Rust 跨平臺-Android 和鴻蒙 OS

1. 安裝 rustup

rustup 是 Rust 的安裝和版本管理工具

$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

該命令會安裝 rusup 和最新的穩定版本的 Rust;包括:

  • rustc Rust 編譯器,用于將 Rust 代碼編譯成可執行文件或庫。

  • cargo Rust 的包管理器和構建工具,用于管理項目依賴、編譯項目、運行測試等。

  • rustfmt 代碼格式化工具,用于自動格式化 Rust 代碼以符合官方風格指南。

  • clippy 靜態分析工具,用于捕捉常見錯誤和改進代碼質量。

  • 其他工具,如rustdoc用于生成文檔等。

成功后控制臺會輸出:Rust is installed now. Great!

macOS 系統上需要安裝:xcode-select --install

cargo 在開發中較為常用,算是打交道最多的工具之一

2. 標準庫 Rust Standard Library

標準庫是 Rust 編程語言的官方庫,提供了一系列預先編寫好的類型和函數,用來處理常見的任務,如:

  1. 基本數據類型(比如i32u64f32等)。

  2. 集合類型(如Vec<T>HashMap<K, V>等)。

  3. 輸入/輸出(I/O)操作,包括文件操作和網絡編程。

  4. 線程和并發編程工具。

  5. 其他有用的工具,如字符串處理、日期和時間操作等。

渠道

通常情況下安裝 rustup 的時候,標準庫就已經安裝到本地;但是 rust 有幾種發布渠道,用于提供不同穩定程度的 Rust 版本,Rust 的三個主要發布渠道是:

  1. Stable(穩定版):這是大多數用戶推薦使用的版本。它每六周發布一次,提供最新的功能和改進,但只包括那些經過充分測試和認為穩定的特性。

  2. Beta(測試版):這個版本比 Stable 新,但可能包含一些即將納入下一個 Stable 版本的特性和改進。它主要用于測試即將發布的功能,以確保它們在正式成為穩定版之前沒有問題。

  3. Nightly(每夜構建版):這是最前沿的版本,包括了所有最新開發的特性。這些特性可能未完全穩定或待評估,因此這個版本主要用于實驗和評估最新的語言改進。Nightly 版本,顧名思義,每夜更新一次,包括最新的代碼提交。

安裝

  • 列出已安裝的版本

rustup toolchain list
  • 安裝新的版本

rustup toolchain install beta

或者

rustup toolchain install nightly

切換版本

切換全局(即默認)Rust 版本,使用rustup default命令:

rustup default stable
rustup default beta
rustup default nightly

這些命令會將你的系統默認 Rust 版本切換為相應的版本。

特定項目切換版本

如果你只想為特定的項目切換 Rust 版本,而不影響全局設置,可以在項目目錄內使用以下命令設置目錄級別的默認版本:

rustup override set stable
rustup override set beta
rustup override set nightly

補裝標準庫源碼

rustup component add rust-src

每一個 toolchain 都有自己的源碼

建議安裝 stable 和 nightly 的源碼,因為只有 nightly 版本支持編譯鴻蒙系統

如果不安裝后續鴻蒙 OS 下編譯會報錯,根據提示安裝也行

為特定目標平臺編譯代碼

在 stable 下,rust 支持 android 平臺的編譯,通過 rustup target list |grep android 可以查看支持的所有平臺架構

% rustup target list |grep android                                                                                                                                                    24-03-19 - 15:46:34
aarch64-linux-android (installed)
arm-linux-androideabi (installed)
armv7-linux-androideabi (installed)
i686-linux-android (installed)
thumbv7neon-linux-androideabi (installed)
x86_64-linux-android (installed)

如果已安裝,后面會有 (installed) 標識;建議一次性都安裝上:

rustup target add aarch64-linux-android arm-linux-androideabi armv7-linux-androideabi i686-linux-android thumbv7neon-linux-androideabi x86_64-linux-android

