火影专场:Redis分布式锁实战 我们学习 Java 都知道锁的概念,例如基于 JVM 实现的同步锁 synchronized,以及 jdk 提供的一套代码级别的锁机制 lock,我们在并发编程中会经常用这两种锁去保证代码在多线程环境下运行的正确性。但是这些锁机制在分布式场景下是不适用的,原因是在分布式业务场景下,我们的代码都是跑在不同的JVM甚至是不同的机器上,synchronized 和 lock 只能在同一个 JVM 环境下起作用。所以这时候就需要用到分布式锁了。

 

例如,现在有个场景就是整点抢消费券(疫情的原因,支付宝最近在8点、12点整点开放抢消费券),消费券有一个固定的量,先到先得,抢完就没了,线上的服务都是部署多个的,大致架构如下:

 

 

 所以这个时候我们就得用分布式锁来保证共享资源的访问的正确性。

为什么要用分布式锁嗯?

假设不使用分布式锁,我们看看 synchronized 能不能保证?其实是不能的,我们来演示一下。

下面我写了一个简单的 springboot 项目来模拟这个抢消费券的场景,代码很简单,大致意思是先从 Redis 获取剩余消费券数,然后判断大于0,则减一模拟被某个用户抢到一个,然后减一后再修改 Redis 的剩余消费券数量,打印扣减成功,剩余还有多少,否则扣减失败,就没抢到。整块代码被 synchronized 包裹,Redis 设置的库存数量为50。

复制代码

//假设库存编号是00001
private String key = "stock:00001";
@Autowired
private StringRedisTemplate stringRedisTemplate;
/*** 扣减库存 synchronized同步锁
*/
@RequestMapping("/deductStock")
public String deductStock(){synchronized (this){//获取当前库存int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get(key));if(stock>0){int afterStock = stock-1;stringRedisTemplate.opsForValue().set(key,afterStock+"");//修改库存System.out.println("扣减库存成功,剩余库存"+afterStock);}else {System.out.println("扣减库存失败");}}return "ok";
}

复制代码

然后启动两个springboot项目,端口分别为8080,8081,然后在nginx里配置负载均衡

复制代码

upstream redislock{server 127.0.0.1:8080;server 127.0.0.1:8081;
}
server {listen       80;server_name  127.0.0.1;location / {root   html;index  index.html index.htm;proxy_pass http://redislock;}
}

复制代码

 然后用jmeter压测工具进行测试

 

  

 

然后我们看一下控制台输出,可以看到我们运行的两个web实例,很多同样的消费券被不同的线程抢到,证明synchronized在这样的情况下是不起作用的,所以就需要使用分布式锁来保证资源的正确性。

 

如何用Redis实现分布式锁?

在实现分布式锁之前,我们先考虑如何实现,以及都要实现锁的哪些功能。

1、分布式特性(部署在多个机器上的实例都能够访问这把锁)

2、排他性(同一时间只能有一个线程持有锁)

3、超时自动释放的特性(持有锁的线程需要给定一定的持有锁的最大时间,防止线程死掉无法释放锁而造成死锁)

4、...

 

基于以上列出的分布式锁需要拥有的基本特性,我们思考一下使用Redis该如何实现?

1、第一个分布式的特性Redis已经支持,多个实例连同一个Redis即可

2、第二个排他性,也就是要实现一个独占锁,可以使用Redis的setnx命令实现

3、第三个超时自动释放特性,Redis可以针对某个key设置过期时间

4、执行完毕释放分布式锁

 

科普时间

Redis Setnx 命令

Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值

语法

redis Setnx 命令基本语法如下:

redis 127.0.0.1:6379> SETNX KEY_NAME VALUE

可用版本:>= 1.0.0

返回值:设置成功,返回1, 设置失败,返回0

 

复制代码

@RequestMapping("/stock_redis_lock")
public String stock_redis_lock(){//底层使用setnx命令Boolean aTrue = stringRedisTemplate.opsForValue().setIfAbsent(lock_key, "true");stringRedisTemplate.expire(lock_key,10, TimeUnit.SECONDS);//设置过期时间10秒if (!aTrue) {//设置失败则表示没有拿到分布式锁return "error";//这里可以给用户一个友好的提示}//获取当前库存int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get(key));if(stock>0){int afterStock = stock-1;stringRedisTemplate.opsForValue().set(key,afterStock+"");System.out.println("扣减库存成功,剩余库存"+afterStock);}else {System.out.println("扣减库存失败");}stringRedisTemplate.delete(lock_key);//执行完毕释放分布式锁return "ok";
}

复制代码

仍然设置库存数量为50,我们再用jmeter测试一下,把jmeter的测试地址改为127.0.0.1/stock_redis_lock,同样的设置再来测一次。

 

测试了5次没有出现脏数据,把发送时间改为0,测了5次也没问题,然后又把线程数改为600,时间为0 ,循环4次,测了几次也是正常的。

上面实现分布式锁的代码已经是一个较为成熟的分布式锁的实现了,对大多数软件公司来说都已经满足需求了。但是上面代码还是有优化的空间,例如:

1)上面的代码我们是没有考虑异常情况的,实际情况下代码没有这么简单,可能还会有别的很多复杂的操作,都有可能会出现异常,所以我们释放锁的代码需要放在finally块里来保证即使是代码抛异常了释放锁的代码他依然会被执行。

2)还有,你有没有注意到,上面我们的分布式锁的代码的获取和设置过期时间的代码是两步操作第4行和第5行,即非原子操作,就有可能刚执行了第4行还没来得及执行第5行这台机器挂了,那么这个锁就没有设置超时时间,其他线程就一直无法获取,除非人工干预,所以这是一步优化的地方,Redis也提供了原子操作,那就是SET key value EX seconds  NX

