宝,我今天CR了,C的什么R? 走过场的CR
原创:猿天地(微信公众号ID:cxytiandi),欢迎分享,转载请保留出处。
CodeReview我相信目前很多公司都会有这么一个流程,关键是这个流程有没有用就很难讲。主要还是取决于你对CR的理解以及有没有真正的去落地CR,去重视CR带来的隐藏价值点。
正好最近也是有人在问我CR相关的问题,他们也要开始做CR了,想了解下有没有最佳实践之类的。所以今天跟大家聊聊CR这个话题,我说的也不一定都是对的,仅供参考哈。
其实说实话,我觉得CR不存在什么最佳实践。因为每个公司或者说每个团队所进行的方式都会不一样,真正的想要做好CR只能先去做,在研发流程中去落地这个事情,然后慢慢的去提炼出符合你们团队的CR方式。
1.CR的目的
既然要做CR那肯定就有原因,CR的目的到底是什么?可以是走个流程,可以是提高代码能力,也可以是大家都在做,我也要做。我认为的目的有下面几个,请往下看。
1.1 稳定生产
大家想想,每个迭代开发完成后会进行测试,测试完成后就要发布到生产了。那么最有可能出现的问题就是你的新功能里面可能改到了老的逻辑,假设测试没有回归出来这个问题。那么一上线这个就影响到了生产的稳定性,所以CR最重要的目的就是稳定生产。
我们需要对代码进行CR,看看有没有改到老代码,会不会影响老的逻辑,有没有加开关呀,有没有兜底动作呀。因为一个团队里面总归会有新人进来,在不是很熟悉业务的情况下,很有可能就会改错,很有可能就会留下一个潜藏的Bug,这些都是需要CR去重点关注的。
上线可以,绝对不能影响到老版本,绝对不能出故障,否则你的绩效就凉凉了。你说你不想做CR,你的同事们会允许么,小伙子还是乖乖做CR吧!
1.2 间接培养backup
在管理团队的时候一定要注意培养backup,因为你也不知道下一个离开团队的人会是谁。互联网公司流动性还是挺大的,因为只有跳槽才能涨工资呀,我又说出了大家的心里话。
除了在明面上,可以指定谁作为某一块业务的owner,开发的时候由owner带着其他的人一起进行开发,这个过程中其实就有了backup,因为这一块业务知道的不在是某一个人了。
在台面下也要注意培养backup,此时CR就是一个很好的机会。CR的时候就可以让更多的人熟悉这些业务,但是方式一定要注意,不要光秃秃的只看代码,这样没参与开发的肯定是一个很懵的状态。可以在CR前让大家先大概的看下PRD,然后让CR的人讲解的时候不是一行行代码去Review, 先要讲自己这个迭代做的什么需求,有哪些功能,对应的代码就是现在CR的代码。这样才能让大家即了解业务又做了CR,一箭双雕。
当然,此时你会说,就算按照你说的方式进行CR,也不一定其他人就很熟悉了呀!这个是当然的,最熟悉的还是写代码的那个人嘛!但是我们让其他人有了一个大概的印象,假如后面写代码的那个人离职了,当有Bug要修的时候,其他人也是有映象当时这个功能的代码在哪里,我还记得CR过,我还提了一些建议。总比啥都不知道要强吧,你说对么?
1.3 提高代码质量
单纯从技术层面出发,CR的目的就是让大家来找茬,挑刺的。每个人的经验都不同,每个人的思路也不一样,往往你觉得这样写是最简单的方式,别人可能有更简单的方式去实现。
在CR的过程中,大家会提出自己的看法,实现的思路,代码是否写的够简洁,是否有开源框架能够直接实现某个功能,是否能否用设计模式进行优化,提高扩展性。领域建模是否合理,模块划分是否到位等等一系列的问题。
对于新人来说,能够得到很多有经验的同事在CR时给出的建议,对他的成长是很有帮助的。而且也会让你们的项目代码的质量一直维持在一个高的水平。这就是我们要做CR的目的,当然现实往往可能很残酷,很多项目到最后都会比较乱,代码也很臃肿,我想可能是当时被业务方倒排期,赶着要上线导致的吧!这种情况很常见,特别在创业型公司。
2.CR的方式
前面讲了几点我认为CR的目的,那么如何进行CR呢?常见的方式有哪些,来,接着往下看。
2.1 Gitlab
使用Gitlab做CR之前一般都是先提一个MR请求,然后针对这个请求做CR。这个MR请求里面所有的变动就是我们需要CR的点,如果有什么需要修改的可以在对应的代码处增加备注,CR结束之后各自根据当时的备注去修改。
2.2 开发工具
在我们的开发工具中直接进行CR也是非常的方便,好处在于可以看到整个功能的所有代码,就是你可以跟着业务的流程去讲解对应的代码。然后也可以很清楚的对比出哪些是你自己的改动,哪些是老的代码。
3.CR的时机
3.1 提测之前
在提测之前是最好的CR时机,这个时候我们有需要改进的再CR之后就直接改掉了。然后提测的时候就已经是我们改过之后的代码了,也许就减少了很多Bug,测起来也如丝般顺滑。
提测之前就CR影响的是什么?是我们的开发时间,本来开发完成之后就马上提测的,但是要在提测前进行CR,除非你的开发进度提前,否则还没开发完怎么做CR?
这个其实就是我们上面讲的流程了,将CR融入到研发流程中去,这样就可以在评估时间的时候给CR留出一天的buffer,比如11号要提测,那么10号就CR, 9号就是开发完成。
3.2 提测之后
提测之后做CR其实很不好,我们之前也有这样做过,做完之后立马改成了提测之前。因为在做的过程中会提出一些需要修改的点,然后这些点有可能测试已经测完了。然后你又改了,导致产生了新的Bug,增加了测试的工作量。
甚至还有一次是CR时候当场改的,然后没注意直接提交了,也没跟测试同步。第二天发生产环境直接出Bug了,所以一定不要在提测之后临近上线之前进行CR。
再举一个列子,之前有个团队老是喜欢在上线当天进行CR,测试已经再整体回归了,他们还在CR。当然有没有改动代码我不太清楚,因为不是一个团队,但是最严重的是回归的时候是有Bug的,需要及时修复。然后找不到人修,他们去CR了,也没人关注。导致的结果就是每次上线都要搞到好晚。
3.3 上线之后
上线之后就更不要CR了,你上线之后CR有什么意义呢?代码都发布了,这个时候CR出来的问题改还是不改呢?下个迭代改吗?下个迭代改完是不是又要回归一次,测试愿意么?
正所谓今日事今日毕,当前迭代的事情就在当前迭代解决,否则就是堆积如山了。
总结
对于CR我们还是要积极的拥抱,去落地,去实践。看上去会花费一部分时间,但带来的收益还是很不错的。项目的代码质量提高了,团队的技术氛围变好了,线上Bug明显变少了,大家对业务更熟悉了。
如果你们没有CR,请把这篇文章刷给你老板,就是这么任性。
如果对你有用,来个转发呗!
关于作者:尹吉欢,简单的技术爱好者,《Spring Cloud微服务-全栈技术与案例解析》, 《Spring Cloud微服务 入门 实战与进阶》作者, 公众号猿天地发起人。
宝,我今天CR了,C的什么R? 走过场的CR的更多相关文章
- LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树
题目:https://loj.ac/problem/3055 先写了暴力.本来想的是 n<=300 的那个在树上暴力维护好整个字符串, x=1 的那个用主席树维护好字符串和 nxt 数组.但 x ...
- LOJ 2586 「APIO2018」选圆圈——KD树
题目:https://loj.ac/problem/2586 只会 19 分的暴力. y 都相等,仍然按直径从大到小做.如果当前圆没有被删除,那么用线段树把 [ x-r , x+r ] 都打上它的标记 ...
- 洛谷 4364 [九省联考2018]IIIDX——“预留”的思路
题目:https://www.luogu.org/problemnew/show/P4364 原来想了一个错误的思路,就是这样: solve( cr , l , r ) 表示 cr 为根的子树填 [ ...
- bzoj 2850 巧克力王国——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2850 改一下估价即可.判断子树能否整个取或者是否整个不能取,时间好像就能行了? 因为有负数, ...
- bzoj 2716 [Violet 3]天使玩偶——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2716 第三道KDtree!仍旧是模板.还有CDQ分治做法,见下面. 数组迷之开大?(开6e5 ...
- bzoj 1941 [Sdoi2010]Hide and Seek——KDtree
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1941 第二道KDtree! 枚举每个点,求出距离它的最远和最近距离.O( n * logn ...
- bzoj 2238 Mst——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2238 一条非树边可以对一条链的树边产生影响.注意是边,所以把边下放到点上,只要跳 top 时 ...
- [考试反思]1112csp-s模拟测试111:二重
还是AK场.考前信心赛? 而且T3的部分分还放反了所有80的都其实只有50. 总算在AK场真正AK了一次... 手感好,整场考试很顺利.要不是因为T3是原题可能就没这么好看了. 20minT1,50m ...
- Oracle中的CR块详解
1.概述 Cr块consistent read块也就是用来维护oracle的读一致性的数据块.当查询某些数据的时候,发现数据块的版本比我们要查询的新,例如session1执行了dml操作并没有提交,s ...
随机推荐
- C#中的元组(Tuple)和结构体(struct)
在正常的函数调用中,一个函数只能返回一个类型的值,但在某些特殊情况下,我们可能需要一个方法返回多个类型的值,除了通过ref,out或者泛型集合可以实现这种需求外,今天,讲一下元组和结构体在这一方面的应 ...
- 一文解决MySQL时区相关问题
前言: 在使用MySQL的过程中,你可能会遇到时区相关问题,比如说时间显示错误.时区不是东八区.程序取得的时间和数据库存储的时间不一致等等问题.其实,这些问题都与数据库时区设置有关,本篇文章将从数据库 ...
- CRM系统全方位管理企业
您在选择一款CRM系统的时候,首先要考虑销售团队的感受和意见.让CRM系统在帮助销售团队优化工作流程的同时,更好地对销售团队进行管理.销售人员每卖出一件商品,要从寻找筛选商机开始,经过沟通客户需求.满 ...
- Django(33)Django操作cookie
前言 cookie:在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.cookie的出现就是为了解决这个问题,第一次登录 ...
- Nginx导航
简介 最近都在弄微服务的东西,现在来记录下收获.我从一知半解到现在能从0搭建使用最大的感触有两点 1.微服务各大组件的版本很多,网上很多博客内容不一定适合你的版本,很多时候苦苦琢磨都是无用功 2.网上 ...
- C语言程序设计#成绩查询系统
学生成绩管理系统 [注释]:请点赞,好人一生平[yi]安[wo]. #codeblocks程序下编写 #include<stdio.h>#include<stdlib.h>// ...
- zabbix监控之自定义监控
自定义监控node1数据库状态,并设置报警 编辑agent客户端的userparameter_mysql.conf 文件,最后一行添加自定义监控内容 [root@node1 ~]# cd /etc/z ...
- Lua _G
1.全局变量的原形 在Lua中,要声明全局变量很简单,那就是定义变量的时候,前面不要加上local. 这个神秘的全局变量,其实本质上也是一个table,它把我们创建的全局变量都保存到一个table里了 ...
- 10.4 route:显示或管理路由表
route命令 可以显示或管理Linux系统的路由表,route命令设置的路由主要是静态路由. 路由的概念 计算机与计算机之间的数据传输必须得经由网络,而网络可以通过直接连接两台计算机的方式或 ...
- 3分钟 Markdown 快速入门(超详细)(Day_33)
Markdown 快速入门 (这个贼重要)注:所有符号要在英文状态下完成哦,中文是没有效果的. 1.标题 # 表示一级标题 ## 表示二级标题 ### 表示三级标题 #### 表示四级标题 ##### ...