|作者:未知



请问:如何写出没有BUG的代码?_Windows

     1947年9月9日,美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 Mark III 计算机进行研究工作。她的团队跟踪到 Mark II 上的一个错误,操作人员发现是由于一只飞蛾钻到了 Mark II 的继电器里导致的。团队清除了这只飞蛾,一切恢复正常。当时的工作人员记录了这样一句日志:” First actual case of bug being found. ”  这次著名的事件,犹如潘多拉打开了魔盒,从此,程序员的世界里,bug 满天飞。

请问:如何写出没有BUG的代码?_开发者_02


世界上第一个 bug

     在我所担任过的角色中,有一个岗位叫做 Development Manager,通常简称 DM. 记得在一次基于一款平台的二次开发项目中,因为 bug 实在太多,我们几乎拿出了一整个里程碑的周期来 debug,于是我这个DM有了新的解释:Debug Man.

     没有人喜欢 bug,bug 意味着错误、不确定性、加班、交付风险,等等…… 负面的词语怎么堆砌都不冗余。随便找个有过一、两个项目经验的开发者,问问他 debug 的回忆,那气氛就跟上坟一样。

     对于 bug,开发者的神经往往也很敏感。有个段子很有趣 —— 说的是“应该如何向程序员反馈一个 bug ” ——

     你不能直接跟他说:“这里不对啊,是不是你程序有 bug 啊?”,要这么说的话,会直接被怼回来:“你丫的自己不会用吧!”。


     你可以换个说法:“咦,这里好像不对,是我操作错了吗?”,这时程序员心里就一咯噔:“Shit.. 不会是我代码有 bug 吧?”

     从业多年,发现有个现象还蛮有趣的:有时候,当某个 bug 被发现时,犯下这个错误的始作俑者会开玩笑地为自己解脱:“谁没写过 bug 啊,Windows 还有 bug 呢。” 这句托词我也用过,感觉挺好用的,就好比:梅西都能罚丢点球,我空门没进,也是可以理解的嘛。

    但其实吧…… 这逻辑经不起推敲的。

    Windows 操作系统,一款长达30多年,装机量估计都超过了地球人口数量的巨型工程,复杂度基本只能靠猜。以微软公布的资料来看:

Windows 95 代码量约 1500 万行
Windows XP 代码量约 4500 万行
Windows Vista 代码量约 5000 万行
Windows 7 代码量 5000+ 万行

     以 Windows 7 为例,超5000万的代码量,23个小组,共1000多人的开发团队。如此规模下产生的bug,和一个在办公室里上了1天班,写了200行代码,就闹出一堆bug,搞得项目乱七八糟的,能同日而语吗?最后再轻描淡写地来句 “微软也有 bug ”,不害臊?

     所以我后来不用这句了,如此开脱,水平太low。其替代方案容我稍后再讲。

请问:如何写出没有BUG的代码?_开发者_03

人类,实在是太容易犯错了。

    如果说凡事都有正反两面的意义,那么 bug 的正能量就是硬生生造就了大量就业机会,进而维护了社会稳定。

为什么我们总是无法避免 bug 的产生?我们能不能杜绝 bug ?

但凡越是高呼要消灭的东西,越是会普遍地存在。就像苍蝇、蚊虫、污染、犯罪、战争,不一而足。

     按照常识,经验越丰富的老手写出来的代码,一次通过的几率更高,比如他们思考得会更周全,对异常的判断和处理更老练,边界条件把握得更精确,等等。所以我们可能会幻想:是不是只要我们足够仔细,并努力磨练技艺,通过让一部分码农先老练起来,然后实现共同老练,最终就可以达到全世界开发者联合起来消灭bug的大解放了?

     很遗憾,这只是一个治标不治本的思路,因为bug是有阶级的。老手们的bug相对少,只是低级错误少,他们也会遇到bug,而他们的bug,往往都是一眼蒙逼的难度系数N.x的难题,不发生在代码层面,大多在业务层面,甚至需求设计层面,或者直接是一些不可抗拒因素(做过政府项目吗?)。总之,萌新有萌新们的秀逗,大叔有大叔们的短路,老杆也会有自己的滑铁卢。

     bug 这个概念的起源,就预示着它的不可避免性。世界上第一个 bug 是一只飞蛾,这剧本,谁能料到?某种意义上说,bug 就是不可预见的错误,能被预估并且提前做好准备的,那叫 exception, try catch 是他们的朋友。

