【Linux】探索Linux进程优先级 | 环境变量 |本地变量 | 内建命令

最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。

目录

  • 一、进程优先级
    • 1.1优先级VS权限
    • 1.2为什么要有进程优先级?
    • 1.3具体Linux中的优先级
      • 1.3.1查看进程优先级
      • 1.3.2 PRI and NI
      • 1.3.3 PRI VS NI
      • 1.3.4 修改进程优先级
      • 1.3.5优先级队列实现原理
    • 1.4拓展小知识
      • 1.4.1并发
      • 1.4.2几个小问题
        • 1.4.2.1为什么函数的返回值会被外部拿到呢?
        • 1.4.2.2系统怎么知道我们的进程当前执行到哪行代码了呢
        • 1.4.2.3在CPU中寄存器扮演什么角色呢?
        • 1.4.2.4为什么要保存进程的上下文数据呢?
        • 1.4.2.5进程数据上下文保存在哪里呢?
  • 二、环境变量
    • 2.1基本概念
    • 2.2环境变量PATH
    • 2.3环境变量HOME
    • 2.4获取环境变量env&&getenv
    • 2.4环境变量USER
  • 三、命令行参数
    • 3.1命令行参数作用
    • 3.3main函数的第三个参数
    • 3.4验证环境变量的继承
  • 四、本地变量&&内建命令
    • 4.1常规命令&&内建命令
  • 🍀小结🍀

在这里插入图片描述
在这里插入图片描述

🎉博客主页:小智_x0___0x_

🎉欢迎关注:👍点赞🙌收藏✍️留言

🎉系列专栏:Linux入门到精通

🎉代码仓库:小智的代码仓库


一、进程优先级

1.1优先级VS权限

优先级(对资源的访问,谁先访问,谁后访问)和权限看起来很像,但实际上它们有一些区别。权限决定的是能否进行某种操作,比如读取、写入或执行某个文件。优先级则是在你已经具备权限的情况下,决定谁先谁后地访问资源。比如在学校食堂排队时,你的优先级决定了你是先吃饭还是后吃饭。如果资源无法提供,或者你没有权限访问,那就是你没有这个权限。而优先级是用来决定当前的某个进程先享受还是后享受某种资源。

1.2为什么要有进程优先级?

在计算机系统中,进城有很多个,而CPU资源是有限的。而进程之间是要互相竞争对应的资源的。操作系统必须保证大家良性竞争,就必须确认优先级,优先级的存在就是为了更好地利用资源,解决不良竞争问题。
如果大家都不排队,都去抢资源,那么就会导致计算机的使用率不高,任务得不到合理分配,排队的本质就是确认优先级,通过设定优先级,让不同的进程能够按照一定的顺序获取资源,避免混乱和无序竞争。如果优先级设计不合理或者调度算法不科学,就可能导致一些进程长时间得不到CPU的资源,该进程的代码长时间得无法推进,就会造成该进程的饥饿问题。

1.3具体Linux中的优先级

1.3.1查看进程优先级

我们先来写一段代码:

#include <iostream>
#include <unistd.h>
using namespace std;int main()
{while(1){cout<<"i am a process"<<endl;sleep(1);}return 0;
}

跑起来之后我们可以使用这段指令来查询进程的状态:

ps -al | head -1 && ps -al | grep myproc

在这里插入图片描述

  • PRI :进程可被执行的优先级,其值越小越早被执行
  • NI :进程的nice值(进程优先级的修正数据)

1.3.2 PRI and NI

  • PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • NI就是进程的nice值,表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
  • 当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  • 所以,调整进程优先级,在Linux下,就是调整进程nice值
  • nice其取值范围是[-20,19],一共40个级别

1.3.3 PRI VS NI

  • 进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  • 可以理解nice值是进程优先级的修正修正数据。

1.3.4 修改进程优先级

我们普通用户是无法给进程提高优先级的,只能减小进程优先级,所以要提升进程优先级必须使用root用户
修改方法:

top
#进入top后按“r”–>输入进程PID–>输入nice值

【注意】: 我们每次修改nice值的时候PRI都是从80开始±的。

1.3.5优先级队列实现原理

