【算法】阿里面试题-编码实现20亿个整数,找出某个数X是否存在其中

简介: 【算法】阿里面试题-编码实现20亿个整数,找出某个数X是否存在其中

1.海量数据去重-BitMap位图解决方案

需求(面试题)

一个32位4G内存的操作系统,在20亿个整数,找出某个数X是否存在其中

假如是java语言,int占4字节,1字节=8位(1 byte = 8 bit)

方式一:每个数字是int类型存储,就是20亿个int需要的空间大小就是 7GB多

方式二:不存储具体数据,而存储是否存在,如果存在则位上存储1,采用bit位存储20亿个数就是20亿位,空间是0.2GB多

什么是BitMap位图

本质上是哈希表的一种应用实现,原理简单,以 bit 为单位构建数组的方案,就叫作 Bitmap,翻译为位图。即bit 的集合

使用一个bit表示状态, 两种状态 (0不存在和1存在) 使用最少字节的类型来定义数组,即最小的空间存储数据标识


abc2aadde7f14ec5b18bfb0f2c1d2b73.jpg

注意

位图适合对【数值类型】的海量数据进行查询统计、排序、去重 和 对两个集合做交集、并集运算

bitmap在数据连续的时候,非常节省空间,但是在数据稀疏的时候,会有极大的浪费

缺点

数据碰撞:

字符串映射到 bitmap会有碰撞问题,即可能映射到同个位置,即hash碰撞

稀疏数据

不连续的数据容易浪费空间,比如存入1和88两个数,需要构建长度89的数组

表示索引从1到88,所以需要构建一个长度为89的数组,存放1到88的元素,但实际只存储2个数字

如果用户的ID的数据类型是int32的话,那么最大值是2^32,需要用512MB的字节的位图来表示

2^32bit=4294967296 比特(bit)=512 兆字节(MB)

如果只往bitmap存储一个最大值,那边需要申请512 兆字节(MB),大大浪费空间

业务应用:日活/月活UV统计、签到统计、用户点赞,用户签到,访问计数,在线用户数等

2.编码实现20亿个数据,找出某个数X是否存在其中

题目需求

20亿个数据,找出某个数X是否存在其中

前提条件:使用java现有数据结构或自定义数据结构,要求高效和省空间

位图在java里面的实现BitSet类

是一个实现按需增长的位向量,位Set的每一个位置都有一个boolean值,默认初始值都是false

底层实现是使用long数组作为内部存储结构的,所以BitSet的大小为long类型大小(64位)的整数倍

如果指定了bitset的初始化大小,会规整到一个大于或者等于这个数字的64的整倍数(内存对齐)

比如64位,bitset的大小是1个long,而65位时,bitset大小是2个long,即128位

主要的API

void and(BitSet set) 对此目标位 set 和参数位 set 执行逻辑与操作。
void or(BitSet set) 对此目标位集执行逻辑或操作
void clear() 将此 BitSet 中的所有位设置为 false
void clear(int bitIndex):将指定索引处的位设置为 false
void set(int index) 将指定索引处的位设置为 true
boolean get(int index) 返回指定索引处的位值
int size():返回此 BitSet 中的位数(按逻辑大小)【表示位值时实际使用空间的位数,值是64的整数倍】
int length() 返回此 BitSet 的"逻辑大小",BitSet 中最高设置位的索引加 1
int cardinality() 返回此 BitSet 中设置为 true 的位数

解答思路

海量数据 里面查找是否存在,排序,交集,并集等,这类题目基本就是使用位图解决

给定20亿个不重复的 int的整数,再给一个数,如何快速判断这个数是否在那X亿个数当中

解法:遍历X亿个数字,映射到BitMap中,对于给出的数,直接判断指定的位上存在不存在即可

编码实现

public class BitSetTest {
    public static void main(String[] args) {
        int targetNum = 39;
        boolean flag = seekNum(targetNum);
        System.out.println("当前数值是否在集合中:"+flag);
    }
    public static boolean seekNum(int targetNum){
        //定义数据生成范围
        int numLength = 2000000000;
        //定义位图
        BitSet bitSet = new BitSet(numLength);
        //随机生成数字
        for (int i = 1; i <= numLength; i++) {
            int random = (int) (Math.random() * numLength);
            bitSet.set(random);
        }
        //输出基本信息
        System.out.println("bitMap是1的个数:"+bitSet.cardinality());
        System.out.println("bitMap的size:"+bitSet.size());
        System.out.println("bitMap的length:"+bitSet.length());
        //判断数值是否存在
        return bitSet.get(targetNum);
    }
}
相关文章
|
2月前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
16天前
|
SQL 关系型数据库 MySQL
阿里面试:1000万级大表, 如何 加索引?
45岁老架构师尼恩在其读者交流群中分享了如何在生产环境中给大表加索引的方法。文章详细介绍了两种索引构建方式:在线模式(Online DDL)和离线模式(Offline DDL),并深入探讨了 MySQL 5.6.7 之前的“影子策略”和 pt-online-schema-change 方案,以及 MySQL 5.6.7 之后的内部 Online DDL 特性。通过这些方法,可以有效地减少 DDL 操作对业务的影响,确保数据的一致性和完整性。尼恩还提供了大量面试题和解决方案,帮助读者在面试中充分展示技术实力。
|
2月前
|
消息中间件 存储 canal
阿里面试:canal+MQ,会有乱序的问题吗?
本文详细探讨了在阿里面试中常见的问题——“canal+MQ,会有乱序的问题吗?”以及如何保证RocketMQ消息有序。文章首先介绍了消息有序的基本概念,包括全局有序和局部有序,并分析了RocketMQ中实现消息有序的方法。接着,针对canal+MQ的场景,讨论了如何通过配置`canal.mq.partitionsNum`和`canal.mq.partitionHash`来保证数据同步的有序性。最后,提供了多个与MQ相关的面试题及解决方案,帮助读者更好地准备面试,提升技术水平。
阿里面试:canal+MQ,会有乱序的问题吗?
|
2月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
2月前
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
33 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
2月前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
2月前
|
消息中间件 架构师 Java
阿里面试:秒杀的分布式事务, 是如何设计的?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴在面试阿里、滴滴、极兔等一线互联网企业时,遇到了许多关于分布式事务的重要面试题。为了帮助大家更好地应对这些面试题,尼恩进行了系统化的梳理,详细介绍了Seata和RocketMQ事务消息的结合,以及如何实现强弱结合型事务。文章还提供了分布式事务的标准面试答案,并推荐了《尼恩Java面试宝典PDF》等资源,帮助大家在面试中脱颖而出。
|
2月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
2月前
|
Kubernetes 架构师 算法
阿里面试:全国14亿人,统计出重名最多的前100个姓名
文章介绍了如何解决“从全国14亿人的数据中统计出重名人数最多的前100位姓名”的面试题,详细分析了多种数据结构的优缺点,最终推荐使用前缀树(Trie)+小顶堆的组合。文章还提供了具体的Java代码实现,并讨论了在内存受限情况下的解决方案,强调了TOP N问题的典型解题思路。最后,鼓励读者通过系统化学习《尼恩Java面试宝典》提升面试技巧。
阿里面试:全国14亿人,统计出重名最多的前100个姓名
|
2月前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?