JAVAEE初阶第一节——计算机的工作原理

ops/2024/9/20 1:53:26/ 标签: java-ee, java, 学习

系列文章目录

JAVAEE初阶第一节——计算机的工作原理


计算机的工作原理

  1. 计算机发展史
  2. 冯诺依曼体系(Von Neumann Architecture)
  3. CPU
  4. 操作系统(Operating System)

文章目录

  • 系列文章目录
    • JAVAEE初阶第一节——计算机的工作原理
  • 计算机的工作原理
  • 一.计算机发展史
  • 二. 冯诺依曼体系(Von Neumann Architecture)
  • 三.CPU
    • 3.1 CPU的构成(简单了解)
    • 3. 2 CPU的基本情况
    • 3.3指令(Instruction)
    • 3.4 CPU 的基本工作流程
  • 四·操作系统(Operating System)
    • 4.1操作系统的定位
    • 4.2 进程/任务(Process/Task)
      • 4.2.1 操作系统的进程管理
    • 4.3进程调度(Process Scheduling)
        • 分时复用(并发):
    • 4.4进程控制块抽象(PCB Process Control Block)
      • 4.4.1 PCB的核心属性
      • 4.4.2 支持系统对进程的调度的PCB属性
    • 4.5内存分配 —— 内存管理(Memory Manage)
    • 4.6进程间通信(Inter Process Communication)


一.计算机发展史

计算的需求在人类的历史中是广泛存在的,发展大体经历了从一般计算工具到机械计算机到目前的电子计算机的发展历程。

请添加图片描述

人类对计算的需求,驱动我们不断的发明、改善计算机。目前这个时代是“电子计算机”的时代,发展的 潮流是:更快速、更稳定、更微型。

想要更加了解计算机发展史的话可以看看 《计算机简史》

二. 冯诺依曼体系(Von Neumann Architecture)

计算机是由软件和硬件构成的,而现代的计算机硬件, 大多遵守 冯诺依曼体系结构
请添加图片描述请添加图片描述

  • CPU中央处理器:进行算术运算和逻辑判断。(计算机中最核心的部分)
  • 存储器:分为外存和内存,用于储存数据(使用二进制方式存储)。
    1. 内存存储空间小,外存的存储空间更大。
    2. 内存访问速度快,外存访问速度更慢。
    3. 内存的成本更高,外存的成本低。
    4. 内存的数据断电后会丢失,外存的数据断电后依然存在。
  • 输入设备:用户给计算机发号施令的设备。(键盘,鼠标,麦克风)
  • 输出设备:计算机给用户汇报结果的设备。(显示器,音箱)

对于存储空间
硬盘 > 内存 >> CPU
对于数据访问速度
CPU >> 内存 > 硬盘

计算机在CPU执行指令的时候,要经历从内存读取数据这样的操作.这就是冯诺依曼体系结构的精髓

冯诺依曼体系结构的本质是把 “执行” 和 “存储” 的操作分开。这么做主要就是为了 “解耦合” 以降低硬件设计的成本.(在那个时候是很必要的,因为当时的硬件设备不想现在这么好)
但随着硬件技术的发展,CPU越来越快了。从内存读取数据这件事就不能像以前那样显著提升计算机的速度,逐渐读取内存数据的速度就跟不上CPU的节奏了。

三.CPU

3.1 CPU的构成(简单了解)

门电路=> 半加器=>全加器=>加法器=>ALU运算器=>CPU(基本上构成)

CPU以及其他的内存硬盘等重要的设备都是由门电路构成的。

3. 2 CPU的基本情况

种类上分为:
X86 架构: intel amd —>家用PC,服务器
arm 架构: 苹果,高通 —> 苹果电脑,智能手机

不同架构的CPU支持的指令集是不同的,对应的机器语言或汇编语言也是不同的

16位CPU, 32位CPU的汇编与64位CPU的汇编的区别:

int main(){int* p = NULL;printf("%d",sizeof(p));return 0 ;
}

