常见场景面试题:BitMap、布隆过滤器

news2025/1/31 11:08:32
typora-copy-images-to: imgs

位图 BitMap

BitMap 到底用于解决什么问题?

BitMap 常常用于解决一些数据量比较大的问题,比如说对于1千万个整数,整数的范围在 1~100000000,对于一个整数 x ,我们怎么知道在不在这1千万个整数中呢?

使用 BitMap 来解决的话,就把存在的整数位置给设置为 true,比如 arr[k]=true,那么判断整数 x 是否在这1千万个整数中,只需要判断 arr[x] == true 即可。

那既然这样为什么不使用数组来标记呢?因为数组所占空间过大,会导致内存溢出。比如使用 int[] arr = new int[10];,在 java 中,一个 int 占用 4B,4B = 32bit,那如果使用 BitMap 一个标记仅仅占 1bit,使用数组所占用空间是数组的 32 倍,

Java 中 BitMap 如何实现了?

Java 中 hutool 工具包中实现了 BitMap,引入Maven依赖为:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.0.M2</version>
</dependency>

Java 中有两种 bitmap,分别为 IntMapLongMap,这里以 IntMap 为例:

初始时,ints 数组即为 bitmap 数组,如果我们要向数组中添加 5,过程如下:

  • 计算存储下标,如果要添加 5,那么在 add() 方法中 i=5,因为 int 数组中一个位置是 4B=32bit,所以计算下标时需要对 32 进行取模
  • 之后计算 5 需要存储的位置,也就是在当前这个 32 个位置中,处于第几个位置,所以和 31 进行与操作,31 也就是全1,通过和全1进行与操作就可以计算出位置

图片解释如下:

1697302919324.png

public class IntMap implements BitMap, Serializable {
    private static final long serialVersionUID = 1L;
    private final int[] ints;
​
    public IntMap() {
        this.ints = new int[93750000];
    }
​
    public IntMap(int size) {
        this.ints = new int[size];
    }
​
    public void add(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i & 31L);
        this.ints[r] |= 1 << c;
    }
​
    public boolean contains(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i & 31L);
        return (this.ints[r] >>> c & 1) == 1;
    }
​
    public void remove(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i & 31L);
        int[] var10000 = this.ints;
        var10000[r] &= ~(1 << c);
    }
}

BitMap总结:

  • BitMap适合存储数据密集的数据,如果对于稀疏数据会造成空间浪费。
  • 相比于其他数组更加节省空间

BitMap的一些适用场景:

  • 统计指定用户一年中的登陆天数,哪几天登陆了,哪几天没有登陆?
  • 判断用户的在线状态
  • 统计活跃用户,使用时间作为缓存的key,用户id值为value中的偏移量,这一时间段如果活跃就设置为1

布隆过滤器

对于仅仅为整数的判断可以使用 BitMap 来进行实现,那么我们来考虑下边这个场景:

如果网站需要设置一个黑名单,url数量会上亿,我们怎么将 url 给存储进 BitMap 中呢?存储在 BitMap 中的下标该如何计算呢?

对于这些复杂情况,就可以使用 Redis 的一种数据结构布隆过滤器,首先布隆过滤器的特点就是判断一个 url 的哈希值的位置,如果是1,则可能在集合中,但是如果不是1,则一定不在集合中。

这是为什么呢?

因为布隆过滤器使用了一组哈希函数,如果仅仅使用一个哈希函数,当 url 数量变多时,计算出来的哈希值冲突概率极高,假设使用的一组哈希函数为h1,h2,...hk,那么布隆过滤器会对一个 url 计算 k 次哈希值,得到 k 个哈希值,将 BitMap 中这 k 个位置都设置为1,那么在判断一个 url 是否存在时,判断这 k 个位置的值是否全部为1,如果有一个位置不为1,则表示该 url 并不在集合中。

布隆过滤器总结:

  • 时间、空间效率高
  • 误判率低,可以通过调整哈希函数数量和数组大小来控制误判率
  • 支持并发
  • 无法确定元素一定集合中!
  • 常用于作为一层程序拦截,

常见面试题

  1. 如果有 256 种优先级,每次要选择当前优先级最高的任务来执行,设计一个算法如何实现?

有两种方案:

  1. 使用最大堆

创建一个最大堆,根据任务的优先级进行排序,堆顶元素优先级最高,每次执行任务取堆顶元素,执行后移除。

