算法通关村第十五关白银挑战——海量数据场景下的热门算法题

news2024/11/17 12:52:33

大家好,我是怒码少年小码。

最近超级忙,很多实验报告,已经四五天没搞了,但是我还是回来了!

海量数据场景下的热门算法题

本篇的题目不要求写代码,面试的时候能很清楚的说出思路就可以了。

1. 从40个亿中产生一个不存在的整数

题目要求:给定一个输入文件,包含40亿个非负整数,设计一个算法,产生一个不存在该文件的整数,假设你有1GB的内存来完成这项任务

进阶:如果只有10MB的内存可用,该怎么办

位图存储大数据的原理

假设用哈希表来保存出现过的数,如果40亿个数都不同,则哈希表的记录数为40亿条,存一个32位整数需要4B,所以最差情况需要40亿 * 4B = 160亿字节,大约需要16GB的空间,不符合要求

  • 40亿 * 4B = 160 亿字节,大约需要16GB
  • 40亿 / 8字节 = 5亿字节,大约0.5GB的数组就可以存下40亿个

如果数据量很大,采用位方式(俗称位图)存储数据是常用的思路。
我们使用bit map(比特数组)的方式来表示数出现的情况。即申请一个长度为4294967 295的bit类型的数组bitArr(就是boolean类型),bitArr上的每个位置只可以表示0 或 1状态。8个bit 为1B,所以长度为4294967 295的bit 类型的数组占用5000MB空间,满足题目给定的要求

使用bitArr数组的方法:遍历40亿个无符号数,遇到所有的数时,就把bitArr相应位置的值设置为1。例如,遇到1000,就把bitArr[1000]设置为1
遍历完成后,再依次遍历bitArr数组,看看哪个位置上的值没被设置为1,这个数就不在40亿个数中。例如,发现bitArr[8001] == 0,那么8001就是没出现过的数,遍历完bitArr之后,所有没出现的数就都没出来了。

位存储的核心是:存储的并不是这40亿个数据本身,而是其对应的位置。

进阶:使用10MB来存储

如果只有10MB内存,位图也不能完成。使用分块思想,时间换空间,通过两次遍历完成
40亿个数采用位图至少需要0.5GB空间,如果只有10MB空间,也至少需要50个块
一般来说,划分都是使用2的整数倍,因此划分成64个块比较合理

一共只有40亿个数,所以,如果统计落在每一个区间上的数有多少,肯定有至少一个区间上的计数少于67 108 864(2^32 / 64)。利用这个可以找出其中一个没出现的数。

  1. 如果当前数是 3422552090, 3422552090 / 67 108 864 = 51,所以第51区间上的计数增加countArr[51]++。

  2. 遍历完40亿个数之后,遍历countArr,必然会有某一个位置上的值(countArr[i])小于67 108 864,表示第 i 区间上至少有一个数没出现过。此时使用的内存就是countArr的大小(64 * 4B),占用的空间非常小

  3. 假设找到第37区间上的计数小于67 108 864(知道哪些区间计数小于67 108 864计数),然后对40亿个数据进行第二次遍历

  • 申请长度为67 108 864的bit map(比特数组),占用大约8MB空间,记为bitArr[0…67 108 864]
  • 遍历这40亿个数,此时的遍历只关注落在第37区间上的数,记为num (num满足num / 67 108 864 == 37),其他区间的数全部忽略
  • 如果步骤2的num在第37区间上,将bit[num - 67 108 864 * 37]的值设置为1,也就是只做第37区间上的数bitArr映射(通过相减可以得到在bit数组的位置i)
  • 遍历完40亿个数之后,在bitArr上必然存在没被设置成1的位置,假设第i个位置上的值没设置成1,那么67 108 864* 37 + i这个数就是一个没出现过的数
总结:
  1. 根据10MB的内存限制,确定统计区间的大小,就是第二次遍历时的bitArr大小
  2. 利用区间计数的方式(用countArr[i]++),找到那个计数不足的区间,这个区间上肯定有没出现的数
  3. 对这个区间上的数做bit map映射,再遍历bit map(bit数组),找到一个没出现的数即可
如何确定分块的区间

针对上面例子中分块大小为64块的问题,为什么不是128块、32块、16块或其他类型
主要保证第二次遍历时每个块都能放进这10MB的空间。223<10MB<224,而2^23占用大约为8MB空间,也就是说一次的分块大小只能为8MB左右。上面的第二次遍历时如果分为64块,则刚好满足要求。
所以这里最少要分成64块,如果分成128块、256块也可以。

