哪個蠢蛋寫的爛代碼?

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

其實早先有過一些關於代碼質量的討論,比如「關於爛代碼的那些事」,「程序員的日常:哪個蠢蛋寫的爛代碼?」,「你的代碼寫的很爛」。這讓很多程序員感受到共鳴,大家紛紛出來吐槽。

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

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

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

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

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

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

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

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

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

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

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

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

代碼是給人讀的,順便讓機器執行

上面這句話我非常認同。好的代碼是什麼樣子的呢?

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一看原來是自己寫的。恭喜你,你進階了!

無恥的廣告:《Python Web開發實戰》上市了!

歡迎關注本人的微信公眾號獲取更多Python相關的內容(也可以直接搜索「Python之美」):


推薦閱讀:

LaTeX 代碼有沒有統一的規範?
編程中如何給變數命名?有哪些規範的做法值得學習借鑒?

TAG:Python | 代码 | 代码质量 |