RSS
菜单
社区成员个人主页
阿成员
DEV CN / 成员主页

阿青 · 社区话题账号

查看阿青 · 社区话题账号发布的技术文章、关注圈子与公开讨论。

0技术文章4关注圈子470圈内发布1关注者
COMMUNITY POSTS

交流圈发布内容

作者在不同技术圈子中的观点与讨论

1
# Golang

Go sync.Once 怎么用?并发安全的单例初始化实现

sync.Once 保证某个函数只执行一次(并发安全),用于单例初始化、懒加载配置、只注册一次的全局操作:var once sync.Once; once.Do(func() { initSomething() })。即使多个 goroutine 同时调用 Do,函数也只执行一次,其他 goroutine 等待完成。内部实现:原子标志 + Mutex + 双重检查。注意:Once 不可复制;Do 内函数 panic 后 once 状态仍…

2
# Golang

Go sync.Map 详解:适用场景、性能对比与 API 用法

sync.Map 是并发安全 map,内部用读写分离(原子读 map + 脏 map + miss 计数)优化。适用场景:① 读多写少且 key 稳定;② 不同 goroutine 操作不同 key(避免锁竞争);③ 只增不减的场景。不适用:频繁写/删除(性能可能低于 Mutex+map)。API:Load、Store、LoadOrStore、Delete、Range(遍历回调)。注意:Range 遍历顺序随机;无 Len 方法(需 R…

3
# Golang

Go sync/atomic 原子操作:与 Mutex 的区别及适用场景

sync/atomic 提供原子操作:AddInt64、Load/Store、CompareAndSwap(CAS)、Swap、指针操作,用于无锁的计数器、标志位、状态机。与锁的区别:atomic 是硬件级单指令原子性,无阻塞、开销小(纳秒级),但只能做简单操作;锁可保护任意代码块。选择:计数、开关、状态切换用 atomic;复杂临界区用 Mutex。注意:atomic 要求 64 位对齐(32 位平台注意);Go 1.19+ 有 at…

4
# Golang

Go 数据竞争是什么?-race 检测与四种避免方案

数据竞争:多个 goroutine 同时访问同一内存,至少一个是写操作且无同步机制,结果不确定、可能崩溃(Go 1.6+ 会报 fatal error)。检测:go test -race / go run -race 运行时报告竞争位置。避免:① Mutex/RWMutex 保护共享数据;② channel 传值替代共享;③ atomic 包原子操作(计数器、标志位);④ 每 goroutine 用局部变量不共享;⑤ 只读数据安全共享。…

5
# Golang

Go Mutex 与 RWMutex:互斥锁和读写锁怎么选?锁粒度优化

sync.Mutex 互斥锁:Lock/Unlock,同一时刻只允许一个 goroutine 进入临界区,防止数据竞争。sync.RWMutex 读写锁:RLock/RUnlock 允许多个读并发,Lock/Unlock 写独占(写时阻塞所有读写)。选择:读多写少用 RWMutex 提高并发度;写多或读写均衡用 Mutex(RWMutex 有额外开销)。规范:锁粒度要小(尽量只包临界区)、Lock 后必须 Unlock(defer 或成…

6
# Golang

Go sync.WaitGroup 怎么用?Add/Done/Wait 的正确姿势与注意事项

WaitGroup 等待一组 goroutine 完成:wg.Add(n) 计数、wg.Done() 减一(defer wg.Done())、wg.Wait() 阻塞到计数归零。注意事项:① Add 必须在 Wait 之前且与 goroutine 数一致;② 不要在 goroutine 内调用 Add(可能 Wait 已开始导致竞态);③ Done 要保证执行(defer);④ WaitGroup 不可复制(传指针);⑤ 计数不能为负(…

7
# Golang

Go select 用法详解:多 channel 监听、随机选择与超时控制

select 同时监听多个 channel 操作(发送/接收),任一就绪执行对应 case;多个同时就绪时**随机**选一个(公平性,避免饿死);无 case 就绪且有 default 执行 default(非阻塞尝试);无 default 则阻塞等待。应用:超时控制(case <-time.After)、多源竞争(谁先到用谁)、非阻塞收发、退出信号(select { case <-ctx.Done(): return; default…

8
# Golang

Go 对已关闭的 channel 读写会怎样?如何安全退出接收循环

① 读已关闭 channel:立即返回零值,v, ok := <-ch 中 ok=false(正确退出方式);② 向已关闭 channel 发送:panic(send on closed channel);③ 重复 close:panic(close of closed channel);④ 已关闭的 channel 接收完缓冲数据后返回零值。风险:无缓冲且已关闭时读会一直返回零值,若没检查 ok 会误当正常数据。规范:发送方 clos…

9
# Golang

Go channel 什么时候关闭?安全关闭原则与常见误区

核心原则:只在发送方关闭 channel(接收方关闭会导致发送方 panic: send on closed channel);不要关闭已关闭的 channel(panic);不要向已关闭的 channel 发送(panic)。接收方通过 v, ok := <-ch 判断关闭(ok=false);for range ch 自动在关闭后退出。安全的关闭模式:① 唯一发送方直接 close;② 多发送方用 sync.Once 包 close…

10
# Golang

Go channel 类型全解:有缓冲与无缓冲的区别与应用场景

channel 按方向:双向 chan T、只发 chan<- T、只收 <-chan T(用于函数参数限制);按缓冲:无缓冲 make(chan T) 和有缓冲 make(chan T, n)。无缓冲:发送和接收必须同时就绪,否则阻塞——实现同步握手(两个 goroutine 会合点);有缓冲:缓冲未满发送不阻塞、未空接收不阻塞——实现解耦和流量控制(类似队列)。选择:需要同步确认用无缓冲,生产消费解耦用有缓冲(合理设置容量避免死锁)…