DDD領域驅動設計C++實現案例:訂單管理系統

一、DDD核心概念簡介

領域驅動設計(Domain-Driven Design)是一種軟件開發方法論,強調將業務領域的概念和規則融入軟件設計中。核心概念包括:

  • 值對象(Value Object): 無唯一標識,基于屬性值判斷相等性
  • 實體(Entity): 有唯一標識,其生命周期由聚合根管理
  • 聚合根(Aggregate Root): 聚合的根節點,維護聚合內的一致性
  • 領域服務(Domain Service): 處理跨實體的業務邏輯
  • 倉儲(Repository): 提供數據持久化接口

二、訂單管理系統領域模型設計

2.1 值對象定義

地址值對象
#include <string>
#include <cstdint>
#include <utility>// 地址值對象 - 無唯一標識,基于屬性值相等
class Address {
private:std::string province_;  // 省份std::string city_;      // 城市std::string district_;  // 區/縣std::string detail_;    // 詳細地址public:// 構造函數 - 確保值對象不可變Address(std::string province, std::string city, std::string district, std::string detail): province_(std::move(province)), city_(std::move(city)), district_(std::move(district)), detail_(std::move(detail)) {}// 僅提供getter,不提供setter,保證不可變性[[nodiscard]] const std::string& GetProvince() const { return province_; }[[nodiscard]] const std::string& GetCity() const { return city_; }[[nodiscard]] const std::string& GetDistrict() const { return district_; }[[nodiscard]] const std::string& GetDetail() const { return detail_; }// 重寫相等運算符 - 基于所有屬性值判斷相等bool operator==(const Address& other) const {return province_ == other.province_ &&city_ == other.city_ &&district_ == other.district_ &&detail_ == other.detail_;}
};
商品值對象
// 商品值對象 - 無唯一標識,代表商品信息
class Product {
private:std::string name_;      // 商品名稱double price_;          // 商品單價std::string sku_;       // 商品唯一編碼public:Product(std::string name, double price, std::string sku): name_(std::move(name)), price_(price), sku_(std::move(sku)) {}[[nodiscard]] const std::string& GetName() const { return name_; }[[nodiscard]] double GetPrice() const { return price_; }[[nodiscard]] const std::string& GetSku() const { return sku_; }// 基于SKU判斷商品是否相同bool operator==(const Product& other) const {return sku_ == other.sku_;}
};

2.2 實體定義

訂單項實體
#include <memory>// 訂單項實體 - 有唯一標識,屬于Order聚合
class OrderItem {
private:uint64_t id_;               // 訂單項唯一標識std::shared_ptr<Product> product_;  // 商品信息int quantity_;              // 商品數量double unit_price_;         // 下單時的單價(快照)public:OrderItem(uint64_t id, std::shared_ptr<Product> product, int quantity): id_(id), product_(std::move(product)), quantity_(quantity) {if (quantity <= 0) {throw std::invalid_argument("訂單項數量必須大于0");}unit_price_ = product_->GetPrice();  // 記錄下單時的價格快照}[[nodiscard]] uint64_t GetId() const { return id_; }[[nodiscard]] const std::shared_ptr<Product>& GetProduct() const { return product_; }[[nodiscard]] int GetQuantity() const { return quantity_; }[[nodiscard]] double GetUnitPrice() const { return unit_price_; }// 計算訂單項總價[[nodiscard]] double CalculateTotal() const {return unit_price_ * quantity_;}// 重寫相等運算符 - 基于唯一標識判斷bool operator==(const OrderItem& other) const {return id_ == other.id_;}
};

2.3 聚合根定義