在这里插入图片描述
我们所对应的优先级[60,99]在运行时会转换成[100,139]。
进程在进程优先级队列当中是从上往下,从左往右进行调度的,当runing中的进程被调度完之后,通过指针交换来继续调度waiting中的进程,以此循环,就构成了我们所看到的优先级队列。

1.4拓展小知识

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

1.4.1并发

我们的CPU在一定的时间内只能运行一个进程(多个CPU除外),因为我们操作系统中的进程不止一个,那么这些进程都想要被CPU调度运行,那就不得不进行进程切换,每个进程在CPU上运行一段时间再切换到下一个进程运行,我们把进程在CPU上运行的时间称为进程的时间片,进程切换是基于时间片轮转的调度算法。因为CPU速度很快,所以我们日常使用上感觉不到进程是被不断切换的。

1.4.2几个小问题

1.4.2.1为什么函数的返回值会被外部拿到呢?

这是因为我们CPU上有很多的寄存器,我们平时函数返回的时候会将返回数据,写入到寄存器中,外部再通过读取寄存器中的值来获取函数返回值。

return a -> mov eax a //返回值a会转化成mov指令,将变量a中的值保存在eax寄存器中
1.4.2.2系统怎么知道我们的进程当前执行到哪行代码了呢

在我们计算机的CPU中有一个程序计数器PC指针,或者eip,这两个都是用来记录当前进程正在执行的下一行指令的地址。
程序计数器通常被存储在寄存器中,这样可以让CPU在读取指令时更快地访问。由于CPU是按照顺序执行指令的,因此程序计数器的主要功能就是告诉CPU下一个要执行的指令在哪里。

1.4.2.3在CPU中寄存器扮演什么角色呢?

在我们CPU中有很多的寄存器例如,

  • 通用寄存器:eax,ebx,ecx,edx等等。通用寄存器从字面意思来理解就是没有什么用的寄存器,只要你需要,我就可以来供你使用,保存一些数据了什么的。
  • 栈帧寄存器:ebp,esp,eip等等。用来维护函数栈帧结构的寄存器。
  • 状态寄存器status。是一个包含有关处理器状态信息的寄存器。它通常包含一些标志位,例如:溢出标志,进位标志,奇偶标志等等。

CPU中有大量的寄存器主要是为了提高效率,进程的高频数据会被放入寄存器中,寄存器中保存了进程的相关数据,以方便进行对数据的访问或者修改。

cpu寄存器中保存的进程的临时数据,也包含进程的上下文数据,进程上下文包括执行该进程有关的各种寄存器(例如通用寄存器、程序计数器PC、程序状态字寄存器PS等)的值。

1.4.2.4为什么要保存进程的上下文数据呢?

所有的保存都是为了恢复,如果我们不保存进程的上下文数据,那么进程再被切换出去之后,再被切换回来的时候,CPU就不知道该从哪里开始运行,所以我们进程在被切换的时候会将自己的上下文保存好甚至带走,等到再次被调度的时候,首先做的第一件事就是恢复上下文,随后再接着执行代码。

1.4.2.5进程数据上下文保存在哪里呢?

一般情况下我们把进程的上下文是以结构体形式保存在进程的PCB数据结构(task_struct)里的。

struct reg_info
{int eax;int ebc;int eip;.......
}

二、环境变量

2.1基本概念

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

在Windows中我们可以通过设置->系统设置->高级系统设置来查看我们Windows中定义的环境变量。
在这里插入图片描述

2.2环境变量PATH

  • PATH : 指定命令的搜索路径

在我们平时想要运行编译好的可执行程序就必须带上./来表示当前目录下的可执行程序,那么我们平时用的pwd,ls指令为什么不用输入路径呢,这是因为系统中存在环境变量PATHPATH里面保存了我们指令的搜索路径,并且这个环境变量是我们打卡开一个终端以生具来的,默认就有的,那么可以使用下面这段指令来查看系统的PATH环境变量:

echo $PATH

在这里插入图片描述
这里是我自己Linux上面配置的环境变量,里面的内容是通过:来分隔开每一个路径的。上面的每一条路径就是我们每执行一条指令,系统查找指令的路径,比如我们想要执行ls指令,系统就会在PATH里的路径中查找ls指令,找到了就正确执行,没有找到就会给我们报错bash:xxx:command not found,报了这个错误表示没有找到指令,证明了我们在执行我们自己的程序的时候如果没有带路径,系统也会给我们在环境变量中查找,只不过没有找到。

