JavaEE学什么?
主要学习Java开发网站后端,为后面学习Spring做铺垫
涉及的内容:
1)操作系统基础知识
2)多线程知识
3)文件操作
4)网络编程
5)网络原理
6)JVM
计算机
计算机 = 软件 + 硬件
CPU是计算机最核心的部分
存储器(内存+外存):内存存储空间小,访问速度快,成本更高,断电后数据丢失
外存存储空间大,访问速度快,成本低,断电后数据依旧存在
输入设备:让人给计算机发号施令(键盘,鼠标,麦克风。。。)
输出设备:计算机给人反馈结果(显示器,音箱。。。)
两者兼具(触摸屏,网卡。。。。)
CPU
CPU是很小的一块硅晶片电路,要提升算力就需要提升集成程度
常见CPU厂商:Intel, AMD, 高通,华为,摩尔线程。。。
Intel和AMD都是同一个架构(x86)
设计CPU有很多种不同的方案就称为架构,不同架构中都会有不同的指令集,会对上层应用程序产生直接的影响
指令集:所谓编程就是采用编程语言描述出一些逻辑,这些逻辑最终被转换成CPU能识别的指令最终执行。这些指令的集合就是机器语言,一些二进制数据
苹果,高通等搞的是另一套架构(ARM),ARM适合低功耗的机器
这个问题得看情况
如果CPU是16位的,得到的结果就是2(2个字节,16个比特位)
如果CPU是32位的,得到的就是4
如果CPU是64位的,得到的就是8
CPU的位数和代码中内存地址用几个字节表示是密切相关的
CPU构成
门电路=>半加器=>全加器=>加法器=>ALU运算器=>CPU
具体内容可以看看我专业课的笔记
CPU的基本单位足够小,小到纳米级别,单位越小,集成程度越高,对应的算力就越强
问题:
CPU能无限小吗?因为晶体管间距有限制,无法无限小
那可以把CPU搞大点吗?不能,加工时的良品率会降低
可以搞多一些数量吗?可以,多核CPU
每个核心都相当于一个完整的CPU,把这些CPU核心集成在一起。
本来一个任务一个人干,两个人一起干就更快了
更快的前提需要软件的配合,需要软件把大任务拆分成多个小任务,合理的分配给多个劳动力(软件的并发编程)
能不能让CPU核心当成两个来用?超线程技术。
像我的电脑,写代码的时候可以当成20个人干活来使用
CPU的睿频技术:我们CPU的动态频率发生变化,取决于当前任务多不多
衡量一个CPU的单核性能,既要看基础频率(下限),又要看最大睿频(上限)
CPU如何执行指令的
寄存器是CPU上的存储单元,支持CPU完成一些计算,保存中间结果
访问速度比内存快3-4个数量级
4位RAM地址:极简版本的4位汇编
这段指令是内存中的一段数据
假定从0号地址开始执行程序,CPU就会先从0号地址读取数据到CPU寄存器里,查询指令表对这个指令进行解析
接着把14号地址的数据读取到A寄存器里
接着CPU默认往下顺序执行内存中的指令
接着执行地址2的指令
继续取指令并解析
上面的过程是CPU如何进行3+14的过程
我们可以得出几个结论
1.CPU要执行的指令是在内存中的
冯诺依曼体系结构的基本设定,把执行和存储分开,解耦合,降低硬件设计的成本
2.CPU要想执行指令,就要先取指令,再解析指令,然后才能执行指令
3.取指令需要从内存中读取指令到CPU的寄存器中。取指令的操作很耗时,开销较大,从内存读取数据这件事跟不上越来越快的CPU了,于是设计出缓存
缓存用于存储数据的硬件或软件的组成部分,以使得后续更快访问相应的数据
4.CPU解析指令的时候需要用到指令表,不同架构的CPU支持的指令表不同
5.指令在执行过程中可能带有一些操作数,不同的指令,操作数的个数含义都有所不同
6.CPU重要的参数:主频,表示一秒钟之内CPU能够执行的指令个数
操作系统
操作系统是一个软件,由代码构成程序
操作系统主要职责:管理各种硬件设备;给其他软件提供稳定的允许环境
假设需要写一个程序相应鼠标的各种操作,但是鼠标品种繁多,无法每个鼠标都写一个程序
此时就需要操作系统来统一管理不同的硬件设备,给软件提供统一的api
此时程序员写代码就不必关注硬件的细节差别了,只需要面向操作系统就行,调用操作系统的api控制不同的硬件,这也叫做封装
常见的操作系统:Windows, Linux, Mac, IOS, Android
进程
操作系统提供的一种软件资源
现在我们用的系统都属于多任务操作系统,同一个时刻可以运行多个任务
这里每一个程序就是一个任务,也叫进程
每个任务/进程在执行过程中都需要消耗一定的硬件资源,进程是系统分配资源的基本单位
单任务系统,比如switch,早期的诺基亚等;没有后台运行,要想执行另一个程序就需要先退出前一个程序
进程在系统中是如何管理的?
1.先描述,使用类/结构体这样的方式,把实体属性给列出来
表示进程信息的结构体,叫做PCB(进程控制块,Process Control Block)
Windows表示进程的结构可以称为PCB,Linux也可以称为PCB
在Linux上,PCB是叫做task_struct的结构体
2.再组织,使用一定的数据结构,把这些结构体/对象串到一起
在Linux中,使用链表这样的数据结构来把若干个task_struct给串起来;如果运行一个新的程序,系统会多一个进程,多的这个进程就要构造出一个新的PCB,并添加到链表上
PCB的一些核心属性
(1)PID:进程的身份标识,通过一个简单不重复的整数来进行区分
系统汇报真同一个机器上,同一时刻每个进程PID都是唯一的
选中某个进程,点击结束任务就是任务管理器获取你选中的进程的PID,然后调用系统api,把PID作为参数穿插进去,从而完成杀死进程的操作
(2)内存指针
进程运行过程中,整个系统的内存都是可以随意使用的吗?
当然不是。要先从系统申请,系统分配一块才能使用
内存指针就是用来描述这个进程使用内存的详细情况
比如在电脑双击一个exe文件,系统会把文件里的指令和数据先加载到内存中,然后再创建进程,让进程开始执行,这样就开始运行进程
(3)文件描述符表
我们的进程经常要访问硬盘,而操作系统把硬盘这样的硬件设备封装成了文件
一个进程要想操作文件,需要先打开文件,就是让进程再文件描述符表中分配一个表项(构造一个结构体)来表示这个文件的相关信息
一个单核CPU怎么支持一个多任务操作系统运行?
分时复用(并发)
先执行进程1的代码,执行一会后让进程1下来,让进程2上;进程2执行一段时间后上进程3
切换的速度极快,人是无法感知切换的过程,所以人眼认为是多个进程同时进行的
多核CPU的进程运行不是靠快速切换,而是并行+并发执行的。
此处CPU的百分数就是进程在CPU消耗的时间的百分比,如果一个进程把CPU吃到100%,意味着其他进程没有执行时间了,这个进程就把CPU霸占了,可能造成CPU卡顿
PCB如何支持进程的调度?
(1)状态
描述某个进程是否能够去CPU上执行
就绪状态:随时准备好去CPU上执行
阻塞状态:这个进程当前不方便去CPU上执行,不应该调度它(比如进程在等待IO)
直观理解就是代码不能继续往下走了
(2)优先级
字面理解就是先调度谁,后调度谁的问题
(3)记账信息
针对每个进程占据了多少CPU的时间进行一个统计,并根据这个统计结果进行进一步的调整调度的策略
(4)上下文
这个是支撑进程调度的重要属性,相当于游戏中的存档和读档
操作系统调度进程的过程可以认为是随机的,任何一个进程,代码执行到任何一个指令的时候都可能被调度出CPU,在进程下次调度回CPU的时候,继续之前的进程执行
所以就需要在进程调度出CPU之前把当前寄存器中的信息保存到内存中,这个就是存档
该进程下次再去CPU上执行的时候再把这些寄存器的信息恢复过来(加载到CPU对应寄存器中),这个过程就是读档
内存分配
每个进程的内存是彼此独立,互不干扰的
(原因:为了系统稳定性,如果某个进程代码出bug,出错影响范围只是影响到自己这个进程,不会影响其他进程,这个叫做进程独立性)
进程间通信
虽然有进程独立性,但是有时候也需要多个进程相互配合完成某个工作
系统提供一些公共的空间(多个进程都能访问到),让两个进程借助这种公共空间来交互数据
操作系统提供的进程间通信的方式
文件和网络是Java程序员主要使用的进程间通信方式
网络:可以支持同一个主机或不同主机的不同进程