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综合练习

团队实践

CODEOWNERS 与 SLA。

25 分钟

团队实践

这一课你将能做到

  1. 用 CODEOWNERS 文件实现「谁写的代码谁负责审」的自动化分配
  2. 设计团队的 Review SLA 并监控执行(首响时间、合并时长、PR 大小分布)
  3. 处理「新人不敢审」「资深审不过来」「跨团队互审」等典型组织问题

为什么要学

Code Review 做到最后是组织问题,不是技术问题。技术工具(CI、Lint、Checklist)解决的是「怎么审」;团队实践解决的是「谁来审、多久审完、审不动怎么办」。

人话:你配置了再好的工具,如果没人知道该找谁审、PR 挂一周没人看、新人不敢点 Approve,review 文化就死了。

先建立图像

团队 Review 健康度仪表盘

分配机制                    时效指标                  参与广度
├─ CODEOWNERS 自动分配     ├─ 首响时间 < 24h         ├─ 全员参与(不只资深)
├─ 负载均衡(轮流)        ├─ 合并周期 < 48h         ├─ 新人也敢审
└─ 紧急通道(hotfix)      ├─ PR 大小中位数 < 300 行  └─ 跨团队互审

          目标状态:
   「任何 PR 提交后 24h 内有人开始审,
    48h 内有结论,作者知道该找谁」

跟着做

步骤 1:配置 CODEOWNERS

.github/CODEOWNERS:

# 全局兜底:任何文件改动都至少通知这两个人
*                                        @zhangsan @lisi

# 后端核心模块:资深后端审
/src/main/java/com/example/course/       @backend-senior
/src/main/java/com/example/payment/      @backend-senior @wangwu

# 数据库迁移:必须 DBA 审
/src/main/resources/db/migration/        @dba-team

# 前端
/web/                                    @frontend-team
/web/components/payment/                 @frontend-team @zhaoliu

# 基础设施:DevOps 审
/Dockerfile                              @devops-team
/k8s/                                    @devops-team
/.github/workflows/                      @devops-team

# 文档:任何人都可以审,但至少一人
*.md                                     @zhangsan @lisi

规则:

  • 后面的规则覆盖前面的(越具体越优先)
  • 文件被改动时,对应的 owner 自动被加为 reviewer
  • 可以配置「必须 owner approve 才能合并」(Branch protection → Require review from Code Owners)

步骤 2:配置 Review 负载均衡

避免「所有 PR 都找同一个资深」:

# .github/workflows/assign-reviewer.yml
name: Auto Assign Reviewer
on:
  pull_request:
    types: [opened]

jobs:
  assign:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            // 从 CODEOWNERS 解析候选人,按当前 open PR 数排序,选负载最低的
            const reviewers = ['zhangsan', 'lisi', 'wangwu'];
            const { data: openPRs } = await github.rest.pulls.list({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open'
            });

            const load = {};
            reviewers.forEach(r => load[r] = 0);
            openPRs.forEach(pr => {
              pr.requested_reviewers.forEach(r => {
                if (load[r.login] !== undefined) load[r.login]++;
              });
            });

            const selected = reviewers.reduce((a, b) =>
              load[a] <= load[b] ? a : b
            );

            await github.rest.pulls.requestReviewers({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: context.issue.number,
              reviewers: [selected]
            });

步骤 3:定义并监控 SLA

团队 SLA 约定(写进 Wiki + 入职培训):

1. 首响时间:PR 提交后 24h(工作日)内必须有 reviewer 评论
2. 合并周期:从提交到合并 < 48h(排除周末)
3. PR 大小:新增 + 删除行数 < 400 行
4. 超时处理:超过 48h 没人审,作者可以在群里 @ 任何人
5. 紧急通道:[HOTFIX] 前缀的 PR 可以 1 人 approve 即合并,
   但必须 24h 内补正式 review

监控:用 GitHub API 或第三方工具(如 LinearB、Swarmia)拉数据:

# 拉取最近 30 天的 PR 数据
gh api graphql -f query='
{
  repository(owner: "myorg", name: "myrepo") {
    pullRequests(last: 100, states: MERGED) {
      nodes {
        number
        createdAt
        mergedAt
        additions
        deletions
        reviews(first: 10) {
          nodes {
            createdAt
            state
          }
        }
      }
    }
  }
}'

计算指标:

  • 首响时间 = 第一个 review 评论时间 - PR 创建时间
  • 合并周期 = 合并时间 - 创建时间
  • PR 大小 = additions + deletions

周报展示:

本周 Review 健康度
- 平均首响时间:18h(目标 < 24h)✓
- 平均合并周期:36h(目标 < 48h)✓
- PR 大小中位数:280 行(目标 < 400)✓
- 超 48h 未合并 PR:3 个(需关注)
  - #234: 支付模块重构(1200 行,建议拆分)
  - #236: 新人提交,reviewer 未响应(已介入)
  - #239: 依赖外部团队接口(已协调)

步骤 4:解决「新人不敢审」

❌ 反例:

新人:我经验不够,不敢给意见,还是等资深来审吧。
结果:所有 PR 都堆在资深身上,资深 burnout,新人成长慢。

✅ 正例:

策略:
1. 新人先做「学习性 review」——只看不 approve,评论里提问
   (「这里的 @Transactional 是怎么生效的?」)

2. 给新人分配「低风险 PR」——文档、测试、简单 CRUD

3. 资深做「二次确认」——新人 approve 后,资深快速过一遍
   (5 分钟),没问题就合并

4. 明确告诉新人:「你审出问题我负责,你漏审了我兜底」
   ——降低心理压力

5. 每月 review 分享会:资深讲解「我是怎么审这个 PR 的」,
   新人学习思路

步骤 5:解决「资深审不过来」

❌ 反例:

资深每天审 10 个 PR,每个 PR 平均 30 分钟,一天 5 小时没了。
结果:资深开始敷衍(LGTM),review 质量下降。

✅ 正例:

策略:
1. 分层审查:
   - 低风险 PR(< 100 行,非核心模块):中级工程师即可
   - 中风险 PR(100-400 行,核心模块):资深必须审
   - 高风险 PR(> 400 行,支付/订单等):资深 + 架构师双审

2. 时间盒:
   - 资深每天固定 2 个 1 小时的 review 时段
   - 其他时间不看 PR,专注编码

3. 授权:
   - 培养 2-3 个中级工程师成为「模块 owner」
   - 模块 owner 可以 approve 自己模块的 PR

4. 减少无效 PR:
   - 鼓励作者先自测(CI 全绿、本地验证)
   - 拒绝「我写完就提了,没看代码」的 PR

步骤 6:跨团队互审

场景:前端团队改了后端 API 的调用方式,需要后端审。

策略:
1. CODEOWNERS 配置跨团队 owner:
   /web/api/course.ts    @frontend-team @backend-liaison

2. 指定「接口联络人」:
   每个团队指定 1 人作为接口 liaison,负责跨团队 review

3. 契约优先:
   - OpenAPI / GraphQL schema 文件必须双方 approve
   - 契约变更提前在 RFC 讨论,而不是 PR 阶段才吵架

4. 定期同步:
   - 每周 30 分钟「接口对齐会」,双方同步最近的接口变更

讲清楚要点

  1. CODEOWNERS 是「责任到人」的自动化:改了什么文件,谁必须审,机器说了算,不靠人记。
  2. SLA 必须监控:定了 SLA 但不监控,等于没定。每周看数据,超时的 PR 要有人跟进。
  3. 新人参与是文化问题:不是「新人能力不够」,而是「团队没给新人参与的路径」。从「学习性 review」开始,逐步授权。
  4. 资深是稀缺资源:不能让资深成为瓶颈。分层审查、时间盒、授权模块 owner,三个手段组合使用。
  5. 跨团队互审靠契约:OpenAPI / GraphQL schema 是双方的「合同」,合同变更必须双方同意。

