面经

1. 美团

1.1 笔试 3.19

5道编程题,两个小时
第一道:打银花,简单,两组数分别排序后输出最大的三个数;
第二道:找出最长上升子序列,可以删除一个数,求删除的最长序列:
利用双指针i, j,令k记录当前可以删除数目,当k为0时,记录当前数组长度,之后i指针向前移动找到离他最近的不符合上升序列的数,j跳过该数,继续遍历:

i, j = 0, 0
k = 0
while i<=j and j0:
        k -= 1
        j += 1
    else:
        maxlen = max(maxlen, j-i)
        while i<=j and vec[i]

第三题:dp问题,但是没有完整思路
一共有n个任务待完成,每个任务有k个子任务,第i个子任务需要花ti时间;
每个任务不能重复完成
完成一个子任务得p分,k个子任务都完成得pk+q分
现在共有m的时间,求最大得分
dp, 对时间排序,看成nxk的二维矩阵,最后的结果肯定是完成i行,完成j列,加上j+1列的一部分

第四题:跑步:图+最短路径
晨晨爱跑步,这天他准备跑k米, 城市可以看成n个点,m条无向边,每条边长度固定。
要求去往一个目的地一定要走最短路,求正好跑k米能走到的目的地的个数,目的地可是是点和边。
总结:开始太慌,没有很好分析题,最短路径直接就用了广度遍历,但对于有权边,应该用dirichlet方法。

第五题:求序列最长不下降子序列,序列有0,1组成,可以对序列进行更改
这道题纯属代码习惯和粗心大意,面壁······

def query(s:str, n: int):
    dp = [[0, 0] for i in range(n+1)]
    for i in range(n):
        if s[i]=='0':
            dp[i+1][0]=dp[i][0]+1
            dp[i+1][1]=max(dp[i][1], dp[i][0])
        else:
            dp[i+1][1]=max(dp[i][0], dp[i][1]) + 1
            dp[i+1][0] = dp[i][0]
    return max(dp[n][0], dp[n][1])

def change(s:str, l:int, r:int):
    tmp = ""
    for i in range(l-1, r):
        if s[i]=='0':
            tmp += '1'
        else:
            tmp += '0'
    s = s[:l] + tmp + s[r:]
    return s

nm = [int(x) for x in input().split()]
n, m = nm[0], nm[1]
strs = input()

for i in range(m):
    memo = [i for i in input().split()]
    if memo[0]=='q':
        print(query(strs, n))
    elif memo[0]=='c':
        l  = int(memo[1])
        r = int(memo[2])
        strs = change(strs, l, r)

数据结构

https://www.cnblogs.com/mr-wuxiansheng/p/8688946.html

快手

笔试 3.22

求一定的K个数最大乘积:给两个整数k, n 求将n分成k份后的最大乘积

class Solution:
    def __init__(self,maxx,K,N):
        self.maxx=maxx
        self.N=N
        self.K=K

    def back(self,ans,loc,right):
        if loc==self.K-1 or right==1:
            self.maxx=max(self.maxx,ans*right)
            return
        for i in range(1,right):
            self.back(ans*i,loc+1,right-i)

p=list(map(int,input().split()))
K=p[0]
N=p[1]
maxx=0
ans=1
loc=0
right=N
s=Solution(maxx,K,N)
s.back(ans,loc,right)
print(s.maxx)
  1. [[1,2,3],[4,5,6],[7,8,9]]
    最短路径:求二维矩阵从左上角到左下角的最小路径
class Solution:
    def find_best_path_cost(self , A ):
        # write code here
        if not A:
            return 0
        row=len(A)
        col=len(A[0])
        dp=[[0 for j in range(col+1)] for i in range(row+1)]
        for i in range(1,row+1):
            dp[i][1]=dp[i-1][1]+A[i-1][0]
        for j in range(1,col+1):
            dp[1][j]=dp[1][j-1]+A[0][j-1]
        for i in range(2,row+1):
            for j in range(2,col+1):
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+A[i-1][j-1]
        return dp[row][col]

