【数据结构】BitMap(1),2024年最新在线面试指南

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

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

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

如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
img

正文

2、取两个集合的交集,并集等

接着上面的查询统计,如果查询十足便利店被高新区下单的情况,该如何查询呢?这里,就相当于取 十足便利店 和 高新区 的交集了,如图所示:

那如果改为查询 十足便利店 或 高新区下单的情况,该如何查询呢?这里,就相当于取 十足便利店 和 高新区 的并集了,如图所示:

三、BitMap的实现

1、自己动手实现BitMap

代码简单实现如下:

public class BitMap {
    private char[] bytes; // 用字符数组存储元素
    private int nBits; // 指定BitMap长度

    public BitMap(int nBits) {
        this.nBits = nBits;
        this.bytes = new char[nBits / 16 + 1]; // 一个字符占2个字节,也就是2*8=16bit
    }

    /**
     * 设置int整数对应的位,修改为1
     */
    public void set(int k) {
        if (k > nBits)
            return;
        int byteIndex = k / 16;
        int bitIndex = k % 16;
        bytes[byteIndex] |= (1 << bitIndex);
    }

    /**
     * 获取int整数对应的位是否存在,true存在,false不存在
     */
    public boolean get(int k) {
        if (k > nBits)
            return false;
        int byteIndex = k / 16;
        int bitIndex = k % 16;
        return (bytes[byteIndex] & (1 << bitIndex)) != 0;
    }
}

测试一下:

@SpringBootTest
class MySportHealthyApplicationTests {
    @Test
    void test1() {
        int[] arr = new int[]{6, 2, 7, 14, 3};
        int maxArr = Arrays.stream(arr).max().getAsInt();
        // 指定BitMap长度
        BitMap bitMap = new BitMap(maxArr + 1);
        // 数组的整数放进BitMap
        for (int i = 0; i < arr.length; i++) {
            bitMap.set(arr[i]);
        }
        // 判断哪些值存在
        for (int i = 0; i < maxArr + 1; i++) {
            logger.info(i + ",是否在BitMap内-----》:" + bitMap.get(i));
        }
    }
}

控制台输出结果:

注意:

实际上海量数据的设置和查询逻辑没有这么简单,甚至会出现一些极端情况,比如有一个整型数组[1,2,50000,80000000000],元素间隔很大,导致2和50000,以及50000和80000000000之间存在很多空的bit,这些bit很明显占据了很大的空间,我们可以参考JDK中位集的概念,引入 word 有效解决了这类问题,感兴趣的可以去阅读 BitSet 集合源码一探究竟。

2、JDK中实现的BitMap —— BitSet 集合

下面这段是JDK对BitSet集合的描述:

This class implements a vector of bits that grows as needed. Each component of the bit set has a boolean value. The bits of a BitSet are indexed by nonnegative integers. Individual indexed bits can be examined, set, or cleared. One BitSet may be used to modify the contents of another BitSet through logical AND, logical inclusive OR, and logical exclusive OR operations.
By default, all bits in the set initially have the value false.
Every bit set has a current size, which is the number of bits of space currently in use by the bit set. Note that the size is related to the implementation of a bit set, so it may change with implementation. The length of a bit set relates to logical length of a bit set and is defined independently of implementation.
Unless otherwise noted, passing a null parameter to any of the methods in a BitSet will result in a NullPointerException.
A BitSet is not safe for multithreaded use without external synchronization.

总结如下:

  • 一个BitSet对象可以通过logical AND、logical inclusive OR、AND logical exclusive OR操作来修改另一个BitSet对象的内容;
  • 默认情况下,集合中的所有位的初始值为false。位集的每个组成部分都有一个布尔值,每个位集都有一个当前大小,即该位集当前使用的空间位数,换言之大小与位集的实现有关,因此它可能随实现而改变;
  • BitSet集合对于多线程使用是不安全的。
  • 另外,BitSet 可以看作是 word 组成的数组,而一个word 对应一个64位的long类型,需要6个地址位。

做下测试:

@SpringBootTest
class MySportHealthyApplicationTests {
    @Test
    void test1() {
        int[] arr = new int[]{1, 7, 50000, 30000000}; //1到3千万
        int maxArr = Arrays.stream(arr).max().getAsInt();
        BitSet bitSet = new BitSet(maxArr + 1);
        // 存放数据
        bitSet.set(1);
        bitSet.set(7);
        bitSet.set(50000);
        bitSet.set(30000000);
        // 查找
        logger.info("1000是否存在------->" + bitSet.get(1000)); //false
        logger.info("7是否存在------->" + bitSet.get(7)); //true
        logger.info("50000是否存在------->" + bitSet.get(50000)); //true
        logger.info("5000000是否存在------->" + bitSet.get(5000000)); //false
        logger.info("30000000是否存在------->" + bitSet.get(30000000)); //true
    }
}

3、谷歌实现的BitMap —— EWAHCompressedBitmap

对于一个很长的 BitMap 只存储少量的数据,比如只有第50000000的位置为1,那么它之前的空间会造成浪费,所以谷歌的实现对这个空间进行了优化,提供了 EWAHCompressedBitmap ,要使用需要先引入依赖:

<!--EWAHCompressedBitmap-->
<dependency>
    <groupId>com.googlecode.javaewah</groupId>
    <artifactId>JavaEWAH</artifactId>
    <version>1.1.0</version>
</dependency>

原理:

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

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
img

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

术提升。**

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-rw9oIm7Y-1713205217260)]

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

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值