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

OrangePi AIpro学习3 —— vscode开发昇腾DVPP程序

目录

一、VScode配置

1.1 下载和安装

1.2 安装和配置需要的插件

二、构建项目

2.1 项目架构

2.2 解决代码高亮显示

2.3 测试编译

2.4 总结出最简单的代码

2.5 vscode报错找不到头文件解决方法

三、代码简单讲解

3.1 初始化部分

3.2 拷贝数据到NPU显存中

3.3 准备裁剪区域

3.4 准备输入输出描述符

3.5 收尾阶段

3.6 其他例程如何学习

四、DVPP输入输出图片限制

4.1 裁剪的输入图片要求

4.2 裁剪的输出图片要求

4.3 输出图片的格式和宽高

4.4 对输出的图片进行处理


一、VScode配置

1.1 下载和安装

1. 下载地址

Download Visual Studio Code - Mac, Linux, Windows

2. 安装中要注意的内容

1.2 安装和配置需要的插件

1. chinese中文

如果在这里安装不了的话,可以使用离线安装的方式,首先进入官网下载离线插件包:Extensions for Visual Studio family of products | Visual Studio Marketplace

然后在vscode中这么操作,选择刚刚下载的VSIX文件即可完成安装

2. 安装远程工具Remote

设置要连接的主机,然后两次回车

重启vscode

选择linux然后再输入密码

进入文件夹

二、构建项目

2.1 项目架构

data数据是从上面的crop中拿过来的 

