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

深入理解分布式锁——以Redis为例

一、分布式锁简介

1、什么是分布式锁
分布式锁是一种在分布式系统环境下,通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据,从而避免数据的不一致性。

  • 线程锁:
    也被称为互斥锁(Mutex),主要用于控制同一进程中的多个线程对共享资源的访问。
  • 进程锁:
    进程锁是用于控制同一台机器上的多个进程对共享资源的访问。进程锁可以是系统级的,如文件锁,也可以是用户级的,如信号量(Semaphore)。
  • 分布式锁:
    分布式锁是用于控制分布式系统中的多个节点对共享资源的访问。由于分布式系统中的节点可能位于不同的机器甚至不同的地理位置,因此分布式锁的实现比线程锁和进程锁要复杂得多。分布式锁需要在网络中的多个节点之间进行协调,以保证锁的唯一性和一致性。
    2、分布式锁的特性
    分布式锁主要有以下几个特性:
    互斥性:在任何时刻,只有一个节点可以持有锁。
    不会发生死锁:如果一个节点崩溃,锁可以被其他节点获取。
    公平性:如果多个节点同时申请锁,系统应该保证每个节点都有获取锁的机会。
    可重入性:同一个节点可以多次获取同一个锁,而不会被阻塞。
    高可用:锁服务应该是高可用的,不能因为锁服务的故障而影响整个系统的运行。

二、分布式锁的基本原理

分布式锁的基本步骤分布式锁的基本原理可以分为以下几个步骤:
请求锁:当一个实例需要访问共享资源时,它会向分布式锁系统发送一个请求,试图获取一个锁。
锁定资源:分布式锁系统会检查是否有其他实例已经持有这个锁。如果没有,那么这个实例就会获得锁,并且有权访问共享资源。如果有,那么这个实例就必须等待,直到锁被释放。
访问资源:一旦实例获取了锁,它就可以安全地访问共享资源,而不用担心其他实例会同时访问这个资源。
释放锁:当实例完成对共享资源的访问后,它需要通知分布式锁系统释放锁。这样,其他正在等待的实例就可以获取锁,访问共享资源。
在这里插入图片描述
2. 分布式锁实现的关键点
在实现分布式锁时,通常会有一个中心节点(或者称为锁服务),所有需要获取锁的节点都需要向这个中心节点申请。
当一个节点申请锁时,中心节点会检查当前是否有其他节点持有锁,如果没有,则将锁分配给申请的节点;如果有,则拒绝申请。当持有锁的节点完成操作后,会向中心节点归还锁,此时其他的节点可以再次申请锁。
在这里插入图片描述

三、基于Redis的分布式锁

Redis的基本介绍Redis是一个开源的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息代理。
Redis 提供了多种命令和能力来支持实现分布式锁SETNX 命令:
SETNX(Set if Not Exists)命令用于在 key 不存在时设置值。这是实现分布式锁的关键命令,因为它能确保在同一时间只有一个客户端能够获得锁。EXPIRE 命令:
EXPIRE 命令用于为 key 设置过期时间。这对于避免死锁非常重要,因为即使某个客户端崩溃,锁也会在一定时间后自动释放。
DEL 命令:DEL 命令用于删除 key。在释放锁时,需要使用此命令删除对应的 key。
Lua 脚本:Redis 支持使用 Lua 脚本来执行一系列原子操作。这对于实现安全的分布式锁非常有用,因为它可以确保在释放锁时检查锁的持有者。
RedLock 算法:Redis 官方推荐了一种名为 RedLock 的分布式锁算法。RedLock 是一种基于多个 Redis 实例的分布式锁算法,旨在提供更高的安全性和容错能力。
一般,在实现Redis分布式锁时,不分开使用SETNX和EXPIRE命令,而是使用SETNX的拓展命令 SET NX EX

 示例:SET my_key my_value NX EX 10 # 设置键值对, 超时时间为10s。 如果my_key存在,则不进行任何操作
  1. Redis实现分布式锁的基本实现请求锁假设我们有一个 Redis 键 my_lock,用于表示锁的状态。当一个客户端想要获取锁时,它会尝试使用 SETNX 命令来设置这个键。
SET my_lock<unique_value> NX EX <lock_timeout>

