豆皮粉儿们,大家好,又见面啦,今天由字节跳动的"躬冯"带来一个 code review 的故事。

作者:躬冯

2020年元旦假期到来的时候,孙总攒了个局,又把当年一起创造过屎山的咱哥仨又聚到一起,名头是庆祝老刘晋升。

当年bugfix一把梭的老刘,如今在某厂带了个小十人的团队,好不威风。借着这个由头,大伙们既是有福同享一把,为他道个喜,也是在疲顿的高脑力生活的罅隙中,寻找一次短暂的休憩,分享分享行业见闻和动态,找寻一些共鸣。

我是喜欢这种聚会的,朋友里面,最不能喝的便是我的这些码哥们儿,这样的饭局,往往意味着我不用担心摆在我面前量酒器里头的酒位线是不是又跟大部队落下了,毕竟可乐还是非常美味的。与此同时,话题总是在是不是要把某个产品拿去祭天,某个线上工单又是什么玄学因素导致,老婆的钻石戒指到底是不是智商税中间打转,空气中总是弥漫着快活的气息。

这一次,老刘走马上任,面泛红光,给大伙一人整了两瓶啤的,大伙头一遭见他如此兴致,纷纷起哄道果然人逢喜事精神爽,当年滴酒不沾的刘哥咋也会带节奏了,没想到他却连声叹气,感慨道:“哪有你们想的这么美,我这是借酒消愁,最近没一天睡得好的,当了老大才知道,团队不好带啊。”

我一边倒酒,一边倒是乐了:“几年没见,刘哥倒是成了资深凡学大师了。”老刘竟没否认,叹了口气,感慨道:“老孟啊,我刚接手的时候,真的都惊了,你敢信不,这儿连CodeReview都没有。”

我把酒瓶缓缓放下,神情半信半疑,下意识的回了一句“不会吧?”却又被另一边颇有杠精气质的孙总抢了白,孙总哼笑一声:“这有啥不敢信的,我之前待的两个创业团队可都没有CodeReview,还不是稳的飞起。你真以为CodeReview有什么用么,哦,找个都不知道你代码是在干嘛的同事,花上十分钟走个过场,就能看出什么问题?”

“得了吧你!”老刘反驳道:“你那儿多奇葩你不知道吗?一天上线八次,前端就你一个,你想Review也没人可以做啊,难不成拉后端那帮搞数据的帮你看你CSS哪边盒儿模型没写对吗?”

孙总接过我递给他的啤酒,小抿了了一口:“别瞎说,哪儿有一天上线八次的?我们那边的CEO是个全栈,强的很好伐?找他完全没问题,是我自己感觉多此一举。”顿了一顿,孙总又补充道:“我吧,个人更看重效率,而不是流程。你要说Github上的那些技术型开源项目,做特性和分支管理的时候,搞个CodeReview合情合理,但你说我们业务项目,有啥好Review的,你为了质量跑去搞Review,那测试是干嘛的?”

我听到这里却有些皱眉,忙打断:“大哥,CodeReview可不仅仅是为了质量,也有出于安全方面的考量,当年沸沸扬扬的ANTD圣诞节雪花事件你忘了吗?不推CodeReview短期看可能的确不会出什么问题,但长期看肯定是有安全风险的。”

“安全风险,那是公司安全部门的事儿。各种安全扫描,Lint规则,不知道用么?”老孙一边说一边拿起一根串儿,并不服气。又不耐烦的发问:“不是,我就好奇你们Review都Review啥啊,还真一行行看代码么?”

“怎么就不能一行行看了?”老刘认真起来:“我说咱们专业点行不行?去年Google不是推了个CodeReview规范,该都看了吧?人家上面写的清清楚楚——任何可以提升代码质量的内容,你都可以做出评论!是吧,老孟?你来说说,你们字节那儿,这方面是不是很严格?”

