OpenHarmony子系統開發 - Rust編譯構建指導

OpenHarmony子系統開發 - Rust編譯構建指導

一、Rust模塊配置規則和指導

概述

Rust是一門靜態強類型語言,具有更安全的內存管理、更好的運行性能、原生支持多線程開發等優勢。Rust官方也使用Cargo工具來專門為Rust代碼創建工程和構建編譯。 OpenHarmony為了集成C/C++代碼和提升編譯速度,使用了GN + Ninja的編譯構建系統。GN的構建語言簡潔易讀,Ninja的匯編級編譯規則直接高效。 為了在OpenHarmony中集成Rust代碼,并最大程度發揮Rust和OpenHarmony中原有C/C++代碼的交互性,采用GN作為統一構建工具,即通過GN構建Rust源碼文件(xxx.rs),并增加與C/C++互操作、編譯時lint、測試、IDL轉換、三方庫集成、IDE等功能。同時擴展gn框架,支持接口自動化轉換,最大程度簡化開發。

基本概念

術語描述
CargoCargo是Rust官方使用的構建工具,允許Rust項目聲明其各種依賴項,并確保您始終獲得可重復的構建。
cratecrate是一個獨立的可編譯單元。
LintLint是指出常見編程錯誤、錯誤、樣式錯誤和可疑結構的工具。可以對程序進行更加廣泛的錯誤分析。

配置規則

OpenHarmony提供了用于Rust代碼編譯構建的各類型GN模板,可以用于編譯Rust可執行文件,動態庫和靜態庫等。各類型模板說明如下:

GN模板功能輸出
ohos_rust_executablerust可執行文件rust可執行文件,不帶后綴
ohos_rust_shared_libraryrust動態庫rust dylib動態庫,默認后綴.dylib.so
ohos_rust_static_libraryrust靜態庫rust rlib靜態庫,默認后綴.rlib
ohos_rust_proc_macrorust proc_macrorust proc_macro庫, 默認后綴.so
ohos_rust_shared_ffirust FFI動態庫rust cdylib動態庫,給C/C++模塊調用,默認后綴.so
ohos_rust_static_ffirust FFI靜態庫rust staticlib庫,給C/C++模塊調用,默認后綴.a
ohos_rust_cargo_crate三方包Cargo craterust三方crate,支持rlib、dylib、bin
ohos_rust_systemtestrust系統測試用例rust可執行系統測試用例,不帶后綴
ohos_rust_unittestrust單元測試用例rust可執行單元測試用例,不帶后綴
ohos_rust_fuzztestrust Fuzz測試用例rust可執行Fuzz測試用例,不帶后綴

配置指導

配置Rust模塊與C/C++模塊類似,參考模塊配置規則。下面是使用不同模板的示例。

配置Rust靜態庫示例

該示例用于測試Rust可執行bin文件和靜態庫rlib文件的編譯,以及可執行文件對靜態庫的依賴,使用模板ohos_rust_executable和ohos_rust_static_library。操作步驟如下:

  1. 創建build/rust/tests/test_rlib_crate/src/simple_printer.rs,如下所示:

    //! simple_printer/// struct RustLogMessagepub struct RustLogMessage {/// i32: idpub id: i32,/// String: msgpub msg: String,
    }/// function rust_log_rlib
    pub fn rust_log_rlib(msg: RustLogMessage) {println!("id:{} message:{:?}", msg.id, msg.msg)
    }
    
  2. 創建build/rust/tests/test_rlib_crate/src/main.rs,如下所示:

    //! rlib_crate example for Rust.extern crate simple_printer_rlib;use simple_printer_rlib::rust_log_rlib;
    use simple_printer_rlib::RustLogMessage;fn main() {let msg: RustLogMessage = RustLogMessage {id: 0,msg: "string in rlib crate".to_string(),};rust_log_rlib(msg);
    }
    
  3. 配置gn腳本build/rust/tests/test_rlib_crate/BUILD.gn,如下所示:

    import("//build/ohos.gni")ohos_rust_executable("test_rlib_crate") {sources = [ "src/main.rs" ]deps = [ ":simple_printer_rlib" ]
    }ohos_rust_static_library("simple_printer_rlib") {sources = [ "src/simple_printer.rs" ]crate_name = "simple_printer_rlib"crate_type = "rlib"features = [ "std" ]
    }
    
  4. 執行編譯得到的可執行文件,運行結果如下:

    test_rlib_crate

