转转转后端

文章发布时间:

最后更新时间:

自我介绍,介绍项目

8年代码经验 算法(noip),全栈,团队沟通,基础(成绩,os,db,计网,组原都有认真手写lab或黑皮书), AI (llm推理引擎,Yolov8,RL) 实习 项目:创业,招新(2年,近万人) 实习:所有浏览器功能(权限,生态,优化) 1框架(组件拦截) 2:截图自定义海报接口 3需求管理机器人 4团购券

! ai工具使用

  1. 学习、lab:不用
  2. 业务项目:把所有 框架(数据关系,这个接口的效果和数据方式)(生成,后期不会让他修,因为代码量大,涉及文件多,不如自己改快)

强制缓存和协商缓存

https://xiaolincoding.com/network/2_http/http_interview.html#%E4%BB%80%E4%B9%88%E6%98%AF%E5%BC%BA%E5%88%B6%E7%BC%93%E5%AD%98

强制缓存由浏览器主导,在一定时间内(Cache-Control)不找后端

协商缓存用 Last-Modified/If-Modified-Since, ETag/If-None-Match 来(后端)判断是否修改过,如果没修改过返回304

Go 静态服务 http.FileServer 使用 Last-Modified(文件系统元数据),hash运算开销太大

手写 ETag,把要发的data做md5 hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func GetData(c *gin.Context) {
// 强制缓存
c.Header("Cache-Control", "public, max-age=3600")

// 协商缓存 (手动实现)
data := getData()
etag := generateETag(data)

if match := c.GetHeader("If-None-Match"); match == etag {
c.Status(http.StatusNotModified)
return
}

c.Header("ETag", etag)
c.JSON(http.StatusOK, data)
}

HTTPS (SSL/TLS)

登录&https 加密 在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,HTTPS 在 TCP 三次握手之后,还需 SSL/TLS 的握手 机密性:非对称加密获得会话密钥,对称加密传输数据

认证 确保公钥的身份

HTTP/2

  • 头部压缩
  • 二进制格式
  • 并发传输:同一个tcp连接里的不同http请求可以并发,用 stream ID 识别
  • 服务器主动推送资源 双方都可以建立 stream,客户端建立的 Stream 必须是奇数号,而服务器建立的 Stream 必须是偶数号。

HTTP/3 QUIC

 QUIC 是一个在 UDP 之上的 TCP + TLS + HTTP/2 的多路复用的协议 - 无队头阻塞:实现每个stream相互独立的TCP的rdt,减少队头阻塞 - 更快的连接建立:把tcp连接和tls连接合在一起 - 连接迁移:不像 TCP的源ip+端口 & 目标ip+端口 来标识每一个tcp连接,而是让进程创建唯一标识,来防止ip改变而引起的

epoll

用于监听多个文件描述符,询问时只返回就绪的文件描述符 一个红黑树map(用于存储所有监听信息,快速查/删)(epoll_ctl添加节点),一个就绪队列(epoll_wait阻塞等待就绪队列有值之后返回就绪队列) select/poll只能知道有fd就绪,不能知道是哪些fd就绪,\(O(所有监听节点)\) 用于轮询查找,epoll \(O(就绪节点)\) for I/O 多路复用

缓存

设计模式

  1. Cache Aside:应用程序负责管理缓存和数据库(后面三个都是只和缓存交互)。即缓存没有命中时app自己找db。read:先缓存;write:先更新数据库再删除缓存(因为先删除缓存可能另一个线程读取db脏数据又给放到缓存了)
  2. Read Through:缓存负责从数据库加载数据。
  3. Write Through:同步写,缓存让db写入数据之后返回success给app
  4. Write Behind:异步写,like page cache in os or db,更新缓存之后返回成功,异步地延迟执行db更新 ### 驱逐参数 volatile/allkeys 是否只驱逐设置了ttl的缓存、 lru 最长时间未被访问 lfu 访问频率

量化指标

缓存20-30%的数据达到85%+的命中率 命中率 请求平均延迟 吞吐量,RPS(请求数/s),QPS(数据库查询数/s) cpu使用率和连接数

如何避免缓存雪崩、缓存击穿、缓存穿透

雪崩:大量缓存数据在同一时间过期,导致大量用户请求访问数据库。随机,不过期 击穿:热点数据过期。提前更新缓存 穿透:数据库没有该值(可能是攻击)。布隆过滤器,手动判断

docker

详见 后端/linux学习笔记

MYSQL

解析器 -> 语法树 -> 优化器 -> plan -> 执行器 -> 存储引擎 InnoDB: - B+树 - 表空间 :段,(索引段,数据段,回滚段) 区(数据量大,让页之间连续) ,页 ,行 - 行格式:变长列长度(len[]),是否null位图,头,rowid 主键(若无定义),事务id, roll id(mvcc),每列值 - 页目录shot 分组,存储每组最大row的偏移

Redis

高性能高开发、高可用(集群) string.hash.set.zset.list bitmap, geo, stream(消息队列) 内部实现: - listpack: (类型、长度、数据、总长度)[] 用于对小的list.hash.zset - 小Set 处整数;intset int16[] 排序 主逻辑单线程 后台线程:chose file.ADP盘、free对象 快的原因:内存、无竞争、I/O多路复用 集群:主从(读写分离)、哨兵(故障、转移)

Golang

面向对象:封装(struct,大小写)、继承(struct嵌套,匿名,自动提升),多态 js:弱类型 大多数值在堆上,变量本身为指针 优势:1协程 2编译速度快、开发效率 2自由 make & new:1类型new(string、int,数组),make(切片、map, Channel) 2返回指针or值 for range 每次循环一个临时变量 string 长度不能用len():字节长度 len ([ ] rune ( str ) 类似char

反射 - Typeof:Struct的元数据:可以找到Tag - ValueOf : 接口值 map.slice.chan为引用类型(值本身类似指针) select:I/O多路复用(每个case为in/out) panic:下标越界、Channel关闭、÷0、断言(no ok)

map不是并发安全->Sync.map (读多买少是优于读写锁) - read map →缓存 hash表 - dirty map

多返回值:在调用此fune的函数的栈上预留空间 Slice/Struct/map: copy(dst, src) & reflect.DeepEqual 程序初始化:最深包 init开始

GC

三色+写屏障 白:未扫描 灰:已扫描,还有出边为白(还在队列中) 根:全局、栈、寄存器 并发:不正确(同时满足1 2):1:创建 黑→白 2删除 灰->白 混合写屏障(对应上面两个条件)1.当创建 黑-》白时白边灰,2.当删除 灰-》白 时检查白没有其他灰指向,就变灰(STW:无能并行 stop the world