“字节嘛——”我故意拉长了声音:“还是很优秀滴。”见两人都是一副不耐烦的表情。我神秘一笑,忙不迭解释:“相比其他我待过的团队,字节技术氛围更浓厚一些。目前我们的确是严格执行Google的那套CR规范的。不过呢,字节很扁平,并没有谁来带着我们做,你可以理解为,这种规范都是大家自发的。”见两人一副果不其然的表情点点头,我又小声补充了一句:“但…其实我们也有过无CR的阶段…”

“哈?”老刘完全没想到竟然引来了敌军。

“来来来,咱先走一个。”我拍拍老刘的肩膀,忽悠着大家干了一杯,啤酒下肚,我才慢悠悠解释道:“我们项目在beta测试之前都是不用CR的,那个时候产品不会触达用户,开发更加注重效率,公司有几个口号嘛,其中就有:务实敢为、始终创业。那时无CR还是具有一定的合理性的,所以我们便大胆执行了。当然,这也是大伙一致认同的,这个状态持续到项目上线才停止。”

老刘松了口气,点点头道:“产品都还没上线,也算可以理解吧。”

“项目上线,常规的组内Review水到渠成的建立起来,除此之外,我们周会还有个分享性质的CodeReview,一周一次,倒是以提交者讲读为主,Review倒是次要了。”

“至于刚刚孙总的问题嘛,Re啥呢?”我皱起眉头稍作思索,才继续解释:“其实刚刚开始的时候我也挺困惑的,我看别人的代码总感觉一水的牛逼,尤其字节跳动你知道吧,个个儿大神级别,我哪儿能看出人家的问题啊。不过跟着大神的好处就是,你能进步得特别快,我虽然一开始提出不了什么问题,但是跟着眼瞅了一个月,也学了不少东西,比如大神Review代码的思路和重点,渐渐地,我也能抓几个屎橛子出来了哈哈哈哈。”

老孙没好气:“你戏可是真多。”

我给说的有点不好意思,挠了挠头道:“你也不能怪我,的确很多诸如最新的语法糖啦,性能优化些许的写法啦,我每次评起来都挺犹豫的,一方面又想让别人知道,一方面又觉得其实也没引起bug,是不是挺没必要的。”

老刘咂咂嘴:“嗨,至于么,这事儿吧就别太多心理负担,有好的写法就上嘛,三人行必有我师没听过么?也是互相学习嘛。”说到这儿,老刘似乎又有些羡慕,转身对着孙总道:“我现在也不要求我们组的小弟弟们能这么一板一眼,毕竟水平在那儿,还是有差距的,我拉了几个老Coder放了Reviewer的权限,团队任何人上线就要找他们其中的一个,出问题了一起背锅。”

我点点头“也倒也是个挺常见的做法,挺好的。虽然放弃了整个团队互相学习的机会,但是至少质量和安全有所保证了。也能帮助新人迅速成长,针对性更强。”

老刘也点点头,似乎是感觉自己说服了孙总,举起酒杯试探道:“怎么样孙总,回头给你们项目搞个Review试试?”

孙总目光停在手里的酒杯上,歪嘴笑了,缓缓道来:“我倒没想这些,我的项目嘛,一个人,着实没有必要,只是我听着你们说着,便想到咱们仨刚工作那会,老黄是怎么搞的CodeReview。你们还记得吗?”

“嘿,老黄每周都会定周五下午的会议室,他到有理,说是我们到了周五就心不在焉,不如组织起来一起Review代码,那会可严肃了,当周提交的代码都打到投影上,他还单独开了个Excel文件,每个人提的问题,问题的文件名和行数,都一行行的记在里头。”

老刘激动起来:“对对对,我那时候还跑去单独找过你,你还记得不。”老刘对着孙总询问。

“你跑来找我,央求我提前Review你的代码,把错提前挑出来,然后留两行不改,等到会议的时候再提。以免你的错误太多,面子上挂不住。”

