网易游戏面经汇总(待更)

1.算法:如何将字符串转换为整数?leetcode 8
题目:
在这里插入图片描述

思路:
基本就是贝多芬了,注意几点 首先就是 标志位

int out = 0;
int isbegin = 0;
int negative = 0;

其次就是需要判断count与INT_MAX的关系(记得同等运算符的优先级 必要时需要加上括号)

if ((negative == 0 && out > INT_MAX / 10) || (negative == 0 && out == INT_MAX / 10 && c - '0' > 7))

代码:

class Solution {
public:
    int myAtoi(string s) {
        int out = 0;
		int isbegin = 0;
		int negative = 0;
		for (char c : s)
		{
			if (isbegin == 0)
			{
				if (c == '+')
				{
					isbegin = 1;
					negative = 0;
					continue;
				}
				else if (c == '-')
				{
					isbegin = 1;
					negative = 1;
					continue;
				}
				else if (c == ' ')
				{
					continue;

				}
			}
			//上面是空格和+ -判断出来了
			if (isdigit(c))
			{
				isbegin = 1;
				if ((negative == 0 && out > INT_MAX / 10) || (negative == 0 && out == INT_MAX / 10 && c - '0' > 7))
				{
					out = INT_MAX;
					return out;
					break;

				}
				else if ((negative == 1 && out > INT_MAX / 10) || (negative == 1 && out == INT_MAX / 10 && (c - '0') >= 8))
				//else if (isnegative == 1 && (out > INT_MAX / 10 || (out == INT_MAX / 10 && (c - '0') >= 8))) {

				{

					out = INT_MIN;
					return out;
					break;


				}
				else
				{
					out = out * 10 - '0' + c;//先减'0',防止先加c会溢出
				}
				// 



			}
			else//不是数字
			{
				break;

			}
			

		}

		if (negative == 1)
		{
			out = 0- out;

		}
		return out;
        
    }
};

2.2^31*2在计算机中如何表示?会输出什么?正数和负数在计算机中如何存储?有什么好处?

使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。负数的补码则是符号位为“1”。并且,这个“1”既是符号位,也是数值位。数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。

3.计算机图形学相关:
3.1渲染管线介绍一下?
在这里插入图片描述

GAMES101-现代计算机图形学入门-闫令琪 讲的非常好 文字参考链接:

首先,我必须对于英文翻译成中文的几个词作出解释
光栅化
(Rasterize/rasteriztion)。这个词儿Adobe官方翻译成栅格化或者像素化。没错,就是把矢量图形转化成像素点儿的过程。我们屏幕上显示的画面都是由像素组成,而三维物体都是点线面构成的。要让点线面,变成能在屏幕上显示的像素,就需要Rasterize这个过程。就是从矢量的点线面的描述,变成像素的描述。如下图,这是一个放大了1200%的屏幕,前面是告诉计算机我有一个圆形,后面就是计算机把圆形转换成可以显示的像素点。这个过程就是Rasterize。
渲染管线
(Pipeline)这个翻译尤其不接地气,简直就是直译(pipe管子line线路)。Pipeline是输送管道的意思。其实是指三维渲染的过程中显卡执行的、从几何体到最终渲染图像的、数据传输处理计算的过程。
着色器
(Shader)这个翻译的挺好。画画的时候我们经常有这么一个过程:先打线稿,再上色。着色器就是用来做这个工作的。通常着色器分两种:
1顶点着色器(vertex shader)这个是告诉电脑如何打线稿的——如何处理顶点、法线等的数据的小程序。
2片面着色器(fragment shader)这个是告诉电脑如何上色的——如何处理光、阴影、遮挡、环境等等对物体表面的影响,最终生成一副图像的小程序。采用了这两种着色器小程序 的 数据传输处理计算的渲染过程,称之为 可编程管线。

渲染管线主要包括五个部分
五个部分, 顶点处理-三角形处理-光栅化-片元处理-Framebuffer的处理
顶点处理:顶点处理的作用是指对所有的顶点数据进行Model,View,和Projection的变换,最终得到投影到二维平面的坐标信息(同时为了Zbuffer保留深度z值)。

三角形处理:就是将所有的顶点按照原几何信息,变成三角面,每个面由3个顶点组成。得到了许许多多个三角形,

三角形光栅化:光栅化是将几何数据经过一系列变换后最终转换为像素,从而呈现在显示设备上的过程

