1. 程式人生 > >騰訊架構師談技術管理:十年沉浮,最後我選擇了離開……

騰訊架構師談技術管理:十年沉浮,最後我選擇了離開……

轉自:http://www.techug.com/post/tencent-architect-talk-about-team-managment.html

作者介紹

韓偉,騰訊科技互娛研發部架構師。曾在網易任職8年,擔任無線事業部產品總監。多年來一直從事技術開發,擅長開發高效能系統,對於軟體架構設計也有豐富的經驗。個人的技術興趣在設計模式、軟體體系架構等提高軟體開發效率方面的知識。

從2001年在網易成為一名專案經理,到2011年進入騰訊,我經歷了從“領導”幾個人到幾百個人的好幾種管理崗位,名字有的叫“總監”,有的叫“經理”,還有什麼O之類的。但在十年之後,現在的我沒有一個下屬,一般的人看來似乎有點不可理解。正常來說,中國人的傳統是“學而優則仕”,管人的總比做事的看起來要“高階”一點。

那麼,為什麼我要“急流勇退”呢?其實並不是我覺得做一般的管理工作力不從心,也不是因為厭倦了管人,或者想要做閒雲野鶴,而是我發現,如果要真正的管理好一個技術團隊,還是要從技術方面下手。而這些真正能對技術團隊管理有幫助的技術,不實際地去學習和實踐,是非常難以掌握和熟練的。

我在管理技術團隊碰到的三大挑戰

1、人員流動

技術團隊有多難管,從人員流動這個事上,最能直接體會到。記得我第一次參加網易的校園招聘,招聘了幾十個應屆畢業生,這些畢業生在一年之內,有70%都離職了:有的是去考研、有的去留學,還有繼承家族生意和考公務員的。當然留下來的那批,也有一部分在兩年之內跳槽了。

按理說,網易也算是不錯的公司,尚且面臨如此之高的離職率,其它的公司可能會更加嚴重。我在這個事情上,花了無數的精力希望打造一個“具備凝聚力”的團隊,試圖降低這種流動性。但無論如何努力,技術團隊還是會“維持”著某個流動率,所以我意識到,如何降低人員流動對工作的衝擊,才是一個必須要做的事情。

我們知道,軟體開發的交接,不是一個簡單的事情。因為軟體開發的文件、程式碼、工作關係,甚至很多工作的經驗,都是以一種智力形式存在的。這種智力產品,如何從一個人的大腦遷移到另外一個大腦,如果不借助任何工具,無異於師徒傳授技藝,是一個效率很低,結果非常不確定的過程。所以我認為,技術知識在團隊內的共享,必須要有一些強而有力的技術工具來保障,才能成功。

2、專案進度控制

技術團隊的管理除了要應付人員流動的挑戰外,如何衡量技術人員的工作量,從而預估工期和掌控開發進度,這也是一個巨大的挑戰。這方面關於“專案管理”的知識也算汗牛充棟了。在實際的工作過程中,我們也嘗試各種方法,但是不管使用什麼“專案管理”的方法,總會發現,在專案經理的表格到產品裡可執行的程式碼之間,總有一道深深的鴻溝。

不管我們的開發進度預留多少buff,也不管我們的專案進度報告的週期,從月、周細化到日甚至小時,都無法真正準確的回答——現在專案開發到什麼地步、將來的某個時間點,專案可能開發到什麼程度。

所以我開始承認,掌控技術專案開發進度,在一些需求變更特別頻繁的領域,特別是網際網路、遊戲這類沒有明確客戶代表的領域,是一個非常模糊而且複雜的工作。我們必須拋棄工業時代對於某個“專案”的管理思路,而採用更新的思路,以及更有效的技術工具,才能真正的對專案管理提供有效的推動。

3、軟體質量提升

管理技術團隊,就必須對技術團隊的產出負責:軟體的質量和開發效率。我們既需要穩定的軟體質量,儘量少的BUG,儘量好的效能和擴充套件性,也需要能跟隨市場快速變化的軟體迭代速度。而我們的技術團隊總會抱怨,需求變化太快,沒有時間去重構系統,導致程式碼的質量下降,開發效率也受影響等等。如果我們僅僅是通過提高技術團隊的個人技術能力,或者刺激開發者更多的“主觀能動性”,結果還是會不盡人意的。因為個人的技術能力成長需要時間和實踐經驗,而且人員也很有可能會流動;如果主觀能動性被刺激成無休止的加班,到頭來最後還是會降低團隊的工作效率,因為疲勞的開發者只會製造更多的BUG和怨言。因此我們不能單靠傳統的工商管理的思路去解決技術團隊的產品質量問題,而應該看到軟體開發本身是一種具有鮮明特色的行業,要提高產品質量和生產效率,還需要使用更先進的軟體生產工具和生產流程。

