建议阅读时间:2分钟
定律1:最难定位的问题要么是最疑难的问题,要么是最低级的问题,这两种问题都有一个共同特征,就是让你意想不到。
举一个例子,一次代码编译不过,报函数没有定义,开始怀疑是类没有“;”结束符,然后怀疑有没有匹配的“{”,折腾了好久,最后才发现是开头的“#ifndef”定义的符号与别的文件重复了,导致整个文件没有生效,报函数未定义错误,都是CtrlC、CtrlV惹的祸啊!
低级问题要靠良好的习惯和必要的排查手段来避免。比如写代码时,敲{的时候,自发地把}也敲出来,包括换行缩进。再如写完代码之后做一下pc-lint,就可以避免函数结束没有return,有的case分支没有break等错误,而这样的错误我经常看到有同事使用gdb进行跟踪定位。
定律2:当非常奇怪的问题发生时,通常是犯了低级错误。
一次执行mv时报命令找不到,郁闷死了,“shit,操作系统被破坏了,连mv都找不到了”,过了一会才发现,原来自己正在windows下的cmd窗口中操作。
定律3:一开始陷得越深,越是难找到问题的真相。
定位问题时先从整体和外部入手,然后再进入细节和内部。郭佳俊的分享:程序设计要遵循“攘外必先安内”,而问题定位则反之,“安内必先攘外”。
定律4:线索明确了,但问题没有定位出来,通常是你钻的不够深。
定律5:程序师能力的高下,通过问题(错虫)能否快速定位(清除)立见分晓。
定律6:长时间找不到问题原因时,做些别的事情再回来,也许就找到问题了。
别的事情例如打一杯水。张伟的分享“当你长时间无法定位问题的时候,尝试向你的同事描述这个问题,经常讲着讲着会突然自己就找到问题了”就是很好的例子。其原理就是阿基米德与酝酿效应。
平时增强探索能力,比如玩一些探索性的游戏,看看探索频道,也是很好的锻炼。
定律7:软件问题99.%都是可以必然重现的。
定律8:一开始就被认定是硬件问题的问题,有可能是软件问题。
定律9:最笨但是最有效,也最简单,但是很多人不用,用了还用不好的定位问题方法就是正交分解法。
其实就是分割法。一个复杂的问题来了,你总有怀疑的地方,把怀疑的地方一个一个排除掉,就是这个方法。正交分解法本身来源于田口法。把一个事情的原因分成几个正交的原因,这样你可以一次试验就可以验证多个原因是否是主要原因。这样可以提高定位问题的效率。但是很多人都觉得这个办法比较笨所以不用,还有一些人在用正交分解的时候把握不好,没有完全正交,所以会出现误判,失去了定位问题的机会。还有一些人,不坚信这个方法,用一用的就放弃了,最有一个情况没有验证,也会错过问题定位的方法。
定律10:问题不会自己消失的,出现过的问题一定会再次重现的。
这个定律给我们的启示是不要存在侥幸心理,问题出现了要在第一时间解决,否则后续问题重现时成本会非常高。我就亲身体验过一个问题在半年前就出现过了,没有定位出来,后来花了很大力气才解决了。
定律11:出现问题时,我们往往更倾向于怀疑自己不太熟悉的领域。
比如,做上层软件的人,倾向于怀疑是驱动的问题;做驱动的人,倾向于怀疑是上层软件的问题。
定律12:同样的用例,以前没有出现问题,最近出现了,通常与最近的修改有关。
定律13:问题定位越晚,花费的时间越多,定位的成本越高。
给我们的启示是,问题出现了要尽早定位,要在第一时间重现,不要拖延。我们经常因为没有及时定位,后续版本要发布了,问题不得不处理,这时原来的测试环境没有了,又重新搭环境重现。
定律14:再次怀疑曾经放弃(排除)的疑点通常需要很长的时间。
一种情况被排除之后,我们很少会再次考虑这种情况,通常要经过对其他情况的多次尝试才会根据可疑信息再次返回到这种情况,因此一开始就处理复杂的情况,效率会比较低。给我们的启示是,定位问题要由浅入深,先排除简单的情况;不要轻易排除一个可疑点。