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

LUA脚本改造redis分布式锁

在redis集群模式下,我们会启动多个tomcat实例,每个tomcat实例都有一个JVM,且不共享。而synchronize锁的作用范围仅仅是当前JVM,所以我们需要一个作用于集群下的锁,也就是分布式锁。(就是不能用JVM自带的锁了,需要一个第三方应用实现锁)

在redis集群中我们是用setnx实现互斥锁来实现分布式锁。

setnx key value NX EX  时间 是往redis中创建一个key-value键值对,如果redis中没有该key,则创建成功,返回true;如果redis已经有了该key,则创建失败,返回null。NX是互斥,EX是超时时间,后跟具体时间+单位(s),EX用于过期时间,过了过期时间自动删除该key-value键值对。

我们用setnx命令实现分布式锁时,key和value都是String类型,key一般是特定前缀+该锁的名字,

value为线程id。

为什么value要存线程id呢?

因为存在这样情况:线程一获取锁,去执行逻辑,过程中遇到网络动荡,线程一卡住了,然后一段时间后,线程一获取的锁的过期时间到了,线程一的锁自动释放。然后线程二来获取锁,线程二获取成功,去执行逻辑,而在这个过程中线程一的网络动荡恢复了,线程一继续执行,线程一先于线程二执行完,线程一去释放锁,但此时线程一创建的锁已经因超时而自动释放了,所以此时线程一会去错误的释放线程二的锁,所以我们要把线程id存入加以判断,防止误删其他线程的id。

代码实现获取锁和释放锁:

package com.hmdp.utils;import cn.hutool.core.lang.UUID;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;import java.util.Collections;
import java.util.concurrent.TimeUnit;public class SimpleRedisLock implements ILock {private String name;private StringRedisTemplate stringRedisTemplate;public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {this.name = name;this.stringRedisTemplate = stringRedisTemplate;}private static final String KEY_PREFIX = "lock:";//randomUUID生成的数字会带一个横线,toString(true)方法就是去掉横线//因为不同JVM中,可能存在线程号相同的情况,所以需要用UUID来区分不同的JVMprivate static final String ID_PREFIX = UUID.randomUUID().toString(true) + "-";@Overridepublic boolean tryLock(long timeoutSec) {// 获取线程标示String threadId = ID_PREFIX + Thread.currentThread().getId();// 获取锁Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, threadId, timeoutSec, TimeUnit.SECONDS);//不能直接返回success,因为会有自动拆箱的风险,如果success是null,就会返回true,返回错误数据return Boolean.TRUE.equals(success);}@Overridepublic void unlock() {// 获取线程标示String threadId = ID_PREFIX + Thread.currentThread().getId();// 获取锁中的标示String id = stringRedisTemplate.opsForValue().get(KEY_PREFIX + name);// 判断标示是否一致if(threadId.equals(id)) {// 释放锁stringRedisTemplate.delete(KEY_PREFIX + name);}}
}

我们需要新建一个类实现ILock接口,然后去重写其中的tryLock获取锁、unlock释放锁方法。

往SimpleRedisLock的构造方法传入name变量,方便我们在实例化SimpleRedisLock类中设置该锁的名字。我们后面用setnx命令创建锁时的key值就是特定前缀KEY_PREFIX加上这个name;value值是randomUUID生成的唯一一串数字加上该线程id,因为不同JVM中,可能存在线程号相同的情况,所以需要用UUID来区分不同的JVM。

问题:

当本线程1在进入这个if判断后(释放锁之前),突然阻塞(比如full GC,该JVM上全服务堵塞)阻塞时间过长,锁超时释放,这时另一个jvm的线程2获取到锁,然后线程1继续执行释放锁
这样就又会出现同一个用户会有俩个线程在同时运行,所以需要保证判断和释放锁这俩步为一个原子性,同成功或同失败
这样很容易想到事务,redis也有事务,但redis的事务可以保证原子性,但不能保证一致性,而且redis的事务,是最后事务中的步骤同时完成。并不是一步一步的执行,所以只能用乐观锁但不建议用乐观锁,推荐用lua脚本

