Linux《基础开发工具(中)》
在之前的Linux《基础开发工具(上)》当中已经了解了Linux当中到的两大基础的开发工具yum与vim;了解了在Linux当中如何进行软件的下载以及实现的基本原理、知道了编辑器vim的基本使用方式,那么接下来在本篇当中将接下去继续来了解另外的两大基础的开发工具gcc/g++和自动化构建make/makefile,相信通过本篇的学习会使得你会有大的收获,一起加油吧!!!
1.gcc/g++
在之前的C语言的学习时我们就了解了程序由我们实现的代码到最终的可执行程序是要经过编译和链接两个大过程的,并且编译还可以细化分为预处理、编译、汇编三个过程。在之前的C语言的编译和链接以及深入理解预处理就了解了以上提到的过程基本的功能是什么,实现之后的结果是什么。但是之前我们在学习的过程当中只是将各个过程实现的功能大体的进行讲解,接下来我们就将在Linux当中验证之前我们了解的各个过程具体实现的结果是否和我们的预期是一样的。
1.1 编译链接
预处理
我们知道在预处理进行的是去注释、宏替换、条件编译、头文件展开等的工作,那么在Linux要得到一个文件只进行预处理之后的文件就需要用到gcc/g++编译选项的指令
注:gcc/g++都是编译器,其中gcc只能编译C语言,而g++既可以编译C语言也可以编译C++
gcc -E [原文件名] -o [生成.i的文件]
使用以上指令就可以将源目标的文件生成一份进行预处理之后的文件,在此一般会将该文件的后缀命名为.i,以上指令当中-E就表示在gcc/g++执行的过程当中只要预处理执行完就停止,-o之后表明预处理之后要生成的文件的名称。
例如以下示例:
以下实现了一个test1.c的文件,之后我们使用vim在里面编写了以下的代码
接下来就来使用以上我们学习的指令来使得gcc编译过程中只执行预处理之后就停止,生成的文件名为test1.i
执行了指令之后接下来就打开生成的test1.i,这时定位到main就可以看到我们代码当中的头文件#include<stdio.h>已经被展开,并且宏M也进行了替换;原先代码当中的注释也去掉了
编译
我们知道在编译过程当中主要就是将预处理之后的C/C++等的语言代码转换为汇编指令,在Linux当中要使得gcc/g++在执行过程当中到编译之后就停止需要使用以下的指令
gcc -S [源文件] -o [目标生成的.s文件]
以上指令的-S选项就可以使得执行完编译就停止,-o选项之后的文件名表明的是要生成的目标文件名,一般会将只执行到编译之后的文件名后缀命名为.s
例如以下示例:
以上我们已经将对应的test1.c使用gcc -E生成了对应的test1.i,那么接下来就继续将该test1.i使用gcc -S生成对应的test1.s
接下来查看生成的test1.s就可以看到此时该文件内已经将原来的C语言代码转化为了汇编代码
汇编
我们知道汇编主要实现的就是将编译之后生成的汇编代码生成机器码,也就是原先的代码当中变成了只含0、1的二进制码。在Linux当中要使得在gcc/g++执行时到汇编这一步就停止就需要使用以下的指令
gcc -c [源文件] -o [生成的目标.o文件]
以上的指令就当中-c表示的是使用gcc/g++时到汇编这一步执行完就停止,-o之后的文件表示的是要生成的目标文件名。一般将只执行到汇编的文件后缀命名为.o
例如以下示例:
以上我们已经使用gcc -S指令生成了对应的执行完编译之后的文件test1.s,那么接下来就继续使用gcc -c指令生成执行完汇编的文件test1.o
使用vim打开生成的test1.o文件之后就可以看到现在该文件内是一堆乱码,这就是因为此时该文件已经是一个二进制文件,直接打开是无法查看该文件的内容的
链接
在链接过程主要是将对应的.o文件和库文件进行链接
要将对应的原文件生成对应的可执行程序就需要使用以下的指令
以上我们就将之前在C语言了解的程序的编译过程在Linux
gcc [源文件名] -o [目标文件]
例如以下示例:
以上我们已经使用gcc -c 生成了执行汇编之后的文件,那么接下来继续将该文件使用gcc 形成test.out
运行产生的test.out
当中具体的演示了一遍,但其实以上的知识在之前我们就已经掌握了,在此只不过是在复习加深。其实在Linux的学习当中我们更要了解的是编译链接当中的链接,之前我们只是知道在汇编之后进行链接时会将此时的.o文件和其他的文件进行链接生成对应的可执行程序,但是在这个过程当中具体是如何实现的在此我们还无法进行详细的讲解,这是因为在该过程当中牵扯到了进程和文件的相关知识,因此我们会在了解完进程和文件系统之后在动静态库和动静态链接再对链接进行详细的了解。
1.2 几个小问题
在此你可能就会有疑惑了,为什么在将我们写的代码转化为可执行程序的过程当中要经历过编译之后再进行链接?
在我们实现一个大的工程项目时,不可避免地要解决不同用户的使用,就比如在一个网页的开发软件内就可能会有免费版和专业版的区别,那么此时在这两个版本当中就需要使用两份不同的代码吗?这样确实是可以的,不过一般是不会这样做,这是因为专业版当中相比免费的版本只是添加了一些功能,这时如果使用不同的底层代码就需要维护两份代码。在这种情况下条件编译的作用不就显示出来了吗,此时在免费版当中就将对应的专业版功能的代码进行条件编译,只要当用户是以专业版进入时才会将这份代码开放,这时在底层就只需要维护一份代码即可。
因此编译的作用简单来说就是减少语言的开发成本
接下来我们来了解什么是编译器的自举
我们知道gcc是用于编译C语言的代码,最后将其编译为机器语言。其实gcc底层的代码也是由C语言实现的,但是问题就来了语言的编译器和C语言那个先诞生呢?
其实是先诞生对应的编译器编译器的之后才产语言的,其实一开始最早的是使用纸袋打孔的方式来实现编程的,此时对应有孔无孔就分别表示1,0。该语言就是机器语言。
之后使用机器语言编写出了了汇编语言的编译器,我们知道编译器的作用可以来
就例如在C语言诞生之前先使用汇编语言产生C语言的的编译器可以编写软件,那么编译器不也是软件,因此就使用汇编语言写出了底层代码为汇编语言的编译器。
在此之后使用汇编语言编写出了C语言的编译器,在使用之后再使用C语言编写出底层代码为C语言的的编译器。
以上描述的过程当中有汇编写出汇编语言的编译器、由C语言写出C语言的编译器都是属于编译器自举。
在此还有问题就是为什么在C、C++当中都是要将将对应的程序代码转化为汇编语言再由汇编语言转化为机器语言?
这其实就是为了提高转化的效率,因为在C/C++诞生之前就已经形成了完善的汇编转化为机器语言的体系,所以在实现出C/C++之后只需要建立C/C++和汇编之间的转化关系即可;这相比要建立C/C++和机器语言之间的直接关系要容易的多,并且效率还更高。
1.3 动静态库和动静态链接
接下来在了解了gcc/g++的使用之后接下来来了解动静态库。
• 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此升成的文件比较大,但在运
行时也就不再需要库文件了。其后缀名一般为“.a”
• 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由
运行时链接文件加载库,这样可以节省系统的开销。动态库⼀般后缀名为“.so”
在此在Linux当中动态库一般是libXXXX.so的格式,其中XXXX是库的名称,静态库一般是XXXX.a的格式。在Windows当中动态库一般是XXXX.dll的格式,静态库一般是XXXX.lib的格式。
因此动态链接就是指在链接过程当中链接动态库,静态链接就是指在链接过程当中在链接的是静态库。
接下来我们就来看看Linux当中的C标准库,在此C标准库一般是保存在/lib64/libc.so.6 路径当中,接下来就使用ls指令来看看
这时就可以看到C标准库名称为c-2.17
在此要看一个可可执行程序的链接情况可以使用以下的指令
ldd [文件名]
例如以上生成的test.out使用ldd就可以看出该程序进行的动态链接 ,链接的动态库如下所示
在此也可以使用file来查看可执行程序链接的方式
这时我们要知道的是Linux当中默认的是采用动态链接的方式。
但是如果要让在链接时进行静态链接呢?
由于Linux当中默认是不存在动态库的,因此我们要使用静态链接之前要先执行以下的指令
yum install glibc-static libstdc++ -static -y
之后要进行静态链接只需要在使用gcc时最后带上-static选项即可
例如以下示例:
将test1.c按照静态链接的方式生成对应的可执行程序test2.out,这时就会发现静态链接形成的可执行程序相比原来动态链接的可执行程序文件大小要大许多。
以上我们就了解了动静态链接的一系列操作,但是现在我们还是未了解动态链接和静态链接有什么区别,但是现在我们又无法理性的从原理具体的讲解,那么接下来就来感性的理解,来通过一个故事来理解动静态链接。
在此你是XXX一中的一名学生,由于之前在初中时学习就比较好,你考上了市里的一中。从初中开始你就喜欢在学习之后玩玩电脑游戏来放松放松,但是到了高中问题就来了,在高中里要住在学校的宿舍里,这就没法玩电脑了,这就使你很苦恼了,你之后有电脑游戏的放松才能让学习的效率提高。此时你想到在你家附近的不是有一个表哥是一中高三的学生吗?去找这位学长来了解有什么解决的方法,到了表哥的家里之后,从表哥的口里得知了在学校的门口向东200米左右有一个网咖,很多的学长都是去这个网咖里打游戏的。因此在入学之前就把表哥说的网咖的地址记到脑子里了。不久之后你就进入到了一中当中,到了周末你感到身心疲惫,最近没了游戏的放松你感觉自己对学习都提不上尽了,此时你就想到之前表哥说的网咖,想着我们早上把数学和 英语作业写完去网咖玩两个小时的游戏,之后下午再把其他的作业写完。想玩你就快速的把相应的作业写完了,出了学校去网咖了打了两个小时的游戏,到了下午你写其他的作业的时候感觉自己的学习效率都提升了。之后的日子里,你都在周末的时候去网咖打几个小时的游戏,有了放松的时间你的学习快速的提高。
在以上的故事当中其实你就是可执行程序,你找的表哥就是编译器以及链接器,此时从表哥的口里得知网咖的地址就是进行动态的链接,之后在周末的时候你就相当于可执行程序加载到了内存当中,执行到了要去上网就想到网咖的地址,这就是调用之前进行动态链接的时候得到的库路径,之后通过网咖的地址找到网咖就相当于找到的对应的动态库,之后从网咖回到学校进行写作业就相当于动态库的调用完成继续进行程序的执行
接下来继续来看以上故事的续集。
随着越来越多的人知道了学校的附近有这么一个网咖,在周末的时候很多的学生都去这个网咖上网了,不久之后就被你们一中的校长知道了,毕竟不是所有人都是像你一样去网咖是为了放松,大多数去的人都沉迷在了游戏当中这就使得大多数学生的成绩大幅度的下降,校长想着是时候解决这个问题了,不久之后校长就告知附近的公安这家网咖非法的给未成年人上网,不久之后帽子叔叔就把这家网咖给拿下了。之后的一个周末当中和之前一样想去网咖放松一下发现网咖已经被封了,你就只好回宿舍了。之后的一段时间由于你无法在周末的时候上网来放松就让你没了学习的动力;学习成绩开始了下滑,从之前的年段前十掉到了百名开外。你的爸爸知道了你的成绩下滑之后就找你谈话,你就把你下滑的原因告诉了你的爸爸,你爸爸说这事放心我和你校长是好哥么,我去找他想想办法。之后你的爸爸就找了校长和他说了你学习成绩的下降是因为在周末的时候没法上网放松,平常的时候没法上网查一些资料,之后和校长说能不能开个特例让你在宿舍里安一台电脑,只要之后你再出现大的成绩下滑就把电脑撤了。这时你的爸爸就还找到了原来的学校附近被封的网咖,从这个网咖内购入了一台电脑,不久之后你的宿舍了就安上了。有了电脑的放松你的学习效率大大的提升,很快就回到了学校的年段前十。其他的学生看到你在宿舍里安了电脑,就和一样也纷纷在自己的宿舍了安装了电脑。
在以上的故事续集当中当原来的网咖被封之后你在自己的宿舍安装了电脑,这样上网不用去网咖里的操作其实就是静态链接,其特点就是直接将对应的库拷贝到可执行程序当中,这样在需要调用相应的库就不需要在调用的时候再去指定的路径当中调用对应的库,可以直接在可执行程序的内部就可以调用。
因此通过以上故事的讲述就可以看出动静态链接的优劣如下所示:
动态链接:程序在调用相应的库的时候只需要通过路径即可找到,因此可执行程序的内部不需要进行库的拷贝,可执行程序的内存会比较小,但是动态库是共享的,所有库不能丢失否则就会出现所有依赖该动态库的程序在运行的时候出现错误。静态链接:优点是不依赖库,即使一个库出现丢失,原来进行过静态链接的可执行程序内部也不会出现运行的错误。但是静态链接需要将库拷贝到对应的可执行程序内,这就会使得空间的浪费,包括内存、磁盘、网络等。
2. 自动化构建-make/Makefile
2.1 背景
在了解make以及makefile之前先来了解make以及makefile的基本背景
• 会不会写makefile,从⼀个侧面说明了⼀个人是否具备完成大型工程的能力
• ⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个目录中,makefile定义了⼀系列的规则来指定,哪些文件需要先编译,哪些⽂件需要后编译,哪些文件需要重新编译,甚⾄于进⾏更复杂的功能操作
• makefile带来的好处就是⸺“自动化编译”,⼀旦写好,只需要⼀个make命令,整个工程完全⾃动编译,极⼤的提⾼了软件开发的效率。
• make是⼀个命令工具,是⼀个解释makefile中指令的命令工具,⼀般来说,大多数的IDE都有这个命令,⽐如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了⼀种在工程方面的编译⽅法。
• make是⼀条命令,makefile是⼀个文件,两个搭配使⽤,完成项目自动化构建。
2.2 make和makefile的使用方法
在以上我们了解了make以及makefile的重要性,那么接下来就来了解怎么使用make以及makefile内的文件内容该如何创建。
首先要知道的是要使用make命令的前提是在当前的所处的目录下,含有名为makefile或者Makefile的文件,因此在当中路径下我们就就先创建一个名为makefile的文件。
当前目录下创建了一个test1.c的文件,该文件内的内容如下所示:
之前我们使用将该文件编译为可执行程序是直接使用 gcc test1.c -o test1.out 来实现,而接下来我要使用的是先创建对应的makefile,之后再使用make命令来实现可执行程序的创建。
在此makefile内的内容就如下所示:
在此以上就是一个简单的makefile的内容,在此我们写的第一行就将要生成的文件依赖的源文件的依赖关系写出来,之后再写明了这两个依赖文件之间的依赖方法,其实也就是提供了源文件转化为目标文件的方式。
在此了依赖关系和依赖方法在现实生活当中可以映射到你和父母要生活费这件事上,只有你和父母的关系才能让你能执行向你的父母要生活费这个动作上,你的舍友就无法向你的父母索要。在此你和父母的关系就是依赖关系,你要钱的行为就是依赖方法,能执行依赖方法的前提是你和父母有依赖关系。
注:在此makefile当中编写依赖方法时要在依赖关系之后另起一行,并且之前还要空4个字符,若之前你已经将vim进行配置,那么在依赖关系之后按回车就会自动换行并且空对应的字符
编写了对应的makefile之后接下来回到之前的目录下,使用make命令就可以看到会将对应依赖关系的的依赖方法进行执行,并且还在当前的目录下生成了对应的目标文件test1.out。
执行该文件就可以得到该可执行程序的输出内容
但其实以上我们编写的makefile是不完整的,一般在编写makefile的时候还要将项目清理工作也在makefile进行实现。
以上的maekfile在添加上清理功能之后如下所示:
以上就是添加上了clean之后的makefile,在此其实clean是一个伪目标文件,为什么接下来会讲解。
• 像clean这种,没有被第⼀个目标文件直接或间接关联,那么它后⾯所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令⸺“make clean”,以此来清除所有的目标文件,以便重编译。
• 但是⼀般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
在此使用make时是会自顶向下扫描makefile文件,默认形成的是第一个目标文件,因此以上的使用make命令时会直接执行gcc test1.c -o test1.out
如果要想指定形成就需要使用 make targetname,就例如以上的make clean
接下来就回到原来的目录下,执行make clean命令
执行了之后再使用 ll 指令就会发现之前创建的test.out被删除了,并且连续多次使用make clean也可以执行
但是如果是多次使用make命令就只有当第一次是可以执行的,接下来的都会报错,这是为什么呢?
要解决该问题就需要了解到ACM时间,在此我们是使用stat来查看对应文件的ACM时间
stat [文件名]
以上使用了stat命令之后就可以看到三个时间的信息,在此Access表示的是之后一次访问文件的时间,Modify表示的是就是文件最近一次内容修改的时间,Change表示的就是文件的属性最后一次被修改的时间。
在此系统在判断是否要执行对应依赖关系的依赖方法时其实比较的就是对应源文件的Modify和目标文件的Modify时间,当目标文件的时间要比源文件的时间要靠后是才执行对应的依赖方法
那么为什么在操作系统当中要这样做,为什么不直接在用户每次使用对应的make命令时都将对应的依赖方法进行执行呢?
这其实是为了提高编译的效率,毕竟真实的情况不是像我们当前这样只是有一个源文件,真正的项目当中都是存在成百上千个源文件的,每一次编译都是需要耗费大量的时间的,因此当源文件的内容未出现修改时就不再进行编译,只有当原文件的M时间在目标文件之后才进行编译。
了解了以上的问题之后接下来就可以来解答之前提到的clean的伪目标文件是什么了,在此伪目标文件就是在目标该文件之后的依赖方法不依据源文件和目标文件的M时间前后来判断是否执行,只要用户使用make命令执行之后就会执行该依赖方法
在以上我们了解makefile的基本编写方式,那么接下来进一步来理解makefile的推导原则
在以上我们了解了在编译当中是可以将编译具体划分为预处理、编译、链接三步的,那么接下来就将原来makefile内的一个依赖关系和依赖方法具体的展开
注:在此在makefile当中使用#可以进行注释
以上就实现了细节更加完整的makefile,接下来就回到之前的目录当中使用make命令
通过make命令输出的结果就可以看出其实在使用make指令时是将makefile内的依赖方法因此入栈,推导完毕依次出栈。
以上只是让我们了解make是会进行依赖关系的推导的,直到依赖文件是存在的。但是一般我们不会将makefile写成以上的形式,接下来写更加具通用性的makefile。
其实在真正的项目当中可能是会有多个.c文件的,在此一般都是将这些.c文件编译为.o文件,之后再和其他的第三方库进行链接打包成为对应的可执行程序。
因此一般在makefile当中一般都会将对应的.c文件编译为.o之后再进行编译。
例如以上的makefile按照以上的要求就变为以下的形式:
但是以上的makefile不具有普遍性,接下来来继续修改,在此当中我们可以像在C/C++当中原因创建变量,在此创建变量的方式是使用 变量名= 变量值 ,之后要访问该变量就使用 $(变量) 的方式,在此可以了解为在C/C++当中指针的解引用一样。
在此实现了以下形式的makefile当要改变对应的文件名时就只需要将对应变量定义的位置进行修改即可。
以上我们改变完成的makefile虽然相比我们之前的实现的makefile有了更好的通配性,但是问题是当要实现非常多文件的编译成为可执行程序的工作时工作以上的makefile还是无法实现,因此接下来我们还要继续来对以上的makefile进行修改
当要实现将多个文件编译链接成为一个可执行程序时,就需要改变以上的SRC,在此在makefile提供了如下所示的两种语法来实现
改变了SRC之后接下来OBJ也要进行改变,改变结果如下所示:
接下来还需要将对应的依赖关系和依赖方法也进行修改
以上的依赖方法也可以按照原来的方式进行,但是一般还是会修改为以上的形式 其中$^ 表示的是依赖文件, $@ 表示的是目标文件
接下来的依赖关系和依赖方法修改为一以下形式,其中 $< 表示的就是将所有的.c文件编译为同名的.o文件
完整的makefile就如下所示:
完成了具有更加普遍性的makefile之后接下来我们来创建100个.c文件来测试实现的makefile是否能实现要求
接下来使用make命令就会出现刷屏的情况,这是因为默认是会将所有的依赖方法都会回显的
如果要在执行make时不进行任何的回显就需要在原来的依赖方法上之前加上@
使用完make指令之后就可以看到当前目录下多了一个make生成的可执行程序mytest
以上就是本篇的全部内容了,接下来还会在以下的篇章中讲解剩下的两个Linux基本开发工具git和gdb,未完待续……
相关文章:

