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

Linux 基本开发工具的使用(yum、vim、gcc、g++、gdb、make/makefile)

文章目录

  • Linux 软件包管理器 - yum
    • 理解什么是软件包和yum
    • 如何查看/查找软件包
    • 如何安装软件
    • 如何实现本地机器和云服务器之间的文件互传
    • 如何卸载软件
  • Linux 编辑器 - vim 的使用
    • vim 的基本概念
    • vim 的基本操作
    • vim 命令模式各命令汇总
    • vim 底行模式各命令汇总
    • vim 的简单配置
  • Linux 编译器 - gcc / g++ 的使用
    • gcc / g++ 的作用
    • gcc / g++ 语法
    • 预处理
    • 编译
    • 汇编
    • 链接
    • 静态库和动态库
  • Linux 调试器 - gdb 的使用
    • gdb 的安装
    • gdb 的背景
    • gdb 指令汇总
    • gdb 操作对标于Windows下 IDE(vs2022等等)的调试操作
  • Linux 项目自动化构建工具 - make/Makefile 的使用
    • make / Makefile 的重要性
    • 依赖关系和依赖方法
    • 多文件编译
    • make 原理
    • 项目清理
  • 编写 Linux 下的小程序 - 进度条
    • 行缓冲区的概念
    • \r (回车) 与 \n(换行)
    • 进度条小程序

Linux 软件包管理器 - yum

理解什么是软件包和yum

1)Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序。但是这样太麻烦了,于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装。
2)软件包和软件包管理器,就好比 “App” 和 “应用商店” 这样的关系。
3)yum (Yellow dog Updater, Modified) 是 Linux 下非常常用的一种软件包管理器( Linux 下提供的一个软件管家,或者叫做应用商店)。主要应用在Fedora, RedHat,Centos 等发行版上。我们可以通过 yum ,搜素、安装或卸载对应的软件。
4)由于 yum 是从远端服务器上下载 RPM 包,所以在下载时必须联网,而我们可以通过 ping 指令查看当前云服务器是否联网。
在这里插入图片描述

注意:一个服务器同一时刻只允许一个yum进行安装,不能在同一时刻同时安装多个软件。

如何查看/查找软件包

指令:yum list
功能:yum list 指令默认罗列出可供下载的全部软件。
在这里插入图片描述
说明
1)软件包名称:主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。
2)"x86_64(体系结构)"后缀表示64位系统的安装包,"i686"后缀表示32位系统安装包,选择包时要和系统匹配。
3)"el8"表示操作系统发行版的版本,“el8"表示的是"centos8/redhat8”,“el7"表示"centos7/redhat7”。
4)最后一列表示的是“软件源”的名称,类似于“小米应用商店”,“华为应用商店”这样的概念。

默认罗列出所有软件时数目有很多,而这时我们可以使用管道 | 和 行过滤指令 grep 进行过滤搜索
这里我们以查找 lrzsz 为例:

lrzsz 可以将 Windows 当中的文件上传到 Linux 当中,也可以将 Linux 当中的文件下载到 Windows 当中,实现云服务器和本地机器之间进行信息互传。

查找 lrzsz : yum list | grep lrzsz
在这里插入图片描述
执行以上命令之后,系统就可以直接在众多的软件源当中帮我们进行过滤搜素 lrzsz 。

如何安装软件

指令: sudo yum install 软件名

[jack@VM-8-12-opencloudos ~]$ sudo yum install lrzsz

执行以上指令后,yum 会自动找到都有哪些软件包需要下载,这时候可能会询问你是否确认安装,如果确认,敲 “y” 确认即可,当出现 “complete” 字样时,说明安装完成。
如果你不想系统询问你,你可以执行 sudo yum install -y 软件名,此时系统便会不询问而直接安装成功。
注意
1)安装软件时由于需要向系统目录中写入内容,一般需要 sudo 或者切换到 root 账户下才能完成。
2)yum 安装软件只能一个装完了再装另一个,正在使用 yum 安装一个软件的过程中,如果再尝试用 yum 安装另外一个软件,yum 就会报错。

如何实现本地机器和云服务器之间的文件互传

上面我们安装了 lrzsz 软件,现在我们可以来看一下这个软件怎么用。
lrzsz 这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件,安装完毕之后可以通过拖拽的方式将文件上传过去。如下:
在这里插入图片描述
拖拽上传完毕后,ll / ls 我们就可以看到当前目录存在这个文件了
在这里插入图片描述

当然,除了拖拽的方式,我们也可以通过下面的方式来完成本地机器和云服务器之间的文件互传:
1)指令:rz -E
通过该指令可选择需要从本地机器上传到云服务器的文件。
在这里插入图片描述
2)指令: sz 文件名
该指令可将云服务器上的文件下载到本地机器的指定文件夹。
在这里插入图片描述

如何卸载软件

指令: sudo yum remove 软件名

[jack@VM-8-12-opencloudos ~]$ sudo yum remove lrzsz

当执行以上命令后,yum会自动卸载该软件,这时候系统也会询问你是否确认卸载,如果确认,敲 “y” 确认卸载即可,当出现 “complete” 字样时,说明卸载完成。
同样,如果你不想系统询问你,你可以执行 sudo yum remove -y 软件名,此时系统便会不询问而直接卸载软件成功。

Linux 编辑器 - vim 的使用

vim 的基本概念

vim 本质上是一个功能强大,多模式的文本编辑器,在我们进行开发的时候,主要解决我们编写代码的问题。

下面我们主要介绍 vim 最常用的三种模式:命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode)
1)正常/普通/命令模式(Normal mode)
在命令模式下,我们可以控制屏幕光标的移动,字符、字或行的删除,复制粘贴,剪贴以及进入Insert mode下,或者到 last line mode下等操作。
2)插入模式(Insert mode)
只有在插入模式下才能进行文字输入,按「Esc」键可回到命令行模式,该模式是我们使用最频繁的编辑模式。
3)底行模式(Command mode)
在底行模式下,我们可以将文件保存或退出,或者进行文件替换,也可以进行查找字符串、列出行号等操作。在底行模式下我们还可以直接输入vim help-modes 查看当前vim的所有模式。

vim 的基本操作

指令:vim 文件名
作用:进入文件进行编辑

[jack@VM-8-12-opencloudos ~]$ vim test.cpp

