亚马逊云AI大语言模型应用下的创新Amazon Transcribe的使用

news2025/1/24 14:28:05

Transcribe简介

语音识别技术,也被称为自动语音识别(Automatic Speech Recognition,简称ASR),其目标是将人类的语音中的词汇内容转换为计算机可读的输入,例如按键、二进制编码或者字符序列。语音识别技术已经发展了几十年,直到2009年,Hinton把人工智能深度学习解决方案引入语音识别中,语音识别才取得了巨大突破。

Amazon Transcribe 是一项自动语音识别 (ASR) 服务,使开发人员能够轻松地为其应用程序添加语音转文本功能。自从在 re:Invent 2017 发布以来,越来越多的用户将语音识别功能添加到其应用程序和设备中。2019年8月,Amazon Transcribe推出对中文普通话的支持。更加另用户兴奋的是,在中国的北京区域(BJS)和宁夏区域(ZHY)也已支持该项服务。

在日常工作学习中,我们往往需要对一个视频文件增加字幕。传统的方法需要将视频中的对话用文字记录下来,通常采用记事本等工具保存文字记录,然后借助一些工具软件为文字加上时间轴,然后进行人工校对,整个过程需要耗费大量的时间和精力。是否有更快捷的方法呢?下面我们分享一个使用Amazon Transcribe为视频自动增加字幕的示例。

AWS Transcribe 服务于利用机器学习来识别语音文件中的声音,然后将其转化为文本。目前支持英语和西班牙文语音。必须将语音文件保存在S3中,输出结果也会被保存在S3中。

  • 输入声音文件,支持 flac、mp3、mp4 和 wav 文件格式。长度不能超过2小时。

  • 指定语言。

几个特色功能:

  • 发音者识别(speaker identification):Transcribe 能区别一个语音文件中的多个说话者。支持2到10个发音者

  • 支持多声道(channel identification): 如果声音文件中有多声道

  • 支持字典(vocabulary):比如不能识别的单词,特定领域不常用的单词

体系架构

  1. 监测到S3存储桶中的文件变化,触发lambda函数;

  2. lambda函数调用Transcribe服务,生成视频对应的文本(json格式);

  3. 对文本进行格式转换,生成字幕文件格式(srt);

  4. 上传字幕文件到存储桶。

控制台操作展示

  • 登录自己的AWS账号进入到aws控制管理台, 然后搜索 Transcribe 进入到这个管理后台

  • 点击 Create job 按钮就可以使用AWS的语音转文本服务,根据提示添加必备的参数设置

api接口

  • StartTranscriptionJob:开始一个转换任务

  • ListTranscriptionJobs:获取任务列表

  • GetTranscriptionJob:获取任务

  • CreateVocabulary:创建字典

  • DeleteVocabulary:删除字典

  • GetVocabulary:获取字典

  • ListVocabularies:获取字典列表

  • UpdateVocabulary:上传字典

python使用Transcribe演示实例

类型1

import time
import boto3
​
transcribe = boto3.client(('transcribe'))
job_name = "testTranscribeJob100"
job_uri = "https://s3.dualstack.us-east-1.amazonaws.com/*****/hellosammy.mp3"
​
transcribe.start_transcription_job(TranscriptionJobName=job_name, Media={'MediaFileUri': job_uri}, MediaFormat='mp3', LanguageCode='en-US')
​
while True:
    status = transcribe.get_transcription_job(TranscriptionJobName = job_name)
    if status['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', "FAILED"]:
        break
​
    print("Job not ready yet...")
    time.sleep(5)
​
print(status)

类型2

  • 安装 Python 的程序包

pip3 install boto3
pip3 install amazon_transcribe
pip3 install websocket-client
  • import 部分

import hashlib
import hmac
import urllib.parse
from datetime import datetime
import time
import ssl
import json
import websocket
import _thread
from amazon_transcribe.eventstream import EventStreamMessageSerializer
from amazon_transcribe.eventstream import EventStreamBuffer
from boto3.session import Session
  • 创建URL 函数

def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()
 
def getSignatureKey(key, dateStamp, region, serviceName):
    kDate = sign(("AWS4" + key).encode("utf-8"), dateStamp)
    kRegion = sign(kDate, region)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, "aws4_request")
    return kSigning
 
