精读《如何做好 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…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...