CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
代码审查入门/课时/文档审查
RawBlame
课时目录12 节

代码审查入门

  1. 01API 语义审查
  2. 02实现语义
  3. 03文档审查
  4. 04测试审查
  5. 05代码风格
  6. 06Review 流程
  7. 07审查清单
  8. 08安全审查
  9. 09AI 辅助审查
  10. 10反馈技巧
  11. 11团队实践
  12. 12综合练习

文档审查

README 与变更说明。

25 分钟

文档审查

这一课你将能做到

  1. 审查 PR 时识别出「代码改了但文档没跟上」的不一致
  2. 写出有用的 Javadoc / 注释,删掉废话注释
  3. 审查 README、CHANGELOG、API 文档是否准确、可执行、面向读者

为什么要学

代码是写给人看的,顺便能在机器上跑。文档和注释是「为什么这样写」的唯一载体——代码只能告诉你「做了什么」,不能告诉你「为什么这么做」。

人话:三个月后你自己回来看这段代码,能不能在 30 秒内搞懂当时的考量?如果不能,就是文档审查没做到位。

先建立图像

一个 PR 里「文档」的完整范围:

PR 涉及文档的 4 层
├─ 代码内注释 / Javadoc       ← 解释「为什么」
├─ README.md                  ← 项目门面,新人能不能跑起来
├─ CHANGELOG.md / 提交信息     ← 历史与演进
└─ 外部文档(Wiki / OpenAPI)   ← 契约与使用手册

审查标准:
✓ 与代码同步(改代码必须改对应文档)
✓ 面向读者(写给谁看?对方要做什么?)
✓ 可执行(命令、示例能复制粘贴跑通)
✓ 解释 Why(What 代码本身会说)

跟着做

步骤 1:审代码内注释——删除废话

❌ 反例:

// 设置课程标题
course.setTitle(req.getTitle());

// 循环章节列表
for (Chapter c : chapters) {
    // 打印章节
    log.info("chapter={}", c);
}

/**
 * 获取课程
 * @param id id
 * @return 课程
 */
public CourseVO get(Long id) { ... }

✅ 正例:注释解释「为什么」和「不明显的坑」

course.setTitle(req.getTitle());

// 章节数量大时(>500)逐条打日志会刷屏,只打前 3 条用于排查
chapters.stream().limit(3).forEach(c -> log.info("chapter={}", c));

/**
 * 获取课程详情(含作者与章节数)。
 *
 * <p>注意:课程被软删除(deleted=1)时此方法仍返回数据,
 * 由上层 Controller 决定是否对 C 端隐藏,避免后台运营看不到历史数据。
 *
 * @param id 课程主键
 * @return 课程详情;课程不存在时抛 {@link BizException} COURSE_NOT_FOUND
 */
public CourseVO get(Long id) { ... }

审查动作:凡是「把代码翻译成中文」的注释,全部删掉。凡是解释「为什么这么写」「有什么坑」「什么时候会抛异常」的注释,保留并鼓励。

步骤 2:审 Javadoc 的完整性

公开 API(Service 层、工具类、对外 SDK)必须有 Javadoc;私有方法、显而易见的 getter/setter 不强制。

/**
 * 报名课程(幂等)。
 *
 * <p>幂等保证:同一 userId + courseId 重复调用不会产生重复记录,
 * 由数据库唯一索引 uk_course_user 兜底。
 *
 * @param courseId 课程 ID,不能为空
 * @param userId   用户 ID,不能为空
 * @throws BizException 名额已满 / 课程不存在 / 重复提交
 * @see CourseMapper#decreaseQuota
 */
void enroll(Long courseId, Long userId);

审查点:

  • 幂等性、线程安全性是否声明?
  • 边界条件(null、空集合)行为是否说明?
  • 抛什么异常、什么场景抛,是否列出?

步骤 3:审 README 的「新人跑通」能力

❌ 反例:

## 启动
mvn spring-boot:run

✅ 正例:

## 环境要求
- JDK 17+
- MySQL 8.0+(本地或 Docker)
- Redis 6.0+

## 快速启动
1. 初始化数据库
   mysql -u root -p < scripts/init.sql

2. 启动 Redis
   docker run -d -p 6379:6379 redis:7

3. 修改配置
   cp application-local.yml.example application-local.yml
   # 填入你的数据库密码

4. 启动
   mvn spring-boot:run -Dspring-boot.run.profiles=local

5. 验证
   curl http://localhost:8080/api/v1/health
   # 期望返回 {"status":"UP"}

审查动作:自己照着 README 在一个干净环境里跑一遍。跑不通就是 README 有问题。很多团队 README 是项目刚成立时写的,半年后再也没人验证过。

步骤 4:审 CHANGELOG 与提交信息

❌ 反例:

fix bug
update
优化

✅ 正例(Conventional Commits 风格):

fix(course): 修复课程名额并发超卖问题

之前用「先 count 再 insert」的写法存在 check-then-act 竞态,
并发报名时会超出 quota 上限。

改为:
- 数据库层用 UPDATE ... WHERE quota > 0 原子扣减
- 加 Redis 防重锁(10s TTL)拦截重复提交
- 保留 uk_course_user 唯一索引兜底

Closes #123

