OpenFOAM中梯度場的復用(caching)和生命期管理

文章目錄

    • OpenFOAM中梯度場的復用(caching)和生命期管理
      • 一、緩存機制的目標
      • 二、如何實現緩存(以 `fvc::grad` 為例)
        • 1. 使用 `IOobject::AUTO_WRITE` 和注冊名
        • 2. 示例:`fvc::grad` 的緩存實現(簡化邏輯)
      • 三、生命期管理是如何實現的?
        • 1. `regIOobject` 的作用
        • 2. 緩存對象的依賴關系
        • 3. 手動控制緩存生命周期
      • 四、底層實現機制總結
      • 五、實際使用建議
      • 六、擴展:自定義智能緩存(帶依賴監聽)
      • 結論
    • OpenFOAM中場和場梯度對象的生命期管理
      • 一、OpenFOAM 中的“場”是什么?
      • 二、場的生命期管理
        • 1. **對象存儲在 Time 或對象注冊表(objectRegistry)中**
        • 2. **自動內存管理機制**
        • 3. **析構與自動釋放**
      • 三、場梯度(如 `fvc::grad(U)`)的生命期管理
        • 1. **臨時對象(Temporary Field)**
        • 2. `tmp<T>` 的作用
        • 3. 示例:梯度計算的生命周期
      • 四、底層實現機制
        • 1. `GeometricField` 的內存布局
        • 2. `tmp<T>` 的實現細節
        • 3. 延遲求值與表達式模板(可選優化)
      • 五、總結:生命期管理的關鍵點
      • 六、最佳實踐建議
      • 參考源碼路徑(OpenFOAM 源碼)
      • 結論
    • OpenFOAM中對象注冊機制實現
    • 一、objectRegistry 簡介
      • 主要功能:
    • 二、類繼承結構
    • 三、核心機制詳解
      • 1. 注冊過程
        • 示例:創建一個場變量
      • 2. 注冊與反注冊(checkIn / checkOut)
      • 3. 查找對象
    • 四、嵌套注冊表結構
    • 五、I/O 機制集成
    • 六、實際代碼示例:手動注冊一個對象
    • 七、高級特性
      • 1. 監聽對象事件(事件驅動)
      • 2. 動態創建對象
      • 3. 引用計數
    • 八、常見問題與調試
    • 九、總結
    • 十、參考源碼路徑(OpenFOAM-9)

OpenFOAM中梯度場的復用(caching)和生命期管理

在 OpenFOAM 中,對于場(如 surfaceScalarField 類型的 phi)的梯度或其他導出場(如 fvc::grad(phi))進行緩存(caching),并實現其生命期管理,是通過 OpenFOAM 的 “自動緩存機制”對象注冊系統(object registry)實現的。這種機制允許在需要時自動計算并緩存導出場,避免重復計算,同時確保緩存對象的生命期與相關場一致。

下面詳細解釋如何實現對 phi 梯度場的緩存與生命期管理,以及底層實現機制。


一、緩存機制的目標

在 OpenFOAM 中,fvc::grad(phi) 是一個常見的操作,用于計算體積場 phi 的梯度。如果在多個地方調用 fvc::grad(phi),默認情況下每次都會重新計算,造成性能浪費。

緩存機制的目標是:

  • 第一次調用 fvc::grad(phi) 時計算梯度;
  • 將結果緩存到與 phi 關聯的 對象注冊表objectRegistry)中;
  • 后續調用時直接復用緩存結果;
  • phi 被銷毀或更新時,自動清理或更新緩存。

二、如何實現緩存(以 fvc::grad 為例)

OpenFOAM 使用 tmp<GeometricField<Type, ...>>IOobject 的注冊機制來實現緩存。

1. 使用 IOobject::AUTO_WRITE 和注冊名

緩存的導出場(如 grad(phi))通常被注冊為臨時場,使用特定命名規則,例如:

word gradName = "grad(" + phi.name() + ")";

然后嘗試從 objectRegistry 中查找是否已有該名稱的場存在。

