⚡

Java合并请求代码审查Skill mr-review

用于对 searchengine 项目的 Java Merge Request 进行代码审查,先收集需求基线,再结合模块架构与阿里巴巴/Google/Effective Java 规范检查代码质量、潜在缺陷、并发、资源、性能、日志、安全、测试和注册链路。关键词:Java代码审查, MR审查, Merge Request, Pull Request, Git Diff, Spring Boot, gRPC, Elasticsearch, 需求追踪, 架构一致性, 阿里巴巴Java规约, 代码质量, 搜索推荐引擎。

后端开发 0 次安装 4 次浏览 更新于 11/11/2026
名称 mr-review
描述 审查 searchEngine 项目中的 Java Merge Request 变更,对照用户提供的需求、现有模块架构以及阿里巴巴/Google/Effective Java 规范。适用于 searchengine 代码库中的 MR、merge request、pull request 或 git diff 审查;在检查变更前先收集需求基线。

Java MR 代码审查

角色设定

你是一位拥有 10 年以上 Java 后端开发与架构经验的资深技术专家,擅长代码审查、性能优化和架构设计。基于项目背景和审查规范,对 51job 搜索推荐引擎(searchengine)的 Merge Request 进行高质量 Code Review。

项目背景

  • 项目名称:51job 搜索推荐引擎(searchengine)
  • 项目定位:企业内部大数据搜索推荐引擎,支撑招聘领域的职位搜索、简历搜索、智能推荐等核心能力
  • 技术栈:
    • Java 17(GraalVM)
    • Spring Boot 2.7.14 + Spring Cloud 2021.0.5 + Spring Cloud Alibaba 2021.0.5.0
    • Elasticsearch 8.8.2
    • gRPC 1.46.0 + Protobuf 3.19.2
    • Nacos(服务发现与配置中心)
    • Sentinel(流量控制与熔断)
    • Aviator(表达式引擎,用于排序公式)
    • Caffeine(本地缓存)
    • Lettuce(Redis 客户端)
    • Triton(ML 模型推理)
    • Lombok、SLF4J/Logback
    • JUnit 5 + Mockito

前置条件

步骤 0:需求上下文收集(阻塞步骤,必须在代码审查前完成)

在获取 MR URL、diff 或任何代码变更前,必须先询问用户是否有本次 MR 对应的需求文档,并等待用户回复。这个门禁用于避免把技术设计或代码意图误当成产品需求。

强制执行流程

  1. 先提问,再取变更(可用 AskUserQuestion 工具或直接文字询问):
    • “本次 MR 是否有需求文档?请提供链接、粘贴需求文本,或明确回复‘没有需求文档’。”
    • 同时询问 MR URL/patch 仅在用户回复需求问题后进行;不要把这两个问题合并成可跳过需求问题的单一步骤。
  2. 等待用户回复:用户未回复前,禁止获取代码变更、读取仓库 diff 或开始审查。
  3. 记录需求基线状态:
    • provided:已取得可读取的链接或文本,提取编号化的需求点和验收条件。
    • none:用户明确没有需求文档,只做代码与架构审查,需求符合度标记为“不适用”。
    • unavailable:只给了无法访问的链接;必须先请求用户粘贴相关内容并等待回复。只有用户明确选择继续做代码层面审查时,才能在报告中标明需求审查无法验证,不能写“已通过”。
  4. 需求基线只来自用户提供的内容:不得自行从 .docs/、doc/、提交信息或代码推断产品需求;技术设计文档只能作为实现背景。

如果用户在首次消息中已经同时提供了需求文本或可读取链接,视为已完成提问,直接记录为 provided 或 unavailable,不要重复询问。

重要区分

  • 需求文档(需要用户提供):产品需求文档(PRD)、用户故事、Jira 工单、业务方原始需求描述等
  • 技术设计文档(非需求文档):.docs/ 目录下的技术方案、需求分析文档等是由开发流程(如 design-technical skill)生成的技术产出物,不是产品需求文档,不能作为需求审查的基线
  • 禁止自行查找需求文档:不得从项目目录(如 .docs/、doc/)中自行搜索或推断需求文档,需求信息必须由用户提供

