架構師日記-軟體工程裡的組織文化

2023-08-29 12:01:03

一 引言

本文是京東到家自動化測試體系建設過程中的一些回顧和總結,刪減了部分系統設計與實踐的章節,保留了組織與文化相關的內容,整理成文,以饗讀者。

下面就以QA(Quality Assurance)的視角來探討工作中經常面臨的問題與挑戰。

關於軟體質量,不知道你有沒有以下困惑:

西醫中「頭疼醫頭,腳疼醫腳」的思路在研發團隊中往往不能奏效。中醫的整體辯證論治往往是解決問題的良方。其根本還是思考維度和觀察視角的不同。舉個例子來說,改變人類出行方式的,並沒有按照培育更加優良健壯的馬匹來演進,而是自行車,汽車的發明;還有被大眾經常戲說的例子,搶佔方便麵市場的不是因為某一款方便麵,可能是外賣的興起。這都告訴我們,從更高維度視角去審視問題,問題往往更容易被定位解決。我們先來看一下研發體系需求交付流程,涉及到的人員合作及各個互動階段,如下圖:

舉個例子,拿軟體漏測率高,導致線上事故頻發的現象來說。先從整個需求交付流程來看,整個產品迭代的節奏如下圖:

那麼導致漏測率高的原因是什麼呢?

可能是產品設計問題,可能是研發實施問題,可能是用例驗證問題,可能資訊不對稱的流程問題,可能是團隊共同作業節奏出現了問題,也有可能是技術儲備的問題,總結起來可以歸納為:組織支援,技術實踐,文化共識幾個維度。下面我們聚焦於組織支援和文化共識兩個方向。

二 康威定律

2.1 定律解讀

亞馬遜CEO貝索斯對於如何提高開會效率這個問題有自己的解決辦法。他稱之為「兩個披薩原則」,即與會人數不能多到兩個披薩餅還不夠他們吃的地步。

談到組織架構就繞不開號稱軟體架構設計中的第一定律,康威定律:「設計系統的架構受制於產生這些設計的組織的溝通結構」;

它們都體現了橫向溝通成本是非常高的現實。技術層面,系統各個模組間的介面也反映了它們之間的資訊流動與合作方式,也是同樣道理。

為了直觀理解,我們借用一張流傳甚廣的圖來理解一下組織結構:

其實根據原文中康威定律,又有人將其拆解為以下四個定律:

第一定律 組織溝通方式會通過系統設計表達出來。

組織的溝通和系統的設計之間緊密相連,特別是複雜系統,解決好人與人的溝通才能有一個更好的系統設計。

第二定律 時間再多一件事情也不可能做的完美,但總有時間做完一件事情。

「敏捷開發」模式很好的詮釋了這條定律,做到不斷迭代、持續交付、快速驗證和反饋,並持續改進。一句話:完成比完美更重要!

在系統真正地投入生產使用之前,再好的架構都只是假設,產品越晚被使用者使用,失敗的成本和風險就越高,而小步行進,通過MVP快速實驗,獲取客戶反饋,迭代演化產品,能有效地減少失敗的成本和風險。避免過度設計問題的出現。

第三定律 線型系統和線型組織架構間有潛在的異質同態特性。

你想要什麼樣的系統設計,就架構什麼樣的團隊,能扁平化就扁平化。最好按業務來劃分團隊,這樣能讓團隊自然的自治內聚,明確的業務邊界會減少和外部的溝通成本,每個小團隊都對自己的模組的整個生命週期負責。這是對第一定律的場景具象化;

組織和系統架構之間有一個對映關係(1 ~ 1 mapping),兩者不對齊就會出各種各樣的問題,一方面,如果你的組織結構和文化結構(民主合作式,集權式,叢林法則式,人才密度)不支援,你也無法成功建立高效的系統架構,例如集中式和嚴格職能(業務, 開發, 測試, 部署, 運維)的企業,很難推行微服務和DevOps,推行Docker/PaaS平臺也會比較困難,這樣的組織職能之間都傾向於區域性優化,無法形成有效的合作和閉環。

反過來也是成立的,如果你的系統設計或者架構不支援,那麼你就無法成功建立一個有效的組織;

第四定律 大的系統組織總是比小系統更傾向於分解。

系統越複雜,越需要增加人手,人手越多,溝通成本也呈指數增長。分而治之便是大多數公司選擇的解決方案。分不同的層級,分不同的小團隊,讓團隊內部完成自治理,然後統一對外溝通。

