Bootstrap

2024Java面试八股文(1000道)

1.java 容器都有哪些?

数组、Util下的容器:Collection(Set、List)、Map

2.Collection 和 Collections 有什么区别?

Collection是集合的接口,其实现类有List和Set;

Collections是工具类,包含许多有关集合操作的静态多态方法,可以直接使用。

3.List、Set、Map 之间的区别是什么?

List:有序集合、元素可重复

Set:元素不可重复,HashSet无序,LinkedHashSet按照插入排序,SortedSet可排序

Map:键值对集合,存储键、值之间的映射。key无序,唯一,value可重复

4.HashMap 和 Hashtable 有什么区别?

HashMap不是线程安全的,HashTable是线程安全的

HashMap允许Null Key和Null Value,HashTable不允许

5.如何决定使用 HashMap 还是 TreeMap?

如果需要得到一个有序的结果应该使用TreeMap

如果不需要排序最好选用HashMap,性能更优

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

6.说一下 HashMap 的实现原理?

HashMap基于Hash算法实现,通过put(key,value)存储,get(key)来获取value

当传入key时,HashMap会根据key,调用Hash(Object key)方法,计算出Hash值,根据Hash值将Value保存在Node对象里,Node对象保存在数组里。

当计算出的Hash值相同时,称为Hash冲突,HashMap的做法是用链表和红黑树存储相同Hash值的value

当Hash冲突的个数:小于等于8使用链表,大于8使用红黑树解决链表查询慢的问题。

7.说一下 HashSet 的实现原理?

HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的操作相对比较简单,相关HashSet的操作,基本上都是直接调用底层的HashMap的相关方法来完成,HashSet不允许有重复的值,并且元素是无序的

8.ArrayList 和 LinkedList 的区别是什么?

ArrayList的数据结构是动态数组;LinkedList的数据结构是双向链表。

ArrayList比LinkedList在随机访问的时候效率要高,因为LinkedList是线性的数据结构,需要依次往后查找

在非首尾的增删操作,LinkedList要比ArrayList的效率要高,因为ArrayList在操作增删时要影响其他元素的下标

总结:需要频繁读取集合中的元素时,推荐使用ArrayList;插入和删除操作较多时,推荐使用LinkedList

9.如何实现数组和 List 之间的转换?

List转数组:String[] list = List.toArray(array);//array为List

数组转List:List list = java.util.Arrays.asList(array);//array为数组

10.ArrayList 和 Vector 的区别是什么?

相同点:都实现了List接口,都是有序集合

区别:Vector是线程安全的,ArrayList不是线程安全的;

当Vector或ArrayList中的元素超过它的初始大小时,Vector会将容量翻倍,而ArrayList只会将容量扩大50%

11.Array 和 ArrayList 有何区别?

Array类型的变量在声明时必须实例化;ArrayList可以只是先声明;

Array大小是固定的,而ArrayList的大小是动态变化的;

Array可以包含基本类型和对象类型,ArrayList只能包含对象类型

12.在 Queue 中 poll()和 remove()有什么区别?

Queue中poll()和remove()都是用来从队列头部删除一个元素;

在队列元素为空的情况下,remove()方法会抛出NoSuchElementException异常,而poll()只会返回null

13.哪些集合类是线程安全的?
  • Vector:相比ArrayList多了线程安全;
  • HashTable:相比HashMap多了线程安全;
  • ConcurrentHashMap:高效且线程安全;
  • Stack:继承于Vector,也是线程安全
14.迭代器 Iterator 是什么?

迭代器是一种设计模式,它是一个对象,可以遍历并选择序列中的对象。

15.Iterator 怎么使用?有什么特点?

next();

hashNext();

remove();

Iterator接口被Collection接口继承,Collection接口的iterator()方法返回一个iterator对象。

16.Iterator 和 ListIterator 有什么区别?

ListIterator有add()方法,可以向List中添加对象,而Iterator不能;

ListIterator有hasPrevious()和previous()方法,可以向前遍历,Iterator不能;

ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现;

ListIterator可以实现对对象的修改,使用set()实现;而Iterator只能遍历,不能修改

17.怎么确保一个集合不能被修改?

可以使用Collections.unmodifiableCollection(Collection c) 方法创建一个只读集合

这样改变集合的任何操作都会抛出Java. lang. UnsupportedOperationException异常。

三、多线程
1.并行和并发有什么区别?

并行是指两个或多个事件在同一时刻发生,是在不同实体上的多个事件;

并发是指两个或多个事件在同一时间间隔发生,是在同一个实体上的多个事件

2.线程和进程的区别?

进程是资源分配最小单位,线程是程序执行最小单位

每个进程都有相应的线程

进程有独立的地址空间,线程没有

线程是指处理机调度的基本单位

进程执行开销大,线程执行开销小

3.守护线程是什么?

在java线程开发中,有两种线程:User Thread(用户线程);Daemon Thread(守护线程)

普通用户进程在JVM退出时依然会继续执行,导致JVM并不能退出

普通进程可以使用setDaemon(true)方法升级为守护进程,守护进程在JVM退出时会自动结束运行。

守护线程拥有自动结束自己生命周期的特性,而非守护线程不具备这个特点

4.创建线程有哪几种方式?

继承Thread类并实现run方法,调用继承类的start方法开启线程;

通过实现Runnable接口,重写run方法,调用线程对象的start方法开启线程;

除此之外,还可以通过实现Callable接口,实现call方法,并用FutureTask类包装Callable对象开启线程。

5.说一下 runnable 和 callable 有什么区别?

实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程并不能返回执行结果

Callable接口的call方法允许抛出异常,而Runnable接口的run方法的异常只能在内部消化,不能继续上抛

6.线程有哪些状态?

新建、就绪、运行、阻塞、死亡

7.sleep() 和 wait() 有什么区别?

sleep后程序不会释放同步锁,wait后程序会释放同步锁

sleep可以指定睡眠时间,自动唤醒,wait可以直接用notify唤醒

sleep的类是Thread,wait的类是Object

 篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

8.notify()和 notifyAll()有什么区别?

notify()方法会唤醒对象等待池中的一个线程,进入锁池;

notifyAll()方法会唤醒等待池中的所有线程,进入锁池

9.线程的 run()和 start()有什么区别?

调用start()方法是用来启动线程的,轮到该线程执行时,会自动调用run方法;

直接运行run方法无法达到启动多线程的目的,相当于调用Thread对象中的run方法

一个线程的start方法只能调用一次,多次调用会抛出异常;而run方法可以多次调用

10.创建线程池有哪几种方式?

主要使用Excutors提供的通用线程池创建方法,去创建不同配置的线程池

newCachedThreadPool();特点:用来处理大量短时间工作任务的线程池

newFixedThreadPool(int nThreads);特点:重用指定数目(nThreads)的线程

newSingleThreadExecutor();特点:工作线程数目限制为1

newSingleThreadScheduledExecutor()和newScheduledThreadPool(int corePoolSize)可以进行周期或定时性的工作调度

newWorkStealingPool(int parallelism);特点:JDK8以后才加入

11.线程池都有哪些状态?

RUNNING:线程池被创建,可以接收新线程

SHUTDOWN:线程池被关闭,不接收新线程,但是可以处理已有的线程。通过调用shutdown()方法;

STOP:线程池停止,不接受新线程,中断当前的线程,并且不会处理已有的线程。通过调用shutdownnow()方法;

TIDYING:线程池等待,当线程池处于SHUTDOWN或者STOP状态,并且任务队列为空且执行中任务为空则会转变;

TERMINATED:线程池彻底终止,线程池在TIDYING状态中执行完terminated()方法后就会转变为此状态。

12.线程池中 submit()和 execute()方法有什么区别?

execute() 参数 Runnable ;submit() 参数 (Runnable) 或 (Runnable 和 结果 T) 或 (Callable)

execute() 没有返回值;而 submit() 有返回值

submit()的返回值Future调用get方法时,可以捕获处理异常

13.在 java 程序中怎么保证多线程的运行安全?

JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题

synchronized、volatile、LOCK,可以解决可见性问题

Happens-Before 规则可以解决有序性问题

14.多线程锁的升级原理是什么?

锁的级别:无锁 => 偏向锁 => 轻量级锁 => 重量级锁

无锁:没有对资源进行锁定,所有线程都可以访问,但是只有一个能修改成功,其他的线程会不断尝试,直至修改成功。

偏向锁:对象的代码一直被同一线程执行,不存在多个线程竞争,偏向锁,指的就是偏向第一个加锁线程,该线程不会主动释放偏向锁,只有当其他线程尝试竞争偏向锁时才会被释放。

偏向锁的撤销,需要在某个时间点上没有字节码正在执行时,先暂停拥有偏向锁的线程,然后判断锁对象是否处于被锁定状态。如果线程不处于活动状态,则将对象头设置成无锁状态,并撤销偏向锁;

如果线程处于活动状态,升级为轻量级锁的状态。

轻量级锁:轻量级锁是指当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。当前只有一个等待线程,则该线程将通过自旋进行等待。但是当自旋超过一定的次数时,轻量级锁便会升级为重量级锁;当一个线程已持有锁,另一个线程在自旋,而此时又有第三个线程来访时,轻量级锁也会升级为重量级锁。

重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。

15.什么是死锁?

死锁是指两个或两个以上的进程在竞争资源的过程中造成的不可解堵塞。两个线程都在互相等待。

16.怎么防止死锁?

预防:资源一次性分配;可剥夺资源;资源有序分配;超时放弃

避免:银行家算法;

检测:为每个进程和每个资源建立唯一的ID,建立资源分配表和进程等待表

解除:剥夺资源;撤销进程

17.ThreadLocal 是什么?有哪些使用场景?

ThreadLocal是线程本地存储,在每个线程中都创建了一个ThreadLocalMap对象,每个线程可以访问自己内部ThreadLocal对象内的value。

经典的使用场景是为每个线程分配一个JDBC连接的Connection,这样就可以保证每个线程都在各自的Connection上进行数据库的操作,不会出现A线程关了B线程的Connection,还有Session管理等问题。

18.说一下 synchronized 底层实现原理?

同步代码块是通过monitorenter和monitorexit指令获取线程的执行权;

同步方法是通过加ACC_SYNCHRONIZED 标识实现线程的执行权的控制

19.synchronized 和 volatile 的区别是什么?
  • volatile本质是在告诉vm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
    synchronize则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞。
  • volatile仅能实现变量的修改可见性,不能保证原子性;synchronize可以保证变量的修改可见性和原子性。
  • volatile不会造成线程的阻塞;synchronize可能会造成线程的阻塞。
  • volatile标记的变量不会被编译器优化,synchronize标记的变量可以被编译器优化
20.synchronized 和 Lock 有什么区别?

synchronized是关键字,属于jvm层面;Lock是具体类,是api层面的锁;

synchronized无法获取锁的状态,Lock可以判断;

synchronized用于少量同步,Lock用于大量同步。

21.synchronized 和 ReentrantLock 区别是什么?

synchronized代码执行结束后线程自动释放对锁的占用;Reentrantlock需要手动释放锁;

synchronized不可中断,除非抛出异常或者执行完成;Reentrantlock可中断;

synchronize非公平锁;Reentrantlock默认非公平锁,也可公平锁;

ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒,而不是像synchronized要么随机唤醒一个,要么唤醒全部线程。

22.说一下 atomic 的原理?

作用:多线程下将属性设置为atomic可以保证读取数据的一致性。

CAS(Compare And Swap),乐观锁的机制,先比较再交换,以实现原子性

 篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

23.理解乐观锁和悲观锁

乐观锁:认为每次去拿数据的时候别人不会修改,所以不会上锁,但是每次要拿数据的时候都会先判断数据是否被别人修改

悲观锁:认为每次去拿数据的时候别人都会修改,所以每次都会上锁。

使用场景:乐观锁使用于多读少写的应用类型,这样可以提高吞吐量;相反的情况则使用悲观锁

四、反射
1.什么是反射?

java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能成为java的反射机制。

2.什么是 java 序列化?什么情况下需要序列化?

序列化:将java对象转换成字节流的过程。

反序列化:将字节流转换成java对象的过程。

当java对象需要在网络上传输或者持久化存储到文件中时,就需要对Java对象进行序列化处理。

序列化的实现:类实现Serializable接口。

3.动态代理是什么?有哪些应用?

在运行时,创建一个新的类,即创建动态代理,可以调用和扩展目标类的方法。动态代理的类是自动生成的。

应用:Spring的AOP,加事务,加权限,加日志

4.怎么实现动态代理?

基于jdk,需要实现InvocationHandler接口,重写invoke方法。

基于cglib,需要jar包依赖;

基于javassist

五、对象克隆
61.为什么要使用克隆?

如果直接使用=给对象赋值的话,那么两个对象其实指向的是同一个地址,其中一个值改变时,另一个也会随之改变。

62.如何实现对象克隆?

1、实现Coloneable接口并重写Object类中的clone()方法;

2、实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

63.深克隆和浅克隆区别是什么?

深克隆:新旧对象不共享一个地址;

浅克隆:新旧对象共享一个地址,改变一个,另一个也会改变

六、Java Web
1.jsp 和 servlet 有什么区别?

Jsp:Java Server Page,是一种动态页面技术,其根本是一个简化的Servlet设计,用来封装产生动态网页的逻辑处理。

Servlet:服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。它担当客户请求与服务器响应的中间层。

相同点:jsp经编译后就变成了Servlet,jsp本质就是servlet,jvm只能识别java的类,不能识别jsp代码,web容器将jsp的代码编译成jvm能够识别的java类。

2.jsp 有哪些内置对象?作用分别是什么?
  • request:用户端请求(get/post)
  • response:网页传回用户端的响应
  • pageContext:管理网页的属性
  • session:与请求有关的会话期
  • application servlet:正在执行的内容
  • out:用来传送回应的输出
  • config: servlet的架构部件
  • page JSP:网页本身
  • exception:针对错误网页,未捕捉的例外
3.说一下 jsp 的 4 种作用域?
  1. application:在所有应用程序中有效
  2. session:在当前会话中有效;
  3. request:在当前请求中有效;
  4. page:在当前页面有效
4.session 和 cookie 有什么区别?
  • 存储位置不同
    cookie的数据信息存放在客户端浏览器上
    session的数据信息存放在服务器上
  • 存储容量不同
    单个cookie保存的数据<=4Kb,一个站点最多保存20个cookie
    对于session来说没有上限
  • 存储方式不同
    cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据;
    session中能够存储任何类型的数据
  • 隐私策略不同
    cookie对客户端是可见的,所以它是不安全的;
    session存储在服务器上,对客户端是透明的,不会信息泄露
  • 有效期不同
    可以通过设置cookie的属性,使cookie长期有效;
    session不能达到长期有效的结果
  • 服务器压力不同
    cookie保存在客户端,不占用服务器资源
    session是保存在服务器的,如果并发访问的用户十分多,会产生很多的session,耗费大量的内存
  • 浏览器支持不同
    cookie是需要浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效
    session只能在本窗口以及子窗口有效,而cookie可以为本浏览器上的一切窗口有效
  • 跨域支持不同
    cookie支持跨域名访问
    session不支持跨域名访问
5.说一下 session 的工作原理?

客户端登录完成之后,服务器会创建相应的session,session创建完成之后,会把session的id发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着sessionid,服务器拿到sessionid之后,在内存找到与之对应的session就可以正常工作了。

6.如果客户端禁止 cookie,session 还能用吗?

如果浏览器禁用了cookie,那么客户端访问服务端时无法携带sessionid,服务端无法识别用户身份,便无法进行会话控制,session就会失效,但是可以通过其他办法实现:

  1. 通过URL重写,把sessionid作为参数追加的原URL中,后续的浏览器与服务器交互中携带session
  2. 服务器的返回数据中包含sessionid,浏览器发送请求时,携带sessionid参数
7.spring mvc 和 struts 的区别是什么?
  • 拦截机制不同
    Struts2是类级别的拦截,每次请求就会创建一个Action
    SpringMVC是方法级别的拦截,一个方法对应一个Request上下文。
  • 底层框架不同
    Struts2采用Filter实现,SpringMVC采用Servlet实现
  • 性能不同
    Struts2需要加载所有的属性值注入,SpringMVC实现了零配置,由于SpringMVC基于方法的拦截。
    所以,SpringMVC开发效率和性能高于Struts2
  • 配置方面
    SpringMVC 和 Spring 是无缝的,从这个项目的管理和安全上也比Struts2高。
8.如何避免 sql 注入?

SQL注入是Web开发中最常见的一种安全漏洞,可以用它来从数据库获取敏感信息,进行数据库的一系列非法操作。

  • 校验参数的数据格式是否合法
  • 对进入数据库的特殊字符进行转义处理,或编码转换
  • 预编译SQL,参数化查询方式,避免SQL拼接
  • 发布前利用工具进行SQL注入检测
9.什么是 XSS 攻击,如何避免?

XSS(Cross Site Scripting)跨站脚本攻击,它是Web程序中常见的漏洞。

原理:攻击者往web页面里插入恶意的HTML代码,当用户浏览该页面时,嵌入其这个你的HTML代码会被执行,从而达到恶意攻击用户的目的。

避免措施:

  • web页面中可由用户输入的地方,对输入的数据转义、过滤处理
  • 前端对HTML标签属性、css属性赋值的地方进行校验
  • 后台输出页面的时候,也需要对输出内容进行转义、过滤处理

 篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

;