四、優秀程式設計師的跡象
我網站上閱讀量最高的文章是《糟糕程式設計師的跡象》,該文已發在《Hacker Monthly 》上,而我總覺得應該再寫一篇主題相反的文章。有些人把它看作是一種挑釁,因為他們認為我在用居高臨下的口氣對他們評頭論足。但事實並非如此,那篇文章不過是一種個人宣洩,作者在文中展示自身存在的許多問題。而且,我認為文中介紹的“補救措施”才是其大受歡迎的原因——我並不想讀者在對號入座時感到鬱悶,而是希望對大家有所裨益和啟發 。
因此,如果你認為自己缺少下面的某些品質,千萬別往心裡去。我不是一時興起才來探討這些,其中的很多跡象來自於對其他程式猿的觀察或閱讀他們的程式碼。
1. 先進行實驗是他們的本能反應
編譯器和執行環境通常能比人更快地解釋一個問題。一個優秀的程式猿在拿著問題去向別人尋求幫助之前,會自己試試看並判斷方法是否有用,而不是直接找一個高階程式設計師問“我這麼做有用嗎?”。
特徵:
- 擁有業餘專案。
- 涉獵其他多種程式語言,尤其是那些來自不同“家族”的語言(例如程式式程式設計語言、基於棧的程式語言、並行程式語言等等)。
- 當你提到arduino時,知道你在說什麼。
- 有一堆陳舊且未提交的程式碼。這些程式碼是為了模仿他人的程式碼功能而寫,但沒在工程的其他地方引用。
- 常常在會議上提出古怪又不切實際的方案。
- 有一個小隔間或一張桌子堆滿了從 ThinkGeek 買的創意玩偶。
如何獲得這種特質
你是不是常常過度謹慎?在得到肯定的時候你心裡是不是隻感到安慰?有沒有人曾經說過你有消極抵抗的態度?你或許該考慮邀請朋友們去參觀當地的六旗主題公園( Six Flags )或其他的過山車公園。如果你想體驗火一般的洗禮,那你必須先嚐試下最恐怖的部分(對我來說, King’s Dominion 的“ Drop Zone ”過山車是最恐怖的,幾年後我又去體驗了一把六旗主題公園的 Kingda Ka 過山車)。如果你覺得自己已經準備好擺脫束手束腳的兒童座椅,你或許可以去嘗試懸掛式滑翔和帆板,它們能教會你什麼是你能控制的,而哪些又是你控制不了的。
人們沒有勇氣去做實驗有一些化學方面的原因:大腦裡有少量的腎上腺素受體,因此一點點的腎上腺素就會導致你做出面對或逃避的強烈應激反應。但是,想想為什麼人們越來越能忍受咖啡的刺激?原因是咖啡因的副作用會強迫大腦產生更多的腎上腺素受體。因此,如果你強迫自己的大腦產生更多的腎上腺素受體,那麼面對同一個讓你畏懼的事情(“ fear juice ”)所觸發的腎上腺素受體數量就會變少。找出那些把你嚇得要死的經歷,多做幾次,你就會從身體層面不再恐懼冒險。
注意:
一個“常常提出怪誕又不切實際方案”的程式猿並不總是一個糟糕的程式猿。這可能是創造性思維的跡象,有這種思維的人認為對問題的證實或糾正可能會來自於某個出其不意的地方。
2. 對待程式碼和設計不要情緒化
程式碼就像紙巾:它有用你就用,沒用了就扔掉。幾乎我們所有人都認為程式碼複用( code-reuse )很重要,儘管確實如此,但是這也不意味著要像養孩子那樣去對待程式碼。程式碼沒有感覺也不會在乎,它們會像法蘭克斯坦( Frankenstein )怪物那樣攻擊你。程式碼只是一堆位元組,是一種責任( liability )。
特徵
- 已提交的程式碼中幾乎沒有被註釋掉的部分。
- 甘願拋開數週或數月的工作,就為了採用其他程式猿的優秀程式碼。
- 當別人指出他們工作中的錯誤時,手指放在嘴邊並皺著眉說“嗯”,但你卻是在看程式碼而不是那個提出評論的人。
- 對“製表符 vs 空格符”兩種縮排方式之爭不感興趣。
- 使用“這段程式碼”而不是”我的程式碼“來指代一段程式碼,除了在接受批評的時候。
- 拋棄自己某個設計,儘管它曾在某個成功的產品中使用過。
- 當老闆提到說正在為你近幾年直到現在還在進行的工程尋找現成備選時,不會變得很牴觸。
如何獲得這種特質
Konrad Lorenz 是《論侵略 | On Aggression 》的作者,他建議每個科學家都應通過扔掉自己的某一個寶貝理論來開始每一天,這樣做是為了保持敏捷。每天早上考慮扔掉自己的一個寶貝演算法、設計模式,或解決數獨( Sodoku )的一行精緻程式碼,以此來提醒自己你才是那個控制思維的人,而不是讓思維控制你。
找出最讓你自豪的程式碼,刪掉它,立刻用不同的方式從頭寫一遍。運用那些讓你困惑或反感的“設計模式”(比如 Singleton 模式),搞清楚如何讓它們發揮作用。必要的話,在這個設計模式正常工作起來之後,就刪除已經完成的工作,並用另一種新的設計模式或程式語言再嘗試一次。你不僅能學會“條條大路通羅馬”,也會明白程式碼的效用期是有限的。從本質上看,程式碼不僅和程式語言、平臺及使用的 APIs 密不可分,而且由於程式碼是以易失靜態電荷和磁粒子取向的形式寫入記憶體或磁碟,因此程式碼還受硬體的限制,同時它們還要受制於變化無常的市場、摩爾定律,還有你的老闆。
利用其他技術來打破這種處處受限的關係:
- 維護他人的程式碼。
- 無論是偶然還是赤裸裸地刻意,去經歷因為備份失敗或提交失誤而丟失一個星期的工作,並全部重寫。
- 為創業公司工作,但是一旦第二輪或第三輪融資失敗你就要捲鋪蓋走人。
- 大膽地把你最棒的程式碼貼到 Reddit 上。
- 閱讀完這篇文章後,下一步仔細閱讀《不顧一切地追求完美 | Destructive pursuit of perfection 》。
3. 磨刀霍霍地想修復那些還未出問題的地方
程式往往是固定不變的,因為建立它們是為了滿足特定的需求,但需求總是在變。優秀的程式猿知道,程式碼中隱藏著值固定的變數很糟糕。例如寫一個像 destoryBaghdad() 這樣的函式就很不道德,應該優先剔除掉“ 程式碼異味”(一些表層的問題和跡象,預示著存在潛藏的大問題)。這麼做並非是出於驕傲,也不是為了讓你的同事或寫方法論書籍的作者能拍著你的肩膀誇你好樣的。而是因為只要問題還在,你就會心癢難耐,根本停不下來。
特徵
- 不要只從字面上理解產品需求書的內容,還要盡力找出它的作者,並且搞明白他們的想法。
- 找到那些每天使用這些程式的人,並和他們交流。
- 擁有一本 Martin Fowler 寫的書。
- 常常對一些很火的技術表達極度喜歡或極度不喜歡的態度,比如 XML 、 ORM 和 REST 等,但是對其中一些技術的態度也發生過逆轉。
- 喜歡使用抽象層,但在語言或平臺已有的抽象層上最多再新增一層。
- 談論“鬆散耦合”。
- 有至少超過 10 % 的提交只是減少了程式碼行數而沒有新增新的功能。
- 在新增新特性之前,檢查判斷現存的一個特效能否通過重新設計來同時執行新舊兩個任務,還是要用一個更好的方法完全替代。
如何獲得這種特質
第一次嘗試用程式碼搞定一個程式總是會得到很多發現:問題的實質、平臺的特性和解決問題的最佳方法。第二次的嘗試會更順利些,但也許仍會繼承大量警告,而越來越多的警告就成為了你的夢魘。現如今的很多程式都跟蘇格蘭福斯橋( Firth of Forth Bridge )一樣:遠遠超過設計標準。有的時候,開發者初次解決問題就像小狗啃草坪,啃得亂七八糟;而有的時候,他們的第二次嘗試又像每隔 2 英尺就在狗身上安裝了割草鐳射塔,小心翼翼就怕哪裡會出問題。設計者還需要進行第三次嘗試,才能完全理解問題並瞭解自己還需做多少功。
在那些不需所有都推倒重來的階段,程式碼讓你受益良多。在你瞭解並明確了每一部分程式碼的功能之後,再去重寫程式碼塊,讓程式碼塊更加短小精悍、簡潔漂亮。
仔細檢查家裡的每個角落,把那些煩人但卻一直拖著沒修的東西修理好;把牆上歪了的照片擺正;疏通堵塞的水槽;修理好水槽排水管,這樣你的地下室就不會再被水淹;買一個 UPS 作為計算機的備用電源,並把計算機設定為斷電即自動啟用備用電源的模式( shut-down/back-up );將所有的白熾燈替換為節能燈;把走廊裡掛著的乙太網電纜替換成無線 WIFI ,或替換成一些適當的牆壁插座和護線管道;給你的貓拿一個真正的食物盤,替換原來那個破舊的芝士醬罐子。
接下來你應該找到自己做的上一個工程並通讀程式碼。想想每一個程式碼塊的功能:這裡有個 loop 迴圈,那裡是做排序;這裡是做些數值計算,那裡是要重新整理介面;在這裡生成 HTML 檔案,那裡是對資料庫進行增刪改查( CRUD ,即 Create、Read 、Update 和 Delete ),等等這類的事情。
現在,把硬編碼( hard-coded )的 HTML 替換成一個模板系統;業務物件中不要再用資料庫的 CRUD操作並重寫這塊程式碼,用適當的引數化查詢替換字串聯結;將錯誤處理程式中所有的“ writenlns ”函式和“ MessageBoxes ”函式替換成日誌記錄框架,由它來記錄資訊狀態;重構那些試圖從其他類中借調方法成員的程式碼;使用環境識別的字串格式化;停止猜測陣列大小,使用動態分配;刪除孤立程式碼( orphaned code )。
以這些原則為目標,它們的重要性依次遞增:
- 程式碼功能一致,但是更精煉或更高效。
- 程式碼功能一致,但是適當使用平臺內建的輔助工具,而不是自己重新設計它們。
- 程式碼功能一致,但是對於類似需求更易修改。
- 程式碼功能一致,但是更易於閱讀和理解。
- 編寫具有新功能的程式碼。
就算你堅持實踐這些原則,從而實現了目標的一半以上,也只能說你是個剛入門的學徒。只有十年如一日的實踐直到內化它們為你的本能,才能稱你為大師。
譯者: #5 在音階中處於 5 和 6 之間,也作 b6。
4. 對令人費解的事物很著迷
雖然我才剛開始理解傅立葉變換( Fourier Transform )是幹什麼的,但我學習它已經有一段時間了,因為我很固執的認為自己總會用上它的。雖然還不清楚我會用它來幹什麼,但或許有一天就會知道。我現在很清楚的是,如果搞不明白它,那學這麼久就白費了。
特徵
- 定期訪問網站 Lambda The Ultimate 。
- 瞭解 ATP 合成酶( ATP synthase )。在自己家廚房裡提取過香蕉的 DNA。
- 擁有一本龍書,尤其是那些不寫編譯器的人。
- 聽到有人說“這個是用膠帶和鐵鏽錄製的( This is recorded on sticky-tape and rust )”就會一陣傻笑。
- 從聚會上擁擠的人群中擠過去,就為了接近那個說“ Bayesian ”的傢伙。
- 為工作在其他領域並且喝醉後三句不離本行的朋友買酒。
- 喜歡向別人解釋和時事新聞毫不相關的事情,比如空客 330(Airbus 330)的駕駛艙佈局,這些都令人厭煩得要死。
- iPod 上有流行歌曲的外語版。
- 對那些擁有專業學歷(你根本一無所知的專業)的人,很羨慕但不憎惡。
譯者:這句話來自《 Secret Life Of Machines – The Vedio Recodered 》視訊,其中介紹了錄影機的工作原理和發明史。
如何獲得這個特質
這種特質趨向於從小就開始培養,但也能在成年時養成,只要你能堅持探索自己的極限。朋友是一種主要的渠道:尋找能讓你結交新朋友的場合,這種場合下大家比較淡定和從容。這種場合可能需要喝酒。不要試圖給別人深刻的印象,也不要和他人競技,你只需要欣然表現出自己的無知,看看那些人會不會願意糾正你的看法並給你啟發。然後就可以結束你的傻瓜式陷阱,聽著就好了。
當你聽到或看到不認識的事物時,常常會 Google 一下或者查詢維基百科。而對程式設計師來說,Ward Cunningham’s Wiki 同樣是很優秀的資源,值得你花數週的時間好好看看。
計算機程式設計兼併了各類科學,它的反饋迴路之廣簡直驚為天人。我們從生物學得到了遺傳演算法,從氣候學得到了混沌理論。現如今,生物學家們使用我們的成果來摺疊蛋白質( fold proteins ),氣候學家們則利用我們的模擬來預測世界末日。我們從各類學科獲得靈感,同時我們的成果也促進了它們的發展。你要麼不斷探索這神祕莫測的世界,要麼退休後就抱著一份“空空的”程式設計師工資過日子。
5. 強迫自己向他人傳授知識經驗
我曾經認識一個人,他認為“傳授知識時要留一手”,因為他們曾經在讓一個同事學會了自己的所有技能之後,他們的飯碗就丟了。我看著他們,實在難以理解。一個優秀的管理者絕不會開除那些不僅自己能勝任所有任務,還有能力訓練新員工的人,這就好比是射殺會下金蛋的鵝。如果你被炒魷魚了,很可能是其他什麼原因。
特徵
- 寫工作部落格。
- 有一個很活躍的維基賬戶。
- 別人向你請教時,毫不猶豫地拿起馬克筆走向白板。
- 往程式碼庫裡提交的更新只包含幾行註釋。
- 允許新員工借走價值 100 刀($ 100)的書。
- 將電影《天外來菌 | The Andromeda Strain 》定格在政府人員拿著銀色召集令,敲門按鈴地召集各個專家的情節上,而你卻像個瘋子一樣咧著嘴笑。
譯者:電影開場的情節是緊急召集所有專家研究這個仙女座細菌,政府人員在召集的過程中拿著銀色的野火召集令到各個專家所在地去敲門按鈴。
如何獲得這個特質
我只在有靈感或“有心情”的時候才會強迫自己給別人傳授知識,而且我認為這種情緒很受環境影響。環境因素包括自信、平臺、機會和激勵。當你還在上學時,學校為老師們提供了這樣的平臺和機會,而老師們受過的訓練也極大地給予了他們自信,但靈感卻難以捉摸。一堂讓老師和同學們都很享受的課,和只能靠死記硬背又費勁的練習之間是有區別的。
計算機程式設計新手通常不會在所有方面都是新手,因為他們有自己的生活、朋友、家庭,還有會一直堅持的興趣和愛好。或許你確實應該把那些對你來說很酷的事情解釋給朋友聽,就算會讓他們厭煩得要命,即使這些事和程式設計一毛錢關係也沒有;或許你可以教弟弟妹妹們彈吉他,或者把你最喜歡的菜譜教給他們,也可以教他們如何在彈簧單高蹺( pogo stick )上保持平衡;或許你還有一個不會滑雪的同事。教什麼不重要,重要的是你親身感受了積極地教會別人一個新事物的過程。
如果你之前從未向別人講解過任何事情,那你會很尷尬的發現:自己準備地一塌糊塗,總是在說 “額”和“嗯”,而且很容易忘記學的那個人對很多東西還不瞭解,因為自己還沒來得及解釋。
我使用的一個訣竅是,主動尋求機會向外行人解釋一個複雜學科(比如微生物學)的主題。第一次嘗試的時候,我用了一個便利貼黑板架和一大堆馬克筆,試圖把所有的東西都寫上去。我當時心裡很亂,感覺很丟臉。但幸運的是,觀眾很友好。
隔年我又試了一次,但這次我有個 iPad,並且用 Keynote(蘋果系統下的幻燈片軟體)來做演示,這個演示本身就充滿樂趣。這一次的課堂進行地完全更順利。我在幻燈片中使用了大量圖片,文字很少,幾乎沒用任何專案符號,同時又穿插了很多笑話。並且,我只憑記憶來講解幻燈片,我設計這些幻燈片是為了激發自己的相關記憶,而不僅僅是為了向觀眾展示。
初次做一份令人畏懼的工作為我下一次的嘗試提供了資料,而如今我已經完成過三四次了,一次比一次做得好。不僅如此,我現在對這個主題的瞭解是以前的十倍,因為我拼命地去學習以此來緩和怕被難題問倒的恐懼。授業本身也讓傳授者受教。