【C++】STL性能優化實戰

STL性能優化實戰

STL (Standard Template Library) 是 C++ 標準庫的核心部分,提供了各種容器、算法和迭代器。雖然 STL 提供了強大的功能,但不恰當的使用可能導致性能問題。下面我將詳細介紹 STL 性能優化的實戰技巧,并通過具體案例說明。

1. 容器選擇優化

不同的 STL 容器有不同的性能特性,選擇合適的容器對性能影響很大。

案例:從 std::liststd::vector

// 優化前:使用list存儲大量數據并頻繁隨機訪問
std::list<int> dataList;
for (int i = 0; i < 1000000; i++) {dataList.push_back(i);
}// 查找第500000個元素
auto it = dataList.begin();
std::advance(it, 500000); // O(n)操作,非常慢
int value = *it;// 優化后:使用vector
std::vector<int> dataVector;
dataVector.reserve(1000000); // 預分配內存,避免多次重新分配
for (int i = 0; i < 1000000; i++) {dataVector.push_back(i);
}// 查找第500000個元素,O(1)操作
int value = dataVector[500000];

性能差異:在百萬級數據上,vector 的隨機訪問可能比 list 快數百倍。

2. 內存管理優化

預分配內存

// 優化前
std::vector<int> v;
for (int i = 0; i < 100000; i++) {v.push_back(i); // 可能導致多次重新分配內存
}// 優化后
std::vector<int> v;
v.reserve(100000); // 預先分配足夠的內存
for (int i = 0; i < 100000; i++) {v.push_back(i); // 不再需要重新分配內存
}

案例:大型應用中的內存優化

class DataProcessor {
private:std::vector<double> data;std::vector<int> indices;public:// 優化前void processData(const std::vector<double>& input) {// 每次處理都重新分配內存data.clear();indices.clear();for (size_t i = 0; i < input.size(); i++) {if (input[i] > 0) {data.push_back(input[i]);indices.push_back(i);}}}// 優化后void processDataOptimized(const std::vector<double>& input) {// 估計可能的大小并預分配data.clear();indices.clear();data.reserve(input.size() / 2);  // 假設約一半的元素符合條件indices.reserve(input.size() / 2);for (size_t i = 0; i < input.size(); i++) {if (input[i] > 0) {data.push_back(input[i]);indices.push_back(i);}}// 釋放多余容量data.shrink_to_fit();indices.shrink_to_fit();}
};

3. 迭代器和算法優化

使用合適的算法

std::vector<int> v(1000000);
// 填充數據...// 優化前:手動查找
int target = 42;
bool found = false;
for (auto it = v.begin(); it != v.end(); ++it) {if (*it == target) {found = true;break;}
}// 優化后:使用STL算法
bool found = std::find(v.begin(), v.end(), target) != v.end();// 更優化:如果容器已排序
std::sort(v.begin(), v.end()); // 先排序
bool found = std::binary_search(v.begin(), v.end(), target); // 二分查找,O(log n)

案例:數據分析應用中的算法優化

class DataAnalyzer {
private:std::vector<double> dataset;public:// 優化前:手動實現統計計算std::pair<double, double> calculateMeanAndStdDev() {double sum = 0.0;for (const auto& value : dataset) {sum += value;}double mean = sum / dataset.size();double sumSquaredDiff = 0.0;for (const auto& value : dataset) {double diff = value - mean;sumSquaredDiff += diff * diff;}double stdDev = std::sqrt(sumSquaredDiff / dataset.size());return {mean, stdDev};}// 優化后:使用STL算法std::pair<double, double> calculateMeanAndStdDevOptimized() {double sum = std::accumulate(dataset.begin(), dataset.end(), 0.0);double mean = sum / dataset.size();double sumSquaredDiff = std::transform_reduce(dataset.begin(), dataset.end(),0.0,std::plus<>(),[mean](double value) { return std::pow(value - mean, 2); });double stdDev = std::sqrt(sumSquaredDiff / dataset.size());return {mean, stdDev};}
};

4. 避免不必要的拷貝

使用引用和移動語義

// 優化前:傳值和返回值導致多次拷貝
std::vector<int> processData(std::vector<int> data) {std::vector<int> result;// 處理數據...return result;
}// 優化后:使用引用和移動語義
std::vector<int> processDataOptimized(const std::vector<int>& data) {std::vector<int> result;// 處理數據...return std::move(result); // 使用移動語義
}// 調用方式優化
std::vector<int> input = {1, 2, 3, 4, 5};
// 優化前
auto result1 = processData(input); // 拷貝input// 優化后
auto result2 = processDataOptimized(input); // 使用引用,避免拷貝