訂單聚合根
#include <vector>
#include <unordered_map>
#include <stdexcept>
#include <algorithm>
#include <chrono>// 訂單狀態枚舉
enum class OrderStatus {CREATED,    // 已創建PAID,       // 已支付SHIPPED,    // 已發貨DELIVERED,  // 已送達CANCELLED   // 已取消
};// 訂單聚合根 - 維護訂單的一致性
class Order {
private:uint64_t id_;                     // 訂單唯一標識std::string customer_id_;         // 客戶IDstd::vector<OrderItem> items_;    // 訂單項集合Address shipping_address_;        // 配送地址OrderStatus status_;              // 訂單狀態std::chrono::system_clock::time_point create_time_;  // 創建時間// 生成訂單項ID的簡單實現uint64_t GenerateItemId() const {return items_.empty() ? 1 : items_.back().GetId() + 1;}public:Order(uint64_t id, std::string customer_id, Address shipping_address): id_(id), customer_id_(std::move(customer_id)), shipping_address_(std::move(shipping_address)),status_(OrderStatus::CREATED),create_time_(std::chrono::system_clock::now()) {}// 添加商品到訂單 - 領域行為void AddProduct(const std::shared_ptr<Product>& product, int quantity) {// 檢查訂單狀態是否允許添加商品if (status_ != OrderStatus::CREATED) {throw std::logic_error("只有已創建狀態的訂單可以添加商品");}// 檢查數量是否合法if (quantity <= 0) {throw std::invalid_argument("商品數量必須大于0");}// 檢查商品是否已存在,存在則更新數量auto it = std::find_if(items_.begin(), items_.end(),[&product](const OrderItem& item) {return *item.GetProduct() == *product;});if (it != items_.end()) {// 在實際實現中,這里應該創建新的OrderItem或提供修改數量的方法throw std::logic_error("當前實現不支持修改訂單項數量,請先移除再添加");} else {// 添加新訂單項items_.emplace_back(GenerateItemId(), product, quantity);}}// 移除訂單項void RemoveItem(uint64_t item_id) {if (status_ != OrderStatus::CREATED) {throw std::logic_error("只有已創建狀態的訂單可以移除商品");}auto it = std::remove_if(items_.begin(), items_.end(),[item_id](const OrderItem& item) {return item.GetId() == item_id;});if (it == items_.end()) {throw std::invalid_argument("訂單項不存在");}items_.erase(it, items_.end());}// 計算訂單總價 - 領域行為[[nodiscard]] double CalculateTotalAmount() const {double total = 0;for (const auto& item : items_) {total += item.CalculateTotal();}return total;}// 訂單支付 - 狀態轉換行為void Pay() {if (status_ != OrderStatus::CREATED) {throw std::logic_error("只有已創建狀態的訂單可以支付");}if (items_.empty()) {throw std::logic_error("空訂單不能支付");}status_ = OrderStatus::PAID;}// 訂單發貨 - 狀態轉換行為void Ship() {if (status_ != OrderStatus::PAID) {throw std::logic_error("只有已支付狀態的訂單可以發貨");}status_ = OrderStatus::SHIPPED;}// 訂單取消 - 狀態轉換行為void Cancel() {if (status_ != OrderStatus::CREATED && status_ != OrderStatus::PAID) {throw std::logic_error("只有已創建或已支付狀態的訂單可以取消");}status_ = OrderStatus::CANCELLED;}// 獲取訂單信息的getter方法[[nodiscard]] uint64_t GetId() const { return id_; }[[nodiscard]] const std::string& GetCustomerId() const { return customer_id_; }[[nodiscard]] const std::vector<OrderItem>& GetItems() const { return items_; }[[nodiscard]] const Address& GetShippingAddress() const { return shipping_address_; }[[nodiscard]] OrderStatus GetStatus() const { return status_; }[[nodiscard]] const std::chrono::system_clock::time_point& GetCreateTime() const { return create_time_; }
};

2.4 領域服務定義