鴻蒙 OS 下需要切換到 nightly,通過 rustup target list |grep ohos 可以查看支持的所有平臺架構:

% rustup target list |grep ohos                                                         
aarch64-unknown-linux-ohos (installed)
armv7-unknown-linux-ohos (installed)
x86_64-unknown-linux-ohos (installed)

同樣,建議一次性都安裝上

3. 創建 Rust Library 工程

使用命令行創建:

cargo new demo --lib

或者使用 IDE,推薦使用 Jetbrains 的 RustRover

此時目錄結構如下:

demo
├── Cargo.toml
└── src└── lib.rs

Cargo.toml 的配置

[lib]

[lib]
crate-type = ["cdylib"]

crate-type屬性用于指定編譯目標類型。這些類型決定了編譯器會如何編譯你的代碼。以下是一些常見的crate-type值及其區別:

1. bin

  • 描述:一個可執行的二進制文件。

  • 使用場景:當你想要創建一個可以直接運行的程序時,使用此類型。大多數應用程序都是以bin類型編譯的。

2. lib

  • 描述:一個庫文件,可以被其他 Rust 包作為依賴使用。

  • 使用場景:如果你正在開發一個提供函數、類型或特性給其他包使用的庫,應選擇此類型。

3. rlib

  • 描述:Rust 編譯的庫文件,包含元數據和符號,供后續的 Rust 編譯階段使用。

  • 使用場景:當你想要編譯一個 Rust 庫供其他 Rust 項目使用,并期望進行鏈接和代碼生成優化時。

4. dylib

  • 描述:一個動態鏈接庫(DLL),可以在運行時被 Rust 或其他語言的應用程序動態鏈接。

  • 使用場景:當你想要創建一個可以被多個程序共享的庫,或者當你需要和其他使用動態鏈接的語言互操作時。

5. cdylib

  • 描述:一個為 C 語言接口定制的動態鏈接庫。它移除了 Rust 特有的元數據,只保留了可以從 C 或其他語言調用的符號。

  • 使用場景:當你開發一個 Rust 庫,希望能夠被 C 或其他語言作為動態鏈接庫使用時。這是創建跨語言共享庫的常見方式。

6. staticlib

  • 描述:靜態庫(.a文件),可以被 C 語言或其他語言的應用程序在編譯時靜態鏈接。

  • 使用場景:如果你想要創建一個可以被其他語言靜態鏈接的庫,或希望你的 Rust 代碼被編譯進一個單獨的二進制文件,而不依賴于 Rust 的運行時或其他動態庫。

7. proc-macro

  • 描述:一個過程宏庫,用于創建自定義#[derive]宏或其他類型的宏。

  • 使用場景:當你想要創建新的宏來擴展 Rust 語法,比如自定義派生屬性或宏指令時。

[dependencies] 和 [features]

由于需要區分 android 和 ohos 兩個平臺的特定庫,所以有一些依賴庫需要配置為可選的,然后使用 cargo 構建的時候添加 --features 參數來分別進行交叉編譯

對于 android 平臺,需要引入 jni 庫,來和 java/kotlin 互相調用

rustnode 互相調用可以使用 node-bindgen,但遺憾的是,node-bindgen并不兼容鴻蒙系統;不過已經有人基于node-bindgen兼容了 ohos:https://crates.io/crates/ohos-node-bindgen

對于 ohos 平臺,需要引入 ohos-node-bindgen 庫,來和 node 通信;由于 ohos-node-bindgen 依賴 socket2,然而 socket2ohos 下有 bug,所以這里需要使用https://github.com/stuartZhang/socket2.git 來替換 ohos-node-bindgen 內部依賴的socket2版本

最終配置如下

[features]
default = ["android"]
android = ["dep:jni", "dep:android_logger"]
ohos = ["dep:ohos-node-bindgen", "dep:socket2"][dependencies]
jni = { version = "0.19.0", optional = true }
android_logger = { version = "0.13.3", optional = true }
ohos-node-bindgen = { version = "6.0.3", optional = true }
socket2 = { version = "0.4.10", optional = true }
dashmap = "5.5.3"
threadpool = "1.8.1"
log = "0.4.21"[patch.crates-io]
socket2 = { version = "0.4.10", git = "https://github.com/stuartZhang/socket2.git", branch = "v0.4.x" }

也就是說:

  • dashmapthreadpoollog 是所有平臺下都參與編譯的庫

  • android 單獨編譯:jniandroid_logger

  • ohos 單獨編譯:ohos-node-bindgensocket2

  • 另外,features 的默認值為 android

編寫代碼 - lib.rs

由于存在不同的 features,所以對于 android:

#[cfg(feature = "android")]
#[no_mangle]
pub extern "system" fn Java_com_haier_uhome_uplus_hook_monitor_app_NativeLib_hello(env: JNIEnv,_class: JClass,
) -> jstring {// 將 Rust 字符串轉換為 JNI 字符串let result = env.new_string("Hello from Rust!").expect("Couldn't create Java string!");// 返回結果result.into_inner()
}

#[cfg(feature = "android")]:與上述 features 對應

#[no_mangle] 則是禁用駝峰警告

對于 ohos:

#[cfg(feature = "ohos")]
#[ohos_node_bindgen]
pub extern "C" fn add(l: i32, r: i32) -> i32 {l + r
}

#[cfg(feature = "ohos")]:與上述 features 對應

#[ohos_node_bindgen] 則是標識 add 函數可以被 node 端調用

node-bindgen 的大致原理如下:

1. FFI(外部函數接口)

Node.js 的原生模塊基于 C++ 和 Node.js 的 N-API(原生 API),N-API 提供了一套與 V8 引擎解耦的接口,使原生模塊在 Node.js 版本升級時保持兼容。node-bindgen 底層利用 Rust 的外部函數接口(FFI)能力,通過這些接口與 Node.js 通信。

Rust 的 FFI 功能允許其調用 C 語言 API。因此,node-bindgen 實際上是通過 Rust 的 FFI 調用 Node.js 的 N-API 來創建和管理 JavaScript 值,以及執行與 JavaScript 環境的交互。

2. 宏和屬性

node-bindgen 提供了一系列宏(例如 #[node_bindgen]),這些宏在編譯時自動生成將 Rust 函數暴露為 Node.js 可調用函數的膠水代碼。這個過程包括自動生成用于參數轉換和返回值處理的代碼,使 Rust 函數能夠直接接收來自 JavaScript 的參數并返回可以直接在 JavaScript 中使用的結果。

3. 內存管理

Rust 和 JavaScript 之間的內存管理是 node-bindgen 的關鍵部分。Rust 有自己的內存管理規則,主要基于所有權和生命周期,而 JavaScript 的內存則由垃圾收集器自動管理。node-bindgen 必須確保在這兩種內存管理模型之間正確地橋接,包括處理 Rust 中的數據所有權轉移和確保 JavaScript 對象在需要時保持存活。

4. 異步操作

Node.js 廣泛使用異步操作,而 Rust 也有強大的異步支持。node-bindgen 支持將 Rust 的異步操作暴露給 Node.js。這通過將 Rust 的 Future 轉換為 Node.js 的 Promise 來實現。node-bindgen 會自動處理這種轉換,允許開發者以 Promise 的形式在 JavaScript 中接收 Rust 異步操作的結果。

5. 類型轉換

node-bindgen 自動處理 Rust 類型和 JavaScript 類型之間的轉換。對于簡單類型(如數字和字符串),這通常是直接的。但對于復雜類型(如結構體或枚舉),node-bindgen 生成的代碼會負責序列化和反序列化操作,確保兩種語言之間可以無縫交換復雜數據結構。

總結

node-bindgen 利用 Rust 的 FFI 能力、宏系統、強類型系統和異步特性,提供了一種高效、類型安全的方式來將 Rust 代碼與 Node.js 集成。它自動處理大部分繁瑣的膠水代碼編寫工作,使得 Rust 和 Node.js 之間的交互變得更加簡單直接。這樣的設計允許開發者專注于實現應用邏輯,而無需深入底層的語言綁定細節。理解頗為淺陋,如有任何問題可私 1239604859@qq.com 討論

編譯 - android 平臺的產物

官方提供了 cargo-ndk 工具,它簡化了為 Android 使用 Rust 編寫原生代碼庫(.so 文件)的過程。

  • 下載安卓 NDK,并配置到環境變量

export ANDROID_HOME=$HOME/ssd/Android/sdk
PATH="$ANDROID_HOME/ndk-bundle:$PATH"
export PATH
  • 安裝 cargo-ndk

cargo install cargo-ndk
  • 使用 cargo-ndk 構建你的項目

cargo ndk -t armv7-linux-androideabi -t aarch64-linux-android -o ../../MonitorTestClient/app/src/main/jniLibs build --release
  • 參數解釋

    • -t--target:指定目標架構

    • -o--output:指定輸出目錄,這里的目錄會用于存放編譯生成的 .so 文件

    • build:是 cargo 的子命令,用于編譯項目,會傳遞它以及任何附加參數給 cargo build

編譯 - ohos 平臺的產物

官方沒有為鴻蒙系統提供類似cargo-ndk的工具,需要手動配置編譯參數

1. 首先切換到 nightly 渠道

rustup override set nightly

2. 配置環境變量:

# huawei
export OHOS_HOME=$HOME/ssd/huawei/sdk
export OHOS_API_V=9
export OHOS_CORE_V=3.1.0
export OH_NDK_ROOT=$OHOS_HOME/openharmony/$OHOS_API_V/native
PATH="$OHOS_HOME/hmscore/$OHOS_CORE_V/toolchains:$PATH"
export PATH

單獨配置 OHOS_API_V 的好處是如果華為更新了 Native SDK,可以更方便的動態切換

3. 創建 ohos 對應 target 的可執行腳本,例如和config.toml中 [target.aarch64-unknown-linux-ohos] 對應

  • 創建位置:~/.cargo

  • aarch64-unknown-linux-ohos-clang.sh

#!/bin/sh
. $HOME/.bash_profile
exec $OH_NDK_ROOT/llvm/bin/clang \-target aarch64-linux-ohos \--sysroot=$OH_NDK_ROOT/sysroot \-D__MUSL__ \"$@"
  • armv7-unknown-linux-ohos-clang.sh

#!/bin/sh
. $HOME/.bash_profile
exec $OH_NDK_ROOT/llvm/bin/clang \-target arm-linux-ohos \--sysroot=$OH_NDK_ROOT/sysroot \-D__MUSL__ \-march=armv7-a \-mfloat-abi=softfp \-mtune=generic-armv7-a \-mthumb \"$@"
  • x86_64-unknown-linux-ohos-clang.sh

#!/bin/sh
. $HOME/.bash_profile
exec $OH_NDK_ROOT/llvm/bin/clang \-target x86_64-linux-ohos \--sysroot=$OH_NDK_ROOT/sysroot \-D__MUSL__ \"$@"
  • . $HOME/.bash_profile 根據實際情況進行修改,只要能拿到 $OH_NDK_ROOT 即可

4. 通用配置:config.toml

  • 創建位置:~/.cargo

# 鴻蒙編譯工具鏈-目前只能手動配置:
[target.aarch64-unknown-linux-ohos]
linker = ".cargo/aarch64-unknown-linux-ohos-clang.sh"[target.armv7-unknown-linux-ohos]
linker = ".cargo/armv7-unknown-linux-ohos-clang.sh"[target.x86_64-unknown-linux-ohos]
linker = ".cargo/x86_64-unknown-linux-ohos-clang.sh"# 會概率性地失敗于exit code: 0xc0000005, STATUS_ACCESS_VIOLATION錯誤 - https://rustcc.cn/article?id=568d35d6-b782-49e9-b9b1-5d870d28f927
[profile.dev.package.compiler_builtins]
opt-level = 2[alias]
ohos-build = ["build", "-Zbuild-std", "--target=aarch64-unknown-linux-ohos", "--target=armv7-unknown-linux-ohos", "--target=x86_64-unknown-linux-ohos"]
  • [alias] 作用是使得:

    ????cargo ohos-build --release 等價于 cargo build -Zbuild-std --target=aarch64-unknown-linux-ohos --target=armv7-unknown-linux-ohos --target=x86_64-unknown-linux-ohos --release

  • 對于我們演示的 demo 工程,最終編譯命令行如下

cargo ohos-build --release --features ohos

4. Android 工程測試 rust 產物

把動態庫拷貝到 app 模塊中

src
├── androidTest
├── main
│?? ├── jniLibs
│?? │?? ├── arm64-v8a
│?? │?? │?? └── libdemo.so
│?? │?? └── armeabi-v7a
│?? │??     └── libdemo.so

創建對應包名的單例

object NativeLib {init {System.loadLibrary("demo")}external fun hello(): Stringexternal fun mapTest()
}

在 MainActivity 中調用

val nstr = NativeLib.hello()
Log.d(TAG, "onCreate: $nstr")
2024-03-19 19:32:32.207 11941-11941 MainActivity             D  onCreate: Hello from Rust!

5. ohos 工程測試 rust 產物

把動態庫拷貝到 entry 模塊中

entry
├── build-profile.json5
├── hvigorfile.ts
├── libs
│?? ├── arm64-v8a
│?? │?? └── libdemo.so
│?? └── armeabi-v7a
│??     └── libdemo.so

在 Index.ets 中

import hello from "libdemo.so"@Entry
@Component
struct Index {@State message: string = 'Hello World';build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)Button("計 算").fontSize(50).fontWeight(FontWeight.Bold).onClick(() => {let sum = hello.add(3, 5);this.message = "3 + 5 = " + sum.toString();})}.width('100%')}.height('100%')}
}

運行結果:

? ?? ?

6. 團隊介紹

三翼鳥數字化技術平臺-智家APP平臺」通過持續迭代演進移動端一站式接入平臺為三翼鳥APP、智家APP等多個APP提供基礎運行框架、系統通用能力API、日志、網絡訪問、頁面路由、動態化框架、UI組件庫等移動端開發通用基礎設施;通過Z·ONE平臺為三翼鳥子領域提供項目管理和技術實踐支撐能力,完成從代碼托管、CI/CD系統、業務發布、線上實時監控等Devops與工程效能基礎設施搭建。

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

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

相關文章

技術速遞|Visual Studio Code 的 .NET MAUI 擴展現已正式發布

作者&#xff1a;Maddy Montaquila 排版&#xff1a;Alan Wang 今天&#xff0c;我們非常高興地宣布 .NET MAUI VS Code 擴展插件結束了預覽階段&#xff0c;并將包含一些期待已久的新功能 - 包括 XAML IntelliSense 和 Hot Reload&#xff01; 什么是 .NET MAUI 擴展插件&…

GuLi商城-商品服務-API-三級分類-刪除-頁面效果

一步步學習Vue太慢了&#xff0c;準備跳過前端的學習&#xff0c;直接使用前端完整的項目 下載依賴npm install&#xff0c;會報錯&#xff0c;排查了好久 我安裝的是Node14&#xff0c;所以必須要安裝4.14 Vscode終端輸入&#xff1a;npm install node-sass4.14 輸入&#x…

