【Python】進階 - 數據結構與算法

?系列篇章🎉

No.文章
1【Python】基礎知識(詳細)🚀
2【Python】基礎 - 循環、容器類型🚀
3【Python】基礎 - 推導式、函數🚀
4【Python】基礎 - 文件、異常、模塊🚀
5【Python】進階 - 面向對象(詳細)🚀
6【Python】進階 - 閉包、裝飾器、深淺拷貝🚀
7【Python】進階 - 網絡編程(TCP開發基礎、進程和線程)🚀
8【Python】進階 - 生成器、正則表達式🚀

文章目錄🎉

一、簡介

二、算法

2.1 時間復雜度🕒

1. 常數時間:

2. 對數時間:

3. 線性時間:

4.?線性對數時間:

5.?平方時間:

6. 指數時間:

2.2 空間復雜度🚀

1. 常數空間:

2. 對數空間:

3. 線性空間:

4.? 線性對數空間:

5. 平方空間:

6. 指數空間:

三、數據結構

3.1?線性結構

?1.?數組(列表)

?2.?鏈表🔗

3. 棧

4. 隊列

3.2?非線性結構

1. 樹🌳

2. 二叉樹🌳

3. 二叉搜索樹🌳

4. 完全二叉樹🌳

5.堆

6. 圖


一、簡介

數據結構與算法主要的作用就是為了提升程序的性能。

算法:是一組解決特定問題的有限、明確、可執行的操作步驟。它接收輸入數據并產生輸出結果,強調的是邏輯性和效率。

數據結構:相互之間存在一種或多種特定關系的數據元素的集合,用于組織、管理和存儲數據,以便能夠高效地訪問和修改數據。

程序 = 算法 + 數據結構

總結:算法是為了解決實際問題而設計的,數據結構是算法需要處理的問題載體

二、算法

特性
輸入? ? ????????有零個或多個輸入
輸出? ? ????????至少有一個輸出
確定性? ? ? ??每一步都必須清晰無歧義
有窮性? ? ? ? 在有限步內結束
可行性? ? ? ? 算法的每一步都是可行的

2.1 時間復雜度🕒

時間復雜度是一個用于描述算法運行時間與輸入規模之間關系的函數。它衡量的是算法執行所需的時間隨著輸入數據量增長的趨勢。通常使用大 O 表示法來描述。

時間復雜度不是表示程序運行的具體時間(如秒、毫秒),而是表示算法操作次數的增長趨勢。

①基本操作

時間復雜度為O(1)

②順序結構

時間復雜度按加法進行計算

③循環結構

時間復雜度按乘法進行計算

④分支結構

時間復雜度取最大值

⑤判斷一個算法的效率時,往往只需要關注操作數量的最高次項,其它次要項和常數項可以忽略

⑥在沒有特殊說明時,我們所分析的算法的時間復雜度都是指最壞時間復雜度

常見時間復雜度(從快到慢):

復雜度名稱示例
O(1)常數時間訪問數組元素
O(log n)對數時間二分查找
O(n)線性時間遍歷數組
O(n log n)線性對數時間快速排序、歸并排序
O(n2)平方時間雙重循環排序
O(2?)指數時間遞歸計算斐波那契數列(不帶緩存)
1. 常數時間

無論數據規模多大,執行時間都是固定的。例如訪問數組中的某個元素,操作次數總是1次,時間復雜度是O(1).

arr = [10, 20, 30, 40, 50]
print(arr[2])  # 直接訪問索引為 2 的元素
2. 對數時間

log^{_{2}7}?>100>log^{_{2}6}??,這里 i 是指數增長,每次運行 i 翻一倍,函數的時間復雜度O(log n).

count = 0
i = 1
while i<100:i *= 2count += 1print(count)    # 7 (2的7次方大于100)
3. 線性時間

當循環變量每次線性遞增(如 i += 1),且循環次數依賴于 n 的大小時,時間復雜度就是 O(n)

n = 100    # 這里 n 不是固定值,可以換成任意數
i = 0
while i < n:i += 1
4.?線性對數時間:

快速排序:每次分區操作需要遍歷整個數組(O(n)),而每次分區后數組被大致分成兩個相等的部分,所以總的遞歸深度是 log n。時間復雜度在平均情況下為 O(n log n),但在最壞情況下(每次選擇的基準值middle都是最大值或則最小值)可能退化到 O(n2)。

def quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) // 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right)# 測試
arr = [38, 27, 43, 3, 9, 82, 10]
print(quick_sort(arr))  # 輸出: [3, 9, 10, 27, 38, 43, 82]
5.?平方時間

冒泡排序:兩層循環,時間復雜度為O(n2)

def bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]return arr# 測試
arr = [64, 34, 25, 12, 22, 11, 90]
print(bubble_sort(arr))  # 輸出: [11, 12, 22, 25, 34, 64, 90]
6. 指數時間:

斐波那契數列:從下圖這個樹可以看出,每個節點會分裂成兩個子節點(除了葉子節點),形成一棵二叉樹。對于較大的 n,這棵樹的深度為 n,而每層的節點數量大致翻倍。時間復雜度接近O(2?)

fib(5)
├── fib(4)
│   ├── fib(3)
│   │   ├── fib(2)
│   │   │   ├── fib(1) = 1
│   │   │   └── fib(0) = 0
│   │   └── fib(1) = 1
│   └── fib(2)
│       ├── fib(1) = 1
│       └── fib(0) = 0
└── fib(3)├── fib(2)│   ├── fib(1) = 1│   └── fib(0) = 0└── fib(1) = 1
def fib(n):if n <= 1:return nreturn fib(n - 1) + fib(n - 2)# 測試
print(fib(5))  # 輸出: 5
print(fib(10)) # 輸出: 55

2.2 空間復雜度🚀

空間復雜度是指算法運行過程中需要的額外內存空間隨著輸入數據量增長的趨勢。通常也使用大 O 表示法來描述。

  • 額外內存空間:指的是除了輸入數據本身占用的空間外,算法運行期間額外使用的內存。
  • 不考慮輸入數據本身的大小:因為輸入數據大小通常是固定的或外部給定的,我們關注的是算法自身的開銷。
  • 遞歸調用棧:如果算法中有遞歸調用,那么遞歸深度會影響空間復雜度。
空間復雜度名稱示例代碼 / 場景簡要說明
O(1)常數空間交換兩個變量、訪問數組元素額外空間固定,與輸入規模無關
O(log n)對數空間快速排序(遞歸實現)遞歸深度為 log n,棧空間增長緩慢
O(n)線性空間創建新數組、哈希表存儲數據、帶緩存的斐波那契額外空間與輸入規模成正比
O(n log n)線性對數空間歸并排序(非原地實現)分治過程中需要較多輔助空間
O(n2)平方空間使用二維數組保存狀態(如動態規劃中的部分實現)空間需求隨輸入平方增長
O(2?)指數空間多重遞歸(如漢諾塔、無剪枝的回溯算法)空間消耗爆炸式增長,慎用
1. 常數空間:
def swap(a, b):a, b = b, areturn a, b

只使用了固定數量的變量(a、b),不隨輸入變化。空間復雜度為 O(1)。

2. 對數空間:

快速排序前面線性對數時間已經舉例過了,是遞歸實現的分治算法。雖然每次遞歸會創建新數組(非原地),但調用棧深度為 log n。因此空間復雜度為 O(log n)(主要是遞歸棧的空間)。

3. 線性空間:
def create_array(n):return [0] * n

創建了一個長度為 n 的數組,額外空間大小直接與輸入規模成正比,空間復雜度為 O(n)。

4.? 線性對數空間:

歸并排序(非原地實現)了解即可。

5. 平方空間:

創建一個 n x n 的二維數組,額外空間為 n * n = n2,空間復雜度為 O(n2)。

def create_2d_table(n):
# 下劃線 _ 只是一個約定俗成的寫法,表示這個循環變量在后續代碼中不會被使用。return [[0] * n for _ in range(n)]    print(create_2d_table(3))   # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
6. 指數空間:

漢諾塔問題是典型的多重遞歸問題,每層遞歸都會產生兩個子問題,導致調用棧指數級增長。空間復雜度為 O(2?),非常消耗內存。

def hanoi(n, source, target, auxiliary):"""漢諾塔游戲規則:使用三根柱子,將疊放的圓盤從一根柱子移動到另一根柱子,每次只能移動一個圓盤,且小圓盤不能放在大圓盤下方。:param n:         當前要移動的圓盤數量:param source:    當前圓盤所在的柱子:param target:    希望把圓盤移動到的目標柱子:param auxiliary: 輔助用的第三根柱:return:"""if n == 1:print(f"Move disk from {source} to {target}")returnhanoi(n - 1, source, auxiliary, target)print(f"Move disk from {source} to {target}")hanoi(n - 1, auxiliary, target, source)

三、數據結構

數據結構(Data Structure) 是計算機中存儲和組織數據的一種方式。它描述了數據之間的關系以及對這些數據的操作。

Python給我們提供了很多現成的數據結構類型,這些系統自己定義好的,不需要我們自己去定義的數據結構叫做Python的內置數據結構,比如列表、元組、字典。而有些數據組織方式,Python系統里面沒有直接定義,需要我們自己去定義實現這些數據的組織方式,這些數據組織方式稱之為Python的擴展數據結構,比如棧,隊列等。

3.1?線性結構

線性結構的特點是每個元素(除了第一個和最后一個)都有一個直接前驅和一個直接后繼。常見的線性結構包括數組、列表、棧、隊列等。

結構特點
數組(Array)固定大小,連續內存,隨機訪問快
鏈表(Linked List)動態大小,非連續內存,插入刪除快
棧(Stack)后進先出(LIFO)
隊列(Queue)先進先出(FIFO)
?1.?數組(列表)

Python中通過list實現,支持動態擴容和多種數據類型混合存儲。支持隨機訪問(通過索引),缺點是插入/刪除慢(需要移動其他元素)。

arr = [1, 2, 3, 'a', True]  # 創建列表
arr.append(4)               # 添加元素
print(arr[0])               # 訪問元素
?2.?鏈表🔗

分為單鏈表和雙鏈表,適合頻繁插入/刪除的場景。

? 特點:

? ? 每個節點包含數據和指向下一個節點的指針
? ? 可以動態增長

?? 缺點:

? ? 不支持隨機訪問
? ? 查找慢(O(n))

單鏈表

?

單鏈表是鏈表的一種形式,包含兩個域(元素域和鏈接域)。表元素域data用來存放具體的數據,鏈接域next用來存放下一個結點的位置,變量head指向鏈表的頭結點(首結點)的位置,從head出發能找到表中的任意結點。

class Node:def __init__(self, data):self.data = dataself.next = None# 創建鏈表
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)# 遍歷
current = head
while current:print(current.data)current = current.next

雙向鏈表

相較于單向鏈表,雙向鏈表多了一個指針,不僅有指向下一節點的指針,還有一個指針指向前一個結點。

class Node:"""節點類:表示雙向鏈表中的一個節點"""def __init__(self, data):self.data = data      # 節點存儲的數據self.prev = None      # 指向前一個節點的指針self.next = None      # 指向下一個節點的指針class DoublyLinkedList:"""雙向鏈表類:支持頭尾插入、刪除指定值節點以及正反向遍歷"""def __init__(self):self.head = None      # 鏈表的頭節點指針self.tail = None      # 鏈表的尾節點指針def append(self, data):"""在鏈表尾部插入一個新節點"""new_node = Node(data)  # 創建新節點if self.head is None:  # 如果鏈表為空self.head = new_nodeself.tail = new_nodeelse:new_node.prev = self.tail  # 新節點前驅指向當前尾節點self.tail.next = new_node  # 當前尾節點后繼指向新節點self.tail = new_node       # 更新尾節點為新節點def prepend(self, data):"""在鏈表頭部插入一個新節點"""new_node = Node(data)  # 創建新節點if self.head is None:  # 如果鏈表為空self.head = new_nodeself.tail = new_nodeelse:new_node.next = self.head  # 新節點后繼指向當前頭節點self.head.prev = new_node  # 當前頭節點前驅指向新節點self.head = new_node       # 更新頭節點為新節點def delete(self, data):"""刪除第一個匹配指定數據的節點(若存在)"""current = self.headwhile current:if current.data == data:  # 找到要刪除的節點if current.prev:current.prev.next = current.next  # 前驅節點連接后繼節點else:self.head = current.next  # 如果是頭節點,更新頭指針if current.next:current.next.prev = current.prev  # 后繼節點連接前驅節點else:self.tail = current.prev  # 如果是尾節點,更新尾指針returncurrent = current.next  # 繼續遍歷下一個節點def traverse_forward(self):"""從頭到尾遍歷鏈表并打印節點數據"""current = self.headwhile current:print(current.data, end=" ")  # 打印當前節點數據current = current.next        # 移動到下一個節點print()def traverse_backward(self):"""從尾到頭遍歷鏈表并打印節點數據"""current = self.tailwhile current:print(current.data, end=" ")  # 打印當前節點數據current = current.prev        # 移動到前一個節點print()

