1. 程式人生 > >哪個蠢蛋寫的爛代碼?

哪個蠢蛋寫的爛代碼?

工作 復雜 方法 數據庫 邏輯 微信公眾號 錯誤 無形中 質量

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

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

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

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

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

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

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

原作者設計得太復雜, 一點小的改進都要大費周章,完全掌控他的代碼需要不少時間。
代碼性能不好。之前因為用戶量和訪問量太少而相安無事,現在問題突然爆發了,拖慢了整個應用甚至影響到基礎設施。
想要修改功能時卻發現程序裏充斥著各種無法理解的邏輯,改完之後莫名其妙的bug一個接一個。
在程序員這個職業裏面,英雄主義實在太普遍了。有無數的理由說服領導、PM和自己,要重新造個輪子,因為大家都認為自己天下無敵了,但是又不好承認看不懂別人的代碼。如果你的個人影響力和表達能力有限,沒有足夠的理由說服其他人選擇這個輪子,又不願意花時間推動和完善,那麽最後的結果是,你認為這麽美好的東西,真的只是你這麽認為。等你不再維護了,離職了,下一個人又會循環這個過程... 等幾年之後,項目是越來越大,但是裏面大量的代碼都是dead code,也就是無作用的代碼。而且新人還不敢動,尤其是裏面有一些magic number,復雜算法片段。

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

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

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

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

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

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

Bjarne Stroustrup(C++之父)說:

邏輯應該是清晰的,bug難以隱藏。
依賴最少,易於維護。
錯誤處理完全根據一個明確的策略。
性能接近最佳,避免代碼混亂和無原則的優化。
整潔的代碼只做一件事。
Michael Feathers(《修改代碼的藝術》作者)說:

整潔的代碼看起來總是像很在乎代碼質量的人寫的。
沒有明顯的需要改善的地方。
代碼的作者似乎考慮到了所有的事情。
可以感受到,對好的代碼的理解有很多共通的地方:

代碼簡單,代碼意圖明確,其他人才容易與你協作。
可讀性和可維護性要高。
以最合適的方式解決問題。
和大家共勉,不要做別人嘴裏的「蠢蛋」。

--- 分割線 ---

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

不記得在哪裏看過, 程序員有三種(我重新潤色了一下):

拿錢幹活,不爽就換 - 程序員只是一份工作。
只要能實現功能就好,學習進步太累了。這年代做技術沒有管理掙錢多,技術搞得再好有什麽用? 還不是買不起房啊。這年代關鍵是你認識多少人。你是不是有眼光去一個能上市會讓你暴富的公司,能不能唬住粉絲兒和投資人。
熱愛程序本身的人, 這些人可能只有1%, 他們有目標的寫程序, 他們願意思考, 願意聽取正確地/更好的方法, 他們會熱愛學習新的東西。
現在產品開發叠代非常快,一周要上多個版本,每天要提多個Pull Request,對於前2種人,只能疲於應付工作,怎麽樣能在天賦不夠又不想多花時間進步的前提下完成工作,還能到領導的好評呢?這是一門藝術呢......

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

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

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

  1. 多看書,多讀其他人的博客,閱讀優秀的開源項目的代碼甚至語言本身的源代碼。這是一個長期的、瑣碎的、需要學習之後記憶和實踐的過程,看代碼要思考別人為什麽這樣寫,組織結構為什麽這樣用,這樣寫代碼為什麽快。當然最重要的還是實踐。

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

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

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

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

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

文章首發於微信公眾號:Python之美

哪個蠢蛋寫的爛代碼?