vim 进入文件后默认为命令模式(普通模式),如果要输入文字则需切换到插入模式。
在这里插入图片描述
命令模式 切换至 插入模式
1)按 i 键:在当前光标处进入插入模式。
2)按 a 键:在当前光标的后一位置进入插入模式。
3)按 o 键:在当前光标处新起一行进入插入模式。

命令模式 切换至 底行模式
1)按 Shift + : 即可,实际上就是输入 :

插入模式 或 底行模式 切换至 命令模式
1)插入模式或是底行模式切换至命令模式都是直接按一下 Esc 键即可。

vim 命令模式各命令汇总

【移动光标】
1)按 k :光标上移。
2)按 j :光标下移。
3)按 h :光标左移。
4)按 l :光标右移。
5)按 $(Shift + 4 = $) :移动到光标所在行的行尾。
6)按 ^ (Shift + 6 = ^):移动到光标所在行的行首。
7)按 gg :移动到文本开始。
8)按 Shift+g(G) :移动到文本末尾。
9)按 n(行号)+Shift+g(n(具体数字) + G) :移动到第n行行首。
10)按 n+Enter :当前光标向下移动n行。
11)按 w :光标从左到右,从上到下的跳到下一个字的开头。
12)按 e :光标从左到右,从上到下的跳到下一个字的结尾。
12)按 b :光标从右到左,从下到上的跳到上一个字的开头
【删除】
1)按 x :删除光标所在位置的字符。
2)按 nx :删除光标所在位置开始往后的n个字符。
3)按 X :删除光标所在位置的前一个字符。
4)按 nX :删除光标所在位置的前n个字符。
5)按 dd :删除光标所在行。
6)按 ndd :删除光标所在行开始往下的n行。
【复制粘贴】
1)按 yy :复制光标所在行到缓冲区。
2)按 nyy :复制光标所在行开始往下的n行到缓冲区。
3)按 yw :将光标所在位置开始到字尾的字符复制到缓冲区。
4)按 nyw :将光标所在位置开始往后的n个字复制到缓冲区。
5)按 p :将已复制的内容在光标的下一行粘贴上。
6)按 np :将已复制的内容在光标的下一行粘贴n次。
【剪切】
1)按 dd :剪切光标所在行。
2)按 ndd :剪切光标所在行开始往下的n行。
3)按 p :将已剪切的内容在光标的下一行粘贴上。
4)按 np :将已剪切的内容在光标的下一行粘贴n次。
【撤销】
1)按 u :撤销。
2)按 Ctrl+r :恢复刚刚的撤销。
【大小写切换】
1)按 ~ :完成光标所在位置字符的大小写切换。
2)按 n~ :完成光标所在位置开始往后的n个字符的大小写切换。
【替换】
1)按 r :替换光标所在位置的字符。
2)按 R :替换光标所到位置的字符,直到按下「Esc」键为止。
【更改】
1)按 cw :将光标所在位置开始到字尾的字符删除,并进入插入模式。
2)按 cnw :将光标所在位置开始往后的n个字删除,并进入插入模式。
【翻页】
1)按 Ctrl+b :上翻一页。
2)按 Ctrl+f :下翻一页。
3)按 Ctrl+u :上翻半页。
4)按 Ctrl+d :下翻半页。

vim 底行模式各命令汇总

在使用底行模式之前,先按 Esc 键确定你已经处于命令模式,再按 Shift + : 即可进入底行模式

【行号设置】
1) set nu :显示行号。
2) set nonu :取消行号。
【保存退出】
1) w :保存文件。
2) q :退出 vim,如果无法离开 vim,可在 q 后面跟一个 ! (即 q!)表示强制退出。
3) wq :保存退出。
【分屏指令】
1) vs 文件名 :实现多文件的编辑。
2) Ctrl+w+w :光标在多屏幕下进行切换。
【执行指令】
1) !+指令 :在不退出vim的情况下,可以在指令前面加上 ! 就可以执行 Linux 的指令,例如查看目录、编译当前代码等。

vim 的简单配置

配置文件的位置
1)在目录 /etc/ 下面,有个名为 vimrc 的文件,这是系统中公共的配置文件,对所有用户都有效。
2)在每个用户的主目录 /home/xxx 下,都可以自己建立私有的配置文件,命名为 “.vimrc” ,这是该用户私有的配置文件,仅对该用户有效。

例如,普通用户在自己的主目录下建立了 “.vimrc” 文件后,在文件当中输入 set nu 指令并保存,下一次打开vim 的时候就会自动显示行号。

vim 的配置比较复杂,某些 vim 配置还需要使用插件,建议不要自己一个个去配置。比较简单的方法是直接在 shell 中执行以下指令(想在哪个用户下让 vim 配置生效, 就在哪个用户下执行这个指令. 强烈 “不推荐” 直接在 root 下执行):

curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh

执行之后需要按照提示输入 root 密码. 您的 root 密码不会被上传, 请放心输入.
在这里插入图片描述
然后等待安装配置,最后手动执行 source ~/.bashrc 即可。
在这里插入图片描述
配置完成后,像什么自动补全、行号显示以及自动缩进什么的就都有了。

注意:以上的一键配置目前只支持 Centos7 x86_64. 如果你的系统不是 Centos7 x86_64. 只能像小编一样前往你自己的服务器中重装系统切换镜像到 Centos7 x86_64. 不然就只能手动配置 vim (网上搜有,不过比较麻烦,还有一些插件)
在这里插入图片描述

Linux 编译器 - gcc / g++ 的使用

gcc / g++ 的作用

gcc 和 g++ 分别是 GNU 的 C 和 C++ 的编译器,gcc 和 g++ 在执行编译的时候一般有以下四个步骤:
1)预处理(头文件展开、去注释、宏替换、条件编译)。( 文件后缀:.i )
2)编译(把C代码翻译成汇编语言)。(文件后缀:.s)
3)汇编(汇编代码转为二进制可重定位目标代码)。(文件后缀:.o)
4)链接(将汇编过程产生的二进制代码进行链接)。

gcc / g++ 语法

语法: gcc/g++ [选项] 要编译的文件 [选项] [目标文件]
常用选项:
1)-E 只进行预处理,这个不生成文件,你需要把他重定向到一个输出文件里面(否则将把预处理后的结果打印到屏幕上)。
2)-S 编译到汇编语言,不进行汇编和链接,即只进行预处理和编译。
3)-c 编译到目标代码 (汇编语言翻译成二进制目标文件)
4)-o 将处理结果输出到指定文件,该选项后需紧跟输出文件名。
5)-static 此选项对生成的文件采用静态链接。
6)-g 生成调试信息(若不携带该选项则默认生成release版本)。
7)-shared 此选项将尽量使用动态库,生成文件较小。
8)-w 不生成任何警告信息。
9)Wall 生成所有警告信息。
10)-O0/-O1/-O2/-O3 编译器优化选项的四个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。