if __name__ == '__main__':
    s=Solution()
    A=[[1,2,3],[4,5,6],[7,8,9]]
    print(s.find_best_path_cost(A))

  1. 给定S, A, B, P, 初始arr[0] = S, 接下来arr[i+1] = (arr[i] * A + B) % P, 并且arr数组里的每个数字最多出现两次,当某个数字出现3次时,终止序列生成。给定两组S, A, B, P分别生成两个序列,求两个序列的最长公共子序列
    3.1 最开始想到的就是LCS算法,本来觉得应该有规律但是找不到···写完之后果然超时:
def longest(s1, s2):
    m, n = len(s1), len(s2)
    if m==0 or n==0:
        return 0
    dp = [[0] * (1+n) for _ in range(m+1)]
    for i in range(m):
        for j in range(n):
            if s1[i]==s2[j]:
                dp[i+1][j+1]=dp[i][j]+1
            else:
                dp[i+1][j+1]=max(dp[i][j+1], dp[i+1][j])
    return dp[m][n]

def generate(line):
    l = [int(x) for x in line.split()]
    S, A, B, P = l[0], l[1], l[2], l[3]
    res = [S]
    while 1:
        x = (res[-1]*A+B)%P
        if x not in res:
            res.append(x)
        else:
            j = 0
            while res[j]!=x:
                j+=1
            n=len(res)
            while j

3.2 参考https://www.nowcoder.com/discuss/388827?toCommentIpt=1

  1. 三维坐标系下半径为1的求,然后与椭球:(x-a)2/d2 + (y-b)2/e2 + (z-c)2/f2 = 1相较,求相较后椭球内部和在椭球外部的表面积分别是多少
    完全没思路...
    牛客上大佬解法:随机数生成
from math import pi
from random import random
from random import uniform

num = [float(x) for x in input().split()]
a, b, c, d, e, f = num[0], num[1], num[2], num[3], num[4], num[5]

ball_area = 4 * pi
part_area = [0] * 2

#假设共有n个数
n = 10000
for i in range(n):
    x= random() * (-1 if random()<0.5 else 1)
    y = uniform(0, 1 - x**2) * (-1 if random()<0.5 else 1)
    z = (1 - x**2 - y**2) * (-1 if random()<0.5 else 1)
    
    def is_ball(x, y, z):
        X = (x-a)/d
        Y = (y-b)/e
        Z = (z-c)/f
        return X**2 + Y**2 + Z**2<1
    
    if is_ball(x, y, z):
        part_area[0] += 1
    else:
        part_area[1] += 1

A1 = (part_area[0]/n) * ball_area
A2= (part_area[1]/n) * ball_area
print(A1, A2)

微软3.26 zz

  1. 击鼓传花
    嗯…突发奇想给这题起了个名
    N个人每个人编号1-N,编号能整除的两个人互相连通,从编号为i的人开始传,最后要传回i手上,要在T次之内传完,问最多有几种传法?

回溯算法

  1. 最少射击几次
    N个瓶子都有编号,每次能射击1个或多个瓶子,如果是回文的就能一次性击倒。最少几次能全击倒?
    测试
    输入:[1, 2]
    输出:2
    输入:[1,3,4,1,5]
    输出:3
    说明:第一次先射3,变成[1,3,1,5],因为有[1,3,1]回文可以一次击倒,剩下[5]再一次
#include 
#include 
#include 
using namespace std;
 
