open-code-review:从形式化到高效落地的Code Review实践指南

📅 发布时间:2026/10/19 4:31:02
open-code-review:从形式化到高效落地的Code Review实践指南
1. 代码审查这件事为什么这么多团队做不好代码审查Code Review在国内开发团队里是个挺微妙的话题。你说它不重要几乎所有团队都认同它重要你说它在认真做真正能把 Review 做出价值的团队少之又少。很多团队的 Code Review 流于形式变成了“走过场”合并前让人点个 Approve评论区里偶尔出现几句无关痛痒的“LGTM”或者更常见的——干脆不看直接通过。我在这个行业里待了十几年经历过不少团队也看过太多 Review 失败的案例。有些团队把 Code Review 当成纯粹的找茬活动Reviewer 和 Author 在评论区里争论到面红耳赤有些团队则把 Review 当成发布流程上的一个关卡谁都不想在这里卡住别人的进度于是草草通过还有一些团队因为代码规模实在太大Reviewer 根本看不过来最后只能靠自动化工具兜底Review 本身成了摆设。说白了大部分团队做不好 Code Review核心原因就三个没有标准、没有方法、没有反馈闭环。没标准Reviewer 全凭个人喜好评论今天觉得这里该抽方法明天觉得那里该加注释没方法Reviewer 不知道从哪看起打开 Diff 页面从头到尾扫一遍就算完事没反馈闭环Review 提出的问题改了就算了背后的原因没人复盘同样的错误下周又犯一次。我们在团队内部做过一次复盘把过去半年所有 PR 的 Review 评论拉出来做了个统计发现超过 40% 的评论集中在三个类型命名不规范、缺少边界处理、分支逻辑过于复杂。这三个问题里命名和边界属于“看一眼就能发现”的问题分支复杂则是“需要深入理解业务后才能判断”的问题。也就是说大部分 Review 评论都集中在前者真正影响系统架构和长期维护性的问题反而很少被提出来——因为 Review 的人根本没时间把整个 PR 的逻辑吃透。所以当我在考虑怎么把这次 review 机制重新梳理一遍时我给自己定的目标非常明确让 Code Review 从“走形式”变成“真能发现问题、真能提升代码质量、真能让所有人都参与进来”的一套流程。我把这套重新整理的方案命名为open-code-review意思是公开的、开放的、透明的代码审查机制——不是某个人关起门来审而是整个团队围绕一个 PR 展开的协作和沉淀。2. 整体设计思路把 Review 从“凭感觉”变成“按清单”2.1 为什么“凭感觉”的 Review 不靠谱先说个我自己的体验。刚开始带团队那会儿我给自己定的标准是“每个 PR 都认真看”但实际执行起来发现压根做不到。一个中大型项目的 PR动辄改几十个文件、上千行代码真要逐行看下来一个下午就没了。更尴尬的是很多时候我花了一下午看完提了一堆意见结果有一半被 Author 反驳说“这是业务逻辑需要”另一半是“这里确实有问题但这块代码是三个月前写的当时就没处理”。时间花了效果却很差。后来我复盘了一下问题出在“没有清单”四个字上。就像你去超市买菜有购物清单和没购物清单的效率是天差地别的。Review 代码也一样如果每个人都是拿到 PR 从头到尾看一遍凭直觉去发现问题那最后能发现什么主要取决于这个人的状态和运气——状态好能看出点门道状态不好就是走马观花。所以第一版 open-code-review 方案的核心就是把“凭感觉”变成“按清单”。我参考了 Google 的 Code Review 标准和一些开源社区的实践结合我们自己团队的业务特点整理了一份 Review 检查清单分成了几个维度功能性、可读性、安全性、性能、可维护性和测试覆盖。每个维度下有具体的检查项Reviewer 拿到 PR 后先对照清单逐项检查而不是打开 Diff 漫无目的地看。2.2 自动化先行人审只做机器做不了的事第二个思路是“自动化先行”。很多团队在 Code Review 上投入了大量人力但实际上有一批问题根本不需要人来看——格式问题、规范问题、简单的安全漏洞这些自动化工具就能拦住。把机械化的问题交给机器处理人才能把精力集中在真正需要判断力的事情上。我们团队目前启用的自动化检查链路是这样的开发本地跑 lint 和单元测试提交代码后由 CI 跑一遍构建和测试再跑静态代码扫描和测试覆盖率检查全部通过后才允许发起 Review 请求。也就是说走到人工 Review 这一步的 PR已经是“机器能发现的所有问题都修完了”的状态。这一步做下来最大的改变是 Reviewer 的体验。以前打开一个 PR光看格式问题和命名问题就要花掉一半时间现在这些问题已经被工具拦截了Reviewer 终于可以把注意力放在逻辑正确性、架构合理性这些真正需要脑子的地方。2.3 开放式协作Review 不是评审是对话第三个思路关于“开放”。我见过不少团队Code Review 做成了“上级审下级”——Team Lead 在评论里宣判其他人只敢围观甚至看都不敢看。这种做法跟 Code Review 的本质是背道而驰的。Code Review 的本质应该是同行之间的互相检查不是等级制度下的审批。open-code-review 在设计的时候有一个原则任何人对任何 PR 都有评论的权利同时也都有回复评论的义务。没有所谓“只有资深工程师才能评论”的说法。新人对代码中可读性部分提的意见往往比一些资深工程师更敏锐因为他们天然会站在“第一次读这段代码的人”的视角去看问题。我还在团队里提倡一个习惯写评论的人尽量把话说清楚——你是在“提问题”还是在“提建议”还是在“单纯表示不理解”。这三者的语气应该是不同的。提问题时给出具体的场景和触发条件提建议时说明建议的原因和改进后的效果不理解时可以直接说“这段逻辑我没看懂能不能解释一下”。这看似是很小的事情但实际操作下来它能极大降低 Review 中的对抗感让讨论聚焦在代码本身而不是人与人之间。3. 核心细节解析一个高质量 Review 到底该看什么3.1 功能性审查不只是“代码能跑”就行功能性审查是所有审查维度里最基础却又是最容易被跳过的一项。很多 Review 的评论只停留在“这个函数命名不对”“这段逻辑需要加注释”这个层面而对于“这段代码到底能不能正确处理所有边界情况”反而不去关注。我在团队里反复强调一个理念看代码不要顺着 Author 的思路走要故意反着来。顺着思路走你会觉得每段代码都挺合理反过来想才能发现问题。举个例子假设有一个用户查询接口传入了分页参数 pageNum 和 pageSizeAuthor 的代码里写了两个默认值你顺着看觉得没问题。但你反过来想pageNum 传了 0、负数或者非数字类型时会发生什么pageSize 传了超过 100 的大数字会发生什么这些情况在真实业务中出现的概率并不低但很多 Reviewer 从来不会主动去想。功能性审查里有一个很有效的技巧叫“等价类划分”。简单来说就是把输入数据按照“处理逻辑是否相同”分成几个类别每个类别各选一个代表性输入来验证。比如上面这个分页参数有效值、零值、负值、超级大值、非数字值每个类别各测试一遍基本就能覆盖绝大多数潜在问题。Reviewer 在看代码时如果能用这个思路去梳理边界条件大部分功能性 bug 其实都能在 Review 阶段被拦截下来。3.2 可读性审查你不是在写给自己看的可读性的问题听起来有点虚但实际上它是影响项目长期维护成本最大的因素之一。代码写出来是给人看的其次才是给机器执行的。一个人写的代码如果只有他自己能看懂那这个代码在交付的那一刻就成了团队的技术债。从 open-code-review 的实践来看可读性审查有几个具体的切入点。第一个是命名变量名、函数名、类名是否符合它的职责是否足够自解释。我不要求命名必须是英文单词全拼但至少要保证“看到变量名能猜出它的大概用途”而不是清一色的 data、result、temp。第二个是函数长度和复杂度单个函数尽量不要超过 40 到 50 行嵌套层级不要超过三层。一旦超过这个规模阅读者就需要很强的上下文记忆能力才能跟上代码的逻辑这会显著增加理解成本。如果看到一个大函数审查意见通常是“抽方法”把一段独立逻辑抽取成一个语义清晰的小函数这样整体可读性会有质的提升。第三个是注释的使用好的注释应该解释“为什么这么做”而不是重复“做了什么”。我在 Review 中最常见到的一种无用注释就是在代码行上方加一行“// 从数据库查询用户列表”然后下面是等价的一行代码。这种注释在 Review 的时候应该直接打回要求删除或者改写成说明意图。3.3 安全与性能隐藏得最深的两个大坑功能性和可读性属于“一眼能看得差不多”的维度但安全问题和性能问题往往是隐藏最深的。一个看起来姿势很优雅的代码片段可能就藏着一个越权漏洞或者一个慢查询。安全审查这块我们在 Review 时有一个固定的思考链路**这个接口谁可以访问数据谁能看、谁能改传给数据库或者渲染层的值有没有经过合法性校验**想起一次真实的踩坑经历当时有一个后台管理的接口Author 在做权限控制时只校验了用户是否登录没有校验用户是否拥有对应角色的权限。单看代码逻辑确实没有语法问题但在安全测试阶段用一个普通账号直接调接口就拿到了管理员才能看到的数据。从那以后我们要求所有涉及后台管理、涉及用户私有数据读取的 PRReviewer 必须重点检查权限校验逻辑不能只看“这段代码本身执行对不对”。性能审查方面最容易踩坑的是数据库查询。我们在 Review 中要求特别关注循环里的查询——一旦看到 for 循环内部出现数据库操作就要立刻警觉。这种 N1 查询在数据量小的时候完全没有感知等到线上数据量上来了接口瞬间就会被打垮。另外还要关注索引的使用查询条件里的字段如果没有索引全表扫描在大表上是灾难性的。这些问题的共同特点是代码在本地跑不出问题只有到了线上才爆。Review 阶段如果能把住这一关省下的运维成本不是一点半点。3.4 测试覆盖你写了测试但不等于覆盖了很多团队把“写了测试”当作目标导致测试变成了纯刷覆盖率数字的工具。但我们要的不是覆盖率报告上的百分比而是关键路径真的被测试到了。open-code-review 里对测试的审查有一个核心问题**这些用例有没有在“验证逻辑”而不是“验证实现”**如果测试用例是跟着实现代码一步一步写的那实现写错了测试也会跟着写错结果就是测试全绿代码全废。真正有价值的测试用例应该是在写测试的时候就预设一个“坏实现”看看测试能不能把它拦下来。如果无论实现怎么改你的测试都能通过那这个测试基本没起到校验作用。具体的 Review 实操中我们会针对这几类情况重点检查测试核心业务逻辑是否有异常分支用例、边界值和非法值是否有用例覆盖、涉及时间计算的逻辑是否验证了不同时区/时间戳下的结果、并发场景是否至少有一个用例覆盖。每一条测试用例我都会要求 Author 在 PR 描述里简单说明“这个用例验证了什么逻辑”这样 Reviewer 在审查时就能更快地判断测试的有效性。4. 实操落地从零开始搭一套 open-code-review 流程4.1 起点先梳理现状再定流程如果你也想在团队里落地一套 Code Review 流程我的建议是不要照搬任何一家公司的现成方案先梳理清楚自己的现状。问自己几个问题团队有多少人每个人每周大概产出多少个 PR一个 PR 平均改多少行代码目前 Review 卡在哪个环节是没人看、看不懂、还是看完了不讨论这些问题的答案会直接影响流程设计。小团队五个人以内和几十个人的团队设计逻辑是完全不同的。小团队可以考虑不做强制关卡让 Review 变得更像日常协作的一部分大团队则更需要制度和工具的保障比如 Review 请求超时提醒、指定 Reviewer 的规则等等。我个人的建议是不要一开始就上一套很复杂的流程。先定最基础的规则PR 必须经过至少一个非作者的同事 Review 才能合并Review 评论必须明确是“必须改”还是“建议改”Author 对每一条“必须改”的评论必须给出修改或解释的回复。这三条规则跑几个 Sprint 之后再根据实际体验做调整。4.2 配置检查清单一个可以直接抄的模板我把我们最终采用的 Review 检查清单整理如下你在设计自己的清单时可以直接参考然后根据业务特性做增删维度具体检查点功能性正常路径是否完整走通边界值是否处理异常路径是否有兜底接口/方法是否校验输入参数可读性命名是否自解释函数是否过长/过深是否有冗余注释是否存在明显可抽取的重复代码安全性接口是否校验登录态和权限用户输入是否过滤是否涉及 SQL 注入/越权风险敏感数据是否脱敏性能循环内是否有数据库操作查询是否用到合理索引是否存在大对象加载/复制缓存使用是否合理可维护性变更是否涉及配置项/常量依赖是否有清晰版本控制删除代码是否干净无注释掉的死代码测试关键逻辑是否有用例覆盖是否存在极端/边界用例测试是否验证逻辑而非实现细节这里要特别提醒一下清单不是法律条文它是用来帮助 Reviewer 校准视角的工具不是一定要逐条打钩的流程。如果一个 PR 只是加一个常量或者改一个日志级别没必要硬凑着每条检查项都过一遍。清单的价值在于“提醒”不在于“强制”。4.3 PR 描述模板让 Review 更高效的第一步Review 效率低的另外一个隐形原因是 PR 本身就写得不好。很多开发者的 PR 描述只有一句话——“fixed a bug”或者“更新代码”Reviewer 只能打开 Diff 猜这个 PR 做了哪些事情、为什么这样做、有哪些风险点。为了从源头上提升 Review 体验我们的 PR 模板是这么设计的变更背景和目的为什么要做这个变更解决什么业务问题变更内容说明核心改动了哪些模块主要的实现思路是什么重点审查说明哪些地方希望 Reviewer 重点看有没有需要特别确认的假设测试说明本地做了哪些验证覆盖了哪些场景部署与兼容性考虑是否涉及数据库变更、是否影响已有接口行为、是否需要回滚预案别看只是加了一个模板实际执行起来效果非常明显。Author 在填写模板的过程中自己就会重新审视一遍代码相当于提前做了一次自我 Review。Reviewer 收到一个描述清晰的 PR可以直接带着问题去读代码不再需要从头猜。4.4 现场复盘一个真实 PR 的完整 Review 实例为了让你更直观地理解这套流程是怎么运转的我拿一个真实发生的 PR 来复盘一下。背景是我们有一个积分系统需要新增一个“积分过期提醒”的定时任务。Author 的实现方案是写一个定时任务每小时扫描一次积分表把当前时间超过过期时间且未使用的积分记录查出来调用消息服务给用户发送提醒。我拿到这个 PR 后没有急着看代码细节而是先看 PR 描述里的“重点审查说明”。Author 自己标了两点积分查询 SQL 写了针对过期条件的索引消息触达做到了同一个用户多次过期合并成一条提醒。带着这两个自证点我再去看代码。看 SQL 时发现一个问题查询条件是expire_time NOW() AND status unused虽然 Author 说建了索引但复合索引的字段顺序是(status, expire_time)。在这个查询条件下status 是等值匹配expire_time 是范围匹配(status, expire_time)的顺序是合理的。这个没毛病。但再看定时任务的调度方案时问题就出来了Author 直接在应用层写了一个Scheduled(cron 0 0 * * * ?)的注解也就是每小时整点跑一次。这个方案在单实例部署时没问题但如果应用是部署多个副本的等于每台机器都会同时跑一遍这个任务重复触达就会发生。Author 自己标记了“合并提醒”但没有考虑多实例部署导致的任务重复执行。我在 Review 评论里给出了两个层面的建议第一M层注释是否需要本项目已有分布式锁工具建议引入避免多实例同时执行第二即使不做分布式锁也建议增加一个幂等机制比如用数据库唯一约束来避免给同一个用户重复发送提醒。这两个建议都被 Author 采纳后续在测试阶段也确实发现了重复消息的问题。这个 PR 的完整 Review 过程其实就用到了前面说的几个方法先看 PR 描述、再按维度逐项过、重点审查关键逻辑的边界和异常场景、最后给出明确的修改建议。5. 工具链选型什么场景用什么配置5.1 代码托管平台的内置 Review 能力代码托管平台是 Code Review 的物理载体目前主流的选择是 GitLab、GitHub 和 Gitee 这几种。如果你的团队项目托管在这些平台上我建议优先把平台自带的 Code Review 能力用足而不是急着找第三方工具。GitLab 的 Merge Request 功能内置了讨论、评论、approve 等能力还支持通过 CI 状态来控制是否允许合并GitHub 的 Pull Request 生态比较成熟配合 GitHub Actions 可以做出很多自动化的 Review 辅助能力Gitee 在国内访问速度有优势团队协作的基础功能也比较齐全。平台内置能力的最大好处是“没有额外维护成本”团队成员不需要额外切换工具直接在原有的开发流程里就能完成 Review。缺点是内置能力的灵活性有限复杂规则需要通过 API 或者 Webhook 自己做二次开发。如果你的团队有比较多的自定义规则比如“必须指定两名 Reviewer”“PR 中某种文件类型必须让某位同事看”可以考虑引入专门的 Review 辅助插件或机器人来实现。但我的建议是宁缺毋滥规则先少后多跑顺了再加。5.2 静态分析与 AI 辅助人审的前置关卡静态分析工具是 Code Review 前置关卡中性价比最高的一环。这类工具可以在不运行代码的情况下通过解析源码发现潜在的 bug、安全隐患、代码坏味道等问题在提交代码后的第一道流水线上就把低级问题拦下来。具体到不同技术栈可选方案也不同。Java 生态可以选 SonarQube、SpotBugs、PMDPython 可以跑 Ruff、BanditJavaScript/TypeScript 可以选 ESLint、CodeQL。这些东西的配置成本不高但收益很直接绝对是“用机器换人工”的典型例子。最近两年基于大模型的 AI 辅助 Review 工具也越来越多比如 GitHub Copilot Code Review、CodeRabbit 等。我个人试过几款总体感受是AI 工具对于“单文件范围内的逻辑问题和代码质量问题”比较敏感能帮你发现一些容易漏掉的边界情况和不规范写法但对于“跨模块的架构影响”“业务逻辑的正确性”这类需要深度上下文理解的问题目前的 AI 工具还远达不到可以替代人工评审的水平。所以我对 AI 辅助 Review 的定位是这样它可以作为 Reviewer 启动人工审查之前的“第一双眼睛”帮人筛选出那些明显的低级问题但最终合不合并的决定权一定要留在人的手里。千万不要把 Review 完全交给 AI那是拿线上质量去冒险。5.3 常见误区别把工具当成 Review 的全部工具能帮我们做很多事情但它永远替代不了人的判断。我见过一个团队上了 SonarQube 之后把 Review 的重心几乎全部放在“消除代码扫描告警”上。一段时间后代码扫描告警数量确实降下来了但线上故障率一点没降——因为真正导致故障的是业务逻辑的边界问题和系统之间的交互问题静态扫描工具根本发现不了。这是一个非常典型的错误。一个好的工具链应该像一条流水线最基础的问题交给机器复杂的问题留给人工。但人工 Review 永远是不可替代的核心环节机器只是前置的过滤器。如果你的团队把“让代码扫描通过”当作 Review 完成的标准那说明流程的顶层设计就已经跑偏了。6. 实践中的踩坑记录与经验技巧6.1 最常见的坑PR 太大Reviewer 根本看不过来如果说 Code Review 实践中有什么问题是出现频率最高的那肯定是 PR 太大导致的“看着看着就放弃了”。一个 PR 改动超过 1000 行Reviewer 就很容易疲惫超过 2000 行绝大多数人已经放弃逐行审核了。Review 的核心质量正是在这个环节悄悄流失的。解决这个问题的思路有两层。第一层是“治本”——引导团队拆更小的 PR。工具层面其实有辅助手段Git 支持把一个需求拆成多个小 commit推送到同一个分支后Reviewer 可以按 commit 逐个审查而不是一次看全量的 Diff。我在团队里的建议是把一次需求拆成“数据模型变更”“核心逻辑实现”“接口对接”“测试补充”这样几个阶段每个阶段单独一个 commit每个 commit 承担的复杂度有限Review 的质量自然会上来。第二层是“治标”——如果某个 PR 因为业务原因确实必须很大那就不要安排一个人从头看到尾让 Review 任务按模块拆开不同人负责不同模块的审查。比如 A 同学看数据库迁移和模型层B 同学看接口和业务逻辑层C 同学看前端调用和联调部分。这种“多人分模块看一个大 PR”的策略能有效降低单人的阅读负担。6.2 人性的问题怎么让大家愿意认真 Review技术问题好解决但人的问题才是 Code Review 落地最大的阻力。很多团队的现状是每个人都想让别人 review 自己的代码但没几个人愿意花时间去 review 别人的代码。原因很直接——Review 别人的代码需要花时间但没有直接的收益反馈做得好也没有人夸做得不好还可能得罪人。我在团队里尝试过几种做法效果比较明显的是这几个。第一个是“轮流主持”每个迭代指定一位同学负责统筹本迭代所有待 Review 的 PR跟踪状态、协调 Review 人选、推动问题闭环。这样 Review 就不再是“想起来才做”的事而是被纳入了既定日程。第二个是“Review 正反馈拉满”当某个人提出了一个很有价值的 Review 意见时一定要在团队里公开讲出来。“某某在 Review 中发现了一个只有线上大数据量才会触发的并发问题帮我们提前排掉了一个雷建议大家以后都留意这种情况。”这种公开的认可比任何考核指标都管用因为它让提意见的人感受到自己的付出是被看见的。第三个是“反对负向指标”这是我个人最看重的一条原则绝不用“Review 提了多少条意见”“驳回率多少”作为考核或排名依据。一旦把 Review 数量和绩效挂钩人性的劣根性就会被激发有些人为了凑数会在无关紧要的地方硬找问题有些人会为了避免冲突选择当老好人。最后整套机制就会变味。6.3 异步与跨时区协作异地团队怎么玩转 Review很多团队现在都有异地甚至跨时区协作的情况这给 Code Review 带来了新的挑战。最大的问题是响应延迟——你在国内下午提了 Review 请求Reviewer 可能已经下班或者在地球的另一边的凌晨。跨时区团队跑下来我觉得最核心的调整是把“像开会一样同步 Review”变成“像记账一样异步 Review”。用文档化的方式把所有信息沉淀下来包括 PR 描述、Review 评论、修改记录和决策依据确保任何人在任何时间点接手都能快速进入状态。另外设定一个 SLO 也很有帮助。比如“PR 创建后 24 小时内必须收到第一条 Review 反馈”超时后自动提醒 Reviewer 或自动扩容到其他成员。这个机制特别适合大团队它不依赖任何一个人的自觉性而是靠制度兜底。6.4 复盘机制从单次 Review 反馈中提炼团队改进点前面提到反馈闭环这实际上是 open-code-review 里我认为最有长期价值的一环。很多团队的 Code Review 做完就完了改完就合并合并完就忘掉。如果一次 Review 发现的典型问题能够在团队内沉淀下来下一次所有人写代码时都能主动绕开那这个团队的技术能力会以肉眼可见的速度提升。我的做法是每隔两个迭代做一次 Review 复盘会。会上不是逐条过评论而是把这一阶段的高频问题进行归类总结出 Top 3 共性问题然后针对性地去做一件事要么更新团队开发规范要么组织一次专项培训要么引入一个新的自动化检查规则。举个例子有段时间我们团队写的接口代码里出现了好几次“数据库查询结果为空时不处理直接取下标 0”的问题导致线上偶发报错。这类问题修起来不难但反复出现非常烦人。复盘会发现这个问题后我们做了一件事在代码规范里明确加了“任何集合查询必须处理空结果”的强制约束同时在单测模板里也加上了一个空结果的测试用例。从那次以后这类问题在团队里就基本绝迹了。复盘的意义不是找谁的锅而是把个人的经验沉淀成团队的能力。Code Review 的价值一半在“当时发现的那个 bug”另一半在“发现这个 bug 后对团队长期认知的提升”。后者才是真正持续复利的东西。7. 一些真心话与补充技巧走到这里open-code-review 的整套思路和实践方法基本都讲完了。最后我再补充几个散落在实践中的小技巧都是亲测有效的经验。第一Review 评论里的语气很重要。建议把“你这里写错了”换成“这里有风险隐患我们确认一下”把“这代码看不懂”换成“这段逻辑我花了几分钟才理解是不是可以考虑换个更直观的写法”。一句话的区别决定了对方是防御性地反驳你还是开放性地听进去。第二你可以把 Review 清单打印出来贴在工位上也可以做成浏览器书签随时参考形式不重要重要的是你真的在用它。清单可以随着团队的阶段不断调整一开始列二十项跑熟了之后精简到十项都是正常的演化过程。第三不管团队规模多大从今天开始哪怕只做一件事也比什么都不做好。你可以先从“给每个 PR 写清楚描述”开始也可以先从“每次 Review 至少提一条真问题”开始。只要方向是对的流程会慢慢生长出来。Code Review 真正难的不是工具不是流程而是让每个人都愿意把心思放在“帮别人把关、也帮自己把关”这件事上。当团队里形成了这种氛围你会发现它不仅提升了代码质量还顺便带出了一个更有ownership感的团队。这大概是我做这套事情最大的收获了。