如何让评审人爱上我
簡(jiǎn)介: 今天小編作為一個(gè)開發(fā)者,放下外部的客觀因素,僅從一個(gè)代碼的實(shí)現(xiàn)者,一個(gè)被評(píng)審人的角度去思考如何讓評(píng)審變得高效而富有意義。換句話說:如何讓評(píng)審人愛上我(被評(píng)審人)。
眾所周知,每個(gè)有技術(shù)追求的團(tuán)隊(duì),都試圖想把Code Review做到極致。正所謂——未經(jīng)審視的代碼,不值一提。為什么Code Review如此重要,本篇不再贅述,僅做簡(jiǎn)單總結(jié):
- 提早發(fā)現(xiàn)問題,防患故障于未然
- 快速提高團(tuán)隊(duì)新同學(xué)的編程能力
然而夢(mèng)想很豐滿,現(xiàn)實(shí)很骨感,團(tuán)隊(duì)的評(píng)審活躍度和評(píng)審質(zhì)量往往令人堪憂,緣由種種,上至技術(shù)TL、下至代碼功能的實(shí)現(xiàn)者,甚至產(chǎn)品經(jīng)理(嗯,一定是業(yè)務(wù)太重導(dǎo)致沒時(shí)間做Code Review)都能成為做不好Code Review的罪魁禍?zhǔn)住=裉煨【幾鳛橐粋€(gè)開發(fā)者,放下外部的客觀因素,僅從一個(gè)代碼的實(shí)現(xiàn)者,一個(gè)被評(píng)審人的角度去思考如何讓評(píng)審變得高效而富有意義。換句話說:如何讓評(píng)審人愛上我(被評(píng)審人)。
為什么要讓評(píng)審人愛上我
?
在以往的文章討論中,我們往往更專注于如何提升評(píng)審人的水平,如何找出評(píng)審代碼的問題,或者如何讓被評(píng)審人能快速解決提出的問題。但我們忽略了評(píng)審人的感受,似乎評(píng)審人就是一個(gè)毫無感情的找BUG機(jī)器。當(dāng)然,不排除一些自動(dòng)化掃描的工具(比如:Codeup的缺陷檢查、漏洞分析等等),它們確實(shí)是AI機(jī)器人。但除此以外很多時(shí)候因?yàn)閷?duì)代碼的業(yè)務(wù)理解、團(tuán)隊(duì)的編碼風(fēng)格等問題,還是需要團(tuán)隊(duì)的其他成員作為評(píng)審者介入其中。對(duì)于不走心的敷衍評(píng)審我們撇開不談,評(píng)審者參與一次評(píng)審還是挺耗費(fèi)精力和時(shí)間的,需要時(shí)間去閱讀、理解、并指出疑問。因此,我們應(yīng)該放下防備,坦然對(duì)待評(píng)審過程,并對(duì)評(píng)審人心懷感激。
如何讓評(píng)審人愛上我
?
既然我們已經(jīng)下定決心與評(píng)審人來一場(chǎng)甜蜜的Code Review之旅,怎樣才能讓評(píng)審人愛上我(的評(píng)審)?我從一次評(píng)審的全周期來分析,分別為:
- 【評(píng)審前】如何做好評(píng)審前的準(zhǔn)備;
- 【評(píng)審中】如何對(duì)待評(píng)審中的討論/問題;
- 【評(píng)審后】評(píng)審后需要做什么。
?
提交評(píng)審前
?
重點(diǎn):
- 認(rèn)真審視自己的代碼
- 做好提交(Commit)
- 保證測(cè)試基線
?
認(rèn)真審視自己的代碼
在評(píng)審中,最忌諱的一點(diǎn)就是犯一些低級(jí)錯(cuò)誤,這樣不僅會(huì)給評(píng)審者很差的印象,也會(huì)將評(píng)審者的時(shí)間浪費(fèi)在一些低級(jí)錯(cuò)誤之中。所以,我們要在提交代碼前自己先認(rèn)真審視自己的代碼。
格式問題
格式問題,常發(fā)生在一些初建的團(tuán)隊(duì),大家有不同的開發(fā)習(xí)慣、編碼風(fēng)格,在單人開發(fā)中,并沒有什么問題。當(dāng)這個(gè)項(xiàng)目涉及到多人協(xié)作時(shí),就會(huì)顯得很麻煩。比如下面這個(gè)評(píng)審,其實(shí)是沒有實(shí)際的改動(dòng)只是編碼風(fēng)格的格式化。但密密麻麻的文件變動(dòng),往往會(huì)讓人心神不寧。
因此在提交前,我們應(yīng)按照?qǐng)F(tuán)隊(duì)的規(guī)范,設(shè)置好自己的編輯器格式工具,并在提交前檢查是否存在格式上問題,避免這種問題在Code Review的時(shí)候浪費(fèi)大家的時(shí)間。
拼寫錯(cuò)誤
拼寫錯(cuò)誤是屬于低級(jí)錯(cuò)誤了,目前主流的編輯器都支持拼寫檢查,只要大家認(rèn)真對(duì)待編輯器高亮的warning,就能找出來啦。
?
代碼規(guī)范掃描
?
一些非常基礎(chǔ)問題,可以通過自動(dòng)化工具掃描出來。比如針對(duì)java的開發(fā)規(guī)約檢測(cè),代碼平臺(tái)提供的漏洞檢測(cè)、安全掃描等。在提交以后看到分支上改動(dòng)的commit都是綠色的pass,心情也會(huì)好很多。畢竟咱給評(píng)審者提供的代碼也是經(jīng)過一遍初選的復(fù)賽選手了。
?
做好提交(Commit)
說到提交(commit),很多同學(xué)都覺得沒什么。不就是git commit 么。或者commit的時(shí)候,因?yàn)镚it的強(qiáng)制要求必須包含message,才隨便輸幾個(gè)只有自己懂的提交說明,然后git push拉倒。比如下面這種提交說明,我在很多兄弟團(tuán)隊(duì)的代碼倉(cāng)庫都有見過。
這種提交說明的問題,我就不再贅述了。接過老項(xiàng)目、給老工程填過坑的人都懂。因此在評(píng)審階段,我們就要做好提交。
?
- 要點(diǎn)一:按功能拆分提交,拒絕大Diff評(píng)審
在平時(shí)的開發(fā)中,大家往往都是多個(gè)任務(wù)并行開發(fā)。很多同學(xué)又不喜歡來回切換變更的分支,導(dǎo)致很多評(píng)審都是多個(gè)功能一股腦的提交,因此評(píng)審自然也就變得很大。或者在開發(fā)一個(gè)比較大的需求時(shí),沒能將功能進(jìn)行拆分細(xì)化,導(dǎo)致所有的改動(dòng)都在同一個(gè)評(píng)審中,甚至在同一個(gè)Code Review中。例如:
這個(gè)評(píng)審,中間混雜了數(shù)十個(gè)功能的提交,評(píng)審者很容易迷失在不同功能的邏輯迷宮中。更有甚者,會(huì)提交增刪行數(shù)高達(dá)上萬行的評(píng)審。對(duì)于這種超大評(píng)審,我不太相信評(píng)審者會(huì)認(rèn)認(rèn)真真地看完。有研究自媒體分享的統(tǒng)計(jì),現(xiàn)代人的注意力只能聚焦5分鐘,如果一個(gè)分享超過5分鐘無法結(jié)束,人們往往會(huì)因?yàn)橄氩黄饋砬懊娴膬?nèi)容而放棄。評(píng)審也是如此,長(zhǎng)達(dá)數(shù)萬行的改動(dòng),都在同一個(gè)評(píng)審中,即便是在評(píng)審頁面上提供鉚釘已閱讀的文件的功能,也很難在短時(shí)間內(nèi)容理解上下文的邏輯。因此評(píng)審者需要耗費(fèi)長(zhǎng)達(dá)半個(gè)小時(shí)以上的獨(dú)立時(shí)間來閱讀評(píng)審的改動(dòng),而這對(duì)于正常的開發(fā)人員是非常崩潰的。因此,我們?cè)谕瓿梢粋€(gè)功能的時(shí)候,應(yīng)當(dāng)合理的按功能拆分,將提交變小(small is beaut iful)。當(dāng)改動(dòng)過于龐大應(yīng)該考慮拆分多個(gè)評(píng)審進(jìn)行。
- 要點(diǎn)二:描述清楚本次提交的內(nèi)容、改動(dòng)點(diǎn)、改動(dòng)影響
一個(gè)評(píng)審的開始,從打開頁面到評(píng)審開始,一般眼睛的順序是:評(píng)審標(biāo)題->評(píng)審描述->改動(dòng)列表->改動(dòng)詳情
評(píng)審的標(biāo)題和評(píng)審的描述往往就是我們提交的內(nèi)容生成的。而作為評(píng)審開始的前兩個(gè)關(guān)鍵點(diǎn),評(píng)審提交描述是非常重要的。比如下面這種例子:
我相信各位作為評(píng)審人,看完這個(gè)評(píng)審已經(jīng)想關(guān)掉評(píng)審了(一些暴躁老哥甚至直接點(diǎn)拒絕)。令人費(fèi)解的評(píng)審標(biāo)題,空白的評(píng)審描述。即便我們拿著Code Review坐在評(píng)審者的電腦前、或者釘釘上附上評(píng)審解釋,這種體驗(yàn)都是非常不好的,因?yàn)榇蠹叶疾辉敢庾⒁饬Ρ环稚ⅰ>拖裎覀儗懘a一樣,大家都更愿意在開發(fā)過程中聚焦在編輯器上,而不是在不同的屏幕間來回切換(查看需求、被人中途打擾等)。因此我們應(yīng)該寫好描述,盡量讓評(píng)審開始的時(shí)候,大家都能在一塊屏幕(一個(gè)頁面上)完成評(píng)審的所有工作。
除此之外,良好提交說明,可以提前讓評(píng)審者感知到改動(dòng)點(diǎn)和改動(dòng)影響。比如下面:
評(píng)審者從描述中就能確定我們改動(dòng)的地方和改動(dòng)的影響,從而可讓評(píng)審者更快的進(jìn)入狀態(tài),而不需要自己去閱讀詳細(xì)內(nèi)容猜我們改了什么。
- 要點(diǎn)三:功能改動(dòng)和非功能改動(dòng)盡量分開
在一次功能中,我們除了功能性的改動(dòng),可能還包含一些非功能性的變動(dòng),如果都揉和在一起,往往看起來非常的難受。比如下面這種情況:
在這個(gè)改動(dòng)中,我除了做一些功能上改動(dòng),還順便修改了文檔、對(duì)以往的格式問題做了格式化。雖然都是同一個(gè)改動(dòng),但觀感還是非常差的。就像老師講課,好的老師一定是按內(nèi)容歸納,按內(nèi)容教授,而不是代數(shù)幾何混在一起講。
因此我們可以在評(píng)審的提交中做進(jìn)一步的拆分。還是針對(duì)上面的例子。我們調(diào)整后的樣子為:
在評(píng)審頁面的左側(cè)點(diǎn)擊全部提交,通過提交信息選擇我們需要獨(dú)立評(píng)審的提交內(nèi)容。
選擇功能性改動(dòng)的提交,進(jìn)行功能改動(dòng)的評(píng)審。
選擇非功能性提交,便可以只關(guān)注非功能的改動(dòng)。比如這里我們只用單獨(dú)看下README里的改動(dòng)就可以,全程清爽。
保證測(cè)試基線
在很多已經(jīng)成型的項(xiàng)目中,往往都有充分的測(cè)試覆蓋掃描。當(dāng)我們提交代碼的時(shí)候,在功能上我們第一個(gè)要保證的就是以往的測(cè)試都能通過(除非是這個(gè)測(cè)試用例已經(jīng)廢棄或存在錯(cuò)誤,這種我們應(yīng)該單拎一個(gè)功能來修正),這也是對(duì)評(píng)審者的尊重,因?yàn)檫B功能的正確性都無法保證的評(píng)審是無意義的。
在云效中,我們可以將評(píng)審的目標(biāo)分支作為保護(hù)分支,在自動(dòng)化檢查中配置自動(dòng)化檢查。通過在流水線中通過靈活的配置來設(shè)置我們工程中需要卡點(diǎn)檢查。
然后,在我們提交的評(píng)審的時(shí)候,就會(huì)自動(dòng)觸發(fā)我們配置的卡點(diǎn)了。如果卡點(diǎn)不通過,是不允許評(píng)審?fù)ㄟ^的。因此我們?cè)谔峤辉u(píng)審中,要注意卡點(diǎn)的內(nèi)容,要讓我們的評(píng)審“綠”起來。
評(píng)審中
?
重點(diǎn):
- 積極對(duì)待評(píng)審反饋
- 代碼是最好的解釋
- 原諒評(píng)審人的誤解/失誤
- 保證Code Review的時(shí)效性
?
積極對(duì)待評(píng)審反饋
一部分同學(xué)反感代碼評(píng)審的原因是,他們認(rèn)為評(píng)審人是有意為難自己。不能排除在一些比較復(fù)雜的社會(huì)環(huán)境中確實(shí)可能存在這種問題。但是作為被評(píng)審人,我們還是要積極的看待評(píng)審的反饋。畢竟雞蛋里挑骨頭的前提是要有骨頭,問題提出就一定有其合理性。絕大部分技術(shù)人對(duì)待代碼還是中立的,不能積極面對(duì)評(píng)審更多的是我們擔(dān)心自己的代碼不夠好,怕別人指出問題。但換個(gè)角度想,評(píng)審人其實(shí)也是在幫助我們,早點(diǎn)在評(píng)審階段發(fā)現(xiàn)問題,總比線上出了問題要好。另外,在不斷的評(píng)審中,我們也能快速的進(jìn)步自己的編碼能力。
代碼是最好的解釋
當(dāng)評(píng)審者對(duì)我們的代碼提出疑問的時(shí)候,我們除了解釋,更應(yīng)該做的是考慮為什么會(huì)出現(xiàn)這種疑問。有時(shí)候雖然我對(duì)評(píng)審人的疑問做了詳細(xì)的回復(fù),評(píng)審人似乎也理解了。但這個(gè)評(píng)審真的就結(jié)束了嗎?馬克思老人家說,我們應(yīng)該透過現(xiàn)象看本質(zhì)。畢竟評(píng)審人可能不只一個(gè),即便當(dāng)前的其他評(píng)審人看到這個(gè)解釋也能明白,但我們無法保證后續(xù)涉及這塊的代碼改動(dòng)再次評(píng)審的時(shí)候,會(huì)有人能明白這里的歧義。因此這種存在歧義的評(píng)審質(zhì)疑,其本身的問題是代碼未能做很好的解釋。
面對(duì)這種情況,一般的建議添加充分的代碼注釋。但我更建議我們直接對(duì)代碼進(jìn)行重構(gòu),讓代碼本身就能解釋清楚其意義。
原諒評(píng)審人的誤解/失誤
孔子云:人非圣賢孰能無過。評(píng)審者在評(píng)審中也會(huì)存在對(duì)正確代碼的誤解。在這種時(shí)候,我們不能得理不饒人,應(yīng)當(dāng)保持謙遜。正如在開篇中提到的,評(píng)審者實(shí)際是對(duì)我們提供幫助的,幫消滅我們自己未知的隱患。因此我們不應(yīng)該貿(mào)然反擊,應(yīng)當(dāng)理性回應(yīng),在解釋的同時(shí)也是對(duì)我們自己的代碼的一個(gè)很好的回顧。除此之外,我們還應(yīng)意識(shí)到這里另一個(gè)問題—— 存在即合理 ,如果評(píng)審者提出了疑問,是否證明這里存在不合理性,可能是代碼有歧義需要重構(gòu)?
保證Code Review的時(shí)效性
評(píng)審也應(yīng)該有時(shí)效性。因?yàn)樵u(píng)審人評(píng)審的代碼,往往不是自己的參與的業(yè)務(wù),評(píng)審周期拉的太長(zhǎng),可能會(huì)想不起來。因此在評(píng)審中,往往會(huì)設(shè)置一個(gè)提醒的鉤子。配合釘釘?shù)膚ebhook接收,能盡早的感知評(píng)審的人的意見。
在修改結(jié)束后及時(shí)給予反饋。這樣讓評(píng)審者對(duì)評(píng)審還沒“冷卻”的時(shí)候,就能更快的繼續(xù)評(píng)審,大家就能早早下班啦。
評(píng)審后
?
評(píng)審后,評(píng)審的內(nèi)容會(huì)保存在平臺(tái)上,后面可以隨時(shí)查看回顧。除此之外,在評(píng)審后最重要的是選擇一個(gè)合并方式。一般我會(huì)選擇squash的模式進(jìn)行合并。將評(píng)審中的所有提交合并為一個(gè)commit。這樣合并到主干中,一個(gè)提交就是一個(gè)功能。注意,這個(gè)和前文的提交拆分并不是一回事。在提交評(píng)審階段,我們?yōu)榱朔奖阍u(píng)審,將提交拆為功能改動(dòng)和非功能改動(dòng)。但在合并階段因?yàn)橐呀?jīng)通過了評(píng)審。我們要將一個(gè)功能的改動(dòng)放到一個(gè)提交中。
點(diǎn)擊合并后,評(píng)審中的多次提交最終會(huì)壓縮為一個(gè)commit合并到目標(biāo)分支中。這樣也就保證了一個(gè)功能一個(gè)commit的原則。在后續(xù)排查問題和線上回滾都會(huì)非常方便。
P.S. 合并方式應(yīng)該依據(jù)各自團(tuán)隊(duì)對(duì)工程管理和開發(fā)模式的選擇來決定,以上只是一個(gè)簡(jiǎn)單的例子。
總結(jié)
?
總結(jié)一下,如果讓評(píng)審者愛上給我做評(píng)審,我會(huì)這么做:
本文作者:陳博俊,阿里云技術(shù)專家,Git開源項(xiàng)目貢獻(xiàn)者,負(fù)責(zé)阿里巴巴經(jīng)濟(jì)體代碼平臺(tái)及云效代碼平臺(tái)底層架構(gòu)設(shè)計(jì)及運(yùn)維開發(fā)。
原文鏈接
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
- 上一篇: 汽车之家:基于 Flink + Iceb
- 下一篇: Java Map中那些巧妙的设计