[转]http://macshuo.com/?p=1361
怎么减少编程中的 bug?

Posted on 2016 年 2 月 17 日

为什么要编程?因为代码没在那里。创造一个世界是如此让人着迷,Linux 的创始者 Linus 这样表述对编程的喜爱之情:

对于喜爱编程的人来说,编程是世界上最有趣的事,比下棋有趣得多!因为你可以自己制订游戏规则,而你制定什么样的规则,也就会随之出现与此规则相符合的结果。

在电脑世界中,你就是创世者,你对所发生的一切拥有最终的控制。

你可以建筑一个这样的房子,有一个活板门,既稳固又实用。但是每个人都可以看出一个仅仅以坚固实用为目的的树上小屋和一个巧妙地利用树本身特点的美妙小屋之间的差异。这是一个将艺术和工程融为一体的工作。编程与造树上小屋有相似之外……

每个热爱编程的人都在编写代码的过程中享受着创造的乐趣,但是,伴随着编码的快感,bug 总是如影随形,开发无止境,bug 随身行。bug 是每个程序员没法绕开的障碍,它们就在那里,修复一个,增加一个,似乎永不减少,永远存在。

遭遇 bug 的时候,理性的程序员会说:这个 bug 能复现吗?
自负型:这不可能,在我这是好好的。
经验型:不应该,以前怎么没问题?
幻想型:可能是数据有问题。
无辜型:我好几个星期都没碰这块代码了!
乐观型:只需要改一行代码,不会影响其它程序的。
实践型:你重启一下服务试试。

无论你是哪种类型的程序员,遭遇 bug,内心都是崩溃的,尤其是产品经理或测试人员在使用或测试产品的过程中抓到你的一个 bug 之后那种如获至宝的表情和欢呼声,会让我们的心情久久不能平静。于情于理,防患于未然,减少编程中的 bug,对产品和程序员,都是最好的结果。

能不能一次编写出没有 bug 的程序呢?一般来说,并不能,除非你写一辈子 Hello World。我见过一些天才的程序员,他们差不多能做到这一点。接到任务之后,思考,冥想,在笔记本上画出数据结构或某个算法片段,腹稿打的差不多了就开始编程,用 Vim、Emacs 或 IDE 工具,大部分时候能够一气呵成,然后构建代码,构造测试数据,运行程序,在反复调试中修复几个编程过程中没有考虑到的问题,就可以提交到代码库了。他们的代码交给测试和其他开发者,少有人能挑出 bug,因为他们对代码有敏锐的感觉,能够在别人忽略的地方发现代码的坏味道,并给出巧妙而优雅的解决方案。他们是天生的代码创造者,这样的人往往效率高而且少有错误,以至于会被一些平庸的团队忽略,因为技术领导总是会下意识的去关注那些最容易出事的环节,但这些人才是团队真正的脊梁,不是那些四处救火者。如果你拥有这样的程序员,就算捡到宝贝了,要好好珍惜。

我不是天才的程序员,但在年轻时大量产出代码的时候,差不多也能做到类似的效果。没什么好的办法,只能下笨功夫,我会在编码之前尽可能把所有的可能性都想清楚,然后认真做好设计。我常常在工作时间完成代码的编写,下班后带着笔记本回家逐行 Review 自己的代码,对着设计图检查是否处理了各种异常和边界条件,并先于测试人员对自己的代码进行白盒测试和黑盒测试。另外,在编程方面我奉行不要在同一个地方摔倒两次的原则,每次自己程序出现的 bug 案例,我都会记录到 bug 库里,检查代码的时候逐一对照,确保不会犯重复的错误。

可能年轻的时候自尊心比较强,我难以忍受自己的程序被别人找出 bug,于是偷偷花费了两倍的时间来保证代码的质量,以至于团队的人认为我一次就能编写出高质量的代码。现在看来,我当时是个错觉制造者。

所以,减少 bug 的第一步,是提升自己的程序员素养,努力不给自己和别人找麻烦。