Linux《基础开发工具(中)》
在之前的Linux《基础开发工具(上)》当中已经了解了Linux当中到的两大基础的开发工具yum与vim;了解了在Linux当中如何进行软件的下载以及实现的基本原理、知道了编辑器vim的基本使用方式,那么接下来在本篇当中将接下去继续来了解另…...

CPU 负载 和 CPU利用率 的区别
简单记录下 top 命令中,CPU利用率核CPU负载的概念, (1)CPU利用率:指在一段时间内 表示 CPU 实际工作时间占总时间的百分比。表示正在执行进程的时间比例,包括用户空间和内核空间程序的执行时间。通常包含以…...

vue源码(二)
文章目录 数据代理示例 初始化组件实例计算属性基本用法ComputedReflmpl类计算属性的创建 Vue3的特点及优势声明式框架采用虚拟DOM区分编译时和进行时 Vue3设计思想 数据代理 示例 以下代码主要是有一个msg的响应式数据,点击按钮后修改msg的内容。根据代码可知有两…...

Ubuntu切换lowlatency内核
文章目录 一. 前言二. 开发环境三. 具体操作 一. 前言 低延迟内核(Lowlatency Kernel) 旨在为需要低延迟响应的应用程序设计的内核版本。Linux-lowlatency特别适合音频处理、实时计算、游戏和其他需要及时响应的实时任务。其主要特点是优化了中断处理、调…...

