抛弃错误的代码调试方法,找到正确的代码调试钥匙
相信每一个从事代码相关的开发人员都能深切体会到代码调试的速度的快慢和准确性而带给你的心理冲击有多大。同样的一个bug,经验老道的程序员可以在几分钟之内调试得到错误的根源,确定缺陷的来由,并在修改时引入尽量少的新错误。
我们都有过这样的体验:调试一段花了30分钟写出来的代码,出错之后往往需要两个小时(甚至更多)来确定错误的根源。并且在最终尝试解决问题的时候,我们可能引入了更多的错误(只是当时没有察觉而已)。
软件质量的普遍性原则:提高软件质量能够减少开发成本。最好的程序员能够找出最多的错误,最快的找到错误并且往往能够正确改正错误。
一、效率低下的调试方法
1.调试魔鬼指南
- 凭猜测找出缺陷,随机放置print语句,试图找出缺陷,不备份原始版本,不记录改变什么。这种方式比较刺激,建议带上吃的喝的,因为你很有可能在电脑前度过一个漫漫长夜。
- 不要把时间浪费在理解问题上。解决问题不需要彻底弄懂程序,只要找出问题就好了。
- 用最唾手可得的方式修正错误。与其把时间浪费在一个庞大的雄心万丈的修正工作,不如直接解决你面对的那个特殊问题,比方说人为地加减一。
2.迷信式调试
每个团队总会有一个人会遇到似乎无穷的问题:不听话的机器,奇怪的编译错误,月圆时才出现的隐藏错误,一个不能正常保存的编译器。我们一般用迷信式调试来统称这种现象。
但是要知道,如果你写的程序出现了某个问题,那就是你的原因,不是计算机的,也不是编译器的,程序不会每次都产生相同的结果,它不是自己写出来的,而是你写出来的,所以要对自己写的代码负责。
二、一些寻找BUG的小建议
- 采用多种方法重现错误:错误常常是由多种因素交织而成,仅仅通过一个测试方法通常无法确定问题的根本原因。
- 用更多的测试结果产生更多的假设:尽量多做一些测试,找到bug出现的流程
- 对可能的假设进行头脑风暴:不要把自己禁锢在一种假设中,而是试试其他假设,然后逐一推翻,这种方法很有可能把你从僵局中解脱出来。
- 在桌上放一个记事本,把需要尝试的事情逐条列出
- 缩小嫌疑代码的范围,用打印语句,日志,或是断点来确定具体出问题的代码段。另外,与其删除某段代码,不如对整个代码分而治之,采用二分法来查找错误。
- 对之前出现过错误的类和子程序保持警惕
- 检查最近修改过的代码:这就需要一个好的版本控制软件
- 扩展嫌疑代码的范围:要专注于一小段代码很容易,但是前提是“问题必然就在这段代码内部“,如果有所怀疑,最好扩大代码的范围,然后用二分法排查
- 增量式集成:一次只对系统添加一部分代码,调试就会变得容易起来,否则就会积重难返,你更改了一大堆程序,现在出了一个错误,尴尬的就是你根本不知道是你更改的那个部分出了问题。
- 检查常见问题:可以针对自己的开发环境列出一张精心定义的常见问题列表
- 与他人讨论问题:忏悔式调试,尝试给别人解释自己的程序,常常就会发现自己犯下的一些错误
- 抛开问题,休息一下:有时太过关注自己的问题,已经到了无法思考的程度。可以暂时放一放,接杯水,如果尝试完了所有可能,把问题放一边,干点其他事情,让你的神经在潜意识中释放问题的答案。
三、蛮力调试
这种调试方法是指一种或许被认为乏味,费神,耗时但是确保问题能最终解决问题的方法。
包括但不限于:
- 对崩溃的代码和设计进行彻头彻尾的逐语句检查
- 抛弃有问题的代码,从头开始设计
- 抛弃整个程序,从头开始设计
- 在最为苛刻的警告级别中编译代码,不放过任何一个警告
- 开发自动化测试工具
- 手动遍历大循环,直到发现问题
- 用另一个完全不同的编译器编译代码
- 对新的代码进行小段集成,对每段进行测试
人们往往会放弃让缺陷无处遁形的彻底系统分析,而去进行快速的尝试,每个人的投机心理都宁愿去用一种有可能五分钟内发现问题的高风险方法,也不愿意为某种保证能找到bug的方法耗费半个小时。风险在于,一旦五分钟的方法没有奏效,你也就麻木了。一旦把这种方法奉为信条,也许几小时几天,几周就过去了。此时你会想,早知道耗费这么多精力,不如一开始就重构代码好了。
如果打算通过捷径来摘取胜利果实,请为尝试的时间设置一个上限,如果超过了该上限,就应当老老实实的承认这个问题比你预想的要难,应该转到稍困难的路上再去尝试。
四、调试过程的一些建议
- 在动手之前先理解问题:避免不懂装懂的动手修改问题,确保在修补问题之前,你已经很透彻的理解了它,如果结果始终与你的预期不符,只能说明你还没有彻底搞懂
- 理解程序本身,而不仅仅是问题:与只了解问题相比,如果能够了解问题的来龙去脉,会更有利于解决该问题。
- 保存最初的源代码:这样你至少能够有一份(不那么完美的)程序可以用,而且一旦修改出了问题,你还可以对比代码,找出问题
- 治本,而不是治标:没有彻底理解问题,就不要去修改代码
- 修改代码时一定要有充分的理由:这就是所谓的“巫毒编程“,不要随机的修改代码直到它能够正确工作,在没有理解代码的时候对它修改越大,你对它能正确工作的信心就越低。
- 一次只做一个改动:错误叠加错误是一种相当尴尬的境地
- 检查自己的改动:或是让别人检查你的改动(code review)
- 寻找类似的问题:看看是否能采用类似的解决方法。
(部分内容来自《代码大全》 作者:Steve McConnell,这本书顺便也推荐一下,包含了软件开发的方方面面,很是不错)