Web 基礎研發體系的建立

發表於2019-03-13

1 導讀

web 基礎研發體系指的是, web 研發中一線工程師所直接操作的技術、工具,以及所屬組織架構的總和。在過去提升企業研發效能的討論中,圍繞的主題基本都是——”通過雲端計算、雲端儲存等方式將底層核心技術封裝成基礎設施“。而我們在實踐中發現,在

  • 網際網路滲入到各行各業,業務爆發
  • 企業競爭白熱化,對速度和品質要求越來越高
  • 一線工程師隊伍越來越龐大,管理成本增高

這樣的多重背景下,除了底層核心技術外,一線 web 研發效能的問題也逐漸成為決勝戰場的重要因素。

然而在現實中我們看到,因為一線的研發工作可替換性強,所以並沒有受到足夠的重視,同時也缺少更統一、更有深度的規劃和管理。實際上,將一線工程師所直接接觸到的應用框架、測試、部署、監控等領域作為一個完整的體系來思考,並打造成一體化的基礎設施,能為企業的業務研發帶來巨大的效能提升。

在《月相》一章中,我們將介紹Web 基礎研發體系有哪些構成部分,並且將深入到關鍵性的技術和問題中。《潮汐》一章將介紹如何配合這套研發體系,在組織結構上做出一些調整,通過管理手段進一步挖掘團隊潛力,打造更高效的組織。

另外,希望這些內容也能為一線工程師提供一些職業規劃上的引導。

2 月相

我們將要討論的研發體系,涵蓋了”研發流程“和”系統“兩個維度。可以用一張大圖來描繪:


Web 基礎研發體系的建立


可以看到,將這些內容作為一個整體,符合目前網際網路公司”核心技術“ + ”web 研發能力“ 的模式,能快速產出應用。其中,”使用者“、”許可權“、”流程“可以說是絕大部分系統的鐵三角,因此我們也劃入到了基礎研發體系中。

接下來看每個部分。從流程的角度來說,提升效能的關鍵在於”工具化“和”自動化“,我們就以這兩點來切入。

2.1 設計

首先是設計,設計與編碼的結合是目前業界想象空間最大,但也是最不成熟的領域。對於自動化的實現,目前的嘗試大致可以歸納成兩類:

第一類,與設計師約定規則,按規則轉化設計稿。這種方式的關鍵在於,“既要規則簡單易於被設計師接受,又要保證視覺上的關係能完整轉化成程式中的關係“。我們舉個例子來說明”視覺上的關係“和”常見的程式中的關係“: 網頁上這樣一個場景:


Web 基礎研發體系的建立


可以很容易地理解為一個 Tab 元件裡面嵌著一個按鈕,他們是”巢狀關係“,在程式中用 html 可能這樣寫:

<Tabs>
  <Tabs.Pane title="tab1">  
    <Button/>
  </Tabs.Pane>
  <Tabs.Pane title="tab2" />
</Tab>
複製程式碼

但是在現代的設計工具中,圖層資訊表示的僅僅是視覺上的前後關係。


Web 基礎研發體系的建立


這就出現了一種不匹配,設計師可以通過一萬種方式來表達同樣的視覺效果。因此,要保證正確識別關係,必須和設計師約定只能以某種方式來建立圖層。但問題是這種約定本身對設計師來說沒有實際意義,對他來說只是約束。除了巢狀關係以外,位置關係也是同樣的問題——目前設計工具產出的設計稿只是某一種具體尺寸的視覺效果,而我們實際產品的尺寸會因裝置不同而不同的,甚至可以隨著瀏覽器視窗的縮放等功能動態變化:


Web 基礎研發體系的建立


怎麼來表示這種變化對設計師來說也是額外的約束。樂觀的是,從技術角度來說,總歸是可實施的。

第二類嘗試,像遊戲一樣做專用的設計工具,則從根本上解決了上述問題。


Web 基礎研發體系的建立


(React Studio)

