Java常用組件之Redis經典面試題(一)

大家好,今天為大家帶來Java項目中,幾乎必不可少的組件之一-Redis的一些常見面試題,幫忙近期需要面試的朋友們來一個理論基礎突擊!

一、數據類型

1.Redis的常用數據類型有哪些 ?

難易程度:☆☆☆

出現頻率:☆☆☆☆☆

Redis是典型的“鍵值型”數據庫,不同數據類型其key結構一致,value有所差異。常見的類型有:string、hash、list、set、SortedSet等。

而基于以上5種基本數據類型,Redis又拓展了幾種拓展類型,例如:BitMap、

HyperLogLog、Geo等。

String類型是Redis中最常見的數據類型,value與key一樣都是Redis自定義的字符串結構,稱為SDS。不過在保存數字、小字符串時因為采用INT和 EMBSTR編碼,內存結構緊湊,只需要申請一次內存分配,效率更高,更節省內存。

而超過44字節的大字符串時則需要采用RAW編碼,申請額外的SDS空間,需要兩次內存分配,效率較低,內存占用也較高,但最大不超過512mb,因此建議單個value盡量不要超過44字節。

String類型常用來做計數器、簡單數據存儲等。復雜數據建議采用其他數據結構。

Hash結構,其value與Java中的HashMap類似,是一個key-value結構。如果有一個對象需要被Redis緩存,而且將來可能有部分修改。建議用hash結構來存儲這個對象的每一個字段和字段值。而不是作為一個JSON字符串存儲到

String類型中。因為Hash結構的每一個字段都可以單獨做修改,而String的 JSON串必須整體覆蓋。

?

與Java中的hashMap不同的是,Redis中的Hash底層采用了漸進式rehash的算法,在做rehash時會創建一個新的hashtable,每次操作元素時移動一部分數據,直到所有數據遷移完成,再用新的HashTable來代替舊的,避免了因為 rehash導致的阻塞,因此性能更高。

List結構的value類型可以看作是一個雙端鏈表,提供了一些命令便于我們從首尾操作元素。為了節省內存空間,底層采用了ZipList(壓縮列表)來做基礎存儲。當壓縮列表數據達到閾值(512)則會創建新的壓縮列表。每個壓縮列表作為一個雙端鏈表的一個節點,最終形成一個QuickList結構。而且QuickList結構與一般的雙端鏈表不同,他可以對中間不常用的ZipList節點做壓縮以節省內存。

List結構常用來模擬隊列,實現任務排隊這樣的功能。

Set結構的value與Java的Set類似,元素不可重復。Redis提供了求交集、并集等命令,可以幫助我們實現例如:好友列表、共同好友等功能。

當存儲元素是整數時,其底層默認采用IntSet結構,可以看作是一個有序的數組,結構緊湊,效率較高。而元素如果不是整數,或者元素量超過512這個閾值時則會轉為hash表結構,內存占用會有大的增加。因此我們在使用Set結構時盡量采用數組存儲,例如數值類型的id。而且元素數量盡量不要超過512,避免出現BigKey。

SortedSet,也叫ZSet。其value就是一個有序的Set集合,元素唯一,并且會按照一個指定的score值排序。因此常用來做排行榜功能。

SortedSet底層的利用Hash表保證元素的唯一性。利用跳表(SkipList)來保證元素的有序性,因此數據會有重復存儲,內存占用較高,是一種典型的以空間換時間的設計。不建議在SortedSet中放入過多數據。

2.跳表你了解嗎?

難易程度:☆☆☆☆

出現頻率:☆☆

跳表(SkipList)首先是鏈表,但與傳統的鏈表相比有幾點差異:

  1. ·跳表結合了鏈表和二分查找的思想元素按照升序排列存儲
  2. ·節點可能包含多個指針,指針跨度不同
  3. ·查找時從頂層向下,不斷縮小搜索范圍
  4. ·整個查詢的復雜度為 O ( log?n )
?

Redis數據類型Sorted?Set使用了跳表作為其中一種數據結構

二、持久化

Redis的數據持久化策略有哪些 ?

難易程度:☆☆☆

出現頻率:☆☆☆☆

在Redis中提供了兩種數據持久化的方式:1、RDB?2、AOF

RDB

定期更新,定期將Redis中的數據生成的快照同步到磁盤等介質上,磁盤上保存的就是Redis的內存快照

優點:數據文件的大小相比于aop較小,使用rdb進行數據恢復速度較快缺點:比較耗時,存在丟失數據的風險

AOF

將Redis所執行過的所有指令都記錄下來,在下次Redis重啟時,只需要執行指令就可以了

?

優點:數據丟失的風險大大降低了

缺點:數據文件的大小相比于rdb較大,使用aop文件進行數據恢復的時候速度較慢

你們的項目中的持久化是如何配置選擇的?

RDB+AOF

三、主從和集群

3.1?Redis集群有哪些方案,?知道嗎??

難易程度:☆☆☆

出現頻率:☆☆☆

在Redis中提供的集群方案總共有三種:

1、主從復制

保證高可用性

實現故障轉移需要手動

實現無法實現海量數據存儲

2、哨兵模式

?保證高可用性

?可以實現自動化的故障轉移

?無法實現海量數據存儲

3、Redis分片集群

保證高可用性

可以實現自動化的故障轉移

可以實現海量數據存儲

3.2什么是 Redis?主從同步?

難易程度:☆☆☆☆

出現頻率:☆☆☆☆

主從第一次同步是全量同步

第一階段,全量同步流程

  1. 從節點執行replicaof命令,發送自己的replid和offset給主節點
  2. 主節點判斷從節點的replid與自己的是否一致,
  3. 如果不一致說明是第一次來,需要做全量同步,主節點返回自己的replid給從節點
  4. 主節點開始執行bgsave,生成rdb文件
  5. 主節點發送rdb文件給從節點,再發送的過程中
  6. 從節點接收rdb文件,清空本地數據,加載rdb文件中的數據
  7. 同步過程中,主節點接收到的新命令寫入從節點的寫緩沖區(repl_buffer)
  8. 從節點接收到緩沖區數據后寫入本地,并記錄最新數據對應的offset
  9. 后期采用增量同步

后期數據變化后,則執行增量同步

?
  1. 主節點會不斷把自己接收到的命令記錄在repl_baklog中,并修改offset
  2. 從節點向主節點發送psync命令,發送自己的offset和replid
  3. 主節點判斷replid和offset與從節點是否一致
  4. 如果replid一致,說明是增量同步。然后判斷offset是否一致
  5. 如果從節點offset小于主節點offset,并且在repl_baklog中能找到對應數據則將offset之間相差的數據發送給從節點
  6. 從節點接收到數據后寫入本地,修改自己的offset與主節點一致

增量同步的風險

repl_baklog大小有上限,寫滿后會覆蓋最早的數據。如果slave斷開時間過?久,導致尚未備份的數據被覆蓋,則無法基于log做增量同步,只能再次全量同步。

repl_baklog可以在配置文件中進行修改存儲大小

3.3你們使用Redis是單點還是集群 ??哪種集群 ?(說說你們生產環境redis部署情況?)

難易程度:☆☆☆

出現頻率:☆☆☆

一般部分服務做緩存用的Redis直接做主從(1主1從)加哨兵就可以了。單節點不超過10G內存,如果Redis內存不足則可以給不同服務分配獨立的Redis主從節點。盡量不做分片集群。

原因:

維護起來比較麻煩

集群之間的心跳檢測和數據通信會消耗大量的網絡帶寬

集群插槽分配不均和key的分批容易導致數據傾斜

客戶端的route會有性能損耗

集群模式下無法使用lua腳本、事務

?

3.4Redis分片集群中數據是怎么存儲和讀取的 ?

難易程度:☆☆☆

出現頻率:☆☆☆

Redis?集群引入了哈希槽的概念,Redis?集群有 16384?個哈希槽,每個 key通過 CRC16 校驗后對 16384 取模來決定放置哪個槽,集群的每個節點負責一部分 hash 槽。


上圖是存值的流程,取值的流程類似

set {aaa}name zhangsan?計算hash是根據aaa計算的

3.5redis集群腦裂?

難易程度:☆☆☆☆

出現頻率:☆☆☆

關于reids集群會由于網絡等原因出現腦裂的情況,所謂的集群腦裂就是,由于 redis master節點和redis salve節點和sentinel處于不同的網絡分區,使得sentinel沒有能夠心跳感知到master,所以通過選舉的方式提升了一個salve為master,這樣就存在了兩個master,就像大腦分裂了一樣,這樣會導致客戶端還在old

master那里寫入數據,新節點無法同步數據,當網絡恢復后,sentinel會將old master降為salve,這時再從新master同步數據,這會導致大量數據丟失。

正常情況:

腦裂情況:

?

當哨兵與主節點由于網絡抖動原因斷開了連接,哨兵監控到之后,則會從剩余的從節點中選出一個作為主節點

redis的客戶端這個時候并沒有是可以正常連接之前的maser(主節點),并且可以正常寫入數據

假如現在網絡恢復了,哨兵發現主從中有兩個主節點,則會強制一個主節點變為從節點,看下圖

由于原來的主節點變成了從節點,則需要執行主從同步流程,清理數據(之前的主節點),同步新主節點中的數據,在之前腦裂過程中,客戶端寫入的數據丟失

解決方案:

redis中有兩個配置參數:

?min-replicas-to-write 1?表示最少的salve節點為1個

?min-replicas-max-lag 5?表示數據復制和同步的延遲不能超過5秒

配置了這兩個參數:如果發生腦裂:原master會在客戶端寫入操作的時候拒絕請求。這樣可以避免大量數據丟失。

3.6怎么保證redis的高并發高可用

難易程度:☆☆☆

出現頻率:☆☆☆

主從+哨兵

集群

四、使用場景

4.1項目中哪塊使用了緩存?

難易程度:☆☆☆

出現頻率:☆☆☆☆☆

結合自己簡歷上寫的項目模塊說明這個問題,要陳述出當時的場景

?數據字典

?用戶Token

?熱點數據

4.2什么是緩存穿透 ??怎么解決 ?

難易程度:☆☆☆☆

出現頻率:☆☆☆☆☆

加入緩存以后的數據查詢流程:

?

緩存穿透:

概述:指查詢一個一定不存在的數據,如果從存儲層查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到 DB 去查詢,可能導致 DB 掛掉。

解決方案:

1、查詢返回的數據為空,仍把這個空結果進行緩存,但過期時間會比較短

2、布隆過濾器:將所有可能存在的數據哈希到一個足夠大的 bitmap?中,一個一定不存在的數據會被這個 bitmap 攔截掉,從而避免了對DB的查詢

4.3什么是緩存擊穿 ??怎么解決 ?

難易程度:☆☆☆☆

出現頻率:☆☆☆☆☆

概述:對于設置了過期時間的key,緩存在某個時間點過期的時候,恰好這時間點對這個Key有大量的并發請求過來,這些請求發現緩存過期一般都會從后端 DB加載數據并回設到緩存,這個時候大并發的請求可能會瞬間把 DB 壓垮。

解決方案:

1、使用互斥鎖:當緩存失效時,不立即去load?db,先使用如 Redis?的 setnx?去設置一個互斥鎖,當操作成功返回時再進行 load db的操作并回設緩存,否則重試get緩存的方法

2、可以設置當前key邏輯過期,大概思路如下:

①:在設置key的時候,設置一個過期時間字段一塊存入緩存中,不給當前key

設置過期時間

②:當查詢的時候,從redis取出數據后判斷時間是否過期

③:如果過期則開通另外一個線程進行數據同步,當前線程正常返回數據,這個數據不是最新

?

兩種方案對比:

解決方案

優點

缺點

互斥鎖

沒有額外的內存消耗保證一致性

實現簡單

線程需要等待,性能受影響可能有死鎖風險

邏輯過期

線程無需等待,性能較好

不保證一致性 有額外內存消耗實現復雜

4.4什么是緩存雪崩 ??怎么解決 ?

難易程度:☆☆☆☆

出現頻率:☆☆☆☆☆

概述:設置緩存時采用了相同的過期時間,導致緩存在某一時刻同時失效,請求全部轉發到DB,DB 瞬時壓力過重雪崩。與緩存擊穿的區別:雪崩是很多key,擊穿是某一個key緩存。

解決方案:

?

將緩存失效時間分散開,比如可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。

4.5什么是布隆過濾器?

難易程度:☆☆☆☆

出現頻率:☆☆☆☆☆

概述:布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實際上由一個很長的二進制向量(二進制數組)和一系列隨機映射函數(hash函數)。

作用:布隆過濾器可以用于檢索一個元素是否在一個集合中。添加元素:將商品的id(id1)存儲到布隆過濾器

假設當前的布隆過濾器中提供了三個hash函數,此時就使用三個hash函數對id1進行哈希運算,運算結果分別為:1、4、9那么就會數組中對應的位置數據更改為1

判斷數據是否存在:使用相同的hash函數對數據進行哈希運算,得到哈希值。然后判斷該哈希值所對應的數組位置是否都為1,如果不都是則說明該數據肯定不存在。如果是說明該數據可能存在,因為哈希運算可能就會存在重復的情況。如下圖所示:

?

假設添加完id1和id2數據以后,布隆過濾器中數據的存儲方式如上圖所示,那么此時要判斷id3對應的數據在布隆過濾器中是否存在,按照上述的判斷規則應該是存在,但是id3這個數據在布隆過濾器中壓根就不存在,這種情況就屬于誤?判。

誤判率:數組越小誤判率就越大,數組越大誤判率就越小,但是同時帶來了更多的內存消耗。

刪除元素:布隆過濾器不支持數據的刪除操作,因為如果支持刪除那么此時就會影響判斷不存在的結果。

使用布隆過濾器:在redis的框架redisson中提供了布隆過濾器的實現,使用方式如下所示:

pom.xml文件


<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.6</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

?

測試代碼:

import org.redisson.Redisson;
import org.redisson.api.RBloomFilter; import org.redisson.api.RedissonClient; import org.redisson.config.Config;public class Application {public static void main(String[] args) {
//鏈接redis,
Config config = new Config();config.useSingleServer().setAddress("redis://192.168.200.130:6379")
.setPassword("leadnews");
//創建redisson客戶端
RedissonClient redissonClient = Redisson.create(config);
//創建布隆過濾器 RBloomFilter<String> bloomFilter =
redissonClient.getBloomFilter("bloom-filter"); int size = 10000;
//初始化數據
//	initData(bloomFilter, size);
//測試誤判率
int count = getData(bloomFilter, size); System.out.println("總的誤判條數為:" + count);}/**
*測試誤判率
*@param bloomFilter
*@param size
*@return
*/
private static int getData(RBloomFilter<String> bloomFilter, int size) {
int count = 0 ;	// 記錄誤判的數據條數
for(int x = size; x < size * 2 ; x++) { if(bloomFilter.contains("add" + x)) {
count++ ;
}
}
return count;
}/**
*初始化數據
*@param bloomFilter
*@param size
*/
private static void initData(RBloomFilter<String> bloomFilter, int size) {
//第一個參數:布隆過濾器存儲的元素個數
//第一個參數:誤判率
bloomFilter.tryInit(size,0.01);
//在布隆過濾器初始化數據
for(int x = 0; x < size; x++) { bloomFilter.add("add" + x) ;
}
System.out.println("初始化完成...");
}
}

Redis中使用布隆過濾器防止緩存穿透流程圖如下所示:

4.6redis雙寫問題?

難易程度:☆☆☆

出現頻率:☆☆☆☆☆

同步方案:

普通緩存,一般采用更新時刪除緩存,查詢時建立緩存的延遲更新方案。異步方案:

1、使用消息隊列進行緩存同步:更改代碼加入異步操作緩存的邏輯代碼(數據庫操作完畢以后,將要同步的數據發送到MQ中,MQ的消費者從MQ中獲取數據,然后更新緩存)

2、使用阿里巴巴旗下的canal組件實現數據同步:不需要更改業務代碼,部署一個canal服務。canal服務把自己偽裝成mysql的一個從節點,當mysql數據更新以后,canal會讀取binlog數據,然后再通過canal的客戶端獲取到數據,更新緩存即可。

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

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

相關文章

2025.5.4總結

