【快手推荐算法工程师面经】怀有残念的凉经
快手的面试要追溯到9月2号了,上午10点开始连着的两场面试,自认为是秋招以来面过的最糟糕的一次。
虽然状态已经凉了,但自己从这次面试中学到了很多东西,写下这篇面经以鞭策自己,也希望能帮助到更多的朋友。
一面
一面面试官是位有点儿小帅的男性,酷酷的不苟言笑的样子。
在问完实习项目后先撕了代码,用栈实现队列。其实有在leetcode刷过这题,但只后悔当时刷得不认真,没有细究其中的细节,这里踩了一个坑。面试官显然不满足于我最原始的两个栈的方法,对时间复杂度提出了更高的要求,在面试官的提醒之下才写出了最优的算法(大概花费了几分钟的时间)。
之后的一面完全是围绕着机器学习算法展开的,对XGBoost和随机森林进行了深挖。
其实很多问题都比较常规,我这里贴几个我回答的不好的问题:
XGBoost 的特征重要性是如何得到的?
我说了根据每个分裂点的特征加权求和的方法,不过说得有一些问题。
这里面试官有在尝试引导我,问了我 XGBoost 是如何分裂的,于是我又说了依据信息增益,遍历特征,遍历特征分裂点,以 exact greedy 和分位数两种方法进行查找。
我一直以为这里的特征重要性的权重是依据特征离根节点的远近来计算的,后来一番探讨之后我自己意识到这种说法是有问题的。面试官主动告诉我特征的权重就是信息的增益。面试官有问我实习中随机森林和 lightgbm 的一些参数,我凭着记忆如实说了。这里就引出了第二个问题。我说随机森林的每棵基决策树都是不剪枝的,通过取均值而达到避免过拟合。而面试官提出随机森林的基决策树也是需要剪枝的,于是面试官让我分析一下到底随机森林可不可以剪枝。
从误差上来看,剪枝的模型偏差会大一些,而方差会更小。不剪枝的模型偏差小,方差大。
然而随机森林的 Bagging 思想本来就是靠取均值来达到降低方差的效果,因此不剪枝的模型方差也未必会很大。反倒我觉得剪枝了的模型会有欠拟合的风险,因为每棵决策树都不一定能拟合得很好。
至于说每棵决策树都拟合得恰到好处的随机森林与每棵树都过拟合的随机森林,这两个究竟孰优孰劣呢?
面完一面还是有点儿小忐忑的,毕竟最基本的机器学习算法回答得不是很好,感觉有点儿小失落和懊悔。
二面
二面面试官是位女性,仍旧酷酷的,一上来先为自己迟到了十几分钟道了歉,这点让我颇为感动。秋招以来迟到的面试官不下六七位,放鸽子的还有三四次,少有面试官主动道歉的。
闲话少叙,先上面经。
还是聊实习项目,面试官对我的实习一些做得不好的地方提出了一丢丢改进的意见。
- XGBoost,又是连珠炮式非常细节的提问。
面试官要求我用纸笔手推 XGBoost 给她看,我虽然看过论文,也自己尝试推过,然而秋招还是第一次被要求手写 XGBoost,心里有点儿紧张,一下子连泰勒展开都有点儿忘了(实在惭愧)。不过最后还是把公式写了个差不多,其中细节难免会有错误。面试结束后又去复习了一下论文,其中关于求和的各种记号还蛮复杂的。
- 聊到线性模型,面试官让我说一下我实习项目中怎么做特征工程的。我说我依据分位数对特征进行离散化分箱,然后尝试对部分特征进行交叉组合来解决特征与label非线性的关系,不过效果仍然比不上树模型。这里面试官好像不是很满意我的回答,应该是有更优的特征工程方法?
- 之后有一道编程题,找出字符串中最长的不含重复字符的子串长度,用双指针轻松解决。
然而这时发生了一个小插曲,在读题过程中我低头用纸笔写了个示例,自己模拟了一下双指针的逻辑。这时面试官喝问我低头做什么,我赶紧把纸上的草稿举起来给面试官看,证明我没有作弊。从这时开始面试官表情开始转阴,态度急转直下,严厉地要求我在屏幕上打草稿(我这种痛恨作弊的人居然被怀疑作弊,我委屈得不得了)。
我赶紧把电脑屏幕翻折下来,让摄像头拍到我的桌面,以自证桌面上并没有可以作弊的工具。(因为在家,所以从来都穿着睡裤面试的。后来发现翻折笔记本屏幕的时候是可以拍到大腿位置的,现在想想巨尴尬…)
调试过程中出现了一点小问题,漏写了右指针右移的操作,我尝试着用打印的方式来 debug。面试官面无表情地要求我先检查好代码再调试。
我自知过多解释没有用,于是还是很快把代码改好了,不过面试的不愉快并没有到此为止。
聊到推荐系统,我说了 FM 和 FFM,面试官问我 FFM 的第一个 F 代表什么,我回答说 Field。面试官让我解释一下为什么要用 FFM。
我解释说这样可以针对每个特征域分别做 Embedding,更精细化。但是 FFM 的时间复杂度比较高,不能像 FM 那样优化到 。面试官不太满意,让我继续说。
我一下子不知道怎么说了(难道不是这个原因吗?)我灵机一动,说 FFM 有点儿像 attention 相比于传统的 seq2seq 模型,是更 flexible,更有针对性的一种模型。
面试官:“那你说一下 attention。”
我:“好,那我就以 self-attention 为例说好了。”
面试官:“行,那你说一下 transformer 吧”
我(满脸黑线):“好,transformer balabala……(略去一百字)” 其中我说到输入是 token 的embedding,话音未落…
面试官:“那你说一下 Word2Vec 吧”
我(脸更黑了,您到底想让我说什么啊?):“没问题。”
于是我讲了 CBOW 和 Skip-gram 两个模型,讲了这两个模型分别是为了预测中心词和 context,词向量是模型的副产物。我说了 CBOW 是如何计算 embedding的,就是两个矩阵来回乘,input 到 hidden layer 其实就是一个 one-hot 向量与矩阵的相乘,本质上也是取矩阵的其中一行;而 hidden layer 取均值之后再做一个映射,乘上另一个矩阵得到输出,输出做 softmax 之后计算对数损失,以此来更新网络中的参数。
这里面试官提醒我,说我说得不对。
我实在没想到哪里说得不对,于是重新又解释了一下。面试官表示还是不对。
(面试结束后我也看了《word2vec Parameter Learning Explained》这篇论文,仍然觉得自己说得好像没什么问题。上面这段 Word2vec 的回答我基本上按照原话进行了精简,可以麻烦大家指正一下吗,不胜感激!)
在反问环节,我第一个问题问的就是“您觉得 word2vec 我哪里说得不对呢?”
面试官有点儿不耐烦:“你自己回去看论文吧。”
我没有咄咄逼人的意思,只是想知道自己的问题所在,我继续客气地追问:“行,但能不能麻烦您指明大概的方向呢,比如说哪个知识点说得不对?”
面试官有点儿被我问得崩溃了:“你自己看论文就知道了。”
我趁着回答的空隙抖擞了一下精神,整了整衣领,不经意间感受到了后背上的汗珠。当时脑袋如一团乱麻,沉浸在糟糕的面试经历中难以自拔。
此时我的心态开始默默地发生着变化,我已然预料到了面试的结果。
我开始尝试着让自己冷静,接受当前发生的一切,尽量保持着自信地问完了我其余的问题,并礼貌地对面试官表达了感谢。
写这么多不是为了抱怨什么,更不是要所谓地“挂”这位面试官。客观说,这不是一场愉快且平等的面试。当天面试结束的若干个小时内心态一直没能很好地平复,对面试官心有芥蒂,对自己也产生了自我怀疑。尤其对于面试官不留情面的作弊指责,我的委屈在心头萦绕。
然而佛系的我还是很快调整好了心态,一场面试而已,不是什么大不了的事情。正如 word2vec 一样,我们在每一场面试过程中学习积累到的经验,才是更宝贵的副产物。
再一次,文中我有疑惑的地方进行了加粗处理,希望大家不吝赐教,万分感谢!(拱手)
#面经##快手##算法工程师##校招#