离职后找新工作遇到的悲催,在面试题被虐得体无完肤。老老实实刷面试题吧。
本文仅针对一些问题进行简单答案补充,但不保证正确。
一、Java 基础
1.JDK 和 JRE 有什么区别?
答:简单的来说,JDK主要面向开发人员使用的SDK,JRE则更像JAVA的运行环境。
2.== 和 equals 的区别是什么?
答:==主要用来对比字符串的堆内存地址,而equals()则比较的是字符串的内容。
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
答:不一定,反过来equals为true,hashCode也不一定相同。
hashCode方法与equals方法均可以重写,返回值完全在于自己定义。
hashCode()返回该对象的哈希码值;equals()返回两个对象是否相等。
注:hashCode与equal常规协定:
(1)两个对象用equals()比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。
(2)两个对象用equals()比较返回false,不要求hashCode()方法也一定返回不同的值,但是最好返回不同值,亿提搞哈希表性能。
(3)重写equals()方法,必须重写hashCode()方法,以保证equals方法相等时两个对象hashcode返回相同的值。
4.final 在 java 中有什么作用?
答:凡是引用final关键字的地方皆不可以修改。类不可继承、方法不可重写、变量赋值后不可修改。
5.java 中的 Math.round(-1.5) 等于多少?
答:结果为Math.round方法的返回值为最近的一个0,long值,如果出现上下距离相等的情况。那就去较大的那个结果。比如说Math.round(11.6)那么结果就是12。
6.String 属于基础的数据类型吗?
答:不是。是final修饰的java类,基础数据类型一共有八种,分别是
基本整型int,long,short
浮点型:float,double
字符类型:byte,char
布尔类型:boolean
7.java 中操作字符串都有哪些类?它们之间有什么区别?
答:String、StringBuffer、StringBuilder
- String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对象,对字符串的修改操作都会生成新的对象。
- StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。
- StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。
8.String str="i"与 String str=new String(“i”)一样吗?
答:不一样,new String()类似在堆内存中new了一个新的对象。所以两者的内容是一样的,但是内存地址是不一样的。且
因为String 是final类型的,所以“i”应该是在常量池。而new String("i"),则是新建对象放到堆内存中。
9.如何将字符串反转?
答:将字符串转换成数组,然后倒序拼装字符串。
10.String 类的常用方法都有那些?
答:
11.抽象类必须要有抽象方法吗?
答:抽象类中可以没有抽象方法,但是一个类中如果有抽象方法,那么这个类必须为抽象类。
12.普通类和抽象类有哪些区别?
答:
(1)抽象类不能被实例化。
(2)抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态。
(3)抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体
(4)含有抽象方法的类必须申明为抽象类
(5)抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类。
13.抽象类能使用 final 修饰吗?
答:抽象类不能被final修饰,抽象类需要被继承才能使用,而被final修饰的类无法被继承,所以abstract和final是不能共存的。
14.接口和抽象类有什么区别?
答:
15.java 中 IO 流分为几种?
答:
16.BIO、NIO、AIO 有什么区别?
答:同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。
17.Files的常用方法都有哪些?
答:
二、Java 集合
18.java 容器都有哪些?
数组、String、java.util下的集合容器
数组长度限制为Integer.Integer.MAX_VALUE;
String的长度限制:底层为char数组,长度是Integer.MAX_VALUE ,线程安全的
List:存放有序,列表存储,元素可重复
Set:无序,元素不可重复
Map:无序,元素可重复
19.Collection 和 Collections 有什么区别?
(1)java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
List,Set,Queue接口都继承Collection。
直接实现该接口的类只有AbstractCollection类,该类也只是一个抽象类,提供了对集合类操作的一些基本实现。List和Set的具体实现类基本上都直接或间接的继承了该类。
(2)java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态方法(对集合的搜索、排序、线程安全化等),大多数方法都是用来处理线性表的。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
20.List、Set、Map 之间的区别是什么?
List的元素以线性方式存储,可以存放重复对象。主要有以下两个实现类:
(1)ArrayList:长度可变的数组,可以对元素进行随机的访问,但是插入与删除元素的速度比较慢,因为需要移动数组数据。
(2)LinkeList:采用双向链表数据结构,插入和删除的速度快,但是访问速度慢。因为需要改变指针指向。
Set中的对象不按特定(hashCode)的方式排序,没有重复对象。主要有以下两个实现类:
(1)HashSet:按照哈希算法来存取集合 中的对象,存取速度比较快。当元素个数超过数组大小×loadFactor
(默认值为0.75)时,就会进行近似两倍扩容。
(2)TreeSet:TreeSet实现SortedSet接口,能购对集合中的对象进行排序。
Map是一种把键对象和值对象映射的集合,他的每一个元素都包含一个键对象和值对象。主要有一下两个实现类:
(1)HashMap:基于散列表实现,其插入和查询<K,V>的开销是固定的,可以通过构造器设置和负载银子来调整容器的性能。
(2)LinkedHashMap:类似与HashMap,但是迭代遍历它时,取得的<K,V>的顺序是其从插入次序,或者是最近最少使用的(LRU)的次序。
(3)TreeMap:TreeMap
基于红黑树实现。查看<K,V>
时,它们会被排序。TreeMap
是唯一的带有subMap()
方法的Map
,subMap()
可以返回一个子树。
21.HashMap 和 Hashtable 有什么区别?
(1)同步性、HashTable的方法是同步的即线程安全,HashMap不能同步即线程不安全。
(2)继承的父类不同、HashTable是继承自Dictionary类,而HashMap继承字AbstractMap类。但是他们都实现了Cloneable(可复制)、Serializable(可序列化)这三个接口。
(3)对null key 和null value的支持不同。hashTable不允许null值KV。HashMap允许,但是这样仅允许一个key值为null,不同的key允许存在多个value值。
(4)遍历方法不同,HashTable使用Enumeration遍历,HashMap使用Iterator进行遍历。
(5)初始化和扩容的方式不同
(6)计算hash值的方法不同
(7)对外提供的接口不同
22.如何决定使用 HashMap 还是 TreeMap?
(1)HashMap:适用于在Map中插入、删除和定位元素。
(2)Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
(3)HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap.
(4)HashMap 非线程安全 TreeMap 非线程安全
(5)HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。
在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。
23.说一下 HashMap 的实现原理?
答:底层实现:HashMap底层整体结构是一个数组,数组中的每个元素又是一个链表。每次添加一个对象(put)时会产生一个链表对象(Object类型),Map中的每个Entry就是数组中的一个元素(Map.Entry就是一个<Key,Value>),它具有由当前元素指向下一个元素的引用,这就构成了链表。
存储原理:当向HsahMap中添加元素的时候,先根据HashCode重新计算Key的Hash值,得到数组下标,如果数组该位置已经存在其他元素,那么这个位置的元素将会以链表的形式存放,新加入的放在链头,最先加入的放在链尾,如果数组该位置元素不存在,那么就直接将该元素放到此数组中的该位置。
去重原理:不同的Key算到数组下标相同的几率很小,新建一个<K,V>放入到HashMap的时候,首先会计算Key的数组下标,如果数组该位置已经存在其他元素,则比较两个Key,若相同则覆盖写入,若不同则形成链表。
读取原理:从HashMap中读取(get)元素时,首先计算Key的HashCode,找到数组下标,然后在对应位置的链表中找到需要的元素。
扩容机制:当HashMap中的元素个数超过数组大小*loadFactor(默认值为0.75)时,就会进行2倍扩容(oldThr << 1)。
24.说一下 HashSet 的实现原理?
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,更确切的说,HashSet中的元素,只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成
25.ArrayList 和 LinkedList 的区别是什么?
(1)ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
(2)对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
(3)对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
26.如何实现数组和 List 之间的转换?
List转数组:toArray(arraylist.size()方法
数组转List:Arrays的asList(a)方法
27.ArrayList 和 Vector 的区别是什么?
1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
28.Array 和 ArrayList 有何区别?
答:1)Array是JAVA中的数组,在定义一个数组的时候,必须指定这个数组的数据类型及数组的大小,也就是说数组中存放的元素个数固定并且类型一样。
2)ArrayList是动态数组,类似数组的复杂版本。在不使用泛型的情况下,这个list是可以添加进不同类型的元素的,而且arraylist是可以不用指定长度的。在使用泛型时,我们就只能添加一种类型的数据了
29.在 Queue 中 poll()和 remove()有什么区别?
答:poll当队列为空时,会抛出异常,而remove只会返回null、
30.哪些集合类是线程安全的?
vector、statck、hashtable、enumeration。但是效率都不怎么样来着
31.迭代器 Iterator 是什么?
答:Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包括了可以返回迭代器实例的迭代方法。迭代器可以在迭代过程中删除底层集合的元素,但是不可以直接调用集合的remove(Object obj)删除,可以通过迭代器的remove()方法删除
32.Iterator 怎么使用?有什么特点?
33.Iterator 和 ListIterator 有什么区别?
32.Iterator 怎么使用?有什么特点?
33.Iterator 和 ListIterator 有什么区别?
34.怎么确保一个集合不能被修改?
答:final表示引用的地址值不可改变。所以数组应该用collections下的unmodifiableMap方法。通过这个方法返回的map是不可修改的。会报错。
答:final
三、多线程
35.并行和并发有什么区别?
答:在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。
36.线程和进程的区别?
37.守护线程是什么?
答:服务线程,当所有线程都结束了。守护线程才结束。比如垃圾回收线程,就是最典型的守护线程。
38.创建线程有哪几种方式?
答:1)继承Thread,调用start方法。
2)实现runnable的run
39.说一下 runnable 和 callable 有什么区别?
40.线程有哪些状态?
41.sleep() 和 wait() 有什么区别?
42.notify()和 notifyAll()有什么区别?
43.线程的 run()和 start()有什么区别?
44.创建线程池有哪几种方式?
45.线程池都有哪些状态?
46.线程池中 submit()和 execute()方法有什么区别?
47.在 java 程序中怎么保证多线程的运行安全?
48.多线程锁的升级原理是什么?
49.什么是死锁?
50.怎么防止死锁?
51.ThreadLocal 是什么?有哪些使用场景?
52.说一下 synchronized 底层实现原理?
53.synchronized 和 volatile 的区别是什么?
54.synchronized 和 Lock 有什么区别?
55.synchronized 和 ReentrantLock 区别是什么?
56.说一下 atomic 的原理?