科普时间

SET key value [EX seconds] [PX milliseconds] [NX|XX]  将字符串值 value 关联到 key

可选参数

从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改:

  • EX second :设置键的过期时间为 second 秒。SET key value EX second 效果等同于 SETEX key second value

  • PX millisecond :设置键的过期时间为 millisecond 毫秒。SET key value PX millisecond 效果等同于 PSETEX key millisecond value

  • NX :只在键不存在时,才对键进行设置操作。SET key value NX 效果等同于 SETNX key value

  • XX :只在键已经存在时,才对键进行设置操作

SpringBoot的StringRedisTemplate也有对应的方法实现,如下代码: 

复制代码

//假设库存编号是00001
private String key = "stock:00001";
private String lock_key = "lock_key:00001";
@Autowired
private StringRedisTemplate stringRedisTemplate;
@RequestMapping("/stock_redis_lock")
public String stock_redis_lock() {String uuid = UUID.randomUUID().toString();try {//原子的设置key及超时时间Boolean aTrue = stringRedisTemplate.opsForValue().setIfAbsent(lock_key, "true", 30, TimeUnit.SECONDS);if (!aTrue) {return "error";}int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get(key));if (stock > 0) {int afterStock = stock - 1;stringRedisTemplate.opsForValue().set(key, afterStock + "");System.out.println("扣减库存成功,剩余库存" + afterStock);} else {System.out.println("扣减库存失败");}} catch (NumberFormatException e) {e.printStackTrace();} finally {//避免死锁if (uuid.equals(stringRedisTemplate.opsForValue().get(lock_key))) {stringRedisTemplate.delete(lock_key);}}return "ok";
}

复制代码

这样实现是否就完美了呢?嗯,对于并发量要求不高或者非大并发的场景的话这样实现已经可以了。但是对于抢购 ,秒杀这样的场景,当流量很大,这时候服务器网卡、磁盘IO、CPU负载都可能会达到极限,那么服务器对于一个请求的的响应时间势必变得比正常情况下慢很多,那么假设就刚才设置的锁的超时时间为10秒,如果某一个线程拿到锁之后因为某些原因没能在10秒内执行完毕锁就失效了,这时候其他线程就会抢占到分布式锁去执行业务逻辑,然后之前的线程执行完了,会去执行 finally 里的释放锁的代码就会把正在占有分布式锁的线程的锁给释放掉,实际上刚刚正在占有锁的线程还没执行完,那么其他线程就又有机会获得锁了...这样整个分布式锁就失效了,将会产生意想不到的后果。如下图模拟了这个场景。

 

所以这个问题总结一下,就是因为锁的过期时间设置的不合适或因为某些原因导致代码执行时间大于锁过期时间而导致并发问题以及锁被别的线程释放,以至于分布式锁混乱。在简单的说就是两个问题,1)自己的锁被别人释放 2)锁超时无法续时间。

