【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇)

article/2025/10/26 15:15:43

【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇)

 

  大家好,我是Lampard~~

  经过一番艰苦奋战之后,我终于是进入了心仪的公司。

  今天给大家分享一下我在之前精心准备的一套面试知识。

 

   今天和大家分享的是操作系统相关的面试题

    额其实这篇博客在项目开发的过程中,用到的情况并不多(也可能因为我还是新人,接触不多)。然鹅各种游戏大厂都会很注重面试者的基础,在博主所见识过的大厂面试中,它们主要是着重面试者以下几种技能:1.语言:c++,c#,lua,js,python等,2.引擎:内存管理,渲染机制,事件分发机制,计时器调度机制,设计模式等,3.基础:虽然客户端和服务端会有不同的侧重,但是只要你是科班出身,它们就要考察你的基础,比如说计算机网络,操作系统,数据库,计算机组成原理等,4.算法:前三者如果说大家可以靠过目不忘的本领把知识点都背下来,那么算法的测试就是见真章的时候了,做出来不是终点,它们会一直深挖一直深挖,让你一直优化(头皮发麻)。5.项目经验:若各位是校招的话,前面4点会占了80,90%的面试比重,但是若是社招的同学,项目经验就是最重要的,起码占50%的比重,面试官会考察你做过什么系统,看你的能力到哪里。对于客户端来说如果你有计算机图形学,接过战斗系统,接过sdk,负责过打包patch业务,有为项目写过脚本完善工具链,那么就会有加分点。所以多准备准备是没有错滴。最后祝大家疯狂收割offer,通过自己的努力摆脱生活的苟且,走向诗和远方~

    

 

一. 线程和进程

基本概念:

进程:进程是对运行时程序的一个封装,是系统进行资源调度和分配的基本单位(在操作系统层面的并发)。

线程:线程是进程的子任务,是cpu调度和分派的基本单位(在进程层面的并发)。

为什么要设计进程和线程呢?有一位解释的很好

一开始大家想要同一时间执行那么三五个程序,大家能一块跑一跑。特别是UI什么的,别一上计算量比较大的玩意就跟死机一样。于是就有了并发,从程序员的角度可以看成是多个独立的逻辑流。内部是单cpu时间分片,能快速的切换逻辑流,看起来像是大家一块跑的就行。

但是一块跑就有问题了。我计算到一半,刚把多次方程解到最后一步,你突然插进来,我的中间状态咋办,我用来储存的内存被你覆盖了咋办?所以跑在一个cpu里面的并发都需要处理上下文切换的问题进程就是这样抽象出来个一个概念,搭配虚拟内存、进程表之类的东西,用来管理独立的程序运行、切换。

后来一电脑上有了好几个cpu,好咧,大家都别闲着,一人跑一进程。就是所谓的并行

因为程序的使用涉及大量的计算机资源配置,把这活随意的交给用户程序,非常容易让整个系统分分钟被搞跪。所以核心的操作需要陷入内核(kernel),切换到操作系统,让老大帮你来做。

有的时候碰着I/O访问,阻塞了后面所有的计算。空着也是空着,老大就直接把CPU切换到其他进程,让人家先用着。当然除了I\O阻塞,还有时钟阻塞等等。一开始大家都这样弄,后来发现不成,太慢了。为啥呀,一切换进程得反复进入内核,置换掉一大堆状态。进程数一高,大部分系统资源就被进程切换给吃掉了。后来搞出线程的概念,大致意思就是,这个地方阻塞了,但我还有其他地方的逻辑流可以计算,这些逻辑流是共享一个地址空间的,不用特别麻烦的切换页表、刷新TLB,只要把寄存器刷新一遍就行,能比切换进程开销少点。

简单来说就是,进程存在的意义是为了在cpu进行并发操作时,保护上下文,保护进程数据间不相互影响而设计出来的概念。有了进程我们就可以在单个cpu进行多进程分片,也可以多个cpu并发处理进程。而线程,就是在一个进程内其实也有多个逻辑,当一个逻辑需要io的时候,会白占cpu,占着茅坑不拉屎。而进程间切换的代价也比较大,为了提高效率,在就设计出可线程的概念,当进程中其中一个线程需要IO的时候,另一个线程来占用cpu以此提高效率。