我听的满头问号,“不是,我咋不知道呢?怪不得那时候你们错都那么少,一到我就十几条十几条的提。”

“噗嗤…”

“哈哈哈哈…不是,老孟,你那时候的代码写的那是真的臭啊…….”

“哎我说你们至于吗?”我有点哭笑不得。

孙总拉住我:“我说,孟哥,咱别在意这些细节,你听我说,我就是感慨啥呢,我就是觉得吧,这么多年了,我早就不记得你们都在老黄的评审会上给我提了什么错了,可我还是能记得咱坐在一起CodeReview的画面,还能记得昏昏欲睡的下午,是吧,那个关了窗拉上帘以后臭气熏天的会议室,嘿嘿,就感觉吧,感觉吧,其实挺有意思的。你想嘛,人家老师医生公务员律师,谁知道什么代码Review,就咱码农,诶,搞得还挺像那么一回事儿的,挺有仪式感的。”孙总感慨了半晌,又悠悠地说:“其实那时候老黄挺好的,我的代码他可是真的一行行的审啊。”

“老黄现在在哪儿混啊?”

“不知道,他也该三十五了,估计退休了吧。”孙总一边回答老刘的提问一边坏笑起来。

“这可是你说的。”老刘像抓住了什么把柄。

“老刘你这人,有没有意思啊,来来来,赶紧喝酒吧。我这瓶可就没了。”

….

我又被两个大哥忽悠到举起杯,一饮而尽,咕噜咕噜咽下冰啤的恍惚间,我的确有些闪回,想到这些年里的一张张面孔,想到了许多人儿,想起他们跑到我的面前跟我说,老孟你帮我Review一下代码的样子,我甚至想到2008年我刚刚开始写HTML页面的时候,中国互联网生态正摆了怎样的姿势来为后来的一跃而起做好准备的。

那时候的我们就是这样一期一会地从简单的一行行div和span开始的CodeReview。一直到今天,CodeReview成为了一种讲述,一种诠释,一种呼唤,一种膜拜。他像一个安全带一样把我们和我们的业务、项目、团队,公司,牢牢绑定,以保证我们不至于因为速度太快而被离心力抛出去。这个颇为简单却异常坚定的行动,背后渐渐聚集起了庞大的能量。

如今,我们在自己时代的BGM中,已经走得很远了,我们国家开发者的身影也时常出现在Github,在一次次的CR中与全球的开发者对话,盛世呈现出了令人动容的神态,这是所有提交者的伟绩。

2020终于过去了,2021的开端,有些不幸—— 因为老刘似乎喝大了,孙总也不太乐观。新一周的上线又风风火火的开始了,几条CodeReview评论我还没来得及阅读,却花了些许时间记录这些。

一方面,是感怀这些酒量平平无奇的开发者们,他们维系着我们的代码库健康茁壮的生长;另一方面,也是感谢出现在我生命中的每个Reviewer,他每个人都曾带给我的力量。CodeReview是简单的,却是精美的。

希望新年里,我们每个人都能从像这样的简单事情中。

找到知识,找到生活,找到自己。

