简单就是易于调试
创始人
2024-03-02 04:16:10
0

对于框架、库或者工具来说,怎样做才算是“简单”?也许有很多的定义,但我的理解通常是易于调试。我经常见到人们宣传某个特定的程序、框架、库、文件格式或者其它什么东西是简单的,因为他们会说“看,我只需要这么一点工作量就能够完成某项工作,这太简单了”。非常好,但并不完善。

你可能只编写一次软件,但几乎总要经历好几个调试周期。注意我说的调试周期并不意味着“代码里面有 bug 你需要修复”,而是说“我需要再看一下这份代码来修复 bug”。为了调试代码,你需要理解它,因此“易于调试”延伸来讲就是“易于理解”。

抽象使得程序易于编写,但往往是以难以理解为代价。有时候这是一个很好的折中,但通常不是。大体上,如果能使程序在日后易于理解和调试,我很乐意花更多的时间来写一些东西,因为这样实际上更省时间。

简洁并不是让程序易于调试的唯一方法,但它也许是最重要的。良好的文档也是,但不幸的是好的文档太少了。(注意,质量并取决于字数!)

这种影响是真是存在的。难以调试的程序会有更多的 bug,即使最初的 bug 数量与易于调试的程序完全相同,而是因为修复 bug 更加困难、更花时间。

在公司的环境中,把时间花在难以修复的 bug 上通常被认为是不划算的投资。而在开源的环境下,人们花的时间会更少。(大多数项目都有一个或多个定期的维护者,但成百上千的贡献者提交的仅只是几个补丁)


这并不全是 1974 年由 Brian W. Kernighan 和 P. J. Plauger 合著的《 编程风格的元素 The Elements of Programming Style 》中的观点:

每个人都知道调试比起编写程序困难两倍。当你写程序的时候耍小聪明,那么将来应该怎么去调试?

我见过许多看起来写起来“极尽精妙”,但却导致难以调试的代码。我会在下面列出几种样例。争论这些东西本身有多坏并不是我的本意,我仅想强调对于“易于使用”和“易于调试”之间的折中。

  • ORM 对象关系映射 库可以让数据库查询变得简单,代价是一旦你想解决某个问题,事情就变得难以理解。
  • 许多测试框架让调试变得困难。Ruby 的 rspec 就是一个很好的例子。有一次我不小心使用错了,结果花了很长时间搞清楚究竟哪里出了问题(因为它给出错误提示非常含糊)。

我在《测试并非万能》这篇文章中写了更多关于以上的例子。

  • 我用过的许多 JavaScript 框架都很难完全理解。Clever(LCTT 译注:一种 JS 框架)的语句一向很有逻辑,直到某条语句不能如你预期的工作,这时你就只能指望 Stack Overflow 上的某篇文章或 GitHub 上的某个回帖来帮助你了。

这些函数库确实让任务变得非常简单,使用它们也没有什么错。但通常人们都过于关注“易于使用”而忽视了“易于调试”这一点。

  • Docker 非常棒,并且让许多事情变得非常简单,直到你看到了这条提示:
ERROR: for elasticsearch Cannot start service elasticsearch:
oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:258:
applying cgroup configuration for process caused \"failed to write 898 to cgroup.procs: write
/sys/fs/cgroup/cpu,cpuacct/docker/b13312efc203e518e3864fc3f9d00b4561168ebd4d9aad590cc56da610b8dd0e/cgroup.procs:
invalid argument\""

或者这条:

ERROR: for elasticsearch Cannot start service elasticsearch: EOF

那么…你怎么看?

  • Systemd 比起 SysVinit.d 脚本更加简单,因为编写 systemd 单元文件比起编写 shell 脚本更加方便。这也是 Lennart Poetterin 在他的 systemd 神话 中解释 systemd 为何简单时使用的论点。

我非常赞同 Poettering 的观点——也可以看 shell 脚本陷阱 这篇文章。但是这种角度并不全面。单元文件简单的背后意味着 systemd 作为一个整体要复杂的多,并且用户确实会受到它的影响。看看我遇到的这个问题和为它所做的修复。看起来很简单吗?


via: https://arp242.net/weblog/easy.html

作者:Martin Tournoij 选题:lujun9972 译者:LuuMing 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

原创 ...
据俄国防部通报,乌军近期在哈尔科夫方向发起多轮进攻,双方伤亡均达数...
2025-08-02 21:13:03
跑步10公里做100个俯卧...
近日,山东菏泽一男子走红,从2021年8月开始,他开始挑战“一天跑...
2025-07-24 20:42:35
原创 ...
根据环球网报道,前不久,共和党参议员格雷厄姆牵头提出的对俄制裁升级...
2025-07-17 16:12:48
“10后玩AI,就像呼吸一...
这里是“AI新榜”的「每日一AI」,我们在这里记录一些人类跟AI对...
2025-07-01 12:45:16
如何压缩jpg大小?jpg...
我们日常的学习、工作中,经常需要收发很多jpg图片。...
2025-06-01 04:50:50
121.Android 简...
             //首页xml布局代码&#x...
2025-06-01 04:29:59

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
从 Yum 更新中排除特定/某... 作为系统更新的一部分,你也许需要在基于 Red Hat 系统中由于应用依赖排除一些软件包。如果是,如...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...
如何检查你的 Linux 系统... 不知道在使用哪个初始化系统?以下是方法。每个主流 Linux 发行版(包括 Ubuntu、Fedor...