哪個蠢蛋寫的爛程式碼?

發表於2016-08-30

最近看到一個問題,叫做「你們會因為程式碼爛,而入職兩三天選擇離職嗎?」。

其實早先有過一些關於程式碼質量的討論,比如《關於爛程式碼的那些事》、《你的程式碼寫的很爛》。這讓很多程式設計師感受到共鳴,大家紛紛出來吐槽。

大家都在抱怨同事的程式碼寫的爛,前同事遺留下來的程式碼bug多…… 那問題來了,寫這些爛程式碼的人都去哪了? 好奇怪哎!

遺憾的是,你既可能是那個吐槽別人給你留下了麻煩,也可能是別人嘴裡那個製造麻煩的人。

非常有幸,我在維護一些歷史超過10年,歷經無數代優秀工程師開發迭代的專案。作為一個工作超過6年的「老人」,我有話說。

筆者總結,其實最難的不是自己寫程式碼,而是維護別人寫的程式碼,在複雜的邏輯中找到某一個隱藏得很深的bug,或者在某個(些)位置新增一些程式碼以實現新的功能。你需要按照最初實現者的思路去理解,這往往是最難的,這個過程中非常讓人容易產生挫敗感和不良情緒。

如果原作者仍然在職還好,有問題直接去問,但假如他已經離職,你很可能偶然會遇到下面的問題:

  1. 原作者設計得太複雜, 一點小的改進都要大費周章,完全掌控他的程式碼需要不少時間。
  2. 程式碼效能不好。之前因為使用者量和訪問量太少而相安無事,現在問題突然爆發了,拖慢了整個應用甚至影響到基礎設施。
  3. 想要修改功能時卻發現程式裡充斥著各種無法理解的邏輯,改完之後莫名其妙的bug一個接一個。

在程式設計師這個職業裡面,英雄主義實在太普遍了。有無數的理由說服領導、PM和自己,要重新造個輪子,因為大家都認為自己天下無敵了,但是又不好承認看不懂別人的程式碼。如果你的個人影響力和表達能力有限,沒有足夠的理由說服其他人選擇這個輪子,又不願意花時間推動和完善,那麼最後的結果是,你認為這麼美好的東西,真的只是你這麼認為。等你不再維護了,離職了,下一個人又會迴圈這個過程… 等幾年之後,專案是越來越大,但是裡面大量的程式碼都是dead code,也就是無作用的程式碼。而且新人還不敢動,尤其是裡面有一些magic number,複雜演算法片段。

我對命名這件事做的極為不好,大部分的命名除了慣例,就是從各種開源專案裡面學到的用法和套路,所以我建議所有入行的人盡最大的能力學好英語。我之前見過一個英語極好而且非常喜歡閱讀英文原著的工程師,但是他寫程式碼很「飄逸」,怎麼說呢, 就是他會直接用英文原著的一些詞語作為變數名字,逼格極高,但是我經常得谷歌翻譯了,因為看變數名完全不懂這是啥啊。有時候還得問他,他總是拽拽的說,這個是因為XXX典故……,恍然大悟。

看程式碼就可以看到作者的性格和風格,比如有的人喜歡用設計模式,有的人喜歡把新學到的程式設計技巧強行放到專案裡。高階特性齊飛,一眼瞅去:高階。但是對於真的高手來說,其實露怯了,因為用的人根本沒懂正確和合理的使用場景呢。 一個真實的故事,在一次程式碼評審中,我們質疑了一下「為什麼在這裡要使用裝飾器?」,結果對方的迴應是:「因為這樣顯得逼格高…」,我當時心中千萬只羊駝呼嘯而過,想象下我的心理陰影。

但是不是所有前人寫的都比自己差呢?其實不盡然,甚至於是可能會讓你不願意接受的事實。我以前也很唾棄別人的程式碼。當我看到一段不符合自己價值觀的程式碼,理所當然認為這毋庸置疑的寫的爛,於是我刪掉了那段程式碼,用自己認為更好的方法重新寫了一遍,心情極好,覺得我挽救了這個專案。當我對這部分業務邏輯熟悉了之後,回頭再看,發現我所刪掉的那段程式碼其實用的處理的方式是最恰當的,而我重寫的雖然Python語法寫的很好,但可擴充套件性很差。

其實有時候我們不理解的,不是人家用的差,而是我們的格調低。我開始收起我的傲慢,不會一上來就指責別人,對不甚瞭解的領域保持敬畏,以免看起來像個小丑。

上面的也是在吐槽,我還是說點對寫好程式碼的理解吧。

程式碼是給人讀的,順便讓機器執行上面這句話我非常認同。好的程式碼是什麼樣子的呢?

