如何高效迅速的進(jìn)行CodeReview

前言

很多公司都要求項(xiàng)目做CodeReview巢块,但很多人第一次CodeReview往往不知道該如何做键袱,也不知道為什么去做鹉动。筆者參加過幾個(gè)項(xiàng)目的CodeReview再菊,發(fā)現(xiàn)一些共性問題:

  • 有時(shí)候參與Review的人太多了,意見太分散颜曾,Review時(shí)間拉的很長(zhǎng)纠拔,發(fā)現(xiàn)問題效率低;
  • 有時(shí)候會(huì)發(fā)現(xiàn)一個(gè)CodeReview時(shí)間很長(zhǎng)泛豪,參與者會(huì)覺得煎熬和浪費(fèi)時(shí)間稠诲;
  • 有時(shí)候不太了解對(duì)方評(píng)審的東西侦鹏,沒法跟上大家的思路,影響效率臀叙;
  • 有時(shí)候走查的代碼量太大了略水,無法做到詳細(xì)走查;
  • 有時(shí)候會(huì)看到有些人無所事事劝萤、精神不集中渊涝、不發(fā)言,影響效果床嫌。

對(duì)這些問題跨释,用魚骨圖做個(gè)分析:

希望本文中的一些建議能夠緩解上述問題,能使大家更快的了解CodeReview的意義和方法厌处,有經(jīng)驗(yàn)的人能夠更加快速有效的進(jìn)行CodeReview鳖谈。


CodeReview的目標(biāo)和原則

CodeReview的目的是提升代碼質(zhì)量,盡早發(fā)現(xiàn)潛在缺陷與BUG阔涉,降低修復(fù)成本缆娃,同時(shí)促進(jìn)團(tuán)隊(duì)內(nèi)部知識(shí)共享,幫助更多人更好地理解系統(tǒng)瑰排。

建議CodeReview的原則如下:

  • 發(fā)現(xiàn)代碼的正確性

代碼審查用意是在代碼提交前找到其中的問題——你要發(fā)現(xiàn)的是它的正確性贯要。在代碼審查中最常犯的錯(cuò)誤—幾乎每個(gè)新手都會(huì)犯的錯(cuò)誤是,審查者根據(jù)自己的編程習(xí)慣來評(píng)判別人的代碼凶伙。

  • 不僅是在Review Code郭毕,更是在分享和學(xué)習(xí)

Code Review最重要的是講解者分享業(yè)務(wù)流程和設(shè)計(jì)思路,參與者通過這些講解獲得這些信息函荣,使得更多人理解這個(gè)系統(tǒng)显押,提升團(tuán)隊(duì)整體水平,使得團(tuán)隊(duì)維護(hù)代碼的能力提升傻挂。

  • 高效迅速完成CodeReview

我們不能為了應(yīng)付匆匆忙忙的進(jìn)行一次代碼審查乘碑,效率也是很重要的,如果不能保證Code Review目的實(shí)現(xiàn)金拒,那么評(píng)審便是徒勞的兽肤。


如何高效完成CodeReview?

參與者要檢查設(shè)計(jì)的合理性以及業(yè)務(wù)邏輯是否錯(cuò)誤绪抛,檢查代碼可讀性资铡;講解者要想辦法分享設(shè)計(jì)、技術(shù)幢码、經(jīng)驗(yàn)等知識(shí)笤休。

