【Linux基础】03 Linux环境基础开发工具使用
1. yum
——软件包管理器
yum
是我们 Linux 预装的一个指令,搜索、下载、、安装对应的软件
yum 相当于 Linux 的应用商店!
安装与卸载
- yum list | grep command
通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用 grep 命令只 筛选出我们关注的包. - yum install [-y] command // sudo or root
安装,直至出现complete
- yum remove command // sudo or root
卸载
2. vim——Linux 编辑器
vim 是一款多模式的编辑器,vim 里面有很多子命令来进行代码的编写操作。
2.1 三种模式
- 普通模式/命令模式(Normal mode):用 vim 命令打开文件就是默认为命令模式。控制屏幕光标移动,字符或行的删除,移动复制某区段及进入插入模式或末行模式下;
- 插入/输入模式(Insert mode):在命令模式下按 i,进入命令模式。只有在此模式下才能进行文字编写。按下 esc 键回到命令行模式;
- 末行模式(Last line mode):文件保存或退出,也可以进行文件替换,查找字符串,显示行号等操作。
基本操作
- 命令模式->插入模式:键入
a
、i
、o
; - 插入模式->命令模式:按下
esc
; - 命令模式->末行模式:键入
:
;
一开始用 vim 就是命令模式,无论处于哪种模式,你都可以按 Esc
就进入命令模式
2.2 命令模式指令集
以下的 n 代表数字 num
移动光标
shift+$
:光标定位在当前行的最右侧结尾处锚点
shift+^
:光标定位在当前行的最左侧开头处锚点
shift+g
:光标定位到文本的最结尾(的开头)
n+shift+g
:光标定位到第 n 行
gg
:光标定位到文本的最开始
h
:左,最左侧,左
j
:下
k
:上 king
l
:右,最右侧,右
w
:按照”单词”在行内进行移动,后
b
:按照”单词“在行内进行移动,前
修改操作
n+ yy
:复制当前行/多行(复制从光标起n 行)
n+p
:在下一行进行粘贴/可以多次粘贴 (粘贴 n 次)
u
:撤销编辑操作,undo
ctrl+r
:对撤销进行撤销
n + dd
:删除/剪切当前行
shift+'=~
:大小写快速切换
替换模式
n+r
:替换当前光标所在字符 (替换 n 个)
shift+r=R
:替换模式
n+x
:删除光标所在字符 (往后删 n 个)
n+shirt+x=X
:向左侧进行局部删除 (往前删 n 个)
小写 x 是光标往后,包括自身。
大写 X 是光标往前
shift+3=#
:高亮要查找的函数名
n
:下一个查找到的函数/字符串名
2.3 末行模式指令集
列出行号
:set nu
保存与退出
:w/q/wq/!/q!/wq!
w
是保存文件,q
是退出,wq
是保存并退出,!
是强制执行
- 多窗口模式
- vs filename
光标在哪一个界面,我们就正在编辑哪一个界面,底行也是一样
光标多终端切换
ctrl+ww:
可以切换文件,进行不同的操作
可以在 A 文件复制内容并且拷贝到 B 文件
跳到文件中的某一行
:n
,再按回车就跳到该行
检索字符
「/关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止;
「? 关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「N」会往前寻找到您要的关键字为止。
区别:前者向下查找,后者向前查找。
前者搭配 n 使用,后者搭配 N 使用。
2.4 视图模式
在正常模式下,输入 ctrl + v
批量注释
用 j、k
选中要注释的行,选好后按 shift+i
进入插入模式,再输入 //
后按 ESC
退出,此时代码就被注释掉了
批量去注释
进入视图模式,使用 hjkl
选中要取消注释的区域,==注意这里要选中前两列,==否则只会删除 //
的第一个 /
,选好后输入 d
,即可删除
实例
3. gcc/g++的使用——Linux 编译器
补充扩展:
语言和编译器的自举过程
3.1 编译的过程
3.1.1 预处理
-
头文件包含
在此过程中,将头文件内容拷贝至源文件。将#include
包含的头文件内容直接插入到源代码中。 -
宏替换
在此过程中,将用#define
定义的宏替换为相应的值。 -
条件编译
根据条件编译指令(如#ifdef
、#ifndef
)来选择性地编译代码段。比如:我们在
code.h
#ifdef _CODE_H_
#define CODE_H
#endif
```
只有在定义了 code. h
的情况下,这段代码才会编。 这也就是为什么可以防止头文件被重复包含的原因。
- 删除注释
预处理器会将所有的注释删除,以简化代码。
输出:
预处理后的结果是一个纯文本文件,它是原始源代码经过宏替换、头文件展开、条件编译后的结果,通常以 .i
文件形式保存。
gcc -E code.c -o code.i
-E
选项告诉编译器只进行预处理,不进行进一步的编译步骤
-o
选项是指目标文件
.i
文件为已经过预处理的C原始程序。
3.1.2 编译
编译 是将预处理后的源代码(如 C 语言) 转换为目标机器的汇编代码的过程。编译器会将高级语言(C/C++)的语法结构翻译为与特定处理器架构相关的汇编指令。
编译步骤:
- 语法检查:编译器会对预处理后的代码进行语法和语义分析,确保代码符合语言规范。
- 生成中间代码:编译器会将代码转化为中间形式,这种形式与平台无关,可以优化。
- 优化:编译器可能会进行一些优化,比如减少不必要的代码、优化循环和条件语句等。
- 生成汇编代码:最后,编译器会生成与目标架构相关的汇编代码。汇编代码是一种低级别的、人类可读的机器语言。
输出:
编译的结果是汇编代码,通常保存为 .s
文件。
gcc -S code.i -o code.s
-S
选项让编译器停止在生成汇编代码的步骤,不继续到汇编和链接阶段。
3.1.3 汇编
汇编 是将汇编代码转换为目标机器可以直接理解的机器指令(机器码)的过程。汇编器会将汇编语言转化为二进制形式的机器码,这个过程是将低级别的汇编指令直接映射为 CPU 可以执行的指令。
汇编步骤:
- 指令翻译:每条汇编指令被转化为对应的机器码。
- 符号解析:将汇编代码中的符号(如变量和函数名)转化为具体的内存地址或偏移量。
输出:
汇编后的输出是目标文件(即可重定位目标二进制文件,是不能执行的),通常以 .o
(在 Linux 上)或 .obj
(在 Windows 上)为后缀。目标文件包含了编译后的二进制代码,但尚未与其他库或文件链接。
gcc -c code.s -o code.o
-c
选项指示编译器只进行到汇编阶段,不进行链接。
3.1.4 链接
链接 是将多个目标文件和库文件合并为一个最终的可执行文件的过程。程序通常由多个源文件组成,编译器会单独编译这些文件生成各自的目标文件,最后由链接器将它们链接在一起,生成最终的可执行文件。
链接步骤:
- 符号解析:链接器会解析所有目标文件中的符号,将各个文件中引用的函数和变量正确地连接起来。比如,如果
main.c
调用了foo.c
中的一个函数,链接器会找到foo.c
中对应的函数定义并将它们链接起来。 - 库的链接:如果程序使用了外部库(如标准 C 库
libc
或用户自定义的库),链接器会把这些库中的符号与程序中的引用进行匹配。可以是静态链接(库代码被复制到可执行文件中)或动态链接(在运行时加载库)。 - 生成可执行文件:最后,链接器会将所有解析后的二进制代码合并为一个可执行文件。
输出:
链接的输出是最终的可执行文件,通常没有文件扩展名(如 a.out
),或有 .exe
(在 Windows 上)。
gcc hello.o -o hello
默认的指令就可以了。
3.2 动、静态函数库
动态库(动态链接)
- 在程序执行时,由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为
.so
,如libc.so.6
就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。gcc code.c -o code
gcc
默认生成的二进制程序是动态链接,可用file
指令验证
优点:比较节省资源,不会出现太多的重复代码
资源:磁盘、内存、网络等。
缺点:对库的依赖性比较强,一旦库丢失,所有使用这个库的程序无法运行
静态库(静态链接)
静态库是指编译链接时, 把库文件的代码全部拷贝到可执行文件中, 因此生成的文件比较大, 但在运行时也就不再需要库文件了。其后缀名一般为“. a”
优点:不依赖库,同类型平台中都可以直接运行使用
缺点:可执行程序体积比较大,比较浪费资源(资源同上)
总结:
允许你拷贝的库就是静态库
允许你关联的库就是动态库
4. makefile
——Linux项目自动化构建工具
gcc
一条指令只能编译(删除)一个或多个源文件,而面对不计其数的项目文件(根据类型、功能等分散在各处)就显得十分低效,所以就有了 makefile
定义了一系列的规则指定文件的编译先后顺序等甚至更复杂的功能操作。
为了提高效率,人们把gcc、g++这些指令都集合在一个文件 Makefile
中,只需编辑一次,有新需求再对其修改,通过工具 make
,自动化执行指令。——一键自动化构建
4.1 make
、依赖关系及方法
make
是一条命令,makefile
是一个特定格式的文件(需要自己创建),两个搭配使用,完成项目自动化构建。
target: dependenciescommand
target
:表示需要构建的目标文件。dependencies
:表示构建目标文件所需要的依赖文件。command
:表示构建目标文件的命令。
你创建了一个 mytest.c
,然后下面你创建了 Makefile
或者 makefile
文件
mybin: mytest.c #这就是依赖关系。gcc -o mybin mytest.c #这就是依赖方法.PHONY: clean # 修饰 clean 目标为伪目标,总是被执行
clean:rm -f mybin
4.1.1 依赖关系与依赖方法、自动化构建
目标 mybin
:
- 第一行定义了一个名为
mybin
的目标,它依赖于mytest.c
文件。
这就是依赖关系。 - 当你运行
make
命令时,make
会找到第一个目标mybin
,并检查其依赖项(即mytest.c
)。如果mytest.c
发生了改变,make
会执行gcc -o mybin mytest.c
来编译生成可执行文件mybin
。
这就是依赖方法
依赖关系:
Makefile
中的依赖关系表示了目标文件和依赖文件之间的关系。如果依赖文件发生更改,或者目标文件不存在,make
将执行规则中的构建命令,以确保目标文件是最新的。
即:如果文件是最新的,make
就不会执行。
那么怎么判断文件是否最新呢?详见第五节。[[03 Linux环境基础开发工具使用#4.3. 文件的三个属性]]
自动化构建:make
工具的一个主要优势是它能够自动检测哪些文件需要重新构建,以减少不必要的编译和链接操作。它只会重新构建已更改或丢失的文件,而不是整个项目。
4.1.2 默认行为
默认行为:——默认形成的是第一个目标文件,且默认只形成一个!
- 默认情况下,执行
make
时,从上到下扫描Makefile
,构建第一个目标mybin
。如果没有其他目标的指定,make
只会创建mybin
,即使Makefile
中有多个目标(比如clean
)。
当我们将clean
和mybin
的位置颠倒,使用make
,不会执行gcc
,但却直接执行clean
4.2、make clean 和 .PHONY
伪目标 clean
:
- 使用
.PHONY: clean
指定clean
是一个伪目标,这意味着它不会与文件系统中的实际文件冲突。无论何时你运行make clean
,都会执行其下的命令。 clean
目标用于清理生成的可执行文件,通过运行make clean
来删除mybin
文件。
.PHONY
是一个特殊的目标,用于告诉 make
哪些目标是伪目标(不表示实际的文件),以防止 make
误解这些目标。通常,伪目标在 Makefile
中不会表示实际的文件,而是用于执行特定的操作或任务(比如clean清理数据)。
伪对象的作用有两个
1. 使目标对象无论如何都要重新生成。
2. 并不生成目标文件,而是为了执行一些指令。
4.3. 文件的三个属性
那么系统怎么判断文件是否最新呢?
文件第一次编写、编译代码后,此时源文件的修改时间一定是早于生成的可执行文件的修改时间。所以,第二次 make
时,系统会提示我们 mybin is up to date
。
当我们修改文件后,此时源文件修改时间晚于可执行程序文件的修改时间,所以系统会执行 make
查看文件的属性
stat 文件名
Access
是最近访问文件的时间
看文件是最频繁的,所以 access
时间并不是实时更新
Modify
是最近对文件内容做修改的时间
Change
是最近对文件属性做修改的时间
总结:
==文件 = 内容 + 属性 ==
修改文件的内容可能会影响文件属性 ,因为增加或减少代码会影响文件的大小
然而修改文件的属性不会影响文件内容,比如修改文件的拥有者,修改文件权限等
4.4 makefile推导能力和变量
这段代码的意思就是
首先,mybin依赖的是.o文件,但是系统中此时没有.o文件,就会执行下一条指令,但是.o文件依赖的是.s文件,系统中此时没有.s文件又会跳到下一条指令,以此往复直到找到系统中存在的.c文件,再倒推回去
这就是 makefile
的推导能力。(简单了解)
makefile
中可以定义变量
#原来的代码
mybin:mytest.cgcc -o mybin mytest.c
.PHONY:clean # 修饰mybin目标文件,成为一个伪目标,总是被执行
clean: rm -f mybin
在要替换的内容前加上 $
和 ()
即可
像C语言定义变量一样编辑代码
#定义变量的代码
target = mybin
cc = gcc
src = mytest.c
$(target):$(src) $(cc) $(src) -o $(target)
.PHONY:clean
clean: rm -rf $(target)
并且,可以用$^
代表依赖关系的左边
可以用 $@
代表依赖关系的右边
有种关键字 auto
的感觉
mybin:mytest.cgcc $@ -o $^
.PHONY:clean
clean: rm -rf mybin
5. Linux第一个小程序——进度条
#include <stdio.h>
#include<unistd.h>int main()
{printf("you can see me.");//注意这里没有`\n`sleep(3);return 0;
}
该程序在三秒后才显示出`you can see me.`——缓冲区
5.1 缓冲区
是临时存储输出数据的内存区域,数据在输出时会先存储在缓冲区中。
在 I/O 操作中,数据一般不会立即直接写入目标。
类型:
- 全缓冲:在数据达到一定量时,才会进行输出(如大文件输出到文件)。
- 行缓冲:每当遇到换行符(
\n
)时,会将缓冲区的数据输出。
如果加了\n
——printf("you can see me.\n");
便会立刻输出在显示屏上。
由于标准输出是行缓冲的,字符串会被存储在缓冲区中,直到遇到换行符或缓冲区满时,才会被输出到终端。 - 无缓冲:数据会立即写入目标,没有缓冲行为。
5.2 回车 \r
- 定义:回车符是 ASCII 控制字符,其值为
13
(十进制),表示将光标移动到当前行的开头。 - 表现:在终端中,回车符的效果是将光标移到行首,而不换行。例如,
printf("Hello\rWorld");
会输出World
,覆盖Hello
,结果只显示World
。
5.3 换行 \n
- 定义:换行符是 ASCII 控制字符,其值为
10
(十进制),表示将光标移动到下一行的开头。(即,并换行) - 表现:在终端中,换行符的效果是将光标移到下一行。例如,
printf("Hello\nWorld");
会在Hello
后换行,接着输出World
,结果显示为:
根据以上的知识点写出的
#include <stdio.h>
#include<unistd.h>int main()
{int cnt = 10; while(cnt >= 0){printf("%-2d\r",cnt);//不满2位数就打印出一位数fflush(stdout);// 强制输出到终端cnt--;sleep(1);//停顿}printf("\n");return 0;
}
fflush(stdout)
确保数字 cnt
会立即显示在终端上,而不是等待程序结束或缓冲区满时才显示。
5.4 进度条
5.4.1 Version 1 (死板固定的进度条)
#pragma once
#include <stdio.h>#define NUM 102
#define S '#'
//version1
void process();
#include "processbar.h"
#include <string.h>
#include <unistd.h>const char *label = "|/-\\";
//version 1
void process()
{char buffer[NUM];memset(buffer,'\0',sizeof(buffer));int cnt = 0;int n = strlen(label);while(cnt <= 100){printf("[%-100s][%3d%%][%c]\r",buffer,cnt,label[cnt%n]); fflush(stdout);buffer[cnt++] = S;usleep(50000);}printf("\n");
}
#include "processbar.h"
int main()
{process();return 0;
}
5.4.2 Version 2 (模拟真实情况)
#pragma once
#include <stdio.h>#define NUM 103
#define Body '='
#define Head '>'typedef void (*callback_t)(double)//回调函数void process_flush(double rate)
#include "processbar.h"
#include <string.h>
#include <unistd.h>const char *label = "|/-\\";char buffer[NUM] = {0};
void process_flush(double rate)
{static int cnt = 0; int n = strlen(label);if(rate <= 1.0) buffer[0] = Head;printf("[\033[4;37;41m%-100s\033[0m][%.1f%%][%c]\r", buffer, rate, label[cnt%n]);//只是,增添了颜色。printf("[%-100s][%3d%%][%c]\r",buffer,cnt,label[cnt%n]);fflush(stdout);buffer[(int)rate] = Body;if((int)rate+1 < 100) buffer[(int)(rate+1)] = Head;if(rate>=100.0) printf("\n");cnt++;cnt%=n;
}
#include "processbar.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>#define FILESIZE 1024*1024*1024//模拟一种场景,表示一种下载的任务
void download(callback_t cb) // 回调函数的形式
{srand(time(NULL)^1023);//- 首先调用 `srand` 来初始化随机数生成器。//在下载循环中,`rand()` 用于生成一个随机下载量(`one`),使得每次循环下载的量都是不固定的,模拟真实下载情况。 int total = FILESIZE;while(total){usleep(10000); //下载动作int one = rand()%(1024*1024*10);total -= one;if(total < 0) total = 0;// 当前的进度是多少?int download = FILESIZE - total;double rate = (download*1.0/(FILESIZE))*100.0; // 0 23.4 35.6, 56.6cb(rate);//process_flush(rate);//printf("download: %f\n", rate); // rate出来了,应该让进度条刷新}
}int main()
{//process();download(process_flush);return 0;
}
6. 版本管理工具——git
Git 是一个强大的版本控制系统,通过一系列指令和操作,可以轻松管理项目的历史、协作开发和代码发布。
Git 工作流程
- 克隆或初始化项目:使用
git clone
克隆远程仓库,或使用git init
创建本地仓库。 - 创建分支:创建新分支进行开发(
git branch <branch_name>
)。 - 修改代码并提交:在分支中修改代码,使用
git add
暂存更改,使用git commit
提交更改。 - 推送更改:将本地分支的更改推送到远程仓库(
git push
)。 - 合并分支:当开发完成后,将分支合并到主分支(
git merge
)
6.1 常用指令
sudo yum install git
记得在系统里安装 git 工具。
git clone
下载项目到本地,创建好一个放置代码的目录。
git clone [url]
这里的 url 就是刚刚建立好的仓库链接
git add
git add <file>
:将指定文件的更改添加到暂存区。git add .
:将当前目录下的所有更改添加到暂存区。
git status
显示当前工作目录中已修改但未提交的文件,以及与远程仓库的不同步情况。
git commit
git commit -m "Commit message"
提交暂存区中的文件到本地仓库,-m
后面跟提交的描述信息。
git log
:
显示当前仓库的提交历史,包含提交 ID、作者、日期和提交信息。
git push
将本地分支的提交推送到远程仓库。
用户名是你 gitee 主页@后面的字符串
6.2 .gitignore
文件
git 仓库只要管理源代码(源文件+头文件+配置文件等)
本地仓库提交的文件进行过滤的,文件后缀在 ign 文件列表中,不会被本地和远端托管
注意
- 不要忽略
*.xxx
- 修改是及时生效的
7. gdb——Linux 调试器
程序的发布方式有两种,debug模式和release模式
前者较于后者,形成的可执行程序会给我们添加调试信息
gcc/g++编译时默认是 release
模式。
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g
选项
mybin:mytest.cgcc -o $@ $^ -g
.PHONY:clean
clean: rm -rf mybin
7.1 调试的目的
只有知道代码逻辑,调试起来才会相对容易。
- 找到问题(通过查找,范围查找,局部逐行查找等)
- 解决问题(联系上下文代码)
7.2 调试过程及 gdb
指令
尽管各平台(如:微软的visual studio )调试的形式不同,但本质是相似的。
Windows 基本的调试功能
- 运行起来才能调试
- 要看得到代码
- 打断点
- 局部调试(如:函数内)
- 看到局部变量的内容和地址
- 看到调用栈
- 单步
- 进入函数
l 行号
:显示指定行之后的代码(gdb 自动记录最近一条指令)
b 行号/函数名/file
:行号:对指定位置打断点
info b
:査看我们所打的断点
d 断点编号
:删除断点
disable/enable 断点编号
:使能(禁用/开启)断点
n
:逐过程–F10
s
:逐语句–F11(进入函数)
p
:显示变量的内容和地址
display 变量名/取地址
:常显示变量的内容和地址
undisplay 编号
:取消常显示变量的内容和地址
c
:从一个断点运行到下一个断点(可用于问题范围查找)
finish
:将一个函数运行结束,就停下来(可用于问题范围查找)
until
:在一个范围内,直接运行到指定行(可用于问题范围查找),不能跳过函数调用,一般用于跳过循环
bt
:查看调用堆栈
相关文章:

【Linux基础】03 Linux环境基础开发工具使用
1. yum ——软件包管理器 yum 是我们 Linux 预装的一个指令,搜索、下载、、安装对应的软件 yum 相当于 Linux 的应用商店! 安装与卸载 yum list | grep command 通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我…...

【CSS】flex: 1; 的意思
在 Flexbox 布局中,flex: 1; 是一个简写属性,它表示弹性容器中的子元素如何分配可用空间。flex: 1 意味着该元素可以根据剩余的空间进行扩展,占据相应的比例。具体来说,flex: 1; 是 flex-grow、flex-shrink 和 flex-basis 这三个属…...

C++ 3D冒险游戏开发案例
3D冒险游戏的C开发案例,包括游戏设计、实现细节、图形渲染、音效处理等内容。 3D冒险游戏开发案例 一、游戏设计 游戏概述 游戏名称:“探索者的传奇”类型:3D冒险游戏目标:玩家控制角色在一个开放的世界中探索、解谜、战斗并完成…...

【AIGC】Exa AI 要做 AI 领域的 Google
又一个AI搜索引擎诞生:Exa AI。 与其他旨在取代谷歌的AI驱动搜索引擎不同,Exa的目标是创建一个专门为AI设计的搜索工具。 Exa的使命: 互联网包含人类的集体知识,但目前的搜索体验更像在垃圾场中导航,而非在知识图书馆中漫游。核…...

YOLOv8 基于MGD的知识蒸馏
YOLOv8 基于MGD的知识蒸馏 接着上一篇我们介绍了YOLOv8的剪枝方案和代码,本篇文章将剪枝后的模型作为学生模型,剪枝前的模型作为教师模型对剪枝模型进行蒸馏,从而进一步提到轻量模型的性能。 Channel-wise Distillation (CWD) 问题和方法 …...

全国消防知识竞赛活动方案哪家强
关键词:消防安全、预防火灾、消防意识、消防员、防火安全 适合行业:所有行业 推荐功能:答题、投票、H5 宣传角度 1.从日常生活场景出发,指导大家如何检查家庭中的火灾隐患。例如检查电线是否老化、插座是否过载、是否在楼梯间…...

JavaEE学习一条龙服务————概述
鉴于之前的笔记较乱,没有逻辑关系,,博主决定从JacaEE整个学习的阶段出发,整理一系列博客,供大家学习交流,提升自己。 此文章已绑定一篇我为大家梳理的JavaEE一条龙学习知识点的文档,大家可下载…...

分支预测器BPU
分支预测器BPU 0 Intro0.1 CPU执行过程0.2 分支预测0.2.1 TAGE预测器0.2.2 跳转地址 分支预测器BPU是深入研究一个高性能处理器的一个很好的开始项目; 0 Intro 条件分支是指后续具有两路可执行的分支。可以分为跳转分支(taken branch)和不跳转分支(not-taken branc…...

Go 系列教程 —— 数组和切片
数组 数组是同一类型元素的集合。例如,整数集合 5,8,9,79,76 形成一个数组。Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组。(译者注:当然,如果是 interface{} 类型数组,可以包含任意类型…...

适配器模式【对象适配器模式和类适配器模式,以及具体使用场景】
2.1-适配器模式 类的适配器模式是把适配者类的API转换成为目标类的API,适配器模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作,其实在具体的开发中,对于自己系统一开始的设计不会优先考虑适配器模式,通常会将接…...

【EXCEL数据处理】保姆级教程 000016案例 EXCEL的vlookup函数。
【EXCEL数据处理】000016案例 vlookup函数。 前言:哈喽,大家好,今天给大家分享一篇文章!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 【EXCEL数据处理】保姆级教…...

【软件推荐】通过Rufus制作信创操作系统U盘安装盘 _ 统信 _ 麒麟 _ 方德
原文链接:【软件推荐】通过Rufus制作信创操作系统U盘安装盘 | 统信 | 麒麟 | 方德 Hello,大家好啊!今天给大家带来一篇关于如何使用Rufus制作信创操作系统(如统信UOS、麒麟KOS、中科方德等)的U盘启动安装盘的文章。Ruf…...

MySql 多表设计
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本分为:一对多,多对多&a…...

wpf实现新用户页面引导
第一步 第二部 部分代码: private void show(int xh, FrameworkElement fe, string con, Visibility vis Visibility.Visible) {Point point fe.TransformToAncestor(Window.GetWindow(fe)).Transform(new Point(0, 0));//获取控件坐标点RectangleGeometry rg new Rectangl…...

【小白向】机器人入门之ROS系统的学习(Ubuntu24.04+ROS2)
目录 一.复杂的机器人系统 二.ROS机器人系统 1.简介 1.节点 2.话题 2.安装 3.测试 4.可视化 RQT: RVIZ: 显示属性: 显示状态: 一.复杂的机器人系统 依照我们现在的技术来看,机器人系统仍是极其复杂的,往…...

SNAP-MS策略:可溶性水凝胶微珠,高效表征蛋白质复合物
大家好!今天来了解一种高效的蛋白质复合物纯化和表征策略的文章——《Biofunctionalized dissolvable hydrogel microbeads enable efficient characterization of native protein complexes》发表于《Nature Communications》。蛋白质复合物在生命过程中起着关键作…...

java对象序列化Serializable的应用场景
目录 Java对象序列化的应用场景 网络通信: 对象持久化: 分布式计算: 缓存存储: 远程方法调用(RMI): 基于JMS的消息传递: Java集合类中的对象需要被存储: 对象深…...

springboot-网站开发-linux服务器部署jar格式图片存档路径问题
springboot-网站开发-linux服务器部署jar格式图片存档路径问题!近期在部署自己的网站源码,使用的是jar格式的编码格式。发布到远程服务器后,发现客户捐款的证书图片存在异常。 经过排查代码,找到了原因。下面分享给大家。 1&…...

面试--java基础
Java基础 Java 中的几种基本数据类型了解么?基本类型和包装类型的区别?包装类型的缓存机制了解么?成员变量与局部变量的区别?静态变量有什么作用?静态方法为什么不能调用非静态成员?重载和重写有什么区别?…...

NLP自然语言处理
计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割OpenCVPytorchNLP自然语言处理 NLP自然语言处理 一、NLP简介二、文本预处理2.1 文本预处理简介2.2 文本处理的基本方法2.3 文本张量表示方法2.3.1 onehot编码2.3.2 word2vec编码 2.4 文本数据分析2.5…...

web自动化测试基础(从配置环境到自动化实现登录测试用例的执行,vscode如何导入自己的python包)
接下来的一段时间里我会和大家分享自动化测试相关的一些知识希望大家可以多多支持,一起进步。 一、环境的配置 前提安装好了python解释器并配好了环境,并安装好了VScode 下载的浏览器和浏览器驱动需要一样的版本号(只看大版本)。 1、安装浏览器 Chro…...

鸿蒙 Next 实战: 电子木鱼
前言 正所谓:Hello Word 是程序员学任何一门语言的第一个程序实践。这其实也是一个不错的正反馈,那如何让学习鸿蒙 Next 更有成就感呢?下面就演示一下从零开发一个鸿蒙 Next 版的电子木鱼,主打就是一个抽象! 实现要点…...

SQLite SQL调优指南及高级SQL技巧
记忆已更新 以下是《SQLite SQL调优指南及高级SQL技巧》文章的完整输出,字数目标为30000字,详细介绍并结合2024年最新技术趋势和优化策略。代码部分不计入字数统计。 SQLite SQL调优指南及高级SQL技巧 SQLite 是广泛使用的嵌入式数据库,因其…...

WordPress 6.7即将发布的新功能(和截图)
我们一直在密切关注 WordPress 6.7 的开发并测试该版本的测试版,它将带来一些令人兴奋的更新和几个新功能。 例如,我们很高兴地发现即将发布的版本将附带全新的默认主题,并对块编辑器和站点编辑体验进行大规模改进。 在本文中,我…...

SpringBoot整合QQ邮箱
SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件.... 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,…...

低质量数据的多模态融合方法
目录 多模态融合 低质量多模态融合的核心挑战 噪声多模态数据学习 缺失模态插补 平衡多模态融合 动态多模态融合 启发式动态融合 基于注意力的动态融合 不确定性感知动态融合 论文 多模态融合 多模态融合侧重于整合多种模态的信息,以实现更准确的预测,在自动驾驶、…...

计算机毕业设计 基于Django的在线考试系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...

Shell脚本linux登录自动检查
.bashrc 用于设置用户的 Bash shell 环境,在每次打开一个新的终端窗口或启动一个新的 Bash 会话时被执行 代码 login_check.sh #!/bin/bash clear LogFileNamepolling.$(date %F-%T) EchoFormat$(for (( i0; i<30; i )); do echo -n ""; done)# 显示…...

Golang | Leetcode Golang题解之第450题删除二叉搜索树的节点
题目: 题解: func deleteNode(root *TreeNode, key int) *TreeNode {var cur, curParent *TreeNode root, nilfor cur ! nil && cur.Val ! key {curParent curif cur.Val > key {cur cur.Left} else {cur cur.Right}}if cur nil {retur…...

Linux 之 Linux应用编程概念、文件IO、标准IO
Linux应用编程概念、文件IO、标准IO 学习任务: 1、 学习Linux 应用开发概念,什么是系统调用,什么是库函数 2、 学习文件IO:包括 read、write、open、close、lseek 3、 深入文件IO:错误处理、exit 等 4、 学习标准IO&a…...