【开源与项目实战:开源实战】80 | 开源实战二(下):从Unix开源开发学习应对大型复杂项目开发
上两节课,我们分别从代码编写、研发管理的角度,学习了如何应对大型复杂软件开发。在研发管理这一部分,我们又讲到比较重要的几点,它们分别是编码规范、单元测试、持续重构和 Code Review。其中,前三点在专栏的理论部分都有比较详细的讲解,而唯独 Code Review 我们还没有讲过,所以,今天我就借机会和你补充一下这一部分的内容。
很多年前,我跟一个有十几年研发经验的某一线大厂的技术专家聊天,聊天中我提起了 Code Review,他便对 Code Review 一顿否定。他说,Code Review 比较浪费时间,往往会虎头蛇尾,不可能在企业中很好地落地执行。当我又提起,Code Review 在 Google 执行得很好,并且是已经习以为常的开发流程的时候,他竟然说这绝对不可能。
一个技术不错,可以玩转各种架构、框架、中间件的资深 IT 从业者,居然对 Code Review 有如此的偏见,这到底是哪里出了问题呢?我觉得问题主要还是出自认知上。
所以,今天,我并不打算讲关于如何做 Code Review 的方法论,我更希望充当一个 Code Review 布道师的角色,讲一讲为什么要进行 Code Review,Code Review 的价值在哪里,让你重视、认可 Code Review。因为我觉得,只要从认知上接受了 Code Review,对于高智商的 IT 人群来说,搞清楚如何做 Code Review 并不是件难事。而且,Google 也开源了它自己的 Code Review 最佳实践,网上很容易搜到,你完全可以对照着来做。
话不多说,让我们正式开始今天的内容吧!
我为什么如此强调 Code Review?
Code Review 中文叫代码审查。据我了解,在国内绝大部分的互联网企业里面,很少有将 Code Review 执行得很好的,这其中包括 BAT 这些大厂。特别是在一些需求变动大、项目工期紧的业务开发部门,就更不可能有 Code Review 流程了。代码写完之后随手就提交上去,然后丢给测试狠命测,发现 bug 再修改。
相反,一些外企非常重视 Code Review,特别是 FLAG 这些大厂,Code Review 落地执行得非常好。在 Google 工作的几年里,我也切实体会到了 Code Review 的好处。这里我就结合我自身的真实感受讲一讲 Code Review 的价值,试着“说服”一下你。
1.Code Review 践行“三人行必有我师”
有时候你可能会觉得,团队中的资深员工或者技术 leader 的技术比较牛,写的代码很好,他们的代码就不需要 Review 了,我们重点 Review 资历浅的员工的代码就可以了。实际上,这种认识是不对的。
我们都知道,Google 工程师的平均研发水平都很高,但即便如此,我们发现,不管谁提交的代码,包括 Jeff Dean 的,只要需要 Review,都会收到很多 comments(修改意见)。中国有句老话,“三人行必有我师”,我觉得用在这里非常合适。即便自己觉得写得已经很好的代码,只要经过不停地推敲,都有持续改进的空间。
所以,永远不要觉得自己很厉害,写的代码就不需要别人 Review 了;永远不要觉得自己水平很一般,就没有资格给别人 Review 了;更不要觉得技术大牛让你 Review 代码只是缺少你的一个“approve”,随便看看就可以。
2.Code Review 能摒弃“个人英雄主义”
在一个成熟的公司里,所有的架构设计、实现,都应该是一个团队的产出。尽管这个过程可能会由某个人来主导,但应该是整个团队共同智慧的结晶。
如果一个人默默地写代码提交,不经过团队的 Review,这样的代码蕴含的是一个人的智慧。代码的质量完全依赖于这个人的技术水平。这就会导致代码质量参差不齐。如果经过团队多人 Review、打磨,代码蕴含的是整个团队的智慧,可以保证代码按照团队中的最高水准输出。
3.Code Review 能有效提高代码可读性
前面我们反复强调,在大部分情况下,代码的可读性比任何其他方面(比如扩展性等)都重要。可读性好,代表后期维护成本低,线上 bug 容易排查,新人容易熟悉代码,老人离职时代码容易接手。而且,可读性好,也说明代码足够简单,出错可能性小、bug 少。
不过,自己看自己写的代码,总是会觉得很易读,但换另外一个人来读你的代码,他可能就不这么认为了。毕竟自己写的代码,其中涉及的业务、技术自己很熟悉,别人不一定会熟悉。既然自己对可读性的判断很容易出现错觉,那 Code Review 就是一种考察代码可读性的很好手段。如果代码审查者很费劲才能看懂你写的代码,那就说明代码的可读性有待提高了。
还有,不知道你有没有这样的感受,写代码的时候,时间一长,改动的文件一多,就感觉晕乎乎的,脑子不清醒,逻辑不清晰?有句话讲,“旁观者清,当局者迷”,说的就是这个意思。Code Review 能有效地解决“当局者迷”的问题。在正式开始 Code Review 之前,当我们将代码提交到 Review Board(Code Review 的工具界面)之后,所有的代码改动都放到了一块,看起来一目了然、清晰可见。这个时候,还没有等其他同事 Review,我们自己就能发现很多问题。
4.Code Review 是技术传帮带的有效途径
良好的团队需要技术和业务的“传帮带”,那如何来做“传帮带”呢?当然,业务上面,我们可能通过文档或口口相传的方式,那技术呢?如何培养初级工程师的技术能力呢?Code Review 就是一种很好的途径。每次 Code Review 都是一次真实案例的讲解。通过 Code Review,在实践中将技术传递给初级工程师,比让他们自己学习、自己摸索来得更高效!
5.Code Review 保证代码不止一个人熟悉
如果一段代码只有一个人熟悉,如果这个同事休假了或离职了,代码交接起来就比较费劲。有时候,我们单纯只看代码还看不大懂,又要跟 PM、业务团队、或者其他技术团队,再重复来一轮沟通,搞的其他团队的人都很烦。而 Code Review 能保证任何代码同时都至少有两个同事熟悉,互为备份,有备无患,除非两个同事同时都离职……
6.Code Review 能打造良好的技术氛围
提交代码 Review 的人,希望自己写的代码足够优秀,毕竟被同事 Review 出很多问题,是件很丢人的事情。而做 Code review 的人,也希望自己尽可能地提出有建设性意见,展示自己的能力。所以,Code Review 还能增进技术交流,活跃技术氛围,培养大家的极客精神,以及对代码质量的追求。
一个良好的技术氛围,能让团队有很强的自驱力。不用技术 leader 反复强调代码质量有多重要,团队中的成员就会自己主动去关注代码质量的问题。这比制定各种规章制度、天天督促执行要更加有效。实际上,我多说一句,好的技术氛围也能降低团队的离职率。
7.Code Review 是一种技术沟通方式
Talk is cheap,show me the code。怎么“show”,通过 Code Review 工具来“show”,这样也方便别人反馈意见。特别是对于跨不同办公室、跨时区的沟通,Code Review 是一种很好的沟通方式。我今天白天写的代码,明天来上班的时候,跨时区的同事已经帮我 Review 好了,我就可以改改提交,继续写新的代码了。这样的协作效率会很高。
8.Code Review 能提高团队的自律性
在开发过程中,难免会有人不自律,存在侥幸心理:反正我写的代码也没人看,随便写写就提交了。Code Review 相当于一次代码直播,曝光 dirty code,有一定的威慑力。这样大家就不敢随便应付一下就提交代码了。
如何在团队中落地执行 Code Review?
刚刚讲了这么多 Code Review 的好处,我觉得大部分你应该都能认可,但我猜你可能会说,Google 之所以能很好地执行 Code Review,一方面是因为有经验的传承,起步阶段已经过去了;另一方面是本身员工技术素质、水平就很高,那在一个技术水平没那么强的团队,在起步阶段或项目工期很紧的情况下,如何落地执行 Code Review 呢?
接下来,我就很多人关于 Code Review 的一些疑惑,谈谈我自己的看法。
有人认为,Code Review 流程太长,太浪费时间,特别是工期紧的时候,今天改的代码,明天就要上,如果要等同事 Review,同事有可能没时间,这样就来不及。这个时候该怎么办呢?
我所经历的项目还没有一个因为工期紧,导致没有时间 Code Review 的。工期都是人排的,稍微排松点就行了啊。我觉得关键还是在于整个公司对 Code Review 的接受程度。而且,Code Review 熟练之后,并不需要花费太长的时间。尽管开始做 Code Review 的时候,你可能因为不熟练,需要有一个 checklist 对照着来做。起步阶段可能会比较耗时。但当你熟练之后,Code Review 就像键盘盲打一样,你已经忘记了哪个手指按的是哪个键了,扫一遍代码就能揪出绝大部分问题。
有人认为,业务一直在变,今天写的代码明天可能就要再改,代码可能不会长期维护,写得太好也没用。这种情况下是不是就不需要 Code Review 了呢?
这种现象在游戏开发、一些早期的创业公司或者项目验证阶段比较常见。项目讲求短平快,先验证产品,再优化技术。如果确实面对的还只是生存问题,代码质量确实不是首要的,特殊情况下,不做 Code Review 是支持的!
有人说,团队成员技术水平不高,过往也没有 Code Review 的经验,不知道 Review 什么,也 Review 不出什么。自己代码都没写明白,不知道什么样的代码是好的,什么样的代码是差的,更不要说 Review 别人的代码了。在 Code Review 的时候,团队成员大眼瞪小眼,只能 Review 点语法,形式大于效果。这种情况该怎么办?
这种情况也挺常见。不过没关系,团队的技术水平都是可以培养的。我们可以先让资深同事、技术好的同事或技术 leader,来 Review 其他所有人的代码。Review 的过程本身就是一种“传帮带”的过程。慢慢地,整个团队就知道该如何 Review 了。虽然这可能会有一个相当长的过程,但如果真的想在团队中执行 Code Review,这不失为一种“曲线救国”的方法。
还有人说,刚开始 Code Review 的时候,大家都还挺认真,但时间长了,大家觉得这事跟 KPI 无关,而且我还要看别人的代码,理解别人写的代码的业务,多浪费时间啊。慢慢地,Code Review 就变得流于形式了。有人提交了代码,随便抓个人 Review。Review 的人也不认真,随便扫一眼就点“approve”。这种情况该如何应对?
我的对策是这样的。首先,要明确的告诉 Code Review 的重要性,要严格执行,让大家不要懈怠,适当的时候可以“杀鸡儆猴”。其次,可以像 Google 一样,将 Code Review 间接地跟 KPI、升职等联系在一块,高级工程师有义务做 Code Review,就像有义务做技术面试一样。再次,想办法活跃团队的技术氛围,把 Code Review 作为一种展示自己技术的机会,带动起大家对 Code Review 的积极性,提高大家对 Code Review 的认同感。
最后,我再多说几句。Google 的 Code Review 是做得很好的,可以说是谷歌保持代码高质量最有效的手段之一了。Google 的 Code Review 非常严格,多一个空行,多一个空格,注释有拼错的单词,变量命名得不够好,都会被指出来要求修改。之所以如此吹毛求疵,并非矫枉过正,而是要给大家传递一个信息:代码质量非常重要,一点都不能马虎。
重点回顾
好了,今天的内容到此就讲完了。我们一块来总结回顾一下,你需要重点掌握的内容。
今天,我们主要讲了为什么要做 Code Review,Code Review 的价值在哪里。我的总结如下:Code Review 践行“三人行必有我师”、能摒弃“个人英雄主义”、能有效提高代码可读性、是技术传帮带的有效途径、能保证代码不止一个人熟悉、能打造良好的技术氛围、是一种技术沟通方式、能提高团队的自律性。
除此之外,我还对 Code Review 在落地执行过程中的一些问题,做了简单的答疑。我这里就不再重复罗列了。如果你在 Code Review 过程中遇到同样的问题,希望我的建议对你有所帮助。
课堂讨论
对是否应该做 Code Review,你有什么看法呢?你所在的公司是否有严格的 Code Review 呢?在 Code Review 的过程中,你又遇到了哪些问题?
相关文章:
【开源与项目实战:开源实战】80 | 开源实战二(下):从Unix开源开发学习应对大型复杂项目开发
上两节课,我们分别从代码编写、研发管理的角度,学习了如何应对大型复杂软件开发。在研发管理这一部分,我们又讲到比较重要的几点,它们分别是编码规范、单元测试、持续重构和 Code Review。其中,前三点在专栏的理论部分…...

