【海量数据处理】面试高频点

50亿数据如何去重?

面对一个如此大的数据集进行去重(例如50亿数据条目),我们需要考虑内存和存储空间的限制,同时还需要有一个高效的算法。一般来说,这样的数据量无法直接载入内存进行处理,因此需要采用磁盘存储和分布式处理的技术。以下是一些可行的方法:

外部排序:

将数据分为多个批次,每个可以加载到内存中。
对每一批数据进行排序和去重,然后存回磁盘。
对所有排序且去重后的批次进行归并排序,同时去重。
适用范围:大数据的排序,去重
基本原理及要点:外排序的归并方法,置换选择败者树原理,最优归并树

哈希切分(Hash partitioning):

使用哈希函数将数据分配到不同的桶(Bucket)或文件中,确保相同的数据项会落到同一个桶里。
对每个桶的数据进行内存中去重操作。
对所有桶进行并行处理以提升效率,并最终合并结果。
适用范围:快速查找,删除的基本数据结构,通常需要总数据量可以放入内存

Bitmap方法:

使用Bitmap算法,每一位表示一个数据,此方法适用于非负整数数据,尤其是范围较小的情况。
如果数据范围过大,可以结合哈希切分使用。
基本原理及要点:使用bit数组来表示某些元素是否存在,比如8位电话号码
适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下

Bloom过滤器:

使用Bloom Filter预处理数据,快速刷选出可能重复的数据。
通过更精确的方法再次检查这部分数据以确认去重。

分布式系统处理:

如果单机处理能力有限,可以使用分布式计算框架如Hadoop或Spark。
在这样的系统中可以使用MapReduce或Spark的RDD/DataFrame转化操作来进行分布式去重。
适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集

数据库和NoSQL解决方案:

利用支持强大索引机制的数据库进行去重操作。
使用如Redis这样的内存数据库,通过其内置的数据结构和算法进行高效去重处理,特别是需要实时去重的场景。
针对50亿这样大规模的数据,任何单一的技术可能都不足够,通常需要结合使用多种技术和算法。务必考虑实际应用场景,数据的特性和可用资源。处理如此大量数据通常还伴随着各种系统层面的优化,包括IO优化、内存管理和并发控制等方面。

50 亿数据如何排序?

处理50亿数据的排序问题时,传统单机内存排序是不现实的,因为这样的数据量远远超出了常规服务器的内存容量。因此,需要采用一些特殊的技术和方法来处理这种大规模数据集。以下是几种处理这类问题的方法:

外部排序:

最基本的处理大数据排序的方法是外部排序,特别是当数据无法全部加载到内存中时。外部排序的基本思路是将大文件分割成多个小文件,小文件加载到内存中进行排序,然后再将排序后的小文件合并成一个有序的大文件。
这个过程通常涉及到数据的分块、排序、合并等步骤。经典的算法是多路归并排序(K-way Merge Sort)。
适用范围:大数据的排序,去重
基本原理及要点:外排序的归并方法,置换选择败者树原理,最优归并树
问题实例

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

这个数据具有很明显的特点,词的大小为16个字节,但是内存只有1m做hash有些不够,所以可以用来排序。内存可以当输入缓冲区使用。

分布式排序:

使用分布式计算框架,如Hadoop或Spark,可以将数据分布到多个节点上并行处理。
在Hadoop上可以使用MapReduce编程模型实现分布式排序,其中Map阶段进行局部排序,Reduce阶段负责将所有结果合并成全局有序的数据。
Spark提供了更为高效的内存计算能力,可以使用它的sortBy或orderBy函数来进行分布式数据排序。

利用数据库:

可以将数据导入关系型数据库或NoSQL数据库中,利用数据库的索引和查询优化器来实现排序。关系型数据库对于排序功能的支持很成熟,可以很方便地处理外部排序。
使用排序软件:
有一些专门的大数据排序软件和工具,如Unix/Linux环境下的sort命令,它支持对大文件进行外部排序。通过合理地配置参数,sort命令可以在处理大文件时,自动将数据分割、排序和合并。

堆排序和内存映射:

对于稍微小一些的数据集或者可以被划分为小块进行处理的数据集,可以使用堆排序结合内存映射文件的技术。内存映射文件可以让你以接近内存速度访问磁盘上的数据,而堆排序可以帮助你有效地从中找到最小(或最大)元素。
处理50亿数据排序的关键在于将问题分解,并利用并行处理和磁盘I/O优化等方法来提升效率。在实际操作中,要根据数据的具体特征和可用资源来选择最合适的方法。

适用范围:海量数据前n大,并且n比较小,堆可以放入内存

基本原理及要点:最大堆求前n小,最小堆求前n大。方法,比如求前n小,我们比较当前元素与最大堆里的最大元素,如果它小于最大元素,则应该替换那个最大元素。这样最后得到的n个元素就是最小的n个。适合大数据量,求前n小,n的大小比较小的情况,这样可以扫描一遍即可得到所有的前n元素,效率很高。

