1.final 关键字的作用?
final可以修饰类,变量,方法
* 被 final 修饰的类不可以被继承
* 被 final 修饰的方法不可以被重写
* 被 final 修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
* 被 final 修饰的方法,JVM 会尝试将其内联,以提高运行效率,被 final 修饰的变量,在编译阶段会存入常量池中.
2.abstract class 和 interface 有什么区别?
抽象类(abstract)
声明方法的存在而不去实现它的类被叫做抽象类(abstract class),
抽象类不能创建的实例对象。
含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是都是抽象的。
如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
接口(interface)
interface 可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。
接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
下面比较一下两者的语法区别:
1.抽象类可以有构造方法,接口中不能有构造方法。
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
\4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
\5. 抽象类中可以包含静态方法,接口中不能包含静态方法
\6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
\7. 一个类可以实现多个接口,但只能继承一个抽象类。
* 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建 abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
* 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义 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
* Queue 遵从先进先出原则,使用时尽量避免 add()和 remove()方法,而是使用 offer()来添加元素,使用 poll()来移除元素,它的优点是可以通过返回值来判断是否成功,LinkedList实现了 Queue 接口,Queue 通常不允许插入 null 元素。
* Stack
* Stack 遵从后进先出原则,Stack 继承自 Vector,它通过五个操作对类 Vector 进行扩展允许将向量视为堆栈,它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 peek()方法、测试堆栈是否为空的 empty 方法等。
* 用法
* 如果涉及堆栈,队列等操作,建议使用 List。
* 对于快速插入和删除元素的,建议使用 LinkedList。如果需要快速随机访问元素的,建议使用ArrayList。
#### 4.说出 ArrayList,Vector, LinkedList 的存储性能和特性?
* ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差,而 LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
#### 5.内存泄漏和内存溢出?
* 内存泄漏(memoryleak),是指应用程序在申请内存后,无法释放已经申请的内存空间,一次内存泄漏危害可以忽略,但如果任其发展最终会导致内存溢出(outofmemory)。如读取文件后流要进行及时的关闭以及对数据库连接的释放。
* 内存溢出(outofmemory)是指应用程序在申请内存时,没有足够的内存空间供其使用。如我们在项目中对于大批量数据的导入,采用分批量提交的方式。
#### 6. 反射中,Class.forName()和 ClassLoader.loadClass()的区别?
* Class.forName(className) 方 法 , 内 部 实 际 调 用 的 方 法 是 Class.forName(className,true,classloader); 第 2 个 boolean 参数表示类是否需要初始化, Class.forName(className)默认是需要初始化,
* 一旦初始化,就会触发目标对象的 static 块代码执行, static 参数也也会被再次初始化 ,ClassLoader.loadClass(className) 方 法 , 内 部 实 际 调 用 的 方 法 是ClassLoader.loadClass(className,false);第 2 个 boolean 参数,表示目标对象是否进行链接, false 表示不进行链接,由上面介绍可以,不进行链接意味着不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行
#### 7. int 和 Integer 的区别?
* Integer 是 int 的包装类型,在拆箱和装箱中,二者自动转换.int 是基本类型,直接存数值;而 integer 是对象;用一个引用指向这个对象.由于 Integer 是一个对象,在 JVM 中对象需要一定的数据结构进行描述,相比 int 而言,其占用的内存更大一些.
#### 8. String、StringBuilder、StringBuffer 区别?
| String | 字符串常量 | 不可变 | 使用字符串拼接时是不同的 2 个空间 | |
| ------------------------ | ---------- | ---------- | --------------------------------- | ---------------------------- |
| StringBuffer | 字符串变量 | 可变 | 线程安全 | 字符串拼接直接在字符串后追加 |
| StringBuilder 字符串变量 | 可变 | 非线程安全 | 字符串拼接直接在字符串后追加 | |
* StringBuilder 执行效率高于 StringBuffer 高于 String.
* String 是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象,StringBuffer 和 StringBuilder 都是可变的,当进行字符串拼接时采用 append 方法,在原来的基础上进行追加,所以性能比 String 要高,又因为 StringBuffer是线程安全的而 StringBuilder 是线程非安全的,所以 StringBuilder 的效率高于 StringBuffer.
* 对于大数据量的字符串的拼接,采用 StringBuffer,StringBuilder.
#### 9. Hashtable 和 Hashmap 的区别?
* HashTable 线程安全,HashMap 非线程安全
2、Hashtable 不允许 null 值(key 和 value 都不可以),HashMap 允许 null 值(key 和 value 都可以)。
两者的遍历方式大同小异,Hashtable 仅仅比 HashMap 多一个 elements 方法。
#### 10. 说几个常见的编译时异常?
* SQLException 提供有关数据库访问错误或其他错误的信息的异常。
IOexception 表示发生了某种 I / O 异常的信号。此类是由失败或中断的 I / O 操作产生的
一般异常类 FileNotFoundException 当试图打开指定路径名表示的文件失败时,抛出此异常。
ClassNotFoundException 找不到具有指定名称的类的定义。
EOFException (读取到文件尾部的时候)当输入过程中意外到达文件或流的末尾时,抛出此异常。
方法重载的规则?
同一个类中,方法名一致,参数列表不同(顺序,类型,个数)。可以抛出不同的异常,可以有不同修饰符。重载与方法的返回值无关,存在于父类和子类,同类中。
方法重写的规则?
参数列表、方法名、返回值类型必须完全一致,构造方法不能被重写;
声明为 final 的方法不能被重写;
声明为 static 的方法不存在重写(重写和多态联合才有意义);
访问权限不能比父类更低;
重写之后的方法不能抛出更宽泛的异常
子类无法重写父类的私有方法
throw 和 throws 的区别?
throw:throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。throw 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常。
throws:throws 语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的
异常的类型。throws 表示出现异常的一种可能性,并不一定会发生这种异常。
抽象类和接口的区别?
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java 接口中声明的变量默认都是 final 的。抽象类可以包含非 final 的变量。
Java 接口中的成员函数默认是 public 的。抽象类的成员函数可以是 private,protecte或者是 public 。
接口是绝对抽象的,不可以被实例化(java 1.8 已支持在接口中实现默认的方法)。抽象类也不可以被实例化,但是,如果它包含 main 方法的话是可以被调用的。
Java 的基础类型和字节大小? bit 8个 = 1 个 byte
四个访问修饰符合访问级别?
public、protected、默认的(没有访问修饰符)、private
String 和 StringBuffer 的区别?
String 和 StringBuffer 主要区别是性能:String 是不可变对象,每次对 String 类型进行操作都等同于产生了一个新的 String 对象,然后指向新的 String 对象.所以尽量不要对 String 进行大量的拼接操作,否则会产生很多临时对象,导致 GC 开始工作,影响系统性能.StringBuffer 是对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用 StringBuffer(线程安全).
HashSet 的底层实现是什么?
HashSet 的实现是依赖于 HashMap 的,HashSet 的值都是存储在 HashMap 中的。在 HashSet 的构造方法中会初始化一个 HashMap 对象,HashSet 不允许值重复。因此,HashSet 的值是作为 HashMap 的 key 存储在 HashMap 中的,当存储的值已经存在时返回 false。
抽象类的意义?(定义规则,提高代码复用性)
抽象类的意义可以用三句话来概括:
1、为其他子类提供一个公共的类型
2、封装子类中重复定义的内容
3、定义抽象方法,子类虽然有不同的实现,但是定义时一致的
你为什么重写 equals 时必须重写 hashCode 方法?
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。如果两个对象相等,则 hashcode 一定也是相同的,如果两个对象相等,对两个对象分别调用 equals 方法都返回 true 如果两个对象有相同的 hashcode 值,它们也不一定是相等的因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据).