热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在团队中做好CodeReview

一、CodeReview的好处想要做好CodeReview,必须让参与的工程师充分认识到CodeReview的好处1、互相学习,彼此成就无论是高手云集的架构师团队,还是以CURD为






一、Code Review的好处

想要做好Code Review,必须让参与的工程师充分认识到Code Review的好处


1、互相学习,彼此成就

无论是高手云集的架构师团队,还是以CURD为主的业务开发团队,大家的技术能力、经验都是有差异的。

通过Code Review,对于同样的功能实现,有经验的工程师可以给经验尚浅的工程师提供合理的优化建议。经验尚浅的工程师可以通过阅读优质代码,快速学习相关技术运用的最佳实践。如果大家技术实力相当,可能就是互相刷新思想了。


你有一个苹果,我有一个苹果,彼此交换一下,我们仍然是各有一个苹果;但你有一种思想,我有一种思想,彼此交换,我们就都有了两种思想,甚至更多。



2、知识共享,自动互备

在大部分团队,尤其是采用服务化架构以及微服务架构的团队,通常都是1个开发人员负责多个服务/项目(Project),如果没有Code Review,那么项目中所涉及的架构知识,或者业务知识,就只存在于项目执行过程中产出的架构文档,以及核心流程、功能的说明文档了。

文档可以帮助其他工程师了解服务/项目的情况,但通常其他工程师不会主动去阅读这些文档,等到真的要维护别的工程师写的代码,文档的完整性往往没有最初的效果好了,文档跟代码实现的匹配度也会下降。

Code Review的过程,就是根据提交者的描述阅读代码的逻辑,看代码实现是否跟描述一致。在这个时候,Reviewer就必须阅读文档,知识的传播性就更好,也基本上不会出现只有1个人了解某个项目的情况了。


3、统一风格,提升质量

如果要给代码质量分一下等级的话,那应该是: 

可以编译通过->可以正常运行->可以测试通过->容易阅读->容易维护。那么,通过Code Review的代码最起码可以达到易阅读这个级别。

要做到易阅读,可不是说只要有Code Review这个环节就可以了,还要有相关的规范,让大家按照同样的工程风格、编码风格去构建项目和编写代码。统一风格一方面是让大家无论是维护项目还是阅读代码,不用互相适应各自的编码习惯,另外也是给Reviewer一个Code Review的基本依据。


发现Bug不是Code Review的必需品,而是附属品。至于那些低级的问题/bug交给代码扫描工具就可以了,这不是Code Review的职责。



二、推动Code Review落地执行


1、选定工具

可以用来做Code Review的工具很多,这里主要介绍相对主流的Gerrit、GitLab


  • Gerrit

Gerrit是Google开源的代码审查工具,Gerrit也是一个基于Git构建的版本管理工具,Gerrit支持将其他Git仓库的代码跟Gerrit自己的仓库做同步。所有的代码审查的操作以及权限控制都是在Gerrit自己的仓库上进行的。

Gerrit是面向代码审查来构建的,所以在代码审查的权限控制,以及功能上都是非常完善的。

Gerrit是可以强制CodeReview的,支持Develop、Reviewer、Approver三种角色支持对每个Project配置不同的CodeReview的人员以及权限。

如果要根据Gerrit的数据做一些统计报表,就直接访问Gerrit的数据库,如果功能上不满足要求,反正是开源的,有Java研发团队就可以自己定制

总之,Gerrit的Code Review功能是非常完善的,缺点可能就是UI、交互太老了以及平台的管理功能较弱。


  • GitLab家族

GitLab是基于Git构建的源代码管理系统,基于GitLab构建的 GitLab.com 是仅次于 GitHub.com 的在线源代码管理平台。

GitLab分GitLab CE(社区版)和 GitLab EE(企业版)两个版本,开源的社区版功能相对会弱一点,但是免费使用,可以自由部署、定制、维护。企业版功能强大,但是需要收费的。