其實康威定義的核心要義就是如何提高組織的共同作業效率。想更加具象化的去理解,我們可以從大自然中尋找智慧,最典型的就是樹的組織結構,樹根->樹幹->樹枝->樹葉,樹根通過樹皮向上提供水分和養分到樹葉,樹葉光合作用將碳水化合物通過樹心從上向下傳導,這種生命有機體的分工共同作業方式就是符合康威定律的。另外樹狀結構在資料結構方面的效率表現也是最為均衡的。所以運用好樹狀架構,對於組織溝通共同作業乃至系統架構都是大有裨益的。重新審視一下我們的組織架構吧,這可能是繁雜問題現象後的罪魁禍首之一。

2.2 實踐案例

京東到家優惠券系統進行過一次大的改版重構。當時的業務背景是O2O業務模式經過一段時間的摸索,我們最終將超市生鮮定為業務的著力點,緊接著針對於超市生鮮業務門類的促銷便接踵而至,僅僅在新人資格上面就有:平臺新人,商家新人,首單新人等若干維度,然後在疊加渠道,城市,商家,門店,品牌,商品等各個維度的組合限制,玩法靈活,多變,需求池裡面擠壓了大量的促銷需求。

當時團隊有3個人在支援當前優惠券系統的業務迭代, 運作模式可以用豎煙囪的方式來形容。架構體系處於失控的狀態。其運轉邏輯是:為了快速支撐業務需求,減少對原有服務邏輯的影響,就只能另起爐灶,重新設計,而越是這樣,從底層的資料結構到中間的基礎服務,以及上層的業務聚合,在元件數量和結構上無法做到必要的內聚和收斂,導致部分業務很難支撐,同時線上漏洞明顯增多,最終到了難以為繼的地步。於是我們進行了系統重構,當然我們的測試人員由一個人從頭到尾全程支援,支撐起了整個重構工作的測試任務。當時的組織架構如下圖:

隨著業務的快速發展,大量的拉新促活需求接踵而至,最重要的是促銷的玩法多變,各個業務團隊都有自己的要求,比如對於使用者留存業務團隊要求有下單返券/分享領券/砍價券等場景,而對於使用者增長團隊可能想要的是定向推播優惠券/地推掃碼領券/新人紅包等玩法。業務方是多線的,而我們的研發團隊以及系統卻是單線的,這就導致了專案溝通和協調的成本巨大,由於研發資源的問題,很多需求長期處於需求池裡面得不到及時響應,即使我們試著將研發人員提高了一倍,但結果還是不能根本解決這個問題,需求交付效率成了業務痛點。

接下來我們在組織架構上做了很大的調整,首先業務架構層面,我們將使用者增長部門和使用者留存部門的業務和研發分別進行了閉環,即兩個業務部門都成立自己獨立的研發團隊內部進行領域閉環;其次我們在技術架構層面,將現有的優惠券服務進行了系統拆分,將處於優惠券核心生命週期的功能進行了中臺化,為各個部門提供基礎服務的能力,而非核心生命週期裡的比如優惠券發放門檻,觸達方式等促銷業務玩法,交由各個業務團隊內部消化就可以了。這樣就消除了業務和技術的多對一的組織共同作業模式,在團隊的溝通和共同作業效率上取得了明顯的效果。

從業務到技術研發都做到了組織和系統的拆分對映,但我們的測試團隊並沒有在第一時間及時的進行人員調整,展現出來的結果就是測試質量有所下降,同時測試效率明顯降低。因為隨著組織和系統架構的重塑,業務和研發做到了溝通共同作業的內部閉環,但對於測試同學來說卻並沒有做到,接下來我們將測試團隊再次與研發團隊的組織進行對應,完成了整個需求交付鏈路的架構調整。

三 組織文化

3.1 團隊認知

成員克服個體差異性,默契配合,彼此信任,形成真正有凝聚力的團隊,是需要一些時間的,可能需要6個月,甚至1年。凝聚力一旦真正形成,團隊的成員會一起做計劃,一起面對問題,一起搞定一切。一旦團隊有了凝聚力,但卻因為專案結束了便將這樣的團隊解散,則是極為荒謬的。最好的做法是不拆散團隊,讓他們繼續合作,只要不斷地把新專案分派給他們就行。

一些新創立的軟體外包公司試圖圍繞專案來構建團隊。這是一種不明智的做法。按照這種做法,團隊永遠都不可能形成凝聚力。每個人都只在專案中短期停留,只有一部分時間是在為專案工作,因此他們永遠都學不會如何默契配合。

專業的開發組織會把專案分配給已形成凝聚力的團隊,而不會圍繞著專案來組建團隊。一個有凝聚力的團隊能夠同時承接多個專案,根據成員各自的意願、技能和能力來分配工作,會順利完成專案。

