代码审查清单Skill code-review-checklist

这个技能提供全面的代码审查清单,覆盖功能、安全、性能和可维护性等方面,用于在软件开发过程中进行系统性代码审查,帮助开发者确保代码质量、发现错误、识别安全问题和优化性能。关键词:代码审查、清单、软件开发、代码质量、安全审查、性能优化、可维护性、测试覆盖。

其他 0 次安装 0 次浏览 更新于 3/21/2026

name: 代码审查清单 description: “进行彻底代码审查的全面清单,覆盖功能、安全、性能和可维护性”

代码审查清单

概述

提供一个系统性的清单,用于进行彻底的代码审查。这个技能帮助审查者确保代码质量,发现错误,识别安全问题,并在代码库中保持一致性。

何时使用此技能

  • 审查拉取请求时使用
  • 进行代码审计时使用
  • 为团队建立代码审查标准时使用
  • 培训新开发者代码审查实践时使用
  • 当你想确保审查中不漏掉任何东西时使用
  • 创建代码审查文档时使用

工作原理

步骤1:理解上下文

在审查代码之前,我会帮助你理解:

  • 这段代码解决了什么问题?
  • 需求是什么?
  • 哪些文件被修改了,为什么?
  • 是否有相关的问题或工单?
  • 测试策略是什么?

步骤2:审查功能性

检查代码是否正确工作:

  • 它是否解决了所述问题?
  • 边界情况是否处理?
  • 错误处理是否适当?
  • 是否有逻辑错误?
  • 是否符合需求?

步骤3:审查代码质量

评估代码可维护性:

  • 代码是否可读和清晰?
  • 名称是否描述性?
  • 是否结构良好?
  • 函数/方法是否专注?
  • 是否有不必要的复杂性?

步骤4:审查安全性

检查安全问题:

  • 输入是否验证?
  • 敏感数据是否保护?
  • 是否有SQL注入风险?
  • 身份验证/授权是否正确?
  • 依赖项是否安全?

步骤5:审查性能

寻找性能问题:

  • 是否有不必要的循环?
  • 数据库访问是否优化?
  • 是否有内存泄漏?
  • 缓存是否适当使用?
  • 是否有N+1查询问题?

步骤6:审查测试

验证测试覆盖:

  • 新代码是否有测试?
  • 测试是否覆盖边界情况?
  • 测试是否有意义?
  • 所有测试是否通过?
  • 测试覆盖是否充分?

示例

示例1:功能性审查清单

## 功能性审查

### 需求
- [ ] 代码解决了所述问题
- [ ] 所有验收标准都满足
- [ ] 边界情况已处理
- [ ] 错误情况已处理
- [ ] 用户输入已验证

### 逻辑
- [ ] 无逻辑错误或缺陷
- [ ] 条件正确(无差一错误)
- [ ] 循环正确终止
- [ ] 递归有适当的基础情况
- [ ] 状态管理正确

### 错误处理
- [ ] 错误被适当捕获
- [ ] 错误消息清晰且有用
- [ ] 错误不暴露敏感信息
- [ ] 失败操作已回滚
- [ ] 日志记录适当

### 示例问题捕获:

**❌ 不良 - 缺少验证:**
\`\`\`javascript
function createUser(email, password) {
  // 无验证!
  return db.users.create({ email, password });
}
\`\`\`

**✅ 良好 - 适当验证:**
\`\`\`javascript
function createUser(email, password) {
  if (!email || !isValidEmail(email)) {
    throw new Error('无效的电子邮件地址');
  }
  if (!password || password.length < 8) {
    throw new Error('密码必须至少8个字符');
  }
  return db.users.create({ email, password });
}
\`\`\`

示例2:安全性审查清单

## 安全性审查

### 输入验证
- [ ] 所有用户输入已验证
- [ ] 防止SQL注入(使用参数化查询)
- [ ] 防止XSS(转义输出)
- [ ] CSRF保护到位
- [ ] 文件上传已验证(类型、大小、内容)

### 身份验证与授权
- [ ] 在需要的地方进行身份验证
- [ ] 授权检查存在
- [ ] 密码已哈希(从不存储明文)
- [ ] 会话安全管理
- [ ] 令牌适当过期

### 数据保护
- [ ] 敏感数据已加密
- [ ] API密钥未硬编码
- [ ] 使用环境变量存储秘密
- [ ] 个人数据遵循隐私法规
- [ ] 数据库凭证安全

### 依赖项
- [ ] 无已知易受攻击的依赖项
- [ ] 依赖项最新
- [ ] 不必要的依赖项已移除
- [ ] 依赖项版本已固定

### 示例问题捕获:

**❌ 不良 - SQL注入风险:**
\`\`\`javascript
const query = \`SELECT * FROM users WHERE email = '\${email}'\`;
db.query(query);
\`\`\`

**✅ 良好 - 参数化查询:**
\`\`\`javascript
const query = 'SELECT * FROM users WHERE email = $1';
db.query(query, [email]);
\`\`\`

**❌ 不良 - 硬编码秘密:**
\`\`\`javascript
const API_KEY = 'sk_live_abc123xyz';
\`\`\`

**✅ 良好 - 环境变量:**
\`\`\`javascript
const API_KEY = process.env.API_KEY;
if (!API_KEY) {
  throw new Error('需要API_KEY环境变量');
}
\`\`\`

示例3:代码质量审查清单

## 代码质量审查

### 可读性
- [ ] 代码易于理解
- [ ] 变量名称描述性
- [ ] 函数名称说明其功能
- [ ] 复杂逻辑有注释
- [ ] 魔法数字已替换为常量

### 结构
- [ ] 函数小而专注
- [ ] 代码遵循DRY原则(不要重复自己)
- [ ] 适当的关注点分离
- [ ] 一致的代码风格
- [ ] 无死代码或注释掉的代码

### 可维护性
- [ ] 代码模块化且可重用
- [ ] 依赖项最小
- [ ] 更改向后兼容
- [ ] 破坏性更改已记录
- [ ] 技术债务已注明

### 示例问题捕获:

**❌ 不良 - 不清晰的命名:**
\`\`\`javascript
function calc(a, b, c) {
  return a * b + c;
}
\`\`\`

**✅ 良好 - 描述性命名:**
\`\`\`javascript
function calculateTotalPrice(quantity, unitPrice, tax) {
  return quantity * unitPrice + tax;
}
\`\`\`

**❌ 不良 - 函数做太多事:**
\`\`\`javascript
function processOrder(order) {
  // 验证订单
  if (!order.items) throw new Error('无项目');
  
  // 计算总额
  let total = 0;
  for (let item of order.items) {
    total += item.price * item.quantity;
  }
  
  // 应用折扣
  if (order.coupon) {
    total *= 0.9;
  }
  
  // 处理支付
  const payment = stripe.charge(total);
  
  // 发送电子邮件
  sendEmail(order.email, '订单确认');
  
  // 更新库存
  updateInventory(order.items);
  
  return { orderId: order.id, total };
}
\`\`\`

**✅ 良好 - 分离关注点:**
\`\`\`javascript
function processOrder(order) {
  validateOrder(order);
  const total = calculateOrderTotal(order);
  const payment = processPayment(total);
  sendOrderConfirmation(order.email);
  updateInventory(order.items);
  
  return { orderId: order.id, total };
}
\`\`\`

最佳实践

✅ 这样做

  • 审查小更改 - 较小的PR更容易彻底审查
  • 先检查测试 - 验证测试通过并覆盖新代码
  • 运行代码 - 尽可能在本地测试
  • 提问 - 不要假设,请求澄清
  • 建设性 - 提出改进建议,不只是批评
  • 关注重要问题 - 不要挑剔次要风格问题
  • 使用自动化工具 - 代码检查器、格式化器、安全扫描器
  • 审查文档 - 检查文档是否更新
  • 考虑性能 - 思考扩展和效率
  • 检查回归 - 确保现有功能仍工作

❌ 不要这样做

  • 不读就批准 - 实际审查代码
  • 不要模糊 - 提供具体反馈和示例
  • 不要忽略安全 - 安全问题关键
  • 不要跳过测试 - 未测试的代码会导致问题
  • 不要粗鲁 - 尊重和专业
  • 不要橡皮图章 - 每次审查都应增加价值
  • 不要疲劳时审查 - 你会错过重要问题
  • 不要忘记上下文 - 理解大局

完整审查清单

预审查

  • [ ] 阅读PR描述和相关问题
  • [ ] 理解解决了什么问题
  • [ ] 检查CI/CD中测试是否通过
  • [ ] 拉取分支并在本地运行

功能性

  • [ ] 代码解决了所述问题
  • [ ] 边界情况已处理
  • [ ] 错误处理适当
  • [ ] 用户输入已验证
  • [ ] 无逻辑错误

安全性

  • [ ] 无SQL注入漏洞
  • [ ] 无XSS漏洞
  • [ ] 身份验证/授权正确
  • [ ] 敏感数据保护
  • [ ] 无硬编码秘密

性能

  • [ ] 无不必要的数据库查询
  • [ ] 无N+1查询问题
  • [ ] 使用高效算法
  • [ ] 无内存泄漏
  • [ ] 适当使用缓存

代码质量

  • [ ] 代码可读且清晰
  • [ ] 名称描述性
  • [ ] 函数专注且小
  • [ ] 无代码重复
  • [ ] 遵循项目惯例

测试

  • [ ] 新代码有测试
  • [ ] 测试覆盖边界情况
  • [ ] 测试有意义
  • [ ] 所有测试通过
  • [ ] 测试覆盖充分

文档

  • [ ] 代码注释解释原因,而非内容
  • [ ] API文档已更新
  • [ ] 如果需要,README已更新
  • [ ] 破坏性更改已记录
  • [ ] 如果需要,提供迁移指南

Git

  • [ ] 提交消息清晰
  • [ ] 无合并冲突
  • [ ] 分支与主分支同步
  • [ ] 无不必要的文件提交
  • [ ] .gitignore正确配置

常见陷阱

问题:遗漏边界情况

症状: 代码在正常路径工作,但在边界情况失败 解决方案: 询问“如果…?”问题

  • 如果输入为空呢?
  • 如果数组为空呢?
  • 如果用户未认证呢?
  • 如果网络请求失败呢?

问题:安全漏洞

症状: 代码暴露安全风险 解决方案: 使用安全清单

  • 运行安全扫描器(npm audit、Snyk)
  • 检查OWASP前10
  • 验证所有输入
  • 使用参数化查询
  • 永不信任用户输入

问题:测试覆盖差

症状: 新代码无测试或测试不足 解决方案: 要求所有新代码都有测试

  • 函数单元测试
  • 功能集成测试
  • 边界情况测试
  • 错误情况测试

问题:代码不清晰

症状: 审查者不理解代码功能 解决方案: 请求改进

  • 更好的变量名称
  • 解释性注释
  • 更小的函数
  • 清晰的结构

审查评论模板

请求更改

**问题:** [描述问题]

**当前代码:**
\`\`\`javascript
// 显示问题代码
\`\`\`

**建议修复:**
\`\`\`javascript
// 显示改进代码
\`\`\`

**原因:** [解释为什么更好]

提问

**问题:** [你的问题]

**上下文:** [你为什么提问]

**建议:** [如果你有]

赞扬好代码

**不错!** [你喜欢什么]

这很棒因为 [解释原因]

相关技能

  • @请求代码审查 - 准备代码审查
  • @接收代码审查 - 处理审查反馈
  • @系统调试 - 调试审查中发现的问题
  • @测试驱动开发 - 确保代码有测试

附加资源


专业提示: 为每次审查使用清单模板,以确保一致性和彻底性。根据团队的具体需求进行自定义!