面经整理资料1

面经资料来源:http://www.nowcoder.com/discuss/3836

阿里实习 Java研发 一面

(1)JVM如何加载一个类的过程,双亲委派模型中有哪些方法?

加载一个类的过程:加载->链接(验证,准备,解析)->初始化

双亲委派模式的方法:向上不断查看是否加载了类(findLoadedClass()),向下尝试加载类(loadClass()),自定义类加载器需要回调(findClass())。

具体请参考Blog Java类装载过程与类装载器

(2)HashMap如何实现的?

在JDK1.7及以前,HashMap中维护着Entry,Entry中维护着key,value以及hash和next指针,而整个HashMap实际就是一个Entry数组

当向 HashMap 中 put 一对键值时,它会根据 key的 hashCode 值计算出一个位置, 该位置就是此对象准备往数组中存放的位置。 

如果该位置没有对象存在,就将此对象直接放进数组当中;如果该位置已经有对象存在了,则顺着此存在的对象的链开始寻找(为了判断是否是否值相同,map不允许<key,value>键值对重复), 如果此链上有对象的话,再去使用 equals方法进行比较,如果对此链上的每个对象的 equals 方法比较为 false,则将该对象放到数组当中,然后将数组中该位置以前存在的那个对象链接到此对象的后面。 

get方法类似,通过key取hash找到数组的某个位置,然后遍历这个数组上的每个Entry,直到key值equals则返回。

如果Hash碰撞严重,那么JDK1.7中的实现性能就很差,因为每次插入都要遍历完整条链去查看key值是否重复,每次get也要遍历整个链,在JDK1.8中,由于链表的查找复杂度为O(n),而红黑树的查找复杂度为O(logn),JDK1.8中采用链表/红黑树的方式实现HashMap,达到某个阀值时,链表转成了红黑树。

具体请参考 JDK7与JDK8中HashMap的实现

(3)HashMap和Concurrent HashMap区别, Concurrent HashMap 线程安全吗, ConcurrentHashMap如何保证 线程安全?

HashMap不是线程安全的,ConcurrentHashMap是线程安全的,HashMap内部维护着一个Entry数组,而ConcurrentHashMap内部有一个Segment段,它将大的HashMap切分成若干个段(小的HashMap),然后让数据在每一段上Hash,这样多个线程在不同段上的Hash操作一定是线程安全的,所以只需要同步同一个段上的线程就可以了,这样实现了锁的分离,大大增加了并发量。ConcurrentHashMap的实现中还使用了不变模式final和volatile来保障线程安全

具体请参考 ConcurrentHashMap原理分析

(4)HashMap和HashTable 区别,HashTable线程安全吗?

  1. HashMap允许key和value为null,HashTable不允许。
  2. HashMap是非线程安全的,HashTable是线程安全的
  3. HashMap的迭代器是Iterator是fail-fast迭代器,当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException(关于ConcurrentModificationException请查看 ConcurrentModificationException的原因以及解决措施) HashTable的迭代器有enumerator和Iterator两种enumerator不会抛出上述异常。
  4. hash算法不同,HashMap能更广泛地分散到数组的不同位置
  5. 扩展数组的算法不同,HashTable:2 * 原数组长度+1,HashMap:原数组长度 * 2

(5)进程间通信有哪几种方式?

传统的进程间通信的方式有大致如下几种:

(1)   管道(PIPE) 
(2)   命名管道(FIFO) 
(3)   信号量(Semphore) 
(4)   消息队列(MessageQueue) 
(5)   共享内存(SharedMemory) 
(6)   Socket

Java如何支持进程间通信。我们把Java进程理解为JVM进程。很明显,传统的这些大部分技术是无法被我们的应用程序利用了(这些进程间通信都是靠系统调用来实现的)。但是Java也有很多方法可以进行进程间通信的。 
除了上面提到的Socket之外,当然首选的IPC可以使用Rmi,或者Corba也可以。另外Java nio的MappedByteBuffer也可以通过内存映射文件来实现进程间通信(共享内存)。

(6)JVM分为哪些区,每一个区干吗的?

虚拟机将所管理的内存分为以下几个部分:

  • 程序计数器        指向正在执行的字节码地址
  • 虚拟机栈           存放局部变量表,操作数栈,动态链接,方法出口
  • 本地方法区        Native方法服务
  • 堆                     用来存放对象实例的
  • 方法区              用于存储已经被虚拟机加载过的类信息,常量(JDK7中String常量池被移到堆中),静态变量(JDK7中被移到Java堆),及时编译期编译后的代码(类方法)等数据。