第一个问题很好解决,在设置分布式锁时,我们在当前线程中生产一个唯一串将value设置为这个唯一值,然后在finally块里判断当前锁的value和自己设置的一样时再去执行delete,如下:

复制代码

String uuid = UUID.randomUUID().toString();
try {//原子的设置key及超时时间,锁唯一值Boolean aTrue = stringRedisTemplate.opsForValue().setIfAbsent(lock_key,uuid,30,TimeUnit.SECONDS);//...
} finally {//是自己设置的锁再执行deleteif(uuid.equals(stringRedisTemplate.opsForValue().get(lock_key))){stringRedisTemplate.delete(lock_key);//避免死锁}
}

复制代码

问题一解决了(设想一下上述代码还有什么问题,一会儿讲),那锁的超时时间就很关键了,不能太大也不能太小,这就需要评估业务代码的执行时间,比如设置个10秒,20秒。即使是你的锁设置了合适的超时时间,也避免不了可能会发生上述分析的因为某些原因代码没在正常评估的时间内执行完毕,所以这时候的解决方案就是给锁续超时时间。大致思路就是,业务线程单独起一个分线程,定时去监听业务线程设置的分布式锁是否还存在,存在就说明业务线程还没执行完,那么就延长锁的超时时间,若锁已不存在则业务线程执行完毕,然后就结束自己。

“锁续命”的这套逻辑属实有点复杂啊,要考虑的问题太多了,稍不注意就会有bug。不要看上面实现分布式锁的代码没有几行,就认为实现起来很简单,如果说自己去实现的时候没有实际高并发的经验,肯定也会踩很多坑,例如,

1)锁的设置和过期时间的设置是非原子操作的,就可能会导致死锁。

2)还有上面遗留的一个,在finally块里判断锁是否是自己设置的,是的话再删除锁,这两步操作也不是原子的,假设刚判断完为true服务就挂了,那么删除锁的代码不会执行,就会造成死锁,即使是设置了过期时间,在没过期这段时间也会死锁。所以这里也是一个注意的点,要保证原子操作的话,Redis提供了执行Lua脚本的功能来保证操作的原子性,具体怎么使用不再展开。

所以,“锁续命”的这套逻辑实现起来还是有点复杂的,好在市面上已经有现成的开源框架帮我们实现了,那就是Redisson。

回到顶部

Redisson分布式锁的实现原理

实现原理:

1、首先Redisson会尝试进行加锁,加锁的原理也是使用类似Redis的setnx命令原子的加锁,加锁成功的话其内部会开启一个子线程

2、子线程主要负责监听,其实就是一个定时器,定时监听主线程是否还持有锁,持有则将锁的时间延时,否则结束线程

3、如果加锁失败则自旋不断尝试加锁

4、执行完代码主线程主动释放锁

 

那我们看一下使用后Redisson后的代码是什么样的。

1、首先在pom.xml文件添加Redisson的maven坐标

复制代码

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.5<www.tengyao3zc.cn /version>
</dependency>

复制代码

2、我们要拿到Redisson的这个对象,如下配置Bean

复制代码

@SpringBootApplication
public class RedisLockApplication {public static void main(String[] args) {SpringApplication.run(RedisLockApplication.class, args);}@Beanpublic www.yuntianyul.com Redisson redisson(){Config config = new Config(www.javachenglei.com );config.useSingleServer(www.xingyunylpt.com).setAddress("redis://localhost:6379").setDatabase(www.yunzeyle.cn);return (www.jintianxuesha.com Redisson) Redisson.create(config);}
}

复制代码

3、然后我们获取Redisson的实例,使用其API进行加锁释放锁操作

复制代码

