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

深度理解进程的概念(Linux)

目录

一、冯诺依曼体系

二、操作系统(OS)

设计操作系统的目的

核心功能

 系统调用

三、进程的概念与基本操作

简介

查看进程

通过系统调用获取进程标识符 

通过系统调用创建进程——fork()

四、进程的状态 

 操作系统中的运行、阻塞和挂起

 理解linux内核链表

 Linux的进程状态

孤儿进程 

五、进程的优先级

查看进程优先级的命令

优先级的极值

进程的竞争、独立和并发

六、进程切换

Linux真实调度算法:O(1)调度算法 


一、冯诺依曼体系

我们所知的计算机大部分都遵循冯诺依曼体系,他们都是由一个个硬件组成的 

输入单元:包括键盘,鼠标,扫描仪等

中央处理器(CPU):含有运算器和控制器等

输出单元:显示器,打印机

(图1) 

理解:

这里的存储器指的是内存。

不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设。

外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。

CPU在数据层面只和内存打交道,所有的设备都只能和内存打交道。

知识点:

1、 体系结构规定,软件没有运行的时候在外设磁盘里面,运行的时候再把它加载到内存里面来,CPU再从内存读取数据来执行代码,所以数据流动的本质就是从一个设备“拷贝”到另一个设备,体系结构效率的高低由设备的“拷贝”效率决定。

2、为什么数据不直接从输入设备直接到CPU在从CPU直接到输出设备呢?

因为存储分级的时候,不同的设备对应的“拷贝”效率,越靠近CPU,效率就越高,CPU的速率要远远高于IO设备,CPU都把数据处理完了,而IO设备还在写入或者读取数据,所以就会导致整个体系的效率由IO设备决定,那为什么不把整个体系中需要处理数据的设备都安排存储分级更高的寄存器呢?因为成本太高了,冯诺依曼体系结构的历史意义就是在保证一定的效率前提下使成本减低。

(图2)

 3、在数据流层面上理解冯诺依曼体系

如我们用qq发信息的数据流动过程,先把qq加载到内存上,把从键盘上的数据存入到内存中,CPU接收到内存中的数据后,经过计算处理后写回内存,再通过qq流入到输出设备,也就是网卡,通过网络传给另一台计算机的输入设备(网卡),存到内存后通过CPU解码后写回到存储器,再刷新到外设(显示器)上。

二、操作系统(OS)

任何一个计算机体系都包含一个基本的程序集合,称之为操作系统。

包括内核(进程管理,内存管理,文件管理,驱动管理)

及其他程序(例如数据库,shell程序等等)

(图3) 

设计操作系统的目的

体系结构:

(图4) 

对下 ,与硬件交互,管理所有的软硬件资源。

硬件部分根据冯诺依曼体系结构组成,访问不同的硬件就要不同的驱动程序,这些工作就是由操作系统完成。

对上,为用户提供一个良好的执行环境。

 知识点

1、软硬件体系结构都是层状结构。

2、访问操作系统,必须使用系统调用,其实就是由系统提供的函数。

3、我们写的程序只要你判断出它访问了硬件,它必须贯穿整个软硬件体系结构。

4、库在底层封装了系统调用。

核心功能

在整个计算机软硬件架构中,操作系统的定位就是一款纯正的"搞管理"的软件。

管理把它理解为“先描述,再组织”。

描述就是把被管理者的属性罗列出来,放在一个结构体中。

组织就是把结构体用指针或者其他方式连接起来。

操作系统在对软硬件管理的时候其实就是“先描述,再组织”,先把软硬件属性、状态等以结构体的方式罗列出来,再把结构体用队列或者链表等方式组织起来,所以操作系统对软硬件的管理就变成了对队列或者链表的增删改查

 系统调用

在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口就叫做系统调用

系统调用在使用上,功能比较基础,对用户的要求相对比较高,所以,有心的开发者可以对部分系统调用进行适度的封装,从而形成库,有了库,就更利于上层用户或者开发者进行二次开发,所以库函数和系统调用是一种上下层的关系

系统调用本质上就是操作系统和用户之间进行某种形式的数据交换,如果让用户直接去访问操作系统的系统调用接口成本高,而且不安全。

其实就是保证在整个环境的安全运行环境下给用户提供服务。

三、进程的概念与基本操作

简介

进程=PCB+自己代码和数据

PCB是存放进程的状态,代码地址,数据地址,id,优先级等信息的,里面包含进程的所有属性,通过PCB提供的属性来对辰戌进行管理,在Linux操作系统中PCB是task_struct.

