操作系统
什么是虚拟内存,干嘛用的,有什么作用?
虚拟内存是计算机系统内存管理的一种技术。
它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上物理内存通常被分割成多个内存碎片(分页),还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
与没有使用虚拟内存计数的系统比,使用这种技术使得大型程序的编写变得更加容易,对真正的物理内存的使用也更有效率。此外,虚拟内存技术可以使多个进程共享同一个运行库,并通过分割不同进程的内存空间来提高系统的安全性。
分页 二级页表
分页是一种操作系统里存储器管理的技术。
操作系统将硬盘中的内存分割成固定大小的区块,称为“页”,主存和硬盘通过交换页来进行内容访问。
常用页面调度算法包括:LRU、LFU
一个程序中的地址是虚拟地址还是物理地址
是虚拟地址。
死锁(Dead Lock)
两个线程都要使用同一个资源,双方都等待对方停止执行以获取资源,但是没有一方释放资源时,就造成了死锁。
死锁的四个条件:(必须同时满足才会造成死锁)
- 禁止抢占:系统资源不能被强制从一个线程中退出。
- 持有和等待:一个线程可在等待时持有系统资源
- 互斥:资源只能同时分配给一个线程,无法多个线程共享
- 循环等待:一系列线程互相持有其他线程所需要的资源
中断(Interrupt)
中断是外部设备发送给 CPU 的信号,通常是 I/O 设备。它们告诉 CPU 停止当前活动转去执行更合适的部分。
中断类型:
- 硬件中断:键盘、硬盘传输数据给内存
- 软件中断:请求系统调用(System Call)
- 陷阱:通常是指 CPU 本身出现了一些错误或者触发了某些条件
进程和线程(Process vs Thread)
- 进程表示一个在执行的应用程序,线程表示进程的一部分
- 进程比线程更重量
- 进程的创建、销毁、调度需要比线程花费更多的时间
- 进程是分离的,线程是共享内存的
进程间通信
- 管道(Pipes):管道是一种半双工的通信方式,常用于在父子进行或者具有共同祖先的进程之间通信。管道分为命名管道和无名管道。无名管道一般用于具有亲缘关系的进程间通信,而命名管道则允许无关进程之间通信。
- 消息队列(Message Queues):消息队列允许进程通过在队列中发送和接收消息来进行通信。这些消息可以按照优先级进行排序,接受者可以根据需要选择消息进行处理。
- 共享内存(Shared Memory):共享内存是指多个进程共享同一块内存区域的机制。这允许进程之间高效地交换数据,因为数据直接存储在内存中,而不需要复制。
- 信号量(Semaphores):信号量是一种用于控制多个进程对共享资源的访问的机制。通过信号量,进程可以协调对共享资源的访问,避免静态条件。
- 套接字(Sockets):套接字是一种用于网络通信的机制,但也可以在同一个机器的不同进程之间通信。它提供了一种面向连接或者面向消息的通信方式。
- 远程过程调用(Remote Procedure Call, RPC):RPC 允许一个进程调用另一个进程中的函数,就像调用本地函数一样。远程过程调用隐藏了底层实现细节,使得进程间通信更加方便。
- Socketcan:用于在 Linux 系统上进行CAN 总线通信的套接字接口。
栈和堆(Stack vs Heap)
- 栈用来存储局部变量,堆允许访问全局变量
- 栈变量不能改变大小,堆变量可以。
- 栈的空间是连续的,堆的空间是随机的
- 栈中变量的申请和释放是编译器做的,堆需要程序员手动进行。
LRU 算法
使用一个 hash 表和一个双向链表。
hash 表存放 key 到链表节点的映射,链表中每个节点包含 key 和 value,最近使用的在头节点,最后使用的在尾节点。
当使用 key 获取数据的时候先根据 hashmap 判断 key 是否存在,如果存在再根据 key 找到节点,然后到链表的节点获取对应的 value,最后把这个节点提到链表的最前面。
当添加 key,value 时,如果能从 hashmap 中获取到 key,说明链表中存在这个包含 key 的节点,那么就找到这个节点并把它更新后放到链表的头节点;如果 hashmap 不包含这个 key,那么就新建一个节点并在 hashmap 中添加键值对,之后如果链表已满则删除尾节点,把新的节点添加到最前面。