一、有return的try catch finally
任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,编译器把finally中的return实现为一个warning。
如果有 finally 代码块,此时程序执行到 try 代码块里的 return 语句之时并不会立即执行 return(如果return后是语句或者函数,eg:return b+=10; or return functionA();,先执行return后的语句或者函数),而再去执行 finally 代码块里的代码,
若 finally 代码块里没有 return 或没有能够终止程序的代码,程序将在执行完 finally 代码块代码之后再返回 try 代码块执行 return 语句来结束整个方法;
若 finally 代码块里有 return 或含有能够终止程序的代码,方法将在执行完 finally 之后被结束,不再跳回 try 代码块执行 return。
二、HashMap
HashMap的底层主要是基于数组和链表来实现的
通过key的hashCode来计算hash值,再通过Hash值去计算存储在数组中的下标【hash(key.hashCode()),h&(length-1)】,进行少量比较即可得到元素,这使得 HashMap 的查找效率贼高。
哈希表的容量是2的整数次幂:length-1得到的二进制数的每个位上的值都为1,保证了散列的均匀;同时h&(length-1)就相当于对length取模,提升了效率;
put 方法的源代码可以看出,当程序试图将一个key-value对放入HashMap中时,程序首先根据该 key 的 hashCode() 返回值决定该 Entry 的存储位置:
如果两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置相同。
如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但key不会覆盖。
如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部——
三、GC算法
标记-清除算:容易产生碎片
复制算法:每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将该两块空间中还存活的对象复制到另一块Survivor空间中。
标记-整理算法:标记后不是清理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象
分代收集算法:新生采用复制算法,老生代采用标记整理算法
四、HTTP协议
是基于TCP的应用层协议,主要是用来规定客户端和服务端数据传输的格式和数据交互行为,并不负责数据传输的细节。
五、NIO
NIO 是一种同步非阻塞的 IO 模型。
同步是指线程不断轮询 IO 事件是否就绪
非阻塞是指线程在等待 IO 的时候,可以同时做其他任务。
同步的核心就是 Selector,Selector 代替了线程本身轮询 IO 事件,避免了阻塞同时减少了不必要的线程消耗;
非阻塞的核心就是通道和缓冲区,当 IO 事件就绪时,可以通过写道缓冲区,保证 IO 的成功,而无需线程阻塞式地等待。
基于阻塞式I/O的多线程模型中,Server为每个Client连接创建一个处理线程,每个处理线程阻塞式等待可能达到的数据,一旦数据到达,则立即处理请求、返回处理结果并再次进入等待状态。
六、索引
优点:1.加快数据的检索速度;
2.创建唯一性索引,保证数据记录的唯一性;
3.加速表和表之间的连接;
4.在使用分组和排序子句进行数据检索时,可以减少查询中分组和排序的时间。
缺点:索引需要占物理空间,当对表中的数据进行增删改的时候,索引也要动态的维护,降低了数据的维护速度。
SELECT * FROM EMP WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
示例一、查询出每个部门的编号,名称,位置,部门人数,平均工资
SELECT d.deptno,d.dname,d.loc,temp.con,temp.avgsal FROM dept d,(SELECT deptno dno,COUNT(empno) con,ROUND (AVG(sal),2) avgsal FROM emp GROUP BY deptno) temp WHERE d.deptno=temp.dno;
示例二、查询出所有在部门SALES(销售部)工作的员工编号,姓名,基本工资,奖金,职位,入职日期,部门最高和最低工资
SELECT e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,e.deptno,temp.maxsal,temp.minsal FROM emp e,( SELECT deptno dno,MAX(sal) maxsal,MIN(sal) minsal FROM emp GROUP BY deptno ) temp WHERE e.deptno=(SELECT deptno FROM dept WHERE dname=’SALES’) AND e.deptno=temp.dno;
七、Springboot
提供starter简化Maven配置
自动配置
内嵌Servlet容器
Spring Boot中使用yaml文件或者properties文件进行配置管理,大大简化了之前的xml文件的繁琐配置,并且主要都是通过注解来进行开发。
八、springboot自动配置的原理
在spring程序main方法中 添加@SpringBootApplication或者@EnableAutoConfiguration
会自动去maven中读取每个starter中的spring.factories文件
该文件里配置了所有需要被创建spring容器中的bean
九、SpringMVC流程
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。执行链(HandlerExecutionChain包含处理器对象及处理器拦截器)
4、DispatcherServlet调用HandlerAdapter处理器适配器
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
十、AOP
AOP应用:事务、缓存、日志、性能等
使用spring的声明式事务后,只需要在数据库处理方法上注解事务,就可以对操作进行管理,事务的设置和逻辑代码分开,
1、Aspect(切面) : 应用运行过程中的关注点,关注点可以横切多个对象,被称为横切关注点。
2、pointcut(切入点):可插入增强处理的连接点。
3、joinpoint(连接点):程序执行过程中明确的点,如方法的调用,或者异常的抛出。
4、advice(增强处理):AOP框架特定的切入点执行的增强处理
在AOP编程,我们需要做如下三部分:
1、定义普通组件。
2、定义切入点、一个切入点可能横切多个业务组件。
3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作。
十一、static
static 表示静态或全局,它可以修饰属性,方法和代码块。由于静态属性和方法是属于该类的所有对象的,所以可以用类名.静态属性/方法名来访问。用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块。
类成员变量分两种:static修饰的变量,叫静态变量或类变量;没有被static修饰的变量,叫实例变量。类中的实例变量是在创建对象时被初始化的,被static修饰的属性,也就是类变量,是在类加载时被创建并进行初始化,类加载的过程是进行一次。也就是类变量只会被创建一次。
this关键字必须放在非静态方法里面,this关键字代表自身,的使用用途:引用成员变量、成员方法,在自身构造方法内部引用其它构造方法,代表自身类的对象。
十二、类初始化主动引用
1.创建类的实例
2.访问类的静态变量(除常量【被final修辞的静态变量】
3.访问类的静态方法
4.反射如(Class.forName(“my.xyz.Test”))
5.当初始化一个类时,发现其父类还未初始化,则先出发父类的初始化
6.虚拟机启动时,定义了main()方法的那个类先初始化
被动引用
1.子类调用父类的静态变量,子类不会被初始化。只有父类被初始化。对于静态字段,只有直接定义这个字段的类才会被初始化.
2.通过数组定义来引用类,不会触发类的初始化
3.访问类的常量,不会初始化类