【Redis】List類型

文章目錄

  • List的特點介紹
  • lpush,lpushx,rpush,rpushx命令
  • lrange命令
  • lpop和rpop
  • lindex命令
  • linsert命令
  • llen命令
  • lrem 命令
  • ltrim命令
  • lset命令
  • 阻塞版本的命令
    • blpop和brpop
  • 命令小結
  • list的內部編碼
  • List的應用場景


List的特點介紹

列表相當于一個數組或者順序表,但是不是一個簡單的數組,而是接近雙端隊列(deque)的結構。
對于雙端隊列來說,頭插頭刪和尾插尾刪的效率都很高,時間復雜度是O(1).
對于普通的數組來說,只有尾插尾刪的效率高一點,但是頭插和頭刪會涉及到內存的大量操作,效率不高。
在這里插入圖片描述
列表類型的特點:

    1. 列表中的元素是有序的,這意味著可以通過索引下標獲取某個元素或者某個范圍的元素列表,例如要獲取上圖第 5 個元素,可以執? lindex user:1:messages 4 或者倒數第 1 個元素,lindex
      user:1:messages -1 就可以得到元素 e。

這里的有序兩個字,要根據上下文區分。
很明顯,列表的有序指的是元素按照一定的順序排列的。
但是實際中的有序,可能是升序和降序,也有可能是按照某個條件進行的有序。
舉個例子:假如面試官問你堆棧的區別,你這時候就先不要著急回答。
而是先反問面試官,您這里說的堆棧,是數據結構的堆棧呢,還是操作系統的堆棧呢,還是JVM中的堆棧呢?亦或者是進程地址空間的堆棧呢?
還有一個同步,同步是指通過加鎖來保證線程安全的同步呢,還是IO中的同步和異步(這里的異步其實就是并發)中的同步呢?

    1. 區分獲取和刪除的區別,例如 lrem 1 b 是從列表中把從左數遇到的前 1 個 b 元素刪除,這個操作會導致列表的?度從 5 變成 4;但是執? lindex 4 只會獲取元素,但列表?度是不會變化的。
    1. 列表中的元素是允許重復的。

deque的底層結構介紹如下:
在這里插入圖片描述

注意區分lindex和lrem,即獲取元素和刪除元素的區別。

lindex 能獲取到元素的值,lrem也能返回被刪除的元素的值。
因為當前的list的頭和尾都能高效地插入和刪除元素,所以當前的List可以用來作棧和隊列使用。
后端開發中,棧用的比較少,但是隊列就非常重要。比如使用隊列實現生產消費者模型。
還有實現消息隊列。

lpush,lpushx,rpush,rpushx命令

將一個或多個元素頭插到list中

lpush key element [element …]
比如:lpush key 1 2 3 4 ,插入完成后,列表的元素是4 3 2 1
返回值:插入后的list的長度。

如果key已經存在,且key對應的value不是list類型,則lpush命令會報錯。
Redis中所有類型的容器都是類似效果。
時間復雜度O(1).

lpushx命令:
在 key 存在時,將?個或者多個元素從左側放?(頭插)到 list 中。不存在,直接返回

lpushx key element [element … ]

時間復雜度O(1)

rpush和rpushx,其實就是尾插入,其他的完全相同。

操作的時間復雜度也是O(1)

lrange命令

獲取key對應的[start stop]區間的元素,左閉右閉。

lrange key start stop

時間復雜度O(n)
在這里插入圖片描述
如果給出的下標超出范圍了,在Redis中的做法是:
直接盡可能給到區間內的元素,如果下標非法,就盡可能獲取對應的內容。

這就是所謂的 ”魯棒性“:你對我越粗魯,我表現的越棒。(其實就是容錯性強了)

然而在C++中,下標超出范圍,這是一個未定義行為:
1.可能導致程序崩潰
2.可能得到不合法的數據
3.可能得到看起來合法,但是是錯誤的數據。
4.可能得到一個恰好符合結果的數據
就像是開盲盒一樣。

缺點:程序員不能第一時間發現問題,可能會出現連鎖反應。
優點:效率是最高的。相比其他編程語言,比如java,對下標超范圍行為會多了一個合法性驗證,然后拋異常,這就導致多了一些動作。

