日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Google的軟件工程概述

 Rdubuis 2017-02-15

1. 介紹

Google已經(jīng)是一個非常成功的公司。正如在搜索和競價廣告方面的成功一樣,Google也提供了許多其他突出產(chǎn)品,包括Google地圖,Google新聞,Google翻譯,Google語音識別,Chrome和Android。Google還通過購買小公司大大增強和擴展了許多產(chǎn)品,例如YouTube,并對多種多樣的開源項目做出了重大貢獻。Google也展示了一些尚未投入市場的驚人產(chǎn)品,如自動駕駛汽車。


Google的成功有很多原因,包括開明的領(lǐng)導(dǎo)力,技術(shù)牛人,高標(biāo)準(zhǔn)招聘,以及成功帶來的經(jīng)濟實力,可以在非常迅速增長的市場早期進行介入。但其中一個原因是谷歌開發(fā)出的優(yōu)秀軟件工程實踐,這幫助谷歌走向成功。這些實踐基于全球最有才華的軟件工程師的大量積累和提取的智慧,隨著時間的推移而不斷演化。我們想跟全球各地的人們分享我們的知識與實踐以及我們從中學(xué)到的一些教訓(xùn)。


本文的目的是記載并簡要介紹Google的關(guān)鍵軟件工程實踐。其他組織和個人可以進行比較和對比,并考慮是否應(yīng)用一些做法。


許多作者(例如[9],[10],[11])都有書籍或文章來分析Google的成功歷史。但大多數(shù)主要涉及商業(yè),管理和文化;只有一小部分(例如[1,2,3,4,5,6,7,13,14,16,21])談到了軟件工程方面的內(nèi)容,大多數(shù)只探討一個方面;并且沒有從整體上提供一個簡短的、書面的關(guān)于谷歌軟件工程實踐的概述,本文目的正在于此。


2. 軟件開發(fā)

2.1 源碼存儲庫

大多數(shù)Google代碼存儲在一個統(tǒng)一的源代碼存儲庫中,Google的所有軟件工程師都可以訪問。有一些值得注意的例外,特別是兩個大型開源項目Chrome和Android,分別使用了獨立的開源代碼存儲庫,以及一些高價值或關(guān)鍵的安全代碼有更嚴(yán)格的訪問限制。但大多數(shù)Google項目共享相同的存儲庫。自2015年1月起,這個86 TB的存儲庫包含了10億個文件,包括超過900萬個源代碼文件,20億行源代碼,具有3500萬個版本修改的歷史記錄和每工作日提交的4萬個版本修改的變更率[18]。存儲庫的寫訪問是受控的:只有存儲庫的每個子分支列出的所有者才可以批準(zhǔn)修改該分支。但一般來說任何工程師都可以訪問任一代碼段,可以簽出并構(gòu)建,可以進行本地修改,可以測試它們,并可以發(fā)送變更以供代碼所有者審核,如果所有者同意,可以簽入(提交)這些變更。在文化上,鼓勵工程師修復(fù)他們看到的任何有問題的知道如何修復(fù)的軟件,無論項目邊界如何。這鼓勵了工程師并帶來了更高質(zhì)量的基礎(chǔ)設(shè)施,更好地滿足了使用它的人的需求。


幾乎所有的開發(fā)都發(fā)生在倉庫的“頭部head”(指git中的head),而不是在分支上。這有助于早期識別集成問題,并最大限度地減少所需的合并工作量。也更容易和更快地推出安全修復(fù)程序。


頻繁運行測試的自動化系統(tǒng),通常在每次更改任何文件,進行傳遞性依賴測試之后進行,雖然這并不總是可行的。這些系統(tǒng)自動通知作者和審閱者測試失敗的任何變更,通常都在幾分鐘之內(nèi)完成。大多數(shù)團隊通過安裝使構(gòu)建的當(dāng)前狀態(tài)突出顯示,甚至用顏色編碼來表示(綠色為建立成功和所有測試通過,紅色表示有一些測試未通過,黑色表示失敗的構(gòu)建)。這有助于工程師集中精力注意保證構(gòu)建通過。大多數(shù)更大的團隊也有一個“構(gòu)建巡警”負責(zé)確保測試的持續(xù)通過,通過與作者合作,不期望的變更能快速修復(fù)或回滾。(構(gòu)建巡警角色通常在團隊或其經(jīng)驗豐富的成員之間輪流承擔(dān)。)這種專注于保持構(gòu)建通過的做法使開發(fā)在頭部進行具有實用性,即使是規(guī)模非常大的團隊。


代碼所有權(quán)。存儲庫的每個分支都可以有一個列出分支“所有者”用戶ID的文件。子目錄還從父目錄繼承所有者,盡管可以有選擇地限制。每個分支的所有者控制寫訪問權(quán)限,如下面的代碼審查部分所述。每個分支都需要有至少兩個所有者,雖然通常需要有更多,特別是在地理分布較遠的團隊。通常將整個團隊列在所有者文件中。變更分支可以由Google公司的任何員工實施,不只是所有者,但必須由所有者批準(zhǔn)。這確保每個變更由理解軟件的工程師審核


有關(guān)Google源代碼存儲庫的更多信息,請參閱[17,18,21];以及另一個大公司如何處理同樣的挑戰(zhàn),見[19]。


2.2 構(gòu)建系統(tǒng)

Google使用一種稱為Blaze的分布式構(gòu)建系統(tǒng),負責(zé)構(gòu)建和鏈接軟件和運行測試。它提供了在整個存儲庫用于構(gòu)建和測試的標(biāo)準(zhǔn)命令。這些標(biāo)準(zhǔn)命令和高度優(yōu)化的實現(xiàn)意味著對于Google工程師構(gòu)建和測試存儲庫中的任何軟件變得相當(dāng)簡單和迅速。這種一致性是關(guān)鍵的推動者,這有助于工程師能夠跨項目邊界進行變更。