进程和线程的区别,我们可以用以下的五点进行概括

1.一个线程只能属于一个进程,而一个进程可以有多个线程,线程依赖于进程而存在。

2.一个进程在执行的过程中有独立的内存空间,而线程之间共享进程的内存(线程有自己的寄存器组)。

3.进程是资源分配的最小单位,而线程是cpu调度的最小单位

4.进程之间切换开销大,而线程切换只需要保存一些寄存器数据

5.进程之间相互独立不会造成影响,而线程之间会造成死锁

 

二. 线程和进程之间的通讯方式

实际上只有进程间需要通信,同一进程的线程共享地址空间,没有通信的必要,但要做好同步/互斥,保护共享的全局变量。

而进程间通信无论是信号,管道pipe还是共享内存都是由操作系统保证的,是系统调用.

一、进程间的通信方式

  1. 管道( pipe ):
    管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  2. 有名管道 (namedpipe) :
    有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
  3. 信号量(semophore ) :
    信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  4. 消息队列( messagequeue ) :
    消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  5. 信号 (sinal ) :
    信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
  6. 共享内存(shared memory ) :
    共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
  7. 套接字(socket ) :
    套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备及其间的进程通信。

二、线程间的通信方式

  1. 锁机制:包括互斥锁、条件变量、读写锁
    互斥锁提供了以排他方式防止数据结构被并发修改的方法。
    读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
    条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
  2. 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
  3. 信号机制(Signal):类似进程间的信号处理
    线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

 

三. 死锁

死锁是不同的进程在争夺资源而造成相互等待的现象。

要造成死锁,必须满足以下的四种条件。

1.互斥条件

    进程对所分配的资源不允许其他进程访问

2.请求和保持条件

    在等待资源的过程中不会释放资源

3.不可剥夺

    其他进程不可以强制剥夺该资源

4.环路等待

    必然存在一条进程资源的环形链

图为环形链:

解决死锁

上文提及,造成死锁必须满足四个条件。那么我们就可以破坏其中任意一个条件来解决死锁。

1.互斥条件

    当超时未释放时允许访问

2.请求和保持条件

    一次性分配资源不需要等待

3.不可剥夺

    超时判定死锁时可以强制剥夺

4.环路等待

    终止某一个进程,破坏该链

 

四. 并发和并行

并发:是指同一个cpu执行多个进程,进程之间交叉执行着指令

并行:指的是多cpu机器,分别单独的运行着不同的程序

 

五. 说一说进程状态的转换图

进程的状态分别有:创建,就绪,执行,终止,等待阻塞

正常的流程是:创建 -> 就绪(准备好)-> 执行 -> 终止

若在执行的过程中,执行量过大,不能够在操作系统分配的时间片内完成,那么就回到就绪态等待下一次执行

若在执行的过程中,需要等待资源,那么就会进入等待阻塞状态,等到资源齐备之后,就会被唤醒回到就绪态再次等待执行。

 

六. 虚拟内存和物理内存

为什么需要虚拟内存

操作系统有虚拟内存与物理内存的概念。在很久以前,还没有虚拟内存概念的时候,程序寻址用的都是物理地址。程序能寻址的范围是有限的,这取决于CPU的地址线条数。

比如在32位平台下,寻址的范围是2^32也就是4G。并且这是固定的,如果没有虚拟内存,且每次开启一个进程都给4G的物理内存,就可能会出现很多问题:因为我的物理内存时有限的,当有多个进程要执行的时候,都要给4G内存,很显然你内存小一点,这很快就分配完了,于是没有得到分配资源的进程就只能等待。当一个进程执行完了以后,再将等待的进程装入内存。这种频繁的装入内存的操作是很没效率的

于是针对上面会出现的各种问题,虚拟内存就出来了。