所以我们想要将我们当前所处的路径添加到环境变量里,是不是就可以不用带路径呢?
我们来试一试,使用下面指令添加环境变量:

PATH=$PATH:/home/xz/xz_-linux/csdn_2023_12_10
#/home/xz/xz_-linux/csdn_2023_12_10是我自己的当前目录
# 如果只用PATH=/home/xz/xz_-linux/csdn_2023_12_10的话就会直接覆盖这个整个PATH

在这里插入图片描述
添加成功之后我们再来不带./来执行一下我们自己的可执行程序>
在这里插入图片描述
我们可以看到程序没有./也是可以正确执行的。

实际上,我们刚刚修改的PATH环境变量是一种在内存中的环境变量,所以无需担心。如果不小心改错了,只需关闭Xshell并重新登录即可。这个PATH环境变量是在shell中保存的。然而,当shell尚未存在时,即在系统启动时,环境变量是从哪里来的呢?实际上,这些环境变量预先存储在我们系统的一些配置文件中。当系统启动时,它们会被加载到内存中。因此,现在你不必担心你的环境变量被错误修改,只需重新启动一下,我们的环境就会恢复。

2.3环境变量HOME

  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录。

在我们平是登录xshell的时候普通用户就会直接进入自己的家目录/home/xxx而root用户会进入自己家目录/root ,那么系统是怎么知道我们的工作目录的呢?
主要原因就是因为当我们在登录时,shell就会直接识别到当前登陆账户是谁,然后给当前用户填充$HOME环境变量,当我们登录时,此时默认就直接cd到了$HOME目录下。这就是我们每次登录之后都会处于自己对应的家目录的原因。

2.4获取环境变量env&&getenv

bash中我们可以使用env命令来获取bash从系统中继承下来的所有环境变量。
在这里插入图片描述
也可以使用getenv来获取某一个环境变量。

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{cout<<"PATH="<<getenv("PATH")<<endl;return 0;  
}

在这里插入图片描述

2.4环境变量USER

USER环境变量用来标识当前登录的用户。在终端中输入命令echo $USER,可以查看当前登录用户的用户名。这个环境变量是bash/shell在启动时自动加载的,它记录了当前登录的用户。
我们再来写一段demo代码:

#include <iostream>
#include <unistd.h>
using namespace std;int main()
{cout<<"USER="<<getenv("USER")<<endl;return 0;  
}

我们在普通用户下执行这个程序会打印我们的用户名,用root账户执行则会打印root:
在这里插入图片描述
在这里插入图片描述
了解了上面内容,我们就可以模拟一下系统权限对普通用户和root用户的判定方式:

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;int main()
{char who[32];strcpy(who,getenv("USER"));if(strcmp(who,"root")==0)cout<<"root用户不受条件约束"<<endl;else cout<<"普通用户受权限约束"<<endl;cout<<"USER:"<<getenv("USER")<<endl;return 0;  
}

在这里插入图片描述
因为有环境变量的存在,我们的系统就已经具备了能够认识你这个人是谁的能力,只要能认识你是谁,就可以和文件属性当中文件的拥有者所属组和文件所对的权限所对比,进而判定出你有没读写权限。

三、命令行参数

我们C/C++中的main函数其实是可以传参的,这两个参数我们称之为命令行参数:

int main(int argc,char *argv[])
{return 0;
}

其中argv是一个指针数组,里面保存了字符串的地址,argc决定了argv中的元素个数,我们来尝试打印一下argv中的内容:

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;
int main(int argc,char *argv[])
{for(int i = 0;i<argc;i++){printf("argv[%d]->%s\n",i,argv[i]);}return 0;
}

在这里插入图片描述
这时候我们发现里面内容只有一个就是./myproc,我们再来给可执行程序后面加一些选项来运行一下看看:
在这里插入图片描述
我们的main函数也是可以被调用的,main函数时程序被执行调用的第一个函数,调用main函数之前,bash会将我们在命令行输入的./myproc -a -b -c -d以空格分隔开分割成argc个字符串。
并保存在argv中其中argv[argc]=NULL,最终再传递给main函数。

3.1命令行参数作用