上面代码的执行结果,关键就是要看你的CPU是哪种CPU.
如果你的CPU是16位CPU,得到的结果就是2(2个字节,16个比特位)。
如果你是32位CPU,得到的结果就是4.
如果你是64位CPU,得到的就是8。

CPU的位数就和代码中内存地址用几个字节表示是密切相关的

3.3指令(Instruction)

所谓指令,即指导 CPU 进行工作的命令,主要有操作码 + 被操作数组成。
其中操作码用来表示要做什么动作被操作数是本条指令要操作的数据,可能是内存地址,也可能是寄存器编号等。 指令本身也是一个数字,用二进制形式保存在内存的某个区域中

请添加图片描述

3.4 CPU 的基本工作流程

CPU是如何计算3 + 14 的:

假设有两个寄存器:寄存器A(0010)和寄存器B(0001)

  1. CPU从内存中读取到 0 地址的数据(指令)到CPU寄存器中并对这个指令进行解析(查询指令表判断这个指令要执行的操作) (前四位是指令,后四位是参数(数据))

0010 1110
0010 - 要完成的工作就是从内存中读取数据到寄存器A中
1110 - 表示内存地址 (十进制的14).说明要读取的数据在地址14上

  1. CPU继续从内存中读取指令并解析

0001 1111
0001 - 要完成的工作就是从内存中读取数据到寄存器B中
1111 - 表示内存地址 (十进制的15).说明要读取的数据在地址15上

![[Pasted image 20240302101332.png]]

  1. CPU继续从内存中读取指令并解析

1000 01 00
1000 - 要完成的工作就是把这两个寄存器中的数据进行相加,结果保存到第二个操作数的寄存器中
01 - 寄存器A 00 - 寄存器B
在这里插入图片描述

  1. CPU继续从内存中读取指令并解析

0100 1101
0100 - 就是把寄存器A中的数据写入到后面操作数表示的地址上(13)
1101 - 表示内存地址 (十进制的15).说明要写入的地址是地址15.

![[Pasted image 20240302101911.png]]

从上面的过程中,得出以下几个结论:

  1. CPU要执行的指令,是在内存中的(冯诺依曼体系结构,基本设定,让执行单元和存储单元解耦合)
  2. CPU要想执行指令,就需要先取指令,再解析指令,然后才能执行指令
  3. 取指令需要从内存中读取指令到CPU的寄存器中(这里没有体现出存储指令的寄存器,就只体现了AB用来计算数据的寄存器.取指令的操作,其实是非常耗时的)(读取内存操作相对于cpu执行计算,要开销大很多). 因此cpu中通过缓存,流水线等技术,来优化这里的效率
  4. .cpu解析指令的时候,需要用到"指令表",不同架构的CPU支持的指令表不同(x86和arm等都是不同的)指令表细节,已经写死到CPU中了,CPU是可以很容易识别的
  5. 指令在执行过程中,可能会带有一些操作数,不同的指令,操作数的个数含义都有所不同
  6. CPU重要的参数,主频。主频表示的含义,近似看成是一秒钟之内,CPU能够执行的指令个数

四·操作系统(Operating System)

4.1操作系统的定位

操作系统是一组做计算机资源管理的软件的统称。目前常见的操作系统有:Windows系列、Unix系列、 Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等。

操作系统有两个基本功能(起到抽象封装的作用):

  1. 防止硬件被时空的应用程序滥用.(管理各种硬件设备)
  2. 向应用程序提供简单一致的机制来控制复杂而又通常大相径庭的低级硬件设备。(给其他软件提供稳定的运行环境)

4.2 进程/任务(Process/Task)

每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以 说是计算机科学中最重要和最成功的概念之一。

进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程,在电脑上正在运行的程序就可被称为是任务或者是进程.同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。(进程就是操作系统提供的一种软件资源)

4.2.1 操作系统的进程管理

  1. 先描述(使用类/结构体这样的方式,把实体属性给列出来)

