远景智能
面经总结Spring boot
-
常用注解有哪些
@Service: 注解在类上,表示这是一个业务层bean
@Controller:注解在类上,表示这是一个控制层bean
@Repository: 注解在类上,表示这是一个数据访问层bean
@Component: 注解在类上,表示通用bean ,value不写默认就是类名首字母小写
@Autowired:按类型注入.默认属性required= true;当不能确定 Spring 容器中一定拥有某个类的Bean 时, 可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false), 这等于告诉Spring:在找不到匹配Bean时也不抛出BeanCreationException 异常。@Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变byName 了。@Autowired可以对成员变量、方法以及构造函数进行注释,而 @Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 不将 @Autowired 和 @Qualifier 统一成一个注释类。
@Resource: 按名称装配区别:
@Resource默认按照名称方式进行bean匹配,@Autowired默认按照类型方式进行bean匹配
@Resource(importjavax.annotation.Resource;)是J2EE的注解,@Autowired(importorg.springframework.beans.factory.annotation.Autowired;)是Spring的注解
@Configuration:注解在类上,表示这是一个IOC容器,相当于spring的配置文件,java配置的方式。 IOC容器的配置类一般与 @Bean 注解配合使用,用 @Configuration 注解类等价与 XML 中配置 beans,用@Bean 注解方法等价于 XML 中配置 bean。
@Bean: 注解在方法上,声明当前方法返回一个Bean@Scope:注解在类上,描述spring容器如何创建Bean实例。
(1)singleton: 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
(2)prototype:表示每次获得bean都会生成一个新的对象
(3)request:表示在一次http请求内有效(只适用于web应用)
(4)session:表示在一个用户会话内有效(只适用于web应用)
(5)globalSession:表示在全局会话内有效(只适用于web应用)
@ComponentScan:注解在类上,扫描标注了@Controller等注解的类,注册为bean 。@ComponentScan 为 @Configuration注解的类配置组件扫描指令。@ComponentScan 注解会自动扫描指定包下的全部标有 @Component注解的类,并注册成bean,当然包括 @Component下的子注解@Service、@Repository、@Controller。
-
bean的生命周期
(1)实例化Bean:
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。
(2)设置对象属性(依赖注入):
实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成依赖注入。
(3)处理Aware接口:
接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:
①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值;
②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;
(4)BeanPostProcessor:
如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
(5)InitializingBean 与 init-method:
如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
(6)如果这个Bean实现了BeanPostProcessor接口,将会调用 postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
(7)DisposableBean:
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
(8)destroy-method:
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
-
Spring-MVC
-
Spring-MVC是基于Spring框架派生出来的Web框架。
-
通过Spring-MVC可以很容易把后台的数据转换为各种类型的数据,以满足移动互联网数据多样化的需求。
-
Spring-MVC框架的运行流程: HTTP的处理请求先到达控制器,控制器的作用是进行请求分发,这样它会根据请求的内容去访问模型层;当控制器获取到模型层返回的数据后,就将数据渲染到视图中,这样就能展现给用户了。
-
复盘 7.15
-
描述生产者、消费者模型及实现过程,超过容量怎么办?
这种设计模式需要满足以下三点要求:
(1)生产者生产数据到缓冲区中,消费者从缓冲区中取数据。
(2)如果缓冲区已经满了,则生产者线程阻塞;
(3)如果缓冲区为空,那么消费者线程阻塞。有三种实现方法:
https://blog.csdn.net/zhengzhaoyang122/article/details/82079021
- 使用synchronized
- 使用lock
- 使用阻塞队列
-
除了单例和工厂模式,还了解哪些模式(具体)
策略模式: https://blog.csdn.net/yeyazhishang/article/details/97150074
使算法的使用和算法的具体实现相互隔离。最直接的例子就是,Collection接口下的sort方法,不需要知道参数Comparator的具体实现,便可以直接使用,因此我们可以通过修改Comparator来实现不同的排序此策略。
-
描述一致性哈希
可用于redis集群中的数据分区: 一致性哈希算法将 整个哈希值空间 组织成一个虚拟的圆环,范围是 [0 - 232 - 1],对于每一个数据,根据
key
计算 hash 值,确定数据在环上的位置,然后从此位置沿顺时针行走,找到的第一台服务器就是其应该映射到的服务器 -
消息中间件
-
浏览器如何区分开多个http请求
-
描述https及ssl协议,双方交换密钥的具体过程
-
https是以安全为目标的Http通道,是Http的安全版。Https的安全基础是SSL。
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:SSL记录协议(SSL Record Protocol),它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。SSL握手协议(SSL Handshake Protocol),它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
-
双方交换密钥的过程:
第1步 网站服务器先基于“非对称加密算法”,随机生成一个“密钥对”(为叙述方便,称之为“k1 和 k2”)。因为是随机生成的,目前为止,只有网站服务器才知道 k1 和 k2。
第2步 网站把 k1 保留在自己手中,把 k2 用【明文】的方式发送给访问者的浏览器。因为 k2 是明文发送的,自然有可能被偷窥。不过不要紧。即使偷窥者拿到 k2,也很难根据 k2 推算出 k1(这一点是由“非对称加密算法”从数学上保证的)。
第3步 浏览器拿到 k2 之后,先随机生成第三个对称加密的密钥(简称 k)。然后用 k2 加密 k,得到 k’(k’ 是 k 的加密结果)浏览器把 k’ 发送给网站服务器。由于 k1 和 k2 是成对的,所以只有 k1 才能解密 k2 的加密结果。因此这个过程中,即使被第三方偷窥,第三方也无法从 k’ 解密得到 k。
第4步 网站服务器拿到 k’ 之后,用 k1 进行解密,得到 k至此,浏览器和网站服务器就完成了密钥交换,双方都知道 k,而且貌似第三方无法拿到 k。然后,双方就可以用 k 来进行数据双向传输的加密。
-
-
IOC如何实现扩展
-
redis等分布式缓存的存在意义、场景等
分布式缓存一般都具有良好的水平扩展能力,对较大数据量的场景也能应付自如。缺点就是需要进行远程请求,性能不如本地缓存。
-
redis集群
集群中的每一个 Redis 节点都 互相两两相连,客户端任意 直连 到集群中的 任意一台,就可以对其他 Redis 节点进行 读写 的操作 。
作用:
- 数据分区: 数据分区 (或称数据分片) 是集群最核心的功能。集群将数据分散到多个节点,一方面 突破了 Redis 单机内存大小的限制,存储容量大大增加;另一方面 每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。
- 高可用: 集群支持主从复制和主节点的 自动故障转移 (与哨兵类似),当任一节点发生故障时,集群仍然可以对外提供服务。
-
redis缓存雪崩及应对方法
缓存雪崩:产生的原因是缓存挂掉,这时所有的请求都会穿透到 DB。
- 事发前:实现 Redis 的高可用(主从架构 + Sentinel 或者 Redis Cluster),尽量避免 Redis 挂掉这种情况发生。 在批量往
Redis
存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保 证数据不会在同一时间大面积失效 ; 如果Redis
是集群部署,将热点数据均匀分布在不同的Redis
库中也能避免全部失效的问题 。 - 事发中:万一 Redis 真的挂了,我们可以设置本地缓存(ehcache) + 限流(hystrix),尽量避免我们的数据库被干掉(起码能保证我们的服务还是能正常工作的)
- 事发后:Redis 持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。
- 事发前:实现 Redis 的高可用(主从架构 + Sentinel 或者 Redis Cluster),尽量避免 Redis 挂掉这种情况发生。 在批量往
-
消息队列中kafka的优势及适用场景
- 消息队列主要解决的问题: https://www.cnblogs.com/jpfss/p/10412603.html
- 解耦
- 异步
- 削峰
- 消息队列主要解决的问题: https://www.cnblogs.com/jpfss/p/10412603.html
-
kafka特点及优势:
-
吞吐量高达十万级;
-
基于分布式架构,一个数据多个副本,少数机器宕机,不会丢失数据,不回导致不可用;
3. 理论上不会丢失消息;
- 适用场景:kafka功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用。kafka的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时kafka最好是支撑较少的topic数量即可,保证其超高吞吐量。而且kafka唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。
-
-
其他消息队列特点及适用场景对比:java面试突击P105-106
二面准备
-
一面问题复盘
-
java多线程与linux多线程的关系
JVM线程跟内核轻量级进程有一一对应的关系。线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
Java线程在Windows及Linux平台上的实现方式,现在看来,是内核线程的实现方式。这种方式实现的线程,是直接由操作系统内核支持的——由内核完成线程切换,内核通过操纵调度器(Thread Scheduler)实现线程调度,并将线程任务反映到各个处理器上。
-
Redis是如何实现分布式锁
-
redis为什么是单线程 IO多路复用:
因为 Redis 是基于内存的操作,CPU 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是 机器内存的大小 或者 网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。
-
Redis的数据结构
-
AOP的实现
-
MySQL引擎、事务、索引
-
如何优化MySQL的sql
二面复盘
- concurrentHashMap的底层原理
- Synchronized和Lock的区别及底层实现
- 算法:实现负载均衡
- 线程池了解吗