画布 1
操作系统（operating system）
  为应用程序提供一个资源集的清晰抽象，并管理这些硬件资源
  调度：将任务分配至资源的过程
    进程（process）：是计算机中已运行程序的实体，是系统进行资源调度和分配的一个独立单位。一个程序可以拥有多个进程。
      时分复用让人感觉进程在同步运行
      内容
        程序的可运行机器码的一个在内存的映像
        分配到的内存（通常是虚拟的一个内存区域）。
          可运行代码
          特定于进程的数据（输入、输出）
          调用堆栈
          堆栈（用于保存运行时运输中途产生的数据）
        分配给该进程的资源的操作系统描述符
          文件描述符（Unix术语）或文件句柄（Windows）
          数据源
          数据终端
        安全特性，诸如进程拥有者和进程的权限集（可以容许的操作）
        处理器状态，诸如寄存器内容、物理内存定址等。
      状态（state）
        新生（new）：进程新产生中
        运行（running）：正在运行
        等待（waiting）：等待某事发生，例如等待用户输入完成。亦称“阻塞”（blocked）
        就绪（ready）：排班中，等待CPU
        结束（terminated）：完成运行
        对于单CPU系统（UP），任何时间可能有多个进程为等待、就绪，但必定仅有一个进程在运行。
      进程间通信（IPC，Inter-Process Communication）：指至少两个进程或线程间传送数据或信号的一些技术或方法
        文件（如进程运行时的临时文件，进程结束时删除）
        信号（Signals）：是一种异步的通知机制，用来提醒进程一个事件已经发生。当一个信号发送给一个进程，操作系统中断了进程正常的控制流程，此时，任何非原子操作都将被中断。如果进程定义了信号的处理函数，那么它将被执行，否则就执行默认的处理函数。
        柏克莱套接字（英语：Internet Berkeley sockets） ，又称为BSD 套接字(BSD sockets)是一种应用程序接口（API），用于网际插座（ socket）与Unix域套接字，包括了一个用C语言写成的应用程序开发库，主要用于实现进程间通讯，在计算机网络通讯方面被广泛使用。
          socket() 为通讯创建一个端点，为套接字返回一个文件描述符。
          bind() 一般用于服务器端，将一个套接字与一个套接字地址结构相关联
          listen() 用于服务器端，使一个绑定的TCP套接字进入监听状态。
          connect() 用于客户端，为一个套接字分配一个自由的本地端口号。
          accept() 用于服务器端。
          send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用于往/从远程套接字发送和接受数据。
          close() 用于系统释放分配给一个套接字的资源。 如果是TCP，连接会被中断。
          gethostbyname()和gethostbyaddr() 用于解析主机名和地址。
          select() 用于修整有如下情况的套接字列表： 准备读，准备写或者是有错误。
          poll() 用于检查套接字的状态。 套接字可以被测试，看是否可以写入、读取或是有错误。
          getsockopt() 用于查询指定的套接字一个特定的套接字选项的当前值。
          setsockopt() 用于为指定的套接字设定一个特定的套接字选项。
        消息队列（Message queue）：用来处理一系列的输入，通常是来自用户。消息队列提供了异步的通信协议，每一条消息包含详细说明的数据，包含发生的时间，输入设备的种类，以及特定的输入参数，也就是说：消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中，直到接收者取回它。
          允许接收者在消息发送很长时间后再取回消息，但接受者需要轮询消息队列
        管道（Pipeline）：是一个由标准输入输出链接起来的进程集合，所以每一个进程的输出（stdout）被直接作为下一个进程的输入（stdin）。 每一个链接都由未命名管道实现。
          匿名管道
          命名管道：允许无亲缘关系的进程间进行通信
          流管道
          半双工通信
        信号量（Semaphore）又称为信号量、旗语，是一个同步对象，用于保持在0至指定最大值之间的一个计数值。
          PV操作：PV操作由P操作原语和V操作原语组成（原语是不可中断的过程），对信号量进行操作
            P（S）：①将信号量S的值减1，即S=S-1；②如果S³0，则该进程继续执行；否则该进程置为等待状态，排入等待队列。
            V（S）：①将信号量S的值加1，即S=S+1；②如果S>0，则该进程继续执行；否则释放队列中第一个等待信号量的进程。
        共享内存：映射一段能被其它进程访问的内存，这段共享内存由一个进程创建，但是多个进程可以访问
        经典问题
          生产者消费者问题
          读者写者问题
        多数操作系统
        所有POSIX系统，Window系统
      进程间同步机制
        原子操作
        信号量机制
        管程 (Monitors，也称为监视器) 是一种程序结构，结构内的多个子程序（对象或模块）形成的多个工作线程互斥访问共享资源。
          管程提供了一种机制，线程可以临时放弃互斥访问，等待某些条件得到满足后，重新获得执行权恢复它的互斥访问。
        会合
        分布式系统
      死锁（Deadlock）：在多任务系统下，当一个或多个进程等待系统资源，而资源又被进程本身或其他进程占用时，就形成了死锁。
        形成条件
          禁止抢占（no preemption）：即不剥夺，进程已获得的资源，在末使用完之前，不能强行剥夺。
          持有和等待（hold and wait）：一个进程因请求资源而阻塞时，对已获得的资源保持不放。
          互斥（mutual exclusion，简称mutex）：一个资源每次只能被一个进程使用。
          循环等待（circular waiting）：若干进程之间形成一种头尾相接的循环等待资源关系
        避免
          按同一顺序访问对象。(注：避免出现循环)
          避免事务中的用户交互。(注：减少持有资源的时间，较少锁竞争)
          保持事务简短并处于一个批处理中。(注：减少持有资源的时间)
          使用较低的隔离级别。(注：使用较低的隔离级别（例如已提交读）比使用较高的隔离级别（例如可序列化）持有共享锁的时间更短，减少锁竞争）
          使用绑定连接
      进程调度算法
        先进先出（FCFS）：算法总是把处理机分配给最先进入就绪队列的进程，一个进程一旦分得处理机，便一直执行下去，直到该进程完成或阻塞时，才释放处理机。
        短进程优先（SCBF--Shortest CPU Burst First）：该算法从就绪队列中选出下一个“CPU执行期最短”的进程，为之分配处理机。
        高优先权优先HRRF：既可以作为作业调度也可以作为进程调度算法；调度作业时，从就绪队列中选择优先级最高的作业进行处理
          抢占式
          非抢占式
          静态优先级
          动态优先级
        最高响应比优先HRN：FCFS可能造成短作业用户不满，SPF可能使得长作业用户不满，于是提出HRN，选择响应比最高的作业运行。响应比=1+作业等待时间/作业处理时间。
        多级反馈队列法：设置多个就绪队列并为每个队列设置不同的优先级，第一个队列优先级最高，其余依次递减。优先级越高的队列分配的时间片越短，进程到达之后按FCFS放入第一个队列，如果调度执行后没有完成，那么放到第二个队列尾部等待调度，如果第二次调度仍然没有完成，放入第三队列尾部…。只有当前一个队列为空的时候才会去调度下一个队列的进程。
        简单轮转法：系统将所有就绪进程按FIFO规则排队，按一定的时间间隔把处理机分配给队列中的进程。这样，就绪队列中所有进程均可获得一个时间片的处理机而运行。
    线程（thread）：线程是进程的实体，是CPU调度和分派的基本单位，它是比进程更小的能独立运行的基本单位。
      可并发执行
      状态
        产生（spawn）
        中断（block）
        非中断（unblock）
        结束（finish）
      同步方式
        互斥量：采用互斥对象机制，只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个，所以可以保证公共资源不会被多个线程同时访问。
        信号量：它允许同一时刻多个线程访问同一资源，但是需要控制同一时刻访问此资源的最大线程数量。
        事件（信号）：通过通知操作的方式来保持多线程同步，还可以方便的实现多线程优先级的比较操作。
  内存
    缓冲区溢出（Buffer Overflow）：当某个数据超过了处理程序限制的范围时，程序出现的异常操作。
      原因
        存在缺陷的程序设计，如没有仔细检查用户输入
        C语言，不会自动进行数组或者指针的边界检查，增加溢出风险
        C语言中的C标准库还具有一些非常危险的操作函数，使用不当也为溢出创造条件，例如strcpy,memcpy
      危害
        程序崩溃，导致拒绝额服务
        跳转并且执行一段恶意代码
          蠕虫病毒就针对缓冲区溢出
    分段，分页与段页式存储管理
      分页
        内存分配：页式存储管理将内存空间划分成等长的若干物理块，称为物理页面也称为物理块，每个物理块的大小一般取2的整数幂。内存的所有物理块从0开始编号，称作物理页号。对程序地址空间的分页是系统自动进行的，即对用户是透明的。
        页表：分页系统中，允许将进程的每一页离散地存储在内存的任一物理块中，为了能在内存中找到每个页面对应的物理块，系统为每个进程建立一张页表，用于记录进程逻辑页面与内存物理页面之间的对应关系。
          页号
          块号
        逻辑地址：页号P和页内位移量W组成
        物理地址：物理块号（由逻辑地址除以页表大小得到页号再查找页表得到块号）*页面大小+ 页内偏移（由逻辑地址对页表大小取模得到偏移）
        优点
          页长固定，便于构造页表、易于管理，且不存在外碎片
        缺点
          页长与程序的逻辑大小不相关
          不利于编程时的独立性
          换入换出处理、存储保护和存储共享等操作造成麻烦
      分段
        内存分配：段是按照程序的自然分界划分的长度可以动态改变的区域，将用户程序地址空间分成若干个大小不等的段，每段可以定义一组相对完整的逻辑信息。
        段表：本身也是一个段，可以存在辅存中，但一般是驻留在主存中。
          段起址
          段长
        逻辑地址：段号和段内地址组成
        物理地址：根据段号找到段表中的起始地址+段内地址 (如果段内地址超过限长则产生“地址越界”程序性中断事件达到存储保护)
        优点
          段的逻辑独立性使其易于编译、管理、修改和保护，也便于多道程序共享
          段长可以根据需要动态改变，允许自由调度，以便有效利用主存空间
          方便编程，分段共享，分段保护，动态链接，动态增长
        缺点
          主存空间分配比较麻烦
          容易在段间留下许多碎片，造成存储空间利用率降低
          由于段长不一定是2的整数次幂，因而不能简单地像分页方式那样用虚拟地址和实存地址的最低若干二进制位作为段内地址，并与段号进行直接拼接，必须用加法操作通过段起址与段内地址的求和运算得到物理地址。因此，段式存储管理比页式存储管理方式需要更多的硬件支持。
      段页式存储
        内存分配
          用分段方法来分配和管理虚拟存储器
          用分页方法来分配和管理实存
        段表与页表：为每个作业分配一个段表，每一段分配一个页表
        段表寄存器：段表始址和表长
        逻辑地址：段号S，页号P和页内地址d组成
        物理地址：(((x)+s)+p)*2^(11)+d，x为基地址
        优点
          它提供了大量的虚拟存储空间
          能有效地利用主存，为组织多道程序运行提供了方便
        缺点
          增加了硬件成本、系统的复杂性和管理上的开消
          存在着系统发生抖动的危险
          存在着内碎片
          还有各种表格要占用主存空间
    虚拟内存：虚拟内存就是具有请求调入功能和置换功能，可以从逻辑上对内存容量加以扩充的一种存储器系统。它使得应用程序认为它拥有连续可用的内存（一个连续完整的地址空间），允许运行比实际系统拥有的内存大得多的程序。而实际上，它通常被分割成多个物理内存碎片，还有部分暂时存储在外部磁盘存储器上，在需要时进行数据交换。
      缺页中断（或页错误）：当程序引用到一部分在物理内存中的地址空间时，由硬件立刻执行必要的映射。当程序引用到一部分不再物理内存中的地址空间时，由操作系统负责将缺失部分装入物理内存并重新执行失败的指令，这个过程或陷阱称为缺页中断（或页错误）。
      代价
        占用额外内存
        虚拟地址到物理地址的转换，增加了指令执行时间
        页式的换入换出需要磁盘I/O，耗费时间
        如果一页中只有部分数据，浪费内存
    页面置换算法
      最优页面置换算法：只具有理论意义的算法，用来评价其他页面置换算法。置换策略是将当前页面中在未来最长时间内不会被访问的页置换出去
      先进先出置换算法：由操作系统维护一个所有当前在内存中的页面的链表，最新进入的页面放在表尾，最早进入的页面放在表头；当发生缺页中断时，淘汰表头的页面并将新调入的页面追加到表尾。简单粗暴的一种置换算法，没有考虑页面访问频率信息。
      最近最少使用算法LRU：算法赋予每个页面一个访问字段，用来记录上次页面被访问到现在所经历的时间t，每次置换的时候把t值最大的页面置换出去(实现方面可以采用寄存器或者栈的方式实现)。
      时钟置换算法(也被称为最近未使用算法NRU)：页面设置一个访问位，页面被访问的时候访问位设置为1；并将所有页面保存在一个循环队列中，表针指向最老的页面。页面置换的时候，如果当前指针所指页面访问为0，那么置换，否则将其置为0，循环直到遇到一个访问为位0的页面。
      改进型Clock算法：在Clock算法的基础上添加一个修改位，替换时根究访问位和修改位综合判断。优先替换访问位和修改位都是0的页面，其次是访问位为0修改位为1的页面。
      最少使用算法LFU：设置寄存器记录页面被访问次数，每次置换的时候置换当前访问次数最少的。存在问题是该访问寄存器并不能真正反映当前页面访问次数，因为访问速度比较快，所以在更新寄存器的时间间隔内访问1次和访问100次都是一样的。另外，LFU和LRU是很类似的，支持硬件也是一样的，但是区分两者的关键在于一个以时间为标准，一个以次数为标准(例如对于寄存器 pa 001111 和pb 111000，两个页面，如果采用LRU，那么被淘汰的是pa，如果采用LFU那么被淘汰的是pb)。
      页面缓冲算法PBA：置换的时候，页面无论是否被修改过，都不被置换到磁盘，而是先暂留在内存中的页面链表(已修改页面链表和未修改页面链表，也可以不区分)里面，当其再次被访问的时候可以直接从这些链表中取出而不必进行磁盘IO，当链表中已修改页面数目达到一定数量之后，进行依次写磁盘操作(相当于将多次IO合并为一次)
    链接
      静态链接库
        优点
          代码装载速度快，执行速度略比动态链接库快
          只需保证在开发者的计算机中有正确的.LIB文件，在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题，可避免DLL地狱等问题。
        缺点
          使用静态链接生成的可执行文件体积较大，包含相同的公共代码，造成浪费
      动态链接库
        优点
          更加节省内存并减少页面交换
          DLL文件与EXE文件独立，只要输出接口不变（即名称、参数、返回值类型和调用约定不变），更换DLL文件不会对EXE文件造成任何影响，因而极大地提高了可维护性和可扩展性
          不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数
          适用于大规模的软件开发，使开发过程独立、耦合度小，便于不同开发者和开发组织之间进行开发和测试
        缺点
          使用动态链接库的应用程序不是自完备的，它依赖的DLL模块也要存在，如果使用载入时动态链接，程序启动时发现DLL不存在，系统将终止程序并给出错误信息。而使用运行时动态链接，系统不会终止，但由于DLL中的导出函数不可用，程序会加载失败
          速度比静态链接慢
          当某个模块更新后，如果新模块与旧的模块不兼容，那么那些需要该模块才能运行的软件，统统撕掉
  磁盘与文件系统
  网络
  安全
  用户界面
  驱动程序