寒假以来一直在投一些算法实习岗位,既然是算法,面大厂的话肯定少不了“手撕代码”的问题,怕自己忘掉,因此做已记录。目标是面试8个公司,现在已经面试了有三星、华为、快手、深信服、字节跳动,其中三星没有考代码题目。
三星
比较水,没有考代码问题。
华为
比较简单,就考察了一个斐波那契数列的问题。面试也是比较简单只考了一个算法题。
class Solution:
def fib(self, n: int) -> int:
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
快手
目前已经面了两面了,结果还不清楚,两面总共考了4到代码题,只记得三道了
1、读取一个文件的图像,然后将结果作为数组输出。
import cv2
img_BGR = cv2.imread(path)
img = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2RGB)
#返回的结果是numpy类型,转为list就可以了
print(img.tolist())
2、如何判断两个二叉树完全一致,节点的value也是一样的。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
if not p and not q:
return True
if not p or not q:
return False
#递归
return p.val==q.val and self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)
#迭代
res_p,res_q = [],[]
def helper(root,res):
queue = collections.deque()
queue.append(root)
while queue:
item = queue.popleft()
if item:
res.append(item.val)
queue.append(item.left)
queue.append(item.right)
else:
res.append('null')
helper(p,res_p)
helper(q,res_q)
return res_p==res_q
3、查找一个字符串中无重复字符的最长子串长度。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:
return 0
res = 1
for i in range(len(s)):
tmp = set()
tmp.add(s[i])
for j in range(i+1,len(s)):
if s[j] not in tmp:
tmp.add(s[j])
else:
break
res = max(res,len(tmp))
return res
k = -1
res = 0
c_dict = {}
for i, c in enumerate(s):
#如果出现重复的元素且下标是大于k
#更新k,更新c的下标
if c in c_dict and c_dict[c] > k:
k = c_dict[c]
c_dict[c] = i
#如果没有出现重复的元素,直接给字典添加并且计算更新res的长度
else:
c_dict[c] = i
res = max(res, i-k)
return res
深信服
-
讲讲SVM和逻辑回归的区别以及底层的原理
-
讲讲RNN和LSTM的原理和优缺点
-
讲讲你用过的损失函数,优化函数的作用
-
讲讲你用过的优化器,SGD和Adam。两个的底层原理是什么?
-
CNN为啥比RNN快
-
CNN的细节实现什么
-
讲讲你的项目,从背景、应用来说,具体将的话从输入、输出和目标函数来讲。不应该一开始就讲细节
-
聊聊Python:一行代码交换两个变量,生成器和yield的原理
-
L1正则化和L2正则化的区别是啥?为啥L2能好一些,对于L1有哪些提升?
-
二面到此结束、觉得自己菜的扣脚、流下了基础薄弱的眼泪;总结下来就是底层、底层的问题、基础太差了!!!好多问题回答的含糊不清;
字节跳动
一面:讲项目或者论文,我讲了一个我正在做的论文,问的比较详细,大概聊了30多分钟吧,然后写代码。比较简单:无重复字符的最长子串。
我面试的时候写的方法3,面试官让我下去在想想如何优化,优化版就是前两个。第二个利用双指针+hash表比较有意思,能加快效率。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
#滑动窗口
#维护一个窗口,必须保证每种元素只出现了一次
res = 0
win = []
for char in s:
#如果字符不在窗口,那就他添加字符
if char not in win:
win.append(char)
#如果字符在窗口里,那就截取第一次出现字符之后作为新的窗口
#并将当前的元素添加进去
else:
win = win[win.index(char)+1:]
win.append(char)
#更新窗口的大小
res = max(res,len(win))
return res
#hash+双指针
dic = defaultdict(int)
res = 0
index = -1
#维护一个字典,key是字符,value是下标
for j in range(len(s)):
#如果当前字符在字典中的话,那就更新下标,将左指针向右移动
if s[j] in dic:
index =max(dic[s[j]],index)
#更新字典
dic[s[j]] = j
#更新子字符串的长度
res = max(res,j-index)
return res
#滑动窗口的模板
res = 0
left,right = 0,0
size = len(s)
counter = collections.Counter()
while right<size:
counter[s[right]]+=1
#当出现频次最高的字符频次大于1的时候,那就更新字典、移动左指针
while counter.most_common(1)[0][1]>1:
counter[s[left]]-=1
left+=1
res = max(res,right-left+1)
right+=1
return res
美团
一面:
- 项目
- 决策树
- 朴素贝叶斯
- 集成学习(不会,没有复习到)
- Stacking
- Boost
- XGboost
- 代码
- 给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
- 你在爬楼梯,需要n步才能爬到楼顶,每次只能爬1步或者n步。有多少种方法可以爬到楼顶?
代码1(没写出来)
动态转移方程
def minCoin(str1, str2, ic, dc, rc):
if str1 == None or str2 == None:
return 0
row = len(str1) + 1
col = len(str2) + 1
#生成矩阵row*col
#加1的原因是因为还有空字符串
dp = [[0 for i in range(col)] for j in range(row)]
#更新第一列,将str1变成空字符串(str2)的代价,删除
for i in range(row):
dp[i][0] = i * dc
#更新第一列,将空字符串(str1)变成str的代价,插入
for j in range(col):
dp[0][j] = j * ic
for i in range(1, row):
for j in range(1, col):
#如果上一个位置相同,dp[i][j]就不用更新
#如果上一个位置不同,有三种情况
#case1:直接替换
#case2:s1[i]->s2[j-1],然后执行插入操作
#case3:对s执行删除操作s1[i-1]->s2[j]
if str1[i-1] == str2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j-1] + rc,dp[i][j-1] + ic,dp[i-1][j] + dc)
return dp[-1][-1]
s1 = 'abc'
s2 = 'adc'
ic = 5
dc = 3
rc = 100
res = minCoin(s1,s2,ic,dc,rc)
print(res)
代码2(比较简单,写出来了)
#动态规划转移方程
#f(n) = f(n-1)+f(n-2)
#最后一步,爬n-1的方法和n-2的方法之和
def question(n):
n = int(input())
if n==1 or n==0:
return 1
dp = [0]*(n+1)
dp[1] = 1
dp[2] = 2
for i in range(3,n+1):
dp[i] = dp[i-1]+dp[i-2]
return dp[-1]
商汤科技
1、为啥多卡训练的时候第一张卡的显存占的多?
2、训练开始的时候学习率无法下降,应该怎么做?
3、如果loss出现NAN怎么去排查问题?
4、BN的原理是什么?
5、faster r-cnn和yolo v3的区别以及优缺点在哪?
招商银行
1、堆和栈的区别
- 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树
- 堆分为两种情况,有最大堆和最小堆。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
- 栈是一个先进后出的一个数据结构形式
- 栈是限定仅在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。栈的特殊之处在于它限制了这个线性表的插入和删除位置,它始终只在栈顶进行。
图1是大顶堆、图2是小顶堆
2、如何进行数据清洗
纠正错误、删除重复项、统一规格、修正逻辑、转换构造、数据压缩、补足残缺/空值、丢弃数据/变量。
- 纠正错位
- 数据类型错位、编码错位
- 删除重复项
- 排序和合并
- 统一规格
- 类型、单位、格式
- 修正逻辑
- 在多源的环境下,很可能存在数据异常或冲突的问题,出现矛盾的记录
- 转换构造
- 数据离散化、数据标准化
- 数据压缩
- 数据压缩是指在保持原有数据集的完整性和准确性,不丢失有用信息的前提下,按照一定的算法和方式对数据进行重新组织的一种技术方法。
- 补足残缺/空值
- 补全缺失值
- 丢弃数据/变量
- 整条删除、变量删除
3、特征选择的方法
当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征:
- 特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
- 特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,本文介绍的其他方法均从相关性考虑
根据特征选择的形式又可以将特征选择方法分为3种:
- 过滤法
- 根据发散性或者相关性对各个特征进行评分,进行特征那个选择
- 方差选择法
- 计算每个特征的方差,然后根据阈值,选择方法大于阈值的特征
-
from sklearn.datasets import load_iris from sklearn.feature_selection import VarianceThreshold from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #导入IRIS数据集 iris = load_iris() print(iris.data.shape) res = VarianceThreshold(threshold=3).fit_transform(iris.data) print(res.shape) #(150, 4) #(150, 1) #经过特征筛选之后就剩下一个特征了
- 相关系数法
- 使用相关系数法,计算每个特征对目标值的相关系数以及相关系数的P值。
-
from sklearn.datasets import load_iris from sklearn.feature_selection import VarianceThreshold from sklearn.feature_selection import SelectKBest,chi2 from scipy.stats import pearsonr from numpy import vstack, array, nan #导入IRIS数据集 iris = load_iris() # print(iris.data.shape) # res = VarianceThreshold(threshold=3).fit_transform(iris.data) # print(res.shape) print(iris.data.shape) res = SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target) print(res.shape) #(150, 4) #(150, 2) #选择两个相关系数比较大的特征
- 方差选择法
- 根据发散性或者相关性对各个特征进行评分,进行特征那个选择
- 包装法
- 根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征
- 嵌入法
- 先使用机器学习的算法进行训练,得到各个特征的权值系数,根据系数从大到小进行特征选择,类似于过滤法
4、决策树和随机森林
决策树既可以进行分类任务也可以进行回归任务、主要有ID3、C4.5、CART(既能做分类也能做回归)
随机森林是属于bagging集成学习的算法,通过组合若干个弱分类器,使得模型具有较高的精确度和泛化性能。将使用CART决策树作为弱学习器的bagging方法称之为随机森林。
5、第K大数字
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
# if not nums or k<1 or k>len(nums):
# return 0
# nums.sort(reverse=True)
# return nums[k-1]
# for i in range(len(nums)):
# if i+1==k:
# return nums[i]
import heapq
nums = [-num for num in nums]
heapq.heapify(nums)
while k-1:
heapq.heappop(nums)
k-=1
return -heapq.heappop(nums)
京东(提前批)
基本顺序是上来就做题,做完题聊项目,聊完项目概率题,最后反问环节,结束面试。
1、两道算法题
2、讲项目
数据集的描述
模型的输入以及输出
该算法要解决什么问题
模型的梳理以及训练的情况
创新点是什么
3、概率题目
有m个球,要扔到n个桶子里。其中每个球都是互相独立地扔。问最后平均有几个桶子是无球的?
先计算每次扔球的时候空桶的概率,然后扔完m个球的概率,最终得到空桶的概率,然后乘以n个桶,就是最终平均有几个桶是空的了。
4、讲讲GCN的输入和输入以及GCN的公式
5、时长
100min
6、不足
项目梳理的不太清楚,讲的不是很好。33个题在用二分法的时候边界没有考虑好。
百度
1、代码
树的后续遍历+归并排序
2、机器学习的算法SVM介绍
3、集成学习之随机森林和XGBT的区别,适用场景,两个算法的偏差低还是方差低
4、如果数据不均衡的话应该怎么办?如何考虑偏差和方差的关系
5、机器学习中如何过自动化的特征组合和特征选择?
6、了解视觉领域中的图像增强技术吗?
Mixup,Cutout,CutMix,这几个的底层的区别是什么?分别适应什么场景
7、在视觉中对图像进行翻转和裁剪,尤其裁剪可能会让图像中某些目标缺失,如何解决图像增强中这个问题
8、反问
未完...... 持续更新