(轉)2年重寫10年279萬行代碼,……他是怎麼做到的?華爲這些人爲了什麼

 

 

                                     改變,做最好的軟件

                                                                                        劉文傑

 

2018年年底,華爲網絡金碼獎頒獎典禮會場掌聲雷動,看着臺上我們團隊的3名員工站立正中,舉起象徵着“碼農”至高榮譽的獎盃,我在臺下思緒萬千。

 

兩年前,公司5G微波等新產品啓動開發,工作量幾近翻倍,爲提高開發效率和質量,我們一邊頂着巨大的交付壓力,一邊痛下決心,用全新理念和架構重寫10年存量的279萬行代碼,將其優化爲90萬行。

 

這就好比汽車一邊高速行駛,一邊“換輪胎”,難度非常大。過程中雖充滿了煎熬和不被認可,但當看到一個又一個軟件精英在團隊湧現,交付的代碼在多個維度高於華爲英國安全認證中心的要求,產品及時、安全、可信地交到客戶手中,我覺得一切堅持都值了。

 

                                            革自己的命,義無反顧踏上架構重構之路

 

我們是公司傳送網軟件平臺開發部門,類似於做手機操作系統的部門,不過我們開發的是波分、微波等網絡通信產品的軟件。手機操作系統讓大家享受智能手機的各種功能,離不開我們開發的軟件。

 

作爲平臺開發部門,我們總共支撐十餘款傳送產品的軟件開發工作,交付壓力一直比較大。時間來到2016年,產品線開始集中開發5G微波等六七個新產品,而且集中在一兩年內推出來並支持測試和商用,時間緊,任務重。面對幾乎翻倍的工作量,如果沿用傳統的基線效率來開發,可以想象大家將一直處於疲於奔命的狀態。

 

其實,過去我們在組織運作、工程能力等效率提升方面做了大量的努力,收效還不錯,但也感覺進入了瓶頸期。原因很簡單,問題的根源在我們的傳統軟件架構上。傳統軟件架構是建造軟件大樓的“基座”和“框架”,已經用了十來年,隨着環境的變化以及新技術、新功能特性的引入,架構難免腐化,就像一部用了很久的手機,開始變得慢、“笨重”,問題還多,再怎麼修修補補都無濟於事,除非做個大手術。

 

5G微波產品的爆發式啓動開發,更將我們的開發效率問題逼上了梁山。不破不立,2016年年中,傳送產品線的上級主管引進了一名海外研究所的專家,期望我們與他合作,在架構上做些探索,我作爲團隊新上崗的LM(Line Manager,資源線主管)承接了該工作。經過與這位專家深入討論,發現他的業務抽象建模思想完全可以解決我們跨產品、跨芯片重用的難題。

 

用一個不太恰當的比喻,他的架構和我們傳統架構相比,類似於“活字印刷”與“刻版印刷”之別。以往我們每支持一款新的芯片都需要重建一套軟件模型,但他幫助我們構建一套統一的、可靈活拼裝的通用模型,可以極大提升軟硬件解耦和重用能力。用上這個架構,我們可以實現“一次開發,多次使用”,而不是之前的“使用一次,開發一次”,效率大大提高。

 

我們成立了一個技術項目組,花了小半年時間仔細驗證,最終確認抽象模型與實際業務匹配,方向是可行的。但擺在面前的挑戰非常大,需要使用新的架構方法重寫原來近300萬行代碼。對於一個80餘人的團隊來說,除去正常的產品需求開發,還需要額外完成架構重構,這幾乎是不可能完成的任務。

 

“太冒險了,萬一完成不了5G微波的交付,影響太大了。”

 

“使用老架構,雖然效率低、問題多,勉強也能把產品推出來。”

 

“老架構大家都在罵,我們能不能做個軟件,未來6到8年不被人罵?”

 

……

 