2. 用2GB内存在20亿个整数中找到出现次数最多的数

题目要求:有一个包含20亿个全是32位整数的大文件,在其中找到出现次数最多的数(内存限制为2GB)

思路分析:

通常在很多整数中找到出现次数最多的数,常见是使用哈希表对出现的每一个数做词频统计,哈希表的key是某一个整数,value是这个数出现的次数。

但是就这题来说,一共有20亿个数,哈希表一条记录(key,value)需要8B,当哈希表记录数为2亿个时,需要至少1.6GB内存,当出现极端情况,20亿个数都不同,内存会不够用

解决方法:

把包含20亿个数的大文件用哈希函数分成16个小文件,根据哈希函数的性质,同一种数不可能被散列到不同的小文件上,同时每个小文件中不同的数一定不会大于2亿种。假设哈希函数足够优秀,然后对每一个小文件用哈希表来统计每种数出现的次数,这样就得到了16个小文件中各自出现次数最多的数和各自次数统计,接下来再进行比较即可。

总结:

把一个大的集合通过哈希函数分配到多台机器中,或者分配到多个文件里,这种技巧是在处理大数据面试题最常用技巧之一。
但是到底分配到多少台机器、分配到多少个文件,在解题时一定要确定下来。可能在与面试官沟通过程中由面试官指定,也可能是根据具体的限制来确定,比如本题确定分成16个文件,就是根据内存限制2GB的条件来确定。

3. 从100亿个URL中查找的问题

题目要求:有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL

补充问题:某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门 Top 100词汇的可行方法)

解答:

原问题的解法使用解决大数据问题的一种常规方法:把大文件通过哈希函数分配到机器,或者通过哈希函数把大文件拆成小文件,一直进行这种划分,直到划分的结果满足资源限制的要求。

  1. 首先要向面试官询问在资源上的限制有哪些,包括内存、计算时间等要求
  2. 明确限制要求之后,可以将每条URL通过哈希函数分配到若干台机器或者拆分成若干个小文件(这里的"若干"由具体的资源限制来计算出精确的数量)
补充问题:

最开始还是用哈希分流的思路来处理,把包含百亿数据量的词汇文件分流到不同的机器上,具体多少台机器由面试官规定或者由更多的限制来决定。

  1. 对每一台机器来说,如果分到的数据量依然很大,比如,内存不够或存在其他问题,可以再用哈希函数把每台机器的分流文件拆成更小的文件处理。
  2. 处理每一个小文件的时候,通过哈希表统计每种词及其词频,哈希表记录建立完成后,再遍历哈希表
  3. 遍历哈希表的过程中使用大小为100的小根堆来选出每一个小文件的Top 100(整体未排序的Top 100)。
  4. 每一个小文件都有自己词频的小根堆(整体未排序),将小根堆里的词按照词频排序,就得到了每个小文件的排序后Top 100。
  5. 然后把各个小文件排序后的Top 100进行外排序或者继续利用小根堆,就可以选出每台机器上的Top 100。同理,不同机器之间的Top 100再进行外排序或者继续利用小根堆,最终求出整个百亿数据量中的Top 100。

对于Top K的问题,除用哈希函数分流和用哈希表做词频统计之外,还经常用堆结构和外排序的手段进行处理。

例如:
  1. 将100亿字节的大文件通过哈希函数分配到100台机器上,然后每一台机器分别统计分给自己的URL中是否有重复的URL,同时哈希函数的性质决定了同一条URL不可能分给不同的机器;
  2. 或者在单机上将大文件通过哈希函数拆成1000个小文件,对每一个小文件再利用哈希表遍历,找出重复的URL;
  3. 还可以在分给机器或拆完文件之后进行排序,排序过后再看是否有重复的URL出现。
总结:

很多大数据问题都离不开分流

  • 用哈希函数把大文件的内容分配给不同的机器
  • 用哈希函数把大文件拆成小文件
  • 用哈希函数把大文件拆成小文件,然后处理每一个小数量的集合

4. 40亿个非负整数中找到出现两次的数

题目要求:32位无符号整数的范围是0 ~ 4294967295,现在有40亿个无符号整数,可以使用最多1GB的内存,找出所有出现了两次的数
(这题可以看作第一题的进阶问题,将出现次数限制在了两次)