配置三方庫示例

rust三方庫的BUILD.gn文件可通過cargo2gn工具自動生成。參見:Cargo2gn工具操作指導

該示例用于測試包含預編譯文件build.rs的三方靜態庫rlib文件的編譯,使用了模板ohos_rust_executable和ohos_rust_cargo_crate。操作步驟如下:

  1. 創建build/rust/tests/test_rlib_cargo_crate/crate/src/lib.rs,如下所示:

    include!(concat!(env!("OUT_DIR"), "/generated/generated.rs"));pub fn say_hello_from_crate() {assert_eq!(run_some_generated_code(), 45);#[cfg(is_new_rustc)]println!("Is new rustc");#[cfg(is_old_rustc)]println!("Is old rustc");#[cfg(is_ohos)]println!("Is ohos");#[cfg(is_mac)]println!("Is darwin");#[cfg(has_feature_a)]println!("Has feature_a");#[cfg(not(has_feature_a))]panic!("Wasn't passed feature_a");#[cfg(not(has_feature_b))]#[cfg(test_a_and_b)]panic!("feature_b wasn't passed");#[cfg(has_feature_b)]#[cfg(not(test_a_and_b))]panic!("feature_b was passed");
    }#[cfg(test)]
    mod tests {/// Test features are passed through from BUILD.gn correctly. This test is the target configuration.#[test]#[cfg(test_a_and_b)]fn test_features_passed_target1() {#[cfg(not(has_feature_a))]panic!("feature a was not passed");#[cfg(not(has_feature_b))]panic!("feature b was not passed");}#[test]fn test_generated_code_works() {assert_eq!(crate::run_some_generated_code(), 45);}
    }
    
  2. 創建build/rust/tests/test_rlib_cargo_crate/crate/src/main.rs,如下所示:

    pub fn main() {test_rlib_crate::say_hello_from_crate();
    }
    
  3. 創建build/rust/tests/test_rlib_cargo_crate/crate/build.rs,如下所示:

    use std::env;
    use std::path::Path;
    use std::io::Write;
    use std::process::Command;
    use std::str::{self, FromStr};fn main() {println!("cargo:rustc-cfg=build_script_ran");let my_minor = match rustc_minor_version() {Some(my_minor) => my_minor,None => return,};if my_minor >= 34 {println!("cargo:rustc-cfg=is_new_rustc");} else {println!("cargo:rustc-cfg=is_old_rustc");}let target = env::var("TARGET").unwrap();if target.contains("ohos") {println!("cargo:rustc-cfg=is_ohos");}if target.contains("darwin") {println!("cargo:rustc-cfg=is_mac");}let feature_a = env::var_os("CARGO_FEATURE_MY_FEATURE_A").is_some();if feature_a {println!("cargo:rustc-cfg=has_feature_a");}let feature_b = env::var_os("CARGO_FEATURE_MY_FEATURE_B").is_some();if feature_b {println!("cargo:rustc-cfg=has_feature_b");}// Some tests as to whether we're properly emulating various cargo features.assert!(Path::new("build.rs").exists());assert!(Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("build.rs").exists());assert!(Path::new(&env::var_os("OUT_DIR").unwrap()).exists());// Confirm the following env var is setenv::var_os("CARGO_CFG_TARGET_ARCH").unwrap();generate_some_code().unwrap();
    }fn generate_some_code() -> std::io::Result<()> {let test_output_dir = Path::new(&env::var_os("OUT_DIR").unwrap()).join("generated");let _ = std::fs::create_dir_all(&test_output_dir);// Test that environment variables from .gn files are passed to build scriptslet preferred_number = env::var("ENV_VAR_FOR_BUILD_SCRIPT").unwrap();let mut file = std::fs::File::create(test_output_dir.join("generated.rs"))?;write!(file, "fn run_some_generated_code() -> u32 {{ {} }}", preferred_number)?;Ok(())
    }fn rustc_minor_version() -> Option<u32> {let rustc_bin = match env::var_os("RUSTC") {Some(rustc_bin) => rustc_bin,None => return None,};let output = match Command::new(rustc_bin).arg("--version").output() {Ok(output) => output,Err(_) => return None,};let rustc_version = match str::from_utf8(&output.stdout) {Ok(rustc_version) => rustc_version,Err(_) => return None,};let mut pieces = rustc_version.split('.');if pieces.next() != Some("rustc 1") {return None;}let next_var = match pieces.next() {Some(next_var) => next_var,None => return None,};u32::from_str(next_var).ok()
    }
    
  4. 配置gn腳本build/rust/tests/test_rlib_cargo_crate/BUILD.gn,如下所示:

    import("//build/templates/rust/ohos_cargo_crate.gni")ohos_cargo_crate("target") {crate_name = "test_rlib_crate"crate_root = "crate/src/lib.rs"sources = [ "crate/src/lib.rs" ]#To generate the build_script binarybuild_root = "crate/build.rs"build_sources = [ "crate/build.rs" ]build_script_outputs = [ "generated/generated.rs" ]features = ["my-feature_a","my-feature_b","std",]rustflags = ["--cfg","test_a_and_b",]rustenv = [ "ENV_VAR_FOR_BUILD_SCRIPT=45" ]
    }# Exists to test the case that a single crate has both a library and a binary
    ohos_cargo_crate("test_rlib_crate_associated_bin") {crate_root = "crate/src/main.rs"crate_type = "bin"sources = [ "crate/src/main.rs" ]#To generate the build_script binarybuild_root = "crate/build.rs"build_sources = [ "crate/build.rs" ]features = ["my-feature_a","my-feature_b","std",]rustenv = [ "ENV_VAR_FOR_BUILD_SCRIPT=45" ]deps = [ ":target" ]
    }
    
  5. 執行編譯得到的可執行文件,運行結果如下:

    test_rlib_cargo_crate