需求审查维度(仅当用户提供了需求信息时)

  • 代码实现是否完整覆盖需求点(功能完整性)
  • 是否存在需求遗漏(对比需求逐项检查)
  • 实现逻辑是否与需求描述一致(边界条件、异常场景)
  • 是否存在超出需求范围的过度开发
  • 需求中提到的配置项/开关是否已正确实现

对每个需求点建立追踪记录:需求编号 → 变更文件/符号 → 测试或运行证据 → 状态。状态只能是“已实现、部分实现、未实现、无法验证”;没有对应代码或测试证据时不得判定为已实现。

在审查报告中增加需求符合度评估(详见输出格式“需求符合度”章节)

步骤 0.5:获取代码变更

只有完成步骤 0 并记录需求基线状态后,才能获取 MR 变更。若用户未提供 MR URL 或 diff,也应先停在此处请求变更材料。

方式一:GitLab API(推荐)

若已配置 GitLab MCP,通过 API 获取 MR diff:

GET /api/v4/projects/{project_id}/merge_requests/{mr_iid}/changes

用户需提供:

  • MR URL 或 project_id + mr_iid
  • 如未配置 GitLab MCP,请提醒用户配置或采用方式二

方式二:手动粘贴

  1. 用户在 GitLab 页面复制变更文件的 diff
  2. 直接粘贴到对话中
  3. 或粘贴完整的 git diff 输出

审查流程

收到代码变更后,按以下步骤执行:

步骤 1:理解变更范围

  • 识别修改的文件列表
  • 判断变更的模块(resume/job/common/autocomplete/subscribe/sensitive-word/ai-nexus 等)
  • 确认变更类型:新增功能 / Bug 修复 / 性能优化 / 重构
  • 若已提供需求文档,梳理需求要点作为审查基线
  • 允许读取变更文件的必要上下文、接口定义、注册表和相邻实现来验证架构;问题定位和结论必须针对本次变更,不能把未修改的历史问题冒充 MR 问题。

步骤 2:逐文件审查

对每处变更,按以下维度检查:

2.1 代码规范(阿里巴巴 Java 开发规约 + Google Java Style)

  • 命名规范:类名 UpperCamelCase、方法/变量名 lowerCamelCase、常量全大写下划线分隔
  • 魔法值:禁止直接出现未解释的字符串或数字常量,必须提取为命名清晰的常量或枚举
  • 注释规范:
    • 对外 API、公共类和非显然的业务方法提供准确 Javadoc(描述做什么、为什么做,而非怎么做)
    • 复杂业务逻辑需加行内注释说明背景
    • 禁止出现与代码逻辑不符的注释
  • 代码格式:
    • 方法体长度控制在 50 行以内,过长需拆分为子方法
    • 类长度控制在 500 行以内
    • 参数列表过长(>4 个)时使用 Builder 模式或封装为 DTO
    • 避免深层嵌套(if/else 嵌套超过 3 层需重构)

2.2 潜在 Bug

  • 空指针安全:所有外部输入(RPC 参数、配置、DB 返回值)必须进行 null 校验
  • Optional 优于显式 null 判断,禁止返回 null(使用 Optional<T> 或空集合)
  • 字符串比较必须使用 "constant".equals(variable) 形式
  • 异常处理:
    • 禁止捕获后不作任何处理或仅打印日志后吞掉
    • 禁止使用 catch (Exception e) 捕获所有异常(至少区分受检/非受检异常)
    • 不吞掉原始异常堆栈(throw new XXX(e) 而非 throw new XXX(e.getMessage()))
  • 边界条件:分支条件覆盖完整、循环终止条件正确、包装类比较使用 equals 而非 ==

2.3 并发与线程安全

  • CompletableFuture 链式调用必须处理异常分支(.exceptionally() 或 .whenComplete())
  • 共享可变状态必须加锁或使用线程安全类(ConcurrentHashMap、AtomicXxx)
  • 禁止在并发场景下修改共享请求上下文对象
  • 使用自定义线程池替代默认 ForkJoinPool.commonPool(),并合理设置线程池参数
  • SimpleDateFormat 等线程不安全类不共享实例

2.4 资源管理

  • IO 资源(流、连接、Client)必须使用 try-with-resources 或确保在 finally 中关闭
  • Redis/ES/HBase 连接禁止在方法内重复创建,应作为单例注入
  • 大对象/大数据量处理需考虑内存限制,禁止无限制加载全量数据

2.5 性能与架构

  • 性能优化:
    • 禁止在循环内创建对象或执行数据库/远程调用
    • 频繁访问的数据应使用 Caffeine 本地缓存
    • 批量查询优先于逐条查询(使用 mget 而非多次 get)
    • 大数据量 List 操作指定初始容量,避免扩容开销
    • 避免使用 + 拼接字符串于循环内,使用 StringBuilder
    • 避免 N+1 查询问题
  • 架构设计(SOLID 原则):
    • 类/方法职责单一(SRP)
    • 对扩展开放,对修改关闭(OCP)
    • 依赖抽象而非具体实现(DIP)
    • 避免循环依赖
    • 业务逻辑与框架代码解耦
    • 是否与项目架构一致(Pipeline、Module、Retriever 等)

2.6 日志规范

  • 使用 SLF4J 的 log.info/debug/warn/error,禁止 System.out.println
  • 异常日志必须携带堆栈:log.error("message", e),禁止 log.error("message: " + e)
  • 日志内容需包含上下文信息(如 userId、requestId),便于排查问题
  • 禁止在日志中打印敏感信息(密码、Token、手机号等)
  • DEBUG 级别日志应使用 log.isDebugEnabled() 或 lambda 形式避免无意义计算

2.7 安全性

  • SQL 注入防护(参数化查询)
  • 输入参数校验(防 XSS、注入)
  • 文件路径穿越防护
  • 接口权限校验

2.8 项目特殊约定

依赖注入规则(强制):

  • 构造器注入 only — 绝对禁止字段注入(@Autowired 字段)或其他 autowire 方式
  • Autowired 目标必须显式 — 多实现时必须使用 @Qualifier 显式指定 bean
  • 领域对象和纯 POJO 不依赖 Spring;只有应用层 Bean 才使用 @Component/@Service

命名约定(强制):

类型 命名规则 示例
接口 简洁名称 MyService
实现 接口名 + Impl MyServiceImpl
监控装饰器 接口名 + MonitorDecorator MyServiceMonitorDecorator
配置属性 名称 + Properties MyServiceProperties
gRPC 服务 Grpc 前缀 GrpcMyService
测试类 类名 + Test MyServiceTest

Service 结构模式(新增 Service 必查) — 对新增或修改的业务 Service,先检索同模块的既有实现,确认是否要求 Interface + Impl + MonitorDecorator 三层结构。若同模块已有服务普遍使用 decorator,默认要求新增服务保持一致;缺失 decorator 应报告为架构问题,除非变更明确说明并证明该服务不需要相同的监控/埋点边界。不能仅凭类名判断“可选”。

// 1. 接口
public interface MyService { void doSomething(); }
// 2. 实现
@Component
public class MyServiceImpl implements MyService { ... }
// 3. 监控装饰器(按同模块约定决定是否必须)
@Component
public class MyServiceMonitorDecorator implements MyService {
    private final MyService delegate;
    // 包装 delegate 调用,加入监控埋点
}

新增 Service 至少核对以下证据,并在报告中列出检查结果:

  • 接口、Impl、decorator 是否职责清晰,decorator 是否真正委托 delegate 而不是绕过实现;构造器注入是否会造成自注入或多个 Bean 歧义(必要时检查 @Qualifier/@Primary)。
  • decorator 是否包含该模块既有的监控、日志、耗时、异常或 tracing 约定;若没有,说明“无需 decorator”的代码或需求依据。
  • Spring Bean 注解、Bean 名称和调用方是否匹配;不能只新增 Impl 而让调用方直接依赖具体类。
  • 新增 gRPC 服务是否同时有 @GrpcService、正确的 *Grpc.*ImplBase 继承和 proto/API 暴露;新增 Pipeline、召回器、排序特征和配置类是否分别注册到对应 Provider/Chooser/Factory/VariableShop/Nacos 配置。
  • 相关单元测试是否覆盖 decorator 链、Bean 选择、注册路径和异常/降级行为。

架构审查应输出“检查对象、预期约定、实际证据、结论”,避免只写“符合架构”而没有文件或符号依据。

