异步

  • 进程,线程,协程的区别?

 1、进程

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

  2、线程

线程是进程的一个实体,是CPU调度和分配的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

  3、协程

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

协程就是在unity主线程运行时开启另外一段逻辑来协助运行,来模拟多线程。使用场景多用于异步、动画、等待等操作,最常见的就是进度条异步加载。原理是利用了像list、Dictionary内部使用的迭代器,但是使用方法不同,不是迭代元素,而是分帧执行代码。每一帧调用迭代器的方法(MoveNext),其中unity利用关键字yield return快速实现了迭代器,两个yield return之间就是MoveNext方法执行的内容。
线程是操作系统调度的基本单位,一个程序至少会有一个线程。unity本身没有多线程,但是支持多线程的使用(不这样说,不懂的就查到网上很多文章说unity没有多线程的概念来质疑你)。unity中使用多线程是无法直接调用unity的api,需要访问unity的GameObject、Transform这些对象的时候可以搞容器去在主线程(比如在update)中处理。一般来说,多线程用在处理网络、数据计算、资源加载此类的场景。

协程是异步,进程和线程是同步

特点 进程 (Process) 线程 (Thread) 协程 (Coroutine)
资源开销 最大,创建和销毁开销大 较小,轻量级 最小,开销极小
调度方式 由操作系统内核调度 由操作系统内核调度 由程序自身调度
独立性 独立地址空间 共享进程资源 共享单线程资源
通信方式 通过 IPC 机制 直接共享内存 直接共享内存
适用场景 高度隔离的任务 并发执行任务 I/O 密集型任务状态管理
状态管理 创建、就绪、运行、等待、终止 创建、就绪、运行、等待、终止 创建、就绪、运行、挂起、终止

编译

  • C++从源文件到可执行文件需要经历哪些步骤

首先是**预处理阶段(preprocessing)-》编译阶段(compilation)-》汇编阶段(assembly)-》链接阶段(linking)**。

c++编译过程简介 - 云东 - 博客园

答:包括四个阶段:预处理阶段、编译阶段、汇编阶段、连接阶段。

(1)预处理阶段处理头文件包含关系,对预编译命令进行替换,生成预编译文件;

(2)编译阶段将预编译文件编译,生成汇编文件(编译的过程就是把预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码);

(3)汇编阶段将汇编文件转换成机器码,生成可重定位目标文件(.obj文件)(汇编器是将汇编代码转变成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单,根据汇编指令和机器指令的对照表一一翻译即可);

(4)链接阶段,将多个目标文件和所需要的库连接成可执行文件(.exe文件)。

死锁

  • 什么是死锁,死锁的条件以及如何防止?什么是银行家算法?

(1)死锁就是多个进程并发执行,在各自占有一定资源的情况下,希望获得其他进程占有的资源以推进执行,但是其他资源同样也期待获得另外进程的资源,大家都不愿意释放自己的资源,从而导致了相互阻塞、循环等待,进程无法推进的情况。

(2)死锁条件:1)互斥条件(一个资源每次只能被一个进程使用);2)请求并保持条件(因请求资源而阻塞时,对已获得的资源保持不放);3)不剥夺条件(在未使用完之前,不能剥夺,只能自己释放);4)循环等待(若干进程之间形成一种头尾相接的循环等待资源关系)。

(3)死锁防止:1)死锁预防,打破四个死锁条件;2)死锁避免,使用算法来进行资源分配,防止系统进入不安全状态,如银行家算法;3)死锁检测和解除,抢占资源或者终止进程;

(4)银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。安全的状态指的是一个进程序列{P1,P2,…Pn},对于每一个进程Pi,它以后尚需要的资源不大于当前资源剩余量和其余进程所占有的资源量之和。

内存

  • 操作系统如何管理内存,什么是虚拟内存?

通过一种分页管理机制来进行内存管理。分页管理机制将程序的逻辑地址划分为固定大小的页,而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离。虚拟内存是基于分页存储管理机制的,它允许程序不必将所有的页都放入内存中,而只是将一部分页映射到内存中,另一部分页放在外存上(如磁盘、软盘、USB),当引用到不在内存中的页时,系统产生缺页中断,并从外存中调入该部分页进来,从而产生一种逻辑上内存得到扩充的感觉,实际上内存并没有增大。

  • 什么是内存碎片,内存碎片是在虚拟内存还是物理内存?

【参考资料】:内存碎片_百度百科 (baidu.com)

采用分区式存储管理的系统,在储存分配过程中产生的、不能供用户作业使用的主存里的小分区称成“内存碎片”。内存碎片分为内部碎片和外部碎片。内存碎片只存在于虚拟内存上。

Cache

计算机组成原理

  • 什么是缓存(Cache)?为什么需要缓存?如何提高缓存的命中率?缓存是不是最快的?(⭐⭐)

(1)Cache即CPU的高速缓冲存储器,是一种是用于减少处理器访问内存所需平均时间的部件;

(2)由于CPU的计算速度远远大于从CPU向内存取数据的速度,如果每次都让CPU去内存取数据,会导致CPU计算能力的浪费,所以人们设计了缓存,CPU通过读写缓存来获取操作数,结果也通过缓存写入内存;

(3)注意程序的局部性原理,在遍历数组时按照内存顺序访问;充分利用CPU分支预测功能,将预测的指令放到缓存中执行;此外缓存的容量和块长是影响缓存效率的重要因素。如何提升CPU的缓存命中率? - 知乎 (zhihu.com)

(4)缓存不是最快的,寄存器更快。

  • 什么是缓存一致性,如何保证缓存一致性

