BitMap在数仓领域的应用【面试加分项】

推荐阅读文章列表:大数据开发面试笔记V4.0 || 面试聊数仓第一季 || 小白大数据学习路线

很多人问我:三石兄,简历没什么亮点怎么办,模型优化除了知道mapjoin,其他啥都不知道,那么这篇文章就可以成为你在面试过程中跟面试官谈论的一个亮点!!!

1.背景

  • 需求:统计8月每种商品类别的购买人数
select mer_type, count(distinct uid)
from t -- 表t在100G左右
where dt between '20230801' and '20230831'
group by mer_type
  • 背景:这个任务跑了2h仍未跑出结果,就是因为count distinct在大数据量的情况下,性能巨差,于是想要使用bitmap来对其进行优化!

2.技术原理

2.1 BitMap

2.1.1 定义

  • BitMap的基本原理就是用一个bit来标记元素是否存在,因为仅用1个bit来存储一个数据,所以可以大大的节省空间;假设要使用BitMap来存储(1,5,1)这几个数字,如何存储呢?

0

1

2

3

4

5

6

7

0

1

0

0

0

1

0

0

2.1.2 使用场景

  • 海量数据量下求不重复的整数的个数

2.1.3 代码实现

以下代码可以直接运行

class Bitmap:
	def __init__(self, size):
		self.size = size
		self.bitmap = [0] * ((size + 31) // 32)
	def set(self, num):
		index = num // 32
		offset = num % 32
		self.bitmap[index] |= (1 << offset)
	def test(self, num):
	  	index = num // 32
		offset = num % 32
		return (self.bitmap[index] & (1 << offset)) != 0
def remove_dup(nums):
  	bitmap = Bitmap(len(nums))
	res = []
	for num in nums:
	  	if not bitmap.test(num):
		  	bitmap.set(num)
			res.append(num)
	return res
 # 测试
nums = [1,2,3,4,1,3]
res = remove_dup(nums)
print(res) # [1,2,3,4]

2.2 RoaringBitMap

2.2.1 BitMap的问题

  • 不管业务中实际的元素基数有多少,它占用的内存空间都恒定不变
  • 数据越稀疏,空间浪费越严重

2.2.2 定义

  • 将数据的前半部分,即216(这里为高16位)部分作为桶的编号,将分为216=65536个桶,RBM中将这些小桶叫做container
  • 存储数据时,按照数据的高16位做为container的编号去找对应的container(找不到就创建对应的container),再将低16位放入该container中
  • 所以一个RBM是很多container的集合

2.2.3 代码实现

import pyroaring
def remove_dup(nums):
  	bitmap = pyroaring.BitMap()
	res = []
	for num in nums:
	  	if num not in bitmap:
		  	bitmap.add(num)
			res.append(num)
# 测试
nums = [1,2,3,4,1,3]
res = remove_dup(nums)
print(res) # [1,2,3,4]

3.案例分析

  • 需求:统计8月每种商品类别的购买人数

3.1 定义UDF函数

import pyroaring
from pyhive import hive
def remove_dup(nums):
  	bitmap = pyroaring.BitMap()
	res = []
	for num in nums:
	  	if num not in bitmap:
		  	bitmap.add(num)
			res.append(num)
	return len(res)

3.2 创建UDF函数

CREATE FUNCTION remove_dup(nums array) RETURNS int
AS 'SELECT remove_dup(nums) FROM bitmap.py' LANGUAGE PYTHON;

3.3 使用UDF函数

select mer_type, remove_dup(collect_list(uid))
from t -- 表t在100G左右
where dt between '20230801' and '20230831'
group by mer_type

#数据人的面试交流地##晒一晒我的offer##我发现了面试通关密码##如何判断面试是否凉了##牛客在线求职答疑中心#
全部评论

相关推荐

01-11 08:47
门头沟学院 Java
choumoduji...:读研的目的就是为了以最快的速度和最低的要求完成“学校”规定的毕业标准,而不是所谓课题组的要求
点赞 评论 收藏
分享
老粉都知道小猪猪我很久没更新了,因为秋招非常非常不顺利,emo了三个月了,接下来说一下我的情况吧本人是双非本&nbsp;专业是完全不着计算机边的非科班,比较有优势的是有两段大厂实习,美团和字节。秋招面了50+场泡池子泡死的:滴滴&nbsp;快手&nbsp;去哪儿&nbsp;小鹏汽车&nbsp;不知名的一两个小厂其中字节13场&nbsp;两次3面挂&nbsp;两次2面挂&nbsp;一次一面挂其中有2场面试题没写出来,其他的都是全a,但该挂还是挂,第三次三面才面进去字节,秋招加暑期总共面了22次字节,在字节的面评可以出成书了快手面了8场,2次实习的,通过了但没去,一次2面挂&nbsp;最后一次到录用评估&nbsp;至今无消息滴滴三面完&nbsp;没几天挂了&nbsp;所有技术面找不出2个问题是我回答不上来的,三面还来说我去过字节,应该不会考虑滴滴吧,直接给我干傻了去哪儿一天速通&nbsp;至今无消息小鹏汽车hr&nbsp;至今无消息美团2面挂&nbsp;然后不捞我了,三个志愿全部结束,估计被卡学历了虾皮二面挂&nbsp;这个是我菜,面试官太牛逼了拼多多二面挂&nbsp;3道题也全写了&nbsp;也没问题是回答不出来的&nbsp;泡一周后挂腾讯面了5次&nbsp;一次2面挂&nbsp;三次一面挂,我宣布腾讯是世界上最难进的互联网公司然后还有一些零零散散的中小厂,但是数量比较少,约面大多数都是大厂。整体的战况非常惨烈,面试机会少,就算面过了也需要和各路神仙横向对比,很多次我都是那个被比下去的人,不过这也正常,毕竟谁会放着一个985的硕士不招,反而去招一个双非读化学的小子感觉现在互联网对学历的要求越来越高了,不仅仅要985还要硕士了,双非几乎没啥生存空间了,我感觉未来几年双非想要进大厂开发的难度应该直线上升了,唯一的打法还是从大二刷实习,然后苟个转正,不然要是去秋招大概率是炮灰。而且就我面字节这么多次,已经开始问很多ai的东西了,你一破本科生要是没实习没科研懂什么ai啊,纯纯白给了
不知名牛友_:爸爸
秋招你被哪家公司挂了?
点赞 评论 收藏
分享
评论
8
24
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务