大家好,我是张小方。
事情是这样的,有一位学医的小同学有个学计算机的女朋友,她投递了大厂 C++ 研发实习岗位,准备去参加 C++ 面试了,找到小方求助如何准备,于是有了这篇文章。
小方作为《C++服务器开发精髓》一书作者,资深
C++ 面试官,这次就来和大家聊一聊 C++ 研发实习生面试如何准备以及面试会被问到哪些问题。
面试的开场通常是面试官让面试者做一下自我介绍。这个自我介绍比较有讲究,但是大多数同学的自我介绍都平平无奇,基本上是,我叫 XXX,毕业于 XXX 院校 XXX 专业等一些客观信息的介绍。
自我介绍其实是很讲究技巧的,如果把握得当,可以引导面试讨论内容的方向,掌握主动权,把面试考察内容往自己擅长的方向引导,所以建议即将参加面试的同学可以按照本文的建议提前演练一下。例如你可以在自我介绍中主动介绍自己的特长、感兴趣的技术点,平常在该方面花了不少时间,或者自己曾经做个 XXX 项目,通过 XXX 技术解决了 XXX 问题。面试官大概率会就你说的这些点追问,这样就把面试话题引导到你擅长的方向了。
下面是两个模板:
自我介绍模板 1
面试官你好,我叫 XXX,即将毕业于 XXX 大学,专业是 XXX,我比较擅长算法和数据结构,在校期间参加过多次 XXX 比赛,并取得了 XXX 成绩,我平常在算法上花的时间比较多,研究过很多开源项目中的算法,如 Linux 内核中的 LRU 算法和进程调度算法等,在个人博客/站点发表过 n 篇高质量算法和数据结构的博文。
自我介绍模板 2
面试官你好,我叫 XXX,即将毕业于 XXX 大学,专业是 XXX,我比较喜欢网络编程,在校期间花过大量时间在网络编程上面,我通读过《TCP/IP 协议》三卷等经典计算机网络书籍,研究并梳理过常见 C/C++ 网络库的结构和运行机理,了解很多网络编程的细节和注意事项,曾经是我校 XXX 项目的底层网络模块的主要开发者,在 github 发布过 XXX 网络库项目,fork 多少,start 多少。
对于应届生来说,面试的要求基本就一句话:要求基础扎实。
那何为“基础扎实”呢?先说基础,基础指的是计算机相关专业的各个专业课程内容,“基础扎实”指的是对这些专业课内容有较好的理解和实践。计算机相关专业课一般包括算法数据结构、编程语言、操作系统原理、计算机网络、数据库等,当然,有些岗位因为特殊需要,可能还会进一步对汇编、编译原理等知识进行考察。下文我会逐一介绍在面试中会考察这些基础课程的哪些内容。
先介绍应届生如何准备算法和数据结构。
算法和数据结构是整个面试中的重中之重,尤其像 BATJ 这样的一二线大厂,在面试考察内容中一般会占到百分之五十的比重(参见上文图中红色部分)。对于应届生或者实习岗位的招聘来说,如果算法题做得不好,基本上会被一票否决。而且与有多年工作经验的社招相比,一般对应届生的算法能力要求更高。举个例子,编写一个对折链表的算法,对于工作多年的社招可能写个大概就可以了,但是对于应届生必须要求完整的写出来。
有的公司在进入人工面试之前,会安排专门的笔试题来考察算法和数据结构,如果笔试过不了,基本不会安排下一轮人工面试;即使进入了人工面试,面试官也会去看面试的同学的笔试成绩和答题内容状况。
包括算法和数据结构在内的所有基础知识,重在平时的积累,而不是面试的时候临时抱佛脚。部分同学直到校招临近才开始准备,但是因为需要准备的内容实在太多而不知所措,这里有个实战策略推荐给你,策略的原则是花最短的时间准备更加重要的面试考察内容:
老实说,算法和数据结构的内容挺多的,我知道很多同学会刷算法题,有一些同学专门挑一些 hard 级别的算法题来刷。这里可以告诉大家,刷一定的算法题是有必要的,但是过多刷 hard 级别的题目是没必要的,不仅浪费时间且收益不大(算法岗位除外)。适当刷题的目的是保持对常见的算法题的熟悉度,算法题一般分为两类,一类是算法书或者 leetcode 上的原题,面试中考察的这类算法题一般都集中在数组、链表、哈希表等常见数据结构上,所以大家准备的时候,也可以以这类算法题为主,对于像红黑树、图等一般不会考察的;另一类是开放性思维题或者场景设计题,举两个例子,在时间和空间算法复杂度有一定要求的情况下,从朋友圈广告(亿级别)中找到最受欢迎(点击量)最高的广告,一只青蛙往楼梯上跳跃,每次可以跳一阶二阶三阶,对于 n 阶楼梯,计算青蛙有多少种跳跃方式。
对于场景题可以看这里。
只要是技术面试,算法和数据结构通常都会考察。
由于本文主题是 C++ 面试,下面我们来说 C++ 部分,C++ 是一门很注重语言和接口背后原理的编程语言,下面我分享一下我作为 C++ 面试官常问的一些问题。
考察 C++,不仅仅指 C++,也可能包含部分 C 语言的内容。
const char *p
、 char const *p
与 char * const p
的区别,这个问题答错,面试基本不会通过,说明基本功差static_cast
、dynamic_cast
、reinterpret_cast
和 const_cast
几种 C++ 类型转换符的区别偶尔也会问到,面试者至少要知道第一种。// 32位系统上
struct A {
int i;
char j;
};
A a;
A* pa = &a;
sizeof(a) = ?
sizeof(pa) = ?
int arr[8];
int* parr = arr;
sizeof(arr) = ?
sizeof(arr[0]) = ?
sizeof(parr) = ?
char sz[] = "helloworld";
char* psz = sz;
sizeof("helloworld") = ?
sizeof(sz) = ?
sizeof(psz) = ?
int operator[](int i)
方法,后者调用 a 类的 int operator[](int i) const
方法。你答对了吗?std::map
、std::set
等数据结构,如果你说没用过,那面试到此就基本结束了(面试不通过);如果你说用过,接下来会问你这些容器背后的数据结构、插入删除的算法复杂度(最好和最坏的情况)、以及各个容器的使用场景和注意事项。有的面试官还会问,std::vector
的 resize
和 reserve
方法的区别。
auto
关键字等少量语法特性,这样显然是不行的。C++11 问得最多的是几种常用的智能指针,即 std::unique_ptr
、std::shared_ptr
、std::weak_ptr
,面试者需要熟悉这几种智能指针的使用场景和区别,以及智能指针背后的实现原理(引用计数),智能指针还会结合多线程场景来问,例如智能指针是否是线程安全的(引用计数是线程安全的,管理的内容不是),关于 C++11 的智能指针的使用,我写过一篇详细的文章 《Modern C++ 智能指针详解》。左值、右值、左值引用、右值引用、std::move
、std::emplace
和移动构造函数的内容也是 C++11 面试常问的问题。读者可以看下面的面试题是够能做出来:
#include <memory> class A { }; void f1(std::unique_ptr<A>&& a1) { } void f2(std::unique_ptr<A>&& a2) { //这里编译有错误,如何修改? f1(a2); } int main() { std::unique_ptr<A> spA(new A()); //这里编译有错误,如何修改? f2(spA); return 0; }va_
系列的宏就可以了,另外一点是这种支持不定参数的函数的调用方式必须是 C 调用(__cdecl
),不能是标准调用(__stdcall
),因为 C 调用由调用者来平衡堆栈,标准调用由被调用者来平衡堆栈,对于支持不定参数的函数,只有实际被调用时,才知道要平衡多长的堆栈,因此如果使用标准调用,编译器不知道如何为该函数生成平衡堆栈的指令。如果你答得不错,面试官可能会深入下去,考察你栈的结构,各个变量和函数参数在栈中的分布。如果你不明白我在说什么,可以参考这篇文章《你一定要搞明白的C函数调用方式与栈原理》。考察 C++ 中无法返回一个局部变量的地址或引用的原因也是对栈结构知识的考察,当然,可能从栈又会引出堆的概念和用法,这就属于操作系统原理的知识了。__thiscall
有时候也会在考察范围内,比如面试官问 C++ 的类实例方法和静态方法如何实现的,给一个类增加一个静态/实例方法是否会增加类的大小,给一个类增加一个静态/实例字段是否会增加类的大小,sizeof 一个无任何方法和成员的空类等于多少,为什么不是 0?操作系统原理考察的内容一般比 C++ 语言考察的内容和范围要广,但是在面试官问了几个问题之后,如果面试者答得不好,面试官就会换其他方向问了。
fork
和 exec
调用的区别。int i = 0;
中变量 i 的地址属于哪种地址,什么是实模式和保护模式等等,堆和栈在内存地址空间的分布和增长方向。对于应届生的话只会问一些计算机网络的理论知识,但是如果面试者的项目中有相关的网络编程的内容,也会问一些网络编程的内容。我们在这个章节只列举经常考察的计算机网络理论知识,更多的网络编程的内容,我们放到项目经验这一节来详细介绍。
常考察的计算机网络知识有:
更详细的内容请接着看项目篇。
一般后端岗位对数据库有一定的要求,但是作为加分项,通常不会作为强行要求。
对于应届生,只要掌握数据库的增删改查、知道索引的概念和实现原理即可,例如你要知道索引的常见实现是 B+ 树,索引的结构,以及如何建立有效索引;另外一点是数据库的事务,面试者只要将事务的概念讲清楚即可。
从面试官的角度来说,我们也是从学生时代过来的,对于大多数学生做的项目的水平都心知肚明。
对于应届生,项目其实不是必需的,还是前面强调的,面试官更看重的还是基础知识部分;倘若某位同学在简历中描述了自己的项目,那么面试的时候,面试官会结合项目的内容考察一下。
为了让大家可以感同身受,我截取了两份真实应届生求职 C++ 岗位的简历中项目描述(这些简历素材来自小方的知识星球,小方的知识星球为球友提供模拟面试服务,一年当中不限次数,有需要的同学可以点这里加入星球),小方带着大家分析一下这两个简历中项目描述。读者可以先想一想,这样描述项目,面试时可能会被问到哪些问题。
看到 A 同学的项目描述了,我在实际面试中问了该同学以下问题:
\r\n\r\n
确定边界,包体如何确定边界呢?该同学说不清楚。我接着又问,既然是 HTTP 协议,那么肯定可以处理 GET 和 POST 请求,那么 GET 请求和 POST 请求有什么区别,你在处理的时候,如何区分的,分别又是如何解包的,该同学只能说出 GET 请求的参数放在 URL 后面,但是说不清楚 POST 请求的数据放在哪里,如何确定数据长度。这里实际是对 HTTP 协议格式的考察。关于面试中常见的网络编程题和考察知识点,我专门总结过一篇文章《网络通信题目集锦》。我在知乎也专门开设过一个 Live 讲解如何回答这些题目,有兴趣的同学可以点这里(微信公众号不支持外链,需要拷贝地址到浏览器打开):
https://www.zhihu.com/lives/922110858308485120
通过面试,我断定这位同学并没有深度参与这个项目,可能只是把别人的东西拿来借用一下.另外,可以看出来该同学不熟悉 HTTP 协议,网络编程的基础勉强及格,实践(调试)经验不足。所以,这个项目写在简历中起到了相反的作用。面试是不通过的。
不知道你能否看出该项目描述的问题?
B 同学的项目描述的问题在于太多的业务描述,关于技术的描述(仅有 C++、算法等字样)太少了,这样给面试官问问题的空间就大了,很容易问到面试者不会的地方。另外,该项目也无法看出面试者在项目中通过何种技术解决问题的能力。
关于项目描述,给同学们有如下几点建议:
最后祝小两口幸福,原创不易,如果觉得有帮助,请给 @张小方 点个赞呗~
本文是《女朋友要去 XXX 系列》第一篇。
关注我,更多有趣实用的编程知识~
推荐阅读
如果想加入 高质量 C++ 技术交流群 进行交流,可以先加我微信 easy_coder,备注"加微信群",我拉你入群。
原创不易,点个赞呗