【梅开二度】字节跳动 分布式存储 日常实习 二面挂经
说一说投这个岗的缘由。我的技术栈是C++,准备的方向偏后端,本来想投后端的。
岗位是C++的,部门应该属于基础架构部门,但是我的经历其实跟岗位不太match(语言是match的),是经过同学内推的(正好同学也说不强制有存储相关的经历)。最初知道我要面的是这个,而不是业务的后端岗位的时候,我是想拒绝的,因为我怕太难面,考太多底层的东西。
我想了想今后有想转鸡架的可能性,也考虑到鸡架岗面试难度不一定比业务岗难。因此选择接受面试。
注:无论是什么语言栈的,如果手头有RPC项目的,可以参考一面对RPC项目的问法,问的还是比较有水平、有深度的
总体流程
- 2022.7.1 投递简历(内推),下周一邮件约面(2022.7.4)
- 2022.7.8 17:00 一面
- 2022.7.14 17:00 二面(2个工作日内)
- 2022.7.20 11:43 感谢信(4个工作日内)
- Update:2022.7.27 挂了的一周内,被某部门后端捞起来面试,由于时间安排问题,遂拒绝
一面(65min)
面试官是校友,看到我的简历的毕业年份愣了一下,觉得不应该是个非应届的过来
自我介绍
继续做字节的舔狗
八股/项目(50min)
问简历的内容,其实还行。主要环节是,智能指针拷打(这块好像说了20min左右),一致性哈希拷打,RPC拷打。
- 用过C++11吗?
- 用过
- 知道
unique_ptr
吗?- 知道,是独占所有权的智能指针
- 怎么实现独占所有权?怎么转移所有权?
b = a;
怎么实现?b = move(a);
怎么实现?- 就是说了移动构造函数/移动赋值运算符的流程
- 知道
shared_ptr
吗?- 知道,是共享所有权的智能指针
- 怎么实现的共享所有权?
- 引用计数
- 引用计数和管理的内存地址怎么实现的?是同一块内存空间吗?
- 都在堆区
make_shared
会放在同一个空间
- 引用计数和管理的内存是相生相依的吗?
- 没搞懂,最后就问了这两个是同时创建的吗?
- 其实不是,传入
new xxx
的构造函数就不是
- 同样问了
shared_ptr
的b = a;
怎么实现?b = move(a);
怎么实现?- 同样说了下拷贝构造函数/拷贝赋值运算符、移动构造函数/移动赋值运算符的流程
- (想问点分布式存储相关的)知道raft吗?
- 只了解是个分布式共识算法,没了解具体内容(论文都没看,我可不敢说我了解了)
- 看我没有相关经历,那就挖一挖简历吧
- 知道一致性哈希吗?
- 顺便提了一嘴自己的RPC实现了这个东西
- 解释一致性哈希是什么,然后开始深挖一致性哈希,怎么减少这种数据的移动,分桶结果改变的
- 然后开始引出虚拟节点
- 互斥锁,信号量使用的场景区别
- 一个线程互斥,另一个线程同步
- 互斥锁,读写锁,自旋锁的区别
- 八股文,只说了自旋锁,就没让继续说了
- 怎么实现自旋锁
- 说了原子操作,test and set指令(tsl)
- RPC的实现流程?
- 八股文
- 怎么在同一个端口,发布多个服务?
- 就说说自己咋实现的
- 怎么实现的超时?
- socket设置,recv超时
- 然后开始问重试机制,如果需要我实现应该怎么实现?
- 最大重试次数,计数
- 如果同时发出很多个RPC请求,这个qps上不去,咋办?
- 不知道,想了一会说,也不能总是创建很多个线程吧
- 然后就说可能得用I/O多路复用了
- RPC调用的同步和异步,和之前说的同步和异步,是一个意思吗?
- socket的同步阻塞,是收到数据前,一直阻塞,等着
- 这个是在得到调用结果前,是否可以继续做下面的事情
- 那我继续问,如果同一个RPC调用,按照你之前的重试机制实现,如果前一个请求(涉及到写,非幂等,比如文件创建)是成功的(但是做的太久,设置的超时太短,以为超时失败了),后面重试的请求失败了(显示文件已创建),应该怎么解决?
- 想了很久,说同一个请求的数据包都是通过请求id关联的,
- 那么每个请求,都单独开个线程去等(因为重试的次数本就不多),然后请求到的结果,放入哈希表,当然,也放到队列里面
- 通过请求id,索引哈希表,看看有没有最近的成功请求结果,如果有,之后的失败请求,就没必要记录了
- 那么,根据这个实现,如果第一次的请求是响应成功的,但是由于网络原因失败,应该怎么办?
- 不懂了,之后没继续深挖
- 那么就说webserver吧(简历的项目名称不是webserver,不过被一眼看出,老面试官了)。你知道I/O多路复用机制,除了epoll,还有啥吗?
- select,poll,原理差不多,没让说具体原理
- ET和LT的区别?
- 八股文
- ET和LT哪个性能更好?
- 一般认为ET更好,毕竟可以从内核中少拷贝就绪文件描述符
- 但是,ET伴随着使用非阻塞socket,要一次性读完、写完数据,也就是说可能进行的
read
或者write
系统调用会更多 - 至于是否真的更好,目前没有定论,需要在更多的环境、场景下去测试
算法题(10min)
直接就在飞书上了,ACM模式
排序链表(LeetCode 148)
- 让选择一种比较擅长的实现,选择了最简单的递归版归并排序,不过今天当天写过,所以bug free了
- 然后讨论了
new
了新节点,没释放的问题(这个习惯在工程实现上确实不好),修改了下代码
反问
- 目前在做的工作,编程语言,技术栈
- 文件系统,C++
- 平时会用什么库,或者什么其他技术栈
- 有一些自研的,也有RPC(字节自己的RPC,百度brpc),也用类似muduo的这种网络库
- 涉及到数据库(存储引擎)吗
- 没有,这个是数据库的组做的
- 我的表现有什么需要改进的?什么时候能知道结果?
- 还行,挺好的
- 几天之内,可以问hr
总结
总体而言,聊的很愉快,虽然中间确实有部分问题不会回答,也回答不够好
项目中的一致性哈希,这块背的不太熟,下次还得再练练
其他还好
二面(50min)
面试官比较年轻,也还好,不会给人很严肃的感觉,没回答上的问题,也没有关系
自我介绍
继续舔狗,说到「字节跳动是我非常尊敬和仰慕的公司」,当然其实每次面试都会说这句话
面试官笑了(尴尬)
八股/项目(25min)
- 用的是C++11吗?(固定开场了这是?)
- 用过
- C++11新特性有啥?
- 八股文
- 解释什么是左值,什么是右值,
move
是干啥的(超高频了) - 什么时候用到右值,移动构造函数/移动赋值运算符函数的流程
- 八股文
- 说了一半,面试官明白意思了,没让再往下说
- 虚拟内存和物理内存的差别,为什么要用虚拟内存?
- 八股文
- (麻了,一直问还有吗)
- 虚拟内存有哪些部分?
- 八股文
- 内核区、用户区
- 用户区有代码段、数据段、堆栈段(中间还有个文件映射区)
- 虚拟内存的查询流程
- 说了下二级页表查询
- C++ 的
new
运算符流程- 八股文
operator new
- 调用构造函数
malloc
函数返回的地址是什么地址- 虚拟地址
malloc
返回什么样的地址,如果分配10字节。- 说了下
malloc
,在分配空间小于128k使用brk
系统调用,将堆区顶部上推 - 实际上不是每次都调用,会维护内存池,把一堆空闲块,用链表链接起来
- 面试官追问,如果链表太长咋办?
- 我就把C++ allocator的二级空间配置器的原理搬过来了(维护不同块长度的空闲链表)
- 这个链表的并发访问,除了加锁还有啥方法吗
- 说了下原子操作(也不知道对不对)
- 了解thread local吗?(听过名字,没了解具体原理,寄)
- 说了下
- 【动态链接库】和【静态链接库】的区别?
- 我本来想先说【动态链接】和【静态链接】的区别的,我就试图先说这个,想杀点时间
- 但是,又问静态库
.a
和动态库.so
有啥不同。麻了,没回答上,回去好好看 - 然后又追问,怎么查看使用到的动态链接库?麻了,忘了,滚去复习(寄)
- C++一般用啥编译工具?
- make、cmake
- 有什么工具,能查看编译后可执行文件的函数?
- objdump
- 其他想不到了,失忆了(寄)
- 你用到了protobuf,知道protobuf是怎么存的吗?(指的是底层怎么进行的序列化)
- 不知道,只知道序列化后是二进制的
- 用protobuf的好处
- 八股文
- 看过什么开源库(关于存储的)
- 我可不敢说leveldb,省的被怼死
- 就说没看过
- 了解mysql吗?(面试官很无奈,其他啥也不知道,mysql总知道吧)
- 了解
- mysql存储引擎,用的什么数据结构?
- B+树
- B+树怎么查询的?
- 八股文
- 失算了,本来想等着面试官问点更深的东西,看来我应该主动说点mysql(innodb/myisam)对B+树的具体实现
- 为什么用B+树,不用B树?
- 八股文
算法题(25min)
飞书,ACM模式
重排链表(需要最优解,LeetCode 143)
- 明明很简单,但是写的有点磕绊,面试官说中途接个电话,暂时消除了紧张感,然后快速把代码框架敲出来
- 中间写了个bug,在debug,结果发现前面没问题,就是后面合并出了问题
- 有惊无险,写出来了
反问
- 如果有幸通过面试,需要提前了解什么?
- 不需要,可以看看存储相关的开源库,对实习生要求不高
- 面试过程中更看重候选人哪些能力?(接着来问的,既然说对实习生要求不高嘛)
- 基础、跟存储相关经历
- 怎么培养实习生,会让刚来的实习生干啥?
- (内容略)
- 最后说,如果没有基础,进来之后会有点痛苦
- 感觉面试官略微有点劝退,可能是在暗示我过不了?
- 我的表现有什么需要改进的地方?
- 表现还可以,对存储不够了解,得讨论一下是否能通过,之后可以问hr结果(加粗的地方也是最终面评内容,hr说不便透露具体内容)
- 我这块有点失误了,应该得更虚心点,解释投这个岗的原因(因为面试官觉得投这个岗,要对存储有所了解),但是我就说了个确实(好糟糕的回答),不过可能再咋说也改变不了啥结果
- 总之就是,通过的概率不如上次高,怕是要收到感谢信了
总结
总体而言这次表现的不算理想,问到了一些知识盲区,也在表达技巧上出了点小失误
虽然确实没有存储相关的经历,但是总体来说,面试体验还不错,面试难度较为友好,面试过程中,不会因为我没有这方面的经历而刻意刁难我
今年总体而言,比去年的表现好点,没有出现口吃的情况,表达也较流畅,算法题顺利解出。内推我的同学也觉得我的表现大概率能过二面,但是他也没想到,hc确实没了,觉得很离谱,面评给了个「没有存储经历」的理由拒绝(对校招生这样要求也情有可原,对日常实习生也是这个要求,就离谱了,应该被冲kpi了),因为去年他面这个岗的时候,也是跟我差不多,没有相关经历的。可能这会在hc收缩的情况下,想面进来的难度,至少得是校招sp一档的吧,那就必须要有相关经历,并且可能掌握的比较深,才行。
对不起,也让去年给我支持的朋友们失望了。我也很对不起我自己。
哎,我真的尽力了,我已经掌握的各种各样的技巧也用上了。只能说,虽然我不少同学都进来了,我也心心念念一年多,还是跟去年一样的结果,二面仍然是我不可逾越的门槛。虽然我的实力确实尚且也达不到校招要求,可能确实跟这家公司也没啥缘分吧。之后有机会了就再接再厉吧,我真的累了。
哦对,顺便说一下,我集齐了字节感谢信的两套模板。
#字节跳动##C++工程师##日常实习##C/C++##面经#