做网站一般都是织梦/想要网站导航推广页
目的
写这一系列文章的目的主要是为了秋招时候应对计算机基础问题能够流畅的回答出来 (如果不整理下 磕磕绊绊的回答会被认为是不熟悉)
本文章题目的主要来源来自于 面试鸭
部分面试鸭上没有而牛客网上有的博主会进行查缺补漏
题目编号按照面试鸭官网题号方便大家寻找
题解大部分是博主根据自己之前的博客再加上部分网上的内容进行口语化的表述 如果涉及到省略的部分博主会提供自己或者其他人的博客链接
16. 什么是C++的左值和右值 有什么区别
参考博客 右值引用和移动语义
左值是那些可以出现在赋值符号左边的值 并且可以被取地址 比如说变量名还有解引用的指针
右值是那些不可以出现在赋值符号左边的值 不能被取地址 比如说常量 函数返回值等等
17. 什么是C++的移动语义和完美转发
移动语义是C++11引入的新特性 它旨在优化资源管理 避免不必要的深拷贝来提升程序性能
它通过右值引用和资源转移来实现
右值引用 通过 && 来绑定一个临时对象 标记可移动资源
资源转移 把窃取临时对象的资源来避免深拷贝
比如说下面的一段代码
// 移动构造 string(string&& s):_str(nullptr), _size(0), _capacity(0){cout << "string(string&& s)" << endl;swap(s);}
这里我们就使用道了右值引用和资源转移来实现了移动语义
完美转发
我们在模板中的 && 符号不代表右值引用 而是万能引用 既能接受左值也能接受右值
但是我们使用万能引用的时候会发现 不管传入的是左值还是右值 最后都显示为左值引用
因为只要右值经过一次引用之后右值引用就会被储存到特定位置 这个右值就可以被取地址和修改了 所以在经过一次参数传递之后右值就会退化为左值 如果我们想要让他保持右值的属性 这个时候就要用到完美转发
完美转发可以保持右值的属性
18. 什么是C++的列表初始化
列表初始化
C++11中引入了列表初始化的概念 它可以使用花括号来初始化变量或者对象
它可以防止类型窄化 防止精度丢失的类型转换
19. C++中的move有什么作用
参考博客
右值引用和移动语义
我们输入参数无论是左值还是右值 它最后都会强制转化为右值
转化后的右值可以触发移动语义
20. C++中三种智能指针的使用场景
参考博客
智能指针
C++中的三大智能指针分别是 unique_ptr share_ptr weak_ptr
他们的使用场景分别是 当我们的一个对象只被一个指针管理的时候 我们这个时候会考虑使用unique_ptr
shared_ptr则是当对象需要被共享的时候 我们考虑使用它
而weak_ptr则是为了解决shared_ptr的循环引用问题
21. C++11有哪些新特性
C++11的新特性有
- auto关键字
- 智能指针
- 右值引用和移动语义
- 匿名函数
22. 什么场景下需要使用移动构造和移动运算符重载
参考博客
右值引用和移动语义
- 当函数内要返回一个对象的时候 我们可以考虑使用移动构造来避免值拷贝
- 当需要传递参数的时候我们可以使用移动构造加上右值来避免参数拷贝
- 当我们要将一个容器内的数据拷贝到另外一个容器内的时候我们可以使用移动赋值来避免重复的资源释放和拷贝
23. using和typedef的区别
using和typedef都可以用来给已有的类型定义一个新的名称
他们的区别是using可以给模板定义别名
24. C++中delete关键字和default关键字的作用
delete关键字用来禁用某些成员函数 比如我不希望这个函数能够拷贝构造 我就可以在拷贝构造函数后面加上delete关键字
default关键字则是显示的要求编译器为某个函数生成它默认的实现
25. vector的原理 resize和reserve的区别
参考博客
vector的模拟实现
vector底层实际上是用一个指针和两个int类型的数据来进行维护的 分别是size和capacity
其中size表示现有元素的个数 而capacity则表示容量大小
我们使用resize来调整vector的大小为n 它可能构造或者析构元素
我们使用reverse来保证vector数组可以存储足够的元素 避免在插入元素的时候来进行频繁的扩容 它不会印象size的大小
26. 介绍下C++中的deque
deque是一个双端队列
它支持头插和尾插 并且时间复杂度都为O(1) 我们可以使用它来做一个滑动窗口
27. C++中map和unordered_map的区别
- 实现不同 map的底层是用红黑树来实现的 而unordered_map的底层则是使用哈希表来实现的
- 遍历顺序不同 我们遍历map得到的会是一个有序的答案 而unmap则不是
- 插入和查找的时间复杂度不同 map是logN unmap是1
28. list的使用场景
参考博客
list的介绍和使用
我们都知道list的底层双向链表 那么我们就要知道它的优势和劣势是什么
它的插入 删除效率很好 但是不支持随机访问
所以说我们应该在频繁的插入删除 但是不需要或者说不频繁使用随机访问的地方去使用它
29. 什么是RAII 使用场景?
RAII是获取资源即初始化
它的核心思想是将资源的生命周期和对象绑定起来 用对象去管理资源
因为对象离开它的作用域的时候会调用析构函数 这样即时程序在执行的时候抛出异常或者多路径返回也不会造成资源泄漏的情况
30. C++中锁的join和detach的区别
参考博客
多线程相关
join是阻塞当前线程 直到子线程完成
detach 是将子线程从调用线程中分离出来 子线程在后台独立运行不会阻塞调用线程
join适合在需要子线程全部完成任务之后由调用线程汇总或整理的场景下使用 我们使用join的时候需要注意避免死锁问题
detach则适合不需要等待子线程结束的情况 此时因为子线程的生命周期不可控 所以说我们要格外注意内存泄漏的问题