#include <iostream>   
#include <cstring>  
using namespace std;  
int main(int argc,char *argv[])  
{  if(argc!=2)  {  printf("Usage:%s -[a|b|c|d]\n",argv[0]);                                           return 0;                                                          }                                                                      if(strcmp(argv[1],"-a")==0)                                            {                                   printf("功能1\n");              }                                   else if(strcmp(argv[1],"-b")==0)    {                                   printf("功能2\n");              }                                   else if(strcmp(argv[1],"-c")==0)    {                                   printf("功能3\n");              }                                   else if(strcmp(argv[1],"-d")==0)    {                                   printf("功能4\n");              }else{printf("defalut功能\n");}return 0;
}             

在这里插入图片描述
命令行参数可以通过输入不同的选项,来控制程序执行不同的功能代码。
命令行参数为指令,工具,软件等提供命令行选项的支持!

3.3main函数的第三个参数

main函数除了上面那两个参数,还有一个叫做char *env[]的参数;

int main(int argc,char *argv[],char *env[])
{return 0;
}

我么也可以来打印一下env中的内容:

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;
int main(int argc,char *argv[],char* env[])
{for(int i = 0;env[i];i++){printf("env[%d]->%s\n",i,env[i]);}return 0;
}

还可以通过第三方变量environ获取

#include <stdio.h>
int main(int argc, char *argv[])
{extern char **environ;int i = 0;for(; environ[i]; i++){printf("env[%d]->%s\n",i,environ[i]);}return 0;
}

在这里插入图片描述

argv和env的结构一模一样,所以我们的C/C++代码一共会有两张核心向量表,一张叫做命令行参数表,一张叫做环境变量表。环境变量表会从父进程中继承下来。
在这里插入图片描述
我们所运行的进程,都是子进程, bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!

3.4验证环境变量的继承

我们可以自己定义一个环境变量导入系统中的环境变量表当中,我们想要增加一个环境变量可以使用下面命令:

export MY_VALUE=666666666666

在这里插入图片描述
可以看到我们自己定义的环境变量已经被导入到环境变量表当中。
我们接下来再去之心我们刚刚的代码:
在这里插入图片描述
可以发现它里面也有 MY_VALUE 这个环境变量,说明子进程 myproc 继承了父进程 bash 的环境变量。
删除一个环境变量可以使用unset 环境变量命令。

unset MY_VALUE

四、本地变量&&内建命令

本地变量指的就是我们可以在命运行当中直接定义,比如a=1,b=2,c=3。
在这里插入图片描述
定义的本地变量是不会被写入环境变量表的,所以我们使用env命令也是不会显示我们刚刚定义的那些变量,我们可以使用set命令来查看当前系统所定义的所有环境变量和本地变量。
在这里插入图片描述
此时我们就可以查出来我们刚刚定义的本地变量。
本地变量是不会被子进程进程的,只会在本地bash中有效。
我们再来通过一段代码验证一下:

#include <iostream>
#include <unistd.h>
using namespace std;int main()
{printf("MY_VALUE=%s\n",getenv("MY_VALUE"));  return 0;  
}

在这里插入图片描述
我们可以通过export将本地变量写入环境变量中

export MY_VALUE
将本地变量MY_VALUE导入到系统环境变量

在这里插入图片描述
此时就可以打印出来我们刚刚添加的环境变量了。

4.1常规命令&&内建命令

我们再来看这个图中,我们定义了本地变量MY_VALUE,我们的可执行程序(bash的子进程)都读不到这个变量,为什么echo可以读取到呢?
在这里插入图片描述
其实我们命令行上执行的指令不一定都要创建子进程,就好比王婆说媒一样,一些有任务特别难的或者风险的,王婆就会找别人去帮忙说媒。如果是一些很有把握的事情,那王婆还是愿意自己去做的。

由此可以推出我们指令是有区别的:

  • 常规命令:通过创建子进程完成的
  • 内建命令:bash不创建子进程,而是有自己亲自执行,类似于bash调用了自己写,或者系统提供的函数。

所以echo是一个内建命令,它是由bash自己执行的,与此同时我们的cd命令也是一个内建命令,我们可以通过调用chdir来改变当前工作目录。

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;
int main(int argc,char *argv[])
{sleep(30);printf("change begin\n");if(argc==2){chdir(argv[1]);}printf("change end\n");sleep(30);return 0;
}

