與代碼結緣
小時候,看見鄰居哥哥在玩電腦,那時候我覺得,能控制電腦,讓它乖乖服從自己的指令,是一件太酷的事情。但由於各種原因,我錯過了幾次學編程的機會,因此我特別羨慕那些有條件學編程的同學。
上大學後,雖然沒能進入計算機系,但我們系的課程有部分涉及編碼。拿到第一張課表,看到“程序設計語言”這門課時,我感覺我的眼睛都在發光。終於能有機會接觸代碼,我激動不已,還沒等到開課,我就自學看完了第一章。還跑去機房搗鼓“Hello world”,從此我就走上了壘碼的“不歸路”。
大一的暑假,我從圖書館帶了一本《高質量C++編程指南》回家,這本書算是我代碼生涯裡裡程碑意義的一本書。到今天我能清晰地記得,當時我躲在屋子裡一口氣看完了它,雖然當時房間開著空調,但我居然出了一身的汗。那是我第一次意識到,原來自己對於寫代碼的認識和理解是那麼淺顯。也就是在那個暑假,我的生活開始和代碼綁在一起,一個“代碼狂熱愛好者”開始誕生了。
再開學的時候,我帶著滿腔熱情繼續投入到編程課中。老師在課上特地強調了我們的校訓——“止於至善”。但那時的我,並沒能理解這句話的深意。
努力,是主動找的辛苦
程序員這個行業中,女生並不多。許多人會帶著“有色眼鏡”看待女程序員,覺得女生不靠譜。我剛參加工作的時候,分到的也總是一些邊邊角角的工作,並沒有太多的技術含量。那個時候的我作為新人,盡力把自己的姿態放低,我常常安慰自己說,本來我也不熟悉系統,這樣的工作正好能讓我有時間上手,況且這些有缺陷的模塊,也確實是需要有人來完善的。所以雖然有些不服氣,但我並沒有抱怨,一心想著要努力做好分給我的工作。
大家都說女生做程序員太辛苦,而我始終覺得,任何工作都是辛苦的。在工作面前,性別是第二位的,我從來不認為女生應該得到一些特別的優待。而事實也證明,當我真的完美地完成任務之後,有色眼鏡也就自然消失了,別人不會再強調我的性別,不會再因為我是女生而不信任我的能力。所謂的“行業性別歧視”的問題,就這樣被我克服了。
工作一年後,我進入一個新的項目,開始負責一個獨立模塊。老代碼到手時才發現這是Demo版的“神級代碼”——只有堆砌的功能,沒有任何容錯設計,一點風吹草動就可能直接罷工。但偏偏這還是個底層模塊,一出問題,整個設備都不轉了。
我就像個救火隊員,不是在測試部查問題,就是在去測試部的路上。歷經了三個多月的撲騰,我逐漸熟悉了新模塊的業務流程,對其依賴的底層系統也有了較為深入的認識。代碼一天天穩定下來,問題單也收斂了,但我實在不能忍受日復一日地在沒有良好設計的代碼上打補丁,特別是新功能加入時,牽一髮而動全身。於是我做了個很大膽的決定,進行重構。
很幸運,我得到了主管的支持,他告訴我:“如果想做,就放開手去做,模塊交給你就是希望你把它給改造好。”我梳理了整個模塊的業務流程,保留了所有對外接口。然後,按模塊的基本功能進行子模塊分層,各個層次相互之間不再幹擾。特別是把複雜錯亂的狀態機抽象成表,避免了大量的重複邏輯判斷,閱讀主體代碼時看到的只有清晰的業務邏輯。
就這樣,我一邊維護老代碼,一邊自己擠時間去獨立完成自己的想法。重構完成時已經是版本交付的關鍵階段,我的主管頂住了版本的巨大壓力,力排眾議堅持將我重構後的代碼合入主線。代碼也相當爭氣,在後續需求不斷的情況下,兩年裡僅僅收到三張問題單。經過這次改造,我收穫了一個擁有良好架構的模塊,極大提高了後期工作的幸福感,同時也收穫了一個讓我受益至今的感悟:
個人成長取決於做了多少重要卻不緊急的事。而所謂努力,是指主動找的辛苦,如果不是主動找的,再多加班再多通宵也是沒有意義的。寫得又好又快的秘訣
後來我負責了三個模塊,看到隔壁組做的一個內部實現不錯,就想借鑑一下,於是,問題來了。這三個模塊中有一部分近似功能代碼,但每個模塊都有自己的一套實現和接口。一旦代碼變更,就需要修改三處,這樣很容易發生修改遺漏,如果後續還有其他模塊需要這種功能,又要重複再去造輪子。這正是我這種“懶惰”的程序員最害怕的事情。
是拷貝粘貼快速上版本,還是一勞永逸地解決問題?我選擇後者。當時的系統中沒有類似的公共機制可以提供接口,我希望能夠實現一個。這樣不僅能自己栽樹,也可以讓後人承蔭。雖然自己的第一個公共庫的需求很簡單,但我在借鑑了一些優秀公共庫的想法後還是花了足足兩天時間進行設計,代碼也是寫的無比小心,雖然簡單但在版本中收到的效果卻非常好。
對於程序員來說,工作的最大困難莫過於需求不斷在改變。 我多少是有一些“代碼潔癖”的,寫的不好的代碼,自己會看不下去。熟悉我的同事們也經常會拿我這種不斷持續優化代碼的行為開玩笑,戲謔地稱我是“又在那兒繡花呢”。但我認為,代碼一定是要好好寫的。
我所理解的“寫得又好又快 ”,其實是在工程進度和代碼質量兩者之間進行平衡。
在同樣的項目預期時間內,有些人習慣很快地寫好代碼,自然難避免錯誤會比較多,後期調試時間會很長;而寫代碼之前的我彷彿是站在岔路口,會先想想選哪條路能走的更好,想好架構和設計之後,再去做。我會更傾向於花費更多的時間在最初的代碼上,儘量減少錯誤和修改,縮短後期調試時間。
因為對於工程來講,也有一個“二八法則”,一旦越過了那條線,重新優化代碼的成本會高很多。所以從總時長上來看,我的方法往往是看起來“慢”,但其實是更“快”一籌。
多思考,才能提高工作效率
我記得我的師父曾經送給我一段話:“工作中有很多問題,不要抱怨,嘗試解決它。你不去解決它,換個環境你還是會遇到。怎麼提高工作效率,如何儘量做到自動化,把我們從重複的工作中解脫出來,這些都是值得考慮的事情。所以
不滿足於現狀,多思考,才能把手頭的事情做得更好。”這段話我一直銘記在心,自己也一直在不斷思考的路上。2016年6月,我參與了紅隼行動(即為比利時電信SIMBA項目,是Satellite虛擬接入創新方案的首個應用局點,是在城域實現競爭力突破的關鍵解決方案)。從前的我更像是一個“接鍋俠”,一直在完善做到一半或者出現問題的項目。但從這一次項目開始,我第一次參與到帶人做方案的全過程裡,整個人都很興奮,也收穫和成長了很多。
當時前方業務要求某特性能夠支持雙機熱備,雖然這項功能在我們系統已經有了,但能夠實現的業務並不多。如果按照原來模塊的交付要求,操作困難複雜,不僅時間上來不及,質量上也很難把握。面臨這樣挑戰,師傅的話又一次在我心裡重複著,“多思考,想想如何減少重複工作”。於是我和項目經理一起立下決斷,把雙機熱備的功能抽象出來,做一套框架。
框架做好之後,我沒有等到上設備的時候才去測試性能,而是在本地模擬環境上,用自己的數據庫和小工具構建了大業務量的場景,進行自測。而測試結果卻讓我大跌眼鏡。原本希望在20秒內傳完的80M數據,用了10分鐘才完成。我覺得這太不科學了,怎麼會這麼慢?問題到底出在哪兒呢?
我開始分析可能原因並逐個測試和排除,但令人奇怪的是,修改後的性能竟然還輕微下降了。雖然百思不得其解,但我不甘心,就和這個問題槓上了,我知道如果現在不解決,以後還是會出問題。我把數據傳輸過程中達到每一個點的時間都記錄下來,看究竟是哪裡卡慢了速度。之後終於發現,原來不是發射端和接收端的代碼有問題,而是中間過程我們用的基準版本里面某個模塊有問題,導致問題發生。
這個問題解決之後,自測也自然有了滿意的結果。代碼上線後至今主線零問題,成為DU部門首個零缺陷上車的標杆項目。而我也憑藉著貢獻的公共庫代碼,獲得2016年固網金碼獎。
我常常覺得,如果能夠把重複的東西抽取出來重構,不去做重複的事情,才有可能達到代碼零增長甚至負增長,做個有心人,勤于思考,就能夠提高工作效率。這一次的雙機熱備框架完成,不僅高質量,而且也為後續上車的雙機熱備特性提供了層次化的公共庫。很多需要實現這個功能的業務,都不必再寫那麼多代碼,可以直接拿這套框架去用了。
我是一個很容易有小小自我滿足感的程序員,自己做的東西能按照預期去進行,就會覺得滿意。而如果能夠通過我的工作和思考,最終減少了其他程序員的工作量,我內心就會有滿滿的成就感。
不忘初心,止於至善
數年後再回首,我才慢慢體會到自己大學的編程課中,老師提到的“止於至善”這四個字中包含了太多的真諦。
在工作最開始的幾年中我都是以最挑剔的眼光來看待自己的代碼:我曾經花十多分鐘去糾結一個函數的命名,只為恰到好處;也曾一旦發現代碼有可能腐化,就儘快進行重構,直到自己覺得已經到了極致,才可以暫時停下對這段代碼的修改。再後來,我在設計的時候慢慢懂得,不去過分追求某一個方面的極致,而是更多地考慮各個維度的合理權衡,現在,我也有意識地在軟件設計和編碼中去思考和體會妥協和灰度的藝術,做到合理地取捨。
每當我看到自己從前的代碼,都會感慨:“天啊,我當時怎麼會把代碼寫成這個鬼樣子?”這時慢慢地就能體會到,老師說的至善和完美都取決於我經驗和視野的不斷提升。
加入華為的五年以來,不論是獲得金碼獎,還是軟件王,這些稱號和光環一方面來說是對我努力工作的肯定,但另一方面更是在時刻提醒著我“不要因為走得太遠,而忘記為什麼出發。”因為人並不是僅僅在尋求結果,如果只是為了尋求結果,人很容易選擇走捷徑。而在走捷徑的過程中,就很容易迷失真實,甚至連滿腔的熱忱也會逐漸喪失。
我認為真正重要的是追求真實的意志,只要有了這種向真實前進的意志,即使這次失敗了,我們終將會達到終點。我自認為不算聰明,性格也相對木訥。要說優點,那就是對編碼的熱愛,以及熱愛所帶來的執著。我一直認為,把興趣作為職業,往往是挫敗感會遠多於成就感。但無論怎麼沮喪,在地上打幾個滾又爬起來,支撐自己一直堅持走下去的正是興趣帶來的熱愛。
我的內心深處依然住著那個希望能控制電腦的小女孩,仍然分分秒秒都在憧憬著有朝一日能搞定一個大型系統。
我不太清楚幸福究竟是什麼,但入行數年,每天醒來我仍對工作充滿熱情。我相信,把這個興趣當做職業,是正確的選擇。
閱讀更多 華為中國 的文章