兵荒马乱的实习春招终于结束了,写点面经回馈社会,再次感叹刷题要趁早啊
个人背景
笔者是南京某985计算机专业本科,平时学的课程、打的比赛、做的项目大都沾点AI,实习就很头铁地全投了算法岗,csdn主页上就有我的个人简历小站。
百度
手撕代码
百度推荐:
给一个list里面存着不同面额的硬币,每次只能从左拿或者从右拿1个,最多拿k次,求能拿到的最大值
def get_largest(coin,k):
"""
每次从最左最右拿硬币,拿k次,取到最大值
return int
"""
res=0
length=len(coin)
if (length == k):
# 拿的长度与硬币序列长度相同,直接返回所有数的和
for i in coin:
res+=i
return res
# 维护左右两个指针,每次贪心地拿一个
coin_in_hand=0#手里拿了几个硬币
L=0#左指针
R=length-1#右指针
while(coin_in_hand<k):
if coin[L]>coin[R]:
res+=coin[L]
coin_in_hand+=1
L+=1
else:
res+=coin[R]
coin_in_hand+=1
R-=1
return res
ans=get_largest([5,4,2,1,6],3)
print(ans)
写完代码之后允许调试,在自己编译器写的,也过了面试官法眼。
百度地图一直在问python API相关问题,包括
- 以字典序排序一个list,如
['a','b','cd','fg']
,我一开始答了python中字符串的比较都是按字典序的,所以可以用快排,结果他问我,你是不知道有api直接可以解决吗。。。就顺便答了sort()和sorted()区别 - Top-k问题,
一个大小为10万的数组 找第1万大的数,有什么算法?
, 如果用快排解决时间复杂度是多少,我算的是O(NlogN),但面试官让我自己再算算…结束了才想明白是这样:
比如快排增序,每一轮就是选一个数x,将比它大的数放右边,比它小的数放左边,然后相当于我们就用n的时间知道了x是第几大的数,比如是第k2大,如果k小于k2,则仅需对左半序列做快排算法,k大于k2则是右半序列,这里就比所有数的排序少了一半工作量,第2轮及之后同理。根据快排的复杂度计算,复杂度为n+1/2n+1/4n…也就是o(n)
答了快排之后又问我还有什么算法,就是最小堆(python内建的堆就是最小堆)
用前k个数建一个小根堆,然后后(n-k)个数依次入堆,每入队一个数弹出一次堆顶,复杂度o(nlogk)。但优点是可以得到排序后的前K大数
- 调换单项链表中A节点和B节点位置,这题我写了四行,用一个temp指针抓着其中某一个换,觉得可以跑。但面试官很怀疑地问“你这是全部代码还是示例代码?”…
- 某数是否在二叉树内
- 某节点是否是AB的公共父节点
【最后当然是挂了,很多时候不和这位面试官在一个频道上,晕了。
简历问答
- 介绍一下BERT
- 介绍一下Attention
- 为什么Attention可以Work
- Attention里有jump link,你了解吗,介绍一下ResNET
- Attention里的layer norm有什么用
- 你怎么处理梯度消失和梯度爆炸
- 你简历上这个比赛,承担了什么工作?用了什么trick拿到这个成绩
- 讲讲你负责的这个项目
- 你觉得这个项目有什么可以提升的空间?
- 我建议你们这个项目可以xxxx…(百度推荐的小姐姐人还是非常温柔的,而且idea确实很好)
滴滴橙心优选
推荐算法岗
手撕代码
自己编译器写,允许调试。
简历问答
- 介绍一下BERT
- 介绍一下梯度消失和梯度爆炸
- 介绍一下LSTM
- 介绍一下GRU
- GRU和LSTM有什么不同?
- 为什么LSTM可以work
最后问我能不能立刻到岗,感觉很缺人。
字节
字节AI LAB, CV算法岗
手撕代码
宇宙条的手撕代码是我所有面试中最难的。。。
第一题 大数乘法,一个非常长的字符串里面存着数字,实现两个大数乘法
第二题 很像 LeetCode 305岛屿数量,求二值图像里连通域的大小
简历问答
- 介绍一下FPN
- 介绍一下UNET,为啥Unet可以work
- 讲一下人脸识别的pipline
- 如何处理真实场景中人脸的旋转,侧脸等问题
- 介绍一下ResNet
- 介绍一下你简历上这个项目,突出算法深度
- 能不能做新的模式数据的Embedding
- 不如你设计一个端对端的新模型解决这个问题
智力题
- 一根绳子烧完是1小时,怎么取出来1小时15分钟
- 一个圆上任意三个点,得到锐角的概率(积分算)
阿里
阿里云算法岗
笔试
牛客,ACM模式,需要自己写输入输出。
第一题
内存限制是C++262144K其他语言524288K,时间C++为1秒,其他语言两秒。
你有一个0,1矩阵,做Q次操作,每次操作告诉你下标(i,j)把这个位置的0,1反转,就是0变1,1变0。最终要输出每次操作后矩阵中【每行连续1的个数】的最大值,共Q个值。这题我超时了…
跟同学交流后说可以用用线段树做。
第二题
给你一个完全二叉树,返回下面操作后该树的层次遍历
K=2后树变成
第二题没写完,打算用组到遍历的映射做,每组的第几个在遍历的什么位置是固定的,组内的顺序也不用真的换,只要能根据原顺序和k计算出这一组的第几个是什么数就行了。
手撕代码
阿里在白板面试后可以把代码历史发过来,很爽
- 第一题:实现函数my_get_oct(字符串s), 返回s中的偶数
def my_get_oct(s:str) -> str:
oct_nums = "02468"
res_str = ""
if len(s) == 0:
return ""
for i in s:
if i in oct_nums:
res_str += i
return res_str
- 第二题:search函数(字符串s,出现次数n),返回"出现了n次的字母在字符串中的下标‘’
判例
s = "xabccbacy"
search(s, 1) -> 0
search(s, 2) -> 1
search(s, 3) -> 3
search(s, 4) -> -1
代码
def search(s: str, n: int):
if len(s) == 0:
return -1
# 建立 字母:频率 字典
my_str_dic = dict()
for i in s:
if i not in my_str_dic:
my_str_dic[i] = 1
else:
my_str_dic[i] += 1
# 获得所有合格字母
res_al_set = set()
for keys in my_str_dic:
if my_str_dic[keys] == n:
res_al_set.add(keys)
if len(res_al_set) == 0:
return -1#没有合格字母
# 找到最左边的合格字母位置
pos = 0
for i in s:
if i in res_al_set:
return pos
pos+=1
其实Python3.6以后字典的键就是有序的了,写的时候是按键无序写的。
【这题其实有个trick,那就是字母表只有26个,所以开一些以’a’,'b’为键的字典其实是一个常数空间的事】
- 第三题:在电视机上画线,给你两个点位置和一个纯0矩阵,纯0矩阵是电视剧,把两个点所连的直线上所有数由0变成1,要求尽量简化,就是用梯度来递推
- 第四题:在电视机上画圆,同理用梯度递推
- 第五题:长度为n的数列,里面会随便填上0~n-1大小的数,每个数都可能重复任意次,找出重复的数。要求线性时间常数额外空间。
for i in range(len(array)):
ex = 0
while(array[i] != i):
array[array[i]], array[i]= array[i], array[array[i]]
ex += 1
if ex == len(array):
ex=0
break
for i in range(len(array)):
if i != array[i]:
print(array[i])
【这题的trick是通过交换的方法,把数和下标相等,且每次交换至少有一个数会到“对的”位置】
简历问答
- 学过哪些课,最喜欢的课是什么(回答了机器学习,就让我做梯度递推的代码了)
- 打算做什么方向,为什么要做NLP,希望从实习中获得什么
阿里的时间线还漫长的,3.09内推,两个月之后发意向书。
总结与反思
笔者从三月开始投递简历,其实已经很晚了,面完最后一家的时候其他同学已经开始秋招了。。
总的来说简历上的项目一定要对答如流,用到了什么模型什么trick为啥可以work有没有改进空间几乎是必答题。
另外可以从二三线公司小面起查漏补缺,笔者上来就投了big name反而因为准备不充分浪费了很多机会。
手撕代码部分矩阵,链表和树是最常用到的,难度基本是medium,提前两个月左右刷题就不用怕。