Spring 中创建对象的注解有哪些,分别介绍下区别

my:应该说的是@Controller,@Service,@Repository,@Configuration这些,不知道有啥区别。

answer:有四个@Controller@Service@Repository@Component@Component是通用的注解。除了@Repository作为持久层标记,用做自动异常转换外。其他的话只有名字上的区别。

IOC 容器的加载流程

my:不知道

answer:太复杂,先不看 IOC容器

Bean 的生命周期,说下涉及到的一些接口名

my:不知道

answer:bean的生命周期大致分为4个主要阶段:实例化,属性赋值,初始化和销毁。 Bean生命周期

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有五种作用域,默认为单例:

  1. Singleton(单例类型),容器启动时就实例化和初始化
  2. Prototype(原型类型),容器启动时没有实例化,只有获取 bean 时才被创建,每次都新建一个实例
  3. request(web 的 Spring AllicationContext 下),每个 HTTP 都有自己的 bean,当处理结束时销毁
  4. session(web 的 Spring ApplicationContext 下),每个 HTTP session 都有自己的 bean
  5. global session(web 的 Spring ApplicationContext 下),全局会话共享一个实例 PS. Spring 的容器可以理解为是一个bean工厂,实现了ApplicationContext 接口

Spring 常用的类有哪些?BeanFactory等

my:没看过源码,看过也忘了

answer:#todo ,再说

Spring 中用到的一些设计模式,举例具体的场景

my:工厂模式,使用 BeanFactory 创建 Bean。

answer:

  • 工厂模式,
  • 单例模式,
  • 代理设计模式:AOP基于动态代理
  • 模板方法模式:Spring 中 jdbcTemplatehibernateTemplate 等以 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:加载、验证、准备、解析、初始化、使用、卸载,详见类加载