C++算法——差分
1.差分 差分与前缀和的核心思想相同,是预处理,可以在暴力枚举的过程中,快速给出查询的结果,从而优化时间复杂度。 是经典的用空间替换时间的做法。 2.一维差分数组 前缀和与差分是⼀对互逆的运算,对差分数组做前缀…...

猫耳大型活动提效——组件低代码化
1. 引言 猫耳前端在开发活动的过程中,经历过传统的 pro code 阶段,即活动页面完全由前端开发编码实现,直到 2020 年接入公司内部的低代码活动平台,满足了大部分日常活动的需求,运营可自主配置活动并上线,释…...

亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(一)- 总体概要 服务无状态化详细设计 目标:确保服务实例完全无状态,可任意扩缩容 1. 会话存储改造(Session Management) 核心问题:传统单体应用中,用…...

零成本短视频爆款制造手册
——Q版+情感+互动的流量密码拆解 适用平台:抖音/快手/视频号 核心指标:点赞率>10% | 完播率>40% | 涨粉成本<0.3元 一、底层逻辑框架 1. 爆款元素融合公式 [ 3秒钩子 ] + [ 7秒沉浸 ] + [ 5秒引爆 ] = 15秒黄金结构 │ │ └─▶ 互动指令+情感…...

红队思想:Live off the Land - 靠山吃山,靠水吃水
在网络安全领域,尤其是红队(Red Team)渗透测试中,“Live off the Land”(简称 LotL,中文可译为“靠山吃山,靠水吃水”)是一种极具隐秘性和实用性的攻击策略。这一理念源于现实生活中…...

