JAVA最全面试题汇总基础篇(二)

网友投稿 273 2022-08-23

JAVA最全面试题汇总基础篇(二)

7 、 重载和重写的区别

重写 (Override)

从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子

类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,

参数列表,返回类型 ( 除过子类中方法的返回值是父类中方法返回值的子类时 ) 都相同的情况下,

方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。

public class Father { public static void main(String[] args) { // TODO Auto-generated method stub Son s = new Son(); s.sayHello(); } public void sayHello() { System.out.println("Hello"); }}class Son extends Father{@Override public void sayHello() { // TODO Auto-generated method stub System.out.println("hello by "); }}

重写 总结: 1. 发生在父类与子类之间 2. 方法名,参数列表,返回类型(除过子类中方法的返回类型

是父类中返回类型的子类)必须相同 3. 访问修饰符的限制一定要大于被重写方法的访问修饰符

( public>protected>default>private) 4. 重写方法一定不能抛出新的检查异常或者比被重写方法申

明更加宽泛的检查型异常

重载( Overload )

在一个类中,同名的方法如果有不同的参数列表( 参数类型不同、参数个数不同甚至是参数顺序不

同 )则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但 不能通过返回类型是

否相同来判断重载 。

public class Father { public static void main(String[] args) { // TODO Auto-generated method stub Father s = new Father(); s.sayHello(); s.sayHello("wintershii"); } public void sayHello() { System.out.println("Hello"); } public void sayHello(String name) { System.out.println("Hello" + " " + name); }}

重载 总结: 1. 重载 Overload 是一个类中多态性的一种表现 2. 重载要求同名方法的参数列表不同 ( 参

数类型,参数个数甚至是参数顺序 ) 3. 重载的时候,返回值类型可以相同也可以不相同。无法以返回

型别作为重载函数的区分标准

8 、 equals 与 == 的区别

== :

== 比较的是变量 ( 栈 ) 内存中存放的对象的 ( 堆 ) 内存地址,用来判断两个对象的地址是否相同,即是

否是指相同一个对象。比较的是真正意义上的指针操作。

1 、比较的是操作符两端的操作数是否是同一个对象。 2 、两边的操作数必须是同一类型的(可以是

父子类之间)才能编译通过。 3 、比较的是地址,如果是具体的阿拉伯数字的比较,值相等则为

true ,如: int a=10 与 long b=10L 与 double c=10.0 都是相同的(为 true ),因为他们都指向地

址为 10 的堆。

equals :

equals 用来比较的是两个对象的内容是否相等,由于所有的类都是继承自 java.lang.Object 类的,所

以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是 Object 类中的方法,而 Object

中的 equals 方法返回的却是 == 的判断。

总结:

所有比较是否相等时,都是用 equals 并且在对常量相比较时,把常量写在前面,因为使用 object 的

equals object 可能为 null 则空指针

在阿里的代码规范中只使用 equals ,阿里插件默认会识别,并可以快速修改,推荐安装阿里插件来

排查老代码使用 “==” ,替换成 equals

9 、 Hashcode 的作用

java 的集合有两类,一类是 List ,还有一类是 Set 。前者有序可重复,后者无序不重复。当我们在 set

中插入的时候怎么判断是否已经存在该元素呢,可以通过 equals 方法。但是如果元素太多,用这样

的方法就会比较满。

于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每

个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的

哈希码就可以确定该对象应该存储的那个区域。

hashCode 方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当

集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理

位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如

果这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相

同就散列其它的地址。这样一来实际调用 equals 方法的次数就大大降低了,几乎只需要一两次。

10 、 String 、 String StringBuffffer 和 StringBuilder 的区别是什

么 ?

阿里内部资料 String 是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个 fifinal 类型的

字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对 String 的操作都会生成

新的 String 对象。

private final char value[];

每次 + 操作 :

隐式在堆上 new 了一个跟原字符串相同的 StringBuilder 对象,再调用 append 方法 拼

接 + 后面的字符。

StringBuffffer 和 StringBuilder 他们两都继承了 AbstractStringBuilder 抽象类,从

AbstractStringBuilder 抽象类中我们可以看到

/*** The value is used for character storage.*/char[] value;

他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用 StringBuffffer 和

StringBuilder 来进行操作。 另外 StringBuffffer 对方法加了同步锁或者对调用的方法加了同步锁,所

以是线程安全的。 StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

11 、 ArrayList 和 linkedList 的区别

Array (数组)是基于索引 (index) 的数据结构,它使用索引在数组中搜索和读取数据是很快的。

Array 获取数据的时间复杂度是 O(1), 但是要删除数据却是开销很大,因为这需要重排数组中的所有

数据 , ( 因为删除数据以后 , 需要把后面所有的数据前移 )

缺点 : 数组初始化必须指定初始化的长度 , 否则报错

例如 :

int[] a = new int[4];//推介使用int[] 这种方式初始化int c[] = {23,43,56,78};//长度:4,索引范围:[0,3]

List— 是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式,它继承 Collection 。

List 有两个重要的实现类: ArrayList 和 LinkedList

ArrayList: 可以看作是能够自动增长容量的数组

ArrayList 的 toArray 方法返回一个数组

ArrayList 的 asList 方法返回一个列表

12 、 HashMap 和 HashTable 的区别

1 、两者父类不同

HashMap 是继承自 AbstractMap 类,而 Hashtable 是继承自 Dictionary 类。不过它们都实现了同时

实现了 map 、 Cloneable (可复制)、 Serializable (可序列化)这三个接口。

2 、对外提供的接口不同

Hashtable 比 HashMap 多提供了 elments() 和 contains() 两个方法。 elments() 方法继承自

Hashtable 的父类 Dictionnary 。 elements() 方法用于返回此 Hashtable 中的 value 的枚举。

contains() 方法判断该 Hashtable 是否包含传入的 value 。它的作用与 containsValue() 一致。事实

上, contansValue() 就只是调用了一下 contains() 方法。

3 、对 null 的支持不同

Hashtable : key 和 value 都不能为 null 。

HashMap : key 可以为 null ,但是这样的 key 只能有一个,因为必须保证 key 的唯一性;可以有多个

key 值对应的 value 为 null 。

4 、安全性不同

HashMap 是线程不安全的,在多线程并发的环境下,可能会产生死锁等问题,因此需要开发人员自

己处理多线程的安全问题。

Hashtable 是线程安全的,它的每个方法上都有 synchronized 关键字,因此可直接用于多线程中。

虽然 HashMap 是线程不安全的,但是它的效率远远高于 Hashtable ,这样设计是合理的,因为大部

分的使用场景都是单线程。当需要多线程操作的时候可以使用线程安全的 ConcurrentHashMap 。

ConcurrentHashMap 虽然也是线程安全的,但是它的效率比 Hashtable 要高好多倍。因为

ConcurrentHashMap 使用了分段锁,并不对整个数据进行锁定。

5 、初始容量大小和每次扩充容量大小不同

6 、计算 hash 值的方法不同

13 、 Collection 包结构,与 Collections 的区别

Collection 是集合类的上级接口,子接口有 Set 、 List 、 LinkedList 、 ArrayList 、 Vector 、 Stack 、

Set ;

Collections 是集合类的一个帮助类,

它包含有各种有关集合操作的静态多态方法,用于实现对各种

集合的搜索、排序、线程安全化等操作。此类不能实例化,就像一个工具类,服务于 Java 的

Collection 框架。

14 、 Java 的四种引用,强弱软虚

强引用

强引用是平常中使用最多的引用,强引用在程序内存不足( OOM )的时候也不会被回收,使用

方式:

String str = new String("str");System.out.println(str);

软引用

软引用在程序内存不足时,会被回收,使用方式:

// 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,// 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中TSoftReference wrf = new SoftReference(new String("str"));WeakReference wrf = new WeakReference(str);PhantomReference prf = new PhantomReference(new String("str"),new ReferenceQueue<>());

可用场景:

创建缓存的时候,创建的对象放进缓存中,当内存不足时, JVM 就会回收早先创建

的对象。

弱引用

弱引用就是只要 JVM 垃圾回收器发现了它,就会将之回收,使用方式:

WeakReference wrf = new WeakReference(str);

可用场景: Java 源码中的 java.util.WeakHashMap 中的 key 就是使用弱引用,我的理解就是,

一旦我不需要某个引用, JVM 会自动帮我处理它,这样我就不需要做其它操作。

虚引用

虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意

哦,其它引用是被 JVM 回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多

被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue ,

使用例子:

PhantomReference prf = new PhantomReference(new String("str"),new ReferenceQueue<>());

可用场景:

对象销毁前的一些操作,比如说资源释放等。 Object.finalize() 虽然也可以做这

类动作,但是这个方式即不安全又低效

上诉所说的几类引用,都是指对象本身的引用,而不是指 Reference 的四个子类的引用

(SoftReference 等 ) 。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Linux内核读取spi-nor flash sn
下一篇:十张GIFs让你弄懂递归等概念(什么是递归定义)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~