我叫謝偉,是一名側重在後端的程序員,進一步定位現階段是 Web
後臺開發。程序員
因爲自身智力通常,技術迭代又很是快,爲不至於總處於入門水平,常常會嚐鮮新技術。golang
爲保持好奇心,平常除技術之外,還會涉獵攝影、演示設計、拍視頻、自媒體寫做等。web
若是此刻我是一個成功人士,看到上面的領域,有人會羨慕說:「斜槓」,遺憾的是,在下沒有成功,因此,上面的領域都必定程度上會被人認爲:「遊手好閒」,不過不重要,我本職仍是一名後端程序員。數據庫
記憶有遺忘曲線,這是你們都懂的道理,因此爲了防止忘記,最重要的方法是常用、反覆使用。這也是爲何,有些人說:在工做中學最容易進步。由於工做的流程、項目不會頻繁變更,你會常常性的關注一個或者多個項目進行開發,假以時日,你會愈來愈熟悉,理所固然,你會越作越快。這個時候,就達到了所謂的:溫馨圈。要再想進步,你得跳到「學習區」。再反覆這個動做。編程
問題是,除了工做以外,你不多有其餘機會再進行技能鍛鍊了。後端
這個比較容易理解,由於更爲複雜的任務,你纔可能嘗試使用新的技術棧,有機會進行其餘技能的鍛鍊,這樣就能進入「學習區」。網絡
若是公司項目就這麼點,沒有太複雜的,或者說新項目和你接觸的相差很少,只不過應用場景不一樣而已。這個時候,任務若是必定須要你的參與,你最好嘗試新的架構,嘗試新的技術點,儘管大致相同,能夠將你認爲原系統不合理的地方改進,這樣也能創造機會進入「學習區」。架構
但就我認爲,通常項目開發時間都很是緊,開發人員有可能沒有充足的時間進行考慮,會依然使用原有技術點,這樣進入學習區的機會就被浪費了,你只是使用一份經驗,作了兩個類型的項目而已。app
剛進入職場,核心位置就那麼幾我的佔着,論經驗、論資歷,你都不如別人,你接觸到的資源有限,沒有新項目讓你獨立開發,只有舊項目的 Bug 讓你修復,那該怎麼辦?
換坑嗎?怕不怕另一個也是坑?
即便是你能完成的任務,你有沒有嘗試過本身獨立寫一個,你有沒有嘗試過本身彌補下不懂的知識點,你有沒有嘗試過總結下本身的開發流程是不是最優的,你有沒有嘗試過總結下項目的技術要點,你有沒有嘗試過提煉能夠複用的技術點...
若是你都沒有,恭喜你,你又找到了一個進入「學習區」的點,即:補充原有技術棧。
也許你工做中已經有一門經常使用編程語言,但都是靠 Google、StackOverFlow,你是否是要嘗試梳理下整個編程語言的知識體系,固然梳理的切入點依然是和工做相關爲先,由於這最迫切,最能反覆,使用頻率最高。
也許你對數據庫相關知識略懂,對優化數據知識點卻不是很懂,你是否是要嘗試下找相關資料彌補下。
也許...
也許你還能夠翻閱源碼,好比內置庫的實現,以前我還不太會關注這些,寫起代碼來不是頗有底氣,後來常常性的查看源碼,藉助 IDE 的跳轉功能實現對源碼的閱讀,再結合 IDE 的 structure
,能夠對文件的函數、結構體、方法等進行組織。這樣從總體觀看一目瞭然,看得多了,你甚至能夠總結出一些共性:
Interface
是方法的集合,內置的經常使用的 Interface
其實很少,不少內置包都相互實現http.DefaultClient
...閱讀庫的源碼,我通常是怎麼作的呢?(不要太關注具體的實現,除非你徹底能看懂)
structure
功能,查看文件的具體組織形式,看可導出的結構體、函數、方法等net/http
包幾乎奠基了 Go 領域全部 Web
框架、網絡請求庫的基礎。由此來看下我是如何梳理的。
隨意找本相關的書,發現是個大塊知識啊。結合通常的歷史經驗,你可能做出這麼張思惟導圖。
整個過程像是:你從一本書總摘出的目錄,前提是看過書的內容而得出來的。
網絡請求分爲兩個層面:
func getHandle(rawString string) { response, err := http.Get(rawString) if err != nil { return } defer response.Body.Close() content, _ := ioutil.ReadAll(response.Body) fmt.Println(string(content)) }
看上去發起網絡請求很簡單,只須要使用 http.Get
便可。
爲完善認知,去看看源碼,直接使用 IDE 的跳轉功能。
結合 IDE 的 structure
功能,原來 http.Get
是源碼中有一個默認的 DefaultClient
調用其方法 Get
。
func Get(url string) (resp *Response, err error) { return DefaultClient.Get(url) }
同理,http.Post
和 http.PostForm
也是。
理所固然,你能夠自定義個定製化的 client
,調用其 Do
或者 Get、Post、PostForm
方法等。
type Client struct { ... }
這個時候,你的思惟導出多是這樣:
好,關於net/http
客戶端層面,你如今應該清楚如何使用了。你既可使用默認的,默認的若是達不到需求,你能夠本身實例化一個client
, 你還能夠實例化 http.Request
,最後調用 client.Do
方法,均可以完成目的。
服務端比較重要,平常 Web
開發,也絕大部分是在服務端工做。
如何啓動 Web
服務呢?
type SelfHandler struct { } func (SelfHandler) ServeHTTP(writer http.ResponseWriter, req *http.Request) { writer.Write([]byte("Hello Python")) } func main(){ // method One http.HandleFunc("/hello_golang", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("Hello Golang")) }) // method Two var self SelfHandler http.Handle("/hello_python", self) log.Fatal(http.ListenAndServe(":9090", selfServerMux)) }
分爲兩步:定義路由和觸發路由以後的動做、啓動服務。
看上去也很簡單啊,看看源代碼,服務端比客戶端更爲複雜。
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler) } type Handler interface { ServeHTTP(ResponseWriter, *Request) }
原來又使用了內部一個默認的 DefaultServeMux
(請求路由器)。Handler 是個接口。上文中 SelfHandler
實現了 Handler
接口。
以前你可能會有點混淆,Handle、HandleFunc、Handler
之間的關係。對比着看,你應該會清晰些。
既然使用默認的 DefaultServeMux
, 那麼也能夠定製化 ServeMux
。
func main(){ var selfServerMux *http.ServeMux selfServerMux = &http.ServeMux{} selfServerMux.HandleFunc("/hello_golang_2", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("Hello Golang 2")) }) log.Fatal(http.ListenAndServe(":9090", selfServerMux)) }
同時能夠定製化服務端的配置信息。
func main(){ var selfServer http.Server var selfMux *http.ServeMux selfMux = &http.ServeMux{} selfMux.HandleFunc("/d", func(writer http.ResponseWriter, request *http.Request) { writer.Write([]byte("Hello Mux")) }) selfServer = http.Server{ Handler: selfMux, Addr: "localhost:9098", } log.Fatal(selfServer.ListenAndServe()) }
至此,你的思惟導圖大概這樣:
固然企業級的 Web
服務開發還須要考慮:
...
使用一些 web 框架
上文就是我平常的一些思考,但願對你有所啓發。
整個的過程,實際上是梳理你的知識體系過程,若是你接觸的知識不少,不常常整理,在你腦海中,可能只是堆積,用到的時候不能及時的調用出來,因此會常常說:這個我見過啊。
及時的梳理,在腦中模塊化,調用起來天然順暢的多,固然,迫於遺忘曲線,這些動做,你還須要反覆的重複。