问题1
在C++开发中定义一个变量,若不做初始化直接使用会怎样?
直接使用一般不会有问题, 但是如果是全局变量,默认值是0, 局部变量的值是随机值。
问题2
程序出现崩溃,如何调试?
如果是Linux平台了下的程序, 可以通过core dump(核心存储)的方式来进行调试。
所谓的core dump,就是当一个进程异常终止(也就是崩溃)的时候,可以把进程的全部数据保存在磁
盘上,文件名叫core, 然后检查core文件就可以精准定位错误(不过Linux机器是默认关闭core文件的)。
如果是windows程序, 当程序崩溃时,会生成一个dump文件,打开任务管理器,找到一个dump文件,检查即可定位错误。
问题3
一个程序是否创建线程越多越好?怎样决定创建线程的数量?
肯定不是的,如果线程数量比处理器数量多,会增加额外的同步和调度开销,会有性能损失;健壮性降
低,编写多线程程序需要更全面更深入的考虑,因为如果一个线程在时间分配上出现了细微的偏差,例
如访问了不该访问的共享变量可能会造成巨大的影响;线程过多会导缺乏访问控制,一个进程内部的一
个线程如果调用某个系统调用函数,可能会对整个进程产生影响。编写与调试多线程是非常困难的。
如何决定创建线程的数量呢?
CPU密集型应用 : CPU核数 + 1
IO密集型应用: IO/CPU时间片 + 1
问题4
一个进程可以访问另一个进程的内存数据?
不能, 因为每个进程都有自己独立的进程地址空间,也就是进程是有独立性的
OS怎样保证每个进程有独立的空间?
每个进程都有属于自己的进程地址空间,当进程需要访问数据和代码的时候,它必须先访问虚拟内存中
的虚拟地址,然后再通过页表将虚拟地址转换为物理地址访问数据和代码。 这样通过权限控制就保证了每个进程都只能访问自己的
代码和数据。
问题5
打开百度网站过程涉及哪些协议?
DNS域名解析协议 + http协议 + tcp + ip + 以太网协议
问题6
说说STL常见容器
string, vector,list, map,set, unordered_map, unordered_set
TCP/IP传输过程中为什么要分片传输?
因为数据链路层一次性向网络中传输的数据是有限制的 <= 1500个字节。
问题6
TCP的拥塞控制如何判断当前网络情况?
TCP引入慢启动机制, 先发少量的数据探探路。
发送开始的时候,定义拥塞窗口的大小为1,每次发送数据报的时候,取拥塞窗口和接受方的窗口
大小作比较, 取最小的发送。每次拥塞窗口成指数形式增加,当达到阈值的时候变成线性增长,一旦发生
超时重传,拥塞窗口创新置回1,并且阈值减小为一半。
智能指针的内存管理机制?
RAII的思想 : 利用对象生命周期管理资源
问题7
了解哪些单例模式?讲一下单例模式
饿汉 :
优点 : 实现起来简单轻松
缺点 : 不管用不用都会创建对象,进程启动可能缓慢, 当构造函数工作量大的时候。
多个线程启动单例对象的时候,无法控制顺序
懒汉:
缺点 : 实现起来复杂,也存在线程安全的问题。
优点: 使用时创建对象, 进程启动无负载。 多个线程启动单例对象顺序可控制。
I/O多路复用机制的优势?
就是单个进程可以同时等待多个文件描述符就绪。 提高IO效率。
有select, poll, epoll
问题8
C和C++的区别,优缺点?
C语言是面向过程语言, C++是面向对象语言。C++兼容C语言的大部分语法。
c语言的优点:面向过程语言的性能比面向对象好,因为类调用时需要实例化,比较消耗资源。
缺点: 没有面向对象语言易维护, 易复用,易扩展。
那为什么很多操作系统的内核都是用c语言写的呢?
C语言出现的比较早
问题9
了解STL吗?讲解一下里的vector、list
vector实质上是数组, list实质上是链表
vector优点 : 支持下标的随机访问
缺点 : 头部和中间的插入删除需要挪动大量元素,效率低,O(N),扩容机制会存在一定的消耗。
list的优点: 按需扩容,任意位置的插入删除效率高 O(1)
缺点: 不支持下标的随机访问。
问题10
讲一下指针和引用的区别?
指针和引用的底层原理完全一样,但是用法上有些区别。
例如 :
有空指针, 无空引用。有多级指针, 无多级引用。
指针有独立的空间,32位机器是4字节,64位是8字节。 引用是别名,没有独立的空间。
引用可以直接访问实体, 指针需要显示的解引用操作。
指针+1向后偏移一个指向类型大小的距离, 引用+1是实体加1。
总体来说, 引用更安全一些。
问题11
对多态的理解?如何实现?
多态即多种形态, 不同类型的对象调用同一个函数产生了不同的行为。 例如 : 买票的例子 (可能很多人说)
如何实现 :
前提 : 满足2个条件
1, 必须通过父类的指针或者引用去调用虚函数
2,调用的虚函数必须是子类重写的父类的。
当子类继承父类的时候,子类会首先拷贝父类的虚函数表到自己的虚函数表中,然后子类如果重写了就替换掉,有新增则直接在虚表的后面 追加即可。当用父类的指针和引用(但是指向子类对象的时候),它实际上会通过子类的虚表指针到子类的虚表中去找虚函数。
可扩展 : 上面这种通过虚函数产生的多态我们称为动态的多态, 实际上多态又分为静态的多态和动态的多态。
静态的多态指在编译阶段就确认行为,例如 : 模板和重载。
动态的多态指程序运行起来才能确定行为。
对继承的理解?如何实现?
继承实质上是代码复用的重要手段, 它允许子类在保持父类原有的功能特性上进行扩张。
但是它实质上是一种白箱复用,父类于子类而言是可见的,一定程度上破坏了封装性。并且父类的改变也可能会导致子类的改变,类和类之间依赖程度高,高耦合。
问题12
双向链表插入一个节点如何操作?