開發者“暗戀的”10個壞編程習慣

程序員咋不禿頭 2024-05-25 09:19:23

從心理學上來講,當人們違反規則甚至破壞規則時,會感覺到有點兒刺激。

比如在限速 55 公裏的地方,我們以 80 公裏的速度行駛,或者讓停車計費表失靈等等。

在軟件開發領域,比方說在沒有測試分母不爲零的情況下將兩個數字相除等。因此說來,程序員們與規則有著各種奇奇怪怪的關系。

一方面,代碼包含著一大堆規則,這些規則被盡職盡責的開發者門無限放大地應用,沒有恐懼或偏愛,我們總是希望沒有奇怪的事情引起BUG。我們甚至希望硬件的晶體管也完美地遵循這些規則。

但還有另一層規則並不怎總那麽“神聖”。

與我們向機器提供的指令不同,我們是人,那麽爲自己制定的規則應該是高度靈活的,就像彈簧一樣。有些只是純風格上的,另一些的目標是在爲不規則的代碼帶來一致性。這套規則適用于我們所做的事情,而不是機器的響應方式。

真正的爭論,人類能否打破自己的規則。我們有權利隨時重新解釋這些規則。也許是因爲有些規則來自不同的時代。也許有些規則從一開始就是不成熟的概念,也許有些規則在當時看起來是個聰明的想法,還有一些規則最好是被稱爲“習慣”。

這裏面,我們整理了一份開發者們“暗戀的”壞編程習慣清單。目標爲了提高編程藝術,這裏還包括另外 10 個編程習慣。

沒有注釋的編碼

我們都知道,沒有文檔的代碼很難閱讀、理解和調試。

因此,我們的編程課除了教人們寫好代碼,還有寫出好的注釋也非常重要。文學式編程,即結合自然語言和代碼的編程風格。

Don Knuth ,文學式編程提出者。著名計算機專家

這是最早由 Don Knuth 發明的,他可能是有史以來最偉大的程序員。我們還有什麽資格可爭論的嗎?

但事實可能有點不一樣,有時注釋會讓事情變得更糟糕。

有時,文檔的內容與代碼關聯並一定大。有時寫文檔的人甚至遠離編碼團隊,處于另一種狀態。也許編碼人員在沒有告訴文檔團隊的情況下推出了一個關鍵補丁,或者文檔團隊知曉但尚未更新注釋。有時,編碼人員可能沒有更新更改的方法頂部的注釋。文檔工程師只能自己解決這個問題。

還有其它一些問題。也許注釋是用你不了解的自然語言寫的。也許這個概念無法用少于七段的文字輕松概括,而程序員正處于敏捷沖刺階段。也許注釋寫的就是錯的。

出于以上這些原因,一些開發人員認爲解決無用注釋的最佳方法是少加注釋,甚至不加注釋。相反,他們更喜歡編寫簡單、較短的函數,並使用較長、描述性強的駝峰式變量名作爲指導。如果編譯器沒有錯誤,代碼應該最准確地反映計算機正在做的事情。

運行慢的代碼

如果你希望你的代碼運行速度變快,那就讓它簡單一點。如果你希望它運行得更快,那就讓它複雜一點。

但是找到這個特定任務的最佳平衡點並不容易。

這對于開發者來說的確是一種平衡。一般來說,我們希望程序運行速度很快,但如果以後沒人理解,那麽複雜性就會成爲累贅。因此上,如果速度不是必需的,那麽編寫速度稍慢點,但更容易理解的代碼也是有意義的。

有時,簡單、略慢一點比超級聰明和超級快速的代碼,是更好的選擇。

新奇古怪的代碼

我的一位同事特別喜歡使用 JavaScript 中剛出來的新運算符,這些符號設計很巧妙,例如省略號(...)。這樣讓生成的代碼更加簡潔,在他看來這意味著更簡單、更好看。而他們所有的代碼審查都會返回給我,我會根據注釋看到哪裏重寫了代碼,以及使用新語法後的建議。

我的其他一些同事不太確定越簡單就越容易理解。閱讀代碼需要理解新的運算符,其中一些運算符可能以各種不同的方式運用。理解運算符的使用方式需要停下來深入思考,而不是像他們習慣的那樣快速浏覽。這樣,閱讀代碼變成了一件苦差事。

關于人們爲什麽不喜歡超前代碼,也有一些曆史爭論。像 APL 這樣的語言,由于其自定義符號設計得非常緊湊和高效,但實際上已經消失了。其他語言,如Python,它避開了大括號,如今繼續在流行。

最新和最偉大的抽象愛好者,繼續推動著簡潔的新功能,並吹噓簡潔的優勢。他們宣稱自己是現代以及時髦的。然而,還是有人會繼續將更長、更易讀的代碼偷偷地放入技術堆棧中;他們知道,最後這樣才會更容易閱讀。

古老的密碼

設計編程語言的人喜歡發明巧妙的抽象和語法結構,以使解決某些類型的問題變得輕松一些。他們的語言充滿了這些抽象,但這就是爲什麽有時他們的手冊長達一千多頁的原因。

有些人認爲使用這些功能是最好的。畢竟他們說過,權力的首要規則是“使用它或失去它”。難道我們不應該使用那本一千頁手冊中描述的每一滴語法糖嗎?

