TikTok Data Engineer 面经|TikTok NG 面试全流程
TikTok Data Engineer NG 面试全流程:简历深挖(Flink checkpoint、状态膨胀、back pressure)、两道 SQL(DAU 日增长率、creator engagement 排名与大表 JOIN 优化)、一道 Python 日志行为模式题,附 SQL 与 Python 参考实现。
面试概况
一般 60 分钟,分三部分:聊简历 + 两道 SQL + 一道 Python。
面试官可能在 San Jose,也可能在国内:
| 面试时间 | 面试官 |
|---|---|
| PT 下午 6 点之后 | 一般是国内面试官,100% 讲中文 |
| PT 下午 6 点之前 | 一般是美国面试官,小概率讲中文 |
Part 1:Resume Deep Dive
以候选人讲为主,没有特定考点。只要项目和 data engineering 相关、并且自己足够熟悉,就没什么问题。
一个真实案例:面试官让候选人从项目里挑一个最能体现数据工程能力的例子。候选人讲了一个基于 Kinesis + Flink 的实时用户行为分析系统,介绍了从数据采集、实时计算到下游入库的整体链路。
面试官的追问:
- Flink checkpoint 延迟或状态膨胀怎么办? 回答:调整 RocksDB state backend、控制 checkpoint 频率,以及给状态数据设置 TTL,避免状态积压。
- 流处理任务出现 back pressure 时如何排查?
back pressure 排查参考:先在 Flink Web UI 看哪个算子被标红(背压从下游往上游传,找到第一个处理不过来的算子);再看这个算子是 CPU 打满、数据倾斜(某些 subtask 特别慢),还是下游 sink 写入慢;对应地加并行度、打散热点 key,或者给 sink 做批量写入、异步写入。
Part 2:SQL 实战(HackerRank)
两道 SQL,难度中等,更注重分析的清晰度和优化思路。
第一题:每日活跃用户与日增长率
根据用户事件表计算每天的活跃用户数(DAU),并统计相比前一天的增长率。
WITH daily AS (
SELECT DATE(event_time) AS dt,
COUNT(DISTINCT user_id) AS dau
FROM events
GROUP BY DATE(event_time)
)
SELECT dt,
dau,
ROUND(100.0 * (dau - LAG(dau) OVER (ORDER BY dt))
/ LAG(dau) OVER (ORDER BY dt), 2) AS growth_pct
FROM daily
ORDER BY dt;
LAG() 窗口函数取前一天的 DAU,第一天没有前一天,增长率为 NULL。
追问:大规模数据下怎么优化?按日期字段做表分区,查询时带上日期范围过滤,避免全表扫描。
第二题:Engagement 最高的 Creator
从多张表 JOIN,计算过去一段时间内 engagement 得分最高的 creator。下面假设得分 = 点赞 × 1 + 评论 × 2 + 分享 × 3,面试时要先和面试官确认得分规则和时间范围(日期函数以 SQLite 为例,MySQL / Hive 等写法略有不同,比如 DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)):
WITH recent AS (
SELECT v.creator_id,
SUM(CASE e.event_type WHEN 'like' THEN 1
WHEN 'comment' THEN 2
WHEN 'share' THEN 3 ELSE 0 END) AS score
FROM engagements e
JOIN videos v ON v.video_id = e.video_id
WHERE e.event_time >= DATE('2026-10-01', '-7 days')
GROUP BY v.creator_id
)
SELECT c.creator_name,
r.score,
RANK() OVER (ORDER BY r.score DESC) AS rnk
FROM recent r
JOIN creators c ON c.creator_id = r.creator_id
ORDER BY rnk, c.creator_name;
先在大表里聚合、再 JOIN 小表(creators),比先 JOIN 再聚合省很多计算量。
追问:事件表达到亿级,大表 JOIN 怎么优化?
- 小表(比如 creators)用 broadcast join,避免大表 shuffle。
- 预先维护按天的 summary 表,查询时只聚合汇总数据。
- 分布式环境下,配合窗口函数和 CTE 简化查询逻辑。
Part 3:Python 编程题(HackerRank)
难度低于 SDE 面试。题目要求在一组用户日志里,找出满足特定行为模式的用户,比如连续执行相同行为达到一定次数。
解法:先按用户分组、按时间排序,再单次遍历统计连续出现的行为次数,时间复杂度 O(n log n)。
from collections import defaultdict
def users_with_streak(logs, k):
"""logs: [(user_id, timestamp, action)];返回连续 k 次(或更多)相同行为的用户"""
by_user = defaultdict(list)
for user, ts, action in logs:
by_user[user].append((ts, action))
result = set()
for user, events in by_user.items():
events.sort() # 按时间排序
streak, prev = 0, None
for _, action in events:
streak = streak + 1 if action == prev else 1
prev = action
if streak >= k:
result.add(user)
break
return result
Follow-up(感觉是面试官临时想的):
- 日志是乱序到达的分布式数据流,怎么保证处理顺序? 用时间分桶 + watermark 控制乱序日志的等待窗口,在窗口内重新排序后再处理。
- 数据量太大,不能一次性加载进内存怎么办? 用流式处理,或者外部排序(先按 user 分片、分批排序)分批计算。
看完有收获? 欢迎交流。
交流面经、互相 mock、内推信息,都可以找我。
