一、需要认识的单词:
word | 说明 | word | 说明 |
---|---|---|---|
instrument | 仪器,工具 | primitives | 原语 |
multiplexing | 多路器 | communicating sequential processes | 基于通信的顺序进程 |
implements | 执行, 履行 | ||
explicit | 明确的,清楚的 | ||
mux *ServeMux | 服务多路器 | ||
wrap | 包裹 | ||
retention | 保留 | ||
fanout | 展开 分列 | ||
retrieval | 检索 取回 | ||
seek | 寻找 搜索 | ||
peek | 窥视 读取数据 |
二、常用操作集合
【极力推荐,所有相关的快速操作 应有尽有】
【知识图谱】【教科书】【基本概念及用例】
【包设计哲学-原则与项目结构组织最佳实践】
【字符串常用操作】
【A golang http request library for humans】
【map实现set,封装接口】【map实现set】
【JSON数据相互转换】 【json的原理及使用方法】
【string、int、float相互转换】 【字符串操作以及与其它类型的转换】
【写工程,必须打好日志啊】 【beego的日志】 【所有的程序中必须使用log】
【时间差、当前时间秒/毫秒/纳秒数以及几天前/后、几小时前/后、几分钟前/后、几秒前/后的时间】
【用gin写接口,开发文档】【配上几个讲解视频,美滋滋】
【gin-vue-admin 量化生产管理代码,不会写没关系,跟着点点就行了】
【websocket】
【estic官方】【estic路人】
【性能调试:分析并优化 Go 程序】
【异常封装处理】
【文件拷贝】【文件读写】
【Go原生提供了连接数据库操作的支持】【gorm】
【Go原生强大的网络包】
【命名规范】
【sync的几个操作】
【Viper-Go一站式配置管理工具】 【flag->kingpin->cobra->viper处理命令行参数和配置文件的库】
【ants是一个高性能的 goroutine 池】
【Casbin 强大的、高效的开源访问控制框架,casbin只负责访问控制】【jwt鉴权=json web token,明白了】
【go test 完美解读版】
三、go tool
会生成可执行文件直接放到bin目录下,当然这是有前提的
你编译的是可执行文件,如果是一个普通的包,会被编译生成到pkg目录下该文件是.a结尾
- go的安装和升级
【安装源】
【升级方法】 - 包依赖管理工具
1.14了直接go mod,通过go mod下载的依赖包,看看官方最佳建议
不在放在GOPATH/src中,而是放到GOPATH/pkg/mod中 - 参考:
go mod文件中的语义版本标记
mod高级操作
关于Go Modules,看这一篇文章就够了
四、tips:
-
deep comparion(reflect.DeepEqual)
-
Function vs Receiver
-
Interface Partterns, program to an interface not an implemention(用embedded的方式删除冗余代码)
-
performance
itoa > Sprint 减少string 转换 byte 避免string拼接 并行 sync.WaitGroup 热点内存分配sync.Pool 磁盘大量读写bufio 正则不要重复compile protobuf 替代json map的key尽量用int
-
IoC业务逻辑依赖控制逻辑
-
错误处理的方式有多种,原则(可读性强)
-
SplitConfig, Function Option (可读性强 扩展性好)
-
Map/Reduce/Filter (最终类似SQL)
-
设计模式(装饰、管道、观察者)
-
syntax error: non-declaration statement outside function body
原因在于 := 只能用于方法内,当定义全局变量时只能通过 var 关键字来定义
分析:因为你在函数体外给赋值了,go语言有闭包原则,还有它的变量命名规则,导致你的赋值函数体没有办法使用,所以才会报错 -
可变参数函数
-
匿名函数和闭包是一个概念
- 通过闭包来使用 匿名函数 - 这个函数的值包含了自己的值 i,这个状态对于这个特定的函数是唯一的 - Go语言支持匿名函数,即函数可以像普通变量一样被传递或使用 - 闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者 任何全局上下文中定义, 而是在定义代码块的环境中定义。要执行的代码块(由于自由变量包含 在代码块中,所以这些自由变量以及它们引 用的对象没有被释放)为自由变量提供绑定的计算环境作用域)。 - 闭包的价值 闭包的价值在于可以作为函数对象或者匿名函数,对于类型系统而言,这意味着不仅要表示 数据还要 表示代码。支持闭包的多数语言都将函数作为第一级对象,就是说这些函数可以存储到 变量中作为参数传递给其 他函数,最重要的是能够被函数动态创建和返回。、 - Go语言中的闭包同样也会引用到函数外的变量。闭包的实现确保只要闭包还被使用,那么被闭包引用的变量会一直存在
func test() { a := 5 b := func()(func()){ c := 10 return func() { fmt.Printf("a,c: %d,%d \n",a,c) a *= 3 } }() b() println(a) } 输出: a,c: 5,10 15 注意: 1、匿名函数的返回值是一个匿名函数,return返回的是一个匿名函数,注意没有加(),所以是用return接收。 2、然后在最外层是加了()的。所以将匿名函数的值给了b。注意了此时的b其实是一个函数。所以下面在使用的时候是b()。 你可以尝试将匿名函数的最外层的()去掉,然后看一下b()打印的值是什么,在试一下b()()打印的值是什么。 3、a在匿名函数内是可以引用的,但是你如果在匿名函数外引用c,你会发现找不到。 并且在闭包内改变了a的值也是会作用到a真实的内存地址中的。
-
回调
函数可以作为其它函数的参数进行传递,然后在其它函数内调用执行,一般称之为回调 -
Go 自动处理方法调用时的值和指针之间的转化。你可以使用指针来调用方法来避免在方法调用时产生一个拷贝,或者让方法能够改变接受的数据
这种回调的方式,使用场景在于多个方法之间形成调用链,下一个方法依赖上一个方法的某些值的时候, 相当于callback是第一个方法,add是第二个方法,add方法需要依赖callback方法中的某些中间值 package main import "fmt" func main() { callback(4,add) } func add(a,b int) { fmt.Print(a+b) } func callback(c int, f func(int, int)) { f(c,c) }
-
接口 是方法特征的命名集合
结构体类型 circle 和 rect 都实现了 geometry接口,所以我们可以使用它们的实例作为 measure 的参数。 -
Go 的通道选择器 让你可以同时等待多个通道操作。
-
Go 协程+通道+选择器+超时处理是 Go 的一个强大特性。
-
定时器 定时器表示在未来某一时刻的独立事件。你告诉定时器需要等待的时间,然后它将提供一个用于通知的通道
定时器是有用原因之一就是你可以在定时器失效之前,取消这个定时器。 -
打点器 在固定的时间间隔重复执行
-
工作池
速率限制 Go 通过 Go 协程、通道和打点器优美的支持了速率限制 -
goroutine 有for循环 为了确保这个 Go 协程不会在调度中饿死,我们在每次操作后明确的使用 runtime.Gosched()进行释放
-
基于通道的方法、每个 Go 协程间通过通讯来共享内存,确保每块数据有单独的 Go 协程所有的思路是一致的
-
使用函数自定义排序,让自定义的结构体类型实现某个排序方法
-
组合函数 我们经常需要程序在数据集上执行操作,比如选择满足给定条件的所有项,或者将所有的项通过一个自定义函数映射到一个新的集合上
-
在接收者是指针时,方法可以改变接收者的值(或状态)
-
字符串格式化
-
数字解析 内置的 strconv 包 Atoi / ParseInt …
-
正则
-
json
-
时间 方法 Sub 返回一个 Duration 来表示两个时间点的间隔
使用 Add 将时间后移一个时间间隔,或者使用一个 - 来将时间前移一个时间间隔 -
时间戳 Unix 时间的秒数
时间的格式化和解析 Format 和 Parse -
随机数 math/rand 包
如果你出于加密目的,需要使用随机数的话,请使用 crypto/rand 包 -
URL解析 内置的处理包
-
SHA1散列 Go 在多个 crypto/* 包中实现了一系列散列函数
-
Go 默认使用按值传递来传递参数,也就是传递参数的副本
-
base64 编解码 内建支持 encoding/base64 标准 base64 编码和 URL 兼容 base64 编码的编码字符串存在稍许不同(后缀为 + 和 -),但是两者都可以正确解码为原始字符串。
-
行过滤器 对 os.Stdin 使用一个带缓冲的 scanner,让我们可以直接使用方便的 Scan 方法来直接读取一行,每次调用该方法可以让 scanner 读取下一行
-
命令行参数
-
命令行标志:注意,flag 包需要所有的标志出现位置参数之前(否则,这个标志将会被解析为位置参数)
-
在编译时用ldflags设置变量的值
-
环境变量
-
生成进程 执行进程 exec
-
Unix 信号
由于 SIGINT, SIGTERM 都是可以被捕获的,也就是会执行信号处理函数的,故按照信号处理函数逻辑,可能进程不会退出,即不一定能终止,所以要处理好exit(0) -
append函数返回值必须有变量接收的原因
当它改变传入的slice变量的信息,原slice变量并不会有任何变化,打印原slice变量和之前也会一模一样。 该函数会返回修改后的slice变量,因为原slice并不会变,假如没有任何slice变量接收返回的值,那么此次append操作就没有意义了。 所以必须要有slice变量重新接收修改后的slice变量,不然编译器会报错。 Go不希望你做无意义的事,就像导入的包或定义的变量没有用上,它也会报错。
五、工程效能思考
【原生log的使用和实现原理,最重要的是它的扩展性引发的第三方库logurs】
【原生error的使用和实现原理,最重要的是它的扩展性引发的第三方库github.com/pkg/errors】
【原生flag的使用和实现原理,最重要的是它的扩展性引发的第三方库kingpin->cobra->viper】
【原生goroutine的使用和实现原理,github.com/oklog/run编排,组合多个相对独立又相互关联的协程】