CodeReview杂谈的更多相关文章

  1. 【腾讯Bugly干货分享】让 CodeReview 这股清流再飞一会儿

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/ToYeT4Y4pzx0ii9Z92fo-Q 作者:刘 ...

  2. 【转】PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数

    原文地址: PHP 杂谈<重构-改善既有代码的设计>之一 重新组织你的函数 思维导图   点击下图,可以看大图.    介绍   我把我比较喜欢的和比较关注的地方写下来和大家分享.上次我写 ...

  3. 【管理心得之三十二】PMP杂谈---------爱情必胜术

    这次一反常态,没有场景设计,我想借此文普及一下PMP是什么? 但我不知道这样枯燥的话题能否能引起你的兴趣,我不得不套用“标题党”<爱情必胜术>来博你眼球. 我真没有说谎,此文是献给那些孤身 ...

  4. [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈

    我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点:        1.可以了解Python简单爬取图片的一些思路和方法 ...

  5. CodeReview Learning

    目录 . 引言 . 代码检视的指导思想 . 代码检视的内容 . 回归测试 0. 引言 代码检视(Code Review)是指软件开发人员在完成代码设计.编写.调试后展开的个人或群体性的代码阅读过程,代 ...

  6. 分享总结:更好地CodeReview

            代码质量分享    2016_06_24_舒琴_代码质量.key    For 代码提交人     基本原则 Review时机: 对于普通bugfix或优化,CodeReview最迟要 ...

  7. 杂谈:HTML 5页面可视性API

    译文来源:http://www.ido321.com/1126.html 原文:HTML5 Page Visibility API 译文:HTML 5的页面可视性API 译者:dwqs 在早期,浏览器 ...

  8. codereview介绍

    1. 定义: Code review is systematic examination (often known as peer review) of computer source code. I ...

  9. Ⅸ.spring的点点滴滴--IObjectFactory与IFactoryObject的杂谈

    承接上文 ObjectFactory与IFactoryObject的杂谈 .net篇(环境为vs2012+Spring.Core.dll v1.31) public class parent { pu ...

随机推荐

  1. 论文笔记:(ICCV2019)KPConv: Flexible and Deformable Convolution for Point Clouds

    目录 摘要 一.引言 二.相关工作 投影网络 图卷积网络 逐点多层感知器网络 点卷积网络 三.核点卷积 3.1由点定义的核函数 3.2刚性的或可变形的核 3.3核点网络层 3.4核点网络架构 四.实验 ...

  2. Gateway网关匹配规则

    Gateway匹配规则 重要概念 路由 route 断言 predicate 过滤器 fliter 一.时间匹配 在 after 时间之后的所有请求转发到 URI中的地址 gateway: disco ...

  3. 使用递归计算1~n之间所有整数的和

    5+getSum(4) 5+4+getSum(3) 5+4+3+getSum(2) 5+4+3+2+getSum(1) 5+4+3+2+1 function getSum(n){ if(n===1){ ...

  4. 记录21.07.22 —— Vue.js基础(一)

    VUE基础 语雀课件地址 Vue.js框架 Vue中文文档 Vue.js 创建vue项目 ①在一个空项目中引入vue的js文件 <script src="https://cdn.jsd ...

  5. 对象转换工具 MapStruct 介绍

    前言 在我们日常开发的分层结构的应用程序中,为了各层之间互相解耦,一般都会定义不同的对象用来在不同层之间传递数据,因此,就有了各种 XXXDTO.XXXVO.XXXBO 等基于数据库对象派生出来的对象 ...

  6. Tensorflow2对GPU内存的分配策略

    一.问题源起 从以下的异常堆栈可以看到是BLAS程序集初始化失败,可以看到是执行MatMul的时候发生的异常,基本可以断定可能数据集太大导致memory不够用了. 2021-08-10 16:38:0 ...

  7. JUC学习笔记(一)

    1.什么是 JUC 1.1.JUC简介 在 Java 中,线程部分是一个重点,本篇文章说的 JUC 也是关于线程的.JUC 就是 java.util .concurrent 工具包的简称.这是一个处理 ...

  8. C++//递增运算符重载

    1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 //重载递增运算符 6 7 //自定义 ...

  9. Numpy数组的组合与分割详解

    在介绍数组的组合和分割前,我们需要先了解数组的维(ndim)和轴(axis)概念. 如果数组的元素是数组,即数组嵌套数组,我们就称其为多维数组.几层嵌套就称几维.比如形状为(a,b)的二维数组就可以看 ...

  10. 基于ivy的源代码调试方法

    项目PORJ_TEST是项目PROJ的测试项目.在它的ivy中引用了PROJ的jar包.由于PROJ正处于开发阶段,源代码更改频繁, 在运行PROJ_TEST中的测试时,需要进入PROJ的jar包内部 ...