2. 示例:fvc::grad 的緩存實現(簡化邏輯)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
grad(const GeometricField<Type, fvsPatchField, surfaceMesh>& ssf)
{const word gradName = "grad(" + ssf.name() + ")";// 查看 registry 中是否已有緩存if (isObjectRegistry && ssf.db().foundObject<GeometricField<Type, fvPatchField, volMesh>>(gradName)){// 返回緩存的場(引用計數管理)return ssf.db().lookupObject<GeometricField<Type, fvPatchField, volMesh>>(gradName);}else{// 計算梯度tmp<GeometricField<Type, fvPatchField, volMesh>> tgrad = fvc::calculateGrad(ssf);// 設置 IO 屬性以便緩存tgrad.ref().rename(gradName);tgrad.ref().store();  // 將其注冊到數據庫中,實現緩存return tgrad;}
}

關鍵點:

  • store() 方法會將 tmp 內部的對象通過 regIOobject::store() 注冊到 objectRegistry
  • 下次調用時可通過 foundObjectlookupObject 查找。

三、生命期管理是如何實現的?

OpenFOAM 使用 regIOobject 類作為所有可注冊對象的基類,實現自動生命期管理。

1. regIOobject 的作用
  • 繼承自 IOobject,支持讀寫、命名、注冊。
  • 提供 store() 方法將對象注冊到 objectRegistry
  • 支持 引用計數(reference counting)事件通知(如父對象銷毀時自動刪除子對象)。
2. 緩存對象的依賴關系

grad(phi) 被緩存時,可以通過設置依賴關系,使得當 phi 被修改或銷毀時,grad(phi) 自動失效或被刪除。

雖然 OpenFOAM 默認的 fvc::grad 并不總是自動監聽 phi 的變化,但可以通過以下方式實現更智能的緩存:

  • 在創建 grad(phi) 時,將其設置為依賴于 phi
  • 利用 eventNo() 或自定義監聽機制,在 phi 修改時觸發緩存失效。

但標準 OpenFOAM 中,緩存不會自動失效,除非手動清除或程序重啟。因此,緩存通常用于“不變場”或在時間步開始前清除。

3. 手動控制緩存生命周期

可以通過以下方式管理:

// 手動清除緩存
if (mesh.foundObject<volVectorField>("grad(phi)"))
{mesh.checkOut("grad(phi)"); // 從 registry 移除,觸發析構
}

或者在每個時間步開始前清除梯度緩存:

mesh.clearOut(); // 清除所有臨時緩存對象

四、底層實現機制總結

機制說明
objectRegistry所有場和對象的注冊中心,支持按名稱查找。
IOobject提供對象命名、讀寫、注冊能力。
regIOobject可注冊對象基類,支持 store()checkOut()
tmp<T>臨時對象包裝器,支持延遲求值和自動內存管理。
store()將對象注冊到 registry,實現緩存。
引用計數tmp 使用引用計數,避免重復拷貝。
生命周期緩存對象生命期由 registry 管理,直到被 checkOut() 或 registry 析構。

五、實際使用建議

  1. 啟用緩存:確保 IOobject 創建時使用 IOobject::NO_READIOobject::NO_WRITE,但通過 store() 注冊。
  2. 命名規范:使用如 grad(phi) 的命名避免沖突。
  3. 手動清理:在時間步或迭代中適當調用 clearOut()checkOut() 避免內存泄漏。
  4. 注意一致性:緩存不會自動感知 phi 的變化,需在 phi 更新后手動清除 grad(phi)

六、擴展:自定義智能緩存(帶依賴監聽)

若需更高級的緩存(如自動失效),可繼承 regIOobject 并重寫 updated(), upToDate() 方法,或使用 fieldDependence 機制(如 functionObject 中的做法),但這在標準 fvc 中未默認實現。


結論

OpenFOAM 中對 phi 梯度的緩存是通過:

  • grad(phi) 作為命名對象注冊到 objectRegistry
  • 使用 tmpstore() 實現復用;
  • 依賴 regIOobject 的注冊與析構機制管理生命期。

生命期由 objectRegistry 控制,緩存對象在注冊后持續存在,直到被顯式移除或 registry 銷毀。雖然高效,但需用戶注意緩存一致性,必要時手動清理。

