深入理解Go语言
上QQ阅读APP看书,第一时间看更新

前言

感谢阅读本书。

Go语言起源于2007年,在一次技术会议中,谷歌公司的技术工程师讨论了C++语言是否能带来新特性的问题。

“与其在臃肿的语言上不断增加新的特性,不如简化编程语言”成为大家讨论后一致认为要改进的问题。于是由罗布·派克(Rob Pike)、肯·汤普逊(Ken Thompson)、罗伯特·格瑞史莫(Robert Griesemer)领军的团队开始对Go语言进行了创作和研发。

直到2009年,Go语言正式开源了。Go项目团队将2009年11月10日(Go语言正式对外开源的日期)作为其官方生日。

但是Go语言一直都不被开发者重点关注,只有一些少数热衷Go语言的开发者或社区在默默地推动Go语言,提高其的市场份额。直到2013年Docker公开在PyCon上问世,持续到2016年前后,容器化的概念和技术才火热推进和产研升级。众人才得知,如此优秀的虚拟化容器居然完全用Go语言开发。2016年借着Docker之势,Go语言才真正被广大开发者关注。

为什么写本书

Go语言至今已经被广大开发者所青睐。Go语言极简单的部署方式(可直接编译出机器代码,除了C标准操作系统库几乎不依赖任何系统库,直接运行即可部署)、优秀的编译速度、“基因”层面的并发支持、强大的标准库支撑、极低的开发成本、简单易学、跨平台等特性深深地打动了每位接触过Go语言的后端开发工程师。

从Docker的兴起,至第二波Kubernetes的冲击(Kubernetes也主要由Go语言开发),让Go语言在后端的地位,尤其在偏中高级业务需求(对性能、代码质量、架构设计等)中已经不可撼动。后端开发工程师逐渐开始对Go语言产生敬畏,无论是擅长何种语言的后端工程师,都有必要了解一下Go语言。

对于C++工程师,他们喜欢Go语言的简洁与优雅,而不失性能的威力;对于Python工程师,在Web等高并发服务场景下,当遇见寸步难行的流量并发压力时,Python工程师更希望在Go语言的高速公路上畅通驾驶。

笔者从2016年开始接触Go语言,作为一名曾经主要使用C与C++的开发者,遇见Go语言的时候,有种“如获珍宝”的感觉。Go语言打动笔者的关键点就是它像极了C,优美而庄严!

Go语言就像一辆自动挡的高端型号汽车,不仅性能好,操作还简单。对于常年开高端手动挡C语言汽车的“司机”来讲,Go语言无疑让笔者爱不释手。

Go语言在云计算基础设施领域(Docker、Kubernetes、Etcd、Consul等)、基础后端软件领域(TiDB、influxDB、Cockroachdb等)、微服务领域(go-kit、micro等)、互联网基础设施领域(以太坊、HyperLedger、P2P等)均表现得非常突出。笔者也在企业中用Go语言创作且实现了互联网场景下数据中心系统、数据实时修复监控系统、链路追踪系统等。

本书针对Go语言学习道路上一些需要去深挖和应理解透彻的点进行详细讲解,这些点并非一定会在日常开发中用上,它们可能仅仅会让我们更加了解Go语言,也可能让我们知道为什么要用Go语言开发。也许每天陪你的语言伙伴——Go语言,它帮助你实现了天马行空的设计与思想,但你可能一直并没有去真正了解过它,仔细阅读本书,去真正了解常年陪伴你的伙伴吧!

本书主要面向的读者

本书针对Go语言在技术领域中的热门专题进行深入分析与讲解,采用丰富的图文描述形式,深入浅出且连贯地讲解各知识点。本书适合对Go语言有深入理解需求的读者,也适合由其他编程语言转职Go语言的开发者,是理解Go语言原理、关键技术点等知识体系构建的捷径之路。

本书主要面向的读者是已经具有软件编程开发经验的工程师、系统开发工程师、期望(由Python、PHP、C/C++、Ruby、Java等编程语言)转职到Go语言开发的后端工程师、期望深入理解Go语言特性的计算机软件学者等。

