【Redis】redis用作缓存和分布式锁
文章目录
- 1. 缓存
- 1.1 Redis作为缓存
- 1.2 缓存更新、淘汰策略
- 1.3 缓存预热、缓存穿透、缓存雪崩和缓存击穿
- 1.3.1 缓存预热(preheating)
- 1.3.2 缓存穿透(penetration)
- 1.3.3 缓存雪崩(avalanche)
- 1.3.4 缓存击穿(breakdown)
- 2. 分布式锁
- 2.1 什么是分布式锁?
- 2.2 分布式锁的基础实现
- 2.3 引入过期时间(防止“死锁”问题)
- 2.4 引入校验id(防止锁误删问题)
- 2.5 引入lua(解决原子性问题)
- 2.6 引入watchdog(解决过期时间不足问题)
- 2.7 引入Redlock算法(防止redis挂了)

1. 缓存
Redis最主要的三个功能
- 存储数据(内存数据库)
- 缓存
- 消息队列
1.1 Redis作为缓存
在⼀个网站中,我们经常会使⽤关系型数据库(比如MySQL)来存储数据;关系型数据库虽然功能强大,但是有⼀个很大的缺陷,就是性能不高(换言之,进⾏⼀次查询操作消耗的系统资源较多)
硬件的访问速度通常是如下情况下:CPU寄存器 > 内存 > 硬盘 > ⽹络
为什么说关系型数据库性能不⾼?
- 数据库把数据存储在硬盘上,硬盘的IO速度并不快,尤其是随机访问.
- 如果查询不能命中索引,就需要进⾏表的遍历,这就会大大增加硬盘IO次数.
- 关系型数据库对于SQL的执行会做⼀系列的解析、校验、优化⼯作.
- 如果是⼀些复杂查询,⽐如联合查询,需要进⾏笛卡尔积操作,效率更是降低很多.
因此,如果访问数据库的并发量⽐较⾼,对于数据库的压⼒是很⼤的,很容易就会使数据库服务器宕机
如何让数据库能够承担更⼤的并发量呢?核心思路主要是两个:
- 开源:引⼊更多的机器,部署更多的数据库实例,构成数据库集群.(主从复制,分库分表等…)
- 节流:引⼊缓存,使⽤其他的⽅式保存经常访问的热点数据,从⽽降低直接访问数据库的请求数量
Redis 就是⼀个⽤来作为数据库缓存的常⻅⽅案,Redis访问速度⽐MySQL快很多,或者说处理同⼀个访问请求,Redis消耗的系统资源⽐MySQL少很多,因此Redis能⽀持的并发量更⼤.
- Redis数据在内存中,访问内存⽐硬盘快很多.
- Redis只是⽀持简单的key-value存储,不涉及复杂查询的那么多限制规则.
1.2 缓存更新、淘汰策略
redis作为缓存,一般存储的热点数据,那么如何知道哪些数据是热点数据呢?
- 定期生成
每隔⼀定的周期(⽐如⼀天/⼀周/⼀个⽉),对于访问的数据频次进⾏统计,挑选出访问频次最⾼的前N%的数据
这种做法实时性较低.对于⼀些突然情况应对的并不好
- 实时生成
先给缓存设定容量上限(可以通过Redis配置⽂件的maxmemory 参数设定).
接下来把用户每次查询:
- 如果在Redis查到了,就直接返回.
- 如果Redis中不存在,就从数据库查,把查到的结果同时也写⼊Redis.
如果缓存已经满了(达到上限),就触发缓存淘汰策略,把⼀些"相对不那么热门"的数据淘汰掉。照上述过程,持续⼀段时间之后Redis内部的数据⾃然就是"热门数据"了.
通⽤的淘汰策略主要有以下⼏种:
- FIFO (First In First Out) 先进先出:把缓存中存在时间最久的(也就是先来的数据)淘汰掉
- LRU(LeastRecentlyUsed)淘汰最久未使⽤的:记录每个key的最近访问时间,把最近访问时间最⽼的key淘汰掉
- LFU(LeastFrequently Used)淘汰访问次数最少的:记录每个key最近⼀段时间的访问次数,把访问次数最少的淘汰掉
- Random随机淘汰:从所有的key中抽取幸运⼉被随机淘汰掉
这⾥的淘汰策略,我们可以自己实现,当然Redis也提供了内置的淘汰策略,也可以供我们直接使用,下面罗列了一部分:
整体来说Redis提供的策略和我们上述介绍的通⽤策略是基本⼀致的,只不过Redis这⾥会针对"过期key" 和"全部key"做分别处理.
1.3 缓存预热、缓存穿透、缓存雪崩和缓存击穿
1.3.1 缓存预热(preheating)
使⽤Redis作为MySQL的缓存的时候,当Redis刚刚启动,或者Redis⼤批key失效之后,此时由于Redis 自身相当于是空着的,没啥缓存数据,那么MySQL就可能直接被访问到,从⽽造成较⼤的压⼒
因此就需要提前把热点数据准备好,直接写⼊到Redis中,使Redis可以尽快为MySQL撑起保护伞
热点数据可以基于之前介绍的统计的⽅式⽣成即可,这份热点数据不⼀定非得那么"准确",只要能帮助MySQL抵挡大部分请求即可,随着程序运⾏的推移,缓存的热点数据会逐渐自动调整,来更适应当前情况
1.3.2 缓存穿透(penetration)
访问的key在Redis和数据库中都不存在,此时这样的key不会被放到缓存上,后续如果仍然在访问该key, 依然会访问到数据库,这就会导致数据库承担的请求太多,压⼒很⼤,这种情况称为缓存穿透
为何产⽣?原因可能有几种:
- 业务设计不合理,比如缺少必要的参数校验环节,导致非法的key也被进⾏查询了
- 开发/运维误操作,不小心把部分数据从数据库上误删了
- ⿊客恶意攻击
如何解决?
- 针对要查询的参数进⾏严格的合法性校验
- ⽐如要查询的key是⽤⼾的⼿机号,那么就需要校验当前key 是否满⾜⼀个合法的⼿机号的格式
- 针对数据库上也不存在的key,也存储到Redis中
- ⽐如value就随便设成⼀个"",避免后续频繁访问数据库.
- 使⽤布隆过滤器先判定key是否存在,再真正查询
1.3.3 缓存雪崩(avalanche)
短时间内大量的key在缓存上失效,导致数据库压力骤增,甚⾄直接宕机,这种情况叫做缓存雪崩
本来Redis是MySQL的⼀个护盾,帮MySQL抵挡了很多外部的压⼒,⼀旦护盾突然失效了,MySQL⾃⾝承担的压⼒骤增,就可能直接崩溃.
产⽣大规模key失效,可能性主要有两种:
- Redis挂了.
- Redis上的大量的key同时过期
为啥会出现⼤量的key同时过期?这种可能是短时间内在Redis上缓存了⼤量的key,并且设定了相同的过期时间.
如何解决?
- 部署⾼可⽤的Redis集群,并且完善监控报警体系.
- 不给key设置过期时间或者设置过期时间的时候添加随机时间因⼦
1.3.4 缓存击穿(breakdown)
相当于缓存雪崩的特殊情况,针对热点key突然过期了,导致⼤量的请求直接访问到数据库上,甚至引起数据库宕机
如何解决?
- 基于统计的方式发现热点key,并设置永不过期.
- 进行必要的服务降级
- 例如访问数据库的时候使用分布式锁,限制同时请求数据库的并发数
2. 分布式锁
2.1 什么是分布式锁?
在⼀个分布式的系统中,也会涉及到多个节点访问同⼀个公共资源的情况,此时就需要通过锁来做互斥控制,避免出现类似于"线程安全"的问题。
而java的synchronized或者C++的std::mutex,这样的锁都是只能在当前进程中⽣效;在分布式的这种多个进程多个主机的场景下就⽆能为力了,此时就需要使用到分布式锁
分布式锁本质上就是使⽤⼀个公共的服务器,来记录加锁状态.
这个公共的服务器可以是Redis,也可以是其他组件(⽐如MySQL或者ZooKeeper等),还可以 是我们自己写的⼀个服务
2.2 分布式锁的基础实现
思路非常简单,本质上就是通过⼀个键值对来标识锁的状态
举个例⼦:考虑买票的场景,现在⻋站提供了若⼲个⻋次,每个⻋次的票数都是固定的。现在存在多个服务器节点,都可能需要处理这个买票的逻辑:先查询指定⻋次的余票,如果余票>0,则设置余票值-=1
显然上述的场景是存在"线程安全"问题的,需要使用锁来控制。
所谓的分布式锁,就是一个/一组单的服务器程序,来给其它服务器提供“加锁”这样的服务。
redis是一种典型的可以用来实现分布式锁的方案,但不是唯一一种
在买票服务器进行买票操作的过程中,就需要先进行加锁
- 加锁:往redis中设置一个特殊的key-value,完成买票操作,再把这个key-value删除掉
- 使用 set nx命令设置,del命令删除
- 其它服务器也想执行买票操作时,也去redis上尝试设置key-value,设置失败,则认为加锁失败(是阻塞/放弃,看具体的策略)
- 此时,就可以解决线程安全的问题了
刚才买票场景,使用 mysql 的事务也可以批量执行 査询 + 修改 操作,但是分布式系统中,要访问的共享资源不一定是 mysq! 也可能是其他的存储介质没有事务,也可能是执行一段特定的操作,是通过统一的服务器完成执行动作
2.3 引入过期时间(防止“死锁”问题)
当服务器1加锁之后,开始处理买票的过程中,如果服务器1意外宕机了,就会导致解锁操作(删除该key) 不能执行,就可能引起其他服务器始终无法获取到锁的情况
为了解决这个问题,可以在设置key的同时引入过期时间,即这个锁最多持有多久,就应该被释放(使用set ex nx
命令)
注意:
此处的过期时间只能使⽤上述⼀个命令的⽅式设置,如果分开多个操作,⽐如setnx之后,再来⼀个单独的expire,由于Redis的多个指令之间不存在关联,并且即使使⽤了事务也不能保证这两个操作都⼀定成功,因此就可能出现setnx成功,但是expire失败的情况,此时仍然会出现⽆法正确释放锁的问题.
2.4 引入校验id(防止锁误删问题)
对于Redis中写⼊的加锁键值对,其他的节点也是可以删除的.
比如服务器1写⼊⼀个
"001":1
这样的键值对,服务器2是完全可以把"001"
给删除掉的。当然,服务器2不会进⾏这样的"恶意删除"操作,不过不能保证因为⼀些bug导致服务器2把锁误删除。
为了解决上述问题,我们可以引⼊⼀个校验id。
比如可以把设置的键值对的值,不再是简单的设为⼀个1,⽽是设成服务器的编号,形如"001":"服务器1"
。
这样就可以在删除key(解锁)的时候,先校验当前删除key的服务器是否是当初加锁的服务器,如果是,才能真正删除;不是,则不能删除
在解锁的时候,要先进行id的校验,再执行del操作,但是这两步不是原子的,就可能出现问题
2.5 引入lua(解决原子性问题)
为了使解锁操作原子,可以使⽤Redis的Lua脚本功能
使⽤Lua脚本完成上述解锁功能
if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1])
else return 0
end;
上述代码可以编写成⼀个.lua后缀的⽂件,由redis-cli 或者redis-plus-plus 或者jedis 等客⼾端加载,并发送给Redis服务器,由Redis服务器来执⾏这段逻辑;⼀个lua脚本会被Redis服务器以原⼦的⽅式来执⾏.
2.6 引入watchdog(解决过期时间不足问题)
上述⽅案仍然存在⼀个重要问题,当我们设置了key过期时间之后(⽐如10s),仍然存在⼀定的可能性,当任务还没执⾏完,key就先过期了,这就导致锁提前失效。
- 把这个过期时间设置的⾜够⻓,⽐如30s,是否能解决这个问题呢?很明显,设置多⻓时间合适,是⽆⽌境的,即使设置再⻓,也不能完全保证就没有提前失效的情况。
- 如果设置的太⻓了,万⼀对应的服务器挂了,此时其他服务器也不能及时的获取到锁
- 因此相⽐于设置⼀个固定的⻓时间,不如动态的调整时间更合适
所谓watchdog(看门狗),本质上是加锁的服务器上的一个单独的线程,通过这个线程来对锁过期时间进⾏"续约".
这样就不担心锁提前失效的问题了,而且另一方面,如果该服务器挂了,看门狗线程也就随之挂了,此时无人续约,这个key⾃然就可以迅速过期,让其他服务器能够获取到锁了
2.7 引入Redlock算法(防止redis挂了)
实践中的Redis⼀般是以集群的⽅式部署的(至少是主从的形式,⽽不是单机),那么就可能出现以下⽐较极端的大冤种情况:
- 服务器1向master节点进行加锁操作,这个写⼊key的过程刚刚完成,master挂了,slave节点升级成了新的master节点。
- 但是由于刚才写⼊的这个key尚未来得及同步给slave呢,此时就相当于服务器1的加锁操作形同虚设了,服务器2仍然可以进⾏加锁(即给新的master写⼊key,因为新的master不包含刚才的key)
为了解决这个问题,Redis的作者提出了Redlock算法
- 我们引入一组Redis节点,其中每⼀组Redis节点都包含⼀个主节点和若⼲从节点,并且组和组之间存储的数据都是⼀致的,相互之间是"备份"关系(而并非是数据集合的⼀部分,这点有别于redis cluster).
- 加锁的时候,按照⼀定的顺序,写多个master节点,在写锁的时候需要设定操作的"超时时间",⽐如50ms,即如果setnx操作超过了50ms还没有成功,就视为加锁失败.
- 如果给某个节点加锁失败,就⽴即再尝试下⼀个节点,当加锁成功的节点数超过总节点数的⼀半,才视为加锁成功.
这样的话,即使有某些节点挂了,也不影响锁的正确性
同理,释放锁的时候,也需要把所有节点都进⾏解锁操作(即使是之前超时的节点,也要尝试解锁,尽量保证逻辑严密)
简而言之,Redlock算法的核心就是:加锁操作不能只写给⼀个Redis节点,而要写个多个!
分布式系统中任何⼀个节点都是不可靠的,最终的加锁成功结论是"少数服从多数的";由于⼀个分布式系统不⾄于⼤部分节点都同时出现故障,因此这样的可靠性要⽐单个节点来说靠谱不少
相关文章:
【Redis】redis用作缓存和分布式锁
文章目录 1. 缓存1.1 Redis作为缓存1.2 缓存更新、淘汰策略1.3 缓存预热、缓存穿透、缓存雪崩和缓存击穿1.3.1 缓存预热(preheating)1.3.2 缓存穿透(penetration)1.3.3 缓存雪崩(avalanche)1.3.4 缓存击穿&…...
深度学习中独热编码(One-Hot Encoding)
文章目录 独热编码独热编码的作用独热编码的优点独热编码的缺点场景选择独热编码(PyTorch实现)替代方案 实际使用分析:对对象类型使用独热编码为什么使用独热编码是合适的?📌 场景说明:📌 为什么…...
如何根据竞价数据判断竞价强度,是否抢筹等
竞价强度判断方法 价格变化幅度 观察开盘价与前一交易日收盘价的差距 :如果一只股票在开盘集合竞价阶段价格大幅高于前一交易日收盘价,说明市场对该股票的预期较为积极,可能有资金在主动抬高价格,这是一种较强的竞价强度表现。例如…...
Codex与LangChain结合的智能代理架构:重塑软件开发的未来
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言:当代码生成遇见智能决策 想象以下场景: 凌晨三点:你需要紧急修复一个遗留系统的内存泄漏漏洞,但代码注释缺失且逻辑复杂; 产品经理需求变更:要求在24小时内将现有…...
2025年PMP 学习十八 第11章 项目风险管理 (11.5~11.7)
2025年PMP 学习十八 第11章 项目风险管理 (11.5~11.7) 第11章 项目风险管理 序号过程过程组1规划风险管理规划2识别风险规划3实施定性风险分析规划4实施定量风险分析规划5规划风险应对执行6实施风险应对执行7监控风险监控 文章目录 2025年PMP 学习十八…...
2025年PMP 学习十七 第11章 项目风险管理 (11.1~11.4)
2025年PMP 学习十七 第11章 项目风险管理 (11.1~11.4) 第11章 项目风险管理 序号过程过程组1规划风险管理规划2识别风险规划3实施定性风险分析规划4实施定量风险分析规划5规划风险应对执行6实施风险应对执行7监控风险监控 文章目录 2025年PMP 学习十七…...
impala
Impala,它是 Cloudera 开发的开源 实时 SQL 查询引擎,专为 Hadoop 设计。与 Presto 类似,Impala 用于交互式分析,但架构和设计理念有所不同。以下是 Impala 的核心特点和工作原理: 一、Impala 核心架构 1. 组件组成 …...
湖北理元理律师事务所:债务优化中的双维支持实践解析
在债务压力与生活质量失衡的社会议题下,法律服务机构的功能边界正在从单一的法律咨询向复合型支持延伸。湖北理元理律师事务所通过“法律心理”双维服务模式,探索债务优化与生活保障的平衡路径,其方法论或为行业提供实践参考。 法律框架&…...
Redis设计与实现——Redis命令参考与高级特性
Redis命令参考 数据类型相关命令 SET:设置键值,支持过期时间、不存在/存在条件。GET:获取键值,若键不存在返回 nil。INCR/DECR:将键的整数值增1/减1,键不存在时初始化为0。MSET/MGET:批量设置…...
TCP/UDP协议原理和区别 笔记
从简单到难吧 区别就是TCP一般用于安全稳定的需求,UDP一般用于不那么需要完全数据的需求,比如说直播,视频等。 再然后就是TPC性能慢于UDP。 再然后我们看TCP的原理(三次握手,数据传输,四次挥手࿰…...
JavaScript基础-对象的相关概念
在JavaScript中,对象是核心的数据结构之一,几乎所有的高级功能都围绕着对象展开。理解对象的基本概念、创建方法以及操作方式对于掌握JavaScript至关重要。本文将详细介绍JavaScript中对象的相关概念,包括对象的定义、属性的操作、原型链和面…...
如何通过交流沟通实现闭环思考模式不断实现自身强效赋能-250517
感谢一直以来和我交流沟通的朋友们。 闭环思考 文字部分(25-05-04)这一天是青年节,在这一天与青年朋友交流这个是事先规划好的: “可以猜一猜,博士会被撤销吗?导师会被处理吗?千万不要回复&…...
震荡指标工具
一、引言 - 可视化数字烛台工具是对传统蜡烛图的补充,旨在帮助交易者更有效地进入和退出交易,提高交易利润。 - 通过分析蜡烛图,结合烛台震荡指标,提出了一个辅助视觉工具来辅助交易决策。 二、烛台指标与交易策略 -图表通过平均开…...
【自然语言处理与大模型】大模型(LLM)基础知识④
(1)微调主要用来干什么? 微调目前最主要用在定制模型的自我认知和改变模型对话风格。模型能力的适配与强化只是辅助。 定制模型的自我认知:通过微调可以调整模型对自我身份、角色功能的重新认知,使其回答更加符合自定义…...
返回码的方案对比和思考
前言 一般我们定义 Restful 接口返回码,常见的就是 const 定义 code , StatusToText() 来实现定义 msg, 在封装1 ~ 2个返回方法(success、error)就可以实现,只是突然想到这样设计是违反开闭原则的…...
Flink 的任务槽和槽共享
在 Apache Flink 中,任务槽(Task Slot) 和 槽共享组(Slot Sharing Group) 是资源管理和任务调度的关键机制。它们决定了 Flink 如何在集群中分配资源并执行任务。 一、任务槽(Task Slot) 1. 定…...
实验七 基于Python的数字图像水印算法
一、实验目的 掌握图像水印的应用; 掌握我国版权保护的发展现状; 掌握常见的数字图像水印算法。 二、实验内容 学习内容补充: 数字水印的鲁棒性评价主要采用含水印图像提取出的水印与原始水印的相似程度,使用归一化相关(NC,Nor…...
C语言:在 Win 10 上,gcc 如何编译 gtk 应用程序
在 Windows 10 上使用 g(或 gcc)编译基于 GTK 的 C 语言程序是完全可行的,且相比 Tcc 更为推荐,因为 g(GNU 编译器套件)对 GTK 的支持更加完善,配置也更简单。以下是详细步骤和注意事项…...
Vue.js---watch 的实现原理
4.7 watch 的实现原理 watch本质上就是使用了effect以及options.scheduler 定义watch函数: // watch函数:传入参数source以及回调函数function watch(source , cb) {effect(() > source.foo,{scheduler(){// 回调函数cb()}})}watch接收两个参数分别是source和c…...
Linux_ELF文件
目录 前言: 一、ELF文件的类型 二、ELF文件的组成格式 1. ELF头部(ELF Header) 2. 节头表(Section Header Table) 3. 程序头表(Program Header Table) 4. 节(Sections)与段(Segments) 三、ELF文件从形成到加载轮廓 1、ELF可执行文件形成过程 2、 可执行文…...
磁盘I/O子系统
一、数据写入磁盘流程 当执行向磁盘写入数据操作的时候,会发生如下的一系列基本操作。假设文件数据存在于磁盘扇区上,并且已经被读入到页缓存中。 进程使用write()系统调用写入文件。内核更新映射到文件的page cache。内核线程pdflush负责把页缓存刷入…...
【2025 技术指南】如何创建和配置国际版 Apple ID
想要体验更丰富的应用生态、使用国际版专属服务,或访问更多开发者工具?一个国际版 Apple ID 能帮你实现这些需求。本教程将详细介绍如何注册国际版 Apple ID 并正确配置支付信息,全程操作简单,适合开发者和技术爱好者参考。 一、准…...
C++(20): 文件输入输出库 —— <fstream>
目录 一、 的核心功能 二、核心类及功能 三、核心操作示例 1. 文本文件写入(ofstream) 2. 文本文件读取(ifstream) 3. 二进制文件操作(fstream) 四、文件打开模式 五、文件指针操作 六、错误处理技巧…...
05、基础入门-SpringBoot-HelloWorld
05、基础入门-SpringBoot-HelloWorld ## 一、Spring Boot 简介 **Spring Boot** 是一个用于简化 **Spring** 应用初始搭建和开发的框架,旨在让开发者快速启动项目并减少配置文件。 ### 主要特点 - **简化配置**:采用“约定优于配置”的原则,减…...
深入理解指针(6)
目录 1 sizeof和strlen的对⽐ 1.1 sizeof 编辑1.2strlen 1.3 sizeof 和 strlen的对⽐ 2 数组和指针笔试题解析 2.1 ⼀维数组 编辑 2.2 字符数组 3 指针运算笔试题解析 3.1 题⽬1: 编辑3.2 题目2 3.3 题目3 3.4 题目4 3.5 题目5 3.6 题目6 3.7…...
力扣HOT100之二叉树:108. 将有序数组转换为二叉搜索树
这道题之前做过,思路又给忘了,这道题用递归做是最简单的。 由于得到的数组是有序的,我们只需要取出中间位置的元素medium作为根节点,然后medium左边的剩余元素组成根节点的左子树,medium右边的剩余元素组成根节点的右子…...
手撕I2C和SPI协议实现
手撕I2C和SPI协议实现 目录 I2C协议原理I2C位操作实现I2C驱动代码编写SPI协议原理SPI位操作实现SPI驱动代码编写 I2C协议原理 I2C(Inter-Integrated Circuit)是一种串行通信总线,使用两根线:SCL(时钟线)…...
452. Minimum Number of Arrows to Burst Balloons
题目描述 这道题用leetcode官方的解答反而搞复杂了。本题其实就是求重叠区间的交集。先按照区间左端点从小到大排序。然后拿出第一个区间作为【当前区间交集】的初始值。遍历后面的区间看那个区间和【当前交集】是否有重叠。如果有重叠则将【当前交集】和【当前区间】求交集并更…...
React 中,闭包陷阱
文章目录 前言1. 经典闭包陷阱示例过期状态问题 2. 解决方案2.1 正确声明依赖数组2.2 使用 useRef 捕获最新值**2.3 使用函数式更新(针对状态更新)****2.4 使用 useCallback 冻结闭包** **3. 异步操作中的闭包陷阱****事件监听示例** **4. 自定义 Hooks …...
代码复现5——VLMaps
项目地址 1 Setup # 拉取VLMaps仓库,成功运行后会在主目录生成文件夹vlmapsgit clone https://github.com/vlmaps/vlmaps.git#通过 conda 创建虚拟环境conda create -n vlmaps python=3.8 -yconda activate vlmaps #激活环境cd vlmaps # 切换到项目文件下bash install.ba…...
qt6 c++操作qtableview和yaml
保存qtableview数据到yaml文件从yaml文件读取数据到qtableview qtableview在UI界面拖放。 代码是问chat百度的深度探索。 - name: a1address: db1.dbw10type: int - name: a2address: db1.dbx1.0type: bool写到yaml,写前检查 bool plot1::isRowValid(const QStan…...
使用UniApi调用百度地图API的需要注意的地方
目录 前言 一、百度开放平台 1、功能简介 2、地点搜索服务 3、按行政区划检索API 二、Uniapi集成百度API 1、API集成流程 2、访问接口的定义 3、业务调用集成 三、可能遇到的问题 1、指定输出格式无效 2、返回数据的总数 四、总结 前言 在之前的系列博客中…...
(9)python开发经验
文章目录 1 os.path.join()拼接路径2 条件变量3 添加临时环境变量 更多精彩内容👉内容导航 👈👉Qt开发 👈👉python开发 👈 1 os.path.join()拼接路径 os.path.join() 是 Python 中处理文件路径拼接的核心函…...
windows 10 做服务器 其他电脑无法访问,怎么回事?
一般我们会先打开win10自己的防火墙策略,但是容易忽略 电脑之间 路由器上的防火墙,此时也需要查看一下,可以尝试先关闭路由器防火墙,如果可以了,再 设置路由器上的防火墙规则。 将路由器的上网设置 改成 路由模式 &a…...
mysql中limit深度分页详细剖析【爽文】
目录 一 mysql中limit深度分页 1.1 背景描述 1.2 mysql深度分页很慢原因 1.2.1 mysql的sql执行流程 1.2.2 mysql的深度分页很慢原因 1.3 解决办法 1.3.1 覆盖索引 1.3.2 子查询 1.3.3 标签查询 1.3.4 分区表 一 mysql中limit深度分页 1.1 背景描述 Limit深度分页造…...
【C++ Qt】布局管理器
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 🤔绪论: 在Qt开发中,界面布局的合理设计是提升用户体验的关键。早期,开发者常采用绝对定位的方式摆放控件,即通…...
Windows系统永久暂停更新操作步骤
目录 Windows系统永久暂停更新操作步骤 打开运行窗口进入注册表编辑器 导航路径图示 新建并配置DWORD值 新建值操作图示数值设置图示 在系统设置中应用暂停 暂停选项图示 注意事项 打开运行窗口 按下键盘上的 Win键 R 组合键,调出“运行”对话框。 进入组策略编…...
Java IO流进阶实战详解(含文件读写、拷贝、加密、字符集)
本文基于 Java 原生 IO 流,从最基础的字节流到字符流,再到实战案例(如文件夹拷贝、文件加密等)进行逐步深入讲解。适合有一定 Java 基础、希望掌握文件读写操作的。 一、前言 Java IO(输入输出)是我们日常…...
JavaScript【7】BOM模型
1.概述: BOM(Browser Object Model,浏览器对象模型)是 JavaScript 中的一个重要概念,它提供了一系列对象来访问和操作浏览器的功能和信息。与 DOM(Document Object Model)主要关注文档结构不同&…...
STM32F10xx 参考手册
6. 什么是寄存器 本章参考资料:《STM32F10xx 参考手册》、《STM32F10xx数据手册》、 学习本章时,配合《STM32F10xx 参考手册》“存储器和总线架构”及“通用I/O(GPIO)”章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。…...
使用instance着色
本节我们学习使用instance着色器进行着色 //拾取var handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction(function(movement){console.log(movement);var pickedObject viewer.scene.pick(movement.position);if(Cesium.defined(picke…...
MySQL——4、表的约束
表的约束 1、空属性2、默认值3、列描述4、zerofill5、主键6、自增长7、唯一键8、外键9、综合案例 真正约束字段的是数据类型,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性…...
Datawhale PyPOTS时间序列5月第3次笔记
下游任务的两阶段(two-stage) 处理 下载数据并预处理的程序: # ------------------------------- # 导入必要的库 # ------------------------------- import numpy as np import torch from benchpots.datasets import preprocess_physionet2012 from pypots.imp…...
初探Reforcement Learning强化学习【QLearning/Sarsa/DQN】
文章目录 一、Q-learning现实理解:举例:回顾: 二、Sarsa和Q-learning的区别 三、Deep Q-NetworkDeep Q-Network是如何工作的?前处理:Convolution NetworksExperience Replay 一、Q-learning 是RL中model-free、value-…...
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 12.曲面细分
1. 曲面细分 曲面细分着色器(Tessellation Shader)是OpenGL 4.0及以上版本引入的一种可编程着色器阶段,用于在GPU上对几何体进行细分,将粗糙的多边形网格自动细分为更平滑、更精细的曲面。它主要用于实现高质量的曲面渲染&#x…...
8天Python从入门到精通【itheima】-14~16
目录 第二章学习内容总体预览: 14节-字面量: 1.学习目标:编辑 2.Python中6大常用数据类型: 3.实现:整数、浮点数、字符串类型的数据输出 4.字面量的定义: 5.小节总结 15节-注释: 1.le…...
Spring Boot 项目的计算机专业论文参考文献
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
linux线程基础
1. 什么是线程 进程是承担系统资源分配的基本实体,而线程(Thread)是进程内的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程,这些线程共享进程的地址空间和资源(如文件描述符、全局变量等&a…...
进阶-数据结构部分:3、常用查找算法
飞书文档https://x509p6c8to.feishu.cn/wiki/LRdnwfhNgihKeXka7DfcGuRPnZt 顺序查找 查找算法是指:从一些数据之中,找到一个特殊的数据的实现方法。查找算法与遍历有极高的相似性,唯一的不同就是查找算法可能并不一定会将每一个数据都进行访…...
JavaScript 中的 for...in 和 for...of 循环详解
在 JavaScript 中,for...in 和 for...of 是两种常用的循环结构,但它们有着不同的用途和行为。很多初学者容易混淆这两者,本文将详细解析它们的区别、适用场景以及注意事项。 目录 for…in 循环 基本用法遍历对象属性注意事项 for…of 循环 …...