【Linux系统编程】环境变量详解

news2025/1/16 4:42:55

文章目录

  • 1. 环境变量的基本概念
  • 2. 如何理解呢?(测试PATH)
    • 2.1 切入点1
      • 查看具体的环境变量
      • 原因剖析
      • 常见环境变量
    • 2.2 切入点2
      • 给PATH环境变量添加新路径
      • 将我们自己的命令拷贝到PATH已有路径里面
    • 2.3 切入点3
  • 3. 显示所有环境变量
  • 4. 测试HOME
  • 5. 通过代码如何获取环境变量
    • 5.1 main函数的第三个参数(环境变量表)
    • 5.2 通过全局变量environ获取
  • 6. 环境变量的组织方式
  • 7. 通过系统调用获取环境变量
  • 8. 再来理解到底什么是环境变量
  • 9. 环境变量通常具有全局属性,可被子进程继承
  • 10. 环境变量与普通变量
  • 11. 命令行参数的理解

我们在学校学习某些编程语言比如Java、python,一开始在配置环境的时候基本上都会做一件事情就是配置环境变量。
那我们当时往往都是按照老师的指导或者跟着网上的一些教程直接就把它配置了,但是,我们可能并不明白配置这个环境变量到底是干啥的,它到底有什么作用?

那这篇文章,我们就来谈一谈环境变量到底是个什么东西?

1. 环境变量的基本概念

首先我们可以来看一下环境变量的概念:

1. 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
2. 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

单凭这段文字,大家肯定还不能理解到底什么是环境变量,那下面我们通过几个问题来帮助大家理解

2. 如何理解呢?(测试PATH)

2.1 切入点1

我们之前在Linux上写过C程序,并且我们知道如何编译链接让它生成可执行程序,然后运行它。

比如:

我写了这样一个test.c
在这里插入图片描述
并且写好了Makefile。
然后我执行make命令就生成了对应的可执行文件
在这里插入图片描述
然后我运行一下
在这里插入图片描述
没什么问题。

但是呢,我想问大家一个问题:为什么我们运行这样的可执行文件要加上./呢?

那我问大家,我们写的.C的文件生成的可执行程序,我们可以像指令那样去执行它来完成相应的任务。
那这个可执行程序可以叫做指令嘛?
🆗,我记得在刚开始我们学习Linux基本命令的时候就有说过:
指令其实也是文件,可执行文件
我们可以file查看一下我们平时常用的命令比如——ls:
在这里插入图片描述
我们看到它其实就是一个可执行(executable)程序啊
那我们这里自己生成的可执行程序myproc呢?
在这里插入图片描述
我们看到它们其实就是一样的,没什么区别。
只不过人家写的ls这些指令被纳入了Linux的基本指令里面,而我们写的只能自己玩玩。但他们本质上都是可执行程序。

但是呢,问题就来了:为什么我们运行ls这些指令可以直接敲对应的指令直接执行,而我们自己生成的可执行程序运行要加./呢?
在这里插入图片描述

为什么呢?
如果我想让我们自己的可执行程序也可以不加./直接运行,能做到吗?如何实现呢?

./我们知道它是啥东西,.代表当前目录嘛,/是路径分隔符嘛。
那我们这里的可执行文件myproc就是当前目录下的一个文件
在这里插入图片描述
所以,执行我们自己的可执行程序好像必须要定位到它所在的路径。
那上面./的定位方式其实是相对路径,那用绝对路径是不是也可以执行这个可执行文件?
在这里插入图片描述
这当然也是可以的。
但是它为什么就不能像ls哪些基本命令那样无需指明路径直接执行呢?
那原因呢其实就在于像ls这些基本指令,系统中原本就存在与之相关的环境变量。我们执行这些指令的时候,系统会自动根据环境变量去相对应的路径下查找这些指令,能够找到就可以直接执行,而无需指明完整路径。
所以,执行一条指令的前提是得先找到它。

那么Linux中就存在这样一个环境变量——PATH:

PATH :用于指定命令的搜索路径

我们可以先查看一下它

查看具体的环境变量

echo $NAME //NAME:环境变量名称
在这里插入图片描述

原因剖析

那么上面说了这么多:为什么ls哪些基本直接无需指明路径就可以直接执行,而我们自己的可执行程序不可以呢?

