Redis 基本認識(筆試、面試題)

来源:https://www.cnblogs.com/l-y-h/archive/2020/04/16/12715723.html
-Advertisement-
Play Games

一、Redis 1、簡介 【官方簡介地址:】 https://redis.io/topics/introduction 看不懂不要緊,先混個眼熟,慢慢來...。 【初步認識 Redis:】 Redis is an open source (BSD licensed), in-memory data ...


一、Redis

1、簡介

【官方簡介地址:】
    https://redis.io/topics/introduction

  看不懂不要緊,先混個眼熟,慢慢來...。

【初步認識 Redis:】
    Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.

【翻譯:】
    Redis 是一個開源的、基於記憶體的數據存儲結構,可以作為資料庫、緩存、消息中間件。
    
【重點:】
    基於記憶體、支持多種數據結構、常用於緩存。

 

2、為什麼使用 Redis 作為緩存?

(1)為什麼要使用緩存?
  對於一個系統來說,若直接操作資料庫,每次讀寫都經過磁碟操作,當併發量過高時,磁碟讀寫速度極大地影響系統的性能。使用緩存,即在訪問磁碟前設置一個緩衝區,若緩衝區沒有數據,再去資料庫進行操作,這樣可以極大地減少磁碟操作,從而提高系統性能。

(2)Redis 是基於記憶體的、一個高性能的 key - value 資料庫(非關係型資料庫)。
  記憶體的處理速度比操作磁碟快,可以提高性能。
  緩存分擔了部分請求,減少了資料庫訪問壓力,提高了併發量。
  說起 key - value 庫,容易想到 Java 中的 Map,map 實現的是本地緩存(即每台機器各自擁有自己的緩存),容量有限,隨著 JVM 存在、消失。而 Redis 實現的是分散式緩存(即多台機器可以共用一份緩存數據),其數據可以持久化到硬碟中,可以自定義緩存過期機制。

 

3、Redis 的數據結構?使用場景?

(1)常用命令:

【參考地址:】
    http://doc.redisfans.com/
    https://www.cnblogs.com/l-y-h/p/12656614.html

(2)常用數據結構:
  Redis 是由 C 語言編寫的,其存儲是以 key - value 的形式。key 為字元串,value 為 Redis 的數據結構。常用數據結構為:string、list、set、hash、sortedset。
  底層實現原理,以後有空再去研究...
  不同數據結構,若採用不同的編碼格式,底層會有不同的實現。

(3)常用數據結構使用場景(舉例,可能不太恰當,大致理解一下):
  String 使用場景:
  比如:一些博客、文章的閱讀量、點贊數等。

  可以根據 文章 ID 生成一個鍵。當某用戶閱讀、點贊後,在相應的 value 上加 1。
  比如 :
    key 為 文章閱讀量:文章id,
    value 為對應的 文章閱讀量。
    可以通過 incr、decr 等進行加減閱讀量。

【根據文章ID 生成一個 key:(每個文章都有不同的 id,從而區分不同的 key)】
    set article:readcount:1001 0      文章 id 為 1001 的文章當前閱讀量為 0
    set article:readcount:1002 0      文章 id 為 1002 的文章當前閱讀量為 0

【閱讀時,數量增 1:】
    incr article:readcount:1001       文章 id 為 1001 的文章閱讀量加 1
    
【獲取閱讀量:】
    get article:readcount:1001        獲取文章 id 為 1001 的文章閱讀量

 

 

 

Hash 使用場景:
  比如:電商網站的購物車。

  可以根據 用戶ID 生成一個 key,商品 ID 為 field,商品數量為 field 對應的 value。
  可以使用 hgetall 獲取所有的 field - value,即實現全選。
  可以使用 hincrby 對指定的 field 修改數量。
  可以使用 hlen 獲取當前購物車商品的種類。等等操作。

比如:
  key 為 用戶 ID user:用戶 ID
  field 為 商品 ID wares:商品 ID
  value 為 商品數量 商品數量

註:

  其餘信息可以通過 ajax 根據 用戶 ID 、商品 ID 進行查詢並返回顯示。

【根據用戶 ID、商品 ID、商品數量 生成一個 key,】
    hset user:10001 wares:3001 110001 用戶 添加 一個 3001 商品。
    hset user:10001 wares:3002 210001 用戶 添加 兩個 3002 商品。
    
【全選操作:】
    hgetall user:10001             獲取 10001 用戶所有的 商品(field)以及數量(value)
    
【增加商品數量:】
    hincrby user:10001 wares:3002 310001 用戶再增加 33002 商品

 

 

 

