面试算法岗总结(持续更新.....)

寒假以来一直在投一些算法实习岗位,既然是算法,面大厂的话肯定少不了“手撕代码”的问题,怕自己忘掉,因此做已记录。目标是面试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大数字

       215. 数组中的第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、两道算法题       

                3. 无重复字符的最长子串

                33. 搜索旋转排序数组

        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、反问

未完...... 持续更新

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值