在这里插入图片描述
在命令行中输入 cd 命令的时候,bash 并不会创建子进程,而是去判断命令行参数是否为 cd,如果是就直接去调用 chdir 系统接口来切换bash的工作目录。

🍀小结🍀

今天我们学习了"【Linux】探索Linux进程优先级 | 环境变量 |本地变量 | 内建命令"相信大家看完有一定的收获。种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!创作不易,辛苦各位小伙伴们动动小手,三连一波💕💕~~~,本文中也有不足之处,欢迎各位随时私信点评指正!
在这里插入图片描述

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

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

相关文章

《YOLOv8改进系列》专栏目录介绍

YOLOv8改进系列 &#x1f680; 专栏目录介绍 本专栏内容是紧跟最新、最前沿的改进方法&#xff0c;不仅适用检测任务&#xff0c;分类任务&#xff0c;分割任务&#xff0c;关键点任务同样适用。文章适用于多种场景&#xff0c;包括但不限于小目标、工业缺陷、轻量化等领域。 …

1.3 什么是接口?什么是接口测试?

上一小节我们认识了C/S和B/S架构,那在B/S架构中,我们测试最常接触的,就是接口。本课程的重点是接口自动化测试,那同学们真的了解什么是接口吗?首先,我们从通俗的角度来看什么是接口。在计算机中,接口是计算机系统中两个独立的部件进行信息交换的共享边界。这种交换可以发…

防火墙访问控制、安全审计、网络设备防护检查表

1、访问控制类检查 2、安全审计类检查 3、网络设备防护类检查 原件&#xff1a; 防火墙标准检查表 分类 测评项 预期结果 访问控制 应在网络边界部署访问控制设备&#xff0c;启用访问控制功能 启用了访问控制规则 应能根据会话状态信息为数据流提供明确的允许/拒绝访…

HarmonyOS—实现UserDataAbility

UserDataAbility接收其他应用发送的请求&#xff0c;提供外部程序访问的入口&#xff0c;从而实现应用间的数据访问。Data提供了文件存储和数据库存储两组接口供用户使用。 文件存储 开发者需要在Data中重写FileDescriptoropenFile(Uriuri,Stringmode)方法来操作文件&#xf…

简单使用selenium抓取微博热搜话题存储进Excel表格中

#test.pyimport requests from selenium import webdriver import time from write import write#首先打开浏览器 drive webdriver.Chrome()#设置隐式等待&#xff1a;等待元素找到&#xff0c;如果找到元素则马上继续执行语句&#xff0c;如果找不到元素&#xff0c;会在设定…

【PWN】学习笔记(三)【返回导向编程】(下)

目录 课程回顾动态链接过程 课程 课程链接&#xff1a;https://www.bilibili.com/video/BV1854y1y7Ro/?vd_source7b06bd7a9dd90c45c5c9c44d12e7b4e6 课程附件&#xff1a; https://pan.baidu.com/s/1vRCd4bMkqnqqY1nT2uhSYw 提取码: 5rx6 回顾 管道符 | 把前一个指令的输出作…

用python打印出菱形图案

你可以使用Python编写一个简单的函数来打印菱形图案。下面是一个例子&#xff0c;这个函数接受一个参数n&#xff0c;表示菱形的高度&#xff0c;然后打印出一个菱形图案&#xff1a; def print_diamond(n): # 上半部分 for i in range(n): print(" " …

springboot098基于web的网上摄影工作室的开发与实现

springboot098基于web的网上摄影工作室的开发与实现 源码获取&#xff1a; https://docs.qq.com/doc/DUXdsVlhIdVlsemdX

微搭低代码实现登录注册功能

目录 1 创建用户数据源2 实现登录逻辑3 搭建登录页面4 设置登录框5 实现登录的逻辑6 用户注册总结 原来产品在创建应用的时候可以创建模型应用&#xff0c;模型应用对应我们小程序的后端。最新的更新已经将模型应用的能力下线&#xff0c;那我们不得不自己实现一下后端的逻辑。…

计网Lesson10 - 网络层之IP协议分析

文章目录 网络层协议IPv4 数据报格式IPv4 数据报首部格式版本&#xff08;Version&#xff09;首部长度&#xff08;Header Length&#xff09;区分服务&#xff08;Differentiated Services Field&#xff09;可选字段填充总长度&#xff08;Total Length&#xff09;标识、标…

