code-review-checklist
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Review Checklist
代码评审检查清单
Review Philosophy
评审理念
A code review is a collaborative conversation, not a gatekeeping exercise. The goals are:
- Catch bugs before they reach production.
- Share knowledge across the team.
- Maintain consistency in style and architecture.
- Improve the code incrementally.
Review the code, not the author. Be specific, be kind, and suggest alternatives rather than only pointing out problems.
代码评审是协作式的沟通,而非把关式的流程。目标如下:
- 在代码上线前发现bug。
- 在团队内共享知识。
- 保持风格与架构的一致性。
- 逐步改进代码质量。
评审的是代码,而非开发者本人。给出具体意见,保持友善,多提出替代方案而非仅指出问题。
Severity Classification
严重程度分类
Classify every comment to set expectations:
| Severity | Meaning | Action Required |
|---|---|---|
| Blocker | Bug, security flaw, data loss risk, or broken build. | Must fix before merge. |
| Major | Design issue, missing test, or significant maintainability concern. | Should fix before merge. |
| Minor | Style inconsistency, naming nit, or small improvement. | Fix if convenient; OK to defer. |
| Suggestion | Alternative approach, future improvement idea, or "did you consider...?" | No action required. |
Prefix comments with the severity: , , , .
[Blocker][Major][Minor][Suggestion]为每条评论划分严重程度,明确预期要求:
| 严重程度 | 含义 | 所需操作 |
|---|---|---|
| 阻塞(Blocker) | 存在bug、安全漏洞、数据丢失风险或构建失败。 | 合并前必须修复。 |
| 主要问题(Major) | 设计问题、缺少测试或重大可维护性问题。 | 合并前应修复。 |
| 次要问题(Minor) | 风格不一致、命名细节问题或小的改进点。 | 方便时修复;可延后。 |
| 建议(Suggestion) | 替代方案、未来改进想法或“你是否考虑过...?” | 无需强制修复。 |
在评论前添加严重程度前缀:、、、。
[Blocker][Major][Minor][Suggestion]1. Correctness Checklist
1. 正确性检查表
Does the code do what it is supposed to do?
- Requirements met. Does the change implement the described feature or fix the described bug completely?
- Edge cases handled. What happens with null, empty, zero, negative, very large, or unexpected inputs?
- Error handling. Are exceptions caught at the right level? Are error messages helpful? Do errors propagate correctly?
- Return values. Are all code paths returning the correct type and value? Are there missing returns?
- Off-by-one. Are loop bounds, array indices, and string slices correct? Inclusive vs. exclusive?
- Type safety. Are types correct? Are there implicit coercions that could cause surprises (e.g., )?
"1" + 1 - Concurrency. If concurrent, are shared resources protected? Are there potential race conditions or deadlocks?
- Data integrity. Are database transactions used where needed? Is there a risk of partial writes?
- Backward compatibility. Does this change break existing callers, APIs, or stored data?
- Idempotency. If the operation is retried, does it produce the same result?
代码是否实现了预期功能?
- 满足需求:变更是否完整实现了描述的功能或修复了描述的bug?
- 处理边界情况:当输入为null、空值、零、负数、超大值或非预期值时,代码表现如何?
- 错误处理:异常是否在合适的层级被捕获?错误提示是否清晰有用?错误是否正确传播?
- 返回值:所有代码路径是否返回了正确的类型和值?是否存在遗漏的返回逻辑?
- 边界索引问题:循环范围、数组索引和字符串切片是否正确?是包含式还是排除式?
- 类型安全:类型是否正确?是否存在可能导致意外结果的隐式类型转换(如)?
"1" + 1 - 并发处理:若涉及并发,共享资源是否受到保护?是否存在潜在的竞态条件或死锁?
- 数据完整性:是否在需要的地方使用了数据库事务?是否存在部分写入的风险?
- 向后兼容性:该变更是否会破坏现有的调用方、API或存储的数据?
- 幂等性:若操作被重试,是否会产生相同的结果?
2. Readability Checklist
2. 可读性检查表
Can a new team member understand this code without asking the author?
- Naming. Do variable, function, and class names clearly express their purpose? Avoid abbreviations unless universally understood.
- Function length. Are functions short enough to understand at a glance (under 20-30 lines)? If not, can they be decomposed?
- Single responsibility. Does each function do one thing? Does each class have one reason to change?
- Comments. Are comments explaining WHY, not WHAT? Is there dead commented-out code that should be removed?
- Complexity. Are nested conditionals minimized? Can guard clauses replace deep nesting?
- Consistency. Does the code follow existing patterns and conventions in the codebase?
- Magic values. Are there unexplained numbers or strings? Should they be named constants?
- Code flow. Can you follow the execution path without jumping around? Is control flow straightforward?
- Formatting. Is indentation, spacing, and line length consistent with the project style?
- Dead code. Is there unreachable code, unused imports, or unused variables?
新团队成员无需询问作者就能理解这段代码吗?
- 命名规范:变量、函数和类的名称是否清晰表达了其用途?除非是通用缩写,否则避免使用缩写。
- 函数长度:函数是否足够简短(20-30行以内),便于一眼理解?如果不是,能否拆分?
- 单一职责:每个函数是否只做一件事?每个类是否只有一个变更理由?
- 注释规范:注释是否解释了“为什么”而非“是什么”?是否存在应删除的已注释掉的无效代码?
- 复杂度控制:嵌套条件是否已最小化?能否用卫语句替代深层嵌套?
- 一致性:代码是否遵循代码库中已有的模式和约定?
- 魔法值:是否存在未解释的数字或字符串?是否应将其定义为命名常量?
- 代码流程:能否不跳转就跟上执行路径?控制流是否直观?
- 格式规范:缩进、空格和行长度是否与项目风格一致?
- 无效代码:是否存在不可达代码、未使用的导入或未使用的变量?
3. Maintainability Checklist
3. 可维护性检查表
Will this code be easy to change six months from now?
- DRY (Don't Repeat Yourself). Is there duplicated logic that should be extracted into a shared function?
- Coupling. Is the code tightly coupled to specific implementations? Could dependency injection improve flexibility?
- Abstraction level. Are high-level and low-level concerns mixed? (e.g., business logic mixed with SQL queries or HTTP handling)
- Configuration. Are environment-specific values (URLs, timeouts, thresholds) configurable rather than hardcoded?
- Module boundaries. Does the change respect existing module/package boundaries? Does it introduce circular dependencies?
- API design. Are public interfaces minimal and well-defined? Can internal details change without affecting callers?
- Migration path. If this changes a schema, API, or data format, is there a migration plan?
- Documentation. Are public APIs documented? Are complex algorithms explained?
- Deprecation. If replacing old code, is the old code marked as deprecated with a removal timeline?
- Feature flags. For risky or incremental changes, should the new behavior be behind a feature flag?
六个月后,这段代码是否容易修改?
- DRY原则(避免重复):是否存在应提取到共享函数中的重复逻辑?
- 耦合度:代码是否与特定实现紧密耦合?依赖注入能否提升灵活性?
- 抽象层级:是否混合了高层和低层关注点?(例如,业务逻辑与SQL查询或HTTP处理混合)
- 配置管理:环境特定的值(URL、超时时间、阈值)是否可配置,而非硬编码?
- 模块边界:变更是否尊重现有的模块/包边界?是否引入了循环依赖?
- API设计:公共接口是否简洁且定义清晰?内部细节变更是否不会影响调用方?
- 迁移方案:如果变更了 schema、API 或数据格式,是否有迁移计划?
- 文档完善:公共API是否有文档?复杂算法是否有说明?
- 废弃标记:如果替换旧代码,是否已将旧代码标记为废弃并给出移除时间线?
- 功能开关:对于有风险或增量式的变更,是否应将新行为放在功能开关后?
4. Security Checklist
4. 安全性检查表
Could this code be exploited by a malicious actor?
- Input validation. Is all user input validated and sanitized before use?
- SQL injection. Are database queries parameterized? No string concatenation for SQL.
- XSS (Cross-Site Scripting). Is user-generated content escaped before rendering in HTML?
- CSRF (Cross-Site Request Forgery). Are state-changing endpoints protected with CSRF tokens?
- Authentication. Are protected routes/resources properly gated behind authentication?
- Authorization. Does the code verify the user has permission to access/modify the specific resource?
- Secrets. Are API keys, passwords, or tokens hardcoded? They should be in environment variables or a secrets manager.
- Logging. Are sensitive data (passwords, tokens, PII) excluded from logs?
- Dependency vulnerabilities. Are new dependencies from trusted sources? Have they been audited?
- File handling. Are uploaded files validated for type and size? Are paths sanitized to prevent directory traversal?
- Rate limiting. Are public-facing endpoints protected against abuse?
- HTTPS. Are external API calls using HTTPS? Are certificates validated?
恶意攻击者能否利用这段代码?
- 输入验证:所有用户输入在使用前是否经过验证和清理?
- SQL注入防护:数据库查询是否使用参数化?是否存在通过字符串拼接构造SQL的情况?
- XSS(跨站脚本)防护:用户生成的内容在HTML中渲染前是否经过转义?
- CSRF(跨站请求伪造)防护:状态变更的接口是否通过CSRF令牌进行保护?
- 身份验证:受保护的路由/资源是否正确通过身份验证进行管控?
- 授权验证:代码是否验证了用户是否有权访问/修改特定资源?
- 密钥管理:API密钥、密码或令牌是否被硬编码?它们应存储在环境变量或密钥管理工具中。
- 日志规范:日志中是否排除了敏感数据(密码、令牌、个人可识别信息)?
- 依赖漏洞:新引入的依赖是否来自可信源?是否经过审计?
- 文件处理:上传的文件是否经过类型和大小验证?路径是否经过清理以防止目录遍历攻击?
- 限流防护:面向公网的接口是否有防滥用的限流措施?
- HTTPS使用:外部API调用是否使用HTTPS?证书是否经过验证?
5. Performance Checklist
5. 性能检查表
Will this code perform acceptably under expected load?
- Algorithmic complexity. Is the algorithm appropriate for the data size? Is O(n^2) acceptable here?
- Database queries. Are queries indexed? Are there N+1 query problems? Are results paginated?
- Caching. Should results be cached? If caching exists, is invalidation handled correctly?
- Payload size. Are API responses, database fetches, or file reads bounded in size?
- Lazy loading. Are expensive resources loaded only when needed?
- Connection pooling. Are database/HTTP connections pooled and reused, not created per request?
- Async / non-blocking. Are I/O operations non-blocking where appropriate? Are there unnecessary s on non-dependent operations?
await - Memory. Are large data sets streamed rather than loaded entirely into memory?
- Startup impact. Does this change slow down application startup?
- Monitoring. Are new critical code paths instrumented with metrics or tracing?
在预期负载下,这段代码的性能是否可接受?
- 算法复杂度:算法是否适合当前的数据规模?O(n^2)的复杂度是否可接受?
- 数据库查询:查询是否有索引?是否存在N+1查询问题?结果是否分页?
- 缓存策略:结果是否应该被缓存?如果已有缓存,缓存失效逻辑是否正确?
- 负载大小:API响应、数据库查询或文件读取的大小是否有上限?
- 懒加载:昂贵的资源是否仅在需要时才加载?
- 连接池:数据库/HTTP连接是否使用连接池复用,而非每个请求创建新连接?
- 异步/非阻塞:I/O操作是否在合适的场景下使用非阻塞模式?是否在不相关的操作上存在不必要的?
await - 内存使用:大数据集是否采用流式处理,而非全部加载到内存中?
- 启动影响:该变更是否会减慢应用启动速度?
- 监控埋点:新的关键代码路径是否添加了指标或链路追踪?
6. Testing Checklist
6. 测试检查表
Is the change adequately tested?
- Tests exist. Does every new behavior have at least one test?
- Tests pass. Do all tests pass in CI? Have you run them locally?
- Happy path tested. Are the primary use cases covered?
- Edge cases tested. Are boundary values, empty inputs, and error conditions tested?
- Regression test. If this is a bug fix, is there a test that would have caught the bug?
- Test quality. Do tests assert on behavior, not implementation details?
- Test isolation. Do tests run independently? No shared mutable state between tests?
- Test readability. Can you understand what each test verifies from its name and body?
- Mocking. Are mocks used judiciously? Are they mocking the right boundaries (I/O, not business logic)?
- Coverage. Is coverage maintained or improved? Are critical paths covered?
- Flakiness. Do new tests depend on timing, external services, or non-deterministic data?
变更是否得到了充分的测试?
- 存在测试:每个新行为是否至少有一个对应的测试?
- 测试通过:所有测试在CI中是否通过?你是否在本地运行过测试?
- 主流程测试:主要使用场景是否被覆盖?
- 边界情况测试:边界值、空输入和错误场景是否被测试?
- 回归测试:如果是bug修复,是否有能捕获该bug的测试?
- 测试质量:测试是否断言行为而非实现细节?
- 测试隔离:测试是否独立运行?测试之间是否没有共享的可变状态?
- 测试可读性:从测试的名称和内容能否理解它要验证的内容?
- Mock使用:Mock是否被合理使用?是否在正确的边界(I/O而非业务逻辑)上使用Mock?
- 测试覆盖率:覆盖率是否保持或提升?关键路径是否被覆盖?
- 测试稳定性:新测试是否依赖于时序、外部服务或非确定性数据?
How to Give Constructive Feedback
如何给出建设性反馈
Do
建议做法
- Be specific. Point to exact lines. Explain the problem concretely.
- Explain why. Not just "change this" but "this could cause X because Y."
- Suggest alternatives. Provide a code snippet or link to a pattern.
- Ask questions. "What happens if X is null here?" is better than "You forgot a null check."
- Acknowledge good work. Call out clever solutions, clean refactoring, or good test coverage.
- Distinguish severity. A nit is not a blocker. Label them differently.
- Offer to pair. If the change is complex, offer to discuss live.
- 具体明确:指向具体代码行,具体解释问题。
- 说明原因:不只是“修改这个”,而是“这可能导致X问题,因为Y”。
- 给出替代方案:提供代码片段或模式链接。
- 提出问题:“如果X为null会发生什么?”比“你忘了做空值检查”更好。
- 认可优秀工作:指出巧妙的解决方案、清晰的重构或完善的测试覆盖。
- 区分严重程度:细节问题不是阻塞问题,要区分标记。
- 提供结对支持:如果变更复杂,主动提出实时讨论。
Do Not
避免做法
- Do not attack the person. "This code is bad" vs. "This function could be simplified by..."
- Do not bikeshed. Do not block a PR over trivial style preferences that are not in the style guide.
- Do not pile on. If another reviewer already made a point, a thumbs-up is enough.
- Do not be vague. "This is confusing" is not actionable. Say what is confusing and why.
- Do not rewrite. If you would rewrite the entire approach, have a conversation first — do not do it through line comments.
- 不攻击个人:不说“这段代码很差”,而是“这个函数可以通过...来简化”。
- 不纠结小事:不要因为风格指南中没有规定的琐碎偏好而阻塞PR。
- 不重复评论:如果其他评审者已经提出了相同观点,点赞即可。
- 不模糊表述:“这很混乱”没有可操作性,要说明哪里混乱以及原因。
- 不直接重写:如果你想完全重写实现,先进行沟通,不要通过行内评论直接修改。
Comment Templates
评论模板
[Blocker] Bug: `items.length` will throw if `items` is null.
Consider adding a null check: `if (!items?.length) return [];`
[Major] Missing test: This new validation logic does not have
a corresponding test for the rejection case.
[Minor] Naming: `d` is ambiguous. Consider `durationMs` or
`elapsedDays` to clarify the unit.
[Suggestion] You could use `Array.flatMap()` here to combine
the map and filter into one pass. Not required though.[Blocker] Bug: `items.length` 在 `items` 为null时会抛出错误。
建议添加空值检查:`if (!items?.length) return [];`
[Major] 缺少测试:这个新的验证逻辑没有对应的拒绝场景测试。
[Minor] 命名问题:`d` 含义模糊,建议改为 `durationMs` 或
`elapsedDays` 以明确单位。
[Suggestion] 你可以在这里使用 `Array.flatMap()`,将map和filter合并为一次遍历。非强制要求。Reviewer Responsibilities
评审者职责
- Respond to review requests within one business day.
- Review the full diff, not just the files you are familiar with.
- Pull the branch and run it locally for non-trivial changes.
- Check CI results before approving.
- Re-review after changes are made to your feedback.
- Approve explicitly when satisfied; do not leave PRs in limbo.
- 在一个工作日内响应评审请求。
- 评审完整的代码差异,而非仅你熟悉的文件。
- 对于非 trivial 的变更,拉取分支并在本地运行测试。
- 批准前检查CI结果。
- 针对你提出的反馈,在变更后重新评审。
- 满意时明确批准;不要让PR处于悬而未决的状态。
Author Responsibilities
提交者职责
- Self-review your diff before requesting review.
- Keep PRs small (under 400 lines of meaningful changes).
- Write a clear PR description explaining what, why, and how.
- Link to the issue or spec being implemented.
- Respond to all comments, even if just "Done" or "Acknowledged."
- Do not merge until all blocker/major comments are resolved.
- Squash fixup commits before merging if the project convention requires it.
- 在请求评审前,先自行评审代码差异。
- 保持PR规模较小(有意义的变更不超过400行)。
- 编写清晰的PR描述,说明变更内容、原因和实现方式。
- 关联对应的需求issue或实现规范。
- 回复所有评论,即使只是“已完成”或“已确认”。
- 所有阻塞/主要问题解决前,不要合并PR。
- 如果项目约定要求,合并前压缩修复提交。
Review Workflow
评审工作流程
- Skim first. Read the PR description and get the big picture.
- Architecture pass. Review the overall design and file structure.
- Detailed pass. Go file by file, line by line, applying the checklists above.
- Test pass. Read the tests. Do they cover the right cases?
- Run it. For anything non-trivial, check out the branch and run it.
- Summarize. Leave an overall summary comment with your verdict.
- 先快速浏览:阅读PR描述,了解整体情况。
- 架构评审:评审整体设计和文件结构。
- 详细评审:逐文件、逐行检查,应用上述检查表。
- 测试评审:阅读测试用例,检查是否覆盖了正确的场景。
- 运行验证:对于非trivial的变更,拉取分支并运行测试。
- 总结反馈:留下整体总结评论,给出你的评审结论。