前言
首先说一下笔试,可以参考我知乎的回答(链接),只能说真的是难炸了,两个半小时的答题时间我只坚持了一个多小时就投降了,四条题目只做了一条,当时还痛骂了网易一顿,完全没有进入面试的心理准备,结果十月假期刚过告诉我笔试通过准备面试。。。我也是醉了。
面试前我上网搜了以往的网易的面经,简单看了一下,发现完全不是自己能应对的问题,于是看都没看直接放弃了,坐等今天面试被羞辱,结果发现,今天的面试过程整体都很愉快,面试我的人超级好,我有问题答不上来他都会引导我去思考问题,就是自己太不争气很多问题还是没答出来。
面试问题
1.解释一下vector的底层实现以及扩容机制,还有map,最后还有hashmap解决存储数据过多的解决方式。
hashmap当存储数据太多的时候可以再重新申请一段大的hashmap空间,然后再哈希。当使用链地址法时可以将链地址转换成二叉树的形式。
2.鸡蛋问题(两个鸡蛋,100层楼,找到鸡蛋刚好摔碎的楼层,求最坏情况下访问最少的方法),这个问题是网易每年都会问的题目,面经上看到了,然而我并没有仔细看…
一开始回答的是10层10层的扔,这样最多的访问次数就是19次。
然后面试官说这么做其实就是将楼层分成10个区间,但是在每个区间内的最坏访问次数都不相同,再想想有没有一种分区间的方法可以使每个区间的最坏访问次数都相同呢?
看我答不出来面试官就直接告诉我答案,假设第一个区间为1–n,那么在第一个区间内摔坏的最多访问次数就是n,第二个区间为n+1–2n-1,那么在第二个区间内摔坏的最多访问次数也是n(因为第二个区间的元素个数比第一个区间的元素个数少一个),依次类推,当总数为100时,n的值计算出来就是14。也就是说按区间划分可以是:1–14,15–27,28–39…。然后恍然大悟,而且好像跟之前学到的哪个算法有点像,但是忘掉了。。。
3.多态问题的理解,为什么要用父类指针来接受子类指针而不直接创建子类对象呢,这么做有什么好处?指向子类的基类在调用虚函数实现方法时在哪个阶段知道其使用的是哪个类的方法?虚函数表存在内存的哪个位置?析构函数可不可以作为虚函数?智能指针是什么?
父类指针接受子类对象是当定义一个函数要对该基类所有的派生类都做某种处理的时候就必须要将子类对象转换成父类对象,这样针对所有派生类都只需要写一个方法就可以了,传入的参数就是父类的类型,极大的简化代码。
通过对象名调用虚函数,在编译阶段就能确定调用的是哪一个类的虚函数,所以属于静态关联;如果通过基类指针调用虚函数,在编译阶段无法从语句本身确定调用哪一个类的虚函数,只有在运行时,指针指向某一具体对象后,才能确定调用的是哪一个类的虚函数,故为动态关联。
虚函数表的位置,其实这个问题水蛮深的,首先知道程序所用内存分为5大区:栈区,堆区,程序代码区,全局数据区(静态区),文字常量区。而虚函数表有以下特征:①全局共享,只有一个。②虚函数表类似一个数组,类对象中存储vptr指针,指向虚函数表.即虚函数表不是函数,不是程序代码,不肯能存储在代码段。③虚函数表存储虚函数的地址,即虚函数表的元素是指向类成员函数的指针,而类中虚函数的个数在编译时期可以确定,即虚函数表的大小可以确定,即大小是在编译时期确定的,不必动态分配内存空间存储虚函数表,所以不在堆中。因此虚函数表存在全局数据区。
虚函数一旦确定了指向就只会调用派生类的而不调用父类的,因此析构函数可以作为虚函数。
c++11支持的智能指针有unique_ptr,shared_ptr, weak_ptr,具体的就没有再了解了。
4.如何判断链表是否有环?
我只知道用死方法,从头结点开始访问,将每个访问的地址使用set存储,每访问一个都判断是否已经有该地址,总的时间复杂度是nlogn。(他没有跟我说更好的方法。。。)
5.有个英雄释放技能,是在他的周围一圈随机释放一个陨石,要求设计算法使每个随机落点的概率都相同。
先想了一个极坐标方法随机一个角度,一个0–r的值确定唯一点。然后被指正说内圈的概率要高于外圈的概率。后来又想直接随机x,y的值,然后判断一下是否在圈内,后来他说如果连续1000次都在外圈那么玩家会等好久都没有技能释放出来。然后我又想混合一下,随机x,y,在外圈的情况就直接在该方向上随机一个长度就好,然后他想了想说好像也可以。最后我问有没有更好的方法他说有,但是不能告诉你(然后一阵坏笑哈哈哈)
然后吃晚饭的时候想了想好像可以把园中的像素点分为n个区域,然后n个区域又分为n个区域,然后计算出n^n=总像素点的解,这样求n次随机值就可以得到一个均匀的解了(只是个人猜想,不知道是否合理)
6.4次挥手的实现过程,为什么建立是3次而断开是4次?
A给B发消息:“我打算关闭了!”
B给A回消息:“你的消息我收到了!但是我活还没干完,等我一会!”
B给A回消息:“好了,我活干完了!”
A给B发消息:“好的,我挂断了!”——同时等待一段时间后关闭
B收到消息后立即关闭
至于为什么4次,其实就是防止一方立即断开而另一方还在准备断开的情况,这时如果重启主动断开方的客户端再次请求,而被动断开方还在准备断开的过程中就会出现请求码错误。(猜的,有一篇博文关于4次挥手写得不错,链接)
最后的提问以及总结
最后提问了一些春招和社招相关的问题,以及网易是不是和空宣说的一样只要工作做完就可以随便娱乐(属实)。
校招进去的人有选择之后从事方向的权利,而社招进去的就是做什么方向就进什么项目组。
感觉网易一面不是特别要求你有很多的开发经验,重点是看你对某些基础知识(C++,计算机网络)的理解是否深刻,同时也会考验你的思维活跃程度,当你不会某些问题的时候会给你适当的提醒,看看你是不是深刻的理解了,场景题和智力题也比较多。总得来说面试过程非常愉快,我也和面试官坦白了我是抱着必挂的心态来面试的,但是对网易是真的非常的向往。这次怕是没有机会了,再战春招,不放弃!!!