文档章节

为什么修复每个 bug 后都要问这 3 个问题?

爱码小士
 爱码小士
发布于 2018/12/28 19:38
字数 2214
阅读 227
收藏 2

你是否曾经修复了一个 bug ,随后又发现了一个跟刚修复 bug 有关的 bug ,又或是修复 bug 的方式引起了另一个 bug ?当我修改 bug 时,我会问自己三个问题,以确保我已经仔细考虑了它的意义。每次你认为发现并修改了一个 bug 时,可以使用这些问题来提高生产力和代码质量。

这些问题背后的主要思想就是:每一个 bug 都是底层进程的一个不良表现。你必须处理这些症状,但如果你仅仅是处理这些外在症状,你就会有永远解决不完的问题。你应该找到产生 bug 的进程,并且修复这个进程。当你确定究竟发生了什么和发生这些的原因时,也许你就会明白产生 bug 的基础进程不是随机的,而是可控的。

在问这三个问题前,你需要克服面对 bug 的这种天生的抗拒,仔细分析 bug 。查看代码并解释出错的原因,从能观察到的现象开始,向后分析,不断地问为什么,直到你可以找到产生 bug 的模式。通常,你该跟同事一起做这件事, 因为解释你认为会发生的事情,将迫使你面对一些假设——这些程序是做什么的。

“它溢出了,因为下标J越界了。”

“为什么?”

“J 是 10,但数组最大下标为 9。”

“为什么?”

“J 是一个字符串长度,数组的起始下标是 0,所以字符串长度为 1 的最后一个字符的索引是 0。”

找到 bug 后,查找其他意外情况。检查程序出错时主要的程序变量的值,是否可以解释这些值。

“为什么 name 是 null?”

“为什么它总是输出错误信息呢?”

记录下你做了哪些操作,发生了哪些变化。你需要知道究竟发生了什么,这样做就意味着你时刻有一把标尺和历史记录。

当完成这些步骤后,你可以准备问第一个问题了。

1. 其他地方也会出现这个错误吗?

查看代码中使用相同模式的地方,系统地改变模式找出类似的 bug 。

“我还在其他什么地方使用长度作为下标的吗?”

“所有数组的起始下标都一样吗?”

“对于一个长度为 0 的字符串会发生什么?”

试着描述这部分代码中应该是正确的,但是这些 bug 没有遵循的规则。寻找这个不变量 [ 1 ]的过程将帮助你找到其他潜在的 bug 。

“起始偏移加上长度减去1就是结束的下标,除非数组长度为 0”。

对于你发现的每一个 bug ,你都可以解决一批 bug ,这是非常高效的。尝试用概括性的语言描述这些 bug 也能提升你对程序的理解程度,并帮助您避免在程序中引入更多的 bug 。

2. 这个 bug 后面隐藏着什么其它的 bug ?

一旦你确定了如何修复这个 bug ,你就需要考虑一下修复后会发生什么。这个执行失败的语句后面的语句也可能有问题,但是程序还没有执行到此就不知道有没有 bug ,或者有些代码因为你修复 bug 而第一次出现在程序中,这些代码也可能有问题。查看这些未执行的语句,检查代码中的 bug 。

“下一条语句会正常运行吗?”

当你在想程序的控制流的时候,可以弄清楚还有哪些地方程序没有执行到。

“是否有我从来没有测试过的功能组合?”

在程序中插桩(instrumentation)并不会耗费太多时间,在运行程序各个部分的过程中就可以进行检查,但是你会惊讶地发现开发者测试过的代码还有很多都不能正常运行。

“我可以测试出所有的错误信息吗?”

注意一个地方的改动可能会引起其他地方的 bug 。一些变量的局部改动可能会在执行时违反后来的假设。

“如果仅是从 J 中减去 1,当长度为 0 时,后面的语句会操作数组中 -1 位置的元素。”

如果程序已经做了大量改动,就要仔细考虑是否有必要增加另外一个补丁,或者是时候考虑重新设计和重新实现了。

(有时候调 Bug 就是这样的)

(有时候调 Bug 就是这样的)

3.我应该做些什么防止类似 bug 的产生呢?

问问自己如何改变编程方法,根据定义避免 bug 的出现,通过改变方法或者工具,经常可以移除整个类的错误而不用一个一个的解决 bug 。

如果对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、面试经验交流。感兴趣可以175317069,群内会有不定期的发放免费的资料链接,这些资料都是从各个技术网站搜集、整理出来的,如果你有好的学习资料可以私聊发我,我会注明出处之后分享给大家。

从“ bug 是何时引入的”这个问题开始:在程序开发生命周期的哪一个阶段可以阻止 bug 的产生?

“设计是没问题的;我在编程时引入了 bug 。”

仔细检查 bug 产生的原因,考虑 bug 产生时正在运行的进程,并想想怎么改变它来阻止 bug 的产生。

“将偏移的数据类型和长度分离出来将会在编译时捕获这个错误。”

“每一个文本项可以用隐藏了下标计算的宏输出,然后我就可以一次找到它。”

