# 我面试后端开发经理的经历


## 我面试后端开发经理的经历

我去年12月份从上一家公司离职，一直到今年3月份，基本上都在面试中度过来的。

先交代下背景：坐标上海，做技术开发，我本人面试的职位是linux服务器开发，最倾向的职位是服务器开发主程或技术经理。我本人也是上几家公司的面试官，因为接下来几年面临着成家，技术上也到了瓶颈期，虽然拿了不少offer，但是想综合比对一下，于是就参加了很多的面试。我先后去了如下一些公司：腾讯、百度、饿了么、爱奇艺、360、携程网、京东、华为、bilibili、上海黄金交易所、东方财富网、zilliz、掌门集团(做无线万能钥匙的那一家)、喜马拉雅听书、峰果网络、华尔街新闻、万得财经、汇正财经、逗屋网络、朝阳永续，还有数家小规模的公司或创业公司吧。

为了避免引起不必要的纠纷，下面我就不说具体的公司名称了。技术面试的细节我尽量写的详细一点，希望对大家有参考价值，技术面试大致有三种情形：

### 经验分享

**一、以百度、爱奇艺等为代表的，以数据结构和算法为主。**

首先是简单地了解下你之前的工作经历和项目经验，然后就是算法和数据结构题目，具体涉及到以下内容：

01

快速排序

 快速排序（包括算法步骤、平均算法复杂度、最好和最坏的情形），有人说校招要把算法写出来，我是社招，所以描述一下算法步骤即可。

02

二分查找算法

写二分查找算法，这个尽管是社招，但是一般也不难，所以要求面试者写出来。但是很多公司，比如不会直接让你写算法，而是结合一个具体场景来提问，然后让你自己联想到二分查找，比如求一个数的平方根。

03

链表

链表，常见的面试题有写一个链表中删除一个节点的算法、单链表倒转、两个链表找相交的部分，这个一般必须得完全无误的情况下写出来。

04

自己实现一些基础的函数

自己实现一些基础的函数，例如strcpy / memcpy / memmov / atoi，同样的道理，这些必须完全无误且高效地写出来，比如你的实现中会动态分配堆内存，那么这道题目就算答错。



第3点和第4点的门道一般在于考察你的代码风格、对边界条件的处理，比如判断指针是否为空，千万不要故意不考虑这种情形，即使你知道也不行，只要你不写，一般面试官就认为你的思路不周详，容错率低；再比如，单链表的倒转，最后的返回值肯定是倒转后的链表头结点，这样才能引用一个链表，这些都是面试官想考虑的重点。

05

 哈希表

哈希表，对哈希表的细节要求很高，比如哈希表的冲突检测、哈希函数常用实现、算法复杂度；比如百度二面就让我写一个哈希表插入元素算法，元素类型是任意类型。

06

AVL树和B树的概念、细节

AVL树和B树的概念、细节，比如会问mysql数据库的索引的实现原理，基本上就等于问你B树了。

07

红黑树

红黑树，这个基本上必问的一个数据结构，包括红黑树的概念、平均算法复杂度、最好最坏情况下的算法复杂度、、左右旋转、颜色变换。面试官常见的算法套路有：你熟悉C++的stl吗？你说熟悉，ok，stl的map用过吧？用过，ok，那map是如何实现的？红黑树，ok，那什么是红黑树？这样提问红黑树就开始了。Java的也类似。



**二、以饿了么、bilibli、喜马拉雅、360、携程等为代表的，兼顾算法数据结构和其他开发技术。**



算法和数据结构部分上文提过了，下面提一下其他技术，大致包括以下东西：

01

基础的C++问题

以C++语言为例（不是C++开发的朋友可以跳过这一点），第一类是**基础的C++问题**，常见的有C++的继承体系中virtual关键字的作用（如继承关系中析构函数为什么要申明成virtual函数，如果不申明为virtual会有什么影响)、在涉及到父子类时构造与析构函数的执行顺序、多重继承时类的成员列表在地址空间的排列；static关键字的作用，static_cast / reinterpret_cast / dynamic_cast等几个转换符的使用场景;问的最多的就是**虚表的布局**，尤其是菱形继承(B和C继承A，D继承B和C)时每个对象的空间结构分布，比如问D有几份虚表，D中B和C的成员空间排布。



另外，如果你应聘的职位使用C++开发，很多公司会问你一些C++11的东西（或者问boost库，基本上都一样），这个你用过就用过，没有用过就说没用过不要装X，**常见的C++11需要掌握的一些技术库**我也列举一下吧（JAVA及其他语言的读者可以忽略）：

