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

Redis 技术详解

一、Redis 基础

(一)为什么使用 Redis

  1. 速度快,因为数据存在内存中,类似于 HashMap,查找和操作的时间复杂度都是 O(1)。
  2. 支持丰富数据类型,支持 string、list、set、Zset、hash 等。
  3. 支持事务,操作都是原子性,即对数据的更改要么全部执行,要么全部不执行。
  4. 丰富的特性:可用于缓存、消息,按 key 设置过期时间,过期后将会自动删除。

(二)Redis 的常用数据类型有哪些

  1. String
    • 介绍:string 数据结构是简单的 key-value 类型。Redis 没有使用 C 的字符串表示,而是构建了一种简单动态字符串(simple dynamic string,SDS)。最大能存储 512MB。
    • 常用命令:set、get、strlen、exists、decr、incr、setex 等等。
    • 应用场景:计数、缓存文章标题、微博内容等。
  2. List
    • 介绍:list 即是链表。特点是易于数据元素的插入和删除并且可以灵活调整链表长度,但随机访问困难。最多可存储 2^32 - 1 元素(4294967295,每个列表可存储 40 亿)。
    • 常用命令:rpush、lpop、lpush、rpop、lrange、llen 等。
    • 应用场景:发布与订阅或者说消息队列。
  3. Hash
    • 介绍:hash 类似于 JDK1.8 前的 HashMap,内部实现也差不多(数组+链表)。Redis 的 hash 做了更多优化,是一个 string 类型的 field 和 value 的映射表,特别适合用于存储对象。每个 hash 可以存储 2^32 - 1 键值对(40 多亿)。
    • 常用命令:hset、hmset、hexists、hget、hgetall、hkeys、hvals 等。
    • 应用场景:系统中对象数据的存储。
  4. Set
    • 介绍:set 类似于 Java 中的 HashSet。Redis 中的 set 类型是一种无序集合,集合中的元素没有先后顺序。当需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口。最大的成员数为 2^32 - 1(4294967295,每个集合可存储 40 多亿个成员)。
    • 常用命令:sadd、spop、smembers、sismember、scard、sinterstore、sunion 等。
    • 应用场景:需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景。
  5. SortedSet(zset)
    • 介绍:SortedSet 和 set 相比,SortedSet 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。有点像是 Java 中 HashMap 和 TreeSet 的结合体。
    • 常用命令:zadd、zcard、zscore、zrange、zrevrange、zrem 等。
    • 应用场景:需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息等信息。

(三)跳表你了解吗?

跳表(SkipList)首先是链表,但与传统的链表相比有几点差异:

  1. 结合了链表和二分查找的思想。
  2. 元素按照升序排列存储。
  3. 节点可能包含多个指针,指针跨度不同。
  4. 查找时从顶层向下,不断缩小搜索范围。
  5. 整个查询的复杂度为 O(log n)。
    Redis 数据类型 Sorted Set 使用了跳表作为其中一种数据结构。
    在这里插入图片描述

(四)Redis 可以用来做什么?

  1. 缓存。
  2. 排行榜。
  3. 分布式计数器。
  4. 分布式锁。
  5. 消息队列。
  6. 分布式 token。
  7. 限流。

(五)Redis 为什么快?

  1. 内存操作:完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
  2. 单线程,省去线程切换、锁竞争的开销:采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。
  3. NIO 的 IO 多路复用模型:使用多路 I/O 复用模型,非阻塞 IO;这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。

(六)Redis 过期删除策略?

  1. 惰性删除:只会在取出 key 的时候才对数据进行过期检查。这样对 CPU 最友好,但是可能会造成太多过期 key 没有被删除。
  2. 定期删除:每隔一段时间抽取一批 key 执行删除过期 key 操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。

定期删除对内存更加友好,惰性删除对 CPU 更加友好。两者各有千秋,所以 Redis 采用的是定期删除+惰性/懒汉式删除。但是,仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。这样就导致大量过期 key 堆积在内存里,然后就 Out of memory 了。解决这个问题的方法是 Redis 内存淘汰机制。

(七)Redis 内存淘汰策略?

Redis 提供 6 种数据淘汰策略:

  1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
  4. allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!4.0 版本后增加以下两种:
    • volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰。
    • allkeys-lfu(least frequently used):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key。

二、持久化

(一)Redis 持久化机制 RDB 和 AOF 区别?

