go程序在main函数返回后立即终止,不会等待任何其他goroutine完成;应使用sync.waitgroup或channel等同步机制确保goroutine执行完毕,而非依赖time.sleep。

go version 命令报错或显示“command not found”
说明 go 命令没进系统 PATH,不是 Go 没装好,而是环境变量没生效。
- Linux/macOS:检查
~/.bashrc或~/.zshrc是否包含export PATH=$PATH:/usr/local/go/bin(或你实际的GOROOT下的bin路径),然后运行source ~/.zshrc(macOS Catalina 及以后默认用 zsh) - Windows:确认系统环境变量中
Path包含C:\Go\bin(或你自定义的安装路径下的bin),修改后需重启终端或命令行窗口 - 验证方式:执行
which go(macOS/Linux)或where go(Windows),有输出路径才算成功
main 函数里启动 goroutine 后程序立刻退出
这是新手最常踩的坑:goroutine 是异步的,main 函数结束,整个进程就终止,所有 goroutine 被强制回收——哪怕它们还没开始执行。
- 别依赖
time.Sleep做同步,它不可靠(比如 goroutine 实际耗时波动、Sleep 时间设短了漏结果、设长了拖性能) - 正确做法是用
sync.WaitGroup显式等待:在启动前wg.Add(1),goroutine 结束前wg.Done(),main 里调wg.Wait() - 如果 goroutine 需要向主协程传数据,优先考虑
channel,而不是共享变量 + Sleep 等待
goroutine + channel 通信时出现 deadlock
典型错误是往无缓冲 channel 写入后没人读,或从空 channel 读取但没人写——Go 运行时检测到所有 goroutine 都阻塞,直接 panic 报 fatal error: all goroutines are asleep - deadlock!。
- 无缓冲 channel(
make(chan int))要求发送和接收必须**同时就绪**,否则阻塞;带缓冲 channel(make(chan int, 2))最多缓存指定数量,超了也会阻塞 - 确保至少有一个 goroutine 在读、一个在写,且顺序合理;常见反模式:main 先
,但写 goroutine 还没启动 - 调试技巧:加
fmt.Println打点,确认 goroutine 是否真被调度、channel 操作是否发生在预期时机
并发修改全局变量导致计数不准
多个 goroutine 直接读写同一个变量(如 counter++),结果远小于预期值——这不是 Go 的 bug,是典型的竞态条件(race condition)。
- Go 编译时加
-race参数可检测:go run -race main.go,会明确指出哪行代码存在数据竞争 - 解决方式二选一:用
sync.Mutex加锁(适合简单读写),或改用sync/atomic的原子操作(如atomic.AddInt64(&counter, 1),性能更高) - 记住:channel 不只是通信工具,更是同步机制;能用 channel 协调的,尽量别用共享内存
真正难的不是写个 go f(),而是让多个 goroutine 安全、可控、可预测地协作。很多问题表面是语法不会,根子在对 Go 并发模型的理解偏差——它不鼓励“锁住一切”,而是引导你用 channel 组织流程。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