訂單領域服務
#include <unordered_map>// 訂單領域服務 - 處理跨聚合的業務邏輯
class OrderService {
public:// 合并訂單 - 跨聚合根操作std::shared_ptr<Order> MergeOrders(const std::shared_ptr<Order>& order1, const std::shared_ptr<Order>& order2) {// 檢查兩個訂單是否屬于同一客戶if (order1->GetCustomerId() != order2->GetCustomerId()) {throw std::invalid_argument("只能合并同一客戶的訂單");}// 檢查訂單狀態if (order1->GetStatus() != OrderStatus::CREATED || order2->GetStatus() != OrderStatus::CREATED) {throw std::invalid_argument("只能合并已創建狀態的訂單");}// 創建新訂單(實際應用中ID通常由倉儲生成)auto merged_order = std::make_shared<Order>(0,  // 臨時ID,實際應用中由倉儲生成order1->GetCustomerId(),order1->GetShippingAddress()  // 使用第一個訂單的配送地址);// 添加第一個訂單的商品for (const auto& item : order1->GetItems()) {merged_order->AddProduct(item.GetProduct(), item.GetQuantity());}// 添加第二個訂單的商品for (const auto& item : order2->GetItems()) {merged_order->AddProduct(item.GetProduct(), item.GetQuantity());}return merged_order;}// 計算客戶訂單總金額double CalculateCustomerTotalOrders(const std::vector<std::shared_ptr<Order>>& orders) {double total = 0;for (const auto& order : orders) {// 只計算已支付和已發貨的訂單if (order->GetStatus() == OrderStatus::PAID || order->GetStatus() == OrderStatus::SHIPPED ||order->GetStatus() == OrderStatus::DELIVERED) {total += order->CalculateTotalAmount();}}return total;}
};

2.5 倉儲接口定義

訂單倉儲接口
// 訂單倉儲接口 - 定義持久化操作
class OrderRepository {
public:virtual ~OrderRepository() = default;// 保存訂單virtual void Save(const std::shared_ptr<Order>& order) = 0;// 根據ID獲取訂單virtual std::shared_ptr<Order> GetById(uint64_t id) = 0;// 獲取客戶的所有訂單virtual std::vector<std::shared_ptr<Order>> GetByCustomerId(const std::string& customer_id) = 0;// 更新訂單virtual void Update(const std::shared_ptr<Order>& order) = 0;// 刪除訂單virtual void Delete(uint64_t id) = 0;
};

2.6 倉儲實現示例

