審開(kāi)放化實(shí)踐:流程設(shè)計(jì)、自動(dòng)化檢查與閉環(huán)管理)
1. 從標(biāo)題說(shuō)起open-code-review 到底在解決什么問(wèn)題第一次看到 open-code-review 這個(gè)標(biāo)題我的直覺(jué)是這大概率是一個(gè)圍繞代碼評(píng)審環(huán)節(jié)做開(kāi)放化、自動(dòng)化或流程化改造的項(xiàng)目。代碼評(píng)審這件事做過(guò)團(tuán)隊(duì)協(xié)作的人都不陌生——它既是保證代碼質(zhì)量的關(guān)鍵閘門(mén)也是最容易變成走過(guò)場(chǎng)、拖進(jìn)度、傷和氣的環(huán)節(jié)。傳統(tǒng)做法無(wú)非是提交合并請(qǐng)求指定一兩個(gè)同事來(lái)看評(píng)論區(qū)來(lái)回幾輪最后要么草草通過(guò)要么卡在某個(gè)細(xì)節(jié)上僵持不下。open-code-review 這個(gè)命名里open 是核心詞。它可以指開(kāi)放式的評(píng)審流程也可以指開(kāi)放給更多人參與的評(píng)審機(jī)制還可以指評(píng)審規(guī)則、評(píng)審記錄、評(píng)審工具鏈的開(kāi)放透明。結(jié)合常見(jiàn)的工程實(shí)踐我傾向于把它理解為一套讓代碼評(píng)審不再依賴(lài)單點(diǎn)人工、不再黑盒化、不再靠人情推動(dòng)的機(jī)制或工具集合。它要解決的問(wèn)題很具體評(píng)審標(biāo)準(zhǔn)不統(tǒng)一、評(píng)審意見(jiàn)難追溯、評(píng)審效率隨團(tuán)隊(duì)規(guī)模下降、新人不知道該怎么審、老人審得疲憊。這篇文章適合誰(shuí)看如果你是團(tuán)隊(duì)里負(fù)責(zé)代碼質(zhì)量的那個(gè)人或者你正在搭建研發(fā)流程規(guī)范又或者你只是想讓自己的提交少被反復(fù)打回那這篇內(nèi)容都能給你一些可以直接抄作業(yè)的思路。我會(huì)從整體設(shè)計(jì)、核心細(xì)節(jié)、實(shí)操流程、常見(jiàn)坑四個(gè)層面展開(kāi)盡量把每個(gè)選擇背后的為什么講清楚而不是只丟一堆結(jié)論。2. 整體設(shè)計(jì)與思路拆解為什么這樣搭而不是那樣搭2.1 評(píng)審流程的三種常見(jiàn)形態(tài)與取舍邏輯在動(dòng)手設(shè)計(jì)任何代碼評(píng)審機(jī)制之前先要搞清楚你面對(duì)的是哪種協(xié)作場(chǎng)景。我見(jiàn)過(guò)的大多數(shù)團(tuán)隊(duì)評(píng)審流程基本落在三種形態(tài)里第一種是集中式評(píng)審所有提交必須經(jīng)過(guò)一個(gè)固定角色或固定小組第二種是分布式評(píng)審提交者指定若干相關(guān)同事誰(shuí)有空誰(shuí)看第三種是開(kāi)放式評(píng)審不指定具體人任何有權(quán)限的人都可以參與按規(guī)則決定是否通過(guò)。open-code-review 這個(gè)標(biāo)題里的 open天然更貼近第三種形態(tài)。但開(kāi)放式評(píng)審有個(gè)致命問(wèn)題如果沒(méi)有人對(duì)結(jié)果負(fù)責(zé)評(píng)審就會(huì)變成無(wú)人認(rèn)領(lǐng)的公共事務(wù)。所以設(shè)計(jì)時(shí)的第一個(gè)關(guān)鍵取舍就是開(kāi)放參與但必須收斂決策。我的做法是評(píng)審意見(jiàn)對(duì)所有人開(kāi)放但合并決策權(quán)仍然綁定到明確的規(guī)則上比如至少兩名具備相應(yīng)模塊權(quán)限的評(píng)審者給出通過(guò)意見(jiàn)或者由自動(dòng)化檢查加一名人工評(píng)審共同決定。這個(gè)取舍背后的邏輯很簡(jiǎn)單開(kāi)放解決的是信息不對(duì)稱(chēng)和參與度問(wèn)題收斂解決的是責(zé)任歸屬和效率問(wèn)題。兩者缺一不可。只開(kāi)放不收斂評(píng)審會(huì)變成菜市場(chǎng)只收斂不開(kāi)放評(píng)審會(huì)變成瓶頸。2.2 自動(dòng)化檢查與人工評(píng)審的邊界劃分很多團(tuán)隊(duì)一上來(lái)就想把所有檢查都自動(dòng)化覺(jué)得機(jī)器比人靠譜。但實(shí)際做下來(lái)會(huì)發(fā)現(xiàn)自動(dòng)化能覆蓋的只是那些有明確規(guī)則、可量化、可重復(fù)判斷的問(wèn)題比如格式規(guī)范、靜態(tài)掃描出的潛在缺陷、單元測(cè)試覆蓋率、依賴(lài)版本沖突。而涉及設(shè)計(jì)合理性、命名語(yǔ)義、業(yè)務(wù)邏輯邊界、可維護(hù)性這些維度機(jī)器目前還給不出讓人信服的判斷。所以 open-code-review 的合理設(shè)計(jì)應(yīng)該是自動(dòng)化檢查作為前置門(mén)檻人工評(píng)審聚焦在機(jī)器不擅長(zhǎng)的領(lǐng)域。具體來(lái)說(shuō)提交進(jìn)入評(píng)審隊(duì)列之前先跑一輪自動(dòng)化檢查不通過(guò)的直接打回不占用人工評(píng)審時(shí)間。通過(guò)自動(dòng)化檢查之后再進(jìn)入人工評(píng)審環(huán)節(jié)評(píng)審者只需要關(guān)注設(shè)計(jì)、語(yǔ)義、邊界和長(zhǎng)期維護(hù)成本。這個(gè)邊界劃分帶來(lái)的收益非常直接人工評(píng)審的負(fù)擔(dān)下降評(píng)審者更愿意認(rèn)真看自動(dòng)化檢查的標(biāo)準(zhǔn)統(tǒng)一不會(huì)因?yàn)樵u(píng)審者心情好壞而波動(dòng)整個(gè)流程的吞吐量提升因?yàn)榇蟛糠值图?jí)問(wèn)題在機(jī)器環(huán)節(jié)就被攔住了。2.3 評(píng)審記錄的開(kāi)放與可追溯設(shè)計(jì)open-code-review 的另一個(gè)核心設(shè)計(jì)點(diǎn)是評(píng)審記錄的開(kāi)放與可追溯。傳統(tǒng)評(píng)審里意見(jiàn)散落在評(píng)論區(qū)、聊天記錄、郵件里過(guò)兩個(gè)月再想查當(dāng)時(shí)為什么這么改基本靠回憶。開(kāi)放評(píng)審要求每一條評(píng)審意見(jiàn)、每一次決策、每一個(gè)通過(guò)或拒絕的理由都要有結(jié)構(gòu)化的記錄并且能被后續(xù)檢索。我的做法是評(píng)審記錄至少包含這幾個(gè)字段提交標(biāo)識(shí)、評(píng)審參與者、評(píng)審意見(jiàn)類(lèi)型缺陷、建議、疑問(wèn)、通過(guò)、意見(jiàn)對(duì)應(yīng)的代碼位置、最終決策、決策時(shí)間。這些字段不需要多復(fù)雜但必須完整。有了這些記錄后續(xù)做質(zhì)量分析、復(fù)盤(pán)、新人培訓(xùn)都有據(jù)可依。注意評(píng)審記錄開(kāi)放不等于評(píng)審者個(gè)人信息完全公開(kāi)。涉及具體人的評(píng)價(jià)性?xún)?nèi)容建議只保留角色標(biāo)識(shí)避免把技術(shù)討論變成對(duì)人的評(píng)判。3. 核心細(xì)節(jié)解析與實(shí)操要點(diǎn)每個(gè)環(huán)節(jié)到底怎么做3.1 提交前的自檢清單設(shè)計(jì)開(kāi)放式評(píng)審最怕的是提交者把明顯沒(méi)準(zhǔn)備好的內(nèi)容丟進(jìn)來(lái)浪費(fèi)所有人的時(shí)間。所以提交前的自檢清單是第一個(gè)關(guān)鍵細(xì)節(jié)。這份清單不需要很長(zhǎng)但每一條都應(yīng)該是硬性要求而不是建議。我常用的清單包括本地自動(dòng)化檢查是否全部通過(guò)、變更范圍是否與描述一致、是否補(bǔ)充了必要的測(cè)試、是否更新了相關(guān)文檔、是否存在調(diào)試殘留代碼。這份清單的執(zhí)行方式有兩種一種是靠提交者自覺(jué)勾選另一種是集成到提交工具里強(qiáng)制校驗(yàn)。實(shí)測(cè)下來(lái)強(qiáng)制校驗(yàn)的效果遠(yuǎn)好于自覺(jué)勾選。因?yàn)槿嗽谮s進(jìn)度的時(shí)候自覺(jué)是最靠不住的東西。強(qiáng)制校驗(yàn)的做法也不復(fù)雜在提交入口加一個(gè)檢查腳本清單里的每一項(xiàng)對(duì)應(yīng)一個(gè)可自動(dòng)驗(yàn)證的條件不滿(mǎn)足就不允許進(jìn)入評(píng)審隊(duì)列。這里有個(gè)細(xì)節(jié)值得展開(kāi)變更范圍與描述一致這一條很多人覺(jué)得沒(méi)法自動(dòng)檢查。其實(shí)可以做一個(gè)粗略的校驗(yàn)比如統(tǒng)計(jì)變更涉及的文件數(shù)量和代碼行數(shù)如果超過(guò)描述里聲明的范圍太多就觸發(fā)提醒。這個(gè)提醒不是拒絕而是讓提交者確認(rèn)是否遺漏了描述更新。實(shí)測(cè)這個(gè)提醒能攔住不少順手改導(dǎo)致的意外變更。3.2 評(píng)審者的分配規(guī)則與輪轉(zhuǎn)機(jī)制開(kāi)放式評(píng)審不指定具體評(píng)審者但也不能完全隨機(jī)。我的經(jīng)驗(yàn)是按模塊歸屬加輪轉(zhuǎn)機(jī)制來(lái)分配。每個(gè)代碼模塊有一組具備評(píng)審權(quán)限的人提交進(jìn)入隊(duì)列后系統(tǒng)從這組人里按輪轉(zhuǎn)順序選取若干名評(píng)審者同時(shí)允許其他人自愿參與。輪轉(zhuǎn)機(jī)制的好處是負(fù)載均衡避免總是那幾個(gè)人在審。自愿參與的好處是讓有興趣的人能介入尤其是新加入的成員可以通過(guò)參與評(píng)審快速熟悉代碼。但自愿參與不能替代輪轉(zhuǎn)否則又會(huì)回到少數(shù)人扛大頭的老路。評(píng)審者數(shù)量怎么定我的建議是至少兩名最多不超過(guò)四名。少于兩名容易形成單點(diǎn)判斷多于四名意見(jiàn)協(xié)調(diào)成本上升評(píng)審周期拉長(zhǎng)。兩名評(píng)審者加自動(dòng)化檢查在大多數(shù)團(tuán)隊(duì)規(guī)模下是效率和質(zhì)量的平衡點(diǎn)。3.3 評(píng)審意見(jiàn)的結(jié)構(gòu)化表達(dá)規(guī)范評(píng)審意見(jiàn)如果只是隨便寫(xiě)幾句后續(xù)很難追溯也很難統(tǒng)計(jì)。所以 open-code-review 要求評(píng)審意見(jiàn)結(jié)構(gòu)化表達(dá)。具體來(lái)說(shuō)每條意見(jiàn)要標(biāo)明類(lèi)型、嚴(yán)重程度、對(duì)應(yīng)位置、具體描述、建議方案。類(lèi)型分為缺陷、建議、疑問(wèn)、通過(guò)四類(lèi)。嚴(yán)重程度分為阻塞、重要、一般、輕微四級(jí)。對(duì)應(yīng)位置精確到文件、行號(hào)或代碼塊。具體描述要說(shuō)清楚問(wèn)題是什么、為什么是問(wèn)題。建議方案可以給也可以不給但給了會(huì)大大加快后續(xù)處理速度。這套規(guī)范剛開(kāi)始執(zhí)行時(shí)大家會(huì)覺(jué)得麻煩。但堅(jiān)持一段時(shí)間后評(píng)審意見(jiàn)的質(zhì)量和可追溯性會(huì)有明顯提升。我自己的體會(huì)是結(jié)構(gòu)化表達(dá)倒逼評(píng)審者想清楚再寫(xiě)減少了模糊意見(jiàn)和情緒化表達(dá)。3.4 決策收斂規(guī)則與爭(zhēng)議處理開(kāi)放式評(píng)審的決策收斂規(guī)則必須提前定好不能等到出現(xiàn)爭(zhēng)議再臨時(shí)商量。我的做法是兩名評(píng)審者給出通過(guò)意見(jiàn)且沒(méi)有阻塞級(jí)意見(jiàn)即可合并。如果存在阻塞級(jí)意見(jiàn)提交者需要修改后重新進(jìn)入評(píng)審。如果評(píng)審者之間意見(jiàn)不一致引入第三方評(píng)審者或由模塊負(fù)責(zé)人裁決。爭(zhēng)議處理的關(guān)鍵是快不能拖。拖久了提交者失去耐心評(píng)審者失去關(guān)注最后往往草草了事。所以規(guī)則里要明確爭(zhēng)議處理的時(shí)限比如二十四小時(shí)內(nèi)必須給出裁決意見(jiàn)否則默認(rèn)按多數(shù)評(píng)審者意見(jiàn)執(zhí)行。提示爭(zhēng)議處理規(guī)則一定要在項(xiàng)目啟動(dòng)階段就寫(xiě)清楚并且讓所有參與者確認(rèn)。事后補(bǔ)規(guī)則說(shuō)服成本會(huì)高很多。4. 實(shí)操過(guò)程與核心環(huán)節(jié)實(shí)現(xiàn)從提交到合并的完整鏈路4.1 環(huán)境準(zhǔn)備與工具鏈搭建動(dòng)手之前先把工具鏈理清楚。open-code-review 不依賴(lài)某個(gè)特定平臺(tái)但需要幾個(gè)基礎(chǔ)能力版本控制、自動(dòng)化檢查執(zhí)行環(huán)境、評(píng)審記錄存儲(chǔ)、通知機(jī)制。版本控制用常見(jiàn)的分布式版本管理工具即可。自動(dòng)化檢查執(zhí)行環(huán)境可以是一臺(tái)持續(xù)集成服務(wù)器也可以是本地腳本加鉤子。評(píng)審記錄存儲(chǔ)可以用數(shù)據(jù)庫(kù)也可以用結(jié)構(gòu)化的文本文件。通知機(jī)制用郵件、即時(shí)通訊工具或站內(nèi)提醒都行。我的建議是初期不要追求大而全先把最小可用鏈路跑通。最小可用鏈路包括提交觸發(fā)自動(dòng)化檢查、檢查結(jié)果寫(xiě)入評(píng)審記錄、評(píng)審者收到通知、評(píng)審意見(jiàn)寫(xiě)入評(píng)審記錄、決策結(jié)果觸發(fā)合并或打回。這條鏈路跑通之后再逐步增加輪轉(zhuǎn)、統(tǒng)計(jì)、看板等功能。4.2 自動(dòng)化檢查腳本的編寫(xiě)與集成自動(dòng)化檢查腳本是整個(gè)流程的前置門(mén)檻寫(xiě)得好能省下大量人工評(píng)審時(shí)間。腳本內(nèi)容根據(jù)項(xiàng)目類(lèi)型不同會(huì)有差異但基本結(jié)構(gòu)類(lèi)似。下面是一個(gè)通用的檢查腳本框架用 Python 編寫(xiě)供參考。import subprocess import sys def run_check(name, command): result subprocess.run(command, shellTrue, capture_outputTrue, textTrue) if result.returncode ! 0: print(f[FAIL] {name}) print(result.stdout) print(result.stderr) return False print(f[PASS] {name}) return True def main(): checks [ (format, python -m black --check .), (lint, python -m flake8 .), (test, python -m pytest --covsrc --cov-fail-under80), (dependency, python -m pip check), ] all_pass True for name, command in checks: if not run_check(name, command): all_pass False if not all_pass: sys.exit(1) print(All checks passed.) if __name__ __main__: main()這個(gè)腳本的邏輯很直白依次執(zhí)行格式檢查、靜態(tài)掃描、測(cè)試與覆蓋率檢查、依賴(lài)一致性檢查任何一項(xiàng)不通過(guò)就整體失敗。集成方式是在提交入口加一個(gè)鉤子提交時(shí)自動(dòng)觸發(fā)這個(gè)腳本不通過(guò)就不允許進(jìn)入評(píng)審隊(duì)列。參數(shù)選擇上覆蓋率閾值我一般設(shè)在百分之八十。低于這個(gè)數(shù)測(cè)試覆蓋明顯不足高于這個(gè)數(shù)邊際收益下降維護(hù)成本上升。當(dāng)然具體閾值要根據(jù)項(xiàng)目階段調(diào)整新項(xiàng)目可以低一些核心模塊可以高一些。4.3 評(píng)審隊(duì)列的管理與優(yōu)先級(jí)排序評(píng)審隊(duì)列如果不管很容易變成一鍋粥緊急的提交被壓在后面不緊急的提交占著評(píng)審資源。所以隊(duì)列管理需要優(yōu)先級(jí)排序。我的做法是按三個(gè)維度打分業(yè)務(wù)影響范圍、變更緊急程度、變更復(fù)雜度。業(yè)務(wù)影響范圍大、緊急程度高、復(fù)雜度適中的提交優(yōu)先處理。打分不需要很精確粗略分級(jí)即可。比如業(yè)務(wù)影響范圍分大中小三級(jí)緊急程度分高中低三級(jí)復(fù)雜度分高中低三級(jí)。綜合得分高的排前面。這個(gè)排序規(guī)則要公開(kāi)讓提交者知道自己的提交大概什么時(shí)候會(huì)被處理減少焦慮和催促。隊(duì)列管理還有一個(gè)細(xì)節(jié)限制同時(shí)處于評(píng)審中的提交數(shù)量。我的經(jīng)驗(yàn)是同時(shí)評(píng)審的提交不超過(guò)評(píng)審者數(shù)量的兩倍。超過(guò)這個(gè)數(shù)評(píng)審者注意力分散評(píng)審質(zhì)量下降。所以隊(duì)列要有準(zhǔn)入控制滿(mǎn)了就排隊(duì)而不是一股腦全塞進(jìn)去。4.4 評(píng)審意見(jiàn)的處理與閉環(huán)評(píng)審意見(jiàn)提出來(lái)只是開(kāi)始處理閉環(huán)才是關(guān)鍵。每條意見(jiàn)都要有明確的處理結(jié)果接受并修改、接受但暫不修改、不接受并說(shuō)明理由。處理結(jié)果要寫(xiě)回評(píng)審記錄并且通知提出意見(jiàn)的評(píng)審者。這里有個(gè)容易忽略的點(diǎn)接受但暫不修改的意見(jiàn)必須記錄后續(xù)處理計(jì)劃比如關(guān)聯(lián)到某個(gè)待辦事項(xiàng)或后續(xù)版本。否則這些意見(jiàn)就會(huì)石沉大海過(guò)一段時(shí)間沒(méi)人記得。我的做法是這類(lèi)意見(jiàn)自動(dòng)生成一條待辦記錄指定負(fù)責(zé)人和預(yù)期處理時(shí)間到期未處理會(huì)觸發(fā)提醒。閉環(huán)的另一個(gè)要求是所有阻塞級(jí)意見(jiàn)必須全部處理完畢才能合并。重要級(jí)和一般級(jí)意見(jiàn)可以協(xié)商但阻塞級(jí)沒(méi)有商量余地。這條規(guī)則執(zhí)行要嚴(yán)格否則阻塞級(jí)意見(jiàn)的權(quán)威性就沒(méi)了。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄踩過(guò)的坑和繞過(guò)的彎5.1 評(píng)審者不積極怎么辦這是開(kāi)放式評(píng)審最常見(jiàn)的問(wèn)題。評(píng)審者不積極原因通常有三個(gè)評(píng)審意見(jiàn)沒(méi)被重視、評(píng)審負(fù)擔(dān)太重、評(píng)審結(jié)果與個(gè)人利益無(wú)關(guān)。對(duì)應(yīng)的解法分別是確保每條評(píng)審意見(jiàn)都有閉環(huán)反饋、控制評(píng)審負(fù)擔(dān)在合理范圍、把評(píng)審參與度納入團(tuán)隊(duì)協(xié)作評(píng)價(jià)。我試過(guò)的一個(gè)有效做法是每周公布評(píng)審參與統(tǒng)計(jì)包括評(píng)審次數(shù)、意見(jiàn)數(shù)量、意見(jiàn)采納率。公開(kāi)統(tǒng)計(jì)本身就能形成一定的正向激勵(lì)。但要注意統(tǒng)計(jì)的目的是促進(jìn)參與不是制造壓力所以不要搞排名懲罰而是側(cè)重展示貢獻(xiàn)。5.2 評(píng)審意見(jiàn)質(zhì)量參差不齊怎么破評(píng)審意見(jiàn)質(zhì)量參差不齊根源在于評(píng)審者不知道什么算好意見(jiàn)。解法是提供示例和培訓(xùn)。我整理過(guò)一份評(píng)審意見(jiàn)示例集把好意見(jiàn)和差意見(jiàn)并列展示新評(píng)審者看完基本就知道該怎么寫(xiě)了。示例集不需要很長(zhǎng)十幾組對(duì)比就夠。另一個(gè)技巧是在評(píng)審意見(jiàn)提交前加一個(gè)自檢提示比如這條意見(jiàn)是否說(shuō)清楚了問(wèn)題是什么、為什么是問(wèn)題、建議怎么改。這個(gè)提示不強(qiáng)制但能提醒評(píng)審者完善表達(dá)。5.3 評(píng)審周期過(guò)長(zhǎng)如何壓縮評(píng)審周期過(guò)長(zhǎng)通常是幾個(gè)原因疊加評(píng)審者響應(yīng)慢、意見(jiàn)來(lái)回輪次多、爭(zhēng)議處理拖沓。壓縮周期的關(guān)鍵是減少輪次。減少輪次的辦法是提交者在提交前盡量把問(wèn)題解決掉評(píng)審者一次性把意見(jiàn)提完整而不是擠牙膏式地一條一條提。我實(shí)測(cè)有效的一個(gè)規(guī)則是評(píng)審者首次評(píng)審必須給出完整意見(jiàn)后續(xù)輪次只針對(duì)修改部分。這條規(guī)則能顯著減少來(lái)回次數(shù)。另外設(shè)置評(píng)審響應(yīng)時(shí)限比如二十四小時(shí)內(nèi)必須給出首次意見(jiàn)超時(shí)自動(dòng)提醒或轉(zhuǎn)給其他評(píng)審者。5.4 常見(jiàn)問(wèn)題速查表問(wèn)題現(xiàn)象可能原因排查方向處理建議評(píng)審隊(duì)列積壓評(píng)審者不足或提交量突增查看評(píng)審者在線狀態(tài)和隊(duì)列長(zhǎng)度臨時(shí)增加評(píng)審者或限制提交頻率自動(dòng)化檢查頻繁誤報(bào)檢查規(guī)則過(guò)嚴(yán)或環(huán)境不一致對(duì)比本地與服務(wù)器檢查結(jié)果調(diào)整規(guī)則閾值或統(tǒng)一環(huán)境配置評(píng)審意見(jiàn)無(wú)人處理閉環(huán)機(jī)制缺失或提醒不到位檢查意見(jiàn)處理記錄和通知日志補(bǔ)全閉環(huán)流程并加強(qiáng)提醒爭(zhēng)議長(zhǎng)時(shí)間未決裁決規(guī)則不明確或裁決人缺位查看爭(zhēng)議處理記錄明確裁決規(guī)則并指定備選裁決人合并后出現(xiàn)回歸問(wèn)題自動(dòng)化檢查覆蓋不足或評(píng)審遺漏復(fù)盤(pán)回歸問(wèn)題與評(píng)審記錄補(bǔ)充檢查項(xiàng)并優(yōu)化評(píng)審重點(diǎn)5.5 幾個(gè)容易被忽略的實(shí)操心得第一個(gè)心得是評(píng)審記錄要定期歸檔和清理?;钴S的評(píng)審記錄保留在主線歷史記錄歸檔到冷存儲(chǔ)避免主線被歷史數(shù)據(jù)拖慢。歸檔周期我一般設(shè)三個(gè)月超過(guò)三個(gè)月的已完成評(píng)審記錄歸檔。第二個(gè)心得是自動(dòng)化檢查腳本要版本化管理。腳本本身也是代碼也會(huì)變更也需要評(píng)審。把腳本納入版本管理每次修改都走評(píng)審流程能避免腳本被隨意改動(dòng)導(dǎo)致檢查標(biāo)準(zhǔn)漂移。第三個(gè)心得是新成員加入時(shí)先安排他們做評(píng)審觀察者看幾輪評(píng)審再正式參與。觀察者不發(fā)表意見(jiàn)只學(xué)習(xí)評(píng)審流程和意見(jiàn)表達(dá)方式。這個(gè)過(guò)渡期能顯著降低新評(píng)審者的出錯(cuò)率。注意評(píng)審觀察者機(jī)制要控制時(shí)長(zhǎng)一般不超過(guò)兩周。時(shí)間太長(zhǎng)觀察者會(huì)失去參與感時(shí)間太短學(xué)習(xí)效果不夠。6. 評(píng)審數(shù)據(jù)的后續(xù)利用讓記錄產(chǎn)生長(zhǎng)期價(jià)值6.1 質(zhì)量趨勢(shì)分析與預(yù)警評(píng)審記錄積累到一定量之后可以做質(zhì)量趨勢(shì)分析。比如統(tǒng)計(jì)每周的阻塞級(jí)意見(jiàn)數(shù)量、平均評(píng)審輪次、平均評(píng)審周期。這些指標(biāo)的變化趨勢(shì)能反映代碼質(zhì)量和協(xié)作效率的變化。如果阻塞級(jí)意見(jiàn)數(shù)量持續(xù)上升說(shuō)明代碼質(zhì)量在下降需要提前干預(yù)。預(yù)警機(jī)制可以設(shè)閾值比如阻塞級(jí)意見(jiàn)數(shù)量連續(xù)兩周上升超過(guò)百分之二十觸發(fā)預(yù)警。預(yù)警不是目的目的是讓團(tuán)隊(duì)及時(shí)關(guān)注而不是等到問(wèn)題積累到不可收拾。6.2 新人培訓(xùn)素材的自動(dòng)沉淀評(píng)審記錄里藏著大量真實(shí)案例這些案例是新人培訓(xùn)的絕佳素材。我的做法是定期從評(píng)審記錄里篩選典型案例整理成培訓(xùn)材料。篩選標(biāo)準(zhǔn)是問(wèn)題有代表性、意見(jiàn)表達(dá)清晰、處理過(guò)程完整。整理時(shí)隱去具體人和項(xiàng)目信息只保留技術(shù)內(nèi)容。這些案例比教科書(shū)上的例子更有說(shuō)服力因?yàn)樗鼈兪钦鎸?shí)發(fā)生過(guò)的。新人看完之后對(duì)什么該做、什么不該做會(huì)有更具體的認(rèn)知。6.3 評(píng)審規(guī)則本身的迭代優(yōu)化評(píng)審規(guī)則不是定下來(lái)就一成不變的。隨著項(xiàng)目演進(jìn)和團(tuán)隊(duì)變化規(guī)則也需要迭代。迭代的依據(jù)來(lái)自評(píng)審記錄的分析和參與者的反饋。比如某個(gè)檢查項(xiàng)長(zhǎng)期沒(méi)有發(fā)現(xiàn)問(wèn)題可以考慮移除或放寬某個(gè)類(lèi)型的意見(jiàn)反復(fù)出現(xiàn)可以考慮加入自動(dòng)化檢查。規(guī)則迭代要謹(jǐn)慎不能頻繁變動(dòng)否則參與者無(wú)所適從。我的做法是每季度做一次規(guī)則回顧收集反饋評(píng)估效果然后決定是否調(diào)整。調(diào)整要提前公告給參與者適應(yīng)時(shí)間。7. 不同規(guī)模團(tuán)隊(duì)的適配策略7.1 小團(tuán)隊(duì)的輕量做法小團(tuán)隊(duì)人少流程要盡量輕。我的建議是小團(tuán)隊(duì)可以只保留自動(dòng)化檢查加一名人工評(píng)審評(píng)審記錄用簡(jiǎn)單的文本文件即可不需要復(fù)雜的數(shù)據(jù)庫(kù)和看板。輪轉(zhuǎn)機(jī)制也可以簡(jiǎn)化甚至固定一兩個(gè)人評(píng)審只要保證評(píng)審質(zhì)量就行。小團(tuán)隊(duì)的優(yōu)勢(shì)是溝通成本低很多問(wèn)題當(dāng)面就能說(shuō)清楚。所以評(píng)審流程不必追求形式完整而是追求實(shí)際效果。能口頭說(shuō)清楚的不必非要寫(xiě)成結(jié)構(gòu)化意見(jiàn)。但記錄還是要留哪怕簡(jiǎn)單幾句方便后續(xù)追溯。7.2 中型團(tuán)隊(duì)的標(biāo)準(zhǔn)化做法中型團(tuán)隊(duì)人數(shù)上來(lái)了溝通成本上升流程需要標(biāo)準(zhǔn)化。這時(shí)候自動(dòng)化檢查、評(píng)審隊(duì)列、輪轉(zhuǎn)機(jī)制、結(jié)構(gòu)化意見(jiàn)、閉環(huán)處理這些環(huán)節(jié)都要建立起來(lái)。評(píng)審記錄要集中存儲(chǔ)方便檢索和統(tǒng)計(jì)。爭(zhēng)議處理規(guī)則要明確避免因?yàn)橐庖?jiàn)不一致導(dǎo)致僵持。中型團(tuán)隊(duì)還要注意評(píng)審者的培養(yǎng)。不能只靠少數(shù)幾個(gè)資深成員評(píng)審要有意識(shí)地讓更多人參與進(jìn)來(lái)逐步擴(kuò)大評(píng)審者隊(duì)伍。培養(yǎng)方式就是前面提到的觀察者機(jī)制加示例培訓(xùn)。7.3 大型團(tuán)隊(duì)的分布式做法大型團(tuán)隊(duì)往往跨模塊、跨地域評(píng)審流程需要分布式設(shè)計(jì)。每個(gè)模塊有自己的評(píng)審者池和評(píng)審規(guī)則模塊之間的接口變更需要跨模塊評(píng)審。評(píng)審記錄要統(tǒng)一存儲(chǔ)但分模塊管理避免信息過(guò)載。大型團(tuán)隊(duì)還要注意評(píng)審規(guī)則的一致性。不同模塊的規(guī)則可以有差異但核心原則要統(tǒng)一比如阻塞級(jí)意見(jiàn)必須處理、評(píng)審記錄必須完整、爭(zhēng)議處理必須有時(shí)限。這些核心原則是評(píng)審體系的地基不能因?yàn)槟K差異而動(dòng)搖。8. 工具選型與自建方案的權(quán)衡8.1 現(xiàn)成工具與自建腳本的對(duì)比現(xiàn)成工具的好處是開(kāi)箱即用功能完整維護(hù)成本低。缺點(diǎn)是定制性差有些流程細(xì)節(jié)可能不符合團(tuán)隊(duì)實(shí)際。自建腳本的好處是完全貼合團(tuán)隊(duì)需求想怎么改就怎么改。缺點(diǎn)是開(kāi)發(fā)和維護(hù)成本高需要有人持續(xù)投入。我的建議是初期用現(xiàn)成工具快速跑通流程等流程穩(wěn)定、需求明確之后再考慮自建或二次開(kāi)發(fā)。不要一上來(lái)就自建那樣很容易陷入造輪子的泥潭流程還沒(méi)跑通開(kāi)發(fā)精力已經(jīng)耗盡了。8.2 關(guān)鍵能力的評(píng)估清單選型時(shí)重點(diǎn)評(píng)估幾個(gè)關(guān)鍵能力自動(dòng)化檢查的集成難度、評(píng)審記錄的結(jié)構(gòu)化程度、通知機(jī)制的靈活性、權(quán)限管理的細(xì)粒度、統(tǒng)計(jì)報(bào)表的豐富度。這幾項(xiàng)能力直接決定流程能不能跑順。評(píng)估方式可以是試用也可以是小范圍試點(diǎn)。試用時(shí)重點(diǎn)看集成難度和記錄結(jié)構(gòu)化程度這兩項(xiàng)最難后期彌補(bǔ)。通知機(jī)制和統(tǒng)計(jì)報(bào)表可以后期增強(qiáng)權(quán)限管理可以先用粗粒度再逐步細(xì)化。8.3 遷移與兼容的注意事項(xiàng)如果從舊流程遷移到新流程要注意兼容。舊流程里的評(píng)審記錄要盡量遷移過(guò)來(lái)避免歷史斷層。遷移時(shí)可以只遷移近期的活躍記錄歷史記錄歸檔保留。遷移過(guò)程中要保證新舊流程并行一段時(shí)間確認(rèn)新流程穩(wěn)定后再完全切換。兼容的另一個(gè)方面是參與者的習(xí)慣。新流程剛上線時(shí)參與者會(huì)不適應(yīng)需要一段過(guò)渡期。過(guò)渡期內(nèi)可以放寬一些非核心要求等大家熟悉之后再逐步收緊。強(qiáng)行一步到位容易引發(fā)抵觸情緒。9. 我個(gè)人在實(shí)際操作中的幾點(diǎn)體會(huì)這套 open-code-review 的思路我在不同規(guī)模的團(tuán)隊(duì)里都試過(guò)有順利的時(shí)候也有翻車(chē)的時(shí)候。最大的體會(huì)是流程是給人用的不是給人看的。任何規(guī)則如果讓參與者覺(jué)得是在增加負(fù)擔(dān)而不是解決問(wèn)題最終都會(huì)流于形式。另一個(gè)體會(huì)是自動(dòng)化檢查的規(guī)則要寧少勿濫。剛開(kāi)始時(shí)容易貪多什么檢查都想加結(jié)果誤報(bào)一堆參與者疲于應(yīng)付反而忽略了真正重要的問(wèn)題。后來(lái)我改成只加那些明確有價(jià)值、誤報(bào)率低的檢查效果反而更好。還有一點(diǎn)評(píng)審記錄的價(jià)值不在于記錄本身而在于后續(xù)的利用。如果記錄只是存著沒(méi)人看那和沒(méi)記錄差不多。所以一定要建立后續(xù)利用的機(jī)制比如趨勢(shì)分析、案例沉淀、規(guī)則迭代。讓記錄活起來(lái)評(píng)審體系才有長(zhǎng)期生命力。最后分享一個(gè)小技巧評(píng)審規(guī)則和流程文檔最好用問(wèn)答形式寫(xiě)而不是條款形式。問(wèn)答形式更貼近實(shí)際使用場(chǎng)景參與者遇到問(wèn)題時(shí)更容易找到答案。條款形式看起來(lái)嚴(yán)謹(jǐn)?shù)珜?shí)際查閱時(shí)往往找不到對(duì)應(yīng)的場(chǎng)景。這個(gè)技巧是我踩過(guò)幾次坑之后才悟出來(lái)的希望對(duì)你有用。