一、Gin框架核心
1. 中间件执行顺序及c.Next()作用
核心逻辑
Gin中间件遵循洋葱模型 ,执行顺序由注册顺序决定,c.Next()是"前置逻辑"与"后置逻辑"的分界点:
- 前置逻辑:按注册顺序执行(先注册先执行);
- 后置逻辑:按注册逆序执行(后注册先执行);
c.Abort()会终止后续中间件/路由执行,直接进入后置逻辑。
代码示例
package main
import (
"github.com/gin-gonic/gin"
"fmt"
)
func m1() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("m1 前置")
c.Next()
fmt.Println("m1 后置")
}
}
func m2() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("m2 前置")
c.Next()
fmt.Println("m2 后置")
}
}
func main() {
r := gin.Default()
r.Use(m1(), m2())
r.GET("/test", func(c *gin.Context) {
fmt.Println("路由执行")
c.JSON(200, gin.H{"msg": "ok"})
})
r.Run(":8080")
}
执行结果:
m1 前置 → m2 前置 → 路由执行 → m2 后置 → m1 后置
二、Go性能分析
1. pprof工具使用
核心定位
内置性能分析工具,支持CPU、内存、协程、阻塞等维度分析,分两种使用方式:
| 使用方式 |
适用场景 |
核心命令 |
| HTTP方式 |
服务端 |
import _ "net/http/pprof" + http.ListenAndServe(":6060", nil) |
| 命令行方式 |
独立程序 |
pprof.StartCPUProfile(f) + pprof.StopCPUProfile() |
常用分析命令
# CPU分析(采样10秒)
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=10
# 内存分析
go tool pprof http://localhost:6060/debug/pprof/heap
# 协程分析
go tool pprof http://localhost:6060/debug/pprof/goroutine
三、Go语法核心
1. defer与return的交互
| 返回值类型 |
是否可修改 |
示例 |
结果 |
| 命名返回变量 |
是 |
func f() (res int) { res=10; defer func(){res=20}(); return res } |
20 |
| 匿名返回值 |
否 |
func f() int { res=10; defer func(){res=20}(); return res } |
10 |
| 指针类型 |
是 |
func f() *int { res=10; defer func(){*&res=20}(); return &res } |
20 |
2. Channel核心(sendq/recvq)
底层结构
type hchan struct {
qcount uint // 队列元素数
dataqsiz uint // 缓冲区容量
buf unsafe.Pointer // 缓冲区指针
recvq waitq // 接收阻塞协程队列
sendq waitq // 发送阻塞协程队列
lock mutex // 互斥锁
}
核心作用
| 队列 |
触发场景 |
设计目的 |
| sendq |
无缓冲Channel无接收方/有缓冲Channel缓冲区满 |
存储阻塞的发送协程,实现同步通信 |
| recvq |
无缓冲Channel无发送方/有缓冲Channel缓冲区空 |
存储阻塞的接收协程,保证数据有序传递 |
设计优势
- 解耦发送/接收协程,无需严格同步;
- FIFO队列保证公平性,避免协程饥饿;
- 统一处理无缓冲/有缓冲Channel的阻塞逻辑。
3. 泛型vs Interface
| 维度 |
泛型编程 |
Interface |
| 核心定位 |
类型抽象(约束数据类型) |
行为抽象(约束方法集合) |
| 类型确定 |
编译期(实例化生成专用代码) |
运行期(通过iface/eface获取类型) |
| 性能开销 |
无运行时开销 |
类型查找/断言开销 |
| 适用场景 |
通用算法/数据结构(如通用排序) |
多态行为封装(如io.Reader) |
代码示例
// 泛型:编译期确定类型
func Sum[T int|float64](s []T) T {
var res T
for _, v := range s {
res += v
}
return res
}
// Interface:运行期确定类型
type Formatter interface {
Format() string
}
func Print(f Formatter) {
fmt.Println(f.Format()) // 运行时确定具体类型
}
四、并发编程
1. 奇偶有序打印(Channel实现)
package main
import "fmt"
func main() {
max := 10
odd, even := make(chan struct{}), make(chan struct{})
// 奇数协程
go func() {
for i := 1; i <= max; i += 2 {
<-odd
fmt.Println(i)
even <- struct{}{}
}
}()
// 偶数协程
go func() {
for i := 2; i <= max; i += 2 {
<-even
fmt.Println(i)
if i == max {
close(odd)
return
}
odd <- struct{}{}
}
}()
odd <- struct{}{} // 启动流程
<-even // 阻塞等待
}
2. 高并发模拟方案
| 方案 |
适用场景 |
核心工具 |
| 原生协程 |
低并发验证 |
sync.WaitGroup |
| 协程池 |
高并发(10万+) |
ants库 |
| 工具压测 |
HTTP接口 |
go-wrk/hey |
协程池示例
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
)
func main() {
pool, _ := ants.NewPool(1000) // 最大并发1000
defer pool.Release()
var wg sync.WaitGroup
wg.Add(10000)
start := time.Now()
for i := 0; i < 10000; i++ {
_ = pool.Submit(func() {
defer wg.Done()
time.Sleep(100 * time.Millisecond)
})
}
wg.Wait()
fmt.Printf("耗时:%v\n", time.Since(start))
}
五、微服务架构
1. 微服务框架对比(Kratos vs Go-Zero)
| 维度 |
Kratos |
Go-Zero |
| 定位 |
企业级、高可扩展 |
轻量、一站式 |
| 代码生成 |
基于Protobuf |
goctl工具(API/Proto双驱动) |
| 服务治理 |
组件解耦、按需集成 |
开箱即用、全量内置 |
| 通信协议 |
优先gRPC |
HTTP/gRPC双支持 |
| 适用场景 |
大规模集群、定制化 |
中小项目、快速落地 |
2. CAP理论
| 特性 |
定义 |
取舍场景 |
典型案例 |
| C(一致性) |
所有节点数据实时一致 |
CP:金融交易 |
Redis主从同步 |
| A(可用性) |
所有请求有限时间响应 |
AP:电商展示 |
商品库存异步同步 |
| P(分区容错) |
网络分区仍可用 |
分布式必选 |
所有分布式系统 |
3. API设计与问题排查
(1)API响应慢排查流程
全局 单个 数据库 缓存 第三方 确认范围 全局/单个接口 检查服务器资源 链路追踪定位慢节点 数据库/缓存/第三方 explain分析SQL 检查命中率 设置超时降级
(2)优质API设计标准
| 维度 |
核心要求 |
| 语义规范 |
RESTful风格 + 版本控制 |
| 响应格式 |
统一code/msg/data结构 |
| 可用性 |
幂等性 + 限流降级 |
| 安全性 |
鉴权 + HTTPS + 防注入 |
| 扩展性 |
预留扩展字段 + 批量操作 |
4. 登录与会话管理
(1)登录流程
前端加密密码 → 后端验证 → 生成凭证(JWT/SessionID)→ 前端存储 → 后续请求校验
(2)Session/Cookie对比
| 维度 |
Session |
Cookie |
| 存储位置 |
服务端(Redis/内存) |
客户端(磁盘/内存) |
| 存储内容 |
复杂对象 |
字符串(≤4KB) |
| 安全性 |
高(服务端存储) |
低(易篡改) |
| 有效期 |
服务端控制 |
客户端持久化 |
(3)分布式会话共享
核心方案:Redis存储SessionID-用户信息映射
1. 登录成功 → 生成SessionID → 存入Redis(设置过期)→ 写入客户端Cookie
2. 跨服务器请求 → 读取Cookie中SessionID → 从Redis获取用户信息 → 校验身份
六、容器与K8s
1. K8s Service核心
| 类型 |
访问范围 |
核心用途 |
| ClusterIP |
集群内 |
服务间通信 |
| NodePort |
集群外 |
简单外部访问 |
| LoadBalancer |
集群外 |
生产环境高可用 |
| ExternalName |
集群内 |
访问外部服务 |
2. 容器启动流程
(1)Docker启动
# 拉取镜像 → 创建容器 → 启动进程
docker pull nginx:1.25
docker run -d -p 8080:80 --name nginx nginx:1.25
(2)K8s启动Pod
提交Pod YAML API Server验证 存入etcd Scheduler调度 kubelet创建容器 containerd拉取镜像 runc启动容器
核心配置示例
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
limits:
cpu: 0.5
memory: 512Mi