Amazon 的 Applied Scientist(AS)岗位面试有个鲜明特点:几乎每一轮都会插入 Leadership Principles(LP)行为题,光靠刷题和啃机器学习理论是不够的,必须提前打磨几个能被随意深挖细节、追问到底的真实项目故事。下面按流程拆解各轮考察重点,L4/L5/L6 在行为面试上的权重差异也会一并说明,其他岗位方向同样能参考。需要 VO辅助 或 VO代面 的同学,也可以照着这份复盘对齐节奏。
AS 面试流程概览
| 阶段 | 时长 / 形式 | 核心考察 |
|---|---|---|
| 电话面 | 45–60 分钟 | 一道 LeetCode 难度算法 + ML 基础问答 + 1–2 道 LP |
| Onsite 第一轮 | Coding + LP | 数据处理题(哈希表 + 手写堆)+ 业务开放题 |
| Onsite 第二轮 | Case Study + LP | 优化理论手写 + 运筹建模 + 系统设计 |
| Onsite 第三轮 | 纯 Coding + Ownership | OOD 面向对象设计 |
| Onsite 第四轮 | ML Application + LP | ML 系统设计(HM 主持) |
| Onsite 第五轮 | Bar Raiser | Leadership Principles 总攻 |
一个贯穿始终的规律:每一轮基本都会留出约 15 分钟问一到两个行为题,所以 LP 准备绝不能只压到最后一轮。
电话面:算法 + ML 基础的组合拳
Phone Screen 是进 Onsite 的门槛,通不过 Recruiter 就不会继续排后面的 Loop。这一轮的配方通常是:一道 LeetCode 难度的算法题,加机器学习基础知识问答,外加一两个 LP 行为题当调味。
面试官往往会顺着简历项目往深处挖,常见考点包括:
- 数据严重不平衡时怎么处理,评估该用 Precision / Recall / F1 还是 ROC-AUC
- SFT 训练流程和 Loss 设计
- Bias-Variance 如何权衡,过拟合怎么判断、怎么治
- Bagging 和 Boosting 的本质区别
真正拉开差距的是这道场景选择题:给定不同的分类任务,Logistic Regression、Decision Tree、Random Forest、DNN 该怎么挑?光背模型特点不够,还得结合数据量、特征类型、非线性程度、可解释性要求和推理成本这几个维度综合判断,讲出取舍逻辑才算过关。
BQ 环节固定两道,且都会被继续往技术细节里追问(当时发现了什么问题、怎么定位的、为什么选这个方案、结果如何量化):
- 一次主动接下职责外的任务,事后才发现自己经验不足的经历
- 一次靠深入分析揪出问题根因并解决的经历
这提示一个关键点:准备项目和 BQ 故事时不能只背 STAR 框架的空壳,技术原理、方案对比和最终的量化结果都要一起理顺,否则追问两轮就露馅。
Onsite 第一轮:Coding + LP
两位 Senior AS 面试官联合面试。流程是自我介绍 → 项目细节深挖(为什么这么选)→ 结合你的研究方向和岗位业务方向做联想。这一轮追问深度不如电话面。
两道 BQ:如何应对紧迫的 deadline,如何做到刨根问底(Dive Deep)。之后会抛一个业务开放题——不用写代码,只讲思路:做交易类业务时哪些 feature 最关键,怎么用机器学习筛出容易导致 deal 失败的那些特征。
编码题:活跃度最低的 K 个用户
给一批日志数据,每条是 (user_id, timestamp)。算出每个用户在指定时间段内的活跃天数(去重后的日期数),找出活跃度最低的 5 个用户。
表面看是哈希表计数的简单题,但面试官会追加约束——数据量极大时如何做内存优化。最优解是哈希表配合最小堆:遍历一遍统计每个用户的活跃天数集合大小,再用一个大小为 K 的最小堆维护「当前活跃度最低的 K 个」。而且现场禁用 heapq,要求手写堆结构和上浮 / 下沉调整逻辑。
思路拆解:
- 用哈希表
user -> set(day)去重统计每个用户的活跃天数;只保留计数,day集合可边扫边丢以省内存。 - 维护一个最小堆,堆里放
(活跃天数, user)。这里要找「最低的 K 个」,用最小堆的技巧是:堆顶始终是已入堆里最小的,我们让堆按count升序,最终堆中较小的若干个就是答案。为控制内存在 O(K),也可反向用「大小为 K 的最大堆」淘汰较大值——下面给出最直接的手写最小堆全量建堆版本。
class MinHeap:
"""手写最小堆,按元素第 0 位(count)比较。禁用 heapq 时使用。"""
def __init__(self):
self.data = []
def _swap(self, i, j):
self.data[i], self.data[j] = self.data[j], self.data[i]
def push(self, item):
self.data.append(item)
self._sift_up(len(self.data) - 1)
def pop(self):
top = self.data[0]
last = self.data.pop()
if self.data:
self.data[0] = last
self._sift_down(0)
return top
def _sift_up(self, i):
while i > 0:
parent = (i - 1) // 2
if self.data[i][0] < self.data[parent][0]:
self._swap(i, parent)
i = parent
else:
break
def _sift_down(self, i):
n = len(self.data)
while True:
left, right, smallest = 2 * i + 1, 2 * i + 2, i
if left < n and self.data[left][0] < self.data[smallest][0]:
smallest = left
if right < n and self.data[right][0] < self.data[smallest][0]:
smallest = right
if smallest == i:
break
self._swap(i, smallest)
i = smallest
def __len__(self):
return len(self.data)
def least_active_users(logs, k=5):
"""logs: List[(user_id, timestamp)];timestamp 为秒级 epoch。
返回活跃天数最低的 k 个 user_id。"""
day_sets = {}
for user, ts in logs:
day = ts // 86400 # 归一到「天」
day_sets.setdefault(user, set()).add(day)
heap = MinHeap()
for user, days in day_sets.items():
heap.push((len(days), user)) # (活跃天数, user)
result = []
for _ in range(min(k, len(heap))):
count, user = heap.pop()
result.append(user)
_ = count
return result
时间复杂度:统计 O(N),建堆并弹出 K 个为 O(M + K log M),M 为用户数、N 为日志条数。空间复杂度:O(M)。若内存吃紧,可把最小堆换成「维护大小为 K 的最大堆」,边扫边淘汰,空间压到 O(K)。
Onsite 第二轮:Case Study + 优化理论(Principal AS 技术面)
这轮先从项目深挖切入,再转向优化理论的硬核考察:
- 手写梯度下降,讲清学习率、收敛条件、停止标准
- 手写 KNN,讨论距离度量方式、K 值选择和查询复杂度
- 牛顿法的原理,与梯度下降在收敛速度和计算成本上的差异
- 为什么凸优化问题更容易求全局最优,哪些问题有闭式解
- 原问题与对偶问题的关系,KKT 条件包含哪些内容、适用场景
这里给一份现场可手写的梯度下降参考实现,用最基础的线性回归 MSE 作载体:
import numpy as np
def gradient_descent(X, y, lr=0.01, max_iter=1000, tol=1e-6):
"""最小化 MSE 的批量梯度下降。
X: (n, d),y: (n,)。返回权重 w 与偏置 b。"""
n, d = X.shape
w = np.zeros(d)
b = 0.0
prev_loss = float("inf")
for it in range(max_iter):
pred = X @ w + b
error = pred - y
loss = np.mean(error ** 2) # MSE
grad_w = (2.0 / n) * (X.T @ error) # 对 w 的梯度
grad_b = (2.0 / n) * np.sum(error) # 对 b 的梯度
w -= lr * grad_w
b -= lr * grad_b
if abs(prev_loss - loss) < tol: # 收敛:损失不再显著下降
break
prev_loss = loss
return w, b
时间复杂度:每轮 O(n·d),共 T 轮为 O(T·n·d)。停止标准通常是「损失变化 < tol」或「达到最大迭代数」,学习率过大会震荡不收敛、过小则收敛太慢。
紧接着是一道运筹优化建模题:为配送中心设计补货计划,在需求、供应量、仓储容量约束下最小化运输和库存成本,Follow-up 追问商品动态加价时目标函数和最优策略如何变化。
Case Study 部分是设计一套生鲜配送系统,同时解决车辆路径规划和到达时间预测,要考虑实时交通、时间窗口、保质期和车辆容量限制。追问会落到模型训练和评估上——路径优化关注总里程、成本、准时率;时间预测则用 MAE、RMSE 和延迟订单比例衡量,Precision / Recall 在这个场景并不适用,需要现场辨析清楚。最后收尾在三维装箱问题:给定货物尺寸、重量和卡车空间,如何摆放提升装载率,同时满足承重、方向、堆叠约束。
Onsite 第三轮:纯 Coding(穿插一道 Ownership 行为题)
面试官简单问了一道关于 Ownership 的行为题后直接进入编码。题目是 OOD 设计——一个物品租赁系统,需要实现 Item、User、Rental 等实体类,通过 Manager 类提供借出、归还、查询接口。
题目本身难度不高,考察重点在于类的职责划分是否清晰、对象关系是否合理、代码是否留有扩展空间。Follow-up 层层加码:增加租赁到期时间和逾期罚金逻辑、支持按名称模糊搜索、提供返回完整目录的接口、以及如何设计单元测试。整体考的是面向对象建模能力和接口设计,不是算法技巧。
from dataclasses import dataclass, field
from typing import Dict, List, Optional
@dataclass
class Item:
item_id: int
name: str
available: bool = True
@dataclass
class User:
user_id: int
name: str
@dataclass
class Rental:
item_id: int
user_id: int
due_day: int
returned_day: Optional[int] = None
class RentalManager:
"""租赁系统入口:借出、归还、搜索、目录、逾期罚金。"""
LATE_FEE_PER_DAY = 5
def __init__(self):
self.items: Dict[int, Item] = {}
self.users: Dict[int, User] = {}
self.rentals: List[Rental] = []
def add_item(self, item: Item) -> None:
self.items[item.item_id] = item
def add_user(self, user: User) -> None:
self.users[user.user_id] = user
def borrow(self, user_id: int, item_id: int, due_day: int) -> bool:
item = self.items.get(item_id)
if item is None or not item.available or user_id not in self.users:
return False
item.available = False
self.rentals.append(Rental(item_id, user_id, due_day))
return True
def give_back(self, user_id: int, item_id: int, today: int) -> int:
"""归还并返回应缴逾期罚金(未逾期为 0)。"""
for r in self.rentals:
if r.item_id == item_id and r.user_id == user_id and r.returned_day is None:
r.returned_day = today
self.items[item_id].available = True
overdue = max(0, today - r.due_day)
return overdue * self.LATE_FEE_PER_DAY
raise ValueError("没有匹配的未归还租赁记录")
def search(self, keyword: str) -> List[Item]:
kw = keyword.lower()
return [it for it in self.items.values() if kw in it.name.lower()]
def catalog(self) -> List[Item]:
return sorted(self.items.values(), key=lambda it: it.item_id)
设计要点:Manager 持有实体的字典索引以支持 O(1) 查找;借出 / 归还只翻转 available 标志并追加记录,便于后续扩展预约队列、多副本库存等。逾期罚金用 due_day 与归还日的差值计算,接口保持单一职责,方便写单元测试。
Onsite 第四轮:ML Application + LP(Hiring Manager 主持)
偏机器学习系统设计,题目围绕广告推荐、CTR 预估等真实业务场景。回答建议按固定顺序展开:需求澄清 → 数据与特征 → 模型选型 → 训练与离线评估 → 在线部署 → 监控与 A/B 测试。
注意:L4 候选人不一定会被安排这一轮。这轮考察的是 ML 知识的广度,覆盖范围可以从线性回归一路延伸到 Transformer,常见考点包括 L1 / L2 正则化、过拟合、梯度消失、损失函数设计和 Transformer 原理。复习时别只背定义,要能讲清楚每个方法的适用场景和优缺点,面试官很爱追问「什么时候不该用这个」。
Onsite 第五轮:Bar Raiser(LP 总攻)
这轮由不属于招聘团队的 Bar Raiser 主持,专注考察 Leadership Principles,对最终是否发 Offer 的影响力很大。但要清楚一点:前面每一轮基本都会留出约 15 分钟问一到两个行为题,所以 LP 准备绝不能只留到最后一轮才做。
L4 / L5 / L6 行为面权重差异
| 级别 | LP 深度 | 侧重的 LP 维度 |
|---|---|---|
| L4 | 讲清楚一次完整经历即可,追问一层 | Learn and Be Curious、Ownership |
| L5 | 需要体现跨团队协作与技术决策,追问两到三层 | Dive Deep、Deliver Results、Earn Trust |
| L6 | 要求战略视野、影响力和带人带项目 | Think Big、Have Backbone、Hire and Develop |
级别越高,面试官越想看到你在更大范围内的影响力和面对分歧时的判断力,故事的量级和复杂度要相应升级。
备考建议
- 项目故事技术化:每个 STAR 故事都要能被追问两三层——发现了什么、怎么定位、为什么选这个方案、结果如何量化,技术原理和数据结果一起理顺。
- 手写基础算法:梯度下降、KNN、堆结构要能现场从零手写,不能依赖
heapq、sklearn这类库。 - ML 广度 + 取舍:模型选型题重在讲清「什么时候不该用」,结合数据量、可解释性、推理成本作答。
- LP 覆盖全 Loop:准备 8–10 个可复用故事,覆盖 Ownership、Dive Deep、Deliver Results 等核心维度,因为每轮都会问。
- 优化理论:凸优化、对偶、KKT、牛顿法这些偏理论的点,AS 岗位会真考,别只停在会用框架的层面。
FAQ
Q1:Amazon AS 面试和 SDE 面试最大的区别是什么?
AS 在算法之外额外考 ML 基础、优化理论和 ML 系统设计,且行为题会往技术细节深挖。SDE 更偏纯算法与系统设计,ML 理论占比很低。AS 候选人必须同时准备 Coding、ML 理论和 LP 三条线。
Q2:电话面的算法题难度如何?
通常是一道 LeetCode 中等偏难的题,外加 ML 基础问答和 LP。算法本身不会特别刁钻,但会追加内存优化、手写数据结构等约束,考的是你能否在压力下把最优解讲清楚并实现。
Q3:Applied Scientist 每一轮都会问行为题吗?
基本是的。除了 Bar Raiser 专攻 LP,前面每一轮都会留 10–15 分钟问一到两个行为题。所以 LP 准备要贯穿整个 Loop,不能只压到最后一轮。
Q4:L4、L5、L6 在面试上有什么不同?
级别越高,行为面越看重跨团队影响力、战略视野和带人带项目的经历,追问层数更多;技术面则期待更成熟的系统设计和更深的理论掌握。L4 可能不安排 ML 系统设计专场,L5/L6 通常会有。
Q5:现场禁用 heapq 之类的库怎么办?
提前把最小堆 / 最大堆的上浮、下沉逻辑手写练熟,梯度下降、KNN 也要能从零实现。面试官禁用库就是想看你对底层数据结构和算法的真实掌握,背 API 没用。
正在准备 Amazon Applied Scientist 或其他 ML / AS 岗位的 VO? 我们熟悉 AS 这类「算法 + ML 理论 + 优化 + LP」多线并考的 Loop 打法,能陪你把项目故事技术化、手写算法和 LP 覆盖一次打磨到位,提供全程 VO辅助 与 VO代面 支持。
立即添加微信 Coding0201,获取一对一定制备考方案。
联系方式
- 微信:Coding0201
- Email:[email protected]
- Telegram:@OAVOProxy