你可能会懵的地方

  • CODEOWNERS 会不会让 owner 成为瓶颈? 会,如果 owner 只有一个人。解法:每个模块至少配 2 个 owner;owner 休假时指定 backup;非核心模块不强制 owner approve。

  • SLA 会不会导致 reviewer 敷衍? 会,如果只考核「时间」不考核「质量」。解法:SLA 只是「最低要求」,质量靠 Checklist + CI + 定期抽查保证。同时给 reviewer 足够的时间盒,而不是「随时待命」。

  • 新人 review 漏了问题,线上出事故,算谁的? 算团队的,不是新人的。Review 是团队活动,不是个人责任。如果团队让新人独自承担高风险 PR 的 review 责任,是团队流程有问题。

  • 跨团队 review 意见不一致怎么办? 契约优先:OpenAPI schema 是合同,双方必须遵守。如果是「实现细节」的分歧,由实现方决定。如果是「接口设计」的分歧,升级到架构师或技术委员会。

  • 小团队(3-5 人)需要 CODEOWNERS 吗? 不需要。直接在群里喊一声就行。CODEOWNERS 是给「不知道该找谁审」的中大型团队用的。小团队的重点是 SLA 和「别让一个人审所有 PR」。

错法对照

错法问题正解
所有 PR 都找资深审资深 burnout分层审查 + 授权模块 owner
定了 SLA 但不监控SLA 形同虚设周报展示数据,超时跟进
新人只看不审新人成长慢,资深累死学习性 review → 低风险授权 → 资深兜底
跨团队 review 靠口头接口变更没人知道CODEOWNERS + 联络人 + 契约文件
PR 挂一周没人审作者失去信心SLA + 超时提醒 + 群里 @ 机制

卡点急救

  1. 资深请假一周,PR 堆积:提前指定 backup reviewer;非核心 PR 可以由中级工程师审;紧急 PR 远程联系资深。

  2. 新人不敢点 Approve:明确告诉新人「你 approve 后我会快速过一遍,有问题我兜底」;前 10 次 review 由资深陪同(结对 review)。

  3. 跨团队 PR 卡住:双方在群里 @ 各自的接口联络人;联络人 30 分钟内响应;如果联络人也无法解决,升级到双方 tech lead。

面试常问

  • 怎么设计团队的 Code Review 流程? 四层:① 分配机制(CODEOWNERS 自动分配 + 负载均衡);② 时效约定(SLA:24h 首响 / 48h 合并);③ 质量控制(Checklist + CI + 分层审查);④ 文化建设(新人培养 + 正面反馈 + 定期回顾)。最好带一个「我们当时遇到 XX 问题,用 YY 方案解决」的具体例子。

  • 怎么平衡「review 质量」和「review 速度」? 不矛盾。PR 越小,质量越高、速度越快。手段:① 控制 PR 大小(< 400 行);② CI 前置(不过 CI 不审);③ 分层审查(低风险 PR 中级工程师审);④ 时间盒(资深每天固定 2 小时 review)。

  • 怎么培养新人的 review 能力? 三步:① 学习性 review——新人只评论提问,不 approve;② 低风险授权——分配文档/测试/简单 CRUD 的 PR 给新人;③ 资深兜底——新人 approve 后资深快速过一遍。配合「每月 review 分享会」让资深讲解思路。

自测三问

  1. CODEOWNERS 文件的作用是什么?规则匹配的优先级是怎样的?
  2. 为什么说「定了 SLA 但不监控等于没定」?
  3. 团队里资深工程师成为 review 瓶颈,有哪些解法?

小结一句话

团队实践的核心是「让正确的行为成为默认行为」——CODEOWNERS 自动分配、SLA 监控时效、分层审查保护资深、新人路径保证传承。

延伸

  • GitHub CODEOWNERS 文档
  • 《Accelerate》(Nicole Forsgren)—— 工程效能的四个关键指标
  • 《Team Topologies》(Matthew Skelton)—— 团队结构与协作模式
  • 下一课:综合练习——Review 本站 PR 模拟。
加载本节练习…
← 上一课反馈技巧下一课 →综合练习