int main() {     
int N = 6;     
    
vector > scores(N, vector(N));     
int bottles[6]={ 1, 2, 3, 4, 5, 6 };

for (int i = 0; i < N; i++) {         
    scores[i][i] = 1;     
}     
for (int i = 1; i < N; i++) {
    for (int j = 0; j < N - i; j++) {
        int min_score = INT_MAX;
            if (bottles[j] == bottles[j + i]) {
                min_score = i > 1 ? scores[j + 1][j + i - 1] : 1;             
                }             
            for (int k = 0; k < i; k++) {                 
                int temp = scores[j][j + k] + scores[j + k + 1][j + i];
                if (temp < min_score) {
                    min_score = temp;                 
                    }             
            }             
            scores[j][j + i] = min_score;         
            
    }     
}     
cout << scores[0][N - 1];     
return 0;
}
  1. 排队
    N个人排队编号1-N,可能3种情况:
    E1: 排在队首的人离开
    E2: 队伍中编号为K的人离开
    E3: 返回编号为X的人在队伍中的位置
    输入一组query,返回所有E3累加的结果
    测试
    N=5 query=3
    [1,0] [2,3] [3,2]
    输出:1
    说明:第一次队首编号1的人走了,第二次编号为3的人走了,第三次编号2的人排在队伍中的第一个

  2. 蜜蜂采蜜
    蜜蜂从家里出发,有几朵花和几处仓库(有坐标),每朵花有一份蜂蜜,蜜蜂一次只能带一份蜂蜜,可以先把采好的蜂蜜送到仓库,最后要回到家里。蜜蜂飞一单位的距离就会消耗一单位的时间(欧式距离),在限定时间T内,蜜蜂最多能采多少蜂蜜?

腾讯

3.30 一面 1h左右

  1. 问题:sickit-learn求你了别说错了
  2. 主要围绕lstm自动生成全唐诗,可不可以做到n对n,1对n的生成
    具体的生成策略
    相关参数:两层lstm, embedding, linner: embedding_size=128, hidden_size= 256, max_len=125
    lstm 1vs n 与 n vs n


    面经_第1张图片
    n vs n
面经_第2张图片
1 vs n
  1. 围绕研究生期间的具体工作,边缘计算,论文是否自己写成
  2. 介绍tf-idf, word2vec,区别,(答得不太好,应该说tf-idf忽略了上下文语义以及相似度),word2vec用了哪种工具包,在哪些数据集上进行了实验
    https://blog.csdn.net/stupid_3/article/details/83184807
    tf-idf:


    term-frequency表示单词在文本中出现的频率
    inverse-document-frequency表示出现这个单词的文档在总文档中的个数的倒数
    工具包:
    class sklearn.feature_extraction.text.TfidfTransformer(norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)
    norm:词向量归一化
    Word2vec: word embedding: cbow skip-gram
    skip-gram在大数据集上表现良好,采用负采样训练时可以看成softmax做二分类模型
    tf-idf word2vec区别:
    word2vec不会出现维度爆炸,是单词的稠密表示,训练过程考虑了上下文环境,更好的表达单词语义。
  3. 详细地问了kaggle分类竞赛,SVM的数据特征,7折bert?(面试官表示疑惑?这个说法不对吗?)
    用bert与transformer+SVM对比表示疑惑,我说内存不够,表示fine
    问到可以如何继续提高效果
  4. 开放问题:在比如地图这样的场景,输入前几个词预测接下来的词,如何做?
    以及在线生成的情况?(我不知道,面试官表示你们没有机会见到这种情况可以理解,人超级随和)
    对hadoop, spark这些有没有了解
    是不是了解linux
    (感觉后面都是结合岗位需要)
  5. 三道算法题,大概用时30min
    1)给定一个字符串如abcABF, 去掉重复词,忽略大小写,输出去除重复词后的字符串abcF,返回字符串长度;
    2)求最长公共子序列:太常见了所以问我会不会,之后只说了思路;
    3)给定一个排序二叉树,返回第k大节点:我感觉最麻烦的在于自己建树,以及输入样例的过程,利用排序二叉树的中序遍历生成;

4.02 腾讯二面 30min

面试小哥没开摄像头,但是态度很好,主要是问项目,问的很细
考虑三个项目重新捋一遍
包括细节、模型搭建、参数设置和调参过程,(原论文)
没做好准备,太惨了
手撕代码:C++手写python split函数

