字节外包面试必考点速查表

基于您剩余未学习的资料(06-10),按重要程度标注必考点。


📌 补充:Go 基础易错点 (大厂必问)

🔥 快问快答

题目答案要点
Q1: Slice 是引用传递吗?错!Go 只有值传递。传的是 Struct{Ptr, Len, Cap} 的副本。函数内 append 扩容不会影响外部 Slice。
Q2: int 和 int32 能通用吗?不能int 在 64位系统是 8字节,int32 是 4字节。必须强转。
Q3: 怎么测 Channel 关闭?v, ok := <-ch!ok 就是关了。没有 isClosed() 方法
Q4: 结构体字段顺序影响内存吗?影响很大(内存对齐)bool 夹在两个 int64 中间会浪费 padding。把小字段凑在一起放能省内存。
Q5: Go 互斥锁能重入吗?不能! 同一个协程连续 Lock 两次会死锁。Go 设计理念是”显式传递锁所有权”,不支持递归锁。
Q6: copy() 是深拷贝吗?是浅拷贝。如果有指针字段,复制的只是指针地址。如果需要完整独立副本,需递归深拷贝。
Q7: 不用结构体,Go 还有哪些传参/建模方式?1. Map: 解析未知 JSON 或动态配置。
2. Option 模式: New(opts ...Option),解决初始化参数过多的构造函数难题。
3. Context: 隐式透传 TraceID/UserID,避免污染函数签名。

📌 06-垃圾回收与性能优化 (重要度: ⭐⭐⭐⭐)

🔥 必考点

知识点考察频率核心内容
三色标记法高频白/灰/黑三色含义,标记过程
写屏障中频为什么需要,插入/删除屏障区别
STW (Stop The World)高频什么时候触发,如何优化减少STW时间
sync.Pool 对象池高频使用场景,减少GC压力
pprof 性能分析中频CPU/内存分析基本用法

💡 速记口诀

三色标记白灰黑,写屏障防漏标
STW越短越好,对象池复用减压

✍️ 高频问法

  • “Go的GC是怎么实现的?”
  • “什么是三色标记法?”
  • “如何减少GC对程序的影响?”
  • “sync.Pool有什么作用?什么时候用?”

📌 07-数据库与中间件 (重要度: ⭐⭐⭐⭐⭐)

🔥🔥🔥 必考点 (最高优先级!)

知识点考察频率核心内容
MySQL索引原理必问B+树结构,聚簇/非聚簇索引
索引优化必问最左前缀,覆盖索引,索引失效场景
事务ACID高频四大特性,隔离级别
Redis数据结构必问5种基本类型+使用场景
缓存穿透/击穿/雪崩必问三者区别,解决方案
Redis持久化高频RDB vs AOF

💡 速记要点

MySQL索引失效场景

1. 最左前缀不匹配
2. 对索引列运算或函数
3. 使用 != 或 NOT IN
4. LIKE '%xxx'(左模糊)
5. OR 条件没有都加索引
6. 隐式类型转换

Redis 5种数据结构

类型典型场景
String缓存、计数器、分布式锁
Hash用户信息、对象存储
List消息队列、最新列表
Set去重、共同好友
ZSet排行榜、延迟队列

缓存三大问题

问题原因解决方案
穿透查不存在的数据布隆过滤器、空值缓存
击穿热点key过期互斥锁、永不过期
雪崩大量key同时过期过期时间加随机值

✍️ 高频问法

  • “MySQL索引为什么用B+树?”
  • “联合索引(a,b,c),查询条件a=1 and c=3能用上索引吗?”
  • “什么是缓存穿透?怎么解决?”
  • “Redis的String最大能存多大?“(512MB)

📌 08-网络与操作系统 (重要度: ⭐⭐⭐⭐)

🔥 必考点

