一個擁有 20 年編程經驗的「熟手」,編程乾貨有多少?本文的作者是一名從業 20 年的程式設計師,在本文中,他分享了自己這 20 年來學到的 5 種編程經驗:重複的知識最糟糕、把代碼當成一種債務、對高級開發人員信任但去驗證、使用 TDD、用「證據」證明自己的代碼更好。下文是關於這 5 種經驗的具體描述。
今年,我對 DEV 開發平臺越來越熟悉。眾多激憤的 Reddit 評論者和「不過如此」的鑑賞家們構成了一片荒漠,在這片荒漠之中,DEV 已經成為了一個令人耳目一新且充滿積極力量的綠洲。
這個社區有著很有趣的一面,它似乎非常注重初學者。我經常在這裡看到行業新手寫的帖子。我所說的新手是指那些在訓練營中尋找入門級工作,或者那些在不幸的「初級」程式設計師崗位上工作的有抱負的程式設計師。
我覺得這很有趣。相對的新手,通常對這個行業充滿著熱情和激情,這種激情是有感染力的。但這也讓我覺得自己是這個行業的熟手。
我想起鮑勃·馬丁在播客或演講中說過的話。
在過去的四、五十年裡,行業對程式設計師的需求急劇增長,以至於程式設計師的數量總是每五年翻一番。因此,擁有 5 年經驗的程式設計師佔據著整個行業一半以上的職位。
熟手的地位
我在這個行業已經快 20 年了。其中 10 年,我的主要職責是編寫代碼。另外 10 年包括管理程式設計師、指導他們、向組織諮詢如何管理他們、施行代碼庫評估實踐以及當前從事的內容營銷。
但在所有這些角色中,我或多或少地也都會編寫代碼。
根據我的計算,程式設計師數量呈幾何級增長,這讓我比這個行業中 94% 的人頭髮更白。
所以我們的差距並不大。我是混跡在編程新手周圍中一名的「職業」程式設計師。
於是,我提醒自己說:「如果我能把這段經歷進行簡明扼要地總結(假設真的有人關心的話),我會向他們提些什麼建議呢?」
所以,就產生了這篇文章。以下是我認為自己在 20 年編程生涯中最重要的經驗和收穫。
1. 重複的知識最糟糕
「避免複製粘貼式編程!」
當你在應用程式中複製、粘貼代碼,然後調來調去的時候 (「複製、粘貼、調整」反模式),如果沒有人打你的手,那麼現在就考慮舉起這根「戒尺「吧。
阻止它!立即!這種做法很糟糕,也很隨意。
假設,你有一個用得好好的 CalculateBill() 方法,但是產品經理卻走過來說:「我們正在墨西哥接待新客戶,與你那個計費的方式有點不同。」因此,你可以複製當前這個方法,粘貼它,將其重命名為 CalculateBillMexico(),並根據需要對其進行調整。
以下是使用這種方式所產生的問題:
如果將來的變更需要對核心邏輯進行調整,你現在必須額外去修改這兩個方法。在做此類變更的時候,現在你就有 2 個引入 bug 的可能。你現在已經建立了一個「設計模式」,隨著在全球的繼續擴展,你的代碼需要一個又一個新的、冗餘的方法。你的工作量將會急劇增加。忘記修改需要修改的地方,從而引入 bug,這種情況只是時間問題。最終,所有這些方法都會有一定的差異,這些差異足以令你無法合理地將它們合併起來修復這種混亂,但是差異又沒有大到可以避免有人在更新一條計費規則時改上 20 次。這是一個爛攤子。然而,「複製 - 粘貼」只是表層問題。
複製 - 粘貼只是開始
真正的問題是系統中的知識重複。
在你的系統中,知識的複製可以以多種方式出現,蹩腳的複製 - 粘貼是最明顯和最笨拙的。看看其他知識重複的例子:
一個 for 循環,在它的正上方有一個解釋開始、結束和遞增的代碼注釋。為一個全局變量內聯賦值,然後 (可能) 從配置文件中取一個值重新賦給它。包含「PretaxTotal」、「Tax」和「Total」列的資料庫表一個範圍很廣的 ERP 系統,它將客戶存儲在 CRM 模塊中,然後再存儲在計費模塊中。有了以上所有這些,最好的情況是,你有適當流程和系統來努力地跟蹤副本,並確保同時更新它。
如果缺乏代碼注釋,可能團隊的首席嘮叨官在你更新代碼時就會一直在你耳邊念叨,檢查注釋、檢查注釋。
或者,以那個 ERP 系統為例,它可能是一個嚴格的部門備忘錄,告訴銷售和會計,他們都需要發送正式的電子郵件,以確保客戶信息保持同步。
記住,這些已是最好的情況。
當你開始構建複雜的邏輯 (之後你必須維護它,請參閱下一節) 以確保同步時,會出現更糟糕的情況。
也許你可以實現一個資料庫觸發器,在「total」列發生更改時確保 PretaxTotal + Tax 仍然等於 total。或者,你可以編寫一些笨拙的狀態檢查邏輯,當默認的全局變量值與要賦的配置文件中的值不匹配時,記錄一個警告。
最糟糕的情況是數據不同步。那麼,你作為一名程式設計師,可能不用擔心它,因為你拿的那份工資所要承擔的工作不包括搞清楚為什麼你們從來沒有給客戶開過發票,或者為什麼多年來一直多收客戶的錢。
但是,面對藏身於系統各處的知識重複,無情地根除和積極地抵制可以幫你避免所有這些問題。
2. 代碼是一種債務
作為開發人員,我們要學會熱愛代碼。編寫代碼感覺很好,創造些什麼出來也很令人興奮。
此外,我們尋找新的語言、範例、框架、堆棧、工具、api 和庫來學。我們沉浸在自己的世界裡,並為「心流」而歡呼,因為在這種狀態下,我們可以愉快地生產代碼。
在這場慶典中,我們並不孤單。
誤入歧途的極端分子甚至把每小時生成的代碼行數作為生產力的度量標準。但即使你沒有達到武器級的愚蠢程度,也很容易認為代碼越多越好。代碼是你們殺手級應用程式和業務的 DNA,公司認為它是有價值的智慧財產權。
然而,忘了這一切吧。
我能理解為什麼我們把代碼看作資產。但事實是,代碼完完全全就是一種債務。
少即是多
你知道什麼比用 10 行代碼來編寫別人用 100 行代碼來完成的事情更好的嗎?那就是用 0 行代碼。
寫這麼一行代碼:
複製代碼
printf("Hello World!");你認為有多少事情會出錯?
這段代碼會在允許控制臺列印的環境中運行嗎?那段神奇的字符串以後不會成為問題嗎?你不應該記錄日誌嗎?這是一條最佳實踐。你有沒有想過這對安全的影響?保守地說,這行代碼中有 10 個地方可能出錯。現在,我們加上第二行。
你覺得這會導致總共 20 件可能會出錯的事情嗎?
我認為幾乎得有 100 件。你可以叫我是悲觀主義者,但我認為潛在問題與代碼行之間的關係更接近於組合而非線性。
實際上,我做過幾年管理顧問,具有特別的職業特殊性。我做數據驅動的代碼庫評估,並幫助 IT 領導層制定代碼庫相關的戰略決策。
所以我看過、分析並收集了大量代碼庫的統計數據。
如果算上在客戶那兒自動分析的代碼庫,那麼我已經收集了 1000 多個代碼庫的詳細統計信息。然後,為了尋找相關性我對這些數據進行了回歸分析。
你知道什麼與不良的代碼庫的相關性更強嗎?那就是代碼庫的大小。
幾乎關於代碼庫的所有壞事都與代碼庫的大小有很大的關係(以代碼的邏輯行來衡量)。
我愛代碼,我喜歡寫它、研究它、分析它,和用它做東西。但毫無疑問,它是一個巨大的債務。我們應該總是努力用儘可能少的代碼來做每件事。
3. 高級開發人員:信任但驗證
在我 23 歲時做了第一份軟體工程工作,當時我對那裡的高級開發人員懷有一種近乎狂熱的崇敬。保羅、雷蒙德、克裡斯、肯,平均每個人大約有 20 年的從業經驗,我可以生動地描繪出他們所有人的樣子,我發現他們對多種程式語言的熟練程度令人驚嘆。
我從他們身上學到了很多。
我提到這些是因為我想適當地鋪墊一下接下來要說的話。
如果你是這個行業的新手,你可能會像我一樣,認為團隊中資深開發人員的每一句話都是智慧的結晶。而且,如果你幸運的話,他們中的很多人的確是這樣的,特別是一開始的時候。
但是並不是所有的高級開發人員都如此。
回想起來,我上面列出的那些人實際上都是很好的程式設計師,我從他們身上學到了很多東西。但我也認識到,在我的職業生涯中,我幸運地擺脫了最初的影響。
既有優秀的、樂於助人的高級開發人員,也有能力並不出眾的小人物,這些人的主要資歷不是技術專長,而是在那兒很長一段時間無所事事,設法不被解僱,並靠混資歷晉升為「資深」或「高級」之類的頭銜。
這種現象非常普遍,幾年前我編造了一個詞來描述它,現在每個月都有數百條谷歌搜索。當我創造了「專家級初學者」這個術語時,它引起了人們的強烈共鳴,最初的帖子像病毒一樣得到了一遍又一遍地傳播。
戴爾將告訴你所謂的專業的對象關係映射是怎麼回事。
我說這些不是為了炫耀。我這樣說是為了提醒你,許多高級開發人員表面上看起來名副其實,但實際上並不是。
所以,當你是新人的時候,要相信前輩的說法,尊重他們,但不要想當然地認為他們說的就是對的。自己得驗證一下,當然了,最好不要在當著他們的面驗證。
4. TDD 真的行,它改變了遊戲規則
當涉及到任何編程,甚至只要是與技術相關的事情時,我們往往會因為帶有偏見的主觀選擇而發瘋。
IDE 與輕量級編輯器的討論?蘋果、Windows 還是 Linux?你怎麼看 PHP?制表符(tab)還是空格(space)?拿出其中任何一個,看看那些持明確觀點的人愚蠢的爭吵。因此,考慮到所有這些,我意識到我正在陷入類似的境地,那就是「做 TDD 還是不做 TDD」。
我的目的不是說教,而是分享我自己的經驗。
大約 10 年前,我是 TDD 懷疑論者。我並不是單元測試的懷疑論者,提醒一句,我從一開始就接受了它,並將其作為一種有用的實踐。
但 TDD 呢?我不太確定。
我決定寫一篇博客來解釋為什麼 TDD 沒那麼好。
但我不想就這件事寫一篇站不住腳的、蹩腳透頂的評論文章。所以我決定做一個嚴格遵循 TDD 的小型客戶項目 (順便一提,固定價格),這樣我就可以寫一篇文章,但這篇文章的前提是「我花幾周時間做純粹的 TDD,但發現它並不好」。
但是,命運另有安排。
我的天啊!時時刻刻與 TDD 相伴
這是尷尬而怪異的一天。實際上,可能是好幾天。
每件事都要花很長時間,我感覺做每件事都很麻煩,很不自然。我只是一樁一樁地把它們記錄下來,以證明為什麼這是一種糟糕的做事方式。
但是,有趣的事情發生了。
我對這個笨拙的範例如此著迷,以至於有一天我花了 4-5 個小時編寫代碼,卻沒有實際運行應用程式來查看我的更改是否有效。通常,我會每隔 10 分鐘左右運行一次應用程式的,以檢查我的更改是否真正有效。
意識到我已經工作了幾個小時,我啟動了應用程式,嘆了口氣,感覺必須得調試上幾個小時了。畢竟,以前的我至少需要調試 30 多回。
但是,不可思議的事情發生了。一切都能正常運轉。
一切都運轉得很完美,第一次沒有任何異常。絕對沒有任何意外。我花了幾個小時編寫代碼,沒有查看自己的 GUI,也沒有在運行時驗證任何東西,但所有的一切都運轉正常。
我寫了另一篇關於 TDD 的文章。這一次,我再也沒有反悔。
我學習了這種技術,掌握了它,還講授了它的相關課程,做了它的相關諮詢,並圍繞它進行了開發人員培訓。但除此之外,我調查了單元測試對代碼庫的影響,發現這些影響無疑都是好的。
學習 TDD 的知識技能吧。你不會後悔的。
5. 證據為王
到目前為止,在這篇文章中,我已經提到了我的代碼庫評估實踐,並討論了經驗數據。讓我們正式來聊聊我目前職業生涯收穫的最後一點經驗。
證據就是一切。
代碼評審可以作為一種教育性的、賦能的活動,或者他們可以處決你的靈魂。
然而,他們很可能會在啟發性的體驗和無意義的爭吵之間來回搖擺。
你會聽到諸如「那不是一個好的設計」或「那沒有效率」之類的話。你可能也會說這些話。你很可能在沒有任何證據的情況下聽到或說出這些話。
解決這個問題。
證據的重要性
如果在代碼評審過程中,或者你的團隊或組織內的任何其他形式的協作過程中,有人對你橫加指責,那麼證據就是你的朋友。如果你試圖向管理層或領導層解釋任何事情,證據就是你的朋友。
證據會為你贏得爭論、尊重、領導角色和職業晉升。
你是否認為團隊大量使用全局變量會害死你們?不要爭論——證明它。
我所說的「證明」,並不是指找一篇關於罪惡的全局狀態的文章,把它當作權威拍到我的面前。我的意思是,在你的代碼庫中找到有全局聲明和沒有全局聲明的模塊,然後將 JIRA 問題單的事故率或者其他數據作為參考依據。
你的團隊中是否有人要求你使用與你的選擇相左的庫或 API,因為它們具有「無憑無據」的良好性能?你接受他所說的嗎?
證明他說的是錯的。進行實際的時間測試。
讓你自己習慣於做實驗,而不是大聲地表達和重複你的觀點。以實證驗證你的想法,這種做法具有直接價值。
面對質疑時,有時你會發現你是對的,而有時候你會意識到是你錯了,這也是很有價值的。
但除此之外,你會開始用一種其他人無法匹敵的方式進行辯論,從而樹立起自己的品牌,那就是勤奮和正確。這可以幫助你克服一些看似不可逾越的障礙,比如「我只是個初學者,而他是個專家」。其實,他不過是一個專家級初學者而已。
眼光再放長遠一點來看,這會讓你在事業上有更好的發展。
能夠編寫代碼確保你會有一個回報豐厚的職業生涯。能夠編寫代碼並能夠使用證據來為行動過程提供技術和業務用例,這將確保你的事業蒸蒸日上。
以健康的方式使用 (或不使用) 這些
寫這篇文章的時候,我覺得自己富有哲理。事實上,我是在從芝加哥飛往休斯頓的飛機上寫完這篇文章的,當時我手裡拿著一杯酒,選擇不使用 wifi。所以我除了和空乘聊天 (我坐在第一排,所以他們都在這裡),回憶我的職業生涯之外,幾乎沒什麼事可做。
如果你足夠努力地做過嘗試,我想你可以反駁這些觀點。
但我並沒有把這些作為一成不變的編程法則或某種專業的行為準則。我只是把它們作為在職業生涯中自己學到的經驗教訓提供給大家,它們只是我的個人觀點,請大家謹慎選擇。
希望這些觀點能對你們有所幫助,使你們能夠根據自己的需要以健康的方式採用它們,或者,不採用它們。
作者介紹Erik Dietrich,DaedTech LLC 的創始人、程式設計師、架構師、IT 管理顧問、作者和技術人員。