Java面试题(java面试必备八股文)
nanshan 2024-10-21 06:13 9 浏览 0 评论
Spring Boot自动配置原理
Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。
springsecurity流程说明
客户端发起一个请求,进入 Security 过滤器链。
当到 LogoutFilter 的时候判断是否是登出路径,如果是登出路径则到 logoutHandler ,如果登出成功则到 logoutSuccessHandler 登出成功处理,如果登出失败则由 ExceptionTranslationFilter ;如果不是登出路径则直接进入下一个过滤器。
当到 UsernamePasswordAuthenticationFilter 的时候判断是否为登录路径,如果是,则进入该过滤器进行登录操作,如果登录失败则到 AuthenticationFailureHandler 登录失败处理器处理,如果登录成功则到 AuthenticationSuccessHandler 登录成功处理器处理,如果不是登录请求则不进入该过滤器。
当到 FilterSecurityInterceptor 的时候会拿到 uri ,根据 uri 去找对应的鉴权管理器,鉴权管理器做鉴权工作,鉴权成功则到 Controller 层否则到 AccessDeniedHandler 鉴权失败处理器处理。
SSM三个框架的优点。
一、mybatis的优缺点:
优点:a、sql写在xml文件中,便于统一管理和优化,解除sql和程序代码的耦合。
b、提供映射标签,支持对象和和数据库orm字段关系的映射,支持对象关系映射标签,支持对象关系的组建
c、提供xml标签,支持编写动态sql。
缺点:a、工作量较大,特别是在表的字段多,关联表多的情况下
b、sql语句的编写依赖于数据库,移植性差。
c、不支持级联删除,级联更新,需要自己对表进行删除。
二、spring的优点:
A、通过Spring的IOC特性,将对象之间的依赖关系交给了Spring控制,方便解耦,简化了开发。
B、通过Spring的AOP特性,很容易实现事务,日志,权限的控制。
C、提供了对其他优秀开源框架的集成支持。
D、地侵入式。
三、SpringMVC的优点
A、springMVC是使用了MVC设计思想的轻量级web框架,对web层进行解耦,是的我们开发更简洁。
B、与Spring无缝衔接。
C、灵活的数据验证,格式化,数据绑定机制
SSM框架实现一个web程序主要使用到如下三个技术:
Spring:用到注解和自动装配,就是Spring的两个精髓IOC(反向控制)和 AOP(面向切面编程)。
SpringMVC:用到了MVC模型,将流程控制代码放到Controller层处理,将业务逻辑代码放到Service层处理。
Mybatis:用到了与数据库打交道的层面,dao(mapper)层,放在所有的逻辑之后,处理与数据库的CRUD相关的操作。
Spring的容器中Bean生命周期如下
对象创建
1、从xml配置的Bean,@Bean注解,或者Java代码BeanDefinitionBuilder中读取Bean的定义,实例化Bean对象;
2、设置Bean的属性;
3、注入Aware的依赖(BeanNameAware,BeanFactoryAware,ApplicationContextAware);
4、执行通用的方法前置处理,方法: BeanPostProcessor.postProcessorBeforeInitialization()
5、执行 InitalizingBean.afterPropertiesSet() 方法
6、执行Bean自定义的初始化方法init,或者 @PostConstruct 标注的方法;
7、执行方法BeanPostProcessor.postProcessorAfterInitialization()
8、创建对象完毕;
对象销毁
9、执行 DisposableBean.destory() 方法;
10、执行自定义的destory方法或者 @PreDestory 标注的方法;
11、销毁对象完毕
struts2和springmvc的区别
一、拦截机制的不同
Struts2是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype,然后通过setter,getter吧request数据注入到属性。Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了,只能设计为多例。
SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。
Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。
二、底层框架的不同
Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet只是在调用时初始化,先于Filter调用,服务停止后销毁。
三、性能方面
Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。所以,SpringMVC开发效率和性能高于Struts2。
四、配置方面
spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高。
拦截器与过滤器的区别 :
拦截器是基于java的反射机制的,而过滤器是基于函数回调。
拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
Struts2的工作流程
一:客户端提交一个HttpServletRequest请求,(.action或JSP页面)
二:请求被提交到一系列的Filter过滤器,如ActionContextCleanUp和FileterDispather等。
三:FilterDispatcher是Struts2的控制核心,它通常是过滤器链中的最后一个过滤器。
四:请求发到FilterDispathcher后,FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个Request(一般根据URL后缀是否为.action来判断)
五:如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求交到ActionProxy,由其进行处理。
六:ActionProxy通过ConfigurationManager(它会访问Struts.xml询问创建的配置文件,找到需要调用的Action类)
七:ActionProxy创建一个ActionInvocation实例,而ActionInvocation通过代理模式调用Action(在调用之后会根据配置文件加载相关的所有Interceptor拦截器)
八:Action执行完毕后,返回一个result字符串,此时再按相反的顺序通过Interceptor拦截器
九:最后ActionInvocation负责根据struts.xml中配置的result,决定进行下一步输出
简化版:
①:客户端初始化一个指向Servlet容器的请求
②:请求经过系列过滤器,FilterDispatcher被调用
③:ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
④:ActionProxy通过ConfigurationManager询问框架的配置文件找到需要调用的Action类
⑤:ActionProxy创建一个ActionInvocation实例
⑥:ActionInvocation调用、回调Action的execute方法
⑦:Action执行完毕ActionInvocation,根据struts.xml配置找到对应的返回结果
springmvc工作流程
1、用户发送请求至前端控制器DispatcherServlet。
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView。
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、ViewReslover解析后返回具体View.
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户。
hibernate和mybatis的区别
一、两者最大的区别
针对简单逻辑,Hibernate与MyBatis都有相应的代码生成工具,可以生成简单基本的DAO层方法。
针对高级查询,MyBatis需要手动编写SQL语句,以及ResultMap,而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于流程。
二、开发难度对比
Hibernate的开发难度大于MyBatis,主要由于Hibernate比较复杂,庞大,学习周期比较长。
MyBatis则相对简单,并且MyBatis主要依赖于sql的书写,让开发者刚进更熟悉。
三、sql书写比较
Hibernate也可以自己写sql来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性,不过Hibernate具有自己的日志统计。
MyBatis的sql是手动编写的,所以可以按照要求指定查询的字段,不过没有自己的日志统计,所以要借助Log4j来记录日志。
四、数据库扩展性计较
Hibernate与数据库具体的关联在XML中,所以HQL对具体使用什么数据库并不是很关心
MyBatis由于所有sql都是依赖数据库书写的,所以扩展性、迁移性比较差。
五、缓存机制比较
Hibernate的二级缓存配置在SessionFactory生成配置文件中进行详细配置,然后再在具体的表对象映射中配置那种缓存。
MyBatis的二级缓存配置都是在每个具体的表对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓冲机制,并且MyBatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。
两者比较,因为Hibernate对查询对象有着良好的管理机制,用户无需关心SQL,所以在使用二级缓存时如果出现脏数据,系统会报出错误提示。 而MyBatis在这一方面使用二级缓存时需要特别小心,如果不能完全去顶数据更新操作的波及范围,避免cache的盲目使用,否则,脏数据的出现会给系统的正常运行带来很大的隐患。
hibernate工作原理
通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的读取并解析映射信息
3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
4.Session session = sf.openSession();//打开Sesssion
5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
6.persistent operate操作数据,持久化操作 session.save(XXX).
7.tx.commit();//提交事务
8.关闭Session
9.关闭SesstionFactory
Hibernate的缓存机制
Hibernate缓存分为一级缓存和二级缓存
一级缓存:每次hibernate跟数据库打交道时,都是通过session来对要操作的对象取得关联,然后在进行操作,那么具体的过程是什么样的呢?
1、首先session将一个对象加入自己的管理范围内,其实也就是把该对象放入自己的一级缓存中,例如,session.save(xxx);这个语句就是将xxx保存在自己的一级缓存中,等待事务提交后,hibernate才真正的发sql语句,对数据库进行操作。注意:session进行操作的时候,是将对象加入自己的一级缓存,并不是就直接跟数据库打交道了。session.save()操作就是一级缓存的过程。
二级缓存:hibernate二级缓存是由第三方提供以插件的形式存在,常用的缓存实现有Ehcache、oscache.
瞬时状态:使用new操作符初始化的对象的状态就是瞬时的,
1、在数据库表中,没有任何一条数据与它对应
2、不在session的缓存中
持久状态:在session的缓存中,
1、在session的缓存中(注意,很多书上都觉得持久化状态都在数据库表中有相应记录,这个是错误的,比如一个瞬时状态的对象刚被session.save(),事务还没提交,此时瞬时状态就已经变为持久化状态了,但是在数据库中还没有记录)
2、在数据库中可能有记录。
托管状态:从session的缓存中移除出来了
1、是从session缓存中出来的,也就是从持久状态转变而来的,没有别的方式能到达游离(脱管)状态,只有这一种。
2、不在session的管理范围内
3、在数据库中有记录
总结:
1、如果是在session缓存中,那么就一定是持久状态
2、如果是刚new出来的对象,那么就肯定是瞬时状态
3、如果是从session缓存中出来的,也就是通过一些session.clear、ecivt等操作,清除了缓存的,那么就是游离状态,
只有瞬时状态能确定数据库中没有对应记录,其他两个状态,都是不确定数据库中是否有对应记录
mybatis工作原理
1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。
2、SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。
3、SqlSession对象完成和数据库的交互:
a、用户程序调用mybatis接口层api(即Mapper接口中的方法)
b、SqlSession通过调用api的Statement ID找到对应的MappedStatement对象
c、通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象
d、JDBC执行sql。
e、借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。
Mybatis缓存
一级缓存
Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
为什么要使用一级缓存,不用多说也知道个大概。但是还有几个问题我们要注意一下。
1、一级缓存的生命周期有多长?
a、MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象。Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。
b、如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。
c、如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用。
d、SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用
2、怎么判断某两次查询是完全相同的查询?
mybatis认为,对于两次查询,如果以下条件都完全一样,那么就认为它们是完全相同的两次查询。
2.1 传入的statementId
2.2 查询时要求的结果集中的结果范围
2.3. 这次查询所产生的最终要传递给JDBC java.sql.Preparedstatement的Sql语句字符串(boundSql.getSql() )
2.4 传递给java.sql.Statement要设置的参数值
二级缓存:
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。
SqlSessionFactory层面上的二级缓存默认是不开启的,二级缓存的开席需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置就可以开启缓存了,如果我们配置了二级缓存就意味着:
映射语句文件中的所有select语句将会被缓存。
映射语句文件中的所有insert、update和delete语句会刷新缓存。
缓存会使用默认的Least Recently Used(LRU,最近最少使用的)算法来收回。
根据时间表,比如No Flush Interval,(CNFI没有刷新间隔),缓存不会以任何时间顺序来刷新。
缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全的被调用者修改,不干扰其他调用者或线程所做的潜在修改。
spring ioc
对于Spring,核心就是IOC容器,这个容器说白了就是把你放在里面的对象(Bean)进行统一管理,你不用考虑对象如何创建如何销毁,从这方面来说,所谓的控制反转就是获取对象的方式被反转了。既然你都把对象交给人家Spring管理了,那你需要的时候不得给人家要呀。这就是依赖注入(DI)!再想下,我们在传入一个参数的时候除了在构造方法中就是在setter方法中,换个好听的名字就是构造注入和设值注入。
关于Jdk动态代理的原理,我归纳得出四步
声明一段源码,源码动态产生动态代理
源码产生java文件,对java文件进行编译
得到编译生成后的class文件
把class文件load到内存之中,产生代理类对象返回即可
spring aop
至于AOP(面向切面),这玩意我举个例子说下,比如你写了个方法用来做一些事情,但这个事情要求登录用户才能做,你就可以在这个方法执行前验证一下,执行后记录下操作日志,把前后的这些与业务逻辑无关的代码抽取出来放一个类里,这个类就是切面(Aspect),这个被环绕的方法就是切点(Pointcut),你所做的执行前执行后的这些方法统一叫做增强处理(Advice)。
简单说说 AOP 的设计:
每个 Bean 都会被 JDK 或者 Cglib 代理。取决于是否有接口。
每个 Bean 会有多个“方法拦截器”。注意:拦截器分为两层,外层由 Spring 内核控制流程,内层拦截器是用户设置,也就是 AOP。
当代理方法被调用时,先经过外层拦截器,外层拦截器根据方法的各种信息判断该方法应该执行哪些“内层拦截器”。内层拦截器的设计就是职责连的设计。
1、代理的创建(按步骤):
首先,需要创建代理工厂,代理工厂需要 3 个重要的信息:拦截器数组,目标对象接口数组,目标对象。
创建代理工厂时,默认会在拦截器数组尾部再增加一个默认拦截器 —— 用于最终的调用目标方法。
当调用 getProxy 方法的时候,会根据接口数量大于 0 条件返回一个代理对象(JDK or Cglib)。
2、代理的调用
当对代理对象进行调用时,就会触发外层拦截器。
外层拦截器根据代理配置信息,创建内层拦截器链。创建的过程中,会根据表达式判断当前拦截是否匹配这个拦截器。而这个拦截器链设计模式就是职责链模式。
当整个链条执行到最后时,就会触发创建代理时那个尾部的默认拦截器,从而调用目标方法。最后返回。
spring bean 容器的生命周期流程如下:
Spring 容器根据配置中的 bean 定义中实例化 bean。
Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName()。
如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。
如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调用它。
最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
如果为 bean 指定了 destroy 方法( 的 destroy-method 属性),那么将调用它。
事务四大特性
原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态
一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的;
隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
持久性:事务一旦提交,其结果就是永久的。即便发生系统故障,也能恢复。
事务隔离级别
未提交读(Read Uncommitted):允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)。
可重复读(Repeated Read):可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响。
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
MySQL数据库(InnoDB引擎)默认使用可重复读( Repeatable read)
索引相关
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用 B_TREE。B_TREE 索引加速了数据访问,因为存储引擎不会再去扫描整张表得到需要的数据;相反,它从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速寻找数据。
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址,即:MyISAM索引文件和数据文件是分离的,MyISAM的索引文件仅仅保存数据记录的地址。MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。MyISAM的索引方式也叫做“非聚集”的。
InnoDB引擎也使用B+Tree作为索引结构,但是InnoDB的数据文件本身就是索引文件,叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这种索引叫做“聚焦索引”。InnoDB的辅助索引的data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。InnoDB的索引实现后,不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。在Innodb中也不建议使用非单调的字段作为主键,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,建议使用自增字段作为主键。
MySQL数据库的四类索引:
index ---- 普通索引,数据可以重复,没有任何限制。
unique ---- 唯一索引,要求索引列的值必须唯一,但允许有空值;如果是组合索引,那么列值的组合必须唯一。
primary key ---- 主键索引,是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值,一般是在创建表的同时创建主键索引。
组合索引 ---- 在多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。
fulltext ---- 全文索引,是对于大表的文本域:char,varchar,text列才能创建全文索引,主要用于查找文本中的关键字,并不是直接与索引中的值进行比较。fulltext更像是一个搜索引擎,配合match against操作使用,而不是一般的where语句加like。
注:全文索引目前只有MyISAM存储引擎支持全文索引,InnoDB引擎5.6以下版本还不支持全文索引
所有存储引擎对每个表至少支持16个索引,总索引长度至少为256字节,索引有两种存储类型,包括B型树索引和哈希索引。
索引可以提高查询的速度,但是创建和维护索引需要耗费时间,同时也会影响插入的速度,如果需要插入大量的数据时,最好是先删除索引,插入数据后再建立索引。
索引生效条件
假设index(a,b,c)
最左前缀匹配:模糊查询时,使用%匹配时:’a%‘会使用索引,’%a‘不会使用索引
条件中有or,索引不会生效
a and c,a生效,c不生效
b and c,都不生效
a and b > 5 and c,a和b生效,c不生效。
检测索引的效果:
show status like ‘%handler_read%’ 越大越好
sql语句分类:
DDL:数据定义语言(create drop)
DML:数据操作语句(insert update delete)
DQL:数据查询语句(select )
DCL:数据控制语句,进行授权和权限回收(grant revoke)
TPL:数据事务语句(commit collback savapoint)
数据库三范式:
第一范式:1NF是对属性的原子性约束,要求字段具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
第二范式:2NF是在满足第一范式的前提下,非主键字段不能出现部分依赖主键;解决:消除复合主键就可避免出现部分依赖,可增加单列关键字。
第三范式:3NF是在满足第二范式的前提下,非主键字段不能出现传递依赖,比如某个字段a依赖于主键,而一些字段依赖字段a,这就是传递依赖。解决:将一个实体信息的数据放在一个表内实现。
脏读、幻读、不可重复读
脏读: 是指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。
不可重复读 :是指在数据库访问时,一个事务范围内的两次相同查询却返回了不同数据。在一个事务内多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改,第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读: 是指当事务不是独立执行时发生的一种现象,比如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生,操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。
不可重复读&幻读区别:
如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
不可重复读重点在于update和delete,而幻读的重点在于insert。如何通过锁机制来解决他们产生的问题
存储引擎 MyISAM 和 InnoDB区别:
InnoDB支持事务,MyISAM不支持。
MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用。
InnoDB支持外键,MyISAM不支持。
从MySQL5.5.5以后,InnoDB是默认引擎。
MyISAM支持全文类型索引,而InnoDB不支持全文索引。
InnoDB中不保存表的总行数,select count() from table时,InnoDB需要扫描整个表计算有多少行,但MyISAM只需简单读出保存好的总行数即可。注:当count()语句包含where条件时MyISAM也需扫描整个表。
对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。
清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表。MyisAM使用delete语句删除后并不会立刻清理磁盘空间,需要定时清理,命令:OPTIMIZE table dept;
InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’)
Myisam创建表生成三个文件:.frm 数据表结构 、 .myd 数据文件 、 .myi 索引文件,Innodb只生成一个 .frm文件,数据存放在ibdata1.log
现在一般都选用InnoDB,主要是MyISAM的全表锁,读写串行问题,并发效率锁表,效率低,MyISAM对于读写密集型应用一般是不会去选用的。
应用场景:
MyISAM不支持事务处理等高级功能,但它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
InnoDB用于需要事务处理的应用程序,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。
CHAR和VARCHAR的区别:
CHAR和VARCHAR类型在存储和检索方面有所不同
CHAR列长度固定为创建表时声明的长度,长度值范围是1到255
当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。
Mysql中的锁类型
MyISAM支持表锁,InnoDB支持表锁和行锁,默认为行锁
表级锁:开销小,加锁快,不会出现死锁。锁定力度大,发生锁冲突的概率最高,并发量最低
星级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高
存储过程
我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。
优点:
(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。
(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
delete、drop、truncate区别
truncate 和 delete只删除数据,不删除表结构 ,drop删除表结构,并且释放所占的空间。
删除数据的速度,drop> truncate > delete
delete属于DML语言,需要事务管理,commit之后才能生效。drop和truncate属于DDL语言,操作立刻生效,不可回滚。
使用场合:
当你不再需要该表时, 用 drop;
当你仍要保留该表,但要删除所有记录时, 用 truncate;
当你要删除部分记录时(always with a where clause), 用 delete.
注意: 对于有主外键关系的表,不能使用truncate而应该使用不带where子句的delete语句,由于truncate不记录在日志中,不能够激活触发器
https://zhuanlan.zhihu.com/p/62382615
spring循环依赖
连接池的工作原理
连接池的核心思想是连接的复用,通过建立一个数据库连接池以及一套连接使用、分配和管理策略,使得该连接池中的连接可以得到高效,安全的复用,避免了数据库连接频繁建立和关闭的开销。
??连接池的工作原理主要由三部分组成,分别为连接池的建立,连接池中连接的使用管理,连接池的关闭。
??第一、连接池的建立。 一般在系统初始化时,连接池会根据系统配置建立,并在池中建立几个连接对象,以便使用时能从连接池中获取。java 中提供了很多容器类,可以方便地构建连接池,例如 Vector(线程安全类),linkedlist 等。
??第二、连接池的管理。 连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其策略是:
??当客户请求数据库连接时,首先查看连接池中是否有空闲连接,如果存在空闲连接,则将连接分配给客户使用并作相应处理(即标记该连接为正在使用,引用计数加 1);如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没有达到最大连接数,就重新创建一个连接给请求的客户;如果达到,就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。
??当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过了就从连接池中删除该连接,并判断当前连接池内总的连接数是否小于最小连接数,若小于就将连接池充满;如果没超过就将该连接标记为开放状态,可供再次复用。
??第三、连接池的关闭。 当应用程序退出时,关闭连接池中所有的链接,释放连接池相关资源,该过程正好与创建相反。
连接池的主要优点
1)、减少连接的创建时间。连接池中的连接是已准备好的,可以重复使用的,获取后可以直接访问数据库,因此减少了连接创建的次数和时间。
??2)、更快的系统响应速度。数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
??3)、统一的连接管理。如果不使用连接池,每次访问数据库都需要创建一个连接,这样系统的稳定性受系统的连接需求影响很大,很容易产生资源浪费和高负载异常。连接池能够使性能最大化,将资源利用控制在一定的水平之下。连接池能控制池中的链接数量,增强了系统在大量用户应用时的稳定性。
问题来源:对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。
问题解决:连接复用。通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。
原理:数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。外部使用者可通过getConnection 方法获取连接,使用完毕后再通过releaseConnection 方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。
PageHelper
PageHelper拦截的是org.apache.ibatis.executor.Executor的query方法,其传参的核心原理是通过ThreadLocal进行的。当我们需要对某个查询进行分页查询时,我们可以在调用Mapper进行查询前调用一次PageHelper.startPage(…),这样PageHelper会把分页信息存入一个ThreadLocal变量中。在拦截到Executor的query方法执行时会从对应的ThreadLocal中获取分页信息,获取到了,则进行分页处理,处理完了后又会把ThreadLocal中的分页信息清理掉,以便不影响下一次的查询操作。所以当我们使用了PageHelper.startPage(…)后,每次将对最近一次的查询进行分页查询,如果下一次查询还需要进行分页查询,需要重新进行一次PageHelper.startPage(…)。这样就做到了在引入了分页后可以对原来的查询代码没有任何的侵入性。此外,在进行分页查询时,我们的返回结果一般是一个java.util.List,PageHelper分页查询后的结果会变成com.github.pagehelper.Page类型,其继承了java.util.ArrayList,所以不会对我们的方法声明造成影响。com.github.pagehelper.Page中包含有返回结果的分页信息,包括总记录数,总的分页数等信息,所以一般我们需要把返回结果强转为com.github.pagehelper.Page类型
相关推荐
- 详解 HTTPS、TLS、SSL、HTTP区别和关系
-
一、什么是HTTPS、TLS、SSLHTTPS,也称作HTTPoverTLS。TLS的前身是SSL,TLS1.0通常被标示为SSL3.1,TLS1.1为SSL3.2,TLS1.2为SSL...
- 锐安信SSL证书自动化运维系统:灵活管理SSL/TLS证书全生命周期
-
点击上方关注“锐成云分销”,云建站解决方案专家!域名、SSL证书、DNS、主机一站选齐在SSL/TLS证书的生命周期管理中,证书的各种操作方式是基础且核心的部分之一,更是保障用户数据传输加密的关键。这...
- 宝塔免费的 SSL/TLS 证书如何续签
-
申请之前,请确保域名已解析,如未解析会导致审核失败(包括根域名)宝塔SSL申请的是免费版TrustAsiaDVSSLCA-G5证书,仅支持单个域名申请有效期1年,不支持续签,到期后需要重新申...
- HTTPS、HTTP、TLS/SSL工作及握手原理、PKI/CA密钥体系
-
一、HTTPS与HTTP介绍二、TLS/SSL工作原理三、TSL/SSL握手过程四、HTTPS性能优化五、PKI体系一、HTTPS与HTTP介绍1.Https(SecureHypetextTran...
- 什么是SSL证书卸载 SSL证书卸载有什么作用
-
SSL证书是数字证书的一种,安装部署的话可以对网站起到身份验证和数据加密的作用。网站部署SSL证书,相对就必然会有SSL证书卸载,那么SSL证书卸载是什么呢?SSL证书卸载有什么作用?随着SSL通信量...
- 让SSL/TLS协议流行起来:深度解读SSL/TLS实现1
-
一前言SSL/TLS协议是网络安全通信的重要基石,本系列将简单介绍SSL/TLS协议,主要关注SSL/TLS协议的安全性,特别是SSL规范的正确实现。本系列的文章大体分为3个部分:SSL/TLS协...
- 苹果、谷歌、微软等一致同意!SSL/TLS证书最长有效期锐减至47天
-
快科技4月14日消息,苹果此前向CA/B论坛(负责管理SSL/TLS证书的行业组织)提议,将所有证书有效期缩短至45天。日前CA/B论坛服务器证书工作组投票通过SC-081v3提案,最终决定将SSL/...
- Android怎么设置端口转发,将访问本设备的端口转到另外一台设备
-
一、Android系统怎么设置端口转发,将访问本设备的端口转到另外一台设备?要设置端口转发,您需要先在Android设备上安装一个支持端口转发的应用程序。其中一个常用的应用是"Termux...
- 大神级产品:手机装 Linux 运行 Docker 如此简单
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:灵昱Termux作为一个强大的Android终端模拟器,能够运行多种Linux环境。然而,直接在Termux上运行Docker并不可行,需要...
- 关于H3C交换机的SSH功能配置方法(华三交换机ssh配置)
-
对于交换机的初步学习,作为初学者的我,还望诸位不吝赐教。若存在不足之处,烦请大家多提宝贵意见。同样身为初学者的我们,亦可携手共进,相互分享技术经验。一、本地用户配置(核心步骤)1.创建用户并设置密码...
- Linux常用操作ssh(linux中的ssh命令)
-
ssh#p是小写ssh-p22user@hostsftp#连接sftp-P22root@host#将文件上传到服务器上:put[本地文件的地址][服务器上文件存储的位置]#将...
- 小白心得,如何使用SSH连接飞牛系统(fnos)?
-
一、背景作为一个刚接触飞牛系统的小白,在研究飞牛os的时候,发现很多功能都需要连接ssh,但是如何使用SSH连接飞牛系统成为入门飞牛os的一道坎。下面以自己的学习经历详细记录下过程吧。二、系统设置1、...
- 如何在 Windows 11 或 10 上使用 Winget 安装 OpenSSH
-
SSH(SecureShell)是大多数开发人员和系统管理员用来通过Linux远程连接托管服务器或任何云服务的工具,因为SSH在Linux中是内置的。然而,对于Windows呢?是的...
- linux文件之ssh配置文件的含义与作用
-
ssh远程登录命令是操作系统(包括linux和window系统)下常用的操作命令,可以帮助用户,远程登录服务器系统,查看,操作系统相关信息。linux系统对于ssh命令有专门保存其相关配置的目录和文件...
- 害怕Linux SSH不安全?这几个小妙招安排上!
-
ssh是访问远程服务器最常用的方法之一,同时,其也是Linux服务器受到攻击的最常见的原因之一。不过别误会...我们并不是说ssh有什么安全漏洞,相反,它在设计上是一个非常安全的协议。但是安...
你 发表评论:
欢迎- 一周热门
-
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
[常用工具] OpenCV_contrib库在windows下编译使用指南
-
Ubuntu系统Daphne + Nginx + supervisor部署Django项目
-
WindowsServer2022|配置NTP服务器的命令
-
WIN11 安装配置 linux 子系统 Ubuntu 图形界面 桌面系统
-
解决Linux终端中“-bash: nano: command not found”问题
-
极空间如何无损移机,新Z4 Pro又有哪些升级?极空间Z4 Pro深度体验
-
NBA 2K25虚拟内存不足/爆内存/内存占用100% 一文速解
-
Linux 中的文件描述符是什么?(linux 打开文件表 文件描述符)
-
- 最近发表
-
- 详解 HTTPS、TLS、SSL、HTTP区别和关系
- 锐安信SSL证书自动化运维系统:灵活管理SSL/TLS证书全生命周期
- 宝塔免费的 SSL/TLS 证书如何续签
- HTTPS、HTTP、TLS/SSL工作及握手原理、PKI/CA密钥体系
- 什么是SSL证书卸载 SSL证书卸载有什么作用
- 让SSL/TLS协议流行起来:深度解读SSL/TLS实现1
- 苹果、谷歌、微软等一致同意!SSL/TLS证书最长有效期锐减至47天
- Android怎么设置端口转发,将访问本设备的端口转到另外一台设备
- 大神级产品:手机装 Linux 运行 Docker 如此简单
- 关于H3C交换机的SSH功能配置方法(华三交换机ssh配置)
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)