额定内存进行资源分配

40亿个非负整数中找到没出现的数,限额1GB

题目剖析

1、数据理解:

整数,1个整数占4个B,即32bit,40亿个整数,占40亿*4B,即16GB

40亿,如果用二级制推算,最接近2^32=4,294,967,296(42.9亿),即32bit,占4个B

2、最坏情况:40亿个数都不相同,需要输出4B*40亿=160亿B=16G

解题重点:

1、找出未出现过的数时,不可以直接将数字存储并输出,需要寻找一个容器

解题思路:

1、寻找策略:借鉴桶排序,用跟数据大小相同长度的数组标记重复情况

2、容器选择:BitSet,容器体积小,每个元素只能为1或0,可以满足需求

3、具体做法:

  • 申请一个长度为2^32 的BitSet,这个长度稍微大于非负整数的取值范围,8个bit即1B,即占了2^32/8/1024/1024=512M,每个位置只标识1或0

  • BitSet默认成一个元素都为0的数组,出现过的数在BitSet对应位置标记为1,最后标号为0的,就是没出现过的数。最后遍历数组,得出结果。

  • 最终只需要512M内存即可。

    .

40亿个非负整数中找到一个没出现过的数,内存限制为10MB

题目解剖:

1、数据理解:

10M,即10240B,即81920bit,如果要用这些来处理40亿数据,即要进行分块处理,每块的数据量为40亿/81920=48.83,比较靠近2^6=64,所以需要拆成64块,然后分开处理,即每组数据最大量为67,108,864(数据全齐状态)

2、最坏情况:全部数据都出现过

3、解题策略:如果按上述桶排序思路,需使用500M内存,超出要求

解题重点:

1、利用布隆过滤器的思想,先把绝对会出现的数据过滤掉,即采用两个容器进行统计

解题思路:

1、寻找策略:借鉴布隆过滤器,先排除不是目标的对象,再找未出现的数

2、具体做法:

—第一个容器:

  • 定制一个长度为64的整形数组int[64] ,该数组占内存空间64*4B=256B
  • 遍历那40亿个数,设num/67108864=i,i为数据块编号,然后intArray[i]++
  • 遍历int数组,找出一个计数少于67108864的位置K

–第二个容器

  • 申请一个长度为67108864bit的bit数组,占用内存8192KB,即约8MB
  • 遍历40亿个数,找出位于区间k的所有数
  • 找出的数n,将bit数组中的n-67108864*k的值置为1
  • 遍历bit数组,找出值为0的位置,假设位置是i,那么67108864*k+i就是没有出现过的数

合并用内存256B+8192KB=8MB,符合条件

.
.

给定一个文件F,其中存放了N个url,每个url占64字节,内存限制是4G,请找出其中出现次数最多的3个url

题目剖析:

数据理解:4G即4,294,967,296字节,可以处理67,108,864个url,即0.67亿个。可分两种情况讨论,一个是小于0.67亿个URL的时候和大于0.67亿个URL的时候

解题重点: 分类处理

解题思路:

1、N小于0.67亿

计算url的hash,通过hash得到每个url的次数,遍历hash找出最大的三个

2、N大于等于0.67
用hash把N个数据分成Y=N/0.67亿(分组数量Y贴近2^X),在每组找出最多的3个,再在Y个组里找出最多的三个进行比对。

.

给定a、b两个文件,各放50亿各url,每个url各占64字节,内存限制是4G,找出a、b文件共同的url

数据理解

一个url64字节,每个文件50亿个,即一个文件298GB,两个文件一共569G,远大于4G

假设所有Url相同,则同时存储相同url时,需要使用内存298GB,也远大于4G

可以考虑分数据块考虑问题,例如哈希分组,每个组内可能有相同的数据,但是不同组肯定没有相同的数据

假设1个文件分组N组,则每组占用空间298/N,要用到2组,则每次加载需要空间2*298/N,另考虑计算用的内存,假设分成1024组,则每次加载数据使用内存598MB。

解题思路

1、将a,b文件分别按N进行哈希分组,先将第一组分别加载进数组。(598)

2、将a数组映射到hashmap里面(298),再遍历b数据,比对是否会存在一样的url,有就保存下来,输出

3、释放内存,再循环后续的分组
.
.

有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存大小限制是1M,要求返回频数最高的100个词?

数据理解:

1个词16B,100个词即1.56KB

1G文件,存的都是16B的词,即16,777,216个词

1M内存,最大能存16,384个词,那么处理1G的词,刚好需要1024个分区,秉承预留运行内存、防止数据严重倾斜的思想,划分2^11即2048个分区,每个分区使用内存情况不确定,因为有可能出现倾斜,出现数据倾斜就要进行二次分组,确保每个分区的大小不超过一定的值

解题思路:(理想情况,不需要二次分组)

1、将文件采用哈希分组分成2048个分区,将第一个分区的数据加载进hashmap,取出value最大的100个词,持久化到文件中,这样就可以得到2048个文件,每个文件有1600B的数据,即一共3.125MB

2、将所有文件加载到内存中,将entry放入容量为100的大顶堆里,按value排序,得到100个最大的值

猜你喜欢

转载自blog.csdn.net/weixin_42712876/article/details/85220084