<<01javaEE系列---入门>>

导论

什么是软件?

软件就是通过写代码来解决一些实际问题,比如写一个记事本程序来用于记录。

如何写出一个软件?

写出一个软件需要我们程序猿同时具备 “内功心法”“外功招式”

  • 内功心法就是我们所学的还有java基本语法,数据结构,数据库,计算机等的必备知识。
  • 外功招式,也就是 API,库 ,框架 比如我想要模拟鼠标点击操作,就需要调用系统提供的 api

创建一个应用程序,我们可以使用别人提供的库和框架。本质上都是别人把执行库,封装好,提供api供我们调用。

如果是图形化应用程序如qt等,如果是安卓开发,我们需要学习android相关的api(android sdk)

内功和外功相辅相成,最终我们才能写出一个具有实际意义的应用程序。

我们需要了解计算机是怎么工作的。

CPU(重要的硬件设备)

cpu的内部构造是由门电路构成半加器构成全加器,再构成加法器等。
不过对于java程序员来说通常不需要了解得这么深入,因为我们只需要写好代码,计算机api的调用就由java虚拟机来做好了。

cpu基本情况
  • x86架构 如intel,amd等,我们的电脑还有服务器大多采用的是x86架构,x86还可以划分为32位和64位。
  • arm架构 如苹果,高通,台积电等, 目前的苹果电脑使用的是m系列也就是arm架构的芯片,还有苹果,以及我们熟知的搭载安卓系统的设备如小米等,还有一些电脑使用的也是arm架构的芯片。

x86和arm的区别在于指令集不同。

我们目前的cpu使用的cpu都是多核和超线程加持的产物。
这是因为cpu不能做的太小,这可能会涉及到我们熟知的量子力学。
也不能做的太大,这样不能保证良品率。

那么有没有一个很好的办法能够有效地实现cpu的性能提升呢?
其实就是通过采用多核来解决这个问题。
通过超线程技术,我们甚至能够把一个cpu当成两个来用,比如我的cpu核心数是8核,那么通过超线程我可以得到16核,相当于一个人干两个人的活。

我的cpu核心数:

在这里插入图片描述

不过有些cpu是采用大小核的架构。这样小核不能使用超线程,大核可以,这样可能引起大小核调度问题。

软件上我们就引入了并发编程。
在后面进行并发编程时,cpu核心数时一个非常重要的参考依据。

什么是cpu频率

cpu频率描述单个cpu核心工作的速度。
严格来将叫做时钟周期。
如果是超线程,那就表示超线程后的单核。
通常可以把频率当作每秒执行的指令数,虽然这只是粗略估计。

单位计算如下:

  • 1KHz=1024Hz
  • 1MHz=1024KHz
  • 1GHz=1024MHz
    我们的cpu频率都是以GHz为单位的,相当于每秒执行亿次指令,这个速度很快。
    睿频技术
    cpu的频率发生动态变化,主要取决于当前任务多不多,因为频率过高会更耗电。
    衡量一个cpu的单核性能,既要看基础频率(下限),也要看最大睿频(上限)
我的cpu频率,可以看到它是动态变化的,上面是动态变化的值,下面是基准频率,还有最大睿频(也就是最大的频率),我的cpu的最大睿频是5.5GHz,但是要注意的是这里基准频率不是所能达到的最低频率,因为可以看到我的动态变化的值比这个基准频率还要小。

在这里插入图片描述

什么是缓存呢?

在这里插入图片描述
为啥需要缓存?
这是因为在冯诺依曼架构下,内存的速度(频率)达不到cpu的速度(频率)。为了解决这个问题,我们引入了缓存和流水线。别看缓存很小,它的速度比内存快很多,如果cpu是舞台,那么缓存类似于临时安置演员的地方,指令比作演员,我们把下一次还要用到的演员安排到离得很近的幕后下,确保下一次能很快上台。

什么是流水线
就是演员A在表演时提前去接演员B,演员C,等演员A谢幕后,正好B就来了。

cpu指令集

对于不同架构的cpu,支持的指令集是不同的 arm是精简指令集,x86是复杂指令集。

那么什么是指令集呢?

类似的,我们来介绍一下指令表。
简单模拟cpu执行指令的过程,这里给出一个简化的版本
指令表

