Duolingo 的语言学习产品背后,是一整套以学习科学 + 机器学习驱动的引擎:什么时候推哪道题、用户多久会忘、如何用最少的练习把记忆留住,全靠模型。它的 AI Research Engineer 岗位介于 Research Scientist 与 ML Engineer 之间——既要会读论文、设计实验,也要能把模型写成可上线的工程代码。
这条岗位线的虚拟 Onsite 和普通 SDE 完全不同:编程只占一轮,剩下三轮考的是 ML 深度、研究设计直觉和把模型嵌进产品的系统能力。本文按这条线的真实反馈,把四轮 VO 的题型骨架、高频追问和准备路径讲清楚。
一、Duolingo AI Research Engineer VO 概览
| 维度 | 详情 |
|---|---|
| 轮次 | 4 轮 VO(编程 / ML 深度 / 研究设计 / 应用系统) |
| 单轮时长 | 45-60 分钟 |
| 平台 | 视频 + 共享编辑器(编程轮用 CoderPad 风格) |
| 语言 | Python 为主,ML 轮可白板推导 |
| 考察重点 | 工程实现 + 建模深度 + 实验思维 + 产品落地 |
| 节奏 | Recruiter → 技术电面 → 四轮 VO → 团队匹配 |
关键认知:这条线最容易翻车的不是算法,而是「能把论文讲清楚、但写不出干净代码」或「会调包、但说不清为什么这么建模」。四轮各有侧重,任何一轮明显短板都可能一票否决。
二、第一轮:编程实现(序列采样)
题目描述
给定一个长度为 n 的词表,每个词有一个权重 weights[i](出现频率)。实现一个采样器,按权重无放回地抽出 k 个不同的词,并保证整体期望与权重成正比。要求 build 一次后支持多次高效采样。
解题思路
无放回加权采样的经典做法是 A-Res(指数跳跃 key):对每个元素生成 key = u^(1/w)(u 为 (0,1) 均匀随机),取 key 最大的 k 个。等价于按权重的 top-k,O(n) 一次扫描用堆维护即可。
Python 解法
import heapq
import random
class WeightedSampler:
def __init__(self, weights):
self.weights = weights
def sample(self, k):
# A-Res: key = u^(1/w),取最大的 k 个
heap = [] # 维护当前 key 最大的 k 个 (key, idx)
for i, w in enumerate(self.weights):
if w <= 0:
continue
u = random.random()
key = u ** (1.0 / w)
if len(heap) < k:
heapq.heappush(heap, (key, i))
elif key > heap[0][0]:
heapq.heapreplace(heap, (key, i))
return [i for _, i in heap]
时间复杂度:O(n log k) 空间复杂度:O(k) 追问:如果权重会动态更新怎么办?答 Fenwick 树前缀和 + 二分定位,单次更新/采样 O(log n)。
三、第二轮:ML 深度(间隔重复建模)
场景
Duolingo 的核心是 SRS(Spaced Repetition System,间隔重复):预测用户在间隔 t 后还记得某个单词的概率,用来决定下次复习时间。面试官会让你从零设计这个「记忆模型」。
建模思路
经典基线是 Half-Life Regression(半衰期回归):把记忆衰减建成指数
$$p = 2^{-t / h}, \quad h = \exp(\theta \cdot x)$$
其中 h 是半衰期,由特征 x(历史正确次数、错误次数、词难度等)经线性层得到,保证恒正。损失同时拟合「召回概率 p」和「半衰期 h」。
import numpy as np
def hlr_loss(theta, X, t, recalled, alpha=0.01):
# X: (N, d) 特征; t: (N,) 间隔; recalled: (N,) 0/1
h = np.exp(X @ theta) # 半衰期,恒正
p = np.power(2.0, -t / h) # 预测召回概率
p = np.clip(p, 1e-6, 1 - 1e-6)
# 主损失:召回概率的平方误差 + L2 正则
loss = np.mean((p - recalled) ** 2) + alpha * np.sum(theta ** 2)
return loss
为什么不用普通分类器:面试官想听到你理解「半衰期 h 是可解释量,能直接驱动调度」——黑盒分类器给不出「下次该隔多久复习」这个调度信号。
高频追问:
- 冷启动(新用户/新词)怎么办?→ 先用词级别先验 + 群体均值。
- 怎么评估?→ 不是 accuracy,而是召回概率的校准(calibration)+ MAE on
p。
四、第三轮:研究设计与实验(A/B + 因果)
场景
「我们想验证:把新的复习调度算法上线,能否提升 7 日留存(D7 retention)。设计一个实验。」
拆解框架
- 指标:主指标 D7 retention;护栏指标 daily lessons、复习负担(避免为留存堆练习量)。
- 单位与分流:按 user 随机分流(不是 session,避免污染),分桶前做 A/A 检验。
- 样本量:基于基线留存率与最小可检测效应(MDE)反推每组 N,固定 power=0.8、α=0.05。
- 新奇效应:调度类改动有 novelty effect,需观察 ≥2 周而非看首日。
- 因果陷阱:留存是幸存者偏差重灾区——只看活跃用户会高估效果,要按分流时点的意图分析(ITT)。
from math import sqrt
def required_n_per_arm(p0, mde, z_alpha=1.96, z_beta=0.84):
# 双比例检验近似样本量
p1 = p0 + mde
p_bar = (p0 + p1) / 2
num = (z_alpha * sqrt(2 * p_bar * (1 - p_bar))
+ z_beta * sqrt(p0 * (1 - p0) + p1 * (1 - p1))) ** 2
return num / (mde ** 2)
# 基线 D7=40%,想检测 +2 个百分点
print(int(required_n_per_arm(0.40, 0.02)))
面试官真正在看:你会不会主动提护栏指标和 novelty effect——只会算样本量是不够的。
五、第四轮:应用系统设计(在线推断管线)
场景
「把上面的记忆模型部署成线上服务:每个用户打开 App,要在 50ms 内返回今天该复习的 20 个词。日活千万级。」
设计要点
| 层 | 方案 | 理由 |
|---|---|---|
| 特征 | 离线批算 + 在线轻量特征 | 历史统计离线算好,请求时只拼实时特征 |
| 模型服务 | 模型轻量(线性/小树),可批量向量化 | 50ms SLA 不允许重模型逐词推断 |
| 调度 | 维护每词「下次到期时间」,到期才进候选池 | 把「预测」转成「优先队列取 top-k」 |
| 存储 | 用户-词状态用 KV(半衰期、上次复习时间) | 读写都按 user 维度,天然分片 |
| 离线回灌 | 每晚用当天反馈重训 + 更新半衰期 | 闭环:复习结果 → 更新 h → 影响明日调度 |
核心 trade-off:把重计算挪到离线,线上只做「取到期词 + 轻量排序」,这样才能扛住 50ms × 千万日活。
六、四轮准备清单
| 轮次 | 重点 | 资源 |
|---|---|---|
| 编程 | 加权采样、流式 top-k、Reservoir Sampling | LeetCode + 概率算法 |
| ML 深度 | 记忆模型、校准、冷启动、可解释性 | Duolingo HLR 论文 + 推荐系统课 |
| 研究设计 | A/B 全流程、护栏指标、novelty、ITT | Trustworthy Online Experiments |
| 系统 | 在线推断、特征管线、调度队列 | ML System Design 资料 |
FAQ
Q1:AI Research Engineer 和普通 ML Engineer 的 VO 有什么区别?
最大差异是研究设计轮和 ML 深挖轮的比重。ML Engineer 更偏工程落地,Research Engineer 要能从零设计实验、解释建模选择、读懂论文。算法编程只占一轮,且偏概率/采样而非纯 LeetCode。
Q2:不是 NLP/教育背景,能投这条线吗?
可以。Duolingo 更看重「建模直觉 + 实验思维」,记忆模型、推荐、排序的迁移性很强。准备时把一个你做过的 ML 项目讲到能回答「为什么这么建模、怎么评估、上线后怎么验证」三层即可。
Q3:编程轮难度对标 LeetCode 什么水平?
骨架接近 Medium,但偏概率与流式算法(加权采样、Reservoir、top-k),不是常规 DP/图。重点是写得干净 + 能回答复杂度和动态更新的追问。
Q4:ML 轮会让我手推公式吗?
会。半衰期回归、损失函数、校准指标都可能让你白板推。不要求记死公式,但要能讲清「为什么用指数衰减、为什么 h 要恒正、为什么不用 accuracy 评估」。
Q5:VO 之后多久出结果?
通常四轮结束后 1 周内给 recruiter 反馈,再进入团队匹配(team match)。研究线团队少、匹配环节可能多等 1-2 周,整体节奏比纯 SDE 慢。
正在准备 Duolingo AI Research Engineer 的虚拟 Onsite?
这条线四轮各考一块短板,最难的不是某一道题,而是「编程、建模、实验、系统」四个维度都不能塌。如果你想要对应批次的 VO 真题还原、记忆模型 / 实验设计的专项陪练,或需要 VO 辅助 / VO 代面 的实时节奏对接,欢迎联系交流,发岗位 JD 截图先做轮次拆解,再排练习计划。
立即添加微信 Coding0201,获取 Duolingo VO 真题与四轮陪练。
联系方式
- 微信:Coding0201
- Email:[email protected]
- Telegram:@OAVOProxy