分享好友 最新动态首页 最新动态分类 切换频道
2024年大数据最全百度、微博的大数据算法Top10热搜怎么实现?,面试必备知识点
2024-12-27 04:36

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化

2024年大数据最全百度、微博的大数据算法Top10热搜怎么实现?,面试必备知识点

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

实际上,它的实现并不复杂。搜索引擎每天会接收大量的用户搜索请求,它会把这些用户输入的搜索关键词记录下来,然后再离线地统计分析,得到最热门的 Top 10 搜索关键词。

那请你思考下,假设现在我们有一个包含 10 亿个搜索关键词的日志文件,如何能快速获取到热门榜 Top 10 的搜索关键词呢

这个问题就可以用堆来解决,这也是堆这种数据结构一个非常典型的应用。堆这种数据结构几个非常重要的应用:优先级队列、求 Top K 和求中位数。

堆的应用一:优先级队列

首先,我们来看第一个应用场景:优先级队列。

优先级队列,顾名思义,它首先应该是一个队列。我们前面讲过,队列最大的特性就是先进先出。不过,在优先级队列中,数据的出队顺序不是先进先出,而是按照优先级来,优先级最高的,最先出队。

如何实现一个优先级队列呢?方法有很多,但是用堆来实现是最直接、最高效的。这是因为,堆和优先级队列非常相似。一个堆就可以看作一个优先级队列。很多时候,它们只是概念上的区分而已。往优先级队列中插入一个元素,就相当于往堆中插入一个元素;从优先级队列中取出优先级最高的元素,就相当于取出堆顶元素。

你可别小看这个优先级队列,它的应用场景非常多。比如,赫夫曼编码、图的最短路径、最小生成树算法等等。不仅如此,很多语言中,都提供了优先级队列的实现,比如,Java 的 PriorityQueue,C++ 的 priority_queue 等。

只讲这些应用场景比较空泛,现在,我举两个具体的例子,感受一下优先级队列具体是怎么用的。

  1. 合并有序小文件

假设我们有 100 个小文件,每个文件的大小是 100MB,每个文件中存储的都是有序的字符串。我们希望将这些 100 个小文件合并成一个有序的大文件。这里就会用到优先级队列。

整体思路有点像归并排序中的合并函数。我们从这 100 个文件中,各取第一个字符串,放入数组中,然后比较大小,把最小的那个字符串放入合并后的大文件中,并从数组中删除。

假设,这个最小的字符串来自于 13.txt 这个小文件,我们就再从这个小文件取下一个字符串,并且放到数组中,重新比较大小,并且选择最小的放入合并后的大文件,并且将它从数组中删除。依次类推,直到所有的文件中的数据都放入到大文件为止。

这里我们用数组这种数据结构,来存储从小文件中取出来的字符串。每次从数组中取最小字符串,都需要循环遍历整个数组,显然,这不是很高效。有没有更加高效方法呢

这里就可以用到优先级队列,也可以说是堆。我们将从小文件中取出来的字符串放入到小顶堆中,那堆顶的元素,也就是优先级队列队首的元素,就是最小的字符串。我们将这个字符串放入到大文件中,并将其从堆中删除。然后再从小文件中取出下一个字符串,放入到堆中。循环这个过程,就可以将 100 个小文件中的数据依次放入到大文件中。

我们知道,删除堆顶数据和往堆中插入数据的时间复杂度都是 O(logn),n 表示堆中的数据个数,这里就是 100。是不是比原来数组存储的方式高效了很多呢

  1. 高性能定时器

