[Linux]从零开始的vs code交叉调试arm Linux程序教程
一、前言
最近的项目中需要集成rknn的视觉识别,在这之前我并且没有将rknn集成到自己项目的经验。这里我需要在rknn原本demo的基础上我还需要集成自己的业务代码。但是又有一个问题,原本rknn我们都是使用交叉编译编译到开发板上的,并且我们还要再demo的基础上进行修改,这么多代码如果不能调试的话,那实现功能还是有一点困难了。后面找到了一种交叉调试的方法,总的来说就是,通过在X86的主机上交叉编译ARM的程序,然后将编译出来的二进制文件发送到开发板中,然后通过网络在X86的主机上交叉调试这个程序。通过网络交叉调试也是目前最主流的调试方式。那么本次教程,就来教大家如何使用vs code交叉调试arm linux中的程序,如果你准备好了,就让我们开始吧!
二、谁适合本次教程
本次教程已经涉及到了Linux C应用开发部分了,所以并不适用于完全没有基础的小白,还请看本次教程的小伙伴具备一定的Linux基础和C语言基础。需要大家了解基本的Linux操作,理解交叉编译的概念。这里我会默认大家有基础,很多细节我并不会说或者是一笔带过。现在让我们开始吧!
三、交叉编译器的安装
这里我们需要在X86的设备上编译ARM的程序就需要使用到交叉编译器,这里我们说的交叉指的就是架构交叉。所以第一步就需要我们安装一个交叉编译器。因为我们是编译ARM Linux的程序,所以这里也必须要在X86的Linux系统中进行编译,这也是为了保证链接的库都是Linux的,不会出现怪异的问题。
这里X86一侧的Linux系统,我们可以选择直接将Linux系统装到我们的电脑中,具体可以看下面的教程:
在物理机中安装Ubuntu:[Linux]如何在物理机安装Ubuntu(小白向)-CSDN博客
这里我们也可以选择将Linux安装到虚拟机中,我在教程中也会使用这种方式,具体可以看下下面的教程:
在虚拟机中安装Ubuntu:[Linux]如何在虚拟机安装Ubuntu?(小白向)_虚拟机 ubuntu-CSDN博客
我在教程中使用的Linux发行版为Ubuntu22.04,在虚拟机中安装Ubuntu的教程在上面给出的教程中已经讲得很详细了,大家直接参考即可。当然,这里也建议大家和我使用同样版本的系统,避免出现奇怪的问题。这里我就默认大家已经安装好了Ubuntu,如下图所示:
这里我们首先需要在终端中使用下面的命令更新一下软件包:
sudo apt update
这里我们安装两个软件包,分别是“openssh-server”和“net-tools”。安装这两个是为了方便我们查看虚拟机的IP地址以及方便我们进行SSH,相信各位Linux大神对此都不陌生,这里就不细说了,直接使用下面的命令安装即可:
sudo apt install openssh-server net-tools
这里安装完成以后,我们就可以通过“ifconfig”命令查看虚拟机的IP地址:
这里大家记住自己虚拟机的IP地址,后面要考的。
现在我们可以来下载一下交叉编译器的压缩包,这里我们直接使用下面的命令拉取即可。这里需要注意,我提供了两种ARM架构的交叉编译器,大家需要根据自己开发板芯片的架构进行选择,这里我们在开发板的终端中输入下面的命令就可以看到开发板的架构了:
uname -m
这里可以看到,我的开发板架构为“aarch64”也就是我们常说的arm64架构:
所以我这里就需要aarch64的交叉编译器。这里非常简单,就不多说了:
aarch64交叉编译器下载:
wget https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.xz
armhf交叉编译器下载:
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz?revision=e09a1c45-0ed3-4a8e-b06b-db3978fd8d56&rev=e09a1c450ed34a8eb06bdb3978fd8d56&hash=9C4F2E8255CB4D87EABF5769A2E65733- armhf-uclibcgnueabihf(RV1103/RV1106): https://console.zbox.filez.com/l/H1fV9a (fetch code: rknn)
因为我的开发板是64位的所以这里就选择了“aarch64”的交叉编译器,我们直接在终端中输入命令并且回车即可,随后就会进入下载:
如果你在这里被提示wget命令找不到之类的,可以使用下面的命令安装一下wget:
sudo apt install wget
当我们下载完交叉编译器以后,就会在当前目录看到一个交叉编译器的压缩包:
这里我们直接使用下面的命令对压缩包进行解压,这里我解压的是aarch64的压缩包,所以命令这样写,如果你的交叉编译器是armhf请自己修改一下命令:
tar -xvf gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.xz
回车以后,解压就开始了:
解压以后,我们就得到了一个交叉编译器的文件夹:
进入这个文件夹,我们就可以看到以下文件夹了:
这里我们主要用到的是交叉编译器文件夹下的bin文件夹,如下图所示:
进入“bin”文件夹中就可以看到非常多的可执行文件了:
这里看着非常多,其实我们就只会用到几个可执行文件。下面为大家依次介绍一下。
aarch64-linux-gnu-gcc :主要用于交叉编译C语言
aarch64-linux-gnu-g++:主要用于交叉编译C++
gdbserver:主要用于在ARM侧启动交叉调试服务
aarch64-linux-gnu-gdb :主要用于连接“gdbserver”进行交叉调试
其实我们主要用到的可执行文件就上面几个,两个用于编译,两个用于调试。这里我们需要注意的是“gdbserver”是放在ARM一侧运行的,所以,我们可以看到它的架构是ARM的:
当然,我们现在也用不到这个,所以放在后面再说。
现在,我们得到了这些可执行文件还不算将交叉编译器安装好了,我们还需要将这个可执行文件目录添加到环境变量中,这一步很重要,这也是为了后面我们编译和调试方便。我们直接在bin目录下输入下面的命令来查看一下当前目录的绝对路径:
pwd
这里需要大家记住这里打印出来的路径,下面修改配置文件会用。
这里我们使用下面的命令打开用户环境变量的配置文件:
nano ~/.bashrc
如果你在这里被提示nano找不到,可以使用下面的命令来安装:
sudo apt isntall nano
我们打开用户环境变量的配置文件以后如图所示:
这里我们来到用户环境变量的最下方,添加下面的一行:
export PATH=/home/chulingxiao/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin:$PATH
这里大家需要注意,我们PATH后面跟的是我们一开始使用pwd命令查询到绝对路径。不要写错了,如果写错了环境变量是没办法正常加载的。
修改完以后,如图所示:
修改完成以后,我们保存退出即可,然后使用下面的命令重新加载环境变量:
source ~/.bashrc
在我们确保环境变量没有问题并且正确加载以后,就可以在终端中输入下面的命令来查看一下我们的环境变量是否添加成功:
aarch64-linux-gnu-gcc --version
这行命令会输出交叉编译器的版本信息:
如果你这里被提示命令找不到之类的,首先检查环境变量的路径有没有设置对,再检配置文件有没有被正确加载。
当然这里如果打印出了交叉编译器的版本号说明环境变量添加正确并且被正确加载。
到这里我们的编译环境就配置完成了。
这里我们只配置编译环境还不行,我们还需要配置调试环境,毕竟本篇文章就是讲交叉调试的。这里我们在终端中输入下面的命令,看看能不能启动gdb:
aarch64-linux-gnu-gdb
这里可以看到,我们这里是启动不起来的,因为我们缺少了一个名为“libncurses”的库:
既然缺这个库我们就需要自己手动安装,这里大家注意在则会个库的“.so”的后面跟了一个数字,这就是依赖这个库的版本,总的来说我们缺少了一个名为“libncurses5”的库,这里我们直接使用下面的命令安装:
sudo apt install libncurses5
安装完成以后,我们再次启动gdb,发现又缺少了一个名为“libpython2.7”的库:
因为这里库名中就跟了一个大致的版本号,所以就不用加后面的版本号了,直接使用下面的命令安装即可:
sudo apt install libpython2.7
安装完成以后,我们再次启动gdb,这里可以看到我们的gdb已经正常启动了:
在gdb的对话框中,我们输入“q”并且回车就可以退出了:
前面为大家演示那些报错就是为了为大家展示,如果在启动gdb报错时应该如何解决,结合上面的思路,我们缺少什么库就安装什么库。最终都可以解决依赖关系。
至此,我们交叉编译环境就已经安装完成了。
四、开发板一侧gdbserver配置
之前也为大家说过,我们交叉调试本质其实是依赖网络进行的,这里我们需要在开发板一侧启动gdbserver我们的X86主机才能对其进行交叉调试,所以现在我们就需要将gdbserver这个可执行程序上传到开发板中,之前我们也看了,在交叉编译器中的这个gdbserver的架构是arm64的,所以它可以直接运行在开发板上。这里需要注意的是,我们使用的交叉编译器和gdbserver必须来自一个交叉编译器的压缩包中,不然可能会出现很奇怪的情况。
这里我使用的是sftp将X86主机的gdbserver上传到开发板中,如果你对Linux比较熟悉,sftp你因该比较熟悉,这里就不细说了。当然你也可以不使用sftp总之能将文件上传到指定目录就行:
这里可以看到我将gdbserver这个可执行文件上传到了开发板的“/usr/bin”目录下,因为这个目录本来就在环境变量中,我们的可执行文件可以直接被找到。当文件传输完成以后,我们直接在开发板的终端中输入下面的命令,注意这里是在开发板的终端中:
gdbserver --version
如果可以正常打印版本信息的话,说明在开发板一侧,gdbserver已经准备好了:
至此,我们开发板一侧的环境就配置完成了。
五、交叉编译程序与gdb测试
当我们搭建好前面的环境以后,我们就可以编译一段代码来测试一下了,首先我们新建一个文件夹,这里我就新建一个名为test的文件夹,直接使用下面的命令:
mkdir test
进入这个文件夹以后,我们使用下面的命令来新建一个.c的文件:
touch main.c
这里我们使用下面的命令打开这个文件:
nano main.c
我们将下面的测试代码复制到这个.c文件中:
#include "stdio.h"
int main()
{printf("Hello World\n");printf("Hello GCC\n");printf("Hello GDB\n");return 0;
}
这里的代码很简单,是C语言中最基础的“Hello World”程序,我们后面就使用这个基础的测试程序来测试gdb调试。
这里我们保存并退出文件,这里我们使用下面的命令来将这个.c的文件编译成可执行文件:
aarch64-linux-gnu-gcc -o main main.c -g -O0
下面我来解释一下这段命令,首先就是“aarch64-linux-gnu-gcc”,这就是我们使用的交叉编译器,然后是“-o main”表示输出的可执行文件的名字,这里我们可执行文件名为“main”;然后是“main.c”,这是我们要编译的c文件。“-g”表示将这个文件编译为Debug版本,这也是为了方便我们后面的调试,“-O0”表示我们编译时的优化等级,注意这里的“-”后面是一个“O”再后面是0,这里的0就是编译优化等级,0表示不优化。
编译以后,我们就得到了一个名为“main”的可执行文件:
这个被我们编译出来的可执行文件在我们的计算机上肯定是不能运行的:
因为这个一个arm64架构的可执行文件,我们只能将其放到arm设备中运行。
这里我们同样将这个可执行文件通过sftp传输到开发板端:
这里我们在开发板端执行这个可执行文件测试一下,我们可以看到,这个可执行文件可以正常打印:
下面我们可以调试测试一下,这里我们首先在开发板启动调试服务器,这里我们使用下面的命令:
gdbserver :8000 ./main
这里的“:8000”表示对外开放的调试端口。后面的“./main”是我们要调试的可执行文件,启动gdbserver以后,我们回到计算机一侧,我们使用下面的命令先启动一下gdb:
aarch64-linux-gnu-gdb ./main
这里的“./main”是我们要调试的程序,输入命令以后就启动了gdb的对话框:
这里我们在gdb的对话框中,使用下面的命令连接开发板:
target remote 192.168.112.50:8000
这里的IP地址就是我们的开发板的IP地址,这里需要我们开发板的IP地址和我们查询到的主机的IP地址在一个网段内,这里很重要。
输入命令以后,我们就可以看到调试已经连接上了:
这里我们在gdb对话框中输入下面的命令进入主函数:
break main
这里我们可以看到来到的地址和这段代码在文件中的行数:
本质上我们使用“break main”是在主函数处打了一个断点,程序是停在了这里我们这里使用下下面的命令来到让程序继续运行:
continue
运行上面的命令以后,我们就能看到我们程序继续运行,并且显示调试到了程序中了哪一行:
这里我们在gdb对话框中使用下面的命令调试到下一行:
next
往下调试完一步以后,我们就可以发现,在开发板一侧的终端中打印出了一行内容:
打印出的这一行就是我们调试过去的一行:
这里我们将所以行都调试过去:
开发板端已经打印出了所有内容:
这里我们的调试就已经完成了。这里至少也证明了我们的gdb调试功能没有问题。
当然,大家肯定已经发现了,这样交叉调试真的是太反人类了,没有图形化不说还都是用命令操作。有没有更好的解决方案呢?当然有,那就是借助vs code进行调试,这个我们放到后面再讲。
六、使用vs code交叉调试Linux程序
在前面相信大家已经看到了,我们使用命令行的gdb交叉调试时,太困难了,所以我们这里就需要借助vs code的强大插件生态来实现图形化的交叉调试。
这里我们首先需要下载一个vscode,这里我们直接使用ubuntu内部的浏览器来下载vscode的安装包,这里我们启动浏览器,直接搜索vscode:
一般我们搜出来的第一个就是vscode的官网:
进入官网以后,直接西在deb文件就好了:
下载完成以后,我们得到了一个.deb的软件包:
这里我们直接使用下面的目录安装vscode:
sudo dpkg -i code_1.98.2-1741788907_amd64.deb
在弹出的弹窗中,我们直接回车即可:
随后我们的vscode就安装完成了:
随后vscode就出现在我们的软件列表中了:
vscode启动以后,就能看到以下界面了:
这里我们先安装一个中文的插件:
这里中文插件的安装大家应该都比较熟悉了,这里就不细说了。
重启以后,我们的vscode就变成中文了:
这里我们再安装一个C语言相关的插件,其中的调试功能也集成在其中了,我们直接搜索“C/C++”:
这里我们需要安装这个名为“C/C++ Runner”的插件。安装完成以后,如图所示:
至此,我们所需的交叉调试插件就安装好了,是的,关于调试的插件其实就只有一个。
这里我们选择“打开文件夹”:
这里我们直接选择我们之前创建的文件夹即可,这个文件夹中包含了我们的可执行文件和源文件:
我们就在这个界面按下“F5”,不出意外的话,会出现这个错误:
这是因为我们没有修改相关的配置文件,这里我们再次回到项目目录中,可以看到,当我们按下“F5”以后,应该会在我们的项目目录下生成一个名为“.vscode”的文件夹:
这个文件夹下生成了几个配置文件,我们这里只需要关注“launch.json”文件,这就是我们的调试配置文件:
打开这个文件,我们可以看到以下内容:
如果你没有正常生成“.vscode”这个目录,可以自己新建目录和“launch.json”文件。
我i们将“launch.json”文件原本的内容删除,将下面的内容写入文件:
{"version": "0.2.0","configurations": [{"name": "gdb server",//配置名称;在启动配置下拉菜单中显示"type": "cppdbg",//配置类型。"request": "launch",//请求配置类型。可以是“启动”或“附加”。"program": "${workspaceFolder}/main",//需要调试的可执行文件"args": [],//传递给程序的命令行参数。"stopAtEntry": true,//可选参数。如果为true,则调试器应在目标的入口点停止。如果传递了进程ID,则无效。"cwd": "${workspaceFolder}",//目标的工作目录"environment": [],//要添加到程序环境中的环境变量。示例:[“name”:“squid”,“value”:“clam”]。"externalConsole": false,//如果为true,则为调试对象启动控制台。如果为false,则在Linux和Windows上,它将出现在集成控制台中。"linux": {"MIMode": "gdb",//指示midebugengine将连接到的控制台调试器。允许值为“gdb”“lldb”。"miDebuggerPath": "aarch64-linux-gnu-gdb",//调试器的路径。},"miDebuggerServerAddress": "192.168.112.50:8000",//要连接到的调试器服务器的网络地址(例如:localhost:1234)。"setupCommands": [//要执行的一个或多个gdb/lldb命令,以便设置底层调试器。{"description": "Enable pretty-printing for gdb",//命令的可选说明。"text": "-enable-pretty-printing",//要执行的调试器命令。"ignoreFailures": true,//如果为true,则应忽略来自命令的失败。默认值为假。 }]}]
}
这里看起来非常复杂,这里我们只需要改几行就行了,下面依次为大家讲解。
首先就是"program": "${workspaceFolder}/main"这一行,这里我们需要填写我们要填写可执行文件的路径,首先大家需要理解workspaceFolder的概念,当我们使用vscode打开一个文件夹以后,workspaceFolder变量就变成了这个文件夹路径,假如我项目文件夹的路径为“/home/chulingxiao/test”这里workspaceFolder路径就是这个。这里我们可执行文件路径就在项目的目录下,并且名为main,所以这里完整路径为“/home/chulingxiao/test/main”。不管怎样,这里大家只要把可执行文件路径写在这里就行。
然后是"miDebuggerPath": "aarch64-linux-gnu-gdb"这里需要我们填写自己的gdb调试器,因为我们已经前面已经将gdb调试器所在的目录添加到环境变量了,所以这里这里直接写gdb调试器的名字即可。如果前面大家没有添加,可以直接写绝对路径。
然后就是 "miDebuggerServerAddress": "192.168.112.50:8000",这里的IP地址大家直接填写要交叉调试的设备的IP地址,端口号就是我们在开发板一侧启动gdbserver时指定的端口。
这里我们只需要修改这几个地方,大家需要根据自己的情况自行修改。
修改好调试的配置文件后,大家记得保存,然后我们在开发板一侧启动gdbserver:
随后我们在vscode中进入调试界面:
这里我们需要选择“gdbserver”:
然后我们再回到vscode中再按“F5”,就可以看到调试已经启动了:
这里的调试就和我们在普通IDE中的调试非常像了,这里我们按如图所示按键可以去到下一条代码:
点击如图所示的按键可以进入函数:
这里在代码前面也可以打断点。
这就是大概的使用教程,具体的还是让大家自己摸索吧,至少现在我们可以使用图形化进行交叉调试了。
至此,我们使用vscode交叉Linux程序就已经完成了。
七、结语
本次教程教了大家如何使用vscode交叉ARM Linux程序,相信大家看了本次教程以后,对C语言的编译与调试一定有更深刻认识了。那么最后,感谢大家观看!
相关文章:
[Linux]从零开始的vs code交叉调试arm Linux程序教程
一、前言 最近的项目中需要集成rknn的视觉识别,在这之前我并且没有将rknn集成到自己项目的经验。这里我需要在rknn原本demo的基础上我还需要集成自己的业务代码。但是又有一个问题,原本rknn我们都是使用交叉编译编译到开发板上的,并且我们还要…...
【顶刊级科研绘图】AI支持下Nature级数据可视化(如何画图、如何标注、如何改图、如何美化、如何组合、如何排序)
技术点目录 第一章、绘图原则与概念:规范清晰简洁自明第二章、DeepSeek、ChatGPT、R绘图系统:八仙过海各显神通第三章、美学设计与细节:完美图表华丽呈现第四章、数据类型与图表:宝典在手各个击破第五章、统计分析与可视化&#x…...
CSRF跨站请求伪造——入门篇【DVWA靶场low级别writeup】
CSRF跨站请求伪造——入门篇 0. 前言1. 什么是CSRF2. 一次完整的CSRF攻击 0. 前言 本文将带你实现一次完整的CSRF攻击,内容较为基础。需要你掌握的基础知识有: 了解cookie;已经安装了DVWA的靶场环境(本地的或云的)&am…...
Spring Boot应用中实现Jar包热更新的实践指南
Spring Boot应用中实现Jar包热更新的实践指南 一、引言 在现代软件开发中,快速迭代和持续交付是至关重要的。对于基于Spring Boot的应用程序,一旦部署到生产环境,传统的更新方式通常是重新打包并重启应用,这不仅耗时,…...
JVM深入原理(七)(一):运行时数据区
目录 7. JVM运行时数据区 7.1. 运行时数据区-总览 7.2. 运行时数据区-查看内存对象 7.3. 运行时数据区-程序计数器 7.3.1. 程序计数器-作用 7.3.2. 字节码指令执行流程 7.4. 运行时数据区-Java虚拟机栈 7.4.1. 栈-概述 7.4.2. 栈帧-组成 7.4.2.1. 栈帧-帧数据 7.4.2…...
约瑟夫环的四种(数组,链表,递归,迭代)解决方案,与空间、时间复杂度分析
以下方法均没有考虑结果集的空间与时间复杂度 1.数组解法 实现代码(未优化) class Main {public static void main(String[] args){Scanner read new Scanner(System.in);int n read.nextInt();int m read.nextInt();int[] people new int[n]; //…...
skynet.start 的作用详细解析
目录 skynet.start 的作用详细解析1. 功能概述2. 基本用法3. 关键作用(1) 注册消息处理函数(2) 启动事件循环(3) 服务生命周期管理 4. 与其他函数的协作5. 未调用 skynet.start 的后果6. 高级场景:何时不需要 skynet.start7. 总结 skynet.start 的作用详细解析 在 …...
Apache Doris 2025 Roadmap:构建 GenAI 时代实时高效统一的数据底座
在全球 290 位开发者的协作下,Apache Doris 在 2024 年完成了 7000 次代码提交,并发布了 22 个版本,实现在实时分析、湖仓一体和半结构化数据分析等核心场景的技术突破及创新。 2025 年,Apache Doris 社区将秉承“以场景驱动创新…...
springboot+easyexcel实现下载excels模板下拉选择
定义下拉注解 Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface ExcelDropDown {/*** 固定下拉选项*/String[] source() default {};/*** 动态数据源key(从上下文中获取)*/String sourceMethod() default "";…...
vue3+ts+element-plus 开发一个页面模块的详细过程
目录、文件名均使用kebab-case(短横线分隔式)命名规范 子组件目录:./progress-ctrl/comps 1、新建页面文件 progress-ctrl.vue <script setup lang"ts" name"progress-ctrl"></script><template>&l…...
软考《信息系统运行管理员》- 7.1 物联网运维
物联网的概念及特征 物联网是在计算机互联网的基础上,通过射频识别 (RFID) 、 无线传感器、红外感应器、 全球定位系统、激光扫描器等信息传感设备,按约定的协议,把物与物之间通过网络连接起来, 进行信息交换和通信,以…...
【GPT入门】第33 课 一文吃透 LangChain:chain 结合 with_fallbacks ([]) 的实战指南
[TOC](【GPT入门】第33课 一文吃透 LangChain:chain 结合 with_fallbacks ([]) 的实战指南) 1. fallback概述 模型回退,可以设置在llm上,也可以设置在chain上,都带有with_fallbacks([])函数 2. llm的回退 2.1 代码 核心代码&…...
裴蜀定理:整数解的奥秘
裴蜀定理:整数解的奥秘 在数学的世界里,裴蜀定理(Bzout’s Theorem)是数论中一个非常重要的定理,它揭示了二次方程和整数解之间的关系。它不仅仅是纯粹的理论知识,还在计算机科学、密码学、算法优化等多个…...
Table as Thought论文精读
标题:Table as Thought: Exploring Structured Thoughts in LLM Reasoning 作者:Zhenjie Sun, Naihao Deng, Haofei Yu, Jiaxuan You 单位:University of Illinois Urbana-Champaign, University of Michigan 摘要: llm的推理…...
PyQt6实例_A股日数据维护工具_使用
目录 前置: 下载预备更新的数据 使用工具更新 用工具下载未复权、前复权、权息数据 在PostgreSQL添加两个数据表 工具&视频 前置: 1 本系列将以 “PyQt6实例_A股日数据维护工具” 开头放置在“PyQt6实例”专栏 2 日数据可在“数据库”专栏&…...
MySQL客户端工具-图形化工具-DataGrip 安装与使用
一. 常见的图形化工具 二. DataGrip 安装 官网:DataGrip:由 JetBrains 开发的数据库和 SQL 跨平台 IDE 二. DataGrip 使用...
企业管理系统的功能架构设计与实现
一、企业管理系统的核心功能模块 企业管理系统作为现代企业的中枢神经系统,涵盖了多个核心功能模块,以确保企业运营的顺畅与高效。这些功能模块通常包括: 人力资源管理模块:负责员工信息的录入、维护、查询及统计分析,…...
1.Qt信号与槽
本篇主要介绍信号和槽,如何关联信号和槽以及用QPixmap在窗口中自适应显示图片 本文部分ppt、视频截图原链接:[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1. 信号 一般不需要主动发送信号,只有自定义的一些控件才需要做信号的…...
再生认证体系有哪些?不同标准对应的要求及可以做的审核机构
再生认证体系 标准 GRS再生回收认证要求 再生原材料的上游企业:需要具备GRS认证证书,以确保原材料的可追溯性和再生成分。 认证条件: 最终商品的再生成分比例必须至少为20%。 只有由至少50%的回收材料制成的产品才能贴上GRS标签。 认证机构…...
[CISSP] [6] 密码学和对称密钥算法
密码学的目标 1. 机密性(Confidentiality) 目标:保护信息不被未授权访问。 通过 加密(Encryption)技术确保数据只能被授权方解密和读取。主要方法: 对称加密(AES、3DES)ÿ…...
thinkphp每条一级栏目中可自定义添加多条二级栏目,每条二级栏目包含多个字段信息
小程序客户端需要展示团购详情这种结构的内容,后台会新增多条套餐,每条套餐可以新增多条菜品信息,每条菜品信息包含菜品名称,价格,份数等字段信息,类似于购物网的商品多规格属性,数据表中以json类型存储,手写了一个后台添加和编辑的demo 添加页面 编辑页面(json数据…...
混杂模式(Promiscuous Mode)与 Trunk 端口的区别详解
一、混杂模式(Promiscuous Mode) 1. 定义与工作原理 定义:混杂模式是网络接口的一种工作模式,允许接口接收通过其物理链路的所有数据包,而不仅是目标地址为本机的数据包。工作层级:OSI 数据链路层&#x…...
Spring Boot项目信创国产化适配指南
将 Spring Boot 项目适配信创国产化环境,需要从底层基础设施到上层应用组件进行全面替换和调整。以下是主要替换点和适配步骤的总结: 一、基础软件替换 1. JDK 替换 国外JDK:Oracle JDK、OpenJDK国产JDK: 阿里龙井(D…...
MySQL:数据类型
数值类型 数值类型用于存储整数、小数、浮点数等,主要分为整数类型和浮点类型。 整数类型 数据类型存储大小取值范围(有符号)取值范围(无符号)说明TINYINT1字节-128 ~ 1270 ~ 255小整数,如布尔值&#x…...
maven引入项目内本地包方法
最近在写java实现excel转pdf功能; 网上有个包很好用,免费:spire.xls.free-5.3.0.jar。 但是maven打包项目时报错,找不到这个包。 jar包位置如下: 在项目/src/jar/spire.xls.free-5.3.0.jar。 解决方法:…...
ARP协议
ARP协议 ARP协议的作用 当网络设备有数据要发送给另一台网络设备时,必须要知道对方的网络层地址(即IP地址)。IP地址由网络层来提供,但是仅有IP地址是不够的,IP数据报文必须封装成帧才能通过数据链路进行发送。数据帧…...
科技赋能安居梦:中建海龙以模块化革新重塑城市更新范式
在北京市西城区桦皮厂胡同,一栋始建于上世纪70年代的住宅楼正经历着一场脱胎换骨的蜕变。这座曾被鉴定为D级危房的建筑,在中建海龙科技有限公司(以下简称“中建海龙”)的匠心打造下,仅用三个月便完成"原拆原建&qu…...
2025 AI智能数字农业研讨会在苏州启幕,科技助农与数据兴业成焦点
4月2日,以"科技助农数据兴业”为主题的2025AI智能数字农业研讨会在苏州国际博览中心盛大启幕。本次盛会吸引了来自全国各地相关部门领导、知名专家学者、行业协会组织,以及县级市农业企业代表、县级市农产品销售商等万名嘉宾齐聚姑苏城,…...
2000-2021年 全国各地区城镇登记失业率数据
全国各地区城镇登记失业率数据2000-2021年.ziphttps://download.csdn.net/download/2401_84585615/90259723 https://download.csdn.net/download/2401_84585615/90259723 城镇登记失业率是衡量地区就业状况的重要指标,反映了在一定时期内,符合就业条件的…...
Cursor的主要好处
以下是Cursor的主要好处: 代码生成与优化 • 快速生成代码:根据简短描述或部分代码片段,Cursor能快速生成完整代码模块,还能智能预测下一步操作,将光标放在合适位置,让开发者一路Tab键顺滑编写代码。 • …...
超便捷语音转文字工具CapsWriter-Offline本地部署与远程使用全流程
文章目录 前言1. 软件与模型下载2. 本地使用测试3. 异地远程使用3.1 内网穿透工具下载安装3.2 配置公网地址3.3 修改config文件3.4 异地远程访问服务端 4. 配置固定公网地址4.1 修改config文件 5. 固定tcp公网地址远程访问服务端 前言 今天给大家安利一个绝对能让你工作效率飙…...
什么是数据仓库
什么是数据仓库 Data warehouse 是面向主题的 主要根据各种数据来源,来进行历史分析 形成一个趋势分析 为数据挖掘、预测建模、机器学习提供基础数据 与传统数据库比如gaussdb的区别。数据仓库注重历史数据分析,guassdb注重实时事务处理 数据仓库时企业的…...
【动态规划】二分优化最长上升子序列
最长上升子序列 II 题解 题目传送门:AcWing 896. 最长上升子序列 II 一、题目描述 给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。 输入格式: 第一行包含整数 N第二行包含 N 个整数,表示完整序列 输…...
MySQL的安装与初始化流程
MySQL概述 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,MySQL AB公司被Sun公司收购,Sun公司又被Oracle公司收购,目前属于Oracle公司。 MySQL是目前最流行的关系型数据库管理系统,在WEB应用方面MySQL是最…...
flink standalone集群模式部署
一. 环境准备 1、下载并安装jdk11 2、下载flink 并解压 3、确保服务器之间的免密登录 二、集群搭建 搭建集群至少有三台机器,每台机器的分配角色如下 master: jobManager salve01:taskManager salve02:taskManager 1、在JobManager(…...
Linux线程概念与控制:【线程概念(页表)】【Linux线程控制】【线程ID及进程地址空间布局】【线程封装】
目录 一. 线程概念 1.1什么是线程 1.2分页式存储管理 1.2.1虚拟地址和页表的由来 1.2.2物理内存管理 1.2.3页表 1.2.4页目录结构 1.2.5二级页表地址转换 1.3线程的优点 二.进程VS线程 三.Linux线程控制 3.1POSIX线程库 3.2创建线程 编辑 pthread库是个什么东西 …...
7-6 混合类型数据格式化输入
本题要求编写程序,顺序读入浮点数1、整数、字符、浮点数2,再按照字符、整数、浮点数1、浮点数2的顺序输出。 输入格式: 输入在一行中顺序给出浮点数1、整数、字符、浮点数2,其间以1个空格分隔。 输出格式: 在一行中…...
最新全开源码支付系统,赠送3套模板
最新全开源码支付系统,赠送3套模板 码支付是专为个人站长打造的聚合免签系统,拥有卓越的性能和丰富的功能。它采用全新轻量化的界面UI 让您能更方便快捷地解决知识付费和运营赞助的难题,同时提供实时监控和管理功能,让您随时随地…...
Eclipse Leshan 常见问题解答 (FAQ) 笔记
本笔记基于 Eclipse Leshan Wiki - F.A.Q. 页面内容,旨在解答关于 Eclipse Leshan(一个开源的 LwM2M 服务器和客户端 Java 实现)的常见问题,帮助您更好地理解和使用该工具。 一、Leshan 是什么,我该如何使用它&#x…...
【6】数据结构的栈篇章
目录标题 栈的定义顺序栈的实现顺序栈的初始化入栈出栈获取栈顶元素顺序栈总代码与调试 双端栈的实现双端栈的初始化入栈出栈双端栈总代码与调试 链栈的实现链栈的初始化入栈出栈获取栈顶元素链栈总代码与调试 栈的定义 定义:栈(Stack)是一种…...
开源虚拟化管理平台Proxmox VE部署超融合
Proxmox VE 是一个功能强大、开源的虚拟化平台,结合了 KVM 和 LXC,同时支持高可用集群、存储管理(ZFS、Ceph)和备份恢复。相比 VMware ESXi 和 Hyper-V,PVE 具有开源、低成本、高灵活性的特点,适用于中小企…...
C语言基础要素(019):输出ASCII码表
计算机以二进制处理信息,但二进制对人类并不友好。比如说我们规定用二进制值 01000001 表示字母’A’,显然通过键盘输入或屏幕阅读此数据而理解它为字母A,是比较困难的。为了有效的使用信息,先驱者们创建了一种称为ASCII码的交换代…...
函数柯里化(Currying)介绍(一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术)
文章目录 柯里化的特点示例普通函数柯里化实现使用Lodash进行柯里化 应用场景总结 函数柯里化(Currying)是一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术。换句话说,柯里化将一个多参数函数转化为一系列嵌套的单参数函数。 …...
基于大模型的主动脉瓣病变预测及治疗方案研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究意义 二、大模型预测主动脉瓣病变原理 2.1 大模型介绍 2.2 数据收集与处理 2.3 模型训练与优化 三、术前预测与评估 3.1 主动脉瓣病变类型及程度预测 3.2 患者整体状况评估 3.3 手术风险预测 四、术中应用与监测…...
VSCode开发者工具快捷键
自动生成浏览器文件.html的快捷方式 在文本里输入: ! enter VSCode常用快捷键列表 代码格式化:Shift Alt F向上或向下移动一行:Alt Up 或者 Alt Down快速复制一行代码:Shift Alt Up 或者 Shift Alt Down快速保…...
AI助力PPT制作,让演示变得轻松高效
AI助力PPT制作,让演示变得轻松高效!随着科技的进步,AI技术早已渗透到各行各业,特别是在办公领域,AI制作PPT已不再是未来的梦想,而是现实的工具。以前你可能需要花费数小时来制作一个完美的PPT,如…...
行业专家视角下的技术选型与任务适配深度解析
行业专家视角下的技术选型与任务适配深度解析 一、任务属性与技术栈的映射逻辑 (1)学术类项目需优先考虑技术严谨性、可复现性和理论深度: 机器学习模型开发:PyTorchJupyterMLflow形成完整实验闭环,TensorFlow Exte…...
从零构建大语言模型全栈开发指南:第五部分:行业应用与前沿探索-5.2.1模型偏见与安全对齐(Red Teaming实践)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 大语言模型全栈开发指南:伦理与未来趋势 - 第五部分:行业应用与前沿探索5.2.1 模型偏见与安全对齐(Red Teaming实践)一、模型偏见的来源与影响1. 偏见的定义与分类2. 偏见的实际影响案例二、安全对齐…...
JUC系列JMM学习之随笔
JUC: JUC 是 Java 并发编程的核心工具包,全称为 Java Util Concurrent,是 java.util.concurrent 包及其子包的简称。它提供了一套强大且高效的并发编程工具,用于简化多线程开发并提高性能。 CPU核心数和线程数的关系:1核处理1线程(同一时间单次) CPU内核结构: 工作内…...
OpenRouter开源的AI大模型路由工具,统一API调用
简介 OpenRouter是一个开源的路由工具,它可以绕过限制调用GPT、Claude等国外模型。以下是对它的详细介绍: 一、主要功能 OpenRouter专注于将用户请求智能路由到不同的AI模型,并提供统一的访问接口。它就像一个“路由器”,能…...