JJava 知识库
JAVA INTERVIEW

高频面试题

Java集合进阶约 2 分钟

一个接口要临时聚合几十万条数据,你会直接用 HashMap 吗?容量、冲突和内存怎么评估?

参考回答约 2 分钟 · 口语表达
我的判断

几十万条聚合可以用 HashMap,但要先估算去重后的键数、对象大小和请求并发;内存预算不够时应改成分批或下推聚合。

我不会看到“几十万”就直接 new 一个 HashMap。先估算最终有多少个 key,而不是输入多少行;再用压测或 JOL 看 key、value、Node 和对象本身的占用。假设 30 万个聚合项每项连同对象开销约 100B,一个请求就接近 30MB,并发 20 个已经可能把堆顶满。

确认内存可接受后,会按预估键数设置初始容量,避免多次扩容:

int capacity = (int) Math.ceil(expectedKeys / 0.75d);
Map<Long, Summary> result = new HashMap<>(capacity);

key 要有稳定、分布正常的 hashCode。聚合值尽量原地累计,别为每条输入创建新的临时对象。如果 key 是基本类型且场景很热,可以评估 primitive map,减少装箱。

如果预算不够,我会优先让数据库按键聚合、按分区流式处理,或者把请求改成异步任务,而不是单纯加大 -Xmx。最后用真实基数和并发观察堆峰值、分配速率与 GC,而不是只测单次接口耗时。

思路拆解问题分析

这题的关键不是 HashMap 的红黑树阈值,而是 一次请求的内存乘以并发数。容量、冲突和扩容只是一部分,key/value 对象、装箱、输入列表是否同时驻留,往往才是主要占用。