【Golang系统开发】搜索引擎(1) 如何快速判断网页是否已经被爬取

news2024/11/15 16:40:21

文章目录

  • 1. 写在前面
  • 2. 数组存储
  • 3. 位图存储
    • 3.1 位图简介
    • 3.2 链表法
    • 3.3 开放寻址法

1. 写在前面

在实际工作中,我们经常需要判断一个对象是否存在,比如判断用户注册登陆时候,需要判断用户是否存在,再比如搜索引擎中的爬虫,判断该网页是否已经爬过,减少一些重复的工作。

2. 数组存储

我们当然可以使用有序数组,二叉搜索树,哈希表等等来存储所有的用户id。但是无论是有序数组还是二叉搜索树,这两种数据结构都是基于二分查找的思想从中间元素开始查起的。所以在查询用户id是否存在时,这两种数据结构的检索时间都是 O(logn)。

而哈希表的检索时间是O(1)。因此如果我们希望能快速查询元素是否存在,那哈希表就是最合适的。但是哈希表中,我们还是需要计算哈希值来获取数组的下标,这也是需要耗费一定的时间。

那应该怎么做呢?

我们可以直接使用一个足够大的数组来存储用户id,如果该用户存在,就在该用户id的位置标识为 1 ,否则就是默认的 0 也就是不存在。但是这个也会有问题,如果我们的用户id范围很广,比如说是在10w之内,那我们就需要保证数组的长度是大于10w的,除此之外,如果这个数组是int类型的话,每个元素就会占据4/8个字节,用4/8个字节存储0和1是不是很浪费空间,所以这个方案比较消耗空间,典型的空间换时间。

那么我们怎么优化存储空间呢?接下来就介绍一下位图了。

3. 位图存储

3.1 位图简介

首先我们需要优化存储的数据结构,不是int,虽然char和bool类型都是1字节,相比较于4/8字节的int类型,已经提升了4/8倍了(32位的机器是4 byte,64位的机器是8 byte),但是其实用字节作为单位来存储一个flag类型也是很浪费的,flag类型的直接使用bit类型的就可以了。

如果我们使用bit类型来存储,就是原来的32倍了,非常亏贼!而这种以bit为单位构建数组的方案就叫做bitmap,也就是位图。

如果你在好奇这个32是怎么算的?我们原来是用一个int类型取表示是否存在这个值,我们假设是在32位的机子上,这个int类型就是4个byte。而我们现在用的是bit来作为存储运算,1 byte = 8 bit,所以就是原来的 1/4*8 ,就是1/32倍。

在这里插入图片描述
虽然位图相对于原始数组来说,在元素存储上已经有了很大的优化,但如果我们还想进一步优化存储空间,要怎么做呢?

其实有一个点很好想到,我们都知道一个数组的空间其实就是 数组元素的个数 * 每个元素大小,位图已经把我们每个元素的大小限定在最小单位的bit了,而我们存储元素的个数一定要大于我们所需要存储的用户id数的,这似乎已经无解了。但其实我们可以通过哈希算法将大于数组长度的用户id转化成一个小于数组长度的数值作为下标,除此之外, 使用哈希函数还可以使我们的用户id不需要是正整数,可以是字符串,因为字符串可以通过哈希函数的转换成正整数。

当然如果我们数组压缩到很小的时候,就容易发生哈希冲突,如果两个元素,A和B都映射到同一个地方了,那么就无法判断是A存在,还是B存在了,那应该如何解决哈希冲突呢?一般会有两种方法,开放寻址法,链表法

3.2 链表法

数组的每个成员是一个链表。该数据结构所容纳的所有元素均包含一个指针,用于元素间的链接。我们根据元素的自身特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。

先调用这个元素的 hash 方法,然后根据所得到的值计算出元素应该在数组的位置。如果这个位置上没有元素,那么直接将它存储在这个位置上;如果这个位置上已经有元素了,那么与新元素进行比较:相同的话就不存了,否则,将其存在这个位置对应的链表中。

在这里插入图片描述

3.3 开放寻址法

