# gostudy **Repository Path**: ursusit/gostudy ## Basic Information - **Project Name**: gostudy - **Description**: go语言的学习笔记。 - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-01-10 - **Last Updated**: 2026-10-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gostudy — Java 工程师的 Go 实战教程 一个**可执行**的 Go 学习仓库:每个知识点都是一个能 `go run` 的示例,配一个能 `go test` 的断言。 目标读者是有多年经验的 Java 后端工程师,学完能直接上手企业级 Go 服务开发。 > 为什么强调"可执行":本仓库的前身有 27 个示例,其中至少 8 条技术断言是**错的** > (例如"append 超容量 cap 就翻倍""ok=true 表示 channel 未关闭""值接收者类型拥有全部方法"), > 而且整个仓库 `go build ./...` 都过不去。 > 这里定的规矩是:**写不出测试的证明,就不写进教程。** - 完整学习路线(10 个阶段、依赖关系、每主题知识点/Java 对照/坑清单):[ROADMAP.md](ROADMAP.md) - Java↔Go 速查表(语言机制、并发、工程与企业栈、版本语义门控):[docs/java-to-go.md](docs/java-to-go.md) - 当前状态:P1~P10 共 55 个主题全部落地、每个都有测试(逐项见 ROADMAP 第八节); 收官项目 `projects/user-api` 已本机端到端跑通(见其 README 的"本机验证记录")。 ## 1. 环境准备(一次就好,5 分钟) ### 1.1 安装 Go 到官方下载页选你系统的安装包:(已实测可访问;国内也可用镜像 )。建议 **Go 1.23 或小版本更高的 1.x**。 装完打开终端,逐条执行下面三行,看到版本号就说明成功(Windows 用 PowerShell 或 Git Bash 都可以): ```bash go version # 期望输出类似:go version go1.23.1 windows/amd64 go env GOROOT # 期望输出 Go 的安装目录 go env GOPATH # 期望输出你的工作区目录(默认 ~/go) ``` 如果 `go version` 报"不是内部或外部命令 / command not found": 把 `go` 可执行文件所在目录(通常是安装目录下的 `bin`)加入系统 `PATH`,然后**重开一个终端**再试。 ### 1.2 国内网络:配置模块代理(可选,但下载依赖慢时必须做) ```bash go env -w GOPROXY=https://goproxy.cn,direct go env GOPROXY # 确认已生效 ``` 本机实测也用阿里云镜像(`https://mirrors.aliyun.com/goproxy/,direct`),两者任选其一即可。 恢复默认:`go env -u GOPROXY`。 ### 1.3 取代码并跑通全部门禁 ```bash git clone https://gitee.com/ursusit/gostudy.git cd gostudy go build ./... go test ./... # 全绿说明环境与代码都没问题 gofmt -l . # 无输出说明格式合规 go vet ./... # 无输出说明静态检查通过 ``` ### 1.4 编辑器 VS Code(装 Go 扩展)或 GoLand 都行。 必开设置:**保存时自动 gofmt**、**启用 gopls**——本仓库以 `gofmt -l .` 零输出为门禁要求(见 §7 与 `tools/check`)。 ## 2. 怎么用这个仓库 ```bash # 跑某个示例(路径就是目录路径) go run ./stages/p1-foundations/04-strings-runes-bytes # 只看某个主题的测试与断言 go test -v ./stages/p1-foundations/04-strings-runes-bytes # 改代码前先看全仓是否还是绿的 go build ./... && go test ./... # 想验证"如果我把 go.mod 的语言版本改低会怎样" # 改 go.mod 的 go 行 → go test ./... → 观察哪些测试失败 → 改回来 ``` 每个主题目录至少两个文件(README 按需补充)。唯一例外是 `p7-engineering/05-packages-layout`, 它的 `func main` 放在 `layout.go` 里而非 `main.go`: | 文件 | 作用 | | --- | --- | | `main.go` | 中文注释陈述"断言 N" + 可运行示例,打印**实测值**而不是靠人眼猜 | | `main_test.go` | 把每条断言变成测试;跑不过就说明教程写错了(这也是给你的工作方式示范) | | `README.md` | 该主题解决什么问题、运行/测试命令、一句话结论 | 学习顺序、每周节奏建议都在 [ROADMAP.md](ROADMAP.md) 第五节。 ## 3. 目录结构 ``` gostudy/ ├── ROADMAP.md 学习路线总纲(先读这个) ├── README.md 本文件 ├── docs/ Java↔Go 对照、版本语义门控与高频带错项(单文件) ├── stages/ 按路线顺序的可运行示例 │ ├── p1-foundations/ 语言基础与类型系统(9 个主题,已完成) │ ├── p2-types-and-abstraction/ 指针·方法·接口·组合·泛型 │ ├── p3-errors/ 错误处理与 panic/recover │ ├── p4-concurrency/ goroutine·channel·sync·context·模式·泄漏 │ ├── p5-io-stdlib/ IO·编码·标准库 │ ├── p6-runtime-internals/ 逃逸分析·内存布局·GC·调度器·pprof │ ├── p7-engineering/ 表驱动测试·fake·benchmark·CI·包布局 │ ├── p8-web-service/ net/http·中间件·gin·服务组装 │ ├── p9-data-layer/ database/sql·GORM·事务·连接池·缓存 │ └── p10-production/ 配置·日志·可观测性·Docker·部署·安全 ├── projects/user-api/ 收官实战:一个可上线的分层用户服务 └── tools/check/ 一条命令跑完质量门禁(跨平台,无需 make) ``` ## 4. 阶段进度 | 阶段 | 内容 | 状态 | | --- | --- | --- | | P1 | 工具链、类型、数值、字符串、控制流、函数、切片、map、struct | ✅ 9 主题,全部有测试 | | P2 | 指针、方法集、接口、组合、泛型 | ✅ 5 主题 | | P3 | error 即值、包装、panic/recover、错误分层 | ✅ 4 主题 | | P4 | goroutine、channel、select、锁、context、并发模式与泄漏 | ✅ 6 主题(`-count=3` 稳定) | | P5 | io、JSON、XML/CSV/base64/hash、time、os/embed、reflect | ✅ 6 个主题全部完成(time 含 Go 1.23 Timer 语义判别实验;os 含 embed 路径坑) | | P6 | 逃逸分析、内存布局、GC、调度器、pprof、性能清单 | ✅ 01~06 全部完成(05 把 CPU + 六种内置画像的取值口径逐条实测;06 把"谁更省"写成能进 CI 的相对断言) | | P7 | 表驱动测试、fake/httptest、benchmark/fuzz、CI 门禁、包布局 | ✅ 01~05 全部完成(04 用 testdata 坏代码实测每道门禁报什么) | | P8 | net/http、client 超时、中间件、gin、服务组装 | ✅ 01~05 全部完成(05 含 liveness/readiness 分离与优雅关停的确定性断言) | | P9 | database/sql、GORM、事务、连接池、缓存 | ✅ 01~04 全部完成(穿透/击穿/雪崩都是可数断言,且不依赖真实数据库) | | P10 | 配置与密钥、构建与交付、日志与 trace、限流熔断、容器调参 | ✅ 01~05 全部完成 | | 项目 | projects/user-api | ✅ 分层 + 离线测试 + Dockerfile;HTTP 全流程本机实测跑通(镜像构建因本机无 docker 未验证) | ## 5. 已知环境限制(如实说明,别当成代码 bug) - **`go test -race` 在本机不可用**:实测本机 `CGO_ENABLED=0` 且无 C 编译器,`-race` 会直接报错。 需要竞态检测时,装 GCC(Windows 用 MSYS2/MinGW-w64,Linux `apt install build-essential`)后执行 `CGO_ENABLED=1 go test -race ./...`。本仓库任何文档都**不会**声称 race 检查已通过, 除非它真的在你手上跑过。 - **不依赖外部数据库**:所有示例默认不联网、不需要 MySQL/Redis 就能跑; 涉及真实中间件的示例统一放在 `p9`/`p10`,用接口 + 内存 fake 演示, 真连库的部分由 build tag 或环境变量开关(见对应 README)。 - 部分示例的**具体数字**(内存占用、benchmark ns/op、map 遍历顺序)随机器与版本变化, 这类断言一律写成"相对关系"而非绝对值。 - **本机没有 docker**:`docker: command not found`,所以涉及镜像构建的内容(`projects/user-api/Dockerfile`、 P10 的容器部分)只做到"文件与官方写法对照",**从未在本机 build 过**。有 docker 的机器上请自行验证。 - **Windows 两个环境坑**(实测,不是代码 bug):8080 常被本机其他服务占用,端口服务要用 `USER_API_ADDR=:18080` 之类换端口;Git Bash 里 `curl -d '{"name":"张三"}'` 的中文会被本机代码页 转成 `????`。两者的现象与对策写在 [projects/user-api/README.md](projects/user-api/README.md) 的"怎么跑"一节。 ## 6. 安全告警(必读) 重建前的 `gobase/` 与 `mysql/` 两个目录已从工作区移除(历史保留在提交 `dea5d45`, 可用 `git checkout dea5d45 -- gobase mysql` 取回)。移除原因:5 个目录因同目录多个 `func main` 导致整仓无法编译、至少 8 条中文技术断言被实测证伪、且其中含密钥泄露。 ⚠️ **`mysql/config/database.go` 曾把真实的内网数据库地址、账号与口令提交进公开仓库, 该内容已进入 git 历史。仅删除文件不足以撤销泄露**,必须: 1. 立即轮换该数据库口令(唯一有效的补救); 2. 若要清除历史,需 `git filter-repo` 重写后强制推送——这是破坏性操作, 会让所有既有克隆失效,需单独决策与团队协作; 3. 新代码一律从环境变量读取凭据,且日志中连**地址**一起脱敏 (见 `stages/p10-production/01-config-and-secrets` 与 `projects/user-api/internal/config`)。 ## 7. Contributing 改任何示例都要遵守三条:① 一个目录只有一个 `func main`;② 新增断言必须同时新增测试; ③ 提交前 `gofmt -l .`、`go vet ./...`、`go build ./...`、`go test ./...` 全部通过。 门禁用仓库内的跨平台工具:`go run ./tools/check`(本仓库托管在 Gitee,不放从未跑过的 GitHub Actions 配置)。