程序員編寫“BUILD”文件,Blaze用它來確定如何構(gòu)建他們的軟件。構(gòu)建實體(例如庫,程序和測試)使用相當(dāng)高級別的聲明性構(gòu)建規(guī)范,為每個實體指定其名稱,源文件和庫或其依賴的其他構(gòu)建實體。這些構(gòu)建規(guī)范包括稱為“構(gòu)建規(guī)則”的聲明,每個都指定高級概念,如“這是一個C++庫,這些源文件依賴這些其他庫文件”,這是由構(gòu)建系統(tǒng)將每個構(gòu)建規(guī)則映射到一組構(gòu)建步驟,例如編譯每個源文件的步驟和鏈接步驟,以及確定編譯器和編譯標(biāo)志。


在某些情況下,特別是Go程序,可以自動生成(和更新)構(gòu)建文件,因為BUILD文件中的依賴信息是(通常是)源文件中依賴信息的摘要。但是,他們?nèi)匀粫炄氲酱鎯熘?。這是確保構(gòu)建系統(tǒng)可以通過僅分析構(gòu)建文件來快速確定依賴而不是分析源文件,并且它避免了構(gòu)建系統(tǒng)與編譯器或分析工具之間的過度耦合,支持許多不同的編程語言。


構(gòu)建系統(tǒng)的實現(xiàn)使用Google的分布式計算基礎(chǔ)架構(gòu)。每個構(gòu)建工作通常分布在數(shù)百或甚至數(shù)千個機器上。這使得快速構(gòu)建大型程序或并行運行數(shù)千個測試成為可能。


各個構(gòu)建步驟必須是“密封的”:僅取決于他們所聲明的輸入。強調(diào)所有依賴正確聲明是分發(fā)構(gòu)建的結(jié)果:只有聲明的輸入被發(fā)送到構(gòu)建步驟的機器上運行。結(jié)果是構(gòu)建系統(tǒng)能可靠地知道真正的依賴。甚至是構(gòu)建系統(tǒng)調(diào)用的編譯器被視為輸入。


獨立構(gòu)建步驟是確定的。因此,構(gòu)建系統(tǒng)可以緩存構(gòu)建結(jié)果。軟件工程師可以將其工作區(qū)同步到舊的變更號,可以重建并獲得完全相同的二進制代碼。此外,可以在不同用戶之間安全地共享該緩存。 (為了使這項工作正常,我們必須在構(gòu)建調(diào)用的工具中消除非確定性,,例如通過清除輸出文件中的時間戳。)

    

構(gòu)建系統(tǒng)是可靠的。構(gòu)建系統(tǒng)跟蹤構(gòu)建規(guī)則自身的變更依賴性,并且如果產(chǎn)生它們的操作發(fā)生改變,則知道要重建目標(biāo),即使該操作沒有輸入,例如當(dāng)只有編譯器選項改變時。它也可以正確處理被中斷的構(gòu)建部分,或在構(gòu)建期間修改源文件:在這種情況下,只需要重新運行build命令。不需要運行相當(dāng)于“make clean”的命令。


構(gòu)建結(jié)果緩存在“云中”。這包括中間結(jié)果。如果另一個構(gòu)建請求需要相同的結(jié)果,構(gòu)建系統(tǒng)會自動重用它們而不是重建,即使請求來自不同的用戶。


增量重建速度快。構(gòu)建系統(tǒng)駐留在內(nèi)存中,以便為了重建,它可以遞增地分析上次構(gòu)建以來已變更的文件。


預(yù)提交檢查。 Google提供了在啟動時自動運行一系列測試的工具,當(dāng)啟動代碼審查和/或準(zhǔn)備向存儲庫提交變更時。每個存儲庫分支可以包含測試運行的配置文件,以及是否在代碼審查時或在提交之前立即運行它們。測試可以是同步的,即在發(fā)送變更以供審閱之前和/或在提交變更到存儲庫之前運行(有利于快速運行測試);或異步結(jié)果通過電子郵件發(fā)送給審查討論線程。 [審查線程是代碼審查之上的電子郵件線程;該線程中的所有信息也顯示在基于Web的代碼審查工具中。]


2.3 代碼審查

Google已經(jīng)建立了完善的基于網(wǎng)絡(luò)的代碼審查工具,與電子郵件集成,允許作者提出審查請求,并允許審閱者并排比較差異(同時有漂亮的顏色編碼)并進行評論。當(dāng)提出變更的作者啟動代碼審查時,通過電子郵件通知審核人,并提供指向該變更的評審工具所在頁面的鏈接。當(dāng)審核人提交審核評論時,會自動發(fā)送通知電子郵件。此外,自動化工具可以發(fā)送通知,包含例如自動測試或靜態(tài)分析工具發(fā)現(xiàn)的結(jié)果。


對主要源代碼存儲庫的所有變更至少需要由另一個工程師進行審核。此外,如果變更的作者不是文件的所有者,則至少需要一個所有者進行審核并批準(zhǔn)該變更。


在特殊情況下,在審查之前,分支所有者可以簽入(提交)緊急變更到該分支,但仍然必須指定審查者,并且變更作者和審查者將自動被定期提醒,直到變更被審核批準(zhǔn)。在這種情況下,任何回應(yīng)評審意見的修改必須提交另一個變更,因為最早的變更已經(jīng)提交。


Google有一些工具可以為特定變更建議審閱者,通過查閱要修改代碼的所有權(quán)和著作權(quán),最近審閱者的歷史記錄,以及每個潛在審閱者承擔(dān)的待審查代碼數(shù)量。至少一個受變更影響的分支的所有者必須審核并批準(zhǔn)該變更,但除此之外,作者可自由選擇他們認為合適的審閱者。