在 Redis 中提供了两种数据持久化的方式:RDB 和 AOF。

  1. RDB
    • 定期更新,定期将 Redis 中的数据生成的快照同步到磁盘等介质上,磁盘上保存的就是 Redis 的内存快照。
    • 优点:数据文件的大小相比于 AOF 较小,使用 RDB 进行数据恢复速度较快。
    • 缺点:比较耗时,存在丢失数据的风险。
  2. AOF
    • 将 Redis 所执行过的所有指令都记录下来,在下次 Redis 重启时,只需要执行指令就可以了。
    • 优点:数据丢失的风险大大降低了。
    • 缺点:数据文件的大小相比于 RDB 较大,使用 AOF 文件进行数据恢复的时候速度较慢。

项目中的持久化配置选择:RDB + AOF。
在这里插入图片描述

(二)Redis 如何选择合适的持久化方式

  1. 如果是数据不那么敏感,且可以从其他地方重新生成补回的,那么可以关闭持久化。
  2. 如果是数据比较重要,不想再从其他地方获取,且可以承受数分钟的数据丢失,比如缓存等,那么可以只使用 RDB。
  3. 如果是用做内存数据库,要使用 Redis 的持久化,建议是 RDB 和 AOF 都开启,或者定期执行 bgsave 做快照备份,RDB 方式更适合做数据的备份,AOF 可以保证数据的不丢失。

补充:Redis4.0 对于持久化机制的优化
Redis4.0 相对与 3.X 版本其中一个比较大的变化是 4.0 添加了新的混合持久化方式。简单的说:新的 AOF 文件前半段是 RDB 格式的全量数据后半段是 AOF 格式的增量数据。

优势:混合持久化结合了 RDB 持久化和 AOF 持久化的优点,由于绝大部分都是 RDB 格式,加载速度快,同时结合 AOF,增量的数据以 AOF 方式保存了,数据更少的丢失。

劣势:兼容性差,一旦开启了混合持久化,在 4.0 之前版本都不识别该 aof 文件,同时由于前部分是 RDB 格式,阅读性较差。

(三)在生成 RDB 期间,Redis 可以同时处理写请求么?

可以的,Redis 使用操作系统的多进程写时复制技术 COW(Copy On Write)来实现快照持久化,保证数据一致性。Redis 在持久化时会调用 glibc 的函数 fork 产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。当主线程执行写指令修改数据的时候,这个数据就会复制一份副本,bgsave 子进程读取这个副本数据写到 RDB 文件。这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

三、主从和集群

(一)Redis 集群方案

在 Redis 中提供的集群方案总共有三种:

  1. 主从复制
    • 保证高可用性。
    • 实现故障转移需要手动实现。
    • 无法实现海量数据存储。 在这里插入图片描述
  2. 哨兵模式
    • 保证高可用性。
    • 可以实现自动化的故障转移。
    • 无法实现海量数据存储。
      在这里插入图片描述
  3. Redis 分片集群
    • 保证高可用性。
    • 可以实现自动化的故障转移。
    • 可以实现海量数据存储。
      在这里插入图片描述

(二)Redis 主从同步

主从第一次同步是全量同步,流程如下:
在这里插入图片描述

  1. 从节点执行replicaof命令,发送自己的replidoffset给主节点。
  2. 主节点判断从节点的replid与自己的是否一致。
  3. 如果不一致说明是第一次来,需要做全量同步,主节点返回自己的replid给从节点。
  4. 主节点开始执行bgsave,生成rdb文件。
  5. 主节点发送rdb文件给从节点,在发送的过程中。
  6. 从节点接收rdb文件,清空本地数据,加载rdb文件中的数据。
  7. 同步过程中,主节点接收到的新命令写入从节点的写缓冲区(repl_buffer)。
  8. 从节点接收到缓冲区数据后写入本地,并记录最新数据对应的offset

后期数据变化后,则执行增量同步:
在这里插入图片描述

  1. 主节点会不断把自己接收到的命令记录在repl_baklog中,并修改offset
  2. 从节点向主节点发送psync命令,发送自己的offsetreplid
  3. 主节点判断replidoffset与从节点是否一致。
  4. 如果replid一致,说明是增量同步。然后判断offset是否一致。
  5. 如果从节点offset小于主节点offset,并且在repl_baklog中能找到对应数据,则将offset之间相差的数据发送给从节点。
  6. 从节点接收到数据后写入本地,修改自己的offset与主节点一致。

