京东二面面经详谈

收到了京东的二面电话,我觉得这次面试有一定的广度和深度,也和面试官发生了一些争论,是一次挺有意思的面试,遂详细记录之。


面经:

首先一上来面试官让我做了一下自我介绍,经过了总共大约四五次电话面试,遇到这样的问题已经是很多次了,但是我还是简单表述了一下自己的技能栈就结束了,这个其实还可以再多说很多。

接着面试官问了一下我的学习过程(刚开始我没搞懂面试官说的学习过程是什么意思,后来了解到是自己的教育经历)。然后我表达了一下自己大连理工大学软件工程大三学生的状态。

紧接着面试官问了下我的必修课有哪些。我说了下计算机网络、操作系统、数据结构与算法、编译原理(实际上当时我不太敢说编译原理..感觉自己编译原理确实已经忘很多了)。面试官对我的计算机基础很感兴趣,说我的笔试成绩很高(京东之前有一个笔试),但是事实上京东那三道算法题我只AC了两道..顶天也只能是80了,可能选择题做的比较好?于是面试官便开始考察起了我的计算机基础。

面试官:常见的排序算法了解吗?

我:嗯,有一些了解。常见排序算法可以分为三种时间复杂度,O(n+k),O(nlog2n),O(n^2)。O(n^2)的排序比如冒泡排序、O(nlog2n)的排序比如快速排序、归并排序、二分插入排序,对于基于比较的排序算法这个时间复杂度已经不能再低了,然后O(n+k)时间复杂度的排序比如桶排序、基数排序、计数排序(可能是这个地方复杂度说多了..面试官后面很大篇幅在问我时间复杂度)。

面试官:恩,我懂你的意思了,你对排序比较了解。你能说一下常见数据结构吗?

我:我能以数据结构在Java中的体现了举例子吗?

面试官:我觉得emmm数据结构应该和语言无关吧...

我:那好吧,我以为您更想听的是Java中的数据结构。常见的数据结构简单的有链表、队列、栈、二叉树,稍微复杂一点的比如B+、B-、B*、红黑树、图等。

面试官:那现在有10w个数字,你如何找出一个最大的那个数字呢?

我:堆(不知道怎么会说出这个答案...很迷了)。(当时脑子有点抽,这个和后面几个数据结构相关问题都说的挺迷)

面试官:blablabla说了一些,大致意思就是你不觉得这个时间复杂度有点高吗?

我:(恍然大悟)实际上一次遍历O(n)时间复杂度就可以找出最大值,用一个temp变量更新最大值,直到遍历完所有数字。

面试官:(打断了我)你不用说得太细,就是一次冒泡对吧。那10w数字如何找出最大的前20个数字呢?

我:这个地方我觉得可以使用最大堆(脑子抽了,为什么是最大堆),可以在O(nlog2n)时间复杂度解决这个问题。

面试官:(感到奇怪)为什么是最大堆呢?

我:可以建一个结点个数为20的最大堆,遍历完所有数据,停留在堆中的结点就是top 20(我当时还是没反应过来)。

面试官:那么如果现在堆中的元素是1,2,3,...,20,你有一个19节点,你是放入还是不放入呢?

我:(还是没有反应过来不是最大堆而是最小堆)我觉得可以将堆的根结点替换为19,然后调整位置,判断最终19还在不在这个堆里。

面试官:那你这个行为很尴尬啊,是不是每个结点你都需要放入堆中然后调整呢,这样不觉得很不对吗?

我:(还是没反应过来)我觉得可以对这个最大堆的数据结构再进行一个封装,添加入最大值和最小值属性。

面试官:你能说一下最大堆的定义吗?

我:(说实话我忘了我当时怎么答的了,我说的很错)

面试官:不对,最大堆的定义是这样的,对于一个结点,其子节点值不大于他的值的完全二叉树。对不对?

我:对...

面试官:(可能觉得引导不出我的正确答案了)你这个地方为什么不用最小堆呢?每当需要查看一个结点是否可以放入堆中,你直接看这个结点的值和根结点的值不就好了?