操作系统,一般是用C/C++实现的。(没有Jva写的操作系统)因此,就可以使用结构体表示进程信息.这样的结构体就叫做PCB(进程控制块,Process Control Block)

  1. 再组织(使用一定的数据结构,把这些结构体/对象,串到一起)
    在Linux中,使用链表这样的数据结构来把若干个task struct给串起来的

当我们看到任务管理器中的这些进程的时候,意味着系统内部就在遍历链表,并且打
印每个节点的相关信息.
如果运行一个新的程序,于是系统中就会多一个进程。多的这个进程就需要构造出一
个新的PCB,并且添加到链表上。
如果某个运行中的程序,退出了,就需要把对应进程的PCB从链表中删除掉,并且
销毁对应的PCB资源

此处的表述是一个简化版本,事实上组织方式会更复杂。

4.3进程调度(Process Scheduling)

进程,是系统分配资源的基本单位。

分时复用(并发):
  1. 假设一个CPU核心是一个比赛区域(CPU是包含若干区域的比赛场地),要执行的指令(进程)就是比赛选手.如果规定同一时刻一个比赛区域上只能有一个选手进行比赛(运行),这就是一个进程消耗了一个CPU资源.

可是如果比赛的选手非常多,远远超过了比赛区域的数量,那该怎么办呢?

  1. 假设此时的比赛区域只有一个,先让选手1,登台比赛,比赛过了一会之后,让选手1下来,选手2上.选手2比赛一段时间之后,进程3上以此类推.(即CPU核心只有一个的情况下,先执行进程1的代码.运行一段时间后让进程1结束,进程2开始执行.进程2执行一段时间后,让进程3执行…以此类推)

而由于计算机中这样切换进程的速度是非常快的(CPU频率,都是多少多少GHz,一秒钟执行几十亿条指令的)意味着,短时间内,CPU就可以进行很多次的任务切换。人也就无法感知到这个切换的过程的.因此在人眼看起来,多个任务/进程,就是"同时执行"的.(当然也有极端情况,比如,系统进程太多了,负担太重,就会出现"卡顿")

  1. 当比赛区域变多时,同时进行比赛的过程变得更加复杂了.这时候在同一时刻就可以有几个不同的选手在各自的比赛区域进行比赛.而不是靠快速换人的方式.(即随着CPU核心的增多,同一时刻就可以有多个不同的进程执行,而不是靠快速切换模拟的"同时执行")这种方式就称为称为"并行执行".

与之对应的,前面的并发执行,仍然存在.每个核心仍然要分时复用,仍然要快速切换.

  1. 当前现代的计算机执行过程,往往是并行+并发同时存在的.两个进程是并行执行还是并发执行都是看系统的调度的.(系统如何调度,取决于系统调度器模块的实现)因此,往往就把"并行"和"并发"统称为"并发".

对应的编程方式(解决一个问题,同时搞多个任务来执行,共同协作解决)就称为“并发编程”

4.4进程控制块抽象(PCB Process Control Block)

计算机内部要管理任何现实事物,都需要将其抽象成一组有关联的、互为一体的数据。在 Java 语言中, 可以通过类/对象来描述这一特征。

java">// 以下代码是 Java 代码的伪码形式,重在说明,无法直接运行  
class PCB {  // 进程的唯一标识 —— pid;  // 进程关联的程序信息,例如哪个程序,加载到内存中的区域等  // 分配给该资源使用的各个资源  // 进度调度信息(留待下面讲解)  
}

这样,每一个 PCB 对象,就代表着一个实实在在运行着的程序,也就是进程。
操作系统再通过这种数据结构,例如线性表、搜索树等将 PCB 对象组织起来,方便管理时进行增删查改的操作.

4.4.1 PCB的核心属性

  1. PID 进程的身份标识

通过一个简单的不重复的整数来进行区分的系统会保证,同一个机器上,统一时刻,每个进程PID 都是唯一的·(后续要针对某个进程进行操作,就可以拿着PID 来进行区分了)

