go语言介绍及应用场景分析

文章目录

  • go语言介绍及应用场景分析
    • 1 概述
      • 1.1 优劣势分析
    • 1.2 应用场景
    • 2 go语言编译原理介绍
      • 2.1 词法分析和语法分析
      • 2.2 类型检查与AST 转换
      • 2.3 通用 SSA 生成(中间代码生成)
      • 2.4 机器码生成
    • 3 go语言环境搭建

1 概述

go语言诞生于2007年,由Google首席软件工程师Rob Pike与Robert Griesemer和Ken Thompson两位大师创造,目的是用来取代C++语言,来解觉google工作者在使用C++语言带来的问题,2009年11月首次向公众发布并开源,自开源后在google内部和公众,都得到了广发的应用,国内大厂字节跳动、腾讯、阿里巴巴等纷纷转型,数以百万计的开发者开始投入Go语言的怀抱。

Go 语言具有很强的表达能力,简洁、清晰且高效。由于其独特的并发机制,用它编写的程序能够非常有效地利用多核与联网的计算机,其新颖的类型系统则使程序结构变得灵活而模块化。Go代码编译成机器码不仅非常迅速,还具有方便的垃圾收集机制和强大的运行时反射机制。它是一个快速的、静态类型的编译型语言,感觉却像动态类型的解释型语言。

1.1 优劣势分析

随着编程人员对编程语言在易用、易学、低代码等方面的要求越来越多,加之C/C++近年来相关的人才越来越难招,学习和人力成本越来越高,python、scala、go等编程语言,愈来愈流行。其中go语言由于其独特的优势,特别在并发性能和易用性上都表现较好,在某些场景下得到了广泛额应用,结合网上资料及总结,下面分析下go语言的优势和劣势

主要优势体现在如下方面:

  • 简单易学:Go语言语法简单,包含了类C语法,很容易上手,开发速度快

  • 媲美C的高性能:可直接编译成机器码,不依赖其他库,相比于java及python,具有更高的性能,夸张点说可媲美C

  • 开发效率高:编译快、开发快、运行高效,相较于 Java 和 C++的编译速度,Go 的快速编译是主要的效率优势。Go拥有接近C的运行效率和接近PHP的开发效率。

  • 自由灵活:Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程、面向接口编程、函数式编程,开发者可自由组合和扩展

  • 高并发性:通过goroutines 和通道,天生支持并发变成,goroutine通过协程实现并发,占用的资源低,几十个goroutine可能体现在底层就是五六个线程,Go语言内部实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),可同时运行成千上万个并发任务,goroutine比thread更易用、更高效、更轻便。

  • 生态强大:背靠google,go语言有着强大的生态系统,有很多开源的框架可选用,有面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 等的稳定强大的标准库。相比于 Rust、Elixir 这样的语言有很大的优势,但是又略逊于 Java、Python语言,但是其高性能和高效率,可弥补。

  • 部署简单:直接生成机器码,可二进制文件直接部署,因为部署太方便了,这一点是很多人选择Go的最大理由

  • 易于组建团队:任何的 Python、Elixir、C++、Scala和 Java 开发者皆可在一月内组建成一个高效的Go团队。

    当然,go语言也有很多的不足之处,以下列出一些主要的不足:

  • 框架不够丰富: Go 语言没有一个主要的成熟框架,开发相比于python等还是没那么便捷

  • 软件包管理不完善:包不支持版本,需要自己控制版本信息

  • 缺乏有经验的go工作者:会用go很多,深入研究的很少,尽管有些程序员带着java和c++的丰富分布式编程经验来到go,但其实好多人并不知道如何针对go的特性来设计和使用API,这造成非常多的go项目是不一定能经受住长期维护考验的

1.2 应用场景

Go语言在云计算、边缘计算、大数据、微服务、物联网、高并发领域应用得越来越广泛,越来越多的知名公司正在把Go作为开发新项目的首选语言,golanguage主要在如下场景中有着广泛的应用:

  • 服务器编程:可以替代前期C/C++,例如HTTP服务、文件系统、虚拟机处理、数据打包等场景,比较好的go开源项目入nsq/heka等
  • 分布式系统:可用于分布式计算、分布式存储、分布式读写等场景开发,例如分布式调度框架,分布式文件系统等,如:cbfs/skynet/doozer等
  • 网络变成:主要包括服务器编程,得益于其高并发能力,目前应用最为广泛,开源项目如:GIN、Beego、Buffalo、Echo、Iris、Revel等
  • 内存数据库/数据库代理:用于做内存数据库,或者内存缓存前一段时间google开发的groupcache,couchbase的部分组建
  • 云平台:基于go语言的云平台组件开发,例如:docker/k8s等,以及云原生服务的开发
  • 嵌入式应用开发:由于其占用资源较少、跨平台、高效率等优势,且其高校编译、高效执行、易于编程的特点,把go语言作为嵌入应用开发语言大厂越来越多

