code-review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Review Best Practices
代码审查最佳实践
Core Principles
核心原则
Review Mindset:
- Be constructive, explain the "why"
- Prioritize by severity (critical vs nice-to-have)
- Suggest alternatives, not just problems
- Acknowledge good work
Goals:
- Catch bugs before production
- Improve code quality
- Share knowledge
- Prevent security vulnerabilities
- Ensure consistency
审查心态:
- 保持建设性,解释“原因”
- 按严重程度优先处理(关键问题 vs 锦上添花的优化)
- 提出替代方案,而非仅指出问题
- 认可优秀的代码实现
目标:
- 在代码上线前捕获漏洞
- 提升代码质量
- 共享知识经验
- 防范安全隐患
- 确保代码一致性
Security Review
安全审查
OWASP Top 10 Critical Checks
OWASP Top 10 关键检查项
Injection Attacks:
- SQL: Use parameterized queries, never concatenate user input
- Command: Avoid shell commands with user input, sanitize properly
- Code: Validate all eval(), exec(), dynamic execution
- NoSQL/LDAP/XML: Use safe APIs
Authentication & Authorization:
- Verify auth checks on protected endpoints
- Proper session management (timeout, secure cookies)
- Authorization logic prevents privilege escalation
- Password policies enforced
Sensitive Data:
- No hardcoded secrets (API keys, passwords, tokens)
- Encryption at rest and in transit
- PII/PHI minimally logged
- No sensitive data in URLs or error messages
XSS Prevention:
- All user input escaped/sanitized for output context
- Content-Security-Policy headers configured
- Framework built-in escaping (React JSX, template engines)
Deserialization:
- Never deserialize untrusted data without validation
- Prefer JSON over pickle/marshal
- Validate object types post-deserialization
Misconfiguration:
- No default credentials in production
- Error messages don't leak internals
- Security headers present (HSTS, X-Frame-Options)
API Security:
- Rate limiting on sensitive endpoints
- CORS properly configured
- Input validation on all endpoints
- No sensitive data in GET requests
注入攻击:
- SQL:使用参数化查询,绝不要拼接用户输入
- 命令注入:避免使用包含用户输入的Shell命令,需正确做数据清洗
- 代码注入:验证所有eval()、exec()及动态执行逻辑
- NoSQL/LDAP/XML:使用安全API
身份认证与授权:
- 验证受保护端点的认证检查逻辑
- 合理的会话管理(超时设置、安全Cookie)
- 授权逻辑需防止权限提升
- 强制执行密码策略
敏感数据:
- 禁止硬编码密钥(API密钥、密码、令牌)
- 静态和传输中的数据均需加密
- 最小化PII/PHI数据的日志记录
- 禁止在URL或错误信息中包含敏感数据
XSS防护:
- 所有用户输入需根据输出场景做转义/清洗
- 配置Content-Security-Policy头部
- 利用框架内置的转义机制(React JSX、模板引擎)
反序列化:
- 未验证的不可信数据绝不能反序列化
- 优先使用JSON而非pickle/marshal
- 反序列化后验证对象类型
配置错误:
- 生产环境禁止使用默认凭据
- 错误信息不得泄露内部细节
- 配置必要的安全头部(HSTS、X-Frame-Options)
API安全:
- 敏感端点需设置速率限制
- 正确配置CORS
- 所有端点均需做输入验证
- GET请求中不得包含敏感数据
Common Security Issues
常见安全问题
- Path Traversal: Validate paths, prevent attacks
../ - SSRF: Validate URLs, restrict internal network access
- Open Redirects: Whitelist redirect destinations
- Race Conditions: Check TOCTOU bugs
- Timing Attacks: Constant-time comparison for secrets
- Regex DoS: Avoid complex regex on user input
- 路径遍历: 验证路径,防范攻击
../ - SSRF: 验证URL,限制内部网络访问
- 开放重定向: 白名单允许的重定向目标
- 竞态条件: 检查TOCTOU漏洞
- 时序攻击: 对敏感信息使用固定时间比较
- 正则表达式DoS: 避免对用户输入使用复杂正则
Code Quality
代码质量
Readability & Maintainability
可读性与可维护性
Naming:
- Clear, descriptive names that reveal intent
- Consistent conventions (camelCase, snake_case, PascalCase)
- Avoid abbreviations unless domain-standard
Function Design:
- Single responsibility, small (<50 lines ideal)
- Clear input/output, minimal side effects
- Pure functions where possible
Complexity:
- Low cyclomatic complexity (<10)
- Avoid deep nesting (max 3-4 levels)
- Early returns to reduce nesting
- Extract complex conditions into named functions
Documentation:
- Comments explain "why", not "what"
- Public APIs documented
- No commented-out code (use version control)
命名规范:
- 清晰、表意明确的命名,体现代码意图
- 一致的命名约定(camelCase、snake_case、PascalCase)
- 除非是领域通用缩写,否则避免使用缩写
函数设计:
- 单一职责,函数体量精简(理想情况下少于50行)
- 输入输出清晰,副作用最小化
- 尽可能使用纯函数
复杂度控制:
- 低圈复杂度(<10)
- 避免深层嵌套(最多3-4层)
- 提前返回以减少嵌套层级
- 将复杂条件提取为命名函数
文档规范:
- 注释解释“为什么”,而非“做什么”
- 公开API必须有文档
- 禁止保留注释掉的代码(使用版本控制管理历史代码)
Error Handling
错误处理
- All errors handled (catch, log, recover or fail fast)
- No bare except/catch without handling
- Informative error messages (what, why, action)
- Proper error types (not generic Exception)
- Resources cleaned up (finally/defer/using)
Anti-patterns:
- Swallowing exceptions silently
- Catching too broadly
- Using exceptions for flow control
- Returning null instead of error
- Not validating inputs
- 所有错误均需处理(捕获、日志记录、恢复或快速失败)
- 禁止使用无处理逻辑的bare except/catch
- 错误信息需具备信息量(包含问题、原因、解决建议)
- 使用合适的错误类型(而非通用Exception)
- 资源需正确清理(finally/defer/using语句)
反模式:
- 静默吞掉异常
- 捕获范围过宽
- 使用异常控制流程
- 返回null而非错误对象
- 未做输入验证
Code Duplication
代码重复
- No copy-paste code blocks
- Extract common logic to reusable functions
- Use inheritance/composition appropriately
- Be pragmatic: 3+ copies = refactor time
- 禁止复制粘贴代码块
- 将通用逻辑提取为可复用函数
- 合理使用继承/组合
- 务实原则:重复3次及以上需重构
Performance
性能优化
Algorithm & Data Structure Efficiency
算法与数据结构效率
- Check time complexity (O(n²) → O(n log n) or O(n))
- Appropriate space complexity
- Right data structure (HashMap vs Array, Set vs List)
- Efficient algorithms for common problems
- 检查时间复杂度(O(n²) → O(n log n) 或 O(n))
- 合理的空间复杂度
- 选择合适的数据结构(HashMap vs Array、Set vs List)
- 针对常见问题使用高效算法
Common Issues
常见问题
Database:
- N+1 query problems (use joins/batch)
- Missing indexes on filtered/sorted columns
- SELECT * instead of specific columns
- Queries inside loops
Caching:
- Repeated expensive calculations
- Duplicate API calls
- Static data not cached
- Appropriate cache TTL
Resource Management:
- Files/connections/streams closed
- No memory leaks (circular refs, event listeners)
- Unbounded collections (need limits/pagination)
Frontend:
- Unnecessary re-renders (React useMemo, useCallback)
- Large bundles (code splitting)
- Images not optimized
- Blocking JavaScript in critical path
数据库:
- N+1查询问题(使用关联查询/批量操作)
- 过滤/排序列缺少索引
- 使用SELECT *而非指定列
- 在循环中执行查询
缓存:
- 重复执行的昂贵计算
- 重复的API调用
- 静态数据未做缓存
- 合理设置缓存TTL
资源管理:
- 文件/连接/流需正确关闭
- 无内存泄漏(循环引用、事件监听器未移除)
- 无界集合需设置限制/分页
前端:
- 不必要的重渲染(使用React useMemo、useCallback)
- 过大的包体积(代码分割)
- 图片未优化
- 关键路径中的阻塞式JavaScript
Architecture & Design
架构与设计
SOLID Principles
SOLID原则
- Single Responsibility: One reason to change
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes substitutable for base types
- Interface Segregation: Small, focused interfaces
- Dependency Inversion: Depend on abstractions
- 单一职责: 一个类/函数只有一个修改理由
- 开闭原则: 对扩展开放,对修改关闭
- 里氏替换: 子类可替换父类使用
- 接口隔离: 小而专注的接口
- 依赖反转: 依赖抽象而非具体实现
Other Key Principles
其他关键原则
- DRY: Don't Repeat Yourself
- KISS: Keep It Simple
- YAGNI: Don't over-engineer
- Separation of Concerns: Distinct responsibilities
- Composition over Inheritance
- DRY: 不要重复自己
- KISS: 保持简单
- YAGNI: 不要过度设计
- 关注点分离: 职责清晰划分
- 组合优于继承
Code Structure
代码结构
- Proper layer separation (presentation, business, data)
- Dependencies flow one direction
- No circular dependencies
- Modules cohesive and loosely coupled
- Configuration separated from code
- 合理的分层(展示层、业务层、数据层)
- 依赖单向流动
- 无循环依赖
- 模块高内聚、低耦合
- 配置与代码分离
Testing
测试
Coverage & Quality
覆盖率与质量
- Critical paths tested
- Edge cases covered (empty, null, max values)
- Error paths tested
- Tests deterministic (no flaky tests)
- Tests isolated (no shared state)
Test Quality:
- Arrange-Act-Assert structure
- One assertion focus per test
- Descriptive test names
- No test logic (tests are simple)
- Realistic test data
- External dependencies mocked appropriately
- 关键路径需覆盖测试
- 覆盖边缘场景(空值、null、最大值)
- 错误路径需覆盖测试
- 测试需确定(无不稳定测试)
- 测试需隔离(无共享状态)
测试质量:
- 遵循Arrange-Act-Assert结构
- 每个测试聚焦一个断言
- 测试名称表意明确
- 测试逻辑简单(无复杂逻辑)
- 测试数据真实合理
- 外部依赖需合理Mock
Review Process
审查流程
Before Review
审查前准备
- Understand context (PR description, tickets)
- Check scope (< 400 lines ideal)
- Run code locally
- Verify CI passes
- 了解上下文(PR描述、需求工单)
- 检查代码范围(理想情况下少于400行)
- 本地运行代码
- 验证CI已通过
During Review
审查中
- Start with architecture/approach
- Use security/performance/quality checklists
- Review tests first (explain intended behavior)
- Ask questions, don't assume
- 先从架构/实现思路入手
- 使用安全/性能/质量检查清单
- 先审查测试代码(明确预期行为)
- 提出问题,而非主观假设
Providing Feedback
提供反馈
Structure:
- Severity: Critical (must fix) vs Nice-to-have
- What: Specific issue
- Why: Why it matters
- How: Concrete alternative
Tone:
- Use "we" language: "We should..." not "You should..."
- Ask questions: "Have we considered...?"
- Be specific: "Function has complexity 32, consider refactoring"
Example:
❌ "This is bad"
✅ "Using string concatenation in loop creates O(n²) complexity. Use StringBuilder for O(n)."
结构:
- 严重程度:关键(必须修复)vs 锦上添花
- 问题:具体的问题点
- 原因:问题的影响
- 方案:具体的替代方案
语气:
- 使用“我们”的表述:“我们应该...”而非“你应该...”
- 以提问方式:“我们是否考虑过...?”
- 具体明确:“该函数圈复杂度为32,建议重构”
示例:
❌ “这写得很差”
✅ “在循环中使用字符串拼接会导致O(n²)的时间复杂度,建议使用StringBuilder实现O(n)复杂度。”
Priority Checklist
优先级检查清单
Critical (Must Fix)
关键(必须修复)
- Security vulnerabilities (injection, XSS, auth bypass)
- Data loss/corruption risks
- Memory/resource leaks
- Breaking API changes without versioning
- Race conditions/concurrency bugs
- 安全漏洞(注入、XSS、认证绕过)
- 数据丢失/损坏风险
- 内存/资源泄漏
- 未做版本管理的破坏性API变更
- 竞态条件/并发漏洞
High Priority
高优先级
- Performance issues (O(n²), N+1 queries)
- Missing input validation
- Hardcoded configuration
- Missing error logging
- No tests for new functionality
- 性能问题(O(n²)、N+1查询)
- 缺少输入验证
- 硬编码配置
- 缺少错误日志
- 新功能无测试覆盖
Medium Priority
中优先级
- Code duplication (3+ instances)
- High complexity (>15 cyclomatic)
- Missing documentation for public APIs
- Deep nesting (>4 levels)
- Large functions (>100 lines)
- 代码重复(3次及以上)
- 高复杂度(圈复杂度>15)
- 公开API缺少文档
- 深层嵌套(>4层)
- 大函数(>100行)
Low Priority
低优先级
- Minor style inconsistencies
- Could be more idiomatic
- Variable names could be clearer
- Magic numbers → constants
- 轻微的风格不一致
- 代码可更符合语言习惯
- 变量名称可更清晰
- 魔法数值→常量
Language-Specific Notes
语言特定注意事项
JavaScript/TypeScript:
- Use const over let, avoid var
- Proper async/await (handle rejections)
- Use === not ==
- TypeScript: Proper types, avoid any
- Null/undefined handling
Python:
- Follow PEP 8
- Type hints for public APIs
- Context managers (with)
- No mutable default arguments
Java:
- Proper exception hierarchy
- Try-with-resources
- Access modifiers (private/protected/public)
- Immutability (final fields)
Go:
- Error handling on every call
- defer for cleanup
- No goroutine leaks (context cancellation)
- Small, focused interfaces
JavaScript/TypeScript:
- 优先使用const而非let,避免使用var
- 正确使用async/await(处理rejections)
- 使用===而非==
- TypeScript:正确定义类型,避免使用any
- 处理Null/undefined
Python:
- 遵循PEP 8规范
- 公开API添加类型提示
- 使用上下文管理器(with)
- 避免可变默认参数
Java:
- 合理的异常层级
- 使用Try-with-resources
- 正确使用访问修饰符(private/protected/public)
- 不可变性(final字段)
Go:
- 每个调用都需处理错误
- 使用defer做资源清理
- 无goroutine泄漏(上下文取消)
- 小而专注的接口
Best Practices Summary
最佳实践总结
- Security First: OWASP Top 10 vulnerabilities
- Test Coverage: Meaningful tests exist
- Error Handling: All errors handled
- Performance: Watch O(n²), N+1, memory leaks
- Readability: Clear, self-documenting code
- Maintainability: Low complexity, no duplication
- Documentation: Public APIs documented
- Consistency: Follow team conventions
- Constructive: Be helpful, not critical
- Prioritize: Critical first, style last
- 安全优先:关注OWASP Top 10漏洞
- 测试覆盖:确保关键路径有意义的测试
- 错误处理:所有错误均需妥善处理
- 性能优化:警惕O(n²)复杂度、N+1查询、内存泄漏
- 可读性:清晰、自文档化的代码
- 可维护性:低复杂度、无重复代码
- 文档规范:公开API需有文档
- 一致性:遵循团队规范
- 建设性:提供帮助而非批评
- 优先级:先处理关键问题,最后关注风格细节