【Android面試八股文】如果需要在Activity間傳遞大量的數據怎么辦?

文章目錄 1. 使用Intent傳遞數據2. 使用靜態變量3. 使用Parcelable或Serializable接口4. 使用文件5. 使用數據庫存儲6. 使用ContentProvider7. 匿名共享內存(Ashmem)總結在Android開發中,如果需要在Activity之間傳遞大量數據,可以采取以下幾種方法: 1. 使用Intent傳遞數據…

【博士每天一篇文獻-綜述】A survey on few-shot class-incremental learning

閱讀時間&#xff1a;2023-12-19 1 介紹 年份&#xff1a;2024 作者&#xff1a;田松松&#xff0c;中國科學院半導體研究所&#xff1b;李璐思&#xff0c;老道明大學助理教授&#xff1b;李偉軍&#xff0c;中國科學院半導體研究所AnnLab&#xff1b; 期刊&#xff1a; Neu…

LearnOpenGL - Android OpenGL ES 3.0 使用 FBO 進行離屏渲染

系列文章目錄 LearnOpenGL 筆記 - 入門 01 OpenGLLearnOpenGL 筆記 - 入門 02 創建窗口LearnOpenGL 筆記 - 入門 03 你好&#xff0c;窗口LearnOpenGL 筆記 - 入門 04 你好&#xff0c;三角形OpenGL - 如何理解 VAO 與 VBO 之間的關系LearnOpenGL - Android OpenGL ES 3.0 繪制…

《Windows API每日一練》6.4 程序測試

前面我們討論了鼠標的一些基礎知識&#xff0c;本節我們將通過一些實例來講解鼠標消息的不同處理方式。 本節必須掌握的知識點&#xff1a; 第36練&#xff1a;鼠標擊中測試1 第37練&#xff1a;鼠標擊中測試2—增加鍵盤接口 第38練&#xff1a;鼠標擊中測試3—子窗口 第39練&…

3.imput 字符串常用方法 字符串倒序,切片

1.input input()函數接收一個標準輸入數據返回string類型 2.字符串常用方法 upper()將字符串中的小寫字母變為大寫 lower()大寫變小寫 len()獲取長度 count(子字符串)統計某個字符出現的次數 index(子字符串)可以返回子字符串出現的位置, rindex從右邊找 find(子字符串)可以返回…

vite-ts-cesium項目集成mars3d修改相關的包和配置參考

如果vite技術棧下使用原生cesium&#xff0c;請參考下面文件的包和配置修改&#xff0c;想用原生創建的viewer結合我們mars3d的功能的話。 1. package.json文件 "dependencies": {"cesium": "^1.103.0","mars3d": "^3.7.18&quo…

重啟ubuntu后命令行出現(initramfs),無圖形界面問題。

由于ubuntu內部軟件問題&#xff0c;需要重啟ubuntu&#xff0c;導致重啟后圖像界面消失&#xff0c;出現如下的命令行&#xff1a; (initramfs): 這里表示進入圖形界面初始化時&#xff0c;某個分區的文件損壞&#xff0c;損壞文件名稱會在上方顯示。 解決方法&#xff1a;…

深度學習 - Transformer 組成詳解

整體結構 1. 嵌入層&#xff08;Embedding Layer&#xff09; 生活中的例子&#xff1a;字典查找 想象你在讀一本書&#xff0c;你不認識某個單詞&#xff0c;于是你查閱字典。字典為每個單詞提供了一個解釋&#xff0c;幫助你理解這個單詞的意思。嵌入層就像這個字典&#xf…

Micrometer+ZipKin分布式鏈路追蹤

目錄 背景MicrometerMicrometer與ZipKin之間的關系專業術語分布式鏈路追蹤原理 ZipKin安裝下載 MicrometerZipKin 案例演示相關文獻 背景 一個系統頁面上的按鈕點擊到結果反饋&#xff0c;在微服務框架里&#xff0c;是由N個服務組成返回結果&#xff0c;中間可能經過a->b-…