【单周期CPU】LoongArch | 立即数扩展模块Ext | 32位算术逻辑运算单元(ALU)
前言:本章内容主要是演示在vivado下利用Verilog语言进行单周期简易CPU的设计。一步一步自己实现模型机的设计。本章先介绍单周期简易CPU中基本组合逻辑部件的设计。 💻环境:一台内存4GB以上,装有64位Windows操作系统和Vivado 201…...
Python实现数据结构的基础操作
目录 一、列表(List) 二、字典(Dictionary) 三、集合(Set) 四、链表的实现 五、队列和栈 数据结构是计算机科学中非常重要的概念,它用于存储和组织数据以便有效地进行操作。Python作为一种…...
20230624----重返学习-vue-响应式处理思路-仿源码
day-098-ninety-eight-20230624-vue-响应式处理思路-仿源码 vue vue大体概念 Vue是渐进式框架 所谓渐进式框架,就是把一套全面的框架设计体系,拆分成为多个框架,项目中需要用到那些需求,再导入对应的框架,以此来保证…...

【MongoDB】三、使用Java连接MongoDB
【MongoDB】三、使用Java连接MongoDB 实验目的实验内容练习1、开启Eclipse,创建Java Project项目,命名为Mongo12、添加项目依赖的jar包3、创建类MongoDemo4、连接数据库5、查看集合6、创建集合7、删除集合8、查看文档9、插入文档10、更新文档11、删除文档…...