思路很簡單,既然設計師能有多種方式來表達,那麼我們從工具角度來約束,是不是就不會有問題了?雖然同樣有約束,但是對設計師來說負擔要小多了,不需要額外記憶,按照工具的指引使用即可。我們甚至還可以提供一些高階功能防止出現一些人為錯誤,以此來吸引設計師。這種方式唯一的缺點是有一次性的學習成本。

雖然目前的自動化方案,都還只是從“視覺稿”到“程式靜態檢視”的自動化,並不包括互動邏輯的自動化,但已經有了巨大的意義。在前端程式設計師工作的統計中發現,他們有一半以上的時間都是在”調整大小、調整位置、對畫素、對色值“,而且越是好的前端,這個時間比例越大。因為寫邏輯是可以通過提升自身素質實現量級縮小的,而寫樣式這個工作本身很難實現量級的時間縮短。

如果在研發體系中,設計稿能自動轉化成可用的程式碼,無疑對傳統的 web 頁面研發會有巨大的提升。雖然做專用工具看起來應該是最終的方向,但在目前的現實環境中,可能會因為加重設計師的使用負擔而被抵制,所以通過在原有設計工具上做約定的方式來過渡可能更合適。在用約定的方案裡,怎樣讓約定即不給設計師造成太大的負擔,又能解決上述的規則轉化問題,就成了重點。在實踐中的解法是,通過工具的高階能力來補償設計師。這部分細節已在《設計稿自動生成可用頁面的展望》中詳細描述過,這裡不再贅述。

2.2 研發、測試和監控

我們將這三個環節合在一起來討論,是因為他們存在技術決策上的上下游關係。過去在大團隊中規劃研發體系,常常會出現一種現象,就是研發、測試、監控都是由不同團隊規劃的,而每個團隊都想著做平臺。後來慢慢發現這個思路是有問題的,因為做平臺必然要考慮到不同端的接入,要花成本將自己的服務抽象得足夠底層,花成本對不同的端做適配。而在這三個環節中,研發中的執行時框架(應用框架)是工具化和自動化的核心,只要對執行時框架多進行一點點投入,後面測試、反饋、監控的研發成本就能降到非常低!

舉個前端的例子。在搭建視覺化頁面搭建平臺時,我們設計了一個將“所有元件資料都統一到一棵樹”上的方案。


Web 基礎研發體系的建立


在傳統的 React 中所有元件的 state 和 props 合起來才能表達一個頁面唯一的狀態,state 和 props 分散在元件中,不易收集。而在這個設計中,全域性的 state tree 即表達了頁面的一個狀態,如果將每一次變化後的state tree 都存起來,即可通過回放來展現頁面動態變化的過程。更進一步的是,利用這個特性,我們在 200 行程式碼之內就實現了“錄製即測試用例”的功能。使用者無需寫任何晦澀的用例程式碼,在除錯自己寫的頁面時只要覺得沒問題,就可以將剛才的除錯過程儲存成一個用例。


Web 基礎研發體系的建立


再舉一個介面層的例子。我們執行時框架的介面採用了 GraphQL ,並且告別了手動寫介面的形式,全部利用檢視勾選生成。


Web 基礎研發體系的建立


這解決了兩個研發中常見的問題:


  • 杜絕了手工約定介面時可能出現的拼寫等錯誤。
  • 能自動統計到所有對某一介面進行消費的頁面,一旦介面進行調整,可以自動通知到下游,甚至能自動生成適配程式碼,不影響下游。

這也就極大地減輕了測試環節的壓力。之前的思路基本都是通過掃描程式碼去發現介面錯誤,要消耗大量資源,現在看起來沒必要了。

這兩個例子都是從研發的角度來思考所看到的收益,我們再單獨從測試與監控的角度來看。

測試領域有一個熱點,—— UI 自動化。目前的 UI 自動化有兩種方案,圖片對比 與 dom 樹對比。


Web 基礎研發體系的建立


(Screenster)

