zoom杭州 windows C/C++ 本科2年 社招面经

Update:给各位观众老爷更新一下终面的情况,site manager + HR,终面面了大概快2个小时...脑壳痛
                为了保证新来朋友顺序阅读,把更新的三面情况放在后面了

已经完成了一面、二面,在等结果,上来写个面经,以飨后人,顺便求个福,Orz

zoom的面试体验,在我有限的面试经历中可以说是独树一帜,尤以一面为佳,老友聊天多于知识点拷问

从两个方面可以佐证,一面完成后,我像个上头的蚂蚱,四处忽悠我同学、朋友赶紧来面zoom,并且推掉近期的面试,只想着搞完zoom入职算了

在一面途中更多是一种探讨和论证,全程是裂开嘴面的,最后我吐槽起了zoom招聘投递异于常人,费了我不少功夫才成功投递出去;面试官说起工作与生活的情况,十分愉快

如果把面试当作平常工作中的浓缩以及映射,我觉得zoom是值得尝试的一家公司,也是我上头的原因之一

二面,面试官明显是个level更高的leader,很熟练地打开了zoom的虚拟背景,因此这次面试是在海滩上完成的。可惜面试官不苟言笑,缺失了一种吹着海风晒太阳的闲适和烂漫。

以下是具体问答

一面:

上来就是互相问候,然后相互扯淡,聊天当中把具体的经历都带出来了,免去了枯燥乏味的自我介绍

接着换了个语调开始念题目,我们知道有个定律是说世界上任意两个人之间通过7次关系可以找到对方,现在想象我们是FB,拥有所有人的朋友关系,现在我们要查询任意两人直接是否可以通过7次认识

答:我们先考虑数量级比较小的情况,大的情况可能会GG,得做优化。最直接的想法就是BFS,然后加上flag,对已经访问过的节点不重复访问(内心OS,直觉就是BFS,DFS大部分情况是BFS慢的,然而BFS也慢啊,先蒙一个)

追问:BFS有没有办法优化?

答:双向BFS,可以从两头开始BFS,就像两个圆,BFS的层数是它的半径,访问的数目是他的周长,两个小圆应该是比一个大圆小的

追问:你用周长来比喻好还是用面积来比喻更好

答:额,面积更好,周长不大对

追问:好,那我们现在的问题就转化了,假设我们两头都经过3次BFS,得到两个队列,那我们如何判断两个队列中有相同的内容?原来的问题转化成这个了对吧

答:对.....(内心OS,妈的,什么狗题,两个队列,这不得排序啊,nlogn啊,这还做啥) 需要精确查找吗,还是模糊查找就可以,因为我暂时没想到精确查找咋做,有个模糊查找的方法

追问:ok,你可以先讲讲模糊查找

答:可以上个布隆过滤器,它能够完成有相同一定找到,但找到不一定一定存在相同(面试官不太懂布隆过滤器,然后我解释了一遍,在此不再重复,总之是多次hash)

追问:好,那我们假设两个队列都是有序的呢

答:都有序啊,那2分呗,复杂度nlogn

追问:还有没有更快的

答:比二分更快啊..........哦,因为两个队列都是相对有序,第二数的二分可以从第一个数二分的ending位置开始,就是把第一个数所排除掉的内容不纳入第二个数的二分范围了(个人认为这个方法小于O(n+m)了,后面也与面试官进行了探讨)

追问:(微笑)还有没有更快的?

答:卧槽?比二分还快的,不可能吧...(内心OS,这么牛逼,比二分还快,这时候脑子已经开始混乱了,记不大清问题是啥了)

想了一会,一个平庸的算法冒出来了,一个一个比呗,第二数的起始位置从第一个数的ending位置开始比较,直接就是O(n+m)(后面 经面试官总结,这玩意有个名称叫归并排序,然而我只会暴力)

暴力半天后,突然灵光一闪,O(n)个屁,O(1)啊,把队列看作区间,头尾两个数作为区间断点,4次特判他们是否存在重叠关系就好了

后来经面试官指出,即便重叠也只能证明他们之间存在可能的相同变量,而不是一定。所以,最后还是乖乖的归并暴力

总结的时候聊了以下,用二分抛弃的做法,应该可以看作对暴力归并的优化,大部分情况是胜任的。

问:答的不错,那咱再做一道简单题

答:刚刚那道可属实不简单啊...

问:拆开看还是很简单的,BFS,双向BFS,归并都很常规嘛

