2022年JAVA面试总结(会持续补充)

本篇博客为博主个人面试总结,欢迎补充指正。
文章大多总结为主,不提供详细内容。

文章目录

  • 数据库篇
    • 一.事务
        • 事务的四大特性(ACID)
        • 数据库事务并发问题
        • 事务的隔离级别
        • Spring中事务的传播行为
    • 二:数据库优化及数据库索引
      • 1.数据库连接池的作用:
      • 2.索引
    • 三:SQL JOINS
  • 框架篇
    • 一:Spring
      • 1. Spring的五个作用域
      • 2. Spring中默认的scope,是否有线程安全问题?
      • 3. Spring中的缓存机制,以及循环依赖
      • 4. IOC
      • 5. AOP
    • 二:SpringMVC
      • Spring MVC的执行流程
    • 三:MyBatis
    • 四:SpringBoot
        • 1.常用注解:
        • 2.springBoot自动配置:
        • 3.SpringBoot启动原理:
  • WEB篇
    • 一:网页状态码
    • 二:Servlet生命周期
    • 三:GET和POST的区别

数据库篇

一.事务

事务的四大特性(ACID)

在数据库系统中,一个事务指数据库的一系列操作组成的完整逻辑,要么全部完成,要么全部不完成

  1. 原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会停在中间某个阶段,发生错误时会进行回滚。

  2. 一致性:事务在发生的前后数据库的完整性不会被破坏;这就表示写入的数据必须必须符合所有预设约束、触发器、级联回滚等。

  3. 隔离性:防止事务在高并发的时候导致不同的事务因为交叉执行而导致数据不一致;事务包括四个隔离级别

  • 读未提交
  • 读已提交
  • 可重复读
  • 串行化
  1. 持久性:事务结束后对数据的修改是永久的,即就算系统故障,数据也不会丢失。

数据库事务并发问题