GitLab可以通过MergeRequest来Review代码,也可以做到强制CodeReview,社区版支持Develop、Reviewer两种角色,企业版支持Develop、Reviewer、Approver三种角色,可以给给项目/组分配不同的角色(Master、Developer)来控制Merge代码的权限。

如果需要根据GitLab的数据做一些统计报表,GitLab提供了非常友好的restful API,如果要定制化,建议是通过API来做定制化的工具,不受编程语言限制。

GitLab的Code Review的功能没有Gerrit功能完善,但是GitLab附带的文档功能、以及GitLab完善的管理后台都要比Gerrit更好,如果要做CI/CD,GitLab的社区版几乎是最佳选择


  • Gerrit VS GitLab 综合对比






























工具权限控制UI交互源代码管理可维护数据统计工具配套
Gerrit⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
GitLab社区版⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
GitLab企业版⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

Gerrit强项只有Code Review的控制,GitLab的功能更全面,但GitLab的企业版是收费的。所以,综合来说,我更推荐GitLab社区版


基于GitLab的CodeReview教程:https://ken.io/note/gitlab-co...



2、制定开发规范

没有规则,就没有执行。规则中首当其冲的就是开发规范。

规范中建议包含:


  • 工程规范(工程结构,分层方式及命名等等)

  • 命名规范(接口、类、方法名、变量名等)

  • 代码格式(括号、空格、换行、缩进等)

  • 注释规范(规定必要的注释)

  • 日志规范(合理的记录必要的日志)

  • 各种推荐与不推荐的代码示例

如果团队人数较少,项目的工程复杂度较低,可以自行制定规范。毕竟适合团队的就是最好的。

如果团队有一定规模,且还会不断扩张,还是建议根据大厂的规范进行制定,或者是直接采用。


Java开发手册:https://github.com/alibaba/p3c 

Google代码风格指南:https://zh-google-styleguide.... (涵盖:C++、Python等)



3、制定流程规范


  • 确定Code Review实施环节

image

CodeReview建议是放在代码提交测试前,也就是开发人员完成代码开发及自测后将代码提交到测试分支时进行Code Review。毕竟,如果测试通过后再进行Code Review,如果需要代码变更,势必会增加测试的工作量,甚至影响项目进度。亦或是顶着项目上线的压力,干脆“以后再说”了

以通用的Git Workflow来说,那就是把Code Review放在Feature分支合并到Develop分支时了。


  • 制定角色行为规范










角色规则
Developer1、一次提交的功能必须是完整的2、默认细粒度提交(以独立的方法/功能/模块为单位)。如需粗粒度提交,需提前跟Reviewer沟通确认3、Commit Message中要清晰描述变更的主题必要时,可以以链接或者文件的形式附上需求文档/设计文档
Reviewer1、不允许自我Review并Merge代码2、Review不通过打回前需跟Developer说明原因并达成一致3、Review不通过需明确填写打回的原因4、单次Review时长需控制在2分钟~2小时内完成(特殊情况请说明原因)
Approver1、审批不通过需注明原因
2、审批时长需要控制在1小时以内3、对于放行的非质量问题,需持续跟进

这样规范,主要是为了:


  1. 控制提交Code Review的代码的粒度

  2. 控制单次Code Review的时间

  3. 提升Commit/MergeRequest描述的质量,减少沟通成本

这样,我们就可以通过细粒度高频次的方式尽可能利用工程师碎片化的时间进行Code Review,一定程度上保证Code Review的效率。

毕竟,粗粒度甚至是集中式的Code Review,时间上难以把控。发现了问题的时候,修复的成本也往往更高。


4、分享与统计

有了工具、开发规范、流程规范,就可以指引参与的工程师参与Code Review,那么我们也要对Code Review的过程以及结果进行检验,毕竟不进行检查/验收的规则,是无法达到预期效果的。

Code Review毕竟不是数学题,我们无法通过简单的计算去验证。所以我们要通过侧面验证,来帮助Code Review的执行


  • 定期分享

