深入解析字节跳动面试经验:应对挑战与成功获得Offer的关键策略

面试经历分享

我成功拿到了字节的offer,准备入职了。虽然又得转向Go语言,感觉似乎总在语言间反复跳跃,Java与Go之间的转换让我学习的深度并不够。

下面是我的字节面试经历,记忆中乱序的分享。

一、算法题

  1. 给定字符串abcdabgh,要随机返回字符a的下标,例如04。要求返回的概率相同,且空间复杂度为O(1)(即不能开辟任何空间存储下标,仅能进行一次遍历)。
  2. 给定n个骰子,求和为k的概率,禁止使用回溯法。
  3. 例如数字234和数组{2, 3, 7},找出第一个不大于234的数,比如233,此过程中采用有序表。

二、八股文

可能不全且有些内容没有整理,但相较而言还算简单。

计算机基础

  1. 堆和树有什么区别?各自的应用场景是什么?什么是二叉搜索树?
  2. 进程间的通信方式有哪些?如何示范一个死锁?又该如何解决?
  3. 操作系统内存满了该怎么办?如何进行内存回收?这会带来什么影响?
  4. 什么是僵尸进程?该如何处理?
  5. 线程安全的问题产生原因及其解决方案是什么?
  6. 请解释乐观锁和悲观锁的区别?什么是CAS?ABA问题是什么?怎么解决它?
  7. HTTP的常见方法和状态码有哪些?502代表什么错误?如何进行问题排查?请讲解反向代理的概念。

MySQL

  1. 索引的构成是什么?(例如B+树)如何优化索引?提供一个SQL语句判断走索引的情况。
  2. 什么是慢SQL?如何检测和优化?
  3. 三大日志的作用是什么?如果relog写入成功,bin log却没有写入,应该怎么处理?(具体情形我记不太清了,回答得不太好)讲解write与flush之间的区别,redo log的刷盘时机,以及三大日志的执行顺序。
  4. MySQL的事务隔离级别有哪些?它们解决了什么问题?mvcc的工作原理是什么?

Redis

  1. zset的底层实现是什么?为何不使用红黑树?(这是我自己引出的,我犯了糊涂,提到不使用红黑树而用跳表)
  2. Redis命令行中的setnx、setex和zset里的命令。
  3. Redis的key有大小限制吗?这会带来什么影响?如何处理?
  4. Redis的内存淘汰策略是什么?(面试时我一直想不起来,背了半天旁路缓存的内容,以为要凉了)
  5. 根据score查member的时间复杂度是怎样的?相反,根据member查score的时间复杂度又是怎样的?

场景设计

设计一个敏感词库,要求实现敏感词的增删改查。对于敏感词的文本匹配,假定有一万个敏感词,文本长度在20到10000之间。

我回答了关于trie树的内容等,但对于如何存储持久化又被面试官一一否定,实在有些无奈。他问我,如果Redis宕机,数据该如何处理?这一块我实在没办法,感觉面试官的思路很强大,我的方案似乎都不太可行。

三、项目与实习

这部分也有一些闲聊内容没有详细记录。

  1. 微信扫码登录的流程是怎样的?了解背后的原理吗?(准备了很久的OAuth2,终于派上用场,开心!)CSRF是什么?如何解决?
  2. 项目中的难点(之前的登录日志是同步写入库的,为了提升效率我们引入了队列,先写入队列再消费入库,以实现解耦,但由于队列使用的是同步操作,一次MQ宕机导致登录服务不可用,这是不可接受的,所以我们将其改为异步方式)。
  3. 订单在30分钟内可取消,延时消息的实现(这是我自己引申的,简单总结了一下MQ的18个队列及Kafka的时间轮)。
  4. 实习时使用的是什么语言?如果Go的协程中发生panic,该如何处理?请讲解defer的概念?你了解GMP模型吗?