【Linux进程】Linux下的---七大进程状态(什么是进程状态?Linux下有哪些进程状态?)

news2024/11/25 5:46:55

目录

一、前言

二、什么是进程状态?

三、操作系统(OS)下的 --- 进程状态

🔥运行状态🔥

🔥阻塞状态🔥

🔥挂起状态🔥

四、Linux下的7种进程状态

🔥运行状态 -- R🔥

🔥浅度睡眠状态 -- S🔥

🔥深度睡眠状态 -- D🔥

🔥停止状态 -- T🔥

🔥进程跟踪状态 -- t🔥  

🔥死亡状态 -- X 🔥

🔥僵死状态Z —— 两个特殊进程 🔥

① 僵尸进程

② 孤儿进程

 五、总结与提炼

 六、共勉


一、前言

        进程 只有被 操作系统(OS)管理好了,才能发挥它的全部作用,而 系统存在多个 进程操作系统(OS)无法做到面面俱到,因此为了更好的管理 进程,操作系统把 进程 分成了几种状态:运行、阻塞、挂起、休眠等等。至于每种状态的应用场景是什么?有什么用?本文将会带大家认识各种 进程 状态


在谈 进程状态 之前,我们需要了解 什么是进程怎么去描述并组织进程如何创建一个进程

  • 操作系统(OS)的本质是:先描述,在组织
  • 操作系统并非直接管理 -- 进程,而是管理 进程 的 PCB(task_struct)
  • PCB 中有着进程的各种信息,包括:PID、PPID 、进程状态
  • 我们可以通过函数 getpid()  获取当前进程的  PID
  • 进程 间存在父子关系,可以通过 fork() 主动创建 子进程
  • 父子进程 相互独立,共享一份代码时,具有 写诗拷贝 机制

如果大家还有不了解-- 进程 --的可以先看一下这篇文章:Linux 下进程的基本概念

二、什么是进程状态?

为了弄明白正在运行的进程是什么意思,我们需要知道------进程的不同状态

  • 所谓的 进程状态 其实就是 PCB(task_struct)内部的一个整形变量 ----- int status
  • 操作系统(OS)要更改一个进程状态,只要更改进程的 PCB(task_struct)中的状态属性,它只是一个标志位用来表明进程的状态,仅此而已。


那么 状态 决定了什么呢?

  • 进程后续的动作! ---- 而 操作系统(OS)中可能会存在多个进程都要根据它的状态执行后续动作,所以说明 --状态-- 对于  操作系统后续如何管理 进程十分重要!!

三、操作系统(OS)下的 --- 进程状态

  • 对于进程而言呢,它是操作系统中的概念,如果有学习过《操作系统》这门学科的话应该可以很清楚对于进程而言的话是存在着许许多多的状态,如果一开始刚刚接触的小伙伴一定会感觉这么多状态要怎么区分呀😵

  •  其实那么多的状态,真正主要的也就那么几个,所以接下去我会中重点讲解以下几种进程的状态

🔥运行状态🔥

首先我们要谈到的是【运行状态】,这个状态是最普遍的:  进程 PCB 被调度到 CPU 运行队列中且已被分配 CPU 资源,就叫做 ------ 运行状态

一个CPU,一个运行队列,也就是说这些进程都需要在CPU这里进行排队,逐个执行。

而排队的是进程么?

