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

TensorRT学习笔记--常用卷积、激活、池化和FC层算子API

目录

1--Tensor算子API

1-1--卷积算子

1-2--激活算子

1-3--池化算子

1-4--FC层算子

2--代码实例

3--编译运行


1--Tensor算子API

TensorRT提供了卷积层、激活函数和池化层三种最常用算子的API:

// 创建一个空的网络
nvinfer1::INetworkDefinition* network = builder->createNetworkV2(0U); // 添加卷积层算子
nvinfer1::IConvolutionLayer* conv1 = network->addConvolutionNd(*data, 64, nvinfer1::DimsHW{3, 3}, weightMap["features.0.weight"], weightMap["features.0.bias"]);// 添加激活算子
nvinfer1::IActivationLayer* relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);// 添加池化算子
nvinfer1::IPoolingLayer* pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});

1-1--卷积算子

IConvolutionLayer* addConvolutionNd(ITensor& input, int32_t nbOutputMaps, Dims kernelSize, Weights kernelWeights, Weights biasWeights
)

第一个参数表示输入的Tensor数据;

第二个参数表示卷积层输出的特征图数,即通道数channel;

第三个参数表示使用的卷积核大小;

第四个参数和第五个参数表示加载的权重;

1-2--激活算子

IActivationLayer* addActivation(ITensor& input, ActivationType type
)

第一个参数表示输入的Tensor数据;

第二个参数表示使用的激活函数类型,包括以下激活函数:

enum class ActivationType : int32_t
{kRELU = 0,             //!< Rectified linear activation.kSIGMOID = 1,          //!< Sigmoid activation.kTANH = 2,             //!< TanH activation.kLEAKY_RELU = 3,       //!< LeakyRelu activation: x>=0 ? x : alpha * x.kELU = 4,              //!< Elu activation: x>=0 ? x : alpha * (exp(x) - 1).kSELU = 5,             //!< Selu activation: x>0 ? beta * x : beta * (alpha*exp(x) - alpha)kSOFTSIGN = 6,         //!< Softsign activation: x / (1+|x|)kSOFTPLUS = 7,         //!< Parametric softplus activation: alpha*log(exp(beta*x)+1)kCLIP = 8,             //!< Clip activation: max(alpha, min(beta, x))kHARD_SIGMOID = 9,     //!< Hard sigmoid activation: max(0, min(1, alpha*x+beta))kSCALED_TANH = 10,     //!< Scaled tanh activation: alpha*tanh(beta*x)kTHRESHOLDED_RELU = 11 //!< Thresholded ReLU activation: x>alpha ? x : 0
};

1-3--池化算子

IPoolingLayer* addPoolingNd(ITensor& input, PoolingType type, Dims windowSize
)

第一个参数表示输入的Tensor数据;

第二个参数表示使用的池化类型;

第三个参数表示池化窗口的大小;

提供的池化类型包括:

enum class PoolingType : int32_t
{kMAX = 0,              // Maximum over elementskAVERAGE = 1,          // Average over elements. If the tensor is padded, the count includes the paddingkMAX_AVERAGE_BLEND = 2 // Blending between max and average pooling: (1-blendFactor)*maxPool + blendFactor*avgPool
};

1-4--FC层算子

IFullyConnectedLayer* addFullyConnected(ITensor& input, int32_t nbOutputs, Weights kernelWeights, Weights biasWeights
)

第一个参数表示输入的Tensor数据;

第二个参数表示输出的通道数;

第三个参数和第四个参数表示加载的权重;

2--代码实例

基于算子 API 搭建 VGG11:(完整可运行的代码参考:liujf69/TensorRT-Demo)

核心程序代码:

