上一節:5. 物 - 技術管理
文 - 文化建設
核心思想: “八面”玲瓏
團隊文化是指團隊成員在相互合作的過程中,為實現各自的人生價值,并為完成團隊共同目標而形成的一些行事態度、思考方式和行為準則。在技術管理方面,我主要是負責塑造技術文化氛圍,并通過這些思想、準則來影響及推行“團隊管理”、“項目管理”及“技術管理”等方面。
我眼中的工程師文化
所謂“八面”玲瓏,不是指要把人培養成圓滑的人,而是我認為在一個以工程師為伍的技術團隊中,應該建立以下八個方面的文化:
- 學習文化
- 創新文化
- 工程文化
- 工具文化
- 自動文化
- 腳本文化
- 開源文化
- 流程文化
學習文化
- 技術調研
- 技術總結
前面“技術管理”中說過要“喜新厭舊”,不斷擴寬知識邊界、填平知識短板,團隊技術水平才能不斷提高。對新出現、不熟悉的技術點要進行調研,出調研報告;對已經熟悉用過的,要做技術總結,使得經驗可以復用。如何鼓勵內部分享,外部交流、互通有無,在前面“團隊管理”如何“培養”已經具體說過就不再展開。
創新文化
公司無創新則無獨特的競爭力,這點大家都懂不多用解釋。但我認為“創新”不止是說創造新的工具、組件,勇于使用新技術、引進新框架、打破陳規做法也是一種創新,能引起“有益的變化”就是創新,應該鼓勵。
例如我看到我們有一個項目后端是ruby,前端是coffee語言編寫,都有大量的類定義,新加入的開發人員上手會比較困難,為此我編寫了一個文檔構建腳本,能自動對2種語言的代碼分別生成統一的YARD風格的文檔,再合并在一份文檔中,以方便開發人員查看熟悉程序結構,如「圖6-1」
? 「圖6-1」build app doc
這種有利于提高工作效率的改進在我看來就算是一種微創新。
工程文化
軟件工程開發,從來不是寫個“Hello World”這么簡單的事情。一個完整的軟件工程,需要考慮程序語言、數據庫、開發工具、系統平臺、依賴包管理、代碼目錄結構、設計模式、日志記錄等方面,開發項目交付時,除了代碼,還要功能說明文檔、代碼說明文檔、單元測試、壓測報告、部署說明文檔。所以在我看來,一個開發框架的工程化成熟度,就是看以上這些方面的覆蓋程度。
前面“技術管理”中說過了我們的Web 開發框架是用Rails,而Rails是fullstack的、從一開始就走工程化的風格,從初始化一個rails項目的第一步的命令: rails new MyProject --database=postgresql --javascript=jquery
看出它會期待你預先考慮好后端使用什么數據庫,前端使用什么js庫,當然這些參數都是可選,不選擇則使用默認配置,Rails遵從CoC(約定優于配置) 原則。
再看一下rails 5自動生成的項目目錄結構:
├── Gemfile # gem依賴管理(Gem是Ruby領域的apt)
├── README.md # 說明文檔
├── Rakefile # 構建任務管理入口(Rake是Ruby領域的Make)
├── app/ # 應用代碼
│ ├── assets/ # 靜態資源文件(js,css,img,font)
│ ├── channels/ # 基于WebSocket 的Pub/Sub實現
│ ├── controllers/ # 控制器,負責處理請求,調取Model,選擇View渲染
│ ├── helpers/ # view 的輔助模塊
│ ├── jobs/ # 隊列任務
│ ├── mailers/ # 郵件內容
│ ├── models/ # 業務模型
│ └── views/ # 視圖(HTML模板)
├── bin/ # 一些項目CLI命令、自定義腳本
│ ├── bundle*
│ ├── rails* # 主要CLI,提供啟動app server、控制臺、生成器、運行測試
│ ├── rake*
│ ├── setup* # 項目初始化腳本,一步完成安裝依賴、數據庫初始化、啟動rails server
│ ├── spring*
│ └── update* # 開發過程更新腳本,一步完成安裝依賴、數據庫遷移、清理臨時文件、重啟rails server
├── config/ # 各種配置,如啟動方式、數據庫配置、路由配置、環境配置、密鑰配置、i18n配置
├── config.ru # Rack架構服務調用接口
├── db/ # 數據庫遷移改動、種子數據
├── lib/ # 獨立的類、模塊、app相關的rake任務
├── log/ # 各種日志文件
├── public/ # 不用預處理、可公開訪問資源目錄,如404.html,robots.txt
│ ├── 404.html
│ ├── 422.html
│ ├── 500.html
│ ├── favicon.ico
│ └── robots.txt
├── test/ # 單元測試、集成測試
│ ├── controllers/
│ ├── fixtures/
│ ├── helpers/
│ ├── integration/
│ ├── mailers/
│ ├── models/
│ └── test_helper.rb
├── tmp/ # 緩存、臨時文件
│ └── cache/
└── vendor/ # 第三庫、資源
└── doc/ # 文檔存放目錄,從rails 4不再默認生成,但可以通過`rake doc:app` 來檢查并生成app代碼文檔
從所生成目錄就能看出在 rails 項目里會涉及到依賴包管理、構建任務、靜態資源處理、消息訂閱處理、消息隊列處理、MVC架構、郵件處理、提供CLI、i18n處理、多環境適配、Rack架構、數據庫連接、數據庫查詢(ORM)、數據結構遷移管理、初始化數據管理、日志處理、單元測試、集成測試這些概念,幾乎涵蓋了一個Web項目需要用到的方方面面,可以大方說句使用rails的開發者相對是比較“幸福”的,因為有很多細枝末節的地方都已經有被考慮到,而且還在不斷的補充引入新的feature。
我們使用的技術框架不止rails,在前后端分離的架構中,前端使用過Backbone/Angularjs/React & Redux,在移動開發中使用Ionic/React Native,但這些技術框架中有些沒有很統一、符合要求的工程化規范,因此我安排整理了一些目錄規范,例如:
- angularjs 項目目錄結構規范文檔
- react-redux 項目目錄結構規范文檔
- React Native項目結構規范
以便開發項目時更工程化、結構化,可以在新項目中可以復用架構、組件可以通用
工具文化
“工欲善其事,必先利其器”這句話我非常贊同。如果說任務開發是戰場,那么開發者使用的工具就是他們的武器,把“武器”打磨得是否順手就會成為戰場生存的關鍵之一。我經常在團隊中推薦并鼓勵每個人都分享、推薦自己使用過、認為高效的工具,例如:
- Shell: zsh/fish - 交互式shell,提高CLI操作效率
- 代碼提交: GitX - 我鼓勵在代碼提交時使用git的GUI工具如GitX而不是命令行,因為GUI工具可以進行代碼整理,有利合理的代碼提交記錄
- 終端操作: TotalTerminal/iTerm - 隨時隨地可以進行敲命令
- 文檔編輯:MacDown - 所寫己所得、兼容github GFM格式
- API查看:Dash - 快速離線查看各種技術API文檔,開發者必備
- 窗口操作:Spectacle - 多屏幕操作利器
- 應用訪問:Alfred - 把Mac變成Google Instant Search 般的體驗
- 圖片編輯:Skitch - 一圖勝千言,快速給截圖加上注釋
- 數據庫操作:Navicat Lite - 支持鏈接mysql/postgres/oracle/sqlite/sql server,開發者必備
- 代碼編輯器:Sublime Text/Vim/Emacs/Atom - 編輯器的選擇對程序員而言是場“圣戰”,為了找出“哪個才是最好的代碼編輯器”,我特意在團隊內發起過專題分享活動:“編輯器到底哪家好”——技術分享 @ 2015-01-10
自動文化
優秀程序員三大特質之一是“懶”,能用程序、腳本解決的,就不用手工,更有“以自動化為榮,手工為恥”的說法,常會出現花費幾個小時的腳本去解決一次只要十幾分鐘簡單但會重復的問題,作為管理者遇到這種情況不應該一昧的打壓,因為這種思想就是以自動化思維去解決重復,前面“技術管理”章節中就提到過了自動化的重要性,從本地開發、到代碼提交、測試、集成、部署、發布、監控等各個環節中都有加入自動化的操作,能執行自動化的都盡量推行自動化,提高效率之余減少人為誤操作。
以現在的觀點來看,一個技術團隊中有沒推行自動化技術,可以認為這個團隊是否達到“高效”的檢驗特征之一了。
腳本文化
無論是作為Java,C++,.Net 這類靜態語言的程序員,還是使用Ruby,PHP,Python,JavaScript 這類腳本語言的程序員,在開發過程中都會接觸到Shell腳本(Shell Script),因此掌握一些基本的Shell腳本操作,可以有效提高工作效率。
除了可以使用上面提到的“工具文化”中推薦的一些交互式shell來提高CLI操作效率外,還應掌握一些簡單的Shell語法,用以編寫輔助開發的腳本。
最簡單的做法是可以增加一些alias作為一些常用命令的組合,使用有語義的命名,配合可交互Shell的提示,很簡單、很低廉的操作成本,就可以在很大程度上減少重復敲打鍵盤、錯誤輸入。例如我給不熟git的新人建了個 git-cmd-helpers,就是增加一些常用git 操作的封裝,用以提高git的使用效率。
開源文化
作為技術開發者,我們是技術開源社區的收益者(可見我發表的 blog post:Beansmile用到的開源產品),因此也鼓勵開源精神。我會經常在團隊中鼓勵在開發中使用一些開源組件遇到問題修復時,給源作者發PR,我們在github上也有發布一些開源作品。
流程文化
制訂流程,是團隊多人協作的基礎,是“規范化”的細節,是“自動化”的前提。
在前面的“團隊管理”提到工作要流程化,我制定了涵蓋從招聘到入職、升退評價的招聘和入職流程;“項目管理”中我制定了[Beansmile開發流程規范]、[Beansmile Trello使用規范],涵蓋從需求對接到項目結束交付;“技術管理”中提到[trello + git開發流程規范],涵蓋了代碼提交流程、代碼審查流程、部署流程步驟細節。
制訂制度、規范的流程
同樣的,在企業中制定一種新的制度、規范時,也應該遵從類似以下流程:
- 調研 - 先看人家怎么做
- 制訂 - 自己要怎么做
- 發布 - 跟團隊說明是什么、怎么做
- 執行 - 怎么說就要怎么做,最忌光說不練
- 監督 - 了解執行效果,收集反饋
- 修正 - 根據反饋意見調整細節,收集到足夠多的改動后發布新版
- 發布新版 -> 執行 -> 監督 -> 修正 ->(重復)
思路:跟寫單元測試一樣
- 編寫測試代碼
- 運行測試
- 觀察結果
- 修正實現代碼 -> 運行測試 -> 觀察結果 -> (重復)
推衍:企業內所有的重大決策都應該如此推行
所以一個成熟的技術團隊中,為了明確職責、分工清晰、減少沖突,是很有必要制定一些常用流程,并將之作為的規范文檔沉淀下來反復推行實踐,以下我制定過且形成規范文檔的流程:
- [Beansmile招聘流程] (見「圖3-5」)
- [Beansmile新員工入職流程] (「圖3-6」)
- [Beansmile開發流程規范](見「圖3-15」)
- wiki:[Beansmile任務開發流程]
- wiki:[Trello + git開發流程規范]
小結
以上這八種便是我認為是對技術團隊有益的文化總結。
企業文化建設能否建設好同樣是門不簡單的技術活,但更大程度上是受企業創始人、管理層影響,因此不同技術團隊中即便是使用相同的技術棧,但由于創始人不同,所施行的管理理念、思考方式不同,執行結果也就不一樣。因此我不認為有“最好”的團隊文化,只有“最適合”的團隊文化,因地制宜、量身打造的才是適合自己的。