一个lua脚本中可以编写多条redis命令,确保多条命令的原子性。即实现判断和释放锁一起执行的原子性。

我们需要把这个脚本写在resources目录下

释放锁的lua脚本:

local key=KEYS[1]  -- 锁的key
local threadId=ARGV[1]  --线程唯一标识
-- 比较线程标示与锁中的标示是否一致
if(redis.call('get', key) ==  threadId) then-- 释放锁 del keyreturn redis.call('del', key)
end
return 0;

if()  then  end 相当于Java命令中的  if(  ) {  }   。

KEYS[1]:为需要传入的key值,当需要传入多个key值时,声明KEYS[2]、KEYS[3]...等就行。

ARGV[1]:为需要传入的其他非key的变量,声明方法与key一样。例如:

local key= KEYS[1] 
local key2= KEYS[2]
local threadId=ARGV[1]
local releaseTime=ARGV[2]

 

redis.call('  ',  ....)是执行的redis命令,命令中单引号'   '中写要执行的redis操作,后面的参数为执行该redis命令所需的参数,例如,get命令,需要知道key值。

然后改写我们的分布式锁:

我们需要先加载我们的lua脚本:

private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;static {UNLOCK_SCRIPT = new DefaultRedisScript<>();UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua")); //加载的脚本的位置,如果脚本文件在resources目录下,则只需写脚本名称即可。UNLOCK_SCRIPT.setResultType(Long.class); //返回值的类型}
@Overridepublic void unlock() {// 调用lua脚本  ,原来的多行代码变成了现在的单行代码就保证了原子性stringRedisTemplate.execute(UNLOCK_SCRIPT,Collections.singletonList(KEY_PREFIX + name), //生成单元素的集合,即脚本中的需要的KETS[1]参数ID_PREFIX + Thread.currentThread().getId()); //即脚本中需要的ARVG[1]参数}

完整代码:

package com.hmdp.utils;import cn.hutool.core.lang.UUID;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;import java.util.Collections;
import java.util.concurrent.TimeUnit;public class SimpleRedisLock implements ILock {private String name;private StringRedisTemplate stringRedisTemplate;public SimpleRedisLock(String name, StringRedisTemplate stringRedisTemplate) {this.name = name;this.stringRedisTemplate = stringRedisTemplate;}private static final String KEY_PREFIX = "lock:";//randomUUID生成的数字会带一个横线,toString(true)方法就是去掉横线//因为不同JVM中,可能存在线程号相同的情况,所以需要用UUID来区分不同的JVMprivate static final String ID_PREFIX = UUID.randomUUID().toString(true) + "-";private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;static {UNLOCK_SCRIPT = new DefaultRedisScript<>();UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua")); //加载的脚本的位置UNLOCK_SCRIPT.setResultType(Long.class); //返回值的类型}@Overridepublic boolean tryLock(long timeoutSec) {// 获取线程标示String threadId = ID_PREFIX + Thread.currentThread().getId();// 获取锁Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, threadId, timeoutSec, TimeUnit.SECONDS);//不能直接返回success,因为会有自动拆箱的风险,如果success是null,就会返回true,返回错误数据return Boolean.TRUE.equals(success);}@Overridepublic void unlock() {// 调用lua脚本  ,原来的多行代码变成了现在的单行代码就保证了原子性stringRedisTemplate.execute(UNLOCK_SCRIPT,Collections.singletonList(KEY_PREFIX + name), //生成单元素的集合,即脚本中的需要的KETS[1]参数ID_PREFIX + Thread.currentThread().getId()); //即脚本中需要的ARVG[1]参数}}

相关文章:

LUA脚本改造redis分布式锁

在redis集群模式下&#xff0c;我们会启动多个tomcat实例&#xff0c;每个tomcat实例都有一个JVM&#xff0c;且不共享。而synchronize锁的作用范围仅仅是当前JVM&#xff0c;所以我们需要一个作用于集群下的锁&#xff0c;也就是分布式锁。&#xff08;就是不能用JVM自带的锁了…...

web端使用HTML5开发《贪吃蛇》小游戏教程【附源码】

自制游戏列表 1植物大战僵尸自制HTML5游戏《植物大战僵尸》2开心消消乐自制HTML5游戏《开心消消乐》3贪吃蛇自制HTML5游戏《贪吃蛇》4捕鱼达人自制HTML5游戏《捕鱼达人》 一、游戏简介 贪吃蛇是一款经典的电子游戏&#xff0c;最早在1976年由Gremlin公司推出&#xff0c;名为…...

Selenium使用教程-Selenium环境搭建与基础操作

Selenium环境搭建与基础操作 1. 引言&#xff1a;Selenium简介​ Selenium&#xff0c;作为自动化测试领域的明星工具&#xff0c;以其强大的跨浏览器测试能力而闻名。它支持多种编程语言&#xff08;如Java、Python、C#等&#xff09;&#xff0c;允许开发者编写脚本来模拟真…...

1950年-2021年中国历年民航航线里程统计报告

数据为1950年到2021年我国每年的民航航线总里程数据。 2021年&#xff0c;我国定期航班航线总里程为689.78万公里&#xff0c;相比2019年下降了258.44万公里。 数据统计单位为&#xff1a;公里. 数据说明&#xff1a; 2011年起民航航线里程改为定期航班航线里程 我国定期航班…...

前端了解到框架-网络复习

前端 HTML 超文本标记语言 画页面 各种各样的标签组成页面进行展示 桌面创建文本修改后缀即可 <!DOCTYPE html>: 声明文档类型和HTML版本。<html>: 根标签&#xff0c;所有其他标签都包含在内。<head>: 包含了文档的元数据&#xff0c;如字符编码、网页标…...

防火墙——网络环境支持

目录 网络环境支持 防火墙的组网 web连接上防火墙 web管理口 让防火墙接到网络环境中 ​编辑 管理员用户管理 缺省管理员 接口 配置一个普通接口 创建安全区域 路由模式 透明模式 混合模式 防火墙的安全策略 防火墙转发流程 与传统包过滤的区别 创建安全策略 …...

阅读笔记:明朝那些事儿之拐弯中的帝国

​万历皇帝时期内阁首辅&#xff1a; 张居正&#xff0c;申时行&#xff0c;王锡爵&#xff0c;许国&#xff0c;王家屏&#xff0c;赵志皋&#xff08;给皇帝写辞职信没有回音&#xff0c;自己不告而回家&#xff09;&#xff0c;沈一贯&#xff0c;于慎行&#xff0c;叶向高…...

React基础知识 精简全面 推荐

这篇博文主要对一些刚入门react框架的同学&#xff0c;以及对react基本知识进行巩固的&#xff0c;最后就是精简一下基本知识&#xff0c;以方便自己查看&#xff0c;感谢参考&#xff0c;有问题评论区交流&#xff0c;谢谢。 目录 1.JSX 2.Props 和 State 3.组件生命周期…...

OV SSL证书申请指南

OV SSL证书除了验证域名所有权外还需要验证组织信息&#xff0c;这类证书适用于对公司官网、品牌、安全性等有较高程度要求的企业级用户。具体申请流程如下&#xff1a; 一 、注册账号 注册账号填写230919注册码即可获得大额优惠券和全程一对一技术支持https://www.joyssl.co…...

变色树脂的变色原理?变色树脂在水处理中的应用?

变色树脂是一种具有特殊功能的高分子材料&#xff0c;能够在特定条件下改变其颜色&#xff0c;从而指示环境变化&#xff08;如pH值、温度、特定离子浓度等&#xff09;或反应进程。这类树脂通常含有能够响应特定刺激的化学结构&#xff0c;通过化学反应、离子交换、分子构象变…...

16 敏捷开发实践(1)

敏捷方法&#xff1a;是一种从1990年代开始逐渐引起广泛关注的一些新型软件开发方法&#xff0c;是一种应对快速变化的需求的一种软件开发能力。 敏捷开发&#xff1a;是一种以人为核心、迭代、循序渐进的开发方法。 敏捷实践&#xff1a;精益软件开发&#xff08;LSD&#x…...

如何使用虚拟机如何安装 Kali Linux ?

1.下载虚拟机&#xff1a;https://www.virtualbox.org/wiki/Downloads 选择你的系统版本 2.下载kali linux系统镜像&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 全部下载完成后&#xff0c;我们会得到以下文件&#xff01; 1.压缩Kali Linux压缩包 2.安…...

Yarn UI 时间问题,相差8小时

位置 $HADOOP_HOME/share/hadoop/yarn/hadoop-yarn-common-2.6.1.jar 查看 jar tf hadoop-yarn-common-2.6.1.jar |grep yarn.dt.plugins.js webapps/static/yarn.dt.plugins.js 解压 jar -xvf hadoop-yarn-common-2.6.1.jar webapps/static/yarn.dt.plugins.js inflated: we…...

【JavaWeb项目】——外卖订餐系统之登入、登入后显示餐品信息、用户注册、注销部分

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…...

怎么保护电脑文件夹?文件夹保护方法大盘点

文件夹是管理电脑数据的重要工具&#xff0c;可以有效避免数据混乱。而为了避免文件夹数据泄露&#xff0c;我们需要严格保护文件夹。下面我们就来盘点一下文件夹的保护方法。 文件夹隐藏 隐藏文件夹是一种简单有效的保护方式&#xff0c;通过隐藏文件夹来避免其他人发现&…...

Temporal(时效)模式01

Andy Carlson, Sharon Estepp, Martin Fowler 著&#xff0c;透明 译 抽象 在面向对象设计中&#xff0c;我们不断使用“对象”&#xff08;object&#xff09;这个词。对象不仅仅用来表现真实世界中存在的物件&#xff0c;它们也被用来表现那些曾经存在但已经消失了的物件&…...

C语言 -- 动态内存管理

C语言 -- 动态内存管理 1. 为什么要有动态内存分配2. malloc 和 free2.1 malloc2.2 free 3. calloc 和 realloc3.1 calloc3.2 realloc 4. 常见的动态内存的错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对非动态开辟内存使用free释放4.4 使用free释放一块动…...

docker 篇

简单描述下&#xff0c;有时候真的要熟练&#xff0c;否者上了生产真的不知所措。 背景&#xff1a;有个项目上线了&#xff0c;依赖的项目没有上线&#xff0c;因此需要紧急发布&#xff0c;发现&#xff1a;打包环境有问题&#xff0c;第一、架构不一致&#xff0c;第二、环…...

汽车、能源、烟草、电力行业洞见:TDengine 用户大会亮点荟萃

近年来&#xff0c;随着物联网、车联网、工业互联网等前沿技术的迅猛发展&#xff0c;全球数据量呈指数级增长。作为大数据的一个重要组成部分&#xff0c;时序数据因其在实时监控、预测分析和智能决策中的独特优势&#xff0c;正逐步成为数字化转型的关键要素。尤其在 AI 时代…...

从零开始编写一个Chrome插件:详细教程

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…...

photoshop学习笔记——选区3 快速选择工具

快速选择工具 W shift W 在3种快速选择工具之间切换 对象选择工具 photoshop CC中没有这个工具&#xff0c;利用AI&#xff0c;将款选中的对象快速的提取选区&#xff0c;测试了一下&#xff0c;选区制作的非常nice快速选择工具 跟磁性套索类似&#xff0c;自动识别颜色相似…...

Centos7下安装配置最新版本Jenkins

1、基础环境配置 1.1 服务器下载Jenkins安装包 下载地址&#xff1a;Download and deploy 下载命令&#xff1a;wget https://get.jenkins.io/war-stable/2.452.3/jenkins.war 1.2 服务器安装配置JDK Jenkins 是基于 Java 语言开发的&#xff0c;因此需要 Java 运行环境支…...

c++ 构造函数与析构函数

本文参考菜鸟教程&#xff0c;仅作笔记用。 构造函数 构造函数&#xff08;Constructor&#xff09;是一种特殊的方法&#xff0c;用于在创建对象时进行初始化操作。构造函数的名称与类的名称是完全相同的&#xff0c;并且不会返回任何类型&#xff0c;也不会返回 void。在面…...

Lc63---1859将句子排序(排序)---Java版(未写完)

1.题目描述 2.思路 &#xff08;1&#xff09;首先将句子按空格分割成若干单词。 &#xff08;2&#xff09;每个单词的最后一个字符是它的位置索引。我们可以通过这个索引将单词恢复到正确的位置。 &#xff08;3&#xff09;按照单词的索引顺序排序这些单词。 &#xff08;4…...

centos7-8/redhat7-8一键安装配置vsftp服务

1.脚本介绍 1.1.介绍&#xff1a; linux下一键安装及配置vsftpd服务 &#xff0c;通过执行install.sh脚本&#xff0c;脚本会根据参数区域的值执行安装和配置vsftp服务&#xff0c;安装后会创建一个默认ftp用户wangxf密码wangxf2023 1、支持自定义安装(更改脚本内参数值) 2、…...

7月24日JavaSE学习笔记

序列化版本控制 序列化&#xff1a;将内存对象转换成序列&#xff08;流&#xff09;的过程 反序列化&#xff1a;将对象序列读入程序&#xff0c;转换成对象的方式&#xff1b;反序列化的对象是一个新的对象。 serialVersionUID 是一个类的序列化版本号 private static fin…...

微信小程序教程008:事件绑定

文章目录 事件绑定1、什么是事件2、小程序中常用事件3、事件对象的属性列表4、target和currentTarget的区别5、bindtap的语法格式6、在事件处理函数中为data中的数据赋值7、事件传参数8、bind:input语法格式9、实现文本框和data之间的数据同步事件绑定 1、什么是事件 事件是渲…...

企业级-实现Nginx的静态文件服务器映射

作者&#xff1a;fyupeng 技术专栏&#xff1a;☞ https://github.com/fyupeng 项目地址&#xff1a;☞ https://github.com/fyupeng/distributed-blog-system-api 留给读者 开发人员往往会经常需要通过浏览器下载文件、图片或者PDF或者缩略图等&#xff0c;这时候我们可以根据…...

CTF Web SQL注入 10000字详解

这里写目录标题 涉及的数据库知识unionorder bydatabase()information_schemalimit--空格注释replaceinto outfilelikeGROUP BYHAVINGGROUP BY、HAVING、WHERE之间的关系regexp 原理信息收集操作系统数据库判断注入点注入点类型POST注入数字型注入字符型注入搜索型注入Insert/u…...

动态SLAM:如何判断一个特征是动态特征(对极几何)

文章目录 1.什么是极线、极点和极面2.如何判断其为动态点特征3.如何判断其为动态线特征 1.什么是极线、极点和极面 由图可知&#xff0c;C1,C2,X(X1,X2)组成了一个三角平面&#xff0c;这个三角所在的平面就是极面 在这个极平面中&#xff0c;和成像平面相交的线是极线&#xf…...

【C++】初识C++基础篇·一(命名空间,函数重载,缺省参数,引用);

文章目录 前言1.输入与输出输出输入cin和scanf的对比 2.命名空间2.1namespace存在的意义2.2namespace的使用3.缺省参数4.函数重载重载函数的调用规则 5.引用 前言 我们先通过一段简单的代码来拉开C的序幕&#xff1b; //text.cpp #include<iostream> #include<stdio…...

2024年道路运输安全员考试题库及答案

一、判断题 1.国家制订《中华人民共和国道路交通安全法》的目的是为了维护道路交通秩序&#xff0c;预防和减少交通事故&#xff0c;保护人身安全&#xff0c;保护公民、法人和其他组织的财产安全及其他合法权益&#xff0c;提高通行效率。 答案&#xff1a;正确 2.依据《中…...

Linux Vim教程(十二):语法高亮与代码折叠

目录 1. 语法高亮 1.1 启用语法高亮 1.2 设置配色方案 1.3 自定义语法高亮 2. 代码折叠 2.1 启用代码折叠 2.2 设置折叠方法 2.3 手动折叠 2.4 基于缩进的折叠 2.5 基于语法的折叠 3. 案例 3.1 配置文件 3.2 编辑Python文件 3.3 使用折叠功能 4. 高级使用技巧 …...

JavaScript(18)——事件类型,事件对象

事件类型 鼠标事件&#xff1a; click&#xff1a;鼠标点击 mouseenter&#xff1a;鼠标经过 mouseleave&#xff1a;鼠标离开 焦点事件&#xff1a; focus&#xff1a;获得焦点 blur&#xff1a;失去焦点 键盘事件&#xff1a; Keydown&#xff1a;键盘按下触发 Keyup&#…...

有效组织离散变量:指针数组在C语言中的应用

把离散变量组织起来&#xff0c;访问起来更加方便&#xff0c;无需一个个变量单独赋值。 如modbus读写reg&#xff0c; 把a\b\c\d实时变化分散的变量组织成一个数组reg&#xff0c;方便获取 相当于变量的内存地址池 int main() {int a 10, b 20, c 30, d 40;int i;int *re…...

qt 应用正在运行时,如何更新升级exe文件

在Qt应用正在运行时&#xff0c;直接替换同名的.exe文件可能会导致文件正在使用中的错误。为了安全地更新.exe文件&#xff0c;你可以采取以下步骤&#xff1a; 创建一个临时的.exe文件。 等待当前.exe文件的进程关闭。 删除原有的.exe文件。 将临时.exe文件重命名为原有的.…...

git的rebase 和 merge 的区别

rebase 和 merge 的区别 Merge&#xff08;合并&#xff09;和 Rebase&#xff08;变基&#xff09;是 Git 中两种常用的分支整合方式&#xff0c;它们有不同的工作原理和适用场景&#xff1a; Merge&#xff08;合并&#xff09;&#xff1a; ● Merge 操作将两个分支的不同提…...

django基于大数据的电影推荐系统-计算机毕业设计源码71246

目 录 摘 要 1 绪论 1.1 选题背景与意义 1.2研究现状 1.3研究内容 1.4 开发环境 1.5论文结构与章节安排 2 相关理论和技术 2.1 协同过滤算法 2.2 B/S体系结构介绍 2.3 Python爬虫技术 2.4 Django框架介绍 2.5 MySQL数据库 3 电影推荐系统系统分析 3.1 可行性分析…...

reverse_re3-入土为安的第十天

一个迷宫题 shirtf12发现flag字样 点进去发现迷宫 675 应该是3 * 15*15 即有三个迷宫 shifte提取 import numpy as np# 你的数据&#xff08;长度应为 225 的倍数&#xff09; dword_202020 [1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,3,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,…...

fastapi之一

文章目录 安装运行HTTP 请求方法示例 POSTMAN 检验GETPOSTPUTDELETE HTTP 状态码示例GETPOST 综合示例POSTGETPUTDELETE 总结 安装 pip install fastapi或者 pip install fastapi -i https://mirrors.aliyun.com/pypi/simple上面两种方法均可以&#xff0c;选择一个即可&…...

【C语言报错已解决】Format String Vulnerability

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引言 在日常开发中&#xff0c;我们经常会遇到各种各样的bug&#xff0c;其中格式化字符串漏洞报错可能是最让人头疼的一种。这…...

关于一个简单的顺序表代码

1.首先是头文件SeqList.h的代码&#xff1a; #pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> typedef int SXBint; typedef struct SL {SXBint* a;int size;int capacity; }SLnode; //初始化 void SeqLsitInit(SLnode* ps); //尾插…...

【资料分享】2024第三届钉钉杯大学生大数据挑战赛B题思路解析+双语言代码

2024钉钉杯大学生大数据挑战赛&#xff0c;B题解题思路和双语言代码分享&#xff0c;资料预览&#xff1a;...

Typescript学习笔记(2.0)

ts编译选项 tsc app.ts -w 参数-w&#xff0c;就是对app.ts进行监视&#xff0c;每次该文件改变时就会自动编译 **:任意目录 *&#xff1a;任意文件 接口 接口用来定义一个类结构&#xff0c;用来定义一个类中应该包含哪些属性和方法&#xff0c;同时接口也可以当做类型…...

【IJHE】:微通道反应器中全氢二苄基甲苯脱氢产氢

Highlight 微通道反应器中全氢二苄基甲苯脱氢产氢两种不同反应器的比较&#xff1a;搅拌釜和连续微通道反应器连续微通道反应器是一种很有前途的脱氢技术 摘要: 本文对全氢二苄基甲苯作为液态有机氢载体从搅拌槽反应器转换为连续流微通道反应器进行脱氢进行了初步研究。与搅拌槽…...

Spring踩坑:抽象类作为父类,使用子类@Autowired属性进行填充,属性值为null

Spring踩坑&#xff1a;抽象类作为父类&#xff0c;使用子类Autowired属性进行填充&#xff0c;属性值为null Spring Boot中抽象类和依赖注入的最佳实践引言在抽象类中使用Autowired注解protected vs private修饰符低版本Spring Boot的注意事项 构造器中的依赖注入陷阱为什么不…...

C#网络连接:TCP/IP模式下的网络连接与同步

1&#xff0c;目的 为了测试局域网的消息同步&#xff0c;简单写了下TCP/IP模式的同步&#xff0c;参考这个帖子。 2&#xff0c;核心库部分 using System; using System.Net; using System.Net.Sockets; using System.Text;namespace Coldairarrow.Util.Sockets {/// <s…...

基于树莓派(Raspberry Pi) 的智能电表监测系统设计:集成 Home Assistant、SQLite 和 MQTT 协议

在全球对可持续发展和能源节约的关注日益加深的背景下&#xff0c;智能能源管理系统&#xff08;IEMS&#xff09;应运而生。该系统利用现代科技&#xff08;如物联网、云计算和大数据分析&#xff09;来优化能源使用&#xff0c;提高能效&#xff0c;降低能源成本。本文将详细…...

C语言程序设计(二)

四.找素数 素数&#xff1a;除了1和它本身不再有其他因数的自然数。换句话说&#xff1a;一个大于1的自然数 &#xff0c;如果只能被1和它本身整除&#xff0c;那就是素数&#xff08;质数&#xff09;。 在打印中遇到的问题就是&#xff0c;知道怎么写却总是运行不起来。主要…...

Oracle对数据库行和数据库的监控

前言&#xff1a; Oracle对表的监控分为数据行修改DML的监控、对表的DDL监控 1、对表的DML监控&#xff08;数据的增删改&#xff09; -- 创建测试表 create table tab_test01( id varchar2(100) default sys_guid(), name varchar2(100), insert_date date default sysdate…...