這兩種方案都有一個共同的缺點,即“無法正確地識別變化的型別”。例如現在有個需求,檢視上的兩個元素需要調換一下位置,但邏輯並沒有變,希望測試平臺不報警。除非人工干預,否則這兩種方案都很難判斷出來,因為他們是以”最後渲染結果“作為判斷依據的。但是如果我們的測試是針對執行時框架來設計的話,就很容易實現。以上面研發時所講的元件樹方案為例,頁面到底有沒有邏輯性的變化只和 state tree 有關,因為頁面的狀態是 state tree,而邏輯操作的也是 state tree,所以我們只要認為 state tree 沒變,就可以認為頁面沒有發生變化,不用觸發報警。

除了能識別變化外,利用執行時框架的設計,我們還能實現更先進的功能,例如 B/S 架構中還原瀏覽器端出錯現場的問題。在過去 debug 時,我們通常都要與測試交流,按照操作步驟手工還原到現場,如果能由程式自動化一次性達到出錯現場,那無疑能給 debug 速度帶來質的提升。要實現這種能力的關鍵點在於,任何表示頁面狀態的資料,都要能暴露到外部,也能由外部傳入進行重置。一旦有一個決定頁面狀態的變數在函式中,不能取出,不能序列化後傳給服務端,就無法做到。毫無疑問,這種能力也是需要應用框架來支援的。例子中 state tree 的設計,有一部分原因就是出於支援這種能力的考慮。

再來看監控領域的熱點,“無埋點”監控,和自動化測試有異曲同工之妙。“無埋點”指的是無手工在程式碼中的埋點,通常是使用視覺化的技術來進行“標記”。


Web 基礎研發體系的建立


(GrowingIO)

目前業界的一些方案中,遇到的問題同樣是不能正確地識別變化。例如當頁面上的元素改變了位置,埋點能不能不受影響?在視覺化搭建平臺這個專案裡,我們同樣是在應用框架這個層面設計瞭解決方案:

我們的頁面使用一種類似於模板的方式來巢狀元件,這個結構我們稱為 component tree,這個結構是靜態可分析的,所以可以很容易地實現視覺化。使用者如果想要控制元件使其產生變化,那麼必須給元件取個唯一的名字,在邏輯程式碼中使用這個名字對它的資料進行操作來實現改變。

有了這個前提,無需任何額外的投入,就已經實現了“無埋點”。因為“埋點”本身就是對邏輯功能的統計,所以埋點一定會埋在有邏輯相關的元件上,因此一定會有唯一的名字,那麼無論元件怎麼變化,只要沒有被刪除,我們的埋點資訊就不會受到影響。同時,如果一個有埋點的元件出現了改名或者刪除,我們還能自動提示報警。而這些功能,同樣是在不到200行的程式碼就實現了。


Web 基礎研發體系的建立


(埋點取名)

綜上,從測試和監控兩個角度我們也可以看到,只要執行時框架提供一點點幫助,就能以極小的成本來實施。針對確定的上游研發框架來進行下游的開發,不用再考慮對各種框架的相容問題,也可以讓下游在能力上走得更遠,實現更多先進的功能。

2.3 框架核心技術

我們線上下交流中發現,很多團隊對框架的投入只停留在寫小工具和包裝開源框架上。因為看不清方向,不知道如何投入,也不知道投入後有多少收益,所以不敢深入。其實方向和具體應該投入哪些技術,都是有跡可循的。這個蹤跡的源頭我們在 《理想的應用框架》中曾提到過的,就是程式的本質——資料和邏輯

2.3.1 資料

先具象一點來說資料。框架的資料就是框架執行時內部儲存的物件等資料結構,只要回答好兩個問題就能展現出強大的威力:


  • 資料在哪?
  • 資料的生命週期是怎樣的?

知道資料在哪,是管理資料的基本條件。應用的任何狀態,都可以看做是內部資料的一種表現。因此只有框架掌握了所有資料,才有可能實現例如還原現場之類的功能。這對我們的研發有兩點指導意義:

一是在使用已經有控制反轉和依賴注入的 web 框架時,應該完全遵循框架的約定,將服務等物件的管理完全由框架。有的框架語法寫起來比較麻煩,可以通過命令列或者IDE工具來自動生成。

