面经整理3

159 阅读10分钟

1.IO

输入:数据输入到计算机内存 输出:输出到外部存储(数据库、文件、远程主机) IO流在Java中分为输入流和输出流;根据数据的处理方式,分为字节流和字符流。 InputStream/Reader:所有输入流的基类,前者是字节输入流,后者是字符输入流 OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流 GPT整理:

1) 字节流(Byte Stream)
  • 定义:字节流用于处理原始二进制数据,如图片、音频文件等。
  • 特点:以字节为单位读写数据。
  • 常用类InputStream 和 OutputStream 及其子类,例如 FileInputStream 和 FileOutputStream
2) 字符流(Character Stream)
  • 定义:字符流用于处理文本数据,以字符为单位读写数据。
  • 特点:自动处理字符编码和解码,适用于处理文本文件。
  • 常用类Reader 和 Writer 及其子类,例如 FileReader 和 FileWriter
3) 字节缓冲流(Byte Buffer Stream)
  • 定义:字节缓冲流在字节流的基础上提供缓冲功能,以提高读写效率。
  • 特点:使用缓冲区减少对磁盘的访问频率。
  • 常用类BufferedInputStream 和 BufferedOutputStream
4) 字符缓冲流(Character Buffer Stream)
  • 定义:字符缓冲流在字符流的基础上提供缓冲功能,以提高读写效率。
  • 特点:缓冲区的使用简化了对字符数据的操作。
  • 常用类BufferedReader 和 BufferedWriter

2.什么是死锁?如何避免死锁?介绍下银行家算法?死锁出现的时候如何进行检测?

死锁描述的是:多个进程/线程同时被阻塞,它们中的一个或全部都在等待某个资源被释放。由于进程/线程被无限期的阻塞,因此程序不可能正常终止。 一、预防死锁(悲观),即破坏产生死锁的4个必要条件: 1)互斥,破坏此条件不太现实 2)占有并等待,破坏此条件,采用静态分配策略(一个进程必须在执行前就申请到它所需全部资源),严重降低资源利用率。 3)非抢占,破坏此条件,可以采用剥夺式调度算法,导致资源利用率下降 4)循环等待,破坏此条件,采用层次分配策略 二、避免死锁(悲观),银行家算法: 当一个进程申请使用资源的时候,银行家算法通过先试探分配给该进程资源,然后通过安全性算法判断分配后系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待,若能够进入到安全的状态,则就真的分配资源给该进程,改善了资源使用率低的问题,但是不断的检测,以及安全性检查需要花费较多的时间。 ps:如果操作系统能够保证所有的进程在有限的时间内得到需要的全部资源,则称系统处于安全状态,否则说系统是不安全的。 三、检测死锁(乐观),进程-资源分配图: 1)如果进程-资源分配图无环路,则没有死锁 2)如果进程-资源分配图有环路,且每个资源类仅有一个资源,则已经发生了死锁 3)如果进程-资源分配图有环路,如果存在一个既不阻塞又非独立的进程,该进程能够在有限的时间内归还占有的资源,则不会发生死锁。 定时运行“死锁检测”的程序如果检测到,在采取措施解除 四、解除死锁(乐观)

image.png

3.Spring

Spring框架一般指的是Spring Framework,提供的核心功能主要是IoC和AOP Spring,Spring MVC,Spring Boot之间有什么关系? Spring包含了多个功能模块,最重要的是Spring-Core(主要提供Ioc依赖注入功能的支持)模块,Spring中的其他模块(如Spring MVC)功能实现基本都需要依赖于该模块。 Spring MVC主要赋予Spring快速构建MVC架构的Web程序的能力。MVC是模型(Model)、视图(View)和控制器(Controller)的简写,核心思想是通过将业务逻辑、数据、显示分离来组织代码。 Spring Boot旨在简化Spring开发,简化了配置,用xml或Java进行显显式配置。

4.谈谈自己对于Spring IoC的理解

Spring IOC(控制反转)是一种设计思想,而不是一个具体的技术实现。IoC的思想就是将原本在程序中手动创建对象的控制权,交给Spring框架来管理。 控制:对象创建的权利 反转:控制权交给外部环境(Spring框架、Ioc容器)

image.png

在 Spring 中, IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。

5.什么是Spring Bean?

Bean代指的就是那些被IoC容器管理的对象,我们通过XML文件注解或者Java配置类来告诉IoC容器帮助我们管理哪些对象。 将一个类声明为Bean的注解有哪些? @Component;@Respository;@Service;@Controller

6.@Component注解和@Bean注解有什么区别?

1)@Component注解作用于类,@Bean注解作用于方法 2)引用第三方库中的类需要装配到Spring容器中,只能通过@Bean注解实现

7.Bean的生命周期了解么?

1)创建Bean的实例 2)Bean属性赋值/填充(@Autowired等注解注入的对象) 3)Bean初始化 4)销毁Bean

8.MySQL存储引擎、事务类型、隔离级别、可重复读怎么解决幻读、MVCC和间隙锁在哪里使用

1)MySQL存储引擎:InnoDB 2)默认使用的隔离级别:可重复读,隔离级别是可以解决幻读问题发生的(基于MVCC和Next-Key-Lock) 解决幻读的方法:解决幻读的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或删除这张表的数据了,解决幻读的方式主要有以下: ①将事务隔离级别调整为SERIALIZABLE ②在可重复读的事务级别下,给事务操作的这张表加表锁 ③在可重复读的隔离级别下,给事务操作的这张表添加Next-Key-Lock(Record Lock+Gap Lock) 3)MySQL 的可重复读隔离级别通过使用间隙锁(Gap Lock)来防止幻读。 4)MVCC(通过版本控制机制)在可重复读和串行化隔离级别下使用,用于提高并发性,减少锁竞争,允许读取操作在不同失误之间不互相阻塞。 间隙锁(通过控制并发写入的冲突)在可重复读和串行化隔离级别下使用,防止在索引范围内插入新记录,从而避免幻读,通过锁定记录之间的空隙。

9.实际情况

脏读(读未提交):事务A读取了事务B尚未提交的数据,若B回滚了,A读取的数据是无效的。 读已提交(不可重复读):事务A读取数据1;事务B提交对数据1的修改,A再次读取1,可能会得到不同的结果。 可重复读:事务A在开始时读取数据1的值,直到事务结束,数据1的值始终不变,即使其他事务修改了数据1. 幻读:事务A查询满足条件的所有记录,事务B插入了一些新记录使得满足该条件的记录数量增加,事务A再次查询时,结果集的记录数不同于第一次查询时的记录数。

10.什么是AOP?

AOP是面向切面编程。 AOP的目的是将横切关注点(日志管理、事务管理、权限控制、接口限流和接口幂等)从核心业务逻辑中分离出来,通过动态代理、字节码操作等技术,实现代码的复用和解耦。 之所以叫面向切面编程,因为它的核心思想就是将横切关注点(多个类或对象中的公共行为,如日志记录、事务管理、权限控制、接口限流和接口幂等)从核心业务逻辑中分离出来,形成一个个切面。 AOP的常见实现方式:动态代理字节码操作

术语: 横切关注点:多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等) 切面:对横切关注点进行封装的 连接点:方法调用或者方法执行时的某个特定时刻 通知:切面在某个连接点要执行的操作,分为前置通知、后置通知、返回通知、异常通知和环绕通知,只有环绕通知可以控制目标方法的执行过程,其余都是在目标方法的前后执行。 织入:将切面和目标对象连接起来的操作

11.Exception 和 Error 有什么区别?

都属于Throwable的子类 Exception是程序本身可以处理的异常,可以通过catch进行捕获,分为受检查异常和不受检查异常 Error属于程序无法处理的错误,不建议通过catch进行捕获,遇到这些异常时,JVM一般会选择线程终止。

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于受检查异常

image.png

12.try-catch-finally 如何使用?

try块:用于捕获异常,后面可以接多个catch块,如果没有catch块,必须接finally块。 catch块:用于处理try捕获到的异常 finally块:无论是否捕获或处理异常,里面的语句都会被执行。当在try块或者catch块遇到return语句时,finally语句块将在方法返回之前被执行。 注意:不要在finally语句块中使用return!

13.finally中的代码一定会执行吗?

不一定,有以下几种情况 1)finally之前虚拟机被终止运行的话,finally中的代码就不会被执行。 2)程序所在的线程死亡 3)关闭CPU

14.什么是泛型?有什么作用?泛型的使用方式有哪几种?项目中哪里用到了泛型?

1)Java泛型是一种语言特性,允许在定义类、接口和方法时使用类型参数 2)①类型安全②代码复用③消除强制类型转换④提高可读性和维护性 3)泛型一般有3种使用方式:泛型类、泛型接口、泛型方法 例如:使用泛型的集合类 List 可以在编译时检查集合中元素的类型,确保只存储指定类型的对象,减少了运行时错误的可能性。 4)自定义接口的通用返回结果Result通过参数T可根据具体的返回类型动态指定结果的数据类型;构建集合工具类(参考Collections中的sort,binarySearch方法)。

15.何为反射?

Java反射是一种功能,使得程序能在运行时查看和操作类的结构和对象,它允许你动态的获取类的信息(比如类名、方法、字段)和创建对象,即使在编写代码时你不知道具体的类和方法名。 例如,你可以在运行时调用一个类的构造方法或函数,甚至修改字段的值,这对于一些需要动态处理的情况非常有用。

image.png