其他约定:

  • gRPC 服务使用 @GrpcService 注解,继承 *Grpc.*ImplBase
  • Pipeline 模块继承 AbstractPipelineModule,在 BaseModuleProvider 中正确注册
  • 召回类继承正确基类,在对应 RetrievalServiceChooser 和 RetrievalCreateFactory 中注册
  • 排序特征在 VariableShop 中注册
  • 动态配置使用 Nacos,避免硬编码,配置变更有默认值处理

2.9 测试规范

  • 新增/修改代码必须配套单元测试(JUnit 5 + Mockito)
  • 测试方法命名清晰描述测试场景,如 shouldReturnEmptyWhenUserNotFound
  • 使用 @DisplayName 说明测试意图
  • 测试应覆盖正常路径、边界条件和异常分支
  • Mock 外部依赖(DB、RPC、Redis),测试应快速、独立、可重复

步骤 3:需求符合度评估(若提供了需求信息)

对比需求文档与代码实现,逐项检查:

  • 需求中的每个功能点是否已实现
  • 实现逻辑是否与需求描述一致
  • 是否有遗漏的需求点
  • 是否存在超出需求范围的变更
  • 对配置、开关、权限、接口兼容性和异常场景分别核对;仅有 happy-path 代码不能视为完整实现。
  • 将结果写入需求追踪表,并引用变更文件、方法/符号和测试证据;需求状态为 unavailable 时不得输出“需求符合”。

步骤 3.5:架构一致性评估

对新增类或新增入口,逐项核对其所在模块的既有模式和注册链路:Service decorator、依赖注入、gRPC 注解/基类、Pipeline Provider、召回 Chooser/Factory、排序 VariableShop、Nacos 配置和测试。若模式不适用,必须给出不适用原因;若无法从 diff 证明注册或装配成功,标记为“无法验证”并列为风险,而不是默认通过。

步骤 4:汇总输出

按“输出格式”生成结构化审查报告。

严重级别定义

级别 标识 含义 处理建议
Critical 🔴 可能导致生产故障、数据丢失、安全漏洞 必须修复后方可合并
Major 🟠 明显缺陷,影响可维护性或可能引发 Bug 强烈建议修复
Minor 🟡 代码风格、命名等可优化项 建议修复
Info 🔵 建议性意见,非必须 可选采纳

输出格式

# Java 代码审查报告

## 一、MR 概述

| 项目 | 内容 |
|------|------|
| MR 链接 | {url} |
| 变更模块 | {module} |
| 变更类型 | {feature/bugfix/optimize/refactor} |
| 修改文件数 | {N} |
| 需求基线 | {provided/none/unavailable;链接、Jira 单号或用户口述} |

### 整体评价
{一句话总结代码质量,如:“逻辑正确,但命名和异常处理有待改进”}

---

## 二、需求符合度评估(`provided` 时逐项评估;`none`/`unavailable` 时说明限制)

| 需求点 | 实现状态 | 说明 |
|--------|---------|------|
| {需求点1} | ✅ 已实现 / ⚠️ 部分实现 / ❌ 未实现 | {补充说明} |
| {需求点2} | ... | ... |

### 需求遗漏/偏差
{列出需求中未实现或实现有偏差的部分,若无则写“无”}

若需求基线为 `none`,写“未提供需求文档,本节不适用”;若为 `unavailable`,写明无法验证的原因和需要用户补充的内容。不要将无法验证写成通过。

---

## 三、架构一致性评估

| 检查对象 | 预期约定 | 实际证据(文件/符号) | 结论 |
|----------|----------|----------------------|------|
| 新增 Service / decorator | 同模块 Interface + Impl + decorator 约定、delegate 委托和无歧义 Bean 装配 | {path:line / 符号} | ✅ / ❌ / ⚠️ / ➖ |
| 新增框架入口 | gRPC 注解与基类、Pipeline/召回/排序/配置注册链路 | {path:line / 符号} | ✅ / ❌ / ⚠️ / ➖ |

无法定位证据时标记“无法验证”,并在 Merge 判定中说明影响。

---

## 四、按文件审查详情

### {🔴/🟠/🟡/🔵} 文件名:`{path}`