代碼審查的一個潛在問題是,如果審閱者的響應(yīng)太慢,或者是不太愿意批準(zhǔn)變更,這可能會阻礙開發(fā)的進展。事實是代碼作者選擇審閱者有助于避免這樣的問題,允許工程師避開可能對其代碼過度干涉的審閱者,或發(fā)送簡單變更給經(jīng)驗少的審閱者,復(fù)雜變更發(fā)送給有經(jīng)驗的審閱者或同時發(fā)給好幾個審閱者共同審閱。


每個項目的代碼審查的討論將自動復(fù)制到項目維護者的專屬郵件列表中。任何人都可以對任何變更發(fā)表評論,無論他們在變更前后是否被指定為該變更的審閱者。如果一個bug被發(fā)現(xiàn),它通常會跟蹤導(dǎo)致bug的變更并在初始的代碼審查線程中指出錯誤以便原來的作者和審閱者意識到該錯誤。


也可以向幾個審閱者發(fā)送代碼審查請求,然后在他們其中之一批準(zhǔn)后盡快提交變更(假設(shè)作者或第一個答復(fù)的審閱者是分支所有者),在其他審閱者還沒有評論之前。任何隨后的審查意見在后續(xù)變更中處理。這可以減少評審的周轉(zhuǎn)時間。


除了倉庫的主庫部分,還有一個“實驗”庫的正常代碼審查要求不是強制的。然而,在產(chǎn)品中運行的代碼必須放在倉庫的主庫中,工程師被強烈鼓勵在存儲庫的主庫中開發(fā)代碼,而不是在實驗庫中開發(fā)然后遷移到主庫,因為代碼審查最有效是在代碼開發(fā)階段而不是之后。實際上,工程師們經(jīng)常要求代碼評審即使是在實驗庫中寫代碼階段。


鼓勵工程師保持獨立的小變更,大變更最好分解成一組小的變更,審閱者可以一次輕松地查看。這也使作者更容易在評審期間對提出的主要變更作出響應(yīng);非常大變更的作者往往太死板,并且抗拒審閱者建議的變更。鼓勵保持小變更的一種方法是代碼審查工具將變更規(guī)模描述在每個代碼審查中,30-99行的添加/刪除/移除被標(biāo)記為“中”變更,大于300行的變更被標(biāo)記為受蔑視的標(biāo)簽,如“Large大”(300-999),“freakin hug出奇大”(1000-1999),(但是,在通常的Google方式中,在每年的那幾天用一些搞笑的方式替換這些熟悉的描述,talk-like-a-pirate day。 :)

1.近年來這種情況發(fā)生了一些變化。更新版本的代碼審查工具不再使用更多的蔑視標(biāo)簽,但是仍然標(biāo)記變更的規(guī)模,例如, “S”,“M”,“L”,“XL”。


2.4 測試

我們強烈鼓勵并廣泛使用單元測試。產(chǎn)品中所使用的所有代碼期望都有單元測試,代碼審查工具將突出顯示沒有進行相應(yīng)測試的源代碼。代碼審查人通常要求任何變更添加新功能時,也應(yīng)添加相應(yīng)的測試。Mocking框架(允許構(gòu)建輕量級單元測試,甚至是依賴重量級庫文件的代碼)是相當(dāng)普遍的。


集成測試和回歸測試也被廣泛應(yīng)用。


如“預(yù)提交檢查”中所述,測試可以作為的一部分自動執(zhí)行的代碼審查和提交過程。


Google還提供用于測量測試覆蓋率的自動化工具。結(jié)果也被整合到源代碼瀏覽器中,作為一個可選層次。


在部署之前進行壓力測試也是Google的重點。團隊希望產(chǎn)生表格或圖形來顯示關(guān)鍵指標(biāo)(特別是延遲和錯誤率)如何隨傳入請求的變化而變化。


2.5 缺陷追蹤

Google使用一個名為Buganizer的錯誤跟蹤系統(tǒng)來跟蹤問題:缺陷,功能請求,客戶問題和過程任務(wù)(如版本發(fā)布或清理工作)。缺陷被分配到有層次的組件上,并且每個組件可以具體到可以抄送的默認責(zé)任人和默認的電子郵件列表。當(dāng)發(fā)送源代碼變更以供審核時,系統(tǒng)會提示工程師將該變更與特定版本發(fā)行號相關(guān)聯(lián)。


Google的團隊通常(但不是通用的)定期掃描期組件中的未解決問題,確定優(yōu)先級,并在適當(dāng)時候分配給特定的工程師。一些團隊有專人負責(zé)缺陷分類,其他團隊采取在小組常規(guī)會議上進行缺陷分類的方法。 Google的許多團隊都使用缺陷標(biāo)簽表示缺陷是否已被分類,以及哪個版本將修復(fù)缺陷。


2.6 編程語言

Google強烈鼓勵軟件工程師選用4個官方批準(zhǔn)的編程語言之一:C ++,Java,Python或Go。減少編程語言的數(shù)量降低了代碼重用和程序員間的協(xié)作障礙。


針對每種語言的Google風(fēng)格指南,確保遍布公司各處的代碼有相似的風(fēng)格,布局,命名約定等。另外還有一個公司范圍內(nèi)的代碼可讀性培訓(xùn)流程,由經(jīng)驗豐富的工程師來培訓(xùn)其他工程師編寫可讀性好,特定語言的常用代碼,通過重大變更審查或系列變更審查,直到審閱者認為工程師知道如何用該語言編寫出可讀性好的代碼。一門特定語言上每個重大新代碼的變更必須由已經(jīng)通過“可讀性”訓(xùn)練過程的人審批。


除了這四種語言之外,還使用了許多專用領(lǐng)域特定語言(DSL)用于特定目的(例如用于指定構(gòu)建目標(biāo)及其依賴性的構(gòu)建語言)。


