為什麼我們在關於「開發者生產力」的討論中卻沒有聽到更多開發者的聲音?大多數自詡為開發者生產力專家的人似乎對銷售產品更感興趣,而不是為開發者提供真正有效的指導。這種現象可能會導致我們沉浸在各種縮略術語、神奇的指標和方法論當中,卻沒能獲得嚴謹的系統性思考。
開發者是系統性思考者。我們的工作是建模和構建系統,我們經常繪製圖表和原理圖來說明這些系統是如何工作的。但我們自己的工作藍圖卻要讓別人來畫——然而他們畫得真的很差。我懷疑自己是唯一一個謹慎對待「開發者生產力專家」所說的話的開發者。
難道我們不應該從自己的經驗和思維模式開始嗎?難道我們不應該畫一些畫來描述我們所生活的世界嗎?下面是我的一些嘗試。
我是 SDLC。你可能在一些開發者營銷活動上見過我,比如 Shift Left、DORA the DevOps Explorer 和 Agile Waterfalls。
SDLC 是軟件開發過程的共同特徵,是 DevOps 營銷活動的支柱,它包含了將代碼交付到生產環境所涉及的幾個階段。然而,SDLC 並沒有定義軟件開發最關鍵的一步:如何理解和編寫代碼本身。
作為一名開發者,我發現 SDLC 中不只有一個大循環,實際上是兩個嵌套循環:
外部循環大致與 SDLC 各個階段形成映射,並發生在 Sprint、項目或發布級別。
內部循環是「讀——寫——運行」循環,在這個循環中,你閱讀代碼、編寫代碼、運行測試,並不斷重複,直到對代碼感到滿意,這個過程每天都會發生很多次。
在開發過程中,只要「接近源代碼」,你就進入了內部循環。這種情況會在外部循環的多個階段發生,例如:
熟悉你將要做出修改的代碼。
開發新特性或修復 Bug。
修復 CI 中出現的測試錯誤。
評審補丁或對一個評論做出回應。
對失敗的部署中出現的錯誤進行調試。
處理生產事故。
針對內部循環的討論很重要,因為它是軟件開發的核心。如果你不討論它,你的組織就會把它當作無關緊要的事情來對待。
心流是內部循環的黃金狀態。心流狀態是指當你受到鼓舞和激勵時能夠達到的專注和生產力狀態。當你「連續讀取」了所有必要的內容後,你就可以享受樂趣了。此時,你可以按照你思維的速度編寫代碼。到達心流狀態的理想路徑如下圖所示:
達到心流狀態可以加速內部循環,但進入心流狀態需要一段不被打斷的時間。心理情境轉換會導致你跳出來,我從開發者那裡聽到的最常見的抱怨是有太多外部干擾。許多開發者的日常生活就如下圖所示:
破壞心流狀態的中斷事件可以是內部的,也可以是外部的。
外部上下文切換是由外部因素觸發的,如預定的會議或來自團隊成員的即興提問。
內部上下文切換是由支線任務觸發的,比如需要了解如何使用開發庫、配置工具或解決阻塞問題。
我覺得每個程序員在他們生命中的某個時刻都經歷過第一張圖所示的狀態,可能這種狀態在早期讓他們進入了編程領域——這種感覺就像是一種誘導性藥品。但是,當他們開始專業編寫代碼時,許多人會陷入第二張圖所示的狀態,這是令開發者感到痛苦和失去生產力的一個重要問題來源。
前面的幾張圖揭示了一個問題:圖中 Y 軸的「生產力」到底是什麼?許多開發者都能描述這種感覺,但我們能給出更精確的定義嗎?代碼行數?提交代碼的次數?從版本控制系統中獲得的一些合成指標?所有這些似乎都不是衡量開發者生產力的好方法。
軟件開發的核心是創新。與生產實物不同,軟件開發的目標不是生產以前生產過的東西,而是產生有用的新知識。創新的原子單位是迭代——一個內部循環周期。
開發者生產力的原子單位應該是內部循環的一次迭代。合適的單位不是代碼的數量,而是迭代的頻率,我們可以把這個量的單位叫做赫茲。
在物理世界裡,速度有兩個分量:方向和速度。類似地,開發者的速度也可以分解為方向和大小。
速度表示你有多快可以執行完一個循環內部周期。越接近心流狀態,迭代速度就越快,就能越早發布新的功能或補丁。
方向表示你所採用的技術方向——例如,是使用庫 X 還是 Y。好的方向可能會成為關鍵的捷徑。不好的方向可能意味着你以後不得不重新再走一遍。
良好的方向設定就是要做出能夠儘可能快啟動和運行端到端系統的選擇。建立一個端到端系統可以快速降低整個項目的風險。在截止日期之前達到可交付狀態意味着你可以在剩餘的時間裡進行進一步的改進。不要把目的地看作一個單一的點,而是一個結果區域。先進入結果區域,然後提升你的位置。
前面的圖片都把軟件開發看作是個體的努力,但大多數軟件其實是團隊合作開發的。團隊合作會帶來更強勁和持續的進步。正如古老的諺語所說:「如果你想走得快,就獨自前行。如果你想走得遠,就一起走。」
個體的速度往往是起伏不定的,所以不可避免地會花一些時間在不熟悉的代碼上,或者一些外部因素中斷了日常的編程進度。但是,當你把它們加在一起時,個體的凸起就變得平滑了。
如果一個團隊經歷了一段持續的低生產力時期,那麼有必要問一問是什麼因素導致了所有團隊成員的生產力下降。也許是因為一個新的季度計劃過程占用了過多時間,也許是因為其他更嚴重的因素——士氣問題、技術債務或缺乏明確的目標和優先級。
人們普遍認為,軟件團隊的生產力會隨着團隊的規模呈次線性增長,並最終會下降。這裡有一個並行計算和安達爾定律的例子:如果你將一台機器上的 CPU 數量增加一倍,程序可能會更快,但幾乎永遠不可能增加一倍那麼多。
導致計算機並行化降低的因素是 CPU 上下文切換,以及如何將工作分解成可獨立處理的塊。在軟件團隊裡,導致團隊生產力降低的主要因素是溝通成本、工作依賴、領域專業知識和熟悉環境的速度。
如果你把一個項目分解成不同的可交付塊,並在紙上畫出來,你會看到最終的成品是一個金字塔,底部的積木必須比上面的先就位:
不同領域的專業知識用不同的顏色表示。如果你是一個具備多個領域經驗的開發人員,可以自己構建整個項目。或者,你可以把任務委派給另外兩個各自在一個領域有專長的開發人員:
這兩個開發人員的優勢是他們可以並行地構建單獨的塊,但他們的並行性受到串行依賴關係 (一些塊必須先於其他塊放置)、理解不熟悉的代碼和溝通成本的限制。
兩個開發人員完成項目的速度一定是一個開發人員的兩倍,這只是一廂情願的想法。事實上,即使是淨加速度都無法保證。但如果有良好的分工和團隊關係,一定程度的淨加速度是可以實現的。
然而,每增加一個人,也增加了協調任務的複雜性。在大多數團隊中,每增加一個人的回報率都在大大減少。這就是為什麼許多組織優先招聘和留住最好的開發人員,而不只是擴大團隊的規模。他們還在工具方面投入,進一步提高個人生產力,協調大規模的軟件開發。
我之前說過,如果開發者不談論生產力的這些元素,我們的組織就不會意識到它們的重要性。
然而,更糟糕的是,總會有人試圖說服我們的組織:其他事情更重要。很多時候,我們發現自己被塞進了一個框架中,這個框架將軟件開發看成是一個沒有想象力的小部件工廠,而不是一個探索之旅。他們不重視內部循環 (充分理解並創建所有的代碼),而且要求我們只是機械式地考慮外部循環。如果你甚至都無法在代碼中自由地跳轉,所謂的「變革失敗率」又有什麼用?作為工程師,我們沒有在可以用提高我們生活質量的工具上投入,而是被迫陷入「人月神話」的謬誤,結局就是更多的人、更多的代碼和更多的問題。
這對我們、整個行業和社會都有好處,有助於提升可以反映我們工作現實並尊重其基本創造力的思維模式。
在這篇文章中,我畫了一些能夠引起開發者共鳴的圖片。你呢?當你在思考你自己和團隊的開發過程時,你看到了什麼樣的畫面?
作者簡介:
Beyang Liu 是 Sourcegraph 的首席技術官和聯合創始人。Sourcegraph 是一個代碼智能平台,幫助更多的人更容易地訪問代碼。在加入 Sourcegraph 之前,Beyang 是 Palantir Technologies 的軟件工程師,為財富 500 強公司開發數據分析軟件。Beyang 在斯坦福大學學習計算機科學,並發表了關於概率圖形模型和計算機視覺的研究論文。
原文鏈接:
https://about.sourcegraph.com/blog/developer-productivity-thoughts