文档审查
README 与变更说明。
文档审查
这一课你将能做到
- 审查 PR 时识别出「代码改了但文档没跟上」的不一致
- 写出有用的 Javadoc / 注释,删掉废话注释
- 审查 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"}