但是人家java這樣做也有優點,就是對程序員來說能更快發現問題,也就能更高效開發代碼。
所以就產生了兩個問題:
是機器跑得快重要呢,還是程序員開發代碼更快重要呢?
肯定是程序員開發代碼重要,因為涉及到了利益問題,程序員如果開發的慢了,可能要加班修bug開發代碼,甚至如果搞砸了,可能要丟失年終獎。但是對程序員來說,機器跑的快不快跟我有啥關系呢,跑的慢的話,讓老板多搞兩臺機器過來不就行了嘛。

lpop和rpop

lpop相當于頭刪

lpop key
返回值:返回刪除后的元素,如果列表沒有元素了,則返回nil
時間復雜度O(1)

rpop相當于尾刪

rpop key
返回值:返回刪除后的元素,如果列表沒有元素了,則返回nil
時間復雜度O(1)

從Redis 6.2版本中,新增了一個count選項(當前我用的是Redis 5,暫不考慮)

lpop key [count]
表明要頭刪幾次

lindex命令

給定下標,獲取到指定下標的元素

lindex key index
支持負數下標,-1表示倒數第一個了。依次類推。
如果下標非法,返回nil
時間復雜度O(n),因為在redis的list列表不是一個簡單的數組,所以不能理解成O(1)的復雜度。

linsert命令

在指定位置插入元素

linsert key <before | after> pivot element
在指定的元素pivot之前/之后,插入元素element
如果指定的元素pivot在列表中存在多個,則在從左往右搜索到的第一個pivot之前/之后插入。

llen命令

獲取key對應的list的長度

llen key

lrem 命令

rem就是remove命令的縮寫,就是刪除命令。

lrem key count element
count是要刪除的個數,element是刪除的值

官方文檔給定的解釋如下
在這里插入圖片描述
意思是:
如果count > 0,則是從頭到尾開始刪除等于element的元素,刪count個。
如果count < 0, 則是從尾到頭開始刪除等于element的元素,刪count個。
如果count = 0, 則是刪除所有等于element的元素。

lrem返回值是被刪除的元素個數。

ltrim命令

該命令是保留key對應的list的[start stop]區間內的元素(同樣是左閉右閉),區間外的元素都刪除。

ltrim key start stop

時間復雜度O(1),也可以理解為O(N),這個N是要刪除的元素個數。

lset命令

把key對應的list列表中的index下標的元素修改成element

lset key index element
時間復雜度O(N),如果是修改頭或者尾,則時間復雜度是O(1)

如果給的下標非法,則直接報錯。
相比于lindex命令不同的是,lindex命令對于非法的下標不報錯,而是盡可能滿足。。。

阻塞版本的命令

blpop和brpop

blpop key [key …] timeout
意思是可以同時對多個key的list進行頭刪
返回值是成功執行blpop命令的key和其刪除的元素
brpop key [key …] timeout
同理
這個timeout(必選項,單位是秒)是設置阻塞的時間,下面會詳細介紹

