The mythical 10x programmer

Salvatore Sanfilippo

傳說中的 10 倍程式設計師

在程式設計的神話中,所謂的 10 倍程式設計師,是指能完成一般程式設計師十倍工作量的程式設計師,而這裡所說的一般程式設計師,可以想像成是一位能勝任本職工作,卻不具備 10 倍程式設計師那種神奇能力的人。實際上,若要更精確地定義「一般程式設計師」,更恰當的說法是,他代表了在這個專業領域中,平均產出的專業程式設計師。

程式設計社群對於這種神獸是否真的存在,意見極度兩極:有人說根本沒有所謂的 10 倍程式設計師,也有人說它不僅存在,甚至只要知道去哪裡找,還能找到 100 倍程式設計師。

如果你把程式設計視為一種「線性」領域,10 倍程式設計師的存在顯然看起來就不合理。一個跑者怎麼可能比另一個跑者快上十倍?或是一個建築工人怎麼可能在同樣時間內蓋出另一個工人十倍的東西?然而,程式設計在非常特殊的意義上,是一種設計領域。即使程式設計師沒有參與程式實際的架構設計,實作的過程本身仍需要對實作策略進行子設計。

因此,如果程式的設計與實作並非線性的能力,那麼在我看來,經驗、編碼能力、知識、對無用部分的辨識等,就不僅僅是線性的優勢,它們在創造程式的過程中是以相乘的方式共同作用。當然,當一位程式設計師能夠同時掌握程式的設計與實作時,這種現象會更加明顯。任務越是「目標導向」,潛在的 10 倍程式設計師就越能發揮其能力,以少得多的心力達成目標。當手邊的任務更加僵化,有著關於該使用何種工具、該如何實作的具體規範時,10 倍程式設計師在更短時間內完成大量工作的能力就會被削弱:他仍然可以利用「局部」的設計空間來做出好得多的工作,但無法以更深刻的方式改變達成目標的路徑,而這樣的改變可能甚至包括將規格中的一部分完全從專案中移除,讓最終要達成的目標看起來幾乎不變,但達成它所需的心力卻能大幅降低。

在擔任程式設計師的二十年間,我觀察過許多與我共事的程式設計師,他們作為同事,在我的引導下為了達成特定目標而工作,也觀察過為 Redis 及其他專案提供 patch 的貢獻者。同時,也有許多人告訴我,他們認為我是個寫程式非常快的程式設計師。考量到我遠非工作狂,我也會以自己作為快速編寫程式的參考對象。

