55.HarmonyOS NEXT 登錄模塊開發教程(九):部署與發布

溫馨提示:本篇博客的詳細代碼已發布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下載運行哦!

HarmonyOS NEXT 登錄模塊開發教程(九):部署與發布

效果預覽

1. 引言

在前八篇教程中,我們介紹了HarmonyOS NEXT登錄模塊的整體架構、模態窗口的實現原理、一鍵登錄頁面的實現、短信驗證碼登錄的實現、狀態管理和數據綁定機制、安全性考慮、UI設計和用戶體驗優化、性能優化和最佳實踐以及測試與調試技巧。本篇教程將深入講解登錄模塊的部署和發布流程,幫助開發者將登錄功能順利部署到實際環境中。

部署和發布是應用開發的最后一環,也是將開發成果轉化為用戶價值的關鍵步驟。在HarmonyOS NEXT中,應用的部署和發布有其特定的流程和要求,本教程將詳細介紹這些內容,確保登錄模塊能夠順利地集成到應用中并發布到應用市場。

2. 應用打包與簽名

2.1 應用打包概述

HarmonyOS NEXT應用的打包過程主要包括以下步驟:

  1. 編譯代碼:將ArkTS代碼編譯為可執行文件
  2. 打包資源:將圖片、字符串等資源文件打包
  3. 生成HAP包:生成Harmony Ability Package(HAP)文件
  4. 簽名驗證:對HAP包進行簽名,確保其完整性和來源可信

2.2 使用DevEco Studio打包應用

DevEco Studio提供了圖形化界面,簡化了應用打包過程:

  1. 在DevEco Studio中,選擇菜單欄的Build > Build Hap(s)/APP(s) > Build APP(s)
  2. 在彈出的對話框中,選擇要構建的模塊和配置
  3. 點擊OK按鈕,開始構建過程
  4. 構建完成后,HAP包將生成在項目的build/outputs/app/debugbuild/outputs/app/release目錄下

2.3 應用簽名

應用簽名是確保應用完整性和來源可信的重要機制。HarmonyOS NEXT要求所有應用必須經過簽名才能安裝和運行。