測試代碼:

# 測試雙向鏈表
dll = DoublyLinkedList()
dll.append(10)
dll.append(20)
dll.prepend(5)
print("正向遍歷:")
dll.traverse_forward()  # 輸出: 5 10 20
print("反向遍歷:")
dll.traverse_backward()  # 輸出: 20 10 5dll.delete(10)
print("刪除后正向遍歷:")
dll.traverse_forward()  # 輸出: 5 20
3. 棧

后進先出(LIFO),僅允許在棧頂進行插入或刪除,通過列表模擬或collections.deque實現。

stack = []
stack.append(1)  # push
stack.append(2)
print(stack.pop())  # pop -> 2
4. 隊列

先進先出(FIFO),推薦使用queue.Queuecollections.deque

from collections import deque
q = deque()
q.append(1)
q.append(2)
print(q.popleft())  # 出隊 -> 1

3.2?非線性結構

非線性結構是數據元素之間不再保持一對一關系的數據結構,主要包括樹形結構、圖形結構和集合結構等。與線性結構(如數組、鏈表)不同,非線性結構中的元素可以有多于一個的前驅或后繼元素。

結構特點
樹(Tree)層次結構,根節點到葉子節點分支
堆(Heap)完全二叉樹,堆頂最大或最小
圖(Graph)節點和邊組成,表示復雜關系
散列表 / 哈希表(Hash Table)鍵值對存儲,查找非常快
1. 樹🌳

樹形結構是層次化的非線性結構,數據元素之間存在一對多的關系。

?

參考上面這張圖我們介紹一下樹相關的一些基本術語

根節點(Root):樹中沒有父節點的節點。在這個例子中,節點A是根節點。
子節點(Child):一個節點直接連接到另一個節點下方,則這個節點稱為另一個節點的子節點。例如,B、C和D是A的子節點。
父節點(Parent):如果一個節點有子節點,那么這個節點就是其子節點的父節點。例如,A是B、C和D的父節點。
兄弟節點(Sibling):具有相同父節點的節點互為兄弟節點。例如,B、C和D互為兄弟節點。
葉節點(Leaf):沒有子節點的節點稱為葉節點或終端節點。在這個例子中,F、G、H、J、K和L都是葉節點。
內部節點(Internal Node):除了根節點外,所有有子節點的節點都稱為內部節點。在這個例子中,B、C、D、G和I是內部節點。
路徑(Path):從一個節點到另一個節點的路徑是由這兩個節點之間的邊組成的序列。例如,從A到L的路徑是A -> B -> G -> L。
深度(Depth):一個節點的深度是從根節點到該節點的唯一路徑上的邊的數量。例如,A的深度為0,B、C和D的深度為1,而L的深度為3。
高度(Height):一棵樹的高度是從根節點到最遠葉節點的最長路徑上的邊的數量。在這個例子中,樹的高度為3。

樹的遍歷

