極其出色程式設計師的各種跡象

柒柒發表於2015-07-03

五、極出色程式設計師的跡象

我多希望自己擁有這些特質,但可惜沒有,我之所以能把它們寫下來,是因為我在別人身上觀察到了這些特質。常常有那麼一刻,我覺得自己正擁有其中一種特質,但那些時候彌足珍貴。這些特質正在逐漸消失,並遭到了那些孤僻學者的刻板成見。而這些特質往往得之不易:如果你想成就卓越,那你必須準備好為此付出代價。

1.   永遠保持耐心

特徵

  1. 火災警報讓你感到心煩勝過恐慌。
  2. 叫不出廣播裡播放的歌曲名稱,或從聽筒裡傳出的電話彩鈴。
  3. 很清楚室友去喝咖啡、洗澡或上醫院的次數。
  4. 對辦公室爭鬥不在乎。
  5. 程式碼還沒執行就能預知其中的 bug。

如何獲得這種特質

幻想會導致分心。我寫這篇文章的那天就發現自己完全不能集中精力,當時我在蒸桑拿,而有個人在健身房唱法語歌讓我很惱火。歌聲在桑拿房外面飄來飄去,徹底把我惹火了。我非常希望他能停下來不要再唱了,因為我實在沒辦法集中注意力。我在腦子裡把他想象成一個不管別人感受的男人,一個穿著粉色襯衫頤指氣使的變態。接著我走出桑拿房發現,那是個紅褐色皮膚的老人,他就像一個帶有鈕釦眼睛的破舊泰迪熊,哪有我想象的那麼危險。他開始唱《 La Vie en rose 》,這是我很喜歡的一首歌,然後我就納悶自己是不是很久以前就變成了一個讓人討厭的混蛋。

我不知道如何才能避免分心,但如果我曾經嘗試去這麼做,那我可能會覺得“這歌聲夾雜了絲絲敬意又飽含魅力”,而這種魅力又會指引我的想象,而不是反過來由主觀臆想來判定那歌聲的魅力。每當我要失去耐心的時候,我都希望自己能不帶個人偏見地去對待生活。

2.   不顧一切地追求完美

最糟糕的優化通常是為了追求利益而非為了美,而二者之間只有美才更長存。追求完美不等同於沉迷,但它們之間的關係確實非常密切。

特徵

  1. 寧願辭職也不願妥協。
  2. 對規定的驗收日期不屑一顧。
  3. 在截止日前夕大量重構程式碼。
  4. 不願意接受獎金、升遷或是短期的優先認股權。
  5. 很喜歡由斯坦利·庫布裡克( Stanley Kubrick )執導的電影。

如何獲得這種特質

正如 Tyler Durden 所說“你必須知道,拋棄恐懼,面對你終將死去的事實”。你那擁有宜家傢俱的漂亮公寓只是生活的附屬品,而不是生活的獎勵。如果你不是個獨特又出色的人,那你創造出來的東西應該是。

追求完美也被認為是對自己的工作感到自豪。記住,理智對待程式碼是一種美德,但這不意味著避免把感情帶入工作也是一種美德。實際上,理智對待程式碼的另一種方法是把興趣放在結果上。你應該思考的結果猶如一位女士,如果她不能搶在下午 4:59 這一分鐘內把你的程式交付出去,那她就會被炒魷魚(譯者:這麼漂亮的姑娘,你應該捨不得她因為你被解僱吧)。

有這樣一個傳說,一個營銷人員在沃爾瑪( Wal-Mart )為 Sam Walton 工作,有一天他/她想出了一個很棒的活動計劃為零售品做廣告。Sam 看了一眼提案然後說了一大堆話,大意是“太棒了,現在算算這個活動的開銷,然後把這些開銷用來降低零售品的價格吧”。從這個故事發現,不做活動反而比做活動能賣出更多零售品,創造出更多的利潤。

在腦子裡好好想想這個故事傳達的精神,思考一下如何將這個故事對映到自己的工作中去。你的 boss 也許不像 Sam Walton,但可能你和 Sam 有一點點像呢。是選擇像別人希望的那樣妥協更好,還是應該選擇堅持把產品做的更好,哪怕只是微小的提升?

這可能會不利於你的收入,對優先認股權也有風險。但只要你工作幹得、做事像樣,按應該使用的方式完成一個專案,那總有一天時間會原諒所有的任性。或許有一天你的 boss 會鄭重地把你叫回來,為以前的事情向你道歉。

