15-bug的源头

136 阅读4分钟

bug来自哪里?我们能把所有bug的成因范围缩小至一个或者几个之内吗?答案是肯定的。

bug通常来自开发者尝试降低代码复杂性未果而产生的副作用。也有部分来自对其实简单的代码产生的误解。

除了一些拼写错误以外,我能十分肯定以上两点基本就是所有bug产生的根本原因,尽管我还没有进行深入的研究来证明这件事。

复杂的事物容易引起用户的误操作。想象一下一个黑色盒子,上面有上百万个没有任何标识的按钮,而其中的16个按钮按下之后会毁灭整个世界,那么使用这个盒子的人中注定有人会一不小心让毁灭降临。在编程中也存在类似的情况,如果你无法轻易理解编程语言的文档,或者是这门语言本身,你就或多或少存在错误使用它的可能。

说真的,就那个长满上百万个没有标识按钮的盒子而言,正确的使用方式不可能存在。你永远也不可能弄清正确的方式是什么,即使你计划阅读完1000页的说明书,也不一定能记住能够帮助你正确使用盒子的整套流程。同样的道理,只要你让事物变得足够复杂,人们就会倾向于用错误的而不是正确的方式使用它。如果你把50、100或者1000个这类的复杂组件拼装在一起,无论由多聪明的工程师来进行拼装,它们也永远无法正常工作。所以你开始明白bug来自哪里了吧?你每引入一丝复杂性,开发者(这里的“开发者”甚至包括你自己)误用你的代码的概率就高一分。

一旦代码的意图和使用方法变得极不明确,就会让使用这份代码的人犯错。又因为你的代码和其他的代码混合在了一起,导致了开发者误用和犯错的可能性大大增加。而后这些代码又会继续和其他的代码混合,形成恶性循环。

复杂性的构成

硬件设计者将硬件制造得极为复杂的情况时常发生。所以它必须与复杂的汇编编程语言集成。而这又使得汇编语言和编译器同样复杂起来。当你遇到这种情况时,如果你不提前对程序进行精妙的设计或者全方位的测试的话,基本上无法避免bug的发生。只要你的设计不够完美,那么在运行的一瞬间,大量的bug就会涌现出来。站在其他程序员的视角看这件事也很重要。毕竟有些事对你来说很简单,但是对其他人来说或许很复杂。

如果你想要感同身受地体验一下其他人看不懂你的代码的感受,你可以找一份你从没有使用过的类库的文档来阅读看看。也可以找一些你从没有阅读过的代码来阅读。尝试理解整段程序而不是单行代码的含义,并且想象当你需要对它进行修改时应该从哪里入手。这些都是其他人阅读你代码时的体验。你大概注意到在阅读他人代码时,即使并不复杂的代码也足以让人产生挫败感。

现在我们考虑另一种程序员误解简单代码的情况。这也是需要额外小心的另一件事。如果你察觉到某位程序员在向你解释一段代码时叙述得牛头不对马嘴,那便意味着他应该是误解了代码中的某些内容。当然如果他正在研究的领域极其复杂,也情有可原,可能需要他读到博士学位才能完全掌握它。

这两个方面是紧密关联的。当你编写代码时,需要承担的部分职责是让将来阅读你代码的程序员理解它,并且是很轻松地就能理解。

如果你确实是这么做的,但是他在阅读过程中仍然产生了严重误解——或许他根本就不明白“if”语句是什么含义。那应该就与你无关了。

假设将来那些阅读你代码的程序员,对编程的基本原理和正在使用的编程语言语法都略知一二,在这个前提下你的职责是写出整洁的代码。

所以最后可以总结出几条有趣的原则:

1.你写的代码越简单,bug就越少。

2.你应该始终想方设法去简化程序中的代码。