go大部分场景能够替代c/c++,但是在某些场景c/c++还是不能被替代,例如实时操作系统和设备驱动程序的开发。

由于我们公司准备使用go语言作为嵌入式开发语言,下面重点介绍下go语言相比于c/C++在嵌入式开发中的优劣势。
嵌入式变成一般对开发语言有如下要求:

  • 编译后的程序尽可能小,由于嵌入式硬件一般硬件资源有线

  • 能够兼容嵌入式系统,如嵌入式linux系统

  • 具备可移植性,嵌入式软件一般在windows下开发,需要具备跨平台调试和运行的能力

  • 具备网络编程的能力,嵌入式需要支持TCP/IP协议,开发语言需要有相应的支持

  • 尽可能少的外部库依赖,因为外部依赖,可能引入兼容性的问题

  • 兼容C语言的接口,因为嵌入式驱动层几乎还是c语言

从嵌入式的基本要求,语言的开发难度等方面,对c/c++/go进行对比,如下:

语言 c c++ go
设备存储要求 最低 低(比c多出几兆) 低(比c++多出几兆,在一个量级)
跨平台能力 支持 支持 支持
缓冲不足/溢出保护 不支持 轻度支持 支持
c接口兼容 完全兼容 完全兼容 支持导入c接口
自动内存管理 不支持 不强制支持(需要自行实现) 支持
标准数据容器 不支持 支持 支持
HTTP库 外部依赖或者开发实现 外部依赖或者开发实现 内置
JSON 外部依赖或者开发实现 外部依赖或者开发实现 内置
SSL/TLS 外部依赖或者开发实现 外部依赖或者开发实现 内置(可选软件包)
共享依赖关系
运行速度 最高 较高
编译速度 较慢 最慢 极快

从上述表中可以看出,由于Go应用程序可以静态编译为单个二进制文件,因此它并不需要任何额外的虚拟环境(比如Java除了二进制文件之外还需要虚拟机),Go代码在设备上运行也不需要依赖其他项,另外Go在代码编译后生成的可执行文件大小也是可以与C,C++和C++ / Qt相媲美,且go语言有极其丰富的标准库,非常易于开发,虽然在代码编译后生成的程序体积上,略大于c/c++,但是也在能够接受的范围内,因此从编译速度、易用性、保护机制、标准库数量等方面,如果嵌入式不是特别极端的场景下(如追求极致速度及资源使用)的情况下,go语言在嵌入式中可以替代c/c++,当然在驱动层及操作系统层,c还是最好的开发语言。

2 go语言编译原理介绍

Go语言需要编译成二进制机器码,包含二进制机器码的文件才能在目标机器上运行,和c/c++类似(预处理/编译/汇编/链接),Go 的编译器在逻辑上分为如下四个阶段:词法与语法分析、类型检查和 AST 转换、通用 SSA 生成和机器代码生成。

2.1 词法分析和语法分析

编译过程是从解析代码的源文件开始的,词法分析的作用是解析源代码文件,它将文件中的字符串序列转换成 Token 序列,方便后面的处理和解析,由词法分析器(lexer)对源代码文件进行解析。

语法分析阶段,由语法分析器按照顺序解析Token序列,根据编程语言定义好的文法(grammer)对Token进行自下而上或自上而下的归约,转换成有意义的结构体,即抽象语法树。每个 Go 源代码文件最终都会被解析成一个独立的抽象语法树(AST)。有关抽象语法树概念了解,可参照:
https://blog.csdn.net/weixin_52690231/article/details/124691503

每一个 Go 的源代码文件最终会被归纳成一个 SourceFile 结构:

SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" }

Token 到上述抽象语法树(AST)的转换过程会用到语法解析器,每一个 AST 都对应着一个单独的 Go 语言文件,这个抽象语法树中包括当前文件属于的包名、定义的常量、结构体和函数等。语法解析的过程中发生的任何语法错误都会被语法解析器发现并将消息打印到标准输出上,整个编译过程也会随着错误的出现而被中止

