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