Chainlit集成Dashscope实现语音交互网页对话AI应用

news2024/11/28 10:48:12

前言

本篇文章讲解和实战,如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型,阿里巴巴在github提供的有开源代码,也可以自己本地部署SenseVoice大模型和CosyVoice大模型接口服务。特别提及一下,阿里云上还有另外一套,语音识别和语音合成的接口,Paraformer语音识别和Sambert语音合成,相比之下个人觉得不如SenseVoice大模型和CosyVoice大模型。中间踩了一个坑,浪费我好几天研究,就是阿里云平台上Paraformer语音识别的接口,可以直接传文件路径或者文件流而SenseVoice大模型的接口。所以我一直中意用Paraformer语音识别的接口,但是识别的语音文件,老是识别不出来,一开始我觉得是哪些参数没传对,或者是我麦克风生成语音文件有问题,老是语音识别不出来,后来看了一些文档,支持的音频采样率,只有16khz的,而我音频格式不是。所以就换成SenseVoice大模型的接口,只接受文件的url不支持本地文件直接上传,这个接口需要需要将音频文件先上传到oss等生成一个可以访问文件的url。一开始我觉得会很慢,但是实测起来,速度还行。

Dashscope

DashScope 是阿里云推出的一款模型服务产品,旨在简化人工智能(AI)模型的应用与部署过程。它针对主流的AI大模型进行了标准化封装,提供了API接口,使得开发者能够轻松调用这些模型,并进行推理、训练、微调等操作。DashScope 的主要特点包括:

  1. 丰富的模型选择:DashScope 提供了多种类型的模型,涵盖自然语言处理、计算机视觉等多个领域,满足不同场景下的需求。
  2. 简便的集成方式:通过Python/Java SDK或HTTP请求,开发者可以方便地将AI模型集成到自己的应用程序中。
  3. 开箱即用:无需深入了解模型内部机制,用户可以直接调用API完成复杂的AI任务。
  4. 高效的性能优化:在模型推理优化、高效微调训练等方面积累了大量的技术实力,提升了模型使用的效率和效果。
  5. 灵活的弹性底座:改善了模型推理、微调效率低及规模响应慢的问题,提供了更加灵活的服务支持。
  6. 成本经济:提供了合理的计费模式,包括免费试用额度,帮助开发者降低成本。

此外,DashScope 还支持特定领域的高级功能,如语音合成、图像识别等,适用于广泛的行业和应用场景。通过DashScope,开发者可以获得一个强大的工具集来加速AI项目的开发和部署。

语音识别SenseVoice大模型

阿里巴巴的语音识别大模型 SenseVoice 是其在语音技术领域的一项重要成果,主要特点和能力如下:

  1. 高精度多语言语音识别:SenseVoice 能够提供高精度的语音转文字服务,支持多种语言的识别,适用于跨国界、跨文化的交流场景。

  2. 情感辨识:除了传统的语音识别外,SenseVoice 还能够识别说话者的情感状态,如高兴、悲伤、愤怒等,这对于构建更加人性化的对话系统非常有用。

  3. 音频事件检测:SenseVoice 可以检测音频中的特定事件,例如掌声、笑声、咳嗽等,这种能力在媒体分析、智能监控等领域具有广泛应用前景。

  4. 快速适应不同场景:通过先进的模型训练技术和算法优化,SenseVoice 能够快速适应不同的环境和使用场景,即使是在嘈杂的环境中也能保持较高的识别精度。

  5. 支持语音克隆:SenseVoice 具备语音克隆的能力,可以通过少量样本学习特定人的声音特征,进而生成相似的声音输出,这项技术在个性化语音助手、虚拟主播等领域有着广阔的应用空间。

  6. 开源共享:作为阿里通义实验室的一部分,SenseVoice 已经被开源,这促进了学术界和工业界之间的技术交流和进步,也为更多开发者提供了研究和应用的机会。

  7. 强大的技术支持:依托阿里巴巴深厚的技术积累和丰富的应用场景,SenseVoice 在性能、稳定性等方面得到了充分保障。

综上所述,SenseVoice 是一款集成了多项先进功能和技术的语音识别大模型,旨在通过提供高质量的语音处理服务,推动人机交互体验的进一步提升。

语音合成CosyVoice大模型

CosyVoice 是阿里通义实验室开发的一款先进的多语言语音合成大模型,旨在通过融合大规模预训练语言模型和深度学习技术,提供高质量、自然流畅的语音合成服务。以下是 CosyVoice 的主要特点和优势:

  1. 多语言支持:CosyVoice 支持包括中文、英文、日文、粤语和韩语在内的多种语言的语音合成,满足全球用户的多样化需求。

  2. 自然逼真的语音质量:通过超过15万小时的多语言语音数据训练,CosyVoice 能够生成几乎与真人无异的语音,无论是发音清晰度还是情感表达都达到了很高的水平。

  3. 快速音色克隆:CosyVoice 可以在短短几秒钟内从提供的音频样本中学习并复制特定的音色特性,使用户能够轻松创建个性化的语音内容。

  4. 情感和韵律控制:CosyVoice 允许对合成语音的情感色彩和节奏进行细致调整,从而更好地适应不同的应用场景和内容需求。

  5. 开源开放:CosyVoice 已经对外开源,不仅为开发者提供了使用这一先进技术的机会,同时也促进了学术界和工业界之间的技术交流和发展。

  6. 灵活的部署选项:CosyVoice 提供了从云端服务到本地部署的多种解决方案,用户可以根据自身需求选择最适合的部署方式。

  7. 全面的技术文档和支持:为了帮助用户更好地理解和使用 CosyVoice,官方提供了详细的使用教程和技术文档,以及持续的技术支持。

总之,CosyVoice 是一个功能强大、使用灵活的语音合成工具,它不仅能够为个人用户提供高质量的语音内容创作能力,同时也为企业和开发者提供了实现语音相关应用和服务的重要手段。

快速上手

创建一个文件,例如“chainlit_chat”

mkdir chainlit_chat

进入 chainlit_chat文件夹下,执行命令创建python 虚拟环境空间(需要提前安装好python sdkChainlit 需要python>=3.8。,具体操作,由于文章长度问题就不在叙述,自行百度),命令如下:

python -m venv .venv
  • 这一步是避免python第三方库冲突,省事版可以跳过
  • .venv是创建的虚拟空间文件夹可以自定义

接下来激活你创建虚拟空间,命令如下:

#linux or mac
source .venv/bin/activate
#windows
.venv\Scripts\activate

在项目根目录下创建requirements.txt,内容如下:

chainlit
dashscope

执行以下命令安装依赖:

pip install -r .\requirements.txt
  • 安装后,项目根目录下会多出.chainlit.files文件夹和chainlit.md文件

代码创建

只使用通义千问的DashScope模型服务灵积的接口

在项目根目录下创建.env环境变量,配置如下:

DASHSCOPE_API_KEY="sk-api_key"
  • DASHSCOPE_API_KEY 是阿里dashscope的服务的APIkey,代码中使用DashScope的sdk实现,所以不需要配置base_url。默认就是阿里的base_url。
  • 阿里模型接口地址 https://dashscope.console.aliyun.com/model
  • DashScope模型服务灵积文档地址 https://help.aliyun.com/zh/dashscope/

在项目根目录下创建app.py文件,代码如下:

import re
import tempfile
import time
from http import HTTPStatus
from io import BytesIO

import chainlit as cl
import dashscope.file
import requests
from chainlit.element import ElementBased
from dashscope.audio.tts_v2 import SpeechSynthesizer
from dashscope.common.constants import FilePurpose



async def text_to_speech(text: str):
    synthesizer = SpeechSynthesizer(model='cosyvoice-v1', voice='longxiaochun')
    audio = synthesizer.call(text)
    return "", audio


async def speech_to_text(audio_file):
    result = dashscope.Files.upload(file_path=audio_file,
                                    purpose=FilePurpose.assistants)
    file_id = result.output['uploaded_files'][0]['file_id']
    file_res = dashscope.Files.get(file_id)
    task_response = dashscope.audio.asr.Transcription.async_call(
        model='sensevoice-v1',
        file_urls=[file_res.output['url']],
        language_hints=['zh', 'en'],
    )
    transcribe_response = dashscope.audio.asr.Transcription.wait(task=task_response.output.task_id)
    if transcribe_response.status_code == HTTPStatus.OK:
        transcription_url = transcribe_response.output["results"][0]["transcription_url"]
        # 发送GET请求
        response = requests.get(transcription_url)
        # 检查请求是否成功
        if response.status_code == 200:
            # 使用内置的json()方法将响应体解析为字典
            data = response.json()
            print(data)
            print(data['transcripts'][0]['text'])
            text = data['transcripts'][0]['text']
            # 使用正则表达式提取标签之间的文本
            pattern = r'<\|Speech\|>(.*?)<\|/Speech\|>'
            match = re.search(pattern, text, re.DOTALL)

            if match:
                text = match.group(1).strip()
            else:
                text = ''
            return text
        else:
            print(f"Failed to retrieve data: {response.status_code}")
    return "fail"


@cl.step(type="tool", name="AI问答")
async def generate_text_answer(message: cl.Message):
    start_time = time.time()
    msg = cl.Message(content="")
    await msg.send()
    messages = [
        {'role': 'system', 'content': 'You are a helpful assistant.'},
        {'role': 'user', 'content': message.content}
    ]
    print('content', message.content)
    stream = dashscope.Generation.call(
        model="qwen-plus",
        messages=messages,
        result_format='message',
        stream=True,
        incremental_output=True
    )
    print(f"代码执行时间: {time.time() - start_time} 秒")
    for part in stream:
        if token := part.output.choices[0].message.content or "":
            await msg.stream_token(token)
    return msg


@cl.on_message
async def on_message(message: cl.Message):
    msg = await generate_text_answer(message)
    await msg.update()


@cl.on_audio_chunk
async def on_audio_chunk(chunk: cl.AudioChunk):
    if chunk.isStart:
        buffer = BytesIO()
        buffer.name = f"input_audio.{chunk.mimeType.split('/')[1]}"
        # Initialize the session for a new audio stream
        cl.user_session.set("audio_buffer", buffer)
        cl.user_session.set("audio_mime_type", chunk.mimeType)

    # For now, write the chunks to a buffer and transcribe the whole audio at the end
    cl.user_session.get("audio_buffer").write(chunk.data)


@cl.on_audio_end
async def on_audio_end(elements: list[ElementBased]):
    # Get the audio buffer from the session
    audio_buffer: BytesIO = cl.user_session.get("audio_buffer")
    audio_mime_type: str = cl.user_session.get("audio_mime_type")
    audio_buffer.seek(0)  # 将文件指针移到开头
    # 使用pydub处理音频
    try:
        with tempfile.NamedTemporaryFile(delete=False, suffix=".webm") as tmpFile:
            tmpFile.write(audio_buffer.read())
            tmpFile_path = tmpFile.name
    except Exception as e:
        print(f"Error processing audio: {e}")

    print('tmpFile_path', tmpFile_path)
    transcription = await speech_to_text(tmpFile_path)
    input_audio_el = cl.Audio(
        mime=audio_mime_type, path=tmpFile_path, name="",
    )
    message = await cl.Message(
        author="You",
        type="user_message",
        content=transcription,
        elements=[input_audio_el, *elements]
    ).send()
    print('transcription', transcription)
    msg = await generate_text_answer(message)
    output_name, output_audio = await text_to_speech(msg.content)
    output_audio_el = cl.Audio(name=output_name, auto_play=True, mime='audio/wav', content=output_audio)
    msg.elements = [output_audio_el]
    await msg.update()

  • 这里我使用的国内阿里云的DashScope sdk 服务。
  • 如果要保存用户聊天记录,这里生成语音文件,如果要保存起来,本地或者oss等。
  • 代码实现的是,语音问答的时候会回复文字和语音,语音设置的默认播放,文字问答的时候,只回复文字。
  • 代码还有一些不完善的地方,比如异常的处理还不完善,部署生产的时候记得完善

代码解读

这段代码是一个基于 chainlit 框架的聊天机器人应用,它结合了阿里云的多个服务,包括语音合成(TTS)、语音识别(ASR)和文本生成(Text Generation),实现了从语音输入到文本处理再到语音输出的完整流程。下面是各个部分的功能解读:

1. 引入必要的模块

import re
import tempfile
import time
from http import HTTPStatus
from io import BytesIO

import chainlit as cl
import dashscope.file
import requests
from chainlit.element import ElementBased
from dashscope.audio.tts_v2 import SpeechSynthesizer
from dashscope.common.constants import FilePurpose
  • 导入了用于处理字符串、文件操作、时间测量、HTTP状态码、字节流处理、网络请求、链式元素以及阿里云 DashScope 相关模块。

2. 定义 text_to_speech 函数

async def text_to_speech(text: str):
    synthesizer = SpeechSynthesizer(model='cosyvoice-v1', voice='longxiaochun')
    audio = synthesizer.call(text)
    return "", audio
  • 使用 SpeechSynthesizer 对象调用语音合成功能,将文本转换为语音。这里使用的是 CosyVoice 模型和特定的声音(longxiaochun)。

3. 定义 speech_to_text 函数

async def speech_to_text(audio_file):
    # 上传音频文件至阿里云
    result = dashscope.Files.upload(file_path=audio_file, purpose=FilePurpose.assistants)
    file_id = result.output['uploaded_files'][0]['file_id']
    file_res = dashscope.Files.get(file_id)
    # 调用语音转文字服务
    task_response = dashscope.audio.asr.Transcription.async_call(
        model='sensevoice-v1',
        file_urls=[file_res.output['url']],
        language_hints=['zh', 'en'],
    )
    transcribe_response = dashscope.audio.asr.Transcription.wait(task=task_response.output.task_id)
    if transcribe_response.status_code == HTTPStatus.OK:
        transcription_url = transcribe_response.output["results"][0]["transcription_url"]
        response = requests.get(transcription_url)
        if response.status_code == 200:
            data = response.json()
            text = data['transcripts'][0]['text']
            # 使用正则表达式提取标签之间的文本
            pattern = r'<\|Speech\|>(.*?)<\|/Speech\|>'
            match = re.search(pattern, text, re.DOTALL)
            if match:
                text = match.group(1).strip()
            else:
                text = ''
            return text
        else:
            print(f"Failed to retrieve data: {response.status_code}")
    return "fail"
  • 此函数负责将音频文件上传到阿里云,并调用语音识别服务将音频转换为文本。如果识别成功,则返回识别后的文本;否则返回 "fail"

4. 定义 generate_text_answer 函数

@cl.step(type="tool", name="AI问答")
async def generate_text_answer(message: cl.Message):
    start_time = time.time()
    msg = cl.Message(content="")
    await msg.send()
    messages = [
        {'role': 'system', 'content': 'You are a helpful assistant.'},
        {'role': 'user', 'content': message.content}
    ]
    stream = dashscope.Generation.call(
        model="qwen-plus",
        messages=messages,
        result_format='message',
        stream=True,
        incremental_output=True
    )
    for part in stream:
        if token := part.output.choices[0].message.content or "":
            await msg.stream_token(token)
    return msg
  • 使用阿里云的文本生成模型 qwen-plus 根据用户的输入生成回复。此函数会将生成的每个片段逐步发送给用户,以实现流式响应。

5. 定义消息处理函数

@cl.on_message
async def on_message(message: cl.Message):
    msg = await generate_text_answer(message)
    await msg.update()
  • 当接收到用户的消息时,调用 generate_text_answer 函数生成回复,并更新消息对象。

6. 处理音频数据

@cl.on_audio_chunk
async def on_audio_chunk(chunk: cl.AudioChunk):
    if chunk.isStart:
        buffer = BytesIO()
        buffer.name = f"input_audio.{chunk.mimeType.split('/')[1]}"
        cl.user_session.set("audio_buffer", buffer)
        cl.user_session.set("audio_mime_type", chunk.mimeType)

    cl.user_session.get("audio_buffer").write(chunk.data)
  • 当接收到音频数据块时,将其写入内存中的缓冲区。如果是音频流的开始,则初始化缓冲区。

7. 结束音频处理

@cl.on_audio_end
async def on_audio_end(elements: list[ElementBased]):
    audio_buffer: BytesIO = cl.user_session.get("audio_buffer")
    audio_mime_type: str = cl.user_session.get("audio_mime_type")
    audio_buffer.seek(0)
    with tempfile.NamedTemporaryFile(delete=False, suffix=".webm") as tmpFile:
        tmpFile.write(audio_buffer.read())
        tmpFile_path = tmpFile.name
    transcription = await speech_to_text(tmpFile_path)
    input_audio_el = cl.Audio(mime=audio_mime_type, path=tmpFile_path, name="")
    message = await cl.Message(
        author="You",
        type="user_message",
        content=transcription,
        elements=[input_audio_el, *elements]
    ).send()
    msg = await generate_text_answer(message)
    output_name, output_audio = await text_to_speech(msg.content)
    output_audio_el = cl.Audio(name=output_name, auto_play=True, mime='audio/wav', content=output_audio)
    msg.elements = [output_audio_el]
    await msg.update()
  • 当音频流结束时,将所有收集到的音频数据保存到临时文件中,并调用 speech_to_text 函数进行语音识别。然后根据识别结果生成回复,并将回复转换为语音发送给用户。

总结

这个应用实现了从接收用户语音输入,到自动转录为文本,再到根据文本生成回复,最后将回复转换为语音输出的全过程。通过阿里云的多个服务,它能够提供流畅的交互体验。

运行应用程序

要启动 Chainlit 应用程序,请打开终端并导航到包含的目录app.py。然后运行以下命令:

 chainlit run app.py -w   
  • -w标志告知 Chainlit 启用自动重新加载,因此您无需在每次更改应用程序时重新启动服务器。您的聊天机器人 UI 现在应该可以通过http://localhost:8000访问。
  • 自定义端口可以追加--port 80

启动后界面如下:

在这里插入图片描述

相关文章推荐

《Chainlit快速实现AI对话应用的界面定制化教程》
《Chainlit接入FastGpt接口快速实现自定义用户聊天界面》
《使用 Xinference 部署本地模型》
《Fastgpt接入Whisper本地模型实现语音输入》
《Fastgpt部署和接入使用重排模型bge-reranker》
《Fastgpt部署接入 M3E和chatglm2-m3e文本向量模型》
《Fastgpt 无法启动或启动后无法正常使用的讨论(启动失败、用户未注册等问题这里)》
《vllm推理服务兼容openai服务API》
《vLLM模型推理引擎参数大全》
《解决vllm推理框架内在开启多显卡时报错问题》
《Ollama 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201216.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频流媒体融合与视频监控汇聚管理系统集成方案

流媒体视频融合与汇聚管理系统可以实现对各类模块化服务进行统一管理和配置等操作&#xff0c;可实现对应用服务的整合、管理及共享&#xff0c;以标准接口的方式&#xff0c;业务平台及其他第三方业务平台可以方便地调用各类数据&#xff0c;具有开放性和可扩展性。在流媒体视…

opencascade鼠标拖拽框选功能

1.首先在OccView中添加用于显示矩形框的类 //! rubber rectangle for the mouse selection.Handle(AIS_RubberBand) mRectBand; 2.设置框选的属性 mRectBand new AIS_RubberBand(); //设置属性 mRectBand->SetLineType(Aspect_TOL_SOLID); //设置变宽线型为实线 mRe…

scanMiR:使用R语言预测 miRNA 结合位点

生信碱移 scanMiR 结合预测 scanMiR&#xff0c;一款R语言工具包&#xff0c;能够高效地扫描任何自定义序列上的典型和非典型miRNA结合位点&#xff0c;估计解离常数并预测聚合的转录物抑制。 最近&#xff0c;几项高通量研究试图阐明miRNA–mRNA靶向的生化决定因素。在一项发…

Unity 克隆Timeline并保留引用

Timeline的资源是.playable文件&#xff0c;简单的复制不会保留引用关系。 下面的脚本可以复制引用关系。 using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; u…

Node.js入门——fs、path模块、URL端口号、模块化导入导出、包、npm软件包管理器

Node.js入门 1.介绍 定义&#xff1a;跨平台的JS运行环境&#xff0c;使开发者可以搭建服务器端的JS应用程序作用&#xff1a;使用Node.Js编写服务器端代码Node.js是基于Chrome V8引擎进行封装&#xff0c;Node中没有BOM和DOM 2.fs模块-读写文件 定义&#xff1a;封装了与…

(03)python-opencv图像处理——图像的几何变换

前言 1、变换 2、缩放 3、平移变换 4、旋转 5、仿射变换 6、翻转 参考文献 前言 在本教程中&#xff1a; 你将会学到将不同的几何变换应用于图像&#xff0c;如平移、旋转、仿射变换等。你会学到如下函数&#xff1a;cv.getPerspectiveTransform 图像的几何变换是图像…

Ping32引领数据防泄漏新潮流:智能、高效、安全

在当今数字化迅猛发展的时代&#xff0c;企业面临着日益严峻的数据安全挑战。数据泄漏事件频发&#xff0c;不仅损害企业声誉&#xff0c;还可能导致巨额的经济损失。为此&#xff0c;Ping32以其创新的数据防泄漏解决方案&#xff0c;正在引领行业新潮流。其技术特点可概括为“…

017 平台属性[属性分组、规格参数、销售属性]