当任务优先级发生变化时,可以更新堆中元素位置,保证优先级最高在堆顶。

优点:

  • 适用于任意数量的优先级,不限制256种。
  1. 使用 bitmap

可以使用一个 256 为的 bitmap,每一位对应一种优先级。当有任务到达时,将对应优先级位置设置为1,每次执行任务时,取最高位的1,表示优先执行该优先级下的任务,执行之后,将该位设置为0.

Java 中取最高位1的方法:


Integer.highestOneBit(5)
// 输出:4  

优点:

  • 使用于固定256种优先级,因为位图的长度是固定的

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

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

相关文章

基于springboot实现医院急诊平台系统项目【项目源码】计算机毕业设计

基于springboot实现医院急诊平台系统演示 Spring Boot框架 Spring Boot是Pivotal团队的一个新框架&#xff0c;旨在简化新Spring应用程序的初始设置和开发。该框架使用特定的配置方法&#xff0c;无需开发人员定义样板配置。通过这种方式&#xff0c;Spring Boot旨在成为蓬勃发…

为什么直接用int转换 字符串内为小数类型的变量,会报错?直接转换失败?如何解决?

见图思考&#xff1a;为什么直接用int转换 字符串内为小数类型的变量&#xff0c;会报错&#xff1f;&#xff1f;&#xff1f;直接转换失败&#xff1f;&#xff1f;&#xff1f; 报错的意思就是&#xff1a;值异常&#xff0c;因为小数类型的字符串 ‘10.88’&#xff0c;不…

深度学习实战57-pytorch框架搭建LSTM+CNN模型与实现时间序列的预测过程

大家好,我是微学AI,今天给大家介绍一下深度学习实战57-pytorch框架搭建LSTM+CNN模型与实现时间序列的预测过程, 随着科技的进步,我们越来越依赖数据来理解世界,预测未来。特别是在金融、气候研究、交通管理等领域,时间序列预测已经成为了重要的工具。本文将介绍如何使用L…

Apifox 学习笔记 - 前置操作之:自定义变量给请求参数中使用

Apifox 学习笔记 - 前置操作之&#xff1a;动态更新请求体中的时间戳 1. 在前置操作中添加一个&#xff1a;自定义脚本或公共脚本2. 定义我们所需的环境变量。3. 在请求参数中使用【时间戳】4. 检验5. 示例自定义变量mock 参考资料 1. 在前置操作中添加一个&#xff1a;自定义脚…

如何下载GitHub上的代码

新建好要存储的文件夹 右键选择Git Bash Here ls是查看当前文件夹下的文件&#xff0c;可以忽略 git clone 地址 地址在这 直接点复制&#xff0c;粘贴的时候没办法粘贴 可以发现复制即为&#xff1a;CtrlIns&#xff1b;粘贴即为&#xff1a;ShiftIns 于是我们用ShiftIns…

开源ESP32智能小车机械臂控制板Baize_Carboard(支持mixly)

介绍 采用esp32做主控的Baize_Carboard&#xff0c;支持4路直流电机或者两路步进电机的控制&#xff0c;也可以用于控制两路直流闭环电机。输入电压范围5-12V&#xff0c;有时候电压5V起不来&#xff0c;要高一点。可以用于学习arduino或者ros编程&#xff0c;同时也可以将ros…

一篇博客学懂文件操作——C语言

一、为什么使用文件 为什么要使用文件呢&#xff1f;在刚开始学文件操作时&#xff0c;我发出这种疑问。我只需要写好程序就行&#xff0c;保不保存到文件中都无所谓吧。所以从一开始我也就抱着走马观花的心态&#xff0c;“象征性听一听就好啦”“以后能用到时候再学吧”....…

[爬虫练手]学校院系专业整理

本文基于上一篇博客&#xff1a;[爬虫练手]整理学校招生信息 文章目录 一.改进上一篇的代码二,嵌套爬虫&#xff0c;提取院系和专业信息目前完整代码 三.让AI润色一下代码完整代码代码学习加入print语句&#xff0c;方便理解 其他 一.改进上一篇的代码 上一篇那个页面没有反爬措…

FastBert学习笔记

论文标题《FastBERT: a Self-distilling BERT with Adaptive Inference Time》。 关于这个论文已经有不错的解读了&#xff0c;所以我写的侧重点可能和别人的不太一样&#xff0c;具体的往下看吧&#xff0c;欢迎讨论。 这个论文从两个方面去掌握&#xff1a; 样本自适应推断…

