新手应先用 go run 运行单文件程序掌握基础语法,再引入 go mod;从第二程序起练习 goroutine 与 channel;用 fmt.Errorf + %w 包装错误;先手写 net/http 路由再学框架。

从写第一个 go run 开始,别碰 go mod init 太早
新手常在装完 Go 就急着建项目、初始化模块,结果卡在代理失败、go: cannot find main module 或依赖拉不下来。这不是你环境没配好,是过早引入了工程复杂度。
真正该做的,是先用最原始方式跑通语言本身:新建一个 hello.go,只写 package main 和 fmt.Println,终端执行 go run hello.go —— 成功就说明 Go 已就位。这个阶段完全不需要 go mod,也不需要任何第三方库。
- 所有语法练习(切片操作、结构体定义、接口实现)都用单文件完成,避免被模块路径、
import冲突干扰判断 - 等你能熟练写出带
map初始化、for range遍历、函数多返回值的代码后,再执行go mod init example.com/hello - 国内务必提前配置代理:
go env -w GOPROXY=https://goproxy.cn,direct,否则go get会卡死或报timeout
并发不是“学完再用”,而是从第二个程序就开始练 goroutine + channel
Go 的并发模型不是高级技巧,它是基础运行单元。等你写完“斐波那契”“学生管理系统”这类同步程序,下一步就该把它们改造成并发版本——否则你永远在用 Go 写 C。
比如一个批量 HTTP 请求,同步写法是循环调用 http.Get,耗时线性增长;改成并发,只需加 go 前缀 + chan 收集结果,几行就能压测出性能差异。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 别一上来就啃
sync.WaitGroup或sync.Mutex:先用channel传递结果,理解“通信优于共享内存”的实际含义 - 避免无缓冲
channel死锁:发送和接收必须成对出现,测试时加select+default防阻塞 -
goroutine泄漏比内存泄漏更隐蔽:确保每个go启动的协程都有明确退出路径(如通过donechannel 控制)
别用 errors.New 模拟业务错误,直接上 fmt.Errorf + %w
很多教程教用 errors.New("xxx"),但真实项目里它根本不够用。你无法区分“数据库连不上”和“用户不存在”,也没法做错误分类处理。
Go 1.13 引入的错误包装机制才是正解:fmt.Errorf("failed to fetch user: %w", err),这样上游可用 errors.Is(err, sql.ErrNoRows) 判断根因,而不是靠字符串匹配。
- 所有自定义错误类型应实现
Unwrap() error方法,否则%w包装无效 - 不要在日志里反复打印同一错误链:
log.Printf("failed: %v", err)会丢失上下文;应只在入口处用log.Printf("failed: %+v", err)(%+v显示栈) - HTTP handler 中别用
panic代替错误处理:它会终止整个 goroutine,且无法被中间件统一捕获
选框架前先亲手写一遍 http.ServeMux + net/http 路由
直接 go get github.com/gin-gonic/gin 然后抄示例,你会很快遇到问题:为什么中间件顺序影响鉴权?为什么 c.BindJSON 有时静默失败?这些都不是 Gin 的 bug,是你没看清底层 HTTP 生命周期。
用原生 net/http 实现一个支持路径参数(如 /user/:id)、JSON 解析、状态码返回的微型路由,花不了 200 行。这个过程能让你看清:请求怎么进来的、上下文怎么传的、响应怎么写的。
- Gin/Echo 的
c.Param("id")底层就是解析r.URL.Path字符串,不是魔法 - 中间件本质是函数套函数:
func(h http.Handler) http.Handler,Gin 的Use只是帮你串起来 - 别为“性能”过早换框架:原生
net/http在 10K QPS 下仍足够,瓶颈通常在 DB 或缓存,不在路由层
路线图里最常被跳过的,其实是“写错三次以上才记住”的部分:比如 slice 传参后修改不影响原切片(因为底层数组指针没变),比如 time.Now().Format("YYYY-MM-DD") 永远错(Go 时间格式化用的是固定时间戳 2006-01-02)。这些坑不亲手踩,文档读十遍也没用。

















