12.12 学习笔记

一、Gin框架核心

1. 中间件执行顺序及c.Next()作用

核心逻辑

Gin中间件遵循洋葱模型 ,执行顺序由注册顺序决定,c.Next()是"前置逻辑"与"后置逻辑"的分界点:

  • 前置逻辑:按注册顺序执行(先注册先执行);
  • 后置逻辑:按注册逆序执行(后注册先执行);
  • c.Abort()会终止后续中间件/路由执行,直接进入后置逻辑。
代码示例
go 复制代码
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()
常用分析命令
bash 复制代码
# 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)

底层结构
go 复制代码
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)
代码示例
go 复制代码
// 泛型:编译期确定类型
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实现)

go 复制代码
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
协程池示例
go 复制代码
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启动
bash 复制代码
# 拉取镜像 → 创建容器 → 启动进程
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启动容器

核心配置示例
yaml 复制代码
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
相关推荐
li星野1 天前
打工人日报#20251231
笔记
孙严Pay1 天前
分享三种不同的支付体验,各自有着不同的特点与适用场景。
笔记·科技·计算机网络·其他·微信
YJlio1 天前
VolumeID 学习笔记(13.10):卷序列号修改与资产标识管理实战
windows·笔记·学习
weixin_440730501 天前
java数组整理笔记
java·开发语言·笔记
小龙1 天前
【学习笔记】多标签交叉熵损失的原理
笔记·学习·多标签交叉熵损失
知识分享小能手1 天前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04的Linux网络配置(14)
linux·学习·ubuntu
手揽回忆怎么睡1 天前
Streamlit学习实战教程级,一个交互式的机器学习实验平台!
人工智能·学习·机器学习
xiaoxiaoxiaolll1 天前
《Advanced Materials》基于MXene的复合纤维实现智能纺织品多模态功能集成
学习
db_murphy1 天前
学习篇 | 英方i2Active和i2Stream工具了解
学习
强子感冒了1 天前
Java学习笔记:String、StringBuilder与StringBuffer
java·开发语言·笔记·学习