cmake_minimum_required(VERSION 3.22)# 设置变量PROJECT_NAME的值为crop
set(PROJECT_NAME "crop")# 设置项目名称为crop
project(${PROJECT_NAME})# 添加dvpp需要的宏定义,相当于在代码中: #define ENABLE_DVPP_INTERFACE
add_definitions(-DENABLE_DVPP_INTERFACE)# 设置头文件目录
include_directories($ENV{INSTALL_DIR}/runtime/include/./include
)# 设置动态库目录
link_directories($ENV{INSTALL_DIR}/runtime/lib64/stub
)# 查找所有CMakeLists.txt所在目录下,src目录中的.c和.cpp文件
file(GLOB_RECURSE CPP_FILES     ${PROJECT_SOURCE_DIR}/src/*.c${PROJECT_SOURCE_DIR}/src/*.cpp
)# 编译输出的文件名为: crop  依赖src目录下的所有.c和.cpp结尾的文件
add_executable(${PROJECT_NAME}${CPP_FILES}
)target_link_libraries(${PROJECT_NAME}ascendcl acl_dvppstdc++
)

2.2 解决代码高亮显示

CMake或者cpp没有高亮显示就上传vsix文件到香橙派

然后在vscode中安装 

2.3 测试编译

提示要增加一行内容,这行内容指定了CMake需要的最小版本

 然后./crop就能运行程程序了

2.4 总结出最简单的代码

#include <iostream>
#include <memory>
#include <dirent.h>
#include <fstream>
#include "acl/acl.h"
#include "acl/ops/acl_dvpp.h"using namespace std;typedef struct PicDesc {string picName;int left;int top;int width;int height;
} PicDesc;aclrtContext g_context;
aclrtStream g_stream;
aclrtRunMode g_runMode;
acldvppChannelDesc * g_dvppChannelDesc;char * ReadBinFile(string fileName, uint32_t &fileSize)
{ifstream binFile(fileName, ifstream::binary);if (binFile.is_open() == false) {printf("Open file %s failed.\n", fileName.c_str());return nullptr;}binFile.seekg(0, binFile.end);uint32_t binFileBufferLen = binFile.tellg();if (binFileBufferLen == 0) {printf("Binfile is empty, filename is %s.\n", fileName.c_str());binFile.close();return nullptr;}binFile.seekg(0, binFile.beg);char * binFileBufferData = new(nothrow) char[binFileBufferLen];if (binFileBufferData == nullptr) {printf("Malloc binFileBufferData failed.\n");binFile.close();return nullptr;}binFile.read(binFileBufferData, binFileBufferLen);binFile.close();fileSize = binFileBufferLen;return binFileBufferData;
}uint32_t AlignmentHelper(uint32_t origSize, uint32_t alignment)
{if (alignment == 0) {return 0;}uint32_t alignmentH = alignment - 1;return (origSize + alignmentH) / alignment * alignment;
}uint32_t SaveDvppOutputData(const char *fileName, const void *devPtr, uint32_t dataSize)
{FILE * outFileFp = fopen(fileName, "wb+");if (g_runMode == ACL_HOST) {void * hostPtr = nullptr;aclrtMallocHost(&hostPtr, dataSize);aclrtMemcpy(hostPtr, dataSize, devPtr, dataSize, ACL_MEMCPY_DEVICE_TO_HOST);fwrite(hostPtr, sizeof(char), dataSize, outFileFp);(void)aclrtFreeHost(hostPtr);} else {fwrite(devPtr, sizeof(char), dataSize, outFileFp);}fflush(outFileFp);fclose(outFileFp);return 0;
}int main()
{/* * 初始化device、context、stream和dvppChannelDesc,并获取运行模式*/aclInit("./src/acl.json");aclrtSetDevice(0);aclrtCreateContext(&g_context, 0);aclrtCreateStream(&g_stream);g_dvppChannelDesc = acldvppCreateChannelDesc(); // 创建图像数据处理通道时的通道描述信息 g_dvppChannelDesc is acldvppChannelDesc typeacldvppCreateChannel(g_dvppChannelDesc);        // 创建图像数据处理通道aclrtGetRunMode(&g_runMode);/* * 读取输入和输出*/// 下面设置输入图片的信息,图片的left和top参数用不到PicDesc inPicDesc  = { "./data/wood_rabbit_1024_1068_nv12.yuv", 0, 0, 1024, 1068 };// 下面设置输出图片的信息PicDesc outPicDesc = { "./output/dvpp_rabbit_224_224_nv12.yuv", 350, 280, 224, 224 };/* * 根据输入读取文件到NPU显存中*/uint32_t buffSize = 0;// inPicDesc.picName:要读取的文件名     buffSize:得到的文件大小    inputBuff:得到的文件的内容char * inputBuff = ReadBinFile(inPicDesc.picName, buffSize);void * inputBufferDev = nullptr;acldvppMalloc(&inputBufferDev, buffSize);     // 在NPU上分配显存if (g_runMode == ACL_HOST)  // 如果本段C++代码是运行在CPU上{                           // 把数据从内存条拷贝到NPU的显存中aclrtMemcpy(inputBufferDev, buffSize, inputBuff, buffSize, ACL_MEMCPY_HOST_TO_DEVICE);} else                        // 如果本段C++代码是运行在NPU中的CPU上{                           // 把数据从NPU显存拷贝到NPU显存中aclrtMemcpy(inputBufferDev, buffSize, inputBuff, buffSize, ACL_MEMCPY_DEVICE_TO_DEVICE);}delete[] inputBuff;/** 设置要裁剪输入图片的区域*/uint32_t outputWidth = AlignmentHelper(outPicDesc.width, 16);   // 输入图片宽度按照16字节对其,例如输入17,得到的outputWidth就是32uint32_t outputHeight = AlignmentHelper(outPicDesc.height, 2);  // 输入图片高度按照2字节对其,例如输入13,得到的outputHeight就是2uint32_t cropLeftOffset = outPicDesc.left;                      // must 偶数uint32_t cropRightOffset = cropLeftOffset + outputWidth - 1;    // must 奇数uint32_t cropTopOffset = outPicDesc.top;                        // must 偶数uint32_t cropBottomOffset = cropTopOffset + outputHeight - 1;   // must 奇数acldvppRoiConfig * cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset);/** 创建输入图片描述符,并填写输入图片信息*/uint32_t inputWidthStride = AlignmentHelper(inPicDesc.width, 16);uint32_t inputHeightStride = AlignmentHelper(inPicDesc.height, 2);uint32_t inputBufferSize = inputWidthStride * inputHeightStride * 3 / 2;acldvppPicDesc * vpcInputDesc_ = acldvppCreatePicDesc();            // 创建入参数描述符acldvppSetPicDescData(vpcInputDesc_, inputBufferDev);               // 原图片存放位置的指针acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);    // 原图片的格式acldvppSetPicDescWidth(vpcInputDesc_, inPicDesc.width);             // 原图片宽度acldvppSetPicDescHeight(vpcInputDesc_, inPicDesc.height);           // 原图片高度acldvppSetPicDescWidthStride(vpcInputDesc_, inputWidthStride);      // 原图片对齐后的宽度acldvppSetPicDescHeightStride(vpcInputDesc_, inputHeightStride);    // 原图片对齐后的高度acldvppSetPicDescSize(vpcInputDesc_, inputBufferSize);              // 输入图片的图片大小/** 创建输出图片描述符,并填写输出图片信息*/void * outputBufferDev = nullptr;uint32_t outputBufferSize = outputWidth * outputHeight * 3 / 2;acldvppMalloc(&outputBufferDev, outputBufferSize);                  // 在NPU上给输出图片分配内存acldvppPicDesc * vpcOutputDesc_ = acldvppCreatePicDesc();acldvppSetPicDescData(vpcOutputDesc_, outputBufferDev);             // 输出图片存放位置指针acldvppSetPicDescFormat(vpcOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420);   // 输出图片的格式cout << outPicDesc.width << " " << outPicDesc.height << " " << outputWidth << " " << outputHeight << endl;acldvppSetPicDescWidth(vpcOutputDesc_, outPicDesc.width);           // 输出图片的宽acldvppSetPicDescHeight(vpcOutputDesc_, outPicDesc.height);         // 输出图片的高acldvppSetPicDescWidthStride(vpcOutputDesc_, outputWidth);          // 输出图片对齐后的宽acldvppSetPicDescHeightStride(vpcOutputDesc_, outputHeight);        // 输出图片对齐后的高acldvppSetPicDescSize(vpcOutputDesc_, outputBufferSize);/** 图片的处理和保存*/// 由g_stream这个流水线来运行处理程序acldvppVpcCropAsync(g_dvppChannelDesc, vpcInputDesc_, vpcOutputDesc_, cropArea_, g_stream);// 等待g_stream流水线完成aclrtSynchronizeStream(g_stream);// 保存图片SaveDvppOutputData(outPicDesc.picName.c_str(), outputBufferDev, outputBufferSize);/** 释放占用的资源*/acldvppFree(outputBufferDev);acldvppDestroyRoiConfig(cropArea_);acldvppDestroyPicDesc(vpcInputDesc_);acldvppDestroyPicDesc(vpcOutputDesc_);aclrtDestroyStream(g_stream);aclrtDestroyContext(g_context);aclrtResetDevice(0);aclFinalize();return 0;
}

下图代表裁剪成功了

2.5 vscode报错找不到头文件解决方法

按 F1 或 Ctrl+Shift+p 在弹出的备选选项中选择 C/C++:Edit Configurations (JSON),自动打开c_cpp_properties.json配置文件

 在.vscode中添加头文件搜索路径的json,然后配置路径

三、代码简单讲解

下面的内容全是我个人的理解,如果有佬,感谢在评论区指正,我会及时修改文章

3.1 初始化部分

88行:aclInit("./src/acl.json");

● 一个进程内只能调用一次aclInit接口。使用AscendCL接口开发应用时,必须先调用aclInit接口,否则可能会导致后续系统内部资源初始化出错,进而导致其它业务异常。

● 输入参数是一个json格式的文件。json里面可以写啥,这个可以看官方文档:

aclInit-系统配置-AscendCL API(C&C++)-应用开发接口-CANN社区版8.0.RC2.alpha001开发文档-昇腾社区 (hiascend.com)

目前我是在json里面就写了一对花括号:{}

● 在进程的最后,要成对的使用 aclFinalize(); 函数,做收尾工作

89行:aclrtSetDevice(0);

● 我的理解就是类似于下图(下图是我的猜想,并不来自于官方),一个板子上面有3块昇腾310B的芯片。上面的代码就是设置本线程(一个进程有一个主线程)使用索引为0的昇腾芯片