【C++】通讯录的基本实现,附有源码分享
目录 1、运行环境 2、系统实现功能 2.1菜单功能 2.2退出通讯录功能 2.3添加联系人功能 2.4显示联系人功能 2.5删除联系人功能 2.6查找联系人功能 2.7修改联系人功能 2.8清空联系人功能 2.9动态扩容功能 2.10选择优化功能 2.11文件操作 3、源码分享 1、运行环境 …...

UI 自动化测试 —— selenium的简单介绍和使用
selenium 是 web 应用中基于 UI 的自动化测试框架,支持多平台、多浏览器、多语言。 提到 UI 自动化就先了解什么是自动化测试? 目录 1. 自动化测试 2. UI 自动化 2.1 UI 自动化的特点 2.2 UI 自动化测试的优缺点 2.3 UI 自动化测试的使用对象 2.4…...
mybatisPlus中apply的使用以进行联表等复杂sql语句
在 MyBatis-Plus 中,apply() 方法可以用于添加任意的 SQL 片段,包括联表查询。因此,你可以使用 apply() 方法来处理各种类型的联表查询。 使用 apply() 方法的好处是可以在查询条件中直接添加原生的 SQL 片段,而不受 MyBatis-Plu…...
自学Python技术的方法
目录 一、Python技术介绍 二、学习前的准备工作 三、学习时的具体操作 四、如何巩固学习 Python是一种高级编程语言,被广泛用于软件开发、数据分析、人工智能和科学计算等领域。它于1991年由Guido van Rossum创建,并且其简洁、易读的语法以及丰富的标…...

