2017 年可以说是 Go 在云计算取得了领导地位,kubernetes 已经成为了所有云计算公司的底层架构,而且越来越多的互联网公司系统架构迁移到 k8s 上面,例如 github、阿里、腾讯、百度、滴滴、京东等大型企业纷纷拥抱,而这个系统就是 Go 开发的,很多公司都开始大力的投入工程师在 Go 开发中来,Go 一下子就成为了云计算的核心语言,大家应该都听过一个组织叫做 CNCF,云计算基金会组织,下面孵化了一堆的云计算项目,https://www.cncf.io/ 就可以看到基本上 90% 的项目都是 Go 语言开发的,从这个我们可以看出来 Go 已经成为了名副其实的云计算系统语言。
同时又是 Go 在第二领域开始发力的一年,我所说的第二领域就是区块链,大家都知道比特币在过去一年可以说迅速的火爆全球,而它的底层技术区块链技术也是开始获得大家的认知,这个可以说是区块链 1.0 版本应用,而区块链 2.0 版本应用就是智能合约以太坊开始获得所有人的认知,基本上目前大多数做区块链的公司都是基于以太坊进行二次开发,而以太坊的底层正是 Go 开发的,同时 IBM 也开源了他们的 fabric,Fabric 是一个分布式账本平台方案,主要用于运行智能合约,利用可靠的技术以及可插拔方式实现各种商业应用场景的模块化架构,而且这个系统也是 Go 开发的,这两个区块链里面的明星项目都是用 Go 开发的,足以说明 Go 在分布式系统中的地位,这也就是为什么今年开始大批量的金融公司开始招聘 Go 工程师。
最近两个大版本分别是 Go1.9 和 Go1.10,我就对于这两个版本里面带来的几个新特性大概的介绍一下。
语言层面
Type alias
我们都知道 Go 代码重构过程中最大的难点就是兼容性,而 Go 里面我们一旦导出的变量、函数等如果想要再次重构,那么就会变得非常困难,这个特性的引入就是为了解决这个问题的,最初由 Robert Griesemer 提出来这个特性的,计划在 1.8 版本加入,但是时间紧迫推迟到了 1.9 版本才加入。
官方对 type alias 的定义非常简单:
An alias declaration binds an identifier to the given type.
我们怎么来理解新增的 type alias 和传统的 type definition 的区别呢?
type T1 T2 // 传统的类型定义 vs.type T1 = T2 // 新增的类型化名
把握住一点:传统的类型定义创造了一个“新类型”,而类型化名并没有创造出“新类型”。
性能优化
编译性能
在 Go 1.9 中,在原先的支持包级别的并行编译的基础上又实现了包函数级别的并行编译,以更为充分地利用多核资源。Go 1.10 的编译性能最大的改变在于 cache 机制的实现。事实证明 cache 机制的使用,在日常开发过程中会很大程度上提升你的工作效率,越是规模较大的项目越是如此。
目标代码的性能
这些年 Go team 在不断优化编译器生成的目标代码的性能,比如在 Go 1.7 版本中引入 ssa 后端。Go 1.10 延续着对目标代码生成的进一步优化,虽说动作远不如引入 ssa 这么大。
GC 性能
GC 的性能一直是广大 Gopher 密切关注的事情,在 Go 1.9 中依旧继续优化和改善,大多数程序使用 1.9 编译后都能得到一定程度的性能提升。1.9 中尤其提到了大内存对象分配性能的显著提升。Go 1.10 在减少内存分配延迟以及 GC 运行时的负担两个方面做了许多工作,但从整体上来看,GC 变化不是很大。
标准库
增加 monotonic clock 支持
2017 年元旦之夜,史上第 27 次闰秒出现,正是因为这个闰秒的出现,欧美知名 CDN 服务商 Cloudflare 的 DNS 出现大规模故障,导致欧美很多网站无法正常被访问。之后,Cloudflare 工程师分析了问题原因,罪魁祸首就在于 golang time.Now().Sub 对时间的度量仅使用了 wall clock,而没有使用 monotonic clock,导致返回负值。一般来说,wall clock 仅用来告知时间,mnontonic clock 才是用来度量时间流逝的。为了从根本上解决问题,Go 1.9 在 time 包中实现了用 monotonic clock 来度量 time 流逝,这以后不会出现时间的“负流逝”问题了。这个改动不会影响到目前大家对 timer 包的方法层面上的使用。
增加 math/bits 包
在一些算法编程中,经常涉及到对 bit 位的操作。Go 1.9 提供了高性能 math/bits package 应对这个问题。
提供了一个支持并发的 Map 类型
Go 原生的 map 不是 goroutine-safe 的,尽管在之前的版本中陆续加入了对 map 并发的检测和提醒,但 gopher 一旦需要并发 map 时,还需要自行去实现。在 Go 1.9 中,标准库提供了一个支持并发的 Map 类型:sync.Map
增加 strings.Builder
strings 包增加一个新的类型:Builder,用于在“拼字符串”场景中替代 bytes.Buffer,由于使用了一些 unsafe 包的黑科技,在用户调用 Builder.String() 返回最终拼成的字符串时,避免了一些重复的、不必要的内存 copy,提升了处理性能,优化了内存分配。
支持 profiler labels
通用的 profiler 有时并不能完全满足需求,我们时常需要沿着“业务相关”的执行路径去 Profile。Go 1.9 在 runtime/pprof 包、go tool pprof 工具增加了对 label 的支持。Go team 成员 rakyll 有一篇文章“Profiler labels in go”详细介绍了 profiler labels 的用法,可以参考,这里不赘述了。
目前使用 Golang 的国内国外公司都非常之多,我这边大概的列一下主要的公司
国外公司列表
国内公司列表
更多的公司可以参考这里:https://github.com/golang/go/wiki/GoUsers
目前 Go 里面开源的大项目太多了,大家可以参考我们最近做的知识图谱上面的一些开源项目,包含了云计算、devops、区块链、人工智能、游戏、存储引擎、Web、系统 / 命令行工具、中间件、测试 / 持续交付、文件系统等各方面的开源项目。
详细地址:https://www.processon.com/view/link/5a9ba4c8e4b0a9d22eb3bdf0
我觉得学习一门语言最重要的就是做到三点,第一看基础知识,第二学习抄代码,第三学习写代码
第一点,很多人都觉得上来就动手写,但是你基础的东西都没掌握,怎么写呢?欲速则不达,所以基础的东西还是必须要先掌握好。这里推荐几个基础的入门材料:
-
https://tour.golang.org/#1
-
邢星翻译的 https://github.com/mikespook/Learning-Go-zh-cn
-
Go byExample https://gobyexample.com/
我觉得你把这几个基础掌握之后就可以开始抄袭代码了, 如果你之前有 PHP 的开发经验, 那么也许我写的这本书对你了解 golang 有帮助, https://github.com/astaxie/build-web-application-with-golang
第二点,我们很多时候开始写代码都是没什么思路,也无从下手,但是我们可以模仿别人写代码,上海俗话里面常说"吃大户,用大户,消灭大户",我们就是"看代码,抄代码,最后自己写代码"。这里给你几个入门级别的代码看看学习一下:
-
https://github.com/hoisie/web 很简单,就是学习他的路由怎么实现的,如何编写自己的路由
-
https://github.com/icub3d/home/ 这是一个 Go+ AngularJS 的实现,看看如何做 API 应用
最后我列一下你可以自己参考去实现的一些功能,我当初培训我们战虎班的同学就是用这些来一起学习的。
-
日志分析
-
IP 库分析
-
管理后台查看分析日志
第三点,自己写代码,这个时候就是已经对 golang 有了一定的了解了,那么我们就可以开始做自己的项目了,做项目最想就是快速开发, 那么我就推荐你
-
https://github.com/astaxie/beego 使用 beego 框架可以很快速的开发你的 Web 或者 API 应用
-
https://www.docker.com/ 使用 docker 来做虚拟化
-
https://github.com/nsqio/nsq 学习消息队列,学习 channel 和分布式
-
https://github.com/coreos/etcd 分布式应用
这个阶段就是找各种东西用 golang 来写,多写就会理解越来越深入。
第四届 Gopher China 大会 4 月将在上海举办,今年第一次增加了会前的 Workshop 。本届大会从规模到内容将创历史新高,并继续赠送 GoPher 限量 T 恤。动心了,快戳省钱秘籍:
点击阅读原文报名大会,输入优惠码【Geekbang】,八五折优惠等着你!
文章评论