面试日志 - 1

Posted by Dongbo on April 13, 2022

阿里OceanBase实习一轮面试总结:

简历上内容包括声明了主要使用语言是 golang,用过c++/java/python,然后对数据库事务比较了解和感兴趣,项目方面放了 pingcap 的 tinykv 和 CMU 15445 的 bustub,以及之前go后端实习搞的一个网络模块相关功能。

面试官一开始就对 tinykv 很感兴趣的样子,其实从约面试的时候他特意问了一句这个项目这点就应该要意识到了,人有点愚钝,虽然确定面试时间之后已经额外复习了项目,但是做项目那会时间仓促完成度不是很高,理解也差点火候,很多问题都没回答好。简要记录一下问题吧。

  1. 介绍一下 tinykv 这个项目
  2. raft的选举过程
  3. raft出现“双主”的情况会有影响吗,有什么办法能够避免;我在回答了实现旧leader退化机制之后,面试官追问能不能保证双主情况完全不会出现(后来回想了一下感觉他其实想问我出现双主之后怎么不让客户端读到旧的数据)
  4. 如果有一条日志被追加到多数节点后,它还会不会被覆盖;回答有可能之后,追问raft作为一个共识算法,在日志已经被写到多数节点后还进行了覆盖,是否不符合认知
  5. 2PC分布式事务,协调者在项目里是如何实现的(面试官似乎不知道实现的是percolator算法,也可能是因为我简历上没有写清楚只写了实现2PC),本来我对percolator了解也有限这块就随便扯了扯 //那踏马的是主管来面的我还跟黄东旭交流过OB和TiDB实现的人怎么会不知道percolator
  6. 看我项目描述里写的是:实现2PC协议,提供快照隔离级别的并发控制。问我这二者有什么关系,具体怎么实现的
  7. 因为我提到基于时间戳的多版本并发控制,提问如何实现时间戳分配的,我说有一个全局的时间戳生成器之后追问,有考虑灾备吗,如果有充足的时间重做这个项目会怎么实现
  8. 描述raft的成员变更过程