#include <unordered_map>
#include <mutex>// 內存訂單倉儲實現 - 實際應用中可能是數據庫實現
class InMemoryOrderRepository : public OrderRepository {
private:std::unordered_map<uint64_t, std::shared_ptr<Order>> orders_;uint64_t next_id_ = 1;std::mutex mutex_;public:void Save(const std::shared_ptr<Order>& order) override {std::lock_guard<std::mutex> lock(mutex_);// 如果是新訂單,分配IDif (order->GetId() == 0) {// 在實際應用中,這里應該通過反射或工廠方法創建新訂單對象// 為簡化示例,我們假設可以修改訂單ID// 注意:在純正的DDD中,聚合根的ID通常在創建時確定auto new_order = std::make_shared<Order>(next_id_++,order->GetCustomerId(),order->GetShippingAddress());for (const auto& item : order->GetItems()) {new_order->AddProduct(item.GetProduct(), item.GetQuantity());}orders_[new_order->GetId()] = new_order;} else {orders_[order->GetId()] = order;}}std::shared_ptr<Order> GetById(uint64_t id) override {std::lock_guard<std::mutex> lock(mutex_);auto it = orders_.find(id);if (it != orders_.end()) {return it->second;}return nullptr;}std::vector<std::shared_ptr<Order>> GetByCustomerId(const std::string& customer_id) override {std::lock_guard<std::mutex> lock(mutex_);std::vector<std::shared_ptr<Order>> result;for (const auto& pair : orders_) {if (pair.second->GetCustomerId() == customer_id) {result.push_back(pair.second);}}return result;}void Update(const std::shared_ptr<Order>& order) override {Save(order);  // 對于內存倉儲,Save和Update可以實現為同一操作}void Delete(uint64_t id) override {std::lock_guard<std::mutex> lock(mutex_);orders_.erase(id);}
};

2.7 應用服務定義

// 訂單應用服務 - 協調領域對象完成業務功能
class OrderAppService {
private:std::unique_ptr<OrderRepository> order_repository_;OrderService order_service_;public:explicit OrderAppService(std::unique_ptr<OrderRepository> repository): order_repository_(std::move(repository)) {}// 創建訂單uint64_t CreateOrder(const std::string& customer_id, const Address& shipping_address) {auto order = std::make_shared<Order>(0, customer_id, shipping_address);order_repository_->Save(order);return order->GetId();}// 添加商品到訂單void AddProductToOrder(uint64_t order_id, const std::shared_ptr<Product>& product, int quantity) {auto order = order_repository_->GetById(order_id);if (!order) {throw std::invalid_argument("訂單不存在");}order->AddProduct(product, quantity);order_repository_->Update(order);}// 提交訂單(支付)void PayOrder(uint64_t order_id) {auto order = order_repository_->GetById(order_id);if (!order) {throw std::invalid_argument("訂單不存在");}order->Pay();order_repository_->Update(order);}// 合并客戶的兩個訂單uint64_t MergeCustomerOrders(uint64_t order_id1, uint64_t order_id2) {auto order1 = order_repository_->GetById(order_id1);auto order2 = order_repository_->GetById(order_id2);if (!order1 || !order2) {throw std::invalid_argument("訂單不存在");}auto merged_order = order_service_.MergeOrders(order1, order2);order_repository_->Save(merged_order);// 刪除原訂單order_repository_->Delete(order_id1);order_repository_->Delete(order_id2);return merged_order->GetId();}// 獲取客戶訂單總金額double GetCustomerTotalSpent(const std::string& customer_id) {auto orders = order_repository_->GetByCustomerId(customer_id);return order_service_.CalculateCustomerTotalOrders(orders);}
};

三、客戶端使用示例

#include <iostream>void RunExample() {// 創建倉儲auto repository = std::make_unique<InMemoryOrderRepository>();OrderAppService app_service(std::move(repository));// 創建地址Address shipping_address("廣東省", "深圳市", "南山區", "科技園路100號");// 創建訂單uint64_t order_id = app_service.CreateOrder("customer_123", shipping_address);std::cout << "創建訂單成功,訂單ID: " << order_id << std::endl;// 創建商品auto product1 = std::make_shared<Product>("C++編程思想", 89.0, "book_001");auto product2 = std::make_shared<Product>("DDD實戰", 79.0, "book_002");// 添加商品到訂單app_service.AddProductToOrder(order_id, product1, 1);app_service.AddProductToOrder(order_id, product2, 2);std::cout << "添加商品到訂單成功" << std::endl;// 支付訂單app_service.PayOrder(order_id);std::cout << "訂單支付成功" << std::endl;// 查詢客戶總消費double total = app_service.GetCustomerTotalSpent("customer_123");std::cout << "客戶總消費金額: " << total << "元" << std::endl;
}int main() {try {RunExample();} catch (const std::exception& e) {std::cerr << "發生錯誤: " << e.what() << std::endl;return 1;}return 0;
}

四、DDD概念在案例中的體現

  1. 限界上下文(Bounded Context): 整個訂單管理系統構成一個限界上下文,包含了訂單相關的所有領域對象

  2. 值對象(Value Object):

    • Address: 表示地址信息,無唯一標識,基于內容判斷相等
    • Product: 表示商品信息,基于SKU判斷相等性,是不可變對象
  3. 實體(Entity):

    • OrderItem: 有唯一ID,生命周期由Order聚合根管理
    • 實體的標識在整個系統中唯一,不受屬性變化影響
  4. 聚合根(Aggregate Root):

    • Order: 作為聚合根,維護訂單項集合的一致性
    • 提供了添加/移除商品、支付、發貨等領域行為
    • 確保訂單狀態轉換的業務規則得到遵守
  5. 領域服務(Domain Service):

    • OrderService: 處理跨聚合的業務邏輯(訂單合并)
    • 包含領域知識,但不適合放在單個聚合根中的操作
  6. 倉儲(Repository):

    • OrderRepository: 抽象訂單的持久化操作
    • InMemoryOrderRepository: 具體實現,隔離領域層與數據訪問層
  7. 領域事件(Domain Event): 案例中未直接實現,但可以擴展添加,如訂單支付后發布OrderPaid事件

