1、简述抽象类与接口的区别
抽象类:体现的是is-a的关系,如对于man is a person,就可以将person定义为抽象类。
接口:体现的是can的关系,是作为模板实现的。如设置接口fly,plane类和bird类均可实现该接口。
一个类只能继承一个抽象类,但可以实现多个接口。
2、出现在java程序中的finally代码块是否一定会执行?
当遇到下面情况不会执行。
当程序在进入try语句块之前就出现异常时会直接结束。
当程序在try块中强制退出时,如使用System.exit(0),也不会执行finally块中的代码。
3、简述==与equals方法的区别
对于==,在基本数据类型比较时,比较的是对应的值,对引用数据类型比较时,比较的是其内存的存放地址。
对于equals方法,在该方法未被重写时,其效果和==一致,但用户可以根据对应需求对判断逻辑进行改写,比如直接比较对象某个属性值是否相同,相同则返回true,不同则返回false。需保证equals方法相同对应的对象hashCode也相同。
4、简述重载与重写的区别
重写即子类重写父类的方法,方法对应的形参和返回值类型都不能变。
重载即在一个类中,方法名相同,参数类型或数量不同。
5、为什么要把String设计为不变量?
1、节省空间:字符串常量存储在JVM的字符串池中可以被用户共享。
2、提高效率:String会被不同线程共享,是线程安全的。在涉及多线程操作中不需要同步操作。
3、安全:String常被用于用户名、密码、文件名等使用,由于其不可变,可避免黑客行为对其恶意修改。
6、为什么java语言不支持多重继承?
1、为了程序的结构能够更加清晰从而便于维护。假设Java语言支持多重继承,类C继承自类A和类B,如果类A和B都有自定义的成员方法f(),那么当代码中调用类C的f()会产生二义性。Java语言通过实现多个接口间接支持多重继承,接口由于只包含方法定义,不能有方法的实现,类C继承接口A与接口B时即使它们都有方法f(),也不能直接调用方法,需实现具体的f()方法才能调用,不会产生二义性。
2、多重继承会使类型转换、构造方法的调用顺序变得复杂,会影响到性能。
7、字节序定义以及java属于哪种字节序?
字节序是指多字节数据在计算机内存中存储或网络传输时个字节的存储顺序。通常由小端和大端两组方式。
小端:低位字节存放在内存的低地址端,高位字节存放在内存的高地址端。
大端:高位字节存放在内存的低地址端,低位字节存放在内存的高地址端。
Java语言的字节序是大端。
8、String和StringBuffer有什么区别?
String用于字符串操作,属于不可变类。String对象一旦被创建,其值将不能被改变。而StringBuffer是可变类,当对象创建后,仍然可以对其值进行修改。
9、简述java的多态
Java多态可以分为编译时多态和运行时多态。
编译时多态主要指方法的重载,即通过参数列表的不同来区分不同的方法。
运行时多态主要指继承父类和实现接口时,可使用父类引用指向子类对象。
运行时多态的实现:主要依靠方法表,方法表中最先存放的是Object类的方法,接下来是该类的父类的方法,最后是该类本身的方法。如果子类改写了父类的方法,那么子类和父类的那些同名方法共享一个方法表项,都被认作是父类的方法。因此可以实现运行时多态。
10、简述泛型擦除
Java编译器生成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程被称为泛型擦除。
11、简述元注解
元注解可以理解为注解的注解,即在注解中使用,实现想要的功能。其具体分为:
@Retention: 表示注解存在阶段是保留在源码,还是在字节码(类加载)或者运行期(JVM中运行)。
@Target:表示注解作用的范围。
@Documented:将注解中的元素包含到 Javadoc 中去。
@Inherited:一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。
@Repeatable:被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。
12、java语言中关键字static的作用是什么
static的主要作用有两个:
为某种特定数据类型或对象分配与创建对象个数无关的单一的存储空间。
使得某个方法或属性与类而不是对象关联在一起,即在不创建对象的情况下可通过类直接调用方法或使用类的属性。
具体而言static又可分为4种使用方式:
修饰成员变量。用static关键字修饰的静态变量在内存中只有一个副本。只要静态变量所在的类被加载,这个静态变量就会被分配空间,可以使用''类.静态变量''和''对象.静态变量''的方法使用。
修饰成员方法。static修饰的方法无需创建对象就可以被调用。static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和静态成员方法。
修饰代码块。JVM在加载类的时候会执行static代码块。static代码块常用于初始化静态变量。static代码块只会被执行一次。
修饰内部类。static内部类可以不依赖外部类实例对象而被实例化。静态内部类不能与外部类有相同的名字,不能访问普通成员变量,只能访问外部类中的静态成员和静态成员方法。
13、java代码块执行顺序
父类静态代码块(只执行一次)
子类静态代码块(只执行一次)
父类构造代码块
父类构造函数
子类构造代码块
子类构造函数
普通代码块
14、简述java的hashmap
JDK8 之前底层实现是数组 + 链表,JDK8 改为数组 + 链表/红黑树。主要成员变量包括存储数据的 table 数组、元素数量 size、加载因子 loadFactor。 HashMap 中数据以键值对的形式存在,键对应的 hash 值用来计算数组下标,如果两个元素 key 的 hash 值一样,就会发生哈希冲突,被放到同一个链表上。
table 数组记录 HashMap 的数据,每个下标对应一条链表,所有哈希冲突的数据都会被存放到同一条链表,Node/Entry 节点包含四个成员变量:key、value、next 指针和 hash 值。在JDK8后链表超过8会转化为红黑树。
若当前数据/总数据容量>负载因子,Hashmap将执行扩容操作。 默认初始化容量为 16,扩容容量必须是 2 的幂次方、最大容量为 1<< 30 、默认加载因子为 0.75。
15、简述注解
Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。
其可以用于提供信息给编译器,在编译阶段时给软件提供信息进行相关的处理,在运行时处理写相应代码,做对应操作。
16、简述java基本数据类型
byte: 占用1个字节,取值范围-128 ~ 127
short: 占用2个字节,取值范围-2^15^ ~ 2^15^-1
int:占用4个字节,取值范围-2^31^ ~ 2^31^-1
long:占用8个字节
float:占用4个字节
double:占用8个字节
char: 占用2个字节
boolean:占用大小根据实现虚拟机不同有所差异
17、简述java中class对象
java中对象可以分为实例对象和Class对象,每一个类都有一个Class对象,其包含了与该类有关的信息。
获取Class对象的方法:
Class.forName(“类的全限定名”)
实例对象.getClass()
类名.class
18、简述java异常的分类
Java异常分为Error(程序无法处理的错误),和Exception(程序本身可以处理的异常)。这两个类均继承Throwable。
Error常见的有StackOverFlowError,OutOfMemoryError等等。
Exception可分为运行时异常和非运行时异常。对于运行时异常,可以利用try catch的方式进行处理,也可以不处理。对于非运行时异常,必须处理,不处理的话程序无法通过编译。
19、简述object类常用方法
hashCode:通过对象计算出的散列码。用于map型或equals方法。 需要保证同一个对象多次调用该方法,总返回相同的整型值。
equals:判断两个对象是否一致。需保证equals方法相同对应的对象hashCode也相同。
toString: 用字符串表示该对象
clone:深拷贝一个对象
20、简述自动拆箱装箱
对于Java基本数据类型,均对应一个包装类。
装箱就是自动将基本数据类型转换为包装器类型,如int->Integer
拆箱就是自动将包装器类型转换为基本数据类型,如Integer->int
21、构造方法、成员变量初始化以及静态成员变量三者的初始化顺序
先后顺序:静态成员变量、成员变量、构造方法。 详细的先后顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数。
22、java中线程安全的基本数据结构有哪些?
HashTable: 哈希表的线程安全版,效率低 ConcurrentHashMap:哈希表的线程安全版,效率高,用于替代HashTable Vector:线程安全版Arraylist Stack:线程安全版栈 BlockingQueue及其子类:线程安全版队列
23、Collection和Collections有什么区别?
Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如List、Set等。
Collections是一个包装类,包含了很多静态方法、不能被实例化,而是作为工具类使用,比如提供的排序方法: Collections.sort(list);提供的反转方法:Collections.reverse(list)。
24、简述java的list
List是一个有序队列,在JAVA中有两种实现方式:
ArrayList 使用数组实现,是容量可变的非线程安全列表,随机访问快,集合扩容时会创建更大的数组,把原有数组复制到新数组。
LinkedList 本质是双向链表,与 ArrayList 相比插入和删除速度更快,但随机访问元素很慢。
25、final、finally和finallize的区别是什么
final用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖、类不可继承。
finally作为异常处理的一部分,只能在try/catch语句中使用,finally附带一个语句块用来表示这个语句最终一定被执行,经常被用在需要释放资源的情况下。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的finalize()方法。当垃圾回收器准备好释放对象占用空间时,首先会调用finalize()方法,并在下一次垃圾回收动作发生时真正回收对象占用的内存。
26、java中的一维数组和二维数组的声明方式?
一维数组的声明方式:
type arrayName[]
type[] arrayName
二维数组的声明方式:
type arrayName[][]
type[][] arrayName
type[] arrayName[]
其中type为基本数据类型或类,arrayName为数组名字
27、简述java访问修饰符
default: 默认访问修饰符,在同一包内可见
private: 在同一类内可见,不能修饰类
protected : 对同一包内的类和所有子类可见,不能修饰类
public: 对所有类可见
28、简述StackOverflowError
调用栈深度超过限制产生的异常。 一般会在递归调用时出现,比如递归终止条件写的不对