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

Redis最终篇分布式锁以及数据一致性

  在前三篇我们几乎说完了Redis的所有的基础知识以及Redis怎么实现高可用性,那么在这一篇文章中的话我们主要就是说明如果我们使用Redis出现什么问题以及解决方案是什么,这个如果在未来的工作中也有可能会遇到,希望对看这篇博客的人有帮助,话不多说直接开干

一.Hotkey以及BigKey

 Hotkey:

   HotKey就是说在一段时间范围之内的访问频率特别高,所以我们常说缓存击穿的问题(不清楚的话可以看Redis持久化策略以及三大缓存问题-CSDN博客)的话几乎就是因为Hotkey所导致的问题常见的场景: 热点新闻 判断是否为Hotkey就是根据访问频率 发现的途径:1.会有第三方监控平台进行监控 2.就是使用命令   3.就是使用二级缓存也就是说JVM的缓存(Caffine)   如果实在不行的话那么就会搭建集群

//这个就能展现出所有的key的访问的次数
redis-cli -p 6379 --hotkeys

Bigkey:

     BigKey就是说以string为数据类型的话那么就是说value的值占用的空间超过512M那么或者如果是Zset数据类型的话那么就是说value的数目过多,所以的话Bigkey占用的内存空间就是特别大,那么我们都知道Redis是基于内存那么如果出现BigKey肯定对其中的一些方面产生一些影响:如AOF文件的重写因为AOF重写的话是需要进行写时复制的那么占用内存更大以及生成的RDB数据快照的话生成的文件也是比较大等等如果不知道AOF以及RDB的话那么可以看我的Hotkey的那个博客      解决方案: 1.可以将Bigkey进行拆分若干个smallKey 2.如果想要删除的话那么要进行异步以及批量进行删除

 

二.怎么保证数据库和缓存数据的一致性问题

 对于数据一致性问题的话这个是一个非常常见的问题除了这个场景的话还有就是Mysql进行读写分离的时候肯定也会遇到怎么保证主数据库和从数据库之间的数据一致性的问题,所以这个问题也是比较头疼的但是这个有一个特别的说明: 就是没有系统可以保证数据的实时的一致性,所以有一段时间的数据不一致的话那么是可以接受的 

解决方案: cannel+旁路缓存cannel中间件的话其实就是为了监听Mysql的binlog日志,因为如果数据库里面的数据发生变化的话那么binnlog日志里面的数据肯定也会发生变化那么这个时候我们的cannel中间件监听到之后这个时候就会告诉我们客户端然后就会对缓存中的数据进行一个删除的操作  旁路缓存: 这个就是说要从读以及写的方面进行说明:

读角度: 读的话那么客户端请求的时候肯定是从缓存中进行数据的读取如果缓存中没有的话那么肯定是从数据库中进行数据的读取那么除了读之外的话就会将读取的数据加载到缓存中 注意: 从缓存中读取数据的时候要先获得分布式锁 

写角度: 当进行数据修改的时候我们是先修改数据库当中的数据然后再删除缓存中的数据,那么这个时候就是又会有问题: 1.为什么不是修改缓存中的数据而是删除 2.为什么不是先改变缓存中的数据而是先改变数据库当中的数据  对于第一个问题:因为对于修改操作的话那么会有一定的时序性(有可能就是因为网络的问题导致修改和预期的结果不一致)而且删除更加轻量级

对于第二个问题:因为先修改(删除)缓存数据的话如果在修改数据库的时候出现网络问题导致修改数据库失败那么后面的请求就会读到旧的数据而且缓存中的数据就是以数据库的数据为根本所以肯定是先修改数据库中的数据

三.Redis分布式锁的应用以及实现原理

  对于分布式锁的话其实一点都不陌生如:我们常听的秒杀或者防止超卖的场景,但是对于分布锁很多人只是停留在理论的基础之上以及只知道这个概念但是不知道分布式锁的底层原理如怎么实现互斥性以及实现可重入性的下面的就会进行说明

 首先我们先说Redis分布式锁的实现方式: 首先我们肯定就是想到的就是原生锁

// NX 表示只有当键不存在时才设置键,EX 设置键的过期时间 这个主要就是为了解决死锁问题
SET RedislockName NX EX second