Oracle11g在红帽Linux上的安装教程

一、版本介绍 本次实验环境所使用虚拟机为VMware17&#xff08;16或15版本也可以&#xff09; 镜像版本为Red Hat 7.9&#xff1a; ISO镜像地址&#xff1a; 百度网盘链接 链接&#xff1a;https://pan.baidu.com/s/1p318ZZGMfDp4MllXZXbusg?pwdmpic 提取码&…

C++学习——继承(1)

目录 一&#xff0c;继承是什么&#xff1f; 二&#xff0c;继承的权限 三&#xff0c;继承赋值兼容规则 四&#xff0c;继承中的作用域 一&#xff0c;继承是什么&#xff1f; 我们说面向对象的语言有三大特性&#xff1a;1.封装&#xff0c;2&#xff0c;继承&#xff0c;…

鸿蒙tabbar ArkTS

鸿蒙tabbar ArkTS 做了仿照现在应用的做了一个tabbar。 官方文档地址 参考文档 tabbar 其中有个比较重要的点是&#xff0c;对image资源的引用问题。 资源相关说明 图片是resources目录下的base目录下的。 media目录下的图片的资源不能添加文件夹&#xff0c;只能是文件&a…

【Spring框架】Spring监听器的源码分析

目录 一、Spring监听器模型 二、源码分析 2.1 initApplicationEventMulticaster()&#xff1a;事件广播器的初始化 2.1.1 Spring默认的事件广播器SimpleApplicationEventMulticaste 2.2 registerListeners()&#xff1a;注册事件监听器 2.3 finishRefresh()&#xff1a;完…

京东店铺所有商品数据接口,京东整店所有商品数据接口,京东店铺商品接口,京东API接口

京东店铺所有商品数据接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取京东整店的商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片、价格信息等详细信息。 京东店铺所有商品数据接口可以用于不同的业务场景&#xff0c;…

【HHO-KELM预测】基于哈里斯鹰算法优化核极限学习机回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

博图数值按照特定格式(“T000000”)转换成字符串

一、前言 数值按照协议格式&#xff0c;转成字符串。方便和第三方厂家对接。如码垛线使用字符串数据&#xff0c;立库厂家使用dint数据类型&#xff0c;上位机使用DINT数据类型&#xff0c;为了判断数据传输、与动作流程&#xff0c;需要条码的比较&#xff0c;此时可以将数值转…

Kotlin vs Java:为什么Springboot官方教程选择了Kotlin?

导语 作为Java开发者的你&#xff0c;是否在为寻找Java的替代品而烦恼&#xff1f;担心受知识产权问题困扰&#xff1f;别担心&#xff0c;Kotlin来了&#xff01;它是你的救星&#xff0c;也是Springboot官网教程的选择。想知道为什么吗&#xff1f;那就往下翻吧&#xff01;…

“通胀噩梦:恶梦继续还是即将终结?经济前景备受关注!“

尽管美联储采取了激进的利率策略&#xff0c;昨天公布的 9 月份 CPI 数据显示&#xff0c;整体同比增长 3.7%&#xff0c;而预期为 3.6%&#xff0c;高于预期。环比预期&#xff0c;为 0.4%&#xff0c;而预期为 0.3%。核心 CPI 环比上涨 0.3%&#xff0c;同比上涨 4.1%&#x…

极限号可以拿到函数的内部吗?【复合函数中极限的进入】

极限号无脑直接拿进来 1.1 如果f&#xff08;极限值&#xff09;在该点连续&#xff0c;ojbk&#xff0c;拿进来。 1.2 如果f&#xff08;极限值&#xff09;不存在或不连续&#xff0c;不能拿进来&#xff0c;出去。

Flask (Jinja2) 服务端模板注入漏洞复现

文章目录 Flask (Jinja2) 服务端模板注入漏洞1.1 漏洞描述1.2 漏洞原理1.3 漏洞危害1.4 漏洞复现1.4.1 漏洞利用 1.5 漏洞防御 Flask (Jinja2) 服务端模板注入漏洞 1.1 漏洞描述 说明内容漏洞编号漏洞名称Flask (Jinja2) 服务端模板注入漏洞漏洞评级高危影响版本使用Flask框架…