Spring 中创建对象的注解有哪些,分别介绍下区别
my:应该说的是@Controller,@Service,@Repository,@Configuration这些,不知道有啥区别。
answer:有四个@Controller
、@Service
、@Repository
、@Component
。@Component
是通用的注解。除了@Repository
作为持久层标记,用做自动异常转换外。其他的话只有名字上的区别。
IOC 容器的加载流程
my:不知道
Bean 的生命周期,说下涉及到的一些接口名
my:不知道
answer:bean的生命周期大致分为4个主要阶段:实例化,属性赋值,初始化和销毁。
Aware接口:实现 Aware 接口能让 Bean 获得相应的 Spring 容器资源。 BeanPostProcessor:Spring 为修改 bean 提供的扩展点。常用场景:对应标记接口的实现类,进行自定义处理,如为其注入相应依赖;为当前对象提供代理实现,例如 Spring AOP 功能,生成对象的代理类,然后返回。 InitializingBean, init-method:bean 初始化的扩展点。 DisposableBean, destory-method:bean销毁的扩展点
- [?] 可能不全
Bean 的作用域有哪些
my:默认的Singleton,在初始化的时候创建。Prototype多例模式,运行时创建,每次新建一个。还有httpSession的bean,http request的Bean,另外还有一个和http相关的忘记是什么了。
answer: bean有五种作用域,默认为单例:
- Singleton(单例类型),容器启动时就实例化和初始化
- Prototype(原型类型),容器启动时没有实例化,只有获取 bean 时才被创建,每次都新建一个实例
- request(web 的 Spring AllicationContext 下),每个 HTTP 都有自己的 bean,当处理结束时销毁
- session(web 的 Spring ApplicationContext 下),每个 HTTP session 都有自己的 bean
- global session(web 的 Spring ApplicationContext 下),全局会话共享一个实例 PS. Spring 的容器可以理解为是一个bean工厂,实现了ApplicationContext 接口
Spring 常用的类有哪些?BeanFactory等
my:没看过源码,看过也忘了
answer:#todo ,再说
Spring 中用到的一些设计模式,举例具体的场景
my:工厂模式,使用 BeanFactory 创建 Bean。
answer:
- 工厂模式,
- 单例模式,
- 代理设计模式:AOP基于动态代理
- 模板方法模式:Spring 中
jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,都使用了模板方法模式。但这些类没有使用模板方法常用的继承方法来实现,而是使用 Callback 模式与模板模式配置,既达到了代码复用的效果,又增加了灵活性。 - 观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用
- 适配器模式:Spring AOP 的增强或通知(Advice)使用到了适配器模式
- 装饰器模式:
InputStream
家族,InputStream
类下有FileInputStream
(读取文件)、BufferedInputStream
(增加缓存,使读取文件速度大大提升)等子类都在不修改InputStream
代码的情况下扩展了它的功能。
Spring 的单例 Bean 是线程安全的吗
- [b] my:不是线程安全的,如果 Bean 有状态的话,使用 Prototype 模式,或者使用 ThreadLocal。
介绍一下线程池,使用线程池的好处,参数有哪些
my:
- [b] 线程池的好处是管理线程更加规范,避免频繁地创建线程和销毁线程,性能更好,然后可以通过配置限制线程数,防止创建过多线程导致应用崩溃。 参数有最小线程数,最大线程数,线程销毁时间,拒绝策略等。
answer: 参数:
- corePoolSize:核心线程的数量(最小线程数)
- maximumPoolSize:最大线程数量
- keepAliveTime:非核心线程的超时时长,超时会被回收
- unit:keepAliveTime 的时间单位
- workQueue:线程池的任务列表
- threadFactory:为线程池提供创建新线程的功能
- handler:拒绝策略
线程池有哪几种,优劣是啥
my:无界队列和有界队列的,无界队列的不安全,可能引发故障。
answer:
- FixedThreadPool:固定线程数量的线程池,适合场景固定
- SingleThreadPool:只有一个线程的线程池,适合线程同步操作的场景
- CachedThreadPool:
corePoolSize = 0, maximumPoolSize = Integer.MAX_VALUE
- ScheduledThredPool:定期执行的线程池
这些使用 Executors 静态工厂类创建的线程池,队列都使用的是无界队列,很容易导致 OOM,所以不建议使用,推荐直接用
ThreadPoolExecutor
创建。
线程池的拒绝策略有哪些
my:默认的策略是抛异常,还有几种策略忘记了,应该有一种是抛弃最早的。
answer:拒绝策略有4钟
- CallerRunsPolicy:提交任务的线程自己去执行任务;
- AbortPolicy:默认的拒绝策略,抛出
RejectedExecutionException
异常; - DiscardPolicy:直接丢弃任务,没有任何异常抛出;
- DiscardOldestPolicy:丢弃最老的任务,把新任务加入到队列。
线程池 execute 和 submit 的区别
my:不知道
answer:execute 不返回,submit 在 execute 的基础上,返回 Future 对象。 如果出现异常,execute 直接抛出异常,然后死掉,会导致线程无法重用;submit 把异常保存在成员变量中,不会出现这种情况。
synchronized 和 volatile
my:多线程有三大问题,原子性、可见性、有序性。用 volatile 修饰的对象不会进入 CPU 寄存器,只会存放在内存中,解决了可见性问题;并且由于 Happenes Before 规则,volatile 禁止部分指令的重排,也可以解决有序性问题。synchronized 可以同时解决原子性、可见性和有序性这三个问题,存在锁升级的机制,可以由偏向锁升级到轻量级锁,最后再升级到重量级锁。
answer: 差不多,synchronized是一个锁实现,是 Java 对于管程的实现
ThreadLocal 的特性和应用场景
my:ThreadLocal 就相当于是一个 HashMap,key 是线程标识,值在线程间相互独立。应用场景包括记录 Session 信息,或者有状态的 bean 用来记录有状态的属性。
answer:ThreadLocal 变量线程独立。ThreadLocal 如果被强引用,较难被回收,可能会导致内存泄漏,所以需要手动释放。ThreadLocal 常用来传递上下文信息,如 Spring 用 ThreadLocal 来传递事务信息;或是用来存储用户信息。
JVM 的内存模型
my:JVM 包括虚拟机栈,本地方法栈,堆内存,程序计数器,方法区(永久代,元空间)。
- 虚拟机栈:存储单位为栈帧,主要存放方法的变量,线程独立
- 本地方法栈:与虚拟机栈类型,存放的是C语言编写的本地方法
- 程序计数器:存放当前执行语句的指针,线程独立
- 堆内存:存放对象实例,线程共用
- 方法区:堆外内存,存放常量,对象等,线程共用
answer:
- 程序计数器:记录线程正在执行的字节码指令的地址,线程隔离
- 虚拟机栈:栈帧中存储局部变量表、操作数栈、动态连接、方法出口信息,线程隔离
- 本地方法栈:同虚拟机栈,存放的 navtive 方法,线程隔离
- 堆:存储 Java 对象,线程共享
- 方法区:存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码,线程 公用
JVM 加载 Class 的过程
my:加载 验证 准备 连接 初始化 使用 卸载,是这样吗? answer:加载、验证、准备、解析、初始化、使用、卸载,详见类加载