设为首页 收藏本站
查看: 94|回复: 0

[经验分享] 最新大厂C++面试真题合集,大厂面试百日冲刺 day9

[复制链接]
累计签到:50 天
连续签到:1 天
发表于 2025-4-1 16:00:40 | 显示全部楼层 |阅读模式
快手——游戏客户端怎么理解C++的封装继承多态

C++的封装、继承和多态是面向对象编程(OOP)的三大基石:

  • 封装:隐藏对象的具体实现细节,只暴露必要的操作接口。这有助于减少系统的复杂度和增加安全性。
  • 继承:允许创建新的类(派生类)来继承一个或多个现有类(基类)的属性和方法。继承支持代码复用和逻辑复用。
  • 多态:指派生类可以定义自己的行为,同时还能共享父类的接口。在运行时,可以根据对象的实际类型来调用相应的方法,即故一个接口,多种实现。这增加了程序的灵活性和可扩展性。

多重继承,如果不用虚继承,能用其他方式解决这个二义性问题?显示调用?

如果不使用虚继承来解决多重继承中的二义性问题,可以通过明确指定父类的作用域来显式调用特定的成员。这种方式称为作用域解析。在成员访问时,需要前缀类名和作用域解析运算符(::)来指明从哪个基类继承的成员被访问。这样可以明确地区分同名成员属于哪个基类,从而避免二义性。

动态多态,讲一下具体的动态多态

具体的动态多态在C++中通常通过虚函数(virtual functions)实现。当一个类中声明了虚函数,任何派生类都可以重写(override)这个函数来提供特定的实现。在运行时,根据对象的实际类型来决定调用哪个版本的函数,而不是在编译时。

静态多态怎么通过不同类型实现多态

静态多态在C++中主要通过函数重载和模板实现。

  • 函数重载:在同一作用域中,可以声明多个具有相同名字但是参数类型或个数不同的函数。编译器根据函数调用时传入的参数类型和个数来决定调用哪个函数。
  • 模板:使用模板(template)可以创建泛型类或函数,它们能够用任何类型工作。编译器根据传入的具体类型生成相应的代码,实现多态性。这包括函数模板和类模板。

虚函数和纯虚函数的区别?

虚函数是在基类中声明的,可以在派生类中被重写的函数。它允许派生类根据需要提供自己的实现。

纯虚函数是一种特殊的虚函数,它在基类中没有具体的实现,并且要求任何派生类必须提供该函数的实现。纯虚函数通过在函数声明的末尾加上= 0的语法来表示。

具有纯虚函数的类称为抽象类,不能直接实例化对象。

析构函数为什么一般都是虚函数

析构函数通常声明为虚函数是为了确保通过基类指针删除派生类对象时,能够正确地调用派生类的析构函数,从而实现资源的适当释放。这防止了内存泄露和资源未正确释放的问题,保证了当对象被删除时,整个对象的析构过程是从派生类到基类的正确顺序进行的。

什么情况下,基类会析构,派生类不会析构,哪种写法会造成这种情况?

当通过基类指针删除指向派生类对象的指针,而基类的析构函数不是虚函数时,会发生这种情况。因为此时运行时不会调用派生类的析构函数,只会调用基类的析构函数,导致派生类可能分配的资源没有被适当释放。

纯虚函数存在什么地方?

纯虚函数存在于抽象类中,用于定义接口规范,它在基类中没有实现(即没有函数体),但必须在派生类中被实现,除非派生类也是抽象类。纯虚函数的声明在基类中以= 0结尾,表示该函数为纯虚函数。

析构函数在什么时候调用呢?

析构函数在对象生命周期结束时被调用,以进行资源释放和清理工作。这通常发生在以下几种情况:

  • 当一个局部非静态对象的作用域结束时(例如,函数返回时)。
  • 当一个对象被delete表达式显式删除时。
  • 当一个临时对象的初始化表达式结束时。
  • 对于全局或静态对象,析构函数在main()函数执行完成后,程序退出前调用。

如果是new,超出作用域范围内,析构函数会调用吗?如果会析构,delete调用的时候还会调用吗?

如果是通过new创建的对象,当超出作用域时,析构函数不会自动调用。必须显式使用delete来删除动态分配的对象,这时才会调用析构函数。如果对象已经被delete,则其析构函数不会再次被调用,重复调用delete会导致未定义行为。

new一个类,在new的过程中,new做了哪些操作?new什么时候分配内存?

new操作符在创建类的对象时主要执行以下操作:

  • 分配内存:new首先分配足够存储对象的内存空间,通常是通过调用内存分配函数operator new进行分配。
  • 构造对象:在分配的内存空间上,new调用类的构造函数来初始化对象。

如果频繁的new和delete?new的时候从堆上面分配内存?delete的时候会将内存还回去?操作系统为什么会帮我们回收内存?

频繁地使用new和delete时:

  • new会从堆上分配内存给对象。
  • delete会将对象所占用的内存还回堆,并调用对象的析构函数。

操作系统帮助回收内存是因为它负责管理计算机的资源,包括内存。这样做可以防止内存泄漏,确保内存可以被重新分配和使用,维护系统的稳定性和性能。

STL容器?如果我比较频繁的增插数据,并且寻找索引,选用什么容器?

STL容器包括:

  • 序列容器(如std::vector,std::deque,std::list):线性存储,支持顺序访问。
  • 关联容器(如std::set,std::multiset,std::map,std::multimap):基于键值对存储,支持快速查找。
  • 无序关联容器(如std::unordered_set,std::unordered_multiset,std::unordered_map,std::unordered_multimap):基于哈希表,支持高效查找和访问。
  • 容器适配器(如std::stack,std::queue,std::priority_queue):通过某个容器提供特定的数据结构接口。

需要频繁地插入数据并且根据索引快速访问元素,应该使用std::vector。向std::vector的末尾添加数据很高效,并且它提供了通过索引快速访问元素的能力。然而,如果要频繁在非尾部位置插入或删除元素,可能要考虑使用std::list或std::deque,但这些容器不支持直接通过索引访问。如需在频繁插入的同时保持排序,则可能考虑使用std::set或std::multiset,但它们不支持直接索引访问,而是提供基于键的查找。

讲讲TCP/UDP

TCP(传输控制协议)和UDP(用户数据报协议)是两种主要的互联网传输层协议。

  • TCP提供一种面向连接的、可靠的字节流服务,当消息被TCP传送时,TCP会确保消息正确无误地到达目的地。如果出现错误,TCP会自动处理重发操作。然而,这种可靠性导致TCP比其他协议消耗更多的资源和带宽。
  • UDP是一种无连接的协议,信息在网络中以独立的包的形式进行传输,这意味着消息可能会乱序到达,也可能丢失。但是,UDP协议的开销小,工作效率较高,对于不需要可靠性,或者可由应用程序自行处理可靠性的应用来说,采用UDP是一种更好的选择。

三次握手,服务器没有收到客户端的第三次握手怎么办?

如果服务器没有收到客户端的第三次握手确认消息(ACK),它将会在一段时间后重发它的第二次握手消息(SYN-ACK)。如果经过多次重试后仍然没有收到第三次握手的确认,服务器最终会超时放弃连接。客户端如果期间已经发送了数据,由于没有建立起一个稳定的连接,数据会被丢弃。客户端如果没有收到服务器对第三次握手的确认,可能会重新尝试建立连接。

四次挥手,第二次我没有收到服务器的ACK,怎么办?

如果你在四次挥手中没有收到服务器的ACK,你的TCP层会重新发送FIN报文,并等待服务器的ACK应答。TCP有自己的重试机制,如果在一定的重试次数或时间后仍未收到应答,连接会超时关闭。

TCP的报文头有什么内容?TCP怎么保证传输的内容没有被修改?CRC?CRC是怎么做的?除了CRC还有什么检验方法?

TCP报文头包含的内容有:源端口号、目的端口号、序列号、确认号、数据偏移、保留位、控制位(如SYN、ACK、FIN等)、窗口大小、校验和、紧急指针以及选项和填充。