答:...

问:建筑面做广告牌,标准矩形,求最大面积(leetcode 经典原题)

答:额...这题我做过,记得是用单调栈

问:(笑喷)那我不问了(我以为他要换一题) 这题我的思路是这样的,blablabla,你理解吧

答:对对对,我的是这样,blablabla

问:好,那我再问几个C++的基础问题

问:new、malloc啥区别

答:额...这个我前几天刚刚面过,blablabla开始背,背到一半就被打断了,大概是够了...

问:一个进程里头最多有多少个栈?

答:啊?多少个栈,不是一个栈就一个吗...

引导:那我们知道局部变量放在栈里,不同的线程可以访问别的线程的局部变量

答:(饼送到嘴边了)额,对,如果按照我一个stack的想法是可以访问的,那他应该是跟随线程的,一个线程配一个?

问:C++多态的虚表有了解吗

答:有,C++对象模式是这样,有个虚表指针,成员变量跟着,成员函数在外,子类虚函数会覆盖基类虚函数所在的位置完成动态多态

追问:那如果一个子类继承了多个基类呢,里面会有多少个虚表

答:额...难道不是一个?

引导:那我们知道子类可以向上转换成基类,多个基类的话,我们怎么转化?

答:噢噢噢噢,那是有多个,内存里面有多个虚表指针,然后虚表里头有个类似叫offset的玩意,来进行起始地址偏移,大概是这样,具体排布我记不清了

问:好,那再问一个,MFC的消息机制你了解吗?

答:不太了解,我都是查MSDN的

好,剩下就是反问环节了,大概问了业务和美国对接的问题,面试官给非常详细的说了,从整个大组讲到具体team,大概说了快10min,中间还给我带跑题了....

--------------------------------------------------------------------------------------手动分割线-----------------------------------------------------------------------------------------------------------------------------------------------------------

二面:
上学的时候老师说过,以后你可能记不得哪个老师教学能力特别强,但一定会记得和你一起扯八卦的老师。

二面的面试官不苟言笑,整场面试给人以深思熟虑,认真负责的感受,嘴角不曾泛起一丝波澜。

刚开始是自我介绍,然后一些形而上学的问题,比如你有啥兴趣爱好,你的优缺点是啥,你如何进行自我学习什么的,问题很常规,但如果你以严肃的态度问出这样的问题,就有种特别的魔力。
我企图逗笑一下面试官,缓解缓解气氛,但是失败了。

因为形而上学搞了时间比较长,我以为这面就是聊聊天,随便问几个简单技术问题就好了,但是后来证明我还是太年轻。

问:你对内存的划分有什么了解?
答:大概知道是用户空间和内核空间

追问:那内核空间在高位还是在低位
答:应该是在低位,因为他要兼容16位的系统,我猜是在低位(这里不对,应该来是说内存还有null指针区以及保留区,用来做内核空间和用户空间的隔断,且地位0x0000位置也是禁止访问的,内核区在高位)

问:应该不对,是在高位的
追问:那用户空间里头是怎么划分的呢?
答:额...我大概知道有heap,stack,静态变量区,常量区还有代码区

问:一个进程里头有几个heap,几个stack
答:(菜鸡如我,又掉坑)heap跟随进程,stack跟随线程

引导:不对吧,你如果在一个线程里头new了一个对象,然后在另一个线程可以delete吗
答:额...按我那样说确实不对,除非系统做了额外保护,所以应该是跟随线程

问:那你知道const和define啥区别吗
答:额...const和define是两个玩意吧,没啥相同的吧。define是个定义宏,比如define ll long long,而const是个修饰?有const 变量, const 指针, const 引用, const 函数四种用法,按照自己的理解讲了讲

问:那你知道vector吧?在vector中使用结构体有啥要注意的
答:(内心OS,这个问题搁面经看到过,当时没查出所以然啊,只能自己瞎编了,估计和写面经的人碰到一个面试官了,面经上还问了消息机制,这个哥们准备了,可以牛逼...然后面试官没问)
额...vector是这样,vector本质就是个数组,只是他是不定长的,他的机制是在申请的内存空间被使用2/3之后会重新申请2倍的空间,然后把内容拷贝过去,所以我们的自定义结构体需要拷贝构造函数,如果需要排序的话,还需要重载小于操作符。(事实证明面试官想问的不是这个,他应该是想说对于template来讲,不能够使用局部变量,要用全局的定义吧...但我确实不会)