片元处理:这里有个重要的点是 片元着色器,片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色。归根结底,实际上就是数据的集合。这个数据集合包含每一个像素的各个颜色分量和像素透明度的值。

Framebuffer的处理:就是将所有的像素颜色信息整合在一起,输送给显示设备加以显示

3.2光照模型、实现?PBR有了解过吗?

光照计算处理共有三个部分:

  1. 环境光
  2. 漫反射
  3. 镜面反射

泛光模型: 泛光模型即只考虑环境光,这是最简单的经验模型,只会去考虑环境光的影响,并且不会去精确的描述,而只是用一个简单的式子表示
 在这里插入图片描述

Lambert漫反射模型:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Phong反射模型
   
在这里插入图片描述
在这里插入图片描述
Blinn-Phong反射模型(优化Phong模型)
在这里插入图片描述
整体计算公式: 泛光模型+Lambert漫反射+Blinn-Phong反射模型在这里插入图片描述

3.3顶点着色器中都可以做哪些事情?
使用vertex shaders,它用一段小程序替换固定功能处理。这段小程序的输入是模型空间的顶点,输出齐次剪裁空间的顶点,并且还携带一些信息,如:per-vertex diffuse 和 specualr,雾,透明度,纹理坐标和点大小
链接:

3.4视图矩阵什么样子的?为什么是那样的形式?
视图矩阵
在这里插入图片描述
至于为什么是那样的形式 因为包括了 旋转 ,放大缩小 以及平移 操作 注意1代表着是点 0代表着是向量

3.5反走样原理是什么?如何实现的
1.增加分辨率
2.先模糊后 采样
采样方法 例如将 增加采样数(一个像素点内)
MSAA
在这里插入图片描述

3.6 OpenGL渲染需要经过哪些状态测试?各自的机制
参考链接
光栅化阶段(包括纹理和雾)之后,数据就不再是像素,而是成为片断。每个片断都具有与像素对应的坐标数据以及颜色值和深度值,然后,每个片断都经历一系列的测试和操作。如果顺利通过这些测试和操作,片断值便可以转换为像素
(1) 裁剪测试

(2) alpha测试

(3) 模板测试

(4) 深度测试

(5) 混合

(6) 抖动

(7) 逻辑操作

3.7为什么会有锯齿?抗锯齿怎么弄?
三角形光栅化算法之后,我们可以把该三角形表示成一个如下图所示的像素点集合,这种问题本质是因为我们在采样的时候的频率过低无法跟上图像的频率从简单的角度去解释这种问题出现的原因就是,我们用有限离散的像素点去逼近连续的三角形,那么自然会出现这种锯齿走样的现象,因为这种近似是不准确的在这里插入图片描述
抗锯齿方法
1.1 超采样反走样(Super Sampling AA)
SSAA的想法其实是非常直观的,如果有限离散像素点逼近结果不好,那么我们用更多的采样点去逼近不就会得到更好的结果了吗?所以根据这个思想我们可以把原来的每个像素点进行细分,比如下例中,我们讲每个像素点细分成了4个采样点
在这里插入图片描述
1.2 多采样反走样(Multi-Sampling AA)
MSAA其实是对SSAA的一个改进,显然SSAA的计算量是非常大的,每个像素点分成4个采样点,我们就要进行4次的shading来计算颜色,额外多了4倍的计算量,如何降低它呢?

MSAA的做法也很容易理解,我们依然同样会分采样点,但是只会去计算究竟有几个采样点会被三角形cover,计算颜色的时候只会利用像素中心坐标计算一次颜色(即所有的信息都会被插值到像素中心然后取计算颜色),如下图
在这里插入图片描述

C++相关:

4.重载和覆盖的区别以及原理(为什么程序可以通过参数个数、类型的不同区分出 不同的重载函数)?

5.动态绑定机制?

6.class A{public: void fun(int x){cout<<"x = "<<x<<endl;}},则((A)0)->fun(100)是否可以调用?*

可以调用
这里当然是可以编译通过的,但是当代码执行到func函数时,如果这个函数中有访问到this则会崩溃,如果没有则不会,因为你传的是空指针,只是那个p本身是用ecx来传递的,你这个例子就相当于
mov ecx, 0
call func

显然如果 fun中有this指针,程序运行时,就会崩溃,因为指针this是通过ecx来进行调用的,现在 this是null(0)

