審校 | 蔡芳芳
作者 | 茹炳晟
騰訊 T4 級技術專家,騰訊研究院特約研究員,業界知名實戰派研發效能和軟體質量雙領域專家。騰訊雲、阿里雲、華為雲最具價值專家,Certified DevOps Enterprise Coach ,年度 IT 圖書最具影響力作者,多本技術暢銷書作者,極客時間《軟體測試 52 講》作者,新書《軟體研發效能提升之美》也即將出版。多次擔任國內各大技術峰會的聯席主席、出品人和主會場演講嘉賓。
前段時間我寫了一篇文章《如何用研發效能搞垮一個團隊》引起了業界同行大量的討論與關注,今天想繼續聊聊研發效能提升過程中另一個話題:“度量”。討論度量的目的不是爭論對錯,而是希望能夠引發大家對這一話題的深入思考。
1 度量失敗的案例
首先來看一個由於度量體系設計不當而引發“內卷”等不良行為的案例。
比如以“點選量”來度量自媒體運營的成果,那麼就有可能出現點選量顯著提升,但是公眾號的關注人數卻下降的現象。原因就是使用“標題黨”等手段誘騙讀者開啟連結,但是實際內容名不副實,幾次之後讀者就不會繼續關注該公眾號了。
2 時代變了,很多事物底層邏輯都變了
今天的度量為什麼容易失敗呢?正如我在之前那篇文章中提到的,面對變革,最重要的並不是方法和技術的升級,而應該是思維模式的升級。我們身處數字化的變革之中,需要將工業化時代科學管理的思維徹底轉為位元組經濟時代的全新思維。
對於軟體研發效能的度量,我們絕大多數時候還在用工業化時代形成的管理理念來試圖改進位元組經濟下的研發模式。但時代變了,很多事物底層邏輯都已經變了,工業化時代形成的科學管理理念在位元組經濟的今天是否還依然適用?值得深思。
本文將站在軟體研發效能的視角,來探討位元組經濟時代下研發效能度量中幾個必須要回答的問題:
- 研發效能到底要不要度量?
- 研發效能到底能不能度量?
- 研發效能到底如何來度量?
- 研發效能的度量指標如何來選取?
3 研發效能到底要不要度量?
要。這個問題的答案不容質疑。
現代管理學之父 Peter Drucker 說過,“沒有度量就沒有改進”,這一底層邏輯自始至終都沒有變過,只是工業化時代的度量和位元組經濟時代的度量在理念和方法上會有很多不同的地方。
度量對於研發流程改進的意義非常明確。工業化時代的實體產品研發與生產,其中的風險是相對明顯的,比較容易找到防範的方法,也分得清相關的責任。但是位元組經濟時代的軟體產品研發(已經沒有了生產),是通過越來越多工程師的數字化協作來推進的。參與研發的人越多,人與人之間的溝通成本越高,產生隨機偏差的概率也會越大,再加上軟體研發過程本身的視覺化程度很低,風險的可見性就容易被各個環節掩蓋,但它最終會在看不見的地方積累起來。如果沒有適當的度量體系去顯性化這些風險,結果可想而知,更不用談什麼持續改進和治理了。
度量對於人的公平性訴求也是必須的。“我雖然沒有功勞,但是我也有苦勞。” 大部分人可能只關注自己的付出,但並不關心付出所獲得的實際效果。作為管理者應該為“苦勞鼓掌,為功勞付錢”。而功勞和苦勞的體現也需要藉助客觀的度量資料來體現,否則團隊中的成員會逐漸陷入碌碌無為的窘境。
4 研發效能到底能不能度量?
明確了研發效能必須度量之後,我們再來看看一個更實際的問題:研發效能到底能不能度量?“要不要”和“能不能”是兩個層面的問題,“要”不表示“能”,就像“我要賺錢”和“我能賺錢”是截然不同的兩個問題一樣。
關於這個問題,業界有兩派截然不同的觀點,一派是以現代管理學之父 Peter Drucker 的理論為依據,主張研發效能能夠度量的;另一派是以世界級軟體開發大師 Martin Fowler 為代表,主張研發效能不可度量的。
在這個問題上,我的觀點比較中庸,我認為能夠度量,但是沒有完美的度量。原因有以下幾點:
4.1 度量本身的片面性無法避免
現實事物複雜而多面,度量正是為描述和對比這些具象事實而採取的抽象和量化措施,從某種意義上來說,度量的結果一定是片面的,只能反映部分事實。
管理者往往會把目標拆解為可度量的指標。但是,目標和指標常常並不是簡單的全域性與區域性的關係。目標的拆解過程看起來很順暢,是那麼地理所當然,但是當把拆解完的指標合併起來的的時候,結果往往讓人哭笑不得。
有一個笑話說的是,“你問人工智慧,我要找一個女朋友,像趙薇一樣的大眼睛,像朱莉婭·羅伯茨一樣的大嘴,喜愛運動,陸上運動、水上運動都會。人工智慧就根據這幾個指標給出了母青蛙的答案”。所以,指標和目標常常並不是充分必要的關係。
4.2 度量過程容易陷入區域性思維
指標是為了實現目標的,但是在實踐過程中,指標很多時候卻是與目標為敵的。
管理者常常把目標拆解為指標,時間久了以後,他就只知道指標,而忘了背後更重要的目標。如果目標是林,那麼指標就是木,時間久了就是隻見樹木,不見森林。這個時候忘記了目標是什麼的管理者就會變得非常短視。那些不懂資料的人很糟糕,而最最糟糕的人是那些只看數字的人。
在福特汽車的發展史上,有一段至暗時期。那些實踐經驗豐富,但是沒有上過商學院的的老一輩管理層被幹掉,取而代之的名校管理背景的資料分析師,公司試圖通過精細化的數字管理來實現業務的增長。由於這些資料分析師並不熟悉業務,所以就只能看度量資料,越是不懂業務就越依賴度量資料來做決策,最後使整個公司陷入了泥潭。
軟體研發也有類似的尷尬,為了更好地程式碼質量,所以就制定了嚴格的程式碼測試覆蓋率要求。時間一久,大家都機械性的追求這個指標,而忘記了當時設立這個指標的初衷,於是就出現了高覆蓋率的大量單元測試中沒有斷言這樣尷尬的局面。
4.3 度量資料的解讀具有很強的誤導性
度量資料本身不會騙人,但資料的呈現和解讀卻有很大的空間可以利用。很多時候,同樣的資料,通過不同的解讀會引匯出截然不同的結果,這點很容易被人為利用來達成各自的目的。
舉個例子,有研究人員問接受調查者一個問題:假如你得了絕症,有款新藥可以治癒,但是會有風險,20% 的服用者可能因此而喪命,你吃嗎?大多數人會選擇不吃。但是如果反過來問:假如你得了絕症,有款新藥可治癒 80% 的患者,但此外的人會死,你吃嗎?絕大多數人會選擇吃。實際上這兩個問題的基本資料是一樣的,但是得到的答案卻相反。原因很簡單,在前面的問題中,強調的是“失去”,在後面的問題中,強調的是“獲得”。人的天性會更喜歡“獲得”,而不是“失去”。
研發效能領域也有很多類似的案例,相同的資料到了不同的人的嘴裡就有了截然不同的解讀,由此做出的決策也會不同。
綜上所述,我認為研發效能到底能不能度量是要基於場景的,脫離了場景去談能不能度量沒有太大意義。就像沒有什麼東西本質上就是髒的,是放錯了位置的東西才是髒的。飯菜,在碗裡就是乾淨的,潑到了衣服上才是髒的。泥土,在花園裡就是乾淨的,抖落到了床上就是髒的。
5 研發效能到底如何度量?
那麼研發效能到底如何度量,以下是我的一些想法。
5.1 要傾聽管理者的度量訴求,但是不要照著做
在汽車還沒有被發明的時代,你問馬車使用者,你要一個什麼樣的交通工具,很有可能得到的答案是“更快的馬車”,如果你按著這個思路去做的話,就會陷入研究馬蹄設計、馬飼料優化的誤區,就不會有汽車的發明了。很多時候使用者告訴你的需求往往都只是自以為是的“解決方案”。
當管理者告訴你我要這些度量資料、我要那些度量資料的時候,你不應該一頭扎進資料獲取的細節中,完全按管理者告訴你他想要的去做,而是應該從本質上去理解管理者想要看這些資料背後真正的動機,管理者通過這些資料到底是想解決什麼樣的問題。要理解管理者的深層次需求,這才是問題的本質。只有這樣才有可能在此基礎上給出相對完美的度量方案。
5.2 度量應該是有層級結構的
高層管理者、中層管理者和一線工程師關心的度量維度肯定是不一樣的。不要試圖去提供一個看似大而全的度量體系,當你的度量體系能服務於所有人的時候,恰恰意味著它什麼都不能。
比較理想的做法可以參考 OKR 的實踐。先由高層管理者制定度量體系的總目標,然後中層管理者分解成可執行可量化的指標,最後再由一線工程師分解成工程維度的的指標。各個層級只關心當前層級的指標以及上一層級的目標,不應該出現高層過多、過細地關注下層指標。
5.3 度量的設計目標是要能夠引匯出正確的行為
度量從來不是目的,而應該是實現目的的手段。度量是為目的服務的,所以好的度量設計一定對目的有正向牽引的作用,如果度量對目標的負向牽引大於正向牽引的話,這樣的度量本質上就是失敗的。
舉個例子,現在國內很多軟體企業都使用 Sonar 來實現程式碼靜態質量的把控,為了推進 Sonar 在團隊內的普及,不少企業會用“Sonar 專案接入率”這樣的指標,也就是有多少百分比的專案已經在持續整合 CI 中啟用了 Sonar,來衡量靜態程式碼檢查的普及率。這個指標看似中肯,實際上對於實現最終目標的牽引力是比較有限的。使用 Sonar 的最終目標是提升程式碼的質量,只是接入 Sonar 並不能實際改善程式碼的質量,而且還容易陷入為了接入而接入的指標競賽。理解了這層邏輯,你會發現使用“Sonar 嚴重問題的平均修復時長”和“Sonar 問題的增長趨勢”其實更有實踐指導意義。
所以,一個好的度量,一定要為解決本質問題服務,並且要能夠引匯出正確的行為。
5.4 切記不要基於“比較思維”而採用“追星式”的度量
我們看到一個人獲得了成功,就會立刻認為他過去所有的行為都是那麼地有道理。我們看到一公司獲得了成功,就會覺得他們採取的策略和工程實踐是多麼有效。這正是“比較思維”的可怕之處。實際上,沒有哪家企業是通過盯住競爭對手而獲得成功的。
OKR 在 Google 的成功應用使得很多公司對此實踐趨之若鶩,但是通過使用 OKR 取得成功的企業又有多少?這種“追星式”的度量只能讓你陷入更深的內卷。
對於研發效能的度量體系,切記不要盲目生搬硬套“大廠”所謂的最佳實踐,也不要拿自己的度量實踐去和大廠的比較,你們的上下文不同、組織生態不同,這藥給大廠吃可以治病,給你吃可能致命。
5.5 度量不要廣撒網,而應該精準捕撈
不要在沒有任何明確改進目標的前提下開展大規模的度量,因為度量是有成本的,而且這個成本還不低。很多大型組織往往會花大成本去建立研發效能度量資料中臺,指望通過研效大資料的分析來獲取改進點。這種“廣撒網”的策略雖然看似有效,實則收效甚微。事實證明,度量資料中臺的建設成本往往會大幅度高於實際取得的效果。
比較理想的做法應該是通過對研發過程的深度洞察,發現有待改定的點,然後尋找能夠證實自己觀點的度量集合並採取相應的措施,最後再通過度量資料來證實措施的實際價值,這種“精準捕撈”的策略往往更具實用價值。
6 研發效能的度量指標如何選取?
這個問題太大了,很難展開。但是這裡想通過兩個典型案例來解釋指標選取的問題。很多時候,當我們無法解釋什麼是正確的時候,我們可以通過逆向思維嘗試著看看什麼是錯誤的,以此來給我們一些啟發。
6.1 “千行程式碼缺陷率”引發的血案
千行程式碼缺陷率是被大家廣泛熟知並且不少企業正在使用的一個程式碼質量相關的度量指標,但是這個指標真的能客觀反應程式碼的質量嗎?這個指標真的是一個合格的指標嗎?這裡我不直接給出結論,而是帶著大家一起來分析一下,讓你自己得出結論。
上面的圖給出了千行程式碼缺陷率的定義,即每千行程式碼的缺陷數量。假定一般情況下,團隊平均的千行程式碼缺陷率大概是在 5-10 的範圍。
現在我們有這麼三個工程師:
- 工程師 A 的技術能力比較差,實現需求 X 用了 20000 行程式碼,同時引入了 158 個缺陷,由此計算出工程師 A 的千行程式碼缺陷率 =7.9,這個值正好在 5-10 這個平均範圍內,所以從千行程式碼缺陷率來看,工程師 A 屬於正常水平,並不會引起大家的注意,屬於無功也無過。
- 工程師 B 是一個技術大牛,實現相同的需求 X 只用了 3000 行程式碼,但是也引入了 10 個缺陷,由此計算出工程師 B 的千行程式碼缺陷率 =3.3,這個值明顯低於 5-10 這個平均範圍,你以為工程師 B 會因此受到表揚?大錯特錯,工程師 B 很有可能會被判定為沒有進行充分的測試,被責令加強測試。
- 工程師 C 是一個有技術追求、努力想讓自己成為技術大牛的人,他實現相同的需求 X 用了 4000 行程式碼,但是由於目前的技術能力有限,所以引入了 58 個缺陷,由此計算出工程師 C 的千行程式碼缺陷率 =14.5,這個值明顯高於 5-10 這個平均範圍,所以毫無疑問,工程師 C 必然會遭受批評,被責令改進程式碼質量。
由此看出,基於千行程式碼缺陷率對這三個工程師的評價顯然是有失公允的。
更糟糕的是,之後的需求有可能會發變化。這個時候工程師 B 和工程師 C 的程式碼具有較好的可維護性,可以方便地變更,所以可以很快完成變更任務,並且基本不會引入新缺陷。而工程師 A 的程式碼由於缺乏設計模式的支援,大量程式碼需要重寫,同時還會引入了很多新缺陷。但是由於程式碼量夠大,工程師 A 的千行程式碼缺陷率依舊在平均範圍內。所以在現有的度量體系下,工程師 A 依然無功也無過,而工程師 B 和工程師 C 則繼續得到差評,因為他們的工作看起來太簡單了,明顯工作量“不飽滿”。
由此可見,千行程式碼缺陷率的度量體系是失敗的,其所傳達的價值觀與我們所期望的背道而馳。從工程師 B 的遭遇可以看出“我們不相信你能夠寫出高質量的程式碼”,從工程師 C 的遭遇可以看出“我們不鼓勵技術提升階段的陣痛”,而從工程師 A 那邊我們看到的是“我們歡迎那些平庸的程式設計師”,這些都直接違背了我們實際的價值觀。
上述的分析還是在沒有人為“粉刷”指標的前提下進行的,在實際工作中,工程師往往會採取稀釋程式碼的方式來降低千行程式碼缺陷率,而不是實際去減少缺陷數量。因為與減少缺陷數量相比,直接稀釋程式碼(比如:一行寫成多行、括弧必須換行、多寫註釋、多加空行等)的難度更低,而且更可控。所以我一直說,永遠不要低估工程師面對度量指標時的“創造性”。
此時度量體系的設計者可能很快會意識到工程師們的小手段,所以全新的“開發當量缺陷率”指標應運而生,這個指標用開發當量去替代千行程式碼數。開發當量是對開發工作量的一種合理估計,可以理解為原始碼編譯成的抽象語法樹 AST 的複雜度。與程式碼行數這類淺層統計相比,開發當量不易受到程式設計習慣或特定行為的干擾(比如換行、註釋等),這樣一來,想通過稀釋程式碼來降低程式碼缺陷率的路就走不通了。
乍一看,用開發當量似乎可以解決問題,但是當你深入思考後會發現,用開發當量可能會讓情況更糟糕。因為工程師依舊可以通過人為增加開發當量(比如減少封裝等)來降低程式碼缺陷率,只不過增加開發當量的難度比直接稀釋程式碼要大,這將直接導致“粉刷”指標的難度變大,進而陷入“演算法對抗”的窘境。最後的結果是工程師為了降低程式碼缺陷率,在錯誤的地方花費了更多時間和精力,而最終程式碼質量依舊沒有任何改善。
那麼到底是什麼地方出了問題呢?你靜下心來仔細想一下,程式碼行數和程式碼質量到底有沒有關係?如果有關係,兩者之間到底是因果關係還是僅僅是相關性?這時你可能會恍然大悟,原來程式碼行數和程式碼質量之間僅僅是相關性,根本不是因果性,程式碼質量不會因為程式碼行數變多而變差,所以試圖用千行程式碼缺陷率來對程式碼質量進行度量的大前提根本就是不成立的,從源頭上就錯了。這就好像森林火災率和冰淇淋銷量之間就是相關性,這個相關性是由天熱而發生關聯的,兩者之間不存在任何因果性。換言之,想通過降低冰淇淋銷量來降低森林火災率是完全行不通的。迷信千行程式碼缺陷率就好像扔磚頭還要看風向一樣自欺欺人。
那麼正確的做法是什麼呢?我們知道,只要缺陷可以很快被修復,那麼有缺陷就並不可怕,缺陷多也不可怕,我們怕的是每個缺陷的修復難度都很高,一個缺陷幾天都修不了,我們更怕缺陷修復對原有程式碼的改動會“傷筋動骨”。
所以我們完全可以採用平均缺陷修復時間 (Mean Time To Repair) 來衡量程式碼的質量。平均缺陷修復時間能夠更好地反映程式碼本身的質量狀況,以及團隊的技術成熟度。往往平均修復時間較長的程式碼都是複雜度高、耦合度高的程式碼。而平均修復時間短的程式碼則是結構相對清晰、命名規範、容易理解、擴充套件和變更的程式碼。相比千行程式碼缺陷率,平均缺陷修復時間對程式碼質量會有更強的正向牽引作用。
6.2 敏捷模式下工作量估算的是是非非
在敏捷模式下的工作量度量,到底應該用“故事點”作為單位呢,還是應該用“人天”作為單位?很多人可能覺得都可以,他們認為這個主要還是看團隊的使用習慣。其實這個答案是完全錯誤的,正確的做法是用“故事點”,而不應該用“人天”。
要理解其中的緣由其實並不複雜,因為工作量是量的概念,而人天是時間的概念。要搬一千塊磚,這一千塊磚就是工作量的概念。
搬得快,它是一千塊磚,搬得慢,還是一千塊磚。工作量本身的大小和時間是沒有關係的。
工作量與時間產生關係是通過速率這個概念。同樣搬一千塊磚,你每分鐘搬 10 塊,100 分鐘搬完;我每分鐘只能搬 5 塊,那就 200 分鐘搬完。所以,只有當速率確定了,才能把工作量換算成時間。
問題是當我們在計劃迭代的時候,我們是沒有辦法明確知道速率值的,速率會隨著很多因素動態變化,並不是一定不變數。比如工程師的熟練程度、是否之前處理過同型別的問題、需要參加會議的多少、家裡的各種瑣事都會對速率產生直接影響。因此我們無法將代表工作量的“故事點”和代表時間的“人天”等同起來。
為什麼很多團隊依然會直接使用時間來估算工作量,並認為“以故事點為單位”和“以人天為單位”沒區別呢?因為在他們的觀念中,速率是常量,所以工作量與時間就可以線性換算,所以這個看似“合理”假設,背後其實是一個巨大的邏輯錯誤。
7 總結
本文系統性探討了研發效能度量的方方面面,重點聚焦研發效能度量的具體實踐,同時通過千行程式碼缺陷率和敏捷工作量估算等具體案例討論了度量指標選取的常見誤區。
其實你會發現,研發效能度量的過程往往是對軟體研發全流程進行抽象和簡化的過程,但簡化就會帶來失真和扭曲,那些具有感性色彩、意味深長、需要反覆斟酌的地方消失了,只剩下言之鑿鑿的度量指標,稍有不慎,就會讓我們產生手握真理的幻覺。
那麼在雲原生的加持與數字化風潮下,企業應該如何快速融會貫通,推動研發效能升級?本文作者茹炳晟誠邀各位讀者,參加騰訊雲 CIF 工程效能峰會 - 數字化風潮下的企業研發管理探索論壇。來自不同企業的 5 位業內專家,將聚焦企業研發效能升級痛點,結合理論與實踐,立足企業發展,放眼產業共建,通過真實案例幫助企業更高效、更高質量、更可靠、可持續地交付更優的業務價值。
2021 年 10 月 19 - 20 日
CIF 線上峰會火熱報名中
更多精彩議程等你開啟!