另外,团队协作也很重要,前期的技术方案和设计评审、代码审查,对减少一些重大的错误和弱智的 bug 都非常有好处。

与几个有经验的程序员一起评审一个技术方案,常常会发现一些重大的问题,比如为什么用缓存,为什么做持久化,高并发下怎么应对,这部分设计支持线程重入吗,这个循环为什么设置成10分钟,这个超时设置为什么是60秒,传输协议加密了吗,等等。很多方案可能会仅限于解决当前的问题,但有经验的程序员却能透过时间的重重迷雾,发现这个方案在未来某个时间点可能爆发的问题。这就是评审的力量。

技术方案和设计评审一般是先于代码的,开始编写代码了,Code Review(代码审查)就可以提上议事日程了。国内很多团队的技术人员内心是抵触代码审查的,他们常常想,在这个国家我们已经被审查的够多了,就不要再自己审查自己了,然后很多 bug 就产生了。

我和 Google、Facebook、Twitter、Airbnb 的中国工程师讨论过 Code Review,他们觉得没有代码审查是不可思议的。在这些公司的研发流程里,Code Review 是必不可少的一个环节,只有别人帮你做了 Code Review 并在代码上「打了戳」,你的代码才能进入 Code Base。在 Facebook,如果你 Review 了别人的代码,如果那个人休假了,你就要接手他的代码,出了任何问题都要唯你是问。

事实上,Code Review 才是真正的白盒测试,没有经过代码审查,仅凭测试很难保证代码质量。测试通过了但没有经过代码审查的代码仍然会出各种问题,这样的案例比比皆是。只有当另外一个人读了你的代码,并且表明能看懂时,这些代码才有真正有了鲜活的意义。代码审查的意义就是,在你的代码库合进代码库之前,至少有一个人读过你的代码。

很多人在做代码审查之前会调研大量的代码审查工具,就像一个人在跑步之前,要先准备好跑鞋、袜子、压缩裤、压缩上衣、鼻贴、眼镜、口罩、导汗带、魔术头巾、各种手表、冷却喷雾、肌内效贴布……然后一个月过去了,你问他跑了几次,他会很扭捏的告诉你,髌骨带还没有到!

没有工具一样可以做代码审查,你只需要偏转身体,在另一个程序员不忙的时候拍拍他的肩膀说,「来,看看我的代码,你能看懂吗?我准备把它们提交到代码库里」。然后阐述你的思路,倾听他的建议,并根据这次讨论的结果决定,是修改一下,还是继续提交到代码库。

不要小看这短短的20分钟,它可能会帮你避免的一些隐藏的和弱智的 bug。

很多团队都是因为代码审查过程或工具过于复杂放弃了Code Review,典型的因噎废食,其实使用 less、diff 和 git 等工具,基本上就可以做一次完整的代码审查了。如果你过于依赖工具和过程,那说明你并没有抓住问题的核心。

写了这么多,如何减少编程中的 bug 呢?不难,也不容易。对内,努力提高自己的程序员素养,不去浪费自己和别人的时间。对外,重视团队协作,进行方案评审和代码审查。做到这两点,你会发现,代码中的 bug 会越来越少的。

没有 bug 的代码,才是好代码!

