转转转后端
最后更新时间:
自我介绍,介绍项目
8年代码经验 算法(noip),全栈,团队沟通,基础(成绩,os,db,计网,组原都有认真手写lab或黑皮书), AI (llm推理引擎,Yolov8,RL) 实习 项目:创业,招新(2年,近万人) 实习:所有浏览器功能(权限,生态,优化) 1框架(组件拦截) 2:截图自定义海报接口 3需求管理机器人 4团购券
! ai工具使用
- 学习、lab:不用
- 业务项目:把所有 框架(数据关系,这个接口的效果和数据方式)(生成,后期不会让他修,因为代码量大,涉及文件多,不如自己改快)
强制缓存和协商缓存
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 | |
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 多路复用
LT 是“只要有数据就一直提醒”,而 ET 是“只有新数据到来时才提醒一次”。*
缓存
设计模式
- Cache Aside:应用程序负责管理缓存和数据库(后面三个都是只和缓存交互)。即缓存没有命中时app自己找db。read:先缓存;write:先更新数据库再删除缓存(因为先删除缓存可能另一个线程读取db脏数据又给放到缓存了)
- Read Through:缓存负责从数据库加载数据。
- Write Through:同步写,缓存让db写入数据之后返回success给app
- Write Behind:异步写,like page cache in os or db,更新缓存之后返回成功,异步地延迟执行db更新 ### 驱逐参数 volatile/allkeys 是否只驱逐设置了ttl的缓存、 lru 最长时间未被访问 lfu 访问频率
量化指标
缓存20-30%的数据达到85%+的命中率 命中率 请求平均延迟 吞吐量,RPS(请求数/s),QPS(数据库查询数/s) cpu使用率和连接数
如何避免缓存雪崩、缓存击穿、缓存穿透
雪崩:大量缓存数据在同一时间过期,导致大量用户请求访问数据库。随机,不过期 击穿:热点数据过期。提前更新缓存 穿透:数据库没有该值(可能是攻击)。布隆过滤器,手动判断
docker
详见 docker & k8s
MYSQL
解析器 -> 语法树 -> 优化器 -> plan -> 执行器 -> 存储引擎 InnoDB: - B+树 - 表空间 :段,(索引段,数据段,回滚段) 区(数据量大,让页之间连续) ,页 ,行 - 行格式:变长列长度(len[]),是否null位图,头,rowid 主键(若无定义),事务id, roll id(mvcc),每列值 - 页目录slot 分组,存储每组最大row的偏移
Redis
高性能高开发、高可用(集群) string.hash.set.zset.list bitmap, geo, stream(消息队列) 内部实现: - listpack: (类型、长度、数据、总长度)[] 用于对小的list.hash.zset - 小Set 处整数;intset int16[] 排序 主逻辑单线程 后台线程:close file.AOF盘、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
微服务
https://juejin.cn/post/7052143950085226510
apollo架构
https://mp.weixin.qq.com/s/-hUaQPzfsl9Lm3IqQW3VDQ ## K8S
https://mp.weixin.qq.com/s/wOMzZw-CImSgDoQasy2iHg
一、微服务基础组件
1. 服务治理(Kitex / Spring Cloud 体系)
核心能力:
1. 服务注册与发现
* 常见组件:Nacos、Eureka
2. 健康检查 / 服务追踪
3. 配置管理(动态配置)
4. 网关(统一入口)
5. 负载均衡
2. 服务注册与发现
- 注册中心:
- Nacos
- Eureka(AP 优先)
- Nacos
- 客户端调用流程:
服务注册 → 服务发现 → 客户端负载均衡 → 调用
3. DNS vs 注册中心
- DNS:
- 简单解析 IP
- 不适合动态服务
- 简单解析 IP
- 注册中心:
- 支持动态上下线
- 健康检查
- 更适合微服务
- 支持动态上下线
4. 负载均衡策略
- Random(随机)
- Round Robin(轮询)
- Pick First(优先选一个)
- 一致性 Hash(部分场景)
5. RPC 框架(Dubbo / gRPC / Kitex)
- 核心:
- 服务调用(远程)
- 序列化协议
- 服务治理
- 服务调用(远程)
- 长连接 + KeepAlive
- Watch 机制(监听服务变化)
二、Kubernetes(K8s)
核心概念
- Master:
- etcd(存储)
- 调度器(scheduler)
- etcd(存储)
- Node:
- 运行 Pod
核心对象
- Pod:最小部署单元
- Deployment:管理副本
- Service:服务暴露
Service 类型
- ClusterIP(集群内访问)
- NodePort(节点端口)
- LoadBalancer(外部负载均衡)
配置中心
配置实时生效(.env),灰度发布(容器的镜像id?) ##
三、网关(Gateway)
### 作用
* 所有外部请求入口
* 做统一处理:
* 路由
* 负载均衡
* 限流
* 鉴权
* 灰度发布
常见网关 Nginx Traefik
traefik
* Provider:
* Docker
* Kubernetes
* 注册中心
鉴权流程:先转到authservice -> 成功 -> 给后端并附加一个header 失败
-> 302/401 给前端
### 熔断 & 降级
* 熔断:
* 下游错误率高 → 直接不请求下游
* 限流:
* 控制 QPS 令牌桶 * 重试 ### 3. CAP 理论
- C(一致性)
- A(可用性)
- P(分区容错)
五、高并发 & 秒杀系统
典型流程
前端限流or验证码 → 网关限流 → Redis 预扣库存(原子lua get&desc 防超卖) → 消息队列削峰 → DB 最终写入(乐观锁&唯一id)-> 最终一致性 ## 六、分布式事务
1. TCC 模式
- Try(预处理)
- Confirm(提交)
- Cancel(回滚)
2. SAGA 模式
- 长事务拆分
- 每一步都有补偿操作
### 3. Seata
- AT 模式(自动回滚 undo log)
## 七、分布式锁
### Redis 实现
- SET NX EX
- 防止死锁:设置过期时间
- 解锁: lua ### Redlock(多节点锁)
直接在多个节点上锁,多数都有才算获取锁 ### Zookeeper
- 临时节点
- Watch 机制
## 八、分布式 ID
### 方案
- UUID(简单但无序)
- redis
- 号段,类ip子网
- 雪花算法(Snowflake)
## 十、乐观锁 ### SQL 示例
1 | |
十一、限流
- 计数器
- 滑动窗口
- 令牌桶 *
- 漏桶
C++
虚函数
实现运行时多态,调用时动态判断时调用哪个版本的函数 基类像是interfere 如果析构函数是虚函数:先调用派生类析构函数 , 再调用基类析构函数。(正常是覆盖)
- 分配内存。
- 调用 A 构造函数:
vptr指向 A 虚表 -> 执行 A 构造体(输出 A)。 - 调用 B 构造函数:
vptr改指向 B 虚表 -> 执行 B 构造体。
查端口
netstate 查询网络状况,最新用ss sudo ss -ltnp sport = :80 lsof -i :80 (list open file)
TIMEWAIT是什么,服务器有大量timewait是为什么,如何缓解
是四次挥手过程中,主动方收到被动方的FIN然后发送ACK之后进入状态,持续两个MSL,大概60s;为了确认ACK被收到(被动方关闭),2msl是ack丢失+被动方重发。 服务器主动关闭:1. 没有长连接 2. 长连接超时 3. 连接数量太多 → 高并发且持续的短连接 过多的timewait会导致无法连接更多,需要手动减少。tcp_tw_reuse 快速回收或增加nginx连接数大小
三次握手

四次挥手

js this
function 是调用时指定,箭头函数是定义时指定 但是
setInterval 里的 function() {}
不是你调用的,是浏览器/Node.js
在定时器触发时调用的,相当于: 1
2// 定时器触发时,浏览器内部大概这样调用:
callback() // 普通函数调用,没有指定 this