拼多多面试|如何用 Redis 统计独立用户访问量?

作者 | 沙茶敏碎碎念

来源 | www.cnblogs.com/xiaoMzjm/p/5223799.html

众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作3年的开发,稍微优秀一点的,都给到30K的Offer

当然,拼多多加班也是出名的,一周上6天班是常态,每天工作时间基本都是超过12个小时,也是相当辛苦的。

废话不多说,今天我们来聊一聊拼多多的一道后台面试真题,是一道简单的架构类的题目:

拼多多有数亿的用户,那么对于某个网页,怎么使用Redis来统计一个网站的用户访问数呢?

使用Hash

哈希是Redis的一种基础数据结构,Redis底层维护的是一个开散列,会把不同的key映射到哈希表上,如果是遇到关键字冲突,那么就会拉出一个链表出来。

当一个用户访问的时候,如果用户登陆过,那么我们就使用用户的id,如果用户没有登陆过,那么我们也能够前端页面随机生成一个key用来标识用户

当用户访问的时候,我们可以使用HSET命令,key可以选择URI与对应的日期进行拼凑,field可以使用用户的id或者随机标识,value可以简单设置为1。

当我们要统计某一个网站某一天的访问量的时候,就可以直接使用HLEN来得到最终的结果了。

优点:简单,容易实现,查询也是非常方便,数据准确性非常高。

缺点:占用内存过大,。随着key的增多,性能也会下降。小网站还行,拼多多这种数亿PV的网站肯定受不了

使用Bitset

我们知道,对于一个32位的int,如果我们只用来记录id,那么只能够记录一个用户,但如果我们转成2进制,每位用来表示一个用户,那么我们就能够一口气表示32个用户,空间节省了32倍!

对于有大量数据的场景,如果我们使用bitset,那么可以节省非常多的内存。

对于没有登陆的用户,我们也可以使用哈希算法,把对应的用户标识哈希成一个数字id。bitset非常的节省内存,假设有1亿个用户,也只需要100000000/8/1024/1024约等于12兆内存。

Redis已经为我们提供了SETBIT的方法,使用起来非常的方便,我们可以看看下面的例子

我们在item页面可以不停地使用SETBIT命令,设置用户已经访问了该页面,也可以使用GETBIT的方法查询某个用户是否访问。最后我们通过BITCOUNT可以统计该网页每天的访问数量。

优点:占用内存更小,查询方便,可以指定查询某个用户,数据可能略有瑕疵,对于非登陆的用户,可能不同的key映射到同一个id,否则需要维护一个非登陆用户的映射,有额外的开销。

缺点:如果用户非常的稀疏,那么占用的内存可能比方法一更大。

使用概率算法

对于拼多多这种多个页面都可能非常多访问量的网站,如果所需要的数量不用那么准确,可以使用概率算法

事实上,我们对一个网站的UV的统计,1亿跟1亿零30万其实是差不多的。

在Redis中,已经封装了HyperLogLog算法,他是一种基数评估算法。这种算法的特征,一般都是数据不存具体的值,而是存用来计算概率的一些相关数据。

当用户访问网站的时候,我们可以使用PFADD命令,设置对应的命令,最后我们只要通过PFCOUNT就能顺利计算出最终的结果,因为这个只是一个概率算法,所以可能存在0.81%的误差。

优点:占用内存极小,对于一个key,只需要12kb。对于拼多多这种超多用户的特别适用。

缺点:查询指定用户的时候,可能会出错,毕竟存的不是具体的数据。总数也存在一定的误差。

上面就是常见的3种适用Redis统计网站用户访问数的方法了。

推荐阅读:Java面试题汇总(208道)
【END】
关注下方二维码,订阅更多精彩内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

被一个熟悉的面试题问懵了:StringBuilder 为什么线程不安全?

作者 | 千山qianshan 来源 | juejin.im/post/5d6228046fb9a06add4e37fe前言周五去面试又被面试的一个问题问哑巴了面试官:StringBuilder和StringBuffer的区别在哪? 我:StringBuilder不是线程安全的,StringBuffer是线程安全的 面试…

面试官:HTTPS 为什么是安全的?说一下他的底层实现原理?

作者 | leapmie来源 | urlify.cn/zQj6f2这篇干货不错,把HTTPS的原理讲清楚了,而且容易懂,建议大家好好读一下。# HTTPS随着 HTTPS 建站的成本下降,现在大部分的网站都已经开始用上 HTTPS 协议。大家都知道 HTTPS 比 HTTP 安全&…

PyQt5在对话框中打开外部链接的方法

利用PyQt5部分控件的Link属性链接 PyQt5有几个控件带有 setOpenExternalLinks , 如 QLabel、QTextLabel 、 QTextBrowser 等 当 setOpenExternalLinks 值为TURE 表示可通过html 添加 A 标签打开外部链接, 如设置: 我测试的是 QLabel 标签控件 self.lab…

面试官:为什么 Spring 中的 bean 默认为单例?

作者 | 小小木来源 | http://1t.click/ksQ熟悉Spring开发的朋友都知道Spring提供了5种scope分别是singleton、prototype、request、session、global session。如下图是官方文档上的截图,感兴趣的朋友可以进去看看这五种分别有什么不同。今天要介绍的是这五种中的前两…