List 使用場景:
  比如:微信訂閱號推送的消息。

  不同的公眾號推送消息有先有後,最後是按照時間順序進行排序顯示(最近的時間顯示在最上面)。
  可以使用 List 存儲接收的消息 ID。每接受一個 公眾號消息 的 ID,就 LPUSH 進 List 中,最後使用 LRANGE 去獲取最新的推送消息。

【接收公眾號推送消息的 ID:】
    LPUSH msg:我的訂閱號-id 安徽共青團:10001
    LPUSH msg:我的訂閱號-id 唐唐頻道:20001
    LPUSH msg:我的訂閱號-id 全是黑科技:34811
    LPUSH msg:我的訂閱號-id 程式人生:2233
    LPUSH msg:我的訂閱號-id 共青團中央:32345
    
【展示公眾號 ID:】
    LRANGE msg:我的訂閱號-id 0 -1

 

 

 

Set 使用場景:
  比如:抽獎小程式,獲取朋友圈點贊的用戶信息,可能關註的人(需要使用並集等操作)等。
  抽獎就是在一堆用戶中隨機抽取用戶。由於 Set 不可重覆性,可以保證用戶唯一。
  使用 SADD 可以添加用戶 ID 到 set 中。
  使用 SMEMBERS 可以查看當前參與抽獎的所有元素。
  使用 SRANDMEMBER、SPOP 可以抽取獲獎者用戶。

【添加用戶:】
    sadd user 1001 1002 1003 1004
    
【查看所有用戶:】
    smembers user
    
【抽選用戶,不刪除用戶:】
    srandmember user 3
    
【抽選用戶,刪除用戶:】
    spop user 3

 

 

 

sortedset(zset)使用場景:
  比如:微博熱搜榜、百度熱議榜等。

 

 

 

二、Redis 持久化、資料庫、單線程

1、Redis 資料庫

  Redis 預設有 16 個庫,庫編號為 db0 - db15。資料庫之間的數據是相互隔離的、互不影響的。
  Redis 是 C/S 結構,有一個 redis-cli 和 redis-server。 redis-server 用於啟動 Redis 服務,預設資料庫數量為 16,可以修改。redis-cli 用於連接某個資料庫。
  資料庫中採用哈希表存儲鍵值對,其中 value 可以為不同類型的數據結構。

2、Redis 鍵過期處理

(1)為什麼進行過期處理?
  Redis 是基於記憶體的,記憶體容量比較有限,如果長期將 key - value 存放在 記憶體中,會占用大量記憶體,這樣肯定是不行的,所以需要對 key 設置過期時間,當 key 過期後,系統響應並將其刪除,從而減少記憶體的占用。

(2)過期策略:
  定時刪除:到某個時間點,就進行刪除 過期鍵 的操作,對 記憶體 友好,對 CPU 不友好。
  惰性刪除:每次獲取鍵時,判斷該鍵是否過期,過期則刪除,對 CPU 友好,對 記憶體 不友好。
  定期刪除:每過一段時間,就去刪除 過期鍵。
  Redis 中採用 惰性刪除 + 定期刪除,即意味著 某個鍵 到了過期時間,也不一定會被立即刪除。

(3)記憶體淘汰機制:
  由於 Redis 可能會不及時的刪除過期 key,導致 記憶體里堆積了很多沒用的 key,會消耗大量記憶體。此時,需要通過記憶體淘汰機制,選擇不需要的 key,並將其刪除。
  比如:設置消耗記憶體最大值,當超過記憶體最大值後,進行數據淘汰,將最近最少使用的 key 數據淘汰(一般應用於熱搜排行榜的場景)。

【常見記憶體淘汰機制:】
    allkeys-lru:      在所有 key 中,移除最近最少使用的 key(常用)
    allkeys-random:   在所有 key 中,隨機移除 key。
    volatile-lru:     在設置過期時間的 key 中,移除最近最少使用的 key
    volatile-random:  在設置過期時間的 key 中,隨機移除 key。
    volatile-ttl:     在設置過期時間的 key 中,優先移除 即將過期 的 key。

 

3、數據持久化 -- RDB

  Redis 是基於記憶體的,Redis 一旦重啟,所有數據都會丟失,所以一般會將數據持久化到硬碟中,Redis 重啟後可以通過硬碟恢複數據。
  Redis 採用兩種方法進行數據持久化 -- RDB 、AOF。
(1)RDB(Redis DataBase)
  RDB 基於快照,可以指定時間間隔、將某一時刻的所有數據保存到一個 RDB 文件中,是一個二進位文件,預設為 dump.rdb。Redis 啟動時,若發現存在 rdb 文件,則會自動載入該文件(載入的過程是一個阻塞的狀態)。

