腾讯二面:有 40 亿个 QQ 号,限制 1G 内存,问如何去重?被问懵了!

Posted Java技术栈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了腾讯二面:有 40 亿个 QQ 号,限制 1G 内存,问如何去重?被问懵了!相关的知识,希望对你有一定的参考价值。

40亿个QQ号,限制1G内存,如何去重?

40亿个unsigned int,如果直接用内存存储的话,需要:

4*4000000000 /1024/1024/1024 = 14.9G ,考虑到其中有一些重复的话,那1G的空间也基本上是不够用的。

想要实现这个功能,可以借助位图。

使用位图的话,一个数字只需要占用1个bit,那么40亿个数字也就是:

4000000000 * 1 /8 /1024/1024 = 476M

相比于之前的14.9G来说,大大的节省了很多空间。

比如要把我的QQ号"907607222"放到Bitmap中,就需要找到第907607222这个位置,然后把他设置成1就可以了。

这样,把40亿个数字都放到Bitmap之后,所有位置上是1的表示存在,不为1的表示不存在,相同的QQ号只需要设置一次1就可以了,那么,最终就把所有是1的数字遍历出来就行了。

什么是BitMap?有什么用?

位图(BitMap),基本思想就是用一个bit来标记元素,bit是计算机中最小的单位,也就是我们常说的计算机中的0和1,这种就是用一个位来表示的。

所谓位图,其实就是一个bit数组,即每一个位置都是一个bit,其中的取值可以是0或者1

像上面的这个位图,可以用来表示1,4,6:

如果不用位图的话,我们想要记录1,4,6 这三个整型的话,就需要用三个unsigned int,已知每个unsigned int占4个字节,那么就是3*4 = 12个字节,一个字节有8 bit,那么就是 12*8 = 96 个bit。

所以,位图最大的好处就是节省空间。

位图有很多种用途,特别适合用在去重、排序等场景中,著名的布隆过滤器就是基于位图实现的。

但是位图也有着一定的限制,那就是他只能表示0和1,无法存储其他的数字。所以他只适合这种能表示ture or false的场景。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

什么是布隆过滤器,实现原理是什么?

布隆过滤器是一种数据结构,用于快速检索一个元素是否可能存在于一个集合(bit 数组)中。

它的基本原理是利用多个哈希函数,将一个元素映射成多个位,然后将这些位设置为 1。当查询一个元素时,如果这些位都被设置为 1,则认为元素可能存在于集合中,否则肯定不存在

所以,布隆过滤器可以准确的判断一个元素是否一定不存在,但是因为哈希冲突的存在,所以他没办法判断一个元素一定存在。只能判断可能存在。

所以,布隆过滤器是存在误判的可能的,也就是当一个不存在的Hero元素,经过hash1、hash2和hash3之后,刚好和其他的值的哈希结果冲突了。那么就会被误判为存在,但是其实他并不存在。

想要降低这种误判的概率,主要的办法就是降低哈希冲突的概率及引入更多的哈希算法。

下面是布隆过滤器的工作过程:

1、初始化布隆过滤器

在初始化布隆过滤器时,需要指定集合的大小和误判率。布隆过滤器内部包含一个bit数组和多个哈希函数,每个哈希函数都会生成一个索引值。

2、添加元素到布隆过滤器

要将一个元素添加到布隆过滤器中,首先需要将该元素通过多个哈希函数生成多个索引值,然后将这些索引值对应的位设置为 1。如果这些索引值已经被设置为 1,则不需要再次设置。

3、查询元素是否存在于布隆过滤器中

要查询一个元素是否存在于布隆过滤器中,需要将该元素通过多个哈希函数生成多个索引值,并判断这些索引值对应的位是否都被设置为 1。如果这些位都被设置为 1,则认为元素可能存在于集合中,否则肯定不存在。

布隆过滤器的主要优点是可以快速判断一个元素是否属于某个集合,并且可以在空间和时间上实现较高的效率。但是,它也存在一些缺点,例如:

  1. 布隆过滤器在判断元素是否存在时,有一定的误判率。、
  2. 布隆过滤器删除元素比较困难,因为删除一个元素需要将其对应的多个位设置为 0,但这些位可能被其他元素共享。

应用场景

布隆过滤器因为他的效率非常高,所以被广泛的使用,比较典型的场景有以下几个:

1、网页爬虫: 爬虫程序可以使用布隆过滤器来过滤掉已经爬取过的网页,避免重复爬取和浪费资源。

2、缓存系统: 缓存系统可以使用布隆过滤器来判断一个查询是否可能存在于缓存中,从而减少查询缓存的次数,提高查询效率。布隆过滤器也经常用来解决缓存穿透的问题。

3、分布式系统: 在分布式系统中,可以使用布隆过滤器来判断一个元素是否存在于分布式缓存中,避免在所有节点上进行查询,减少网络负载。

4、垃圾邮件过滤: 布隆过滤器可以用于判断一个邮件地址是否在垃圾邮件列表中,从而过滤掉垃圾邮件。

5、黑名单过滤: 布隆过滤器可以用于判断一个IP地址或手机号码是否在黑名单中,从而阻止恶意请求。