博主推荐【文件Hash校验工具V1.0 -免费版】

文件Hash校验工具有什么用途? ​Hash校验工具可以用来计算文件的MD5、SHA1、SHA256、CRC32值。简单来说,MD5值就是文件的身份ID,并且具有唯一性。通过比对MD5值,用户能够检查文件是否被篡改过,确保安全性。一般来说&a…

基于深度学习的瓷砖色差分类方法研究——学习笔记(评价:色差的定义太模糊。。。问题描述不清楚,太水了)

文章目录 摘要0 引言1 瓷砖图像处理1.1 图像采集1.2 图像处理 2 基于深度学习的瓷砖色差分类算法设计2.1 数据预处理2.2 卷积神经网络的设计2.3 实验设计 3 瓷砖色差分类平台的设计与实现 摘要 瓷砖是人类建筑不可或缺的一种材料,而瓷砖品质最重要的指标之一就是色…

面试官 | 讲一下如何给高并发系统做限流?

作者 | nick hao来源 | uee.me/cDuRD在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。本文结合作者的一些经验介绍限流的相关概念、算法和常规的实现方式。缓存缓存比较好理解,在大型高并发系统中,如果没有缓存数据库将分分钟被…

Python利用multiprocessing实现多进程,Pyinstaller打包python多进程程序出现多个窗口

一、为什么需要采用multiprocessing多线程技术 自己在做文件Hash校验工具V1.0小工具软件时,需要读取文件,计算文件的MD5、SHA1、SHA256和CRC32这些Hash值,对于小文件能够很快计算出hash值,但是对于大文件需要花费一些时间,不知道进度如何?使用进度条指示也无法正确显示进…

面试官 | 说一下数据库如何分库分表?

作者 | butterfly100来源 | cnblogs.com/butterfly100/p/9034281.html一. 数据切分关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索…

面试官 | JVM 为什么使用元空间替换了永久代?

7:40到11:40历时4个小时完成了该文,看到电脑中左边的便签了么,我也是拼了。在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试者,如果知晓这些变化&a…

Typora颠覆写作体验的极简好用 Markdown 编辑器基本设置教程

Typora是一款Markdown编辑器。 无论你是建网站写博客、每天写日记、自媒体写稿、办公、程序员写代码文档等等,Typora 都能满足你的要求。 Typora基本设置教程 1.“通用”项设置 打开“文件”下的“偏好设置”选项,在“通用”这项下,设置自…

面试官问:一个Java字符串中到底能有多少个字符?

作者 | 鸟窝来源 | urlify.cn/qYNR3q依照Java的文档, Java中的字符内部是以UTF-16编码方式表示的,最小值是 \u0000 (0),最大值是\uffff(65535), 也就是一个字符以2个字节来表示,难道Java最多只能表示 65535个字符?char…

PHP多进程处理并行处理任务实例

2019独角兽企业重金招聘Python工程师标准>>> 本文目的 本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步。写得比较简单,作为备忘录。 PHP多进程 通过pcntl_XXX系列函数使用多进程功能…

Python PyCharm利用PyQt5使QPlainTextEdit支持拖放文件,类提升,重写QPlainTextEdit类

一、利用PyCharm新建基于PyQt5对话框工程MyMainTest,添加QPlainTextEdit控件,保存主窗口MyQTMainForm.ui文件运行如下: 二、新建myqplaintextedit.py文件,创建MyQPlainTextEdit类继承于QPlainTextEdit,只允许excel(.xls或.xlsx)文件拖放,及信号发射处理。代码如下: #…

经典面试题|ConcurrentHashMap 读操作为什么不需要加锁?

作者 | 上帝爱吃苹果来源 | cnblogs.com/keeya/p/9632958.html我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题——为什么它…

正能量

2019独角兽企业重金招聘Python工程师标准>>> 对别人,永远把最好的方面表现出来,这样别人都会为你传递正能量,你就能够得到能量累加。 对自己,要自信,永远给自己传递正能量,这样自己周边的能量场…

Python datetime time计算时间差

一、计算时间差 """ python主文件 """ # -*- coding: utf-8 -*-import time"""主函数 """ if __name__ __main__:# 获取当前开始的日期和时间,例:2022-02-05 14:20:36strStartDateTime …

面试官 | AJAX请求为什么不安全?

作者 | 撒网要见鱼链接 | cnblogs.com/dailc/p/8191150.html# AJAX三问AJAX请求真的不安全么?AJAX请求哪里不安全?怎么样让AJAX请求更安全?# 前言本文包含的内容较多,包括AJAX,CORS,XSS,CSRF等内…

IE6,IE7 Firefox 兼容问题

2019独角兽企业重金招聘Python工程师标准>>> 关于ie6、ie7和ff浏览器兼容网友评论 0 条 转载到博客 2009-1-8 16:11:23 来源: 本站整理顶一下这些方法都是我平时用到时在网上找到收藏下来的呵呵,我提前声明一下免得误会!一、CSS HACK以下两种方法几乎能…

面试官 | 说一下什么是代理模式?

看了这篇文章,你会对静态代理模式,JDK 动态代理模式和 CGLIB 动态代理模式有个很清晰的认识。01、简介什么是代理模式代理模式也称为委托模式,属于结构型模式之一。在某些情况下,一个对象不适合或者不能直接引用另一个对象&#x…