● 查看官方的device操作发现,aclrtGetDeviceCount函数可以获取Device的数量,我觉得如果有3个昇腾芯片,可能返回的是3。目前香橙派上面只有一个昇腾310B芯片,返回的就是1

hiascend.com/doc_center/source/zh/canncommercial/601/inferapplicationdev/aclcppdevg/aclcppdevg_03_0019.html

● 在线程的最后,要成对的使用aclrtResetDevice(0);函数,做收尾工作

90行:aclrtCreateContext(&g_context, 0);

● 香橙派上是昇腾310B芯片,昇腾310B芯片device中默认存在1个context,本程序中可创建也可不创建context

● 猜测context可能不是一个实体的内容,而是stream集合的一个概念,几个stream组成一个context

● 本程序就是在昇腾设备0上创建了一个context。创建好了以后,本线程就默认使用新创建的context。当前线程在同一时刻内只能使用其中一个Context

●  在线程的最后,要成对的使用aclrtDestroyContext(g_context);函数,做收尾工作

91行:aclrtCreateStream(&g_stream);

● 用于给当前context创建一个stream。上图昇腾310B芯片硬件资源最多支持1024个stream

● 一个stream可以用于执行一个任务,本案例中使用这个stream执行了图片裁剪指定区域的任务。多个stream可以用于同时执行多个任务

● 在线程的最后,要成对的使用aclrtDestroyStream(g_stream);函数,做收尾工作

92、93行:g_dvppChannelDesc = acldvppCreateChannelDesc();
acldvppCreateChannel(g_dvppChannelDesc);

● 这个是图片处理函数必须要的一个参数,在这里提前准备一下
acldvppVpcCropAsync(g_dvppChannelDesc, vpcInputDesc_, vpcOutputDesc_, cropArea_, g_stream);

94行:aclrtGetRunMode(&g_runMode);

● 获取当前程序的运行模式

ACL_DEVICE:昇腾AI软件栈运行在Device的Control CPU或板端环境上
ACL_HOST:昇腾AI软件栈运行在Host CPU上

如果是ACL_DEVICE,就代表当前程序是在AI CPU上运行的;如果是ACL_HOST,就代表当前程序是在CPU上运行的,如下图红色圆圈中写的那样

3.2 拷贝数据到NPU显存中

● 111行,通过ReadBinFile函数读取数据到内存中。如果程序是运行在CPU上,那么读取到的数据就放在运行内存上;如果程序是运行在昇腾芯片的AI CPU上,那么读取到的数据就放在昇腾芯片的内存,也就是显存上

● 114行,在显存上分配一段文件大小的内存。

● 115行,做判断。如果程序是运行在CPU上,就要把数据从运行内存上搬运到显存上;如果程序是运行在昇腾芯片的AI CPU上,那么就把数据从显存搬运到显存上(这里也可以不搬运,主要是为了后面写库的时候使用)

在运行内存上对应的就是HOST,到显存上对应的就是TO_DEVICE;在显存上对应的就是DEVICE,到显存上对应的就是TO_DEVICE。同理也可以HOST_TO_HOST,DEVICE_TO_HOST。

补充一下:如果程序运行在昇腾AI CPU上,想要在运行内存中分配内存,就需要使用aclrtMallocHost来申请内存

3.3 准备裁剪区域

上面分别生成了cropArea_,用于告诉下面的函数,输入图片要裁剪的范围