本书的目的是以最容易理解的方式介绍Go语言运作原理,让读者通过一个形象的轮廓理解Go语言更深层次的概念并以此感受它的魅力。Go语言领域有很多源码分析类书籍、语法精髓类书籍、设计方法类书籍等,但是如果要深入理解这些理论需读者用较长的时间去精读与沉淀,并且可能印象不深刻,一些关键性技术和原理也极容易被忘记。本书的每个章节专题所描述的知识点和知识点之间具备流畅的衔接,遵循知识点吸收的三步法:“为什么这样”“这样会如何”“所以才这样”的抽象编写架构。

如果学会了本书的全部理论且亲自实现了本书第三篇从0到1构建服务器框架程序,你将开始成为Go语言领域极少数的“牛人”,这些“牛人”不仅了解Go语言特性及其底层运作原理,并且知道自己如何去开发一套服务程序框架。同时,也要做好更深入探究的准备,本书虽然图文描述丰富,初识概念在脑海中建立模型较快,但本书也牺牲了烦琐的源码类解读,更有耐心且喜欢深究的读者建议配合Go语言源代码讲解或其他讲解源码类的书籍阅读,效果则会更佳。

本书读者应具备的背景知识

希望你对C和C++有一定的了解。如果你以前只有Java、Python和PHP编程经验,则可能需要付出较多的努力来完成这种转换,不过本书也会帮助你。编程语言的语法层面均类似,不过一些C语言的内容,特别是指针、显示的内存分配等,其他语言(如Java、PHP)是没有的。所幸的是C语言是一门简单、基础的语言,无论你的编程背景如何,都应该考虑去学一学C语言。

如果你想更流畅地阅读本书,则需要具备一定的后端开发功底,包括基础的Linux操作系统知识(如常用的Linux指令、操作系统文件特性、常用系统编程等)、对网络知识有一定的了解、掌握Socket编程及常见网络协议等。本书的一些章节为了更好地打好Go语言知识底层基础,会引入一些Linux的系统编程接口,这些接口多数是Linux原生的C语言接口,虽然不会妨碍阅读和理解,但是具备相关知识可能让你理解和吸收得更多。

你也要具备使用代码版本控制工具(如Git)的能力,在本书第三篇“Go语言框架设计之路”中强烈建议跟着书中的代码一步一步通过代码版本控制工具迭代开发且提交代码练习。这样在完成本书的全部内容后,就可以基于自己的源代码仓库去二次开发适合自己业务场景的框架,在完成本书的阅读后,也可以拥有一套属于自己的开源项目和框架。

本书概述

本书由3篇共21章组成,前半部分多为Go语言理论精髓,后半部分为框架实战。

第一篇包括第1~4章,是本书的重点章节,主要讲解Go语言开发工程师必备的知识。

第1章深入理解Go语言协程调度器GPM模型,形象介绍GPM模型的各个触发条件及运作的场景。

第2章Go语言混合写屏障的GC全场景分析,主要以推演的形式逐一介绍Go语言垃圾回收的处理机制。

第3章Go语言内存管理洗髓经,详细讲解内存管理的模型,一站式学习虚拟内存到TCMalloc再到Go语言的堆内存管理模型机制。

第4章深入理解Linux网络I/O复用并发模型,介绍服务器端对于网络并发模型及Linux系统下常见的网络I/O复用并发模型。

第二篇包括第5~12章,内容为Go语言学习中比较热门的知识点,也是深入理解Go语言编程的语言特性的进阶相关领域知识。

第5章有关Goroutine无限创建的分析,在基于控制Goroutine办法的基础上,实现协程Worker工作池的设计。

第6章Go语言中的逃逸现象,变量“何时在栈、何时在堆”,主要对Go语言逃逸现象进行分析。

第7章interface剖析与Go语言中面向对象思想,主要讲解interface关键字与interface{}类型内部剖析。

第8章defer践行中必备的要领,详细地罗列在defer的一些使用场景中所涉及的细节问题和案例代码分析。

第9章Go语言中常用的问题及性能调试实践方法。

第10章make和new的原理性区别,介绍make和new在使用过程中需要注意的地方,并结合一些代码场景分析,罗列出如果错误地使用二者将会带来哪些问题。

第11章精通Go Modules项目依赖管理,介绍Go Modules的一些管理方法。

