1.1 為什么重視Code Review?
結(jié)合下面這個例子,我們來談?wù)劄槭裁匆匾昪ode review。假設(shè)你作為新人剛?cè)肼?,領(lǐng)導(dǎo)分配了一個需求,于是接下來做了下面這些事:
為了完成任務(wù)瘋狂敲了三天代碼
你將一個包含大約 800行新代碼的commit提交MR
收到兩條關(guān)于代碼風(fēng)格的意見,以及一個對某塊代碼不是很理解的疑問
修復(fù)了代碼風(fēng)格問題并回答了reviewer的問題,接著reviewer通過了你寫的代碼
把代碼分支合并到 Master,自動化測試完成,沒有異常發(fā)生
此后 幾個月,你一直戰(zhàn)戰(zhàn)兢兢,不知道代碼何時會crash,以及以什么方式crash…….
聽完這個例子我們是不是有共鳴呢?也許這就是發(fā)生在我們身邊的真實例子。我們將code review的作用歸納為以下幾個方面:
給編碼者帶來良性的社交壓力。你正寫一個比較緊急的需求,團(tuán)隊對代碼的單元測試有一個要求:凡是新增的代碼,必須有完整的單元測試以及需要達(dá)到一定覆蓋率。此時你是否會有這樣的想法,為了應(yīng)付測試工具的覆蓋率要求,先寫一點不那么有用但是能帶來覆蓋率的測試。但是,一旦想到你的代碼將會有你的同事參與review,有沒有為剛才的這種想法產(chǎn)生一絲絲壓力?這種壓力是良性的,會阻止你去選擇這些隱患很大的“投機(jī)”行為。
提高代碼質(zhì)量和可維護(hù)性。通過review發(fā)現(xiàn)缺陷,統(tǒng)一代碼規(guī)范,功能模塊化等保障代碼質(zhì)量和可維護(hù)性。
查缺補(bǔ)漏,發(fā)現(xiàn)一些潛在的問題。比如性能是否存在瓶頸,平臺兼容性,錯誤異常處理。
知識分享,review他人代碼其實也是一個學(xué)習(xí)的過程,自己可以從中學(xué)習(xí)別人的優(yōu)點,反思自己平常開發(fā)過程中的不足。
對需求的double-check,與開發(fā)前的方案評審形成閉環(huán)。
讓別人易看懂,讓代碼可以傳承。

上圖是出自applied software measurement這本書,圖中有三條曲線。橫坐標(biāo)代表軟件開發(fā)的5個階段:編碼,單測,功能測試,線上環(huán)境模擬測試,線上發(fā)布。縱坐標(biāo)表示缺陷百分比。綠線表示缺陷產(chǎn)生在各階段的分布,黃線表示各階段發(fā)現(xiàn)缺陷的數(shù)量分布,紅線表示修復(fù)缺陷在不同階段需要的成本。我們可以從圖中得到以下結(jié)論:大多數(shù)缺陷是在編碼過程中產(chǎn)生,在測試中被發(fā)現(xiàn)和修復(fù),隨著功能的測試上線,修復(fù)缺陷的成本也成指數(shù)級增長。因此code review作為測試后上線前的階段,發(fā)現(xiàn)缺陷和解決缺陷也變得尤為關(guān)鍵,有效避免缺陷留到線上造成巨大損失。
1.2 Code Review存在哪些通用性難點?
在了解了code review及其重要性后,接下來我們分析下code review的難點:
review代碼本身并不困難,但是需要耗費不少時間和精力去了解項目背景,需求背景,方案設(shè)計,甚至還需要了解關(guān)聯(lián)模塊的相關(guān)信息。除了讀懂代碼,還需要找到代碼中測試沒有發(fā)現(xiàn)的潛在的問題,這對reviewer的專業(yè)素養(yǎng)有較高要求。
review一般要求盡快完成,避免持續(xù)太長時間因為雙方記憶的遺忘造成review效率降低。假如此時你很忙,code review的工作在一定程度上會造成很大的負(fù)擔(dān)。
雖然我們提倡盡量不要出現(xiàn)大的代碼量提交MR,但是也不能犧牲功能的完整性。假如你一下子收到了幾千行需要被review的MR。是不是感覺很崩潰?
1.3 TDSQL-C是什么?
隨著互聯(lián)網(wǎng)的發(fā)展,各種業(yè)務(wù)數(shù)據(jù)快速膨脹,用戶對數(shù)據(jù)庫計算和存儲能力的需求日益增長。在應(yīng)對業(yè)務(wù)需求持續(xù)增長時,傳統(tǒng)數(shù)據(jù)庫的迭代和優(yōu)化已經(jīng)變得舉步維艱,而分布式架構(gòu)的優(yōu)勢則愈發(fā)明顯。借助計算存儲分離的架構(gòu),新硬件優(yōu)勢,物理復(fù)制特點,分布式系統(tǒng)優(yōu)勢,云原生數(shù)據(jù)庫?TDSQL-C對比傳統(tǒng)MySQL具有高性能,低成本,大存儲,主從復(fù)制延遲低,秒級擴(kuò)縮容,極速回檔,serverless化等優(yōu)勢。