比如,选中某个进程,并且点击结束任务,此时,就是任务管理器获取到你选中的进程的PID,然后调用一个系统api,把PID作为参数穿进去,从而完成这里的杀死进程的操作

  1. 内存指针

进程运行过程中,需要消耗一些系统资源的。其中内存就是一种重要的资源
整个系统,内存这么多(16G),这16G都是可以随意使用嘛??当然不是,先从系统这里申请,系统给你分配一块,你才能使用.
每个进程都必须使用自己申请到的内存. 内存指针,就是用来描述说你这个进程,都能使用哪些内存.
一个进程跑起来的时候需要有"指令”也需要有"数据”(指令和数据,都是要加载到内存中的)
进程也需要知道,哪里是存的指令,哪里是存的数据.

  1. 文件描述符表
    – >描述了这个进程,所涉及的硬盘相关的资源

1)操作系统,对于硬盘这样的硬件设备,进行了封装=>文件
2)操作系统,不管你是哪种盘,都是统一进行的抽象,都是按照"文件"的方式来操作的
3)一个进程要想操作文件,需要先"打开文件”(就是让你的进程在文件描述符表中分配一个表项(构造一个结构体)表示这个文件的相关信息)

4.4.2 支持系统对进程的调度的PCB属性

1.状态

用来描述某个进程是否能够去CPU上执行,有的时候某个进程比较特殊,这时候再判断它的状态就不太方便.比如,某个进程,通过Scanner等待用户输入内容.但是用户啥时候输入就是完全不可控的事情.
因此就会有不同的状态来应对不同的问题:
(1)就绪状态:随时准备好去CPU上执行,给操作系统一打招呼就可以执行了.
(2)阻塞状态:这个进程当前不方便去CPU上执行,就不应该去调度它.(比如,进程在等待O,来自控制台的输入输出/硬盘输入输出/网卡输入输出)

例如:

java">void main(){Scanner scanner = new Scanner(System.in);int num = scaner.next();
}

上面代码在执行到第二条时,等待用户往控制台输入内容时,什么时候输入是不知道的.此时代码就需要暂停下来,不能继续向下走了,就是要等待用户输入一个整数.

这种进程暂停下来,不继续执行,这种等待的状态,就称为"阻塞"(这个阻塞,就是因为等待IO引起的阻塞)

  1. 优先级

多个进程等待系统调度,多个进程之间,调度的先后关系不是平均的,可以选择先调度哪个进程,后调度哪个,先调度谁,后调度谁都是可以调配的.比如在电脑上运行QQ的同时打开腾讯视频看视频,这个时候腾讯视频的优先级是更高的.

  1. 记账信息

针对每个进程, 占据了多少CPU时间,进行一个统计,并根据这个统计结果来进一步地调整不同状态的调度策略.因此就需要在下一个轮流执行的时候进行调整调度的策略.确保没有进程出现没在CPU上执行过的情况.

  1. 上下文

它是PCB中的数据结构相当于是在内存上的,它能支撑进程调度的重要属性,相当于文件的保存和读取.每个进程在运行的过程中,就会有很多的中间值(临时数据)在CPU的寄存器中

例如:上面CPU计算 3 + 14 的时候,CPU先使用寄存器保存3 和14 ,但是计算得出结果17后执行该指令的CPU被调度走去执行其他指令了,后面结果写入的操作还没执行.而又需要等到进程下次CPU调度回CPU的时候就可以按照之前的进度继续执行进程.

因此,就需要在进程调度出CPU之前,把当前寄存器中的这些信息单独保存到一个地方(存档)
在该进程下次再去CPU上执行的时候,再把这些寄存器的信息给恢复回来(读档)

结论:

“保存上下文”:就是把CPU的关键寄存器中的数据保存的内存中(PCB的上下文属性中)
“恢复上下文”: 就是把内存中的关键寄存器中的数据加载到CPU的对应寄存器中.

注意:内存指针,文件描述符表,记账信息,上下文都是数据结构,不是简单的int变量之类的

