JavaEE初识计算机是如何工作的——Java Enterprise Edition(Java平台企业版)
JavaEE——服务器后端开发
1.冯诺依曼体系
CPU、存储器、输入设备、输出设备。
存储器可分为内存,硬盘,光盘,U盘等
内存与硬盘的区别
内存读写速度快,硬盘慢
内存存储空间小,硬盘大
内存成本高,硬盘低
内存断点后数据丢失,硬盘断电后数据存在
2.CPU
1.主频与睿频
主频=基准速度
CPU工作的频率是变频的,所以有一个最大睿频
CPU的频率越高,运算速度越快
2.核心数
CPU内部的核心上有海量的“运算单元”,运算单元越多,CPU算力越强;
CPU的核心数量越多,CPU的算力就越强。
超线程
利用超线程技术,可以让一个核心当2个用,所以就有了物理核心和逻辑核心
上图CPU有10个物理核心,20个逻辑核心
大小核
win11CPU采取大小核心,通过操作系统的调度,用大核心做高负载任务,提高效率,用小核心做低负载任务,提高电池续航
核心不全是超线程。上图CPU有14个物理核心,18个逻辑核心。4个物理核心支持超线程,10个物理核心不支持超线程
3.缓存(cache)
缓存是什么?
缓存是存放在CPU芯片内部的告诉小容量存储器,用来临时存放CPU最近可能要用到的数据。
为什么用缓存?
避免CPU每次都去慢速的内存读取数据(内存的访问速度低于CPU访问速度)
缓存的特点
容量:L3>L2>L1
空间越大,访问速度越慢
缓存的工作流程
首先明确一点,在计算其中,数据通常存储在内存/硬盘中,且CPU永远优先去更快的地方读取数据,即L1——>L2——>L3——>内存
1.L1有目标数据,读取,结束
2.L2有目标数据,读取L2中的目标数据,同时把数据拷贝一份到L1,方便下次访问
3.L3有目标数据,读取L3中的目标数据,同时把数据分别拷贝到L2,L1,方便下次访问
4.内存有目标数据,读取内存中的目标数据,同时把数据分别拷贝到L3,L2,L1,方便下次访问
以上逐级拷贝的过程叫缓存填充
逐级拷贝是因为L1空间太小,如果访问数据大,覆盖次数多,反而达不到L1的快速访问。主机拷贝是为了尽可能多的覆盖数据
缓存中的数据在空间不够时,最不常用的旧数据会被新数据覆盖,这个机制叫做缓存替换
4.指令——instruction
指令是CPU上执行的任务的基本单位,指令是CPU工作的最小单位,是一串二进制编码。
指令的组成
操作码+操作数
操作码:告诉CPU做什么
操作数:告诉CPU对谁做,数据在哪
CPU的设计者在设计CPU时就设置好了CPU支持哪些指令,不同CPU厂商设计的CPU不同
编程语言与指令
编程语言分为机器语言、汇编语言、高级语言
高级语言有C/C++/Java/Python...
高级语言编译运行的过程:
C/C++:.c/.cpp文件被编译器转为汇编语言,汇编语言再转为机器语言(包含指令)
Java:.java文件转为.class字节码文件,然后JVM把字节码转为机器语言
指令的存储位置
指令保存在内存中,比如运行一个.exe文件:双击——操作系统把exe加载到内存中
假设一个指令为8bit(实际更长),前4位操作码,后4位操作数
RAM随机存取存储器——Random Access Memory,即内存
寄存器在CPU内部,是存储数据的硬件设备。寄存器空间很小,主要进行临时数据的计算和保存,一般有几十个寄存器
CPU运行指令的过程
假设有以下指令(真实的内存中“地址”不需要保存,而是通过硬件的电路结构计算出来的)
内存内的数据可随机访问,时间复杂度位O(1)
操作系统会安排好内存中哪个部分存指令,哪个部分存数据
1.执行第一条指令
取指令:从内存中读取指令00101110,从内存读取到CPU的寄存器中
解析指令:将指令分为操作码0010,操作数1110
查询指令表,理解操作码含义,0010是LOAD_A,通过指令表,明确后四位1110是内存地址14.
功能是从14地址的内存单元处读取数据放到寄存器A中
执行指令:14地址处的数据为
寄存器A:
寄存器B:
2.执行第二条指令
取指令:从内存中读取指令
解析指令:将指令分为操作码0001,操作数1111
查询指令表,0001是LOAD_B,通过指令表,后四位1111是内存地址15.
功能是将15地址内存单元处的数据读取放到寄存器B中
执行指令:15地址处的数据为
寄存器A:
寄存器B:
3.执行第三条指令
取指令:
解析指令:1000是ADD,0100是两个寄存器的地址,01——寄存器B,00——寄存器A
功能计算两个寄存器中数值之和,将结果放到第二个寄存器,即寄存器A中
执行指令:add结果17
寄存器A:00010001
寄存器B:00001110
4.执行第四条指令
取指令:
解析指令:0100将寄存器A的值写入指定RAM,1101:指定的RAM地址
执行指令:省略
5.执行第五条指令
取指令:
直接结束
上述整个流程是CPU完成3+14运算的过程
假设每一步消耗一个Hz,整体需要消耗12Hz,1GHz/s=10亿Hz/s,所以CPU完成这个过程只需几毫秒。
并且在真实情况下CPU是“流水线式”作业,即并非等一条指令执行完整个“取指令——解析指令——执行指令”过程,而是当第一条指令进入“解析”阶段时,取指令的电路空闲下来,就可以去取第二条指令。当第一条指令进入"执行"阶段时,解析电路空闲,就可以去解析第二条指令,同时取指令电路去取第三条指令。
3.操作系统
作用:1.管理各种硬件设备;2.给软件提供稳定的运行环境
应用程序不能直接操作硬件,只能通过API请求操作系统
例如在idea里打印“hello world”,需要经过一下过程:
System.out.println(“hello world”)——>JVM调用C++版函数——>调用操作系统的API——>操作系统把字符串给驱动程序——>驱动程序控制硬件显示打印\
1.进程
在操作系统中,进程是操作系统资源分配的基本单位
计算机上运行起来的应用程序,就称为进程,现在的计算机通常都是多进程的。
进程的运行是需要消耗一定的硬件资源。
一个可执行文件可能对应多个进程
2.操作系统如何管理进程
1.描述
操作系统用C语言的结构体,把一个进程的所有信息成一个PCB(进程控制块)保存在内存中
2.组织
使用特定的数据结构,把多个PCB组织起来(通常使用链表)
为什么要组织?
因为操作系统通常要管理几十个进程,需要能快速:
- 找到下一个要运行的进程
- 找到某个PID对应的进程
- 把阻塞的进程放在一边
3.PCB中的核心属性
1.PID——进程的标识符
PID是操作系统自动分配的整数。确保同一台设备上、在同一时刻不会存在两个相同的PID。
有的应用程序有多个进程:
2.内存指针
内存指针是一组属性。
进程运行需要内存,一个进程的内存空间里有的部分是“是指令”,有的部分是“数据”,或其它。
内存指针的作用就是告诉操作系统,哪些部分是指令,哪些是数据
3.文件描述符表
文件都是在硬盘上保存的,让各种进程打开和关闭、读和写文件。一个进程想要读写一个文件,需要先打开,打开时就会在PCB中构建一个文件相关的结构体,放在PCB的文件描述符表中。
文件描述符表可以看作一个数组,这个数组里包含着很多个结构体,每个结构体表示了文件的具体信息(通过文件信息,确定文件内容在硬盘的那个位置)。
4.进程状态
进程的状态可简单分为:就绪,阻塞2种状态
阻塞意味着该进程无法参与到CPU的调度执行上(例如Scanner)
就绪意味着该进程可以参与到CPU的调度上
5.进程的优先级
进程的优先级决定了哪个进程优先分配到CPU资源
6.进程的上下文
一个进程调度到CPU上执行了一部分,离开CPU,过一段时间后会调回到CPU上继之前的执行过的部分继续执行,上下文就记录了进程的执行信息。
“上下文”指的是CPU的寄存器存的值(进程的上下文类似于存档信息)
CPU内部有很多寄存器,不同的寄存器有不同的功能,例如:“保存当前程序运行的一些中间状态”、“记录当前指令执行到哪一条”、“记录当前程序的函数调用关系型”等功能
进程在CPU上执行的时候,寄存器的值不停的发生变换
进程要离开CPU的时候,把这一时刻CPU上这些寄存器的值全都拷贝出来保存到PCB的结构体中(保存进程的上下文)
进程后续如果回到CPU上,把之前PCB保存的寄存器的值,写入到CPU的寄存器上(恢复上下文)
7.进程的记账信息
在优先级机制下,某个进程就可能分配到的CPU资源非常少
为避免这种情况,就有了进程的记账信息
记账信息统计每个进程分别在CPU上运行了多久,识别出哪个进程分配的CPU资源多,哪个进程分配到的CPU资源少,从而灵活调整分配
