面试题总结

本文详细解析了HashMap的基本概念,包括初始长度、数据存储策略(基于哈希函数的碰撞解决)、扩容机制以及红黑树的使用场景。讲解了Spring MVC的DispatcherServlet流程和SQL优化技巧,还涵盖了线程池配置及状态分析,以及事务隔离级别的理解。
摘要由CSDN通过智能技术生成

hashmap原理

基本概念:

1.hashmap的初始长度

hashmap底层是一个entry数组,数组每个元素都是一个entry(键值对的形式),所以初始化一个数组的时候,java是必须要给他定义一个初始长度的。

entry[]数组的初始长度为16

2.hashmap数据的存储:

当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量

3.扩容和加载因子

根据存放数据的形式,可以知道,hashmap存放数据就好比往插槽中插入数据,当hashmap中entry[]数组的有数据的插槽占所有插槽数量的一定比例的时候,entry[]数组会自动进行扩容,这个比例就叫做加载因子。

为什么hashmap=数组+链表:

当计算的位置,有数据时,会发生hash冲突/hash碰撞
解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素
也就是说数组中的元素都是最早加入的节点

红黑树:

如果链表的长度>8且数组长度>64时,链表会转为红黑树,当链表的长度<6时,红黑树会重新恢复成链表

springmvc执行流程

底层有一个类叫做dispatcherservlet,自身维护了一个hadlermappings,在接收到httprequest请求的时候,会根据请求的内容筛选出合适的handlermapping,handlermapping包装了一些interceptors,在调用handler之前进行前处理,之后进行后处理。最后返回一个modeladnview给servlet的调用方。

sql优化

尽量不要使用like和select *

sql索引失效的情况:

1.使用like关键字时

(注意不是所有使用like的情况都会索引失效,当使用了前缀的方式模糊查询的时候, 索引并不会失效,因为没有违反最佳左前缀法则)

2、组合索引

使用组合索引时,如果查询条件不包括该组合索引全部字段或查询条件不是该组合索引左边第一个字段时,索引失效。

当使用or关键字时,or语句前后没有同时使用索引或当or关键字左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效。

3.数据类型

数据类型出现隐式转化。如某个索引字段的数据类型为varchar,查询内容为123,如不加引号的话可能会自动转换为int型,使索引无效,产生全表扫描

4.not查询

5.对索引字段使用函数

6.表内数据极少,全表查询速度比索引速度还要快的情况

线程池的参数

corePoolSize
核心线程数,这是线程空闲时可以保存的线程数,线程池刚创建时,可以指定 corePoolSize的个数,而后线程池可以创建多个线程直到到达 corePoolSize的个数,如果没有特殊设置,corePoolSize线程一创建,就不会主动销毁,即使是在空闲的时间

maximumPoolSize
最大线程数量,指的是一个线程池最多可以创建线程的个数,maximumPoolSize ≥ corePoolSize,当maximumPoolSize 的设置的大于数量 corePoolSize且线程需要创建超出 corePoolSize线程直到 maximumPoolSize个数的话,之后在线程池空闲的时间,线程池会根据 keepAliveTime参数设置的时间销毁多于 corePoolSize个数的线程

keepAliveTime
空闲线程存活时间,当线程池创建的线程数大于 corePoolSize但小于等于maximumPoolSize的时候,只要线程处于空闲的时候,线程池会根据 keepAliveTime设置的时间去销毁多出 corePoolSize个数的线程

unit
线程池设置 keepAliveTime的时间单位,上面的 FixedThreadPool默认的时间单位是 TimeUnit.MILLISECONDS,也就是毫秒级别

workQueue
阻塞队列,存放任务的工作队列,用来存放 corePoolSize处理不过来的任务

threadFactory
线程工厂,用来生产线程以便去处理任务,可以自定义适合业务的线程工厂

handler
任务拒绝策略,用来处理当 workQueue已经满且 maximumPoolSize达到最大上限的时候,用来处理新提交的任务

线程的状态

1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。

 集合的分类(线程安全)

事务的隔离级别

事务的并发问题:

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34116044

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值