Go学习圣经:0基础精通GO开发与高并发架构

Posted 疯狂创客圈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go学习圣经:0基础精通GO开发与高并发架构相关的知识,希望对你有一定的参考价值。

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 :

免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备
免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,完成职业升级, 薪酬猛涨!加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷1)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷2)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷3)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领

免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取


GO 学习圣经:底层原理和实操

说在前面:

现在拿到offer超级难,甚至连面试电话,一个都搞不到。

尼恩的技术社群中(50+),很多小伙伴凭借 “左手云原生+右手大数据”的绝活,拿到了offer,并且是非常优质的offer,据说年终奖都足足18个月

从Java高薪岗位和就业岗位来看,云原生、K8S、GO 现在对于 高级工程师/架构师来说,越来越重要。尼恩从架构师视角出发,基于自己的尼恩 3高架构师知识体系和知识宇宙,写一本《GO学习圣经》

最终的学习目标

咱们的目标,不仅仅在于 GO 应用编程自由,更在于 GO 架构自由。

前段时间,一个2年小伙伴希望涨薪到18K, 尼恩把GO 语言的项目架构,给他写入了简历,导致他的简历金光闪闪,脱胎换股,完全可以去拿头条、腾讯等30K的offer, 年薪可以直接多 20W

足以说明,GO 架构的含金量。

另外,前面尼恩的云原生是没有涉及GO的,但是,没有GO的云原生是不完整的。

所以, GO语言、GO架构学习完了之后,咱们在去打个回马枪,完成云原生的第二部分: 《Istio + K8S CRD的架构与开发实操》 ,帮助大家彻底穿透云原生。

本文目录

目录

学习 GO 的相关资料:

The Go Programming Language (google.cn)

Dubbo Java 3.1.4 正式发布 | Apache Dubbo

dubbo-go

安装 Dubbo-go 开发环境 | Apache Dubbo

完成一次 RPC 调用 | Apache Dubbo

Go/C/C++/Java四大语言的对比

面向过程C语言

C语言产生的背景主要有以下几个方面:

  1. 软件危机:在20世纪60年代,随着计算机软件规模的扩大,软件设计和开发面临了巨大的挑战。很多软件项目的开发进度缓慢、成本高昂,甚至出现了完全失败的情况。为了解决这个问题,需要一种更加高效、可靠的编程语言。
  2. ALGOL语言的不足:ALGOL语言是20世纪60年代最流行的编程语言之一,但它的表达能力和可读性都不够强。因此,需要一种新的编程语言,既能保留ALGOL的优点,又能增强表达能力和可读性。
  3. UNIX操作系统的出现:在20世纪70年代初,贝尔实验室开发了UNIX操作系统,而操作系统的核心部分就是用C语言编写的。由于C语言效率高、灵活性好,逐渐成为了UNIX操作系统和其他系统软件的首选开发语言。

基于以上原因,Dennis Ritchie在20世纪70年代初开始着手开发C语言,并于1972年正式发布了第一个稳定版本。C语言具有效率高、表达能力强、可移植性好等特点,成为了通用编程语言中非常重要的一种。目前,C语言被广泛用于操作系统、嵌入式系统、程序语言解释器等方面,也是很多编程语言的基础。

到了70年代,诞生了一门非常重要的语言,这就是今天的大名鼎鼎的C语言。而C语言之父是美国著名的计算机专家。丹尼斯.利奇。

目前 C语言是世界上最常用的程序语言之一。

C语言之父:Dennis Ritchie(丹尼斯·里奇)。美国著名计算机专家、C语言发明人、UNIX之父。在1969-1973年期间发明了C语言和Unix操作系统。

面向对象 C++语言

1982年,美国贝尔实验室的Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了—种新的程序语言。为了表达该语言与c语言的渊源关系,它被命名为C++。

C++语言产生的背景主要有以下几个方面:

  1. C语言的问题:C语言是一种高效、灵活的编程语言,但它在类型安全性、模块化和代码复用等方面存在一些问题。因此,Bjarne Stroustrup希望开发一种新的编程语言,在保留C语言的优点基础上解决这些问题。
  2. 面向对象编程的兴起:在20世纪80年代,面向对象编程开始蓬勃发展,Smalltalk、Simula等语言引领了这股潮流。Bjarne Stroustrup希望能开发一种新的编程语言,可以实现面向对象编程。
  3. 硬件性能的提升:在20世纪80年代末和90年代初,计算机硬件性能得到了极大的提升,使得程序员可以使用更加复杂的编程语言来编写程序。因此,Bjarne Stroustrup希望开发一种新的编程语言,可以满足这种需求。

基于以上原因,Bjarne Stroustrup在1983年开始着手开发C++语言,并于1985年正式发布了第一个稳定版本。C++语言结合了C语言的效率和面向对象编程的特性,成为了通用编程语言中非常重要的一种。

C++语言被广泛用于游戏开发、操作系统、大型软件系统等领域,也是很多编程语言的基础。

C++之父:Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)。

Java语言