acldvppVpcCropAsync(g_dvppChannelDesc, vpcInputDesc_, vpcOutputDesc_, cropArea_, g_stream);

这里为什么减1呢,我猜测可能是因为DVPP主要应用于人工智能,少一行信息对人工智能来说是没影响的

3.3和3.4为什么要使用AlignmentHelper对输入和输出数据进行16位和2位对齐呢,这要看第四节讲的内容

3.4 准备输入输出描述符

● 143行,为什么输入的图片大小是这么计算的呢

首先是对齐后图片的宽高如下图,前面这部分很好理解:

● 后面的*3,是因为存储图片的是YUV 3个通道,这样就需要 对齐后的宽高*3得到需要的字节数,

● 那么为什么要除2呢?这是因为YUV本来YUV三个通道都应该有4个信息,也就是8bit来表示Y,8bit来表示U,8bit来表示V。YUV420图片,有8bit来表示Y,只有4bit来表述U,0bit来表示V,字节数自然就少了一半,所以要/2

3.5 收尾阶段

在图片处理的过程中,程序可以异步的去执行了,但是176行,我们任然阻塞的去等待图片处理结果。等到图片处理结束,就将输出的图片指针和大小传入181行的函数中,函数会将图片保存到picName指定的位置去

做完上面这些任务,就释放掉占用的资源

3.6 其他例程如何学习

把其他历程中的关键内容抽取出来,写成像上面那种形式的程序,多动手练习。自己依次分析函数的功能等。

上面代码过程分为这几步:初始化->读取要处理的图片->创建输入图片描述符->创建输出图片描述符->acl处理图片->把输出的图片保存->释放占用的资源

四、DVPP输入输出图片限制

4.1 裁剪的输入图片要求

官方文档:

hiascend.com/doc_center/source/zh/canncommercial/601/inferapplicationdev/aclcppdevg/aclcppdevg_03_0168.html#ZH-CN_TOPIC_0000001405674684__section17242141311416

输入图片有4个信息,图片宽度按照2字节对齐,高度按照2字节对齐。还有两个信息是按照宽16字节对齐,高2字节对齐输入进去的

4.2 裁剪的输出图片要求

直观的看一下,如果我们指定输出的图片宽高不是按照2字节对齐的,输出出来的图片对应的就是绿色

输出描述符中的图片宽高要求2字节对齐:

输出图片另外两个信息分别是,宽16字节对齐,高2字节对齐

4.3 输出图片的格式和宽高

经过上面一通运算,输出出来的yuv图片宽高是按照原图片,宽=原图片按16字节对齐,高=原图片按2字节对齐

最后输出的图片右边有黑边

4.4 对输出的图片进行处理

我不太会使用AIPP的工具,所以使用python对输出的图片进行处理

读取yuv格式图片,对它进行裁剪,再输出jpg格式图片。

所以,我们现在学习这个DVPP的目的是干嘛呢?opencv不是一样可以处理,当然是有原因的,DVPP是使用硬件加速,大量的运算都交给昇腾完成,我们的CPU只需要执行好自己的复杂任务。

