面试总结

网易互娱视频一面


1.重载与重写的区别
答:重载指在同一作用域,多个函数拥有相同的函数名,但参数个数/参数类型/参数顺序不同,编译器会根据函数名和参数内容匹配所需的函数。
重写是指在不同作用域,即基类和派生类中,两个函数完全相同,将基类中的函数声明成虚函数,则实现了函数的重写。通过基类的指针或引用指向派生类的对象,则调用的是重写的函数。

2.构造函数中调用虚函数,调用的是父类的函数还是子类的函数?
答:如果是在父类的构造函数中,调用虚函数,调用的肯定是父类自己的虚函数。如果是子类的构造函数,会先调用父类的构造函数,调用自己的虚函数。

3.析构函数声明为虚函数的作用
答:将析构函数声明为虚函数是为了当有基类的指针指向派生类的对象时,这个指针离开作用域,调用的是派生类的析构函数而不是基类的析构函数,防止无法析构掉派生类对象出现内存泄漏。

4.智能指针的原理?shared_ptr的引用计数原理?
答:智能指针其实是一个类,在类的构造函数中传递进去一个普通指针,在析构函数中将这个指针指向的内存释放。因为智能指针都是是栈上的对象,当它离开作用域后,将自动调用析构函数释放内存,能有效的防止因为忘记delete/free造成的内存泄漏。常用的智能指针有auto_ptr,shared_ptr,unique_ptr,weak_ptr。
share_ptr采用引用计数的原理,当调用构造函数,拷贝构造函数,赋值函数时,引用计数加一。当一个对象离开作用域时,引用计数减一。当引用计数为0时,将调用析构函数,释放掉指针指向的内存。

5.阻塞与非阻塞的区别?
答:阻塞是指,函数调用结果返回之前,当前线程将被挂起,函数只有在得到结果后才会返回。非阻塞是指若不能立即得到调用结果,函数不会阻塞当前线程,立即返回。

6.io多路复用中select/poll 与epoll的区别?
当时没有关注这一点,答的很乱整理一下

7.堆的数据结构,如何实现插入与删除?
堆也被称为优先队列,可以实现在堆底插入元素,在堆顶删除元素,但堆中的顺序不是按照先来后到,而是按照一定的优先顺序。堆可以看成用数组实现的二叉树,分为最大堆和最小堆。最大堆是指,堆中每个节点的值都比它的左子节点和右子节点大,所以最大堆堆顶元素为其最大值,最小堆与之完全相反。
堆的插入,首先将新的元素插入数组尾部,如果使得其它的节点不满足堆的特性(此节点比起父节点值大/小),将此节点与其父节点进行交换,在递归调整其他节点直到每一个父节点都比其子节点大/小。
堆删除根节点,当根节点被删除后,将数组最后一个元素与树顶元素进行交换,然后再修复堆属性(排除数组最后一个元素)。
堆删除任意节点,找到要删除的节点,让其与数组最后一个元素进行交换,然后再修复堆属性(排除数组最后一个元素)。
堆的插入与删除平均时间复杂度为o(logn),查找时间复杂度为o(n);

8.常用的STL容器及区别?
STL容器分为序列式容器与关联式容器,序列式容器有array,vector,list,deque。关联式容器有map,set,multimap,multiset,unordered_map,unordered_set,适配器stack,queue
array是数组,它是一段静态连续空间,查询时间复杂度为o(1),不允许插入和删除。
vector是动态数组,它是一段动态连续空间,查询时间复杂度为o(1),允许插入和删除元素,在末尾插入的时间复杂度为o(1),头部删除的时间复杂度为o(1),中间插入删除的平均时间复杂度为o(n)。当vector空间不足时会执行重新开辟内存,拷贝,删除操作。
list链表,它是一个动态非连续空间,插入和删除的时间复杂度为o(1),但查询的时间复杂度为o(n)。
deque双端队列,它是一段动态分段非连续空间,扩展空间不需要像vector一样拷贝元素,从头尾插入和删除的时间复杂度为o(1),底层结构是一个小块连续空间,其中每个元素都是指针指向另一端较大的连续线性空间。
stack栈,它是一端动态连续空间,只能从栈顶top插入和删除元素
queue队列,它是一组动态连续空间,只能从队列前端front删除元素,对尾back插入元素时间复杂度为o(1)
map图,拥有键值key与实值value,它的底层结构是红黑树,查询与插入删除时间复杂度为o(logn)
set集合,只拥有键值key,其他同上
unordered_map,无序图,底层结构为hash表,查询时间为o(1)

9.hash表的冲突解决方法
开放定址法:从发生冲突的的单元起,按照一定的次序,从hash表中找到一个空闲的地址,然后把发生冲突的元素放在这个单元。有线性探测,平方探测等。
拉链法:将hash值相同的元素构成一个同义词的单链表,并将单链表的头指针存放在hash表的第i个单元中。
再hash法:构造多个hash函数,当第一个hash值发生冲突,计算第二个hash值,直到不发生冲突。
建立公共溢出区:将hash表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放在溢出区。

10.map和unorder_map的区别?
它们俩都是key-value结构,可以通过key值快速索引到value,map会对key值进行排序,unorder_map不会进行排序;map的底层结构是红黑树,能实现o(logn)的查询,插入删除,unorder_map的底层是hash表,插入删除和查询的时间复杂度为o(1)。

11.堆和栈的区别?
堆是操作系统所维护的一块特殊内存,用于存放动态申请的内存;栈是由操作系统自动分配释放,用于存放局部变量,函数参数等的一块内存。主要区别有
管理方式不同,堆由程序员手动申请与释放,栈由操作系统自动申请和释放,无需手动操作。
可分配空间大小不同,堆理论上可分配虚拟空间大小,栈的大小远远小于堆的大小。
生成方向不同,栈向低地址生长,堆向高地址生长。
分配效率不同,栈由操作系统自动申请释放,会在硬件层对栈进行支持,因此效率比较高。堆的申请和释放比较复杂,频繁的申请释放会产生内存碎片。

12虚拟地址如何转换为物理地址?
不会

13.osi七层模型和tcp/ip四层模型?tcp协议在哪一层,ip协议在哪一层?
七层模型分别为应用层,会话层,表示层,传输层,网络层,数据链路层,物理层;四层模型为应用层,传输层,网络层,网络接口层。tcp协议位于传输层,ip协议位于网络层。

14.socket网络编程有哪些API?
服务端:建立套接字socket,绑定地址与端口bind,监听listen,接收accept;客户端建立套接字socket,连接connect;通用读写read/write,recv/send。

15线程与进程的区别?
进程是系统资源分配的基本单位,线程是cpu调度的基本单位。一个线程只能属于一个进程,而一个进程可以有多个线程。操作系统会为每一个进程分配4G的虚拟地址空间,而同一个进程中的线程共享进程的空间,但拥有自己独立的栈空间和计数器。进程之间相互隔离,一个进程出问题不影响另一个进程,而进程中的一个线程出问题将导致整个进程挂掉。

16手撕代码
双向链表按“节点值->”打印每个节点。
双向链表转置
更定一个值m,交换链表前m个节点和后续节点的顺序

360服务端C++工程师视频面试


1.线程与进程的区别?

2.线程间的同步方式?互斥量与临界区的区别?解释下什么是事件?
线程间的同步方式有:临界区,互斥量,信号量,事件。
临界区:保证在某一时刻只有一个线程能够访问资源的简单方法。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问临界区,那么在有一个线程进入后其他线程将被挂起,并一直持续到进入临界区的线程离开。临界区在释放后,其他资源可以继续抢占。以此来达到操作的原子性
互斥量:与临界区类似,只有拥有互斥量对象的线程才具有访问资源的权限,因为互斥对象只有一个,所以任何情况下共享资源都不会被多个线程访问。当占据资源的线程处理完后,将互斥对象交出,其他线程获得互斥对象后才能继续访问资源。
区别互斥量不仅仅能在同一进程的不同线程下实现资源的安全共享,也能够在不同进程间的线程之间实现对资源的安全共享。
信号量:允许多个线程同时访问资源,能指出最大访问资源的线程数目。
事件:事件可以处于激发状态和未激发状态,通过通知操作保持线程同步,如一个线程会等待事件变为激发状态再执行,执行完事件会自动变为未激发状态,并通知其他线程的事件变为激发状态。

3.TCP和UDP的区别?何时使用TCP,何时使用UDP?
TCP叫做传输控制协议,是一种面向连接的可靠协议,UDP叫做用户数据报协议,是一种无连接的不可靠协议。
面向连接是指TCP在传输前会通过三次握手建立连接,断开时会通过四次挥手关闭连接。而UDP没有以上操作。
可靠是指TCP在传输信息时,会通过一系列的措施来保证信息一定传递到目的地,这些措施包括校验和,序列号,超时重传,连接管理,流量控制,拥塞控制等,而UDP不会有这些措施,也并不保证一定能把信息传输到目的地
TCP是面向字节流的,它把数据看成一连串无结构的字节流,可以进行分段传输。UDP是面向数据报的,对应用层传来的报文,即不合并也不拆分,直接传输。
TCP应用于效率要求较低,但准确性要求较高的场景,如文件传输。
UDP应用于效率要求较高,但准确性要求较低的场景,如QQ视频,视频直播。

4.四次挥手的几个状态?
客户端关闭连接发送FIN报文,序列号seq=M,进入FIN_WAIT1;服务端收到报文回发ACK,ack=M+1,进入CLOSE_WAIT;客户端收到ACK报文进入FIN_WAIT2;服务端发出FIN报文,序列号seq=N,进入LAST_ACK;客户端收到报文,回送ACK,ack=N+1,进入TIME_WAIT,等待2MSL后进入CLOSED;服务端收到ACK报文,进入CLOSED状态

5.TIME_WAIT为什么要设置为2MSL?
设置为2倍的最长报文生成时间有两点:1.经过2MSL时间,传输通道中所有残余的报文都将失效,防止新的连接接收到残余的数据包,造成错误;2.为了保证被关闭方能接收到关闭方的确认应答,如果确认应答在传输过程中丢失,被关闭方会重新发送关闭请求,若此时没有等待时间,关闭方已经关闭连接,会造成被动方一直超时重传永远无法关闭。

6.虚函数virtual的三种用法?
1.将析构函数声明为virtual;2.将类的成员函数声明为virtual;3.菱形继承中的虚继承

7.手撕单例模式
不会

8链表是否有环?推导快慢指针相遇位置
判断是否有环,可以采用快慢指针,快指针每次走两步,慢指针每次走一步,若两指针相遇则有环。
设链表头节点到环入口节点的距离为a,相遇点距环入口节点为x,慢指针走了s步,链表长为L
所以有2s=s+nr,n表示环内转圈数,即s=nr;有a+x=s推出a+x=nr=(n-1)r+r=(n-1)r+L-a,推出a=(n-1)r+L-a-x,其中L-a-x表示相遇点距离环入口点的距离。因为(n-1)r表示在环内循环,从哪出发会回到哪,所以相遇点距离环入口点的距离与头节点到环入口点的距离。

9.多线程与多进程的区别?
多进程的数据共享复杂,需要使用进程间的通信IPC,数据是分开的,数据的同步很简单;多线程因为共享进程数据,所以数据共享简单,但导致数据的同步复杂;
多进程占用内存多,切换复杂,cpu利用率低;多线程占用内存少,切换简单,cpu利用率高;
多进程编程简单调试也简单;多线程编程复杂度,调试复杂;
多进程,进程互不影响;多线程一个线程挂掉导致整个进程挂掉;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值