1.檢查設(shè)計(jì)的合理性和業(yè)務(wù)邏輯的正確性:

  • 代碼的設(shè)計(jì)是否符合設(shè)計(jì)要求
    • 如果存在代碼和設(shè)計(jì)有出入的地方需要問詢?yōu)槭裁匆儎?dòng),因?yàn)檫@些變動(dòng)有可能是出于開發(fā)者在真正設(shè)計(jì)代碼時(shí)候的深入考慮症副,或者是由于一時(shí)大意出現(xiàn)偏差店雅。
  • 業(yè)務(wù)邏輯是否正確
    • 業(yè)務(wù)流程是否按照詳細(xì)設(shè)計(jì)的流程走政基,不要出現(xiàn)原本是先A流程后B流程而設(shè)計(jì)的時(shí)候出現(xiàn)先B后A,或者丟失流程闹啦。
    • 某些傳入?yún)?shù)是否合理:判斷某些接口的參數(shù)輸入是否是冗余的沮明,比如輸入A字段可以滿足A接口里面的所有操作,那么多輸入一個(gè)B就冗余的窍奋。
    • 數(shù)據(jù)庫字段的設(shè)計(jì)荐健,數(shù)據(jù)庫的設(shè)計(jì)是對(duì)實(shí)際業(yè)務(wù)的映射,我們要保證每一個(gè)字段的出現(xiàn)都反應(yīng)實(shí)際業(yè)務(wù)并且經(jīng)過合理性的驗(yàn)證费变,比如設(shè)計(jì)table1的時(shí)候A字段在table2中已經(jīng)出現(xiàn)摧扇,并且A和B表有相應(yīng)的關(guān)聯(lián),那么要注意A字段對(duì)于table1的冗余是否有合理性挚歧,如果沒有合理的說服性可以去掉A扛稽,而節(jié)省對(duì)A字段的維護(hù)成本(存儲(chǔ)空間,更新操作等)滑负。
    • 某些判斷是否合理在张,比如某些參數(shù)的輸入金額是否可以為0的判斷等等。
    • 系統(tǒng)交互是否合理矮慕,比如在代碼設(shè)計(jì)的時(shí)候沒有關(guān)注考慮系統(tǒng)交互的順序而造成有些信息不能獲取到帮匾;比如獲取支付方式的費(fèi)率信息必須要等待支付的時(shí)候才能拿到,那么獲取這些信息就應(yīng)該放在pay_trans的時(shí)候而不是create_trans痴鳄,大多數(shù)這種問題其實(shí)都是詳細(xì)設(shè)計(jì)時(shí)出現(xiàn)的瘟斜,代碼評(píng)審階段比較少見。
    • 是否有異常處理機(jī)制痪寻,一個(gè)好的代碼設(shè)計(jì)應(yīng)該考慮各種異常并對(duì)相應(yīng)的異常做出合理的處理螺句,比如接口的可重入,當(dāng)代碼檢測(cè)到有重入的這種情況橡类,怎樣去做這種異常處理使得調(diào)用方能捕捉的這些異常而進(jìn)行后面的處理蛇尚。
  • 關(guān)注業(yè)務(wù)可拓展性
    • 我們的業(yè)務(wù)在不斷的發(fā)展,每一個(gè)項(xiàng)目設(shè)計(jì)都會(huì)影響后續(xù)業(yè)務(wù)的拓展顾画,一個(gè)好的設(shè)計(jì)應(yīng)該考慮到后續(xù)業(yè)務(wù)的發(fā)展取劫,而盡量避免定制化的設(shè)計(jì)。
  • 關(guān)注使用到的數(shù)據(jù)結(jié)構(gòu)研侣、設(shè)計(jì)模式和代碼性能
    • 一個(gè)好的數(shù)據(jù)結(jié)構(gòu)和設(shè)計(jì)模式可以增加代碼的可維護(hù)性安全性和效率等谱邪,比如我們?cè)谠O(shè)計(jì)的時(shí)候要考慮到不同的場(chǎng)景選擇什么樣的數(shù)據(jù)結(jié)構(gòu),有時(shí)候我們會(huì)糾結(jié)于用map還是用hash_map庶诡,這時(shí)候我們要根據(jù)具體的情況具體分析虾标;
    • 當(dāng)我們?cè)O(shè)計(jì)代碼的時(shí)候如果能用上系統(tǒng)提供的函數(shù)那么最好不要自己去寫,比如自己實(shí)現(xiàn)一個(gè)鏈表的時(shí)候是否可以想到用系統(tǒng)庫提供的list_head以確保鏈表結(jié)構(gòu)的正確性;
    • 某些設(shè)計(jì)如果能套用設(shè)計(jì)模式會(huì)讓設(shè)計(jì)更加美觀也讓閱讀者更加明了璧函;出于對(duì)系統(tǒng)性能的考量,我們要關(guān)注編寫代碼對(duì)系統(tǒng)的開銷基显,包括使用的算法是否合理蘸吓,以及對(duì)某些比較耗時(shí)的操作比如數(shù)據(jù)庫的操作要加以關(guān)注。

