嵌入式(C語言篇)Day13

嵌入式Day13


一段話總結

文檔主要介紹帶有頭指針和尾指針的單鏈表的實現及操作,涵蓋創建、銷毀、頭插、尾插、按索引/數據增刪查、遍歷等核心操作,強調頭插/尾插時間復雜度為O(1),按索引/數據操作需遍歷鏈表、時間復雜度為O(n),并對比提及雙向鏈表因存儲前后指針、操作更高效,是典型的空間換時間策略。


思維導圖

## **單鏈表結構**
- 頭指針(head)
- 尾指針(tail)
- 節點(Node):data+next指針
- 鏈表結構體(LinkedList):包含head、tail、size
## **核心操作**
- 創建:calloc分配LinkedList結構體
- 銷毀:先釋放所有節點,再釋放結構體
- 遍歷:按"x->y->z->NULL"格式打印
- 新增- 頭插(add_before_head):更新head,首個節點時更新tail- 尾插(add_behind_tail):有節點時尾節點next指向新節點,否則更新head- 按索引(idx):idx=0頭插,idx=size尾插,中間需找idx-1前驅節點
- 查詢- 按索引(search_by_idx):遍歷找idx節點- 按數據:遍歷找匹配data節點
- 刪除- 按索引(delete_by_idx):idx=0刪頭節點,其他找前驅節點,刪尾節點需更新tail- 按數據(delete_by_data):遍歷找節點及前驅,刪頭/尾節點特殊處理
## **時間復雜度**
- O(1):頭插、尾插、刪頭節點
- O(n):按索引/數據增刪查、刪非頭節點
## **雙向鏈表對比**
- 節點增加前驅指針
- 操作更靈活,附近操作O(1)
- 空間換時間,如C++ list/Java LinkedList底層實現

詳細總結

一、單鏈表結構與核心操作概述
  • 結構組成:由LinkedList結構體管理head(頭指針)、tail(尾指針)、size(節點數),每個Node包含data(數據)和next(后繼指針)。
  • 核心操作:涵蓋創建、銷毀、遍歷、增刪查等,操作時需注意頭/尾節點特殊情況(如首個節點需同時更新headtail)。
二、具體操作實現要點
  1. 創建與銷毀
    • 創建:使用calloc分配LinkedList結構體,初始head=tail=NULLsize=0
    • 銷毀:先遍歷釋放所有Node節點,再釋放LinkedList結構體。
  2. 新增操作
    • 頭插法:新節點直接指向原head,更新head;若為首個節點,同時更新tail
    • 尾插法:若鏈表非空,原tail->next指向新節點,更新tail;若為空,直接更新headtail
    • 按索引插入:索引范圍[0, size]idx=0頭插,idx=size尾插,中間需遍歷找到idx-1前驅節點,時間復雜度O(n)
  3. 查詢操作
    • 按索引查詢:索引范圍[0, size-1],遍歷找到對應節點,時間復雜度O(n)
    • 按數據查詢:遍歷全鏈表匹配數據,時間復雜度O(n)
  4. 刪除操作
    • 按索引刪除idx=0直接刪頭節點,更新head;若為尾節點(idx=size-1),需更新tail為前驅節點;其他情況遍歷找前驅節點,時間復雜度O(n)(除刪頭節點為O(1))。
    • 按數據刪除:遍歷找到節點及其前驅,刪頭節點時更新head,刪尾節點時更新tail,時間復雜度O(n)(除刪頭節點為O(1))。
三、時間復雜度對比表
操作類型具體操作時間復雜度是否需遍歷
新增頭插/尾插O(1)
按索引插入O(n)是(中間)
查詢按索引/數據查詢O(n)
刪除刪頭節點O(1)
刪非頭節點(含尾)O(n)
四、雙向鏈表對比
  • 優勢:節點增加前驅指針(prev),可直接訪問前后節點,附近操作(如刪除當前節點)時間復雜度為O(1),性能更優。
  • 應用:C++ list、Java LinkedList底層均為雙向鏈表,體現空間換時間策略。

