-
Go 1.20 的 errors.Join 可以把多条错误合并为一个错误值,同时保留 errors.Is 和 errors.As 的判断能力。本文用批量关闭资源、并行任务汇总等场景说明该怎么用,以及哪些时候不该把错误一股脑拼在一起。
-
Go语言通过go.mod声明和gob工具实现版本兼容与切换。首先检查go.mod中的Go版本,确保构建语义一致;如需新特性可手动升级版本号并测试影响。使用goblist、install、set命令管理多版本,实现项目级Go版本隔离。通过GOROOT和PATH临时切换环境适用于CI或调试场景。依赖问题可通过gomodtidy修复,替换过时import路径,使用replace指令锁定稳定版本。Go的向后兼容性保障了旧项目在新环境中通常只需少量调整即可运行,关键在于合理管理版本声明与依赖关系。
-
不能直接用map做多引擎缓存统一接口,因其内存独占、无生命周期管理、不支持序列化/持久化,且无法对接Redis、Badger等外部引擎;核心矛盾是各后端读写语义不一致,强行抽象易致类型断言或panic。
-
Go1.14+默认不自动使用vendor目录,需显式指定-mod=vendor;gomodvendor可能遗漏隐式依赖,应清理后配合gomodtidy重生成;离线构建必须设置GOPROXY=off、GOSUMDB=off,并确保根目录go.mod和go.sum完整。
-
slice本身不会泄露,但其Data指针会“钉住”整个底层数组,导致本该被GC回收的大块内存长期驻留;根本原因是SliceHeader中Data指针存在即视为整块底层数组仍在使用,哪怕仅取s[i:j]并存入context或缓存,几MB原始数组也无法释放。
-
Go 服务把审计日志同步写进一个文件后,吞吐上不去、磁盘抖动还会拖慢请求。本文用分片队列和批量落盘拆开写入压力,并验证顺序、重放与停机收尾。
-
不会——http.ServeFile默认Content-Disposition为inline,浏览器可能直接打开而非下载;需手动设置attachment头,且必须校验路径防遍历,推荐用ServeContent替代以支持断点续传和缓存控制。
-
gotest需确保模块初始化、测试文件以_test.go结尾、函数名以Test开头且参数为*testing.T;推荐表格驱动测试、接口抽象mock外部依赖,并注重边界覆盖与可维护性。
-
Go事务不会自动回滚,必须显式调用tx.Rollback()或tx.Commit(),否则事务持续挂起导致锁表、阻塞查询;推荐用defer+committed标志位精准控制回滚,避免重复回滚报错。
-
ast.Inspect遍历需先判空再访问Params/Results,init函数名特殊,返回false可提前退出,节点只读不可修改;它比手写递归更全、更稳、不栈溢出。
-
Gochannel不支持广播,扇出需显式复制消息到多个独立channel;直接多goroutine读同一channel会导致竞态、丢数据或deadlock;正确做法是用分发goroutine从源channel读一次并复制发送至多个目标channel。
-
因为atomic.CompareAndSwapUint32不记录持有者ID、不支持重入计数,同一线程重复加锁必死锁;它仅比对数值,无法区分“谁设置”,且无退避机制易致CPU空转100%。
-
在使用Go语言的time包实现定时任务时,应避免以下易错点:1.误用time.Sleep(),应使用time.Ticker以确保任务执行频率不受影响;2.使用带超时的select语句防止任务执行过慢;3.正确使用time.Timer,记得重置以实现重复执行;4.处理时间区间时,使用第三方库如cron以避免夏令时或时区变更问题。
-
滑动窗口不能只用ZREMRANGEBYSCORE清旧数据,因ZSET不保证原子性:清理与计数分离会导致并发插入漏判超限;必须用Lua脚本将ZREMRANGEBYSCORE、ZCARD和ZADD三步封装为原子操作。
-
QPS上不去主因是http.DefaultClient的Transport连接池参数过于保守,MaxConnsPerHost默认仅2,导致并发请求阻塞;需新建Client并调大MaxConnsPerHost、MaxIdleConns等参数,配合Ticker限速、ulimit调优及Context超时控制。