深入浅出:深度学习模型部署全流程详解
- 博主简介:努力学习的22级计算机科学与技术本科生一枚🌸
- 博主主页: @Yaoyao2024
- 往期回顾: 【论文精读】PSAD:小样本部件分割揭示工业异常检测的合成逻辑
- 每日一言🌼: 生活要有所期待, 否则就如同罩在玻璃瓶子里的苍蝇, 每天只忙碌地嗡嗡地飞来飞去, 却不清楚这一切的意义何在。—— 郭城《人间行走:向着通透与自由》
0、前言:
在我大二,参与了一个较为完整的机器学习的目标检测项目,在这个过程中,我陆陆续续写了以下博客,目的是记录我在这个过程中所学习到的知识和技术。
🌸部署和系统开发系列文章
- QT C++实现点击按键弹出窗口并显示图片/视频|多窗口应用程序的设计和开发
- QT C++实战:实现用户登录页面及多个界面跳转
- QT C++实践|超详细数据库的连接和增删改查操作|附源码
- 【yolov8部署实战】VS2019+OpenCV环境部署yolov8目标检测模型|含详细注释源码
- 【yolov8部署实战】VS2019环境下使用Onnxruntime环境部署yolov8目标检测|含源码
- 【yolov8部署实战】VS2019+Onnxruntime环境部署yolov8-seg分割模型|含详细注释源码
- QT C++实践| 连接数据库的登录界面实现| 附源码
- VS2019下打包QT项目的方法(包含第三方库)、打包成一个 exe 安装包
本篇文章的目的,是对整个AI模型生产和AI系统开发做一个较为宏观和整体介绍和讲解。博主本人也只是初学者,若文章有不恰当和错误的地方,恳请指出!万分感谢!
一、AI 模型生产流程过程
生产一个具体的AI模型都会有哪些步骤呢?我们以一个具体例子来串起整个过程。我希望能达到的目的是:输入一张影视明星的图片,可以帮我输出这个明星的名字。
而AI模型生产流程可以分为一下6个步骤:
相信大家对前四个步骤都是很熟悉了:从确定项目需求,到收集数据,到选择or设计模型到模型的训练。
而在部署的前一个步骤:模型选择和训练,我们都是在pycharm/远程服务器上进行的,我们编写python代码,在一定环境上运行和测试。
Tips:本篇文章的背景是我们在Windows操作系统下,使用开发工具(pycharm/vs code等)进行模型的训练。
这篇文章我们着重讲解的是:模型的部署和系统的开发 。
我知道你们可能想问为什么呢?在IDE上运行出来结果不就可以了吗?为什么要进行后续这么多“复杂”的操作呢?其实不是这样的。下面我将对模型的部署的各个步骤进行讲解:
-
模型格式转换:
首先研究员通过各种训练框架训练好的模型一般都需要进行模型格式适配。模型训练大家可以选择各种不同的训练框架,例如TensorFlow,Pytorch,PaddlePaddle,Caffe等等一系列的开源框架,这么多不同的训练框架他们训练出来的模型格式都有各自的标准,各不相同,部署要解决的第一个问题就是要适配各种不同的模型格式。但是如果要一个个训练框架去适配格式,工作量太大,也不适合扩展,所以微软联合Facebook等大厂推出一种中间格式ONNX,希望能解决多种模型格式适配的问题,就是无论是什么训练框架训练出来的模型格式,最终都是用ONNX格式来进行部署。所以一般模型部署可以跑的第一步要解决的问题就是模型格式转换。 -
模型压缩:
模型压缩是对已经训练好的深度模型进行精简,进而得到一个轻量且准确率相当的网络,压缩后的网络具有更小的结构和更少的参数,可以有效降低计算和存储开销,便于部署在受限的硬件环境中。 训练的时候因为要保证前后向传播,每次梯度的更新是很微小的,这个时候需要相对较高的精度,一般来说需要float型,如FP32,32位的浮点型来处理数据,但是在推理(Inference)的时候,对精度的要求没有那么高,很多研究表明可以用低精度,如半长(16)的float型,即FP16,也可以用8位的整型(INT8)来做推理(Inference)。所以,一般来说,在模型部署时会对模型进行压缩。模型压缩方法有:蒸馏,剪枝,量化等。⭐Tips:在我部署的模型,由于时间原因,其实并没有对模型进行剪枝,这其实导致模型结构大,参数多,效率并不是很高,这其实也是有待优化的一点。
-
模型推理和前后处理
- 前处理:因为模型推理的输入是Tensor(多维矩阵)数据,但是正常AI应用的输入都是图片,视频,文字等数据,所以前处理就是要将业务的输入数据(图像,视频,文字等)预先处理成模型推理可以接收的数据—Tensor(多维矩阵)。以图像处理为例,前处理动作就包括但不限于:图像格式转换,颜色空间变换,图像变换(resize,warpaffine(仿射变换)),图像滤波等操作。OpenCV就是intel推出开源的跨平台的计算机视觉库。
Tips:在后续我们部署的过程中,主要也就是利用OpenCV库进行的。
- 模型推理:模型推理应该是模型部署pipline中最核心的部分。就是需要在实际应用环境中(具体部署设备)将实际输入的数据(转换成Tensor数据后)在训练好的模型中跑通,并且性能和精度等商业指标上达到预期效果。这个过程包括了对部署设备的适配(CPU/GPU/DSP/NPU),要想将模型跑在任何一种设备上,都需要提前针对设备进行适配,并且还要保证性能和精度等指标。这是个非常复杂的过程。
市面上有非常多的开源深度学习推理框架都是在解决模型推理相关的问题。例如:国内各大厂推出的开源的推理框架:OpenPPL、NCNN、TNN、MNN、PaddleLite、Tengine等等,还有NVIDIA推出的针对GPU卡的TensorRT、intel针对intel芯片的OpenVINO等。 - 后处理:就是将模型推理后的Tensor数据转换成业务可以识别的特征数据(不同的业务会呈现不同的最终效果数据)。
总结下:模型推理和前后处理的流程:
- step1:PreProcess(Image -> Tensor)
- step2:NN Forword/Inference(Input Tensor -> Output Tensor)
- step3:PostProcess(Output Tensor -> Annotation Data)。
⭐Tips:其实在我个人实现的项目中,并没有自己设计推理的代码,大部分根据该模型对应的
c++
版本稍加修改(这个要看其官网或者民间有没有高手自己手写c++版本的上述推理),这点可以看我写的这几个博客:
- 【yolov8部署实战】VS2019+OpenCV环境部署yolov8目标检测模型|含详细注释源码
- 【yolov8部署实战】VS2019环境下使用Onnxruntime环境部署yolov8目标检测|含源码
- 【yolov8部署实战】VS2019+Onnxruntime环境部署yolov8-seg分割模型|含详细注释源码
- 部署 SDK 和集成
- 部署SDK:需要模型推理和前后处理功能打包,并考虑实际应用中的license、模型安全(加解密)等功能实现,最终输入一个业务方方便使用的部署SDK。
这是一种单机模式的部署,现在大型模型部署和公有云部署可能是另一种形式。
SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”。这是一个覆盖面相当广泛的名词,可以这么说:辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”。具体到我们这个系列教程,我们后面只讨论广义 SDK 的一个子集——即开发 Windows 平台下的应用程序所使用的 SDK。 为了解释什么是 SDK 我们不得不引入 API、动态链接库、导入库等等概念,详细可以看这篇文章:什么是SDK? SDK是什么意思?。
- 集成:由具体的业务方工程化的同学去实现,将部署SDK集成到具体的应用中,根据实际业务需要通过接口调用,最终达到实际应用AI的效果。例如:上述例子中,具体是要将部署SDK集成进手机端还是pc端,是通过app来实现还是小程序来实现,最终效果如何展示,这些都是集成部分具体业务同学去实现。
- 部署SDK:需要模型推理和前后处理功能打包,并考虑实际应用中的license、模型安全(加解密)等功能实现,最终输入一个业务方方便使用的部署SDK。
⭐Tips:在我使用的部署和集成方法中,我首先在Windows操作系统的C++开发平台上进行模型的部署(就是将模型转换为onnx模式,且将项目代码转换成c++格式),然后在这基础之上呢直接使用专门的模型打包和系统集成工具,一步到位,实现部署SDK和系统的集成,具体可以看我的这篇文章: 🔗VS2019下打包QT项目的方法(包含第三方库)、打包成一个 exe 安装包。
二、我的模型部署和系统集成思路
在讲解之前,先对以下几个概念进行解释:
AI模型特指使用神经网络作为参数结构进行优化的最终具有一个特定作用的模式。 不知道大家在刚开始接触AI模型概念时,是否有这样的疑惑,模型,算法和网络经常是混着出的,而经常好像是互相替换使用的。而下面关于网络,模型和算法的概念是我认为讲的比较清楚的。
- 网络: 一种简单的网络结构,不包含任何权重参数。
- 模型: 设计一个网络后,在某些数据集上进行训练,得到一个包含权重参数的数据,称为模型。
- 算法: 在模型的基础上通过一些代码具体实现某些相关目的,这些代码以及模型文件等等资源被称为某算法。
下面是我个人模型部署的方法:在我的部署方法中,这种方法的具体流程是什么?
我是先在pycharm上开发模型代码(python)格式,然后转换为c++的Qt项目,在c++开发平台上进行开发,我需要对整个模型预测的过程用c++代码和库进行重构,这个过程需要对训练出来的模型权重文件进行转换,以及配置相关的环境。
在把整个python和相关python框架下的模型预测代码转换部署到c++之前,因为我们的目的是:开发在windows上的Qt软件(应用程序),这个软件集成了我们的算法功能。那么这里我们需要使用的就是在C++开发环境下结合Qt相关开发环境,共同进行这个软件的开发,其中Qt的作用就是界面设计,和设计将算法集成到这个系统中。
当我们用Qt设计好界面、且模型也均转换且预测代码部署为c++格式后(上述两个步骤同时进行);对于前者,我们需要在Qt项目的控件触发时留好对应的槽函数,对于后者,在集成时候,注意分好文件,一个功能设计为一个类(一个文件),功能都用函数封装好;在集成时,注意对应设计的功能函数(槽函数)的名称相同,以便加快我们的集成速度。
当上述操作均完成,我们在C++开发平台(如:VS 2019) 上完成了界面设计、模型部署和系统集成后吗,测试无误,则我们可以进行打包操作,打包操作你可以简单理解我把我们智能在开发软件上运行的项目变成任何一个我们在电脑上软件一样的运行方式,这样我们每次想要用这个软件的时候,不用安装开发软件点击exe
应用程序即可运行。
总结:
-
Python模型开发:
在Pycharm或其他开发环境中编写并训练你的机器学习模型,使用Python编程语言及其相关框架(如TensorFlow、PyTorch等)。在这个阶段,你将完成模型训练、验证,并获得最终的模型权重文件。 -
预测算法由python转换为c++:
一旦模型在Python中训练完成,你需要将模型从Python格式转换为C++可使用的格式。这通常需要将模型权重文件导出为通用格式(如ONNX、TensorFlow Lite等),然后在C++环境中加载这些权重文件。这一步还涉及对Python中的预测代码进行重写,以使用C++的相关库来实现同样的预测功能。 -
C++和Qt平台上的系统开发:
在C++环境下(如使用Visual Studio或Qt Creator),你将开发整个应用系统。Qt负责界面设计,C++负责实现模型的推理和业务逻辑。在界面设计上,你使用Qt进行控件的布局和交互设计,确保用户可以通过界面与模型进行交互。你需要将Qt控件的槽函数(事件处理函数)与C++代码中的模型推理函数进行关联。例如,用户点击某个按钮时,程序调用相应的C++模型推理代码,给出预测结果。
-
代码模块化和封装:
在C++中开发模型预测功能时,建议将每个功能模块独立封装为类或函数。比如,一个模型的推理过程可以封装为一个类,相关功能和操作都设计为独立的函数。这样能够提高代码的可维护性,也方便在系统集成时快速匹配相应的槽函数和功能函数。 -
系统集成:
当模型转换完毕,Qt界面也设计好之后,你需要将模型的预测功能集成到Qt项目中。此时,要确保在Qt的事件槽函数中正确调用对应的模型推理函数。通过这种方式,你的整个模型预测功能将与Qt界面无缝结合,用户能够通过界面直接触发模型预测。 -
测试与打包:
在C++环境(如Visual Studio或Qt Creator)中完成系统的功能开发后,进行充分的测试,确保模型部署、界面交互及系统集成功能都能正常运行。完成测试后,接下来就是打包操作。打包的目的是生成一个可执行文件(
.exe
),让用户不需要开发环境即可运行软件。在打包时,你需要确保所有依赖库和资源文件都被正确包含在打包文件中,以便于最终用户能够直接运行程序。
通过以上步骤,你将把Python训练好的机器学习模型成功部署到C++环境下,并且通过Qt设计的图形界面提供给最终用户使用。
这个方法的关键点是:
- 模型转换(Python到C++);
- C++中功能模块化(确保每个功能独立封装,方便集成);
- Qt与C++的系统集成(槽函数与模型推理函数的关联);
- 打包操作(将整个项目打包为可执行文件)。
下面是将模型部署和系统集成思路转换为详细的Mermaid流程图的代码:
🪧解释:
- Python模型开发:开发Python代码并进行模型训练与验证。
- 模型转换为C++:模型训练完毕后,导出模型权重文件(如ONNX格式),并重写C++代码实现模型推理。
- C++平台开发应用系统:在C++环境中进行Qt界面设计和模型推理功能的实现。模型的推理功能独立封装,Qt界面的控件与对应的槽函数绑定。
- 系统集成:将各个功能模块集成在一起,确保界面操作触发相应的模型推理。
- 测试与调试:测试系统并进行调试,确保模型部署和界面集成功能无误。
- 打包与发布:打包为可执行文件,用户可以直接运行。
下面我将分三个大的部分进行介绍,分别是:
- Qt项目的创建和Qt界面的设计
- 模型转换为C++的部署在Qt项目中
- 将完整的Qt项目打包成exe文件
2.1:Qt项目的创建和Qt界面的设计
首先是在VS2019中创建Qt项目,这个网上教程就很多了,我也不重复造轮子了,大家就安装我下面发的几个教程进行即可
-
VS2019 Qt开发环境搭建与配置
-
VS2019+opencv4.5.1+Qt5.12.10配置+Qt设计图片处理GUIDemo实操 全记录
Qt这个工具的主要作用是:
- 软件界面的设计
- 软件功能的设计
它的用法也很简单,这个一边学一边做就可以,我上面展示的博客也记录了我使用Qt开发的一些功能,很多代码都是现成的,需要什么功能现场搜着学习就行。
最重要的就是按钮和槽函数,理解这个开发起来就会容易很多。让我来通俗易懂解释一下,按钮也就是槽,当我们点击我们软件上的按钮时候,软件会给出一些反应,这些反应就是因为这个按钮触发到了其对应的槽函数,运行这个函数进行的。
相信我们计科的同学都学过前端设计,和html
的工作原理是基本相同的,而且Qt还是拖拽式的,相信你们上手也会非常快。
🌻总结:
Qt开发流程:
-
VS2019中创建Qt项目
- 参考教程配置VS2019与Qt环境,创建一个新的Qt项目。此步骤主要是项目的初始配置,可以根据教程一步步完成。
-
界面设计(UI设计)
- 使用Qt Designer(集成在Qt Creator中)或VS2019中的Qt UI工具进行软件界面设计。拖放按钮、文本框、图像等UI控件,快速创建用户界面。
-
按钮和槽函数关联
- 槽函数是Qt中用来响应用户交互的机制。通过信号和槽的机制,将按钮等控件的动作(例如点击)与具体的功能逻辑关联起来。
-
实现软件功能
- 在VS2019的C++开发环境中编写与界面相关的功能代码。例如,实现按钮点击后触发的功能逻辑,将算法功能集成到槽函数中。
-
模型功能集成
- 将C++重构后的算法模型整合到Qt项目中。实现当用户点击某个按钮时,触发模型推理功能并在界面上显示结果。
-
测试和调试
- 反复测试UI交互、模型推理功能,确保每个控件触发的功能符合预期。
-
打包发布
- 完成界面设计与功能集成后,将项目打包成可执行文件,生成一个独立的可运行软件。
Qt开发流程图(Mermaid)
解释:
- 创建项目:参考教程在VS2019中创建Qt项目,完成开发环境的配置。
- UI设计:通过Qt Designer设计软件界面。用户可以通过拖放控件(按钮、文本框等)快速生成界面。
- 按钮和槽函数:按钮的点击事件通过槽函数与功能代码关联,Qt的信号和槽机制将控件的动作与功能逻辑连接。
- 功能实现:编写C++代码,定义槽函数的具体功能,实现算法推理功能。
- 测试与调试:测试按钮点击、功能触发及模型推理的正确性,调试并优化代码。
- 打包发布:完成项目后,生成EXE文件,使软件可以独立运行。
🌟Tips:其中我们第二部中,功能的实现,就是指我们把我的模型预测功能用c++实现,放到槽函数中,进行功能的完成。
2.2:模型转换为C++的部署在Qt项目中
因为我们代码中主要涉及到了两个功能:
- 目标检测
- 分割
- 和上述功能的集成
这里对于前两个,如何进行部署,我都写了详细的博客,这个直接去看我写的博客即可:
- 【yolov8部署实战】VS2019+OpenCV环境部署yolov8目标检测模型|含详细注释源码
- 【yolov8部署实战】VS2019环境下使用Onnxruntime环境部署yolov8目标检测|含源码
- 【yolov8部署实战】VS2019+Onnxruntime环境部署yolov8-seg分割模型|含详细注释源码
部署完后,我们再将其与对于的槽函数连接,在对应的槽函数中调用其部署好的C++功能函数即可。
🚨注意:在我们把预测代码转换为c++后,我们要注意我们开发环境(推理所用到的环境。如库等)需要适配于目标部署机器,不同设备(如GPU、CPU、DSP、NPU)的适配问题以及同意设备不同型号之间的差别需要格外注意。
2.3:将完整的Qt项目打包成exe文件
这一步是最简单的一步,我也写了完整的操作流程博客:
- VS2019下打包QT项目的方法(包含第三方库)、打包成一个 exe 安装包
三、最后
上文对模型部署和系统集成的流程进行了较为全面的概述,但实际上每一个步骤都并非那么简单。在整个开发流程中,一些具体的功能性实现,如连接数据库、菜单栏的设计以及模型的优化等,都蕴含在各个大的步骤当中。
连接数据库需要考虑数据库的类型选择、连接参数的配置以及数据的存储和读取方式等问题。在进行菜单栏设计时,要充分考虑用户的操作习惯和需求,合理布局菜单选项,以提高软件的易用性。而模型的优化则涉及到多个方面,包括但不限于调整模型的超参数、采用更高效的训练算法、进行数据增强等,以提升模型的性能和准确性。
这些具体的功能和优化需要开发者在实际的开发过程中不断探索和实践,根据具体的项目需求和实际情况进行调整和改进。只有深入理解每一个步骤的内涵和要求,才能开发出高质量的 AI 系统,实现预期的目标。
相关文章:
深入浅出:深度学习模型部署全流程详解
博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: Yaoyao2024往期回顾: 【论文精读】PSAD:小样本部件分割揭示工业异常检测的合成逻辑每日一言🌼: 生活要有所期待, 否则就如同罩在…...
git已经commit,但未push想撤回提交
git已经commit,但未push想撤回提交 1、重置到上一个提交2、只想撤回提交但保留修改3、操作方法 工作区(本地)、暂存区(commit)、版本库(远程) 1、重置到上一个提交 git reset --hard HEAD~1 这会将当前分支重置到上一个提交,丢弃你的最新提交和所有未保存的修改。 …...
SSL VPN调试思路及配置指南
一、概述 本指南旨在详细阐述外部人员通过SSL VPN访问内部资源的调试过程与配置步骤。SSL VPN被单臂部署在核心交换机上,并通过外网防火墙将SSL VPN的443端口映射至外部网络,以实现安全的远程访问。 二、配置步骤 系统管理 网络设置: 配置接…...
多租户架构的全景分析(基本概念、实现策略、资源管理和隔离、数据安全与隔离、性能优化、扩展性与升级、案例研究)
文章目录 1. 多租户的基本概念2. 多租户的实现策略2.1 独立数据库模式2.2 共享数据库-独立Schema模式2.3 共享数据库-共享Schema模式 3. 资源管理和隔离4. 数据安全与隔离5. 性能优化6. 扩展性与升级7. 案例研究总结 多租户架构在云计算和SaaS应用中越来越流行,因为…...
TDengine数据库整合MyBatis实现SpringBoot项目CRUD
TDengine数据库整合MyBatis实现SpringBoot项目CRUD 官网: https://docs.taosdata.com/引入依赖 <!-- mybatis版本必须与druid版本兼容,否则无法创建DataSource --><dependency><groupId>com.alibaba</groupId><artifactId&…...
1493. 删除一个元素以后全为1的最长子数组 - 题解
> Problem: 1493. 删掉一个元素以后全为 1 的最长子数组 1493. 删除一个元素以后全为1的最长子数组 - 题解 问题描述 给定一个二进制数组 nums,你需要从中删除一个元素。请你在删掉元素后返回最长的且只包含 1 的非空子数组的长度。如果不存在这样的子数组&…...
密钥管理方法DUKPT的OpenSSL代码实现Demo
目录 1 DUKPT简介 2 基本概念 2.1 BDK 2.2 KSN 2.3 IPEK 2.4 FK 2.5 TK 3 工作流程 3.1 密钥注入过程 3.2 交易过程 3.3 BDK派生IPEK过程 3.4 IPEK计算FK过程 4 演示Demo 4.1 开发环境 4.2 功能介绍 4.3 下载地址 5 在线工具 6 标准下载 1 DUKPT简介 DUKPT&a…...
计算机视觉中的坐标变换
1.概述 高级驾驶辅助系统(ADAS)领域,存在多种常用的坐标系:LiDAR 坐标系、车辆坐标系、相机坐标系、图像坐标系等。因为和这些坐标系频繁打交道,本文对点的旋转与坐标系旋转等变换给出直观推导与说明。 2.坐标点平移…...
C++——NetWork
1.network.h #include <iostream> #include <winsock2.h> #include <cstring>class NetWork {int type; // 通信协议类型int sock_fd; // socket 描述符sockaddr_in addr; // 通信地址int addrlen; // 通信地址字节数bool issvr; …...
iOS -- 代码优化
目录 1. filter 优化2. return 优化案例1案例2 3. for循环优化案例1案例2 4. 枚举 优化5. 未完待续…… 1. filter 优化 原代码 if var vcs vcs {for vc in vcs {if vc is XXLoginViewController {if let index vcs.firstIndex(of: vc) {vcs.remove(at: index)}} }修改后 v…...
docker配置普通用户访问
文章目录 🌕方法一:让所有用户都可以使用docker🌙创建docker用户组🌙把当前用户加入docker用户组🌙单独把某个用户加入docker用户组🌙更新激活docker用户组🌙验证不需要sudo执行docker命令&…...
php后端学习,Java转php
遇到前后端跨域 php解决跨域问题可以加上下面的代码: header(“Access-Control-Allow-Origin:*”); 并且查看自己的数据库信息是否连接成功。 从Java转php 个人感受php跟偏向前端, 写后端逻辑时没有像java又springboot工具方便。 但是和前端联调很方便…...
Elasticsearch 中管道介绍
Elasticsearch 中管道 文章目录 Elasticsearch 中管道1、管道( Ingest Pipeline)1.**管道描述**2.**处理器(Processors)**(1)**`attachment`处理器**(2)**`remove`处理器**3.**整体流程**4.**应用场景**示例:如何使用该管道总结2、如何设置`attachment`处理器取出`指定…...
将jinjia2后端传到前端的字典数据转化为json
后端代码 from flask import Flask, render_template, jsonifyapp Flask(__name__)app.route(/) def index():data {key: value, number: 123}return render_template(index.html, datadata)if __name__ __main__:app.run(debugTrue) 前端代码 使用tojson过滤器即可 <!…...
Linux中如何理解一切皆文件
根据之前的学习我们会有一些少许的疑惑,我们的stdin ,stdout,stderr访问的是键盘显示器,然而键盘显示器等他们都有一个共同的特点就是他们都是外设,那么这些外设是怎么被看成是文件的呢? 看图可以知道硬件的…...
【贪心算法】(第十一篇)
目录 坏了的计算器(medium) 题目解析 讲解算法原理 编写代码 合并区间(medium) 题目解析 讲解算法原理 编写代码 坏了的计算器(medium) 题目解析 1.题目链接:. - 力扣(Leet…...
React(五) 受控组件和非受控组件; 获取表单元素的值。高阶组件(重点),Portals; Fragment组件;严格模式StrictMode
文章目录 一、受控组件1. 什么是受控组件2. 收集input框内容3. 收集checkBox的值4. 下拉框select总结 二、非受控组件三、高阶组件1. 高阶组件的概念 (回顾高阶函数)2. 高阶组件应用:注入props(1) 高阶组件给---函数式组件注入props(2) 高阶组件给---类组件注入prop…...
深入解析 Jenkins 自动化任务链:三大方法实现任务间依赖与状态控制
文章目录 前言1. 使用 “Build Trigger”(构建触发器)2. 使用 Jenkins Pipeline 实现任务触发3. 使用 Jenkins 的 “Parameterized Trigger Plugin” 插件例子1:任务 A 成功后自动执行任务 B例子2:任务 A 成功后自动执行 Pipeline…...
无人机飞手执照培训为什么需要脱产学习?
无人机飞手执照培训需要脱产学习的原因主要基于以下几个方面: 一、知识体系的系统性与复杂性 无人机飞手培训涵盖的内容广泛且深入,包括无人机基础知识、飞行原理、气象学、法律法规等多个方面。这些知识体系相互关联,需要学员进行系统的学…...
PostgreSQL(十三)pgcrypto 扩展实现 AES、PGP 加密,并自定义存储过程
目录 一、pgcrypto 简介1.1 安装 pgcrypto 扩展1.2 pgcrypto 包含的函数 二、用法①:对称加密(使用 AES、Blowfish 算法)2.1 密钥2.2 密钥偏移量 三、用法②:PGP加解密3.1 什么是PGP算法?3.2 使用 GPG 生成密钥对3.3 列…...
uniapp使用webView打开的网页有缓存如何解决(APP,微信小程序)
1、给webView的url增加时间戳 this.webviewUrl ${url}?t${new Date().getTime()}; // 添加时间戳 2、在nginx服务器上添加响应头,告诉浏览器不可以使用缓存 location / {root /opt/webs/lcdp-client/dist;index index.html index.htm;try_files $uri $uri/ /…...
HarmonyOS 模块化设计
1.HarmonyOS 模块化设计 模块化设计文档 应用程序包开发与使用文档 1.1. 概述 组件化一直是移动端比较流行的开发方式,有着编译运行快,业务逻辑分明,任务划分清晰等优点,HarmonyOs组件化的使用,有利于模块之间的解…...
解决docker拉取readeck镜像报Error response from daemon: toomanyrequests问题
readeck 是一个内容中心,目前已支持中文翻译 这是本地化部署后的效果: 原命令为: docker run --rm -ti -p 8000:8000 -v readeck-data:/readeck codeberg.org/readeck/readeck:latest Unable to find image codeberg.org/readeck/readeck:la…...
duilib的应用 在双屏异分辨率的显示器上 运行显示不出来
背景:win11,duilib应用,双显示器,两台分辨率相同,分别设置不同的缩放以后,应用运行以后,程序闪一下消失或者程序还在,但是UI显示不出来。 原因 窗口风格设置不合理,所以…...
零代码快速开发智能体 |甘肃旅游通
在互联网信息爆炸的时代,寻找一处让人心动的旅游胜地往往需要花费大量的时间和精力。而今天,我要向大家介绍一款能够帮助你轻松规划甘肃之行的智能体——“甘肃旅游通”。这款智能体通过低代码开发,集合了丰富的旅游信息和个性化推荐功能&…...
【MATLAB源码-第187期】基于matlab的人工蜂群优化算法(ABC)机器人栅格路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 Artificial Bee Colony(ABC)算法是一种模仿蜜蜂觅食行为的优化算法,它通过模拟蜜蜂群体的社会结构和行为来解决数学优化问题。本文将详细介绍ABC算法的基本原理、算法流程、以及在实际应用…...
qt获取本地语言
获取本地语言 #define QSTRING_TO_UTF8(str) std::string(str.toUtf8()) enum LanguageType {kLanguageTypeChinese,kLanguageTypeTradition,kLanguageTypeEnglish };QLocale qlLanguage;QString qstrLangCode qlLanguage.languageToString(qlLanguage.language());LOG(INFO)…...
【Spring篇】Spring中的Bean管理
🧸安清h:个人主页 🎥个人专栏:【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🎯Spring IOC容器 Ὢ…...
UV灯 VS LED灯,LED美甲灯是紫外线灯吗?
美甲灯是使甲油胶固化的重要工具,目前最常用的美甲灯一般是UV灯、LED灯以及CCFL灯。 一、不同的灯之间到底有什么区别呢?这次让我们好好看一下 UV灯: UV灯是紫外线灯管的简称。UV灯属于热阴极荧光灯,发出UVA(长波紫…...
得物App3D博物馆亮相“两博会”,正品保障助力消费体验升级
近日,2024中国体育文化博览会、中国体育旅游博览会(以下简称“两博会”)在苏州国际展览中心盛大开幕。本次展会汇聚了众多国内外体育文化、体育旅游领域的顶尖企业和品牌,共同展示体育产业的发展成果和最新趋势。在C展馆C21展位&a…...
wordpress 主题制作 视频/杭州上城区抖音seo有多好
Python3.6如何安装Shapely Shapely是一个用于处理平面几何图形的Python库,它是基于GEOS C ++库的Python接口。对于需要进行地理信息、地图处理和绘制的项目,Shapely是一个非常有用的库。但是,如果您在安装Shapely时遇到了问题,这篇文章将为您提供指导。 安装前的准备工作在…...
江阴做网站优化/钟南山今天感染新冠了
php下调用ueditor 1.2.6 使用方法说明发布于 2014-11-30 09:55:11 | 157 次阅读 | 评论: 0 | 来源: 网友投递UEditor富文本WEB编辑器UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量、可定制、用户体验优秀等特点。本文为大家讲解的是php…...
网站中图片中间是加号怎么做/免费文件外链网站
给axios配置公共请求地址 给axios把各个请求都需要使用的相同的根地址做统一配置,使得相同代码只维护一份,提升开发速度。 语法: axios.defaults.baseURL 公共根地址把axios配置成为vue实例成员 在Vue的大环境中不要直接使用axios&#…...
wordpress 延迟加载/互联网销售可以卖什么产品
关于Lua源码的基础型别、内存分配、字符串存储、垃圾回收机制、table原理等部分讲解,我发现有位仁兄写得相当之好,强烈推荐大家先认真阅读下面这篇文章,链接如下: http://simohayha.iteye.com/blog/517748 本文将只对Lua的字节码和…...
垃圾桶 东莞网站建设/百度网站提交
数据库除了“查询”之外,有时也会对数据库进行更新,这种情况下就需要对其进行增、删、改,所以对数据库的增删改成都是非常常见的操作。对数据库操作之前,你需要做两件事:1.创建一个你的数据库表存储的实体 2.建立程序与…...
建设网站的技术手段/哈尔滨网络推广优化
在子类继承父类中,一般有一行super的语句,需要记住三种使用方法: 1、super.变量/对象名; 使用这种方法可以直接访问父类中的变量或对象,进行修改赋值等操作 2、super.方法名(); 直接访问并调用父类中的…...