java开发面试问答----spring框架及数据库缓存篇

参数配置

YAML配置和properties配置相比有什么区别

  • 配置有序,在一些特殊的场景下,配置有序很关键
  • 支持数组,数组中的元素能够是基本数据类型也能够是对象
  • 简洁
  • 不支持 @PropertySource 注解导入,须要建立一个实现PropertySourceFactory接口的类

获取配置文件中的参数有哪几种方式

  • @Value
  • @ConfigurationProperties
  • 经过Environment
    final ApplicationContext ctx = SpringApplication.run(SpringBootDemo3Application.class, args);
    Environment environment = ctx.getEnvironment();
    System.out.println(environment.getProperty("datasource.username"));
    复制代码
  • @PropertySource注解加载自定义的配置文件

spring

spring框架的原理

spring框架的核心是IOC控制反转和依赖注入。前端

  • 什么是控制反转:一般一个对象要调用另一个对象必须将对方new出来,而后在使用完后销毁掉,这就形成了对象之间的强耦合,而spring作的事情是将全部的对象注册到bean factory中,若是一个对象要调用另一个直接从bean factory中取就好,对于一个对象而言,以前是它控制其余对象的生命周期,而如今是spring 控制全部对象的生命周期,这就是控制的反转(控制权上交)。
  • 什么是依赖注入:既然全部对象的生命周期都被spring控制了,那若是一个对象要调用其余对象要怎么办呢,这就须要从spring中获取这个对象而后注入到本身里面来,这就是依赖注入。实现依赖注入的重要方法就是反射。

AOP和IOC原理

  • IOC实现原理:一个bean有id,类型和属性,首先须要定义一个bean的配置,spring读取配置实例化bean写到一个map中,map的key是bean id,value就是这个bean,若是有依赖其余对象,则从map中获取这个对象而后使用set方法set到bean属性中,最后返回这个bean的实例。
  • AOP:面向切面编程,在一个业务流程中有多个横向关注点,好比权限验证日志打印,在aop中几个重要概念:
    • 链接点:指须要切入执行的方法
    • 切入点:围绕链接点的一种判断表达式,判断是否要执行
    • 通知:通知有前置,后置,环绕,后置返回四种,当知足切入点时会发起通知
    • Aop实现技术有aspectj和spring aop两种,aspectj是编译时加强,须要按照规范写一个代理类加强业务类,而spring aop是动态代理实现,支持jdk代理和cglib代理,jdk动态代理是利用反射机制生成代理类链接点执行前执行的invokeHandler。

动态代理

动态代理是指经过类加载器和接口复制在具体方法执行时使用invokeHandler执行额外的操做。java

beanfactory和factory bean的区别

beanfactory是ioc容器,管理全部bean的生命周期,而factorybean是一个特殊的bean,它能够生产某一个特定bean,一般用来封装复杂bean的实例化过程。mysql

如何实现(保证)事务一致性完整性,spring中事务传播机制类型

  • REQUEST:方法必须在事务中执行,若是当前有事务则执行,若是没有则启动一个新的事务执行
  • SUPPORT:若是当前有事务则在事务中执行,若是没事务则以非事务执行
  • REQUEST_NEW:方法必须在本身的事务中执行,每次启动一个新的事务,两个事务互不影响
  • MANDATORY:方法必须在事务中执行,没有事务则抛错
  • NOT_SUPPORT:方法老是非事务的执行,若是存在外层事务,则外层事务挂起,方法非事务的执行
  • NEVER:方法老是非事务的执行,若是存在外层事务则抛错
  • NESTED:若是当前存在事务则挂起外层事务,启动子的事务执行,子事务执行失败会回到save点,外层事务回滚会影响子事务,子事务在外层事务commit时才commit

spring如何定义一个bean?代码描述。Bean的生命周期?Bean的scope?

将bean注册到spring有三种方法:使用@Component@Service注解,使用xml配置文件定义,基于java配置@bean。 首先是bean的实例化,而后调用set方法设置属性,获取上下文,执行关联器的before方法,执行初始化bean接口的afterPropertiesSet方法,执行init方法,执行关联器的after方法,bean完成,容器关闭,执行destroy方法。spring管理的bean默认都是单例的,非单例的bean会交给用户本身管理面试

MVC相关

什么是servlet,servlet生命周期

servlet是服务器端处理http请求小程序,当客户端发起请求时,服务器接到请求并发送给servlet,当servlet第一次被访问时执行实例化,并init初始化操做,servlet执行service方法生成响应内容后返回给服务端,服务端返回给客户端,最后当servlet关闭时执行servlet的destory方法销毁。redis

注解restcontroller和controller的区别

@RestController = @Controller + @ResponseBodyspring

一、若是使用@RestController注解controller,则controller中的方法没法返回页面,配置的视图解析器InternalResourceViewResolver不起做用,返回的内容就是return的内容。sql

二、若是须要返回到指定页面,须要使用@Controller注解controller数据库

三、若是须要直接返回内容如json,则须要在方法前使用@ResponseBody编程

拦截器和过滤器的区别

过滤器实现Filter接口,拦截器实现HandlerInterceptor接口json

相同点:

  • 都是aop编程思想的体现,能够在程序执行先后作一些操做,如权限操做,日志记录等

不一样点:

  • Filter是Servlet规范中定义的,SpringMVC的机制是由DispaterServlet来分发请求给不一样的Controller,拦截器是Spring框架中的
  • 触发时机不同,过滤器是在请求进入容器后,但请求进入servlet以前进行预处理的,过滤器在拦截器的外围
  • 拦截器能够获取IOC容器中的各个bean,而过滤器就不行,拦截器归Spring管理

