字节跳动基础架构暑期实习生应聘记录
自从上次腾讯面试的失败之后又在学长的内推下投了字节跳动的暑期实习,没想到这次居然这么顺利,就试着写一篇回忆记录下吧。
因为时间跨度近一个月,关于面试题的回忆可能有些遗忘了,关于这部分只能尽可能记录一点,更多的是关于个人的感受的记录。
时间线:
- 2025-02-20:内推网站填写个人信息,当晚收到面试邀请
- 2025-02-24:一面
- 2025-02-27:一面通过,收到二面邀请
- 2025-03-03:二面
- 2025-03-04:二面通过,收到三面邀请
- 2025-03-07:三面
- 2025-03-11:三面通过,收到HR面邀请
- 2025-03-13:HR面
- 2025-03-17:加HR微信得到口头offer
- 2025-03-25:offer call后立刻收到offer
都说字节的流程很快,但是基架部门似乎不是这样。因为很多都是周一面然后约下周周一再面,所以之间相隔有些久,基本上一周一个流程。
最后这个offer卡了一个星期,好事多磨吧。
面试回顾
正如前面所说,因为有些久远而且我没有录屏,所以只能做一些基本的回忆。
一面
- 简述Raft协议,Raft协议和Paxos协议的异同
- Raft协议在工业界的优化
- Raft协议中如果存在恶意节点,要保证其比例占总体不高于多少才能保证系统安全
- 实现Raft协议时最困难的部分
- STL中dequeue的实现
- 数据库的MVCC机制
- 算法题:实现InnoDB中的冷热LRU
肯定有一些遗漏,下面说下我对这些问题的理解和回顾
- 按着论文思路讲解了一下,Paxos直接说没看过,因为Raft论文花了大段批评Paxos的难以理解。
- 说实话不知道,大概讲了下应该主要是通过优化读请求的方式进行优化。后面查了一下资料,工业界对Raft的优化主要有:batch化,流水线化,并行Append。一是将多条日志合并成一条日志,二是流水线化发送日志,三是并行化append操作。
- 这个是经典的拜占庭问题,当时也不会,盲猜了一个数1/3,结果还真被我猜对了。
- 主要是对空日志的实现上,这个占用了我很多的时间。
- dequeue(double edge queue),在《STL源码剖析》这本书中读过,大概思路就是用一个中央控制器来决定数据的具体存放区块,以此实现高效的头插和尾插并且支持随机访问。
- 数据库直接歇逼,后面再学吧。
- 普通的LRU刚好面试前几天有写过,但是这个冷热LRU一点都没有想法,面试官最后叫我写了个普通的LRU,并问了为什么要使用冷热LRU,当时没回答上来,后面查了一下资料才想明白为什么(这成了三面的伏笔)
额,从回顾的角度来看简直是一场非常糟糕的面试,很多问题都没有回答上来。不过我想这是因为我顺利回答的问题应该印象都不怎么深,所以没有记录下来罢了。
不过确实能通过一面就很幸运了,相比于被腾讯挂了两次一面而言已经是不能再好的结果了(是的,我后面又面了一次腾讯云,也是秒挂)
字节的面试官素质没的说,确实很高,刚开始的时候还感觉到紧张,到了后半部分就感觉只是一场普通的聊天。也因此对面试不再感到紧张了,果然还是要多试才能顺利啊。
二面
个人感觉表现最好的一次面试
- 问了下为什么不读人工智能
- 简述Raft协议,Raft协议和Paxos协议的异同
- Raft协议为什么不能让leader当选时直接询问follower的情况来commit上一任期的日志(也就是论文figure 8关注的问题)
- Raft的读优化
- xv6中mmap的实现
- xv6的中断处理
- 进程和线程的区别
- 一道智力题
- 算法题,翻转链表
总感觉好像漏了什么很重要的部分
- 关于这个问题我以后可能会更详细的写一篇文章描述一下为什么。面试中我回答是因为单纯不喜欢当前人工智能的实现方式,同时也表达了一下就算干基架也能和人工智能有关联,也能为人工智能构建基础设施(刚好面试前看过一篇介绍deepseek的3FS的文章)
- 公式化问题,我和一面的回答基本一样,但是这个面试官似乎不太喜欢这样回答,强调了Paxos的重要性。看来之后还得找个时间认真研究下Paxos才行。
- 这就是Raft论文Figure 8中提到的问题,也是6.824的测试中的重点项目。不过非常遗憾的是我当时居然没有回想起来为什么,只提到了我是怎么做的,以及为什么要在选举成功后立刻添加一条空日志(以我的看法描述的,我实现这个机制主要是因为会造成堵塞而不是为了解决Figure 8的问题)。后面重新看了下论文,才回想起来是因为达成majority的旧任期的日志也是存在被覆盖的风险的。
- 主要是借助租约机制来实现,允许一部分的读请求从follower获取,代价是可能会导致读到旧数据。
- 说实话当时有点忘记了自己是怎么做的了,只记得是专门划分了一个区域进行mmap,然后在内核维护进程的数据结构中记录了相关的信息,在第一次调用时向该数据结构记录,然后当用户访问时触发缺页中断进入内核,接着将数据从文件中读取进页面中。
- 主要是根据risc-v的scause寄存器来得知是什么原因触发的中断。
- 这个问题正中我下怀,刚好之前翻译过一篇linus的文章,就是关于linus对于进程和线程的区别的看法。结论是没有区别,两者唯一的区别就在于创建时对父进程的拷贝情况,而在内核调度的角度没有任何差异,并且它们都是通过clone系统调用实现的(可以用strace查看)。不过以上讨论仅适用于linux,对于windows的话两者还是有显著区别的。感觉这个回答应该对我的加分挺大的。
- 这个智力题挺有意思的,感觉有点所谓的侧信道攻击的感觉,通过他人的反应来判断自己的情况。花了两三分钟才想出了答案。
- 这个就纯送的了,随便写写都能过。
反问问了一面的拜占庭问题,面试官也和我讲了很多很前沿的理解。学到了不少。
一次非常愉快的面试经历。面试官一开始的时候就说因为网络比较差就不用开摄像头,直接相当于电话面试,感觉这也算一点小因素。
从反馈速度来看(第二天就通过),二面面试官应该对我评价还不错。
三面
三面的风格和前两面就完全不同了,是大leader的压力面,面试官会批评你的回答。
刚开始的时候面试官表情很严肃,也一直在皱眉,这让我的回答总是充满着不自信。
这就是所谓的压力面,通过这个来考察候选人在高压环境下的应变能力。只要能当场意识到这是压力面并及时调整就能很好地通过压力面。不过可惜我当时没有意识到这点,回答的都不怎么好。能够通过三面真是一个奇迹。
提问的内容以场景题为主,考察特定场景下的处理。
- 如何改进Raft协议,使其在同一时刻一定不会出现两个leader
- 读多写少的数据库系统要怎么实现
- 使用MVCC的数据库系统如何在清理旧版本减轻对数据库访问的影响
- 假设有一批热点数据需要保持高访问速度,且系统需要定期进行全盘扫描,要怎么设计缓存系统来保证全盘扫描时对热点数据访问速度的影响最小
问题很少但难度都很高,都是开放性问题,没有一个准确的答案,最主要的我觉得是展示自己的思考内容。
- 我的回答是,当网络分区时,让旧leader在一段时间内没有得到majority的机器的回应时自动放弃leader地位,同时让其他的follower在这段时间之前都不发起选举。这个思路我感觉是对的,但是在表达的时候似乎因为高压没有表达清楚,被面试官质问了好几次。最后他还要求我精简到一句话,想了半天没有想出来,最后他只能告诉我就是租约机制。这才恍然大悟地发现自己想表达的就是租约机制。同时面试官也告诉我使用时间来保证的机制要处理好时钟同步的问题,刚好前几天读过spanner的论文,接了句google他们使用原子钟来保证。接着面试官告诉我国内的公司基本不使用原子钟,因为太贵了,更多的是使用逻辑时钟,应该指的是lamport的那篇论文中提过的,不过我没看过那篇。
- 我回答说可以使用多版本来实现读多写少的问题,类似于RCU的思路,允许一部分的请求访问到旧版本的数据,然后在某个时刻将所有的请求指向新版本。似乎也算是答对了,然后就引出了第三问题。
- 这个问题是一个开放性问题,我只能凭借本能地回答这个问题,首先说应该考虑业务的访问频率在时间上的差异,大部分的业务不可能24小时都处于高负载状态,那么只要在低负载的时候进行删除就可以了。面试官似乎不喜欢这个回答。接着我又脑洞打开地说让多个版本的数据同时处在一个页内,在访问新版本的时候顺便进行旧版本的删除。面试官似乎比较喜欢这个说法。但是他还接着让我想解决方案,遗憾的是我想尽办法也没有想到别的做法,看来还得多学才行。之后面试官跟我介绍了他的看法,我反问他如果删除速度低于数据产生速度的话要怎么办,接着他承认这是业内暂时无解的问题,只能通过流量控制,减慢用户对数据库的访问速度来处理。
- 这个问题面试官还没描述完我就知道他的意思是什么了,这就是一面的伏笔–InnoDB的冷热LRU。我当时直接笑了出来,面试官听到我说一面面试官提过直接跟我说一面面试官就是他招进来了的,当时也问了这个问题。哈哈,果然面试后进行复盘是有用的。InnoDB通过冷热LRU的做法来处理这个问题,冷热LRU维护两个LRU,当数据被读取时,首先进入冷LRU,一段时间后,如果该数据还存在于冷LRU,则说明该数据是热点数据,则将其移动到热LRU中。通过这个做法,就算进行全盘扫描,大部分数据也只不过是进入冷LRU中一段时间后被淘汰,而真正的热点数据在热LRU中长期存在,不会因为全盘扫描而被冷数据淘汰。
在回答完第四个问题之后气氛就莫名的好起来了,也没有考算法题,直接就进入了反问环节。
反问我问了团队是否需要强数据库背景,面试官说并不太需要,因为具体的工作是要分组的。不过该部门是做数据库的,所以在入职之前最好要有一些基础的数据库知识。
所以我最近在补15445,尽量在入职前至少看完整个课程吧。
HR面
这一面倒是没有什么好记录的问题,问的东西都比较公式化,主要是关于团队协作和人际关系的问题
我在大学中和人合作的项目说实话不多,很多项目说是和人合作,最后都因为看不下去所以一个人把所有的工作做完了。服务外包的合作经历倒是算一个,不过那次因为我个人划水所以没有很好的结果。
还问了将来有没有读研的打算,不过我都来应聘暑期实习生了还问我有没有读研的打算。。。我回答主要是说不太想考研吧,考研太累了同时还要去花大量的时间在不是很想学习的东西上,而且容错率也很低,就算成功上岸了也是被压榨的份,那还不如来赚大米呢。。。不知道未来会不会后悔这样的选择。
总结
总的来说肯定是一次不错的求职经历,遇到的四个面试官人都很不错,从他们的提问中学到了很多,这也是我少有的和别人交流自己的看法的经历。
虽然面试过程总是很愉快,但是等结果的过程却很煎熬,也因此失眠了很多夜,感觉自己的抗压能力还是有待提高。
本次暑期实习只投了两家,本来就是抱着随便找找的心态来试一试,如果找不到就考研去,结果居然能在字节这里走到最后的流程,挺意外的,毕竟我在腾讯可是被两脚踢走的来着。
感觉更多应该是运气好吧,字节这个部门的成都分部成立于五年前,还是一个很新的组织。加上投递的比较早,HC应该还有不少,竞争没有那么激烈,而且遇到的面试官也都很对口。
不过话说回来写到这里的时候其实只是HR发了口头offer,还没有真正意义上获得offer,要是之后又挂了就尴尬了。。。希望能审批通过吧。(update:后面收到了offer了)
我真的准备好进入社会了吗。。。
不管怎么说,迷茫也要前进!!!!!