二是在我們改造或者創造框架時,應該把資料的統一管理作為最基本的底線,這是上下游實現自動化的基礎。上一節中所提到的測試錄製的能力,就是建立在統一資料來源的基礎上。再舉個更有意思的例子,過去的前端的 ajax 請求基本都是獨立呼叫 api,無中心的模式。這種模式可能會出現的問題是:

請求A發出後,由於網路等問題,一直未返回,這時使用者有重新傳送一次請求 A1。結果 A1 迅速返回在回撥函式中提示成功。然後請求 A 超時返回,在回撥中提示失敗,導致最後使用者看到的是失敗的資訊。


Web 基礎研發體系的建立


當引入 saga 之後,所有非同步的操作都統一收歸到通訊管道中,就能進行跨請求的管理了。單個非同步請求的取消、多個非同步請求到底是獨立、還是競爭、還是隻保持最後一個,就都能很容易地實現了。基於中心化的請求管理,還能進行視覺化:


Web 基礎研發體系的建立



Web 基礎研發體系的建立


(kuker)

繼續講到第二個問題,資料的生命週期是怎樣的?生命週期通常是由外部事件來觸發,或者自己執行到某一階段自動觸發的。對深度開發來說,有兩個基礎能力必須由框架來提供。即框架要支援:


  • 手動驅動生命週期
  • 內部資料的複製和置換

手動驅動生命週期對自動化測試之類的功能來說很重要,特別是在做一些基礎性的測試時,有了這個能力就不用再完全模擬外部的觸發條件。而內部資料的複製和置換則能為錄製、還原現場、協同等高階功能提供基礎。我們現在就在嘗試基於這種能力,實現“使用者可以將自己的出錯場景一鍵傳送給開發人員來複現”的功能。值得注意的是,有的語言中複製物件是非常昂貴的操作,這時可能就需要考慮,是否使用 immutable 的資料格式會更好?還是依靠一些約定和標記提供自身提供廉價的複製能力?限於篇幅,在此就不再展開。對框架中的資料問題感興趣的讀者可以去搜尋 Single Source of Truth 和 Shared Mutable State 之類的話題,業界已經有非常多的精彩討論。

2.3.2 邏輯

聊完資料,終於來到最有意思的邏輯部分。框架從某種意義上來說,就是提供了一種邏輯表達的方式。要在邏輯表達上提升效能,有兩個發展階段:


  • 提供一些模式或技術。讓使用者寫出低耦合、易重用、易擴充套件的程式碼。在寫程式碼時提高效能。例如 MVC、IOC 等等。
  • 針對不同場景設計更合理的 DSL,能實現程式碼、圖等表達方式的互相轉換。在研發的整條鏈路上實現自動化。

我們看到大部分的框架都處於第一個階段,不管是伺服器端的 MVC 還是前端的 MVVM 。但也有少量第二階段的嘗試。例如 Flow Based Programming,試圖完全用資料流向的角度來詮釋業務中的邏輯。它的程式碼可以天然被分析成圖,甚至能在執行時進行觀察:


Web 基礎研發體系的建立


(noflo)

還有《理想的應用框架》中提到的基於事件來表示業務邏輯,也是一種 DSL。但這些嘗試離最終的目標仍然有差距,最終理想的狀態應該是能實現業務流程圖、時序圖、決策樹等業務領域常用的表達方式與程式碼的互轉。雖然有差距,而且看起來要走的路還很長,但是針對一些已經比較穩定的場景,已經有一些好的經驗。CMS 框架 Drupal 就是一個很好的例子。它定義好了資料釋出的整個流程和相應的鉤子系統,讓開發者用模組的方式在鉤子裡去修改或者增加自己的功能。曾經一度實現了一個非常繁榮的社群。更值得肯定的是,社群中很多模組都是視覺化的,終端使用者不需要寫任何程式碼,按照模組的視覺化指引就能完成相應的功能。這實際上就等同於 DSL 與程式碼的互轉了。