Edsger W. Dijkstra

If debugging is the process of removing software bugs,  then programming must be the process of putting them in.

这就是上文提到的那句托词 “ Windows 也有 bug. ” 的替代方案。?

     设想一下,当你从无到有的写下一句句代码时,中间的任意一个时刻,你的程序都是运行不起来的,至少也是达不到目标效果的。从效用上完全等效于充满 bug 的一堆代码。你可能会辩解,程序还没写完呢,只是功能还没实现,并没有 bug 。事实上,换位思考一下,缺失某个功能和包含一个有故障的功能,对于用户而言,都是无用的。一个处于开发阶段尚没写完的代码和开发结束但写得有缺陷的代码,是一回事。

由此可以引申出了一个著名的命题:

That’s not a bug, it’s a feature request. 

     有时候,我们很难分清楚一个问题到底属于 bug 还是 feature request . 文中作者抛出了一个案例:用 Visual Studio 构建一个 Windows GUI 程序时没有采用系统默认字体。这个算不算一个 bug 呢?

被宠坏了,在这样的时代下,bug 早已悄悄地泛化了。

请问:如何写出没有BUG的代码?_Windows_04

所以,到底如何才能写出没有 bug 的代码呢?

答案: 不写代码。

一个悲观又绝望却正确的唯一解。

尽可能少写代码。因为 Dijkstra 大师已经说得很清楚了,编程就是制造 bug 的过程。那么,代码写的越少,犯错的几率就越小,这个道理显而易见。维护一段300行的代码,我们很容易有信心;接手一段3000行的代码,什么反应就看各人素质了。

      现代的开发方式也都包含有这个思路,从 IDE 的智能提示,代码补全功能,到每门语言都会有的各种“21天从入门到精通”的开发框架,以及很多实战层面的约定俗成,都是在帮助开发者减少不必要的编码。框架化、规范化思维能降低出错的可能性。

     事实上,就连编程语言本身的历史发展都是按照这个思路在进行。从底层的汇编语言,到C/C++,再到Java/C#/Python……等各种高级语言,语言演化的目的之一就是为了把程序员从脏活、累活的工作中解放出来。

不要重复造轮子”的精神,一方面是在指导我们提高效率,不要重复劳动成本,另一方面也是减少重复犯错的几率。

NPM & left-pad

     这个事件让人们开始反思:我们是不是忘了该如何编程了? 一个功能简单到人人都会写的函数,却都不约而同地选择引入,而不是自己实现。最终,过犹不及。

写代码,真的很难。

NO CODE , NO BUG .

请问:如何写出没有BUG的代码?_Windows_05

     可是,如果真的只能不写代码了,那么本身就已经没有女朋友的程序员们,现在连代码也没有了,这还让不让人活了?

    不能这样把程序员们给逼死了,要讲人权。

问题问错了。

    所以,换个角度,为什么要追求无 bug 呢?也许我们根本就没必要害怕 bug.

面对困难能提供解决方案的人。简单来讲,想赚钱,就别怕麻烦。

     对于客户来说,不管是 bug 或是 feature request,都是一个需要解决的问题。一个优秀的PM,可以把客户反馈的 bug,包装成 feature request,返回一套解决方案。然后,优秀的商务代表出马,签订补充协议。恭喜,你们的项目经费增加了一点点。

英格兰有句谚语:

Where there’s muck, there’s brass.

如此看来,“ 如何写出没有BUG的代码?” 这问题,恐怕确实问错了。



请问:如何写出没有BUG的代码?_开发者_06

请问:如何写出没有BUG的代码?_开发者_07