当前位置: 首页 > news >正文

海思ss928部署手写数字识别模型

大致流程---------------------------------------------------------------------------------------------------------------------

模型转换----------------------------------------------------------------------------------------------------

1:准备MNIST的onnx模型---> https://kdocs.cn/l/ctULnY8mxXuE

github地址--> GitHub - warren-wzw/MNIST-pytorch

搭建好ATC的环境--> https://kdocs.cn/l/cjeQxGjfojsX

首先设置环境变量

source /home/warren/Ascend/ascend-toolkit/latest/x86_64-linux/bin/setenv.bash

转化模型

atc --model=/home/warren/Ascend/yolov5/model/yolov5s.onnx \

--soc_version=OPTG  --framework=5 \

--output=/home/warren/Ascend/yolov5/model/yolov5s \

--input_shape="input0:1,2,64,64"  

atc --model=/home/warren/ss928/NNN_PC/amct/amct_onnx/sample/MNIST/outputs/calibration/MNIST_deploy_model.onnx \

> --soc_version=OPTG  --framework=5 \

> --output=/home/warren/ss928/NNN_PC/amct/amct_onnx/sample/MNIST/outputs/calibration/MNIST \

> --input_shape="input0:1,3,640,640"

模型转化成功后得到以下文件

        

模型量化--------------------------------------------------------------------------------------------------------------

目录结构

import os
import argparse
import cv2
import numpy as np
import onnxruntime as ort
import time
import torchimport amct_onnx as amctPATH = os.path.realpath('./')
DATA_DIR = os.path.join(PATH, 'data')
PARSER = argparse.ArgumentParser(description='amct_onnx MNIST quantization sample.')
ARGS = PARSER.parse_args()
OUTPUTS = os.path.join(PATH, 'outputs/calibration')
TMP = os.path.join(OUTPUTS, 'tmp')def onnx_forward(onnx_model, batch_size=1, iterations=100):ort_session = ort.InferenceSession(onnx_model, amct.AMCT_SO)with open("./data/train-images-idx3-ubyte","rb") as f:file = f.read()num = -1j=0inference_time =[0]for j in range(100):num=num+1i = 16+784*numimage1 = [int(str(item).encode('ascii'),16) for item in file[i:i+784]]input_data = np.array(image1,dtype=np.float32).reshape(1,1,28,28)#np.set_printoptions(linewidth=150)#print(input_data)input_name = ort_session.get_inputs()[0].name# inferencestart_time = time.time()output = ort_session.run(None, {input_name: input_data})end_time = time.time()inference_time.append(end_time - start_time)# 处理输出结果output = torch.tensor(output[0])  # 将输出转换为 PyTorch 张量#print(output_tensor)# 输出结果处理和后续操作...pred =np.argmax(output)print("------------------------The num of this pic is ",pred,"use time ",inference_time[num]*1000,"ms",j)def main():model_file = './model/model.onnx'print('[INFO] Do original model test:')onnx_forward(model_file,1,1)config_json_file = os.path.join(TMP, 'config.json')skip_layers = []amct.create_quant_config(config_file=config_json_file, model_file=model_file, skip_layers=skip_layers, batch_num=1,activation_offset=True, config_defination=None)# Phase1: do conv+bn fusion, weights calibration and generate#         calibration modelscale_offset_record_file = os.path.join(TMP, 'record.txt')modified_model = os.path.join(TMP, 'modified_model.onnx')amct.quantize_model(config_file=config_json_file, model_file=model_file, modified_onnx_file=modified_model,record_file=scale_offset_record_file)onnx_forward(modified_model, 32, 1)# Phase3: save final model, one for onnx do fake quant test, one#         deploy model for ATCresult_path = os.path.join(OUTPUTS, 'MNIST')amct.save_model(modified_model, scale_offset_record_file, result_path)# Phase4: run fake_quant model testprint('[INFO] Do quantized model test:')onnx_forward('%s_%s' % (result_path, 'fake_quant_model.onnx'), 1, 1)
if __name__ == '__main__':main()

推理代码编写---------------------------------------------------------------------------------------------------

将官方的sample复制一份改为MNIST,目录结构如下图所示

更改camke文件

1:添加环境变量:

export DDK_PATH=$HOME/Ascend/ascend-toolkit/latest

export NPU_HOST_LIB=$DDK_PATH/runtime/lib64/stub

2:创建build目录

mkdir -p build/intermediates/host

3:cmake ../../../src -DCMAKE_CXX_COMPILER=aarch64-mix210-linux-g++ -DCMAKE_SKIP_RPATH=TRUE

将整个MNIST文件夹拷贝至板端,添加库文件路径的环境变量

export ASCEND_GLOBAL_EVENT_ENABLE=0

export ASCEND_AACPU_KERNEL_PATH=/opt/sd/lib

export ASCEND_AICPU_KERNEL_PATH=/opt/sd/lib

export LD_LIBRARY_PATH=/opt/sd/lib

执行可执行文件main

执行成功。

代码讲解-------------------------------------------------------------------------

大致逻辑

 

main.cpp

#include "main.h"
#include "acl/acl.h"#define INFO_LOG(fmt, ...)  fprintf(stdout, "[INFO]  " fmt "\n", ##__VA_ARGS__)
#define WARN_LOG(fmt, ...)  fprintf(stdout, "[WARN]  " fmt "\n", ##__VA_ARGS__)
#define ERROR_LOG(fmt, ...) fprintf(stderr, "[ERROR]  " fmt "\n", ##__VA_ARGS__)
const int MODEL_CHANNEL = 1;
const int MODEL_IN_WIDTH = 28;
const int MODEL_IN_HEIGHT = 28;
const int loop_count = 1000;typedef enum Result {SUCCESS = 0,FAILED = 1
} Result;static inline int64_t getCurrentTimeUs()
{struct timeval tv;gettimeofday(&tv, NULL);return tv.tv_sec * 1000000 + tv.tv_usec;
}
void Load_data(int num,unsigned char * input_image)
{int j=16+784*num;FILE *file = fopen("../data/train-images-idx3-ubyte", "rb");if (file == NULL) {printf("can't open the file!\n");}fseek(file,j,SEEK_SET);fread(input_image,sizeof(char),784,file);//print
/*     for(int i=0;i<MODEL_IN_WIDTH;i++){for(int j=0;j<MODEL_IN_WIDTH;j++){printf("%4d",input_image[i*28+j]);}printf("\n");}  */fclose(file);
}
void Bubble_sort(float *buffer,int num)
{float temp;for(int i=0; i<num;i++){for(int j=0; j<num-i-1;j++){if(buffer[j]>buffer[j+1]){temp = buffer[j];buffer[j]=buffer[j+1];buffer[j+1]=temp;}}}
}
int main()
{
/***************************************************/
/*****************define var************************/
/***************************************************/int num=0;aclError ret=1;const char *aclConfigPath = "../src/acl.json";int32_t deviceId_=0;aclrtContext context_=nullptr;aclrtStream stream_=nullptr;aclrtRunMode runMode;uint32_t modelId_=0;const char* modelPath = "../model/MNIST.om";aclmdlDesc *modelDesc_;aclmdlDataset *output_;aclmdlDataset *input_;void * inputDataBuffer = nullptr;size_t size = 784;void* input_image_original;void* time_ori;int64_t sum=0;int64_t start_time=0;int64_t end_time=0;
/***************************************************/
/*****************Init ACL**************************/
/***************************************************/ret = aclInit(aclConfigPath);if (ret != ACL_SUCCESS) {ERROR_LOG("acl init failed, errorCode = %d", static_cast<int32_t>(ret));return FAILED;}INFO_LOG("--------------------acl init success");
/***************************************************/
/*****************apply resource********************/
/***************************************************/// set device only one device    ret = aclrtSetDevice(deviceId_);if (ret != ACL_SUCCESS) {ERROR_LOG("acl set device %d failed, errorCode = %d", deviceId_, static_cast<int32_t>(ret));return FAILED;}INFO_LOG("set device %d success", deviceId_);// create context (set current)ret = aclrtCreateContext(&context_, deviceId_);if (ret != ACL_SUCCESS) {ERROR_LOG("acl create context failed, deviceId = %d, errorCode = %d",deviceId_, static_cast<int32_t>(ret));return FAILED;}INFO_LOG("create context success");// create streamret = aclrtCreateStream(&stream_);if (ret != ACL_SUCCESS) {ERROR_LOG("acl create stream failed, deviceId = %d, errorCode = %d",deviceId_, static_cast<int32_t>(ret));return FAILED;}INFO_LOG("create stream success");// get run moderet = aclrtGetRunMode(&runMode);if (ret != ACL_SUCCESS) {ERROR_LOG("acl get run mode failed, errorCode = %d", static_cast<int32_t>(ret));return FAILED;} 
/***************************************************/
/********load model and get infos of model**********/
/***************************************************/ret = aclmdlLoadFromFile(modelPath,&modelId_);if (ret != ACL_SUCCESS) {ERROR_LOG("load model from file failed, model file is %s, errorCode is %d",modelPath, static_cast<int32_t>(ret));return FAILED;}INFO_LOG("load model %s success id is %d\n", modelPath,modelId_);//get model describemodelDesc_ = aclmdlCreateDesc();if (modelDesc_ == nullptr) {ERROR_LOG("create model description failed");return FAILED;}ret = aclmdlGetDesc(modelDesc_, modelId_);if (ret != ACL_SUCCESS) {ERROR_LOG("get model description failed, modelId is %u, errorCode is %d",modelId_, static_cast<int32_t>(ret));return FAILED;}INFO_LOG("create model description success");
/***************************************************/
/******************print input tensor***************/
/***************************************************/     
/*     aclmdlIODims *dim;ret=aclmdlGetInputDims(modelDesc_,0,dim);printf("----------------in dims is %d \n",dim->dimCount);printf("----------------in dims name is: %s dims: \n",dim->name);for(int num=0;num<dim->dimCount;num++){printf("%d ",num,dim->dims[num]);}ret = aclmdlGetOutputDims(modelDesc_,0,dim);printf("----------------out dims is %d \n",dim->dimCount);printf("----------------out dims name is: %s dims:\n",dim->name);for(int num=0;num<dim->dimCount;num++){printf("%d \n",num,dim->dims[num]);} deviceId_=0;*/
/***************************************************/
/******************prepare output data buffer***************/
/***************************************************/output_ = aclmdlCreateDataset();if (output_ == nullptr) {ERROR_LOG("can't create dataset, create output failed");return FAILED;}size_t outputSize = aclmdlGetNumOutputs(modelDesc_); for (size_t i = 0; i < outputSize; ++i) {size_t modelOutputSize = aclmdlGetOutputSizeByIndex(modelDesc_, i);void *outputBuffer = nullptr;ret = aclrtMalloc(&outputBuffer, modelOutputSize, ACL_MEM_MALLOC_NORMAL_ONLY);if (ret != ACL_SUCCESS) {ERROR_LOG("can't malloc buffer, size is %zu, create output failed, errorCode is %d",modelOutputSize, static_cast<int32_t>(ret));return FAILED;}//apply output bufferaclDataBuffer *outputData = aclCreateDataBuffer(outputBuffer, modelOutputSize);if (outputData == nullptr) {ERROR_LOG("can't create data buffer, create output failed");(void)aclrtFree(outputBuffer);return FAILED;}ret = aclmdlAddDatasetBuffer(output_, outputData);if (ret != ACL_SUCCESS) {ERROR_LOG("can't add data buffer, create output failed, errorCode is %d",static_cast<int32_t>(ret));(void)aclrtFree(outputBuffer);(void)aclDestroyDataBuffer(outputData);return FAILED;}}INFO_LOG("create model output success");
/***************************************************/
/******************prepare input data***************/
/***************************************************/    if (modelDesc_ == nullptr) {ERROR_LOG("no model description, create input failed");return FAILED;}input_ = aclmdlCreateDataset();if (input_ == nullptr) {ERROR_LOG("can't create dataset, create input failed");return FAILED;}size_t modelInputSize = aclmdlGetInputSizeByIndex(modelDesc_, 0);ret = aclrtMalloc(&input_image_original, 784, ACL_MEM_MALLOC_NORMAL_ONLY);if (ret != ACL_SUCCESS) {ERROR_LOG("malloc device buffer failed. size is %zu, errorCode is %d",size, static_cast<int32_t>(ret));return FAILED;}unsigned char * input_image = static_cast<unsigned char*>(input_image_original);void* input_image_float_ori;ret = aclrtMalloc(&input_image_float_ori, 784*sizeof(float), ACL_MEM_MALLOC_NORMAL_ONLY);if (ret != ACL_SUCCESS) {ERROR_LOG("malloc device buffer failed. size is %zu, errorCode is %d",size, static_cast<int32_t>(ret));return FAILED;}float * input_image_float = static_cast<float*>(input_image_float_ori);;Load_data(num,input_image);for(int num=0;num<784;num++){input_image_float[num]=(float)input_image[num];}
/*     aclrtFree(input_image);input_image=nullptr; */aclDataBuffer *inputData = aclCreateDataBuffer(input_image_float, modelInputSize);if (inputData == nullptr) {ERROR_LOG("can't create data buffer, create input failed");return FAILED;}ret = aclmdlAddDatasetBuffer(input_, inputData);if (ret != ACL_SUCCESS) {ERROR_LOG("add input dataset buffer failed, errorCode is %d", static_cast<int32_t>(ret));(void)aclDestroyDataBuffer(inputData);inputData = nullptr;return FAILED;}INFO_LOG("create model input success");ret = aclrtMalloc(&time_ori, loop_count*sizeof(int64_t), ACL_MEM_MALLOC_NORMAL_ONLY);if (ret != ACL_SUCCESS) {ERROR_LOG("malloc device buffer failed. size is %zu, errorCode is %d",loop_count*sizeof(int64_t), static_cast<int32_t>(ret));return FAILED;}int64_t * time = static_cast<int64_t*>(time_ori);for(int loop_time=0;loop_time < loop_count;loop_time++){num++;Load_data(num,input_image);for(int loop_num=0;loop_num<784;loop_num++){input_image_float[loop_num]=(float)input_image[loop_num];}void* data = aclGetDataBufferAddr(inputData);uint32_t len = aclGetDataBufferSizeV2(inputData);     float *indata = NULL;  indata = reinterpret_cast<float*>(data);  /***************************************************//******************inference************************//***************************************************/start_time = getCurrentTimeUs();ret = aclmdlExecute(modelId_, input_, output_);end_time = getCurrentTimeUs();time[loop_time]=end_time-start_time;sum=sum+time[loop_time];printf("---Elapse Time = %.3f ms \n", (end_time-start_time) / 1000.f);   
/***************************************************/
/******************post process*********************/
/***************************************************/// get model output dataaclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, 0);void* data_1 = aclGetDataBufferAddr(dataBuffer);uint32_t len_1 = aclGetDataBufferSizeV2(dataBuffer);     float *outData = NULL;  outData = reinterpret_cast<float*>(data_1);  void* buffer_copy_ori;ret = aclrtMalloc(&buffer_copy_ori, len_1*sizeof(float), ACL_MEM_MALLOC_NORMAL_ONLY);if (ret != ACL_SUCCESS) {ERROR_LOG("malloc device buffer failed. size is %zu, errorCode is %d",len_1, static_cast<int32_t>(ret));return FAILED;}float * buffer_copy = static_cast<float*>(buffer_copy_ori);for(int i_1 = 0; i_1 < len_1/sizeof(*outData);i_1++){buffer_copy[i_1]=outData[i_1];}Bubble_sort(outData,len_1/sizeof(*outData));for(int i_2 =0;i_2<len_1/sizeof(*outData);i_2++){if(buffer_copy[i_2]==outData[9]){printf("------------------------------------------%d time the pic value is %d \n",loop_time,i_2);}} aclrtFree(buffer_copy);buffer_copy=nullptr;}printf("--------loop %d times sum is %.4f ms average time is %.3f ms\n", loop_count,sum / 1000.f,(sum / 1000.f)/loop_count);aclrtFree(time);time=nullptr;aclrtFree(input_image);input_image=nullptr;aclrtFree(input_image_float);input_image_float=nullptr;/***************************************************/
/*******************destroy model input*************/
/***************************************************/for(size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) {aclDataBuffer *dataBuffer = aclmdlGetDatasetBuffer(input_, i);(void)aclDestroyDataBuffer(dataBuffer);}(void)aclmdlDestroyDataset(input_);input_ = nullptr;INFO_LOG("destroy model input success");
/***************************************************/
/*********************destroy model output*********/
/***************************************************/for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);void* data = aclGetDataBufferAddr(dataBuffer);(void)aclrtFree(data);(void)aclDestroyDataBuffer(dataBuffer);}(void)aclmdlDestroyDataset(output_);output_ = nullptr;INFO_LOG("destroy model output success");
/***************************************************/
/******uninstall model and release resource*********/
/***************************************************/modelId_=1;ret = aclmdlUnload(modelId_);// releasemodelDesc_if (modelDesc_ != nullptr) {aclmdlDestroyDesc(modelDesc_);modelDesc_ = nullptr;}INFO_LOG("unload model success, modelId is %u", modelId_);// release resorceif (stream_ != nullptr) {ret = aclrtDestroyStream(stream_);if (ret != ACL_SUCCESS) {ERROR_LOG("destroy stream failed, errorCode = %d", static_cast<int32_t>(ret));}stream_ = nullptr;}INFO_LOG("end to destroy stream");if (context_ != nullptr) {ret = aclrtDestroyContext(context_);if (ret != ACL_SUCCESS) {ERROR_LOG("destroy context failed, errorCode = %d", static_cast<int32_t>(ret));}context_ = nullptr;}INFO_LOG("end to destroy context");ret = aclrtResetDevice(deviceId_);if (ret != ACL_SUCCESS) {ERROR_LOG("reset device %d failed, errorCode = %d", deviceId_, static_cast<int32_t>(ret));}INFO_LOG("end to reset device %d", deviceId_);ret = aclFinalize();if (ret != ACL_SUCCESS) {ERROR_LOG("finalize acl failed, errorCode = %d", static_cast<int32_t>(ret));}INFO_LOG("end to finalize acl");
}

 

执行结果:

fp32

int8

相关文章:

海思ss928部署手写数字识别模型

大致流程--------------------------------------------------------------------------------------------------------------------- 模型转换---------------------------------------------------------------------------------------------------- 1&#xff1a;准备MNI…...

组学知识速递(五)|ChIP-seq知多少?

近段时间来&#xff0c;我们合作的ChIP-Seq技术发表的高分成功案例一篇接一篇&#xff0c;您是否心动了呢&#xff1f;本篇文章&#xff0c;总结了ChIP-Seq实验部分重点知识点&#xff0c;开启ChIP-Seq的你绝不要错过&#xff01; Q1 什么是ChIP-Seq&#xff1f; ChIP-Seq即染…...

2308C++内存序概略

参考 释放:在释放前的任意读写操作不能放在此操作之后. 获取:在获取后的任意读写操作不能放在此操作之前. 放松:只保证本操作的原子性,一般用于统计. 消费:在加载后的依赖本原子变量的,都不能重排在本操作之前. 获取释放:获取释放 序列一致,完全一致....

【C++】string的使用

1、string的使用 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include<string> using namespace std;void Test1() {string s1;string s2("hello");cin >> s1;cout << s1 << endl;//strcat【字符串拼接】string ret1 s…...

Android 周期任务

AlarmManager使用 1.创建意图 // 创建意图&#xff0c;启动MonthlyTaskServiceIntent intent new Intent(getContext(), TimeTaskService.class); // 传递数据intent.putExtra(TimeTaskService.KEY_TITLE,userRemind.getTitle());intent.putExtra(TimeTaskService.KEY_DEC,u…...

修改第三方组件默认样式

深度选择器 修改el-input的样式&#xff1a; <el-input class"input-area"></el-input>查看DOM结构&#xff1a; 原本使用 /deep/ 但是可能不兼容 使用 :deep .input-area {:deep(.el-input__inner){background-color: blue;} }将 input 框背景色改为…...

【游戏客户端】制作你玩我猜Like玩法

【游戏客户端】制作你玩我猜Like玩法 大家好&#xff0c;我是Lampard猿奋~~ “你画我猜”相信大家都不陌生&#xff0c;当初这款小游戏可谓茶余饭后必玩之选&#xff0c;风头一时无二。今天要和大家分享如何实现一个你玩我猜Like的玩法。 我们可以简单的把需求拆成两个个部分&…...

分页查询从接口到实现,统一对日期类型进行格式化处理

编写Service实现类编写Mapper的sql&#xff0c;但复杂的sql语句需要写到mapper对应的xml文件中日期类型格式化处理 /*** 扩展springmvc框架的消息转换器* param converters*/Overrideprotected void extendMessageConverters(List<HttpMessageConverter<?>> conve…...

栈和队列详解(1)

目录 一、什么是栈&#xff1f; 二、创建一个我们自己的栈 1.前置准备 1.1需要的三个文件 1.2结构体的创建和头文件的引用 2.接口的实现 2.1初始化栈结构体 2.2尾插(压栈) 2.3栈存放的元素个数和判断栈是否为空 2.4获取栈顶元素 2.5出栈 2.6摧毁栈 2.7测试接口 三、…...

苏州OV泛域名RSA加密算法https

RSA加密算法是一种非对称加密算法&#xff0c;它被广泛应用于信息安全领域。与对称加密算法不同&#xff0c;RSA加密算法使用了两个密钥&#xff0c;一个公钥和一个私钥。公钥可以公开&#xff0c;任何人都可以使用它加密信息&#xff0c;但只有私钥的持有者才能解密信息。RSA加…...

凯迪正大—微机继电保护校验仪

一、继电保护测试仪产品概述 KDJB-802继电保护测试仪是在参照电力部颁发的《微机型继电保护试验装置技术条件&#xff08;讨论稿&#xff09;》的基础上&#xff0c;听取用户意见&#xff0c;总结目前国内同类产品优缺点&#xff0c;充分使用现代的微电子技术和器件实现的一种新…...

Linux文件属性与权限管理(可读、可写、可执行)

Linux把所有文件和设备都当作文件来管理&#xff0c;这些文件都在根目录下&#xff0c;同时Linux中的文件名区分大小写。 一、文件属性 使用ls -l命令查看文件详情&#xff1a; 1、每行代表一个文件&#xff0c;每行的第一个字符代表文件类型&#xff0c;linux文件类型包括&am…...

Centos7.9安装lrzsz进行文件传输---Linux工作笔记059

这里咱们lrzsz命令,需要用来进行文件传输,因为如果不安装这个命令的话,那么 传输安装包什么的就不方便因为只有少数传输工具,才支持,直接拖拽的.没有的时候就可以用这个工具,用命令来传输 直接就是: sz 文件名 就可以把文件下载下来 rz 选择一个文件, 就可以把文件上传到当…...

酒吧座位全解析 小白必看

相信还有很多第一次去酒吧的朋友们还不了解吧台、散台、卡座的区分&#xff0c;下面我简单解说一下&#xff0c;如有错漏&#xff0c;欢迎指正&#xff01;一、吧台吧台是酒吧的核心部位&#xff0c;走进酒吧门&#xff0c;首先映入眼帘的就是吧台&#xff0c;一排人围着吧台几…...

DAY19

题目一 空间尝试模型 一个样本做行一个样本做列 范围尝试模型 以....做分隔 dp[i][j] 为以i为左界限 以j为右界限 求这个范围内的计算值(不对 是方法数) 这& | ^ 都是双目运算符 观察一下规律 整体字符数量一定为奇数(包括运算符和数字) 对应到数组中 数组的位一定是偶数…...

Data analysis|Tableau基本介绍及可实现功能

一、基础知识介绍 &#xff08;一&#xff09;什么是tableau tableau 成立于 2003 年&#xff0c;是斯坦福大学一个计算机科学项目的成果&#xff0c;该项目旨在改善分析流程并让人们能够通过可视化更轻松地使用数据。Tableau可以帮助用户更好地理解和发现数据中的价值&#x…...

单元测试优化:为什么要对程序进行测试?测试有什么好处?

单元测试&#xff08;Unit Testing&#xff09;又称为模块测试, 是针对程序模块&#xff08;软件设计的最小单位&#xff09;来进行正确性检验的测试工作。 程序单元是应用的最小可测试部件。简单来说&#xff0c;就是测试数据的稳定性是否达到程序的预期。 我们日常开发时可能…...

自动装配在Spring Boot中的重要性及实现方式

这里写目录标题 自动装配在Spring Boot中的重要性及实现方式什么是自动装配&#xff1f;如何实现自动装配&#xff1f;如何使用自动装配自动装配的优势总结 手写自动装配的Java代码示例原理 自动装配在Spring Boot中的重要性及实现方式 Spring Boot是基于Spring框架的开源框架…...

校对软件在司法系统中的应用:加强刑事文书审查

校对软件在司法系统中的应用可以加强刑事文书审查&#xff0c;提高文书的准确性和可靠性。 以下是校对软件在刑事文书审查方面的应用&#xff1a; 1.语法和拼写检查&#xff1a;校对软件可以自动检查刑事文书中的语法错误和拼写错误。这包括句子结构、主谓一致、动词形式等方面…...

微信小程序上传图片和文件

1.从微信里选择图片或文件上传 使用的vant的上传组件 原生用 wx.chooseMessageFile() html <!-- 从微信上面选择文件 --><van-uploader file-list"{{ file }}" bind:after-read"afterRead" max-count"{{3}}" deletable"{{ true…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

Xcode 16 集成 cocoapods 报错

基于 Xcode 16 新建工程项目&#xff0c;集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...