五、總結

本案例通過一個簡單的訂單管理系統展示了DDD的核心概念和設計思想:

1.** 以領域為中心 : 設計圍繞訂單業務領域的概念和規則展開
2.
面向對象設計 : 將業務行為封裝在領域對象中,而非過程式的服務中
3.
關注業務規則 : 通過聚合根確保業務規則(如訂單狀態轉換)得到遵守
4.
分層架構 : 領域層、應用層、基礎設施層清晰分離
5.
隔離技術細節 **: 通過倉儲接口隔離領域層與數據訪問技術

在實際項目中,DDD的應用往往更加復雜,可能還會涉及領域事件、事件溯源、CQRS等模式,但本案例展示的核心概念是DDD的基礎。通過將業務領域模型化,團隊可以更好地與領域專家溝通,構建出更符合業務需求、更易維護的軟件系統。## 六、DDD架構設計

6.1 DDD分層架構

DDD推薦采用分層架構,將系統劃分為不同職責的層次,各層之間通過明確的接口交互。以下是典型的DDD四層架構:

DDD四層架構圖

各層職責:

  • 表示層(Presentation Layer):處理用戶交互和請求響應,如API接口、UI界面
  • 應用層(Application Layer):協調領域對象執行業務操作,不包含業務邏輯
  • 領域層(Domain Layer):核心層,包含業務模型、規則和邏輯
  • 基礎設施層(Infrastructure Layer):提供技術支持,如數據庫訪問、消息隊列等

在我們的訂單管理系統中:

  • 表示層:未直接實現,可對應API控制器或UI界面
  • 應用層:OrderAppService類,協調領域對象完成業務功能
  • 領域層:OrderOrderItemProduct等領域對象和OrderService領域服務
  • 基礎設施層:OrderRepository接口及InMemoryOrderRepository實現

6.2 領域事件

領域事件是DDD中一個重要概念,用于捕獲領域中發生的重要事件并通知其他組件。例如:

// 訂單支付事件示例
class OrderPaidEvent {
private:uint64_t order_id_;std::string customer_id_;double amount_;std::chrono::system_clock::time_point paid_time_;public:OrderPaidEvent(uint64_t order_id, std::string customer_id, double amount): order_id_(order_id), customer_id_(std::move(customer_id)), amount_(amount), paid_time_(std::chrono::system_clock::now()) {}// Getter方法...
};// 在Order類的Pay方法中發布事件
void Pay() {// ... 現有支付邏輯 ...// 發布訂單支付事件DomainEventPublisher::Publish(std::make_shared<OrderPaidEvent>(id_, customer_id_, CalculateTotalAmount()));
}

領域事件可用于實現跨聚合通信、集成其他系統(如支付系統、物流系統)等,提高系統的解耦度。

七、使用DDD的優化點

7.1 業務與技術分離

DDD將業務邏輯集中在領域層,與技術實現分離。在訂單管理系統中,訂單的狀態轉換、價格計算等核心業務規則封裝在Order類中,不依賴于數據庫訪問、UI框架等技術細節。

優勢:

  • 業務邏輯更清晰,易于理解和維護
  • 技術變更(如更換數據庫)不影響領域模型
  • 領域模型可獨立測試,無需依賴外部系統

7.2 領域知識顯性化

DDD鼓勵創建與業務語言一致的模型,使領域知識直接體現在代碼中。例如:

  • Order::Pay()方法對應"訂單支付"業務動作
  • OrderStatus枚舉反映業務中的訂單狀態流轉
  • OrderService::MergeOrders()實現"合并訂單"業務場景

這種顯性化使開發人員和領域專家能使用共同語言溝通,減少理解偏差。

7.3 維護數據一致性

聚合根模式確保了數據的一致性。Order作為聚合根,控制著訂單項的添加、移除和訂單狀態的轉換,防止出現無效狀態(如空訂單支付、已發貨訂單添加商品等)。