2.3.1 創建簽名證書
# 使用keytool創建簽名證書
keytool -genkeypair -alias key0 -keyalg RSA -keysize 2048 -validity 3650 -keystore my_application.p12 -storetype PKCS12 -storepass 123456
n```在交互式提示中,需要輸入以下信息:
- 名字與姓氏(CN)
- 組織單位名稱(OU)
- 組織名稱(O)
- 城市或區域名稱(L)
- 省/市/自治區名稱(ST)
- 國家/地區代碼(C)#### 2.3.2 配置簽名信息在項目的`build-profile.json5`文件中配置簽名信息:```json
{"app": {"signingConfigs": [{"name": "release","type": "HarmonyOS","material": {"certpath": "C:/Users/Username/my_application.cer","storePassword": "123456","keyAlias": "key0","keyPassword": "123456","profile": "C:/Users/Username/my_application.p7b","signAlg": "SHA256withECDSA"}}],"compileSdkVersion": 9,"compatibleSdkVersion": 9,"products": [{"name": "default","signingConfig": "release"}]},"modules": [// 模塊配置]
}
2.3.3 使用DevEco Studio簽名應用
  1. 在DevEco Studio中,選擇菜單欄的Build > Build Hap(s)/APP(s) > Build APP(s)
  2. 在彈出的對話框中,選擇Release模式和之前配置的簽名信息
  3. 點擊OK按鈕,開始構建和簽名過程

3. 環境配置與切換

3.1 多環境配置

在實際開發中,通常需要為不同的環境(開發、測試、生產)配置不同的參數,如API地址、日志級別等。

3.1.1 使用配置文件

創建不同環境的配置文件:

// config/dev.ets - 開發環境配置
export default {API_BASE_URL: 'https://dev-api.example.com',LOG_LEVEL: 'DEBUG',ENABLE_MOCK: true
};// config/test.ets - 測試環境配置
export default {API_BASE_URL: 'https://test-api.example.com',LOG_LEVEL: 'INFO',ENABLE_MOCK: false
};// config/prod.ets - 生產環境配置
export default {API_BASE_URL: 'https://api.example.com',LOG_LEVEL: 'ERROR',ENABLE_MOCK: false
};
3.1.2 環境切換機制

創建一個環境管理模塊,用于加載和切換環境配置:

// utils/env.ets
import devConfig from '../config/dev';
import testConfig from '../config/test';
import prodConfig from '../config/prod';// 環境類型
export enum EnvType {DEV = 'dev',TEST = 'test',PROD = 'prod'
}// 當前環境
let currentEnv: EnvType = EnvType.DEV;// 環境配置映射
const configMap = {[EnvType.DEV]: devConfig,[EnvType.TEST]: testConfig,[EnvType.PROD]: prodConfig
};// 獲取當前環境配置
export function getConfig() {return configMap[currentEnv];
}// 設置當前環境
export function setEnv(env: EnvType) {currentEnv = env;
}// 獲取當前環境類型
export function getEnv(): EnvType {return currentEnv;
}
3.1.3 在登錄模塊中使用環境配置
// services/auth.ets
import { getConfig } from '../utils/env';
import http from '@ohos.net.http';// 發送驗證碼
export async function sendVerifyCode(phoneNumber: string): Promise<boolean> {const config = getConfig();const url = `${config.API_BASE_URL}/auth/sendVerifyCode`;// 如果啟用了模擬模式,直接返回成功if (config.ENABLE_MOCK) {return true;}try {const httpRequest = http.createHttp();const response = await httpRequest.request(url, {method: http.RequestMethod.POST,extraData: { phoneNumber },connectTimeout: 60000,readTimeout: 60000});httpRequest.destroy();if (response.responseCode === 200) {const result = JSON.parse(response.result.toString());return result.success;}return false;} catch (error) {console.error(`Failed to send verify code: ${error}`);return false;}
}

3.2 構建變體

使用DevEco Studio的構建變體功能,可以更方便地管理不同環境的構建配置:

  1. 在項目的build-profile.json5文件中配置構建變體:
{"app": {// 應用配置},"modules": [{"name": "entry","srcPath": "./entry","targets": [{"name": "default","applyToProducts": ["default"]}],"buildVariants": [{"name": "dev","productFlavors": [{"name": "flavor1","value": "dev"}]},{"name": "test","productFlavors": [{"name": "flavor1","value": "test"}]},{"name": "prod","productFlavors": [{"name": "flavor1","value": "prod"}]}]}]
}
  1. 在代碼中獲取當前構建變體:
import bundleManager from '@ohos.bundle.bundleManager';// 獲取當前構建變體
async function getBuildVariant(): Promise<string> {try {const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA);const metadata = bundleInfo.metadata;return metadata['flavor1'] || 'dev'; // 默認為dev} catch (error) {console.error(`Failed to get build variant: ${error}`);return 'dev'; // 默認為dev}
}// 根據構建變體設置環境
async function initEnv() {const variant = await getBuildVariant();switch (variant) {case 'dev':setEnv(EnvType.DEV);break;case 'test':setEnv(EnvType.TEST);break;case 'prod':setEnv(EnvType.PROD);break;default:setEnv(EnvType.DEV);}
}

4. 版本管理

4.1 版本號規范

HarmonyOS NEXT應用的版本號由兩部分組成:

  1. 版本名稱(versionName):用于向用戶展示的版本號,通常采用語義化版本號格式(主版本號.次版本號.修訂號)
  2. 版本號(versionCode):用于系統識別的整數版本號,每次更新都應該遞增

在項目的module.json5文件中配置版本信息:

{"module": {"name": "entry","type": "entry","description": "$string:module_desc","mainElement": "EntryAbility","deviceTypes": ["phone","tablet"],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","abilities": [{"name": "EntryAbility","srcEntry": "./ets/entryability/EntryAbility.ets","description": "$string:EntryAbility_desc","icon": "$media:icon","label": "$string:EntryAbility_label","startWindowIcon": "$media:icon","startWindowBackground": "$color:start_window_background","skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home"]}]}],"requestPermissions": [{"name": "ohos.permission.INTERNET"}]},"app": {"bundleName": "com.example.myapplication","vendor": "example","versionCode": 1000000,"versionName": "1.0.0"}
}

4.2 版本更新策略

在更新應用時,應遵循以下版本更新策略:

  1. 主版本號:當進行不兼容的API更改時遞增
  2. 次版本號:當添加向下兼容的功能時遞增
  3. 修訂號:當進行向下兼容的問題修復時遞增
  4. 版本號(versionCode):每次發布都遞增,建議使用格式:主版本號×1000000 + 次版本號×1000 + 修訂號

4.3 版本更新檢測

在應用中實現版本更新檢測功能,提醒用戶更新到最新版本:

// services/update.ets
import http from '@ohos.net.http';
import promptAction from '@ohos.promptAction';
import bundleManager from '@ohos.bundle.bundleManager';// 檢查更新
export async function checkUpdate(): Promise<void> {try {// 獲取當前應用版本信息const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT);const currentVersionCode = bundleInfo.versionCode;const currentVersionName = bundleInfo.versionName;// 從服務器獲取最新版本信息const httpRequest = http.createHttp();const response = await httpRequest.request('https://api.example.com/app/version', {method: http.RequestMethod.GET,connectTimeout: 60000,readTimeout: 60000});httpRequest.destroy();if (response.responseCode === 200) {const result = JSON.parse(response.result.toString());const latestVersionCode = result.versionCode;const latestVersionName = result.versionName;const updateUrl = result.updateUrl;const updateDescription = result.description;// 檢查是否需要更新if (latestVersionCode > currentVersionCode) {// 顯示更新提示promptAction.showDialog({title: '發現新版本',message: `當前版本:${currentVersionName}\n最新版本:${latestVersionName}\n\n${updateDescription}`,buttons: [{text: '稍后再說',color: '#666666'},{text: '立即更新',color: '#0000ff'}],success: (result) => {if (result.index === 1) {// 用戶點擊了立即更新,跳轉到更新頁面或應用市場// 實際實現可能需要調用系統API打開瀏覽器或應用市場console.info(`Update URL: ${updateUrl}`);}}});} else {console.info('當前已是最新版本');}}} catch (error) {console.error(`Failed to check update: ${error}`);}
}

5. 應用市場發布

5.1 華為應用市場發布流程

將應用發布到華為應用市場(AppGallery)的主要步驟:

  1. 注冊開發者賬號:在華為開發者聯盟注冊開發者賬號
  2. 創建應用:在華為開發者聯盟控制臺創建應用
  3. 上傳應用包:上傳簽名后的HAP包
  4. 填寫應用信息:填寫應用名稱、描述、分類、標簽、截圖等信息
  5. 設置定價和發布范圍:設置應用的定價策略和發布國家/地區
  6. 提交審核:提交應用進行審核
  7. 發布應用:審核通過后發布應用

5.2 應用發布前的檢查清單

在發布應用前,應進行以下檢查:

  1. 功能完整性:確保所有功能正常工作
  2. 兼容性:在不同設備和系統版本上測試
  3. 性能:檢查應用的啟動時間、響應速度、內存占用等
  4. 安全性:確保敏感數據加密、網絡通信安全等
  5. 隱私合規:檢查隱私政策是否完整,權限申請是否合理
  6. 資源完整:確保所有圖片、文本等資源文件完整
  7. 版本信息:檢查版本號是否正確
  8. 簽名驗證:確保應用已正確簽名

5.3 灰度發布策略

灰度發布是一種將新版本逐步推廣給用戶的策略,可以降低風險:

  1. 階段性發布:先發布給小部分用戶,逐步擴大發布范圍
  2. 用戶分組:根據用戶特征(如地區、設備類型)進行分組發布
  3. 監控反饋:密切監控用戶反饋和應用性能
  4. 快速響應:發現問題時能夠快速響應和修復

在華為應用市場中,可以通過以下方式實現灰度發布:

  1. 在發布新版本時,選擇"分階段發布"選項
  2. 設置每個階段的用戶比例和時間間隔
  3. 根據每個階段的反饋情況,決定是否繼續推進或回滾

6. 登錄模塊的部署注意事項

6.1 服務端接口對接

登錄模塊需要與服務端接口對接,確保通信正常:

  1. 接口文檔:明確接口的URL、參數、返回值等
  2. 錯誤處理:處理各種可能的錯誤情況
  3. 超時設置:設置合理的超時時間
  4. 重試機制:實現請求失敗后的重試機制
// services/auth.ets
import http from '@ohos.net.http';
import { getConfig } from '../utils/env';// 登錄接口
export async function login(phoneNumber: string, verifyCode: string): Promise<any> {const config = getConfig();const url = `${config.API_BASE_URL}/auth/login`;try {const httpRequest = http.createHttp();const response = await httpRequest.request(url, {method: http.RequestMethod.POST,extraData: {phoneNumber,verifyCode},connectTimeout: 30000,readTimeout: 30000});httpRequest.destroy();if (response.responseCode === 200) {return JSON.parse(response.result.toString());}throw new Error(`Login failed with code: ${response.responseCode}`);} catch (error) {console.error(`Login error: ${error}`);// 實現重試邏輯return await retryLogin(phoneNumber, verifyCode);}
}// 重試登錄
async function retryLogin(phoneNumber: string, verifyCode: string, maxRetries = 3): Promise<any> {let retries = 0;let lastError;while (retries < maxRetries) {try {const config = getConfig();const url = `${config.API_BASE_URL}/auth/login`;const httpRequest = http.createHttp();const response = await httpRequest.request(url, {method: http.RequestMethod.POST,extraData: {phoneNumber,verifyCode},connectTimeout: 30000,readTimeout: 30000});httpRequest.destroy();if (response.responseCode === 200) {return JSON.parse(response.result.toString());}throw new Error(`Login failed with code: ${response.responseCode}`);} catch (error) {lastError = error;retries++;// 等待一段時間后重試await new Promise(resolve => setTimeout(resolve, 1000 * retries));}}throw lastError;
}

6.2 用戶數據遷移

在更新應用時,可能需要遷移用戶數據:

  1. 數據備份:在更新前備份用戶數據
  2. 數據遷移:實現數據格式轉換和遷移邏輯
  3. 兼容處理:處理新舊版本數據格式不兼容的情況
// utils/dataMigration.ets
import data_preferences from '@ohos.data.preferences';// 數據遷移
export async function migrateUserData(): Promise<void> {try {const context = getContext(this);const oldPreferences = await data_preferences.getPreferences(context, 'user_data_v1');const newPreferences = await data_preferences.getPreferences(context, 'user_data_v2');// 檢查是否需要遷移const migrated = await newPreferences.get('data_migrated', false);if (migrated) {return; // 已經遷移過,無需再次遷移}// 獲取舊數據const userId = await oldPreferences.get('userId', '');const token = await oldPreferences.get('token', '');const loginTime = await oldPreferences.get('loginTime', 0);// 遷移到新格式if (userId) {await newPreferences.put('user_id', userId); // 新的鍵名格式await newPreferences.put('auth_token', token); // 新的鍵名格式await newPreferences.put('last_login_timestamp', loginTime); // 新的鍵名格式// 標記為已遷移await newPreferences.put('data_migrated', true);await newPreferences.flush();console.info('User data migration completed');}} catch (error) {console.error(`Data migration failed: ${error}`);}
}

6.3 多端同步

對于支持多端登錄的應用,需要考慮數據同步問題:

  1. 用戶標識:使用統一的用戶標識符
  2. 數據同步:實現多端數據同步機制
  3. 沖突解決:處理數據沖突情況

7. 最佳實踐與注意事項

在部署和發布登錄模塊時,有以下幾點最佳實踐和注意事項:

  1. 環境隔離:嚴格隔離開發、測試和生產環境
  2. 配置外部化:將配置參數外部化,便于不同環境切換
  3. 版本控制:使用語義化版本號,便于版本管理
  4. 發布節奏:建立規律的發布節奏,避免頻繁更新
  5. 監控告警:部署監控和告警系統,及時發現問題
  6. 灰度策略:采用灰度發布策略,降低風險
  7. 回滾機制:建立快速回滾機制,應對緊急情況
  8. 用戶反饋:收集和分析用戶反饋,持續改進

8. 小結

本文詳細介紹了HarmonyOS NEXT登錄模塊的部署和發布流程,包括應用打包與簽名、環境配置與切換、版本管理、應用市場發布以及登錄模塊的部署注意事項。通過合理的部署和發布策略,可以確保登錄模塊穩定可靠地運行在用戶設備上。

部署和發布是應用開發的最后一環,但同樣重要。良好的部署和發布實踐不僅能夠提高應用的質量和穩定性,還能提升用戶體驗和滿意度。在登錄模塊的部署和發布過程中,應注重安全性、穩定性和用戶體驗,確保用戶能夠順利登錄并使用應用。

9. 參考資源

  • HarmonyOS開發者文檔 - 應用打包與簽名
  • HarmonyOS開發者文檔 - 應用發布
  • HarmonyOS開發者文檔 - 版本管理
  • 華為應用市場開發者政策

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

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

相關文章

vue3實現跨頁面緩存

避免頻繁向后端發送請求,vue3中,可以用緩存機制,為了實現跨頁面緩存,可以把緩存放到localsotrage里面 關鍵代碼: const globalCache JSON.parse(localStorage.getItem(globalCache)) || {}; 然后加一個forceRefresh關鍵字, const fetchData async (forceRefresh false) …

c++類和對象(下篇)上

今天又重新回到c的學習中~在前兩篇博客中,我簡單的學習了類的定義,實例化,以及類中的默認成員函數.下篇是類和對象的收尾篇,在這篇中我將補充一下中篇所講的構造函數以及介紹一些類和對象的新知識.下面讓我們開始學習吧. 再談構造函數 在之前我們實現構造函數時,初始化成員變量…

深度學習 bert流程

Token IDs 在自然語言處理任務中&#xff0c;特別是使用預訓練模型如BERT時&#xff0c;文本首先通過一個分詞器&#xff08;例如 BertTokenizer&#xff09;轉換為一系列的token IDs。這些ID是每個詞或子詞單元在詞匯表&#xff08;包含漢字、英文單詞、標點符號&#xff09;…

PPT內視頻播放無法播放的原因及解決辦法

PPT內視頻無法播放&#xff0c;通常是視頻編解碼的問題。目前我遇到的常見的視頻編碼格式有H.264&#xff0c;H.265&#xff0c;VP9&#xff0c;AV1這4種。H.264編解碼的視頻&#xff0c;Windows原生系統可以直接播放&#xff0c;其他的視頻編碼格式需要安裝對應的視頻編解碼插…

星越L_行李艙空間拓展講解

目錄 1.儲物槽 2.底板蓋儲物空間 3.掛鉤 3.左側照明燈 4.第二排座椅放倒 1.儲物槽 使用鑰匙或者后備箱按鈕打開電動后備箱,左側儲物槽可儲藏物品。 2.底板蓋儲物空間 打開地板蓋,下方有儲物空間。并放置了隨車工具。 3.掛鉤 后備箱左右兩測各有一個掛鉤。

深度學習與大模型-矩陣

矩陣其實在我們的生活中也有很多應用&#xff0c;只是我們沒注意罷了。 1. 矩陣是什么&#xff1f; 簡單來說&#xff0c;矩陣就是一個長方形的數字表格。比如你有一個2行3列的矩陣&#xff0c;可以寫成這樣&#xff1a; 這個矩陣有2行3列&#xff0c;每個數字都有一個位置&a…

LuaJIT 學習(2)—— 使用 FFI 庫的幾個例子

文章目錄 介紹Motivating Example: Calling External C Functions例子&#xff1a;Lua 中調用 C 函數 Motivating Example: Using C Data StructuresAccessing Standard System FunctionsAccessing the zlib Compression LibraryDefining Metamethods for a C Type例子&#xf…

基于 FastText、dlib 和 CppJieba 的中文語義相似度計算實踐

在自然語言處理(NLP)領域,語義相似度計算是許多任務的核心,例如問答系統、文本檢索和推薦系統。然而,中文因缺乏顯式分詞和復雜的語義結構,實現高效的語義對比具有一定挑戰性。 本文將介紹如何結合 CppJieba(高效中文分詞工具)、FastText(詞向量模型)和 dlib(機器學…

HCIA-11.以太網鏈路聚合與交換機堆疊、集群

鏈路聚合背景 拓撲組網時為了高可用&#xff0c;需要網絡的冗余備份。但增加冗余容易后會出現環路&#xff0c;所以我們部署了STP協議來破除環路。 但是&#xff0c;根據實際業務的需要&#xff0c;為網絡不停的增加冗余是現實需要的一部分。 那么&#xff0c;為了讓網絡冗余…

Unity基于C#+UGUI解決方案,制作每日簽到系統(本地存儲簽到數據)

一、需求介紹:基于本地存儲系統制作一個每日簽到系統界面,相關簽到界面如下圖所示,點擊“簽到有禮”按鈕后就會跳轉到“每日登錄禮”這個界面,點擊“立即簽到”按鈕之后,按鈕就會置灰,而且按鈕的文字會變成“等待明日”。 二、制作界面顯示相關功能,需要在Unity中新建一…

AI本地部署

文檔加載&#xff08;Document Loading&#xff09;&#xff1a;從多種不同來源加載文檔。LangChain提供了100多種不同的文檔加載器&#xff0c;包括PDF在內的非結構化的數據、SQL在內的結構化的數據&#xff0c;以及Python、Java之類的代碼等? ?文本分割&#xff08;Splitti…

精準車型識別:視覺分析技術的力量

隨著智慧城市和智能交通系統的快速發展&#xff0c;車型識別檢測成為交通管理、安全監控和數據分析的關鍵技術之一。利用視覺分析的方式&#xff0c;我們可以高效、準確地檢測監控下的車輛類型、車牌信息及車流量&#xff0c;為城市交通管理提供有力支持。本文將從背景、技術實…

上下文微調(Contextual Fine-Tuning, CFT)提高大型語言模型(LLMs)在特定領域的學習和推理能力

大型語言模型(LLMs)在開放領域任務中表現出色,但在快速演變的專業領域(如醫學、金融)中面臨挑戰: 知識更新難題:傳統指令微調(Instruction Fine-Tuning, IFT)依賴顯式指令,難以適應動態知識。災難性遺忘:持續預訓練(Continued Pretraining, CPT)可能導致模型遺忘已…

在 LaTeX 中強制表格位于頁面頂部

在 LaTeX 中強制表格位于頁面頂部&#xff0c;可以通過以下 多種方法結合使用&#xff0c;按優先級推薦&#xff1a; 方法 1&#xff1a;使用 [!t] 位置限定符 原理&#xff1a;通過 [!t] 強制 LaTeX 優先將表格放置在頁面頂部&#xff08;Top&#xff09;&#xff0c;! 表示忽…

kotlin與MVVM的結合使用總結(二)

在 MVVM&#xff08;Model - View - ViewModel&#xff09;架構中&#xff0c;M 層即 Model 層&#xff0c;主要負責數據的管理、存儲和獲取&#xff0c;它與業務邏輯和數據處理相關。在 Kotlin 中實現 MVVM 的 M 層&#xff0c;通常會涉及數據類的定義、數據的本地存儲與遠程獲…

電子元器件選型與實戰應用—16 怎么選一個合適的MCU芯片?

文章目錄 1. 選型要素1.1 價格1.2 技術支持1.3 廠家優勢1.4 功耗1.5 特殊功能1.6 統計外設1.7 確定外設占用的內存和flash大小1.8 確定外設通信接口1.9 確定外設通信接口的電平1.10 確定外設的GPIO數量1.11 確定外設的供電和功耗1.12 確定外設GPIO的種類1.13 確定ADC的數量1.14…

VSCode 搭建C++編程環境 2025新版圖文安裝教程(100%搭建成功,VSCode安裝+C++環境搭建+運行測試+背景圖設置)

名人說&#xff1a;博觀而約取&#xff0c;厚積而薄發。——蘇軾《稼說送張琥》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 目錄 一、VScode下載及安裝二、安裝 MinGW-w64 工具鏈三、Windows環境變量配置四、檢查 M…

Django系列教程(7)——路由配置URLConf

目錄 URLconf是如何工作的? path和re_path方法 更多URL配置示例 URL的命名及reverse()方法 使用命名URL 硬編碼URL - 不建議 URL指向基于類的視圖(View) 通過URL傳遞額外的參數 小結 Django的項目文件夾和每個應用(app)目錄下都有urls.py文件&#xff0c;它們構成了D…

transformer bert 多頭自注意力

輸入的&#xff08;a1,a2,a3,a4&#xff09;是最終嵌入&#xff0c;是一個(512,768)的矩陣&#xff1b;而a1是一個token&#xff0c;尺寸是768 a1通過wq權重矩陣&#xff0c;經過全連接變換得到查詢向量q1&#xff1b;a2通過Wk權重矩陣得到鍵向量k2&#xff1b;q和k點乘就是值…

Spring Boot + MyBatis-Plus 項目目錄結構

以下是一個標準的 Spring Boot MyBatis-Plus 項目目錄結構及文件命名規范&#xff0c;包含每個目錄和文件的作用說明&#xff0c;適用于中大型項目開發&#xff1a; 項目根目錄結構 src/ ├── main/ │ ├── java/ # Java 源代碼 │ │ └── com/…