Redis學習其二(事務,SpringBoot整合,持久化RDB和AOF)

文章目錄

  • 5,事務
    • 5.1Redis 事務不保證原子性的原因
    • 5.2事務操作過程
    • 5.3監控
  • 6,SpringBoot整合Redis
    • 6.1Redis客戶端
      • 6.1.1Jedis簡單使用
      • 6.1.2Lettuce&Jedis
    • 6.2配置相關
    • 6.3使用
      • 6.3.1使用RedisTemplate
      • 6.3.2Redis工具類
  • 7,持久化RDB
    • 7.1RDB持久化原理
    • 7.2觸發機制
      • save命令
      • flushall命令
      • bgsave命令
    • 7.3優缺點
  • 8,持久化AOF
    • 8.1AOF持久化原理
    • 8.2相關配置
    • 8.3aof文件重寫
    • 8.3優缺點

5,事務

Redis 事務雖然具備一次性、順序性、排他性(即事務中的命令會按順序執行,且執行期間不會被其他命令插入)。Redis的單條命令是保證原子性的,但是redis事務不能保證原子性。

Redis 事務的本質是一組命令的集合,其執行過程可概括為三個階段:

  1. 開啟事務MULTI):標記事務的開始,后續命令會被加入隊列而非立即執行。
  2. 命令入隊:所有輸入的命令(如SETHSET等)會按順序存入事務隊列,等待執行。
  3. 執行事務EXEC):一次性執行隊列中的所有命令,執行期間不會被其他客戶端的命令干擾。

5.1Redis 事務不保證原子性的原因

原子性的核心是 “要么全部成功,要么全部失敗”,但 Redis 事務不滿足這一點:

  • 若命令語法錯誤(如命令不存在):在EXEC執行前,Redis 會檢測到錯誤并拒絕執行事務,此時所有命令都不執行(類似 “全部失敗”)。
  • 若命令邏輯錯誤(如對字符串執行INCR):EXEC會正常執行其他命令,錯誤命令僅自身失敗,不會影響其他命令(即 “部分成功,部分失敗”)。

例如:

MULTI
SET key1 "123"   // 成功
INCR key1        // 邏輯錯誤(字符串無法自增)
SET key2 "456"   // 成功
EXEC

執行后,key1key2都會被創建,僅INCR key1失敗,事務并未回滾,因此不滿足原子性。

5.2事務操作過程

  • 開啟事務(multi
  • 命令入隊
  • 執行事務(exec

所以事務中的命令在加入時都沒有被執行,直到提交時才會開始執行(Exec)一次性完成。

127.0.0.1:6379> multi # 開啟事務
OK
127.0.0.1:6379> set k1 v1 # 命令入隊
QUEUED
127.0.0.1:6379> set k2 v2 # ..
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> keys *
QUEUED
127.0.0.1:6379> exec # 事務執行
1) OK
2) OK
3) "v1"
4) OK
5) 1) "k3"2) "k2"3) "k1"

取消事務(discurd)

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> DISCARD # 放棄事務
OK
127.0.0.1:6379> EXEC 
(error) ERR EXEC without MULTI # 當前未開啟事務
127.0.0.1:6379> get k1 # 被放棄事務中命令并未執行
(nil)

事務錯誤

代碼語法錯誤(編譯時異常)所有的命令都不執行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> error k1 # 這是一條語法錯誤命令
(error) ERR unknown command `error`, with args beginning with: `k1`, # 會報錯但是不影響后續命令入隊 
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors. # 執行報錯
127.0.0.1:6379> get k1 
(nil) # 其他命令并沒有被執行

代碼邏輯錯誤 (運行時異常) **其他命令可以正常執行 ** >>> 所以不保證事務原子性

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> INCR k1 # 這條命令邏輯錯誤(對字符串進行增量)
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR value is not an integer or out of range # 運行時報錯
4) "v2" # 其他命令正常執行# 雖然中間有一條命令報錯了,但是后面的指令依舊正常執行成功了。
# 所以說Redis單條指令保證原子性,但是Redis事務不能保證原子性。

5.3監控

悲觀鎖(Pessimistic Locking)

