Go 语言从入门到后端项目实战完整指南
适合对象:零基础学习 Go、前端开发转后端、后端开发补充 Go 技术栈、准备 Go 面试、想做 Gin + MySQL + Redis + JWT 项目的开发者。
更新时间:2026-05-28
当前官方下载页显示稳定版本:Go 1.26.3
目录
- [一、Go 语言是什么](#一、Go 语言是什么)
- [二、Go 适合做什么](#二、Go 适合做什么)
- [三、Go 的核心优势](#三、Go 的核心优势)
- [四、Go 环境安装与配置](#四、Go 环境安装与配置)
- [五、Go 项目结构与模块管理](#五、Go 项目结构与模块管理)
- [六、Go 基础语法](#六、Go 基础语法)
- 七、数组、切片、Map
- 八、函数、闭包、defer
- 九、结构体、方法、接口
- [十、错误处理与 panic/recover](#十、错误处理与 panic/recover)
- 十一、指针与内存理解
- 十二、并发编程:Goroutine、Channel、Context
- 十三、标准库重点学习
- [十四、Go Web 开发](#十四、Go Web 开发)
- [十五、Gin 框架开发 API](#十五、Gin 框架开发 API)
- 十六、数据库:MySQL、GORM、Redis
- 十七、登录注册、JWT、权限拦截
- 十八、项目工程化与目录设计
- 十九、测试、日志、配置、接口文档
- [二十、Docker 部署 Go 项目](#二十、Docker 部署 Go 项目)
- 二十一、微服务与云原生方向
- [二十二、Go 常用命令速查](#二十二、Go 常用命令速查)
- [二十三、Go 官方文档与学习资源](#二十三、Go 官方文档与学习资源)
- [二十四、Go 学习路线](#二十四、Go 学习路线)
- [二十五、Go 面试题与答案](#二十五、Go 面试题与答案)
- [二十六、适合练手的 Go 项目](#二十六、适合练手的 Go 项目)
一、Go 语言是什么
Go,也常被称为 Golang,是 Google 推出的开源编程语言。它是一门静态类型、编译型、并发友好、部署简单的语言。
Go 的设计目标不是"语法炫技",而是解决工程开发中的几个真实问题:
- 代码结构清晰,团队协作成本低。
- 编译速度快,适合大型项目。
- 原生支持并发,适合高并发服务。
- 生成单个二进制文件,部署简单。
- 标准库强大,可以直接开发 HTTP 服务、命令行工具、网络程序。
- 非常适合云原生、微服务和基础设施工具开发。
官方文档入口:
二、Go 适合做什么
| 应用方向 | 说明 | 常用技术 |
|---|---|---|
| 后端 API 服务 | 开发 RESTful API、管理后台接口、业务系统接口 | net/http、Gin、Echo、Fiber |
| 微服务 | 多服务拆分、RPC 通信、服务注册发现 | gRPC、Protobuf、Go-Zero、Kratos |
| 云原生 | Kubernetes、Docker、Prometheus 等生态大量使用 Go | Kubernetes、Docker、Helm |
| DevOps 工具 | 自动化部署、命令行工具、运维脚本 | Cobra、Viper、SSH、Shell |
| 高并发系统 | 网关、聊天室、弹幕系统、任务队列 | Goroutine、Channel、Context |
| 中间件 | 网关、代理、缓存、消息系统客户端 | Redis、Kafka、NATS |
| 数据处理 | 日志采集、数据清洗、批处理程序 | 文件 IO、并发、Worker Pool |
| 区块链 | 节点服务、钱包服务、链上工具 | go-ethereum |
| 爬虫采集 | 并发抓取、网页解析、接口采集 | Colly、goquery |
| 命令行工具 | 脚手架、代码生成器、系统工具 | Cobra、urfave/cli |
三、Go 的核心优势
1. 语法简洁
Go 语法比 Java、C++ 更轻量,适合快速上手。
go
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
运行:
bash
go run main.go
编译:
bash
go build -o app main.go
2. 编译部署方便
Go 可以直接编译成二进制文件:
bash
go build -o server main.go
./server
部署时通常只需要上传一个可执行文件,不需要像 Java 一样安装 JVM,也不需要像 Node.js 一样携带大量 node_modules。
3. 并发能力强
Go 使用 Goroutine 实现轻量级并发。
go
go func() {
fmt.Println("异步执行")
}()
配合 Channel,可以实现多个任务之间的通信。
4. 标准库强大
Go 标准库直接提供 HTTP、JSON、文件、时间、加密、测试、并发等能力。
官方标准库文档:
5. 工程化风格统一
Go 官方提供了统一格式化工具:
bash
go fmt ./...
这让团队代码风格更统一,减少无意义的格式争论。
四、Go 环境安装与配置
1. 官方安装入口
2. Windows 安装
- 打开 Go 下载页
- 下载 Windows
.msi安装包 - 一路下一步安装
- 打开 CMD 或 PowerShell 检查:
bash
go version
3. macOS 安装
下载 .pkg 安装包:
bash
go version
如果使用 Homebrew:
bash
brew install go
4. Linux 安装
下载 Linux 压缩包后:
bash
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.26.3.linux-amd64.tar.gz
配置环境变量:
bash
export PATH=$PATH:/usr/local/go/bin
检查:
bash
go version
5. 常用环境变量
查看 Go 环境:
bash
go env
常见变量:
| 变量 | 作用 |
|---|---|
GOROOT |
Go 安装目录 |
GOPATH |
Go 工作区目录,旧项目常见 |
GOMOD |
当前项目 go.mod 文件路径 |
GOPROXY |
Go 模块下载代理 |
GOOS |
目标操作系统 |
GOARCH |
目标 CPU 架构 |
CGO_ENABLED |
是否启用 CGO |
国内常用代理:
bash
go env -w GOPROXY=https://goproxy.cn,direct
恢复默认代理:
bash
go env -w GOPROXY=https://proxy.golang.org,direct
五、Go 项目结构与模块管理
1. 创建项目
bash
mkdir hello-go
cd hello-go
go mod init hello-go
项目结构:
bash
hello-go/
├── go.mod
└── main.go
go.mod 示例:
go
module hello-go
go 1.26
官方模块文档:
2. 安装依赖
bash
go get github.com/gin-gonic/gin
整理依赖:
bash
go mod tidy
查看依赖:
bash
go list -m all
3. go.mod 与 go.sum
| 文件 | 说明 |
|---|---|
go.mod |
记录模块名、Go 版本、依赖版本 |
go.sum |
记录依赖校验值,保证依赖完整性和一致性 |
六、Go 基础语法
1. package
每个 Go 文件都必须声明包名。
go
package main
main 包表示可执行程序入口。
2. import
go
import "fmt"
多个包:
go
import (
"fmt"
"time"
)
3. main 函数
go
func main() {
fmt.Println("程序入口")
}
4. 变量
go
var name string = "张三"
var age int = 20
city := "深圳"
常见写法:
go
var a int = 10
var b = 20
c := 30
注意:
:=只能在函数内部使用。- 声明的变量如果没有使用,Go 会编译报错。
- Go 不支持隐式类型转换。
5. 常量
go
const PI = 3.1415926
const (
StatusOK = 200
StatusNotFound = 404
)
6. iota 枚举
go
const (
Sunday = iota
Monday
Tuesday
Wednesday
)
输出:
text
Sunday = 0
Monday = 1
Tuesday = 2
Wednesday = 3
7. 基础数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
int |
整数 | 10 |
int64 |
64 位整数 | 1000000 |
float64 |
浮点数 | 3.14 |
string |
字符串 | "hello" |
bool |
布尔值 | true |
byte |
uint8 别名 | 'a' |
rune |
int32 别名,常用于中文字符 | '中' |
8. 字符串
go
name := "Go语言"
fmt.Println(len(name))
遍历中文建议使用 range:
go
for index, char := range "你好Go" {
fmt.Println(index, string(char))
}
9. 条件判断
go
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
Go 的 if 条件不需要括号。
10. switch
go
day := 2
switch day {
case 1:
fmt.Println("星期一")
case 2:
fmt.Println("星期二")
default:
fmt.Println("其他")
}
Go 的 switch 默认不会自动穿透,不需要写 break。
如需穿透:
go
fallthrough
11. for 循环
Go 只有 for,没有 while。
go
for i := 0; i < 5; i++ {
fmt.Println(i)
}
类似 while:
go
i := 0
for i < 5 {
fmt.Println(i)
i++
}
死循环:
go
for {
fmt.Println("一直执行")
}
七、数组、切片、Map
1. 数组 Array
数组长度固定。
go
var arr [3]int = [3]int{1, 2, 3}
fmt.Println(arr[0])
自动推断长度:
go
arr := [...]int{1, 2, 3}
2. 切片 Slice
切片长度可变,是 Go 最常用的数据结构之一。
go
nums := []int{1, 2, 3}
nums = append(nums, 4)
fmt.Println(nums)
创建切片:
go
s := make([]int, 0, 10)
含义:
| 参数 | 说明 |
|---|---|
| 第一个参数 | 类型 |
| 第二个参数 | 长度 |
| 第三个参数 | 容量 |
3. 切片截取
go
nums := []int{1, 2, 3, 4, 5}
a := nums[1:3] // [2 3]
b := nums[:3] // [1 2 3]
c := nums[2:] // [3 4 5]
4. 遍历切片
go
for index, value := range nums {
fmt.Println(index, value)
}
5. Map
go
user := map[string]string{
"name": "张三",
"city": "广州",
}
fmt.Println(user["name"])
判断 key 是否存在:
go
value, ok := user["age"]
if ok {
fmt.Println(value)
} else {
fmt.Println("不存在")
}
删除:
go
delete(user, "city")
注意:普通 map 并发读写不安全,高并发场景需要使用锁或 sync.Map。
八、函数、闭包、defer
1. 普通函数
go
func add(a int, b int) int {
return a + b
}
简写:
go
func add(a, b int) int {
return a + b
}
2. 多返回值
go
func calc(a, b int) (int, int) {
return a + b, a - b
}
调用:
go
sum, sub := calc(10, 5)
Go 的错误处理大量使用多返回值:
go
data, err := os.ReadFile("test.txt")
if err != nil {
return err
}
fmt.Println(string(data))
3. 命名返回值
go
func add(a, b int) (sum int) {
sum = a + b
return
}
实际项目中不要滥用命名返回值,否则可读性会下降。
4. 匿名函数
go
fn := func(name string) {
fmt.Println("你好", name)
}
fn("Go")
5. 闭包
go
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
func main() {
c := counter()
fmt.Println(c()) // 1
fmt.Println(c()) // 2
}
闭包可以记住外层函数的变量。
6. defer
defer 表示延迟执行,常用于释放资源。
go
file, err := os.Open("test.txt")
if err != nil {
return
}
defer file.Close()
多个 defer 按后进先出执行:
go
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
输出:
text
3
2
1
九、结构体、方法、接口
1. 结构体 Struct
Go 没有传统 class,但有结构体。
go
type User struct {
ID int
Name string
Age int
}
创建结构体:
go
u := User{
ID: 1,
Name: "张三",
Age: 20,
}
2. 结构体标签
常用于 JSON、数据库映射。
go
type User struct {
ID int `json:"id" gorm:"primaryKey"`
Username string `json:"username" gorm:"size:50"`
Password string `json:"-" gorm:"size:255"`
}
说明:
| 标签 | 作用 |
|---|---|
json:"id" |
JSON 输出字段名 |
json:"-" |
JSON 序列化时忽略 |
gorm:"primaryKey" |
GORM 主键 |
gorm:"size:50" |
数据库字段长度 |
3. 方法
go
type User struct {
Name string
}
func (u User) SayHello() {
fmt.Println("你好,我是", u.Name)
}
调用:
go
u := User{Name: "张三"}
u.SayHello()
4. 值接收者与指针接收者
值接收者:
go
func (u User) GetName() string {
return u.Name
}
指针接收者:
go
func (u *User) SetName(name string) {
u.Name = name
}
选择建议:
| 场景 | 推荐 |
|---|---|
| 不修改结构体 | 值接收者或指针接收者都可以 |
| 需要修改字段 | 指针接收者 |
| 结构体较大 | 指针接收者 |
| 保持方法集一致 | 通常统一用指针接收者 |
5. 接口 Interface
接口是一组方法规范。
go
type Animal interface {
Speak()
}
type Dog struct{}
func (d Dog) Speak() {
fmt.Println("汪汪")
}
func makeSound(a Animal) {
a.Speak()
}
Go 接口是隐式实现的,不需要写 implements。
6. 空接口 any
Go 1.18 后,any 是 interface{} 的别名。
go
func printAny(v any) {
fmt.Println(v)
}
7. 类型断言
go
var value any = "hello"
str, ok := value.(string)
if ok {
fmt.Println(str)
}
十、错误处理与 panic/recover
1. error
go
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}
调用:
go
result, err := divide(10, 0)
if err != nil {
fmt.Println("错误:", err)
return
}
fmt.Println(result)
2. errors.New
go
return errors.New("用户名不能为空")
3. fmt.Errorf
go
return fmt.Errorf("用户ID %d 不存在", id)
4. 错误包装
go
if err != nil {
return fmt.Errorf("查询用户失败: %w", err)
}
判断:
go
errors.Is(err, sql.ErrNoRows)
5. panic
panic 表示程序遇到不可恢复错误。
go
panic("系统严重错误")
实际项目中,不建议随意使用 panic,业务错误应返回 error。
6. recover
go
defer func() {
if err := recover(); err != nil {
fmt.Println("捕获 panic:", err)
}
}()
Web 框架中的 Recovery 中间件通常就是基于类似机制实现。
十一、指针与内存理解
1. 指针基础
go
a := 10
p := &a
fmt.Println(p) // 地址
fmt.Println(*p) // 地址对应的值
| 符号 | 说明 |
|---|---|
&变量 |
获取变量地址 |
*指针 |
获取指针指向的值 |
2. 修改外部变量
go
func change(num *int) {
*num = 100
}
func main() {
a := 10
change(&a)
fmt.Println(a) // 100
}
3. new 与 make 区别
go
p := new(int)
*p = 10
go
s := make([]int, 0, 10)
m := make(map[string]int)
ch := make(chan int)
| 对比 | new | make |
|---|---|---|
| 用途 | 分配内存 | 初始化 slice、map、channel |
| 返回值 | 指针 | 类型本身 |
| 常用对象 | 基础类型、结构体 | slice、map、channel |
十二、并发编程:Goroutine、Channel、Context
1. Goroutine
go
func task(name string) {
for i := 1; i <= 3; i++ {
fmt.Println(name, i)
time.Sleep(time.Second)
}
}
func main() {
go task("任务A")
go task("任务B")
time.Sleep(4 * time.Second)
}
2. WaitGroup
等待多个 Goroutine 完成:
go
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Println("任务", id)
}(i)
}
wg.Wait()
3. Channel
go
ch := make(chan string)
go func() {
ch <- "任务完成"
}()
msg := <-ch
fmt.Println(msg)
4. 缓冲 Channel
go
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
5. select
go
select {
case msg := <-ch1:
fmt.Println("ch1:", msg)
case msg := <-ch2:
fmt.Println("ch2:", msg)
case <-time.After(time.Second):
fmt.Println("超时")
}
6. Mutex
go
var count int
var mu sync.Mutex
func add() {
mu.Lock()
defer mu.Unlock()
count++
}
7. RWMutex
读多写少时使用:
go
var mu sync.RWMutex
mu.RLock()
// 读操作
mu.RUnlock()
mu.Lock()
// 写操作
mu.Unlock()
8. Context
context 用于超时控制、取消控制、请求链路传值。
go
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
select {
case <-time.After(3 * time.Second):
fmt.Println("任务完成")
case <-ctx.Done():
fmt.Println("任务超时:", ctx.Err())
}
Web 请求、数据库查询、RPC 调用都应该尽量传递 context.Context。
9. Worker Pool 示例
go
func worker(id int, jobs <-chan int, results chan<- int) {
for job := range jobs {
fmt.Println("worker", id, "处理任务", job)
results <- job * 2
}
}
func main() {
jobs := make(chan int, 5)
results := make(chan int, 5)
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 5; a++ {
fmt.Println(<-results)
}
}
十三、标准库重点学习
官方标准库文档:
| 标准库 | 作用 | 学习重点 |
|---|---|---|
fmt |
格式化输入输出 | Println、Printf、Sprintf |
os |
操作系统接口 | 文件、环境变量、退出程序 |
io |
输入输出抽象 | Reader、Writer |
bufio |
缓冲 IO | 逐行读取文件 |
strings |
字符串处理 | 分割、替换、包含判断 |
strconv |
字符串与数字转换 | Atoi、Itoa |
time |
时间处理 | 格式化、定时器、超时 |
net/http |
HTTP 服务与客户端 | 路由、请求、响应 |
encoding/json |
JSON 编码解码 | Marshal、Unmarshal |
database/sql |
数据库标准接口 | 连接池、查询、事务 |
sync |
并发同步 | Mutex、WaitGroup |
context |
上下文控制 | 超时、取消、链路传值 |
testing |
单元测试 | 测试函数、基准测试 |
log/slog |
结构化日志 | JSON 日志、分级日志 |
十四、Go Web 开发
1. 原生 net/http
go
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello Go Web")
}
func main() {
http.HandleFunc("/", hello)
http.ListenAndServe(":8080", nil)
}
访问:
text
http://localhost:8080
2. JSON API
go
func users(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
data := map[string]any{
"code": 200,
"msg": "success",
"data": []string{"张三", "李四"},
}
json.NewEncoder(w).Encode(data)
}
3. HTTP 客户端
go
resp, err := http.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
十五、Gin 框架开发 API
Gin 官方文档:
1. 安装 Gin
bash
go get github.com/gin-gonic/gin
2. Hello Gin
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello Gin",
})
})
r.Run(":8080")
}
3. 路由分组
go
api := r.Group("/api")
{
api.GET("/users", listUsers)
api.POST("/users", createUser)
}
4. 获取 Query 参数
go
func listUsers(c *gin.Context) {
page := c.DefaultQuery("page", "1")
keyword := c.Query("keyword")
c.JSON(200, gin.H{
"page": page,
"keyword": keyword,
})
}
5. 获取 Path 参数
go
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(200, gin.H{"id": id})
})
6. 接收 JSON
go
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
func login(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "参数错误"})
return
}
c.JSON(200, gin.H{"message": "登录成功"})
}
7. 中间件
go
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(401, gin.H{"error": "未登录"})
c.Abort()
return
}
c.Next()
}
}
使用:
go
admin := r.Group("/admin")
admin.Use(AuthMiddleware())
{
admin.GET("/dashboard", dashboard)
}
十六、数据库:MySQL、GORM、Redis
1. database/sql
MySQL 驱动:
安装:
bash
go get github.com/go-sql-driver/mysql
连接:
go
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
err = db.Ping()
if err != nil {
panic(err)
}
2. GORM
GORM 官方文档:
安装:
bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
连接 MySQL:
go
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("数据库连接失败")
}
模型:
go
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"unique;size:50" json:"username"`
Password string `gorm:"size:255" json:"-"`
Nickname string `gorm:"size:50" json:"nickname"`
}
自动迁移:
go
db.AutoMigrate(&User{})
创建:
go
db.Create(&User{
Username: "admin",
Password: "123456",
Nickname: "管理员",
})
查询:
go
var user User
db.Where("username = ?", "admin").First(&user)
更新:
go
db.Model(&user).Update("nickname", "超级管理员")
删除:
go
db.Delete(&user)
3. Redis
Go Redis 官方仓库:
安装:
bash
go get github.com/redis/go-redis/v9
连接:
go
import (
"context"
"github.com/redis/go-redis/v9"
)
var ctx = context.Background()
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "name", "Go", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "name").Result()
fmt.Println(val)
Redis 常见用途:
| 场景 | 说明 |
|---|---|
| 登录 Token 缓存 | 保存 JWT 黑名单或 session |
| 验证码 | 设置短期过期时间 |
| 排行榜 | Sorted Set |
| 限流 | 计数器、滑动窗口 |
| 缓存热点数据 | 减少数据库压力 |
十七、登录注册、JWT、权限拦截
1. 安装 JWT 包
bash
go get github.com/golang-jwt/jwt/v5
官方仓库:
2. 生成 Token
go
type CustomClaims struct {
UserID uint `json:"user_id"`
Username string `json:"username"`
jwt.RegisteredClaims
}
func GenerateToken(userID uint, username string) (string, error) {
claims := CustomClaims{
UserID: userID,
Username: username,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte("your-secret-key"))
}
3. 解析 Token
go
func ParseToken(tokenString string) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (any, error) {
return []byte("your-secret-key"), nil
})
if err != nil {
return nil, err
}
claims, ok := token.Claims.(*CustomClaims)
if !ok || !token.Valid {
return nil, errors.New("无效 token")
}
return claims, nil
}
4. Gin 登录拦截中间件
go
func JWTAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.JSON(401, gin.H{"code": 401, "msg": "请先登录"})
c.Abort()
return
}
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
c.JSON(401, gin.H{"code": 401, "msg": "Token 格式错误"})
c.Abort()
return
}
claims, err := ParseToken(parts[1])
if err != nil {
c.JSON(401, gin.H{"code": 401, "msg": "Token 无效或已过期"})
c.Abort()
return
}
c.Set("userID", claims.UserID)
c.Set("username", claims.Username)
c.Next()
}
}
5. 前后端配合逻辑
以前端 Vue/React 项目为例:
- 用户输入账号密码。
- 前端调用
/api/login。 - 后端校验账号密码。
- 后端生成 JWT 返回给前端。
- 前端保存 token。
- 后续请求在 Header 中携带:
http
Authorization: Bearer token内容
- 后端中间件验证 token。
- 验证成功放行,失败返回 401。
- 前端拦截 401,跳转登录页。
十八、项目工程化与目录设计
1. 中小型项目目录
bash
go-admin-api/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── config/
│ ├── handler/
│ ├── middleware/
│ ├── model/
│ ├── repository/
│ ├── router/
│ ├── service/
│ └── response/
├── pkg/
│ ├── jwt/
│ ├── logger/
│ └── utils/
├── configs/
│ └── config.yaml
├── docs/
├── scripts/
├── Dockerfile
├── docker-compose.yml
├── go.mod
└── README.md
2. 分层说明
| 层级 | 作用 |
|---|---|
cmd |
程序入口 |
internal/config |
配置加载 |
internal/router |
路由注册 |
internal/handler |
接收请求、参数校验、返回响应 |
internal/service |
业务逻辑 |
internal/repository |
数据库操作 |
internal/model |
数据模型 |
internal/middleware |
中间件 |
pkg |
可复用工具包 |
configs |
配置文件 |
docs |
接口文档 |
scripts |
构建和部署脚本 |
3. 推荐请求流程
#mermaid-svg-9zYB6jKhQA3BI8am{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9zYB6jKhQA3BI8am .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9zYB6jKhQA3BI8am .error-icon{fill:#552222;}#mermaid-svg-9zYB6jKhQA3BI8am .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9zYB6jKhQA3BI8am .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9zYB6jKhQA3BI8am .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9zYB6jKhQA3BI8am .marker.cross{stroke:#333333;}#mermaid-svg-9zYB6jKhQA3BI8am svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9zYB6jKhQA3BI8am p{margin:0;}#mermaid-svg-9zYB6jKhQA3BI8am .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9zYB6jKhQA3BI8am .cluster-label text{fill:#333;}#mermaid-svg-9zYB6jKhQA3BI8am .cluster-label span{color:#333;}#mermaid-svg-9zYB6jKhQA3BI8am .cluster-label span p{background-color:transparent;}#mermaid-svg-9zYB6jKhQA3BI8am .label text,#mermaid-svg-9zYB6jKhQA3BI8am span{fill:#333;color:#333;}#mermaid-svg-9zYB6jKhQA3BI8am .node rect,#mermaid-svg-9zYB6jKhQA3BI8am .node circle,#mermaid-svg-9zYB6jKhQA3BI8am .node ellipse,#mermaid-svg-9zYB6jKhQA3BI8am .node polygon,#mermaid-svg-9zYB6jKhQA3BI8am .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9zYB6jKhQA3BI8am .rough-node .label text,#mermaid-svg-9zYB6jKhQA3BI8am .node .label text,#mermaid-svg-9zYB6jKhQA3BI8am .image-shape .label,#mermaid-svg-9zYB6jKhQA3BI8am .icon-shape .label{text-anchor:middle;}#mermaid-svg-9zYB6jKhQA3BI8am .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9zYB6jKhQA3BI8am .rough-node .label,#mermaid-svg-9zYB6jKhQA3BI8am .node .label,#mermaid-svg-9zYB6jKhQA3BI8am .image-shape .label,#mermaid-svg-9zYB6jKhQA3BI8am .icon-shape .label{text-align:center;}#mermaid-svg-9zYB6jKhQA3BI8am .node.clickable{cursor:pointer;}#mermaid-svg-9zYB6jKhQA3BI8am .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9zYB6jKhQA3BI8am .arrowheadPath{fill:#333333;}#mermaid-svg-9zYB6jKhQA3BI8am .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9zYB6jKhQA3BI8am .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9zYB6jKhQA3BI8am .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9zYB6jKhQA3BI8am .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9zYB6jKhQA3BI8am .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9zYB6jKhQA3BI8am .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9zYB6jKhQA3BI8am .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9zYB6jKhQA3BI8am .cluster text{fill:#333;}#mermaid-svg-9zYB6jKhQA3BI8am .cluster span{color:#333;}#mermaid-svg-9zYB6jKhQA3BI8am div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9zYB6jKhQA3BI8am .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9zYB6jKhQA3BI8am rect.text{fill:none;stroke-width:0;}#mermaid-svg-9zYB6jKhQA3BI8am .icon-shape,#mermaid-svg-9zYB6jKhQA3BI8am .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9zYB6jKhQA3BI8am .icon-shape p,#mermaid-svg-9zYB6jKhQA3BI8am .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9zYB6jKhQA3BI8am .icon-shape .label rect,#mermaid-svg-9zYB6jKhQA3BI8am .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9zYB6jKhQA3BI8am .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9zYB6jKhQA3BI8am .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9zYB6jKhQA3BI8am :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 前端请求
Router 路由
Middleware 中间件
Handler 控制器
Service 业务层
Repository 数据访问层
MySQL/Redis
统一响应
十九、测试、日志、配置、接口文档
1. 单元测试
官方测试文档:
测试文件以 _test.go 结尾。
go
func Add(a, b int) int {
return a + b
}
测试:
go
func TestAdd(t *testing.T) {
got := Add(1, 2)
want := 3
if got != want {
t.Errorf("got %d, want %d", got, want)
}
}
运行:
bash
go test ./...
查看覆盖率:
bash
go test -cover ./...
2. 日志
Go 标准库结构化日志:
常用第三方日志:
Zap 示例:
bash
go get go.uber.org/zap
go
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("用户登录", zap.String("username", "admin"))
3. 配置管理 Viper
官方仓库:
安装:
bash
go get github.com/spf13/viper
配置文件:
yaml
server:
port: 8080
mysql:
dsn: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local
读取:
go
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("./configs")
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
port := viper.GetString("server.port")
4. 接口文档 Swagger
常用工具:
安装:
bash
go install github.com/swaggo/swag/cmd/swag@latest
生成:
bash
swag init
二十、Docker 部署 Go 项目
1. Dockerfile
dockerfile
FROM golang:1.26 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o server ./cmd/server
FROM debian:bookworm-slim
WORKDIR /app
COPY --from=builder /app/server /app/server
COPY --from=builder /app/configs /app/configs
EXPOSE 8080
CMD ["./server"]
2. 构建镜像
bash
docker build -t go-admin-api .
运行:
bash
docker run -d -p 8080:8080 --name go-admin-api go-admin-api
3. docker-compose 示例
yaml
services:
mysql:
image: mysql:8.0
container_name: go-mysql
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: go_admin
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:7
container_name: go-redis
ports:
- "6379:6379"
api:
build: .
container_name: go-admin-api
ports:
- "8080:8080"
depends_on:
- mysql
- redis
volumes:
mysql-data:
二十一、微服务与云原生方向
1. gRPC
官方文档:
适合服务内部通信,常用于微服务架构。
2. Go-Zero
适合快速构建微服务,内置 API、RPC、限流、熔断、代码生成等能力。
3. Kratos
Bilibili 开源的 Go 微服务框架,适合企业级微服务项目。
4. Kitex
字节跳动 CloudWeGo 生态中的高性能 RPC 框架。
5. 云原生相关资源
| 资源 | 链接 |
|---|---|
| Kubernetes | https://kubernetes.io/ |
| Docker | https://docs.docker.com/ |
| Helm | https://helm.sh/ |
| Prometheus | https://prometheus.io/ |
| OpenTelemetry | https://opentelemetry.io/ |
二十二、Go 常用命令速查
| 命令 | 作用 |
|---|---|
go version |
查看 Go 版本 |
go env |
查看 Go 环境变量 |
go run main.go |
运行 Go 文件 |
go build |
编译项目 |
go build -o app |
编译并指定输出文件 |
go mod init 项目名 |
初始化模块 |
go get 包名 |
安装依赖 |
go mod tidy |
整理依赖 |
go test ./... |
运行所有测试 |
go test -cover ./... |
查看测试覆盖率 |
go fmt ./... |
格式化代码 |
go vet ./... |
静态检查 |
go list -m all |
查看所有模块依赖 |
go clean -modcache |
清理模块缓存 |
go install 包路径@版本 |
安装命令行工具 |
go doc 包名 |
查看包文档 |
go help |
查看帮助 |
官方命令文档:
二十三、Go 官方文档与学习资源
1. Go 官方核心文档
| 资源 | 链接 | 说明 |
|---|---|---|
| Go 官网 | https://go.dev/ | Go 官方入口 |
| Go 下载 | https://go.dev/dl/ | 下载稳定版本 |
| Go 官方文档 | https://go.dev/doc/ | 文档总入口 |
| Installing Go | https://go.dev/doc/install | 安装教程 |
| Getting Started | https://go.dev/doc/tutorial/getting-started | 官方入门教程 |
| Create a module | https://go.dev/doc/tutorial/create-module | 创建模块教程 |
| A Tour of Go | https://go.dev/tour/ | 交互式入门教程 |
| Effective Go | https://go.dev/doc/effective_go | Go 惯用写法 |
| How to Write Go Code | https://go.dev/doc/code | 如何组织 Go 代码 |
| Go Standard Library | https://pkg.go.dev/std | 标准库文档 |
| Go Packages | https://pkg.go.dev/ | 第三方包搜索 |
| Go Language Specification | https://go.dev/ref/spec | 语言规范 |
| Go Modules Reference | https://go.dev/ref/mod | 模块管理参考 |
| Go Release History | https://go.dev/doc/devel/release | 版本发布历史 |
| Go Blog | https://go.dev/blog/ | 官方博客 |
| Go Wiki | https://go.dev/wiki/ | 社区 Wiki |
| Go GitHub | https://github.com/golang/go | Go 源码仓库 |
2. Go 官方专题教程
| 资源 | 链接 | 说明 |
|---|---|---|
| RESTful API with Go and Gin | https://go.dev/doc/tutorial/web-service-gin | 官方 Gin API 教程 |
| Writing Web Applications | https://go.dev/doc/articles/wiki/ | 官方 Web 应用教程 |
| Getting started with generics | https://go.dev/doc/tutorial/generics | 泛型入门 |
| Getting started with fuzzing | https://go.dev/doc/tutorial/fuzz | 模糊测试 |
| Managing dependencies | https://go.dev/doc/modules/managing-dependencies | 依赖管理 |
| Workspaces | https://go.dev/doc/tutorial/workspaces | 多模块工作区 |
| Coverage | https://go.dev/doc/build-cover | 测试覆盖率 |
| Diagnostics | https://go.dev/doc/diagnostics | 性能诊断 |
| GC Guide | https://go.dev/doc/gc-guide | 垃圾回收指南 |
| Profile-guided Optimization | https://go.dev/doc/pgo | PGO 优化 |
3. 常用 Web / 后端框架文档
| 类型 | 名称 | 链接 |
|---|---|---|
| Web 框架 | Gin | https://gin-gonic.com/ |
| Web 框架 | Echo | https://echo.labstack.com/ |
| Web 框架 | Fiber | https://gofiber.io/ |
| ORM | GORM | https://gorm.io/ |
| ORM | Ent | https://entgo.io/ |
| MySQL 驱动 | go-sql-driver/mysql | https://github.com/go-sql-driver/mysql |
| Redis 客户端 | go-redis | https://redis.uptrace.dev/ |
| JWT | golang-jwt/jwt | https://github.com/golang-jwt/jwt |
| 配置 | Viper | https://github.com/spf13/viper |
| CLI | Cobra | https://github.com/spf13/cobra |
| 日志 | Zap | https://github.com/uber-go/zap |
| 日志 | Zerolog | https://github.com/rs/zerolog |
| 测试断言 | Testify | https://github.com/stretchr/testify |
| Swagger | swaggo/swag | https://github.com/swaggo/swag |
4. 微服务与云原生资源
| 类型 | 名称 | 链接 |
|---|---|---|
| RPC | gRPC Go | https://grpc.io/docs/languages/go/ |
| 协议 | Protocol Buffers | https://protobuf.dev/ |
| 微服务框架 | Go-Zero | https://go-zero.dev/ |
| 微服务框架 | Kratos | https://go-kratos.dev/ |
| RPC 框架 | Kitex | https://www.cloudwego.io/docs/kitex/ |
| 服务注册 | Etcd | https://etcd.io/ |
| 容器 | Docker | https://docs.docker.com/ |
| 编排 | Kubernetes | https://kubernetes.io/docs/ |
| 可观测性 | Prometheus | https://prometheus.io/docs/ |
| 链路追踪 | OpenTelemetry | https://opentelemetry.io/docs/ |
5. 免费学习资源
| 资源 | 链接 | 说明 |
|---|---|---|
| Go by Example | https://gobyexample.com/ | 通过例子学习 Go |
| Learn Go with Tests | https://quii.gitbook.io/learn-go-with-tests | 用测试驱动学习 Go |
| Go 101 | https://go101.org/ | 语法、运行时、底层知识 |
| Awesome Go | https://github.com/avelino/awesome-go | Go 生态资源合集 |
| Exercism Go Track | https://exercism.org/tracks/go | 在线练习 |
| Go Patterns | https://github.com/tmrts/go-patterns | Go 设计模式 |
| 100 Go Mistakes | https://100go.co/ | Go 常见错误与最佳实践 |
| Go Proverbs | https://go-proverbs.github.io/ | Go 编程箴言 |
二十四、Go 学习路线
第一阶段:基础语法
学习内容:
- Go 环境安装
- 变量、常量、数据类型
- 条件判断、循环
- 数组、切片、Map
- 函数、多返回值
- 结构体、方法
- 指针
- 接口
- 错误处理
练习项目:
- 命令行计算器
- 学生成绩管理系统
- 文件读取统计工具
- JSON 格式化工具
第二阶段:并发编程
学习内容:
- Goroutine
- Channel
- WaitGroup
- Mutex / RWMutex
- Context
- Select
- Worker Pool
- 定时任务
练习项目:
- 并发下载器
- 并发爬虫
- 批量图片压缩工具
- 任务队列模拟器
第三阶段:Web 后端开发
学习内容:
net/http- Gin 路由
- 请求参数绑定
- JSON 响应
- 中间件
- 文件上传
- 跨域处理
- 统一错误处理
练习项目:
- 用户管理 API
- 博客系统 API
- 文件上传服务
- 后台管理系统接口
第四阶段:数据库与缓存
学习内容:
- MySQL 基础
- SQL CRUD
- GORM
- 事务
- 连接池
- Redis
- 缓存设计
- 数据库索引
练习项目:
- 用户登录注册
- 文章管理系统
- 商品管理系统
- 短链接系统
第五阶段:工程化
学习内容:
- 项目分层
- 配置管理
- 日志系统
- 单元测试
- 接口文档
- 错误码设计
- Docker 部署
- CI/CD
练习项目:
- Go Gin 企业级后台 API
- Vue/React + Go 前后端分离项目
第六阶段:微服务
学习内容:
- gRPC
- Protobuf
- 服务注册发现
- 配置中心
- 限流熔断
- 链路追踪
- 消息队列
- Kubernetes
练习项目:
- 微服务商城
- 订单支付系统
- 分布式任务调度系统
二十五、Go 面试题与答案
1. Go 语言有什么特点?
Go 的特点包括:语法简洁、编译速度快、部署简单、并发能力强、标准库丰富、工程化规范统一。适合后端服务、微服务、云原生、命令行工具等场景。
2. Go 是面向对象语言吗?
Go 不属于传统面向对象语言。它没有 class、extends、implements,但支持结构体、方法、接口和组合,可以实现面向对象中的封装、多态和代码复用。
3. Go 如何实现继承?
Go 不支持传统继承,通常使用结构体组合实现复用。
go
type Animal struct {
Name string
}
type Dog struct {
Animal
}
4. Go 如何实现多态?
通过接口实现多态。只要某个类型实现了接口的所有方法,就自动实现该接口。
5. Goroutine 是什么?
Goroutine 是 Go 的轻量级并发执行单元,用 go 关键字启动。
go
go task()
6. Goroutine 和线程有什么区别?
Goroutine 更轻量,由 Go 运行时调度;线程由操作系统调度。一个程序可以轻松创建大量 Goroutine,但不能随意创建大量系统线程。
7. Channel 是什么?
Channel 是 Go 中用于 Goroutine 通信的管道。
go
ch := make(chan int)
ch <- 1
value := <-ch
8. 无缓冲 Channel 和有缓冲 Channel 区别?
无缓冲 Channel 发送和接收必须同时准备好,否则阻塞。有缓冲 Channel 可以在缓冲区未满时发送,在缓冲区非空时接收。
9. select 有什么用?
select 用来监听多个 Channel,哪个 Channel 准备好就执行哪个 case,常用于超时控制、多路复用和取消任务。
10. defer 执行顺序是什么?
多个 defer 按后进先出执行,类似栈。
11. new 和 make 区别?
new 分配内存并返回指针;make 用于初始化 slice、map、channel,并返回类型本身。
12. slice 和 array 区别?
array 长度固定,是值类型;slice 长度可变,是对底层数组的引用描述。
13. map 是否并发安全?
普通 map 并发读写不安全。如果多个 Goroutine 同时读写 map,需要使用 sync.Mutex、sync.RWMutex 或 sync.Map。
14. interface 是什么?
interface 是方法集合。任何类型只要实现了接口中的全部方法,就隐式实现该接口。
15. 空接口有什么用?
空接口可以接收任意类型。Go 1.18 后通常使用 any 表示空接口。
16. Go 如何处理错误?
Go 通常通过返回 error 处理错误。
go
result, err := doSomething()
if err != nil {
return err
}
17. panic 和 error 区别?
error 用于可预期的业务错误;panic 用于不可恢复的严重错误。业务代码不建议频繁使用 panic。
18. recover 有什么用?
recover 可以捕获 panic,避免程序崩溃。通常配合 defer 使用。
19. context 有什么用?
context 用于请求链路中的超时控制、取消控制和传递少量请求级数据。
20. Go Modules 是什么?
Go Modules 是 Go 官方依赖管理机制,用 go.mod 和 go.sum 管理模块和依赖版本。
21. go mod tidy 有什么用?
go mod tidy 会移除无用依赖,补全缺失依赖,并更新 go.sum。
22. GMP 模型是什么?
GMP 是 Go 运行时调度模型:
| 名称 | 含义 |
|---|---|
| G | Goroutine |
| M | Machine,系统线程 |
| P | Processor,调度上下文 |
Go 调度器通过 GMP 模型将大量 Goroutine 调度到较少的系统线程上执行。
23. 值接收者和指针接收者怎么选?
需要修改结构体字段时使用指针接收者;结构体较大时也建议使用指针接收者;如果方法集需要统一,通常全部使用指针接收者。
24. Go 如何实现接口隔离?
定义小接口,只暴露调用方真正需要的方法。例如只需要读数据,就定义 Reader 接口,而不是定义一个很大的接口。
25. Go 中 init 函数什么时候执行?
init 函数在包初始化时自动执行,先初始化导入包,再初始化当前包,最后执行 main 函数。
26. Go 的 GC 是什么?
GC 是垃圾回收机制,用于自动回收不再使用的内存。Go 的 GC 适合服务端应用,但高性能场景仍需要减少不必要的内存分配。
27. Go 如何做性能分析?
使用 pprof。
相关文档:
28. Go 如何做单元测试?
测试文件以 _test.go 结尾,测试函数以 Test 开头。
go
func TestAdd(t *testing.T) {
got := Add(1, 2)
if got != 3 {
t.Fatal("结果错误")
}
}
运行:
bash
go test ./...
29. Gin 中间件原理是什么?
Gin 中间件本质是一个 gin.HandlerFunc,可以在请求到达业务 Handler 前后执行逻辑,例如鉴权、日志、跨域、异常恢复。
30. JWT 登录流程是什么?
- 用户登录。
- 后端验证账号密码。
- 后端生成 JWT。
- 前端保存 token。
- 前端请求接口时携带 token。
- 后端中间件解析 token。
- 解析成功放行,失败返回 401。
二十六、适合练手的 Go 项目
1. 入门项目
| 项目 | 技术点 |
|---|---|
| 命令行 Todo | 文件 IO、JSON、命令行参数 |
| 学生成绩管理 | 结构体、切片、Map |
| 文件批量重命名 | os、filepath |
| 日志分析工具 | 文件读取、字符串处理 |
| JSON 格式化工具 | encoding/json |
2. Web 项目
| 项目 | 技术点 |
|---|---|
| 用户登录注册系统 | Gin、MySQL、JWT |
| 博客 API | CRUD、分页、分类、标签 |
| 文件上传服务 | multipart、静态资源 |
| 商品管理系统 | GORM、事务、权限 |
| 后台管理 API | RBAC、菜单、角色、权限 |
3. 进阶项目
| 项目 | 技术点 |
|---|---|
| 短链接系统 | Redis、MySQL、哈希算法 |
| WebSocket 聊天室 | WebSocket、Goroutine、Channel |
| 秒杀系统 | Redis、限流、消息队列 |
| 分布式任务调度 | Worker Pool、RPC、定时器 |
| 微服务商城 | gRPC、服务注册、网关、链路追踪 |
推荐你作为前端开发工程师的学习路径
你有前端基础,学习 Go 不建议只看语法,而应该尽快结合前后端分离项目。
推荐路线:
text
Go 基础语法
↓
Gin Web API
↓
MySQL + GORM
↓
Redis
↓
JWT 登录鉴权
↓
Vue/React 调用 Go 接口
↓
Docker 部署
↓
Nginx 反向代理
↓
微服务与 gRPC
最推荐练手项目:
text
Vue3 / React + Go Gin + MySQL + Redis 后台管理系统
核心功能:
- 登录注册
- JWT 鉴权
- 用户管理
- 角色管理
- 菜单管理
- 权限控制
- 文件上传
- 操作日志
- 数据分页
- 搜索筛选
- Docker 部署
- Nginx 反向代理
总结
Go 是一门非常适合后端、微服务、云原生和高并发场景的语言。它的语法不复杂,但工程能力很强。学习 Go 的关键不是死记语法,而是通过项目掌握:
- Go 基础语法
- 并发模型
- Web API 开发
- 数据库操作
- 登录鉴权
- 项目分层
- 测试与日志
- Docker 部署
- 微服务思想
如果你已经会 Vue、React 或 JavaScript,Go 是非常适合作为后端补充技能的语言。前端 + Go 后端的组合,在个人项目、企业后台、接口服务、部署上线方面都非常实用。