但是,這並不總是一個好規則。太多的功能可能會造成混亂。

現在有這麽多巧妙的語法糖、編程花招,估計沒有一個程序員能夠完全精通它們。我們爲什麽要精通呢?比如說,我們需要多少種方法來測試無效性,或者使繼承在多個維度上起作用?其中一種是正確的,還是比其他的更好?當然,團隊中的一些程序員會想方設法通過爭論這些來制造戲劇性遊戲,從而毀掉你的午餐或站立會議。

至少有一組語言設計者決定了功能集的限制。

比如 Go 語言的創建者就表示,他們希望構建一些可以很快學會的東西,甚至可能在一天之內搞定。這意味著團隊中的所有程序員都可以閱讀所有代碼。因爲更少的功能可以減少混亂。

編寫屬于自己的代碼

效率專家喜歡說:“不要重新發明輪子。” 也就是要使用經過充分測試,並准備好運行的代碼庫。

嗯,是的,請使用已經經過驗證的遺留代碼。

但是,有時候新方法也是有意義的。庫通常是爲通才和日常用例編寫的,它們裝載了安全帶和吊帶測試,能夠確保數據一致,並且用戶不會因爲發送錯誤的參數而搞砸工作。如果遇到了特殊情況,幾行專門的代碼就會大大加快開發速度。它不會做代碼庫能做的所有事情,但它可以用一半兒的時間內完成你所需要的事情。

在某些情況下,這樣做可能會帶來“危險”。有些代碼非常深奧與複雜,比如在加密系統中,即使你知道所有的數學知識,拼湊起來也不是一個好主意。但在適當的情況下,當庫成爲你工作量的最大瓶頸時,一些巧妙的替換函數便會産生奇迹。

代碼優化的太早

程序員通常會將一些代碼放在一起,並用“過早優化是浪費時間”這一舊的格言來證明他們的快速工作是合理的。

我們的想法是,在啓動整個系統之前,沒有人知道代碼的哪一部分將成爲真正的瓶頸。如果每年只調用一次,那麽浪費時間來構建一個出色的函數是不明智的。

以下是一個很好的經驗法則。有些項目因爲太多的過度規劃、過度優化而未能沖出起跑線。但在很多情況下,只要稍微深思熟慮,就可以産生很大的不同。有時,選擇錯誤的數據結構和模式,會産生事後不容易優化的架構。有時,它們的結構已經融入到代碼的許多部分中,以至于一些巧妙的重構並不能解決問題。在這些情況下,一些過早的優化最終是正確的答案。

疏忽

每個人都知道,優秀的程序員在穿過單行道之前,都會先看看兩邊。他們插入大量額外的代碼行,在對數據進行任何操作之前總是對數據進行雙重甚至三次檢查。畢竟,空指針可能會滑入其中!

唉,所有這些額外的關注可能會減慢我們的代碼運行速度。有時,出于性能原因,我們需要忽略一些直覺,只編寫那些不太在意的代碼。如果我們想要運行速度快的代碼,我們應該只做最低限度的事情,不要做更多。

不一致

做技術的人們通常喜歡秩序。程序員們經常堅持一堆代碼的每一部分都要使用相同的技術、算法或語法。我們這樣的勤奮可以讓後來理解代碼人的工作變得容易。

但是從另一方面來講,一致性需要付出時間成本,有時也會增加複雜性。修複差異意味著要回頭重寫所有“走錯路”的代碼。僅此一項就會給預算成本造成壓力。

更深層次的問題還有不同部分之間的關系。有些項目依賴于遺留代碼。其他依賴于庫。如果沒有來自不同公司中不同的人來編寫API,許多系統功能是無法運行的。

消除這些群體之間的差異通常是不切實際的,而且你想重寫整個堆棧以適應最新願景的次數有限。我們大腦的一個奇怪的角落渴望完美的秩序,但也許最好是與不一致和平共處。

追求花哨的東西

過于一致性的另一個問題是阻礙創新,它還鼓勵嚴格遵守舊的做事方式。

有時添加新功能、加入新庫或將堆棧與新 API 集成,這意味著打破舊模式。是的,這會讓那些在閱讀代碼時必須換個思路的人的生活變得困難,但這是進步的代價。這也是讓編碼變得很有趣的一部分原因。

打破規則吧

爲了讓自己一笑,我詢問了 Google 的 Gemini:“程序員在創建它的過程中是否違反了相關規則?”

Gemini 回答說:“與其說程序員違反了特定規則,不如說他們在創建像我這樣的大型語言模型時可能突破了一些最佳實踐的界限。”

“像我這樣的大型語言模型需要訓練大量數據,而模型如何從這些數據中學習存在一些“未知”因素。一些用于創建大型語言模型的技術可能非常有效,但很難准確理解模型如何得出答案。”

就這樣吧,連大語言模型都比我們更清楚舊規則正在發生變化。

當你可以將大量訓練集輸入到盒子裏時,你可能不需要花費太多時間來理解算法。所以,讓大模型來遵守規則,我們繼續做個真實的人吧!

0 阅读:59

程序員咋不禿頭

簡介:感謝大家的關注