CVTE面试题汇总
一.
C++基础
1)多态、虚函数相关
C++多态的实现机制
静态多态:重载函数 编译器根据函数名、参数类型以及个数来判断重载函数
动态多态:可以用基类指针指向派生类对象,执行虚函数时根据动态类型确定调用哪一个函数。虚函数表 在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据所指对象的实际类型来 调用相应的函数,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数
虚函数表
虚函数表类似一个指针数组,虚函数表存储虚函数的地址,即虚函数表的元素是指向类成员函数的指针 如果派生类没有重写函数,那么派生类的虚指针指向基类的虚函数表 否则建立一张连续地址的新表
虚函数表在哪里建立的?
栈还是堆 虚函数表不在堆或者栈,而是存放在只读数据段,即常量区
虚函数表内部结构是什么
内部是相应虚函数的地址
2)引用和指针的区别:
引用是对象的别名,不占内存空间,指针占空间 引用声明时必须初始化并且不能改变所指向的对象,指针可以后来初始化并且可以改变所指向的对象 引用和指针的使用场景: 引用常作为函数的参数以及返回类型,因指针有可能为空,但引用一定存在对象
3)shared_prt相关,是线程安全的吗?可以指向数组吗?
是智能指针,其本身的引用计数是线程安全的,但是多个线程对所指对象进行读写需要加锁。 肯定可以指向数组,需要自己定义删除器,可用lambda 访问需要用get成员函数进行指针操作,没有重载下标运算符
4)static的作用:
1、用于对其他文件进行“隐藏”的作用,被声明为static的变量或函数只会执行内部链接,导出符号表没有static的变量或函数 2、如果实在函数内进行声明,能使变量常驻内存并且默认初始化为0,存放于全局数据区 3、修饰成员,能够使类的所有对象共享一个实例,不影响类的大小,可以用域运算符进行访问
5)编译相关
C/C++ 文件到可执行文件: 预处理、编译、汇编、链接
1、预处理:进行宏定义、头文件的替换、处理条件预编译
2、编译:1.词法分析 2.语法分析 3.语义分析 (优化)4.产生相应的汇编代码文件
3、汇编:将汇编代码文件翻译为机器语言、填充符号表,包含未解决符号表、导出符号表、地址重定向表
4、链接:对地址进行重定向,根据未解决符号表,遍历其他导出符号表对相应的符号表填充地址(连接),然后生成可执行文件
6)malloc内存分配原理:
申请的内存小于128K: 调用brk(),虚拟内存的_edata指针向前推进,此时没有实际分配物理内存,当对此内存写入数据时,产生缺页中断,系统正式为其分配物理内存
大于128K: 调用mmap(),在文件映射区(未初始化区)分配虚拟内存,可以单独释放
7)std::move函数
std::move,可以避免不必要的拷贝操作。std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝。 是一个函数模板,通过传入T&& 利用引用折叠维持传入参数的左值/右值属性,然后调用remove_reference模板类,获取原本的类型,然后通过强制转换static_cast返回右值类型
template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_cast<typename remove_reference<T>::type&&>(t);
}
8)const、static关键字,分别存放在哪里
const 修饰的量确切说叫只读量,不是常量。
const volatile修饰的变量可以通过指针修改变量
const 修饰指针分为顶层与底层
const 修饰返回类型时,返回的值不能作为左值
const 修饰成员函数,不能与static一并使用
可能在栈区,可能在全局区,看作用域以及有没有static修饰了,如果没有对其取地址的话,也可能被编译器优化为字面常量。
static变量在全局数据区
**9)shareed_ptr已经这么成熟了,为什么还用weak_ptr ** 提醒 -> 循环引用 weak_ptr可以解决shared_ptr循环引用问题,导致内存泄漏问题 shared_ptrA指向的class A中有shared_ptr指向class B shared_ptrB指向的class B中有shared_ptr指向class A 那么离开作用域的时候,因为类中有shared_ptr互相指向,导致引用计数不为0,不会自动析构A与B,造成内存泄漏 而如果类中使用weak_ptr则不会导致引用计数不为0,避免了内存泄漏
二.
1、单例设计模式实现;
2、程间通信:
3、读写锁,一个正在读的过程中,另一个线程写怎么办;
4、智能指针的实现、智能指针的使用;
5、进程使用过没有;
6、子类有几个虚函数表,虚函数的实现;
7、UDP、TCP的连接;
8、UDP怎么发数据给局域网指定设备,只知道有这个设备的情况(ARP?);
9、内存泄漏有几种情况;
10、申请了10个字节,但是需要访问第20个字节这种情况怎么处理;
11、map的使用;
12、路由器与交换机的区别,
三.
C++
1、C++11特性有哪些
2、C++智能指针,底层实现
3、C++多态说一下
4、一个空类多少字节?加一个函数呢?加一个虚函数呢?
5、构造函数可以调用虚函数吗
6、析构函数可以是虚函数吗,不是虚函数会怎么样?
7、final关键字的作用
8、重载函数如何实现
Qt
1、讲一下元对象QObject
2、connect()包含哪些参数
3、有几种connect方式
计网
1、TCP如何保证可靠
2、TCP粘包问题和解决办法
2、ARP协议
3、讲一下keepalive
OS
1、进程通信的方式
2、共享内存实现原理
3、互斥锁底层实现
4、IO同步,IO异步
答案整理
C++
1、C++11特性有哪些
1)关键字:auto 关键字、nullptr代替NULL、for循环语法
2)array、forward_list、unordered_map、unordered_set
- thread、atomic、condition_var
4)新智能指针unique_ptr、share_ptr、weak_ptr
5)function、bind、lambda
2、C++智能指针,底层实现
- auto_ptr——自动回收内存资源
2)unique_ptr——限制一个指针指向一个内存
3)share_ptr——实现多个指针指向一个内存
4)weak_ptr——解决share_ptr循环引用的死锁问题
3、C++多态说一下
静态多态——函数模板和函数重载
动态多态——子类代码重写,基类指针指向不同子类相同函数实现不同的动作
4、一个空类多少字节?加一个函数呢?加一个虚函数呢?
空类占1字节,加一个函数还是1字节,加一个虚函数变为4字节
5、构造函数可以调用虚函数吗
可以
1)因为创建一个对象时需要确定对象的类型,而虚函数是在运行时确定其类型的。而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等等
2)虚函数的调用需要虚函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数即构造函数了
6、析构函数可以是虚函数吗,不是虚函数会怎么样?
/*析构函数可以是虚函数
类作为基类时析构函数必须为虚函数,否则会造成内存泄漏
类不被继承时析构函数不必设为虚函数,因为虚函数会消耗一定的内存资源*/
首先析构函数可以为虚函数,当析构一个指向派生类的基类指针时,最好将基类的析构函数声明为虚函数,否则可以存在内存泄露的问题。
如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除指向派生类的基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。
7、final关键字的作用
修饰类,表示该类不允许继承
修饰虚函数,表示该虚函数不允许重写
8、重载函数如何实现
重载函数表示,函数具有相同的函数名,参数不同
编译阶段,编译器根据参数的不同将相同函数名的函数编译成不同的函数名
运行阶段,就可以根据不同的函数名对重载函数进行调用
Qt
1、 讲一下元对象QObject
Qt中绝大多数的对象都是基于Qobject实现的
Meta Object Compiler元对象编译器,实现了元对象机制,增加了C++新特性 信号槽机制、复杂的定时器、层次化的对象树、智能指针等…
2、 connect()包含哪些参数
自定义对象/系统对象,信号函数,自定义对象/系统对象,槽函数,连接类型
3、 有几种connect类型
1)Qt::Autoconnection——自动解析连接类型
2)Qt::DirectConnection——发送者与接收者在同一个线程
3)Qt::QueuedConnection——发送者与接收者在同一个线程
4)Qt::BlockingQueuedConnection——发送者发送信号后进入阻塞状态,直到槽函数运行完
5)Qt::UniqueConnection——避免重复连接
计网
1、 TCP如何保证可靠 拥塞控制——保证网络不瘫痪——慢开始,拥塞避免,拥塞调整,快重传
流量控制——保证客户端与服务器的收发信息同步
确认机制——保证发出去的数据被完整地接收,通过序号化数据实现
超时重传——连续三次收到丢包,重传数据
验证和——对数据二进制求和取反,保证数据的完整性
2、 TCP粘包问题和解决办法
粘包原因
1)TCP协议基于流式传输,在缓存区会有多个TCP包
2)发送端等待缓存区满才发送数据
3)接收端等待缓存区满才读数据
4)TCP协议会将几个较小的包合并成一个进行发送
解决办法
1)发送定长包
2)包与包之间加边界符
3)给每个包指明长度
4)使用更复杂的应用层协议
3、 ARP协议
本地网络寻址:将主机B名转IP,在缓存找有没有对应的MAC,无则通过主机A的子网掩码判断是否属于同个子网,是则进行广播,主机B收到ARP广播对比自己的MAC,相同进行回应,主机A将主机B的MAC写入缓存,进行数据链路层的封装,发送数据。
非本地网络寻址:将主机B名转IP,在缓存找有没有对应的MAC,无则通过主机A的子网掩码判断是否属于同个子网,否则将数据包发送给自己的缺省网关,跳转到下一个路由器,路由器通过路由表决定将数据包从哪个接口发送。
4、 讲一下keepalive
TCP的keepalive意图保存客户端和服务器的连接,一方会不定期发送心跳包给另一方,当一方断开连接,没断开连接定时发送几次心跳包,如何连续收到断开方的RST,而不是ACK则断开连接。如果TCP没有keepalive机制,自动断开,没断开的会一直以为当前连接是存活的,这对服务器的连接资源影响会很大。 HTTP的keep-alive意图在短时间内连接复用,希望可以短时间内同一个连接上进行多次请求与响应。当客户端与服务器连接上后,传输完一次数据不会马上断开连接,而是让后面传输数据依旧走这一条TCP连接。
OS
1、 进程通信的方式
管道、信号量、信号、共享内存、消息队列、套接字
2、 共享内存实现原理
两个进程的地址空间为同一个物理空间,两个进程可以同时对内存进行读写访问。但由于共享内存本身未实现同步机制,需要自己配合信号量使用。
1)Ipcs -m 查看系统中的共享存储区
2)Ipcre -m[shmid] 删除系统中的共享存储段
3)int shmget(key_t key,size_t size,int shmflg) 创建共享内存 Key为IPC资源表示,size为申请共享内存的大小,shmflg创建模式
4)void *shmat(int shmid,const void *shmaddr,int shmflg) 挂接共享内存 Shmid为共享内存标识符,shmaddr为指定共享内存地址,shmflg读写挂接
5)Int shmdt(const void *shmaddr)去关联共享内存 Shmaddr为共享内存地址
6)Int Shmctl(int shmid,int cmd, struct shmid_ds *buf)销毁共享内存 Shmid为共享内存标识,cmd设为IPC_RMID可以删除共享内存,buf置NULL
3、互斥锁底层实现
通过一个标志位,进行原子分配,用时置0,释放置1
4、 linux的IO模式,同步异步的区别,阻塞与非阻塞的区别
阻塞IO:等待数据准备完毕,不干别的事就等待
非阻塞IO:等待数据准备完毕前 会返回进程干别的事
多路复用IO:内核通过select/epoll/poll 检测是否有准备好的数据 有则唤醒进程
信号驱动IO:进程通过sigaction注册信号函数,数据准备好内核发送信号
异步IO:进程通过aio_read,实现内核准备好数据并完成复制后再告诉进程
四.
1.static关键字
2.STL中map和unordered_ map的底层实现
3.重载和重写
4.多态
5.基类的析构函数为什么要写成虚函数
6.C++11的特性
7.智能指针shared_ ptr的底层实现,提示说use_ _count是用指针来记录程序到可运行中间经历的4个步骤
8.静态链接和动态链接
9.Linux的操作
10.守护进程的概念
11.lambda表达式的对象捕获方式
12.TCP保证可靠传输的机制
13.CLOSE_ WAIT状态
14.流量控制和拥塞控制
15.网络层和运输层的作用
16.七层网络模型有哪些
17.进程间通信
18.线程的同步机制
19.读写锁、自旋锁和互斥锁的机制
20.单例模式
五.
1.先来个自我介绍
2.做过哪些项目
3.C++看过哪些书
4.STL有哪些组件,
5.map和unordermap有哪些区别
6.哈希表如何实现(完全不了解,乱扯了一堆)
7.map为什么是logn的查询和修改时间
8.map中红黑树最长路径和最短路径的差值,(不会, 然后在瞎扯,最后扯错了)9.new和melloc的区别,他们的返回值,申请空间失败返回的是什么
10.智能指针的用处
11.空指针NULL和nullptr的区别
12.-个类,默认会有哪些成员函数
13.-个空类占用的内存大小是多少
14.TCP和UDP的区别
15.TCP的流协议中出现的粘包现象如何处理,粘包的坏处。
16.MTU是什么
17.IP层下面的一-层和上面的一层,网络接口层一-次性允许发送多大的包。
18.C++中static的作用
19.反问环节
六.
-
TCP四次挥手
-
TCP怎么实现可靠传输的?
-
c++构造函数可以是私有的吗? 析构函数呢?
4.C++默认的函数
5.虚函数的原理,构造函数可以是虚函数吗?
6.静态成员函数是什么?可以是cons的吗?
7.拷贝构造函数是什么,有什么作用?
-
const char* ptr 与char* const ptr有啥区别?
-
struct与class的区别?
10.线程A,B,C循环顺序打印
11.代码实现死锁
12.虚拟内存空间
13.堆/栈的区别
- shared_ prt是什么, 是线程安全的吗?可以指向数组吗?
15.vector的工作原理,什么时候迭代器会失效?
16.了解设计模式吗?如何实现单例模式?
17.你知道的进程通信
18.知道深拷贝浅拷贝吗,C++ 默认的是深拷贝还是浅拷贝?
19.了解泛型编程吗?函数模板和类模板有啥区别。
20.怎样判断主机字节序?
七.
1、如何学习C++,遇到什么困难,怎么解决
2、多态如何实现
3、虚拟内存的结构,虛函数表在其中的哪个阶段,存放在哪里
4、虚拟内存如何映射到物理内存,多级页表,页表使用的算法
5、内存池、内存泄漏
6、I0复用,epoll的ET跟LT是什么, epol的结构,Reactor\Proactor模式7、C10K问题
8、C++1有了解过吗,讲一讲
9、智能指针,shared_ ptr 底层实现,weak_ pt和shared ptr关系10、move函数
11、const. static关键字, 分别存放在哪里
12、new、 malloc,new 具体做了什么
13、tcp、 udp 区别,为什么tcp安全
14、tcp滑动窗口、慢启动
15、tcp粘包,如何避免粘包
16、心跳包
17、tcp拥堵流量控制
18、 三次握手、四次挥手
19、 项目
20、有什么想问的吗