1.equals和==的区别

  • ==
  • 如果是基础类型,判断值是否相等
  • 如果是引用类型,判断的是内存地址是否相等
  • equals
  • 如果是字符串,判断字符串的内容是否相同
  • 如果是object对象原始的equals方法,比较的也是引用的内存地址的值
  • 如果重写equals,则可以实现比较两个对象内容是否相等

2. final、finally、finalize的区别

  • final 用于修饰属性,方法和类, 分别表示属性不能被重新赋值, 方法不可被覆盖, 类不可被继承
  • finally是异常处理语句结构的一部分,一般以 try-catch-finally 出现,finally 代码块表示总是被执行
  • finalize是Object类的一个方法,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用 finalize()方法,回收垃圾,JVM 并不保证此方法总被调用

3. 重载和重写的区别

  • 重写必须继承,重载不用
  • 重载表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同
  • 重写表示子类中的方法与父类中的某个方法的名称和参数完全相同,通过子类实例对象调用这个方法时,将调用子类中的定义方法,这相当于是父类中定义的那个完全相同的方法被覆盖了,这是面向对象编程的多态性的一种表现。
  • 重写的方法修饰符大于等于父类的方法,即访问权限只能比父类的更大,不能更小,而重载和修饰符无关。
  • 重写覆盖的方法中,只能比父类抛出更少的异常,或者抛出父类抛出异常的子异常

4. 两个对象的hashCode()相同,则 equals()是否也一定为true?

两个对象equals相等,则它们的hashcode必须相等,如果两个对象的hashCode相同,则equals不一定为 true。

5. 抽象类和接口有什么区别?

  1. 抽象类要被子类继承,接口要子类被实现
  2. 抽象类可以有构造方法,接口不能有构造方法
  3. 抽象类中可以有普通的成员变量,接口中没有普通的成员变量,它的变量只能是公共的静态常量
  4. 一个类可以实现多个接口,但是只能继承一个父类,这个类可以是抽象类
  5. 接口只能做方法声明,抽象类可以只做方法声明,也可以做方法实现
  6. 抽象级别:接口>抽象类>实现类
  7. 抽象类主要是用来抽象类别,接口是用来抽象方法功能
  8. 抽象类的关键字是abstract,接口的关键字是interface

6. BIO、NIO、AIO有什么区别?

  • BIO(同步阻塞IO)
  • 概述:线程发起IO请求,不管内核是否准备好,从发起请求起,线程一直处于阻塞状态,知道操作完成。
  • 同步并阻塞,服务器实现模式为一个请求一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
  • NIO(同步非阻塞IO)
  • 概述:线程发起IO请求,立即返回;内核在做好IO操作的准备之后,通过调用注册的回调函数通知线程处理IO操作,线程这时候开始阻塞,知道操作完成。
  • 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  • AIO(异步非阻塞IO)
  • 概述:线程发起IO请求,立即返回;OS内存做好IO操作的准备之后,做IO操作,直到操作完成或者失败,通过调用注册的回调函数通知线程做IO操作完成或者失败。(AIO采用“订阅-通知”模式: 即应用程序向操作系统注册IO监听,然后继续做自己的事情。当操作系统发生IO事件,并且准备好数据后,在主动通知应用程序,触发相应的函数)
  • 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的 IO 请求都是由 OS 先完成了再通知服务器应用去启动线程进行处理。

7.String、StringBuffer、StringBuilder的区别

  1. 可变性:
  • String内部的value值是final修饰的,所以是不可变类,每次修改值的时候,都会生成一个新的对象。
  • StringBuffer和StringBuilder都是可变类,字符串的修改不产生新的对象
  1. 线程安全:
  • String是不可变类,所以是线程安全的
  • StringBuffer是线程安全的, 因为每个方法上都加上了synchronized关键字
  • StringBuilder是线程不安全的
  1. 性能方面
  • String性能最低,因为每次修改的时候,都需要重新创建新的对象和分配内存
  • StringBuffer性能比String高,比StringBuilder低,因为StringBuffer加了锁
  1. 存储方面
  • String存储在常量池里面
  • StringBuffer和StringBuilder存储在堆空间

8.java中的几种基本数据类型是什么?各占多少字节呢?

数据类型

位数

字节数

byte

1

8

char

2

16

short

2

16

int

4

32

float

4

32

double

8

64

long

8

64

boolean

1?

8?

对于boolean,官方文档未明确定义,它依赖于 JVM 厂商的具体实现。逻辑上理解占用 1 位,但实际中会考虑计算机高效存储因素

9.Comparator和Comparable有什么区别?

Comparable是自已完成比较,Comparator时外部程序实现比较的差别而已。

Comparator 体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。 比如:你想对整数采用绝对值大小来排序,Integer 是不符合要求的,你不需要去修改Integer 类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了 Comparator 接口的对象来实现控制它的排序就行了。

10.String类能被继承吗?为什么?

String是一个final修饰的类,所以不能被继承。

深层原因:

  1. 效率性:String作为一个最常被使用的类,禁止被继承和重写,可以提高效率
  2. 安全性:String类中有很多调用底层的本地方法,调用了操作系统的API,如果被重写可能会被植入恶意代码,破坏程序

11. 说说java中多态的实现原理

  • 多态机制包括静态多态(编译时多态)和动态多态(运行时多态),静态多态比如说重载,动态多态一般是在运行时才能确定调用哪个方法,我们说的多态一般指动态多态
  • 多态的实现方式:继承和接口实现
  • 多态的核心就在于通过对父类方法的改写和对接口实现,使在运行时取得不同的执行结果
  • java里对象方法的调用是依靠类信息里面的方法表实现的,对象方法的引用调用和接口方法的引用调用大致思想是一致的,当调用对象的某个方法时,JVM查找该类的方法表以确定该方法的直接引用地址,有了地址后才真正调用该方法。

12. int和Integer有什么区别?还有Integer缓存的实现

  • int是基础数据类型,Integer是对象类型,它封装了很多的方法和属性,使我们在使用时更灵活
  • int默认值是0,Integer默认值是null
  • int类型是直接存储在栈空间,Integer存储在堆内存

Integer的缓存机制:为了节省内存和性能,Integer类在内部通过使用相同的对象引用实现缓存和重用,Integer类默认在-128-127之间,可以通过-XX:AutoBoxCacheMax修改,且这种机制仅在自动装箱时有用,在使用构造器创建Integer对象时无用。

13. java获取反射的三种方法

  1. 使用Class.forName方法
  2. 使用类的.class方法
  3. 使用实例对象的getClass()方法

14. 面向对象的三大特征

  1. 封装
  2. 继承
  3. 多态