C++ 詳細講解vector類

目錄

1. 什么是vector?

2. vector的使用

1. 構造函數---初始化

1. 默認構造函數(無參構造)

2. 填充構造函數(指定數量和初始值)

3. 范圍構造函數(通過迭代器拷貝其他容器元素)

4. 拷貝構造函數(直接拷貝另一個vector)

注意:

2.?vector成員函數的使用

1. 三種遍歷方法

2. size

3. capacity

4.?max_size

5. reserve

6. resize

7. assign

8. insert

9. find

10. sort

11. erase

3. 二維vector(重點)

1. 核心本質與優勢

2. 常見初始化方式

3. 核心操作(訪問、添加、刪除)

4. 遍歷二維?vector?

5. 注意事項

4. 總結:


1. 什么是vector?

  • vector是表示可變大小數組的序列容器。
  • 就像數組一樣,vector也采用的連續存儲空間來存儲元素。也就是意味著可以采用下標對vector的元素進行訪問,和數組一樣高效。但是又不像數組,它的大小是可以動態改變的,而且它的大小會被容器自動處理。
  • 本質講,vector使用動態分配數組來存儲它的元素。當新元素插入時候,這個數組需要被重新分配大小為了增加存儲空間。其做法是,分配一個新的數組,然后將全部元素移到這個數組。就時間而言,這是一個相對代價高的任務,因為每當一個新的元素加入到容器的時候,vector并不會每次都重新分配大小。
  • vector分配空間策略:vector會分配一些額外的空間以適應可能的增長,因為存儲空間比實際需要的存儲空間更大。不同的庫采用不同的策略權衡空間的使用和重新分配。但是無論如何,重新分配都應該是對數增長的間隔大小,以至于在末尾插入一個元素的時候是在常數時間的復雜度完成的。
  • 因此,vector占用了更多的存儲空間,為了獲得管理存儲空間的能力,并且以一種有效的方式動態增長。
  • 與其它動態序列容器相比(deques, lists and forward_lists), vector在訪問元素的時候更加高效,在末尾添加和刪除元素相對高效。對于其它不在末尾的刪除和插入操作,效率更低。比起lists和forward_lists統一的迭代器和引用更好。

2. vector的使用

我們先來看一下C++官方文檔中對vector成員函數的一些介紹 :?vector文檔

1. 構造函數---初始化

圖中詳細列出了?std::vector?的4種構造方式:

  1. 默認構造函數:創建空容器,無元素。
  2. 填充構造函數:創建包含?n?個元素的容器,每個元素都是?val?的副本。
  3. 范圍構造函數:用迭代器范圍?[first, last)?內的元素初始化容器。
  4. 拷貝構造函數:復制另一個?vector???x?的所有元素來初始化容器。

1. 默認構造函數(無參構造)

  • 作用:創建一個空的vector容器,不包含任何元素,內部數組(動態內存)未分配或僅分配最小默認空間。
  • 示例:?
    std::vector<int> vec;?(此時vec.empty()為?true , vec.size()?為0)。
  • 核心特點:極簡初始化,適合后續通過?push_back()?、?assign()?等方法動態添加元素的場景。

2. 填充構造函數(指定數量和初始值)

  • 作用:創建一個包含固定數量(n個)元素的vector,且所有元素都初始化為同一個值(?val?的副本,若不指定?val?,內置類型默認初始化,如int為0)。
  • 示例:
    std::vector<int> vec(5, 10);?(創建含5個元素的vector,每個元素都是10)。
    std::vector<int> vec(5);    ?(創建含5個元素的vector,每個元素默認初始化為0)。
  • 核心特點:一次性初始化“批量相同值”的元素,避免后續逐個賦值,適合已知元素數量和統一初始值的場景(如創建固定長度的初始數組)。

3. 范圍構造函數(通過迭代器拷貝其他容器元素)

  • 作用:從其他容器(如vector、array、list等)的指定迭代器范圍?[first, last)??中,拷貝元素來初始化當前vector(左閉右開,即包含?first?指向的元素,不包含?last?指向的元素)。
  • 示例:??
  • std::vector<int> src = {1,2,3,4};
    std::vector<int> vec(src.begin(), src.end()); // 拷貝src所有元素,vec變為{1,2,3,4}
    std::vector<int> vec2(src.begin()+1, src.end()-1); // 拷貝src的[2,3],vec2變為{2,3}

  • 核心特點:靈活復用其他容器的“部分或全部元素”,無需手動逐個拷貝,適合需要基于現有容器子集/全集創建新vector的場景。

4. 拷貝構造函數(直接拷貝另一個vector)

  • 作用:創建一個完全復制另一個vector(?x?) 的新vector,新vector的元素、大小、容量(通常)與原vector完全一致。
  • 示例:
  • std::vector<int> src = {1,2,3};
    std::vector<int> vec(src); // 拷貝src,vec與src完全相同
    std::vector<int> vec2 = src; // 等價于上一行,拷貝構造的另一種寫法

  • 核心特點:專門用于“復制已有vector”,是C++默認的“值拷貝”語義體現,適合需要創建原vector副本(獨立于原vector,修改新vector不影響原vector)的場景。

注意:

  • 可以看到第三個迭代器構造函數是一個模板函數,所以不一定只用vector的迭代器,也可以用其他容器迭代器初始化,只要數據類型匹配(*iterator對象的類型跟vector中存的數據類型是一致的):
  • 迭代器進行初始化模板函數實際是這樣實現的:
// template <class InputIterator> 表明這是模板函數,InputIterator是迭代器類型參數
template <class InputIterator>
vector(InputIterator first, InputIterator last) {// 函數體內通過迭代器的通用操作(++、* 解引用)遍歷序列,無需關心具體迭代器類型while (first != last) {push_back(*first); // *first 取迭代器指向的元素++first; // 迭代器向后移動}
}
  • 我們定義下面兩個對象有沒有差別?
string s("111111");
vector<char> vc(6,'1');  //調用構造函數
  • 答 : 不能,vector里面給char,雖然它們底層都是數組中存char類型數據,但是還是不一樣的,s對象中指向的空間結尾有\0,string的很多操作是獨有的,比如+=字符串等等

2.?vector成員函數的使用

1. 三種遍歷方法

上面知道了vector類對象如何初始化,那么我們想要遍歷該對象該怎么遍歷呢?

首先使用push_back尾插進去數據,遍歷方法:

  1. 下標+[]
  2. 迭代器遍歷
  3. 范圍for遍歷
#include<iostream>
#include<vector>
using namespace std;
void test_vector()
{vector<int> v;//使用push_back尾插數據v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//遍歷vector//1、下標+[]for(size_t i =0;i<v.size(),i++){v[i]-=1;cout<<v[i]<<" ";}cout<<endl;//2、迭代器vector<int>::iterator it = v.begin();while(it!=v.end()){*it += 1;cout<<*it<<" ";++it;}cout<<endl;//范圍forfor(auto e:v){cout<< e <<" ";}cout<<endl;
}
int main()
{test_vector();return 0;
}

我們還可以利用反向迭代器進行反向遍歷:

void test_vector()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//反向迭代器進行遍歷vector<int>::reverse_iterator rit = v.rbegin();while(rit!=v.rend()){cout<<*rit<<" ";++rit;}cout<<endl;
}

這里的rit不是原生指針,而是被封裝的類對象,重載operator++才能實現++rit時,倒著走 , 而非原生質真的直接操作。

2. size

  • size ?函數是用于獲取容器中當前元素個數的核心接口
  • 返回 vector ?中實際存儲的元素數量,類型為 size_t (無符號整數)。
vector<int> v = {1,2,3};
size_t count = v.size();  // count = 3

3. capacity

capacity ?是 std::vector ?的一個重要屬性,它表示當前分配的內存能夠容納的最大元素個數(即不重新分配內存時,最多能存多少元素)。而 size ?是當前實際存儲的元素個數。

vector<int> v;
v.push_back(1);
v.push_back(2);
// 此時 size 是 2,capacity 可能是 2、4 或其他(由編譯器和標準庫實現決定,通常會預分配多于當前元素數的內存以減少擴容次數)
  • 當 size ?超過 capacity ?時, vector ?會自動擴容(重新分配更大的內存塊,復制原有元素,釋放舊內存),這也是 vector ?動態增長的底層機制。可以通過 vector ?的 capacity() ?函數來獲取這個值。