🆗,那原因就在于我们在命令行执行ls这些基本指令的时候,系统会自动去环境变量PATH中指定的这些路径里面查找,如果能找到对应的指令,就可以执行,无需我们自己指明具体路径。
在这里插入图片描述
而我们自己的可执行程序
在这里插入图片描述
所在的路径是没有包含在PATH环境变量定义的路径里面的。
所以运行的时候我们必须自己指明路径,如果没有指明,那么系统就找不到该命令,无法去执行
在这里插入图片描述

那这里我们提到的PATH其实就是一种环境变量:

常见环境变量

PATH : 指定命令的搜索路径
HOME : 指定用户的主工作/家目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash

那到这里,大家再去回看最开始环境变量的概念以及后面跟的例子:

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

相信大家可能就有一点感觉了。

2.2 切入点2

那如果我想让我们自己的可执行程序像ls这些基本命令那般可以直接执行而无需指明路径,应该怎么实现呢?

那经过上面的学习,我们知道为啥我们自己的可执行程序不能直接运行而需要指明路径啊?不就是因为我们自己的可执行程序没有在PATH环境变量定义的路径里面嘛。
在这里插入图片描述
那所以呢?
如果我们想要我们自己的可执行程序可以像ls这些基本命令那样直接执行,是不是把我们自己的可执行程序所在的路径添加到PATH环境变量里面就行了。

给PATH环境变量添加新路径

那如何添加呢?

export PATH=$PATH:要添加的路径(修改PATH环境变量添加一个新的路径)
export可新增,修改或删除环境变量

我们来试一下:

我们把myproc的路径添加到PATH里面在这里插入图片描述
那现在我们再来执行我们自己的可执行程序myproc
在这里插入图片描述
我们发现就可以直接执行而无需再指明路径了
另外需要注意的是,如果这样写的话:
在这里插入图片描述
在这里插入图片描述
这样就不是添加而是修改PATH里面的路径了,这样修改后PATH里面就只有这一条路径了。
那你的ls这些基本命令可能就无法执行了。
但是如果这样做了也没关系,关闭你的Xshell重新登录就恢复了。
当然同样的,我们添加之后,后面重新登录的话,它其实也会恢复

将我们自己的命令拷贝到PATH已有路径里面

那除此之外,大家想一下还有没有其它的方法可以使我们自己的可执行程序能够不带路径直接执行呢?

🆗,我们如果把我们自己的可执行程序放在PATH环境变量里面已包含的路径里面,按理说应该也可以啊。

我们试一下:

我新打开一个渠道
在这里插入图片描述
现在执行myproc是不行的。
那我们现在把myproc拷贝到PATH里面已有的路径比如usr/bin/下面
在这里插入图片描述
拷贝好了。
那我现在把当前目录下面的这个myproc删掉
在这里插入图片描述
然后我现在像执行ls那样直接执行myproc
在这里插入图片描述
是可以的,并且我们which命令也可以查到。

🆗,那像我们上面这样:

在Linux中,把可执行程序拷贝到系统环境变量默认路径下,让我们可以直接访问的方式——其实就相当于Linux下软件的安装。
那如果我不想要它了,把他从对应路径里面删掉:
在这里插入图片描述
就用不了了,那这其实就相当于卸载。

2.3 切入点3

我们在Linux上用不同用户登录的时候,系统中也会有对应的环境变量来记录当前登录的用户是谁

这个环境变量呢就叫做——USER
我们可以来查看一下它
在这里插入图片描述
我当前登录的用户是yhq,那我查看这个环境变量就是yhq
如果我切换成root
在这里插入图片描述
查看到就是root

然后大家再来思考一个问题:

前面我们讲文件权限的时候,我们要判断一个用户对某个文件是否拥有某些权限的时候,一般首先我们要定位一下该用户的角色,它是这个文件拥有者,还是所属组,或者other。
那么系统是如何知道当前用户是什么角色呢?
那就是因为有环境变量的存在。
当你登录的时候,环境变量就记录了你是哪个用户
在这里插入图片描述
所以当我们访问某个文件的时候,那系统就可以拿着你当前的用户名和文件的拥有者、所属组或other进行对比,从而就能判断出来你是什么角色,然后拿对应的权限去套你,以此来确定你对某个文件拥有哪些权限。
所以这种情况也是依靠环境变量来处理的。

