系统设计面试. 1point 3acres
系统设计面试是我要着重说的,因为我本身算是MLE,对于系统设计是从零开始准备的。我在三月份大概花了三周的时间把DDIA(Designing Data-intensive Applications)这本书看了一遍,然后四月把grokking(grokking the system design interviews)看了一遍。当时我觉得自己简直无敌,然后去面试Robinhood的第二轮电面(job scheduling system那道题)就挂了。那是我人生第一次系统设计面试,也是我这次这么多轮面试第一次挂在电面上,对我打击很大。特别是我提前刷了面经,知道了他们大概率面这道题目,提前把公司内部的job scheduling那个组的文档和论文都读了几遍,对于这个系统可以说是了如指掌了,但是面试依然挂了。
当时我就意识到一个重要问题:系统设计面试,技巧也很重要。面试技巧只能在实战中学会。于是我幡然醒悟,在一个付费模拟面试的网站(interviewing.io)进行了4次系统设计模拟面试。每次模拟面试完了之后,面试官会立刻跟你反馈,hire还是no hire,问题在哪里。只有这种即时反馈的模拟面试,才能真正让你的面试技巧得到提升。我当时第一次模拟面试就拿了一个weak hire at senior level,面试官给我的反馈就是对面试节奏把握不好,达不到一个senior的要求,这个一会儿我会详细说。
. .и在那个面试官花了十分钟教我如何把握面试节奏之后,我变质了。我像是打开了任督二脉一样,突然意识到了,在花了那么多时间看书看资料练习内功之后,如果把功力在面试的时候表现出来也很重要。于是我给自己定了一个系统设计面试套路,后面的面试都坚持那个套路,同时根据面试官的风格不断调整,做到始终掌握节奏。后面的三个模拟面试,拿了两个hire一个strong hire at senior level,因为我花了那么长时间看DDIA和grokking,我不缺内功,我只缺面试技巧。
下面我来分享这个我自己总结出来的系统设计面试套路,特别是针对senior level。因为senior的系统设计面试,很多公司会要求面试者能主导整个谈话(drive the conversation)。
在搞清楚需求之后,对于senior面试者,一般都是希望你从这里开始一直主导对话直到结束的。所以我会直接说"okay now let me list a few topics that we wanna cover",然后直接写下"API design", "capacity estimation", "high-level architecture design","database (schema, sql/nosql, sharding, replication)"和"other topics"。这些就是系统设计可能会讨论的大方面,提前写好可以保证你在主导对话的同时记得涵盖所有的点,不然自己一直说,可能一兴奋忘了说重点。列出这些点之后我会说"now let's start with API design, what do you think?"然后面试官就会回答好或者不好,你就可以继续说下去了。这里要注意的是,我们其实只是在假装"drive the conversation",最后先说哪个再说哪个其实还是面试官决定的,除非在少数情况下面试官没有偏好,告诉你先说哪个都行,那你就可以自己随便挑。注意,如果面试官让你自己挑顺序,你也要按照合理的顺序,或者让自己最舒服的顺序,来最大化自己的收益。下面具体说说买个方面应该怎么应对。
Database (schema, sql/nosql, sharding, replication)。一般讨论数据库的时候就是讨论这些点,说schema的时候一般说一下有哪些表,每张表有哪些column,谁是primary key就行了。对于sql/nosql,要根据场景来说,我遇到的只能用sql的场景很少,只能用nosql的场景也不多,一般都是二者都可以,但是我会跟面试官说虽然二者都可以,但我更偏向于nosql,因为这里写操作比较多。但是大家还是要根据具体情况来,比如订票系统,牵扯到多张表的distributed transaction,那么只能是sql,还有购物相关的系统,user-order-item这些东西是天生relational的,那么sql也是更好的选择。我印象中的其他系统就很少遇到那种只能用sql的。对于sharding,一般都有一个"shard by user id"还是"shard by item id"的trade off,如果是user id,那么会有Hotspotting问题(因为有的user特别活跃),如果是item id,虽然可以解决hotspotting问题,但是如果需要读某个user的数据,就需要访问所有的shard。这个trade off对于大多数题目都适用,如果是你在讲database的时候主动提出,会大大加分。
Other topics(cache/how to scale/push vs. pull/monitoring/rate limiting/failure handling/logging)。如果以上所有东西说完还有时间,一般面试官会让你在这里面挑一两个点讲一讲,就挑最拿手的讲就行了。注意,有时候这里面的某个点会是这个系统的重点,那么就应该把这个点放在前面着重讲。
. Χ
以上就是我总结出来的套路,但是一定要注意在面试的时候根据面试官风格的不同适当调整。技巧就是每次都先问问面试官是不是ok,比如"let's start with capacity estimation, what do you think?",有的面试官压根就不希望你做capacity estimation,会告诉你先不要做,后面有时间再做,那么这个技巧就可以帮你节省大量的时间。有时候有的面试官自己有强烈的偏好,会告诉你先画high-level architecture,然后等你画完不给你机会自己说,而是开始问问题,不给你机会drive the conversation。我面了这么多家,各种风格的面试官都遇到过,最后得出来的体会是:这个套路可以应付大多数面试,但是一但发现面试官有自己的偏好,就一定要放弃套路,跟着面试官走,有的面试官完全不需要你来drive conversation,你就让他问问题就好了。有的面试官在你说话的时候绝对不会打断,所以你要不断确认你说的是否合理,不然花很多时间说一些面试官根本不在乎的东西,虽然不扣分,但是浪费了宝贵的时间。对于大多数传统的面试官,根据这个套路就能应付。
第一轮的谈判要点就是绝对不要透露自己真正的期望,同时尽可能拿到比较高的初始offer。所以对于你最想去的公司,一定要留在靠后的位置,已经拿了很多的competing offer之后再开启初始谈判。有时候某个公司出结果比较早,但是你又比较想去,你可以说“我现在还暂时没有期望,能不能等我拿到其他offer告诉你”,然后你就可以拖到你拿到一些competing offer之后再开启谈判。一般的公司都不能来回很多次的,所以对于特别想去的公司,要力求在第一轮就让他们给出比较好的offer。一般的公司都不会给你很多轮谈判的机会,所以我珍惜了每一轮的机会,我对于最想去的公司,在谈到一个不错的价格之后,直接使出了最后一招:给到多少就签字。这个就是你的底牌,说出这句话就意味着这就是最后一轮谈判了。而且这张牌也只能对最想去的公司说。这个只是在一个已经不错的offer基础上再加一点钱的方法。我最后靠这个方法拿到了out of band的数字。