又快到「金三银四」了,一定不少同学在摩拳擦掌,怎样更好的准备从而拿到更高的级别和更好的报酬,咱们来看一位曾在 Facebook和微软工作,面试过数百人的工程师给的经验总结。
三个月?真的可以?
人们常问我,新人或者几年不曾面试的人,成功通过代码面试,合理的时间一般至少要多久?
我觉得三个月是个合理的时间。真的,三个月。如果刚面试不久,也至少需要准备4-6周,如果你过去一年多都没面试过,那不能比三个月再少了。
说回正题,下面是像 Facebook, Google, 微软等大公司面试程序员时主要问的五个部分:
- Coding 面试 (主要考查问题解决能力、数据结构和算法)
- 操作系统和并发相关
- 系统设计(PS:类似于设计一个电商系统,秒杀系统之类的)
- 面向对象
- 文化契合度
和其他需要持续准备的长期目标一样(比如跑个马拉松),遵循一些规则很重要,因为它会鼓励你在动力可能减弱的日子里保持在正轨上。
为此,我创建了一个12周的准备计划,你可以跟着准备。跟着这个计划12周后,基本会覆盖到上面提到的几个部分。
咱们开始吧。
Week 0 - 你应该使用什么编程语言?
选择一种编程语言并坚持下去。经常有人问:如果我知道不止一种,该怎么选?比如 Python 比 Java 好吗?
答案是你该选择自己最熟悉的编程语言。大多数面试官并不在意你是否精通主流编程语言。我看到有人在面试中决定「换」一种不同的语言,这很糟糕,别这样,早选好一种,坚持下去。
Week 1 - 复习你最熟悉的语言的基础
复习一下你选择的语言,即使你在日常编码时,常用到你喜欢的语言,也还是会忘记不少内容。
我见过不少人努力回想这些内容:
- 怎么读写文件
- 怎样从控制台读内容
- 字符串怎么分隔
- String 的 length 是个方法还是属性
- 如何定义和使用二维数组
有一次我还看到候选人不记得判断一个数是正数还是负数(我觉得他知道只是一下想不起来)
你花在回想所选编程语言语法等细节上的时间不如将其放在展示你解决实际问题的能力上,那才是面试官更想看到的。
像Lyft和Salesforce等一些公司,会要求你用笔记本电脑解决问题。您得编写能通过测试用例的完整代码。在这些 case 里,您可能做类似:
- 处理命令行参数
- 解析 CSV 或者 文本文件
当然,你可以直接 Google,但这会花你不少时间,但并不能让你脱颖而出。
而像 Amazon 和 Google 在内的大多数公司,会让你在白板上解决问题。这种考察的能力,和你在IDE里编写代码的经验是完全不同的。现在就得开始练习实际编写代码来锻炼一下了。
Week 2&3 - 数据结构和算法
需要开始复习一下像数据结构和算法这些计算机科学的概念了。实际上,你曾经在大学时上过课但从没认真学过的那些概念实际上对编程面试非常有用。
要复习这些主题:
- 复杂度分析(大O)
- 数组
- 栈
- 队列
- 链表
- 树
- 图( BFS 和 DFS)
- Hash Table
- 堆
- 排序
- 查找
Weeks 4&5 练习简单的数据结构和算法
在您复习数据结构时,开始练习一下和这些数据结构和算法相关的相对简单的编码问题。
通常这些问题在大公司面试里并不常见。即使问,也只能算热身问题。这些反而在电话面试里更常见。但练习这些问题能帮助你内化数据结构,解决几周后要练习的更难的问题。
对于数组,可以复习像下面的这些内容:
- 从数组中删除偶数(奇数)
- 合并两个有序数组
- 找到数组中的第一个非重复整数
- 查找数组中第二大的数
用下面的问题来复习链表:
- 计算链表的长度
- 在单向链表中查找
- 链表反转
- 查找链接的中间值
通过以下的问题来复习栈/队列:
- 对栈中的值进行排序
- 创建返回最小值复杂度是O(1)的栈
- 用一个数组实现两个栈
复习树的问题:
- 在二叉搜索树中查找最小值
- 计算二叉树的高度
- 在二叉搜索树中找到第N大的值
复习图的问题:
- 实现广度优先查找
- 实现深度优先查找
- 检查图中的回路
复习堆的问题:
- 在 list 里找到第 N 小的元素
- 在 array 里找到第 N 大的元素
Weeks 6,7,8 - 练习更复杂的编码问题
你已经练了两周的简单问题,现在该练一些更难些的,在实际面试中更可能问到的问题了。
下面这些准则,在解决这些问题时要注意遵循:
- 一般来说,解决任何给定问题的时间不应超过 20-30分钟。所以现在你自己也要计个时。
- 如果不能在给定时间内解决问题也别灰心。即使花几个小时,也先别看答案,这能帮助你建立信心,然后能更专注的在以后更快的解决。
- 开始考虑每种解决方案的的运行时和内存的复杂度。实际面试的时候必须能清楚地说明,因此最好现在开始。
以下一些可以参考的问题:
- 实现二叉树
- 找到两个链表的交点
- 对句子中的进行逆序
- 检查两个二叉树是否相同
- 克隆(深拷贝)有向图
- 确定数组中是否存在三个等于给定值的整数。
这些你得花2到3周时间。如果遇到问题或者被卡住了,别太担心。一段时间后你一定能解决。在练习开始几天看着难的问题之后会变得容易起来。
Weeks 9&10 - 系统设计面试
系统设计的面试在现在已经成了面试中必不可少的一部分,特别是你要申请高级职位的时候,这些面试会直接影响你的面试「等级」。
学习一些 CAP 、 一致性、 分区、负载均衡等分布式相关的概念很有必要。
在系统设计中,面试官一般会让你设计一个「弹性」的应用,他会根据这些来评估你设计可扩展服务不同部分的能力。比如下面这些方面:
- Web 服务器是怎么做负载均衡的?
- 数据库是怎样分片的?
- 大文件是怎样存储的?
- 为了稳定性和吞吐量,网络是如何设计的
而对应考察这些方面的问题,会体现在类似这种问题中:
- 请设计一个 Instagram (图片分享)
- 请设计一个 Facebook Newsfeed (新闻Feed)
- 请设计一个 Uber
PS: 关于系统设计的问题,我的公众号「Tomcat那些事儿」里后面会陆续分享,包含数据库分片、一致性、数据库设计,负载均衡等设计可扩展应用必备的技术,敬请期待。
Week 11 - 操作系统和并发
今天,即使最便宜的笔记本电脑和手机,也都有多个核。无论你是开发移动应用,还是 Web 服务,了解线程、锁、同步等概念都很有用。
像系统设计面试的问题一样, 多线程和并发问题在衡量你的面试等级也很有用。初级工程师一般只是简单了解。而一个相对高级的工程师应该在这些问题上能做的更好。
Week 12 - 面向对象设计
一些常见的问题类似:
- 设计一个 ATM程序
- 设计一个电梯程序
- 设计一个停车场程序
在面向对象设计的问题中,面试官一般会考察你对软件设计模式的理解,以及你对从需求抽象出 Class 的能力。你得花大部分时间来解释不同的组件,它们的接口,以及组件之间是如何交互的。
文化契合度面试
这一部分有时候可能是最重要的,但许多人并没太注意。例如,在 Amazon,文化深深植根于他们的录用过程中,一些深度认同和践行文化的人最终决定是否录用你。(PS: 和阿里的HR 是否有一拼)
这种方式思想其实也很简单:如果你态度很好,你学新技能也没什么问题,因此编码和系统设计时的一些问题也是可以忽略的。但如果一个人对产品感兴趣但看样子和团队不太好合作,可能也不会录用。
文化契合度面试的一些基本规则:
- 表现出你对产品的兴趣,和对它的理解
- 要做好准备「在与同事或者与经理发生冲突的时候是怎么解决的」这类问题的答案。不要说工作几年,不会有冲突之类的
- 说一下如果面试成功,你在公司想要做什么
- 说一下做为工程师你最近或最有影响力的一些成就。
- 说一些你遇到特别难解决的bug。
总结
准备面试会花费你大量的时间和精力,但如果这能帮助你脱颖而出,那也是值的。在准备的过程中要牢记你的最终目标是找到一个个人满意的高薪工作,将有助于你坚持下去。