来源:www.cnblogs.com/sherrywasp/p/9262877.html

1947年9月9日,美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 Mark III 计算机进行研究工作。

她的团队跟踪到 Mark II 上的一个错误,操作人员发现是由于一只飞蛾钻到了 Mark II 的继电器里导致的。

团队清除了这只飞蛾,一切恢复正常。

当时的工作人员记录了这样一句日志:“First actual case of bug being found. ”  这次著名的事件,犹如潘多拉打开了魔盒,从此,程序员的世界里,bug 满天飞。

世界上第一个 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,人们发明了各种各样的工具和手段,上至方法论,下至生产工具。越来越先进的 IDE, 复杂的代码审查制度,从单元测试到集成联调,再配上 beta 版,试用,公测,等等。凡此种种,其目标无一不是消灭 bug 。

可这些琳琅满目的解决方案的存在,反倒证明了一个悲剧:人类,实在是太容易犯错了

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

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

答案当然是不可能了。因为那样一来,程序员的日子岂不是太舒服了?不符合苦逼的定位。而且,我们所处的这个世界,但凡越是高呼要消灭的东西,越是会普遍地存在。就像苍蝇、蚊虫、污染、犯罪、战争,不一而足。

按照常识,经验越丰富的老手写出来的代码,一次通过的几率更高,比如他们思考得会更周全,对异常的判断和处理更老练,边界条件把握得更精确,等等。

所以我们可能会幻想:是不是只要我们足够仔细,并努力磨练技艺,通过让一部分码农先老练起来,然后实现共同老练,最终就可以达到全世界开发者联合起来消灭bug的大解放了?

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

总之,萌新有萌新们的秀逗,大叔有大叔们的短路,老杆也会有自己的滑铁卢。《如何写出让同事无法维护的代码?》了解下

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

对于为什么会产生 bug 的原因,著名的荷兰计算机科学家 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 了,避免空指针的 5 个案例!

你可能会辩解,程序还没写完呢,只是功能还没实现,并没有 bug 。事实上,换位思考一下,缺失某个功能和包含一个有故障的功能,对于用户而言,都是无用的。一个处于开发阶段尚没写完的代码和开发结束但写得有缺陷的代码,是一回事。

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

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

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

不好说。毕竟,随着软件应用越来越普及、越来越追求所谓人性化的趋势,传统意义上的只要程序能运行就不算 bug 的观点,也在慢慢发生改变。

对于一个强迫癌用户来说,UI 上有缺陷,那基本上整个软件就不能用了。事实上,在当今各类 app 竞争白热化、同质化的时代,用户体验上的问题,往往是致命的。

以前大家没得选,所以没那么挑剔,只要程序能干活就行了。如今的计算机用户已经被宠坏了,在这样的时代下,bug 早已悄悄地泛化了。关注Java技术栈微信公众号,在后台回复关键字:Java,可以获取一份栈长整理的 Java 最新技术干货。

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

答案: 不写代码。

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

试着在这绝望里挖掘一点希望吧。这个答案隐含了一个方法论: 尽可能少写代码。因为 Dijkstra 大师已经说得很清楚了,编程就是制造 bug 的过程。

那么,代码写的越少,犯错的几率就越小,这个道理显而易见。维护一段300行的代码,我们很容易有信心;接手一段3000行的代码,什么反应就看各人素质了。推荐:优秀 Java 程序员写代码的风格

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

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

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

当代 Web 开发中的各种包管理概念正深刻地践行着这条精神,以至于在2016年3月爆发了著名的 NPM & left-pad 事件: 一段区区11行的字符串填充函数模块,被全世界依赖,结果作者 Azer 下架模块包的那一天,全球前端大崩溃。受波及的产品和团队中,甚至包含著名的 React !

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

写代码,真的很难。

NO CODE , NO BUG .

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

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

有时候,当答案实在不可接受的时候,我们就该思考是不是问题问错了。

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

有 bug 的地方就有麻烦,有麻烦就有解决麻烦的需要,客户就是给那些能解决麻烦事的人支付报酬的。只处理简单的问题,是没有价值的,市场只认可那些面对困难能提供解决方案的人。简单来讲,想赚钱,就别怕麻烦。

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

英格兰有句谚语:

Where there’s muck, there’s brass.

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

关注Java技术栈微信公众号,在后台回复关键字:Java,可以获取一份栈长整理的 Java 最新技术干货。

最近干货分享

公司不用 Spring Boot,果断离职了!

Java 12 骚操作, switch居然还能这样玩!

Java 12 骚操作, String居然还能这样玩

Spring Boot 1.x 正式退役,2.x大步向前

分享一份 2019 最新 Java 架构师学习资料

点击「阅读原文」加入栈长的战队~