辅助记忆:E(预处理),S(编译),c(汇编):ESc ->键盘左上角的 Esc 键

预处理

指令:gcc -E test.c -o test.i

1)预处理功能主要包括头文件展开、去注释、宏替换、条件编译等。
2)预处理指令是以 # 开头的代码行。
3)-E 选项的作用是让 gcc/g++ 在预处理结束后停止编译过程。
4)-o 选项是指目标文件,“xxx.i” 文件为已经过预处理的原始程序。

在这里插入图片描述

编译

指令:gcc -S test.i -o test.s

1)在这个阶段中,gcc/g++ 首先检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,将代码翻译成汇编语言。
2)用户可以使用 -S 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
3)-o选项是指目标文件,“xxx.s” 文件为已经过翻译的原始程序。

在这里插入图片描述

汇编

指令:gcc -c test.s -o test.o

1)汇编阶段是把编译阶段生成的 “xxx.s” 文件转成目标文件
2)读者在此可使用选项 “-c” 就可看到汇编代码已转化为 “xxx.o” 的二进制目标代码了

在这里插入图片描述
小贴士:执行 od test.o 就能以二进制代码的方式查看原来的 test.o 文件。
注意:这里的二进制文件(可重定向目标二进制)还不能执行,需要链接之后才能变成可执行文件。链接形象来说就是:把你写的代码和 c/cpp 标准库中的代码合起来。

链接

指令:gcc test.o -o test
1)在成功完成以上步骤之后,就进入了链接阶段。
2)链接的主要任务就是将生成的各个 “xxx.o” 文件进行链接,生成可执行文件。
3)gcc/g++ 不带 -E、-S、-c 选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
4)若不用 -o 选项指定生成文件的文件名,则默认生成的可执行文件名为 a.out。
在这里插入图片描述
注意:链接后生成的也是二进制文件

想了解更多的更详细内容点击这里。

静态库和动态库

以上内容我们涉及到了一个函数库的内容,我们知道我们的 C 程序中,并没有定义“printf” 函数的实现(我们打代码 printf 并不是实现 printf 函数,而是调用 printf 函数),且在预编译中包含的 “stdio.h” 头文件中也只有该函数的声明,而没有定义函数的实现,那是在哪里实现 “printf” 函数的呢?
答案是:系统把这些函数实现都写到一个名为 libc.so.6 的库中,在没有指定时,gcc 会到系统默认的搜索路径 “/usr/lib” 下进行查找,然后链接到 libc.so.6 的库去,这样就有了 printf 函数的实现了,这也就是链接的作用。

这里我们引出了一个函数库的内容,而函数库一般分为静态库动态库两种: Windows下静态库后缀名一般为 .lib 动态库后缀名一般为 .dll

1)静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了,静态库后缀名一般为 “.a” 。
2)动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中而是在程序执行时由运行时链接文件加载到库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库.gcc 在编译时默认使用动态库完成了链接之后,gcc 就可以生成可执行文件。

动态链接:
 优点:省空间(节省资源,磁盘的空间,内存的空间),bin 体积小,加载速度快(运行时加载到内存中) 。
 缺点:依赖动态库,程序可移植性较差。
静态链接:
 优点:不依赖第三方库(形成可执行程序以后),程序的可移植性较高
 缺点:浪费空间。

gcc / g++ 默认生成的二进制程序是动态链接的,这点我们可以通过 file 命令来验证:
在这里插入图片描述
其次,我们还可以使用 ldd 指令查看动态链接的可执行文件所依赖的库。
在这里插入图片描述
小贴士:上面图中的 /lib64/libc.so.6 就是当前云服务器当中的C标准库。

虽然 gcc和g++ 默认采用的是动态链接,但是如果我们想要使用静态链接,带上 -static 选项就可以实现。
指令:gcc test.c -o test_s -static

小贴士:如果上面这条指令无法执行,则需要安装静态库 g++ 和 gcc 的选项、动静态库链接没有任何差别,可能需要下载静态库libc.a
安装C静态库 & C++ 静态库指令如下:
C 静态库:sudo yum install -y glibc-static
C++静态库:sudo yum install -y libstdc+±static

执行上面指令后生成的可执行文件便是静态链接的了:
在这里插入图片描述
我们通过对比源代码相同,但链接方式不同而生成的两个可执行程序 test 和 test_s 的大小,可以看到静态链接的文件大小比动态链接的文件的大小大很多,这也验证了动态链接比较节省空间,而静态链接比较浪费空间这点。
在这里插入图片描述

Linux 调试器 - gdb 的使用

gdb 的安装

当我们第一次使用 gdb 的时候,系统会告知我们命令找不到,这时候我们就需要自行安装一下 gdb :
指令:sudo yum install -y gdb

gdb 的背景

进入 gdb:
指令:gdb 可执行程序文件名

程序发布方式:
 1)debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
 2)release版本:不会添加任何调试信息,是不可调试的。
小贴士:在 Windows下的 VS 想要调试也需要在 debug 模式下。

拓展:为什么有了debug 版本,还要有 release 版本呢?(为什么要有两个版本呢)
release 是给客户去用的,而对于程序员,要经常进行代码编写、调试代码等等,那就必须以 debug 版本发布来保证他的程序是便于调试的,而作为客户不需要关心debug,客户不需要得到他不需要的东西。程序员需要调试,而用户用不到也不关心。
release 版本只是单纯软件的功能,没有加任何的调试信息。

在Linux当中 gcc/g++ 默认生成的可执行程序是 release 版本的,是不可被调试的(包括 l 看不了代码,r 也跑不起来)。如果想生成 debug 版本,就需要在使用 gcc/g++ 生成可执行程序时加上 -g 选项:
在这里插入图片描述
在这里插入图片描述

对同一份源代码分别生成其 release 版本和 debug 版本的可执行程序,可以看到,debug 版本发布的可执行程序的大小比 release 版本发布的可执行程序的大小要大一点,其原因就是以 debug 版本发布的可执行程序当中包含了更多的调试信息:
在这里插入图片描述

gdb 指令汇总

我们先来写一个程序,下面所有操作都基于这个程序:
在这里插入图片描述
进入gdb
指令: gdb 可执行程序文件名

