这里是
content/posts/golang/tutors的目录页,收录 151 篇「单点讲透」型文章。和start/的编号序列不同,这里的文章按主题横向铺开:想查 Go 1.21 的 slices 包怎么替代手写循环、想弄清 context 取消原因怎么设计、想给 HTTP 客户端加重试中间件,都可以直接从下面的主题小节定位。每篇都控制在能一次读完的篇幅,适合当作日常开发的随身手册。
专题速览
| 维度 | 说明 |
|---|---|
| 文章规模 | 151 篇,按 14 个主题小节归类 |
| 时间跨度 | 2020-02 至 2025-12,从 Go 1.14 时代一直写到 1.22 |
| 难度分布 | 入门友好型约 90 篇,工程实践型约 50 篇,深度解析型约 11 篇 |
| 覆盖方向 | 版本特性、语法与值语义、错误与日志、并发与 context、HTTP 服务端与客户端、认证安全、数据处理、模板与静态资源、数据库缓存、测试、性能观测、工程结构、构建配置、时间与正则 |
| 典型读者 | 能写 Go 但想系统补齐「边界知识」的中级开发者 |
| 使用方式 | 按主题小节查阅;每个小节内部按由浅入深排列 |
推荐阅读路径
路径一 从「能写」到「写对」
先读 go-variables-types-and-control-flow、go-functions-pointers-and-value-semantics、go-slices-maps-and-strings、go-structs-methods-and-composition 把值语义与数据结构的手感校准,再读 go-interfaces-for-beginners 与 go-empty-interface-and-type-assertions 理解接口与空接口,最后用 go-error-handling-practical-guide 与 go-structured-error-types-2024 把错误处理写成体系。
路径二 服务端开发主线
按 go-http-server-first-project → go-servemux-routing-2024 → go-http-middleware-patterns-2024 → go-http-json-api-structure-2024 搭出服务骨架,再补 go-http-server-timeouts-2023、go-http-server-shutdown-drain-2025、go-graceful-shutdown 处理超时与退出,最后用 go-cookie-session-basics-2024、go-password-hashing-basics、go-rate-limit-token-bucket-2024 加固安全与限流。
路径三 性能与排障
从 go-benchmark-and-profiling-basics 与 go-benchmark-allocations-2023 建立度量习惯,进入 go-pprof-http-service-2023 找热点,再用 go-debugging-common-tools、go-race-detector-practice-2023、go-memory-limit-gogc-2025 定位并发与内存问题,最后用 go-small-service-observability-2022 建立指标、日志与链路三支柱。
路径四 版本特性速查
只想补新特性的话,按版本顺序读 go-118-any-vs-interface-2022、go-118-generics-first-look-2022、go-120-errors-join-2023、go-121-slices-maps-cmp-2023、go-121-slog-first-use-2023、go-122-loop-variable-subtests-2024、go-iterators-range-over-func-2024 七篇即可覆盖近年最常用的语言变化。
相关专题
| 专题 | 关联点 |
|---|---|
| Go / Golang 专题总目录 | 本目录的上级专题,含并发模式、gRPC 与可观测性长文 |
| Go 入门专题导航 | 128 篇按学习阶段排列的入门序列 |
| Plumego 框架专题 | 用标准库思路组织服务的极简框架实践 |
| 分布式系统专题 | 服务发现、消息队列与一致性问题的延伸阅读 |
| 可观测性专题 | Metrics、Logs、Traces 的体系化方法 |
版本特性与语言演进
这一节按版本顺序收拢 Go 1.18 到 1.23 的语言变化。每篇都从「这个特性解决了什么问题」出发,而不是罗列语法,适合在升级 go.mod 里的版本号之前先扫一遍。
| 文章 | 一句话核心内容 |
|---|---|
| Go 1.18 any 与 interface{} 深度对比:类型别名背后的演进与最佳实践 | any 与 interface{} 的编译器等价性、迁移策略,以及空接口的 nil 陷阱 |
| Go 1.18 泛型初体验:先从三个小函数开始理解 | 用 Contains、Map 与泛型 Set 三个小函数建立类型参数与约束的直觉 |
| Go 泛型切片工具入门:自己写 Filter、Map 和 Reduce | 手写 Filter/Map/Reduce,说明泛型切片工具为何比 interface{} 更自然 |
| Go netip 入门:更清楚地处理 IP 地址和网段 | net/netip 的 IP 解析、网段判断与 IPv6 处理,对比传统 net.IP 的优缺点 |
| Go 构建信息入门:在程序里查看版本、依赖和构建来源 | 在程序内读取自身构建信息,用于确认线上到底跑的是哪一版 |
| Go 1.20 context 取消原因入门:让并发任务知道为什么停下 | WithCancelCause 与 context.Cause 的基本用法,让取消链路可排查 |
| Go 1.20 多错误处理入门:errors.Join 怎么用才自然 | errors.Join 在批量校验、资源关闭与并发任务中的多错误保留方式 |
| Go 1.21 slices、maps 和 cmp 入门:集合工具终于标准化 | slices/maps/cmp 三包统一 Contains、Clone、Equal、SortFunc 等常见操作 |
| Go 1.21 slog 入门:不用第三方库也能写结构化日志 | log/slog 的文本与 JSON 输出、字段与 With 用法,以及请求日志写法 |
| Go 1.21 工具链管理入门:go.mod 里的 go 和 toolchain 怎么理解 | go.mod 中 go 与 toolchain 指令的含义,以及团队版本管理策略 |
| Go 1.22 循环变量入门:为什么子测试和 goroutine 更不容易踩坑了 | Go 1.22 循环变量语义调整后,子测试与 goroutine 闭包为何不再踩坑 |
| Go 1.23 迭代器入门:range over func 能解决什么问题 | range over func 的基本写法与适用场景,以及避免过度设计的边界 |
| Go 泛型之前怎么复用代码:接口、函数参数和清楚的重复 | 回顾泛型出现前用接口与函数参数做复用的方式,理解泛型的设计背景 |
语法基础与值语义
基础不牢时最容易写出「能跑但边界就崩」的代码。这一节重讲变量、函数、切片、Map、结构体与接口,重点在值语义与隐式实现这两个 Go 特有的心智模型。
| 文章 | 一句话核心内容 |
|---|---|
| Go 语言入门:从安装环境到写出第一个可维护程序 | 从安装、命令行、main 包到 go run/go build 与代码格式化写出第一个可维护程序 |
| Go 变量、类型和流程控制:把基础语法写得清清楚楚 | 用真实业务片段讲变量声明、零值、常量、基本类型与 if/for/switch 作用域 |
| Go 函数、指针和值语义:为什么代码看起来简单却很讲究 | 从函数签名、指针与值语义解释 Go 函数为什么朴素却更好推理 |
| Go 切片、Map 和字符串:写业务代码绕不开的数据结构 | 业务代码绕不开的三种数据结构,以及不了解底层时容易踩的边界问题 |
| Go 结构体和方法:用组合组织真实业务数据 | 用结构体加方法组织业务数据,再用组合而不是继承表达复用 |
| Go 接口入门:从会写到真正理解隐式实现 | 接口不是为了面向对象,而是为了划边界:隐式实现与最小接口设计 |
| Go 空接口与类型断言深度解析:从 interface{} 内存布局到泛型替代趋势 | interface{} 的内存布局、类型断言的两种形式、type switch 与 nil 陷阱 |
| Go 包和模块入门:把代码从一个文件整理成一个小项目 | package、import、go.mod、导出规则与小项目的目录组织方式 |
| Go slices 和 maps 包入门:少写一点重复集合代码 | slices 与 maps 标准库的常用函数,对比手写循环的效率差异 |
| Go 泛型入门:从重复函数到类型参数的自然过渡 | 从重复函数过渡到类型参数,讲清约束、可比较类型与使用边界 |
| Go泛型集合实战:手写Set、Stack、Queue与迭代器 | 手写泛型 Set、Stack、Queue 与迭代器,含并发安全版本 |
| Go 排序与搜索集合完全指南:sort 包、container 包与泛型 slices 对比 | sort 包与 container 三件套,对比 Go 1.21+ 泛型 slices 包的新写法 |
错误处理与日志
Go 的错误与日志都强调「显式」。这一节把哨兵错误、自定义错误类型、errors.Is/As 与结构化日志串成一条线,让失败路径可判断、可检索。
| 文章 | 一句话核心内容 |
|---|---|
| Go 错误处理实战:别怕 if err != nil,它是在保护你 | 别怕 if err != nil:为什么显式失败路径是 Go 的保护机制 |
| Go 结构化错误入门:错误码、包装和 HTTP 映射 | 哨兵错误、自定义错误类型、errors.Is/As 与 HTTP 状态码映射 |
| Go 领域错误入门:errors.Is 和 errors.As 如何服务业务判断 | 用 errors.Is/As 把订单不存在、库存不足等业务错误映射成提示与重试策略 |
| Go 日志和配置入门:让程序出问题时能看得懂、改得动 | 让程序出问题时能看懂日志、改得动配置的基础工程习惯 |
| Go slog 入门:用结构化日志记录更清楚的服务行为 | slog 的文本与 JSON 格式、With 字段传递与 HTTP 请求日志中间件 |
| Go 入门:用 slog 写可检索的结构化日志 | 把关键信息放进字段,让日志平台可以按字段过滤、聚合与统计 |
| Go 日志脱敏入门:不要把密码、Token 和身份证写进日志 | 避免把密码、验证码、Token 与身份证号写进日志的脱敏做法 |
并发与 context
并发是 Go 的主场,也是最容易出事的地方。这一节从 goroutine 与 channel 的基础编排讲到 context 取消原因、并发 map、atomic、sync.Pool 与竞态检测。
| 文章 | 一句话核心内容 |
|---|---|
| Go 并发入门:goroutine、channel 和 context 怎么一起用 | 用并发抓取、超时取消与 worker 池串起 goroutine、channel、select 与 context |
| Go channel 流水线入门:生产、处理、取消和关闭怎么配合 | 生产者、工作者、结果汇总与 channel 关闭规则,含背压与超时处理 |
| Go Worker 队列入门:用 channel 和 context 处理后台任务 | 用 channel、goroutine、WaitGroup 与 context 实现后台任务队列 |
| Go worker 取消入门:后台循环如何听懂 context | 后台循环如何听懂 context 取消,并正确关闭资源与退出 goroutine |
| Go 入门:WaitGroup 不只等待,还要收好结果 | WaitGroup 之外还要收结果、处理错误、控制并发并正确关闭 channel |
| Go context 值入门:请求范围数据可以放,业务参数不要乱塞 | WithValue 的适用边界:请求 ID 可以放,业务参数不要乱塞 |
| Go Context 取消原因深度解析:从 WithCancelCause 到梯度超时设计 | WithCancelCause 源码、WithoutCancel 与 AfterFunc,以及梯度超时设计 |
| Go 并发 map 入门:mutex、sync.Map 和单 goroutine 管理 | 并发 map 的三种做法:mutex、sync.Map 与单 goroutine 独占管理 |
| Go atomic 包深度使用指南:从原子计数到无锁编程的完整实践 | atomic.Value 与类型化原子操作、CAS 原理、内存序与无锁计数器 |
| Go atomic 计数入门:比 mutex 更适合简单计数的场景 | 用请求计数与开关状态讲 Add/Load/Store,以及不适合用 atomic 的场景 |
| Go sync.Once 入门:懒加载资源时只初始化一次 | 懒加载昂贵资源时如何保证只初始化一次并避免重复执行 |
| Go sync.Pool 入门:复用临时对象前先看清边界 | 复用临时对象前先看清边界,避免对象没清理干净引入 bug |
| Go 竞态检测入门:用 -race 找出并发读写问题 | 用 -race 找出计数器、并发 map 写入与 HTTP 指标中的数据竞争 |
| Go singleflight 思路入门:避免缓存击穿时重复查询 | 同一 key 的并发请求只让第一个真正查库,避免缓存击穿打满数据库 |
HTTP 服务与路由
这一节只谈服务端:路由、中间件、超时、优雅关闭、表单与上传、流式响应与分页。全部基于标准库,读完可以直接迁移到任意框架。
| 文章 | 一句话核心内容 |
|---|---|
| Go Web 入门:只用标准库写一个小而清楚的 HTTP 服务 | 只用标准库 net/http 写一个小型 JSON 服务:路由、解析、编码与错误处理 |
| Go ServeMux 路由入门:用标准库写更清楚的 HTTP 路由 | ServeMux 的现代用法:方法路由、路径参数与 JSON API 组织 |
| Go HTTP 中间件入门:日志、恢复、鉴权和请求 ID 怎么串起来 | 请求 ID、panic 恢复、鉴权与日志中间件如何串成一条链 |
| Go JSON API 入门:Handler、请求解析和统一响应怎么组织 | Handler、请求解析与统一响应结构,让第十个接口依然清楚 |
| Go HTTP 服务超时入门:ReadTimeout、WriteTimeout 和请求上下文 | ReadTimeout/WriteTimeout/IdleTimeout 与请求 context,避免被慢请求拖住 |
| Go HTTP 服务优雅关闭入门:停止接新请求,等旧请求收尾 | 停止接新连接、等待旧请求收尾,并处理信号与超时边界 |
| Go 服务优雅关闭入门:让 HTTP 服务收到信号后稳稳退出 | SIGINT/SIGTERM、Server.Shutdown 与后台任务退出的完整配合 |
| Go HTTP ResponseController 入门:更明确地控制响应写入 | 用 ResponseController 做 Flush、写截止时间与 SSE 流式响应 |
| Go 表单解析入门:FormValue、ParseForm 和 PostForm 怎么选 | FormValue、ParseForm、PostForm 的差异,以及 multipart 与大小限制 |
| Go HTTP gzip 压缩入门:什么时候压缩响应,什么时候不要压 | 响应压缩的中间件写法:Accept-Encoding、小响应跳过与测试 |
| Go http.ServeContent 入门:文件下载、修改时间和断点续传 | 用 http.ServeContent 做文件下载:文件名、修改时间与 Range 断点续传 |
| Go 文件上传入门:限制大小、校验类型和安全保存 | 头像上传接口的大小限制、文件名处理、类型校验与安全保存 |
| Go JSON 流式响应入门:边查边写,避免一次性占满内存 | 列表接口边查边编码边写,避免一次性把全部数据读进内存 |
| Go 分页 API 设计与实现:Offset、Cursor、稳定排序与性能对比 | Offset 与 Cursor 两种分页方案的原理、性能对比与稳定排序实现 |
HTTP 客户端与外部调用
服务端之外,调用别人同样重要。这一节覆盖客户端超时与重试、multipart 上传、httptrace 定位慢请求、TLS 与 mTLS 配置。
| 文章 | 一句话核心内容 |
|---|---|
| Go HTTP 客户端入门:请求、超时、重试和 JSON API 调用 | 请求构造、响应读取、JSON 编解码、超时、重试与错误处理的基础 |
| Go HTTP 客户端中间件入门:给外部调用加日志、重试和请求 ID | 通过 RoundTripper 给外部调用加日志、请求头注入与有限重试 |
| Go HTTP 客户端上传文件入门:multipart 请求怎么构造 | 构造 multipart/form-data 请求上传文件,含文件字段、普通字段与测试 |
| Go httptrace 入门:看清一次 HTTP 请求慢在哪里 | 用 httptrace 拆解一次请求耗时在 DNS、连接、TLS 还是响应下载 |
| Go net/url 入门:安全地拼 URL 和查询参数 | 用 net/url 安全拼路径与查询参数,避开手写 URL 的安全误区 |
| Go 超时和重试入门:context、退避和幂等性一起看 | 把超时、退避与幂等性放在一起考虑,避免无脑重试放大抖动 |
| Go 限流入门:用令牌桶保护一个 HTTP 接口 | 用令牌桶保护公开表单、登录接口与 AI 调用入口的限流边界 |
| Go 入门:用 time.Ticker 做一个朴素限速器 | 用 time.Ticker 做朴素限速器,应对第三方接口的每秒请求上限 |
| Go 后台任务重试入门:失败后怎么重试才不添乱 | 重试的最大次数、退避等待、错误分类、幂等性与死信队列设计 |
| Go os/exec 入门:调用外部命令时如何处理超时和输出 | CommandContext 调用外部命令时的超时、stdout/stderr 与参数安全 |
| Go TLS/HTTPS 客户端安全完全指南:证书验证、双向认证与 TLS 1.3 | 证书验证、双向认证、自定义 CA、证书固定与 TLS 1.3 配置 |
| Go TLS 客户端证书入门:什么时候需要 mTLS | mTLS 的适用场景:内部服务调用、企业网关与高安全 API |
认证安全与随机数
认证与安全属于「做错了才被看见」的部分。这一节从 Cookie/Session 讲起,到密码哈希、重置 Token、随机数选型与 IP 地址处理。
| 文章 | 一句话核心内容 |
|---|---|
| Go HTTP Basic Auth 入门:用中间件保护内部页面 | 用 HTTP Basic Auth 中间件低成本保护内部管理页面 |
| Go Cookie 和 Session 入门:登录态到底放在哪里 | 登录态放在哪里:Cookie、Session ID、HttpOnly/Secure/SameSite 与服务端存储 |
| Go 入门:Cookie、Session 和一个简单登录状态 | 从 HTTP 角度看 Cookie 与 Session 的区别,实现一个简单登录状态 |
| Go 密码哈希完整安全指南:bcrypt、Argon2、盐值与时序攻击防范 | bcrypt/argon2/scrypt/pbkdf2 对比、盐值与 pepper、时序攻击防范 |
| Go 密码重置 Token 入门:随机数、过期时间和一次性使用 | 重置 Token 的随机性、过期时间、一次性使用与数据库存储方式 |
| Go 随机数入门:math/rand、crypto/rand 和安全 Token | math/rand 与 crypto/rand 的区别,以及验证码与安全 Token 的正确选型 |
| Go 入门:随机数别乱用,Token 要用 crypto/rand | Session、验证码与重置链接必须用 crypto/rand 的原因与写法 |
| Go 入门:用 net/netip 处理 IP 地址更省心 | 用 net/netip 的 Addr/Prefix 做 IP 解析、私网判断与 CIDR 匹配 |
数据处理与文件 IO
数据格式与文件操作是后端日常。这一节覆盖 CSV、JSON、XML、io 流式处理、bufio、压缩归档、临时文件、跨平台路径与工作目录问题。
| 文章 | 一句话核心内容 |
|---|---|
| Go CSV 处理入门:读取表格数据、清洗字段和导出报表 | 读取表格数据、清洗字段与导出报表,处理引号、换行与编码问题 |
| Go CSV 导入入门:逐行读取、校验和错误报告 | 逐行读取 CSV 并校验,设计表头检查与面向用户的错误报告 |
| Go 入门:CSV 导入导出别只会 strings.Split | 别用 strings.Split 解析 CSV:标准库如何正确处理逗号与引号 |
| Go 文件、JSON 和命令行工具:做一个真正能用的小程序 | 用一个真正能用的小工具串起文件、JSON、参数解析与结构体建模 |
| Go JSON 解码细节:字段缺失、未知字段、流式读取和接口边界 | 字段缺失、零值、未知字段、Decoder 与 RawMessage 的处理细节 |
| Go JSON 流式处理入门:不用一次把大文件读进内存 | 用流式 Decoder/Encoder 处理大 JSON 数组、日志导出与请求体 |
| Go 部分更新 API 入门:区分未提交、空值和清空字段 | 用自定义 Optional 类型区分未提交、null 与空值,实现安全的 PATCH 更新 |
| Go JSON 请求校验入门:不用框架也能写清楚规则 | 不用框架也能写清楚校验规则:字段缺失、长度、枚举与错误组织 |
| Go XML 处理入门:用 encoding/xml 解析配置和旧系统数据 | encoding/xml 的结构体标签、属性解析与流式解码,对接旧系统数据 |
| Go io.Reader 与 io.Writer 实战完全指南:从设计哲学到流式处理 | 从 io 接口设计到 bytes.Buffer、io.Copy、TeeReader 与自定义流实现 |
| Go io.Pipe 入门:边生成边上传的流式处理 | 用 io.Pipe 边生成边上传,注意错误传播与关闭顺序避免卡住 |
| Go bufio 包完全实战指南:逐行扫描、缓冲读写与流式处理优化 | bufio 缓冲原理、Scanner 自定义 SplitFunc、大文件逐行读取与 Flush 策略 |
| Go 压缩和归档入门:gzip、tar 和 zip 的基本用法与实战 | gzip、tar 与 zip 的用法,覆盖日志压缩、文件打包与流式输出 |
| Go 临时文件入门:os.CreateTemp、MkdirTemp 和清理责任 | 用 os.CreateTemp/MkdirTemp 替代手写固定路径,明确清理责任 |
| Go fs.FS 入门:让文件读取逻辑更容易测试 | 用 io/fs 抽象文件读取,配合 os.DirFS 与 fstest.MapFS 让测试更简单 |
| Go 工作目录入门:为什么本地能读到文件,部署后却找不到 | 为什么本地能读到文件部署后却找不到:工作目录、相对路径与 embed |
| Go 跨平台路径处理完全指南:filepath、embed 与路径安全实践 | path 与 path/filepath 的差异、Windows/Unix 路径区别与路径遍历攻击防范 |
| Go 文件变化轮询入门:不用依赖也能做简单热加载 | 不引依赖的配置热加载:轮询修改时间的做法与实时性边界 |
模板与静态资源
当服务需要输出 HTML、邮件或报表时,模板是绕不开的。这一节讲清自动转义的安全边界,以及 embed 把模板与静态文件打包进二进制的做法。
| 文章 | 一句话核心内容 |
|---|---|
| Go 模板入门:用 html/template 生成安全的 HTML 页面 | html/template 的解析、渲染、数据传递、循环条件与自动转义 |
| Go HTML 模板安全入门:自动转义、模板函数和页面渲染边界 | 自动转义的边界、模板函数与常见误用导致的安全问题 |
| Go 入门:用 text/template 生成一份朴素报表 | 用 text/template 生成纯文本日报、邮件正文与 Markdown 摘要 |
| Go 邮件模板入门:把验证码和通知邮件渲染清楚 | 渲染验证码、邀请链接与账单通知邮件,利用自动转义避免注入 |
| Go embed 入门:把模板和静态文件打进二进制 | 编译时嵌入单文件、目录、模板与静态资源,兼顾安全与部署体验 |
| Go embed 模板布局入门:base、partial 和页面模板怎么组织 | base layout、partial 与页面模板的组织方式,以及模板测试 |
| Go 静态文件处理全历史演进:从 go-bindata 到 embed 完全指南 | 从 go-bindata 到 embed 的演进、embed FS 只读特性与 SPA 嵌入方案 |
数据库与缓存
这一节围绕 database/sql 展开:连接、NULL 值、context 传播、事务、预编译与迁移,最后补一个带 TTL 的进程内缓存实现。
| 文章 | 一句话核心内容 |
|---|---|
| Go 数据库入门:用 database/sql 写清楚的查询和事务 | 连接池、查询、Scan、Exec、事务与 context 的基本边界 |
| Go 数据库 NULL 值入门:sql.NullString、指针和业务语义 | sql.NullString/NullTime、指针字段与 JSON 响应的 NULL 处理 |
| Go database/sql 上下文入门:QueryContext、超时和连接释放 | QueryContext、超时传播、Rows 关闭与常见的连接泄漏问题 |
| Go SQL 事务入门:把转账、订单和库存写得更可靠 | 用转账与订单扣库存讲 BeginTx、defer Rollback 与 Commit 的正确姿势 |
| Go SQL 预编译入门:PrepareContext 什么时候值得用 | PrepareContext 与普通 ExecContext 的取舍,以及批量插入场景 |
| Go 数据库迁移入门:SQL 文件、版本表和上线顺序 | 迁移文件组织、版本表、幂等性与分批回填的上线顺序 |
| Go 内存缓存入门:TTL、并发安全和清理策略 | 带 TTL 的进程内缓存:并发安全、过期清理与适用边界 |
测试与质量
测试不是额外负担,而是让修改变轻。这一节从表驱动与子测试讲到 httptest、黄金文件、测试替身、TestMain、覆盖率、模糊测试与发布清单。
| 文章 | 一句话核心内容 |
|---|---|
| Go 表驱动测试入门:用一张用例表保护越来越多的业务规则 | 用一张用例表保护越来越多的业务规则,替代手工验证 |
| Go 子测试组织入门:表驱动、t.Run 和测试命名怎么写 | 用 t.Run 组织子测试、命名用例并改善失败信息的可读性 |
| Go HTTP Handler 测试入门:不用启动端口也能测接口 | 用 httptest.NewRecorder 不启动端口就能测 handler |
| Go httptest.Server 入门:给 HTTP 客户端写可信测试 | 用 httptest.Server 给 HTTP 客户端写可信测试,替代真实外部调用 |
| Go 黄金文件测试入门:适合输出很长的文本和 JSON | 把长文本与 JSON 期望输出放进单独文件,让测试保持可读 |
| Go 测试替身入门:用小接口写出容易测试的业务代码 | 用小接口加手写 fake/spy 替代 mock 框架,写出容易测试的业务代码 |
| Go TestMain 入门:为一组测试准备共享环境 | TestMain 准备共享测试环境的结构与边界,以及何时不该用 |
| Go 测试覆盖率入门:数字之外更重要的是关键路径 | 覆盖率命令、HTML 报告解读,以及关键路径优先的测试策略 |
| Go Fuzzing 基础工作流完整教程:从第一个 Fuzz 函数到 CI 持续集成 | 从第一个 fuzz 函数到语料库、崩溃分析与 CI 持续集成 |
| Go Fuzz 测试 2024 完全指南:从语法到实战的模糊测试体系 | go test -fuzz 语法、覆盖率引导、崩溃最小化与 CI 集成策略 |
| Go 项目发布与上线完整清单:从代码冻结到生产验证的系统性流程 | 从代码冻结、测试、安全扫描到灰度上线与回滚的发布清单 |
性能与可观测性
优化之前先测量。这一节建立基准测试与 pprof 的度量闭环,再补上内存限制调参、expvar 轻量指标与三支柱可观测性建设。
| 文章 | 一句话核心内容 |
|---|---|
| Go 性能入门:基准测试、pprof 和先测量再优化 | Benchmark 编写、benchstat 对比与 pprof CPU/内存分析的入门闭环 |
| Go 基准测试和分配入门:用 -benchmem 看清楚优化是否值得 | 用 -benchmem 看清字符串拼接与切片预分配是否真的值得优化 |
| Go pprof 入门:给 HTTP 服务找 CPU 和内存热点 | 给 HTTP 服务找 CPU 与内存热点,含 goroutine 排查与安全实践 |
| Go 调试完整工具链指南:从 fmt.Println 到 Delve 与 pprof 深度分析 | 从 fmt.Println 到 race detector、Delve 与 pprof 的完整调试工具链 |
| Go 内存限制入门:GOMEMLIMIT、GOGC 和容器里的服务 | GOMEMLIMIT 与 GOGC 在容器里的取舍,避免被 OOM kill |
| Go expvar 入门:给小服务加几个轻量指标 | 用标准库 expvar 低成本暴露 JSON 指标,理解服务该展示哪些状态 |
| Go 微服务可观测性三支柱实战:Metrics、Logs 与 Traces 完整建设指南 | Metrics、Logs、Traces 三支柱的渐进式建设路径与告警规则设计 |
工程结构与依赖管理
项目一大,结构就是生产力。这一节讲命令行工具组织、cmd/internal 取舍、轻量分层,以及 go mod 与 go work 的依赖管理。
| 文章 | 一句话核心内容 |
|---|---|
| Go 命令行程序结构:从一个 main.go 整理成可维护工具 | 把一个 main.go 整理成可维护的命令行工具结构 |
| Go 入门:用 flag 写一个不慌不忙的命令行配置 | 用 flag 写不慌不忙的命令行配置,避免路径写死与超时散落 |
| Go CLI 子命令入门:用 flag.FlagSet 写清楚的命令行工具 | 用 flag.FlagSet 实现 add/list/done 这类子命令的组织方式 |
| Go 项目结构入门:什么时候需要 cmd、internal 和分层目录 | 什么时候需要 cmd、internal 与分层目录,避免过度设计 |
| Go 轻量分层入门:Handler、Service、Store 怎么刚刚好 | Handler/Service/Store 的职责边界与刚刚好的轻量分层 |
| Go 依赖管理入门:go mod、版本号、replace 和 tidy 怎么用 | go.mod/go.sum 维护、版本选择、replace 调试与 v2+ 模块路径规则 |
| Go 工作区 2024 最新实践:go.work 完整语法与 monorepo 实战 | go.work 完整语法、多版本模块联调、go work sync 与 monorepo 实战 |
| Go 工作区深度使用指南:go work 解决本地多模块联调与工程化实践 | go work 的 use 与 replace 区别,以及 CI/CD 中的工作区策略 |
构建配置与时间处理
上线相关的一堆细节:构建标志与交叉编译、版本信息注入、配置分层与热重载边界、信号退出、时间与时区、正则与反射标签。
| 文章 | 一句话核心内容 |
|---|---|
| Go 构建标志与环境变量完全指南:ldflags、交叉编译与可复现构建 | ldflags 注入版本、tags 条件编译、交叉编译与可复现构建 |
| Go build tags 入门:为不同环境编译不同文件 | 用 build tags 为平台差异、集成测试隔离与功能开关编译不同文件 |
| Go 构建版本信息入门:把 commit、版本号和构建时间写进程序 | 把 commit、版本号与构建时间写进程序并在健康检查中展示 |
| Go 配置分层入门:默认值、环境变量和启动校验 | 默认值、环境变量与启动校验的分层配置设计 |
| Go 配置校验入门:让服务启动时就发现问题 | 在服务启动时就发现配置问题:必填校验、URL 校验与启动摘要 |
| Go 配置热重载入门:哪些配置能重载,哪些不该重载 | 哪些配置能热重载、哪些不该:日志级别可以,监听端口不行 |
| Go 信号处理入门:让 CLI 和服务收到 Ctrl+C 后体面退出 | 用 signal.NotifyContext 处理 Ctrl+C 并优雅停止后台任务 |
| Go 时间处理入门:time 包、时区、定时器和超时控制怎么用 | time 包的解析、格式化、时区、Ticker/Timer 与超时控制 |
| Go 时区处理入门:time.Location、UTC 和用户本地时间 | UTC 存储、本地展示、LoadLocation 与 ParseInLocation 的正确用法 |
| Go regexp 包实战完全指南:正则语法、性能优化与常见模式 | regexp 语法速查、Compile 实现、性能优化与常见模式 |
| Go 入门:regexp 能做什么,不能替你做什么 | regexp 适合做什么、不能替你做什么,以及预编译与分组提取 |
| Go 反射和结构体标签入门:看懂 JSON、校验和框架背后的机制 | 通过 JSON 标签与简单校验器理解结构体标签和框架绑定机制 |
| Go 2025 入门专题目录:从能写小程序到能维护小服务 | 把入门文章按基础工具、HTTP、数据处理、并发、测试与观测排出阅读顺序 |
高频问题速查
| 你遇到的问题 | 先看这一篇 |
|---|---|
| 线上服务内存一直涨,怀疑是泄漏 | go-memory-limit-gogc-2025 |
| 接口偶发 502,想知道重试该怎么做 | go-timeout-retry-backoff-2024 |
| 并发读写 map 直接 panic | go-concurrent-map-patterns-2025 |
| 缓存失效瞬间数据库被打满 | go-singleflight-cache-miss-2024 |
| 服务重启时请求被中断 | go-http-server-shutdown-drain-2025 |
| 调用外部接口慢,但不知道慢在哪 | go-httptrace-client-debug-2024 |
| 不知道某个字段是没提交还是提交了空值 | go-json-patch-style-update-2024 |
| 用 strings.Split 解析 CSV 出问题 | go-csv-reading-writing-2025 |
| 本地能读到的配置文件部署后找不到 | go-working-directory-paths-2025 |
| 想给 handler 写测试但不想起端口 | go-http-handler-testing |
| 想给 HTTP 客户端写测试 | go-httptest-server-client-2025 |
| 日志里不小心打印了密码和 Token | go-log-redaction-basics-2024 |
| 想在启动时就把配置问题拦住 | go-config-validation-2023 |
| 想把模板和静态文件打进二进制 | go-embed-static-assets-2023 |