前面講了TDSQL-C相對傳統(tǒng)數(shù)據(jù)庫的優(yōu)勢,那么接下來講講code review在TDSQL-C存在哪些難點?從下面的對比圖可以看出,傳統(tǒng)MySQL的數(shù)據(jù),邏輯日志,物理日志,元數(shù)據(jù)都是存在本地盤,主從管理各自的數(shù)據(jù),通過邏輯日志進(jìn)行主從同步。TDSQL-C分為計算層和存儲層,本地不再存儲任何數(shù)據(jù),共享存儲層數(shù)據(jù),主從通過物理日志進(jìn)行同步,存儲層通過接受主庫發(fā)送的物理日志進(jìn)行回放生成數(shù)據(jù)及元數(shù)據(jù),不再需要邏輯日志。架構(gòu)的巨大改變帶來了以下問題:
TDSQL-C基于開源MySQL(系統(tǒng)復(fù)雜,項目總代碼數(shù)百萬級別),重構(gòu)了日志系統(tǒng),IO模塊,事務(wù)模塊,啟動流程等多個模塊,代碼改動量巨大
TDSQL-C項目包括計算層,存儲層,分布式文件系統(tǒng),管控,運維等,參與人數(shù)眾多,代碼改動牽一發(fā)動全身
復(fù)雜的系統(tǒng)對研發(fā),測試,code review都提出了極高要求

1.4? TDSQL-C Code Review流程
作為一個比較大的項目團(tuán)隊,經(jīng)歷多年的發(fā)展和優(yōu)化,我們形成了目前的研發(fā)流程:
基于master分支創(chuàng)建屬于自己的分支;
在自己的分支上進(jìn)行開發(fā);(開發(fā)之前要記錄詳細(xì)的設(shè)計方案,郵件的方式發(fā)送所有相關(guān)人及相關(guān)領(lǐng)導(dǎo))
進(jìn)行單元測試,性能測試,長穩(wěn)測試,使用valgrind工具進(jìn)行缺陷檢查
上述測試通過后提交MR,自動觸發(fā)單測,靜態(tài)缺陷檢測,生成覆蓋率報告
全量覆蓋率和增量覆蓋率均需要達(dá)到90%以上才合格。
通知reviewer進(jìn)行code review,并提供issue單,設(shè)計文檔和測試數(shù)據(jù),author和reviewer進(jìn)行接下來的code review
code review通過后合入master分支
出包,正式提測
1.5? ? 在這個過程中,對author和reviewer有不同的要求:
對author的要求
每次提交code review的代碼量要少
以文檔或其它方式向reviewer介紹修改了哪些文件,增加了什么樣的功能
對reviewer的要求
把程序跑起來,調(diào)試一下是否符合預(yù)期
盡可能及時的進(jìn)行 code review
在你讀代碼之前,先想想自己會怎么做

Code Review主要參照以下幾個方面進(jìn)行:
代碼書寫規(guī)范,是否遵照代碼規(guī)范進(jìn)行書寫
代碼實現(xiàn)與需求文檔是否一致:核對需求單
算法優(yōu)化,思考最佳實現(xiàn)方法:if else的八二法則等
細(xì)節(jié)把控:內(nèi)存釋放問題,錯誤處理
注釋是否合理
單元測試是否完善
代碼提交commit規(guī)范
寫好commit log很重要,它可以幫助我們快速了解這段代碼的很多信息。為了從commit log中獲取足夠多的信息,我們對commit log有嚴(yán)格要求,每一個commit需要包括完整的信息:
類別:bug修復(fù)還是功能開發(fā)
Issue:本地提交對應(yīng)的issue
主題:本次commit的概述
Problem:要解決什么問題
Solution:解決方法是什么
MR:MR編號是多少
Reviewer:記錄reviewer同學(xué)

1.6 TDSQL-C CodeReview規(guī)范優(yōu)化
前面介紹完了TDSQL-C的code review流程,接下來講一下我們TDSQL-C在多年的code review實踐中做的一些改進(jìn)。
?Code Review 的呈現(xiàn)形式
過去我們在評論里直接寫上自己的意見,有時候給author沒有傳遞準(zhǔn)確的信息。
后來對Review的評論進(jìn)行分級,不同級別打上不同的Tag:
[blocker]:代碼行的問題必須要修改
[optional]:代碼行的問題可改可不改
[question]:對代碼行不理解,有問題需要問,author需要針對問題進(jìn)行回復(fù)澄清
定期復(fù)盤
過去開發(fā)和線上穩(wěn)定性維護(hù)的同學(xué)各司其職,缺乏有效反饋機(jī)制幫助開發(fā)人員了解線上會出現(xiàn)的一些通用性問題。
目前團(tuán)隊每周進(jìn)行一次線上穩(wěn)定性分析會,主要針對目前線上遇到的問題,討論解決辦法及后期如何避免,經(jīng)驗豐富的reviewer可以借助這些經(jīng)驗幫助author找到一些設(shè)計上,甚至是用戶使用上可能觸發(fā)的異常情況。
Code Review是一種開發(fā)文化而不是制度
Code review 的執(zhí)行,很大程度上依賴于reviewer的認(rèn)真審查,以及author的積極配合。過去往往流于形式,審查不夠嚴(yán)格。
后來Code Review變成團(tuán)隊的一種文化,開發(fā)人員從心底接受并認(rèn)真執(zhí)行:
讓開發(fā)人員認(rèn)識到Code Review這件事為自己、為團(tuán)隊帶來的好處
團(tuán)隊負(fù)責(zé)人及資深工程師帶頭做好表率作用
把code review作為開發(fā)任務(wù)的一部分,給author和reviewer都留出時間
進(jìn)行模塊owner劃分,每個子模塊由資深工程師把關(guān),提升效率
代碼合入master時需要注明reviewer,author和reviewer對代碼承擔(dān)同等責(zé)任
團(tuán)隊定期組織topic share,加強(qiáng)技術(shù)分享
注意: