文章目录

  • 前言
  • C++
    • 多态
  • 计算机组成原理
  • 数据结构
  • 计算机网络
  • 操作系统
    • 栈和堆
  • 图形学
  • Unity

前言

网上搜索来的各种一面的问题以及回答
搜罗了很多面经,把所有问题像上面一样根据类别分好,从频率高到低一个类别一个类别复习,我这里的顺序是C++基础–>计算机网络/算法&数据结构&面向对象–>软件工程/图形学–>操作系统/编译原理,最后事实证明前人经验非常靠谱,面试官就考这些。

C++

重载和重写的区别

class A{
public:
void test(int i);
void test(double
i);//overload
void test(int i, double j);//overload
void test(double i, int j);//overload
int test(int i);
//错误,非重载。注意重载不关心函数返回类型。 }; ```隐藏:是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。 重写:```cpp
#include <iostream> using namespace std;class Base { public:void fun(double ,int ){ cout << "Base::fun(double ,int )" << endl; } };class Derive : public Base { public:void fun(int ){ cout << "Derive::fun(int )" << endl; } };int main() {Derive pd;pd.fun(1);//Derive::fun(int )pb.fun(0.01, 1);//error C2660: “Derive::fun”: 函数不接受 2 个参数system("pause");return 0; }

重写(覆盖):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

重载和重写的区别:

(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。

(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。

(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。

怎么用C实现多态

指针跟数组的区别,二者基于内存的区别

数组对应着一块内存区域,而指针是指向一块内存区域。其地址和容量在生命期里不会改变,只有数组的内容可以改变;而指针却不同,它指向的内存区域的大小可以随时改变。

野指针和空指针
出现野指针的两种情况,如何避免
回答可见这个:

https://blog.csdn.net/qq_33757398/article/details/81259636

智能指针

回答:动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。
为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。
当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。
智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。

什么情况会使用指针

面向对象是什么?



c++的三大特性是什么?

封装,继承,多态

c++中 模板是 编译时多态还是运行时多态

虚函数,虚表原理
虚函数表确定时期(编译期)

http://c.biancheng.net/view/267.html

为什么在虚函数表在编译期确定,如果在运行时确定会怎样

我觉得这样的话就无法实现运行时的多态了,因为首先要在编译时将虚函数确定在虚函数表上的地址,而运行时直接到类中该函数的地址并调用

怎样判断单链表是否存在回环

最简单的方法, 用一个指针遍历链表,
每遇到一个节点就把他的内存地址做为key放在一个map中.
这样当map中出现重复key的时候说明此链表上有环. 这个方法的时间复杂度为O(n), 空间同样为O(n).

判断单链表是否存在回环原理很简单,即假设有两个指针p1,p2。在每次循环的时候,p1先走一步,p2走两步,直到p2碰到空指针或两者相等时循环结束,如果两个指针相等则说明存在回环。

C++函数的调用约定?

C++语言中的函数调用约定主要针对三个问题: A、函数参数的入栈顺序 B、清理栈的主体(负责清理栈的主体:函数自身还是调用函数者)
C、函数名称重整
调用约定主要是指函数被调用的方式,C++语言的函数调用约定主要有stdcall,fastcall,pascal,cdecl,thiscall等约定。
在C++中,为了允许操作符重载和函数重载,C++编译器通常按照某种规则改写每一个入口点的符号名,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器。这项技术通常被称为名称改编(Name
Mangling)或者名称修饰(Name Decoration)。C++编译器厂商通常选择自己的名称修饰方案。

内联函数?

定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.

优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.

内联函数定义?

使用关键字:inline  函数定义形式:inline [返回类型] 函数名{[函数体]}

例子:

当调用max函数本身所产生的开销可能比函数内语句执行开销大,所以我们采用内联函数,减少调用开销。

#include<iostream>
using namespace std;
inline int Max(int a,int b){   //定义内联函数if(a>b) return a;else return b;
}
int main(){int a = 3;int b = 5;cout << "Max:" << Max(a,b) << endl;  //内联函数的定义
}

当调用了这个Max函数时,经过编译器预处理后真正执行的程序可能是下面这个样子

#include<iostream>
using namespace std;
int main(){int a = 3;int b = 5;int temp;if(a>b) temp = a;else temp = b;cout << "MAX:" << temp << endl;;
}

为什么要使用内联函数?

因为函数调用时候需要创建时间、参数传入传递等操作,造成了时间和空间的额外开销。C++追求效率所以引入了内联的概念。

通过编译器预处理,在调用内联函数的地方将内联函数内的语句Copy到调用函数的地方,从而提高了效率,减少了一些不必要的开销。

内联函数的缺点?

内联函数的弊端
使用内联函数后虽然调用函数的开销降低了,但是有利必有弊,内联函数会导致主函数指令增多、函数体积增大等情况。

开发中要根据情况正确使用内联函数 。

内联函数和宏的比较?

C++基础,这里主要问了define与inline的区别;
只有当函数只有 10 行甚至更少时才将其定义为内联函数.

https://blog.csdn.net/vivien1997/article/details/78618258

虚函数,纯虚函数,为什么要有这些;


动态绑定怎么实现的,这样设计有什么优点,

静态变量的保存方式

全局变量、静态局部变量保存在全局数据区

问了一下全局与局部都定义一个静态变量会有什么样的结果

静态变量生存期为整个程序期间,但只能在函数内部被使用,当在函数内部使用全局已有的同名变量时,此时使用的局部静态变量。当在函数外部使用,使用的是外部的全局变量。
可以理解为全局静态变量a为a1,局部静态变量为a2,这两个是互相不会影响对方的值的。

多继承的时候两个父类都有同名函数,可以么,如果可以,函数能调用么,为什么?
不可以调用,会报错,说有二义性


https://www.cnblogs.com/sunada2005/archive/2013/10/30/3397090.html

函数后面放const什么作用

C++在函数声明时,后面跟个const是限定函数类型为常成员函数, 常成员函数是指不能改变成员变量值的函数

char *p = new char[10], 求sizeof§

p是一个指针,只是指向了字符串char[3]而已。所以sizeof§不是字符串占的空间也不是字符数组占的空间,而是一个字符型指针占的空间。所以sizeof§=4,在C/C++中一个指针占4个字节

C++11的新特性:

https://www.cnblogs.com/feng-sc/p/5710724.html

用过哪些stl(map,unordered_map, array, vector),

set的特性是,所有元素都会根据元素的键值自动排序。

unordered_map和map区别

https://blog.csdn.net/batuwuhanpei/article/details/50727227
头文件
map: #include < map >
unordered_map: #include < unordered_map >
内部实现机理
map: map内部实现了一个红黑树,该结构具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素,因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行这样的操作,故红黑树的效率决定了map的效率。
unordered_map: unordered_map内部实现了一个哈希表,因此其元素的排列顺序是杂乱的,无序的
优缺点以及适用处
map
优点:
有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作
红黑树,内部实现一个红黑书使得map的很多操作在lgnlgn的时间复杂度下就可以实现,因此效率非常的高
缺点:
空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点,孩子节点以及红/黑性质,使得每一个节点都占用大量的空间
适用处,对于那些有顺序要求的问题,用map会更高效一些
unordered_map
优点:
因为内部实现了哈希表,因此其查找速度非常的快
缺点:
哈希表的建立比较耗费时间
适用处,对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
note:
对于unordered_map或者unordered_set容器,其遍历顺序与创建该容器时输入元素的顺序是不一定一致的,遍历是按照哈希表从前往后依次遍历的

stl的vector和list的区别,增删分别的时间复杂度

vector是顺序存储,其地址空间是连续的,对其进行插入、删除操作会引起内存的拷贝与移动。在中间插入(或删除)元素,其后面的元素都要移动,如果该快内存后面的剩余空间不足以存储插入的元素还会造成整个容器的拷贝,vector每次扩展容量时是扩展capacity的整数倍(对于小对象来说效率比较高)。如果存储的是复杂数据类型,拷贝构造函数又比较复杂的话,vector的插入和删除操作的运行代价是非常大的。另外,因为vector是顺序存储,因此支持下标访问,随机访问效率较高。

list类似于数据结构的双向链表,其地址空间是不连续的,通过指针来进行数据的访问。list的插入删除不会引起其他数据元素内存的拷贝,只是指针的变化。list支持在容器的任意位置高效的插入和删除。

new/delete和malloc/free有什么区别

1、new、delete是C++中的操作符,而malloc和free是标准库函数。

2、对于非内部数据对象来说,只使用malloc是无法完成动态对象要求的,一般在创建对象时需要调用构造函数,对象消亡时,自动的调用析构函数。而malloc
free是库函数而不是运算符,不在编译器控制范围之内,不能够自动调用构造函数和析构函数。而NEW在为对象申请分配内存空间时,可以自动调用构造函数,同时也可以完成对对象的初始化。同理,delete也可以自动调用析构函数。而mallloc只是做一件事,只是为变量分配了内存,同理,free也只是释放变量的内存。

3、new返回的是指定类型的指针,并且可以自动计算所申请内存的大小。而
malloc需要我们计算申请内存的大小,并且在返回时强行转换为实际类型的指针。

右值引用

https://www.cnblogs.com/qicosmos/p/4283455.html

多态

多态是面向对象编程的特性之一,还包含继承和封装,多态跟继承关系比较大,通常是为了实现父类指针指向子类对象,然后调用同一个方法实现不同效果的功能。




C++垃圾回收

https://www.cnblogs.com/QG-whz/p/5079638.html
1、引用计数算法
引用技术算法是唯一一种不用用到根集概念的GC算法。其基本思路是为每个对象加一个计数器,计数器记录的是所有指向该对象的引用数量。每次有一个新的引用指向这个对象时,计数器加一;反之,如果指向该对象的引用被置空或指向其它对象,则计数器减一。当计数器的值为0时,则自动删除这个对象。这个思路可以参考C++ 引用计数技术及智能指针的简单实现。
缺点二是多个线程同时对引用计数进行增减时,引用计数的值可能会产生不一致的问题,必须使用并发控制机制解决这一问题,也是一个不小的开销。
Mark & Sweep 算法
这个算法也称为标记清除算法,为McCarthy独创。它也是目前公认的最有效的GC方案。Mark&Sweep垃圾收集器由标记阶段和回收阶段组成,标记阶段标记出根节点所有可达的对节点,清除阶段释放每个未被标记的已分配块。典型地,块头部中空闲的低位中的一位用来表示这个块是否已经被标记了。通过Mark&Sweep算法动态申请内存时,先按需分配内存,当内存不足以分配时,从寄存器或者程序栈上的引用出发,遍历上述的有向可达图并作标记(标记阶段),然后再遍历一次内存空间,把所有没有标记的对象释放(清除阶段)。因此在收集垃圾时需要中断正常程序,在程序涉及内存大、对象多的时候中断过程可能有点长。当然,收集器也可以作为一个独立线程不断地定时更新可达图和回收垃圾。该算法不像引用计数可对内存进行即时回收,但是它解决了引用计数的循环引用问题,因此有的语言把引用计数算法搭配Mark & Sweep 算法构成GC机制。

3、 节点复制算法
Mark & Sweep算法的缺点是在分配大量对象时,且对象大都需要回收时,回收中断过程可能消耗很大。而节点复制算法则刚好相反,当需要回收的对象越多时,它的开销很小,而当大部分对象都不需要回收时,其开销反而很大。
算法的基本思路是这样的:从根节点开始,被引用的对象都会被复制到一个新的存储区域中,而剩下的对象则是不再被引用的,即为垃圾,留在原来的存储区域。释放内存时,直接把原来的存储区域释放掉,继续维护新的存储区域即可。过程如图:

分代回收
以上三种基本算法各有各的优缺点,也各自有许多改进的方案。通过对这三种方式的融合,出现了一些更加高级的方式。而高级GC技术中最重要的一种为分代回收。它的基本思路是这样的:程序中存在大量的这样的对象,它们被分配出来之后很快就会被释放,但如果一个对象分配后相当长的一段时间内都没有被回收,那么极有可能它的生命周期很长,尝试收集它是无用功。为了让GC变得更高效,我们应该对刚诞生不久的对象进行重点扫描,这样就可以回收大部分的垃圾。为了达到这个目的,我们需要依据对象的”年龄“进行分代,刚刚生成不久的对象划分为新生代,而存在时间长的对象划分为老生代,根据实现方式的不同,可以划分为多个代。
一种回收的实现策略可以是:首先从根开始进行一次常规扫描,扫描过程中如果遇到老生代对象则不进行递归扫描,这样可大大减少扫描次数。这个过程可使用标记清除算法或者复制收集算法。然后,把扫描后残留下来的对象划分到老生代,若是采用标记清除算法,则应该在对象上设置某个标志位标志其年龄;若是采用复制收集,则只需要把新的存储区域内对象设置为老生代就可以了。而实际的实现上,分代回收算法的方案五花八门,常常会融合几种基本算法。

计算机组成原理

c++函数调用机制

https://www.cnblogs.com/chenhuan001/p/7425507.html

cache的作用

高速缓冲存储器。它是位于CPU与内存间的一种容量较小但速度很高的存储器。CPU的速度远高于内存,当CPU直接从内存中存取数据时要等待一定时间周期,而Cache则可以保存CPU刚用过或循环使用的一部分数据,如果CPU需要再次使用该部分数据时可从Cache中直接调用,这样就避免了重复存取数据,减少了CPU的等待时间,因而提高了系统的效率。

高速缓存是最快的存储器吗?

还有主存

数据结构

什么数据结构用得比较多一点?
链表 二叉树 字符串
为什么会用它比较多?
在使用的过程中遇到了什么问题?
(这一次说了链表,但感觉字符串明明才是用得更多了而且也比较好回答下面的问题啊!

排序算法
稳定排序与不稳定排序,时间复杂度

排序算法有哪些?
最快的排序算法是哪个?
在不同情况下有不同的最快,平均是快排
手写一个冒泡排序
for(int i=0;i<len;i++)
for(int j=i;j<len;j++)
if(array[i]>array[j])swap(array[i],array[j])

手写快速排序代码

快速排序的过程、时间复杂度、空间复杂度

#include<iostream>
using namespace std;class Sort{int len;   //数组长度int *data;
public:Sort(){     //初始化cin>>len;data=new int[len+1];for(int i=1;i<=len;i++)cin>>data[i];}void QuickSort(int low, int high){      int i, j, Pivotkey;i = low;j = high;           //记录顺序表的上、下界Pivotkey = data[low];while(low <high) {             //当high>low的时候循环while((low < high) && (Pivotkey <= data[high]))high--;if(low < high)data[low++] = data[high];elsebreak;while((low < high) && (data[low]<= Pivotkey))low++;if(low < high)data[high--] = data[low];}data[low] = Pivotkey;        // low == highprint();if (i<low-1)QuickSort(i, low-1); //对子对象数组进行递归快速排序if (high+1<j)QuickSort(high+1, j);}int getLen(){return len;}void print(){int i;for(i=1;i<len;i++)cout<<data[i]<<" ";cout<<data[i]<<endl;}~Sort(){delete[] data;len=0;}
};int main(){int t;cin>>t;while(t--){Sort s;s.QuickSort(1,s.getLen());cout<<endl;}return 0;
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210309142445 16.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80Mzc1NzMzMw==,size_16,color_FFFFFF,t_70)

快排的实现

分而治之

计算机网络

TCP和UDP的区别,使用
TCP的优点: 可靠,稳定 TCP的可靠
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。

tcp/ip的五层有哪五层

解释TCP3次握手

https://www.cnblogs.com/bj-mr-li/p/11106390.html
面试回答:这个问题我是清楚的,TCP/IP是传输层面向连接的可靠协议,三次握手的机制是为了保证安全可靠的连接。第一次由客户端向服务器发送报文,这个报文的SYN位置一,代表请求建立连接,并包含seq报文表示请求服务器发送的报文序列号,服务器收到报文后会知道客户端请求建立连接,于是向客户端发送确认消息报,SYN置1表示建立连接,ACK置一,并且ack设置为第一次握手中的seq+1。
在服务器发送报文后,服务器方不知道自己的报文是否发送成功,因此此时需要第三次握手,客户端发送报文,并且ACK位置1,表示客户端已经收到服务器端的确认报文了。
在三次握手结束后,双方都知道了可以发送和接受到对方的消息,此时连接成功建立,接下来双方就可以进行数据的发送了。

四次挥手:
首先由客户端发起,表示请求断开连接,此时客户端发送请求断开连接的报文,FIN置一,当服务器端收到报文后,此时可能还没准备好断开连接,此时可能还有需要继续发送的报文。
当服务器准备好的时候,服务器向客户端发送请求断开连接的报文,FIN置1,但是服务器并不知道自己是否发送成功,于是最后还需要一次挥手,就是让客户端向服务器发送收到断开信息的报文。

操作系统

进程通信



多线程怎么通信

https://www.xuebuyuan.com/3180849.html

进程和线程的区别?
https://www.cnblogs.com/jobbible/p/9766649.html

(1)进程

进程是程序的一次执行过程,是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间,至少有 5
种基本状态,它们是:初始态,执行态,等待状态,就绪状态,终止状态。

(2)线程

线程是CPU调度和分派的基本单位,它可与同属一个进程的其他的线程共享进程所拥有的全部资源

(3)联系

线程是进程的一部分,一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

(4)区别:理解它们的差别,我从资源使用的角度出发。(所谓的资源就是计算机里的中央处理器,内存,文件,网络等等)

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。

包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

操作系统怎么管理内存的

操作系统实现锁的方法

https://blog.csdn.net/zjck1995/article/details/46491631

线程的生命周期

线程的生命周期,以及不同的阶段的区别:

新建状态(NEW)

当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存, 并初始化其成员变量的值
就绪状态(RUNNABLE)

当线程对象调用了 start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和 程序计数器,等待调度运行。
运行状态(RUNNING)

如果处于就绪状态的线程获得了 CPU,开始执行run()方法的线程执行体,则该线程处于运行状态。 阻塞状态(BLOCKED)

阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。
直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice转到运行(running)状态。 阻塞的情况分三种:
等待阻塞(o.wait->等待对列):
运行(running)的线程执行o.wait方法,JVM会把该线程放入等待队列(waitting queue)中。
同步阻塞(lock-〉锁池) 运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,
则JVM会把该线程放入锁池(lock pool)中。 其他阻塞(sleep/join)
运行(running)的线程执行Thread.sleep(long ms)或join方法,或者发出了 I/O请求时,
JVM会把该线程置为阻塞状态。 当sleep()状态超时、join()等待线程终止或者超时、或者I/O 处理完毕时,
线程重新转入可运行(runnabl e)状态。 线程死亡(DEAD)

线程会以下面三种方式结束,结束后就是死亡状态: 正常结束:run或call方法执行完成,线程正常结束。
异常结束:线程抛出一个未捕获的Exception或Error。
调用stop:直接调用该线程的stop方法来结束该线程,该方法通常容易导致死锁,不推荐使用。

栈和堆

数据结构中的堆和栈


  1. 是一种连续储存的数据结构,具有先进后出的性质。
    通常的操作有入栈(压栈),出栈和栈顶元素。想要读取栈中的某个元素,就是将其之间的所有元素出栈才能完成。

  2. 是一种非连续的树形储存数据结构,每个节点有一个值,整棵树是经过排序的。特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。常用来实现优先队列,存取随意。

堆内存与栈内存的区别


堆栈(stack):内存总是向一个方向增加或向相反方向减少,这个内存区用于存放方法或块中声明的局部变量。遇到局部变量声明时(包括调用方法中的变元变量-通C中的形参)内存增长,退出方法或块时这些变量弹出堆栈。
堆(heap):用于存储对象,对象的引用放在堆栈区,但是对象的数据区必须存放在堆中。堆是内存单元构成的一个巨大的表。New语句生成新对象时,保留的小块内存单元随时进行分配,一个内存单元块不再被现有变量引用时,这些不用的单元被释放和收集起来。

函数栈
printf函数是如何实现可变长参数的原理?

图形学

简述渲染管线过程

然后针对渲染管线的具体细节进行提问,比如某一过程的作用是什么,具体是如何实现的。
虽然有些过程都硬件化了,但是还是要清楚实现的算法


渲染管线中坐标系变换经过了哪几个坐标系



判断一个点是否在多边形内部?
https://www.pianshen.com/article/9475339846/

下面是几个比较基本的方法:
(1)面积法:将这个点与多边形的所有顶点连线,将所形成的所有三角形面和求和,如果和多边形面积相等则点在多边形内部
(2)夹角法:将这个点与多边形的所有顶点连线,如果夹角和为360°则点在多边形内部
(3)射线法:以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外,考虑沿着L从无穷远处开始自左向右移动,遇到和多边形的第一个交点的时候,进入到了多边形的内部,遇到第二个交点的时候,离开了多边形,……所以很容易看出当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。

水平/垂直交叉点数判别法(适用于任意多边形)
注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1,P2),
1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况
2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。
3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。
4)再判断相交之前,先判断P是否在边(P1,P2)的上面,如果在,则直接得出结论:P再多边形内部。

Unity

骨骼蒙皮动画
https://gameinstitute.qq.com/community/detail/127900

骨骼动画的基本原理可概括为:在骨骼控制下,通过顶点混合动态计算蒙皮网格的顶点,而骨骼的运动相对于其父骨骼,并由动画关键帧数据驱动。一个骨骼动画通常包括骨骼层次结构数据,网格(Mesh)数据,网格蒙皮数据(skin
info)和骨骼的动画(关键帧)数据。下面将具体分析。
骨骼只是一个形象的说法,实际上骨骼可理解为一个坐标空间,关节可理解为骨骼坐标空间的原点。

对象池用于减少内存开销,其原理就是把可能用到到的对象,先存在一个地方(池),要用的时候就调出来,不用就放回去。而不是要用的时候创建,不用的时候销毁。
https://blog.csdn.net/l773575310/article/details/71601460

unity3d怎样update操作?

Unity 3d 几种Update Update
Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(可以认为是三角形的数量)。在性能好的机器上可能fps
30,差的可能小些。这会导致同一个游戏在不同的机器上效果不一致,有的快有的慢。因为Update的执行间隔不一样了。

FixedUpdate
FixedUpdate是在固定的时间间隔执行,不受游戏帧率的影响。Tips:在处理Rigidbody的时候最好用FixedUpdate。

LateUpdate LateUpdate是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。

unity3D OnTriggerEnter和OnCollisionEnter区别

https://blog.csdn.net/lihao161530340/article/details/81609886

Unity GC垃圾回收

GC (garbage collection)简介
在游戏运行的时候,数据主要存储在内存中,当游戏的数据在不需要的时候,存储当前数据的内存就可以被回收以再次使用。内存垃圾是指当前废弃数据所占用的内存,垃圾回收(GC)是指将废弃的内存重新回收再次使用的过程。

Unity中将垃圾回收当作内存管理的一部分,如果游戏中废弃数据占用内存较大,则游戏的性能会受到极大影响,此时垃圾回收会成为游戏性能的一大障碍点。

Unity内存管理机制简介

Unity主要采用自动内存管理的机制,开发时在代码中不需要详细地告诉unity如何进行内存管理,unity内部自身会进行内存管理。这和使用C++开发需要随时管理内存相比,有一定的优势,当然带来的劣势就是需要随时关注内存的增长。

unity的自动内存管理可以理解为以下几个部分:

1.unity内部有两个内存管理池:堆内存和堆栈内存。堆栈内存(stack)主要用来存储较小的和短暂的数据,堆内存(heap)主要用来存储较大的和存储时间较长的数据。

2.unity中的变量只会在堆栈或者堆内存上进行内存分配,值类型变量都在堆栈上进行内存分配,其他类型的变量都在堆内存上分配。

3.只要变量处于激活状态,则其占用的内存会被标记为使用状态,则该部分的内存处于被分配的状态。

4.一旦变量不再激活,则其所占用的内存不再需要,该部分内存可以被回收到内存池中被再次使用,这样的操作就是内存回收。处于堆栈上的内存回收及其快速,处于堆上的内存并不是及时回收的,此时其对应的内存依然会被标记为使用状态。

5.垃圾回收主要是指堆上的内存分配和回收,unity中会定时对堆内存进行GC操作。

协程:

https://www.pianshen.com/article/5061180965/

  1. C#装箱作用

图形学:

速度过快/体积过小导致物理引擎检测不到碰撞,如何解决
开放性问题:

如何优化内存,实际开发过程中用过什么优化内存的方法
如果有对象要频繁创建和删除,用什么减少开销。(对象池)
对象池的大小通常如何决定

c++多态
多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

4.模版的声明和实现应该在.h还是.cpp
6.timewait是哪个时候
7.

8.这五层里有哪些协议

11.如何判定tcp报文是否发送完整


下面这些应该就是二面的内容了
手写堆排序

堆排序过程、时间复杂度及空间复杂度

写出你所知道的排序算法及时空复杂度,稳定性

二叉树给出根节点和目标节点,找出从根节点到目标节点的路径
给阿里2万多名员工按年龄排序应该选择哪个算法?
堆排序

GC算法(各种算法的优缺点以及应用场景)
这个是啥

算法题
蚁群算法与蒙特卡洛算法

子串包含问题(KMP 算法)写代码实现
一个无序,不重复数组,输出N个元素,使得N个元素的和相加为M,给出时间复杂度、空间复杂度。手写算法
万亿级别的两个URL文件A和B,如何求出A和B的差集C(提示:Bit映射->hash分组->多文件读写效率->磁盘寻址以及应用层面对寻址的优化)
百度POI中如何试下查找最近的商家功能(提示:坐标镜像+R树)。
两个不重复的数组集合中,求共同的元素。
两个不重复的数组集合中,这两个集合都是海量数据,内存中放不下,怎么求共同的元素?
一个文件中有100万个整数,由空格分开,在程序中判断用户输入的整数是否在此文件中。说出最优的方法
一张Bitmap所占内存以及内存占用的计算
2000万个整数,找出第五十大的数字?
烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢?
求1000以内的水仙花数以及40亿以内的水仙花数
5枚硬币,2正3反如何划分为两堆然后通过翻转让两堆中正面向上的硬8币和反面向上的硬币个数相同
时针走一圈,时针分针重合几次
N*N的方格纸,里面有多少个正方形
x个苹果,一天只能吃一个、两个、或者三个,问多少天可以吃完?

腾讯游戏客户端一面准备相关推荐

  1. 腾讯游戏客户端开发面试

    碎碎念----第一次腾讯游戏客户端开发面试   作为一个本科.研究生专业都跟计算机不沾边的学生,简历被通过筛选本来就应该是最好的结果了,然而自己还是抱着一点点的期望,万一自己就通过了所有面试,进入腾讯 ...

  2. 腾讯游戏客户端开发网易互娱暑期实习面经

    腾讯提前批(二面挂) 在打算笔试的下午,收到了一面电话通知,周一去腾讯上海大厦现场面试,于是提前批的笔试就没有参加(这可能有点影响) 腾讯一面 和面试官约了时间,结果到了腾讯大厦楼下没法进去,所以只能 ...

  3. 腾讯游戏客户端开发公开课面试心得

    沉浸在我是fw的忧伤之中写下这篇文章,呜呜. 笔试 8月的时候,朋友推荐我去报名腾讯游戏公开课,里面包含三个方向:策划.运营和客户端开发.我报了客户端开发,但是过了一个月之后才收到笔试通知,收到通知的 ...

  4. 2019腾讯游戏客户端面试

    第一次面试腾讯,个人感觉,每个问题都会问的比较深入,以及原理性的理解. 一面是电话面试,一个还比较年轻的面试官跟我开视频面试的,面试时间一小时.下面是一些问到的内容: 1.针对简历,问一下你之前的项目 ...

  5. 2018腾讯游戏客户端岗位暑期实习生面试

    1. 流程 网申 在线笔试 面试 offer 2. 网申和笔试 网申和在线笔试不用多说,过了在线笔试才可以进入到关键的面试环节,笔试的话倒不是很难,基础扎实就行,由选择和编程题,其中编程题3题,300 ...

  6. 腾讯游戏客户端日常实习面经

    文章目录 碎碎念 一面 二面 三面 HR面 总结 碎碎念 这是我人生第一次面试, 因为无论是以前高中和大学, 我都没有参加过什么社团, 没想到能够这么顺利. 这里非常感谢实验室的几位师兄, 顺爷卢爷朋 ...

  7. 2021 腾讯游戏客户端暑期实习 一面

    面的是魔方工作室, 面试官他们目前是在用Unreal开发一些功能提高给游戏业务使用. 然后这次面试的目的, 主要是看我和这个岗位是否契合. 下面说一下面试的内容: 首先自我介绍. 然后问项目, 比如先 ...

  8. 腾讯游戏客户端开发面经(电话面试)

    本人在3.12号接到腾讯电话面试,不幸在3.14收到拒信.现在对电话面试内容作业总结 1.首先他会问你一些跟简历上的与技术无关的东西,比如你的简历上写得自我评价(比如我写得热爱编程..要我用经历说明我 ...

  9. 网上搜刮的一些腾讯游戏客户端开发(实习)面试的考题及部分答案

    真的好多都中了....就先不整理自己遇到的了,依旧因为之前是在OneNote里面写的,所以排版很乱很乱 C/C++/C#基础: 32位情况下: Char 1个字节 short 2个字节 long 4个 ...

  10. 腾讯游戏平台下载|腾讯游戏平台使用体验

    菜鸟比较多,地图库好玩,还能ban图,简直是菜鸟乐园.但是平台开图的人好多,以前都不相信,有天有个orc上来就报我点位(TM四人图),还直接说我就是开图打怎么了.最后他赢了还要推销一波全图软件,想卖给 ...

最新文章

  1. 大厂的面试官是如何挑人的?
  2. Flask中的重定向redirect和url_for
  3. Python+selenium自动化测试中Windows窗口跳转方法
  4. 在.NET客户端程序中使用多线程
  5. 备份全网服务器数据生产架构方案案例模型
  6. 洛谷 P3368 【模板】树状数组 2
  7. Boost.Function 库示例
  8. 广西大学计算机专业研究生录取分数线,广西大学电子信息(专硕)专业考研录取分数线-研究生分数线-历年分数线...
  9. vs2017常量文本字符串无法转换成char*
  10. 检测高CPU线程定位shell脚本
  11. Ubuntu配置安装NFS服务器
  12. 天梯—打印沙漏以及剩余个数(C语言)
  13. 《HFSS电磁仿真设计从入门到精通》一1.3 HFSS工程的通用设置
  14. 字体靠右代码_html中怎么把文字往右移
  15. 促使新网站快速增加百度收录的几个不外传技巧
  16. icns文件_感染phobos家族勒索病毒文件后缀.phobos如何应对处理?
  17. OC5228 100V多功能LED恒流驱动器-高辉调光 65536:1 调光比
  18. 中国人寿财险java_中国人寿财险社会招聘笔试内容: 今天刚笔试完,蹭着记着赶紧写上来,以便大家以后参考;...
  19. 2021年全球与中国临时起搏器行业市场规模及发展前景分析
  20. 如何运用大数据搭建谷歌竞价账户?做外贸出口

热门文章

  1. Ubuntu下修改只读文件方法
  2. 求饶不经过原点的旋转轴的旋转矩阵
  3. Docker容器之间互访
  4. c语言贪吃蛇游戏视频,贪吃蛇游戏,贪吃蛇游戏视频
  5. python爬虫12306查票
  6. Windows 10 21H2正式版镜像
  7. Visual studio 2017 安装
  8. SMURF(5R)-Science封面文章使用的16S新流程(二)
  9. 阿里云香港服务器配置选择帮助文档(超详细)
  10. 解决jQuery(e).addclass(‘xxx‘)始终不生效的问题 - $(...).addclass is not a function