扩展:双堆,一个最大堆与一个最小堆结合,可以用来维护中位数

trie树

适用范围:数据量大,重复多,但是数据种类小可以放入内存
基本原理及要点:实现方式,节点孩子的表示方式
扩展:压缩实现。
问题实例
  1).有10个文件,每个文件1G,每个文件的每一行都存放的是用户的query,每个文件的query都可能重复。要你按照query的频度排序。
  2).1000万字符串,其中有些是相同的(重复),需要把重复的全部去掉,保留没有重复的字符串。请问怎么设计和实现?
  3).寻找热门查询:查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个,每个不超过255字节。

分布式处理

适用范围:数据量大,但是数据种类小可以放入内存

基本原理及要点:将数据交给不同的机器去处理,数据划分,结果归约。

问题实例

1).The canonical example application of MapReduce is a process to count the appearances ofeach different word in a set of documents:

2).海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。

3).一共有N个机器,每个机器上有N个数。每个机器最多存O(N)个数并对它们操作。如何找到N^2个数的中数(median)?

面试题:

1.海量日志数据,提取出某日访问百度次数最多的那个IP

答:IP的数目还是有限的,最多2^32个,所以可以考虑使用hash将ip直接存入内存,然后进行统计。

再详细介绍下此方案:首先是这一天,并且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个 IP。同样可以采用映射的方法,比如模1000,把整个大文件映射为1000个小文件,再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。然后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求。

2.举例:40亿QQ号如何设计算法去重(相同的QQ号码仅保留一个,内存限制为1个G)

腾讯的QQ号都是4字节正整数,所以QQ号码的个数是43亿左右,理论值2^32-1个,又因为是无符号的,翻倍了一下,所以43亿左右。

方法1:排序
这估计也是最多人能够想到的解决方法,那就是排序,重复的QQ肯定会挨在一起,然后保留第一个,去重就行了。排序后的去重比较简单就不在这里赘述。
但是这么做的问题显然很大,时间复杂大太高了,效率低下。
方法2:hsahmap
hashmap的意思:
如果使用hashmap,好处是由于hashmap的去重性质,就可以做到去重。看似上个问题的效率问题解决了,但是又遇到了新的问题,1g的内存太小,解决不了。
方法3:文件切割
对于海量数据问题,可以使用文件切割方式,避免内存过大。但是还是需要使用文件间的归并排序、桶排序、堆排序等等,但是这么多文件操作,40亿的数据量还是比较大,那么有没有更好的方法。
方法4:bitmap位图操作
可以对hashmap进行优化,采用bitmap这种数据结构,可以顺利地同时解决时间问题和空间问题。
在很多实际项目中,bitmap经常用到。

3.搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。

假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10个查询串,要求使用的内存不能超过1G。

典型的Top K算法,还是在这篇文章里头有所阐述。 文中,给出的最终算法是:第一步、先对这批海量数据预处理,在O(N)的时间内用Hash表完成排序;然后,第二步、借助堆这个数据结构,找出Top K,时间复杂度为N‘logK。 即,借助堆结构,我们可以在log量级的时间内查找和调整/移动。因此,维护一个K(该题目中是10)大小的小根堆,然后遍历300万的Query,分别和根元素进行对比所以,我们最终的时间复杂度是:O(N) + N’*O(logK),(N为1000万,N’为300万)。

4.怎么在海量数据中找出重复次数最多的一个?

先做hash,然后求模映射为小文件,求出每个小文件中重复次数最多的一个,并记录重复次数。然后找出上一步求出的数据中重复次数最多的一个就是所求(具体参考前面的题)

5.上千万或上亿数据(有重复),统计其中出现次数最多的钱N个数据

上千万或上亿的数据,现在的机器的内存应该能存下。所以考虑采用hash_map/搜索二叉树/红黑树等来进行统计次数。然后就是取出前N个出现次数最多的数据了,可以用第3题提到的堆机制完成

6.一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。

方案1:这题是考虑时间效率。用trie树统计每个词出现的次数,时间复杂度是O(nle)(le表示单词的平准长度)。然后是找出出现最频繁的前10个词,可以用堆来实现,前面的题中已经讲到了,时间复杂度是O(nlg10)。所以总的时间复杂度,是O(nle)与O(nlg10)中较大的哪一个。

附、100w个数中找出最大的100个数。

方案1:在前面的题中,我们已经提到了,用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)。

方案2:采用快速排序的思想,每次分割之后只考虑比轴大的一部分,知道比轴大的一部分在比100多的时候,采用传统排序算法排序,取前100个。复杂度为O(100w*100)。

方案3:采用局部淘汰法。选取前100个元素,并排序,记为序列L。然后一次扫描剩余的元素x,与排好序的100个元素中最小的元素比,如果比这个最小的要大,那么把这个最小的元素删除,并把x利用插入排序的思想,插入到序列L中。依次循环,知道扫描了所有的元素。复杂度为O(100w*100)。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值