3. 显示所有环境变量

那如果我想查看我这个用户当前系统上所有的环境变量都有哪些,要如何查看呢?

这里用到的命令叫做——env:列出所有环境变量及其赋值
在这里插入图片描述
它就列出了当前系统上我这个用户所有的环境变量,这些环境变量基本上都是我们登录的时候就设定好的。
比如:
在这里插入图片描述
在这里插入图片描述
挺多的,大家感兴趣可以自己查询了解一下。

4. 测试HOME

上面我们提到过一个环境变量——HOME

HOME : 指定用户的主工作/家目录(即用户登陆到Linux系统中时,默认的目录)
那当前我是普通用户,我们查看HOME环境变量的话
在这里插入图片描述
显示的值就是我的家目录
那如果我切换成root
在这里插入图片描述
那我们再查看就是root的家目录。
所以对于同一个环境变量,如果对应的用户不同,那它的值可能就是不一样的。

5. 通过代码如何获取环境变量

上面我们提到,系统启动的时候,就已经存在大量的环境变量,那如果我们想获取到这些环境变量要怎么做呢?

那我们其实是可以自己写一个程序来获取的

5.1 main函数的第三个参数(环境变量表)

那首先来问大家一个问题:大家之前肯定都写过C/C++的程序,那我想问大家的是main函数可以带参数吗?如果可以的话最多可以带几个呢?

我们平时自己写C/C++代码一般写的main函数都是无参的
在这里插入图片描述
但是呢相信大家可能会在网上或者一些书籍上见过带参数的main函数,比如这样的
在这里插入图片描述
最常见的就是这种两个参数的,如果这两个参数你不知道是啥,没关系,我们后面也会给大家介绍。

但是呢,main函数其实是可以有3个参数的:

在这里插入图片描述
那我们先来讨论一下这个第三个参数——envp,通常我们把它叫做环境变量表
我们再来看第三个参数,大家说 char* envp[] 这是个啥啊?
🆗,这不是一个字符指针数组嘛。
在这里插入图片描述
每个元素都是一个char*的指针,那这些指针都指向什么东西呢?
我们学过C语言,对于一个字符指针来说,它指向的内容无非就两种:

  1. 指向一个字符(即存储一个字符变量的地址)
  2. 指向一个字符串(即存储的是一个字符串的首字符地址)

那在这里我明确的告诉大家它指向的就是一个字符串,并且:

char* envp[]这个字符数组的最后一个元素里面一定存的是NULL,当然其实不一定总是最后一个元素,应该说第一个无效元素存的是NULL。
比如该数组大小为10,只有前5个元素都指向字符串,那么它第六个元素就指向NULL。

那它指向的字符串是什么呢?

不知道没关系,那我们可以遍历envp数组打印出来看一下
在这里插入图片描述
我们来运行一下看看这个表里面存的到底是啥?
在这里插入图片描述
大家看看,这打印出来的是啥啊!
这不是跟我们之前用env命令列出的环境变量一样嘛,只不过我们在前面加了下标这些信息。
其实不用打印我们也能猜出来,我们说了它是环境变量表嘛,所以它里面放的就是一个一个的环境变量以及它们对应的值组成的字符串。

5.2 通过全局变量environ获取

那么除了上面的方法,我们还可以通过一个全局变量来获取环境变量:

这个全局变量叫做——environ
我们可以来查看一下
在这里插入图片描述
我们看到,它的类型是char**,是一个二级指针类型

char**的话其实跟上面的char* envp[]不是一样嘛!

因为char* envp[]是在main函数的参数列表里面,那传参的话传一个数组传过去的真正是啥,是不是数组首元素地址啊。
char* envp[]首元素是char*,那首元素的地址不就是char**的二级指针嘛。
所以同样的,environ也指向环境变量表。

那我们就来用environ打印一下环境变量表:

那其实跟上面用char* envp[]的方式是一样的
在这里插入图片描述
我们来运行一下
在这里插入图片描述
效果是一样的。
libc(Linux下的ANSI C的函数库)中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

那么由此,我们也引出——环境变量的组织方式

6. 环境变量的组织方式

每个程序都会收到一张环境变量表,环境变量表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串(即环境变量名及其值组成的字符串)
在这里插入图片描述

7. 通过系统调用获取环境变量

上面呢我们已经介绍了两种通过代码获取环境变量的方式,但是:

我们以后如果要获取某个环境变量比如PATH的时候,难道要像上面那样遍历指针数组(环境变量表),再通过字符串匹配去一个个找吗?
可以是可以,但是好像有点麻烦,那有没有更简便的方法呢?
🆗,当然是有的,除了上面介绍的两种方式,我们还可以通过函数(系统调用)直接获取指定的环境变量。

那我们下面就来学习一下:

首先,用来获取特定系统变量的函数——getenv

那它是如何使用的呢?

我们可以打开man手册来看一下:man getenv
在这里插入图片描述
需要包含的头文件是stlib.h
该函数的返回值是char*,一个参数const char *name
所以我们调用时传入指定的环境变量名,就可以获取到该环境变量
如果没有匹配到
在这里插入图片描述
返回NULL

那我们可以来写个代码试一下:

比如我们获取一下环境变量USER
在这里插入图片描述
我们来运行一下
在这里插入图片描述
🆗,就成功获取到了我们当前系统上环境变量USER 的值。
那其他的也是一样,我们调用getenv传对应的环境变量名称就行了。

8. 再来理解到底什么是环境变量

那讲到这里,我们再回过头来理解一下到底什么是环境变量:

那在上面的学习中,我们了解了环境变量的概念,也进行了一些实操。
比如我们把自己写的可执行程序的路径添加到了PATH环境变量中,使得我们运行自己的可执行程序时可以像基本命令ls那样无需指定完整路径,直接可以运行。

但是呢?我们同时也注意到一个问题,就是我们如果重新登录的话,环境变量PATH里面的路径就被重置了,我们再去直接运行我们的可执行程序就不行了,除非你再次添加。
那这说明了什么呢?

上面我们获取了环境变量,我们知道它其实就是一张表嘛。表里面包含了所有的环境变量以及它们对应的值(键值对集合)。
那上面我们提到的现象又说明了什么呢?
🆗,它说明了环境变量其实本质是一张内存级的表,在用户登录的时候,就会由系统去特定用户形成属于自己的环境变量表。
而表中的每一个环境变量,都有自己特定的应用场景,比如有的是指定命令搜索路径的,有的是进行身份验证的等等。
表中的每一个环境变量都是KV的键值对形式。

那再来思考一个问题:

我们说环境变量是一张内存级的表,用户登录时由系统形成。那么表中的数据都是从哪来的呢?
🆗,表中的环境变量信息呢其实都是从系统的相关配置文件中读取进来的。

那这些配置文件又在哪里呢?

我们进入用户的家目录,在家目录下面呢我们能找到这样两个文件
在这里插入图片描述
它们其实是两个shell脚本。
那打开的话其实我们现在也看不太懂
在这里插入图片描述
但是它们里面其实就是对环境变量进行设置啥的,这样一些操作。
当我们每次登录成功的时候,系统会重新读取配置文件,把这些配置文件中的脚本执行,然后就自动形成对应的环境变量,加载到内存中。

9. 环境变量通常具有全局属性,可被子进程继承

上面我们提到环境变量其实是一张内存级的表:

那这张表其实是在shell内部由shell来维护的,那我们知道Linux上的shell一般是bash,我们在命令行启动的所有程序通常都是bash的子进程。

然后呢在上面我们学过一个命令——export:

export可以新增,修改或删除环境变量。
上面我们使用export对PATH环境变量进行了修改。

那我现在想新增一个环境变量,怎么做呢?

export VARIABLE_NAME="value"
其中,VARIABLE_NAME是要新增的环境变量的名称,value是环境变量的值
我们来试一下
在这里插入图片描述
我新增了一个环境变量为hello="youcanseeme"
那我们知道所有的环境变量都在环境变量表里面存放,那我们在环境变量表里面是不是能查看到我们新增的这个环境变量呢?
那我们使用env命令列出所有环境变量及其赋值
在这里插入图片描述
那在显示出来的环境变量表中我们就看到了刚才我们自己添加进行的环境变量表。

上面我们说到:

环境变量表是在bash中由bash维护的,所以我们执行export VARIABLE_NAME="value"命令之后。
那bash就会把这个环境变量及其赋值作为一个字符串添加到环境变量表的指针数组中。

然后呢想告诉大家的是:

经过之前的学习我们知道命令行启动的程序都是bash的子进程,而环境变量——环境变量通常具有全局属性,可以被子进程继承下去

那我们能不能证明一下呢,你说环境变量可以被子进程继承,那就真的是这样吗?

那我们来写这样一个程序:
在这里插入图片描述
我们刚才不是新增了一个环境变量嘛,那我们现在来获取一下它,如果获取到了,打印一下。
来试一下
在这里插入图片描述
我们成功获取到了刚才新增的那个环境变量。

那这能证明什么呢?

这个结果不就证明了环境变量被子进程继承下来了嘛。
因为我们在命令行启动的这个程序是bash的子进程啊,而我们上面新增的子进程是在bash里面新增的,而现在子进程获取到了它,那也就证明环境变量被子进程继承了下来。

10. 环境变量与普通变量

我们来做一个实验:

我们知道export VARIABLE_NAME="value"可以新增环境变量到环境变量表里面。

那如果我不加export呢?

比如:
在这里插入图片描述
另外我们发现这样的话这个hello1也可以像环境变量那样打印
在这里插入图片描述

那它也可以通过子进程获取到嘛,我们来试一下:

现在我们用getenv来获取hello1在这里插入图片描述
我们来运行一下
在这里插入图片描述
我们发现啥也没有,那就是没有获取到,返回的是NULL

那所以呢,带export和不带export有什么区别呢?

我们知道,带export的话,它就会把后面的变量及其赋值当作环境变量导入环境变量表中,我们在环境变量表中可以查到,并且它可以被子进程继承。
那不带export呢?
通过上面的实验我们知道它不会被子进程继承,那就说明它不是环境变量,但是我们可以像查看环境变量那样查看到它,那就说明它也被bash记录下来了,但是它没有被添加到环境变量表中,成为环境变量。
所以,不带export的这种变量我们把它叫做shell的本地变量或者叫普通变量,它就不具有全局属性,而是局部有效,只在shell内部有效。

但是如果我后续就是想让这个hello1这个普通变量能够被子进程继承怎么办呢?

那也很简单,你就再用export把它导进去环境变量表就行了
在这里插入图片描述
然后,我们看到就可以了。

但是,这里好像还有一点问题值得我们思考:

在这里插入图片描述
这样不加export他就是一个普通变量,也会被bash记录下来。
在这里插入图片描述
我们也可以用echo $变量名打印它的值,只是它没有被添加到环境变量表里面,子进程不会继承,获取不了。
但是,你不觉得奇怪吗?
我们执行echo $hello2,这也是一个指令啊,那按理说他也是bash的子进程啊,但是本地变量不是不会被子进程继承吗?可是为什么这里我们能够打印出来呢?
🆗,那这个问题我们先放一放,后面再说,大家有兴趣可以自己先去研究思考一下。

那么以上就是环境变量的全部内容…

不过还有一个东西也值得我们来说一下:

11. 命令行参数的理解

上面我们提到过:

main函数呢其实是可以有3个参数的,前面我们重点介绍了第三个参数char* envp[]

那么下面,我们来介绍一下前两个命令行参数int argc, char* argv[]

它们叫做命令行参数
在这里插入图片描述
那它们有什么用呢?
首先呢,这个argv[],我们看到它的类型和我们上面提到的环境变量表的类型是一模一样的,是一个char*的指针数组。
argv[]也是一张表,只不过内容肯定和环境变量表是不一样的。
那么第一个参数argc又是啥呢?
🆗,他其实就是argv这个指针数组的大小。

那他里面到底放的是啥呢?我们可以直接遍历这个数组打印看一下:

在这里插入图片描述
我们来运行几次,大家看一下现象:
在这里插入图片描述
大家看看,现在是否对命令行参数这几个字有一点感觉了?
🆗,我们在调用这个程序的时候,在命令行输入的这些内容
在这里插入图片描述
在shell看来,就是一个字符串,那么按照空格将其分割成子串
它们分别对应:
在这里插入图片描述
那说到参数选项,相信大家应该不陌生,我们之前学习基本命令的时候,很多命令后面都可以跟对应的选项
在这里插入图片描述
在这里插入图片描述

那此时我们再来讨论argv这个表里面存的是什么:

那其实存的就是我们在命令行输入的字符串以空格分隔出来的一个个子串
在这里插入图片描述
bash通过命令行输入的字符串生成了这张表,我们子进程里面可以用这个表。