1995年5月正式Java 发布。java的出现,正是互联网大力兴起的时候,而java因为语言的特性,在互联网上有很大的优势,发布最初就异常火爆。

Java语言产生的背景主要有以下几个方面:

  1. 面向对象编程的兴起:在上世纪80年代末和90年代初,面向对象编程开始逐渐成为主流编程范式,C++等语言受到广泛关注。Sun Microsystems公司希望能开发一种新的、更加高级的面向对象编程语言。
  2. 跨平台需求:在90年代初期,计算机硬件和操作系统环境比较复杂,软件需要针对不同的平台进行编写和调试。Sun Microsystems公司希望能开发一种新的编程语言,可以实现跨平台的编写和运行。
  3. 互联网的出现:互联网的出现让人们开始追求大规模分布式应用程序的开发。Sun Microsystems公司希望能开发一种新的编程语言,能够轻松地构建分布式网络应用程序。

基于以上原因,Sun Microsystems公司在1991年启动了Oak项目(后改名为Java),并于1995年正式发布了第一个稳定版本。Java语言最初被设计用于家电控制器,但随着互联网的发展,Java语言迅速成为网络应用程序的首选开发语言。目前,Java语言已经成为了企业级应用程序开发的主流,广泛应用于金融、电子商务、大数据等多个领域。

java最初的模型是在1991年的时候开发出,他的创始人詹姆斯高斯林。那个时候还叫做Oak橡树,后来詹姆斯希望使用java语言可以像喝咖啡一样轻松,愉悦。改名为java。

Java之父是James Gosling(詹姆斯.高斯林)。

Golang:

Go语言,也被称为Golang,是一种由Google公司开发的静态类型、编译型、并发性强的编程语言。

它最初于2007年由Robert Griesemer、Rob Pike和Ken Thompson等人设计,并于2009年正式发布第一个稳定版本。

Go语言产生的背景主要有以下几个方面:

  1. 并发编程需求:随着计算机性能的提升和互联网应用的普及,越来越多的应用需要具备高并发处理能力。然而,传统的编程语言如C++和Java等,在并发编程方面存在诸多问题。因此,Google公司希望开发一种新的编程语言,可以更好地满足这种需求。
  2. 程序员生产效率:Google公司拥有大量的程序员和代码库,而传统的编程语言复杂度较高,代码量也比较大,导致程序员生产效率不高。因此,Google公司希望开发一种简洁、易于学习和使用的编程语言。
  3. 代码安全性:在编写大型软件系统时,常常会出现缓冲区溢出等安全问题。因此,Google公司希望开发一种新的编程语言,可以避免这些问题。

基于以上原因,Google在2007年启动了Go语言的开发工作。

Go语言的设计者之一Rob Pike表示,Go语言的目标是“使编程更加愉悦和生产力更高”。

经过数年的开发和完善,Go语言逐渐得到广泛应用,并且在某些领域已经成为了首选语言。

Go语言在设计上注重简洁性和性能,目标是提供一种高效、可靠、易于编写和维护的系统级编程语言。它具有以下特点:

  1. 简单易学:Go语言语法简单,仅有25个关键字,易于学习和使用。
  2. 并发性强:Go语言原生支持协程和通道,可以轻松实现高并发程序。
  3. 内存管理:Go语言具有自动内存管理和垃圾回收机制,可以避免常见的内存错误。
  4. 高性能:Go语言编译速度快,生成的二进制文件体积小,运行速度快。
  5. 跨平台支持:Go语言可以在多个操作系统和硬件平台上编译执行。
  6. 天然支持网络:Go语言标准库中包含了丰富的网络编程接口,可以轻松实现Web应用程序。

总之,Go语言是一种面向现代编程需求的编程语言,其简洁性、高性能和并发性强等特点,使得其在互联网、大数据、网络编程等领域得到了广泛的应用。目前,Go语言已经成为了众多开发者的首选语言之一。

Go的三个作者分别是: Rob Pike(罗伯.派克),Ken Thompson(肯.汤普森)和Robert Griesemer(罗伯特.格利茨默)

Golang与Java等其他语言的对比

Golang、Java和C都是常见的编程语言,它们具有以下关系:

  1. Golang是由Google公司开发的一种编程语言,最初用于应对大规模网络应用程序的需求。Java也是由Sun Microsystems(现在是Oracle)发明的语言,目前被广泛应用于企业级应用程序的开发。
  2. Java和C都是传统的编程语言,已经有很长的历史和广泛的应用领域。与之相比,Golang是一种较为年轻的语言,但其标准库丰富、性能优越等特点使得其在某些场景下具有优势。
  3. Java和Golang都有良好的跨平台支持。Java使用Java虚拟机(JVM)来实现跨平台,而Golang则通过自身的编译器来实现跨平台。C虽然也可以实现跨平台,但需要手动编写平台相关的代码,并且不如Java和Golang方便。
  4. 在使用领域上,Java主要用于构建大型企业应用,例如电子商务网站、金融系统等;Golang则主要用于构建互联网应用、分布式系统和网络服务器等;而C则主要用于操作系统、嵌入式系统、驱动程序等方面。
  5. 在语言特性上,Java和Golang都是强类型语言,具有良好的代码可读性和维护性。C则是一种相对较为底层的编程语言,需要手动管理内存等资源。

