我认为很有用的3万字Java面试题总结(2022版)

前言:

在经历了这个疫情、裁员的金三银四,劳动节的假期就要来了,有的人跳槽成功有的人还在备战!想在面试、工作中脱颖而出?想在最短的时间内快速掌握Java 的核心基础知识点?想要成为一位优秀的 Java 工程师?这个2022年面试题总结今天就分享给大家。

在这里插入图片描述

另外本人整理收藏了22年多家公司面试知识点整理 ,以及各种Java核心知识点免费分享给大家,我认为对面试来说是非常有用的,想要资料的话请点白嫖这份答案←戳我**

在这里插入图片描述

1.Java 自动装箱与拆箱

装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer 的 valueOf(int) 方法

拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int)。调用方法:Integer 的 intValue 方法

在 Java SE5 之前,如果要生成一个数值为 10 的 Integer 对象,必须这样进行:

Integer i = new Integer(10);

而在从 Java SE5 开始就提供了自动装箱的特性,如果要生成一个数值为 10 的 Integer 对象,只需要这

样就可以了:

Integer i = 10;

2.重载和重写的区别

重写(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 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)重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准

3.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

4. Hashcode 的作用

java 的集合有两类,一类是 List,还有一类是 Set。前者有序可重复,后者无序不重复。当我们在 set 中插入的时候怎么判断是否已经存在该元素呢,可以通过 equals 方法。但是如果元素太多,用这样的方法就会比较满。

于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。

hashCode 方法可以这样理解:它返回的就是根据对象的内存地址换算出的一个值。这样一来,当集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。这样一来实际调用 equals 方法的次数就大大降低了,几乎只需要一两次。

5.String、String StringBuffer 和 StringBuilder 的区别是什么?

String 是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final 类型的字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对 String 的操作都会生成新的 String 对象。

private final char value[];

每次+操作 : 隐式在堆上 new 了一个跟原字符串相同的 StringBuilder 对象,再调用 append 方法 拼接+后面的字符。

StringBuffer 和 StringBuilder 他们两都继承了 AbstractStringBuilder 抽象类,从 AbstractStringBuilder 抽象类中我们可以看到。

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

他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用 StringBuffer 和 StringBuilder 来进行操作。 另外 StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

6.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 方法返回一个列表

ArrayList 底层的实现是 Array, 数组扩容实现

LinkList 是一个双链表,在添加和删除元素时具有比 ArrayList 更好的性能.但在 get 与 set 方面弱于

ArrayList.当然,这些对比都是指数据量很大或者操作很频繁。

7.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)计算 hash 值的方法不同

8.Collection 包结构,与 Collections 的区别

Collection 是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;Collections 是集合类的一个帮助类, 它包含有各种有关集合操作的静态多态方法,用于实现对各种集合的搜索、排序、线程安全化等操作。此类不能实例化,就像一个工具类,服务于 Java 的 Collection 框架。

9.Java 的四种引用,强弱软虚

强引用

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

String str = new String("str");

软引用

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

// 注意:wrf 这个引用也是强引用,它是指向 SoftReference 这个对象的,
// 这里的软引用指的是指向 new String("str")的引用,也就是 SoftReference 类中 T
SoftReference<String
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值