我们历史上执行的所有指令,工具,自己的程序,运行起来,全部都是进程

查看进程

1、可以通过 /proc系统文件查看,如要获取PID为1的进程信息,ls /proc/1

2、大多数进程可以通过top、ps这些用户级工具来查

补充知识点 

(图5)

exe是进程对应的可执行文件 

cwd是当前工作目录,在使用fopen函数对一个没有创建的文件进行写操作时,可以带路径,也可以不带路径,因为进程启动时会找到cwd,并把新文件创建到cwd下,chdir可以改变cwd

通过系统调用获取进程标识符 

gitpid(),获取进程id

gitppid(),获取父进程id

输入的命令、代码运行起来后它们的父进程都是bash,也就是命令行解释器。

OS会给每一个登录用户分配一个bash。

通过系统调用创建进程——fork()

fork()有两个返回值,进程创建成功,会把子进程的pid返回给父进程,0返回给子进程,失败返回-1给父进程。

默认情况下,父进程与子进程共享代码,在子进程创建成功后子进程会把父进程的pcb拷贝下来,再做与其属性对应的修改

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{int ret = fork();if (ret < 0) {perror("fork");return 1;}else if (ret == 0) { //childprintf("I am child : %d!, ret: %d\n", getpid(), ret);}else { //fatherprintf("I am father : %d!, ret: %d\n", getpid(), ret);}sleep(1);return 0;
}

(代码1) 

运行结果:

(图6) 

 知识点:

对于代码1

1、为什么要给父进程和子进程返回不同的值?

一个父进程可能有多个子进程,父进程要通过子进程的pid对他进行管理,所以要返回子进程的pid给父进程

子进程只有一个父进程,他可以通过ppid获取父进程,所有只需要通过返回值来知道它是否被创建成功即可

2、为什么一个函数函数会返回两次

在执行fork函数时,在执行return语句之前子进程已经被创建好了,他和父进程共享代码,所以父子进程都会执行return语句

3、为什么一个变量既大于0,又等于0,代码1的if 和else同时成立

进程具有独立性,他们的PCB不同,默认指向相同的代码和数据,代码是常量不能修改,在数据修改时不管是父子的哪一方进行数据修改,os都会把对修改的数据在底层拷贝一份,让目标进程修改这个拷贝,来保证进程的独立性,这种形式叫做写时拷贝。

四、进程的状态 

(图7) 

 操作系统中的运行、阻塞和挂起

(图8)

运行:只要进程在调度队列中,它的状态就是running。

阻塞:进程在等待某种设备或者资源就绪(如键盘、网卡、磁盘等),比如程序运行到scanf或者cin这条语句,现在进程就是在等到键盘的反应,而cpu对硬件的管理也会进行结构体描述再组织一个队列,这个结构体中就包含了 “等待队列” 这个成员,在os没有收到键盘的反应时,进程就会从调度队列被链入到等待队列,直到os收到键盘的反应后再重新链入到调度队列。

挂起:如果更多的进程被链入到等待队列导致cpu资源紧张的时候,在磁盘中有一个“swap交换分区”,OS会把阻塞状态的进程的代码和数据唤出到这个分区而PCB不动,此时他就处于阻塞挂起状态等收到资源的反应时再把对应的代码和数据唤入回来;如果是调度队列的太多导致资源紧张,os也会按照进程重要性与“swap交换分区”进行唤入和唤出操作,此时进程就属于运行挂起状态。

进程状态的变换表现之一就是要在不同的队列中进行流动。本质上都是对某种数据结构的增删查改。

 理解linux内核链表

在task_struct里面还存在一个list_head的结构体,

 正是因为有了它,我们的task_struct就可以以这样的方式连接起来:

(图9)

找到首地址的方式(struct task_struct*)(next-&(struct task_struct*)0)。

 task_struct中也可以有多个不同的list_head,所以一个PCB可以隶属于多种数据结构。

(图10)

 Linux的进程状态

进程状态就是task_struct内的一个整数

R状态对应的就是操作系统中运行状态。

S和D状态对应的就是操作系统中阻塞状态,在linux中叫休眠状态。

其中S状态是可中断休眠(浅睡眠)。

D状态是不可中断休眠(深睡眠),比如有一个进程需要在磁盘中写入数据,在写的过程中进程属于S状态,此时内存的资源紧张,os就把这个进程释放掉了,而磁盘恰好又写入失败了,在CPU中控制这个任务的进程不在了,接收不到成功与否的信息的同时数据也不知道如何管理,就有可能会丢失,而D状态的就可以保证这时候的进程不被“杀死”,规避了数据丢失的风险。

T和t是暂停状态输入Linux操作系统的特有状态,当操作系统觉得当前进程有问题或者其他情况,就会把它暂停,在由用户决定这个进程是否继续。

使用gdb时对语句打断点就会使得程序被debug,此时进程就是 “t” 状态;在键盘中输入ctrl+r就进入T状态

X状态(死亡状态)对应操作系统中的结束状态

Z状态(僵尸状态),在Linux操作系统中所有的进程一定是某一个进程的子进程,创建子进程的目的是为了让子进程执行任务的,任务的结果父进程需要知道,子进程的数据可以清除掉,但是他的PCB必须要维持起来,所以在子进程退出之后,父进程获取退出信息之前,子进程的状态就是Z状态

僵尸状态的模拟:

#include <stdio.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if (id < 0) {perror("fork");return 1;}else if (id > 0) { //parentprintf("parent[%d] is sleeping...\n", getpid());sleep(30);}else {printf("child[%d] is begin Z...\n", getpid());sleep(5);exit(EXIT_SUCCESS);}return 0;
}

结果:

(图11)

可以看到子进程变成了Z状态,当时他还有PID,所以如果父进程对子进程的状态一直不管 ,信息一直不回收,那么子进程就会一直处于僵尸状态,PCB就一直需要维护,并会造成内存资源的浪费。

slab机制

当一个进程结束后他的PCB选择可以不释放,而是把他放到一个表中存起来,当再有新进程运行起来的时候,就可以再表里面把PCB拿出来,把它初始化后就可以使用了,节省了一定的效率

孤儿进程 

父进程比子进程先退出,子进程就叫做 “孤儿进程”

模拟孤儿进程代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if (id < 0) {perror("fork");return 1;}else if (id == 0) {//childprintf("I am child, pid : %d\n", getpid());sleep(10);}else {//parentprintf("I am parent, pid: %d\n", getpid());sleep(3);exit(0);}return 0;
}

进程的结果:

可以看到, 当父进程退出后,子进程就被一个PID为1的进程“领养”了,对于1号进程暂时可以把它理解为操作系统,如果不被“领养”的话,子进程进入僵尸状态后就会造成资源浪费,被“领养”后子进程就可以被1号进程回收了,被1号进程“领养”后子进程就会自动变成后台进程,ctrl+c就不能关闭它,用 “kill -9 pid”才可以关闭这个进程。

对于1号进程,在前面的 “进程概念” 中提到,当我们登录Linux操作系统时,操作系统会给用户分配一个bash,这个bash就是1号进程分配的;0号进程也是存在的,它在开机的时候就被1号进程给替换掉了。

五、进程的优先级

优先级是进程得到CPU资源的先后顺序。

优先级也是一种数字,是int类型,在task_struct里面。

值越低,优先级越高,反之优先级越低。

计算机的操作系统是基于时间片的分时操作系统,规定了每个进程的调度时间问题,时间片到了就会把进程从CPU上面剥离下来因为要考虑公平性,所以改变优先级的幅度不能太大。

使用ps -l命令查看优先级的时候能看到UID、PRI和NI等属性

 UID就是用户名,

PRI是进程的优先级,默认值为80,

NI是进程优先级的修正数据,

进程的真实优先级=PRI的默认值(也就是80)+NI

查看进程优先级的命令

进入top后按“r”,再输入进程PID,再输入nice值。

也可以通过系统调用:

优先级的极值

Linux进程的优先级范围是[60,99],

nice值:[-20,19],

基于时间片的分时操作系统,规定了每个进程的调度时间问题,如果优先级设计的不合理就会导致优先级低的进程长时间的得不到CPU资源,进而导致进程饥饿。

进程的竞争、独立和并发

竞争性:系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级

 独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰并行:多个进程在多个CPU下分别,同时进行运行,这称之为并行

并行:多个进程在多个CPU下分别,同时进行运行,这称之为并行

并发:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

六、进程切换

引言

1、死循环进程不会打死系统,它不会一直占有CPU,因为存在时间片,规定时间到了就把进程切换了。

2、一个CPU里有很多寄存器,它就是CPU内部的临时空间,可以用来存放正在运行的进程的临时数据,但寄存器并不等于寄存器里面的数据

(图12) 

进程切换最核心的就是保存和恢复当前进程的硬件上下文的数据,即CPU内存的内容,

当前进程要把自己的进程硬件上下文数据保存起来,就是保存到task_struct里面:

(图13) 

Linux真实调度算法:O(1)调度算法 

(图14)

 解释:

1、一个CPU拥有一个调度队列

2、queue[140]

一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以数组下标就是优先级,其中[0,99]下标主要用于实时操作系统,应用于制造业、工业等领域,[100,140]就是我们要了解的,进程在进程队列的下标等于:进程优先级-60+(140-40)

3、bitmap[5]

称之为位图,unsing int bitmap[5],它有32x5个比特位,每个比特位里面的数据1/0表示在queue的队列有没有进程,比如101.......111,就表示queue数组中下标为0的数组里面有数据,下标为1的数组里面没有数据,所以调度器调用进程就变成了,遍历比特位中的数据,再看queue数据,使调度的时间复杂度为O(1)

4、*active和*expired

操作系统具有分时的特性,当一个进程在它的调度时间片用完后,就被按优先级放入到了*expired所指向的队列中,*active队列中所有的进程时间片用完后,在把两个队列进行交换swap(&active,&expired),像这样一直循环这个操作

七、环境变量 

概念

环境变量一般指在操作系统中用来指定操作系统运行环境的一些参数,

如:在编写c/c++代码的时候,链接过程中,我们不知道所链接的动静态库在哪里,但是照样可以链接成功,输出可执行程序,原因就是有相关的环境变量帮助编译器进行查找

环境变量通常具有某些特殊用途,它在系统中通常具有全局特性

 命令行参数

main函数的两个参数argc,argv[ ]作用

(图15)

用上图15的理论来实现自己写的code的不同子功能

//指令选项的原理
//main函数的参数,就是用来实现程序不同子功能的
int main(int argc,char* argv[])
{if (argc != 2){printf("Usage: %s [-a|-b|-c]", argv[0]);return 1;}const char* arg = argv[1];if (strcmp(argv, "-a") == 0)printf("这是功能1\n");else if (strcmp(argv, "-b") == 0)printf("这是功能2\n");else if (strcmp(argv, "-c") == 0)printf("这是功能3\n");elseprintf("Usage: %s [-a|-b|-c]", argv[0]);return 0;
}

结果:

 所以得出结论进程会拥有一张命令行表,argv表来实现功能选项。

 5个问题切入环境变量

问题1:为什么我们自己写的程序需要带路径才能执行,./表示当前路径,而系统自带的不用带路径就可以执行?

答:因为系统自带的配置了环境变量

问题2:根据问题1的回答,现在ls这个指令在"/usr/bin"目录下面,那我们把自己写的code也把它拷贝进入"/urs/bin“目录下面是不是就可以和系统的指令一样,不用带路径了呢?
答:是的,但是不建议 

问题3:它为什么会自己去“use/bin”目录下面去查呢?
答:还是因为配置了环境变量:PATH,PATH的作用是告诉系统怎么找文件 

env:查看所有的环境变量;

echo &+环境变量名:仅查看一个环境变量

问题4:那如果我把我的"code”文件的路径加入到这个PASH环境变量里面,是不是也可以达到上面的效果?
答:是的!

方法

问题5:把Xshell关掉,重新进来的时候发现PASH路径又回复原有的样子了,为什么?

答:这要在从存储的角度去理解环境变量。
当我们登录的时候系统给我们创建了一个bash进程,bash必须从系统中读取所有环境变量的
信息,随后在bash进程的内部就形成了一种环境变量表;当我们输入命令时,bash先拿到命令,把命令进行拆分后,放入到命令行参数表,再找需要执行的命令是否存在。
env命令查的就是这张环境变量表,bash进程就有命令行表和环境变量表,
所以要执行一个程序bash要先通过环境变量找到他。

获取环境的方法

操作

export 变量名=变量值,自己导入环境变量,它是一个内建命令,它在执行时不需要创建子进程,由bash自己执行,不会经手子进程

env:查看所有环境变量

echo &变量名:仅查看一个环境变量

unset 变量名:删除环境变量

代码:

1、main函数的参数共有三个,除了“argc”和“argv”,还有一个“char* env[ ]”(环境变量指针数组),这三个参数都是父进程传给main的。

int main(int argc,char* argv[])
{//env数组的最后一个元素也是NULLfor (int i = 0; env[i]; i++){printf("env[%d] -> %s\n", i, enc[i]);}return 0;
}

2、getenv(“变量名”)

环境变量为什么是全局变量可以传给子进程呢?因为它可以让子进程有一些个性化的操作,

比如我想让代码只能由我一个人使用:

int main(int argc, char* argv[])
{const char* who = getenv("USER");if (who == NULL) return 1;if (strcmp(who, "whb") == 0){printf("正常执行");}elseprintf("only whb\n");return 0;
}

3、变量environ

