为什么要使用布隆过滤器?

布隆过滤器(bloomfilter)有两大作用,一是为了防止缓存穿透,二是为了在百万级数据里快速高效的去重

什么是布隆过滤器?

1,布隆过滤器是用来判断一个元素是否出现在给定集合中的重要工具,具有快速,比哈希表更节省空间等优点,而缺点在于有一定的误识别率(false-positive,假阳性),亦即,它可能会把不是集合内的元素判定为存在于集合内,不过这样的概率相当小,在大部分的生产环境中是可以接受的;
2,其原理比较简单,假设S集合中有n个元素,利用k个哈希函数,将S中的每个元素映射到一个长度为m的位(bit)数组B中不同的位置上,这些位置上的二进制数均置为1,如果待检测的元素经过这k个哈希函数的映射后,发现其k个位置上的二进制数不全是1那么这个元素一定不在集合S中,反之,该元素可能是S中的某一个元素;
3,综上描述,那么到底需要多少个哈希函数,以及创建长度为多少的bit数组比较合适,为了估算出k和m的值,在构造一个布隆过滤器时,需要传入两个参数,即可以接受的误判率fpp和元素总个数n(不一定完全精确);
4,哈希函数的要求尽量满足平均分布,这样既降低误判发生的概率,又可以充分利用bit数组的空间;

google guava的布隆过滤器

Guava中,布隆过滤器的实现主要涉及到2个类,BloomFilter和BloomFilterStrategies,首先来看一下BloomFilter:

 /** The bit set of the BloomFilter (not necessarily power of 2!) */private final BitArray bits;/** Number of hashes per element */private final int numHashFunctions;/** The funnel to translate Ts to bytes */private final Funnel<? super T> funnel;/*** The strategy we employ to map an element T to {@code numHashFunctions} bit indexes.*/private final Strategy strategy;

这是它的4个成员变量:

1,BitArrays是定义在BloomFilterStrategies中的内部类,封装了布隆过滤器底层bit数组的操作,后文详述;
2,numHashFunctions表示哈希函数的个数,即上文提到的k;
3,Funnel,这是Guava中定义的一个接口,它和PrimitiveSink配套使用,主要是把任意类型的数据转化成Java基本数据类型(primitive value,如char,byte,int……),默认用java.nio.ByteBuffer实现,最终均转化为byte数组;
4,Strategy是定义在BloomFilter类内部的接口,代码如下,有3个方法,put(插入元素),mightContain(判定元素是否存在)和ordinal方法(可以理解为枚举类中那个默认方法)

interface Strategy extends java.io.Serializable {/*** Sets {@code numHashFunctions} bits of the given bit array, by hashing a user element.** <p>Returns whether any bits changed as a result of this operation.*/<T> boolean put(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits);/*** Queries {@code numHashFunctions} bits of the given bit array, by hashing a user element;* returns {@code true} if and only if all selected bits are set.*/<T> boolean mightContain(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits);/*** Identifier used to encode this strategy, when marshalled as part of a BloomFilter. Only* values in the [-128, 127] range are valid for the compact serial form. Non-negative values* are reserved for enums defined in BloomFilterStrategies; negative values are reserved for any* custom, stateful strategy we may define (e.g. any kind of strategy that would depend on user* input).*/int ordinal();}

对于创建布隆过滤器,BloomFilter并没有公有的构造函数,只有一个私有构造函数,而对外它提供了5个重载的create方法,在缺省情况下误判率设定为3%,采用BloomFilterStrategies.MURMUR128_MITZ_64的实现。其中4个create方法最终都调用了同一个create方法,由它来负责调用私有构造函数,其源码如下:

static <T> BloomFilter<T> create(Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {checkNotNull(funnel);checkArgument(expectedInsertions >= 0, "Expected insertions (%s) must be >= 0", expectedInsertions);checkArgument(fpp > 0.0, "False positive probability (%s) must be > 0.0", fpp);checkArgument(fpp < 1.0, "False positive probability (%s) must be < 1.0", fpp);checkNotNull(strategy);if (expectedInsertions == 0) {expectedInsertions = 1;}/** TODO(user): Put a warning in the javadoc about tiny fpp values, since the resulting size* is proportional to -log(p), but there is not much of a point after all, e.g.* optimalM(1000, 0.0000000000000001) = 76680 which is less than 10kb. Who cares!*/long numBits = optimalNumOfBits(expectedInsertions, fpp);int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);try {return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, strategy);} catch (IllegalArgumentException e) {throw new IllegalArgumentException("Could not create BloomFilter of " + numBits + " bits", e);}}