3. 精通平臺

絕大部分程式猿都知道手頭工具的壽命期很短,也不會花功夫去記住哪些工具註定會被淘汰。同樣,絕大多數程式設計師都沒有重視這樣一個事實:這個行業的一切都是早先積累的產物,它們之間有共同的秩序和規則,而這些東西的存在時間會比我們的壽命長得多。最優秀的程式設計師們都在踐行牛津大學一貫堅持的原則:學會拉丁和數學,走遍天下都不怕,因為你已經掌握了理解一切事物的鑰匙。(譯者:也就是已經抓住了事物的本質,掌握了學習的精髓。)

特徵

  1. 可以憑記憶背誦 C 標準庫裡的所有標頭檔案。
  2. 提到“ 500 mile email ”的時候,揚揚眉毛一副早就瞭然的樣子。
  3. 書架上有《 OpenDoc Programmer’s Guide 》的影印本,太久沒看上面落了一層灰。
  4. 可以完整說出《魔戒 | Lord of the Rings》、《星際大戰 | Star Wars》,《紅矮星號 | Red Dwarf》或《蒙提派森 | Monty Python》中的任何一句對白。
  5. 可以快速定位一個由 TCP 滑動視窗( TCP’s Sliding Window )演算法引起的同步漏洞。
  6. 可以識別出由於測試 CPU 上發生微指令錯誤而引起的 bug。
  7. 有一張來自 Donald Knuth 的個人支票,價值 2.56 刀

譯者:因為曾在 Donald Knuth 出版的書中發現過錯誤而得到這個支票獎勵,詳見 Knuth reward check

如何獲得這種特質

要達到廣博的知識面需要花費數十年的時間,但世界上每一位大師都是通過每天都做相同的三件事才達到這個水平,這三件事大致是:

  1. 努力解決他們認為很難的問題。
  2. 記錄他們是如何解決難題的。
  3. 反思他們解決難題的過程。

從前,有一個程式設計師菜鳥被一個他搞不明白的程式 bug 難倒了。在這個令人崩潰的報告裡全是看不懂的數字,比如 -32760。這些數字到底從哪來的?他按下 Ctrl-F ,在程式碼裡到處找“ -32760 ”,但是一無所獲,沒有發現任何有用的線索。 他花了一個星期的時間返回去看大學時用的破舊電腦科學課本、編譯器手冊,幾乎什麼都找過了,最後一天的時候,他那呆滯的目光突然落在了一個數字表上。他的精神早已疲憊不堪,但透過思維的迷霧他猛然認出了其中一個數字: -32768。他心裡想這個數字和自己要找的那個實在太像了,接著他注意到這個數字表格顯示的是幾種整型的表示範圍,以及每種型別都有帶符號和不帶符號兩種版本。真相的出現讓人措手不及。

對這個問題遲來的洞悉讓他非常激動,於是他為此寫了一篇部落格。很快這篇文章就消失得無影無蹤,沒什麼人閱讀,只有一群給力的小夥伴支援著他。那一夜他失眠了,一直想著那個 bug 、整型變數、由編譯器來檢查變數型別的利弊等等。

十年後,我們的這位朋友成為了公司的程式設計師主管。有一天,他眼睛一掃,發現一個初級程式設計師正耷拉著肩膀,顯然這個人是遇到了挫折。輸出視窗上顯示了一連串除錯跟蹤資訊,還有一個數字 -32762 。如今已是專家的他拍了拍這個新手的肩膀,並說“你是不是把一個無符號的 16 位整型值賦給了帶符號的 16 位整型變數了?”。

如果現在沒有遇到讓你感覺棘手的問題,那你需要換一份工作,或者換個愛好,或者換個舞臺,或者改變一下其他什麼事情。在你的工作中或學校裡,找機會做做新事物;嘗試破解你的 Roomba 機器人;從一個好幾個月都沒人碰過的開源專案中找出 bug ,並修復它;嘗試在 StackOverflow 上回答那些荒廢已久沒人回答的問題,這會迫使你去查閱那些你不懂的知識。

如果你能帶上一個有魔法的放大鏡,看看一個大師的大腦內部構造,你可能會發現有大量的神經元包圍著視覺皮質。這些神經元就像臭名昭著的“ Grandmother cells ”,它們長年累月地休眠著,但只要看到了某些象徵,它們就會被啟用,比如一個 2 的冪次函式、精度可疑的延遲(意味著 DNS 超時)、奔騰浮點除法錯誤( FDIV bug )的訊號。這些“ grandmother cells ”只有通過如此艱難的方式才能形成。