前序遍歷(根-左-右):先訪問根節點,然后遞歸地進行左子樹的前序遍歷,最后遞歸地進行右子樹的前序遍歷。對于給定的樹,前序遍歷的結果為:A -> B -> F -> G -> L -> C -> H -> D -> I -> M -> J -> K。
中序遍歷?(左-根-右):首先遞歸地進行左子樹的中序遍歷,然后訪問根節點,最后遞歸地進行右子樹的中序遍歷。對于給定的樹,中序遍歷的結果為:F -> B -> L -> G -> A -> C -> H -> I -> M -> D -> J -> K。
后序遍歷?(左-右-根):首先遞歸地進行左子樹的后序遍歷,然后遞歸地進行右子樹的后序遍歷,最后訪問根節點。對于給定的樹,后序遍歷的結果為:F -> L -> G -> B -> H -> C -> M -> I -> J -> K -> D -> A。

代碼實現:

class TreeNode:def __init__(self, val):self.val = valself.left = Noneself.middle = Noneself.right = None# 構建樹
def build_tree():# 創建節點A = TreeNode('A')B = TreeNode('B')C = TreeNode('C')D = TreeNode('D')F = TreeNode('F')G = TreeNode('G')H = TreeNode('H')I = TreeNode('I')J = TreeNode('J')K = TreeNode('K')L = TreeNode('L')M = TreeNode('M')# 構建樹結構A.left = BA.middle = CA.right = DB.left = FB.right = GG.left = LC.left = HD.left = ID.middle = JD.right = KI.left = Mreturn A# 前序遍歷
def preorder_traversal(node):if node:print(node.val, end=' ')preorder_traversal(node.left)preorder_traversal(node.middle)preorder_traversal(node.right)# 中序遍歷
def inorder_traversal(node):if node:inorder_traversal(node.left)print(node.val, end=' ')inorder_traversal(node.middle)inorder_traversal(node.right)# 后序遍歷
def postorder_traversal(node):if node:postorder_traversal(node.left)postorder_traversal(node.middle)postorder_traversal(node.right)print(node.val, end=' ')# 使用
root = build_tree()print("Pre-order traversal:")
preorder_traversal(root)
print("\nIn-order traversal:")
inorder_traversal(root)
print("\nPost-order traversal:")
postorder_traversal(root)
2. 二叉樹🌳

二叉樹是每個節點最多有兩個子節點的樹結構。

class TreeNode:def __init__(self, value):self.value = valueself.left = Noneself.right = None# 創建二叉樹
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 前序遍歷
def preorder_traversal(node):if node:print(node.value, end=' ')preorder_traversal(node.left)preorder_traversal(node.right)print("前序遍歷:")
preorder_traversal(root)  # 輸出: 1 2 4 5 3
3. 二叉搜索樹🌳

二叉搜索樹是一種特殊的二叉樹,左子節點的值小于父節點,右子節點的值大于父節點。

class BSTNode:# 定義二叉搜索樹節點類def __init__(self, value):self.value = value  # 節點值self.left = None    # 指向左子節點self.right = None   # 指向右子節點class BinarySearchTree:# 定義二叉搜索樹類def __init__(self):self.root = None  # 初始化根節點為空# 插入新值到二叉搜索樹中def insert(self, value):if not self.root:  # 如果樹為空,則創建根節點self.root = BSTNode(value)else:self._insert_recursive(self.root, value)  # 否則,使用遞歸方法插入# 遞歸實現插入操作def _insert_recursive(self, node, value):if value < node.value:  # 如果新值小于當前節點值if node.left is None:  # 若左子節點為空,則插入為左子節點node.left = BSTNode(value)else:self._insert_recursive(node.left, value)  # 否則,繼續在左子樹中查找位置else:  # 如果新值大于或等于當前節點值if node.right is None:  # 若右子節點為空,則插入為右子節點node.right = BSTNode(value)else:self._insert_recursive(node.right, value)  # 否則,繼續在右子樹中查找位置# 在二叉搜索樹中搜索指定值def search(self, value):return self._search_recursive(self.root, value)  # 使用遞歸方法進行搜索# 遞歸實現搜索操作def _search_recursive(self, node, value):if node is None or node.value == value:  # 如果節點為空或找到了目標值,則返回該節點return nodeif value < node.value:  # 如果目標值小于當前節點值,則在左子樹中繼續搜索return self._search_recursive(node.left, value)return self._search_recursive(node.right, value)  # 否則,在右子樹中繼續搜索# 使用示例
bst = BinarySearchTree()  # 創建一個二叉搜索樹實例
bst.insert(50); bst.insert(30); bst.insert(20); bst.insert(40); bst.insert(70); bst.insert(60); bst.insert(80)print("\n查找40:", bst.search(40) is not None)  # 輸出: True
print("查找100:", bst.search(100) is not None)  # 輸出: False
4. 完全二叉樹🌳