京东

3.31 京锐夏令营 推荐算法 30min

我也不知道当时怎么投了这个,是想把Nlp结合推荐来做,答得很乱
开放性问题:比如给定部分物品和相关文案,如何生成一个新物品的文案
进一步可以得到用户评论,应该怎么做
小姐姐提示说,可以对用户评论提取关键字,取频率最高的k种,对这些进行分类,选取优质评论从而生成新文案。
但是让我过了,小姐姐真是个好人。
明天继续转锦鲤

京锐夏令营 二面 35min

主要问的是项目和相关的基础问题

  1. 自我介绍
  2. 唐诗生成项目:lstm的结构,相比rnn有什么优势,为什么?
    了解batch norm/layer norm这些吗?具体怎么实现的
  3. 文本序列标注:bert起什么作用?有多少层?crf如何解码?具体说一下维特比算法?损失函数怎么设计的?
  4. 表述有点模糊,其实就是问各种优化算法sgd、adam这些
  5. 为什么会出现梯度消失和梯度爆炸?(主要从激活函数这方面说的)怎么解决呢?(激活函数的变种balabala)还有吗?
  6. 过拟合怎么解决?
  7. 最后口述0-1背包问题的解决方法

crf那里有点模糊,然后一直在深究,感觉不太好。(真的很玄学,我前一天和早上刚看的各种归一化方法···)而且真的要练一练自己的表述能力···

字节

一面 1h 04.01

  1. 自我介绍
  2. 直接手撕代码
    面经_第3张图片

    开始有点没思路,直接深度遍历找最小距离,之后面试官提示说可能会出现死循环,于是增加了一个二维矩阵记录已遍历节点,写完说可以;然后问时间复杂度,能不能优化;回答O((mn)^2)的复杂度,优化的方法想到可以遍历靠近0的节点,随后一步步包围,这种优化方法好像还挺满意的,问时间复杂度呢?脑子瘸说O(mnlogn), 其实应该是O(mn)
    总共用时20min
  3. 问了第一个项目,为什么要用bert+svm?还可以怎么做分类?
    如果没有内存限制,怎么做会更好?
    基于bert,提供抖音的评论,如何进行分类?
    强调如果不限制资源可以怎么做?其实是想说可以从bert预训练开始,谷歌提供的预训练模型是基于自己的数据集,和评论不完全相符,因此可以自己从预训练开始训练模型。
    就这一点问了bert的原理,为什么具有优势?(mlm and nsp, 因此下游可以从mlm开始预训练)
    如果下游重点是要处理低俗的单词,可以怎么做?
    (回答mask可以不再随机mask,而且有选择的重点选择低俗词语。)
    还有吗?
    (我开始瞎答了,用图像加入预训练balabala),提示可以增加其他预训练任务,可以利用举报、相关视频如美女视频等信息,在bert预训练两个任务的基础上,加上这一个分类任务,如视频的tag分成“美女”“性感”等分类,从而扩充低俗词汇。
    (自我介绍说了一个文本预处理)你了解哪些文本预处理?
    文本增强场景,(欠拟合?)可以去分析文本看是不是有错拼、这种情况下文本纠正和顺序置换是有效果的。

二面 1h

  1. 自我介绍
  2. 还是第一个项目,对方法犹疑, 叹息
  3. 介绍下transformer结构,这里可以说的更详细
  4. 展开说下word2vec(层次softmax, 怎么应用到fasttext, 在面对K类数目差不多的类别时会有什么效果?)
  5. 评估方法都有哪些,auc和其他的有什么区别(排序)
  6. 开放性问题:提供抖音评论,相比正常文本更短,应该怎么处理?
    语句部分用户会用正常词替换违禁词或者低俗词汇,怎么做?
    其他的,没录音,忘了····
  7. 手撕代码
    写出二叉树非递归中序遍历,gg
    换成装雨问题,开始用两个数组,之后要求o(1)空间复杂度,口述思路。

