鸿蒙OSUniApp 实现的语音输入与语音识别功能#三方框架 #Uniapp
UniApp 实现的语音输入与语音识别功能
最近在开发跨平台应用时,客户要求添加语音输入功能以提升用户体验。经过一番调研和实践,我成功在UniApp项目中实现了语音输入与识别功能,现将过程和方法分享出来,希望对有类似需求的开发者有所帮助。
为什么需要语音输入功能?
随着移动设备的普及,语音交互已成为一种高效的人机交流方式。与传统的文字输入相比,语音输入具有以下优势:
- 操作便捷:免去键盘敲击,尤其适合单手操作或行走等场景
- 输入高效:语音输入速度通常快于手动输入
- 提升体验:为特定人群(如老年人、视障人士)提供便利
- 解放双手:适用于驾车、做家务等无法腾出手打字的场景
在商业应用中,语音输入可以显著降低用户的操作门槛,提高转化率和用户留存。
技术方案选型
在UniApp环境中实现语音识别,主要有三种方案:
- 使用原生插件:调用各平台的原生语音识别能力
- 对接云服务:接入第三方语音识别API(如百度、讯飞等)
- Web API:在H5平台利用Web Speech API
经过对比和测试,我最终采用了混合方案:
- 在App平台使用原生插件获取最佳体验
- 在微信小程序使用微信自带的语音识别能力
- 在H5平台尝试使用Web Speech API,不支持时降级为云服务API
实现步骤
1. App端实现(基于原生插件)
首先需要安装语音识别插件。我选择了市场上比较成熟的speech-baidu插件,这是基于百度语音识别SDK封装的UniApp插件。
安装插件后,在manifest.json中配置:
"app-plus": {"plugins": {"speech": {"baidu": {"appid": "你的百度语音识别AppID","apikey": "你的API Key","secretkey": "你的Secret Key"}}},"distribute": {"android": {"permissions": ["<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>","<uses-permission android:name=\"android.permission.INTERNET\"/>"]}}
}
接下来创建语音识别组件:
<template><view class="voice-input-container"><view class="voice-btn" :class="{ 'recording': isRecording }"@touchstart="startRecord" @touchend="stopRecord"@touchcancel="cancelRecord"><image :src="isRecording ? '/static/mic-active.png' : '/static/mic.png'" mode="aspectFit"></image><text>{{ isRecording ? '松开结束' : '按住说话' }}</text></view><view v-if="isRecording" class="recording-tip"><text>正在聆听...</text><view class="wave-container"><view v-for="(item, index) in waveItems" :key="index" class="wave-item":style="{ height: item + 'rpx' }"></view></view></view></view>
</template><script>
// #ifdef APP-PLUS
const speechPlugin = uni.requireNativePlugin('speech-baidu');
// #endifexport default {name: 'VoiceInput',data() {return {isRecording: false,timer: null,waveItems: [10, 15, 20, 25, 30, 25, 20, 15, 10]}},props: {lang: {type: String,default: 'zh' // zh: 中文, en: 英文},maxDuration: {type: Number,default: 60 // 最长录音时间,单位秒}},methods: {startRecord() {if (this.isRecording) return;// 申请录音权限uni.authorize({scope: 'scope.record',success: () => {this.isRecording = true;this.startWaveAnimation();// #ifdef APP-PLUSspeechPlugin.start({vadEos: 3000, // 静音超时时间language: this.lang === 'zh' ? 'zh-cn' : 'en-us'}, (res) => {if (res.errorCode === 0) {// 识别结果this.$emit('result', res.result);} else {uni.showToast({title: `识别失败: ${res.errorCode}`,icon: 'none'});}this.isRecording = false;this.stopWaveAnimation();});// #endif// 设置最长录制时间this.timer = setTimeout(() => {if (this.isRecording) {this.stopRecord();}}, this.maxDuration * 1000);},fail: () => {uni.showToast({title: '请授权录音权限',icon: 'none'});}});},stopRecord() {if (!this.isRecording) return;// #ifdef APP-PLUSspeechPlugin.stop();// #endifclearTimeout(this.timer);this.isRecording = false;this.stopWaveAnimation();},cancelRecord() {if (!this.isRecording) return;// #ifdef APP-PLUSspeechPlugin.cancel();// #endifclearTimeout(this.timer);this.isRecording = false;this.stopWaveAnimation();},// 波形动画startWaveAnimation() {this.waveAnimTimer = setInterval(() => {this.waveItems = this.waveItems.map(() => Math.floor(Math.random() * 40) + 10);}, 200);},stopWaveAnimation() {clearInterval(this.waveAnimTimer);this.waveItems = [10, 15, 20, 25, 30, 25, 20, 15, 10];}},beforeDestroy() {this.cancelRecord();}
}
</script><style scoped>
.voice-input-container {width: 100%;
}.voice-btn {width: 200rpx;height: 200rpx;border-radius: 100rpx;background-color: #f5f5f5;display: flex;flex-direction: column;align-items: center;justify-content: center;margin: 0 auto;
}.voice-btn.recording {background-color: #e1f5fe;box-shadow: 0 0 20rpx rgba(0, 120, 255, 0.5);
}.voice-btn image {width: 80rpx;height: 80rpx;margin-bottom: 10rpx;
}.recording-tip {margin-top: 30rpx;text-align: center;
}.wave-container {display: flex;justify-content: center;align-items: flex-end;height: 80rpx;margin-top: 20rpx;
}.wave-item {width: 8rpx;background-color: #1890ff;margin: 0 5rpx;border-radius: 4rpx;transition: height 0.2s;
}
</style>
2. 微信小程序实现
微信小程序提供了原生的语音识别API,使用非常方便:
// 在小程序环境下的代码
startRecord() {// #ifdef MP-WEIXINthis.isRecording = true;this.startWaveAnimation();const recorderManager = wx.getRecorderManager();recorderManager.onStart(() => {console.log('录音开始');});recorderManager.onStop((res) => {this.isRecording = false;this.stopWaveAnimation();// 将录音文件发送到微信后台识别wx.showLoading({ title: '识别中...' });const { tempFilePath } = res;wx.uploadFile({url: 'https://api.weixin.qq.com/cgi-bin/media/voice/translatecontent',filePath: tempFilePath,name: 'media',formData: {access_token: this.accessToken,format: 'mp3',voice_id: Date.now(),lfrom: this.lang === 'zh' ? 'zh_CN' : 'en_US',lto: 'zh_CN'},success: (uploadRes) => {wx.hideLoading();const data = JSON.parse(uploadRes.data);if (data.errcode === 0) {this.$emit('result', data.result);} else {uni.showToast({title: `识别失败: ${data.errmsg}`,icon: 'none'});}},fail: () => {wx.hideLoading();uni.showToast({title: '语音识别失败',icon: 'none'});}});});recorderManager.start({duration: this.maxDuration * 1000,sampleRate: 16000,numberOfChannels: 1,encodeBitRate: 48000,format: 'mp3'});// #endif
},stopRecord() {// #ifdef MP-WEIXINwx.getRecorderManager().stop();// #endif// ...与App端相同的代码...
}
需要注意的是,微信小程序的语音识别需要获取access_token,这通常需要在后端实现并提供接口。
3. H5端实现
在H5端,我们可以利用Web Speech API来实现语音识别,当浏览器不支持时则降级为云服务API:
startRecord() {// #ifdef H5this.isRecording = true;this.startWaveAnimation();// 检查浏览器是否支持Speech Recognitionif ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;this.recognition = new SpeechRecognition();this.recognition.lang = this.lang === 'zh' ? 'zh-CN' : 'en-US';this.recognition.continuous = false;this.recognition.interimResults = false;this.recognition.onresult = (event) => {const result = event.results[0][0].transcript;this.$emit('result', result);};this.recognition.onerror = (event) => {uni.showToast({title: `识别错误: ${event.error}`,icon: 'none'});};this.recognition.onend = () => {this.isRecording = false;this.stopWaveAnimation();};this.recognition.start();} else {// 不支持Web Speech API,调用云服务APIthis.useCloudSpeechAPI();}// #endif// 设置最长录制时间this.timer = setTimeout(() => {if (this.isRecording) {this.stopRecord();}}, this.maxDuration * 1000);
},stopRecord() {// #ifdef H5if (this.recognition) {this.recognition.stop();}// #endif// ...与App端相同的代码...
},useCloudSpeechAPI() {// 这里实现降级方案,调用后端接口进行语音识别uni.chooseFile({count: 1,type: 'file',extension: ['.mp3', '.wav'],success: (res) => {const tempFilePath = res.tempFilePaths[0];// 上传音频文件到后端进行识别uni.uploadFile({url: this.apiBaseUrl + '/speech/recognize',filePath: tempFilePath,name: 'audio',formData: {lang: this.lang},success: (uploadRes) => {const data = JSON.parse(uploadRes.data);if (data.code === 0) {this.$emit('result', data.result);} else {uni.showToast({title: `识别失败: ${data.msg}`,icon: 'none'});}},complete: () => {this.isRecording = false;this.stopWaveAnimation();}});}});
}
4. 通用接口封装
为了让调用方便,我封装了一个统一的API:
// 在 utils/speech.js 中
const Speech = {// 开始语音识别startRecognize(options) {const { lang = 'zh', success, fail, complete } = options;// #ifdef APP-PLUSconst speechPlugin = uni.requireNativePlugin('speech-baidu');speechPlugin.start({vadEos: 3000,language: lang === 'zh' ? 'zh-cn' : 'en-us'}, (res) => {if (res.errorCode === 0) {success && success(res.result);} else {fail && fail(res);}complete && complete();});return {stop: () => speechPlugin.stop(),cancel: () => speechPlugin.cancel()};// #endif// #ifdef MP-WEIXIN// 微信小程序实现逻辑// ...// #endif// #ifdef H5// H5实现逻辑// ...// #endif}
};export default Speech;
实战案例:聊天应用中的语音输入
现在,我们来看一个实际应用场景 - 在聊天应用中添加语音输入功能:
<template><view class="chat-input-container"><view class="chat-tools"><image :src="isVoiceMode ? '/static/keyboard.png' : '/static/mic.png'" @tap="toggleInputMode"></image><image src="/static/emoji.png" @tap="showEmojiPicker"></image></view><view v-if="!isVoiceMode" class="text-input"><textareav-model="message"auto-heightplaceholder="请输入消息...":focus="textFocus"@focus="onFocus"@blur="onBlur"></textarea></view><view v-else class="voice-input"><voice-input @result="onVoiceResult"></voice-input></view><button class="send-btn" :disabled="!message.trim()" @tap="sendMessage">发送</button></view>
</template><script>
import VoiceInput from '@/components/voice-input/voice-input.vue';export default {components: {VoiceInput},data() {return {message: '',isVoiceMode: false,textFocus: false};},methods: {toggleInputMode() {this.isVoiceMode = !this.isVoiceMode;if (!this.isVoiceMode) {this.$nextTick(() => {this.textFocus = true;});}},onVoiceResult(result) {this.message = result;this.isVoiceMode = false;},sendMessage() {if (!this.message.trim()) return;this.$emit('send', this.message);this.message = '';},onFocus() {this.textFocus = true;},onBlur() {this.textFocus = false;},showEmojiPicker() {// 显示表情选择器}}
};
</script><style>
.chat-input-container {display: flex;align-items: center;padding: 20rpx;border-top: 1rpx solid #eee;background-color: #fff;
}.chat-tools {display: flex;margin-right: 20rpx;
}.chat-tools image {width: 60rpx;height: 60rpx;margin-right: 20rpx;
}.text-input {flex: 1;background-color: #f5f5f5;border-radius: 10rpx;padding: 10rpx 20rpx;
}.text-input textarea {width: 100%;min-height: 60rpx;max-height: 240rpx;
}.voice-input {flex: 1;display: flex;justify-content: center;
}.send-btn {width: 140rpx;height: 80rpx;line-height: 80rpx;font-size: 28rpx;margin-left: 20rpx;padding: 0;background-color: #1890ff;color: #fff;
}.send-btn[disabled] {background-color: #ccc;
}
</style>
性能优化和注意事项
在实际开发中,我遇到了一些需要特别注意的问题:
1. 权限处理
语音识别需要麦克风权限,不同平台的权限处理方式不同:
// 统一请求录音权限
requestAudioPermission() {return new Promise((resolve, reject) => {// #ifdef APP-PLUSconst permissions = ['android.permission.RECORD_AUDIO'];plus.android.requestPermissions(permissions,function(e) {if (e.granted.length === permissions.length) {resolve();} else {reject(new Error('未授予录音权限'));}},function(e) {reject(e);});// #endif// #ifdef MP-WEIXIN || MP-BAIDUuni.authorize({scope: 'scope.record',success: () => resolve(),fail: (err) => reject(err)});// #endif// #ifdef H5if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {navigator.mediaDevices.getUserMedia({ audio: true }).then(() => resolve()).catch(err => reject(err));} else {reject(new Error('浏览器不支持录音功能'));}// #endif});
}
2. 流量控制
语音识别需要上传音频数据,在移动网络下会消耗流量:
// 检查网络环境并提示用户
checkNetwork() {uni.getNetworkType({success: (res) => {if (res.networkType === '2g' || res.networkType === '3g') {uni.showModal({title: '流量提醒',content: '当前处于移动网络环境,语音识别可能消耗较多流量,是否继续?',success: (confirm) => {if (confirm.confirm) {this.startSpeechRecognition();}}});} else {this.startSpeechRecognition();}}});
}
3. 性能优化
长时间语音识别会增加内存和电量消耗,需要做好优化:
// 设置最大录音时长和自动结束
setupMaxDuration() {if (this.timer) {clearTimeout(this.timer);}this.timer = setTimeout(() => {if (this.isRecording) {uni.showToast({title: '录音时间过长,已自动结束',icon: 'none'});this.stopRecord();}}, this.maxDuration * 1000);
}// 空闲自动停止
setupVAD() {// 监测静音,如果用户停止说话3秒,自动结束录音let lastAudioLevel = 0;let silenceCounter = 0;this.vadTimer = setInterval(() => {// 获取当前音量const currentLevel = this.getAudioLevel();if (Math.abs(currentLevel - lastAudioLevel) < 0.05) {silenceCounter++;if (silenceCounter > 30) { // 3秒 (30 * 100ms)this.stopRecord();}} else {silenceCounter = 0;}lastAudioLevel = currentLevel;}, 100);
}
增强功能:语音合成(TTS)
除了语音识别外,语音合成(Text-to-Speech)也是很有用的功能,可以将文本转换为语音:
// 语音合成
textToSpeech(text, options = {}) {const { lang = 'zh', speed = 5, volume = 5 } = options;// #ifdef APP-PLUSconst speechPlugin = uni.requireNativePlugin('speech-baidu');return new Promise((resolve, reject) => {speechPlugin.textToSpeech({text,language: lang === 'zh' ? 'zh-cn' : 'en-us',speed,volume}, (res) => {if (res.errorCode === 0) {resolve(res);} else {reject(new Error(`语音合成失败: ${res.errorCode}`));}});});// #endif// #ifdef H5return new Promise((resolve, reject) => {if ('speechSynthesis' in window) {const speech = new SpeechSynthesisUtterance();speech.text = text;speech.lang = lang === 'zh' ? 'zh-CN' : 'en-US';speech.rate = speed / 10;speech.volume = volume / 10;speech.onend = () => {resolve();};speech.onerror = (err) => {reject(err);};window.speechSynthesis.speak(speech);} else {reject(new Error('当前浏览器不支持语音合成'));}});// #endif
}
踩坑记录与解决方案
开发过程中,我遇到了一些常见问题与解决方法,分享如下:
- 百度语音插件初始化失败:检查API密钥配置和网络环境,特别是HTTPS限制
- H5录音无法使用:多数浏览器要求必须在HTTPS环境下才能使用麦克风
- 识别结果不准确:尝试调整录音参数,如采样率、声道数等,或者使用更专业的噪声抑制算法
- 微信小程序调用失败:检查access_token是否有效,注意token有效期
- 不同设备体验差异大:针对低端设备优化,如减少动画效果、降低采样率等
我们的解决方案是进行兼容性检测,并根据设备性能自动调整参数:
// 检测设备性能并调整参数
detectDevicePerformance() {const platform = uni.getSystemInfoSync().platform;const brand = uni.getSystemInfoSync().brand;const model = uni.getSystemInfoSync().model;// 低端安卓设备优化if (platform === 'android') {// 特定型号的优化if (brand === 'samsung' && model.includes('SM-J')) {return {sampleRate: 8000,quality: 'low',useVAD: false // 禁用语音活动检测,降低CPU占用};}}// 默认配置return {sampleRate: 16000,quality: 'high',useVAD: true};
}
总结与展望
通过本文,我们探讨了在UniApp中实现语音输入与识别功能的多种方案,并提供了具体的代码实现。这些实现方案已在实际项目中得到验证,能够满足大多数应用场景的需求。
语音技术在移动应用中的重要性不断提升,未来可以探索更多高级功能:
- 离线语音识别:降低网络依赖,提高响应速度
- 多语言支持:增加更多语言的识别能力
- 声纹识别:通过语音实现用户身份验证
- 情感分析:从语音中识别用户情绪
希望本文对你在UniApp中实现语音功能有所帮助!如有问题欢迎在评论区交流讨论。
参考资料
- UniApp官方文档
- 百度语音识别API文档
- Web Speech API
相关文章:
鸿蒙OSUniApp 实现的语音输入与语音识别功能#三方框架 #Uniapp
UniApp 实现的语音输入与语音识别功能 最近在开发跨平台应用时,客户要求添加语音输入功能以提升用户体验。经过一番调研和实践,我成功在UniApp项目中实现了语音输入与识别功能,现将过程和方法分享出来,希望对有类似需求的开发者有…...
python:一个代理流量监控的媒体文件下载脚本
前言 一个mitmproxy代理服务应用,作用是监听系统流量,并自动下载可能的video媒体文件到本地。 如果你没有安装mitmproxy或没有做完准备工作,请参考我的这篇文章: python:mitmproxy代理服务搭建-CSDN博客 文件架构目录…...
openfeign与dubbo调用下载excel实践
一、前言 openfeign和dubbo均是rpc框架 RPC(Remote Procedure Call,远程过程调用)框架 是一种允许程序像调用本地方法一样调用远程服务器上函数的技术。它隐藏了底层网络通信的复杂性,让开发者可以专注于业务逻辑,实现…...
Android多媒体——媒体start流程分析(十三)
当多媒体的数据源准备好,并且完成调用准备结束流程后,接下来就开始是调用 start() 方法开始播放媒体了。这里我们就来分析一下媒体开始播放的整个流程。 一、媒体播放流程 对于媒体播放流程的 Java 层和 JNI 层与前面的示例基本相同,这里不再重复展示了,我们直接从 mediap…...
数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)
数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握) 前言一、创建表(了解一下就好,后面会详细讲)二、数据查询的概念2.1 什么是数据查询?2.2 数据查询的…...
【IPMV】图像处理与机器视觉:Lec11 Keypoint Features and Corners
【IPMV】图像处理与机器视觉:Lec11 Keypoint Features and Corners 本系列为2025年同济大学自动化专业**图像处理与机器视觉**课程笔记 Lecturer: Rui Fan、Yanchao Dong Lec0 Course Description Lec3 Perspective Transformation Lec7 Image Filtering Lec8 I…...
C++23 中的 ranges::starts_with 与 ranges::ends_with
文章目录 功能介绍ranges::starts_withranges::ends_with 示例代码编译器支持总结 C23 标准引入了 ranges::starts_with 和 ranges::ends_with,这两个算法由提案 P1659R3 提出,旨在为任意范围提供检查前缀和后缀的功能。 功能介绍 ranges::starts_wit…...
2025 uniapp的请求封装工具类以及使用【拿来就用】
一、创建一个http请求封装的js文件,名字自定义:my_http.js /*** 基础API请求地址(常量,全大写命名规范)* type {string}* constant*/ let BASE_URL //通过环境来判断基础路径 if (process.env.NODE_ENV development…...
Axure设计之内联框架切换页面、子页面间跳转问题
在Axure中,你可以通过以下步骤实现主页面中的内联框架在点击按钮时切换页面内容,从A页面切换到B页面。(误区:子页面之间切换不要设置“框架中打开链接”然后选“父级框架”这个交互) 主框架页面(左侧导航展…...
PyTorch 中神经网络相关要点(损失函数,学习率)及优化方法总结
笔记 1 神经网络搭建和参数计算 1.1 构建神经网络模型 import torch import torch.nn as nn # 线性模型和初始化方法 # todo:1-创建类继承 nn.module类 class ModelDemo(nn.Module):# todo:2-定义__init__构造方法, 构建神经网络def __init__(self):# todo:2-1 调用父…...
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
一、软件介绍 文末提供程序和源码下载 该项目利用 Ultralytics 最先进的 YOLO11 模型将您的 iOS 设备转变为用于对象检测的强大实时推理工具。直接从 App Store 下载该应用程序,或浏览我们的指南,将 YOLO 功能集成到您自己的 Swift 应用程序中。 二、…...
why FPGA喜欢FMC子卡?
FMC 即 FPGA Mezzanine Card ( FPGA中间层板卡),由子板模块、载卡两构成。 FMC 载卡:为子板模块提供插槽,使用母座FMC连接器。载卡连接器引脚与具有可配置IO资源的芯片例如FPGA引脚通过PCB设计连接在一起。。 盘古100…...
【优选算法 | 字符串】字符串模拟题精选:思维+实现解析
算法相关知识点可以通过点击以下链接进行学习一起加油!双指针滑动窗口二分查找前缀和位运算模拟链表哈希表 在众多字符串算法题中,有一类题目看起来没有太多算法技巧,却经常让人“翻车”——那就是字符串模拟题。这类题型往往不依赖复杂的数据…...
比亚迪固态电池突破:王传福的技术哲学与产业重构|创客匠人热点评述
合肥某车间凌晨两点依然灯火通明,工程师正在调试的银白色设备,即将颠覆整个电动车行业 —— 比亚迪全固态电池产线的曝光,标志着中国新能源汽车产业正式迈入 “技术定义市场” 的新纪元。 一、技术突破的底层逻辑 比亚迪全固态电池的核心竞…...
UUG杭州站 | 团结引擎1.5.0 OpenHarmony新Feature介绍
PPT下载地址:https://u3d.sharepoint.cn/:b:/s/UnityChinaResources/EaZmiWfAAdFFmuyd6c-7_3ABhvZoaM69g4Uo2RrSzT3tZQ?e2h7RaL 在2025年4月12日的Unity User Group杭州站中,Unity中国OpenHarmony技术负责人刘伟贤带来演讲《团结引擎1.5.0 OpenHarmony新…...
OpenHarmony轻量系统--BearPi-Nano开发板网络程序测试
本文介绍RISC-V架构海思Hi3861开发板,通过Linux开发环境运行OpenHarmony轻量化系统,下载测试网络例程的过程与步骤。 OpenHarmony操作系统分类 轻量系统(mini system) 面向MCU类处理器例如Arm Cortex-M、RISC-V 32位的设备&#x…...
k8s 中使用 Service 访问时NetworkPolicy不生效问题排查
背景 针对一个服务如下NetworkPolicy, 表示只有n9e命名空间的POD才能访问 k8s-man 服务 kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata:name: k8s-mannamespace: n9elabels:app: k8s-manversion: v1 spec:podSelector:matchLabels:app: k8s-manversion: v1…...
2025 AI如何重构网络安全产品
威胁检测与防御 利用机器学习算法提升威胁检测能力 :AI能够分析大量的网络数据和行为模式,通过机器学习算法自动识别出潜在的威胁和异常行为。例如,Darktrace的Cyber AI Analyst基于真实SOC数据训练,可推进威胁调查,提…...
ARM杂谈——临界段保护恢复的中断状态可靠吗
0 前言 在MCU中,临界段保护是指在多任务或多线程环境中,确保某段代码在执行时不会被其他任务或中断打断,从而避免数据竞争或不一致的问题。临界段保护通常用于共享资源的访问,如全局变量、硬件寄存器等。 我们有一些常用的临界段…...
数据库MySQL学习——day10()
文章目录 1. 什么是子查询(Subquery)?2. 创建样例表:商品表 products3. 插入示例数据4. 子查询的三种常用位置4.1 子查询在 WHERE 子句中(最常见)4.2 子查询在 FROM 子句中(可以当成临时表&…...
YashanDB V23.4 LTS 正式发布|两地三中心、库级闪回重磅特性上线,生产级可用性再升级
近日,YashanDB V23.4 LTS(Long-Term Support Release)版本正式发布,新版本深度契合关键行业数字化转型对数据库“业务永续、风险可控”的核心诉求,打造两地三中心秒级容灾、库级闪回秒级恢复、MySQL全面兼容等重磅特性…...
AI规则引擎:解锁SQL数据分析新姿势
一、AI 规则引擎与 SQL 的奇妙邂逅 在当今数字化时代,数据如同石油,是企业发展和创新的核心驱动力。而如何从海量的数据中提取有价值的信息,成为了企业面临的关键挑战。人工智能规则引擎和 SQL,作为数据分析领域的两大重要工具&a…...
Kotlin Multiplatform与Flutter、Compose共存:构建高效跨平台应用的完整指南
简介 在移动开发领域,跨平台技术正在重塑开发范式。Kotlin Multiplatform (KMP) 作为 JetBrains 推出的多平台开发框架,结合了 Kotlin 的简洁性与原生性能优势,使开发者能够高效共享业务逻辑。而 Flutter 凭借其高性能渲染引擎(Skia)和丰富的组件库,成为混合开发的首选方…...
FunASR:语音识别与合成一体化,企业级开发实战详解
简介 FunASR是由阿里巴巴达摩院开源的高性能语音识别工具包,它不仅提供语音识别(ASR)功能,还集成了语音端点检测(VAD)、标点恢复、说话人分离等工业级模块,形成了完整的语音处理解决方案。 FunASR支持离线和实时两种模式,能够高效处理多语言音频,并提供高精度的识别结果。…...
【Spark分析HBase数据】Spark读取并分析HBase数据
Spark读取并分析HBase数据 一、摘要二、实现过程三、小结 一、摘要 Apache Spark 是一个快速、通用的大数据处理引擎,提供了丰富的 API 用于数据处理和分析。HBase 是一个分布式、可扩展的 NoSQL 数据库,适合存储海量结构化和半结构化数据。Spark 与 HB…...
探索直播美颜SDK的核心算法:图像增强与AI美颜技术详解
一款优秀的直播美颜SDK不仅能让主播拥有完美的在线形象,还能帮助平台吸引更多用户。然而,这背后的关键在于其核心算法——从基本的图像增强到前沿的AI美颜技术,每一步都至关重要。今天,我们就来深入探讨这些技术背后的秘密。 一、…...
全新linux网络配置工具nmcli:
1.Linux全新网络管理工具nmcli的使用 ,网络管理命令行工具nmcli 在nmcli中有2个命令最为常用: (1)nmcli connection 表示连接,可理解为配置文件,相当于ifcfg-ethX。可以简写为nmcli c (2)nmcl…...
LeetCode100.5 盛最多水的容器
对于这题,首先明确的是:盛水的体积取决于两垂线间的距离与两垂线中最短的长度。 那么使用双指针,在每次移动时,只移动其中最短的那个,因为若移动最长的那个,体积不会变大。 class Solution { public:int …...
AI开发者的算力革命:GpuGeek平台全景实战指南(大模型训练/推理/微调全解析)
目录 背景一、AI工业化时代的算力困局与破局之道1.1 中小企业AI落地的三大障碍1.2 GpuGeek的破局创新1.3 核心价值 二、GpuGeek技术全景剖析2.1 核心架构设计 三、核心优势详解3.1 优势1:工业级显卡舰队3.2 优势2:开箱即用生态3.2.1 预置镜像库…...
Java元注解
Java 元注解(Meta-Annotations) 元注解是指用于注解其他注解的注解,Java 提供了5个内置的元注解: 1. Target 指定注解可以应用的目标元素类型。 Target(ElementType.TYPE) // 只能用于类、接口或枚举 public interface MyAnno…...
FPGA:Xilinx Kintex 7实现DDR3 SDRAM读写
在Xilinx Kintex 7系列FPGA上实现对DDR3 SDRAM的读写,主要依赖Xilinx提供的Memory Interface Generator (MIG) IP核,结合Vivado设计流程。以下是详细步骤和关键点: 1. 准备工作 硬件需求: Kintex-7 FPGA(如XC7K325T&…...
深度剖析 GpuGeek 实例:GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察
深度剖析 GpuGeek 实例:GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察 前言 GpuGeek专注于人工智能与高性能计算领域的云计算平台,致力于为开发者、科研机构及企业提供灵活、高效、低成本的GPU算力资源。平台通过整合全球分布式数据中心资源&#…...
散列表(1)
散列表概念 键通过散列函数后转换为数组的下标,在对应的下标位置上存储相应的信息 键------>散列函数-------->数组下标------->存储信息 散列函数 散列函数就是一个函数,能够将给定的key转换为特定散列值。hashValuehash(key&…...
E. 23 Kingdom【Codeforces Round 1024 (Div. 2)】
E. 23 Kingdom 思路: 这道题的核心在于如何构造一个数组b,使得每个数的最远两个出现位置之差总和最大。通过分析,我们发现要最大化总美丽值,应尽可能让每个数的首次出现尽可能靠左、末次出现尽可能靠右。这样每个数的距离贡献j-i…...
TTS-Web-Vue系列:Vue3实现侧边栏与顶部导航的双向联动
🔄 本文是TTS-Web-Vue系列的最新文章,重点介绍如何在Vue3项目中实现侧边栏与顶部导航栏的双向联动功能。通过Vue3的响应式系统和组件通信机制,我们构建了一套高效、流畅的导航联动方案,让用户在不同入口都能获得一致的导航体验。 …...
【C++】模板(初阶)
一、模板与泛型编程 我们先来思考一下:如何实现一个通用的交换函数? void Swap(int& left, int& right) {int temp left;left right;right temp; }void Swap(double& left, double& right) {double temp left;left right;right te…...
大模型微调实战:基于GpuGeek平台的低成本高效训练方案
文章目录 引言一、GpuGeek平台使用入门1. 注册与账号设置2. 控制台功能概览3. 快速创建GPU实例3. 预置镜像与自定义环境 二、GpuGeek平台核心优势解析1. 显卡资源充足:多卡并行加速训练2. 镜像超多:开箱即用的开发环境3. 计费灵活:按需付费降…...
黑马k8s(六)
1.Deployment(Pod控制器) Selector runnginx 标签选择:会找pod打的标签 执行删除之后,pod也会删除,Terminating正在删除 如果想要访问其中的一个pod借助:IP地址端口号访问 假设在某一个瞬间,…...
WEB安全--Java安全--CC1利用链
一、梳理基本逻辑 WEB后端JVM通过readObject()的反序列化方式接收用户输入的数据 用户编写恶意代码并将其序列化为原始数据流 WEB后端JVM接收到序列化后恶意的原始数据并进行反序列化 当调用: ObjectInputStream.readObject() JVM 内部逻辑: → 反…...
16S18S_OTU分析(3)
OTU的定义 OTU:操作分类单元是在系统发生学研究或群体遗传学研究中,为了便于进行分析,人为给某一个分类单元(如品系、种、属、分组等)设置的同一标志。目的:OTU用于将相似的序列归为一类,以便于…...
嵌入式开发学习日志(数据结构--单链表)Day20
一、gdb调试 (一)一般调试步骤与命令 1、gcc -g (调试版本,内含调试信息与源码;eg:gcc -g main.c linklist.c) 2、gdb a.out(调试可执行文件,eg:gdb …...
nginx报错-[emerg] getpwnam(“nginx“) failed in /etc/nginx/nginx.conf:2
报错 - nginx: [emerg] getpwnam(“nginx”) failed in /etc/nginx/nginx.conf:2 问题描述: nginx: [emerg] getpwnam(“nginx”) failed in /etc/nginx/nginx.conf:2 问题原因: 是因为配制文件中使用的启动账户在系统中并没有找到 解决方法&#x…...
Linux系统编程——fork函数的使用方法
在 Linux 系统编程 中,fork() 函数是创建新进程的关键系统调用。fork() 在当前进程(父进程)中创建一个几乎完全相同的子进程。子进程和父进程从调用 fork() 的位置继续执行,但它们是两个独立的进程,每个进程都有自己的…...
Linux进程信号处理(26)
文章目录 前言一、信号的处理时机处理情况“合适”的时机 二、用户态与内核态概念重谈进程地址空间信号的处理过程 三、信号的捕捉内核如何实现信号的捕捉?sigaction 四、信号部分小结五、可重入函数六、volatile七、SIGCHLD 信号总结 前言 这篇就是我们关于信号的最…...
黑马Java跟学.最新AI+若依框架项目开发(一)
黑马Java跟学.最新AI若依框架项目开发.一 前瞻为什么学习若依?AI局限性若依是什么?创新项目开发新方案课程安排前置知识 一、若依搭建若依版本官方非官方 RuoYi-Vue运行后端项目初始化项目Git下载Maven构建 MySQL相关导入sql配置信息 Redis相关启动配置信息 项目运…...
【自学30天掌握AI开发】第1天 - 人工智能与大语言模型基础
自学30天掌握AI开发 - 第1天 📆 日期和主题 日期:第1天 主题:人工智能与大语言模型基础 🎯 学习目标 了解人工智能的发展历史和基本概念掌握大语言模型的基本原理和工作机制区分不同类型的AI模型及其特点理解AI在当前社会中的…...
(十六)Java String类全面解析
一、String类概述 1.1 String的本质 在Java中,String类可能是使用最频繁的类之一,但它也是最容易被误解的类之一。从本质上讲,String代表的是一个不可变的Unicode字符序列。这种不可变性(immutability)是String类设计的核心特性。 java S…...
Android架构之自定义native进程
在Android五层架构中,native层基本上全是c的世界,这些c进程基本上靠android世界的第一个进程init进程创建,init通过rc配置文件,创建了众多的c子进程,也是这众多的c进程,构建了整个android世界的native层。 …...
#跟着若城学鸿蒙# HarmonyOS NEXT学习之AlphabetIndexer组件详解
一、组件介绍 AlphabetIndexer(字母索引条)是HarmonyOS NEXT中一个非常实用的UI组件,它主要用于在列表视图中提供快速的字母导航功能。当应用中有大量按字母顺序排列的数据(如联系人列表、城市列表等)时,A…...
React百日学习计划——Deepseek版
阶段一:基础巩固(1-20天) 目标:掌握HTML/CSS/JavaScript核心语法和开发环境搭建。 每日学习内容: HTML/CSS(1-10天) 标签语义化、盒模型、Flex布局、Grid布局、响应式设计(媒体查询…...