记录 | vscode无法在这个大型工作区中监视文件更改,请按照说明链接解决问题

在 VSCode 上打开一个项目时&#xff0c;突然弹出以下错误&#xff1a; 无法在这个大型工作区中监视文件更改。请按照说明链接解决问题。 原因&#xff1a; 由于工作区太大包含太多文件导致vs code监视文件达到上限而因此这个错误。在 Linux 上执行以下命令&#xff1a; cat …

spingboot项目实战之若依框架创建新模块

前言 目前的脚手架系统很多&#xff0c;比较早接触诺依框架&#xff0c;以若依框架为参考如何创建新模块 步骤 1. 下载诺依框架&#xff0c;依照参考说明一步步&#xff0c;能做到系统运行起来。 2. 准备好mysql文件&#xff0c;创建新数据库表 3. 数据库管理工具navicat…

操作系统原理-作业三-存储器

某页式虚拟存储管理系统中&#xff0c;页面大小为 2KB &#xff0c;某一进程分配到的内存块数为 3 &#xff0c;并按下列地址顺序引用内存单元&#xff1a; 2531 、 6632 、 4140 、 3584 、 2892 、 5743 、 1700 、 2148 、 6940、 4345 、 3209 、 0732 、 6202 、 4541 。…

[MySQL] MySQL中的索引

文章目录 一、初识索引 1、1 索引的概念 1、2 索引案例 二、认识磁盘 2、1 磁盘结构 2、2 操作系统与磁盘的数据交互 2、3 磁盘随机访问与连续访问 2、4 MySQL与磁盘的数据交互 三、索引的理解 3、1 建立测试表 3、2 为何MySQL与磁盘IO交互是 Page 3、3 理解Page 3、3、1 页目录…

在线教育培训系统搭建,打造方便快捷的学习模式

教育在我国是一件重中之重的事业发展&#xff0c;所谓“活到老学到老”&#xff0c;人们都离不开教育。 而在当下互联网的发展下&#xff0c;教育、职业培训的方式也变得越来越多样&#xff0c;在线教育模式成为了不少高校的选择&#xff0c;也成为了不少学生的选择。 在线教…

Flutter 上了 Apple 第三方重大列表,2024 春季 iOS 的隐私清单究竟是什么?

这个话题的起因来自 2023 年 WWDC 之后苹果发布的「App Store 提交隐私更新」政策&#xff0c;政策主要提出了两点&#xff1a;第三方 SDK 隐私清单和签名和需要提供必要理由的 API 流程。 其实先简单总结&#xff0c;就是 Apple 想通过隐私清单来进一步提升用户数据收集和使用…

共创共赢|美创科技获江苏移动2023DICT生态合作“产品共创奖”

12月6日&#xff0c;以“5G江山蓝 算网融百业 数智创未来”为主题的中国移动江苏公司2023DICT合作伙伴大会在南京成功举办。来自行业领军企业、科研院所等DICT产业核心力量的百余家单位代表参加本次大会&#xff0c;共话数实融合新趋势&#xff0c;共拓合作发展新空间。 作为生…

I/O设备模型

I/O设备模型 绝大部分的嵌入式系统都包括一些I/O&#xff08;Input/Outut&#xff0c;输入/输出&#xff09;设备&#xff0c;例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的Flash或SD卡&#xff0c;以及网络设备的以太网接口等。 I/O设备模型…

【人工智能Ⅰ】实验8:DBSCAN聚类实验

实验8 DBSCAN聚类实验 一、实验目的 学习DBSCAN算法基本原理&#xff0c;掌握算法针对不同形式数据如何进行模型输入&#xff0c;并结合可视化工具对最终聚类结果开展分析。 二、实验内容 1&#xff1a;使用DBSCAN算法对iris数据集进行聚类算法应用。 2&#xff1a;使用DBS…

macOS Sonoma 14.2RC(23C63)发布

系统介绍 黑果魏叔12 月 6 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 14.2 RC更新&#xff08;内部版本号&#xff1a;2323C633&#xff09;&#xff0c;本次更新距离上次发布隔了 49 天。 预计正式版会在下周到来。届时用户可以打开“设置”->“通用”->…