4.用程式碼表達思想

特徵

  1. 隨意交談中,他們那些信手拈來的暗喻都來源於程式設計結構的靈感。
  2. 雖然大部分時間都在“遊手好閒”,但每天都比同事提交更多無 bug 的程式碼。
  3. 站在後面看你的程式碼,並用手指出其中的錯誤。
  4. 無論是喝醉了還是躺在床上,通過電話就能正確診斷出程式碼的 bug。
  5. 洗澡的時候想出了他們最棒的程式碼。
  6. 面對一個很頑固的 bug,他們的直覺是起身出去走走。
  7. 在交談的中途突然停頓發呆,然後什麼都不解釋就拋下你,快步走向電腦。(這又叫做“ A Columbo Moment ”或“ Gregory House behavior ”)。

譯者:“ A Columbo Moment ”或“ Gregory House behavior ”是一類怪異但預示著有重大發現的行為。

如何獲得這種特質

就拿那些搗蛋鬼和他們的手機來說,一個 12 歲的小姑娘怎麼能夠在數字鍵盤上如此快速地發簡訊呢?這不是遺傳,因為所有乳臭未乾的小孩都能做到,不論是男是女,不論父母是誰;這也不是培養出來的,因為社會各個階層的孩子都能做到。你想來想去想破了腦袋,最後得到這樣一個古老的真相:人們用語言來表達思想才學會了說話。一個青少年的手指頭知道發簡訊該按哪裡,這是他們用發簡訊的方式來表達。在編輯簡訊的時候,打錯字就會感覺到不對勁。那些學習多種口語並經常使用的人傾向於用多種語言來表達自己的思想,在經過長期訓練之後,他們就不再需要先在腦子裡翻譯一遍。不用把讀入的俄語片語翻譯成英文後他們才能明白其中的含義,他們就是用俄語的方式來理解。

你不能想著“向後開炮”,然後翻譯成俄語,你應該用俄語思考如何表達。

如果你聽說過薩丕爾-沃爾夫或讀過《 1984 》等諸如此類的書,那或許你已經領會過這種隱喻:文字傳遞的是理念,語言體現的思想。無論你腦子裡掌握的是句法語言,還是視覺化或聽覺型的語言,這些都沒關係,重要的是你的大腦如何處理這些符號以及操縱這些符號的規則。

要獲得這種特質,你最好讀一讀由 Abelson 、 Sussman  和  Sussman 共著的《計算機程式的結構與解釋 | Structure and Interpretation of Computer Programs 》,並完成書中的練習。 這本書使用了 Scheme 語言介紹每一課,即使那不是你寫程式用的語言,它也仍然是教你學習程式設計的最佳語言之一。記住:學會數學和拉丁,就能理解任何事物

不管你有沒有這本書,關鍵在於練習寫程式碼,直到你能像對待自己的母語那樣閱讀和思考程式碼。你不可能在 30 天內就學會這項技能,這或許要花 30 個月以上。當你開始用程式碼來表達自己的思想,就會知道自己是不是已經獲得了這個特質。

5.   入鄉隨俗

我認為自己做不到這點,因為我就是喜歡用 MonoTouch 來寫 iOS 下的應用。我確實瞭解Objective-C,也能用它編寫應用程式,但我最愛的還是 LINQ (整合語言查詢)。如果我要為這個規則給出一個例外,可能就是“入鄉隨俗,但在羅馬會計部門的話,做一個會計該乾的事。”儘管程式碼執行在直譯器或其它層上會對效能或特性不利,但選擇某種適合特定領域的語言並不總是錯誤的。就連那些極好的程式設計師們也從不拒絕跟硬體打交道,而且還會學習相應的本機語言。抽象都是有漏洞的。(譯者:語言層面上的抽象不是萬能的,總是存在漏洞,你應該通過了解底層硬體,從而在語言提供的抽象層面之下去思考並解決遇到的問題。)