解题思路:
  1. 可以用bit map的方式表示数出现的情况。具体就是申请一个长度为 4294967295 * 2的bit类型的数组bitArr,用两个位置表示一个数出现的词频,1B占用8个bit,所以长度为4294967295 * 2的bit类型数组占用1GB空间

  2. 使用方法:遍历这40亿个无符号数

  • 如果初次遇到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]设置为01
  • 如果第二次遇到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]设置为10
  • 如果第三次遇到num,就把bitArr[num * 2 + 1]和bitArr[num * 2]设置为11
  • 以后再遇到num,发现此时bitArr[num * 2 + 1]和bitArr[num * 2]已经被设置为11,就不再做任何设置。
  • 遍历完成后,再依次遍历bitArr,如果发生bitArr[num * 2 + 1]和bitArr[num * 2]设置为10,那么i就是出现了两次的数

END

看得很枯燥无味~但是!加油!!

参考文章1:https://juejin.cn/post/7288229413034999866
转载文章1:https://cv3c20a1rv4.feishu.cn/wiki/DViewhOX9iSxCAkmvHGcxxMsnRd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1201713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flutter开发中的一些Tips(四)

最近接手了一个flutter项目&#xff0c;整体感觉代码质量不高&#xff0c;感觉有些是初学者容易犯的问题。几年前写的前三篇&#xff0c;我是站在我自己开发遇到问题的角度&#xff0c;这篇是站在别人遇到问题的角度&#xff0c;算是一种补充。下面我整理一下遇到的小问题&…

Linux安装微信

Linux安装微信 环境&#xff1a;ubuntu 20.04 https://archive.ubuntukylin.com/ubuntukylin/pool/partner/weixin_2.1.4_amd64.deb sudo dpkg -i weixin_2.1.4_amd64.deb完成 参考文章

【Spring进阶系列丨第一篇】初识Spring框架

前言 小伙伴们大家好&#xff0c;我是陈橘又青&#xff0c;今天起 《Spring进阶系列》 开始更新。本专栏将涵盖Spring框架的核心概念、配置管理、Web开发、AOP、Boot、Security、Data、Integration和Batch等多个主题。通过理论讲解和实际案例的剖析&#xff0c;帮助读者深入理解…

k8s的Init Containers容器实现代码版本升级发布和deployment版本回退:实战操作版

Pod中的初始化容器&#xff1a;Init Containers initContainers实现理论前提:同一个Pod内的容器共享 网络、volume等资源 Init Containers 在Kubernetes中&#xff0c;init容器是在同一个Pod中的其他容器之前启动和执行的容器。它的目的是为Pod上托管的主应用程序执行初始化…

【C++】STL容器适配器——priority_quene(堆/优先级队列)类的使用指南(含代码使用)(19)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.priority_quene的文档介绍二、prior…

爬虫实战:基于urllib和mysql爬取苏州公交线路信息

文章目录 写在前面实验环境实验描述实验目标实验内容1. 确定并分析目标网页结构2. 编写urllib代码爬取公交信息3. 保存公交数据到csv文件中4. 保存公交数据到mysql数据库中 写在后面 写在前面 本文将基于python的urllib模块&#xff0c;爬取北京公交线路的信息&#xff0c;最后…

web基础和http协议(粗糙版)

服务部署&#xff0c;集训&#xff0c;分布式&#xff0c;数据库&#xff0c;日志系统&#xff0c;等二阶段 web基础和http协议&#xff1a; web的相关基础知识&#xff0c;包括域名 dns解析 网页的概念以及http协议 1.网络当中通信&#xff1a;端口 ip 协议 tcp/ip 传输过程…

CAD转换器:CAD Exchanger SDK --Crack

转换器 目录 概述读取文件 增量加载写入文件格式特定的详细信息进度状态支持例子 读取和写入多种 CAD 和 BIM 文件格式。 概述 读取&#xff08;导入&#xff09;和写入&#xff08;导出&#xff09;文件是使用 CAD Exchanger SDK 时的主流场景。支持的格式列表可在此处获取。 …

Misc | bucket 第二届“奇安信”杯网络安全技能竞赛

题目描述&#xff1a; 解密Base全家桶。 密文&#xff1a; 下载附件&#xff0c;解压得到一个txt文本&#xff0c;打开如下。 3441344134363435344435323442344534423441343635353334353333323442343935413442353434393535354135333441344534353536353535333332353534413436…