這些不同的編程語言之間的交互操作主要使用Protocol Buffer。ProtocolBuffer是一種以高效而可擴展的方式編碼的結(jié)構(gòu)化數(shù)據(jù)的方法。它包括用于指定結(jié)構(gòu)化數(shù)據(jù)的特定領(lǐng)域語言,帶有相應(yīng)描述的編譯器并在C ++,Java,Python中生成代碼,構(gòu)建,訪問,序列化和反序列化這些對象。 Google的ProtocolBuffer版本與谷歌的RPC庫集成,可使用簡單的跨語言RPC,具有請求和響應(yīng)的序列化和反序列化,由RPC框架自動處理。


流程通用性是使開發(fā)變得容易的關(guān)鍵,即使使用巨大的代碼庫和多種語言:有一組單一命令執(zhí)行所有通用的軟件工程任務(wù)(如簽出,編輯,構(gòu)建,測試,審查,提交,文件錯誤報告等等),并且無論什么項目或語言都可以使用相同的命令。開發(fā)人員不需要學(xué)習(xí)一個新的開發(fā)過程,只是因為他們正在編輯的代碼恰好是另一個項目的一部分或者是用不同的語言編寫的相同功能。


2.7 調(diào)試和分析工具

Google服務(wù)器與庫相關(guān)聯(lián),這些庫提供了許多用于調(diào)試運行的工具。在服務(wù)器崩潰的情況下,信號處理程序?qū)⒆詣訉⒍褩8欈D(zhuǎn)儲到日志文件,而且保存核心文件。如果崩潰是由于內(nèi)存泄漏,服務(wù)器將轉(zhuǎn)儲活動堆對象的采樣子集的分配站點的堆棧跟蹤。還有用于調(diào)試的Web界面,允許檢查傳入和傳出的RPC(包括定時,錯誤率,速率限制等),改變命令行標(biāo)志值(例如增加特定模塊的日志級別),資源消耗,概要分析等。這些工具大大增加了調(diào)試的整體便利性,傳統(tǒng)的調(diào)試器難以實現(xiàn)該目的,如gdb。


2.8 發(fā)布工程

只有一部分團隊有專門的發(fā)布工程師,但對于Google的大多數(shù)團隊來說,發(fā)布工程工作由常規(guī)軟件工程師完成。


大多數(shù)軟件經(jīng)常發(fā)布;每周或每兩周發(fā)布一次是常見的,有些團隊甚至每天發(fā)布。這是通過自動化大部分正常的發(fā)布工程任務(wù)實現(xiàn)的。經(jīng)常發(fā)布有助于保持工程師的積極性(如果許多個月甚至幾年后才發(fā)布,很難被認為是激動人心的事),通過允許更多的迭代從而增加整體速度,因而在給定的時間越多的反饋帶來越多響應(yīng)反饋的機會。


發(fā)布通常在新的工作區(qū)中開始,通過同步到最新的“綠色”構(gòu)建的變更號(即,所有自動測試通過的最后一個變更),并產(chǎn)生一個發(fā)布分支。發(fā)布工程師可以選擇“最優(yōu)選擇”的額外變更,即從主分支合并到發(fā)布分支上。然后從草稿重建軟件并執(zhí)行測試。如果有任何失敗的測試,則進行變更以修復(fù)缺陷并且讓那些額外的變更在發(fā)布分支上達到最優(yōu),之后再次進行軟件重建和測試重運行。當(dāng)測試全部通過,構(gòu)建的可執(zhí)行文件和數(shù)據(jù)文件被打包。所有這些步驟都是自動的,以便發(fā)布工程師只需運行一些簡單的命令,甚至只需在菜單驅(qū)動的UI上選擇一些條目并選擇那些最優(yōu)變更(如果有)。


一旦候選構(gòu)建被打包,它通常被加載到“預(yù)演staging”服務(wù)器上做進一步通過少量用戶的集成測試(有時只是開發(fā)團隊)。


一種發(fā)送來自生產(chǎn)流量的請求副本(或子集)到預(yù)演服務(wù)器的有用技術(shù),但也將這些相同的請求發(fā)送到當(dāng)前生產(chǎn)服務(wù)器用于實際處理。來自預(yù)演服務(wù)器的響應(yīng)被丟棄,并且從實際生產(chǎn)服務(wù)器的響應(yīng)發(fā)回給用戶。這有助于確保任何可能會導(dǎo)致嚴(yán)重的問題(例如服務(wù)器崩潰)在服務(wù)器投入生產(chǎn)之前可以被檢測到。


下一步通常是推出一個或多個“公測canary”服務(wù)器來處理一小部分實時生產(chǎn)流量。與“預(yù)演”服務(wù)器不同,這些是處理和響應(yīng)是真實的用戶。


最后,該版本可以推廣到所有數(shù)據(jù)中心中的所有服務(wù)器。對于超高流量,高可靠性的服務(wù),這種逐步推出在幾天的時間內(nèi)完成,有助于減少任何運行中斷的影響,因為新引入的缺陷沒有被前面的步驟捕獲。


有關(guān)Google發(fā)布工程的更多信息,請參見SRE手冊[7]的第8章。也可以參見[15]。


2.9 上線批準(zhǔn)

 任何用戶可見的變更或重大設(shè)計變更的上線都需要來自實施變更的核心工程團隊之外的審批。某些特定批準(zhǔn)(通常需經(jīng)過詳細審核),需要確保代碼合規(guī),符合法律,隱私,安全以及可靠性方面的要求(例如具有適當(dāng)?shù)淖詣颖O(jiān)控以檢測服務(wù)器中斷并自動通知相關(guān)的工程師),以及業(yè)務(wù)需求等。


上線過程還旨在確保公司內(nèi)的適當(dāng)人員在任何重要的新產(chǎn)品或功能投放時能被通知到。


