你离互联网大公司的距离只有三个月:算法小白的面试成长之旅之路线图

写在前面的话,如果大家购买本文提到的任何课程,都可以使用折扣码 awesome-developer-20 享受额外八折的优惠,本文中所有课程都适用,网站上其他课程一样适用。

这篇文章翻译自educative.io的CEO和联合创始人Fahim ul Haq的原文。
(背景: 我在脸书和巨婴面试过几百个软件工程师面试者;同时我在我没准备充分的时候,自己的算法面试也失败过很多次。起初我只是在美国知乎上面回答一个问题,但随着答案变得越来越长,我觉得把它写成博客。)

三个月是真的吗?你会问。

我们先来看看小伙伴们经常问我的一个问题:多长时间是一个用来准备面试的合适区间,如果我们从零开始的话。当然也包括你多年没面试过了。

我个人觉得三个月是一个比较合理的时间段。对的,就是三个月。要不然,你至少也得准备四到六周吧。当然了,如果你过去一年内面试过的话,可能需要的时间能短点。

现在就让我们来看看本文的主旨吧。下面即将登场的是我们在面对互联网巨头公司(脸书,狗狗,巨婴,等等)的面试时,会遇到的五个主要组成部分。我们来详细看看,他们就是:

算法面试

主要着眼于解决问题能力,数据结构,还有就是算法能力

操作系统和同步性的概念

系统设计面试

面向对象设计面试

企业文化适应面试

和其他我们设定的其他长期目标一样,这些目标的实现需要长时间的坚持工作,比如说,准备跑长途马拉松。而且我们需要遵循一些做事情的步骤。因为这样的方式会让我们保持在一个进步的道路上,哪怕有时候我们士气不是很足。为了到达这样的目标,我写了一个十二周的准备计划,咱们可以用来准备你的下一次算法面试。如果你确实遵循这个计划的话,那么你掌握以上提到五个方面是没有问题的,而且你应该会感到有条不紊。
那我们进入正题吧。

第0周:你需要用哪门语言?

选取一门语言,并坚持下去。我经常会被问到:如果我会不止一门的话,怎么办?比如说,有人会问,是不是Python比Java好呀?答案当然是,你应该选取你用起来最熟悉的语言来进行你的面试。其实很多公司或是面试官根本不会在意你用哪种语言,他们更在乎你能熟练使用一门主流语言。

最糟糕的情形是这样的,我经常会看到有些小伙伴在面试过程中决定语言。这绝对是大忌,纯粹是浪费时间和精力。千万别扯这种犊子。选了就别动摇了,好好练就行。

第1周:掌握你最喜欢的语言的基础

掌握你选取的语言。即使你选择的语言是你工作中常用的,肯定有很多东西你已经忘得一干二净了。我就经常看到有人纠结于以下的情形:
怎么从文件读取,存储?
怎么从控制台读取输入?
怎么分割字符串?
字符串的长度到底是一个方法还是一个性质呀?(答案是,根本不重要,但这样也经常够你喝一壶的)
怎么声明一个二维数组?
C和C++中,怎么处理空字符串?

有一次,我见一个面试者懵逼了,因为他记不起来怎么去判断一个数是正数还是负数。我知道他肯定没问题的,就是头脑僵住了。

其实花在回忆你选取的编程语言的细节的的时间和精力,更应该放在解决问题的能力上。这也是面试官想知道的。

有些公司,比如Lyft和Salesforce,就要求你在你电脑上解决问题。面试官就想看到你能写出完整的代码,而且还能通过测试用例。在这种情况下,你就需要做到以下的事情了:

处理命令行参数
分析CSV或是文本文件

当然了,你可以进行搜索,但你同时也就需要花不少的时间在这些琐事上面,那你的结果也不会太理想了。
其他的公司的话,包括亚马逊,狗狗,你可以把你知道的公司填在这里,他们会要求你在白板上直接解决算法问题。这种体检和在电脑上写代码有巨大的区别。那我们就来开始训练怎么去练习白板写题目吧,其实同时你还得讲明白你的思路,我们需要通过这样的训练锻炼一下我们的写代码相关肌肉。

第2–3周:数据结构和算法