?? 注意:OpenFOAM 版本不同(如 v2006、v2212、v2312)在 fvc::grad 是否默認緩存上可能有差異,建議查閱對應版本源碼(src/finiteVolume/finiteVolume/divSchemes/gradScheme/gradScheme.C)確認行為。


OpenFOAM中場和場梯度對象的生命期管理

在 OpenFOAM 中,場(Field)場梯度(Gradient of Field) 的生命期管理是通過 C++ 的對象生命周期機制與 OpenFOAM 特有的內存管理策略結合實現的。理解其底層機制需要從 OpenFOAM 的類結構、對象存儲方式以及自動內存管理等方面入手。


一、OpenFOAM 中的“場”是什么?

在 OpenFOAM 中,場(Field)是表示在網格點(如體心、面心、節點等)上定義的物理量(如壓力 p、速度 U、溫度 T 等)的數據結構。主要類型包括:

  • volScalarField:體心標量場(如壓力)
  • volVectorField:體心矢量場(如速度)
  • surfaceScalarField:面心標量場(如通量)
  • 等等

這些場本質上是繼承自模板類 GeometricField<Type, PatchField, Mesh>,并封裝了值、維度、邊界條件、時間信息等。


二、場的生命期管理

1. 對象存儲在 Time 或對象注冊表(objectRegistry)中

OpenFOAM 使用 objectRegistry(通常是 TimefvMesh 的成員)來管理所有場的生命周期。每個場在創建時都會被注冊到一個 objectRegistry 中。

例如:

volScalarField p
(IOobject("p",runTime.timeName(),mesh,IOobject::MUST_READ,IOobject::AUTO_WRITE),mesh
);
  • IOobject 是關鍵:它定義了場的名稱、讀寫策略、是否自動寫入等。
  • p 被構造時,它會自動注冊到 meshrunTimeobjectRegistry 中。
2. 自動內存管理機制
  • 場對象一旦注冊到 objectRegistry,其生命周期由該注冊表管理。
  • 在時間步進過程中,如果創建了新的場(如 grad(U)),它們可能不會自動注冊,除非顯式指定 IOobject
  • 但大多數求解器中,主變量(如 U, p)是持久的,存在于整個模擬過程中。
3. 析構與自動釋放
  • objectRegistry 被銷毀(如程序結束、時間步切換、網格重構),它會自動調用注冊對象的析構函數。
  • C++ 的 RAII(Resource Acquisition Is Initialization)機制確保資源(內存)在對象析構時被釋放。
  • 場內部的數據(如 Field<Type>)使用動態數組(List<Type>)存儲,其內存由 new/delete 或 STL 容器管理。

三、場梯度(如 fvc::grad(U))的生命期管理

1. 臨時對象(Temporary Field)

fvc::grad(U) 返回的是一個臨時的 tmp<GeometricField<vector, fvPatchField, volMesh>> 對象

tmp<volVectorField> tgradU = fvc::grad(U);
  • tmp<T> 是 OpenFOAM 提供的智能指針類,用于管理臨時對象的生命周期。
  • 它類似于 std::unique_ptrstd::shared_ptr,但更輕量,專為性能優化設計。
2. tmp<T> 的作用
  • tmp<T> 封裝了一個指針,可以是“擁有”或“引用”模式。
  • tmp<T> 被賦值或傳遞時,OpenFOAM 會判斷是否需要復制或轉移所有權。
  • tmp<T> 超出作用域時,若其擁有對象,則自動刪除。
3. 示例:梯度計算的生命周期
solve(fvm::ddt(U) + fvm::div(phi, U) - fvm::laplacian(nu, U) == -fvc::grad(p));
  • fvc::grad(p) 返回 tmp<volVectorField>
  • 該臨時場在表達式求值完成后,其 tmp 對象析構,內部場被自動釋放。
  • OpenFOAM 的矩陣組裝完成后,不再需要梯度場,因此立即釋放。

四、底層實現機制

1. GeometricField 的內存布局
  • 數據存儲在 Field<Type> 中,本質是 List<Type>,使用動態內存(malloc/new)。
  • 邊界字段(BoundaryField)也類似。
  • 內存分配由 List 類管理,析構時自動 delete[]
