7-24-腾讯-PCG-QQ-后台开发-一面
问题和回答记录
- 自我介绍(答:专业,研究方向,实习经历,常用语言)
- Momenta 实习做得最好的项目(答:背景,痛点,解决方案,效果)
- C++ 和 Golang 哪个用得多 (答:C++)
- 秒杀系统项目中 Redis 的作用 (答:缓存热点数据,压测之前做缓存预热,ZSet 实现排行榜)
- ZSet 的底层数据结构是什么 (答:哈希 和 跳表)
- 跳表的层数是怎么决定的,比如说刚开始是一层 (答:数据添加的时候,会导致跳表层数增加,具体应该是一个概率,不清楚是一个范围还是一个定值)
- 跳表具体是什么 (答:多层链表,底层是链表,每一层的元素是上一层的子集,跳表的查找效率和二分查找类似)
- Redis 中跳表层数的上限是多少 (答:32层)
- 数据不一致问题怎么解决 (答:延迟双删,双写)
- 延迟双删为什么要延迟 (答:第一次删完缓存之后,然后删数据库,此时有线程并发请求读到了数据库的数据,并且再次把数据写入缓存,出现脏数据)
- 可以不延迟吗,延迟的理由是什么(答:不延迟会导致脏数据,延迟可以确保缓存和数据库的一致性)
- 双写会有什么问题,实际项目用的什么 (答:缓存写入成功但是数据库写入失败,或者反过来,导致数据不一致。解决方案可以使用消息队列,定期同步数据。实际项目还是使用延迟双删)
- 限流是怎么做的 (答:令牌桶,给商品设置)
- 令牌桶减法失败了怎么办 (答:阻塞等待,熔断降级)
- Lua 脚本的原子性是怎么保证的 (答:Redis 单线程执行命令,脚本执行期间不会被其他命令打断)
- Lua 脚本失败了可以回滚吗 (答:不可以,Lua 脚本执行失败会报错异常退出,不会回滚之前的操作)
- Redis TTL 具体是怎么实现删除的 (答:定时任务,随机删除,不是很准确)
- 分布式KV中如何保证数据一致性(答:etcd/raft)
- Raft 具体过程 (答:Leader 选举,日志复制,日志提交)
- 强一致性读怎么做的 (答:ReadIndex,向 Leader 查询最新的 commit index,等待状态机应用到该 index 后返回数据)
- 除了 ReadIndex 还有什么方法 (答:本地读和线性写后读,一个数据可能不一致,一个效率低,ReadIndex 是折中的方案)
- KV在高并发写的场景下怎么解决锁竞争问题(答:首先有分区路由和Region的概念,分片写入会解决一部分,其次使用LSM Tree,Write Ahead Log,在写密集场景下,先写入内存中的 MemTable,定期刷新到磁盘的 SSTable,相当于批处理,相比B+Tree减少了磁盘IO,但是写放大倍数会增加)
- TCP三次握手了解吗,accept发生在哪个阶段 (答:三次握手具体过程,不是很清楚问的是否是accept函数调用的阶段)
- TCP怎么感知网络拥塞 (答:超时重传,RTT增大)
- 这个是处理的方式,具体是怎么感知的 (答:比如说发送方连续收到三个连续ACK)
- 流量控制和拥塞控制的区别 (答:流量控制主要提到滑动窗口,主要是为了保护缓冲区;拥塞控制主要是网络链路层面)
- 流量控制有哪些机制 (答:零窗口)
- 有序链表去重(5min)
- 时间复杂度和空间复杂度(答:时间复杂度O(n),空间复杂度O(1))
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 The Coding Odyssey | Chronicles of a Software Developer!