7.4 提高代碼復用性

領域模型抽象了業務概念,可在不同場景中復用。例如Product值對象可用于訂單系統、庫存系統、購物車系統等多個模塊。

7.5 更好的可擴展性

DDD的分層架構和領域模型設計使系統更易于擴展:

  • 新增業務功能時,只需擴展領域模型或添加新的領域服務
  • 通過限界上下文隔離不同業務模塊,減少相互影響
  • 領域事件機制支持松耦合的擴展

八、不使用DDD的問題

8.1 業務邏輯分散

傳統開發中,業務邏輯常分散在服務層、控制器甚至UI層,形成"貧血模型"。例如:

// 傳統方式:業務邏輯分散在服務中
class OrderService {
public:double CalculateTotal(OrderDTO order) {double total = 0;for (auto& item : order.items) {total += item.price * item.quantity;}return total;}void PayOrder(uint64_t order_id) {// 查詢訂單、更新狀態等邏輯}// 更多業務方法...
};

這種方式導致業務規則難以追蹤和維護,需求變更時需修改多個地方。

8.2 技術驅動設計

缺乏領域模型時,開發往往以數據庫表結構為中心(數據庫驅動設計),導致代碼與業務脫節。例如,為了適應數據庫關系而設計的類結構,可能無法反映真實業務概念。

8.3 難以應對復雜業務

對于復雜業務規則,沒有領域模型的支撐會導致代碼變得混亂:

  • 條件判斷嵌套復雜
  • 業務規則隱藏在過程式代碼中
  • 難以進行單元測試
  • 團隊協作困難,代碼沖突頻繁

8.4 系統剛性

傳統架構缺乏明確邊界,模塊間依賴緊密,一處修改可能引發多處問題。例如,修改訂單狀態字段可能影響到訂單查詢、統計、報表等多個功能。

九、DDD適用場景與注意事項

9.1 適合DDD的場景

  • 復雜業務領域:如金融、電商、物流等業務規則復雜的系統
  • 長期演進系統:需要持續迭代、擴展的大型應用
  • 團隊協作開發:多團隊、多角色參與的項目
  • 業務價值優先:業務邏輯對系統成功至關重要的項目

9.2 DDD的局限性

  • 學習曲線陡峭:需要團隊理解領域驅動設計的概念和原則
  • 前期投入大:領域建模需要與領域專家深入溝通
  • 不適合簡單系統:對于CRUD為主的簡單應用,可能增加不必要的復雜度
  • 需要持續重構:領域模型需要隨業務發展不斷優化

9.3 實施建議

  1. 從小處著手:選擇核心業務模塊先行實施DDD
  2. 領域專家參與:確保開發人員與領域專家密切合作
  3. 持續建模:通過事件風暴、示例驅動等方法不斷完善模型
  4. 避免過度設計:根據業務復雜度調整DDD實踐的深度
  5. 自動化測試:為領域模型編寫全面的單元測試

十、總結與擴展

本案例通過訂單管理系統展示了DDD的核心概念和實踐方法。從值對象、實體到聚合根,從領域服務到倉儲,每個組件都有其明確的職責和設計意圖。DDD不是銀彈,但在復雜業務系統中,它提供了一套有效的方法論,幫助團隊構建出更符合業務需求、更易維護的軟件。

擴展方向