4.?max_size

返回vector可以容納的最大元素數。實際中并沒有什么意義

void test_vector()
{vector<int> v;cout<<v.max_size()<<endl;//沒什么意義v.reserve(10);//開空間,改變容量
}

5. reserve

功能 : 主動為?vector?預分配內存,確保其?capacity?(容量)至少達到指定大小,不改變?size?(實際元素個數)。避免多次自動擴容(擴容會復制元素、釋放舊內存,耗時),適合已知元素大致數量時提升效率。若?n?≤當前?capacity?,函數不做任何操作;只增容,不縮容(縮容需用?shrink_to_fit()?)。

vector<int> vec;
vec.reserve(100); // 預分配能存100個int的內存,此時size=0,capacity≥100
for (int i=0; i<100; ++i) 
{vec.push_back(i); // 因已預分配,這100次插入不會觸發自動擴容
}

6. resize

改變這個vector對象的長度為n,如果n小于當前vector的長度,則將當前值縮短到第n個數據,刪除第n個以外的數據。如果n大于當前vector對象長度,延長該vector對象長度,并在最后插入指定內容直到達到的延長后的長度n。如果指定值, 用該值來初始化,否則,他們初始化為匿名對象。

vector<int> v = {1,2,3};// 場景1:n > size → 新增元素,值為0(int的默認值)
v.resize(5); // 現在v的size是5,元素為[1,2,3,0,0]// 場景2:n > size 且指定默認值
v.resize(7, 99); // 元素變為[1,2,3,0,0,99,99]// 場景3:n < size → 銷毀末尾元素
v.resize(2); // 元素變為[1,2],capacity仍保持擴容后的大小(如7)

7. assign

分配新的內容給vector,代替它當前的內容,并且修改它的大小。可以看到assign函數的參數可以是迭代器,也可以是val個數和val

vector<int> v = {1,2,3};// 示例1:范圍賦值(從其他容器/數組批量賦值)
list<int> lst = {4,5,6};
v.assign(lst.begin(), lst.end()); // v變為[4,5,6]// 示例2:重復賦值(填充n個相同元素)
v.assign(3, 99); // v變為[99,99,99]

8. insert

用于在指定位置插入元素的核心接口,支持單個元素、多個元素或范圍元素的插入,在容器的指定位置插入元素,插入后容器 ?size??增加,若空間不足會觸發擴容。

調用格式(三種重載):
插入單個元素:?

iterator insert(iterator pos, const T& val);?(pos是插入位置的迭代器,val是要插入的元素)。

插入多個相同元素:

?iterator insert(iterator pos, size_t n, const T& val);?(n是插入個數)

插入范圍元素:

iterator insert(iterator pos, InputIterator first, InputIterator last);(?first/last是迭代器范圍)

插入位置的后續元素會向后移動(若空間不足,先擴容再移動,移動過程有性能開銷)。
返回值是指向第一個插入元素的迭代器,可用于后續操作。

vector<int> v = {1,3,4};// 示例1:插入單個元素
auto it = v.insert(v.begin() + 1, 2); // 在索引1的位置插入2,v變為[1,2,3,4]// 示例2:插入多個相同元素
v.insert(v.end(), 2, 5); // 在末尾插入2個5,v變為[1,2,3,4,5,5]// 示例3:插入范圍元素
list<int> lst = {6,7};
v.insert(v.begin(), lst.begin(), lst.end()); // 在開頭插入lst的元素,v變為[6,7,1,2,3,4,5,5]

那么我們假設想在3的前面插入呢?我們想一想我們肯定先需要找到3這個元素,才能在它前面插入元素,而我們發現vector當中沒有find函數,但是在算法里面有一個find函數模板以提供使用:

9. find

find函數參數是迭代器區間以及需要找到的val值,返回的是這段區間第一次發現的元素的迭代器,如果沒有發現則返回的是last,我們想要在3之前插入元素數據20:

void test_vector5()
{int a[] = { 1,3,4 };vector<int> v(a, a + 3);vector<int>::iterator pos = find(v.begin(),v.end(),3);if(pos!= v.end()){v.insert(pos,20);}for(auto e:v){cout<< e <<" ";}cout<<endl;
}

