精读《如何做好 CodeReview》
1 引言
任何软件都是协同开发的,所以 CodeReview 非常重要,它可以帮助你减少代码质量问题,提高开发效率,提升稳定性,同时还能保证软件架构的稳定性,防止代码结构被恶意破坏导致难以维护。
所以 CodeReview 机制是否健全是一个工程团队能否长期健康发展的决定因素之一,这次我们读一篇关于 CodeReview 如何做得更好的文章: how-to-make-good-code-reviews-better。
2 概述 & 精读
作者结合自己在 Uber、微软的工作经历介绍了自己对如何做好 CodeReview 的看法。
CodeReview 的覆盖范围
Good CodeReview 会检查代码的正确性、测试覆盖率、功能变化、是否遵循代码规范与最佳实践、可以指出一些较为明显的改进点,比如难以阅读的写法、未使用到变量、一些边界问题、commit 数量过大需要拆分等等。
Better CodeReview 会检查引入代码的必要性,与已有系统是否适配,是否具有可维护性,从抽象角度思考代码是否与已有系统逻辑能够自洽。
Better CodeReview 会关注在可维护性层面,并具有全局性,往往几个局部正确的代码组合在一起会产生错误的结果,或者是没必要的代码,或者是相互冲突的逻辑。Better CodeReview 更多用在底层架构场景,因为架构底层模块关联比较紧密,需要有整体视角,而业务上层模块间最好采用解耦模式,这样不仅不需要更耗费精力的 Better CodeReview,也是一种更正确的架构设计。
CodeReview 的语气
Good CodeReview 会给出建设性意见,而不是发表强硬措辞要求对方改正,或认为自己的意见是唯一正确的答案,因为这样的评论其实具有一定攻击性,激发对方的防御心理,产生敌对心态,这样会从内部瓦解一个团队。最好能给出建议,或者多个选择,给对方留有余地。
Better CodeReview 永远是考虑全面且正向积极的,会对写的好的地方进行鼓励,对写的不好的地方也体现出善解人意的关怀,考虑到对方可能花费了很多心血,以一种换位思考的鼓励心态进行评论。
其实读到语气这一章节,逐渐发现 CodeReview 不仅是一个技术专业行为,还是一个人与人相处的社交行为,有的人平时与人打交道非常谦逊,但在 CodeReview 中就变得尖酸刻薄,显然是只关注到了 CodeReview 的专业性这一面,忽略了社交性这一点。而要做到 Better CodeReview 还要学会换位思考,体现出包容、正向积极的态度,因为你技术经验更丰富,能指出别人的问题很正常,但能保持谦逊,让别人容易接受并受到鼓励,可以让你成为一个有气度的技术专家。
如何完成 CodeReview 的审阅
Good CodeReview 不会轻易通过那些开放式 PR,至少在其被得到充分讨论前,但每个 Review 者对自己关注的部分完成 Review 后需要进行反馈,无论是 “看起来不错” 或者用缩写单词 “LGTM”,之后需要有明确的跟进,比如通过协作软件通知作者进行进一步反馈。
Better CodeReview 实际执行中会更加灵活一些,对于一些比较紧急的改动会留下改进建议,但快速通过,让作者通过后续代码提交解决遗留的问题。
实际工作场景会遇到一些开放式或紧急的提交,良好的 CodeReview 习惯自然是要严谨一些,讨论清楚再通过,并且要及时反馈。但某些比较紧急的提交就要区别对待了,更好的态度是在实践中灵活对待,但及时紧急通过了,也要保证问题在后续得以修复,比如在代码中留一些 “TODO” 或 “FIXME” 的标记,写上对应的负责人与预期解决时间。
从 CodeReview 到直接交流
Good CodeReview 会给出完整的评论和修改建议,如果后续提交的代码不符合预期,Review 者可以直接与代码提交者面对面交流,这样可以避免后续花费更多沟通时间。
Better CodeReview 会在第一次给出完整的评论和修改建议,如果后续提交代码不符合预期,会立即与代码提交者当面沟通,避免异步沟通带来更多的理解偏差。
补充一下,在 PR 内容过多时也可以选择直接与提交者当面沟通,这样可以更多理解作者的想法,使 Review 准确性更高。另外并不要每次都直接交流,异步的 CodeReview 本身就是一种提效方案,这会使你工作节奏把握在自己手中,仅在这种方案出现沟通问题时再选择当面交流。
区分重点
Good CodeReview 可以区分提示的重要程度,并在不太重要的改动前面加上 “nit:” 标记,这样可以使提交者的注意力集中在重要的问题上。
Better CodeReview 会采取工具手段解决这些问题,比如一些代码 lint 工具,因为这些问题往往是可以被工具自动化解决的。
代码自动化工具的目的,很大一部分也是为了保证代码一致性,从而降低 CodeReview 成本,也减少不重要的评论信息出现,让 CodeReview 尽可能反馈逻辑问题而不是格式问题。
针对新人的 CodeReview
Good CodeReview 对任何人都是用相同评判标准,可以遵循上面几点注意事项。
Better CodeReview 会对新人区分对待,对新人给予对多的耐心、解释和评论,甚至给出解决方法,并更积极的给出鼓励。
任何人到一家新公司都有适应过程,一视同仁是 base 要求,但如果能给予新人更多关怀就更好啦。
跨办公区、时区的 CodeReview
Good CodeReview 仅在工作时间有重叠的时间范围内进行 CodeReview,这样能保证对方可以积极响应,在必要时进行语音、视频沟通。
Better CodeReview 会注意到更本质的问题,留意跨团队协作的必要性,如果某个模块经常被另一个时区同时修改,也许可以将这个模块交给对方维护,或者将 CodeReview 交给对方团队内部进行会更加高效。
笔者所在公司也有跨时区协作情况,但绝大部分场景会避免跨时区的 CodeReview,因为 CodeReview 一般会在同一时区团队内部进行,这样效率更高,应对跨时区协作时,往往也是电话、视频会议优先。
公司支持
Good CodeReview 会得到公司组织支持,公司能意识到这么做虽然看起来占用开发时间,但长远来看提升了开发效率,因此能任何 CodeReview 价值。
Better CodeReview 会得到公司进一步支持,公司甚至不断研发并完善 CodeReview 系统与流程,通过系统化方案保证上面几项 CodeReview 注意事项是否有在团队内落实,可以全员参与。
CodeReview 也是一种团队文化和公司文化,公司文化带来的是规章制度与系统工具,团队文化带来的是良好 CodeReview 氛围与更高 CodeReview 的效率。
3 总结
总结一下,良好的 CodeReview 需要做到以下几点:
- 更全面,从正确性到系统影响评估。
- 注意语气,从给出建设性一觉到换位思考。
- 及时完成审阅,从充分讨论到随机应变。
- 加强交流,从面对面交流到灵活选择最高效的沟通方式。
- 区分重点,从添加标记到利用工程化工具自动解决。
- 对新人要更友好。
- 尽量避免跨时区协作,必要时选择视频会议。
最后,希望 CodeReview 能够得到公司的支持,如果你们公司还没有认可 CodeReview 的价值,可以将这篇文章分享给你的领导。
讨论地址是:精读《如何做好 CodeReview》 · Issue #237 · dt-fe/weekly
相关文章:
精读《如何做好 CodeReview》
1 引言 任何软件都是协同开发的,所以 CodeReview 非常重要,它可以帮助你减少代码质量问题,提高开发效率,提升稳定性,同时还能保证软件架构的稳定性,防止代码结构被恶意破坏导致难以维护。 所以 CodeRevie…...
双指针(滑动窗口)-算法刷题
一.移动零(. - 力扣(LeetCode)) 算法思想 : 设置两个指针left,right,将数组分为三块[0,left]为不为0的元素,[left1,right-1]为0元素,[right,num.size()-1]为未扫描的区域,…...
上位机图像处理和嵌入式模块部署(qmacvisual之ROI设定)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 ROI,全称是region of interest,也就是感兴趣区域。这里面一般分成两种情况,一种是所有的算法都依赖于这个ROI&a…...
银行监管报送系统介绍(五):金融统计数据大集中自动化报送系统——PBOC Report
人民银行金融统计数据大集中自动化报送系统(简称PBOC Report),是基于现代计算机网络技术应用基础上,由人行总行设置金融统计数据服务器,建立的一个全国统一的金融统计数据库。 人行针对各银行存贷款、中间业务、网点人…...
常用中间件redis,kafka及其测试方法
常用消息中间件及其测试方法 一、中间件的使用场景引入中间件的目的一般有两个:1、提升性能常用的中间件:1) 高速缓存:redis2) 全文检索:ES3) 存日志:ELK架构4) 流量削峰:kafka 2、提升可用性产品架构中高可…...
ROS1通过rosbridge在局域网中控制turtle进行运动(PC和手机)
通过ROSbridge控制小海龟(turtlesim)的具体案例。使用一个简单的Python脚本通过通过局域网上连接上传ROSbridge服务器,并发送速度指令来控制小海龟的移动 功能包的结构如下: HTML文件的编写(界面) html用…...
MQ高级篇---消息可靠性
MQ的一些常见问题 后面内容基于springboot 2.3.9.RELEASE 消息可靠性 生产者确认机制 在publisher微服务中application.yml中添加 spring:rabbitmq:publisher-confirm-type: correlatedpublisher-returns: truetemplate:mandatory: true每个RabbitTemplate只能配置一个Return…...
SpringMVC | SpringMVC中的 “文件上传和下载”
目录: 一、文件上传1.1 文件上传“概述”1.2 文件上传“具体配置” :“前端”中配置“文件上传” ( type“file” 满足3个条件 )“后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean 配置“文件上传”的“约束条件” 通过“MultipartFile接口”参数接…...
JVM快速入门(2)HotSpot和堆、新生区、永久区、堆内存调优、JProfiler工具分析OOM原因、GC(垃圾回收)、JVM经典面试笔试题整理
5.6 HotSpot和堆 5.6.1 Hotspot 三种JVM: Sun公司,HotspotBEA,JRockitIBM,J9 VM,号称是世界上最快的Java虚拟机 我们一般学习的是:HotSpot 5.6.2 堆 Heap,一个JVM只有一个堆内存,…...
我的风采——android studio
目录 实现“我的风采”页面要求理论代码生成apk文件 实现“我的风采”页面 要求 要求利用’java框架的边框布局实现“找的风采 ”页而,其中中间为你的生活照,左右和下面为按钮,上面为标签 理论 Java GUI编程是Java程序设计的重要组成部分…...
BMS设计中的短路保护和MOSFET选型(上)
电池管理系统(BMS)是一种能够对电池进行监控和管理的电子装备,是电池与用户之间的纽带。通过对电压、电流、温度以及SOC等数据采集,计算进而控制电池的充放电过程,主要就是为了能够提高电池的利用率,防止电…...
用go实现一个任务调度类 (泛型)
用go实现一个任务调度类 (泛型) 源码地址: https://github.com/robinfoxnan/BirdTalkServer/blob/main/server/core/workmanager.go 1.概述 实现了一个简单的任务管理系统,允许用户定义任务和工作者,并将任务分配给…...
ansible 管理工具以及常用模块
一、前期准备 1、安装 yum install ansible 如果yum源没有ansible,需要提前配置yum源: mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup wget -O…...
javaSSM公司招聘管理系统IDEA开发mysql数据库web结构计算机java编程maven项目
一、源码特点 IDEA开发SSM公司招聘管理系统是一套完善的完整企业内部系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发)MAVEN方式加 载,系统具有完整的源代码和…...
蓝桥杯day11刷题日记
P8615 [蓝桥杯 2014 国 C] 拼接平方数 思路:先把数据范围内的平方数打上标记,然后就是遍历这个区间,转成字符串(好拆数据),用substr拆开数据,再强转成整数类型,最后查看拆开的数据是…...
IDEA, Pycharm, Goland控制台乱码
IDEA, Pycharm, Goland控制台乱码 问题描述: 控制台出现����等乱码 复现频率: 总是 解决方案: 以IDEA为例 添加 -Dfile.encodingUTF-8位置 idea64.exe.vmoptions 在安装idea的bin目录idea.vmoptions idea客户端 示意图...
JavaScript单元测试jasmine学习(一)
介绍: jasmine是用于测试JavaScript的一种测试框架,BDD(Behavior Driven Development)行为驱动开发。不依赖于任何其他JavaScript框架,也不需要DOM 准备工作: 1. 首先添加jasmine到自己的项目中 npm install --save-dev jasmine 2. 在项目…...
108、3D Gaussian Splatting for Real-Time Radiance Field Rendering
简介 官网 更少训练时间的同时实现最先进的视觉质量,能在1080p分辨率下实现高质量的实时(≥30 fps)新视图合成 NeRF使用隐式场景表示,体素,点云等属于显示建模方法,3DGS就是显示辐射场。它用3D高斯作为灵活高效的表示方法&…...
PHP之CURL和Socket
文章目录 一、CURL1.基本流程(1)初始化(2)向服务器发送请求(3)向服务器发送请求(4)关闭curl 2.CURLOPT参数记得写一个文件curl上传的例子记得写一个json上传的例子3.CURL批处理 二、…...
【Web】NKCTF 2024 个人wp(部分)
目录 my first cms 全世界最简单的CTF attack_tacooooo 属实太菜了,3/4 my first cms 一眼搜版本2.2.19 CVE -CVE-2024-27622 GitHub - capture0x/CMSMadeSimple 访问/admin/login.php 爆出弱口令,后台登录 admin Admin123 Extensions > User D…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