调试
1)run / r :运行代码(启动调试),有断点在断点处停下来。
在这里插入图片描述
2)next / n :逐过程调试。
在这里插入图片描述
3)step / s :逐语句调试。(遇到函数会进入函数里面)
在这里插入图片描述

4)until 行号:跳转至指定行。
可以用于跳出循环。

5)finish:执行完当前正在调用的函数后停下来(不能是主函数)。
不进入函数调试,也不从一个断点运行到下一个断点,只单纯把这一个函数跑完。
finsh 方便我们快速把代码跑完,排查代码问题。(直接进入函数,finsh,如果代码有误会直接停下来,就不用在函数里面逐语句排查问题,方便我们快速找到代码出错的范围)

6)continue / c :运行到下一个断点处。(有多个断点时由一个断点运行到下一个断点)
7)set var 变量=x:修改变量的值为x。

显示
1)list / l n:显示从第n行开始的源代码,每次显示10行,若n未给出则默认从上次的位置往下显示.。
在这里插入图片描述

2)list / l 函数名:显示该函数的源代码。
3)print / p 变量:打印变量的值。
4)print / p &变量:打印变量的地址。
5)print / p 表达式:打印表达式的值,通过表达式可以修改变量的值。
6)display 变量:将变量加入常显示(每次停下来都显示它的值)。
类似于 Windows下的窗口,用于监控变量。

7)display &变量:将变量的地址加入常显示。
8)undisplay 编号:取消指定编号变量的常显示。(记住是编号)
类似于 Windows下的取消窗口,不想再监控这个变量了。就取消。

9)bt:查看各级函数调用及参数。(查看函数的调用堆栈)
在这里插入图片描述
10)info / i locals:查看当前栈帧当中局部变量的值。

断点
1)break / b n:在第n行设置断点。
在这里插入图片描述

2)break / b 函数名:在某函数体内第一行设置断点。

3)info breakpoint / b:查看已打断点信息。
在这里插入图片描述

4)delete / d 编号:删除指定编号的断点。(编号不是行号,记住了)
在这里插入图片描述

5)disable 编号:禁用指定编号的断点。(保留痕迹,断点不生效)
disable 之后,再次 info b,对应断点的 Enb 那项显示 n;生效的显示 y。可以看看上图。

6)enable 编号:启用指定编号的断点。

退出gdb
1)quit / q:退出gdb。

gdb 操作对标于Windows下 IDE(vs2022等等)的调试操作

在这里插入图片描述
注意:以上 IDE 调试有些电脑需要配合 Fn 按键一起才能生效。

Linux 项目自动化构建工具 - make/Makefile 的使用

make / Makefile 的重要性

1)会不会写 Makefile / makefile,从侧面说明了一个人是否具备完成大型工程的能力。
2)一个工程的源文件不计其数,按照其类型、功能、模块分别放在若干个目录当中,Makefile 定义了一系列的规则来指定:哪些文件需要先编译,哪些文件需要后编译,甚至于进行更复杂的功能操作。
3)Makefile 带来的好处就是“自动化编译”,一旦写好,只需一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。
4)make 是一个命令工具,是一个解释 Makefile 当中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,例如:Delphi 的 make,Visual 中 C++的 nmake,Linux 下 GNU 的 make。可见,Makefile都成为了一种在工程方面的编译方法。
5)make是一条命令,Makefile是一个文件,两个搭配使用,完成项目自动化构建。

依赖关系和依赖方法

在使用 make / Makefile 前我们首先应该理解各个文件之间的依赖关系以及它们之间的依赖方法。
1)依赖关系: 文件A的变更会影响到文件B,那么就称文件B依赖于文件A。
例如,test.o 文件是由 test.c 文件通过预处理、编译以及汇编之后生成的文件,所以 test.c 文件的改变会影响test.o,所以说 test.o 文件依赖于 test.c 文件。

2)依赖方法: 如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法。
例如,test.o 依赖于 test.c,而 test.c 通过 gcc -c test.c -o test.o指令就可以得到 test.o,那么 test.o 依赖于test.c 的依赖方法就是 gcc -c test.c -o test.o 。

多文件编译

当你的工程当中有多个源文件的时候,我们可以直接使用 gcc 指令对多个源文件进行编译,进而生成可执行程序:
在这里插入图片描述
但是进行多文件编译的时候一般不使用源文件直接生成可执行程序,而是先用每个源文件各自生成自己的二进制文件,然后再将这些二进制文件通过链接生成可执行程序。
在这里插入图片描述

原因:
1)若是直接使用源文件生成可执行程序,那么其中一个源文件进行了修改,再生成可执行程序的时候就需要将所以的源文件重新进行编译链接。
2)而若是先用每个源文件各自生成自己的二进制文件,那么其中一个源文件进行了修改,就只需重新编译生成该源文件的二进制文件,然后再将这些二进制文件通过链接生成可执行程序即可。
注意: 编译链接的时候不需要加上头文件,因为编译器通过源文件的内容可以知道所需的头文件名字,而通过头文件的包含方式( “尖括号” 包含和 “双引号” 包含),编译器可以知道应该从何处去寻找所需头文件。

但是问题来了:如果源文件有很多,我们每次重新生成可执行程序时,所需输入的gcc 指令的长度与个数也会随之增加,这时我们就需要使用 make 和 Makefile 了,这将大大减少我们的工作量。
那如何使用 make / makefile 呢?
步骤一: 在源文件所在目录下创建一个名为 makefile / Makefile 的文件。
步骤二: 编写 makefile 文件。
makefile 文件最简单的编写格式是,先写出文件的依赖关系,然后写出这些文件之间的依赖方法,依次写下去。
注意:依赖关系下面一行,必须是以 tab 键开头再写依赖方法。

在这里插入图片描述
编写完毕Makefile文件后保存退出,然后在命令行当中执行make指令便可以生成可执行程序,以及该过程产生的中间产物。
在这里插入图片描述

Makefile文件的简写方式:
$@:表示依赖关系中的目标文件(冒号左侧)。
$^:表示依赖关系中的依赖文件列表(冒号右侧全部)。
$<:表示依赖关系中的第一个依赖文件(冒号右侧第一个)。
例如上面 makefile 文件可以简写为:
在这里插入图片描述
说明: gcc / g++ 携带 -c 选项时,若不指定输出文件的文件名,则默认输出文件名为 xxx.o,所以这里也可以不用指定输出文件名。

