SSM面试题

框架面试题

一、Mybatis

1、谈谈你对框架的理解,框架有什么好处?

1、啥是框架
  框架就是一个架子,表演节目,舞台已经搭建好,表演什么节目,看自己的需求了。
  框架是一个半成品,对于Java语言来说,框架就是封装了别人的代码。在框架的基础上我们在进一步开发,拿来主义。(你想啊,在二阶段我们都手动去用request.getParameter()获取参数、在dao手动去写sql,不管啥业务,这些东西都是一样的,框架就将这些给你封装好啦)
2、解决的问题
	解决的是技术整合问题。软件开发环境和规模都很大,不可能任何一个项目的代码都从零开始,此时就需要一个非常优秀的框架把基础技术整合完毕,我们在他的基础上进一步开发。提高性能,易扩展,易维护,最终提高整个团队的开发效率
3、怎么用框架呢?
  (1) 导入相关坐标(jar包)
  (2) 框架运行细节定义,编写配置文件(每个框架都有自己的配置文件呀)
  (3) 调用框架中的API

2、Mybatis框架的好处

1、原先使用jdbc时
   每次CRUD都要写那六大步骤,太冗余了吧
而且:
  (1)频繁连接,释放数据库资源,降低系统性能
  (2)SQL语句硬编码,难以维护(sql都写到.java里了)
  (3)参数和占位符对应问题
  (4)结果集解析复杂,列名硬编码
2、mybatis框架
   是一个very优秀的持久层(dao)框架,对JDBC进行了封装,使得开发者只需要关注Sql语句(业务)本身即可,无需开发者处理加载驱动、获取连接、创建Statement等繁琐的过程。
   实现了ORM思想

3、如何理解ORM思想呢?

对象关系映射

    将数据库中的关系数据表映射为JAVA中的对象,把对数据表的操作转换为对对象的操作,实现面向对象编程。因此ORM的目的是使得开发人员以面向对象的思想来操作数据库。
    Mybatis框架是一个半自动的ORM持久层框架,也可以在Java中实现类似 insert(User)的操作最终操作数据库,但是需要我们自己写Sql语句。Mybatis是目前比较流行的Dao层框架。

4、Mybatis的编程步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FzpbauxZ-1639100484220)(img/2.png)]

//1、加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2、创建构建器  
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3、构建SqlSession工厂
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
//4、生产SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//5、执行业务
 User user = sqlSession.selectOne("test.queryUserById",2);
    System.out.println(user);
//6、释放资源
 sqlSession.close();

5、#{} 和 ${} 的区别

 1. #{}是预编译处理,${}是字符串替换。
 2. Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
 3. Mybatis在处理${}时,就是把${}替换成变量的值,相当于字符串拼接
 4. 使用#{}可以有效的防止SQL注入,提高系统安全性。

6、动态代理开发方式的好处以及规范是什么

   定义一个Mapper接口,这个接口其实和我们UserDao接口是一样的,从Mybatis框架中拿到一个代理对象(代理的是这个Mapper接口),通过代理对象调用接口当中的方法完成业务。

四大规范:
1、sql映射文件的namespace必须和mapper接口的全限定类名保持一致
2、mapper接口的接口方法名必须和xml中的sql语句id保持一致
3、mapper接口的接口方法形参类型必须和sql语句的输入参数类型保持一致
4、mapper接口的接口方法返回类型必须和sql语句的resultType保持一致

7、mybatis的配置文件有哪些?作用是啥

  • SqlMapperConfig.xml

    主配置文件

1、enviroments配置数据源环境:
	数据源、事务管理器的配置
2、全局typeAliases配置:
	别名配置
3、mappers:加载指定的配置文件
    <mappers>
        <mapper resource="mapper/UserMapper.xml" />
        <mapper class="com.ujiuye.mapper.UserMapper"></mapper>
        <package name="com.ujiuye.mapper"></package>
    </mappers>	
  • 写sql的配置文件

    比如:
     <select>、<update>、<insert>、<delete>
    

8、MyBatis应用动态SQL解决了什么问题?

	有时候,固定的sql语句不能够满足我们的应用需求。这个时候需要在 标准的基础上建立动态的查询语句。
