新手必讀:編程前輩留下的五條經(jīng)典傳世心得
譯文雖然年輕就是本錢,不過多年經(jīng)驗能讓我們編寫出最卓越的代碼。
在硅谷,企業(yè)招聘人才時總會面臨著兩難局面。考慮到過去幾年中出現(xiàn)的歧視訴訟案,人力資源方面往往不敢詢問申請者的年齡。為了解決問題,他們只好想出一些只有老鳥們才懂的梗,希望借此了解對方的從業(yè)時間。
計算機行業(yè)永遠充斥著新的技術(shù)與模式,當然也包括新晉程序員。不過必須承認,舊有技術(shù)仍然廣泛存在。大型機之類的古董級產(chǎn)物可能已經(jīng)無法登上頭條新聞,但其還在運轉(zhuǎn)不休。事實上,目前的Cobol從業(yè)者數(shù)量仍達到Ocaml、Erlang以及Haskell從業(yè)者總和的五倍。
年齡歧視非常普遍,在一定程度上也可以理解。年輕的程序員們不受舊觀念束縛,但老鳥們則更加專注且勤奮——至少不會把大量精力分散到自己的PC及智能手機上。
事實上,擁有多年開發(fā)經(jīng)驗的程序員曾經(jīng)經(jīng)歷過一切親自動手的時代。那時候根本沒有什么集成化開發(fā)環(huán)境、優(yōu)化編譯器乃至持續(xù)集成方案,想要的全部工具都得自己想辦法解決。毫無疑問,這是年輕一代所想象不到的。
因此我們將在今天的文章中共同了解由編程前輩們傳遞,并應由新一代新鮮血液繼續(xù)傳承的五項心得。
匯編
不到50歲的從業(yè)者們可能根本搞不清mov ah, 09h或者cmp eax, ebx這樣的語句。如今的程序員們以為計算機天然需要使用大括號來實現(xiàn)代碼塊分隔,但實際上最初分隔效果是依靠以上表達實現(xiàn)的。即使是了解Java或者C應當被翻譯為二進制形式的朋友,也往往很少或者完全沒有實際操作經(jīng)驗。
老程序員們曾拿出大量時間編寫匯編代碼,這也是原始填制機器碼與人類可讀版本之間的第一道橋梁。當然,這并不是說匯編仍是一項必須掌握的技術(shù)。由于極為冗長且存在大量重復內(nèi)容,我們很可能在處理匯編語言時犯下錯誤。如今的編譯器已經(jīng)足以識別各類復雜且仍有優(yōu)化空間的模式;一部分編譯器開發(fā)者甚至堅信自己的工具能夠編寫出水平高于手動構(gòu)建的代碼成果。
也許確實如此,但學習匯編語言的益處在于,我們能夠借此了解計算機的工作方式。高級語言帶來大量便捷的標準操作設定,例如連接字符串,但這同時也帶來了新的陷阱——程序員們開始誤以為“加號”在連接兩個整數(shù)以及對兩個整數(shù)進行相加時,占用的時長是相同的。實際情況并非如此。操作的耗時要遠高于普通連接,而理解匯編代碼以及JMP(jump)操作原理的程序員能夠順利做出正確的選擇。
另外,理解對象如何在內(nèi)存中打包并載入至CPU能夠幫助我們降低遲緩代碼的出現(xiàn)機率。雖然接觸過匯編語言的從業(yè)者們?nèi)缃窨赡懿辉儆浀脁86代碼的編寫方式,但他們?nèi)匀痪邆淞己玫谋灸?,足以發(fā)現(xiàn)一切可能導致代碼效率低下的狀況。
聲與光
很久以前,一位程序員告訴我,他對Unix極為厭惡?為什么?因為他在剛剛?cè)胄袝r,使用的是Altair或者Sol 20這樣的單用戶微機,其一次只能處理一個代碼塊。
“Unix計算機總是在同時處理多項任務,”他告訴我。“你會聽到磁盤突然就轉(zhuǎn)動起來,但卻不知道是怎么回事。”
真正困擾他的是,他失去了對計算機當前運作目的的判斷能力。在現(xiàn)代計算機當中,沒人知道這臺設備究竟在干什么——因為其中包含著數(shù)不清的軟件層,并運行在四核甚至是八核CPU當中。病毒與蠕蟲亦可潛伏于其中,而用戶完全感覺不到由此帶來的性能影響。
前輩程序員們?nèi)匀涣晳T于通過視覺與聽覺判斷問題,幫助他們理解并調(diào)試代碼。他們觀看數(shù)據(jù)經(jīng)過時RJ-45以太網(wǎng)插孔的閃爍,聆聽磁道改變時硬盤的響聲。他們甚至能夠借此意識到不同分頁間的差別,甚至借此了解設備在對索引的哪部分進行讀寫。
這些線索的價值正在逐漸消失,SSD以及無線路由器的大量普及讓它們不復存在。但只要智能手機上還有小小的指示標記提醒數(shù)據(jù)流通,這種敏銳的嗅覺就仍有用武之地。
數(shù)據(jù)大爆炸
遙想當年,程序員們需要將8個不同的布爾值轉(zhuǎn)化為1個字節(jié)。他們對每個存儲位都極為珍視,因為當初的容量資源真的非常有限。
現(xiàn)代數(shù)據(jù)結(jié)構(gòu)則充斥著浪費與隨意。XML中的各類標簽名稱極長,且每個名稱都會以額外的斜杠作為結(jié)束標記。JSON相對更為進步,因為其無需關(guān)閉標簽——而只需要大括號,這就讓其身材更苗條一點。然而,JSON的標簽與字符串內(nèi)也存在著眾多不必要的引號。
好消息是,現(xiàn)代壓縮算法能夠顯著降低數(shù)據(jù)結(jié)構(gòu)所占用的空間。但壓縮并不能徹底解決問題,而前輩程序員們卻知道如何從起步階段避免這種浪費。也正因為如此,MS-DOS 3.0操作系統(tǒng)仍有32MB,這意味著其最大空間占用量也不會超過3200萬個字節(jié)。
事實上,MS-DOS 3.0誕生于上世紀八十年代初,七十年代的代碼在精簡程度上更勝一籌。而六十年代的代碼——簡直就是藝術(shù)品。
二進制數(shù)學
對bit位的測試與調(diào)整并非出于好奇,而是一種必要。某些操作的執(zhí)行速度太慢,迫使程序員們尋求更理想的方式加以解決。最典型的例子就是除以二相當于在二進制中將小數(shù)點向右移一位,而除以十則為十進制中將小數(shù)點向右移一位。
相較于正常除法,CPU在處理數(shù)位移動時速度明顯更快。出色的程序員會利用這種優(yōu)勢加快代碼運行速度,而非笨笨地坐等乘法與除法處理。
但如今這種良好的思維方式正在逐漸消失,強大的處理性能足以承載我們的揮霍。不過必須強調(diào)的是,這種敏銳的本能在現(xiàn)代開發(fā)工作中仍然有著重要價值。
細節(jié)累加即為結(jié)果
在多數(shù)早期處理器中,某些操作的時耗要遠高于其它操作。在初代8086處理器中,數(shù)學除法要耗費80到190個時鐘周期,而將兩個數(shù)字相加則只需要耗費3個時鐘周期。即使當時的CPU主頻已經(jīng)達到5 MHz,大量操作疊加起來也會造成巨大的處理時長差距。
前輩程序員們很清楚每行代碼或者每項指令的執(zhí)行時間差別,他們也明白計算資源是如此寶貴,需要認真規(guī)劃與管理。錯誤的操作類型將大大延長處理時間,而錯誤的數(shù)據(jù)類型也會帶來同樣的后果。一旦使用錯誤的數(shù)據(jù)結(jié)構(gòu),我們辛苦打造的程序?qū)⑺查g成為垃圾。
很多年輕一代認為CPU能夠在瞬間完成幾乎無限量的計算,但前輩們則很清楚CPU是如何一步步向用戶交付結(jié)果的。多年以來,經(jīng)驗豐富的程序員對自己的代碼細節(jié)進行研究、調(diào)試與重新研究,也正是這些積累讓他們成為行業(yè)中的翹楚。因此,請抱著敬畏的心對待自己指尖流出的代碼——它們正一步步塑造著我們的職業(yè)生涯。
原文標題: 5 more timeless lessons of programming 'graybeards'
【51CTO譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】