如果命令返回 OK,则表示客户端成功获取了锁。如果返回 nil,则表示锁已被其他客户端持有。<unique_value>: 一个唯一的值,比如 UUID,用于标识锁的持有者。
NX: 只有当 my_lock 不存在时,才会设置该键。这确保了同一时间只有一个客户端能获得锁。
EX <lock_timeout>: 设置锁的过期时间,防止因客户端崩溃而导致的死锁。
锁续期为了防止锁过早地因为过期而被释放,可以在锁快到期时进行续期操作。这可以通过定期检查锁的剩余时间,并在必要时使用 EXPIRE 命令来更新过期时间来实现。

检查锁是否仍由当前客户端持有

if redis.call("get", "my_lock") ==<unique_value>" then# 续期锁redis.call("EXPIRE", "my_lock", <new_lock_timeout>)
end

注意:上述代码是一个简化的 Lua 脚本示例,实际应用中可能需要更复杂的逻辑来处理续期操作。
释放锁当客户端完成需要加锁保护的操作后,应该释放锁。为了确保只有锁的持有者才能释放锁,可以使用 Lua 脚本来执行释放操作。

if redis.call("get", "my_lock") ==<unique_value>" thenreturn redis.call("del", "my_lock")
elsereturn 0 -- 锁未被当前客户端持有,无法释放
end

这个 Lua 脚本首先检查锁是否仍由当前客户端持有,如果是,则删除 my_lock 键以释放锁。
3. Redis分布式锁的使用场景Redis分布式锁可以用于所有需要在分布式环境中同步访问共享资源的场景。例如,电商秒杀活动中,为了防止超卖,可以使用Redis分布式锁来保证同一时刻只有一个请求可以操作库存。又如,在分布式计算中,为了防止重复计算,可以使用Redis分布式锁来保证同一时刻只有一个节点可以进行计算。
4. Redis分布式锁的优点和缺点
优点:性能高:由于Redis是基于内存的,因此Redis分布式锁的性能非常高。实现简单:Redis提供的命令可以很容易地实现分布式锁。
缺点:不可重入:Redis分布式锁默认是不可重入的,如果需要可重入,需要额外的逻辑来实现。非阻塞:Redis分布式锁是非阻塞的,如果获取锁失败,需要自己进行重试。安全性:如果Redis服务器出现故障,可能会导致锁无法正常工作。

四、其他分布式锁的实现方式

  1. 基于数据库的分布式锁
    数据库分布式锁是通过在数据库中创建一个锁表,表中包含锁的名称和锁的状态等信息。
    当一个节点需要获取锁时,它会在这个表中插入一条记录,如果插入成功,那么这个节点就获取到了锁。当节点使用完锁后,会删除这条记录,从而释放锁。
    这种方式的优点是实现简单,缺点是性能较低,且如果数据库出现故障,可能会影响到锁的功能。
  2. 基于Zookeeper的分布式锁
    Zookeeper是一个开源的分布式协调服务,它提供了一种高效且可靠的分布式锁实现方式。
    在Zookeeper中,可以创建一个临时节点作为锁,当一个节点需要获取锁时,它会尝试创建这个临时节点,如果创建成功,那么这个节点就获取到了锁。
    当节点使用完锁后,会删除这个临时节点,从而释放锁。如果节点崩溃,Zookeeper会自动删除这个临时节点,从而避免了死锁的问题。
  3. 基于Etcd的分布式锁Etcd是一个开源的分布式键值存储系统,它也提供了一种分布式锁的实现方式。Etcd的分布式锁是通过创建一个带有TTL(Time To Live)的键值对来实现的,当一个节点需要获取锁时,它会尝试创建这个键值对,如果创建成功,那么这个节点就获取到了锁。当节点使用完锁后,会删除这个键值对,从而释放锁。如果节点崩溃,Etcd会自动删除这个键值对,从而避免了死锁的问题。
  4. 各种实现方式的比较
    在这里插入图片描述