Google有一個內(nèi)部上線批準(zhǔn)工具,用于跟蹤所要求的評審,批準(zhǔn)并確保符合為每個產(chǎn)品定義的上線過程。這個工具很容易客戶化,所以不同的產(chǎn)品或產(chǎn)品領(lǐng)域可以有不同的審查和批準(zhǔn)。


有關(guān)上線過程的更多信息,請參見SRE手冊[7]的第27章。


2.10 事后分析

每當(dāng)我們的任何生產(chǎn)系統(tǒng)發(fā)生嚴(yán)重停機或類似事故時,涉及的人員需要寫一份事后分析報告。這份文檔描述了事件經(jīng)過,包括標(biāo)題,摘要,影響,時間表,根本原因,什么有效/什么無效,以及行動計劃。重點是問題,如何在未來避免,而不是責(zé)任人或分?jǐn)傌?zé)任。影響部分試圖量化事件的影響,術(shù)語上報告中斷持續(xù)時間,丟失的查詢數(shù)(或失敗的RPC等),以及收益。時間表部分給出了事件中斷、分析及修正步驟的時間表。什么有效/什么無效部分描述了經(jīng)驗教訓(xùn) - 

這些做法有助于快速發(fā)現(xiàn)和解決問題,出了什么問題,采取了什么具體行動(最好記錄下解決缺陷的特定責(zé)任人)以減少未來類似問題發(fā)生的可能性和/或嚴(yán)重性。


有關(guān)Google事后分析文化的更多信息,請參閱SRE手冊[7]的第15章。


2.11 頻繁重寫

Google的大多數(shù)軟件每隔幾年就會重寫一次。


這看起來成本非常高。事實上,這消耗了谷歌的很大一部分

資源。然而,這也有一些決定性的好處,這是谷歌敏捷性和長期成功的關(guān)鍵。在幾年的時間里,對一個產(chǎn)品變更有顯著需求是典型的現(xiàn)象,隨著軟件環(huán)境等周圍的技術(shù)發(fā)生變化以及技術(shù)或市場的變化影響到用戶的需求和期望。幾年前的軟件是圍繞一套老的要求設(shè)計的,通常不是以當(dāng)前要求的最佳方式設(shè)計的。此外,它通常積累了很多的復(fù)雜性。重寫代碼能消除所有不必要累積的,不再那么重要的復(fù)雜性。此外,重寫代碼是一種將知識和所有權(quán)感覺傳遞給后來的團隊成員的方式。這種所有權(quán)意識對于生產(chǎn)力至關(guān)重要:工程師自然會更努力開發(fā)軟件特性并修復(fù)他們認為是“自己的”的代碼中的問題。頻繁重寫也鼓勵工程師在不同項目之間的移動,這也有助于鼓勵思想的交叉碰撞。頻繁重寫也有助于確保完成的代碼使用了更先進的技術(shù)和方法。


3. 項目管理

3.1 20%時間

工程師被允許花費高達20%的工作時間在他們選擇的任何項目上,無需他們的經(jīng)理或任何人的批準(zhǔn)。針對幾個原因,這種對工程師的信任是非常有價值的。首先,它允許任何有好主意的人,即使這只是一個其他人不會立即認同的想法,有足夠的時間開發(fā)原型,演示或介紹來展示他們的想法的價值。其次,它向管理層提供可能被隱藏活動的可見性。在其他公司沒有官方政策允許20%的時間,工程師有時候會工作在“臭鼬(注:指秘密項目,上世紀(jì)洛克希德.馬丁公司生產(chǎn)U-2、F117等飛機的秘密項目)”項目上而不會提示管理層。更好方式是,如果工程師可以公開這些項目,定期更新他們在這些項目上的狀態(tài),即使其管理層可能不同意項目價值。擁有一個公司范圍內(nèi)的官方政策和支持文化使這成為可能。第三,允許工程師花費一小部分時間在更有趣的事情上工作可以保持工程師的動力和激情,防止他們因感覺被迫花費100%的時間在更多乏味的工作任務(wù)上而心力交瘁,這是很容易發(fā)生的。受到激勵的工程師的生產(chǎn)力能夠提高20%以上。第四,它鼓勵創(chuàng)新文化??吹狡渌こ處煿ぷ髟?0%的有趣的試驗性項目上會鼓勵大家做相同的事。


3.2 OKRs

Google的個人和團隊需要明確記錄他們的目標(biāo)并評估在實現(xiàn)這些目標(biāo)所取得的進展。團隊設(shè)置季度和年度目標(biāo),帶有可衡量的關(guān)鍵結(jié)果,顯示在實現(xiàn)這些目標(biāo)方面取得的進展。這是每個公司水平要做的事,自底向上直到為整個公司定義目標(biāo)。個人和小團隊的目標(biāo)應(yīng)該與更大的團隊的更高級目標(biāo)保持一致,他們是公司總體目標(biāo)的一部分。在每個季度結(jié)束時,可度量關(guān)鍵結(jié)果的進展情況被記錄,并且每個目標(biāo)被賦予從0.0(無進展)至1.0(100%完成)的分?jǐn)?shù)。 OKRs標(biāo)準(zhǔn) 和OKR分?jǐn)?shù)通常在Google內(nèi)部是公開的(偶爾會出現(xiàn)例外情況,例如高度敏感的機密項目),但它們不直接作為個人績效評價的輸入。


 OKRs應(yīng)該設(shè)置為高:期望的目標(biāo)總平均分是65%,意味著一個團隊鼓勵將目標(biāo)設(shè)置為比他們實際完成的任務(wù)多50%的任務(wù)。如果一個團隊得分明顯高于這個數(shù)值,鼓勵他們在下一個季度設(shè)置更有野心的OKR(反之,如果他們的得分明顯低于標(biāo)準(zhǔn),他們被鼓勵在下一季度更加保守地設(shè)置OKR)。


