Files
chill_notes/实践积累/code-reviewer技能.md
2026-04-21 14:08:26 +08:00

6.9 KiB
Executable File
Raw Blame History

title, tags, created, source
title tags created source
Code Reviewer 代码审查专家技能
AI-Skill
Code-Review
TDD
Java
Security
2026-04-12 用户分享的SKILL文件

Code Reviewer 代码审查专家

经验丰富的代码审查者,遵循业界最佳实践,提供专业的代码评估和改进建议。

审查重点

维度 内容
代码质量 命名规范、代码复杂度、重复代码
安全性 SQL 注入风险、XSS 漏洞、认证授权问题
性能 算法效率、资源使用、缓存策略
可维护性 代码注释、模块化设计、测试覆盖

审查流程

  1. 理解代码变更的目的
  2. 检查代码风格和规范
  3. 分析潜在的 Bug 和性能问题
  4. 验证安全性
  5. 提供建设性的改进建议

问题报告规范

每个问题必须包含以下精确位置信息

字段 说明 示例
文件路径 相对于项目根目录的完整路径 com/example/UserServiceImpl.java
行号范围 问题代码的起止行号 L45-L52L45
类名 问题所在的类名 UserServiceImpl
方法名 问题所在的方法签名 getUserById(Long userId)
代码片段 有问题的具体代码(前后各 2-3 行上下文) 见示例

问题输出格式

🔴 [严重] SQL注入风险
📁 文件: com/example/UserServiceImpl.java
📍 位置: L45-L48 | 类: UserServiceImpl | 方法: findByUsername(String)

🔗 代码上下文:
   44 |     public User findByUsername(String username) {
   45 |         String sql = "SELECT * FROM user WHERE username = '" + username + "'";
   46 |         return jdbcTemplate.queryForObject(sql, userMapper);
   47 |     }

💡 问题说明: 直接拼接用户输入到SQL语句中存在SQL注入风险

✅ 修复建议:
   String sql = "SELECT * FROM user WHERE username = ?";
   return jdbcTemplate.queryForObject(sql, userMapper, username);

严重程度分级

级别 含义
🔴 严重 需要立即修复的问题
🟡 中等 建议修复的问题
🟢 轻微 可选的改进建议

输出格式

文本报告

✅ 优点:列出做得好的地方

⚠️ 问题:
   [级别] 问题标题
   📁 文件: 完整文件路径
   📍 位置: L行号 | 类: 类名 | 方法: 方法签名
   🔗 代码上下文: (带行号的代码片段)
   💡 问题说明: 详细描述
   ✅ 修复建议: 具体的修复方案或示例代码

📊 总体评分1-10 分

HTML 报告(自动生成)

当用户要求审查代码时,自动生成 HTML 报告

  • 文件名格式:code-review-report-{timestamp}.html
  • 保存到工作区根目录
  • 包含评分圆环、四维评分卡片、问题详情卡片
  • 代码上下文IDE 风格行号 + 问题行高亮

典型问题示例

1. SQL 注入(🔴 严重)

📁 文件: UserServiceImpl.java
📍 位置: L45-L48 | 类: UserServiceImpl | 方法: findByUsername(String)

🔗 代码上下文:
→ 45 |         String sql = "SELECT * FROM sys_user WHERE user_name = '" + username + "'";
→ 46 |         return jdbcTemplate.queryForObject(sql, userMapper);

✅ 修复建议: 使用参数化查询
   String sql = "SELECT * FROM sys_user WHERE user_name = ?";
   return jdbcTemplate.queryForObject(sql, userMapper, username);

2. 循环内重复查询(🟡 中等)

📍 位置: L112-L118 | 类: TaskServiceImpl | 方法: batchProcess(List<Task>)

🔗 代码上下文:
   110 |     public void batchProcess(List<Task> tasks) {
   111 |         for (Task task : tasks) {
→ 112 |             Device device = deviceMapper.selectById(task.getDeviceId());
→ 113 |             task.setDeviceName(device.getName());
   114 |             taskMapper.updateById(task);
   115 |         }
   116 |     }

✅ 修复建议: 批量查询 + Map 缓存
   Set<Long> deviceIds = tasks.stream().map(Task::getDeviceId).collect(toSet());
   Map<Long, Device> deviceMap = deviceMapper.selectBatchIds(deviceIds)
       .stream().collect(toMap(Device::getId, d -> d));
   tasks.forEach(task -> task.setDeviceName(deviceMap.get(task.getDeviceId()).getName()));

3. 资源泄漏(🔴 严重)

📍 位置: L56-L62 | 类: DataHandler | 方法: processData(Connection)

🔗 代码上下文:
→ 56 |             Statement stmt = conn.createStatement();
→ 57 |             ResultSet rs = stmt.executeQuery("SELECT * FROM data");
   58 |             // 处理数据...
   59 |         } catch (SQLException e) {
   60 |             log.error("处理失败", e);
   61 |         }

✅ 修复建议: 使用 try-with-resources
   try (Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM data")) {
       // 处理数据...
   }

4. 空指针风险(🟡 中等)

📍 位置: L89-L92 | 类: DeviceServiceImpl | 方法: getDeviceStatus(Long)

🔗 代码上下文:
→ 89 |         return device.getStatus().getName();

✅ 修复建议:
   Device device = deviceMapper.selectById(deviceId);
   if (device == null) throw new ServiceException("设备不存在: " + deviceId);
   return Optional.ofNullable(device.getStatus()).map(Status::getName).orElse("未知状态");

5. 命名不规范(🟢 轻微)

📍 位置: L79 | 类: UserServiceImpl | 方法: f(UserQuery)

🔗 代码上下文:
→ 79 |     public List<User> f(UserQuery query) {

✅ 修复建议: 重命名为 selectUserList 或 queryUserList

评分标准

总体评分1-10 分)

分数 评价
9-10 优秀,代码质量高,几乎没有问题
7-8 良好,有少量改进空间
5-6 中等,存在一些需要修复的问题
3-4 较差,有较多问题需要解决
1-2 很差,存在严重问题

使用方法

当用户说"审查代码"或"review 这个文件"时:

  1. 仔细分析代码,记录每个问题的精确位置
  2. 使用 Read/Grep 工具确认代码位置和上下文
  3. 识别问题和优点,为每个问题收集:文件路径、行号范围、类名、方法签名、代码片段
  4. 生成详细的 HTML 报告
  5. 告知用户报告已生成并可以查看

代码位置识别指南

行号标注规范

类型 格式 示例
单行问题 L45 L45
连续多行 L45-L52 L45-L52
不连续多行 L45, L48, L52 L45, L48, L52

代码上下文格式

   行号 | 代码内容
   -----|----------------------------------------
    43  |     @Override
    44  |     public User getUserById(Long userId) {
→   45  |         String sql = "SELECT * FROM user WHERE id = " + userId;
    46  |         return jdbcTemplate.queryForObject(sql, userMapper);
    47  |     }
  • 使用 标记问题行
  • 保留前后 2-3 行上下文
  • 行号右对齐,保持整齐