在create中接受了4个参数,funnel(输入的数据),expectedInsertions(预计插入的元素总数),fpp(期望误判率),strategy(实现Strategy的实例),然后它计算了bit数组的长度以及哈希函数的个数(公式参考前文),最后用numBits创建了BitArray,并调用了构造函数完成赋值操作

static long optimalNumOfBits(long n, double p) {if (p == 0) {p = Double.MIN_VALUE;}return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));}static int optimalNumOfHashFunctions(long n, long m) {// (m / n) * log(2), but avoid truncation due to division!return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));}

接着再来看一下BloomFilterStrategies类,首先它是实现了BloomFilter.Strategy 接口的一个枚举类,其次它有两个2枚举值,MURMUR128_MITZ_32和MURMUR128_MITZ_64,分别对应了32位哈希映射函数,和64位哈希映射函数,后者使用了murmur3 hash生成的所有128位,具有更大的空间,不过原理是相通的,我们选择默认的MURMUR128_MITZ_64来分析:

MURMUR128_MITZ_64() {@Overridepublic <T> boolean put(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits) {long bitSize = bits.bitSize();byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal();long hash1 = lowerEight(bytes);long hash2 = upperEight(bytes);boolean bitsChanged = false;long combinedHash = hash1;for (int i = 0; i < numHashFunctions; i++) {// Make the combined hash positive and indexablebitsChanged |= bits.set((combinedHash & Long.MAX_VALUE) % bitSize);combinedHash += hash2;}return bitsChanged;}@Overridepublic <T> boolean mightContain(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits) {long bitSize = bits.bitSize();byte[] bytes = Hashing.murmur3_128().hashObject(object, funnel).getBytesInternal();long hash1 = lowerEight(bytes);long hash2 = upperEight(bytes);long combinedHash = hash1;for (int i = 0; i < numHashFunctions; i++) {// Make the combined hash positive and indexableif (!bits.get((combinedHash & Long.MAX_VALUE) % bitSize)) {return false;}combinedHash += hash2;}return true;}

抽象来看,put是写,mightContain是读,两个方法的代码有一点相似,都是先利用murmur3 hash对输入的funnel计算得到128位的字节数组,然后高低分别取8个字节(64位)创建2个long型整数hash1,hash2作为哈希值。循环体内采用了2个函数模拟其他函数的思想,即上文提到的gi(x) = h1(x) + ih2(x) ,这相当于每次累加hash2,然后通过基于bitSize取模的方式在bit数组中索引。

这里之所以要和Long.MAX_VALUE进行按位与的操作,是因为在除数和被除数符号不一致的情况下计算所得的结果是有差别的,在程序语言里,“%”准确来说是取余运算(C,C++和Java均如此,python是取模),如-5%3=-2,而取模的数学定义是x
mod y=x-y[x/y](向下取整),所以-5 mod 3=
-5-3*(-2)=1,因此当哈希值为负数的时候,其取余的结果为负(bitSize始终为正数),这样就不方便在bit数组中取值,因此通过Long.MAX_VALUE(二进制为0111…1111),直接将开头的符号位去掉,从而转变为正数。当然也可以取绝对值,在另一个MURMUR128_MITZ_32的实现中就是这么做的。

在put方法中,先是将索引位置上的二进制置为1,然后用bitsChanged记录插入结果,如果返回true表明没有重复插入成功,而mightContain方法则是将索引位置上的数值取出,并判断是否为0,只要其中出现一个0,那么立即判断为不存在。

 static final class BitArray {final long[] data;long bitCount;BitArray(long bits) {this(new long[Ints.checkedCast(LongMath.divide(bits, 64, RoundingMode.CEILING))]);}// Used by serializationBitArray(long[] data) {checkArgument(data.length > 0, "data length is zero!");this.data = data;long bitCount = 0;for (long value : data) {bitCount += Long.bitCount(value);}this.bitCount = bitCount;}/** Returns true if the bit changed value. */boolean set(long index) {if (!get(index)) {data[(int) (index >>> 6)] |= (1L << index);bitCount++;return true;}return false;}boolean get(long index) {return (data[(int) (index >>> 6)] & (1L << index)) != 0;}/** Number of bits */long bitSize() {return (long) data.length * Long.SIZE;}
...
}

之前也提到了Guava没有使用java.util.BitSet,而是封装了一个long型的数组,另外还有一个long型整数,用来统计数组中已经占用(置为1)的数量,在第一个构造函数中,它把传入的long型整数按长度64分段(例如129分为3段),段数作为数组的长度,你可以想象成由若干个64位数组拼接成一个超长的数组,它的长度就是64乘以段数,即bitSize,在第二个构造函数中利用Long.bitCount方法来统计对应二进制编码中的1个数,这个方法在JDK1.5中就有了,其算法设计得非常精妙,有精力的同学可以自行研究。

另外两个重要的方法是set和get,在get方法中,参考put和mightContain方法,传入的参数index是经过bitSize取模的,因此一定能落在这个超长数组的范围之内,为了获取index对应索引位置上的值,首先将其无符号右移6位,并且强制转换成int型,这相当于除以64向下取整的操作,也就是换算成段数,得到该段上的数值之后,又将1左移index位,最后进行按位与的操作,如果结果等于0,那么返回false,从而在mightContain中判断为不存在。在set方法中,首先调用了get方法判断是否已经存在,如果不存在,则用同样的逻辑取出data数组中对应索引位置的数值,然后按位或并赋值回去。

到这里,对Guava中布隆过滤器的实现就基本讨论完了,简单总结一下:

1,BloomFilter类的作用在于接收输入,利用公式完成对参数的估算,最后初始化Strategy接口的实例;
2,BloomFilterStrategies是一个枚举类,具有两个实现了Strategy接口的成员,分别为MURMUR128_MITZ_32和MURMUR128_MITZ_64,另外封装了long型的数组作为布隆过滤器底层的bit数组,其中在get和set方法中完成核心的位运算。

使用Redis整合BloomFilter

前面说的BloomFilter算法是单机的,可以使用JDK自带的BitSet来实现。但是拥有大数据量的系统绝不是一台服务器,所以需要多台服务器共享。结合Redis的BitMap就能够完美的实现这一需求。利用redis的高性能以及通过pipeline将多条bit操作命令批量提交,实现了多机BloomFilter的bit数据共享。唯一需要注意的是redis的bitmap只支持232大小,对应到内存也就是512MB,数组的下标最大只能是232-1。不过这个限制我们可以通过构建多个redis的bitmap通过hash取模的方式分散一下即可。万分之一的误判率,512MB可以放下2亿条数据。
直接上代码:

BloomFilterHelper
import com.google.common.base.Preconditions;
import com.google.common.hash.Funnel;
import com.google.common.hash.Hashing;/*** @author shihaowei* @date 2020/8/7 3:33 下午*/
public class BloomFilterHelper<T> {private int numHashFunctions;private int bitSize;private Funnel<T> funnel;public BloomFilterHelper(Funnel<T> funnel, int expectedInsertions, double fpp) {Preconditions.checkArgument(funnel != null, "funnel不能为空");this.funnel = funnel;bitSize = optimalNumOfBits(expectedInsertions, fpp);numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, bitSize);}public int[] murmurHashOffset(T value) {int[] offset = new int[numHashFunctions];long hash64 = Hashing.murmur3_128().hashObject(value, funnel).asLong();int hash1 = (int) hash64;int hash2 = (int) (hash64 >>> 32);for (int i = 1; i <= numHashFunctions; i++) {int nextHash = hash1 + i * hash2;if (nextHash < 0) {nextHash = ~nextHash;}offset[i - 1] = nextHash % bitSize;}return offset;}/*** 计算bit数组的长度*/private int optimalNumOfBits(long n, double p) {if (p == 0) {p = Double.MIN_VALUE;}return (int) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));}/*** 计算hash方法执行次数*/private int optimalNumOfHashFunctions(long n, long m) {return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));}
}
BloomFilterCache
/*** @author shihaowei* @date 2020/8/7 3:41 下午*/
@Component
public class BloomFilterCache {private static final Logger LOG = LoggerFactory.getLogger(BloomFilterCache.class);private static final Integer PIPLINE_LIST_LEN = 1000;@Resource(name = "jedisTemplate")private JedisTemplate jedisTemplate;/*** 根据给定的布隆过滤器添加值** @param bloomFilterHelper* @param key* @param value* @param <T>*/public <T> void addByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, T value) {if (value == null) {return;}Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");int[] offset = bloomFilterHelper.murmurHashOffset(value);for (int i : offset) {jedisTemplate.execute(s -> {s.setbit(key, i, true);});}}/*** 根据给定的布隆过滤器批量添加值** @param bloomFilterHelper* @param key* @param values* @param <T>*/public <T> void addByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, List<T> values) {if (values.size() < 1) {return;}Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");List<List<T>> subList = getSubList(values, PIPLINE_LIST_LEN);jedisTemplate.execute(jedis -> {subList.stream().forEach(s -> {// 通过管道异步添加数据Pipeline p = jedis.pipelined();s.stream().forEach(h -> {int[] offset = bloomFilterHelper.murmurHashOffset(h);for (int i : offset) {p.setbit(key, i, true);}});p.sync();});});}/*** 根据给定的布隆过滤器判断值是否存在*/public <T> boolean includeByBloomFilter(BloomFilterHelper<T> bloomFilterHelper, String key, T value) {Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");int[] offset = bloomFilterHelper.murmurHashOffset(value);for (int i : offset) {boolean flag = jedisTemplate.execute(s -> {return s.getbit(key, i);});if (!flag) {return false;}}return true;}/*** 删除过滤key** @param key*/public void removeByBloomFilter(String key) {jedisTemplate.key().del(key);}/*** 拆分list队列** @param list* @param len* @param <T>* @return*/private <T> List<List<T>> getSubList(List<T> list, Integer len) {if (list == null || list.size() == 0 || len < 1) {return null;}List<List<T>> resultList = new ArrayList<>();for (int i = 0; i < list.size(); i++) {if (i % len == 0) {int count = i / len;List<T> subList = list.stream().limit((count + 1) * len).skip(count * len).collect(Collectors.toList());resultList.add(subList);}}return resultList;}
}
测试
@Test(priority = 10, testName = "测试布隆过滤器")public void testBloomFilterCache(){BloomFilterHelper<String> bloomFilterHelper = new BloomFilterHelper((Funnel<String>)(from,into) ->into.putString(from, Charsets.UTF_8),150000,0.00001);bloomFilterCache.addByBloomFilter(bloomFilterHelper,"app_bloomfilter_key","aaaaa");boolean a = bloomFilterCache.includeByBloomFilter(bloomFilterHelper, "app_bloomfilter_key", "aaaaa");System.out.println("aaaaa ======>"+a);boolean b = bloomFilterCache.includeByBloomFilter(bloomFilterHelper, "app_bloomfilter_key", "bbbbb");System.out.println("bbbbb ======>"+b);}
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 超简单详细的网页部署到云服务器上方法

    1.先登录阿里云网站注册账号,选择服务器类型(我用的是 云服务器ECS), 如果你还是在读大学生可享受优惠价,最低好像是9.9元一月。之后勾选系统镜像。 PS:阿里云可以通过学生验证免费领取阿里云服务器半年,想要知道具体的操作方式可以联系qq:599808461或评论留言。2. 购买好之…...

    2024/4/28 5:11:23
  2. 热烈庆祝星系社区首届分布式存储产业峰会圆满落幕

    一起来回顾精彩会议过程。 2020年8月8日由星系社区主办的,首届区块链存储生态峰会,在上海举行,会议现场汇集了区块链存储行业精英、知名投资机构、区块链存储行业顶级技术团队以及众多区块链爱好者,大家汇聚一堂,共襄盛举,共同讨论区块链存储生态的现状及未来趋势,携手推…...

    2024/4/25 12:37:37
  3. JQ+CSS实现老虎机抽奖效果

    date: 2020-08-07 categoery: [技术,前端,JavaScript] toc: true 介绍 现在不少app都会有一些抽奖活动,热门的抽奖当属九宫格循环抽奖,而还有一种抽奖形式也是比较常见,比如老虎机的形式 预期效果那么我们就用JQ和CSS实现一下这个效果。简单的实现思路 其实这个效果和实现一…...

    2024/4/28 3:11:25
  4. 怕入错行?这群技术人写了本“择业指南”

    计算机专业好找工作吗?哪些方向是当前的主流和热门方向呢?计算机专业的你是不是还在为职业发展纠结犹豫呢?刚经历完高考选专业的你是不是还在迷茫徘徊呢?那么福利来啦!《软件技术职业选择之道》重磅来袭!本书集结七位蚂蚁一线的技术专家和管理者,谈谈他们本方向的技术发…...

    2024/4/28 10:41:08
  5. 基于ubuntu18.04虚拟机(VMware)的dvwa环境搭建

    DVWA环境搭建_基于ubuntu18.04虚拟机虚拟环境1.基于ubuntu18.04虚拟机(VMware)的dvwa环境搭建:1.基于ubuntu18.04虚拟机(VMware)的dvwa环境搭建: (1)为了方便起见,使用lamp(linux+apache+mysql+php)集成平台,下载xampp-linux-x64-7.3.10-0-installer.具体下载链接为链…...

    2024/4/28 3:42:38
  6. 最具创新价值人工智能产品 Imagination PowerVR NNA再获殊荣

    人工智能(AI)正在赋能百业,推动各行各业迈入智能时代。为进一步洞悉AI技术走向和产业落地趋势,推进AI产业的升级和可持续发展,电子发烧友网于7月10日以在线形式举办了第三届人工智能高峰论坛。本届论坛以“洞见AI,智变未来”为主题,邀请了专家、学者、企业代表、投资机构…...

    2024/4/14 3:39:12
  7. 推荐一些好用的学习网站,大家千万不要错过哦

    程序员学习网站 牛客网 https://www.nowcoder.com/ 牛客网,是一个集笔面试系统、题库、课程教育、社群交流、招聘内推于一体的招聘类网站。如果是程序员,千万不要错过。GitHub:https://github.com/ GitHub是最大的开源代码托管平台,上面有全球各地在上面托管的项目,好多网…...

    2024/4/27 12:59:18
  8. 无线通信频率分配表!(非常全面,请收藏)

    1、 5G NR 3GPP已指定5G NR 支持的频段列表,5G NR频谱范围可达100GHz,指定了两大频率范围:①Frequency range 1 (FR1):就是我们通常讲的6GHz以下频段•频率范围:450MHz - 6.0GHz•最大信道带宽100MHz②Frequency range 2 (FR2):就是毫米波频段•频率范围:24.25GHz…...

    2024/4/23 8:37:45
  9. django中异步化celery的使用

    ~网站优化第一定律:缓存 (空间换时间) -热数据(热点数据):体量不大、访问频率极高、更新不频繁 ~网站优化第二定律:削峰 (能不马上做的事情都不要马上做)、消息队列 -遇到耗时间的任务(用户请求),用户不需要马上得到结果、异步化、推迟执行 -多线程 -异步消息队列 -celery #…...

    2024/4/25 3:09:22
  10. 即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况

    前言随着移动互联网的快速发展以及智能终端性能的逐步提高,智能终端间进行实时音视频通讯成为移动互联网发展的一个重要方向。那么如何保证智能终端之间实时音视频数据通讯成为一个很现实的问题。 实际上,实时音视频通讯 = 音视频处理 + 网络传输。包括采集、编码、网络传输、…...

    2024/4/1 14:23:50
  11. CRO的作用,现状,发展和名录

    随着跨国制药企业向低成用本市场转移医药研发外包业务,中国因为丰富的临床受试群体、庞大的医疗卫生人才库、逐步增加的符合国际标准的多中心临床试验基地、以及政府的政策支持,作为一个新兴市场赢得越来越多的机会。由专业的人做专业的事,联合各专业的临床研究组织,整合各…...

    2024/3/31 17:27:54
  12. 大数据技术之Flume知识点

    定义Flume是一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume基于流式架构,灵活简单。 支持在日志系统中定制各类数据发送方(服务器本地磁盘文件夹、网络端口数据),用于收集数据 同时,Flume提供对数据进行简单处理,并写到各种数据接受方(HDFS、K…...

    2024/4/25 6:34:21
  13. 八个常用的网络命令ping、nbtstat、tracert、Telnet等详细方法介绍,弄懂瞬间成大神

    一,ping它是用来检查网络是否通畅或者网络连接速度的命令。它所利用的原理是这样的:网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等…...

    2024/4/14 17:44:01
  14. 不懂复盘,再努力也是白忙一场

    有这样一类人:他们做事不讲方法,别人半小时搞定的事情,他用半天都没搞定。他们在同样的坑里反复跌倒,新的错误不停,旧的也不见改。但你要说他们根本没努力,他们一定很委屈。那这是为什么呢?因为他们不懂复盘,不知道把事情想明白,谋定而后动,才能事半功倍。作者:邱昭…...

    2024/4/24 7:44:52
  15. 2020 VMware ESXi6.7/7.0 安装及基本设置

    VMware ESXi 的安装:在物理服务器、pc安装ESXI6.7或者71.VMware ESXi 的安装:在物理服务器、pc安装ESXI6.7或者72.VMware ESXi 控制台3.使用vSphere Aost Client管理ESXi6.7 :创建虚拟机、修改虚拟机配置、在虚拟机中安装操作系统、应用程序;为虚拟机添加内存、CPU、网卡、硬…...

    2024/4/20 15:49:02
  16. C8051编译调试工具的安装

    原文地址:https://blog.csdn.net/sygdp21/article/details/317928891、首先安装keil编译器c51v951.exe,如安装目录为:d:\keil2、然后安装调试器驱动SiC8051F_uVision.exe,注意此文件的安装目录必须与keil的安装目录一致(如本例中的d:\keil)。3、打开任意一个keil工程,点…...

    2024/4/1 18:06:57
  17. 初识 Spring

    1.1 简介 1.1.1 什么是框架软件框架(software framework),通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。框架的功能类似于基础设施,与具体的软件应用无关,但是提供并实现最为基础…...

    2024/4/19 4:44:45
  18. NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE翻译

    摘要 神经机器翻译是一种最近被提出的用于进行机器翻译的方法。不像传统的统计机器翻译,神经机器翻译的目的是构建可以联合调整以最大化翻译性能的单个神经网络。最近提出的用于神经机器翻译的模型通常属于编码器-解码器类型,该类型将源句子编码为固定长度的向量,解码器根据…...

    2024/4/17 4:34:23
  19. 强化学习中Q-learning和SARSA的区别,以及与马尔可夫决策过程,贝尔曼方程之间的关系

    首先,Q-learning与SARSA的最大不同就是更新Q表的方式不同。具体地,表现如下: 1)首先理解什么是Q表? Q表是指构建一个表格,行:某时刻的状态s(state),列:该时刻该状态下可能采取的所有动作a(action),Q(s,a)的值是该状态下,采取该动作能够获得收益的期望,并通过…...

    2024/4/14 7:45:47
  20. centos7 安装 mysql5.6

    启动mysql报错mysqld_safe error: log-error set to /var/log/mariadb/mariadb.log因为没有路径也没有权限,所以创建此路径并授权给mysql用户mkdir /var/log/mariadb touch /var/log/mariadb/mariadb.log # 用户组及用户 chown -R mysql:mysql /var/log/mariadb/ /usr/local/m…...

    2024/4/4 21:23:49

最新文章

  1. MogDB如何兼容Oracle的管道函数

    在之前很多数据库国产化改造项目中&#xff0c;我们遇到了很多难题&#xff0c;其中一个难点在于重度使用Oracle的一些用户使用了大量的管道函数&#xff08;pipeline&#xff09;。在之前的版本中&#xff0c;由于MogDB还不支持pipeline&#xff0c;因此给我们造成了不小的麻烦…...

    2024/4/28 16:20:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. yolov9直接调用zed相机实现三维测距(python)

    yolov9直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 相关代码2.1 相机设置2.2 测距模块2.2 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1. yolov4直接调用zed相机实现三维测…...

    2024/4/28 3:06:36
  4. springboot 项目整合easy-captcha验证码功能

    效果 1、验证码使用easy-captcha,在pom文件增加依赖 <!-- google 验证码 --><dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId></dependency> 2、增加获取kaptcha的ctrl package com.*.*.s…...

    2024/4/24 13:16:37
  5. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/4/28 4:04:40
  6. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/4/28 12:01:04
  7. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/4/27 12:24:35
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/4/27 12:24:46
  9. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/28 12:01:03
  10. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/4/28 12:01:03
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/4/28 12:01:03
  12. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/4/28 16:07:14
  13. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/4/27 21:08:20
  14. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/4/28 9:00:42
  15. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/27 18:40:35
  16. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/4/28 4:14:21
  17. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/4/27 13:52:15
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/4/27 13:38:13
  19. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/4/28 12:00:58
  20. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/4/28 12:00:58
  21. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/4/27 22:51:49
  22. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/4/28 7:31:46
  23. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/4/28 8:32:05
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/4/27 20:28:35
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57