面灵AI→

字节面经-字节跳动数据开发与数据分析岗面经-04

轮次
面试合集
时间
2026-10
来源
牛客网

《面试题目》

(面经 01)

  1. 查询这张表十分钟前的状态,SQL 怎么写?
  2. 你理解它是元数据管理系统,还是文件存储系统?
  3. 针对这个问数 Skill,你做了哪些优化?
  4. 从元数据、链路搭建,AI 完成数据校验,人工只把控输入输出,AI 写 SQL 建表、调优链路,这种模式是否已经落地?

(面经 02)

  1. 自我介绍
  2. 简述一下几种向量索引方案?
  3. 现在 Milvus 里有一千亿个向量,你怎么设计索引?
  4. 如果分完桶之后,有一个桶里面只有 10000 个向量,为什么会出现这样只有 10000 个向量的桶,这些向量是怎么组织的,怎么分层的?
  5. 设计一个 10 个 Redis 机器构成的集群,内部存的是普通的 K-V,K 是 UID,V 是一个二进制文件,要求考虑单点故障、负载均衡等,要实现高可用、低延迟。

《参考解析》

查询这张表十分钟前的状态

这题考的是「表有没有历史版本」而不是「SQL 语法」。如果底层是 Iceberg / Hudi / Delta 这类带快照的表格式,直接走时间旅行:SELECT * FROM t TIMESTAMP AS OF <十分钟前的时间戳>,或者用 VERSION AS OF <snapshot_id> 指定快照;快照 id 要从元数据表查,时间戳写法依赖 catalog 保留的 snapshot 过期策略。如果底层只是 Hive 外表或普通数仓表,没有任何办法查出十分钟前的状态——文件被覆盖后旧版本就不存在了,只能靠额外的机制补:拉链表 / 每日快照表、binlog 或 CDC 落地、Flink 双流 join 保留中间态。回答时先反问一句「底层是哪套表格式、快照保留多久」,再给方案,比直接写 SQL 更稳。

元数据管理系统还是文件存储系统

要看它存的是什么。Hive Metastore这类组件只存 schema、分区、文件路径和统计信息,真实字节在 HDFS 或对象存储上,它是纯元数据系统;Iceberg 的表格式层比它多走一步,除了元数据还维护 manifest、快照和提交协议,但依然不存数据字节。判断标准很简单:这个系统里有没有用户数据的 payload。之所以要拆开,是因为两者特性完全相反——元数据小、要求事务性和强一致,适合放在关系库;数据文件大、便宜、吞吐优先,放在分布式文件系统或对象存储。真正的一致性靠的是 catalog 的原子提交:先写数据文件、再原子地切换元数据指针,失败时靠孤儿文件清理兜底。

问数 Skill 的优化

Text2SQL 类应用的效果瓶颈很少在模型,多数在上下文和校验。可以做的优化:① schema 裁剪——按问题先检索出相关表和字段,而不是把全库 DDL 塞进 prompt;② 口径注入——把指标定义、字段业务含义、枚举值、常用 join 关系做成可检索的知识,避免模型猜;③ 少样本示例按相似问题动态召回,而不是写死几条;④ 生成后校验——语法解析加试跑(EXPLAIN 或小样本 limit 执行),报错原文回灌让它自己改,连续失败就降级到人工;⑤ 结果自检——空结果、行数异常、量级离谱时让它回看口径;⑥ 把高频问题做语义缓存。另外权限过滤和行列级脱敏必须在执行层做,不能交给模型自觉。

AI 写 SQL 建表、调优链路这种模式是否已落地

要分开看「能自动做」和「能自动上线」。DDL 生成已经比较可靠,但必须过评审门:分区键、存储格式、生命周期、压缩方式选错,代价是长期的存储成本和查询变慢,而且改起来贵。链路调优(并行度、资源、拆分粒度、调度依赖)AI 已经能做初版建议,但判断依据要落成可对账的指标——任务耗时、扫描量、产出行数、资源占用、失败率,调完之后拿这些数据做前后对比,而不是听它解释。真正需要人守住的只有两处:需求与指标口径的确认、上线前的验收。合理的形态是「AI 出方案 + 自动回归对比 + 人做验收」,而不是「AI 全自动、人只看输入输出」。

