Go命令找不到是PATH未生效;goroutine无输出是主goroutine提前退出。需检查shell配置文件、重开终端、验证which go或Get-Command go,用WaitGroup而非Sleep等待子协程。

Go 环境装不起来,go version 报 command not found,90% 是 PATH 没生效;协程跑不起来或“没输出”,大概率是主 goroutine 提前退出,没等子 goroutine 执行完。
go 命令找不到?先盯住 PATH 和 shell 配置文件
Windows 上装了 .msi 却仍提示命令不存在,不是安装失败,而是 PowerShell 或 CMD 没读到新 PATH —— 安装器勾选的“添加到 PATH”只对新打开的终端生效。关掉所有终端再重开,或者手动运行 $env:Path 看是否含 C:\Program Files\Go\bin。
macOS/Linux 更常见的是 shell 类型不匹配:~/.bashrc 里写了 export PATH,但你用的是 zsh(macOS Catalina+ 默认),结果 source ~/.bashrc 白忙活。查当前 shell:echo $SHELL,然后改对应文件(~/.zshrc 或 ~/.bash_profile)并 source。
- 验证是否真生效:运行
which go(macOS/Linux)或Get-Command go(PowerShell),有输出才算成功 - 别依赖安装器自动配置:尤其 Linux 手动解压后,
/usr/local/go/bin必须显式加进PATH -
go env GOROOT输出为空?说明GOROOT没设或设错,多数情况不用手动设,除非你把 Go 解压到了非标准路径
go mod init 失败?清理 vendor 和 GOPATH/src 干扰
在已有旧项目里执行 go mod init 却生成空 go.mod 或报错,往往是因为残留了 vendor/ 目录,或当前目录还在 $GOPATH/src 下。Go 模块模式会优先按旧 GOPATH 规则推导 module 名,一错全错。
立即学习“go语言免费学习笔记(深入)”;
- 删掉项目根目录下的
vendor/(除非你明确要用 vendor 锁依赖) - 运行
go env -w GO111MODULE=on强制启用模块模式(Go 1.16+ 默认开启,但 CI 脚本或老环境可能关着) - 切到任意非
$GOPATH/src的路径新建项目,比如~/projects/myapp,再go mod init myapp - 检查
go env GOPATH,如果它指向一个带src子目录的路径,且你正待在$GOPATH/src/xxx里,立刻cd出来
goroutine 启动后没反应?主函数退出太快
写了个 go fmt.Println("hello") 却看不到输出,不是协程没跑,是 main 函数执行完直接退出进程,子 goroutine 还没调度到就被杀掉了。Go 不会自动等 goroutine 结束。
- 最简验证法:加
time.Sleep(10 * time.Millisecond)—— 仅用于调试,不能进生产代码 - 正确做法是用
sync.WaitGroup计数等待:wg.Add(1)在go前,wg.Done()在 goroutine 末尾,wg.Wait()在main结尾 - 别用
runtime.Gosched()“让出时间片”来凑效:它只建议调度器切换,不保证子 goroutine 立刻执行,不可靠 - 通道(
chan)也可阻塞等待,比如done := make(chan struct{}),goroutine 结尾写done ,<code>main里<-done
协程数量失控?别无脑套 go f()
看到并发就写几十个 go,结果内存爆掉或被系统限流,是因为每个 goroutine 至少占 2KB 栈空间,上万 goroutine 就是 20MB+,更别说它们可能同时发起网络请求打垮下游。
- 用
runtime.NumGoroutine()在关键点打印数量,确认是否意外泄漏(比如循环里忘了break) - I/O 密集场景(如 HTTP 请求)优先用带缓冲的 channel 控制并发数,而不是硬起 N 个 goroutine
- 长时间运行的 goroutine 必须处理退出信号,比如监听
context.Context的Done(),否则无法优雅关停 -
go func() { ... }()匿名函数捕获循环变量时容易出错:所有 goroutine 共享同一个变量实例。应传参,如go func(i int) { ... }(i)
真正难的不是启动协程,而是控制它的生命周期和资源边界 —— 什么时候该等、什么时候该停、数据怎么安全传递,这些细节一旦漏掉,程序就从“高并发”变成“随机崩溃”。


