python熟悉python基础语法,了解html网络结构,了解json格式数据,含有字符串
前言 Python网络爬虫是利用Python编写的程序,通过自动化地访问网页、解析html或json数据,并提取所需信息的技术。下面将详细介绍一些与Python网络爬虫相关的重要知识点。 1、Python基础语法: 变量和数据类型:学习如何声明变量以及…...

linux mail -s发送邮件异常解决
异常: Error initializing NSS: Unknown error -8015. "/root/dead.letter" 11/301 . . . message not sent. 出现此问题,大概率是和证书相关。如果没有安装证书,请先安装: 1,下载 yum -y install mailx …...

Netty核心技术七--Google Protobuf
1.编码和解码的基本介绍 编写网络应用程序时,因为数据在网络中传输的都是二进制字节码数据,在发送数据时就需要编码,接收数据时就需要解码 codec(编解码器) 的组成部分有两个:decoder(解码器)和encoder(编码器)。encoder 负责把…...
【Docker】Docker常用命令总结
文章目录 一、帮助命令二、镜像命令三、容器命令四、常用的其他命令 在开发过程中,经常涉及到 docker 的相关操作,本文对常用的指令进行汇总。 一、帮助命令 docker version # 显示docker版本信息 docker info # 显示docker系统信息ÿ…...

