扩展阅读

如何有效进行代码评审:一位 GitHub 资深工程师的理念

代码评审·2026/7/21·6 阅读

如何有效进行代码评审:一位 GitHub 资深工程师的理念

来源: https://github.blog/developer-skills/github/how-to-review-code-effectively-a-github-staff-engineers-philosophy/ 抓取时间: 2026-07-21 16:25:05


Sarah Vessels

Sarah Vessels

@cheshire137 Staff Software Engineer, GitHub


作为 GitHub 的一名资深工程师,代码评审是我日常工作的主要重点之一。在过去八年里,我已经评审了超过 7,000 个拉取请求。为什么要评审这么多?因为代码评审对于构建优质软件至关重要,另一双眼睛往往能发现你原本会忽略的问题。

我认为代码评审是我工作中最重要的方面之一。事实上,每当我看到队友有准备好进行代码评审的拉取请求时,我更愿意放下我正在开发的分支,转而评审他们提出的更改。毕竟,他们的拉取请求已经通过了持续集成(CI)的考验,并达到了他们自己对"完成"的判断标准,所以它可能比我自己仍在开发的工作更接近可交付状态。我宁愿让他们的代码跨越终点线,也不愿花费未知的更多时间来完成我的代码。

我越早提供反馈——"这可能为 nil 并导致错误"、"这看起来像是一个 n+1 查询"、"如果在这上面有一个方法签名会很好"——反馈就能越快得到处理,漏洞就能越快被修复,功能就能越快上线。

我想分享我进行代码评审的方法,希望我们都能交付更好的代码。

什么是代码评审?

严格来说,代码评审——通过 GitHub 上的拉取请求评审——允许协作者对拉取请求中提出的更改发表评论、表示他们对这些更改的批准,或在拉取请求合并前请求进一步更改。

我将拉取请求视为对话的开始。我把它理解为作者在说"我认为这改进了我们目前拥有的东西"。代码评审是塑造产品实现的绝佳机会。作为代码评审者,我的工作是与作者进行反复讨论,通过提问、质疑假设,并一般作为第二双眼睛来改进他们的代码。

为什么要评审代码?这对你的职业发展有好处

我从其他评审者对我自己代码的看法中学到了很多东西,在多次收到感谢我及时进行代码评审的积极反馈后,我知道我的代码评审评论同样帮助了我的队友们提升水平。简而言之,代码评审具有影响力,而获得晋升需要展示你的影响力。

代码评审之所以有影响力,是因为它们有助于交换知识并提高交付速度。它们是很好的、可链接的工件,同事和管理者可以用它们来展示你多么有帮助和知识渊博。它们可以突出良好的沟通技巧,特别是如果需要进行复杂或有争议的更改。因此,在代码评审中充分表达你的观点不仅可以指导产品的未来,帮助避免事故,还可能对你的职业发展有好处。

优化你的代码评审流程

如何找到需要评审的拉取请求

我每天都在我的 GitHub 通知收件箱中工作。这是我在浏览器中固定的少数标签之一,所以它总是可用的。每当我在等待 CI、在任务之间切换、开始一天的工作,或者一般有空的时候,我都喜欢检查我的收件箱。我在那里找到了我评审的大部分拉取请求。GitHub 的团队倾向于有一个特定的 Slack 频道作为他们的基地,这是分享准备好评审的拉取请求的好地方——这是我发现拉取请求的其他主要方式之一。

我还利用 GitHub Slack 集成将 Slack 频道订阅到与我的团队相关的新拉取请求。为了筛选哪些拉取请求出现在 Slack 中,我使用特定于团队的标签,然后在 Slack 中使用"订阅"命令,如 /github subscribe your/repo pulls +label:"your-team-label"

提示:你可以在查询中重复使用 team-review-requested: 限定符,以获取跨许多不同代码所有者的待评审拉取请求。

我喜欢使用诸如 is:open archived:false is:pr org:github -is:draft team-review-requested:github/relevant-codeowner-team 这样的查询来搜索可能需要评审的未完成拉取请求。通过这个查询,我找到了 GitHub 组织中开放、未归档的拉取请求,它们不是草稿,并且相关代码所有者团队被要求进行评审。我通常会省略 review:required 搜索限定词,因为即使队友已经评审了拉取请求,我仍然有兴趣进行评审。毕竟,评审代码不仅帮助作者,还帮助我了解我负责的代码的更改。

使用评审团队来管理通知

