调试九法读书笔记(三)

第六章 分而治之

当我们排除所有的不可能,不管留下什么,也不管看起来多么不可思议,那必定都是事实。
————福尔摩斯,《四签名》
书中管这种方法叫分而治之,分而治之解决问题的方法在程序中经常被用到,例如归并排序。在现实生活中也是一种解决问题非常有效的方法。在调试程序的时候,分而治之可以帮助我们缩小范围,一步一步接近目标。这个方法通俗的说法叫二分法查bug,我更喜欢这个名字^_^。

6.1 缩小搜索范围

缩小搜索范围,向目标追踪,找到目标范围。在任何有效的目标搜索都会使用的一种共同的技术,那就是逐次逼近。分而治之实际上是第一条需要使用的原则。事实上,在查找问题时它也是唯一需要应用的规则。所有其他规则都知识帮助你遵循这条规则。分而治之是调试的核心,很多人都知道它,但是很多人都没有遵守它。
逐次逼近依赖于两个重要的细节:

  1. 你必须知道搜索范围
  2. 当你查看一个位置时,必须知道问题在这个位置的哪一侧

6.2 插入易于识别的模式

当我们确定了搜索的范围时候,因为系统的复杂有时候很难区分出,我们在系统的哪一侧,这时候我们最好

6.3 从有问题的支路开始查找问题

很多系统都是有多个流程汇合到一起,就像河流的支流汇入到主干。如果从源头开始搜索,可能会由于找错了支流而浪费了大量时间。不要采取这种方法,正确的支流太多了,从错误的一端开始,然后向上有追查。把分支点作为测试点,如果问题仍出在上游,则分别追查每个分支的一小段,以便确定哪个分支有问题。

6.4 修复已知的bug

我们有时候会遇到系统中有很多bug,这种情况下使用分而治之会遇到很大的困难。所以当我们查明了一个bug,应该立刻修复它。然后再查找其他问题。因为bug之间会相互影响,修复好了上一个bug,才能专心致志找寻其他问题。

6.5 首先消除噪声干扰

基于前一条规则的推论,有些bug会引起其他bug,因此要首先找到并修复他们。消除系统的噪声,才能让我们快速定位到真正的问题。

6.6 总结

当bug的藏身之处被缩小一半时,它将很难再隐藏下去

  1. 通过二分法逼近。猜测1到100内的一个数字,只需要7次。因为2^7 = 128,2^6 = 64,所以最多需要7次。
  2. 确定范围。如果数字是135而你却认为它在1到100之间,那么你必须扩大范围。
  3. 确定你位于bug的哪一侧。确认bug在你这一侧,还是在另一侧,然后继续我们的追踪。
  4. 使用干净的测试方法。如果水浑浊了,我们无法分辨bug在哪
  5. 从有问题的那一段开始。除非正确的部分过少。简单说就是从小的那部分开始。
  6. 修复已知bug。bug们会相互掩护,如果在过程中发现了bug,马上修复,继续寻找。
  7. 消除噪声干扰,才能让我们找到真正的bug。

其实现在觉得调试程序的过程就像破案一样,刺激,曲折。