总之,Golang、Java和C都是不同的编程语言,在特性、应用场景和语言生态等方面都有所不同。在选择使用何种编程语言时,需要根据实际应用需求和个人技能水平进行评估和选择。

Go的很多语言特性借鉴与它的三个祖先:C,Pascal和CSP。

Go的语法、数据类型、控制流等继承于C,Go的包、面对对象等思想来源于Pascal分支,而Go最大的语言特色,基于管道通信的协程并发模型,则借鉴于CSP分支。

Java

编译语言,速度适中(2.67s),目前的大型网站都是拿java写的,比如淘宝、京东等。

主要特点是稳定,开源性好,具有自己的一套编写规范,开发效率适中,目前最主流的语言。

作为编程语言中的大腕。具有最大的知名度和用户群。无论风起云涌,我自巍然不动。他强任他强,清风拂山岗;他横由他横,明月照大江。

c#

执行速度快(4.28),学习难度适中,开发速度适中。但是由于c#存在很多缺点,京东、携程等大型网站前身都是用c#开发的,但是现在都迁移到了java上。

C/C++

现存编程语言中的老祖,其他语言皆由此而生。执行速度最快无人能及。但是写起来最为复杂,开发难度大。

Javascript

编程语言中特立独行的傲娇美女。前端处理能力是其它语言无法比拟。发展中的js后端处理能力也是卓越不凡。前后端通吃,舍我其谁?

Python

脚本语言,速度最慢(258s),代码简洁、学习进度短,开发速度快。豆瓣就是拿python写的。Python著名的服务器框架有django,flask。但是python在大型项目上不太稳定,因此有些用python的企业后来迁移到了java上。

scala

编译语言,比python快十倍,和java差不多,但是学习进度慢,而且在实际编程中,如果对语言不够精通,很容易造成性能严重下降。,后来比如Yammer就从scala迁移到了java上。微服务框架有lagom等。

Go

编程界的小鲜肉。高并发能力无人能及。即具有像Python一样的简洁代码、开发速度,又具有C语言一样的执行效率,优势突出。

Go语言的官网

设计Go语言是为了解决当时Google开发遇到的问题:

  • 大量的C++代码,同时又引入了Java和Python
  • 成千上万的工程师
  • 数以万计行的代码
  • 分布式的编译系统
  • 数百万的服务器

Google开发中的痛点:

  • 编译慢
  • 失控的依赖
  • 每个工程师只是用了一个语言里面的一部分
  • 程序难以维护(可读性差、文档不清晰等)
  • 更新的花费越来越长
  • 交叉编译困难

如何解决google的问题和痛点?

