放式代碼評(píng)審:從形式化打卡到工程質(zhì)量門(mén)禁)
先說(shuō)一個(gè)我觀察了很久的現(xiàn)象很多團(tuán)隊(duì)的代碼評(píng)審?fù)ㄟ^(guò)率常年保持在95%以上但線上故障、返工成本、技術(shù)債一點(diǎn)都沒(méi)有減少。這不是個(gè)例我在維護(hù)某跨部門(mén)中臺(tái)項(xiàng)目時(shí)也踩過(guò)同樣的坑。后來(lái)我把整個(gè)評(píng)審機(jī)制推翻重做跑通了一套以開(kāi)放透明為核心的方法代號(hào)就叫open-code-review。這套東西沒(méi)有用什么新框架、新語(yǔ)言純粹是把評(píng)審從走流程改造成工程鏈路里真正能攔住問(wèn)題的環(huán)節(jié)。這篇文章就是把整套設(shè)計(jì)和落地過(guò)程拆開(kāi)講為什么傳統(tǒng)評(píng)審會(huì)退化成打卡游戲、open-code-review的核心取舍是什么、具體在技術(shù)協(xié)作平臺(tái)上怎么配置、用哪些指標(biāo)可以判斷它有沒(méi)有效。適合正在被形式化評(píng)審困擾的技術(shù)負(fù)責(zé)人、研發(fā)骨干以及剛接手團(tuán)隊(duì)想重建協(xié)作文化的人。1. 傳統(tǒng)代碼評(píng)審為什么越來(lái)越流于形式1.1 三個(gè)高頻但危險(xiǎn)的現(xiàn)場(chǎng)先說(shuō)我反復(fù)遇到的三種場(chǎng)景你可以對(duì)照一下自己的團(tuán)隊(duì)。第一種是評(píng)審區(qū)很熱鬧改動(dòng)卻沒(méi)人認(rèn)真看。某次功能合入一次變更涉及文件超過(guò)四十個(gè)diff 總量接近兩千行。評(píng)審頁(yè)面里評(píng)論不少但往下翻基本都是這個(gè)變量名換一下這里少了個(gè)空格。真正影響正確性的并發(fā)處理邏輯、異常分支幾乎沒(méi)有人碰。不是評(píng)審者偷懶而是兩千行的 diff 靠人肉逐行去看本身就是不現(xiàn)實(shí)的。第二種是意見(jiàn)全被采納缺陷卻照樣漏。有一段時(shí)間我們統(tǒng)計(jì)過(guò)評(píng)審意見(jiàn)的解決率數(shù)據(jù)非常漂亮接近百分之百。但解決率高不代表質(zhì)量高因?yàn)殚_(kāi)發(fā)者把每條評(píng)論都當(dāng)成待辦任務(wù)改完就關(guān)掉從不停下來(lái)想這個(gè)改動(dòng)會(huì)不會(huì)引入新的邊界問(wèn)題評(píng)審意見(jiàn)是否真的被理解了結(jié)果就是評(píng)審催生了一堆表面合規(guī)的修改真正的隱患照樣流到測(cè)試環(huán)境甚至線上。第三種是老手一言堂新人不敢開(kāi)口。當(dāng)團(tuán)隊(duì)里資歷深的人先發(fā)表了意見(jiàn)后續(xù)討論基本會(huì)沿著他的方向走。我見(jiàn)過(guò)一個(gè)新同事在評(píng)審里指出一個(gè)真實(shí)的性能隱患結(jié)果被一句這里之前就是這么寫(xiě)的頂回去。他后來(lái)再也不在評(píng)審里說(shuō)話了只在私下跟我提。這三個(gè)場(chǎng)景疊加起來(lái)會(huì)形成一種特別尷尬的氛圍評(píng)審流程每天都在跑但所有人對(duì)評(píng)審的信任度在持續(xù)走低。有人開(kāi)始繞過(guò)評(píng)審直接合代碼有人把評(píng)審當(dāng)成形式上的打卡最后問(wèn)題靠線上事故來(lái)暴露。1.2 真正應(yīng)該背鍋的是流程結(jié)構(gòu)如果把上面這些現(xiàn)象放在一起看問(wèn)題的根源并不是某個(gè)人不夠負(fù)責(zé)而是評(píng)審流程本身存在三個(gè)結(jié)構(gòu)性缺陷。第一沒(méi)有統(tǒng)一標(biāo)準(zhǔn)。每個(gè)人對(duì)什么叫可以合入的理解都不一樣。有人盯著代碼風(fēng)格有人只關(guān)心功能是否跑通有人干脆不評(píng)論。當(dāng)標(biāo)準(zhǔn)變成個(gè)人經(jīng)驗(yàn)時(shí)評(píng)審質(zhì)量就取決于評(píng)審者當(dāng)天的心情和資歷而不是代碼本身。第二沒(méi)有意見(jiàn)閉環(huán)。評(píng)論發(fā)出去之后改沒(méi)改、為什么沒(méi)改、哪些意見(jiàn)需要升級(jí)決策全靠自覺(jué)。這一輪合入之后下一輪又從零開(kāi)始?xì)v史討論完全沒(méi)有沉淀下來(lái)。評(píng)審過(guò)程沒(méi)有形成任何積累同一個(gè)問(wèn)題換個(gè)文件會(huì)反復(fù)踩。第三沒(méi)有效果度量。團(tuán)隊(duì)問(wèn)不出評(píng)審到底值不值這個(gè)問(wèn)題。大家只能憑感覺(jué)說(shuō)好像有用或者看不出用在哪一旦有人質(zhì)疑評(píng)審的必要性拿不出任何數(shù)據(jù)來(lái)回應(yīng)。open-code-review要解決的就是這三個(gè)結(jié)構(gòu)性問(wèn)題。它的出發(fā)點(diǎn)很簡(jiǎn)單把評(píng)審從憑感覺(jué)變成對(duì)標(biāo)準(zhǔn)、留證據(jù)、可度量。2. open-code-review 在解決什么問(wèn)題2.1 open的三個(gè)落點(diǎn)記錄開(kāi)放、角色開(kāi)放、規(guī)則開(kāi)放很多人聽(tīng)到開(kāi)放式評(píng)審第一反應(yīng)是把評(píng)審權(quán)限放開(kāi)所有人都能評(píng)論。這只是最表層的意思。我在設(shè)計(jì)open-code-review時(shí)open 實(shí)際指三件事。第一是記錄開(kāi)放。所有評(píng)審意見(jiàn)、討論結(jié)論、最終處理方式必須留在公開(kāi)可檢索的位置而不是散落在聊天記錄和個(gè)人私聊里。我們團(tuán)隊(duì)后來(lái)排查一個(gè)線上超時(shí)問(wèn)題時(shí)就是靠翻半年前的評(píng)審記錄找到了當(dāng)時(shí)的取舍依據(jù)這比問(wèn)一圈人高效太多。第二是角色開(kāi)放。評(píng)審參與方不局限于后端開(kāi)發(fā)。前端同事可以評(píng)論接口契約問(wèn)題測(cè)試同學(xué)可以指出可測(cè)試性不足產(chǎn)品經(jīng)理偶爾能補(bǔ)充業(yè)務(wù)邊界。我在機(jī)制里加了一個(gè)評(píng)審觀察員的角色不強(qiáng)制必須發(fā)言但所有人都可以基于技術(shù)事實(shí)補(bǔ)充信息。這個(gè)微小變化帶來(lái)一個(gè)好處評(píng)審討論不再是一對(duì)一的攻防而是一群人對(duì)一段代碼的共識(shí)建立。第三是規(guī)則開(kāi)放。評(píng)價(jià)標(biāo)準(zhǔn)不看資歷、不看嗓門(mén)按統(tǒng)一的檢查清單走。哪怕是最資深的成員如果某項(xiàng)檢查沒(méi)過(guò)也得給出理由。而新人也擁有同樣的權(quán)利指出問(wèn)題只要他引用的是事實(shí)而非個(gè)人偏好。2.2 從挑錯(cuò)到對(duì)齊意圖評(píng)審對(duì)象變了傳統(tǒng)評(píng)審最大的問(wèn)題是評(píng)審者把注意力放在找出毛病上。但代碼是意圖的載體一段代碼寫(xiě)得別扭往往不是因?yàn)閷?xiě)代碼的人水平差而是因?yàn)樾枨笊舷挛?、歷史約束沒(méi)有被表達(dá)清楚。open-code-review的一個(gè)重要轉(zhuǎn)變是把評(píng)審對(duì)象從代碼文本擴(kuò)展成改動(dòng)意圖。評(píng)審者要回答的問(wèn)題不再是這行代碼對(duì)不對(duì)而是作者想解決什么問(wèn)題、這個(gè)方案是否匹配問(wèn)題本身、有沒(méi)有更簡(jiǎn)單的路徑。這個(gè)轉(zhuǎn)變?cè)趯?shí)操中很直觀。比如我看到一個(gè)同學(xué)為了兼容某種極端輸入在核心邏輯里加了三個(gè)嵌套的防御判斷。按傳統(tǒng)挑錯(cuò)視角我會(huì)評(píng)論這里太復(fù)雜建議簡(jiǎn)化。但按意圖對(duì)齊視角我會(huì)先問(wèn)這個(gè)輸入場(chǎng)景是真實(shí)存在的嗎有沒(méi)有數(shù)據(jù)支撐。如果只是臆想中的邊界那這段防御邏輯就是廢代碼如果確實(shí)是真實(shí)場(chǎng)景那三個(gè)判斷可能都有存在的必要我要評(píng)價(jià)的是它有沒(méi)有被封裝清楚。把意圖對(duì)齊放在第一位之后評(píng)審討論的質(zhì)量明顯上升。很多原本會(huì)吵起來(lái)的問(wèn)題最后都變成了我們?cè)俅_認(rèn)一下這個(gè)場(chǎng)景到底存不存在這樣的事實(shí)核查而不是個(gè)人偏好之爭(zhēng)。2.3 評(píng)論分級(jí)與仲裁機(jī)制沒(méi)有分級(jí)制度的評(píng)審最容易出現(xiàn)什么事都重要的錯(cuò)覺(jué)。次要點(diǎn)意見(jiàn)和阻塞性問(wèn)題混在一起作者只能靠猜來(lái)判斷優(yōu)先級(jí)最終要么全部照單全收要么干脆全部忽略。我在open-code-review里把評(píng)審意見(jiàn)分成三級(jí)并且和合入門(mén)禁綁定級(jí)別含義處理方式P0必須修復(fù)否則不應(yīng)該合入不修復(fù)就自動(dòng)阻塞合并P1強(qiáng)烈建議修復(fù)可討論延期允許帶條件合入但必須登記待辦P2優(yōu)化建議不阻塞合入作者自行決定是否采納這里的關(guān)鍵不是分級(jí)本身而是配套的仲裁流程。P0 和 P1 的爭(zhēng)議如果討論超過(guò)兩輪還沒(méi)有結(jié)論自動(dòng)升級(jí)給技術(shù)負(fù)責(zé)人或者被改動(dòng)模塊的負(fù)責(zé)人仲裁。仲裁結(jié)果所有人可見(jiàn)理由必須寫(xiě)明。開(kāi)發(fā)者如果覺(jué)得某條意見(jiàn)不合理同樣有申訴窗口可以不改但必須把不改的理由寫(xiě)清楚。這個(gè)機(jī)制保護(hù)了作者的判斷力也給了評(píng)審者一個(gè)反饋循環(huán)——如果一條意見(jiàn)經(jīng)常被申訴且經(jīng)常被駁回那說(shuō)明評(píng)審意見(jiàn)本身的質(zhì)量需要提高。3. 落地實(shí)操這套機(jī)制怎么跑起來(lái)3.1 先把變更變小評(píng)審才可能認(rèn)真動(dòng)手設(shè)計(jì)評(píng)審機(jī)制之前一定要先解決一個(gè)前提問(wèn)題變更的大小。評(píng)審者再負(fù)責(zé)任也沒(méi)有辦法對(duì)上千行的 diff 保持全程專注。這不光是態(tài)度問(wèn)題而是人的注意力本身就是有限資源。我在團(tuán)隊(duì)里定了一條硬規(guī)矩單次合并請(qǐng)求盡量控制在三百行以內(nèi)超過(guò)四百行必須拆分或者先合入一個(gè)接口殼子再迭代。剛開(kāi)始阻力很大有人覺(jué)得拆分麻煩有人覺(jué)得反正最終都是要合進(jìn)去的分批更耽誤時(shí)間。但跑了兩個(gè)月之后反對(duì)聲音基本消失了。原因很簡(jiǎn)單拆分之后評(píng)審者真的會(huì)認(rèn)真看。三百行的 diff十分鐘可以過(guò)完大家愿意逐行讀一千行的 diff三十分鐘也讀不完最后只會(huì)草草掃一眼。而且變更變小之后出問(wèn)題時(shí)定位也快回滾也只需要回滾一個(gè)很小的范圍。我還讓 CI 流水線自動(dòng)檢查 diff 行數(shù)超過(guò)限制直接打警告標(biāo)簽不讓合并按鈕變綠。這個(gè)機(jī)制把拆小變更從倡議變成了硬約束。3.2 給評(píng)審意見(jiàn)套一個(gè)統(tǒng)一模板評(píng)審意見(jiàn)質(zhì)量參差不齊很多時(shí)候是因?yàn)樵u(píng)審者不知道怎么把想法說(shuō)清楚。我后來(lái)在團(tuán)隊(duì)規(guī)范里加了一個(gè)簡(jiǎn)單的意見(jiàn)模板要求每條評(píng)論至少包含問(wèn)題定位 建議方案 影響范圍。這個(gè)模板降低了雙方的溝通成本。下面是我們內(nèi)部常用的一種評(píng)審評(píng)論格式【位置】src/service/order.js#L120-L135 【問(wèn)題】訂單狀態(tài)流轉(zhuǎn)這里缺少并發(fā)控制兩個(gè)請(qǐng)求同時(shí)到達(dá)時(shí)可能出現(xiàn)重復(fù)回調(diào)。 【建議】在狀態(tài)變更入口加分布式鎖或者用數(shù)據(jù)庫(kù)樂(lè)觀鎖校驗(yàn)版本號(hào)。 【影響】高頻下單場(chǎng)景下概率觸發(fā)生產(chǎn)環(huán)境影響約為每萬(wàn)單 1~2 次。 【級(jí)別】P0不要小看這個(gè)模板。它強(qiáng)制評(píng)審者把感覺(jué)不對(duì)翻譯成具體的事實(shí)和方案。我們統(tǒng)計(jì)過(guò)用了模板之后一條評(píng)審意見(jiàn)被來(lái)回追問(wèn)你說(shuō)的到底是什么意思的次數(shù)明顯減少。作者回復(fù)意見(jiàn)的耗時(shí)也降了接近四成。對(duì)于經(jīng)常重復(fù)出現(xiàn)的問(wèn)題類(lèi)型模板還可以進(jìn)一步細(xì)分成缺陷類(lèi)和設(shè)計(jì)類(lèi)。缺陷類(lèi)模板要回答什么條件下會(huì)出錯(cuò)設(shè)計(jì)類(lèi)模板要回答這個(gè)方案在什么擴(kuò)展場(chǎng)景下會(huì)失效。有模板不代表討論會(huì)變得死板反而是把討論引導(dǎo)到更有價(jià)值的技術(shù)層面。3.3 打通質(zhì)量門(mén)禁讓評(píng)審結(jié)果說(shuō)了算評(píng)審意見(jiàn)如果只是留在討論區(qū)它永遠(yuǎn)只是建議。open-code-review最重要的動(dòng)作是讓評(píng)審結(jié)果參與決策。具體來(lái)說(shuō)我在流水線里加了三個(gè)和評(píng)審相關(guān)的檢查點(diǎn)。第一個(gè)檢查點(diǎn)合并請(qǐng)求一旦創(chuàng)建自動(dòng)化工具會(huì)把靜態(tài)掃描結(jié)果、測(cè)試覆蓋率變化、依賴安全掃描結(jié)果直接貼到評(píng)審頁(yè)面最顯眼的位置。評(píng)審者不用再重復(fù)問(wèn)你測(cè)試過(guò)了嗎這些信息一眼就能看到。第二個(gè)檢查點(diǎn)CI 會(huì)統(tǒng)計(jì)當(dāng)前合并請(qǐng)求里未解決的 P0 級(jí)別評(píng)論數(shù)量。只要 P0 還沒(méi)清零合并按鈕就是灰的。這個(gè)機(jī)制讓必須修復(fù)不再是一句口號(hào)而是一條無(wú)法繞過(guò)的限制。第三個(gè)檢查點(diǎn)是針對(duì)長(zhǎng)期未處理的合并請(qǐng)求。如果某個(gè)合并請(qǐng)求創(chuàng)建后超過(guò)四個(gè)工作日沒(méi)人評(píng)審機(jī)器人會(huì)在團(tuán)隊(duì)群里提醒同時(shí)把排隊(duì)時(shí)間算入團(tuán)隊(duì)的評(píng)審效率指標(biāo)。這個(gè)設(shè)計(jì)是為了防止合并請(qǐng)求堆成山到發(fā)布日之前集中突擊評(píng)審。這幾個(gè)檢查點(diǎn)跑起來(lái)之后評(píng)審從人和人之間的協(xié)商變成了流程自動(dòng)執(zhí)行的一部分。人的注意力只花在真正需要判斷的地方其余全部交給機(jī)制。4. 用數(shù)據(jù)回答評(píng)審到底值不值4.1 四個(gè)值得長(zhǎng)期盯的指標(biāo)很多團(tuán)隊(duì)從未量化過(guò)評(píng)審效果是因?yàn)椴恢涝摽词裁础N覀兣芰巳齻€(gè)季度之后沉淀出了四個(gè)核心指標(biāo)。第一個(gè)是平均評(píng)審周期指一個(gè)合并請(qǐng)求從創(chuàng)建到合入經(jīng)過(guò)多少時(shí)間。這個(gè)數(shù)字過(guò)高說(shuō)明合并請(qǐng)求積壓嚴(yán)重評(píng)審形成瓶頸過(guò)低也不一定是好事要結(jié)合下面對(duì)有效性的指標(biāo)看。我們團(tuán)隊(duì)的目標(biāo)控制在兩個(gè)工作日內(nèi)閉環(huán)。第二個(gè)是評(píng)論密度計(jì)算方式是有效評(píng)論數(shù)除以合并請(qǐng)求數(shù)量。這里的有效評(píng)論指那些被作者采納、或者引發(fā)過(guò)后續(xù)討論的評(píng)論。評(píng)論密度長(zhǎng)期為零說(shuō)明評(píng)審大概率只是形式上點(diǎn)了個(gè)通過(guò)。第三個(gè)是缺陷逃逸率指評(píng)審?fù)ㄟ^(guò)之后、仍然在測(cè)試環(huán)境或線上被發(fā)現(xiàn)的缺陷數(shù)量。這個(gè)指標(biāo)是評(píng)審有效性最直白的證明。如果逃逸率高推倒重來(lái)都不為過(guò)。第四個(gè)是一輪通過(guò)率指一個(gè)合并請(qǐng)求只經(jīng)過(guò)一輪評(píng)審就直接通過(guò)的占比。很多人以為這個(gè)數(shù)字越高越好恰恰相反。如果一輪通過(guò)率接近百分之百說(shuō)明評(píng)審者沒(méi)有認(rèn)真看如果長(zhǎng)期低于百分之四十說(shuō)明標(biāo)準(zhǔn)定義有問(wèn)題或者溝通成本過(guò)高。健康的區(qū)間通常在百分之六十到百分之八十。這些指標(biāo)不需要單獨(dú)開(kāi)發(fā)一套系統(tǒng)從代碼托管平臺(tái)的接口就可以拉取數(shù)據(jù)每?jī)芍軈R總一次就夠了。重點(diǎn)是團(tuán)隊(duì)要形成共識(shí)指標(biāo)是用來(lái)發(fā)現(xiàn)問(wèn)題不是用來(lái)處罰個(gè)人的。4.2 月度復(fù)盤(pán)應(yīng)該看什么指標(biāo)拉出來(lái)之后如果不定期復(fù)盤(pán)就只是一堆數(shù)字。我們每個(gè)月底會(huì)做一次一小時(shí)的質(zhì)量復(fù)盤(pán)只看三類(lèi)內(nèi)容。第一類(lèi)找出評(píng)論量最多、評(píng)審周期最長(zhǎng)的合并請(qǐng)求。這類(lèi)請(qǐng)求往往暴露架構(gòu)問(wèn)題比如模塊之間耦合太深、職責(zé)邊界不清晰、或者拆分的粒度不夠細(xì)。修復(fù)辦法不是讓大家多花時(shí)間評(píng)審而是去重構(gòu)那部分設(shè)計(jì)。第二類(lèi)統(tǒng)計(jì)被駁回的 P0 和 P1 意見(jiàn)也就是爭(zhēng)議記錄。如果某個(gè)模塊反復(fù)出現(xiàn)同一種爭(zhēng)議說(shuō)明這部分的規(guī)范是模糊的。我在某個(gè)歷史項(xiàng)目里遇到過(guò)錯(cuò)誤處理到底用返回碼還是異常的爭(zhēng)論連續(xù)出現(xiàn)四周后來(lái)干脆在團(tuán)隊(duì)規(guī)范里補(bǔ)了一節(jié)說(shuō)明爭(zhēng)論立刻就停了。第三類(lèi)回看 P2 意見(jiàn)的采納情況。P2 雖然不阻塞合入但它們往往反映了代碼演進(jìn)的方向。我們要求月度復(fù)盤(pán)里挑三條被采納的 P2 意見(jiàn)追蹤它們后來(lái)是否真的帶來(lái)了收益再挑三條沒(méi)被采納的檢查是否值得后續(xù)補(bǔ)上。復(fù)盤(pán)不需要追求每次都有大動(dòng)作但至少要記錄下來(lái)形成團(tuán)隊(duì)的決策沉淀。半年之后往回翻能看到質(zhì)量改進(jìn)的清晰軌跡這也成為評(píng)審機(jī)制不被推翻的最大依據(jù)。5. 常見(jiàn)問(wèn)題與避坑實(shí)錄5.1 團(tuán)隊(duì)不認(rèn)真評(píng)強(qiáng)制必須評(píng)論是下策推行評(píng)審機(jī)制不久會(huì)遇到一個(gè)典型問(wèn)題合并請(qǐng)求提交上去半天沒(méi)人看或者只有一個(gè)人點(diǎn)了個(gè)通過(guò)。面對(duì)這種情況第一反應(yīng)可能是規(guī)定每條評(píng)論必須有人回復(fù)。這個(gè)決策是我踩過(guò)最大的坑。強(qiáng)制之后團(tuán)隊(duì)確實(shí)開(kāi)始評(píng)論了但冒出來(lái)的全是看起來(lái)沒(méi)問(wèn)題這處命名我建議調(diào)整一下這類(lèi)偽評(píng)論。規(guī)則把評(píng)審變成了任務(wù)參與者只想著完成指標(biāo)而不是真正理解代碼。正確的做法是雙管齊下。一方面縮短單次評(píng)審的范圍讓評(píng)審者從心理上覺(jué)得十分鐘能看完我愿意看另一方面建立評(píng)審者輪值制度明確每周由誰(shuí)負(fù)責(zé)主要評(píng)審職能而不是任由合并請(qǐng)求在列表里排隊(duì)。輪值的人有歸屬感看代碼時(shí)會(huì)更有主人意識(shí)。5.2 評(píng)審爭(zhēng)議僵持怎么打破僵局兩個(gè)人對(duì)一段實(shí)現(xiàn)方案持有不同意見(jiàn)在評(píng)審里來(lái)回回復(fù)了七八輪誰(shuí)也說(shuō)服不了誰(shuí)最終消耗的是兩邊的時(shí)間還容易傷感情。我們針對(duì)這種情況定了一條清晰的升級(jí)規(guī)則同一爭(zhēng)議討論超過(guò)兩輪必須把問(wèn)題提交給模塊負(fù)責(zé)人或引入第三方評(píng)審由仲裁人做最終決策。仲裁人的要求是不看資歷、只看事實(shí)必須基于測(cè)試數(shù)據(jù)、線上數(shù)據(jù)或具體擴(kuò)展場(chǎng)景來(lái)判斷。我在某跨部門(mén)項(xiàng)目里處理過(guò)一次典型僵局一個(gè)同學(xué)堅(jiān)持用方案A因?yàn)榇a更簡(jiǎn)潔另一位堅(jiān)持用方案B因?yàn)楹罄m(xù)擴(kuò)展更省事。兩邊都有道理連續(xù)吵了一周。最后我們把仲裁聚焦到一個(gè)問(wèn)題上這個(gè)模塊在下一個(gè)季度的規(guī)劃里有沒(méi)有明確的擴(kuò)展需求。有就選方案B沒(méi)有就選方案A。事實(shí)一擺半小時(shí)內(nèi)就達(dá)成了一致。5.3 評(píng)審變成找茬大會(huì)怎么轉(zhuǎn)回來(lái)評(píng)審機(jī)制運(yùn)行久了會(huì)有一個(gè)副作用個(gè)別評(píng)審者把注意力集中在代碼風(fēng)格、命名、格式上每條都提條條都標(biāo) P0。這樣做的直接后果是作者疲憊不堪真正重要的邏輯問(wèn)題反而被淹沒(méi)。要扭轉(zhuǎn)這個(gè)局面要在團(tuán)隊(duì)規(guī)范里明確區(qū)分意圖級(jí)問(wèn)題和表達(dá)級(jí)問(wèn)題。命名和格式屬于表達(dá)級(jí)不是不重要而是不應(yīng)該成為阻塞項(xiàng)。我們?cè)谀0謇锇堰@類(lèi)問(wèn)題直接歸到 P2并且允許作者批量說(shuō)明已記錄本輪不處理。還有一個(gè)經(jīng)驗(yàn)評(píng)審者如果連續(xù)多條評(píng)論都是 P2會(huì)被系統(tǒng)標(biāo)記為風(fēng)格偏好型評(píng)審數(shù)據(jù)看板里會(huì)提示團(tuán)隊(duì)關(guān)注。這聽(tīng)起來(lái)有點(diǎn)嚴(yán)苛但效果很好至少大家會(huì)反思自己的評(píng)論是不是在為質(zhì)量服務(wù)。5.4 新人不敢評(píng)、不會(huì)評(píng)怎么辦新成員加入團(tuán)隊(duì)后讓他立刻參與評(píng)審一般會(huì)有兩個(gè)障礙一是不知道標(biāo)準(zhǔn)是什么二是擔(dān)心自己說(shuō)錯(cuò)被老成員反駁于是干脆不發(fā)言。我后來(lái)調(diào)整了規(guī)則新成員前兩周不要求負(fù)責(zé)評(píng)審只要求訂閱團(tuán)隊(duì)里所有合并請(qǐng)求的評(píng)審?fù)ㄖ瓤磩e人怎么評(píng)。兩周之后先讓新人評(píng)審一些低風(fēng)險(xiǎn)模塊比如工具類(lèi)、配置類(lèi)代碼。這類(lèi)代碼邊界清晰、測(cè)試覆蓋高即使漏審了問(wèn)題也不大適合用來(lái)建立信心。更進(jìn)一步我會(huì)給新人配一個(gè)評(píng)審向?qū)臋n里面是團(tuán)隊(duì)歷次高頻問(wèn)題的歸類(lèi)。新人照著文檔對(duì)照代碼比自己憑空摸索快得多。我觀察下來(lái)大部分新人第四周開(kāi)始就能提出有價(jià)值的設(shè)計(jì)層面意見(jiàn)比直接扔到核心模塊里硬審效果要好太多。寫(xiě)在最后的一點(diǎn)體會(huì)open-code-review走到現(xiàn)在我最大的感悟是代碼評(píng)審的難點(diǎn)從來(lái)不在工具而在團(tuán)隊(duì)對(duì)什么是對(duì)的代碼是否有一個(gè)默認(rèn)共識(shí)。開(kāi)放式評(píng)審的本質(zhì)是把這個(gè)默認(rèn)共識(shí)顯性化、可爭(zhēng)論、可沉淀。如果你正打算在團(tuán)隊(duì)里推一套評(píng)審機(jī)制別急著買(mǎi)工具或者定一堆考核指標(biāo)。先花兩周時(shí)間把檢查清單、評(píng)論分級(jí)、升級(jí)仲裁這三條基本規(guī)則理清楚。至于效果不要憑感覺(jué)衡量跑一個(gè)月之后用數(shù)據(jù)和復(fù)盤(pán)說(shuō)話。任何一個(gè)開(kāi)發(fā)團(tuán)隊(duì)只要認(rèn)真堅(jiān)持這套方法跑一個(gè)季度都會(huì)明顯感覺(jué)到評(píng)審不再是負(fù)擔(dān)而是一項(xiàng)有復(fù)利的技術(shù)投資。