面试总结
多线程面试题
-
线程的实现方式
继承Thread类重写run()方法
实现runnable接口
实现Callable接口通过FutureTask包装器创建Thread线程
可返回值的实现Callable 无返回值的实现runnable接口,返回值是一个阻塞线程。 -
CountDownLatch和CyclicBarrier
CountDownLatch减计数方式,CyclicBarrier加计数方式。
CountDownLatch数据为0的时候释放所有等待线程,CyclicBarrier计数达到指定值时释放等待线程
CountDownLatch变成0无法重置,CyclicBarrier达到指定值时计数重置。
CountDownLatch调用CountDown()方法减一,await()方法只阻塞,对计数器没影响,CyclicBarrier await()计数加一,若加一后值不等于构造方法的值,线程阻塞。
CountDownLatch不可重复利用,CyclicBarrier可重复利用。 -
Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的情况下尤其重要。Java内存模型对一个线程所做的变动能被其它线程可见提供了保证,它们之间是先行发生关系。这个关系定义了一些规则让程序员在并发编程时思路更清晰。比如,先行发生关系确保了:
线程内的代码能够按先后顺序执行,这被称为程序次序规则。
对于同一个锁,一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前,也叫做管程锁定规则。
前一个对volatile的写操作在后一个volatile的读操作之前,也叫volatile变量规则。
一个线程内的任何操作必需在这个线程的start()调用之后,也叫作线程启动规则。
一个线程的所有操作都会在线程终止之前,线程终止规则。
一个对象的终结操作必需在这个对象构造完成之后,也叫对象终结规则。
可传递性
Java内存模型是围绕着并发编程中原子性、可见性、有序性
原子性(Atomicity):一个操作不能被打断,要么全部执行完毕,要么不执行。在这点上有点类似于事务操作,要么全部执行成功,要么回退到执行该操作之前的状态。
可见性:一个线程对共享变量做了修改之后,其他的线程立即能够看到(感知到)该变量这种修改(变化)。
可见性实现:volatile,Lock(lock()和unlock()加锁从共享内存拿出解锁将数据放入主内存),synchornized,final
有序性:对于一个线程的代码而言,我们总是以为代码的执行是从前往后的,依次执行的。这么说不能说完全不对,在单线程程序里,确实会这样执行;但是在多线程并发时,程序的执行就有可能出现乱序。用一句话可以总结为:在本线程内观察,操作都是有序的;如果在一个线程中观察另外一个线程,所有的操作都是无序的。前半句是指“线程内表现为串行语义(WithIn Thread As-if-Serial Semantics)”,后半句是指“指令重排”现象和“工作内存和主内存同步延迟”现象。
-
线程通信
- 共享变量
- wait notify
- Lock/Condition机制
- 管道机制
-
Semaphore信号量
acquire()
release() -
ThreadLocal一般称为线程本地变量,它是一种特殊的线程绑定机制,将变量与线程绑定在一起,为每一个线程维护一个独立的变量副本。通过ThreadLocal可以将对象的可见范围限制在同一个线程内。
-
多线程死锁
-
ReentrantLock
1.等待可中断,持有锁的线程长期不释放的时候,正在等待的线程可以选择放弃等待,这相当于Synchronized来说可以避免出现死锁的情况。
2.公平锁,多个线程等待同一个锁时,必须按照申请锁的时间顺序获得锁,Synchronized锁非公平锁,ReentrantLock默认的构造函数是创建的非公平锁,可以通过参数true设为公平锁,但公平锁表现的性能不是很好。 3.锁绑定多个条件,一个ReentrantLock对象可以同时绑定对个对象。
-
线程池ThreadPoolExecutor的常用参数
corePoolSize:核心线程数
queueCapacity:任务队列容量(阻塞队列)
maxPoolSize:最大线程数
keepAliveTime:线程空闲时间
allowCoreThreadTimeout:允许核心线程超时
rejectedExecutionHandler:任务拒绝处理器
java虚拟机面试题
java虚拟机结构
如何判断对象是否死亡(两种方法)。
引用计数法
可达性分析
简单的介绍一下强引用、软引用、弱引用、虚引用(虚引用与软引用和弱引用的区别、使用软引用能带来的好处)。
垃圾收集有哪些算法,各自的特点?
标记-清除算法
标记-压缩-清除算法
复制算法
分代收集算法
HotSpot为什么要分为新生代和老年代?
常见的垃圾回收器有那些?
介绍一下CMS,G1收集器。
Minor Gc和Full GC 有什么不同呢?
新生代GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC非常频繁,回收速度一般也比较快。
老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC的慢10倍以上。
JVM调优的常见命令行工具有哪些?
简单说说类加载过程,里面执行了哪些操作?
加载、验证、准备、解析、初始化、使用、卸载
对类加载器有了解吗?
启动类加载器(Bootstrap ClassLoader)
扩展类加载器(Extension ClassLoader)
应用程序类加载器(Application ClassLoader)
什么是双亲委派模型?
双亲委派模型的工作过程以及使用它的好处。
-
分布式锁
基于redis的分布式事务锁
创建一张锁表,锁资源的时候就加一条数据,释放就删除掉
基于for update 排它锁
基于数据库分布式锁
基于zookeeper的分布式锁 -
分布式事务解决方案
1.全局消息
2.基于可靠消息服务的分布式事务
3.TCC
try 完成一致性检查 并不执行事务
confirm 执行事务
cancel 若业务执行失败 释放所占的资源 并回滚
4.最大努力通知 -
数据库优化 索引优化
索引创建原则
经常搜索的条件上
经常连接的列上加外键
范围搜索索引
需要排序的列上加索引
不应该在经常修改的地方创建索引
不能再数据值很少地方创建索引
不要大文本或者bit类型创建索引索引失效
or会失效索引
联合索引如果不是使用的第一个也会失效
like %开头不会使用索引 %结尾会使用索引
大于等于索引失效
字符串不加引号也会索引失效sql优化
子查询转换成left join 查询
in exists 转换成 inner join
in 用exists代替
尽量使用索引
索引不能使用函数,不要对索引拼接 -
控制spring bean的加载顺序
@DependsOn -
jvm面试题
方法区,堆 栈 计数器
触发垃圾回收的情况
System.gc()方法的调用
新生代内存不足
老年代内存不足
堆中分配很大的对象的时候 -
Spring配置事务的方式
1.编程式事务 明确的需要控制事务的边界,
2.声明式事务 粗粒度实现事务管理事务的隔离级别
默认隔离级别,这时候使用的是数据库自己的隔离级别
读未提交:无法防止 脏读 幻读 不可重复读
读已提交:无法防止幻读,不可重复读
可重复读:无法防止幻读
串行化:最慢的一种
a.脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏 数据所做的操作肯能是不正确的。
b.不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事 物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。
c.幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中) -
mysql存储过程
-
存储过程回滚
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK ;
-
顺序 declare-start/begin-prepare-execute-commit-end
-
-
mysql两种索引区别,B+索引和hash索引
B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接。
在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。
因此,B+树索引被广泛应用于数据库、文件系统等场景。顺便说一下,xfs文件系统比ext3/ext4效率高很多的原因之一就是,它的文件及目录索引结构全部采用B+树索引,而ext3/ext4的文件目录结构则采用Linked list, hashed B- tree、Extents/Bitmap等索引数据结构,因此在高I/O压力下,其IOPS能力不如xfs。简单地说,哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。
10。红黑树时间复杂度O(lgn)
-
ArrayList的最大长度 Integer.MAX_VALUE-8;默认构造大小是10. 默认扩容1.5倍
-
LinkedList 双向链表实现的
-
set如何实现去重的 底层使用HashMap实现,key不会重复