图形/引擎/渲染相关面经
网易互娱:游戏引擎研发工程师
C++
- class 与 struct 有什么区别?
- 了解过内存对齐吗,为什么要对齐,不对齐会怎样?
struct 内存对齐
__declspec(align(#)) 的用法和大小计算 struct TA { char a; int b; char c; }; struct TB { char a; char b; int c; };
这两个结构体的大小一样吗?- C++ 11 是什么,C++ 11 有什么新特性,说一下你对 C++ 11 的理解。
C++11 常用新特性快速一览 - C++ 的多态是怎么实现的?
- 虚函数是什么,什么时候应该用虚函数,虚函数是怎么实现的,虚函数表在哪,虚函数指针在哪?
虚函数实现原理
C++ 虚函数实现原理
图形学
- 简述一下渲染管线。
- 了解过线性颜色空间吗?
GPU Gems 3 Chapter 24
Gamma 与线性颜色空间
色彩校正中的 gamma 值是什么?
什么是线性
Tone Mapping
我理解的伽马校正
伽马还是线性?用一张图理理在U3D中该如何设置。
Tone mapping 进化论 - 读 glsl,贴图采样、性能优化、高精度浮点。
- 了解过市面上游戏中的渲染技术吗?
搜狐畅游:引擎开发
- 背面剔除怎么做的?
- 深度测试发生在那个阶段,了解过 Early-Z 吗?
- 推导一下 view 矩阵。
- 布林冯模型与冯模型哪个快?
冯与布林冯 - 做过 IBL 吗?
- 了解过各类渲染优化吗?
当我们谈优化时,我们谈些什么
GPU 并行架构及渲染优化
early-z、z-culling、hi-z、z-perpass 到底是什么
延迟渲染与 MSAA 的那些事
腾讯:游戏客户端开发
- 100 层高楼扔两个水晶球,设计一个算法,可以快速确定水晶球会摔碎的临界值。
100 层楼扔两个鸡蛋的问题 - 浮点数是怎么存储的?
- STL库中 sort 底层实现、pow 底层实现?
std::sort 源码剖析 - 快排复杂度是多少,有更快的吗,数学上怎么证明使用比较进行排序的时间复杂度不小于 O(nLog(n))?
算法:排序算法之桶排序
排序的最低时间复杂度为什么是 O(nlogn)
如何证明快速排序法的平均复杂度为 O(nlogn)? - 两个进程处理一个数组,一个写入一个删除,怎么不冲突,怎么快?
- 哈希冲突了怎么办
哈希表及处理冲突的方法 - 模型描边几种做法,使用法线外扩时几次渲染?
GAMES202 Lecture 11
两次渲染,一次关闭深度写入画轮廓,第二次正常画模型。 - 工厂模式与抽象工厂区别?
抽象工厂模式和工厂模式的区别? - Unity 的协程用过吗?
快手:游戏图形开发
代码
- 反转从位置 left 到位置 right 的链表节点
LeetCode 92. 反转链表 II - 输出最长的不重复连续子串的长度
LeetCode 3. 无重复字符的最长子串
C++
- 什么是纯虚函数?
- override 与 overload 有什么区别?
- 堆与栈有什么区别?
c++ 中在堆和栈中申请空间的差别 - map 与 set
图形学
- 正交投影和透视投影的矩阵有什么区别?
- 法线贴图有什么意义,为什么法线贴图偏蓝色,TBN 矩阵怎么推导?
切线空间与法线贴图 - 了解过抗锯齿吗,TAA 和 FXAA 是怎么做的?
GAMES104 Lecture 7
GAMES202 Lecture 14 - stencil 了解过吗?
- pbr 材质公式包含哪几项,分别有什么意义,金属度影响的是哪一项?
GAMES202 Lecture 10 & 11
LearnOpenGL - 阴影怎么做,软阴影怎么做,着色点是怎么对应到 ShadowMap 上的,平行光阴影怎么做?
GAMES202 Lecture 1 - glsl 写一个布林冯
其他
- 最小生成树
【neko】最小生成树【算法编程#9】 - 进程与线程有什么区别
线程和进程的区别是什么 - 虚拟内存
如何理解虚拟内存 - TCP/IP,三次握手四次挥手
- 红黑树与平衡二叉树有什么区别
- CPU 架构
- CPU 调度机制
剑心互娱:渲染引擎开发工程师
代码
- 类似 LeetCode 226. 翻转二叉树
- 类似 LeetCode 1503. 所有蚂蚁掉下来前的最后一刻
关键在于两只蚂蚁碰撞的时候会完全交换速度,就像他们互不影响地穿过去了一样。
C++
-
字符串长度?
有个 ‘\0’,要加一。 -
给出一段代码
1
2
3void Foo(){
static char *pBuffer = new char[128];
}pBuffer 存储在什么内存区域,如果这个函数被执行多次会怎么样?
实例详解 C++ 程序的五大内存分区
动态存储区、静态存储区、堆和栈的区别
【Cherno】Local Static in C++ -
父类虚函数 A,子类同名非虚函数(应该指的是同名不同参的函数),子类中虚函数表中存储的是哪个函数指针?
虚函数与作用域 -
什么时候需要使用虚函数,父类的析构函数不是虚函数会怎么样?
C++ 中虚析构函数的作用
【68】【Cherno C++】【中字】C++的虚析构函数
指向子类的父类类型指针无法调用子类的虚构函数,造成内存泄漏。 -
new 和 malloc 有什么区别,自由存储区是什么?
【ISOCPP】What is the difference between new and malloc()?
细说 new 与 malloc 的 10 点区别
C++ 自由存储区是否等价于堆?堆是 C 语言和操作系统的概念,自由存储区是 C++ 中通过 new 动态分配对象的抽象概念。基本上,所有 C++ 编译器预设会使用对去实现自由存储区。但程序员也可以通过重载操作符改用其他方式实现自由存储区。
–《游戏引擎架构》 -
内存池了解过吗?
简单讲解 C++ 内存池原理与实现 -
引用和指针有什么区别,引用占内存空间吗?
C++ 中指针和引用的区别
你真的了解引用吗 -
结构体为什么要对齐,什么规则,#pragma pack() 的应用场合?
#pragma pack 指令详解
关于应用场合,网上的文章清一色地表示:在网络协议编程中,经常会处理不同协议的数据报文。一种方法是通过指针偏移的方法来得到各种信息,但这样做不仅编程复杂,而且一旦协议有变化,程序修改起来也比较麻烦。在了解了编译器对结构空间的分配原则之后,我们完全可以利用这一特性定义自己的协议结构,通过访问结构的成员来获取各种信息。这样做,不仅简化了编程,而且即使协议发生变化,我们也只需修改协议结构的定义即可,其它程序无需修改,省时省力。
-
模板优缺点有哪些?
使用 c++ 模板的优点和缺点
c++ 模板类声明和定义都放在 .h 文件的原因
模板类在 .h 中定义,在 .cpp 中实现 -
红黑树和平衡二叉树有什么区别,红黑树什么情况比平衡二叉树快,什么情况慢?
插入删除快,查找慢 -
队列怎么实现?
数组双指针、双向链表 -
delete[] 是怎么知道数组长度的?
【ISOCPP】over-allocation1
2
3
4
5
6
7char* tmp = (char*) operator new[] (WORDSIZE + n * sizeof(Fred));
Fred* p = (Fred*) (tmp + WORDSIZE);
*(size_t*)tmp = n;
try{
// 分配
}
catch(...){ ... }1
2
3
4
5
6
7
8
9Fred* p = (Fred*) operator new[] (n * sizeof(Fred));
try{
// 分配
}
catch(...){ ... }
// arrayLengthAssociation is the imaginary name of a hidden,
// global associative array that maps from void* to size_t
// they maby use an AVL tree
arrayLengthAssociation.insert(p, n); -
对 new[] 出来的数组做 delete 会怎样。
【ISOCPP】What if I forget the [] when deleteing an array allocated via new T[n]?All life comes to a catastrophic end.
【ISOCPP】Can I drop the [] when deleteing an array of some built-in type (char, int, etc)?
But the above code is wrong, and it can cause a disaster at runtime. In particular, the code that’s called for delete p is operator delete(void*), but the code that’s called for delete[] p is operator delete. The default behavior for the latter is to call the former, but users are allowed to replace the latter with a different behavior (in which case they would normally also replace the corresponding new code in operator new). If they replaced the delete[] code so it wasn’t compatible with the delete code, and you called the wrong one (i.e., if you said delete p rather than delete[] p), you could end up with a disaster at runtime.
我并没有完全理解在这样的极端情况中具体会发生什么,这里仅记录一些测试结果。
在 VS2020 的测试中,对于基本数据类型数组来说,这么操作并不会引起内存泄漏。
对于自定义的数据类型数组,一旦为其定义了析构函数,便会报错:Critical error detected c0000374
。
若没有定义析构函数,又在对象构造过程中发生了内存分配,便会产生内存泄漏。 -
new 出来的内存可以被 free 吗?
【ISOCPP】Can I free() pointers allocated with new? Can I delete pointers allocated with malloc()?There is no guarantee that the mechanism used by new and delete to acquire and release raw memory is compatible with malloc() and free(). If mixing styles works on your system, you were simply “lucky” – for now.
-
虚函数在虚函数表中是怎么匹配的?
虚函数底层原理 -
编译几个阶段?
C/C++ 程序编译的四个阶段 -
map 和 unorder_map 区别?
map 和 unordered_map 的区别
其他
- 最喜欢哪款游戏,为什么?
- 我看你 2077 和巫师三都玩过,你觉得 2077 相比于巫师三有哪些技术上的进步?
- 游戏中实时光追是怎么应用的?
- UE5 演示视频看过吧,你觉得就画面来说还有哪些能够提升的地方,为什么人物相对于场景看起来那么不真实?
- 你觉得在游戏画面中哪部分最容易让人一眼察觉到画面的不真实?
- mc 玩了多久,你觉得这个游戏开发过程中会有哪些技术难点,他是怎么呈现出这么大的一个世界的,世界中的方块是怎么存储的,实体之间的碰撞是怎么做的?
- 你之前的这个项目(一个 2D 平台跳跃游戏)你现在觉得有什么能改进的地方?
Bilibili:游戏引擎开发工程师
图形学
- 延迟渲染优缺点?
延迟渲染(Deferred Rendering)的前生今世
游戏引擎中的光照算法
Forward+ Shading
延迟渲染为什么不支持 MSAA?
FXAA、FSAA 与 MSAA 有什么区别? - ECS 了解过吗?
GAMES104 Lecture 3 - PBR 相对于传统经验模型优缺点?
GAMES104 Lecture 5
E 星计划 光照综述 - 屏幕空间阴影了解过吗?
unity 屏幕空间阴影 - 级联阴影了解过吗?
Cascaded Shadow Maps(CSM) 实时阴影的原理与实现
Unity 实时阴影实现——Cascaded Shadow Mapping - HDR 了解过吗?
百人计划 图形 2.7 LDR 与 HDR
Tone Mapping 与 Gamma Correction
GAMES104 Lecture 7 - mesh shader 了解过吗?
GAMES104 Lecture 6
Quick Introduction to Mesh Shaders (OpenGL and Vulkan)
UE5 的 nanite 和 DX12U 的 meshshader 有什么不同? - 光线追踪是怎么做的,离线光追有哪些加速策略,实时光追有哪些加速策略?
这里讲讲概念就给过了,展开讲我不会也讲不完。 - 测试分为哪几个部分,什么顺序?
深度测试/模版测试/透明度测试先后顺序是什么样的?
用一篇文章理解半透明渲染、透明度测试和混合、提前深度测试并彻底理清渲染顺序。 - 有哪些降低 DrawCall 的手段,剔除分为哪几个部分,怎么做的?
剔除:从软件到硬件
【游戏场景剔除】剔除算法综述
E 星计划 Lecture 6 - 移动端的 TBDR 了解过吗,有什么优缺点?
IMR, TBR, TBDR 还有 GPU 架构方面的一些理解
移动设备 GPU 架构知识汇总 - Forward+ 了解过吗?
- 用 Unity 写过 Shader 吗,为什么选择学习 OpenGL?
面试官建议可以尝试一下新一点的图形 API,比如 Vulkan、DX12 - Eigen 这个库的效率非常高,你觉得是为什么?
Eigen 的速度为什么这么快?
Lazy Evaluation and Aliasing
What happens inside Eigen, on a simple example - 你觉得 C++11 中最重要的特性有哪些?
面试官又简单介绍了一些现代 C++ 的特性:rang、函数式编程、执行策略
其他
- 快排优缺点,稳定吗,时间复杂度,空间复杂度,最坏什么情况?
- 堆排序优缺点?
- 这些排序算法怎么选择?
各种排序算法的总结和比较 - 装箱开销体现在哪里?
- map、unordered_map 中查询的时间复杂度是多少?
- 有哪些 hash 算法?
光线云:图形算法工程师
图形学
- 光栅化有哪些做法
- VSM
- 平面反射
- VBO、EBO、VAO
- PBR 有哪些贴图
Albedo、Normal、Metallic、Roughness、AO
C++
- STL 底层
- C++ 异常
- 多线程
- 死锁怎么处理
死锁,死锁的四个必要条件以及处理策略 - 哪些数据是一个线程私有的
- 红黑树底层
红黑树算法和应用 - 构造函数为什么不能是虚函数
对象未创建时不存在虚函数表指针。 - 智能指针
- 模板类
网龙:程序研究员
图形
- 深度测试在什么空间
- 三角形内怎么进行插值,重心坐标怎么求
- PBR 公式什么意义,怎么推导
- 法向量乘以变换向量逆矩阵的转置
C++
- forward 和 move 的区别
- 线程 move
- function 和 lambda 的区别
- weak_ptr 怎么保证有效
- unic_ptr 怎么实现
- obj 文件左右手坐标系
其他
- Unity 场景资源管理
- M乘N 大小的矩阵,每个元素的值都是 X乘Y 的结果,怎么找到第 K 小的元素。
- 三维空间中有一个圆圈,已知圆上两点 A、B 以及过 A 点的切线,如何用线性代数的方式求圆心位置。
释厄:游戏引擎开发
C++
- const 对象可以触发移动函数吗,为什么?
- 被 move 了的对象还能继续使用吗?
图形
- 为什么要使用双重缓冲?
- 模型数据从 CPU 到 GPU,再到最后的画面,会经历哪些空间转换?
- 使用 NDC 空间的目的是什么?
- shader 在你的理解里是指什么?
- 为什么在 shader 中计算会比在 cpu 计算快?
- 写 shader 需要注意些什么?
- 为什么要避免分支,分支的开销在于什么?
- CPU 传递给 shader 数据要注意些什么?
- GPU Driven 是什么?
- 为什么经常用贴图去存储数据?
- 了解过现代化的图形api设计吗?
- FrameGraph 定义了哪些 Stage 去划分一个 Pass 的流程?
- FrameGraph 定义了哪些资源类型,来更好的管理动态资源,或者说资源的生命周期?