三面 04.03 40min

无自我介绍

  1. 手撕代码:给定两个由大到小的排序数组,输出最大的K个数,要求尽量严谨;
    升级:m个由大到小的数组,输出最大的K个数;
    开始自作聪明合并头尾,实际上和依次合并的时间复杂度是一样的 o(mk)
    升级:减小时间复杂度
    其实这个时候前面的时间复杂度没回答上来就down了,然后也没思路,面试官提示了很久,最后说是用最大堆,时间复杂度o(klogm)
    总结:字节很爱问时间复杂度这种,而且心态绝对不能论 ············(冷知识,m个数据建堆的复杂度是o(m)
  2. 基础知识
    bert(应该好好把整个优势捋一遍,可惜心态有点炸了)
    优化方法
    如果样本不均衡,可以怎么做:
    1)从采样角度,欠采样和过采样
    如果数据集比较大,可以使用欠采样,减少丰富类的数目;
    如果数据量比较小,可以过采样,通过使用重复、自举或合成少数类过采样等方法(SMOTE)来生成新的稀有样品。
    过采样改进方法1
    通过抽样方法在少数类样本中加入白噪声(比如高斯噪声)变成新样本一定程度上可以缓解这个问题。如年龄,原年龄=新年龄+random(0,1)
    过采样代表算法:SMOTE 算法
    SMOTE[Chawla et a., 2002]是通过对少数样本进行插值来获取新样本的。比如对于每个少数类样本a,从 a最邻近的样本中选取 样本b,然后在对 ab 中随机选择一点作为新样本。
    2)K-折交叉验证,过采样之前采用
    3)阈值移动
    在样本分类决策过程中,改变决策阈值为两类样本的比例,
    4)评估指标,auc,交叉熵
    5)模型选择,选择树模型或者集成学习方法,xgboost,随机森林

hr面 25min 4.07

4.06 接到电话通知hr面,嗯,接到电话的时候可以上天了
hr应该是之前一直跟我沟通的小姐姐
没有自我介绍,对方应该是知道了大概情况,问对整体面试的评价;对哪个面试官印象最深;
实验室的方向,研究生期间做的事情
个人职业规划,对第一份工作有什么要求,看重哪些地方,希望在哪里工作,导师的评价
个人优缺点,遇到的一件困难的事情,能给公司带来什么,优缺点那里追问了一下
对字节有哪些了解,有用过哪些app
反问:实习转正要求,这个职位具体要做的工作,以及转正后能否调整工作地点(不能orz)

阿里淘系

4.8 笔试

  1. 勇士n秒内获得增幅,每秒一点伤害,伤害范围为b,木头人血量为a, 数量为m,求最多可以打倒的木头人数量;
  2. 给定一个矩阵,求从左上角出发累计的路径最大值,要求每一步需要比前一步的数值大,可以跨越的距离为k: ac35%

招行信用卡中心

4.8笔试

  1. 判断是不是镜像字符串;
  2. 给定一个数字字符串和k, 可以添加+,-,找到和为k的组合数:ac50%
def calcu(vec, k):
    total = sum(vec)
    if (total-k)%2!=0:
        return 0
    else:
        limit = (total-k)//2
        memo = [0]*(limit+1)
        memo[0]=1
        for i in range(1, len(vec)):
            j=limit
            while j>=vec[i]:
                if memo[j-vec[i]]>0:
                     memo[j]+= memo[j-vec[i]]
                j -= 1
        return memo[limit]
    
def permu(s, vec, res):
    if len(s)==0:
        res.append(vec)
    for i in range(len(s)):
        permu(s[i+1:], vec+[int(s[:i+1])], res)
    return

t = int(input())
while t>0:
    t -= 1
    s, k = input().split()
    if s

你可能感兴趣的:(面经)