大数据算法面试题目及答案(一)

01 如何从海量数据中找出最高频词

题目描述:

有一个GB大小的文件,文件里面每一行是一个英文单词,每个单词的大小不超过16个字节,内存限制是1MB。请设计一个算法思路,返回单词词频数最高的100个单词(Top100)。

题目解析:

题目中文件的大小为1GB,由于内存大小的限制,我们无法直接将这个大文件的所有单词一次性读入内存中。因此我们需要采用分治法,将一个大文件分割成若干个小文件,并且每个小文件的大小不超过1MB,从而能将每个小文件分别加载到内存中进行处理。然后使用HashMap分别统计出每个小文件的单词词频数,并获取每个小文件词频最高的100个单词。最后使用小顶堆统计出所有单词中出现词频最高的100个单词。

实现方式:分治法

步骤1

首先遍历这个大文件,对文件中遍历到的每个单词word,执行n=hash(word)%5000操作,然后将结果为n的单词存放到第fn个文件中。整个大文件遍历结束之后,我们可以得到5000个小文件,每个小文件的大小为200KB左右。如果有的小文件的大小仍然超过1MB,则采用同样的方式继续进行分解,直到每个小文件的大小都小于1MB为止。文件分割过程如图1-1所示。

图1-1 文件分割过程

步骤2

分别统计每个小文件中出现单词词频数最高的100个单词,最简单的实现方式是使用HashMap来实现,其中key为单词,value为该单词出现的词频数。具体做法是:遍历文件中的所有单词,对于遍历到的单词word,如果word在map中不存在,那么就执行map.put(word,1),将该词频设置为1;如果word在map中存在,那么就执行map.put(word,map.get(word)+1),将该单词词频数加1。遍历完成之后,可以很容易找出每个文件出现频率最高的100个单词。词频统计逻辑如图1-1所示。

图1-1词频统计逻辑

步骤3

因为步骤2已经找出了每个文件出现频率最高的100个单词,接下来我们可以通过维护一个小顶堆来找出所有单词中出现频率最高的100个单词。具体做法是:依次遍历每个小文件,构建一个小顶堆,堆大小为100。如果遍历到的单词出现的次数大于堆顶单词出现的次数,那么就用新单词替换堆顶的单词,然后重新调整为小顶堆。当遍历完所有文件后,小顶堆中的单词就是出现频率最高的100个单词。小顶堆构建过程如图1-1所示。

如图1-1 小顶堆构建过程

方法总结:

针对限定内存,求解海量数据的TopN问题,可以采取以下几个步骤。

1.分而治之,利用哈希取余,将大文件分割为小文件。

2.使用HashMap统计每个单词的词频。

3.求解词频最大的TopN,使用小顶堆;求解词频最小的TopN,使用大顶堆。

02 如何找出访问百度最多的IP地址

题目描述:

现在有一个1亿条记录的超大文件,里面包含着某一天海量用户访问日志,但已有内存存放不下该文件,现要求从这个超大文件中统计出某天访问百度次数最多的那个IP地址。

题目解析:

因为题目中只关心访问百度最多的IP地址,所以需要对原始文件进行遍历,将这一天访问百度的IP的相关记录输出到一个单独的大文件中。由于内存大小的限制,我们无法将这个大文件一次性加载到内存中,所以需要采用分治法将大文件分割为若干个小文件,直到内存可以装下每个小文件为止。然后使用HashMap分别统计出每个小文件中的每个IP地址出现的次数,并找出每个小文件中出现次数最多的IP地址。最后比较所有小文件中出现次数最多的IP,从而最终统计出这个超大文件中访问百度最多的IP地址。

实现方式:分治法

步骤1

首先遍历超大原始日志文件,将包含百度url地址的相关信息记录输出到一个单独的大文件中,那么这个新生成的大文件只包含访问百度的相关信息记录。文件过滤如图1-1所示。

图1-1 文件过滤

步骤2

然后遍历新生成的大文件,对文件中遍历到的每个IP执行n=hash(IP)%1000操作,将结果为n的日志记录放到第fn个文件中。整个大文件遍历结束后,我们可以得到1000个小文件。那么相同的IP会存储到同一个文件中,分割后的每个小文件的大小为大文件的1/1000。如果分割后的文件中仍然有部分文件无法装载到内存中,可以对该文件进行分割直至内存可以装下为止。文件分割过程如图1-1所示。

如图1-1 文件分割过程