当发生哈希冲突时,重新找到空闲的位置,然后插入元素。寻址方式有多种,常用的有线性寻址、二次方寻址、双重哈希寻址等等

线性寻址就是如果冲突了,就从冲突位置线性顺序向下继续寻找空位置。

在这里插入图片描述

二次寻址就是每次向上找两格,冲突就向下找两格,再冲突就是向上找四个,-2,+2,-4,+4这样的上下的找,直到找到不冲突为止。

双重哈希寻址就是使用多个hash函数获取多个哈希值。 而这种方法也称为双散列。可以使用两个哈希寻址,也可以使用多个哈希来寻址,那这是不是就有点像布隆过滤器。在布隆过滤器中,如果我们对一个对象,使用来N个哈希函数,就会得到N个值,也就是N个下标,我们会把数组中对应下标位置都变成1。

而布隆过滤器和位图最大的区别就是我们不再使用一位来表示一个对象,而是使用N位来表示一个对象。这样两个对象的N位都相同的概率就会大大降低了,就能大大缓解哈希冲突了。
在这里插入图片描述
而N个哈希都冲突的情况也是会有的,或者说刚好是下面这种Z的情况

在这里插入图片描述
那么我们就当这个Z是已经存在了,让用户重新输入就好了,因为在大多数系统中,我们并不要求100%的准确,我们只要保证用户体验就行了,这种方案已经是权衡很多之后才确定是最优解了。

这个X,Y,Z其实就是我们的网址。这样我们就可以快速判断网页是否已经被爬取了。

还有一种位图的优化:Roaring Bitmap 后续在合并多个postingsList会有作用。

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

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

相关文章

大数据面试题之Elasticsearch:每日三题(七)

大数据面试题之Elasticsearch:每日三题 1.Elasticsearch索引文档的流程?2.Elasticsearch更新和删除文档的流程?3.Elasticsearch搜索的流程? 1.Elasticsearch索引文档的流程? 协调节点默认使用文档ID参与计算(也支持通过routing)&a…

【UE4】给角色添加脚步声

步骤: 1. 导入一个脚步声音频文件(.wav格式) 2. 打开角色蓝图,这里以第三人称角色模板蓝图“ThirdPersonCharacter”为例,在事件图表中添加一个生成音效的自定义事件。 3. 打开动画序列“ThirdPersonRun” 找到小白人…

Python编程——while循环嵌套讲解(附案例)

作者:Insist-- 个人主页:insist--个人主页 本文专栏:Python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、while嵌套的语法 二、注意事项 三、while嵌套循…

【Java】分支结构习题

【Java】分支结构 文章目录 【Java】分支结构题1 :数字9 出现的次数题2 :计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值。题3 :猜数字题4 :牛客BC110 X图案题5 :输出一个整数的每一位题6 : 模拟三次密码输…

统信UOS安装mysql数据库(mariadb)-统信UOS安装JDK-统信UOS安装nginx(附安装包)

统信UOS离线全套安装教程(手把手教程) 银河麒麟的各种离线全套安装教程: https://blog.csdn.net/ACCPluzhiqi/article/details/131988147 1.统信UOS桌面系统安装mysql(mariadb) 2.统信UOS桌面系统安装JDK 3.统信UOS桌…

CAN学习笔记3:STM32 CAN控制器介绍

STM32 CAN控制器 1 概述 STM32 CAN控制器(bxCAN),支持CAN 2.0A 和 CAN 2.0B Active版本协议。CAN 2.0A 只能处理标准数据帧且扩展帧的内容会识别错误,而CAN 2.0B Active 可以处理标准数据帧和扩展数据帧。 2 bxCAN 特性 波特率…

【JavaWeb】正则表达式

🎄欢迎来到边境矢梦的csdn博文,本文主要讲解Java 中正则表达式 的相关知识🎄 🌈我是边境矢梦,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下🫰🫰&am…

Metabase RCE漏洞复现(CVE-2023-38646)

