秋招面经自己总结的,第一弹
1. string和stringbuilder区别,内存上的区别?
String是固定长度的;stringbuilder是可扩展的,线程不同步的;
String分配在栈区,stringbuilder分配在堆区;
StringBuffer可扩展,线程安全,效率低;
2. 堆和栈的区别?
首先栈是类似于箱子类型的,先进后出;堆是经过排序的树形的数据结构,根节点大于(小于)子节点,并且左右节点都是堆结构;
栈是操作系统自动的分配和释放内存,用完就释放;堆是程序员主动的去申请内存,并且OS不会自动的去释放内存;
栈是连续的内存空间,大小固定,一般是2M,空间较小;堆是利用内存中的空闲地址,用链表来存储这些空闲的地址,不是连续的内存地址;
3. 事务,隔离级别?四个特性?
事务指的是一系列数据库操作的集合,理解就是把一堆事情捆绑到一起,全部都完成了,事务才算完成;
首先事务在高并发下会产生三个问题,脏读(其他事务未commit),不可重复读(update或者delete造成),幻读(insert造成,多读);
4个隔离级别:
read uncommitted(未提交读)
read committed(提交读)避免脏读
repeatable read(重复读)避免不可重复读
serializable(串行化)避免幻读
四个特性:
1. Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成 功,要么全部失败。
2. Consistency(一致性):事务完成时,数据必须处于一致状态,数据的完整性约束没有被破坏,事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没 有执行过一样。
3.Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性 和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
4.Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。
4. IOC和DI?自动注入的作用?
IOC控制反转,就是利用IOC容器来控制依赖对象的创建,控制外部资源的获取和生命周期;反转的是IOC容器帮忙创建和查找这些依赖对象,对象只需要被动的接受就行;
DI依赖注入,应用程序依赖IOC容器,需要IOC容器提供的外部资源,IOC注入应用程序的某个对象或者依赖对象,注入的是对象所需要的外部资源;
区别是不同方面的表述,IOC是容器方面,DI是应用程序方面;
自动注入的作用主要是避免手动写properties文件;
5. 线程池?
线程池的核心类就是ThreadpoolExecutor类;
线程池的作用:为了在高并发的条件下,避免频繁的创建和销毁线程;
线程池的种类:
1.newCachedThreadPool创建一个可缓存线程池程
2.newFixedThreadPool创建一个定长线程池
3.newScheduledThreadPool创建一个定长线程池
4.newSingleThreadExecutor创建一个单线程化的线程池
线程池的参数或者属性:
(1)corePoolSize:线程池维护线程的最少的数量----就是核心池的大小;
(2)MaxmumPoolSize:线程池的最大容量
(3)WorkQueue:缓冲队列
(4)Handler:线程池对拒绝人物的策略;
(5)KeepAliveTime:线程池维护线程所允许的空闲时间----超过这个时间,线程就 会被终止;
(6)Unilt:线程池维护线程所允许的空闲时间的单位;
Handler处理策略:
(1)TreadPoolExecutor.AbortPolicy()-抛出java.util.concurrent.rejectedExecutionException异常;
(2)ThreadPoolExecutor.CallerRunsPolicy()---重试添加当前的任务,他会自动重复调用execute()方法;
(3)ThreadPoolExecutor.DiscardOldestPolicy()---抛弃旧的任务;
(4)ThreadPoolExecutor.DiscardPolicy()---抛弃当前任务;
讲解一下核心线程数,最大线程数和缓冲队列:
一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个Runnable类 型的对象,任务的执行方法就是Runnable类型对象的run()方法。当一个任务通过 execute(Runnable)方法欲添加到线程池时:
(1)如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲 状态,也要创建新的线程来处理被添加的任务。
(2)如果此时线程池中的数量等于corePoolSize,但是缓冲队列workQueue未满, 那么任务被放入缓冲队列。
(3)如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且 线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
(4)如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且 线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此 任务;