最近,机器学习岗位越来越火爆,那么自然对算法的一些能力要求也是越来越高,想要在求职者中脱颖而出,起步自然非常重要。
我和小伙伴们一起研讨了 2019 年校招的一些算法面试,有些是亲自经历的,也有伙伴分享的。总结了在所做过的项目中大家应该能牢记于心的点、在机器学习算法、数据结构和代码中出现频率最高的问题。希望大家能通过该调研报告,对自己的情况查漏补缺,了解自己需要提升的方向。
友情提示:本文文字内容过多,可能引发视觉不适,敬请见谅。
项目
介绍机器学习项目的时候,项目中的损失函数、如何优化、怎么训练模型的、用的什么数据集能够十分清晰的描述出来。对自己做过的项目要自信一些,在讲解的过程中不要自己有一些疑惑或者模棱两可的说法。以下是几个在介绍自己项目时需要注意的点。
准备细节:一旦被问倒了,面试官在心里就认为你没做过。在面试前,应当适当的准备项目描述的一些说辞。很多同学在准备的过程中,会局限于项目具体完成了哪些业务,以及代码实现中的各种细节。事实上,这并不是一个非常好的回答,这相当于把后继提问权直接交给面试官,很可能在中间环节被面试官直接打断,提问中间他感兴趣的某些细节。因此,建议大家按照以下的方式进行介绍:
-
讲述项目的基本情况,项目的背景、规模、用时、用到的技术以及各个模块。重点突出自己比较熟悉的技术,防止在面试官打断的提问的时候,问到自己最薄弱的环节。
-
主动说出自己做了哪些事情,这部分的描述要尽量和自己的技术背景一致,描述自己在项目中的角色。
-
描述模块中用到的技术细节,这部分一定要注意,一定要把话题到自己最熟悉模块的技术细节。自己说出口的技术,一定要是自己会的,宁可少说,不要夸大。
-
注意面试官提问的问题,不要太过于简单的回答,尽量把自己知道的相关的部分都说出来。
-
注意不要说得太流利,让面试官感觉自己是在背答案。要一遍思考一遍说。
展现自己在技术和项目上的思考,表现自己的工程能力,下面列出几点:
-
能考虑到代码的扩展性,有框架设计的意识;
-
有调优意识,能通过监控发现问题点,然后解决;
-
动手能力很强,肯干活,会的东西比较多,团队合作精神比较好;
-
有主见,能不断探索新的知识。
一定要主动:作为面试者,应该能够主动并且逻辑清晰的说出自己的项目中有哪些亮点,能够主动的把自己的闪光点在短短几十分钟的面试中都展现出来。
机器学习算法问题
这里给出了调研中,问到的频率最高的算法问题。
-
L1 L2 正则化的区别,为什么 L1 产生稀疏矩阵,L2 可以防止过拟合 (0.5);
-
梯度消失和梯度爆炸 (0.4);
-
LR 的数学原理 (0.4);
-
SVM 推导 (0.35);
-
SVM 核函数 (0.35);
-
算法评估指标 ROC曲线,AUC值 (0.3);
-
bagging 和 boosting 区别 (0.3);
-
RF、Adaboost、GBDT、XGBoost 的区别和联系 (0.3)。
大家可以看到,这些基础的细节问题还是很容易被问到的,具体到概念和公司,自己知道的,一定要保证可以准确的写出来,而不能只记住个大概,这样会显得非常的不专业。
总结:对每个算法,尽量能够做到可以手推其损失函数、清晰讲解如何求解损失函数,同时,了解该算法的应用场景和优缺点。并将应用场景类似的算法进行比较。还有一点需要注意的是,针对每个问题,要尽可能了解的深入,例如,L1,L2 正则化,除了以上的问题,还有 L1,L2 的先验分布是什么,正则化的参数选择问题等等。
数据结构问题
这里给出了调研中,问到的频率最高的代码问题。
-
快排 (0.4)
-
归并排序 (0.3)
-
10 万个数中找 TopK(0.3)
-
最长回文子串 (0.2)
-
反序字符串 (0.2)
-
链表反转 (0.2)
总结:《剑指 offer》基本是要过一遍的,面试中有很多同学指出很多是来自这本书的原题。另外,总结题目类型以及对应的解题方法也是很有必要的,题目场景多种多样,但其本质的问题总的来说只有那么几种。如果有余力,可以多多练习 LeetCode。建议大家刷题的时候,最好用 Java 或者 C++,很多面试官不太喜欢大家做题的时候使用 Python。
概率题
面试中考到的问题中,几乎 80% 的问题都是条件概率题,贝叶斯公式一定要牢记于心。因此,大家在准备的过程中,需要重点准备条件概率问题。下面是面经中出现频率最高的面试题,希望给大家的面试准备上提供一点线索。
一、随机数发生器 这类题目在解决的过程中要注意:最后产生的随机数中,可以存在没有用的随机数,但必须保证所有要用到的随机数产生的概率必须是相同的。
已知一随机发生器,产生 0 的概率是 p,产生 1 的概率是 1-p,现在要你构造一个发生器,使得它产生 0 和 1 的概率均为 1/2。
求解:让该随机数生成器生成两个数,那么序列是 00,01,10,11 概率分别为 pp,p(1-p),(1-p)p,(1-p)(1-p)。我们发现产生序列 01 以及 10 的概率是相等的,那么我们把 01 看作为 0,把 10 看作是 1,则他们产生的概论均为 p(1-p),其他情况舍弃不用,这样就得到了0和 1 均等生成的随机器了。
已知有个 rand7() 的函数,返回 1 到 7 随机自然数,怎样利用这个 rand7() 构造 rand10(),随机产生出 1 到 10 的自然数。
求解:如果能够得到一组等概率的数,不管是什么数,只要等概率而且个数大于 10,那么问题就可以解决了。事实上,解决方案是有无数种的,只要保证产生的结果映射到 1 到 10 的自然数后,是等概率的独立事件即可。例如, (rand7() - 1) * 7 + rand7(),可以等概率的生成 1 到 49,那么,只要把 11-49 去掉就可以了。不过这样的做法在实际使用过程中毕竟低效。因此可以去掉 41-49,然后在把 1-40 映射到 1-10 (每四个数映射为 1 个数),那么问题也就解决了。
二、掷筛子的期望 商家发明一种扔筛子游戏,顾客扔到多少点就得到多少钱,但扔筛子之前顾客需要付一定数量的钱 x,假设商家和顾客都足够聪明:
-
顾客付一次钱可以扔一次的情况下,顾客能接受的最大 x 是多少?
-
现在规则改为顾客付一次钱可以扔两次,顾客扔了第一次之后可以选择是否继续扔第二次,如果扔了第二次则以第二次的结果为准,如果没有扔第二次就以第一次的结果为准,这时顾客能接受的最大 x 为多少?
求解:题目本质上是问掷一次筛子的期望以及掷两次筛子的期望。
-
1/6(1+2+3+4+5+6)=3.5。
-
考虑顾客什么情况下会扔第二次,就是扔第二次得到钱变多的概率相对较大的时候,那么当顾客第一次扔到 1,2,3 的时候他会选择继续扔第二次,则这时候期望变为 1/6 (4+5+6) + 1/2 (1/6 (1+2+3+4+5+6)) = 4.25。
其他
-
为什么学算法
-
觉得自己是什么样的人
-
性格介绍
-
优缺点介绍
这些问题主要在于一方面尽量展示自己对该方向的热情,另一方面展示自己的学习能力、毅力等软实力。