Tauri 跨平臺開發指南及實戰:用前端技術征服桌面應用(合集-萬字長文)

厭倦了笨重的Electron應用?想要構建體積小、性能高、安全可靠的跨平臺桌面應用?Tauri將是你的不二之選!本教程帶你從入門到精通,掌握這個下一代桌面應用開發框架,并通過實戰APK分析工具項目,將理論知識轉化為實際應用。無論你是前端開發者還是Rust愛好者,這篇萬字長文都將助你快速駕馭Tauri的強大能力!

目錄

  • 什么是 Tauri
  • Tauri vs Electron
  • 環境準備
  • 創建首個 Tauri 應用
  • Tauri 架構詳解
  • 前后端通信
  • 文件系統訪問
  • 安全策略
  • 打包與發布
  • 實戰項目:APK 分析工具
  • 性能優化
  • 常見問題與解決方案
  • 擴展資源

什么是 Tauri

Tauri 是一個構建跨平臺桌面應用的現代化框架,它允許開發者使用 Web 技術(HTML、CSS、JavaScript/TypeScript)來構建應用的 UI,同時使用 Rust 作為后端來保證性能和安全性。與傳統的 Electron 不同,Tauri 應用通常更小、更快、更安全。

Tauri 的核心理念是:

  • 安全優先:精細的權限系統和嚴格的 CSP(內容安全策略)
  • 性能至上:基于 Rust 構建的高性能后端
  • 資源效率:更小的應用大小和更低的內存占用
  • 隱私保護:默認不收集任何數據

自 Tauri 2.0 起,該框架已經成熟并得到了廣泛應用,支持 Windows、macOS 和 Linux 平臺,并提供了豐富的 API 和插件生態系統。

Tauri vs Electron

特性TauriElectron
底層架構Rust + 系統 WebViewChromium + Node.js
應用大小小(~3-10MB)大(~120MB+)
內存占用
安全性高(精細權限控制)中等
生態系統增長中成熟
學習曲線陡峭(需要了解 Rust)平緩(純 JavaScript)
開發體驗需要管理前后端接口單一運行時
支持平臺Windows, macOS, LinuxWindows, macOS, Linux

環境準備

在開始使用 Tauri 前,需要配置好開發環境:

1. 安裝 Rust

# Windows/macOS/Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh# 或在 Windows 上通過安裝程序
# 訪問 https://www.rust-lang.org/tools/install 下載安裝程序

驗證安裝:

rustc --version
cargo --version

2. 安裝系統依賴

Windows

  • 安裝 Visual Studio 構建工具
  • 選擇"C++ 構建工具"
  • 安裝 WebView2

macOS

xcode-select --install

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \build-essential \curl \wget \libssl-dev \libgtk-3-dev \libayatana-appindicator3-dev \librsvg2-dev

3. 安裝 Node.js 和包管理器

推薦使用 Node.js 16+ 和 pnpm:

# 安裝 nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash# 安裝并使用 Node.js
nvm install 18
nvm use 18# 安裝 pnpm
npm install -g pnpm

4. 安裝 Tauri CLI

cargo install tauri-cli
# 或
npm install -g @tauri-apps/cli

創建首個 Tauri 應用

使用 Tauri CLI 創建項目

# 交互式創建新項目
pnpm create tauri-app my-app# 按提示選擇前端框架和配置
cd my-app

項目結構

my-app/
├── src/                 # 前端代碼
│   ├── App.vue          # Vue 主組件
│   └── main.js          # 入口點
├── src-tauri/           # Rust 后端代碼
│   ├── src/             # Rust 源碼
│   │   └── main.rs      # 程序入口
│   ├── Cargo.toml       # Rust 依賴配置
│   ├── tauri.conf.json  # Tauri 配置
│   └── build.rs         # 構建腳本
└── package.json         # 前端依賴

開發與調試

# 啟動開發模式
pnpm run tauri dev# 構建生產版本
pnpm run tauri build

Tauri 架構詳解

Tauri 采用前后端分離的架構:

  1. 前端:使用 Web 技術(Vue、React、Svelte 等)構建 UI
  2. 后端:使用 Rust 構建本地功能和系統集成
  3. 核心:WebView 窗口管理和 IPC(進程間通信)系統

關鍵概念:

  • Window:應用窗口管理
  • Command:暴露給前端的 Rust 函數
  • Event:前后端之間的消息傳遞系統
  • State:多窗口共享的狀態管理
  • Plugin:擴展 Tauri 功能的模塊

前后端通信

定義 Rust 命令

src-tauri/src/main.rs 中:

#[tauri::command]
fn hello(name: &str) -> String {format!("Hello, {}!", name)
}fn main() {tauri::Builder::default().invoke_handler(tauri::generate_handler![hello]).run(tauri::generate_context!()).expect("error while running tauri application");
}

從前端調用 Rust 函數

import { invoke } from '@tauri-apps/api/core';// 調用 Rust 命令
async function greet() {const response = await invoke('hello', { name: 'Tauri' });console.log(response); // "Hello, Tauri!"
}

在 Rust 中訪問前端狀態

#[tauri::command]
async fn save_settings(window: tauri::Window, settings: String) -> Result<(), String> {// 操作窗口window.set_title(&format!("New settings: {}", settings)).map_err(|e| e.to_string())?;// 執行其他操作Ok(())
}

事件系統

Rust 發送事件

#[tauri::command]
fn start_process(window: tauri::Window) -> Result<(), String> {// 啟動長時間運行的任務std::thread::spawn(move || {// 執行任務window.emit("process-update", Some(42)).expect("failed to emit event");});Ok(())
}

前端監聽事件

import { listen } from '@tauri-apps/api/event';// 監聽事件
const unlisten = await listen('process-update', (event) => {console.log('Got update:', event.payload);
});// 停止監聽
unlisten();

文件系統訪問

Tauri 提供了安全的文件系統訪問 API,在 Tauri 2.0 中通過插件提供:

import { writeTextFile, readTextFile } from '@tauri-apps/plugin-fs';// 讀取文件
async function readFile() {try {const contents = await readTextFile('example.txt');console.log(contents);} catch (err) {console.error('Failed to read file:', err);}
}// 寫入文件
async function writeFile() {try {await writeTextFile('output.txt', 'Hello, Tauri!');console.log('File written successfully');} catch (err) {console.error('Failed to write file:', err);}
}

安全策略

Tauri 實現了多層安全保護:

  1. 權限系統:精細控制應用可以訪問的資源

tauri.conf.json 中配置:

{"tauri": {"allowlist": {"fs": {"scope": {"allow": ["$APP/*"],"deny": ["$APP/config.json"]}},"shell": {"execute": false,"sidecar": false,"open": true}}}
}
  1. CSP:內容安全策略控制資源加載
{"tauri": {"security": {"csp": "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'"}}
}
  1. 沙箱隔離:限制應用能力

打包與發布

配置應用信息

src-tauri/tauri.conf.json 中:

{"package": {"productName": "My Tauri App","version": "1.0.0"},"build": {"distDir": "../dist","devPath": "http://localhost:5173","beforeDevCommand": "pnpm dev","beforeBuildCommand": "pnpm build"},"tauri": {"bundle": {"identifier": "com.mycompany.myapp","icon": ["icons/32x32.png","icons/128x128.png","icons/128x128@2x.png"]}}
}

構建生產版本

pnpm run tauri build

構建產物位于 src-tauri/target/release/bundle/,包括:

  • Windows: .exe, .msi
  • macOS: .app, .dmg
  • Linux: .AppImage, .deb, .rpm

自動更新

tauri.conf.json 中配置:

{"tauri": {"updater": {"active": true,"endpoints": ["https://releases.myapp.com/{{target}}/{{current_version}}"],"dialog": true,"pubkey": "YOUR_PUBLIC_KEY"}}
}

實戰項目:APK 分析工具

