2020拼多多算法实习生笔试、面试记录

笔试

拼多多笔试两小时四道题,做出来三道,最后一道题未果,后寻得答案。

N个方块涂有颜色,玩家可以从所有的方块中任意移除最多k个方块,使得在剩余的方块中,连续相同的颜色的方块长度最长。问通过移动,可以得到的相同颜色的方块最长多长。

起初以为是用dp来做,不过确实能做:

1
2
3
4
5
6
7
8
9
10
//dp[i][j]表示以[i]结尾,移动j个方块所能得到的最长长度;
//状态转移方程为:
if(a[i] == a[i-1])
{
dp[i][j] = max(dp[i][j], dp[i-1][j] + 1);
}
else
{
dp[i][j] = max(dp[i][j], dp[i-1][j-1]);
}

不过这种做法,需要的时间复杂度为O(nk),超时了,显然不能满分。

实际上,正确的解法为使用滑动窗口的技巧,对于初始情况下的每一块相同颜色的色块,以该色块颜色为当前的目标颜色,维护最大移除长度为k的滑动窗口(即最多跳过k个不相同的颜色方块),记录当前窗口内,通过移除可得的最大相同长度,在依此更新全局的最大长度。不过,我寻思这样做时间复杂度也是O(nk),只不过可能常数要小一些而已。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<algorithm>

using namespace std;

int cicada[100010];
int n, k;
int main()
{
cin>>n>>k;
for(int i = 0 ; i < n; i++)
cin>>cicada[i];
int i = 0, ans = 0;
while(i < n)
{
int len = 1;
while(i + 1 < n && cicada[i] == cicada[i+1]) //维护初始色块
{
i++, len++;
}
int t = 1, count = 0;
while(i + t < n - 1 && count < k)
{
if(cicada[i] == cicada[i + t]) len++;
else count++;
t++;
}
while(i + t < n && cicada[i] == cicada[i + t])
{
t++, len++;
}
ans = max(anx, len);
i++;
}
cout << ans << endl;
return 0;
}


一面

面试官是一个和蔼的叔叔(真滴好和蔼呀,整个面试的过程都轻松了很多呢)太和蔼了,好感度+10,终于不会被庄小姐杀死而潜伏失败了。
令我吃惊的是,面试官先向我做了一个自我介绍,他是拼多多图像组的组长,工作内容是拼多多内部或者产品的一些人脸识别、图像搜索等内容。之后,大抵寻常的过程,我做了自我介绍,而他针对我的项目问了很多问题,以下作为记录:

  • 问:你的这篇论文工作是在哪里一些改进呢?你说是系统的响应时间,怎么看着你们使用社交网络的维度是在推荐系统的效果上做出了一些改进呢?

    答:是的,考虑社交网络关系对于用户查询的影响的确能够在推荐系统的推荐效果上给用户以更好的对象推荐,那我所说的在响应时间上的改进是得益于我们使用用户的社交网络影响进行了一些剪枝算法的设计。首先我们使用图嵌入算法得到用户特征向量之后,使用用户之间的相似度对于用户朋友对于每个索引节点的访问次数进行加权求和之后归一化,得到用户受其社交关系的影响因子,并设定一个阈值,我们认为低于这个阈值的索引节点是在社交与当前用户不相关的节点,就剪枝掉,从而节省了很多对于不相关节点的访问时间。

  • 问:你的鸟类图像分类这个项目中为什么要做边缘检测、去背景,难道去背景之后效果会更好嘛?

    答:我们拿到的图片中,有些鸟类主体只占图片的非常小的一部分,我们觉得去除多余的背景,可以去除一些冗余的信息,可能会提高模型的效果。

    问:那你去了背景之后模型效果提高了多少。

    答:我没做对比实验

    之后,尬住。。

  • 问:你毕设项目中的这个验证器是什么?能具体介绍一下嘛?

    答:

  • 问:介绍一下CycleGAN。

    答:我大概说了一下,这里记录一下自己说错的一点。实际上,Cycle Consistencey Loss包括的是x -> G(x) -> F(G(x))中F(G(x))相对于x的loss(这个叫forward cycle consistency),还包括y -> F(y) -> G(F(y))中G(F(y))相对于y的loss(这个叫backward cycle consistency)。两者之和才是cycle consistency loss。

  • 问:你的deblur项目中改进了CycleGAN模型的什么网络结构?

    答:我们改进了CycleGAN的生成器网络,用了类似于Amulet的方法,使用多层次的特征提取,把低层次的卷积特征通过上采样的一些反卷积的操作,和后一层的feature map做concat操作。这样做就是希望一些低分辨率的粗糙去模糊图片引导高分辨率的去模糊图片的生成。

  • (我自己)问:什么是反卷积?

    (知乎)答:在应用在计算机视觉的深度学习领域,由于输入图像通过卷积神经网络(CNN)提取特征后,输出的尺寸往往会变小,而有时我们需要将图像恢复到原来的尺寸以便进行进一步的计算,这个采用扩大图像尺寸,实现图像由小分辨率到大分辨率的映射的操作,叫做上采样。而反卷积是一个常用的上采样方法,那反卷积是一种特殊的正向卷积,先按照一定的比例通过补0来扩大输入图像的尺寸,再进行正向卷积(也就是根据要上采样到的图片大小,进行补0,在对补0之后的矩阵做正向卷积)所以反卷积只能恢复尺寸,而不能恢复数值。

  • 问:SSIM loss是什么?

    答:SSIM loss是基于样本x和y之间三个方面的比较,分别是亮度、对比度和结构,SSIM loss改进了MSE不能衡量图像结构相似性的缺陷(SSIM越大,两个图像之间的差距越小)。

  • 问:介绍一下3D表面重建的Matching Cube算法。

    答:首先我们这个点云空间被分为k k k个小方块,也就是所谓的体素,存在模型点的体素,我们称为实体素,不存在的成为虚体素。定义体元是由8个相邻的体素所构成的正方体。而我们要做的3D表面重建就是在做3D模型表面的三角形面片的重建。那位于3D模型表面的体元的8个体素点都可能是实体素点或者虚体素点,那只有一共有2的8次方种情况,也就是256种情况。Matching Cube的思想就是利用这256种可枚举的情况来进行体元内3D模型表面的抽取。那这么抽取呢,举个例子,如果在边界体元中,A体素是实体素,B体素是虚体素,那这个表面就一定经过A和B的中点位置。也就是根据这样的表面划分方法,通过关注边界的体元,我们就能进行3D模型的表面重建。

  • 问:我看你都是在做一些深度学习的内容,你对传统的机器学习了解吗。介绍一下GBDT。

  • 问:介绍一下决策树的种类。(我并不是很懂这个问题,于是说了决策树的生成过程,这里试着回答这个问题。)