用途
Code Review Checklist 是一个结构化代码审查清单,用于审查代码变更——无论是 diff、Pull Request 还是单个文件。它的目标是让反馈保持一致、有优先级且可执行,而不是零散或只停留在风格层面。
何时使用
- 在合并前审查 Pull Request 或 diff
- 人类或其他智能体要求“审查这段代码”
- 在打开 PR 之前进行自我审查
- 审计现有文件中的潜在问题
五个维度
按顺序逐一检查每个维度。只有在确实不适用时才跳过某个维度(例如仅文档变更的“性能”),并且要明确说明跳过,而不是默默省略。
1. 正确性
- 变更是否实现了它声称的功能?对照声明的意图(PR 描述、issue、commit message)追踪逻辑。
- 是否处理了边界情况:空输入、null/None、零、负数、空集合、并发访问、差一错误边界?
- 错误路径是否真正处理了错误,还是只是吞掉/记录日志后静默继续?
- 是否引入了回归?要与之前的行为做 diff 对比,而不只是孤立地看新代码。
- 是否存在逻辑反转(== 与 !=、&& 与 ||、包含与排除边界)?
2. 安全性
- 不可信输入:来自用户、网络请求、文件或环境变量的内容,是否未经净化就被插入到 shell 命令、SQL 查询、HTML 模板或文件路径中?
- 密钥:是否有硬编码的凭据、令牌或密钥——包括测试夹具或注释中的?
- 授权:变更是否在操作前检查权限/所有权,还是信任客户端提供的 ID?
- 依赖风险:是否新增了第三方依赖?如果有,它是否被维护且范围合理?
- 需要显式扫描的注入类别:命令注入、SQL 注入、路径遍历、SSRF、日志注入(未净化值写入日志,之后被运维人员 grep/粘贴),以及用作供应链载体的未固定/可变 CI Action 标签。
3. 性能
- 对生产环境可能很大的集合,是否存在明显二次方或更差的运算(对同一数据集嵌套循环、重复线性扫描)?
- N+1 查询模式(循环中每次迭代发起一次 DB/API 调用,而不是批量处理)?
- 无界增长:变更是否引入了没有淘汰或大小上限的缓存、缓冲区或累加器?
- 昂贵操作(网络调用、磁盘 I/O、加密)是否位于热路径上,而本可以记忆化、批处理或移出热路径?
4. 可读性与可维护性
- 对这段代码陌生的人,仅凭 diff 和命名能否理解变更,而不需要作者的上下文?
- 变更是否聚焦于单一关注点,还是把重构与新行为混在一起(使 diff 更难审查和回滚)?
- 命名是否准确且具体(不是 data、temp、handleStuff)?
- 是否留下死代码、注释掉的代码块或残留调试输出(console.log、print、pdb.set_trace())?
- 是否遵循文件/仓库现有约定(格式、错误处理风格、模块布局),而不是不一致地引入新约定?
5. 测试覆盖
- 变更是否包含针对新行为的测试,还是只覆盖了正常路径?
- “正确性”中识别出的边界情况是否真的被测试覆盖,而不只是在注释中提及?
- 如果修复的是 bug,是否有本可以捕获它的回归测试——即新测试在旧代码上失败、在新代码上通过?
- 现有测试是否仍然通过?变更是否悄悄削弱了断言以使其通过(例如放宽严格相等检查,或添加宽泛的 try/except: pass)?
输出格式
生成摘要,而不是逐行检查的转录:
## Code Review: <file/PR>
**Correctness**: <发现或“no issues found”>
**Security**: <发现或“no issues found”>
**Performance**: <发现或“no issues found”>
**Readability**: <发现或“no issues found”>
**Test Coverage**: <发现或“no issues found”>
### Priority Actions
1. <最高优先级修复,带 file:line>
2. <下一优先级>
...
- 按实际风险/影响排序,而不是按发现来自哪个维度排序。
- 每个发现都要引用 file:line——没有位置的审查评论不可执行。
- 区分阻塞性问题(正确性 bug、安全漏洞、缺失关键测试)与建议(风格、次要可读性细节)——不要让细节淹没真正的缺陷。
- 永远不要评论 linter/formatter 已自动强制执行的格式问题。
应避免的反模式
- 橡皮图章:没有对照声明意图追踪至少变更的逻辑路径就批准。
- 只做风格审查:标记命名/格式,却遗漏同一 diff 中真正的正确性或安全缺陷。
- 模糊反馈:“这可以更干净”,却没有具体替代方案。
- 孤立审查:不阅读足够上下文就判断一个 diff 块,不知道它在实际环境中是否正确。