酷柚易汛ERP-自定义打印整体介绍

1、产品介绍 每种单据系统预设常用模板&#xff0c;提供A4纸张、三等分、二等分&#xff0c;销货单额外提供80mm、58mm供用户选择&#xff1b;每张单据可设置一个默认模板和多个常用模&#xff1b;除默认模板外&#xff0c;其他模板都允许删除&#xff0c;用户可以根据公司业务…

ArcGIS实现矢量区域内所有要素的统计计算

1、任务需求&#xff1a;统计全球各国所有一级行政区相关属性的总和。 &#xff08;1&#xff09;有一个全球一级行政区的矢量图&#xff0c;包含以下属性&#xff08;洪灾相关属性 province.shp&#xff09; &#xff08;2&#xff09;需要按照国家来统计各个国家各属性的总值…

前端前沿技术

文章目录 网站静态化PWA - Progressive Web APP, 渐进式 Web 应用PWA 简介解决了哪些问题?PWA 的优势浏览器支持情况参考文档 Weex 是一个可以使用现代化的 Web 技术开发高性能原生应用的框架。高性能跨平台贴近前端生态被大规模的使用 GraphQL[一种用于 API 的查询语言](http…

并发事务下,不同隔离级别可能出现的问题

并发事务下&#xff0c;不同隔离级别可能出现的问题 1、事务的 ACID2、并发事务下&#xff0c;不同隔离级别可能出现的问题2.1、脏写2.2、脏读2.3、不可重复读2.4、幻读 3、SQL 中的四种隔离级别 1、事务的 ACID 原子性&#xff08;Atomicity&#xff09;&#xff1a;原子性意味…

数据结构 | 栈的实现

数据结构 | 栈的实现 文章目录 数据结构 | 栈的实现栈的概念及结构栈的实现 Stack.h初始化栈入栈出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空销毁栈 Stack.c 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。…

勘察设计考试公共基础之数学篇

1、数学 向量点积&#xff1a;向量叉积&#xff1a;平面的法向量为n&#xff08;A&#xff0c;B&#xff0c;C&#xff09;&#xff0c;则该平面的点法式方程为&#xff1a; A&#xff08;x-x0&#xff09;B&#xff08;y-y0&#xff09;C&#xff08;z-z0&#xff09;0 两平…

爬虫,TLS指纹 剖析和绕过

当你欲爬取某网页的信息数据时&#xff0c;发现通过浏览器可正常访问&#xff0c;而通过代码请求失败&#xff0c;换了随机ua头IP等等都没什么用时&#xff0c;有可能识别了你的TLS指纹做了验证。 解决办法&#xff1a; 1、修改 源代码 2、使用第三方库 curl-cffi from curl…

【T690 之十一】基于方寸EVB2开发板,结合 Eclipse+gdb+gdbserver 调试 CCAT 的流程总结

目录 1. 准备工作1.1 Eclipse1.2 工程编译1.3 烧写固件 2. 创建工程2.1 搭建调试工程2.2 配置Dbug调试信息 3. 调试4. 手动调试过程4. 总结 备注&#xff1a; 1&#xff0c;假设您已对方寸微电子的T690系列芯片的使用方式都有了一定的了解&#xff0c;可以根据此文的配置进行Li…

3D模型人物换装系统二(优化材质球合批降低DrawCall)

3D模型人物换装系统 介绍原理合批材质对比没有合批材质核心代码完整代码修改总结 介绍 本文使用2018.4.4和2020.3.26进行的测试 本文没有考虑法线贴图合并的问题&#xff0c;因为生成法线贴图有点问题&#xff0c;放在下一篇文章解决在进行优化 如果这里不太明白换装的流程可以…

基于物理的多偏置射频大信号氮化镓HEMT建模和参数提取流程

标题&#xff1a;Physics-Based Multi-Bias RF Large-Signal GaN HEMT Modeling and Parameter Extraction Flow 来源&#xff1a;JOURNAL OF THE ELECTRON DEVICES SOCIETY 摘要 本文展示了一种一致的Al镓氮化物&#xff08;AlGaN&#xff09;/氮化镓&#xff08;GaN&#x…

CSS省略号n行公式

记得改图中的n&#xff0c;这是你需要的几行省略号&#xff01;复制中间的5行就行了。 .text {overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: n; //n为你想省略的行数&#xff0c;需要改-webkit-box-orient: vertical; } 这是…