如何使用

Java中可以使用第三方库来实现布隆过滤器,常见的有Google Guava库和Apache Commons库以及Redis。

如Guava:

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
public class BloomFilterExample 
    public static void main(String[] args) 
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    

Apache Commons:

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections4.BloomFilter;
import org.apache.commons.collections4.functors.HashFunctionIdentity;
public class BloomFilterExample 
    public static void main(String[] args) 
        // 创建布隆过滤器,预计插入100个元素,误判率为0.01
        BloomFilter<String> bloomFilter = new BloomFilter<>(HashFunctionIdentity.hashFunction(StringUtils::hashCode), 100, 0.01);
        // 插入元素
        bloomFilter.put("Lynn");
        bloomFilter.put("666");
        bloomFilter.put("八股文");
        // 判断元素是否存在
        System.out.println(bloomFilter.mightContain("Lynn")); // true
        System.out.println(bloomFilter.mightContain("张三"));  // false
    

Redis中可以通过Bloom模块来使用,使用Redisson可以:

Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myfilter");
bloomFilter.tryInit(100, 0.01);
bloomFilter.add("Lynn");
bloomFilter.add("666");
bloomFilter.add("八股文");
System.out.println(bloomFilter.contains("Lynn"));
System.out.println(bloomFilter.contains("张三"));
redisson.shutdown();

首先创建一个RedissonClient对象,然后通过该对象获取一个RBloomFilter对象,使用tryInit方法来初始化布隆过滤器,指定了最多能添加的元素数量为100,误判率为0.01。

然后,使用add方法将元素"犬小哈"、"666"和"八股文"添加到布隆过滤器中,使用contains方法来检查元素是否存在于布隆过滤器中。

或者Jedis也可以:

Jedis jedis = new Jedis("localhost");
jedis.bfCreate("myfilter", 100, 0.01);
jedis.bfAdd("myfilter", "Lynn");
jedis.bfAdd("myfilter", "666");
jedis.bfAdd("myfilter", "八股文");
System.out.println(jedis.bfExists("myfilter", "Lynn"));
System.out.println(jedis.bfExists("myfilter", "张三"));
jedis.close();

版权声明:本文为CSDN博主「code.song」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/songmulin/article/details/130814507

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

微信应用号 +QQ娱乐社交 腾讯能否独步天下?

备受关注的微信应用号“小程序”终于得到腾讯官方证实。在9月23日召开的2016腾讯全球合作伙伴大会上,腾讯方面确认已经通过微信公众平台陆续对外发送“小程序”内测邀请,也就是外界广泛关注的微信“应用号”。


现如今,每个用户的手机中都装有几十上百款APP,但实际打开率比较有限。对于不是高频次打开的APP,如订火车票、团购等,一旦“应用号”推出市场,相信都会愿意“移植”到微信平台上,享受微信的用户红利。


技术分享


对于“移植”后的低频次APP而言,“小程序”归集为微信入口并提供检索功能,方便用户需要时就能便捷操作,更容易找到,且平时就安静地躺在那里不推送信息,成为轻量化的App,增强了用户粘度,对低频次APP本身发展也大有裨益。


从微信发展角度看,“小程序”配合腾讯的地图、电商、支付等工具,微信将形成更为稳定的移动互联网生态,对百度、阿里以及小米的移动生态战略都造成强烈冲击。


与此同时,作为和微信内部有力竞争产品的腾讯QQ,在2016腾讯全球合作伙伴大会QQ分论坛也首次展示了其在“娱乐社交生态”构建上的设想,并在重量级合作伙伴的参与下,深入探讨了QQ在娱乐内容与社交平台融合发展的前景和举措。


由此看来,微信和QQ不仅没有互相挤压,反而在各自的领域颇有建树,形成差异化竞争,相信“双剑合璧”会对未来移动互联网的发展产生深远影响。


拥抱“年轻人”


在这个日新月异的时代,每当夜深人静的时候,一个问题始终让众多资深互联网从业者辗转反侧——究竟该如何与“年轻人”相处?他们一定会纳闷,连90后还没有研究清楚的时候,00后竟然已经站了起来;他们也一定会思索,不管是90后,还是00后,这些年轻人究竟都在哪儿?他们一定也会不断地在心里问自己,当“友谊的小船”、“宝宝心里苦”这些网络热语层出不穷的时候,我究竟应该提供一款什么样的产品? 


在最近的热门电影《小别离》中,小孩子使用QQ、大人使用微信的场景比比皆是,这都能够反应出QQ在微信强势崛起的情况下,寻找到了一条“差异化”竞争的路线。


腾讯公司第二季度财报显示,QQ月活跃账户数达到8.99亿,智能终端月活跃账户也达到6.67亿。与此同时,QQ最高同时在线账户数达到2.47亿。在所有的QQ用户中,有近6成是90后用户。而在QQ会员里,90后也占到了近8成。


同样根据腾讯的2016年第二季度财报,截至2016年6月底,微信和WeChat的合并月活跃账户数达到8.06亿,但微信用户的年龄层次远比QQ用户高,而对于同时使用微信和QQ的用户微信和QQ上满足了他们差异化的精神需求。