具体请查看  Java内存区域

(7)JVM如何GC,新生代,老年代,持久代,都存储哪些东西?

JVM通过可达性(可触及性)分析算法标记出哪些对象是垃圾对象,然后将垃圾对象进行回收,在新生代中采用复制算法,在老年代中采用标记清理或标记压缩算法。新生代存储了新new出的对象,老年代存储了大的对象和多次GC后仍然存在的老年对象,持久代存储了类信息,常量(JDK7中String常量池被移到堆中),静态变量(JDK7中被移到了Java堆),类方法

具体请查看 JVM 垃圾回收机制 , Java内存区域

(8)GC用的引用可达性分析算法中,哪些对象可作为GC Roots对象?

  • 栈中引用的对象
  • 方法区中静态成员或者常量引用的对象(全局对象)
  • JNI方法栈中引用对象

总体来说就是,全局中的引用(例如常量或者静态属性)与执行上下文(例如栈帧中的本地变量表)。

具体请查看  JVM 垃圾回收机制

(9)快速排序,过程,复杂度?

快排的基本思想是:

1.先从数列中取出一个数作为基准数(pivot)。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。

平均复杂度O(NlogN),最差O(N^2),最好O(NlogN)

具体请查看 排序总结(不断更新)

(10)什么是二叉平衡树,如何插入节点,删除节点,说出关键步骤。

二叉平衡树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

AVL树的插入和删除,主要是依靠左旋和右旋来达到平衡状态。

红黑树的插入,插入节点是红色,通过一系列选择和着色使其成为红黑树。

步骤为:

  • 插入节点的父亲节点是黑色,直接插入。
  • 插入节点的父亲节点是红色:
  1. 插入节点的叔叔节点是红色的话,将父节点和叔叔节点变成红色,父节点的父节点变成红色。然后整体上移
  2. 叔叔节点是黑色,当前节点是右孩子,通过旋转将当前节点转到左孩子
  3. 叔叔节点是黑色,当前节点是左孩子,一次旋转一次着色。

所以红黑树的插入需要最多两次旋转,删除需要最多三次旋转

具体请查看 红黑树

(11)TCP如何保证可靠传输?三次握手过程?

(13)TCP和UDP区别?
(14)滑动窗口算法?
(15)Linux下如何进行进程调度的?
(16)Linux下你常用的命令有哪些?
(17)操作系统什么情况下会死锁?
(18)常用的hash算法有哪些?
(19)什么是一致性哈希?
(20)如何理解分布式锁?
(21)数据库中的范式有哪些?
(22)数据库中的索引的结构?什么情况下适合建索引?
(23)Java中的NIO,BIO,AIO分别是什么?
(24)用什么工具调试程序?JConsole,用过吗?
(25)现在JVM中有一个线程挂起了,如何用工具查出原因?
(26)线程同步与阻塞的关系?同步一定阻塞吗?阻塞一定同步吗?
(27)同步和异步有什么区别?
(28)线程池用过吗?
(29)如何创建单例模式?说了双重检查,他说不是线程安全的。如何高效的创建一个线程安全的单例?
(30)concurrent包下面,都用过什么?
(31)常用的数据库有哪些?redis用过吗?
(32)了解hadoop吗?说说hadoop的组件有哪些?hdfs,hive,hbase,zookeeper。说下mapreduce编程模型。
(33)你知道的开源协议有哪些?
(34)你知道的开源软件有哪些?
(35)你最近在看的书有哪些?
(36)你有什么问题要问我吗?
(37)了解哪些设计模式?说说都用过哪些设计模式

(38)如何判断一个单链表是否有环?

给定一个单链表,只给出头指针h:

1、如何判断是否存在环?

2、如何知道环的长度?

3、如何找出环的连接点在哪里?

4、带环链表的长度是多少?

解法:

1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。

3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度

(39)操作系统如何进行分页调度?
(40)匿名内部类是什么?如何访问在其外面定义的变量?


Reference:

1. http://www.importnew.com/7010.html

2. http://www.cnblogs.com/flyingwind/archive/2012/10/24/2737204.html

你可能感兴趣的:(面经整理资料1)