go底层相关八股复习
| 特性 | 聚合 (Aggregation) | 组合 (Composition) |
|---|---|---|
| 菱形 | 空心 ◇ | 实心 ◆ |
| 强度 | 弱拥有 | 强拥有 |
| 生命周期 | 部分独立 | 部分与整体同生共死 |
| 共享性 | 部分可被多个整体共享 | 部分仅属于一个整体 |
| 典型例子 | 班级 - 学生、汽车 - 轮胎 | 人 - 心脏、订单 - 订单项、房子 - 房间 |
pk代表主键 fk代表外键
map 必须初始化才能用,零值是 nil,直接赋值会 panic
var m map[string]int // nil map
m[“a”] = 1 // panic: assignment to nil map
m := make(map[string]int)
m[“a”] = 1 // 正常
判断 key 是否存在,不能直接用值
_, ok := m[“a”]
if ok {
// 存在
} else {
// 不存在
}
1 | v := m["key"] |
不能取 map 元素的地址
p := &m[“key”] // 编译错误!
delete () 是安全操作,删不存在的 key 不会报错
delete(m, “not-exist-key”) // 啥事没有,不 panic
map 作为函数参数是传引用(本质是指针包装)
nil map 可以读、可以遍历、可以 delete,但不能写
var m map[string]int
v, ok := m[“a”] // 可以
delete(m, “a”) // 可以
for range m {} // 可以
m[“a”] = 1 // panic
map 中的 map 必须初始化才能用[可以嵌套 map,但内层必须初始化]
m := make(map[string]map[string]int)
m[“outer”] = make(map[string]int) // 必须初始化内层
m[“outer”][“inner”] = 1
cap () 看最大容量,map 不能用
go Map
hmap + 桶数组(bmap)+ 溢出链表
C++ std::map:红黑树,有序,O (log n)
C++ unordered_map:哈希表,无序,类似 Go map
溢出桶
溢出桶是临时方案,不能无限链下去。
map 扩容触发条件(满足其一):
负载因子 ≥ 6.5(元素数 / 桶数)
溢出桶总数 ≥ 桶总数 / 16(链太长)
扩容时:
桶数翻倍(B+1)
所有 KV 重新哈希到新桶
溢出链全部打散,缩短查找路径。
固定窗口的致命问题:边界突刺
假设:1 秒最多允许 5 个请求
第 0.9 秒 来了 5 个
第 1.1 秒 又来了 5 个
这 0.2 秒内,瞬间进来 10 个请求
分布式认证与集中式认证
- 集中式认证(Session 模式)
原理:用户登录后,服务端生成 Session ID,把用户数据存服务端内存 / Redis,只把 SessionId 下发给客户端。
特征:
状态存储在服务端
多服务 / 集群时,必须做 Session 共享(Redis 统一存储),否则登录态失效
认证校验:每次请求服务端都要查存储拿到用户信息
归类:集中式认证 - JWT(JSON Web Token)
原理:登录后,把用户身份、权限、基本信息加密编码进 Token 字符串,全部下发给客户端保存。
特征:
服务端不存储任何会话状态(无状态)
校验逻辑:服务端只做签名验签,解码就能拿到用户信息,不用查第三方存储
多节点、分布式集群、跨服务、跨域名天然支持,无需共享会话
归类:分布式 / 无状态认证
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 皖月清风的个人博客!
评论




