序言
Motivation
这是我第一次向商业公司投递简历。我从三月开始投 Optiver 到五月下旬收到拒信,经历了从 OA 到一面、二面乃至三面的一个比较长的流程,积累了宝贵的经验,思考了很多,也在面试中学到了许多。我曾一度犹豫是否要写这样一篇文章,最终我选择写下来,一是对人生中第一次面试商业公司的经历做一个比较完整的反思总结,以求精进,也算是这个事情有始有终;二是为门友提供一些(可能不太成功的)经验,供大家参考。
之所以发在交大门平台,是因为我是从交大门获取到这个岗位信息的,也算是一种回馈社区吧。
我的水平有限,还望各位多加指正。
本文会包含的内容
- 各轮面试的流程简介
- 部分面试问题
- 我对于面试问题的思考
- 我对于我的不同思考的评价
本文不会包含的内容
- 面试的细节
- 面试问题的正解
- 我对于公司的评价
OA
Optiver 是一家量化交易公司,他们的 OA 相比于互联网公司的花样稍微多一点,其中比较有特点的就是所谓的“Zap-N”。我投递的 SDE Intern 岗位 OA 包括三个部分:算法题、基础理论知识题和 Zap-N。
算法题是在 HackerRank 平台上,两道不太简单的题目。给到我的是一个 LogServer 背景的数据结构题和一个图论题,当时我没怎么准备,也不太在状态,写的都不好。LogServer 正解感觉是平衡树,图论是拓扑排序;实战中我前者用 multiset 乱搞,后者写了个奇异的 dfs(后来我证明了这个 dfs 的复杂度是错的)。这部分内容本文不展开说。
理论知识部分是选择题,主要考察计算机和算法相关的基础知识,有限时,把自己搞得怪紧张的,但是实际上时间还是比较充裕的。
Zap-N 是比较有意思的一部分,它由若干个小游戏组成。这些小游戏考察反应力、记忆力、逻辑推理能力,整个玩一遍感觉非常累,但是趣味性还是很足的。
做完 OA 之后,我的心里没什么底。我当天就进行了复盘,结论是算法题全错啊全错。
一面
在得知进入面试流程后,我怀着惊喜与惶恐(夸张),开始准备第一轮面试。这一轮是 HR 面,问的都是 BQ,我针对性地做了相关准备。Optiver 的整个面试流程原则上都是英文交流,因此我也在这方面下了大力气,准备了一些稿子。差不多就是这个时候,我开始关注 1p3a,这是题外话。
一面的形式是和 HR 约好时间后,打电话交流。非常幸运,我的准备没有白费,几乎所有的 BQ 都在我的准备范围内。很快,HR 和我约了下一面的时间。
这一轮面试给了我不小的信心,事前的准备工作确实是必要的。
二面
这一轮开始是技术面,考察 coding 和 system design。我本身不太担心 coding,因为按照我的预期,常规的算法题应该不太能构成我的障碍(伏笔);转而去担心 system design。这一轮的准备不太充分,当时的时间比较排不开,而且我本人对于面试中考察的 system design 完全是一个没有概念的状态。
然而现实更加出乎我的意料。coding 部分直接给到了 Concurrency Queue,并且平台对该题只有 Python 3 的高亮和补全。所幸面试官比较友好,允许我使用别的语言。
我的 Concurrency 水平肯定不能说是低,但要发挥出 production-ready 的实力,没有 linter 和搜索引擎肯定是不行的,最起码我需要看 api doc,但这不现实。于是我选择用 Rust 开搞,无脑加了 Mutex(后来我得知 spsc 的 concurrent queue 是完全可以 lock-free 的,而我根本没有加以分析,可见是乱了阵脚),中途犯了很多小错(比如元素入队之后指针没有自增),磕磕绊绊才造完,十分狼狈。同时,我心里清楚这玩意大概率是没办法通过编译的,心里凉了半截。
coding 部分结束,面试官问了一个“why Rust”的问题,我勉勉强强从”relative safety“、”great type system“几个角度讲了一下,特别还提了一嘴”fearless concurrency“,可惜英语口语不太好,也可能比较紧张,说话磕磕绊绊的。
system design 部分是经典题”Design a ticketing system“。我并没有什么面试经验,因此没有做什么 QPS 相关的分析,我问了关于 scaling 的问题,面试官答的也比较 open,于是直接按照基本法去设计了。这部分没什么好说的,网上有很多讲这种东西的资料。
这一轮面试给我泼了一盆冷水,不过我至少找到了努力的方向。在那之后我看了一些 system design 的资料,也去简单了解了一下 lock-free 的 concurrent queue 实现。我认为进一步提高这些硬实力对于我是很关键的。
三面
能到三面完全是老天爷给面子。这一面依旧是 coding,注重工程能力的考察,让我实现一个多线程应用程序中的某些关键调度逻辑。有上一面的缓冲之后,我把 C++ 基本的一些同步原语背了一下,同时面试官也说”just p-code“,因此在编码上没遇到太多障碍,主要还是思维障碍。
题目给的需求场景我在做个人兴趣项目的时候是经常遇到的,但可能是我平时不主 C++,也可能是面试不够平常心,我完全没有想到 event queue 这个做法(搞笑的是,system design 时我给的 solution 核心就是一个差不多的 message queue),更搞笑的是我没有意识到 map 的 key 可以作为一个 search index,出了一点思维上的失误。
这一轮整体感觉一般,有时候思维上的失误比小错误更致命。
反思总结
- 表达很重要,如何把 idea 以一种恰当的方式传达给对方,是一个非常重要的课题;
- 不能着急,保持冷静才是关键,还是需要训练抗压能力,无论有没有思路,都要能够正常地尝试思考;
- 相关硬实力的提升不可懈怠。