zoukankan      html  css  js  c++  java
  • Java面试题一

    面试官:spring和springboot区别,redis的数据类型,springboot有哪些注解,bean和value注解说一下,数据库的索引和存储过程,MQ,注解读取springboot配置文件

    一.spring和springboot区别:

    答:       spring:其实你说的spring准确来说是指spring framework。spring Framework是一站式的轻量级的java开发框架,核心是控制反转(IoC)和面向切面(AOP),针对于开发的WEB层(springMVC)、业务层(IoC)、持久层(jdbcTemplate)等都提供了多种配置解决方案。

       IOC就是控制权的转移。以前我们对象的依赖都是通过自己创建的,而现在这些都交给了spring容器来管理这些依赖。那么什么是spring容器呢?从宏观的角度来看他就像一个大水桶,而桶里的水就可以把他看作是bean,当然如果从代码角度来看,我们说的就是ApplicationContext

        依赖注入,就是IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

    Spring对bean的管理(注入对象):

    1.xml三种方式:

     2.注解实现:

    创建对象有四个注解

    (1)@Component

    (2)@Controller

    (3)@Service

    (4)@Repository

    目前这四个注解功能是一样的,都创建对象

    spring属性注入方式:

      1.构造注入(带参构造,建议无参也写上) 

    <bean id="person" class="com.cmy.entity.Person">
        <!--constructor-arg:代表构造函数中的一个参数 索引从0开始-->
        <constructor-arg type="java.lang.String" value="VizualProphet"></constructor-arg>
        <constructor-arg type="int" value="16"></constructor-arg>
    </bean>

       2.P命名空间注入

       注意点:也要有set方法,要在配置文件引入  xmlns:p="http://www.springframework.org/schema/p"   aop:xmlns:aop="http://www.springframework.org/schema/aop"

    <bean id="person" class="com.cmy.entity.Person" p:name="VizualProphet" 
          p:age="16">
    </bean>

          3.set注入

        

          4.注解注入

           

    注入复杂类型属性

      AOP就是面向切面。面向切面其实就是对方法增强的一种方式。原理就是通过代理模式遵守开闭原则,实现专心做事的功能!!! (就拿我们的业务来说吧,可能我们做很多的模块开发,都需要日志记录,性能统计,安全控制,事务处理,异常处理等东西,但这些都是交叉业务,我们不应该在这些业务上花费太多的时间,我们更应该关心的是主业务的实现!)

        AOP增强处理类型

    • 前置增强:目标方法调用前
    • 后置增强:目标方法调用后
    • 环绕增强:前置+后置
    • 异常抛出增强:只有在目标方法抛出异常时才执行
    • 最终增强:finally

     AOP术语

      

     多种方式实现AOP

    Ø JDK动态代理是通过接口中的方法名(InvocationHandlerinvoke(Object proxy, Method method, Object[] args)方法),在动态生成的代理类中调用业务实现类的同名方法;

    Ø CGlib动态代理是通过继承业务类 MethodInterceptor  intercept(),不能代理final修饰的类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理;

    Ø 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

    Ø 如果目标对象实现了接口,可以强制使用CGLIB实现AOP

    Ø [aop:config proxy-target-class="true"] 强制切换成CGLIB动态代理

    Ø 如果目标对象没有实现了接口,必须采用CGLIB库,spring自动在JDK动态代理和CGLIB之间转换

     编程式增强 就是不借助spring自己写增强类。

     声明式增强  

        

    顾问包装通知      NameMatchMethodPointcutAdvisor/Regx....Advisor

     

     顾问代理生成器

    • 自动顾问代理生成器:DefaultAdvisorAutoProxyCreator
    • 名称顾问代理生成器:BeanNameAutoProxyCreator

       

     

    <!---自动顾问代理生成器默认为Spring中所有的Bean对象创建代理 无需使用ID注入-->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    </bean>

    环绕增强   

      环绕增强相当于前置增强和后置增强的结合体,使用<aop:around>处理

    <!--将目标对象声明到Spring容器中-->
    <bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
    <!-- 声明增强方法所在的Bean -->
    <bean id="advice" class="com.cmy.around.AroundLogger"></bean>
    <!-- 配置切面 -->
    <aop:config>
       <aop:aspect ref="advice">
          <aop:around method="aroundLogger" pointcut="execution(* com.cmy.*.*.*(..))"/>
       </aop:aspect>
    </aop:config>

    异常抛出增强

      异常增强处理,在目标方法抛出异常后织入;使用<aop:after-throwing>处理

    -*<!--将目标对象声明到Spring容器中-->
    <bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
    <!--将advice声明到容器中-->
    <bean id="advice" class="com.cmy.exception.errorAdvice"></bean>
    <!--声明异常抛出增强-->
    <aop:config>
           <!-- 定义切入点 -->
           <aop:pointcut id="pointcut" expression="execution(* com.cmy.service.*.*(..))" />
           <!-- 引用包含增强方法的Bean -->
           <aop:aspect ref="advice">
                  <!-- 将afterThrowing()方法定义为异常抛出增强并引用pointcut切入点 -->
                  <!-- 通过throwing属性指定为名为e的参数注入异常实例 -->
                  <aop:after-throwing method="afterThrowing"
                                      pointcut-ref="pointcut" throwing="e" />
           </aop:aspect>
    </aop:config>

    最终增强  <aop:after> 类似finally

    <!--将目标对象声明到Spring容器中-->
    <bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
    <!--将advice声明到容器中-->
    <bean id="advice" class="com.cmy.after.AfterLogger"></bean>
    <!--声明异常抛出增强-->
    <aop:config>
           <!-- 定义切入点 -->
           <aop:pointcut id="pointcut" expression="execution(* com.cmy.service.*.*(..))" />
           <!-- 引用包含增强方法的Bean -->
           <aop:aspect ref="advice">
                  <!-- 将afterThrowing()方法定义为异常抛出增强并引用pointcut切入点 -->
                  <!-- 通过throwing属性指定为名为e的参数注入异常实例 -->
                  <aop:after method="afterLogger"
                                      pointcut-ref="pointcut" />
           </aop:aspect>
    </aop:config>

     

    JdbcTemplate+Spring

       来源:为了使 JDBC 更加易于使用,Spring 在 JDBCAPI 上定义了一个抽象层, 以此建立一个JDBC存取框架,Spring Boot Spring Data-JPA。

      缺点:不支持关联映射和属性注入,所以在SQL方向的操作我们仍需使用MyBatis

    JdbcTemplate主要提供以下五类方法:

    1、execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;

           Execute、executeQuery、executeUpdate

    2、update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句 SQL SERVCER(GO SQL语句 GO) ;

    3、query方法及queryForXXX方法:用于执行查询相关语句;

    4、call方法:用于执行存储过程、函数相关语句。 

    Spring事务

       事务:就是作为单个逻辑工作单元执行的一系列操作,要么都执行,要么都不执行,不可分割的逻辑单元。

      事务特性原子性一致性隔离性(并发事务之间相互独立、隔离),持久性(对数据库的修改被永久保持)

    Spring对事务的整合

        在Spring中,所有操作事务的类都继承自 PlatformTransactionManager

      事务隔离级别:       

    • ISOLATION_READ_UNCOMMITTED:读未提交       
    • ISOLATION_READ_COMMITTED:读已提交
    • ISOLATION_REPEATABLE_READ:可重复读 
    • ISOLATION_SERIALIZABLE:串行化

       

     脏读:A事务读取B事务尚未提交的更改数据,并在这个数据的基础上进行操作,这时候如果事务B回滚,那么A事务读到的数据是不被承认的。 

     不可重复读:不可重复读是指A事务读取了B事务已经提交的更改数据。假如A在取款事务的过程中,B往该账户转账100,A两次读取的余额发生不一致。

     幻读:A事务读取B事务提交的新增数据,会引发幻读问题。幻读一般发生在计算统计数据的事务中,例如银行系统在同一个事务中两次统计存款账户的总金额,在两次统计中,刚好新增了一个存款账户,存入了100,这时候两次统计的总金额不一致。

    事务传播行为:

     配置事务的方式:

      1.代理工厂配置事务   org.springframework.transaction.interceptor.TransactionProxyFactoryBean

    <!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!--配置Spring 事务的代理工厂-->
    <bean id="transactionFactory" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="target" ref="accountService"/> 
        <property name="transactionAttributes">
            <props><!--键值 key为具体的方法名 value可以为传播行为或隔离级别-->
                <prop key="transferMoney">ISOLATION_READ_COMMITTED</prop>
            </props>
        </property>
    </bean>

      2.使用aop方式配置事务

    <!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 通知 -->
    <tx:advice transaction-manager="transactionManager" id="txAdvice">
        <tx:attributes>
            <tx:method name="transferMoney" propagation="REQUIRED"
                       isolation="READ_COMMITTED" /><!-- transferMoney的事务隔离级别和传播行为 -->
        </tx:attributes>
    </tx:advice>
    <!-- 切面 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.cmy.service.*.*(..))"
                      id="myCut" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myCut" />
    </aop:config>

    3.使用注解方式配置

    <!--配置Spring的事务管理器,默认在发生异常的情况下回滚,否则提交-->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--开启事务的注解配置-->
    <tx:annotation-driven/>

    @Transactional(isolation=Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED )

    不管如何,以上三种都需要在Application.xml中配置事务管理器

     mybatis-spring 1.3.0

    重点!!!!!配置application.xml

    <!-- 引入属性文件 -->
    <context:property-placeholder location="database.properties"/>
    
    <!--注册DAO层:mapper的代理对象-->
    <bean id="accountDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
       <property name="mapperInterface" value="com.cmy.dao.AccountDao"></property>
       <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>
    <!--配置service层对象-->
    <bean id="accountService" class="com.cmy.service.impl.AccountServiceImpl">
       <property name="dao" ref="accountDao"></property>
    </bean>
    
    <!-- 配置数据源  spring内置的数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="${driver}"></property>
       <property name="url" value="${url}"></property>
       <property name="username" value="${user}"></property>
       <property name="password" value="${password}"></property>
    </bean>
    <!-- sqlSessionFactory 创建SqlSession对象的工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"></property>
          <!-- Mybatis的大配置文件 -->
          <property name="typeAliasesPackage" value="com.cmy.entity"></property>
         <!-- 扫描sql配置文件:mapper需要的xml文件 -->
         <property name="mapperLocations" value="com/cmy/dao/*.xml"/>
    </bean>
    <!-- MapperScannerConfigurer 扫描mapper文件扫描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         <property name="basePackage" value="com.cmy.dao"></property>
    </bean>
    
    <!-- transactionManager 事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 事务通知-->
    <tx:advice transaction-manager="transactionManager" id="txAdvice">
       <tx:attributes>
          <!--get系列方法设置事务的隔离级别和传播行为-->
          <tx:method name="get*" isolation="READ_COMMITTED" propagation="REQUIRED"/>
       </tx:attributes>
    </tx:advice>

    spring+mybatis整合注解的方式

    :只需要开启注解,然后和之前一样 配置上数据源 事务管理器 包扫描器 sqlsession工厂 

    <!--开启Spring IOC和DI的注解支持-->
    <context:component-scan base-package="com.cmy"/>
    
    <context:annotation-config/>
    
    <!--开启注解对声明式事务的注解支持-->
    <tx:annotation-driven/>

    然后使用对应的注解完成实现

    spring 配置补充

    <!-- 引入属性文件 -->
    <context:property-placeholder location="database.properties"/>
    
    <!---引入多个属性文件->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" value="classpath:database.properties"></property>
    </bean>
    
    <!--在spring中配置JNDI数据源-->
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
       <!--通过jndiName指定引用的JNDI数据源名称 -->
       <property name="jndiName">
          <value>java:comp/env/jdbc/mysql</value>
       </property>
    </bean>

    SpringBean的作用域

     Spring的自动装配

    部署模式:Tomcat + WAR包 不能随JAVAEE容器启动而装载,所以出现了boot!


                 springboot:可以看作是sring框架的扩展,没有了之前的大量xml配置,更高效节省时间。application.yml或者.propterties 更方便

                                      spring-boot-starter-web为我们提供了嵌入的Tomcat以及Spring MVC的依赖 springframework.
              还提供了第三包 如redis mongdob等 ,再比如test直接包含了springtest,junit,等库!
              boot还会它会自动扫描同一个包中的所有类或Main类的子包中的组件
              在Spring Boot中默认支持的模板引擎是Thymeleaf(spring-boot-starter-thymeleaf),因为内嵌的web容器不支持以jar的形式运行jsp
          部署模式: 使用命令java -jar独立运行jar

    总结:pring Boot只是Spring本身的扩展,使开发,测试和部署更加方便

    二.springboot有哪些注解?注解读取springboot配置文件?

    注解读取springboot配置文件:

    @ConfigurationProperties(prefix = "person")
    @PropertySource("classpath:person.properties") 

    springboot的注解:

    springboot中除了包含之前的springspringmvc的注解,他还有多自己的注解!如:

    @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中

    @ComponentScan:让spring Boot扫描到Configuration类并把它加入到程序上下文。

    @Configuration :等同于spring的XML配置文件;使用Java代码可以检查类型安全。

    @EnableAutoConfiguration :自动配置。

    @ComponentScan :组件扫描,可自动发现和装配一些Bean。

    @Component:可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

    @RestController:注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

    @Autowired:自动导入。

    @PathVariable:获取参数。

    @JsonBackReference:解决嵌套外链问题。

    @RepositoryRestResourcepublic:配合spring-boot-starter-data-rest使用。

    spingboot注解详细总结:https://blog.csdn.net/weixin_40753536/article/details/81285046

    mvc和spring注解:https://www.cnblogs.com/caijh/p/7744604.html

    3.redis数据类型:

    String key-value get set del
    List(列表) 可以存储相同字符串 在3.2版本之前,列表是使用ziplist和linkedlist实现的 3.2版本之后,重新引入了一个quicklist的数据结构,列表的底层都是由quicklist实现的,它结合了ziplist和linkedlist的优点
    hash 键值对 hash底层的数据结构实现有两种ziplist和hashtable
    Set(集合) 存储不同字符串 无序的 intset有序
    zset(有序集合) 键值对 key:member(成员) value:score(分值)

    redis应用场景:    1.缓存会话(单点登陆)   

              2.分布式锁(setnx)

              3.排行榜或计数器

              4.商品列表或用户基础数据列表

              5.使用list作为消息队列

              6.秒杀。库存扣减

    五种类型应用场景:
      String:计数器,统计在线人数。存储图片 视频
      hash:键值对--用户信息 商品信息等。hash数据的底层ziplist比较节约内存,可以分段存储。如商品图片地址,商品编码固定10位,取前7位作为key,后三位作为field,图片地址作为value,
        这样每个hash表都不超过999个,只要把redis.conf中的hash-max-ziplist-entries改为1024,即可。
      list:列表类型,可以用于实现消息队列,也可以使用它提供的range命令,做分页查询功能。
      set:集合,整数的有序列表可以直接使用set。可以用作某些去重功能,例如用户名不能重复等,另外,还可以对集合进行交集,并集操作,来查找某些元素的共同点
      zset:有序集合,可以使用范围查找,排行榜功能或者topN功能。

    4.数据库的索引和存储过程

    5.mq知道吗?

    Message Queue
    能干啥?:解耦、异步、削峰
    有哪些mq?RocketMQ    RabbitMQ   ActiveMQ    Kafka
          其实redis也可以当做一个轻量级的队列服务来使用 入队时不大于10k时,Redis的性能很高。出队,性能更好比rb强多了。

    https://blog.csdn.net/u014590757/article/details/79602309

     

          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

  • 相关阅读:
    10、代码块、构造代码块、静态代码块及main方法之间的关系
    2.0、Hibernate框架的简单搭建
    1.0、Struts2的简单搭建方法
    5、Servlet的使用
    angular组件之间的通信
    angular项目中遇到的问题
    ng-zorro-mobile中遇到的问题
    angular管道操作符的使用
    angular路由配置以及使用
    搭建Angular环境
  • 原文地址:https://www.cnblogs.com/jiayiblog/p/11455149.html
Copyright © 2011-2022 走看看