Skip to content

面试速答(先看这里)

**一句话结论:**Stream底层使用了ForkJoin进行并发处理,但是,并不代表着用了并发处理就一定比串行处理更快。

60秒标准回答:

Stream底层使用了ForkJoin进行并发处理,但是,并不代表着用了并发处理就一定比串行处理更快。有以下几个因素影响着并行流的性能

线程管理的开销 :并行流使用了多线程,而用了多线程就会带来线程管理和任务分配的开销

任务分割 :并行流的性能提升依赖于任务能够有效地分割和分配。如果任务分割不均衡,一些线程可能空闲或等待,从而影响性能

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**任务分割 :并行流的性能提升依赖于任务能够有效地分割和分配。
  • **要点2:**线程争用 :并行流使用公共的ForkJoinPool,如果系统中有其他并行任务,这些任务会争用线程资源,可能导致性能下降。
  • **要点3:**数据依赖性 :并行流适用于没有数据依赖性的操作。
  • **要点4:**主要区别就是CPU核数、任务的数量以及Stream中的元素的类型。
  • **要点5:**而在多核CPU的情况下,Stream的并行迭代速度要比Stream的串行迭代效率要高。

**记忆锚点:**Stream → CPU → E+8 → int → ForkJoinPool → nickliuchao

关键取舍:

  • 有以下几个因素影响着并行流的性能: 线程管理的开销 :并行流使用了多线程,而用了多线程就会带来线程管理和任务分配的开销。
  • 任务分割 :并行流的性能提升依赖于任务能够有效地分割和分配。
  • 如果任务分割不均衡,一些线程可能空闲或等待,从而影响性能。

加分表达:

  • 线程争用 :并行流使用公共的ForkJoinPool,如果系统中有其他并行任务,这些任务会争用线程资源,可能导致性能下降。
  • 如果操作之间存在依赖关系,并行流可能无法有效地提升性能,甚至可能导致错误。

追问准备:

  • 围绕「Stream」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「CPU」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「E+8」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

不一定!

Stream底层使用了ForkJoin进行并发处理,但是,并不代表着用了并发处理就一定比串行处理更快。有以下几个因素影响着并行流的性能:

线程管理的开销:并行流使用了多线程,而用了多线程就会带来线程管理和任务分配的开销。

任务分割:并行流的性能提升依赖于任务能够有效地分割和分配。如果任务分割不均衡,一些线程可能空闲或等待,从而影响性能。

线程争用:并行流使用公共的ForkJoinPool,如果系统中有其他并行任务,这些任务会争用线程资源,可能导致性能下降。

数据依赖性:并行流适用于没有数据依赖性的操作。如果操作之间存在依赖关系,并行流可能无法有效地提升性能,甚至可能导致错误。

环境配置:机器的硬件配置(例如CPU核心数)和当前系统负载也会影响并行流的性能。如果CPU核心数较少或负载较高,并行流的性能可能不如串行流。

在github(https://github.com/nickliuchao/stream/tree/master )上看到过有人做过测试,他测试的几个case是:

  • 多核CPU服务器配置环境下,对比长度100的int数组的性能;
  • 多核CPU服务器配置环境下,对比长度1.00E+8的int数组的性能;
  • 多核CPU服务器配置环境下,对比长度1.00E+8对象数组过滤分组的性能;
  • 单核CPU服务器配置环境下,对比长度1.00E+8对象数组过滤分组的性能。

主要区别就是CPU核数、任务的数量以及Stream中的元素的类型。得到的结果如下:

  • 多核CPU服务器配置环境下,对比长度100的int数组

  • 常规的迭代>Stream并行迭代>Stream串行迭代

  • 多核CPU服务器配置环境下,对比长度1.00E+8的int数组

  • Stream并行迭代>常规的迭代>Stream串行迭代

  • 多核CPU服务器配置环境下,对比长度1.00E+8对象数组过滤分组

  • Stream并行迭代>常规的迭代>Stream串行迭代

  • 单核CPU服务器配置环境下,对比长度1.00E+8对象数组过滤分组

  • 常规的迭代>Stream串行迭代>Stream并行迭代

所以,我们可以得到结论:

在单核CPU的情况下,Stream的串行迭代的效率是要高于Stream的并行迭代的效率的。

而在多核CPU的情况下,Stream的并行迭代速度要比Stream的串行迭代效率要高。但是,如果元素数量比较少的话,直接用常规迭代反而性能更好。