Go希望成为互联网时代的C语言。多数系统级语言(包括Java和C#)的根本编程哲学来源于C++,将C++的面向对象进一步发扬光大。但是Go语言的设计者却有不同的看法,他们认为值得学习的是C语言。C语言经久不衰的根源是它足够简单。因此,Go语言也是足够简单。

所以,他们当时设计Go的目标是为了消除各种缓慢和笨重、改进各种低效和扩展性。Go是由那些开发大型系统的人设计的,同时也是为了这些人服务的;它是为了解决工程上的问题,不是为了研究语言设计;它还是为了让我们的编程变得更舒适和方便。

但是结合Google当时内部的一些现实情况,如很多工程师都是C系的,所以新设计的语言一定要易学习,最好是类似C的语言;20年没有出新的语言了,所以新设计的语言必须是现代化的(例如内置GC)等情况。最后根据实战经验,他们向着目标设计了Go这个语言。

Go语言语法简单,包含了类C语法。因为Go语言容易学习,所以一个普通的大学生花几个星期就能写出来可以上手的、高性能的应用。在国内大家都追求快,这也是为什么国内Go流行的原因之一。

Go之所以叫Go,是想表达这门语言的运行速度、开发速度、学习速度(develop)都像gopher一样快。

gopher是一种生活在加拿大的小动物,go的吉祥物就是这个小动物, 它的中文名叫做囊地鼠,他们最大的特点就是挖洞速度特别快,当然可能不止是挖洞啦。

Go的官网: https://golang.google.cn/

Go语言主要发展过程

Go语言是谷歌2009发布的第二款开源编程语言。

Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。

  • 2007年9月,雏形设计 ,Rob Pike(罗伯.派克) 正式命名为Go;
  • 2008年5月,Google全力支持该项目;
  • 2009年11月10日,首次公开发布,Go将代码全部开源,它获得了当年的年度语言;
  • 2011年3月16日,Go语言的第一个稳定(stable)版本r56发布。
  • 2012年3月28日,Go语言的第一个正式版本Go1发布。
  • 2013年4月04日,Go语言的第一个Go 1.1beta1测试版发布。
  • 2013年4月08日,Go语言的第二个Go 1.1beta2测试版发布。
  • 2013年5月02日,Go语言Go 1.1RC1版发布。
  • 2013年5月07日,Go语言Go 1.1RC2版发布。
  • 2013年5月09日,Go语言Go 1.1RC3版发布。
  • 2013年5月13日,Go语言Go 1.1正式版发布。
  • 2013年9月20日,Go语言Go 1.2RC1版发布。
  • 2013年12月1日,Go语言Go 1.2正式版发布。
  • 2014年6月18日,Go语言Go 1.3版发布。
  • 2014年12月10日,Go语言Go 1.4版发布。
  • 2015年8月19日,Go语言Go 1.5版发布,本次更新中移除了”最后残余的C代码”。
  • 2016年2月17日,Go语言Go 1.6版发布。
  • 2016年8月15日,Go语言Go 1.7版发布。
  • 2017年2月17日,Go语言Go 1.8版发布。
  • 2017年8月24日,Go语言Go 1.9版发布。
  • 2018年2月16日,Go语言Go 1.10版发布。
  • 2018年8月24日,Go语言Go 1.11版发布。
  • 2019年2月25日,GO语言Go1.12版发布。

Go 语言起源 2007 年,并于 2009 年正式对外发布。它从 2009 年 9 月 21 日开始作为谷歌公司 20% 兼职项目,即相关员工利用 20% 的空余时间来参与 Go 语言的研发工作。

其实可以看到,Go语言的历史不算很短。

2009年11月 GO语言第一个版本发布。2012年3月 第一个正式版本Go1.0发布。

2015年8月 go1.5发布,这个版本被认为是历史性的。完全移除C语言部分,使用GO编译GO,少量代码使用汇编实现。另外,他们请来了内存管理方面的权威专家Rick Hudson,对GC进行了重新设计,支持并发GC,解决了一直以来广为诟病的GC时延(STW)问题。并且在此后的版本中,又对GC做了更进一步的优化。到go1.8时,相同业务场景下的GC时延已经可以从go1.1的数秒,控制在1ms以内。GC问题的解决,可以说GO语言在服务端开发方面,几乎抹平了所有的弱点。

直到今年的2月25日,Go语言发布最新的版本是Go 1.12。

在GO语言的版本迭代过程中,语言特性基本上没有太大的变化,基本上维持在GO1.1的基准上,并且官方承诺,新版本对老版本下开发的代码完全兼容。事实上,GO开发团队在新增语言特性上显得非常谨慎,而在稳定性、编译速度、执行效率以及GC性能等方面进行了持续不断的优化。

Go语言的特色

Go语言具有以下几个特点:

  1. 高并发性:Go语言原生支持协程和通道,可以轻松实现高并发程序,并且在多核、分布式等场景下表现优异。
  2. 内存安全:Go语言通过垃圾回收机制和指针限制等手段,避免了常见的内存错误(如缓冲区溢出、野指针等),提高了程序的可靠性。
  3. 快速编译:Go语言的编译速度很快,即使在大型项目中也不会出现明显的编译延迟。同时,Go语言生成的可执行文件体积小,运行速度快。
  4. 简单易学:Go语言语法简单、结构清晰,易于学习和使用。它的标准库设计也非常简洁,便于开发者上手使用。
  5. 跨平台支持:Go语言可以在多个操作系统和硬件平台上编译执行,具有很好的跨平台支持性能。
  6. 丰富的工具链:Go语言提供了一系列的工具,例如go fmt、go vet、go test等,帮助开发者更加方便地进行代码格式化、检查、测试等工作。
  7. 天然支持网络编程:Go语言标准库中包含了丰富的网络编程接口,可以轻松实现Web应用程序和分布式系统等。

总之,Go语言是一种简单、高效、安全、易学、并发性强的编程语言。它因其多个特点而备受青睐,在互联网、大数据、网络编程等领域得到了广泛的应用。

简单来说, Go语言是一种 在执行效率和开发效率上都能兼备的语言。

go出现之前,无论汇编语言、还是动态脚本语言,在执行效率和开发效率上都不能兼备。

执行效率 execution speed: C/C++ > Java > PHP
开发效率 developing efficiency: PHP > Java > C/C++

Go语言的核心特性

Go语言之所以厉害,是因为它在服务端的开发中,总能抓住程序员的痛点,以最直接、简单、高效、稳定的方式来解决问题。

Go语言的核心特性包括以下几点:

1 并发:

Go语言天生具有高并发能力,通过goroutine(轻量级线程)和channel(通道)的方式,可以轻松实现并发编程,避免了多线程编程中的一些问题。

2 内存回收(GC)

从C到C++,从程序性能的角度来考虑,这两种语言允许程序员自己管理内存,包括内存的申请和释放等。因为没有垃圾回收机制所以C/C++运行起来速度很快,但是随着而来的是程序员对内存使用上的很谨小慎微的考虑。因为哪怕一点不小心就可能会导致“内存泄露”使得资源浪费或者“野指针”使得程序崩溃等,尽管C++11后来使用了智能指针的概念,但是程序员仍然需要很小心的使用。后来为了提高程序开发的速度以及程序的健壮性,java和C#等高级语言引入了GC机制,即程序员不需要再考虑内存的回收等,而是由语言特性提供垃圾回收器来回收内存。但是随之而来的可能是程序运行效率的降低。

GC过程是:先stop the world,扫描所有对象判活,把可回收对象在一段bitmap区中标记下来,接着立即start the world,恢复服务,同时起一个专门gorountine回收内存到空闲list中以备复用,不物理释放。物理释放由专门线程定期来执行。

GC瓶颈在于每次都要扫描所有对象来判活,待收集的对象数目越多,速度越慢。

一个经验值是扫描10w个对象需要花费1ms,所以尽量使用对象少的方案,比如我们同时考虑链表、map、slice、数组来进行存储,链表和map每个元素都是一个对象,而slice或数组是一个对象,因此slice或数组有利于GC。

GC性能可能随着版本不断更新会不断优化,这块没仔细调研,团队中有HotSpot开发者,应该会借鉴jvm gc的设计思想,比如分代回收、safepoint等。

  • 内存自动回收,再也不需要开发人员管理内存
  • 开发人员专注业务实现,降低了心智负担
  • 只需要new分配内存,不需要释放

3 内存分配

初始化阶段直接分配一块大内存区域,大内存被切分成各个大小等级的块,放入不同的空闲list中,对象分配空间时从空闲list中取出大小合适的内存块。

内存回收时,会把不用的内存重放回空闲list。

空闲内存会按照一定策略合并,以减少碎片。

4 快速编译:

Go语言的编译速度相对较快,在大型项目中也不会出现明显的编译延迟。同时,Go语言生成的可执行文件体积小,运行速度快。

5 简单易学

Go语言语法简单、结构清晰,易于学习和使用。它的标准库设计也非常简洁,便于开发者上手使用。

6 跨平台支持:

Go语言可以在多个操作系统和硬件平台上编译执行,具有很好的跨平台支持性能。

7 丰富的工具链:

Go语言提供了一系列的工具,例如go fmt、go vet、go test等,帮助开发者更加方便地进行代码格式化、检查、测试等工作。

8 天然支持网络编程:

Go语言标准库中包含了丰富的网络编程接口,可以轻松实现Web应用程序和分布式系统等。

总之,Go语言具有高并发、内存安全、快速编译、简单易学、跨平台支持、丰富的工具链等核心特性,使得它成为一种很受欢迎的编程语言,在互联网、大数据、网络编程等领域得到了广泛的应用。

Go语言行业案例

Go语言在多个行业中都有广泛的应用,以下是一些代表性的行业案例:

  1. 互联网:谷歌、知乎等众多互联网公司都在采用Go语言进行后台开发。例如,谷歌的网络爬虫系统Google Crawler就是用Go语言编写的。
  2. 金融:很多金融领域的公司也开始采用Go语言进行开发。例如,美国在线支付公司Stripe使用Go语言编写了一个高性能的数据分析系统。
  3. 游戏:Go语言在游戏行业中也有着广泛应用。例如,腾讯的游戏服务器框架TarsGO就是用Go语言编写的。
  4. 大数据:Go语言具有高并发和高性能的特点,因此在大数据领域中也受到欢迎。例如,Uber公司的Cherami消息传递系统就是用Go语言编写的。
  5. 区块链:Go语言也成为了区块链领域的首选编程语言之一。例如,以太坊的客户端Geth就是使用Go语言编写的。

总之,Go语言在多个行业中都得到了广泛的应用,并且随着其不断完善和优化,其使用范围还将进一步扩大。

除了大名鼎鼎的Docker,完全用GO实现。业界最为火爆的容器编排管理系统kubernetes完全用GO实现。之后的Docker Swarm,完全用GO实现。

除此之外,还有各种有名的项目,如etcd/consul/flannel,七牛云存储等等均使用GO实现。

有人说,GO语言之所以出名,是赶上了云时代。

但为什么不能换种说法?也是GO语言促使了云的发展。

除了云项目外,还有像今日头条、UBER这样的公司,他们也使用GO语言对自己的业务进行了彻底的重构。

GO语言产生的宽松工作环境

go语言的产生,得益于谷歌 宽松的技术研究环境。

谷歌的“20%时间”工作方式,允许工程师拿出20%的时间来研究自己喜欢的项目。

语音服务Google Now、谷歌新闻Google News、谷歌地图Google Map上的交通信息等,全都是20%时间的产物。

Go语言最开始也是20%时间的产物。

这点,特别值得 国内大厂 学习。 国内大厂 流行 996,极致压榨 大家的 工作时间 ,严格管控 大家的 技术产出, 大家没有任何的 创新空间、创造空间。

国内大厂的管理方式,极度不利于技术创新。 享受不到技术创新、专利创新带来的 赢家通吃 红利。

Go语言开发环境搭建

常用链接

Go语言SDK工具包括以下几种:

  1. Go编译器:

    Go编译器是将Go源代码编译成可执行文件的工具。Go编译器可以通过命令行或者集成开发环境(IDE)中进行使用。

  2. Go开发环境(IDE):

    Go语言没有官方推荐的IDE,但是有很多第三方的IDE可以供开发者使用。

    例如,GoLand、Visual Studio Code、Sublime Text等。

  3. Go fmt:

    Go fmt是一个格式化代码的工具,可以让Go代码更加规范和易读。

  4. Go vet:

    Go vet是一个静态代码分析工具,可以检查代码中的潜在问题,并提供相应的建议。

  5. Go test:

    Go test是一个单元测试工具,可以帮助开发者编写测试用例并进行自动化测试。

总之,Go语言的开发工具丰富多样,可以根据个人需求选择最适合自己的工具进行开发。

Go编译器SDK的安装

Golang是一种编程语言,其安装和使用步骤如下:

安装Golang:

从官方网站下载对应操作系统的安装文件。

All releases - The Go Programming Language (google.cn)

尼恩的工具包里边,给大家都准备好了

Golang的官方网站提供了多个版本的二进制安装程序,可以根据不同的操作系统和硬件架构选择相应的版本。

  • 对于Windows系统,可以下载.msi文件的安装程序,
  • 对于Linux或Mac OS X系统,可以下载源代码或二进制文件的压缩包。

Windows系统,使用.msi文件的安装程序,一路按照向导,安装就ok了。

Golang的安装路径

配置环境变量:

安装完成后,我们需要将Golang的安装路径添加到系统的环境变量中。

对于Windows系统,可在“计算机”或“我的电脑”右键选择“属性”,在“高级系统设置”中点击“环境变量”,在“系统变量”中添加环境变量“GO_HOME”和“GOPATH”,分别指向Golang的安装路径和工作目录。

GO_HOME  指向  Golang的安装路径
GOPATH   指向  工作目录

GO_HOME 环境变量如下:

在Windows系统上,可以打开“控制面板” -> “系统与安全” -> “系统”,点击“高级系统设置”,然后点击“环境变量”按钮,在“系统变量”中找到“Path”变量,添加Golang的bin目录路径,例如“C:\\Go\\bin”。

C:\\Program Files\\Go\\bin 已经自动进入到了 path 环境变量里边,不需要手动添加了:

对于Linux或Mac OS X系统,可将Golang的安装路径添加到PATH环境变量中,例如在~/.bashrc文件中添加:

export  PATH=$PATH:/usr/local/go/bin

以上就是Golang的安装和使用步骤。Golang具有高效、简单、安全等优点,适合构建各种类型的应用程序,例如服务器、网络服务、命令行工具等。

GoLang SDK 安装和 Java SDK的安装比较

简直是一模一样,就是 名字不同而已。

Golang 集成开发工具IDE

以下是一些常用的 Golang 开发工具:

  1. GoLand:由 JetBrains 开发,拥有丰富的功能和插件支持的集成开发环境(IDE)。
  2. Visual Studio Code:轻量级的代码编辑器,使用 Go 扩展可以获得与 GoLand 类似的功能。
  3. Sublime Text:另一个流行的代码编辑器,也有很多插件可用于支持 Golang 开发。
  4. Vim:强大的文本编辑器,可以通过添加插件和配置来支持 Golang 开发。
  5. LiteIDE:专门为 Golang 打造的开发环境,支持自动补全等基本功能,适合初学者。
  6. Eclipse:一个广泛使用的 IDE,可以通过安装相应的插件来支持 Golang 开发。

以上是一些常用的 Golang 开发工具,您可以根据个人偏好选择最适合您的开发工具。

GoLand 安装和使用

大部分小伙伴,非常熟悉 JetBrains公司 的idea, 这里推荐的是 这个公司 提供的 GoLand。

GoLand是一款由JetBrains公司开发的集成开发环境(IDE),专门用于Go编程语言。

下面是GoLand的安装和使用步骤:

下载安装包:

从官方网站https://www.jetbrains.com/go/download/ 下载对应操作系统的安装文件。尼恩的工具包里边,给大家都准备好了

安装GoLand:

运行安装包并按照提示进行安装。

打开GoLand:

打开GoLand后,会看到一个欢迎界面。在这里可以新建项目、打开已有项目等。

创建项目:

在欢迎界面选择"Create New Project",选择项目类型和存储位置,然后点击"Create"按钮。

创建一个项目

配置Go SDK:

打开File -> Settings菜单,在左侧导航栏中选择"Go",然后在右侧"GOROOT"选项中添加你的Go SDK路径,例如“/usr/local/go”。

完成之后,空项目如下:

编写代码:

在编辑器中编写代码,new 一个新的文件,名字为hello,类型为 simple application , 如下:

新的go 文件创建好了,如下:

编写一个 hello world 案例:

一共是两句:

  • 一句是 import "fmt"
  • 一句是 fmt.Println("Hello, World!")

第一句什么意思呢? import "fmt" 是 Go 语言中用于导入标准库 fmt 的语句。

fmt提供了格式化输入输出的函数,例如:Println()Printf() 等,可以在控制台打印输出内容。

这个包也包括了一些其他的函数,如字符串格式化和解析、文件读写等。

使用 import "fmt" 可以让你在Go程序中使用fmt包中的函数,从而方便地进行输入输出操作。

例如上面的代码:

import "fmt"

func main() 
    fmt.Println("Hello, World!")

这段代码中,我们使用 import "fmt" 导入了 fmt 包。

第二句 fmt.Println("Hello, World!") 是什么意思呢?

fmt.Println("Hello, World!") 是 Go 语言中用于向控制台输出 "Hello, World!" 的语句。

Println 是位于 fmt 包中的 Println() 函数。

在这个例子中,我们使用 fmt.Println() 函数按顺序打印给定参数,并在最后一个参数后添加换行符。

因此,将 "Hello, World!" 作为参数传递给 fmt.Println() 函数将在控制台上显示 Hello, World! 并自动换行。

main() 函数中调用了 Println() 函数来输出 Hello, World! 到控制台上。

运行程序:

点击编辑器顶部的运行按钮(绿色三角形)或者使用快捷键Shift+F10来运行程序。

运行结果如下:

以上就是GoLand的安装和使用步骤。

GoLand具有良好的用户界面、丰富的功能和插件支持,可以提高开发效率,让Go语言的开发变得更加简单和高效。

Go的执行原理以及Go的命令

Go 的源码文件分类:

在 Go 中,源码文件分为4种类型:

  1. 命令源码文件:
  • .go 为扩展名的文件
  • 命令源码文件属于main包
  • 包含main方法,是程序的运行入口,是每个可独立运行的程序必须拥有的。
  1. 库源码文件:
  • .go 为扩展名的文件。
  • 不包含main入口方法。
  1. 测试文件:
  • _test.go 为后缀的源码文件
  • 测试文件用于编写单元测试和性能测试等测试代码。
  1. C 语言源码文件:

.c.h.s 等后缀名的文件,用于包含一些 C 语言实现的辅助代码或工具。

  1. 无源码文件:
  • 不包含代码的文件,例如 README、LICENSE 等。
  • 这些文件虽然对于程序的运行没有影响,但对于开发者来说具有重要意义。

其中,.go 源码文件和 _test.go 测试文件是最常见的文件类型。

总体而言:

  • 在一个 Go 工程中,通常将所有的源码文件组织在一个或多个 package 中,并对外提供相应的接口。测试文件则用于测试这些接口的正确性和性能。
  • 除此之外,Go 还支持嵌套的 package 和 vendor 目录,使得工程的组织结构更加灵活和清晰。
  • 同时,在 Go 编译时,会自动生成相关的二进制文件、静态库或动态链接库等文件。

1、命令源码文件:

命令源码文件的两个特征:

  • 声明自己属于 main 代码包、
  • 包含 main 函数, 这是一个无参数声明和结果声明、名字叫做 main 的函数。

命令源码文件 的作用:

  • 命令源码文件是 Go 程序的入口。
  • 命令源码文件是可以单独运行的。

可以使用 go run 命令直接运行,也可以通过 go build 或 go install 命令得到相应的可执行文件。所以命令源码文件是可以在机器的任何目录下运行的。

step1: 通过 go run 命令直接运行 命令源码文件:

同一个代码包中最好也不要放多个命令源码文件。多个命令源码文件虽然可以分开单独 go run 运行起来,但是无法通过 go build 和 go install。

命令源码文件被 go install 安装以后,变成了exe可执行文件,一般去了哪儿呢?

  • 如果GOPATH 只有一个工作区,那么相应的可执行文件会被存放当前工作区的 bin 文件夹下;
  • 如果有多个工作区,就会安装到 GOBIN 指向的目录下。

复制hello.go为hello2.go文件,并修改里面的内容:

hello目录下有两个go文件了,两个命令源码文件:

  • 一个是hello.go
  • 一个是hello2.go。

先说明一下,在上述文件夹中放了两个命令源码文件,同时都声明自己属于 main 代码包 : package main 。

打开 控制台 终端,进入工目录,执行go run命令执行两个 命令源码文件,可以看到两个go文件都可以被执行:

上面执行go run没有问题,但是 执行 go build 和 go install 问题就来了。

看看会发生什么:

PS C:\\Users\\nien\\go\\src\\awesomeProject> go build 
# awesomeProject
.\\hello2.go:5:6: main redeclared in this block
        .\\hello.go:5:6: other declaration of main
PS C:\\Users\\nien\\go\\src\\awesomeProject>  go install
# awesomeProject
.\\hello2.go:5:6: main redeclared in this block
        .\\hello.go:5:6: other declaration of main

运行效果图:

这也就证明了一个问题:多个命令源码文件虽然可以分开单独 go run 运行起来,但是无法通过 go build 和 go install。

2、库源码文件

库源码文件就是不具备命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通的源码文件。

在 Go 语言中,库源码文件也需要遵循一定的命名规则和编写规范。

以下是一些通用的概念和步骤:

  1. 创建一个新的 package,package 名称应该与文件夹名称相同。

  2. 在 package 中编写代码,可以包含多个源码文件。

  3. 对外暴露需要让其他 package 访问的函数、类型或变量,需要在其名称前面添加大写字母。

func Add(a, b int) int 
   return a + b

  1. 编写文档注释,可以使用 go doc 命令来查看文档。
// Add 将两个整数相加并返回结果
func Add(a, b int) int 
    return a + b

  1. 使用 go buildgo install 命令来构建和安装库,安装后可以在其他程序中 import 并使用。
$ go install github.com/xxx/yyy

以上是库源码文件的基本流程和示例,更多细节和高级用法可以参考官方文档:

How to Write Go Code - The Go Programming Language (google.cn)

库源码文件被安装后,相应的归档文件(.a 文件)会被存放到当前工作区的 pkg 的平台相关目录下。

3、测试源码文件

在 Go 语言中,测试源码文件需要遵循一定的命名规则和编写规范。

以下是一些通用的概念和步骤:

  1. 在同一个 package 中创建一个名为 xxx_test.go 的文件,其中 xxx 是要测试的源码文件的名称。

  2. 在测试文件中导入 testing 包。

import "testing"
  1. 编写测试函数,函数名以 Test 开头,函数签名为 func TestXxx(*testing.T),其中 Xxx 是要测试的函数的名称。
func TestAdd(t *testing.T) 
    // 测试代码...

  1. 在测试函数中,可以使用 t.Errort.Fail 等方法判断测试结果是否符合预期。
func TestAdd(t *testing.T) 
    if add(1, 2) != 3 
        t.Errorf("add function failed")
    

  1. 运行测试程序,可以使用 go test 命令来运行当前目录下所有测试文件。
$ go test
PASS
ok      command-line-arguments  0.001s

更多细节和高级用法可以参考官方文档:https://golang.google.cn/pkg/

[日常] Go语言圣经--示例: 并发的Echo服务

最简单的回声服务器:

package main

import (
        "io"
        "net"
        "log"
)


func main() {
        listener, err := net.Listen("tcp", ":8040")
        if err != nil {
                log.Fatal(err)
        }   

        for {
                conn, err := listener.Accept()
                if err != nil {
                        log.Print(err) // e.g., connection aborted
                        continue
                }   
                go handleConn(conn) //新建goroutines处理连接
        }   
}

func handleConn(c net.Conn) {
    io.Copy(c, c) // NOTE: ignoring errors
    c.Close()
}

原理:

1.io.Copy()方法
func Copy(dst Writer, src Reader) (written int64, err error)

2.net.Conn类型
type Conn interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
...
}
一个类型如果拥有一个接口需要的所有方法,那么这个类型就实现了这个接口

