1 面试背景

  • 面试公司:快手
  • 面试岗位:推荐算法实习生【模型算法】
  • 面试类型:技术二面
  • 面试时间:2024-12-10 14:00~15:00
  • 面试结果:待定

2 整体感受

第一眼感觉面试官 30~40 岁之间,之后没有让我自我介绍,直接让我找一个自己做的好的项目介绍。当时感觉面试官有点不一样,一般都先让自我介绍。

之后问了我几个问题,我都答上来了,然后就是手撕代码环节,也是很快就做出来了,最后面试官的意思基本就是通过了,问我什么时候能去之类的。总之,还是挺好的,找到了实习。

后来了解到面试官是那个组的 leader 😮。


3 提问的问题

面试官:新闻推荐比赛的数据集规模大概是多少?

数据集的话是一共有30万个用户,然后是20万个用户作为训练集,然后5万个用户作为公共的测试集,剩下的5万作为私有的测试集。然后新闻的话大概是60万个新闻。

面试官:你的方案有什么创新点?

首先我对传统的协同过滤进行了改进,传统的协同过滤只考虑两个物品,比如说同时被点击的次数,但是并没有考虑点击顺序和点击时间的权重。balabala……

面试官:除了做一些特征工程,模型结构上有啥变化吗?

balabala……

总之面试官问的问题我都答上来了,在此就不赘述了。


4 手撕代码

一共就一道题,考的是动态规划,力扣原题322. 零钱兑换。因为这题之前自己做过,所以看到题目就知道用动态规划做。但是具体的状态定义也忘记了,所以当时现想的。题目如下:

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。可以认为每种硬币的数量是无限的。

  1. 状态表示:$f[i]$ 表示凑成总金额为 $i$ 所需的最少硬币个数
  2. 状态计算:对于每个总金额 $i$ ,枚举每枚硬币 $coins[j]$ ,如果 $i \geq coins[j]$ ,则:

$$
f[i] = \min(f[i], f[i - coins[j]] + 1)

$$

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f = [inf] * (amount + 1)
coins.sort()
f[0] = 0

for i in range(amount + 1):
for coin in coins:
if coin > i:
break
f[i] = min(f[i], f[i - coin] + 1)

if f[amount] == inf:
print(-1)
else:
print(f[amount]

一开始写的时候没有写 coin > i ,所以不对,后来发现了这个问题,然后测试用例都对了。面试官还夸我做的真快哈哈哈,拿捏了。