給想轉Go或者Go進階同學的一些建議

語言: CN / TW / HK

highlight: a11y-dark theme: Chinese-red


本文為掘金社區首發簽約文章,14天內禁止轉載,14天后未獲授權禁止轉載,侵權必究!

前言

最近一直有小夥伴私信我學Go語言的問題:

有的小夥伴覺得客户端太捲了,想轉服務端,覺得Java也卷,想學Go語言;

有的小夥伴是想從PHP或者Java轉Go,做高併發編程,覺得Go更有前途。

聊的多了,發現這是一個共性問題,所以乾脆整理成文章,希望對更多的人有幫助。

這篇文章會結合我的經歷:

聊聊我認為客户端轉服務端開發最大的挑戰是什麼?

如何高效轉型做服務端開發?如何高效學完Go基礎?

在熟練掌握Go基礎之後,如何進階?進階要掌握哪些知識點?

先説結論

  1. 客户端轉服務端,最大的挑戰不是學一門新語言,而是編程思維的改變
  2. “三刷”官方文檔是我高效學習一門新的編程語言的制勝法寶1刷從頭看到尾,掃清知識盲點,搞清楚概念;2刷必須手敲,而且要寫註釋和總結;3刷先只寫註釋,不看文檔實現功能,遇到問題再和文檔比較,加深理解。 如果還有餘力,就和我一樣整理成文章,分享出來幫助大家學習,回饋社區。
  3. 在掌握Go基礎之後,也可以通過“三刷”的方式掌握SQL,Redis,Linux,Nginx的基礎知識點,這樣就有能力開發Web項目了。
  4. 要進階就要學“微服務”和“DDD”!下文也會重點講講微服務和DDD的概念,讓大家先有個目標,這樣才能心中有火,眼裏有光。

我的經歷

我從2015年開始編程,已經有7年經驗。入行時用Java語言開發了2年安卓客户端,然後轉崗用PHP做服務端開發,最近2年用Go做Web應用開發和微服務開發。

下面介紹一下我的轉型經歷,看看對小夥伴們有沒有啟發,歡迎在評論區留言。

客户端開發到服務端開發

無論客户端轉服務端,還是服務端轉客户端,在有基礎的情況下,學習一門新的編程語言,我認為都是比較輕鬆的。

對有基礎的同學來説,學習一門新的語言,無外乎就是學習新語言的:數據類型、函數、運算符、錯誤處理等,再重點攻克一下語言的特點,基本2周時間就能去嘗試寫簡單的demo,開發項目了。

當然,開發項目往往不是一帆風順的,遇到問題也不要怕,一個一個的去解決就好了。 多在論壇或者社區裏和大家交流,聞道有先後,不用擔心自己提的問題太簡單而不好意思。

難點在哪裏呢?

我認為難點在編程思維的轉變,思考問題角度的轉變。

客户端開發思維

82ad99aa806b9299f967811c7e14de95.jpeg

回想一下當年用Java開發安卓時考慮的問題:

  1. 如何複用UI,如何做到高保真還原設計稿,機型兼容處理
  2. Activity生命週期的管理,不同生命週期適合處理什麼業務
  3. 如何做機型兼容?小米和華為的消息通知如何做特殊處理?
  4. 內存泄露的場景和解決辦法
  5. 客户端如何實現三級緩存
  6. 如何合理的使用線程和線程池等

尤其是剛入行的時候,就是照着設計稿按部就班的切頁面開發功能。

有了經驗之後,會先把項目中所有的列表頁面抽取出來,封裝一套組件;再把所有的按鈕、輪播圖等抽取出來,封裝成組件...

反思一下,我們開發客户端的思維習慣是什麼呢?我們是如何設計代碼的?

我認為是以設計稿為標準進行開發的,每位客户端開發的同學要開展工作都離不開UI設計師的設計稿。我稱這種編程思維是:“頁面驅動設計”

資深的客户端小夥伴們還有哪些高見,歡迎在評論區討論。

服務端開發思維

63b9279cf91967c208ca912fa64de8a1.jpeg

當我轉崗做服務端開發,發現一個非常爽的事情:我不需要再等UI同學的設計稿、UE同學的交互圖了。

