C++面试基础整理(私房菜)

说实话,这两年的就业形势比较严峻,忙里偷闲整理了之前面试的基础,都是实实在在的干货啦,对于离职或想换工作的小伙伴有一定帮助。当然,我自己后续有需要也会回过来看看!

文章目录

  • 多态原理(新)
  • http通信原理
  • 构造函数和析构函数
  • vector和list的区别
  • map和unordered_map的区别
  • 关于智能指针
  • 堆和栈的区别
  • sendmessage和postmessage的区别
  • 多进程和多线程
  • 线程同步的几种方式
  • windows消息机制
  • TCP拥塞控制
  • TCP流量控制
  • nullptr和NULL
  • 单核多线程同步
  • 内存泄露常用处理方式
  • 常用的几种设计模式
  • enable_shared_from_this作用
  • 动态库的二进制兼容
  • MT和MD的区别
  • 多线程和并发的区别
  • 常用的进程间通信
  • 智力题
  • 简单问答

多态原理(新)

  • 对象在构造时会创建虚函数表,并提供一个虚表指针;
  • 将子类对象赋值给基类时,基类对象会获取子类对象指针,可通过虚表指针找到虚函数地址;
  • 当虚函数被调用时,会去虚函数表查询函数地址;

http通信原理

通过tcp建立连接 — web浏览器请求 — 请求头部信息 — 服务器应答(带协议版本号和应答状态码)- 服务器应答头部信息 - 服务器应答web浏览器的请求

构造函数和析构函数

  • 构造函数不能为虚函数,因为虚函数表是在构造函数中创建的,如果构造函数为虚函数,将无法被调用;
  • 析构函数可以为虚函数,一般基类中的析构函数会神明为虚函数,这样delete基类指针时,会调用子类析构函数去销毁子类对象;
  • 构造函数中可以调用虚函数,但因为子类对象虚函数表还未创建,故调用的是基类的虚函数;

vector和list的区别

  • 存储
    vector与数组类似,内存空间是连续的;list基于双链表实现,内存空间不连续;
  • 元素访问
    vector支持随机访问,list不支持;
  • 插入删除
    vector插入或删除伴随着拷贝、移动,不高效;list基于双链表实现,插入和删除更高效;
  • 迭代器
    vector用的是随机访问迭代器,支持+=><等操作;list只支持++操作;

map和unordered_map的区别

  • 查询效率
    map是基于红黑树(有序,平衡二叉树)实现的,查找效率为O(n);unordered_map是基于哈希表实现的,查询效率为O(1)。
  • 空间占用
    map更高,unordered_map更低。
  • 创建耗时
    unordered_map创建耗时更高,map更低。

关于智能指针

  • unique_ptr独占对象所有权,无引用计数;
  • shared_ptr共享对象所有权,带有引用计数,是非线程安全的;
  • weak_ptr赋值不会增加引用计数,可解决共享指针互相引用的问题;

堆和栈的区别

  • 分配方式不同。栈内存由系统分配,堆内存动态分配的;
  • 空间存储不同。栈上分配的是连续内存,堆上是不连续的;
  • 分配效率不同。栈上的内存是快速分配,堆上内存较慢;
  • 空间大小不同。堆上可分配的内存远大于栈;

sendmessage和postmessage的区别

  • sendMessage不会进入窗口的消息队列,postMessage会进入窗口消息队列。
  • sendMessage是线程阻塞的,必须执行完后,才能执行后面的代码;postMessage是非阻塞的,立即返回;
  • sendMessage的返回值表示执行结果,postMessage返回true或false,表示;

多进程和多线程

  • 线程是进程的子集,一个进程可以拥有多个线程;
  • 进程有独立的内存空间,线程是共享进程的内存空间;
  • 进程占用内存大,切换复杂,CPU利用率低;
  • 线程占用内存小,切换简单,CPU利用率高;
  • 进程创建、销毁、切换复杂,线程较简单,且线程切换速度快;
  • 多进程互相不影响,多线程中一个线程挂掉整个进程挂掉;

线程同步的几种方式

  1. 自动重置事件。运行于内核态、同步慢。
  2. 信号量。运行于内核态、同步慢。
  3. 互斥对象。运行于内核态、同步慢。
  4. 关键代码段。运行于用户态、同步快,但不能跨进程。
    注意:互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

windows消息机制

当系统中触发一个事件时,windows会把这个事件翻译成消息,将消息投递到应用程序消息队列中,应用程序根据作用对象将消息分发到各个窗口,最终窗口过程(消息响应函数)处理。

TCP拥塞控制

通过拥塞窗口来控制。首先设置一个很小的值,也就是所谓的慢启动,单数据包能准时发送时,开始指数式增长,也就是快增长。当增长到”慢启动阀值”后,开始线性增长(窗口大小的倒数),当发生超时时,”慢启动阀值”设置为超时值的一半。
四个控制算法:慢启动、拥塞避免、快重传、快恢复。

TCP流量控制

通过滑动窗口来实现。

nullptr和NULL

两者有明显的区别,NULL是一个宏,常被定义为#define NULL ((void*)0),而且会被隐式转换为intnullptr是c++的新特效,可以避免C++重载时传入NULL引发的二义性。

单核多线程同步

  1. (单核CPU)同一时间,cpu只能处理1个线程,只有1个线程在执行
  2. 多线程同时执行:是CPU快速的在多个线程之间的切换
  3. cpu调度线程的时间足够快,就造成了多线程的“同时”执行
  4. 如果线程数非常多,cpu会在n个线程之间切换,消耗大量的cpu资源
  5. 每个线程被调度的次数会降低,线程的执行效率降低

内存泄露常用处理方式

  1. 使用VLD工具。只需包含#include 即可;
  2. 写一个宏重新定义newmalloc

常用的几种设计模式

  • 简单工厂模式
    定义多个产品类,这些产品拥有统一的接口:生产产品;定一个工厂类,根据不同的产品类型,可以生产出不同的产品。
  • 工厂方法模式
    有多个工厂,每个工厂负责某一个品牌的生产。
  • 抽象工厂模式
    有多个工厂,每个工厂只负责一个品牌的生产,每个品牌下可以有多款产品;
  • 单例模式
    保证一个类只有一个实例化对象,分为懒汉模式和恶汉模式:
  • 懒汉模式。在使用时才去创建实例,初始化为nullptr;
  • 饿汉模式。初始化时使用new创建一个实例;
  • 观察者模式
    一种一对多的关系,被观察者有变化时会通知观察者更新。可以理解为观察者注册回调接口到被观察者,被观察者有添加/注销观察者的权限。
    注意:当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯。
  • 发布—订阅者模式
    此模式区别于观察者模式,中间还有个调度者的角色,负责把发布的博文,推送给订阅者。如:订阅者,博主,微博(调度者)。
  • 模板方法模式
    将一些公共行为抽象成基类,具体细节由子类实现。如:老师制作答卷,让不同的学生填写答案。

enable_shared_from_this作用

这是一个模板类,相当于返回一个shared_ptr类型的this指针,其内部是一个weak_ptr类型,不会增加引用计数。

动态库的二进制兼容

将dll库导出接口统一为extern "C"形式。如果要为您的dll导出具有C ++链接的类,则编译器将需要为导出的符号生成混杂名称。名称修饰不是C ++标准的一部分,因此在编译器供应商之间甚至有时在同一供应商的编译器版本之间都是不兼容的。

简而言之:使用C++版本的接口,对于不同的编译器,导出的符号可能不一致。

MT和MD的区别

  • /MD:表示运行时库由操作系统提供一个DLL,程序里不集成。编译出来的文件比较小。使用的库文件是 MSVCRT.lib
  • /MT:表示运行时库由程序集成。编译出来的文件比较大。在运行的机器上不需要安装依赖的VS的动态库,使用的库文件是 LIBCMT.lib

多线程和并发的区别

并发是一种目的,多线程只是实现并发的一种手段,实现并发还有其它方法,如:函数式编程。

常用的进程间通信

  • 文件映射
  • 共享内存
  • 匿名管道
  • 命名管道
  • WM_COPYDATA
  • 剪贴板
  • socket

智力题

  1. 两根燃烧速度不同的绳子,每根1小时可燃完,如何测算出15分钟的时间?
    答:给两根绳子编号为A和B,点燃A的两头,B只点燃一头,A烧完后开始计时,点燃B的另一头,B烧完后即为15分钟。
  2. 十个箱子,每个箱子里面有10个罐头,每个罐头1斤,有一个箱子里面的罐头是9两,称重一次,获取那个9两的罐头在哪个箱子里面?
    答:给10个箱子编号,编号为1的取1个罐头,编号为n的取n个罐头,正常情况是(1+10)*10/2=55斤,称出来少几两就是几号箱子。
  3. 有8个球,其中有一个偏重,用天秤称几次能找出来?
    答:2次。按3-3-2来分,第1次称:3-3称量,重的那3个球拿出来单独称,如平衡则称量剩下2个球;第2次称:1-1称量,重的那一端就是偏重的球,平衡则是余下那个球。

简单问答

  1. http是网络通信的哪一层协议
    答: 应用层协议。
  2. weak_ptr存在的意义是什么?
    答:解决共享指针的互相引用和环引用问题。
  3. https用的是对称加密,还是非对称加密?
    答:内容传输用的对称加密,证书验证用的非对称加密。
  4. 使用make_shared而不用new shared_ptr有哪些优势?
    答:更高效、更安全。

你可能感兴趣的:(技术杂谈,c++,面试,开发语言,私房菜)