// 创建builder和config
nvinfer1::IBuilder* builder = nvinfer1::createInferBuilder(gLogger);
nvinfer1::IBuilderConfig* config = builder->createBuilderConfig();// 基于builder创建network
nvinfer1::INetworkDefinition* network = builder->createNetworkV2(0U); // 一开始是空的// 调用API搭建Network
// 创建输入
nvinfer1::ITensor* data = network->addInput(this->INPUT_BLOB_NAME, dt, nvinfer1::Dims3{3, this->INPUT_H, this->INPUT_W});
// 搭建卷积层
nvinfer1::IConvolutionLayer* conv1 = network->addConvolutionNd(*data, 64, nvinfer1::DimsHW{3, 3}, weightMap["features.0.weight"], weightMap["features.0.bias"]);
conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});
// 搭建激活层
nvinfer1::IActivationLayer* relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);
// 搭建池化层
nvinfer1::IPoolingLayer* pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});
pool1->setStrideNd(nvinfer1::DimsHW{2, 2});
...
// 搭建FC层
nvinfer1::IFullyConnectedLayer* fc1 = network->addFullyConnected(*pool1->getOutput(0), 4096, weightMap["classifier.0.weight"], weightMap["classifier.0.bias"]);
...// 基于config和network生成engine
builder->setMaxBatchSize(maxBatchSize);
config->setMaxWorkspaceSize(1 << 20);
nvinfer1::ICudaEngine* engine = builder->buildEngineWithConfig(*network, *config);
...

主程序代码:

#include "NvInfer.h"
#include "cuda_runtime_api.h"
#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <chrono>
#include "logging.h"
#include <iostream>#define CHECK(status) \do\{\auto ret = (status);\if (ret != 0)\{\std::cerr << "Cuda failure: " << ret << std::endl;\abort();\}\} while (0)static Logger gLogger; // 日志class VGG_Demo{
public:VGG_Demo(){this->prob = new float[OUTPUT_SIZE];}~VGG_Demo(){delete[] prob;}int serialize();void APIToModel(unsigned int maxBatchSize, nvinfer1::IHostMemory** modelStream);nvinfer1::ICudaEngine* createEngine(unsigned int maxBatchSize, nvinfer1::IBuilder* builder, nvinfer1::IBuilderConfig* config, nvinfer1::DataType dt);std::map<std::string, nvinfer1::Weights> loadWeights(const std::string file);void doInference(nvinfer1::IExecutionContext& context, float* input, float* output, int batchSize);void deserialize(float* data);void load_engine();const char* INPUT_BLOB_NAME = "data"; // 输入名称const char* OUTPUT_BLOB_NAME = "prob"; // 输出名称const int INPUT_H = 224; // 输入数据高度const int INPUT_W = 224; // 输入数据宽度const int OUTPUT_SIZE = 1000; // 输出大小std::string engine_file = "./vgg.engine";char* trtModelStream = nullptr;float* prob = nullptr;size_t size = 0;
};int VGG_Demo::serialize(){nvinfer1::IHostMemory* modelStream  = nullptr;this->APIToModel(1, &modelStream); // 调用API构建networkassert(modelStream != nullptr);// 保存std::ofstream p("./vgg.engine", std::ios::binary);if (!p) {std::cerr << "could not open plan output file" << std::endl;return -1;}p.write(reinterpret_cast<const char*>(modelStream->data()), modelStream->size());modelStream->destroy();return 1;
}void VGG_Demo::APIToModel(unsigned int maxBatchSize, nvinfer1::IHostMemory** modelStream){// 创建builder和confignvinfer1::IBuilder* builder = nvinfer1::createInferBuilder(gLogger);nvinfer1::IBuilderConfig* config = builder->createBuilderConfig();nvinfer1::ICudaEngine* engine = this->createEngine(maxBatchSize, builder, config, nvinfer1::DataType::kFLOAT);assert(engine != nullptr);// 序列化*modelStream = engine->serialize();// 销毁engine->destroy();builder->destroy();config->destroy();
}nvinfer1::ICudaEngine* VGG_Demo::createEngine(unsigned int maxBatchSize, nvinfer1::IBuilder* builder, nvinfer1::IBuilderConfig* config, nvinfer1::DataType dt){// 加载权重std::map<std::string, nvinfer1::Weights> weightMap = loadWeights("../weights/vgg.wts");nvinfer1::Weights emptywts{nvinfer1::DataType::kFLOAT, nullptr, 0};nvinfer1::INetworkDefinition* network = builder->createNetworkV2(0U); // 创建一个空的networknvinfer1::ITensor* data = network->addInput(this->INPUT_BLOB_NAME, dt, nvinfer1::Dims3{3, this->INPUT_H, this->INPUT_W}); // 创建输入assert(data);// 使用卷积、激活和池化三种算子,按顺序连接三种算子,并用对应的权重初始化nvinfer1::IConvolutionLayer* conv1 = network->addConvolutionNd(*data, 64, nvinfer1::DimsHW{3, 3}, weightMap["features.0.weight"], weightMap["features.0.bias"]);assert(conv1);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});nvinfer1::IActivationLayer* relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);assert(relu1);nvinfer1::IPoolingLayer* pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});assert(pool1);pool1->setStrideNd(nvinfer1::DimsHW{2, 2});conv1 = network->addConvolutionNd(*pool1->getOutput(0), 128, nvinfer1::DimsHW{3, 3}, weightMap["features.3.weight"], weightMap["features.3.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});pool1->setStrideNd(nvinfer1::DimsHW{2, 2});conv1 = network->addConvolutionNd(*pool1->getOutput(0), 256, nvinfer1::DimsHW{3, 3}, weightMap["features.6.weight"], weightMap["features.6.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);conv1 = network->addConvolutionNd(*relu1->getOutput(0), 256, nvinfer1::DimsHW{3, 3}, weightMap["features.8.weight"], weightMap["features.8.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});pool1->setStrideNd(nvinfer1::DimsHW{2, 2});conv1 = network->addConvolutionNd(*pool1->getOutput(0), 512, nvinfer1::DimsHW{3, 3}, weightMap["features.11.weight"], weightMap["features.11.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);conv1 = network->addConvolutionNd(*relu1->getOutput(0), 512, nvinfer1::DimsHW{3, 3}, weightMap["features.13.weight"], weightMap["features.13.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});pool1->setStrideNd(nvinfer1::DimsHW{2, 2});conv1 = network->addConvolutionNd(*pool1->getOutput(0), 512, nvinfer1::DimsHW{3, 3}, weightMap["features.16.weight"], weightMap["features.16.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);conv1 = network->addConvolutionNd(*relu1->getOutput(0), 512, nvinfer1::DimsHW{3, 3}, weightMap["features.18.weight"], weightMap["features.18.bias"]);conv1->setPaddingNd(nvinfer1::DimsHW{1, 1});relu1 = network->addActivation(*conv1->getOutput(0), nvinfer1::ActivationType::kRELU);pool1 = network->addPoolingNd(*relu1->getOutput(0), nvinfer1::PoolingType::kMAX, nvinfer1::DimsHW{2, 2});pool1->setStrideNd(nvinfer1::DimsHW{2, 2});// 使用全连接层算子nvinfer1::IFullyConnectedLayer* fc1 = network->addFullyConnected(*pool1->getOutput(0), 4096, weightMap["classifier.0.weight"], weightMap["classifier.0.bias"]);assert(fc1);relu1 = network->addActivation(*fc1->getOutput(0), nvinfer1::ActivationType::kRELU);fc1 = network->addFullyConnected(*relu1->getOutput(0), 4096, weightMap["classifier.3.weight"], weightMap["classifier.3.bias"]);relu1 = network->addActivation(*fc1->getOutput(0), nvinfer1::ActivationType::kRELU);fc1 = network->addFullyConnected(*relu1->getOutput(0), 1000, weightMap["classifier.6.weight"], weightMap["classifier.6.bias"]);fc1->getOutput(0)->setName(OUTPUT_BLOB_NAME); // 设置输出名称network->markOutput(*fc1->getOutput(0)); // 标记输出// 生成enginebuilder->setMaxBatchSize(maxBatchSize);config->setMaxWorkspaceSize(1 << 20);nvinfer1::ICudaEngine* engine = builder->buildEngineWithConfig(*network, *config);std::cout << "build out" << std::endl;// 生成engine后释放networknetwork->destroy();// 释放权重内存for (auto& mem : weightMap) free((void*) (mem.second.values)); return engine;
}std::map<std::string, nvinfer1::Weights> VGG_Demo::loadWeights(const std::string file){std::cout << "Loading weights: " << file << std::endl;std::map<std::string, nvinfer1::Weights> weightMap; // 权重名称和权重类的哈希表std::ifstream input(file);assert(input.is_open() && "Unable to load weight file.");// 首先读取权重block的个数int32_t count;input >> count;assert(count > 0 && "Invalid weight map file.");// 遍历权重blockwhile (count--){nvinfer1::Weights wt{nvinfer1::DataType::kFLOAT, nullptr, 0}; // 初始化一个权重对象uint32_t size;// Read name and type of blobstd::string name;input >> name >> std::dec >> size; // std::dec表示使用十进制表示权重的sizewt.type = nvinfer1::DataType::kFLOAT; // 设置权重的类型// 拷贝权重值uint32_t* val = reinterpret_cast<uint32_t*>(malloc(sizeof(val) * size));for (uint32_t x = 0, y = size; x < y; ++x){ // 拷贝size大小input >> std::hex >> val[x];}// 完成哈希映射wt.values = val;wt.count = size;weightMap[name] = wt;}return weightMap;
}void VGG_Demo::deserialize(float* data){load_engine(); // 加载enginenvinfer1::IRuntime* runtime = nvinfer1::createInferRuntime(gLogger);assert(runtime != nullptr);nvinfer1::ICudaEngine* engine = runtime->deserializeCudaEngine(this->trtModelStream, this->size);assert(engine != nullptr);nvinfer1::IExecutionContext* context = engine->createExecutionContext();assert(context != nullptr);delete[] this->trtModelStream; // 手动释放trtModelStream// 执行推理for (int i = 0; i < 10; i++){ // 记录推理10次的时间auto start = std::chrono::system_clock::now();doInference(*context, data, this->prob, 1);auto end = std::chrono::system_clock::now();std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms" << std::endl;}// 销毁context->destroy();engine->destroy();runtime->destroy();// 打印推理结果std::cout << "\nOutput:\n\n";for (unsigned int i = 0; i < 10; i++){ // 打印10个std::cout << this->prob[i] << ", ";if (i % 10 == 0) std::cout << i / 10 << std::endl;}std::cout << std::endl;
}void VGG_Demo::load_engine(){std::ifstream file(this->engine_file, std::ios::binary);if(file.good()){file.seekg(0, file.end);this->size = file.tellg();file.seekg(0, file.beg);this->trtModelStream = new char[size];assert(this->trtModelStream);file.read(this->trtModelStream, size);file.close();}
}void VGG_Demo::doInference(nvinfer1::IExecutionContext& context, float* input, float* output, int batchSize){const nvinfer1::ICudaEngine& engine = context.getEngine();assert(engine.getNbBindings() == 2);void* buffers[2];const int inputIndex = engine.getBindingIndex(this->INPUT_BLOB_NAME);const int outputIndex = engine.getBindingIndex(this->OUTPUT_BLOB_NAME);CHECK(cudaMalloc(&buffers[inputIndex], batchSize * 3 * this->INPUT_H * this->INPUT_W * sizeof(float)));CHECK(cudaMalloc(&buffers[outputIndex], batchSize * this->OUTPUT_SIZE * sizeof(float)));// 创建streamcudaStream_t stream;CHECK(cudaStreamCreate(&stream));// Host to deviceCHECK(cudaMemcpyAsync(buffers[inputIndex], input, batchSize * 3 * INPUT_H * INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream));context.enqueue(batchSize, buffers, stream, nullptr);// device to hostCHECK(cudaMemcpyAsync(output, buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost, stream));cudaStreamSynchronize(stream);// 释放cudaStreamDestroy(stream);CHECK(cudaFree(buffers[inputIndex]));CHECK(cudaFree(buffers[outputIndex]));
}int main(int argc, char** argv){// 判断参数是否准确if(argc != 2){std::cerr << "arguments not right!" << std::endl;std::cerr << "./vgg_demo -s   // serialize model to plan file" << std::endl;std::cerr << "./vgg_demo -d   // deserialize plan file and run inference" << std::endl;return -1;}VGG_Demo vgg_demo1;if(std::string(argv[1]) == "-s"){ // 序列化vgg_demo1.serialize();}else if(std::string(argv[1]) == "-d"){ // 反序列化并推理// 生成测试数据float data[3 * 224 * 224];for (int i = 0; i < 3 * 224 * 224; i++) data[i] = 1;vgg_demo1.deserialize(data);}else{std::cerr << "wrong arguments!" << std::endl;;return -1;}return 0;
}

3--编译运行

mkdir build && cd build
cmake ..
make ./vgg_demo -s
./vgg_demo -d

相关文章:

TensorRT学习笔记--常用卷积、激活、池化和FC层算子API

目录 1--Tensor算子API 1-1--卷积算子 1-2--激活算子 1-3--池化算子 1-4--FC层算子 2--代码实例 3--编译运行 1--Tensor算子API TensorRT提供了卷积层、激活函数和池化层三种最常用算子的API&#xff1a; // 创建一个空的网络 nvinfer1::INetworkDefinition* network …...

【Edabit 算法 ★☆☆☆☆☆】 Less Than 100?

【Edabit 算法 ★☆☆☆☆☆】 Less Than 100? language_fundamentals math validation Instructions Given two numbers, return true if the sum of both numbers is less than 100. Otherwise return false. Examples lessThan100(22, 15) // true // 22 15 37lessTha…...

C++中的智能指针:更安全、更便利的内存管理

在C++编程中,动态内存管理一直是一个重要且具有挑战性的任务。传统的C++中,程序员需要手动分配和释放内存,这往往会导致内存泄漏和悬挂指针等严重问题。为了解决这些问题,C++11引入了智能指针(Smart Pointers)这一概念,它们是一种高级的内存管理工具,可以自动管理内存的…...

google登录k8s dashboard ui显示“您的连接不是私密连接”问题解决梳理

1.问题描述 OS Version:CentOS Linux release 7.9.2009 (Core) K8S Version:Kubernetes v1.20.4 k8s dashboard ui安装完毕后&#xff0c;通过google浏览器登录返现https网页&#xff0c;发现非官方的https网页无法打开 网址&#xff1a;https://192.168.10.236:31001 2.原…...

MIPS指令集摘要

目录 MIPS指令R I J三种格式 MIPS五种寻址方式 立即数寻址 寄存器寻址 基址寻址 PC相对寻址 伪直接寻址 WinMIPS64汇编指令 助记 从内存中加载数据 lb lbu lh lhu lw lwu ld l.d lui 存储数据到内存 sb sh sw sd s.d 算术运算 daddi daddui dadd…...

数据可视化素材分享 | 数十图表、无数模板

很多人在后台求分享报表、源代码&#xff0c;其实何必这么麻烦&#xff0c;在奥威BI数据可视化平台上点击即可获得大量的可视化素材&#xff0c;如数十种可视化图表&#xff0c;适用于不同分析场景&#xff1b;又如大量不同主题的BI数据可视化报表模板&#xff0c;套用后替换数…...

Hadoop3教程(三十二):(生产调优篇)NameNode故障恢复与集群的安全模式

文章目录 &#xff08;159&#xff09;NameNode故障处理&#xff08;160&#xff09;集群安全模式&磁盘修复集群安全模式磁盘修复等待安全模式 参考文献 &#xff08;159&#xff09;NameNode故障处理 如果NameNode进程挂了并且存储的数据也丢失了&#xff0c;如何恢复Nam…...

uniapp下载附件保存到手机(文件、图片)ios兼容

downloadFile(file)&#xff0c;其中file为下载的文件地址uni.downloadFile图片使用uni.saveImageToPhotosAlbum【安卓、ios都合适】文件使用uni.openDocument【安卓图片也可以用这个&#xff0c;ios会失败】 // 下载文件 export function downloadFile(file) {let acceptArr …...

【Edabit 算法 ★☆☆☆☆☆】 Basketball Points

【Edabit 算法 ★☆☆☆☆☆】 Basketball Points language_fundamentals math numbers Instructions You are counting points for a basketball game, given the amount of 2-pointers scored and 3-pointers scored, find the final points for the team and return that …...

Web攻防04_MySQL注入_盲注