增量同步的风险repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于log做增量同步,只能再次全量同步。repl_baklog可以在配置文件中进行修改存储大小。

(三)Redis 分片集群中数据的存储和读取

Redis 集群引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。
在这里插入图片描述
上图是存值的流程,取值的流程类似:

  • 例如:set {aaa} name zhangsan,计算 hash 是根据aaa计算的。取值的流程类似。

(四)Redis 主从架构数据会丢失吗?为什么?

有两种数据丢失的情况:

  1. 异步复制导致的数据丢失:因为 master -> slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这些部分数据就丢失了。
  2. 脑裂导致的数据丢失:某个 master 所在机器突然脱离了正常的网络,跟其他 slave 机器不能连接,但是实际上 master 还运行着,此时哨兵可能就会认为 master 宕机了,然后开启选举,将其他 slave 切换成了 master。这个时候,集群里就会有两个 master,也就是所谓的脑裂。此时虽然某个 slave 被切换成了 master,但是可能 client 还没来得及切换到新的 master,还继续写向旧 master 的数据可能也丢失了。因此旧 master 再次恢复的时候,会被作为一个 slave 挂到新的 master 上去,自己的数据会清空,重新从新的 master 复制数据。

四、使用场景

(一)如何保存 Redis 数据与 DB 一致?

  1. 方案 1:同步双写,即更新完 DB 后立即同步更新 redis。
  2. 方案 2:异步监听,即通过 Canal 监听 MySQL 变化的表,同步更新数据到 Redis。
  3. 方案 3:MQ 异步,即更新完 DB 后生产消息到 MQ,MQ 消费者更新数据到 Redis。

(二)Redis 中什么是缓存预热?

缓存预热是指系统上线后,提前将相关的缓存数据加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。

如果不进行预热,那么 Redis 初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中,对数据库造成流量的压力。

缓存预热解决方案

  1. 数据量不大的时候,工程启动的时候进行加载缓存动作。
  2. 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新。
  3. 数据量太大的时候,优先保证热点数据进行提前加载到缓存。

(三)什么是缓存降级?

缓存降级是指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。

在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:

  1. 一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级。
  2. 警告:有些服务在一段时间内成功率有波动(如在 95% - 100%之间),可以自动降级或人工降级,并发送告警。
  3. 错误:比如可用率低于 90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级。
  4. 严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

(四)什么是缓存穿透?怎么解决?

加入缓存以后的数据查询流程:
在这里插入图片描述
缓存穿透概述:指查询一个一定不存在的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。例如:get 请求:api/v1/news/13

解决方案

  1. 查询返回的数据为空,仍把这个空结果进行缓存,但过期时间会比较短。
  2. 布隆过滤器:将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对 DB 的查询。

Redis 中使用布隆过滤器防止缓存穿透流程图如下所示:
在这里插入图片描述

(五)什么是缓存击穿?怎么解决?

概述:对于设置了过期时间的 key,缓存在某个时间点过期的时候,恰好这时间点对这个 Key 有大量的并发请求过来,这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把 DB 压垮。

解决方案

  1. 使用互斥锁:当缓存失效时,不立即去load db,先使用如 Redis 的setnx去设置一个互斥锁,当操作成功返回时再进行load db的操作并回设缓存,否则重试get缓存的方法。
  2. 可以设置当前 key 逻辑过期:大概是思路如下:
    • 优点:线程无需等待,性能较好。
    • 缺点:不保证一致性,有额外内存消耗,实现复杂。
    • 解决方案:
      • ①:在设置 key 的时候,设置一个过期时间字段一块存入缓存中,不给当前 key 设置过期时间。
      • ②:当查询的时候,从 redis 取出数据后判断时间是否过期。
      • ③:如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据,这个数据不是最新。在这里插入图片描述

两种方案对比

解决方案优点缺点
互斥锁没有额外的内存消耗,保证一致性,实现简单线程需要等待,性能受影响,可能有死锁风险,不保证一致性
逻辑过期线程无需等待,性能较好有额外内存消耗,实现复杂

(六)什么是缓存雪崩?怎么解决?

概述:设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到 DB,DB 瞬时压力过重雪崩。与缓存击穿的区别:雪崩是很多 key,击穿是某一个 key 缓存。

解决方案
将缓存失效时间分散开,比如可以在原有的失效时间基础上增加一个随机值,比如 1 - 5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

(七)Redis 分布式锁如何实现?