其他源碼實例

在build/rust/tests目錄下有Rust各類型模塊的配置實例可供參考:

用例目錄測試功能
build/rust/tests/test_bin_crate用ohos_rust_executable模板在host平臺編譯可執行文件,在target平臺上運行可執行文件。
build/rust/tests/test_static_link測試可執行文件對標準庫的靜態鏈接。
build/rust/tests/test_dylib_crate測試對動態庫的編譯和動態鏈接功能
build/rust/tests/test_rlib_crate測試對靜態庫的編譯和靜態鏈接功能
build/rust/tests/test_proc_macro_crate測試對Rust過程宏的編譯和鏈接功能。提供對不同類型的宏的測試用例。
build/rust/tests/test_cdylib_crate測試將Rust代碼編譯成C/C++動態庫。
build/rust/tests/test_staticlib_crate測試將Rust代碼編譯成C/C++靜態庫。
build/rust/tests/rust_test_ut測試Rust代碼單元測試模板功能(ability)。
build/rust/tests/rust_test_st測試Rust代碼系統測試模板功能(ability)。
build/rust/tests/test_bin_cargo_crate測試Rust三方可執行文件的編譯和運行。三方源碼中包含build.rs。
build/rust/tests/test_rlib_cargo_crate測試Rust三方靜態庫的編譯和靜態鏈接。三方源碼中包含build.rs。
build/rust/tests/test_proc_macro_cargo_crate測試Rust三方過程宏的編譯和鏈接。三方源碼中包含build.rs。
build/rust/tests/rust_test_fuzzb測試Rust代碼Fuzz測試模板功能。

參考

特性點實例

Rust源碼依賴調用C/C++庫

OpenHarmony上C/C++模塊動態庫默認用.z.so后綴,但是Rust的編譯命令通過-l鏈接時,默認只會鏈接.so后綴的動態庫。因此如果要依賴一個C/C++動態庫編譯模塊,需要在該動態庫的GN構建文件中添加output_extension = "so"的聲明,這樣編譯得到的動態庫將會以".so"作為后綴,而不是".z.so"。 在Rust源碼中如果直接鏈接動態庫,后綴也需要使用".so",這時使用動態庫的中間名,不需要添加lib前綴。例如Rust源碼中鏈接libhilog.so:

#[link(name = "hilog")]
externs使用

某個模塊如果依賴二進制的rlib庫,可以使用externs屬性:

executable("foo") {sources = [ "main.rs" ]externs = [{                    # 編譯時會轉成`--extern bar=path/to/bar.rlib`crate_name = "bar"path = "path/to/bar.rlib"}]
}

Lint規則

OpenHarmony框架支持rustc lints和clippy lints兩種Lint,每種Lint劃為三個等級的標準:"openharmony"、"vendor"和"none",嚴格程度按照"openharmony" -> "vendor" -> "none"逐級遞減。 配置Rust模塊時可以通過rustc_lints和clippy_lints來指定使用Lint的等級。 模塊中沒有配置rustc_lints或者clippy_lints時會根據模塊所在路徑來匹配lints等級。不同路徑下的Rust代碼的語法規范會有不同程度地約束,因此用戶在OpenHarmony配置Rust代碼編譯模塊時還應關注模塊所在路徑。

rustc lints和clippy lints的各等級標志
lints類型模塊屬性lints等級lints等級標志lints內容
rustc_lintsrustc_lintsopenharmonyRustOhosLints"-A deprecated", "-D missing-docs", "-D warnigngs"
rustc_lintsrustc_lintsvendorRustcVendorLints"-A deprecated", "-D warnigs"
rustc_lintsrustc_lintsnoneallowAllLints"-cap-lints allow"
clippy lintsclippy lintsopenharmonyClippyOhosLints"-A clippy::type-complexity", "-A clippy::unnecessary-wraps", "-A clippy::unusual-byte-groupings", "-A clippy::upper-case-acronyms"
clippy lintsclippy lintsvendorClippyVendorLints"-A clippy::complexity", "-A Clippy::perf", "-A clippy::style"
clippy lintsclippy lintsnoneallowAllLints"--cap-lints allow"
代碼路徑與lints等級的對應關系
路徑Lints等級
thirdpartynone
prebuiltsnone
vendorvendor
devicevendor
othersopenharmony

交互工具使用指導

Cargo2gn工具操作指導

二、Rust 工具鏈使用說明

簡介

本文用于指導 Rust 語言開發者編譯構建 OpenHarmony OS Rust 應用程序。

Rust 是一門靜態強類型語言,具有更安全的內存管理、更好的運行性能、原生支持多線程開發等優勢。

本工具鏈基于開源 rust 與 llvm 增量開發,適配了 OpenHarmony OS target 二進制構建。可將 rust 源碼編譯成能在 OpenHarmony OS 設備上使用的目標二進制。

使用場景

  • 在 Linux x86環境本地編譯 Linux x86 目標二進制或交叉編譯 OpenHarmony OS 目標二進制。
  • 在 Mac x86 環境本地編譯 Mac x86 目標二進制。
  • 在 Mac arm64 環境本地編譯 Mac arm64 目標二進制。

操作指導

OpenHarmony 社區代碼編譯

  1. 下載或更新環境中 OpenHarmony 社區代碼,下載方式可參考獲取源碼。

  2. 執行源碼中腳本下載安裝工具鏈。

    ./build/prebuilts_download.sh
    
  3. 準備待編譯代碼。

    創建 build/rust/tests/test_bin_crate 目錄,目錄下新建如下所示文件與文件夾。

    ├── BUILD.gn
    └── src└── main.rs
    

    main.rs 代碼示例。

    //! Hello world example for Rust.fn main() {println!("Hello, world!");println!(env!("RUSTENV_TEST"));
    }
    

    BUILD.gn 代碼示例。

    import("//build/ohos.gni")ohos_rust_executable("test_bin_crate") {sources = [ "src/main.rs" ]rustenv = [ "RUSTENV_TEST=123" ]features = [ "std" ]if (is_mingw) {rust_static_link = true}
    }
    
  4. 執行編譯命令。

    ./build.sh --product-name {product_name} --build-target
    

    以RK3568為例,若要編譯,請執行如下命令。

    ./build.sh --product-name rk3568 --build-target build/rust/tests/test_bin_crate:test_bin_crate –no-prebuilt-sdk
    

    編譯生成的文件。

    ./out/rk3568/build/build_framework/test_bin_crate
    

非OpenHarmony 社區代碼編譯

安裝 rust 工具鏈
  1. 下載 build 倉代碼。

    git clone git@gitee.com:openharmony/build.git
    
  2. 執行腳本下載安裝工具鏈。

    ./build/prebuilts_download.sh
    
  3. 查看安裝情況。

    ./prebuilts/rustc/linux-x86_64/current/bin/rustc --version
    

    有類似如下顯示表示安裝成功。

    rustc 1.72.0-nightly (xxxx)
    
安裝 OpenHarmony OS Clang 工具

icon-note

說明

用于在 Linux x86 環境下進行 OpenHarmony OS 的 target 交叉編譯,不編譯 OpenHarmony OS target 可不安裝。

  1. 在 OpenHarmony 的最新版本說明中獲取 SDK 包下載路徑

    ohos_sdk_download

  2. 選擇 Linux 環境 SDK 包下載,依次解壓下載的壓縮包。

    mv ohos-sdk-windows_linux-public.tar.gz /opt/
    cd /opt/
    tar -zxvf ohos-sdk-windows_linux-public.tar.gz
    cd ohos-sdk/linux
    unzip native-linux-x64-4.1.7.5-Release.zip
    
編譯代碼
  1. 代碼用例main.rs。

    fn main() {println!("hello world");
    }
    
  2. 編譯 target 為本地環境時命令示例。

    ./prebuilts/rustc/linux-x86_64/current/bin/rustc main.rs
    

    執行構建結果。

    ./main
    hello world
    
  3. 編譯 target 為 armv7-unknown-linux-ohos時命令示例。

    ./prebuilts/rustc/linux-x86_64/current/bin/rustc main.rs --target=armv7-unknown-linux-ohos -C linker=/opt/ohos-sdk/linux/native/llvm/bin/armv7-unknown-linux-ohos-clang
    
  4. 編譯 target 為 aarch64-unknown-linux-ohos時命令示例。

    ./prebuilts/rustc/linux-x86_64/current/bin/rustc main.rs --target=aarch64-unknown-linux-ohos -C linker=/opt/ohos-sdk/linux/native/llvm/bin/aarch64-unknown-linux-ohos-clang
    
  5. 編譯 target 為 x86_64-unknown-linux-ohos時命令示例。

    ./prebuilts/rustc/linux-x86_64/current/bin/rustc main.rs --target=x8

三、Cargo2gn工具操作指導

概述

rust三方庫使用cargo編譯,配置為Cargo.toml。集成到OpenHarmony上需要轉換成BUILD.gn規則。為了滿足這個需求,需要提供一個cargo2gn轉換工具。當需要引入rust三方crate時使用cargo2gn轉換工具來把三方庫的Cargo.toml轉換成BUILD.gn規則。cargo2gn可以單個庫進行轉換,也可以多個庫進行批量轉換。

單個庫轉換操作步驟

  1. 進入到需要轉化的rust三方庫的目錄下,比如需要轉化bindgen。

    cd openharmony/third_party/rust/bindgen
    
  2. 創建配置文件cargo2gn.json,可以參考如下配置。

    {"copy-out": true,"run": true,"add-workspace": true,"cargo-bin": "/mnt/xxx/openharmony/prebuilts/rustc/linux-x86_64/current/bin"
    }
    
  3. 執行以下命令進行轉換。

    python3 /mnt/xxx/openharmony/build/scripts/cargo2gn.py --config cargo2gn.json
    

    轉換結果

    import("//build/templates/rust/ohos_cargo_crate.gni")ohos_cargo_crate("lib") {crate_name = "bindgen"crate_type = "rlib"crate_root = "./lib.rs"sources = ["./lib.rs"]edition = "2018"cargo_pkg_version = "0.64.0"cargo_pkg_authors = "Jyun-Yan You <jyyou.tw@gmail.com>,  Emilio Cobos álvarez <emilio@crisal.io>,  Nick Fitzgerald <fitzgen@gmail.com>,  The Servo project developers"cargo_pkg_name = "bindgen"cargo_pkg_description = "Automatically generates Rust FFI bindings to C and C++ libraries."deps = ["//third_party/rust/bitflags:lib","//third_party/rust/cexpr:lib","//third_party/rust/clang-sys:lib","//third_party/rust/lazy_static:lib","//third_party/rust/lazycell:lib","//third_party/rust/log:lib","//third_party/rust/peeking_take_while:lib","//third_party/rust/proc-macro2:lib","//third_party/rust/quote:lib","//third_party/rust/regex:lib","//third_party/rust/rustc-hash:lib","//third_party/rust/shlex:lib","//third_party/rust/syn:lib","//third_party/rust/which:lib",]features = ["default","log","logging","static","which","which-rustfmt",]build_root = "build.rs"build_sources = ["build.rs"]build_script_outputs = ["host-target.txt"]
    }
    

多個庫批量轉換操作步驟

  1. 進入到rust目錄下。

    cd openharmony/third_party/rust
    
  2. 把所有需要轉換的rust三方庫添加到rust目錄下的Cargo.toml的[workspace]里,如下所示。

    [workspace]
    members = ["aho-corasick","memchr",
    ]
    
  3. 執行單個庫轉換操作步驟的2和3。

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

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

相關文章

【SpringMVC】常用注解:@ModelAttribute

1.作用 該注解是在SpringMVC4.3版本后新加入的。它可以修飾方法和參數。出現在方法上&#xff0c;表示當前方法會在控制器的方法之前執行。它可以修飾 沒有返回值的方法&#xff0c;也可以修飾沒有返回值的方法。它修飾參數&#xff0c;獲取指定 的數據給參數賦值。 當表單提…

人工智能之數學基礎:如何將線性變換轉換為矩陣?

本文重點 在機器學習中,常用的理論就是線性變換,線性變化一定有對應的矩陣表示,非線性變換是不具備這個性質的,那么現在如果有一個線性變換T那么如何知道它對應的矩陣呢? 線性變換的本質 我們知道線性變換相當于一個函數,而矩陣也是一個函數,所以線性變換一定存在一個…

STM32驅動代碼規范化編寫指南(嵌入式C語言方向)

點擊下面圖片&#xff0c;為您提供全新的嵌入式學習路線 文章目錄 一、命名規范體系1.1 變量/函數命名1.2 宏定義規范1.3 類型定義 二、代碼結構組織2.1 文件組織結構2.2 頭文件規范模板 三、注釋體系構建3.1 Doxygen風格示例3.2 復雜邏輯注釋 四、硬件抽象層設計4.1 寄存器封…

C++Primer學習(7.1 定義抽象數據類型)

類的基本思想是數據抽象(data abstraction)和封裝(encapsulation)。數據抽象是種依賴于接口(interface)和實現(implementation)分離的編程(以及設計)技術。類的接口包括用戶所能執行的操作:類的實現則包括類的數據成員、負責接口實現的函數體以及定義類所需的各種私有函數。 封…

【人工智能】大語言模型學習大綱

大語言模型學習大綱 大語言模型學習知識點大綱一、基礎知識準備二、機器學習入門三、自然語言處理(NLP)基礎四、Transformer架構與實踐五、高級主題六、前沿研究與實戰項目 學習步驟第一步&#xff1a;打牢基礎第二步&#xff1a;掌握機器學習與深度學習基礎第三步&#xff1a;…

Trae與Builder模式初體驗

說明 下載的國際版&#xff1a;https://www.trae.ai/ 建議 要選新模型 效果 還是挺不錯的&#xff0c;遇到問題反饋一下&#xff0c;AI就幫忙解決了&#xff0c;真是動動嘴&#xff08;打打字就行了&#xff09;&#xff0c;做些小的原型效果或演示Demo很方便呀&#xff…

基于VM的CentOS 7.4系統安裝與配置說明系統環境主機系統

系統環境 主機系統&#xff1a;Windows 11虛擬機版本&#xff1a;VMware Workstation 17 ProDVD鏡像版本&#xff1a;CentOS-7-x86_64-DVD-1908 虛擬機配置 內存&#xff1a;1G處理器&#xff1a;1核硬盤&#xff1a;80G 安裝步驟 1. 準備鏡像文件 下載并獲取CentOS 7.4的…

【設計模式】《設計模式:可復用面向對象軟件的基礎》:設計模式怎樣解決設計問題?

文章目錄 ?前言?一、設計模式怎樣解決設計問題&#xff1f;&#x1f31f;1、尋找合適的對象&#x1f31f;2、決定對象的粒度&#x1f31f;3、指定對象接口&#x1f31f;4、描述對象的實現&#x1f31f;5、運用復用機制?(1)針對接口編程&#xff0c;而不是針對實現編程。?(2…

【SpringMVC】常用注解:@MatrixVariable

1.作用 接收矩陣變量傳送的值 或許有人聽都沒聽過矩陣變量是什么&#xff0c;下面來介紹一下 矩陣變量是一種在URL路徑中傳遞多個鍵值對參數的方式&#xff0c;它是在 Servlet 規范之外的一種擴展機制&#xff0c;可用于更靈活地傳遞參數。 例如&#xff1a;/cars;colorred…

【項目管理git】git學習

ps&#xff1a;所有東西都是個人理解 文章目錄 一、git是什么&#xff0c;它用來做什么&#xff1f;二、相關知識庫2.1 簡單的linux指令2.2 git配置指令2.3 git常見的指令2.3.1 Git的上傳原理2.3.2 版本回退相關內容 2.4 設置遠程地址&#xff0c;本地上傳到github2.4.1 ssh相…

【性能優化】MySQL 生產環境 SQL 性能優化實戰案例

&#x1f680; MySQL 生產環境 SQL 性能優化實戰案例 &#x1f3d7;? 背景介紹 最近在處理一個項目時&#xff0c;發現在生產環境的工作流相關接口中&#xff0c;某些查詢的執行時間異常緩慢&#xff0c;盡管數據量僅為 2 萬條。經過分析&#xff0c;發現以下 SQL 語句執行非…

python速通小筆記-------1.容器

1.字符串的標識 字符串需要用“”標識。 與c不同&#xff0c;python 寫變量時 不需要標明數據類型每一行最后不需要加&#xff1b; 2.print函數的使用 與c中的printf函數一致 3.運算符 4.字符串str操作 1. 實現字符串拼接 2.% 實現字符串初始化 %s占位會把變量強制轉變為…

【SpringMVC】常用注解:@SessionAttributes

1.作用 用于多次執行控制器方法間的參數共享 2.屬性 value&#xff1a;用于指定存入的屬性名稱 type&#xff1a;用于指定存入的數據類型 3.示例 先寫JSP代碼 <a href"demo1/putMethod">存入 SessionAttribute</a><br><a href"demo…

零基礎上手Python數據分析 (2):Python核心語法快速入門

寫在前面 場景:每周銷售數據報表整理 任務描述: 你需要每周從多個Excel文件中匯總銷售數據,計算各項指標(銷售額、訂單量、客單價等),并生成周報。Excel操作痛點: 文件太多,手動打開復制粘貼,效率低下,容易出錯。 多個Excel文件,每個都要打開、篩選、復制數據,重復…

【PHP】獲取PHP-FPM的狀態信息

文章目錄 一、前言二、環境三、過程1&#xff09;修改PHP-FPM配置文件2&#xff09;修改Nginx配置文件3&#xff09;訪問頁面4&#xff09;修改狀態頁面端口 一、前言 PHP-FPM內置有一個狀態頁面&#xff0c;通過這個頁面可以獲取到FPM的一些狀態信息&#xff08;見下圖&#…

CCF CSP 第30次(2023.09)(2_坐標變換(其二)_C++)

CCF CSP 第30次&#xff08;2023.09&#xff09;&#xff08;2_坐標變換&#xff08;其二&#xff09;_C&#xff09; 題目背景&#xff1a;題目描述&#xff1a;輸入格式&#xff1a;輸出格式&#xff1a;樣例輸入&#xff1a;樣例輸出&#xff1a;樣例解釋&#xff1a;子任務…

搭建Spring Boot Admin監控系統

什么是Spring Boot Admin Spring Boot Admin 是一個用于管理和監控 Spring Boot 應用程序的開源工具。它提供了一個用戶友好的 Web 界面&#xff0c;用于集中管理和監控多個 Spring Boot 應用程序的運行狀態、健康狀況、日志、配置等信息。 Spring Boot Admin 的核心功能 應用…

機器學習中的激活函數是什么起什么作用

在機器學習&#xff0c;尤其是神經網絡中&#xff0c;?激活函數?&#xff08;Activation Function&#xff09;是一個非常重要的組件。它的主要作用是為神經網絡引入非線性&#xff0c;從而使神經網絡能夠學習和表示復雜的模式或函數。 1.激活函數的定義 激活函數是一個數學…

[CISCN 2022 初賽]ezpop(沒成功復現)

打開在線環境可以看到&#xff1a; 記得之前做過一個類似的就是有點像照著漏洞去復現。應該可以直接在網上找到鏈子去打。 www.zip查看路由是 Index/test&#xff0c;然后 post 傳參 a&#xff1a; exp&#xff08;參考了別的大神的wp&#xff09;&#xff1a; <?php //…

C 語 言 --- 二 維 數 組 的 應 用

C 語 言 --- 二 維 數 組 的 應 用 第 一 題 - - - 冒 泡 排 序冒 泡 排 序冒 泡 排 序 的 原 理 第 二 題 - - - 回 型 矩 陣特 點 第 三 題 - - - 蛇 形 矩 陣總結 &#x1f4bb;作者簡介&#xff1a;曾 與 你 一 樣 迷 茫&#xff0c;現 以 經 驗 助 你 入 門 C 語 言 &…