完全二叉樹是一棵深度為 h 的二叉樹,除了最后一層外,其他層的節點都是滿的,并且最后一層的節點都盡可能靠左排列。完全二叉樹是構建 堆 的基礎結構。

?

我們可以用列表來模擬完全二叉樹的存儲方式。在完全二叉樹中,可以通過索引快速找到父節點和子節點:

  • 父節點索引:(i - 1) // 2
  • 左子節點索引:2 * i + 1
  • 右子節點索引:2 * i + 2
class CompleteBinaryTree:def __init__(self):self.tree = []  # 使用列表存儲完全二叉樹的節點值def insert(self, value):"""向完全二叉樹中插入一個節點"""self.tree.append(value)def get_parent_index(self, index):"""獲取父節點的索引"""if index == 0:return Nonereturn (index - 1) // 2def get_left_child_index(self, index):"""獲取左子節點的索引"""left_index = 2 * index + 1if left_index >= len(self.tree):return Nonereturn left_indexdef get_right_child_index(self, index):"""獲取右子節點的索引"""right_index = 2 * index + 2if right_index >= len(self.tree):return Nonereturn right_indexdef display(self):"""顯示完全二叉樹的結構"""print("完全二叉樹的層次遍歷:")for i in range(len(self.tree)):print(f"節點 {self.tree[i]} | 父節點索引: {self.get_parent_index(i)} | 左子節點索引: {self.get_left_child_index(i)} | 右子節點索引: {self.get_right_child_index(i)}")# 使用示例
cbt = CompleteBinaryTree()
cbt.insert(1)
cbt.insert(2)
cbt.insert(3)
cbt.insert(4)
cbt.insert(5)
cbt.insert(6)cbt.display()

?輸出結果:

完全二叉樹的層次遍歷:
節點 1 | 父節點索引: None | 左子節點索引: 1 | 右子節點索引: 2
節點 2 | 父節點索引: 0 | 左子節點索引: 3 | 右子節點索引: 4
節點 3 | 父節點索引: 0 | 左子節點索引: 5 | 右子節點索引: None
節點 4 | 父節點索引: 1 | 左子節點索引: None | 右子節點索引: None
節點 5 | 父節點索引: 1 | 左子節點索引: None | 右子節點索引: None
節點 6 | 父節點索引: 2 | 左子節點索引: None | 右子節點索引: None
5.堆

堆是一種特殊的完全二叉樹,分為最大堆和最小堆。

  • 最大堆(Max Heap):每個節點的值都大于等于其子節點的值。
  • 最小堆(Min Heap):每個節點的值都小于等于其子節點的值。

Python 中可以使用 heapq 模塊實現最小堆:

import heapq# 創建一個最小堆
min_heap = []
heapq.heappush(min_heap, 3)
heapq.heappush(min_heap, 1)
heapq.heappush(min_heap, 2)
heapq.heappush(min_heap, 5)
heapq.heappush(min_heap, 4)print("最小堆的內容:", min_heap)
print("彈出最小值:", heapq.heappop(min_heap))
print("更新后的最小堆:", min_heap)
6. 圖

圖形結構是最一般的非線性結構,數據元素之間存在多對多的關系。表示對象之間的復雜關系,由節點(Vertex)和邊(Edge)組成。

鄰接表表示法(Python 字典):

graph = {'A': ['B', 'C'],'B': ['A', 'D'],'C': ['A', 'D'],'D': ['B', 'C']
}

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

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

相關文章

【如何實現分布式壓測中間件】

分布式壓測中間件的原理及其實現 原理全鏈路追蹤框架&#xff08;Trace&#xff09;MQ中間件數據庫分布式緩存中間件&#xff08;Redis&#xff09;分庫分表中間件 原理 通過大量閱讀中間件源碼&#xff0c;開源社區調研&#xff0c;得到設計原理&#xff1a; &#xff08;1&a…