make 原理

理解 makefile 的推导规则:
先看一个例子:
当 makefile 里面的内容是:
mycode:mycode.o
gcc mycode.o -o mycode
mycode.o:mycode.s
gcc -c mycode.s -o mycode.o
mycode.s:mycode.i
gcc -S mycode.i -o mycode.s
mycode.i:mycode.c
gcc -E mycode.o -o mycode.i

执行make 的时候;顺序是
gcc -E mycode.o -o mycode.i
gcc -S mycode.i -o mycode.s
gcc -c mycode.s -o mycode.o
gcc mycode.o -o mycode
所以 makefile 从上往下扫描的时候,并不会直接执行第一个依赖方法,因为 mycode.o并不存在,所以他会先去找 mycode.o ;以此类推。跟栈结构一样

1)make 会在当前目录下找名字为 “Makefile” 或 “makefile” 的文件。
2)如果找到,它会找文件当中的第一个目标文件,在上面的例子中,它会找到 mytest 这个文件,并把这个文件作为最终的目标文件。
3)如果 mytest 文件不存在,或是 mytest 所依赖的后面的 test.o 文件和 main.o 文件的文件修改时间比 mytest文件新,那么它就会执行后面的依赖方法来生成 mytest 文件。
4)如果 mytest 所依赖的 test.o 文件不存在,那么 make 会在 Makefile 文件中寻找目标为 test.o 文件的依赖关系,如果找到则再根据其依赖方法生成 test.o 文件(类似于堆栈的过程)。
5)当然,你的 test.c 文件和 main.c 文件是存在的,于是 make 会生成 test.o 文件和 main.o 文件,然后再用test.o 文件和 main.o 文件生成最终的 mytest 文件。
6)make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7)在寻找的过程中,如果出现错误,例如最后被依赖的文件找不到,那么 make 就会直接退出,并报错。

项目清理

在我们每次重新生成可执行程序前,都应该将上一次生成可执行程序时生成的一系列文件进行清理,但是如果我们每次都手动执行一系列指令进行清理工作的话,未免有些麻烦,因为每次清理时执行的都是相同的清理指令,这时我们可以将项目清理的指令也加入到 Makefile 文件当中。
在这里插入图片描述
注意: 一般将这种 clean 的目标文件设置为伪目标,用.PHONY修饰,伪目标的特性是:总是被执行。

像 clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,但我们可以显示要 make 执行。
在这里插入图片描述

拓展知识:在这里插入图片描述

编写 Linux 下的小程序 - 进度条

行缓冲区的概念

我们先来看一段代码:
在这里插入图片描述
对于上面的代码,大家并不陌生,当我们 gcc 编译以上代码以后,./执行可执行程序,可以看到程序先输出字符串 hello linux 然后休眠 10秒 之后结束运行。
那我们再来看一段代码:
在这里插入图片描述
我们可以看到,两段代码只相差了一个 \n 换行符,那当我们 gcc 编译以上代码以后,./执行可执行程序,看到的结果还是和上面一样吗?答案是否定的,该代码的运行结果是:先休眠10秒,然后再打印字符串hello linux,然后结束运行。为什么呢?这里我们可以看到了行缓冲区的存在。
上面第二段代码首先执行的仍然是 printf ,再执行 sleep ;但是显示器对应的是行刷新,即当缓冲区当中遇到 ’\n’ 或是缓冲区被写满才会被打印出来,而在第二份代码当中并没有 ’\n’ ,所以字符串 hello linux 先被写到缓冲区当中去了,然后休眠 10 秒后,直到程序运行结束时才将 hello linux 打印到显示器当中。\n 默认打印的时候往显示器上打,\n 叫行缓存。
在这里缓冲区我们不过多介绍,后面文章会详细说,我们这里只需要知道缓冲区就是一块内存即可,那如果我们执行第二段代码,想让 hello linux 立即打印出来,而不是休眠之后再打印,该怎么做呢?很简单,我们使用 fflush 函数刷新一下缓冲区即可,如下:
在这里插入图片描述

\r (回车) 与 \n(换行)

\r: 回车,使光标回到当前行的行首。
\n: 换行,使光标下移一格(并没有回到行首)。在语言层面是回车换行。
Enter键:回车换行,等价于 \n + \r 。
我们知道 \r 是使光标回到本行行首,那么如果我们向显示器上写了一个数之后再让光标回到本行行首,然后再写一个数,不就相当于将前面一个数字覆盖了吗?
所以这里有一个问题:不使用 ’\n’ 进行换行怎么将缓冲区当中数据打印出来?
答案:我们可以使用 fflush 函数,该函数可以刷新缓冲区,即将缓冲区当中的数据刷新当显示器当中。
对此我们可以编写一个倒计时的程序(利用到 \r 覆盖和刷新缓冲区的原理)。

在这里插入图片描述
注意:如果上面程序不刷新缓冲区,则执行程序时什么都不会显示。
\r 让在输出下一个数之前都让光标先回到本行行首,就得到了倒计时的效果。
在这里插入图片描述
gcc 编译程序之后,./a.out 运行程序即可得到倒计时,大家可按上图自行运行试试。

进度条小程序

【百度笔试题】进度条: 不进行换行,从左至右依次变长
知道了 \r 这个概念我们就可以实现一个简单的进度条了。
代码
在这里插入图片描述
小贴士:上面用 usleep 函数的原因是:sleep 函数以秒为单位,刷新太慢了。
注意:
1)如果这里的程序不刷新缓冲区,执行程序时什么都不会显示。
2)%100s 默认右对齐(如果用这个,进度条会从右往左打),%-100s 默认左对齐

3)关于转义字符:
注意 \ 为特殊字符需要转义 ,\ 代表的就是
% 也是特殊字符,也需要转义 ,%% 代表的就是 %

gcc 编译代码以后,./ 执行可执行程序的效果如下:
在这里插入图片描述
除此之外,我们还可以给进度条加上颜色,让进度条更好看。
代码:
在这里插入图片描述
gcc 编译代码以后,./ 执行可执行程序的效果如下:
在这里插入图片描述
这里是学习 printf 输出颜色的一个链接,感兴趣的可以看看。

相关文章:

Linux 基本开发工具的使用(yum、vim、gcc、g++、gdb、make/makefile)

文章目录 Linux 软件包管理器 - yum理解什么是软件包和yum如何查看/查找软件包如何安装软件如何实现本地机器和云服务器之间的文件互传如何卸载软件 Linux 编辑器 - vim 的使用vim 的基本概念vim 的基本操作vim 命令模式各命令汇总vim 底行模式各命令汇总vim 的简单配置 Linux …...

