计算机是如何⼯作的
计算机是如何⼯作的
- 计算机发展史
- 冯诺依曼体系(Von Neumann Architecture)
- CPU
- 指令(Instruction)
- CPU 是如何执行指令的(重点)
- 操作系统(Operating System)
- 进程(process)
- 进程 PCB 中的关键属性
- 1.PID (进程 id)
- 2.内存指针
- 3. 文件描述符表
- PCB 中支持进程调度的几个属性
- 1.状态
- 2.优先级
- 3.上下文
- 4. 记账信息
- 内存分配 -- 内存管理(Memory Manage)
- 进程间通信(Inter Process Communication)
- 小结
JavaEE==网站开发
学习⽬标
这阶段的学习中,我们会从软件⼯程师的⻆度解释计算机是如何⼯作的,我们的主要⽬标既不是期待⼤家可以造出⾃⼰的计算机,也不是介绍如何编程,⽽是希望让⼤家了解计算机的核⼼⼯作机制后,打破计算机的神秘感,并且有利于理解我们平时编程时的⼀些⾏为、动作的历史渊源。
⼤家可以配合 Crash Course Computer Science 视频做更详尽的学习和了解。
计算机是啥?
一个计算机(电脑)分成几个部分??
寄存器 和 存储器 是一个东西嘛??
不是!!!
寄存器 是 cpu 上的一个模块, 存储器 是 内存 +硬盘(统称)
内存,存储空间比硬盘小, 速度比硬盘快,价格比硬盘贵, 掉电后数据丢失,
寄存器,存储空间比内存还小,速度比内存还快, 价格比内存更贵,掉电后数据也丢失
计算机发展史
计算的需求在⼈类的历史中是⼴泛存在的,发展⼤体经历了从⼀般计算⼯具到机械计算机到⽬前的电⼦计算机的发展历程。
⼈类对计算的需求,驱动我们不断的发明、改善计算机。⽬前这个时代是“电⼦计算机”的时代,发展的潮流是:更快速、更稳定、更微型。计算机的以后将如何发展,期待⼤家的努⼒。
推荐书籍: 《计算机简史》
Java发展史
Java 在后面又抓住了两波机会.
- 后端开发
- 移动端开发
这两波机会,使 Java 始终在人们的视线中,始终是最流行的编程语言之一
美好的时光,短暂的.新的挑战又会出现
- 后端
后端这里,随着网站规模变大,越来越复杂,PHP 这种网站开发的形式, 逐渐难以胜任了
JSP 也同样收到影响~(Spring 也有了) - 移动端
2008 年,乔布斯发布苹果手机~标志着移动互联网时代开启了.手机功能机 =>智能机.
这双重加持,就在 2010 之后, 连续好几年 Java 都霸榜 编程语言排行榜第一把交椅~
(从这开始,谈到入行 程序猿,很多人都会推荐 java)
Java 就是最流行的编程语言,没有之一了
Java 看起来稳坐第一,实际上也面临很多挑战~
2023 Java虽然还是最主流的编程语言(不是第一,Python 和 C 偶尔会反超)
- 后端
字节(Go+Python)
还有B站 知乎 腾讯/腾讯云……都在使用Go - 移动端
上面的东西面试都用得到 其实面试呢不仅仅是一问一答 而且要学会去和面试官聊天
聊什么呢 上面的这些东西都是可以和面试官聊的东西
冯诺依曼体系(Von Neumann Architecture)
现代的计算机, ⼤多遵守 冯诺依曼体系结构
• CPU 中央处理器: 进⾏算术运算和逻辑判断.
• 存储器: 分为外存和内存, ⽤于存储数据(使⽤⼆进制⽅式存储)
• 输⼊设备: ⽤⼾给计算机发号施令的设备.
• 输出设备: 计算机个⽤⼾汇报结果的设备.
针对存储空间
硬盘 > 内存 >> CPU
针对数据访问速度
CPU >> 内存 > 硬盘
认识计算机的祖师爷 – 冯诺依曼
冯·诺依曼(John von Neumann,1903年12⽉28⽇-1957年2⽉8⽇), 美籍匈⽛利数学家、计算机科学家、物理学家,是20世纪最重要的数学家之⼀。冯·诺依曼是布达佩斯⼤学数学博⼠,在现代计算机、博弈论、核武器和⽣化武器等领域内的科学全才之⼀,被后⼈称为“现代计算机之⽗”、“博弈论之⽗”.
CPU
CPU是怎么构成的
对于 CPU 重点关注两个参数:
咱们后面进行并发编程的时候,cpu 的核心数,就是一个非常重要的参考依据~
(软件很多时候都是跟着硬件走的,硬件有啥特性,软件,把这些特性充分的利用起来,扬长避短)
英特尔最近几年还搞了大小核 从 12 代 intel cpu 开始有大小核:大核一个顶俩,小核一个还是顶一个(功耗更低)
amd 的CPU都是大核.
哪种更好呢?
各有各的好。大小核就是更适合笔记本,能剩电. 但是要追求极致算力,就得是全大核的好
指令(Instruction)
指令就可以认为是 CPU 被设计的时候,给程序猿提供的一些"编程接口" => 近似理解成 cpu 提供给程序猿的 API
不同的 cpu, 提供哪些指令, 是不一样的.
指令本⾝也是⼀个数字,⽤⼆进制形式保存在内存的某个区域中。
CPU 是如何执行指令的(重点)
所谓的指令,都是要先加载到内存中,然后才能被 cpu 读取,并执行
通过一个例子~ 搞一个简化版本的机器语言
简单模拟一下CPU执行指令的过程
虽然咱们可以不用理解 cpu 具体的构造,但是需要理解,cpu 是怎么执行代码的~
默认情况下,cpu 执行内存中的指令是"顺序执行"的~
当然,也可能会遇到一些 跳转 类的指令(代码中的 if, while, for, throw,函数调用……)
当前指令表中没这些,,默认还是按照顺序来执行~
当前的计算机, 在 cpu 执行指令的时候,要经历从内存读取数据这样的操作的!!!
这个事情其实放在今天,非常不科学了
cpu 就设计了很多的机制,来解决上述问题~
接下来
然后接下来到地址4了 数据显示00000000,结束!
其实上述就是CPU是如何计算4+14的
具体步骤
在上面的过程中,就有以下几个结论:
上述内容,是计算机执行程序的基本过程 (基本盘)
对于理解计算机非常有意义的~~(面试一般不会直接考这个)
虽然,作为一个 java 程序猿,日常开发中不太会直接和 cpu 打交道,(JVM 都封装好了) 不太需要了解硬件的细节
但是实际上有些技术场景,还是和上述内容直接相关的.多少还是得知道一点~
操作系统(Operating System)
cpu, 内存,硬盘… 是硬件
操作系统, 就是软件了。只是一些数据,(一组指令的集合)但是可以让计算机按照一定的规则进行执行
操作系统是⼀组做计算机资源管理的软件的统称。⽬前常⻅的操作系统有:Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等。
操作系统 要能够管理好各种硬件资源,让他们能很好的相互配合
也需要管理好各种软件资源,给每个软件都提供稳定的运行环境
软件工程的本质,就是针对"复杂程度"的管理。 人脑,能够处理的复杂程度是有限的~
如何管理"复杂程度"核心就是"抽象封装。 同一时刻,只关注其中的一个部分~来降低思考的成本
这也是操作系统所做的事
操作系统 =内核(操作系统最核心的部分,前面谈到的"管理"都是内核里完成的) + 配套的应用程序(往往要靠内核提供一些功能作为支撑(画图板,cctalk, qq 音乐…) )
操作系统,本身是一个很大的话题,在此处就不展开其他的.
操作系统里的知识,很多面试中不太涉及到,只需要掌握一些和工作密切相关的即可. 网络和数据结构是面试中更高频的话题
此处重点讨论操作系统中,非常核心的(和咱们 Java 程序猿息息相关的)
进程~
进程(process)
重要结论:进程是操作系统进行资源分配的基本单位(重点)
进程在系统中是如何管理的??
操作系统的进程管理:
- 先描述(使用类/结构体这样的方式,把实体属性给列出来)
操作系统, 一般是用 C/C++ 实现的.(没有 Java 写的操作系统)
因此,就可以使用结构体表示进程信息的结构体,起了个名字,PCB
在 操作系统中, 通常使用称为 PCB(进程控制块,Process Control Block)这样的结构体来描述进程的
落到具体的操作系统上,不同的操作系统代码中实际上写的名字是不一样的。比如 Linux 的 PCB 实际的名字是 task_struct - 再组织(使用一定的数据结构,把这些结构体/对象,串到一起)
在 Linux 中,使用链表这样的数据结构来把若干个 task struct 给串起来的~
此处的表述是一个简化版本(咱们 Java 程序猿,不需要了解太多细节)
事实上组织方式会更复杂:(不是一个链表,更加复杂的链式结构)
即
进程 PCB 中的关键属性
PCB 这个结构体,是一个非常庞大的结构体~ (有上百个属性)
1.PID (进程 id)
进程的身份标识符~系统会保证 同一个机器上,统一时刻,每个进程 pid 都是唯一的,不会重复的(后续要针对某个进程进行操作,就可以拿着 pid 来进行区分了)
2.内存指针
本质上描述了一个进程能使用的"内存资源”(是一组指针,不是一个)
3. 文件描述符表
一个进程运行的时候,会操作一些文件. 要操作文件,需要先"打开文件"(就是让你的进程在文件描述符表中分配一个表项 (构造一个结构体)表示这个文件的相关信息~)
硬盘资源,也是重要的资源.
操作系统通过"文件"这样的概念,管理硬盘。你的进程使用某个文件,就相当于在访问对应的一块硬盘空间~
进程在使用文件的时候,需要先打开,才能使用。打开文件成功,就会得到一个"文件描述符"(整数,也是类似于身份标识)一个进程可以打开多个文件,使用多个文件的硬盘资源。这些文件的文件描述符,就可以通过一个"数组"/“顺序表"来进行表示了
本质上就体现了,一个进程能够使用的"硬盘资源”
PCB 中支持进程调度的几个属性
操作系统进行进程管理过程中,完成的重要工作. 我的电脑上,进程有百八十个.但是电脑 cpu 的核心数 16 个
一个 cpu 逻辑核心,同一时刻,只能执行一个进程的指令,16 个干活的牛马,如何同时进行 一百多个任务的工作?
需要进程调度来负责了!!
当前现代的计算机 执行过程,往往是并行+并发同时存在的~
两个进程是并行执行还是并发执行都是看系统的调度的.(系统如何调度,取决于系统调度器模块的实现, 咱们普通程序猿干预不了,也感知不到,写代码时无法区分当前这些进程是并行执行还是并发执行~)
因此,往往就把并行和并发统称为"并发”。对应的编程方式 (解决一个问题,同时搞多个任务来执行,共同协作解决) 就称为"并发编程”
因为需要并发执行,所以操作系统需要进行进程的快速切换,也就是"进程调度
PCB 中就需要提供一些属性,来支持系统完成对这些进程的调度
需要有哪些属性来支撑进程调度呢?
1.状态
2.优先级
操作系统给进程分配 CPU 资源 不一定是公平的.
有的会多一些,有的会分少一些。有些进程,就是要优先级更高一些,吃到更多的 cpu 资源
你电脑上运行着 吃鸡和 QQ ,肯定优先给吃鸡 (哪怕 QQ 吃 cpu 资源少, 延迟几秒收到消息 吃鸡卡了一下,结果可能会死掉~)
3.上下文
所谓的“保存上下文"就是把 CPU 的关键寄存器中的数据, 保存到 内存 中(PCB 的上下文属性中)
所谓的"恢复上下文"就是把 内存中 的关键寄存器中的数据, 加载到 CPU 的对应寄存器中
4. 记账信息
PCB 会统计该进程在 CPU 过去一共执行了多久/多少条指令~ 针对每个进程,统计占据了多少 cpu 时间,可以用来识别出,某个进程是不是太久没有在 cpu 上执行了~
会根据这个统计结果来在下一个轮次进行调整,确保每个进程都不至于出现完全捞不着CPU 的情况的~ 如果发现某个进程,好久没有吃到 cpu 资源了,就会给这个进程倾斜一些资源
内存分配 – 内存管理(Memory Manage)
进程间通信(Inter Process Communication)
虽然有进程的独立性,但是有时候也需要,多个进程相互配合,完成某个工作
进程间通信, 和 进程的"独立性"并不冲突
系统提供一些 公共的空间(多个进程都能访问到的),让两个进程借助这种公共空间来交互数据
小结
上述对于进程的讨论,只是 序幕。
实际上, 在 Java 中不太去鼓励"多进程编程
线程 更加重要了
线程见下一篇文章!