人員流動、專案進度控制、軟體質量提升,是我在管理技術團隊中,碰到的最多也是最大的三個挑戰。在深刻的思考和做了大量的管理實踐後,我深深地認識到,作為一個技術團隊的管理者,最需要的往往不是所謂的“管理能力”,而是對軟體開發這個行業,更專業的技術能力。這些技術能力,大體包含了所謂的“軟體工程”知識,以及大量的軟體開發工具以及最佳行業實踐的經驗。所以我認為,認真地去研究、實踐、開發這些,能有效提高技術團隊開發效率、準確掌控專案進度、降低人員流動性影響的技術,這些是具有非常重要的意義的。

技術管理者需要研究的三種“技術”

在這裡我所說的這種“技術”,具體包含些什麼呢?概括一下,無非有這幾類:軟體模式知識、開發工具和實踐、需求領域知識:

1、軟體模式知識

主要是來自軟體工程類,包括如何寫出可讀性好的程式碼,面向物件或者結構化程式設計的知識,設計模式、架構模式等等。其中最基礎也最重要的,就是“編寫可讀性好的程式碼”,與其說這是一種知識,還不如說是一種態度。無可否認大多數工科、理科出身的程式設計師,對於寫文章的訓練都比較少,所以也不難理解為何對此沒有“感覺”。其實要編寫可讀性好的程式碼,最簡單的方式就是重視“命名”。顧名思義是人類最簡單的閱讀體驗,程式碼中的變數、函式、類的名字如果是“有意義”的,那就會大大提高程式碼的可讀性。

但是,怎樣才能定義一個有意義的名字,而不是僅僅根據技術功能實現的需求來設計名字呢?我知道我們都愛迴圈變數int i,但那是因為我們都熟悉它的這個含義。對於可能閱讀程式碼的人來說,還有什麼是確定大家都會比較熟悉的呢?肯定就是業務領域的內容,因為要接觸這份程式碼,肯定就是那些要在這個業務領域工作的人,所以使用業務領域的內容詞彙是最好的。但是,由於我們的程式碼往往會有很多層的抽象和封裝,所以在某些層次也許無法找到業務領域詞彙去對應,這確實需要一些想象力和抽象能力,但是不管這種想象的是否合理,一定會比不假思索的用Controllor或者Manager這樣的名字來得“有意義”。

除了命名以外,程式碼可讀性還有各種各樣的需求,而業界也對這一類要求,總結出很好的規範,他們就是各種“程式碼風格規範”,最著名的有Google公司開放的規範,包含了多種程式語言的版本。更重要的是,我們還可以用類似cpplint這類的“程式碼靜態檢查工具”來自動的檢查程式碼是否符合這樣的規範。就連Google這樣業界知名的公司,也會要求所有程式設計師寫出來的程式碼,都要像是一個人寫出來的那樣(出自《Google軟體測試之道》),我們還有什麼理由去追求各種程式碼編寫層面的奇技淫巧呢?

除了靜態程式碼檢查工具,我們也可以組織一些程式碼檢視(Code Reivew)來保障這個方面,所幸的是,市面上的大多數IDE都支援某些Code Review的外掛,尋找一個好的程式碼檢視工具,然後在實踐中用好這個軟體,也是一種讓人愉快的體驗。更重要的是,如果一個新入職的程式設計師,能發現自己的程式碼是受人關注的,在編碼上的技巧和問題是有人指導的,也會加強對團隊的信任和凝聚力,從另外一個意義上看,這也是一種有效的降低團隊流動性的手段。反過來說,如果不時地參加程式碼檢視或者其它程式碼監管的活動,管理者也能更準確地瞭解成員的編碼水平,從而做到賞罰有據。