Redis 实现分布式锁主要利用 Redis 的setnx命令。setnxSET if not exists(如果不存在,则 SET)的简写。
在这里插入图片描述
加锁:使用setnx key value命令,如果 key 不存在,设置 value(加锁成功)。如果已经存在 lock(也就是有客户端持有锁了),则设置失败(加锁失败)。

解锁:使用del命令,通过删除键值释放锁。释放锁之后,其他客户端可以通过命令进行加锁。

(八)Redis 分布式锁的有效时长

  1. 第一种解决方案:程序员自己去把握,预估一下业务代码需要执行的时间,然后设置有效期时间比执行时间长一些,保证不会因为自动解锁影响到客户端业务代码的执行。
  2. 第二种解决方案:给锁续期。

锁续期实现思路:当加锁成功后,同时开启守护线程,默认有效期是用户所设置的,然后每隔 10 秒就会给锁续期到用户所设置的有效期,只要持有锁的客户端没有宕机,就能保证一直持有锁,直到业务代码执行完毕由客户端自己解锁,如果宕机了自然就在有效期失效后自动解锁。

上述的第二种解决方案可以使用 redis 官方所提供的 Redisson 进行实现。Redisson 分布式锁原理(重要)
在这里插入图片描述
注意:Redisson 的watchDog不是每 10 秒做一次续期,而是每隔(releaseTime / 3)的时间做一次续期。也就是锁自动释放时间的 1/3,默认的锁释放时间是 30 秒,因此默认每隔 10 秒续期。

相关文章:

Redis 技术详解

一、Redis 基础 (一)为什么使用 Redis 速度快,因为数据存在内存中,类似于 HashMap,查找和操作的时间复杂度都是 O(1)。支持丰富数据类型,支持 string、list、set、Zset、hash 等。支持事务,操…...

Kubernetes Pod入门

在 Kubernetes 中,一个重要的概念就是 Pod(豆英),Kubernetes 并不是直接管理容器的,他的最小管理单元叫做 Pod。 一、什么是 Pod。 Pod 是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及运行规范。在 Pod中&…...

opencv批量修改图片大小

文章已删除,访问可以 在点击这里查找. 在点击这里查找. 在点击这里查找. 在点击这里查找. 在点击这里查找. 在点击这里查找. 在点击这里查找. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~...

【RTT-Studio】详细使用教程十二:UART的分析和使用

文章目录 一、简介1.串口发送模式2.串口接收模式 二、串口配置三、串口发送四、串口接收 一、简介 本文主要阐述STM32串口的几种工作中使用的工作模式和编程思路。串口通常情况下使用的是:1个起始位,8个数据位,无奇偶校验,1位停止…...

【AI绘画】Midjourney前置指令/settings设置详解

文章目录 💯Midjourney前置指令/settings设置详解💯Use the default model(AI绘画所使用的大模型)Midjourney Model(Midjourney 模型)Niji Model(Niji模型) 💯Midjourney…...

【NI国产替代】PXIe‑4330国产替代24位,8通道PXI应变/桥输入模块

25 kS/s,24位,8通道PXI应变/桥输入模块 PXIe‑4330是一款同步输入模块,为基于桥接的传感器提供集成数据采集和信号调理。 PXIe‑4330具有更高的准确性、高数据吞吐量和同步特性,使其成为高密度测量系统的理想选择。\n\n为了消除噪…...

哪里可以免费上传招生简章

随着招生季的临近,各高校和培训机构纷纷摩拳擦掌,准备迎接新一代学子们的到来。在这个信息化的时代,如何让招生简章发挥最大的效用,成为吸引优质生源的关键。 那么如何制作招生简章? 1. 注册账号:访问FLBO…...

Midjourney中文版教程:参数详解

1.长宽比 可以设置图片的纵横比。按照需求可以选择不同的尺寸,也可以自定义。 注意:--ar必须使用整数。使用139:100代替1.39:1。 长宽比会影响生成图像的形状和构图。 在放大时,某些长宽比可能会稍微改变。 较旧的…...

误闯机器学习(第一关-概念和流程)

以下内容,皆为原创,实属不易,请各位帅锅,镁铝点点赞赞和关注吧! 好戏开场了。 一.什么是机器学习 机器学习就是从数据中自动分析获取模型(总结出的数据),并训练模型,去预…...

Tensorflow 2.16.0+在PyCharm中找不到keras的报错解决