//假设库存编号是00001
private String key = "stock:00001";
private String lock_key = "lock_key:00001";
@Autowired
private StringRedisTemplate stringRedisTemplate;
/*** 使用Redisson实现分布式锁* @return*/
@RequestMapping("/stock_redisson_lock")
public String stock_redisson_lock() {RLock redissonLock = redisson.getLock(lock_key);try {redissonLock.lock(www.anxinzc5.cn);int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get(key));if (stock > www.tainfengyue.cn) {int afterStock = stock - 1;stringRedisTemplate.opsForValue().set(key, afterStock + "");System.out.println("扣减库存成功,剩余库存" + afterStock);} else {System.out.println("扣减库存失败");}} catch (NumberFormatException e) {e.printStackTrace(www.zhuyngyule.cn);} finally {redissonLock.unlock();}return "ok";
}

 

看这个Redisson的分布式锁提供的API是不是非常的简单?就像Java并发变成里AQS那套Lock机制一样,如下获取一把RedissonLock

RLock redissonLock = redisson.getLock(www.qiaoheibpt.com lock_key);

默认返回的是RedissonLock的对象,该对象实现了RLock接口,而RLock接口继承了JDK并发编程报包里的Lock接口

在使用Redisson加锁时,它也提供了很多API,如下

 

现在我们选择使用的是最简单的无参lock方法,简单的点进去跟一下看看他的源码,我们找到最终的执行加锁的代码如下:

我们可以看到其底层使用了Lua脚本来保证原子性,使用Redis的hash结构实现的加锁,以及可重入锁。

比我们自己实现分布式锁看起来还要简单,但是我们自己写的锁功能他都有,我们没有的他也有。比如,他实现的分布式锁是支持可重入的,也支持可等待,即尝试等待一定时间,没拿到锁就返回false。上述代码中的redissonLock.lock();是一直等待,内部自旋尝试加锁。

Distributed Java locks and synchronizers 

Lock 

FairLock 

MultiLock 

RedLock 

ReadWriteLock 

Semaphore 

PermitExpirableSemaphore 

CountDownLatch

redisson.org

Redisson提供了丰富的API,内部运用了大量的Lua脚本保证原子操作,篇幅原因redisson实现锁的代码暂不分析了。

结语

到这里,Redis分布式锁实战基本就讲完了,总结一下Redis分布式锁吧。

1、如果说是自己实现的话,需要特别注意四点:

1) 原子加锁 2)设置锁超时时间  3)谁加的锁谁释放,且释放时的原子操作  4)锁续命问题。

2、如果使用现成的分布式锁框架Redisson,就需要熟悉一下其常用的API以及实现原理,或者选择其他开源的分布式锁框架,充分考察,选择适合自己业务需求的即可。

 

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