核心思想:總是假設最壞的情況,認為數據隨時可能被其他線程修改,因此在訪問數據前先加鎖,確保只有自己能操作數據。

樂觀鎖(Optimistic Locking)

核心思想:假設數據一般不會被其他線程修改,因此不上鎖,僅在更新數據時檢查是否有人在此期間修改過(使用版本號進行檢查)。

而Redis使用watch key監控指定數據,相當于樂觀鎖加鎖。監控某一key后,如果key在一個線程/客戶端A執行事務時,有另外一個客戶端/線程B對key進行修改,則執行A的事務失敗(全部失敗)。

并且Redis 的 WATCH 是一次性的,且第二次事務沒有重新執行 WATCH money

案例一:成功案例

客戶端B在客戶端A的事務期間執行(multi之后和exec之前)。

-------------客戶端A--------------
127.0.0.1:6379[2]> set money 100
OK
127.0.0.1:6379[2]> set use 0
OK
127.0.0.1:6379[2]> watch money
OK
127.0.0.1:6379[2]> multi
OK
127.0.0.1:6379[2]> decrby money 20
QUEUED
127.0.0.1:6379[2]> incrby money 20
QUEUED
127.0.0.1:6379[2]> exec
(nil)
127.0.0.1:6379[2]> get money
"600"
127.0.0.1:6379[2]> get use
"0"
-------------客戶端B--------------
127.0.0.1:6379[2]> incrby money 500
(integer) 600

案例二:失敗案例

客戶端B在客戶端A的第二次事務期間執行(multi之后和exec之前)。這就是“Redis 的 WATCH 是一次性的,且第二次事務沒有重新執行 WATCH money。”

-------------客戶端A--------------
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set use 0
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby use 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> get use
"20"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> incrby use 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 560
2) (integer) 40
-------------客戶端B--------------
127.0.0.1:6379> incrby money 500
(integer) 580

6,SpringBoot整合Redis

6.1Redis客戶端

什么是客戶端?在 Spring Boot 應用中,Redis 客戶端是指用于連接和操作 Redis 數據庫的工具庫。spring-boot-starter-data-redis作為官方提供的啟動器,默認集成了Lettuce作為 Redis 客戶端。

6.1.1Jedis簡單使用