只要產品同學確定好PRD文檔,我就可以開發了,開發的順序往往是這樣的:

  1. 通讀一遍需求文檔和原型圖
  2. 梳理業務邏輯,進行抽象,明確有多少個功能需求要開發
  3. 根據功能需求創建數據庫,創建表,添加字段,設置合適的字段類型,長度,主外鍵等
  4. 考慮業務場景,創建索引...
  5. 開始瘋狂的CRUD...
  6. 開始瘋狂的加Cache...
  7. 開發瘋狂的給客户端提供數據接口...
  8. 持續迭代:根據業務增長做負載均衡、分庫分表、讀寫分離....

做服務端開發的小夥伴是不是和我一樣呢?歡迎在評論區討論。

你認為上面哪個步驟最重要呢?

我認為設計數據庫表結構是最重要的環節:對業務的理解程度,對可擴展性的考慮程度都直接影響到了我們會“如何設計數據庫表結構”;數據庫表結構設計是否合理,也直接影響了我們後續開發業務邏輯是否順利。

我稱這種編程思維是:“數據驅動設計”

(PS:網絡上關於“數據驅動設計”這一名詞更主流的解釋:通過不斷的數據積累和反饋,來指導產品的更新迭代。

階段性總結

客户端和服務端就是會有不同的編程思維,關注點是不一樣的:

客户端不需要關心數據是怎麼來的,要求服務端返回自己需要的數據即可。

服務端不需要關心客户端如何管理應用的生命週期,只需要按照客户端要求返回數據即可。

以上,就是我認為的客户端轉服務端,最大的挑戰是編程思維,思考方式,考慮問題關注點的轉變

客户端同學在學完服務端編程語言後,要有意識的站在服務端的角度去思考問題,及時調整自己的角度,不要用之前開發客户端的角度思考問題,不然會很痛苦。

如果你有PHP或者Java的基礎想轉Go,相比於前端同學會輕鬆很多,可以復刻一下我的轉Go之旅:# 回顧一下我的Go學習之旅 | 對你應該會有啟發

好了,給想轉Go同學的建議聊完了,咱們再聊一聊進階的知識點:DDD和微服務。

不同崗位的技術人員思維方式有區別,技術人員和非技術人員的思考問題的方式就更不一樣了。

正是因為不同羣體在協助中就是會有“思考方式的不同”,有一個科學的方法來指導我們更好的協作就非常重要了。

d975dfece989019c4b2640cbe0fa9423.jpeg

我們再來延伸一下,聊一聊“軟件架構演進史”:

軟件架構演進史

結合我自己的經歷來介紹一下:

軟件的架構模式總的説經歷了三個階段的演進:從單機、集中式到分佈式微服務架構

image.png

第一階段:單機架構,這個階段通常採用面向過程的設計方法。通常採用C/S架構。現在反思一下,我在2015年剛剛入行做Android開發時的思考方式,本質上是面向過程的。雖然Java是面嚮對象語言,並且一直強調面向對象編程,但是因為自己的編程思想並沒有轉變過來,導致寫了一段時間爛代碼,被組長一頓KO操作。

第二階段:集中式架構,這個階段通常採用面向對象的設計方法。一般採用經典的三層架構MVC,系統包括業務接入層、業務邏輯層和數據庫層。在開發Android的後期是採用的這種方式,包括使用PHP做服務端開發時也是這種架構。這種設計模式的問題是:容易使系統變得臃腫,不易擴展性、彈性伸縮能力差。

第三階段:分佈式微服務架構,微服務架構可以實現業務和應用之間的解耦。解決單體應用擴展性差、彈性伸縮能力不足的問題,非常適合在雲計算環境下的部署和運營。近期在使用go-micro微服務框架開發項目,對微服務架構有了新的認識。

分佈式微服務架構是主流趨勢,越來越多的企業採用分佈式微服務架構進行業務轉型。

那麼如何才能更好的從單體架構和集中式架構轉型到分佈式微服務架構呢?答案就是:DDD。 這也是我們的進階之道。

我們再回顧一下上面提到的”頁面驅動設計“和”數據驅動設計“的場景,這樣能更好的理解DDD。

什麼是DDD?

DDD (Domain Driven Design):領域驅動設計。

我不想複製粘貼官方對於DDD晦澀難懂的定義,下面我將用最簡單易懂的話告訴你DDD是什麼?你值得知道的幾個概念,對一線開發人員來説,知道這些,足矣。

1. 核心思想

  1. DDD的核心思想就是避免業務邏輯的複雜性和技術實現的複雜性耦合在一起。
  2. 明確業務複雜性和技術複雜性的邊界,隔離雙方的複雜性,站在更高的角度實現解耦。

2. 最大價值

DDD最大的價值就是梳理業務需求,抽象出一個個“領域”,並形成各個領域之間的接口交互,方便團隊協作,推進項目前進。

3. 必懂概念

領域

領域就是一種邊界的劃分,首先舉一些生活中的例子:

比如互聯網、機械製造、種植業、養殖業等等這就是不同的領域;

再比如互聯網中的:移動互聯網、互聯網金融、互聯網健康這也是不同的領域;

我們把領域抽象一下,領域還可以這樣劃分:

  1. 核心領域:業務系統中的核心價值
  2. 通用領域:提供通用服務的領域,比如消息系統
  3. 支撐領域:作為基礎設施,專注於業務系統中的某個重要業務,比如日誌系統

在明確領域的概念之後,還有個更重要的概念:

領域模型

DDD的核心就是通過一套科學的方法論告訴大家如何創建不同的領域,如何確定領域的邊界。

“模型”是DDD中的重要概念:模型是對領域的抽象和模擬。

“建模”是DDD中重要的手段:建模是針對特定問題建立領域的合理模型。

“不以用户為中心”

DDD領域驅動設計,還有一個有意思的觀點:“不以用户為中心”。

為什麼會這麼説呢?

因為DDD認為,“以用户為中心”其實是表層需求,真正的需求應該是基於領域的,領域之所以有意義,一定是和人有關的。

所以做領域驅動設計時,應該做到“客觀設計”,就是無論是誰使用,如何使用,這個領域都是這樣的,挖掘深層次的需求。

講個小故事:

在汽車出現之前,那時候人們的需求就是想要一輛更快的馬車,如果當時被限制在“用户需求”的框框裏,怎麼能發明出來汽車呢?

仔細品品這個小故事,是不是很有意思。

階段性小結

對於小白來説,關於DDD瞭解到這裏就足夠了。

畢竟設計思想這種東西需要長時間的積累,需要不斷的通過項目實戰才能領悟。

目前也有不少人噴“DDD”,認為這是給CTO、項目經理、老闆吹水用的。

對於一線開發人員來講,與其關注DDD,不如關注如何用好“微服務架構”。

以我的經驗,當我看了很多DDD的資料之後還是雲裏霧裏,但是當我使用微服務架構去開發了一個項目,回過頭來再思考DDD,就清晰多了。

下面開始介紹微服務是如何讓DDD落地的?

微服務

微服務的特點如下,大家先有個整體的概念,後面我會使用go-micro和go-zero框架帶大家進行微服務項目的實踐。

1. 單一職責

DDD思想指導我們對業務邏輯進行拆分,明確各自邊界,形成不同的領域,不同的領域對應不同的微服務,這就是單一職責。

2. 團隊獨立

不同的領域對應不同的業務團隊,也對應着不同的技術團隊,彼此之間是解耦的。

3. 技術獨立

不同的領域,不同的團隊可以使用不同的開發語言,各自獨立,只要按規範提供服務即可。

4. 數據庫分離

每個領域(每個服務)都擁有自己的數據源。

5. 獨立部署

每個領域(每個服務)都是獨立的組件,可複用,可替換,降低耦合,易維護,易集羣Docker部署服務

總結

這篇文章結合我的經歷,分享了一下我客户端轉服務端在編程思維上的轉變;再通過軟件架構演進史帶大家瞭解了從單體架構到集中式架構,再到目前主流的分佈式微服務架構,為大家進階實戰指明瞭方向。

歡迎關注我的# Go語言進階實戰 專欄會持續更新Go進階實戰的知識點,學而不思則罔,思而不學則殆。 和我一起邊學邊實踐,把Go進階實戰進行到底。