MST

星途 面试题库

面试题:Java并行流在复杂数据处理场景下的多CPU资源分配

假设有一个包含大量复杂对象(每个对象有多个属性)的列表,需要对这些对象按某个属性分组后,再对每组数据进行复杂计算(例如多层次的聚合操作)。请描述在这种场景下,如何利用并行流有效利用多CPU资源,同时避免线程安全问题和性能瓶颈,并给出关键代码示例。
17.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 并行流的使用思路
    • 首先利用Streamparallel()方法将顺序流转换为并行流,以充分利用多CPU核心。
    • 分组操作可以使用Collectors.groupingBy,在并行环境下,它能自动处理数据的分区和合并。
    • 对于每组数据的复杂计算,要确保计算过程是线程安全的,例如使用不可变对象或者线程安全的集合。同时,避免在计算过程中产生大量中间数据,以免造成性能瓶颈。
  2. 关键代码示例 假设我们有一个Person类,包含nameage属性,要按age分组并计算每个年龄组中名字的长度总和。
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 25));
        people.add(new Person("Bob", 30));
        people.add(new Person("Charlie", 25));

        Map<Integer, Integer> result = people.parallelStream()
               .collect(Collectors.groupingBy(
                        Person::getAge,
                        Collectors.summingInt(p -> p.getName().length())
                ));

        result.forEach((age, sumLength) -> System.out.println("Age " + age + ": Total name length = " + sumLength));
    }
}

在上述代码中:

  • people.parallelStream()List转换为并行流。
  • Collectors.groupingBy(Person::getAge, Collectors.summingInt(p -> p.getName().length()))age分组,并对每个组内的名字长度进行求和。这一操作在并行流环境下能够并行执行,有效利用多CPU资源,并且Collectors中的方法在并行处理时是线程安全的。