五、分布式锁的常见问题和解决方案

  1. 死锁问题
    问题:当一个客户端获取了锁,但由于某些原因(如程序崩溃、异常等)无法释放锁时,会导致其他客户端永远无法获取锁。
    解决方案:设置锁的过期时间。当锁的持有者未能在过期时间内执行完毕并释放锁时,锁将自动过期,从而允许其他客户端获取锁。
  2. 锁续命问题
    问题:如果一个操作需要的时间可能超过锁的过期时间,那么在操作执行过程中锁过期会导致其他客户端获取到锁,从而产生并发问题。
    解决方案:使用锁续命机制。在锁持有者执行操作期间,可以定期检查锁是否即将过期,并在适当的时候对锁进行续命,即重新设置锁的过期时间。
    在这里插入图片描述
  3. 锁释放问题
    问题:为确保数据的一致性,只有锁的持有者才能释放锁。但在实际应用中,可能会出现误解锁的情况。
    解决方案:在设置锁时,为锁关联一个唯一的值(如UUID)。在释放锁时,先检查锁的值是否与当前客户端的值匹配,如果匹配则释放锁,否则不做任何操作。注意,锁持有人的判断和锁的释放应该在一个原子操作内完成。
  4. 锁的公平性问题
    问题:在高并发环境中,如果多个节点同时请求获取锁,可能会出现“饥饿”现象,即某些节点长时间无法获取到锁。
    解决方案:引入队列,将请求锁的节点按照顺序排队。例如,在Zookeeper中,可以使用顺序节点来实现公平锁。
  5. 锁的可重入性问题
    问题:在某些场景中,一个节点可能需要多次获取同一个锁,如果锁不支持重入,可能会导致死锁。解决方案:为锁添加一个拥有者的概念,只有锁的拥有者才能再次获取到锁。例如,在Redis中,可以将锁的值设置为节点的唯一标识,获取锁时检查锁的值是否为自己的标识。
  6. 锁的安全性问题
    问题:如果分布式锁的存储系统(如Redis、Zookeeper等)出现故障,可能会导致锁无法正常工作。
    解决方案:使用高可用的存储系统,如使用Redis集群或Zookeeper集群。另外,可以使用心跳机制来检测存储系统的状态,如果检测到故障,可以及时进行切换。

相关文章:

深入理解分布式锁——以Redis为例

一、分布式锁简介 1、什么是分布式锁 分布式锁是一种在分布式系统环境下&#xff0c;通过多个节点对共享资源进行访问控制的一种同步机制。它的主要目的是防止多个节点同时操作同一份数据&#xff0c;从而避免数据的不一致性。 线程锁&#xff1a; 也被称为互斥锁&#xff08…...

OrangePi Zero 3学习笔记(Android篇)1 - 搭建环境

目录 1. 下载安装Ubuntu22.04 1.1 安装增强功能 1.2 设置共享文件夹 1.3 创建AOSP.vdi 1.4 更新相关软件包 2. 解压AOSP源代码 3. 编译代码 3.1 编译uboot/Linux 3.2 编译AOSP源代码 3.3 内存问题调试记录 3.3.1 查看具体什么问题 3.3.2 关闭dex2oat&#xff08;无…...

RabbitMq(尚硅谷)

RabbitMq 1.RabbitMq异步调用 2.work模型 3.Fanout交换机&#xff08;广播模式&#xff09; 4.Diret交换机&#xff08;直连&#xff09; 5.Topic交换机&#xff08;主题交换机&#xff0c;通过路由匹配&#xff09; 6.Headers交换机&#xff08;头交换机&#xff09; 6…...

OpenAI的“四面楚歌”:从营利到非营利,一场关于AGI控制权的革命

引言 当“奥特曼妥协”与“四面楚歌”并置时&#xff0c;OpenAI的这次重大调整&#xff0c;仿佛在科技史上投下一颗震撼弹。这家曾因“拒绝盈利”而备受争议的人工智能公司&#xff0c;如今却在资本与理想之间艰难抉择——放弃营利性转型&#xff0c;回归非营利初心。这不仅是对…...

[250505] Arch Linux 正式登陆 Linux 的 Windows 子系统

目录 Arch Linux 正式登陆 Windows Subsystem for Linux (WSL) Arch Linux 正式登陆 Windows Subsystem for Linux (WSL) Arch Linux 社区与 Microsoft 合作&#xff0c;正式宣布 Arch Linux 现已提供官方的 Windows Subsystem for Linux (WSL) 镜像。这意味着 Windows 用户现…...

MySQL 日期格式化:DATE_FORMAT 函数用法

MySQL 日期格式化&#xff1a;DATE_FORMAT 函数用法 在 MySQL 中&#xff0c;DATE_FORMAT() 函数用于将日期或时间值格式化为指定的字符串格式。 正确语法 DATE_FORMAT(date, format)常用格式说明符 说明符描述%Y四位数的年份&#xff08;例如&#xff1a;2023&#xff09;…...

