go语言基础学习十三
sync.Pool有什么用途?#
一、用途#
- 缓存短期临时对象([] byte、临时结构体),复用内存
- 减少频繁堆分配,降低 GC 压力,提升高并发性能
- 协程安全,无需手动加锁
二、原理#
- 结构:每个 P 独立poolLocal(1 个无锁 private + 共享链表 shared),额外设置victim旧缓存区
- Get 顺序:当前 P 私有 → 同 P 共享链表 → victim 旧缓存 → New 新建
- Put 顺序:有空 private 就存入,否则追加到 shared
- GC 双缓冲机制:每次 GC 把当前 local 迁移到 victim,新建空 local;下一轮 GC 直接废弃 victim;闲置池对象最多留存两轮 GC 周期
- 性能优化:缓存行填充规避伪共享,shared 只用 CAS 原子操作,极少锁竞
反射机制是什么?如何使用?#
概念:程序运行期动态获取变量的类型、字段、方法,并且能读写字段、调用方法#
核心包与两大入口#
reflect.TypeOf(x):拿类型信息 reflect.ValueOf(x):拿值信息
- 获取基础类型
package main
import (
"fmt"
"reflect"
)
func main() {
var a int = 10
t := reflect.TypeOf(a)
v := reflect.ValueOf(a)
fmt.Println(t.Kind(), t.Name()) // int int
fmt.Println(v.Int()) // 10
}
//Kind:底层大类(int、struct、slice、ptr 等)
//Name:自定义类型名,基础类型和 Kind 一致
- 操作结构体
type User struct {
Name string `tag:"uname"`
Age int
}
func main() {
u := User{Name: "张三", Age: 20}
t := reflect.TypeOf(u)
v := reflect.ValueOf(u)
// 遍历所有字段
for i := 0; i < t.NumField(); i++ {
ft := t.Field(i)
fv := v.Field(i)
fmt.Println("字段名:", ft.Name, "值:", fv.Interface(), "标签:", ft.Tag.Get("tag"))
}
}
//字段名: Name 值: 张三 标签: uname
//字段名: Age 值: 20 标签:
- 修改结构体字段
u := User{}
v := reflect.ValueOf(&u).Elem() // Elem()解指针
nameField := v.FieldByName("Name")
if nameField.CanSet() {
nameField.SetString("李四")
}
fmt.Println(u)
原创
go-13
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法