我:(恍然大悟..)嗯..是这样的

面试官:那我们再来聊一下时间复杂度。你觉得平均来说,这个算法的复杂度在多少?

我:建堆过程是O(n),之后放入每个结点调整的时间复杂度是O(nlog2n)。

面试官:(吃惊)为什么建堆是O(n),你可以证明一下吗?

我:(我也吃惊..那个一长串的求和公式化简就是O(n)线性时间复杂度,这个在电话里面说不清楚..听到这个问题我楞了一下)我觉得这个问题很难说啊..但是可以用数学公式证明建堆过程的确是O(n)时间复杂度。

面试官:不对,建堆过程应该是O(nlog2n)时间复杂度,你如果硬要说是O(n)你可以证明吗?

我:(这个怎么在电话里证明..有一些绝望)这个确实在电话里很难证明,但是我觉得建堆确实是O(n)时间复杂度。

面试官:不对,我可以明确地告诉你,建堆是O(nlog2n)时间复杂度,你下来可以查一下。

我:(还是坚持建堆是O(n)时间复杂度)我还是觉得建堆的确是O(n)时间复杂度,当然我可能记错了,但是我还是希望我们能下来确认一下,建堆的确是O(n)时间复杂度。

面试官:(我感觉面试官有些无奈了)你之前说过基于比较的排序时间复杂度上限是O(nlog2n),这样的话岂不是你自己的话就自相矛盾了。

我:(我也有点懵了,觉得不应该再争论下去,本质上还是自己知识不过硬)那可能我记错了...

面试官:(突然一愣)是不是你说的建堆和我说的建堆不一样,你是不是把建堆想成将20个元素放入到堆中但是不调整啊?那样的确是O(n),但是我们这里说的建堆是建好这个堆,不只是放进去。

我:(其实争论了挺久,文字上看不出来这么长的时间,我也有点动摇。本质上还是自己知识不过硬,我动摇了。)恩,那可能我建堆概念理解错了。

(我下来仔细确认了这个建堆时间复杂度的问题,并不能说谁对谁错。从空堆开始,依次插入各个关键码,这个时间复杂度确实是O(nlog2n)。但是事实上有一种叫做筛选法的建堆方法,完全二叉树大小为n,对于结点编号(从0开始作为第一个)为n/2-1的结点开始,判断这个结点为根的的子树是否满足最大堆性质。满足,不做调整;不满足,做出调整。直到从n/2-1到结点0,整个完全二叉树就变成了堆。时间复杂度为(2^i)*(log2n-i)从i=0到i=log2n进行求和,时间复杂度趋于线性,也就是O(n)。关键在于我们理解的建堆算法出现了差异,所以对建堆复杂度的理解产生了一些不一样的看法。但是由于本质上还是自己基础不扎实,不敢继续争论下去,所以与真理擦肩而过...)

面试官:好,那么现在我们达成了一个共识,建堆是O(nlog2n)时间复杂度,基于这个共识,我们来看下面的问题。10w数据,选出top 20,使用最小堆,时间复杂度是多少?

我:nlog2n。

面试官:详细一点,比如n是多少?

我:100000log2 20

面试官:好,那么如果前20个结点就是top20,时间复杂度是多少,以建堆时间复杂度为O(nlog2n)为基础。

我:O(n)   (我这个回答很粗...)

面试官:(可能还是想引导一下我的正确答案)前20个结点建堆时间复杂度是多少?

我:20log2 20

面试官:那后面10w-20个结点呢?

我:O(n)

面试官:那总的时间复杂度是不是20log2 20 + 99980?

我:是的。

面试官:好,那么我们接下来来看看计算机网络吧。你能说一下TCP的三次握手吗?

我:(回答不详细写了,这个问题太常见了)....

面试官:那你能说一下断开连接的四次挥手吗?

我:(同 略)....

面试官:嗯,那么比如我现在在浏览器敲入www.baidu.com,并且在搜索框中输入了词条,点击搜索,整个过程发生了什么呢?

我:首先会进行DNS解析,将www.baidu.com解析为一个IP地址...