步骤3

接着统计每个小文件中出现次数最多的IP,最简单的方法是通过HashMap来实现,其中key为IP地址,value为该IP地址出现的次数。具体做法是:遍历每个小文件中的所有记录,对于遍历到的IP,如果IP地址在map中不存在,那么就执行map.put(IP,1),将该IP出现次数设置为1;如果IP地址在map中存在,那么就执行map.put(IP,map.get(IP)+1),将该IP出现的次数加1。然后再遍历HashMap,可以很容易分别统计出每个文件中访问百度次数做多的IP。IP访问次数统计逻辑如图1-1所示。

如图1-1 IP访问次数统计逻辑

步骤4

最后比较所有小文件中访问百度次数最多的IP,便可以统计出整个超大文件中某日访问百度次数最多的IP地址。结果汇总过程如图1-1所示

如图1-1 结果汇总过程

方法总结:

针对限定内存,求解海量数据的最大值问题,可以采取以下几个步骤。

1.分而治之,利用哈希取余,将大文件分割为小文件。

2.使用HashMap统计每个IP出现的次数。

3.求解IP出现次数的最大值,遍历HashMap即可。

03 如何从2.5亿个整数中找出不重复的整数

题目描述:

在2.5亿个整数文件中找出不重复的整数。

备注:现有内存无法容纳2.5亿个整数。

题目解析:

题目中已经说明现有内存无法容纳2.5亿个整数,所以我们无法一次性将所有数据加载到内存中进行处理。

实现方式1:分治法

由于无法直接将2.5亿个整数一次性加载到内存处理,所以我们需要采用分治法,将一个大文件分割成若干个小文件,从而能将每个小文件分别加载到内存中进行处理,然后使用HashMap分别统计出每个小文件中每个整数出现的次数,最后遍历HashMap输出value值为1的整数即可。

步骤1

首先遍历这个大文件,对文件中遍历到的每个整数digit执行hash(digit)%1000操作,将结果为n的整数存放到第fn个文件中。整个大文件遍历结束之后,我们就可以将2.5亿个整数划分到1000个小文件中。那么相同的整数会存储到同一个文件中,分割后的每个小文件的大小为大文件的1/1000。如果有的小文件仍然无法加载到内存中,则可以采用同样的方式继续进分解,直到每个小文件都可以加载到内存中为止。文件分割过程如图1-1所示。

如图1-1 文件分割过程

步骤2

然后在每个小文件中找出不重复的整数,最简单的方法是通过HashMap来实现,其中key为整数,value为该整数出现的次数。具体做法是:遍历每个小文件中的所有记录,对于遍历到的整数digit,如果digit在map中不存在,那么就执行map.put(digit,1),将digit出现次数设置为1;如果digit在map中存在,那么就执行map.put(digit,map.get(digit)+1),将digit出现的次数加1。整数出现次数统计逻辑如图1-1所示。

如图1-1 整数出现次数统计逻辑

步骤3

最后针对每个小文件,遍历HashMap输出value为1的所有整数,就可以找出这2.5亿个整数中所有的不重复的数。这里不用再对每个小文件输出的整数进行重复筛重,因为每个整数经过hash函数处理后,相同的整数只会被划分到同一个小文件中,不同的文件中不会出现重复的整数。

实现方式2:位图法

对于整数相关的算法的求解,位图法是一种非常实用的算法。假设整数占用4B,即32bit,那么可以表示的整数的个数为2^32。那么对于本题目来说,我们只需要查找不重复的数,而无需关心具体整数出现的次数,所以可以分别使用2个bit来表示各个数字的状态:00表示这个数字没有出现过;01表示这个数字出现过一次;10表示这个数字出现过多次。那么这2^32个整数,总共需要的内存为2^32*2b=1GB。因此,当可用内存超过1GB时,可以采用位图法求解该题目。

步骤1

首先需要开辟一个用2Bitmap法标志的2^32个整数的桶数组,并初始化标记位为00,其存储的数据量远远大于2.5亿个整数。开辟并初始化位图如图1-1所示。

如图1-1开辟并初始化位图

步骤2

然后遍历2.5亿个整数,并查看每个整数在位图中对应的位,如果位值为00,则修改为01,如果位值为01,则修改为10,如果位值为10则保持不变。遍历数据并修改位图状态如图1-1所示。

如图1-1 遍历数据并修改位图状态

步骤3

