go 语言介绍
背景
一直有在零散的时间用go写点代码,正好借着最近比较有时间写东西的契机,给这个看着年轻,实际也已经发展10几年,并在当下众多开发领域都有不可忽视作用的语言做个介绍吧
golang 的起点
golang 的诞生可以说是时代造就了它,它也成就了研发工具、云原生和高性能服务开发百花齐放的时代
本节主要参考文章:
Go at Google: Language Design in the Service of Software Engineering
翻译-Google 里的 Go 语言:服务于软件工程的语言设计
煎鱼-为什么要开发 Go 这门新语言?
开发痛点
- 当时谷歌使用的语言:C++、Java 和 Python ,已经不适用于计算层面的需求,对于多核处理、大规模计算 和 web应用编程层面,遇到的问题都只能绕过,而不是直接解决
ced by multicore processors, networked systems, massive computation clusters, and the web programming model
-
软件规模:千万行代码,数千程序员共同维护(言外之意就是效率太低了,语言和开发者两个层面)
-
编译时间太长,几分钟到几小时都有(特别讲了 C++ #include 在编译上的消耗: Dependencies in C and C++)
-
依赖混乱,跨语言构建麻烦
-
难以编写自动化工具
译者注: 结合原文之后的内容来看,最主要的两类问题就是 大规模的 C++ 项目编译时间长,以及多种语言维护成本高的问题
发明者
Robert Griesemer: 参与过谷歌 V8 引擎的开发,Sawzall 语言(谷歌内部用的日志分级打印库,之后被 go 的日志库替代)、JVM 和 strongtalk 系统(用于类型检查,现在不维护了)
Rob Pike:Unix 开发者之一,为 Unix 编写过终端,后续编写过 sam、acme 文本编辑器,再之后和 Ken Thompson 一起创造了 UTF-8
Ken Thompson: Unix 开发者之一,B语言(C语言的前身)的发明者,后面 Dennis Ritchie 基于 B 语言又开发了 C语言。1983 年 Ken 和 Dennis 一同获得了图灵奖
扩展: Russ Cox,你可以在 golang 的很多 issue 中看到他的身影,他也是go代码提交次数最多的
推荐阅读: 图灵奖历届得主、golang talk
吉祥物
名字: Gopher(囊地鼠)
由 Rob Pike 的妻子 Renee French 创作,官网甚至还有细节描述呢
go 是什么样的语言
为了解决前面说的问题,go 必须有下面的特点:
- 高效率、可扩展、满足生产力需求
- 必须有可扩展性,对于代码量多、依赖多、开发者多的大型项目 必须能很好运作
- 自带 GC,并在对象内存申请、释放空间上进行优化,保证GC尽量不影响业务运行
- 符合C的编程习惯,让程序员能丝滑切换(如: 静态类型对象)
- 必须足够现代化,在多核处理、网络、web 应用开发上需要更加方便,也要支持更多新特性,如内置的并发编程方案
时间和版本
golang 版本来源: 从 1.10 到最新
go 语言特点
go 语言特点
本节中,笔者将结合自己平时开发过程中使用到的 go 比较核心的特性进行基本介绍,这些也是 go 和其他编程语言最不同的地方,包括 基本语法、基本指令、函数、关键字、基本类型、打包方式等
语法
- 通过大括号划分代码块,保证大项目下依旧结构清晰
- 不需要分号,虽然加了也不会报错
- 不需要小括号,比如在 if a < b 判断语句、for 循环中的判断,都不需要
- 未使用的 import / 局部变量将报错,保证编译不会引入多余的代码,提升编译效率
执行
- go build: 统一的打包语句
- 编译后生成一个可执行文件
debug
- pprof: 自带性能指标库,可通过火焰图、命令行查看堆栈情况、堆大小、各协程调用耗时等
函数
- 接口不需要显式说明继承,只要实现了接口的方法即算是继承
- 接口可以通过 指针接收器(pointer receiver) 或 **值接收器(value receiver)**实现,分别适合 setter 和 getter 的实现,大对象的方法也适合用 指针接收器 避免频繁拷贝(参考: 什么时候适合用什么接收器?)
- 方法可以作为对象传递,可以作为 map 的 value、声明匿名方法、定义闭包(闭包常用于定义配置方法,如 trpc 的 server.Opts 及其具体实现方法)
- 不支持重载,用开发必须增加少量代码的代价换来了 代码可读性和编译性能(一些讨论)
- 建议使用组合(composition),而不是继承(inheritance)(对比: java 类在多次继承后,要找到只在基类实现的方法的源代码,需要跳很多次才能找到,相反,组合的结构就很清晰,只有一层)
错误处理
- 没有异常机制,通过 error + 函数返回值 直接返回报错,在外部及时处理错误(也促使开发者封装好会出现 error 的代码块,减少主函数的层级)
- 通过 panic + recover 机制捕获协程中发生的严重错误(如空指针)
基本类型和关键字
- 切片(slice)和数组(array): 切片包含数组、长度(len)和容量(cap)
- map: 非协程安全的 map(slice 也是非协程安全的,go 设计上就是让 channel 成为唯一的协程间通信对象)
- defer: 常用于释放资源、panic 处理
- make: 申请切片、map 和 channel 的空间
- init 方法: 被引用的时候,包内的所有 init 方法会自动执行。单个包内的 init 方法执行顺序按 文件名字段序 -> 方法从上到下 的顺序执行,参考
- 声明对象的方式: 通过 var 指定对象名称和类型,或直接 a := 1,编译器自动识别字段类型
- const: 声明常量
- iota: 枚举,只能是数值
- 空白标识符: 下划线(_),可用于忽略返回值,迭代 slice 或者 map 时忽略 下标/key,以及 init import(只执行包的 init 方法,不需要显式调用包的资源,如: import _ “net/http/pprof”)
- select case: 多个 Channel 同时读取方式
- 总共只有[25个关键字](https://articles.wesionary.team/know-about-25-keywords-in-go-eca109855d4d),相比: C99 有 37 个,C++11 有 84 个
原生库和方法
- time: 时间,方法有 time.Parse, time.Now, time.DateTime(常量 2006-01-02 15:04:05)等
- io.ReadAll: 数据流
- bytes.Buffer: 字符串缓冲
- strings、maps、slices: 集合类型的工具方法,如 strings.ReplaceAll、maps.Clone、slices.Sort 等
- regexp: 正则
- net/http: http 核心库
- sort: 1.19 之前的数组排序库
- log/slog: 1.21 新增的日志库,支持等级和格式化打印
- sync: 协程之间同步、状态共享的相关组件库。Mutex: 锁;Once: 只执行一次;WaitGroup: 等待n个协程执行;Pool: 协程间复用对象;Cond: 等待和唤醒
反射
- reflect.TypeOf: 获取对象的具体类型
- reflect.Kind: 获取对象的类别(和类型的区别: 具体值或指针的类别为 interface / pointer,类型可以拿到具体的 struct或接口类型)
- reflect.ValueOf: 获取对象的具体值
- struct tag: 标注 struct 内属性的附加信息,一般用于 json序列化、yaml 内容解析、orm 字段映射等场景
并发
- 协程(Routine): 用户层的“线程”,通过 go func() 开启并发
- 管道(Channel): 协程间的通信方式
- 上下文(Context): 协程间传递数据、父协程控制子协程状态的媒介
运行时(Runtime)
- GPM: Go 进程的核心,协程(Goroutine)、处理器(Processor)、系统线程(Machine)
- GC: 三色标记法、混合写屏障等
包管理
- 从 git 路径引用依赖,没有“官方仓库”的说法,去中心化的设计
- 以 git tag 或者 commit id 作为版本标识
- 对象和方法是否对外可见,通过首字母大小写来标识,大写为开放,简单明了
工具
- gofmt、goformat、staticcheck: 代码格式化
- test、bench、fuzz: 普通测试、并发测试、混沌测试
- doc: 文档,go 的文档可在源码中通过注释编写,并自动生成
以上就是自己常接触的原生库了,可以从 go源码的src目录 更多的实现细节
自己写的和go有关的博客
golang 编程规范查漏补缺
golang-使用 go test 输出单元测试覆盖率
golang-单元测试和mock框架的介绍和推荐
golang-使用 godoc 工具编写代码注释
golang-文章翻译-go高效编程
golang-文章翻译-go常见的10种错误
vscode 使用技巧(vscode+go插件的开发环境)
go 学习方法总结
官网
Go 的官网其实是最好的学习资料,教程、博客、社区动态都有,绝对适合作为入门资料的第一位
下面说明官网中右上角各个栏目的内容
为什么使用 Go(Why Go)
大体就是 Go 在一些通用领域的使用场景,以及在大厂的使用情况
Case Studies: 大厂的使用场景,如 Google、CloudFare、Meta、Netflix 等
Use Cases: 在云服务、网络通信、命令行工具、网页/客户端应用 和 运维和可持续开发(DevOps、SRE)领域的应用
每一个领域下都有比较流行的开源项目的推荐
Security: 如何提升自己工程的安全性,如通过 govulncheck 检查项目存在哪些已知漏洞
Learn
非常适合上手的 go tour,几乎覆盖了 go,可以说练习完所有示例就会写 go 代码了
Docs
所有官方文章: 可以挑讲原理的文章看,如 Using and understanding Go 中的 A Guide to the Go Garbage Collector 以及 References 中的 The Go Memory Model
Effective Go: 上手之后,进一步了解 go 编程风格的必读文章
std: 标准库文档
faq: 囊括了从其他语言迁到 go 语言的常见问题,也体现了 go 的设计思想
社区
blog: go 博客,社区新动态
开源项目和代码推荐
go
go 本身的源码就很好阅读,也和 go 本身语法比较简洁有关。如果你想了解 go 的基础库的原理,大可不用搜一堆博客,一点点地消化别人的总结,读go源码就是最好的学习go原理的方法
包括: sync, runtime, context, reflect,这些都是 go 的核心库
web 应用
开发后台必须要掌握的就是 web 框架,当然不同公司对它的定制化也会不同,如果想从简单的入手,使用官方推荐的 gin 就行。想参考大厂实际用的,可参考国内开发者开源的 web 框架(功能比较全),如字节的 hertz、go-zero、goframe 等
中间件
gorm: 数据库 orm 库
redis: redigo
kafka: sarama
云原生和监控
如 Kubernetes、Istio、Prometheus、Grafana 等,也能接触到当下比较流行的项目
命令行工具
以往我们需要用工具进行文档格式转换、爬虫、文件批量下载等场景,可能会主要以 python 项目作参考,因为它语法简单,执行方便,你需要的只是一个 python 环境
现在,拥有类似特性的 go 让我们多了一个选项,同样的需求,也可以看 go 社区有没有现成的方案。甚至 go 只需要编译好的可执行文件,更加方便
具体用哪个工具因需求而异,可以参考别人的整理,这里列几个可能比较常用的:
hugo: 博客网站生成,类似 hexo
buffalo: 快速生成 web 项目
vhs: 终端录制
pget: 并发下载
fsnotify: 系统文件监听
lux: 网站视频下载工具(不能下载需要登录才能下的超高画质)
migrate: 跨不同类型数据库迁移
博客推荐
golang 在国内大厂实践还是比较多的,因此国内开发者写的博客也不会缺少。本着技术的学习方法来说,这里推荐两个博主 分别对应前沿动态,和深度剖析原理
煎鱼: go 语言开发者,对 go 社区动态、新版本特性的跟踪比较及时,类似的博主还有 polarisxu
go语言设计与实现: go 原理和设计思想,这个博客对技术的思考方式值得应用到所有技术的学习上: 从为什么这么设计的问题基础上,去理解技术实现细节
相关文章:

go 语言介绍
背景 一直有在零散的时间用go写点代码,正好借着最近比较有时间写东西的契机,给这个看着年轻,实际也已经发展10几年,并在当下众多开发领域都有不可忽视作用的语言做个介绍吧 golang 的起点 golang 的诞生可以说是时代造就了它&a…...

查询平均提速 700%,奇安信基于 Apache Doris 升级日志安全分析系统
本文导读: 数智时代的到来使网络安全成为了不可忽视的重要领域。奇安信作为一家领先的网络安全解决方案领军者,致力于为企业提供先进全面的网络安全保护,其日志分析系统在网络安全中发挥着关键作用,通过对运行日志数据的深入分析…...

Linux越学越头疼,我要怎么办?
最近,听到一些同学说,“Linux越学越头疼”。其实这句话,在我之前刚接触Linux的时候,也是深有感触。Linux越学越不明所以。最后干脆放弃学习,转而学习其他东西。 其实大家在初学Linux的时候, 有这个感受&am…...

使用Fiddler进行Mock测试
1、接口抓包 找到要mock的接口,打开fiddler抓包 以某某接口为例,找到下面的接口 http://XXX/SYSTEMS 2、复制该接口数据到本地 在接口上进行右键点击,选择save -> …and Open as Local File -> 默认会保存至桌面,示例中的数…...

js字符串支持多个分隔符分割
js字符串支持多个分隔符分割 场景代码 场景 用户输入内容后,支持多个分隔符(比如:中英文逗号,分号以及换号)对字符串进行分割,之后提交给后台同学解析。 代码 function splitString(inputString, separat…...

ajax-axios发送 get请求 或者 发送post请求带有请求体参数
/* axios v0.21.1 | (c) 2020 by Matt Zabriskie */ !function(e,t){"object"typeof exports&&"object"typeof module?module.exportst():"function"typeof define&&define.amd?define([],t):"object"typeof export…...
C++ 单例模式
C 单例模式跟Java中的单例模式没什么区别 什么是单例? 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 什么时候使用单例 1个类里面的方法要在很多地方都使用到的时候建议使用单例。 单例的3个步骤,也是判断是否是单例…...

apache seatunnel支持hive jdbc
上传hive jdbc包HiveJDBC42.jar到seatunel lib安装目录 原因是cloudera 实现了add batch方法 创建seatunnel任务文件mysql2hivejdbc.conf env {execution.parallelism = 2job.mode = "BATCH"checkpoint.interval = 10000 } source {Jdbc {url = "jdbc:mysql:/…...

【Git企业开发】第四节.Git的分支管理策略和bug分支
文章目录 前言一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 1.2 企业分支管理策略二、bug分支三、删除临时分支四、总结总结 前言 一、Git的分支管理策略 1.1 Fast forward 模式和--no-ff 模式 通常合并分支时,如果可能,Git 会…...

玩转硬件之Micro:bit的玩法(四)——声控灯
智能家居的普及在近几年来呈现出了爆发式的增长。随着科技的不断进步和人们对便利生活的追求,越来越多的家庭开始采用智能家居系统,使生活更加智能化、便捷化。 智能家居的普及不仅改变了人们的生活方式,也为家庭带来了更多的便利和舒适。现…...

STM32-创建项目流程
一、基于STM官网得库进行开发 准备工作:下载STM库文件 1、创建项目文件夹 2、在keil 中new uVision project,然后选择刚刚创建得文件夹,在文件夹里面创建一个文件,用来存放这个项目,然后在文件夹里面,写个文件名&am…...

软件测试 —— 移动端测试
1. 移动端 指移动设备(如智能手机、平板电脑、智能手表等)上的操作系统和应用程序。移动设备具有便携性和多功能性,可以随时随地连接互联网,提供丰富的应用和服务。 2. 移动端应用分类 (1) 原生应用(Native App&…...
PCL 计算一个平面与一个三角形的交线
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里实现一个很有趣的功能,就是获取一个平面与一个三角形的交线,具体的思路很简单,就是借助之前的博客中的思路:Matlab 计算一个平面与一条线段的交点,我们只需要遍历三角形中的所有边即可获取我们想要的交线,…...

Redis 应用问题
1-缓存穿透 1.1-问题描述 Key 对应的数据在数据源并不存在,每次针对此 Key 的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。 比如:用一个不存在的用户ID 获取用户信息,不论缓存还是数据库都没有&…...

Java 谈谈你对OOM的认识
文章目录 前言一、基础架构二、常见OOM1、栈内存溢出java.lang.StackOverflowError2、堆内存溢出java.lang.OutOfMemoryError:Java heap space3、GC回收时间过长java.lang.OutOfMemoryError: GC overhead limit exceeded4、NIO程序堆外内存溢出java.lang.OutOfMemor…...

JavaScript中BOM与DOM
BOM window对象 所有的浏览器都支持window对象,他表示浏览器窗口, 所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。 全局变量是 window 对象的属性。全局函数是 window 对象的方法。 接下来要讲的HTML DOM 的 document 也是…...

Nginx域名重定向(如何访问的域名和实际的数据请求路径不同,可解决前端跨域)
感情需要被抑制,不能泛滥… 当需要将一个域名重定向到另一个域名并且用户仍然看到原始域名时,Nginx是一个强大的工具。这种场景通常涉及到反向代理或重写URL的技巧。在本篇博客中,我们将详细介绍如何使用Nginx来实现这个目标,以及…...

2023年11月2日历史上的今天大事件早读
1082年11月02日宋徽宗出生 1861年11月02日辛酉政变 1910年11月02日中国社会学家和人类学家费孝通诞生 1910年11月02日畜生态学科的创始人汤逸人诞生 1917年11月02日《贝尔福宣言》和犹太复国主义 1917年11月02日美日订立“兰辛—石井协定”损害中国利益 1937年11月02日忻…...
红帽Redhat--Ansible实战1
在运行Windows操作系统的主机LAPTOP-OUR52V78上安装有VMware Workstation Player软件。因为Windows自带的虚拟机平台软件"Hyper-V"使用难度较大,而且关于在"Hyper-V"上运行虚拟机,修改虚拟机错误的相关技术博客和文章的数量稀少&…...
213. 打家劫舍 II
你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...