java springboot解析出一个图片的多个二维码

引入 <dependencies><!-- ZXing --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.google.zxing…...

【四川省专升本计算机基础】第一章 计算机基础知识(上)

前言 对计算机专业的同学来说这门课程可能很简单&#xff0c;容易拿高分&#xff08;125分以上&#xff09;&#xff0c;但也可能很容易大意丢分。因为本门课程人称&#xff1a;背多分。大意丢分者的心态觉得计算机基础都学过&#xff0c;内容很简单&#xff0c;最后才开始背计…...

406错误,WARN 33820 --- [generator] [nio-8080-exec-4] .w.s.m.s.DefaultHa

在接口调用过程中&#xff0c;后端出现.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation]错误。检查了一个小时才发现我返回的对象没有写getter方法&#xff0c; 当Spring B…...

基于STM32、HAL库的SST26VF064B NOR FLASH存储器驱动应用程序设计

一、简介: SST26VF064B是Microchip公司生产的一款64Mbit(8MB)串行闪存器件,采用SPI接口通信,具有以下特点: 工作电压:2.7-3.6V 最高104MHz时钟频率 统一4KB扇区结构 快速擦除和编程时间 低功耗特性 支持标准SPI、Dual SPI和Quad SPI模式 二、硬件接口: STM32L4引脚SST26V…...

美信监控易:全栈式自主可控的底层架构优势

在当今数字化时代&#xff0c;企业的运维管理面临着越来越多的挑战。为了确保业务的稳定运行&#xff0c;企业需要一款高效、可靠的运维管理软件。北京美信时代的美信监控易运维管理软件&#xff0c;以其全栈式自主可控的底层架构优势&#xff0c;成为了运维团队的理想选择。 …...

Class AB OPA corner 仿真,有些corenr相位从0开始

Class AB OPA做 STB 仿真时&#xff0c;会遇到有些corner(c0_0、c0_4、c0_5)相位从0开始的情况。 首先应该去检查电路&#xff0c;电路里是否有正反馈&#xff1b;排除没有正反馈后&#xff0c;考虑是图中的红框中的线性跨导环中的Vds 太大导致了碰撞电离导致的。 查找了网上…...

【JEECG】BasicTable单元格编辑,插槽添加下拉组件样式错位

1.功能说明 BasicTable表格利用插槽&#xff0c;添加组件实现单元格编辑功能&#xff0c;选择组件下拉框错位 2.效果展示 3.解决方案 插槽内组件增加&#xff1a;:getPopupContainer"getPopupContainer" <template #salesOrderProductStatus"{ column, re…...

第十五届蓝桥杯单片机国赛-串口解析

串口通信像是蓝桥杯单片机组国赛中一个若隐若现的秘境&#xff0c;总在不经意间为勇者们敞开大门。然而&#xff0c;初次探索这片领域的冒险者&#xff0c;常常会被其神秘莫测的特性所震慑&#xff0c;黯然退场&#xff08;编不下去了&#xff0c;直接进入正题&#xff09;。 附…...

Flutter开发HarmonyOS实战-鸿蒙App商业项目

Flutter开发HarmonyOS实战内容介绍&#xff1a; Flutter开发HarmonyOS 鸿蒙App商业项目&#xff08;小米商城APP&#xff09;实战视频教程 Flutter开发鸿蒙APP是在《FlutterGetx仿小米商城》项目基础之上讲解的&#xff0c;调试Flutter HarmonyOS应用需要有HarmonyOS Next的手机…...

【回眸】香橙派Zero2 超声波模块测距控制SG90舵机转动

前言 知识准备 超声波模块时序图 gettimeofday()函数作用 gettimeofday()函数原型 tv结构体 获取当前系统时间与格林威治时间的时间差 获取香橙派数10万秒花费的时间 使用超声波模块获取到障碍物距离 SG90舵机模块 舵机模块的作用 舵机模块方波时序图 舵机模块工作原…...

RabbitMQ 添加新用户和配置权限

以下是关于使用 sudo rabbitmqctl add_user 命令创建新用户的详细示例&#xff0c;同时包含创建用户后进行权限设置、角色设置等相关操作的示例。 1. 前提条件 确保你的 RabbitMQ 服务已经正常运行&#xff0c;并且你具有执行 sudo 命令的权限。 2. 创建新用户 假设我们要创…...

