The mythical 10x programmer

Salvatore Sanfilippo

傳說中的 10 倍程式設計師

原文由 Salvatore Sanfilippo 發布,訂閱此部落格

在程式設計的神話裡,所謂的 10 倍程式設計師,指的是能完成一般程式設計師十倍工作量的人,而這裡的「一般程式設計師」,可以想像成是能把分內工作做好、但沒有 10 倍程式設計師那種神奇能力的人。更精確地說,所謂的「一般程式設計師」,代表的是在這個領域的專業人士之中,產出位於平均水準的人。

程式設計社群對於這種生物是否真的存在,看法極度兩極:有人說根本沒有 10 倍程式設計師這回事,也有人說不但真的存在,甚至只要知道去哪裡找,還能找到 100 倍程式設計師。

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

所以,如果程式的設計與實作並非線性的能力,那麼在我看來,經驗、編碼能力、知識、辨識無用部分的能力,就不只是線性的優勢,它們在創造程式的過程中是以相乘的方式共同作用的。當然,當程式設計師能同時掌握設計與實作時,這種現象會更加明顯。任務越是「目標導向」,潛在的 10 倍程式設計師就越能發揮自身能力,用少得多的力氣達成目標。當手邊的任務越是僵化,有著該用什麼工具、該怎麼實作的具體規範時,10 倍程式設計師在更短時間內完成大量工作的能力就會被削弱:他仍然可以利用「局部」的設計空間把工作做得好得多,卻無法更根本地改變達成目標的路徑,而那種根本的改變,甚至可能包括把規格中的一部分直接從專案中刪掉,讓最終要達成的目標看起來幾乎不變,但所需的努力卻大幅減少。

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

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

  • 純粹的程式設計能力:把子任務完成

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

  • 經驗:模式比對

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

  • 專注:實際時間 vs. 假想時間

    花在寫程式上的時數,如果不看時間的品質,是沒有意義的。缺乏專注可能來自內在與外在因素。內在因素包括拖延、對手邊專案缺乏興趣(你不可能把不喜歡的事做得好)、缺乏運動/身心狀態不佳、睡眠品質差或睡眠不足。外在因素則是頻繁的會議、沒有獨立辦公室的工作環境、同事經常打斷等等。很自然地,試圖提升專注、減少干擾,對程式設計的生產力會有不容小覷的影響。有時為了獲得專注,需要採取極端的手段。舉例來說,我只有偶爾才會看電子郵件,而且大部分都不會回覆。

  • 設計取捨:犧牲 5% 以換得 90%

    複雜性常常是在不願承認專案中某個非核心目標,正造成大量的設計複雜度,或是讓另一個更重要的目標變得難以達成時所產生的,因為核心功能與非核心功能之間存在著設計上的張力。對設計者而言,辨識出設計中那些不是「輕鬆獲勝」的部分非常重要,也就是投入與回報不成比例的部分。一個以最大化產出為目標來執行的專案,會精確地聚焦在真正重要、且能在合理時間內實作的面向。舉例來說,在設計訊息中介軟體 Disque 時,我在某個時刻意識到,只要對訊息僅提供盡力而為(best-effort)的順序保證,專案的其他面向就能獲得大幅改善:可用性、查詢語言與客戶端的互動、簡潔性以及效能。

  • 簡潔

    這是一個看似顯而易見,卻又什麼都沒說的要點。要理解什麼是簡潔,值得先看看複雜性通常是如何產生的。我認為,複雜性的兩個主要驅動因素,是不願做出設計上的取捨,以及在設計過程中錯誤的不斷累積。

    如果思考設計的過程,每當走上錯誤的路徑,我們就會離最佳解越來越遠。一個最初的設計錯誤,落在不對的人手裡,不會帶來對同一個系統的重新設計,而是會導致為了彌補最初的錯誤,又設計出另一個複雜的解決方案。於是,專案在每一個錯誤的步驟中,都變得更加複雜、也更沒效率。

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

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

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

    完美主義有兩種樣貌:一種是追求程式達到可量測的最佳效能的工程文化,另一種則是人格特質。在這兩種情況下,我都認為這是阻礙程式設計師快速交付成果的最大障礙之一。完美主義與對外界評價的恐懼,會植入一種設計偏誤,導致為了僅僅依循心理層面或瑣碎可量測的參數來精雕細琢設計,而做出糟糕的選擇,卻往往從未將穩健性、簡潔性、準時交付的能力等因素納入考量。

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

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

  • 底層:理解機器

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

  • 除錯能力

    要花費大量的精力來尋找錯誤,是非常容易的事。善於逐步掌握關於錯誤的狀態、並以一組理性的步驟來修復它,再加上撰寫不太可能包含太多錯誤的簡潔程式碼的態度,兩者相加,會對程式設計師的效率產生巨大的影響。

對我來說,上述這些程式設計師的特質會對產出帶來十倍的影響,一點也不令人意外。綜合起來,它們讓出發點就是可行模型的設計得以被良好地實作,並且可以比替代方案簡單好幾倍。有一種強調簡潔的方式,我喜歡稱之為「機會主義式程式設計(opportunistic programming)」。基本上,在每一個開發步驟中,要實作的功能集合,都是以用最少的努力,對程式的使用者群產生最大影響為原則來挑選的。

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

留言