其中RAM就是我们所说的内存。
寄存器就是cpu上存储数据的单元。和缓存不同,寄存器是在cpu内部,而缓存是在cpu和内存连接的通道上。
cpu上直接存储的数据比较少,这些寄存器主要是为了支持cpu完成一些计算,保留中间结果的。
和缓存一样的,虽然空间有限,但是访问速度极快,比内存访问速度至少快3-4个数量级。

下面这段指令,其实就是内存中的一段数据,我们写好的代码最终想要执行,都是要让操作系统先把编译好的代码加载到内存中,然后cpu才能执行的。

假定从0号地址开始执行。
cpu就会先从0号地址依次读取数据到cpu寄存器中,并且对这个指令进行解析。具体解析就是参照指令表。指令表时cpu出场就规定好的一种规范。
当然,并不一定是依次执行,比如if,while,for,还有函数调用。这就需要cpu调用对应的指令。
在这里插入图片描述

操作系统

操作系统时一个重要的软件,用于管理各种硬件设备,并给其他软件提供稳定的运行环境。
在这里插入图片描述

一个电脑的硬件有:

  • 显示器
  • 键盘
  • 鼠标
  • 麦克风
  • 摄像头
  • 内存
  • 外存(硬盘,软盘,u盘等)

目前主流的操作系统有:

  • Windows
  • Linux
  • Mac
  • Ios
  • Android

由于操作系统的api都已经写好了,我们在写代码时只需要调用系统api即可,另外我们java的jvm对系统又进行了抽象封装,因此咱们java程序猿只要使用JVM提供的api就可以起到操作各种不同的系统来完成编程了!咱们写的代码不仅能在windows上能跑,到linux能跑,到macos上也能跑!

小结

  • 冯诺依曼体系架构下,执行单元cpu)和存储单元内存)是分开的,要执行的指令会被加载到内存中,cpu需要从内存中读取数据和指令,解析指令和执行指令。cpu的这种读取很低效,因此我们需要给cpu加入缓存或者引入流水线。
  • 操作系统 是管理各种硬件设备软件设备的集合,给软件提供稳定的环境,对各种硬件和软件进行抽象和封装,例如在linux下,就是一切皆文件。

进程/任务

进程就是操作系统提供的一种软件资源。也就是说,进程是系统分配资源的基本单位。

多任务操作系统是当下的主流。
我们现在所用的系统都属于多任务操作系统,同时可以运行多个任务,比如我用着画图板和浏览器,还在使用qq音乐听歌。这些运行中的程序,就可以称为任务,也叫做进程

当然,也有单任务操作系统,例如“老人机”。单任务操作系统不能后台运行,也就是说:“要想执行另一个程序,就需要先退出前一个程序”。
我们目前使用的智能手机,能够来回切换,其实也是有在后台运行的。

对于多任务操作系统来说,进程的概念就非常重要了。
可以认为,计算机中的每一个进程在运行时,都需要给它分配一定的系统资源。进程是系统分配资源的基本单位。

进程在系统中是如何管理的呢?
我们操作系统的进程管理,其实就分为两步:

  1. 描述:使用类/结构体这种方式,把一个实体熟悉给列出来。
  2. 再组织:使用一定的数据结构,把这些对象/结构体串到一起。

例如,学校要对学生进行统一管理,那么就需要:

  1. 先描述:把一个学生的各种属性都给列出来;
  2. 再组织:使用一定的数据结构,把所有学生的信息整合到一起。

再细分:
描述:操作系统一般是使用c/c++实现的,例如linux,因此就可以使用结构体来表示进程信息,我们给它起个名字,就叫**PCB(进程控制块)**吧。(注意,这里的PCB是Process Control Block,不是你想到的那个)

PCB是操作系统学科的通用概念(不管在windows上,还是在linux上,都适用)。在linux上,PCB就是一个struct task——struct这样的结构体。

组织 以linux为例,我们使用链表这样的数据结构来把若干个task_struct(前面讲的PCB),给串起来的,就像烤串一样。
当我们看到任务管理器中的进程时,意味着系统内部就在遍历这些链表,并打印每个节点的相关信息。
如果运行一个新的程序,于是就在系统中多出一个进程,多的这个进程就需要构造一个新的PCB,并添加到链表上。
如果某个运行的程序退出了,操作系统就需要把对应的进程的PCB从链表中删除掉,并销毁对应的PCB资源。学过数据结构应该会对这些很清楚。