不管哪一個階段的關鍵技術,都離不開分析語義的能力。直白一點來說,就是“知道哪段程式碼是幹什麼”的能力。

在第一階段的框架中,最影響效能的因素並不是”要寫程式碼的多少“,而是寫按框架概念寫出來的程式碼是否易於理解、易於維護。這一點在越是大型、越是多人蔘與的專案中,越是明顯。而程式碼的“語義”是否清晰在某種程度上直接決定了我們是否能通過技術手段來提升可維護性。例如,在使用依賴注入的系統中,如果所有程式碼的注入宣告都清晰地表明瞭注入的到底是什麼的話,那我們就很容通過語言層面的支援或者簡單字串匹配得到依賴關係圖。反之,如果注入的資訊模糊,既可能是函式也可能是 model,沒有任何明顯約束的話,那就可能得通過語法樹,找到注入的入口才能分析出來,這樣實現的成本就成倍增加了。


Web 基礎研發體系的建立


(Rekit Studio 依賴分析圖)

相比於依賴分析,更重要的是“呼叫關係分析”,它對於幫助理解流程,特別是排查問題特別有用。舉個簡單的例子,在資料驅動的前端框架中,因為檢視完全是資料的展現,發現檢視不對了,如果能動態展示出修改了資料的業務堆疊(不是函式堆疊),就非常有用。不需要再一步一步斷點。


Web 基礎研發體系的建立


當然實現起來也更難。難點有兩個:一是依賴分析一般是執行前的,是靜態的,而呼叫關係一般是執行時的,是動態的;二是依賴通常是宣告出來,容易讀出來,而呼叫通常是在主動式的語句中,會遇到條件判斷、迴圈、甚至通過變數在不同函式、類作用域中傳遞,比較難分析。這種難,其實也就是語義不清。在框架的設計或者我們自己的改造中,可以通過三點來儘量提供明確的語義:


  • 儘量轉主動為被動
  • 儘量片段化
  • 消除使用者程式碼中的副作用和對外部作用域中變數的依賴

前兩點很好理解,被動宣告式的程式碼結構更容易被分析。雖然在實踐的時候需要大量經驗,來保障設計出來的宣告格式即能覆蓋所有場景又要容易編寫,但是它帶來的收益也是最可觀的。GraphQL 就是一個最好的例子,在伺服器端用宣告的結構將資料結構和關係表達出來,在客戶端用宣告的結構將要獲取的資料結構表達出來,後端就可以使用統一的引擎來生成呼叫,省去的大量寫介面的時間。第二點,儘量片段化是指我們在引導使用者寫程式碼的時候,應該把生命週期等等概念拆得儘可能小,使語義更細緻。寫起來繁瑣的問題可以通過工具或者語法糖去解決。

第三點最重要,消除副作用指的是任何時候執行使用者的程式碼片段應該都不會對外部環境產生影響。而消除對外部作用域中變數的依賴指的是對要用的資料、服務儘量都用引數的形式傳入。這樣做的好處有兩個,對於一些複雜的,難以分析的呼叫的關係,可以將要觀測的物件包裝一下再傳入,這樣就能動態得到呼叫關係。在整體執行前,因為無副作用,也可以很容易地通過試執行這些片段來得到一些資訊。雖然現在的語法樹工具已經比較流行,但真的要完全通過語法分析來得到足夠的語義仍然有很大的工作量。而上述的這三點,可以看做是快速、廉價的實現方式,並且實踐中效果非常不錯。

2.3.3 綜合

最後值得一提的是,上面所講到的資料和邏輯中的原則與技術並不是相互獨立的。在《前端服務化——頁面搭建工具的死與生》和《通天塔之石——企業級前端元件庫方案》這兩篇文章中看到,我們所使用的很多技術,其實是混合支撐著資料修改追溯、元件屬性視覺化等功能。他們中間有的也有著依賴關係。但相比於“資料和邏輯”這兩個源頭,這些並不重要。只要掌握了這兩個源頭面對的問題,其他都是能推匯出來的。