2.2 类型检查与AST 转换

类型检查会遍历AST中的节点,检验每个节点的类型,找出其中存在的语法错误。此过程中也可能改写AST,包括去除一些不会被执行的代码,优化代码以提高执行效率,而且会修改make、new等关键字对应节点的操作类型。

在类型检查阶段,会根据创建的类型将make替换成特定的函数,后面生成中间代码的阶段就不会再处理OMAKE类型的节点了。比如如果make的第一个类型参数是切片,那么在对参数数量和合法性进行校验之后,还会将当前节点的操作Op改成OMAKESLICE,方便后面编译阶段的处理。

中间代码的生成过程是从 AST 抽象语法树到 SSA 中间代码的转换过程,在这期间会对语法树中的关键字再进行改写,改写后的语法树会经过多轮处理转变成最后的 SSA 中间代码,相关代码中包括了大量 switch 语句、复杂的函数和调用栈,阅读和分析起来也非常困难。

2.3 通用 SSA 生成(中间代码生成)

中间代码是编译器或者虚拟机使用的语言,它可以来帮助我们分析计算机程序。在编译过程中,编译器会在将源代码转换到机器码的过程中,先把源代码转换成一种中间的表示形式,即中间代码

由于 Go 语言编译器的中间代码使用了 SSA 的特性,在这一阶段能够分析出代码中的无用变量和片段并对代码进行优化,生成中间代码包括初始化SSA生成的配置和函数编译两部分,详细参照:
https://zhuanlan.zhihu.com/p/454419598

2.4 机器码生成

Go 语言编译的最后一个阶段是根据 SSA 中间代码生成机器码,这里谈的机器码是在目标 CPU 架构上能够运行的二进制代码。
机器码的生成过程其实是对 SSA 中间代码的降级(lower)过程,在 SSA 中间代码降级的过程中,编译器将一些值重写成了目标 CPU 架构的特定值,降级的过程处理了所有机器特定的重写规则并对代码进行了一定程度的优化;在 SSA 中间代码生成阶段的最后,Go 函数体的代码会被转换成cmd/compile/internal/obj.Prog结构,机器码的生成在 Go 的编译器中主要由两部分协同工作,其中一部分是负责 SSA 中间代码降级和根据目标架构进行特定处理的 cmd/compile/internal/ssa 包,另一部分是负责生成机器码的汇编器 cmd/internal/obj包,详细请参照:
https://zhuanlan.zhihu.com/p/454419598

最后汇总下整个编译流程,如下:

3 go语言环境搭建

这里顺便介绍下go语言在windows下的安装及部署过程,后续文章会针对go的IDE做详细讲解。

  1. 下载go语言:建议下载最新稳定版本,本文下载版本是1.18.3,下载地址如下

go1.18.3.windows-amd64.msi

  1. 安装go

双击下载文件安装即可,可自定义安装路径

  1. 配置环境变量

最新版本安装包,安装完成之后会自动配置好环境变量,这一步可以略过,可以直接通过在cmd命令提示行中输入:
go version
如果弹出如下版本信息,则说明环境变量已经配置好,环境安装成功。

  1. 编写实例go代码

创建工作目录,创建go文件(hello.go),编辑hello.go,输入如下代码:

package mainimport "fmt"func main() {fmt.Println("Hello, World!")
}

编写好的代码可以直接通过go run hello.go命令执行,并得到执行结果,在代码所在的目录shift+右键,在此处打开powershell,然后如下操作:

  1. 编译生成二进制文件

通过go run可以直接运行hello.go,但是在无go环境的情况,不能单独运行,需要编译成二进制文件,才能单独运行,通过如下命令进行编译:
go build hello.go

编译后生成hello.exe,此二进制文件 可以在无go环境下直接运行。

通过文本方式编程开发,很不方便,后续介绍VSCODE中配置go集成开发环境。