知识点考察频率核心内容
TCP三次握手必问SYN→SYN-ACK→ACK,为什么是三次
TCP四次挥手高频FIN→ACK→FIN→ACK,TIME_WAIT作用
TCP vs UDP高频可靠/不可靠,连接/无连接
HTTP状态码高频200/301/302/400/401/403/404/500/502/503
HTTPS原理中频对称+非对称加密,证书验证过程

💡 速记要点

TCP三次握手

客户端 → SYN=1, seq=x        → 服务端   "我要连接"
客户端 ← SYN=1, ACK=1, seq=y, ack=x+1 ← 服务端   "可以,你能收到吗"
客户端 → ACK=1, seq=x+1, ack=y+1 → 服务端   "能收到,开始吧"

为什么是三次?

防止”已失效的连接请求”突然到达服务端造成资源浪费

常见HTTP状态码

状态码含义
200成功
301永久重定向
302临时重定向
400请求参数错误
401未认证
403无权限
404资源不存在
500服务器内部错误
502网关错误
503服务不可用

✍️ 高频问法

  • “TCP三次握手的过程?”
  • “为什么握手是三次,挥手是四次?”
  • “TIME_WAIT有什么作用?”
  • “HTTP和HTTPS的区别?”

📌 09-Linux与容器化 (重要度: ⭐⭐⭐)

🔥 必考点

知识点考察频率核心内容
Linux基础命令中频grep, awk, sed, top, ps, netstat
Dockerfile编写中频多阶段构建,镜像优化
Docker常用命令中频build, run, exec, logs

💡 速记要点

常用Linux命令

# 查看日志
tail -f app.log
grep "error" app.log
 
# 查看进程
ps aux | grep go
top -H -p <pid>
 
# 查看端口
netstat -tunlp | grep 8080
lsof -i :8080
 
# 查看磁盘/内存
df -h
free -m

Dockerfile多阶段构建

# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
 
# 运行阶段(镜像更小)
FROM alpine:latest
COPY --from=builder /app/main .
CMD ["./main"]

✍️ 高频问法 & 答案

Q1: 如何查看Go程序的CPU占用?

# 方法1:top 命令(实时监控)
top -H -p <pid>          # -H 显示线程级别,-p 指定进程ID
 
# 方法2:ps 命令(快照)
ps aux | grep myapp      # 查看 CPU% 列
 
# 方法3:Go 内置 pprof(最专业)
import _ "net/http/pprof"
go func() { http.ListenAndServe(":6060", nil) }()
 
# 然后访问
curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
go tool pprof cpu.prof   # 分析报告

面试加分回答

“先用 top -H 定位高 CPU 的线程,再用 pprof 分析具体是哪个函数消耗 CPU。如果是生产环境,可以用 runtime/pprof 导出采样数据离线分析。“


Q2: Docker镜像太大怎么优化?