审查点:提交信息能否让半年后的人(或回滚时的运维)看懂「改了什么、为什么、影响面」。

步骤 5:审「代码改了但文档没改」

这是文档审查最常见的坑。检查清单:

代码改动必须同步的文档
新增/修改接口OpenAPI 注解、API 文档
改默认配置application.yml 注释、部署文档
加新依赖README 环境要求
改启动流程README 快速启动
改数据库表ER 图、迁移脚本注释
改环境变量.env.example、部署文档

审查动作:对照 PR 的代码 diff,逐项检查上面这张表。

讲清楚要点

  1. 注释的黄金法则:代码说 What,注释说 Why。翻译代码的注释是噪音,不如删掉。
  2. 公开 API 必须有 Javadoc:包括幂等性、线程安全性、参数边界、抛出异常。私有实现细节可以不写。
  3. README 是项目门面:新人能否在 30 分钟内跑起来,是 README 质量的唯一标准。
  4. 文档与代码同 PR 更新:「文档下次再补」基本等于「文档永远不会补」。审查时把「代码改了文档没改」当作阻断项。
  5. CHANGELOG 是给未来的自己看的:线上出问题要回滚时,CHANGELOG 决定你能不能 5 分钟内判断「这次问题是不是上次改动引入的」。

你可能会懵的地方

  • 注释和「代码即文档」冲突吗? 不冲突。好的命名、清晰的结构确实能减少 80% 的注释需求,但剩下 20%——业务规则、历史包袱、性能权衡、临时方案——代码本身表达不了,必须靠注释。审查时区分「代码该表达但没表达」(改名、抽方法)和「代码表达不了」(写注释)。

  • Javadoc 要不要写 @param @return? 参数名本身有语义时(courseId、pageSize),@param 可以省略;参数含义不直观(type=1 是什么意思)时必须写。@return 同理——返回 boolean 时最好写清楚 true/false 各代表什么。

  • README 要写多长? 够新人跑通即可。常见的 README 反模式:把 Wiki 内容全塞进来。README 只放「跑起来 + 项目结构 + 常用命令」,深度文档放 Wiki 并给链接。

  • 提交信息有必要写那么细吗? 看团队。但至少做到:标题行说清「做了什么」(动词开头,50 字内),正文说「为什么」和「影响面」。fix bug 这种提交在线上事故复盘时会让所有人骂娘。

  • 临时方案(hack)要不要注释? 必须!而且要带日期和负责人。// TODO(zhangsan, 2026-10): 临时方案,等 XX 接口上线后重构。否则半年后没人敢动这段代码。

错法对照

错法问题正解
// 设置标题 这种翻译式注释噪音,分散注意力删掉,或改为解释 Why
接口改了但 OpenAPI 注解没改前端拿错的契约文档同 PR 更新 @Operation @Schema
README 启动命令过期新人跑不起来,第一印象差定期验证 + CI 加 README 测试
提交信息 fix bug无法回溯定位Conventional Commits
Javadoc 只有 获取课程 四个字等于没写说明幂等性、边界、异常

卡点急救

  1. 老项目大量代码没注释,要不要补? 不要全量补(工作量爆炸且收益低)。只在你「改到这段代码时」补充——既降低单次成本,又让最常变动的代码先有文档。

  2. PR 太大,文档审查抓不住重点? 让作者拆 PR。超过 400 行变更的 PR,文档审查和代码审查都会流于形式。参考 Review 流程课的「PR 大小」原则。

  3. 团队没人写文档,怎么推动? 从「卡 CI」开始:接入 javadoc 校验、PR 模板强制填「文档更新」勾选项。先强制再养成习惯。

面试常问

  • 你怎么看待「代码即文档」? 同意一半。好的命名和结构确实能让代码自解释 What,但 Why(业务背景、权衡、历史原因)只能靠注释。实战策略:公开 API 必写 Javadoc,复杂业务逻辑必有注释解释 Why,临时方案必带 TODO + 负责人 + 日期。

  • 提交信息规范怎么做? 推荐 Conventional Commits:<type>(<scope>): <subject>。type 用 feat/fix/docs/refactor/chore 等;scope 是模块名;subject 是动词开头的短句。配套工具:commitlint 卡 CI,standard-version 自动生成 CHANGELOG。

  • 怎么做文档与代码同步? 三个手段:① 文档和代码在同一个仓库同 PR 评审;② CI 校验(如 springdoc 生成 OpenAPI 后和仓库里的契约文件对比 diff);③ 定期演练——新人入职第一周任务就是照着 README 跑通项目,跑不通的地方立刻提 PR 修文档。

自测三问

  1. 什么样的注释应该被删掉?什么样的注释必须保留?
  2. 改了默认配置但没改 README,会有什么问题?
  3. 一个合格的 Javadoc 至少应该包含哪三类信息?

小结一句话

文档审查的核心是「同步」与「面向读者」——代码改文档必改,文档写出来是给人跑通、给人看懂「为什么」的。

延伸

  • Google Java Style Guide - Javadoc
  • Conventional Commits 规范
  • 《The Art of Readable Code》
  • 下一课:测试审查——覆盖率与断言质量。
加载本节练习…
← 上一课实现语义下一课 →测试审查