如何写出没有 bug 的代码?的更多相关文章

  1. fir.im Weekly - 如何写出零 bug 的代码

    神兽护体,代码无bug.经常看到代码注释的各种形状,这是一种程序员情怀.那么,如何能写出零 Bug 的代码呢,来看看@码农翻身 的这篇手册--零Bug的代码是怎么炼成的. 写零 Bug 一定少不了代码 ...

  2. 如何写出没有BUG的代码

    1947年9月9日,美国海军准将 Grace Hopper 在哈佛学院计算机实验室里使用 Mark II 和 Mark III 计算机进行研究工作.她的团队跟踪到 Mark II 上的一个错误,操作人 ...

  3. QT就是别人好心帮你做一些枯燥,并且很重复的代码编写工作,让你更好的把精力投入到你界面的逻辑和功能的实现的功能库(否则写了上万行代码了,才写出个BUG一大堆的毛坯)

    好了,现在开始记录我学习QT的学习历程 . 本人也不是计算机专业出来的,自学了一点,但还是不好找工作,于是参加了培训,虽然感觉没多学到什么 编程的学习生涯就是不断的看别人的源码,然后自己参考着写写自己 ...

  4. 如何写出健壮的Java代码

    近来在公司写代码,写出的代码发现BUG很多,为了实现一个功能,代码改了又改,影响了工单的效率,也影响个人绩效,因此从网上找了些关于写健壮代码的文章看了看,再加上自己的一些经验总结. 所谓健壮的代码是指 ...

  5. 如何写出优雅的JavaScript代码 ? && 注释

    如何写出优雅的JavaScript代码 ? 之前总结过一篇<如何写出优雅的css代码?>, 但是前一段时间发现自己的js代码写的真的很任性,没有任何的优雅可言,于是这里总结以下写js时应当 ...

  6. 《数据结构与算法之美》 <05>链表(下):如何轻松写出正确的链表代码?

    想要写好链表代码并不是容易的事儿,尤其是那些复杂的链表操作,比如链表反转.有序链表合并等,写的时候非常容易出错.从我上百场面试的经验来看,能把“链表反转”这几行代码写对的人不足 10%. 为什么链表代 ...

  7. 如何用java写出无副作用的代码

    搞java的同学们可能对无副作用这个概念比较陌生,这是函数式编程中的一个概念,无副作用的意思就是: 一个函数(java里是方法)的多次调用中,只要输入参数的值相同,输出结果的值也必然相同,并且在这个函 ...

  8. 如何写出优雅的CSS代码 ?(转)

    对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于团队合作和后期的维护:而有的混 ...

  9. 如何写出优雅的css代码 ?

    如何写出优雅的css代码 ? 对于同样的项目或者是一个网页,尽管最终每个前端开发工程师都可以实现相同的效果,但是他们所写的代码一定是不同的.有的优雅,看起来清晰易懂,代码具有可拓展性,这样的代码有利于 ...

随机推荐

  1. js中reduce()的牛掰所在 本质作用:实现数值累计,筛选过滤,类似递归

      先看w3c官说   array.reduce(function(total, currentValue, currentIndex, arr), initialValue); /* total: ...

  2. rsync 和 inotify 结合

    我们知道 rsync 可以实现推送和拉取,而 inotify-tools 借助内核的 inotify 机制实现了文件的 实时监控.因此,借助这个思路,我们可以通过使用 shell 脚本,调整 inot ...

  3. Shell脚本的fork炸弹

    #!bin/bash#功能:快速消耗计算机资源,致使计算机死机#作者:liusingbon#定义函数名为.(点), 函数中递归调用自己并放入后台执行function . { .|.& };.

  4. bzoj 3569 DZY Loves Chinese II 随机算法 树上倍增

    题意:给你一个n个点m条边的图,有若干组询问,每次询问会选择图中的一些边删除,删除之后问此图是否联通?询问之间相互独立.此题强制在线. 思路:首先对于这张图随便求一颗生成树,对于每一条非树边,随机一个 ...

  5. Redis安装配置以及开机启动

    1.下载源码,解压缩后编译源码.  $ wget http://download.redis.io/releases/redis-2.8.3.tar.gz $ .tar.gz $ cd redis- ...

  6. Java 根据银行卡号获取银行名称以及图标

    转 https://blog.csdn.net/N_007/article/details/78835526 参考 CNBankCard 中国各大银行卡号查询 一.支付宝接口获取名称 根据 卡号 获取 ...

  7. Zabbix分布式监控系统实践

    https://www.zabbix.com/wiki/howto/install/Ubuntu/ubuntuinstall 环境介绍OS: Ubuntu 10.10 Server 64-bitSer ...

  8. Spring中都用到了哪些设计模式

    JDK 中用到了那些设计模式?Spring 中用到了那些设计模式?这两个问题,在面试中比较常见.我在网上搜索了一下关于 Spring 中设计模式的讲解几乎都是千篇一律,而且大部分都年代久远.所以,花了 ...

  9. Android Release 打包提示 "错误:找不到符号"

    搞了一上午....必须记录下来

  10. springboot版本依赖

    springboot2.x及以后依赖于jdk1.8及以上. 如图: