由于业务的需要,最近面试了很多数据库候选人。发现很多候选人在面试准备时会有一些普遍的误区,借此机会展开聊聊我作为面试官的一些建议。这次主要讲四个误区:代码基础差、工程素养弱、沟通思维无、知识框架碎。
误区一:代码基础差
数据库是一个工程性极强的领域,因此代码是面试考察中非常重要的一个环节,可以说代码写得好,即使背景稍弱,也可能会通过面试;但反之则不然,遇到过一些候选人,分布式事务的一些细节可以说的头头是道,但却连链表等基础数据结构都写不太明白,这个情况就是想给过也有心无力。
说到代码,我们并不期望候选人要能做出多么难的算法题。反而,会更针对偏基础、偏工程的方向考察。
- 基础数据结构。基础数据结构包括链表、哈希表、树等常见的数据结构和相关算法,最好都能快速地自己实现,并了解每种数据结构的特点。图偶尔会考察,但比较少,而且考察点很固定,通常就是最基本的遍历(BFS、DFS)、最短路、最小生成树和拓扑排序等三四个固定的算法。
- 常见算法。最基本的就是几种常见的排序算法[1],弄清楚其时间复杂度和空间复杂度以及基本的优缺点。另外一个初学者比较难理解的就是基于树的回溯算法,这个本质上是对递归思想了解的不透彻。当然,我当年也是花了很久才理解这种思想,但一般不会考很难的回溯。另外就是二分算法和分治算法,其核心思想是拆解问题域,去解决子问题:二分就是不断缩小问题规模,分治则是在缩小规模的基础上,还要将子问题的解进行组合,进而求解原问题。动态规划算法会比较难,通常不会考,即使考也只会考非常简单的,比如最基础版本的 01 背包问题。
- 工程题目。我之前去面试其他公司,偏工程题目被考到最多的就是 LRU,因为他结合了哈希表、链表等多个数据结构,Corner case 也比较多,是很看代码功底的题,但是后来背的人多了,区分度也就不太高了。另外就是前缀树,也就是 Trie 树,这个相对少一些,代码写起来也会细节很多。我自己多会问一些基础数据结构的实现,比如实现一个哈希表,这个题可以有很多 follow up,比如扩缩容、线程安全等等;此外一些涉及文件读写、字节操作、多线程的题目偶尔也会问,由于这些 API 通常都很难记,这时候我通常让候选人可以随便查阅互联网,只需要让我看着就行。其实看候选人如何解决问题、如何搜索的过程本身也是一种考察。
误区二:工程素养弱
现代的数据库代码,动辄数十万行,如果没有良好的代码规范,会在项目演进过程中很快变得不可维护。因此如果候选人在写代码时能够比较注意代码风格、体现出工程素养,会非常加分;反之如果胡乱命名、没有基本的抽象和复用,则会很减分。
另一个很能够体现工程素养的点是:解决实际问题的思路。比如当面试官考察一些工程代码时,题目可能比较模糊、宏大。这时候候选人如果能:
- 用一些计算机常识,将模糊地带进行确定化。比如题目不要求基于内存还是文件,我们都先假设都在内存中,然后跟面试官说下利用 WAL 和 SnapShot 等方法应对宕机即可。
- 做一些简单假设,将问题域进行收束。比如数据类型不确定时,我们可以假设是最简单的整形;又如文件数据格式不确定时,我们可以假设一行一个数据。
- 抽象出基本模块,先走通宏观思路。也就是做项目时常用的最小可用原型思想,将每个子问题(比如读写文件、排序等)模块化,使用最简单实现、甚至暂时留白,从而专注主干逻辑搭建,迅速实现一个可用的原型,尔后再跟面试官讨论,对需要的模块进行优化。
其中,最后一点非常重要,因为面试时间通常都很有限,如果你很快陷入某一块的工程细节中,比如如何读写文件、如何取舍 buffer 大小、如何处理 offset ,轻则时间到了还写不完、重则由于紧张陷进去根本出不来。这时候一定要注意使用最小可用模型、自顶向下逐步求精等思想,因为这也是我们在实际工作中完成任务常见的思想,是非常能够体现工程素养的一个侧面。
误区三:沟通思维无
本篇文章出自我的持续更新的小报童技术专栏:《系统日知录》,还剩下两小段,欢迎前往