我是如何拿到字节跳动AI Lab算法Offer的?

求职目标:NLP工程师

为什么想换工作?

毕业之后,除了技术相关书籍,我没读过太多其他类型的书,其中有一本内容短但是对我影响特别大的书——《谁动了我的奶酪》。出门问问是我毕业后的第一份工作,无论是工作内容还是团队氛围,我很满意在出门问问的工作,但是考虑到自己已经在出门问问工作了将近3年半,一直在从事人机对话NLU相关工作,我很难确定几年以后自己的能力和技术是否还有足够的竞争力?虽然继续在出门问问工作依然能够提升自己,但是我觉得如果换一个环境能够更大程度的提升自己,所以感觉是时候强迫自己去探索下一个“奶酪站”了。

面试情况:面试了平安寿险/爱奇艺/字节跳动/58/阿里小蜜/作业帮6家,拿到3个offer。

流水账:

  • 国庆节10月8日之后开始刷题&复习。

  • 10月25日进行第一次面试,面试了平安寿险和爱奇艺两家。上午面试平安寿险,平安寿险等了面试官40分钟,然后临时换了面试官,问了很多算法模型细节的问题,准备不充分,没通过。下午面试爱奇艺,聊了三轮技术面,让回去等通知,后来被告知这个岗位是9月份开放的,有候选人接受了offer,hc关闭了。

  • 10月29日去字节跳动面试,抱着积累经验的态度去的,两轮技术面,竟然通过了。

  • 11月03日再去字节跳动面试,进行第三轮技术面试,竟然通过了。11月03日上午还接到了一轮58电话面试,没提前预约,我还以为骚扰电话,囧。

  • 11月08日去58 AI Lab和作业帮进行面试,两家都通过了。后来作业帮和58等头条先出offer。

  • 11月18日收到字节跳动/58 AI Lab/作业帮三个口头offer。

  • 最终选择了字节跳动,11月19日出了书面offer。

  • (期间还接到2次阿里小蜜的电话面试,具体记不清哪天了。)

1. 编程题

感觉我自己刷题比较少,面试比较靠运气了。如果求稳,建议尽可能多刷,不要浪费面试机会。

leetcode刷了85道题:

主要是简单和中等级别的题目:

强烈推荐题库集合

详细的题目列表:

https://leetcode-cn.com/problems/add-two-numbers	两数相加
https://leetcode-cn.com/problems/median-of-two-sorted-arrays	寻找两个有序数组的中位数
https://leetcode-cn.com/problems/longest-palindromic-substring	最长回文子串
https://leetcode-cn.com/problems/reverse-integer	整数反转
https://leetcode-cn.com/problems/palindrome-number	回文数
https://leetcode-cn.com/problems/container-with-most-water	盛最多水的容器
https://leetcode-cn.com/problems/longest-common-prefix	最长公共前缀
https://leetcode-cn.com/problems/3sum	三数之和
https://leetcode-cn.com/problems/3sum-closest	最接近的三数之和
https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list	删除链表的倒数第N个节点
https://leetcode-cn.com/problems/valid-parentheses	有效的括号
https://leetcode-cn.com/problems/merge-two-sorted-lists	合并两个有序链表
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array	删除排序数组中的重复项
https://leetcode-cn.com/problems/implement-strstr	实现 strStr()
https://leetcode-cn.com/problems/search-in-rotated-sorted-array	搜索旋转排序数组
https://leetcode-cn.com/problems/permutations	全排列
https://leetcode-cn.com/problems/powx-n	Pow(x, n)
https://leetcode-cn.com/problems/maximum-subarray	最大子序和
https://leetcode-cn.com/problems/spiral-matrix	螺旋矩阵
https://leetcode-cn.com/problems/merge-intervals	合并区间
https://leetcode-cn.com/problems/spiral-matrix-ii	螺旋矩阵 II
https://leetcode-cn.com/problems/rotate-list	旋转链表
https://leetcode-cn.com/problems/unique-paths	不同路径
https://leetcode-cn.com/problems/climbing-stairs	爬楼梯
https://leetcode-cn.com/problems/edit-distance	编辑距离
https://leetcode-cn.com/problems/subsets	子集
https://leetcode-cn.com/problems/merge-sorted-array	合并两个有序数组
https://leetcode-cn.com/problems/gray-code	格雷编码
https://leetcode-cn.com/problems/binary-tree-inorder-traversal	二叉树的中序遍历
https://leetcode-cn.com/problems/maximum-depth-of-binary-tree	二叉树的最大深度
https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree	将有序数组转换为二叉搜索树
https://leetcode-cn.com/problems/pascals-triangle	杨辉三角
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock	买卖股票的最佳时机
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii	买卖股票的最佳时机 II
https://leetcode-cn.com/problems/word-ladder-ii	单词接龙 II
https://leetcode-cn.com/problems/single-number	只出现一次的数字
https://leetcode-cn.com/problems/word-break	单词拆分
https://leetcode-cn.com/problems/linked-list-cycle	环形链表
https://leetcode-cn.com/problems/linked-list-cycle-ii	环形链表 II
https://leetcode-cn.com/problems/binary-tree-postorder-traversal	二叉树的后序遍历
https://leetcode-cn.com/problems/sort-list	排序链表
https://leetcode-cn.com/problems/maximum-product-subarray	乘积最大子序列
https://leetcode-cn.com/problems/min-stack	最小栈
https://leetcode-cn.com/problems/intersection-of-two-linked-lists	相交链表
https://leetcode-cn.com/problems/majority-element	求众数
https://leetcode-cn.com/problems/word-frequency	统计词频
https://leetcode-cn.com/problems/valid-phone-numbers	有效电话号码
https://leetcode-cn.com/problems/transpose-file	转置文件
https://leetcode-cn.com/problems/tenth-line	第十行
https://leetcode-cn.com/problems/number-of-islands	岛屿数量
https://leetcode-cn.com/problems/reverse-linked-list	反转链表
https://leetcode-cn.com/problems/implement-trie-prefix-tree	实现 Trie (前缀树)
https://leetcode-cn.com/problems/contains-duplicate	存在重复元素
https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst	二叉搜索树中第K小的元素
https://leetcode-cn.com/problems/power-of-two	2的幂
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree	二叉搜索树的最近公共祖先
https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree	二叉树的最近公共祖先
https://leetcode-cn.com/problems/delete-node-in-a-linked-list	删除链表中的节点
https://leetcode-cn.com/problems/product-of-array-except-self	除自身以外数组的乘积
https://leetcode-cn.com/problems/nim-game	Nim 游戏
https://leetcode-cn.com/problems/additive-number	累加数
https://leetcode-cn.com/problems/reverse-string	反转字符串
https://leetcode-cn.com/problems/reverse-vowels-of-a-string	反转字符串中的元音字母
https://leetcode-cn.com/problems/intersection-of-two-arrays	两个数组的交集
https://leetcode-cn.com/problems/intersection-of-two-arrays-ii	两个数组的交集 II
https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix	有序矩阵中第K小的元素
https://leetcode-cn.com/problems/arithmetic-slices	等差数列划分
https://leetcode-cn.com/problems/partition-equal-subset-sum	分割等和子集
https://leetcode-cn.com/problems/repeated-substring-pattern	重复的子字符串
https://leetcode-cn.com/problems/coin-change-2	零钱兑换 II
https://leetcode-cn.com/problems/reverse-words-in-a-string-iii	反转字符串中的单词 III
https://leetcode-cn.com/problems/merge-two-binary-trees	合并二叉树
https://leetcode-cn.com/problems/maximum-product-of-three-numbers	三个数的最大乘积
https://leetcode-cn.com/problems/palindromic-substrings	回文子串
https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal	N叉树的前序遍历
https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal	N叉树的后序遍历
https://leetcode-cn.com/problems/goat-latin	山羊拉丁文
https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence	将数组拆分成斐波那契序列
https://leetcode-cn.com/problems/fruit-into-baskets	水果成篮
https://leetcode-cn.com/problems/smallest-range-i	最小差值 I
https://leetcode-cn.com/problems/smallest-range-ii	最小差值 II
https://leetcode-cn.com/problems/smallest-string-starting-from-leaf	从叶结点开始的最小字符串
https://leetcode-cn.com/problems/available-captures-for-rook	车的可用捕获量
https://leetcode-cn.com/problems/maximum-subarray-sum-with-one-deletion	删除一次得到子数组最大和
https://leetcode-cn.com/problems/day-of-the-week	一周中的第几天

