字节跳动大数据开发面经(10.9)
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 你先做一下自我介绍。
- 你搭建湖仓用到 Iceberg,介绍下 Iceberg 的优点。
- 一张 Iceberg 管理的表如何做 Time Travel?查询这张表十分钟前的状态,SQL 怎么写?
- 如果表已经接入湖仓、由 Iceberg 管理,查询十分钟前的数据,select from 后面该怎么写?
- 数据写入 Iceberg 是 Flink 直接写入,还是其他方式导入?
- 数据源有二十多个,你读取原始数据、构建 Hive 数仓,对吧?
- 你做数仓性能优化,提到分层分桶、降低存储开销,怎么理解?
- 说得不够具体,分层是怎么实现存储低于常规方案的?这和分层分桶的关联是什么?
- 你构建的数据模型,是用 Iceberg 管理整套数据吗?
- 回到 Iceberg,在你的实践中 Iceberg 起到什么作用?你理解它是元数据管理系统,还是文件存储系统?
- 如果没有 Iceberg,普通 Hive 表底层如何存储?
- 举例子,一张 Hive 表包含十个字段,底层 HDFS 怎么存储?
- 这些是特性。这些特性来源于 Iceberg 内部文件组织方式,这块可以讲讲吗?
- 介绍你觉得最复杂的一个 Skill。
- 你提到智能问数 Skill,可以理解为用户通过 Skill 查询平台内表、指标以及指标组合口径,是这样吗?针对这个问数 Skill,你做了哪些优化?
- 可以理解为你的核心目标是保证 Agent 思考与 Skill 执行流程符合预期,知识库、MCP 能力是外部接入的?
- 假设用户查询一个指标,比如 DAU,十次回答八次正确,两次因为幻觉、执行链路不符合预期,这种情况你如何强控?
- 面试到这里,你有什么想问我的?
《参考解析》
Iceberg 到底解决了什么问题。它的价值不在「存得更快」,而在把一张表变成有元数据管理的事务性数据集。一是快照与 ACID:每次提交生成新快照,读写隔离,写失败不会污染读取方,也能做原子替换。二是 schema evolution:加列、改列、删列不需要重写数据,靠字段 ID 而不是位置绑定,避免了 Hive 里加列后读到串位数据的经典事故。三是隐藏分区:分区由 partition spec 的 transform 表达,查询侧不用写分区列,也不会因为忘写分区条件而全表扫。四是时间旅行与增量读:可以按快照或时间点查历史,也能只读两次快照之间的增量文件,对 CDC 入湖与回溯重跑很有用。五是文件级统计:每个数据文件的列 min/max、行数、空值数存在 manifest 里,scan planning 能裁到文件级,比 Hive 的目录级裁剪细得多。最后是引擎生态,Spark、Flink、Trino、StarRocks 都能读写同一份表,还支持 compaction 合小文件而不改变表语义。
Time Travel 的 SQL 怎么写。以 Spark 为例有两种写法:按时间戳 SELECT * FROM db.t TIMESTAMP AS OF '2026-10-09 12:00:00',或按快照 SELECT * FROM db.t VERSION AS OF <snapshot_id>,Flink 也有对应的 VERSION AS OF。Hive 表则完全没有这个概念——它只有当前状态,要查历史只能自己按天建快照表或按分区留档。面试官专门追问「select from 后面怎么写」,考的就是你有没有真写过:Iceberg 是把快照写进元数据的,查询时由引擎改写扫描计划去读对应快照的 manifest。两个坑要提:历史能回溯多久取决于 expire snapshots 的保留策略,过期后查不到;按时间戳查用的是快照提交时间而不是业务时间,写入有延迟时要和业务对齐数据边界。
「分层分桶降低存储」这句话要拆开说。严格讲分层本身不省存储,反而会多存几份中间结果,它省的是重复计算和扫描量,间接降低整体成本。真正让存储降下来的是:列存加压缩(ORC/Parquet 按列编码,同质数据压缩比远高于文本)、分区与分桶让文件大小均匀、治理小文件(小文件既占 NameNode 内存又放大读开销)、按生命周期清理与冷热分层、去重与增量合并。分桶在这里的作用是让相同 key 落到相同文件,join 时可以只扫需要的桶,间接减少中间结果落盘。所以更严谨的回答是:分层提升复用、减少重复计算,分桶降低 shuffle 与扫描量,两者合起来削减的是整体资源消耗,而不只是表占用的空间。面试官连着追问两遍「说得不够具体」,就是在等这个区分。
Hive 表在 HDFS 上到底怎么存。一张十个字段的 Hive 表落到 HDFS 上就是目录加文件:库是一级目录,非分区表一个目录,分区表按「分区列=值」生成多级子目录,叶子目录下是一个个数据文件。文件的内部格式决定组织方式:TextFile 就是一行记录一行文本、字段用分隔符隔开;ORC、Parquet 这类列存会按行组切块(ORC 的 stripe、Parquet 的 row group),块内按列独立编码与压缩,并在块尾或文件尾保存统计信息(每列 min/max、行数)。所以「十个字段只查两个」时,引擎可以只读这两列的块,扫描量能降到十分之一左右。把「目录结构(分区)」和「文件内部结构(列存块与统计)」这两层讲清楚,基本就能接住追问。
Iceberg 是元数据系统还是文件存储系统。它是表格式,也就是「元数据管理 + 文件组织约定」,数据文件仍然由 HDFS、S3、OSS 承担。组织是三级:metadata 层的 metadata.json(记录当前快照、schema、partition spec、快照列表)、manifest list(一个快照对应一个列表,列出包含哪些 manifest)、manifest file(记录一批数据文件及分区信息与列统计),最后才是真实的数据文件。查询时引擎先读 metadata 拿到快照,再用 manifest 里的统计信息裁剪出要读的文件,最后才打开数据文件。这正是它比 Hive「目录即元数据」精细的原因:Hive 的裁剪只在目录级,文件级过滤要靠引擎打开文件才知道,而 Iceberg 在计划阶段就能完成。
智能问数 Skill 的幻觉怎么强控。「十次里八次对、两次错」的典型根因是口径没有固化在语义层里。强控分四层:第一层固化口径,把指标定义、维度组合、时间口径写进语义层与知识库,Agent 只做「选指标 + 填维度」,不允许自己发挥业务口径;第二层约束生成,用模板化 SQL 或受限 DSL,配合元数据做 schema 校验,字段名、表名、聚合方式对不上就不执行;第三层执行后校验,做量纲与量级检查(DAU 不可能大于 UV、环比波动超阈值要标注)、多路等价写法交叉验证、空结果与异常值显式提示;第四层交互兜底,置信度低或口径有歧义时反问澄清,而不是硬给一个数字,同时把每次问答沉淀成评测集做回归,用错误样本反推语义层缺了什么。最后一点很关键:Agent 的输出要能点开看到用了哪个指标、跑了什么 SQL、数据来自哪张表,可追溯本身就是最有效的防幻觉手段。
面试官补充的团队信息。这个数据团队对标海外版直播平台,面向海外用户提供主播、公会、厂商等 B 端业务,所有直播相关数据都归该组,规模一百多人;团队内 AI 应用分两条线,一是用 AI 加速数据生产、提升数据管理效率,二是用 AI 拓展数据能力边界——传统模式下数据开发很难独立完成全链路分析归因,借助 AI 可以低成本组装各模块。对于「单人 + AI 完成数据全链路闭环、人工只把控输入输出」的想法,面试官的答复是:需求明确的前提下 AI 完成大部分开发、人工负责验收,这套模式在该团队 2026 年上半年已经比较成熟。这句话对准备方向很有参考价值——把「怎么和 AI 分工、怎么验收 AI 的产出」当成可以讲的能力,比只讲工具使用更有竞争力。