React 对比class与Effect Hook优化响应式数据更新监听,感受useEffect真正的强大
还是之前写过的一个组件 import React from "react"export default class index extends React.Component{constructor(props){super(props);this.state {name: "小猫猫"}}componentDidMount ()>{document.title this.state.name;}componentDidUpda…...

AWS Lambda 介绍
计算服务的演进 EC2------Container-------Lambda 虚拟机---容器--------------serverless无服务器架构 什么是AWS Lambda? AWS lambda的核心是事件驱动,驱动可能来自,Alexa,SNS,DynamoDB,S3,Kinesis等&…...
linux之权限管理
目录 1.一.基本小语句 2.文件权限操作chmod 1.一.基本小语句 ls - a 查看此文件夹所有和隐藏内容 ls - l 查看此文件夹权限 chown 改变文所有者 2.文件权限操作chmod chmod 参数 文件名 文件的权限主要针对三类对象进行定义 owner 属主, u:针对前三个部分的权限修改 …...
【设计模式与范式:行为型】61 | 策略模式(下):如何实现一个支持给不同大小文件排序的小程序?
上一节课,我们主要介绍了策略模式的原理和实现,以及如何利用策略模式来移除 if-else 或者 switch-case 分支判断逻辑。今天,我们结合“给文件排序”这样一个具体的例子,来详细讲一讲策略模式的设计意图和应用场景。 除此之外&…...

【C++】auto_ptr为何被唾弃?以及其他智能指针的学习
搭配异常可以让异常的代码更简洁 文章目录 智能指针 内存泄漏的危害 1.auto_ptr(非常不建议使用) 2.unique_ptr 3.shared_ptr 4.weak_ptr总结 智能指针 C中为什么会需要智能指针呢?下面我们看一下样例: int div() {int a, b;cin >&g…...

数据结构练习题1:基本概念
练习题1:基本概念 1 抽象数据类型概念分析2. 逻辑结构与存储结构概念分析3.综合选择题4.综合判断题5.时间复杂度相关习题6 时间复杂度计算方法(一、二、三层循环) 1 抽象数据类型概念分析 1.可以用(抽象数据类型)定义…...

如何消除Msxml2.XMLHTTP组件的缓存
之前使用这个组件,是每隔十分钟取数据,没有遇到这个缓存问题, 这次使用它是频繁访问接口,就出现了一直不变的问题。觉得是缓存没有清除的问题。 网上搜了一些方案。最好的方案就是给url地址末尾给一个随机参数。用于让组件觉得是…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...