1.** 脏读**:前者修改,后者读若前者回滚,后者读取数据无效

  1. 不可重复读:前者读,后者改,前者在读,造成两次数据不同。(重点在update和delete

  2. 幻读:前者读,后者插入,前者再读时多出数据(例如新增行操作,重点在于insert

事务的隔离级别

  1. 读未提交:都不能解决(允许事务1读取事务2未提交的修改

  2. 读已提交:能解决脏读(Oracle默认隔离级别)(要求事务1只能读取事务2已提交的修改

  3. 可重复读:能解决脏读、不可重复读(MySQL默认隔离级别)(事务1执行期间禁止其他事务对数据进行更新

  4. 串行化:能解决脏读、不可重复读、幻读(事务1执行期间禁止其他事务对数据进行添加、更新、删除操作

Spring中事务的传播行为

例如:一个方法运行在一个开启了事务的方法中,那么这个方法是使用原来的事务还是再开启一个事务就需要传播行为来确定。

Spring中事务的传播行为有七种:

1.REQUIRED(required):需要,如果存在一个事务,就使用当前的事务,如果没有就开启一个新的事务。(一般用于Service中的方法里有更新的操作)

2.SUPPORTS(supports):支持,如果存在一个事务,就是用当前事务,如果没有事务,则非事务的执行(一般用于Service中的方法里都是查询的操作)

3.REQUIRES_NEW:总是开启一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起。

4.MANDATORY(mandatory)

5.NEVER

6.NOT_SUPPORTED

7.NESTED

二:数据库优化及数据库索引

1.数据库连接池的作用:

  • 限定数据库的个数,防止由于连接过多的数据库而导致系统缓慢或崩溃。
  • 数据库连接不必每次都去创建或销毁,节约了资源和时间

2.索引

  1. 什么是索引?
  • 索引是一种能提高数据库查询效率的数据结构,好比字典,加快查找效率。
  • 在数据库中表的检索分为两种:
    1.全表扫描
    2.就是根据索引检索。
  1. 索引的分类:
  • 数据结构维度:
    • B+树索引
    • B树索引
    • Hash索引
    • 全文索引
  • 物理存储维度:(B+Tree存储的方式不同划分)
    • 聚集索引:主键创建索引,叶子节点存储表中的数据
    • 非聚集索引:非主键创建索引,叶子节点存储主键和索引列
  • 逻辑维度:
    • 主键索引
    • 普通索引
    • 唯一索引
    • 联合索引
  1. 什么时候使用索引?
  • 数据量庞大
  • 字段很少进行DML操作(修改,插入,删除操作需要维护索引表)
  • 使用索引的字段经常出现在where语句中

三:SQL JOINS

连接:

select a.name, b.name from student a,classroom b;(笛卡尔积)

内连接:(多表之间平等)

  • 等值连接(select a.name, b.name from student a inner join classroom b on a.class_id = b.id;)
  • 非等值连接(select a.name, b.name from student a inner join classroom b on a.class_id between 1 and 2;)
  • 自连接

外连接:(有主表与副表之分

  • 左连接,左表为主表,左表必须全部查出,右表根据左表匹配查出,若无则用NULL表示
  • 右连接,与左连接相反。

全连接:用的少

框架篇

一:Spring

1. Spring的五个作用域

  • Singleton:单例**(Spring默认)**
  • Prototype:原型模式,每次getBean就会获取该bean对象的一个实例,创建后不Spring不在对其管理
  • Request:web项目中,每次请求产生一个实例
  • Session:web项目中,每次会话产生一次实例
  • Global Session:web项目中,全局的web域

知识关联:

JSP中的九大内置对象

  1. request
  2. response
  3. page
  4. pageContext
  5. config
  6. session
  7. application
  8. out
  9. exception

四大作用域:

  • request :作用于当前请求,若客户端发起多次请求则域中属性缺失,主要运用于资源转发
  • session: 作用于当前会话请求,若会话结束则域中属性缺失
  • application :作用于当前应用,若服务器关闭,则域中所有属性缺失
  • pageContext :作用于当前页面,一旦切换页面,则域中属性缺失,主要用来在jsp页面中的标签之间传递数据。

2. Spring中默认的scope,是否有线程安全问题?

Spring默认scope为’‘singleton’',存在线程安全问题

解决办法如下:

  • 将singleton改为protoType
    • 缺点:增加了spring的资源开销
  • 减少成员变量的使用,替换为requestMapping方法中的局部变量
    • 缺点:有些必须定义成员变量
  • 为了解决以上问题,可以采用线程安全的数据结构:concurrHashMap,,concurrHashSet等。
  • 分布式或微服务的线程安全可以使用Redis解决。

3. Spring中的缓存机制,以及循环依赖

一级缓存,也就是单例池,spring中bean的创建需要经过:

getBean()–>

单例池(有就返回,无就doCreatBean)–>

{doCreatBean (createBeanInstance<实例化>)–>

(populateBean<填充属性>))}–>

initalizeBean<初始化>–>

如果是可销毁的Bean则注册到Factory(放入单例池)中–>

Aop处理器–>

后置处理/提前处理–>

创建代理

循环依赖情况一:在不涉及代理对象的情况下,A类填充b,B类填充a,则产生循环依赖,解决方法,A实例化将a放入半成品池(二级缓存),B填充时在单例池中找不到就去半成品池中找。

循环依赖情况二:在建立代理对象时,半成品池中放着的是该某个类的实例对象,而不是代理对象,所以在A实例化时就需要对A放入三级缓存中,该缓存只有一个作用,进行提前处理,将A类创建代理对象(CGLIB),放入二级缓存中,当B类填充a时就可以从二级缓存中获取A的代理对象。

4. IOC

控制反转,是一种设计思想,而依赖注入(DI)是一种实现的方法。原本对象需要由程序员自己new,(这样确实可以,但是有个问题就是每次更改操作都需要修改源码,这是大忌),现在交给Spring容器帮我们创建并管理。

依赖注入(DI),将Spring容器中new出来的对象通过set方法(自动补全)赋值给studentService,这个过程叫依赖注入:DI

2022年JAVA面试总结(会持续补充)_第1张图片
依赖注入的四种形式:

  1. Set方式注入

setter是Spring现在最流行的注入方式,它可以利用Java Bean规范所定义的set/get方法来完成注入,它不需要使用构造器注入时出现的多个参数,它可以把构造方法声明成无参构造,再使用setter注入设置相对应的值,其实也是通过java反射技术去实现的。

package com.callen.spring.pojo;

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String gender;
    private Banji banji;
   //getter/setter方法和构造器省略...
}

xml文件配置:
2022年JAVA面试总结(会持续补充)_第2张图片

2.构造器注入

构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是无参,我们在平常都是通过类的构造方法来创建类对象,以及给他赋值,同样Spring 也可以采用反射的方式,通过构造方法来完成注入(赋值)。
2022年JAVA面试总结(会持续补充)_第3张图片

xml文件配置:

2022年JAVA面试总结(会持续补充)_第4张图片

3.注解方式

@Autowired默认按类型装配
@Qualifier和Autowired配合使用,指定bean的名称
@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
2022年JAVA面试总结(会持续补充)_第5张图片

这里再谈一下@Qualifier这个注解:

@Qualifier和Autowired配合使用,指定bean的名称,针对一个包下有多个子类的情况:

请添加图片描述

目的是让Controller层指定确定要注入哪个类

@Qualifier(value = "courseService2")
@Autowired
private ICourseService courseService;
//此时注入的就是CourseSercice2这个类。

4.接口注入(已废弃)

不做介绍,知道即可(本人也没了解,都废弃了知道了也没用)

5. AOP

AOP面向切面编程,是基于JDK代理模式的,将非业务代码,但是业务代码可共同使用的模块进行封装,以业务代码为切入点,增强代码为通知组成切面,增强业务代码的逻辑,是对面向对象编程的一种补充,使用场景例如计算业务代码的执行时间,输出日志等。

二:SpringMVC

Spring MVC的执行流程

三:MyBatis

四:SpringBoot

1.常用注解:

  • @Component
  • @Autowired
  • RequestMapping
  • ResponseBody
  • SpringBootApplication

2.springBoot自动配置:

核心注解:@SpringBootApplication

包括:

  • @SpringBootConfiguration

    • 项目中只有一个标注了SpringBootConfiguration的类
  • @ComponentScan

    • 组件扫描
    • 通过过滤器过滤掉实现了TypeExcludeFilter接口的类
    • 通过过滤器排除自身的自动配置类
  • @EnableAutoConfiguration

    • @AutoConfigurationPackage

      • 记录该注解所标注的类所在包名
    • @Import({AutoConfigurationImportSelector.class})

      • 用来加载(META-INF/spring.factories)下的配置类

      • AutoConfigurationImportSelector.class

        • 将所有的从属配置放入文件中,而不是直接指定类名(解耦)
        • 优先级低,保证当主配置处理完后再处理从属配置

2022年JAVA面试总结(会持续补充)_第6张图片

3.SpringBoot启动原理:

2022年JAVA面试总结(会持续补充)_第7张图片

WEB篇

一:网页状态码

状态码归类 作用
2开头(200) 请求成功,表示成功处理请求。
3开头
(302)
请求被重定向,表示要完成请求,需要进一步操作。
4开头
(404)
请求错误,这些状态码表示请求可能出错,妨碍了服务器的处理。
5开头
(500)
服务器错误,这些状态码表示服务器在尝试处理请求时发生内部错误,这些错误可能是服务器本身的错误,而不是请求出错。

二:Servlet生命周期

加载类—>**实例化(**为对象分配空间)—>init()初始化(为对象的属性赋值)—>service()请求响应(服务阶段)—>destroy()销毁

三:GET和POST的区别

1.URL可见性:

GET请求将参数拼接在url上,用户可见

POST请求将参数封装在body体中,用户不可见

2.缓存性:

get请求是可以缓存的

post请求不可以缓存

3.回退反应

get请求回退无影响

post请求回退会重新提交请求

4.数据传输大小

get 2k-4k

post根据php.ini配置文件设定,也可以无限大

5.安全性

原则上post会比get安全,但实际上是差不多的。

你可能感兴趣的:(java,Mysql,线程,java,面试,数据库)