Mybatis提供了多种注解,可以提供动态查询语言。
	比如说在开发的时候,遇到这样的场景,界面提供了多种查询,但是都是非必填写,在选择查询条件时可以选中任意几种组合作为查询条件,如果在使用jdbc的时候,需要判断参数为空,自己组装sql,但是mybatis提供动态sql机制,依靠标签。
	
应用场景:
	比如模块的多条件查询时

9、Mybatis的缓存

缓存作用:提升查询效率

1.mybatis 一级缓存是 SqlSession 级别的缓存,默认支持一级缓存,不需要在配置文件去配 置。
2.mybaits 的二级缓存是 mapper 范围级别,除了在 SqlMapConfig.xml 设置二级缓存的总开关 <settingname='cacheEnabled'value='true'/>,还要在具体的 mapper.xml 中开启二级缓存:<mappernamespace='cn.hpu.mybatis.mapper.UserMapper'>

10、Mybatis如何处理多对多关系?举一个多对多的例子

	比如说学生表和课程表,一个学生可以选择多门课程, 一门课程都能被多个学生选择,这 样两张表的关系就是多对多的关系, 怎么处理多对多的情况? 遇到这种情况我们得创建一 张中间的桥表,关联后就是 课程表对桥表就是一对多,学生表对桥表也是一对多,就可以了

11、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

(1)Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

(2)它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

12、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。

第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。

13、Mybatis都有哪些Executor执行器?它们之间的区别是什么?

Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。
1.SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
2.ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。
3.BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

二、Spring

1、你觉得Spring框架有什么优势?

  • 方便解耦,简化开发

    通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
    UserService{
        //硬编码
        private UserDao userDao = new UserDaoImpl();
    }
    
  • AOP编程的支持

通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付
  • 声明式事务的支持

    可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
    
  • 方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
  • 方便集成各种优秀框架
Spring 可以降低各种框架的使用难度,提供了对各种优秀框架( Struts、 Hibernate、 Hessian、 Quartz
等)的直接支持。
  • 降低 JavaEE API 的使用难度
