1、LinkedList和ArrayList的区别
2、List是否可以存放null,Map中key是否可以为null
3、类加载过程
加载,验证,准备(为类变量<static修饰的>分配内存及赋默认值),解析,初始化(为static变量赋定义的值,执行static代码块等)
启动类加载器(BootstrapClassLoader):加载$JAVA_HOME\lib目录下的,并且是虚拟机识别的类库
扩展类加载器(ExtensionClassLoader):$JAVA_HOME\lib\ext下的所有类库,开发者可以直接使用
应用程序类加载器(ApplicationClassLoader):加载用户类路径上的制定的类库,开发者可以直接使用,一般情况下这个就是程序中默认的类加载器
4、静态变量什么时候初始化
5、一个账号,同时往里存钱,如何保证最后余额的准确性
第一反应是通过select ... for update将行数据加排他锁。
面试之后想到可以使用CAS无锁机制进行更新,通过版本号进行验证更新时是否一致。该方案不适合并发特别高的情况。
分布式锁
6、垃圾回收相关
分代收集:新生代,老年代
新生代使用复制算法
老年代使用标记清楚或标记整理算法,看具体jvm的实现
7、事务隔离级别
ISOLATION_DEFAULT:默认的隔离级别,使用数据库默认的事务隔离级别
ISOLATION_READ_UNCOMMITTED:允许另一个事务可以看到这个事务的未提交数据。可产生脏读,不可重复读和幻读。
ISOLATION_READ_COMMITTED:一个事务修改的数据提交后另一个事务才可读到。可避免脏读,可能会出现不可重复读和幻读
ISOLATION_REPEATABLE_READ:可防止脏读,不可重复读。可能会产生幻读
ISOLATION_SERIALIZABLE:可避免脏读,不可重复读,幻读。事务被处理为必须顺序执行,代价最高,会锁表。
MySQL的默认隔离级别为:REPEATABLE_READ
不可重复读和幻读区别要点:不可重复读主要针对update和delete;幻读主要针对insert,返回查询
8、事务传播机制
9、LCN框架保证分布式事务CAP
10、mybatis缓存机制
一级缓存:也称为本地缓存,用于保存用户在一次会话过程中查询的结果,用户一次会话中只能使用一个sqlSession,一级缓存是自动开启的,不允许关闭。
一级缓存失效原因:1、使用不同的sqlSession进行查询;2、使用不同条件查询;3、两次查询之间有有数据修改操作;4、手动刷新缓存
注意问题:1、生命周期与sqlSession一致;2、多个sqlSession情况下可能脏读;3、mybatis和spring整合后进行mapper代理开发,不支持一级缓存
二级缓存:也称为全局缓存,是mapper级别的缓存,是针对一个表的查结果的存储,可以共享给所有针对这张表的查询的用户。也就是说对于mapper级别的缓存不同的sqlsession是可以共享的。
11、SpringBootApplication注解
组合注解
SpringBootConfiguration--读取配置文件,配置文件的路径是当前根目录(src/main/resources/application.yml等)
EnableAutoConfiguration--开启自动配置
ComponentScan--组件扫描
12、HashMap实现原理
之前看了一篇文章,有一句话我觉得可以记住:数据结构都是由数组和链表组合演变而成的。HashMap的数据结构可以看成,整体为数组,每个位置可能由多个或一个Node组成,多个Node之间记录了应用,构成了链表。
看HashMap的变量,table是一个Node数组,threshold是容量阈值,loadFactor是加载因子。
简单看下Node类,为HashMap中的内部类。hash为对K取的哈希值,next为下一个Node的引用(构成了链表)
从构造方法看:有四个,主要看前三个。能看出默认加载因子为0.75,容量阈值为0或者根据提供paramInt计算。注意,此时table为null-即为null的数组,没有初始化。
put方法,hash方法就先跳过;第一次放值时,会进行resize,初始化了Node数组。经过数组长度-1和hash值进行位与运算得出数组下标后,判断当前下标是否有值,如为null,将Node放入数组中;不为null,进行链表追加
13、ArrayList动态扩容
我记得之前看网上的源码分析,ArrayList的默认长度是10,今天看了下源码jdk1.8发现不是那么回事。
构造方法主要有三个,看下无参构造,当不指定容量时,能看到是创建了个空数组。这个时候你去调用set方法,就会得到一个IndexOutOfBoundsException异常。
这是只能通过add方法添加元素。经过计算,取用的DEFAULT_CAPACITY--10,这时,数组大小为10。可以debug跟踪下。发现添加一个元素后,数组大小发生了变化。
此时调用ensureExplicitCapacity方法,传进的参数为10,而elementData还是一个0数组,所以调用grow方法
grow方法能看出是是对数组进行了拷贝,从而实现了ArrayList的动态扩容。容量每次扩容的大小为 oldCapacity>>1,可以简单的理解为原来的1.5倍左右。
14、线程池简单知识
核心参数:core,maxsize,working queue
拒绝策略:丢弃报错,丢弃,丢弃第一个加入最新,由调度线程执行任务
15、redis简单
单线程快:内存数据库,避免了线程频繁切换,多路复用
16、SpringBoot-配置文件优先级
①命令行参数
②来自java:comp/env的JNDI属性
③JAVA的系统的环境属性(System.getProperties())
④系统环境变量
⑤jar包外部的application-xxx.properties或yml文件
⑥jar包内部的application-xxx.properties或yml文件
⑦jar包外部的application.properties或yml文件
⑧jar包内部的application.properties或yml文件
其中bootstrap.properties> bootstrap.yml>application.properties>application.yml