Scala开发工程师面试宝典 - 第4节
第4章:集合框架与高阶函数
本章聚焦 Scala 核心的集合操作与高阶函数,覆盖 List、Map、Set 的常见用法,以及 map、flatMap、filter、fold 等函数的原理与面试高频考点。掌握这些模式能体现函数式编程思维,是大厂 Scala 岗的必修课。
💡 记忆口诀: map 一对一,flatMap 一对零到多个;filter 保留 true,fold 带初始值聚合。
📌 面试问题 1:map 和 flatMap 的区别?
| 考察点 | 函数式编程理解、类型签名、Option / List 混合用法 |
| 回答框架 | 定义 → 返回值差异 → 嵌套集合处理 → 实例 → 总结 |
| 示例回答 | map 对每个元素应用函数,结果仍嵌套;flatMap 会展平一级。例如 List("ab","cd").map(_.toList) 得到 List(List('a','b'), List('c','d')),用 flatMap 则得到 List('a','b','c','d')。 |
| 可能追问 | ① flatMap 如何处理 Option? ② 性能上谁优? ③ 能否用 map + flatten 模拟? |
| 避坑提醒 | ✘ 误以为 flatMap 只是 map + flatten(对 Option 也适用但含义不同);✔ 注意传入的函数必须返回可遍历类型(GenTraversableOnce)。 |
📌 面试问题 2:fold 和 reduce 的区别?
| 考察点 | 初始值作用、空集合安全处理、结果类型控制 |
| 回答框架 | 有无初始值 → 空集合行为 → 结果类型 → 调用方式 |
| 示例回答 | fold(0)(_+_) 对空 List 返回 0;reduce(_+_) 在空 List 抛 UnsupportedOperationException。且 fold 允许结果类型与元素不同(如 fold("")(_+_.toString)),reduce 必须相同。 |
| 可能追问 | ① foldLeft / foldRight 区别? ② 时间复杂度? ③ scan 与 fold 关系? |
| 避坑提醒 | ✘ 用 reduce 处理可能为空的集合;✔ 明确 fold 初始值类型与累加器一致(若集合类型为 Int,初始值用 0 而非 0.0)。 |
📌 面试问题 3:如何对 List 进行分组和聚合?
| 考察点 | 基础算子掌握、函数式聚合思维、多级分组与性能意识 |
| 回答框架 | 单级分组 → 值转换 → 多级分组 → 聚合示例 |
| 示例回答 | list.groupBy(_.age) 得到 Map[Int, List[Person]];再 .mapValues(_.size) 得各年龄人数。若需多级分组:list.groupBy(p => (p.age, p.city)),再用 map 统计。 |
| 可能追问 | ① groupBy 后如何排序? ② 大量数据时 groupBy 导致的 OOM 风险? ③ 能否用 aggregate 替代? |
| 避坑提醒 | ✘ groupBy 返回 Map 键唯一,若 key 为 case class 需注意 equals/hashCode;✔ 用 view 或 iterator 实现惰性分组以减少内存。 |
📋 项目案例:电商订单聚合分析系统
| 项目名称 | 电商订单实时聚合分析平台 |
| 业务背景 | 对接电商平台每日百万级订单流,按商家、品类、时间窗口实时聚合成交额、件数等指标,支持运营看板与自助分析。 |
| 规模指标 | 日均订单 100 万+,商家 5 万+,品类 2000+,延迟 < 5 秒 |
| 技术栈 | Scala 2.13, Spark Structured Streaming, Kafka, HDFS, Redis 缓存 |
| 核心难点 |
- 数据倾斜:少数大商家占 40% 订单
- 内存 OOM:全量 groupBy 后 map 导致内存溢出
- join 性能:订单表与商品表关联时 shuffle 压力大
|
| 面试高频追问 |
- 你如何解决数据倾斜? —— 预聚合 + 加盐 + 广播小表
- 选择
groupBy 还是 reduceByKey? —— RDD 优先 reduceByKey,DataFrame 用 groupBy + agg
- 如何保证聚合准确性? —— 水位线 + 幂等写入
|
| 可迁移回答话术 | “我在项目中遇到数据倾斜时,首先通过采样识别倾斜 key,然后采用两阶段聚合:第一阶段加随机后缀打散热点,第二阶段去掉后缀合并结果。同时配合广播变量缓存小表,减少 shuffle 数据量。这套方案也适用于其他基于 spark 的聚合场景。” |
💡 课程提示: 本章项目案例中,强调“预聚合 + 打散”是面试中体现系统设计能力的关键点,建议结合自己真实项目重构话术。