问题1
局部变量和全局变量的区别,能同名吗?
可以同名
作用域 : 全局变量作用域是整个程序, 而局部变量的作用域是当前代码块。
生命周期 : 全局变量的生命周期随进程, 而局部变量的声明周期只是在当前作用域。
存储区域:全局变量存放于数据段, 局部变量存放于栈区。
问题2
如何让本文件的类在外部文件不可见?
私有的内部类
问题3
讲一讲你了解的多态
多态即多种形态,不同类型的对象调用同一个函数产生了不同的行为。(举一个生活中的例子)
多态又分为静态的多态和动态的多态。 静态的多态有模板 + 函数重载,在编译时就已经确定了行为。
动态的多态 : 就是通过虚函数产生的多态,运行起来才可以确定行为。 但是要满足这样两个条件 : 1,2
问题4
数据结构都用过哪些,讲一些数组和链表的区别
顺序表,链表, 栈,队列,优先队列,二叉树,堆,哈希。
数组的优点 和缺点
优点 : 支持下标的随机访问,CPU高速缓存命中率高
缺点 : 头部和中部位置的插入删除需要挪动大量元素, 效率低。扩容机制存在一定的损耗。
链表的优点和缺点
优点 : 任意位置的插入删除效率高, 按需扩容
缺点 :不支持下标的随机访问
CPU高速缓存命中率高???
当CPU去访问内存中数据的时候,不是直接访问,而是将数据先加载到缓存中。当将一个数据加载到缓存的时候,会认为用户即将会访问相邻位置的元素,则CPU将该元素向后的一段连续空间也加载缓存中。
CPU缓存污染 : 就是将不必要的数据加载到了缓存中,降低CPU处理数据的效率, 例如顺序表,当我们只用访问1个元素的时候,CPU会将它以及向后的一段连续空 间的数据也加载到缓存中。
题目4
c++内存布局,和每个区存储的数据类型??
栈 : 向下生长,先使用高地址后使用低地址。存放局部变量,形参,函数返回值。
内存映射段:用于转装载一个共享的动态库。
堆 : 向上生长, 先使用低地址后使用高地址。 用于存放动态申请的空间。例如new。
数据段:全局变量 + 静态变量
代码段 : 存放执行的代码 + 只可读常量。
题目5
如何检测内存是否泄漏,如何快速定位 ???
什么是内存泄漏呢? 内存泄漏是指因为疏忽或错误造成程序未能正确释放已经不在使用的内存的情况,
它并不是指内存在物理上的消失, 而是指在分配某段内存后,因为某种原因对该段内存失去了控制。
内存泄漏分为:
1 堆内存泄漏。 new/malloc/realloc/calloc的资源未能通过delete/free释放掉
2 系统资源泄漏, 例如 套接字,文件描述符,管道,共享内存未能通过对应的函数正确释放掉
如果是VS环境, 可以通过Windows操作系统提供的 _CtrDumpMemoryLeaks()进行检测, 不过它只说明泄漏了多少内存,并不定位。
可以通过一些检测工具, 例如Linux平台下的valgrind
Windows的VLD(泄漏检测器)
题目6
进程和线程的区别???
进程是程序的一次执行, 而线程是进程内部的一个执行流。
进程是CPU分配资源的最小实体, 线程是CPU调度的基本单位。
线程没有独立的地址空间,共享了进程的地址空间,虚拟内存和页表。
所以线程间的通信要比进程间通信要简单,前者只用通过函数传参和全局变量就可以实现通信。
而后者需要调用系统调用函数,以及OS的参与。
问题7
进程间通信
管道,共享内存,消息队列,套接字
问题8
介绍一下深拷贝和浅拷贝
深浅拷贝本质都是拷贝对象, 深拷贝和浅拷贝用于拷贝内置类型是没有问题的,例如 int, char
如果涉及到用指针管理的资源时浅拷贝就会出现问题, 因为浅拷贝是按字节序拷贝。
例如 : 用浅拷贝string类的对象的时候,它仅仅是拷贝了一份指针,资源字符串没有进行拷贝,拷贝出来的对象中的char*指针指向和被拷贝 对象存储的地址一样,也就是他们指向同一块资源。
而深拷贝会复制那块资源,然后用创建新的指针去指向。
问题9
C++11的特性了解哪些,讲一个自己最熟悉的
范围for, 智能指针, auto, 右值引用,lambda表达式。
右值引用 : 右值(通常是一些字面常量或者临时变量,不能取地址),只能出现在赋值符号的右边,
而右值引用 就是给右值取别名,并且给右值取别名后,会导致右值存储在特定的位置。而它通
常用于类的移动构造和移动赋值。
它并不是为了减少拷贝而存在, 真正的意义而是为了窃取即将销毁的资源来构造自己,从而提高资源的利用率。
算法题
问题10
堆和栈的区别???
栈是向下生长的, 堆是向上生长的。
栈是可以动态和静态分配的, 堆只能动态分配。
一般而言,栈的变量不需要手动释放,堆上的资源需要我们手动释放的。
问题11
虚函数的原理,多态底层的实现
当一个类有虚函数的时候, 实例化的对象会有有一个虚函数表指针(它是在初始化列表初始化的),
其中的虚函数表是在编译阶段生成的,它存放的是虚函数的地址。
而对于多态,当子类继承父类的时候,它会继承父类的所有虚函数,生成自己的虚表,如果子类重写了
虚函数,会直接替换自己虚表的虚函数, 当父类的指针和引用指向子类对象, 并且调用虚函数的时候,
它实际上会去子类的虚表中查找.
问题12
看代码,计算带有虚函数的类大小
会多一个虚函数指针 4/8字节 注意内存对齐 !!!!
空类大小用sizeof计算为多少,为什么
1个字节, 用来占位。
了解C++11的一些锁机制吗
互斥锁
问题13
内存管理机制有了解吗
分为连续分配管理 和 非连续管理分配。
连续分配 : 将内存分为几个固定大小的块, 每个块之只能给一个进程使用。当一个进程运行只需要少
量内存的时 候,就会造成这块内存很大一部分都被浪费了,也就是说它极易容易产生碎片。
非连续分配 :将内存分为一页一页或者一段一段的形式, 比较与连续分配的块,划分力度细,提高了内
存利用率,减少了碎片。但是管理页式或者段式内存需要通过页表进行逻辑地址和物理地址的转换。
问题14
讲一下tcp的三次握手
为什么是三次不是四次发送流程 : 客户端: 首先发送syn报文,
服务端收到后发送ack + syn报文
客户端再次发送ack报文, 服务端收到后, 3次握手成功, 建立链接。
为什么是3次链接呢? 如果1,2次握手就 成功建立链接的话,意味着只要客户端发送一个syn报文,服
务端就认为链接建立, 并且需要维护这个链接。 也就是服务端挡不住syn洪水攻击。
而3次握手, 意味着客户端需要发送2次报文,服务端只用发送一次。意味着建立这个链接,服务端比客
户端做的工作要少,这样对于服务端来说会更加安全。
4次握手会导致服务端也会发送2次报文,这样来说会稍微浪费资源一些。
问题15
tcp和udp的区别
可靠 vs 不可靠
有连接 vs 无链接
字节流 vs 数据报。
问题16
select和epoll的区别
1,每次调用select的时候,都需要手动设置fd集合,而epoll只用在需要的时候通过epoll_ctr()将需要
关心的fd
添加即可。
2, select是轮询遍历检测哪些fd是准备就绪的, 而epoll底层是通过就绪队列来直接获取就绪的fd的,
O(1)
3,由于fd_set是一个位图结构, 所以select关心的fd有限制, 而epoll关心的fd无上限。
4,select上fd没有分开监视的事件和就绪的事件,而epoll实际上是分开了的。
问题17
七层模型将一下各层的作用
应用层 : 负责进程之间的沟通。 例如:HTTP, FTP。
表示层 : 主机固有的数据格式和网络标准数据格式的转换。
会话层 : 负责主机间的通信管理。
传输层 : 负责数据间的传输, 例如TCP协议, 负责数据流式的可靠传输。
网络层: 地址管理 和 路由选择, 例如IP协议。 其中路由器工作在这一层。
数据链路层: 相邻设备之间传送和识别数据帧。 例如以太网协议, 交换机工作在一层。
物理层 : 负责光电信号的传递。