def create_pre_signed_url(region, language_code, media_encoding, sample_rate):
    # 获得access key和secret key
    credentials = Session().get_credentials()
    access_key_id = credentials.access_key
    secret_access_key = credentials.secret_key
 
    method = "GET"
    service = "transcribe"
    endpoint = "wss://transcribestreaming." + region + ".amazonaws.com:8443"
    host = "transcribestreaming." + region + ".amazonaws.com:8443"
    algorithm = "AWS4-HMAC-SHA256"
 
    t = datetime.utcnow()
    amz_date =t.strftime('%Y%m%dT%H%M%SZ')
    datestamp =t.strftime('%Y%m%d')
 
    canonical_uri = "/stream-transcription-websocket"
 
    canonical_headers = "host:" + host + "\n"
    signed_headers = "host"
 
    credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
 
    canonical_querystring = "X-Amz-Algorithm=" + algorithm
    canonical_querystring += "&X-Amz-Credential=" + urllib.parse.quote_plus(access_key_id + "/" + credential_scope)
    canonical_querystring += "&X-Amz-Date=" + amz_date
    canonical_querystring += "&X-Amz-Expires=300"
    canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
    canonical_querystring += "&language-code="+ language_code +"&media-encoding=" + media_encoding +"&sample-rate=" + sample_rate
 
    # Zero length string for connecting
    payload_hash = hashlib.sha256(("").encode('utf-8')).hexdigest()
 
    canonical_request = method + '\n' \
                        + canonical_uri + '\n' \
                        + canonical_querystring + '\n' \
                        + canonical_headers + '\n' \
                        + signed_headers + '\n' \
                        + payload_hash
 
    string_to_sign = algorithm + "\n" \
                     + amz_date + "\n" \
                     + credential_scope + "\n" \
                     + hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
 
    signing_key = getSignatureKey(secret_access_key, datestamp, region, service)
 
    signature = hmac.new(signing_key, string_to_sign.encode("utf-8"),
                         hashlib.sha256).hexdigest()
 
    canonical_querystring += "&X-Amz-Signature=" + signature
 
    request_url = endpoint + canonical_uri + "?" + canonical_querystring
 
    return request_url
  • main 函数

def main():
    url = create_pre_signed_url("us-east-1", "en-US", "pcm", "16000")
    ws = websocket.create_connection(url, sslopt={"cert_reqs": ssl.CERT_NONE})
 
    _thread.start_new_thread(loop_receiving, (ws,))
    print("Receiving...")
    send_data(ws)
 
    while True:
        time.sleep(1)
main()
  • loop_receiving 函数

该函数位于 main 函数上方。它将接收 Amazon Transcribe Streaming Service 的返回数据,并且打印出来。

def loop_receiving(ws):
    try:
        while True:
            result = ws.recv()
 
            if result == '':
                continue
 
            eventStreamBuffer = EventStreamBuffer()
 
            eventStreamBuffer.add_data(result)
            eventStreamMessage = eventStreamBuffer.next()
 
            stream_payload = eventStreamMessage.payload
 
            transcript = json.loads(bytes.decode(stream_payload, "UTF-8"))
 
            print("response:",transcript)
 
            results = transcript['Transcript']['Results']
            if len(results)>0:
                for length in range(len(results)):
                    if 'IsPartial' in results[length]:
                        print('IsPartial:', results[length]['IsPartial'])
 
                    if 'Alternatives' in results[length]:
                        alternatives = results[length]['Alternatives']
                        if len(alternatives)>0:
                            for sublength in range(len(alternatives)):
                                if 'Transcript' in alternatives[sublength]:
                                    print('Transcript:', alternatives[sublength]['Transcript'])
 
 
    except Exception as e:
        if 'WebSocketConnectionClosedException' == e.__class__.__name__:
            print("Error: websocket connection is closed")
        else:
            print(f"Exception Name: {e.__class__.__name__}")
  • send_data 函数

该函数位于 main 函数上方。它将发送音频数据到 Amazon Transcribe Streaming Service。其中 testFile 变量是测试音频文件地址,测试音频为 pem 格式,英语,采样率为16000。

def send_data(ws):
 
    testFile = "xxx.pem"
 
    bufferSize = 1024*16
 
    stream_headers = {
        ":message-type": "event",
        ":event-type": "AudioEvent",
        ":content-type": "application/octet-stream",
    }
 
    eventstream_serializer = EventStreamMessageSerializer()
 
    with open(testFile, "rb") as source:
        while True:
            audio_chunk = source.read(bufferSize)
            # 将音频数据进行编码
            event_bytes = eventstream_serializer.serialize(stream_headers, audio_chunk)
 
            ws.send(event_bytes, opcode = 0x2) # 0 x 2 send binary
 
            # end with b'' data bytes
            if len(audio_chunk) == 0:
                break

java使用Transcribe演示实例

import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.Upload;
import com.amazonaws.services.transcribe.AmazonTranscribe;
import com.amazonaws.services.transcribe.AmazonTranscribeClientBuilder;
import com.amazonaws.services.transcribe.model.*;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
 
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
/**
 * 代码注意: 生成job只保存到S3,所以要保存到本地的思路是先保存到S3,然后下载,
 * 但是期间需要时间,所以不断的查询是否存在在不断的遍历循环比较慢
 *
 * @author DELL
 * @Desc 将本地MP3上传到S3, 然后再转文本,保存json 文件到本地
 * 基本步骤:
 * 1.建立S3客户端连接
 * 2.上传本地音频到S3库中,并返回一个S3地址
 * 3.上传MP3对应的备用单词词库
 * 3.在Amazon Transcribe 创建一个job,将生成的json 文件保存到MP3同级目录
 */
public class Mp3ToJsonUtils {
 
    // 执行文件配置信息
    private static String FILE_TYPE = "mp3";
    // S3配置信息
    private static String AWS_ACCESS_KEY = "自己生成";
    private static String AWS_SECRET_KEY = "自己生成";
    private static final String BUCKET_NAME = "自己生成";
    private static final String JOB_BUCKET_NAME = "自己生成";
    // Aws对象信息
    private static AmazonS3 s3;
    private static TransferManager tx;
    private static AmazonTranscribe amazonTranscribe;
    private static BasicAWSCredentials awsCredentials;
 
