1. 集合类有哪些,有什么区别?
集合
collection
List
ArrayList
底层是动态数组,线程不安全的,可以实现顺序访问,扩容当前容量*1.5倍
Vector
底层是动态数组,线程安全的,可以实现顺序访问,扩容当前容量*2倍
LinkedList
底层是双向链表,线程不安全的,增删快,查询慢,可以当作堆栈队列使用
Set
HashSet
底层使用hashmap,无重复元素
TreeSet
内部是treemap,,有序的,无重复元素
LinkedHashSet
内部是linkedHashMap.记录数据的插入顺序
Queue
两端出入的List,可以使用LinkedList实现
Map
HashMap
entry数组,键值对的形式,线程不安全,允许key和value为null,1.7使用putForNUll,1.8中key为nullhashcode=0
HashTable
key和value都不允许为null,线程安全
TreeMap
底层二叉树实现的
ConcurrentHashMap
锁的粒度更低的线程安全的map
LinkedHashMap
继续插入顺序的HashMap
2. SpringMVC原理 流程
MVC模式,解耦
工作流程:
- 客户端(浏览器)发送请求,直接请求到
DispatcherServlet
。 DispatcherServlet
根据请求信息调用HandlerMapping
,解析请求对应的Handler
。- 解析到对应的
Handler
(也就是我们平常说的Controller
控制器)后,开始由HandlerAdapter
适配器处理。 HandlerAdapter
会根据Handler
来调用真正的处理器开处理请求,并处理相应的业务逻辑。- 处理器处理完业务后,会返回一个
ModelAndView
对象,Model
是返回的数据对象,View
是个逻辑上的View
。 ViewResolver
会根据逻辑View
查找实际的View
。DispaterServlet
把返回的Model
传给View
(视图渲染)。- 把
View
返回给请求者(浏览器)
3. IOC和AOP
4.JVM内存分布
运行时数据区:
线程共享
堆内存(新生代(eden,from survivor, to survivor),老年代),方法区(永久代)
线程私有
虚拟机栈VM Stack,本地方法栈(Nativa Method Stack),程序计数器PC
直接内存(不受GC管理)
类加载子系统, 执行引擎, 本地库接口
5.Spring原理
6.mysql的引擎,索引结构,索引有哪些类型?
7.MySQL的事务四大特性ACID
- Automicity原子性
- Consistency一致性
- Isolation隔离性
- Durability持久性 –>
并发事务可能带来 脏读,丢失修改,不可重复读,幻读等问题
8.MySQL事务隔离级别
READ-UNCOMMITTED(读未提交):允许读取尚未提交的事务数据变更,最低的隔离级别,会产生脏读,不可重复读,幻读
READ-COMMITTED(读已提交):只能读取并发事务已经提交的数据变更,可以阻止脏读,但是会有不可重复读,幻读,
REPEATABLE-READ(可重复度):对同一字段的多次读取数据是一致的,但是会幻读
SERIALIAZABLE(可串行化):最高的隔离级别,完全遵循ACID
MySQL 中InnoDB事务默认隔离级别是 可重复读.但是不同于SQL事务隔离级别的是他已经保证了可以避免幻读所以已经完全达到SQL中事务的SERIALAIAZABLE串行化级别.
9.mysql 的共享锁和排它锁
可以是表级或者行级的共享锁或者排他锁
共享锁ShareLock
又称为读锁,任何事务都不能获取数据的排他锁,直到所有的读锁释放之后
排他锁Exclusive Lock
又称为写锁,是要一个事务获得了排他锁只有他能进行读写,其他任何事务都不能进行操作,直到释放排他锁
IS意向共享锁
当一个事务需要读一个已经上了排他锁的行时,无法获取共享锁,可以给该表添加一个意向共享锁,可以是多个
IX意向排他锁
当一个事务需要获取一个已经上了共享锁的行时,可以为该表获取一个意向排他锁
10.mybatis如何防止sql注入
11.设计模式会吗,单例设计模式?
12.mybatis如何防止sql注入
使用#{id},会对SQL语句进行编译的时候用?代替,然后使用预编译好的statement语句设置好参数.
而是用${},不会参与编译直接静态替换.
13.如何创建线程,线程池的创建
1.继承Thread类
2.实现Runnable接口
3.使用线程池技术
传入Runnable子类或者Callable(1.5引入的)子类(有返回值Future对象).
submit和execute方法的区别
使用线程池的Future future = ThreadPool.submit(Callable c); Submit方法是提交就会要求有返回值当如Future.get拿到
ThreadPool.execute(Runnable a); Execute只管执行就行不需要返回值.
线程池的创建方式
Executors 返回线程池对象的弊端如下:
- FixedThreadPool 和 SingleThreadExecutor : 允许请求的队列长度为 Integer.MAX_VALUE ,可能堆积大量的请求,从而导致OOM。
- CachedThreadPool 和 ScheduledThreadPool : 允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建大量线程,从而导致OOM。
- 以上都是通过调用ThreadPoolExecutor的构造方法创建的线程池.
使用 ThreadPoolExecutor创建
1 | public ThreadPoolExecutor(int corePoolSize, |
corePoolSize:最小可以同时运行的线程个数.
maximumPoolSize:当等待队列满了的时候,最大可以运行的线程个数
workQueue:当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
ThreadPoolExecutor
饱和策略抛出异常 ,直接丢弃 , 增加等待队列长度, 丢弃最早的还未处理的请求任务
线程死亡
- run()或者call()运行完成正常死亡
- 线程抛出一个未捕获的 Exception 或 Error,–>异常结束
- 调用stop方法结束线程,会抛出Error,会释放线程持有的所有的锁导致不可控制性
如何结束线程
- 正常运行完
- 使用boolean变量用vilatile修饰之后,若改变则退出
- Interrupt()方法中断线程,线程会抛出InterruptedException,然后捕获从而进去结束异常