TCP保证内容没有被修改主要是通过校验和(Checksum)机制,而非CRC。校验和是对报文段中的所有16位字进行二进制反码求和,然后再进行一次反码操作得到的。接收方会对接收到的数据执行相同的计算过程,比较计算出的校验和与报文中的校验和是否一致,以此验证数据的完整性。

除了校验和,其他检验方法包括:循环冗余检验(CRC)、消息摘要(如MD5、SHA系列)以及更高级的错误检测和纠正代码(如汉明码)。

四次挥手,能不能三次挥手?

TCP四次挥手过程中,必须要做四次挥手来结束连接,不能只做三次。

这是因为TCP的半关闭状态设计。即,发送FIN报文的一方在发送完FIN后,就进入了FIN-WAIT-1状态,但是此时仍可以接收对方的数据。这就说明了为什么不能三次挥手结束。因为当一方发送FIN,并且对方返回ACK和FIN时,虽然这一方能确认对方不再发送数据了,但是对方并不能确认这一方不再发送数据,没有达到"四次挥手"正常断开连接的目的。因此,仍然需要四次挥手才能断开连接。

TCP怎么判断丢包?

TCP判断丢包主要依靠超时重传和冗余ACK机制。当发送的数据包超出设定的超时时间后,还没有收到ACK确认,发送方就会认为该包已丢失,进行重传。若发送方连续收到三个或以上的重复ACK,也会认为相应序列号的包已丢失,并触发快速重传机制。

HTTP和HTTPS的区别?传输协议使用什么协议,TCP?UDP?HTTPS的数据加密过程怎么做的?

HTTP和HTTPS的主要区别在于安全性。HTTP不提供数据加密,传输的内容可能被窃听或者篡改。而HTTPS提供了SSL/TLS加密层,确保了数据的安全传输。

HTTP和HTTPS都使用TCP协议进行传输,不使用UDP协议,因为TCP提供了可靠的、面向连接的数据传输服务。

HTTPS的数据加密过程涉及对称加密和非对称加密的结合使用。首先,通过非对称加密协商生成一个会话密钥,接下来的通信都使用这个对称会话密钥进行加密,确保了数据的机密性和完整性。

讲讲帧同步和状态同步的概念

帧同步是指在游戏或应用中,所有客户端在同一时间内都执行相同的“帧”操作,通过发送用户的输入而不是游戏状态来保持所有玩家的游戏状态同步。

状态同步则指直接同步所有玩家的游戏状态,如玩家位置、分数等信息,通常需要更频繁地数据传输,以确保所有玩家看到的游戏世界状态一致。

一场游戏里面有十个敌人,这个场景可以用状态同步做吗?怎么做呢?AOI的常用的实现方式?

AOI的常用实现方式主要有以下几种:

  • 格子法(Grid-Based):将整个游戏场景划分为多个格子,每个格子存储当前该格子内的角色,角色移动或者做出行为时,只对相邻格子的角色进行消息通知和状态更新。
  • 九宫格法:也是格子法的一种,将每个格子的周围8个格子以及自己称为九宫格,只向九宫格内的角色发送消息。
  • 四叉树/八叉树(Quad/Octree):将空间按四叉树(二维)或八叉树(三维)进行划分,每个节点包含当前区域内的对象,更适合处理不均匀分布的场景。

我的游戏由某个客户端组转发数据,那么是什么同步?

客户端主导的同步或P2P(Peer-to-Peer)同步

帧同步分为锁帧同步和什么?

帧同步分为锁帧同步和非锁帧同步。

寻路算法?

常用的寻路算法有:

  • A*(A星算法)
  • Dijkstra算法
  • 广度优先搜索(BFS)
  • 深度优先搜索(DFS)
  • 贪婪最佳优先搜索(Greedy Best-First Search)
  • 跳点搜索(JPS,Jump Point Search)



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-1005706-1-1.html 上篇帖子: 最新大厂C++面试真题合集,大厂面试百日冲刺 day8 下篇帖子: C++的两个派系之争
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表