在list中存在元素的情況下,blpop和brpop命令和lpop,rpop命令作用完全相同。
但是如果list中沒有元素,則blpop和brpop會產生阻塞。
這里的阻塞很好理解,就是生產消費者模型中的阻塞。
在這里插入圖片描述
這里并不是無休止地阻塞,阻塞時間由timeout決定,在阻塞期間,Redis可以執行其他命令(這是經過特殊處理的,畢竟怎么可能讓兩個命令阻塞住Redis處理命令時的單線程模型呢,如果阻塞住了, 其他客戶端發來的命令請求就得不到執行了。

注意事項:

  • 1.如果命令設置了多個key,那么會從左到右遍歷這些key,一旦有其中一個key對應的list的元素就緒了,就會馬上頭刪該key對應的list,然后立即返回。
  • 2.如果多個客戶端同時對一個key進行blpop/brpop,則最先執行命令的客戶端會得到刪除后的元素
    在這里插入圖片描述
    所以返回值是一個二元組,一方面是告訴我這個數據是來自哪個key,一方面是告訴我這個數據是什么。

在這里插入圖片描述
這種情況就是key不存在,所以阻塞住了,一旦key就緒了,就立即刪除返回。
這個15.17s就是阻塞的時長。

命令小結

在這里插入圖片描述

list的內部編碼

其實前面的文章講過了。在這里插入圖片描述

在這里插入圖片描述

List的應用場景

Redis 阻塞消息隊列模型
在這里插入圖片描述

分頻道阻塞消息隊列模型

在這里插入圖片描述
在這里插入圖片描述

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

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

相關文章

QT:qt5調用打開exe程序并獲取調用按鈕控件實例2025.5.7

為實現在 VS2015 的 Qt 開發環境下打開外部 exe&#xff0c;列出其界面按鈕控件的序號與文本名&#xff0c;然后點擊包含特定文本的按鈕控件。以下是更新后的代碼&#xff1a; #include <QCoreApplication> #include <QProcess> #include <QDebug> #include…

基于Jenkins的DevOps工程實踐之Jenkins共享庫

文章目錄 前言Jenkins共享庫結構1、共享庫演示2、知識點補充3、實踐使用共享庫格式化輸出日志4、groovy基礎語法4.1、 什么是 Groovy&#xff1f;4.2、groovy特點4.3、運行方法4.4、標識符4.5、基本數據類型4.5.1、string類型4.5.2、list類型 4.6、函數使用4.7、正則表達式 5、…

【Qt4】Qt4中實現PDF預覽

方案一&#xff1a; 在Qt4中預覽PDF文件&#xff0c;你可以使用多種方法&#xff0c;但最常見和簡單的方法之一是使用第三方庫。Qt本身并沒有內置直接支持PDF預覽的功能&#xff0c;但你可以通過集成如Poppler、MuPDF等庫來實現這一功能。下面我將展示如何使用Poppler庫在Qt4中…

php artisan resetPass 執行密碼重置失敗的原因?php artisan resetPass是什么 如何使用?-優雅草卓伊凡

php artisan resetPass 執行密碼重置失敗的原因&#xff1f;php artisan resetPass是什么 如何使用&#xff1f;-優雅草卓伊凡 可能的原因 命令不存在&#xff1a;如果你沒有正確定義這個命令&#xff0c;Laravel 會報錯而不是提示”重置密碼失敗”用戶不存在&#xff1a;’a…

ai說什么是注解,并以angular ts為例

在編程中&#xff0c;注解&#xff08;Annotation&#xff09; 是一種特殊的語法結構&#xff0c;用于為代碼添加元數據&#xff08;metadata&#xff09;&#xff0c;從而在不修改代碼邏輯的情況下&#xff0c;提供額外的信息或指示編譯器、框架、工具如何處理這些代碼。注解通…

【MySQL】-- 聯合查詢

文章目錄 1. 簡介1.1 為什么要使用聯合查詢1.2 多表聯合查詢時MySQL內部是如何進行計算的 2. 內連接2.1 語法2.2 示例 3. 外連接3.1 語法3.2 示例 4. 自連接4.1 應用場景4.2 示例4.3 表連接練習 5. 子查詢5.1 語法5.2 單行子查詢5.3 多行子查詢5.4 多列子查詢5.5 在from 子句中…

【多線程】六、基于阻塞隊列的生產者消費者模型

文章目錄 Ⅰ. 生產者消費者模型的概念Ⅱ. 生產者消費者模型的優點Ⅲ. 基于阻塞隊列的生產者消費者模型MakefileBlock_queue.hpptask.hpptest.cpp Ⅳ. 如何理解提高了效率??? Ⅰ. 生產者消費者模型的概念 ? 生產者消費者模型是一種常見的并發模式&#xff0c;用于解決生產者…

【Vue】全局事件總線 TodoList 事件總線

目錄 一、 實現所有組件看到x事件 二、 實現$on $off 以及 $emit 總結不易~ 本章節對我有很大的收獲&#xff0c; 希望對你也是&#xff01;&#xff01;&#xff01; 本節素材已上傳至Gitee&#xff1a;yihaohhh/我愛Vue - Gitee.com 全局事件總線圖&#xff1a; 本節素材…

Python編程virtualenv庫的簡介和使用方法

Python編程virtualenv庫的簡介和使用方法 virtualenv和conda的區別是什么

MySQL的行級鎖鎖的到底是什么?

大家好&#xff0c;我是鋒哥。今天分享關于【MySQL的行級鎖鎖的到底是什么?】面試題。希望對大家有幫助&#xff1b; MySQL的行級鎖鎖的到底是什么? 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 MySQL的行級鎖是數據庫管理系統&#xff08;DBMS&#xff09;的一…

【C++游戲引擎開發】第33篇:物理引擎(Bullet)—射線檢測

一、射線檢測核心理論體系 1.1 射線檢測的數學基礎 1.1.1 參數化射線方程 射線在三維空間中的數學表達采用參數方程: r ( t ) = o + t d ^ ( t ∈ [

【操作系統】線程崩潰機制詳解

在分布式系統與多線程編程的世界里&#xff0c;一個看似簡單的問題卻暗藏玄機&#xff1a;當某條線程突然崩潰&#xff0c;其所屬進程會隨之消亡嗎&#xff1f;這個問題背后隱藏著操作系統與編程語言的精妙設計&#xff0c;本文將從底層原理到工程實踐層層剖析。 一、線程崩潰…

無人機 | 無人機設計概述

無人機設計是一個復雜的系統工程&#xff0c;涉及空氣動力學、電子技術、材料科學、控制算法等多個領域的綜合應用。以下是無人機設計的主要模塊和關鍵要素概述&#xff1a; 一、總體設計目標 任務需求定義 用途&#xff1a;航拍、物流、農業、軍事偵察、環境監測等性能指標&am…

強啊!Oracle Database 23aiOracle Database 23ai:使用列別名進行分組排序!

大家好&#xff0c;這里是架構資源棧&#xff01;點擊上方關注&#xff0c;添加“星標”&#xff0c;一起學習大廠前沿架構&#xff01; 從 Oracle Database 23ai 開始&#xff0c;您可以在 GROUP BY 和 HAVING 子句中直接使用列別名。此功能在早期版本的 Oracle Database 中不…

Modbus 轉 IEC61850 網關

第一章 產品概述 Modbus 轉 IEC61850 網關型號 SG-IEC61850-Modbus &#xff0c;是三格電子推出的工業級網關&#xff08;以 下簡稱盒子或網關&#xff09;&#xff0c;主要用于 Modbus RTU/TCP 數據采集、 DLT645-1997/2007 數據采集&#xff0c; 可接多功能電力儀表…

MySQL 中的 MVCC 是什么?

MySQL 中的 MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并發控制&#xff09; 是一種用于實現高并發讀寫操作的機制&#xff0c;它通過維護數據的多個版本來解決讀寫沖突&#xff0c;從而在保證事務隔離性的同時&#xff0c;減少鎖的使用&#xff0c…

【Python】讓Selenium 像Beautifulsoup一樣,用解析HTML 結構的方式提取元素!

我在使用selenium的find_element的方式去獲取網頁元素&#xff0c;一般通過xpath、css_selector、class_name的方式去獲取元素的絕對位置。 但是有時候如果網頁多了一些彈窗或者啥之類的&#xff0c;絕對位置會發生變化&#xff0c;使用xpath等方法&#xff0c;需要經常變動。…

使用xlwings將excel表中將無規律的文本型數字批量轉化成真正的數字

之前我寫了一篇文章excel表中將無規律的文本型數字批量轉化成真正的數字-CSDN博客 是使用excel自帶的操作&#xff0c;相對繁瑣。 今天使用xlwings操作&#xff0c;表格如下&#xff08;有真正的數字&#xff0c;也有文本型數字&#xff0c;混在在一起&#xff09;&#xff1…

ICML 2025錄取率公布,spotlight posters僅占2.6%

近日&#xff0c;ICML 2025公布了論文錄用結果。本次大會共收到 12,107篇有效論文投稿&#xff0c;比去年增加了28%&#xff0c;今年錄取論文3,260篇&#xff0c;錄取率為 26.9%。其中僅有313篇被列為“焦點海報”&#xff08;即所有投稿中排名前2.6%的論文&#xff09;&#x…

全局網絡:重構數字時代的連接范式

從局部到全局 —— 網絡架構的范式革命 在全球化與數字化深度融合的今天&#xff0c;傳統網絡架構的 “碎片化” 問題日益凸顯&#xff1a;跨地域數據流通低效、設備互聯孤島化、安全策略難以統一。 全局網絡作為一種突破地域與技術邊界的新型網絡架構&#xff0c;正成為企業…