2. tmp<T> 的實現細節
template<class T>
class tmp
{T* ptr_;           // 指向對象bool isPtr_;       // 是否擁有指針
public:tmp(T* t) : ptr_(t), isPtr_(true) {}tmp(const tmp& t) : ptr_(t.ptr_), isPtr_(t.isPtr_) { t.isPtr_ = false; }~tmp() { if (isPtr_) delete ptr_; }T& operator()() const { return *ptr_; }
};
  • 所有權轉移:拷貝構造后原對象不再擁有指針(避免雙重釋放)。
  • 高效:避免不必要的復制,尤其對大型場對象至關重要。
3. 延遲求值與表達式模板(可選優化)

OpenFOAM 還使用表達式模板(如 fvMatrix 的操作)來延遲計算,避免生成中間場,進一步減少臨時對象數量。


五、總結:生命期管理的關鍵點

機制說明
objectRegistry持久場(如 U, p)注冊其中,由時間或網格控制生命周期
IOobject控制讀寫、自動注冊、持久性
tmp<T>管理臨時場(如梯度、散度)的自動釋放
RAIIC++ 析構函數自動釋放內存
Field/List底層動態數組,析構時釋放內存

六、最佳實踐建議

  • 主變量(求解變量)應定義在 createFields.H 中,注冊到 objectRegistry
  • 臨時計算盡量使用 tmp 返回類型(OpenFOAM 內部函數已封裝)。
  • 避免手動 new/delete,依賴 RAII 和 tmp
  • 若需保存梯度場,應顯式創建并注冊:
volVectorField gradU
(IOobject("gradU", runTime.timeName(), mesh, IOobject::AUTO_WRITE),fvc::grad(U)
);

參考源碼路徑(OpenFOAM 源碼)

  • src/OpenFOAM/primitives/tmp/tmp.Htmp<T> 定義
  • src/finiteVolume/fields/fvPatchFields/basic/grad/:梯度計算
  • src/OpenFOAM/fields/GeometricFields/GeometricField.H:場類定義
  • src/OpenFOAM/db/objectRegistry/:對象注冊機制

結論

OpenFOAM 通過 objectRegistry + IOobject + tmp<T> + RAII 的組合,實現了高效且安全的場與場梯度的生命期管理。持久場由注冊表管理,臨時場通過 tmp 自動釋放,底層依賴 C++ 的構造/析構機制,避免內存泄漏,同時兼顧高性能計算需求。


OpenFOAM中對象注冊機制實現

在 OpenFOAM 中,objectRegistry 是一個非常核心的類,它實現了對象的注冊與管理機制,是 OpenFOAM 運行時系統(Runtime System)的基礎之一。理解 objectRegistry 的工作機制對于深入掌握 OpenFOAM 架構至關重要。


一、objectRegistry 簡介

objectRegistry 是 OpenFOAM 中用于管理所有可命名對象(如 volScalarField, volVectorField, IOdictionary, fvMesh 等)的容器。它本質上是一個命名對象的注冊表(registry),支持按名稱查找、存儲、創建和銷毀對象。

主要功能:

  • 存儲和管理運行時創建的對象(如場、字典、邊界條件等)。
  • 支持對象的自動命名與查找。
  • 支持對象的生命周期管理(通過引用計數)。
  • 提供 I/O 功能(與 IOobject 配合)。
  • 支持嵌套注冊表結構(如 Time 包含 fvMeshfvMesh 又包含 volField)。

二、類繼承結構

class objectRegistry: public regIOobject, public HashTable<regIOobject*, word, string::hash>
  • 繼承自 regIOobject:表示它本身也是一個可注冊的 I/O 對象(可以被其他 registry 管理)。
  • 繼承自 HashTable<regIOobject*, word, string::hash>:使用哈希表存儲對象指針,鍵為對象名稱(word 類型)。

三、核心機制詳解

1. 注冊過程

當一個對象(如 volScalarField)被創建時,它通常會繼承自 regIOobject,并在構造函數中自動注冊到某個 objectRegistry(如 meshtime)中。