2. 面试记录

这次求职面试了平安寿险,爱奇艺,字节跳动 AI Lab,58 AI Lab,作业帮和阿里小蜜。

最后拿到了字节跳动AI Lab/58 AI Lab和作业帮三家的Offer。

最终选择了字节跳动AI Lab。

20191025 平安寿险面试(AI算法工程师,1轮)

1. CNN网络结构

2. dropout细节(https://blog.csdn.net/program_developer/article/details/80737724)
 - 训练时候dropout之后,需要进行rescale,x = x/(1-p)
 - 或者测试的时候,权重W乘以p,即pW

3. 梯度消失原因?(https://blog.csdn.net/qq_25737169/article/details/78847691)

4. LSTM为什么能缓解梯度消失

5. 解决梯度消失的方法

6. 逻辑回归是线性?还是非线形?(https://www.zhihu.com/question/30726036)

7. cross entropy公式

8. 10*64的输入,mutil-head attention,大概多少参数量?【回答不好】

9. 项目相关

10. 详细介绍最大熵模型 
 - (https://blog.csdn.net/golden1314521/article/details/45576089)
 - (http://crad.ict.ac.cn/CN/abstract/abstract774.shtml)

20191025 爱奇艺面试(NLP工程师,3轮)

共三轮,不是按难度递增,三轮难度差不多,第一轮问的更细致一些,应该是和面试官有关。

第一轮大概50分钟,第二轮大概35分钟,第三轮大概40分钟。

开始先自我介绍。

然后面试官问项目,结合项目考察模型和算法,聊项目偏多,大部分都在说怎么做的,感觉模型和算法考察的不是很多。

以下问题基本都是结合简历中的项目问的:

1. CRF比HMM好在哪?为什么?

HMM是一种有向概率图模型,有三个主要参数,A,B和兀,有两个假设,观测独立性假设,齐次马尔可夫假设,这两个假设就限制了HMM无法根据全局信息去预测隐藏状态;

CRF是一种无向概率图模型,属于判别式模型,通过定义特征函数,学习每个特征函数的权重,这些权重就是模型需要学习的参数。

HMM可以看作是CRF的特殊情况,也可以理解为任意HMM都可以表示为CRF模型。比如转移概率矩阵中的Aij,可以看作是特征函数t-1时刻状态为i,t时刻状态为j的权重,发射概率矩阵中的Bkj,可以看作是特征函数t时刻状态为j且观测值为k的权重。

但是CRF能够定义更丰富的特征函数,比如存在多维特征的时候,可以很方便的将当前观测值的上下文以及属性值都引入到模型。如果是HMM的,可能需要层级HMM或者高阶HMM。

2. 如何做分词?用HMM怎么做分词?

3. BERT fine-tuning是如何融入知识的?

4. 介绍Attention/Transformer/BERT之间的关系,详细介绍Self-Attention部分;

5. 简单画出Bi-LSTM CRF的结构图,CRF在其中的作用是什么?


6. 在使用Bi-LSTM CRF的过程中都进行了哪些改进和优化?

7. 人机对话系统的整体流程是什么?

8.了解DM部分的作用吗?

9. NLU中的难点是什么,如何解决的?  

10. BERT/GPT/Elmo的区别?BERT的优点在哪?

ELMo主要是用来做特征抽取,应用到下游任务的时候,模型参数不更新,架构上是利用两个双向LSTM,一个对输入句子进行正向编码,一个对输入句子进行反向编码,然后将两个编码连接在一起,作为下游任务的输入。

GPT可以用来微调,应用到下游任务的时候,可以根据具体任务,更新模型参数,架构上是堆叠的单向Transformer,可以看作是Encoder-Decoder架构的Encoder部分,但是预训练的时候为了避免self-attention看到整句的信息,借鉴了Decoder的Mask方法,就是训练到时刻t的时候,将t+1以及之后的信息屏蔽掉,这也就是单向的原因。

ELMo虽然是双向的,但是无法将上下文编码在同一个向量里,比如

“这个小狗无法跳上台阶因为它太累了”或者“这个小狗无法跳上台阶因为它太高了”

正向编码无法得知“它”是谁,因为看不到后边的“累”或者“高”

反向编码无法得知“它”是谁,因为看不到前边的“小狗”或者“台阶”

GPT中的Self-Attention本身是可以同时利用“它”前边和后边的信息,但是为了防止看到未来的信息,引入了Mask机制,所以其实看不到后边的信息。

GPT采用的是普通的语言模型的策略,也就是根据历史信息预测当前信息。BERT为了解决GPT中看不到未来信息,只能利用一个方向的信息的问题,引入了Masked LM。类似完形填空,训练的时候,遮蔽一些词,然后让BERT预测这些词,目标函数就是使得预测的词尽可能正确。

强迫模型在编码当前时刻的时候不能太依赖于当前的词,而要考虑它的上下文,甚至更加上下文进行”纠错”。

OpenAI GPT使用的是BooksCorpus语料,总的词数800M;而BERT还增加了wiki语料,其词数是2,500M。所以BERT训练数据的总词数是3,300M。

11. BatchNorm和LayerNorm
- (https://zhuanlan.zhihu.com/p/68651018)

20191031 字节跳动面试(NLP工程师,3轮)

介绍CNN

介绍CRF

介绍HMM

20191102 58面试(NLP工程师,1轮)

电话面试

1. CNN参数量估计

2. Bi-LSTM参数量估计

3. 编程题:如何找到相交链表第一个交点

4. 编程题:如何层次遍历二叉树

5. 介绍BERT的预训练过程并尽可能展开

6. SVM和LR哪个对异常点更敏感

7. Tensorflow的Name Scope和Variable Scope

8. Tensorflow如何复制一个Tensor

9. Python多线程/多进程/GIL

10. Python生成器

11. Bi-LSTM CRF的损失函数是什么,包含哪些部分,每部分如何计算?

20191107 阿里小蜜(算法工程师,电话2轮)

1. 长度n的无序数组,从中找第k大的数;

2. 如何跟一个没有机器学习背景的人解释什么是CRF;

隔了一周之后又接到了第二轮电话面试,问了些KBQA相关的问题,和我之前的工作经验不匹配。虽然自我感觉全程聊的挺好,但是最终还是没过。还需要努力提升自己!

20191108 58面试(算法工程师,现场3轮)


1. 知不知道满二叉树和完全二叉树的概念,深度为n的完全二叉树,节点个数的范围是多少?

2. 层次遍历二叉树,奇数层从左向右遍历,偶数层从右向左遍历

3. 给定n个数,可以组成多少种二叉排序树

4. Bi-LSTM CRF中的CRF怎么计算概率,写公式

5. Bi-LSTM如何防止过拟合

6. Batch Norm/Dropout

7. 正则化会怎样影响loss曲线?为什么?从公式角度解释下。

20191108 作业帮面试(NLP工程师,现场3轮)

一面是算法三连:

1. 给定一个矩阵和点A,从A点开始顺时针打印点A右下角的矩阵

2. 给定一个数组,找到这个数组中,最小和连续子数组,并找到起始位置和终止位置

3. 非递归中序遍历二叉树(这题离最优方案差一点点)

二面也是概率&思路题:

4. 有一批植物的数据,每株植物有n个维度数据,n个工作人员将这批数据录入系统时,第m个员工录入信息时不认真,录入个别数据时填写了错误的数据,填高了或者填低了,比例不高,约1/1000。设计一种方案,能够尽可能找出录入错误的数据。

5. 五枚硬币,1枚(正面花,反面字),2枚(正面花,反面花),2枚(正面字,反面字),现在随机挑一枚硬币放在桌上,正面是花,问:反面是花的概率?

三面是个大数据的题:

6. 100亿行的日志文件,一行一条Query,1G内存,找到频率最高的1000个Query

其他算法和模型:

7. LSTM一个Cell的结构图/公式

8. 介绍LSTM,为什么用双向LSTM

9. Bi-LSTM CRF中CRF的作用是什么

10. 使用BERT的改进空间在哪?

11. 用BERT做NLU,有哪些亮点的尝试?
posted @ 2019-11-25 15:33  ZH奶酪  阅读(9131)  评论(5编辑  收藏  举报