2.檢查代碼可讀性和可維護(hù)性:

  • 如果代碼的可讀性強(qiáng)撩幽,那么維護(hù)起來也就方便很多库继;一個(gè)好的代碼規(guī)范和編碼風(fēng)格會(huì)節(jié)省大家對(duì)代碼的理解時(shí)間,減少維護(hù)成本窜醉;雖然我們有編程規(guī)范檢查工具宪萄,但有些內(nèi)容檢查不出來,是需要靠大家去規(guī)范的榨惰。
  • 關(guān)注代碼注釋:我們?cè)诰帉懞瘮?shù)和進(jìn)行邏輯判斷的時(shí)候最好要標(biāo)注一下這個(gè)函數(shù)或者這段判斷是用來做什么的拜英;做了這種注釋的好處,一來當(dāng)別人閱讀這段代碼的時(shí)候看到你的注釋以后就會(huì)根據(jù)你的思路快速理解代碼琅催,甚至不閱讀直接跳過居凶;二來防止自己由于長(zhǎng)時(shí)間不閱讀代碼而忘記這段代碼的用途。
  • 關(guān)注命名規(guī)范:雖然我們有自己的編碼規(guī)范藤抡,但是這種規(guī)范只是限制了使用駝峰命名法還是其他命名法侠碧;而好的命名風(fēng)格應(yīng)該是看到變量或者函數(shù)名字就能“望文生義”,畢竟我們不能把自己寫的所有代碼都做注釋缠黍。
  • 關(guān)注重復(fù)代碼:如果出現(xiàn)大量的重復(fù)性代碼弄兜,要考慮將這些代碼抽象出公用函數(shù),以減少代碼量并增強(qiáng)代碼可讀性瓷式。
  • 關(guān)注繁瑣的邏輯:如果一個(gè)簡(jiǎn)單的功能卻對(duì)應(yīng)大篇幅的代碼替饿,要考慮一下是不是有比較簡(jiǎn)單的實(shí)現(xiàn)方式,因?yàn)檫^于復(fù)雜的代碼會(huì)給后來者的維護(hù)帶來麻煩蒿往;如果沒有簡(jiǎn)略的辦法盛垦,一定要把注釋寫好。

3.分享設(shè)計(jì)瓤漏、技術(shù)腾夯、知識(shí)和經(jīng)驗(yàn)

  • 在代碼審查的過程中,大家往往把關(guān)注點(diǎn)放在發(fā)現(xiàn)代碼的不足上蔬充,忽略了代碼評(píng)審過程中的設(shè)計(jì)思想蝶俱、技術(shù)方法、業(yè)務(wù)知識(shí)的傳播饥漫,我覺得這些內(nèi)容也是非常重要的榨呆,也需要同時(shí)關(guān)注。
  • 評(píng)審者在自己的代碼時(shí)會(huì)深入業(yè)務(wù)流程庸队,參與這可以看到評(píng)審代碼的一些算法积蜻、數(shù)據(jù)結(jié)構(gòu)闯割、設(shè)計(jì)模式甚至是系統(tǒng)架構(gòu)等知識(shí)以及評(píng)審者在編碼過程中踩過的坑;通過這些信息參與者可以提升自己的業(yè)務(wù)水平和技術(shù)能力使得整個(gè)團(tuán)隊(duì)的水平得到提高竿拆。
  • 參與者除了要有這種學(xué)習(xí)意識(shí)外宙拉,評(píng)審者也要想辦法讓參與者更加快速高效的去理解代碼中傳播的知識(shí),這樣能幫助提升Review速度丙笋,所以建議評(píng)審者能簡(jiǎn)單介紹一下項(xiàng)目的背景以及詳細(xì)設(shè)計(jì)谢澈,這些信息的介紹有以下好處:
    • 首先,代碼的設(shè)計(jì)是按照詳細(xì)設(shè)計(jì)來執(zhí)行的御板,但是設(shè)計(jì)者在真正code的時(shí)候會(huì)出現(xiàn)一些變動(dòng)锥忿,這些變動(dòng)要給大家一個(gè)同步;
    • 其次怠肋,參與過詳細(xì)設(shè)計(jì)的人可能由于沒有直接參與的code敬鬓,時(shí)間長(zhǎng)會(huì)忘記之前詳細(xì)設(shè)計(jì)的流程,簡(jiǎn)單介紹之后就會(huì)讓參與者想起灶似,方便參與者的理解列林;
    • 第三,對(duì)于沒參與詳細(xì)設(shè)計(jì)的同學(xué)酪惭,在簡(jiǎn)單介紹過這些信息后希痴,可以有個(gè)大致了解,不然整個(gè)評(píng)審過程會(huì)很煎熬春感;
    • 所以砌创,如果參與者對(duì)代碼的信息不理解,會(huì)造成參與者理解代碼的難度鲫懒,也就不能提出有建設(shè)性的意見嫩实,同時(shí)也難以學(xué)到評(píng)審中傳播的知識(shí);這一點(diǎn)在之前的評(píng)審中是比較容易被大家忽略的窥岩,尤其是在跨團(tuán)隊(duì)代碼評(píng)審時(shí)甲献,準(zhǔn)備不足和經(jīng)驗(yàn)不足的同學(xué)是很難理解對(duì)方在講什么的。
  • 講解code的時(shí)候最好是以接口功能為單位去講解
    • 如果評(píng)審者一下子把所有的詳細(xì)設(shè)計(jì)都講解完颂翼,可能會(huì)因?yàn)樾畔⒘勘容^大晃洒,或者設(shè)計(jì)到一些細(xì)節(jié)問題,參與者不能有效的記住或理解也會(huì)影響評(píng)審的速度和效率朦乏;
    • 評(píng)審者可以在講解的過程中分享一下自己踩過的坑球及,參與者可以隨時(shí)根據(jù)自己發(fā)現(xiàn)的問題進(jìn)行討論。


