JAVA面试题第一章
JAVA面试题第一章
1.接口与抽象类的区别和相似点
相似点:
1.接口和抽象类都不可被实例化
2.继承或者实现了接口和抽象类的子类都必须重写父类中的抽象方法。
区别:
1.抽象类当中可以有普通方法和代码块,但是接口当中不能存在普通方法和代码块,接口当中只能包含抽象方法,默认方法,静态方法
2.抽象类当中可以由构造方法但是接口不可以
3.抽象类当中可以存在任意类型的成员属性,但是接口当中只能存在静态常量,并且必须赋值。
2.== 和equals
1.==比较基本数据类型的时候比较的是值,比较引用数据类型的时候比较的在内存当中的地址。
2.equals是object类的一个方法,本质上和==是一样的,但是重写了equals方法,例如String重写了equals方法就是比较的字符串的值,另外重写了equals方法就必须重写hashcode方法。
3.重写和重载区别
1.重载发生在同一个类当中,方法名相同,参数列表、返回值类型、类修饰符都可以不同。
2.重写发生在当前类的子类当中,方法名、参数列表、返回值类型都必须相同,权限修饰符必须大于父类的权限修饰符,子类的异常必须小于父类的异常声明,但是final和static修饰的方法不可被重写。
4.异常处理机制
1.try-catch-finally是进行异常捕获并进行处理的异常异常处理机制,finally不管程序出没出现异常最终丢会被执行,出现异常程序继续运行。
2.throws是声明该方法可能会出现的异常,一旦出现异常,程序终止运行。
5.HashMap原理
1.HashMap在jdk1.8以后采用的是数组+链表+红黑树构成的集合,HashMap的特点是,key是不可重复的,key的值可以为null,线程不安全。
2.HashMap的扩容机制:HashMap采用默认的容量是16,扩容的默认的负载因子是0.75,当数组的容量大于默认的容量乘以负载因子0.75时,就会创建一个原数组二倍的数组,将原来数组当中的内容从复制到新的数组当中,当数组的长度大于64并且链表的长度大于8时,就会使用红黑树来存储数据。
3.HashMap的存储原理:
- 先计算key的hash值,然后进行二次hash,然后根据二次hash的值找到索引位置。
- 如果根据hash找到索引位置并且有值根据equals方法比较的返回值为true那么将进行取代,如果返回的时false那么就进行高低位平移法将节点插入链表。
4.想要HashMap线程安全的方法
- 使用ConcurrentedHashMap
- 使用HashTable
- Collections.synchronizedHashMap()方法
5.HashTable和HashMap 的区别
- HashTable当中的每一个方法ychronized修饰,因此线程安全,但是执行的效率低。
- HashTbale的key值不允许为null
- HashTable计算hash值只有一次,但是HashMap进行两次hash值计算
- HashTable底层使用的数组+链表
6.ArrayList和LinkList
1.ArrayList底层采用的时动态数组,采用的默认的容量为10,当元素的个数超过10个时将重新创建一个原数组1.5倍的新数组将原数组的数据复制到新的数组当中。因为Array List在内存中是连续的,所以查找的效率更高,由于扩容的机制添加数据的效率更高。
2.LinkList 底层采用的是链表,没有扩容机制,查找数据需要从头到尾的查找,但是添加数据的效率更高。
7.ArrayList线程安全办法
- 使用Collections.synchronizedList()方法进行加锁操作
- 使用Vector,Vector当中的每一个方法都加了synchronized锁修饰,但是速度很慢
- 使用juc下的copyonWriterArraylist方法,他写操作是创建一个数组的副本,将写操作都在副本里进行,写操作之后在将指针直线数组的副本,线程安全。
8.String、StringBuffer、StringBulider
-
String是一个被final修饰的类,String字符串是不可变的,当对String字符串进行修改时,String会创建一个新的字符串,将所有的指针指向他。
-
StringBuffer可变线程安全
-
StringBulider可变线程不安全
-
在操作比较少的字符串的时候适合使用String,在操作大量的字符的时候适合是使用Stringbulider,在操作多线程情况下的字符时使用StringBuffer。
9.Hashcode和equals
-
hashcode和equals都是object类的方法,hashcode采用的是对内存地址进行hash值的计算,但是有些类重写了hashcode可能计算的的是数组的hash值,重写了hashcode 就必须重写equals方法,equals比较的是两个值是否相等,但是也可能被类重写之后比较的是两个对象。
-
所以如果两个值如果相等,那么他们两个的hashcode值和equals都相等,但是如果hash值相等,equals不一定相等,两个对象也不一定相等。
-
如果重写了hashcode就必须重写equals,例如一个String类型的key的map集合,如果equals相等但是没有判断hash值的话就会出现一个Map当中出现了两个相同的key。
10.面向对象和面向过程
- 面向对象有封装、继承、多态的特性(四特性就增加一个abstract抽象),所以相对面向过程更加易扩展、易维护、易使用,但是面向对象类调用需要实例化内存的开销相对较大,性能低。
11.浅拷贝和深拷贝
- 浅拷贝支持复制了类的引用,而不复制类的本身,和类共享一个内存地址。
- 深拷贝复制一个新的类对象,和类不共享一个内存地址,修改新对象对源对象没有影响。
12.多态的作用
多态的实现需要继承、重写,父类调用指向子类。他的好处是消除了类型之间的耦合性。增加了类的可扩充性和灵活性。
13.什么是反射
-
反射是通过类获取class对象,通过类对象来动态获取类的内部结构,动态的操作类的方法和属性。
-
反射适合的场景是:要操作权限不够的类属性和方法时、实现自定义注解时、动态加载第三方jar包时、按需加载类,节省编译和初始化时间;
-
获取class类的方法:class.forName(类路径),类.class(),对象的getClass()
14.Java当中创建对象的方法
(1)new关键字 (2)Class.newInstance (3)Constructor.newInstance
(4)Clone方法 (5)反序列化