案例:大型文本處理應用

class TextProcessor {
private:std::vector<std::string> documents;public:// 優化前void addDocument(std::string doc) {documents.push_back(doc); // 拷貝doc}std::vector<std::string> findMatchingDocuments(std::string pattern) {std::vector<std::string> matches;for (const auto& doc : documents) {if (doc.find(pattern) != std::string::npos) {matches.push_back(doc); // 拷貝doc}}return matches; // 拷貝整個matches}// 優化后void addDocumentOptimized(std::string&& doc) {documents.push_back(std::move(doc)); // 移動doc,避免拷貝}std::vector<std::string> findMatchingDocumentsOptimized(const std::string& pattern) {std::vector<std::string> matches;matches.reserve(documents.size() / 10); // 預估匹配數量for (const auto& doc : documents) {if (doc.find(pattern) != std::string::npos) {matches.push_back(doc); // 仍然是拷貝,但預分配了內存}}return std::move(matches); // 移動返回,避免拷貝}
};

5. 使用 emplace 系列函數

struct ComplexObject {std::string name;int id;std::vector<double> data;ComplexObject(std::string n, int i, std::vector<double> d): name(std::move(n)), id(i), data(std::move(d)) {}
};// 優化前
std::vector<ComplexObject> objects;
std::string name = "Object1";
int id = 42;
std::vector<double> data = {1.0, 2.0, 3.0};
objects.push_back(ComplexObject(name, id, data)); // 構造臨時對象然后拷貝/移動// 優化后
objects.emplace_back(name, id, data); // 直接在容器內構造對象,避免臨時對象

案例:游戲引擎中的實體管理

class EntityManager {
private:std::vector<Entity> entities;std::unordered_map<std::string, Entity*> entityMap;public:// 優化前void addEntity(const std::string& name, int health, const Position& pos) {Entity entity(name, health, pos);entities.push_back(entity);entityMap[name] = &entities.back();}// 優化后void addEntityOptimized(std::string name, int health, Position pos) {entities.emplace_back(std::move(name), health, std::move(pos));Entity& entity = entities.back();entityMap.emplace(entity.getName(), &entity);}
};

6. 使用正確的查找方法

案例:頻繁查找操作的優化

// 場景:需要頻繁查找元素
// 優化前:使用vector和find算法
std::vector<int> data = {/* 大量數據 */};
bool exists = std::find(data.begin(), data.end(), target) != data.end(); // O(n)// 優化方案1:如果數據已排序,使用binary_search
std::sort(data.begin(), data.end()); // 一次性排序
bool exists = std::binary_search(data.begin(), data.end(), target); // O(log n)// 優化方案2:如果需要頻繁查找,使用unordered_set
std::unordered_set<int> dataSet(data.begin(), data.end());
bool exists = dataSet.find(target) != dataSet.end(); // 平均O(1)

實際應用:網絡包過濾器

class PacketFilter {
private:// 優化前:使用vector存儲IP黑名單std::vector<std::string> blacklistedIPs;// 優化后:使用unordered_set存儲IP黑名單std::unordered_set<std::string> blacklistedIPSet;public:// 優化前bool isBlacklisted(const std::string& ip) {return std::find(blacklistedIPs.begin(), blacklistedIPs.end(), ip) != blacklistedIPs.end();// 時間復雜度:O(n),n為黑名單大小}// 優化后bool isBlacklistedOptimized(const std::string& ip) {return blacklistedIPSet.find(ip) != blacklistedIPSet.end();// 時間復雜度:平均O(1)}// 初始化函數void initialize(const std::vector<std::string>& ips) {// 優化前blacklistedIPs = ips;// 優化后blacklistedIPSet.clear();blacklistedIPSet.reserve(ips.size());for (const auto& ip : ips) {blacklistedIPSet.insert(ip);}}
};

7. 自定義比較和哈希函數

案例:復雜對象的高效存儲和查找