idea创建第一个springboot程序

说明&#xff1a; 我计划用idea&#xff0c;创建第一个springboot程序&#xff0c;但是作为新手完全不会弄&#xff0c;今天我就亲自尝试一边&#xff0c;并且出一期详细&#xff0c;完美的教程&#xff0c;亲测可以运行 step1. 点击file &#xff0c; 选new&#xff0c; 选…...

python 使用 venv 创建虚拟环境 (VSCode)

Python 自带了一个名为 venv 的模块&#xff0c;可以用来创建虚拟环境。这是 Python 官方推荐的方式&#xff0c;不需要额外安装 Anaconda 或其他工具。 假设项目名为myproject&#xff0c;进入到项目目录 cd myproject 创建虚拟环境 python3 -m venv 虚拟环境名&#xff08…...

组态软件在物联网中的应用

随着物联网的快速发展&#xff0c;组态软件在物联网中的应用也越来越广泛。组态软件是一种用于创建和管理物联网系统的可视化工具&#xff0c;它能够将传感器、设备和网络连接起来&#xff0c;实现数据的采集、分析和可视化。本文将探讨组态软件在物联网中的应用&#xff0c;并…...

字节火山引擎-大模型声音复刻,流式语音合成接口

字节火山引擎-大模型声音复刻&#xff0c;流式语音合成接口 参考文档&#xff1a;火山引擎-大模型声音复刻文档 官网给出的示例代码有bug&#xff0c;这里已经修改了 创建应用 声音复刻大模型页面查看应用&#xff0c;获取接口调用需要的参数 注意调用tts接口时候需要三个参数…...

QT:Graphics View的坐标系介绍

在 Qt 的 Graphics View 框架中&#xff0c;存在三种不同的坐标系&#xff0c;分别是 物品坐标系&#xff08;Item Coordinates&#xff09;、场景坐标系&#xff08;Scene Coordinates&#xff09; 和 视图坐标系&#xff08;View Coordinates&#xff09;。这三种坐标系在图形…...

轻松搭建:使用Anaconda创建虚拟环境并在PyCharm中配置

一、使用Anaconda创建虚拟环境 1. 安装Anaconda 2..conda常用的命令 3. 创建虚拟环境-以搭建MachineVision为例 4. 激活虚拟环境 5. 安装依赖包 二、PyCharm配置环境 在进行Python项目开发时&#xff0c;合理的环境管理是必不可少的&#xff0c;特别是当你在多个项目中…...

Unity TMPro显示中文字体

TMP默认的字体只能显示英语&#xff0c;那么怎么显示中文呢 1、找到支持中文的字体文件 在c盘搜索Fonts文件夹有很多支持中文的字体文件 我这里选择雅黑 PS.双击打开发现里面有粗体细体普通三个版本&#xff0c;也可以只导入一个版本进去 2、将其拖入到unity Assets里面 3…...

【嵌入式原理设计】实验五:远程控制翻盖设计

目录 一、实验目的 二、实验环境 三、实验内容 四、实验记录及处理 五、实验小结 六、成果文件提取链接 一、实验目的 熟悉和掌握舵机及串口控制方式 二、实验环境 Win10ESP32实验开发板 三、实验内容 1、熟悉舵机的控制方式&#xff1b; 2、用串口发…...

矩阵乘积态简介

定义 矩阵乘积态&#xff08;Matrix Product State, MPS&#xff09;是一种用于表示量子多体系统的强大工具&#xff0c;特别是在一维系统中。MPS 是一种张量网络状态&#xff0c;它通过将全局量子态分解为一系列局部张量的乘积来有效地表示量子态。 注释&#xff1a; 量子态表…...

国自然面上项目|基于肺癌精准靶向治疗的基因影像组学研究|基金申请·25-02-26

小罗碎碎念 今天和大家分享一个国自然面上项目&#xff0c;执行年限为2019.01&#xff5e;2022.12&#xff0c;直接费用为57万元。 项目旨在解决肺癌靶向治疗耐药问题&#xff0c;通过整合多组学和影像组学技术构建预测模型。 研究期间&#xff0c;对非小细胞肺癌 CT 影像组学…...

OA办公系统自动渗透测试过程

目录 一、下载环境源码 二、部署环境 三、测试 XSS漏洞 SQL注入 文件上传漏洞 一、下载环境源码 OA源码打包地址: https://download.csdn.net/download/weixin_43650289/90434502?spm=1001.2014.3001.5503 二、部署环境...

Fisher信息矩阵(Fisher Information Matrix,简称FIM)

Fisher信息矩阵简介 Fisher信息矩阵&#xff08;Fisher Information Matrix&#xff0c;简称FIM&#xff09;是统计学和信息理论中的一个重要概念&#xff0c;广泛应用于参数估计、统计推断和机器学习领域。它以统计学家罗纳德费希尔&#xff08;Ronald Fisher&#xff09;的名…...

nginx反向代理以及负载均衡(常见案例)

一、nginx反向代理 1、什么是代理服务器&#xff1f; 代理服务器&#xff0c;客户机在发送请求时&#xff0c;不会直接发送给目的主机&#xff0c;而是先发送给代理服务器&#xff0c;代理服务接受客户机请求之后&#xff0c;再向主机发出&#xff0c;并接收目的主机返回的数据…...

LabVIEW形状误差测量系统

在机械制造领域&#xff0c;形状与位置公差&#xff08;GD&T&#xff09;直接影响装配精度与产品寿命。国内中小型机加工企业因形状误差导致的返工率高达12%-18%。传统测量方式存在以下三大痛点&#xff1a; ​ 设备局限&#xff1a;机械式千分表需人工读数&#xff0c;精度…...