0x01 产品简介 Metabase是一个开源的数据分析和可视化工具,它可以帮助用户轻松地连接到各种数据源,包括数据库、云服务和API,然后使用直观的界面进行数据查询、分析和可视化。 0x02 漏洞概述 未经身份认证的远程攻击者利用该漏洞可以在服务器…

【C语言趣味教程】(4) 变量:代码注释 | 变量的声明 | 初始化与赋值 | 变量的命名 | 关键字 | 标识符 | 变量名的命名规范

🔗 《C语言趣味教程》👈 猛戳订阅!!! Ⅰ. 代码注释(Comment) 0x00 引入:注释的作用 "程序员最讨厌两种人:一种是不写注释的人,一种是让我写注释的人。…

如何用DHTMLX组件为Web应用创建甘特图?(一)

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。甘特图仍然是项目管理应用程序中最需要的工具之一,DHTMLX Gantt组件提供了能提升研发甘特图功能所需的重要工具。 在这篇…

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文

代码:https://github.com/zyxElsa/InST 论文:https://arxiv.org/abs/2211.13203 文章目录 AbstractIntroductionRelated WorkImage style transferText-to-image synthesisInversion of diffusion models MethodOverview ExperimentsComparison with Sty…

我的第一个后端项目(环境搭建,Springboot项目,运行,接口验证)

一. 安装Java开发工具包(JDK): 访问Java Software | OracleOracle官方网站,下载适合你操作系统的最新版本的JDK。安装JDK并设置好JAVA_HOME环境变量。 二. 安装集成开发环境(IDE): 推荐使用In…

Appium+python自动化(二十八)- 高级滑动(超详解)

高级溜冰的滑动 滑动操作一般是两点之间的滑动,这种滑动在这里称其为低级的溜冰滑动;就是上一节给小伙伴们分享的。然而实际使用过程中用户可能要进行一些多点连续滑动操作。如九宫格滑动操作,连续拖动图片移动等场景。那么这种高级绚丽的溜…

word里的页码问题

一份文档写完,如果需要页码,第一页是封面,封面不需要页码怎么办? 解决:打开页眉页脚,然后把首页不同勾选上,这一页就没有页码了。 目录页,往往要使用罗马数字,其他正文又…

《遗留系统现代化》读书笔记(模式篇-代码现代化(一))

本文地址:http://t.csdn.cn/vS0Za 文章目录 代码现代化:你的代码可测吗?你的代码可测吗?标题如何让代码变得可测?接缝的位置接缝的类型新生和外覆为代码添加测试决策表模式测试的类型和组织遗留系统中的测试策略 代码…

【深度学习笔记】Softmax 回归

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记,视频由网易云课堂与 deeplearning.ai 联合出品,主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习,视频的链接如下: 神经网络和…

QuantMania!《快乐机器学习》和《Python 从入门到入迷》作者,FRM,CAIA

王的机器主理人 王圣元 (FRM, CAIA) 某加密货币公司 Head of Quant 冬海集团 SeaMoney 建模负责人 八方咨询 量化总监 新加坡国立大学金融数学硕士 新加坡国立大学量化金融学士 《快乐机器学习》的作者 《Python 从入门到入迷》的作者 第一本书 《快乐机器学习》 第二本书《Pyt…

MySQL 8.0详细安装配置教程

一. 前言 MySQL是目前最为流行的开源数据库产品,是完全网络化跨平台的关系型数据库系统。它起初是由瑞典MySQLAB公司开发,后来被Oracle公司收购,目前属于Oracle公司。因为开源,所以任何人都能从官网免费下载MySQL软件&#xff0c…

【4】-多个User执行测试

目录 一个locustfile中有多个User 使用--class-picker指定执行 小结 一个locustfile中有多个User from locust import task, HttpUserclass User01(HttpUser):weight 3 # 权重host https://www.baidu.comtaskdef user_01_task(self):self.client.get(url/, nameuser_01_…

echarts柱状图每根柱子添加警戒值/阈值,分段警戒线

需求:柱状图每根柱子都添加单独的警戒值(黄色线部分),效果图如下: 实现方式我这有两种方案,如下介绍。 方案1:使用echarts的标线markLine实现(ps:此种方案有弊端&#x…