//libc中定义的全局变量environ指向环境变量表,
//environ没有包含在任何头⽂件中, 所以在使⽤时 要⽤extern声明。
int main(int argc, char* argv[])
{extern char** environ;int i = 0;for (; environ[i]; i++) {printf("%s\n", environ[i]);}return 0;
}

 八、程序地址空间

引言

学习c语言的时候脑海中会有这样的图:

它就是程序地址空间图,也就是进程地址空间图(虚拟地址空间图),它属于系统层面的概念

其中,字符串是只读的原因就是它被编码成了代码,在代码区只读,

static修饰的变量本质就是全局变量,只是让他只能在某个函数内被访问而已

 那程序地址空间是内存吗?

跟随代码:

int gval = 100;
int main()
{pid_t id = fork();if (id == 0){//子进程创建成功while (1){printf("子:gval:%d,&gval;%p,pid:%d,ppid:%d\n", gval, &gval, getpid(), getppid());sleep(1);gval++;}}else{//父进程while (1){printf("父:gval:%d,&gval;%p,pid:%d,ppid:%d\n", gval, &gval, getpid(), getppid());sleep(1);}}
} 

结果:

(图16)

结论:父子进程地址一样,如果这个地址是内存地址的话,同一个地址空间怎么会有两个不同的值呢? 所以这个地址一定不是内存地址,它是虚拟地址,所学的c/c++指针用的地址全都是虚拟地址!

 通过一张图了解页表、物理地址和虚拟地址的关系

(图17) 

解释:

一个进程就有一个虚拟地址空间和一套页表。

页表当中存了虚拟地址和对应的物理地址,用户是看不到物理地址的,当用户要访问这块数据时,页表就会通过虚拟地址映射到物理地址。

子进程的PCB、虚拟地址、页表全部都是拷贝父进程的,所以在默认情况下。父进程和子进程的代码和数据都是共享的。

对图16的运行结果,子进程在进行gval++时,他会把物理地址的数据拷贝到一块新空间,在对新空间里面的数据进行修改,并且会更新页表,这叫做写时拷贝。

 虚拟地址空间是什么?

虚拟地址空间本质就是操作系统给进程创建的一个结构体对象,一部分数据如下:

问题:为什么要有虚拟地址空间呢?为什么不直接去物理空间上找,而是要通过虚拟地址映射找呢?

因为:

1、页表当中除了虚拟地址和物理地址之外,还有对应地址的权限,在
地址转化的过程中,也可以对地址的的操作合法性进行判断,进而保护
内存,所以在对字符常量区的数据写入失败时的原因就是,查找页表的
时候权限拦截了

2、将地址从“无序”变为“有序”

物理空间的地址可以不是连续的,因为每一个物理空间地址对应的虚拟空间是有序的

3、节省内存空间,缺页中断,动态加载

4、让进程管理和内存管理进程解耦合

知识点:

1、在创建一个进程时,可以不加载代码和数据,只有task struct,mm struct和页表 

因为当虚拟地址想要通过页表映射找物理地址时,没有发现物理地址时进程就会暂停进行缺页中断们进行补全,如果代码和数据非常大就达到可节省内存空间的目的

2、创建进程先有task struct,mm_struct等,再加载代码和数据

3、进程挂起时,进程的唤出换入swap分区操作时,只把代码和数据换入/唤出,保存PCB,这就是解耦合的作用

4、在mm_struct里面还有一个vm_area_struct,它里面细分了每一段地址空间的起始和结束地址,而mm_struct就是包含整体的栈、堆、代码段等空间的起始地址。

相关文章:

深度理解进程的概念(Linux)

目录 一、冯诺依曼体系 二、操作系统(OS) 设计操作系统的目的 核心功能 系统调用 三、进程的概念与基本操作 简介 查看进程 通过系统调用获取进程标识符 通过系统调用创建进程——fork() 四、进程的状态 操作系统中的运行、阻塞和挂起 理解linux内核链表 Linux的进…...

【C++】STL容器中的比较函数对象

目录 set、map容器 priority_queue容器 在STL中涉及到以某种规则排序的容器都需要比较函数对象&#xff0c;比如&#xff1a;set、map、priority_queue这些容器内部都是依赖比较函数对象以某种规则存储数据的。STL容器中的比较函数对象可以是&#xff1a;函数指针、仿函数(函…...

深度学习基础02_损失函数BP算法(上)

目录 一、损失函数 1、线性回归损失函数 1.MAE损失 2.MSE损失 3.SmoothL1Loss 2、多分类损失函数--CrossEntropyLoss 3、二分类损失函数--BCELoss 4、总结 二、BP算法 1、前向传播 1.输入层(Input Layer)到隐藏层(Hidden Layer) 2.隐藏层(Hidden Layer)到输出层(Ou…...

6.584-Lab4A

6.584-LabA HomeworkReference CodeReference Blog 通过作业提供的概览图可以看出整个系统的组成&#xff1a;用户 Clerk 会发出命令&#xff08;Get、Put、Append&#xff09;到每个 Service&#xff0c;每个 Service 接收到命令后向下传递到 RaftCode 层&#xff0c;由 RaftC…...

语义版本控制

注意&#xff1a; 本文内容于 2024-11-27 22:25:05 创建&#xff0c;可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容&#xff0c;请访问原文地址&#xff1a;语义版本控制。感谢您的关注与支持&#xff01; 由于自己平时喜欢写点小玩意&#xff0c;自然而…...

深入理解HTML基本结构:构建现代网页的基石

深入理解HTML基本结构&#xff1a;构建现代网页的基石 在数字时代&#xff0c;HTML&#xff08;超文本标记语言&#xff09;是构建和设计网页的基础。了解HTML的基本结构对于任何希望掌握网页开发的人来说至关重要。本文将详细介绍HTML文件的基本骨架&#xff0c;包括其核心标…...

一体化数据安全平台uDSP 入选【年度创新安全产品 TOP10】榜单

近日&#xff0c;由 FreeBuf 主办的 FCIS 2024 网络安全创新大会在上海隆重举行。大会现场揭晓了第十届 WitAwards 中国网络安全行业年度评选获奖名单&#xff0c;该评选自 2015 年举办以来一直饱受赞誉&#xff0c;备受关注&#xff0c;评选旨在以最专业的角度和最公正的态度&…...

【机器学习】机器学习的基本分类-监督学习(Supervised Learning)

监督学习是一种通过已有的输入数据&#xff08;特征&#xff09;和目标输出&#xff08;标签&#xff09;对模型进行训练的机器学习方法&#xff0c;旨在学到一个函数&#xff0c;将输入映射到正确的输出。 1. 监督学习概述 监督学习需要&#xff1a; 输入数据&#xff08;特…...

Oracle之提高PLSQL的执行性能

目录 1、SQL解析详解 2、演示示例 3、启用Oracle跟踪事件 4、查看改造后SQL性能对比结果 更多技术干货,关注个人博客吧 1、SQL解析详解 SQL解析是数据块处理SQL语句不可缺少的步骤,是在解析器中执行的。将SQL转换成数据库可以执行的低级指令。 SQL解析分为硬解析和软…...

[VSCode] vscode下载安装及安装中文插件详解(附下载文件)

前言 vscode 链接&#xff1a;https://pan.quark.cn/s/3acbb8aed758 提取码&#xff1a;dSyt VSCode 是一款由微软开发且跨平台的免费源代码编辑器&#xff1b;该软件支持语法高亮、代码自动补全、代码重构、查看定义功能&#xff0c;并且内置了命令行工具和Git版本控制系统。 …...

PHP中类名加双冒号的作用

在 PHP 中&#xff0c;类名加双冒号&#xff08;::&#xff09; 是一种用于访问类的静态成员和常量的语法。它也可以用来调用类的静态方法和访问 PHP 的类相关关键词&#xff08;如 parent、self 和 static&#xff09;。以下是详细的解释和用法。 1. 用途概述 :: 被称为作用域…...

前端编程训练 异步编程篇 请求接口 vue与react中的异步

文章目录 前言代码执行顺序的几个关键点接口请求vue与react中的异步vue中的异步react的state修改异步 前言 本文是B站三十的前端课的笔记前端编程训练,异步编程篇 代码执行顺序的几个关键点 我们可以理解为代码就是一行一行&#xff0c;一句一句是执行&#xff08;定义变量&…...

【kafka03】消息队列与微服务之Kafka 读写数据

Kafka 读写数据 参考文档 Apache Kafka 常见命令 kafka-topics.sh #消息的管理命令 kafka-console-producer.sh #生产者的模拟命令 kafka-console-consumer.sh #消费者的模拟命令 创建 Topic 创建topic名为 chen&#xff0c;partitions(分区)为3&#xff0…...

【分布式系统】唯一性ID的实现

1、UUID&#xff08;通用唯一标识符&#xff09; 1、UUID本身 一种用于标识信息的标准化方法。一个128位的数字&#xff0c;常表示为32个十六进制数字&#xff0c;以连字符分隔成五组&#xff1a;8-4-4-4-12。 版本&#xff1a; UUID有不同的版本&#xff0c;最常见的是基于时…...

哪里能找到好用的动物视频素材 优质网站推荐

想让你的短视频增添些活泼生动的动物元素&#xff1f;无论是搞笑的宠物瞬间&#xff0c;还是野外猛兽的雄姿&#xff0c;这些素材都能让视频更具吸引力。今天就为大家推荐几个超实用的动物视频素材网站&#xff0c;不论你是短视频新手还是老手&#xff0c;都能在这些网站找到心…...

SRAM芯片数据采集解决方案

SRAM芯片数据采集解决方案致力于提供一种高效、稳定且易于操作的方法&#xff0c;以确保从静态随机存取存储器SRAM芯片中准确无误地获取数据。 这种解决方案通常包括硬件接口和软件工具&#xff0c;它们协同工作&#xff0c;以实现对SRAM芯片的无缝访问和数据传输。 在硬件方…...

【贪心算法第七弹——674.最长连续递增序列(easy)】

目录 1.题目解析 题目来源 测试用例 2.算法原理 3.实战代码 代码分析 1.题目解析 题目来源 674.最长递增子序列——力扣 测试用例 2.算法原理 贪心思路 3.实战代码 class Solution { public:int findLengthOfLCIS(vector<int>& nums) {int n nums.size();in…...

[AI] 知之AI推出3D智能宠物:助力语言学习与口语提升的新选择

Hello! 知之AI官网 [AI] 知之AI推出3D智能宠物&#xff1a;助力语言学习与口语提升的新选择 随着人工智能技术的飞速发展&#xff0c;虚拟助手和智能设备不断进入我们的生活。近日&#xff0c;知之AI重磅推出了一款创新产品——3D智能宠物。这一产品不仅具备多国语言交流能力&…...

Android 14之HIDL转AIDL通信

Android 14之HIDL转AIDL通信 1、interface接口1.1 接口变更1.2 生成hidl2aidl工具1.3 执行hidl2aidl指令1.4 修改aidl的Android.bp文件1.5 创建路径1.6 拷贝生成的aidl到1和current1.7 更新与冻结版本1.8 编译模块接口 2、服务端代码适配hal代码修改2.1 修改Android.bp的hidl依…...

【R库包安装】R库包安装总结:conda、CRAN等

【R库包安装】R studio 安装rgdal库/BPST库 R studio 安装rgdal库解决方法 R studio 安装BPST库&#xff08;github&#xff09;解决方法方法1&#xff1a;使用devtools安装方法2&#xff1a;下载安装包直接在Rstudio中安装 参考 基础 R 库包的安装可参见另一博客-【R库包安装】…...

学习PMC要不要去培训班?

在当今快速变化的商业环境中&#xff0c;PMC作为供应链管理的核心环节之一&#xff0c;其重要性日益凸显。PMC不仅关乎产品的物料计划、采购、库存控制及物流协调&#xff0c;还直接影响到企业的生产效率、成本控制以及市场竞争力。面对这一专业领域的学习需求&#xff0c;许多…...

前端 用js封装部分数据结构

文章目录 Stack队列链表Setset 用来数组去重set用来取两个数组的并集set用来取两个数组的交集set用来取两个数组的差集 字典 Stack 栈&#xff0c;先进后出&#xff0c;后进先出。用数组来进行模拟&#xff0c;通过push存入&#xff0c;通过pop取出。 class Stack {// 带#表示…...

cocoscreator-doc-TS:目录

cocoscreator-doc-TS-脚本开发-访问节点和组件-CSDN博客 cocoscreator-doc-TS-常用节点和组件接口-CSDN博客 cocoscreator-doc-TS-脚本开发-创建和销毁节点-CSDN博客 cocoscreator-doc-TS-脚本开发-加载和切换场景-CSDN博客 cocoscreator-doc-TS-脚本开发-获取和设置资源-CS…...

理解Java集合的基本用法—Collection:List、Set 和 Queue,Map

本博文部分参考 博客 &#xff0c;强烈推荐这篇博客&#xff0c;写得超级全面&#xff01;&#xff01;&#xff01; 图片来源 Java 集合框架 主要包括两种类型的容器&#xff0c;一种是集合&#xff08;Collection&#xff09;&#xff0c;存储一个元素集合&#xff08;单列…...

IOC容器实现分层解耦

文章开始之前&#xff0c;先引入软件开发的两个名词&#xff1a;耦合和内聚。耦合是指&#xff1a;衡量软件中各个层&#xff08;三层架构&#xff09;/各个模块的依赖关联程度&#xff1b;内聚是指&#xff1a;软件中各个功能模块内部的功能联系。三层架构中Controller、Servi…...

Flutter 共性元素动画

在 Flutter 中&#xff0c;共性元素动画&#xff08;Shared Element Transitions&#xff09;用于在页面导航或组件切换时创建视觉上更流畅和连贯的动画效果。这种动画可以使用户感受到两个界面之间的“物理联系”&#xff0c;比如图片从缩略图到全屏的扩大效果。 前置知识点整…...

K8s内存溢出问题剖析:排查与解决方案

文章目录 一、背景二、排查方案&#xff1a;1. 可能是数据量超出了限制的大小&#xff0c;检查数据目录大小2. 查看是否是内存溢出2.1 排查数据量&#xff08;查看数据目录大小是否超过limit限制&#xff09;2.2 查看pod详情发现问题 三、解决过程 一、背景 做redis压测过程中…...

乌班图单机(不访问外网)部署docker和服务的方法

面向对象:Ubuntu不能访问外网的机子,部署mysql、redis、jdk8、minio 过程: 1、安装docker(照着图去这里找对应的下载下来https://download.docker.com/linux/static/stable/),将7个docker官网下载的文件下载下来后,传上去服务器随便一个文件夹或者常用的opt或者/usr/lo…...

使用 pycharm 新建使用 conda 虚拟 python 环境的工程

1. conda 常见命令复习&#xff1a; conda env list // 查看 conda 环境列表 conda activate xxxenv // 进入指定 conda 环境2. 环境展示&#xff1a; 2.1. 我的物理环境的 Python 版本为 3.10.9&#xff1a; 2.2. 我的 conda 虚拟环境 env_yolov9_python_3_8 中的 pyth…...

Docker的save和export命令的区别,load和import的区别 笔记241124

Docker的save和export命令的区别,load和import的区别 解说1: Docker的save和export命令&#xff0c;以及load和import命令&#xff0c;在功能和使用场景上存在显著的区别。以下是对这两组命令的详细对比和解释&#xff1a; Docker save和export命令的区别 使用方式和目的&am…...

做封面的免费网站/网站制作工具有哪些

点击上方“蓝色字”可关注我们&#xff01;暴走时评&#xff1a;Morgan Creek的Anthony Pompliano宣称&#xff0c;与区块链领域的一些人的期望相反&#xff0c;Facebook最终将构建“加密货币领域中最常用的产品。”Pompliano的话也算是回应了The Block创始人Mike Dudas的推文&…...

webmin 添加网站/网站查找工具

最近在弄zabbix监控MySQL和Redis事宜&#xff0c;发现shell脚本无法解决字符串转换为整数操作&#xff0c;于是想到了Python&#xff0c;这里就用Python3环境 首先安装pymysql pip install pymysql 1 #!/usr/bin/env python2 # -*- coding: utf8 -*-3 import pymysql4 mysql_co…...

网站建设公司哪个好点/深圳做网站

关于挂载的作用一直不是很清楚&#xff0c;今天在阅读教材时看见了mount这个命令&#xff0c;发现它的用处很隐晦但非常强大。奈何教材说的不明朗&#xff0c;因此在网上整合了一些优秀的解释&#xff0c;看完之后豁然开朗。 1.提一句Windows下&#xff0c;mount挂载&#xff…...

dw5做简单的企业网站/百度推广话术全流程

Django的配置文件setting.py用于配置整个网站的环境和功能&#xff0c;核心配置必须有项目密钥配置、域名访问权限、App列表、中间件、资源文件、模板配置、数据库的连接方式。 1、基本配置信息 一个简单的项目必须具备的基本配置信息有&#xff1a;项目路径、密钥配置、域名…...

柳州哪里有网站建设/企业网络推广方法

一&#xff0c;介绍&#xff1a; 1&#xff0c;Nginx本身是一款静态&#xff08;html , js , css , jpg等&#xff09;www软件&#xff1b;特点是静态小文件高并发&#xff1b;同时占用资源少。网上说&#xff1a;3W并发&#xff0c;开10个线程 &#xff0c;消耗150M内存 n…...

如何建设网站并与数据库相连/关键词排名点击

centos 7 虚拟化支持&#xff1a;1、更高性能的KVM内核虚拟化支持2、嵌套虚拟化支持&#xff0c;可以在KVM中安装配置OpenStack3、继续支持作为虚拟机的Xen技术&#xff0c;但不再支持作为寄主机的Xen技术4、加强了对VMWARE的技术支持&#xff0c;自带open-vm-tools替换vm-tool…...