關鍵問題

  1. 為什么頭插法和尾插法的時間復雜度是O(1)?
    答:頭插法直接通過頭指針操作首個節點,尾插法通過尾指針直接定位最后一個節點,無需遍歷鏈表,因此時間復雜度為O(1)。

  2. 刪除單鏈表尾節點的時間復雜度為什么是O(n)?
    答:刪除尾節點需先遍歷找到其前驅節點(需O(n)時間),才能更新前驅節點的next指針為NULL,因此整體時間復雜度為O(n)。

  3. 雙向鏈表相比單鏈表的核心優化點是什么?
    答:雙向鏈表每個節點增加前驅指針(prev),可直接訪問前后節點,使在確定節點附近的操作(如刪除當前節點)時間復雜度從O(n)降至O(1),以空間換時間提升性能。

文檔主要介紹了單鏈表常見的五道經典面試題及解法,包括求中間結點、判斷是否有環、反轉鏈表、合并兩條有序鏈表(兩種方法),具體如下:

六、求鏈表中間結點

問題:給定單鏈表,找到中間結點(奇數長度取中間結點,偶數長度取中間偏右結點)。
解法

  1. 遍歷統計法
    • 先遍歷鏈表統計長度 list_len,再計算中間索引 mid_idx = list_len / 2,再次遍歷找到對應結點。
    • 時間復雜度:O(n)(兩次遍歷)。
  2. 快慢指針法(雙指針法)
    • 思路:定義兩個指針 slow(每次走1步)和 fast(每次走2步)。當 fast 到達鏈表末尾(fast == NULLfast->next == NULL)時,slow 指向中間結點。
    • 代碼邏輯
      int find_mid_ele2(Node *head) {Node *fast = head, *slow = head;while (fast != NULL && fast->next != NULL) { // 循環條件確保快慢指針有效移動slow = slow->next;fast = fast->next->next;}return slow->data; // 直接返回中間結點數據
      }
      
    • 時間復雜度:O(n)(單次遍歷),效率更高。

七、判斷單鏈表是否有環

問題:判斷單鏈表是否存在環(尾結點 next 指向鏈表中任意結點)。
解法快慢指針法

  • 思路:若鏈表有環,快慢指針最終會在環內相遇;若無環,fast 會先到達 NULL,循環結束。
  • 代碼邏輯
    bool has_circle(Node *head) {Node *fast = head, *slow = head;while (fast != NULL && fast->next != NULL) {slow = slow->next;fast = fast->next->next;if (slow == fast) return true; // 相遇即有環}return false; // 循環正常結束,無環
    }
    
  • 關鍵點
    • 環的形成:尾結點 next 指向頭結點、中間結點或自身。
    • 快慢指針速度差確保在環內必然相遇(數學證明:快指針每次比慢指針多走1步,環長有限,最終會追上)。

八、單鏈表反轉(循環迭代法)

問題:反轉單鏈表,返回新鏈表的頭指針(原尾結點)。
解法三指針法(prev、curr、succ)

  • 思路
    1. 初始化 prev = NULL(前驅指針,指向反轉后的尾部),curr = head(當前結點),succ = head->next(后繼結點,防止鏈表斷開)。
    2. 遍歷鏈表,每次將 curr->next 指向 prev,然后 prevcurrsucc 依次后移。
    3. 遍歷結束后,prev 指向新鏈表的頭結點(原尾結點)。
  • 代碼實現
    Node *reverse(Node *head) {Node *prev = NULL, *curr = head, *succ = head ? head->next : NULL; // 處理頭結點為空的情況while (curr != NULL) {curr->next = prev; // 反轉當前結點指向prev = curr;curr = succ;succ = (succ != NULL) ? succ->next : NULL; // 避免空指針訪問}return prev; // 返回新頭指針
    }
    
  • 變種:通過二級指針直接修改原頭指針(reverse2 函數),適用于需要修改原始鏈表頭指針的場景。

九、合并兩條有序單鏈表(循環迭代法)

問題:合并兩條升序單鏈表,返回合并后的升序鏈表頭指針。
解法1:無虛擬頭結點(需處理頭部特殊情況)

  • 步驟
    1. 校驗空鏈表,直接返回非空鏈表。
    2. 找到兩條鏈表的最小結點,作為新鏈表的頭指針 head 和尾指針 tail,并移動對應鏈表指針(list1list2)。
    3. 循環比較 list1list2 的當前結點,將較小結點接入 tail->next,更新 tail 和對應鏈表指針。
    4. 循環結束后,將剩余非空鏈表接入 tail
  • 代碼邏輯
    Node *merge_lists(Node *list1, Node *list2) {if (!list1 || !list2) return list1 ? list1 : list2; // 處理空鏈表Node *head, *tail;if (list1->data < list2->data) {head = tail = list1;list1 = list1->next;} else {head = tail = list2;list2 = list2->next;}while (list1 && list2) { // 合并剩余結點if (list1->data < list2->data) {tail->next = list1;tail = list1;list1 = list1->next;} else {tail->next = list2;tail = list2;list2 = list2->next;}}tail->next = (list1 != NULL) ? list1 : list2; // 接入剩余鏈表return head;
    }
    

解法2:使用虛擬頭結點(簡化頭部處理)

  • 優化點:在鏈表頭部添加一個虛擬結點 dummy_node,避免單獨處理頭指針初始化,統一邏輯。
  • 代碼邏輯
    Node *merge_lists2(Node *list1, Node *list2) {if (!list1 || !list2) return list1 ? list1 : list2;Node dummy_node = {0, NULL}; // 棧上創建虛擬頭結點Node *tail = &dummy_node; // tail指向虛擬結點,作為初始尾結點while (list1 && list2) { // 直接合并所有結點,無需頭部特殊處理if (list1->data < list2->data) {tail->next = list1;tail = list1;list1 = list1->next;} else {tail->next = list2;tail = list2;list2 = list2->next;}}tail->next = (list1 != NULL) ? list1 : list2;return dummy_node.next; // 返回虛擬結點的下一個結點(真正的頭結點)
    }
    
  • 優勢:虛擬頭結點使頭部和后續結點的處理邏輯一致,代碼更簡潔,減少邊界條件判斷。

十、核心算法總結

面試題關鍵思路時間復雜度空間復雜度
求中間結點快慢指針法(單次遍歷)O(n)O(1)
判斷是否有環快慢指針法(相遇即有環)O(n)O(1)
反轉鏈表三指針迭代反轉(prev、curr、succ)O(n)O(1)
合并有序鏈表(無虛擬頭)比較結點+尾插法(處理頭部特殊情況)O(n+m)O(1)
合并有序鏈表(有虛擬頭)虛擬頭結點統一邏輯O(n+m)O(1)

注意事項

  • 指針操作需避免空指針訪問(如判斷 succ != NULL 再取值)。
  • 處理邊界條件(如空鏈表、單結點鏈表、環的特殊情況)。
  • 虛擬頭結點常用于簡化鏈表操作的頭部邏輯,提高代碼魯棒性。

文檔主要介紹單鏈表反轉與合并的遞歸實現方法,包括遞歸思路、代碼實現及復雜度分析,以下是詳細總結:

十一、單鏈表反轉(遞歸實現)

核心思路:通過遞歸分解問題,將長鏈表反轉拆解為短鏈表反轉,逐步構建反轉后的鏈表。

  1. 遞歸分解邏輯
    • 問題分解:反轉 n 個結點的鏈表 = 反轉第 1 個結點 + 反轉后續 n-1 個結點。
    • 遞歸出口:當鏈表為空或只剩一個結點時,直接返回頭結點(無需反轉)。
    • 關鍵操作
      • 先遞歸反轉后續結點(從第 2 個結點開始),得到新鏈表頭指針 new_head
      • 修改第 2 個結點的指針,使其指向第 1 個結點(head->next->next = head)。
      • 將第 1 個結點的指針置為 NULL,使其成為新鏈表的尾結點。
  2. 代碼實現
    Node *reverse_recursion(Node *head) {// 遞歸出口:空鏈表或單結點鏈表if (head == NULL || head->next == NULL) {return head;}// 遞歸反轉后續結點,得到新鏈表頭指針Node *new_head = reverse_recursion(head->next);// 讓第 2 個結點指向第 1 個結點head->next->next = head;// 第 1 個結點置為尾結點(指針域為 NULL)head->next = NULL;return new_head; // 返回新鏈表頭指針
    }
    
  3. 復雜度分析
    • 時間復雜度:O(n),每個結點遞歸處理一次。
    • 空間復雜度:O(n),遞歸棧深度最多為 n(鏈表長度),存在棧溢出風險。

十二、合并兩條有序單鏈表(遞歸實現)

核心思路:通過遞歸逐層比較兩條鏈表的當前結點,將較小結點作為當前層結果,并遞歸合并剩余結點。

  1. 遞歸分解邏輯
    • 問題分解:合并鏈表 list1list2 = 選擇當前較小結點 + 遞歸合并剩余結點。
    • 遞歸出口:當任一鏈表為空時,直接返回另一鏈表(已處理完所有結點)。
    • 關鍵操作
      • 比較 list1list2 的當前結點,選擇較小者作為當前層合并結果。
      • 將較小結點的 next 指針指向遞歸合并剩余結點的結果(形成鏈式合并)。
  2. 代碼實現
    Node *merge_lists3(Node *list1, Node *list2) {// 遞歸出口:處理空鏈表if (list1 == NULL) return list2;if (list2 == NULL) return list1;// 選擇較小結點,并遞歸合并剩余結點if (list1->data < list2->data) {list1->next = merge_lists3(list1->next, list2); // 遞歸合并 list1 剩余結點和 list2return list1; // 返回當前較小結點} else {list2->next = merge_lists3(list1, list2->next); // 遞歸合并 list1 和 list2 剩余結點return list2; // 返回當前較小結點}
    }
    
  3. 復雜度分析
    • 時間復雜度:O(m+n),每條鏈表的每個結點遞歸處理一次(m、n 為鏈表長度)。
    • 空間復雜度:O(m+n),遞歸棧深度最多為 m+n,大鏈表場景下可能導致棧溢出。

十三、遞歸與迭代實現對比

操作實現方式時間復雜度空間復雜度優缺點對比
單鏈表反轉迭代O(n)O(1)(原地算法)無額外空間,效率高,適合大鏈表;邏輯較直觀,需維護三指針(prev、curr、succ)。
遞歸O(n)O(n)(遞歸棧)代碼簡潔,利用遞歸分解問題;但存在棧溢出風險,大鏈表場景下不推薦。
合并有序鏈表迭代O(m+n)O(1)(原地算法)需處理頭部特殊情況(或用虛擬頭結點簡化),邏輯稍復雜,無棧風險。
遞歸O(m+n)O(m+n)(遞歸棧)代碼更簡潔,遞歸分解自然;但棧空間占用隨鏈表長度增長,大鏈表易棧溢出。

十四、注意事項與擴展

  1. 遞歸的局限性
    • 遞歸深度受系統棧空間限制,處理長鏈表(如上萬結點)時可能引發棧溢出錯誤。
    • 迭代實現更適合生產環境,尤其對性能和穩定性要求高的場景。
  2. 虛擬頭結點的應用
    • 迭代合并鏈表時,虛擬頭結點可統一頭部和后續結點的處理邏輯,減少邊界條件判斷(如 merge_lists2 函數)。
  3. 其他反轉思路
    • 復制頭插法:遍歷原鏈表,復制每個結點并采用頭插法構建新鏈表。時間復雜度 O(n),但需額外空間且涉及內存分配,效率較低。

十五、總結

  • 遞歸的核心思想:將大問題分解為同類型小問題,通過遞歸出口終止分解,逐層構建結果。
  • 適用場景:遞歸適合邏輯簡潔、鏈表長度較小的場景;迭代更適合長鏈表或對性能敏感的場景。
  • 指針操作要點:遞歸實現中需注意指針指向的正確性(如反轉時避免鏈表斷開),確保每一步遞歸調用后鏈表結構有效。

文檔主要介紹七種基于比較的排序算法,包括簡單排序(冒泡、選擇、插入)、希爾排序及高級排序(歸并、快速、堆排序),以下是從第十六條開始的詳細總結:

十六、插入排序(重點)

  • 核心思想:將未排序元素逐個插入到已排序序列的合適位置,類似撲克牌整理。
  • 操作流程
    1. 從第二個元素開始(視為未排序元素),與前序已排序元素比較。
    2. 若未排序元素小于前序元素,則前序元素后移,直至找到合適位置插入。
  • 代碼邏輯(偽代碼):
    for (i = 1; i < n; i++) {  temp = arr[i];  j = i - 1;  while (j >= 0 && arr[j] > temp) {  arr[j+1] = arr[j];  j--;  }  arr[j+1] = temp;  
    }
    
  • 復雜度
    • 時間復雜度:O(n2)(最壞/平均),但常數項和系數優于冒泡、選擇排序,實際性能更好。
    • 空間復雜度:O(1)(原地排序)。
  • 穩定性:穩定(相鄰交換,不改變相同元素相對順序)。
  • 適用場景:小規模數據排序的首選算法。

十七、希爾排序(了解)

  • 核心思想:插入排序的改進版,通過增量遞減將數組分組,對每組進行插入排序,逐步縮小增量至1。
  • 操作流程
    1. 選擇初始增量(如 gap = n/2),將數組分為 gap 組(每組元素下標差為 gap)。
    2. 對每組進行插入排序,縮小增量(如 gap = gap/2),重復直至 gap=1(此時退化為插入排序)。
  • 復雜度
    • 時間復雜度:依賴增量選擇,介于 O(nlogn) 到 O(n2) 之間(通常優于插入排序)。
    • 空間復雜度:O(1)(原地排序)。
  • 穩定性:不穩定(跨組交換可能改變相同元素相對順序)。
  • 評價:適用場景有限,大數據集下不如高級排序,小數據集下犧牲穩定性但性能提升不明顯。

十八、歸并排序(高級排序)

  • 核心思想:分治策略,遞歸將數組分成兩半,分別排序后合并有序子數組。
  • 關鍵步驟
    1. 分解:將數組從中間分成左右兩部分,直至子數組長度為1(有序)。
    2. 合并:將兩個有序子數組合并為一個有序數組(需額外空間存儲臨時合并結果)。
  • 代碼邏輯(偽代碼):
    void merge_sort(int arr[], int left, int right) {  if (left < right) {  mid = (left + right)/2;  merge_sort(arr, left, mid);  merge_sort(arr, mid+1, right);  merge(arr, left, mid, right); // 合并兩個有序子數組  }  
    }
    
  • 復雜度
    • 時間復雜度:O(nlogn)(所有情況均穩定)。
    • 空間復雜度:O(n)(需額外數組存儲合并結果)。
  • 穩定性:穩定(合并時保留相同元素順序)。
  • 適用場景:需要穩定排序的大數據集,如外部排序(磁盤數據排序)。

十九、快速排序(高級排序,重點)

  • 核心思想:分治策略,選擇基準值(pivot),將數組分為小于/大于基準值的左右兩部分,遞歸排序子數組。
  • 關鍵步驟
    1. 分區:選擇基準值,通過交換將數組分為左(< pivot)、中(= pivot)、右(> pivot)三部分。
    2. 遞歸:對左右子數組重復分區操作,直至子數組長度為1。
  • 優化點
    • 基準值選擇:隨機選、三數取中(避免最壞情況O(n2))。
    • 雙向分區:從兩端向中間掃描,減少交換次數。
  • 復雜度
    • 時間復雜度:平均 O(nlogn),最壞 O(n2)(可通過基準值優化規避)。
    • 空間復雜度:O(logn)(遞歸棧深度,平均情況),最壞 O(n)(退化為鏈表遞歸)。
  • 穩定性:不穩定(跨區交換可能改變相同元素順序)。
  • 適用場景:大數據集排序的首選(性能最優),但需注意棧溢出風險(大遞歸深度)。

二十、堆排序(高級排序)

  • 核心思想:基于堆(大頂堆/小頂堆)結構,每次將堆頂元素(最大值/最小值)與末尾元素交換,逐步構建有序數組。
  • 關鍵步驟
    1. 建堆:將數組轉換為大頂堆(父節點≥子節點)。
    2. 排序:交換堆頂(最大值)與末尾元素,對前 n-1 個元素重新建堆,重復直至排序完成。
  • 復雜度
    • 時間復雜度:O(nlogn)(建堆 O(n),每次調整堆 O(logn))。
    • 空間復雜度:O(1)(原地排序,僅利用數組本身空間)。
  • 穩定性:不穩定(堆頂交換可能破壞相同元素順序)。
  • 適用場景:無需遞歸、空間受限的大數據集排序,如操作系統進程調度。

二十一、七種排序算法對比表

算法時間復雜度(最壞)時間復雜度(平均)空間復雜度穩定性適用場景
冒泡排序O(n2)O(n2)O(1)穩定玩具算法,僅學習用途
選擇排序O(n2)O(n2)O(1)不穩定玩具算法,僅學習用途
插入排序O(n2)O(n2)O(1)穩定小規模數據首選
希爾排序O(n2)O(nlogn)~O(n2)O(1)不穩定了解即可,實際應用少
歸并排序O(nlogn)O(nlogn)O(n)穩定大數據集穩定排序
快速排序O(n2)O(nlogn)O(logn)不穩定大數據集首選(性能最優)
堆排序O(nlogn)O(nlogn)O(1)不穩定無需遞歸、空間受限場景

二十二、總結與建議

  1. 簡單排序選擇
    • 小規模數據:優先使用插入排序(性能最佳,穩定)。
    • 學習用途:了解冒泡、選擇排序邏輯,但無需用于實際項目。
  2. 高級排序選擇
    • 需要穩定性:選歸并排序(如數據庫排序、物流訂單排序)。
    • 性能優先:選快速排序(默認場景,需注意基準值優化)。
    • 空間受限/禁止遞歸:選堆排序(如嵌入式系統、內核排序)。
  3. 算法實現建議
    • 必學:插入排序(簡單高效)、快速排序(工業級應用)。
    • 擴展學習:歸并排序(分治思想)、堆排序(數據結構應用)。
  4. 復雜度注意點
    • 時間復雜度是趨勢描述,O(n2) 算法在小規模下可能比 O(nlogn) 更快(如插入排序 vs 快排)。
    • 空間復雜度需關注額外堆空間(如歸并排序),棧空間(如遞歸快排)可能導致棧溢出。

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

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

相關文章

【ASR】基于分塊非自回歸模型的流式端到端語音識別

論文地址:https://arxiv.org/abs/2107.09428 摘要 非自回歸 (NAR) 模型在語音處理中越來越受到關注。 憑借最新的基于注意力的自動語音識別 (ASR) 結構,與自回歸 (AR) 模型相比,NAR 可以在僅精度略有下降的情況下實現有前景的實時因子 (RTF) 提升。 然而,識別推理需要等待…

RNN循環網絡:給AI裝上“記憶“(superior哥AI系列第5期)

&#x1f504; RNN循環網絡&#xff1a;給AI裝上"記憶"&#xff08;superior哥AI系列第5期&#xff09; 嘿&#xff01;小伙伴們&#xff0c;又見面啦&#xff01;&#x1f44b; 上期我們學會了讓AI"看懂"圖片&#xff0c;今天要給AI裝上一個更酷的技能——…

DAY41 CNN

可以看到即使在深度神經網絡情況下&#xff0c;準確率仍舊較差&#xff0c;這是因為特征沒有被有效提取----真正重要的是特征的提取和加工過程。MLP把所有的像素全部展平了&#xff08;這是全局的信息&#xff09;&#xff0c;無法布置到局部的信息&#xff0c;所以引入了卷積神…

【仿生系統】愛麗絲機器人的設想(可行性優先級較高)

非程序化、能夠根據環境和交互動態產生情感和思想&#xff0c;并以微妙、高級的方式表達出來的能力 我們不想要一個“假”的智能&#xff0c;一個僅僅通過if-else邏輯或者簡單prompt來模擬情感的機器人。您追求的是一種更深層次的、能夠學習、成長&#xff0c;并形成獨特“個性…

面向連接的運輸:TCP

目錄 TCP連接 TCP報文段結構 往返時間估計與超時 可靠數據傳輸 回退N步or超時重傳 超時間隔加倍 快速重傳 流量控制 TCP連接管理 三次握手 1. 客戶端 → 服務器&#xff1a;SYN 包 2. 服務器 → 客戶端&#xff1a;SYNACK 包 3. 客戶端 → 服務器&#xff1a;AC…

SpringAI系列 - 升級1.0.0

目錄 一、調整pom二、MessageChatMemoryAdvisor調整三、ChatMemory get方法刪除lastN參數四、QuestionAnswerAdvisor調整Spring AI發布1.0.0正式版了?? ,搞起… 一、調整pom <properties><java.version>17</java.version><spring-ai.version>

前端高頻面試題2:JavaScript/TypeScript

1.什么是類數組對象 一個擁有 length 屬性和若干索引屬性的對象就可以被稱為類數組對象&#xff0c;類數組對象和數組類似&#xff0c;但是不能調用數組的方法。常見的類數組對象有 arguments 和 DOM 方法的返回結果&#xff0c;還有一個函數也可以被看作是類數組對象&#xff…

Spring Security入門:創建第一個安全REST端點項目

項目初始化與基礎配置 創建基礎Spring Boot項目 我們首先創建一個名為ssia-ch2-ex1的空項目(該名稱與配套源碼中的示例項目保持一致)。項目需要添加以下兩個核心依賴: org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-secur…

秋招Day12 - 計算機網絡 - UDP

說說TCP和UDP的區別&#xff1f; TCP使用無邊界的字節流傳輸&#xff0c;可能發生拆包和粘包&#xff0c;接收方并不知道數據邊界&#xff1b;UDP采用數據報傳輸&#xff0c;數據報之間相互獨立&#xff0c;有邊界。 應用場景方面&#xff0c;TCP適合對數據的可靠性要求高于速…

【QQ音樂】sign簽名| data參數加密 | AES-GCM加密 | webpack (下)

1.目標 網址&#xff1a;https://y.qq.com/n/ryqq/toplist/26 我們知道了 sign P(n.data)&#xff0c;其中n.data是明文的請求參數 2.webpack生成data加密參數 那么 L(n.data)就是密文的請求參數。返回一個Promise {<pending>}&#xff0c;所以L(n.data) 是一個異步函數…

Codeforces Round 1028 (Div. 2)(A-D)

題面鏈接&#xff1a;Dashboard - Codeforces Round 1028 (Div. 2) - Codeforces A. Gellyfish and Tricolor Pansy 思路 要知道騎士如果沒了那么這個人就失去了攻擊手段&#xff0c;貪心的來說我們只需要攻擊血量少的即可&#xff0c;那么取min比較一下即可 代碼 void so…

【存儲基礎】存儲設備和服務器的關系和區別

文章目錄 1. 存儲設備和服務器的區別2. 客戶端訪問數據路徑場景1&#xff1a;經過服務器處理場景2&#xff1a;客戶端直連 3. 服務器作為"中轉站"的作用 剛開始接觸存儲的時候&#xff0c;以為數據都是存放在服務器上的&#xff0c;服務器和存儲設備是一個東西&#…

macOS 安裝 Grafana + Prometheus + Node Exporter

macOS 安裝指南&#xff1a;Grafana Prometheus Node Exporter 目錄簡介&#x1f680; 快速開始 安裝 Homebrew1. 安裝 Homebrew2. 更新 Homebrew 安裝 Node Exporter使用 Homebrew 安裝驗證 Node Exporter 安裝 Prometheus使用 Homebrew 安裝驗證安裝 安裝 Grafana使用 Home…

不可變集合類型轉換異常

記錄一個異常&#xff1a;class java.util.ImmutableCollections$ListN cannot be cast to class java.util.ArrayList (java.util.ImmutableCollections$ListN and java.util.ArrayList 文章目錄 1、原因2、解決方式一3、解決方式二4、關于不可變集合的補充4.1 JDK8和9的對比4…

【DAY37】早停策略和模型權重的保存

內容來自浙大疏錦行python打卡訓練營 浙大疏錦行 知識點&#xff1a; 過擬合的判斷&#xff1a;測試集和訓練集同步打印指標模型的保存和加載 僅保存權重保存權重和模型保存全部信息checkpoint&#xff0c;還包含訓練狀態 早停策略 作業&#xff1a; 對信貸數據集訓練后保存權…

【Zephyr 系列 3】多線程與調度機制:讓你的 MCU 同時干多件事

好的,下面是Zephyr 系列第 3 篇:聚焦 多線程與調度機制的實踐應用,繼續面向你這樣的 Ubuntu + 真板實戰開發者,代碼清晰、講解通俗、結構規范,符合 CSDN 高質量博客標準。 ??關鍵詞:Zephyr、線程調度、k_thread、k_sleep、RTOS、BluePill ??適合人群:想從裸機開發進…

實現RabbitMQ多節點集群搭建

目錄 引言 一、環境準備 二、利用虛擬機搭建 ? 三、鏡像集群配置 四、HAProxy實現負載均衡(主用虛擬機操作) 五、測試RabbitMQ集群搭建情況 引言 在現代分布式系統中&#xff0c;消息隊列&#xff08;Message Queue&#xff09;扮演著至關重要的角色,而 RabbitMQ 作為…

異步上傳石墨文件進度條前端展示記錄(采用Redis中String數據結構實現-蘇東坡版本)

昔者&#xff0c;有客臨門&#xff0c;亟需自石墨文庫中擷取卷帙若干。此等文冊&#xff0c;非止一卷&#xff0c;乃累牘連篇&#xff0c;亟需批量轉置。然吾輩慮及用戶體驗&#xff0c;當效東坡"腹有詩書氣自華"之雅意&#xff0c;使操作如行云流水&#xff0c;遂定…

Axure 基礎入門

目錄 認識產品經理 項目團隊* 基本概述 認識產品經理 A公司產品經理 B公司產品經理 C公司產品經理 D公司產品經理 產品經理工作范圍 產品經理工作流程* 產品經理的職責 產品經理的分類 產品經理能力要求 產品工具 產品體驗報告 原型設計介紹 原型設計概述 為…

零基礎學習計算機網絡編程----socket實現UDP協議

本章將會詳細的介紹如何使用 socket 實現 UDP 協議的傳送數據。有了前面基礎知識的鋪墊。對于本章的理解將會變得簡單。將會從基礎的 Serve 的初始化&#xff0c;進階到 Client 的初始化&#xff0c;以及 run。最后實現一個簡陋的小型的網絡聊天室。 目錄 1.UdpSever.h 1.1 構造…