CodeReview 的经验和原则
资深的程序员都知道 Code Review 可以对代码质量,代码规范,团队代码能力提升带来很大的提升,还有著名的技术专家“左耳朵耗子”也说过:
我认为没有 Code Review 的公司都没有必要呆(因为不做 Code Review 的公司一定是不尊重技术的)
- 出自《程序员的练级攻略 - 修养篇》
国外很多技术公司都非常重视 Code Review 也都做的特别好,例如 Google,亚马逊,但是国内很多公司在践行 Code Review 的时候却是步履蹒跚,步步艰难,选用的方法不对,最终导致事倍功半的结果,总结一下我见过的几种情况:
- 因为 Code Review 导致团队成员之间相互指责,团队凝聚力产生间隙
- Code Review 形式化,没有提升代码质量,减少 bug,反而降低开发效率
- Code Review 确实产生了效果,但是因为流程太重,导致团队效率降低
我们也在践行 Code Review,探索的路上也遇到一些障碍和经验,总结分享一下,如果你也遇到这些问题,或许可以花一点时间读一读这篇文章,说不定会有帮助。
Code Review 能带来哪些好处,本文就不说了,大家都很熟悉了,本文主要简单说一下 Code Review 有哪几个基本的共识和原则:
- Code Review 高效的原则是用机器去做大部分的事情
- Code Review 的时机(天时地利人和)
- 推行 Code Review 的关键原则
Code Review 高效的原则是用机器去做大部分的事情
不同的语言的格式和风格都是比较固定的,例如我最熟悉的 Java 语言常见的风格有以下几种规范:
- Order Java SE 的标准规范:https://www.oracle.com/technetwork/java/codeconvtoc-136057.html
- Google Java 开发规范: https://google.github.io/styleguide/javaguide.html
- 阿里巴巴 Java 开发手册:https://github.com/alibaba/p3c (国内常用)
还有我最近常用的 Ruby 语言,官方所推崇的几种风格规范:
- Ruby Style Guide:https://github.com/rubocop-hq/ruby-style-guide
- Airbnb Ruby Style:https://github.com/airbnb/ruby
但凡是标准规范都是比较机械化的条条框框,应该交给机器去检查(常用的工具由:P3C,Rubocop,SonarQube 等),机器静态扫描效率不仅比人高出一个数量级,而且非常严谨,不容易出错,甚至可以武断的说:所有的自动化工具的本质,都是为了要减少对人的依赖性,因为人本身是具备很多种不确定性,所以并不适合做一些需要确定性并且反复重复的事情
Code Review 的时机(天时地利人和)
在以往的工作经验中,Code Review 越是靠左移,修改代码的成本越低,开发人员的修改意愿也就越高,那什么叫左移?
我们看一下软件开发的流水线和个人认为最合理的 code review 时机:
软件工程的开发流水线(图)
从流水线上来说,有些人会在临近上线,在靠右的地方合并 master 的时候才进行 code review,这个时候修改成本就很高,因为代码已经测试过,如果因为 code review 有问题需要重新修改代码,那么功能本身又要回归测试,占用的测试双倍的时间,对于人力资源是双倍的浪费,因为已经临近上线,却因为 code review 被打回,开发人员愿意重构代码的意愿也会很低,如果明明发现问题,又因为上线压力,不打回不符合规范的代码,那么久而久之大家失去对 code review 的敬畏心理,code review 也会慢慢变成形式化,应用发布流程而已,既不能提高代码质量,降低系统 Bug,也不能提升开发人员的水平,反而降低的开发团队的效率,所以选择在上线前进行 code review 不是一个好主意,所以从性价比上来说 code review 最好的时机应该是在 功能分支自测完成后,需要合并到 develop 分支申请提测前 通知项目组成员对增量的代码进行 code review。
所以,代码审查要高效的话,核心就是要追求快速反馈,越早发现代码问题修改的成本就越低,具体参考下图:
这里需要注意的是,代码在经过机器扫描后(这里有一个技巧就是可以在 GitLab CI 加入自动的代码风格检查,代码静态扫描是一个高频操作,一天可能会有几十,甚至上百次的 Commit,如果接入 GitLab CI 实现自动化静态扫描,大家不需要在自己本地执行静态扫描,那么效率也会大大的提升),项目组成员只需要把注意力放在 代码逻辑结构,功能设计的可维护,可扩展性 等机器不容易发现问题的地方上,然后就完成代码审查。因为代码还未提测,所以就算 Merge Request 不合格被打回后,因为还未提测,也不会占用测试人员的资源,开发人员的修改意愿也会更高,总体来说是可以达到高效和质量的要求
Code Review 要计入开发的工作量
很多团队不做 code review 都有一个共同的原因是觉得浪费时间,结果导致糟糕的代码合并入库,频繁出现线上问题,然后开发人员疲于奔命的去修复线上事故 BUG,虽然短期来看功能是快速上线了,但是算上复工的时间,长期来看整体的交付周期还是被拉长了,整体还是低效的,而且糟糕的生产质量人很容易打击开发人员的持续生产高质量代码的信心,所以将 code review 计入开发的工作量是重视长期利益的一种做法,也是 code review 能够成功落地的重要前提,从团队管理的角度来说,不计入工作量的事情就不会被重视,不被重视的话那么 code review 最终在团队只会被废弃或者流于应付形式,并未发挥作用。也是很多团队推行 code review 失败的原因。
推行 Code Review 的关键原则
想要在审核代码的时候,避免团队成员因为某些模糊不清的细节争论不休的情况,那么就要提前让团队建立对代码审核的原则和方法达成共识,我就曾经见过团队的技术人员在代码审核的时候因为某个函数方法的实现方式争吵不休,各自都认为自己的实现是正确的,那么提前建立一下这种共识:
相互尊重原则
站在代码作者的角度:
- 审核人花费时间和精力阅读他不熟悉的代码,并且帮忙指出代码中的问题来帮助代码作者提高,代码作者应该尽可能的为审核人提供配合和方便
- 代码作者提交高质量的代码,就是对审核人和审核团队的最基本尊重(提交一堆乱如麻花的代码,没有自测错误百出的代码是极度不负责任的表现)
- 最好要有清晰的 commit 历史,让人可以一目了然代码的提交内容,如果代码过度复杂,那么就需要和审核人面对面沟通,才能足够的高效
站在代码审查者的角度:
- 一定要懂得相互尊重,提出建议要懂得换位思考,考虑代码作者的感受,不要用主观的批评或者情绪化的语气指责团队的同事
- 提出代码改进建议,必须是基于事实,或者明确的代码规范文档,不可强行把个人喜好强加在对方身上(例如用不同的语法实现相同的功能 for/while )
- 不要钻进代码的牛角尖和抠细节,人工审查更多的要把精力放在代码逻辑,功能设计等无法扫描的问题上
建立共识
站在团队的角度:
- code review 的目标长期来看,收益是提升团队的项目质量,减少团队陷入反复修复 bug 的困境中,让团队有机会去面对更多的挑战
- code review 对个人和团队而言都是成长的机会,放下不必要的自尊心,要用开放的包容的心态去接受不同的意见,取其精华
总结
以上就是我个人和团队在 code review 中的实践和总结,Code Review 关键还是要结合团队的情况选择合适的审查方式,如果团队追求敏捷开发,快速迭代那么集中式的代码审查会可能就不太适合你们当前的团队,可能项目成员 1 对 1 的结对编程可以更加高效的完成代码审查,每个团队的发展阶段不同,适用的 GitFlow 开发流程也不同,反正没有最好的工具,最有最合适的工具。
CodeReview 的经验和原则的更多相关文章
- atitit.提升研发效率的利器---重型框架与类库的差别与设计原则
atitit.提升研发效率的利器---重型框架与类库的差别与设计原则 1. 框架的意义---设计的复用 1 1.1. 重型框架就是it界的重武器. 1 2. 框架 VS. 库 可视化图形化 1 2.1 ...
- android( java) 处理 null 和 预防空指针异常(NullPointerException) 的一些经验。
概述: 在实际编码中总是会遇到 空指针异常 ,本文总结了一些处理空指针的个人经验. 原则: 尽早的检查,尽早的失败. 比如: 通过intent传参到新的目标 activity,而且一定需要这个参数,那 ...
- atitit.提升研发效率的利器---重型框架与类库的区别与设计原则
atitit.提升研发效率的利器---重型框架与类库的区别与设计原则 1. 框架的意义---设计的复用 1 1.1. 重型框架就是it界的重武器. 1 2. 框架 VS. 库 可视化图形化 1 2.1 ...
- WCF分布式开发步步为赢(6):WCF服务契约继承与分解设计
上一节我们学习了WCF分布式开发步步为赢(5)服务契约与操作重载部分.今天我们来继续学习WCF服务契约继承和服务分解设计相关的知识点.WCF服务契约继承有何优势和缺点?实际项目里契约设计有什么原则和依 ...
- ASP.NET网站中设置404自定义错误页面
在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页面,然后在Global.asax文件中,加入如下代码: &l ...
- 走进小作坊(十一)----移动web实现指南
四.五年前智能手机行业刚刚兴起,差别于之前功能机阉割版的web开发方式,一些学者就開始探索移动web的UI方向了.从PC迁移到移动端的web设计现成可用的原则有,很多其它的则是依据移动端独有特点进行探 ...
- 毕业后的第二份工作:进入国外 在新加坡工作 每月一次18K
--訪传智播客成都校区12.26就业班学员 杨洋 姓名:杨洋 毕业院校:重庆科技学院 专业:电子信息技术与project 就职公司:新电科技 岗位:Javaproject师 月薪:18K 上午.他刚去 ...
- session的使用
一.什么是session? Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 Web 页之间跳转时, ...
- JVM GC(整理)
1 GC类型 1 )YGC 一般情况下,当新对象生成,并且在Eden申请空间失败时,就好触发YGC ,堆Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区.然后整理S ...
随机推荐
- 主席树铺垫——总区间第k小
题目描述(口糊) 先给定一个长度为n的数列,然后给m次操作,每次输入b,求第b小的数. 样例输入 5 7 4 10 9 23 5 1 2 3 4 5 样例输出 4 7 9 10 23 数据范围及温馨提 ...
- oracle 在物理机上添加磁盘操作
物理机上添加磁盘操作 注意:1)物理机上添加磁盘操作,不涉及到start_udev的动作.2)磁盘分区的操作,需要谨慎进行,核准无误后再操作. (1)查看磁盘名称命名 # su - grid$ sql ...
- javascript : 点击按钮,把某标签中的内容复制到剪贴板
需求如题. 静态页面如下. 需要的库:jquery(不用应该也能做). 浏览器:PC chrome 68 Mobile MIUI9.5(Android 7) <p>1.用电脑打开网址:&l ...
- SQL : 把特定的数据排前面 & 分别查询几组数据的最大值
把特定的数据排前面 : 比如说,把没有审核身份证的人排最前面,然后再按userId正序排. select case when idcardverified = 1 then 0 else 1 end ...
- ssh配置、vscode使用及常用扩展
1.ssh配置 1.1 进入命令行 win + r > cmd 1.2 输入如下代码直接回车即可生成ssh ssh-keygen -t rsa -C "xxx@qq.com&quo ...
- 架构师都该懂的 CAP 定理
面对可能出现的网络延迟,不可预估的请求流量等情况,设计一个分布式系统,我们通常围绕系统高可用,数据一致性的目标去规划和实现,想要完全实现这个目标,却并非易事.由此,分布式系统领域诞生了一个基本定理,即 ...
- JAVA 实现将多目录多层级文件打成ZIP包后保留层级目录下载 ZIP压缩 下载
将文件夹保留目录打包为 ZIP 压缩包并下载 上周做了一个需求,要求将数据库保存的 html 界面取出后将服务器下的css和js文件一起打包压缩为ZIP文件,返回给前台:在数据库中保存的是html标签 ...
- OFDM通信系统的MATLAB仿真(1)
由于是第一篇博客,想先说点废话,其实自己早就想把学到的一些东西总结成文章随笔之类的供自己复习时查看的了.但是一是觉得自己学的的不够深入,总结也写不出什么很深刻的东西:二是觉得网上也有海量的资料了,需要 ...
- web自动化 -- Keys(键盘操作)
Keys没啥好讲的 语法:Keys.CONTRAL 等等类似. 下方就是可以 Keys. 跟的键 那些 \ue000 就是对应的 Windows系统中的键盘码,pywin32 也一样的 ...
- 3分钟看懂Python后端必须知道的Django的信号机制!
概念 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者( ...