在良好的程式碼可讀性基礎之上,對於程式碼模組和模組抽象,也是需要一定的專門技術的。這裡要接觸到的就是“結構化程式設計”和“面向物件”兩種概念。這兩方面的書籍汗牛充棟,但是我覺得需要強調的是,“結構化程式設計”並不和“面向物件”是衝突的,它們之間的關係非常密切。如果你能把某個需求有邏輯性的細分下去,必須要有足夠的抽象思考和業務領域理解知識。

面向物件是一種面向名詞的思考方式,結構化的思維同樣需要用到。所以結構化程式設計的思維同樣是面向物件設計的基礎。這方面的專業論述有很多,但是最可惜的是,我們很多技術團隊,僅僅把這些看成是程式設計師的“個人修養”,而不是一個團隊的必要要求,所以我們的程式碼質量往往參差不齊。

其實和“程式碼風格規範”一樣,程式碼模組的設計也是必須要符合一定規範的,這個在不同的團隊和業務領域中可能不一樣,但是沒有規範或者指導思想,是最差的一種。因為這個層面的知識,由於業務需求和領域的不同,往往很難有完全統一的業界標準,所以更加需要團隊的管理者來制訂和執行。這也是對一個技術團隊管理中最具挑戰性的部分——如何定義、抽象、管理業務模型。而這部分也是很多管理者忽視的部分,他們有太多行政工作要做,反而認為這些事情應該交由其他人代勞。在這個事情上,如果不是有業務領域經驗豐富的人去做抽象,就一定避免不了模型和需求不對應產生的修改工作量;如果不具備豐富的程式碼設計能力,如設計模式的人去設計,需求變更造成的工作量可能會毀掉整個專案。

優秀的程式設計師——往往都成了管理者,必須要發揮自己的這些智力優勢來提高技術團隊的產出,而不是去做別的一些沒有什麼“技術要求”的工作。況且這些設計工作是那麼的有挑戰性和趣味性,工作量(從開發時間看)也不是那麼大。如果管理者在系統的設計過程中和團隊密切的互動,解釋和宣導自己的想法,在執行過程中監督這些設計的實施,本身也是對產品質量的一種把控,不管是評價下屬的工作量,還是理解專案的進度和瓶頸,都是擁有第一手資料的。這種情況,就是我認為的技術管理工作,最後還是要落實到技術工作之中的重要理由。

當然,你可能會說,如果一個非常大型的團隊,CTO也是需要這樣去管理嗎?聽起來似乎不太可能,但實際上任何一個團隊,在某個時間點上,一定會有一些非常重點的專案,或者一些關鍵的問題要解決,CTO並不是簡單的做做規劃想想點子,而是要針對關鍵的業務問題,去做具體的解決方案的。這裡提一點題外的例子,比如二戰時德國裝甲兵總監古德里安,除了多次打報告要求組建強大的裝甲兵集團,還自己去找了兩輛卡車裝上鐵皮,安排模擬的坦克訓練。這類高階管理者做具體工作的例子非常多,最重要的是要抓到問題的關鍵點去做。我們最常見的毛病反而是不關注難點重點,一味高屋建瓴的提要求而不找解決方案,這是管理的大忌。

如果一個團隊能關注程式碼模組的抽象,能經常討論諸如設計模式、重構這些設計問題,那麼就能有機會在更高的抽象層次上,使用更有價值的設計理論,比如架構模式。最近幾年無論是Web service、SOA、restful,還是所謂雲(PaaS、SaaS),這些流行的名詞,從某種意義上來說,都是一種架構上的創新:結合最新的技術和最新的業務領域。使用什麼技術,上生命架構,是一個技術團隊管理者必須隨時學習和思考的問題,固步自封肯定會有穩定可靠的好處,但也是讓一個產品腐爛落後的原因。勇於挑戰和嘗試,才是一個積極向上的技術團隊的應有的氣氛,而這個氣氛首先要考驗的是管理者的勇氣。

2、開發工具和實踐

關於先進的開發工具和實踐,一直以來都有推陳出新,從最簡單的版本管理工具(《人月神話》中寫到,由於沒有版本管理工具,作者所在的團隊花了巨大的努力,制定了各種管理規範,來解決程式碼分支和覆蓋的問題,甚至要靠把原始碼列印到紙上,堆得比人還高),到各種高階的IDE軟體、缺陷管理系統、知識庫管理等等……其中自動化測試技術,是最重要的一種。

