# 初识操作系统

# 计算机组成原理

这个问题是可计算的吗?

不可计算问题

  • 无穷问题
  • 停机问题

# 人工智能

此外,包括停机问题、包括 NP 问题在内的很多问题,虽然不能解决,但可以努力让计算机的解决方案超过人类的水平,这就是人工智能。

# 冯诺依曼模型

# CPU

64位和32位的区别

在进行2^32次内的计算是没有区别的,但是进行2^64的数字时 32位就需要把拆成2个2^32来进行低位计算 然后再进位。

# 不支持递归的程序语言如何实现递归程序?

计算机编程语言用来实现递归函数。

栈的使用方法是不断往上堆数据,所以需要一个栈指针(Stack Pointer, SP)指向栈顶(也就是下一个可以写入的位置)。每次将数据写入栈时,就把数据写到栈指针指向的位置,然后将 SP 的值增加。

为了提高效率,我们通常会用一个特殊的寄存器来存储栈指针,这个寄存器就叫作 Stack Pointer,在大多数芯片中都有这个特殊的寄存器。一开始,SP 指向 0x100 位置,而 0x100 位置还没有数据。

# class的实现

首先一个 class 会分成两个部分,一部分是数据(也称作属性),另一部分是函数(也称作方法)。

class 有一个特殊的方法叫作构造函数,它会为 class 分配内存。构造函数执行的时候,开始扫描类型定义中所有的属性和方法。

  • 如果遇到属性,就为属性分配内存地址;

  • 如果遇到方法,方法本身需要存到正文段(也就是程序所在的内存区域),再将方法的值设置为方法指令所在的内存地址。

当我们调用一个 class 方法的时候,本质上是执行了一个函数,因此和函数调用是一致的:

  1. 首先把返回值和返回地址压栈;
  2. 然后压栈参数;
  3. 最后执行跳转。

总结:

  1. 我们写的程序需要翻译成指令才能被执行,这个翻译工具叫作编译器。
  2. 平时你编程做的事情,用机器指令也能做,所以从计算能力上来说它们是等价的,最终这种计算能力又和图灵机是等价的。如果一个语言的能力和图灵机等价,我们就说这个语言是图灵完备的语言。现在市面上的绝大多数语言都是图灵完备的语言,但也有一些不是,比如 HTML、正则表达式和 SQL 等。
  3. 我们通过汇编语言构造高级程序;通过高级程序构造自己的业务逻辑,这些都是工程能力的一种体现。

# SSD、内存和 L1 Cache 相比速度差多少倍?

我们希望存储器速度快、体积小、空间大、能耗低、散热好、断电数据不丢失。但在现实中,我们往往无法把所有需求都实现。

下面我们举几个例子,带你深入体会一下,比如:

  1. 如果一个存储器的体积小,那它存储空间就会受到制约。
  2. 如果一个存储器电子元件密度很大,那散热就会有问题。因为电子元件都会产生热能,所以电子元件非常集中的 CPU,就需要单独的风扇或者水冷帮助电子元件降温。
  3. 如果一个存储器离 CPU 较远,那么在传输过程中必然会有延迟,因此传输速度也会下降。

# 存储器分级策略

既然我们不能用一块存储器来解决所有的需求,那就必须把需求分级。

一种可行的方案,就是根据数据的使用频率使用不同的存储器:高频使用的数据,读写越快越好,因此用最贵的材料,放到离 CPU 最近的位置;使用频率越低的数据,我们放到离 CPU 越远的位置,用越便宜的材料。

具体来说,通常我们把存储器分成这么几个级别:

  1. 寄存器;

  2. L1-Cache;

  3. L2-Cache;

  4. L3-Cahce;

  5. 内存;

    内存的主要材料是半导体硅,是插在主板上工作的。因为它的位置距离 CPU 有一段距离,所以需要用总线和 CPU 连接。因为内存有了独立的空间,所以体积更大,造价也比上面提到的存储器低得多

    内存速度大概在 200~300 个 CPU 周期之间。

  6. 硬盘/SSD。

    SSD 也叫固态硬盘,结构和内存类似,但是它的优点在于断电后数据还在。内存、寄存器、缓存断电后数据就消失了。内存的读写速度比 SSD 大概快 10~1000 倍。

# 缓存的算法

# 方案1

CPU 读取到一个内存地址,我们就增加一个条目。当我们要查询一个内存地址的数据在不在 L1- 缓存中的时候,可以遍历每个条目,看条目中的内存地址是否和查询的内存地址相同。如果相同,我们就取出条目中缓存的值。

这个方法需要遍历缓存中的每个条目,因此计算速度会非常慢,

# 方案2

这里,我们可以用一个数学的方法。比如有 1000 个内存地址,但只有 10 个缓存条目。内存地址的编号是 0、1、2、3,...,999,缓存条目的编号是 0~9。我们思考一个内存编号,比如 701,然后用数学方法把它映射到一个缓存条目,比如 701 整除 10,得到缓存条目 1。

用这种方法,我们每次拿到一个内存地址,都可以快速确定它的缓存条目;然后再比较缓存条目中的第一列内存地址和查询的内存地址是否相同,就可以确定内存地址有没有被缓存。

延伸一下,这里用到了一种类似哈希表的方法:地址 % 10,其实就构成了一个简单的哈希函数。

# Linux

ls -F就可以看到当前目录下的文件和它的类型。

  • *结尾的是可执行文件;
  • =结尾的是 Socket 文件;
  • @结尾的是软链接;
  • |结尾的管道文件;
  • 没有符号结尾的是普通文件;
  • /结尾的是目录。

# 文件的增删改查

man touch manual 说明书

mkdir 新建目录

touch 新建文件

ls 查看文件目录

rm 删除目录 remove 缩写

cat cat /ect/hosts/ 查阅

# 进程

应用的可执行文件是放在文件系统里,把可执行文件启动,就会在操作系统里(具体来说是内存中)形成一个应用的副本,这个副本就是进程。

ps 查看当前进程

# Linux 内核和 Windows 内核有什么区别?

# 内核的能力

  • 对于一个现代的操作系统来说,它的内核至少应该提供以下 4 种基本能力:

  • 管理进程、线程(决定哪个进程、线程使用 CPU)

  • 管理内存(决定内存用来做什么);

  • 连接硬件设备(为进程、和设备间提供通信能力);

  • 提供系统调用(接收进程发送来的系统调用)。

# GC回收算法

吞吐量,暂停时间,使用空间三者不可兼得。

标记的过程主要分为 3 个步骤:

  • 如果对象在白色集合中,那么先将对象放入灰色集合;

  • 然后遍历节点的所有的引用对象,并递归所有引用对象;

  • 当一个对象的所有引用对象都在灰色集合中,就把这个节点放入为黑色集合。

# 计算机网络

每个课程都不够深入,这部分 去看

Last Updated: 12/22/2022, 9:53:26 AM