追问:那这个2/3是怎么来的?
答:额...我只记得这个数,怎么来的我没研究过

追问:好,那我要设计一个结构体,让他无法出现在stack要怎么做
答:还能这样做....?局部变量是放在stack的,难道我把构造函数禁了?那也无法new了啊...我想想哈

引导:换个说法吧,我要设计一个结构体,让他无法出现在heap要怎么做
答:哦哦哦,把new 或者 malloc禁了在结构体里
噢噢噢噢,我知道stack了,在结构体里头另起一个变量,把构造函数做private,暴露一个函数,把所有的局部变量都转换成new来申请空间,大概这样,对不对?

问:差不多这个思路吧
答:脑壳疼....

问:postmessage 和 sendmessage啥区别?
答:post丢到消息队列就返回,不等结果,send要等结果

问:一个程序(窗口?)只启动一个实例怎么做(用什么函数?)
答:题目记不大清了,答的不好。讲了下对于驱动来说,我们会给他起个别名,像符号连接名这样,这是唯一的,然后调用create方法的时候,会自动去查找是否有相同名字的以及启动了,如果有就直接返回一个类似handle的东西,如果没有才启动,windows用户态应该也是类似。(这里应该没答到点上,那时候就想到单例和这个,然后只答了这个,其实注册表写东西,往文件写东西应该都是常用方法)

问:我要启动一个三角形的窗口用什么函数
答:这个真不会...

问:__stdcall和__cdcel 调用方式上有什么区别
答:这个...我大概只记得他们是C编译和C++编译的区别了,然后一个函数比如FOO来说,__cdcel是编译成FOO@8这种格式然后__stdcall是翻译成FOO@ii这样的格式的

引导:这是多态的支持,调用上什么区别,比如参数入栈
答:参数入栈都是从右到左放到栈里面的,然后再把返回地址丢到栈里头去,然后调用函数,被调用的函数再来用栈顶+8,+12这样取用参数的,一半是放在eax这个寄存器里头的....
(很明显没答到点上,面试官是想问处理栈平衡上的区别...我确实没用心记这玩意)

问:C++11 了解不
答:只了解一些智能智能和右值引用

追问:智能指针说一下
答:blablablabla

问:伪函数了解吗
答:只懂概念,没用过。类里头重载()操作符,可以实现传递操作,与函数指针的区别没研究过...


问的问题比较多,有些问题记不住了,以至于二面问题的连贯性较差。最后反问我还是问了老问题,业务是咋样,两个面试官讲的差不多,举得例子也几乎一致。

最后面试官总结了以下,C/C++ 基础还不错,windows编程(Windows API?)缺一些,然后问了问我上一份工作的工资以及通过了啥时候能到岗,一周内会给我答复...(听着像是会有好消息吧:D)

PS. 这个面经写的真累,脑壳痛。

--------------------------------------------------------------------------------------手动分割线-----------------------------------------------------------------------------------------------------------------------------------------------------------

终面:
本来是说终面由杭州的大BOSS出面聊一聊,大致就是20min,大致就是混一混脸熟,不会问太多技术问题。但是大BOSS临时有事吧,换了一个交叉面的leader,而且可能怕我误会没有提前通知,导致终面重回二面的状态,而且还是突然袭击,问了相当多的技术问题。

交叉面的leader和前面的面试官比起来更重视应用和调试经验吧,与本组的面试官风格不太一致。

问:vector 中要删除2个元素(多个元素)要怎么处理
答:vector中有两种删除方法,remove和erase,remove是把元素放到最后,不释放空间,erase释放空间,会造成迭代器失效。最保险的方法是每次删除从头开始++,然后找到要删除的位置开始删除

追问:(笑) 那这个复杂度太高了
答:对,太高了,那我们可以保存我们要删除的迭代器前面一个迭代器,然后用前面一个迭代器继续更新操作,或者把要删的remove到最后,一次性再删除

追问:这不是标准做法,你一会可以去查一下
答:好(很久没用erase了,简单查询后发现,erase会有一个返回值,拿这个返回值直接处理就行了)

问:C++ lambda表达式了解吗
答:没太用过

问:类的拷贝构造函数了解吗,什么时候会调用?
答:额...拷贝的时候会调用?具体来说就是我们已经有了一个实例化的A,然后要完全复制这个A的内容,形成一个B,这时候就会调用拷贝构造函数。然后,拷贝构造函数的形参是const 引用,这样可以防止修改,也可以防止出现递归调用拷贝构造函数的情况