你不希望代码更改通知的团队太大,以至于团队中的每个人都认为评审更改不是他们的责任。这可能导致拉取请求要么因未评审而拖延,要么在应该之前就被合并,因为关键评审者在大量通知中错过了它们。这两种情况都会影响产品的质量。

我建议,如果你有能力的话,优化你加入的代码所有者团队数量,以保持你的通知可控。这样,落在你收件箱中的拉取请求不只是噪音,而是你实际上觉得应该评审的内容。虽然大型、通用的代码所有者团队作为后备选项可能没问题,但它们不适合作为自动评审请求的首选默认设置。保持你仓库的 CODEOWNERS 文件组织良好,配合明确定义的代码边界,以限制通知并帮助评审者避免通知疲劳。

限制基于团队的通知的另一种方法是创建一个应急响应团队,然后使用自动化根据计划添加和删除团队成员。这可以让你的团队专注于他们日常的代码库,而计划的应急响应人员会收到你团队服务领域的拉取请求通知。例如,使用 PagerDuty API,你可以确定某一天谁是应急响应人员。然后你可以使用 Octokit 库来添加和删除团队成员。

使用自动化在团队之间标准化代码评审

仓库级别的配置和自动化,例如使用 CODEOWNERS 文件和分支保护规则,可以帮助在团队之间强制执行评审流程标准。其他标准,例如在拉取请求中哪些内容值得评论,必须由我们人类来维护。记录你的团队内代码评审的工作方式,以确保任何提供代码评审或提交拉取请求的人都知道如何让他们的拉取请求得到评审、预期的评审周转时间,以及使用什么自动化来促进评审。

一些团队使用项目板来跟踪哪些拉取请求进入评审;我看到这对于管理共享 API 的团队效果很好,这个领域经常被团队外的人修改。其他团队仅依赖 GitHub 通知,当代码所有权范围明确且团队在拉取请求进入时就有纪律地进行评审时,我看到这种方式效果很好。

如果你遵循特定于你的团队的独特流程,自动化可以帮助与团队外的人沟通期望。例如,如果许多其他团队依赖你的团队的评审,你可以使用机器人自动在请求你团队评审的任何拉取请求上留下评论,告诉作者他们什么时候可以期待收到你的回复。

什么让代码评审变得好或坏?

好的代码评审增加了清晰度,并推动代码向比开始时更好的状态发展。

作为评审者,沟通的清晰度至关重要。你需要明确你的哪些评论是个人偏好,哪些是批准的阻碍。提供你建议的方法示例,以提升你的代码评审质量,让你的意思更加清晰。如果你能从拉取请求所在的同一仓库中提供示例,那就更好了——这通过鼓励一致的实现来进一步支持你的建议。

相比之下,糟糕的代码评审缺乏清晰度。例如,没有任何评论的全面批准或拒绝可能会让拉取请求作者想知道评审是否彻底。即使只是在批准时重申你对拉取请求作者意图的理解,也可以揭示你和作者是否有相同的理解。

代码评审如果不清楚何时应该实施其建议,也可能给作者带来糟糕的体验。可以注意到现有、未更改的代码应该被重构,或者应该处理额外的情况,但重要的是要说明这些是否是批准的先决条件。如果拉取请求在没有你的建议的情况下也可以合并,请确保这样说。保持小的差异并作为单独的拉取请求单独交付这些更改可能更安全。

以下是一个显示特异性并清楚传达建议实现的代码评审评论示例:

"我看到你的新方法匹配了这个文件中的现有风格,接受了 [X] 个参数。有这么多参数会损害可读性,并暗示函数做了太多事情。你怎么看在以后的拉取请求中重构这个方法和现有的方法,以减少它们接受的参数数量?"

这个评论做得好的地方:

  • 提供具体细节
  • 引用特定代码或问题
  • 建议问题的解决方案
  • 引用证据或提供解释

另一方面,以下是一些可以改进的评审评论示例:

"我不喜欢这个。" —— 评审者不喜欢什么?他们有没有可以明确说明的替代方案?

可能的改进:

  • "这行代码做了很多事情,我们可以简化它来提高可读性吗?"
  • "我认为这会因为 n+1 查询而产生性能问题。"
  • "我们可以使用 [首选框架] 的解决方案来代替编写自定义实现吗?"

"这不会工作。" —— 为什么更改不会工作?

可能的改进:

  • "这不会工作,因为 [X],请参见这个相关问题:[问题链接]。"
  • "这之前在 [拉取请求链接] 中尝试过,因为 [X] 没有工作。"
  • "如果你遇到 [X] 的问题,你可以尝试 [替代方法]。"