auto关键字、for-each循环、右值及移动构造函数 + std::forward + std::move + stl容器新增的emplace_back()方法、std::thread库、std::chrono库、智能指针系列（std::shared_ptr/std::unique_ptr/std::weak_ptr）(智能指针的实现原理一定要知道，最好是自己实现过)、线程库std::thread+线程同步技术库std::mutex/std::condition_variable/std::lock_guard等、lamda表达式（JAVA中现在也常常考察lamda表达式的作用）、std::bind/std::function库、其他的就是一些关键字的用法(override、final、delete)，还有就是一些细节如可以像JAVA一样在类成员变量定义处给出初始化值。

02

网络通信问题

 网络通信问题，比如协议栈的层级关系，三次握手和四次挥手的【细节】，注意我说的是细节，比如CLOSE_WAIT和TIME_WAIT状态（**bilibili**问了这样一个问题，你可以感受一下：A与B建立了正常连接后，从未相互发过数据，这个时候B突然机器重启，问A此时的tcp状态处于什么状态？如何消除服务器程序中的这个状态？

**万得**问过流量拥塞和控制机制、腾讯问过tcp和ip包头常见有哪些字段），阻塞和非阻塞socket在send、recv函数上的行为表现，异步connect函数的写法，select函数的用法，epoll与select的区别，基本上只要问到epoll，必问epoll的水平模式和边缘模式的区别；一些socket选项的用法，nagle / keepalive / linger等选项的区别；tcp / udp的区别和适用场景；通信协议如何设计避免粘包；http协议的get和post方法的区别（问的比较深的会让你画出http协议的格式，参照这篇文章中关于http协议格式的讲解：http://blog.csdn.net/analogous_love/article/details/72540130）；**windows用户**可能会问到完成端口模型(IOCP)，网络通信方面的问题，我专门开了一个知乎live系统地总结了一下，有兴趣的朋友可以看这里：https://www.zhihu.com/lives/922110858308485120 和 这里：https://www.zhihu.com/lives/902113324999778304。

总之，**网络通信问题能搞的多清楚就可以搞的多清楚，最起码把tcp应用层的各种socket API的用法细节搞清楚。**

03

操作系统原理性的东西

比如**linux下elf文件的节结构**，映射到进程地址空间后，分别对应哪些段，相关的问题还有，全局变量、静态存储在进程地址空间的哪里；堆和栈的区别，栈的结构，**栈的细节一点要搞的特别清楚**，因为一些对技术要求比较高的公司会问的比较深入，例如京东的一面是让我先写一个从1加到100的求和函数，然后让我写出这个函数的汇编代码（JAVA开发的同学可能会让你试着去写一点JVM的指令），如果你对栈的结构（如函数参数入栈顺序、函数局部变量在栈中的布局、栈帧指针和栈顶指针的位置）不熟悉的话，这题目就无法答对了；**栈的问题，可能会以常见的函数调用方式来提问**，**常见的函数调用**有如下__cdecl/__stdcall/__thiscall/__fastcall的区别，比如像printf这样具有不定参数的函数为什么不能使用__stdcall；还有就是**进程和线程的联系与区别**，问的最多的就是**线程之间的一些同步技术**，如互斥体、信号量、条件变量等(Windows上还有事件、临界区等)，这些东西你必须熟悉到具体的API函数使用的层面上来，从另外一个角度来说，这是咱们实际工作中编码最常用的东西，如果你连这个都不能熟练使用，那么你肯定不是一个合格的开发者；这类问题还可以**引申为什么是死锁、如何避免死锁**；**进程之间通信的常用技术**也需要掌握，常用的通信方式（linux下）有共享内存、匿名和具名管道、socket、消息队列等等，管道和socket是两个必须深入掌握的考察点（与上面网络通信有点重复）；**linux系统下**可能还会问什么是daemon进程，如何产生daemo进程，什么是僵尸进程，僵尸进程如何产生和消除（bilibili问过）。

CAS机制（饿了么二面问过）。

04

使用过的开源技术

第四类就是一个使用过的开源技术，比如代表nosql技术的redis；网络库libevent等等；数据库如mysql的一些东西。这个一般不做硬性要求，但是这里**必须强调的就是redis**，熟练使用redis甚至研究过redis源码，现在一般是做后台开发的技术标配或者说不可缺少的部分，基于redis的面试题既可以聊算法与数据结构，也可以聊网络框架等等一类东西。我面试的公司中基本上百分之九十以上都问到了redis，只是深浅不一而已，比如喜马拉雅问了redis的数据存储结构、rehash；bilibili问了redis的事务与集群。



**三、只问一些做过的业务或者项目经验。**

这类公司他们招人其实对技术要求不高（资深及主管级开发除外），只要你过往的项目与当前应聘职位匹配，可以过来直接上手干活就可以了，当然薪资也就不会给很多。比如游戏公司会关心你是否有某某类型的游戏开发经验、股票类公司会关心你是否有过证券或者交易系统的开发经验等。我的经验就是这类公司，能去的话可以去，不能去的话就当积累面试经验。业务开发哪里都能找到，真正的重视技术的公司，应该是广大做技术尤其是初中级开发的朋友应该值得关心的事情。



### 不靠谱型公司。

我遇到的大致有四类：

01

装X忽悠型

第一类：装X忽悠型

面试过程冗长繁琐，比如号称每一百份简历中才发一个面试邀请，号称每一百个面试者发一个offer，号称硅谷风格，我面试的有一家公司就是这个样子，先是一轮长长的电话面试，然后是五轮技术面试，前三轮是刷leetcode上原题，然后后几轮面试，面试官从基本的操作系统的中断、GDT、LDT、分表分页机制问到上层高并发海量数据的架构，说的不好听，真是从外太空聊到内子宫，最后问具体职位做什么时，要么遮遮掩掩要么原型毕露；或者讨论薪资时，要么面露难色要么各种画饼，但是实际就给不了多少薪水的。

02

佛性公司

第二类：佛性公司

面试下来，全程面试官面带微笑，问你的问题你回答的面试官也很赞同，但最后你就没通过，我猜测要么公司不是很缺人，想观望一下是否有合适的人才；要么招聘信息上开的薪资给不到。

03

老奶奶裹脚布型公司

第三类：老奶奶裹脚布型公司

其特点是面试周期长，往往第一轮面试通知你过了，让你回去等上十天半个月后，给你打电话通知你来第二轮面试，面试要求穿正装，带好各种证件，面试前必须先查验你的身份证、学历证学位证，甚至是四六级考试证等等，麻烦至极，即使你一路过关斩将过了终面，薪资也给不了多少。大家都是要养家糊口的，都是忙着找工作，谁有时间和你耗上十天半个月呢？

04

不尊重人类型公司

第四类：不尊重人类型公司

我这里说的不尊重人，不是指的是面试过程中对你人身攻击，而是不根据你的工作年限和经验随意安排面试官，举个例子，比如你工作十年，你去面试一个技术总监的职位，对方公司安排一个工作不满两年的部门职员作为面试官，这个面试官如果是走过场可以理解，但是非要和你纠结一个如二进制位移、现代编译器要不要在子类析构函数前加virtual关键字这些技术细节就没必要了。还有一类就是故意问一些刁钻的问题，或者全场都心不在焉、玩手机、漫不经心的面试官，比如问你tcp协议头有多少个字段，每个字段是干啥的。遇到这一类面试官我的经验就是要么婉拒，要么直接怼回去。





### 注意细节

下面再说下面试中需要注意的一些细节：

01

把目光放长远一点

第一，如果你的工作年限不长，尤其是渴望在技术方面有一定的造诣，那么你首先考虑的应该是新的单位是否能有利于你技术上的成长，而不是两份同样的工作，薪资上的上下相差的三五千、五六千。如果想转行的同学（比如从客户端转服务器，从C++转JAVA），不要因为薪资突然变低而拒绝这种阵痛，要把目光放长远一点。

02

可能最终会因为薪资达不到不被录取

第二，一些公司虽然招聘信息上写了最多能给到多少多少，但实际即使你全程面试下来都很完美，可能最终你也会因为薪资达不到不被录取。

03

多面试积累经验

第三，一些根本不想去的公司，如果你有时间的话，去面试积累下经验也不是什么坏事。

04

警惕技术天花板

第四，面试的时候，同时也是你在考察面试官，一般面试官问你的问题，你能回答出来的在百分之八十左右，这样的公司可以考虑去入职，你进去的话可能才会在技术上有一些提升。如果你全场秒杀面试官的题目，你的技术天花板可能也在那里。

05

聊清楚将来的职位内容

第五，面试的时候聊清楚你将来的职位内容，避免进去客串一些不想做的工作。

06

不会的面试题尝试去和面试官沟通

第六，遇到不会的面试题，不要直接就否定自己，可以尝试着去和面试官沟通一下，或者要求给点提示或者思路。

07

不要轻视笔试中的数学智力题

第七，不要轻视笔试中的一些数学智力题目，认真作答，试问算法不也是数学智力题吗？

08

自信点

第八，自信一点，每个人的经历和经验都是独一无二的，面试的时候，一些特定领域的问题，回答不出来也不要太在意。



希望对阅读的朋友有所帮助。因为个人经验能力有限，所说的也可能只是一家之言，说的不妥当的地方还请温和地提出建议，如果读者有任何问题可以加我微信 **easy_coder** 交流。
