最近正在准备面试,网上查了许多的面试题,但是却都很少有相关答案。因此特意在这里整理一份题型以及我自己填充的部分答案,如果有错误,或者部分我不知道结果的题目,可以请大家私信或评论我调整。同时本内容也会不定期进行更新,为了方便检索,会在前面先写问题和问题序号,下面会再写答案。其他相关内容spring、redis、数据库等稍后会一一进行编写。
侵删。
Java基础问题
- ArrayList和Linked区别
- HashMap实现原理
- HashSet的原理
- ConcurrentHashMap的原理
- equals和==区别
- IO和NIO的区别
- HashMap和HashTable区别?
- Object中常见的方法
- Java中的异常体系。
- JDK8新特性
- Java类加载器
- 类加载器的双亲委托模式
- public、private、protected以及不写时候的区别。
- String是基本类型吗
- float i = 1.1正确吗
- ConcurrentHashMap的增删改查如何保证线程安全
- final、finally、finalize区别
- 抽象类和接口的不同区别
Java基础答案
- ArrayList和LinkedList区别
ArrayList和LinkedList都继承自List,是有序可重复集合,而List和Set又都继承自Collection。
ArrayList:底层采用数组形式存储数据,默认情况下初始化的数组长度为10,每次会扩容1.5*length+1。查询可以通过数组下标来快速找到,因此查询数据非常的快。但添加或删除可能会导致后面的元素位置都发生变化,会使操作步骤增加,因此添加或删除 可能会速度较慢。
LinkedList:底层采用双向链表来存储数据。在LinkedList中定义了一个内部类Node,每一个数据都会被保存在Node中,在Node中同时记录了它的前一个节点preNode和后一个节点nextNode。由于链表的长度可以无限,不会发生扩容的操作。查询操作会先判断是在链表的前半部分还是后半部分,然后分别从头结点或尾节点遍历查询数据。如果不指定下标,则会从头结点开始遍历整个链表,因此查询操作很慢。但是添加或删除可以直接修改Node中的preNode或nextNode所指向的对象。
2.HashMap实现原理
HashMap采用了链表加数组的形式来存放数据。它里面的每一个元素都会存放在一个内部类Entry中。默认初始化大小为2的整数倍16,每次扩容*2,负载因子为0.75。对元素操作时,会先根据key的hash值与数组长度计算在数组中的存放位置,找到位置后再判断key是否相同,不相同则作为链表遍历,相同则替换value。在jdk1.8后为了防止hash碰撞发生太过频繁,增加了红黑树的结构,在特定的情况下会替换链表结构。
3.HashSet的原理
HashSet继承自Set,是无需不可重复集合,而Set又与List继承自Collection。
HashSet底层采用HashMap来实现,每一个存放在Set中的元素,实际都是存放在了HashMap的Key中,所有元素的Value都是一个private final static Objcect OBJECT = new Object()。同样的可以添加null数据。
4.ConcurrentHashMap的原理
ConcurrentHashMap底层同样采用数组加链表的结构。与HashMap的区别在于前者是线程安全的,并且采用了分段锁。同时在JDK1.8后对其中的部分方法进行了更新,对数据的操作使用了Unsafe类中的方法直接对内存进行操作(除了删除是直接在方法上添加Synchronized)。
5. equals和==区别
==是一种关系运算符,用来比较两个属性是否相等。如果比较的是基本类型,则是比较他们的值是否相等,如果比较的是对象,则是比较他们在内存中的地址是否相等。
equals是Object类中的一个方法,只能用来比较对象,不能比较基本类型。如果在对象中需要使用该方法,需要先对它进行重写,同时还要重写hashcode()方法。
http://6.IO和NIO的区别
IO面向流,阻塞。单线程一次只能应付一个连接。
NIO面向缓存,非阻塞,拥有选择器。可以单线程管理多个连接。
7.HashMap和HashTable区别?
HashMap是线程不安全的。
HashTable是线程安全的,它是在HashMap所有的方法上添加了synchronized,极大的降低了性能。
8.Object中常见的方法
getClass():获取当前类对象
hashcode():返回对象的hash值
equals(Object obj):判断两个对象是否相等
clone():创建并返回此对象的副本
toString():返回该对象的字符串表示。
notify():唤醒一个等待的线程。
notifyAll():唤醒所有等待的线程。
wait():另当前线程等待
finalize():垃圾回收器回收该对象前会先执行一次该方法。
9.Java中的异常体系。
Java中的所有异常都来自顶级父类Throwable。
Throwable下有两个子类Exception和Error。
Error是程序无法处理的错误,一旦出现这个错误,则程序将被迫停止运行。
Exception不会导致程序停止,又分为两个部分RunTimeException运行时异常和CheckedException检查异常。
RunTimeException常常发生在程序运行过程中,会导致程序当前线程执行失败。CheckedException常常发生在程序编译过程中,会导致程序编译不通过。
10.JDK8新特性
lambda表达式、方法引用、函数式接口、默认方法、stream、Optional类、Nashorn,JavaScript引擎、新的日期时间API、 Base64
11.Java类加载器
JDK自带有三个类加载器:bootstrap ClassLoader、ExtClassLoader、AppClassLoader。
BootStrapClassLoader是ExtClassLoader的父类加载器,默认负责加载%JAVA_HOME%lib下的jar包和class文件。
ExtClassLoader是AppClassLoader的父类加载器,负责加载%JAVA_HOME%/lib/ext文件夹下的jar包和class类。
AppClassLoader是自定义类加载器的父类,负责加载classpath下的类文件。
12.类加载器的双亲委托模式
类加载器加载类文件时首先会交给它的父类加载器进行加载,如果在父类加载器的加载范围下有全限定名相同的类,则由父类加载器进行加载该类,子类加载器不会再重复加载。
13.public、private、protected以及不写时候的区别。
public:所有地方的类都可以访问。
private:只能在当前类中进行访问。
protected:可以在当前类、当前包、子类中进行访问
不写默认为default:可以在当前类,当前包中进行访问。
14.String是基本类型吗
不是。基本类型只有八个:int、short、long、double、float、boolean、byte、char
15.float i = 1.1正确吗
不正确,默认的小数在java中是double类型,float相比double范围更小,因此需要显示的进行类型转换,如float i = (float)1.1或float i = 1.1f。
16.ConcurrentHashMap的增删改查如何保证线程安全
增(put(K key, V value)):在一个for死循环中,判断hash值对应的数组位置上是否有值,没有值则通过CAS操作添加数据。添加成功跳出循环,添加操作结束,对数组加一。操作失败则通过synchronized对数组中的第一个节点加锁添加数据,也即会对整条链表加锁。
删(remove(Object key)):在一个for死循环中,判断当前map为空,或者数组对应的位置上为null,则表示没有值,返回null。否则也是通过synchronized对数组中的第一个节点加锁删除数据。
查(get(Object key)):先判断map不为空,对应的数组位置上也有元素,即不能等于null,如果不满足则返回null。然后先判断数组位置上的这个元素是否与传入参数key相等,相等则直接返回。不相等则遍历链表,直到找到key相等的节点,否则返回null。
17.final、finally、finalize区别
final:可以用来修饰类、方法、成员变量。修饰类表示该类不能被集成,修饰方法表示该方法不能被重写,修饰成员变量表示该成员变量的值不能被修改。
finally:一般配合try……catch使用,用来保证程序不论是正常执行或是抛出异常或是中途return,都会执行finally中的代码。
finalized:这是配合GC的一个方法,在GC回收前都会先执行该方法。但由于致命缺陷已被废弃。
18.抽象类和接口的不同区别
(1)抽象类是一个类,只能被继承,一次只能继承一个抽象类。而接口可以被一次实现多个。
(2)抽象类可以有构造方法,接口没有。但是这两个都不能有自己的实例对象。
(3)抽象类的修饰符可以是public、private、protect、默认,但接口只能是public(JDK8后添加了关键字default,但这个default不等同于抽象类的默认)。
(4)抽象类中可以有抽象方法也可以没有抽象方法。接口中的方法都是没有方法体的。(JDK1.8后增加了default和static关键字可以在接口中写方法体)