优化方法效果示例
多阶段构建🔥 最有效编译和运行分开,只保留二进制
使用小基础镜像减少几百MBalpine(5MB) 替代 ubuntu(72MB)
合并 RUN 命令减少层数多个命令用 && 连接
删除缓存减少几十MBrm -rf /var/cache/apk/*
使用 .dockerignore避免复制无用文件忽略 .gitnode_modules

最佳实践 Dockerfile

# ✅ 多阶段构建(Go项目从1GB+降到10MB)
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download       # 利用缓存
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o main .
#    ↑ 禁用CGO      ↑ 去掉调试信息,进一步减小
 
FROM scratch              # 空镜像,最小!
COPY --from=builder /app/main /main
ENTRYPOINT ["/main"]

镜像大小对比

golang:1.21        → 800MB
golang:1.21-alpine → 250MB  
alpine + 二进制     → 15MB
scratch + 二进制    → 8MB   ← 最小!

Q3: 如何查看某个端口被哪个进程占用?

# 方法1:lsof(推荐,信息最全)
lsof -i :8080
# 输出示例:
# COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
# main     1234 root    3u  IPv4  123456      0t0  TCP *:8080 (LISTEN)
 
# 方法2:netstat(传统方法)
netstat -tunlp | grep 8080
# -t TCP  -u UDP  -n 端口号  -l 监听中  -p 显示进程
 
# 方法3:ss(netstat的替代品,更快)
ss -tunlp | grep 8080
 
# 找到 PID 后查看进程详情
ps aux | grep 1234
ls -l /proc/1234/exe    # 查看可执行文件路径

面试加分:如果端口被占用想强制释放

kill -9 <pid>            # 强制杀进程
fuser -k 8080/tcp        # 直接杀占用8080的进程


9. 微服务与分布式 (大厂必问)

🔥 深度解析请看11-微服务与分布式架构.md (含 Raft、分布式事务、一致性 Hash、Top K 详解)

核心考点速览

知识点必考点面试简答
Raft 算法选主过程核心是选主复制。Leader/Follower/Candidate 三态切换。
分布式事务TCC vs MQ强一致用 TCC/Seata,最终一致用 MQ 事务消息(最常用)。
Top K 问题1亿找最小100个使用大顶堆,维护 100 个元素,比堆顶小就更替。
TCP 滑动窗口流量控制接收方告知窗口大小,控制发送方速度。
一致性 Hash负载均衡数据/节点映射到环上,解决节点变动导致的大规模缓存失效问题。


10. Gin & GORM 框架实战 (项目必问)

🔥 深度解析请看12-Gin与GORM框架详解.md (含洋葱模型、N+1问题、零值更新详解)

核心考点速览

🔥 Gin 核心

知识点面试简答
中间件原理洋葱模型Next() 把执行权交给下一个中间件,执行完后再回到当前中间件继续处理(如计算耗时)。
Context 传值使用 c.Set("uid", 123)c.Get("uid") 在中间件链中传递数据。
路由原理使用 Radix Tree (基数树/前缀树)。比正则匹配快,通过压缩公共前缀节省空间。

🔥 GORM 避坑

知识点面试简答
N+1 问题查列表时循环查子表。解决:使用 Preload 预加载(db.Preload("Orders").Find(&users)),生成 2 条 SQL。
零值更新Updates 默认不更新 0/false/""。解决:使用 map.Select("Age") 强制更新。
Hooks 隐患BeforeSave 失败会回滚事务。不建议在 Hooks 里写复杂业务逻辑。

📌 11-测试与工程实践 (重要度: ⭐⭐⭐)

🔥 必考点

知识点考察频率核心内容
表驱动测试中频Go测试最佳实践
Go项目结构中频cmd/internal/pkg目录作用
Go Modules中频go mod命令

💡 速记要点

标准Go项目结构

├── cmd/          # 主程序入口
├── internal/     # 私有代码(不可被外部引用)
├── pkg/          # 公共库(可被外部引用)
├── api/          # API定义(proto/openapi)
├── configs/      # 配置文件
└── deployments/  # 部署文件(Dockerfile/K8s)

测试命令

go test ./...                    # 运行所有测试
go test -v -run TestXxx          # 运行指定测试
go test -cover                   # 查看覆盖率
go test -bench=. -benchmem       # 基准测试

📋 一周冲刺优先级

优先级内容预计时间必考程度
P0MySQL索引 + 事务2小时🔥🔥🔥
P0Redis数据结构 + 缓存问题2小时🔥🔥🔥
P0TCP三次握手/四次挥手1小时🔥🔥🔥
P1GC三色标记 + sync.Pool1小时🔥🔥
P1HTTP状态码 + HTTPS0.5小时🔥🔥
P2Docker/Linux命令0.5小时🔥
P2Go项目结构0.5小时🔥

💪 面试小贴士

  1. MySQL + Redis 必须会:这是后端面试的硬门槛
  2. 算法坚持刷:每天2道,重点刷链表、二叉树、排序
  3. 项目经验准备:用STAR法则准备1-2个亮点项目
  4. 不会就说不会:不要瞎编,但可以说”我理解的是…”

⏰ 离面试还有约一周,重点突破 P0 内容,P1 快速过一遍!