Bjarne Stroustrup(C++之父)說:

  1. 邏輯應該是清晰的,bug難以隱藏。
  2. 依賴最少,易於維護。
  3. 錯誤處理完全根據一個明確的策略。
  4. 效能接近最佳,避免程式碼混亂和無原則的優化。
  5. 整潔的程式碼只做一件事。

Michael Feathers(《修改程式碼的藝術》作者)說:

  1. 整潔的程式碼看起來總是像很在乎程式碼質量的人寫的。
  2. 沒有明顯的需要改善的地方。
  3. 程式碼的作者似乎考慮到了所有的事情。

可以感受到,對好的程式碼的理解有很多共通的地方:

  1. 程式碼簡單,程式碼意圖明確,其他人才容易與你協作。
  2. 可讀性和可維護性要高。
  3. 以最合適的方式解決問題。

和大家共勉,不要做別人嘴裡的「蠢蛋」。

— 分割線 —

Python語言給外人第一印象就是簡單,上手快,有其他開發語言經驗的人一週就可上手工作,好像Python就是這麼簡單似得。可是為啥合適的Python高階開發者這麼難找?因為絕大多數開發者都止步於能完成工作這個程度,也就是我們經常自嘲的一個詞「碼農」。

不記得在哪裡看過, 程式設計師有三種(我重新潤色了一下):

  1. 拿錢幹活,不爽就換 – 程式設計師只是一份工作。
  2. 只要能實現功能就好,學習進步太累了。這年代做技術沒有管理掙錢多,技術搞得再好有什麼用? 還不是買不起房啊。這年代關鍵是你認識多少人。你是不是有眼光去一個能上市會讓你暴富的公司,能不能唬住粉絲兒和投資人。
  3. 熱愛程式本身的人, 這些人可能只有1%, 他們有目標的寫程式, 他們願意思考, 願意聽取正確地/更好的方法, 他們會熱愛學習新的東西。

現在產品開發迭代非常快,一週要上多個版本,每天要提多個Pull Request,對於前2種人,只能疲於應付工作,怎麼樣能在天賦不夠又不想多花時間進步的前提下完成工作,還能到領導的好評呢?這是一門藝術呢……

優秀的工程師在思考、重構,「其他」工程師在給自己找理由:「怎麼組織程式碼、怎麼提升執行效率、原理是什麼」這些重要嗎?程式碼能跑起來不就完了。需求這麼多,做都做不完,哪有時間考慮怎麼做得更好啊?

明年的今天「其他」工程師還寫一樣的程式碼, 唯一不一樣的是Ta老了一歲。

對於這種「其他」工程師,我也確實沒有辦法,每個人有自己選擇生活和工作的權力,我絕對尊重,本文也不是給這些人看的。假如你不滿意現狀,希望做得更好,但是苦於不知道自己進階,我分享下自己的經驗。

1. 多看書,多讀其他人的部落格,閱讀優秀的開源專案的程式碼甚至語言本身的原始碼。這是一個長期的、瑣碎的、需要學習之後記憶和實踐的過程,看程式碼要思考別人為什麼這樣寫,組織結構為什麼這樣用,這樣寫程式碼為什麼快。整個過程就是進階。

2. 想好了再開始寫。大家都知道,核心的、重要的系統的程式碼上線後改動起來會很麻煩,非常有可能給未來留大坑,甚至於要耗費以年為單位的時間來填。所以前期的資料庫表結構設計、工程實現這些東西要先想清楚了再開始寫。

3. 給自己提要求。實現過程中不斷的提高要求,這個要求就是比你現有的能力要高一點點。一段程式碼寫出來的時候考慮一下會不會有比自己寫的好的方法,之前有沒有遇到過別人的實現借鑑下等等。

4. 選擇更強的隊友。遇見什麼樣的人,就會變成什麼樣子的人。去一個身邊技術水平都比你爛甚至只是相當的環境,你能提高的空間非常有限。遇到一幫厲害的隊友,能幫助你坐上進階直通車,前提是你的心理素質要高,要不然長期的受到別人吐槽會產生大量不良情緒的。

5. 對別人吐槽狠。這是我的個人祕笈。之前我寫程式碼也沒有那麼高的要求,後來在程式碼評審的時候,我為了證明比人程式碼寫的爛,不惜花費大量時間找各種證據吐槽別人(不能說人家寫的爛,但是又寫不出來更好的,做這種嘴炮啊),這個過程對我有極大的能力的提高,也包括搜尋資訊的能力。而且你吐槽了別人,別人正憋著勁還回來。你總不希望這件事發生吧,所以你只能讓自己的程式碼寫的更好,這無形中讓你對自己的程式碼要求要高了很多。

可能有一天, 看到一段程式碼,罵了句「哪個蠢蛋寫的爛程式碼?」 結果git blame一看原來是自己寫的。恭喜你,你進階了!

最近看到一個問題,叫做「你們會因為程式碼爛,而入職兩三天選擇離職嗎?」。

相關文章