這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
在創業公司初創伊始,如何選擇合適的語言決定了產品後續的技術棧和如何進行合理的業務支撐方向。如果你在讀這篇文章之前,更傾向於選擇Java/C#/PHP常見語言技術棧,我覺得對於你而言,這篇文章協助不大。因為對你而言,這些技術棧意味著更加方便招人,更方便的故障處理資料等等。但是如果一個初創公司想要選擇合理的小眾語言技術棧,我想這篇文章對你也許有一些協助。
在文章開始之前,我覺得有必要描述一下所謂的小眾語言,這裡我在最初進行技術選型時,考察了包括:
- Python: 你可能在接觸爬蟲、大資料分析等等方面聽過Python的大名,大家都知道Pythonista都習慣說的一句話就是:人生苦短,我用Python。
- Ruby: 你如果做過Web架構,你遇到最多的是很多人都會提到RoR架構。用過之後只有一個驚歎了。
- JavaScript(Nodejs): 有沒有聽過JavaScript全棧工程師?有沒有聽過JavaScript全棧工程師?有沒有聽過JavaScript全棧工程師?
- Golang: 簡單粗暴的語言,也許你見過很多人跟你吹噓,Golang是下一代的雲端運算開發語言。
其他語言太過於小眾,考慮語言的應用很多需要得到更多的社區支援,目前不在考慮的範疇內。
小眾語言的劣勢
正所謂知己知彼百戰不殆,在瞭解一個技術選型之前,最好是研究這些語言的缺點。因為你最後感覺這個技術選型不適合你的時候,根本的原因是這些劣勢影響了你。
在上面提到的幾個語言中,Python、Ruby、JavaScript是屬於動態語言。關於動態語言的爭議最大的地方是:動態語言到底是否合適進行大型項目。事實上,在某些階段,多人合作,並且大家水平語言不同時,這個時候通常會有這樣的問題:團隊需要花更多的時間在確保動態語言的準確性上。對於一個項目有高可用、低錯誤率的要求時,由於語言的動態特性,就需要對程式開發時的單元測試和後期整合測試的要求更高。因為變數在運行時才會賦予類型含義,所以很難在靜態檢測過程中發現足夠多的問題。這樣對測試人員的壓力也會更大,當你沒有合適的測試人員時,這個時候通常會變成,你只覆蓋測試了理想情況下的成功失敗情況,而對特別異常情況缺少評估。
Python、Ruby文法對程式員而言最大的成本在於需要重新學習一門新的語言。這個學習成本、時間成本通常對初創公司而言通常是支付不起的,哪怕像這些比較容易學習的動態語言而言。另外一個值得一提的是,無論是Python還是Ruby,從長遠看,如果你後續有較大的使用者增長又需要保證使用者體驗時,Python、Ruby的執行效率和輸送量會有較大的影響。
Python和程式員入門的語言差距較大:用4個空格表述程式縮排。這意味著,程式員直接從網上尋找解決方案(拷貝代碼)時成本更高,因為很有可能他需要手工進行代碼格式化,這樣有可能造成程式邏輯的改變。另外一個不得不提的是一些Python庫看似好用,實際上或多或少有有一些坑,這對新手而言,往往是致命的。對應的,Ruby語言本身時不存在這些問題的。然而Ruby作為開發主語言時最大的問題是,如果選擇RoR架構作為初始的Web架構時,如果沒有一個熟悉RoR架構的人,那麼學習修改RoR架構的成本是特別高的:對於一個通用型架構而言,你可能需要更多的特殊情境定製,這可能需要做大量的猴子補丁,如果不對架構有一個清晰瞭解時,這樣的成本會更高。
JavaScript(後面統一用Nodejs代稱)則藉助Nodejs實現了高效能和較大輸送量。而且從語言層面上,JavaScript對很多程式員並不陌生。然而,在過去的很長時間,真正熟練掌握JavaScript的都是前端工程師,這是一個非常尷尬的問題。對後端工程師而言,Nodejs需要與前端不同的技術棧,而且大概沒有公司希望一個完全沒有任何後端經驗的前端工程師去接手後端項目的開發的。Nodejs是一個年輕的語言,年輕必然會伴隨一些問題,比如,庫比較少(當然現在也是井噴期)。一些必要的庫需要慢慢尋找。事實上,我也不得不吐槽,可能是開發人員水平問題,導致很多npm提供的包,往往或多或少存在一些比較惱人的BUG,這些BUG可能會在你開發過程中,正常運行中出現,而你卻不得不幹掉它。對於這種BUG,很多時候更快的處理方式是你自己動手進行快速修複。然而當你的程式員不具備這種能力的時候,就需要提一個issue到開發人員,由開發人員進行修複,並且需要等待版本更新到npm源中。很多時候這個過程都是比較尷尬的,尤其是你選擇了一個開發人員並不是特別活躍的包。
Golang是一個編譯型語言,文法簡單,似乎一切看起來都是那麼的美好。事實上Golang本身還是處於在Google開發維護的階段,本質上雖然語言完全開源了,但是卻不是一個完全社區維護的語言。換句話說,Google會決定Golang未來的走向。不過好在第三方包都是由社區來驅動的,這樣還是提供了更多的可定製性。另外一個比較煩惱的是Golang本身的包管理機制,事實上,這是完全是一個偽命題。別告訴我你覺得go get完全足夠了,那隻是因為你還沒有遇到依賴導致break的問題而已(Godep也可以解決一部分問題,然而第三方包API的變更你是沒辦法控制的)。不過從現在看起碼Google意識到自己的問題,也正在努力改變吧。Golang同時也是一個年輕的語言,庫比較少的問題也會出現。雖然你可以利用cgo去橋接一些現有的C/C++庫到Golang程式中,但是這部分的代碼維護,涉及到GC的最佳化處理等各個方面,對開發人員的要求不低。另外一個大家都會抓住講的就是GC問題,在高並發環境下GC的影響從1.5開始下降了很多,但是GC並不像Java一樣更加可控,很多時候GC還是需要進行代碼層面進行控制。
上面所有的小眾語言還面臨一個共同的問題,招人。沒錯,找到一個適合的小眾語言工程師是一個痛苦的事情。雖然你可以通過語言的高開發效率去節省人力,但是當你面臨人手緊缺的困境時,去找一個合適的替補人就變成了一件非常昂貴的事情。通常你需要從現有的人員中培養則更加靠譜。(慶幸的是,經過培養後,哪怕我們的移動開發工程師也可以hold住我們現在的後端部分需求。當然,這隻是感興趣的前提下。)
如何選擇合適的技術棧
這是一個複雜的問題。選擇合適的技術棧,你需要覆蓋上面我提到的所有的劣勢問題。比如說,你選擇了Nodejs,你就要考慮,你可以hold住所有的痛點,你可以修正開源包的問題,甚至你可以解決現在沒有包的難題,OK,那麼你選擇這個語言本身是沒有任何問題的。
而我在綜合考慮之後,選擇的技術棧比較簡單:Python和Golang。其實選擇的原因很簡單,這兩種語言我更熟悉。沒錯,這個是第一個理由。為什麼會有2個技術棧,這個其實與我們現有的業務狀態和未來發展的思考有關,這個會在後面進行一下介紹。厚臉皮的說一下,Python和Golang語言中的絕大部分問題目前都可以自己解決,這也是另外一個理由。
接下來,人員培養方面,上面提到的小眾語言大多培訓容易,以現在產品發展節奏和產品演化速度,我們的人員培養成本目前是可以承受的。
使用Python的原因,是開發更快,從而可以快速試錯。利用現有的Web架構,搭配合適的資料庫,我們可以在1-2周內實現一個完整產品的上線,進行快速試錯。我們針對Python制訂了一系列的標準,用於規範代碼的格式,保證代碼的強壯度。這個可以參考下我之前關於代碼風格要求的文章。
使用Golang的原因,在於需要製作大型長期穩定運行項目的考量。事實上,我在前面也提到了,在目前的開發過程中,Python在多人協作過程中個人編碼風格、工程性上要更弱、長期運行無法控制的記憶體流失等等問題,如果需要長期穩定運行,我更傾向於選擇可以進行編譯的編譯型語言,通過靜態檢查+動態測試方式,更好的保證程式的強壯型。
結語
上面囉裡八嗦說了那麼多,只是想告誡大家,對小眾語言而言,選擇的機會成本是特別高的。如果你只是驗證試錯,或者你只是想卷一筆錢就跑,小眾語言的高開發效率是絕對可以滿足你的。但是從一個大型工程的角度,你需要通盤考慮小眾語言的劣勢,選擇一個合適的語言作為你的技術棧是十分必要的。
另,杭州雲柚科技長期招聘有潛力的Python/Golang開發人員,有興趣的請發送簡曆至 kevin |at| yeeuu |dot| com
Others