輸出:

1 20 3 4

10. sort

在算法模塊還有一個函數便于我們使用:sort函數

核心參數傳遞的就是迭代器,且明確要求是隨機訪問迭代器

void test_vector6()
{int a[] = { 1,2,3,4,5 };vector<int> v(a, a + 5);//默認排升序sort(v.begin(),v.end());
}

我們還可以用sort對數組進行排序:

void test_vector6()
{//指向數組的空間的指針是天然的迭代器int a1[]={30,1,13,23,42};sort(a1,a1+5);//也可以對數組排序for(auto e:a1){cout<< e <<" ";}cout<<endl;
}

指向數組的空間的指針是天然的迭代器,故也是可以對數組進行排序的

11. erase

erase??是用于從容器中刪除指定元素或元素范圍的核心接口,刪除后容器 ?size??減小,剩余元素會自動前移,但不會自動縮減內存容量(?capacity??不變)。

erase??有兩種主要重載形式,均通過迭代器指定刪除范圍:
1. 刪除單個元素

?iterator erase(iterator pos);?pos?:指向要刪除元素的有效迭代器(不能是 ?end()?)。

返回值:指向被刪除元素下一個元素的迭代器(用于避免迭代器失效)。
2. 刪除元素范圍

?iterator erase(iterator first, iterator last);?first?/?last?:指定刪除范圍[first, last)(左閉右開,包含first指向的元素,不包含last指向的元素)。

返回值:指向范圍 ?[first, last)??之后第一個元素的迭代器。

#include <vector>
#include <iostream>int main() {std::vector<int> v = {1, 2, 3, 4, 5};// 示例1:刪除單個元素(刪除值為3的元素)auto it = v.begin() + 2; // 指向元素3it = v.erase(it); // 刪除后,it指向元素4,v變為 [1,2,4,5]// 示例2:刪除元素范圍(刪除從it開始到末尾的元素)v.erase(it, v.end()); // 刪除4、5,v變為 [1,2]// 示例3:釋放多余內存(size=2,capacity可能大于2)v.shrink_to_fit(); // 可選,將capacity縮減至與size一致return 0;
}

3. 二維vector(重點)

C++ 中的二維vector :(vector<vector<T>>)

二維 vector?本質是“元素類型為 ?vector??的 ?vector?”,可理解為“動態二維數組”,其每行長度可獨立變化(非嚴格矩形,也叫“鋸齒數組”),核心特性和用法如下:

1. 核心本質與優勢

  1. 本質:外層 ?vector??存儲的每個元素,都是一個獨立的內層 ?vector?(即“一行”數據)。
  2. 優勢:
  3. 動態大小:無需預先指定行數和列數,可隨時添加/刪除行、擴展每行的列數。
  4. 靈活性:每行長度可不同(如第一行3個元素,第二行5個元素),適合不規則數據。
  5. 內存安全:自動管理內存,無需手動釋放,避免數組越界和內存泄漏。

2. 常見初始化方式

(1) 直接初始化(指定行數和每行列數)
適用于創建“矩形二維數組”(每行長度相同):

#include <vector>
using namespace std;// 方式1:初始化3行4列,所有元素默認值(int默認0,string默認空串)
vector<vector<int>> vec1(3, vector<int>(4));?// 方式2:初始化2行3列,所有元素指定為10
vector<vector<int>> vec2(2, vector<int>(3, 10));?
// 結果:vec2 = [[10,10,10], [10,10,10]]

(2) 列表初始化(自定義每行元素)
適用于不規則或已知具體數據的場景:

// 方式1:初始化3行,每行長度分別為2、3、1
vector<vector<int>> vec = {{1, 2}, ? ?// 第0行{3, 4, 5}, // 第1行{6} ? ? ? ?// 第2行
};// 方式2:先創建空外層vector,再逐個添加行
vector<vector<int>> vec2;
vec2.push_back({10, 20}); // 添加第0行
vec2.push_back({30}); ? ? // 添加第1行
// 結果:vec2 = [[10,20], [30]]

3. 核心操作(訪問、添加、刪除)

(1) 訪問元素
通過“外層索引[行號] + 內層索引[列號]”訪問,與普通二維數組語法一致:

vector<vector<int>> vec = {{1,2}, {3,4,5}};
int a = vec[0][1]; // 訪問第0行第1列,a = 2
int b = vec[1][2]; // 訪問第1行第2列,b = 5// 推薦:用 at() 訪問(會做越界檢查,更安全)
int c = vec.at(0).at(1); // 效果同上,越界時拋異常

(2) 添加元素

  • 添加一行:用 ?push_back()??直接添加一個內層 ?vector??作為新行。
  • 添加一列(擴展某行):通過外層 ?vector??的索引找到目標行,再用 ?push_back()??給該行添加元素。
vector<vector<int>> vec = {{1,2}, {3,4}};// 1. 添加新行
vec.push_back({5,6,7}); // 結果:[[1,2], [3,4], [5,6,7]]// 2. 給第0行添加一個元素(擴展列)
vec[0].push_back(8); // 結果:[[1,2,8], [3,4], [5,6,7]]

(3)刪除元素

  • 刪除最后一行:外層 ?vector??調用 ?pop_back()?。
  • 刪除某一行:外層 ?vector??調用 ?erase()?,通過迭代器指定行。
  • 刪除某行的某個元素:找到目標行,調用該行(內層 ?vector?)的 ?erase()?。
vector<vector<int>> vec = {{1,2,8}, {3,4}, {5,6,7}};// 1. 刪除最后一行
vec.pop_back(); // 結果:[[1,2,8], [3,4]]// 2. 刪除第0行(通過迭代器)
vec.erase(vec.begin()); // 結果:[[3,4]]// 3. 給第0行刪除第1個元素(列)
vec[0].erase(vec[0].begin() + 1); // 結果:[[3]]

4. 遍歷二維?vector?

(1) 普通 ?for??循環(依賴索引)

vector<vector<int>> vec = {{1,2}, {3,4,5}};
// 外層循環遍歷行,內層循環遍歷每行的列
for (int i = 0; i < vec.size(); ++i) 
{   // vec.size() 是行數for (int j = 0; j < vec[i].size(); ++j) { // vec[i].size() 是第i行的列數cout << vec[i][j] << " ";}cout << endl;
}

(2) 范圍 ?for??循環(更簡潔)

for (auto& row : vec) 
{          // 遍歷每一行(用引用避免拷貝)for (auto& elem : row) {      // 遍歷當前行的每個元素cout << elem << " ";}cout << endl;
}

5. 注意事項

  • ?內存連續性:與普通二維數組(內存連續)不同,二維 ?vector??的每行(內層 ?vector?)是獨立的內存塊,整體內存不連續,訪問效率略低于普通二維數組。
  • 行長度一致性:若需嚴格的“矩形二維數組”,需手動保證每行 ?size??相同(可封裝函數檢查或初始化時統一設置)。
  • 性能優化:頻繁添加行時,可先給外層 ?vector??用 ?reserve(n)??預分配行數;頻繁擴展某行時,給對應內層 ?vector??預分配列數,減少擴容開銷。

典型使用場景:

  • 存儲不規則數據(如每行元素個數不同的表格、稀疏矩陣)。
  • 動態調整大小的場景(如刷題時不確定輸入數據的行數和列數)。
  • 作為函數參數傳遞(需注意傳遞方式,推薦用引用 ?const vector<vector<T>>&??避免拷貝)。

4. 總結:

本文介紹了C++中vector容器的基本概念和使用方法。vector是可變大小的序列容器,采用連續存儲空間,支持高效隨機訪問和動態增長。文章詳細講解了vector的四種構造方式、常用成員函數(如size、capacity、resize、assign等)、遍歷方法(下標、迭代器、范圍for)以及二維vector的使用。重點內容包括:vector的動態擴容機制、元素訪問和修改操作、二維vector的初始化和遍歷(支持不規則數據結構)。vector相比數組和鏈表在隨機訪問和尾部操作上更高效,但在中間插入刪除時性能較低,適合需要頻繁訪問和動態調整大小的場景。

感謝大家的觀看!

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

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

相關文章

Windows Server2012 R2 安裝.NET Framework 3.5