使用Java來操作Redis,Jedis是Redis官方推薦使用的Java連接redis的客戶端。

  1. 導入依賴

    <!--導入jredis的包-->
    <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version>
    </dependency>
    <!--fastjson-->
    <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version>
    </dependency>
    
  2. 這里直接在springboot的測試類里測試了

    @SpringBootTest
    public class One {@Testpublic void test() {Jedis jedis = new Jedis("127.0.0.1", 6379);String pong = jedis.ping();System.out.println(pong);}@Testpublic void test2() {Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.select(2);JSONObject jsonObject = new JSONObject();jsonObject.put("hello", "world");jsonObject.put("name", "Selena");// 開啟事務Transaction multi = jedis.multi();String result = jsonObject.toJSONString();try {multi.set("user1", result);multi.set("user2", result);// 執行事務multi.exec();}catch (Exception e){// 放棄事務multi.discard();} finally {// 關閉連接System.out.println(jedis.get("user1"));System.out.println(jedis.get("user2"));jedis.close();}}
    }
    

6.1.2Lettuce&Jedis

在 Spring Boot 應用中,spring-boot-starter-data-redis默認使用 Lettuce 作為 Redis 客戶端,因為其依賴中包含lettuce-core包。若要切換為 Jedis,需排除 Lettuce 并引入 Jedis 依賴。

特性LettuceJedis
連接模型基于 Netty 的響應式、非阻塞 I/O,支持異步和多路復用基于傳統 BIO(阻塞 I/O),每次操作需新建連接
線程安全性線程安全,可多線程共享連接實例線程不安全,需通過連接池管理連接
資源消耗使用 Netty 事件循環,資源消耗少,適合長連接頻繁創建 / 銷毀連接,資源消耗大,依賴連接池降開銷
功能特性支持響應式編程(Reactive Redis API)、集群和哨兵模式提供傳統同步 API,適合簡單業務場景
適用場景高并發、異步操作、響應式應用(如 Spring WebFlux)簡單同步操作、傳統 Servlet 應用

6.2配置相關

RedisProperties 是 Spring Boot 中用于配置 Redis 連接信息的核心配置類,位于 org.springframework.boot.autoconfigure.data.redis 包下。它通過 @ConfigurationProperties 注解綁定 spring.redis 前綴的配置項,讓你可以在 application.propertiesapplication.yml 中輕松配置 Redis 連接參數。

此外,RedisAutoConfiguration這個類,顧名思義就是Redis的自動化配置。在這個類中,會引入LettuceConnectionConfiguration 和 JedisConnectionConfiguration 兩個配置類,分別對應lettuce和jedis兩個客戶端。而這個兩個類上都是用了ConditionalOnClass注解來進行判斷是否加載。

而由于我們的項目自動引入了lettuce-core,而沒有引入jedis相關依賴,所以LettuceConnectionConfiguration這個類的判斷成立會被加載,而Jedis的判斷不成立,所以不會加載。進而lettuce的配置生效,所以我們在使用的使用, 默認就是lettuce的客戶端。

配置文件(基礎配置):

server: # 服務器配置port: 8080servlet:context-path: /
spring:# redis 配置redis:# 地址host: localhost# 端口,默認為6379port: 6379# 數據庫索引database: 0# 密碼password:# 連接超時時間timeout: 10s

但是有的時候我們想要給我們的redis客戶端配置上連接池。就像我們連接mysql的時候,也會配置連接池一樣,目的就是增加對于數據連接的管理,提升訪問的效率,也保證了對資源的合理利用。

如果使用的是jedis,就把lettuce換成jedis(同時要注意依賴也是要換的)。

spring:# redis 配置redis:# 地址host: localhost# 端口,默認為6379port: 6379# 數據庫索引database: 0# 密碼password:# 連接超時時間timeout: 10slettuce:pool:# 連接池中的最小空閑連接min-idle: 0# 連接池中的最大空閑連接max-idle: 8# 連接池的最大數據庫連接數max-active: 8# #連接池最大阻塞等待時間(使用負值表示沒有限制)max-wait: -1ms

但是僅僅這在配置文件中加入,其實連接池是不會生效的。還少了最關鍵的一步,就是要導入一個依賴,不導入的話,這么配置也沒有用。

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

之后,連接池才會生效。我們可以做一個對比。 在導包前后,觀察RedisTemplate對象的值就可以看出來。

添加依賴前:
在這里插入圖片描述

添加依賴后:

在這里插入圖片描述

6.3使用

6.3.1使用RedisTemplate

簡單案例:

@SpringBootTest
public class RedisTemplateTest {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testRedisTemplate1() {redisTemplate.opsForValue().set("name", "saber");}
}

在 Spring 的RedisTemplate中,opsForValue()是用于獲取操作 Redis 字符串(String)類型數據的操作接口,通過它能執行一系列針對字符串的操作。除了opsForValue()外,RedisTemplate還提供了opsForHash()(操作哈希類型數據)、opsForList()(操作列表類型數據 )、opsForSet()(操作集合類型數據 )和opsForZSet()(操作有序集合類型數據)等方法,方便開發者針對不同的 Redis 數據類型進行操作。

拿opsForValue()舉例,其常用方法

  • set(String key, Object value):將鍵值對存儲到 Redis 中。如果對應的 key 已經存在,新值會覆蓋舊值。
  • get(String key):根據給定的 key,從 Redis 中獲取對應的字符串值,如果 key 不存在,則返回null
  • set(String key, Object value, long timeout, TimeUnit unit):存儲鍵值對,并設置該鍵值對的過期時間。
  • increment(String key, long delta):對存儲在 Redis 中的數字類型的 key 進行自增操作,delta表示自增的步長,返回自增后的值。若 key 不存在,會將其初始化為delta的值。
  • decrement(String key, long delta):對存儲在 Redis 中的數字類型的 key 進行自減操作,delta表示自減的步長,返回自減后的值。

6.3.2Redis工具類

Redis工具類-CSDN博客

7,持久化RDB

7.1RDB持久化原理

RDB 是 Redis 默認的持久化方式,其核心機制是:

  • 定期執行:Redis 在指定時間間隔內(如 5 分鐘),將內存中的數據快照保存為二進制文件(默認名為dump.rdb可以通過配置文件修改)。
  • fork 子進程:執行快照時,Redis 主進程會fork一個子進程,由子進程負責將數據寫入磁盤,主進程繼續處理客戶端請求。
  • 全量復制:RDB 文件包含某一時刻 Redis 的全部數據,恢復時直接加載整個文件。

fork是操作系統提供的一個系統調用,用于創建一個與父進程幾乎完全相同的子進程。RDB 持久化需要將內存中的全量數據寫入磁盤,如果由主線程直接執行,會導致長時間阻塞(尤其數據量大時),影響 Redis 的響應性能。

在進行 RDB 的時候,redis 的主線程是不會做 io 操作的,主線程會 fork 一個子線程來完成該操作;

  1. Redis 調用forks。同時擁有父進程和子進程。
  2. 子進程將數據集寫入到一個臨時 RDB 文件中。
  3. 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,并刪除舊的 RDB 文件。

這種工作方式使得 Redis 可以從寫時復制(copy-on-write)機制中獲益(因為是使用子進程進行寫操作,而父進程依然可以接收來自客戶端的請求。)

1,寫時復制(Copy-On-Write):初始時,父子進程共享同一塊物理內存;當父進程或子進程修改數據時,才會復制被修改的內存頁,避免了全量復制的性能消耗。

2,什么是 “臨時的 RDB 文件”?

在 RDB 持久化過程中,子進程并非直接寫入最終的 RDB 文件(如默認的dump.rdb),而是先將內存數據寫入一個臨時文件(例如命名為temp-xxx.rdb)。

臨時文件的作用是:

  • 保證數據完整性:如果子進程在寫入過程中意外崩潰(如磁盤滿、進程被 kill),臨時文件會被丟棄,不會影響原有的 RDB 文件(原文件仍可用于恢復數據)。
  • 避免部分寫入:如果直接寫入目標文件,中途失敗會導致目標文件損壞,而臨時文件可確保只有當全量數據寫入完成后,才會成為有效的 RDB 文件。

3,替換過程是怎樣的?

當子進程成功將全量數據寫入臨時文件后,Redis 會執行原子性的文件替換操作

  1. 子進程完成寫入后,通知主進程 “臨時文件已就緒”。
  2. 主進程通過操作系統的rename(或類似)系統調用,將臨時文件重命名為目標 RDB 文件名(如dump.rdb)。
    • 例如:temp-xxx.rdbdump.rdb
  3. 替換完成后,刪除舊的dump.rdb文件(如果存在)。這意味著舊的數據會被新的數據覆蓋。

7.2觸發機制

  1. save的規則(配置文件中設值,在快照模塊,如下)滿足的情況下,會自動觸發rdb原則
  2. 執行flushall命令,也會觸發我們的rdb原則
  3. 退出redis,也會自動產生rdb文件

配置文件相關內容

# 當至少1個key被修改且時間超過900秒(15分鐘)時,執行一次快照
save 900 1
# 當至少10個key被修改且時間超過300秒(5分鐘)時,執行一次快照
save 300 10
# 當至少10000個key被修改且時間超過60秒時,執行一次快照
save 60 10000# RDB文件保存路徑
dir ./# RDB文件名
dbfilename dump.rdb# 啟用壓縮(可能影響性能)
rdbcompression yes

save命令

使用 save 命令,會立刻對當前內存中的數據進行持久化 ,但是會阻塞,也就是不接受其他操作了;

由于 save 命令是同步命令,會占用Redis的主進程。若Redis數據非常多時,save命令執行速度會非常慢,阻塞所有客戶端的請求。

flushall命令

flushall 命令也會觸發持久化 ;

bgsave命令

bgsave 是異步進行,進行持久化的時候,redis 還可以將繼續響應客戶端請求 ;配置文件中的save規則本質上也是bgsave,異步執行數據持久化。
在這里插入圖片描述

bgsave和save對比

命令savebgsave
IO類型同步異步
阻塞?是(阻塞發生在fock(),通常非常快)
復雜度O(n)O(n)
優點不會消耗額外的內存不阻塞客戶端命令
缺點阻塞客戶端命令需要fock子進程,消耗內存

7.3優缺點

優點:

  1. 適合大規模的數據恢復,相比AOF恢復速度快。
  2. 對數據的完整性要求不高

缺點:

  1. 需要一定的時間間隔進行操作,如果redis意外宕機了,這個最后一次修改的數據就沒有了,破快數據完整性。
  2. fork進程的時候,會占用一定的內容空間。

8,持久化AOF

8.1AOF持久化原理

Append Only File

將我們所有的命令都記錄下來,恢復的時候就把這個文件全部再執行一遍。

AOF 通過追加寫命令到日志文件的方式實現持久化:

  1. 命令實時記錄:Redis 執行寫命令后,會將命令追加到 AOF 緩沖區(內存)。
  2. 緩沖區同步到磁盤:根據配置的同步策略(fsync),將緩沖區中的命令寫入磁盤 AOF 文件。
  3. 文件重寫(AOF Rewrite):定期通過BGREWRITEAOF命令對 AOF 文件進行瘦身,去除冗余命令。

8.2相關配置

如果要使用AOF,需要修改配置文件:

在這里插入圖片描述

appendonly no yes則表示啟用AOF

默認是不開啟的,我們需要手動配置,然后重啟redis,就可以生效了!

相關配置:

appendonly yes  # 默認是不開啟aof模式的,默認是使用rdb方式持久化的,在大部分的情況下,rdb完全夠用
appendfilename "appendonly.aof"# appendfsync always # 每次修改都會sync 消耗性能
appendfsync everysec # 每秒執行一次 sync 可能會丟失這一秒的數據
# appendfsync no # 不執行 sync ,這時候操作系統自己同步數據,速度最快# AOF文件重寫觸發條件
auto-aof-rewrite-percentage 100  # 當前AOF文件大小超過上次重寫后大小的100%時觸發
auto-aof-rewrite-min-size 64mb   # AOF文件最小達到64MB時才考慮重寫

8.3aof文件重寫

重寫的作用:通過生成一個只包含當前數據庫最新狀態的 AOF 文件,替代舊文件,大幅減小文件體積。隨著 Redis 運行,AOF 文件會不斷追加寫命令,導致文件體積膨脹,例如:對同一 key 多次修改(如SET k 1 → SET k 2 → SET k 3),舊命令變得冗余。就是舍去大量的中間狀態,并記錄當前數據庫最新的狀態。

觸發方式

  1. 自動觸發:當滿足以下兩個條件時,Redis 自動觸發重寫:

    auto-aof-rewrite-percentage 100  # 當前AOF文件大小超過上次重寫后大小的100%
    auto-aof-rewrite-min-size 64mb   # AOF文件最小達到64MB才考慮重寫
    
  2. 手動觸發:執行命令:

    redis-cli BGREWRITEAOF
    

重寫執行的流程。

  1. 主線程 fork 子進程
    • 主線程通過fork()創建子進程,子進程獲得當前內存數據的副本。
    • 關鍵特性:寫時復制(Copy-On-Write),父子進程共享內存,僅在修改數據時復制內存頁,避免全量內存拷貝。
  2. 子進程生成新 AOF 文件
    • 子進程遍歷內存中的所有鍵值對,生成對應的寫命令序列(如SET k vHSET hash f v)。
    • 新 AOF 文件僅包含重建當前數據庫所需的最小命令集,不包含任何冗余命令。
  3. 處理增量寫命令
    • 在子進程重寫期間,主線程繼續處理客戶端請求,并將新的寫命令同時追加到:
      • 舊 AOF 文件:確保當前持久化過程不受影響。
      • AOF 重寫緩沖區:保存重寫期間的增量命令。
  4. 替換舊文件
    • 子進程完成重寫后,向主線程發送信號。
    • 主線程將 AOF 重寫緩沖區中的增量命令追加到新 AOF 文件中。
    • 主線程使用原子性的rename()系統調用,將新 AOF 文件替換舊文件。

8.3優缺點

優點

  1. 每一次修改都會同步,文件的完整性會更加好
  2. 每秒同步一次,可能會丟失一秒的數據
  3. 從不同步,效率最高

缺點

  1. 相對于數據文件來說,aof遠遠大于rdb,修復速度比rdb慢!
  2. Aof運行效率也要比rdb慢,所以我們redis默認的配置就是rdb持久化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89366.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89366.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89366.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

springboot項目部署到K8S

java后臺 創建harbor鏡像拉取Secret&#xff1a;kubectl create secret docker-registry harbor-regcred \--docker-server \ #harbor倉庫地址--docker-username \ #harbor 賬號--docker-password \ #harbor密碼-n productionDockerfile FROM *harbor地址*/library/custom-jdk…

【FPGA開發】一文輕松入門Modelsim的基本操作

Modelsim仿真的步驟 &#xff08;1&#xff09;創建新的工程。 &#xff08;2&#xff09;在彈出的窗口中&#xff0c;確定項目名和工作路徑&#xff0c;庫保持為work不變(如有需要可以根據需求進行更改)。 &#xff08;3&#xff09;添加已經存在的文件&#xff08;rtl代碼和t…

服務攻防-Java組件安全FastJson高版本JNDI不出網C3P0編碼繞WAF寫入文件CI鏈

服務攻防-Java組件安全&FastJson&高版本JNDI&不出網C3P0&編碼繞WAF&寫入文件CI鏈26天 原創 朝陽 Sec朝陽 2025年07月18日 09:23 湖北 標題已修改 演示環境&#xff1a; https://github.com/lemono0/FastJsonParty FastJson全版本Docker漏洞環境(涵蓋1.…

【Python】DRF核心組件詳解:Mixin與Generic視圖

在 Django REST Framework (DRF) 中&#xff0c;mixins.CreateModelMixin、mixins.ListModelMixin、GenericAPIView 和 GenericViewSet 是構建 API 視圖的核心組件。以下是對這些組件的主要方法及其職責的簡要說明&#xff0c;內容清晰且結構化&#xff1a;1. mixins.CreateMod…

HTML+CSS+JS基礎

文章目錄&#xff08;一&#xff09;html1.常見標簽&#xff08;1&#xff09;注釋&#xff08;2&#xff09;標題 h1~h6&#xff08;3&#xff09;段落 p&#xff08;4&#xff09;換行與空格 br \ &#xff08;5&#xff09;格式化標簽 b i s u&#xff08;6&#xff09;…

Vue導出Html為Word中包含圖片在Microsoft Word顯示異常問題

問題背景 碰到一個問題&#xff1a;將包含圖片和SVG數學公式的HTML內容導出為Word文檔時&#xff0c;將圖片都轉為ase64格式導出&#xff0c;在WPS Word中顯示正常&#xff0c;但是在Microsoft Word中出現圖片示異常。具體問題表現 WPS兼容性&#xff1a;在WPS中顯示正常&#…

橢圓曲線密碼學 Elliptic Curve Cryptography

密碼學是研究在存在對抗行為的情況下還能安全通信的技術。即算法加密信息&#xff0c;再算法解密出信息。加密分為兩類 1. Symmetric-key Encryption (secret key encryption) 即一種密鑰&#xff0c;加密和解密使用同一密鑰&#xff0c;可相互轉換 2. Asymmetric-key Encry…

wedo牛-----第47節(免費分享圖紙)

夸克網盤&#xff1a;https://pan.quark.cn/s/4b40a8d18979 高清圖紙源文件&#xff0c;需要的請自取

Unity | AmplifyShaderEditor插件基礎(第十集:噪聲的種類+火焰制作-下)

目錄 一、&#x1f44b;&#x1f3fb;前言 二、圓火焰 三、制作梯度 梯度成品預覽 1.GradientSample節點 2.gradient的用法 3.time節點 四、添加顏色 Color節點 五、火焰搖擺 1.X方向的移動 2.Y方向的移動 3.Z方向的移動 4.把xyz組合起來 Panner節點 六、擺放和…

黑馬Node.js全套入門教程,nodejs新教程含es6模塊化+npm+express+webpack+promise等_ts對象筆記

1.1 什么是運行環境&#xff1f; 運行環境是指代碼正常運行所需的必要環境&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; V8引擎負責解析和執行JavaScript代碼。內置API是由運行環境提供的特殊接口&#xff0c;只能在所屬的運行環境中被調用 1.2 JavaScrip…

React 項目環境變量使用指南

在 React 項目中正確使用環境變量是管理不同環境配置的關鍵技術。以下是完整的解決方案&#xff1a; 1. 創建環境變量文件 React 項目支持以下環境變量文件&#xff08;按優先級從高到低&#xff09;&#xff1a; .env.development.local (本地開發環境).env.development (開發…

Oracle 關于一些連接故障的總結

積累了幾次Oracle客戶端連接故障&#xff0c;做下總結。 文章目錄1、案例案例1&#xff1a;客戶端連接報錯ORA-12514案例2&#xff1a;客戶端連接報錯ORA-28547案例3&#xff1a;客戶端連接報錯&#xff1a;Got minus one from a read call案例4&#xff1a;客戶端連接報錯&…

V-USB USB設備模擬原理分析

V-USB USB設備模擬原理分析 通過分析V-USB項目的核心文件&#xff0c;詳細解釋這個項目是如何在AVR微控制器上模擬USB設備的&#xff1a; 1. 整體架構 V-USB是一個純軟件實現的USB低速設備驅動&#xff0c;主要由以下幾個核心文件組成&#xff1a; usbdrv.c : USB協議棧的C語言…

kafka3.6下載安裝(傳統架構/KRaft模式)+實例測試

知識補充&#xff1a; Kafka 和 ZooKeeper 的關系可以用 “協作依賴” 來概括。在 Kafka 的早期版本&#xff08;Kafka 2.8.0 之前&#xff09;中&#xff0c;ZooKeeper 是 Kafka 的核心依賴&#xff0c;用于管理集群元數據、協調 Broker 和 Controller 選舉等關鍵功能。但從 …

華控智能產品特點——產品生態全景與場景化創新

公司構建 “3X”產品戰略&#xff0c;以三大核心場景為基礎持續拓展技術外延&#xff1a; 1. 智能安防產品線軍工級指紋槍盒&#xff1a;采用6061-T6航空鋁材&#xff0c;內嵌震動報警模塊&#xff0c;非法開箱觸發90dB警鳴。為軍工企業定制的雙人認證版本需兩位授權人員同時驗…

爬蟲核心原理與入門技巧分析

一、爬蟲核心原理&#xff1a;模擬人類瀏覽的“自動化工具” 簡單來說&#xff0c;網絡爬蟲&#xff08;Web Crawler&#xff09;是一種按照一定規則&#xff0c;自動抓取互聯網信息的程序或腳本。其核心原理可以類比人類瀏覽網頁的過程&#xff0c;只不過將手動操作轉化為了代…

spring-cloud微服務部署-feign服務間調用

1 準備工作 需要安裝并啟動nacos&#xff0c;作為服務注冊中心。地址&#xff1a;https://nacos.io/ 2 項目結構 parent的pom.xml聲明依賴&#xff1a; <dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</gr…

IDEA高效開發:Database Navigator插件安裝與核心使用指南

目錄 1.前言 2.正文 2.1安裝流程 2.1.1IDE內部安裝 2.1.2手動下載安裝 ?? 避坑指南 2.2使用教程 2.2.1連接數據庫 2.2.2查看數據庫/表 2.2.3查詢數據 2.2.4修改表結構 2.2.5生成代碼 2.2.6常見故障排除 3.小結 1.前言 “作為Java開發者&#xff0c;日常與數據…

Maven私服倉庫,發布jar到私服倉庫,依賴的版本號如何設置,規范是什么

Maven私服倉庫&#xff0c;發布jar到私服倉庫&#xff0c;依賴的版本號如何設置&#xff0c;規范是什么

量子卷積神經網絡:量子計算與深度學習的融合革命

引言&#xff1a;當卷積神經網絡遇上量子計算在人工智能與量子計算雙重浪潮的交匯處&#xff0c;量子卷積神經網絡&#xff08;Quantum Convolutional Neural Network, QCNN&#xff09;正成為突破經典算力瓶頸的關鍵技術。傳統卷積神經網絡&#xff08;CNN&#xff09;在圖像識…