【Electron】Electron入門實現

Electron 學習筆記 Electron 是一個開源框架&#xff0c;允許開發者使用網頁技術&#xff08;HTML、CSS 和 JavaScript&#xff09;來構建跨平臺的桌面應用程序。它由 GitHub 開發并維護&#xff0c;最初是為了支持開發 Atom 編輯器。Electron 結合了 Chromium&#xff08;用于…

密碼學及其應用 —— 對稱加密技術

1. 對稱加密、流加密和塊加密 1.1 對稱加密 對稱加密&#xff08;也稱為密鑰加密&#xff09;是一種加密方式&#xff0c;其中加密和解密使用相同的密鑰。這種加密方法基于二進制層面的操作&#xff0c;如XOR&#xff08;異或&#xff09;、SHIFT&#xff08;位移&#xff09;…

Redis Stream Redisson Stream

目錄 一、Redis Stream1.1 場景1&#xff1a;多個客戶端可以同時接收到消息1.1.1 XADD - 向stream添加Entry&#xff08;發消息 &#xff09;1.1.2 XREAD - 從stream中讀取Entry&#xff08;收消息&#xff09;1.1.3 XRANGE - 從stream指定區間讀取Entry&#xff08;收消息&…

【DevExpress】WPF DevExpressMVVM 24.1版本開發指南

DevExpressMVVM WPF 環境安裝 前言重要Bug&#xff08;必看&#xff09;環境安裝控件目錄Theme 主題LoginWindow 登陸窗口INavigationService 導航服務DockLayout Dock類型的畫面布局TreeView 樹狀列表注意引用類型的時候ImageSource是PresentationCore程序集的博主找了好久&am…

[筆記] keytool 導入服務器證書和證書私鑰

背景 我當前手頭已有一個服務器證書和對應的私鑰&#xff0c;現在需要轉換為 Java KeyStore 格式使用&#xff0c;找了一大圈才發現 keytool 無法直接導入服務器證書和私鑰&#xff0c;當然證書可以直接導入&#xff0c;但是私鑰是無法直接導入。找了一大圈發現可以先將服務器…

LeetCode題解:1669. 合并兩個鏈表,JavaScript,詳細注釋

原題鏈接&#xff1a; https://leetcode.cn/problems/merge-in-between-linked-lists/ 解題思路&#xff1a; 注意該題傳入的a和b是鏈表的索引&#xff0c;而不是節點的值先遍歷list1&#xff0c;找到a-1和b1節點將a-1的next指向list2的頭節點在將list2的尾節點的next指向b1節…

Navicat 外網連接 mysql (1、通過SSH方式內網訪問 2、對外開放3306端口)

1、通過SSH方式內網訪問 直接常規方式使用IP、賬號密碼連接&#xff0c;失敗 SSH方式&#xff1a; 常規 選項卡中&#xff1a;localhost錄入數據庫賬號密碼 SSH 選項卡中&#xff1a;勾選使用SSH&#xff0c;輸入服務器IP、賬號、密碼 如果出現該錯誤&#xff0c;可能是服務器…

計算機網絡重點名詞解釋整理

名詞解釋 GPTVersion 一、網絡協議 網絡協議 數據交換的規則 組成&#xff1a;語義、語法、定時 二、DHCP DHCP 動態規劃主機配置協議 作用&#xff1a;讓計算機自動獲取IP地址 特點&#xff1a;即插即用&#xff0c;不需要手動設置 三、信號的基本調制方法以及定義 …

Windows下activemq開啟jmx

1.activemq版本信息 activemq&#xff1a;apache-activemq-5.18.4 2.Windows下activemq開啟jmx 1.進入activemq conf目錄&#xff0c;備份activemq.xml文件 2.編輯activemq.xml文件&#xff0c;在broker節點增加useJmx"true" <broker xmlns"http://active…