Windows Server2012 R2 安裝.NET Framework 3.5 虛擬機系統是Windowsserver 2012R2&#xff0c;在安裝SQlserver2012時候警告未安裝.NET Framework 3.5。于是找了個.NET Framework 3.5的安裝包&#xff0c;但是由于系統原因無法正常安裝。按照提示從控制面板-程序-啟動或關閉Wi…

IDEA中Transaction翻譯插件無法使用,重新配置Transaction插件方法

原因 由于Transaction默認的翻譯引擎為谷歌翻譯&#xff0c;由于一些原因&#xff0c;這個翻譯無法使用&#xff0c;因此導致插件無法使用。 解決辦法 更換Transaction插件翻譯引擎即可。 方法步驟 1.進入Idea的設置里&#xff0c;找到Tool下的Transaction選項2.更改翻譯引擎&a…

外置flash提示音打包腳本

批處理腳本說明文檔 - 音頻資源打包與分發 一、腳本功能概述 本批處理腳本&#xff08;.bat 文件&#xff09;用于將指定目錄下的多個音頻文件&#xff08;.wtg 和 .mp3 格式&#xff09;打包為音頻資源配置文件&#xff08;tone.cfg&#xff09;&#xff0c;進一步將配置文件與…

Go語言設計模式(三)抽象工廠模式

抽象工廠模式與工廠模式類似,被認為是工廠方法模式的另一層抽象.抽象工廠模式圍繞創建其他工廠的超級工廠工作.1.角色:1.1抽象產品:構成產品系列的一組不同但相關的產品的聲明接口.1.2具體產品:實現抽象產品接口的類,主要用于定義產品對象,由相應的具體工廠創建.1.3抽象工廠:創…

大狗王 DG1+ 13.6G礦機詳細參數解析與性能評測

近年來&#xff0c;隨著加密貨幣挖礦行業的不斷發展&#xff0c;越來越多的礦機廠商推出了高性能、低功耗的礦機設備。大狗王&#xff08;DG1&#xff09;13.6G礦機便是其中一款備受關注的設備&#xff0c;特別是在LTC&#xff08;萊特幣&#xff09;、Doge&#xff08;狗狗幣&…

Python 算術運算練習題

計算數字特征值題目描述 編寫一個程序&#xff0c;接收用戶輸入的兩個整數 a 和 b&#xff08;a > b > 0&#xff09;&#xff0c;計算并輸出以下結果&#xff1a;a 與 b 的和的平方a 除以 b 的商和余數a 與 b 的平均數&#xff08;保留 2 位小數&#xff09;示例請輸入整…

OS項目構建效能改進策劃方案

一、現狀分析與問題定位構建穩定性問題&#xff1a; 表現&#xff1a;非代碼變更引發的構建失敗&#xff08;如環境依賴、工具鏈版本、第三方庫更新、資源競爭等&#xff09;“幽靈構建”時有發生。影響&#xff1a;嚴重破壞開發流程的順暢性&#xff0c;耗費大量開發/測試人員…

Ai8051 2.4寸320*240 ILI9341 I8080接口驅動

