面灵AI→

腾讯算法岗面经合集:推荐样本、多目标优化与特征交叉

轮次
多轮面试合集
时间
2026-10
来源
牛客网

《面试题目》

面经 01 · 算法岗(2026-04-12)

  1. 这里推荐用的是公开的数据集做的是吧?详细介绍下数据集?
  2. 数据集中的评价是文本类的评价吗?
  3. 因为你是做推荐,你肯定用到了不同维度的特征嘛,介绍下所用的特征?
  4. 针对这种数据你是怎么去编码,以及训练的方法?
  5. 怎么理解这里的正样本和负样本?
  6. 正负样本的比例大概是多少呢?
  7. 训练数据总共用了多少?训练了多久?
  8. embedding 的初始化方法?
  9. 多目标优化模型有了解哪些?详细介绍下。
  10. 手撕:颜色分类(Hot100)。

面经 02 · 算法岗(2025-12-15)

  1. 最长递增子序列的变种题型。
  2. 手撕:二叉树公共祖先问题。
  3. 对其他特征交叉类模型的了解程度。

《参考解析》

正负样本的定义、比例与采样陷阱。 正负样本的定义取决于业务目标:做点击率就「曝光且点击」为正、「曝光未点击」为负;做转化就把「点击未下单」当负例或直接建成 ESR(曝光-点击-转化)的样本空间;做推荐召回时正例是「用户真实交互过的 item」,负例是全局随机采样的物品。比例本身不是关键,分布才是——线上真实点击率可能只有百分之几,训练时如果按 1:1 采样,模型学到的先验严重偏高,上线后必须做校准(用 p/(p + (1−p)/w) 之类的重加权,或直接对输出做 logistic 校正)。负采样策略也有讲究:全是随机负例会让模型只会粗筛,要掺入曝光未点击和「被召回但最终没交互」的 hard negative,但 hard negative 掺多了会引入假负例(用户其实会点、只是没曝光)。数据侧最容易出事的是时间穿越:特征必须只由预测时点之前的信息算出,训练/验证要按时间切分而不是随机切分,否则线下 AUC 好看、线上崩。

特征编码与 embedding 初始化。 特征按类型分开处理:类别特征(用户 ID、物品 ID、类目、城市)走词表或哈希映射到 embedding 查表,低频类别要设兜底桶并做频次截断;数值特征(价格、时长、年龄)可以分桶离散化后查 embedding,也可以归一化后过一层 MLP 再与类别特征拼接,分桶的好处是引入非线性、坏处是损失精度,实践中不少模型两者都给。多值特征(标签、历史行为序列)常用 pooling 或 target attention 聚合成定长向量。embedding 初始化常见的是小方差正态分布或均匀分布,Xavier/He 初始化在稀疏 ID 特征上并不一定最优;Adam 配合稀疏特征最好用 sparse 梯度更新,否则没被激活的 embedding 会被动量项带着漂移。有文本或图像 side information 时,可以用预训练语义向量初始化 embedding,冷启动阶段明显更稳。训练方法的追问一般落在目标函数与采样上:CTR 用交叉熵,召回的 softmax 在物品量级大时用 sampled softmax 或 in-batch negative(要处理同 batch 内热门物品的采样偏差),双塔还可以加温度系数控制分布锐度。

多目标优化模型:MMoE、PLE 与 ESMM。 多目标建模要解决两个不同的问题。一是「多个目标之间样本空间不一致」——典型是 CVR:只有点击过的样本才进入转化模型,直接用点击样本训练会有严重的样本选择偏差,ESMM 的解法是把 pCTCVR = pCTR × pCVR 放在全曝光样本上学,CVR 塔只在连乘里被间接监督,从而在无偏的样本空间上训练。二是「多个目标互相冲突」——共享底层在有负相关任务时会互相拖累,MMoE 用多个专家加任务自己的 gate 做软共享,让每个任务自己决定从哪些专家取信息;PLE 进一步把专家分成共享专家和任务特有专家,缓解跷跷板效应。答题时要能说出取舍:任务相关性高、数据量小时硬共享(shared-bottom)就够,任务冲突明显或量级差异大时才上 MMoE/PLE;融合层按业务价值加权(如按转化价值折算成 eCPM)而不是简单预测分数相加;还要提一句线上要盯每个目标的独立指标,避免一个目标涨、另一个目标被牺牲却看不出来。

特征交叉类模型与 Wide&Deep 家族。 特征交叉的价值在于给线性模型补上非线性交互,也让深层网络省掉从零学组合的力气。Wide&Deep 是最经典的组合:Wide 侧吃人工构造的交叉特征负责「记忆」高频共现,Deep 侧吃 embedding 负责「泛化」没见过的组合,两边输出相加过一层 sigmoid。后续演进都在「怎么少写人工特征」上做文章:DeepFM 用 FM 的二阶项替换 Wide 侧,自动学二阶交叉,不再需要人工设计;DCN 系列用显式的 cross network 做高阶交叉(x_{l+1} = x0 · x_lᵀ · w + b + x_l),order 可控且参数量小;xDeepFM 的 CIN 做 vector-wise 的显式高阶交叉;AutoInt 用多头注意力自己学交叉。答题时别只背名字,要讲清三件事:交叉是显式还是隐式、能到几阶、以及工程成本(参数量、显存、线上延迟)。面试官问「你们线上为什么选它」,想听的是「业务特征以稀疏类别为主、需要强记忆,所以 Wide 侧保留了人工交叉 + Deep 侧兜冷启动」这类有依据的选择,而不是哪个模型更新。

手撕「颜色分类」:三指针一次遍历。 这是荷兰国旗问题,要求原地、O(n)、O(1):用 cur 从左往右扫,left 指向已确定的 0 区右边界,right 指向已确定的 2 区左边界。遇到 0 就和 left 交换、left++、cur++;遇到 2 就和 right 交换、right--(注意此时 cur 不动,因为换过来的元素还没检查过,这是最容易写错的一行);遇到 1 直接 cur++。循环条件是 cur <= right。面试时不要只写代码,先说清循环不变量——[0, left) 全是 0、(right, n) 全是 2、[left, cur) 全是 1——不变量立住了,边界条件自然就对了。常见的追问是改成三路快排的 partition(用来处理大量重复元素的排序场景,可以把重复键一次到位、避免快排退化到 O(n²)),以及如果颜色不是 0/1/2 而是任意分组怎么做(计数排序两遍扫描)。