對開源框架如何使用也是同樣的道理。對於嚴肅的企業生產來說,應該找到業務所面臨場景的源頭,吸收解決問題的先進的想法,但自己實現,就像程式語言各自實現語言特性一樣。而不應該只是停留在包裝開源框架這個層次。開源框架為了適應儘量廣的場景,有更大的群眾基礎,給出的一定是普適性的方案,這種普適性在業務發展到一定程度,有了足夠多的獨特性之後就會變成巨大的包袱反噬研發效能。等到了這個時候再考慮自己研發,其遷移、適配、研發成本以及帶來的風險可能會變得非常大。而我們從前文看到,掌握了框架研發的幾個核心,從小的場景就開始投入,成本並不高。最重要的是長久積累形成體系後,所帶來的“流程上自動化“、”降低下游實現成本”等能力能持續地幫助企業提升研發效能。

2.4 通用子系統與核心介面

從流程的角度來看,提升效能的主要是靠自動化。而從系統的角度來說,則主要是靠能力的複用。”使用者“、”流程“、”許可權“幾乎是任何業務系統中都存在的,因此將這三者也納入到了基礎研發體系的範圍。在這裡我們並不打算深入到每個系統所面臨的具體問題中,只講兩點:

一、產品化或者子系統化,不要過早平臺化,對將來系統整體打包有益。過去的網際網路公司習慣將這些公用系統平臺化,各個業務系統來接入。但這幾年網際網路業務進入的都是新領域,面臨的市場、使用者常常是需要隔離的。這個時候系統整體複製的能力就變得非常重要,所以一開始就將這三者以子系統或者子產品的方式來對待,能為之後的發展提供更多的靈活性。

二、三者不是並列關係,不用糾結於能力解耦,制定核心系統接入規範才是最重要的。許可權系統無論是 RBAC 還是 DAC 都離不開使用者系統的支援。流程則是既依賴於許可權也依賴於使用者。如果把執行時框架看做是主機板,這三者應該是主機板上的補充部分,一起為核心系統的接入提供針腳。同樣是為了系統整體打包的能力,應該儘早制定核心系統接入的規範。

3 潮汐

在《月相》一章我們探討了 web 基礎研發體系的構成及部分重難點。相比於具體技術本身,這套方案對組織成長和重塑的意義更大。在這一章中我們會先從大團隊中兩個有啟發性的問題出發,逐步深入到如何打造一個更高效的研發組織方案中。雖然問題出現是在大團隊的,但對小團隊仍有兩點借鑑意義:


  • 小團隊隨著業務發展會長成大團隊,也可能碰到一樣的問題。
  • 問題本身萌芽於成長過程之中,予以正確的指導能更加節約人力,助力公司發展。

3.1 平臺林立

首先注意,我們討論的仍是 web 層的問題。這個現象在有多個不同業務的大公司中最常見。出現這種現象的原因有兩個,一是公司到了萬人規模,實際上就相當於上百個百人規模的小公司,必然想法很多,出現重複的自然也多。

另一個更重要是,在 web 這個領域,特別是前端,基礎設施變化太快

無論是瀏覽器底層所支援的 api,還是 javascript 語言本身變化都非常快。底層一變化,研發的各個環節必然出現基於新技術的空缺,很多框架和平臺就是隨著這些空缺出現的。現象本身存在即合理,但如果有更好的統一管理,是能從如下兩個方面提取出巨大的效能的。

一、如果將研發流程中的各個環節中獨立的平臺統一,可以極大地加速業務開發。直接決定業務發展速度的是進行業務開發的工程師。他們最希望的就是隻有一個平臺將研發的所有流程都搞定,並且儘量自動化。平臺一多,對業務開發工程師來說,學習、溝通、協作的成本就會陡增。這個成本有多大?在我們通過線下了解發現,這個成本很多時候甚至會超過業務開發本身。