文章目录 获取指定分类的属性列表AttrController.javaAttrServiceImpl.java 获取属性分组所关联的所有属性AttrGroupControllerAttrServiceImpl.java 移除AttrGroupController.javaAttrServiceImpl.javaAttrAttrgroupRelationDao.javaAttrAttrgroupRelationDao.xml 获取属性分组…

动态规划算法专题(六):回文串问题

目录 1、回文子串&#xff08;"引子题"&#xff09; 1.1 算法原理 1.2 算法代码 2、最长回文子串 2.1 算法原理 2.2 算法代码 3、分割回文串 IV&#xff08;hard&#xff09; 3.1 算法原理 3.2 算法代码 4、分割字符串 II&#xff08;hard&#xff09; 4…

甲虫身体图像分割系统源码&数据集分享

甲虫身体图像分割系统源码&#xff06;数据集分享 [yolov8-seg-EfficientRepBiPAN&#xff06;yolov8-seg-C2f-FocusedLinearAttention等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challen…

C语言之扫雷小游戏(完整代码版)

说起扫雷游戏&#xff0c;这应该是很多人童年的回忆吧&#xff0c;中小学电脑课最常玩的必有扫雷游戏&#xff0c;那么大家知道它是如何开发出来的吗&#xff0c;扫雷游戏背后的原理是什么呢&#xff1f;今天就让我们一探究竟&#xff01; 扫雷游戏介绍 如下图&#xff0c;简…

从0开始linux(12)——命令行参数与环境变量

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 命令行参数环境变量 我们先打断一下关于进程的话题&#xff0c;博主先来介绍两个东西&#xff0c;分别是命令行参数与环境变量。那么有人看到这就会问了&#xff0c;难道说命令行参数和环境变…

Spring系列 循环依赖

文章目录 注入方式循环依赖的场景单例创建流程getSingletoncreateBeandoCreateBeancreateBeanInstance 循环依赖分析为什么都使用构造函数无法解决&#xff1f;为什么使用Autowired可以解决&#xff1f;为什么要添加到 earlySingletonObjects 缓存中&#xff1f;allowCircularR…

基于Kafka2.1解读Producer原理

文章目录 前言一、Kafka Producer是什么&#xff1f;二、主要组件1.Kafka Producer1.1 partitioner1.2 keySerializer1.3 valueSerializer1.4 accumulator1.5 sender 2.Sender2.1 acks2.2 clientinFlightBatches 3. Selector3.1 nioSelector3.2 channels 4. 全局总览 总结 前言…

【hot100-java】N 皇后

回溯篇 视频题解 真的裂开了&#xff0c;多看视频题解。 class Solution {public List<List<String>> solveNQueens(int n) {List<List<String>>retnew ArrayList<>();int []colnew int[n];boolean[] onPathnew boolean[n];boolean[] diag1ne…

(Linux和数据库)1.Linux操作系统和常用命令

了解Linux操作系统介绍 除了办公和玩游戏之外不用Linux&#xff0c;其他地方都要使用Linux&#xff08;it相关&#xff09; iOS的本质是unix&#xff08;unix是付费版本的操作系统&#xff09; unix和Linux之间很相似 Linux文件系统和目录 bin目录--放工具使用的 操作Linux远程…

双光吊舱图像采集详解!

一、图像采集 可见光图像采集&#xff1a; 使用高性能的可见光相机&#xff0c;通过镜头捕捉自然光或人工光源照射下的目标图像。 相机内部通常配备有先进的图像传感器&#xff0c;如CMOS或CCD&#xff0c;用于将光信号转换为电信号。 红外图像采集&#xff1a; 利用红外热…

【hot100-java】二叉树的最近公共祖先

二叉树篇 我觉得是比两个节点的深度&#xff0c;取min&#xff08;一种情况&#xff09; DFS解题。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ clas…

Unity/VS 消除不想要的黄色警告

方法一&#xff1a;单个消除 在要关闭的代码前一行写上#pragma warning disable 警告代码编码 在要关闭代码行下面一行写上#pragma warning restore 警告代码编码 精准的关闭指定地方引起的代码警告&#xff0c;不会过滤掉无辜的代码 #pragma warning disable 0162,1634HandleL…

JDBC: 连接池

文章目录 没有连接池的现状连接池解决现状问题的原理连接池好处常用连接池的介绍Druid连接池DRUID简介Druid常用的配置参数Druid连接池基本使用API介绍 案例代码 没有连接池的现状 通过下图来分析一下我们目前jdbc程序的结构。 以前使用的jdbc的缺点&#xff1a; 1、操作数据库…