以下是我認為對程式設計師生產力影響最大的特質清單。

  • 基礎程式設計能力:完成子任務

    程式設計師最明顯的限制或優勢之一,在於處理實際實作程式中某個部分的次任務:一個函式、一個演算法或其他任何東西。令人驚訝的是,根據我的經驗,能夠非常有效率地運用基本命令式程式設計結構來實作某個東西的能力,並不如人們想像中那麼普遍。在團隊中,我有時觀察到一些非常不稱職的程式設計師,甚至連簡單的排序演算法都不知道,卻比那些理論上極為優秀、但在實作解決方案上卻非常拙劣的科班出身程式設計師完成了更多工作。

  • 經驗:模式匹配

    所謂經驗,我指的是針對許多重複出現的任務,已經探索過的解決方案集合。一位經驗豐富的程式設計師最終會知道如何處理各種子任務。這不僅能省去大量的設計工作,更重要的是,它是對抗設計錯誤的極其強大的武器,而設計錯誤本身又是簡潔性最大的敵人之一。

  • 專注:實際時間與假想時間

    如果不看時間的品質,花在寫程式上的時數是毫無意義的。缺乏專注可能由內部與外部因素造成。內部因素包括拖延、對手邊專案缺乏興趣(你無法把不熱愛的事情做好)、缺乏運動/健康不佳、睡眠品質差或睡眠不足。外部因素則包括頻繁的會議、沒有獨立辦公室的工作環境、同事頻繁打斷等等。試圖提升專注力並減少干擾,對程式設計生產力產生不容小覷的影響,似乎是理所當然的。有時為了獲得專注,需要採取極端的措施。例如,我只是偶爾才讀電子郵件,而且大多數都不回覆。

  • 設計上的取捨:犧牲 5% 以獲得 90%

    複雜性往往源於不願承認專案中一個非核心的目標,正造成了大量的設計複雜度,或是讓另一個更重要的目標變得難以達成,因為核心功能與非核心功能之間存在著設計上的張力。對於設計者而言,辨識出設計中所有並非輕鬆可得的部分至關重要,也就是那些付出與收穫不成比例的部分。一個以最大化產出為目標來執行的專案,會精確地聚焦在那些真正重要且能在合理時間內實作的層面上。舉例來說,在設計 Disque 這個 message broker 時,我在某個時刻意識到,只要對訊息僅提供盡力而為的排序,就能大幅改善專案的其他所有層面:可用性、查詢語言與客戶端的互動、簡潔性以及效能。

  • 簡潔性

    這是一個看似顯而易見,卻又包羅萬象、等於什麼都沒說的觀點。為了理解何謂簡潔,值得先檢視複雜性通常是如何產生的。我認為,複雜性的兩大主要驅動力,是不願做出設計上的取捨,以及在設計活動中錯誤的不斷累積。

    如果思考設計過程,每當走上一條錯誤的路徑,我們就會離最佳解越來越遠。一個最初的設計錯誤,在不適當的處理下,不會導致對同一系統的重新設計,反而會導致為了彌補最初的錯誤而設計出另一個複雜的解決方案。因此,專案在每一個錯誤的步驟中,都會變得更加複雜且更沒有效率。

    達成簡潔的方法,是以小型的 metal「概念驗證」來進行思考,讓程式設計師能在腦中探索大量簡潔的設計,從看起來最可行、最直接的解決方案開始著手。之後,經驗與個人的設計能力將有助於改進設計,並為需要解決的子設計找到合理的解決方案。

    然而,每當需要一個複雜的解決方案時,重要的是要花很長時間去思考如何避免這種複雜性,只有在即使考慮了完全不同的替代方案後,仍找不到更好的可能性的情況下,才繼續朝該方向前進。

  • 完美主義,或如何扼殺你的生產力並扭曲你的設計

    完美主義有兩種形式:一種是追求程式中最佳可測量效能的工程文化,另一種則是人格特質。在這兩種情況下,我都認為這是程式設計師快速交付成果的最大障礙之一。完美主義與對外界評判的恐懼,會植入一種設計偏誤,導致為了僅根據心理層面或微不足道的可測量參數來精雕設計而做出糟糕的選擇,而諸如穩健性、簡潔性、準時交付的能力等,往往完全未被納入考量。

  • 知識:一些理論會有所幫助

    在處理複雜任務時,關於資料結構、計算的基本限制、非常適合用來建模特定任務的非平凡演算法等方面的知識,將會影響找到合適設計的能力。不需要成為所有領域的超級專家,但至少要知道針對某個問題存在眾多潛在的解決方案,這一點是必要的。舉例來說,運用設計上的取捨(接受一定比例的誤差)並了解機率式集合基數估算器,可以結合在一起,以避免為了計算串流中不重複項目的數量而採用一個複雜、緩慢且記憶體效率不佳的解決方案。

  • 底層:理解機器

    即使在使用高階語言時,程式中的許多問題也源於對電腦將如何執行特定任務的誤解。這甚至可能導致需要將專案從頭重新設計與重新實作,因為所使用的工具或演算法存在根本性的問題。對 C 語言的良好掌握、對 CPU 運作方式的理解,以及對核心如何運作與系統呼叫如何實作的清晰概念,可以避免在後期出現令人措手不及的糟糕狀況。

  • 除錯能力

    為了找出錯誤而耗費龐大的心力是非常容易發生的事。善於逐步掌握關於錯誤的狀態、以一組合理的步驟來修復它,再加上撰寫不太可能包含太多錯誤的簡潔程式碼的態度,兩者相加能對程式設計師的效率產生巨大的影響。

看到上述程式設計師的特質能對產出帶來 10 倍的影響,對我來說一點也不意外。這些特質結合在一起,能讓從可行模型出發的設計得到良好的實作,並且可以比替代方案簡單數倍。有一種強調簡潔的方式,我喜歡稱之為「機會主義式編程」。基本上,在每一個開發步驟中,所選擇要實作的功能集合,都是為了以最少的心力,對程式的使用者群體產生最大的影響。

原文由 Salvatore Sanfilippo 發布

本文章由 muse-spark-1.2-contributor 進行翻譯