-
sync.OnceValue 会把初始化函数的返回值复用给后续调用,因此承载在返回值里的 error 也可能被持续复用。本文区分错误返回与 panic,给出显式重建 getter 和自定义可重试状态两种恢复策略,并说明并发交换与失败风暴边界。
-
sync.RWMutex 不支持把 RLock 升级为 Lock,读锁未释放时申请写锁会等待自己释放读锁而形成阻塞。本文用原创代码对比拆分读写临界区与直接使用单写锁的改造方案,并说明重新检查、锁复制和对象生命周期边界。
-
结构体里放入 sync.Mutex 后,按值传参、赋值或返回都会复制锁的内部状态,可能造成异常解锁、数据竞争和锁失去保护对象。本文从根因、错误写法、指针改造和 go vet copylocks 检查四个方面说明安全设计方式。
-
使用 sync.WaitGroup 收尾并发任务时,关键不是把 Wait 放在最后,而是保证任务计数先建立、空 WaitGroup 上的 Go 先于 Wait,并在复用前等上一轮 Wait 返回。本文对比 WaitGroup.Go 与 Add/Done 的调用顺序,给出一份可直接落地的并发收尾写法。
-
sync.Pool 取出的对象带着上一次请求的字段时,问题通常不是 Pool 失效,而是复用对象没有在交接边界清理。本文从临时对象契约、Reset 设计、Get/Put 时机和不适合放入 Pool 的状态四个方面,整理一套可落地的排查方式。
-
sync.Cond 出现等待不返回时,先检查共享条件是否由同一把锁保护,再确认 Wait 是否位于 for 循环中。本文用原创 Go 示例拆开 Signal、Broadcast、条件状态与 channel 的适用边界,帮助定位所谓的唤醒丢失。
-
context.WithValue 出现字段覆盖时,通常不是值被修改,而是相同键在父子 Context 中发生遮蔽。本文用包内私有键类型和类型安全访问器规避跨包冲突。
-
Go 的 ctx.Err() 只能告诉你已取消或已超时,context.Cause(ctx) 才能携带主动取消的具体原因。本文用原创示例拆开主动取消、超时取消和父子上下文竞争时的判断方式。
-
Go 的 context.AfterFunc 回调是在上下文取消后异步启动的,stop 返回 true 才表示回调被阻止;返回 false 不等于回调已经完成。本文按取消、停止和完成三个时刻拆解排查方法,并给出可等待回调收尾的写法。
-
Go net/http 中,响应 Trailer 不是普通响应头,服务端要在写出响应前声明尾部字段,客户端还要先把 Response.Body 读到 EOF 才能读取最终 Trailer。本文解释声明顺序、读取时机与为空排查方法。
-
Go net/http 中,ReadHeaderTimeout 只限制请求头,读取请求体要用 ReadTimeout 或按请求设置 ResponseController.SetReadDeadline。本文给出慢上传、超大请求、客户端断开和 HTTP/1.1 连接关闭的处理方式。
-
Go net/http 的请求体是一次性读取资源。Client.Do 会关闭请求体,关闭 TCP 连接也不会把 Body 重置;需要重试或重定向时,应保存原始数据、重新创建 Request,或确保 GetBody 能返回新的读取器。
-
unsafe.Slice 的 len 参数决定返回切片的长度和容量,计算时若混用元素数与字节数,或发生整数溢出,就可能把访问范围带出原始对象。本文按指针来源、Sizeof 换算、nil 特例和边界测试逐步定位并修正。
-
Go 包迁移时,type A = B 只增加一个兼容名称,不会创建新类型,因此 reflect.Type 的 Name 和 PkgPath 仍然对应原定义类型。本文用一个小项目区分类型别名与类型定义,并给出以 reflect.Type 身份比较替代字符串判断的兼容方案。
-
go build -trimpath 会移除可执行文件中的本机文件系统路径,但不会自动删除调试符号。本文用最小示例拆解它对堆栈、源码导航、CI 可复现构建和生产发布的影响,并给出按场景选择构建参数的方法。