【前缀和】矩阵区域和

文章目录 1314. 矩阵区域和解题思路1314. 矩阵区域和 1314. 矩阵区域和 ​ 给你一个 m x n 的矩阵 mat 和一个整数 k ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和: i - k <= r <= i + k, j - k <= c <= j + k …...

编程日志4.25

栈的stl模板 可直接用<stack>库进行调用 #include<iostream> #include<stack>//栈的模板库 using namespace std; int main() { stack<int> intStk;//整数 栈 stack<double> doubleStk;//浮点数 栈 intStk.push(1); intStk.pu…...

【中间件】brpc之工作窃取队列

文章目录 BRPC Work Stealing Queue1 核心功能2 关键数据结构2.1 队列结构2.2 内存布局优化 3 核心操作3.1 本地线程操作&#xff08;非线程安全&#xff09;3.2 窃取操作&#xff08;线程安全&#xff09; 4 设计亮点4.1 无锁原子操作4.2 环形缓冲区优化4.3 线程角色分离 5 性…...

用OMS从MySQL迁移到OceanBase,字符集utf8与utf8mb4的差异

一、问题背景 在一次从MySQL数据库迁移到OceanBase的MySQL租户过程中&#xff0c;出现了一个转换提示&#xff1a; [WARN][CONVER] he table charset:utf8->utf8mb4&#xff0c; 你可能会担心这种转换可能导致字符集不兼容的问题。但通过查阅相关资料可知&#xff0c;utf8m…...

知乎前端面试题及参考答案

Webpack 和 Vite 的区别是什么? 构建原理: Webpack 是基于传统的打包方式,它会将所有的模块依赖进行分析,然后打包成一个或多个 bundle。在开发过程中,当代码发生变化时,需要重新构建整个项目,构建速度会随着项目规模的增大而变慢。Vite 利用了浏览器对 ES 模块的支持,…...

项目中为什么选择RabbitMQ

当被问及为什么选择某种技术时&#xff0c;应该结合开发中的实际情况以及类似的技术进行分析&#xff0c;适合的技术才是最好的。 在项目中为什么选择RabbitMQ 作为消息中间件&#xff0c;主要可以基于以下几方面进行分析&#xff1a; 1. 可靠性 消息持久化&#xff1a;Rabbi…...

深入解析二维矩阵搜索:LeetCode 74与240题的两种高效解法对比

文章目录 [toc]**引言** **一、问题背景与排序规则对比****1. LeetCode 74. 搜索二维矩阵****2. LeetCode 240. 搜索二维矩阵 II** **二、核心解法对比****方法1&#xff1a;二分查找法&#xff08;适用于LeetCode 74&#xff09;****方法2&#xff1a;线性缩小搜索范围法&…...

Qt案例 以单线程或者单生产者多消费者设计模式实现QFTP模块上传文件夹功能

前文:Qt案例 使用QFtpServerLib开源库实现Qt软件搭建FTP服务器,使用QFTP模块访问FTP服务器 已经介绍了Qt环境下搭建FTP服务器或者使用QFTP上传的方式示例, 这里主要介绍下使用QFTP模块上传整个文件夹的案例示例。 目录导读 前因后果单线程处理1.定义FTPFolderUpload 继承 QT…...

含锡废水回收率提升技术方案

一、预处理环节优化 物理分离强化 采用双层格栅系统&#xff08;孔径1mm0.5mm&#xff09;拦截悬浮物&#xff0c;配套旋流分离器去除密度>2.6g/cm的金属颗粒&#xff0c;使悬浮物去除率提升至85%。增设pH值智能调节模块&#xff0c;通过在线pH计联动碳酸钠/氢氧化钠投加系…...

第八章,STP(生成树协议)

广播风暴----广播帧在二层环路中形成逆时针或顺时针的转动的环路&#xff0c;并且无限循环&#xff0c;最终导致设备宕机&#xff0c;网络瘫痪。 MAC地址表的翻摆&#xff08;漂移&#xff09;----同一个数据帧&#xff0c;顺时针接收后将记录MAC地址及接口的对应信息&#xff…...

《面向对象程序设计-C++》实验五 虚函数的使用及抽象类

