上图表示了go的应用领域,包括容器如k8s, 服务发现如consul,kv存储如etcd,中间件如codis, 存储如minio,分布式数据库tidb,此外还有devops、区块链、人工智能、web框架、微服务等等领域的应用。
相比C++和java, Go语言更年轻,他存在的意义何在呢?
1)在计算领域,是C/C++的天下,因为执行效率高,但缺点是开发和编译效率低。
2)对于Java,虽然编译速度快、开发效率高,但执行效率不如C/C++。
3)而动态语言如Python,由于没有强类型约束,很多问题需要在运行时发现:这种低级错误由编译器来发现更好些。
综上,期待出现一种语言来解决上述语言的缺点,Go语言这时出现,它易于开发、快速编译、高效执行。
Go语言起源于2007年,由google 2009年发布。
Go编译后的代码,运行速度可媲美C/C++,且编译速度更快,因此风靡全球,被称为21世纪的C语言(Go不仅具备C的性能与安全,且提供了21世纪互联网环境下服务端开发的各种使用特性)
Go语言的设计哲学是:简单、实用。
Go语言是对类C语言的重大改进,它可以访问底层操作系统,还提供了强大的网络编程和并发编程的支持。Go语言可进行网络编程、系统编程、并发编程、分布式编程。
1)并发场景性能快
2)静态的语言:没有面向对象中的“类”
3)支持自动垃圾回收
4)编译型语言:编译速度快
Go遵循简洁编程原则:
1)它没有隐式的数值转换
2)没有构造函数和析构函数
3)没有运算符重载
4)没有默认参数
5)也没有继承
6)没有泛型
7)没有异常
8)没有宏
9)没有函数修饰
10)更没有线程局部存储
Go承诺保证向后兼容:
用之前的Go语言编写程序可以用新版本的Go语言编译器和标准库直接构建而不需要修改代码
Go语言支持交叉编译,即可以在Linux系统上开发基于Windows上运行的程序,因为这是一门完全支持UTF-8的语言,不仅体现在他可以处理使用UTF-8编码的字符串,就连他的源码稳居格式都是使用UTF-8编码。
2.2、Go是编译型语言Go代码在运行前,需要使用编译器来编译代码,编译器将源代码编译成二进制(或字节码)格式;在编译代码时,编译器会做错误检查、性能优化,然后输出可在不同平台上运行的二进制文件。
要运行Go程序,需要的步骤:
1)使用文本编辑器写Go代码
2)编译程序
3)运行编译后得到的可执行文件。
这与Python, Javascript等语言不同,Go自带了编译器。
2.3、Go语言的特性 1、语法简单Go语法与C类似,但没有C那些隐秘晦涩的规则,Go语法简单严谨,无歧义。
2、并发模型Go引入了携程Goroutine,从根本上将一切都并发化,运行时用goroutine运行所有的一切,包括main.main入口函数。
Goroutine用类携程的方式来处理并发单元,却又在运行时层面做了更深度的优化处理。但语法上的并发编程变得极为简单,无需处理回调,无需关注现场切换。
goroutine搭配channel,实现CSP模型。将并发单元间的数据耦合拆解开来,各司其职。这样对所有纠结于内存共享、锁粒度的程序员都是一种解脱。
3、内存分配将一起并发化虽然好,但也带来了新问题,即如何实现高并发下内存的分配和管理。Go选择了tcmalloc,他本就是为了并发儿设计的高性能内存分配组件。
去除因配合垃圾回收而修改的内容,内存分配器完整保留了tcmailoc的原始架构。使用cache为当前线程提供无锁分配,多个central在不同线程间平衡内存单元复用。在更高层次里,heap管理大块内存分配,用以切分成不同等级的复用内存块。快速分配和二级平衡机制,让内存分配器能优秀地完成高压力下的内存管理任务。
除了偶尔因性能问题而被迫采用对象池和自主内存管理外,我们基本无需参与内存管理操作。
4、垃圾回收相比Java, Go的垃圾回收面临的困难更多,因为指针的存在。幸好,指针运算被阻止,否则要做到精确回收都难。
每次版本升级,垃圾回收期都是核心组件里修改最多的部分,从并发清理,到降低STW的时间,直到Go的1.5版本实现并发标记,逐步引入三色标记和写屏障等,都是为了能让垃圾回收在不影响用户逻辑的情况下更好地工作。但当前最新版本的垃圾回收算法也只能说堪用,距离好用还有不少距离。
静态链接,只需编译后的一个可执行文件(将运行时、依赖库直接打包到可执行文件内部),无需附加任何东西,就能部署。这种简单的方式对于编写系统软件有极大好处,无需实现安装运行环境和下载各种第三方库。
6、标准库Go的标准库算比较丰富,其中值得称道的事net/http,仅需要简单的几条语句,就能实现一个高性能的web server,大批基于此的优秀第三方Framework更将Go推到了Web/微服务 开发标准之一的位置。
7、工具链完整的工具链对日常开发极有帮助,Go的工具链做的不错,无论是编译、格式化、错误检查、帮助文档,还是第三方包的下载、更新,都有对应的工具。虽然这些工具算不上多完善,但简单易用。
Go内置的测试框架,其中包括单元测试、性能测试、代码覆盖率、数据竞争,及用来调优的pprof,都是包子代码正确与稳定运行的必备利器。
此外,还可通过环境变量输出运行时的监控信息,尤其是垃圾回收和并发调度跟踪,可进一步帮助我们改善算法,获得最佳的运行期表现。
2.4、Go语言为并发而生Go语言的祖先C语言的指令都是串行执行,即同一时刻仅有一个指令在使用CPU。
随着多核处理器的发展,一些语言框架(如Java Netty)也在致力于提高多核CPU使用效率,但仍需要开发人员花精力去搞懂这些框架的原理及使用方法。
Go语言是在多核和网络化时代诞生的语言,天生就从底层支持并发,无需第三方库,程序员可以在写程序时很轻松地指定怎样使用CPU资源。
Go的并发,基于goroutine,可以将goroutine理解为一种虚拟线程。Go语言运行时会参与调度goroutine,并将goroutine合理地分配到每个CPU中,最大限度地使用CPU性能。
多个goroutine之间,通过使用channel通信,channel是一种内置的数据结构,可以让用户在不同的goroutine之间同步发送具有类型的消息。这种编程模型更倾向于在goroutine之间发送消息,而不是让多个goroutine争夺同一个数据的使用权。



