【算法题】单机 2G 内存下大数据年龄统计:如何统计全国人口中每个年龄的人数
·
在处理全国人口数据时,我们常常需要统计每个年龄的人数。然而,在大数据场景下,这个任务并不简单。假设我们有如下条件:
- 文件中包含
几十亿条年龄数据; - 年龄为整数,通常
在 0\~150 岁范围内; - 机器条件有限:
单台 2 CPU + 2G 内存; - 禁止使用现成容器(如 HashMap),只能
使用数组或其他基础数据结构。
一、问题分析
数据特点
-
年龄范围有限
人口年龄通常在 0~150 岁之间,属于整数类型。 -
数据量巨大
全国人口几十亿条记录,无法一次性全部加载到内存。
机器限制
-
内存受限
内存仅 2G,无法存储所有数据到内存中进行统计。写算法需要考虑空间复杂度,避免OOM -
禁止使用 Map
只能使用数组或其他简单数据结构进行统计。
二、最优算法思路
方法:数组计数法(Counting Array)
原理
- 年龄是整数且范围固定 →
可以用数组下标表示年龄。 - 数组
元素存储该年龄的人数。 - 每读取一条年龄数据,对应数组下标的值加 1。
实现示例(Java)
int MAX_AGE = 150; // 假设最大年龄为150
long[] ageCount = new long[MAX_AGE + 1]; // 使用long防止人口过大溢出
// 逐行读取文件数据
try (BufferedReader br = new BufferedReader(new FileReader("ages.txt"))) {
String line;
while ((line = br.readLine()) != null) {
int age = Integer.parseInt(line.trim());
ageCount[age]++;
}
}
// 输出统计结果
for (int i = 0; i <= MAX_AGE; i++) {
if (ageCount[i] > 0) {
System.out.println(i + ": " + ageCount[i]);
}
}
方法优点
-
内存占用固定
只需存储 151 个long,约 1.2 KB,非常节省。 -
时间复杂度低
- 读取文件逐行处理:O(n),n 为文件中的总记录数;
- 输出结果遍历数组:O(MAX_AGE),MAX_AGE = 150,可忽略不计。
-
- 遍历数组输出结果可以认为是 O(1),因为 MAX_AGE 是固定常数,不会随着数据规模变化
- 总体时间复杂度:O(n)
-
实现简单
不需要复杂的数据结构,直接使用数组即可。
注意事项
-
人口数量可能很大
使用long类型存储计数,避免溢出。 -
适用场景
- 统计范围固定、值为整数的数据,如年龄、评分等级等。
- 数据量大,但数值范围小。
三、总结
在大数据场景下,数组计数法是一种高效、节省内存的统计手段。它充分利用了问题特点:
- 整数范围固定 → 可映射到数组下标;
- 计数数据量大 → 数组大小远小于数据量,满足低内存需求;
- 时间复杂度 O(n) → 线性处理数据,即便数据量几十亿条,也可快速统计。
在理想情况下,统计 13 亿条年龄数据的耗时主要由磁盘 I/O 决定:假设每条记录平均 3 字节,总文件约 3.9 GB,普通机械硬盘顺序读取约 100 MB/s → 读取约 40 秒,SSD 顺序读取约 500 MB/s → 读取约 8 秒,而 CPU 的数组计数操作非常快,只增加几秒,总耗时分别约 45 秒和 10 秒左右。
更多推荐


所有评论(0)