特徵

  1. 不會下意識地對跨平臺的框架感興趣。
  2. 鄙視“語言之戰”。
  3. 沒有看到用多種語言維護同一個程式在策略上存在的劣勢。
  4. 把產生 bug 的責任歸咎於編譯器、函式庫或作業系統之前,知道自己的程式碼才是根源。
  5. 派分到基於 Linux 或 Android 平臺的專案之後,會在自己的隔間裡放一個毛絨燕尾服企鵝或安卓機器人。
  6. 工作環境不變,但不斷更換手機或平板品牌。
  7. 在確認諸如 double 或 decimal 等資料型別能否按他們設想的在新裝置上執行之前,先查閱一堆技術手冊。

如何獲取這種品特質

平臺多樣性對這類傢伙而言,就像同一個餐盤中的多種蔬菜一樣平常,讓他們感到輕鬆自如。我之前說過“用程式碼作為思維表達的方式( thinking in code )”和“理智對待程式碼( emotional detachment )”都是美德,而這個特質就是前面這兩種美德的附加福利。雖然這些程式設計師很重視抽象,但他們並沒有自然而然就欣賞泛化。如果一個新平臺沒有任何優勢,那最初為什麼建立它呢?

由於我們可以用軟體解決上千種問題,因此就會有上千種計算機語言存在。在二十世紀八十年代首次推出麥金託什( Macintosh )以後,有上百種DOS產品移植到了這個滑鼠驅動的新平臺。這些產品從頭整頓基於 Alt 的使用者介面,並粗暴地將桌上型電腦的鍵盤驅動正規化轉向Mac的視覺氛圍。這些DOS產品中的大部分都被蘋果公司或市場淘汰掉了,就算它們還想捲土重來也已經落人之後,因為已經有人快速地翻開了這本裝幀成冊的人性化介面指南(HIG)並如飢似渴地在閱讀。

或許 Excel 曾經需要模仿 Lotus 1-2-3 (電子表格的開山鼻祖,由 Lotus 公司出品)基於斜線的選單;或許 AutoCAD 如今仍然需要處理命令列,但這兩個產品的設計者從未忽視這個日新月異的世界,這也是它們到今天還很著名的原因。就擴充套件來說, Objective-C 有 Categories , C# 有 Extensions ,但這兩者不太一樣,稍有不同。鍵值觀察( Key-Value Observer )或許就像是事件( Event ),這跟說“機會等同於許可”表達的含義是一樣的。

要獲得這種特質,你必須從學習一個新平臺開始,學習它獨特的指令集和使用者與之互動的方式。新平臺的大部分外觀設計得和你已經熟悉的平臺非常相似,這樣就能快速上手使用(那些“太過前衛”且改變劇烈的平臺常常會失敗),但也能讓你注意到不同之處。安卓手機常常比 iPhone 更喜歡新增硬體按鈕。或許那麼做很不錯,也有可能很糟糕,但使用者們期望以後可能有程式會用上它們。不要讓他們失望:畢竟,操控人們的思想可比控制電晶體難得多。

新平臺要麼會推出一種新的程式語言,要麼推出一些獨特的新約定,無論如何,你要學的其實就是個新的詞彙表。儘管它看上去就像是拿了一個現有平臺來進行“改造”,但這裡談到的改造必須是有意義的。他們都說“麥當勞巨無霸的特製醬不過是外面加了更多甜泡菜的千島醬”。

要管理好一個面向多平臺的單一產品,必須對你的產品進行抽象,而不是對產品要面向的平臺抽象。你可以通過消除來實現,將關於平臺特性的程式碼從產品的靈魂中抽離。如果你能掌握“渴望修復那些沒出問題的東西”這條規則,然後大刀闊斧地修整你的程式碼直到它被你精簡得所剩無幾,那最後剩下來的部分就是應該留下的。

程式碼越簡單,越好模組化;越容易模組化,就越容易解耦;越容易解耦,為了修復 bug 和新增特性而要修改的程式碼就越少;要改變的程式碼越少,就越容易將那些變化移植到其他系統。不要依賴自動化的方法——這就好像要依賴一隻貓來為你係鞋帶,不靠譜。

6.   建立自己的工具

特徵

  1. 建立了一個可自動建立的伺服器。
  2. 寫了一個自己的基準程式或專業分析器。
  3. 在 GitHub 上維護一個開源專案。
  4. 至少重造過一次 LISP。
  5. 知道什麼是特定領域語言( Domain Specific Language ),為其中某個語言設計並寫了一個直譯器。
  6. 通過自定義巨集來擴充套件 IDE 或 Editer。
  7. 桌上套著一個 Radio Shack 專案封皮,上面用 7 段顯示器展示了 bug 追蹤器拋給他們的問題個數。

相關文章