經過多次研討, 大家逐漸統一了意見:研發應更關注長期,不能因爲眼前的一點風險而放棄對未來的追求。但風險也不能不顧,爲此,我們制定了一份詳盡的計劃,並且邀請了產品線3位軟件牛人加入,再加上本部門五六位軟件高手的投入,組成了一個10餘人的小團隊探路,準備殺出一條血路,革自己的命。

 

                                             寫最優秀的代碼,不“爽”不休

 

架構重構就像把老房子推倒重建,代碼就是高樓大廈的一磚一瓦,沒有高質量的代碼,任何好的架構都會演變成一個壞的架構。在重寫近300萬行代碼之前,大家對什麼是最優秀的代碼進行了討論。

 

寫代碼就像是藝術創作,優秀的原則很難形成統一標準,而軟件總工程師申力華常常掛在嘴邊的“爽”字,成爲我們對代碼的一致追求。“爽”是什麼概念?現在回頭來看,其實就是“Clean Code”,代碼要簡潔、易閱讀、易重用、易擴展、易測試、高可靠。其次,大家一致認可函數要短小、文件要小,函數深度不能過深、文件不要網狀依賴……

 

要寫出“爽”的代碼,第一個面臨的就是編程語言的選擇。C++在公司已經用了十幾年,我們都清楚C++的複雜,都對C++代碼中經常遇到的內存管理問題深惡痛絕。幾個技術專家在工作之外,深入學習和實踐了C++11,深知C++11在編碼效率和安全性上具有天然的優勢,而且C++11已經得到業界的認可。但C++11在華爲產品中無應用經驗,無支撐工具鏈,有人認爲最好等配套工具成熟後,再切換編程語言。在沒有經驗和工具支撐的情況下,誰敢去脫一層皮?但最後大家還是統一了認識,不脫皮,何來脫胎換骨!編程語言應該切換成C++11,在使用中催熟工具。

 

爲了讓我們的架構約束得到落實,爲了讓代碼簡潔,我們部署了諸多代碼門禁,不符合要求的“磚瓦”連“施工場地”都進入不了。我們參考優秀開源代碼庫的要求,制定嚴格的標準(如函數最大圈複雜度不能超過5,函數代碼、函數行數不能超過30行),超出門禁標準的代碼不允許入庫。嚴苛的門禁對固有的編碼習慣形成巨大的衝擊,所有代碼都需要白盒測試(注:在知道目標功能的前提下采用的一種測試方法,與黑箱測試法不同,白箱測試法關注程序在設計盒定義方面的缺陷與錯誤,故要求對程序代碼本身要有較詳盡的瞭解)覆蓋,因此帶來了成倍的編碼工作量,以至代碼一度堆積到上萬行無法上庫。一時間,團隊中“認清現實、杜絕理想主義”的呼聲越來越高。

 

我們進行了激烈的辯論,雖然對絕大多數人來說,蛻變是一個痛苦的過程,但是大家也都認可好的代碼能夠帶來質量和效率提升的價值。因此,我們解剖了從編碼到上庫的所有環節,有什麼問題就解決什麼問題。比如支撐工具PC-Lint不支持,我們就找到替代的開源工具Clang-tidy;語言和架構難,我們通過牛人帶牛人,讓專家手把手教;門禁嚴格,我們提升門禁執行效率、本地部署門禁檢查項,在同等的時間內可以多次執行門禁,在實戰中逐漸改變編程習慣。

 

在追求極致的過程中,團隊成員互相檢視,時刻切磋,不留情面地駁回一切不“爽”的代碼。部門一名骨幹成員興沖沖地加入到該重構項目,由於是公認的軟件高手,他第一次信心滿滿地提交了代碼,但被評審人員無情地駁回了:“你這個設計不夠簡潔,還需要考慮異步場景的擴展性。”通過不斷修改、提交,一共被駁回了8次。在開始的幾次被駁回時,他雖然內心非常不服氣,但經過討論和深挖,發現確實可以找到更好的設計,最終將原來需要500行代碼實現的功能現在使用200行即可實現。團隊屢“駁”屢戰,不“爽”不休,每一處代碼的設計與編碼只要覺得還可以更好,就持續優化,直至無可挑剔。新技術的引入,更好看的代碼,高手間切磋帶來的快感,讓大家又找回了編程的樂趣。

 

