笔者毕业两年,最近通过猎头拿到了腾讯IEG以及网易游戏的两个客户端研发offer(UE4/C++)。在面试前夕,笔者对C++进行了较为全面的复习和总结,乐观估计可以涵盖80%左右的面试基础问题。
这个系列的文章预计有《C++基础》、《内存、STL、虚函数相关》、《数据结构与算法》、《操作系统与网络》四篇(后续可能会调整),每篇都是以问答的形式分享并给出了参考资料的链接地址。大部分问题回答的比较简洁,需要大家去仔细阅读参考资料的具体内容,当然也可以直接问我(人多的话会考虑建一个群)~
个人觉得如果这些问题你全部搞懂的话,大部分面试官在C++上就拿你没什么办法或者说不会再进一步为难你了。不过想彻底理解所有内容也并不容易,这里面涉及到操作系统、数据结构、计算机系统原理、汇编等基础内容,涉及到的书籍包括《C++ Primer》《Inside the C++ Object Model》《Effctive C++》《More Effctive C++》《C++ Template》《The Design and Evolution of C++》《STL源码剖析》《深入理解计算机系统》等。在后续的文章里,我会把这些电子书分享给大家。
问:了解const么?哪些时候用到const?与宏定义有什么差异?(提问概率:★★★★)
简单理解,const的目的就是定义一个“不会被修改的常量”,可以修饰变量、引用、指针,可以用于函数参数、成员函数修饰。成员变量。使用const可以减少代码出错的概率,我们通常要注意的是区分常量指针(指向常量的指针)和指针常量(地址是常量,指针指向的地址不变)以及合理的在函数参数里面使用。具体的情况可以参考下面的书籍与资料。
参考书籍与资料:《Effctive C++》
Const用法总结(快速区分指针常量与常量指针)https://blog.csdn.net/u012999985/article/details/49009531
问:reference和pointer的区别?哪些情况使用pointer?(提问概率:★★)
1.指针可以为空,而引用不可以指向空值。
2.指针可以不初始化,引用必须初始化。这意味着引用不需要检测合法性
3.指针可以随时更改指向的目标,而引用初始化后就不可以再指向任何其他对象
根据上面的情况我们知道大概知道哪些时候需要使用指针了。不过还有一种情况,在重载如[]符号的时候,建议返回引用,这样便于我们书写习惯也方便理解。因为平时我们都是这样使用, a[10] = 10;而不是 *a[10] = 10;
参考书籍与资料:《More Effctive C++》
问:inline的优劣(提问概率:★★)
优点:减少函数调用开销
缺点:增加函数体积,exe太大,占用CPU资源,可导致cache装不下(减小了cache的命中) ,不方便调试debug下一般不内联, 每次修改会重新编译头文件增加编译时间
注意:inline只是一个请求,编译器有权利拒绝。有7种情况下都会拒绝,虚调用,体积过大,有递归,可变数目参数,通过函数指针调用,调用者异常类型不同,declspec宏等
forceinline字面意思上是强制内联,一般可能只是对代码体积不做限制了,但是对于上面的那些情况仍然不会内联,如果没有内联他会返回一个警告。 构造函数析构函数不建议内联,里面可能会有编译器优化后添加的内容,比如说初始化列表里面的东西。
参考书籍与资料:
WiKi(https://zh.wikipedia.org/wiki/内联函数)
MSDN(https://msdn.microsoft.com/zh-cn/magazine/z8y1yy88(v=vs.110).aspx)
问:final和override的作用,以及使用场合(提问概率:★★)
final:禁止继承该类或者覆盖该虚函数
override:必须覆盖基类的匹配的虚函数
场合(final):不希望这个类被继承,比如vector,编码者可能不够了解vector的实现,或者说编写者不希望别人去覆盖某个虚函数,顾名思义,final就是最终么
场合(override):第一种,在使用别人的函数库,或者继承了别人写的类时,想写一个新函数,可能碰巧与原来基类的函数名称一样,被编译器误认为要重写基类的函数。第二种情况是想覆写一个基类的函数,但是不小心参数不匹配或者名字拼错,结果导致写了一个新的虚函数
参考书籍与资料:《C++ Primer》
问:The rule ofthree是什么?为什么这么做?(提问概率:★)
If you need to explicitly declare either the destructor,copy constructor or copy assignment operator yourself, you probably need toexplicitly declare all three of them.(析构函数,拷贝构造函数,赋值运算符尽可能一起声明。如果你只定义一个,编译器会帮助你定义另外两个,而编译器定义的版本也许不是你想要的)
参考书籍与资料:WIKI Rule of three
(https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming))
问:C++03/98有什么你不习惯或不喜欢的用法?C++11有哪些你使用到的新特性?(提问概率:★★★★★)
这个问题最简单的办法就是看下一个版本的C++有哪些特性,新的特性肯定是有意义的。
如:
auto,有一些迭代器或者map嵌套类型,遍历时比较麻烦,auto写起来很方便。
vector以及其他容器的列表初始化,原来想要像数组一样初始化的话,需要一个一个来,很麻烦。
类内初始值问题&#x