分(fēn)享到:

Airbnb 資深工(gōng)程師(shī)分(fēn)享:怎樣才是正确、有效的 code review

日(rì)期:2017-01-13 21:02:00     閱讀(dú):282     文章(zhāng)來(lái)源:源美網絡     标簽:深圳網站(zhàn)建設,深圳網站(zhàn)設計(jì)

當開始與其他(tā)工(gōng)程師(shī)合作(zuò)項目時 code review 就(jiù)變成了必做的功課之一,然而許多工(gōng)程師(shī)大(dà)多走馬看(kàn)花地浏覽過,不然就(jiù)是大(dà)刀闊斧地把自(zì)己不順眼的地方大(dà)修特修。


而本文作(zuò)者朱赟,現爲美國(guó)矽谷 Airbnb 的資深工(gōng)程師(shī),向大(dà)家介紹了幾個 code review 時應該注意的細節與架構。我認爲不管對初出茅廬,或是身(shēn)經百戰的工(gōng)程師(shī)都(dōu)有非常值得(de)一看(kàn)的價值。

之前寫過一篇《寫代碼的四個境界》,那個時候,大(dà)部分(fēn)時候我還(hái)是愉快(kuài)地寫着自(zì)己的代碼。Code review 也是每天工(gōng)作(zuò)的一部分(fēn),但(dàn)是相(xiàng)對而言花的時間還(hái)是有限的。


最近一是因爲角色轉換,二是突然來(lái)了很多新人(rén)。花在 code review 上的時間比寫代碼多出了好多,也有一些心得(de)和感觸,随便寫寫吧(ba)。


總的說(shuō)來(lái),矽谷稍具規模的公司 code review 的流程都(dōu)是比較規範的。模式也差不多。一來(lái)所有的 PR(見(jiàn)下批注)都(dōu)必須有至少一個人(rén) stamp,才能 merge。如(rú)果改的東西涉及到多個項目,則需要每個項目都(dōu)有人(rén) stamp 才行。還(hái)有一些特别關鍵的代碼,比如(rú)支付相(xiàng)關的,通常也會需要支付組的人(rén) stamp 才行。