在PyCharm(2024.2版本)中,直接使用from tensorflow import keras会提示“Cannot find reference ‘keras’ in ‘init.py’ ”,找不到keras,如下图所示。 查阅相关资料,可以发现在tf2.16之后,默认的keras后端升级为了…...

【Python】高效的Web自动化测试利器—Python+Playwright快速上手自动化实战指南(限时开放)

文章目录 前言一.playwright是什么二.python引入playwright1.安装2.playwright命令行参数3.playwright codegen自动生成代码4.Chrome和Chromium有什么关系?三.基本概念1. 无头浏览器(Headless Browser)2.同步和异步模式操作playwright2.1.同步(Sync)模式同步方式代码模板2…...

CentOS上安装和配置Docker与Docker Compose的详细指南

引言 大家好,我是小阳,在这篇文章中,我将带大家一步步完成在CentOS系统上安装和配置Docker与Docker Compose的过程。通过这篇详细的指南,你将能够轻松配置Docker环境,并在日常开发和部署中享受其带来的便利。 原文阅…...

Vim多文件操作

Vim多文件编辑的实际意义在于它极大地提高了开发者在处理多个相关文件时的效率和便利性。在软件开发、文本编辑、代码审查、配置管理等场景中,经常需要同时打开和操作多个文件。Vim的多文件编辑功能使得这些任务变得更加直观和高效。 提高编码效率:在开发…...

【ARM+Codesys 客户案例 】 基于RK3568/A40i/STM32+CODESYS在智能制造中的应用案例:全自动切片机器人

蔬菜是人们日常生活必不可缺的食品,并且食用方法多种多样。自步入小康社会以来,人们的生活节奏越来越快,很多传统服务已不能满足人们的物质需求和生活节奏。日常生活中通过手工快速切菜严重地威胁着人身安全,切菜时间过长或切菜不…...

NSI程序打包脚本文件编写教程

引言 NSIS (Nullsoft Scriptable Install System) 是一个专业开源的制作 windows 安装程序的工具。我们通过HM NSIEDIT编写好脚本、编译即可生成exe安装包。安装过程中可以配置其安装包图标、名称、出版人、网站等。此外,还可以设置程序开机自启动、管理员权限运行…...

[LitCTF 2023]1zjs

很有意思的一道题,打开题目环境之后F12可以看到 点击那个蓝色下划线的就能看到: 然后访问: /fk3f1ag.php就可以看到: 然后将这些复制到控制台然后回车就能得到flag。...

MCU复位RAM会保持吗,如何实现复位时变量数据保持

在使用MCU时,通常大家默认MCU复位时RAM会被复位清零,那实际MCU复位时RAM是什么状态?如何让mcu复位时RAM保持不变呢? MCU复位有电源复位、Standby复位、内核复位、看门狗复位、引脚复位等。 其中内部会有掉电动作的复位有电源复位…...

解决window 端口的占用问题

netstat -nao | findstr "5554" taskkill -pid 5076 -f 本文资料来自 https://cloud.tencent.com/developer/article/1703982...

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署 什么是RAG: 我能把这个过程理解为Kimi.ai每次都能列出的一大堆网页参考资料吗?Kimi学了这些资料以后,根据这里面的信息综…...

PyTorch 基础学习(10)- Transformer

系列文章: 《PyTorch 基础学习》文章索引 介绍 Transformer模型是近年来在自然语言处理(NLP)领域中非常流行的一种模型架构,尤其是在机器翻译任务中表现出了优异的性能。与传统的循环神经网络(RNN)不同&a…...

mybatis-plus使用

目录 1. 快速开始 1. 创建user表 2. 插入几条数据 3. 创建一个新的springboot项目 4. 导入mybatis-plus依赖 5. 在配置文件中进行配置 6. 编写实体类 7. 编写Mapper 接口类 8. 添加 MapperScan 注解 9. 测试 ​编辑2. CRUD 1. 插入一条语句 2. 根据主键id删除一条记录 3. 根据…...

ant-design-vue快速上手指南及排坑攻略

前言 ant-design-vue是Ant Design的Vue实现,旨在为Vue用户提供一套企业级的UI设计语言。本文将带你快速上手ant-design-vue,并在实践中分享一些常见的坑及解决方法。遵循本文档,让你轻松搭建优雅的Vue应用。 一、环境准备 在开始之前&…...

【GitLab】使用 Docker 安装 3:gitlab-ce:17.3.0-ce.0 配置