OKRs提供了一個重要機制,用于溝通公司的每個工作部分,并鼓勵員工通過社會激勵獲得好的績效。工程師知道他們的團隊將有一個關(guān)于OKRs打分的會議,并自然而然試著獲得好分?jǐn)?shù),盡管OKR對績效考核沒有直接影響,但仍然努力取得好成績。定義客觀和可衡量的關(guān)鍵結(jié)果有助于將員工引導(dǎo)到做真正具體可衡量的事情上來,對實現(xiàn)共同目標(biāo)的進展產(chǎn)生正面影響。


3.3 項目審批

雖然有一個明確的啟動批準(zhǔn)的過程,但Google沒有一個明確的項目審批或取消過程。盡管已經(jīng)在谷歌呆了近10年,現(xiàn)在已經(jīng)成為一個自我管理者,我還是不完全明白是怎樣做出這樣決定的。某種程度上,這是因為這不是一種貫穿整個公司的統(tǒng)一方法。每個級別的管理者都對他們團隊的項目負責(zé),并行使自己的決策權(quán)。在某些情況下,這意味著這樣的決定是以完全自下而上的方式做出的,工程師可以自由地

在他們的團隊范圍內(nèi)選擇工作項目。在其他情況下,類似的決定更多是以自上而下的方式進行,由高管或經(jīng)理決定哪些項目將繼續(xù),這將獲得額外的資源,或者將取消。


3.4 組織重組

偶爾,管理層決定取消一個大項目,然后許多曾經(jīng)在該項目上工作的工程師可能不得不在新的團隊中尋找新的項目。同樣,偶爾會出現(xiàn)“碎片整理”工作的情況,跨越多個地理位置的項目被整合,有些地方的工程師被要求換一個團隊和/或項目,以實現(xiàn)整合的目的。在這種情況下,工程師通??梢栽谒麄兊牡乩砦恢蒙献杂蛇x擇新團隊和角色,或在碎片整理的情況下,他們也可以選擇留在同一個團隊和項目,移動到不同的位置。


此外,其他類型的團隊重組,如合并或拆分團隊以及報告關(guān)系的變更,似乎是相當(dāng)頻繁地發(fā)生,雖然我不知道如何在這方面把Google與其他大公司進行比較。在一個大的,技術(shù)驅(qū)動的組織,有時頻繁的重組可能是必要的,以避免組織在技術(shù)和需求發(fā)生變化時出現(xiàn)低效率。


4. 人員管理

4.1 角色

我們將在下面更詳細地解釋,Google將工程和管理分開成不同的職業(yè)發(fā)展階梯,將技術(shù)領(lǐng)導(dǎo)角色與管理層分開,將工程嵌入到研究中,并支持產(chǎn)品經(jīng)理,項目經(jīng)理和現(xiàn)場保障工程師角色(SREs)。似乎至少有一些做法很重要,支持了Google開發(fā)的創(chuàng)新文化。


Google在工程中有少量不同的角色。在每個角色中,有一個職業(yè)發(fā)展可能,有一系列的層次和晉升的可能性(關(guān)系到報酬增長,例如。工資)來識別下一個績效水平。


主要角色有:


●工程經(jīng)理


這是此列表中唯一的人員管理角色。其他角色,例如軟件工程師可以管理人,但是工程經(jīng)理總是管理人。工程經(jīng)理通常是前軟件工程師,并且總是有相當(dāng)?shù)募夹g(shù)專長,以及人員管理的技能。


存在技術(shù)管理和人員管理之間的區(qū)別。工程經(jīng)理不一定領(lǐng)導(dǎo)項目;項目由技術(shù)主管領(lǐng)導(dǎo),他可以是工程經(jīng)理,但他更可能是軟件工程師。一個項目的技術(shù)主管對該項目的技術(shù)決策有最終決定權(quán)。


經(jīng)理負責(zé)選擇技術(shù)主管和并評估他們團隊的績效。他們執(zhí)行指導(dǎo)并協(xié)助員工的職業(yè)發(fā)展,進行績效評估(使用同行反饋的輸入,見下文),并負責(zé)一些薪酬方面的工作。他們也負責(zé)招聘的一些部分。


工程經(jīng)理通常直接管理3到30人,8到12人是最常見的。


●軟件工程師(SWE)


大多數(shù)做軟件開發(fā)工作的人都有這個角色。Google的軟件工程師招聘條件非常高;通常只聘用異常優(yōu)秀的軟件工程師,這能避免或減小困擾其他組織的很多軟件問題。


Google有獨立的工程和管理職業(yè)發(fā)展序列。雖然軟件工程師可以管理人員,也可以轉(zhuǎn)任工程經(jīng)理,但管理人員不是晉升所必需的,甚至在最高級別也是如此。在更高的層次,顯示領(lǐng)導(dǎo)力是需要,但可以有多種形式。例如創(chuàng)造有很大的影響力的偉大軟件或者被很多其他工程師使用就夠了。這是重要的,因為它意味著有強悍的技術(shù)技能但缺乏人員管理技能仍然有一個很好的職業(yè)發(fā)展道路,沒有要求他們一定有管理經(jīng)驗。這避免了一些組織遭受的問題,人員由于職業(yè)發(fā)展原因結(jié)束在管理職位上,但忽視了團隊中人的管理。


●研究科學(xué)家