7.const string、string const、string* const的区别?**
const string* p=string const* 这表达方式是一样的
const 在 * 左边,说明义的是指向常量的指针
就是说 不允许 *p=5 这种辅助了
String * const p
const 在 * 右边,说明定义的是常指针
就是说 p 不允许 再指向别处 p=&b 这种就会报错

8.指针和引用的区别?
在这里插入图片描述
在这里插入图片描述

9.vector和list的区别?vector的扩容是怎么进行的?有序的数分别存放在vector和list中,查找目标值哪个快一些?(vector扯了二分查找)

在这里插入图片描述

10.函数调用的过程是什么?
这个过程涉及到一些汇编的知识,过程可以讲的比较复杂,下面我说一种容易理解的,截图来源于 CLR via C#(第4版)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

网易互娱一面(80mins)
1.hr出了一道算法题:字符串转整数(半个小时)
2.自我介绍
3.项目介绍
4.虚函数表?
5.怎么实现虚函数表?
6.多态?
7.封装,继承,多态,抽象介绍一下?
8.多进程了解吗?
9.进程的通信方式?
10.socket编程了解吗?
11.tcp和udp的区别?
12.设计模型了解吗?
13.单例模式的应用场景?
14.观察者模式?组合模式?
15.类B继承类A,那么类B的内存分配方式?
16.场景题:微博关注:你关注我,我关注你,用什么数据结构存储?
17.怎么搜关注第三层的关注者?
18.python了解吗?
19.列表和元祖的区别?
20.装饰器介绍一下?
21.字典的底层结构?
22.场景题:吃鸡游戏网络延迟会怎么处理?

1、手撕LFU页面置换算法(讲思路并手撕O(1))

2、激光导航怎么解决误差累积

3、多态怎么实现的

4、虚函数结构(讲讲虚函数表是什么,子类的内存结构是怎样的)

5、STL容器和算法

6、迭代器的分类

7、泛型模板编程了解多少

8、C++内存泄漏(智能指针)

9、快速排序的时间和空间复杂度分析(最好,最坏,平均时间复杂度,空间复杂度),给一串数字,问你第一次快排后的结果

10、解决Hash冲突的方法(开放地址,拉链。。。)

11、TCP三次握手四次挥手 、TCP和UDP的区别

12、解释Socket字段(四元组)

13、网络编程的流程(有写过post,get。。。。吗)

14、Socket的阻塞与非阻塞

15、线程和进程的区别

16、进程调度的方法
进程调度的方法参考链接
一、先来先服务和短作业(进程)优先调度算法
1.先来先服务调度算法
2.短作业(进程)优先调度算法
二、高优先权优先调度算法
1.优先权调度算法的类型
1) 非抢占式优先权算法
2) 抢占式优先权调度算法

2.高响应比优先调度算法(我的理解是动态的改变响应比,使得低的优先级进程随着等待时间的增加,高响应比也会增加,这样保证了低优先也可以调度)

在这里插入图片描述
由于等待时间与服务时间之和就是系统对该作业的响应时间,故该优先权又相当于响应比RP。据此,又可表示为:
在这里插入图片描述
三、基于时间片的轮转调度算法
1.时间片轮转法
2.多级反馈队列调度算法
多级反馈队列调度算法:前面介绍的各种用作进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程,而且如果并未指明进程的长度,则短进程优先和基于进程长度的抢占式调度算法都将无法使用(前面两大类进程调度算法无法使用)。而多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。在采用多级反馈队列调度算法的系统中,调度算法的实施过程如下所述。

(1) 应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小。例如,第二个队列的时间片要比第一个队列的时间片长一倍,……,第i+1个队列的时间片要比第i个队列的时间片长一倍。

(2) 当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n 队列便采取按时间片轮转的方式运行。