最后当所有数据都遍历完成之后,可以再遍历一遍位图,把对应位值是01的整数输出,即可统计出2.5亿个整数中所有不重复的数。

方法总结:

判断整数是否重复的问题,位图法是一种非常高效的方法,当然前提是:内存要满足位图法所需要的存储空间。

04 判断一个数在40亿数据中是否存在

题目描述:

给定40亿个不重复的没有排序过的整数,然后再给定一个整数,如何快速判断这个整数是否包含在这40亿个整数当中。备注:现有内存不足以容纳这40亿个整数。

题目解析:

题目中已经说明现有内存无法容纳40亿个整数,所以我们无法一次性将所有数据加载到内存中进行处理,那么最容易想到的方法还是分治法。

实现方式1:分治法

根据实际内存大小情况,确定一个hash函数,比如hash(digit)%1000,通过这个hash函数将40亿个整数划分到若干个小文件(f1,f2,f3,...,f1000),从而确保每个小文件都能加载到内存中进行处理。然后再对待找出的整数使用相同的hash函数求出hash值,假设计算出的这个hash值为n,如果这个整数存在的话,那么它一定存在fn文件中。接着将fn文件中所有的整数都保存到HashSet中,最后判断待查找的整数是否存在。由于详细步骤与前面分治法类似,这里就不再赘述了。

实现方式2:位图法

假设整数占用4B,即32bit,那么可以表示的整数的个数为2^32。那么对于本题目来说,我们只需要判断整数是否存在,而无需关心整数出现的次数,所以可以使用1个bit来标记整数是否存在:0表示这个整数不存在;1表示这个整数存在。那么这2^32个整数,总共需要的内存为2^32*2b=1GB。因此,当可用内存超过1GB时,可以采用位图法求解该题目。

步骤1

首先需要开辟一个用1Bitmap法标志的2^32个整数的桶数组,并初始化标记位为0,其存储的数据量大于40亿个整数。开辟并初始化位图如图1-1所示。

如图1-1开辟并初始化位图

步骤2

然后遍历40亿个整数,将对应的位值设置为1。遍历数据并修改位图状态如图1-1所示。

如图1-1 遍历数据并修改位图状态

步骤3

最后再读取要查询的整数,查看对应的位值是否为1,如果位值为1表示存在,如果位值为0表示不存在。

方法总结:

判断数字是否存在、判断数字是否重复的问题,位图法是一种非常高效的方法。

05 如何找出CSDN网站最热门的搜索关键词

题目描述:

CSDN网站搜索引擎会通过日志文件把用户每次搜索使用关键词都记录下来,每个查询关键词限定长度为1~255个字节。假设目前有1000万个搜索记录,现要求统计最热门的10个搜索关键词。备注:现有内存不超过1GB。

题目解析:

从题目中给出的信息可知,每个搜索关键词最长为255个字节,1000万个搜索记录需要占用约10000000*255B≈2.55GB内存,因此,我们无法将所有搜索记录全部读入内存中处理。

实现方式1:分治法

分治法依然是一个非常实用的方法。首先将整个搜索记录文件分割为多个小文件,保证单个小文件中的搜索记录可以全部加载到内存中处理,然后统计出每个小文件中出现次数最多的10个搜索关键词,最后设计一个小顶堆统计出所有文件中出现最多的10个搜索关键词。在本题目中,分治法虽然可行,但不是最好的方法,因为需要2次遍历文件,分割文件的Hash函数被调用1000万次,所以性能不是很好,这里就不再赘述。

实现方式2:HashMap法

虽然题目中搜索关键词的总数比较多,但是一般关键词的重复度比较高,去重之后搜索关键词不超过300万个,因此可以考虑把所有搜索关键词及出现的次数保存到HashMap中,由于存储次数的整数一般占用4个字节,所以HashMap所需要占用的空间为300万*(255+4)≈800M,因此题目中限定的1GB内存完全够用。

步骤1

首先遍历所有搜索关键词,如果关键词存在与map中,则value值累加1;如果关键词不在map中,则value值设置为1。关键词出现次数统计逻辑如图1-1所示。

如图1-1 关键词出现次数统计逻辑

步骤2

然后遍历map集合,构建一个包含10个元素的小顶堆,如果遍历到的关键词出现的次数大于堆顶关键词出现的次数,则进行替换,并将堆调整为小顶堆。小顶堆构建过程如图1-1所示。

图1-1 小顶堆构建过程

步骤3