如果我们每次把argc也都打印出来的话:

在这里插入图片描述
再来运行几次
在这里插入图片描述
我们发现argc就是子串的个数,也是指针数组argv的大小。

🆗,那这就是命令行参数,那它有什么用呢?

那下面我们来做一个实验:

我们来尝试写这样一个程序:
就是你调用我这个程序的时候,必须带选项,如果你第一次调用不知道的话,没有带选项,就打印提示;然后根据提示,你带不同的选项,就会打印不同的语句代表完成不同的任务。(就像我们的基本命令后面跟不同选项一样)
所以,我来写这样一个代码:
在这里插入图片描述
我们来运行一下看看效果
在这里插入图片描述
那大家看,这就是命令行参数的意义。
现在我们再来想我们之前学习基本命令的时候,为什么我们跟不同的选项,就对应不同的功能,那其实就是通过命令行参数来实现的。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1401011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch8 集群搭建(二)配置篇:(1)节点和集群配置

安装完Elasticsearch后,需要对其进行配置,包括以下几部分:节点和集群配置、系统配置、安全配置。 此篇记录节点和集群配置的内容,后续将更新系统配置和安全配置。 节点和集群配置: 通过编辑/usr/local/elasticsearc…

2024最新版Python3.12.1的新特性

2024最新版Python3.12.1的新特性 New Features followed by the latest version - Python 3.12.1 in 2024 By JacksonML Python 3.12.1最新版已经于2023年12月3日在python.org正式发布! 详细信息可见官网链接:https://www.python.org 作为2024年的最新…

新发现个上头的神仙写简历工具,分分钟惊掉你下巴!

你们在制作简历时,是不是基本只关注两件事:简历模板,还有基本信息的填写。 当你再次坐下来更新你的简历时,可能会发现自己不自觉地选择了那个“看起来最好看的模板”,填写基本信息,却没有深入思考如何使简历…

SpringMVC第一天

简介 SpringMVC技术与Servlet技术功能等同&#xff0c;均属于web层开发技术 SpringMVC是一种基于java实现的MVC模型的轻量级Web框架 优点 使用简单,开发便捷(相比于Servlet) 灵活性强 入门案例 第一步、导入SpringMVC与Servlet坐标 <?xml version"1.0" encod…

flink内存管理(二):MemorySegment的设计与实现:(1)架构、(2)管理堆内/外内存、(3)写入/读取内存、(4)垃圾清理器

文章目录 一. MemorySegment架构概览二. MemorySegment详解1.基于MemorySegment管理堆内存2.基于MemorySegment管理堆外内存3.基于Unsafe管理MemorySegment4.写入和读取内存数据5.创建MemoryCleaner垃圾清理器 在flink内存管理&#xff08;一&#xff09;中我们已经知道&#x…

四.Winform使用Webview2加载本地HTML页面并互相通信

Winform使用Webview2加载本地HTML页面并互相通信 往期目录本节目标核心代码实现HTML代码实现的窗体Demo2代码效果图 往期目录 往期相关文章目录 专栏目录 本节目标 实现刷新按钮点击 C# winform按钮可以调用C# winform代码显示到html上点击HTML按钮可以调用C# winform代码更…

Python schedule任务调度及其用法

如果需要执行更复杂的任务调度&#xff0c;则可使用 Python 提供的 sched 模块。该模块提供了 sched.scheduler 类&#xff0c;该类代表一个任务调度器。 sched.scheduler(timefunctime.monotonic, delayfunctime.sleep) 构造器支持两个参数&#xff1a; timefunc&#xff1a…

思迅商旗-loaddata-信息泄露-未公开Day漏洞复现

0x01阅读须知 本文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考。本文章仅用于信息安全防御技术分享&#xff0c;因用于其他用途而产生不良后果,作者不承担任何法律责任&#…

比特币狂人引爆达沃斯论坛

点击查看TechubNews原文链接&#xff1a;比特币狂人引爆达沃斯论坛 比特币狂人、自称无政府资本主义者的阿根廷总统米莱在达沃斯的最新演讲引爆社交网络大讨论。 1 月 15 日&#xff0c;第 54 届世界经济论坛在瑞士阿尔卑斯山的达沃斯开幕。来自约 60 个国家首脑和跨国公司的领…