一羣軟件專家在自己的“獨立王國”中,恰同學少年,揮斥方遒。 

 

                                                  進度與質量重壓下的選擇

 

技術問題雖得到解決,然而更大的壓力來自外部。交付過程中進行軟件架構優化無異於飛行途中換引擎,速度必然受到影響。架構優化的優勢要兩三年才能凸顯出來,當下感知沒有那麼明顯,還因爲人力限制等因素,給人感覺“你飛得更慢了”,質疑聲不斷。

 

內部研發過程中因爲進度的延遲,多次受到產品線的投訴。產品線不斷地發出預警郵件、不斷地在各級會議通報風險,產品部和我們團隊都承受着巨大的壓力。

 

2017年年底,我們迎來了最艱難的時刻。5G微波正式進入預商用階段,距離某大T運營商客戶測試僅有三個月,我們還有幾萬行代碼沒寫出來。產品線判斷按時完成任務的風險巨大,投訴接踵而至。按照以前的方法,面對一個有進度壓力的需求,複製一個代碼,稍作修改即提交是最方便快捷的,雖然這種方式可能在後期問題會比較多,但不會出現大面積延遲交付的情況。

 

但當時我們的架構已經發生了天翻地覆的變化,要求和標準都有了更高的基線,開發進度受限。是堅持對代碼的追求,還是降低標準以滿足眼前的交付進度?

 

團隊內部一直有兩種不同聲音,每隔半個月,雙方就“房間具體要裝修到什麼程度”進行討論博弈。“保守派”認爲,大堂搞豪華點就行了,其他的簡單裝修,這樣可以快速交付,面對產品線的壓力小一些;“激進派”堅持高標準,所有房間的裝修必須用最好的方案、最好的材料, 要做良心工程。從我的角度來說,對代碼最高的要求是我們的初心,必須堅守,質量差的材料也可以完成房屋裝修,但壽命不長,還時常漏水漏電、牆皮脫落,我們寧願暫時苦一點,也要保證長期不出問題。

 

面對外部壓力,我們也不是一個人在戰鬥,時任產品部部長王春鈿、流程負責人楊曦給大家儘可能爭取更寬鬆的外部環境,並爭取到產品線管理層的支持,不斷給大家釋放壓力。同時,我們預定多個會議室封閉開發,大家把手機統一放在“停機坪”上,全身心投入。那段時間大家一個星期不回家是很正常的事情,累了困了就在公司打地鋪。

 

堅持高質量代碼交付,讓我們實現了以質量換進度。以前還是老架構時,寫代碼時間短,可能兩個月就寫完了,但後續問題多,解決問題也要一個半月,而且再擴展新功能很麻煩,投入大;如今雖然前期寫代碼要兩個半月,但後續問題少,解決問題只要半個月,擴展新功能很容易、投入小。

 

經過一段時間的緊張開發,某大T運營商客戶測試的幾萬行代碼也按時交付了,而且質量比之前更高。

 

                                               從量變到質變,奇蹟發生了

 

就在我們沒日沒夜開發時,內部測試發現了某芯片存有一個致命的設計問題,可能需要改片。面臨數百萬美元的改片費用,產品線認爲芯片早期驗證存在疏漏。一紙通報批評落到了我頭上,整個團隊籠罩在不被信任、壓力無處訴說的陰霾之中。當所有人認爲只有改片這條路時,我們沒有放棄。幾名專家通過連續一週的論證,找到了一條可以用軟件來解決芯片缺陷的方案。再經過一週的編碼與驗證工作,在某天的凌晨三點,驗證項全部通過,大家一片歡呼,喜極而泣,不僅因爲節省了數百萬美元,更是因爲我們通過智慧,解決了一個原以爲不可能解決的問題。

 

