2-4 面试准备
广义上的算法岗又可以细分为机器学习、深度学习、自然语言处理、图像处理等岗位。其中自然语言处理和图像处理这两个岗位有比较强的专业特性,一般需要你在学校时就接触相应的项目实践,或者之前就做过相应的实习,否则很难申请到这两个岗位的工作。所以我们这里的讨论就只针对一般意义上的算法工程师。
要注意的一点是,算法工程师,首先是一个工程师,其次才是算法工程师。这就意味着,面试考核的标准首先是工程师的,就是计算机和代码能力,其次才是机器学习算法。有太多同学忽视了这一点,面试跪于代码题,最终没有取得自己理想的offer。
算法岗要求总览
在互联网公司的职位表中,这个算法工程师又有几个别名:数据挖掘工程师,数据算法工程师。或者根据具体的方向又分为:广告算法工程师,推荐算法工程师等等,本质上考察的东西都差不多。我大致整理了一下,主要有以下几个方面:
- 计算机能力
- 程序设计:代码题。主要是基本的代码使用能力,主要是代码逻辑符合预期,不出现代码bug,以及会分析和优化代码效率。
- 算法能力
- 传统机器学习算法:逻辑回归(考的最多),SVM,树及其组合算法(GBDT, Xgboost, 随机森林)
- 深度学习算法,一些常见的模型结构以及深度学习的基础知识要了解
- 其他机器学习基础知识,比如梯度下降,以及AUC计算等等
- 数学能力
- 一些基础的概率与数理统计知识。机器学习算法的概率解释。
其中,数学能力的考察其实比较基础和随意,没有什么明确的章法。主要考察的能力是计算机能力和算法能力,下面我将对这两个能力做详细阐述。
不论是面试也好,笔试也罢,毕竟是一次考试。任何考试都一样,都需要花时间去准备才能考出好成绩。所以大家不要对准备考试这件事掉以轻心。下功夫了,自然可以取得好成绩。
计算机能力
计算机能力实际上是面试笔试考察的重点,我这里着重讲一下。
首先,我来讲一下为什么需要计算机能力。
如果想走算法方向,那计算机能力就是我们手中的工具。我们想通过模型解决问题,首先要对要解决的问题本身有足够的了解之后才有可能解决问题。在互联网公司,整体的流程架构,都是由计算机搭建起来的,自然要遵循计算科学的一些基本法则。
模型算法只是在某一个具体的问题上可以得到某一个看起来更科学的解。所以你如果想让你的算法结果对实际生产产生效用,就必须要至少学会能驾驭得了公司的业务流程架构,驾驭得了数据。
比如我们在学习理论模型的时候,总是假设数据从一个假设的总体之中来,输出了一个结果写完了一个报告就算完事。须知生产过程中获取数据可能需要从hdfs中取得,结果可能也需要打入下一个模块之中,这些都是需要代码来完成的。
此外,算法模型是为了优化某个具体的业务问题。首先我们需要做的是把业务的一般解决方法实现出来。这个实现方法可以根据直觉拍脑袋想出一些规则出来,至少可以先实现业务逻辑,使业务方的要求先实现了。如果效果不理想,在后期有精力的条件下,我们可以再对这个问题上算法模型,做一些结果的优化。所以如果想做算法方面的工作,必须要会做一些基本的开发工作。
对于需要的编程语言,这个其实是看团队的。以头条为例,主要的开发语言是C++和Python,需要Java就少一点,但一些其他公司可能就需要Java多点。但就从整体找工作的情况来看,一般是Python + (C++ / Java)。如果只会Python的话,可能会吃点亏,所以建议大家最好学一下C++和Java其中的一个。因为C++和Java很像,而Python相对来说又比较简单,建议大家用C++进行下面的准备;当然,对于只想用Python的同学们,用纯Python通过笔试面试也是可以的,不过也需要写出正确时间复杂度的算法。其实算法这块,算法是个思路,具体你用什么语言实现都是一样的。
对于实习生的要求,一般python就够了,大家不要太过紧张。
考察方式:代码题
其实计算机能力最核心的考察是看你的代码能力。那么如何进行考察呢?就是给你一道代码题,看你对这道代码题的回答怎样,解题的思路如何?知不知道基本概念比如时间空间复杂度?通过考察一道代码题,至少可以确定你知道这个代码中的基本控制结构,熟悉编程语言。最主要的是,在手写代码的过程中可以看你写代码的写的快不快,有没有bug。
面试算法:本质上考察的是数据结构和算法,比如排序,链表,二叉树。对于非计算机专业的同学,面试中不会特别为难你,让你去写一些深搜or广搜or动态规划。如果是计算机专业的同学的要求高一点。因为你用好几年的时间都在研究这个问题,自然要你掌握的牢靠一些。准备面试这件事就是,尽量要准备的多一些全一些胜算就会大一些。所以建议有空余时间的同学还是看一看这些东西,毕竟笔试题还是有可能会涉及的。
需要准备的科目:数据结构与算法。如果完全没有概念的同学建议先学习一些课程;比如网上的公开课或者自己找些书看。
- 经典教材:《算法导论》。不过比较厚,能啃下来肯定是最好的。
- 薄一点的教材:《数据结构与算法分析》 有C语言实现的,也有C++、Java实现的,作者都是Mark Allen Weiss。找一个适合自己的教材即可。
- 实在想看Python的:《数据结构与算法:Python语言描述》作者是裘宗燕。国内作者写的,我觉得废话比较多,体系比较奇怪。不过好在是Python的。自己定夺吧~
有一点基础的同学:最简单快速的方式是直接刷题。
刷什么题?当然是刷题库。在笔试面试的过程中,有一个非常权威的题库,名叫LeetCode。这个题库搜集的是在硅谷的互联网公司的面试题。我们现在找工作的笔试面试的题库基本都出自这里或者是这里题目的变种。在笔试面试现场屡屡能够命中其中的原题,所以大家一定要好好刷题,认真刷题。不仅仅要看这个代码解题思路,
怎么刷题?当然你可以每道题目都冥思苦想自己做,锻炼自己的思维能力,但是我个人觉得这并不是最有效率的做法。最有效率的做法是先看题,如果短时间内没有思路就直接看答案,对照答案进行反思和体会,然后最好能够在纸上默写解题代码。在面试中,非常重要的一个环节就是手写代码,所以大家一定要注意练习手写代码,和在电脑编辑器上的感觉还是很不一样的。一些资源如下:
- leetcode代码库1 这份代码库中有一个pdf文件,有作者整理的非常全面的leetcode题目的C++题解,直接拿着这个刷答案即可。pdf文件中的题目可能略有点年代了并没有实时更新,但各个题目都是经典。我用的就是这个。大家可以先看C++的解题思路,再用Python自己实现一下。
- leetcode代码库2 这份代码库中是一个新近整理的LeetCode题解,有C++也有Python的解法。甚至还有一些SQL和Shell的题解。应该会很有帮助。
- 除了LeetCode之外,还值得推荐的是一个国内的刷题网站:牛客网。如果大家将来需要做笔试的话,应该也会在这个平台上进行笔试。所以熟悉一下这个平台肯定也是有好处的。
算法能力
我将分为算法推导、项目经验和主要参考资料三个部分来展开。
算法推导
- LR(Logistic Regression, 逻辑回归),这是机器学习的最基础算法,一定要熟练掌握。默写目标函数,极大似然函数。最好由此出发掌握一些LR极大似然函数的解法,实际上就是常见的凸优化问题的解法。
- 树类算法(决策树,随机森林,GBDT)
- 决策树有三种算法,分别是什么?区别何在?节点分叉的是如何判定的?剪枝算法的思路是什么?
- 随机森林。为什么叫随机森林?变量重要性如何度量?
- GBDT。如何实现?常见的损失函数有什么?Xgboost与GBDT有什么区别?Xgboost为什么速度会快?
- SVM。这是一个比较经典的数据挖掘算法,因为比较容易写出推倒公式而被经常考察,手推SVM在前几年是必考题。从目标函数的由来,推到拉格朗日方程。如果面试官要求高,会再细问SMO解法的思路的。
- 深度学习
- BP算法推导,尽量自己可以手推一下
- 常见的attention的做法以及其解释
- 深度学习中的一些基础操作,比如初始化怎么做,梯度消失要怎么处理等等
- 一些其他算法比如DBSCAN和算法工具,比如AUC的计算,ROC曲线绘制等等。
项目经验:
经验在算法岗还是很重要的,所以如果有算法方面的实习那肯定是最好的。此外还可以用在学校期间和导师做的项目以及自己在各类竞赛网上参加的一些比赛来充当自己的项目经验。这些东西也是拿来填充简历的利器。
在面试中,一般面试官都会详细的询问你在自己的项目中用到了哪些算法。具体到你要解决的问题,解决思路,最后的效果及评价指标,以及在项目过程中遇到的难点。这就需要你非常清楚整个算法的解决思路以及曾经踩过的一些坑。如果你回答的有磕绊或者对某些细节没有讲清楚,比如你们没有讲清楚你的特征是如何构造的,那肯定会导致你在面试官的心目中大大减分。毕竟写在简历上的东西应该是你最清楚最熟悉的。所以如果有对简历上的细节不太熟悉的,还需要再斟酌考虑一下。
主要参考资料:
- 《神经网络与深度学习》 近两年我读过的最好的深度学习教科书了
- 李航《统计学习方法》。这本书言简意赅,主要的机器学习算法讲的非常透彻。有关的算法推导一定要非常熟悉。
- 《百面机器学习》、《百面深度学习》。这是两本
- 公开课
- 吴恩达的公开课
- 斯坦福大学公开课:(财富密码)cs229 cs231n cs224n cs234
- 不懂的问题及时查搜索引擎,有很多技术大牛的博客是很值得参考的。
一些其他能力
以上为大家介绍的,都是计算机能力方面最主要的考察——代码题。此外,可能还会有一些其他能力在笔试面试的考核过程中会涉及。这部分的要求的高度不及代码题那么高,属于入职后肯定会用到,会了会很加分的那种。所以希望大家有时间的话也一定要多看一看,练一练。排名按重要性分先后。
- MapReduce, Spark。这是现在最主流计算平台,最基本的使用是需要掌握的。常见的考题有:写一个简单的MapReduce程序(Word Count),hive数据偏斜问题的优化等。
- Shell脚本。因为公司的服务器基本都是Linux系统,所以一些Shell脚本是需要掌握的。主要考察的命令有:awk grep sed crontab等。推荐阅读《Linux Shell脚本攻略》
- git。这是一个代码版本控制工具,能够方便多人代码的写作和管理。大家可以自己弄一个Github管理自己的代码,平时坚持命令行操作就基本上没有问题了。两个推荐的学习资料如下:
Vim/Emacs Vim和Emacs是两个不同的在服务器写代码的编辑器,挑一个熟练掌握即可。因为我是Vim党,就不说Emacs的事了。推荐阅读《Vim实用技巧》(豆瓣)。