你好,我是yes。
上周一位读者给我发了他最近秋招美团的面试题,大概面了一小时40分钟,他说题目答的还行,只不过智力题的话没答好,对校招来说这就有点悬了,所以校招的小伙伴除了技术题,智力题也要好好准备下~
这篇文章,我把这些题分享一下,大致可以分为计算机网络类、Java基础类、JVM类、redis、mysql,最后还有个智力题,可以看到涉及的知识点还是比较广的,就少了个操作系统的。
先列举下题目,然后我会就个别题目分析一下。
上面这些题目,之前我的面试仓库都包含了,大部分就不作解答的,大家可以自行去网站上查找。
有个别没提到的,或者稍微难一点的,我这里拿出来提下:
ArrayList中的数组为什么用transient进行修饰?
我们都知道 transient 标记的字段代表不序列化,而 ArrayList 的数组用 transient 当然就表示其内部的数据不序列化,那岂不是数据要没了?
并不是的。之所以这样标记,是因为我们数组的实际大小会大于真正的元素量,比如你的数组长度是10,实际上里面就只有5个元素。
如果正常序列化的话,那会把空值也给序列化了,所以为了只序列化实际有值的元素,ArrayList 用 transient 标记了 elementData字段,然后再实现了 writeObject 和 readObject 方法,里面的实现逻辑是只会序列化实际存在的元素。
简单来说就是为了避免多余元素的序列化,用 transient 标记了 elementData 字段避免使用默认的序列化方式,定义了 writeObject 和 readObject 实现了自定义的序列化方式。
老年代引用新生代,除了 gc root 还用什么?
这个场景就是假如当前要进行新生代 GC, 那可能存在老年代到新生代对象的引用,这部分如果要全区域扫描老年代,效率就低了,所以弄了个记忆集(Remembered Set)来优化这个跨代引用场景。
而记忆集的实现,一般用卡表,简单理解就是不是精确到具体老年代哪个地址对新生代有引用,而仅仅是一块区域对新生代有引用,这样记忆集就不会那么大,扫描起来也不会那么多,毕竟一个区域可能有好多都引用的新生代,还能合并一起标记了。
出现以下几种情况的话,你觉得是出了什么问题 ?
结合 5 点一起来看:CPU 不忙了,gc有抖动,但是年轻代基本稳定,老年代内存一直在变,说明对象应该是直接进去老年代,但是这些对象的生命周期又比较短,所以老年代内存涨涨涨,GC 了之后又下来,然后又涨涨涨,这就叫抖动。
那什么样的对象不进新生代而是直接到老年代?
是大对象。
跟着 GC 抖动的同时,线程数也在抖动,那说明肯定是哪块业务一次请求,new了很多线程,线程里new 了很多大对象,所以老年代大小就上去了, GC 就开始操作了。
等这波线程任务执行完之后,线程就关闭了,对象也就可以回收了,GC操作完之后,老年代大小又降下来了。
基本上就是这么个情况。
好了,今天就说这么多,关于 mysql 的那个 change buffer 啥的,等我下篇吧,一起把 mysql 里面的各种 buffer 盘一遍,比如啥 Log Buffer、Double Write Buffer 等等。
其实上面这些问题都不是很难,最关键的还是看你有没有理解。就拿跨代引用的那个记忆集来说,肯定不会直接问你记忆集是什么,而是拐着弯的问,你只有理解了你才能联想起来。
包括 5 个因素的 GC 分析题,其实也是一样的,你需要理解整个 GC 的流程和原理,死记硬背的话这些题吃不住的。
好了,关于上面别的题目有疑问的话可以留言,我会选择性的给予解答,更多的其实我的面试仓库里面都整理了,可以去看看。
我是yes,从一点点到亿点点,我们下篇见~
#美团##面试##秋招#