Redis数据结构HyperLogLog以及布隆过滤器
HyperLogLog
引言
在开始之前,先思考一个常见的业务问题:如果负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的UV数据,然后来开发这个统计模块,需要如何实现?
如果统计PV非常好办,给每个网页一个独立的Redis计数器即可,这个计数器的key后缀加上当天的日期。这样每次一个请求,incrby一次,最终就可以统计出所有的PV数据。
但是UV不一样,他要去重,同一个用户一天之内的多次访问请求只能计数一次,这就要求每一个网页请求都需要带上用户ID。无论是登录用户还是未登录用户都需要一个唯一ID来标识。也许你已经想到了一个简单的方案,那就是为每一个页面设置一个独立的set集合来存储所有当天访问过此页面的用户ID,当一个请求过来时,使用sadd将用户ID塞进去即可,通过scard可以取出这个集合的大小,这个数字就是这个页面的UV数据。
但是,如果页面的访问量非常大,比如一个爆款页面几千万的UV,此时就需要一个很大的set集合来统计,这非常浪费空间。如果这样的页面很多,那么所需要的存储空间是惊人的。为了这样一个去重功能耗费如此多的存储空间,其结果必然是不值得。其实,老板需要的数据不需要太精确,105w和106w这两个数字对于老板们来说并没有多大区别,因此,需要探讨一种更好的解决方案。
因此,本文主要讨论,Redis提供的HyperLogLog来解决这个问题。HyperLogLog提供不精确的去重计数方案,
其标准误差是0.81%,这样的精确度足够满足很多UV需求。
使用方法
HyperLogLog提供了两个指令pfadd和pfcount,一个是增加计数,一个是获取计数。pfadd用法和set集合的sadd一样,来一个用ID,就将用户ID塞进去即可。pfcount和scard用法一样,直接获取计数值。
127.0.0.1:6379> pfadd codehole user1
(integer) 1
127.0.0.1:6379> pfcount codehole
(integer) 1
127.0.0.1:6379> pfadd codehole user2
(integer) 1
127.0.0.1:6379> pfcount codehole
(integer) 2
127.0.0.1:6379> pfadd codehole user3 user4 user5 user6
(integer) 6
简单试了一下,发现还蛮精确的,一个没多一个也没少,接下来,使用脚本,灌入更多的数据,看看是否还可以继续精确下去,如果不能精确,差距有多大。
public class PfTest {public static void main(String[] args) {Jedis jedis = new Jedis();for (int i = 0; i < 100000; i++) {jedis.pfadd("codehole", "user" + i);long total = jedis.pfcount("codehole");if (total != i + 1) {System.out.printf("%d %d\n", total, i + 1);break;}}jedis.close();}
}
当加入10w数据的时候,输出结果为99723,差了277,按照百分比是0.277%。当再次运行这个脚本的时候输出结果仍然是99723(redis运行过一次已经存在数据的情况下),说明他确实具备去重功能。
pfmerge
HyperLogLog除了上面的pfadd和pfcount之外,还提供了第三个指令pfmerge,用于将多个pf计数值累加在一起形成一个新的pf值。比如在网站中我们有两个内容差不多的页面,需要将这两个页面的数据进行合并,其中页面的UV访问量也需要合并,那么这个时候pfmerge就可以派上用场。
布隆过滤器
引言
上文讲述了使用HyperLogLog数据结构来进行估数,可以解决很多精确度不高的统计需求。但是,如果我们想知道某一个值是不是已经在HyperLogLog结构里面了,他就无能为力,他只提供pfadd和pfcount方法,没有提供pfcontains方法。
举个使用场景,我们在使用新闻客户端看新闻时,他会给我们不停的推荐新的内容,他每次推荐时要去重,去掉那些已经看过的内容。新闻客户端的推荐系统如何实现推送去重?
很容易想到服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。问题是当用户量很大,每个用户看过的新闻又很多的情况下,这种方式,推荐系统的去重工作在性能上跟得上吗?
实际上,如果历史记录存储在关系数据库里,去重就需要频繁的对数据库进行exists查询,当系统并发量很高时,数据库是很难扛住压力的。
如果将如此多的历史记录全部缓存起来,那得浪费多大存储空间。而且这个存储空间是随着时间线性增长,很难长时间撑的住。但是不缓存的话,性能又跟不上,此时该如何解决。
这时,布隆过滤器(Bloom Filter)闪亮登场,他就是专门用来解决去重问题的。他在起到去重的同时,在空间上还能节省90%以上,只是稍微有点不精确,也就是有一定的误判概率。
布隆过滤器是什么
布隆过滤器可以理解为一个不怎么精确的set结构,当使用它的contains方法判断某个对象是否存在时,他可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合适,他的精确度可以控制的相对足够精确,只会有小小的误判概率。
当布隆过滤器说某个值存在时,这个值可能不存在;当他说不存在时,那就肯定不存在
。套在上面的使用场景中,布隆过滤器能准确过滤掉那些已经看过的内容,那些没有看过的新内容,他也会过滤掉极小一部分,但是绝大多数心能容他都能准确识别。这样就可以完全保证推荐给用户的内容都是无重复的。
Redis中的布隆过滤器
Redis官方提供的布隆过滤器到了Redis4.0提供了插件功能之后才正式登场。布隆过滤器作为一个插件加载到Redis Server中,给Redis提供了强大的布隆去重功能。
布隆过滤器基本使用
布隆过滤器有三个基本指令,bf.add添加元素,bf.exists查询元素是否存在
,他的用法和set集合的sadd和sismember差不多。bf.add一次只能添加一个元素,如果想要一次添加多个,就需要用到bf.madd指令。同样如果需要一次查询多个元素是否存在,就需要使用bf.mexists指令。
127.0.0.1:6379> bf.add codehole user1
(integer) 1
127.0.0.1:6379> bf.add codehole user2
(integer) 1
127.0.0.1:6379> bf.add codehole user3
(integer) 1
127.0.0.1:6379> bf.exists codehole user1
(integer) 1
127.0.0.1:6379> bf.exists codehole user2
(integer) 1
127.0.0.1:6379> bf.exists codehole user4
(integer) 0
代码测试
public class BloomTest {public static void main(String[] args) {Client client = new Client();client.delete("codehole");for (int i = 0; i < 100000; i++) {client.add("codehole", "user" + i);boolean ret = client.exists("codehole", "user" + (i + 1));if (ret) {System.out.println(i);break;}}client.close();}
}
运行后,可以看到输出214,即到第214的时候,就出现了误判。那么如何测量误判率呢?我们先随机出一堆字符串,然后切分为2组,将其中一组塞入布隆过滤器,然后判断另外一组的字符串存在与否,取误判的个数和字符串总量一半的百分比作为误判率。
代码如下:
pom中添加依赖
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.9.0</version></dependency><dependency><groupId>com.redislabs</groupId><artifactId>jrebloom</artifactId><version>2.2.2</version></dependency>
package example;
import io.rebloom.client.Client;
import redis.clients.jedis.Jedis;class BloomRedis {private Client client;private Jedis jedis;private int capacity = 20000;// 容错率,只能设置0 < error rate range < 1 不然直接会异常!private double errorRate = 0.01;public BloomRedis() {jedis = new Jedis("127.0.0.1", 6379);client = new Client(jedis);}public void count(String key) {if (!jedis.exists(key)) {client.createFilter(key, capacity, errorRate);}int realCapacity = 20000;for (int i = 0; i < realCapacity; i++) {client.bfInsert(key, String.valueOf(i));}System.out.println("存入元素为=={" + realCapacity + "}");// 统计误判次数int count = 0;// 我在数据范围之外的数据,测试相同量的数据,判断错误率是不是符合我们当时设定的错误率for (int i = capacity; i < realCapacity * 2; i++) {if (client.exists(key, String.valueOf(i))) {count++;}}System.out.println("误判元素为=={" + count + "}");// 删除过滤器client.delete(key);}
}
class ExampleTest {public static void main(String[] args) {BloomRedis bloomRedis = new BloomRedis();bloomRedis.count("codehole");}
}
输出结果:
存入元素为=={20000}
误判元素为=={174}
设置处理容量为20000,容错率为0.01的情况下,输出结果最终错误率为0.0087。
一组其他测试数据
//当realCapacity为5000,capacity 20000,错误率为0
//当realCapacity为10000,capacity 20000,错误率为0
//当realCapacity为20000,capacity 20000,错误率为0.08
//当realCapacity为40000,capacity 20000,错误率为0.5
//当realCapacity为40000,capacity 80000,错误率为0
注意事项
布隆过滤器的initial_size估计的越大,会浪费存储空间,估计的过小,就会影响准确率,用户在使用之前一定要尽可能的精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会高出估计值很多。
布隆过滤器的error_rate越小,需要的存储空间越大,对于不需要过于精确的场合,error_rate设置稍大一点也无伤大雅。比如在新闻去重上而言,误判率高一点只会让小部分文章不能让合适的人看到。文章的整体阅读量不会因为这点误判率就带来巨大的改变。
布隆过滤器原理
每个布隆过滤器对应到Redis的数据结构里面就是一个大型的位数组和几个不一样的无偏hash函数。所谓无偏就是能够把元素的hash值算的比较均匀。
向布隆过滤器中添加key时,会使用多个hash函数对key进行hash算的一个整数索引值然后对位数组长度进行取模运算得到一个位置。每个hash函数都会算得一个不同的位置,再把位数组的这几个位置都置为1,就完成了add操作。
向布隆过滤器询问key是否存在时,跟add一样,也会把hash的几个位置(对一个值进行多次hash,每次hash计算得出在位数组中的一个索引,多个hash得到多个索引,每个索引位置在位数组中都是1那这个值就是存在)
都算出来,看看位数组中这几个位置是否都为1.只要有一个为0,那么说明布隆过滤器这个key不存在。如果都是1,这不能说明这个key一定存在,只是极有可能存在,因为这些位置为1可能是因为其他的key存在所致。
使用时不要让实际元素大于初始化大小,当实际元素开始超出初始化大小时,应该对布隆过滤器进行重建,重新分配一个size更大的过滤器。再将所有的历史元素批量add进去(这就要求我们在其他的存储器中记录所有的历史数据)。因为error_rate不会因为数量超出就急剧增加,这就给我们重建过滤器提供了较为宽松的时间。
空间占用估计
布隆过滤器有两个参数,第一个是预计元素的数量n,第二个是错误率f。公示根据这两个输入得到两个输出,第一个输出是位数组的长度1,也就是需要的存储空间大小(bit),第二个输出是hash函数的最佳数量k。hash函数的数量也会直接影响到错误率,最佳的数量会有最低的错误率。
k = 0.7 * (1/n)
f = 0.6185 ^ (1/n)
从公式中可以看出
- 位数组相对越长(1/n),错误率 f 越低,这个和直观上理解一致。
- 位数组相对越长(1/n),hash函数需要的最佳数量也越多,影响计算效率。
- 当一个元素平均需要1个字节(8bit)的指纹空间时(1/n =8),错误率大约为0.02.
- 错误率为10%,一个元素需要的平均指纹空间为4.792个bit,大约为5 bit.
- 错误率为1%,一个元素需要的平均指纹空间为9.585个bit,大约为10 bit。
- 错误率为 0.1%,一个元素需要的平均指纹空间为 14.377 个 bit,大约为 15 bit。
此时,也许会想,如果一个元素需要占据15个bit,那相对set集合的空间优势是不是就没有那么明显了?这里需要明确的是,set会存储每个元素的内容,而布隆过滤器仅仅存储元素的指纹。元素的内容大小就是字符串的长度,他一般会有多个字节,甚至是几十个字节,每个元素还需要一个指针被set集合来引用,这个指针又会占去4个字节或者8个字节,取决于系统是32bit还是64bit。而指纹空间只有接近2个字节,所以布隆过滤器的优势还是非常明显的。
推荐使用布隆过滤器计算需要提供的存储空间。
实际元素超出时,误判率会怎样变化
当实际元素超出预计元素时,误判率变化需要引用下述计算公式。引入参数 t 表示实际元素和预计元素的倍数 t。
f = (1-0.5^t )^k. #极限近似,k是hash函数的最佳数量
当t增大时,错误率 f 也会跟着增大,分别选择错误率为 10%,1%,0.1%的k值,观察他的曲线
从这个图中可以看出曲线还是比较陡峭的
错误率为10%时,倍数比为2时,错误率就会升至40%,这就比较危险了
错误率为1%时,倍数比为2时,错误率升至15%。
错误率为0.1%,倍数比为2时,错误率升至5%。
布隆过滤器的其他应用
在爬虫系统中,我们需要对URL进行驱虫,已经爬过的网页就可以不用爬了,但是URL太多了,几千万几个亿。如果用一个集合装下这些URL地址那是非常浪费空间的,这时候就可以考虑使用布隆过滤器,他可以大幅降低去重存储消耗,只不过也会使得爬虫系统错误少量的页面。
布隆过滤器在NoSql数据库领域使用非常广泛,我们平时用到的Hbase、Cassandra还有LevelDB、RocksDB内部都有布隆过滤器结构,布隆过滤器可以显著降低数据库IO请求数量,当用户来查询某个row时,可以先通过内存中的布隆过滤器过滤掉大量不存在的row请求,然后再去磁盘进行查询。
邮箱系统的垃圾邮件过滤功能也普遍用到了布隆过滤器,因为用了这个过滤器,所以平时也会遇到某些正常的邮件被放进了垃圾邮箱目录中,这个就是误判所致,概率很低。
相关文章:
Redis数据结构HyperLogLog以及布隆过滤器
HyperLogLog 引言 在开始之前,先思考一个常见的业务问题:如果负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的UV数据,然后来开发这个统计模块,需要如何实现? 如果统计PV非常好办&…...
C++——从C语言快速入门
目录 一、数组 1、声明数组 2、初始化数组 3、访问数组元素 4、示例 5、注意事项 6、数组小练习 计算器支持加减乘除 数组找最大值 二、指针 三、字符串 string 类型 一、数组 在 C 中,数组是一种存储固定大小的相同类型元素的序列。数组的所有元素都存…...
thinkpad T440p ubuntu-slam软件安装记录
安装问题 1.ubuntu20.04安装后提示"x86/cpu:VMX(outside TXT) disabled by BIOS" 这是虚拟化被禁止了,到BIOS里去把Virtualization选项打开即可。 2.ACPI Error:Needed type[Reference],found [Integer] 等错误 link这篇博客中提到该问题,…...
本地电脑访问windows server系统服务器 并传输文件
1、 mstsc 命令打开远程桌面连接。 2、填入登入的用户密码,在本地资源中设置需要共享的盘。登入成功后就可以在服务器与本地电脑互传文件了。...
kubernetes负载均衡---MetalLB
https://github.com/metallb/metallb 参考 : https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q 自建的Kubernetes集群,默认情况下是不支持负载均衡的。当需要提供服务的外部访问时,可使用 Ingress、NodePort等方式。他们都存在一些问题 …...
Python面试宝典:Python中与设计模式相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)
Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第二十二章:代码设计和设计模式:第二节:设计模式】 第二十二章:代码设计和设计模式第二节:设计模式创建型模式结构型模式行为型模式python中与设计模式相关的面试笔试题面试题1面试题…...
以sqlilabs靶场为例,讲解SQL注入攻击原理【18-24关】
【less-18】 打开时,获取了自己的IP地址。,通过分析源码知道,会将用户的user-agent作为参数记录到数据库中。 提交的是信息有user-Agent、IP、uname信息。 此时可以借助Burp Suite 工具,修改user_agent,实现sql注入。…...
【已有项目版】uniapp项目发版pda -- Android Studio
必备资料清单: 构建完成的app项目 在HBuilderX开发的uniapp项目 .keystore文件 文章目录 1. 安装Android Studio:https://developer.android.google.cn/studio?hlzh-cn2. 安装Android 离线SDK:https://nativesupport.dcloud.net.cn/AppDocs…...
三维重建,谁才是顶流?
3DGS技术是近年来计算机视觉领域最具突破性的研究成果之一。它不仅在学术界引起了广泛关注,成为计算机视觉、SLAM等领域的研究热点,而且每天都有大量基于Gaussian Splatting的新研究问世。此外,3DGS技术在商业应用方面也取得了显著进展&#…...
s32k314【入门新手篇】-开发环境安装【ds32开发平台】
软件包下载 登录nxp官网下载:https://www.nxp.com/ 然后输入关键字:S32 查看 下载安装包 以上三步请先注册好并登录你的个人账号 下载完之后如下: 软件安装 eb安装并激活【试用版】 激活 2 安装ds 弹出什么就安装什么就好了。 …...
DiffBIR论文阅读笔记
这篇是董超老师通讯作者的一篇盲图像修复的论文,目前好像没看到发表在哪个会议期刊,应该是还在投,这个是arxiv版本,代码倒是开源了。本文所指的BIR并不是一个single模型对任何未知图像degradation都能处理,而是用同一个…...
基于STM32的位置速度环PID控制伺服电机转动位置及程序说明
PID控制原理 PID控制原理是一种广泛应用于工业自动化和其他领域的控制算法。PID控制器的名字来源于其三个主要组成部分:比例(Proportional)、积分(Integral)和微分(Derivative)。PID控制器实现…...
操作失败——后端
控制台观察,页面发送的保存菜品的请求 返回的response显示: ---------- 我开始查看明明感觉都挺正常,没啥错误,就是查不出来。结果后面电脑关机重启后,隔一天看,就突然可以了。我觉着可能是浏览器的缓存没…...
基于SSM的“学校访客登记系统”的设计与实现(源码+数据库+文档)
基于SSM的“学校访客登记系统”的设计与实现(源码数据库文档) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 平台架构图 系统首页 校园公告信息界面 留言板管理界面 家庭来…...
linux配置IP、子网掩码、网关
linux虚拟机配置IP、子网掩码、网关 本方法适用于 Ubuntu 18.04 之后的版本。 例1: 配置信息: IP:10.100.100.23 子网掩码:255.255.255.240 网关:10.100.100.56 1、打开网络配置文件 01-network-manager-all.yaml sudo vi /etc/netplan/01-network-…...
Java 垃圾回收
文章目录 1 Java 垃圾回收1.1 JVM1.2 Java 对象生命周期 2 如何判断一个对象可被回收2.1 引用计数算法2.2 可达性分析算法 3 垃圾回收过程3.1 总体过程3.2 为什么要进行世代垃圾回收?3.3 分代垃圾回收过程 在 C 和 C 中,许多对象要求程序员声明他们后为其…...
多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政线下预约等多场景应用支持H5+小程序+APP
多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政按摩线下预约等多场景应用支持H5小程序APP 软件架构 前端:Uniapp-vue2.0 后端:Thinkphp6 前后端分离 前端支持: H5小程序双端APP(安卓苹果) 安装教程 【商业…...
书生·浦语大模型全链路开源体系-笔记作业2
全部写成了shell脚本,可以一键执行。 笔记: 1. 环境安装(InternStudio开发机) # 1. 创建conda环境 studio-conda -o internlm-base -t demo # 2. 激活conda环境 conda activate demo # 3. 安装额外的依赖 pip install huggingface-hub0.17.3 pip inst…...
手把手教你发布你的第一个npm插件包
在开源的世界里,npm(Node Package Manager)不仅是JavaScript生态中不可或缺的一部分,也是全球最大的软件注册表,它使得分享和复用代码变得异常简单。如果你有一个很棒的想法或者实用的功能想要封装成一个npm包供他人使…...
Docker-compose 编排lnmp(dockerfile) 完成Wordpress
一、部署 Nginx 镜像 1. 建立工作目录 mkdir /opt/lnmp/nginx -pcd /opt/lnmp/nginx#上传 nginx 安装包 nginx-1.12.0.tar.gz#上传 wordpress 服务包 wordpress-4.9.4-zh_CN.tar.gz mkdir /opt/lnmp/nginx/htmltar zxvf wordpress-4.9.4-zh_CN.tar.gz -C /opt/lnmp/nginx/html…...
秋招突击——算法打卡——5/28——复习{Z字形变换、两数之和}——新做:{整数反转、字符串转整数}
文章目录 复习Z字形变换实现代码参考代码 两数之和复习代码 新作整数反转个人实现实现代码 参考做法字符串转换整数个人解法 分析总结 复习 Z字形变换 实现代码 这里使用了他的思想,但是没有用他的代码,虽然已经比上次简洁了,但是还是不够&…...
PPT设置为本框的默认格式以及固定文本框
调整文本框固定位置 双击文本框之后勾选如下三个位置 设置文本框为默认 在调整好文本框的基本性质后,设置为默认即可...
计算机基础(5)——进制与进制转换
💗计算机基础系列文章💗 👉🍀计算机基础(1)——计算机的发展史🍀👉🍀计算机基础(2)——冯诺依曼体系结构🍀👉ἴ…...
发现情绪背后的真实心理需求,选择适合你的情绪调节方式
一、教程描述 心态对人的生活质量以及身体健康等多方面,都会产生非常重要的影响,受到不良情绪的影响,人的心态也会发生一定的变化。对于处于不良情绪状态的人来讲,应该重视学会调整自己的情绪。在心理学上,人的每种情…...
代理记账公司的五大问题及其解决方案
代理记账公司是现代企业管理中不可或缺的一部分,它为企业的日常运营提供了专业、高效的服务,随着行业的发展和竞争的加剧,代理记账公司的面临的问题也日益突出,这些问题主要表现在以下几个方面: 业务流程不规范 许多代…...
TH方程学习 (7)
一、内容介绍 TH存在广泛应用,在下面案例中,将介绍几种相对运动模型,斜滑接近模型,本节学习斜滑接近制导方法能够对接近时间、接近方向以及自主接近过程的相对速度进行控制。施加脉冲时刻追踪器的位置连线可构成一条直线…...
2024最新python入门教程|python安装|pycharm安装
前言:在安装PyCharm之前,首先需要明确PyCharm是一款功能强大的Python集成开发环境(IDE),由JetBrains公司开发。PyCharm旨在通过提供智能代码补全、语法高亮、代码检查、快速导航和重构等丰富的编码辅助工具,…...
docker架构
docker架构 Docker daemon 是Docker最核心的后台进程,它负责响应来自Dockerclient的请求,然后将这此请求翻译成系统调用完成容器管理操作。该进程会在后台后启动一个APIServer,负责接收由 Dockerclient发送的请求;接收到的请求将通…...
使用Java进行网络采集:代理IP与参数传递详解
在Java编程语言中,参数传递机制是一个常见的讨论话题。理解这一点对于编写高效且无错误的Java代码至关重要。本文将探讨Java的参数传递机制,解析其究竟是“按引用传递”还是“按值传递”,并结合网络爬虫技术的实例,展示如何在实际…...
多功能光时域反射仪的工作原理
6426A-2101多功能光时域反射仪是新一代掌上型智能化光纤通信测量仪器,具有强大的功能和广泛的应用领域。它能够显示光纤及光缆的损耗分布曲线图,测量光纤及光缆的多种关键参数,包括长度、损耗、接续质量等,为光纤通信系统的工程施…...
网站建设费用包括/百度seo排名优化提高流量
CentOS上,除了os类的yum源,还需要配置几个常用的源:epel、ius。 有很多国内很多镜像站点都提供了各类仓库的镜像站点,个人感觉比较全的是阿里云http://mirrors.aliyun.com和清华大学开源镜像站点https://mirrors.tuna.tsinghua.ed…...
淘宝客网站建设公司/网络营销策划书的结构
这道题主要注意精度问题就行。还有就是二分的时候,leftmid1或者leftmid;都行。不过个人更喜欢mid1。View Code 1 #include<cstdio>2 #include<cstring>3 #include<cmath>4 #define eps 0.00000000015 using namespace std;6 double n…...
网站建设的/百度推广怎么做最好
开头 在找工作的过程中,对于 Redis 技术知识的掌握已经成为必须的技能。美团面试常常就会被问到Redis相关知识,而这次我就差点倒在了美团3面,面试官连问我以下几个Redis的问题,然后就卡壳了… redis了解吗?你说说怎么…...
微网站开发微网站建设/在线资源搜索引擎
#每天一点点# python while 里边用if break 查询1-100之间前20个偶数 嘚~~~ 先找1-100之间的偶数 代码如下: #while 循环 i 1 while i <100:if i%2 0: #除以2余0,即偶数print(i)i 1再看前20个偶数呢 i 1 num 0 while i <100:if i%2 0: #…...
深圳网站建设的客户在哪里/做一套二级域名网站怎么做
PHP1 1994年,一位名叫Rasmus lerdorf的兄台为了在网上展示自己的履历和网页流量的统计,用Perl开发了一套脚本,后来因与日俱增的需求无法得到满足,lerdorf便使用c语言进行了重写,重写后的程序支持数据库的访问ÿ…...
在线视频网站怎么做/有没有免费的crm系统软件
最近项目中需要用到文字转语音。 本来是想使用朗读女生成的声音文件放到项目资源中进行播放。 但是产品要求改成动态的。于是就用了Google为我们封装好的类TTS,即[TextToSpeech]:大家可以看下详细文档。 代码其实不多,但是写完之后测试就有…...