华为HarmonyOS实现实时语音识别转文本
场景介绍
将一段音频信息(短语音模式不超过60s,长语音模式不超过8h)转换为文本,音频信息可以为pcm音频文件或者实时语音。
开发步骤
- 在使用语音识别时,将实现语音识别相关的类添加至工程。
-
import { speechRecognizer } from '@kit.CoreSpeechKit'; import { BusinessError } from '@kit.BasicServicesKit';
-
- 调用createEngine方法,对引擎进行初始化,并创建SpeechRecognitionEngine实例。
createEngine方法提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
-
let asrEngine: speechRecognizer.SpeechRecognitionEngine; let sessionId: string = '123456'; // 创建引擎,通过callback形式返回 // 设置创建引擎参数 let extraParam: Record<string, Object> = {"locate": "CN", "recognizerMode": "short"}; let initParamsInfo: speechRecognizer.CreateEngineParams = { language: 'zh-CN', online: 1, extraParams: extraParam }; // 调用createEngine方法 speechRecognizer.createEngine(initParamsInfo, (err: BusinessError, speechRecognitionEngine: speechRecognizer.SpeechRecognitionEngine) => { if (!err) { console.info('Succeeded in creating engine.'); // 接收创建引擎的实例 asrEngine = speechRecognitionEngine; } else { // 无法创建引擎时返回错误码1002200008,原因:引擎正在销毁中 console.error(`Failed to create engine. Code: ${err.code}, message: ${err.message}.`); } });
-
- 得到SpeechRecognitionEngine实例对象后,实例化RecognitionListener对象,调用setListener方法设置回调,用来接收语音识别相关的回调信息。
-
// 创建回调对象 let setListener: speechRecognizer.RecognitionListener = { // 开始识别成功回调 onStart(sessionId: string, eventMessage: string) { console.info(`onStart, sessionId: ${sessionId} eventMessage: ${eventMessage}`); }, // 事件回调 onEvent(sessionId: string, eventCode: number, eventMessage: string) { console.info(`onEvent, sessionId: ${sessionId} eventCode: ${eventCode} eventMessage: ${eventMessage}`); }, // 识别结果回调,包括中间结果和最终结果 onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) { console.info(`onResult, sessionId: ${sessionId} sessionId: ${JSON.stringify(result)}`); }, // 识别完成回调 onComplete(sessionId: string, eventMessage: string) { console.info(`onComplete, sessionId: ${sessionId} eventMessage: ${eventMessage}`); }, // 错误回调,错误码通过本方法返回 // 如:返回错误码1002200006,识别引擎正忙,引擎正在识别中 // 更多错误码请参考错误码参考 onError(sessionId: string, errorCode: number, errorMessage: string) { console.error(`onError, sessionId: ${sessionId} errorCode: ${errorCode} errorMessage: ${errorMessage}`); } } // 设置回调 asrEngine.setListener(setListener);
-
- 分别为音频文件转文字和麦克风转文字功能设置开始识别的相关参数,调用startListening方法,开始合成。
-
// 开始识别 private startListeningForWriteAudio() { // 设置开始识别的相关参数 let recognizerParams: speechRecognizer.StartParams = { sessionId: this.sessionId, audioInfo: { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 } //audioInfo参数配置请参考AudioInfo } // 调用开始识别方法 asrEngine.startListening(recognizerParams); }; private startListeningForRecording() { let audioParam: speechRecognizer.AudioInfo = { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 } let extraParam: Record<string, Object> = { "recognitionMode": 0, "vadBegin": 2000, "vadEnd": 3000, "maxAudioDuration": 20000 } let recognizerParams: speechRecognizer.StartParams = { sessionId: this.sessionId, audioInfo: audioParam, extraParams: extraParam } console.info('startListening start'); asrEngine.startListening(recognizerParams); };
-
- 传入音频流,调用writeAudio方法,开始写入音频流。读取音频文件时,开发者需预先准备一个pcm格式音频文件。
-
let uint8Array: Uint8Array = new Uint8Array(); // 可以通过如下方式获取音频流:1、通过录音获取音频流;2、从音频文件中读取音频流 // 2、从音频文件中读取音频流:demo参考 // 写入音频流,音频流长度仅支持640或1280 asrEngine.writeAudio(sessionId, uint8Array);
-
- (可选)当需要查询语音识别服务支持的语种信息,可调用listLanguages方法。 listLanguages方法提供了两种调用形式,当前以其中一种作为示例,其他方式可参考API参考。
// 设置查询相关的参数 let languageQuery: speechRecognizer.LanguageQuery = { sessionId: sessionId }; // 调用listLanguages方法 asrEngine.listLanguages(languageQuery).then((res: Array<string>) => { console.info(`Succeeded in listing languages, result: ${JSON.stringify(res)}.`); }).catch((err: BusinessError) => { console.error(`Failed to list languages. Code: ${err.code}, message: ${err.message}.`); });
- (可选)当需要结束识别时,可调用finish方法。
-
// 结束识别 asrEngine.finish(sessionId);
-
- (可选)当需要取消识别时,可调用cancel方法。
-
// 取消识别 asrEngine.cancel(sessionId);
-
- (可选)当需要释放语音识别引擎资源时,可调用shutdown方法。
// 释放识别引擎资源 asrEngine.shutdown();
- 需要在module.json5配置文件中添加ohos.permission.MICROPHONE权限,确保麦克风使用正常。详细步骤可查看声明权限章节。
//... "requestPermissions": [ { "name" : "ohos.permission.MICROPHONE", "reason": "$string:reason", "usedScene": { "abilities": [ "EntryAbility" ], "when":"inuse" } } ], //...
开发实例
点击按钮,将一段音频信息转换为文本。index.ets文件如下:
import { speechRecognizer } from '@kit.CoreSpeechKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo } from '@kit.CoreFileKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import AudioCapturer from './AudioCapturer';
const TAG = 'CoreSpeechKitDemo';
let asrEngine: speechRecognizer.SpeechRecognitionEngine;
@Entry
@Component
struct Index {
@State createCount: number = 0;
@State result: boolean = false;
@State voiceInfo: string = "";
@State sessionId: string = "123456";
private mAudioCapturer = new AudioCapturer();
build() {
Column() {
Scroll() {
Column() {
Button() {
Text("CreateEngineByCallback")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.createCount++;
hilog.info(0x0000, TAG, `CreateAsrEngine:createCount:${this.createCount}`);
this.createByCallback();
})
Button() {
Text("setListener")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.setListener();
})
Button() {
Text("startRecording")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.startRecording();
})
Button() {
Text("writeAudio")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.writeAudio();
})
Button() {
Text("queryLanguagesCallback")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
this.queryLanguagesCallback();
})
Button() {
Text("finish")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 结束识别
hilog.info(0x0000, TAG, "finish click:-->");
asrEngine.finish(this.sessionId);
})
Button() {
Text("cancel")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AE7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 取消识别
hilog.info(0x0000, TAG, "cancel click:-->");
asrEngine.cancel(this.sessionId);
})
Button() {
Text("shutdown")
.fontColor(Color.White)
.fontSize(20)
}
.type(ButtonType.Capsule)
.backgroundColor("#0x317AA7")
.width("80%")
.height(50)
.margin(10)
.onClick(() => {
// 释放引擎
asrEngine.shutdown();
})
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
}
// 创建引擎,通过callback形式返回
private createByCallback() {
// 设置创建引擎参数
let extraParam: Record<string, Object> = {"locate": "CN", "recognizerMode": "short"};
let initParamsInfo: speechRecognizer.CreateEngineParams = {
language: 'zh-CN',
online: 1,
extraParams: extraParam
};
// 调用createEngine方法
speechRecognizer.createEngine(initParamsInfo, (err: BusinessError, speechRecognitionEngine:
speechRecognizer.SpeechRecognitionEngine) => {
if (!err) {
hilog.info(0x0000, TAG, 'Succeeded in creating engine.');
// 接收创建引擎的实例
asrEngine = speechRecognitionEngine;
} else {
// 无法创建引擎时返回错误码1002200001,原因:语种不支持、模式不支持、初始化超时、资源不存在等导致创建引擎失败
// 无法创建引擎时返回错误码1002200006,原因:引擎正在忙碌中,一般多个应用同时调用语音识别引擎时触发
// 无法创建引擎时返回错误码1002200008,原因:引擎正在销毁中
hilog.error(0x0000, TAG, `Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
}
// 查询语种信息,以callback形式返回
private queryLanguagesCallback() {
// 设置查询相关参数
let languageQuery: speechRecognizer.LanguageQuery = {
sessionId: '123456'
};
// 调用listLanguages方法
asrEngine.listLanguages(languageQuery, (err: BusinessError, languages: Array<string>) => {
if (!err) {
// 接收目前支持的语种信息
hilog.info(0x0000, TAG, `Succeeded in listing languages, result: ${JSON.stringify(languages)}`);
} else {
hilog.error(0x0000, TAG, `Failed to create engine. Code: ${err.code}, message: ${err.message}.`);
}
});
};
// 开始识别
private startListeningForWriteAudio() {
// 设置开始识别的相关参数
let recognizerParams: speechRecognizer.StartParams = {
sessionId: this.sessionId,
audioInfo: { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 } //audioInfo参数配置请参考AudioInfo
}
// 调用开始识别方法
asrEngine.startListening(recognizerParams);
};
private startListeningForRecording() {
let audioParam: speechRecognizer.AudioInfo = { audioType: 'pcm', sampleRate: 16000, soundChannel: 1, sampleBit: 16 }
let extraParam: Record<string, Object> = {
"recognitionMode": 0,
"vadBegin": 2000,
"vadEnd": 3000,
"maxAudioDuration": 20000
}
let recognizerParams: speechRecognizer.StartParams = {
sessionId: this.sessionId,
audioInfo: audioParam,
extraParams: extraParam
}
hilog.info(0x0000, TAG, 'startListening start');
asrEngine.startListening(recognizerParams);
};
// 写音频流
private async writeAudio() {
this.startListeningForWriteAudio();
hilog.error(0x0000, TAG, `Failed to read from file. Code`);
let ctx = getContext(this);
let filenames: string[] = fileIo.listFileSync(ctx.filesDir);
if (filenames.length <= 0) {
hilog.error(0x0000, TAG, `Failed to read from file. Code`);
return;
}
hilog.error(0x0000, TAG, `Failed to read from file. Code`);
let filePath: string = `${ctx.filesDir}/${filenames[0]}`;
let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE);
try {
let buf: ArrayBuffer = new ArrayBuffer(1280);
let offset: number = 0;
while (1280 == fileIo.readSync(file.fd, buf, {
offset: offset
})) {
let uint8Array: Uint8Array = new Uint8Array(buf);
asrEngine.writeAudio("123456", uint8Array);
await this.countDownLatch(1);
offset = offset + 1280;
}
} catch (err) {
hilog.error(0x0000, TAG, `Failed to read from file. Code: ${err.code}, message: ${err.message}.`);
} finally {
if (null != file) {
fileIo.closeSync(file);
}
}
}
// 麦克风语音转文本
private async startRecording() {
this.startListeningForRecording();
// 录音获取音频
let data: ArrayBuffer;
hilog.info(0x0000, TAG, 'create capture success');
this.mAudioCapturer.init((dataBuffer: ArrayBuffer) => {
hilog.info(0x0000, TAG, 'start write');
hilog.info(0x0000, TAG, 'ArrayBuffer ' + JSON.stringify(dataBuffer));
data = dataBuffer
let unit8Array: Uint8Array = new Uint8Array(data);
hilog.info(0x0000, TAG, 'ArrayBuffer unit8Array ' + JSON.stringify(unit8Array));
// 写入音频流
asrEngine.writeAudio("1234567", unit8Array);
});
};
// 计时
public async countDownLatch(count: number) {
while (count > 0) {
await this.sleep(40);
count--;
}
}
// 睡眠
private sleep(ms: number):Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 设置回调
private setListener() {
// 创建回调对象
let setListener: speechRecognizer.RecognitionListener = {
// 开始识别成功回调
onStart(sessionId: string, eventMessage: string) {
hilog.info(0x0000, TAG, `onStart, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
},
// 事件回调
onEvent(sessionId: string, eventCode: number, eventMessage: string) {
hilog.info(0x0000, TAG, `onEvent, sessionId: ${sessionId} eventCode: ${eventCode} eventMessage: ${eventMessage}`);
},
// 识别结果回调,包括中间结果和最终结果
onResult(sessionId: string, result: speechRecognizer.SpeechRecognitionResult) {
hilog.info(0x0000, TAG, `onResult, sessionId: ${sessionId} sessionId: ${JSON.stringify(result)}`);
},
// 识别完成回调
onComplete(sessionId: string, eventMessage: string) {
hilog.info(0x0000, TAG, `onComplete, sessionId: ${sessionId} eventMessage: ${eventMessage}`);
},
// 错误回调,错误码通过本方法返回
// 返回错误码1002200002,开始识别失败,重复启动startListening方法时触发
// 更多错误码请参考错误码参考
onError(sessionId: string, errorCode: number, errorMessage: string) {
hilog.error(0x0000, TAG, `onError, sessionId: ${sessionId} errorCode: ${errorCode} errorMessage: ${errorMessage}`);
},
}
// 设置回调
asrEngine.setListener(setListener);
};
}
添加AudioCapturer.ts文件用于获取麦克风音频流。
'use strict';
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/import {audio} from '@kit.AudioKit';
import { hilog } from '@kit.PerformanceAnalysisKit';const TAG = 'AudioCapturer';/**
* Audio collector tool
*/
export default class AudioCapturer {
/**
* Collector object
*/
private mAudioCapturer = null;/**
* Audio Data Callback Method
*/
private mDataCallBack: (data: ArrayBuffer) => void = null;/**
* Indicates whether recording data can be obtained.
*/
private mCanWrite: boolean = true;/**
* Audio stream information
*/
private audioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_16000,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
}/**
* Audio collector information
*/
private audioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0
}/**
* Audio Collector Option Information
*/
private audioCapturerOptions = {
streamInfo: this.audioStreamInfo,
capturerInfo: this.audioCapturerInfo
}/**
* Initialize
* @param audioListener
*/
public async init(dataCallBack: (data: ArrayBuffer) => void) {
if (null != this.mAudioCapturer) {
hilog.error(0x0000, TAG, 'AudioCapturerUtil already init');
return;
}
this.mDataCallBack = dataCallBack;
this.mAudioCapturer = await audio.createAudioCapturer(this.audioCapturerOptions).catch(error => {
hilog.error(0x0000, TAG, `AudioCapturerUtil init createAudioCapturer failed, code is ${error.code}, message is ${error.message}`);
});
}/**
* start recording
*/
public async start() {
hilog.error(0x0000, TAG, `AudioCapturerUtil start`);
let stateGroup = [audio.AudioState.STATE_PREPARED, audio.AudioState.STATE_PAUSED, audio.AudioState.STATE_STOPPED];
if (stateGroup.indexOf(this.mAudioCapturer.state) === -1) {
hilog.error(0x0000, TAG, `AudioCapturerUtil start failed`);
return;
}
this.mCanWrite = true;
await this.mAudioCapturer.start();
while (this.mCanWrite) {
let bufferSize = await this.mAudioCapturer.getBufferSize();
let buffer = await this.mAudioCapturer.read(bufferSize, true);
this.mDataCallBack(buffer)
}
}/**
* stop recording
*/
public async stop() {
if (this.mAudioCapturer.state !== audio.AudioState.STATE_RUNNING && this.mAudioCapturer.state !== audio.AudioState.STATE_PAUSED) {
hilog.error(0x0000, TAG, `AudioCapturerUtil stop Capturer is not running or paused`);
return;
}
this.mCanWrite = false;
await this.mAudioCapturer.stop();
if (this.mAudioCapturer.state === audio.AudioState.STATE_STOPPED) {
hilog.info(0x0000, TAG, `AudioCapturerUtil Capturer stopped`);
} else {
hilog.error(0x0000, TAG, `Capturer stop failed`);
}
}/**
* release
*/
public async release() {
if (this.mAudioCapturer.state === audio.AudioState.STATE_RELEASED || this.mAudioCapturer.state === audio.AudioState.STATE_NEW) {
hilog.error(0x0000, TAG, `Capturer already released`);
return;
}
await this.mAudioCapturer.release();
this.mAudioCapturer = null;
if (this.mAudioCapturer.state == audio.AudioState.STATE_RELEASED) {
hilog.info(0x0000, TAG, `Capturer released`);
} else {
hilog.error(0x0000, TAG, `Capturer release failed`);
}
}
}
在EntryAbility.ets文件中添加麦克风权限。
import { abilityAccessCtrl, AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');let atManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(this.context, ['ohos.permission.MICROPHONE']).then((data) => {
hilog.info(0x0000, 'testTag', 'data:' + JSON.stringify(data));
hilog.info(0x0000, 'testTag', 'data:' + JSON.stringify(data));
hilog.info(0x0000, 'testTag', 'data permissions:' + data.permissions);
hilog.info(0x0000, 'testTag', 'data authResults:' + data.authResults);
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag', 'errCode: ' + err.code + 'errMessage: ' + err.message);
});windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
相关文章:
华为HarmonyOS实现实时语音识别转文本
场景介绍 将一段音频信息(短语音模式不超过60s,长语音模式不超过8h)转换为文本,音频信息可以为pcm音频文件或者实时语音。 开发步骤 在使用语音识别时,将实现语音识别相关的类添加至工程。 import { speechRecogni…...
DIY可视化-uniapp悬浮菜单支持拖动、吸附-代码生成器
在Uniapp中,悬浮菜单支持拖动和吸附功能,可以为用户带来更加灵活和便捷的操作体验。以下是对这两个功能的详细解释: 悬浮菜单支持拖动 提高用户体验:用户可以根据自己的需要,将悬浮菜单拖动到屏幕上的任意位置&#x…...
HTTP cookie 与 session
一.Cookie 定义: 是服务器发送到用户浏览器并保存在浏览器上的一小块数据, 它会在浏览器之后向同一服务器再次发起请求时被携带并发送到服务器上。 通常, 它用于告知服务端两个请求是否来自同一浏览器, 如保持用户的登录状态、 …...
智慧停车场导航系统架构及反向寻车系统解决方案
一、系统概述: 随着当前室内定位导航技术在大型公共场所如政务中心、商业综合体、车站中的应用越来越多,人们对智慧停车场的需求也日益凸显出来,并且智慧停车场对大型公共场所智慧化的整体建设起到重要作用。如何更有效提高停车效率…...
【小程序上传图片封装2024,支持多图,带进度,上传头像】
import config from ./config;// 支持多图,显示进度 export function uploadImages(count 1, sourceType, onLoading null, showProgress false, fileKey file) {return new Promise((resolve, reject) > {wx.chooseMedia({count: count, // 可以选择的图片数…...
[A-14]ARMv8/ARMv9-Memory-内存模型的类型(Device Normal)
ver0.1 [看前序文章有惊喜。] 前言 前面花了很大的精力把ARM构建的VMSA中的几个核心的议题给大家做了介绍,相信大家已经能够理解并掌握ARM的内存子系统的工作原理大致框架。接下来我们会规划一些文章,对ARM内存子系统的一些细节做一下介绍,使ARM的内存子系统更加的丰满。本…...
驾校管理系统|基于java和小程序的驾校管理系统设计与实现(源码+数据库+文档)
驾校管理系统平台 目录 基于java和小程序的驾校管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&#…...
@Mapper使用中遇到的问题解法汇总
最近终于有时间写点代码相关的文章了,工作真的太忙了,果然又要测试又要开发的人最🐂🐴。 1.查询数据库有数据,但是代码中写select语句的时候查出为null Select("SELECT * FROM xx_manager order by id limit 1&q…...
深度学习:YOLO V3 网络架构解析
引言 YOLO V3(You Only Look Once Version 3)是YOLO系列算法的第三个版本,相比之前的版本,它在多个方面进行了优化和改进,不仅提升了检测精度,还保持了较快的检测速度。本文将详细介绍YOLO V3的主要改进以…...
SpringCloudAlibaba-Sentinel-熔断与限流
版本说明 <spring.boot.version>3.2.0</spring.boot.version> <spring.cloud.version>2023.0.0</spring.cloud.version> <spring.cloud.alibaba.version>2023.0.1.2</spring.cloud.alibaba.version>是什么 能干嘛 面试题 服务雪崩 安装使…...
mysql中的mvcc理解
是什么:MVCC指的是在读已提交、可重复读这两种隔离级别下的事务在执行普通的select操作时,访问记录的版本链的过程,可以使不同事务的读写操作并发执行,提高性能。 MVCC 隐藏字段 undo log 版本链 ReadView 1.隐藏字段…...
ETF申购赎回指南:详解注意事项与低费率券商推荐!
ETF 申购&赎回 ETF申购赎回是个啥业务? 01 ETF申购、赎回是一种交易委托方式,指投资者通过申购方式(买入方向)获得ETF份额,通过赎回的方式(卖出方向)换掉/卖出ETF份额。ETF申购,通常是通过一篮子成…...
List<T>属性和方法使用
//author:shark_ddd using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;//使用函数来减少长度namespace List_T {class Student{public string Name { get; set; }public int Age { get; set; …...
记一次:使用使用Dbeaver连接Clickhouse
前言:使用了navicat连接了clickhouse我感觉不太好用,就整理了一下dbeaver连接 0、使用Navicat连接clickhouse 测试连接 但是不能双击打开,可是使用命令页界面,右键命令页界面,然后可以用sql去测试 但是不太好用&#…...
Java面向对象编程进阶(四)
Java面向对象编程进阶(四) 一、equals()方法的使用二、toString()方法的使用三、复习 一、equals()方法的使用 适用性:任何引用数据都可以使用。 自定义的类在没有重写Object中equals()方法的情况下,调用的就是Object类中声明的…...
【51单片机】第一个小程序 —— 点亮LED灯
学习使用的开发板:STC89C52RC/LE52RC 编程软件:Keil5 烧录软件:stc-isp 开发板实图: 文章目录 单片机介绍LED灯介绍练习创建第一个项目点亮LED灯LED周期闪烁 单片机介绍 单片机,英文Micro Controller Unit࿰…...
如何通过自动化有效地简化 Active Directory 操作?
我们都知道规模稍微大一点的企业为了便于计算机的管理,基本都上了微软的AD域控制器。 那么肯定就会存在这么一个问题, 不断的会有计算机加入或者是退出域控制器,批量的创建、修改、删除AD域用户,如果企业的架构需要改变ÿ…...
Java-POI导出EXCEL(动态表头)
1、主要功能 导出excel,表头有固定的和动态的。动态表头之间不能穿插固定表头。 2、使用方法 引入下方两个工具类,定义excel固定表头类。调用方法即可。 调用方法: ExcelDynamicHeader<MajorNameChangeReport> ledgerSafetyProblemEx…...
利用 Direct3D 绘制几何体—9.流水线状态对象
到目前为止展示过编写输入布局描述、创建顶点着色器和像素着色器,以及配置光栅器状态组这 3 个步骤。接下来讲如何将这些对象绑定到图形流水线上,用以实际绘制图形。大多数控制图形流水线状态的对象被统称为流水线状态对象(Pipeline State Ob…...
【开源项目】libfaketime安装、使用——小白教程
项目 Github:GitHub - wolfcw/libfaketime: libfaketime modifies the system time for a single application libfaketime安装 01.切换路径,目标路径:/usr/local (在/usr/local路径下git clone 开源项目) 切换路径指令: cd …...
java.util.concurrent包
java.util.concurrent包是Java中用于并发编程的重要工具集,提供了丰富的并发原语和组件,以简化多线程编程的复杂性,并帮助开发者编写高效、可伸缩和线程安全的并发程序。其主要功能包括以下几个方面: 一、线程池和任务执行框架 …...
Django创建项目模块+创建映射类+视图
确保你的项目已经正确链接数据库 链接数据库的工具有很多,数据库的种类也有很多,我使用的数据库是mysql,工具是pmysql,使用pymysql链接数据库,在settings文件中这么设置: DATABASES {# default: {# ENGINE: dja…...
使用AMD GPU和LangChain构建问答聊天机器人
Question-answering Chatbot with LangChain on an AMD GPU — ROCm Blogs 作者:Phillip Dang 2024年3月11日 LangChain是一个旨在利用语言模型强大功能来构建前沿应用程序的框架。通过将语言模型连接到各种上下文资源并基于给定的上下文提供推理能力,L…...
2024年808数据结构答案
1.已知带头结点单链表,H为头指针。设计一个算法,查找到链表的第m个结点(不包含头结点),并将元 素值为X的结点插入到该结点后,形成一个新的链表。 // 定义单链表节点结构 typedef struct Node {int data;struct Node* next; } Nod…...
Amazon Linux 2023 安装 Docker
Amazon Linux 2023 安装 Docker 1. 简介 在公司需要将代码部属到 Amazon Linux 2023 系统上时,去 Docker 官方文档里面看也没有针对该系统的部属文档。虽然有通用的 Linux 部属方案但不能应用包管理工具。 首先执行yum、dnf、apt,执行yum和dnf都有正确…...
接口测试(八)jmeter——参数化(CSV Data Set Config)
一、CSV Data Set Config 需求:批量注册5个用户,从CSV文件导入用户数据 1. 【线程组】–>【添加】–>【配置元件】–>【CSV Data Set Config】 2. 【CSV数据文件设置】设置如下 3. 设置线程数为5 4. 运行后查看响应结果...
GGD证明推导学习
GGD证明推导学习 这篇文章,建议先看相关的论文。这篇是我读证明的感悟,因此,不会论文的主体内容 首先,给出命题: DGI的sumary向量是一个常数 给定一个图: G { X ∈ R N D , A ∈ R N N } \mathcal{G…...
Flink难点和高频考点:Flink的反压产生原因、排查思路、优化措施和监控方法
目录 反压定义 反压影响 WebUI监控 Metrics指标 backPressureTimeMsPerSecond idleTimeMsPerSecond busyTimeMsPerSecond 反压可视化 资源优化 算子优化 数据倾斜优化 复杂算子优化 背压机制 反压预防 性能调优 内置工具 第三方工具 反压定义 在探讨Flink的性…...
Swarm - Agent 编排工具
文章目录 一、关于 Swarm(实验性、教育性)为什么选择蜂群文档 二、安装使用安装基本用法其它示例 三、Running Swarmclient.run()ArgumentsResponse字段 四、AgentFields Agent指令函数切换和更新上下文变量函数模式 流媒体评估工具 一、关于 Swarm&…...
使用Python中的jieba库进行简单情感分析
在自然语言处理(NLP)领域,情感分析是一项重要的任务,它可以帮助我们理解文本背后的情感倾向。本文将通过一个简单的例子来介绍如何使用Python的jieba库对中文文本进行基本的情感分析。 1. 环境准备 首先,确保已经安装…...
广告联盟的网站怎么做/新疆今日头条新闻
①linuxpostfixextmaildovecot搭建邮件服务器②mysql主从复制③zabbix开启中文语言zabbix解决中文乱码问题④PXEKickStart无人值守安装RHEL⑤Tomcat 安全配置与性能优化转载于:https://blog.51cto.com/henxiangni/1609275...
太原seo代理商/哈尔滨推广优化公司
最近脑子比较乱,一直昏昏沉沉的。昨天加班,突然想吃葡萄。我(可能,其实我忘了。)跟我对面的同事嘀咕了一句: 我让阿姨去买点葡萄。然后就一溜小跑的到阿姨房间跑去。回来后。我:喂,*…...
广州白云区哪里封了/一键关键词优化
ifstat介绍ifstat工具是个网络接口监测工具,比较简单看网络流量实例默认使用#ifstateth0 eth1KB/s in KB/s out KB/s in KB/s out0.07 0.20 0.00 0.000.07 0.15 0.58 0.00默认ifstat不监控回环接口,显示的流量单位是KB。监控所有网络接口# ifstat -alo eth0 eth1KB/…...
电子配件 技术支持 东莞网站建设/关键词名词解释
题库来源:安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员考试内容是由公众号安全生产模拟考试一点通提供,危险化学品经营单位安全管理人员证模拟考试题库是根据危险化学品经营单位安全管理人员最新版教材汇编出危险化学品经营单位…...
互联网网站开发服务合同/网上兼职外宣推广怎么做
BZOJ放这种丝帛我也是醉了... 不过来填一下求最小循环节的坑... 以这道题为例,相同文本串粘起来的串中取一小节,可以把任意一个字符看做文本串头. 那么我们一次KMP求出next函数然后显见,最后一个字符它会与上一个循环串的尾匹配,所以减一减就好啦... /* # Last modified: 2016-…...
做网站的前途/广州网站优化工具
我在构思这篇文章。我想象自己能够在时机成熟时,把自己的想法都倾诉于纸端。但刚刚过去一个月,我就意识到这并非易事:随着工作的推进,我忘掉了很多自己刚刚学到的东西。这些东西快速内化,使我的大脑开始欺骗自己&#…...