收获: 先看文档,再看代码,再理解输入处理输出 要有自己的调试环境 不要猜,要看
1. 理解系统
含义: 调试前先搞清楚系统正常是怎么工作的。包括阅读文档、源码、接口说明、时序、依赖关系、数据流。
核心思想: 只有知道“正常应该是什么样”,你才看得出“哪里不正常”。书评中特别强调,理解系统也是“在不破坏别的地方前提下修复 bug”的前提。
我的理解:
很多人调试慢,不是因为不会用工具,而是因为对系统理解不完整。比如:
- 不清楚调用链
- 不知道输入输出边界
- 不理解缓存、异步、重试、并发等机制
实践动作:
- 先画模块图/调用链
- 明确“输入 → 处理 → 输出”路径
- 确认正常值范围、异常表现和关键依赖
2. 制造失败
含义: 必须能稳定复现问题。
书评中把这一条直接概括为 Reproduce,并指出:如果你没有在原始失败条件下验证,所谓“修好了”很可能只是碰巧没再触发。
核心思想:
- 先复现,再修复
- 修复后还要用同样条件回归验证
- 能把偶发问题尽量变成高概率问题
实践动作:
- 固定环境、输入、版本、参数、数据集
- 提高触发概率:压测、并发、边界输入、特定时序
- 建立最小复现场景
一句话记忆:
不能稳定复现,就很难证明你真的修好了。
3. 不要想,而要看
含义: 不要只靠脑补原因,要去观察真实发生了什么。
书评中强调,“猜测失败如何发生”常常会让人修错地方;观察日志、状态、数据变化、执行路径,通常比猜更快接近根因。
核心思想:
- 现象优先于猜测
- 证据优先于经验
- 看到实际的数据流、控制流、状态变化
实践动作:
- 打日志、抓包、trace、profile
- 看变量真实值,不靠想象
- 看调用栈、内存、寄存器、时间线
- 对比“正常样本”和“失败样本”
常见误区:
- “我觉得一定是这里”
- “上次也是这个原因”
- “理论上不会这样”
4. 分而治之
含义: 通过把问题空间不断二分,快速缩小搜索范围。
资料中将其概括为:把问题反复拆成“好的一半”和“坏的一半”,逐步锁定故障区域。
核心思想:
- 不要全局乱查
- 先判断问题在前端/后端、上游/下游、框架/业务、主流程/边缘逻辑哪一边
- 每次排除一半,比漫无目的试更快
实践动作:
- 模块隔离
- 二分注释/二分开关
- 中间结果校验
- 用 mock 或替身组件切断链路
适合你的场景:
比如算子/内核问题,可以先分:
- 是编译期还是运行期
- 是 host 侧还是 device 侧
- 是输入构造错还是 kernel 实现错
- 是特定 shape 才错还是普遍都错
5. 一次只改一个地方
含义: 调试时不要一次改很多处,否则你不知道到底是哪一个改动起了作用。
核心思想:
- 控制变量
- 让“原因—结果”保持可解释
- 若改动无效,尽快回退,避免引入新扰动
实践动作:
- 一次只动一个变量/一个 patch/一个参数
- 每次改动后立即验证
- 无效改动及时 revert
常见误区:
- 一口气改 5 个地方,然后“居然好了”
- 结果下次又坏了,根本不知道真正原因是什么
6. 保持审计跟踪
含义: 记录你做过什么、看到什么、哪一步开始变化。
书评提到,很多 bug 能通过 revision history、复现录像、变更记录找到线索,并强调不要相信记忆,要把细节写下来。
核心思想:
- 调试过程要可回溯
- 记录是为了自己,也为了团队复盘
- 今天看似无关的细节,明天可能就是关键证据
实践动作:
- 记录版本号、commit、环境、依赖
- 保存日志、截图、trace、profile
- 写调试 diary:做了什么、结果如何、结论是什么
一句话记忆:
没有记录的调试,等于重复劳动。
7. 检查插头
含义: 先排除最基础、最蠢但最常见的问题。
书评直接点明:“插头插上了吗?”这种问题看似愚蠢,但非常常见。它也延伸到拼写错误、配置错误、路径错误、环境错误这类低级失误。
核心思想:
- 不要把简单问题复杂化
- 先查最可能、最廉价、最基础的原因
实践动作:
- 检查输入是否正确
- 检查配置、路径、权限、环境变量
- 检查版本匹配、依赖安装、服务是否启动
- 检查函数名、参数名、字段名、单位、类型
很适合工程里的 checklist:
- 端口通了吗
- 代理配置对吗
- 文件真存在吗
- 编译产物是最新的吗
- 运行的到底是不是你刚编出来的版本
8. 获得全新观点
含义: 卡住时,不要一个人死磕,去找别人帮你看。
书评指出,寻求帮助的价值在于获得新的视角、专业知识和经验,而别人往往也愿意帮忙。
核心思想:
- 你会被自己的假设困住
- 别人更容易发现你忽略的前提
- 讲清楚问题本身,也能帮助你理顺思路
实践动作:
- 做一个简洁的问题说明
- 说明“现象、复现步骤、已排除项、怀疑点”
- 请别人 review 日志、代码、复现过程
补充理解:
这和“橡皮鸭调试”很像。你把问题完整讲一遍,经常自己就发现漏洞了。
9. 如果不修复 bug,它将依然存在
含义: 不要自欺欺人。问题没真正修复,只是暂时没出现。
这条规则强调:必须确认根因被解决,而不是表面现象被掩盖。
核心思想:
- 区分“消失”与“修复”
- 区分“绕过去”与“解决掉”
- 修复后要验证根因链条是否闭合
实践动作:
- 回到原始复现步骤重新验证
- 做回归测试和边界测试
- 确认不会引入新的问题
- 能解释“为什么现在不会再发生”
一句话记忆:
bug 不会因为你不看它就自己消失。