/*---------------------------------------------------------------------*/ /* --- Web: www.STCAI.com ---------------------------------------------*/ /* 液晶屏驅動程序參考wiki技術網站提供的開源源碼&#xff0c;僅供學習使用 */ /*----------------------…

最大似然估計:損失函數的底層數學原理

引言當你第一次看到線性回歸時&#xff0c;你是否注意到了作為參數優化關鍵的損失函數&#xff08;均方損失&#xff09;&#xff0c;你是否能夠理解它的本質和由來。其實&#xff0c;在我第一次接觸時&#xff0c;我是感到有些驚訝的&#xff0c;然后試著去強行理解它&#xf…

使用 n8n 結合通義千問大模型構建業務數據庫分析智能體

一、項目概述 本項目致力于構建一個結合 n8n 工作流引擎 與 通義千問大模型 的智能體&#xff0c;旨在對龐大的業務數據庫進行自動化分析、語義建模及自然語言問答。通過不同工作流的迭代構建&#xff0c;實現了表結構解析、業務含義提取、關系可視化、問答服務等能力&#xff…

css margin外邊距重疊/塌陷問題

一、定義 相鄰塊級元素或父子元素的垂直外邊距會合并&#xff08;折疊&#xff09;為單個邊距&#xff0c;其大小為單個邊距的最大值&#xff08;或如果他們相等&#xff0c;則僅為其中的一個&#xff09;&#xff0c;這種行為稱為邊距折疊 <div style"margin-bottom: …

可重復讀 是否“100%”地解決幻讀?

這是一個非常深刻的問題&#xff0c;答案是&#xff1a;幾乎解決了&#xff0c;但在一個非常特殊且罕見的邊界場景下&#xff0c;理論上仍然可能出現幻讀。 因此&#xff0c;嚴格來說&#xff0c;它并非被“徹底”或“100%”地解決。下面我們來詳細分解這個結論&#xff1a;1. …

從零開始的云計算生活——第五十八天,全力以赴,Jenkins部署

目錄 一.故事背景 二.安裝Jenkins必要插件 1.安裝Publish Over SSH 2.安裝maven integration插件 3. 配置jenkins并發執行數量 4. 配置郵件地址 三. 基于Jenkins部署PHP環境 1. 下載ansible插件 2. 下載ansible應用 3. 構建項目 ?編輯 使用Jenkins賬戶生成ssh密鑰 …

串口HAL庫發送問題

想了很久&#xff0c;不知道該標題起的是否合適&#xff0c;該篇Blog用于記錄在使用HAL庫的USART模塊時實際遇到的一個涉及發送方式的問題&#xff0c;用于提醒自身同時也希望能幫到各位。程序問題敘述先來看一段代碼&#xff1a;void CusUSART_SendByte_IT( uint8_t Byte ) { …

CUDA默認流的同步行為

默認流 對于需要指定 cudaStream_t參數的 cuda API&#xff0c;如果將 0作為實參傳入&#xff0c;則視為使用默認流&#xff1b;對于不需要指定 cudaStream_t參數的 cuda API&#xff0c;則也視為使用默認流。 在 cuda中&#xff0c;默認流有兩種類型&#xff0c;一種是 legacy…

「數據獲取」《中國電力統計年鑒》(1993-2024)(含中國電力年鑒)

01、數據簡介一、《中國電力統計年鑒》作為全面系統反映中國電力領域發展狀況的權威性年度統計資料&#xff0c;涵蓋了電力建設、生產、消費及供需等全鏈條關鍵信息。其編制工作有著深厚的歷史積淀&#xff0c;可追溯至 20 世紀 50 年代&#xff0c;歷經數十年的積累與完善&…

《AI大模型應知應會100篇》第68篇:移動應用中的大模型功能開發 —— 用 React Native 打造你的語音筆記摘要 App

&#x1f4f1; 第68篇&#xff1a;移動應用中的大模型功能開發 —— 用 React Native 打造你的語音筆記摘要 App &#x1f3af; 核心目標&#xff1a;零門檻集成大模型&#xff0c;5步開發跨平臺智能功能 &#x1f9e9; 適用人群&#xff1a;前端開發者、產品經理、獨立開發者 …

FPGA ad9248驅動

ad9248的最高時鐘頻率65mhz&#xff0c;采用cmos3.3v電壓的并行io接口&#xff0c;做成電子模塊后一般為雙通道adc&#xff0c;有兩個對外輸出時鐘cha_clk與chb_clk&#xff0c;一個并行輸入端口&#xff0c;14分辨率的ddr_data&#xff0c;其模塊邏輯如下&#xff0c;首先向ad…

Spring MVC 處理請求的流程

Spring MVC 處理請求的流程流程步驟詳解第1步&#xff1a;發起請求 (HTTP Request)第2步&#xff1a;映射處理器 (Handler Mapping)第3步&#xff1a;獲取適配器 (Handler Adapter)第4步&#xff1a;執行攔截器前置處理 (Interceptors - preHandle)第5步&#xff1a;真正調用處…

敏捷scrum管理實戰經驗總結

1.敏捷 敏捷的構成 敏捷由實踐來源、應用場景、組織文化、領導力、團隊、需求、管理、技術、質量、度量、交付、過程改進、大型項目組合管理以及受監管行業中的敏捷等構成 敏捷開發的特點 短發布周期小批量的方式、開展從需求到實現的開發工作高層級的預先規劃結合詳細的即時規…