文章目录 MYSQL-SQL操作-增删改查盲注概念盲注分类盲注语句参考&更多盲注语句/函数 注入条件-数据回显&错误处理PHP开发项目-注入相关条件&#xff1a;基于延时&#xff1a;基于布尔&#xff1a;基于报错&#xff1a; CMS案例-插入报错&删除延时-PHP&MYSQL1、x…...

Flask自定义装饰和g的使用

1. 在commons.py文件中新增一个装饰器类: 注&#xff1a;一定要加入wraps进行装饰否则&#xff0c;装饰器在给多个函数进行装饰时会报错 from functools import wraps from flask import session, current_app, g# 定义登陆装饰器&#xff0c;封装用户的登陆数据 def user_log…...

【汇编】汇编语言基础知识(学习笔记)

一、汇编语言概述 汇编语言是直接在硬件之上工作的编程语言&#xff0c;首先要了解硬件奈统的结构&#xff0c;才能有效的应用汇编语言对其编程。 二、汇编语言的产生 机器语言&#xff1a;机器语言是机器指令的集合 汇编语言的主体是汇编指令 汇编指令和机器指令的差别在…...

前端 | FormData 用法详解

前端 | FormData 用法详解 介绍 ​FormData 是 Ajax2.0 对象用以将数据编译成键值对&#xff0c;以便于 XMLHttpRequest 来发送数据。XMLHttpRequest Level 2 提供的一个接口对象&#xff0c;可以使用该对象来模拟和处理表单并方便的进行文件上传操作 ​ 如果表单属性设为 mu…...

linux常见命令-文件目录类

9.4 文件目录类 &#xff08;1&#xff09;pwd 指令:显示当前工作目录的绝对路径 &#xff08;2&#xff09;Is指令:查看当前目录的所有内容信息 基本语法&#xff1a; ls [选项,可选多个] [目录或是文件] 常用选项:-a:显示当前目录所有的文件和目录&#xff0c;包括隐藏的…...

2023 10月8日 至 10 月16日学习总结

1.做的题目 [RootersCTF2019]I_&#xff1c;3_Flask_双层小牛堡的博客-CSDN博客 [NCTF2019]SQLi regexp 盲注-CSDN博客 [网鼎杯 2018]Comment git泄露 / 恢复 二次注入 .DS_Store bash_history文件查看-CSDN博客 PHP LFI 利用临时文件Getshell_双层小牛堡的博客-CSDN博客 …...

【Java 进阶篇】深入了解 Bootstrap 表格和菜单

表格和菜单是网页设计中的重要组成部分&#xff0c;它们用于展示数据、导航和用户交互。Bootstrap 是一个强大的前端框架&#xff0c;提供了丰富的表格样式和菜单组件&#xff0c;使开发者能够轻松创建功能丰富的网页。在本文中&#xff0c;我们将深入探讨 Bootstrap 中表格和菜…...

java的for循环中遇到异常抛出后继续循环执行

java的for循环中遇到异常抛出后继续循环执行 Test public void loopTryCatchTest() throws Exception {Map<String, Object> a new HashMap();a.put("a", "1");a.put("b", null);a.put("c", "3");for (Map.Entry<…...

【Javascript】构造函数之new的作用

目录 new的作用 把对象返回了回来 无new 有new 把构造函数的this指向了要返回的对象 无new​编辑 有new new的执行流程 new的作用 创建了新空对象将构造函数的作用域赋值给新对象(this指向新对象)执行构造函数代码 &#xff08;为这个新对象添加属性&#xff09;返回新对…...

粘包和半包问题及解决办法

粘包问题是指数据在传输时&#xff0c;在一条消息中读取到了另一条消息的部分数据&#xff0c;这种现象就叫做粘包。 半包问题是指数据在传输时&#xff0c;接收端只收到了部分数据&#xff0c;而非完整的数据&#xff0c;就叫做半包。 产生粘包和半包问题原因&#xff1a; …...

MySQL数据库查询实战操作

前置条件: 创建库:MySQL基本操作之创建数据库-CSDN博客 创建表:MySQL基本操作之创建数据表-CSDN博客 目录 常规查询常用函数union查询一、常规查询 1、查询所有姓名以 "张" 开头的学生: SELECT * FROM student WHERE name LIKE 张%; 这条语句使用 LIKE 运算…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...