這個角色的聘用標(biāo)準(zhǔn)非常嚴(yán)格,并且招聘條件也是非常高的,要求表現(xiàn)出杰出的研究能力,需要有大量的出版記錄的證明 *并且* 有能力編寫代碼。在學(xué)術(shù)界許多非常有才華的人勝任軟件工程師角色但并不符合谷歌的研究科學(xué)家角色;大多數(shù)在谷歌有博士頭銜的人是軟件工程師,而不是研究科學(xué)家。研究科學(xué)家在他們的研究貢獻上被評價,包括他們的出版物,但除此之外和不同的頭銜,軟件工程師和研究科學(xué)家的角色之間沒有太大的不同。兩者都可以做原創(chuàng)研究和發(fā)表論文,都可以開發(fā)新的產(chǎn)品思路和新技術(shù),也能夠?qū)懘a和開發(fā)產(chǎn)品。 Google的研究科學(xué)家通常與軟件工程師一起工作,在相同的團隊和工作在相同的產(chǎn)品或相同的研究上。這種將工程嵌入到研究工作中的做法極大地方便了新的研究成果落地形成產(chǎn)品。


●現(xiàn)場保障工程師(SRE)


 操作系統(tǒng)的維護由軟件工程團隊完成,而不是傳統(tǒng)的系統(tǒng)管理類型,但SRE軟件工程師的招聘要求的技能略低于軟件工程師的要求。 SRE角色的性質(zhì)和目的在下文中進行了詳細的解釋,SRE書[7],所以我們不在這里進一步討論。


●產(chǎn)品經(jīng)理


產(chǎn)品經(jīng)理負責(zé)管理產(chǎn)品;作為產(chǎn)品用戶的支持者,他們協(xié)調(diào)軟件工程師的工作,將重要的產(chǎn)品特性傳導(dǎo)給用戶,與其他團隊協(xié)調(diào),跟蹤錯誤和計劃,并確保所需的一切資源按時到位,以產(chǎn)生高品質(zhì)的產(chǎn)品。產(chǎn)品經(jīng)理通常不會自己編寫代碼,而是與軟件工程師一起工作,確保代碼的正確。


●項目經(jīng)理/技術(shù)項目經(jīng)理


項目經(jīng)理的角色與產(chǎn)品經(jīng)理大致相同,但是相比管理產(chǎn)品,他們管理項目,過程或運維(例如數(shù)據(jù)采集)。技術(shù)項目經(jīng)理工作類似,但也需要與工作相關(guān)的特定的技術(shù)專門知識。例如處理語音數(shù)據(jù)的語言學(xué)。


整個組織中的軟件工程師與產(chǎn)品經(jīng)理和項目經(jīng)理的比例不盡相同,但通常較高,例如,在4:1至30:1的范圍內(nèi)。


4.2 辦公條件

Google有名是因為它有趣的娛樂設(shè)施,如像滑梯,球池和游戲室等。這有助于吸引和留住優(yōu)秀的人才。 Google的咖啡館,對員工免費,這也巧妙鼓勵了Google員工留在辦公室;饑餓絕不是離開的理由。 “微型廚房”的頻繁安置,員工可以隨時取用小吃和飲料,也可以作為一個重要的非正式想法交流的地方,因為許多溝通就是從那里開始的。健身房,運動和現(xiàn)場按摩幫助保持員工健康,快樂,提高生產(chǎn)力并留住人才。


Google的座位是開放式的,通常相當(dāng)密集。雖然有爭議[20],但這鼓勵了溝通,有時犧牲個人的注意力集中,但也很經(jīng)濟。


員工分配到一個單獨的座位,但座位相當(dāng)頻繁地重新分配(每隔6-12個月,通常是由于組織擴大),通過管理者推動和鼓勵溝通,員工可以選擇座位,這些座位總是比較容易彼此相鄰或接近相鄰的其他人。


Google的辦公設(shè)施都配備有最先進的視頻會議設(shè)施的會議室,其中連接到另一方預(yù)先安排的日程邀請只需單擊一下屏幕。


4.3 培訓(xùn)

Google鼓勵員工在許多方面受到教育:

●新的Google員工(“Noogler”)有一個強制性的初始培訓(xùn)課程。

●技術(shù)人員(SWE和研究科學(xué)家)從“Codelabs”開始:在線短期個人技術(shù)培訓(xùn)課程,編碼練習(xí)。

●Google為員工提供各種在線和面對面培訓(xùn)課程。

●Google還支持在外部機構(gòu)學(xué)習(xí)。


此外,每個Noogler通常有官方任命的“導(dǎo)師”和一個單獨的“伙伴”幫助他們加快成長速度。非正式指導(dǎo)也通過與經(jīng)理的定期會議,團隊會議,代碼審查,設(shè)計審查和非正式過程而進行。



4.4 換崗

鼓勵公司不同部門之間的換崗,有助于跨組織的知識和技術(shù)的傳播,改善跨組織的溝通。允許員工在12個月后,可以項目和/或辦公室之間進行交流。軟件工程師也鼓勵做組織其他部分的臨時任務(wù),例如一個六個月的SRE(現(xiàn)場保障工程師)“輪換”(臨時的分配)。


4.5 績效考核和獎勵

Google積極鼓勵反饋。工程師可以給對方明確積極的反饋,通過“同行獎金”和“kudos”。任何員工可以提名任何其他員工的“同行獎金” - 每年100美元的現(xiàn)金獎金,每年最多兩次的超出正常工作職責(zé)的協(xié)作,只需填寫一個Web表單來描述原因。隊友也是發(fā)放同行獎勵才通知。員工也可以給予“kudos”,正式的贊揚聲明,為良好工作提供明確的社會認可,但沒有財務(wù)上的獎勵;對于“kudos”,沒有要求工作要超出正常的工作職責(zé),也不限制授予的次數(shù)。


經(jīng)理還可以獎勵獎金,包括現(xiàn)金獎金,例如,項目完成后發(fā)獎金。與許多公司一樣,Google員工基于績效獲得年度績效獎金和股權(quán)獎。


Google有一個非常仔細和詳細的晉升過程,由自己或經(jīng)理提名經(jīng)理,自我審查,同行評審,經(jīng)理評價;然后由晉升委員會做出實際決定,結(jié)果可以由晉升上訴委員會進一步審查。確保正確的人得到晉升至關(guān)重要,保持對員工的正確激勵。