程序片段编程题 1.【问题描述】 基类shape类是一个表示形状的抽象类&#xff0c;area( )为求图形面积的函数。请从shape类派生三角形类(triangle)、圆类&#xff08;circles&#xff09;、并给出具体的求面积函数。注&#xff1a;圆周率取3.14 #include<iostream> #in…...

PCIe - ZCU106(RC) + KU5P(EP) + 固化

目录 1. 简介 1.1 Data Mover 1.2 描述符 2. ZCU102 2.1 Ubuntu OS 2.2 USB Host 2.2.1 连接拓扑 2.2.2 设备类型 2.2.3 USB 跳帽设置 2.3 无线网卡 2.4 PCIe Info 2.4.1 Diagram 2.4.2 lspci -tv 2.4.3 lspci -v 2.4.2.1 设备基本信息 2.4.2.2 控制与状态寄存…...

网络编程核心技术解析:从Socket基础到实战开发

网络编程核心技术解析&#xff1a;从Socket基础到实战开发 一、Socket编程核心基础 1. 主机字节序与网络字节序&#xff1a;数据传输的统一语言 在计算机系统中&#xff0c;不同架构对多字节数据的存储顺序存在差异&#xff0c;而网络通信需要统一的字节序标准&#xff0c;这…...

SQL注入总结

一.sql注入 原理&#xff1a;当一个网站存在与用户交互的功能&#xff08;如登录表单、搜索框、评论区等&#xff09;&#xff0c;并且用户输入的数据未经充分过滤或转义&#xff0c;直接拼接到后台数据库查询语句中执行时&#xff0c;就可能引发SQL注入漏洞。攻击者可以通过构…...

conda 安装cudnn

通过 Conda 安装 cuDNN 确保你有 NVIDIA GPU 和 CUDA Toolkit&#xff1a;首先&#xff0c;确保你的系统上安装了 NVIDIA GPU 和 CUDA Toolkit。你可以通过运行以下命令来检查 CUDA 是否已安装&#xff1a;nvcc --version 如果没有安装 CUDA&#xff0c;你需要先从 NVIDIA CU…...

强啊!Oracle Database 23aiOracle Database 23ai:使用列别名进行分组排序!

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; 从 Oracle Database 23ai 开始&#xff0c;您可以在 GROUP BY 和 HAVING 子句中直接使用列别名。此功能在早期版本的 Oracle Database 中不…...

RAG 2.0 深入解读

一、Introduction 过去一年可谓是RAG元年&#xff0c;检索增强生成技术迅速发展与深刻变革&#xff0c;其创新与应用已深刻重塑了大模型落地的技术范式。站在2025年&#xff0c;RAG不仅突破了早期文本处理的局限&#xff0c;更通过多模态融合、混合检索优化和语义鸿沟跨越等突…...

Excel Vlookup

VLOOKUP(A2, Sheet2!A:B, 2, 0) 代表的是检查A2,匹配源是sheet2表AB两列 Sheet2!A:B&#xff1a;指定要在其中查找数据的范围&#xff0c;这里是 Sheet12中的 A 列和 B 列&#xff0c;A 列是查找的依据列&#xff0c;B 列是要返回值的列。2&#xff1a;表示要返回查找区域中的…...

css媒体查询及css变量

媒体查询是 CSS 样式表最重要的功能之一&#xff0c;所谓媒体查询指的就是根据不同的媒体类型&#xff08;设备类型&#xff09;和条件来区分各种设备&#xff08;例如&#xff1a;电脑、手机、平板电脑、盲文设备等&#xff09;&#xff0c;并为它们分别定义不同的 CSS 样式。…...

CSS网格布局

网格布局将元素占用的空间划分为二维格子&#xff0c;下级元素放置在格子所在的位置上。划分格子的元素叫做网格容器&#xff0c;其 display 属性是 grid &#xff08;块元素&#xff09;或 inline-grid &#xff08;内联块元素&#xff09;。网格容器的下级元素叫做网格项。容…...

Windows远程连接MySQL报错,本地navicat能连接MySQL

一、报错 telnet 119.87.111.79 3306​​“无法打开到主机的连接。在端口 3306: 连接失败”​​ 表明无法通过 TCP 协议连接到目标服务器的 3306 端口。 二、目的 &#xff08;1&#xff09;​​Telnet 测试的目的​​ Telnet 仅用于测试 ​​TCP 端口是否开放​​&#xff…...

Github打不开怎么办?