几种向量索引方案

按「精度—内存—延迟」这条轴记忆。FLAT 暴力检索,召回 100%,只适合百万级以内或做评测基线。IVF 系列先对向量做 k-means 聚类,查询时只搜最近的 nprobe 个桶,用 nprobe 换召回;PQ / SQ 是量化,把向量压成短码,内存降一个数量级,代价是精度损失,通常和 IVF 组合成 IVF-PQ。HNSW 是分层可导航小世界图,查询从稀疏的顶层往下逐层贪心下降,延迟最低、召回最好,代价是内存占用大(图上要存边)、构建慢、删除只能标记。DiskANN / SPANN 把图和量化码放到 SSD 上,用磁盘换内存,适合单机放不下的规模。选型先问清数据量、维度、内存预算、QPS 与召回要求,再落到具体方案。

千亿向量怎么设计索引

一千亿这个量级不存在「一个索引」——单机内存装不下,能落地的一定是分片 + 分桶 + 量化的组合。① 水平分片:按向量 id 哈希或按业务维度(租户、时间、类目)切到多台机器 / 多个 collection,路由层维护映射;② 片内分桶:先用粗聚类把向量分成大桶,每桶一个独立的倒排索引,查询时按 nprobe 只扫部分桶;③ 量化降内存:PQ / SQ 把原始 float32 压成字节码,原向量放磁盘或对象存储,只在需要重排时按 id 回捞;④ 两级检索:量化码粗排 topN,再用原始向量精排 topK,兼顾速度和精度;⑤ 副本与冷热分层,热数据常驻内存、冷数据走磁盘。回答时主动说清「召回率、延迟、内存、成本」四项里你优先保哪几项,面试官一般就是在听这个取舍。

为什么会出现只有 10000 个向量的桶

桶不均匀是分桶键选得不对或数据本身长尾。常见原因:按业务维度分桶(比如按租户、按类目),而业务量天然倾斜,小租户的桶就只有几万条;按哈希分时如果分桶数是拍脑袋定的,尾桶也可能偏小;另外持续写入下桶会分裂、合并,新桶刚开始就是小的。组织方式一般是三层:聚类中心(或桶元数据)→ posting list(桶内向量 id 列表,按量化码排布)→ 原始向量存储。桶内还会再分层:粗排阶段只读量化码,精排回捞原始向量。工程上要处理的是倾斜——桶太小就合并、太大就分裂,并在路由层记录每个桶的大小与负载,避免查询集中打到同一个桶上。

10 台 Redis 机器构成的集群

先纠一个前提:value 是二进制文件本身就不该往 Redis 放,几个 MB 的 value 就是典型大 key,序列化、网络、主从同步、扩容迁移都会被拖死。正确做法是文件进对象存储,Redis 只存 UID → 对象地址加少量元数据,这样 K-V 都是小对象。剩下的按四件事答:① 单点故障——主从 + 哨兵,或者直接用 Redis Cluster 分片,每片一主多从,故障自动切换;切换期间先降级(读本地缓存、返回兜底数据、限流),别让请求直接穿透到底层;② 负载均衡——Cluster 用 16384 个 slot 做哈希分配,客户端做路由,注意热点 slot 可以再拆;③ 热 key——本地缓存挡一层、同一 key 的多个副本打散到不同节点、读多写少的场景直接用多级缓存;④ 一致性——异步复制下只能做到最终一致,要靠版本号 / 时间戳和定期对账来发现并修正不一致,写关键数据时用 WAIT 或强一致读主。作者答到的大 key、热 key、雪崩、降级方向都对,缺的是「分片 + 故障切换 + 一致性模型」这三块要讲成体系。