Phuong Le 用一个看似正常却暗藏数据竞争的 Go 程序切入:一个 goroutine 写入变量和 done 标志,主 goroutine 用 for 循环自旋等待——Playground 上能打印出正确结果,但用 go run -race 立即报出两处数据竞争。文章解释了真实机器上为何会出现这种"碰巧工作",剖析 Go 内存模型关于跨协程可见性的规则,以及为什么必须用 channel、sync 原语等显式同步来保证顺序。