YNZH's Blog

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模式,解耦

工作流程:

  1. 客户端(浏览器)发送请求,直接请求到 DispatcherServlet
  2. DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler
  3. 解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。
  4. HandlerAdapter 会根据 Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。
  5. 处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View
  6. ViewResolver 会根据逻辑 View 查找实际的 View
  7. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
  8. 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

  1. Automicity原子性
  2. Consistency一致性
  3. Isolation隔离性
  4. Durability持久性 –>

并发事务可能带来 脏读,丢失修改,不可重复读,幻读等问题

8.MySQL事务隔离级别

  1. READ-UNCOMMITTED(读未提交):允许读取尚未提交的事务数据变更,最低的隔离级别,会产生脏读,不可重复读,幻读

  2. READ-COMMITTED(读已提交):只能读取并发事务已经提交的数据变更,可以阻止脏读,但是会有不可重复读,幻读,

  3. REPEATABLE-READ(可重复度):对同一字段的多次读取数据是一致的,但是会幻读

  4. 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
2
3
4
5
6
7
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
  1. corePoolSize:最小可以同时运行的线程个数.

  2. maximumPoolSize:当等待队列满了的时候,最大可以运行的线程个数

  3. workQueue:当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。

  4. ThreadPoolExecutor 饱和策略

    抛出异常 ,直接丢弃 , 增加等待队列长度, 丢弃最早的还未处理的请求任务

线程死亡

  1. run()或者call()运行完成正常死亡
  2. 线程抛出一个未捕获的 Exception 或 Error,–>异常结束
  3. 调用stop方法结束线程,会抛出Error,会释放线程持有的所有的锁导致不可控制性

如何结束线程

  1. 正常运行完
  2. 使用boolean变量用vilatile修饰之后,若改变则退出
  3. Interrupt()方法中断线程,线程会抛出InterruptedException,然后捕获从而进去结束异常

 评论


博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Material X 作为主题 , 总访问量为 次 。
载入天数...载入时分秒...