追问:指针和引用啥区别
答:引用就是个别名,没有自己的地址空间,指针是有自己的地址空间的。引用不可以为空,而指针是可以为空的。

追问:那你讲讲智能指针
答:blablablabla

追问:浅拷贝和深拷贝的区别
答:浅拷贝和深拷贝都是针对指针的概念,浅拷贝指向同一片内存,深拷贝把内存也拷贝一份,指向不同的

追问:现在我们有一个类A,A的里面有有个成员变量也是自定义类B,这时候我们要重写拷贝构造函数,要怎么做?
询问:成员变量B是一个指针还是就是一个普通的变量?

追问:是一个普通的变量
答:如果是一个普通的变量那不存在浅拷贝,只有深拷贝

追问:那他是一个指针
答:浅拷贝只要正常操作,声明一个指针指到B就行,而深拷贝需要声明一块空间,然后调用B的拷贝构造函数,再把指针指向新的内存位置

问:异常怎么处理
答:throw出来?

追问:具体一点系统和用户态都需要怎么处理?
答:系统会保存我们当前这个造成异常的汇编地址,可能是保存在stack里面,如果这个异常被正确处理了,系统会回到这个地址再次执行这条语句,然后接着干活。对于用户态程序来说,可能要注意把我们声明出来放在heap里的东西释放掉?

追问:大致是这样
答:后期没有去查询,有点累了...有朋友知道更详细可以说一哈

问:stack和heap啥区别?
答:stack放局部变量,heap放new出来的玩意。stack要连续,heap可以不连续

问:虚函数和纯虚函数什么区别?
答:纯虚函数无法实例化,子类必须实现纯虚函数,类似Java指针,虚函数可以被实例化,不一定要被子类覆盖实现

追问:对象模式你说一下
答:blablabla,见一面

追问:继承两个不同的基类呢
答:blablabla,见一面

问:我们知道程序奔溃后会形成一个core dump文件,如果不能使用windbg那我们要怎么查找问题?
答:额...如果不能用windbg,那是不是stack被踩塌了,那我们只能根据esp寄存器来找它的调用顺序了,然后打log,找出哪里崩了?

追问:对,这是比较复杂的一种情况,dump文件损坏了,这可能查不出来,那如果没损坏呢
答:没损坏直接windbg啊

追问:对,那不用windbg呢
答:额...你是想问windbg解析dump文件的原理啊

追问:对,看看你有没有做过
答:额...我没用过,我大概猜是这样,汇编里面的调用函数多会用到esp寄存器,然后被调用函数会临时保存esp的值用到ebp寄存器,返回值多在eax寄存器中,大致是抓这几个寄存器的值吧

追问:额...差不多,是这几个点,理论对了,但是理论和实际操作还是有一些区别
答:对...

问:windows API的调用过程说一下
答:大致是这样,我们使用的API 多是win32 API,然后win32 API 会调用Native API,由Native API开始陷入内核态,调用具体的内核外围组件,然后有需要的话再调用内核

问:windows 消息机制
答:windows是消息驱动或者说事件驱动的,有两个消息队列,一个是系统消息队列,消息先进入到系统消息队列,然后由系统消息队列分发给对应的进程。另一个消息队列是进程中的,如果进程启动了一个窗口,他就会有消息队列,然后他是以消息循环的方式,从消息队列中取出消息,发给窗口。这个是让权等待的,如果消息队列中没有消息,它就让出CPU

追问:消息循环怎么实现的?用了什么函数?
答:起一个线程一直while?用getmessage

追问:具体一点,拿消息后怎么做?
答:额...根据消息的title或者消息头之类的,dispatchmessege吧

追问:消息循环怎么终止?
答:额...大概有个进程终止信号,或者终止消息进到getmessage,然后特判一下把进程杀掉吧

追问:postmessage和sendmessage什么区别
答:blablabla,见二面

问:你们平常多人协作开发吗
答:额...什么算多人协作,用git就算吗?

追问:用git也可能大家领个模块去干就好了,比如你会去修改别人的类吗
答:很少,我一般使用别人的类,如果要别人的类增加功能,我会和他打报告,让所有者帮我增加代码(这里加上设计模式的 开放 - 封闭 原则会更好)