(2)通過三種方式可以實現 RDB。
  Method1:SAVE 命令觸發
    客戶端執行 SAVE 命令後,會阻塞當前 Redis 伺服器(即 Redis 不能處理其他命令),直到 RDB 過程結束。若存在舊的 RDB 文件,會進行替換。(此方式若數據量過大,會影響系統性能)

  Method2:BGSAVE 命令觸發
    客戶端執行 BGSAVE 命令後,會創建一個子進程,由子進程來創建 RDB 文件,不會阻塞當前 Redis 伺服器。

  Method3:redis.conf 配置文件中配置

【save 格式:】
    save m n          指的是 m 時間間隔內,至少出現了 n 次 key 變化,則進行保存

【舉例:】
    save 60 10000       指的是 60 秒內,至少出現了 10000 次 key 變化,則保存

 

(3)SAVE 與 BGSAVE 比較:
  SAVE 屬於 同步操作,會阻塞當前 Redis 伺服器,但不會消耗額外記憶體。
  BGSAVE 屬於 非同步操作,不會阻塞當前 Redis 伺服器,但會消耗額外記憶體(創建子進程)。

(4)RDB 優缺點:
  優點:
    RDB 是全量備份,將數據壓縮到二進位文件中,格式緊湊(文件小),適合數據備份以及恢復。
    RDB 可以使用子進程去創建 RDB 文件,主進程不進行 磁碟操作。
  缺點:
    子進程進行持久化時,父進程若修改記憶體中的數據,子進程不會知曉,此時可能造成數據丟失。

 

4、數據持久化 -- AOF

(1)AOF(Append Only File)
  AOF 指當 Redis 伺服器執行寫命令時,會將寫命令 保存到 AOF 文件中(可以理解為日誌記錄)。

(2)AOF 執行流程:
  Step1:命令追加到緩衝區
    遇到寫命令時,將命令寫入 aof_buf 緩衝區。

  Step2:確認是否需要將緩衝區內容寫入文件。
    通過配置文件 redis.conf 中 appendfsync 去確定是否將緩衝區內容寫入文件。

    appendfsync always     # 每次有數據修改發生時都會寫入AOF文件(磁碟開銷大)。
    appendfsync everysec   # 每秒鐘同步一次,該策略為AOF的預設策略(丟失 1 秒數據)。
    appendfsync no         # 從不同步。高效但是數據不會被持久化(數據丟失)。

 

  Step3:文件從緩衝區寫入到文件。
    將緩衝區的內容寫入到 aof 文件中。

  不停的執行寫命令操作後,會使得 aof 文件變得越來越大,可以使用 BGREWRITEAOF 命令進行 AOF 重寫(可以合併 寫操作命令,減少文件內容冗餘),此重寫基於當前 資料庫數據重寫,不需要讀取舊的 aof 文件。
  BGREWRITEAOF 命令會創建子進程,由子進程進行 AOF 重寫,其會存在一個 AOF 重寫緩衝區,重寫緩衝區用於 記錄 創建子進程後 主進程執行的 寫操作。當子進程執行完 AOF 重寫後,向父進程發送請求,將重寫緩衝區的數據寫入新的 aof 文件中,從而使 當前資料庫 與 AOF 文件寫操作一致。

(3)AOF優缺點:
  優點:
    可以更好的保護數據,預設進行 1 秒同步一次的操作,最多丟失 1 秒數據。
  缺點:
    AOF 文件過大,恢複數據速度較慢。

(4)AOF、RDB 如何選擇?
  AOF、RDB 可以同時使用,但伺服器優先使用 AOF 文件進行數據還原。
  AOF:丟失數據少(視 appendfsync 而定),文件體積大,恢複數據速度較慢。
  RDB:可能丟失一部分數據,文件體積小,恢複數據速度較快。

 

5、為什麼 Redis 是單線程?速度為什麼快?

(1)為什麼 Redis 是單線程的?
  Redis 基於記憶體進行操作,CPU 不是 Redis 的瓶頸,且單線程 比 多線程容易實現。

(2)速度為什麼快?
  基於記憶體操作,讀寫速度快。
  單線程操作,避免頻繁上下文切換。
  採用了非阻塞 I/O 多路復用機制,保證系統高吞吐量。
註:
  非阻塞 I/O 多路復用機制,用來保證多個連接時的系統吞吐量(此處不展開,有時間再總結)。
  多路 指的是 多個 socket 連接。
  復用 指的是 共用 同一個線程。
  簡單的講,就是使單線程高效的處理多個連接請求。