第12章ACID、CAP、BASE的分布式理论推进,介绍ACID、CAP、BASE理论的演进过程。

第三篇包括第13~21章,内容为项目实战,基于Go语言的基础理论知识,从0到1地构建并设计实现Go语言的基于TCP/IP的网络服务器框架。Go语言目前在服务器的应用框架很多,但是应用在游戏领域或者其他长连接领域的轻量级企业框架甚少。笔者设计Zinx框架的目的是通过Zinx框架了解基于Go语言编写一个TCP服务器的整体轮廓,让更多的Go语言爱好者能深入浅出地学习和认识这个领域。

Zinx框架曾获得“GVP——码云最有价值开源项目”荣誉,如图1所示。

图1 “GVP——码云最有价值开源项目”荣誉

第13~21章的内容概述如下:

第13章Zinx框架基础服务构建。

第14章Zinx框架路由模块设计与实现。

第15章Zinx全局配置。

第16章Zinx消息封装模块设计与实现,包括创建消息封装类型、消息的封包与拆包等的描述。

第17章Zinx多路由模式设计与实现,包括创建消息管理模块与多路由方式的设计与实现。

第18章Zinx读写分离模型构建。

第19章Zinx消息队列和任务工作池设计与实现,包括消息队列的创建、Worker工作池的启动、消息队列管理等模块的设计和实现。

第20章Zinx连接管理及属性设置,包括Zinx连接管理模块的创建、连接启动/停止自定义Hook方法的注册、连接配置接口等相关模块的设计与实现。

第21章基于Zinx框架的应用项目案例。

致谢

在此衷心感谢那些给我中肯的批评和鼓励的众多朋友及伙伴。

感谢早期为我提供发表文章的几大Go语言国内社区:Go语言中文网、GoCN、LeranKu、语雀、简书、知乎、GitBook、看云、博学谷等内容平台,能够让本书中早期的雏形文章广为传播,让更多的Go语言开发爱好者可以学习且提供平台分享和讨论。

特别感谢为Zinx提供创作且早期帮助Zinx维护的Go语言技术同道。感谢张超(GitHub:@zhngcho)对Zinx最早版本的代码构建。感谢刘洋(GitHub:@marklion)同步创作C++版本Zinx。感谢胡琪(GitHub:@huqitt)提供的Lua版本Zinx。感谢胡贵建(GitHub:@huguijian)提供的WebSocket版本Zinx。感谢Zinx开发小组负责维护建设的其他几位伙伴:张继瑀(GitHub:@kstwoak)、高智辉(GitHub:@adsian)、辜飞俊(GitHub:@gufeijun)、翼飞虎(GitHub:@JiBadBoy)、杜家辉(GitHub:@graydovee),同时感谢所有为Zinx做出贡献的人。

感谢开源中国(OSChina)对Zinx开源项目的收录和早期的平台推荐。感谢红薯老师对优良开源作品的认可和大力支持。

感谢所有对本书内容提出过勘误的目光锐利的读者,也感谢给我提出建议和改进的读者。

感谢最早期学习Zinx的学生们,他们提出了很多宝贵的反馈意见。特别感谢杜旭老师多次课堂上的教学。

感谢因学习本书内容而汇聚在一起的技术讨论社区的日常运营管理志愿者张继瑀(网名:熊猫№.47)、谢心怡两位伙伴。

感谢清华大学出版社所有为本书顺利出版而付出努力的工作人员,尤其感谢赵佳霓编辑早期不懈的支持,对文稿的校验和正文内容结构的严谨调整。

致谢早期支持我网络博客作品且认真阅读的伙伴及技术同仁,感谢你们前期的阅读支持和提出的一些宝贵建议。

感谢我的家人,包括我的妻子王雪、我的儿子刘今煜,感谢他们愿意每天给我时间让我完成这部作品,没有他们的强烈支持,我可能也没有充足的业余时间让本书落地。

最后致正在阅读本书的读者,遇见本书是你与我的缘分,感谢你阅读至此处,希望你在Go语言的道路上越来越好!

谢谢为本书付出过和帮助过我的所有人。

刘丹冰(Aceld)

2022年11月于北京