團隊比專案更難構建。因此,組建穩健的團隊,讓團隊在一個又一個專案中整體移動共同工作是較好的做法。並且,團隊也可以同時承接多個專案。在組建團隊時,要給予團隊充足的時間,讓他們形成擬聚力,一直共同工作,成為不斷交付專案的強大引擎。

團隊的向心力如何打造?一定是結合業務場景,設定合適的價值導向。從普通的研發團隊來看,有以下幾方面可能是需要投入精力來保障的:

  1. 識別團隊瓶頸,優化木桶短板,提高資源利用率;

  2. 縮短交付週期,提高吞吐率;

  3. 週期預估準確,精準把控節奏;

如果我們的團隊產出達不到預期,那就要識別出問題出現的原因,是因為目標沒對齊,流程不規範,還是技術儲備少,基礎設施薄弱,最關鍵的是我們要有良好的洞察力和執行力。發現問題,問題就解決了一半。

  1. 目標不對齊:讓資訊透明,明確度量指標;

  2. 流程不規範:對流程進行治理,比如採用敏捷開發模式;

  3. 技術儲備少:解構->觀測->對標->學習->重構

  4. 基礎設施薄弱:善用工具(CI/CD)/自研

最困難的是做決策和執行。在執行的時候也要考慮現實的環境和團隊文化,這是自上而下快速推進位制度落地的準繩和依據。比如我們應該如何去進行需求立項,如何將專案落地?

這就需要找出我們做決策的依據和貫徹執行的方法:

  1. 做正確的事情(價值驅動-決策依據):關注ROI/優先順序;

  2. 正確的做事情(規則驅動-執行方法):關注規則/方法/質量效率體系建設;

3.2 問題認知

我想提高軟體交付質量,就需要抓住問題的本質。如何定位問題的本質呢?核心就是多問幾個為什麼。參照六度分隔(Six Degrees of Separation)理論,「你和任何一個陌生人之間所間隔的人不會超六個,也就是說,最多通過六個人你就能夠認識任何一個陌生人。」

什麼樣的狀態才算是高質量的軟體交付?

回答可能是:問題少,交付效率高。

進一步拆解,問題少,交付效率是通過什麼來衡量的?

千行bug數,單位週期上線的故事點數量。

如何統計千行bug數,單位週期上線的故事點數量?

可以藉助Bug跟蹤管理軟體,比如Jira。

第三方軟體不能很好的支援我的訴求,我想要的更多,怎麼辦?

可以研發自有的CI/CD工具...

那麼問題問到什麼時候才能結束呢?

將問題被拆解到至少可以被度量的粒度。拿軟體交付質量來講,問題可能會被拆解到下面幾個維度:

結合PDCA工具,我們可以將整個度量體系抽象為以下流程:

拆解完成的可以被執行的任務,如下:

1. 提升程式碼質量:指標度量(千行bug率,圈複雜度)/工具輔助(掃描)/服務拆分/流程保障(技術評審);

2. 加強流程把控:提測流程線上化/上線流程(質量門禁,灰度等)/指標度量(提測通過率);提高測試覆蓋率:指標度量(介面覆蓋率/程式碼覆蓋率/自動化覆蓋率/缺陷分析)等;

最終按照軟體交付流程,將產研測運等核心節點如法炮製,最終形成體系化的解決方案,如下圖:

3.3 知識賦能

在一個擁有戰鬥力的團隊中,默契和共識是基礎。而要形成某些共識,就需要擁有一套良好的問題反饋和解決機制,借事練人。可以借用如何進行單元測試和如何進行預估排期兩個工作當中常見的問題,來審視一下團隊的共識情況吧。

3.3.1 如何單元測試?

軟體可測性和研發過程息息相關的,但是現實場景是軟體開發人員很不願意編寫單元測試用例,原因有很多,比如:方法和分支太多,單元測試用例的編寫甚至要比業務程式碼還要多,時間根本不夠用;好多方法依賴於上下文,需要做模擬(mock),只有這樣才能跑起來;推行單元測試似乎就困難重重。

很多公司程式程式碼正確性的驗證就交由軟體測試人員來完成,工作的轉移必定產生了更多的溝通與共同作業成本,如果軟體不經常迭代,問題還不大,如果軟體是按照週期迭代的,每個週期都要進行全量測試,那麼這個測試團隊的人員必將會非常之大,這個問題就比較突出了,測試階段極有可能成為需求交付的瓶頸,損害軟體產品的釋出,影響業務的增長。

為了提升測試效率,很多測試過程可以進行自動化,比如迴歸測試,效能測試等。當然還有另一種提升測試效率的辦法,就是讓單元測試迴歸到開發人員的職責範圍內,當然單元測試也屬於自動化測試的範疇。

舉個我們日常web開發中經常遇到的一種場景,比如說我想根據給定的篩選條件,獲取相應的資料資訊:

範例中這個方法的測試有容器的依賴HttpServletRequest,需要模擬出來才可以測試,否則就只有把伺服器啟動才能夠執行這段程式碼,這就不屬於單元測試了,而屬於整合測試了。僅模擬容器還不夠,還需要模擬底層的資料庫才能跑起來,於是模擬就會變得越來越複雜。測試程式碼明明不復雜,單元測試的成本確非常之高,如何解決呢?

要知道我們真正要測試的是程式碼邏輯,程式碼執行所依賴的環境不是單元測試的目的,它只會讓測試變得困難。所以我們要寫可進行單元測試的程式碼,就是要測試程式碼的引數開發人員可以自由模擬,不需要依賴於環境。比如,上述範例我們就以拆分改造一下:

我們拆分出來的子方法是不需要依賴於容器環境的,這樣我們的單元測試就可以順利進行了。可能還會有人提出疑問,拆分後難道原方法裡的程式碼就不需要測試了嗎?答案其實是肯定的,因為原方法裡的程式碼都是順序執行的,並沒有邏輯,如果程式碼裡沒有邏輯,是不需要進行測試的。同樣的還有底層的資料庫操作也是如此,我們進行單元測試的時候也不需要真正的做落庫操作,落庫動作對於驗證業務邏輯本身也沒有太大意義。

單元測試交給軟體開發人員來編寫,本身是沒有問題的,有問題的其實是軟體開發人員對單元測試的認知,以及開發出來的程式碼本身。測試驅動開發模式就是規範我們進行單元測試用例編寫的一種實踐方式。

3.3.2 如何預估排期?

研發人員應該懂得如何為業務人員提供可信的預估結果,以便做出計劃。一旦做了承諾.就要提供確定的數位,按時兌現。但是大多數情況下,精確數位這很難做到。專業的做法是提供概率預估,來描述期望的完成時間及可能的變數。對預估結果,研發人員會與團隊的其他人協商,以取得共識。

1957年,為支援美國海軍的潛艇極地航行計劃,計劃評審技術(PERT, Program Evaluation and Review Technique )誕生了。PERT 的一部分內容就是對預估的計算方法。這種技術包含了一個非常簡單而有效的辦法,把預估變成概率分佈,讓主管們看懂。

你可以根據3個數位預估某項任務。這就是三元分析法。

O:樂觀預估。這是非常樂觀的數位。如果一切都異常順利,你可以在這個時間內完成。實際上,為了保證樂觀預估有意義,這個數位對應的發生概率應當小於1%。舉例:假如是1天。

N:標稱預估。這是概率最大的數位。如果畫一張柱狀圖,標稱預估就是最高的那個。舉例:假如3天。

P:悲觀預估。這是最糟糕的數位。它應當考慮到各種意外,比如颶風、核戰爭、黑洞、其他災難等。為保證悲觀預估有意義,這個數位對應的發生概率也應當小於1%。舉例:假如12天。

有了以上三個預估,我們可以這樣描述概率分佈:μ=(O+4N+P)/6

針對於例子,我們可以的出預估值(1+4*3+12)/6=4.2天

通常這個數位都有點水分,因為分佈圖的右邊部分比左邊部分長。所以我們用任務的概率分佈的標準差來衡量不確定性:σ=(P-O)/6

σ是這個任務的概率分佈的標準差,如果這個數位很大, 就表示非常不確定。對上文舉例來說,它等於(12-1)/6,也就是大概1.8天。

現在我們預估結果是4.2天/1.8(標準差),給人傳遞的資訊是,實際可能5天完成,但也可能要6天甚至9天。

實際情況可能會更復雜一些,有時候我們會多項任務並行,這時候的預估模型也會進行調整,總任務統計分佈:μseq=μtask,總標準差就是標準差平方和的平方根。

掌握一些基本的時間預估模型的知識,對於專案規劃和實施節奏的把控,是非常必要的,畢竟依據經驗甚至是拍腦袋給出的排期往往是不能讓人滿意和信服的。

四 總結

本文介紹了軟體與組織架構的關係-康威定律,並結合實際案例進行了解讀。又從組織文化層面,描述了團隊規模對軟體交付的影響,給出應該圍繞團隊來承接專案,而不是依據專案來組建團隊的觀點。接下來又藉助六度分隔(Six Degrees of Separation)理論,給出了分析問題,解決問題的方法和思路。最後介紹了團隊應該共同成長,將工作中常見的問題(比如:如何預估排期),給出科學的指導和訓練,從而打造出一支能戰能勝的「特種部隊」。

注:本文部分圖片來自網際網路

作者:京東零售 劉慧卿

來源:京東雲開發者社群 轉載請註明來源