struct Customer {std::string id;std::string name;std::string address;// 其他字段...bool operator==(const Customer& other) const {return id == other.id; // 只比較ID}
};// 自定義哈希函數
namespace std {template<>struct hash<Customer> {size_t operator()(const Customer& c) const {return hash<std::string>()(c.id); // 只哈希ID}};
}// 使用自定義哈希的容器
std::unordered_set<Customer> customers;
std::unordered_map<Customer, int> customerScores;

實際應用:緩存系統

class CacheSystem {
private:struct CacheKey {std::string resource;std::string version;std::string locale;bool operator==(const CacheKey& other) const {return resource == other.resource && version == other.version && locale == other.locale;}};struct CacheKeyHash {size_t operator()(const CacheKey& key) const {// 組合哈希size_t h1 = std::hash<std::string>()(key.resource);size_t h2 = std::hash<std::string>()(key.version);size_t h3 = std::hash<std::string>()(key.locale);return h1 ^ (h2 << 1) ^ (h3 << 2);}};// 使用自定義鍵和哈希函數的緩存std::unordered_map<CacheKey, std::vector<char>, CacheKeyHash> cache;public:void store(const std::string& resource, const std::string& version, const std::string& locale, const std::vector<char>& data) {CacheKey key{resource, version, locale};cache[key] = data;}bool retrieve(const std::string& resource, const std::string& version,const std::string& locale, std::vector<char>& outData) {CacheKey key{resource, version, locale};auto it = cache.find(key);if (it != cache.end()) {outData = it->second;return true;}return false;}
};

8. 并行算法優化

C++17 引入了并行算法,可以顯著提高性能。

#include <execution>
#include <algorithm>
#include <vector>std::vector<int> data(10000000);
// 填充數據...// 優化前:單線程排序
std::sort(data.begin(), data.end());// 優化后:并行排序
std::sort(std::execution::par, data.begin(), data.end());// 其他并行算法示例
std::for_each(std::execution::par, data.begin(), data.end(), [](int& x) { x *= 2; });
auto sum = std::reduce(std::execution::par, data.begin(), data.end(), 0);

案例:圖像處理應用

class ImageProcessor {
private:std::vector<Pixel> imageData; // 假設Pixel是一個表示像素的結構體int width, height;public:// 優化前:單線程處理void applyFilter(const Filter& filter) {for (auto& pixel : imageData) {pixel = filter.process(pixel);}}// 優化后:并行處理void applyFilterParallel(const Filter& filter) {std::for_each(std::execution::par,imageData.begin(),imageData.end(),[&filter](Pixel& pixel) {pixel = filter.process(pixel);});}// 優化前:單線程邊緣檢測std::vector<Edge> detectEdges() {std::vector<Edge> edges;// 復雜的邊緣檢測算法...return edges;}// 優化后:分塊并行邊緣檢測std::vector<Edge> detectEdgesParallel() {// 將圖像分成多個塊const int blockSize = height / std::thread::hardware_concurrency();std::vector<std::vector<Edge>> blockEdges(std::thread::hardware_concurrency());std::vector<std::thread> threads;for (int i = 0; i < std::thread::hardware_concurrency(); ++i) {threads.emplace_back([this, i, blockSize, &blockEdges]() {int startY = i * blockSize;int endY = (i == std::thread::hardware_concurrency() - 1) ? height : (i + 1) * blockSize;// 處理當前塊for (int y = startY; y < endY; ++y) {for (int x = 0; x < width; ++x) {// 邊緣檢測邏輯...if (/* 檢測到邊緣 */) {blockEdges[i].push_back(Edge{x, y});}}}});}// 等待所有線程完成for (auto& thread : threads) {thread.join();}// 合并結果std::vector<Edge> allEdges;for (const auto& edges : blockEdges) {allEdges.insert(allEdges.end(), edges.begin(), edges.end());}return allEdges;}
};

9. 小字符串優化 (SSO) 和字符串視圖

// 優化前:頻繁創建臨時字符串
std::string extractSubstring(const std::string& str, size_t start, size_t length) {return str.substr(start, length);
}void processSubstrings(const std::string& text) {for (size_t i = 0; i < text.size(); i += 10) {std::string sub = extractSubstring(text, i, 10);// 處理sub...}
}// 優化后:使用string_view避免拷貝
std::string_view extractSubstringView(const std::string& str, size_t start, size_t length) {return std::string_view(str.data() + start, std::min(length, str.size() - start));
}void processSubstringsOptimized(const std::string& text) {for (size_t i = 0; i < text.size(); i += 10) {std::string_view sub = extractSubstringView(text, i, 10);// 處理sub...}
}

案例:日志解析器

class LogParser {
private:std::vector<std::string> logLines;public:// 優化前std::vector<std::string> extractTimestamps() {std::vector<std::string> timestamps;timestamps.reserve(logLines.size());for (const auto& line : logLines) {// 假設時間戳在每行的前19個字符if (line.size() >= 19) {timestamps.push_back(line.substr(0, 19));}}return timestamps;}// 優化后:使用string_viewstd::vector<std::string_view> extractTimestampsOptimized() {std::vector<std::string_view> timestamps;timestamps.reserve(logLines.size());for (const auto& line : logLines) {if (line.size() >= 19) {timestamps.emplace_back(line.data(), 19);}}return timestamps;}// 進一步優化:直接處理而不存儲void processTimestamps(std::function<void(std::string_view)> processor) {for (const auto& line : logLines) {if (line.size() >= 19) {processor(std::string_view(line.data(), 19));}}}
};

10. 性能分析與測量

優化的最后一步是測量和驗證。

#include <chrono>template<typename Func>
auto measureTime(Func&& func) {auto start = std::chrono::high_resolution_clock::now();std::forward<Func>(func)();auto end = std::chrono::high_resolution_clock::now();return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}// 使用示例
void comparePerformance() {std::vector<int> data(1000000);// 填充數據...auto timeOriginal = measureTime([&]() {// 原始算法std::sort(data.begin(), data.end());});auto timeOptimized = measureTime([&]() {// 優化算法std::sort(std::execution::par, data.begin(), data.end());});std::cout << "原始算法: " << timeOriginal << "ms\n";std::cout << "優化算法: " << timeOptimized << "ms\n";std::cout << "性能提升: " << (static_cast<double>(timeOriginal) / timeOptimized) << "x\n";
}

案例:大型應用性能分析

class PerformanceAnalyzer {
public:void analyzeDataStructures() {const int dataSize = 1000000;// 測試vector vs list的隨機訪問性能std::vector<int> vec(dataSize);std::list<int> lst;for (int i = 0; i < dataSize; ++i) {vec[i] = i;lst.push_back(i);}std::cout << "隨機訪問性能測試:\n";auto vecTime = measureTime([&]() {int sum = 0;for (int i = 0; i < 1000; ++i) {int idx = rand() % dataSize;sum += vec[idx];}});auto lstTime = measureTime([&]() {int sum = 0;for (int i = 0; i < 1000; ++i) {int idx = rand() % dataSize;auto it = lst.begin();std::advance(it, idx);sum += *it;}});std::cout << "Vector隨機訪問: " << vecTime << "ms\n";std::cout << "List隨機訪問: " << lstTime << "ms\n";std::cout << "性能差異: " << (static_cast<double>(lstTime) / vecTime) << "x\n";// 測試查找性能std::cout << "\n查找性能測試:\n";std::vector<int> searchVec(dataSize);std::set<int> searchSet;std::unordered_set<int> searchHashSet;for (int i = 0; i < dataSize; ++i) {searchVec[i] = i;searchSet.insert(i);searchHashSet.insert(i);}auto vecSearchTime = measureTime([&]() {int count = 0;for (int i = 0; i < 10000; ++i) {int target = rand() % (dataSize * 2); // 一半會找不到if (std::find(searchVec.begin(), searchVec.end(), target) != searchVec.end()) {count++;}}});auto setSearchTime = measureTime([&]() {int count = 0;for (int i = 0; i < 10000; ++i) {int target = rand() % (dataSize * 2);if (searchSet.find(target) != searchSet.end()) {count++;}}});auto hashSetSearchTime = measureTime([&]() {int count = 0;for (int i = 0; i < 10000; ++i) {int target = rand() % (dataSize * 2);if (searchHashSet.find(target) != searchHashSet.end()) {count++;}}});std::cout << "Vector線性查找: " << vecSearchTime << "ms\n";std::cout << "Set二分查找: " << setSearchTime << "ms\n";std::cout << "Unordered_set哈希查找: " << hashSetSearchTime << "ms\n";}private:template<typename Func>auto measureTime(Func&& func) {auto start = std::chrono::high_resolution_clock::now();std::forward<Func>(func)();auto end = std::chrono::high_resolution_clock::now();return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();}
};

總結

STL 性能優化是一個系統性工作,需要從多個角度考慮:

  1. 選擇合適的容器:根據操作特性選擇最適合的容器類型
  2. 內存管理:預分配內存、避免頻繁重新分配
  3. 算法選擇:使用 STL 提供的高效算法,考慮并行算法
  4. 避免拷貝:使用引用、移動語義和 emplace 系列函數
  5. 高效查找:對于頻繁查找操作,使用哈希容器或保持有序狀態
  6. 自定義比較和哈希:為復雜對象提供高效的比較和哈希函數
  7. 字符串優化:利用 SSO 和 string_view 減少字符串操作開銷
  8. 性能測量:通過實際測量驗證優化效果

通過這些技術,可以顯著提高 C++ 程序的性能,同時保持代碼的可讀性和可維護性。

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

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

相關文章

OSI模型_TCP/IP模型_五層模型

文章目錄 OSI模型_TCP/IP模型_五層模型模型對比模型層級對比關鍵區別對比 OSI模型OSI模型概述舉例說明流程圖示 TCP/IP 四層模型模型結構舉例說明流程圖示 TCP/IP 五層模型模型的結構舉例說明流程圖示 OSI模型_TCP/IP模型_五層模型 學OSI&#xff0c;用TCP/IP&#xff0c;分析選…

R語言——字符串

參考資料&#xff1a;學習R 文本數據存儲在字符向量中。重要的是&#xff0c;字符向量中的每個元素都是字符串&#xff0c;而非單獨的字符。 文本的基本單位是字符向量&#xff0c;著意味著大部分字符串處理函數也能用于字符向量。 1、創建和打印字符串 字符向量可用c函數創建…

如何區別在Spring Boot 2 和 Spring Boot 3 中使用 Knife4j:集成與配置指南

在現代的 Web 開發中&#xff0c;API 文檔是不可或缺的一部分。Knife4j 是基于 Swagger 的增強工具&#xff0c;它不僅提供了更友好的 API 文檔界面&#xff0c;還支持更多實用的功能&#xff0c;如離線文檔導出、全局參數配置等。本文將詳細介紹如何在 Spring Boot 2 和 Sprin…

pagehelper 分頁插件使用說明

pom.xml&#xff1a;pageHelper坐標 <!--pageHelper坐標--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version></dependency> 分…

C++可變參數

可變參數C風格的可變參數C風格可變參數的使用 C11可變參數模板遞歸展開參數包參數列表展開折疊表達式 STL中的emplace插入接口 可變參數 C風格的可變參數 可變參數是一種語言特性&#xff0c;可以在函數聲明中使用省略號...來表示函數接受可變數量的參數。 例如典型的printf…

數據庫的操作,以及sql之DML

首先&#xff0c;創建表以及插入數據 create table t_text(id int primary key auto_increment,name varchar(20) unique not null,gender char(5) not null check(gender in ("男","女")),deed varchar(255) not null default "事例不詳"); in…

vue2前端日志數據存儲(indexedD)自動清理3天前的數據

前言&#xff1a;關于Dexie.js這個前端本地數據庫&#xff0c;如何使用IndexedDB來存儲數據&#xff0c;并且設置到期自動清理的機制。首先&#xff0c;我需要回憶一下Dexie.js的基本用法&#xff0c;以及IndexedDB的特性。IndexedDB是瀏覽器中的一種非關系型數據庫&#xff0c…

【MySQL篇】索引特性,索引的工作原理以及索引的創建與管理

目錄 一&#xff0c;初識索引 二&#xff0c;MySQL與磁盤交互的基本單位 三&#xff0c;MySQL中數據文件的特性 四&#xff0c;理解page和索引 五&#xff0c;聚簇索引和非聚簇索引 六&#xff0c;索引操作 查詢索引 創建主鍵索引 唯一索引的創建 普通索引的創建 全文…

springboot項目啟動常見的問題以及配置以及一些使用技巧

1.配置倉庫 這里要把xml文件從國外的鏡像源改成國內的鏡像源。改鏡像源可以查看這篇文章 點擊查看 2.更改文件類型 方法一&#xff1a;右鍵文件找到Mark Dircetory as可以更改文件類型 方法二&#xff1a; 3.springboot本地Maven倉庫的位置 4.pom.xml文件報紅錯誤怎么辦 這…

【初探數據結構】二叉樹的順序結構——堆的實現詳解(上下調整算法的時間復雜度分析)

&#x1f4ac; 歡迎討論&#xff1a;在閱讀過程中有任何疑問&#xff0c;歡迎在評論區留言&#xff0c;我們一起交流學習&#xff01; &#x1f44d; 點贊、收藏與分享&#xff1a;如果你覺得這篇文章對你有幫助&#xff0c;記得點贊、收藏&#xff0c;并分享給更多對數據結構感…

流量分析2

一&#xff0c;webshell流量 [GKCTF 2021]簽到 先看協議分級&#xff0c;大部分是tcp&#xff0c;里面有http的基于的行文本數據占了很大的比重&#xff0c;看看里面有什么 過濾http的流量 點擊一條流量&#xff0c;里面的內容進去后面有基于行的文本數據&#xff0c; 先解he…

頭歌實踐教學平臺--【數據庫概論】--SQL

一、表結構與完整性約束的修改(ALTER) 1.修改表名 USE TestDb1; alter table your_table rename TO my_table; 2.添加與刪除字段 #語句1&#xff1a;刪除表orderDetail中的列orderDate alter table orderDetail drop orderDate; #語句2&#xff1a;添加列unitPrice alter t…

在 React 中,組件之間傳遞變量的常見方法

目錄 1. **通過 Props 傳遞數據**2. **通過回調函數傳遞數據**3. **通過 Context API 傳遞數據**4. **通過 Redux 管理全局狀態**5. **通過事件總線&#xff08;如 Node.js 的 EventEmitter&#xff09;**6. **通過 Local Storage / Session Storage**7. **通過 URL 查詢參數傳…

Redis + 布隆過濾器解決緩存穿透問題

Redis 布隆過濾器解決緩存穿透問題 1. Redis 布隆過濾器解決緩存穿透問題 &#x1f4cc; 什么是緩存穿透&#xff1f; 緩存穿透指的是查詢的數據既不在緩存&#xff0c;也不在數據庫&#xff0c;導致每次查詢都直接訪問數據庫&#xff0c;增加數據庫壓力。 例如&#xff1…

Vue動態添加或刪除DOM元素:購物車實例

Vue 指令系列文章: 《Vue插值:雙大括號標簽、v-text、v-html、v-bind 指令》 《Vue指令:v-cloak、v-once、v-pre 指令》 《Vue條件判斷:v-if、v-else、v-else-if、v-show 指令》 《Vue循環遍歷:v-for 指令》 《Vue事件處理:v-on 指令》 《Vue表單元素綁定:v-model 指令》…

vue h5實現車牌號輸入框

哈嘍&#xff0c;大家好&#xff0c;最近鵬仔開發的項目是學校校內車輛超速方面的統計檢測方面的系統&#xff0c;在開發過程中發現有個小功能&#xff0c;就是用戶移動端添加車牌號&#xff0c;剛開始想著就一個輸入框&#xff0c;提交時正則效驗一下格式就行&#xff0c;最后…

硬件基礎(5):(3)二極管的應用

文章目錄 [toc]1. **整流電路****功能**&#xff1a;**工作原理**&#xff1a;**應用實例**&#xff1a;電路組成&#xff1a;整流過程&#xff1a;電路的應用&#xff1a; 2. **穩壓電路****功能**&#xff1a;**工作原理**&#xff1a;**應用實例**&#xff1a;電路組成及功能…

Wireshark網絡抓包分析使用詳解

序言 之前學計網還有前幾天備考華為 ICT 網絡賽道時都有了解認識 Wireshark&#xff0c;但一直沒怎么專門去用過&#xff0c;也沒去系統學習過&#xff0c;就想趁著備考的網絡相關知識還沒忘光&#xff0c;先來系統學下整理點筆記~ 什么是抓包&#xff1f;抓包就是將網絡傳輸…

安心聯車輛管理平臺源碼價值分析

安心聯車輛管理平臺源碼的價值可從技術特性、功能覆蓋、市場適配性、擴展潛力及商業化支持等多個維度進行分析。以下結合實際應用進行詳細解讀&#xff1a; 一、技術架構與開發優勢 主流技術棧與高性能架構 源碼采用成熟的前后端分離架構&#xff0c;后端基于Java技術&#xff…

【操作系統】Docker如何使用-續

文章目錄 1、概述2、鞏固知識2.1、基礎命令2.2、容器管理2.3、鏡像管理2.4、網絡管理2.5、Compose 3、常用命令 1、概述 在使用Docker的過程中&#xff0c;掌握常用的命令是至關重要的。然而&#xff0c;隨著時間的推移&#xff0c;我們可能會遺忘一些關鍵的命令或對其用法變得…