本節將介紹如何使用 Tauri 構建一個實際的 APK 分析工具,與本項目 apkparse-tauri 類似。
項目地址:ApkParse Github

架構設計

APK 分析工具由以下部分組成:

  1. 前端:Vue 3 + TypeScript UI
  2. 后端:Rust 處理 APK 解析
  3. 核心功能:文件解析、權限分析、簽名驗證

項目創建

# 創建 Tauri + Vue 項目
pnpm create tauri-app apk-analyzer
cd apk-analyzer

Rust 后端實現

src-tauri/src/ 中創建 APK 解析器:

// src-tauri/src/apk_parser.rs
use serde::{Serialize, Deserialize};
use std::path::Path;
use std::io::Read;
use std::fs::File;
use zip::ZipArchive;#[derive(Debug, Serialize, Deserialize)]
pub struct ApkInfo {pub package_name: String,pub version_name: String,pub version_code: String,pub permissions: Vec<String>,
}pub struct ApkParser;impl ApkParser {pub fn parse(path: &Path) -> Result<ApkInfo, String> {// 打開 APK 文件 (實際上是 ZIP 文件)let file = File::open(path).map_err(|e| format!("Failed to open APK: {}", e))?;let mut archive = ZipArchive::new(file).map_err(|e| format!("Invalid APK format: {}", e))?;// 提取 AndroidManifest.xml// 注意:實際實現需要解析二進制 AndroidManifest.xml// 這里簡化處理// 模擬解析結果Ok(ApkInfo {package_name: "com.example.app".to_string(),version_name: "1.0.0".to_string(),version_code: "1".to_string(),permissions: vec!["android.permission.INTERNET".to_string(),"android.permission.READ_EXTERNAL_STORAGE".to_string(),],})}
}

定義 Tauri 命令:

// src-tauri/src/commands.rs
use crate::apk_parser::{ApkParser, ApkInfo};
use std::path::Path;#[tauri::command]
pub fn parse_apk(path: String) -> Result<ApkInfo, String> {let path = Path::new(&path);ApkParser::parse(path)
}

注冊命令:

// src-tauri/src/main.rs
mod apk_parser;
mod commands;use commands::parse_apk;fn main() {tauri::Builder::default().invoke_handler(tauri::generate_handler![parse_apk]).run(tauri::generate_context!()).expect("error while running tauri application");
}

前端實現

創建上傳組件:

<!-- src/components/ApkUploader.vue -->
<template><div class="uploader"@dragover.prevent@drop.prevent="onFileDrop"@click="openFileDialog"><div class="upload-area"><div v-if="!isUploading"><p>拖放 APK 文件或點擊選擇</p></div><div v-else><p>分析中...</p></div></div></div>
</template><script setup>
import { ref } from 'vue';
import { invoke } from '@tauri-apps/api/tauri';
import { open } from '@tauri-apps/plugin-dialog';const isUploading = ref(false);
const emit = defineEmits(['result']);async function openFileDialog() {try {const selected = await open({multiple: false,filters: [{name: 'APK Files',extensions: ['apk']}]});if (selected) {processApkFile(selected);}} catch (err) {console.error('Failed to open file dialog:', err);}
}async function onFileDrop(e) {const files = e.dataTransfer.files;if (files.length > 0) {const fileInfo = files[0];// 在 Tauri 中,我們需要獲取真實路徑// 瀏覽器 API 受限,需要通過 Tauri 路徑轉換if ('path' in fileInfo) {processApkFile(fileInfo.path);}}
}async function processApkFile(path) {isUploading.value = true;try {// 調用 Rust 命令解析 APKconst result = await invoke('parse_apk', { path });emit('result', result);} catch (err) {console.error('Failed to parse APK:', err);} finally {isUploading.value = false;}
}
</script><style scoped>
.uploader {border: 2px dashed #ccc;border-radius: 8px;padding: 40px;text-align: center;cursor: pointer;transition: all 0.3s ease;
}.uploader:hover {border-color: #4a86e8;background-color: rgba(74, 134, 232, 0.05);
}
</style>

創建結果顯示組件:

<!-- src/components/AnalysisResult.vue -->
<template><div v-if="apkInfo" class="result-container"><h2>APK 分析結果</h2><div class="info-section"><h3>基本信息</h3><p><strong>包名:</strong>{{ apkInfo.package_name }}</p><p><strong>版本:</strong>{{ apkInfo.version_name }} ({{ apkInfo.version_code }})</p></div><div class="permissions-section"><h3>權限 ({{ apkInfo.permissions.length }})</h3><ul><li v-for="(perm, index) in apkInfo.permissions" :key="index">{{ formatPermissionName(perm) }}</li></ul></div></div>
</template><script setup>
import { defineProps } from 'vue';const props = defineProps({apkInfo: Object
});function formatPermissionName(permission) {// 簡化權限名稱顯示return permission.split('.').pop() || permission;
}
</script><style scoped>
.result-container {padding: 20px;background: #f9f9f9;border-radius: 8px;margin-top: 20px;
}.info-section, .permissions-section {margin-bottom: 20px;
}h3 {border-bottom: 1px solid #eee;padding-bottom: 8px;
}ul {list-style-type: none;padding: 0;
}li {padding: 6px 0;border-bottom: 1px dashed #eee;
}
</style>

主應用組件:

<!-- src/App.vue -->
<template><div class="container"><h1>APK 分析工具</h1><p class="description">上傳 Android APK 文件進行分析</p><ApkUploader @result="handleResult" /><AnalysisResult :apk-info="apkInfo" /></div>
</template><script setup>
import { ref } from 'vue';
import ApkUploader from './components/ApkUploader.vue';
import AnalysisResult from './components/AnalysisResult.vue';const apkInfo = ref(null);function handleResult(result) {apkInfo.value = result;
}
</script><style>
body {font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;margin: 0;padding: 0;background: #fafafa;color: #333;
}.container {max-width: 800px;margin: 0 auto;padding: 40px 20px;
}h1 {text-align: center;margin-bottom: 10px;
}.description {text-align: center;color: #666;margin-bottom: 30px;
}
</style>

實現完整功能

對于完整的 APK 分析工具,還需添加以下功能:

  1. Rust 擴展功能

    • 處理二進制 AndroidManifest.xml
    • 提取簽名信息
    • 分析 APK 組件
    • 計算哈希值
  2. UI 增強

    • 添加詳細分析頁面
    • 實現結果導出功能
    • 添加歷史記錄
  3. 安全功能

    • 權限風險評估
    • 惡意軟件檢測集成
    • 證書驗證

性能優化

Rust 性能優化

  1. 并行處理:使用 Rust 的并行處理能力
use rayon::prelude::*;fn process_large_dataset(data: &[u8]) -> Vec<u8> {data.par_chunks(1024).map(|chunk| process_chunk(chunk)).collect()
}
  1. 異步命令:避免 UI 凍結
#[tauri::command]
async fn long_task() -> Result<String, String> {// 執行耗時操作tokio::time::sleep(std::time::Duration::from_secs(2)).await;Ok("Done".to_string())
}

前端優化

  1. 虛擬列表:處理大量數據
<template><div class="list-container" ref="container"><divv-for="item in visibleItems":key="item.id":style="{ top: `${item.position}px` }"class="list-item">{{ item.content }}</div></div>
</template><script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue';const props = defineProps({items: Array
});const container = ref(null);
const scrollTop = ref(0);
const itemHeight = 50;
const visibleCount = ref(10);onMounted(() => {const el = container.value;if (el) {el.addEventListener('scroll', handleScroll);visibleCount.value = Math.ceil(el.clientHeight / itemHeight) + 2;}
});onUnmounted(() => {const el = container.value;if (el) {el.removeEventListener('scroll', handleScroll);}
});function handleScroll(e) {scrollTop.value = e.target.scrollTop;
}const visibleItems = computed(() => {const start = Math.floor(scrollTop.value / itemHeight);return props.items.slice(start, start + visibleCount.value).map((item, index) => ({...item,position: (start + index) * itemHeight}));
});
</script><style scoped>
.list-container {height: 400px;overflow-y: auto;position: relative;
}.list-item {position: absolute;left: 0;right: 0;height: 50px;
}
</style>
  1. 懶加載組件:減少初始加載時間
import { defineAsyncComponent } from 'vue';const HeavyComponent = defineAsyncComponent(() => import('./components/HeavyComponent.vue')
);
  1. Web Workers:移除主線程阻塞
// worker.js
self.onmessage = (e) => {const result = heavyComputation(e.data);self.postMessage(result);
};function heavyComputation(data) {// 執行耗時計算return processedData;
}// 使用 Worker
const worker = new Worker('worker.js');
worker.onmessage = (e) => {console.log('Result from worker:', e.data);
};
worker.postMessage(data);

常見問題與解決方案

1. 路徑問題

問題:跨平臺路徑不一致

解決方案:使用 Tauri 的路徑 API

import { appConfigDir, join } from '@tauri-apps/api/path';async function getConfigPath() {const configDir = await appConfigDir();return await join(configDir, 'config.json');
}

2. 窗口管理

問題:創建和管理多窗口

解決方案

import { WebviewWindow } from '@tauri-apps/api/window';// 創建窗口
const webview = new WebviewWindow('settings', {url: 'settings.html',title: '設置',width: 800,height: 600
});// 監聽窗口事件
webview.once('tauri://created', () => {console.log('Settings window created');
});webview.once('tauri://error', (e) => {console.error('Settings window error:', e);
});

3. 狀態共享

問題:不同窗口間狀態共享

解決方案:使用 Rust 狀態管理

// 定義全局狀態
struct AppState {config: Mutex<Config>,
}// 在 main.rs 中管理狀態
fn main() {let state = AppState {config: Mutex::new(Config::default()),};tauri::Builder::default().manage(state).invoke_handler(tauri::generate_handler![get_config, update_config]).run(tauri::generate_context!()).expect("error while running tauri application");
}// 在命令中訪問狀態
#[tauri::command]
fn get_config(state: tauri::State<AppState>) -> Result<Config, String> {let config = state.config.lock().map_err(|e| e.to_string())?;Ok(config.clone())
}#[tauri::command]
fn update_config(state: tauri::State<AppState>, new_config: Config) -> Result<(), String> {let mut config = state.config.lock().map_err(|e| e.to_string())?;*config = new_config;Ok(())
}

擴展資源

  • Tauri 官方文檔
  • Rust 編程語言
  • Tauri GitHub 倉庫
  • Awesome Tauri
  • Tauri Discord 社區

本教程通過理論講解和實戰示例介紹了 Tauri 框架,從基礎概念到構建實際應用。隨著生態系統的不斷發展,Tauri 正成為構建高性能、安全且體積小的桌面應用程序的首選工具之一。

通過跟隨本教程中的實戰部分,你已經了解了如何構建一個基本的 APK 分析工具。要了解更多復雜功能的實現,可以參考本項目的完整源代碼,該項目展示了更多高級特性和最佳實踐。

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

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

相關文章

【LeetCode 熱題 100】矩陣置零 / 螺旋矩陣 / 旋轉圖像 / 搜索二維矩陣 II

??個人主頁&#xff1a;小羊 ??所屬專欄&#xff1a;LeetCode 熱題 100 很榮幸您能閱讀我的文章&#xff0c;誠請評論指點&#xff0c;歡迎歡迎 ~ 目錄 矩陣矩陣置零螺旋矩陣旋轉圖像搜索二維矩陣 II 矩陣 矩陣置零 矩陣置零 用兩個數組分別標記行和列&#xff0c;判斷…

JavaScript進階(三十一): === 與 == 比較運算符

文章目錄 一、前言二、嚴格相等運算符 ()三、寬松相等運算符 ()四、推薦做法五、特殊情況 一、前言 在 JavaScript 中&#xff0c; 和 都是比較運算符&#xff0c;但它們在比較時有重要區別&#xff1a; 二、嚴格相等運算符 () 不進行類型轉換只有當兩個操作數的值和類型都…

HTML與安全性:XSS、防御與最佳實踐

HTML 與安全性&#xff1a;XSS、防御與最佳實踐 前言 現代 Web 應用程序無處不在&#xff0c;而 HTML 作為其基礎結構&#xff0c;承載著巨大的安全責任。跨站腳本攻擊&#xff08;XSS&#xff09;仍然是 OWASP Top 10 安全威脅之一&#xff0c;對用戶數據和網站完整性構成嚴…

安達發|破解醫療器械多BOM困局:APS生產計劃排產軟件解決方案

在醫療器械設備制造行業&#xff0c;生產計劃與排程&#xff08;Advanced Planning and Scheduling, APS&#xff09;系統的應用至關重要。由于醫療器械行業具有嚴格的法規要求&#xff08;如FDA、ISO 13485&#xff09;、復雜的多級BOM&#xff08;Bill of Materials&#xff…

組件輪播與樣式結構重用實驗

任務一&#xff1a;使用“Swiper 輪播組件”對自行選擇的圖片和文本素材分別進行輪播&#xff0c;且調整對應的“loop”、“autoPlay”“interval”、“vertical”屬性&#xff0c;實現不同的輪播效果&#xff0c;使用Swiper 樣式自定義&#xff0c;修改默認小圓點和被選中小圓…

【Stable Diffusion】文生圖進階指南:采樣器、噪聲調度與迭代步數的解析

在Stable Diffusion文生圖(Text-to-Image)的創作過程中,采樣器(Sampler)、噪聲調度器(Schedule type)和采樣迭代步數(Steps)是影響生成效果的核心參數。本文將從技術原理、參數優化到實踐應用,深入剖析DPM++ 2M采樣器、Automatic噪聲調度器以及采樣步數的設計邏輯與協…

第一天 車聯網定義、發展歷程與生態體系

前言 車聯網&#xff08;Internet of Vehicles, IoV&#xff09;作為物聯網&#xff08;IoT&#xff09;在汽車領域的延伸&#xff0c;正在徹底改變人們的出行方式。無論是自動駕駛、遠程診斷&#xff0c;還是實時交通優化&#xff0c;車聯網技術都扮演著核心角色。本文將從零…

foc控制 - clarke變換和park變換

1. foc控制框圖 下圖是foc控制框圖&#xff0c;本文主要是講解foc控制中的larke變換和park變換clarke變換將 靜止的 a b c abc abc坐標系 變換到 靜止的 α β αβ αβ坐標系&#xff0c;本質上還是以 定子 為基準的坐標系park變換 則將 α β αβ αβ坐標系 變換到 隨 轉…

軟件系統容量管理:反模式剖析與模式應用

在數字化時代&#xff0c;軟件系統的重要性日益凸顯。隨著業務的不斷拓展和用戶數量的持續增長&#xff0c;軟件系統的容量管理成為保障其高效運行的關鍵因素。《發布&#xff01;軟件的設計與部署》第二部分圍繞容量展開深入探討&#xff0c;系統地闡述了容量的定義、范圍&…

23種設計模式-行為型模式之解釋器模式(Java版本)

Java 解釋器模式&#xff08;Interpreter Pattern&#xff09;詳解 &#x1f9e0; 什么是解釋器模式&#xff1f; 解釋器模式是一種行為型設計模式&#xff0c;主要用于解釋和執行語言的語法規則。它定義了一個解釋器來處理特定的語言句法&#xff0c;并通過一個抽象語法樹來…

基于Springboot + vue + 爬蟲實現的高考志愿智能推薦系統

項目描述 本系統包含管理員和學生兩個角色。 管理員角色&#xff1a; 個人中心管理&#xff1a;管理員可以管理自己的個人信息。 高校信息管理&#xff1a;管理員可以查詢、添加或刪除高校信息&#xff0c;并查看高校詳細信息。 學生管理&#xff1a;管理員可以查詢、添加或…

五種機器學習方法深度比較與案例實現(以手寫數字識別為例)

正如人們有各種各樣的學習方法一樣&#xff0c;機器學習也有多種學習方法。若按學習時所用的方法進行分類&#xff0c;則機器學習可分為機械式學習、指導式學習、示例學習、類比學習、解釋學習等。這是溫斯頓在1977年提出的一種分類方法。 有關機器學習的基本概念&#xff0c;…

Blender插件 三維人物角色動作自動綁定 Auto-Rig Pro V3.68.44 + Quick Rig V1.26.16

Auto-Rig Pro是一個集角色綁定、動畫重定向和Unity、Unreal Engine的Fbx導出于一體的全能解決方案。最初作為我個人的內部角色綁定工具開發&#xff0c;我幾年前將其發布&#xff0c;并自那時起增加了許多新功能。 Blender插件介紹 Auto-Rig Pro插件簡介 Auto-Rig Pro是一個強…

網絡基礎概念:從菜鳥到入門

前言&#xff1a;快遞小哥的故事 想象一下你要給朋友寄個禮物&#xff0c;這個過程其實和網絡通信非常相似&#xff1a; 1. 你需要知道朋友的”地址“&#xff08;IP地址&#xff09; 2. 要注明是送到他家大門還是物業代收&#xff08;端口號&#xff09; 3. 要選擇快遞公司并…

23種設計模式-行為型模式之中介者模式(Java版本)

Java 中介者模式&#xff08;Mediator Pattern&#xff09;詳解 &#x1f9e0; 什么是中介者模式&#xff1f; 中介者模式是一種行為型設計模式&#xff0c;它通過定義一個中介者對象來封裝一組對象之間的交互。中介者使得各個對象不需要顯式地知道彼此之間的關系&#xff0c…

【Redis】基礎4:作為分布式鎖

文章目錄 1. 一些概念2. MySQL方案2.1 方案一&#xff1a;事務特性2.1.1 存在的問題2.1.2 解決方案 2.2 方案二&#xff1a;樂觀鎖2.3 方案三&#xff1a;悲觀鎖 3. Redis3.1 實現原理3.2 實現細節3.2.1 問題1&#xff1a;持有期間鎖過期問題3.2.2 問題2&#xff1a;判斷和釋放…

深度學習---框架流程

核心六步 一、數據準備 二、模型構建 三、模型訓練 四、模型驗證 五、模型優化 六、模型推理 一、數據準備&#xff1a;深度學習的基石 數據是模型的“燃料”&#xff0c;其質量直接決定模型上限。核心步驟包括&#xff1a; 1. 數據收集與標注 來源&#xff1a;公開數據集…

阿里云 OpenManus 實戰:高效AI協作體系

阿里云 OpenManus 實戰&#xff1a;高效AI協作體系 寫在最前面初體驗&#xff1a;快速部署&#xff0c;開箱即用 真實案例分享&#xff1a;從單體開發到智能良好提示詞過程展示第一步&#xff1a;為亞馬遜美國站生成商品描述第二步&#xff1a;為eBay全球站生成商品描述結果分析…

Kubernetes》》k8s》》explain查 yaml 參數

在創建json 和yaml 時&#xff0c;我們可能不知道具體的參數該怎么寫。同樣 我們可以通過explain這個 命令來查看 每個參數具體的作用與寫法 # 查看 pod類性有哪些參數 kubectl explain pod# 查看pod中 spec下面有哪些參數 kubectl explain pod.spec

從零構建Dagster分區管道:時間+類別分區實戰案例

分區是Dagster中的核心抽象概念&#xff0c;它允許我們管理大型數據集、處理增量更新并提高管道性能。本文將詳細介紹如何創建和實現基于時間和類別的分區資產。 什么是分區&#xff1f; 分區是將數據集劃分為更小、更易管理的部分的技術。在Dagster中&#xff0c;分區可以基于…