原文 What Makes A Good Engineering Culturenode
Soft & Share 取得 The Effective Engineer 做者 Edmond Lau 受權翻譯。程序員
我最喜歡問面試的工程師的其中一個問題–告訴我各一件在他們之前上班的公司中,他們喜歡和不喜歡的軟件開發團隊(譯註 : 原文爲 engineering ,可是內文都是意指軟件開發和團隊管理)文化。我已經面試了超過500人– 其中許多來自頂尖高科技公司像 Facebook ,Google,Amazon,Palantir,和 Dropbox – 隨着時間的演進,這個面試問題給了我了一種感受讓我知道優秀的工程師在尋找什麼樣的軟件開發團隊文化和避免什麼樣的軟件開發團隊文化。從這些面談迴應給個人反思和我本身從Google、Ooyala、 和 Quora 7年的工做經驗,我精選了十件軟件開發團隊能夠作的事用來建立一個良好的軟件開發團隊文化。web
快速地重複步驟速度增長工做的動機和使人感到興奮。由於基礎建設和官僚政治阻礙了代碼部署和新的功能上線,這是工程師在面試時想起來最多見並且最使人感到挫折感的事情,並且也是他們想離開目前公司的理由之一。面試
以組織而言,快速地重複步驟速度用意是給工程師和設計師擁有彈性和自主性,不用得到容許而能夠去作平常的決策。當我還在 Google 時,任何用戶能夠看到的搜索結果變動,即便是低流量的實驗,都須要 Marissa Mayer(譯註 : 後來去 Yahoo 當了 CEO ) 在每週的 UI 審查會議批准。沒必要多說,此舉是要保護 Google 這塊搜索的品牌,可是這種方式確顯著地阻礙創新。最佳化重複步驟速度也意味着有一個定義明確的產品推出的流程,因此通過有意義的投資時間後,取消產品上線這件事並不會不可預期的發生。算法
以基礎建設而言,最佳化重複步驟速度用意在建立了持續部署以支持快速驗證,高測試覆蓋率,減小建置和站臺毀損的風險,快速的單元測試激勵工程師去運行它們,快速並漸增式編譯和重載以縮短開發時間。特別值得一提,持續部署,可承諾立刻進入產品準備上線狀態。在 Quora 用持續部署以前,這技術的好處曾經對我而言很難去內化,持續部署獲得的好處對於提高重複步驟速度比起避免站臺掛掉的風險還更有價值,至少以小型的工程團隊是如此。人們對於功能增長了感到興奮和有誘因去修復 bug ,由於變動很快的從實際的流量看到。相較於一週或數週建構一次,或是有更多的批次修改,持續部署也更明顯而容易去推理並查明從有限的代碼提交中找出錯誤的來源。編程
從團隊的角度來看,快速的重複步驟速度也表明具備一羣強而有力的領導者去幫助協調和推進團隊的努力。關鍵項目利益相關者(stakeholders)在作一個需求決策,須要有效率地決定而且承諾他們的選擇。借用Bill Walsh 的一句話,他是帶領舊金山49人(譯註 一個美式足球隊)贏得 3 次超級盃的教練,優秀的領導者須要 「承諾(commit),引爆(explode)、回覆(recover)」,這意味要承諾攻擊計劃,運行它,針對結果作出反應。(注1) 一個團隊因猶豫不決而削弱其能力只會致使我的的努力舉步維艱。緩存
Instagram 共同創辦人 Mike Krieger 在他的技術演講 「Scaling Instagram」 中,談到 「爲最小的操做負擔作最佳化」 是他的13人開發團隊在產品擴展到數千萬用戶時學到了關鍵的一課。(注2) 當產品成長時,每位工程師的操做負擔也會增長,這能夠用每多少用戶須要多少工程師的比率來衡量或是多少功能須要多少工程師。例如,Facebook 以宣揚它的延展指針(scaling metrics)而聞名,像是每一位工程師支持超過100個萬用戶。(注3)服務器
自動化解決方案和將重複性任務腳本化(scripting)是很重要的,由於這件事釋放出了工程團隊的時間能夠用在實際產品開發的工做上。若是服務器失效,確保它們儘量會自動從新啓動,而且會在流量高峯時,簡單並且快速地複製本身,這是在規模擴大時,惟一明智的方式去管理複雜度。以短時間眼光,老是會有誘惑寧肯採用快速匆忙拼湊的手動折衷方法,而不要用自動化和測試一個長期的修正。架構
Etsy 的座右銘–「度量任何事,度量一切」 (注4) 這樣的需求可使用開放原代碼的監控與圖表工具像是 graphite 和 statsd 來達成,這句話強調了自動化的一個重要面向–自動化必須被數據和監控所驅動。若是沒有監控和日誌去了解發生什麼事、有些事情是如何出錯、或是爲何出錯了,自動化變成是困難的一件事。一個好的遵循座右銘會是– 「度量任何事,度量一切,儘量自動化一切」。框架
個人 MIT 教授和大學研究指導教師 Daniel Jackson 指出了良好的軟件抽象層重要性 (注 5)
「選擇對的抽象層設計, 編程將會從抽象層設計去天然地遵循, 模塊將會有小而簡單的接口 ; 不須要過分的從新組織代碼,加入新的功能也很容易適應。然而選擇錯誤的抽象層設計,編程將會出現一連串使人討厭的意外 : 接口將會變成結構複雜並且笨拙的,程序員被迫去適應沒法預期的交互做用, 甚至連最簡單的變動都很難去進行。」
可讓數千名Google 工程師能夠建置可延展性的系統其中一部分緣由是 Google 擁有像是 Jeff Dean 和 Sanjay Ghemawat 這樣真正聰明的工程師建構了像是 MapReduce, SSTable, Protocol Buffers 簡單且多才多藝的抽象層,相同的,可讓 Facebook 工程師去延展他們的系統其中一部分緣由是他們專一在類似的核心抽象層像是 Thrift,Scribe, 和 Hive。在 Quora 有一部分緣由可讓設計師更有效率地建構產品是由於有建置在其上至關簡單並且容易瞭解的 Webnode 和 Livenode 。
保持核心抽象簡單並且通用減小了客製化解決方案的須要而且增長了團隊的熟悉度與具有有共同抽象層的專門技術。逐漸普及和可靠的系統像是 Memcached, Redis, MongoDB, 等等已經減小須要自行建立客製化保存和緩存系統。寧肯讓開發團隊像漏斗狀,灌注注意力在少數的核心抽象層也不要分散注意力在特定的解決方案。這也意味共用的程序庫會更穩健,監控變得更聰明,性能特徵獲得更好的理解,測試取得更多的全面性。全部這一切都有助於一個能夠下降營運負擔的簡單系統。
維護一個高品質的代碼庫,提升了整個工程團隊的生產力。整潔的代碼更容易理解,更快速去開發,更適應於變化,而且較不容易受 bug 交互影響。一個健康的代碼審查流程讓這一切成真。
建立及時的代碼審查流程,不管是在 pre-commit 或是 post-commit 後,在幾個方面提升了代碼品質。首先,有人要審查你的代碼的同儕壓力和由於提交了設計不良的代碼將會浪費同事的時間,這對於採用不當技巧的、沒法維護的、未經測試的代碼有嚇阻的做用。其次,代碼審查提供了代碼審查者和做者交流的機會,彼此互相學習而寫出更好的代碼。
若是代碼審查流程很容易被工程團隊的其餘成員容易接近使用,那麼代碼審查也順便帶來如下的好處 a) 增長對及時審查代碼方式的責任感 b) 讓團隊成員–特別是新進的成員,從其餘人好的代碼審從中學習 c) 加快宣傳最佳的編程實踐。
反觀,追求快速的開發團隊沒有把時間花費在代碼審查,而忽略了很差的代碼很容易累積技術債。Ooyala 在它很是早期公司剛開始的時候,習慣於最佳化儘量地實做出越多的功能越好,卻疏於作代碼審查, 最後形成告終果–雖然最初的產品能夠很快地推向市場,可是產生的代碼變得修改起來很痛苦, 咱們花了一年的時間也只是在改寫脆弱的代碼以消除技術債。
Google 在公司還很小的時候,對於全部的代碼有作 pre-commit代碼審查 但規模較小的團隊並不須要那麼全面或嚴格,並且全部代碼不須要一樣嚴格地審查。Ooyala,我在那裏的時候 採用了 post-commit 方式經過電子郵件通知來審查覈心或是高風險的代碼變動。在 Quora,咱們透過 Phabricator進行的全部代碼審查,大部分透過 post-commit 方式,模型( model )或控制器( controller )代碼和視圖( view )代碼採用了不一樣的標準; 敏感代碼或重新進工程師產出的代碼,咱們使用 pre-commit 作代碼審查或是試着在提交代碼前花幾個小時內作審查。
同事之間的尊重造成了任何形式開放溝通的基礎。一個讓人們感到自在去互相挑戰對方想法的地方,也是一個合理的概念會經由辯論而前進的地方。一我的們很容易被冒犯的地方,也是重要的回饋會被壓抑的地方。
在 1948,Alex Osborn 介紹了知名的腦力激盪方法,這在過去的幾十年工做環境中一直很受歡迎,參加者會聚在一塊兒,拋開批評和負面回饋而且共同一塊兒激盪出創造性的想法,不會有被批判的恐懼。(注 6) 這種形式的腦力激盪會議關鍵在它尊重任何潛在創意。最近的心理學研究已經開始推翻 Osborn 的作法,建議在腦力激盪會議鼓勵辯論在實際上有助於避免羣體思惟,併產生更有效的思路。在這項研究中點指出,抨擊是針對概念想法而不是作人身攻擊,這在一個彼此尊重的環境中變得更加關鍵。(注 7)
工程每每跨越普遍的領域(系統,機器學習,產品等)並且不是每一個人在每個領域都同有一樣的專業知識。一個強大的團隊裏面應該有一些人對特定領域專精,即便他們跟別人相較之下有不足之處。這樣有時候提及來有點複雜,例如讓系統工程師來評估產品工程師的專長, 但去尊重這些差別性在一個健康的工程師文化是很重要的,並且並不能徹底根據本身的優點去評斷。
當很天然地每一個人對於代碼庫不一樣部分的代碼或是架構變得逐漸精通,就沒有人會以爲他們是任何代碼一部份的擁有者或是惟一的維護者。以短時間而言,當一我的擁有特定範圍的代碼一年會成爲專家或是更能增長工做性能,可是這種作法最終從長遠看對團隊而言是傷害的。
在組織中,共享代碼全部權提供了三個好處。首先,讓巴士因子(bus factor 見注 8)大於一使維護者釋放壓力而且幫團隊下降了風險若是維護者離職了。對於一我的在放假中還不用擔憂工做是很困難的一件事。我確定不會想念我在 Ooyala 是惟一維護日誌處理器開發者的那段日子,當我在夏威夷度假爬火山時,居然還會收到短信要求處理問題。
第二,共享代碼全部權受權給那些沒有深刻特定區域代碼的工程師貢獻新鮮的看法。讓工程師免於屈就於特定項目的感受而且鼓勵他們參與不同的項目,這有助於維持工做的樂趣,並提高員工學習意願和動機。從長遠來看,它下降組織有些工程師感到成長停滯而定離開的風險。
第三,共享代碼全部權,必要時要更迅速地完成戰略目標,讓多個團隊成員共同協做(swarma together: 來自敏捷開發的技術)一塊兒解決高優先級的問題殿定了基礎。孤立代碼的全部權(譯註 穀倉效應),責任一般落在一個或兩我的身上。
一個錯誤發生在許多任務程組織單位–當團隊還在很小的時候,太早切割成許多子團隊並有各自的技術領導者。子團隊打造的全部權這道牆,並減小了動機去越過那道牆。由於我的可能只會以子團隊的目標來評估。當我還在 Ooyala 公司 時還有子團隊,我錯過了與其餘團隊其中一些人一塊兒工做的機會。他們已經採用了敏捷開發流程而且有更大的重點放在共享的代碼全部權,我據說已在工做幸福感和生產力上有巨大的進步。在 Quora 工做的初期,讓我樂在其中的一個緣由是咱們超越團隊來強調項目,因此我有機會參與項目從用戶增加、機械學習、調節工具、 推薦機制、分析、網站速度和垃圾消息檢測。
單元測試的覆蓋率和必定程度的集成測試覆蓋率是惟一能夠延展的方法來管理由大型開發團隊維護的較大的代碼基底(codebase),不會常常破壞了建置(build)或是產品。自動化測試提供了信心和針對了要提升代碼品質而作大規模的重構有意義的保護。缺乏了嚴格的自動化測試,須要由工程團隊或外包測試團隊作手動測試的時間是容易變成使人望而卻步,並且很容易陷入一種恐懼去改善一段代碼的文化,只是由於它有可能被破壞了什麼。
在實務中,當團隊成長時,自動化測試是讓持續部署能夠做業的需求。當產品成長時代碼基底(codebase)的大小也隨着時間成長,可是當新進工程師加入,團隊成員對於代碼基底(codebase)的平均熟悉度也隨之降低。當代碼在開發者的腦海裏還記憶猶新的時候, 這時候測試和驗證代碼比較容易被原開發者來完成,相較於寫完代碼一個月後或是一年後再來修改。鼓勵強大的單元測試的文化,將驗證責任轉移朝向原開發者。
Gmail 發現它的根源是在 Paul Buchheit 的 20% 項目,並且他只花了一天的時間作出了初版。(注10) Google 新聞、Google Transit 和 Google Suggest 也是從 20 % 項目發起的。在 Google ,我用 20% 的時間,寫了一個 Python 框架,使得它來建置搜索頁面演示顯著更容易。雖然 Google 如今的 20% 時間跟公司剛開始的那段日子相較,產出是比較少的。(注11) 讓工程師花 20 % 的時間作某件事情跟他們的負責產品路線(product map)無關的概念,依然是小型工程組織創新的搖籃。
我還在 Ooyala 工做時,沒有正式有20%的時間策略。但我花了一些時間寫了一個 Flex 和 ActionScript 命令行(command-line)編譯工具,加速了團隊的構建(build)時間。我完成這個工具的時候恰好 Adobe 的 Flex Builder 工具煉開始走下坡,該工具仍然在使用,即便當工程團隊的規模較本來成長了三倍。通過一年實驗,Atlassian 也採用了20%的時間策略。(注12) 一種受到 Facebook 的喜好的 20% 時間策略變種,Ooyala 後來也採用了,就是按期的舉辦黑客鬆(hackathons)–一個通宵達旦的活動,其中的規則是除了你日常的項目,你能夠作任何事。(注13)
自上而下的方法作產品規劃,並且必須聚焦公司的整體方向,沒法自最接近基層的工程師取得最多的創意。 只要工程師爲他們 20% 的時間負責,而且專一於可產生高影響力的變動 ,這些項目能夠跨出較大的腳步並往進步方向前進。沒有正式的 20%的時間,這些事仍然是可能發生,可是對於工程師和設計師去嘗試瘋狂的概念是比較困難的。專一的人基本上必須利用週末的時間或是本身的假期來作這些嘗試。
學習和充分的獲得挑戰是進入心理學教授 Mihaly Csikszentmihalyi 稱之爲「心流」狀態(或是神馳狀態)的需求,若是人進入這樣的狀態徹底集中精神和被他們正在作的事所驅動,他們甚至忘了去追蹤時間。(注14) 經過快速的重複步驟(iteration)週期獲得直接和快速的回饋循環(feedback loop)是進入「心流」狀態的另外一種需求。
每週的技術講座提供了論壇(forum)讓工程師們分享他們的設計或是開發的做品,創造一個機會,讓工程師以他們的工做感到驕傲和讓團隊學習到更多他們目前工做之外的技術。將內部流程文檔化,像是 email 服務是如何運做的或是如何對搜索服務作排名變化,這也給予工程師權力本身主動去學習和探索新的技術,恰到好處跟 20 % 時間策略造成互補。在 Quora,咱們在內部有本身的 Quora 服務器,在上面咱們會問跟產品和開發相關的問題。
一個建立學習文化的必然結果是專一在師徒(mentoring)制和教育訓練去確認每個人有基本的算法、系統和爲了確保產品成功所具有的開發技能。隨着工程組織成長更大要花更多功夫投入在招募上(特別是學院招募),也須要花更多力氣投注在師徒制輔導和教育訓練。對於一位獨立的導師(mentor),天天花一個小時在一位剛到職4周內的新進工程師的工做上,這彷佛是一件沈重的工做,可是這個投入時間少於新進工程師一年內將會花費全部時間的 1% ,這有了很明顯的槓桿做用在決定新進工程師是否成功融入團隊。
招聘最好的人,是上述我所提出的許多點論述的基礎。要去尊敬一位你認爲對方是B級工程師的專業能力是很困難的一件事。若是你不信任某人的產品直覺(product instincts) ,讓他們在產品開發上有自主權是很困難的。若是沒有足夠的軟件工程經驗,要去識別正確的抽象層來建立是很困難的。若是沒有其餘聰明的工程師去挑戰你的概念和驅使你朝向簡單化,很容易掉入建構一個複雜軟件架構的陷阱。
在硅谷流傳一個 Steve Jobs 創造的說法 「A 級玩家聘請 A 級玩家。B 級玩家聘請 C 級玩家」。(注15 16) 專一在招募而且聘僱對的人是困難的可是對於一個工程組織有效率地成長是很關鍵的。Yishan Wong ,他先前在 Facebook 擔任工程經理和主管,主張招聘已成爲你們在工程組織的首要任務,並不只僅針對管理者,還包含工程師。(注17) 他還準確地指出 「招聘最好的」 和 「招聘最好的候選者」 之間的區別。
Ooyala 的早期,咱們由於客戶排入的工做而如此不堪重負,咱們幾乎下降招聘的標準因此咱們能夠聘僱足夠的工程師來完成全部的工做。我很高興咱們沒有這樣作,從較差品質代碼和團隊中的較弱工程師產生的技術債將不會中止傷害團隊和產品。
建立一個良好的軟件工程文化確定要花費不少的功夫,但由此產生的工做環境是很是值得的。
這篇博客文章源自於 Edmond 在 Quora 上的回答。
若是要找 Edmond 演講關於軟件工程文化相關主題的演講能夠跟他聯繫 。
Edmond 目前教導軟件工程師和技術經理如何有效率的建立有意義的影響力。
他是 Quip 早期的軟件工程師,曾經在 Quora、Google和 Ooyala 帶領軟件開發團隊。