面试复盘:被字节跳动面试官连问了8个问题
Nina Santos | 2026-08-12T06:29:00 | Java, Spring Boot, Database
字节跳动后端面试真题复盘,涵盖TCP/HTTP、Redis、MySQL索引、Spring Bean生命周期和分布式锁
# 面试复盘:被字节跳动面试官连问了8个问题 ## 前言 上周面了字节跳动的后端岗位,二面面试官连环追问了8个问题,答得磕磕继绤。回来之后把每个问题都深入研究了一遍,整理出来分享给大家。 ## Q1:TCP三次握手为什么不能两次? ``` 两次握手的问题: 客户端发送的第一个SYN包延迟到达 -> 服务器以为是新连接,回复SYN+ACK -> 服务器分配资源等待 -> 但客户端并不会响应 -> 服务器资源浪费! 三次握手保证双方都确认了对方的收发能力。 ``` ## Q2:HTTP和HTTPS的区别? - HTTP明文传输,HTTPS加密传输 - HTTPS需要SSL证书 - HTTP端口80,HTTPS端口443 - HTTPS多了TLS握手过程 ## Q3:Redis为什么这么快? ``` 1. 纯内存操作 2. 单线程避免上下文切换 3. IO多路复用(epoll) 4. 高效的数据结构(SDS、跳表、压缩列表) ``` ## Q4:Redis的过期策略? ``` 惰性删除 + 定期删除 惰性删除:访问key时检查是否过期 定期删除:每100ms随机抽取20个key检查 淘汰策略: - allkeys-lru:所有key中淘汰最近最少使用的 - volatile-lru:设置了过期时间的key中淘汰LRU - allkeys-random:随机淘汰 ``` ## Q5:MySQL索引为什么用B+树? ``` B+树 vs B树: - B+树叶子节点有双向链表,范围查询高效 - B+树非叶子节点不存数据,能放更多key - 树的高度更矮,IO次数更少 B+树 vs Hash: - Hash不支持范围查询 - Hash不支持排序 ``` ## Q6:Spring Bean的生命周期? ```java // 简化版生命周期 1. 实例化 (new) 2. 属性注入 (@Autowired) 3. Aware接口回调 4. BeanPostProcessor.postProcessBeforeInitialization 5. @PostConstruct / InitializingBean.afterPropertiesSet 6. BeanPostProcessor.postProcessAfterInitialization 7. 使用Bean 8. @PreDestroy / DisposableBean.destroy ``` ## Q7:分布式锁怎么实现? ```java // Redis分布式锁 String result = redis.set(lockKey, requestId, "NX", "EX", 30); // 解锁(Lua脚本保证原子性) String script = "if redis.call('get',KEYS[1]) == ARGV[1] then " + " return redis.call('del',KEYS[1]) " + "else return 0 end"; redis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); ``` ## Q8:分布式锁的问题? > 这个问题我没答好,面试官追问了锁续期的问题。 ``` 问题1:锁过期但业务没执行完 -> 解决:Redisson看门狗自动续期 问题2:Redis主从切换导致锁丢失 -> 解决:RedLock算法(多节点加锁) 问题3:可重入 -> 解决:记录线程ID和重入次数 ``` ## 面试总结 字节的面试风格就是不断追问细节,一个问题能问到你答不上来为止。建议大家准备面试时不要只背概念,要真正理解原理。 被问懵是正常的,关键是面试完回来把没答上的问题搞明白。