HarmonyOS后臺任務調度:JobScheduler與WorkManager實戰指南

本文將深入探討HarmonyOS 5(API 12)中的后臺任務調度機制,重點講解JobScheduler和WorkManager的使用方法、適用場景及最佳實踐,幫助開發者實現高效、智能的后臺任務管理。

1. 后臺任務調度概述

HarmonyOS提供了兩種主要的后臺任務調度方式:JobSchedulerWorkManager。兩者都支持基于條件觸發任務執行,但各有不同的設計目標和適用場景。

1.1 核心特性對比

特性維度JobSchedulerWorkManager
設計目標系統級任務調度,精確控制執行時機應用級任務管理,更靈活的任務鏈
最低APIAPI 9+API 12+
任務持久化支持設備重啟后繼續執行支持,且提供更豐富的重試策略
任務鏈有限支持完整支持(鏈式、并行、組合)
約束條件網絡、充電、設備空閑等網絡、充電、存儲、電池等更豐富條件
適用場景精確時間要求的系統任務復雜的業務邏輯和任務依賴關系

2. JobScheduler實戰開發

JobScheduler適合執行對時間精度要求高、需要系統級調度的后臺任務。

2.1 創建JobService

首先創建繼承自JobService的類,實現任務邏輯:

import { JobService, JobInfo, JobParameters } from '@ohos.resourceschedule.backgroundTaskManager';
import { BusinessError } from '@ohos.base';
import hilog from '@ohos.hilog';// 定義任務標識
const JOB_ID = 1001;
const LOG_TAG = 'DataSyncJob';export default class DataSyncJob extends JobService {// 任務開始時調用onStartJob(parameters: JobParameters): boolean {hilog.info(0x0000, LOG_TAG, '數據同步任務開始執行');// 執行異步任務this.performDataSync(parameters).then(() => {hilog.info(0x0000, LOG_TAG, '數據同步任務完成');this.jobFinished(parameters, false); // 任務完成,不需要重試}).catch((error: BusinessError) => {hilog.error(0x0000, LOG_TAG, `數據同步失敗: ${error.message}`);this.jobFinished(parameters, true); // 任務失敗,需要重試});return true; // 返回true表示任務正在異步執行}// 任務停止時調用(系統強制停止)onStopJob(parameters: JobParameters): boolean {hilog.info(0x0000, LOG_TAG, '數據同步任務被停止');// 執行清理操作this.cleanupResources();return false; // 返回false表示不需要重新調度任務}// 執行實際的數據同步邏輯private async performDataSync(parameters: JobParameters): Promise<void> {const extras = parameters.getExtras();const syncType = extras?.getString('sync_type') || 'full';hilog.info(0x0000, LOG_TAG, `開始${syncType}數據同步`);// 模擬網絡請求和數據同步await this.fetchDataFromServer();await this.processAndStoreData();await this.updateLocalCache();hilog.info(0x0000, LOG_TAG, '數據同步流程完成');}private async fetchDataFromServer(): Promise<void> {// 實現網絡請求邏輯await new Promise(resolve => setTimeout(resolve, 2000)); // 模擬網絡延遲hilog.debug(0x0000, LOG_TAG, '從服務器獲取數據成功');}private async processAndStoreData(): Promise<void> {// 實現數據處理和存儲邏輯await new Promise(resolve => setTimeout(resolve, 1000));hilog.debug(0x0000, LOG_TAG, '數據處理和存儲完成');}private async updateLocalCache(): Promise<void> {// 更新本地緩存await new Promise(resolve => setTimeout(resolve, 500));hilog.debug(0x0000, LOG_TAG, '本地緩存更新完成');}private cleanupResources(): void {// 清理網絡連接、文件句柄等資源hilog.debug(0x0000, LOG_TAG, '任務資源清理完成');}
}

2.2 配置和調度任務

module.json5中注冊JobService:

{"module": {"abilities": [{"name": "DataSyncJob","type": "jobService","visible": true,"permissions": ["ohos.permission.INTERNET","ohos.permission.GET_NETWORK_INFO"]}]}
}

在頁面中調度任務:

import { backgroundTaskManager, JobInfo, JobScheduler } from '@ohos.resourceschedule.backgroundTaskManager';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';@Entry
@Component
struct JobSchedulerDemo {private context: common.Context = getContext(this) as common.Context;@State jobStatus: string = '未調度';// 調度周期性數據同步任務private async schedulePeriodicSync(): Promise<void> {try {const jobInfo: JobInfo = {jobId: 1001,bundleName: this.context.applicationInfo.name,abilityName: 'DataSyncJob',type: backgroundTaskManager.JobType.JOB_TYPE_PERIODIC,period: 2 * 60 * 60 * 1000, // 每2小時執行一次requiredNetworkType: backgroundTaskManager.NetworkType.NETWORK_TYPE_ANY,isChargingRequired: true,isBatteryNotLowRequired: true,isDeviceIdleRequired: false,isPersisted: true, // 設備重啟后保持任務extras: {'sync_type': 'incremental','priority': 'high'}};const scheduler: JobScheduler = backgroundTaskManager.getJobScheduler(this.context);const result = await scheduler.schedule(jobInfo);if (result === backgroundTaskManager.JobSchedulerResult.RESULT_SUCCESS) {this.jobStatus = '周期性同步任務已調度';hilog.info(0x0000, 'JobSchedulerDemo', '周期性數據同步任務調度成功');} else {this.jobStatus = '任務調度失敗';hilog.error(0x0000, 'JobSchedulerDemo', `任務調度失敗,錯誤碼: ${result}`);}} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'JobSchedulerDemo', `調度任務異常: ${err.message}`);this.jobStatus = `調度異常: ${err.message}`;}}// 調度一次性任務private async scheduleOneTimeTask(): Promise<void> {try {const jobInfo: JobInfo = {jobId: 1002,bundleName: this.context.applicationInfo.name,abilityName: 'DataSyncJob',type: backgroundTaskManager.JobType.JOB_TYPE_ONE_SHOT,minLatency: 5000, // 5秒后執行requiredNetworkType: backgroundTaskManager.NetworkType.NETWORK_TYPE_UNMETERED,extras: {'sync_type': 'full','priority': 'critical'}};const scheduler: JobScheduler = backgroundTaskManager.getJobScheduler(this.context);const result = await scheduler.schedule(jobInfo);if (result === backgroundTaskManager.JobSchedulerResult.RESULT_SUCCESS) {this.jobStatus = '一次性任務已調度';hilog.info(0x0000, 'JobSchedulerDemo', '一次性任務調度成功');}} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'JobSchedulerDemo', `一次性任務調度異常: ${err.message}`);}}// 取消任務private async cancelJob(jobId: number): Promise<void> {try {const scheduler: JobScheduler = backgroundTaskManager.getJobScheduler(this.context);await scheduler.cancel(jobId);this.jobStatus = `任務 ${jobId} 已取消`;hilog.info(0x0000, 'JobSchedulerDemo', `任務 ${jobId} 取消成功`);} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'JobSchedulerDemo', `取消任務異常: ${err.message}`);}}build() {Column({ space: 10 }) {Text('JobScheduler任務調度演示').fontSize(20).margin(10)Text(`任務狀態: ${this.jobStatus}`).fontSize(16).margin(5)Button('調度周期性同步任務').onClick(() => this.schedulePeriodicSync()).width('80%').margin(10)Button('調度一次性任務').onClick(() => this.scheduleOneTimeTask()).width('80%').margin(10)Button('取消所有任務').onClick(() => {this.cancelJob(1001);this.cancelJob(1002);}).width('80%').margin(10)}.width('100%').height('100%')}
}

3. WorkManager實戰開發

WorkManager適合處理復雜的業務工作流,支持任務鏈和豐富的約束條件。

3.1 創建Worker類

import { Worker, WorkRequest, WorkInfo } from '@ohos.app.dispatcher.workManager';
import { BusinessError } from '@ohos.base';
import hilog from '@ohos.hilog';const LOG_TAG = 'ImageProcessingWorker';// 圖像處理工作器
export default class ImageProcessingWorker extends Worker {// 執行實際工作async doWork(parameters: WorkRequest): Promise<WorkRequest.Result> {hilog.info(0x0000, LOG_TAG, '開始圖像處理任務');try {const imageUrl = parameters.getString('image_url');const processType = parameters.getString('process_type', 'thumbnail');// 執行圖像處理const resultPath = await this.processImage(imageUrl, processType);hilog.info(0x0000, LOG_TAG, '圖像處理任務完成');// 返回成功結果return WorkRequest.Result.success(new WorkRequest.Data.Builder().putString('processed_image_path', resultPath).putLong('processing_time', Date.now()).build());} catch (error) {const err = error as BusinessError;hilog.error(0x0000, LOG_TAG, `圖像處理失敗: ${err.message}`);// 返回失敗結果,支持重試return WorkRequest.Result.retry();}}private async processImage(imageUrl: string, processType: string): Promise<string> {hilog.debug(0x0000, LOG_TAG, `處理圖像: ${imageUrl}, 類型: ${processType}`);// 模擬圖像處理過程await new Promise(resolve => setTimeout(resolve, 3000));// 返回處理后的圖像路徑return `/data/storage/processed/${Date.now()}_${processType}.jpg`;}
}

3.2 配置工作請求和約束條件

import { WorkManager, WorkRequest, Constraints } from '@ohos.app.dispatcher.workManager';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';@Entry
@Component
struct WorkManagerDemo {private context: common.Context = getContext(this) as common.Context;@State workStatus: string = '未開始';private workId: string = '';// 創建圖像處理任務private async createImageProcessingWork(): Promise<void> {try {// 定義約束條件const constraints: Constraints = {requiredNetworkType: WorkRequest.NetworkType.CONNECTED,requiresCharging: false,requiresBatteryNotLow: true,requiresStorageNotLow: true,requiresDeviceIdle: false};// 創建工作任務const workRequest: WorkRequest = new WorkRequest.Builder(this.context).setWorkerClass(ImageProcessingWorker).setConstraints(constraints).setInputData(new WorkRequest.Data.Builder().putString('image_url', 'https://example.com/image.jpg').putString('process_type', 'enhance').build()).setBackoffCriteria(WorkRequest.BackoffPolicy.EXPONENTIAL,30000, // 30秒重試延遲WorkRequest.BackoffDelayUnit.MILLISECONDS).build();// 獲取WorkManager實例const workManager = WorkManager.getInstance(this.context);// 提交任務this.workId = await workManager.enqueue(workRequest);this.workStatus = `任務已提交,ID: ${this.workId}`;hilog.info(0x0000, 'WorkManagerDemo', `任務提交成功,ID: ${this.workId}`);// 監聽任務狀態this.monitorWorkStatus(this.workId);} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'WorkManagerDemo', `創建任務失敗: ${err.message}`);this.workStatus = `任務創建失敗: ${err.message}`;}}// 監聽任務狀態變化private async monitorWorkStatus(workId: string): Promise<void> {try {const workManager = WorkManager.getInstance(this.context);workManager.getWorkInfoById(workId).then((workInfo: WorkInfo) => {this.handleWorkInfoUpdate(workInfo);}).catch((error: BusinessError) => {hilog.error(0x0000, 'WorkManagerDemo', `獲取任務信息失敗: ${error.message}`);});// 監聽任務狀態變化workManager.addWorkStatusListener(workId, (workInfo: WorkInfo) => {this.handleWorkInfoUpdate(workInfo);});} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'WorkManagerDemo', `監聽任務狀態失敗: ${err.message}`);}}private handleWorkInfoUpdate(workInfo: WorkInfo): void {switch (workInfo.state) {case WorkInfo.State.ENQUEUED:this.workStatus = '任務排隊中';break;case WorkInfo.State.RUNNING:this.workStatus = '任務執行中';break;case WorkInfo.State.SUCCEEDED:this.workStatus = '任務成功完成';const outputData = workInfo.outputData;const imagePath = outputData?.getString('processed_image_path');hilog.info(0x0000, 'WorkManagerDemo', `處理后的圖像路徑: ${imagePath}`);break;case WorkInfo.State.FAILED:this.workStatus = '任務執行失敗';break;case WorkInfo.State.CANCELLED:this.workStatus = '任務已取消';break;}}// 創建任務鏈private async createWorkChain(): Promise<void> {try {const workManager = WorkManager.getInstance(this.context);// 第一個任務:下載圖像const downloadWork = new WorkRequest.Builder(this.context).setWorkerClass(ImageDownloadWorker).setConstraints({requiredNetworkType: WorkRequest.NetworkType.CONNECTED}).build();// 第二個任務:處理圖像(依賴第一個任務)const processWork = new WorkRequest.Builder(this.context).setWorkerClass(ImageProcessingWorker).setConstraints({requiresBatteryNotLow: true}).build();// 第三個任務:上傳結果const uploadWork = new WorkRequest.Builder(this.context).setWorkerClass(ImageUploadWorker).setConstraints({requiredNetworkType: WorkRequest.NetworkType.UNMETERED}).build();// 創建任務鏈:下載 → 處理 → 上傳await workManager.beginWith(downloadWork).then(processWork).then(uploadWork).enqueue();this.workStatus = '任務鏈已提交';hilog.info(0x0000, 'WorkManagerDemo', '圖像處理任務鏈提交成功');} catch (error) {const err = error as BusinessError;hilog.error(0x0000, 'WorkManagerDemo', `創建任務鏈失敗: ${err.message}`);}}build() {Column({ space: 10 }) {Text('WorkManager任務管理演示').fontSize(20).margin(10)Text(`任務狀態: ${this.workStatus}`).fontSize(16).margin(5)Button('提交圖像處理任務').onClick(() => this.createImageProcessingWork()).width('80%').margin(10)Button('提交任務鏈').onClick(() => this.createWorkChain()).width('80%').margin(10)Button('取消任務').onClick(async () => {if (this.workId) {const workManager = WorkManager.getInstance(this.context);await workManager.cancelWorkById(this.workId);this.workStatus = '任務已取消';}}).width('80%').margin(10)}.width('100%').height('100%')}
}

4. 高級特性與最佳實踐

4.1 智能任務調度策略

根據設備狀態和用戶習慣智能調度任務:

import { backgroundTaskManager } from '@ohos.resourceschedule.backgroundTaskManager';
import deviceInfo from '@ohos.deviceInfo';
import { BusinessError } from '@ohos.base';class SmartScheduler {// 根據設備狀態選擇最佳調度策略static async scheduleWithSmartStrategy(jobInfo: JobInfo): Promise<void> {const deviceType = deviceInfo.deviceType;const isLowEndDevice = deviceInfo.totalMemory < 1024; // 內存小于1GB// 根據設備類型調整任務參數if (deviceType === 'wearable' || isLowEndDevice) {// 穿戴設備或低端設備:減少頻率,增加延遲容忍度jobInfo.period = jobInfo.period ? jobInfo.period * 2 : 4 * 60 * 60 * 1000; // 每4小時jobInfo.isBatteryNotLowRequired = true;jobInfo.requiredNetworkType = backgroundTaskManager.NetworkType.NETWORK_TYPE_UNMETERED;} else if (deviceType === 'tablet' || deviceType === 'pc') {// 平板或PC:更積極的調度策略jobInfo.period = jobInfo.period || 60 * 60 * 1000; // 每1小時jobInfo.isChargingRequired = false;}// 根據時間選擇執行窗口(避免用戶活躍時段)const currentHour = new Date().getHours();if (currentHour >= 9 && currentHour <= 18) {// 白天工作時間:降低優先級jobInfo.priority = backgroundTaskManager.JobPriority.PRIORITY_LOW;} else {// 夜間:正常優先級jobInfo.priority = backgroundTaskManager.JobPriority.PRIORITY_DEFAULT;}try {const scheduler = backgroundTaskManager.getJobScheduler(getContext());await scheduler.schedule(jobInfo);} catch (error) {throw new Error(`智能調度失敗: ${(error as BusinessError).message}`);}}// 根據網絡類型調整任務行為static async adjustForNetworkType(taskId: string): Promise<void> {import network from '@ohos.net';const netHandle = await network.getDefaultNet();const netCapabilities = await netHandle.getNetCapabilities();if (netCapabilities.hasCapability(network.NetCap.NET_CAPABILITY_INTERNET)) {if (netCapabilities.hasCapability(network.NetCap.NET_CAPABILITY_NOT_METERED)) {// 非計量網絡:執行大數據量任務await this.executeDataIntensiveTask(taskId);} else {// 計量網絡:執行必要的小數據量任務await this.executeEssentialTaskOnly(taskId);}}}
}

4.2 任務監控與調試

實現任務執行監控和性能分析:

import { WorkManager, WorkInfo } from '@ohos.app.dispatcher.workManager';
import hilog from '@ohos.hilog';class TaskMonitor {private static monitoredWorks: Map<string, number> = new Map();// 監控任務執行時間static startMonitoring(workId: string): void {this.monitoredWorks.set(workId, Date.now());hilog.info(0x0000, 'TaskMonitor', `開始監控任務: ${workId}`);}// 記錄任務完成情況static recordCompletion(workId: string, success: boolean): void {const startTime = this.monitoredWorks.get(workId);if (startTime) {const duration = Date.now() - startTime;hilog.info(0x0000, 'TaskMonitor', `任務 ${workId} ${success ? '完成' : '失敗'}, 耗時: ${duration}ms`);this.monitoredWorks.delete(workId);// 性能統計:記錄到分析平臺this.logPerformanceMetrics(workId, duration, success);}}// 監控所有任務狀態static async monitorAllWorks(): Promise<void> {try {const workManager = WorkManager.getInstance(getContext());const workInfos = await workManager.getWorkInfos();workInfos.forEach((workInfo: WorkInfo) => {hilog.debug(0x0000, 'TaskMonitor', `任務 ${workInfo.id}: ${workInfo.state}, 嘗試次數: ${workInfo.runAttemptCount}`);});} catch (error) {hilog.error(0x0000, 'TaskMonitor', '監控任務狀態失敗');}}
}

5. 性能優化與資源管理

5.1 電池優化策略

import batteryInfo from '@ohos.batteryInfo';
import { backgroundTaskManager } from '@ohos.resourceschedule.backgroundTaskManager';class BatteryAwareScheduler {// 根據電池狀態調整任務調度static async scheduleWithBatteryAwareness(jobInfo: JobInfo): Promise<void> {const batteryLevel = await batteryInfo.getBatteryLevel();const isCharging = await batteryInfo.isCharging();if (batteryLevel < 20 && !isCharging) {// 低電量未充電:只執行關鍵任務if (!this.isCriticalTask(jobInfo)) {hilog.info(0x0000, 'BatteryAwareScheduler', '電池電量低,延遲非關鍵任務');jobInfo.minLatency = 6 * 60 * 60 * 1000; // 延遲6小時}}if (batteryLevel > 80 || isCharging) {// 高電量或充電中:執行資源密集型任務jobInfo.isBatteryNotLowRequired = false;}}private static isCriticalTask(jobInfo: JobInfo): boolean {const criticalTags = ['sync', 'notification', 'backup'];return criticalTags.some(tag => jobInfo.abilityName.includes(tag));}
}

5.2 內存優化策略

import systemMemory from '@ohos.systemMemory';class MemoryAwareWorker {// 檢查內存狀態后再執行任務async executeWithMemoryCheck(task: () => Promise<void>): Promise<void> {const memoryInfo = await systemMemory.getMemoryInfo();const availableMemory = memoryInfo.availRam;if (availableMemory < 100 * 1024 * 1024) { // 100MB閾值hilog.warn(0x0000, 'MemoryAwareWorker', '可用內存不足,延遲任務執行');await this.cleanupMemory();await new Promise(resolve => setTimeout(resolve, 30000)); // 等待30秒}await task();}private async cleanupMemory(): Promise<void> {// 清理緩存、釋放資源hilog.info(0x0000, 'MemoryAwareWorker', '執行內存清理');}
}

6. 實戰案例:智能數據同步系統

以下是一個完整的智能數據同步系統示例:

import { backgroundTaskManager, JobInfo, JobScheduler } from '@ohos.resourceschedule.backgroundTaskManager';
import { WorkManager, WorkRequest, Constraints } from '@ohos.app.dispatcher.workManager';
import { BusinessError } from '@ohos.base';
import deviceInfo from '@ohos.deviceInfo';
import network from '@ohos.net';@Entry
@Component
struct SmartDataSyncSystem {private context: common.Context = getContext(this) as common.Context;@State systemStatus: string = '就緒';// 初始化智能同步系統async aboutToAppear(): Promise<void> {await this.initializeSyncSystem();}private async initializeSyncSystem(): Promise<void> {// 根據設備能力選擇不同的調度策略const deviceCapabilities = await this.assessDeviceCapabilities();if (deviceCapabilities.highPerformance) {await this.scheduleAggressiveSyncStrategy();} else {await this.scheduleConservativeSyncStrategy();}this.systemStatus = '同步系統已初始化';}// 評估設備能力private async assessDeviceCapabilities(): Promise<{ highPerformance: boolean }> {const totalMemory = deviceInfo.totalMemory;const deviceType = deviceInfo.deviceType;const netHandle = await network.getDefaultNet();const netCapabilities = await netHandle.getNetCapabilities();return {highPerformance: totalMemory >= 2048 && // 2GB以上內存deviceType !== 'wearable' && // 非穿戴設備netCapabilities.hasCapability(network.NetCap.NET_CAPABILITY_INTERNET)};}// 高性能設備策略:頻繁同步private async scheduleAggressiveSyncStrategy(): Promise<void> {const jobInfo: JobInfo = {jobId: 2001,bundleName: this.context.applicationInfo.name,abilityName: 'DataSyncJob',type: backgroundTaskManager.JobType.JOB_TYPE_PERIODIC,period: 30 * 60 * 1000, // 每30分鐘requiredNetworkType: backgroundTaskManager.NetworkType.NETWORK_TYPE_ANY,isPersisted: true,extras: { 'sync_mode': 'aggressive' }};const scheduler = backgroundTaskManager.getJobScheduler(this.context);await scheduler.schedule(jobInfo);}// 低性能設備策略:保守同步private async scheduleConservativeSyncStrategy(): Promise<void> {const constraints: Constraints = {requiredNetworkType: WorkRequest.NetworkType.UNMETERED,requiresCharging: true,requiresBatteryNotLow: true};const workRequest = new WorkRequest.Builder(this.context).setWorkerClass(DataSyncWorker).setConstraints(constraints).setPeriodic(2 * 60 * 60 * 1000) // 每2小時.build();const workManager = WorkManager.getInstance(this.context);await workManager.enqueue(workRequest);}build() {Column({ space: 10 }) {Text('智能數據同步系統').fontSize(20).margin(10)Text(`系統狀態: ${this.systemStatus}`).fontSize(16).margin(5)Button('立即同步').onClick(() => this.triggerImmediateSync()).width('80%').margin(10)Button('查看同步統計').onClick(() => this.showSyncStatistics()).width('80%').margin(10)}.width('100%').height('100%')}
}

7. 總結

通過合理使用JobScheduler和WorkManager,開發者可以在HarmonyOS中實現高效、智能的后臺任務調度:

  1. 正確選擇調度器:精確計時需求用JobScheduler,復雜工作流用WorkManager
  2. 智能條件判斷:根據設備狀態、網絡條件、電池情況動態調整任務策略
  3. 資源優化:實現內存和電池感知的任務調度,提升系統整體性能
  4. 監控調試:建立完善的任務監控體系,確保任務可靠執行
  5. 用戶體驗:避免在用戶活躍時段執行資源密集型任務

遵循這些最佳實踐,可以構建出既高效又省電的后臺任務系統,為用戶提供無縫的應用體驗。

需要參加鴻蒙認證的請點擊 鴻蒙認證鏈接

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

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

相關文章

Prompt工程實踐

你在寫prompt時候&#xff0c;是不是總覺得大模型它不聽話。要么答非所問、要么一堆廢話。扒開思考過程仔細閱讀時而覺得它聰明絕頂&#xff0c;時而又覺得它愚蠢至極。明明已經對了怎么又推理到錯的地方去了&#xff0c;明明在提示詞中提醒過了不要這么思考它怎么就瞎想了。這…

基于springboot的畢業旅游一站式定制系統

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了多年的設計程序開發&#xff0c;開發過上千套設計程序&#xff0c;沒有什么華麗的語言&#xff0c;只有實…

輸入1.8V~5.5V 輸出28V DCDC升壓芯片TLV61046A

今天來一款TI的升壓芯片TLV61046A。輸入電壓范圍1.8V~5.5V。最高可以輸出28V。開關電流980mA&#xff0c;那具體能輸出多大的電流就得看輸入輸出的電壓了。以上面的輸入3.6V輸出12V為例&#xff0c;效率是85%&#xff0c;那最高可以輸出的電流就差不多只有200mA左右。封裝也是非…

ubuntu22.04源碼安裝ffmpeg-4.4

# ubuntu22.04源碼安裝ffmpeg-4.4cd /tmpwget https://ffmpeg.org/releases/ffmpeg-4.4.6.tar.xztar -xvf ffmpeg-4.4.6.tar.xzcd ffmpeg-4.4.6apt updateapt install -y yasm pkg-config libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev libav…

Pyhon中字符串常用的函數

一、字符串的格式化1.format()方法format()是 Python 中用于字符串格式化的方法&#xff0c;通過占位符&#xff08;如 {}&#xff09;動態插入變量或表達式。name小明 age18 grade99.556245585 information"我是{}&#xff0c;今年{}歲了,考試得分&#xff1a;{:.2f}&quo…

小迪安全v2023學習筆記(八十一講)—— 框架安全ThinkPHPLaravelStruts2SpringBootCVE復現

文章目錄前記服務攻防——第八十一天開發框架安全&SpringBoot&Struts2&Laravel&ThinkPHP&CVE復現開發框架 - 常見語言開發框架PHP - 框架安全-Thinkphp&LaravelLaravel漏洞介紹漏洞復現CVE-2021-3129ThinkPHP漏洞介紹漏洞復現CVE-2018-1002015QVD-2022…

從音頻到Token:構建原神角色語音識別模型的完整實踐

本文將帶你從零實現一個基于音頻Token化的角色語音識別系統&#xff0c;完整復現原神角色語音分類任務&#xff0c;包含數據處理、模型訓練和推理全流程。音頻波形通過滑動窗口轉換為數值Token序列的過程 一、為什么需要音頻Token化&#xff1f; 傳統音頻處理通常依賴MFCC、頻譜…

關于TCP和UDP兩種網絡協議的區別

1、tcp協議TCP (Transmission Control Protocol - 傳輸控制協議)TCP 的核心目標是為應用層提供一條可靠的、無差錯的、有序的字節流通道。主要特點&#xff1a;面向連接&#xff1a;在數據傳輸之前&#xff0c;必須通過“三次握手”建立穩定的連接&#xff0c;傳輸結束后通過“…

Alibaba Lens:阿里巴巴推出的 AI 圖像搜索瀏覽器擴展,助力B2B采購

本文轉載自&#xff1a;https://www.hello123.com/alibaba-lens ** 一、&#x1f31f; 一鍵截圖&#xff0c;輕松找貨&#xff1a;采購神器 Alibaba Lens 詳解 Alibaba Lens 是阿里巴巴集團專為全球 B2B 采購商打造的一款智能瀏覽器插件&#xff08;支持 Chrome 等主流瀏覽器…

WPF常見問題清單

1.Grid 內容自動換行及自適應行高 <DataGrid Grid.Row"1" FontSize"14" IsReadOnly"True" VerticalScrollBarVisibility"Auto" RowHeight"NaN" ItemsSource"{Binding List}" AutoGenerateColumns"False…

Linux驅動開發筆記(十)——中斷

視頻&#xff1a;第13.1講 Linux中斷實驗-Linux內核中斷框架簡介_嗶哩嗶哩_bilibili 文檔&#xff1a;《【正點原子】I.MX6U嵌入式Linux驅動開發指南V1.81.pdf》五十一章 1. 中斷API函數 每個中斷都有一個中斷號&#xff0c;通過中斷號即可區分不同的中斷。在Linux 內核中使用一…

ubuntu18.04安裝PCL1.14

簡化版說明 1. 安裝依賴庫&#xff1a; (1) boost1.84 &#xff08;https://www.boost.org/releases/1.84.0/&#xff09; tar vxf boost_xxx.tar.gz ./bootstrap.sh --prefix/usr/local/ ./b2 sudo ./b2 install (2) vtk9.1.0 &#xff08;https://vtk.org/files/releas…

python將pdf轉txt,并切割ai

python將pdf轉txt&#xff0c;并切割ai step1:pdf轉換 from PIL import Image import pytesseract import os import tempfile from pdf2image import convert_from_path# 設置 Tesseract 路徑 pytesseract.pytesseract.tesseract_cmd rC:\Users\wangrusheng\AppData\Local\Pr…

Ubuntu22.04更換阿里鏡像源,ubuntu更換源

在 Ubuntu 22.04 上更換為阿里云鏡像源可以加速軟件包的下載和更新&#xff0c;大幅提升系統更新速度。以下是更換阿里云鏡像源的步驟&#xff1a;1. 備份現有源列表在更換鏡像源之前&#xff0c;建議先備份當前的源配置文件&#xff1a;bashsudo cp /etc/apt/sources.list /et…

Git版本控制工具+基礎命令

Git是什么&#xff1f;Git是目前世界上最先進的分布式版本控制系統代碼托管平臺&#xff1a;Gitlab/Github/Gitee&#xff08;碼云&#xff09;什么是版本控制系統&#xff1f;指對軟件開發過程中各種程序代碼、配置文件及說明文檔等文件變更的管理。版本控制最主要的功能就是追…

圖解設計模式【3】

本系列共分為三篇文章&#xff0c;其中包含的設計模式如下表&#xff1a; 名稱設計模式圖解設計模式【1】Iterator、Adapter、Template Method、Factory Method、Singleton、Prototype、 Builder、Abstract Factory、 Bridge、 Strategy圖解設計模式【2】Composite、 Decorato…

(純新手教學)計算機視覺(opencv)實戰十四——模板與多個對象匹配

圖片旋轉、圖片鏡像相關教學&#xff1a; &#xff08;純新手教學&#xff09;計算機視覺&#xff08;opencv&#xff09;實戰十三——圖片旋轉、圖片鏡像 的幾種常用方法-CSDN博客https://blog.csdn.net/2302_78022640/article/details/151356600?spm1011.2415.3001.5331 模板…

Java面試核心知識點總結:Redis與MySQL高可用、高并發解決方案

在分布式系統開發中&#xff0c;高并發場景下的數據一致性、系統可用性以及性能優化始終是核心挑戰。本文基于Java技術棧&#xff0c;結合Redis與MySQL的工程實踐&#xff0c;系統梳理分布式系統設計的關鍵技術要點。一、Redis集群架構演進與高可用實踐1.1 主從哨兵模式部署方案…

R 語言科研繪圖第 72 期 --- mantel檢驗圖

在發表科研論文的過程中&#xff0c;科研繪圖是必不可少的&#xff0c;一張好看的圖形會是文章很大的加分項。 為了便于使用&#xff0c;本系列文章介紹的所有繪圖都已收錄到了 sciRplot 項目中&#xff0c;獲取方式&#xff1a; R 語言科研繪圖模板 --- sciRplothttps://mp.…

4.2-中間件之MySQL

4.2.1MySQL的基本知識SQL語句用于存取數據以及查詢、更新和管理關系數據庫系統。包括&#xff1a;DQL&#xff08;select&#xff09;、DML&#xff08;insert,update,delete&#xff09;、DDL&#xff08;create,alter,drop&#xff09;、DCL&#xff08;grant,revoke&#xf…