"我认为这修复了一个 bug。" —— 我喜欢这个指出,但是有没有任何额外的上下文,比如问题链接,可以让这更清楚?

可能的改进:

  • "我认为这修复了 [问题链接]。"
  • "这是在修复 [问题链接] 中的 bug 吗?"
  • "这看起来像是我们在 [失败构建链接] 中遇到的那个 bug。感谢修复!"

如何进行好的代码评审

提问

我认为拉取请求作者是最了解他们的拉取请求所做更改上下文的人。我可以根据我的历史经验指出我看到的问题——我在 Ruby on Rails 单体应用、TypeScript 或处理大量流量的数据库方面的经验——但我相信作者对我的问题的回答。我认为他们对细节的理解比我更好。

提示:如果你是代码库或团队的新手,请在代码评审中提问,以了解技术栈以及可用的内部工具和库。你评审的每个拉取请求都是一个了解作者为什么更喜欢一种方法而不是另一种方法的机会。

我也喜欢提出涉及代码中假设的问题。他们正在处理的数据形状是什么?是否存在不符合该形状的数据?代码对此的响应是否良好?代码是否资源密集?它的性能会好吗?作为评审者,我最喜欢的回答是作者提供一个自动化测试来验证这些场景下的行为。我第二喜欢的回答是经验数据,比如来自我们数据仓库的查询,或者显示为什么这些场景不成问题的 Datadog 图表。

作为拉取请求作者,我很欣赏收到问题。当有人提出问题时,它为我创造了空间来解释为什么我对我的更改有信心,必要时引用问题、查询或图表。它还让我与其他人分享我的知识和经验。作者不仅看到我的回答,其他评审者和未来的读者也能看到,他们可能正在追踪过去决定的上下文。

给予肯定

除了提问之外,对你同意的拉取请求部分发表评论也是好的做法。这些评论可以突出表明你阅读并理解了正在更改的内容,或者你验证了代码中的某些假设。以下是几个示例:

  • "看起来这匹配了这个模块中其他类使用的模式。"
  • "感谢添加测试!"
  • "这比以前可读性强多了。"

根据我的经验,在接收端收到这样的评论也很好。接收代码评审有时会让人感到疲惫。当我在处理来自几方的问题和建议时,收到一些不需要我做任何事情的评论,而是支持和承认我已经投入的工作,这会是一个很好的激励。

意识到偏见和假设

很容易让你对评审者或他们正在更改的代码领域的偏见影响你的评审。你习惯了某人在某个领域工作或具有某种资历级别,并假设他们知道自己在做什么——但每个人都会犯错。你对他们的更改的关注,你检查他们的假设或验证你自己的假设的问题,可以在部署之前发现问题。

我非常重视编写测试,因为它们可以消除一些偏见。当你编写测试来检查代码是否正常工作时,你不必相信作者的话,你只需要看测试是否通过——当然,前提是你的测试是正确的。

我也非常重视初级开发者在代码评审中向高级开发者提问,即使他们认为他们的问题很愚蠢或有明显的答案。如果对你来说这不明显,那就是有效的。对其他人来说也不会明显!提出问题,为作者创造空间写下他们的答案,并为后来的人保留那一点教育。

批准还是不批准

我将我的评审视为一个可以阻止其他人改进我们产品的阻塞关口,所以我会认真地拒绝批准。我经常会有个人偏好,并建议我希望作者进行的可选更改,但我不会仅仅因为这些而拒绝批准。如果我对某人的拉取请求有建议,但他们的拉取请求原样不会破坏生产、对用户产生负面影响,或导致其他问题,我会批准并附上这些评论。作者可以选择在合并他们的拉取请求之前解决我的反馈,或者在另一个分支中跟进。

提示:使用功能标志并让你的拉取请求保持小。你的更改越不可怕,它在生产中就能越快被逆转,我就越容易批准它!

在评审代码时,请记住你的建议的重要性。延迟交付以解决你的建议是否值得?这是否值得整个周期:作者看到你的反馈、进行建议的更改、等待 CI、重新评审、部署和最终合并?如果没有建议也不会让某人的日子变得更糟,那就让作者决定是否或何时进行建议的更改。

"请求更改"选项会阻止拉取请求合并,直到评审者回来并批准它。我很少使用它,因为它通常感觉过于强硬。我相信我的团队知道何时批准拉取请求,所以队友的批准就可以代替我的批准。同样,我相信拉取请求作者会尊重我的反馈并考虑它,而不是仅仅因为其他人批准了而我没有批准就盲目合并。我唯一会选择"请求更改"选项的时候是当我认为存在即时安全问题,并且我担心他们在合并前不会看到我的担忧。

