调试九法读书笔记(二)

第五章 不要想,而要看

看到这章的标题,感触很深。因为自己刚工作开始写程序的时候就是书中的反面例子——出问题的时候主管臆断,想当然的认为某个地方出现错误,然后就去修改。但是其实正确的做法是观察,了解系统,运用之前学习的两个原则——理解系统和制造失败。这一章说的就是如此,当我们遇到错误的时候,不要去想哪里出现问题,首先通过制造失败,然后不断搜集系统的环境数据和状态数据,然后通过对自己对系统的了解去分析系统,然后逐步定位错误。下面我们看看书中具体是如何讲解这条规则的。

5.1 观察失败

如果想找到故障所在,必须真正看到发生故障的情况。这很显而易见,但是我们要知道,当我们看到bug的时候,其实是失败的结果。比如:我们打开开关,灯没有亮。但实际情况出在哪里呢?是开关坏掉了吗?还是灯丝坏了?或者仅仅是按错了开关,这个开关并不是这盏灯的?所以必须仔细观察,找到足够的问题细节,才能调试。

5.2 查看细节

当我们观察到失败后,接下来我们需要查看更多的细节并找到问题的原因。在查找细节的过程中,经验会起到帮助作用,就像理解系统会起到帮助作用一样。当你做出了错误的假设并沿着它追查问题时,经验会告诉你在特定情况下追查到什么程度就应该停止了。经验会告诉你什么时候问题的原因已经被锁定到一个很小的方位内。你会知道怎样做一个好的调试人员。评判标准不是多块地提出一个猜测,也不是猜测得有多好,而是尽可能少地按错误的猜测行动。

5.3 修复间歇性问题

在调试间歇性bug时,观察底层的失败细节有另外有一个好处。观察到底层失败细节后,当你认为已经修复bug时,很容易就证明确实已经修复了。因为通过底层细节我们可以了解到问题的根本原因是什么。

5.4 对系统进行插装

插装是硬件系统中常用的工具。通俗来讲就是一些能帮助我们观察内部行为的工具。
在硬件中插装工具工具可能是LED和状态显示器,他们可以帮助我们研究电路的内部。还有温度感应器,可以查看CPU温度。在软件领域最初级的内置插装策略就是以调试模式编译,这样就可以通过源码调试器来观察程序的运行。但是正式上线后,就无法使用这种模式了。另外就是通过外部监视器收集各种有意义的变量。收集的状态信息越多,就越有利于调试。但是应该有某种方式有控制选中的消息和消息类型的开关。因为收集消息会使系统发生一些改变,从而对bug造成影响。如果把过多的信息发送到调试窗口,可能会极大的影响系统处理的速度。
ps:即使是简单的打印日志也会让系统的处理速度变慢,但是现在的日志处理框架log4j等已经做得很好了。

5.5 海森堡测不准原理

海森堡原理简单说就是我们不可能同时知道一个粒子的位置和它的速度。这是量子力学的原理之一。具体的情况看wiki吧,作为非专业人士也解释不清楚。相似的说就是我们在系统中添加了调试器会对系统造成影响,但没办法,这是不可避免的。所以我们在通过插装和调试器找到问题修复后,要去掉插装和调试器再次运行确保问题真正解决了。

5.6 猜测只是为了确定搜索的终点目标

不要想,而要看并不意味着不做任何猜想。事实上猜测是好事,我们在做一件事情前应该好好想清楚,然后再去做。当我们理解系统后,你的猜测可能很接近事实,但是猜测只是为了确定搜索的重点。在尝试修复之前,仍要看到问题的失败,确保你的猜测是正确的。如果经过插装后仍然无法确定你的猜测是否正确,那么就回到原点再次猜测。猜测的另一种有效方式是某些问题比其他问题更容易出现,或者比其他问题更易于吸附物,因此首先检查这些问题。这样或许我们足够幸运马上就能找到问题,即使没有也可以快速去掉很多"非正确选项"

5.7 总结

不要想,而要看
凭空想象,问题可能有几千条原因。而实际的原因只有去看了才能发现。

  1. 观察失败。高级工程师看到了真实的问题,并且能够找到原因。而初级工程师认为他们知道错误发生在哪里,结果他们修复的地方根本没有出错。
  2. 查看细节。听到水泵私服发出声音不要停下来。到地下室查明是哪个水泵。
  3. 植入插装工具。使用源码调试器,调试日志,状态消息,信号灯等方法了解系统
  4. 注意海森堡效应。不要让仪器影响了系统
  5. 猜测只是为了确定搜索的终点。大胆猜测内存时序发生了错误,但在修复前应该先查看它。