本篇博客为博主个人面试总结,欢迎补充指正。
文章大多总结为主,不提供详细内容。
在数据库系统中,一个事务指数据库的一系列操作组成的完整逻辑,要么全部完成,要么全部不完成
原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会停在中间某个阶段,发生错误时会进行回滚。
一致性:事务在发生的前后数据库的完整性不会被破坏;这就表示写入的数据必须必须符合所有预设约束、触发器、级联回滚等。
隔离性:防止事务在高并发的时候导致不同的事务因为交叉执行而导致数据不一致;事务包括四个隔离级别
- 读未提交
- 读已提交
- 可重复读
- 串行化
- 持久性:事务结束后对数据的修改是永久的,即就算系统故障,数据也不会丢失。
1.** 脏读**:前者修改,后者读若前者回滚,后者读取数据无效。
不可重复读:前者读,后者改,前者在读,造成两次数据不同。(重点在update和delete)
幻读:前者读,后者插入,前者再读时多出数据(例如新增行操作,重点在于insert)
读未提交:都不能解决(允许事务1读取事务2未提交的修改)
读已提交:能解决脏读(Oracle默认隔离级别)(要求事务1只能读取事务2已提交的修改)
可重复读:能解决脏读、不可重复读(MySQL默认隔离级别)(事务1执行期间禁止其他事务对数据进行更新)
串行化:能解决脏读、不可重复读、幻读(事务1执行期间禁止其他事务对数据进行添加、更新、删除操作)
例如:一个方法运行在一个开启了事务的方法中,那么这个方法是使用原来的事务还是再开启一个事务就需要传播行为来确定。
Spring中事务的传播行为有七种:
1.REQUIRED(required):需要,如果存在一个事务,就使用当前的事务,如果没有就开启一个新的事务。(一般用于Service中的方法里有更新的操作)
2.SUPPORTS(supports):支持,如果存在一个事务,就是用当前事务,如果没有事务,则非事务的执行(一般用于Service中的方法里都是查询的操作)
3.REQUIRES_NEW:总是开启一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起。
4.MANDATORY(mandatory)
5.NEVER
6.NOT_SUPPORTED
7.NESTED
- 数据结构维度:
- B+树索引
- B树索引
- Hash索引
- 全文索引
- 物理存储维度:(B+Tree存储的方式不同划分)
- 聚集索引:主键创建索引,叶子节点存储表中的数据
- 非聚集索引:非主键创建索引,叶子节点存储主键和索引列
- 逻辑维度:
- 主键索引
- 普通索引
- 唯一索引
- 联合索引
- 数据量庞大
- 字段很少进行DML操作(修改,插入,删除操作需要维护索引表)
- 使用索引的字段经常出现在where语句中
连接:
select a.name, b.name from student a,classroom b;(笛卡尔积)
内连接:(多表之间平等)
外连接:(有主表与副表之分)
全连接:用的少
知识关联:
JSP中的九大内置对象
- request
- response
- page
- pageContext
- config
- session
- application
- out
- exception
四大作用域:
- request :作用于当前请求,若客户端发起多次请求则域中属性缺失,主要运用于资源转发
- session: 作用于当前会话请求,若会话结束则域中属性缺失
- application :作用于当前应用,若服务器关闭,则域中所有属性缺失
- pageContext :作用于当前页面,一旦切换页面,则域中属性缺失,主要用来在jsp页面中的标签之间传递数据。
Spring默认scope为’‘singleton’',存在线程安全问题
解决办法如下:
一级缓存,也就是单例池,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的代理对象。
控制反转,是一种设计思想,而依赖注入(DI)是一种实现的方法。原本对象需要由程序员自己new,(这样确实可以,但是有个问题就是每次更改操作都需要修改源码,这是大忌),现在交给Spring容器帮我们创建并管理。
依赖注入(DI),将Spring容器中new出来的对象通过set方法(自动补全)赋值给studentService,这个过程叫依赖注入:DI
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方法和构造器省略...
}
2.构造器注入
构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是无参,我们在平常都是通过类的构造方法来创建类对象,以及给他赋值,同样Spring 也可以采用反射的方式,通过构造方法来完成注入(赋值)。
xml文件配置:
3.注解方式
@Autowired默认按类型装配
@Qualifier和Autowired配合使用,指定bean的名称
@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
这里再谈一下@Qualifier这个注解:
@Qualifier和Autowired配合使用,指定bean的名称,针对一个包下有多个子类的情况:
目的是让Controller层指定确定要注入哪个类
@Qualifier(value = "courseService2")
@Autowired
private ICourseService courseService;
//此时注入的就是CourseSercice2这个类。
4.接口注入(已废弃)
不做介绍,知道即可(本人也没了解,都废弃了知道了也没用)
AOP面向切面编程,是基于JDK代理模式的,将非业务代码,但是业务代码可共同使用的模块进行封装,以业务代码为切入点,增强代码为通知组成切面,增强业务代码的逻辑,是对面向对象编程的一种补充,使用场景例如计算业务代码的执行时间,输出日志等。
核心注解:@SpringBootApplication
包括:
@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
用来加载(META-INF/spring.factories)下的配置类
AutoConfigurationImportSelector.class
状态码归类 | 作用 |
---|---|
2开头(200) | 请求成功,表示成功处理请求。 |
3开头 (302) |
请求被重定向,表示要完成请求,需要进一步操作。 |
4开头 (404) |
请求错误,这些状态码表示请求可能出错,妨碍了服务器的处理。 |
5开头 (500) |
服务器错误,这些状态码表示服务器在尝试处理请求时发生内部错误,这些错误可能是服务器本身的错误,而不是请求出错。 |
加载类—>**实例化(**为对象分配空间)—>init()初始化(为对象的属性赋值)—>service()请求响应(服务阶段)—>destroy()销毁
1.URL可见性:
GET请求将参数拼接在url上,用户可见
POST请求将参数封装在body体中,用户不可见
2.缓存性:
get请求是可以缓存的
post请求不可以缓存
3.回退反应
get请求回退无影响
post请求回退会重新提交请求
4.数据传输大小
get 2k-4k
post根据php.ini配置文件设定,也可以无限大
5.安全性
原则上post会比get安全,但实际上是差不多的。