如何迅速完成CodeReview呻疹?

所謂的迅速就是節(jié)省時(shí)間吃引,只要我們盡量避免一些意義不大的事情就能節(jié)省時(shí)間,加快評(píng)審速度,要做到這點(diǎn)建議大家盡量不要做以下這些事情:

1.不要刻意地去尋找代碼bug

  • 有些代碼的邏輯是比較復(fù)雜的镊尺,如果是很容易就發(fā)現(xiàn)的缺陷朦佩,大多數(shù)情況下評(píng)審者自己在編碼過程就會(huì)發(fā)現(xiàn),那么剩下不容易發(fā)現(xiàn)的缺陷要發(fā)現(xiàn)也會(huì)花費(fèi)較多的時(shí)間鹅心,這些問題可以交給測(cè)試人員去發(fā)現(xiàn)吕粗;
  • 如果參與者刻意去找bug會(huì)造成顧此失彼,忽略更重要的東西旭愧;當(dāng)然,有些bug你可能一眼就看出來了宙暇,那提出來就再好不過了输枯。

2.不要按照自己的編程風(fēng)格去評(píng)論別人的代碼

  • 有些人參與者比較自信,對(duì)自己寫得代碼感覺很滿意占贫,所以有時(shí)候就會(huì)根據(jù)自己熟悉的編碼語言或者編碼風(fēng)格去評(píng)論別人的代碼桃熄;
  • 作為參與者,只要覺得評(píng)審者的代碼符合命名要求和設(shè)計(jì)要求就可以了型奥,但假如評(píng)審者的代碼缺陷很明顯瞳收,可以提出帶大家進(jìn)行討論。

3.不要帶著抨擊和質(zhì)疑別人能力的心態(tài)去進(jìn)行代碼評(píng)審

  • 有時(shí)候參與者可能心情不好厢汹,或者感覺對(duì)方是新人就忍不住會(huì)抨擊對(duì)方的代碼螟深,這樣會(huì)比較容易在模棱兩可的問題上浪費(fèi)時(shí)間;
  • 參與者可能認(rèn)為A方法好烫葬,評(píng)審者可能認(rèn)為B方法也不壞界弧,這樣就會(huì)造成沒有必要的爭(zhēng)論而浪費(fèi)時(shí)間。