6、Redis 和 memcached 區別?

(1)Redis 可以將數據持久化到硬碟中,memcached 只能將數據存儲在記憶體中(斷電後消失)。

(2)Redis 支持多種數據類型,memcached 支持類型簡單。

 

三、緩存雪崩、緩存穿透、緩存與資料庫讀寫一致

1、緩存穿透是什麼?如何解決?

(1)緩存穿透是什麼?
  緩存穿透指查詢一個不存在的數據,且數據不在緩存中,則查詢會從資料庫查詢,而資料庫查不到數據,則不會將數據存儲在緩存中。以致於每次查詢都會繞過緩存,從資料庫查數據,使緩存失效。

(2)緩存穿透的可能原因?解決?
原因:
  請求的參數不合理。
  比如資料庫的 id 自增,且從 100 開始,但是每次請求都是 100 以下的 id 或者 負數的 id,則每次查詢,緩存中沒有值,直接去查資料庫,而資料庫查不到值,就不會將數據保存到緩存中,從而使緩存失效。

解決:
  方式一:對參數進行過濾處理(比如 BloomFilter),不合法的參數不會訪問到資料庫。
  方式二:當資料庫找不到數據時,返回一個空對象到緩存中,並設置一個過期時間,這樣就可以從緩存中獲取數據了。

2、緩存雪崩是什麼?如何解決?

(1)緩存雪崩是什麼?
  緩存雪崩指的是由於某種原因,導致緩衝層出現了問題,所有的請求(大量請求)直接訪問資料庫(可以理解為發生大量數據穿透),從而使資料庫宕機。

(2)緩存雪崩的可能原因?解決?
原因一:
  Redis 服務掛掉了,即緩存失效,所有請求不經過緩存直達資料庫,資料庫反應不過來而宕機。

如何解決:
  Step1:應該儘量避免 Redis 服務掛掉。
    為了實現 Redis 高可用,應該使用 主從模式 + 哨兵模式(或者採用 Redis 集群),儘量避免 Redis 服務掛掉。
  Step2:應該儘量避免 資料庫 掛掉。
    萬一 Redis 服務真的掛了,應當進行 熔斷、降低、限流等操作,儘量避免資料庫被幹掉,至少要保證服務還能正常運行。
  Step3:數據恢復。
    對 Redis 數據進行持久化,重啟 Redis 服務後,載入磁碟數據進行數據恢復。

原因二:
  Redis 對數據設置了過期時間,同一時間這些數據失效,此時恰巧有大量請求同時訪問這些數據,會穿過緩存直接訪問資料庫,造成大量緩存穿透,從而導致資料庫宕機。

如何解決:
  緩存的同時,將過期時間設置成隨機值,此時能極大避免大量數據 過期時間一致。

3、緩存、資料庫讀寫一致

(1)讀操作流程:
  Step1:查詢緩存中是否存在數據,存在數據則直接返回。
  Step2:緩存中不存在數據,則查詢資料庫中是否存在數據,存在數據,則將數據保存在緩存中,並返回數據。

(2)讀寫操作同時進行時可能出現數據不一致。
  造成讀寫不一致的情況有很多。
  比如一件商品,開始時 資料庫、緩存里顯示的庫存數量均為 1000。此時讀操作並沒有問題。現在賣出一件商品,需要更新資料庫,假如更新資料庫數據成功,但是更新緩存數據失敗 ,即此時資料庫顯示庫存數量為 999,而緩存顯示數量為 1000,則下次操作,獲取到的商品數量仍為 1000,此時就造成了讀寫不一致。

(3)如何解決讀寫不一致?
  方式一:一般給緩存的數據設置過期時間,數據過期則被刪除,下次會從資料庫查詢並更新緩存。
  方式二:保證資料庫、緩存更新的原子性(分散式事務)。要麼同時成功、要麼同時失敗。

(4)更新緩存、資料庫的兩種方式:
  方式一:先更新緩存,再更新資料庫。
  方式二:先更新資料庫,再更新緩存。
註:
  對於更新緩存,一般直接刪除某個數據,簡單粗暴。下次讀取時從資料庫讀取並保存到緩存中。

對於方式一(單線程情況):
  若刪除緩存失敗,可以直接拋出異常,此時資料庫與緩存數據均無變化,即數據一致。
  若刪除緩存成功,但是更新資料庫失敗,此時緩存中沒有該數據,下次讀取時,從資料庫中讀取並保存到緩存中,從而數據一致。
  若刪除緩存、更新資料庫均成功,下次讀取數據肯定一致。