raft 部分问得我头皮发麻,然后开始提问一些基础知识:

  1. 两阶段锁如何实现不同的隔离级别(bustub)
  2. 全局变量和静态变量了解吗,有什么区别?如果把一个静态变量的地址通过指针传给其他文件的函数,合法吗,为什么?
  3. 用C++模板比不用模板,有什么区别(大意,原问题记不清了
  4. 进程间通信的共享内存方式如何实现的
  5. 网络编程(我说不了解就没再问

最后的沟通环节面试官还跟我聊了会儿天,觉得做数据库内核的,真要快还得是C/C++,原话是”虽然go也挺快的,但是有些时候还是没法做到极致“,本来想趁机问一下他们最近在解决什么问题的、有什么有挑战性的工作,但是他说OB本身做得差不多了,像一些分布式延迟(大概?)的问题都差不多解决了,最近在做性能上的阿巴阿巴(我没听清,甚至不确定他说的是不是性能),反正这块没太给我细说,但是给我补了一句,”我觉得还是挺有意思的一些问题“。问我有没有跟其他公司聊过,希望选哪里的base,还说早知道给我多介绍一下OB,聊下来感觉没有太大距离感,挺像是跟学长聊天的,很nice。确实让我产生一种跟这样的同事共事应该会很愉快的感觉,希望能过吧QAQ

最后做了一道算法题,leetcode 第2题的两数之和但是链表是正序的,给了5分钟思考时间和30分钟实现。听我讲完思路(反转链表然后逐位相加)之后面试官问我还有没有别的做法,我一时想不到,就让我按自己的思路做,要求尽量按照实际项目的编程要求,把各种特殊情况都考虑进去。我满嘴答应,交了之后才想起来用了两处 new 分配节点但是刷题养成习惯了没有写 delete,呃,这应该大概也许没有太大影响吧。。。

总之第一次面试的概况就是这样,回去抓紧学习了


更新二面情况:

两周之后接到二面的通知,我都以为已经凉了。这次约的面试时间是半个小时,看时长感觉应该不会像一面那样广泛问各种基础知识了。

开始简单自我介绍一下之后,面试官看我简历上提到了解过 BoltDB,让我介绍一下。我就把之前归纳进博客里的 b+ 树、freelist 和 shadow paging 简单给描述了一遍,然后面试官抓着 shadow paging 问这个机制如何保证事务的性质。我正打算按 ACID 顺序逐个分析一下,但是刚讲完原子性,不知道是我无意中提到 partial write 问题了还是咋地,面试官突然说你刚才介绍的包括修改元数据也好,写页面也好,这些过程能保证原子性吗。我大惊,怎么开始问这个,这我可没准备啊,回忆了一下之前看日志恢复时候的笔记,感觉操作系统确实没有保证,回答之后面试官接着问,那你有什么办法来保证这个过程是原子的吗。我:之前了解过一点 MySQL 对这个问题的解决方案,它是通过二次写机制来解决的….(诶反转了,虽然没准备但是曾经看过还做了笔记)

然后开始介绍二次写的原理,如何通过二次写来保证写入页面的原子性,但是面试官又追问,那如何判断一个页面是否发生了部分写呢。我最开始想的是,那就不判了,每次恢复我们都从 double write buffer 里恢复最后正在写的页面的数据。面试官指出 buffer 里的数据不能保证是完整的,如果无脑用 buffer 的数据难道不会读到不完整的数据吗,“所以怎么判断一个页面是不是完整的”。我一番思索,既然这样我们在页面的末尾加上一个flag,只有写完整个页面才会设置这个flag,就能判断页面是否完整。面试官问,这个flag你要怎么设置,如果你先写完页面,然后再写flag,那相当于又重新进行一次写的操作。我回答说把flag放在页面末尾吧,这样不是写完页面才会出现 flag 吗。面试官说,那我告诉你,写页面的过程其实不是顺序的,一个页面多个扇区可能是并发在写(如果有多通道的话),你要怎么设计。我:要不我们把写入块的大小设为跟页面一样大,这样写操作就是原子的,我们就不用考虑这个问题了(开始逃避)。面试官说,那是另一种解决方案,但是现在我就想问你这种情况你怎么处理,别逃避,实际工程里要解决的问题多着呢(无情铁手!),给你两分钟思考一下。

被拉扯了,只好想想这要怎么做,脑子里不停的过着:并发写、页面内容固定、写之前需要预先处理好。沉默了半分钟突然想起来校验和,艹,操作系统没学好难道我机网也没学吗,早干什么去了。跟面试官说了校验和三个字,面试官心领神会点点头,哎,这个问题终于过了。面试官又补充介绍了其他的处理方法,比如可以把页面的信息写到外面,然后把那些页面设置为原子的。

再后面又简单问了几个 raft 的问题,比如选举冲突怎么处理,等待时间的范围怎么确定,也没太深入问就差不多到时间了,这次面试就这样结束了。

这次表现自我感觉比上次好不少,起码没有一直对不起我不会了。知足了,就算没过这次经验也必能活用于下一次!


又过了一周,安排了 HR 面,不过到现在(又过去了几周)具体的流程可能记得没那么清晰了,就只能简单记几条我记得的问题。

同样是自我介绍开局,问了一下本科成绩和研究生成绩都怎么样;过去一年半年有碰到什么比较大的挫折,方便展开介绍一下吗;你的老师和同学是如何评价你的;为什么选择我们部门,对我们部门了解多少,能说一下对 OceanBase 的理解吗;还有别的 offer 吗,有投过其他公司(比如字节华为Pingcap) 吗;比较理想和比较难以接受的工作时间或者工作状态是什么样的。

HR 面之前我还问学长有什么要注意的,告诉我没有。现在看来好像也是,基本如实回答就行了,只要回答别太离谱,应该不会挂在 HR 面里。比方说我其实对 OB 没什么了解,我就跟 HR 直接说,我了解不多,但是我可以给你介绍一下简历上的项目,HR 说不用了(笑;另外老师和同学的评价这个问题我也不知道怎么讲,只好说他们怎么评价我不知道,我只能给你说一下我的自我评价…诸如此类


大概一周之后收到了意向书,确认之后又过了大概十天,才有 HR 和入职管家联系我,安排了体检,确认之后入职的具体日期。终于可以把每天的通勤时间缩短到单程10分钟了,应该不会像之前那么累了吧,能更好的摸鱼了(bushi

不如入职之后每周概括一下本周的主要工作内容和收获吧,鞭策一下自己,也能当作成长过程的一个记录吧

The End