但是我们都知道如果设置过期时间的话那么如果到了过期时间的话但是我的线程执行的业务逻辑还没有执行完成这个时候如果释放锁的话那么就会产生巨大的问题,所以后来的话我们就使用Redission分布式锁

Redisson分布式锁:

 优点:这个相对于原生锁的话就是添加了一个看门狗(watchDog)机制也就是说会自动续约,这个看门狗机制就是说默认的条件下就是每隔10s就会检查key是否要过期了如果要过期的话那么就会进行续约,但是这个的话就是会有一个疑问: 假如我续约完成之后由于一些原因导致线程暂停那么这个时候不是会一直进行续约吗那么这个不就会产生一定的问题 回答: 会有一个心跳的检测功能,如果发生心跳在一段时间范围之内没有接收到回应的话那么就会自动释放分布式锁

实现步骤以及应用:
1.引入相关的依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>2.7.0</version>
</dependency>
2.进行配置redisclient:
@Configuration
@Slf4j
public class redisConfig {private static final Logger logger = LoggerFactory.getLogger(redisConfig.class);@Beanpublic RedissonClient createClient() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(4);return Redisson.create(config);}
3.获得以及释放锁实现相关的业务逻辑

线程实现的业务逻辑代码:

3.1. 在获得锁的时候添加持有锁的的参数(方案1)

 public void run() {RLock lock = redissonClient.getLock("lockName");boolean isLock = false;try {//3就是代表最多等待获得锁的时间//2就是代表的就是持有锁的时间isLock = lock.tryLock(3,2,TimeUnit.SECONDS); if (isLock) {System.out.println("线程 " + threadId + " 获取到了锁");// 模拟业务逻辑System.out.println("线程 " + threadId + " 执行业务逻辑...");Thread.sleep(2000); // 模拟长时间的业务处理} else {System.out.println("线程 " + threadId + " 未能获取到锁");}} catch (InterruptedException e) {System.err.println("线程 " + threadId + " 被中断");} finally {// 释放锁if (isLock) {lock.unlock();System.out.println("线程 " + threadId + " 释放了锁");}}}

3.1.2.线程进行trylock的时候不添加持有锁的时间(方案2)

  isLock = lock.tryLock(3,TimeUnit.SECONDS); 

3.2.测试代码

3.3.测试结果

方案1:


 

不难看出来这个是会报错的这个错误的意思就是说 当一个线程试图解锁它没有锁住的对象时抛出的异常 那么就说明锁已经释放了并且被别的线程获得了那么看门狗机制不生效了

Exception in thread "Thread-13" java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: eec734cc-03c5-4879-adf6-f981e58c0809 thread-id: 89

方案2:

这个和方案1不一样那么就说明看门狗机制,因为线程4获得锁之后业务逻辑没有执行完成那么这个时候不会自动释放锁的因为其他获得线程等待时间到了之后就获得不了锁了

特别说明: 使用分布式锁的中trylock方法的时候不要添加持有锁的时间

相关文章:

Redis最终篇分布式锁以及数据一致性

在前三篇我们几乎说完了Redis的所有的基础知识以及Redis怎么实现高可用性,那么在这一篇文章中的话我们主要就是说明如果我们使用Redis出现什么问题以及解决方案是什么,这个如果在未来的工作中也有可能会遇到,希望对看这篇博客的人有帮助,话不多说直接开干 一.Hotkey以及BigKey…...

TCP协议

报文格式 源/目的端口号&#xff1a;数据从哪个进程来&#xff0c;到哪个进程去32位序号&#xff1a;TCP传输过程中&#xff0c;在发送端出的字节流中&#xff0c;传输报文中的数据部分的每一个字节都有它的编号32位确认号&#xff1a;标识了报文接收端期望接收的字节序列4位首…...

Vue3 源码解析(十):watch 的实现原理

本篇文章笔者会讲解 Vue3 中侦听器相关的 api&#xff1a;watchEffect 和 watch 。在 Vue3 之前 watch 是 option 写法中一个很常用的选项&#xff0c;使用它可以非常方便的监听一个数据源的变化&#xff0c;而在 Vue3 中随着 Composition API 的写法推行也将 watch 独立成了一…...

2023年9月GESPC++一级真题解析

一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 题号 123456789101112131415 答案 CDBCDBACACBBDDA 1. 我们通常说的 “ 内存 ” 属于计算机中的&#xff08;&#xff09;。 A. 输出设备 B. 输 ⼊ 设备 C. 存储设备 D. 打印设备 【答案】 C 【考纲知识点】…...

vscode 远程连接ssh 密钥方式

目录 1. powershell 生成key&#xff1a; 2. 在服务器上安装公钥 linux测试成功&#xff1a; 3).为了确保连接成功&#xff0c;输入如下指令以保证以下文件权限正确&#xff1a; 3 开启 ssh 密钥登录 vscode 远程连接配置 python连接测试ok 查看日志&#xff1a; 1. po…...

字符函数和字符串函数

字符分类函数 C语言中有⼀系列的函数是专门做字符分类的&#xff0c;也就是⼀个字符是属于什么类型的字符的。 这些函数的使用都需要包含⼀个头文件&#xff1a;ctype.h 这些函数的用法非常类似。 int islower ( int c )islower是能够判断参数部分是否是小写字母的。 通过返…...

如何利用ChatGPT加速开发与学习:以BPMN编辑器为例

在现代开发中&#xff0c;开发者经常会遇到各种需要编写和学习新技术的任务。ChatGPT作为一种强大的自然语言处理工具&#xff0c;不仅可以辅助编写代码&#xff0c;还可以帮助学习新的编程概念和解决开发中的难题。本文将以开发一个BPMN&#xff08;业务流程建模与标注&#x…...

深度学习2

四、tensor常见操作 1、元素值 1.1、获取元素值 tensor.item() 返回tensor的元素&#xff1b;只能在一个元素值使用&#xff0c;多个报错&#xff0c;当存在多个元素值时需要使用索引进行获取到一个元素值时在使用 item。 1.2、元素值运算 tensor对元素值的运算&#xff1a;…...

工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程

一.背景 公司是非煤采矿业&#xff0c;核心业务是采选&#xff0c;大型设备多&#xff0c;安全风险因素多。当下政府重视安全&#xff0c;头部技术企业的安全解决方案先进但价格不低&#xff0c;作为民营企业对安全投入的成本很敏感。利用我本身所学&#xff0c;准备搭建公司的…...

单片机学习笔记 9. 8×8LED点阵屏

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~单片机学习笔记 5. 数码管静态显示单片机学习笔记 6. 数码管动态显示单片机学习笔记 7. 独立键盘单片机学习笔记 8…...

c++ 力扣题(1)JZ64

JZ64求123...n_牛客题霸_牛客网 因此不能使用等差求和&#xff08;禁掉位运算为了禁掉等差求和&#xff0c;右移一位就是等差除二&#xff09;、循环、递归来解决 我们运用到在 统计构造次数所学到的内容&#xff1a; 1.可以利用静态全局变量的思想来做 2.构造n次对象&…...

logback动态获取nacos配置

文章目录 前言一、整体思路二、使用bootstrap.yml三、增加环境变量四、pom文件五、logback-spring.xml更改总结 前言 主要是logback动态获取nacos的配置信息,结尾完整代码 项目springcloudnacosplumelog&#xff0c;使用的时候、特别是部署的时候&#xff0c;需要改环境&#…...

基于零相差前馈补偿的 PID 控制

零相差前馈补偿是一种结合前馈补偿与反馈控制的策略&#xff0c;旨在提高控制系统对参考信号的跟踪精度。通过设计合理的前馈补偿器&#xff0c;使得系统对参考输入实现零相位差的跟踪&#xff0c;同时利用 PID 控制器保证系统的稳定性和动态性能。 1. 原理概述 目标&#xff…...

任务通知的本质(任务通知车辆运行) 软件定时器的本质(增加游戏音效)

任务通知的本质 没有任务通知 所谓"任务通知"&#xff0c;你可以反过来读"通知任务"。 我们使用队列、信号量、事件组等等方法时&#xff0c;并不知道对方是谁。使用任务通知时&#xff0c;可 以明确指定&#xff1a;通知哪个任务。 使用队列、信号量、…...

如何在 MySQL 中进行数据导入和导出?

在 MySQL 中进行数据的导入和导出是一项常见的任务&#xff0c;用于数据备份、恢复、迁移以及数据分析等多种用途。MySQL 提供了多种方法来进行数据的导入和导出&#xff0c;每种方法都有其适用的场景和特点。以下是几种常用的 MySQL 数据导入和导出方法&#xff0c;包括命令行…...

python语言基础-5 进阶语法-5.3 流式编程

声明&#xff1a;本内容非盈利性质&#xff0c;也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站&#xff0c;会尽量附上原文链接&#xff0c;并鼓励大家看原文。侵删。 5.3 流式编程&#xff08;参考链接&#xff1a;https://www.zhihu.com/question/59062…...

centos 服务器 docker 使用代理

宿主机使用代理 在宿主机的全局配置文件中添加代理信息 vim /etc/profile export http_proxyhttp://127.0.0.1:7897 export https_proxyhttp://127.0.0.1:7897 export no_proxy"localhost,127.0.0.1,::1,172.171.0.0" docker 命令使用代理 例如我想在使用使用 do…...

[个人专属博客] - docker安装

&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389; 欢迎访问的个人博客&#xff1a;http://swzbk.site/&#xff0c;加好友&#xff0c;一起赚&#x1f9e7;&#x1f9e7;&#x1f9e7; &#x1f389;&#x1f389;&#x1f389;&#x1f389;&…...

推荐一个QDirStat基于 Qt 的目录统计工具

QDirStat 是一款基于 Qt 的目录统计工具&#xff0c;旨在帮助用户分析磁盘空间使用情况并进行清理。QDirStat的一些主要特点和功能&#xff1a; 跨平台兼容性&#xff1a;QDirStat 支持 Linux、BSD、Unix-like 系统以及 macOS&#xff0c;确保了广泛的用户基础。 直观的数据展…...

yolo自动化项目实例解析(九) 导航

比如我们经常使用的导航&#xff0c;说白了就是寻找两点之间最近的路径&#xff0c;也就是所谓的寻路&#xff0c;我们需要想办法让程序知道他要去哪里&#xff0c;路径包含&#xff08;起点、轨迹、终点&#xff09; 一、录制轨迹 从平面角度来看&#xff0c;我们可以把区域视…...

MySQL 报错:1137 - Can‘t reopen table

MySQL 报错&#xff1a;1137 - Can’t reopen table 1. 问题 对临时表查询&#xff1a; select a.ts_code,a.tsnum,b.tsnum from (select t.ts_code ,count(*) tsnum from tmp_table t group by t.ts_code having count(*) > 20 and count(*)< 50 ) a ,(select t.ts_…...

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域,数据可视化是一个至关重要的环节。通过可视化,我们可以直观地理解数据的特征和趋势,为数据分析和决策…...

HTMLCSS:比赛记分卡

效果演示 这段 HTML 和 CSS 代码创建了一个卡片式的体育比赛信息展示组件&#xff0c;用于显示篮球比赛的两个队伍名称、比赛时间、比分以及一些装饰性的视觉元素。 HTML <div class"card"><div data-status"inprogress" class"teams"…...

什么是 Faiss?

好的&#xff0c;我来详细解释 Faiss&#xff0c;它的用途、使用场景&#xff0c;以及如何安装和使用。 什么是 Faiss&#xff1f; Faiss 是由 Facebook AI Research 开发的一个开源库&#xff0c;专门用于高效的相似性搜索和聚类。它非常擅长在高维向量空间中进行快速搜索&a…...

【prism】遇到一个坑,分享!

背景 我通用prism的方式写了一个弹窗,弹窗绑定一个 Loaded 事件,但是Loaded事件一直不触发!!! 具体过程 我的loaded事件也是通过命令的方式绑定的: <i:Interaction.Triggers><i:EventTrigger EventName="Loaded...

vue制作代码比较工具

前两天朋友问我 有没有vue可以做一个json代码在线比较工具 我也是在网上搜了一下找到的 废话不说 直接上代码 采用 v3 pnpm i v-code-diff <div><CodeDiff:old-string"oldStr":new-string"newStr"output-format"side-by-side"/>…...

GPT系列文章

GPT系列文章 GPT1 GPT1是由OpenAI公司发表在2018年要早于我们之前介绍的所熟知的BERT系列文章。总结&#xff1a;GPT 是一种半监督学习&#xff0c;采用两阶段任务模型&#xff0c;通过使用无监督的 Pre-training 和有监督的 Fine-tuning 来实现强大的自然语言理解。在 Pre-t…...

Qt实现可拖拽的矩形

之前项目上需要用Qt来绘制可拖拽改变形状的矩形。看了Qt Graphics相关的内容&#xff0c;虽然对Qt怎么添加图元的有了些了解&#xff0c;但是具体如何实现拖拽效果&#xff0c;一时也没有什么好的想法。还好网上有人分享的例子&#xff0c;很受启发。后来又回顾了一下这部分的代…...

python爬虫初体验(五)—— 边学边玩小游戏

1. 打开浏览器 利用webbrowser 模块的 open()函数可以启动一个新浏览器&#xff0c;打开指定的 URL。 import webbrowser webbrowser.open(http://inventwithpython.com/) 2. 猜数字游戏 # -*- coding: utf-8 -*- # This is a guess the number game. import randomsecretN…...

学习日志015--python单链表

创建 class Node:def __init__(self,data):# 数据域self.data data# 链接域self.next Noneclass LinkList:def __init__(self,):# 初始化头节点self.head None# 记录链表的长度self.size 0 增加 #头插def insert_head(self,value):# 创建新节点node Node(value)q self…...

51WORLD与南京水利研究院联合研发,国产数字孪生超融合一体机

近日&#xff0c;太湖流域水治理国际会议在江苏省无锡市举行。大会由水利部国际合作与科技司、河湖管理司、中国水利学会、水利部太湖流域管理局、无锡市人民政府、中国交通建设集团有限公司指导&#xff0c;南京水利科学研究院主办&#xff0c;以“践行新发展理念、推进流域水…...

自动泊车变自动撞车?小米SU7遭遇批量事故

科技新知 原创作者丨依蔓 编辑丨蕨影 小米系统bug&#xff0c;70多辆小米SU7同一天自动泊车撞墙、撞柱&#xff01; 近日&#xff0c;多名车主反映小米汽车SU7标准版“自动泊车”功能出现故障&#xff0c;造成不同程度的撞击、剐蹭损伤。 小米客服此前回应涉事车主&#xff0…...

异常和中断

在计算机系统中&#xff0c;异常和中断是两种常见的用于处理异步事件的机制。以下是常见的异常和中断及其特点的详细解释&#xff1a; 异常&#xff08;内中断&#xff09; 异常&#xff0c;也称为内中断&#xff0c;是由CPU内部事件引起的中断。异常通常与程序执行的当前指令…...

代理IP在后端开发中的应用与后端工程师的角色

目录 引言 代理IP的基本概念和工作原理 代理IP在后端开发中的应用 网络爬虫与数据采集 负载均衡与性能优化 安全防护与隐私保护 后端工程师在使用代理IP时面临的挑战 结论 引言 在数字化时代&#xff0c;网络技术的飞速发展极大地推动了各行各业的发展。其中&#xff…...

设计模式之 观察者模式

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听一个主题对象&#xff08;Subject&#xff09;。当主题对象的状态发生变化时&#xff0c;所有依赖于它的观察者都会得到…...

SQLSever显示物理和逻辑 IO活动量的相关信息及显示分析、编译和执行各语句所需的毫秒数。

SQLSever SET STATISTICS IO显示物理和逻辑 IO活动量的相关信息及SET STATISTICS TIME显示分析、编译和执行各语句所需的毫秒数。 1、 SET STATISTICS IO (Transact-SQL) 物理 IO 与访问磁盘上的数据页相关&#xff0c;逻辑 IO 与访问内存中的数据页&#xff08;数据缓存&…...

CSS3 动画:前端开发的动态美

CSS3 动画:前端开发的动态美 CSS3 动画是现代网页设计中不可或缺的一部分,它为静态的网页元素添加了动态效果,提升了用户体验。本文将深入探讨CSS3动画的基础知识、高级技巧,并展示如何在实际项目中应用这些动画。 CSS3 动画基础 CSS3动画主要通过@keyframes和动画属性(…...

JavaWeb之综合案例

前言 这一节讲一个案例 1. 环境搭建 然后就是把这些数据全部用到sql语句中执行 2.查询所有-后台&前台 我们先写后台代码 2.1 后台 2.2 Dao BrandMapper&#xff1a; 注意因为数据库里面的名称是下划线分割的&#xff0c;我们类里面是驼峰的&#xff0c;所以要映射 …...

基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】

&#x1f388;系统亮点&#xff1a;协同过滤算法、二维码识别&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框…...

使用 Maven 构建一个简单的 Java 项目

Apache Maven 是一个强大的构建自动化工具&#xff0c;主要用于 Java 项目。它简化了构建和管理任何基于 Java 的项目的流程。 本指南将涵盖 Maven 的安装、设置一个简单的 Java 项目以及使用 Maven 运行该项目。 1. 安装 安装 Java 在安装 Maven 之前&#xff0c;需要确保…...

【51单片机】LCD1602液晶显示屏

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 LCD1602存储结构时序结构 编码 —— 显示字符、数字 LCD1602 LCD1602&#xff08;Liquid Crystal Display&#xff09;液晶显示屏是…...

UDP协议

UDP&#xff08;UserDatagramProtocol&#xff09;是一个简单的传输层协议&#xff0c;特点&#xff1a;无连接、不可靠、面向数据包、全双工。 报文结构 1.源端口&#xff1a; 源端口号&#xff0c;需要对方回信时选用&#xff0c;不需要时全部置0. 2.目的端口&#xff1a;目…...

阅读 ADiffusion-Based Framework for Multi-Class Anomaly Detection

A Diffusion-Based Framework for Multi-Class Anomaly Detection 我觉得引言部分写的不错&#xff0c;将问题清楚的讲出来了&#xff0c;值得借鉴&#xff01;&#xff01; 摘要 基于重建的方法在异常检测方面取得了显著成果。最近流行的扩散模型的卓越图像重建能力引发了研…...

网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操解析1

文章目录 1、RAID6配置指南&#xff08;大致步骤&#xff09;2、注意事项3、截图和视频 网络云计算】2024第47周-每日【2024/11/21】周考-实操题-RAID6实操 RAID6是一种在存储系统中实现数据冗余和容错的技术&#xff0c;其最多可以容忍两块磁盘同时损坏而不造成数据丢失。RAID…...

ts- declare关键词及vue3报错“Window typeof globalThis”上不存在属性“nextLoading”、`

报错“Window & typeof globalThis”上不存在属性“nextLoading”、 代码环境&#xff1a;vue3、ts 阮一峰讲解 declarets 用法告诉编译器某个类型是存在的 下面的例子是脚本使用浏览器全局对象document。 declare var document; document.title "Hello";上面…...

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…...

【单点知识】基于PyTorch讲解自动编码器(Autoencoder)

文章目录 0. 前言1. 自动编码器的基本概念1.1 定义1.2 目标1.3 结构 2. PyTorch实现自动编码器2.1 导入必要的库2.2 定义自动编码器模型2.3 加载数据2.4 训练自动编码器 3. 自动编码器的意义4. 自动编码器的应用4.1 图像处理4.2自然语言处理&#xff1a;4.3推荐系统&#xff1a…...

html+js实现图片的放大缩小等比缩放翻转,自动播放切换,顺逆时针旋转

效果图&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>图片预览</title><sty…...

【蓝桥杯C/C++】翻转游戏:多种实现与解法解析

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;题目&#x1f4af;问题分析解法一&#xff1a;减法法解法二&#xff1a;位运算解法解法三&#xff1a;逻辑非解法解法四&#xff1a;条件运算符解法解法五&#xff1a;数组映射法不同解法的比较…...

介绍一下toupper(ch);函数(c基础)

hi , I am 36 适合对象c语言初学者 toupper(ch1); tolower(ch2); 是返回ch的大写或小写的字符但并不改变ch 若传递数字仍返回该数字 格式 #include<ctype.h> char res toupper(ch); 链接扫雷游戏代码分享(c基础)-CSDN博客 hi , I am 36. thanks for your look…...