可以解决的问题 🔗
遇到过的 bug
- golang 中数组和切片的区别,数组是值类型,函数传参数时是拷贝一个副本。
- init() 函数滥用
- 函数功能是查询类的,能不用指针传参数就不用,避免函数内部对 对象做修改
- 代码里不要吞掉任何一个错误
- first path segment in URL cannot contain colon 原因:字符串 http 前面多了空格,post 请求在本地就会失败
- err:crypto/cipher: input not full blocks
- AES 加密后的数据存入 mysql 时,由于字段有长度限制, 加密后的内容被截断了,所以 AES 解密时爆出这个 panic
- 问题排查 http
- 499 对应的是 “client has closed connection”。这很有可能是因为服务器端处理的时间过长,客户端主动关闭
- 字段总结 remote_addr, x_forwarded_for
- kafka: the provided member is not known in the current generation kafka
- rebalance
- signal.Notify(signals) (Notify 使用时需要指定接收信号的类型), 这种写法 <-signals 可以接收 os 发的 64 种信号, 其中 broken pipe signal 导致进程主进程结束
- 本质是 IOError 错误, 读写文件 IO 和网络 Socket IO
- 管道存在上游发送数据的进程,下游读取数据的进程,在下游不再需要读取上游数据的时候,就会发送 SIGPIPE 信号给上游进程
- Broken Pipe 是可以忽略
- .ignore 文件中配置 dubug,导致忽略了 vendor 里的 dubug 包,导致本地编译通过,但是远程 scm 编译失败
- brew upgrade go && should modify .zshrc
- ss -l 看到主机上的端口在使用, lsof -i:port 没有发现使用这个端口的进程
- Unix domain socket 同一台操作系统上的两个或多个进程进行数据通信 跨进程通信
- 使用 循环迭代器变量的引用, 大概率全部遍历的都是迭代的最后一个元素
- es 使用上坑很多
- script 方式更新文档时,字符串需要额外添加`"'" +str + "'"``
- 不指定返回条数,默认只会回 10 条
未解决的问题 🔗
- 构建 go module 项目时,go get github.com/xxx 后,在 nvim 中 出现 no required module privides package xxx
- 但是可以 go run 起来,之后换成 go get -u github.com/xxx 之后,重启 nvim 就没有出现这个问题了, 所以问题是哪儿,在这里 mark 一下。
gopls 插件占用内存过大, 不能忍受。
unsolved: 阅读go源码时,执行单测出现: use of internal package internal/byteal not allowed
cannot solve
Failed to run "go env env,-json,GOMOD": Command failed: /usr/local/go/bin/go env -json GOMOD $GOPATH/go.mod exists but should not
2022-09-12 晚。
在 golang 源码里点击跳转到定义,却是跳转到 golang 安装目录下的源代码,而不是本项目原有的文件夹下
怎样在 vs code 下阅读 golang 的源代码?
https://stackoverflow.com/questions/58018729/go-linter-in-vs-code-not-working-for-packages-across-multiple-files
could not import fmt (cannot find package "fmt" in any of
/usr/local/go/src/fmt (from $GOROOT)
/Users/brett/go/src/fmt (from $GOPATH))compilerBrokenImport
$ code $GOROOT
No package found for open file, go/src/cmd/compile/main.go
容器中运行 go 程序 🔗
runtime/cgo: pthread_create failed: Operation not permitted #467 🔗
docker run --privileged
单测 🔗
单测 mock 框架,测试框架 stub/mock
- GoConvey https://github.com/smartystreets/goconvey
- Convey, so, 不是很习惯
- testify https://github.com/stretchr/testify
- GoStub
- GoMock
- https://bou.ke/
- copy 覆盖函数的前 12 个字节的汇编代码,植入 mock 函数的地址, 在运行时实现函数的 mock 和 unmock
- github.com/bouk/monkey
官方测试工具 gomock 🔗
install: go get github.com/golang/mock/gomock, github.com/golang/mock/mockgen.
工具 🔗
- Guru 导航 go 代码的编辑器集成工具
- 变量,函数的声明地点
- 变量,函数的所有引用地点
- 实现此接口的所有具体类型
- golang.org/x/tools/cmd/guru
go monkey 🔗
package main
func from() int {return 1}
func to() int (return 2)
func main() {
// 在执行from之前把from函数内的机器码 替换为一条跳转指令,让cpu跳转到to函数的机器码上执行。
patch(from, to)
fmt.Println(from()) // should print 2
}
taoshu.in/go/monkey
- 找到 from, to 的内存地址
- 修改 from 函数的机器码,构造跳转指令,跳到 to 的内存地址上
调试 🔗
- delve 调试工具
- gdb 单步调试 go 程序的执行过程 Delve 更好
- 执行某个单测函数 go test -run TestDefine ./compiler
性能分析 🔗
利用 runtime/pprof, net/http/pprof 采集运行时数据
-
pprof (CPU profiles, Heap profiles, block profile, traces)
- kite, ginex 框架开启了 prof 功能
- 定时任务,消费者等 worker 需要 import _ net/http/pprof 手动开启
- 性能 pprof
- go tool pprof http://localhost:8080/debug/pprof/profile
- http://127.0.0.1:8080/debug/pprof/heap?debug=1
- 终端连接到 go tool pprof -inuse_space http://127.0.0.1:8080/debug/pprof/heap
- svg go tool pprof -alloc_space -cum -svg http://127.0.0.1:8080/debug/pprof/heap > heap.svg
-
wrk 压力测试 github.com/juju/ratelimit
-
优化 go 程序 运行速度的方向 只对关键的路径进行优化 (优化运行速度,开会速度会慢 hah)
- 避免堆分配可以成为优化的主要方向。 若频繁使用堆,可以 sync.Pool 复用对象
- cpu cache line(64 字节),结构体填充,避免 False Sharing。
- 为了保证 cache 的一致性,对内存的一个小小的写入都会让 cache line 被淘汰。
- 对相邻地址的读操作就无法命中对应的 cache line。