他山之石,能夠攻玉。html
話說本人從畢業到如今一直在某 B 公司工做,前些年折騰過很多開發方式和工具,但總以爲或許有更好的方案,因此很好奇其它公司內部是如何工做的,我曾經瀏覽過某 Y 公司內部無所不包的 TWiki,也拜訪過某 F 總部瞭解他們的開發流程,但對某 G 公司卻瞭解很少,只零零碎碎知道一些,這兩天抽空梳理了以前收集到的各類資料,但願能給 FEX 後續改進提供參考。前端
注意:如下內容主要信息來自網上收集、『In The Plex』這本書及閒聊,純粹爲了技術交流和討論,僅表明我的觀點,本人從未在某 G 工做過,不受 NDA 限制,但大部分信息沒法確認真僞,加上某 G 很大,每一個部門都有可能不同,因此這裏的信息也是比較片面的,歡迎你們提供更多參考信息。java
分工協做
首先,某 G 大部分產品線都不區分前端工程師和後端工程師,一我的須要用從前到後都負責開發,儘管這幾年彷佛有變化,能看到專門的Front End 職位了,但應該是不多數產品線的作法。node
N 年前有人去 G 面試過,和他閒聊後瞭解到某 G 要求應聘者必須至少要會 C++ 和 Java 中的一種,只會 Python/PHP 是不夠的,要是隻懂 JS 就更不行了。這個信息很關鍵,能用來解釋一些內部現象,後面我會提到。mysql
我我的認爲前端工程師確實應該瞭解基本的後端知識,某 B 公司之前不少前端工程師都只負責模板(好比 Smarty)開發,這致使一個很嚴重的問題,那就是前端工程師每每不知道如何搭建環境,開發時須要依賴後端工程師提供環境和數據,嚴重影響了開發效率,這也是爲何 FIS 還內嵌了本地服務功能。git
另外國內有公司還對前端工程師作進一步細分,按照職能分爲寫 HTML/CSS 和 JS 的,對於我所屬的團隊,我我的並不贊同這種作法,由於 HTML 和 JS 是密切相關的,這樣分工將不利於代碼管理與優化,尤爲是交互複雜的頁面,由於 JS 很依賴 HTML,拆分反而增長溝通成本,但或許在重運營的網站這麼作會更好。web
代碼管理方法
如下是一些零碎瞭解到的幾點:面試
- 內部全部人都能看到代碼
- 聽說在 09 年時某國家的 office 有例外(來自『In The Plex』第 6 章,內容比較不和諧,這裏就不展開了)
- 提交代碼須要相關人員的 review
- 這使得某 G 內部工程師能夠很方便地切換項目,不多一我的只負責一個項目
- 代碼只有最新版(trunk),沒有 release 版本,沒有版本號
- 通常你們喜歡新增接口
- 若是要修改原有的接口,就必須通知全部使用方,不過由於全部人都能看到全部代碼,因此很容易找到有誰使用
- 據瞭解某 F 也是這樣的
- 有個代碼的搜索引擎
- 估計和下線的 Code Search 比較像(好像仍是某高管寫的,不過我忘記在哪看到的了)
- 若是想使用某個基礎庫,最好的方法是搜索使用到這個庫的相關代碼,抄過來
- 我認爲這種方式比讓工程師寫文檔靠譜多了,由於絕大部分調用這個庫的代碼都是類似的,因此直接給出例子能讓別人更容易上手
- 代碼依賴是經過全局的方式統一管理的
- 不多使用第三方庫
- 只能選用內部維護的版本,好比相似這個 MySQL
- 會將第三方庫的編譯工具改爲內部的,好比 Chromium 中都改爲 GYP 方便管理
- 聽說想申請用某個新第三方庫須要審覈,週期比較長
- 代碼管理軟件用的 Perforce
- 某 G 直接將這個公司買下了(未確認,但下面那篇論文是在某 G 網站上的,因此我感受消息可靠),Perforce 的員工爲某 G 內部定製了一套代碼管理工具
- 另外我找到一篇 Perforce 的性能優化的論文,這裏面透露了不少 G 公司內部的代碼狀況(發表時間是 2011 年 5 月),如下信息取自這篇論文:
- 這個程序用了 17 年,有 2 千萬次 changelist(能夠理解就是 ci 數量)
- 最大的 client 有 6 百萬個文件(應該絕大部分是數據吧,要知道 chromium 項目也就不到 30 萬個文件)
- 文檔及相關數據文件也放上面
- Reivew 工具叫 Mondrian(確認就是 Rietveld 的前身)
總體來講某 G 的代碼管理方式有不少可取之處,尤爲是代碼開放,能最大程度地調動開發人員的主動性與協做意識,從而創造出更大的價值。不過沒有版本管理這點是個雙刃劍,我也沒想好是否這樣會更好。sql
feature flag
由於沒有分支,代碼只有一份,因此要實驗新功能就得經過 flag 來控制的,這個 flag 由線上 Borg 系統來管理,能作到針對某一部分的 Cookie 開啓不一樣的 feature,方便進行對比抽樣。typescript
若是某個功能最終不上線,後續須要手工刪除相關代碼。
這個 flag 開關功能在某 F 也有,我認爲這是大型網站是必備功能,但須要注意,這個系統自己會成爲關鍵節點,以前某 F 的相似系統掛過,直接致使整個網站大部分功能都關閉了,因此一旦出問題後果很嚴重。
嚴格的代碼檢查
聽說某 G 工程師大部分時間在寫單元測試,單元測試能夠保證 UI 無關代碼的質量,但對於頁面測試就很難了,雖然可使用 selenium,但某 G 內部你們都不肯意寫,我我的認爲這個問題確實無解,頁面隨便一改就致使大量測試失效,我還沒見任何一家公司解決(某 F 說他們用的是 Watir,但主要用於保證登陸等基本功能可用),目前看來惟一可行的就是自動頁面截圖 diff,某 G 在 Consumer Surveys 這個產品中也在嘗試。
聽說某 G 的項目大多沒有嚴格的上線時間點,因此不能以項目緊急爲藉口來不寫單元測試,這點和天朝不太同樣,你們更傾向犧牲質量來追求速度。
另外國外公司通常對瀏覽器兼容性問題都不怎麼關注,由於現代瀏覽器中的兼容性問題比之前好得多,這點某 G 和某 F 公司同樣,只支持高版本的 IE。
由於只有主幹,因此提交代碼很謹慎,須要通過 3 個主要階段:
- 代碼風格檢查
- 單元測試檢查
- 代碼 owner 的 Review
提交一旦出錯可能會致使影響其它人的工做(由於每一個人都依賴主幹啊),甚至遭到其它國家 office 工程師的指責,因此你們對於代碼提交都很是謹慎,再三確認,壓力不小。
在單元測試、代碼風格和 review 的執行上,某 G 作得很完全,這點值得學習,國內你們彷佛更喜歡開發效率而不是質量。
前端如何開發
除了 Gmail、Maps、Plus 這樣的特例,基本上都是由後端模板生成頁面,不多項目使用 JS 來寫界面,更少使用 MVC 框架,這點其實在不少公司都差很少,好比某 B 也是同樣的,除了地圖及廣告管家等產品,其它產品基本上都是經過模板生成的。
某 G 的頁面是一般是由 Java 或 C++ 語言所寫的模版引擎生成的,並且開源出來了,分別是 Closure Templates 和 CTemplate,話說某 B 在幾年前也本身寫了個 C++ 的模板引擎,但目前基本被淘汰了。
對某 G 來講,「前端」工程師要寫 Java 和 JavaScript,而「後端」服務主要是 C++(某些地方開始使用 Go 了,好比這個)。
前面說到招人時都要會 Java,這帶來的結果是大多數團隊成員更瞭解 Java 而不是 JavaScript,因而在這種背景下很天然地誕生了 GWT這個神奇的東西,它在內部不少地方使用,按照內部人士的說法,主要的考慮是:
- 能自動生成跨瀏覽器瀏覽器代碼
- 結構規範,經過編譯器就能提早發現不少問題
- 能使用強大的 IDE 來提升效率(重構、自動完成、方便跳轉到定義等)
對於專業作前端的同窗,看到 GWT 多半不喜歡,感受就是畫蛇添足,但若是是 Java 出身的工程師實際上是很容易接受的,尤爲是對於習慣了 Java 的代碼組織方式及強類型語言的人,反而會很不習慣 JavaScript 這種弱類型的語言,以爲太難控制太容易出錯了,好比拿到一個變量,在 Java 代碼中經過它的類型就能知道它的數據結構,但 JavaScript 就不行了,只能在運行時 console.dir
出來或找相關實現的代碼,從我我的體會來看,對於陌生代碼,JavaScript 版本的理解難度要明顯高於 Java 版本。
話說某 G 曾經弄過一個叫 Wave 的產品,後來產品失敗後就將代碼開源出來了,我認爲這個代碼能反應出 G 內部在使用 GWT 時的開發風格,我用 cloc 統計了一下它的代碼狀況,結果以下:
----------------------------------------------------------
Language files blank comment code
----------------------------------------------------------
Java 2329 50121 139226 245856
Python 34 1308 2537 4451
CSS 57 617 1670 2791
XML 148 1009 2627 2487
Ant 15 131 335 987
HTML 8 124 155 831
Bourne Shell 9 61 190 185
Javascript 1 12 26 56
神奇吧,這麼複雜的前端交互應用,只有 1 個 56 行的 JS 文件,並且其實這個 JS 仍是可有可無的,因此你能夠理解爲何某 G 只招懂 Java 或 C++ 的工程師了吧。
後來某 G 的 Lars Bak 大神推出了 Dart,在我看來就是用來取代 GWT 的,前面說到的 GWT 優勢在 Dart 都有,並且在 I/O 2012 有一個演講題目是 Migrating Code from GWT to Dart,赤裸裸啊。
另外其實某 G 內部也不是全部人都喜歡 GWT,好比 Plus 就沒使用,而是直接基於 Closure 開發,並使用 Closure template。
說到 Closure,就不得不提它的起源:Gmail,在 WebApps 2010 會議上,有篇 PPT 介紹了 Gmail 代碼的狀況,如下摘抄其中幾個信息:
- 2004 年就有 9400 行代碼了,還有個 JS 編譯器(Closure compiler 的前身)來壓縮代碼、檢查錯誤等
- 2005 年有 22000 行代碼,10000 行註釋
- 2006 年有 52000 行代碼,23000 行註釋,開始使用面向對象,並初步造成 Closure library
- 2007 年重寫,代碼達到 90000 行,註釋竟然有 97000 行(太厲害了。。。),開始出現模塊化機制,並且出現了 Closure Templates
- 隨後開始內部使用,並最終對外推出了 Closure 系列工具
- 演講人認爲
Type-checking is important and possible
- 有報道說在這個會議中演講人還透露 Gmail service 也是用 JS 寫的,代碼有 443000 行
- 對於這個消息,我不肯定是否真實,但確實是有可能,08 年時 Stevey Yegge 也說過某 G 的規範有漏洞,沒說 JS 只能用在前端,並且他還真這麼作過。
最後插一句個人觀點:對於我所處的團隊及用戶類產品來講,GWT 沒有意義,而 Dart 雖然比起 GWT 要好得多,但和 JS 交互實在太麻煩,致使它的使用場景頗有限,語法有明顯變化,使得難以讓大部分前端工程師接受(Lars Bak 就在 I/O 2013 上吐槽工程師太糾結語法,看起來大神在內部推廣時確定遇到很多阻力)。對於類型檢查的好處,我我的是比較贊同的,所以我更喜歡 TypeScript 這種加強形方案,由於它能夠逐步適應,既有類型支持的優點,又能直接使用現有代碼。
內部工做流程
如下是打聽到的某個產品項目開發流程:
- PM 或工程師提出某個想法,UX 作原型 mock
- PM 申請項目審覈(經過率不高)、工程師開發 UX 無關部分
- 工程師完成開發
- 線上小流量實驗
- PM/工程師分析實驗結果,完成報告,申請全量上線(經過率不高)
- 經過數據來證實這個功能是有價值的
- 須要解釋這些數據的變化緣由
- 分批逐步上線,這個過程當中還會有不少審覈
- 最終肯定是否要上線(經過率不高)
通常整個項目週期很長(至少一季度),項目最終上線時間點沒法肯定,大部分的項目最終都沒法正式上線。
最大的特色是徹底靠數聽說話,而不是由某個 PM 決定一切,之前有個視覺設計師在離開 G 後就在博客上吐槽這點,他認爲這會致使沒法進行大膽的界面改版。
這個流程和咱們搜索產品幾年前的開發流程很相似,對於成熟的搜索引擎來講這麼作確實有它的道理,畢竟隨便改個什麼都極可能影響收入,固然要十分謹慎了,但這種開發方式並不適合面向用戶類的產品,如社區、遊戲等,由於開發週期太長了,很容易錯過期機。
某人一天的工做
這裏拿 Matt Welsh 來舉例介紹一個工程師在某 G 一天的工做,雖然他不是作前端開發的,但他目前在 Chrome 團隊負責[移動 Web 性能優化]((http://matt-welsh.blogspot.com/2013/04/running-software-team-at-google.html),因此仍是比較相關,並且最重要的是他比較喜歡寫博客,有意無心地透露了不少信息,因此我比較好公開談。
另外話說他以前仍是哈佛的計算機終身教授(!!!),八卦不少,好比差點說服小扎同窗不要搞什麼社交網絡了,仍是好好學習拿畢業證書。。。
這這篇文章裏,Matt Welsh 介紹他的一天是如何度過的(另外還提到了在哈佛當教授是如何度過的,也頗有意思),我摘抄以下:
- 9:00,到公司,查郵件
- 9:30-10:15,寫代碼,增長功能,編寫單元測試,發起 changelist 代碼 review,喝無糖可樂
- 10:15-11:00,切換 git 分支到其它項目,查看同事 review 代碼的結果,回覆評論併發新版本 changelist
- 10:00-11:30,再次切換 git 分支,提交一個要運行 3 小時的 MapReduce 任務分析網絡延遲日誌
- 11:30-12:00,和山景城的團隊成員開視頻會議
- 12:00-12:35,午飯
- 12:35-14:00,檢查郵件,檢查 MapReduce 任務運行狀態,回覆代碼 review 的評論,再次提交代碼,而後查看任務列表肯定接下來的工做
- 14:00-15:00,和在劍橋(有評論指出這裏是波士頓的劍橋,不是英國那個)、山景城等多個地區的團隊成員開項目會議
- 15:00-16:00,喝紅牛,這時 MapReduce 任務已經跑完了,生成圖表,分析數據中不符合預期的部分,整理代碼,準備下一次 MapReduce
- 16:00-17:00,喝蘇格蘭威士忌(scotch)並玩吉他英雄(Guitar Hero)
- 17:00,收拾筆記本回家
看完後個人幾點體會是:
- 前面提到的代碼只有 trunk 並不許確,固然每一個部門確實可能不同
- 代碼 review 作得很認真
- 看起來任務很明確,因此雖然工做時間是 9-5,但效率挺高,這點我最爲好奇的,怎麼作到將工做安排這麼具體?
- 除了寫代碼,分析數據也是天天的重要工做,具體分析什麼能夠經過他的論文瞭解,看得出來是很細緻的
內部工具
2008 年前的內部工具狀況能夠經過這篇文章和這個 PPT 瞭解,不過以後就不清楚了,看起來不少外部工具都有內部版本(Docs、Mail、Talk、Calendar 等)。
這裏說一下 Chromium 項目中我看到的工具使用狀況:
- 網站是基於 Sites 搭建的
- 設計文檔喜歡使用 Docs,由於能夠在線編輯和評論功能,因此多人協做會很方便
- https://codereview.chromium.org/
- 在 Groups 中進行討論
- 使用 code 來管理 issues
- Buildbots 來進行編譯和集成測試
- 搭建了各類檢測工具來保證質量,具體細節推薦讀這本書,看完這本書我最大的體會是沒什麼神奇的東西,徹底靠細心的工做
可用的石頭
如下是我認爲能夠借鑑的地方:
- 源碼不分版本,對內部全部人公開
- 在 FEX 內部已是這樣了,但咱們應該推進更普遍的開放與共享
- 嚴格的代碼規範及單元測試機制
- FEX 全部項目將接入 Travis CI
- 代碼規範及單元測試的強制檢查
- 代碼 owner 的 review 機制
- 經過實際例子來使用,甚至不用看文檔
- 增強對 demo 及 example 的要求,不能是簡單的 hello,而最好是從產品線實際使用案例中抽取出來
- 文檔及相關資料和代碼放一塊兒
- 這能保證找起來很方便
- 若是因爲種種緣由不能放一塊兒,至少也要放連接
- 外部產品有內網版,好比 Docs
- 典型的 Eating your own dog food
- 在內網提早測試外部產品的新功能,並且通常內部人員都會很積極地吐槽,對產品改進頗有幫助
- GWT 的靜態檢查機制
- 整理這篇文章時我發現 TypeScript 也已經接近 1.0 版本了,看起來時機快成熟了,後續計劃嘗試 TypeScript