AI Day 46
AI Day 46: 系统设计面试(4):设计一个推荐系统
AI Day 46: 系统设计面试(4):设计一个推荐系统
2026-05-17
系统设计推荐系统召回精排重排实时特征LLM增强AB实验
日期: 2026-05-17 阶段: Phase 4 — 面试冲刺 (System Design + Product + Architecture) 主题: System Design Interview — Design a Recommendation System 进度: Day 1-45 ✅ | Day 46 ← current 标签: #系统设计 #推荐系统 #召回 #精排 #重排 #实时特征 #LLM增强 #AB实验
学习路径 (50-Day Full Tree)
AI/LLM 深度技术学习 50天计划
├── 第一阶段:模型基础 (Day 1-15) ✅
│ ├── Day 1-7: Transformer/量化/训练/Prompt/RAG/向量DB/FineTune ✅
│ ├── Day 8-11: 推理优化/长上下文/多模态/Reasoning ✅
│ └── Day 12-15: Agent/MCP/评估/阶段总结 ✅
│
├── 第二阶段:工程实践 (Day 16-30) ✅
│ ├── Day 16-18: 应用架构/安全/可观测性 ✅
│ ├── Day 19-21: 生产级RAG三部曲 ✅
│ ├── Day 22-25: Agent工程化四部曲 ✅
│ └── Day 26-30: 成本/编排/测试/案例/总结 ✅
│
├── 第三阶段:金融零售AI应用 (Day 31-42) ✅
│ ├── Day 31: 金融AI(1):智能风控与反欺诈 ✅
│ ├── Day 32: 金融AI(2):智能投顾与量化策略 ✅
│ ├── Day 33: 金融AI(3):合规科技与监管AI ✅
│ ├── Day 34: 金融AI(4):信贷全链路AI ✅
│ ├── Day 35: 金融AI总结 — PM视角的AI重塑金融 ✅
│ ├── Day 36: 零售AI(1):推荐系统与个性化 ✅
│ ├── Day 37: 零售AI(2):智能客服与对话系统 ✅
│ ├── Day 38: 零售AI(3):供应链预测与优化 ✅
│ ├── Day 39: 零售AI(4):智能营销与用户增长 ✅
│ ├── Day 40: 零售AI总结 — PM视角零售智能化全景 ✅
│ ├── Day 41: CeFi × DeFi × AI 融合架构(上) ✅
│ └── Day 42: CeFi × DeFi × AI 融合(下) + 职业定位 ✅
│
└── 第四阶段:面试冲刺 (Day 43-50)
├── Day 43: 系统设计面试(1):企业LLM平台 ✅
├── Day 44: 系统设计面试(2):生产级RAG系统 ✅
├── Day 45: 系统设计面试(3):AI Agent系统 ✅
├── Day 46: 系统设计面试(4):推荐系统 ← 你在这里
├── Day 47-49: 产品/架构面试模拟
└── Day 50: 总结与作品集
一、面试题
"Design a recommendation system for a large e-commerce platform (like Amazon/JD.com). The system should serve personalized product recommendations on the homepage, product detail pages, and search results. The platform has 100M users and 50M products."
二、Step 1: Requirements 需求澄清 (5 min)
面试时必须问的澄清问题:
Q1: "用户和商品规模?"
→ 假设: 100M注册用户, 10M DAU, 50M商品(SKU)
Q2: "推荐出现在哪些场景?"
→ 假设:
├── 首页"猜你喜欢" (Homepage)
├── 商品详情页"看了又看/买了又买" (Detail Page)
├── 搜索结果的个性化排序 (Search)
├── 购物车页"搭配推荐" (Cart)
└── 推送通知 (Push Notification)
Q3: "延迟要求?"
→ 假设: P99 < 200ms (用户体验关键, 不能让页面等)
Q4: "核心业务指标?"
→ 假设:
主要: CTR(点击率), CVR(转化率), GMV(交易额)
辅助: 多样性, 新颖性, 覆盖率, 用户满意度
Q5: "冷启动? 新用户和新商品如何处理?"
→ 假设: 必须处理, 每天有50K新用户和10K新商品
功能性需求 (Functional):
├── 个性化推荐: 基于用户画像和行为
├── 多场景支持: 首页/详情页/搜索/购物车/推送
├── 实时响应: 用户最近行为立刻影响推荐
├── 多样性控制: 不能全是同类商品
├── 业务规则: 置顶/屏蔽/库存过滤
└── AB实验: 支持多模型并行实验
非功能性需求 (Non-Functional):
├── 延迟: P99 < 200ms (从请求到返回推荐列表)
├── 吞吐: 峰值100K QPS
├── 可用性: 99.99% (推荐挂了=收入损失)
├── 新鲜度: 用户行为< 1min反映到推荐
├── 扩展: 用户/商品量翻倍时线性扩展
└── 成本: 推理成本可控
三、Step 2: Estimation 规模估算 (3 min)
请求量估算:
DAU: 10M
每用户: ~30次推荐请求/天(首页+详情页+搜索)
日请求: 10M × 30 = 300M requests/day
平均QPS: 300M / 86400 ≈ 3,500 QPS
峰值QPS: 3500 × 30(峰值系数, 电商大促) ≈ 100K QPS
→ 这是真正的高并发系统!
数据规模:
用户画像:
100M用户 × 1KB = 100GB
商品特征:
50M商品 × 2KB = 100GB
行为日志:
300M events/day × 200bytes = 60GB/day
保留90天: ~5.4TB
Embedding:
用户: 100M × 128dim × 4bytes = 50GB
商品: 50M × 128dim × 4bytes = 25GB
模型推理成本:
召回: 向量检索, ~1ms/query
粗排: 轻量模型, ~5ms/query(1000 candidates)
精排: 重模型, ~20ms/query(100 candidates)
重排: 规则+多样性, ~5ms
总计: ~31ms (远低于200ms预算, 留余量给网络和序列化)
四、Step 3: High-level Architecture 高层架构 (8 min)
经典四阶段架构: 召回→粗排→精排→重排
推荐系统核心Pipeline:
50M商品
│
┌─────────────────────────────┐
│ Stage 1: 召回 (Recall) │ ← 从50M中选出~1000
│ 多路召回, < 10ms │
└──────────────┬──────────────┘
│ ~1000 candidates
┌──────────────▼──────────────┐
│ Stage 2: 粗排 (Pre-rank) │ ← 从1000中选出~100
│ 轻量模型, < 10ms │
└──────────────┬──────────────┘
│ ~100 candidates
┌──────────────▼──────────────┐
│ Stage 3: 精排 (Rank) │ ← 从100中精确排序
│ 重模型, < 30ms │
└──────────────┬──────────────┘
│ ~100 scored items
┌──────────────▼──────────────┐
│ Stage 4: 重排 (Re-rank) │ ← 业务调整, 最终~20
│ 规则+多样性, < 10ms │
└──────────────┬──────────────┘
│
最终20个推荐结果
返回给用户
为什么需要四阶段:
如果直接对50M商品用精排模型:
50M × 0.5ms/item = 25,000秒 = 不可能
所以需要逐层漏斗:
50M →(召回)→ 1000 →(粗排)→ 100 →(精排)→ 排序 →(重排)→ 20
每层用越来越准但越来越慢的模型
完整架构图:
┌───────────────────────────────────────────────────┐
│ Online Serving │
├───────────────────────────────────────────────────┤
│ │
│ User Request │
│ │ │
│ ┌────▼────┐ │
│ │ Feature │◄── Feature Store (Redis/Feast) │
│ │ Service │ (用户特征 + 商品特征 + 实时特征) │
│ └────┬────┘ │
│ │ │
│ ┌────▼────┐ ┌──────────┐ ┌──────────┐ │
│ │ Recall │ │ Recall │ │ Recall │ │
│ │ (CF) │ │ (ANN) │ │ (Rule) │ │
│ └────┬────┘ └────┬─────┘ └────┬─────┘ │
│ └──────────────┼──────────────┘ │
│ │ Merge & Dedup │
│ ┌────▼────┐ │
│ │Pre-Rank │ (Two-Tower, lite) │
│ └────┬────┘ │
│ ┌────▼────┐ │
│ │ Rank │ (DIN/DIEN/DCN, heavy) │
│ └────┬────┘ │
│ ┌────▼────┐ │
│ │Re-Rank │ (多样性/规则/实验) │
│ └────┬────┘ │
│ │ │
│ Response │
└───────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────┐
│ Offline Training │
├───────────────────────────────────────────────────┤
│ User Logs → Feature Engineering → Model Train │
│ → Model Evaluation → Model Deploy (A/B) │
└───────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────┐
│ Nearline Processing │
├───────────────────────────────────────────────────┤
│ Real-time Events (Kafka) → Feature Update │
│ → User Embedding Update → Trigger Refresh │
└───────────────────────────────────────────────────┘
五、Step 4: Detailed Design 深入设计 (12 min)
5.1 Stage 1: 召回 (Recall) — 从50M中快速筛选
多路召回策略 (Multi-channel Recall):
为什么多路召回:
单一召回算法都有盲区
├── 协同过滤: 冷启动问题
├── 向量检索: 热门商品偏差
├── 规则召回: 不够个性化
→ 多路互补, 提高覆盖率
Channel 1: 协同过滤召回 (Item-CF / User-CF)
原理: "和你相似的用户也买了X"
实现:
离线: 计算Item-Item相似度矩阵(LSH优化)
在线: 用户最近交互的item → 查找相似item
优点: 经典有效, 可解释
缺点: 冷启动差, 稀疏数据差
召回数: ~200
Channel 2: 双塔模型召回 (Two-Tower / DSSM)
原理:
User Tower: 用户特征 → User Embedding (128dim)
Item Tower: 商品特征 → Item Embedding (128dim)
相似度: cos(user_emb, item_emb)
实现:
离线: 训练双塔模型, 计算所有item embedding
在线: 实时计算user embedding → ANN检索Top-K
ANN引擎: Faiss / ScaNN / HNSW (Qdrant/Milvus)
优点: 能处理冷启动(利用特征), 语义理解
缺点: 交叉特征弱(user和item独立编码)
召回数: ~300
Channel 3: 热门/趋势召回
原理: 推荐当前热门和趋势商品
实现:
每小时更新热门商品列表
按类目/地区/时间段细分
优点: 不需要个性化, 覆盖新用户
缺点: 没有个性化
召回数: ~100
Channel 4: 规则召回
原理: 基于业务规则的确定性推荐
实现:
├── 用户浏览过的类目 → 同类目热门
├── 购物车商品 → 搭配商品
├── 地理位置 → 本地热门
└── 运营置顶 → 促销商品
召回数: ~200
Channel 5: Swing/Graph召回 (进阶)
原理: 基于用户-商品二部图的图算法
实现: Swing算法/GraphSAGE
优点: 捕获高阶交互关系
缺点: 计算成本高
召回数: ~200
合并策略:
各路召回结果合并 → 去重 → ~1000 candidates
分配权重: ANN 30% + CF 25% + Rule 20% + Hot 15% + Graph 10%
5.2 Stage 2: 粗排 (Pre-Ranking)
粗排目的: 用轻量模型从1000→100, 控制精排计算量
模型选择: 轻量双塔 / 简单MLP
输入特征 (有限, 追求速度):
├── 用户侧: user_embedding(128) + 年龄 + 性别 + 城市
├── 商品侧: item_embedding(128) + 类目 + 价格 + 评分
└── 交叉: dot_product(user_emb, item_emb)
注意: 粗排不用复杂交叉特征(太慢)
模型结构:
Input(~260 dim) → Dense(128) → ReLU → Dense(64) → ReLU → Dense(1) → Sigmoid
参数量: ~50K (非常轻量)
推理: 1000 items × 0.005ms = 5ms ✅
训练:
目标: 预测点击概率 (pCTR)
数据: 用精排模型的打分做蒸馏(Knowledge Distillation)
更新: 每天重训
输出: Top-100 candidates → 送入精排
5.3 Stage 3: 精排 (Ranking) — 核心模型
精排模型 — 推荐系统的核心
模型演进:
LR → FM → DeepFM → Wide&Deep → DIN → DIEN → DCN v2 → DLRM
当前主流: DIN (Deep Interest Network) 或 DCN v2
DIN (Deep Interest Network) 详解:
核心思想: 用户对不同商品的兴趣强度不同
关键创新: Attention机制 — 根据候选商品计算用户历史行为的权重
举例:
用户历史: [iPhone手机壳, 运动鞋, Python书, 耳机]
候选商品A: AirPods耳机
→ Attention权重: [0.3, 0.05, 0.05, 0.6] ← 耳机相关的权重最高
候选商品B: 跑步鞋
→ Attention权重: [0.05, 0.7, 0.05, 0.2] ← 运动鞋相关的权重最高
模型结构:
┌────────────────────────────────────────────┐
│ User Features │ Item Features │ Context│
│ (Profile+ │ (Category+ │ (Time+ │
│ History) │ Attributes) │ Device│
└───────┬──────────┴───────┬─────────┴───┬────┘
│ │ │
▼ │ │
┌───────────────┐ │ │
│ Attention │◄─────────┘ │
│ over History │ │
└───────┬───────┘ │
│ │
▼ │
┌───────────────────────────────────────────┐
│ Concat All Features │
└───────────────────┬───────────────────────┘
│
┌───────────────────▼───────────────────────┐
│ MLP: 512 → 256 → 128 → 64 → 1 │
└───────────────────┬───────────────────────┘
│
pCTR (0~1)
输入特征 (Feature Groups):
用户画像特征 (User Profile):
├── 基础: user_id, age, gender, city, device
├── 统计: 7d/30d购买次数, 客单价, 活跃度
└── 偏好: 偏好类目, 偏好品牌, 偏好价格带
商品特征 (Item):
├── 基础: item_id, category, brand, price
├── 统计: 7d/30d点击率, 转化率, 好评率
└── 属性: 标题embedding, 图片embedding
上下文特征 (Context):
├── 时间: hour, weekday, is_holiday
├── 设备: device_type, os, screen_size
├── 位置: city, is_nearby_store
└── 场景: homepage / detail_page / search / cart
交叉特征 (Cross):
├── 用户×商品: 是否同类目, 价格偏差, 品牌匹配度
└── 实时: 是否刚搜索过相关词, 是否刚浏览过类似商品
用户行为序列 (Behavior Sequence):
├── 最近50个点击商品的embedding序列
├── 最近20个购买商品的embedding序列
└── 最近10个搜索query的embedding序列
Multi-Task Learning (多目标学习):
不只预测点击, 同时预测:
├── pCTR: 点击概率 (primary)
├── pCVR: 转化概率 (购买)
├── pFavor: 收藏概率
└── pShare: 分享概率
最终排序分 = pCTR^α × pCVR^β × price^γ × ...
其中α,β,γ由业务目标决定:
如果目标是GMV: 提高β和price权重
如果目标是DAU: 提高α(点击)权重
如果目标是新客转化: 对新用户加权
推理优化:
100 items × DIN模型 → ~20ms
优化手段:
├── GPU推理 (TensorRT)
├── 特征预计算 (用户特征缓存)
├── 模型量化 (FP16)
└── 批处理 (Batch inference)
5.4 Stage 4: 重排 (Re-Ranking)
重排: 精排之后的业务调整层
为什么需要重排:
精排只优化点击/转化, 但业务还需要:
├── 多样性: 不能推10个手机壳
├── 新鲜度: 用户看过的不要再推
├── 公平性: 给新商品/小品牌曝光机会
├── 运营干预: 促销商品置顶
└── 库存: 过滤无库存商品
重排规则:
Rule 1: 多样性保证 (MMR — Maximum Marginal Relevance)
算法:
每次从候选集中选一个商品加入推荐列表
选择标准: λ × relevance - (1-λ) × max_similarity_to_selected
λ=0.7 (偏向相关性) / λ=0.5 (平衡多样性)
效果:
类目去重: 同一类目最多3个
品牌去重: 同一品牌最多2个
价格多样: 高中低价格带都有
Rule 2: 曝光过滤
├── 用户24h内已见过的商品不再推
├── 用户已购买的商品不再推(除非是消耗品)
└── 用户标记"不感兴趣"的商品永久过滤
Rule 3: 运营置顶
├── 促销商品 → Position 1-3
├── 新品推广 → 混入前10位
└── 品牌广告 → 标记为"推广"并插入
Rule 4: 库存和物流过滤
├── 无库存 → 移除
├── 用户所在区域无法配送 → 移除
└── 预售商品 → 标记预售标签
Rule 5: 上下文适配
├── 早上推荐早餐/咖啡
├── 周末推荐休闲/户外
├── 下班时间推荐外卖/娱乐
└── 节日推荐礼品/节日用品
六、实时特征系统
实时特征 — 推荐系统的"新鲜血液"
为什么需要实时特征:
场景: 用户刚搜了"运动鞋" → 立刻推荐运动鞋
如果用离线特征: 要等到第二天模型更新才能反映
用实时特征: 秒级反映用户最新意图
实时特征架构:
User Action (click/buy/search)
│
┌────▼────┐
│ Kafka │ (Event Stream)
└────┬────┘
│
┌────▼────────────────┐
│ Flink / Spark │ (Stream Processing)
│ Streaming │
│ ├── 实时点击计数 │
│ ├── 实时行为序列 │
│ ├── 滑动窗口统计 │
│ └── 用户意图识别 │
└────┬────────────────┘
│
┌────▼────┐
│ Redis │ (Feature Store - Online)
│ ├── user:{id}:recent_clicks: [item1,item2,...]
│ ├── user:{id}:recent_search: ["运动鞋","耐克"]
│ ├── user:{id}:session_stats: {clicks:5, cart:2}
│ └── item:{id}:realtime: {ctr_1h: 0.05, views_1h: 1200}
└─────────┘
Feature Store设计 (Feast / 自研):
离线特征 (Offline Features):
更新频率: 每天/每小时
存储: Hive/S3 → 推送到Redis
例: 用户30天购买次数, 商品30天平均评分
近线特征 (Nearline Features):
更新频率: 分钟级
存储: Flink → Redis
例: 用户1小时内点击类目分布, 商品实时CTR
实时特征 (Realtime Features):
更新频率: 秒级
存储: Redis (在线请求时实时计算)
例: 用户当前session的行为序列, 当前搜索词
Feature Serving:
推荐请求进来 →
1. 从Redis获取用户实时特征 (~1ms)
2. 从Redis获取候选商品特征 (~2ms, batch get)
3. 拼接特征向量 → 送入模型
总Feature Serving延迟: < 5ms
七、LLM增强推荐系统
2025-2026: LLM正在改变推荐系统
传统推荐 vs LLM增强推荐:
传统推荐:
├── 输入: 用户ID + 行为ID序列 + 数值特征
├── 模型: 专门的推荐模型(DIN/DCN)
├── 输出: 分数(0-1)
└── 局限: 不理解语义, 不能解释, 冷启动差
LLM增强推荐:
├── 输入: 用户画像描述 + 商品文本描述 + 行为上下文
├── 模型: LLM (理解语义和意图)
├── 输出: 推荐理由 + 排序
└── 优势: 语义理解, 可解释, 冷启动好
LLM在推荐中的5个应用点:
1. 语义理解增强 (Feature Enhancement):
传统: item_id → learned embedding (不理解含义)
LLM: "Nike Air Max 270 男士跑步鞋 黑色 气垫缓震"
→ LLM Embedding (理解语义)
实现:
离线: 用LLM为每个商品生成语义Embedding
在线: 使用缓存的Embedding, 不增加延迟
效果: 冷启动商品推荐质量提升30%+
2. 推荐理由生成 (Explanation):
传统: "猜你喜欢" (没有解释)
LLM: "因为您最近购买了跑步鞋, 为您推荐这款专业运动袜,
材质透气排汗, 与您的Nike跑鞋搭配更佳"
实现:
Input: 用户行为 + 推荐商品 + 推荐原因(from model)
LLM: 生成自然语言解释
注意: 延迟敏感 → 预生成 or 异步生成
效果: CTR提升5-10% (用户更信任有理由的推荐)
3. 对话式推荐 (Conversational Recommendation):
传统: 用户只能浏览, 被动接受推荐
LLM:
用户: "我想给老婆买个生日礼物, 她喜欢瑜伽"
LLM: 理解意图(礼物+女性+瑜伽爱好者)
→ 推荐瑜伽垫/运动服/冥想APP礼品卡
→ 还能追问: "她有瑜伽垫了吗? 预算多少?"
实现:
LLM理解用户意图 → 生成结构化query → 调用推荐系统 → 格式化结果
效果: 搜索转化率提升15-20%
4. 用户画像生成 (User Profiling):
传统: 统计特征 (购买次数/类目分布/价格偏好)
LLM: 基于行为历史生成自然语言画像
"这是一位25-30岁的都市女性, 注重品质生活,
偏好运动健身类商品, 客单价在200-500元,
对促销敏感度低, 品牌忠诚度高(Nike/Lululemon)"
用途:
├── 作为LLM推荐的上下文
├── 运营参考(用户分群)
└── 冷启动迁移(新平台快速建画像)
5. Cross-domain推荐 (跨域推荐):
传统: 电商推荐只能用电商数据
LLM: 理解跨域语义关系
用户在视频平台看了"瑜伽教程"
→ LLM理解 → 在电商推荐瑜伽用品
前提: 需要跨平台数据打通(隐私合规)
LLM增强的架构位置:
传统四阶段 Pipeline:
召回 → 粗排 → 精排 → 重排
LLM增强后:
召回 → 粗排 → 精排 → 重排 → [LLM Explanation]
↑ ↑
└── LLM Semantic Embedding └── LLM生成推荐理由
注意: LLM不替代传统Pipeline, 而是增强
原因: LLM太慢/太贵, 不适合处理100K QPS
八、AB实验系统
AB实验 — 推荐系统的"发动机"
为什么AB实验如此重要:
推荐系统的每一个改进都需要验证:
├── 新模型是否比旧模型好?
├── 新特征是否有用?
├── 新策略是否提升业务指标?
└── 没有AB实验 = 盲人开车
AB实验架构:
用户请求
│
┌───▼───┐
│ 分流 │ → 根据user_id hash分配到实验组
│ 层 │ Experiment A: 30% / Control: 70%
└───┬───┘
│
┌───▼───┐
│ 推荐 │ → 实验组用新模型, 对照组用旧模型
│ 服务 │
└───┬───┘
│
┌───▼───┐
│ 指标 │ → 收集两组的CTR/CVR/GMV
│ 收集 │
└───┬───┘
│
┌───▼───┐
│ 统计 │ → 统计显著性检验 (p-value < 0.05)
│ 分析 │ → 置信区间 / 效果大小
└───────┘
分层实验:
推荐系统通常有多个实验同时运行
需要"正交分层"确保实验互不干扰
Layer 1: 召回层实验 (测试不同召回策略)
Layer 2: 排序层实验 (测试不同排序模型)
Layer 3: 展示层实验 (测试不同UI/推荐理由)
每层独立分流:
用户A: Layer1-Control + Layer2-ExpB + Layer3-ExpA
用户B: Layer1-ExpA + Layer2-Control + Layer3-ExpB
关键指标:
核心指标 (Primary Metrics):
├── CTR: 点击率 (用户参与度)
├── CVR: 转化率 (购买转化)
└── GMV: 交易额 (商业价值)
护栏指标 (Guardrail Metrics):
├── DAU: 不能因为推荐变差导致用户流失
├── 多样性: Shannon Entropy > threshold
├── 新商品曝光率: > 5%
└── 用户投诉率: 不能上升
实验周期:
最少7天(覆盖一周行为模式)
大促期间暂停实验(数据不稳定)
九、冷启动解决方案
冷启动 — 推荐系统的永恒难题
新用户冷启动:
阶段1 (0次行为):
├── 热门推荐 (按地区/时间/设备)
├── 引导用户选择兴趣标签
└── 利用注册信息(年龄/性别/来源渠道)
阶段2 (1-5次行为):
├── 基于少量行为的简单CF
├── 利用Bandit算法探索(Explore vs Exploit)
└── LLM理解用户前几次行为的语义意图
阶段3 (5+次行为):
├── 正常推荐Pipeline生效
└── 随着数据累积, 个性化越来越准
新商品冷启动:
├── 利用商品属性(类目/品牌/价格/描述)
│ → 找到属性相似的已有商品, 借用其用户群
├── LLM语义Embedding
│ → 不需要行为数据, 基于文本描述生成Embedding
├── 新品流量池
│ → 给新商品分配一定的曝光quota
│ → 快速收集行为数据
└── Bandit探索
→ EE策略: 给不确定的商品更多曝光机会
Explore vs Exploit (探索与利用):
Exploit: 推荐已知用户喜欢的(高CTR, 低风险)
Explore: 尝试新的/不确定的(低CTR, 但可能发现新兴趣)
算法:
ε-Greedy: 90%时间Exploit, 10%时间Explore
Thompson Sampling: 基于置信区间的概率探索
LinUCB: 上下文Bandit, 利用特征做智能探索
十、常见追问及应答
追问 1: "如何处理100K QPS?"
回答:
推荐系统的高并发策略:
1. 预计算 (Offline Pre-compute):
离线为每个活跃用户预计算推荐列表
存入Redis/Memcached
在线直接读取, < 1ms
→ 适用首页推荐(变化不频繁)
2. 多级缓存:
L1: 本地缓存 (服务器内存, ~10ms TTL)
L2: Redis集群 (分布式, ~1ms)
L3: 实时计算 (回退方案)
命中率: L1 ~30%, L2 ~50%, L3 ~20%
3. 水平扩展:
推荐服务无状态, 可任意扩展
100K QPS / 5K per instance = 20 instances
峰值预备: 30-40 instances (auto-scaling)
4. 降级策略:
正常: 四阶段完整Pipeline
高负载: 跳过精排, 用粗排结果
极端: 直接返回预计算列表
兜底: 返回热门推荐(永远有值)
追问 2: "推荐结果的多样性怎么保证?"
回答:
三个层面:
1. 召回层多样性:
多路召回本身就带来多样性
CF召回偏好相似品, 规则召回带来新类目
2. 重排层多样性 (MMR):
贪心选择: 每次选relevance最高且与已选最不相似的
约束: 同类目≤3个, 同品牌≤2个, 同价格带混合
3. 用户级别多样性:
跨Session去重: 不重复推荐
类目滑动窗口: 最近推了太多某类 → 降低该类权重
Novelty Score: 推荐用户没见过的新类型
指标:
Intra-list Diversity: 单次推荐列表内的多样性
Inter-list Diversity: 跨多次请求的多样性
Coverage: 推荐系统覆盖了多大比例的商品库
追问 3: "如何防止推荐茧房(Filter Bubble)?"
回答:
推荐茧房 = 用户只看到自己喜欢的, 视野越来越窄
防止策略:
1. 强制Explore配额:
每次推荐列表中, 20%是探索性推荐
来自用户没接触过的类目/风格
2. 兴趣拓展:
从用户已有兴趣出发, 推荐"近邻"类目
例: 喜欢跑步 → 推荐瑜伽/登山(运动近邻)
而不是直接推美食(太远, 用户不接受)
3. 社交信号:
"你的朋友也在看..." → 引入社交维度
打破个人兴趣的封闭循环
4. 时间衰减:
旧兴趣权重随时间下降
鼓励推荐系统发现用户的新兴趣
5. 监控指标:
Interest Diversity Score: 用户接触的类目数
New Category Rate: 用户点击新类目的比率
设定下限, 低于阈值时增加Explore比例
追问 4: "如何评估推荐系统的整体效果?"
回答:
离线评估 + 在线评估 双管齐下:
离线评估 (开发阶段):
├── AUC: 排序质量 (越接近1越好)
├── NDCG: 排序列表质量 (考虑位置)
├── Recall@K: 在Top-K中召回了多少正样本
├── Hit Rate: 用户是否点击了推荐的商品
└── 局限: 离线指标好 ≠ 在线效果好
在线评估 (AB实验):
├── CTR: 核心参与指标
├── CVR: 核心转化指标
├── GMV per User: 核心商业指标
├── Session Duration: 用户停留时长
└── Return Rate: 次日/7日回访率
长期评估:
├── 用户LTV: 长期价值(推荐好→LTV高)
├── 用户流失率: 推荐差→用户离开
└── 生态健康: 商品覆盖率, 中小商家曝光
追问 5: "推荐系统和搜索系统的区别?"
回答:
┌───────────┬───────────────────┬────────────────────┐
│ │ 搜索 (Search) │ 推荐 (Recommend) │
├───────────┼───────────────────┼────────────────────┤
│ 触发方式 │ 用户主动(有query) │ 系统主动(无query) │
│ 用户意图 │ 明确(搜索词) │ 模糊(猜测兴趣) │
│ 核心挑战 │ 理解query意图 │ 理解用户偏好 │
│ 评估指标 │ NDCG / MRR │ CTR / CVR / GMV │
│ 时效性 │ 实时(秒级) │ 准实时(分钟级) │
│ 个性化 │ 中等 │ 强 │
│ 多样性 │ 低(集中在query) │ 高(需要覆盖面) │
└───────────┴───────────────────┴────────────────────┘
但两者正在融合:
├── 搜索越来越个性化(同搜索词不同人结果不同)
├── 推荐越来越有意图(基于实时行为推断意图)
└── LLM使两者进一步融合(对话式推荐≈自然语言搜索)
十一、面试评分要点
推荐系统设计评分标准:
Must-have (必须提到):
├── 四阶段架构 (召回→粗排→精排→重排)
├── 多路召回 (至少3种)
├── 精排模型选择和理由 (DIN/DCN/Wide&Deep)
├── 特征工程 (用户/商品/上下文/交叉特征)
├── 实时特征 (用户最新行为如何影响推荐)
└── AB实验 (如何验证效果)
Nice-to-have (加分):
├── LLM增强 (语义理解/解释/对话推荐)
├── 冷启动方案 (新用户/新商品)
├── 多样性控制 (MMR/去重/茧房防止)
├── 系统扩展性 (100K QPS方案)
└── 多目标优化 (CTR+CVR+GMV)
Key insight (核心洞察):
"推荐系统的核心挑战不是模型多复杂,
而是如何在200ms内, 从5000万商品中
找到用户此刻最想要的20个."
十二、今日总结
Day 46 核心收获:
1. 四阶段架构:
召回(广)→ 粗排(快)→ 精排(准)→ 重排(调)
每层解决不同问题, 逐层漏斗
2. 推荐 vs 前三天的AI系统:
LLM平台: 核心是Router+Cost → 中等QPS
RAG: 核心是Retrieval Quality → 低QPS
Agent: 核心是Planning+Safety → 低QPS
推荐: 核心是Latency+Scale → 超高QPS(100K)
3. LLM正在改变推荐:
不是替代传统Pipeline, 而是增强
语义理解 + 推荐解释 + 对话推荐 + 冷启动
4. 面试关键:
画四阶段架构 → 深入精排模型 → 讲实时特征 → AB实验
对于PM角色: 多讲业务指标和AB实验
对于架构角色: 多讲系统扩展和特征工程
Phase 4系统设计面试四连击完成!
Day 43: 企业LLM平台 ✅
Day 44: 生产级RAG系统 ✅
Day 45: AI Agent系统 ✅
Day 46: 推荐系统 ✅
明天开始: Day 47-49 — 产品/架构面试模拟
参考资源: