java高频面试题(2023最新)

Posted 爱穿背带裤的馫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java高频面试题(2023最新)相关的知识,希望对你有一定的参考价值。

目录


后续会持续更新,广告回来更精彩!如果想看原理可以看看我的另几篇文章
没有过多的讲解原理,你们只要背会了,就能快乐两年半。

一.java基础

1.八大基础类型

数字型: 字节类型(byte)、短整型short、整型int、长整型Long、单精度浮点数float、双精度浮点数double
字符型: 字符类型char、
布尔型: 布尔类型boolean、

2.java三大特性

封装: 使用private关键字,让对象私有,防止无关的程序去使用。
继承: 继承某个类,使子类可以使用父类的属性和方法。
多态: 同一个行为,不同的子类具有不同的表现形式。

3.重载和重写的区别

重载: 发生在同一类中,函数名必须一样,参数类型、参数个数、参数顺序、返回值、修饰符可以不一样。
重写: 发生在父子类中,函数名、参数、返回值必须一样,访问修饰符必须大于等于父类,异常要小于等于父类,父类方法是private不能重写。

4.pubilc、protected、(dafault)不写、private修饰符的作用范围

pubilc: 同类、同包、子类、不同包都可以使用。
protected: 同类、同包、子类可以使用,不同包不能。
(dafault)不写: 同类、同包可以使用,子类、不同包不能。
private: 只有同类可以。

5.==和equals的区别

==: 基础类型比较的值,引用类型比较的是地址值。
equals: 没有重写比较地址值是否相等,重写比较的内容是否相对。比如String类重写equals,源码首先比较是否都是String对象,然后再向下比较。

6.hashcode()值相同,equals就一定为true

不一定,因为 "重地"和"通话"的hashcode值就相同,但是equals()就为false。
但是equals()为true,那么hashcode一定相同。

7.为什么重写equals(),就要重写hashcode()?

保证同一对象,如果不重写hashcode,可能会出现equals比较一样,但是hashcode不一样的情况。

8.short s = 1;s = s + 1;(程序1)和 short s = 1; s += 1;(程序2)是否都能正常运行

程序1会编译报错,因为 s + 1的1是int类型,因为类型不兼容。强制转换失败。
程序2可以正常运行,因为java在复合赋值解释是 E1 += E2,等价于 E1 = (T)(E1 + E2),T是E1的类型,因此s += 1等价于 s = (short)(s + 1),所以进行了强制类型的转换,所以可以正常编译。

9.说出下面程序的运行结果,及原因

public static void main(String[] args) 
    Integer a = 128, b = 128, c = 127, d = 127;
    System.out.println(a == b);
    System.out.println(c == d);

结果:falsetrue

因为Integer = a,相当于自动装箱(基础类型转为包装类),因为Integer引入了IntegerCache来缓存一定的值,IntegerCache默认是 -128~127,所以128超过了范围,a和b不是相同对象,c和d是相同对象。
可以通过jvm启动时,修改缓存的上限。

10.&和&&的区别

&&: 如果一边为假,就不比较另一边。具有短路行
&: 两边都为假,结果才为假,多用于位运算。

11.String、StringBuffer、StringBuilder的区别

String: 适用于少量字符串。创建之后不可更改,对String的修改会生成新的String对象。
StringBuilder: 适用于大量字符串,线程不安全,性能更快。单线程使用
StringBuffer: 适用于大量字符串,线程安全。多线程使用,用synchronized关键字修饰。

12.String rap = new String(“ctrl”);创建了几个对象?

一个或两个,如果常量池存在,那就在堆创建一个实例对象,否则常量池也需要创建一个。

13.什么是反射

在运行过程中,对于任何一个类都能获取它的属性和方法,任何一个对象都能调用其方法,动态获取信息和动态调用,就是反射。

14.浅拷贝和深拷贝的区别

浅拷贝: 基础数据类型复制值,引用类型复制引用地址,修改一个对象的值,另一个对象也随之改变。
深拷贝: 基础数据类型复制值,引用类型在新的内存空间复制值,新老对象不共享内存,修改一个值,不影响另一个。

深拷贝相对浅拷贝速度慢,开销大。

15.构造器能被重写吗

不能,可以被重载。

16.并发和并行

并发: 一个处理器同时处理多个任务。(一个人同时吃两个苹果)
并行: 多个处理器同时处理多个任务。(两个人同时吃两个苹果)

17.实例变量和类变量。

类变量是被static所修饰的,没有被static修饰的叫实例变量也叫成员变量。同理也存在类对象和实例对象,类方法和实例方法。

//类变量
public static String kunkun1 = "鸡你太美";

//实例变量(成员变量)
public String kunkun2 = "鸡你不美";

18.说出下面程序的运行结果,及原因

public class InitialTest 
    public static void main(String[] args) 
        A ab = new B();
        ab = new B();
    

class A 
    static  // 父类静态代码块
        System.out.print("A");
    
    public A()  // 父类构造器
        System.out.print("a");
    

class B extends A 
    static  // 子类静态代码块
        System.out.print("B");
    
    public B()  // 子类构造器
        System.out.print("b");
    


结果:ABabab

原因:
①执行顺序是 父类静态代码块(父类静态变量) -> 子类静态代码块(子类静态变量) -> 父类非静态代码块 -> 父类构造方法 -> 子类非静态代码块 -> 子类构造方法
②静态代码块(静态变量)只执行一次。

19.抽象类和接口的区别

抽象类只能单继承,接口可以实现多个。
抽象类有构造方法,接口没有构造方法。
抽象类可以有实例变量,接口中没有实例变量,有常量。
抽象类可以包含非抽象方法,接口在java7之前所有方法都是抽象的,java8之后可以包含非抽象方法。
抽象类中方法可以是任意修饰符,接口中java8之前都是public,java9支持private。
扩展:普通类是亲爹,手把手教你怎么学,抽象类(多个类具有相同的东西,拿出来放抽象类)是师傅,教你一部分秘籍,然后告诉你怎么学。接口(规范了某些行为)是干爹,只给你秘籍,怎么学全靠你。

20.Error和Exception有什么区别

Error: 程序无法处理,比较严重的问题,程序会立即崩溃,jvm停止运行。
Exception: 程序本身可以处理(向上抛出或者捕获)。编译时异常和运行时异常

21.NoClassDefFoundError和ClassNotFoundException区别

NoClassDefFoundError: 在打包时漏掉了某些类或者打包时存在,然后你把target里的类删除,然后jvm运行时找不到报错。
ClassNotFoundException: 在编译的时候某些类找不到,然后报错。

22.如果try 里有一个 return 语句,那么finally 里的代码会不会被执行,什么时候被执行,在 return 前还是后?

会执行,在return之前执行,如果finally有return那么try的return就会失效。

23.看一面代码执行结果是啥

public class TryDemo 
    public static void main(String[] args) 
        System.out.println(test1());
    
    public static int test1() 
        int i = 0;
        try 
            i = 2;
            return i;
         finally 
            i = 3;
        
    

结果 2

因为在return前,jvm会把2暂存起来,所以当i改变了,回到try时,还是会返回暂存的值。

24.final关键字有哪些用法?

修饰类: 不能被继承。
修饰方法: 不能被重写。
修饰变量: 声明时给定初始值,只能读取不能修改。如果是对象引用不能改,但是对象的属性可以修改。

25.jdk1.8的新特性

①lambda 表达式
②方法引用
③加入了base64的编码器和解码器
④函数式接口
⑤接口允许定义非抽象方法,使用default关键字即可
⑥时间日期类改进

26.http中重定向和转发的区别

重定向发送两次请求,转发发送一次请求
重定向地址栏会变化,转发地址栏不会变化
重定向是浏览器跳转,转发是服务器跳转
重定向可以跳转任意网址,转发只能跳转当前项目
重定向会有数据丢失,转发不会数据丢失

27.get和post请求的区别 delete、put

get相对不安全,数据放在url中(请求行),post放在body中(请求体),相对安全。
get传送的数据量小,post传送的数据量大。
get效率比post高,是form的默认提交方法。

28.cookie和session的区别

存储位置不同:cookie放在客户端电脑,session放在服务器端内存的一个对象
存储容量不同:cookie <=4KB,一个站点最多保存20个cookie,session是没有上限的,但是性能考虑不要放太多,而且要设置session删除机制
存储方式不同:cookie只能存储ASCLL字符串,session可以存储任何类型的数据
隐私策略不同:cookie放在本地,别人可以解析,进行cookie欺骗,session放在服务器,不存在敏感信息泄露
有效期不同:可以设置cookie的过期时间,session依赖于jsessionID的cookie,默认时间为-1,只需要关闭窗口就会失效

29.java中的数据结构

数组、链表、哈希表、栈、堆、队列、树、图

30.什么是跨域?跨域的三要素

跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制
协议、域名、端口
注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域

31.tomcat三个默认端口及其作用

8005:这个端口负责监听关闭tomcat的请求。
8009:接受其他服务器的请求
8080:用于监听浏览器发送的请求

32.throw 和 throws 的区别?

throw:抛出一个异常。
throws:声明一个异常。

33.说一下你熟悉的设计模式

单例模式: 保证被创建一次,节省系统开销。
工厂模式: 解耦代码。
观察者模式: 定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
代理模式: 代理对象具备被代理对象的功能,并代替被代理对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理。
模板模式: 较少代码冗余。例如:redis模板。

34.实例化对象有哪几种方式

① new
② clone()
③ 反射
④先序列化在反序列化

35.序列化和反序列化

序列化: 把对象转为字节序列的过程,在传递和保存对象时,保证了对象的完整性和可传递性,便于在网络传输和保存在本地文件中。
反序列化: 把字节序列转为对象的过程,通过字节流的状态和信息描述,来重建对象。

36.序列化的优点

将对象转为字节流存储到硬盘上,当JVM噶了的话,字节流还会在硬盘上等待,等待下一次JVM的启动,把序列化的对象,通过反序列化为原来的对象,减少储存空间和方便网络传输(因为是二进制)。

37.你知道什么是单点登录吗?

单点登录(SSO:Single Sign On): 同一账号在多系统中,只登录一次,就可以访问其他系统。多个系统,统一登录。
列如:在一个公司下,有多个系统,比如淘宝和天猫,你登录上淘宝,就不用再去登录天猫了。

38.实现单点登录的方式

① Cookie: 用cookie为媒介,存放用户凭证。登录上父应用,返回一个加密的cookie,访问子应用的时候,会对cookie解密校验,通过就可以登录。不安全和不能跨域免登。
② 分布式session实现: 用户第一次登录,会把用户信息记录下来,写入session,再次登录查看session是否含有对应信息。session系统不共享,使用缓存等方式来解决。
③重定向: 父应用提供一个GET方式的登录接口A,用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个登录页面,用户输入账号密码进行登录,如果用户已经登录了,则生成加密的token,并且重定向到子应用提供的验证token的接口B,通过解密和校验之后,子应用登录当前用户,虽然解决了安全和跨域,但是没前两种简单。

39.sso(单点登录)与OAuth2.0(授权)的区别?

单点登录: 就是一个公司多个子系统登录问题。
OAuth2.0: 是授权问题,比如微信授权问题。是一种具体的协议。

40.如何防止表单提交

①js屏蔽提交按钮。
②给数据库添加唯一约束。
③利用Session防止表单重复提交。会有一个token标记,表单提交的时候拦截器会检查是否一致,不一致就不通过。
④使用AOP切入实现。自定义注解,然后新增切入点,然后每次都记录过期时间,然后做比较。

41.泛型是什么?有什么好处?

本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
好处:
①类型安全
②消除强制类型转换
③提高性能
④提高代码的复用性

42.值传递和引用传递

值传递: 函数调用时会把实际参数,复制一份到函数中,函数中对参数进行操作,并不会影响参数实际的值。
引用传递: 将实际参数的地址值传递到函数中,函数对参数进行操作,会影响到实际参数的值。
注意: java中不存在引用传递(即使传的是对象,那也只是传递了对象的引用地址的副本,也属于值传递)。

二.java集合

java集合框架详解

HashMap底层原理详解

1.List、Set、Map的区别

List集合有序、可重复的单例集合。
Set集合无序、不可重复的单例集合。
Map集合有序、k不可重复,v可重复的双例集合。

2.List、Set、Map常用集合有哪些?

List
vector: 底层是数组,方法加了synchronized来保证线程安全,所以效率较慢,使用ArrayList替代。
ArrayList: 线程不安全,底层是数组,因为数组都是连续的地址,所以查询比较快。增删比较慢,增会生成一个新数组,把新增的元素和原有元素放到新数组中,删除会导致元素移动,所以增删速度较慢。
LinkedList: 线程不安全,底层是链表,因为地址不是连续的,都是一个节点和一个节点相连,每次查询都得重头开始查询,所以查询慢,增删只是断裂某个节点对整体影响不大,所以增删速度较快。

Set
HashSet: 底层是哈希表(数组+链表或数组+红黑树),在链表长度大于8时转为红黑树,在红黑树节点小于6时转为链表。其实就是实现了HashMap,值存入key,value是一个final修饰的对象。
TreeSet: 底层是红黑树结构,就是TreeMap实现,可以实现有序的集合。String和Integer可以根据值进行排序。如果是对象需要实现Comparator接口,重写compareTo()方法制定比较规则。
LinkedHashSet: 实现了HashSet,多一条链表来记录位置,所以是有序的。

Map<key,value>双例结构
TreeMap: 底层是红黑树,key可以按顺序排列。
HashMap: 底层是哈希表,可以很快的储存和检索,无序,大量迭代情况不佳。
LinkedHashMap: 底层是哈希表+链表,有序,大量迭代情况佳。

3.什么是哈希表

根据关键码值(Key value)而直接进行访问的数据结构,在一个表中,通过H(key)计算出key在表中的位置,H(key)就是哈希函数,表就是哈希表。

4.什么是哈希冲突

不同的key通过哈希函数计算出相同的储存地址,这就是哈希冲突。

5.解决哈希冲突

(1)开放地址法
如果发生哈希冲突,就会以当前地址为基准,再去寻找计算另一个位置,直到不发生哈希冲突。
寻找的方法有:① 线性探测 1,2,3,m
② 二次探测 1的平方,-1的平方,2的平方,-2的平方,k的平方,-k的平方,k<=m/2
③ 随机探测 生成一个随机数,然后从随机地址+随机数++。

(2)链地址法
冲突的哈希值,连到到同一个链表上。

(3)再哈希法(再散列方法)
多个哈希函数,发生冲突,就在用另一个算计,直到没有冲突。

(4)建立公共溢出区
哈希表分成基本表和溢出表,与基本表发生冲突的都填入溢出表。

6.HashMap的hash()算法,为什么不是h=key.hashcode(),而是key.hashcode()^ (h>>>16)

得到哈希值然后右移16位,然后进行异或运算,这样使哈希值的低16位也具有了一部分高16位的特性,增加更多的变化性,减少了哈希冲突。

7.为什么HashMap的初始容量和扩容都是2的次幂

因为计算元素存储的下标是(n-1)&哈希值,数组初始容量-1,得到的二进制都是1,这样可以减少哈希冲突,可以更好的均匀插入。

8.HashMap如果指定了不是2的次幂的容量会发生什么?

会获得一个大于指定的初始值的最接近2的次幂的值作为初始容量。

9.HashMap为什么线程不安全

jdk1.7中因为使用头插法,再扩容的时候,可能会造成闭环和数据丢失。
jdk1.8中使用尾插法,不会出现闭环和数据丢失,但是在多线程下,会发生数据覆盖。(put操作中,在putVal函数里) 值的覆盖还有长度的覆盖。

10.解决Hashmap的线程安全问题

(1)使用Hashtable解决,在方法加同步关键字,所以效率低下,已经被弃用。
(2)使用Collections.synchronizedMap(new HashMap<>()),不常用。
(3)ConcurrentHashMap(常用)

11.ConcurrentHashMap的原理

jdk1.7: 采用分段锁,是由Segment(继承ReentrantLock:可重入锁,默认是16,并发度是16)和HashEntry内部类组成,每一个Segment(锁)对应1个HashEntry(key,value)数组,数组之间互不影响,实现了并发访问。
jdk1.8: 抛弃分段锁,采用CAS(乐观锁)+synchronized实现更加细粒度的锁,Node数组+链表+红黑树结构。只要锁住链表的头节点(树的根节点),就不会影响其他数组的读写,提高了并发度。

12.为什么用synchronized代替ReentrantLock

①节省内存开销。ReentrantLock基于AQS来获得同步支持,但不是每个节点都需要同步支持,只有链表头节点或树的根节点需要同步,所以使用ReentrantLock会带来很大的内存开销。
②获得jvm支持,可重入锁只是api级别,而synchronized是jvm直接支持的,能够在jvm运行时做出相应的优化。
③在jdk1.6之后,对synchronized做了大量的优化,而且有多种锁状态,会从 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁一步步转换。

AQS (Abstract Queued Synchronizer): 一个抽象的队列同步器,通过维护一个共享资源状态( Volatile Int State )和一个先进先出( FIFO )的线程等待队列来实现一个多线程访问共享资源的同步框架。

13.HashMap为什么使用链表

减少和解决哈希冲突,把冲突的值放在同一链表下。

14.HashMap为什么使用红黑树

当数据过多,链表遍历较慢,所以引入红黑树。

15.HashMap为什么不一上来就使用红黑树

维护成本较大,红黑树在插入新的数据后,可能会进行变色、左旋、右旋来保持平衡,所以当数据少时,就不需要红黑树。

16.说说你对红黑树的理解

①根节点是黑色。
②节点是黑色或红色。
③叶子节点是黑色。
④红色节点的子节点都是黑色。
⑤从任意节点到其子节点的所有路径都包含相同数目的黑色节点。
红黑树从根到叶子节点的最长路径不会超过最短路径的2倍。保证了红黑树的高效。

17.为什么链表长度大于8,并且表的长度大于64的时候,链表会转换成红黑树?

因为链表长度越长,哈希冲突概率就越小,当链表等于8时,哈希冲突就非常低了,是千万分之一,我们的map也不会存那么多数据,如果真要存那么多数据,那就转为红黑树,提高查询和插入的效率。

18.为什么转成红黑树是8呢?而重新转为链表阈值是6呢?

因为如果都是8的话,那么会频繁转换,会浪费资源。

19.为什么负载因子是0.75?

加载因子越大,填满的元素越多,空间利用率越高,但发生冲突的机会变大了;
加载因子越小,填满的元素越少,冲突发生的机会减小,但空间浪费了更多了,而且还会提高扩容rehash操作的次数。
“冲突的机会”与“空间利用率”之间,寻找一种平衡与折中。
又因为根据泊松分布,当负载因子是0.75时,平均值时0.5,带入可得,当链表为8时,哈希冲突发生概率就很低了。

20.什么时候会扩容?

元素个数 > 数组长度 * 负载因子 例如 16 * 0.75 = 12,当元素超过12个时就会扩容。
链表长度大于8并且表长小于64,也会扩容

21.为什么不是满了扩容?

因为元素越多,空间利用率是高了,但是发生哈希冲突的几率也增加了。

22.扩容过程

jdk1.7: 会生成一个新table,重新计算每个节点放进新table,因为是头插法,在线程不安全的时候,可能会出现闭环和数据丢失。
jdk1.8: 会生成一个新table,新位置只需要看(e.hash & oldCap)结果是0还是1,0就放在旧下标,1就是旧下标+旧数组长度。避免了对每个节点进行hash计算,大大提高了效率。e.hash是数组的hash值,,oldCap是旧数组的长度。

23.HashMap和Hashtable的区别

①HashMap,运行key和value为null,Hashtable不允许为null。
②HashMap线程不安全,Hashtable线程安全。

24.集合为什么要用迭代器(Iterator)

更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。
如果不用迭代器,只能for循环,还必须知道集合的数据结构,复用性不强。

三.多线程

java多线程及线程池原理讲解

1.线程是什么?多线程是什么?

线程: 是最小的调度单位,包含在进程中。
多线程: 多个线程并发执行的技术。

2.守护线程和用户线程

守护线程: jvm给的线程。比如:GC守护线程。
用户线程: 用户自己定义的线程。比如:main()线程。

拓展:
Thread.setDaemon(false)设置为用户线程
Thread.setDaemon(true)设置为守护线程

3.线程的各个状态

新建(New): 新建一个线程。
就绪(Runnable): 抢夺cpu的使用权。
运行(Running): 开始执行任务。
阻塞(Blocked): 让线程等待,等待结束进入就绪队列。
死亡(Dead): 线程正常结束或异常结束。

4.线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等

wait(): 线程等待,会释放锁,用于同步代码块或同步方法中,进入等待状态
sleep(): 线程睡眠,不会释放锁,进入超时等待状态
yield(): 线程让步,会使线程让出cpu使用权,进入就绪状态
join(): 指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。
notify(): 随机唤醒一个在等待中的线程,进入就绪状态。
notifyAll(): 唤醒全部在等待中的线程,进入就绪状态。

5.wait()和sleep()的区别?

① wait() 来自Object,sleep()来自Thread。
② wait()会释放锁,sleep()不会释放锁。
③ wait()只能用在同步方法或代码块中,sleep()可以用在任何地方。
④ wait()不需要捕获异常,sleep()需要捕获异常。

6.为什么 wait()、notify()、notifyAll()方法定义在 Object 类里面,而不是 Thread 类?

① 锁可以是任何对象,如果在Thread类中,那只能是Thread类的对象才能调用上面的方法了。
② java中进入临界区(同步代码块或同步方法),线程只需要拿到锁就行,而并不关心锁被那个线程持有。
③ 上面方法是java两个线程之间的通信机制,如果不能通过类似synchronized这样的Java关键字来实现这种机制,那么Object类中就是定义它们最好的地方,以此来使任何Java对象都可以拥有实现线程通信机制的能力。

7.实现多线程的方式

①继承Thread类。
②实现Runnable接口
③实现Callable接口
④线程池

8.Runnable和Callable的区别

①Runnable没有返回值,Callable有返回值。
②Runnable只能抛出异常,不能捕获,Callable 能抛出异常,也能捕获。

9.线程池的好处

① 线程是稀缺资源,使用线程池可以减少线程的创建和销毁,每个线程都可重复使用。
② 可以根据系统的需求,调整线程池里面线程的个数,防止了因为消耗内存过多导致服务器崩溃。

10.线程池的七大参数

corePoolSize: 核心线程数,创建不能被回收,可以设置被回收。
maximumPoolSize: 最大线程数。
keepAliveTime: 空闲线程存活时间。
unit: 单位。
workQueue: 等待队列。
threadFactory: 线程工程,用于创建线程。
handler: 拒绝策略。

11.线程池的执行过程

①接到任务,判断核心线程池是否满了,没满执行任务,满了放入等待队列。
②等待队列没满,存入队列,等待执行,满了去查看最大线程数。
③最大线程数没满,执行任务,满了执行拒绝策略。

12.四大方法

①ExecutorService executor = Executors.newCachedThreadPool(): 创建一个缓存线程池,灵活回收线程,任务过多,会oom。
②ExecutorService executor = Executors.newFixedThreadPool(): 创建一个指定线程数量的线程池。提高了线程池的效率和线程的创建的开销,等待队列可能堆积大量请求,导致oom。
③ExecutorService executor = Executors.newSingleThreadPool(): 创建一个单线程,保证线程的有序,出现异常再次创建,速度没那么快。
④ExecutorService executor = Executors.newScheduleThreadPool(): 创建一个定长的线程池,支持定时及周期性任务执行。

13.四大拒绝策略

①new ThreadPoolExecutor.AbortPolicy(): 添加线程池被拒绝,会抛出异常(默认策略)。
②new ThreadPoolExecutor.CallerRunsPolicy(): 添加线程池被拒绝,不会放弃任务,也不会抛出异常,会让调用者线程去执行这个任务(就是不会使用线程池里的线程去执行任务,会让调用线程池的线程去执行)。
③new ThreadPoolExecutor.DiscardPolicy(): 添加线程池被拒绝,丢掉任务,不抛异常。
④new ThreadPoolExecutor.DiscardOldestPolicy(): 添加线程池被拒绝,会把线程池队列中等待最久的任务放弃,把拒绝任务放进去。

14.shutdown 和 shutdownNow 的区别?

① shutdown没有返回值,shutdownNow会返回没有执行完任务的集合。
②shutdown不会抛出异常,shutdownNow会抛出异常。
③shutdown会等待执行完线程池的任务在关闭,shutdownNow会给所以线程发送中断信号,然后中断任务,关闭线程池。

15.什么是死锁?

各进程互相等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象。

16.造成死锁的四个必要条件

互斥: 当资源被一个线程占用时,别的线程不能使用。
不可抢占: 进程阻塞时,对占用的资源不释放。
不剥夺: 进程获得资源未使用完,不能被强行剥夺。
循环等待: 若干进程之间形成头尾相连的循环等待资源关系。

17.线程安全主要是三方面

原子性: 一个或多个操作,要么全部执行,要么全部不执行(执行的过程中是不会被任何因素打断的)。
可见性: 一个线程对主内存的修改可以及时的被其他线程观察到。
有序性: 程序执行的顺序按照代码的先后顺序执行。

保证原子性
使用锁 synchronized和 lock。
使用CAS (compareAndSet:比较并交换),CAS是cpu的并发原语)。

保证可见性
使用锁 synchronized和 lock。
使用volatile关键字 。

保证有序性
使用 volatile 关键字
使用 synchronized 关键字。

18.volatile和synchronized的区别

① volatile仅能使用在变量级别的,synchronized可以使用在变量、方法、类级别的
② volatile不具备原子性,具备可见性,synchronized有原子性和可见性。
③ volatile不会造成线程阻塞,synchronized会造成线程阻塞。
④ volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好。

19.synchronized和lock的区别

① synchronized是关键字,lock是java类,默认是不公平锁(源码)。
② synchronized适合少量同步代码,lock适合大量同步代码。
③ synchronized会自动释放锁,lock必须放在finally中手工unlock释放锁,不然容易死锁。

20.JMM(java内存模型)

java内存模型,一个抽象的概念,不是真是存在,描述的是一种规则或规范,和多线程相关的规则。需要每个JVM都遵循。

21.JMM的约定

①线程解锁前,必须把共享变量立即刷回主存。
②线程加锁前,必须读取主存中的最新值到工作内存中。
③加锁和解锁必须是同一把锁。

22.JMM的八个命令

为了支持JMM,定义了8条原子操作,用于主存和工作内存的交互。

lock(锁定): 作用于主内存的变量,把一个变量标识为一条线程独占状态。
unlock(解锁): 作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。

read(读取): 作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用。
load(载入): 作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。

use(使用): 作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎。
assign(赋值): 作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量。

store(存储): 作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以遍随后的write的操作。
write(写入): 作用于主内存的变量,它把store操作从工作内存中的一个变量的值传送到主内存的变量中。

23.为什么要有JMM,用来解决什么问题?

解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。

四.jvm

JVM详解

垃圾回收机制详解

1.jvm是什么?

java虚拟机,是实现java跨平台的核心组件。

2.jvm的作用

java中所有的类,必须被装载到jvm中才能使用,装载由类加载器完成,.class这个类型可以在虚拟机运行,但不是直接和操作系统交互,需要jvm解释给操作系统,解释的时候需要java类库,这样就能和操作系统交互。

3.java文件的加载过程

.java -> .class -> 类加载器 -> jvm

4.jdk、jre、jvm的区别

jdk: 包含java运行环境和开发环境、jvm、java类库。
jre: 包含java运行环境和jvm、java类库。
jvm: java虚拟机,是跨平台的核心组件。

5.类加载器的作用

将.class文件装载到jvm中,实质就是把文件从硬盘写到内存。

6.类加载器的类型

引导类加载器(Bootstrap ClassLoader): c++编写,jvm自带的加载器,负责加载java核心类库,该加载器无法直接获取。
拓展类加载器(Extension ClassLoader): 加载jre/lib/etc目录下的jar包。
系统类加载器(Application ClassLoader): 加载当前项目目录下的类或jar包,最常用的加载器。
自定义加载器(Custom ClassLoader): 开发人员自定义的。需要继承ClassLoader

7.双亲委派机制的加载过程

①接到类加载的请求。
②向上委托给父类加载器,直到引导类加载器。
③引导类加载器检查能否加载当前这个类,如果能,使用当前加载器,请求结束,如果不能,抛出异常,通知子加载器进行加载。
④重复③。

8.双亲委派机制的优缺点

优点:保证类加载的安全性,不管那个类被加载,都会被委托给引导类加载器,只有类加载器不能加载,才会让子加载器加载,这样保证最后得到的对象都是同样的一个。
缺点:子加载器可以使用父加载器加载的类,而父加载器不能使用子加载器加载的类。

9.为什么要打破双亲委派机制

子加载器可以使用父加载器加载的类,而父加载器不能使用子加载器加载的类。
例如:使用JDBC连接数据库,需要用到 com.mysql.jdbc.Driver和DriverManager类。然而DriverManager被引导类加载器所加载,而com.mysql.jdbc.Driver被当前调用者的加载器加载,使用引导类加载器加载不到,所以要打破双亲委派机制。

10.打破双亲委派机制的方式

① 自定义类加载器,重写loadclass方法。
② 使用线程上下文类(ServiceLoader:使父加载器可以加载子加载器的类)。

11.jvm的每个部分储存的都是什么

方法区(线程共享): 常量池、静态(static)变量以及方法信息(方法名、返回值、参数、修饰符等)等。
堆(线程共享): 是虚拟机内存中最大的一块,储存的是实例对象和数组。
本地方法栈(线程不共享): 调用的本地方法,被native修饰的方法,java不能直接操作操作系统,所以需要native修饰的方法帮助。
虚拟机栈(线程不共享): 8大基本类型、对象引用、实例方法。
程序计数器(线程不共享): 每个线程启动是都会创建一个程序计数器,保存的是正在执行的jvm指令,程序计数器总是指向下一条将被执行指令的地址。

12.内存溢出(oom)和栈溢出

内存溢出的原因: (1)内存使用过多或者无法垃圾回收的内存过多,使运行需要的内存大于提供的内存。
         (2)长期持有某些资源并且不释放,从而使资源不能及时释放,也称为内存泄漏。
解决: (1)进行jvm调优。-Xmx:jvm最大内存。-Xms:启动初始内存。-Xmn:新生代大小。 -Xss:每个虚拟机栈的大小。
   (2)使用专业工具测试。
手动制造: 一直new对象就ok。

栈溢出原有: 线程请求的栈容量大于分配的栈容量。
解决: (1)修改代码 (2)调优 -Xss
手动制造: 一直调用实例方法。

13.垃圾回收的作用区域

作用在方法区和堆,主要实在堆中的伊甸园区。年轻代分为(伊甸园区和幸存区)

14.怎么判断对象是否可回收

可达性分析算法: 简单来说就是一个根对象通过引用链向下走,能走到的对象都是不可回收的。可作为根对象有: 虚拟机栈的引用的对象,本地栈的引用的对象,方法区引用的静态和常量对象。

引用计数算法: 每个对象都添加一个计数器,

2021Java最新学习路线海量算法高频面试题精编解析

Java基础

1Java语言的三大特性

2.Java语言主要特性

3. JDK和JRE有什么区别

4.Java基本数据类型及其封装类

5.如果main方法被声明为private会怎样?

6.说明- -下public static void main(String argsQ])这段声明里每个关键字的作用

7.==与equals的区别

8.Object有哪些公用方法

9.为什么Java里没有全局变量?

10.while循环和do循环有什么不同?

11.char型变量中能不能存储一个中文汉字?为什么?

12.public, private, protected的区别, 继承方法与访问权限

13.float f=3.4;是否正确?

14.shorts1 = 1;s1 = s1 + 1;有错吗? shorts1 = 1;s1 += 1;有错吗

15.8u和&:&的区别?

16.IntegerCache

17.Locale类是什么?

18Java中final. finally. finalize的区别与用法

19.hashCode0和equals0的区别

20.深拷贝和浅拷贝的区别是什么?

21Java中操作字符串都有哪些类?它们之间有什么区别?

22.String str= "a"与String str=new String(“a”)-样吗?

23.抽象类能使用final 修饰吗?

24.static关键字5连问

25.重载(Overload) 和重写(Override) 的区别。重载的方法能否根据返回类型进行区分?

26.Java的四种引用

27.Java中Comparator与Comparable有什么不同?

28. Java序列化,反序列化?

29.什么情况需要Java序列化?

30.序列化的实现?

31.如果某些数据不想序列化,如何处理?

腾讯T4架构师:刷3遍以下面试题,你也能从小公司成功跳到大厂

IO&NIO

1.什么是I0流?

2java中有几种类型的流?

3.字节流和字符流哪个好?怎么选择?

4.读取数据量大的文件时,速度会很慢,如何选择流?

5.1O模型有几种?

6.阻塞1O (blocking 10)

7.非阻塞I/O (nonblocking 10)

8.I/O多路复用模型(I0 multiplexing)

9.信号驱动I/O模型

10.异步/O(asynchronous 10)

11.NIO与10的区别?

12.NIO和IO适用场景

13.NIO核心组件

14.什么是channel

15.Java NIO中最常用的通道实现?

16.Buffer是什么?

腾讯T4架构师:刷3遍以下面试题,你也能从小公司成功跳到大厂

多线程面试题

1.什么是进程?

2.什么是线程?

3.线程的实现方式?

4.Thread类中的start0和run0方法有什么区别?

5.线程NEW状态

6.线程RUNNABLE状态

7.线程的RUNNING状态

8.线程的BLOCKED状态

9.线程的TERMINATED状态

10.线程状态转化图

11.i——与System.out.printIn0的异常

12.如何知道代码段被哪个线程调用?

13.线程活动状态?

14.sleep0方法

15.如何优雅的设置睡民时间?

16.停止线程

17.interrupted和isInterrupted

18.yield

19.线程的优先级

20.优先级继承特性

21.谁跑的更快?

22.线程种类

23.守护线程的特点

24.Java中典型的守护线程

25.如何设置守护线程

25Java虚拟机退出时Daemon线程中的finally块一定会执行?

26.设置线程上下文类加载器

27.join

28.什么是synchronized?

29.synchronized包括哪两个jvm重要的指令?

30.synchronized关键字用法?

31.synchronized锁的是什么?

32.Java对象头

还有很多,这里就不一一例举了

腾讯T4架构师:刷3遍以下面试题,你也能从小公司成功跳到大厂

JVM

1JDK. JRE、 JVM关系?

2.启动程序如何查看加载了哪些类,以及加载顺序? ’

3. class字节码文件10个主要组成部分?

4.画一下jvm内存结构图?

5.程序计数器

6Java虚拟机栈

7.本地方法栈

8Java堆

9.方法区

10.运行时常量池?

11.什么时候抛出StackOverflowError?

12.Java7和Java8在内存模型上有什么区别?

13.程序员最关注的两个内存区域?

14.直接内存是什么?

15.除了哪个区域外,虚拟机内存其他运行时区域都会发生OutOfMeoryError?

16.什么情况下会出现堆内存溢出?

17如何实现一个堆内存溢出?

18.空间什么情况下会抛出OutOfMemoryError?

19.如何实现StrackOverflowError?

20.如何设置直接内存容量?

21.Java堆内存组成?

22. Edem : from : to默认比例是?

23.垃圾标记阶段?

24.引用计数法?

25.根搜索算法?

26.JVM中三种常见的垃圾收集算法?

27.标记-清除算法?

28.复制算法?

29.标记-整理算法?

30.分代收集算法?

31.垃圾收集器?

32.Stop The World?

最后

本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以免费送给我的读者朋友们

目录:

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

Java面试核心知识点

一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!有需要的朋友戳这里即可免费获取

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

Java面试核心知识点

已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了,各位读者朋友们快来免费获取吧

全靠这套面试题,才让我有惊无险美团二面拿offer  (面经解析)

一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!有需要的朋友戳这里即可免费获取

[外链图片转存中…(img-0ryc8YIv-1625755707969)]

Java面试核心知识点

已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了,各位读者朋友们快来免费获取吧

[外链图片转存中…(img-cxYV5AkQ-1625755707971)]

以上是关于java高频面试题(2023最新)的主要内容,如果未能解决你的问题,请参考以下文章

前端CSS面试题2023前端最新版css模块,高频15问

2023最新---java面试题大全

前端vue2面试题2023前端最新版vue模块,高频17问(上)

前端vue2面试题2023前端最新版vue模块,高频17问(上)

前端vue2面试题2023前端最新版vue模块,高频17问(上)

2023最新Android大厂高频面试题+解析大全,全文干货