Systematic Debugging 是一个调试方法论类技能,适用于遇到任何 Bug、测试失败或意外行为、在提出修复方案之前使用。它强调“不要猜,系统调查”的核心原则,并在连续 3 次修复尝试失败后停止,转而质疑架构设计。
第一阶段理解问题:收集期望行为、实际行为、何时开始失败、最近有何变更等信息;稳定复现并创建最小复现用例、记录精确步骤、判断问题是确定性还是偶发;先检查明显项,如服务是否运行、依赖是否安装、环境是否正确、文件是否保存、缓存是否清除。
第二阶段追踪根因:采用反向追踪,从错误值出现的位置向上追溯调用者直到找到源头,并在源头而非症状处修复;寻找同一代码库中相似的可用代码作为参照;逐一列出可用与损坏之间的所有差异,不轻易假设某项“不可能有影响”。
第三阶段形成假设:一次只提一个假设,预测假设成立时会看到什么,设计并运行验证测试,失败则基于新数据重新假设;不并行多假设,不混用调试方法。
第四阶段实施修复:先写会失败的测试,确保修复前失败、修复后通过;每次只做一处改动,不做顺手改进和捆绑重构;完整验证原测试通过、其他测试未被破坏、问题真正解决、边界情况覆盖。
第五阶段修复无效时:每次失败后停止并计数;少于 3 次则回到第一阶段用新信息重新分析;达到或超过 3 次则停下质疑架构,观察是否每次修复都暴露新问题、是否需要大规模重构、是否产生新症状,并追问该模式是否根本合理、抽象是否正确、是否需要重新设计。
技能还给出调试工具建议:日志中加入组件名、方法名、输入、相关状态和时间戳等上下文;二分搜索调试在可疑代码中点加日志,判断问题在前还是在后,逐步隔离;小黄鸭调试法通过口头解释应该发生什么、实际发生什么、尝试过什么、有哪些假设来理清思路。
常见陷阱包括同时改动多处、自以为知道原因、只修症状不修根因、未验证修复是否真正生效、未补充回归测试。危险信号包括“在我机器上是好的”“昨天还好好的”“我什么都没改”“那不可能是问题”。