4.5内存分配 —— 内存管理(Memory Manage)

操作系统对内存资源的分配,采用的是空间模式 (详细的暂不说明)—— 核心结论是:不同进程使用内存中的不同区域,互相之间不会干扰。(为了保证系统的稳定性,避免系统的一个进程崩溃影响到其他进程)—>“进程独立性”

4.6进程间通信(Inter Process Communication)

如上所述,进程是操作系统进行资源分配的最小单位,这意味着各个进程互相之间是无法感受到对方存 在的,这就是操作系统抽象出进程这一概念的初衷,这样便带来了进程之间互相具备”隔离性(Isolation)“。
但现代的应用,要完成一个复杂的业务需求,往往无法通过一个进程独立完成,总是需要进程和进程进 行配合地达到应用的目的,如此,进程之间就需要有进行“信息交换“的需求。进程间通信的需求就应运而生。

进程间通信,和进程的"独立性”并不冲突,系统提供一些公共的空间(多个进程都能访问到的),让两个进程借助这种公共空间来交互数据。

目前,主流操作系统提供的进程通信机制有如下:

  1. 管道
  2. 共享内存
  3. 文件
  4. 网络
  5. 信号量
  6. 信号

其中,网络是一种相对特殊的 IPC 机制,它除了支持同主机两个进程间通信,还支持同一网络内部非同一主机上的不同进程间进行通信。


http://www.ppmy.cn/ops/105842.html

相关文章

在.gitignore文件中重新添加或修改了忽略文件未生效的原因

因为git在初始化时就已经对忽略文件进行了不追踪,其它文件都会追踪,重新添加忽略文件后,实际上是没有进行更改追踪记录的,所以需要重新初始化。 git rm -r --cached .git add .git commit -m "Update .gitignore"

秋招突击——算法练习——8/30、9/4——技巧题练习——复习{}——新作{只出现一次的数字、多数元素、颜色分类、下一个排列、寻找重复数}

文章目录 引言复习新作136、只出现一次的数字个人实现 169、多数元素个人实现 75、颜色分类个人实现参考实现 31、下一个排列个人实现参考实现 287寻找重复数个人实现参考实现 总结 引言 手撕的代码大部分都是出自于这里,还是要继续加强,把剩下一些零碎…

Qt是不是经常写个QWidget输入参数?

发现Qt自带的一个输入控件QInputDialog类 QInputDialog类提供了一个简单方便的对话框,用于从用户获取单个值。 输入值可以是字符串、数字或列表中的项。必须设置一个标签来告诉用户他们应该输入什么。 提供了五个静态方便函数:getText()、getMultiLineText()、getI…

Java Lock 中使用 await() 和 signal()实现 wait()/notify()机制

