面试问题
数据工程师面试问题
练习 SQL 转换、数据建模、ETL 流水线、任务编排、批处理与流处理、Spark、数据质量、可观测性和系统设计等数据工程师面试题。 如需系统备考,请同时阅读 数据工程师面试指南。
21 道题
8 个类别
数据工程师
更新于 2026年5月
SQL 与数据转换面试题
数据工程师 SQL 面试通常关注正确性和生产可用性:数据粒度、去重、增量逻辑、窗口函数、分区和性能。
回答框架: 使用窗口函数和确定性的排序规则
使用窗口函数在每个 event_id 分区内分配行号,按最可靠的新旧顺序字段降序排列,例如 ingestion_timestamp 或 updated_at。如果可能并列,再加上 source_sequence_number 或 raw_file_name 等确定性的次级排序键。 查询模式是:选取所有行,计算 row_number() over(partition by event_id order by ingestion_timestamp desc, source_sequence_number desc),再筛选行号等于 1 的记录。 面试中的重点是结果必须确定。如果两条记录时间戳相同且没有次级排序键,不同运行可能得到不同结果。还应澄清“最新事件”指最新入库时间、最新事件发生时间,还是最新源系统更新时间。 在生产环境中,我会监控重复率、延迟到达事件、event_id 为空的数量,以及去重是否意外改变下游指标。
可能的追问
如果 event_id 缺失呢?
如何处理延迟到达的更正记录?
如果采用增量处理,你会如何调整?
回答框架: 筛选活跃事件 → 统一日期 → 按日期和用户分组
先定义什么是活跃用户。通常并非所有事件都应计入。页面浏览、机器人事件、后台刷新和内部用户可能需要排除;应根据产品选择 session_start、purchase、message_sent 或 feature_used 等有意义的事件。 转换流程筛选有效事件,把事件时间戳转换为业务时区,按 activity_date 和 user_id 分组,每个活跃用户每天输出一行。如果最终表是汇总表,则按天计算去重用户数;如果是供下游使用的明细模型,可保存日期、user_id、平台、国家和首次活跃时间。 生产环境还要考虑时区、延迟到达事件、机器人与测试账户过滤、已删除用户、重复事件,以及按 activity_date 分区。增量构建时应重新处理最近几个分区,以捕获迟到事件,而不只处理当天。 好的回答还包括验证:将日活与源事件量对比,监控逐日变化,并检查各细分群体是否一致。
可能的追问
哪些事件应计为活跃?
如何处理延迟到达的事件?
日活应该做成一张表,还是通过指标查询计算?
回答框架: 影响范围 → 查询计划 → 数据增长 → 表关联 → 分区 → 近期变更
先判断问题只影响这条查询,还是影响整个数仓或基础设施。如果很多查询都变慢,可能是集群容量、数仓负载或服务退化;如果只有一条变慢,应检查查询本身和数据。 查看近期变化:表规模增长、模式变更、新增关联、筛选条件变化、未能裁剪分区、统计信息过旧、数据倾斜、关联结果行数暴涨,或增加了 DISTINCT/ORDER BY 操作。如可获取,检查查询执行计划。 常见原因包括以错误粒度关联、多对多关联、缺少日期筛选、扫描所有分区、效率低的窗口函数、大规模数据混洗,或在分区列上使用函数导致无法裁剪。 修复方式可能包括提前筛选、预先汇总、增加分区筛选、聚簇或排序、物化中间模型、更新统计信息、减少读取列,或修正关联逻辑。我还会监控运行时间、扫描字节数、行数和成本。
可能的追问
什么是分区裁剪?
表关联为什么会导致行数暴涨?
你会如何防止性能回退?
数据建模与数仓面试题
数据建模面试考查你能否设计清晰、可扩展、兼顾成本,并适用于分析、机器学习和运营报告的数据模式。
回答框架: 业务流程 → 事实表 → 维度表 → 粒度 → 指标
先识别核心业务流程:浏览、购物车、订单、支付、发货、退货、退款、库存和营销归因。根据使用方式,每个流程可能对应事实表或事件模型。 重要事实表包括一张订单一行的 fact_orders、一张订单中每件商品一行的 fact_order_items,以及 fact_payments、fact_refunds、fact_shipments 和 fact_inventory_snapshot。维度表包括 dim_customer、dim_product、dim_date、dim_store 或 dim_warehouse、dim_channel 和 dim_campaign。 明确声明粒度。按产品类别分析收入通常应使用订单明细粒度,而不是订单粒度;客户生命周期指标可能使用客户或订阅粒度;库存分析可能需要每日快照粒度。 建模时还要考虑客户或商品属性的缓慢变化、退款与取消、订单与商品层级的折扣、货币、税费、运费、访客结账和延迟到达数据。我会定义权威指标,并为财务、营销、产品和运营建立语义模型或数据集市。 验证包括将收入与财务数据对账、订单数与交易系统核对、退款额与支付数据核对,以及库存与仓储系统核对。
可能的追问
fact_order_items 的粒度是什么?
你会如何对退款建模?
如何处理产品类别随时间变化?
回答框架: 根据历史记录需求选择类型 1 或类型 2
选择取决于是否需要准确还原历史。类型 1 直接覆盖旧值,简单,适合只关心当前值的场景。类型 2 则为每次属性变更新增一条维度记录,保留历史,通常带有 effective_start_date、effective_end_date、current_flag 和代理键。 例如,客户所在地区从西部改为东部。类型 1 会把原记录更新为东部,历史收入报告因此可能把过去的西部收入错误归到东部。类型 2 保留旧的西部记录并新增东部记录,使事实表能按事件发生时对应的维度版本关联。 类型 2 会增加代理键、日期范围关联、延迟到达事实、当前与历史报告区分,以及维度表规模等复杂度。只有当报告确实需要反映事件发生时的属性,才值得这样做。 好的回答会先解释业务需求,再选择缓慢变化维度类型。
可能的追问
什么情况下使用类型 1 就足够?
事实表如何关联类型 2 维度?
延迟到达的事实如何处理?
回答框架: 治理与灵活性,对比查询简单性与性能
星型模式将事实与维度分开,适合需要可复用维度、一致指标、治理、清晰粒度和灵活分析的场景。它减少重复,也便于管理维度变化。 宽表适合某些高频分析、机器学习特征或仪表板,尤其在查询简单性和性能很重要时。它让使用者少写关联,但可能重复存储数据;如果多张宽表对同一指标各自定义,还会带来治理风险。 实践中,我通常维护规范的核心事实表与维度表,再按具体场景发布经过整理的数据集市或宽表。数仓基础应保持可信,而下游模型可针对用户需求优化。 最终选择取决于规模、使用者、商业智能工具行为、成本、延迟,以及业务定义变动频率。
可能的追问
哪一种更适合商业智能仪表板?
如何避免指标定义不一致?
什么是语义层?
数据管道设计与任务编排
数据管道面试考查你能否设计幂等、可观测、可恢复,且符合数据时效性与成本要求的工作流程。
回答框架: 抽取 → 原始数据落地 → 转换 → 验证 → 发布 → 监控
先明确要求:数据时效性、订单量、可接受延迟、源数据库负载限制、下游使用者,以及历史订单是否会被更正。 一种简单方案是用 updated_at 或 CDC 增量抽取订单,将原始数据落到对象存储或数仓原始表,再转换为暂存表,最后发布 fact_orders、fact_order_items 等模型化事实表。可使用 Airflow、Dagster、dbt Cloud 或托管工作流工具编排。 管道必须幂等。某个日期或批次重跑时,应确定性地替换或合并数据,而不是追加重复记录。谨慎使用水位标记,并重新处理一段回看窗口以捕获迟到更新。 验证包括行数、主键空值、重复订单 ID、收入总额、状态分布、数据时效性,以及与源系统对账。故障、异常数据量、高重复率或数据延迟都应触发提醒,并记录负责人和下游依赖。
可能的追问
为什么只看 updated_at 不一定足够?
如何避免加载重复订单?
你会如何回填过去两年的历史数据?
回答框架: 相同输入重跑仍产生相同输出
幂等的数据管道对同样输入运行多次,仍会产生相同的正确输出,不会增加重复记录或造成意外副作用。这很重要,因为管道可能失败、需要重试,也需要回填历史数据。 例如,不具幂等性的管道每运行一次,就把昨天的订单再次追加进去;故障后重试可能让收入翻倍。具幂等性的版本则会删除并替换目标分区、按主键合并,或写入临时表后原子切换。 幂等性依赖清晰的键、分区策略、确定性转换,以及谨慎处理副作用。它是生产数据工程最重要的概念之一,因为系统能否可靠恢复取决于此。
可能的追问
如何让只能追加写入的管道保持幂等?
什么是原子切换?
幂等性如何帮助历史回填?
回答框架: 检测 → 分类 → 保护 → 沟通 → 迁移
先通过模式注册中心、元数据检查、契约测试或接入校验自动发现变化,再分类:新增列、删除列、重命名列、类型变化、可空性变化,或语义变化。 可为空的新增列通常较安全;删除列、重命名和类型变化可能破坏下游转换与仪表板。语义变化尤其危险,因为模式看似合法,但字段含义已经改变。 通过保留原始数据、兼容性检查、提醒和关键数据源契约保护管道。对于破坏性变更,应与源系统负责人协调,更新转换,必要时回填,并沟通下游影响。 成熟的方案会包含数据契约、版本管理、血缘、测试和明确责任,避免模式变化悄悄污染分析结果。
可能的追问
什么是数据契约?
列的数据类型改变时如何处理?
如果源系统团队没有提前通知呢?
批处理与流处理系统
批处理与流处理面试题考查你是否理解延迟、吞吐量、顺序、状态、窗口、重放,以及简单架构与实时架构之间的运维取舍。
回答框架: 决策延迟与系统复杂度的取舍
当低延迟能产生实质价值时,才选流处理。例如欺诈检测、运营提醒、实时个性化、库存更新、实时实验指标,以及需要新鲜事件数据的用户功能。 对日报、历史分析、财务对账,以及可接受几小时延迟的转换,批处理通常更合适。它更易运维、容易重放,成本也往往更低。 决策时应考虑时效要求、事件量、顺序要求、有状态处理、容错、团队经验、成本和下游使用者。流处理并非天然更好,它会增加去重、迟到事件、检查点、模式演进和监控的复杂度。 好的回答是:选择满足业务需求的最简单架构。如果业务只需要每日指标,就不要为了追求技术光环而建流处理系统。
可能的追问
什么是迟到事件?
如何在流处理中处理重复事件?
“仅一次处理”是什么意思?
回答框架: 事件 → 流 → 信息补充 → 规则/模型 → 行动 → 存储 → 监控
先明确要求:事件量、目标延迟、欺诈决策类型、可接受误报率,以及决策是阻止交易还是触发人工审查。 一种方案是将支付事件发布到 Kafka 或 Kinesis。流处理器消费事件、验证模式、按 event_id 去重,补充用户、设备、商户和历史行为频率等特征,再应用规则或模型。高风险事件交给决策服务、人工审查队列或额外身份验证。原始事件和决定写入持久存储,用于审计和模型训练。 重要工程问题包括重复与乱序事件、特征时效性、状态存储规模、仅一次或实际等效仅一次的处理、背压、死信队列、重放、延迟监控及模型和规则版本。 数据质量和治理很重要,因为欺诈决策会影响客户。应记录原因代码、监控误报率,并在规则或模型表现异常时支持回滚。
可能的追问
如何计算一定时间内的行为频率特征?
如何安全地重放事件?
死信队列有什么用?
Spark 与分布式处理面试题
Spark 与分布式处理面试题考查你是否理解分区、数据混洗、数据倾斜、缓存、表关联、文件格式,以及作业为何失败或成本过高。
回答框架: 跨分区重新分配数据
当 Spark 需要在不同分区间重新分配数据时,会发生数据混洗,常见于 groupBy、join、distinct、orderBy 和 repartition。它成本高,是因为数据需要通过网络传输、序列化和反序列化、写入磁盘,并在各执行器之间协调。 混洗常占据作业大部分运行时间。若数据倾斜或中间结果过大,还可能导致失败。一个特别热门的键可能把大量数据集中到单个分区,造成拖慢任务或内存不足。 降低成本的方法包括提前筛选、只选择必要列、预先汇总、对小表使用广播关联、按关联键分区、对倾斜键加盐、避免不必要的 distinct/orderBy,以及调整分区数。 好的回答还应联系实际排查:查看 Spark UI 中的阶段、混洗读写量、数据倾斜、磁盘溢写、任务时长和执行器内存。
可能的追问
什么会造成数据倾斜?
什么时候使用广播关联?
如何排查运行缓慢的 Spark 作业?
回答框架: 定位阶段 → 减少数据 → 修正倾斜 → 调整分区 → 避免低效操作
先用 Spark UI 或日志定位失败发生的阶段、操作、分区和执行器。内存不足可能来自数据倾斜、大表关联、collect 操作、过大的分区、低效 UDF,或缓存过多数据。 然后尽早减少数据:筛选行、只读取必要列、尽可能下推条件,并避免扫描不需要的分区。检查关联:如果一张表很小,使用广播关联;如果某个键严重倾斜,可加盐或拆分热门键。分区太大就增加分区数,过多小分区则适当合并。 避免对大数据调用 collect();原生函数能实现时不要用 Python UDF;只有重复使用且内存允许时才缓存。写文件时应避免过多小文件,选择 Parquet 等有压缩的列式格式。 如果确实需要资源调优,可调整执行器内存、核心数、混洗分区及内存开销,但不能只靠更大的集群。修正数据形态和查询计划通常更持久。
可能的追问
如何发现数据倾斜?
分区过多为什么不好?
什么时候应该缓存 DataFrame?
回答框架: 列式存储、模式、压缩和谓词下推
Parquet 是列式文件格式,适合分析,因为查询常只读取一部分列。它支持压缩、保存数据类型和模式,并让许多计算引擎进行谓词下推与列裁剪。 CSV 是面向行的纯文本格式,易于人阅读,也便于交换,但类型约束弱、文件可能更大、扫描更慢,分隔符与转义容易出错,也难以高效跳过无关列。 用于数据湖和数仓时,Parquet 通常能降低存储成本并提高查询性能。CSV 仍适合简单导出、小文件或系统互通,但不适合作为主要分析存储格式。
可能的追问
什么是谓词下推?
什么情况下 CSV 仍然合适?
大量小文件如何影响查询性能?
数据质量与可观测性
数据质量面试题考查你能否在错误数据破坏仪表板、模型、产品功能、财务报告或面向客户的系统前发现问题。
回答框架: 时效性 → 完整性 → 唯一性 → 有效性 → 对账
对收入管道,我会检查数据时效性、行数、主键空值、重复交易 ID、有效状态、有效货币、适用情况下非负金额、允许的日期范围,以及订单、支付、退款和客户之间的引用完整性。 还要做对账:将收入总额与源支付系统、财务报告或上一版管道结果比较。设置逐日、逐周变化阈值,但应考虑季节性和已知业务事件。 业务规则同样重要:取消订单不应计为收入,退款应减少净收入,测试交易应排除,货币换算也必须使用正确汇率。 提醒应可操作、明确发送给负责人,并提供上下文:哪项检查失败、受影响的表、严重程度、下游依赖和建议的运行手册。噪声太多的提醒最终会被忽略。
可能的追问
你会如何确定提醒阈值?
如果月末结账期间检查失败呢?
如何防止收入重复计算?
回答框架: 评估影响 → 比较版本 → 追踪血缘 → 缓解 → 查找根因
先评估影响:哪些仪表板、指标、用户、日期范围和决策受到影响。判断新数字是错误的,还是这次部署纠正了过去的问题。 按表、分区、行数、去重计数、指标总额和关键用户群比较新旧输出。利用数据血缘定位上游变化,检查代码、模式、筛选、关联、去重和日期逻辑的变更。 如果指标确实错误且影响业务用户,应迅速缓解:回滚转换、恢复表的旧版本、暂时关闭仪表板,或加上警告。之后做根因分析,必要时回填修正后的数据。 沟通同样重要。通知相关方发生了什么、影响范围、目前的判断把握、预计修复时间,以及过去的决定是否需要重新审视。
可能的追问
如何判断新旧数字哪个正确?
你希望具备哪些回滚方式?
数据血缘能提供什么帮助?
数据工程系统设计
数据工程系统设计面试评估架构判断:数据源、接入、存储、转换、服务、质量、血缘、治理和成本。
回答框架: 埋点 → 接入 → 存储 → 处理 → 建模 → 服务 → 治理
先明确要求:事件量、延迟、使用者、保留期限、模式演进、隐私和可靠性。产品分析事件可能用于仪表板、实验、个性化和机器学习特征。 客户端通过 SDK 发送包含 event_name、user_id、session_id、时间戳、属性、应用版本、平台和匿名 ID 的事件。事件进入接入 API 或收集器,再进入 Kafka、Kinesis 或 Pub/Sub 等持久事件流。原始事件写入对象存储以供重放,并进入数仓或湖仓用于分析。 处理阶段包括模式校验、去重、机器人与内部流量过滤、会话划分、身份解析,再转换为 fact_events、fact_sessions、dim_users 和产品专用数据集市等模型表。批处理和流处理可根据时效需求并存。 质量与治理方面要有事件契约、模式注册中心、个人身份信息处理、用户同意执行、血缘、负责人、时效检查、数据量异常提醒及文档。服务层包括商业智能仪表板、实验分析、反向 ETL 和特征存储。 需要权衡实时与批处理成本、严格与灵活的模式、原始事件保留、身份解析复杂度,以及多少逻辑放在接入层或转换层。
可能的追问
你会如何处理模式演进?
你会如何对事件去重?
分析师会查询哪些表?
回答框架: 离线与在线一致性 → 特征定义 → 时效性 → 服务 → 监控
特征存储应为模型训练和线上服务提供可复用、可靠的特征。需求包括特征定义、时间点正确性、离线训练数据、低延迟在线服务、时效性、访问控制和监控。 离线特征可保存在按日期和实体分区的数仓或湖仓中;在线特征可由低延迟键值存储提供。特征注册表记录名称、负责人、实体键、转换逻辑、时效服务级别、源表和说明。 时间点正确性至关重要。训练数据必须使用预测发生时已经可用的特征值,不能泄露未来信息。为保证线上与离线一致,最好复用同一套转换逻辑;如果必须使用独立管道,就需要充分测试。 监控应覆盖特征时效、空值率、分布漂移、在线服务延迟、训练与服务数据偏差,以及对下游模型的影响。治理还包括个人身份信息控制、血缘、弃用流程和责任归属。
可能的追问
什么是时间点正确性?
如何避免训练与线上服务使用的特征不一致?
哪些特征需要在线服务?
行为面试与协作题
数据工程行为面试重点关注生产责任、事故响应、跨职能沟通、优先级,以及能否建立让其他团队信任的系统。
回答框架: 影响 → 排查 → 缓解 → 根因 → 预防
选择一次有真实影响的事故:数据缺失、指标错误、管道延迟、记录重复、仪表板故障、模型特征问题,或对下游产品造成影响。先说明谁受影响,以及为什么重要。 再说明排查过程:日志、编排状态、源数据时效、近期部署、模式变更、行数、分区、血缘和下游依赖。描述如何缓解:重跑、回滚、补丁、回填,或向相关方发出警告。 最有说服力的回答包含预防措施。你是否增加了数据质量检查、提醒、重试、模式契约、幂等写入、运行手册、血缘或更严格的部署控制?不要把责任推给上游团队,而要展示你对系统和沟通的负责态度。 最后说明你对可靠性的认识如何改变,以及之后如何改进工作流程。
可能的追问
你如何沟通影响范围?
什么检查能更早发现问题?
你如何防止事故再次发生?
回答框架: 澄清 → 复现 → 追踪血缘 → 解决 → 记录
先澄清具体哪里不对:指标、表、日期范围、仪表板、筛选条件、预期数值,以及业务上为何认为有误。“数据有问题”需要转化为可复现的情况。 然后把分析师的查询或仪表板与源表和模型定义比较,检查粒度、筛选、关联、时区、时效、指标定义和近期变更,并通过数据血缘追踪上游依赖。 如果数据确实错误,就修复并沟通影响;如果数据正确,但定义与预期不一致,就统一指标定义和文档。如果仍有不确定性,应说明已知事实、正在检查什么,以及何时跟进。 合作关系很重要。分析师是数据平台的使用者,快速、清晰且有证据支持的响应才能建立信任。
可能的追问
如果分析师错误使用了表呢?
你如何避免类似疑问反复出现?
哪类文档最有帮助?
回答框架: 影响 → 可靠性 → 紧迫性 → 依赖 → 杠杆效应
我会根据业务影响、可靠性风险、紧迫性、下游依赖和杠杆效应排序。收入管道故障或合规问题,通常比可有可无的仪表板模型更优先。如果平台改进能帮助很多团队,也可能优先于一次性请求。 我还会区分紧急事故、战略性平台工作、相关方请求、技术债和日常重复劳动。如果团队只处理工单,可靠性和平台质量会退化;如果只做平台抽象,业务团队又可能被阻碍。 好的优先级流程包含明确责任、服务级别、严重程度、路线图对齐和透明取舍。我会沟通目前做什么、推迟什么、为什么,以及这会带来什么风险。
可能的追问
你会如何说明技术债工作的重要性?
如果管理层急需仪表板呢?
你如何平衡事故处理与路线图工作?