A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小鲁哥哥 于 2021-7-21 17:18 编辑

框架


1. Mybatis框架              1.1 谈一谈你对Mybatis框架的理解(了解)
       MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

       1.2 在mybatis中,${} 和 #{} 的区别是什么?(必会)

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


       1.3 MyBatis编程步骤是什么样的?(了解)

         1、 创建SqlSessionFactory
         2、 通过SqlSessionFactory创建SqlSession
         3、 通过sqlsession执行数据库操作
         4、 调用session.commit()提交事务
         5、 调用session.close()关闭会话

       1.4 在mybatis中,resultType和ResultMap的区别是什么?(必会)

        如果数据库结果集中的列名和要封装实体的属性名完全一致的话用 resultType 属性
        如果数据库结果集中的列名和要封装实体的属性名有不一致的情况用 resultMap 属性,通过resultMap手动建立对象关系映射,resultMap要配置一下表和类的一一对应关系,所以说就算你的字段名和你的实体类的属性名不一样也没关系,都会给你映射出来


        1.5 在Mybatis中你知道的动态SQL的标签有哪些? 作用分别是什么?(必会)

          1. <if>if是为了判断传入的值是否符合某种规则,比如是否不为空.
          2. <where> where标签可以用来做动态拼接查询条件,当和if标签配合的时候,不用显示的声明类型where 1 = 1这种无用的条件
          3. <foreach> foreach标签可以把传入的集合对象进行遍历,然后把每一项的内容作为参数传到sql语句中.
          4. <include> include可以把大量的重复代码整理起来,当使用的时候直接include即可,减少重复代码的编写;
          5. <set>适用于更新中,当匹配某个条件后,才会对该字段进行跟新操作


       1.6 谈一下你对mybatis缓存机制的理解?(了解)

       Mybatis有两级缓存一级缓存是SqlSession级别的,默认开启,无法关闭;
                                          二级缓存是Mapper级别的,二级缓存默认是没有开启的,但是手动开启
       1. 一级缓存:基础PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session flush或close之后,Session中的所有Cache就将清空
       2. 二级缓存其存储作用域为Mapper(Namespace),使用二级缓存属性类需要实现Serializable序列化接口
       3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了C(增加)/U(更新)/D(删除)操作后,默认该作用域下所有select中的缓存将被clear.
       需要在setting全局参数中配置开启二级缓存,如下conf.xml配置:
file:///C:\Users\谁动了~1\AppData\Local\Temp\ksohtml752\wps17.jpg
       当我们的配置文件配置了cacheEnabled=true时,就会开启二级缓存,二级缓存是mapper级别的,如果你配置了二级缓存,那么查询数据的顺序应该为:二级缓存→一级缓存→数据库。


2. Spring框架

       2.1 Spring的两大核心是什么?谈一谈你对IOC的理解? 谈一谈你对DI的理解? 谈一谈你对AOP的理解?(必会)
        1. Spring的两大核心是:IOC(控制反转)和AOP(面向切面编程) DI(依赖注入)
        2. IOC的意思是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。最直观的表达就是,IOC让对象的创建不用去new了,可以由spring根据我们提供的配置文件自动生产,我们需要对象的时候,直接从Spring容器中获取即可.
        Spring的配置文件中配置了类的字节码位置及信息, 容器生成的时候加载配置文件识别字节码信息, 通过反射创建类的对象.
Spring的IOC有三种注入方式 :构造器注入, setter方法注入, 根据注解注入。
        3. DI的意思是依赖注入,和控制反转是同一个概念的不同角度的描述,即应用程序在运行时依赖Io c容器来动态注入对象需要的外部资源。
        4. AOP,一般称为面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect). SpringAOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
        5. Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理
          (1)JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler 接口和 Proxy 类,InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起,Proxy 利用 InvocationHandler 动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
          (2) 如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。


        2.2 Spring的生命周期?(高薪常问)

      1. 实例化一个Bean,也就是我们通常说的new
      2. 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
      3. 如果这个Bean实现dao了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID
      4. 如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean)
      5. 如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法
      6. 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术
      7. 如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法
      8. 如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法