二、加大對趨勢和方向的研究,預防無序的框架和平臺的投入,這樣能儘量防止走偏和無效勞動,也是一種提升。越是大的團隊,這一點越明顯。“基礎設施變化”這樣一個滾滾巨輪這些年壓碎了多少框架和平臺,其中很多產生的效益都不足以覆蓋其研發成本。更壞的是,出於個人利益等原因,有的平臺過時了也不肯下線,阻擋了整個團隊隨基礎設施一起進步的機遇,消耗的是更多的未來的人力。

我們在《月相》中提出的研發體系就是實現這兩個提升的具體手段。

首先,有一個完整的體系來將研發流程當成一個整體對待,並且通過統一的平臺來實現,能更好地實現流程的自動化。降低一線工程師溝通、學習成本。

其次,對執行時框架的投入,本身就包含著對趨勢和新技術的研究,可以緩解被基礎設施帶著跑的問題。並且我們看到執行時框架研究到了一定程度,能夠極大的減少後續測試、監控實現的成本,也降低了基礎設施變化所產生的多米諾效應。這裡對管理帶來的反思是,我們應該謹慎“平臺化”的思考。特別是下游環節,因為“平臺化”的思維,必然要考慮對各種不同的端進行適配,必然要制定各種規範,這些都是人力成本。如《月相》中所示,上游理清楚並且統一後,下游是能有針對性地、很低成本地實現的,根本不需要“平臺級”的成本投入。當然,在這裡所說的只是減少技術上的投入,環節本身還是非常重要的。

平臺林立從某一方面來說也表示著團隊內部有著大量的無序的力量,這種力量在團隊出現不同環節的分工時就產生了,儘早地建立研發體系就能儘早地將這些力量用起來,創造真正的價值。

3.2 資源池

很多大公司的 web 研發團隊都被當成資源池來用,哪個業務需要就投入到哪裡。現象的直接原因有兩個:一是從管理的角度來說,web 層的研發工作相對來說可替換性強,具備形成資源池的可能。二是 web 研發處於業務決策鏈底層,人員相對來說最緊張,因此通過資源池的方式能動態地支援業務開發,是最簡單的解決方案。但這個方案其實是相當低效的。我們從對工程師個人的關注來切入這個話題。

首先從主觀的角度出發,一個有激情,對職業未來充滿憧憬的工程師與苦大仇深的工程師在效率上是有成倍差別的。除了其本身的性格外,造就這兩種態度有很大一部分是職業上升渠道的問題。首先,和任何能被當成資源池來用的工作一樣,因為可替換性強,所以不容易被重視。其次,目前的上升渠道不夠。web 研發工程師的上升渠道要麼是縱向的,當業務發展得足夠好,重要性提高,成為系統負責人。要麼是橫向的,隨著團隊擴大,管理需要,成為管理者。這兩者一個基於業務一個基於人力,和技術相關不大。所以有才華的工程師自然會想要造框架、造平臺,努力成為公司技術中重要的一部分。但沒有正確的引導,就會成為上面所說”無序的力量“,發展得不對反而會變成公司的消耗。而當他發現自己付出的努力得不到回報的時,就有可能變成苦大仇深的工程師。

最終影響的不只是工程師自身,公司也會要在管理成本上為其買單。我們在與一些資深 hr 交流時,他們進一步說明了這個問題。在公司工作了四、五年的員工,是已經融入了公司,理解公司文化也瞭解公司問題的人,算是中流砥柱。如果得不到好的上升,可能會有兩種情況:其中有想法有行動力的,多半會選擇離開。既會對組織穩定性會造成影響,也會讓公司付出的培養成本付諸東流,對公司來說可算是很大的損失;另一種更不好的則是既不離開,也不像以前一樣努力。他們在團隊內有一定的話語權,卻喪失了進去的激情,不再發揮積極的作用。當公司需要快速擴張、快速發生變革的時候,他們就會成為隱性的管理成本。