今天去光谷步行街逛了一下&#xff0c;感覺熟悉又陌生&#xff0c;說熟悉是因為初二的時候來過武漢光谷&#xff0c;盡管過去了8年時間&#xff0c;但絲毫不影響標志性建筑的存在&#xff0c;也陌生是商場的建筑風格真實氣派&#xff0c;感覺進入了一座城堡&#xff0c;在里面都…

神經網絡在專家系統中的應用:從符號邏輯到連接主義的融合創新

自人工智能作為一個學科面世以來&#xff0c;關于它的研究途徑就存在兩種不同的觀點。一種觀點主張對人腦的結構及機理開展研究&#xff0c;并通過大規模集成簡單信息處理單元來模擬人腦對信息的處理&#xff0c;神經網絡是這一觀點的代表。關于這方面的研究一般被稱為連接機制…

Doo全自動手機殼定制系統

Doo全自動手機殼定制系統 項目概述 Doo全自動手機殼定制系統是一個完整的手機殼定制解決方案&#xff0c;支持多端應用&#xff0c;包括服務端、客戶端、管理后臺等多個組件。系統采用現代化的技術棧&#xff0c;提供完整的手機殼定制、訂單管理、用戶管理等功能。 目錄結構…

PageOffice在線打開word文件,并實現切換文件

本示例關鍵代碼的編寫位置&#xff0c;請參考“PageOffice 開發者中心-快速起步–開始 - 快速上手”里您所使用的開發語言框架的最簡集成代碼 注意 本文中展示的代碼均為關鍵代碼&#xff0c;復制粘貼到您的項目中&#xff0c;按照實際的情況&#xff0c;例如文檔路徑&#xff…

Webug4.0靶場通關筆記12- 第17關 文件上傳之前端攔截(3種方法)

目錄 一、文件上傳前端攔截原理 二、第17關 文件上傳(前端攔截) 1.打開靶場 2.構造php腳本 3.源碼分析 &#xff08;1&#xff09;js源碼 &#xff08;2&#xff09;服務器源碼 &#xff08;3&#xff09;總結 4.滲透實戰 &#xff08;1&#xff09;禁用js法 &#…

高性能 WEB 服務器 Nginx:多虛擬主機實現!

Nginx 配置多虛擬主機實現 多虛擬主機是指在一臺 Nginx 服務器上配置多個網站 在 Nginx 中&#xff0c;多虛擬主機有三種實現方式&#xff1a; 基于IP地址實現多虛擬主機 基于端口號實現多虛擬主機 基于域名實現多虛擬主機 1 基于域名實現多虛擬主機 在 Nginx 中配置多個…

網星安全AWS攻防方案,重磅發布!

AWS介紹 AWS&#xff08;Amazon Web Services&#xff09; 是 Amazon 提供的云計算平臺&#xff0c;提供了廣泛的云服務&#xff0c;包括計算、存儲、數據庫、網絡、安全、人工智能、大數據處理等功能&#xff0c;幫助企業和開發者構建、部署和管理應用程序。AWS 是全球最大的…

qt的containers里的QToolBox和QTabWidget

Tool Box是一個多層次的折疊面板&#xff0c;通常用于組織多個可展開/折疊的面板組&#xff0c;每個面板有一個標題欄&#xff0c;用戶點擊標題欄可以展開或收起內容區域。比如設置界面中的分類選項&#xff0c;每個分類可以展開查看詳細內容。這樣能節省空間&#xff0c;讓界面…

【神經網絡與深度學習】深度學習中的生成模型簡介

深度學習中的生成模型 openai 的一個古早介紹 引言 深度學習中的生成模型能夠學習數據分布并生成新數據&#xff0c;在人工智能的多個領域中都有重要應用。不同類型的生成模型在原理和結構上各有特點&#xff0c;適用于不同的任務&#xff0c;如圖像生成、文本生成和時間序列…

js獲取明天日期、Vue3大菠蘿 Pinia的使用

直接上代碼 const today new Date(2019, 2, 28) const finalDate new Date(today) finalDate.setDate(today.getDate() 3)console.log(finalDate) // 31 March 2019 安裝 yarn add pinia # or with npm npm install pinia創建第一個store倉庫 1、在src目錄下創建store目錄…

