我叫谢伟,是一名侧重在后端的程序员,进一步定位现阶段是 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 框架
上文就是我平常的一些思考,但愿对你有所启发。
整个的过程,实际上是梳理你的知识体系过程,若是你接触的知识不少,不常常整理,在你脑海中,可能只是堆积,用到的时候不能及时的调用出来,因此会常常说:这个我见过啊。
及时的梳理,在脑中模块化,调用起来天然顺畅的多,固然,迫于遗忘曲线,这些动做,你还须要反复的重复。