当前位置: 首页 > news >正文

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. 位数组相对越长(1/n),错误率 f 越低,这个和直观上理解一致。
  2. 位数组相对越长(1/n),hash函数需要的最佳数量也越多,影响计算效率。
  3. 当一个元素平均需要1个字节(8bit)的指纹空间时(1/n =8),错误率大约为0.02.
  4. 错误率为10%,一个元素需要的平均指纹空间为4.792个bit,大约为5 bit.
  5. 错误率为1%,一个元素需要的平均指纹空间为9.585个bit,大约为10 bit。
  6. 错误率为 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 引言 在开始之前&#xff0c;先思考一个常见的业务问题&#xff1a;如果负责开发维护一个大型的网站&#xff0c;有一天老板找产品经理要网站每个网页每天的UV数据&#xff0c;然后来开发这个统计模块&#xff0c;需要如何实现&#xff1f; 如果统计PV非常好办&…...

C++——从C语言快速入门

目录 一、数组 1、声明数组 2、初始化数组 3、访问数组元素 4、示例 5、注意事项 6、数组小练习 计算器支持加减乘除 数组找最大值 二、指针 三、字符串 string 类型 一、数组 在 C 中&#xff0c;数组是一种存储固定大小的相同类型元素的序列。数组的所有元素都存…...

thinkpad T440p ubuntu-slam软件安装记录

安装问题 1.ubuntu20.04安装后提示"x86/cpu:VMX(outside TXT) disabled by BIOS" 这是虚拟化被禁止了&#xff0c;到BIOS里去把Virtualization选项打开即可。 2.ACPI Error:Needed type[Reference],found [Integer] 等错误 link这篇博客中提到该问题&#xff0c;…...

本地电脑访问windows server系统服务器 并传输文件

1、 mstsc 命令打开远程桌面连接。 2、填入登入的用户密码&#xff0c;在本地资源中设置需要共享的盘。登入成功后就可以在服务器与本地电脑互传文件了。...

kubernetes负载均衡---MetalLB

https://github.com/metallb/metallb 参考 &#xff1a; https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q 自建的Kubernetes集群&#xff0c;默认情况下是不支持负载均衡的。当需要提供服务的外部访问时&#xff0c;可使用 Ingress、NodePort等方式。他们都存在一些问题 …...

Python面试宝典:Python中与设计模式相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)

Python面试宝典:1000加python面试题助你轻松捕获大厂Offer【第二部分:Python高级特性:第二十二章:代码设计和设计模式:第二节:设计模式】 第二十二章:代码设计和设计模式第二节:设计模式创建型模式结构型模式行为型模式python中与设计模式相关的面试笔试题面试题1面试题…...

以sqlilabs靶场为例,讲解SQL注入攻击原理【18-24关】

【less-18】 打开时&#xff0c;获取了自己的IP地址。&#xff0c;通过分析源码知道&#xff0c;会将用户的user-agent作为参数记录到数据库中。 提交的是信息有user-Agent、IP、uname信息。 此时可以借助Burp Suite 工具&#xff0c;修改user_agent&#xff0c;实现sql注入。…...

【已有项目版】uniapp项目发版pda -- Android Studio

必备资料清单&#xff1a; 构建完成的app项目 在HBuilderX开发的uniapp项目 .keystore文件 文章目录 1. 安装Android Studio&#xff1a;https://developer.android.google.cn/studio?hlzh-cn2. 安装Android 离线SDK&#xff1a;https://nativesupport.dcloud.net.cn/AppDocs…...

三维重建,谁才是顶流?

3DGS技术是近年来计算机视觉领域最具突破性的研究成果之一。它不仅在学术界引起了广泛关注&#xff0c;成为计算机视觉、SLAM等领域的研究热点&#xff0c;而且每天都有大量基于Gaussian Splatting的新研究问世。此外&#xff0c;3DGS技术在商业应用方面也取得了显著进展&#…...

s32k314【入门新手篇】-开发环境安装【ds32开发平台】

软件包下载 登录nxp官网下载&#xff1a;https://www.nxp.com/ 然后输入关键字&#xff1a;S32 查看 下载安装包 以上三步请先注册好并登录你的个人账号 下载完之后如下&#xff1a; 软件安装 eb安装并激活【试用版】 激活 2 安装ds 弹出什么就安装什么就好了。 …...