示例:創建一個場變量
volScalarField p
(IOobject("p",                    // 名稱runTime.timeName(),     // 時間目錄mesh,                   // objectRegistry(通常是 mesh)IOobject::MUST_READ,    // 讀取方式IOobject::AUTO_WRITE    // 寫入方式),mesh                      // 構造所需網格
);

在這個構造過程中:

  1. IOobject 構造時會檢查 objectRegistry(這里是 mesh)中是否已有名為 "p" 的對象。
  2. volScalarField 構造完成后,會調用 regIOobject::checkIn(),將自己注冊到 meshobjectRegistry 中。
  3. 注冊本質是將 (name, pointer) 插入哈希表。

2. 注冊與反注冊(checkIn / checkOut)

  • checkIn():將對象注冊到其指定的 objectRegistry
  • checkOut():從注冊表中移除對象(通常在析構時自動調用)。
bool regIOobject::checkIn()
{return ownedByRegistry_ ? false : registry_->insert(name(), this);
}

注意:ownedByRegistry_ 表示是否已注冊,防止重復注冊。

3. 查找對象

const volScalarField& p = mesh.lookupObject<volScalarField>("p");

lookupObjectobjectRegistry 提供的模板方法,通過名稱查找對象。

內部實現:

template<class Type>
const Type& objectRegistry::lookupObject(const word& name) const
{const regIOobject* obj = this->find(name);if (!obj){FatalErrorInFunction<< "Cannot find object " << name << " in registry " << this->name();}return dynamic_cast<const Type&>(*obj);
}

四、嵌套注冊表結構

OpenFOAM 使用樹狀結構組織 objectRegistry

Time (rootRegistry)
└── fvMesh├── volScalarField "p"├── volVectorField "U"└── surfaceScalarField "phi"
  • Time 是頂級注冊表,管理所有時間步相關的對象。
  • fvMeshTime 的子注冊表,管理所有與網格相關的對象。
  • 每個場變量注冊到 fvMesh 中。

這種結構支持模塊化和作用域管理。


五、I/O 機制集成

objectRegistryIOobject 配合實現自動讀寫:

  • 當調用 runTime.write() 時,objectRegistry 會遍歷所有對象,調用其 write() 方法。
  • 每個 regIOobject 可設置 WRITE_ALWAYSAUTO_WRITE 等寫入策略。
// 寫入所有可寫對象
mesh.objectRegistry::write();

六、實際代碼示例:手動注冊一個對象

#include "objectRegistry.H"
#include "IOdictionary.H"// 假設 mesh 已經創建
IOdictionary transportProperties
(IOobject("transportProperties",mesh.time().constant(),   // constant 目錄mesh,                     // registryIOobject::MUST_READ,IOobject::NO_WRITE)
);// 此時 transportProperties 已自動注冊到 mesh 中// 查找并使用
const dictionary& muDict = mesh.lookupObject<IOdictionary>("transportProperties");
dimensionedScalar mu("mu", dimViscosity, muDict);

七、高級特性

1. 監聽對象事件(事件驅動)

objectRegistry 支持監聽對象的注冊/注銷事件,用于實現插件機制或后處理觸發。

2. 動態創建對象

可通過 objectRegistry::store() 存儲臨時對象:

mesh.store(new volScalarField(...));  // 自動注冊并管理內存

store() 會調用 checkIn() 并將所有權交給 registry。

3. 引用計數

regIOobject 使用引用計數管理內存,避免懸空指針。


八、常見問題與調試

  • 重復注冊:確保對象未被多次 checkIn
  • 找不到對象:檢查 IOobjectregistry 是否正確設置。
  • 內存泄漏:使用 store() 而非裸 new,確保自動管理。

九、總結

特性說明
核心作用管理 OpenFOAM 中所有命名對象
數據結構哈希表(名稱 → 對象指針)
生命周期通過 checkIn/checkOut 管理
I/O 支持IOobject 協同實現自動讀寫
層次結構支持嵌套注冊表(Time → mesh → fields)
查找機制lookupObject<type>(name)

十、參考源碼路徑(OpenFOAM-9)

  • src/IOObjects/IOobject/IOobject.H
  • src/IOobjects/IOobject/IOobject.C
  • src/OpenFOAM/db/objectRegistry/objectRegistry.H
  • src/OpenFOAM/db/regIOobject/regIOobject.H

通過理解 objectRegistry,你可以更好地掌握 OpenFOAM 如何管理場變量、字典、網格等對象,為開發自定義求解器或庫打下堅實基礎。

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

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

相關文章

【Hot100】貪心算法

系列文章目錄 【Hot100】二分查找 文章目錄系列文章目錄方法論Hot100 之貪心算法121. 買賣股票的最佳時機55. 跳躍游戲45. 跳躍游戲 II763. 劃分字母區間方法論 Hot100 之貪心算法 121. 買賣股票的最佳時機 121. 買賣股票的最佳時機&#xff1a;給定一個數組 prices &#…

電子電氣架構 --- 軟件項目復雜性的駕馭思路

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

SSE實時通信與前端聯調實戰

1.SSE 原理機制 sse 類似websocket,但是sse是單向的&#xff0c;不可逆的&#xff0c;只能服務端向客戶端發送數據流 2.解決跨域問題 Access to XMLHttpRequest at http://127.0.0.1:8090/sse/doChat from origin http://127.0.0.1:3000 has been blocked by CORS policy: Re…

從傳統到創新:用報表插件重塑數據分析平臺

一、傳統 BI 平臺面臨的挑戰 在當今數字化時代&#xff0c;數據已成為企業決策的重要依據。傳統的商業智能&#xff08;BI&#xff09;平臺在數據處理和分析方面發揮了重要作用&#xff0c;但隨著數據量的爆炸式增長和用戶需求的日益多樣化&#xff0c;其局限性也逐漸顯現。 …

MySQL--MySQL中的DECIMAL 與 Java中的BigDecimal

1. 為什么需要 DECIMAL在數據庫中&#xff0c;常見的數值類型有&#xff1a;INT、BIGINT → 整數&#xff0c;存儲容量有限。FLOAT、DOUBLE → 浮點數&#xff0c;存儲效率高&#xff0c;但存在精度丟失問題。DECIMAL(M, D) → 定點數&#xff0c;存儲精確值。例子&#xff1a;…

低空無人機系統關鍵技術與應用前景:SmartMediaKit視頻鏈路的基石價值

引言&#xff1a;低空經濟的新興格局 低空經濟作為“新質生產力”的代表&#xff0c;正在從政策驅動、技術突破和市場需求的共振中走向產業化。2023年&#xff0c;中國低空經濟的市場規模已超過 5000 億元人民幣&#xff0c;同比增長超過 30%。無人機&#xff08;UAV&#xff…

在Windows系統上升級Node.js和npm

在Windows系統上升級Node.js和npm&#xff0c;我推薦以下幾種方法&#xff1a; 方法1&#xff1a;使用官網安裝包&#xff08;最簡單&#xff09; 訪問 nodejs.org 下載Windows安裝包&#xff08;.msi文件&#xff09; 運行安裝包&#xff0c;選擇"修復"或直接安裝新…

【Jetson】基于llama.cpp部署gpt-oss-20b(推理與GUI交互)

前言 本文在jetson設備上使用llama.cpp完成gpt-oss 20b的部署&#xff0c;包括后端推理和GUI的可視化交互。 使用的設備為orin nx 16g&#xff08;super&#xff09;&#xff0c;這個顯存大小推理20b的模型完全沒有問題。 使用硬件如下&#xff0c;支持開啟super模式。&#…

Matplotlib 可視化大師系列(一):plt.plot() - 繪制折線圖的利刃

目錄Matplotlib 可視化大師系列博客總覽Matplotlib 可視化大師系列&#xff08;一&#xff09;&#xff1a;plt.plot() - 繪制折線圖的利刃一、 plt.plot() 是什么&#xff1f;二、 函數原型與核心參數核心參數詳解三、 從入門到精通&#xff1a;代碼示例示例 1&#xff1a;最基…

第二階段Winfrom-8:特性和反射,加密和解密,單例模式

1_預處理指令 &#xff08;1&#xff09;源代碼指定了程序的定義&#xff0c;預處理指令&#xff08;preprocessor directive&#xff09;指示編譯器如何處理源代碼。例如&#xff0c;在某些情況下&#xff0c;我們希望編譯器能夠忽略一部分代碼&#xff0c;而在其他情況下&am…

【開題答辯全過程】以 微信小程序的醫院掛號預約系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

鴻蒙ArkUI 基礎篇-06-組件基礎語法-Column/Row/Text

目錄 掌握組件寫法&#xff0c;使用組件布局界面 ArkUI與組件 先布局再內容 DevEco Studio代碼實戰 預覽效果 總結 練習 掌握組件寫法&#xff0c;使用組件布局界面 ArkUI與組件 ArkUI&#xff08;方舟開發框架&#xff09;&#xff1a;構建 鴻蒙 應用 界面 的框架 組件…

8.27 網格memo

lc329計算矩陣中最長遞增路徑長度嘗試從矩陣每個位置出發&#xff0c;int dfs() 往上下左右四個方向找嚴格遞增的路徑retmax(ret,dfs(x,y)1);return memo[i][j]ret;返回所有路徑里的最長長度 class Solution {public:int dx[4]{0,0,1,-1};int dy[4]{1,-1,0,0};int m,n;vector&l…

flume監控文件寫入 Kafka 實戰:解耦應用與消息隊列的最佳實踐

flume監控文件寫入 Kafka 實戰&#xff1a;解耦應用與消息隊列的最佳實踐 在日志采集場景中&#xff0c;直接讓應用程序通過 log4j2 寫入 Kafka 會導致應用與 Kafka 強耦合&#xff08;如 Kafka 故障可能影響應用運行&#xff09;。更優的方案是&#xff1a;應用程序將日志寫入…

從瀏覽器無法訪問到Docker容器的 FastAPI 服務地址【宿主機瀏覽器和容器不在同一個網絡層面:端口映射】

文章目錄1. 問題根源&#xff1a;Docker 網絡模型2. 解決方案&#xff1a;端口映射&#xff08;Port Mapping&#xff09;方法 1&#xff1a;重新運行容器并添加端口映射&#xff08;推薦&#xff09;方法 2&#xff1a;獲取宿主機的 IP 進行訪問&#xff08;特定情況&#xff…

線性代數中矩陣等價與離散數學中關系的閉包之間的關聯

最近在重溫線性代數時&#xff0c;學到矩陣的等價的定義及其性質&#xff0c;發現其性質與離散數學中關系的閉包所要滿足的性質非常相似&#xff0c;不由的讓人不懷疑這二者之間存在某種關聯&#xff0c;從而引發以下的思考&#xff1a;從deepseek的回答中我明白了矩陣的等價其…

從MyJUnit反思Java項目的工程實踐(版本控制篇)

從 MyJUnit 反思Java項目的工程實踐(版本控制篇) 參考資料 deepseekgithub copilotCSDN-Git代碼管理工作流程&#xff1a;GitFlow詳解Conventional Commits手冊封面來自 qwen-image 遵循 git flow 分支管理模型 Git Flow 是一種圍繞項目發布的核心分支模型, 它規定了不同的開發…

小工具推薦

小工具 ? 平時不太喜歡去搜羅一些好用的工具&#xff0c;但是看到自己感興趣的還是會記下來&#xff0c;有的是github上的開源項目&#xff0c;有的是一些直接在線的工具。主要是除了工作時間也不知道去干點什么&#xff0c;或者是和朋友玩玩游戲&#xff0c;或者是city walk…

【js】加密庫sha.js 嚴重漏洞速查

前言sha.js 是 JavaScript 生態里最常用的輕量級加密庫。它由 Browserify 社區維護&#xff0c;體積不足 20 KB&#xff0c;卻實現了 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 全系列算法&#xff0c;是 crypto-browserify、webpack、web3.js 等數百個流行包的“根依賴”。而…

FPGA入門學習路徑

FPGA入門學習路徑 專業基礎 數電&#xff08;數字電路基礎-CSDN博客&#xff09; 語法 Verilog&#xff08;Verilog硬件描述語言-CSDN博客&#xff09; VHDL&#xff08;VHDL硬件描述語言-CSDN博客&#xff09; FPGA開發流程 常用接口設計 學習目的&#xff1a;通過簡單…