首页 > 高质量C++面试
头像
linux地平线
编辑于 2021-08-13 14:58
+ 关注

高质量C++面试

1. 语言基础

C++虚函数这是面试初、中级C++职位一个概率95%以上的面试题。一般有以下几种问法:

1. 在有继承关系的父子类中,构建和析构一个子类对象时,父子构造函数和析构函数的执行顺序分别是怎样的?

2. 在有继承关系的类体系中,父类的构造函数和析构函数一定要申明为virtual吗?如果不申明为virtual会怎样?

3. 什么是C++多态?C++多态的实现原理是什么?

4. 什么是虚函数?虚函数的实现原理是什么?

5. 什么是虚表?虚表的内存结构布局如何?虚表的第一项(或第二项)是什么?

6. 菱形继承(类D同时继承B和C,B和C又继承自A)体系下,虚表在各个类中的布局如何?如果类B和类C同时有一个成员变了m,m如何在D对象的内存地址上分布的?是否会相互覆盖?

2. C++新特性和类库

一定要熟悉C++11/14/17常用的语言特性和类库,这里简单地列一下:

· 统一的类成员初始化语法与std::initializer_list<T>

· 注解标签(attributes)

· final/override/=default/=delete语法

· auto关键字

· Range-based循环语法

· 结构化绑定

· stl容器新增的实用方法

· std::thread

· 线程局部存储thread_local

· 线程同步原语std::mutex、std::condition_variable等

· 原子操作类

· 智能指针类

· std::bind/std::function

C++11/14/17需要一定的练习才能掌握,

推荐一个学习C++新特性的地址:https://github.com/0voice/cpp_new_features

推荐几个学习C++11/14/17的开源项目:

1. filezilla

2. uWebSocket网络库

3. TeamTalk的PC端

3. 算法与数据结构基础

说到算法和数据结构,对于社招人士和对于应届生一般是不一样的,对于大的互联网公司和一般的小的企业也是不一样的。下面根据我当面试官面试别人和找工作被别人面试经验来谈一谈。

先说考察的内容,除了一些特殊的岗位,常见的算法和数据结构面试问题有如下:

1. 排序(常考的排序按频率考排序为:快速排序>冒泡排序>归并排序>桶排序)

一般对于对算法基础有要求的公司,如果你是应届生或者工作经验在一至三年内,以上算法如果写不出来,给面试官的影响会非常不好,甚至直接被pass掉。对于工作三年以上的社会人士,如果写不出来,但是能分析出其算法复杂度、最好和最坏的情况下的复杂度,说出算法大致原理,在多数面试官面前也可以过的。注意,如果你是学生,写不出来或者写的不对,基本上面试过不了。

1. 二分查找
二分查找的算法尽量要求写出来。当然,大多数面试官并不会直接问你二分查找,而是结合具体的场景,例如如何求一个数的平方根,这个时候你要能想到是二分查找。我在2017年年底,面试agora时,面试官问了一个问题:如何从所有很多的ip地址中快速找个某个ip地址。

2. 链表
无论是应届生还是工作年限不长的社会人士,琏表常见的操作一定要熟练写出来,如链表的查找、定位、反转、连接等等。还有一些经典的问题也经常被问到,如两个链表如何判断有环(我在2017年面试饿了么二面、上海黄金交易所一面被问过)。链表的问题一般不难,但是链表的问题存在非常多的“”,如很多人不注意边界检查、空链表、返回一个链表的函数应该返回链表的头指针等等。

3. 队列与栈
对于应届生来说一般这一类问的比较少,但是对于社会人士尤其是中高级岗位开发,会结合相关的问题问的比较多,例如让面试者利用队列写一个多线程下的生产者和消费者程序,全面考察的多线程的资源同步与竞态问题(下文介绍多线程面试题时详细地介绍)。
栈一般对于基础要求高的面试,会结合函数调用实现来问。即函数如何实现的,包括函数的调用的几种常见调用方式、参数的入栈顺序、内存栈在地址从高向低扩展、栈帧指针和栈顶指针的位置、函数内局部变量在栈中的内存分布、函数调用结束后,调用者和被调用者谁和如何清理栈等等。某年面试京东一基础部门,面试官让写从0加到100这样一个求和算法,然后写其汇编代码。

4. 哈希表
哈希表是考察最多的数据结构之一。常见的问题有哈希冲突的检测、让面试者写一个哈希插入函数等等。基本上一场面试下来不考察红黑树基本上就会问哈希表,而且问题可浅可深。我印象比较深刻的是,当年面试百度广告推荐部门时,二面问的一些关于哈希表的问题。当时面试官时先问的链表,接着问的哈希冲突的解决方案,后来让写一个哈希插入算法,这里需要注意的是,你的算法中插入的元素一定要是通用元素,所以对于C++或者Java语言,一定要使用模板这一类参数作为哈希插入算法的对象。然后,就是哈希表中多个元素冲突时,某个位置的元素使用链表往后穿成一串的方案。最终考察linux下malloc(下面的ptmalloc) 函数在频繁调用造成的内存碎片问题,以及开源方案解决方案tcmalloc和jemalloc。总体下来,面试官是一步步引导你深入。(有兴趣的读者可以自行搜索,网上有很多相关资料)

5. 树
面试高频的树是红黑树,也有一部分是B树(B+树)。
红黑树一般的问的深浅不一,大多数面试官只要能说出红黑树的概念、左旋右旋的方式、分析出查找和插入的平均算法复杂度和最好最坏时的算法复杂度,并不要写面试者写出具体代码实现。一般C++面试问stl的map,java面试问TreeMap基本上就等于开始问你红黑树了,要有心里准备。笔者曾经面试爱奇艺被问过红黑树。
B树一般不会直接问,问的最多的形式是通过问MySQL索引实现原理(数据库知识点将在下文中讨论)。笔者面试腾讯看点部门二面被问到过。