DiffBIR论文阅读笔记

这篇是董超老师通讯作者的一篇盲图像修复的论文&#xff0c;目前好像没看到发表在哪个会议期刊&#xff0c;应该是还在投&#xff0c;这个是arxiv版本&#xff0c;代码倒是开源了。本文所指的BIR并不是一个single模型对任何未知图像degradation都能处理&#xff0c;而是用同一个…...

基于STM32的位置速度环PID控制伺服电机转动位置及程序说明

PID控制原理 PID控制原理是一种广泛应用于工业自动化和其他领域的控制算法。PID控制器的名字来源于其三个主要组成部分&#xff1a;比例&#xff08;Proportional&#xff09;、积分&#xff08;Integral&#xff09;和微分&#xff08;Derivative&#xff09;。PID控制器实现…...

操作失败——后端

控制台观察&#xff0c;页面发送的保存菜品的请求 返回的response显示&#xff1a; ---------- 我开始查看明明感觉都挺正常&#xff0c;没啥错误&#xff0c;就是查不出来。结果后面电脑关机重启后&#xff0c;隔一天看&#xff0c;就突然可以了。我觉着可能是浏览器的缓存没…...

基于SSM的“学校访客登记系统”的设计与实现(源码+数据库+文档)

基于SSM的“学校访客登记系统”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 平台架构图 系统首页 校园公告信息界面 留言板管理界面 家庭来…...

linux配置IP、子网掩码、网关

linux虚拟机配置IP、子网掩码、网关 本方法适用于 Ubuntu 18.04 之后的版本。 例1&#xff1a; 配置信息&#xff1a; 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 为什么要进行世代垃圾回收&#xff1f;3.3 分代垃圾回收过程 在 C 和 C 中&#xff0c;许多对象要求程序员声明他们后为其…...

多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政线下预约等多场景应用支持H5+小程序+APP

多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政按摩线下预约等多场景应用支持H5小程序APP 软件架构 前端&#xff1a;Uniapp-vue2.0 后端&#xff1a;Thinkphp6 前后端分离 前端支持&#xff1a; H5小程序双端APP&#xff08;安卓苹果&#xff09; 安装教程 【商业…...

书生·浦语大模型全链路开源体系-笔记作业2

全部写成了shell脚本&#xff0c;可以一键执行。 笔记&#xff1a; 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插件包

在开源的世界里&#xff0c;npm&#xff08;Node Package Manager&#xff09;不仅是JavaScript生态中不可或缺的一部分&#xff0c;也是全球最大的软件注册表&#xff0c;它使得分享和复用代码变得异常简单。如果你有一个很棒的想法或者实用的功能想要封装成一个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字形变换 实现代码 这里使用了他的思想&#xff0c;但是没有用他的代码&#xff0c;虽然已经比上次简洁了&#xff0c;但是还是不够&…...

PPT设置为本框的默认格式以及固定文本框

调整文本框固定位置 双击文本框之后勾选如下三个位置 设置文本框为默认 在调整好文本框的基本性质后&#xff0c;设置为默认即可...

计算机基础(5)——进制与进制转换

&#x1f497;计算机基础系列文章&#x1f497; &#x1f449;&#x1f340;计算机基础&#xff08;1&#xff09;——计算机的发展史&#x1f340;&#x1f449;&#x1f340;计算机基础&#xff08;2&#xff09;——冯诺依曼体系结构&#x1f340;&#x1f449;&#x1f34…...

发现情绪背后的真实心理需求,选择适合你的情绪调节方式

一、教程描述 心态对人的生活质量以及身体健康等多方面&#xff0c;都会产生非常重要的影响&#xff0c;受到不良情绪的影响&#xff0c;人的心态也会发生一定的变化。对于处于不良情绪状态的人来讲&#xff0c;应该重视学会调整自己的情绪。在心理学上&#xff0c;人的每种情…...

代理记账公司的五大问题及其解决方案

代理记账公司是现代企业管理中不可或缺的一部分&#xff0c;它为企业的日常运营提供了专业、高效的服务&#xff0c;随着行业的发展和竞争的加剧&#xff0c;代理记账公司的面临的问题也日益突出&#xff0c;这些问题主要表现在以下几个方面&#xff1a; 业务流程不规范 许多代…...

TH方程学习 (7)

