硬核軟體開發者 30 多年的 11 條經驗教訓
從非專業編程到專業的開發者,從 BASIC、C++ 到 Rust,在本篇文章中,已在軟體開發行業摸爬滾打 30 年的老兵將帶來自己最為深刻的 11 個經驗教訓。
作者 | Dean Roddey
譯者 | 譚開朗,責編 | 屠敏
出品 | CSDN(ID:CSDNnews)
以下為譯文:
我先是從事了多年的非專業編程工作,直至1988年,才開始從事專業編程工作。我入門時正值軟盤時代,我高中的計算機課程是主機終端上的BASIC程序。從那以後,我在這方面投入了大量的時間和精力。我只期盼著,在編程領域上度過50年的年華,將從中學到的或相信的一些東西丟掉並探索多方面問題領域,跟隨內心的接受或忽略它。
複雜性是噩夢
根本上說來,對於我們這種處於軟體頻譜十分重要一端的人來說,複雜性是噩夢。很遺憾的是,優化和靈活性都是噩夢的間接產生者。之所以說很遺憾,是因為我們無法真正避免它們,且在某種的程度上它們是非常有用或絕對必要的。但顯然,它們是複雜性的重要來源,而複雜性不僅僅是糟糕決策或普遍冷漠無視的結果,即使是最好的設計系統也無法避免,我們有目的地創建它們。
顯然,在小局部範圍內,這些工具可以提供很多幫助。但從更大的範圍來看,沒有什麼能幫到我們。這裡有一個實際問題,無論是在開頭還是中間,我們在不同的代碼之間創建鏈接,這樣我們就不能向工具充分傳達信息,來確保我們正在做正確的事情。我們不可避免地會創建始終不一致的對象內部狀態,以便避免不必要的消耗,或者支持一些必需的或期望的功能(可能像C++中的move語義)。
30多年過去了,我對此依然沒有答案。可能就是沒有答案的吧。除非有人能在一個預先解決所有問題的框架內『完全按照我的想法去做』,否則每一項重大任務都將面臨那些複雜的問題,而在我看來,只有人們極度的謹小慎微才能做到。而我們對此並不擅長。
頑固的持久性問題
我學到的一件很重要的事情是,始終確保保存的數據都經過了版本控制和使用了精心設計的構架,以便支持擴展。如果沒能做到這一點,它總會在不經意的地方出現問題。一旦你拿到的存儲數據是不受版本控制的,如果該數據類型反過來仍維持不變而作為其他類型的一部分,解決問題的唯一方式可能是:對每一種包含的類型做處理,因為你可能必須依靠版本的包含類型來確定你處理的是哪個,是舊的,壞的格式那個還是新修復的一個。
早期我曾經犯過一些錯誤,但直至今日,我也不想考慮要去彌補它們,它們仍然存在,而且很可能永遠不會改變。
我早期犯的另一個錯誤是:先寫出包含的數據值,然後再寫關於包含數據類型本身的內容。但是,這意味著你甚至不能使用包含數據類型的版本來糾正包含未受版本控制值的持久性中的錯誤,因為在讀取所有包含的值之前,你無法獲得包含數據類型值的版本。在早期的幾個項目中,這一點讓我很難受。因此,得到的教訓是,如果數據是分層的,請確保你的版本控制信息與之匹配(我想應該是預排序)。如此一來,你就可以糾正包含值持久性的錯誤。
在家就能創造的帝國
我是如此幸運。這是這樣一個事實:軟體最棒的事情之一是,你可以在卧室身著內衣的去做很多可能改變世界的事情,或創造一個小公司進而發展成一個商業帝國,從而極大的改變你的銀行資產和創造了大量的就業機會。當然也有一些其他的,儘管其中很多是創造性的,但你的勞動價值更多的是一個觀點和流行趨勢,而非一個實際效用的東西,因為它更有可能是軟體。
有了一台計算機、一個編譯器和一個概念,你就可以以某種方式使世界發生真正的變化。
說你所想
雖然持續努力是理所應當的,但一些輕鬆的工作對此可能不是那麼敏感,因為他們沒有那麼複雜,達到一定複雜性反而變成了麻煩,明確的意向聲明是最好的。
語言上可能總是存在一定的壓力,以使更容易實現快速編寫代碼。大多數產品都是如此。那些能讓人坐下來,以最快的速度進入輕鬆愉悅的演示階段的人,更容易被接受。這對於那些較輕鬆一端的東西來說是一個巨大的優勢,或者通過創建演示取得風投也是一個巨大的優勢。
但是對於你所創建的複雜系統來說,你所要做的就是把它寫出來,然後你要永遠為其負責。因此,任何以顯式語義表達為代價來提高開發速度的方法(向工具表達你真正的意思,這是唯一讓工具做你真正想讓它做的事情的方法)都不是一個好的折衷方案。在我看來,所有的語言都應該優先提高表達語義的能力。例如,Rust在這方面做了一些有趣的事情,儘管我不同意他們的一些其他決定。
中年的必然性
語言似乎隨著人們的生活軌跡而變化。他們開始的時候非常專註,然後他們慢慢地增加了越來越多的東西。我猜其中的部分原因是「游泳還是死亡」定律,在這種情況下,你覺得你必須不斷地添加功能,否則你會被認為是落後了,且變得無關緊要。部分原因是為了讓越來越多的人接受更多的東西來增加吸引力和適用性。還有部分原因是在與用戶打交道時,他們總是在爭論那些他們特別著迷的內容,但這些內容往往千差萬別或相互排斥。
最終,這個語言就好似一個穿著speedo泳裝的中年胖子,它有點肥胖,過於複雜,過於分散,試圖滿足很多人的很多要求。在某些情況下,它甚至可能是為了與之相反而被創造出來的,這在更廣闊的世界中通常是正確的。這讓我有時有點期待朋克革命。
與此相關的一個觀點是,我認為語言必須得有底氣:我本身就是這樣的。這就是進化的終點。它將得到維護,僅此而已。我們需要放下進化的包袱,在相當高的高度上建立一個新的大本營。很明顯,這很難做到,但不這麼做的後果也是非常明顯的,因為進化的包袱在不斷累積,而且很可能在語言的整個領域都對根本的改進有了免疫,因為當空間被佔用時,它們根本無法重建。
過去的錯誤變成未來的希望
時間足夠久後,那些過去在現實生活中被證明是不成形的和次優的,然後以巨大犧牲來糾正的東西,將作為激進未來的新願景重新出現。一旦有足夠多的人,在艱難地實施解決方案後開始了他們的職業生涯,他們將成長於這樣一個世界:他們受挫的唯一目標就是解決最初遺留的問題。
最終,許許多多的人沒有了以前糟糕的記憶,他們只看到現存的問題,他們看到糟糕決策的後果並怪罪於工具和技術,或相信固有複雜性問題實際上是工具和技術的複雜性,然後,他們開始認為舊的東西是他們所有問題的答案,因為它優於當前的模式。他們經常把這些想法當作現代主義來推行,而實際上他們可能是倒退的。他們並沒有意識到,如果他們回到過去,他們仍然會作出那些糟糕的決策,同樣存在固有問題和複雜性,但在現在的技術背景下,這些技術在幾年前因為恰當的理由而被徹底拒絕了。
企業家與僱傭兵
在我看來,開發人員有兩種基本類型。有些人想創造自己的東西來銷售,有些人則為別人工作。這是很明顯的,而且似乎與開發無關,但是這兩個方向創造了一個截然不同的軟體世界版圖。對於前者,語言主要只是一種工具,一種達到目的的手段,沒有必要追求最新的和最好的語言特性,因為客戶可能不太關心,他們只關心功能和質量。因此,如果一種新的語言特性對產品或代碼質量沒有真正的貢獻,企業家可能根本不在乎。
另一方面,在我看來,僱傭兵似乎更痴迷於語言本身,因為他們相信(通常是有理由的)了解所有最新的功能對他們進入下一份工作很重要。也就是說,語言對他們來說可能是職業發展的一個工具。因此,他們更有可能採用新功能,因為他們可能會在下次的面試中被問及這些功能。
在我看來,這就是為什麼有很多人在面向語言的論壇討論新語言的特性,而且這些特性不可能沿用多年,就算有,實際公司也不可能使用的兩次修正回來的功能特性。
網上討論中產生了一些不和諧之音,因為參與者的潛在觀點可能是截然不同的,但雙方都沒有真正清楚地理解對方的出發點。不得不說,編程論壇上的大多數人似乎都傾向於謀取私利,所以創業的觀點往往並不一定被很好地接受或理解。
少數特殊需求需特殊處理
我們從小學習就知道過度優化的弊端,這是正確的。你可以花費數月的時間來優化代碼,並引入大量額外的複雜性,但收效甚微,而在非常有限的代碼區域內進行簡單的調整,最終可能會提供數量級的性能提升。而且很多程序根本沒有顯著的性能限制。
但是,比如C++,它對性能的優化有時也會造成底層基礎設施和應用程序中的複雜性,即使它實際上可能只是在一個非常小區域內的項目中。虛擬方法或運行時的繼承往往是謹慎使用,因此在大部分項目中無需擔心,應該直接選擇最適合實現的方案。
顯然,通用代碼在這方面確實有一些額外的義務,但總的來說,引入大量的複雜性來優化通用代碼並不是一種整體上的勝利。這些代碼變得更難維護,更難安全快速地向前推進,也需要更多的大腦周期,而這些周期本可以應用到其他事情上,再且更容易引發bug。所以這實際上是花費90%的份額獲取10%的收益,或者不管實際的相對比例是多少。
我想說的是,那些有特殊性能需求的人請自給自足,而那些在更一般的程序中真正需要進行重大優化的少數地方,則需要特別處理。這並不一定意味著他們每個人都必須自己動手,但他們至少應該為那些程序或真正需要它的小程序使用專門的工具。這意味著更多的時間投入到對我們大多數人都有好處的事情上,並且隨著時間的推移,我們所有的代碼都不太可能會引入bug。
從第一天開始就認真對待項目結構
雖然常說:哦,我們後面可以重構。但我們都知道,現實中的大型團隊和大型代碼庫以及粗糙的代碼都沒人願意接手。做任何重大的重組很難解釋說我們的努力是為了追趕之前的軌跡。甚至也很難為自己辯護,知道這事情確實需要去做,因為不管你是否有心臟病發作的風險,你都只能得到相同的報酬。
所以我主張從一開始就認真對待項目的結構。提前考慮一些相當糟糕的情況,並為大量擴展做好計劃。就算永遠不重構,也不會太費力。如果是這樣,你會更有準備。即使你一開始看起來過於小心翼翼,最終你可能也不會後悔。
顯然,這不是最大的問題。我之所以提到它,是因為開始一個項目的時候,很容易就會想,好吧,讓我們做點什麼,然後我們就能知道下一步該怎麼做。然後你得到了一些有用的東西,商業現實開始發揮作用,突然間,多年以後,這將是一個混亂殘酷的局面,所以你現在就必須做好。
你可能仍不太能預先完成它,但是一些認真的準備思想和預先的基礎設施設置工作對於非瑣碎的項目通常是值得的。作為一個單槍匹馬的開發人員,我的情況比大多數人都好,因此更容易停止開發,並在整個代碼庫中進行大規模更改。但這可能是靈魂和腦細胞的損耗,也可能是本可以避免的時間浪費,而這些時間本可以花在更有成效的事情上。
數據和表達的分歧
這是一個很常見的問題,但仍然很容易出錯。萬事開頭難,當你開始一項新的工作時,就很容易忘記這些問題,而要把這項工作安排好通常需要更多的精力。這樣的問題我可是受夠了。我仍想做個辯解:我的大多數錯誤(其中一些錯誤由於處理起來很困難,至今仍未完全處理)都是在很久以前就犯下了,至今已成為我們日常生活的一部分。
我造成的最大問題是自動化系統的觸摸屏系統。這是非常複雜的。僅僅是完成最初的部分就已經是一項艱巨的任務,而且從那以後它已經得到了巨大的發展。像許多類似的東西一樣,它是一組圖形化的、通常是互動式的小部件,你可以通過設計器將其放置在屏幕上,並配置成你想要的樣子和行為/反應。最後,配置這些小部件的數據是類層次結構的一部分,其負責實際顯示這些小部件,因此這兩個小部件被綁定在一起。
儘管大約15年前當我做最初的工作時,我並沒有意識到這些類型的問題。我可以解開這個結,但這需要大量的工作,由此也需要犧牲其他一些重要的東西。
永不放棄,永不投降
最後,對於像我這樣的技術極客,以及可能正在閱讀本文的許多人來說,軟體是一個完美的挑戰,是在對抗混亂時的黑暗勢力。它包含了數學或純邏輯等智力挑戰,但它(至少潛在地)具有實際結果。而且一般來說,它的薪酬相比起來也高得多。
如果你剛加入這個行業,那就請堅持下去吧。就像無止境的努力一樣,通過時間的打磨才能讓你變得更好。你不可能通過思考來解決這個問題。如果你想成為一名真正的大師,你必須披襟斬棘,並犧牲你的大部分時間在這個領域之中。
對我們中的一些人來說,這並不是一個壞的權衡,因為我們並不能一開始就如魚得水。但是,無論哪種方式,你都不可能通過偶然的努力就成為大師,這將需要作出相當大的承諾。儘管如此,生活中的大多數事情都能達到一定高度以獲取豐厚的報酬,但如果它很容易的話,那每個人都能做到了。
如果你願意投入時間,我認為這是一個很好的選擇,因為可以獲得許多智慧、開拓視野和積累經驗。每個人幾乎隨時隨處都要用到軟體。所以你可以把你的職業生涯聚焦於一個領域,或者培養一項有用的技能,然後深入到許多不同的領域。鑒於其高於平均水平的薪酬,很多情況下在家就可以完成工作,以及在一天工作結束時身體毫髮無傷,這優勢就更不用說了。
原文:https://www.codeproject.com/Articles/5152541/Lessons-from-a-Life-in-a-Chair
本文為 CSDN 翻譯,轉載請註明來源出處。
【END】
熱 文推 薦
?小鵬員工承認備份特斯拉源代碼;Apple Watch 現漏洞;Python 3.7.4 發布 | 極客頭條
?JavaScript 的函數式編程與面向對象編程區別在哪?
?如果微軟開發了 Android,會有何不同?
?我在阿里的十年:從 BI 到產品經理,曾被程序員踢翻桌子罵
?Libra的Move編程語言到底是個啥? 美女程序員通讀26頁的白皮書後, 找出了這些精華… | 技術頭條
?文末送書啦!| Device Mapper,那些你不知道的Docker核心技術
?BigBiGAN問世,「GAN父」都說酷的無監督表示學習模型有多優秀?
?學好正態分布有多重要?
?實測!華為鴻蒙比 Android系統快60%!
點擊閱讀原文,輸入關鍵詞,即可搜索您想要的 CSDN 文章。
你點的每個「在看」,我都認真當成了喜歡


※重磅!Python又第一了!網友:為什麼找不到好工作?真相讓人臉紅…
※不是碼農,不會敲代碼的她,卻最懂程序員!| 人物誌
TAG:CSDN |