1.Excrption和Error的区别?
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
常见的异常;
NullPointerException 空指针异常
ArrayIndexOutOfBoundsException 数组下标越界异常,
ArithmaticException 算数异常 如除数为零
IllegalArgumentException 不合法参数异常

2.类加载过程?
从类的生命周期而言,一个类有5个阶段,按照顺序进行分别是加载、验证、准备、解析、初始化(也就是加载阶段;连接阶段:验证、准备、解析;初始化阶段)。

2.1在加载阶段,虚拟机需要完成以下3件事情:
a.通过一个类的全限定名来获取定义此类的二进制字节流;
b.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
c.在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2.2连接阶段:
2.2.1验证:确保被加载的类的正确性
确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
a.文件格式验证:验证字节流是否符合Class文件格式的规范,如:是否以模数0xCAFEBABE开头、主次版本号是否在当前虚拟机处理范围内等等。
b.元数据验证:对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求;如:这个类是否有父类,是否实现了父类的抽象方法,是否重写了父类的final方法,是否继承了被final修饰的类等等。
c.字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,如:操作数栈的数据类型与指令代码序列能配合工作,保证方法中的类型转换有效等等。
d.符号引用验证:确保解析动作能正确执行;如:通过符合引用能找到对应的类和方法,符号引用中类、属性、方法的访问性是否能被当前类访问等等。
验证阶段是非常重要的,但不是必须的。

2.2.2准备:为类的静态变量分配内存,并将其赋默认值:
为类变量分配内存并设置类变量初始值,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:
a.只对static修饰的静态变量进行内存分配、赋默认值(如0、0L、null、false等)。
b.对final的静态字面值常量直接赋初值(赋初值不是赋默认值,如果不是字面值静态常量,那么会和静态变量一样赋默认值)。
2.2.3解析:将常量池中的符号引用替换为直接引用(内存地址)的过程。
a.符号引用就是一组符号来描述目标,可以是任何字面量。属于编译原理方面的概念如:包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。
b.直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。如指向方法区某个类的一个指针。
假设:一个类有一个静态变量,该静态变量是一个自定义的类型,那么经过解析后,该静态变量将是一个指针,指向该类在方法区的内存地址。

2.3初始化:为类的静态变量赋初值
赋初值两种方式:
定义静态变量时指定初始值。如 private static String x="123";
在静态代码块里为静态变量赋值。如 static{ x="123"; }
注意:只有对类的主动使用才会导致类的初始化。

3.类加载方式:
这里的类加载不是指类加载阶段,而是指整个类加载过程,即类加载阶段到初始化完成。
(1)隐式加载
创建类对象
使用类的静态域
创建子类对象
使用子类的静态域
在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class
在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class
在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件
(2)显式加载
ClassLoader.loadClass(className),只加载和连接、不会进行初始化
Class.forName(String name, boolean initialize,ClassLoader loader); 使用loader进行加载和连接,根据参数initialize决定是否初始化。

4.说一下JVM运行时数据区?
(1)不同虚拟机的运行时数据区可能有点不同,但都会遵从Java虚拟机规范,Java虚拟机规范规定的区域分为以下5个部分:
(2)程序计数器:当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值来选取下一条需要执行的字节码指令、分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
(3)Java虚拟机栈:用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
(4)本地方法栈:与虚拟机栈的作用一样,只不过虚拟机栈是服务Java方法,而本地方法栈是为虚拟机调用Natice方法服务的;
(5)Java堆:java虚拟机中内存最大的一块,是被所有线程共享的,几乎所有对象实例都在这里分配内存;
(6)方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。

5.线程和进程的区别?
进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。
线程:单个进程中执行的每个任务就是一个线程。线程是进程中执行运算的最小单位。
一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。

6.什么是线程安全?
当多个线程访问某个方法时,不管你通过怎样的调用方式、或者说这些线程如何交替地执行,我们在主程序中不需要去做任何的同步,这个类的结果行为都是我们设想的正确行为,那么我们就可以说这个类是线程安全的。

7.怎么实现线程安全?
synchronized关键字,就是用来控制线程同步的,保证我们的线程在多线程环境下,不被多个线程同时执行,确保我们数据的完整性,使用方法一般是加在方法上。
Lock让锁有了可操作性,就是我们在需要的时候去手动的获取锁和释放锁,甚至我们还可以中断获取以及超时获取的同步特性,但是从使用上说Lock明显没有synchronized使用起来方便快捷。

8.说一下设计模式?你都知道哪些?
1.单例模式:是一种常用的软件设计模式,在应用这个模式时,单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例。
2.简单工厂模式:又叫静态工厂方法模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。比如,一台咖啡机就可以理解为一个工厂模式,你只需要按下想喝的咖啡品类的按钮(摩卡或拿铁),它就会给你生产一杯相应的咖啡,你不需要管它内部的具体实现,只要告诉它你的需求即可。
3.抽象工厂模式:在简单工厂的基础上将未来可能需要修改的代码抽象出来,通过继承的方式让子类去做决定。
4.观察者模式:是定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
5.适配器模式:将两个原来不兼容的类兼容起来一起工作。生活中的例子:变压器、充电器
6.代理模式:为其他对象提供一个代理,以控制对当前对象的访问。生活中的例子:房屋中介、婚姻介绍所。

9.JDK类库常用的设计模式有哪些?
工厂模式、适配器模式、代理模式、单例模式、装饰器、模板方法模式。

Spring 中都使用了哪些设计模式?
单例模式、工厂模式、观察者模式、适配器模式、代理模式、模板方法模式。

10.Spring MVC的流程?
(1)用户发送请求到前端控制器DispatcherServlet,
(2)前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping;
(3)处理器映射器HandlerMapping根据请求url找到具体的处理器,并生成处理器执行链HandlerExcutionChain(包括处理器对象和处理器拦截器)返回给前端控制器DispatcherServlet;
(4)前端控制器DispatcherServlet根据处理器Handler获取对应的适配器;
(5)处理器适配器HandlerAdapter调用处理器Handler,处理器Handler执行完后返回ModeAndView给处理器适配器HandlerAdapter;
(6)处理器适配器HandlerAdapter返回ModelAndView给前端控制器;
(7)前端控制器统一将返回的ModelAndView派送到视图解析器ViewResolve;
(8)视图解析器ViewResolve解析后返回View;
(9)对view进行渲染
(10)前端控制器响应用户。

11.Spring IOC和AOP区别?
AOP一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。用于权限认证、日志、事务处理。
IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间的松散耦合,也利用功能的复用。