我之前寫過一篇叫《加班與效率》的文章,從概念上說了一些我對“效率”的認識,但是那篇文章趨於概念化,對於一些沒有經歷過這樣的環境的同學來說,可能會覺得太抽象了。很早以前就想寫一篇更具體一點的,可執行的文章與《加班與效率》這篇文章相輝映,並再把我兩年前在杭州QCon上的那個“鼓吹工程師文化”的《建一支強大的小團隊》(新浪微盤)的觀點再加強一下。
但是我遇到了一些思維方式上的麻煩——我講的總是從我的經歷背景出發,沒有從其它人的經歷背景來講。這就好像,我在網站裡說了很多東西(比如:專職的QA,CodeReview很重要,程式設計年齡,創業的,Rework的……),有好些人覺得是不可能甚至太理想,其實我說的那些東西都是實實在在存在的,也是我所經歷過的。於是,不同的經歷,不同的環境,不同的眼界,造成了——有些人不理解我說的,而我也不能理解他們所說的。
所以,過去的這段時間我一有機會就找一些人交流並觀察一些身邊的事情,並去試著跟從和理解那些我不能理解的東西。現在覺得差不多了,所以,寫下了這篇文章。(但越是去理解對方,我就越堅持我的觀點,所以這篇文章可能還是會出現雞同鴨講的情形,無所謂了)
本文不討論任何業務上的效率問題,只討論軟體開發或是軟體工程中的效率問題。雖然產品和業務上的效率問題是根本,但是因為本文不是拉仇恨的,我也不想混在一起談,所以請原諒我在這裡先說開發團隊的,以後重新開篇文章專門談產品和業務的。
我下面會羅列幾個非常典型的開發方式——軟體開發中的“鎖”,接力棒式軟體開發,保姆式軟體開發,WatchDog軟體開發,故障驅動式軟體開發。
軟體開發中的“鎖”
如果你搞過併發程式設計,你一定知道什麼是“鎖”,鎖就是用來同步和互斥。我發現有好些開發部門裡的各個開發團隊間存在很多鎖。比如:
- 技術能力上的鎖。有一個專案需要在不同的地方做開發,這些模組用到不同的技術,比如:Java, C/C++, Python,Javascript,但是,這個團隊裡的每一個開發人員就只懂一門語言,於是,需要配合,需要任務排期,同步互斥鎖就很多,於是,一個本來只需要2個人幹3周的的工作變成了8個人幹兩個月。
- 負責模組上的鎖。同理,不同的人負責不同的模組,於是一個專案要動好多模組,那麼你就需要把這些模組的人找過來,和上面一樣。每個人都有自己的時間安排,人越多,鎖越多。於是,一個來來只需要2個人幹2兩週的事,變成了7、8個人幹一個多月。
- 時間鎖、進度鎖。這堆有不同技能或是負責不同模組的開發人員有鎖,有鎖你就要等,他們有自己的安排,所以,要協作起來,你就需要排期,去同步。而參與的人越多,你的鎖就越多。你協調他們的時間就更復雜。
- 通鎖、利益鎖。而且,最恐怖的事情是,他們之間的溝通成本巨大。他們會花大量的時間在討論,一個功能是實現在你那邊,還是我這邊,每個人都有自己的利益和算盤。無形中增加了很多推諉、官僚和政治上的東西。
【解決方案】
一個程式設計師應該能夠掌握多個語言,也能夠負責多個模組甚至不同的職責。如果一個程式設計師覺得多學習一門語言,多掌握一個模組是件很困難的事,那麼這個程式設計師本質上是不合格的。
“接力棒式”軟體開發
在有各種“工作鎖”的軟體開發團隊裡,一般都無法避免“接力棒式”的開發。也就是說,底層的C程式設計師幹完了,交給上層的Java程式設計師,然後再交給更上層的前端程式設計師,最後再交給運維人員。這就是接力棒式的開發。
而且,更糟糕的是,如果在引入了軟體流程下,這種“接力棒的方式”真是會把你搞崩潰的。比如下游團隊開發一個月,交給QA測試一個月,再交給運維分步上線一個月,然後,上游團隊拿到下游開發的API後開發一個月,再交給自己的QA測試一個月,然後再交給自己的運維上線一個月,於是,半年就這樣過去了。這是一個由一個一個小瀑布疊出來的一個大瀑布。
哦,你會說,這個好辦啊,上下游不會先商定好介面麼?然後做並行開發麼?是的,這是其中的一個優化方式,但是需要很好的介面設計。但是,在實際過程中,你會發現(這時我並非信口開河,我說的都是事實),
- 如果這兩個上下游團隊在一起還好辦,要是不在一起,那麼,實際情況是,後面的團隊會等到前面的團隊提測了,才開始開發,本質上就是序列開發的。
- 如果有更多的團隊呢?比如:A團隊 -> B團隊 -> C團隊 ->D團隊呢。介面就變得非常地關鍵了。而在實際情況下,因為沒有好的介面設計人員,所以,在開發過程經常性地修改介面,或者是因為介面不好用也只得忍著。
我以前寫過一篇叫《IoC/DIP其實是一種管理思想》,對於這種接力棒的方式,應該反過來,如果業務應用團隊是A團隊,那B/C/D團隊應該把自己的做成一個開發框架也好,服務化也好,讓應用團隊自己來接入。比如:前端做好一個前端開發框架,PE做好一個運維開發框架、各種工具,共享模組團隊做好開發框架,讓應用團隊自己來接入,而不是幫他做。你會發現,在這麼多團隊各自P2P勾況出來的很隨意的介面的所帶來的成本已經遠超過一個統一標準的協議。
“保姆式”軟體開發
所謂“保姆式”軟體開發就是——我只管吃飯,不管做菜洗碗,就像——衣來伸手,飯來張口的“小皇帝”一樣,身邊有一堆太監或宮女,不然生活不能自理。這種情況經常見於開發和測試,開發和運維間的關係。很多公司,測試和運維都成了開發的保姆。
我就能看到,很多開發快速寫完程式碼後基本上都不怎麼測試就交給QA去測試了,QA一測,我草,各種問題,而只會做黑盒的QA並不能馬上就能確定是程式碼的問題還是環境的問題,所以還要花大量時間排除不是環境問題,才給開發報BUG。很多問題,可能只需要做個Code Review,做個單測就可以發現了,硬要交給QA。運維也是一樣的,開發出來的軟體根本就沒有考慮什麼運維的東西,因為有運維人員,所以我才不考慮呢。
這和我們帶孩子的道理是一樣的,對於孩子來說,如果父母幫孩子做得越多,孩子就越覺得理所應當,就越不會去做。“保姆式”開發一般會進化成“保安式”開發。
- 因為你的團隊開發人員的能力不行,設計不行,Code Reivew/UT不做,你就只能找堆QA看著他。
- 因為Dev/QA只管功能不管運維,所以,還得找堆運維人員看著他們。
- 因為你的技術人員不懂業務,不懂需求,需要再找個BA,找個產品經理來指揮他。
- 因為你的技術人員不會管理專案,所以,再搞個專案經理,找個敏捷教練、以及SQA來管著他。
網路上一個非常經典的圖片,來源不詳,程式設計師在挖坑,其它人站在當監工
【解決方案】
1)不要招只會寫程式碼的“碼農”,要招懂“需求”,注重“軟體工程”和“軟體質量”和“軟體維護”的“工程師”。
2)最好的管理,不是找人來管人,而是自己管自己。
3)組織和團隊中支援性工作的人越少越好,最好不要。
4)服務化。我服務於你並不代表我要幫你幹活,而是代表——我要讓你幹活幹得更爽
運維要用“雲服務”的思路去做。如果一個公司內的運維團隊開發出一堆工具,讓做應用開發團隊可以很容易地申請機器、儲存、網路、中介軟體、安全等資源,並很容易管理、監控和部署應用,並提供運維資詢。而不是幫應用開發團隊幹活擦屁股當保姆。那麼,這個公司就會不經意地做出一個雲端計算平臺來了。
“WatchDog式”軟體開發
什麼是WatchDog?就是說——為了解決某個系統的問題,我要用一個新的系統去看著它。
-
我的系統架構太複雜,出了問題不好查詢。咋辦?那就搞個專門的特殊的監控系統吧……
-
我的系統配置太複雜,容易配錯了。咋辦?那就加一個配置校驗系統吧……
-
我的系統配置和真實的情況有時候可能會不一性。咋辦?那就加一個巡檢系統吧……
-
我的系統測試環境和線上環境有時候會搞混了。咋辦?那就為線上環境加一個許可權控制系統吧……
一開始沒有想清楚就放到線上,然後,出了故障後,也無法重新設計和重新架構,只能以打補丁地方式往上打,這就好像一個本來就有缺陷的樓沒有蓋好,你要拆了重蓋是不可能的,也只能不停地打補丁了。字是一隻狗,越描越醜。
【解決方案】
1)設計好了再做,簡化,簡化,簡化。
2)殘酷無情地還債,就算是CEO來了,也無法阻止我還債的腳步。
“故障驅動式”軟體開發
WatchDog式的軟體開發通常來說都是“故障驅動式”軟體開發的產物。這種開發方式其實就是在表明自己智力和能力的不足。以上線為目的,上了線再說,有什麼問題出了再改。
上面的老大或是業務方基本上會說,沒關係,我們不一開始並不需要一個完美的系統,你先上了再說,先解業務的渴,我們後面有時間再重構再完善。而有的技術人員也會用“架構和設計是逐步演化出來的”這句話來證明“故障驅動”開發是值得的。
我同意逐步迭代以及架構演化論,但是,我覺得“系統迭代說”和“架構演化論”被徹徹底底地成為那些能力有限甚至不學無術的人的超級藉口。
你們有沒有搞錯啊?你們知道什麼叫迭代,什麼叫演化嗎?你們知道,要定位一個線上的故障需要花多大的力氣嗎?
雖然,我看到那些系統在一個又一個的故障後得到一點又一點的改善,但是我想說,為什麼一開始不認真不嚴謹一點呢?我從來就沒有見過一個精良的系統是靠一個一個的故障和失敗案例給堆出來的,就算是Windows 95/98這樣史上最爛的作業系統,如果沒有設計精良Windows NT的補位,Windows也早玩完了(看看IE的下場就知道了)。
【解決方案】
1)基礎知識和理論知識非常重要。多多使用已有的成熟的方案是關鍵。
2)對技術要有一顆嚴謹和敬畏的心。想清楚了再幹,堅持高標準,Design for failure! 很多事情都急不得。
其它開發方式
其實,這樣的事情還有很多。比如:
1)配置管理上的問題。對於原始碼的配置管理,其實並不是一件簡單的事情。配置管理和軟體和團隊的組構的結構非常有關係。我看到過兩種非常沒有效率的配置管理,一種是以開專案分支的方式來做專案,同時開很多分支,分支開的時間還很長,導致merge回主幹要花大量的時間去解決各種衝突,另一種是N多的團隊都在一個程式碼庫中做修改,導致出現很多複雜的問題,比如某團隊的改動出現了一個bug,要麼所有的團隊的功能都得等這個bug被修復才能被髮布,要麼就是把所有的改動回滾到上一個版本,包括其它團隊開發的功能。很明顯,軟體模組的結構,軟體的架構,以及團隊的組織形式都會嚴重影響開發效率。
2)人肉式的軟體開發。大多數的軟體團隊和主管都會用“人手不夠”做為自己開發效率不夠的藉口,而大多數故障發生的時候,都會使用更重的“人肉流程”來彌補自己能力的不足。他們從來沒有想過使用“技術”,使用更“聰明”的方式來解決問題。
3)會議驅動式開發。人多了,團隊多了,想法也就多了,溝通也就多了,於是需要不停得開會開會開會。
總結一下
綜上所述,我有如下總結:
1)軟體工程師分工分得越細這個團隊就越沒效率,團隊間的服務化是關鍵的關鍵。不管是從語言上還是從軟體模組上的分工,越細越糟糕。服務化不是我要幫你做事,而是我讓你做起事來更容易。
2)你總需要在一個環節上認真,這個環節越往往前就越有效率,越往後你就越沒效率。要麼你設計和編碼認真點,不然,你就得在測試上認真點。要是你設計、編碼、測試都不認真,那你就得在運維上認真,就得在處理故障上認真。你總需要在一個地方認真。另外一篇文章你可以看一下——《多些時間少寫些程式碼》
3)“小而精的團隊”+“條件和資源受限”是效率的根本。只有團隊小,內耗才會小,只有條件或資源受限,才會逼著你去用最經濟的手段做最有價值的事,才會逼著你喜歡簡單和簡化。
4)技術債是不能欠的,要殘酷無情地還債。很多事情,一開始不會有,那麼就永遠不會有。一旦一個事情爛了,後面只能跟著一起爛,爛得越多,就越沒有人敢去還債。
5)軟體架構上要鬆耦合,團隊組織上要緊耦合。
6)工程師文化是關鍵,重視過程等同於重視結果。只重視結果的KPI等同事“竭澤而漁”和“飲鴆止渴”。
本文轉載自:酷殼網