谷歌的代碼審核和自動化測試的高效,是否會讓軟體開發者的工作效率低下?
谷歌強大的代碼審核,自動化測試,基礎設施無疑讓代碼的可維護性和項目的長期發展得到保障。Code Review 也會嚴格對待變數名、格式等,這是否會導致效率變低?
而且有時候 owner 在度假時,是否也會導致開發效率低下?
事情不能光看工作量。你說google的code review嚴格(其實我看起來也很水的),有自動化測試,設施完整,build系統統一,做東西就快,因為不會把時間浪費掉(譬如說寫到半死發現設計不行搞不出來etc)。你讓BAT的方法就算是997,干一年的系統編程,不一定頂的過人家一個季度的效果那麼好。
當你只有從事那些,每天【需要使用電腦的時間】低於【工作時間】的1/5的東西的編程工作時候,你才能明白這些流程的好處。如果你的工作就是只要加班4個小時就能比8個小時多出50%的產量的搬磚工作的話,那是無法體會的。這個問題的回答其實蠻反直覺的:這兩個方法,實際上反而節省開發時間,而且越長期的項目,效果越明顯。
這個反直覺的實踐會帶來一個很弔詭的副作用: 你很難讓一個從來沒有真正實踐過自動化測試的人去理解自動化測試的好處^^.
這個有點像如果你領了一個有時間限制的任務:全團隊需要越過一條大河,到河對岸去。最符合直覺的方法是趕緊帶著團隊開始往對岸游。 而且老闆看到你的團隊每天都離對岸近一點也很開心。但是最快方式,其實是先造一艘船。而沒有見過船的團隊,是非常難理解這一點的。
所以,我對完全沒有實踐過這兩種方法的人其實一般的說法都是, 先不要下結論,找個小的項目先推行下試試 ^^.
好吧, 解釋具體的原因之前,我來普及一下人生三大幻覺:
- 我的代碼沒有問題。
- 這個演算法跑起來了。
- 馬上就可以發布了。
事實上一個軟體工程師成長過程基本上就是不斷出現幻覺然後被打臉的過程。 這種幻覺不僅軟體工程師會出,離開技術崗位一段時間的技術管理人員也會出現。
一般來說你寫著寫著代碼突然有人在會上說, 我們打算明天就發出去, 你就知道,肯定有人又出現幻覺了。
這些幻覺出現的根本原因其實所有軟體工程的書都講過,最著名的書包括 《人月神話》 和 《The Psychology of Computer Programming》, 這些 70, 80 年代寫的書裡面的案例,每天都可以在很多公司裡面找到。可惜據我觀察,讀這些書對人的影響其實比我想得小的多,大多數老司機還是真的被現實按在地上狠狠的摩擦以後,才能學會怎麼做人。
我們可以從兩個方面來說為什麼能節省時間:
- 對於一個工程師來說,特別是比較初級的工程師,出現這種幻覺的原因是他沒有意識到, 把一個工程的實現代碼寫完,平均來說僅僅是完成了 60%[1] 左右的進度,如果最開始寫代碼的時候沒有考慮到代碼的可測試性, 這個比例可能會更少。
除非你的代碼極其簡單 (比如你寫個 hello world), 你的代碼裡面一定是有 bug 的, 只是 bug 的多少而已。那麼問題就來了, 你怎麼把這些 bug 找出來呢?
是的, 估計你已經想到了, 代碼審查和自動化測試。
綜合來看,這兩種做法是最高效的找出大部分潛在 bug 的方式。 除開這兩種方法以外,另外一個常用的就是人工黑盒測試。人工黑盒測試雖然不可少,但是相比自動化測試來說,少了可以快速復用的特點。自動化測試屬於高回報的投資, 一旦寫好了以後, 就算改一行代碼都可以重新跑一次,而人工測試相對來說遠沒這麼靈活。
於是如果你的開發高效 + 最高效的去除 bug 的手段(代碼審查 + 自動化測試)。 從整個工程角度來說, 是最省時間的。
而如果你不去做代碼審查 + 自動化測試, 代碼寫完黑盒測測就上線,不管覆蓋率, 也不管 boundery , 看起來好像上線更快,整個工程其實並沒有完成,你只是把問題推到了未來,於是我們就會看到這種情形:
如果把最後折騰來折騰去的把代碼搞穩定時間算進去,花的時間遠比這個長。
當然很多公司可能搞著搞著,項目就取消了。
- 對於技術管理來說,code review + 和自動化測試是一個非常重要進度管理的工具。 因為你知道,如果一個工程師告訴你, 我馬上就寫完了。 這句話的置信度基本上為 50%, 就是說五五開,可能他確實做完了,也可能他已經做飛了。
那我們換種問法: 你的 code review 和自動化測試寫完了嗎? 如果答案是 「是」, 那麼基本上這個項目進度不會有什麼問題了。
而對項目進度的正確信息,恰恰是合理分配資源最重要的依據。
記住: 一個測試過的軟體,才是一個完成的軟體。
最後,自動化測試並非一個黑和白的問題,事實上 一個覆蓋不完全的自動化測試,效果也遠遠好於完全沒有自動化測試, 呃, 這句這麼有哲理的話其實是 Martin Fowler 大神說的 - Martin Fowler - Wikipedia。
所以老是說沒有時間的同學,這個不是借口哦 ^^
PS: 問題裡面提到的 owner 休假一類的問題實際上工程管理的執行細節,這個和整個原理不相悖, 這塊需要工程管理者花很大力氣去慢慢梳理的, 比如之前在 Opera 每個 Module 除了 owner 還需要一個 co owner, 同時還要避免把代碼審查變成代碼審判一類的問題 . 工程管理並不是立一個 FLAG 就完了對不對 ^^
[1] 這個因項目而已,我自己的經驗平均在 60% 左右。
「一個正常的程序員,應該有大約一半的時間花在debug上。」
「當你覺得功能已經基本實現的時候,這個項目大約就完成了一半了。」對於一個code base很大的項目而言,有零零碎碎bug的代碼簡直是惡夢。對於一個公司來說,每個commit應該都是在本地跑完所有(至少一部分重要的)test,bug free之後再上傳到code base的。如果commit的代碼沒經過繁複的檢驗,有個小毛病,break了一個test,後面人就直接全崩了。即便他們知道這個failure不是他們造成的,他們也不知道他們新的commit是不是會造成這個failure,你相當於屏蔽了一個test。這樣所有人都對validation failure越來越不在意,整個code base就變成了一個充斥bug的垃圾站了。
這就是為什麼code base越大,往裡commit東西的時候越要經過嚴格的檢驗和測試。
對於這些巨頭公司來說,走得穩比走得快重要得多,一個人的小錯誤會影響太多人的工作。如果你是一個三個人的公司,那一個人犯錯誤,隻影響到另外兩個人,打個招呼就完了,犯錯誤的成本很低,所以開發效率很高。如果你是個好幾萬人的公司,你的錯誤可能影響到幾百甚至幾千人,就必須要把錯誤率降到最最低。
對於coding standard也是一樣的,因為你的代碼會被很多公司其他同事查閱(在他們需要了解你功能的時候不能總問你),同時也要在你走了之後被維護或者重寫,所以你要把代碼寫得可讀性盡量好。同時,可讀性越好的代碼,犯錯誤的幾率越小。越是艱澀「高端」的代碼,反而越容易出錯。
當然,任何事情都會有一個極端化之後邊際效益減小的過程,對於Google這種大公司,毫無疑問其個人開發效率是小於一些相對規模小的公司的,這是由開發者犯錯誤的成本決定的。所以他們要僱傭很多人呀!
但是對於一些做純加法的項目來說,bug根本不是問題,這些項目就是單純的線性加法,把各種東西拼在一起,每天做的都是相似卻不相關的內容,壞了也沒人在意。或許這就是為什麼我不喜歡寫網頁吧。變數名是非常核心的問題啊。名正則言順。格式難道不是一個快捷鍵自動刷出來么?
討論這個問題之前,我覺得先得說清楚到底「什麼叫做效率」?
Code Review等實踐對於產出高質量、可持續維護的代碼是非常有效的,這一點已經被不止一家成功的軟體公司證明了吧。如果一定要從效率的角度進行討論的話,我們可以先看看不同人眼裡的不同的效率定義:
1,效率=給定時間內寫出的代碼行數。如果按照這個定義的話,Code Review也好,單元測試也好,通通是效率不高的惡行。效率最高的做法,就是找一幫完全不會在意自己代碼今後將會怎樣被修改的工程師——對了,記得面試他們敲鍵盤的速度。2,效率=考慮到需要產出符合質量的產品,需要保證在一個需求、設計、開發與測試周期中以低投入獲得合理的產出。如果按照這個定義,在設計、實現的過程中付出額外的成本:通過Code Review,CI等方式保持代碼的水準,通過Unit Test的方式使得代碼具有更好的解耦特性等,但這種成本的付出顯然會大大減少測試和伴隨需求變更而來的修改的投入。3,高效率=消除浪費(不做不需要做的事情)。如果按照這個定義,出了2中考慮的需求、設計、測試中的投入外,還需要引入更多的消除浪費的實踐。例如,按照敏捷建議的方式小步快走,通過協商機制識別出真正具有價值的需求,保證交付的價值等等。當然,在這些實踐的背後,必然需要一個具有良好工程實踐的團隊通過好的工程實踐進行保證。考慮到團隊的規模,協作的開銷,很多時候必須設置必要的規則來最小化溝通成本。簡單的說,環境決定想法。想法這種東西,在給定的背景下總有合理的成分。但缺乏對一件事情背後的理解,簡單的結論化某種存在的實踐,實在不是聰明的做法。當從來不code review的半吊子工程交到你手上維(ca)護(pigu)時,你就知道code review的好了。
而且,你前面的人得了效率高的美名,效率低的鍋還得你來背。看效率是怎麼定義吧?說說某些一線公司的情況:
- 本周上線兩三個項目,下周因為數據輕微波動回滾四五個功能點排查問題
- 某某或某團隊偷偷摸摸上線了個東西,出現故障整個團隊摸不著頭腦到處問那個時間段你幹了啥他幹了啥誰誰誰幹了啥,無盡地踢皮球四壁大賽- 要做一個新項目的時候,發現這裡那裡都是坑,都是那些已經離職n年的傳說中某某挖的坑,誰碰誰知道如果因為每天的各種看數據查原因回滾找人填坑四壁然而忙得屁滾尿流廢寢忘食還覺得自己很有效率,領導還要在9點後巡邏公司美其名曰提供夜宵並且要在深夜發朋友圈感慨一天的滿足感,讓員工997,這不是效率!是浪費地球資源!答案自然是否定的,經常出差的人都知道:條理清晰的旅行箱能夠放置更多的衣物,為何?衣物凌亂扔進箱子的時候,相互之間沒有被利用到的空隙非常大。
研發工作流程調整和定義工作的核心與衣物整理類似:有了規範的流程,那麼效率反而會提升的更多,題主所說的owner在休假往往是小概率事件,在一件事情上,大概率事件佔據大多數情況的時候,建議少數服從多數。另一方面沒有流程的後果就是 混亂,各種問題找不到介面人,也不知如何處理。超人也沒辦法天天滿世界飛去救火,他每天也只有二十四個小時。另一個可能性是流程丟失可能會導致大量的人力和時間成本浪費。舉個例子,我們做代碼靜態分析,按照美國國家標準委員會提供的基礎數據,代碼階段修復一個Bug,能夠比產品發布後定位源代碼,修復和回歸測試工作節省約6個工時。但如果你沒有這種流程或者形同虛設,那工時仍舊會浪費。能夠不出現百度的消息已讀還不斷提醒的話,那麼還是很有必要的。
我最久的一個change交了62天。。。
做demo自然是效率比不過bat
寫測試和code review所花的時間,遠小於因為它們而減少的debug的時間。適用於平均情況,不適用於個案。
一個人搞個 apps,寫一段script, 半個月完事,無售後,甚至完全開源,情形就像獨行俠客,或者藝術家,可以講究自由,講究個性。
大的項目,周期長的項目是一場戰役,工程師都是衝鋒陷陣的小兵,如何組織,如何面對逃兵,戰鬥減員,兵種之間如何協作,是取勝關鍵。所以工具,流程,紀律,這些枯燥的東西都必不可少。code review嚴格就相當於肯德基的那種流程一樣,你就算是個小學沒畢業的都會炸雞腿,因為各方面都設計好了,code review嚴格一點的話,就算你是個渣渣,不合格你也入不了庫,慢慢的你總會有點長進的,只要跟上節奏,你就是個機器一樣的,生產代碼,豈能慢?
變數名,格式這些大公司都有規定的,一個函數的行數都規定死了,有的大公司連遞歸都不能給你用,還有圈複雜度,函數傳入的參數不能超過5個之類的,這些東西,講真,pc-lint什麼的跑出來不過你就重寫去吧
推薦閱讀:
※七八個函數,兩三門語言㈠
※NB-IOT 終端開發板對接 NB-IOT 網路模擬器調試與測試記錄
※一周工作所用的日常 Git 命令
※為什麼我的egg-bin在Visual Studio Code中調試功能無法使用?