NOTE: PR (pull request, a set of changes someone tries to push to a GitHub repository. Once a PR is sent, interested parties (peer engineers) can review the set of changes, discuss potential modifications, and even push follow-up commits if necessary.

在 stamp 前,通常是 github page 上可(kě)以給出各種 comments,page 是共享的,所以誰都(dōu)能看(kàn)到。有些 comments 是詢問(wèn),那麽代碼作(zuò)者直接回複或解釋就(jiù)行。有些 comments 是指出代碼的問(wèn)題,這樣代碼作(zuò)者可(kě)能會依此改動;也可(kě)能不同意,那就(jiù)回複 comments,有的時候關于一個實現細節,討(tǎo)論的 comments thread 可(kě)以多達十幾條。這樣對于大(dà)家達成共識很有幫助。


以前遇到有朋友說(shuō):


「看(kàn)到代碼寫的太爛,覺得(de)來(lái)回扯皮效率不高,幹脆撲上去(qù)自(zì)己寫。」


曾經我也有過類似的想法。不過最近遇到的一些事(shì)讓我慢(màn)慢(màn)地意識到這種想法很要不得(de)。


首先就(jiù)是從(cóng)對方的角度來(lái)說(shuō)。對方寫不好,可(kě)能是對業務不熟悉,可(kě)能是對語言不熟悉,也可(kě)能是對公司代碼的大(dà)架構不熟悉。如(rú)果你(nǐ)是幫他(tā)/她「寫」而不是耐心指出哪裡(lǐ)有問(wèn)題,那麽下一次,他(tā)/她可(kě)能還(hái)是不知道。不僅無益于别的人(rén)成長,有的時候甚至會讓别人(rén)有挫敗感。


再然後就(jiù)是這種方式的可(kě)擴展性很差。即使 code review 會花掉哪怕十倍于你(nǐ)自(zì)己寫的時間和精力,但(dàn)它會讓人(rén)明白(bái)代碼應該怎麽寫,從(cóng)長遠(yuǎn)來(lái)看(kàn),這其實是在一定程度上「複制」你(nǐ)的生(shēng)産力。你(nǐ)不能什麽都(dōu)自(zì)己寫。尤其是你(nǐ)慢(màn)慢(màn)開始帶項目、帶新人(rén)。每天 review 五個人(rén)的代碼,和寫五個人(rén)的代碼,你(nǐ)覺得(de)長期而言哪個更合算?


此外,如(rú)果說(shuō)寫代碼是一個學習過程,怎麽做一個好的代碼審核人(rén)更是一個學習和成長的過程。自(zì)己繞過一個坑不難,難的是看(kàn)到别人(rén)那麽走,遠(yuǎn)遠(yuǎn)地你(nǐ)就(jiù)能告訴他(tā)/她那裡(lǐ)有個坑。而他(tā)/她在經你(nǐ)指出多次後,下一次他(tā)/她也會幫着指出别人(rén)的類似的問(wèn)題。


這一點最近感觸尤爲深刻。前一陣組裡(lǐ)咔咔咔接二連三來(lái)了好多新人(rén),老大(dà)說(shuō),你(nǐ)少寫點代碼,多做點 review。于是那幾天我幾乎工(gōng)作(zuò)的一半時間都(dōu)用來(lái)看(kàn)代碼,寫 comments。可(kě)是最近就(jiù)會發現,他(tā)/她們相(xiàng)互之間大(dà)部分(fēn)時候已經可(kě)以很好的相(xiàng)互 review 了,于是我又騰出好一些時間來(lái)做别的工(gōng)作(zuò)。


Code review 做多了,發現其實也是有一定套路(lù)的,試着歸納如(rú)下:


代碼格式方面

很多公司都(dōu)有 coding style guideline。大(dà)家的約定俗成,避免公司的代碼風(fēng)格不一緻,也避免一些不不要的爲了「要不要把閉括号另起一行」而無謂地争論,除非是不小心,通常大(dà)家都(dōu)不會弄錯。但(dàn)是新員(yuán)工(gōng)往往會在這方面還(hái)不太熟悉。這一類問(wèn)題也比較容易指出。


代碼可(kě)讀(dú)性方面

這包括一個函數不要太長,太長就(jiù) break down。所有的變量名盡量能夠說(shuō)明它的用意和類型。比如(rú) hosting_address_hash,一看(kàn)就(jiù)知道是房(fáng)東地址,而且是個 hash 類型。不要有嵌套太多層的條件(jiàn)語句或者循環語句。不要有一個太長的 boolean 判斷語句。如(rú)果一個函數,别人(rén)需要看(kàn)你(nǐ)的長篇注釋才能明白(bái),那這個函數就(jiù)一定有重構的空間。另外,如(rú)果不可(kě)避免有一些注釋,則一定要保證注釋準确且與代碼完全一緻。


幫代碼作(zuò)者想想他(tā)/她有沒有漏掉任何 corner case

很多時候這是業務邏輯相(xiàng)關的,尤其需要比較老的工(gōng)程師(shī)幫助指出需要處理(lǐ)的所有情況。


Error handling

這是最常見(jiàn)也是代碼審核最容易幫别人(rén)看(kàn)出的問(wèn)題。舉個例子,下面一段簡單到不能再簡單的代碼就(jiù)至少有三個潛在的問(wèn)題:params 裡(lǐ)面需要 validate 是不是有 user_id 和 new_name 這兩個 key;能不能找到這個 user_id 對應的 user;save 的時候會不會有 DB level 的 exception,應該怎麽處理(lǐ)。

測試例和防坑

測試例不用說(shuō)了,每段代碼都(dōu)應該有測試例。但(dàn)是對于一些你(nǐ)能預見(jiàn)如(rú)果别人(rén)改動代碼會引起可(kě)能問(wèn)題的情況,一定要額外的加測試例防止這種事(shì)情的發生(shēng)。這一點沒有例子參考也不太好說(shuō)。怎麽寫好測試例,本身(shēn)就(jiù)值得(de)寫一篇文章(zhāng)了。


小架構

什麽意思呢(ne),就(jiù)是一個文件(jiàn)或者類内部的代碼組織。比如(rú)如(rú)果有重複的代碼段,就(jiù)應該提取出來(lái)公用。不要在代碼裡(lǐ)随意設常數,所有的常數都(dōu)應該文件(jiàn)頂部統一定義。哪些應該是 private,等等


大(dà)架構

這個就(jiù)更廣了。包括文件(jiàn)組織,函數是不是應該抽像到 lib 或者 helper 文件(jiàn)裡(lǐ);是不是應該使用繼承類;是不是和整個代碼庫的風(fēng)格一緻,等等。


當然,視具體(tǐ)情況可(kě)能還(hái)有很多别的需要在 code review 中注意的。但(dàn)是如(rú)果按照(zhào)這個 checklist 過一遍,一些明顯的問(wèn)題就(jiù)可(kě)以避免個八九不離(lí)十了。


另外,代碼 review 和寫代碼是我們每個工(gōng)程師(shī)都(dōu)應該緻力的兩個方面,缺一不可(kě)。可(kě)能在工(gōng)作(zuò)中的某個階段或者某個項目裡(lǐ),你(nǐ)會花更多的時間在某一面,但(dàn)長久看(kàn)來(lái),兩個技能缺一不可(kě)。


代碼審核是工(gōng)作(zuò),不要抱有情緒化

我曾經幹過一件(jiàn)事(shì),一個外組同事(shì)的代碼,别人(rén)已經 stamp 了,可(kě)是我覺得(de)有問(wèn)題,于是把 stamp revert 掉了,在 comments 裡(lǐ)寫了爲什麽有問(wèn)題,和建議(yì)的改法。當時心裡(lǐ)還(hái)有點覺得(de)好像怪得(de)罪人(rén)的。可(kě)是後來(lái)發現同事(shì)反而很客氣地接受并道謝了。心裡(lǐ)也是很感激有這樣的工(gōng)作(zuò)環境。


另外,經常會遇到有些 review 的 comments 裡(lǐ)出現不同意見(jiàn),其實是兩個人(rén)在編程習慣和約定俗成上沒有共識。如(rú)果在不違背公司 style guideline 的情況下,沒必要一定讓對方和你(nǐ)有一樣的習慣。如(rú)果你(nǐ)真的覺得(de)這樣更好,通常我也隻會寫「I personally would prefer A over B, but no strong opinion.」或者「How about change it to A, since … However, this is not a merge blocker. 」


人(rén)都(dōu)有不周到的時候。多幾雙眼睛一起幫你(nǐ)看(kàn)一遍,就(jiù)可(kě)以很大(dà)程度地減少代碼裡(lǐ)的錯誤。另外,相(xiàng)互 review 的過程中還(hái)能從(cóng)彼此那裡(lǐ)學到很多編程的小技巧和好習慣。細想來(lái),很多 Java 和 Ruby 的特别好用的 feature,我都(dōu)是在 code review 的過程中學到的。



文章(zhāng)引用:

本站(zhàn)文章(zhāng)爲深圳網站(zhàn)建設·源美網絡原創策劃,如(rú)有版權糾紛或者違規問(wèn)題,請(qǐng)聯系我們删除,謝謝!

上一篇: 支付寶回應安全漏洞

下一篇: 回顧2016年(nián)最紅(hóng)開發程序語言

返回列表
最新案例
OUR ADVANTAGE WORKS

售後保障

承諾任何問(wèn)題1小時内解決

數據備份

更安全、更高效、更穩定

價格公道精準

項目經理(lǐ)精準報價不弄虛作(zuò)假

合作(zuò)無風(fēng)險

重合同講信譽,無效全額退款