SSM阶段面试题

SSM阶段面试题

1.mybatis

1.1. #{}和${}的区别是什么?
  1. #{}是预编译处理,$ {}是字符串替换。
  2. MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。
  3. 使用 #{} 可以有效的防止SQL注入,提高系统安全性。
1.2. 当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
  1. 如果符合驼峰命名规则,可以使用@Column(name = “表字段名”)转驼峰

  2. 如果符合驼峰命名规则,也可以在xml配置文件中开启全局配置

    <setting name="mapUnderscoreToCamelCase" value="true"/>

  3. 如果不符合驼峰命名,可以通过@result自定义映射规则或者<result column="字段名" property="实体属性名"/>

1.3. Mybatis是如何进行分页的?分页插件的原理是什么?

实现原理:使用Mybatis里面的第三方插件pagehelper(也称为拦截器)进行分页,通过PageHelper.startPage(拦截规则)进行拦截数据库数据,也就是重写sql语句,根据不同的数据生产不同的分页语句。

  1. 导入pagehelper导入依赖

    <dependency>
        <groupId>com.github.pagehelper</groupId>
    	<artifactId>pagehelper</artifactId>
    	<version>5.1.11</version>
    </dependency>
    
  2. 在setPlugins()设置添加pageInterceptor插件

PageInterceptor pageInterceptor = new PageInterceptor();
pageInterceptor.setProperties(new Properties());
factoryBean.setPlugins(new PageInterceptor[]{pageInterceptor});
  1. 或者在xml配置文件中<configuration>中添加plugin插件配置和设置分页规则

    <plugin interceptor="com.autumn.interceptor.MyPageInterceptor">

1.4. 在mapper中如何传递多个参数?
  1. 可以将多个参数封装成一个对象或map集合传递
  2. 可以通过参数池传递,@param设置存储在参数池的名字
  3. 也可以通过#{}表达式传值,前提是参数命名和#{}的参数保持一致
1.5. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis支持延迟加载,实现原理主要通过使用CGLIB为目标对象建立代理对象,当调用目标对象的方法时进入拦截器方法,当调用一个方法时,拦截器方法invoke()会根据这个方法所需要的东西发送给方法。

1.6. 详细解释一下Mybatis的一级、二级缓存

一级缓存是sqlsession级别:首先从sqlsession的一级缓存中cache查找数据,如果没有数据,则从数据库中查询返回给一级缓存,再返回数据信息。

/**
  * 一级缓存是sqlSession级别
  * 在一个sqlSession的声明周期中有效
  * 在一次的连接过程中有效(无法跨sqlsession有效)
  * 默认开启无法关闭
  * 当前的sqlSession调用了增删改会清空一级缓存中的数据
  * 如果提交也会清空一级缓存中的数据
*/

二级缓存是mapper级别:首先通过cacheExecuter缓存执行器中,在二级缓存mapper查找,如果没有记录,再从一级缓存sqlsession中查找,如果再没有记录,则从数据库查找返回给一级缓存返回给执行器,再返回数据信息,但关闭session时,一级缓存会清空,一级缓存的会将数据序列号放入二级缓存中,下次再查相同的数据时,可以直接从二级缓存中查找,可以跨sqlsession传递。

/**
  * 二级缓存:
  * mapper级别的缓存,所有sqlSession都可以获取到二级缓存中的数据
  * 当一级缓存关闭的时候,会将数据写入二级缓存
  * 当数据发生更改,会导致缓存清空
  *
  * 二级缓存操作:
  * 1.开启全局二级缓存支持,默认开启
  * 2.在需要使用二级缓存的mapper添加 <cache></cache> 或 @CacheNameSpace
  * 3.需要被缓存的方法查询数据上添加 useCache=true  默认是true
  * 4.需要被缓存的数据对象的类型上,需要添加序列化
*/

缓存的执行顺序:二级缓存==》一级缓存==》数据库

1.7. Mapper编写有哪几种方式?
  1. 可以在.xml中配置mapper.xml文件即可(使用此种方法需要编写mapper 接口,mapper 接口实现类、mapper.xml 文件)

    <mappers>
    	<mapper resource="mapper.xml 文件的地址" />
    	<mapper resource="mapper.xml 文件的地址" />
    </mappers>
    
  2. 通过mapper扫描器扫描dao包,注解@MapperScan,或者xml配置:

    <!--映射配置
    namespace:设置命名空间 mapper的唯一id  mybatis会创建一个配置文件对象,并根据namespace设置其id值
    零配置操作需要与dao接口的全限定名一致
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    	<property name="basePackage" value="mapper 接口包地址"></property>
    	<property name="sqlSessionFactoryBeanName"value="sqlSessionFactory"/>
    </bean>
    
  3. 使用org.mybatis.spring.mapper.MapperFactoryBean,此方法即mapper接口开发方法,只需定义mapper接口,不用编写mapper接口实现类。每个mapper接口都需要在spring配置文件中定义。

2. SpringMVC

2.1. SpringMVC的流程?
  1. 发送请求
  2. DispatcherServlet核心控制器(配置映射规则,配置读取spring配置文件,创建spring容器)
  3. handlermapping处理映射器,根据请求的URL匹配对应的处理器(方法)
  4. Controller控制器处理请求,返回给核心控制器一个handler处理对象
  5. 核心控制器传递给HandAdapter处理适配器执行handler,返回ModelAndView给核心控制器
  6. ViewResolver视图解析器解析ModelAndView查找视图(view)资源,并传送Model
  7. 返回页面
2.2. SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?

默认是单例模式,这样每一次访问时就不需要new一个新的控制器,减少内存,但是当多线程访问时,会出现线程安全问题,尽量不要在控制器中定义一个成员变量就可以解决,也可以通过同步代码块解决(会影响性能,不介意使用)

2.3. SpringMVC常用的注解有哪些?

@Controller:标志为控制层

@RestController:相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,不能直接返回一个页面,只能通过ModelAndView封装返回一个页面

@RequestMapping:处理请求地址映射的,支持上下文路径

@ResponseBody:用于将Controller的方法返回的是对象,不是页面

@Autowired:spring容器元素注入

@RequestBody:表示请求体,请求的数据类型是一个对象类型

@RequestParam:根据指定请求数据的key值,获取请求数据

@PathVariable:用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。

2.4. 如何自定义一个视图解析器?
  1. 可以在xml配置文件配置:
   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="prefix" value="/"></property>
       <property name="suffix" value=".jsp"></property>       	
   </bean>
  1. 自定义一个MVC配置类,设置视图解析器规则:
@Bean
       public InternalResourceViewResolver getViewResolver(){
           return new InternalResourceViewResolver("/WEB-INF/html", ".html");
       }
2.5. 在SpringMVC如何添加适配器?
2.6. SpringMVC如何实现多文件上传?
  1. 导入依赖

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
    	<version>1.3.3</version>
    </dependency>
    
  2. xml配置上传文件解析器

    <bean id="multipartResolver"  
    	class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  //命名必须为multipartResolver
    	<property name="defaultEncoding" value="utf-8"></property>   //文件字符集为utf-8
    	<property name="maxUploadSize" value="104857600"></property>  //上传文件大小限制
    </bean>
    
  3. Java配置类配置上传文件解析器

   @Bean("multipartResolver") //bean名必须是multipartResolver
       public CommonsMultipartResolver getMultipartResolver(){
           return new CommonsMultipartResolver();
       }
  1. 前端上传文件是,用MultiFileDomain multiFileDomain接收多个文件,MultiFile接收单个文件
2.7. 如何定义一个拦截器,并让其生效

3. Spring

3.1. Spring的AOP理解

AOP:面向切面编程,可在不改变程序源码的情况下为程序添加额外的功能,从而降低代码之间的耦合度。

3.2. 说说JDK动态代理和CGLIB动态代理
  1. 利用cglib工具包

    目标对象没有实现接口使用CGLIB代理。

  2. 利用 JDK Proxy API

    如果目标对象实现接口,使用JDK代理。

3.3. Spring的IoC理解

IOC:控制反转,就是将代码的调用权从调用方转移给第三方容器

3.4. BeanFactory和ApplicationContext有什么区别?

BeanFactory:是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;

ApplicationContext:应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能(国际化,访问资源,载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,消息发送和响应,AOP拦截器)

两者装载bean的区别:

BeanFactory:BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;

ApplicationContext:ApplicationContext在启动的时候就把所有的Bean全部实例化了。

3.5. 请解释Spring Bean的生命周期?
  1. bean的实例化
  2. 封装属性
  3. 获取bean的名字或实现上下文
  4. 前置处理
  5. 全局初始化
  6. 本类初始化
  7. 后置处理
  8. 业务执行
  9. 销毁
3.6. 解释Spring支持的几种bean的作用域。
  1. singleton,单例模式(可实现懒加载)。
  2. prototype,一个bean的定义可以有多个实例。
  3. request,每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
  4. session,在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
  5. global-session,在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
3.7. Spring框架中的单例Beans是线程安全的吗?

大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。

3.8. Spring如何处理线程并发问题?

在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

3.9. spring的事务传播行为
  1. PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  2. PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  3. PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
  4. PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  6. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
3.10. Spring中的隔离级别
  1. 读未提交(READ_UNCOMMITTED),也称为脏读,就是一个事务可以读取另一个事务未提交的内容
  2. 读已提交(READ_COMMITTED),也称为不可重复读,就是不同的事务重复读了一条记录会出问题。一个事务只可以读取另一个事务提交的内容
  3. 可重复读(REPEATABLE_READ),一个事务在读取了记录之后,这条记录不能再被修改,也就是把这一行记录给锁住,不在允许其它的事物染指此行记录
  4. 串行化(SERIALIZABLE),一个事务必须等待另一个事务执行完成再可以执行
3.11. Spring框架中有哪些不同类型的事件?
  1. 上下文更新事件(ContextRefreshedEvent):该事件会在 ApplicationContext 被初始化或者更新时发布。也可以在调ConfigurableApplicationContext 接口中的 refresh()方法时被触发。

  2. 上下文开始事件(ContextStartedEvent):当容器调用 ConfigurableApplicationContext 的Start()方法开始/重新开始容器时触发该事件。

  3. 上下文停止事件(ContextStoppedEvent):当容器调用 ConfigurableApplicationContext 的Stop()方法停止容器时触发该事件。

  4. 上下文关闭事件(ContextClosedEvent):当 ApplicationContext 被关闭时触发该事件。容器被关闭时,其管理的所有单例 Bean 都被销毁。

  5. 请求处理事件(RequestHandledEvent):在 Web 应用中,当一个 http 请求(request)结束触发该事件。

3.12. 介绍一下AOP相关术语?

切面,通知,连接点,切点,织入

连接点:符合进行切面条件的点或位置

切点:进行切面编程的连接点,和连接点的主要区别在于,连接点只是符合条件的点或位置,而切点是实际上真正进行切面的点。

通知:通知切面什么时候,什么位置进行切面,又分为前置通知,环绕通知,异常通知,后置通知,返回通知五种通知,

前置通知:在方法被调用前执行

环绕通知:在方法被调用前后执行

异常通知:在方法被调用抛出异常时执行

后置通知:在方法被调用后执行

返回通知:目标方法成功执行后调用通知,如果出现异常则不执行

切面:进行切面的内容或插入的逻辑内容

织入:进行切面切入的过程

4.shiro认证器

4.1.说说Shiro授权过程

调用了SecurityManager进行鉴权,使用了认证器进行鉴权,调用Realm自身的getAuthorizationInfo进行授权,再根据自定义的realm鉴权,最后才是鉴权操作。

4.2.Shiro 如何自实现认证

在认证、授权内部实现机制中,最终处理都将交给Real进行处理。因为在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。在应用程序中要做的是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doGetAuthenticationInfo (),重写获取用户信息的方法。而授权实现则与认证实现非常相似,在我们自定义的Realm中,重载doGetAuthorizationInfo()方法,重写获取用户权限的方法。

4.3.如何在spring配置中使用shiro
Subject主体
SecurityManager安全管理器
Authenticator认证器
Authrizer授权器
Realm
SessionManagerSession管理器
CacheManager缓存控制器
Cryptography密码模块
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值