问:如果对同一个功能有两个方案A、B,你会怎么做?
答:额...开会讨论啊,然后确立一个方案,开始干活

追问:(微小) 还有吗
答:额...这只有两种可能吧,一种讨论确立,另一种两种方案分开干

追问:分开干不大现实,太花时间了(腾讯不就是这样,养蛊政策)
追问:那这样,你设计了A方案,同事设计了B方案,你们一直讨论一直争吵怎么办?
答:找领导拍板啊,每个功能设计肯定要有一个最终能够下决心的人

追问:领导用了B方案,后来开发途中各种,你就一直说早就知道有问题,应该用A的
答:这时候只能闭嘴吧,开会时啥都能说,开完会啥都不能说,只能干活了吧。

好,你有啥想问我的?
在zoom拥有什么样特质的员工能够得到更好的发展,或者说我们zoom在招聘员工的时候更愿意要什么样的员工?
blablabla,更多要求技术吧。

然后切了HR聊天,HR非常非常非常能说,咕噜咕噜嘴巴不停的,也不需要喝水,我坐着听都听得口干舌燥,补了好几次水,HR都不用的,后来还是HR临时要接另一场面试,才结束的...
最后忘记问问HR学啥的,这么牛。

最后这场面试过去的时间虽然不长,但很难记忆起技术官具体问了什么,可能太散乱了吧...















#面试复盘##面经##社招##ZOOM##C++工程师#
全部评论
大佬,想问问技术岗有英文面试吗(我英文太菜了/(ㄒoㄒ)/~~)
1 回复 分享
发布于 2021-08-15 16:14
楼主入职了吗
1 回复 分享
发布于 2022-03-20 21:12
感谢分享
点赞 回复 分享
发布于 2021-08-11 12:32
大佬 offer收割到了吗 什么待遇啊?
点赞 回复 分享
发布于 2021-08-27 22:39
这个岗位做什么的啊
点赞 回复 分享
发布于 2021-08-31 10:13
好玩哈哈哈哈
点赞 回复 分享
发布于 2021-09-03 00:36
去了么,感觉咋样
点赞 回复 分享
发布于 2021-12-06 16:47
一个线程new的东西另一个线程不是可以删么 堆区是共享的 就是不符合规范吧
点赞 回复 分享
发布于 2022-03-20 22:34
这问的也太难了
点赞 回复 分享
发布于 07-09 15:50 上海

相关推荐

#腾讯光子面经##软件开发笔面经#腾讯(光子工作室--后台开发1. 定义和声明的区别?2. 说一下static 3. 介绍一下const4. map 和list区别5. C++11的特性有哪些6. 静态库和动态库的区别7. 哈希冲突解决的方式有哪些8. C++怎么实现多态的9. 虚函数底层怎么实现的?10. 指针和引用的区别11. 线程和进程的区别?12. 协程呢?什么时候用线程,什么时候用协程13. malloc和new的区别14. SLT中,sort的第三个参数,判断相等的时候返回true 还是false为什么?15. STL中 vector是怎么扩容的?xia16. 介绍一下快排,是怎么实现的17. 快排有哪些不足的地方,怎么优化18. c++17的标准有用过吗?19. core文件怎么生成?20. gdb调试,怎么调试到线程级别的?21. mysql都有哪些存储引擎,介绍一下?22. Mysql 慢查询?23. mysql什么情况下会进行分库分表?24. TCP timeout?25. TCP 粘包26. epoll在不考虑服务器内存 网卡的情况下最大支持多少并发?27. 说一下简单的web服务器用C++怎么实现? Socket28. recv()函数返回值,什么错误是可以接受的?29. http建立连接的过程?30. 主机字节序和网络字节序31. Linux  命令 nm iostat ln32. 硬连接 软连接33. Perf 底层怎么实现的? 让你设计一个perf怎么做?34. 游戏服务器和客户端的连接,你觉得采用TCP还是UDP35. 为什么换实习了?36. 有了解那些分布式的架构吗(好像是这么说的)37. 介绍一下zookeeper 38. 说一下一致性哈希39. 说一下raft40. redis有了解吗。41. 我看你用过docker, 有用过k8s吗?42. 给你10亿个数据,怎么找出重复最多次的10个数Coding翻转对二进制求和给你10亿个数据,怎么找出重复最多次的10个数
查看45道真题和解析 软件开发笔面经
点赞 评论 收藏
分享
评论
45
241
分享
牛客网
牛客企业服务