C语言八股---预处理,编译,汇编与链接篇
前言 从多个.c文件到达一个可执行文件的四步: 预处理–>编译–>汇编–>链接 预处理 预处理过程就是预处理器处理这些预处理指令(要不然编译器完全不认识),最终会生成 main.i的文件 主要做的事情有如下几点: 展开头文件展开宏条件编译删除注释添加行号等信息保留…...

平衡二叉树(AVL树)
平衡二叉树是啥我就不多说了,本篇博客只讲原理与方法。 首先引入平衡因子的概念。平衡因子(Balance Factor),以下简称bf。 bf 右子树深度 - 左子树深度。平衡结点的平衡因子可为:-1,0,1。除此…...

SpringBoot(一)--搭建架构5种方法
目录 一、⭐Idea从spring官网下载打开 2021版本idea 1.打开创建项目 2.修改pom.xml文件里的版本号 2017版本idea 二、从spring官网下载再用idea打开 三、Idea从阿里云的官网下载打开 编辑 四、Maven项目改造成springboot项目 五、从阿里云官网下载再用idea打开 Spri…...

RabbitMQ使用延迟消息
RabbitMQ使用延迟消息 1.什么情况下使用延迟消息 延迟消息适用于需要在一段时间后执行某些操作的场景,常见的有以下几类: 1.1. 订单超时取消(未支付自动取消) 场景: 用户下单后,如果 30 分钟内未付款&a…...

