字节跳动暑期后端开发一面面经
《面试题目》
- 项目中使用Redis做限流,具体是怎么防止刷单的?
- 如何限制“一人一单”?(追问:如果用户ID不是自增的,怎么限制?-> 引出用 Set)
- Redis 的 Set 底层是怎么存储/实现的?
- 跳表(SkipList)底层是怎么实现的?
- 这个项目为什么选择用 Redis 来实现?
- 场景题:如果把所有用户的下单ID存入一个优惠券的 Set 中,会导致“大Key”问题。大Key会给系统性能带来什么影响?如何解决或规避大Key问题?
- SQL 手撕:有一张成绩表(包含字段:学生姓名、课程名、分数),请查出所有选修课程分数都大于80分的学生姓名。
- 你是怎么理解数据库的事务的?
- 事务的“一致性”(Consistency)是怎么保证的?
- 事务的“隔离性”(Isolation)是怎么保证的?(引出 MVCC)
- MVCC(多版本并发控制)底层是怎么实现的?
- 多线程下,控制资源并发访问(并发控制)有什么具体的方式或方法?
- Java 中有哪些具体的锁?
- ReentrantLock 是怎么实现的?
- AQS(AbstractQueuedSynchronizer)底层是怎么实现的?
- 多线程下,线程之间的通信方式有哪些?
- 为什么会有垃圾回收器(GC)?在 JVM 中,什么是“垃圾”?
- TCP 的可靠性是怎么保证的?
- 具体讲讲 TCP 的流量控制和拥塞控制是什么?
- 了解 HTTPS 协议吗?它的交互通信过程是什么样的?
- 你了解哪些对称加密和非对称加密的具体算法?
- 设计模式了解过吗?责任链模式是什么样的?
- 你认为我们在工程设计中,为什么要使用这些设计模式(主要解决什么痛点)?
- 手撕:实现一个栈,包含最基本的 push、pop、top 方法,要求这三个方法的时间复杂度都是 O(1);同时包含一个获取当前栈中最大元素的方法 getMax,时间复杂度也严格要求为 O(1)。
《参考解析》
- Redis 大Key问题:会导致阻塞主线程、内存分布不均及网络带宽拥塞。规避方案包括:拆分Key(如Hash分桶)、使用异步删除(UNLINK)、缩减数据大小或将数据拆分到多个节点存储。
- MVCC 实现:通过数据库表中的隐藏字段(DB_TRX_ID、DB_ROLL_PTR)、Undo Log(记录历史版本)以及 ReadView(快照读判定规则)共同实现,保证了在并发读写下的高性能与隔离性。
- AQS 原理:AQS通过一个双向链表(CLH队列)管理等待资源的线程,利用volatile修饰的int类型的state变量表示锁状态,通过CAS操作来实现状态的原子性修改。
- TCP可靠性:通过确认应答(ACK)、序列号、超时重传、流量控制(滑动窗口)、拥塞控制(慢启动、拥塞避免等)机制,保证数据不丢失、不乱序、不重复且适配网络负载。
- O(1) getMax 栈:使用两个栈实现,一个存储数据,另一个存储当前栈内的最大值。每次push时,若元素大于等于辅助栈顶则压入,pop时若元素与辅助栈顶相同则辅助栈也pop。