这个虚拟内存你可以认为,每个进程都认为自己拥有4G的空间,这只是每个进程认为的,但是实际上,在虚拟内存对应的物理内存上,可能只对应的一点点的物理内存,实际用了多少内存,就会对应多少物理内存。进程得到的这4G虚拟内存是一个连续的地址空间(这也只是进程认为),而实际上,它通常是被分隔成多个物理内存碎片,还有一部分存储在外部磁盘存储器上,在需要时进行数据交换。

进程开始要访问一个地址,它可能会经历下面的过程

  1. 次我要访问地址空间上的某一个地址,都需要把地址翻译为实际物理内存地址
  2. 所有进程共享这整一块物理内存,每个进程只把自己目前需要的虚拟地址空间映射到物理内存上
  3. 进程需要知道哪些地址空间上的数据在物理内存上,哪些不在(可能这部分存储在磁盘上),还有在物理内存上的哪里,这就需要通过页表来记录
  4. 页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址(如果在的话)
  5. 当进程访问某个虚拟地址的时候,就会先去看页表,如果发现对应的数据不在物理内存上,就会发生缺页异常
  6. 缺页异常的处理过程,操作系统立即阻塞该进程,并将硬盘里对应的页换入内存,然后使该进程就绪,如果内存已经满了,没有空地方了,那就找一个页覆盖,至于具体覆盖的哪个页,就需要看操作系统的页面置换算法是怎么设计的了。

上文提及,若能够在页表中找到虚拟内存对应的物理内存,那么就会访问到该物理内存的内容。但是当在页表中查询发现对应的数据不在物理内存上(在磁盘中),就会发生缺页异常。

缺页中断的处理步骤:

1.保护cpu现场

2.分析原因

3.执行缺页中断恢复

4.恢复现场

执行缺页中断恢复同样分两种情况

首先是当前的物理内存还有空余,那么就会将硬盘里对应的页换入内存。若当前内存已经满了,那么此时可以有两种执行方案:1.替换最先进入的页,2.替换最少使用的页(常用)

 

好,今天的分享就到这里,祝各位功力渐长平步青云,谢谢大家~~

 


http://chatgpt.dhexx.cn/article/B3CCfFZl.shtml

相关文章

操作系统和网络(一):计算机网络常见面试题

计算机网络常见面试题总结 1. OSI , TCP/IP ,五层协议的体系结构 OSI分层(7层) :物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层(4层) :网络接…

【Java实习生】每日面试题打卡——操作系统篇

临近秋招,备战暑期实习,祝大家每天进步亿点点!Day15本篇总结的是 操作系统 相关的面试题,后续会每日更新~ 1、请分别简单说一说进程和线程以及它们的区别? 根本区别:进程是操作系统资源分配的基本单位,而…

操作系统面试题(一)

请你说一下进程与线程的概念,以及为什么要有进程线程,其中有什么区别,他们各自又是怎么同步的 参考回答: 基本概念: 进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了…

操作系统面试常问——for考研复试面试

关于操作系统的一些面试常问问题 前言: 本人22考研党已上岸,发一些复试准备整理的资料作为对考研准备的一个收尾。由于近几年基本都是线上复试,线上的话会更加注重概念的考察,本人在复试准备期间搜集了面试题,整理了…

操作系统面试题(三)

请你来说一说协程 参考回答: 1、概念: 协程,又称微线程,纤程,英文名Coroutine。协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适…

操作系统面试题(十四):什么是虚拟内存?

虚拟内存(virtual Memory) 日常生活中,当我们使用电脑的时候,尤其是windows电脑,经常会打开许多软件,这些软件占用的内存已经远远大于计算机的物理内存。之所以会这样,就是因为虚拟内存的存在 …

操作系统面试题:设备管理

管理什么设备? 除cpu,内存外的所有设备 怎么管理设备? 通过将物理设备映射成逻辑设备 为什么要把物理设备映射成逻辑设备? 物理设备是I/O系统中实际安装的设备,物理名通常是字符串或者ID 而逻辑设备的逻辑名比较好记 如何理解…

操作系统面试问题汇总(超详细)

操作系统的组成 1、驱动程序是最底层的、直接控制和监视各类硬件的部分,它们的职责是隐藏硬件的具体细节,并向其他部分提供一个抽象的、通用的接口。 2、内核是操作系统之最内核部分,通常运行在最高特权级,负责提供基础性、结构性…

