当前位置: 首页 > 面试题库 >

特别大的数据量,如何实现查找,排序?

余善
2023-03-14
本文向大家介绍特别大的数据量,如何实现查找,排序?相关面试题,主要包含被问及特别大的数据量,如何实现查找,排序?时的应答技巧和注意事项,需要的朋友参考一下

参考回答:

1)、位图法

位图法是我在编程珠玑上看到的一种比较新颖的方法,思路比较巧妙效率也很高。

使用场景举例:对2G的数据量进行排序,这是基本要求。

数据:1、每个数据不大于8亿;2、数据类型位int;3、每个数据最多重复一次。

内存:最多用200M的内存进行操作。

首先对占用的内存进行判断,每个数据不大于8亿,那么8亿是一个什么概念呢。

**

1 byte = 8 bit(位)

1024 byte = 8*1024 bit = 1k

1024 k = 810241024 bit = 1M = 8388608 bit

**

也就是1M=8388608位

而位图法的基本思想就是利用一位代表一个数字,例如3位上为1,则说明3在数据中出现过,若为0,则说明3在数据中没有出现过。所以当题目中出现每个数据最多重复一次这个条件时,我们可以考虑使用位图法来进行大数据排序。

那么假如使用位图法来进行这题的排序,内存占用多少呢。由题目知道每个数据不大于8亿,那么我们就需要8亿位,占用800000000/8388608=95M的空间,满足最多使用200M内存进行操作的条件,这也是这题能够使用位图法来解决的一个基础。

2)、堆排序法

堆排序是4种平均时间复杂度为nlogn的排序方法之一,其优点在于当求M个数中的前n个最大数,和最小数的时候性能极好。所以当从海量数据中要找出前m个最大值或最小值,而对其他值没有要求时,使用堆排序法效果很好。

使用场景:从1亿个整数里找出100个最大的数

步骤:

(1)读取前100个数字,建立最大值堆。(这里采用堆排序将空间复杂度讲得很低,要排序1亿个数,但一次性只需读取100个数字,或者设置其他基数,不需要1次性读完所有数据,降低对内存要求)

(2)依次读取余下的数,与最大值堆作比较,维持最大值堆。可以每次读取的数量为一个磁盘页面,将每个页面的数据依次进堆比较,这样节省IO时间。

(3)将堆进行排序,即可得到100个有序最大值。

堆排序是一种常见的算法,但了解其的使用场景能够帮助我们更好的理解它。

3)、较为通用的分治策略

分治策略师对常见复杂问题的一种万能的解决方法,虽然很多情况下,分治策略的解法都不是最优解,但是其通用性很强。分治法的核心就是将一个复杂的问题通过分解抽象成若干个简单的问题。

应用场景:10G的数据,在2G内存的单台机器上排序的算法

我的想法,这个场景既没有介绍数据是否有重复,也没有给出数据的范围,也不是求最大的个数。而通过分治虽然可能需要的io次数很多,但是对解决这个问题还是具有一定的可行性的。

步骤:

(1)从大数据中抽取样本,将需要排序的数据切分为多个样本数大致相等的区间,例如:1-100,101-300…

(2)将大数据文件切分为多个小数据文件,这里要考虑IO次数和硬件资源问题,例如可将小数据文件数设定为1G(要预留内存给执行时的程序使用)

(3)使用最优的算法对小数据文件的数据进行排序,将排序结果按照步骤1划分的区间进行存储

(4)对各个数据区间内的排序结果文件进行处理,最终每个区间得到一个排序结果的文件

(5)将各个区间的排序结果合并。通过分治将大数据变成小数据进行处理,再合并。

#分治排序
def merge(left,right):
    temp=[]
    begin1=begin2=1
    while begin1<len(left) and begin2<len(right):
        if left[begin1]<right[begin2]:
            temp.append(left[begin1])
            begin1+=1
        else:
            temp.append(right[begin2])
            begin2+=1
    if begin1==len(left) and begin2<len(right):
        temp.append(n for n in right[begin2:])
    if begin2==len(right) and begin1<len(left):
        temp.append(n for n in left[:begin1])
    return temp
 
def merge_sort(num_list):
    mid=int(len(num_list)/2)
    if len(num_list)<=1:
        return num_list
    left=num_list[:mid]
    right=num_list[mid:]
    return merge(left,right)

 

 类似资料:
  • 本文向大家介绍Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?相关面试题,主要包含被问及Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?时的应答技巧和注意事项,需要的朋友参考一下 Elasticsearch 提供的首个近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的 distinct 或者unique 值的数目。它是基于 HLL 算

  • 问题内容: 假设我们有一个具有如此简单结构的“汽车”表… 拳头,我选择的是汽车(1,黑色,重型,豪华轿车),然后我想获取相关汽车的列表,这些列表按匹配列的数量排序(没有任何列的权重)。所以,首先我期望看到(黑色,重型,豪华轿车)汽车,然后我期望看到只有2个匹配字段的汽车,等等。 是否可以使用SQL执行这种排序? 对不起,我的英语,但我真的希望我对您的问题很清楚。 谢谢你。 问题答案: 可能有几种方

  • 问题内容: 因此,我正在编写一个从redis读取的节点应用程序,我想执行某种查询,该查询返回有人知道怎么做的数据库数量。 因此,现在基本上我所拥有的是一种获取数据库中所有密钥的方法,但是我希望级别更高,我想遍历所有数据库然后获取所有密钥。这是用于获取当前数据库的所有密钥的代码。 问题答案: 解决方案1 正如@carebdayrvis所提到的,您可以使用command获取数据库信息,并解析该信息以获

  • 本文向大家介绍mysql 大表批量删除大量数据的实现方法,包括了mysql 大表批量删除大量数据的实现方法的使用技巧和注意事项,需要的朋友参考一下 问题参考自:https://www.zhihu.com/question/440066129/answer/1685329456 ,mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量差不多占50

  • 问题内容: 我想知道如何在数据库中最好地实现“ 观看次数最多 ”的功能(例如youtube)。 让我来解释一下“ 最多观看 ”功能更好一点: 基本上,我想列出从这天/周/月访问最多的网页/视频/等,见 http://www.youtube.com/charts/videos_views为一个例子。 因此,我想知道如何最好地实现此功能,因为我可以想到许多实现此功能的方法,但是所有方法都具有+和-的含

  • 问题内容: 这可能是一个琐碎的问题。但是,由于我正在研究很久以前由其他人创建的数据库,没有适当的文档或注释,因此遇到了一个关键问题,我需要知道如何将数据插入到特定表中吗?是否有任何脚本或其他方法可以标识数据源。换句话说,我需要知道是否通过某些过程,函数,手动…等插入了数据。我无法搜索所有过程或函数,它们有数百个。我正在使用SQL Developer,它是oracle 11g DB。 问题答案: 没