Qt進程間保活方案:詳解如何實現進程間通信與自動保活機制

目錄 摘要 一、進程間保活的基本原理 二、具體步驟及代碼示例 三、常見問題與優化 四、總體方案 摘要 在一些需要長時間運行的應用程序中&#xff0c;確保進程在意外退出時能夠自動重啟是一項非常重要的任務。尤其是在嵌入式開發、后臺服務以及需要高可用性的場景下&#x…

Python-內置數據結構-list-tuple-bubble-字符串-bytes-bytesarray-切片-學習筆記

欠4年前自己的一份筆記&#xff0c;獻給今后的自己。 分類 數值型 int、float、complex、bool 序列對象 字符串 str 列表 list tuple 鍵值對 集合set 字典dict 數值型 int、float、complex、bool都是class&#x…

利用事務鉤子函數解決業務異步發送問題

利用事務鉤子函數解決業務異步發送問題 一、問題背景二、實現方案1、生產者代碼2、消費者代碼 三、測試與驗證1、未開啟事務場景2、開啟事務場景 四、項目結構及源碼 一、問題背景 在某項業務中&#xff0c;需要在事務完成后&#xff0c;寫入日志到某數據庫中。需要要么都成功&…

uniapp選擇相冊

概述 一款針對Android平臺下的圖片選擇器&#xff0c;支持從相冊獲取圖片、視頻、音頻&拍照&#xff0c;支持裁剪(單圖or多圖裁剪)、壓縮、主題自定義配置等功能&#xff0c;支持動態獲取權限&適配Android 5.0系統的開源圖片選擇框架。 支持Uniapp和Uniapp X下的Vue2、…

MAC 多應用切換技巧,單應用切換技巧

在 Mac 上&#xff0c;有幾種快捷鍵可以幫助你快速切換應用程序窗口&#xff1a; 1. Command (?) Tab - 這是最常用的快捷鍵&#xff0c;用于在打開的應用程序之間進行循環切換。按住 Command 鍵不放&#xff0c;然后反復按下 Tab 鍵可以選擇下一個應用程序。當你松開 Comm…

SpringBoot+本地部署大模型實現知識庫功能

SpringBoot本地部署大模型實現RAG知識庫功能 1、Linux系統部署本地大模型1.1 安裝ollama1.2 啟動ollama1.3 下載deepseek模型 2、Springboot代碼調用本地模型實現基礎問答功能3、集成向量數據庫4、知識庫數據喂取5、最終實現RAG知識庫功能 1、Linux系統部署本地大模型 1.1 安裝…

嵌入式原理與應用篇---ARM

ARM 架構的 STM32 系列微控制器廣泛應用于嵌入式系統開發&#xff0c;理解其匯編語言指令對于優化性能、訪問硬件底層非常重要。下面詳細解釋常見的 ARM 匯編指令及其使用實例。 數據處理指令 1. MOV&#xff08;移動&#xff09; 功能&#xff1a;將立即數或寄存器值復制到…

【RHCSA-Linux考試題目筆記(自用)】servera的題目

一、開始 1、啟動rhcsa環境 2、點擊題目&#xff0c;看題 3、通過控制器來啟動所有虛擬機 控制器 打開后點start&#xff0c;然后ok 之后進入一個有classroom、servera、serverb&#xff08;考試不一定叫這些名&#xff0c;但大差不差&#xff09;什么之類的界面&#xff0c;…

SpringBoot項目使用arthas-tunnel-server

參考官網Arthas Spring Boot Starter | arthas Spring Boot系列之使用Arthas Tunnel Server 進行遠程調試實踐-騰訊云開發者社區-騰訊云 springBoot項目, 增加maven依賴 <dependency><groupId>com.taobao.arthas</groupId><artifactId>arthas-sprin…

Modbus TCP 進階:基于以太網的遠程設備控制(二)

基于 Modbus TCP 的遠程設備控制實戰 &#xff08;一&#xff09;硬件與網絡搭建實操 1. 設備選型與連接 在工業現場&#xff0c;根據遠程控制需求進行設備選型至關重要 。對于傳感器&#xff0c;若要監測溫度&#xff0c;可選擇高精度的熱電偶傳感器&#xff0c;如 K 型熱電…