  1. 事件溯源(Event Sourcing):通過記錄領域事件來重建對象狀態,適合審計、溯源需求
  2. CQRS:命令查詢職責分離,優化讀寫性能
  3. 微服務與DDD:結合限界上下文設計微服務邊界
  4. 領域驅動設計工具:使用事件風暴工具、領域模型可視化工具等提升建模效率

要真正掌握DDD,需要在實踐中不斷學習和調整。建議結合具體業務場景,逐步應用DDD原則,而非教條式地套用所有模式。

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

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

相關文章

神經網絡和機器學習的一些基本概念

記錄一些基本概念,不涉及公式推導,因為數學不好,記了也沒啥用,但是知道一些基本術語以及其中的關系,對神經網絡訓練有很大幫助。 可能有些概念不會講得很詳細,但是當你有了這個概念,你就知道往這個方向去獲取更詳細的信息,不至于連往哪走都不知道。 下面以多元線性回歸…

MySQL(146) 如何遷移數據庫到新服務器?

數據庫遷移到新服務器是一項復雜而重要的任務&#xff0c;確保數據完整性和最小化停機時間至關重要。以下是一個詳細的步驟指導&#xff0c;包括準備工作、數據備份、數據傳輸、數據恢復和驗證的全過程。 一、準備工作 1. 確認服務器環境 源服務器&#xff1a;當前運行數據庫的…

圖論的整合

圖 有若干個節點&#xff0c;有若干條邊連接節點。&#xff08;兩個點之間不是必須相連&#xff09; 比如&#xff1a; 有向圖 可以理解為邊上面有箭頭的圖&#xff0c;比如下面這張圖&#xff1a; 在這張圖中&#xff0c;點 111 可以通過這條有向邊到達點 222&#xff0c…

電子設計大賽【C語言核心知識點】講解

目錄 前言 1. 基礎語法 2. 流程控制 3. 函數 4. 數組與字符串 5. 指針&#xff08;核心重點&#xff09; 6. 內存管理 7. 結構體與聯合體 8. 文件操作 9. 預處理器 10. 高級特性 內存布局圖解 前言 在進行程序代碼開發之前&#xff0c;需要掌握好C語言各個模塊之間…

Numpy 庫 矩陣數學運算,點積,文件讀取和保存等

目錄 1.數組&#xff08;矩陣&#xff09;的組合 2.數組&#xff08;矩陣&#xff09;的切割 3.數組的數學運算 4.數組的深拷貝和淺拷貝 5.隨機模塊 6.矩陣統計運算 7.矩陣的特有運算點積&#xff0c;求逆 8.文件讀取和保存 1.數組&#xff08;矩陣&#xff09;的組合 水…

STL學習(?函數對象,謂詞,內建函數對象)

目錄 一、函數對象 1.函數對象的概念 2.函數對象的使用 &#xff08;1&#xff09;函數對象在使用的時候&#xff0c;可以像普通函數那樣調用&#xff0c;可以有參數&#xff0c;也可以有返回值。 &#xff08;2&#xff09;函數對象超出普通函數的概念&#xff0c;函數對象…

【爬蟲】05 - 爬蟲攻防

爬蟲05 - 爬蟲攻防 文章目錄爬蟲05 - 爬蟲攻防一&#xff1a;隨機User-Agent爬蟲1&#xff1a;fake-useragent2&#xff1a;高級反反爬策略3&#xff1a;生產環境建議二&#xff1a;代理IP爬蟲1&#xff1a;獲取代理IP2&#xff1a;高階攻防3&#xff1a;企業級的代理實戰三&am…

FPGA自學——存儲器模型

FPGA自學——存儲器模型 文章目錄FPGA自學——存儲器模型一、IP核二、ROM&#xff08;read only memory&#xff09;三、ROM的IP核調用四、RAM&#xff08;random access memory&#xff09;五、RAM的IP核調用總結1.不同波形的使用的存儲器2.塊與分布式的選擇3.FPGA與模塊的容量…

【C++】stack和queue拓展學習

目錄 1.反向迭代器思路及實現 1.1. 源碼及框架分析 1.2. 實現反向迭代器 2.stack和queue練習拓展-計算器實現 2.1. 后綴表達式概念 2.2. 后綴表達式運算規則 2.3. 中綴表達式轉后綴表達式 2.3.1 轉換思路 2.3.2 代碼實現 2.4. 計算器實現 1.反向迭代器思路及實現 1.1…

Web3與區塊鏈如何革新網絡安全——走在前沿

隨著互聯網技術的飛速發展&#xff0c;網絡安全問題日益成為全球關注的焦點。Web3和區塊鏈技術作為新興的技術力量&#xff0c;正在逐步改變網絡安全的格局。本文將探討Web3和區塊鏈技術如何革新網絡安全&#xff0c;走在技術前沿。 1. Web3技術概述 Web3&#xff0c;即第三代互…

網絡初級安全第三次作業

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用戶登錄</title><style>* {margin:…

CSS中用display實現元素的顯示/隱藏切換

** 通過display中的none和block ** 在前端開發中&#xff0c;display: none 和 display: block 是兩種常用的 CSS 顯示模式&#xff0c;核心區別在于&#xff1a;是否在頁面中保留元素的占位空間 1. 核心區別屬性display: nonedisplay: block占位空間元素完全從渲染樹中移除&am…

因果圖方法設計測試用例的價值與使用范圍

一、因果圖方法的核心原理 因果圖方法通過分析軟件規格說明中的輸入條件&#xff08;因&#xff09;和輸出結果&#xff08;果&#xff09;之間的邏輯關系&#xff0c;利用圖形化方式將這些關系清晰展現。它使用特定的符號表示因果關系&#xff08;如恒等、非、或、與&#xff…

智慧農服數字化平臺-數字科技賦能農業,開啟智慧三農新篇章

智慧農服數字化平臺數字科技賦能農業&#xff0c;開啟智慧三農新篇章平臺概覽在鄉村振興和農業現代化的時代背景下&#xff0c;我們推出了創新的農業服務數字化平臺——一個專為農業生產者打造的綜合性SaaS服務平臺。平臺以"科技助農、數據興農"為使命&#xff0c;通…

在線教育培訓課程視頻如何防下載、防盜錄?

在數字化學習日益普及的今天&#xff0c;高質量的在線課程已成為教育機構、知識付費平臺和講師的核心競爭力。如何在不影響學員正常學習體驗的前提下&#xff0c;有效防止課程視頻被惡意盜取&#xff1f;今天介紹在線教育課程防下載、防盜錄的10種視頻加密方法&#xff0c;看看…

圖像分析學習筆記(2):圖像處理基礎

圖像分析學習筆記&#xff1a;圖像處理基礎圖像增強方法圖像復原方法圖像分割方法形態學處理圖像增強方法 目的&#xff1a;改善視覺效果&#xff0c;例如增強對比度定義&#xff1a;為了改善視覺效果、便于人或計算機對圖像的分析理解&#xff0c;針對圖像的特點或存在的問題…

生存分析機器學習問題

研究目標&#xff1a; 開發一個機器學習模型&#xff0c;用于個性化預測XXX的總體生存期。 模型輸入&#xff1a;結合生存時間、治療方案、人口統計學特征和實驗室測試結果等多種特征。 模型輸出&#xff1a;預測二元結果&#xff08;活著 vs. 死亡&#xff09;。 應用場景&…

【華為機試】547. 省份數量

文章目錄547. 省份數量描述示例 1示例 2提示解題思路核心分析問題轉化算法選擇策略1. 深度優先搜索 (DFS)2. 廣度優先搜索 (BFS)3. 并查集 (Union-Find)算法實現詳解方法一&#xff1a;深度優先搜索 (DFS)方法二&#xff1a;廣度優先搜索 (BFS)方法三&#xff1a;并查集 (Union…

09_Spring Boot 整合 Freemarker 模板引擎的坑

09_Spring Boot 整合 Freemarker 模板引擎的坑 1.背景&#xff1a; springboot 版本&#xff1a;3.0.2 2. 引入依賴 在 pom.xml 中添加&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web<…

十七、【Linux系統yum倉庫管理】替換阿里源、搭建本地yum源

替換阿里源、搭建本地yum源本章學習目標內容簡介阿里外網源核心功能本地yum核心功能操作演示替換阿里外網源備份原有yum源清理沖突配置下載阿里源配置文件添加EPEL擴展源清理緩存重建索引驗證源狀態測試安裝軟件使用鏡像搭建本地倉庫準備ISO鏡像創建掛載點目錄掛載iso文件驗證掛…