最后直接取出堆中的10个关键词就是出现次数最多的字符串。

实现方式3:前缀树法

前缀树:又称为字典树、单词查找树,是一种哈希树的变种。典型应用是用于统计、排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。

实现方式2使用了HashMap来统计关键词出现的次数,当这些关键词有大量相同的前缀时,可以考虑使用前缀树来统计搜索关键词出现的次数,树的结点可以保存关键词出现的次数。

步骤1

首先遍历所有搜索关键词,针对每个关键词在前缀树中查找,如果能找到,则把结点中保存的关键词次数加1,否则就为这个关键词构建新的结点,构建完成之后把叶子结点中关键词的出现次数设置为1。当遍历完所有关键词之后,就可以知道每个关键词的出现次数了。前缀树的构建过程如图1-1所示。

如图1-1 前缀树的构建过程

备注:每个结点中的P表示所有字符添加到树的过程中,这个结点到达过几次,E表示当前结点有多少个字符串是以它结尾。

步骤2

然后遍历前缀树,就可以找出出现次数最多的关键词。

方法总结:

前缀树经常被用来统计字符串的出现次数,它的另外一个用途是字符串查找,判断是否有重复的字符串等。

关注【大数据研习社】公众号回复【大数据算法面试】领取!

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. 什么是大数据? 答:大数据是指数据量过大、复杂度高、处理速度快的数据,这些数据通常来自于各种不同的来源,包括传感器、社交媒体、互联网搜索、交易记录等。 2. 大数据的四个特点是什么? 答:大数据的四个特点是:数据量大、数据速度快、数据种类多、数据价值高。 3. Hadoop的主要组成部分是什么? 答:Hadoop的主要组成部分包括:Hadoop Distributed File System(HDFS)、MapReduce计算框架、YARN资源管理器。 4. 什么是MapReduce? 答:MapReduce是一种基于分布式计算模型的计算框架,用于处理大规模数据集。它将数据划分为多个小块,并在分布式计算节点上并行执行计算任务。 5. Hadoop和Spark的区别是什么? 答:Hadoop是一个基于MapReduce计算框架的分布式计算平台,而Spark是一个基于内存计算的分布式计算平台。Spark比Hadoop更快,更灵活,支持更多的数据处理任务和算法。 6. 什么是NoSQL数据库? 答:NoSQL数据库是一种非关系型数据库,适用于处理大量非结构化数据和半结构化数据,例如面向文档、键值对、列族等。 7. 什么是ETL过程? 答:ETL过程是将数据从不同的来源提取、转换和加载到目标数据库中的过程。ETL代表抽取、转换和加载。 8. 什么是数据仓库? 答:数据仓库是一个用于存储和管理大量结构化数据的系统,数据仓库通常用于支持企业的决策和分析。 9. 什么是数据挖掘? 答:数据挖掘是一种从大量数据中发现有用信息的过程,通常涉及使用统计分析、机器学习和人工智能技术。 10. 什么是机器学习? 答:机器学习是一种通过训练算法,使计算机系统能够自动改进和学习的方法。 11. 什么是深度学习? 答:深度学习是一种机器学习技术,它使用多层神经网络实现自动特征提取和分类。 12. 什么是人工智能? 答:人工智能是一种计算机科学技术,旨在使计算机系统能够模拟人类智能行为,包括学习、推理、自适应和创造性思考等。 13. 什么是大数据分析? 答:大数据分析是使用各种技术和工具对大量数据进行处理,以发现有用的信息、趋势和模式。 14. 什么是数据可视化? 答:数据可视化是通过图表、图形和其他视觉元素将数据呈现出来的过程,以便于人们理解和分析数据。 15. 什么是自然语言处理? 答:自然语言处理是一种计算机科学技术,旨在使计算机系统能够理解、处理和生成自然语言文本。 16. 什么是分布式计算? 答:分布式计算是将计算任务分配给多个计算机节点,以便更快地完成任务。 17. 什么是云计算? 答:云计算是一种通过互联网提供计算资源和服务的方法,包括存储、处理和分析大量数据。 18. 什么是流式数据? 答:流式数据是一种连续产生的数据,通常以流的形式传输和处理。 19. 什么是数据安全? 答:数据安全是指保护数据免受未经授权的访问、使用、泄露或修改的过程。 20. 什么是隐私保护? 答:隐私保护是指保护个人信息和隐私免受未经授权的访问、使用、泄露或修改的过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据研习社

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值