其实不是,排队的是进程的PCB(面试时不是你在排队,而是你的简历信息在排队)。


  • 首先对于一个进程而言,我们知道它是由 内核数据结构 + 所对应的代码和数据 所组成的,所以当系统中存在多个进程的时候就势必会存在多个结构体;当然我们需要将这些进程给链接组织起来(双向链表链接
  • 那么这些 进程 就相当于是在处在一个运行队列中,我们如果要找到这个队列中的某个进程的话,只需要找到这个进程的头部即可,那我们就可以对应地去调度某个进程,把这个进程所对应的代码和数据放到CPU上去执行


 💬 因为每个进程是需要去竞争CPU资源的,但是呢CPU不可能同时给这么多进程分配资源

  • 所以每一个CPU都会去维护一个运行队列,里面的队 头指针 head 所指向就是第一个进程所对应的【PCB】队尾指针tail 所指向就是最后一个所对应的【PCB】。所以我们要运行某一个进程只需要将 head 所指向的那个进程放到 CPU上去运行即可


提问:一个 进程 只要把自己放到 CPU 上开始运行了,是不是一直要到执行完毕,才把自己放下来?

  • 不是,每一个进程都有一个叫做:时间片的概念! 其时间大概是在10 ms左右。所以并不是一个进程一直在执行,而是这多个进程在一个时间段内所有代码都会被执行 —— 这就叫做【并发执行】 
  • 所以呢这就一定会存在大量的进程 被CPU放上去、拿下来的动作 —— 这就叫做【进程切换】 

💬 所以呢我们不要拿自己的时间感受去衡量CPU,其运行一遍速度是非常快的,你根本感受不到这种进程切换的效果 

 🔥阻塞状态🔥

 何为阻塞?

  • 阻塞 就是 进程 因等待某种条件就绪,而导致的一种不推进状态(比如等待 键盘输入)。
  • 通俗的来说 阻塞 就是 进程卡住了原因就是缺少资源

比如在我们日常生活中,常常发生堵车,原因就是道路资源不够用了,车辆这个 进程 就需要原地等待 

那么进程需要什么资源呢?

  • 比如 磁盘网卡显卡 等各种外设
  • 假设你现在想在 steam 上下载游戏,当你点击下载按钮后提示磁盘空间不足,此时是无法运行 steam下载 这个进程的,因为此 进程 需要等待足够大的 磁盘资源
  • 此时我们就称此 进程 为 阻塞 状态

 总结: 进程 阻塞 就是不被调度

  • 此时 PCB(task_struct) 就会被设置为 阻塞状态,并链入等待的资源提供的等待队列
  • 没错,这里的等待队列 类似于 CPU 运行队列 

🔥挂起状态🔥

挂起(阻塞挂起):

  • 当 CPU 资源紧张时,将 进程的数据和代码 交换至 磁盘 中挂起,此时内存中只有 PCB
     
  • 挂起 可以看作一种特殊的 -- 阻塞状态

详解:

  • 当计算机资源比较吃紧时,操作系统一定要确保自身不会因为资源的紧张而崩溃,所以就会将一些等待资源(阻塞)的进程的代码和数据交换到磁盘的 swap分区 中,这个过程称为唤出
  • 当需要调度此进程时,就会将磁盘的 swap分区 中保存的内容换回到内存中,这个过程称为唤入

注意:交换的是进程的代码和数据,不是PCB!!如果PCB被交换出内存了,那操作系统如何管理呢?

所以当某个进程的代码和数据不在内存中,而被换出到磁盘上时,该进程就为挂起状态。


思考:swap分区是越大越好么? 

磁盘本质是输入输出设备,每次唤入唤出其实都是非常低效的操作,如果swap分区设置的过大,那么操作系统就会十分依赖它,导致出现更多低效IO,这本身就是一种牺牲效率来确保操作系统能够正常运行的行为。

所以swap分区不宜设置的过大,一般为内存大小或内存大小的一半,具体要看不同的操作系统。


举个-- 挂起-- 例子 : 

在我们生活中,一边走路一边玩手机很危险,所以此时我们会将玩手机这个 进程挂起 ,即把手机揣进兜里,然后 专心执行走路这个 进程


总结: 
看了上面的三种基本的进程状态后我们可以来总结一下,如果要看进程是什么状态的话一般看这个 进程在哪里排队

  • 位于【运行队列】的话它就是处于运行状态
  • 位于【阻塞队列】的话它就是处于阻塞状态

四、Linux下的7种进程状态

        在介绍完操作系统学科下的三种最主要进程状态后,我们对进程的状态有了基本的概念,接下去就让我们正式地来学习一下 Linux 系统7种进程状态

 先来小结并回顾一下上面所学:

  1. 如果当前是运行状态,那么接下来就需要被调度运行
  2. 如果当前是阻塞状态,那就等条件就绪,等设备准备好就把当前进程投递到运行队列里,然后再被CPU调度运行
  3. 如果当前是挂起状态,要做的就是把当时换出的代码和数据重新换入,然后再把所对应的进程列入到运行队列中

以下就是关于进程的所有状态 

static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

🔥运行状态 -- R🔥

 首先我们要来聊的是【运行状态R】

  • 来看下下面的这段代码,是一个死循环去 printf打印循环语句
   #include <stdio.h>
   #include <unistd.h>
   
   int main(void)
   {
      while(1);                                                                
      {
          printf("Hello process, pid: %d\n",getpid());
          sleep(1);
      }

      return 0;
   }
  • 然后我们将下面的代码给运行起来,观察这个进程的状态时,看到其显示为 S+,不过呢读者想看到的应该是 R 才对

  • 接下去呢,我们把代码修改一下再来看看,不使用 printf打印语句了,而且直接使用一个while(1)去做循环
   #include <stdio.h>
   #include <unistd.h>
   
   int main(void)
   {
      while(1);                                                                
      {
         //printf("Hello process, pid: %d\n",getpid());
         //sleep(1);
      }

      return 0;
   }
  • 然后我们看到,此时再运行起来时这个进程的状态就改变了,变成了 R+,这才是我们想要的【进程状态】

 💬 那有读者就要问了:为什么把 printf打印语句给去掉之后就变成这样了呢?

  • 原因就在于 printf 打印语句它是属于 IO流 的一种,第一次因为是循环的缘故,它一直在等IO设备就绪,所以其进程状态就一直为 S+,对应的即是在操作系统中的【阻塞状态】;但是当我们去掉 printf 这种IO流之后呢,它就是在纯纯运行,没有IO,那也就变成了 R 状态


 这里再补充说明一下这个  S 和 R 后面的 +

  • 这里的 R+ 代表的就是这个进程是在前台运行的,所以我们在输入任何指令后不会对其造成 任何的影响

  • 那若是我们不以正常的方式去启动这个进程的话,其进程的状态就会不一样了,可以看到我在 ./mytest 的后面加上了一个 &;那么其状态变成了 R,此代表的意思就是这个进程它是运行在了【后台】的

  •  不过呢,R状态并不代表这个进程就在运行,而代表其在运行队列中排队而已.

总结:
          "+"代表是前台运行,无"+"代表后台运行,后台运行时可在命令行继续输入指令并执行,但无法用ctrl+c结束,需要用kill -9 pid杀死。想要后台运行某个程序就在后面加"&",如:./test &


 🔥浅度睡眠状态 -- S🔥

 接下去我们再来介绍一下Linux下的睡眠状态S

  • 我们再通过一段代码来看看
   #include <stdio.h>
   #include <unistd.h>
   
   int main(void)
   {
       int a = 0;
       printf("Enter# ");
       scanf("%d", &a);
   
       printf("echo : %d\n", a);
       return 0;                                                                         
   } 

  • 将该进程运行起来我们可以看到其是出于 S+ 的状态,因为【shell】此时正在等待用户的输入,这个就对应到了我们上面所讲到的 阻塞状态


 🔥深度睡眠状态 -- D🔥

 除了【浅度睡眠】之外呢,还有一种叫做【深度睡眠】,它们俩呢,都是 阻塞状态

  • 对于浅度睡眠来说,之所以称为 “浅度”,是有原因的:也就是处于这种状态的进程容易被唤醒。例如说我们在上面所讲到的这个处于阻塞状态的进程,我们使用 kill -9 PID 向这个进程发送【9号信号】,那么这个进程就被杀死了,你也可以认为被唤醒了

 好,接下去呢我就通过一个故事📖来描述一下这个【深度睡眠】到底是怎样一种状态

  • 深度睡眠状态/不可中断睡眠状态/磁盘休眠状态,顾名思义,在这个状态的进程不会被杀掉,哪怕是操作系统也不行,通常会等待IO的结束。
  • 例如,某一进程要求对磁盘进行写入操作,那么在磁盘进行写入期间,该进程就处于深度睡眠状态,是不会被杀掉的,因为该进程需要等待磁盘的回复(是否写入成功)以做出相应的应答。
  • 如果在这个过程中,操作系统能够杀死该进程,那么就有可能丢失数据。

🔥停止状态 -- T🔥

好,接下去呢我们来讲讲【停止状态T

  • 首先我们要通过下面这句命令来查看一下对应的进程信号
kill -l
  • 此处我们要使用到的是18、19号信号

  • 接下去我们就来试一试如何让这个进程暂停之后又重新启动会是怎样的
#include <stdio.h>
#include <unistd.h>
 
int main()
{
   while(1)
   {
     printf("hello my process: %d\n",getpid());
     sleep(1);                                                                                       
   }
   return 0;
 }


 所以我们来总结一下

  • 暂停进程
kill -19 PID
  • 启动进程
kill -18 PID

💬 所以呢,如果我们要将一个进程给终止的话,发送19号信号即可,要让其继续启动起来,则发起18号信号 


那我现在要问了,这个 T停止状态S睡眠状态 有什么不同呢?

  1. stopped状态 进程 完全暂停了, 其不会再接收任何信号了
  2. 一个进程通过 stopped 状态可以控制另一个
  3. S 和 D 一定是在等待某种资源,而 T状态 可能在等待某种资源,也可能被其他进程控制

🔥进程跟踪状态 -- t🔥  

 接下去呢,我们再来说说进程的跟踪状态t,还记得我们在基础篇中所学习的 GDB 调试 吗?

  • 首先我们在正常状态下查看这个进程的状态,其为 S睡眠状态。接下去呢我进行了【gdb】调试,在行内打上断点后,输入 运行起来后,我们再去查看这个进程的状态时,就发现其状态变成了t原因就在于这个进程在调试的时候停了下来


🔥死亡状态 -- X 🔥

对于【死亡状态X】来说呢,这个状态只是一个返回状态,你不会在任务列表里看到这个状态🙅‍ 

  • 第一种方法就是向这个进程发送9号信号,就可以杀掉这个进程
kill -9 PID

  • 第二种方法就是通过这个进程的名称来杀掉它
killall 进程名


🔥僵死状态Z —— 两个特殊进程 🔥

接下去我们来介绍一种状态叫做【僵死状态Z】,对于这个状态,我们要涉及到两个特殊的进程叫做 僵尸进程 与 孤儿进程 

① 僵尸进程

 首先我们要来介绍的是僵尸进程,这里呢通过一个故事来进行引入

  • 你呢,很喜欢晨跑🏃‍,这一天早晨6点又起来跑步了,当你路过一个公园的时候,遇到了一个晨练的【程序员】,边跑边掉头发😀 但是呢,跑着跑着,此时突然他就“啪叽”倒了下来。那你此时就非常担惊受怕了,马上拨打了110和120的电话,然后守在他的身边等待救援来到,周边的人看到也都纷纷围了过来,其中不免有一些人会紧急救援。不过等了一会这个人就没了呼吸🖤

  • 过了十几分钟后,救护车和警车都来了,警察先封锁了,让法医过来检验一下其状况,就说:“这个人已经没救了,赶紧通知家属准备后事吧~。”


好,我们回归正题,来说说这个【僵尸进程】 

  • 因为在救护车来之前这个人其实就已经死亡了,但是其状态还没有被检测,当前并不知道它的死因,所以我们操作系统就可能会维护当前的这个状态,这个状态即为Z状态,即[僵死状态]

 💬 那我现在想问了:有一个进程暂时退出了,它要将它的状态暂时维持一段时间,问题是它维持给谁看呢?

  •  答:父进程!当一个进程退出的时候,那最关心它的便是【父进程】。因为这个父进程费了很大的劲才将这个子进程 fork 出来,此时呢它突然挂掉了,那么此时父进程就必须去关心一下对应的子进程退出时的原因

就上面这样生冷的文字来叙述还不太行,接下去我们通过实际的案例来观察一下🔍

    #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 
  6 int Test1()
  7 {    
  8   pid_t id = fork();    
  9   if(id < 0)    
 10   {          
 11     //创建失败                                                                                         
 12     printf("创建fork失败!\n");
 13     return 1;           
 14   }                                 
 15   else if(id == 0)                
 16   {                                   
 17     //子进程暂停3s后终止
 18       printf("I'm child process, ");
 19       printf("pid:%d ", getpid());
 20       printf("ppid:%d \n", getppid());
 21       sleep(3);       
 22     return 0;
 23   }  
 24   else{                               
 25     //父进程死循环                 
 26     while(1)                          
 27     {          
 28       printf("I'am parent process, ");
 29       printf("pid: %d ", getpid());
 30       printf("ppid: %d\n", getppid());
 31       sleep(1);
 32     }
 33     return 0;
 34   }
 35 }
 36           
 37  
 38           
 39            
 40 int main()
 41 {
 42   Test1();
 43   return 0;
 44 }                    
  • 运行起来可以看到,在一开始的 3s 内,父子进程还是同时在跑的,但是当子进程在循环结束后退出了。不过此时呢父进程还在运行并没有退出。所以我们在右侧查看这两个进程的状态时间就发生了一定的变化

  • 仔细地来看一下这个状态的变化,其中【PID】为 2815,其父进程为 2814,一开始它们均为S 睡眠状态,但是呢到了后面子进程的状态就变成了Z僵死状态。也就意味着此时子进程已经死亡了,但是呢父进程还不知道
  • 这里还可以通过右侧的这个<defunct>这个来看,它表示【失效的、不再存在的

所以我们总结一下: 

💬 进程一般退出的时候,一般其不会立即彻底退出。如果父进程没有主动回收子进程信息,子进程会一直让自己处于Z状态,这也是为了方便后续父进程读取子进程的相关退出结果。 

那对于上面的这种子进程,我们就将其称作为是【僵尸进程】,不过呢这种进程是存在一定危害的!

  • 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间
  • 那么对于上面的这种危害我们就称作为是【内存泄漏】,要如何去进行避免呢,之后的文章会做讲解~ 

 ② 孤儿进程

  • 上面我们讲到,当一个子进程突然退出但是父进程并没有去主动回收的话,那么此时这个子进程就会变成【僵尸进程
  • 那看到下面我们将这个进程突然终止之后,父子进程都不见了

💬 那此时我想问:这个父进程突然之间退出了,但是呢它的父进程并不知晓,那为何这个父进程没有处于【僵尸状态Z】呢? 

因为当前这个进程是 bash 的子进程,当其一退出之后,bash 就将其回收了。可是这个子进程为什么也没了呢?这个的话我们就要聊聊【孤儿进程】了 


接下去我们来将上面测试僵尸进程的代码做个修改,让父进程先于子进程退出 

    #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 
  6 int Test1()
  7 {
  8   pid_t id = fork();
  9   if(id < 0)
 10   {
 11     //创建失败                                                                           
 12     printf("创建fork失败!\n");
 13     return 1;
 14   }
 15   else if(id == 0)
 16   {
 17     //子进程进入死循环
 18     while(1)
 19     {
 20       printf("I'm child process, ");
 21       printf("pid:%d ", getpid());
 22       printf("ppid:%d \n", getppid());
 23       sleep(1);
 24     }
 25     return 0;
 26   }
 27   else{
 28     //父进程暂停3s后终止    
 29       printf("I'am parent process, ");
 30       printf("pid: %d ", getpid());
 31       printf("ppid: %d\n", getppid());
 32       sleep(3);                                                                  
 33     return 0;
 34   }
 35 }
 36 
 37 
 38 
 39 
 40 int main()
 41 {
 42   Test1();
 43   return 0;
 44 }
  • 然后通过进程状态追踪来看看,我们观察到一开始两个父进程和子进程是同步在走的,但是呢过了一会父进程终止了,只有子进程还在跑,此时我们需要留意的不是其进程状态,而是这个子进程的 PPID 即父进程的 PID,它由原先的【22677】变成了【1】,这是为什么呢?

  • 这里的话就要给读者普及一下了,对于PID的值为1的进程,我们一般将其称作为是【系统进程】。我们可以使用下面这句指令去查找一下
ps ajx | head -1 && ps ajx | grep systemd
  • 然后我们看到这个【系统进程】的PID即为1

 那为何会出现上面这种现象呢?是这个子进程突然换父进程了吗?

  •  对于父子进程来说,如果父进程先于子进程结束的话,那么这个子进程就会被称作为是【孤儿进程】,对于孤儿进程来说呢,它会有1号进程即【系统进程】所领养,因为此时这个进程没有了父进程了,所以需要有人去带领它 

 💬 但是这个孤儿进程为什么要被领养呢?

  • 其实很简单,既然它是一个进程的话,最终都是要退出的,但是没了父亲的话就只能由系统进程来进行维护了

 五、总结与提炼

最后来总结一下本文所学习的内容📖 

在本文中,我们主要讲解了两个大点,一个是在操作系统中所常见的一些进程状态,它们分别为:运行状态、阻塞状态、挂起状态 

  • 所被调度的、处于运行队列里的这些进程所处的状态我们称之为 运行状态R
  • 处于等待队列中,同时在等待外设相应的进程所处的状态我们称之为 阻塞状态R
  • 当把一个进程的 数据和代码都重新交换到外设当中,进程所处的状态我们称之为 挂起状态R

接下去我们又介绍了在Linux系统下的七种进程状态,分别是:运行状态R、浅度睡眠状态S、深度睡眠状态D、停止状态T、进程跟踪状态t、死亡状态X、僵死状态Z

  • 当一个进程没有在等待IO流的时候,其就会处于 运行状态R
  • 使用 sleep() 函数可以很好地使一个进程处于浅度睡眠状态S
  • 如果不想让一个进程在等待磁盘操作的时候被操作系统杀掉,则可让其处于 深度睡眠状态D
  • 可以向一个进程发送【19】号信号使其暂停,处于停止状态T继续发送【18】号信号的话则可以使其重新启动
  • 在【gdb】的环境下去运行一个断点的话则可以使其处于进程跟踪状态t
  • 使用kill -9 PID就可以杀掉一个进程,使其处于死亡状态X
  • 如果让一个子进程在父进程不知晓的时候退出,那么其就会处于僵死状态Z,变为【僵尸进程】;若是在父子进程中父进程先于子进程退出的话,那么这个子进程就会变成【孤儿进程

 六、共勉

        以下就是我对【Linux系统编程】Linux下的七大进程状态 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新【Linux系统编程】请持续关注我哦!!! 

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

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

相关文章

内存优化技巧:让数据处理更高效

Pandas无疑是我们数据分析时一个不可或缺的工具&#xff0c;它以其强大的数据处理能力、灵活的数据结构以及易于上手的API赢得了广大数据分析师和机器学习工程师的喜爱。 然而&#xff0c;随着数据量的不断增长&#xff0c;如何高效、合理地管理内存&#xff0c;确保Pandas Da…

vue中实现百度地图全国与省市地图切换

前言 本文主要是用于示例全国地图&#xff0c;点击省市地图直接跳转到该省市地图并展示&#xff0c;可以拓展在地图上显示标记点&#xff08;本文未做示例&#xff09;&#xff0c;后续有完整代码&#xff0c;但是由于需要与本来项目业务代码进项分割&#xff0c;可能会有些问题…

centos 7无需token编译安装freeswitch 1.10.11 ——筑梦之路

准备工作 安装编译工具和依赖包 yum update -y sudo yum install epel-release vim tcpdump net-tools.x86_64 -y sudo yum install gcc-c sqlite-devel zlib-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel openssl-devel git -y yum install yasm n…

Web APIs--Dom获取属性操作

目录 1.DOM&#xff08;操作网页内容、用户交互&#xff09; 2.DOM对象获取&#xff08;querySelect(‘’)、querySelectAll(‘’)&#xff09; 总结&#xff1a; 3.操作元素内容&#xff08;修改元素的文本更换内容&#xff09; 1. 元素innerText 属性 2.元素.innerHTML…

JavaSE 面向对象程序设计初级 静态static 包package 常量final 代码块 代码实操理论内存原理详解

目录 static(静态) 静态的特点 应用示例 静态变量 静态方法 注意事项 内存图 重新认识main方法 包 什么是包 使用导包在什么时候 final关键字 常量 命名规范 细节&#xff08;重点&#xff09; 权限修饰符 代码块 局部代码块 构造代码块 静态代码块 个人号…

【机器学习】必会降维算法之:随机投影(Random Projection)

随机投影&#xff08;Random Projection&#xff09; 1、引言2、随机投影&#xff08;Random Projection&#xff09;2.1 定义2.2 核心原理2.3 应用场景2.4 实现方式2.5 算法公式2.6 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;降维算法还没讲完呢。 小鱼&a…

EE trade:炒伦敦金的注意事项及交易指南

在贵金属市场中&#xff0c;伦敦金因其高流动性和全球认可度&#xff0c;成为广大投资者的首选。然而&#xff0c;在炒伦敦金的过程中&#xff0c;投资者需要注意一些关键点。南华金业小编带您一起来看看。 国际黄金报价 一般国际黄金报价会提供三个价格&#xff1a; 买价(B…

c++里 父类私有的虚函数,也是可以被子类重写和继承的。但父类私有的普通函数,子类无法直接使用

谢谢 。今天看课本上有这么个用法&#xff0c;特测试一下。这样就也可以放心的把父类的私有函数列为虚函数了&#xff0c;或者说把父类的虚函数作为私有函数了。 再补充一例&#xff1a;

ls命令的参数选项

ls命令的参数的作用 可以指定要查看的文件夹&#xff08;目录&#xff09;的内容&#xff0c;如果不指定参数&#xff0c;就查看当前工作目录的内容。ls 命令的选项 常用语法&#xff1a;ls [-a -l -h] [linux路径] -a 选项表示 all &#xff0c;即列出全部内容&#xff0c;包括…

Linux文件编程详解

Linux文件编程详解 在Ubuntu&#xff08;Linux&#xff09;系统下进行文件操作涉及一系列的系统调用&#xff0c;这些调用是基于Unix风格的文件操作API。这些操作包括打开或创建文件、从文件中读取数据、向文件中写入数据、移动文件指针以及关闭文件。以下是这些函数的详细介绍…

WPF/C#:在DataGrid中显示选择框

前言 在使用WPF的过程中可能会经常遇到在DataGrid的最前或者最后添加一列选择框的需求&#xff0c;今天跟大家分享一下&#xff0c;在自己的项目中是如何实现的。 整体实现效果如下&#xff1a; 如果对此感兴趣&#xff0c;可以接下来看具体实现部分。 实践 假设数据库中的…

LeetCode LCP 61. 气温变化趋势

别怕麻烦&#xff0c;模拟题有时候就是要多写一些条件&#xff08;或者你思维很活跃找出规律&#xff09;&#xff0c;代码如下&#xff1a; class Solution { public:int temperatureTrend(vector<int>& temperatureA, vector<int>& temperatureB) {int …

GraphQL vs REST:API设计的现代选择

随着技术的飞速发展&#xff0c;API&#xff08;应用程序接口&#xff09;设计成为了软件开发中不可或缺的一部分。REST&#xff08;Representational State Transfer&#xff09;和GraphQL作为两种主流的API设计风格&#xff0c;各自具有独特的优势和适用场景。本文将深入探讨…

audacity音频处理

1.安装 Audacity | Free Audio editor, recorder, music making and more! 添加OpenVINO插件: https://zhuanlan.zhihu.com/p/676542556 2.使用 2.1注意事项 1.编辑音频,点击左上方打开或导入都可以;打开视频文件则需要安装ffmpeg模块,打开后只显示视频中的音频信息; 2.编辑…

手机k歌用什么麦克风最好?轻揭无线麦克风哪个品牌音质最好!

​无线领夹麦克风作为现代音频技术的重要代表&#xff0c;已广泛应用于各种场合。它不仅能提升演讲者声音质量&#xff0c;还能增加演讲互动性和生动性。然而面对众多产品如何选择适合自己的设备成难题。本文将提供选购使用无线领夹麦克风的建议与推荐款式&#xff0c;帮助你轻…

一文带你全面详细了解安全运维

一、安全运维-网络 1、IP地址相关 IP地址属于网络层地址&#xff0c;用于标识网络中的节点设备。 IP地址由32bit构成&#xff0c;每8bit一组&#xff0c;共占用4个字节。 IP地址由两部分组成&#xff0c;网络位和主机位。 IP地址分类&#xff1a; 类别网络位子网掩码私有地…

tomcat常用配置详解和优化方法

常用配置详解 1 目录结构 /bin&#xff1a;脚本文件目录。 /common/lib&#xff1a;存放所有web项目都可以访问的公共jar包&#xff08;使用Common类加载器加载&#xff09;。 /conf&#xff1a;存放配置文件&#xff0c;最重要的是server.xml。 /logs&#xff1a;存放日志文件…

vue 基于antV 实现流程图编辑器代码

最近在做流程图功能开发&#xff0c;发现阿里antV 有对应的可视化引擎&#xff0c;于是自己做了一个简单vue 基于antV 实现流程图编辑器代码 部分代码如下&#xff1a; <template><div id"flowEditorContent"><header><h3>antv X6 流程编辑…

iptables(4)规则匹配条件

简介 前面我们已经介绍了iptables的基本原理,表、链,数据包处理流程。如何查询各种表的信息。还有基本的增、删、改、保存的基础操作。 经过前文介绍,我们已经能够熟练的管理规则了,但是我们只使用过一种匹配条件,就是将”源地址”作为匹配条件。那么这篇文章中,我们就来…

搞IT需不需要考个软考中级?

如果你是在事业单位、银行、国企等体制内工作&#xff0c;建议考虑参加软考。通过软考评职称后&#xff0c;可以获得加薪和晋升的机会&#xff0c;而且晋升时也会更看重你的职称等级。我就是通过软考评定了中级职称&#xff0c;薪水涨了500元。 评职称并不仅仅是拿到证书就行&…