面试题 (1)

一、Java 基础

  1. final 关键字的作用

被 final 修饰的类不可以被继承,被 final 修饰的方法不可以被重写,被 final 修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.被 final 修饰的方法,JVM 会尝试将其内联,以提高运行效率,被 final 修饰的常量,在编译阶段会存入常量池中.

  1. abstract class 和 interface 有什么区别?

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建 abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。

接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义 static final 成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换, instanceof 运算符可以用来决定某对象的类是否实现了接口

  1. 抽象类和接口的区别?

1、接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象修饰的方法。

2、类可以实现很多个接口,但是只能继承一个抽象类

3、类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。

4、抽象类可以在不提供接口方法实现的情况下实现接口。

5、Java 接口中声明的变量默认都是 final 的。抽象类可以包含非 final 的变量。

6、Java 接口中的成员函数默认是 public 的。抽象类的成员函数可以是 private,protecte或者是 public 。

7、接口是绝对抽象的,不可以被实例化(java 8 已支持在接口中实现默认的方法)。用default修饰的方法也可以写方法体  抽象类也不可以被实例化,但是,如果它包含 main 方法的话是可以被调用的。                                   

  1. 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 遵从先进先出原则

每一Queue实施必须指定排序性能

使用时尽量避免 add()和 remove()方法,而是使用offer()来添加元素,使用 poll()来移除元素,它的优点是可以通过返回值来判断是否成功,LinkedList实现了 Queue 接口,Queue 通常不允许插入 null 元素。

Stack

Stack 遵从后进先出原则,Stack 继承自 Vector,它通过五个操作对类 Vector 进行扩展,允许将向量视为堆栈,它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 peek()方法、测试堆栈是否为空的 empty 方法等。

如果涉及堆栈,队列等操作,建议使用 List。

对于快速插入和删除元素的,建议使用 LinkedList。如果需要快速随机访问元素的,建议使用 ArrayList。

  1. 说出 ArrayList,Vector, LinkedList 的存储性能和特性

ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差,而 LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。


  1. 内存泄漏和内存溢出?

内存泄漏(memoryleak),是指应用程序在申请内存后,无法释放已经申请的内存空间,一次内存泄漏危害可以忽略,但如果任其发展最终会导致内存溢出(outofmemory)。如读取文件后流要进行及时的关闭以及对数据库连接的释放。

内存溢出(outofmemory)是指应用程序在申请内存时,没有足够的内存空间供其使用。如我们在项目中对于大批量数据的导入,采用分批量提交的方式。


  1. 反射中,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 表示不进行链接,由上面介绍可以,不进行链接意味着不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行


  1. Int 和 Integer 的区

Integer 是 int 的包装类型,在拆箱和装箱中,二者自动转换.int 是基本类型,直接存数值;而 integer 是对象;用一个引用指向这个对象.由于 Integer 是一个对象,在 JVM 中对象需要一定的数据结构进行描述,相比 int 而言,其占用的内存更大一些.


  1. String、StringBuilder、StringBuffer  区别?

String 字符串常量 不可变 使用字符串拼接时是不同的 2 个空间 StringBuffer 字符串变量  可变  线程安全 字符串拼接直接在字符串后追加 StringBuilder 字符串变量 可变 非线程安全 字符串拼接直接在字符串后追

    1. StringBuilder 执行效率高于 StringBuffer 高于 String.
    2. String 是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象, StringBuffer 和 StringBuilder 都是可变的,当进行字符串拼接时采用 append 方法,在原来的基础上进行追加,所以性能比 String 要高,又因为 StringBuffer 是线程安全的而 StringBuilder 是线程非安全的,所以 StringBuilder 的效率高于 StringBuffer.
    3. 对于大数据量的字符串的拼接,采用 StringBuffer,StringBuilder.

  1. Hashtable 和 Hashmap 的区别?

1、HashTable 线程安全,HashMap 非线程安全

2、Hashtable 不允许 null 值(key 和 value 都不可以),HashMap 允许 null 值(key 和 value 都可以)。

3、两者的遍历方式大同小异,Hashtable 仅仅比 HashMap 多一个 elements 方法。

返回哈希表中的值的枚举

clone() 创建一个哈希表的浅拷贝相当于复制hashmap  clone对象新生成了一个数组。

  1. 说几个常见的编译时异常

SQLException  提供有关数据库访问错误或其他错误的信息的异常。

IOexception 表示发生了某种 I / O 异常的信号。此类是由失败或中断的 I / O 操作产生的一般异常类

FileNotFoundException 当试图打开指定路径名表示的文件失败时,抛出此异常。 ClassNotFoundException 找不到具有指定名称的类的定义。

EOFException  当输入过程中意外到达文件或流的末尾时,抛出此异常。

  1. 方法重载的规则?

方法名一致,参数列表中参数的顺序,类型,个数不同。重载与方法的返回值无关,存在于父类和子类,同类中。可以抛出不同的异常,可以有不同修饰符。

  1. 方法重写的规则?  

参数列表、方法名、返回值类型必须完全一致,构造方法不能被重写;声明为 final 的方法不能被重写;声明为 static 的方法不存在重写(重写和多态联合才有意义);访问权限不能比父类更低;重写之后的方法不能抛出更宽泛的异常

  1. throw 和 throws 的区别?

throw:

throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。throw 是具体向外抛出

异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常

 throws:

throws 语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型。throws  表示出现异常的一种可能性,并不一定会发生这种异常

  1. Java 的基础类型和字节大小?

布尔型 boolean 8 位;字节型 byte 8 位; 字符型 char 16 位;短整型 short 16 位;整形 int 32 位; 长整形 long 64 位; 浮点型 float 32 位;双精度 double 64 位;

  1. HashSet 的底层实现是什么

HashSet 的实现是依赖于 HashMap 的,HashSet 的值都是存储在 HashMap 中的。在 HashSet 的构造法中会初始化一个 HashMap 对象,HashSet 不允许值重复。

hashset 不同步的 所有出现  treeset 同步 

因此,HashSet 的值是作为 HashMap 的 key 存储在 HashMap 中的,当存储的值已经存在时返回 false。

  1. 抽象类的意义?(不会使用 用他的变体)

抽象类的意义可以用三句话来概括: 

1、为其他子类提供一个公共的类型

2、封装子类中重复定义的内容

3、定义抽象方法,子类虽然有不同的实现,但是定义时一致的

  1. 你为什么重写 equals 时必须重写 hashCode 方法?

hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。如果两个对象相等,则 hashcode 一定也是相同的如果两个对象相等,对两个对象分别调用 equals 方法都返回 true 如果两个对象有相同的 hashcode 值,它们也不一定是相等的因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。

hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值