什么时候使用拦截器?什么时候使用过滤器?

  • 若是是非spring项目,那么拦截器不能用,只能使用过滤器。
  • 若是是处理controller先后,既可使用拦截器也可使用过滤器。
  • 若是是处理dispaterServlet先后,只能使用过滤器。

spring mvc框架

(1)首先浏览器发送请求——>DispatcherServlet,前端控制器收到请求后本身不进行处理,而是委托给其余的解析器进行处理,做为统一访问点,进行全局的流程控制;

(2)DispatcherServlet——>HandlerMapping,处理器映射器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象;

(3)DispatcherServlet——>HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持不少类型的处理器;

(4)HandlerAdapter——>调用处理器相应功能处理方法,并返回一个ModelAndView对象(包含模型数据、逻辑视图名);

(5)ModelAndView对象(Model部分是业务对象返回的模型数据,View部分为逻辑视图名)——> ViewResolver, 视图解析器将把逻辑视图名解析为具体的View;

(6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构;

(7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

mybatis mysql

#{}和${}的区别

  • {}:简单字符串替换,把{}直接替换成变量的值,不作任何转换,这种是取值之后再去编译SQL语句。
  • #{}:预编译处理,sql中的#{}替换成?,补全预编译语句,调用PreparedStatement的set方法来赋值,有效的防止Sql语句注入,这种取值是编译好SQL语句再取值。

CHAR和VARCHAR的区别

mybaits在处理char类型时会把字符串补齐长度再比较,若是数据库中数据小于定义的char长度则会右侧补齐空格,而varchar没有这个问题。

like查询的几种方式

  • like '%${xxx}%'
  • like "%"#{xxx}"%"
  • like concat('%',#{xxx},'%')

事务的概念,脏读,如何定义一个事务,如何定义事务的隔离级别

  • 事务是一个最小的完整业务工做单元,它具备原子性(事务不可分割),一致性(要求全部DML操做要么同时成功要么同时失败),隔离性(不一样的事务之间互不影响)和持久性(事务完结内存数据写到磁盘)
  • mybatis的事务管理是用sqlsession作的,打开一个session后事务开始直到session被commit;spring事务管理中将事务的实现交给jdbc,jta,自身封装相同的api,要实现一个事务,可使用@transcational注解。
  • 第一类更新丢失,指事务b回滚将事务a的修改也回滚了,这种是没有隔离
  • 脏读的意思是读取了未提交的数据,事务a读取了事务b修改的数据,结果事务b回滚致使事务a中产生了脏数据。
  • 不可重复读的意思是同一个事务中不能读取重复的数据,缘由是并发状态同一个事务中可能先后两次读取的数据不一致。
  • 第二类更新丢失,指事务b修改将事务a修改的数据覆盖了。
  • 幻读和不可重复读有点像,意思是同一个事务中先后两次统计的条数不一致了。和不可重复度的区别是不可重复读读到的是别人修改的数据,而幻读读到的是别人新增的数据。

隔离级别

  • 读未提交:事务读不锁其余事务写也不锁读,事务写只锁其余事务写不锁读,能够防止第一类更新丢失,对写操做上持续排他锁
  • 读已提交:事务读不锁其余事务写也不锁读,事务写锁其余事务写也锁事务读,能够防止脏读,对写操做上持续排他锁,对读操做上临时共享锁
  • 可重复读:事务读锁其余事务写不锁事务读,事务写锁其余事务写也锁事务读,能够防止不可重复读,写操做上持续排他锁,读操做上持续共享锁(mysql默认隔离级别)
  • 串行化:全部操做串行化,表锁

锁的级别

innodb 有读锁(共享锁)和写锁(排他锁),读锁时其余事务只能读不能写,写锁时其余事务不能读也不能写。innodb在检索时若是不使用索引采起的是表级锁,采用索引则是行级锁,这是由于innodb是经过对索引项加锁实现的行级锁。另外innodb为了解决幻读问题采用了间隙锁,当范围查询时会将不存在的id也锁住防止新增数据。

redis相关

使用场景

  • 计数器 数据统计的需求很是广泛,经过原子递增incr保持计数。因为redis中存的是字符串,在递增时会把字符串转成十进制64位有符号整数计算。例如,点赞数、收藏数、分享数等。
  • 锁 setnx设置全局锁
  • 缓存 缓存一些热点数据
  • 消息队列 经过list的pop及push接口进行队列的写入和消费

持久化机制

  • redis支持两种持久化机制
    • 一种是rdb快照模式,将内存中的数据不断写入磁盘,优势是能够存储大量数据,缺点是每次生成快照时主线程会fork一个子线程写数据,会影响性能,另外若是忽然断电数据还没落盘则会丢失。
    • 一种是aof日志模式,记录每次更新的日志,这种方式详细记录了操做,弥补了rdb的一致性问题,可是aof文件记录太多会致使恢复很慢。

redis memcache的区别

  • memcache将数据所有放在内存中,断电会丢失,而redis支持持久化存储能够将数据存在硬盘上
  • redis支持的数据类型比memcache更丰富,在kv以外还支持如list,set,hash等
  • memcache最大不能超过内存大小,而redis因为能够写磁盘能够突破内存大小
  • 一般memcache仅用做数据库前的一层内存缓存,适合多读少写的场景;而redis因为支持更丰富的数据类型有更高的可靠性,能够当成内存数据库使用
相关文章
相关标签/搜索