国内无法打开github&#xff0c;使有watt toolkit一键加速即可打开。 加速器 加速器直接加速Github原站&#xff0c;在开发者使用或者需要登录账号时非常有效 Watt Toolkit&#xff08;原Steam&#xff09; 官网地址&#xff1a;Watt Toolkit 一、进入官网后&#xff0c;点…...

亿级流量系统架构设计与实战(四)

本章关键词 : 读 / 写分离 、 数据缓存 、 缓存更新 、 CQRS 、 数据分片 、 异步写。 高并发架构设计的要点 形成高并发系统的必要条件 高性能、高可用、可扩展。 高性能: 性能代表一个系统的并行处理能力,在同样的硬件设备条件下 , 性能越高 , 越能节约硬件资源。高可…...

Java基础问题——八股盛宴 | 3w字分享

目录 面向对象与面向过程的区别&#xff1f; Java面向对象有哪些特征&#xff0c;如何应用&#xff1f; 介绍下Java中的四种引用&#xff1f; Java中创建对象有几种方式&#xff1f; Java中的序列化和反序列化是什么&#xff1f; 什么是Java中不可变类&#xff1f; Java…...

保障企业的数据安全需要做什么?

守护企业数据安全&#xff0c;犹如构筑一座固若金汤的城堡&#xff0c;需要从技术壁垒、管理护城河、流程吊桥和人员守卫等多维度精心布局&#xff0c;打造环环相扣的立体防御体系。我们从以下关键项分析&#xff1a; 一、技术层面 数据加密 对敏感数据&#xff08;如客户信息、…...

Flutter开发IOS蓝牙APP的大坑

Core Bluetooth 框架限制&#xff1a;iOS 的 Core Bluetooth 框架存在限制&#xff0c;如果指定的特征配置同时允许通知&#xff08;Notifications&#xff09;和指示&#xff08;Indications&#xff09;&#xff0c;调用相关方法设置通知值时&#xff0c;默认仅会开启通知功能…...

LeetCode 解题思路 45(分割等和子集、最长有效括号)

解题思路&#xff1a; dp 数组的含义&#xff1a; 在数组中是否存在一个子集&#xff0c;其和为 i。递推公式&#xff1a; dp[i] | dp[i - num]。dp 数组初始化&#xff1a; dp[0] true。遍历顺序&#xff1a; 从大到小去遍历&#xff0c;从 i target 开始&#xff0c;直到 …...

AI Agent 入门指南:从 LLM 到智能体

AI. AI. AI. 最近耳朵里是不是总是被这些词轰炸&#xff1f;特别是“Agent”、“AI Agent”、“智能体”、“Agentic”…… 感觉一夜之间&#xff0c;AI 就从我们熟悉的聊天框里蹦出来&#xff0c;要拥有“独立思考”和“自主行动”的能力了&#xff1f; 说实话&#xff0c;一…...

高级java每日一道面试题-2025年5月02日-基础篇[反射篇-编码]-使用反射,获取Class对象

如果有遗漏,评论区告诉我进行补充 面试官: 编写代码通过三种方式&#xff08;类名.class、对象.getClass()、Class.forName()&#xff09;获取java.util.ArrayList的Class对象。 我回答: 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#…...

【bug】fused_bias_act_kernel.cu卡住没反应

简述 在推理人脸修复face restoration算法 GPEN的时候&#xff0c;发现有时候fused_bias_act_kernel.cu卡住没反应。 解决 清理下缓存&#xff0c;让程序自己再编译下...

小游戏(2)扫雷游戏

一、简述 鸽子的时间太长了&#xff0c;其实学完数组和函数就应该搞出来这个丐版的小游戏了&#xff0c;不耽误&#xff0c;反正总归是轮到了&#xff0c;嘻嘻。 二、依旧菜单\. 我们这里写的是一个丐版的扫雷游戏&#xff0c;难度就固定了&#xff0c;所以菜单写起来就是玩游…...

如何在vscode中set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`

1.打开工作区设置文件 在 VS Code 中通过文件 -> 首选项 -> 设置&#xff0c;接着在设置窗口的右上角点击打开设置&#xff08;JSON&#xff09;&#xff0c;这会打开settings.json文件。 2.添加环境变量设置 "terminal.integrated.env.linux": { "TF_EN…...

leetcode 24. 两两交换链表中的节点

题目描述 代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next…...