分庫分表之實戰-sharding-JDBC

大家好&#xff0c;我是工藤學編程 &#x1f989;一個正在努力學習的小博主&#xff0c;期待你的關注實戰代碼系列最新文章&#x1f609;C實現圖書管理系統&#xff08;Qt C GUI界面版&#xff09;SpringBoot實戰系列&#x1f437;【SpringBoot實戰系列】Sharding-Jdbc實現分庫…

httpcore-nio引起的線程、fd泄露問題

依賴來源&#xff1a;httpasyncclient-4.1.4.jar 現象 程序報錯too many open files 線程數飆升、句柄數飆升 thread dump顯示大量 "I/O dispatcher 7215" #9102 prio5 os_prio0 tid0x00002b7ba036a800 nid0x6f24 runnable [0x00002b7d98d41000]java.lang.Thread.…

多線程生產者消費者模型實戰案例

多線程生產者消費者模型實戰案例 前言業務場景術前準備無鎖無事務有事務 synchronized事務在鎖外事務在鎖內 數據庫行鎖什么是數據庫行鎖有事務沒有事務 樂觀鎖ReentrantLock分布式鎖 前言 曾經一直有一個疑惑&#xff0c;就是關于多線程生產者消費者模型的學習過程中&#xf…

青少年編程與數學 02-022 專業應用軟件簡介 03 三維建模及動畫軟件:Autodesk Maya

青少年編程與數學 02-022 專業應用軟件簡介 03 三維建模及動畫軟件&#xff1a;Autodesk Maya 一、什么是三維建模二、什么是計算機動畫三、三維建模及動畫設計軟件的發展歷程&#xff08;一&#xff09;早期探索階段&#xff08;20世紀60年代 - 80年代&#xff09;&#xff08…

獲得 OCM 大師證書學習歷練

當我站在山城重慶的洪崖洞前&#xff0c;看著璀璨的夜景倒映在嘉陵江上&#xff0c;手中緊握著 OCM 大師證書&#xff0c;那一刻&#xff0c;備考時的艱辛與考試時的緊張都化作了滿滿的成就感。這段在重慶獲得 OCM 大師證書的經歷&#xff0c;就像一場充滿挑戰與驚喜的冒險&…

srs-gb28181 與 SRS 5.0 對 GB28181 國標支持

srs-gb28181 是基于 SRS 4.0/5.0 的國標&#xff08;GB28181&#xff09;擴展分支&#xff0c;而 SRS 5.0 官方版本也逐步增強了對 GB28181 的支持。以下是兩者的主要區別&#xff1a; 1. 功能支持對比 功能srs-gb28181&#xff08;擴展分支&#xff09;SRS 5.0&#xff08;官…

算法第18天|繼續二叉樹:修剪二叉搜索樹、將有序數組轉化為二叉搜索樹、把二叉搜索樹轉換為累加樹

今日總結&#xff1a; 1、修剪二叉搜索樹&#xff08;重點思考如何修剪&#xff09; &#xff08;1&#xff09;遞歸的返回值是什么&#xff1f;&#xff08;與插入、刪除一樣&#xff09; &#xff08;2&#xff09;遞歸的單層邏輯一定要縷清&#xff08;3中情況討論&#xff…

C# 多線程(三)線程池

目錄 1.通過TPL使用線程池 2.不使用TPL進入線程池的辦法 異步委托 3.線程池優化技術 最小線程數的工作原理 每當啟動一個新線程時&#xff0c;系統都需要花費數百微秒來分配資源&#xff0c;例如創建獨立的局部變量棧空間。默認情況下&#xff0c;每個線程還會占用約1…

學習筆記(29):訓練集與測試集劃分詳解:train_test_split 函數深度解析

學習筆記(29):訓練集與測試集劃分詳解&#xff1a;train_test_split 函數深度解析 一、為什么需要劃分訓練集和測試集&#xff1f; 在機器學習中&#xff0c;模型需要經歷兩個核心階段&#xff1a; 訓練階段&#xff1a;用訓練集數據學習特征與目標值的映射關系&#xff08;…