如何進行高效迅速的CodeReview | 百度敏捷教練



如何進行高效迅速的CodeReview | 百度敏捷教練

2015-09-15 張宏宇 百度敏捷教練 百度敏捷教練
百度敏捷教練

百度內部精益實踐,敏捷改進,研發效率,項目管理,工程文化等相關案例和實踐經驗分享和推廣。

背景

第一次參加CodeReview不知道該如何去做,也不知道爲什麼去做,後來參加多了,慢慢了解了CodeReview的意義,也同時發現CodeReview的效率問題:

  • 有時候會發現一個CodeReview時間很長,參與者會覺得煎熬和浪費時間;

  • 有時候不太瞭解對方評審的東西,沒法跟上大家的思路,影響效率;

  • 有時候會看到有些人無所事事、精神不集中、不發言,會影響效果。

寫這篇文章,希望本文中的一些建議能夠緩解上述問題,能使新人更快的瞭解CodeReview的意義和方法,有經驗的人能夠更加快速有效的進行CodeReview。

CodeReview的目標和原則

CodeReview的目的提升代碼質量,儘早發現潛在缺陷與BUG降低修復成本,同時促進團隊內部知識共享,幫助更多人更好地理解系統。建議CodeReview的原則如下:

  • 發現代碼的正確性

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

  • 不僅是在Review Code,更是在分享和學習

    Code Review最重要的是講解者分享業務流程和設計思路,參與者通過這些講解獲得這些信息,使得更多人理解這個系統,提升團隊整體水平,使得團隊維護代碼的能力提升。

  • 高效迅速完成CodeReview

    我們不能爲了應付匆匆忙忙的進行一次代碼審查,效率也是很重要的,如果不能保證Code Review目的實現,那麼評審便是徒勞的。

如何高效完成CodeReview?

參與者要檢查設計的合理性以及業務邏輯是否錯誤,檢查代碼可讀性;講解者要想辦法分享設計、技術、經驗等知識。

1.檢查設計的合理性和業務邏輯的正確性:

  • 代碼的設計是否符合設計要求:

    • 如果存在代碼和設計有出入的地方需要問詢爲什麼要變動,因爲這些變動有可能是出於開發者在真正設計代碼時候的深入考慮,或者是由於一時大意出現偏差。

  • 業務邏輯是否正確:

    • 業務流程是否按照詳細設計的流程走,不要出現原本是先A流程後B流程而設計的時候出現先B後A,或者丟失流程。

    • 某些傳入參數是否合理:判斷某些接口的參數輸入是否是冗餘的,比如輸入A字段可以滿足A接口裏面的所有操作,那麼多輸入一個B就冗餘的。

    • 數據庫字段的設計,數據庫的設計是對實際業務的映射,我們要保證每一個字段的出現都反應實際業務並且經過合理性的驗證,比如設計table1的時候A字段在table2中已經出現,並且A和B表有相應的關聯,那麼要注意A字段對於table1的冗餘是否有合理性,如果沒有合理的說服性可以去掉A,而節省對 A字段的維護成本(存儲空間,更新操作等)。

    • 某些判斷是否合理,比如某些參數的輸入金額是否可以爲0的判斷等等。

    • 系統交互是否合理,比如在代碼設計的時候沒有關注考慮系統交互的順序而造成有些信息不能獲取到;比如獲取支付方式的費率信息必須要等待支付的時候才能拿到,那麼獲取這些信息就應該放在pay_trans的時候而不是create_trans,大多數這種問題其實都是詳細設計時出現的,代碼評審階段比較少見。

    • 是否有異常處理機制,一個好的代碼設計應該考慮各種異常並對相應的異常做出合理的處理,比如接口的可重入,當代碼檢測到有重入的這種情況,怎樣去做這種異常處理使得調用方能捕捉的這些異常而進行後面的處理。

  • 關注業務可拓展性:

    • 我們的業務在不斷的發展,每一個項目設計都會影響後續業務的拓展,一個好的設計應該考慮到後續業務的發展,而儘量避免定製化的設計。

  • 關注使用到的數據結構、設計模式和代碼性能:

    • 一個好的數據結構和設計模式可以增加代碼的可維護性安全性和效率等,比如我們在設計的時候要考慮到不同的場景選擇什麼樣的數據結構,有時候我們會糾結於用map還是用hash_map,這時候我們要根據具體的情況具體分析;

    • 當我們設計代碼的時候如果能用上系統提供的函數那麼最好不要自己去寫,比如自己實現一個鏈表的時候是否可以想到用系統庫提供的list_head以確保鏈表結構的正確性;

    • 某些設計如果能套用設計模式會讓設計更加美觀也讓閱讀者更加明瞭;出於對系統性能的考量,我們要關注編寫代碼對系統的開銷,包括使用的算法是否合理,以及對某些比較耗時的操作比如數據庫的操作要加以關注。