当微信被“大人们”占据,QQ则负责接纳那些在现实世界中还没有太多物质基础,但仍有丰富精神需求,从而构建属于自己的互联网平行世界的“年轻人”们。


网剧《太子妃升职记》很好地折射了这种心态的差异。和大人们爱看的高成本高投入的“大片”不同,作为一部从剧本到演员都不知名、制作粗糙、道具和布景简直没法看的网剧,火得令人猝不及防,原因可能仅仅只是因为它足够“奇葩”。追捧它的心态,和硬要让汪峰上头条一样没什么理由,唯一的理由可能就是它让年轻人觉得“好玩”。


用娱乐社交回归初心


与QQ一起成长的第一代用户大多数为70后、80后,走过17载,不少用户已对QQ产生了刻板印象——通常被当做是工作交流和邮件收发的工具。而积累了庞大的用户群的QQ,早已不甘于做一个普通的沟通工具,转而上升为开放式的生态构建平台。


抓住一代用户并不难,难的是让产品迭代的速度紧跟每一代用户,随着70后、80后的使用习惯改变,如何将90后的互联网“原住民”和QQ构建的生态平台连接起来?本次大会上,QQ将方向确定为娱乐和社交的有机结合,算是回归了初心——娱乐和社交是PC端QQ起步时的法宝,从最早的QQ头像、表情,到后来的QQ秀,再到现在基于移动端的个性化产品,与时俱进的改变获得了年轻人的喜爱。


技术分享


近一年来,手机 QQ在娱乐社交方面进行了相当多布局和探索,除开与腾讯动漫、腾讯游戏、阅读等腾讯自有业务联动外,手机QQ还搭建有相当多自己的产品,QQ的Now和企鹅电竞已经是国内排名前列的直播平台;而兴趣部落在部分前沿话题中,其用户数和活跃度都超越了贴吧。


当然,娱乐和社交二者的融合不是简单的1+1=2,而是希望达到1+1>2的效果。QQ的合作伙伴分享的娱乐内容,通过社交平台,用社交表情、兴趣讨论、直播等方式,开始社交型流转,娱乐内容可能被解读甚至重新创造,进而深刻的影响一个或多个群体,创造出广泛的社会影响力。


随着年轻人逐渐成为消费市场的中坚力量,对于年轻群体的洞察,是互联网等新兴行业和传统行业的共有痛点。腾讯公司副总裁殷宇就表示:“QQ娱乐社交生态的核心在于‘年轻人’。年轻人是娱乐社交生态的原力。年轻人作为内容消费者,也是传播者,甚至生产者。”


QQ上的众多年轻用户同样是娱乐产业的主力消费群体。通过大数据,腾讯QQ洞察了95后群体倾向“认同消费”的规律,与更多国际知名IP合作,与年轻人喜爱的品牌、影视剧作品以及明星合作,寻求年轻人的价值认同,从而建立QQ的品牌认同。


去年以来,QQ在承载娱乐内容的布局上有显著进展。QQ与迪斯尼、20世纪福克斯等多个世界级IP在影视领域深度合作;同时,QQ借助腾讯文学平台、QQ阅读产品两大板块,不仅为用户提供优质的文学阅读服务,也为内容创造者提供良好的扶持计划。此外,由QQ主办的QGC联赛已经发展成为国内影响力最大的手游电竞赛事之一,包括影视、动漫、游戏、文学都进行了联动,QQ在线上和线下体现出是娱乐内容的良好“容器”。 


处在社交和内容十字节点上的QQ,回归聚焦在娱乐社交,也是在做回最契合自己的业务,从而避免了生存空间被微信挤压,确立了自己在新生代年轻人心目中位置。


腾讯QQ标志性的消息提示音与闪动跳跃的头像,早已成为大多数网民生活和记忆的一部分。从这一点来看,QQ依然保持着“永远年轻”的姿态十分难得,重新与用户达成共识,拥抱互联网“原住民”,确实需要勇气和智慧。


2016腾讯全球合作伙伴大会上,微信和QQ各自找准定位“双剑合璧”之后,其创新精神可以用“永远年轻,永远热泪盈眶”来形容,这句话出自美国作家杰克·凯鲁亚克最精彩的自传体小说《达摩流浪者》结尾,书中宣扬的自由上路、追求理想与爱的理念影响了上世纪六十年代整整一代年轻人——ever youthful, ever weeping,让我们对未来的互联网生态拭目以待。


以上是关于腾讯二面:有 40 亿个 QQ 号,限制 1G 内存,问如何去重?被问懵了!的主要内容,如果未能解决你的问题,请参考以下文章

腾讯三面:40 亿个 QQ 号码如何去重?

腾讯三面:40亿个QQ号码如何去重?

腾讯微云上传文件大小限制是多少?为啥我不能上传超过1g的文件?今天刚用不了解,我记得以前不是宣传

腾讯二面5s内建立多少个mysql连接?

腾讯面试——SNG,QQ音乐

6.3 40亿个非负整数中找到没出现的数