go语言介绍及应用场景分析相关推荐

  1. nio的优势_BIO、NIO、AIO 介绍和适用场景分析

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.同步阻塞的BIO 在JDK1.4之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个serverS ...

  2. Hbase原理介绍和使用场景分析

    目录 主流nosql HBase是列式存储还是行式存储 架构 HBase数据模型 列簇与数据存储 HBase 优点 HBase 缺点 HBase 适用场景 思考几个问题 读写性能对比 Hbase三个重 ...

  3. 大厦设计师 -- 建造者模式 (Builder Pattern) 介绍 使用案例场景分析 优缺点 及代码演示

    一句话概括: 使用多个简单对象一步一步构建成复杂对象,将复杂对象的构建与表示相分离. 补充介绍: 建造者模式(Builder Pattern)中有一个 Builder 类,这个类会一步一步构造最终的对 ...

  4. BIM建筑环境规则和分析(BERA)语言介绍(一)概要

    -------作者:JIN KOOK LEE   指导: Charles M. Eastman 本研究旨在设计和实现特定领域的计算机 编程语言:建筑环境规则和分析(BERA)语言. 由于建筑信息模型( ...

  5. ESB产品调用场景分析

    随着企业服务总线ESB产品功能的逐渐完善,对用户来说,使用时流畅便捷是对产品的基本需求.那么对于数通畅联来说,让用户使用产品时更便捷是产品不断完善的前进方向.在产品功能实现的基础上,提升应是交互越简单 ...

  6. python私有方法应用场景_Python 私有属性和私有方法应用场景分析

    类的私有属性和方法 Python是个开放的语言,默认情况下所有的属性和方法都是公开的 或者叫公有方法,不像C++和 Java中有明确的public,private 关键字来区分私有公有. Python ...

  7. mysql表分区占用存储_MySQL 分区分表应用场景分析和分区中可能遇到的坑点

    MySQL的分区和分表应用场景分析 在日常工作中当我们的某张表的数据量过大的时候,首当其冲的可能就是进行分区和分表,但是是如何分区或者分表都要结合一点的业务场景下进行分析,才会显著的提升性能,来聊一聊 ...

  8. 电商抢购秒杀系统的设计_1_应用场景分析

    2019独角兽企业重金招聘Python工程师标准>>> 电商抢购秒杀系统的设计_1_应用场景分析 概述 所谓知已知彼,百战不殆,在开始详细介绍实战中的抢购秒杀系统时,我们了解一些抢购 ...

  9. mysql 事务 查询 范围加锁_MySQL死锁系列-常见加锁场景分析

    本文我们就从原理走向实战,分析常见 SQL 语句的加锁场景.了解了这几种场景,相信小伙伴们也能举一反三,灵活地分析真实开发过程中遇到的加锁问题. 如下图所示,数据库的隔离等级,SQL 语句和当前数据库 ...

  10. mysql常见死锁_MySQL死锁系列-常见加锁场景分析

    如下图所示,数据库的隔离等级,SQL 语句和当前数据库数据会共同影响该条 SQL 执行时数据库生成的锁模式,锁类型和锁数量. 下面,我们会首先讲解一下隔离等级.不同 SQL 语句 和 当前数据库数据对 ...

最新文章

  1. [NC19798]区间权值
  2. 青源LIVE第22期|旷视刘松涛:YOLOX,高性能目标检测的最新实践
  3. Request请求用Cookie记录SessionId
  4. 21天精通python-21天学通Python 完整pdf扫描版[58MB]
  5. php 导出csv设置列宽度,php数据库导出excel表格数据-php从数据库导出csv格式的Excel表格是,字段本身就......
  6. Keras-数据增广
  7. PowerShell与活动目录
  8. 前端学习(983):jquery概念
  9. 阿里云朱照远:边缘计算,无处不在
  10. mysql数据表中取几列_MySQL实现表中取出随机数据
  11. 飞鸽传书谈哈希表之数学原理
  12. Git命令:git常用命令
  13. 为什么DNN的SectionHead Control图片无法显示,也无法折叠
  14. 干货来袭!java从入门到精通第五版pdf
  15. 基于JSP实现的影视创作论坛系统
  16. 关于元器件选型需要注意的问题
  17. Python类型说明符、格式限定符(格式说明符)
  18. 机票预订系统活动图_机票预订ppt
  19. 元宇宙,小荷才露尖尖角
  20. 《读万卷书行万里路》国画大家罗建泉写生艺术

热门文章

  1. 爬虫(二)-创建项目应用
  2. Python用可变参数找出最大值和最小值
  3. [PKUSC2018游记]
  4. Docker快速入门(一)
  5. centos7 yum install redis
  6. Wsus 清理的计划任务
  7. sql 将某一列的值拼接成字符串
  8. Matlab中struct的用法
  9. 73本免费的、语言无关的优秀的编程书籍
  10. Java方法重载解析