一、JAVA基础理解
1.final 关键字的作用
- 类:被修饰的类不能被继承。
- 方法:被修饰的方法不能被重写。
- 变量:被修饰的变量如果是基本类型则其值不可更改,如果是引用类型,则其引用不可改变,引用的值可变。
- 被final修饰的方法,JVM会尝试对其进行内联,提高运行效率。
- 被final修饰的常量,在编译阶段将其值存入常量池。
2.abstract class 与 interface有什么区别?
-
抽象类:声明方法的存在而不去实现它的类被称作抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但是不能在该类中实现该类的情况,不能创建abstract类的实例。却可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法,Abstract类的子类为它们父类中的所有抽象方法提供实现。否则他们也是抽象类。取而代之,在子类中实现该方法。知道其行为的其他类可以再类中实现这些方法。
-
接口:是抽象类的变体。在接口中,所有方法都是抽象的。多继承性,可以通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量,接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法,然后,他可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换道接口类型或从接口类型转换,Instanceof 运算符可以用来决定某对象的类是否实现了接口。
3.JAVA集合类:list、set、queue、map、stack 的特点与用法
-
Map:Map是键值对,键Key是唯一不能重复的,一个键对应一个值,值可以重复,TreeMap可以保证顺序,HashMap不保证顺序,即无序的。Map中可以将Key,Value单独抽取出来,KeySet()方法将所有的keys取出来封装成一个Set,Values()方法可以将Map中所有values抽取出来封装成一个set集合,不包含仇富元素的集合
-
Set:不包含重复元素的集合,最多包含一个Null元素,可以用iterator()对其进行遍历,Set中没有同步方法。
-
List:有序的可重复的集合,可以再任意位置增加删除元素,通过iterator实现单向遍历,ListIterator实现双向遍历
-
Queue:遵从先进先出原则,使用时候避免使用add()与remove()方法,而是使用offer()添加元素,使用poll()来移除元素,优点,可通过返回值判断是否成功。LinkedList实现了Queue接口,Queue不允许插入null元素
-
Stack:遵从先进后出原则,继承自Vector,通过五个操作对类Vector进行扩展,允许将向量视为堆栈,提供了通常的push与pop操作,以及取出堆栈顶点的peek()方法,测试对战是否为空的empty方法等。
-
用法:
- 如果涉及堆栈,队列等操作,使用List
- 对于需要快速插入和删除元素使用LinkedList
- 如果需要快速随机访问元素,使用ArrayList
4.说出ArrayList,Vector,LinkedList 的存储性能和特性
ArrayList与Vector内部都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,他们都允许直接按需要索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项前后项即可,所以插入速度较快。
5.内存泄漏和内存溢出
内存泄漏(memoryleak),是指应用程序在申请内存后,无法释放已经申请的内存空间,一次内存泄漏危害可以忽略,但如果任其发展最终会导致内存溢出。例如读取文件后流要及时关闭以及对数据库连接的释放。
内存溢出(outofmemory),是指应用程序在申请内存时,没有足够的内存供其使用。如我们在项目中对于大批量数据的导入,采用分批量提交的方式。
6.反射中,Class.forName() 和 ClassLoader.loadClass()的区别
Class.forName(className) 方法,内部实际调用的方法是Class.forName(className,true,classloader):第2个boolean参数表示类是否需要初始化,Class.forName(className)默认是需要初始化,一旦初始化,就会触发目标对象的static 块代码执行,static参数也会被再次初始化ClassLoader.loadClass(className)方法,内部实际调用的方法是Class.loadClass(className,flase);第二个boolean参数,表示目标对象,是否进行链接,flase表示不进行链接,由上面介绍可以,不进行链接意味着不进行包括初始化等一系列步骤,那么静态块和静态对象就不会得到执行。
7.Int和Integer的区别
Integer是int的包装类型,在拆箱和装箱中,二者自动转换,int是基本类型,直接存数值;Integer是对象,使用一个引用指向这个对象。由于Integer是一个对象,在JVM中对象需要一定的数据结构进行描述,相比int而言。其占用的内存更大一些。
8.String、StringBuilder、StringBuffer 区别
String 字符串常量 不可变 使用字符串拼接时是不同的2个空间
StringBuffer 字符串变量 可变 线程安全 字符串拼接直接在字符串后追加
StringBuilder 字符串变量 可变 非线程安全 字符串拼接直接在字符串追加
1、StringBuilder 执行效率高于StringBuffer 高于String
2、String是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象,StringBuffer和StringBuilder都是可变的,当进行字符串拼接时采用append方法,在原来的基础上进行追加,所以性能比String要高,又因为StringBuffer是线程安全的而StringBuilder是线程非安全的,所以StringBuilder的效率高于StringBuffer.
3、对于大数据量的字符串的拼接,采用StringBuffer,StringBuilder.
9.hashtable 和 hasmap的区别
1.HashTable线程安全,HashMap线程不安全
2.HashTable不允许null值(key 与value都不行),HashMap允许
3.两者遍历方式大同小异,Hashtable仅仅比HashMap多一个elements方法
10.说几个常见的编译时异常类
- NullPointerException 空指针异常
- ArrayIndexOutOfBoundsException 数组下标越界
- NumberFormatException 数字转换异常
- IllegalArgumentException 参数不匹配异常
- InstantiationException 对象初始化异常
- ArithmeticException 算数异常
11.方法重载的规则
方法名一致,参数列表中参数的顺序,类型,个数不同。
重载与方法的返回值无关,存在于父类和子类,同类中。
可以抛出不同的异常,可以有不同修饰符。
12.方法重写的规则
参数列表、方法名、返回值类型必须一致;构造方法不能被重写,声明为final的方法不能被重写;声明为static的方法不存在重写(重写和多态联合才有意义),访问权限不能比父类更低,重写之后的方法不能抛出更宽泛的异常;