记一次失败的面试经历
最近一直比较忙,每天忙于家里和工作,好久都没有时间来更新日志了,今天刚趁着有时间来好好更新一篇日志,主要想谈谈最近一直影响比较深刻的某外企的面试经历,虽然没有通过,但是我觉得把这段经历去复盘一下,总结其中的不足之处,也是对自己的一种成长,提醒自己在哪方面准备的还不足。
1. 接到通知
某日正在上班期间,突然接到一个陌生的上海的电话,告知我因为在某次力扣双周赛排名比较靠前,问我有没有兴趣参加他们公司的面试。当时接到电话的那一刻确实比较诧异,因为很多公司都会介意我目前是在职公务员的经历,然后我跟她反复确认了一下,是否介意我目前是在职公务员的身份,被告知不是很介意,然后就发了面试确认。
实话实说我目前是在职公务员,并且已经从工程师的职业生涯已经GAP
了好几年了,很多公司基本上看到简历都会直接丢弃的那种状态。不过只是业余爱好,平时工作之余时间也非常多,非常喜欢刷力扣算法题和计算机的四大的公开课。平时工作之余因为时间确实较多,心想反正闲着也是闲着,不能把这些时间浪费掉,纯粹是出于兴趣的目的来刷算法题目和学习这些专业课程的,一方面是把这些时间花在学习上总比浪费在抖音和游戏上强的多;另一方面,说句实话这些课程真的是非常非常有意思,纯粹是激起了我这种有两娃的中年男人的学习兴趣。
2. 笔试过程
跟HR
确认邮件后,很快就收到了first step
的online assignment
.查看了一下,题目是在hackrank
上,用c++
设计一道系统设计题目,需要通过所有的测试用例。平时周一到周五确实没有时间,只能乘着周末来完成这个题目。大概在周日的时候,到旁边大学的自习室,打开了题目,从开始构思系统设计,到通过全部测试用例差不多花费了2个多小时,虽然最终的代码量再精简一下,估计也就不到200
行就能完成。虽然花费了精力,但是完成提交online assignment
,我觉得题目本身来说非常有意思,这个系统设计题目出的还是相当有水平的。题目大意如下:
要求设计一个由多个
unit
连接组成的系统,该系统有多个输入,只有一个输出,通过每次输入不同的input
来给出系统的最终输出。每个unit
也可能有多个输入input
,但是只有一个输出output
,每个unit
会执行某种运算,运算操作可能是+,-,/,*,异或,与,或,非
等等,运算操作的数即为该unit
的输入input
,最终运算的结果即通过输出output
获取。关键的一点在于,必须所有的unit
的输入上input
上都有合法的输入参数时,unit
的output
才会有输出。需要提示的是系统的input
可能会连接多个unit
的输入,一个unit
的output
可能会连接多个unit
的input
。题目给出了给出了所有解析输入的函数,要求利用这些函数来解析输入的参数。
解题思路如下:
本题实际就是一个有向图的遍历的问题,我们将每个的
unit
都看作为图中一个特殊的节点。图中的不同的unit
的输出与unit
的输入的连接即可看作为两个节点之间的边。我们每次遇到系统不同的input
输入时,则我们会对相连接的unit
的进行运算,并将运算的结果向后传递给下一个unit
,如果我们检查传递后的unit
的所有的input
的输入状态是否都是合法,如果合法,则我们进行该unit
的运算,并将输出结果再继续向下一个节点进行传递,直到最终由系统的output
有输出,此时我们打印出系统的输出即可。系统中特别需要注意的一点是一个
unit
的某个input
只能连接一个unit
的输出,但是一个unit
的输出output
,可以连接到多个unit
的输入端口input
。此时我们就需要记载每个unit
的输出output
连接了哪些unit
的input
;但是我们不需要记载每个unit
的输入连接了哪个unit
的输出。每个unit
定义如下:/*unit define*/
struct unit{
std::string name; // unit name
UNIT_TYPE type; // unit type
vector<bool> valid; // every input port state
vector<int> input; // every input value
int output; // output
vector<Edge> out; // output link to the input of the next unit
};
/*edge link*/
struct Edge{
std::string us; // the next unit name
int in; // input port of the unit
};同时我们需要对整个系统的
input
和output
也做抽象成为特殊的unit
,每个input
端口表示为只有一个输入和输出的unit
,它的运算即为输出等于输入,系统的output
端口表示为只有一个输入和输出的unit
,它的运算也为输出等于输入,这样我们即可把整个系统全部抽象为unit
,不同的input
进入时,相当于有向图中的部分节点的值向它的相邻节点进行值传递,我们依次即可计算出图中中所有的unit
的输出,最终能够计算出系统的output
.实际即是一个非常简单的bfs
即可完成,时间复杂度也即为O(n)
即可。按照这个思路很快就完成了代码的编写,不过期间debug
花了不少时间才完成。
2. 准备电话面试
笔试很快就完成了,然后就给HR
发了email
确认了笔试已经完成,后面HR
告知online assignment
已经通过了,就需要进入second step
的phone interview
了,并且明确告知需要用英文进行,想想自己刚刚过六级的水平,口语搓的一比,并且在体制内也不会有用口语的地方,那也只能硬着头皮硬上了。办法总比困难多,那就开始练习口语了,不过确实不太好练习,因为周围也没有几个口语特别好的;另一方面即使口语非常好的,但是也没有时间来陪我模拟面试,大家基本上都有家庭了。
我想办法总比困难多,这就需要发挥自己的主观能动性了,分别从四个方面着手来准备面试:
- 从该公司的官方网站上查找一下相关公司的信息,大概需要了解一下公司的
backgroud
和interview detail
,job description
,大概对公司的基本信息和招聘职位的信息做一下基本的了解,同时也在linked in
上找了该公司的员工的部分个人背景简介和工作内容的详细介绍,以上这些都是对基本信息的搜集,能够快速的对公司的基本信息和职位信息做一个基本的了解。 - 从
youtube
上快速的找一些software engineer interview tips
诸如此类的视频,以及一些部分up
主的online mock coding interview
的面试视频来学习观看,一方面通过这些视频的学习了解phone technical interview
的基本流程,另一方面能够顺便对部分专有的专业英语术语能够熟悉下,毕竟CS
专业的英语专业术语非常多,同时自己也在默默的模仿一下。 - 在网上找了一个口语较好的
师弟
来进行练习,大概练习了有两三次,可惜期间师弟parterner
有事中途退场了,我只能自己找了,在网上搜了几个还不错的APP
,都能够付费进行口语练习。第一次拨通跟老外进行口语练习,还是蛮紧张的,不过想想就是要脸皮厚点,不过大部分国外人还是非常热心的,反正大部分口语说错了,他们大概也能懂,并且跟其中一个叫ALEX
的老外还混熟了,基本上都找他瞎聊,感觉蛮开心的。不过其中HR
问我要了一份英文简历,我也只能硬着头皮把我那个本身就写的非常烂的简历又用tex
重新弄了一份英文版本的,不过写作英语时,发现国外的Grammarly
的软件真心好用,如果需要写书面英语的话强烈推荐。 - 其余就是针对
whitepaper coding
和C++ concept detail
的学习了,这个是本次面试中最大的失误,太注重在线coding
能力了,反而忽视了对c++ basic concept
的学习了,在binary search
平台上练习了大量的算法题,感觉如果是靠算法题的话,我基本上可以百分之九十的题目都能秒杀。不过也是因为干公务员太长时间了,没有过多去关注实际工程中需要应用的技术细节和语言的语法细节方面了,另一方面也确实没有多少可以实践的地方。虽然自己尝试在hackrank
上面去练习c++
的专题训练,同时通过网上的部分面经来学习一些常见的C++
的问题了,这方面是此次面试的最大失误,毕竟实际工程中算法其实并没有那么重要,实际工程中可能更加关注技术细节和代码落地,比如最基本的现程同步之类的,结果就是在这些细节的concept
上失败了。
3. 电话面试过程
电话面试邮件通知的时间大概是在周五的下午四点钟,于是早早的提前周五下午请好假,回家打开电脑,打开hackerRank
,因为之前HR
通知是在hackerRank
上面进行白板面试,所有的题目都会在hackerRank codepair
上出现,早早打开hr
通知的链接,然后等在电脑前,四点到了,发现怎么还没有电话进来,后来又等了10
分钟,还米有电话进来,以为面试取消了,都准备去洗洗睡了。结果差不多到了4
点15
了,手机显示上海的陌生号码打过来了,接听后,一位很轻的小哥告诉我是本次的面试官,说抱歉刚才因为有会议所以才迟到了,耳测小哥年龄应该在25~30岁之间。
我以为会有简单的自我介绍或者基本的关于过往的项目经历的简介之类的,没想到面试官上来就说开始吧,然后就开始了一堆关于C++
的基础知识的细节和系统基础知识的考问,感觉之前准备的部分behavior problem
都白准备了。下面是对部分详细问题的描述
Q1
what's the difference of stack memory and heap memory ? |
- 这个问题用中文还是蛮简单,用英文确实有点麻烦了,就用用举例的方法简单说了一下。定义静态数组的空间都是使用栈内存的,每次进行函数调用的时候,也是需要将参数压入栈,利用
stackmachine
,实际上如果要利用栈空间,大都是由在编译阶段编译器会直接定义好栈空间的分配;定义动态数组时则使用的是heap memory
,比如我们常见的malloc
,new
的操作,则是在heap
中进行申请。目前的操作系统中,每一个线程都会分配一个独立的stack
,stack
的大小则可以由现程初始化时进行指定,而heap
则是由操作系统统一进行管理,每次申请动态内存时,操作系统则会在空余的heap
中分配一块,常见的heap
分配的算法有first fit
,best fit
等常见的分配算法。
Q2
what's the usage of memory pool? |
memory pool
常用内作为缓存,由于我们需要一些缓存来存储一些关键信息,如果我们每次需要使用内存时,都直接用malloc,new
之类得动态内存申请,必然会造成很大一部分时间得开销,因为在实际得操作系统中malloc
之类得开销非常耗费时间得,因为我们可以在系统初始化化即申请一大块动态内存,然后后面如果需要用到存储时,则从这一大块memory pool
中取出一小块即可,避免了系统过多次得malloc
操作,从而造成系统不必要得开销。
Q3
C++ smart pointer: |
- 常见的C++智能指针得问题。
unique_ptr
和shared_ptr
主要关注内部实现即可知道他们的内部的原理和不同,这个基本上可以通过阅读智能指针的源代码即可了解其中的不同。
Q4
c++ template: |
- 这个问题直接卒掉,C++的模板编程非常方便,这个也是C++的高级特性的一个核心,说实话已经很长时间没有用模板编程了,还是好好的去学习学习
haskell
之类的语言,好好的学习一下lisp
之类的高级语言,或者学习学习SCIP
从而对这些语言的高级特性能够一劳永逸的去解决。
Q5
what's the useage of conditional variables ? |
- C++的
conditional variables
主要用来作为线程同步和并发。
Q6
object oriented question: |
- 题目中定义了函数的构造函数和析构函数,但是并没有对函数进行构造函数和虚构函数进行实例化,最终会导致我们在进行初始化一个类的变量时,就会报错
undefined reference
。问了一个关于C++基类的问题,这个问题确实已经很长时间没有关注过C++基类的用法。
Q7
coding: |
- 给了一个超级简单的
coding
题目,就是用c++
写出split
函数,感觉可能面试官不想再继续面了,可能就随便给了一个题目打发人的意思。刚开始明显看他还准备问我dynamic programming
的题目,后面可能发现对我不敢兴趣了,就想快点结束面试的意思。差不多不到2分钟就写出了一个无bug
的代码,反正是非常的简单。
4. 面试总结
总得来说面试得不是非常好,许多基础知识都忘记得差不多了,但是我觉得通过自己练习算法题,还是得到了不少的面试机会,至少这样能感受到自己的努力有一些回报。还是需要多加努力学习,因为我知道像我这种没有背景没有关系得人什么都需要靠自己,在这个社会上立足,只有越努力才能越自由。
努力挣扎,虽然中年人生活不易,但是一定不要放弃自己得努力,依次诫勉,来告诫一个不敢轻易松懈得中年人。俗话说,“君子不立于危墙之下”,如果自己对周围的环境不爽,那么要么尝试着去改变这个环境,要么就努力脱离这个让你变得糟糕得环境,不要一味的抱怨环境和抱怨人生,尽快让自己进入一个上升的正循环的通道。
- 下一步的计划,是需要对基础知识进行恶补,虽然
C++
的不是一门特别容易上手的语言,但是里面非常多的语言特性是非常值得学习的,还是自己的基础不够扎实。学习的书单目前基本如下: - 《the little scheme》
- 《MIT SCIP》
- 《C++ 深度探索内存模型》
- 《C++ 模板元编程》
- 《C++ 多线程编程》
- 《C++ 智能指针的实现》
- 《C++ 对象池的实现》
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章