第 9 章:调试与排错 — 遇到 bug 不要慌
💡 进群学习加 wx: agentupdate
(申请发送: agentupdate)
(申请发送: agentupdate)
你将学到什么
- 用 superpowers 的
/systematic-debugging科学方法调试 - 用 gstack 的
/investigate调查代码问题 - 模拟一个真实 bug 的完整调试过程
9.1 调试不是瞎猜
很多开发者调试的方式是:改一下试试、再改一下再试试。这不叫调试,叫碰运气。
科学的调试方法:
flowchart TB
A["1. 复现
稳定地触发 bug"] --> B["2. 假设
猜 bug 在哪里"]
B --> C["3. 验证
用测试或日志确认"]
C --> D{"假设正确?"}
D -- "是" --> E["4. 修复"]
D -- "否" --> B
E --> F["5. 回归测试
确认修复没改坏别的"]
style A fill:#fecaca,stroke:#dc2626
style E fill:#dcfce7,stroke:#16a34a
style F fill:#dbeafe,stroke:#2563eb9.2 /systematic-debugging — 科学方法调试
命令语法
/systematic-debugging [bug 描述]
实战:模拟一个真实 bug
Bug 描述: 用户报告"搜索功能有时找不到明明存在的笔记"。
/systematic-debugging
Bug:搜索笔记时,某些情况下搜索不到应该存在的结果。
复现步骤:
1. 创建一条笔记,标题"工作计划"
2. 再创建一条,标题"项目计划"
3. 搜索"计划"
4. 预期:显示两条笔记
5. 实际:有时只显示一条,有时显示两条
环境:React 18 + Chrome 120
Claude 会做什么:
- 复现 — 读取搜索相关代码,理解搜索逻辑
- 假设 — 分析可能的原因
- 验证 — 通过代码审查或测试确认
- 修复 — 提供修复方案
调试过程
第 1 步:复现
Claude 读取 useSearch.js 和 search.js:
// src/hooks/useSearch.js
export function useSearch(notes, query) {
return useMemo(() => filterNotes(notes, query), [notes, query]);
}
第 2 步:假设
可能的原因:
- A)
useMemo依赖项不对,notes引用变化导致缓存失效- B)
filterNotes函数有 bug- C) 搜索时机问题:笔记还没加载完就搜索了
第 3 步:验证
Claude 检查 useNotes Hook:
// src/hooks/useNotes.js
export function useNotes() {
const [notes, setNotes] = useState(() => loadNotes());
const addNote = (note) => {
const updated = [...notes, note]; // ← 这里!
setNotes(updated);
saveNotes(updated);
};
// ...
}
发现问题: addNote 使用 notes 闭包变量而不是函数式更新。如果快速连续添加笔记,notes 可能是旧值。
第 4 步:修复
// 修复前
const addNote = (note) => {
const updated = [...notes, note];
setNotes(updated);
saveNotes(updated);
};
// 修复后
const addNote = (note) => {
setNotes(prev => {
const updated = [...prev, note];
saveNotes(updated);
return updated;
});
};
第 5 步:回归测试
npm test
全部通过。再加一个测试覆盖这个场景:
test('快速连续添加笔记不会丢失', () => {
const { result } = renderHook(() => useNotes());
act(() => {
result.current.addNote({ id: '1', title: 'A' });
result.current.addNote({ id: '2', title: 'B' });
});
expect(result.current.notes).toHaveLength(2);
});
9.3 /investigate — gstack 代码调查
命令语法
/investigate [调查目标]
gstack 的 investigate 更偏向"理解代码为什么这样写",适合排查复杂的历史问题。
实战:调查搜索性能
/investigate NoteFlow 搜索功能在笔记数量多时的性能表现
调查结果:
发现:
NoteList.jsx使用Array.map()渲染所有笔记,没有虚拟滚动
- 100 条笔记:正常
- 500 条笔记:渲染延迟约 200ms
- 1000 条笔记:渲染延迟约 500ms,输入卡顿
useSearch的useMemo缓存有效,搜索本身不是瓶颈瓶颈在 DOM 渲染,不在搜索逻辑
建议:
- 短期:限制列表渲染数量(最多显示 50 条,加"加载更多")
- 长期:引入虚拟滚动库(如
react-window)
9.4 两个命令怎么配合
flowchart LR
A["遇到 bug"] --> B{什么类型?}
B -- "逻辑错误
结果不对" --> C["/systematic-debugging
科学方法找 bug"]
B -- "性能问题
运行慢" --> D["/investigate
调查瓶颈"]
B -- "不确定" --> C
C --> E["修复 + 回归测试"]
D --> E
style C fill:#dbeafe,stroke:#2563eb
style D fill:#fef3c7,stroke:#d97706简单判断:
- 功能不对(搜索结果错误、数据丢失)→
/systematic-debugging - 性能不好(卡顿、慢)→
/investigate - 不知道怎么了 → 先
/systematic-debugging,排除逻辑问题
动手做
- 故意引入一个 bug:在
useNotes.js中把函数式更新改回闭包方式 - 运行
/systematic-debugging,描述搜索结果偶发丢失的 bug - 观察 Claude 的调试过程:复现 → 假设 → 验证 → 修复
- 运行
/investigate调查 NoteFlow 的性能瓶颈 - 全量测试确认修复有效
本章小结
| 命令 | 来源 | 适合场景 |
|---|---|---|
/systematic-debugging |
superpowers | 逻辑 bug、结果不正确 |
/investigate |
gstack | 性能问题、代码调查 |
核心原则: 调试不是猜,是科学实验。复现 → 假设 → 验证 → 修复 → 回归测试,每步都有依据。