    static {
        //1. 建立连接
        try {
            init_with_key();
        } catch (Exception e) {
            e.printStackTrace();
        }
        awsCredentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
        amazonTranscribe = AmazonTranscribeClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).withRegion(Regions.US_EAST_2).build();
    }
 
    public static void main(String[] args) throws Exception {
        List<String> list = new ArrayList<>();
        mp3TOJosn("C:\\Users\\DELL\\Desktop\\BK测试数据\\A_Cinderella_Atlas_5.mp3", list);
    }
 
    public static void mp32Josn(String inPath, String savePath, List<String> list) throws Exception {
        String jsonPath = new File(inPath).getParent();
        String name = new File(inPath).getName().replaceAll(" ", "_").replaceAll("-", "_");
        File file = new File(savePath + "\\" + name + ".json");
        //确保上传一次
        if (file.exists()) {
            System.out.println(savePath + "--->已经处理完毕,跳过处理");
            return;
        }
        //2. 上传文件到S3库,得到上传文件对应的S3 URL
        String s3Path = uploadFileToBucket(inPath, BUCKET_NAME);
        String key = new File(s3Path).getName();
        key = key.replaceAll(" ", "_").replaceAll("-", "_");
        //3. 创建Transcription jobs
        createJob(JOB_BUCKET_NAME, FILE_TYPE, key, s3Path);
        //4. 将json文件下载到本地和MP3 同目录
        // 在创建job 生成json 的时候需要一定的时间,先等待一段时间,然后判断存在不存在
        boolean flag = isObjectExit(BUCKET_NAME, key + ".json");
        while (!flag) {
            flag = isObjectExit(BUCKET_NAME, key + ".json");
        }
        amazonS3Downloading(s3, JOB_BUCKET_NAME, key + ".json", savePath + "\\" + key + ".json");
    }
 
    /**
     * 将 MP3 转成 Json文件保存到本地
     *
     * @param inPath
     * @throws Exception
     */
    public static void mp3TOJosn(String inPath, List<String> list) throws Exception {
        String jsonPath = new File(inPath).getParentFile().getParentFile().getParentFile().getAbsolutePath() + "\\json";
        File file1 = new File(jsonPath);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        mp32Josn(inPath, jsonPath, list);
    }
 
    /**
     * 通过在代码中包含 access key id 和 secret access key 连接 aws
     *
     * @throws Exception
     */
    private static void init_with_key() throws Exception {
        AWSCredentials credentials = null;
        credentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
        s3 = new AmazonS3Client(credentials);
        //Region usWest2 = Region.getRegion(Regions.US_WEST_2);
        //s3.setRegion(usWest2);
        tx = new TransferManager(s3);
    }
 
    /**
     * 上传一个本地文件(对应位置为path)上传到名为bucketName的bucket
     *
     * @param path       需要上传文件的路径
     * @param bucketName S3中存储文件的桶名称
     *                   return 返回对应上传文件的key
     */
    private static String uploadFileToBucket(String path, String bucketName) {
        String keyName = new File(path).getName();
        File fileToUpload = new File(path);
        if (fileToUpload.exists() == false) {
            System.out.println(path + " not exists!");
            return null;
        }
        PutObjectRequest request = new PutObjectRequest(bucketName, fileToUpload.getName(), fileToUpload);
        Upload upload = tx.upload(request);
        while ((int) upload.getProgress().getPercentTransferred() < 100) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(path + " MP3上传成功!");
        String s3Path = "s3://" + BUCKET_NAME + "/" + keyName;
        return s3Path;
    }
 
    /**
     * 创建一个 Transcription jobs
     *
     * @param bucketName     S3桶的名称
     * @param fileName       文件类型 eg: mp3, mp4
     * @param jobName        要创建的job的名称
     * @param S3Path         对应S3桶中的对应MP3 或其他路径的S3URL
     * @param vocabularyName Custom vocabulary 对应的名称
     */
    protected static void createJob(String bucketName, String fileName, String jobName, String S3Path) {
        StartTranscriptionJobRequest startTranscriptionJobRequest = new StartTranscriptionJobRequest();
        Media media = new Media();
        media.setMediaFileUri(S3Path);
        // 设置JOb的相应参数  sampling rate 采(抽)样率;
        startTranscriptionJobRequest.withMedia(media)
                .withLanguageCode(LanguageCode.EnUS)
                .withMediaFormat(fileName)
                .withOutputBucketName(bucketName)
                .withSettings(settings)
                .setTranscriptionJobName(jobName);
 
        amazonTranscribe.startTranscriptionJob(startTranscriptionJobRequest);
        GetTranscriptionJobRequest request;
        request = new GetTranscriptionJobRequest();
        request.withTranscriptionJobName(jobName);
        GetTranscriptionJobResult result = amazonTranscribe.getTranscriptionJob(request);
        String status = result.getTranscriptionJob().getTranscriptionJobStatus();
        while (!status.toUpperCase().equals("COMPLETED")) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //System.out.println(status);
            result = amazonTranscribe.getTranscriptionJob(request);
            status = result.getTranscriptionJob().getTranscriptionJobStatus();
            if (status.toUpperCase().equals("FAILED")) {
                System.out.println(result.getTranscriptionJob().getTranscriptionJobName() + "---> is failed");
                System.out.println(result.getTranscriptionJob().getTranscriptionJobName() + "--->" + result.getTranscriptionJob().getFailureReason());
                throw new RuntimeException("transcriobe 失败");
            }
        }
        System.out.println(jobName + "Mp3 Job 生成成功");
    }
    /**
     * 将S3上的文件下载到本地
     *
     * @param s3Client s3客户端
     * @param bucketName 桶名称
     * @param key 文件名称
     * @param targetFilePath 本地路径
     */
    public static void amazonS3Downloading(AmazonS3 s3Client, String bucketName, String key, String targetFilePath) {
        S3Object object = s3Client.getObject(new GetObjectRequest(bucketName, key));
        if (object != null) {
            System.out.println("Content-Type: " + object.getObjectMetadata().getContentType());
            InputStream input = null;
            FileOutputStream fileOutputStream = null;
            byte[] data = null;
            try {
                //获取文件流
                input = object.getObjectContent();
                data = new byte[input.available()];
                int len = 0;
                fileOutputStream = new FileOutputStream(targetFilePath);
                while ((len = input.read(data)) != -1) {
                    fileOutputStream.write(data, 0, len);
                }
                System.out.println(targetFilePath + "json 文件下载文件成功");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
 
    /**
     * 判断名为bucketName的bucket里面是否有一个名为key的object
     *
     * @param bucketName
     * @param key
     * @return
     */
    private static boolean isObjectExit(String bucketName, String key) {
        int len = key.length();
        ObjectListing objectListing = s3.listObjects(bucketName);
        String s = new String();
        for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
            s = objectSummary.getKey();
            int slen = s.length();
            if (len == slen) {
                int i;
                for (i = 0; i < len; i++) {
                    if (s.charAt(i) != key.charAt(i)) {
                        break;
                    }
                }
                if (i == len) {
                    return true;
                }
            }
        }
        return false;
    }
}
 

效果演示

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

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

相关文章

星宿UI2.51资源付费变现小程序 支持流量主广告投放

目前&#xff0c;最新版的星宿UI是2.51版本。要搭建星宿UI&#xff0c;您需要准备备用域名、服务器和微信小程序账号。星宿UI提供了多项功能&#xff0c;包括文章展示、文章分类、资源链接下载和轮播图等。此外&#xff0c;还支持直接下载附件功能。这些功能使得星宿UI非常适合…

OpenHarmony Promise详解

一&#xff0c;定义 作为一个android开发人员&#xff0c;刚接触Promise可能不好理解&#xff0c;因为android中的异步操作都是开启线程操作或者kotlin的协程&#xff0c;但是Promise并不是单独去开启一个线程来处理异步任务&#xff0c;它是在同一个线程中去处理异步任务。异…

IntelliJ IDEA cmd和idea Terminal查看java版本不一致

参考&#xff1a;IntelliJ IDEA cmd和idea Terminal查看java版本不一致的解决方案 1、idea清缓存重启 没用 2、删除缓存文件 没试 3、修改环境变量的顺序 没试 4、重启电脑 麻烦&#xff0c;没试 5、项目配置jdk7 没试 按照这个url配置了一个遍 https://blog.csdn…

假如我是Langchain专家,你会问什么来测试我的水平

推荐Langchain YouTube 视频排行榜 1. 假如我是Langchain专家&#xff0c;你会问什么来测试我的水平&#xff1b; 作为Langchain专家&#xff0c;您可能需要回答一系列深入和具体的问题&#xff0c;这些问题旨在测试您对Langchain的理解和实际应用能力。以下是一些可能的问题…

机器学习入门案例(3)之使用决策树预测是否适合打网球

大家好&#xff0c;我是邵奈一&#xff0c;一个不务正业的程序猿、正儿八经的斜杠青年。 1、世人称我为&#xff1a;被代码耽误的诗人、没天赋的书法家、五音不全的歌手、专业跑龙套演员、不合格的运动员… 2、这几年&#xff0c;我整理了很多IT技术相关的教程给大家&#xff0…

U-Mail海外邮件中继帮您解决企业邮件退信难题

过去一年&#xff0c;国内外形势严峻复杂&#xff0c;但中国外贸顶住压力、爬坡过坎&#xff0c;进出口规模冲破40万亿元大关&#xff0c;高达42万亿元人民币&#xff0c;中国连续6年位居货物贸易第一大国。随着我国疫情防控措进入新阶段&#xff0c;“拼经济”正在成为各地的一…

【Windows 开发环境配置——NVIDIA 篇】CUDA、cuDNN、TensorRT 三件套安装

CUDA 从CUDA Toolkit Archive下载相应版本的离线安装包&#xff0c;这里以11.7为例。 打开安装包&#xff0c;在安装选项选择自定义模式&#xff0c;点击下一步。 在自定义安装选项中&#xff0c;仅选择CUDA组件&#xff08;其中Nsight相关组件用于代码调试与性能分析&#xff…

NSSCTF第12页(1)

[FSCTF 2023]细狗2.0 应该是和[HUBUCTF 2022 新生赛]ezsql搞混掉了 点击按钮出现了 发现输入什么回显什么 伪协议也不行 看源代码发现了这个玩意 输入了1;发现了其他回显 ls 发现了两个文件 发现被限制了 不知道是cat还是空格 绕过 直接找吧还是 得到flag [SCTF 2021]loginm…

详解 KEIL C51 软件的使用·建立工程

单片机要运行,就必须将程序代码下载到程序存储器内部,但是在写进单片机之前要先将你写 的程序转换成*.hex 或*.bin 的文件.不同系列的单片机都有不同的软件对其进行编绎,而 keil Cx51 是德国开发的一个专为 51 系列单片机提供的软件开发平台,基本上现在的所有 51 系列内核的单片…

嵌入式养成计划-53----ARM--串口通信

一百三十四、串口通信 134.1 串口的概念 串口&#xff08;UART&#xff09;&#xff1a;Universal asynchronous receiver transmitter (USART/UART)&#xff0c;通用异步接收发送器通过串口可以实现两个不同机器之间的信息交互串口通信属于总线通信的一种 134.2 总线的概念…

GZ038 物联网应用开发赛题第7套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 &#xff08;第7套卷&#xff09; 工位号&#xff1a;______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具&#xff0c;操作安全规范&#xff1b; 2、竞赛过程中如有异议&#xff0c;可向现场考评…

处理本地DNS劫持,导致域名解析失败

回顾情形 在公司内网&#xff0c;有同事反馈appstoreconnect.apple.com网站需要通过代理才能正常访问。 向我这边询问&#xff0c;否修改过路由策略&#xff1b; 检测域名 通过域名ping检测网址&#xff0c;https://ping.chinaz.com/astrill.com&#xff0c;来ping域名apps…

1688往微信小程序自营商城铺货商品采集API接口

一、背景介绍 随着移动互联网的快速发展&#xff0c;微信小程序作为一种新型的电商形态&#xff0c;正逐渐成为广大商家拓展销售渠道、提升品牌影响力的重要平台。然而&#xff0c;对于许多传统企业而言&#xff0c;如何将商品信息快速、准确地铺货到微信小程序自营商城是一个…

第五章ARM处理器的嵌入式硬件系统设计——课后习题

1ARM处理器的工作状态 ARM处理器有两种工作状态。具体而言&#xff0c;ARM处理器执行32位ARM指令集时&#xff0c;工作在ARM状态&#xff0c;当ARM处理器执行16位thumb指令集时候&#xff0c;工作在thumb状态。 1ARM指令特点 1一个大的&#xff0c;统一的寄存器文件。 2基于…

后端接口性能优化分析-数据库优化

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

​如何解决SSD NAND Path冲突导致的性能问题?

1.引言 最近看到一篇关于SSD的NAND并发瓶颈相关的论文&#xff0c;思路非常好&#xff0c;这里分享给大家。本篇论文的解读&#xff0c;也是小编上周末在高铁上完成的。存储随笔的论文解读&#xff0c;不是直接翻译&#xff0c;是小编先研读一遍后&#xff0c;再结合自己的理解…

SoftwareTest6 - 用 Selenium 怎么点点点

用 Selenium 来点点点 一 . 什么是自动化 ?1.1 自动化测试的分类接口自动化测试UI 自动化测试 (界面测试) 1.2 实现自动化测试的工具 : selenium环境部署驱动 二 . selenium 的使用2.1 一个简单的示例 : 让谷歌浏览器在百度首页搜索蔡徐坤准备工作编写代码 2.2 打开谷歌浏览器…

世界互联网大会|美创科技新一代 灾备一体化平台(DRCC v3.0)重磅亮相

11月9日&#xff0c;在2023年世界互联网大会“互联网之光”博览会上&#xff0c;美创科技携2023年重磅新品——新一代 灾备一体化平台&#xff08;DRCC v3.0&#xff09;亮相&#xff01; ◼︎ 云计算、国产化浪潮下&#xff0c;各类信息基础设施的运行安全面临全新挑战&#…

性能测试 —— Jmeter分布式测试的注意事项和常见问题

Jmeter是一款开源的性能测试工具&#xff0c;使用Jmeter进行分布式测试时&#xff0c;也需要注意一些细节和问题&#xff0c;否则可能会影响测试结果的准确性和可靠性。 Jmeter分布式测试时需要特别注意的几个方面 1. 参数化文件的位置和内容 如果使用csv文件进行参数化&…

【Java 进阶篇】JQuery 案例:优雅的隔行换色

在前端的设计中&#xff0c;页面的美观性是至关重要的。而其中一个简单而实用的设计技巧就是隔行换色。通过巧妙地使用 JQuery&#xff0c;我们可以轻松地实现这一效果&#xff0c;为网页增添一份优雅。本篇博客将详细解析 JQuery 隔行换色的实现原理和应用场景&#xff0c;让我…