不要满足于肤浅的答案。假如你对于一个 bug 的解释是,“我记不清了”,那还怎么改进这个过程,让你不再需要记住它?你可以更改编程语言,使被忽略的细节可以完全隐藏,否则你遗漏的部分会被检测到从而导致编译问题。对这个问题域,你可能使用了预处理器或者智能的编辑器,有默认值,错误检查,智能提示和快速文档。这个 bug 可能是编程团队沟通的问题,亦或是需要讨论的设计冲突。

思考发现 bug 的方式,并问问自己如何能更早发现它。测试怎么可以更严密一些?能否进行自动化测试?是否要添加代码实时检测功能,以便可以及时捕获错误信息?

“我应该在我的测试单元中尝试长度为 0 的数组”。

“我应该进行下标检查,提前捕获不符合的下标”。

有必要创建一些系统方法和自动化工具,用于编译、构建和测试,它们可以减少长时间的调试和查明具体事实的过程。

这个技巧的应用

养成这样一种习惯:每当你发现一个 bug 时,问自己这三个问题,甚至你不必等到有 bug 时才使用这三个问题。

在设计和审查过程中,你都可以用这三个问题来处理你得到的每一条意见。审阅意见是潜在的沟通过程的结果,使你可以有所改进。如果你认为读者评论是错误的,比如,你可能会问是什么使你的文章没被理解,如何更好地与审稿人沟通。

设计评审和代码审查是找出 bug 的强有力手段,你可以对审查过程出现的每一个缺陷都提出三个问题。如果审查彻底,前两个问题不会出现太多新的 bug ,但第三个问题可以帮助你找到方法,用来避免未来可能会出现的 bug 。

扩展阅读

© 著作权归作者所有

爱码小士
粉丝 57
博文 83
码字总数 194222
作品 0
深圳
技术主管
私信 提问
加载中

评论(0)

程序员必知的10大编码原则

每个程序员的职业生涯都是与一个又一个代码共度的,每天除了码代码还是码代码。总结回顾下我的职业生涯,经历的多了,总觉得不总结点有用的东西出来感觉对不起程序员码代码这份职业!编码多了...

小开2014
2014/10/23
138
1
【译文】不是所有的 bug 都值得修复的

原文作者:KRISTINE PINEDO 译者:白乐航 欢迎访问网易云社区,了解更多网易技术产品运营经验。 作为软件开发者,您只需要为客户编写和交付出色的产品和功能。 但您也知道软件开发并不总是那...

网易云
2018/12/04
0
0
为什么我不使用 shrinkwrap(lock)

最近 Facebook 发布的 yarn 又引发了前端(node)界的海啸,yarn 除了速度比 npm 更快、支持离线安装等特性外,对 npm 体系最大的一个冲击是 yarn 默认提供了 lock 功能。也就是说在通过 ya...

死马
2016/10/13
0
0
浅谈即时验收在敏捷开发中的应用

[注]:这是2008年底写的一篇关于即时验收(即常说的BA sign off)的文章,原文发表于《程序员》杂志。从去年刚开始加入ThoughtWorks,对敏捷懵懂了解,到现在随着经历的增多,对敏捷的了解也...

一堆BUG
2012/02/28
173
0
为何我暂停了维护 Python 社区的志愿者工作

作者是 Python 的核心开发者,从2002年开始,十四年来自愿用业余时间为 Python 语言添砖加瓦。但这种活雷锋行为并没有得到开发者们的理解,很多人甚至用命令的口吻要求活雷锋们再苦再累也得免...

局长
2016/11/18
1.2W
39

没有更多内容

加载失败,请刷新页面

加载更多

基于Spring Boot2.0.2版本--SpringBoot整合Quartz调度框架

一、引言 定时任务调度是Java开发中不可或缺的重要部分,但是Java自带的Time等任务调度类在实际项目中不好用。所以Quartz和Spring Task就成了我们项目开发技术选型最多的,在这里我们着重探讨...

修改bug工程师
26分钟前
28
0
hbase查询速度优化

优化思路 1.构建良好的索引 2.查询时只查需要的字段 3.java使用habse原生方式链接hbase spring集成的hbase链接和查询方式 @Configurationpublic class HbaseConfig { @Bean publi...

qiaoaniu
26分钟前
27
0
Python3 +scrapy爬虫识别验证码(二)点触验证码识别

感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30742.html 点触验证码主要有点击文字或者点击图片,例如 如何通过点击图片当中的文字或者图片进行识别呢?那么这里介绍一下超级鹰平...

曹长卿
28分钟前
24
0
Jackson deserialize using generic

某度找出来的实在惨不忍睹,还是记一下吧. 用jackson 把 Json string 转换成 java object 大家都会,比较简单. 怎么转带泛型的类呢,头一遭儿. 参考链接: https://stackoverflow.com/questions...

园领T
28分钟前
19
0
学习Tomcat - 类加载器

Servlet规范定义的类加载顺序 在Servlet规范中有对web应用程序类的加载方式作出建议,重要的有两点: 容器要加载某个类时,类加载器首先应该加载本地web应用程序中“WEB-INF/classes”路径中...

閒散人員
30分钟前
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部