Java基础部分
1.抽象类和接口的共同点和区别?
共同点:
-
都不能被实例化。
-
都可以包含抽象方法。
-
都可以有默认实现的方法(Java 8 可以用
default
关键字在接口中定义默认方法)。
不同点:
语法层面
-
抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
-
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
-
接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
-
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
设计层面
-
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
-
设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。
2.重载(Overload)和重写(Override)的区别
- 发生的位置不同:重载发生在同一个类中;重写发生在子类种
- 发生阶段:重载发生在编译时期;重写发生在运行时期;
- 参数列表:重载方法名相同,参数列表一定不同;重写是方法名和参数列表一定相同;
- 修饰符,异常,返回类型:重载与这些都无关;重写中:修饰符不能严于父类,抛出异常要比父类的更小,返回值类型要比父类的更小
3.什么是java序列化和反序列化,如何实现java序列化?
- 序列化:将数据结构或对象转换成二进制字节流的过程
- 反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
- 实现序列化:JDK 自带的序列化,只需实现
Seriazable
接口即可。 - 还要有SerialVersionUID序列化号
serialVersionUID
属于版本控制的作用。反序列化时,会检查serialVersionUID
是否和当前类的serialVersionUID
一致。如果serialVersionUID
不一致则会抛出InvalidClassException
异常。
4.final,finally,finlize关键字的用法?
- final用于修饰变量,方法和类
- final修饰变量:被修饰的变量不可变,final修饰的变量必须初始化,通常称被修饰的变量为常量
- final修饰方法:被修饰的方法不可以被任何子类重写,子类可以使用该方法
- final修饰类:被修饰的类不可以被继承,所有方法都不可以被重写
- finally作为异常处理的一部分,它只能在try catch语句中,在此代码块中的代码一定会被执行,(无论是否抛异常),经常被使用在需要释放资源的情况下,System.exit(0)可以阻断finally的执行
- finalize是Object类中的方法,也就是说每一个对象都拥有此方法,对象被GC回收时调用,且一个对象的finalize方法只会被调用一次
5.== 和equals区别?
- 对于基本数据来说 == 比较的是值,对于引用数据来说 == 比较的是对象的内存地址
- equals()是Object类中的一个方法,所以所有类都有该方法,因此他不能用于比较基本数据类型,只能比较两个对象是否相等
- 如果类中没有重写equals方法,那么就是使用Object类中的默认方法,等价与用==比较,比较的是两个对象的内存地址
- 如果类重写了equals方法,我们一般都是重写equals方法来比较对象中的属性是否相等,若他们的属性相等返回true,即认为这两个对象相等
- String中的equals方法是被重写过的,比较的是值
6.静态变量 和 实例变量的区别?
- 静态变量就是被static修饰的,他是被类的所有实例共享的,无论创建了多少个对象,他都共享同一份静态变量;
- 存储位置不同:静态变量存储在方法区中,而实力变量存储在堆中
- 生命周期不同,静态变量是属于类的,随着类的存在而存在,随着类的消失而消失。而实列变量随着对象的创建而产生,随着对象的销毁而销毁
7.int和Integer有什么区别?
- int是基本数据类型,Integer是int的包装类
- int如果在成员变量中无需赋初始值,在局部变量中需要赋初始值。Integer必须实例化才能使用
- int存储的是数据的值,Integer存储的是对象的值
- int的默认值是0,Integer的默认值是null
8.String、StringBuffer、StringBuilder 的区别?
- 可变性:String是不可变的,StringBuffer和StringBuilder都是可变的
- 线程安全性:
String
中的对象是不可变的,也就可以理解为常量,线程安全;StringBuffer
对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder
并没有对方法进行加同步锁,所以是非线程安全的。 - 效率:每次对
String
类型进行改变的时候,都会生成一个新的String
对象,然后将指针指向新的String
对象。StringBuffer
每次都会对StringBuffer
对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StringBuilder
相比使用StringBuffer
仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
9.synchronized和lock的区别?
- synchronized是Java关键字,Lock是接口
- synchronized 可以给类. 方法. 代码块加锁;而 lock 只能给代码块加锁。
- synchronize可以自动获得锁和释放锁,遇到异常会自动释放锁,不会造成死锁。而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁
- Lock锁适合大量代码的同步问题,synchronized锁适合少量代码的同步问题。
3. Comparable和Comparator接口的区别?
- comparable是内比较器,实体类实现Comparable接口,并实现 compareTo(T t) 方法
- 创建一个外部比较器,这个外部比较器要实现Comparator接口的 compare(T t1, T t2)方法