MyBatis-Plus 分页查询接口返回值问题剖析
在使用 MyBatis-Plus 进行分页查询时,很多开发者会遇到一个常见的问题:当分页查询接口返回值定义为 Page<T> 时,执行查询会抛出异常;而将返回值修改为 IPage<T> 时,分页查询却能正常工作。本文将从 MyBatis-Plus 的分页机制入手,详细分析这一问题的根源,并提…...

DeepLabv3+改进7:在主干网络中添加SegNext_Attention|助力涨点
🔥【DeepLabv3+改进专栏!探索语义分割新高度】 🌟 你是否在为图像分割的精度与效率发愁? 📢 本专栏重磅推出: ✅ 独家改进策略:融合注意力机制、轻量化设计与多尺度优化 ✅ 即插即用模块:ASPP+升级、解码器 PS:订阅专栏提供完整代码 论文简介 近期有关移动网络设计…...

c语言笔记 内存管理之栈内存
物理内存和虚拟内存 在c语言的程序需要内存资源,用来存放变量,常量,函数代码等,不同的内容存放在不同的内存区域,不同的内存区域有着不同的特征。 c语言的每一个进程都有着一片结构相同的 虚拟内存,虚拟内…...

分布式事务的原理
文章目录 基于 XA 协议的两阶段提交(2PC)三阶段提交(3PC)TCC(Try-Confirm-Cancel)Saga 模式消息队列(可靠消息最终一致性) 分布式事务是指在分布式系统中,涉及多个节点或…...

鸿基智启:东土科技为具身智能时代构建确定性底座
人类文明的每一次跨越都伴随着工具的革新。从蒸汽机的齿轮到计算机的代码,生产力的进化始终与技术的“具身化”紧密相连。当大语言模型掀起认知革命,具身智能正以“物理实体自主决策”的双重属性重新定义工业、医疗、服务等领域的运行逻辑。在这场革命中…...

SQL29 计算用户的平均次日留存率
SQL29 计算用户的平均次日留存率 计算用户的平均次日留存率_牛客题霸_牛客网 题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的留存率。 示例:question_practice_detail -- 输入: DROP TABLE IF EXISTS question_practice_detai…...

MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流
在无人零售市场蓬勃发展的浪潮中,自动售货机正经历着从传统机械式操作向AI视觉技术的重大跨越。 移远通信作为全球领先的物联网整体解决方案供应商,精准把握行业趋势,在2025世界移动通信大会(MWC)上宣布推出全新AI智能…...

sparkTTS window 安装
下载 Spark-TTS Go to Spark-TTS GitHubClick "Code" > "Download ZIP", then extract it. 2. 建立 Conda 环境 conda create -n sparktts python3.12 -y conda activate sparktts 3. Install Dependencies pip install -r requirements.txt In…...

数据库原理6
1.数据是信息的载体 2.数据库应用程序人员的主要职责:编写应用系统的程序模块 3.关系规范化理论主要属于数据库理论的研究范畴 4.数据库主要有检索和修改(包括插入,删除,更新)两大操作 5.概念模型又称为语义模型。…...