(3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。如果处理机正在第i队列中为某进程服务时,又有新进程进入优先权较高的队列(第1~(i-1)中的任何一个队列),则此时新进程将抢占正在运行进程的处理机,即由调度程序把正在运行的进程放回到第i队列的末尾,把处理机分配给新到的高优先权进程。

17、进程开销为什么会大

18、虚拟内存和物理内存

当每一个进程创建的时候,就会为其分配4G的虚拟内存,当该进程还没有开始运行时,并不会立即就把虚拟内存对应位置的程序数据和代码拷贝到物理内存中,只要建立好虚拟内存和磁盘文件之间的映射就好,当运行到对应程序的时候,进程去寻找页表,发现页表中地址没有存放在物理地址上,而是在磁盘上,于是将磁盘上的数据拷贝到物理内存中(发生缺页异常)

进程开始要访问一个地址,它可能会经历下面的过程:
每次我要访问地址空间上的某一个地址,都需要把地址翻译为实际物理内存地址

所有进程共享这整一块物理内存,每个进程只把自己目前需要的虚拟地址空间映射到物理内存上

进程需要知道哪些地址空间上的数据在物理内存上,哪些不在(可能这部分存储在磁盘上),还有在物理内存上的哪里,这就需要通过页表来记录

页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址(如果在的话)

当进程访问某个虚拟地址的时候,就会先去看页表,如果发现对应的数据不在物理内存上,就会发生缺页异常

缺页异常的处理过程,操作系统立即阻塞该进程,并将硬盘里对应的页换入内存,然后使该进程就绪,如果内存已经满了,没有空地方了,那就找一个页覆盖,至于具体覆盖的哪个页,就需要看操作系统的页面置换算法是怎么设计的了。

页表的工作原理

我们的cpu想访问虚拟地址所在的虚拟页(VP3),根据页表,找出页表中第三条的值.判断有效位。 如果有效位为1,DRMA缓存命中,根据物理页号,找到物理页当中的内容,返回。

若有效位为0,参数缺页异常,调用内核缺页异常处理程序。内核通过页面置换算法选择一个页面作为被覆盖的页面,将该页的内容刷新到磁盘空间当中。然后把VP3映射的磁盘文件缓存到该物理页上面。然后页表中第三条,有效位变成1,第二部分存储上了可以对应物理内存页的地址的内容。

缺页异常处理完毕后,返回中断前的指令,重新执行,此时缓存命中,执行1。

将找到的内容映射到告诉缓存当中,CPU从告诉缓存中获取该值,结束。
虚拟内存的好处
在这里插入图片描述
虚拟内存的代价:
在这里插入图片描述

19、静态链接库和动态链接库
在这里插入图片描述

静态链接库和动态链接库参考地址
20、3个圆形摆在平面上,两两外切,问是否能够确定这三个圆心的相对位置
设已知的两个圆的圆半径分别为r1,r2,第三个圆的半径为r3。以第一个圆的圆心为圆心,r1+r3为半径画圆;以第二个圆的圆心为圆心,r2+r3为半径画圆,这两个圆的交点就是第三个圆的圆心。

网易一面
顶点着色器和片元着色器
我需要说明 像素,片元的关系
片元是光栅化过程的产物;光栅化是将一个图元转变为一个二维图象,二维图象上每个点都包含了颜色、深度和纹理数据,将该点和相关信息叫做一个片元;

片元和像素等价,但它比像素多了其它信息,如位置,法线,颜色,纹理坐标等;

片元着色器的作用是处理由光栅化阶段生成的每个片元,最终计算出每个像素的最终颜色。归根结底,实际上就是数据的集合。这个数据集合包含每一个像素的各个颜色分量和像素透明度的值。

相关概念:顶点是构成几何图形的基本要素;图元是有几何顶点组合而成的,包括:点,线段,多边形;3D场景中将三角形作为基本图元;

1.编程:括号匹配

2.图形渲染管线

3.顶点着色器的作用

4.顶点着色器中坐标系的变化
5.是否必须要经历这些坐标系的变化
6.片元着色器的作用
7.什么时候在顶点做光照什么时候在片元做光照
9.我有一个场景,有建筑、有天空盒。先画那个效率更高 (最后画天空盒效率高)
10.保证天空盒最后画的情况下,且天空盒深度不对,如何保证天空盒不会遮挡建筑物(1.模板测试 2.在vs中直接修改天空盒z值,保证其在最后面)
11.知道那些光照模型
12.介绍下PBR的原理
泛光模型+
13.PBR实现需要哪些参数
13.说下1中的思路

14.实现模板类的 stack的push 函数

15.什么是虚函数
16.虚函数的原理
17.静态多态
18.进程与线程的区别

19.线程共享资源时要注意什么(多线程问题,保证互斥)

  1. A 锁变量x 然后 call B, B函数里也会锁x, 会出现什么问题,如何解决 (1.传递线程标志量,当同一线程多次lock时,保证不lock 2.设置计数器,lock时计数+1, unlock时计数-1, 计数为0是释放资源)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值