4.不要在不確定的問題上爭(zhēng)來爭(zhēng)去

  • 大家在討論的時(shí)候如果某些問題討論一段時(shí)間以后仍然沒有結(jié)論搭综,或者需要第三方確認(rèn)或者評(píng)審者不能馬上理解參與者提出的意見時(shí)垢箕,不要花太多時(shí)間討論這些問題;
  • 把這些問題先記錄下來兑巾,等會(huì)議結(jié)束后評(píng)審者可以與參與者進(jìn)行線下討論条获,同時(shí)將這些問題根據(jù)自己的理解進(jìn)行解決,之后給大家一個(gè)反饋即可蒋歌,這樣可以節(jié)省很多時(shí)間帅掘。

5.不要聽不進(jìn)別人的意見

  • 有些評(píng)審者比較固執(zhí),不愿意接受大家的意見奋姿,會(huì)造成一些不必要的爭(zhēng)端和討論锄开,浪費(fèi)時(shí)間;
  • 當(dāng)然称诗,有時(shí)候參與者的意見不見得是最好的萍悴,作為評(píng)審者將其作為一個(gè)參照的方向和視角,如果存在爭(zhēng)論,這些建議也可以做成會(huì)議記錄癣诱,評(píng)審者私下和建議提出者討論以后給大家一個(gè)結(jié)論计维。

6.參與者最好不要自己都沒想明白就提意見

  • 如果參與者自己沒有想明白的事情就去提意見,那么評(píng)審者反問的時(shí)候會(huì)浪費(fèi)大家的時(shí)間撕予;
  • 參與者可以先將自己的想法大致記下來鲫惶,自己想清楚了之后再提給評(píng)審者也是節(jié)省時(shí)間的辦法。

7.評(píng)審前最好先通過代碼靜態(tài)檢查工具檢測(cè)

  • 一般規(guī)范性的問題都可以通過靜態(tài)檢測(cè)工具發(fā)現(xiàn)实抡,借助工具是最省事欠母,也是效率最高的,還可以避免大家都評(píng)審時(shí)提出很多規(guī)范性問題吆寨,而遺漏了業(yè)務(wù)邏輯赏淌、設(shè)計(jì)合理性等問題。

寫在最后

希望我們都能夠有效而迅速進(jìn)行CoderReview啄清,一方面提升代碼質(zhì)量本身六水,另一方面也可以創(chuàng)造一個(gè)良好的學(xué)習(xí)氛圍互相支持提升團(tuán)隊(duì)的整體代碼水平。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辣卒,一起剝皮案震驚了整個(gè)濱河市掷贾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荣茫,老刑警劉巖想帅,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異计露,居然都是意外死亡博脑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門票罐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叉趣,“玉大人,你說我怎么就攤上這事该押×粕迹” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蚕礼,是天一觀的道長(zhǎng)烟具。 經(jīng)常有香客問我,道長(zhǎng)奠蹬,這世上最難降的妖魔是什么朝聋? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮囤躁,結(jié)果婚禮上冀痕,老公的妹妹穿的比我還像新娘荔睹。我一直安慰自己,他們只是感情好言蛇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布僻他。 她就那樣靜靜地躺著,像睡著了一般腊尚。 火紅的嫁衣襯著肌膚如雪吨拗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天婿斥,我揣著相機(jī)與錄音劝篷,去河邊找鬼。 笑死民宿,一個(gè)胖子當(dāng)著我的面吹牛携龟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播勘高,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼坟桅!你這毒婦竟也來了华望?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤仅乓,失蹤者是張志新(化名)和其女友劉穎赖舟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夸楣,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宾抓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豫喧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片石洗。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖紧显,靈堂內(nèi)的尸體忽然破棺而出讲衫,到底是詐尸還是另有隱情,我是刑警寧澤孵班,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布涉兽,位于F島的核電站,受9級(jí)特大地震影響篙程,放射性物質(zhì)發(fā)生泄漏枷畏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一虱饿、第九天 我趴在偏房一處隱蔽的房頂上張望拥诡。 院中可真熱鬧触趴,春花似錦、人聲如沸袋倔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宾娜。三九已至批狐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間前塔,已是汗流浹背嚣艇。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留华弓,地道東北人食零。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寂屏,于是被迫代替她去往敵國和親贰谣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345