PCB核心属性

PCB这个结构体,是一个非常庞大的结构体(有上百个属性)

pid属性

进程身份标识,通过一个简单的不重复的整数来进行区分的,系统会保证pid的唯一性,针对某个进程来操作,就可以通过pid,pid一般是从1开始累加的。一般来说pid是一个32位整数

我们想要结束系统中正在运行的某个进程,就先选中某个进程,然后点击结束任务,此时任务管理器获取你选中的这个进程的pid,然后调用系统api,把这个参数(pid)传进去,从而完成结束进程的操作。

为了描述进程使用哪些内存,我们需要引入内存指针的概念

内存指针

什么是内存指针?
通常是一组,进程在运行过程中需要消耗一些系统资源,其中内存就是一个重要的系统资源。整个系统的内存不是我们决定的,而是操作系统给我们分配的。

可以把内存想象成一个旅馆,这个旅馆里面有很多个房间,所谓的申请内存,就是你跟老板(具体跟谁说我不清楚,因为我没有去过旅馆)说开一个房间,这时候就是申请到了一个空的房间号(这个房间号是我们不能确定的)。
那么,如果房间没申请,我们能进去嘛?
一方面,你没申请你也进不去,另一方面,你强行破门而入,后果不可预知。

每个进程都必须使用自己申请到的内存
内存指针就是为了描述这个进程都能使用哪些内存。
一个进程润(run)起来时,需要有指令和数据,这些都是要加载到内存中的,进程需要知道哪里是存的指令,哪里是存的数据

指令和数据是在进程跑起来之前加载的

比如我们双击运行一个exe文件,就是运行进程,这个过程中,就是系统先把指令和数据加载到内存中,然后再创建进程,让进程执行。

指令一般不会很大,数据是有可能会非常大的,比如服务器程序,启动过程至少要消耗10分钟,这十分钟里要加载100GB的数据到内存中。

虽说需要加载到内存,但是总有断电的时候,那么我们该如何操作呢?这就需要引入文件描述表的概念。

文件描述表

我们的进程经常要访问硬盘,操作系统将硬盘进行了封装,比如linux的/dev/目录下,我们可以找到nvme0n1pX,或是sda、sdb等。
我们所说的存储器,就是内存加外存,其中外存包括不限于,硬盘、软盘、光盘和U盘等。

一个进程想要操作一个文件,就需要先“打开文件”,就是让进程在文件描述符表中分配一个表项(构造一个结构体),表示这个文件的相关信息。
进程是操作系统分配资源的基本单位。内存和外存这些都在PCB中体现。

CPU资源

CPU是最复杂的,一个进程消耗的cpu资源,一般都是指cpu占用率,每个cpu的核心(一个cpu可以有多个核心)就好比一个舞台,进程要执行的指令就是演员,演员要上台才能进行表演。
我们在资源管理器所看到的cpu的百分数,其实就是你的进程在cpu舞台上消耗的时间的百分比。
如果有一个进程把cpu吃满(100%)了,就意味着这个进程把cpu霸占了,
同一个时刻,同一个舞台上,只能有一个演员

分时复用

我的这台电脑上的cpu,就有16个逻辑核心(如果不了解逻辑核心,可以看看我前面讲的)。

我系统上的进程远远不止16个!!!但是只有16个逻辑核心,该怎么分呢?
这就需要让多个演员轮流上台,(假设我们现在的电脑只有一个核心),如果有多个核心,就可以不同舞台同时刻安排演员。这就是我们所说的分时复用(并发)

注意,这里讲的和我们之前所说的同时运行是不冲突的,(CPU频率往往都是GHz,一秒钟能够执行几十亿条指令的,由于执行速度太快,我们肉眼感知不到)

现代计算机的执行,往往是并行+并发同时存在。
多个进程并行执行还是并发执行,都是看系统调度,系统如何调度取决于系统的调度器模块,这我们干预不了。
因此,我们往往就把“并行”和“并发”统称为“并发”,后续相关的编程方式,我们一般称为“并发编程”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值