面试官:(打断了我)什么是DNS?

我:DNS是域名解析协议,运行在53端口号,主机会对代理服务器发出递归的解析请求,然后这个代理域名解析服务器会向其他服务器发出迭代的解析请求。

面试官:好,那么DNS是一定会发生的吗?

我:不是的,存在浏览器缓存、主机缓存、服务器缓存,甚至还有Hosts文件。

面试官:嗯,事实上www.baidu.com这样的域名在代理服务器一定是有缓存的。那么接下来发生了什么呢?

我:域名解析出来了ip地址,同时也解析出来了端口号,主机就会向这个主机对于端口号建立连接,然后传输数据...

面试官:(打断了我)等一下,这样说的话所有用户都是连接同一个主机,像www.baidu.com这样的网站,一台主机根本不可能让他维持在6个9可用率上(这个我解释一下,就是99.9999%的可用率)。

我:(这个我是真的不了解,但是我还是猜了一下)这个我可能不太了解,但是我觉得这个ip每次解析出来对应的一定不是同一台主机,可能这是一个集群,只不过是通过了DNS解析返回了不同的ip,或者做了反向代理什么的。

面试官:blablabla(说了一堆东西....我其实记不太清了,但是我觉得面试官在这个方面应该是个专家...)

面试官:那现在假如建立了连接,服务器端发送完数据了,现在还要发送,会怎样呢?

我:我觉得这个主要是看这里是长连接还是短连接。HTTP头部有一个Connection字段,当为close的时候为短连接,为keep-alive的时候为长连接。短连接则需要重新建立连接传输数据,否则就在当前连接上传输数据。

面试官:恩。你自己做过一些项目吗?

我:blablabla (说了一点)

面试官:那现在给你一个真实场景,嘀嘀打车,你如果需要客户下单,然后司机接单,你来实现,会怎么实现?

我:(感觉可能面试官想考察我的高并发程序涉及思路)这是一个高并发场景吗?

面试官:不,就考虑最基础的。

我:那么我觉得可以用生产者-消费者模型来实现...

面试官:(再次打断了我)太粗糙了,说说细节。

我:将用户的唯一标识、出发时间、出发地点、到达地点包装成一个请求实体,放入到队列中,然后司机从队列中取出,返回一个已收到并且确认订单的信息。

面试官:(可能不太满意,但是还是没深究这个问题)那么这个请求你用什么协议来发送呢?

我:TCP

面试官:为什么是TCP?HTTP不好吗?比如现在微信,你觉得是用TCP吗?

我:(不敢乱说)我觉得不一定,可能是其他协议,但是一定有自己的方法保证传输的可靠性。

面试官:(我感觉他不满意)好吧,你后面想读研吗?

我:暂时没有这个打算(后面说了一些自己的看法)。

面试官:你的实习时间可以是多长?

我:都可以。

面试官:恩,那我的问题就问完了,你有什么想问我的吗?


我其实在面试的过程中一直觉得面试官思维敏捷,知识面很广,就忍不住问了一下面试官的履历...结果发现面试官08年毕业,在外企干了一段时间,自己创业过,百度干过三年,腾讯干过三年,后来积累了许多云相关的知识,想要做一些相关工作。自己也拿到了阿里云、腾讯云、京东云的offer,但是自己觉得阿里云和腾讯云都是体系很成熟了,于是选择了京东云,毕竟京东云是从16年才开始认认真真做起来的。然后面试官和我说了一下他的看法,他觉得自己还是想在一个技术不是那么成熟的地方认真做,而不是去一个技术很成熟的地方去修修补补。面试官在最后说了很多,确实也觉得面试官很有想法而且很厉害。最后面试就结束了。


感觉和这些优秀的前辈交流确实是一件很开心也很值得的事,通过一次面试得到了很多东西,看到了自己的不足,也看到了一位前辈的技术履历和独到的看法。


确认复试已通过,等候HR面。

猜你喜欢

转载自blog.csdn.net/qq_35580883/article/details/80044446
今日推荐