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

前言

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

  • 有時候參與Review的人太多了,意見太分散,Review時間拉的很長,發(fā)現(xiàn)問題效率低;
  • 有時候會發(fā)現(xiàn)一個CodeReview時間很長,參與者會覺得煎熬和浪費(fèi)時間;
  • 有時候不太了解對方評審的東西,沒法跟上大家的思路,影響效率;
  • 有時候走查的代碼量太大了,無法做到詳細(xì)走查;
  • 有時候會看到有些人無所事事、精神不集中、不發(fā)言,影響效果。

對這些問題,用魚骨圖做個分析:

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


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

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

建議CodeReview的原則如下:

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

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

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

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

  • 高效迅速完成CodeReview

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


如何高效完成CodeReview?

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

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

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

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

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

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

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


如何迅速完成CodeReview?

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

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

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

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

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

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

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

4.不要在不確定的問題上爭來爭去

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

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

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

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

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

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

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

寫在最后

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容