相关文章

  1. ubuntu安装python3.8 - 两种方式

    一种源码安装 参考文章:https://blog.csdn.net/lixuhui2468/article/details/105210957一种是add-apt-repository方式安装sudo apt-get install software-properties-common -y sudo add-apt-repository ppa:deadsnakes/ppa sudo apt-get update sudo apt-get install python3…...

    2024/3/28 1:19:20
  2. 牛客暑假多校 200713C Cover the Tree dfs序+思维

    链接:https://ac.nowcoder.com/acm/contest/5667/C 来源:牛客网 题意 给你一棵树 让你找出最小数量的“链”(链就是树上任意两点连线)使得覆盖所有边。 思路 dfs序 从左到右存遍历到的叶子节点 然后 从第一个和中间开始遍历 若最后剩下一个 和之前的任意一个叶子相连即可…...

    2024/3/27 20:53:22
  3. Error:(5, 55) java: 程序包org.springframework.cloud.netflix.eureka.server不存在

    Error:(5, 55) java: 程序包org.springframework.cloud.netflix.eureka.server不存在 今天,准备去网上找一个项目写写,没想到刚把项目搭建好跑一下看看,结果出现了java程序包找不到的错误,首先我先进行clean和install都没有问题,错误依旧,接着我把下载在maven中的删除加上重启i…...

    2024/3/24 6:46:46
  4. offer 61扑克牌中的顺子

    题目 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。 示例 1: 输入: [1,2,3,4,5] 输出: True 示例 2: 输入: [0,0,1,2,5] 输出: True 思路如果没有重复…...

    2024/3/18 9:20:21
  5. 1.3 第三章 数组和字符串

    1.求子序列 输入两个字符串s和t,判断是否可以从s中删除0个或多个字符(其他字符顺序不变),得到字符串t. #include<cstring> int main(){char a[20],b[20];scanf("%s %s",a,b);int j=0,t=0;for(int i=0;i<strlen(b);i++){for(;j<strlen(a);j++){if(b[i…...

    2024/3/17 19:40:41
  6. 字符串拆分

    ...

    2024/3/24 11:19:49
  7. 启动hive时报: Call From hadoop /192.168.1.128 to hadoop :9000 failed on connection的原因之一hadoop启动没有Namenod

    昨天上午启动集群,发现master莫名其妙引导坏了,修了半天也修不好,无奈之下把原来搭的集群的master“嫁接”到这个集群里(动态节点增删)。 昨天shutdown now关机后,今天开机启动hive又不行了, 主要部分错误代码: Exception in thread "main" java.lang.Runtim…...

    2024/3/27 15:20:45
  8. JAVA网站高并发解决方案

    一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对…...

    2024/3/22 3:56:05
  9. PAT刷题记录 1025 PAT Ranking (25分)

    #include<iostream> #include<vector> #include<algorithm> #include<string> using namespace std;/*总结:用vector的insert来进行合并操作 */struct Student {string id;int grade;int location_number;int local_rank;int final_rank; }; vector&l…...

    2024/3/24 10:53:10
  10. 基于端到端的数据关联(二)

    参考:https://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/105524922...

    2024/3/23 22:35:33
  11. 120. 三角形最小路径和

    题目:添加链接描述 给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。 相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的…...

    2024/3/24 1:05:00
  12. 出现:Microsoft Visual C++ 14.0 is required 的有效解决方法

    以安装WordCloud为例: 如:pip install WordCloud 时出现: error: Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual C++ Build Tools”:解决方法: 解决办法安装 Microsoft visual c++ 14.0 下载地址 https://964279924.ctfile.com/fs/1445568-23944…...

    2024/3/24 12:07:27
  13. 02: 计算机概论组成篇

    目录一:计算机的总线1.1 总线的概述1.1.1总线的概述(是什么、什么用)1.1.2总线的分类1.2 总线的仲裁1.2.1为什么需要总线仲裁1.2.2总线的仲裁方法一:计算机的总线1.1 总线的概述1.1.1总线的概述(是什么、什么用)解决不同设备之间的通信问题1.1.2总线的分类片内总线: 高集…...

    2024/3/25 22:22:31
  14. 详解综合学习粒子群算法——CLPSO(附该文作者给出的matlab代码)

    最近团队出了两篇基于CLPSO[1]的改进算法,这里根据自己的理解分析一下这个综合学习的算法,并将文章作者给出的源代码分享出来供大家学习:https://download.csdn.net/download/Bernard_S/12612817 (免费下载,本身就是从作者的主页搬的哈哈)。首先综合评价一下CLPSO,正如作者…...

    2024/3/28 14:39:26
  15. USB数据线充电线转接头织梦网站模板

    电子产品USB数据线、充电线、转接头企业网站织梦模板,该模板属于企业通用、html5响应式、数码、科技、电子类企业使用,一款适用性很强的模板,基本可以适合各行业的企业网站! 模板特点: 1:织梦自适应产品模板,代码简洁,风格大气高端,页面干净。 2:首页带新闻展示,服务…...

    2024/3/25 15:05:15
  16. 在vue组件的ts脚本中导入图片

    原先我是这么导入图片的,可以看到我加了一些eslint-disable注释: // eslint-disable-next-line @typescript-eslint/no-var-requires const onLight = require("../imgs/light-on.png"); // eslint-disable-next-line @typescript-eslint/no-var-requires const of…...

    2024/3/20 11:37:37
  17. git撤销已经push到远端的commit

    使用git时,push到远端后发现commit了多余的文件,或者希望能够回退到以前的版本。 先在本地回退到相应的版本: git reset --hard <版本号>使用 --hard 参数会抛弃当前工作区的修改 使用 --soft 参数的话会回退到之前的版本,但是保留当前工作区的修改,可以重新提交 如…...

    2024/3/22 14:04:30
  18. 国内免费可用的stun服务器(2020.7.14)

    端口号都是3478 stun.xten.com stun.voipbuster.com stun.sipgate.net stun.ekiga.net stun.ideasip.com stun.schlund.de stun.voiparound.com stun.voipbuster.com stun.voipstunt.com stun.counterpath.com stun.1und1.de stun.gmx.net stun.callwithus.com stun.co…...

    2024/3/24 1:22:33
  19. Oracle数据库开启闪回查询(flashback)

    闪回查询的用途常用于误删数据库数据场景,用于恢复误删的数据;配置闪回查询要使用闪回询查功能,首先需要检查闪回查询功能是否已经开启:select * from v$version;select flashback_on from v$database;如果结果是“NO”,且不确定之前是否配置过flashback,先检查日志状态,如…...

    2024/3/25 19:59:04
  20. USB/UART/I2C/SPI等接口传输速率

    目录USB总线UARTI2C总线SPI总线GPIO(RK3399)FMC参考 USB总线 USB1.1: ——-低速模式(low speed):1.5Mbps ——-全速模式(full speed): 12Mbps USB2.0:向下兼容。增加了高速模式,最大速率480Mbps。 ——-高速模式(high speed): 25~480Mbps USB3.0:向下兼容。 ——-super …...

    2024/3/25 22:10:28

