代码评审中的吹毛求疵是无处不在且不可避免的。但是,如果我们可以用更少的NIT进行代码审查——并确保确实存在的NIT是真正有价值的呢?几个月前,我在内部展示了一些关于Datto的代码审查细节的数据。接下来的讨论非常活跃,并且正在影响我们在Dat如何审查代码。我想我会借此机会在这里无耻地分享这些挑剔的发现,以吸引今天的读者成为明天的Datto工程师。与愿意参与并成长的有才华的工程师一起工作是一种乐趣;来加入我们的旅程吧。
研究NIT的原因是希望改进团队的代码审查流程。理想的代码审查过程如下所示:
工程师们致力于交付业务价值,并承诺在第一时间完美地交付该价值的代码。
当同事们去查看代码时,他们会在阅读中得到启发,并迅速批准合并请求。
这是理想,但尽管我们的Datto工程师很棒,但我们也是人。因此,我们的代码可能会成为大多数工程师常见故障的牺牲品,而我们的代码最初并不完美。我们的工程师同事的审查和评论旨在完善它。NIT就是在这个审查过程中出现的。
在代码评审期间,评审人员有很多话要说,那么我为什么要关注NIT呢?nit这个词在软件评论中有很多含义,它是为数不多的几个评论者主动应用于评论的标签之一。我对nit的工作定义是:有nit标签的审查不如没有nit标签的审查实质性。当审查人员应用标签时,他们希望工程师给予的重量比标签丢失时轻。
用Gitlab的API收集评论相当简单。循环浏览我们的每个项目,在注释范围内搜索“nit”,你会发现一些nit!结果是几千个数量级。尽管我致力于这项分析,但我并不特别想费力阅读成千上万的NIT。起初,我尝试将一些文本分析工具应用于它(最有成效的是雅克算法,它帮助进行了一些初始桶识别)。然而,这只对一小部分NIT有所帮助。当时的解决方案是取样。使用95%的置信水平和4%的置信区间,我只需要阅读几百个NIT:我发现这是更容易管理的。
前五个桶约占所有NIT的24%。通过我们与linter和formatters的持续集成管道,我们可以并且应该自动化这些类型的反馈。这些琐碎的反馈可以由机器人完成,而不是人类。机器人反馈的另一个好处是,作为一个质量关卡,它能更快地得到反馈。
我认为,六桶到十桶应该留在这里,而且不能自动离开。拼写让人感觉像是拼写检查机器人可以管理的东西,但我们的代码通常有完全有效的变量名,大多数拼写检查者都会难以处理。(我看着你绕过vCenter异常。)
在我看来,最后两桶是最有趣的。谦逊的评论是带有“nit”标签的评论,但实际上是相当实质性和有益的。即使评审员使用nit标签以使工程师更喜欢反馈,也应保留实质性反馈。
最后一个水桶,工程师的声音,包含了可以归结为“这段代码在技术上很好,但评审员会选择以不同的方式编写它”的细节考虑到我们可以用各种各样的方法解决代码问题,这并不奇怪。当涉及到CPU效率、内存效率、网络效率、易读性、更少的行数、项目一致性,以及当今任何“最佳实践”所指的不断变化的目标时,工程师通常会有不同的优先级。大约20%的NIT属于工程师类。
对NIT有了基本了解后,我们现在如何改进代码审查流程?
在我们的评论中,努力做到有心、专注、节俭。这一步本质上不是技术性的,而是人的。每次代码审查都会触发电子邮件和通知。审阅者应该帮助工程师尽快交付最好的代码。有时候,这看起来像是根本没有留下评论。
自动处理细节。前五个桶(新行、间距、报价、大小写、常规格式)可以也应该由Linter和quality bots处理。如果文件末尾的换行符很重要,我们应该进行自动化检查。我们的团队现在将对持续集成流程进行更改,使我们今天的NIT变得自动化。工程师可以通过使用诸如预提交库之类的工具,在推送提交之前自动执行linting和格式化修复,从而将这种自动化提升到下一个级别。
虽然研究和分析是一次有趣的经历,但随后出席的大约80名工程师之间的协作讨论才是这个项目真正的精华所在。该小组分享了过去在NIT、工具方面的经验,以及未来代码审查和交付的愿景。不出所料,我们在自动更改代码的工具上存在分歧,如果交付的放缓值得工程师通过建议替代方案来启发,或者工具应该修复代码,或者仅仅通知工程师其不足之处。
我毫不怀疑,我们将继续迭代我们的代码审查和交付过程。在我在Datto的一年任期内,它已经得到了改进,通过额外的CI Linter和开发人员告诉我,由于我们的讨论,他们保留了不必要的细节;我很高兴看到我的工程师同事们下一步的想法。