简单概括:
1.刷新预处理
2.将配置信息解析,注册到BeanFactory
3.设置bean的类加载器
4.如果有第三方想再bean加载注册完成后,初始化前做点什么(例如修改属性的值,修改bean的scope为单例或者多例。),提供了相应的模板方法,后面还调用了这个方法的实现,并且把这些个实现类注册到对应的容器中
5.初始化当前的事件广播器
6.初始化所有的bean
7.广播applicationcontext初始化完成。
//来自于AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
//进行加锁处理
synchronized (this.startupShutdownMonitor) {
// 进行刷新容器的准备工作,比如设定容器开启时间,标记容器已启动状态等等
prepareRefresh();
// 让子类来刷新创建容器
// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
prepareBeanFactory(beanFactory);
try {
// 这里需要知道 BeanFactoryPostProcessor 这个知识点,
//Bean 如果实现了此接口,那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 初始化当前 ApplicationContext 的 MessageSource
initMessageSource();
// 初始化当前 ApplicationContext 的事件广播器
initApplicationEventMulticaster();
// 从方法名就可以知道,典型的模板方法(钩子方法),
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
onRefresh();
// 注册事件监听器,监听器需要实现 ApplicationListener 接口
registerListeners();
// 初始化所有的 singleton beans(lazy-init 的除外)
// 重点方法将会在下一个章节进行说明
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + ex);
}
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
// Reset ‘active’ flag.
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
// Reset common introspection caches in Spring’s core, since we
// might not ever need metadata for singleton beans anymore…
resetCommonCaches();
}
}
}
了解过字节码的编译过程吗(这个还真不知道)
三面
自我介绍,不超过3分钟(这次好像时间更久了,也就2分钟多点)
说一下你对哪个项目比较熟悉
数据库项目
为什么做这个项目
当时公司里为了整改balabala
项目采用了什么架构,数据库如何设计的
简单是MVC架构,数据库数据库由哪些表,为什么有这些表
主要有哪些核心模块,模块之间如何通信的session放在哪里
主要有哪些核心模块,模块之间如何通信的 session放在哪里
如何保存会话状态,有哪些方式、区别如何
cookie 保存在客户端,容易篡改
session 保存在服务端,连接较大的话会给服务端带来压力,分布式的情况下可以放在数据库中,
优点:
1:简单且高性能
2:支持分布式与集群
3:支持服务器断电和重启
4:支持 tomcat、jetty 等运行容器重启
缺点:
1、需要检查和维护session过期,手动维护cookie;
2、不能有频繁的session数据存取;
token 多终端或者app的话一定要这个,
随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。
JWT的token包含三部分数据:
Header:头部,通常头部有两部分信息: 声明类型,这里是JWT 加密算法,自定义
我们会对头部进行base64加密(可解密),得到第一部分数据 Payload:载荷,就是有效数据,一般包含下面信息: 用户身份信息(注意,这里因为采用base64加密,可解密,因此不要存放敏感信>息) 注册声明:如token的签发时间,过期时间,签发人等
这部分也会采用base64加密,得到第二部分数据 Signature:签名,是整个数据的认证信息。一般根据前两步的数据, 再加上服务的>的密钥(secret)
(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性(不要泄漏,最好周期性更换),
通过加密算法生成。用于验证整个数据完整和可靠性
分布式session如何管理,你有哪些方案 Redis做缓存持久化存储session 数据库存储session
学过数据结构和算法吗(当然),你说说二分搜索的过程 二分搜索有一点要求就是数据有已经排序好的,假设是自然排序的,拿到目标数据后查找中间的值,如果大了,就去右边一部分的中间值比较,小了就去左边一部分的中间值
说一下快排的过程,写一下伪代码 取一个值,然后设置两个指针,一个指针先从后到前开始遍历,遇到小于这个值的就停止,然后另一个指针从前到后遍历,遇到大于这个值的就停止,知道这两个指针相遇,此时交换这个值与相遇的时候指针的值,以这个坐标为边界两边开始递归
了解哪设计模式,举例说说在jdk源码哪些用到了你说的设计模式 单例:ioc容器 模板:ioc、springmvc 建造者模式:lombok 工厂:ioc 代理:aop 订阅/发布:消息队列,redis的pub/sub
你有什么问我吗(仍然上面三个问题)
四面:
来个自我介绍呗,不超过3分钟 介绍下你最熟悉的项目 项目使用了什么架构,亮点是什么 MVC,用到Lucene,用aop实现了权限的管理 平时主要学习什么课程 Java、数据结构、数学建模 你目前的研究方向是什么 家是哪的 喜欢看什么书
大概什么时候能来实习呢 四面总结
五面
自我介绍下吧
做了哪些项目
看你在问题中说你在杭州看到很多商贩使用付款二维码,你对支付宝怎么看
每天有那么多人使用支付宝,这些数据如果给你存储,你会怎么设计呢(不是说HR不问技术问题吗?不愧是阿里的HR)
为什么想来支付宝实习呢
技术栈、对移动支付比较好奇,
你身边同学如何评价你、老师呢
如果与同事发生了意见的不一致,你会如何解决呢
首先就是要确保双方都理解了对方的意思,因为有些是沟通不充分导致的,然后同时综合对比不同意见,可能会对工作内容产生的影响,并且会根据利弊来选择方法
通过阿里的面试,我查看了这些面试资料,现在分享出来给大家,希望能给大家带来帮助
Java多线程
说一说自己对于 synchronized 关键字的了解
说说自己是怎么使用 synchronized 关键字,在项目中用到了吗
讲一下 synchronized 关键字的底层原理
说说 JDK1.6 之后的synchronized 关键字底层做了哪些优化,可以详细介绍一下这些优化吗
谈谈 synchronized和ReenTrantLock 的区别
说说 synchronized 关键字和 volatile 关键字的区别
为什么要用线程池?
实现Runnable接口和Callable接口的区别
执行execute()方法和submit()方法的区别是什么呢?
如何创建线程池
介绍一下Atomic 原子类
JUC 包中的原子类是哪4类?
讲讲 AtomicInteger 的使用
能不能给我简单介绍一下 AtomicInteger 类的原理
多线程面试专题与答案
JVM的设计目标是提供一个基于抽象规格描述的计算机模型,为解释程序开发人员提供很好的灵活性,同时也确保Java代码可在符合该规范的任何系统上运行。JVM对其实现的某些方面给出了具体的定义,特别是对Java可执行代码,即字节码(Bytecode)的格式给出了明确的规格。这一规格包括操作码和操作数的语法和数值、标识符的数值表示方式、以及Java类文件中的Java对象、常量缓冲池在JVM的存储映象。这些定义为JVM解释器开发人员提供了所需的信息和开发环境。Java的设计者希望给开发人员以随心所欲使用Java的自由。
JVM
内存模型以及分区,需要详细到每个区放什么。
GC 收集器有哪些?CMS 收集器与 G1 收集器的特点。
Minor GC 与 Full GC 分别在什么时候发生?
堆里面的分区:Eden,survival (from+ to),老年代,各自的特点。
简述 java 垃圾回收机制?
java 中垃圾收集的方法有哪些?
类加载器双亲委派模型机制?什么是类加载器,类加载器有哪些?
简述 java 内存分配与回收策率以及 Minor GC 和Major GC
Redis
为什么要用 redis /为什么要用缓存?
为什么要用 redis 而不用 map/guava 做缓存?
redis 和 memcached 的区别?
上述 Redis 分布式锁的缺点?
redis 常见数据结构以及使用场景分析
最后
GC 收集器有哪些?CMS 收集器与 G1 收集器的特点。
Minor GC 与 Full GC 分别在什么时候发生?
堆里面的分区:Eden,survival (from+ to),老年代,各自的特点。
简述 java 垃圾回收机制?
java 中垃圾收集的方法有哪些?
类加载器双亲委派模型机制?什么是类加载器,类加载器有哪些?
简述 java 内存分配与回收策率以及 Minor GC 和Major GC
Redis
为什么要用 redis /为什么要用缓存?
为什么要用 redis 而不用 map/guava 做缓存?
redis 和 memcached 的区别?
上述 Redis 分布式锁的缺点?
redis 常见数据结构以及使用场景分析
最后
[外链图片转存中…(img-HFFQPed9-1714693391596)]
[外链图片转存中…(img-VY6oILR1-1714693391596)]