這個致命問題的解決,只是我們這兩年來遇到的衆多問題中的一個,類似的挑戰和壓力無處不在。新架構、新技術與現有人員能力的不匹配帶來的挫敗感,產品線的不斷投訴和質疑帶來的無助感,有時讓大家產生動搖。有一天,一個關係要好的PL(Project Leader,項目主管)骨幹向我提交了辭職信,正焦頭爛額的我猶如當頭一棒。他說,我很清楚事情的價值,但實在太辛苦了,還不被認可。靜下心來,我和他掏心掏肺地聊了很久,他理解當下兄弟們的難,現在正是缺人之際,答應等過了這段時間再走。

 

那段時間對我來說,壓力非常大,績效受到影響,連續兩年拿了B,要好的朋友都勸我換個地方,但我還是想把事情做完,雖然不被理解,也無處訴說。有個週五晚上部門組織看電影,當天剛被產品線投訴,我心情非常壓抑,電影很歡快,歡笑聲此起彼伏,但我完全沒看進去,坐在昏暗的影院裏,一個三十多歲的大男人,眼淚止不住地流下來。

 

中途走出影院,外面下着淅淅瀝瀝的小雨,我攔了輛出租車準備回家,但想到公司肯定還有同事在加班,還有很多問題需要解決,毅然讓司機調頭回到公司。使命還未完成,我們還須堅持。

 

項目進行到中後期時,部門60%的人員都加入到了新架構重構工作中來。隨着開發活動的深入,大家的能力也逐步得到提升,從量變到質變,奇蹟就此發生。大家突然發現,門禁失敗次數、被Committer(代碼提交者)駁回的MR(提交請求)個數越來越少;白盒測試覆蓋率日漸提升,迭代期間缺陷密度遠低於歷史水平;代碼直觀漂亮,書寫行雲流水。

 

新架構、新代碼帶來的好處終於開始顯現。平臺代碼總量實現了從297萬行到90萬行的“瘦身”,我們的開發效率得到極大提升,開發相似的單板要修改的代碼量比以往減少一半以上,更少的人力便可支撐現有業務。至此,交付逐步趕上進度,團隊也迎來了5G微波產品的成功,5G微波和波分新產品高質量地通過120場次的客戶測試。我們還意外發現,我們開發的新代碼在代碼重複度、函數圈複雜度等多個關鍵指標上優於華爲英國安全認證中心的要求。

 

                                             撥開雲霧見月明,軟件“場”已經形成

 

兩年多來,隨着一羣有追求的同事敲出一行行優秀的代碼,團隊形成了一種軟件“場”。大家已經形成一種共識,“我不願意成爲破壞軟件架構和好代碼的第一人”。當時跟我提離職的PL最終也留了下來,我們清楚地知道,所做之事,值得一生付出。

 

如今公司越來越重視軟件工程能力提升,計劃用5年時間,在ICT基礎設施領域實現爲客戶打造可信的高質量產品的目標。今年年初,公司總裁任正非在《全面提升軟件工程能力與實踐,打造可信的高質量產品——致全體員工的一封信》中提到,“我們要從最基礎的編碼質量做起,視高質量代碼爲尊嚴和個人聲譽”,對此我感觸良多。

 

高質量代碼就是我們心中的信仰。迎着朝陽前進,做最好的軟件,我們一直在路上。希望每個人都有勇氣做正確的事,有決絕的信念堅持到底,用代碼築起心中的殿堂。

                                                                                                 -END-

轉自https://mp.weixin.qq.com/s/O4EB17sfI3SguEwTvgGL9Q

和華爲心聲論壇http://xinsheng.huawei.com/cn/index.php?app=forum&mod=Detail&act=index&id=4516577&search_result=1&p=1

目前csdn中還沒有,特拿來分享一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章