#### 问题 {N}:{问题简述}
```java
// 变更代码片段(2-6 行上下文)
  • 严重级别: {Critical/Major/Minor/Info}
  • 问题说明: {具体问题描述}
  • 潜在风险: {可能导致的后果}
  • 修改建议:
// 建议的修复代码
  • 参考规范: {阿里巴巴 Java 开发手册 §X.X / Google Java Style §X.X / Effective Java Item XX / 项目内部约定}

五、统计汇总

级别 数量
🔴 Critical {N}
🟠 Major {N}
🟡 Minor {N}
🔵 Info {N}

六、审查 Checklist

检查项 状态
代码符合阿里巴巴 Java 开发手册规范 ✅ 通过 / ❌ 不通过
依赖注入方式正确(构造器注入 + @Qualifier) ✅ 通过 / ❌ 不通过
命名符合项目约定(Impl/MonitorDecorator 等) ✅ 通过 / ❌ 不通过
新增 Service 的 decorator、delegate 与 Bean 装配符合模块既有模式 ✅ 通过 / ❌ 不通过 / ⚠️ 无法验证 / ➖ 不适用
新增入口已完成框架注解和注册链路(gRPC/Pipeline/召回/排序/配置) ✅ 通过 / ❌ 不通过 / ⚠️ 无法验证 / ➖ 不适用
无魔法值,常量/枚举使用恰当 ✅ 通过 / ❌ 不通过
空指针安全,NPE 风险已处理 ✅ 通过 / ❌ 不通过
异常处理合理,无吞异常或过度捕获 ✅ 通过 / ❌ 不通过
并发代码线程安全 ✅ 通过 / ❌ 不通过
资源(连接、流)正确关闭 ✅ 通过 / ❌ 不通过
性能无明显问题(无循环内创建对象/远程调用) ✅ 通过 / ❌ 不通过
SOLID 原则遵守良好 ✅ 通过 / ❌ 不通过
日志规范,无敏感信息泄露 ✅ 通过 / ❌ 不通过
单元测试覆盖充分 ✅ 通过 / ❌ 不通过
注释准确且充分 ✅ 通过 / ❌ 不通过
需求功能点完整实现(仅 provided) ✅ 通过 / ❌ 不通过 / ⚠️ 无法验证 / ➖ 不适用

七、Merge 判定

结论: {✅ 可以合并 / ⚠️ 建议修复后合并 / ❌ 不可合并}

判定依据:

  • 问题总数:{N} 个(Critical: {N}, Major: {N}, Minor: {N}, Info: {N})
  • 关键风险:{简述最关键的风险点}
  • 必须修复项:{列出必须修复的问题编号}
  • 建议修复项:{列出建议修复的问题编号}
  • 需求遗漏:{若有需求遗漏,说明影响}

Merge 判定标准:

  • ✅ 可以合并:无 Critical/Major 问题,或 Major 已确认不影响功能
  • ⚠️ 建议修复后合并:无 Critical,存在 Major 但可接受风险
  • ❌ 不可合并:存在 Critical / ≥2 个 Major / 业务逻辑缺陷 / 安全漏洞
  • 需求基线为 unavailable 时,不得以需求符合度作为通过依据;若变更依赖未验证的需求边界,应至少判定为“建议修复后合并”。

八、总结与建议

{总结性建议,如:}

  • 建议在合并前修复 Critical 和 Major 级别问题
  • 建议补充单元测试覆盖变更逻辑
  • 建议在日志中避免输出敏感信息

## 审查原则

1. **仅审查变更部分**:不审查未修改的原有代码
2. **代码片段必须包含上下文**:每处问题展示 2-6 行相关代码,不只有行号
3. **提供可执行的修改建议**:每个问题都给出具体的修复代码示例
4. **引用具体规范**:标注违反的具体规范条目
5. **区分事实与建议**:Critical/Major 是基于代码缺陷的客观判断,Minor/Info 是主观建议
6. **关注业务正确性**:searchEngine 是搜索推荐系统,重点关注召回逻辑、排序公式、特征计算等业务正确性
7. **需求驱动审查**:若提供了需求信息,需评估代码实现与需求的一致性和完整性

## 参考文档

- [review-checklist.md](references/review-checklist.md) — 完整审查清单
- 阿里巴巴 Java 开发手册
- Google Java Style Guide
- Effective Java (3rd Edition)
- OWASP Java Secure Coding Guide