目录
小米:
C++:
大疆:
C++:
计算机网络:
项目:
代码:
项目:
开放性问题:
计网:
猿辅导:
项目:
算法:
对象模型:
C++:
操作系统:
数据库:
计网:
BIGO
项目:
C++:
计网:
操作系统:
设计模式:
阿里
C++:
操作系统:
计网:
算法:
浅拷贝思想?
指针所有权的转移。。bulabula
引申到拷贝构造函数、移动构造函数?移动构造函数如何实现?为什么要有移动构造?
初始化 person p1=p2;调用了哪个函数?
拷贝构造函数,而非赋值运算符函数
赋值运算符函数可以通过哪些方式实现?
重载 operator= 函数,面试官说还可以用友元函数
说一下你对友元的理解,是否破坏了类的封装特性?
友元函数、友元类。哪些函数、成员函数或类为友元是由类定义的,而不能从外部强加友情。因此,尽管友元被授予从外部访问类的私有部分的权限,但他们不与面向对象的编程思想相悖,而是提高了公有接口的灵活性。
智能指针说一下?
问了太多次了,背的很熟
避免多个路径下的继承有同一个子对象的多个版本靠什么实现?
虚拟继承,virtual 关键字
继承体系中的类的析构函数为什么是虚函数?
只问了C++,半个小时搞定。。。问我熟悉算法和数据结构吗,说还行,面试官说那这一面就不让你写题了,还提到 MIUI 体统优化这个岗位 基本都是用的 java Linux 开发环境,可能得自学 java 的知识。
一面
* 模板为什么要放在头文件里?
当你不使用这个模版函数或模版类,编译器并不实例化它 ,当你使用时,编译器需要实例化它, 因为编译器是一次只能处理一个编译单元, 也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义 . 所以都放在头文件中 这不同于普通的函数, 在使用普通的函数时,编译时只需看到该函数的声明即可编译, 而在链接时由链接器来确定该函数。
其实模板实现不能放在cpp文件中,主要就是CPP在c++编译期间不能决定模板参数的类型,所以不能生成模板函数的实例,所以他会把模板类型带到链接期间,如果这个期间有函数调用了该实例,这个时候由于没有把模板实例到特定类型,就会导致编译错误。
C++从代码到可执行目标文件经历过哪些阶段?
类定义会生成哪些默认成员函数? 不会
纯虚函数与虚函数的区别?
类对象禁止复制与赋值如何实现?
从三层到二层的通信是怎么实现的?
浏览器报错后如何定位通信链路中的问题节点?
如何实现把建立的连接分配到各个线程中去?
为什么要有多个epoll?
快排思想?算法复杂度?最坏最好情况?改进方法?
二面不问基础,只问项目相关和开放性问题:
简单说一下 Reactor 模式?为什么能实现高并发量?测试时如何选择并发量测试参数?
核心思想是实现一个 while(true) 时间循环,每次循环调用 epoll 并处理发生的事件,然后处理任务队列。
如何做的性能测试?
ping pong测试协议 ,没细问。
线程池是调用的第三方库还是,如何实现的?线程个数如何确定?
自己实现,线程个数由服务器物理核心数确定。
要在项目中实现一个日志,有以下四个需求,怎么实现,实现的时候要考虑哪些问题?
多线程日志提到利用线程ID做哈希运算后放在不同的桶里,追问:
这个哈希表中用什么数据结构实现存取日志?做本地持久化时如何取出日志信息?
服务器端给客户端发视频信息流,客户端有一定的解码性能,带宽等条件限制的条件下,如何保证客户端收到尽可能多的信息?(质量最好的视频?)
说了可伸缩视频编解码的思想。
上面情景问题的延伸,唯一一个可能与基础相关的问题,如何在传输的时候保证客户端控制接收流量?
TCP层的流量控制
TCP 流量控制的实现机制?
如何实现将主线程建立的连接注册到线程池中的子线程的?
epoll 与 select 的区别?
一个链表和一个正整数n,实现将小于这个数的值放在链表前半部分,大于这个数的值放在后半部分,不能申请额外空间,不能使用 swap 操作?
如何利用以上算法实现链表的快排算法?
为什么要有虚拟继承?
虚拟继承的类在内存中的分布? 提到了虚表指针,他说不用说了。。
虚拟继承中虚拟父类在内存中的位置时怎么确定的? 虚表指针下面有4个字节存放偏移量。
提到了运行时类型判别,具体问的啥忘了? 回答说虚函数表的-1位置有 type_info,被质疑说,这个特性在有的编译器里就没有提供所以不可靠,而且普遍的做法也不是用这个来检查。。。尬住
右值引用的实现思想与目的?
右值引用相比左值引用体现出来的优化性是编译器层面实现的还是。。。(忘了)实现的?回答“编译器吧”,说是不对。。
说一下虚拟内存机制?
每个程序不用全部载入内存运行是靠什么机制? 回答分页,通过查询页表,,bulabula,,页面置换
只靠分页机制就可以了么?还有什么? 分段。。
为什么要有分段?怎么实现的?
了解事务吗?有什么特性、这些特性是靠什么机制实现的?
说是加锁,被否定。。undo_log redo_log
说一下网络模型分层,每层有什么作用? 说的贼不好
网络层有哪些协议? 真的忘了
有哪些 shell 命令用到了网络层协议?回答 ping
ping 的 TTL 是怎么得到的? TTL 为报文生存时间,表示报文在网络中的最大转发次数。数据包每经过一次转发,则 TTL值减一,直到减到零时丢弃数据包(可能出现了不可达或者路径中有环路的情况)。一般来说,TTL的初始值减去接收端得到的值表示了数据包在网络中被转发的次数,差越小代表路由效率越高。
epoll 初始化一个监听文件描述符时,默认关注哪些事件?
事件初始化时 关注 EPOLLRDHUP 事件,表示对端断开连接,对于监听描述符关注可读事件,对于 conn FD 构造时就关注了可读事件,如果发送数据没能一次性写入内核或内核缓冲区已满,则手动设置继续关注可写事件。
具体对于一个 socket 文件描述符,什么情况下是可读的?什么情况下是可写的?
可读即消息到来,可写即内核缓冲区不为full,可以往内核中这个文件描述符写数据。(内核缓冲区受TCP流量控制影响,如果窗口字段为0,则不能发送数据,导致内核缓冲区已满)写数据是主动操作,由用户主动调用,在写操作因为某些原因不能实现时,才会设置关注可写事件,以提醒用户关注这个文件描述符,在下次返回可写时继续写。
shared_ptr 与 weak_ptr 指向同一个对象,如果 shared_ptr 过期,已经及指向的对象已经析构,weak_ptr 如何处理?
weak_ptr 通过 expired() 来判断所管理的资源是否被释放,会返回一个 bool 值,访问时可以通过 lock() 方法将 weak_ptr 提升为 shared_ptr,将该弱指针提升为强指针,若提升成功,指针不为空,否则为空,说明对象已经析构。
LRU算法应通过什么数据结构实现?
map 和 双向链表 其中 map 保存要查询的序号或者查询 key 值,以实现O(1)的查询效率,双向链表(可直接访问尾节点)保存各个页面,每次将访问的页面排在链表头部,缺页中断时选择链表尾部的节点进行淘汰。
大端字节序与小端字节序?
举例来说,数值0x2211
使用两个字节储存:高位字节是0x22
,低位字节是0x11
。
- 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
- 小端字节序:低位字节在前,高位字节在后,即以
0x1122
形式储存。
Nagle算法?
Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块,减少了广域网的小分组数目,从而减小网络拥塞的出现;Nagle的算法通常会在TCP程序里添加两行代码,在未确认数据发送的时候让发送器把数据送到缓存里。任何数据随后继续直到得到明显的数据确认或者直到攒到了一定数量的数据了再发包。
该算法要求一个tcp连接上最多只能有一个未被确认的未完成的小分组,在该分组ack到达之前不能发送其他的小分组,tcp需要收集这些少量的分组,并在ack到来时以一个分组的方式发送出去。
TCP 连接出现大量的 time_wait 状态如何处理?
tcp_tw_reuse tcp_tw_recyle
TCP 连接如果突然中断,重连后会如何处理?
网络编程中 listen 的参数?
int listen(int sockfd,int backlog)
- sockfd:是bind后的文件描述符
- backlog:设置请求排队的最大长度。当有多个客户端程序和服务端相连时, 使用这个表示可以设置的排队长度。
项目中,此处使用 somaxconn ,定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为1024。
TCP 中的 RST?
RST表示复位,用来关闭异常的连接。
发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),发送端直接丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。
TCP处理程序会在自己认为的异常时刻发送RST包。例如:
- A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。
- AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了,A通过若干原因放弃了这个连接(例如进程重启)。网通了后,B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的,就发了个RST包强制把连接关了,B收到后会出现connect reset by peer错误。
TCP通信过程中异常情况整理:https://blog.csdn.net/yyc1023/article/details/80242815
父进程 fork() 后,与子进程在内存中的分布是怎样的?
写时复制 读时共享
单例模式具体怎么实现的?
操作系统:
MMU:内存管理单元,实现了将虚拟地址映射为物理地址。
快表:为计算机设置一个小型的硬件设备,将虚拟地址直接映射到物理地址,而不必再访问页表。通常在 MMU 中,包含少量的表项(大多数程序总是对少量的页面进行多次的访问)
为什么快?一条指令要把一个数据复制到另一个数据,由于牵扯两个变量物理地址的访问,就会读取两次页表。由于执行速度通常被 CPU 从内存中取指令和数据的速度所限制,所以两次访问内存才能实现一次内存访问性能底下。
构造函数和析构函数可以是虚函数吗?
构造函数不可以,析构函数可以。虚函数在派生类和基类中需要函数名字和参数表都相同,但是这里的虚析构函数显然在每个类中是不一样的,可能是析构函数比较特殊吧。另外构造函数不可以是虚函数,为什么呢,因为类的虚函数表指针是在构造函数中初始化的,这时候如果构造函数本身是虚函数,又应该由谁来初始化它的虚函数指针呢,所以构造函数不能是虚函数。构造函数和析构函数中也不能调用虚函数,调用了也没用,一个是虚函数表指针还没有初始化好,一个是可能虚函数指针已经被析构了。
stack 和 queue 区别?
先进先出、先进后出 queue 和 stack 都是基于 deque 实现
进程与线程的区别?
线程间通信的几种方式?
互斥量,信号量,条件变量。
造成死锁的必要条件?
互占剥环
Linux 下如何查看一个进程的当前堆栈转态?
虚拟内存机制?
TCP 和 UDP 的区别?
TCP 快重传 和 快恢复?
二分查找、无序数组找 topK (不用堆排,改造快排)