假设我们有一个定时器,定时器中维护了很多定时任务,每个任务都设定了一个要触发执行的时间点。定时器每过一个很小的单位时间(比如 1 秒,就扫描一遍任务,看是否有任务到达设定的执行时间。如果到达了,就拿出来执行。

但是,这样每过 1 秒就扫描一遍任务列表的做法比较低效,主要原因有两点:第一,任务的约定执行时间离当前时间可能还有很久,这样前面很多次扫描其实都是徒劳的;第二,每次都要扫描整个任务列表,如果任务列表很大的话,势必会比较耗时。

针对这些问题,我们就可以用优先级队列来解决。我们按照任务设定的执行时间,将这些任务存储在优先级队列中,队列首部(也就是小顶堆的堆顶)存储的是最先执行的任务。

这样,定时器就不需要每隔 1 秒就扫描一遍任务列表了。它拿队首任务的执行时间点,与当前时间点相减,得到一个时间间隔 T。

这个时间间隔 T 就是,从当前时间开始,需要等待多久,才会有第一个任务需要被执行。这样,定时器就可以设定在 T 秒之后,再来执行任务。从当前时间点到(T-1)秒这段时间里,定时器都不需要做任何事情。

当 T 秒时间过去之后,定时器取优先级队列中队首的任务执行。然后再计算新的队首任务的执行时间点与当前时间点的差值,把这个值作为定时器执行下一个任务需要等待的时间。

这样,定时器既不用间隔 1 秒就轮询一次,也不用遍历整个任务列表,性能也就提高了。

堆的应用二:利用堆求 Top K

堆的另外一个非常重要的应用场景,那就是“求 Top K 问题”。

我把这种求 Top K 的问题抽象成两类。一类是针对静态数据集合,也就是说数据集合事先确定,不会再变。另一类是针对动态数据集合,也就是说数据集合事先并不确定,有数据动态地加入到集合中。

针对静态数据,如何在一个包含 n 个数据的数组中,查找前 K 大数据呢?我们可以维护一个大小为 K 的小顶堆,顺序遍历数组,从数组中取出取数据与堆顶元素比较。如果比堆顶元素大,我们就把堆顶元素删除,并且将这个元素插入到堆中;如果比堆顶元素小,则不做处理,继续遍历数组。这样等数组中的数据都遍历完之后,堆中的数据就是前 K 大数据了。

遍历数组需要 O(n) 的时间复杂度,一次堆化操作需要 O(logK) 的时间复杂度,所以最坏情况下,n 个元素都入堆一次,所以时间复杂度就是 O(nlogK)。

针对动态数据求得 Top K 就是实时 Top K。怎么理解呢?我举一个例子。一个数据集合中有两个操作,一个是添加数据,另一个询问当前的前 K 大数据。

如果每次询问前 K 大数据,我们都基于当前的数据重新计算的话,那时间复杂度就是 O(nlogK),n 表示当前的数据的大小。实际上,我们可以一直都维护一个 K 大小的小顶堆,当有数据被添加到集合中时,我们就拿它与堆顶的元素对比。如果比堆顶元素大,我们就把堆顶元素删除,并且将这个元素插入到堆中;如果比堆顶元素小,则不做处理。这样,无论任何时候需要查询当前的前 K 大数据,我们都可以里立刻返回给他。

堆的应用三:利用堆求中位数

前面我们讲了如何求 Top K 的问题,现在我们来讲下,如何求动态数据集合中的中位数。

中位数,顾名思义,就是处在中间位置的那个数。如果数据的个数是奇数,把数据从小到大排列,那第 n/2+1 个数据就是中位数;如果数据的个数是偶数的话,那处于中间位置的数据有两个,第n/2 个和第 n/2+1 个数据,这个时候,我们可以随意取一个作为中位数,比如取两个数中靠前的那个,就是第 n/2 个数据。

对于一组静态数据,中位数是固定的,我们可以先排序,第 n/2 个数据就是中位数。每次询问中位数的时候,我们直接返回这个固定的值就好了。所以,尽管排序的代价比较大,但是边际成本会很小。但是,如果我们面对的是动态数据集合,中位数在不停地变动,如果再用先排序的方法,每次询问中位数的时候,都要先进行排序,那效率就不高了。

借助堆这种数据结构,我们不用排序,就可以非常高效地实现求中位数操作。我们来看看,它是如何做到的

我们需要维护两个堆,一个大顶堆,一个小顶堆。大顶堆中存储前半部分数据,小顶堆中存储后半部分数据,且小顶堆中的数据都大于大顶堆中的数据。

也就是说,如果有 n 个数据,n 是偶数,我们从小到大排序,那前 n/2 个数据存储在大顶堆中,后 n/2 个数据存储在小顶堆中。这样,大顶堆中的堆顶元素就是我们要找的中位数。如果 n 是奇数,情况是类似的,大顶堆就存储 n/2+1 个数据,小顶堆中就存储 n/2 个数据。

我们前面也提到,数据是动态变化的,当新添加一个数据的时候,我们如何调整两个堆,让大顶堆中的堆顶元素继续是中位数呢

如果新加入的数据小于等于大顶堆的堆顶元素,我们就将这个新数据插入到大顶堆;如果新加入的数据大于等于小顶堆的堆顶元素,我们就将这个新数据插入到小顶堆。

这个时候就有可能出现,两个堆中的数据个数不符合前面约定的情况:如果 n 是偶数,两个堆中的数据个数都是n/2;如果 n 是奇数,大顶堆有 n/2+1 个数据,小顶堆有 n/2 个数据。这个时候,我们可以从一个堆中不停地将堆顶元素移动到另一个堆,通过这样的调整,来让两个堆中的数据满足上面的约定。

于是,我们就可以利用两个堆,一个大顶堆、一个小顶堆,实现在动态数据集合中求中位数的操作。插入数据因为需要涉及堆化,所以时间复杂度变成了 O(logn),但是求中位数我们只需要返回大顶堆的堆顶元素就可以了,所以时间复杂度就是 O(1)。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导,让我们一起学习成长

,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

最新文章
撒拉族服饰经过了怎样的历史变迁
  撒拉族,是一个信仰伊斯兰教的民族,因自称“撒拉尔”,简称“撒拉”而得名。有人认为撒拉族是古代西突厥乌古斯部撒鲁尔的后裔,唐代时原住中国境内,后西迁中亚。自元代取道撒马尔罕,东返中国,行至今青海循化地区定居,至今已有七百
自主制造执行系统中的调度执行外文翻译doc.png
"自主制造执行系统中的调度执行"这个术语可能指的是在一个自动化制造系统或工业自动化环境中,调度器负责管理制造任务的顺序和执行。在自主制造执行系统中,调度执行是确保生产流程顺畅进行的关键部分。如果需要将这个概念翻译成英文,可能
彩票缩水大揭秘:如何用形态法和排序技术打造中奖利器》 引言:
在彩票的世界里,3D游戏以其1000注的全排列组合看似简单,实则隐藏着中奖的复杂性。许多彩民在深入研究后发现,中奖并非易事。本文将分享一种无需额外条件即可从大量注数中精准提取胆码的高级技巧——形态法与排序技术。一、缩水技术的现状
自动抢票软件排名第一(抢票实测:美团火车票综合实力位居四大主流火车票APP之首)
1.铁路12306官方抢票软件稳居抢票软件排行榜首位。2.铁路12306是中国铁路总公司推出的官方抢票工具,旨在帮助用户轻松抢到优惠的火车票。3.抢票软件是为解决春运期间用户购票难题而由互联网公司研发的产品,通常作为浏览器的插件存在。4.铁
青浦爱采购运营价格
百度作为最大的搜索引擎之一,在互联网经济发展的过程中一直扮演着人流量分发端口的角色,很多平台在发展初期都是从百度引流完成自己的用户积累。在这个过程中积累了丰富的运营经验,百度爱采购作为B2B平台,与同类平台相比有什么好处呢?
智能AI语音助手:全方位解决沟通与交互需求的对话机器人
智能AI语音助手:全方位解决沟通与交互需求的对话机器人随着科技的不断发展人工智能技术已经深入到了咱们生活的方方面面。作为人工智能领域的关键应用之一语音对话机器人凭借其强大的沟通与交互能力,正逐渐改变着咱们的生活。本文将围绕语
漫蛙manwa漫画官网手机版下载最新版
漫蛙manwa漫画官网手机版是一款备受喜爱的漫画阅读软件,漫蛙manwa漫画官网手机版是专为热爱漫画的用户而设计,提供了丰富多样的漫画资源,涵盖了各种题材和风格,让用户可以根据自己的喜好自由选择,还提供了热门漫画推荐功能,会根据用户
肠炎和肠癌有什么区别
肠炎与肠癌的区别在于病因、症状、实验室检查、影像学检查以及内镜检查结果。1.病因肠炎是由病毒、细菌或食物中毒引起的急性肠道炎症,而肠癌是由于结肠或直肠细胞异常增生形成的恶性肿瘤。...2.症状肠炎通常表现为腹泻、腹痛、恶心呕吐等
深圳中学生编程培训咨询热线:   在线咨询: 点击交谈
课程单价:165元课时数:80节全部校区:童程童美少儿编程(幸福里校区)课程内容:乐高创意启蒙课程主要分为三个部分,认识世界、观察世界以及探索世界。认识世界是通过扮演、创造来引导孩子对社会创造一个认知,并且拥有真实的自我情感;
页黄冈大推广的最佳实施策略是什么-如何提高品牌曝光度和销售转化率
网页黄冈大推广是一项专注于黄冈地区市场的互联网推广活动,旨在通过多种网络手段提升本地企业或品牌的知名度与曝光度。随着互联网技术的快速发展,越来越多的黄冈地区的商家开始关注网页推广的潜力,以便在激烈的市场竞争中脱颖而出。这项
相关文章
推荐文章
发表评论
0评