存儲過程補充——定義條件、處理程序及游標使用

文章目錄 1. 定義條件與處理程序1.1 定義條件1.2 處理程序1.3 案例演示 2. 游標2.1 使用游標第一步&#xff0c;聲明游標第二步&#xff0c;打開游標第三步&#xff0c;使用游標&#xff08;從游標中取得數據&#xff09;第四步&#xff0c;關閉游標 2.2 舉例2.3 小結 在 MySQL…

藍橋杯單片機國賽模板——基于柳離風模板

藍橋杯單片機國賽模板——基于柳離風模板 文章目錄 藍橋杯單片機國賽模板——基于柳離風模板一、工程結構二、USER文件夾main.c 三、BSP文件夾1、sys2、display3、key4、timer5、iic6、ds13027、onewire8、uart9、ultrasound 四、源碼五、內存不夠 一、工程結構 與省賽模板相比…

C與指針——常見庫函數

字符串 #include<stdlibs.h> int abs(int); long labs(long); int rand(void);//0-RAND_MAX //字符串轉值 int atoi(const char*); long atol(const char*); float atof(const char*);數學\排序 #include<math.h> \\常見三角&#xff0c;sqrt(); exp(); double p…

數學復習筆記 2

前言 朋友和我討論了一個二重積分題&#xff0c;非常有意思。內容非常細致。整理如下&#xff1a; 二重積分 題目來源是 1000 上面的 16 題&#xff0c;積分區域是一個偏心圓&#xff0c;偏心圓的圓心在 y 軸上面&#xff0c;偏心圓是關于 y 軸對稱的&#xff0c;可以看關于…

Javaweb項目--Mybatis,導入com.mysql.cj.jdbc.Driver時報錯,Cannot resolve class ‘Driver‘

目錄 問題解決方法結果 問題 在項目java文件下&#xff0c;包文件下的application.properties文件中&#xff0c;項目目錄如下&#xff1a; 報錯信息如下&#xff1a; 解決方法 在pom.xml文件中增加此依賴 結果 報錯信息消失

分布式-redisson

分布式鎖redisson 加鎖流程緩存相關問題 加鎖流程 redisson底層通過lua腳本實現加鎖的原子性lock動作包含&#xff1a;加鎖、設置超時時間、鎖續命未獲取到鎖的線程通過獲取信號量許可等待&#xff0c;所釋放后釋放信號量通知等待線程 緩存相關問題 緩存失效&#xff08;擊穿…

Java基礎學完,繼續深耕(0505)Linux 常用命令

昨天休息了一天&#xff0c;沒有寫csdn 昨天和今天把Linux大概學了一下。總結一下常用命令&#xff0c;總結的不全。 Linux目錄結構 / 是所有目錄的頂點 目錄結構像一顆倒掛的樹 注意&#xff1a;/itheima 是絕對路徑&#xff0c;是指根目錄 / 下的itheima目錄 itheima…

【AI論文】Sadeed:通過小型語言模型推進阿拉伯語變音

摘要&#xff1a;由于語言的形態豐富&#xff0c;阿拉伯語文本的變音符號仍然是自然語言處理中一個持續的挑戰。 在本文中&#xff0c;我們介紹了一種基于微調解碼器語言模型的新方法Sadeed&#xff0c;該方法改編自Kuwain 1.5B Hennara等人[2025]的模型&#xff0c;該模型最初…

學習海康VisionMaster之亮度測量

一&#xff1a;進一步學習了 今天學習下VisionMaster中的亮度測量&#xff1a;這個和前面學習的都不一樣了&#xff0c;這個是測量ROI區域內的平均亮度等 1&#xff1a;什么是亮度測量&#xff1f; 我們工業上用的相機里面有一個感光芯片&#xff08;CCD/CMOS&#xff09;&…

學習路線(python)

Python從初級到專家的學習路線# 初級階段 (1-3個月)基礎語法數據結構文件操作推薦資源 中級階段 (3-6個月)面向對象編程常用模塊錯誤處理進階特性推薦資源 高級階段 (6-12個月)并發編程性能優化元編程設計模式推薦資源 專業方向 (選擇1-2個方向深入)Web開發數據分析/科學計算機…