3.io.Writer
type Writer interface {
Write(p []byte) (n int, err error)
}
4.io.Reader
type Reader interface {
Read(p []byte) (n int, err error)
}

升级版,每条连接一个goroutine,每个goroutine中分出多个输出goroutine

package main

import (
        "bufio"
        "fmt"
        "log"
        "net"
        "strings"
        "time"
)

func main() {
        listener, err := net.Listen("tcp", ":8040")
        if err != nil {
                log.Fatal(err)
        }   

        for {
                conn, err := listener.Accept()
                if err != nil {
                        log.Print(err) // e.g., connection aborted
                        continue
                }   
                go handleConn(conn) //新建goroutines处理连接
        }   
}

func handleConn(c net.Conn) {
        input := bufio.NewScanner(c)
        for input.Scan() {
                go echo(c, input.Text(), 1*time.Second)
        }   
        // NOTE: ignoring potential errors from input.Err()
        c.Close()
}
func echo(c net.Conn, shout string, delay time.Duration) {
        fmt.Fprintln(c, "\\t", strings.ToUpper(shout))
        time.Sleep(delay)
        fmt.Fprintln(c, "\\t", shout)
        time.Sleep(delay)
        fmt.Fprintln(c, "\\t", strings.ToLower(shout))
}

  

1.fmt.Fprintln()
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

2.bufio.NewScanner()
func NewScanner(r io.Reader) *Scanner
func (s *Scanner) Scan() bool
func (s *Scanner) Text() string

也用到了大量的7.3节 实现接口的条件

  

以上是关于Go学习圣经:0基础精通GO开发与高并发架构的主要内容,如果未能解决你的问题,请参考以下文章

Go基础:入门学习资料

Go学习资料

调优圣经:零基础精通Jmeter分布式压测,10Wqps+超高并发

[日常] Go语言圣经--示例: 并发的Echo服务

golang基础学习及web框架

[日常] Go语言圣经-示例: 并发的目录遍历习题