對於方式一(高併發情況):
  線程 A 進行更新操作,線程 B 進行讀操作。
  線程 A 刪除緩存,此時線程 B 進行讀取,發現緩存不存在,則直接從資料庫中讀取,並將該值存入緩存。
  線程 A 對資料庫數據進行更新,此時緩存中的值 與 資料庫的值不一致了。
如何解決上述的數據不一致:
  將命令操作積壓到隊列中(先進先出),進行串列化,比如先刪除緩存,再更新資料庫,最後再進行讀取。

對於方式二(單線程情況):
  若更新資料庫失敗,則直接拋出異常,此時資料庫與緩存數據均無變化,即數據一致。
  若更新資料庫成功,但刪除緩存失敗,則資料庫的數據為新數據,與緩存數據不一致了。
  若更新資料庫、刪除緩存均成功,則下次讀寫的數據肯定一致。
如何解決上述的數據不一致:
  不斷重覆刪除 key,直至可以刪除。

對於方式二(高併發情況):
  線程 A 進行查詢操作,線程 B 進行更新操作。
  線程 A 查詢時,恰好緩存失效,直接通過資料庫進行查詢,此時 線程 B 更新資料庫數據,併進行緩存刪除,然後 線程 A 將從資料庫獲取的數據寫入緩存中,此時緩存數據與資料庫數據不一致了。
上例情況發生概率很低,畢竟寫操作的速度慢於讀操作,且讀操作要先於寫操作進入資料庫,且慢於寫操作操作緩存,同時滿足這個情況的概率只能說是走了狗屎運。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本教程主要介紹如何在Ubuntu 18.04系統上實現Spire.Cloud私有化部署。CentOS 7系統部署請參考 這篇教程。 詳細步驟如下: 一、環境配置 1、關閉防火牆 1)首先查看防火牆狀態 ufw status verbose (非管理員需在最前面加sudo) 預設情況下,防火牆狀態是i ...
  • 基本GCC命令的使用 GCC是一套由GNU項目開發的編程語言編譯器,可處理C語言、 C++、Fortran、Pascal、Objective C、Java等等。GCC通常是 跨平臺軟體的編譯器首選。gcc是GCC套件中的編譯驅動程式名。 若電腦是x86 64位系統,為了編譯成IA 32指令集, 則 ...
  • 目錄和文件都能操作的命令 rm cp mv rm 英文原意:remove files or directories 功能:刪除文件或目錄 語法:rm 選項[ fir] 文件或目錄 cp 英文原意:copy files and directories 功能:複製文件和目錄 語法:cp 選項[ adil ...
  • 本文主要給大家羅列了HBase協處理器載入的三種方式:Shell載入(動態)、Api載入(動態)、配置文件載入(靜態)。其中靜態載入方式需要重啟HBase。 我們假設我們已經有一個現成的需要載入的協處理器Jar包: HelloCoprocessor 0.0.1.jar 。 協處理器載入的三種方式 S ...
  • 一個問題 有一張表test,這張表除了主鍵id外,還有a,b, c 三列 假設給這三個欄位建一個複合索引 index_abc (a, b, c),問,下麵幾種查詢中,哪種查詢會用到索引 index_abc ? 1. 查詢一 select * from test where a > 1000 and ...
  • 前言:當項目上線並穩定運行後,我們就需要考慮自動備份功能了,自動備份固然簡單,但是需要相應的自動刪除來配合使用。 首先我們打開SqlServer管理工具(SSMS),在左側目錄中找到 管理-->右鍵維護計劃-->新建維護計劃 雙擊左側下方目錄:創建 ”清除維護“ 任務 雙擊後打開提示視窗,我們設置 ...
  • 文章目錄 前言 Druid介紹 主要特性 基礎概念 數據格式 數據攝入 數據存儲 數據查詢 查詢類型 架構 運維 OLAP方案對比 使用場景 使用建議 參考 近期主題 前言 項目早期、數據(報表分析)的生產、存儲和獲取業務,MySQL基本上可以滿足需要,但是隨著業務的快速增長,數據量翻至億為單位時, ...
  • 前言: 工欲善其事必先利其器,今天給大家介紹一下HBase Shell十大花式利器,在日常運維工作中,可以試著用起來。 1. 交互模式 也就是我們最常用到的Shell命令行的方式。 2. 非交互模式 與交互模式比較 如果我們想要知道HBase Shell命令執行之後是否成功,那一定要使用非交互模式。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...