[转] 怎么减少编程中的 bug?的更多相关文章

  1. 写代码的心得,怎么减少编程中的 bug?

    遭遇 bug 的时候,理性的程序员会说:这个 bug 能复现吗? 自负型:这不可能,在我这是好好的. 经验型:不应该,以前怎么没问题? 幻想型:可能是数据有问题. 无辜型:我好几个星期都没碰这块代码了 ...

  2. FindBugs 入门——帮你减少代码中的bug数

    FindBugs 入门 FindBugs 作用 开发人员在开发了一部分代码后,可以使用FindBugs进行代码缺陷的检查.提高代码的质量,同时也可以减少测试人员给你报的bug数. 代码缺陷分类 根据缺 ...

  3. 基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG

    基于Keil C的覆盖分析,总结出编程中可能出现的几种不可预知的BUG,供各位网友参考 1.编译时出现递归警告,我看到很多网友都采用再入属性解决,对于再入函数,Keil C不对它进行覆盖分析,采用模拟 ...

  4. Java编程中的一些常见问题汇总

    转载自  http://macrochen.iteye.com/blog/1393502 每天在写Java程序,其实里面有一些细节大家可能没怎么注意,这不,有人总结了一个我们编程中常见的问题.虽然一般 ...

  5. Java编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  6. 【转】资源文件在Delphi编程中的应用

    段东宁 计亚南 (郴州职业技术学院, 湖南 郴州  423000) 摘要: 资源文件是一种能有效地组织.管理和使用资源的文件形式,在软件开发中有着广泛的应用.本文详细介绍了在Delphi编程中资源文件 ...

  7. PHP编程中10个最常见的错误

    PHP是一种非常流行的开源服务器端脚本语言,你在万维网看到的大多数网站都是使用php开发的.本篇经将为大家介绍PHP开发中10个最常见的问题,希望能够对朋友有所帮助. 错误1:foreach循环后留下 ...

  8. Android编程中的实用快捷键

    作为一个优秀的程序员,不但要能开发出漂亮的软件,也要能熟练掌握编程的技巧,包括IDE的快捷键使用.比如linux 下的VI编辑器,对于不熟练快捷键的人来说就是一个噩梦,但一旦你熟练了VI的快捷键,VI ...

  9. 一文读懂高性能网络编程中的I/O模型

    1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...

随机推荐

  1. 子类化GetOpenFileName/GetSaveFileName, 以及钩子函数OFNHookProc的使用的简要说明

    昨天, 群里面有一个人问起: 要怎么让"文件打开对话框"居中显示, 有人说子类. 而我告诉他的方法是用钩子函数OFNHookProc, 不知道这是不是所谓的子类?相信看了我今天这篇 ...

  2. java 获取局域网中的全部主机名和IP地址

    DOS命令 命令 意义 net view 获取局域网中的全部主机名 ipconfig -all 获取本地IP,主机名,MAC地址 arp -a 获取本局域网中的全部IP地址和物理地址 ping -a ...

  3. [Perforce]password (P4PASSWD) invalid or unset. 的错误解决

    前言 使用 Perforce , 能够使用Perforce 的Client 端. 有时候在编写一些脚本或代码的时候, 可能或使用到 Perforce的命令的方式. 正常状况下. 使用例如以下命令: p ...

  4. 编写 T4 文本模板

    文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...

  5. [转]Intellij IDEA快捷键与使用小技巧

    Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ ...

  6. Android系统版本与API级别对照表

    对照表 API Level 最初Android版本 Linux内核版本 首次发布日期 后续Android版本 28 9 Unknown 2018-07-02(Beta 3) - 27 8.1 4.10 ...

  7. Windows Mobile入门

    转自 http://www.cnblogs.com/peterzb/archive/2009/05/12/1455256.html [准备篇]        最近安排做手机视频监控方面开发,这个对我来 ...

  8. elk 使用中遇到的问题(kafka 重复消费)

    问题描述: 在使用过程中,当遇到大量报错的时候,我们到eagle后台看到报错的那个consumer的消费情况到到lag 远远大于0(正常情况应该为0),activie  节点没有,kibana面板上没 ...

  9. ELK logstash邮件报警

    这个方法有一个问题就是我这边不能给我们公司的邮箱发邮件.还有就是我们有两个邮箱一个是腾讯企业邮箱,还有一个就是我们的集团邮箱 使用下面的这个方法是不能给我们的集团邮箱发邮件的.第二个问题就是这个方法给 ...

  10. php分享十四:php接口编写

    一:加密协议选择 二:常用url传递函数介绍 urlencode 和 rawurlencode 区别是: urlencode把空格变为+号,而rawurlencode编码为20%: base64_en ...