参考阿里云的教程docker的重启 sudo systemctl daemon-reload sudo systemctl restart docker配置 –publish 8443:443 --publish 8084:80 --publish 22:22 sudo docker ps -a 當容器狀態為healthy時,說明GitLab容器已經正常啟動。 root@k8s-master-pfsrv:~...

多线程(4)——单例模式、阻塞队列、线程池、定时器

1. 多线程案例 1.1 单例模式 单例模式能保证某个类在程序中只存在唯一一份实例,不会创建出多个实例(这一点在很多场景上都需要,比如 JDBC 中的 DataSource 实例就只需要一个 tip:设计模式就是编写代码过程中的 “软性约束”&am…...

告别电量焦虑,高性能65W PD快充芯片HUSB380A打造梦中情【头】

市面上的充电器越来越卷,让人眼花缭乱。压力同样也给到了快充芯片行业,要在激烈的市场竞争中脱颖而出,快充芯片必须集高功率、高性价比与广泛的兼容性等于一身。 基于此,慧能泰推出了新一代高性能PD Source产品——HUSB380A。 图…...

vulnhub靶场 — NARAK

下载地址:https://download.vulnhub.com/ha/narak.ova Description:Narak is the Hindu equivalent of Hell. You are in the pit with the Lord of Hell himself. Can you use your hacking skills to get out of the Narak? Burning walls and demons are around every cor…...

RabbitMQ如何保证消息不丢失

RabbitMQ消息丢失的三种情况 第一种:生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。 第二种:RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了。 第三种…...

(亲测有效)SpringBoot项目集成腾讯云COS对象存储(1)

目录 一、腾讯云对象存储使用 1、创建Bucket 2、使用web控制台上传和浏览文件 3、创建API秘钥 二、代码对接腾讯云COS(以Java为例) 1、初始化客户端 2、填写配置文件 3、通用能力类 文件上传 测试 一、腾讯云对象存储使用 1、创建Bucket &am…...

无人机之故障排除篇

一、识别故障 掌握基本的无人机系统知识,遵循“先易后难、先外后内、先软件后硬件”的原则进行故障识别。一旦发现故障,立即停止飞行,避免进一步损坏。 二、机械部件维修 对于机身裂痕、螺旋桨损坏等情况,根据损坏程度更换相应部…...

深入理解Python常见数据类型处理

目录 概述数字类型 整数(int)浮点数(float)复数(complex) 字符串(str) 字符串基本操作字符串方法 列表(list) 列表基本操作列表方法列表推导式 元组&#xf…...

搭建一个网站需要多久/百度快照怎么删除

总述 文件存储格式(Text、Sequence、ORC、Parquet)与数据压缩格式(gzip、lzo、snappy、bzip2)的选择是两件事,Text使用Gzip、Bzip2较为推荐,Parquet使用Snappy、Gzip较为推荐。 Hive 语句最终是转化为 MapReduce 程序来执行的,而 MapReduce…...

自己做网站可以赚钱吗/竞价推广渠道

论文看的云里雾里,希望通过阅读其代码来进一步了解。 参考:http://blog.csdn.net/sloanqin/article/details/51525692 首先是./tools/train_faster_rcnn_alt_opt.py,通过其main函数了解整个训练流程。 if __name__ __main__: #建议读者调试这…...

宝塔一键wordpress/域名注册查询

什么是LVM LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性。 逻辑卷管理概念 物理卷&#xff0…...

abcd设计公司/北京网站seo费用

最近因为工作需要申请了3台Linux虚拟机,因为需要多人多地协作,所以开通了互联网访问权限,即给每天服务器配置了公网IP,有一天突然发现服务器运行速度巨慢,就上服务器进行查看,下面把整个过程如实记录&#…...

怎样做b2b网站/网站排名工具

【面向对象设计与构造】第二次博客作业 一、多线程协同和同步控制策略 1. 第五次作业 第五次作业设计了一套由3 部电梯组成的多电梯调度系统,通过采用线程机制, 在第三次作业所实现程序的基础上完成新的调度系统程序。本次作业为调度器,3部电…...

最简单的做网站的软件/seo关键词大搜

针对上一节的插入排序算法,它也有一定的弊端,如下: 数组 arr {2,3,4,5,6,1} 这时需要插入的数 1( 最小), 这样的过程是: {2,3,4,5,6,6} {2,3,4,5,5,6} {2,3,4,4,5,6} {2,3,3,4,5,6} {2,2,3,4,5,6} {1,2,3,4,5,6} 结论: 当 需要插…...