操作系统面试题(二)

请你讲述一下互斥锁(mutex)机制,以及互斥锁和读写锁的区别 参考回答: 1、互斥锁和读写锁区别: 互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时…

几率大的杂乱+操作系统面试题(含答案)

其他面试题类型汇总: Java校招极大几率出的面试题(含答案)----汇总 几率大的网络安全面试题(含答案) 几率大的多线程面试题(含答案) 几率大的源码底层原理,杂食面试题(含…

操作系统常见面试题

文章目录 进程和线程进程和线程的区别协程与线程的区别进程与线程的切换流程什么是虚拟地址空间为什么虚拟地址空间切换后感觉程序变慢进程间通信方式线程(进程)间同步方式线程的分类协程(纤程)线程和协程的区别 进程(…

这可能最全的操作系统面试题

文章目录 操作系统简介篇解释一下什么是操作系统操作系统的主要功能软件访问硬件的几种方式解释一下操作系统的主要目的是什么操作系统的种类有哪些为什么 Linux 系统下的应用程序不能直接在 Windows 下运行操作系统结构单体系统分层系统微内核客户-服务器模式 为什么称为陷入内…

操作系统面试题(史上最全、持续更新)

尼恩面试宝典专题40:操作系统面试题(史上最全、持续更新) 本文版本说明:V28 《尼恩面试宝典》升级规划为: 后续基本上,每一个月,都会发布一次,最新版本,可以联系构师尼…

操作系统面试题总结(2022最新版)

关于作者 🐶 程序猿周周 ⌨️ 短视频小厂BUG攻城狮 🤺 如果文章对你有帮助,记得关注、点赞、收藏,一键三连哦,你的支持将成为我最大的动力 本文是《后端面试小册子》系列的第 4️⃣ 篇文章,该系列将整理和梳…

MFC中MENU的使用

一、创建基于对话框的应用程序框架 1.选择菜单项文件->新建->项目,弹出“新建项目”对话框。 2.直接选择“MFC应用程序”或左侧面板中模板的Visual C下选择MFC,中间窗口中选择MFC应用程序,然后在下面编辑框中键入工程名称,并…

MFC 菜单栏一片黑,界面卡顿问题

这是在公司做的一个项目, 实现可视化调节参数内容包括频段、频点、增益和Q值等,可以美化(包括丑化)和修饰声音,使声音(或音乐)风格更加鲜明突出。软件如下图所示: 但这软件开发过程中一直存在一…

C#版封装的近400个Windows API 类

【实例简介】 Windows API 类常用方法锦集 【实例截图】 文件&#xff1a;590m.com/f/25127180-494402201-213b68&#xff08;访问密码&#xff1a;551685&#xff09; 【核心代码】/// <summary> /// 封装Windows API类&#xff0c;可直接调用&#xff0c;和调用平常…

C#实现QQ窗体的步骤和总结

C#实现QQ窗体的步骤和总结 程序结构控件布局代码分析公共变量API调用公用方法事件 知识总结IntPtrMarshal 类PointOffset PaintEventArgs 类效果演示 GraphicsMouseEventArgs 类代码案例 ContextMenu 概述演示效果程序代码 MouseEventHandler句柄user32详细介绍使用方法 DllImp…

VC++:菜单的使用总结

菜单是windows应用程序经常使用的资源之一。从今天开始&#xff0c;把有关菜单的创建及使用等各方面的基本用法总结到一起&#xff0c;算是做个笔记吧&#xff01;准备一天写一点&#xff0c;陆陆续续完成&#xff01; 一、菜单的创建&#xff1a; &#xff08;一&#xff09…

Windows 编程[18] - 更换菜单项: ModifyMenu

为什么80%的码农都做不了架构师&#xff1f;>>> 本例效果图: 本例使用的资源文件(TestRes.rc): MyMenu1 MENUEX BEGINMENUITEM "Open" ,101MENUITEM "Old" ,102MENUITEM "Help" ,103 END本例代码文件: program Project1;{$R Tes…