接口自动化入门 —— Http的请求头,请求体,响应码解析!
在接口自动化测试中,HTTP请求头、请求体和响应码是核心组成部分。理解它们的作用、格式和解析方法对于进行有效的接口测试至关重要。以下是详细解析: 1. HTTP 请求头(Request Header) 1.1 作用 请求头是客户端向服务器发送的附加…...

tcc编译器教程6 进一步学习编译gmake源代码
本文以编译gmake为例讲解如何使用tcc进行复杂一点的c代码的编译 1 简介 前面主要讲解了如何编译lua解释器,lua解释器的编译很简单也很容易理解.当然大部分c语言程序编译没那么简单,下面对前面的gmake程序进行编译. 2 gmake源码结构 首先打开之前tcc-busybox-for-win32\gmak…...

公司共享网盘怎么建立
公司共享网盘的建立,关键在于明确使用需求、选择合适的网盘服务、搭建统一的文件管理规范、做好权限分级与安全防护。尤其要强调选择合适的网盘服务这一点,如果企业规模较大,且对协同办公的需求强烈,就需要考虑支持多人实时协作、…...

【高分论文密码】AI大模型和R语言的全类型科研图形绘制,从画图、标注、改图、美化、组合、排序分解科研绘图每个步骤
在科研成果竞争日益激烈的当下,「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点,因此科研绘图已成为成果撰写中的至关重要的一个环节&am…...

深入理解Java中的static关键字及其内存原理
static是Java中实现类级共享资源的核心修饰符,它突破了对象实例化的限制,使得变量和方法能够直接与类本身绑定。这种特性让static成为构建工具类、全局配置等场景的利器,但同时也带来独特的内存管理机制需要开发者关注。 static修饰成员变量…...

linux 系统 之centos安装 docker
对于 CentOS 安装 Docker 的前置条件 首先,需要安装一些必要的软件包, 对于 CentOS 7,可以使用以下命令: sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加 Docker 仓库 设置 Docker 的官方仓库。对于 …...

Python语法核心架构与核心知识点:从理论到实践
一、Python的核心设计哲学 Python以“简洁优雅”为核心理念,遵循以下原则: # Zen of Python(输入 import this 可查看) >>> import this The Zen of Python, by Tim Peters ... Simple is better than complex. Readab…...

FreeRTOS(5)内核控制函数及其他函数
FreeRTOS 提供了一些用于控制内核的 API 函数,这些 API 函数主要包含了进出临界区、开关中断、启停任务调度器等一系列用于控制内核的 API 函数。本章就来学习 FreeRTOS 的内 核控制函数。 内核控制函数 1. 函数 taskYIELD() 此函数用于请求切换任务, …...