注意:以上工作完成以后就可以用这个Bean了,那这个Bean是一个single的,所以一般情况下我们调用同一个ID的Bean会是在内容地址相同的实例
      9. 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法
     10. 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法


      2.3 Spring支持bean的作用域有几种吗? 每种作用域是什么样的?(必会)

      Spring支持如下5种作用域:
     (1)singleton:默认作用域,单例bean,每个容器中只有一个bean的实例。
     (2)prototype:每次请求都会为bean创建实例。
     (3)request:为每一个request请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
     (4)session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例。
     (5)global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享的存储变量的话,那么这全局变量需要存储在global-session中。


     2.4 BeanFactory和ApplicationContext有什么区别(了解)

       BeanFactory:
            Spring最顶层的接口,实现了Spring容器的最基础的一些功能, 调用起来比较麻烦, 一般面向Spring自身使用
            BeanFactory在启动的时候不会去实例化Bean,从容器中拿Bean的时候才会去实例化
       ApplicationContext
            是BeanFactory的子接口,扩展了其功能, 一般面向程序员身使用
            ApplicationContext在启动的时候就把所有的Bean全部实例化了


      2.5 Spring框架中都用到了哪些设计模式?(必会)

       1. 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例
       2. 单例模式:Bean默认为单例模式
       3. 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
       4. 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
       5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener


       2.6 Spring事务的实现方式和实现原理(必会)

        Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
        spring事务实现主要有两种方法
        1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法
        2、声明式,利用注解Transactional 或者aop配置


       2.7 你知道的Spring的通知类型有哪些,分别在什么时候执行?(了解)

        Spring的通知类型有四种,分别为:
        前置通知[before]:在切点运行之前执行
        后置通知[after-returning]:在切点正常结束之后执行
        异常通知[after-throwing]:在切点发生异常的时候执行
        最终通知[after]:在切点的最终执行
         Spring还有一种特殊的通知,叫做环绕通知
        环绕通知运行程序员以编码的方式自己定义通知的位置, 用于解决其他通知时序问题


       2.8 Spring的对象默认是单例的还是多例的? 单例bean存不存在线程安全问题呢?(必会)

         1. 在spring中的对象默认是单例的,但是也可以配置为多例。
         2. 单例bean对象对应的类存在可变的成员变量并且其中存在改变这个变量的线程时,多线程操作该bean对象时会出现线程安全问题。
            原因是:多线程操作如果改变成员变量,其他线程无法访问该bean对象,造成数据混乱。
            解决办法:在bean对象中避免定义可变成员变量;
            在bean对象中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中。


       2.9 @Resource和@Autowired依赖注入的区别是什么? @Qualifier使用场景是什么?(了解)

        @Resource
         只能放在属性上,表示先按照属性名匹配IOC容器中对象id给属性注入值若没有成功,会继续根据当前属性的类型匹配IOC容器中同类型对象来注入值。
         若指定了name属性@Resource(name = "对象id"),则只能按照对象id注入值。
         @Autowird
         放在属性上:表示先按照类型给属性注入值如果IOC容器中存在多个与属性同类型的对象,则会按照属性名注入值
         也可以配合@Qualifier("IOC容器中对象id")注解直接按照名称注入值。
         放在方法上:表示自动执行当前方法,如果方法有参数,会自动从IOC容器中寻找同类型的对象给参数传值
         也可以在参数上添加@Qualifier("IOC容器中对象id")注解按照名称寻找对象给参数传值。        
         @Qualifier使用场景:
         @Qualifier("IOC容器中对象id")可以配合@Autowird一起使用, 表示根据指定的id在Spring容器中匹配对象


        2.10 Spring的常用注解(必会)

        1. @Component(任何层)  @Controller  @Service  @Repository(dao): 用于实例化对象
        2. @Scope : 设置Spring对象的作用域
        3. @PostConstruct @PreDestroy : 用于设置Spring创建对象在对象创建之后和销毁之前要执行的方法
        4. @Value: 简单属性的依赖注入
        5. @Autowired: 对象属性的依赖注入
        6. @Qualifier: 要和@Autowired联合使用,代表在按照类型匹配的基础上,再按照名称匹配。
        7. @Resource 按照属性名称依赖注入
        8. @ComponentScan: 组件扫描
        9. @Bean: 表在方法上,用于将方法的返回值对象放入容器
       10. @PropertySource: 用于引入其它的properties配置文件
       11. @Import: 在一个配置类中导入其它配置类的内容
       12. @Configuration: 被此注解标注的类,会被Spring认为是配置类。Spring在启动的时候会自动扫描并加载所有配置类,然后将配置        类中bean放入容器
       13. @Transactional 此注解可以标在类上,也可以表在方法上,表示当前类中的方法具有事务管理功能。


        2.11 Spring的事务传播行为(高薪常问)

        spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。