(1)在多核CPU中,每个核有自己的缓存,在两个核进行独自修改缓存中的数据的时候,就可能会造成数据不一致的问题,就是缓存的一致性问题;

(2)一个是在总线中加锁,一个是采用缓存一致性协议。

  • 一个缓存块的大小是多少,读取内存中的字段是读多少数据取多少内存吗?

如果缓存没有命中(即读取一个数据没有在缓存中),不仅需要把该字(数据)从主存中取出,还需要从主存中将它所在的整个字块一次调入缓存中。缓存线(块)的长度是64B。

  • 操作系统的四大功能:进程控制,内存管理,设备管理,文件管理
  • 进程的定义:并发程序的执行,进程的同步与互斥
  • 进程的状态:创建,终止,挂起,激活,阻塞,唤醒,以及相互转换关系
  • 进程同步问题:生产者消费者模型,信号量机制
  • 进程的调度与死锁,死锁条件
  • 进程死锁的原因,如何避免
  • 存储器管理:只读存储器,随机存储器,相对地址和绝对地址
  • 速度问题:CPU>寄存器>缓存>主存>磁盘缓存>硬盘
  • 程序的装入和链接(动态装入,静态装入,重定位)
  • 内存空间划分算法:首次适应;最佳适应;最坏适应
  • 段式存储和页式存储,以及段页式存储的优缺点,原理
  • 页面置换算法(LRU,LFU,FIFO这些)
  • 进程与线程的区别和联系
  • 多线程编程安全性
  • 线程池,线程的创建,同步,安全问题
  • 信号量机制
  1. 四大操作系统功能:
    • 进程控制: 管理程序执行,包括进程的创建、调度和终止。
    • 内存管理: 分配和管理内存空间,保证内存的有效使用。
    • 设备管理: 管理计算机硬件设备的访问,包括输入输出设备。
    • 文件管理: 管理文件的存储、访问、保护和共享。
  2. 进程的定义:
    • 进程是计算机中运行的一个程序,它是程序执行的实例。
    • 并发执行: 同时运行多个进程。
    • 进程的同步与互斥: 同步是指不同进程间的协调,互斥是指多个进程共享资源时的访问控制。
  3. 进程的状态:
    • 创建: 进程被创建。
    • 终止: 进程完成并退出。
    • 挂起: 进程因某些原因被暂停执行,等待条件满足。
    • 激活: 挂起的进程恢复执行。
    • 阻塞: 进程等待某个事件的发生(如I/O操作)。
    • 唤醒: 阻塞的进程条件满足,恢复执行。
    • 状态转换的关系:进程在不同状态间转换,通常由调度器和事件控制。
  4. 进程同步问题:
    • 生产者-消费者模型: 解决多个进程共享资源时的同步问题。
    • 信号量机制: 通过计数器控制进程对共享资源的访问。
  5. 进程调度与死锁:
    • 进程调度: 操作系统决定哪个进程获得CPU时间。
    • 死锁条件: 互斥、请求与保持、不剥夺、环路等待。
  6. 进程死锁的原因与避免:
    • 死锁的原因是进程相互等待资源而无法释放,导致永远无法继续执行。
    • 避免死锁: 可以通过资源分配策略(如资源有序分配、死锁检测等)避免死锁。
  7. 存储器管理:
    • 只读存储器(ROM): 只能读取的存储器,通常用于存储固件。
    • 随机存储器(RAM): 计算机的主要内存,数据可以读写。
    • 相对地址与绝对地址: 相对地址是偏移量,绝对地址是内存中的实际位置。
  8. 速度问题:
    • CPU > 寄存器 > 缓存 > 主存 > 磁盘缓存 > 硬盘:速度从快到慢。
  9. 程序的装入和链接:
    • 动态装入: 程序在运行时加载。
    • 静态装入: 程序在执行前就加载到内存。
    • 重定位: 调整程序的地址使其适应不同的内存位置。
  10. 内存空间划分算法:
    • 首次适应: 第一个足够大的空闲块。
    • 最佳适应: 最小的足够大的空闲块。
    • 最坏适应: 最大的空闲块。
  11. 存储管理方式:
    • 段式存储: 将程序分为多个段,如代码段、数据段。
    • 页式存储: 将程序划分为固定大小的页。
    • 段页式存储: 结合段式和页式存储,平衡两者的优缺点。
  12. 页面置换算法:
    • LRU (Least Recently Used): 最近最少使用页面替换。
    • LFU (Least Frequently Used): 最少使用次数的页面替换。
    • FIFO (First In, First Out): 先进先出页面替换。
  13. 进程与线程的区别:
    • 进程: 操作系统中的独立执行单元,拥有自己的地址空间。
    • 线程: 进程内部的执行单元,多个线程共享同一进程的资源。
    • 区别与联系: 线程是轻量级的进程,多个线程可以并发执行,并且共享进程的内存。
  14. 多线程编程安全性:
    • 多线程编程需要关注同步和互斥,防止资源竞争和数据不一致。
  15. 线程池:
    • 线程池: 用于管理多个线程,减少线程创建和销毁的开销。
    • 线程的创建与同步: 线程池通过线程的复用来避免频繁创建销毁线程,并保证线程间同步。
    • 安全问题: 线程之间的资源共享需要通过锁等机制保证数据一致性和安全性。
  16. 信号量机制:
    • 用于进程间同步,控制多个进程对共享资源的访问。

参加数十次校招笔试面试后,我做了全面的总结(游戏开发岗) - 知乎