大数据面试题
Kafka 的 message 包括哪些信息?
一个 Kafka 消息通常可以概括为:
- 固定长度头部
- 变长消息体
头部中常见的元信息包括:
magicCRC- 属性位
消息体里则是具体的 key/value 数据。
怎么查看 Kafka 的 offset?
不同版本和客户端方式不同。
常见思路:
- 使用 Kafka 自带命令行工具
- 使用消费者客户端 API
- 在代码中结合
seekToEnd()、position()等接口查看
Hadoop 的 shuffle 过程是什么?
Shuffle 分为 Map 端和 Reduce 端两个阶段。
Map 端:
- 结果先写入内存缓冲区
- 达到阈值后 spill 到磁盘
- 排序、分区、可选 combiner
- 多个 spill 文件最终归并
Reduce 端:
- 从各个 Map 拉取对应分区数据
- 归并排序
- 交给 Reduce 逻辑处理
Spark 集群有哪些常见运行模式?
常见模式包括:
- 本地模式
- Standalone
- Yarn
- Mesos
- Cloud 环境
实际生产里最常见的是:
- Standalone
- Yarn
HDFS 读写数据的过程是什么?
读流程:
- 客户端先向 NameNode 获取元数据
- 找到目标 block 所在的 DataNode
- 与 DataNode 建立连接
- 按 packet 接收数据
写流程:
- 客户端先请求 NameNode
- NameNode 返回目标 DataNode 列表
- 建立写入 pipeline
- 客户端按 packet 向 DataNode 链路写入数据
reduceByKey 和 groupByKey 哪个性能更好?为什么?
通常 reduceByKey 更好。
原因:
reduceByKey会在 map 端先做局部聚合- 可显著减少网络传输量
而 groupByKey 会把更多原始数据直接拉到 reduce 端,容易造成:
- 网络开销更大
- 内存压力更高
Kafka 的数据存在内存还是磁盘?
Kafka 的核心设计是以磁盘为主,而不是只放内存。
原因包括:
- 顺序读写磁盘性能很高
- OS 页缓存会参与加速
- 避免 JVM 堆过大导致 GC 问题
- 数据持久化更可靠
如何解决 Kafka 数据丢失问题?
要分 Producer、Broker、Consumer 三端来看。
常见手段:
- Producer 端开启确认机制
- Broker 端做好副本和 ISR 配置
- Consumer 端关闭自动提交,处理完成后再提交 offset
核心目标是保证:
- 消息写入可靠
- 消费确认时机正确
宽依赖和窄依赖有什么区别?
- 窄依赖:父 RDD 的一个分区只会被子 RDD 的一个分区使用
- 宽依赖:父 RDD 的分区会被多个子分区依赖
通常:
- 宽依赖往往伴随 shuffle
- 窄依赖更适合流水线执行
Spark Streaming 读取 Kafka 数据有哪些方式?
常见两种:
Receiver-basedDirect
通常更推荐 Direct 方式,因为:
- offset 控制更清晰
- 更容易做可靠性保障
设计题:如何采集海量 Nginx 日志并提供实时查询?
这是典型的日志采集和实时分析题。
常见链路:
- 日志采集:Logstash / Filebeat
- 消息缓冲:Kafka
- 实时计算:Spark Streaming / Flink
- 结果存储:Redis / Elasticsearch / OLAP 引擎
- 查询展示:报表或服务接口
如果要求 3 秒内查询响应,通常需要把统计结果提前聚合,而不是临时扫原始日志。
海量 Query 统计 Top K 应该怎么做?
这是经典 Top K 题。
常见思路:
- 先按 hash 分桶,把大文件拆成多个小文件
- 在每个桶内做词频统计
- 维护每个桶的局部 Top K
- 最后归并得到全局 Top K
如果机器内存足够,也可以直接用哈希表统计后再堆排序。
在海量整数中找出不重复的整数,内存不足怎么办?
经典做法之一是位图或 2-Bitmap。
例如:
00:未出现01:出现一次10:出现多次
扫描完后,把状态为“只出现一次”的数输出即可。
给 40 亿个不重复的 unsigned int,如何快速判断某个数是否存在?
经典做法是位图(Bitmap)。
思路:
- 每个数对应一个 bit 位
- 读入数据后把对应 bit 置为 1
- 查询时直接看目标 bit 是否为 1
这种做法非常适合“海量整数 + 存在性判断”问题。
海量数据中如何找出重复次数最多的一个?
常见思路:
- 先 hash 分桶
- 每个桶内统计出现次数最多的元素
- 最后在所有桶结果中再比较一次
本质上仍然是“分治 + 统计 + 汇总”。
上亿数据中统计出现次数最多的前 N 个,怎么做?
典型套路:
- 哈希统计频次
- 用最小堆维护 Top N
如果数据过大无法一次放内存,就先分桶,再在每个桶里做局部统计。
一个文本文件中统计出现最频繁的前 10 个词,怎么做?
如果数据量不大,可以直接:
- 遍历文件
- 用哈希表统计词频
- 用最小堆维护前 10
如果题目强调超大数据量,则需要进一步考虑:
- 分桶
- 外排序
- 分布式处理
100 万个数中找出最大的 100 个数,怎么做?
经典方法是维护一个大小为 100 的最小堆。
过程:
- 先用前 100 个数建堆
- 遍历剩余元素
- 如果新元素大于堆顶,就替换堆顶并调整堆
这样时间复杂度更可控。
评论
使用 GitHub 账号即可参与加载较慢?可 直接前往 GitHub Discussions 查看与参与。