【算法】阿里面试题-编码实现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);
    }
}
相关文章
|
5月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
4月前
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
3月前
|
负载均衡 架构师 Cloud Native
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选  CP 还是 AP?为什么?
|
4月前
|
SQL Java 数据库连接
阿里腾讯互联网公司校招 Java 面试题总结及答案解析
本文总结了阿里巴巴和腾讯等互联网大厂的Java校招面试题及答案,涵盖Java基础、多线程、集合框架、数据库、Spring与MyBatis框架等内容。从数据类型、面向对象特性到异常处理,从线程安全到SQL优化,再到IOC原理与MyBatis结果封装,全面梳理常见考点。通过详细解析,帮助求职者系统掌握Java核心知识,为校招做好充分准备。资源链接:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
118 2
|
9月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
6月前
|
存储 NoSQL Redis
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 +  无锁架构 +  EDA架构  + 异步日志 + 集群架构
|
6月前
|
存储 算法 架构师
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
阿里面试:PS+PO、CMS、G1、ZGC区别在哪?什么是卡表、记忆集、联合表?问懵了,尼恩来一个 图解+秒懂+史上最全的答案
|
8月前
|
存储 SQL 算法
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer
例如,在一个有 10 个节点的系统中,增加一个新节点,只会影响到该新节点在哈希环上相邻的部分数据,其他大部分数据仍然可以保持在原节点,大大减少了数据迁移的工作量和对系统的影响。狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由”。在 3 - 5 年的中期阶段,随着业务的稳定发展和市场份额的进一步扩大,订单数据的增长速度可能会有所放缓,但仍然会保持在每年 20% - 30% 的水平。
阿里面试:每天新增100w订单,如何的分库分表?这份答案让我当场拿了offer

热门文章

最新文章