一位开发者提交了一个拉取请求,为结账服务添加了折扣计算功能。测试通过,差异很小。一位审核员两分钟就批准了,并评论“LGTM”(看起来不错)。三个月后,一位团队成员需要修改同一个功能,却发现它把定价规则、舍入和数据库访问混杂在了一起。没有人能确定哪些操作是允许的。
这是一个示例场景,并非已记录的事件。它展示了当同行代码审查作为一种学习活动发挥作用时,应该产生什么结果:审查者能够看到合理的变更,发现尚未被认定为缺陷的问题,并以作者能够理解的方式进行解释。
本指南面向工程赋能负责人和工程经理,展示了如何进行设计。 代码审查练习 与其指望评审员在待审稿件中自然而然地发现这项技能,不如有意识地培养它。它涵盖了性能问题、需要诊断的差距、如何安排准备和练习、一个已完成的示例,以及如何检验这项技能能否应用于实际评审。在使用前,请务必让资深工程师验证每个案例、缺陷和标准。
什么是代码审查练习?
代码审查练习是一种结构化的实践任务,开发人员需要审查预先准备好的变更,解释他们发现的问题及其重要性,并获得关于解释质量的反馈。这与团队日常进行的审查有所不同。变更事先选定,其中的问题也已明确,其目的在于提升审查者的能力,而非发布变更本身。
要闻速览
| 问题 | 简答 |
|---|---|
| 任务是什么? | 解释评审结果,并向作者提供可采纳的反馈意见。 |
| 你得了多少分? | 研究结果的准确性以及解释的实用性。 |
| 统计缺陷数量就足够了吗? | 不。评论不仅仅是关于缺陷,所以只奖励缺陷数量的做法会养成错误的习惯。 |
| 认知需求是什么? | 分析和评估设计方案,然后提出更好的建议。 |
| 谁来验证这个案例? | 负责代码库的工程经理或高级工程师。 |
| 哪些问题是运动无法解决的? | 审查时间长、所有权不明以及快速合并的压力。 |
| 你怎么知道它奏效了? | 一项新的、未曾公开的变更,根据既定标准进行审查,并根据实际审查结果进行后续跟进。 |
1. 描述性能问题
首先,用一句话概括任务:审阅者需要解释他们发现的问题、问题的重要性以及作者可以采取的应对措施。“解释”是关键。发现问题是成功的一半,而另一半则是能够清晰地表达出来,让持有不同观点的同事也能理解、权衡并采取行动。
现代代码审查的研究表明,不应仅仅关注缺陷查找。在微软的一项研究中,Bacchelli 和 Bird 对开发人员和管理人员进行了观察、访谈和调查。他们发现,发现缺陷仍然是代码审查的主要动机,但审查的重点远不如人们预期的那样在于缺陷。代码审查还带来了其他益处,例如知识共享、团队意识和替代解决方案。研究人员将对代码和变更的理解描述为代码审查的关键方面。Bacchelli 和 Bird,ICSE 2013这是一项针对一家公司团队的研究,所以请将其作为理解性设计的理由,而不是作为您自己团队的衡量标准。
谷歌发布的审查标准也指向同一个方向。它告诉审查员,即使代码并不完美,只要更改能够显著改善代码的整体健康状况,就应该优先批准;它还指出,审查可以教会开发者一些新东西,因此欢迎有助于他人学习的评论。谷歌工程实践这两个来源都将评审描述为运用和传递判断力的场所。这正是你的练习应该着重演练的内容。
2. 诊断学习和情境差距
将这项任务与你当前课程的练习和评估内容进行比较。
- 目前的做法是否使用了实际任务? 如果新审阅者通过阅读风格指南并审阅实际的拉取请求来学习,他们就能在真实的工作环境中练习,而没有犯错的余地。如果评估方式是审查礼仪的测验,那么它衡量的是审阅者对规则的记忆,而不是将规则应用于实际变更的能力。
- 认知需求是什么? 在修订后的布鲁姆分类法中,判断设计是否合理并权衡其利弊属于分析和评价层面,而提出更优的结构则属于创造层面。如果你的练习只问“这段代码是做什么的?”,那就止步于理解。我们的指南…… 将学习活动与布鲁姆分类法相匹配 展示了如何将活动与水平相匹配。
- 除了技能之外,还有其他因素阻碍了你吗? 检查审核时间、工具、负责人和团队规范。如果审核人员每个拉取请求只有五分钟时间,那么任何努力都无法产生深思熟虑的解释。如果作者将每条评论都视为批评,审核人员就会逐渐淡化他们的意见,直到最终什么也不说。将这些问题报告给能够解决它们的人员。
3. 设计准备、练习和反馈
给每个阶段分配单独的任务。
准备。 在审阅者开始审阅之前,请确认他们需要哪些信息:团队的审阅清单、所依据的设计原则,以及如何在你们的工具中解读差异。审阅过程应保持自主节奏,并尽量简短。回顾性检查仅用于确认前提条件,并不能证明审阅者具备审阅能力。
实践。 使用预先准备好的变更,其中包含少量不同类型的预设问题:一个正确性错误、一个可维护性问题(例如开篇示例中的职责混合)、一个不清晰的名称或缺失的测试,以及一些没有问题的代码。请审阅者写下他们会留下的评论,对这些问题进行排序,并说明他们还需要哪些信息。CodeRefinery 的实践课程展示了这种模式:人们创建一个包含一个小拼写错误和一个较大错误的拉取请求,然后以同行身份进行审阅(CodeRefinery,实践代码审查)从你自己的代码库构建,这样约定和权衡取舍才是真实的。
反馈。 将其与审阅者做出的决定联系起来。“你注意到了舍入问题,但你的评论只是说‘这看起来不对劲’,却没有说明是哪个输入导致了这个问题”比“发现了 4 个问题中的 2 个”更有用。
实时输入还是异步审核? 当问题含糊不清时,实时反馈最具价值,审阅者可以从资深工程师的解释中获益,了解他们提出问题或放弃问题的原因。异步审阅足以将评论与带有注释的专家审阅进行比较。
4. 通过一个实际例子进行分析
举例说明。工程经理在使用前应验证案例和答案标准。
案子。 一项变更在结账服务中添加了折扣计算功能。该变更通过了所有测试。在一个函数中,它应用百分比折扣和固定折扣,对结果进行四舍五入,写入数据库并发送事件。它只有一个测试用例,用于测试单个百分比折扣。
任务。 审稿人写下他们要留下的评论,对他们的担忧进行排序,并说明在批准之前他们需要知道哪些信息。
第一次尝试。 “看起来没问题,测试通过了。或许可以拆分一下?”审阅者注意到了一些问题,但没有说明是什么问题,为什么重要,或者应该怎么做。作者无法据此采取行动。
反馈并重试。 主持人会问:未来对这个功能的改动可能会破坏哪些现有功能?在批准之前,您会要求作者添加哪些内容?重试环节要求针对每个问题给出具体评论,包括原因和建议。
一次更有力的尝试。 该函数应用两种折扣、四舍五入、保存并发布事件,因此四舍五入方式的更改可能会同时影响我们存储和发布的内容。我建议将定价规则移到一个纯函数中,以便我们可以单独进行测试。目前的测试仅涵盖百分比折扣。我希望增加固定折扣和使总金额为零的订单测试。我不确定事件是否应该在总金额为零时触发,因此我建议向作者咨询。请注意,此评论指出了问题所在,给出了原因,提出了具体的建议,并说明了审阅者不了解的内容。
5. 评估能力并制定转移计划
能力证明是指对评审员未曾见过的新变化进行评估的表现。对评估结果的准确性和解释的实用性进行评分。一个简单的评分标准是每个标准采用 0 到 2 分的等级:
| 标准 | 可观察的证据 |
|---|---|
| 任务执行 | 找出变更中的相关问题,并记录每项问题的证据。 |
| 推理 | 解释每个问题的重要性,提供替代方案,并说明仍然存在的不确定因素。 |
| 边界 | 遵循团队的审查规则,并在缺乏权限或背景信息时寻求帮助或信息。 |
评分标准:0 分表示缺失或缺乏支持,1 分表示部分缺失但存在相关遗漏,2 分表示完整且符合既定标准。请单独定义关键错误,例如批准存在数据丢失风险的变更,以免高分掩盖关键错误。请与工程经理共同调整评分标准;本评分细则仅为初步方案,并非最终验证的就绪标准。有关评分依据的更多信息,请参阅我们的指南。 设计具有实用反馈的互动练习.
制定迁移计划。演练结束后,几周后使用相同的标准,抽取部分审阅者的实际审阅记录进行检查。与培训前的基线数据进行比较,并预先确定样本人群和时间安排。在评估演练效果之前,还要考虑同期发生的其他变化,例如新的审阅工具或人员变动。
6. 使用 AhaSlides 进行实时或自主节奏的练习
您可以将练习安排在研讨会上,也可以让审阅者自行完成。在现场会议中,展示准备好的修改内容,并使用交互式幻灯片进行讨论:
- 选择答案 对于“您会首先提出哪个问题?”这个问题,请将预设的问题作为选项。在公布您自己的排名之前,先展示所有选项的分布情况。
- 开放式 对于“写下你想留下的评论”这一题,审阅者可以将自己的措辞与其他审阅者的措辞进行比较,这正体现了审阅者的解释能力。
- 评定量表 为了“这有多严重?”,以便小组能够看到判断上的差异,并讨论原因。
对于无法到场的审阅者,可以按照相同的流程进行自主学习,每次回复后都会显示专家注释。在您使用自己的代码进行测试之前,请将任何关于代码执行、集成或人工智能功能的说法视为未经证实。
如果您还对代码审查员进行人工智能编写代码的培训,请参阅我们的配套指南。 AI生成的代码审查培训那篇文章是关于审核生成的输出结果的。这篇文章是关于人们如何互相审阅彼此的工作,以及如何解释他们发现的问题。
可能存在的限制
- 复习时间。 一条深思熟虑的评论需要比“LGTM”更长的时间,而截止日期却迫使人们选择简短的版本。
- 团队规范。 如果反馈被解读为个人批评,审稿人会淡化或放弃他们的评价。
- 案件承保范围。 一项练习展现了几种类型的担忧。分数并不能反映评论者的整体判断。
- 转让。 车间里的表现与繁忙排队时的表现并不相同,所以也要查看真实评价。
尽早将这些问题告知赞助商,并制定单独的解决方案。练习可以提高审阅者观察和解释的能力,但并不能创造时间或规范。
常见问题
什么是代码审查练习?
这些练习任务是预先准备好的,开发人员需要审查一个已知存在问题的变更,写下他们会留下的评论,并获得关于准确性和实用性的反馈。其目的是为了提升审查者的技能,而不是为了发布变更。
如何评估审稿人的判断力是否有所提高?
提出他们未曾见过的新变化,并根据既定标准对发现的问题和解释进行评分。几周后,再检查一些真实的评论样本。关于评论规则的测试仅用于确认前提条件。
同行代码审查的主要目的是发现错误吗?
发现缺陷仍然是主要动机之一,但微软的一项研究发现,评审中缺陷的占比低于预期,同时也促进了知识共享和团队意识的提升。设计评审活动时,应奖励解释和理解,而不仅仅是缺陷数量。
从哪儿开始
选择一种团队经常需要评估的变更类型。撰写绩效说明,请一位资深工程师准备一个包含三到四个预设问题的变更示例,并拟定一个包含三个评分标准的评估表,评分范围为 0 到 2 分,并列出关键错误。先在一个小组中进行试点,然后将他们下次正式评估的结果与基准值进行比较。
要了解如何让回顾练习在您的团队中实时进行,并在之后以自定进度重复使用,请探索 AhaSlides。