6. 图
图的问题就我个人面试从来没遇到过,不过据我某位哥哥所说,他在进三星电子之前有一道面试题就是深度优先广度优先问题。

7. 其他的一些算法

如A*寻路、霍夫曼编码也偶尔会在某一个领域的公司的面试中被问到。

推荐一个数据结构和算法的Github地址:https://github.com/0voice/algorithm-structure

3. 编码基本功

还有一类面试题不好分类,笔者姑且将其当作是考察编码基本功,这类问题既可以考察算法也可以考察你写代码基本素养,这些素养不仅包括编码风格、计算机英语水平、调试能力等,还包括你对细节的掌握和易错点理解,如有意识地对边界条件的检查和非法值的过滤。

4. 多线程开发基础

现如今的多核CPU早已经是司空见惯,而多线程编程早已经是“飞入寻常百姓家”。对于大多数桌面应用(与Web开发相对),尤其是像后台开发这样的岗位,且面试者是社会人员(有一定的工作经验),如果面试者不熟悉多线程编程,那么一般会被直接pass掉。

这里说的“熟悉多线程编程”到底熟悉到什么程度呢?一般包括:知道何种场合下需要新建新的线程、线程如何创建和等待、线程与进程的关系、线程局部存储(TLS或者叫thread local)、多线程访问资源产生竞态的原因和解决方案等等、熟练使用所在操作系统平台提供的线程同步的各种原语。

对于C++开发者,你需要:

· 对于Windows开发者,你需要熟练使用Interlock系列函数、CriticalSection、Event、Mutex、Semphore等API函数和两个重要的函数WaitForSingleObject、WaitForMultipleObjects。

Windows 多线程相关知识可以看《Windows 核心编程》一书

· 对于Linux开发者,你需要熟练使用mutex、semphore、condition_variable、read-write-lock等操作系统API。

· 可以使用C++实现一个简单的线程池,当然支持优先级、动态创建线程功能就更好了。

5. 数据库

数据库知识一般在大的互联网企业对应届生不做硬性要求,对于小的互联网企业或社会人士一般有一定的要求。其要求一般包括:

(1)熟悉基本SQL操作
包括增删改查(insert、delete、update、select语句),排序order,条件查询(where子语句),限制查询结果数量(LIMIT语句)等

(2)稍微高级一点的SQL操作(如Group by,in,join,left join,多表联合查询,别名的使用,select子语句等)

(3)索引的概念、索引的原理、索引的创建技巧

(4)数据库本身的操作,建库建表,数据的导入导出

(5)数据库用户权限控制(权限机制)

(6)MySQL的两种数据库引擎的区别

(7)SQL优化技巧

以上属于对开发的基本的数据库知识要求,你可以找一本相关入门级的数据库图书学习即可。

高级开发除了以上要求还要熟悉高可用MySQL主从同步读写分离分表分库等技术,这些技术的细节一定要清楚,它们是你成为技术专家或者高级架构的必备知识。我们在实际面试时,在讨论高可用服务服务方案时,很多面试者也会和我们讨论到这些技术,但是不少面试者只知道这些技术的大致思想,细节往往说不清楚,细节不会就意味着你的高可用方案无法落地,企业需要可以落地的方案。

这些技术我首推《高性能MySQL》这本书,这本书高级开发者一定要通读的,另外还有2本非常好的图书也推荐一下:一本是《MySQL排错指南》,读完这本书以后,你会对整个“数据库世界”充满了清晰的认识;另外一本是《数据库索引设计与优化》,这本书读起来非常舒服,尤其是对于喜欢算法和数据结构的同学来说。

6. 网络编程

网络编程这一块,对于应届生或者初级岗位一般只会问一些基础网络通信原理(如三次握手和四次挥手)的socket基础API的使用,客户端与服务器端网络通信的流程(回答 【客户端创建socket ->连接server ->收发数据;服务器端创建socket ->绑定ip和端口号->启动侦听->接受客户端连接->与客户端通信收发数据】即可)、TCP与UDP的区别等等。

对于工作经验三年以内的社会人士或者一些中级面试者一般会问一些稍微重难点问题,如select函数的用法,非阻塞connect函数的写法,epoll的水平和边缘模式、阻塞socket与非阻塞socket的区别、send/recv函数的返回值情形、reuse_addr选项等等。Windows平台可能还会问WSAEventSelect和WSAAsyncSelect函数的用法、完成端口(IOCP模型)。

对于三年以上尤其是“号称”自己设计过服务器、看过开源网络通信库代码的面试者,面试官一般会深入问一些问题,这类问题要么是实际项目中常见的难题或者网络通信细节,根据我的经验,一般有这样一些问题:

1. nagle算法;

2. keepalive选项;

3. Linger选项;

4. 对于某一端出现大量CLOSE_WAIT或者TIME_WAIT如何解决;

5. 通讯协议如何设计或如何解决数据包的粘包与分片问题;

6. 心跳机制如何设计;(可能不会直接问问题本身,如问如何检查死链)

7. 断线重连机制如何设计;

8. 对IO Multiplexing技术的理解;

9. 收发数据包正确的方式,收发缓冲区如何设计;

10. 优雅关闭;

11. 定时器如何设计;

12. epoll的实现原理。

全部评论

(0) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

热门推荐