腾讯Java后台开发一面面经整理

腾讯Java后台开发一面

一面:
1 有序数组排序,二分,复杂度

2 常见排序算法,说下快排过程,时间复杂度
首先设置一个标志位数字,一般选取第一个数作为标志,然后从右向左找到第一个比标志位小的数字,再从左向右找出第一个比标志位大的数字,两个数字交换位置,继续该过程,知直到左右两个方向的查找过程相遇,此时第一个标志位数字到达最终位置。接着以此位置为中间点,左右两部分数组分别递归执行该过程,最终即可完成快速排序。
时间复杂度是NlogN,因为递归栈的深度是LogN,并且需要执行N次。
空间复杂度是LogN,因为递归栈的深度是LogN。

3 有N个节点的满二叉树的高度。
1+logN

4 朋友之间的点对点关系用图维护,怎么判断两人是否是朋友,并查集,时间复杂度,过程。
该问题可以拆解为以下过程,其实就是建立并查集的过程。
初始化元素
实现元素与元素间的联合操作(设置元素的父节点)
实现查找元素所在树的根节点(一直往上找父节点,知道知道根节点)
判定两个元素是否在同一棵树上(如果根节点相同,那么它们自然是相连的)

5 单元点最短路的方法,时间复杂度
单元点最短路径问题可以使用迪杰斯特拉算法解决,这里就不赘述了。时间复杂度为O(N^2)
迪杰斯特拉算法

6 如何实现关键字输入提示,使用字典树,复杂度多少,有没有其他方案,答哈希,如果是中文呢,分词后建立字典树?
使用字典树是比较好的联想输入方案。

7 hashmap的实现讲一下吧,讲的很详细了。讲一下红黑树的结构,查询性能等。
hashmap基本上是Java面试必问的内容了。这里我把常见的考点都列举一下。
hashmap的数据结构:数组加链表的结构,hashmap类中会维护一个entry类型的数组,里面保存的是entry对象,entry对象包括key和value。
用户在添加一个键值对时,hashmap会首先计算key的hash值,并且通过该hash值&(数组长度-1)计算出一个index值,该inxdex值决定着该键值对会放在entry数组的哪个位置。
确定完键值对在数组的位置后,hashmap会判断该位置是否已经有元素或者是多个元素形成的链表,如果没有则直接放入,如果有则会遍历链表(对于1.8的hashmap来说,也可能是红黑树)如果能找到和自己key完全一样的键值对(通过equals方法判断)则替换掉该键值对,如果找不到key相同的,则插入到链表的尾部(不同版本hashmap的插入位置不同,我记得JDK1.7是头插法,1.8是尾插法)
JDK1.8对hashmap进行了一些优化,当某个数组位置上的链表长度超过8的时候,会优化成为一颗红黑树,所有结点变成树节点,这样既提高了查找效率也提高了插入的效率。所以1.8的hashmap相关方法也会随之调整,比如需要先判断一个节点是否是红黑树节点。
hashmap的扩容是2倍扩容,也就是数组变成原来的两倍长度,因此节点也需要进行位置调整,对于JDK1.7版本来说,需要对每个节点进行重哈希,然后重新插入到新的位置。而1.8版本优化了这一方式,它使用两个链表来串联两种不同类型的节点,区分的依据是,两种节点的hash值。
上述方法的原理是这样的:因为是两倍扩容,假如原数组长度是8,现在就变成16,对应的表长度-1用就是7和15,用二进制表示就是111和1111,而用hash值和这两个数相与的结果,区别也只会在最后一位,要么是0要么是1,所以只要判断相与结果最后一位是0还是1,即可判断它的位置需不需要改变,如果不需要,则连入第一个链表,如果需要,则连入第二个链表,最后在转移时重新放入合适的位置即可。

8 Java中的垃圾回收讲一下,讲了分代,gc算法,gc root可达性分析等讲到垃圾回收,一般都需要讲到这么几点内容:
JVM的内存分区,包括虚拟机栈、程序计数器、堆区、方法区、本地方法栈。
堆区用于存放对象。
栈区用于执行方法,保存引用。
方法区用于保存类的元数据信息。
本地方法栈则用来执行本地方法。
程序计数器则是记录当前程序运行到哪里的一个指示器。
垃圾回收主要发生在堆区,有时候也会发生在方法区(full gc)
堆区又可以被分为年轻代和老年代。
年轻代又可以被分为eden区和survivor区。
年轻代发生的垃圾回收叫做young gc,一次YGC后剩余的对象会被转移到survivor区。
而survivor又可以分为from区和to区。刚刚说到进入survivor区就是进入from区。
接下来每次YGC后,都可能会有新的对象进入survivor区。
而survivor中的from和to区每一次都换交换角色,什么意思呢,就是比如第一轮ygc后from区有2个对象,to区有0个对象,第二轮ygc后from区的对象会被转移到to区,并且from区变为to区,to区变成from区。
这样做的原因是,每次对象转移都会更新对象自身的转移次数,一旦转移次数到达阈值,便会自动进入老年代。
老年代发生的gc叫major gc,一般由full gc触发,full gc包括young gc和major gc,并且还会回收方法区中的垃圾。
full gc有几种触发条件,使用system.gc()方法可能触发gc但不能保证执行。
一般当survivor区的对象无法晋升到老年代时会发生full gc,又或者大对象无法进入老年代时也会触发full gc。full gc会触发stop the world,导致应用停顿几秒。
垃圾回收算法一般包含停止复制、标记清除、分代回收等方法。分代垃圾回收的方法是指在年轻代使用停止复制算法,在老年代使用标记清除算法。
垃圾回收器有传统的串行垃圾回收器,以及并行垃圾回收器,并且有适用于年轻代和老年代的不同版本,另外也有注重吞吐量的垃圾回收器(要求服务线程执行的时间/垃圾回收线程执行时间 尽量大)以及注重停顿时间的垃圾回收器。
CMS垃圾回收器就是一个注重停顿时间的垃圾回收器。它的回收过程是这样的:
首先,标记GC ROOT,完成初始标记(这些被标记的对象不会清除)
然后,开始进行并发标记,gc线程和应用线程并发运行,不会出现长时间的停顿,但是吞吐量较低。
接着,stop the world,短暂地停顿,完成剩余的标记工作,必须要有一段时间的停顿才能最终完成正确的标记。
最后,并发清除剩余的垃圾。
另外我们还会用到的垃圾回收器G1,g1收集器和cms的收集方式类似,但是g1将堆内存划分成了大小相同的小块区域,并且将垃圾集中到一个区域,存活对象集中到另一个区域,然后进行收集,防止产生碎片,同时使分配方式更灵活,它还支持根据对象变化预测停顿时间,从而更好地帮用户解决延迟等问题。

9 讲一下两个项目你都做了什么把。

10 除了代码之外你还学习了什么技术,框架。

11 死锁是怎么产生的
死锁的四个必要条件。

12 线程和进程的区别
操作系统基本概念问题

13 进程的通信方式
线程通信和进程通信
线程通信一般只需要使用共享内存的方式即可实现。
而进程通信则需要额外的通信机制。
1 信号量,一般多进程间的同步使用信号量来完成,系统为临界区添加支持并发量为n的信号量,多进程访问临界区资源时,首先需要执行p操作来减少信号量,如果信号量等于0则操作失败,并且挂起进程,否则成功进入临界区执行。
当进程退出临界区时,执行v操作,将信号量加一,并唤醒挂起的进程进行操作。
2 管程,管程是对信号量的一个包装,避免使用信号量时出错。
3 管道,直接连接两个进程,一个进程写入管道,另一个进程可以读取管道,但是他不支持全双工,并且只能在父子进程间使用,所以局限性比较大。
4 消息队列
操作系统维护一个消息队列,进程将消息写入队列中,其他进程轮询消息队列看是否有自己的消息,增加了轮询的开销,但是提高了消息的可靠性和易用性,同时支持了订阅消息。
5 socket
socket一般用于不同主机上的进程通信,双方通过ip和port的方式寻址到对方主机并找到监听该端口的进程,为了完成通信,他们先建立tcp连接,在此基础上交换数据,也就完成了进程间的通信。

14 CPU的执行方式
大概的思路是这样的:
计算机启动,cpu执行引导代码,加载操作系统到引导区
操作系统接手控制,执行特定程序,将程序代码装载到内存中,并将cpu的计数器指定到该内存位置,让cpu从当前位置开始执行代码。

15 代码中遇到进程阻塞,进程僵死,内存泄漏等情况怎么排查。
通过ps查询状态,分析dump文件等方式排查。

16 Linux了解么,查看进程状态ps,查看cpu状态 top。查看占用端口的进程号netstat grep

17 10g文件,只有2g内存,怎么查找文件中指定的字符串出现位置。
MapReduce分割文件处理。
他说可以用cat | grep 管道处理。

18 Linux的swap了解么,完全不懂。
和内存分页有关,有兴趣的可以了解一下。

19 Redis和MySQL最大的区别
一个是内存数据库,一个是关系数据库(存储数据在磁盘中)

20 讲一下Tomcat的基本架构和组件,以及请求的整个流程。说了一下connector和container架构和servlet请求过程。
Tomcat的基本架构:
connector主要用于接收http请求和发送http响应。当http请求到来时,connector负责解析该请求,并且将请求重新封装,然后转发到container的入口servlet。
container中包含多层结构,最外层是engine,接着是host,然后是context,最后是wrapper,一个wrapper对应着一个servlet,每个http请求被指定的servlet处理,最后完成http的响应。
servlet是一个请求处理器,在请求到达servlet之前,可能要经过一系列的filter调用链,比如字符集过滤器,可以把把字符集设置为UTF-8。

21 MySQL的存储引擎,有什么区别。
简单来说,MySQL的myisam引擎是不支持聚簇索引、行级锁以及事务的,而innodb是支持这些特性的。

22 范围1到1000的数,原本有1000个,互不重复,现多出来1个重复的数,怎么找到他。
统计次数后找出该数,面试官表示太慢,实际上答案是求和相减。

23 N个糖果,每次只能取1个到6个,不能不取,你先取,请问是否有必胜策略,怎么取。
刚开始说不太记得了,面试官提示了几个例子,找出规律不能为7的倍数,每次取到只剩7的倍数个糖果即可。

原文参考:https://xiaozhuanlan.com/topic/2934507168

发布了18 篇原创文章 · 获赞 4 · 访问量 923

猜你喜欢

转载自blog.csdn.net/weixin_43698561/article/details/104209840