2.檢查檢查代碼可讀性和可維護性:

  • 如果代碼的可讀性強,那麼維護起來也就方便很多;一個好的代碼規範和編碼風格會節省大家對代碼的理解時間,減少維護成本;雖然我們有編程規範檢查工具,但有些內容檢查不出來,是需要靠大家去規範的。

  • 關注代碼註釋:我們在編寫函數和進行邏輯判斷的時候最好要標註一下這個函數或者這段判斷是用來做什麼的;做了這種註釋的好處,一來當別人閱讀這段代碼的時候看到你的註釋以後就會根據你的思路快速理解代碼,甚至不閱讀直接跳過;二來防止自己由於長時間不閱讀代碼而忘記這段代碼的用途。

  • 關注命名規範:雖然我們有自己的編碼規範,但是這種規範只是限制了使用駝峯命名法還是其他命名法;而好的命名風格應該是看到變量或者函數名字就能“望文生義”,畢竟我們不能把自己寫的所有代碼都做註釋。

  • 關注重複代碼:如果出現大量的重複性代碼,要考慮將這些代碼抽象出公用函數,以減少代碼量並增強代碼可讀性。

  • 關注繁瑣的邏輯:如果一個簡單的功能卻對應大篇幅的代碼,要考慮一下是不是有比較簡單的實現方式,因爲過於複雜的代碼會給後來者的維護帶來麻煩;如果沒有簡略的辦法,一定要把註釋寫好。

3. 分享設計、技術、知識和經驗

  • 在代碼審查的過程中,大家往往把關注點放在發現代碼的不足上,忽略了代碼評審過程中的設計思想、技術方法、業務知識的傳播,我覺得這些內容也是非常重要的,也需要同時關注。

  • 評審者在自己的代碼時會深入業務流程,參與這可以看到評審代碼的一些算法、數據結構、設計模式甚至是系統架構等知識以及評審者在編碼過程中踩過的坑;通過這些信息參與者可以提升自己的業務水平和技術能力使得整個團隊的水平得到提高。

  • 參與者除了要有這種學習意識外,評審者也要想辦法讓參與者更加快速高效的去理解代碼中傳播的知識,這樣能幫助提升Review速度,所以建議評審者能簡單介紹一下項目的背景以及詳細設計,這些信息的介紹有以下好處:

    • 首先,代碼的設計是按照詳細設計來執行的,但是設計者在真正code的時候會出現一些變動,這些變動要給大家一個同步;

    • 其次,參與過詳細設計的人可能由於沒有直接參與的code,時間長會忘記之前詳細設計的流程,簡單介紹之後就會讓參與者想起,方便參與者的理解;

    • 第三,對於沒參與詳細設計的同學,在簡單介紹過這些信息後,可以有個大致瞭解,不然整個評審過程會很煎熬;

    • 所以,如果參與者對代碼的信息不理解,會造成參與者理解代碼的難度,也就不能提出有建設性的意見,同時也難以學到評審中傳播的知識;這一點在之前的評審中是比較容易被大家忽略的,尤其是在跨團隊代碼評審時,準備不足和經驗不足的同學是很難理解對方在講什麼的。

  • 講解code的時候最好是以接口功能爲單位去講解

    • 如果評審者一下子把所有的詳細設計都講解完,可能會因爲信息量比較大,或者設計到一些細節問題,參與者不能有效的記住或理解也會影響評審的速度和效率;

    • 評審者可以在講解的過程中分享一下自己踩過的坑,參與者可以隨時根據自己發現的問題進行討論

如何迅速完成CodeReview?

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

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

  • 有些代碼的邏輯是比較複雜的,如果是很容易就發現的缺陷,大多數情況下評審者自己在編碼過程就會發現,那麼剩下不容易發現的缺陷要發現也會花費較多的時間,這些問題可以交給測試人員去發現;

  • 如果參與者刻意去找bug會造成顧此失彼,忽略更重要的東西;當然,有些bug你可能一眼就看出來了,那提出來就再好不過了。

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

  • 有些人參與者比較自信,對自己寫得代碼感覺很滿意,所以有時候就會根據自己熟悉的編碼語言或者編碼風格去評論別人的代碼;

  • 作爲參與者,只要覺得評審者的代碼符合命名要求和設計要求就可以了,但假如評審者的代碼缺陷很明顯,可以提出帶大家進行討論。

3.不要帶着抨擊和質疑別人能力的心態去進行代碼評審

  • 有時候參與者可能心情不好,或者感覺對方是新人就忍不住會抨擊對方的代碼,這樣會比較容易在模棱兩可的問題上浪費時間;

  • 參與者可能認爲A方法好,評審者可能認爲B方法也不壞,這樣就會造成沒有必要的爭論而浪費時間。

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

  • 大家在討論的時候如果某些問題討論一段時間以後仍然沒有結論,或者需要第三方確認或者評審者不能馬上理解參與者提出的意見時,不要花太多時間討論這些問題;

  • 把這些問題先記錄下來,等會議結束後評審者可以與參與者進行線下討論,同時將這些問題根據自己的理解進行解決,之後給大家一個反饋即可,這樣可以節省很多時間。

5.不要聽不進別人的意見

  • 有些評審者比較固執,不願意接受大家的意見,會造成一些不必要的爭端和討論,浪費時間;

  • 當然,有時候參與者的意見不見得是最好的,作爲評審者將其作爲一個參照的方向和視角,如果存在爭論,這些建議也可以做成會議記錄,評審者私下和建議提出者討論以後給大家一個結論。

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

  • 如果參與者自己沒有想明白的事情就去提意見,那麼評審者反問的時候會浪費大家的時間;

  • 參與者可以先將自己的想法大致記下來,自己想清楚了之後再提給評審者也是節省時間的辦法。

總結

綜上,給大家介紹了一些如何進行高效迅速的CodeReview一些思考方向,這些方式是否適用還需要大家在實踐過程中進行驗證,也需要根據不同團隊的實際情況做相應的調整,我們最終的目的是希望CoderReview能夠有效而迅速,一方面提升代碼質量本身,另一方面也可以創造一個良好的學習氛圍互相支持提升團隊的整體代碼水平。本文是結合自己和他人經驗的總結,內容不一定完整,觀點也只是代表個人,希望給大家有些啓發和幫助,大家有更好的經驗可留言反饋給我們。

參考資料

  • 谷歌是如何做代碼審查的:http://www.vaikan.com/things-everyone-should-do-code-review/

  • Code Review中的幾個提示:http://coolshell.cn/articles/1302.html

  • 敏捷開發中的Code Review的目的及內容:http://www.chinatesting.cn/281/12667781.shtml


作者:張宏宇,百度錢包支付發展部研發工程師

發佈了50 篇原創文章 · 獲贊 48 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章