使用 AI 编码工具时为什么代码评审很重要

AI 编码工具通常包括各种防止不正确或不安全代码的保护措施,但不要被误导产生虚假的安全感。作为掌舵的人类评审者,你是最后一道防线,应该以同等程度的谨慎评审所有代码。

如何充分利用代码评审

评审你自己的代码

GitHub 高级软件工程师 Paul Smith 教我在请求其他人评审之前先评审自己的拉取请求,我也建议你这样做。进行第一次评审,并对不明显的更改或你在其他人的拉取请求中看到会提问的更改在代码行中留下评论。自我评审还可以帮助确定拉取请求是否太大,是否需要拆分。

特别提及:如果你关心保持拉取请求小,你可以使用 lerebear/sizeup-action 自动在拉取请求上应用标签,表明它们的复杂性和大小。

欢迎合并后的评审

如果我碰巧在某人有机会评审之前合并了拉取请求,我仍然欢迎他们的评审。如果我的拉取请求破坏了什么或产生了意外后果,在拉取请求上发表评论会留下面包屑轨迹,帮助未来的读者追踪发生了什么!

如果我在合并的拉取请求上收到评审,我会像在拉取请求落地之前一样处理反馈。也许会是一个解释我的观点的评论,也许会是额外的拉取请求来迭代我最初交付的代码。也许会是打开新问题来捕获需要完成的额外工作。

使用草稿拉取请求

当你创建新的拉取请求时,你可以选择将拉取请求设置为草稿。我严重依赖草稿阶段来表明我是否想要评审。例如,如果一个必需的 CI 构建失败了,或者我还没有完成,我会让它保持草稿状态。我倾向于对其他人的拉取请求有同样的期望:如果它是草稿,我假设作者还没有准备好评审。如果它标记为准备好评审,我假设获得足够的批准是阻止他们部署拉取请求的唯一因素。

草稿状态意味着拉取请求尚未完成,所以我在解决合并冲突或处理评审者反馈时将拉取请求移回草稿状态。如果我必须修改代码,我会先将我的拉取请求标记为草稿,以免让已经评审过的人感到不知所措。当我把它移回"准备好"状态时,它会向那些评审者发送 GitHub 通知,以便他们可以再次查看。

保持亲切

"用蜂蜜比用醋能抓到更多苍蝇"这句话浮现在脑海中。我希望我的拉取请求得到评审,所以我喜欢回复拉取请求上的评论——特别是如果我不同意评审者的意见。即使我不写对评审评论的回复,我也经常用 👍 反应来表示我同意,或者用 ❤️ 反应来表示感谢。

我希望评审者相信他们的建议不会被遗忘,所以我通过评论让他们了解情况。如果我同意他们的建议——例如,进一步重构现有代码——我可能会这样说,同时在当前拉取请求中反对进行该更改。当我在以后的拉取请求中处理他们的反馈时,我会回来提供一个链接,让评审者知道他们的反馈没有被忽视。

我还会在实现建议更改的后续拉取请求中标记他们,并附上说明"这处理了来自 <前一个拉取请求 URL> 的 @某人的反馈。"这既为其他读者提供了上下文,也对原始评审者表示了感谢,给予他们这个想法的功劳。

当你履行在以后的分支中处理反馈的承诺时,这有助于建立与评审者的信任,这可以帮助他们在未来舒适地批准你的拉取请求,因为他们知道你不会留下未完成的东西。

总结

代码评审对产品质量的重要性怎么强调都不为过,特别是在 AI 代码生成时代。在我的职业生涯中,很多时候仅仅通过第二双眼睛就发现了 bug 或避免了事故。无论是花在日常评审上、梳理流程上,还是构建支持它的自动化上,代码评审的时间投入都是非常值得的。对于开发者来说,现在彻底评审拉取请求比以后处理已经发布到生产中的问题更快、更少痛苦。

感谢你对代码质量足够关心,阅读了我关于代码评审的理念。你最近检查了你的评审队列吗?也许现在是将这些想法付诸行动的好时机。

如果你想了解更多关于如何在 GitHub 上使用拉取请求评审的信息,请查看 GitHub 社区上由资深 DevOps 架构师 Mickey Gousset 和资深 DevOps 架构师 Joshua Johanning 撰写的讨论"评审拉取请求的 5 个技巧"的帖子。

评论 (0)

暂无评论,快来抢沙发吧!

91学AI

© 2026 91学AI · 按岗位学 AI 与大数据. All rights reserved.