将VsCode变得顺手好用(1

目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹&#xff0c;用于放置调试文件以及你未来写的代码&#xff0c;随便命名但…...

排序模板——C++

0.排序模板题目 题目描述 将读入的 N 个数从小到大排序后输出。 输入格式 第一行为一个正整数 N。 第二行包含 N 个空格隔开的正整数 ai​&#xff0c;为你需要进行排序的数。 输出格式 将给定的 N 个数从小到大输出&#xff0c;数之间空格隔开&#xff0c;行末换行且无空格。 …...

HTTP/HTTPS 服务端口监测的简易实现

一 HTTP/HTTPS 服务端口监测的简易实现方法 在当今快节奏的工作环境中&#xff0c;工作忙碌成为了许多职场人的常态。就拿我们团队最近经历的事情来说&#xff0c;工作任务一个接一个&#xff0c;大家都在各自的岗位上争分夺秒地忙碌着。然而&#xff0c;就在这样高强度的工作…...

快速入门——状态管理VueX

Vuex介绍 状态管理 每一个Vuex应用的核心都是一个store&#xff0c;与普通的全局对象不同的是&#xff0c;基于Vue数据与视图绑定的特点&#xff0c;当store中的状态发生变化时&#xff0c;与之绑定的视图也会被重新渲染。 store中的状态不允许被直接修改&#xff0c;改变sto…...

C# 根据Ollama+DeepSeekR1开发本地AI辅助办公助手

在上一篇《访问DeepSeekR1本地部署API服务搭建自己的AI办公助手》中&#xff0c;我们通过通过Ollama提供的本地API接口用Python实现了一个简易的AI办公助手&#xff0c;但是需要运行Py脚本&#xff0c;还比较麻烦&#xff0c;下面我们用C#依据Ollama提供的API接口开发一个本地A…...

Flutter - 基础Widget

Flutter 中万物皆 Widget&#xff0c;基础Widget 同步对应 Android View. 普通文本 Text /*** 控制文本样式统一使用 style:TextStyle, 例&#xff1a;fontSize(字体大小),color(颜色),shadows(阴影)等等* 控制文本布局需单独设置&#xff1a;* textAlign(文不对齐方式)* te…...

Tips :仿真竞争条件 指的是什么?

文章目录 **为什么会出现仿真竞争条件?****典型场景举例****System Verilog 如何解决竞争条件?****1. 使用 `program` 块隔离测试平台****2. 使用 `clocking` 块明确时序关系****3. 非阻塞赋值(`<=`)的合理使用****竞争条件的根本原因****总结****代码结构****1. 设计模…...

【Elasticsearch】script_fields 和 runtime_fields的区别

script_fields和runtime_fields都是 Elasticsearch 中用于动态计算字段值的功能&#xff0c;但它们在实现方式、应用场景和性能表现上存在显著区别。以下是两者的详细对比&#xff1a; 1.定义和应用场景 • script_fields&#xff1a; • 定义&#xff1a;通过 Painless 脚本…...

达梦DTS数据迁移工具生产篇(MySQL->DM8)

本文章使用的DTS工具为 2024年9月18日的版本&#xff0c;使用的目的端DM8数据库版本为2023年12月的版本&#xff0c;注意数据库版本和DTS版本之间跨度不要太大&#xff0c;以免出现各种兼容性的报错。若发现版本差距过大时&#xff0c;请联系达梦技术服务工程师处理。 1. 迁移…...

【安卓逆向】逆向APP界面UI修改再安装

1.背景 有一客户找到我&#xff0c;说能不能把APP首页的底部多余界面去掉。 逆向实战 想要去除安卓应用软件中的内容&#xff0c;需要对APP逆向进行修改再打包。 通过工具 MIT管理器工具 提取APK包&#xff0c;点击apk文件&#xff0c;点击查看反编译apk。 搜索关键字。这里关键…...

企业级大模型应用的Java-Python异构融合架构实践

一、后端语言相关技术生态 Python语言 Python在AI计算领域拥有全面的生态支持&#xff1a; 底层工具库: Pandas、NumPy、SciPy、Matplotlib深度学习框架: PyTorch、TensorFlow领域专用框架: HuggingFace Transformers&#xff08;社区生态为主&#xff09; 常见Python框架 …...

深度剖析数据中台架构图,铸造数字文明的基石

🔥🔥 AllData大数据产品是可定义数据中台,以数据平台为底座,以数据中台为桥梁,以机器学习平台为中层框架,以大模型应用为上游产品,提供全链路数字化解决方案。 ✨奥零数据科技官网:http://www.aolingdata.com ✨AllData开源项目:https://github.com/alldatacenter/a…...

python实现基于文心一言大模型的sql小工具

一、准备工作 注册与登录&#xff1a; 登录百度智能云千帆控制台&#xff0c;注册并登录您的账号。 创建千帆应用&#xff1a; 根据实际需求创建千帆应用。创建成功后&#xff0c;获取AppID、API Key、Secret Key等信息。如果已有千帆应用&#xff0c;可以直接查看已有应用的AP…...

飞腾腾锐D2000 + OpenHarmony 4.1release部署deepseek大模型

简介 1.1 飞腾腾锐D2000 飞腾腾锐D2000是一款面向桌面应用的高性能通用处理&#xff0c;集成8个飞腾自主研发的高能效处理器核FTC663&#xff0c;兼 容64位ARMv8指令集并支持ARM64和ARM32两种执行模式&#xff0c;支持单精度、双精度浮点运算指令和ASIMD处理 指令&#xff0c;主…...

进程概念、PCB及进程查看

文章目录 一.进程的概念进程控制块&#xff08;PCB&#xff09; 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序&#xff0c;而程序是存放在磁盘的&#xff0c;cpu要想执行程序的指…...

Oracle 数据库基础入门(一):搭建数据管理基石

在当今数字化时代&#xff0c;数据库作为数据管理的核心工具&#xff0c;对于各类应用系统的开发至关重要。尤其是在 Java 全栈开发领域&#xff0c;掌握一款强大的数据库技术是必备技能。Oracle 数据库以其卓越的性能、高度的可靠性和丰富的功能&#xff0c;在企业级应用中广泛…...

selenium如何实现,开启浏览器的开发者工具模式,并且开启 toggle移动设备模拟模式

核心实现代码 pythonCopy Code from selenium import webdriver from selenium.webdriver.chrome.options import Options def enable_devtools_with_toggle(): options Options() # 强制开启开发者工具 options.add_argument("--auto-open-devtools-for-tabs&quo…...

分布式锁实现(数据库+Redis+Zookeeper)

1. 数据库分布式锁 实现原理 基于唯一索引&#xff1a; 创建一张锁表&#xff0c;通过唯一索引&#xff08;如锁名称&#xff09;保证互斥性。 加锁&#xff1a;插入一条记录&#xff0c;成功则获取锁&#xff0c;失败则重试。 解锁&#xff1a;删除对应记录。 乐观锁&…...

七、Spring Boot:初识与项目搭建

深入解析 Spring Boot&#xff1a;初识与项目搭建 Spring Boot 是基于 Spring Framework 的开源 Java 基础框架&#xff0c;旨在简化 Spring 应用的开发过程。它通过“约定优于配置”的理念&#xff0c;极大地减少了开发中的配置工作&#xff0c;同时提供了“开箱即用”的功能…...

记录一下用docker克隆某授权制定ip的环境恢复

#首先还是要看日志根据问题去进行调整 java web的老项目配置文件一般是 bin启动里边的脚本 还有conf中的 xml配置文件 再或者就是classes中的配置文件,再或者就是lib中的jar包中的配置文件 1.安装docker 2.创建docker网络 docker network create --driver bridge --subnet…...

【含文档+PPT+源码】基于微信小程序的健康饮食食谱推荐平台的设计与实现

项目介绍 本课程演示的是一款基于微信小程序的健康饮食食谱推荐平台的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...

主流虚拟化技术讲解

目录 VMware vSphere Microsoft Hyper-V KVM&#xff08;Kernel-based Virtual Machine&#xff09; OpenStack VMware vSphere 架构与组件&#xff1a;VMware vSphere 是基于裸金属虚拟化技术的平台&#xff0c;核心组件包括 ESXi 主机和 vCenter Server。ESXi 是虚拟化层…...

java开发——为什么要使用动态代理?

举个例子&#xff1a;假如有一个杀手专杀男的&#xff0c;不杀女的。代码如下&#xff1a; public interface Killer {void kill(String name, String sex);void watch(String name); }public class ManKiller implements Killer {Overridepublic void kill(String name, Stri…...

kotlin 知识点一 变量和函数

在Kotlin中定义变量的方式和Java 区别很大&#xff0c;在Java 中如果想要定义一个变 量&#xff0c;需要在变量前面声明这个变量的类型&#xff0c;比如说int a表示a是一个整型变量&#xff0c;String b表 示b是一个字符串变量。而Kotlin中定义一个变量&#xff0c;只允许在变量…...

将CUBE或3DL LUT转换为PNG图像

概述 在大部分情况下&#xff0c;LUT 文件通常为 CUBE 或 3DL 格式。但是我们在 OpenGL Shader 中使用的LUT&#xff0c;通常是图像格式的 LUT 文件。下面&#xff0c;我将教大家如何将这些文件转换为 PNG 图像格式。 条形LUT在线转换&#xff08;不是8x8网络&#xff09;&am…...

侯捷 C++ 课程学习笔记:类的声明与构造函数

目录 一、类的声明 二、内联函数 三、访问级别 四、构造函数 五、构造函数重载 六、实际应用案例 七、学习心得 一、类的声明 类的声明是定义类的基本结构&#xff0c;包括类的成员变量和成员函数。类的声明分为类头和类体两部分。 类头&#xff08;class head&#xf…...

BGP状态和机制

BGP邻居优化 为了增加稳定性,通常建议实验回环口来建立邻居。更新源:建立邻居和邻居所学习到的路由的下一跳。多跳:EBGP邻居建立默认选哟直连,因为TTL=1,如果非直连,必须修改TTL。命令备注peer 2.2.2.2 connect-interface lo1配置更新源peer 2.2.2.2 ebgp-max-hop 2配置T…...

MongoDB 数据库简介

MongoDB 数据库简介 引言 随着互联网技术的飞速发展,数据已经成为企业的重要资产。为了高效地管理和处理这些数据,数据库技术应运而生。MongoDB作为一种流行的NoSQL数据库,因其灵活的数据模型和高效的数据处理能力,受到了广泛的关注。本文将为您详细介绍MongoDB的基本概念…...

浏览器下载vue.js.devtools,谷歌浏览器和edg浏览器

1、谷歌浏览器下载&#xff1a; 情况一&#xff1a;如果谷歌应用商店可以打开&#xff0c;那么就直接到谷歌应用商店下载&#xff0c;直接搜索vue.js.devtools添加扩展即可。 情况二&#xff1a;谷歌浏览器的谷歌应用商城打不开&#xff0c;那么就百度搜索极简插件找到vue.js.…...

Android AOSP系统裁记录

Android 系统裁剪是指根据需求移除不必要的组件和功能&#xff0c;以优化系统性能、减少存储占用或满足特定设备需求。以下是 Android 系统裁剪的基本步骤&#xff1a; 1. 准备环境 操作系统&#xff1a;推荐使用 Ubuntu 或 macOS。 工具&#xff1a; Android SDK Android N…...

Could not download npm for node v14.21.3(nvm无法下载节点v14.21.3的npm)

场景描述&#xff1a;之前的项目用的是node以前的版本&#xff0c;使用nvm没下载下来&#xff0c;npm命令执行不了 错误如下图&#xff0c;15版本的node同理&#xff0c;下载的都是.exe可执行文件的扩展名&#xff0c;使用npm命令终端无法识别 解决思路&#xff1a;去node官网…...

React进阶之React核心源码解析(三)

React核心源码解析 diff多节点比较diff两轮遍历比较第一轮比较第二轮比较Update 状态更新Concurrent Modediff 多节点比较diff isArray方法比较 节点更新// 更新前 <ul><li key="0" className="before">0<li><li key=...

2025吐槽季第一弹---腾讯云EO边缘安全加速平台服务

前言&#xff1a; 关于EO边缘安全加速平台服务 参照&#xff1a;产品概述,具体如下&#xff1a; 边缘安全加速平台 EO&#xff08;Tencent Cloud EdgeOne&#xff0c;下文简称为 EdgeOne&#xff09;是国内首款基于全新架构的真正一体化的边缘安全加速平台。提供全面的安全防…...

Dify自定义工作流集成指南:对接阿里云百炼文生图API的实现方案

dify工作流的应用基本解释 dify应用发布相关地址&#xff1a;应用发布 | Dify 根据官方教程&#xff0c;我们可以看到dify自定义的工作流可以发布为----工具 这个教程将介绍如何通过工作流建立一个使用阿里云百炼文生图模型。 工具则可以给其他功能使用&#xff0c;如agent…...

WebSocket简单介绍 并接入deepseek

目录 什么是 WebSocket&#xff1f;工作原理&#xff1a; 为什么需要 WebSocket&#xff1f;WebSocket 的优势HTTP 和 WebSocket 的区别WebSocket 的劣势WebSocket 的应用场景WebSocket 握手过程1. 客户端发起握手请求2. 服务器响应握手请求3. 建立连接 WebSocket 事件处理WebS…...