最新文章

  1. 常用开源机器学习库

    开源工具和机器学习库为数据科学家提供了强大的工具集&#xff0c;以便进行数据分析、模型训练和预测。以下是一些流行的开源机器学习库的简单介绍&#xff1a; Scikit-learn&#xff1a; Scikit-learn 是一个广泛使用的 Python 机器学习库&#xff0c;提供了大量的监督和非监督…...

    2024/3/29 6:30:44
  2. 梯度消失和梯度爆炸的一些处理方法

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

    2024/3/20 10:50:27
  3. 埃克拉姆·阿拉姆,MindPortal的CEO和联合创始人 - 采访系列

    Ekram Alam 专访&#xff1a;MindPortal 创始人兼首席执行官 引言 Ekram Alam 是 MindPortal 的创始人兼首席执行官&#xff0c;该公司致力于开发非侵入式神经接口&#xff0c;改变人类与人工智能的交互方式。他们的使命是通过让用户仅通过思想与人工智能交互&#xff0c;从而…...

    2024/3/28 10:04:37
  4. ChatGPT为您的论文写作提供无限可能

    ChatGPT无限次数:点击直达 在现代科技的快速发展下&#xff0c;人工智能正逐渐渗透到各个领域&#xff0c;为我们的生活和工作带来了诸多便利和创新。其中&#xff0c;ChatGPT作为开放AI的一项重要成果&#xff0c;以其卓越的自然语言处理能力&#xff0c;为我们的论文写作提供…...

    2024/3/28 3:39:33
  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/3/28 16:59:55
  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/3/28 4:39:34
  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/3/28 5:03:31
  8. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

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

    2024/3/28 19:59:46
  9. VB.net WebBrowser网页元素抓取分析方法

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

    2024/3/28 21:57:52
  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/3/28 9:07:44
  11. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

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

    2024/3/28 18:09:48
  12. 【ES6.0】- 扩展运算符(...)

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

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

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

    2024/3/28 9:58:22
  14. Go语言常用命令详解(二)

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

    2024/3/28 10:24:59
  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/3/28 19:51:36
  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/3/28 19:36:32
  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/3/28 17:15:47
  18. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

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

    2024/3/28 8:42:54
  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/3/28 8:14:39
  20. 基于深度学习的恶意软件检测

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

    2024/3/28 19:58:12
  21. JS原型对象prototype

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

    2024/3/28 21:57:45
  22. C++中只能有一个实例的单例类

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

    2024/3/28 8:24:01
  23. python django 小程序图书借阅源码

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

    2024/3/28 5:29:22
  24. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

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

    2024/3/28 9:26:43
  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