Spring 对 JavaEE API(如 JDBC、 JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。
  • Java 源码是经典学习范例
Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。 

2、如何理解Spring的IOC思想

1、想了解IOC,先看下该概念
解耦合
软件设计原则:高内聚,低耦合
内聚:一个模块内各个元素彼此结合的紧密程度,描述的是模块内的功能联系
耦合:是软件结构中各模块之间相互连接的一种度量
简而言之:
	高内聚,低耦合,其实就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却不要那么紧密
2、IOC
全称是Inversion Of Control,意为控制反转,不是一个技术,而是一种思想
其作用是用于削减代码间的耦合。它的实现思想就是利用了工厂设计模式,把创建对象代码从具体类中剥离出去,交由工厂来完成,从而降低代码间的依赖关系。

作用:
	它是用于降低我们代码间的依赖关系,削减程序中的耦合。

3、如何理解Spring中的依赖注入(DI)

1、什么是依赖注入
	就是让spring框架给Bean对象的属性进行赋值. 它是 spring 框架核心 ioc 的具体实现
	我们的程序在编写时, 通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。ioc 解耦只是降低他们的依赖关系,但不会消除。 例如:我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系, 在使用 spring 之后, 就让 spring 来维护了。
	简单的说,依赖注入(DI)就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
2、依赖注入的几种方式
(1)使用构造函数方式注入
(2)使用set方法方式注入   p名称空间
(3)静态工厂的方法注入
(4)实例工厂的方法注入

4、Spring框架的常用注解有哪些?

1、@Component :将普通pojo实例化到spring容器中,相当于配置文件中的
<bean id=""  class="">
以及三个衍生注解
   @Controller:控制器层用
   @Service:服务层用
   @Repository:dao层用
2、依赖注入注解
   @Autowired注解:按类型注入
   @Qualifier("id") 注解  按照id注入
   @Resource注解
3、@Configuration标识当前类是Spring的一个配置类
	@ComponentScan替代xml中的`<context:component-scan/>`
	@Import引入其他配置类,被引入的配置类可以不加@Configuration注解     @PropertySource:引入外部properties文件,注意加classpath:
@Value对成员变量赋值
@Bean将一个方法的返回值对象加入到Spring的容器当中管理
@Qualifier可以使用在方法参数上,表明对应的形参引入/注入的对象类型

5、你们公司使用SSM框架采用的注解方式还是XML方式开发?

企业主流的开发方式:半注解半xml开发

往往第三方jar中的对象我们使用xml配置(比如druid数据库连接池、Mybatis的SQLSessionFactory),类似于service层和dao层的实现类,这属于我们自己写的代码,往往会使用注解,这就是半xml半注解的模式

6、你对Spring的AOP如何理解?

1、AOP:面向切面编程
	它是一种编程思想,一种设计理念,是OOP的一种延续。运用AOP编程思想,可以提高代码的可重用性,使编码更加简洁,更易于维护。
	简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
2、应用场景:事务和日志、统计方法执行效率

7、简述一下Spring支持的事物管理有哪些?

1.声明式事务管理:设置配置文件与先前比照简化了许多。我们把这类设置配置文件格式称为 Spring 经典的声明式事务治理。 
2.编程式事务管理:为了不损坏代码原有的条理性,避免出现每一个方法中都包括相同的启动事物、提交、回滚事物样板代码的现象,spring 提供了 transactionTemplate 模板来实现编程式事务管理。这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。
3.区别
   (1)编程式事务是自己写事务处理的类,然后调用。
   (2)声明式事务是在配置文件中配置,一般搭配在框架里面使用。

8、事物的四大特性有哪些(ACID)?

1.原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
2.一致性:执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
3.隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
4.持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

9、Spring的事物管理机制实现原理?

Spring的事务管理机制实现的原理,就是通过这样一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的 方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。Spring中的AOP实 现更为复杂和灵活,不过基本原理是一致的。

10、请解释Spring Bean的生命周期?

1.Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。
2.Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
初始化之后调用的回调方法。
销毁之前调用的回调方法。
Spring框架提供了以下四种方式来管理bean的生命周期事件:
         (1)InitializingBean和DisposableBean回调接口
         (2)针对特殊行为的其他Aware接口
         (3)Bean配置文件中的Custom init()方法和destroy()方法w
         (4)@PostConstruct和@PreDestroy注解方式
         
 实例化 Instantiation
属性赋值 Populate
初始化 Initialization
销毁 Destruction        

11、Spring 中@Autowired 和@Resource 的区别

1.@Autowired 默认的是按照类型进行注入, 如果没有类型会按照名称进行注入. 如果想直接按照名称注入需要加入@Qualifier("gatheringDao") 
@Autowired
@Qualifier("gatheringDao")
private GatheringDao gatheringDao; 
2.@Resource 默认的会按照名称注入,名称找不着会按照类型来找,如果这里写了名称,就直接 按照名称找了不会按类型找@Resource(name = "aaa") @Resource
private GatheringDao gatheringDao;

12、Spring 中用到了那些设计模式?

Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:
1.代理模式—在AOP和remoting中被用的比较多。
2.单例模式—在spring配置文件中定义的bean默认为单例模式。
3.模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
4.工厂模式—BeanFactory用来创建对象的实例。
适配器–spring aop
装饰器–spring data hashmapper
观察者– spring 时间驱动模型
回调–Spring ResourceLoaderAware回调接口

13、Spring 如何保证 Controller 并发的安全

Spring 多线程请求过来调用的Controller对象都是一个,而不是一个请求过来就创建一个Controller对象。

并发的安全? 原因就在于Controller对象是单例的,那么如果不小心在类中定义了类变量,那么这个类变量是被所有请求共享的,这可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常

那有没有办法让Controller不以单例而以每次请求都重新创建的形式存在呢?

答案是当然可以,只需要在类上添加注解@Scope(“prototype”)即可,这样每次请求调用的类都是重新生成的(每次生成会影响效率)

虽然这样可以解决问题,但增加了时间成本,总让人不爽,还有其他方法么?答案是肯定的!

使用ThreadLocal来保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来

14、什么是基于Java的Spring注解配置? 给一些注解的例子?

基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。

以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。

15、Spring如何解决循环依赖问题

spring提供的两种注入方式,构造注入和setter,那其实构造注入时如果发现循环依赖会直接初始化容器失败,setter注入是采用三级缓存,发现循环依赖会有一个半初始化状态进行流转。
1.架构问题,优先架构重构
2.@lazy懒加载
3.不用构造器注入改用set,Spring已经帮忙解决

16、Spring如何处理线程并发问题?

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

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

三、SpringMvc

1、简单描述一下你对SpringMVC的理解

 SpringMVC是一个轻量级的Web表现层框架,用来写Controller接收请求跳转页面的,它是Spring框架的一部分。SpringMVC是对Servlet的封装和增强,简化了servlet的操作。它已经超越了Struts2,成为目前最优秀的表现层框架。
1、本质
 web表现层的一个框架,主要用来接收请求、转发请求、跳转页面
2、优势
   操作特简单,性能特别高,灵活性特别强

2、描述springmvc的处理流程吧

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Nh8YjAr-1639100484225)(img/1.png)]