这个时间就需要去复习或是学习计算机的基础知识了,其中最重要的就是数据结构和算法了。你也知道,感觉这些知识你只是在你本科学习的时候见过,在那之后,你就讲他们抛之脑后。但现实却是这些东西在面试中占的比重特别大。以下的这些课程就会对你有帮助:如果你之前选择了Python,那么你就去看 Data Structures in Python: An Interview Refresher;Java则是Data Structures in Java: An Interview Refresher;当然了,JavaScript的话则是Data Structures in JavaScript: An Interview Refresher;相应的,C++选手的课程是:C++: An Interview Refresher, as well as Algorithms in C++: An Interview Refresher
里面也包含了算法部分。

你也需要熟悉大 O O O的概念以及复杂度的分析,你可以去看这么课:Big O for Coding Interviews and Beyond。你也可以去看这篇博客“The insider’s guide to algorithm interview questions”,里面会有详细的分析,以及实际的操作过程。
算法和数据结构的学习,必须掌握以下的内容:
复杂度分析(也就是 B i g O BigO BigO
数组:Arrays
栈:Stacks
队列:Queues
链表:Linked List
树:Trees
字母树:Tries (其实他们和普通树是一样的,但他们的应用场景比较特殊,也值得单列一下)
图(宽度优先搜索和深度优先搜索):Graphs (BFS and DFS)
堆:Heaps
排序:Sorting
搜索:Searching

第4–5周:练习一些基础的数据结构和进行算法练习

随着你对数据结构的熟悉或是重新熟悉,你同时也应该开始练习一下和这些数据结构和算法相关的算法题目。

这些问题虽然一般不会在面试中被问到,即使问到,也都是诸如fizz-buzz之类的暖场问题。这种问题在电话面试中比较常见。但练习这些东西却是至关重要的,因为这能让你内化这些知识,以便于你更好地解决更难的问题,当然了,咱们下面几周就需要训练更难的问题。

比如你可以练习你的数组操作相关的能力,诸如:
怎么删除数组中的所有偶数
怎么合并两个已经排好序的数组
找到数组中第一个没有重复的数
找数组中第二大的数

练习链表相关的以下能力:
求链表的长度
单向链表中查询数字
反转链表
找链表中最中间的数

栈/队列相关的基础题目:
给栈里面的数排序
构造一个新的栈数据结构,让我们能在 O ( 1 ) O(1) O(1)的时间里返回最小值
用一个数组实现两个栈

练习树相关的以下题目:
找BST中最小的数
计算二叉树的高度
在BST中找到第K大的数

图的题目:
代码实现BFS
代码实现DFS
检测图中是否有环

字母树的题目:
字母树中总的单词总数
找到字母树中排好序的单词

堆的题目:
链表中第k小的数
数组中第k大的数

第6–8周:练习更复杂一些的面试题

现在你已经练习了不少很直接的算法题了,是时候来点挑战了。因为面试中,其实题目都不会像之前练习到的那么简单直接,很多题目还是蛮有挑战性的。稍稍难一些的题目,更容易在面试中出现。

为了让你更好的了解和练习这些题目,你可以跟着这门课程(Coderust: Hacking the Coding Interview)学习。
在练习的过程中,记住一些纲要性的东西很重要,比如:
一般来说,别在任何问题上花超过20-30分钟时间。当然了,不是每个题目都那么快就有思路的。

但如果在规定的时间没法解决问题的话,大家也别灰心。还是要接着把遇到的问题解决掉的,哪怕花费几个小时,但记得别去看答案。这样会建立你解决问题的信心。你只要下一次解决起来更快就行了。

解决问题的过程中,要同时考虑到时间复杂度度和空间复杂度。在面试过程中,你就需要清晰地列出来复杂度,所以你得从平时训练中就注意到。

这个阶段的训练,你可以解决以下的类似问题:
实现二分搜索
找两个链表中的交集
反转句子里面的单词
检查两棵树是否相等
深拷贝一个有向图
找到Boggle game中的答案
判断数字中是否有三个数加起来等于某个数(3sum)

这个阶段需要花费2–3周。如果遇到困难或是经常卡住什么的,也别太担心。你能搞定他们的。相信我,一开始看起来无从下手的问题,练习多了,也就得心应手了。

第9–10周:系统设计面试

软件工程师的面试中,系统设计面试已经是不可缺少的部分了,尤其是你申请的是更资深的职位的话。而且系统面试的结果,往往将决定你的等级。

学习分布式系统中诸如Cap Theorem, Consistency, Partitioning, Load-Balancing等等概念。
准备过程中,推荐去看这门算法设计课:Grokking the System Design Interview.
比如你会遇到诸如设计一个可以处理大流量的网页服务。面试过程中,你会遇到这样的问题:
你的网站服务器怎么实现负载均衡?
数据库是怎么共享数据的?
大文件如何存储?
如何设计网络,能处理冗余和高的吞吐量?

你在这个课程中能学到:
设计Instagram
设计脸书的Newsfeed系统
设计Uber

可以去看看作者的博文:Top 10 System Design Interview Questions for Software Engineers获取更多的系统设计面试的信息。

第11周:操作系统和同步概念

现如今,即使很一般的个人电脑或是移动电话,都是多核的。理解诸如线程,锁,同步等等的概念,都将是大有裨益的。无论你是搞移动开发还是网页开发。就如大部分的系统设计问题一样,关于多线程和同步面试问题,都是测试你水平的有效方式。一般入门的程序员都会纠结于这些问题,当然了,这些东西也是在工作中慢慢积累起来的。资深一点的程序员回答这些问题就比较得心应手了,因为他们在工作中不可避免地写了类似的代码,可以用到多核或是多线程资源。这门课对相关的概念就会起很大的帮助作用。

第12周:OOD面试

常见的问题有:
设计ATM机
设计电梯
设计停车场系统
更多的问题参见这个博客:The Top 10 Object-Oriented Design Interview Questions for Developers。

这OOD面试中,面试官通常是考察你对软件设计模式的考察,以及你讲要求转换成各种实体类的能力。你讲会花大量的时间解释各个模块,以及他们的交互。下面这个课对OOD有很好的帮助:Grokking the Object-Oriented Design Interview。
软件设计模式的话,可以参考这个课程:Software Design Patterns: Best Practices for Software Developers。

企业文化适配面试

这个是大家特别容易忽略,觉得不重要的地方。但其中有时候这却是最重要的一环。比如Amazon的面试,文化适配简直就是面试中最看重的地方,没有之一。很多时候,遇到Bar Raiser的面试者话,可以一票否决你的面试结果。

其实背后的原因很简单,如果你态度好的话,你学起技术来也没问题的,所以代码或是系统设计中的小差错就不那么看重了。但如果面试者对产品根本不感兴趣,或是根本不是一个团队选手的话,这样的选手一般就不会被招聘,哪怕你确实很厉害。有一本出门的书叫做The No Asshole Rule。讲的就是公司一般不会招聘哪些对公司不利的员工,因为长期的的成本是很高的。同样的,公司也不会招聘对公司产品没兴趣的人。企业文化适配就是为了不招聘这些人。

下面是一些这个方面面试的小规则:

  1. 表现对产品的兴趣,展示自己对产品的了解。比如我就遇到面试者说脸书卖AWS这样的云服务。他竟然还用过。但这些肯定就说明这个面试者不是很了解脸书了。

  2. 得准备一下,怎么去描述一些场景里面,你和队友或是经理有冲突,你是怎么协调解决的。千万别说,你从来没遇到过这种情况。

  3. 讲述一下你在该公司想实现哪些东西。

  4. 讲一下你作为程序员,最近取得的不错进展。

  5. 讲一下你遇到最麻烦的bug。

结语

准备算法面试需要花费很多的时间和精力,但同时也能让你脱颖而出,让公司信任你能做好复杂的工作,这些努力都是值得的。我觉得在这个过程中,一直记得自己的目标会很有帮助。针对面试的话,目标就是实现个人的满足感,以及找到一份高薪工作带来的待遇。

好的资源

作为参考,作者在这里列出了上面提到的课程链接:

Coderust: Hacking the Coding Interview
Algorithms in C++: An Interview Refresher
Data Structures for Coding Interviews in Python
Data Structures for Coding Interviews in Java
Data Structures for Coding Interviews in JavaScript
Big O for Coding Interviews and Beyond
Grokking the System Design Interview
Grokking the Object-Oriented Design Interview
Grokking Dynamic Programming for Coding Interviews
Java Multithreading and Concurrency for Senior Engineering Interviews
Software Design Patterns: Best Practices for Software Developers

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值