另一方面,較差的績效由管理者反饋處理,如果需要的話,提出績效改進計劃,其中涉及設(shè)置非常明確的具體績效目標(biāo)并評估這些目標(biāo)的進展情況。如果失敗,終止不良績效是可以的,但在實踐中這是非常罕見的。


經(jīng)理績效通過反饋調(diào)查進行評估;每個員工都被要求填寫,每年兩次對他們的經(jīng)理的業(yè)績進行調(diào)查,結(jié)果被匿名化并匯總,然后提供給經(jīng)理。這種向上反饋對于保持和提高整個組織的管理質(zhì)量非常重要。


5. 結(jié)論


 我們簡要介紹了Google使用的大多數(shù)關(guān)鍵軟件工程實踐。當(dāng)然Google現(xiàn)在也是一個龐大和多樣化的組織,并且組織的一些部分有不同的做法。但是這里描述的做法通常被大多數(shù)谷歌團隊遵循。


有這么多不同的軟件工程實踐被涉及到,有很多其他Google成功的原因與我們的軟件工程實踐無關(guān),非常難以給出任何量化或客觀的證據(jù)。然而,這些做法經(jīng)受了時間的考驗,是數(shù)以千計的優(yōu)秀谷歌軟件工程師的集體主觀判斷。


對于那些主張使用特定實踐,這篇文章中描述到的其他組織,也許會說“這對谷歌足夠好了”。


長按二維碼發(fā)現(xiàn)驚喜

L

O

V

E

致謝

特別感謝Alan Donovan非常詳細和建設(shè)性的反饋,感謝Y aroslav Volovich,UrsH?lzle,Brian Strope,Alexander Gutkin,Alex Gruenstein和Hameed Husaini對本文的早期草稿提出了非常有益的意見。


作者簡介

 Fergus Henderson在Google做軟件工程師已經(jīng)超過10年以上。當(dāng)他在1979年還是一個孩子時就開始了編程,并一直在編程語言設(shè)計與實現(xiàn)方面做學(xué)術(shù)研究。與他的博士生導(dǎo)師在墨爾本大學(xué)共同創(chuàng)立了一個研究小組,開發(fā)了名為水星的編程語言。他是8個國際會議的方案委員會成員,并發(fā)布了超過50萬行的開源代碼。他還是Usenet新聞組comp.std.c ++的前主席并且是ISO C和C ++委員會官方認可的“技術(shù)專家”。他有超過15年的商業(yè)軟件行業(yè)經(jīng)驗。在Google,他是Blaze的初始開發(fā)人員之一,這是一個構(gòu)建(編譯連接)工具,現(xiàn)在在Google內(nèi)部使用,并工作在服務(wù)器端,用于語音識別、語音動作(早于Siri?。┮约罢Z音合成。他目前管理著Google的文字轉(zhuǎn)語音工程團隊,但仍然編寫與評審很多的代碼。他編寫的軟件安裝在十億多個設(shè)備上,并每天被調(diào)用十億次以上。

張勇譯,吳穹審

引用

[2] Build in the Cloud: How the Build System works , Christian Kemper,

[1] Build in the Cloud: Accessing Source Code , Nathan York,

[3] Build in the Cloud: Distributing Build Steps, Nathan York

[4] Build in the Cloud: Distributing Build Outputs, Milos Besta, Yevgeniy Miretskiy and Jeff Cox

[5] Testing at the speed and scale of Google , Pooja Gupta, Mark Ivey, and John Penix, Google engineering tools blog, June 2011.

[6] Building Software at Google Scale Tech Talk, Michael Barnathan, Greg Estren, Pepper Lebeck-Jone,  Google tech talk,

[7] Site Reliability Engineering , Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy, O'Reilly Media, April 2016, ISBN 978-1-4919-2909-4.

[8] How Google Works,  Eric Schmidt, Jonathan Rosenberg. 

[9] What would Google Do?: Reverse-Engineering the Fastest Growing Company in the History of the World , Jeff Jarvis, Harper Business, 2011.

[10] The Search: How Google and Its Rivals Rewrote the Rules of Business and Transformed Our Culture , John Battelle, 8 September 2005.

[11] The Google Story , David A. Vise, Pan Books, 2008. 

[12] Searching for Build Debt: Experiences Managing Technical Debt at Google,  J. David Morgenthaler, Misha Gridnev, Raluca Sauciuc, and Sanjay Bhansali.

[13] Development at the speed and scale of Google , A. Kumar, December 2010, presentation, QCon.

[14] How Google Tests Software , J. A. Whittaker, J. Arbon, and J. Carollo, Addison-Wesley,2012.

[15] Release Engineering Practices and Pitfalls , H. K. Wright and D. E. Perry, in Proceedings of the 34th International Conference on Software Engineering (ICSE ’12) , IEEE, 2012, pp. 1281–1284. 

[16] Large-Scale Automated Refactoring Using ClangMR , H. K. Wright, D. Jasper, M. Klimek, C.Carruth, Z. Wan, in Proceedings of the 29th International Conference on Software Maintenance(ICSM ’13) , IEEE, 2013, pp. 548–551.

[17] Why Google Stores Billions of Lines of Code in a Single Repository , Rachel Potvin, presentation. 

[18] The Motivation for a Monolithic Codebase , Rachel Potvin, Josh Levenberg, to be published in Communications of the ACM, July 2016.

[19] Scaling Mercurial at Facebook, Durham Goode, Siddharth P. Agarwa, Facebook blog post, January 7th, 2014.

[20] Why We (Still) Believe In Private Offices , David Fullerton, Stack Overflow blog post, January 16th, 2015.

[21] Continuous Integration at Google Scale , John Micco, presentation, EclipseCon, 2013.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多