- 第一步:用户发送请求至前端控制器DispatcherServlet
- 第二步:DispatcherServlet收到请求调用HandlerMapping处理器映射器
- 第三步:处理器映射器根据请求Url找到,具体的Handler(后端控制器),生成处理器对象及处理器拦截器(如果有则生成)一并返回DispatcherServlet
- 第四步:DispatcherServlet调用HandlerAdapter处理器适配器去调用Handler
- 第五步:处理器适配器执行Handler
- 第六步:Handler执行完成给处理器适配器返回ModelAndView
- 第七步:处理器适配器向前端控制器返回 ModelAndView,ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View
- 第八步:前端控制器请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图。
- 第九步:视图解析器向前端控制器返回View
- 第十步:前端控制器进行视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域
- 第十一步:前端控制器向用户响应结果

3、介绍一下SpringMvc中的组件以及作用

1、DispatcherServlet:前端控制器
	接收用户请求,响应结果,相当于中央处理器,DispatcherServlet是整个流程控制的中心,由它调用其它组件完成用户请求的处理。DispatcherServlet的存在降低了组件之间的耦合性
2、HandlerMapping:处理器映射器
	理解为一个Map<url,Hanlder>,HandlerMapping负责根据用户请求的Url找到Handler即处理器,SpringMVC提供了不同的映射器来实现不同的映射方式,例如:实现接口方式,注解方式等。
3、Handler:处理器
	在SpringMVC当中有两层意思:Controller或者Controller当中的方法,Handler相对于前端控制器DispatcherServlet来说是后端控制器,执行具体业务处理的,它在DispatcherServlet的控制下处理用户的具体请求。
4、HandlAdapter:处理器适配器
	不同的接口类型转换成usb,体现了万物归一的思想,通过HandlerAdapter对Handler处理器进行执行,这是适配器模式的应用
5、ViewResolver:视图解析器
	ViewResolver进行视图解析,首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象。

4、SpringMVC 的 controller 里可不可以写成员变量?

可以写啊,注入的 service 不就是成员变量么,你是不想问 struts2 里的获取参数的方式啊? Struts2 早就不用了,他那种用成员变量获取参数的方式,在高并发下会造成线程不安全, springmvc 是使用的形参接收前台数据的,线程比较安全。

5、如何开启注解处理器和适配器?

我们在项目中一般会在 springmvc.xml 中通过开启 <mvc:annotation-driven> 来实现注解处理器和适配器的开启.

6、SpringMVC如何与Ajax相互调用

通过Jackson框架把Java对象转换成js可以识别的json对象

步骤:
1、加入Jackson.jar
2、配置json的映射
3、在接收Ajax方法里直接返回Object、List等,方法前要加@RequestBody注解

7、简述web.xml的作用?

web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的。 
web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。
当你的web工程没用到这些时,你可以不用web.xml文件来配置你的Application。

注解处理器和适配器?

我们在项目中一般会在 springmvc.xml 中通过开启 <mvc:annotation-driven> 来实现注解处理器和适配器的开启.

6、SpringMVC如何与Ajax相互调用

通过Jackson框架把Java对象转换成js可以识别的json对象

步骤:
1、加入Jackson.jar
2、配置json的映射
3、在接收Ajax方法里直接返回Object、List等,方法前要加@RequestBody注解

7、简述web.xml的作用?

web中可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的。 
web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。
当你的web工程没用到这些时,你可以不用web.xml文件来配置你的Application。
  • 6
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值