标准库与工程实践
Go 的标准库是核心竞争力:HTTP 服务器、JSON、测试、性能分析全内置。面试主线:net/http 模型、模块管理、测试、pprof。
net/http
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
w.Write([]byte(`{"ok":true}`))
})
http.ListenAndServe(":8080", nil)- 每个请求一个 goroutine:标准库的并发模型(goroutine 轻量,十万连接可行)
http.Handler接口:ServeHTTP(w, r),中间件就是包 Handler(洋葱模型,见设计模式篇)- 路由:1.22+ 的 ServeMux 支持方法 + 路径参数(
GET /users/{id}) - 生产框架:gin(最流行)、echo、chi,底层都是 net/http
Server 配置要点:http.Server 要显式设 ReadTimeout/WriteTimeout(默认无超时,慢客户端会占住连接)。
go mod 模块管理
go mod init example.com/myapp # 初始化
go get github.com/gin-gonic/gin # 加依赖
go mod tidy # 清理依赖- go.mod:模块声明 + 依赖版本;go.sum:依赖校验和(供应链安全)
- 版本规则:语义化版本,
v1.2.3;replace指令可换源(本地调试、镜像) - vendor:把依赖打进仓库(离线构建);GOPROXY 配代理加速
testing
func TestAdd(t *testing.T) {
cases := []struct{ a, b, want int }{
{1, 2, 3}, {0, 0, 0}, {-1, 1, 0},
}
for _, c := range cases {
if got := Add(c.a, c.b); got != c.want {
t.Errorf("Add(%d,%d) = %d, want %d", c.a, c.b, got, c.want)
}
}
}- 表驱动测试是 Go 惯例:cases 切片 + 循环断言
go test ./...跑全部;-cover看覆盖率;-race检测数据竞争(并发代码必开)- 基准测试
BenchmarkXxx:go test -bench=.性能对比 - 命名:
xxx_test.go同包(白盒)或_test包(黑盒)
pprof 性能分析
import _ "net/http/pprof" // 注册 /debug/pprof
// 采集 30 秒 CPU profile
go tool pprof http://localhost:8080/debug/pprof/profile| profile | 看什么 |
|---|---|
| cpu | 热点函数(哪个函数烧 CPU) |
| heap | 内存分配(哪里分配多、是否泄漏) |
| goroutine | goroutine 堆积(泄漏排查,见 GMP 篇) |
| block / mutex | 阻塞和锁竞争 |
排查流程:cpu 找热点、heap 找分配、goroutine 找泄漏。go tool pprof -http 出火焰图。
面试追问
- net/http 的并发模型? 每请求一个 goroutine + Handler 接口。中间件 = 包 Handler
- go.mod 和 go.sum? go.mod 声明依赖版本,go.sum 校验和防篡改。tidy 清理
- 表驱动测试? cases 切片 + 循环断言,Go 的测试惯例。并发代码必开 -race
- pprof 怎么定位性能问题? cpu 找热点函数、heap 找分配、goroutine 找泄漏、block 找锁竞争
- http.Server 要配什么? 读/写超时:默认无超时,慢客户端会拖住连接。配超时是生产必修