** Java Lock 中使用 await() 和 signal()实现 wait()/notify()机制 ** 案例 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class MyService {private Lock lock new R…

5.8幂律变换

目录 示例代码1 运行结果1 示例代码2 运行结果2 补充示例原理 示例:使用cv::pow进行图像处理 代码 运行结果 ​编辑 补充 实验代码3 运行结果3​编辑 在OpenCV中,幂律变换(Power Law Transformations)是一种常用的图像…

一起学习LeetCode热题100道(63/100)

63.搜索插入位置(学习) 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5…

Android 事件分发:为什么有时候会出现事件冲突?事件的顺序是如何的?出现事件冲突如何解决呢?比如为什么左右可以滑动,而上下却不行?

目录: 一、为什么要学习事件呢? 1.在开发复杂的应用时,经常需要处理复杂的用户交互逻辑。学习事件分发机制可以帮助你更好地控制事件的传递和处理流程,从而解决一些复杂的交互问题,如滑动冲突、点击穿透等。 2.面试需…

【ACM独立出版 | 厦大主办】第五届计算机科学与管理科技国际学术会议(ICCSMT 2024,10月18-20)

第五届计算机科学与管理科技国际学术会议(ICCSMT 2024) 定于2024年10月18-20日在中国厦门举行。 会议旨在为从事“计算机科学”与“管理科技”研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术,了解学术发展趋势,拓宽研究思路…

【LeetCode】两数之和

题目: 在数组中找到 2 个数之和等于给定值的数字,结果返回 2 个数字在数组中的下标。要求时间复杂度为 O(n)。 解题分析: 作者:halfrost 链接:https://leetcode.cn/leetbook/read/leetcode-cookbook/5lu4og/ 顺序扫描…

黑马头条docker启动minio访问不了,端口一直变化

原先代码为 docker run -p 9000:9000 --name minio -d --restartalways -e "MINIO_ROOT_USERminio" -e "MINIO_ROOT_PASSWORDminio123" -v /home/data:/data -v /home/config:/root/.minio minio/minio server /data 访问结果为,且9000会变为3…

Django+vue自动化测试平台(29)--测试平台集成playwright录制pytest文件执行

需求背景 一、 系统目标与功能概述 脚本管理: 系统需要能够组织和存储所有通过playwright官方插件录制的脚本。这包括脚本的上传、编辑、删除和版本控制功能。 脚本执行: 用户应该能够在后台界面上查看所有可用的脚本,并能够通过简单的点击操作来启动特定脚本的执…

pytest压力测试:不断发送数据,直到发现数据丢失

示例场景 假设有一个 send_data 函数接受数据并返回成功或失败的状态。 创建一个测试用例,通过逐步增加数据量来测试这个函数,直到返回失败为止。 步骤 定义压力测试函数 定义一个函数。不断发送数据,直到发现数据丢失。 创建 pytest 测试…

C#如何查看/写入日志到Windows事件查看器

Windows事件日志 Windows 操作系统将与计算机的系统性能、应用程序和安全方面相关的每个事件记录在 C:\WINDOWS\system32\winevt 的日志中。 事件查看器从这些原始事件日志中读取信息,然后以可读格式呈现信息。 打开Windows事件查看器的方法是 1、运行输入event…

Java字节码文件、组成、详解、分析;jclasslib插件、阿里arthas工具;Java注解

文章目录 一、字节码文件1.1 以正确的方式打开文件1.2 字节码文件的组成1.2.1 基础信息1.2.2 常量池1.2.3 方法 1.3 字节码常用工具1.4 总结 二、Java注解2.1 什么是Java注解2.2 注释和注解Annotation的区别(掌握)2.3 如何使用注解(掌握&…

嵌入式硬件-ARM处理器架构,CPU,SOC片上系统处理器

多进程空间内部分布图:注意:创建线程实际使用堆区空间,栈区独立 ARM处理器架构: 基于ARM920T架构的CPU:以下为哈佛结构 ALU:算数运算器 R0~R12:寄存器 PC:程序计数器,默认为0,做自加运算&#x…

使用Java实现LRU缓存和LFU缓存

LRU缓存 问题描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值&…

【Kotlin设计模式】Kotlin实现外观模式

前言 外观模式(Facade Pattern)是一种结构型设计模式,旨在为子系统中的一组接口提供一个统一的接口。外观模式定义了一个高层接口,使得这一子系统更加容易使用。它将复杂的子系统封装在一个简单的接口后面,从而降低了客…

互联网全景消息(1)之RabbitMq基础入门

一、消息中间件 1.1消息队列回顾 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实 现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ &a…

2024.9.2 作业

完成mystring类部分功能实现 代码&#xff1a; /*******************************************/ 文件名&#xff1a;work4.h /*******************************************/ #ifndef WORK4_H #define WORK4_H #include <iostream> #include<cstring> using n…

ubuntu 22.04安装NVIDIA驱动和CUDA

新拿到一个服务器&#xff0c;发现啥都没有。于是就安装 1.安装驱动 禁用自带显卡驱动nouveau lsmod | grep nouveau 这个有输出代表该驱动存在 vim /etc/modprobe.d/blacklist.conf 在文件末尾添加 blacklist nouveau options nouveau modeset0update-initramfs -u 更新 r…