我們常常把測試認為是一種“質量檢查”的工作,但實際上,測試是程式碼生產的生產線。我們如果以測試驅動開發的角度來看,需求首先變成測試用例程式碼,具體實現程式碼的首次執行也是在測試用例程式碼中,最後整體專案的執行,也是由測試程式碼來啟動。這個過程中,測試程式碼就好像產品的模具,保障整個產品是設計的樣子。可惜我們常常並不願意花時間去打造模具,就好像我們直接用手工直接去做產品一樣。

但問題是,如果我們的產品只是一次做出來就好,但是軟體系統往往需要大量的,不同部分的修改,沒有測試系統的保障,我們肯定會改了A地方,B功能就會出錯。一個專案如果測試用例足夠全面,就算功能程式碼全部丟失了,憑藉測試用例,也能很快地重建出功能程式碼來。更重要的是,測試程式碼還能保證多個層次的程式碼,都維持一個穩定的“樣子”,這對於專案團隊的人員交接,是有重要意義的。

我們在專案管理的過程中,常常會苦於不知道專案進度如何,但如果你有一個完整的測試驅動開發的流程,這個問題就不會那麼棘手。

  • 首先,需求的明確工作可以看測試用例的編寫進度。在編寫測試用例的過程中,大量的模糊不清的需求,都會被落實成程式碼,這也排除了很多日後延期的可能。如果在比較複雜的系統中,程式碼的抽象層次有多個,所以測試用例也許同樣會有很多組。但不管怎麼說,每一層的設計最後都落實成為測試用例的話,整個專案的需求也會因此就穩定下來。
  • 然後,如果我們是針對這些測試用例去做開發,那麼每天我們都可以統計到有多少個用例被完成,這比從或空洞或繁瑣的程式設計師日報裡,可以獲得的資訊準確的多。
  • 最後,在產品運營的過程中,我們可以把所有發現的故障和缺陷,都補充為測試用例,這樣就可以確保專案的質量可以逐漸穩定下來,當我們真的需要重構的時候,只要有這些測試用例,就能放心大膽的去修改程式碼,因為只要通過所有的測試用例,專案的質量就一定是可靠的。所以一個自動化、高覆蓋率的測試系統,是一個專案在管理上最有效的工具。

測試工作有那麼多好處,但為啥總會覺得有很多困難無法實踐呢?關鍵點就是測試中的各種依賴很難構建,這就是一個比較專業的技術問題——Mock和Fack系統。所以我們的問題又一次回到了技術上,構建足夠專業的Mock和Fack系統。

3、需求領域知識

需求領域知識,從某種方面來說,不算是“純技術”的領域,但對於特定開發某個業務領域的團隊,這些知識的掌握程度,往往是至關重要的,因為只有在深刻地理解了需求,才能真正用好各種抽象、模式等軟體工程知識。

程式設計師們往往都會有一些誤區,認為只有技術領域才是自己應該關注的,有些人可以非常熟悉Linux核心的各種實現細節,但卻對最近的一個專案的市場情況漠不關心。很多程式設計師往往會認為,電腦科學中的那些知識,才是知識,而他們所接觸的其它業務領域,都應該不是他們關心的。可惜的是,大部分的程式設計師,也叫軟體工程師,都是需要解決電腦科學以外的業務問題的。所謂工程師,就是利用已有的工具,去解決實際的問題。

所以,對於實際要解決的問題領域,不進行完整細緻的學習理解是不行的。事實上,電腦科學,也是因為其它業務領域的需求而發展起來的,比如軍事、金融等。要深入地去學習一個業務行業領域的知識,也是需要很多時間的,這往往和程式設計師希望自己的技能通用化有衝突。但我認為這個世界上沒有那麼多“通用”的知識可以用,能專心做好某一個領域已經很不錯了。所以在花時間到具體的業務領域上,去學習和實踐各種技術解決方案,會比只是空泛的“領導”一隊人做事更能發揮作用。 

小結

技術團隊的管理,如果僅僅從一般意義的“管理”上去解決問題,往往是無解的。但彼得·德魯克說:管理本質就是創新。我的理解是,管理就是要去找解決問題的方法,如果這個方法看起來很不像一般意義上的管理,那也無所謂,因為解決問題才是目的。

打破對“管理”的看法,求真務實的去尋找解決問題之道,才是真正的“管理”。技術團隊的管理問題用技術手段解決,是我切身體會的最好的解決方法。