import numpy as np
import cv2
import sysdef AlignmentHelper(origSize, alignment):alignmentH = alignment - 1return (origSize + alignmentH) // alignment * alignmentwidth = int(sys.argv[1])
height = int(sys.argv[2])
yuv_file = "./output/dvpp_rabbit_" + sys.argv[1] + "_" + sys.argv[2] + "_nv12.yuv"
alignment_width = AlignmentHelper(width, 16)
alignment_height = AlignmentHelper(height, 2)
yuv_file = open(yuv_file, "rb")frame_size = alignment_width * alignment_height * 3 // 2
data = yuv_file.read(frame_size)
yuv_image = np.frombuffer(data, dtype=np.uint8)
yuv_image = yuv_image.reshape((alignment_height*3//2, alignment_width))
bgr_image = cv2.cvtColor(yuv_image, cv2.COLOR_YUV2BGR_I420)patch_tree = bgr_image[0:width, 0:height]
cv2.imwrite("./output/dvpp_rabbit_" + sys.argv[1] + "_" + sys.argv[2] + "_nv12.jpg", patch_tree)

相关文章:

OrangePi AIpro学习3 —— vscode开发昇腾DVPP程序

目录 一、VScode配置 1.1 下载和安装 1.2 安装和配置需要的插件 二、构建项目 2.1 项目架构 2.2 解决代码高亮显示 2.3 测试编译 2.4 总结出最简单的代码 2.5 vscode报错找不到头文件解决方法 三、代码简单讲解 3.1 初始化部分 3.2 拷贝数据到NPU显存中 3.3 准备裁…...

redis的数据结构与对象

简单动态字符串 文章目录 简单动态字符串SDS的定义SDS的结构图示结构SDS字段解析SDS的特点 SDS和字符串的区别常数复杂度获取字符串的长度杜绝缓冲区的溢出减少修改字符串时的内存分配次数二进制安全兼容部分c字符串函数总结 链表链表和链表节点的实现链表节点&#xff08;list…...

ARM 汇编语言基础

目录 汇编指令代码框架 汇编指令语法格式 数据处理指令 数据搬移指令 mov 示例 立即数的本质 立即数的特点 立即数的使用 算术运算指令 指令格式 add 普通的加法指令 adc 带进位的加法指令 跳转指令 Load/Store指令 状态寄存器指令 基础概念 C 语言与汇编指令的关…...

c语言小知识点小计

c语言小知识点小计 1、运算符的优先级 运算符的优先级是和指针解引用*的优先级相同的&#xff0c;但在代码运行中执行顺序是从后往前的。因此下面代码 int a[10] {1,2,3,4}; int* arr a; printf("%d",*arr);//访问的值是2 //注意&#xff1a;printf("%d&qu…...

《C#面向语言版本编程》C# 13 中的新增功能

将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Studio 2022 版本或 .NET 9 预览版 SDK 尝试这些功能。若想在.NET项目中尝试使用C#的最新预览版特性&#xff0c;可以按照以下步骤来升级你的项目语言版本&#xff1a; .打开项目文件&#xff1a; 找…...

0成本通过Hugo和GitHub Pages搭建博客

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 使用 Chocolatey 安装 Hugo Chocolatey 是一个 Windows 软件包管理器&#xff0c;使用 PowerShell 和 NuGet 作为基础。它可以自动化软件的安装、升级和卸载过…...

Ollama 可以玩 GLM4和CodeGeeX4了

最近这一两周看到不少互联网公司都已经开始秋招提前批了。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友…...

浅析C++指针与引用的关系

前言&#xff1a; 在实践中指针与引用相辅相成&#xff0c;功能相互叠加&#xff0c;但各有各的特点&#xff0c;互相不可替代&#xff01;&#xff01;&#xff01;...

Python面试宝典第31题:字符串反转

题目 编写一个函数&#xff0c;其作用是将输入的字符串反转过来&#xff0c;输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组&#xff0c;并使用O(1)的额外空间解决这一问题。备注&#xff1a;s[i]都是ASCII码表中的可打印…...

【深入理解SpringCloud微服务】深入理解微服务中的远程调用,并手写一个微服务RPC框架

【深入理解SpringCloud微服务】深入理解微服务中的远程调用&#xff0c;并手写一个微服务RPC框架 远程过程调用微服务中的RPC框架如何实现一个微服务中的RPC框架接口扫描生成代理对象代理对象处理逻辑 手写一个微服务RPC框架RPCClientEnableRPCClientMicroServiceRPCClientRegi…...

数据结构----二叉树

小编会一直更新数据结构相关方面的知识&#xff0c;使用的语言是Java&#xff0c;但是其中的逻辑和思路并不影响&#xff0c;如果感兴趣可以关注合集。 希望大家看完之后可以自己去手敲实现一遍&#xff0c;同时在最后我也列出一些基本和经典的题目&#xff0c;可以尝试做一下。…...

通过python管理mysql

打开防火墙端口&#xff1a; 使用 firewall-cmd 命令在防火墙的 public 区域中永久添加 TCP 端口 7500&#xff08;FRP 控制台面板端口&#xff09;、7000&#xff08;FRP 服务端端口&#xff09;以及端口范围 6000-6100&#xff08;一组客户端端口&#xff09;。这些端口是 FR…...

Run the OnlyOffice Java Spring demo project in local

Content 1.Download the sample project in java2.Run the project3.Test the example document 1.Download the sample project in java Link: download the sample code in official website document properties setting spring 项目所在的服务器 server. Address192.168…...

11. Rancher2.X部署多案例镜像

**部署springboot项目 : ** **部署中间件Mysql8.0 : ** 名称&#xff1a;service-mysql 端口 &#xff1a;3306:3306 镜像&#xff1a;mysql:8.0 环境变量&#xff1a; MYSQL_ROOT_PASSWORDxdclass.net168路径映射 /home/data/mysql/data /var/lib/mysql:rw /etc/localtime…...

探索Linux世界之Linux环境开发工具的使用

目录 一、yum -- Linux软件包管理器 1、什么是yum 2、yum的使用 2.1 yum一些经常见的操作 1.查看软件包 2. 安装软件包 3. 删除软件包 3、yum的周边知识 3.1 yum的软件包都是从哪里来的&#xff1f;是从哪里能下载到这些软件包&#xff1f; 3.2 yum的拓展软件源 二、…...

探索Spring Boot微服务架构的最佳实践

目录 引言 一、Spring Boot简介 二、微服务架构的关键要素 三、Spring Boot在微服务中的最佳实践 3.1 清晰的服务边界 3.2 自动化配置与依赖管理 3.3 服务注册与发现 3.4 配置管理 3.5 安全与认证 3.6 监控与日志 3.7 分布式事务 四、总结 引言 在当今快速迭代的软…...

[论文泛读]zkLLM: Zero Knowledge Proofs for Large Language models

文章目录 介绍实验数据实验数据1实验数据2实验数据3 介绍 这篇文章发在CCS2024&#xff0c;CCS是密码学领域的顶会。作者是来自加拿大的University of Waterloo。文章对大语言模型像GPT和LLM等大语言模型实现了零知识可验证执行&#xff0c;但不涉及零知识可验证训练。个人觉得…...

vscode插件中的图标怎么设置

首先在ts文件目录下和package.json同级的目录下加入一张图片&#xff0c;后缀是jpg、png、jpeg都可以。 然后package.json中加入该行 重新 vsce package即可 如果出现报错 The specified icon xxx/xxx/icon.jpg wasnt found in the extension. 那就是没有放正确文件夹的位…...

Study--Oracle-08-oracle数据库的闪回技术

一、闪回恢复区(Flash Recovery Area) 1、什么是闪回恢复区 闪回恢复区是Oracle数据库中的一个特殊存储区域&#xff0c;用于集中存放备份和恢复数据库所需的所有文件&#xff0c;包括归档日志和闪回日志。这个区域可以帮助数据库在遇到介质故障时进行完全恢复。通过将备份数…...

获取客户端真实IP

出于安全考虑&#xff0c;近期在处理一个记录用户真实IP的需求。本来以为很简单&#xff0c;后来发现没有本来以为的简单。这里主要备忘下&#xff0c;如果服务器处于端口回流&#xff08;hairpin NAT&#xff09;,keepalived&#xff0c;nginx之后&#xff0c;如何取得客户端的…...

韩式告白土味情话-柯桥生活韩语学习零基础入门教学

你们韩国人别太会告白了&#xff01; 1、너 얼굴에 뭐가 조금 묻었어! 你的脸上有点5376东西&#xff01; 뭐가 조금 묻었1585757는데? 有点什么&#xff1f; 이쁨이 조금 묻었네. 有点漂亮。 2、돌잡이 때 뭐 잡았어요&#xff1f; 你抓周的时候抓了什么&#xff1f; 쌀 잡았…...

Linux安全与高级应用(一)深入探讨Linux安全与高级应用

文章目录 深入探讨Linux安全与高级应用引言目录一、Linux安全与应用概述1.1 Linux的应用现状1.2 Linux的安全需求 二、构建LAMP企业网站平台2.1 LAMP平台简介2.2 安装和配置Apache服务器2.2.1 安装Apache2.2.2 配置Apache 2.3 安装和管理MySQL数据库2.3.1 安装MySQL2.3.2 配置M…...

【nginx 第二篇章】各个环境安装 nginx

一、Windows环境安装 1、下载 Nginx 访问Nginx官网&#xff08;http://nginx.org/en/download.html&#xff09;下载稳定版本的 Nginx 压缩包&#xff0c;如 nginx-1.xx.x.zip。下载后解压到指定的目录&#xff0c;例如 D:\nginx。 2、启动 Nginx 直接双击解压目录下的 ngi…...

在Spring Boot和MyBatis-Plus项目中,常见的错误及其解决方法2.0

1. org.springframework.beans.factory.BeanCreationException: Error creating bean with name requestMappingHandlerMapping 现象 在创建bean时发生错误&#xff0c;通常是因为存在重复的URL映射。 解决方法 检查所有控制器方法上的URL映射注解&#xff0c;确保没有重复…...

招聘信息数据清洗

文章目录 前言代码示例如下 前言 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 1.Spark 清洗数据的相关方法, 2.空值列怎么删除&#xff1b; 3.怎么数据切分才能达到想要的数据。 Spark清洗数据相关方法 一、将含有空值的数据删除 1.将含有空值的数据删除&a…...

机器学习——支持向量机(SVM)(1)

目录 一、认识SVM 1. 基本介绍 2. 支持向量机分类器目标 二、线性SVM分类原理&#xff08;求解损失&#xff09; 三、重要参数 1. kernel&#xff08;核函数&#xff09; 2 .C&#xff08;硬间隔与软间隔&#xff09; 四、sklearn中的支持向量机&#xff08;自查&#…...

Elastic Observability 8.15:AI 助手、OTel 和日志质量增强功能

作者&#xff1a;来自 Elastic Alex Fedotyev, Tom Grabowski, Vinay Chandrasekhar, Miguel Luna Elastic Observability 8.15 宣布了几个关键功能&#xff1a; 新的和增强的原生 OpenTelemetry 功能&#xff1a; OpenTelemetry Collector 的 Elastic 分发&#xff1a;此版本…...

Unity3D ECS架构的优缺点详解

前言 Unity3D作为一款强大的游戏开发引擎&#xff0c;近年来在性能优化和架构设计上不断进化&#xff0c;其中ECS&#xff08;Entity-Component-System&#xff09;架构的引入是其重要的里程碑之一。ECS架构通过重新定义游戏对象的组织和处理方式&#xff0c;为开发者带来了诸…...

理解Go语言中多种并发模式

Go 的同步原语使实现高效的并发程序成为可能,并且选择合适的同步原语和并发模式可以更加容易地实现并发的可能,减少错误的发生。这里谈论的并发模式是只在 Go 语言中常见的并发的“套路” ,一种可解决某一类通用场景和问题的惯用方法。 1. 并发模式概述 我们先来回顾下同步…...

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出03:文件模式:二进制文件

系列文章目录 17.4.5 文件模式 程序清单17.18 append.cpp 程序清单17.19 binary.cpp 文章目录 系列文章目录17.4.5 文件模式程序清单17.18 append.cpp程序清单17.19 binary.cpp17.4.5 文件模式1.追加文件来看一个在文件尾追加数据的程序。程序清单17.18 append.cpp2.二进制文…...