备注(方便记忆): propagation传播
       require必须的/suppor支持/mandatory 强制托管/requires-new 需要新建/     not -supported不支持/never从不/nested嵌套的
       ① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
       ② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
       ③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
       ④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
       ⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
       ⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
       ⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。


       2.12 Spring中的隔离级别 (高薪常问)

       ISOLATION隔离的意思
       ① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
       ② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个事务未提交的数据。
       ③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。解决脏读问题
       ④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。行锁
       ⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。


      3. SpringMVC框架

       3.1 谈一下你对SpringMVC框架的理解(了解)
       SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
       在我看来,SpringMVC就是将我们原来开发在servlet中的代码拆分了,一部分由SpringMVC完成,一部分由我们自己完成


       3.2 SpringMVC主要组件(必会)

       前端控制器 DispatcherServlet:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
       处理器映射器 HandlerMapping:根据请求的URL来查找Handler
       处理器适配器 HandlerAdapter:负责执行Handler
       处理器 Handler:处理业务逻辑的Java类
       视图解析器 ViewResolver:进行视图的解析,根据视图逻辑名将ModelAndView解析成真正的视图(view)
       视图View:View是一个接口, 它的实现类支持不同的视图类型,如jsp,freemarker,pdf等等

        3.3 谈一下SpringMVC的执行流程以及各个组件的作用(必会)file:///C:\Users\谁动了~1\AppData\Local\Temp\ksohtml752\wps18.jpg
        1. 用户发送请求到前端控制器(DispatcherServlet)
        2. 前端控制器(DispatcherServlet)收到请求调用处理器映射器(HandlerMapping),去查找处理器(Handler)
        3. 处理器映射器(HandlerMapping)找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
        4. 前端控制器(DispatcherServlet)调用处理器映射器(HandlerMapping)
        5. 处理器适配器(HandlerAdapter)去调用自定义的处理器类(Controller,也叫后端控制器)。
        6. 自定义的处理器类(Controller,也叫后端控制器)将得到的参数进行处理并返回结果给处理器映射器(HandlerMapping)
        7. 处理器适配器(HandlerAdapter)将得到的结果返回给前端控制器(DispatcherServlet)
        8. DispatcherServlet(前端控制器)将ModelAndView传给视图解析器(ViewReslover)
        9. 视图解析器(ViewReslover)将得到的参数从逻辑视图转换为物理视图并返回给前端控制器(DispatcherServlet)
       10. 前端控制器(DispatcherServlet)调用物理视图进行渲染并返回
       11. 前端控制器(DispatcherServlet)将渲染后的结果返回


       3.4 说一下SpringMVC支持的转发和重定向的写法(必会)

         1)转发:
              forward方式:在返回值前面加"forward:",比如"”"forward:user.do?name=method4"
         2)  重定向:
              redirect方式:在返回值前面加redirect:, 比如"redirect:http://www.baidu.com"


         3.5 SpringMVC的常用注解(必会)

          1.@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
          2.@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
          3.@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。
          4.@PathVariable 用户从url路径上获取指定参数,标注在参数前 @PathVariabel("要获取的参数名")。
          5.@RequestParam: 标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:
              - value:默认属性,用于指定前端传入的参数名称
              - required:用于指定此参数是否必传
              - defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值

          6. @ControllerAdvice 标注在一个类上,表示该类是一个全局异常处理的类。
          7. @ExceptionHandler(Exception.class) 标注在异常处理类中的方法上,表示该方法可以处理的异常类型。


         3.6  谈一下SpringMVC统一异常处理的思想和实现方式(必会)

           使用SpringMVC之后,代码的调用者是SpringMVC框架,也就是说最终的异常会抛到框架中,然后由框架指定异常处理类进行统一处理
          方式一: 创建一个自定义异常处理器(实现HandlerExceptionResolver接口),并实现里面的异常处理方法,然后将这个类交给Spring容器管理
          方式二: 在类上加注解(@ControllerAdvice)表明这是一个全局异常处理类
          在方法上加注解(@ExceptionHandler),在ExceptionHandler中有一个value属性,可以指定可以处理的异常类型


         3.7  在SpringMVC中, 如果想通过转发将数据传递到前台,有几种写法?(必会)

         方式一:直接使用request域进行数据的传递   
        request.setAttirbuate("name", value);
         方式二:使用Model进行传值,底层会将数据放入request域进行数据的传递
        model.addAttribuate("name", value);
        方式三:使用ModelMap进行传值,底层会将数据放入request域进行数据的传递
        modelmap.put("name",value);
        方式四:借用ModelAndView在其中设置数据和视图
        mv.addObject("name",value);
        mv.setView("success");
        return mv;


       3.8  在SpringMVC中拦截器的使用步骤是什么样的?(必会)

       1 定义拦截器类:
        SpringMVC为我们提供了拦截器规范的接口,创建一个类实现HandlerInterceptor,重写接口中的抽象方法;
                preHandle方法:在调用处理器之前调用该方法,如果该方法返回true则请求继续向下进行,否则请求不会继续向下进行,处理器也不会调用
                postHandle方法:在调用完处理器后调用该方法
                afterCompletion方法:在前端控制器渲染页面完成之后调用此方法               
       2 注册拦截器:
        在SpringMVC核心配置文件中注册自定义的拦截器
        <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="拦截路径规则"/>
                <mvc:exclude-mapping path="不拦截路径规则"/>
                <bean class="自定义拦截器的类全限定名"/>
            </mvc:interceptor>
        </mvc:interceptors>


       3.9 在SpringMVC中文件上传的使用步骤是什么样的? 前台三要素是什么?(必会)

       文件上传步骤:
        1.加入文件上传需要的commons-fileupload包
        2.配置文件上传解析器,SpringMVC的配置文件的文件上传解析器的id属性必须为multipartResolver
        3.后端对应的接收文件的方法参数类型必须为MultipartFile,参数名称必须与前端的name属性保持一致
       文件上传前端三要素:
        1.form表单的提交方式必须为post
        2.enctype属性需要修改为:multipart/form-data
        3.必须有一个type属性为file的input标签,其中需要有一个name属性;如果需要上传多个文件需要添加multiple属性


       3.10 SpringMVC 中如何解决GET|POST请求中文乱码问题?(了解)

     (1)解决post请求乱码问题:在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;
[AppleScript] 纯文本查看 复制代码
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

       (2) get请求中文参数出现乱码解决方法有两个:
         ①修改tomcat配置文件添加编码与工程编码一致,如下:
       <ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
         ②另外一种方法对参数进行重新编码:
        String userName= new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
        ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。


1 个回复

倒序浏览
您需要登录后才可以回帖 登录 | 加入黑马