碰键盘之前
Understand the system.
Read the manual. 不是建议你去翻文档。你动手之前,知不知道信号从哪来、到哪去、中间经过什么?不知道就先停下,改代码的手放开键盘。
Make it fail.
不能稳定复现的 bug,你修的可能根本不是它。"偶发"不是免死金牌。能让它出错,你就在逼近根因;不能,你在碰运气。
Quit thinking and look.
调试效率最大的敌人是你自己的假设。"我觉得应该是那个模块"——然后你花两小时验证一个错误的猜测。打开日志、加断点、看实际数据。先看,再想。
缩小包围圈
Divide and conquer.
系统太大,不知道从哪查?砍一半。上半段正常还是异常?不正常的那半继续砍。二分法在调试里和在算法里一样有效——把搜索空间按对数缩小。
Change one thing at a time.
一次改了三处,问题消失。哪处是关键?不知道。退回去一个一个试?如果能退回去的话。这条规则保护的不是代码——是你对因果关系的控制权。
不要丢线索
Keep an audit trail.
"我刚才试了什么来着?"——说出这句话的那一刻,前面的工作等于白做。写下来。每一步改了什么、观察到什么、结论是什么。调试不是冲刺,是侦查。
Check the plug.
最蠢的原因往往最后才被检查。电源没插、网线松了、环境变量没设、配置文件指错了路径。先排除最简单的可能,再进入复杂分析。Agans 把它单独列成一条规则,因为人的本能是先找复杂原因。
跳出当前视角
Get a fresh view.
找个人听你描述问题。不一定需要对方比你强——你在组织语言把问题讲清楚的过程中,经常自己发现了盲点。这就是"小黄鸭调试法"的正式版。
If you didn't fix it, it ain't fixed.
问题消失不等于被修复。重启之后好了?那不叫修好,叫掩盖。验证到根因级别:你能解释为什么之前坏、为什么现在好、为什么以后不会再坏。三个问题都答得上来,才算修完。