我们是期望CodeReview可以让工程师之间互相学习的,那么对于一次Code Review通常只有参与的2-3个工程师有互相学习的机会,那么在这个过程中学到的知识,定期的分享出来,既可以加强知识的流动,又可以检查大家究竟有没有在Code Review过程中学习到知识,或者有没有认真的进行Code Review

至于分享的内容,可以是开发规范中的范例代码,也可以是规范中的正例代码,也可以是针对某个功能实现的最佳算法/最佳实践,也可以是Code Review过程中的争议代码,也可以是自己踩过的坑。

总之,Code Review之后的代码分享,不但可以加强知识的流动,还可以检验Code Review的效果。


  • 数据统计

为了在一定程度上保证Code Review的效率,我们在规范里是要求参与的工程师:


  1. Developer控制提交Code Review的粒度,或者控制每个Commit的粒度

  2. Developer要准确清晰的描述所提交的代码

  3. Reviewer&Approver要在规定时间内完成Code Review

这些情况纯粹靠人工是无法检验的,还是需要有一定的数据统计。

如果用Gerrit,可以查询Gerrit的数据库,里面会有Code Review的信息,

如果用GitLab,可以通过WebHook或者restful API获取Code Review信息

我们可以做成报表,来展示Code Review的情况:


  1. 每人每周Code Review所消耗的时间

  2. 每人每周被Code Review所消耗的平均时间

  3. 超过规定时间的Code Review情况

  4. 代码提交描述字数过少的情况

  5. 等等(根据自己的需要来)

以上情况只是Code Review的侧面反馈,用来帮我们发现Code Review执行过程中可能出现的问题。不过,出现问题并不意味着Code Review的质量/效率一定受到了影响。

比如,工程师A被Code Review的耗时是团队内最高,有可能是有某次代码是周五晚上提交的CodeReviw,这单次CodeReview的耗时就会超过48小时。也有可能是对应的Reviewer是团队新人,要通过相关业务项目了解对应Project的承担的职责及代码,这是个学习的过程,自然耗时加长。

又比如工程师B提交的代码描述文字过少,可能就是中间件团队对某些基础组件进行升级,或者安全团队要求升级某个依赖的开源组件,以修复某个安全漏洞。

但是通过这种的数据,可以让Code Review的情况直观的展示出来。来发现大家执行过程中需要优化的事项, 不断帮助大家完善规则,做好执行。


三、保证Code Review质量的关键


1、工程师对研发规范的认真学习

无论Code Review的工具以及流程是怎么样的,都少不了开发规范作为支撑,毕竟我们期望Code Review达到的效果之一就是,团队中的工程师可以写出像规范中描述那样的高质量代码。

工程师对研发规范的掌握程度,决定了自己编码代码的质量,也决定了自己Review通过的代码的质量。所以,无论如何,加强对研发规范的学习和理解,都是保证Code Review质量的重中之重


2、资深工程师的认真对待

Code Review目的是帮助工程师交流和学习进步的。无论是技术能力还是编码习惯,亦或是业务知识。无论规则怎么制定,终究还是需要参与的工程师来执行,如果大家互相睁一只眼闭一只眼,互相降低要求,那么执行的效果一定会打折扣。

虽说三人行必有我师,但收益最大的一定是经验(技能/业务知识)尚浅的工程师,收益最低的一定是团队中最资深的工程师。而恰恰经验尚浅的工程师的收益大部分都要来自资深工程师的付出。

所以,一定要跟资深工程师最好沟通,让他们严格要求,不能对经验尚浅的工程师放水,以帮助他们提升编码能力以及业务知识。

这也可以减少甚至避免他们为经验尚浅的工程师的代码“善后”。


四、备注


附录


  • Java开发手册:https://github.com/alibaba/p3c

  • 基于GitLab的CodeReview教程:https://ken.io/note/gitlab-co...

  • Google代码风格指南:https://zh-google-styleguide....

  • Jenkins+Sonar执行代码扫描:https://ken.io/note/jenkins-m...

原文链接:https://segmentfault.com/a/119000002136830...




推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
author-avatar
煭敻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有