一、内容介绍 TH存在广泛应用&#xff0c;在下面案例中&#xff0c;将介绍几种相对运动模型&#xff0c;斜滑接近模型&#xff0c;本节学习斜滑接近制导方法能够对接近时间、接近方向以及自主接近过程的相对速度进行控制。施加脉冲时刻追踪器的位置连线可构成一条直线&#xf…...

2024最新python入门教程|python安装|pycharm安装

前言&#xff1a;在安装PyCharm之前&#xff0c;首先需要明确PyCharm是一款功能强大的Python集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。PyCharm旨在通过提供智能代码补全、语法高亮、代码检查、快速导航和重构等丰富的编码辅助工具&#xff0c…...

docker架构

docker架构 Docker daemon 是Docker最核心的后台进程&#xff0c;它负责响应来自Dockerclient的请求&#xff0c;然后将这此请求翻译成系统调用完成容器管理操作。该进程会在后台后启动一个APIServer&#xff0c;负责接收由 Dockerclient发送的请求&#xff1b;接收到的请求将通…...

使用Java进行网络采集:代理IP与参数传递详解

在Java编程语言中&#xff0c;参数传递机制是一个常见的讨论话题。理解这一点对于编写高效且无错误的Java代码至关重要。本文将探讨Java的参数传递机制&#xff0c;解析其究竟是“按引用传递”还是“按值传递”&#xff0c;并结合网络爬虫技术的实例&#xff0c;展示如何在实际…...

多功能光时域反射仪的工作原理

6426A-2101多功能光时域反射仪是新一代掌上型智能化光纤通信测量仪器&#xff0c;具有强大的功能和广泛的应用领域。它能够显示光纤及光缆的损耗分布曲线图&#xff0c;测量光纤及光缆的多种关键参数&#xff0c;包括长度、损耗、接续质量等&#xff0c;为光纤通信系统的工程施…...

网站建设费用包括/百度seo排名优化提高流量

CentOS上&#xff0c;除了os类的yum源&#xff0c;还需要配置几个常用的源&#xff1a;epel、ius。 有很多国内很多镜像站点都提供了各类仓库的镜像站点&#xff0c;个人感觉比较全的是阿里云http://mirrors.aliyun.com和清华大学开源镜像站点https://mirrors.tuna.tsinghua.ed…...

淘宝客网站建设公司/网络营销策划书的结构

这道题主要注意精度问题就行。还有就是二分的时候&#xff0c;leftmid1或者leftmid&#xff1b;都行。不过个人更喜欢mid1。View Code 1 #include<cstdio>2 #include<cstring>3 #include<cmath>4 #define eps 0.00000000015 using namespace std;6 double n…...

网站建设的/百度推广怎么做最好

开头 在找工作的过程中&#xff0c;对于 Redis 技术知识的掌握已经成为必须的技能。美团面试常常就会被问到Redis相关知识&#xff0c;而这次我就差点倒在了美团3面&#xff0c;面试官连问我以下几个Redis的问题&#xff0c;然后就卡壳了… redis了解吗&#xff1f;你说说怎么…...

微网站开发微网站建设/在线资源搜索引擎

#每天一点点# python while 里边用if break 查询1-100之间前20个偶数 嘚~~~ 先找1-100之间的偶数 代码如下&#xff1a; #while 循环 i 1 while i <100:if i%2 0: #除以2余0&#xff0c;即偶数print(i)i 1再看前20个偶数呢 i 1 num 0 while i <100:if i%2 0: #…...

深圳网站建设的客户在哪里/做一套二级域名网站怎么做

PHP1 1994年&#xff0c;一位名叫Rasmus lerdorf的兄台为了在网上展示自己的履历和网页流量的统计&#xff0c;用Perl开发了一套脚本&#xff0c;后来因与日俱增的需求无法得到满足&#xff0c;lerdorf便使用c语言进行了重写&#xff0c;重写后的程序支持数据库的访问&#xff…...

在线视频网站怎么做/有没有免费的crm系统软件

最近项目中需要用到文字转语音。 本来是想使用朗读女生成的声音文件放到项目资源中进行播放。 但是产品要求改成动态的。于是就用了Google为我们封装好的类TTS&#xff0c;即[TextToSpeech]&#xff1a;大家可以看下详细文档。 代码其实不多&#xff0c;但是写完之后测试就有…...