UE5 - Polycam扫描文件导入插件

Polycam是利用Gaussian Splatting进行3D重建的3D扫描相关软件&#xff0c;其对应有UE引擎的插件&#xff08;Plugin_XV3dGS&#xff09;可以把相关格式的文件导入到引擎&#xff1b; 首先Polycam的官网为&#xff1a;My Captures | Polycam 可以下载各种用户扫描文件&#xff…

Linux中的共享内存

定义&#xff1a; 共享内存允许两个或者多个进程共享物理内存的同一块区域&#xff08;通常被称为段&#xff09;。由于一个共享内存段会称为一个进程用户空间的一部分&#xff0c;因此这种 IPC 机制无需内核介入。所有需要做的就是让一个进程将数 据复制进共享内存中&#xff…

Mysql运维篇(三) MySQL数据库分库分表方案

一路走来&#xff0c;所有遇到的人&#xff0c;帮助过我的、伤害过我的都是朋友&#xff0c;没有一个是敌人&#xff0c;如有侵权请留言&#xff0c;我及时删除。 一、前言 关系型数据库本身比较容易成为系统瓶颈&#xff0c;单机存储容量、连接数、处理能力都有限。当单表的数…

Liunx系统和Window系统有什么区别

在信息技术世界里&#xff0c;操作系统扮演着至关重要的角色&#xff0c;它负责管理和控制计算机硬件与软件资源。Linux和Windows是市面上两个最流行的操作系统。接下来&#xff0c;我们将深入研究这两种操作系统的主要差异。 核心体系结构及源代码访问&#xff1a; 首先&#…

多线程-线程状态和线程安全(加锁-synchronized 关键字)

目录 1.线程状态 示例&#xff1a; 1.1线程状态和状态转移的意义 2.线程安全 2.1观察线程不安全 2.2线程不安全的原因 3.synchronized 关键字 - 监视器锁 monitor lock 3.1synchronized 的特性 1. 互斥 2.可重⼊ 应用示例&#xff1a; 3.2synchronized 使⽤⽰例 1.…

简单了解AJAX

文章目录 1、什么是AJAX2、AJAX快速入门3、Axios异步框架3.1、Axios 快速入门3.2、Axios 请求方式别名 1、什么是AJAX 概念&#xff1a;AJAX(Asynchronous JavaScript And XML)&#xff1a;异步的 JavaScript 和 XML AJAX作用&#xff1a; 与服务器进行数据交换&#xff1a;通…

【Unity学习笔记】New Input System 部分源码和测试用例补充

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/135630016 作者&#xff1a;CSDN|Ringleader| 主要参考&#xff1a; Unity官方Input System手册与API【Unity学习笔记】Unity TestRunner使用【Unity学习笔记】第十二 New Inp…

k8s资源介绍

Kubernetes架构图 Kubernetes系统用于管理分布式节点集群中的微服务或容器化应用程序&#xff0c;并且其提供了零停机时间部署、自动回滚、缩放和容器的自愈&#xff08;其中包括自动配置、自动重启、自动复制的高弹性基础设施&#xff0c;以及容器的自动缩放等&#xff09;等…

java黑马学习笔记

数组 变量存在栈中&#xff0c;变量值存放在堆中。 数组反转 public class test{public static void main(String[] args){//目标&#xff1a;完成数组反转int[] arr {10,20,30,40,50};for (int i 0,j arr.length - 1;i < j;i,j--){int tep arr[j]; //后一个值赋给临时…

数学建模常见算法的通俗理解(2)

目录 6 K-Means&#xff08;K-均值&#xff09;聚类算法&#xff08;无需分割数据即可分类&#xff09; 6.1 粗浅理解 6.2 算法过程 6.2.1 选定质心 6.2.2 分配点 6.2.3 评价 7 KNN算法&#xff08;K近邻算法&#xff09;&#xff08;K个最近的决定方案&#xff09; 7.…

怎么从视频中提取动图?一个方法快速提取gif

视频以连续的方式播放一系列图像帧&#xff0c;通过每秒播放的帧数&#xff08;帧率&#xff09;来创做&#xff0c;由于GIF动图则以循环播放一系列静态图像帧的方式展现动画效果。由于视频的优势在于流畅的动画、丰富的细节和长时间播放&#xff0c;因此常用于电影、电视节目、…