而解決方案,其實很簡單。大公司內部通常都有”框架組“、”平臺組“類似的部門,但基本都停留在”可用“階段就完成任務了。這遠遠不夠,如果將建立 web 基礎研發體系作為目標,以產品化為衡量標準,加強重視和投入。 web 工程師的上升渠道就會得以擴張,公司內無序的力量就會進入到正確的領域。創造的價值又能進一步為研發提供能量,形成一個正迴圈,逐步緩解人力緊張的態勢,資源池現象也就自然會消失。這很像我們身體受傷時,外部腫脹只是炎症的表現,消炎了,腫脹自然也就好了。重點是找到關鍵進行消炎,而不是圍著外部現象思考。


Web 基礎研發體系的建立


建立體系還能帶來的好處是,通過提升 web 研發的效率,降低業務研發所需的人數,能幫助大公司重新回到小步快跑的節奏。張小龍有一篇演講《警惕KPI和複雜流程》,講到了小團隊的重要性,隨著網際網路公司的競爭越來越激烈,這種重要性會變得越來越高。我們從一些網際網路的新巨頭上,其實已經看見了“核心技術+基礎web研發能力”來快速出產品,佔領市場的趨勢。對小公司來說,統一的 web 基礎研發體系,是幫助實現超車的重要一環。對大公司來說,則是進一步挖掘效能,防止掉隊的必修課了。

4 後記

這篇文章筆者前後重寫了三次,因為面對 web 一線工程師這樣一個龐大的群體,效能提升已經不僅僅是技術或管理某一方面的事情,而是要綜合各個方面來尋求個人和公司發展的共贏。 web 一線研發是很多工程師進入這個領域最開始做的事情,但是筆者看到了很多有才華的人困在了低效、重複的工作裡面,努力了也因為方向不對而徒勞。這對個人和公司都是損失。在技術上找到方向,在管理上予以支援,多方發力,其實能提升的效能遠超十倍。當然,一篇文章不足以實現任何改變,這篇文章最主要的目還是拋磚引玉,也希望對這個方向有想法,志同道合的朋友聯絡我,一起交流,一起推動。

郵箱: ariesate@outlook.com。

5 答讀者問

問:研發體系的統一規劃不是破壞了競爭和創新嗎?

答:統一規劃並不是指不要競爭,不要創新。而是防止開倒車的情況出現,是給競爭和創新指定一個方向。例如我們在文中理清上下游關係,目的是指導研發力量應該往哪裡投入,在投入的過程中仍然可以採取競爭的形式。

問:框架研發提升效能的趨勢?

答:分兩個方向。一是框架本身,會朝著“增強對使用者程式碼的理解和控制力”這個方向前進。使用者按框架寫的程式碼,能不能通過工具分析出具體的語義?人工的低階錯誤能不能自動檢測出來並自動修正?能不能轉化成某種人類習慣的表達方式,比如圖?當控制力達到一定程度後,這些能力都實現後,再往下應該就是程式碼的自動生成。

另一個值得一提的是框架能力與業務特有屬性會一起沉澱到 IDE 上,會出現面向專有框架的 IDE,面向單個具體工程的 IDE。分析圖,自動掃描工具都由 IDE 作為載體,就像很多遊戲的專用編輯器一樣。只有沉澱到 IDE 上才是最便捷、最有針對性的。對這個方向感興趣的讀者可以跟我郵件討論,目前我們已經有一些初步的想法。

問:文章中講到的問題都是大公司的,對小團隊來說,什麼時候應該開始建立自己的基礎研發體系?

答:研發體系的建立可以分為規劃和實施兩個階段。規劃的話,從一開始就應該有所規劃。在前期人力不夠的情況下,不用強行追求打造自己的框架和工具,可以用開源的。但應該始終把開源的東西拿到自己的體系中,清楚地知道它在自己體系中的角色,也清晰地知道自己用了它的什麼特性,未來還需要補充什麼。什麼時候開始實施其實有一個象徵性的標準,也是我們前面在無序的力量中提到的——出現了不同環節的分工時。有的團隊業務擴張太快,人力一直不夠,那麼建議按五分之一到三分之一的比例來抽出人力打造基礎設施。磨刀不誤砍柴工,何況投資得到的回報是電鋸呢。



相關文章