gitbook/Tony Bai · Go语言第一课/docs/426265.md

137 lines
14 KiB
Markdown
Raw Permalink Normal View History

2022-09-03 22:05:03 +08:00
# 开篇词这样入门Go才能少走弯路
你好我是白明英文名Tony Bai欢迎你和我一起学习Go语言。
我现在在一家初创企业东软睿驰工作是一名车联网平台的架构师同时我也是技术博客tonybai.com的博主、GopherChina大会讲师。
从2011年开始我便关注了Go语言是Go语言在国内的早期接纳者。那个时候离Go开源还不过两年没有人想到它会成长到今天这样成为后端开发的主流语言之一。
在对Go长达十年的跟随和研究中我沉淀了很多个人的经验和思考。我也希望通过这门课跟你分享我学习和使用Go语言的一些心法。
## 我与Go的这十年
2011年一次偶然的机会我非常幸运地看到了Go语言之父Rob Pike的Go语言课程[幻灯片](https://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15440-f11/go/doc/GoCourseDay1.pdf)。当时我正经受着C语言内存管理、线程调度和跨平台运行等问题的折磨看到Go语言的语法清新简洁还支持内存垃圾回收、原生支持并发便一见钟情。
我是个对编程语言非常“挑剔”的人,这跟我从事的方向有关。十多年来,我一直在电信领域从事高并发、高性能、大容量的网关类平台服务端的开发,这两年也进入了智能网联汽车行业。由于长期从事后端服务开发,我涉猎过很多后端编程语言。
我曾深入研究过C++短暂研究过Java、Ruby、Erlang、Haskell与Common Lisp但都因为复杂度、耗资源、性能不够、不适用于大规模生产等种种原因放弃了。
而且如果你对我所在的行业有所了解你可能会知道我参与开发的系统对性能十分敏感。我也曾长期使用C语言作为生产语言同时使用Python开发各种辅助工具。但是C语言的生产效率不高各种陷阱也很多而Python开发效率确实很高但性能又不好。
**难道就没有一门相对“完美”、符合我使用需求的编程语言吗这个时候Go来了。**
但在我开始接触和学习Go的2011年Go语言还未发布Go 1.0稳定版本还处于“周发布weekly release”的状态。我还记得我接触的第一个Go版本还是[release.r60](https://github.com/golang/go/tree/release-branch.r60)也就比Rob Pike的Go课程里使用的版本稍新一些。
但这个时候的Go版本存在着很多不尽如人意的地方尤其是GC延迟比较大成为了Go语言上生产环境的最大障碍。
虽然Go早期版本无法上生产环境但我却一直紧跟Go语言的演化进程。
从[Go 1.4版本](https://tonybai.com/2014/11/04/some-changes-in-go-1-4/)开始每当Go发布一个大版本我都撰文分析这个大版本中Go语言的主要变化。这一系列文章至今仍在继续未来也将持续进行下去。
特别是在 Go 1.5版本实现自举、Go 1.11版本解决Go包依赖问题后Go语言逐渐成熟我也逐渐尝试在生产中使用Go。从开始替代Python编写一些辅助工具到编写一些网关所需的网络协议我发现Go都可以完美适用。
一直到近些年Go替代了C、Python成为了我的第一生产语言。我开始直接使用Go编写生产系统诸如短信网关、5G消息网关、MQTT网关还有API网关等等。事实证明Go语言不仅生产效率高其应用的执行效率也完全能满足要求。
从2019年开始我将自己每天阅读到的Go社区的优秀技术资料整理成公开的[Gopher日报](https://github.com/bigwhite/gopherdaily)供大家参阅。在国内Go社区中Gopher日报得到了圈里许多同学的欢迎。
紧跟Go演进十年的我已经将Go语言的点点滴滴深深地烙印在大脑中。
## 推荐你入坑Go的三大理由
如果说十年前的我是因为“一见钟情”瞬间入坑Go那么在十年后的今天我们应该做的是系统地、认真地思考一下为什么要选择学习Go。
我想了想我会从这三个角度建议你现在开始学习Go语言。
**第一个理由:对初学者足够友善,能够快速上手。**
十多年来,业界都公认:**Go是一种非常简单的语言**。到底有多简单呢在2011年我从一个C语言程序员的身份开始学习Go使用Rob Pike的Go教程我在一天之内就学完了Go的全部语法一周内就可以编写一些简单、实用而且质量不低的小程序了。
而且跟现在很多逐渐添加各种特性的语言相比Go不仅一开始简单直到现在也都保持“简单”。Go的设计者们在发布Go 1.0版本和兼容性规范后似乎就把主要精力放在精心打磨Go的实现、改进语言周边工具链还有提升Go开发者体验上了。演化了十多年Go新增的语言特性也同样是“屈指可数”。
正因为如此,**作为静态编程语言的Go已经将入门门槛降低到和动态语言一个水平线上了。**
**第二个理由:生产力与性能的最佳结合。**
Go的简单和对初学者的友善可以让更多的开发者走进Go语言大门但要让更多开发者留在Go语言世界Go还需体现出自己的核心竞争力。这个核心竞争力就是**Go语言是生产力与性能的最佳结合**。
如果你熟悉的是静态语言那你刚好就是Go最初的目标用户。Go创建的最初目的就是构建流行的、高性能的服务器端编程语言用以替代当时在这个领域使用较多的Java和C++。而且Go也实现了它的这个目标。
Go语言的性能在带有GC和运行时的语言中名列前茅与不带GC的静态编程语言比如C/C++之间也没有数量级的差距。在各大基准测试网站上在相同的资源消耗水平的前提下Go的性能虽然低于C++但高出Java不少。
如果你熟悉的是动态语言那也完全不用担心。Go的大部分早期采用者就来自动态语言程序员群体包括Python、JavaScript、Ruby和PHP等语言的使用群体。因为和动态语言相比Go能够在保持生产力的同时大幅度提高性能。比如全球知名的非营利教育组织可汗学院从2019年末开始就将其在线教育平台的实现[从Python迁移到了Go](https://blog.khanacademy.org/half-a-million-lines-of-go/)。虽然Go代码行数要多于Python但他们收获了近10倍的性能提升。
如果你立志或者已经上手云开发那你就更应该马上开始学习Go语言。现在Go已经成为了云基础架构语言它在云原生基础设施、中间件与云服务领域大放异彩。同时GO在DevOps/SRE、区块链、命令行交互程序CLI、Web服务还有数据处理等方面也有大量拥趸我们甚至可以看到Go在微控制器、机器人、游戏领域也有广泛应用。
**第三个理由:快乐又有“钱景”。**
Go最初的目标就是重新为开发人员带来快乐。这个快乐来自哪里呢相比C/C++甚至是Java来说Go在开发体验上的确有很大提升。笼统来说这个提升来自于简单的语法、得心应手的工具链、丰富和健壮的标准库还有生产力与性能的完美结合、免除内存管理的心智负担对并发设计的原生支持等等。而这些良好的体验恰恰是你写Go代码时的快乐源泉。
当然了我相信你学习和使用Go肯定不是为了自嗨。运用Go体现自身价值赢得理想职位才是最终目标。在十年后的今天无论是在国内还是国外无论是在大厂还是初创小公司Go都有着广泛的应用。Go语言人才越来越抢手对他们的争夺也日益激烈。
有报告表明在腾讯、字节跳动、Uber等许多公司Go都是极其受欢迎在字节跳动、Uber内部甚至已经成长为主力语言。
更何况相对于C、C++以及Java等主流语言Go语言人才目前仍处于蓝海阶段。根据[stackoverflow 2021调查报告](https://insights.stackoverflow.com/survey/2021)的结果仅考虑主流语言的话Go语言平均薪水位于头部位置。
![图片](https://static001.geekbang.org/resource/image/64/da/649823d58098499226bdc8d0058103da.png?wh=1694x1300)
这还仅仅是以欧美开发人员调查数据为主的计算结果。在Go更加火爆的国内Go的平均薪水水平位次可能还要更高。
## 怎样学才能少走弯路?
看到Go语言对初学者如此友好又是生产力与性能结合得最好的语言写起来还能体会到快乐。关键是当前国内外互联网大厂、初创小厂也都广泛接纳并应用Go就业“钱景”极佳很多人都纷纷投身于Go语言的学习中但是盲目的“一头热”只会让你多走许多弯路。
我总结了一下,最常见的无非就是这几个:
* “入错行”,从开始到放弃。如果你在最开始缺乏对这门语言的认真评估,盲目投入进去,后期沉没的时间和精力成本都会巨大;
* 不动手。语言学习不是“纸上谈兵”,要动手去用,并且动手越早效果越好;
* 用其他编程语言思维编写Go代码。我认为每门编程语言都有着自己独特的编程思维方式如果你用其他编程语言的思维方式去写Go代码那只能“形神皆丧”无法掌握语言真谛
* 没有建立起“设计意识”。编程语言学习的最终目的是写出具有现实实用意义的程序所以你要培养自己选择适当的语言元素构造程序骨架的能力也就是“设计意识”。尤其是要弄清楚不同语言元素所在的层次不然你只能停留在“Hello, World”的世界里。
那么我们到底要怎么学才能学好Go呢
学好Go的前提是能坚持学下去。而要保证持续学下去做好Go入门学习就至关重要。入门学习就好比一座在建大厦的地基只有地基坚实、稳固大厦才可能迎来建成并耸立云霄的那天。
那么如何做好入门学习呢?这里告诉你**三个诀窍与五个阶段**。所谓三个诀窍是“**心定、手勤、脑勤”**。什么意思呢?我将这个入门课的学习分为下面五个阶段,我会结合这五个阶段来和你说明这三个诀窍。
**第一个阶段:前置篇,“心定”建立认同感。**
这一部分我会带你了解Go的前世今生和设计哲学。如果你是有其他语言编程经验的开发人员你就更应该完成前置篇的学习了。
这一部分存在的意义就是让你“心定”。所谓“心定”就是为了建立对Go语言的认同感。这种认同感是全方位的包括对Go语言的设计目标、设计哲学、演化思路还有社区行为规范等等。只有“心定”才能避免出现“Hello-and-Bye”的情况这是学好Go的前提。
**第二个阶段:入门篇,“手勤”多动手实践。**
在这一部分中我将告诉你在不同平台上安装各种Go版本的方法带你了解一个Go程序应该长什么模样看看一些实用Go程序都有哪些语法元素和结构。关于Go的版本如果我在课程中没有特地说明那便默认使用的是Go最新的稳定版本这里请你注意下。
编程不是“纸上谈兵”。我们最终都是要将编写完的源码提交给计算机编译运行的,因此,我希望你在这部分多动手、多实践。我在入门篇中将会让你拥有“照猫画虎”的能力。只有拥有这种能力,你才能“随心所欲”地动手实践。
**第三个阶段:基础篇,“脑勤”多理解,夯实基础。**
这一部分,我们会围绕着“程序=数据+算法”的逻辑从变量、常量等基本概念到数据类型再到广义的算法让你可以用Go建立对现实世界的抽象认知也能明白Go程序运行的基本逻辑。
在基础篇的结尾,我们会结合已学习的基础语法做一个小练习项目。实践与理论的结合才能达到更好的学习效果。
**第四个阶段:核心篇,“脑勤+”建立自己的Go应用设计意识。**
在这部分我会跟你介绍Go语言独有或经过较大创新的接口类型与goroutine等并发原语类型这些语法元素是Go语言的核心。
Go接口与Goroutine等并发原语类型有一个共同的特点那就是它们都是可以影响到Go应用程序的结构设计的语法元素。Goroutine等并发原语是Go应用运行时并发设计的基础而接口则是Go推崇的面向组合设计的抓手这一动一静共同构成了Go应用程序的骨架。通过这一部分你就能建立自己的Go应用“设计意识”。
**第五个阶段实战篇攻克Go开发的“最后一公里”。**
编程就是要做到学以致用。在掌握了Go语言的基础语法、核心语法并建立起自己的“设计意识”后我们就是时候应用这些Go语言的特性来解决实际问题了。
在这部分中我们将通过一个实战的例子展示如何做好学习与使用之间的衔接帮助你走完“使用Go进行生产级开发”这“最后一公里”。
![图片](https://static001.geekbang.org/resource/image/fc/9d/fcf857acac0ec2512de6f9dd77b1a69d.jpg?wh=1920x1080)
更具体的目录,我也放在了这里,你可以看一下:
![](https://static001.geekbang.org/resource/image/61/2e/611962c4a98776cf9c79010ab189552e.jpg?wh=1563x8650)
在开篇词的最后我想说Go是一门非常优秀的后端编程语言它简单而不失表达力兼具高生产力与战斗力高性能。它既能给你带去编码的快乐也能因市场的广泛接受与热捧而提升你的个人价值。
所以我衷心地希望你能完成这门课程的学习。希望我的这门课能帮助你将Go语言之路走得更顺畅早日成长为一名优秀的Go语言开发工程师。
不要再犹豫了来和我一起开启Go语言的学习之旅吧。