面试准备

1. Spring框架

1) spring框架的好处是什么?

答:

首先spring比较轻量,基本上只有几mb,

第二是spring通过控制反转IOC实现了松散耦合(控制反转),对象给出它们的依赖,而不是由我们创建或者查找依赖的对象们

  1. 谁控制谁:在传统的开发模式下,我们都是采用直接 new 一个对象的方式来创建对象,也就是说你依赖的对象直接由你自己控制,但是有了 IOC 容器后,则直接由 IoC 容器来控制。所以“谁控制谁”,当然是 IoC 容器控制对象。
  2. 控制什么:控制对象。
  3. 为何是反转:没有 IoC 的时候我们都是在自己对象中主动去创建被依赖的对象,这是正转。但是有了 IoC 后,所依赖的对象直接由 IoC 容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是反转。
  4. 哪些方面反转了:所依赖对象的获取被反转了。

因为有了IOC,所以有了第三个好处,spring作为容器帮我们包含和管理应用中对象的生命周期还有配置。

第四个spring支持面向切面的编程,也就是AOP,可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置插入这些功能。把应用业务逻辑和系统服务分开,AOP 的实现是基于代理模式

        代理模式:在被代理类的基础上做一层封装作为代理类,java中有静态代理、JDK动态代理、CGLib动态代理的方式

                静态代理的实现逻辑就是简单粗暴,在代理类中持有一个被代理类的实例,通过被代理类实例调用被代理对象的方法,另外在方法之前前后均可加入其它的方法处理逻辑,实现诸如权限及日志的操作。但是方法一多就变得麻烦了,每个方法都要写个代理,增加了代码维护的成本。所以为了减少维护成本,就有了动态代理

               JDK动态代理,通过实现JDK中的InvocationHandler接口,实现其中的invoke方法,在此方法中通过反射的方式调用被代理类的方法,可以在方法执行前或后进行别的处理。使用的时候通过Proxy类的newProxyInstance方法,生成代理类的实例,需要三个参数,第一个为被代理类的类加载器,第二个为被代理类实现的接口,第三个则为invocationHandler的实现类,这样就生成了代理对象,另外,由于第三个参数为一个接口,还可以使用匿名内部类的方式进行书写代理类。

               CGLib动态代理是一个第三方实现的动态代理类库,不要求被代理类必须实现接口,它采用的是继承被代理类,使用其子类的方式,弥补了被代理类没有接口的不足。

AOP包含三个概念:通知、切点和切面,通知是何时执行,定义了要织入目标对象的逻辑,以及执行时机。切点是何处执行,通过匹配规则查找合适的连接点(Joinpoint),AOP 会在这些连接点上织入通知。

spring在底层集成了JDK动态代理和CGLib动态代理,如果有接口用前者,反之用后者(不是final)

spring AOP可用来:

    1.Spring声明式事务管理配置。

    2.Controller层的参数校验。

    3.使用Spring AOP实现MySQL数据库读写分离案例分析

    4.在执行方法前,判断是否具有权限。

    5.对部分函数的调用进行日志记录。监控部分重要函数,若抛出指定的异常,可以以短信或邮件方式通知相关人员。

    6.信息过滤,页面转发等等功能

cart项目代码用spring AOP做特殊用户日志记录,ServiceEnhanceAspect类

第五个是springmvc框架

第六个是事务管理,Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

Spring事务管理基于底层数据库本身的事务处理机制。ACID:原子一致隔离持久。

https://blog.csdn.net/cs_fei/article/details/9748571

spring事务的实现方式主要有四种:

       (1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。
  (2)基于 TransactionProxyFactoryBean的声明式事务管理
  (3)基于 @Transactional 的声明式事务管理
  (4)基于Aspectj AOP配置事务

第七个是异常处理,Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常,具体再学习https://zhuanlan.zhihu.com/p/92322197

2)beanFactory

Bean 工厂是工厂模式的一个实现

         1. 简单工厂模式通过向工厂传递类型来指定要创建的对象

         2. 工厂方法模式将生成具体产品的任务分发给具体的产品工厂,也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。派生类工厂定义返回的产品类型,这样就不用指定类型创建对象了

         3. 抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。

XmlBeanFactory 它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。

3) ApplicationContext通常的实现是什么?和beanFactory的区别?

 

 

 

 

2. Redis缓存

缓存雪崩: 缓存的key有设置有效时间,当key过期时,会被自动删除。一般缓存都是定时任务去刷新,或者查不到后去更新,定时任务就会有问题。就是本来缓存能扛下部分请求,但是当时缓存所有的key全部失效,那么请求就都切到数据库,数据库扛不住就直接挂了,重启数据库又被新的流量干掉了。

简而言之,就是当缓存服务器重启或者大量缓存集中在某一个时间段失效,这时会给后端系统(比如DB)带来很大压力。

解决方案:在缓存失效后通过加锁或者队列来控制读数据库写缓存的线程数量,比如对某个key只允许一个线程查询数据和写缓存,其他线程等待;不同的key设置不同的过期时间,批量写缓存的时候可以加个随机值,让缓存失效的时间点尽量均匀;做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。

其他方案:如果缓存是集群部署,可以把热点数据均匀分布在不同的库中避免全部失效的问题,不过就比较难管理。或者设置热点数据永远不过期,有更新操作就更新缓存,但是这个就要看场景用了,我觉得首页数据就可以用这个操作。

缓存穿透:一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。如果key对应的value是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

解决方案:将查询结果为空的情况也进行缓存,缓存时间设置短一点,并在该key对应的数据insert之后清理缓存;对一定不存在的key进行过滤。

具体一点就是在接口层增加校验,不合法的参数直接return,直接拦截。redis还有一个布隆过滤器可以防止穿透

缓存击穿:定点打击,对一个热点key不停地大并发集中访问则个点,这个key失效的时候,持续的大并发就击穿缓存,直接请求数据库,就好像巨龙持续撞击

解决方案:设置热点数据永不过期 ,或者加上互斥锁

缓存崩了事后怎么补救? 降级,接口返回默认值之类

分布式缓存系统的需要注意缓存一致性、缓存穿透和雪崩、缓存数据的清理等问题。可以通过锁解决一致性问题;为了提高缓存命中率,可以对缓存分层,分为全局缓存,二级缓存,他们是存在继承关系的,全局缓存可以有二级缓存来组成。为了保证系统的HA,缓存系统可以组合使用两套存储系统(memcache,redis)。缓存淘汰的策略包括定时去清理过期的缓存、判断过期时间来决定是否重新获取数据。

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值