Java多线程
1、线程池的原理,为什么要创建线程池?
答:1)线程池可以降低创建和销毁线程时的资源消耗,提高响应速度,提高现成的可管理性。
2)线程池构造参数:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:空闲时间
unit:空闲时间单位
workQueue:任务等待队列。ArrayBlockingQueue(有界);SynchronousQueue(容量为1);LinkedBlockingQueue(无界)
threadFactory:线程工厂
handler:任务拒绝策略。丢弃并抛异常(默认策略);丢弃但不抛异常;丢弃最前面的任务;由调用线程处理该任务
3)几个参数之间的关系。corePoolSize>workQueue>maximumPoolSize>reject
2、线程的生命周期,什么时候会出现僵死进程;
答:1)new -> runnable -> running -> block -> dead
2)两个线程相互等待对方释放锁时,会出现僵死现象
3、什么是现线程安全,如何实现线程安全;
答:1)多线程并发访问共享资源时,能保证结果正确
2)可通过阻塞同步(加锁);非阻塞同步(CAS);避免共享资源(session、threadLocal)
4、java线程池如何合理配置核心线程数?
答:1)获取CPU核数。Runtime.getRuntime().availableProcessors()
2)分析程序属于CPU密集型还是IO密集型?
CPU密集型,核心线程数=CPU核数+1。减少花在任务切换上的时间
IO密集型,核心线程数=CPU核心数*2。线程越多,CPU利用率越高
5、synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;
答: 1)死锁产生的条件:
互斥条件;环路等待;保持条件;不剥夺条件
2)synchronized锁粒度:无锁、偏向锁、轻量锁、重量锁
JVM相关
1、JVM内存模型
答:1)内存划分:堆、栈(java、本地)、方法区、计数器。方法区存放类信息、静态变量、常量、运行时常量池;堆主要放数组、对象、字符串常量池;栈是方法运行过程的内存模型。
方法区和堆都是线程共享的,栈和计数器是线程数有的。
2)JVM内存模型,和Java虚拟机运行时区域有关;JAVA内存模型是JAVA并发编程有关。
3)JAVA内存模型:主存(变量) -> 本地内存(变量副本) -> CPU(使用)
4)缓存一致性协议:
5)工作内存与主内存交互:
lock(锁定) -> read(读取) -> load(载入) -> use(使用) -> assign(赋值) -> store(存储) -> write(写入) -> unlock(解锁)
6)内存屏障(Memory barrier):是一种CPU指令,可以让CPU在内存访问上有序,保证屏障之前的指令会先于屏障之后的指令执行,用于控制特定条件下的重排序和内存可见性问题
7)指令重排序:为提高效率,程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致
2、JVM里的有几种classloader,为什么会有多种?
答:BootstrapClassLoader -> ExtensionClassLoader -> AppClassLoader -> UserDefinedClassLoader
1)BootstrapClassLoader,负责加载<JAVA_HOME>/lib下的class,开发者不可以直接使用
2) ExtensionClassLoader,负责加载<JAVA_HOME>/lib/ext下的class,开发者可以直接使用
3)AppClassLoader,负责加载用户的class
3、java类加载机制、亲委派机制、双亲委派模型的好处?
答:1)类加载的几个阶段:加载、连接(验证、准备、解析)、初始化、使用、卸载。加载的目的是为了获取该类的二进制流
2)双亲委派:如果一个类加载器收到一个类加载的请求,会先将该请求委托给父级类加载器去加载,每一层都是如此。只有父类反馈无法完成这个加载请求时(它的搜索范围内找不到这个类),才会向下委托给子类加载器去加载。
3)双亲委派的好处:自己写的String.java不会覆盖系统的String.java,进而保护系统内部代码。
4、什么情况下我们需要破坏双亲委派模型;
答:1)Tomcat的WebAppClassLoader只会加载自己目录下的class文件,不会交给父类。因为一个Tomcat可以同时装载多个webapp,可防止jar包冲突
2)根据类加载机制,当被装载的类引用了另外一个类的时候,虚拟机就会使用装载第一个类的类装载器装载被引用的类。JDBC的Driver接口定义在JDK中,DriverManager也在JDK中,Driver实现类则在各厂商的实现包中,需要子类去加载。
5、常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?
答:1)给新生代合理的空间,尽量避免新对象直接进入到老年代
2)大对象进入老年代,减少新生代对大对象的GC。 -XX:PretenureSizeThreshold 设置大对象直接进入老年代的阀值
3)设置对象进入老年代的年龄。-XX:MaxTenuringThreshold:默认值是15
6、什么时候触发FullGC?什么时候触发MinorGC(YoungGC)?
答:1)主动调用System.gc();
2) 老年代不足、持久代不足
3) YoungGC出现promotion failure
4)稳定对大小。设置 -Xmx 和 -Xms 一样的值。
7、JVM垃圾收集算法、垃圾收集器、class文件结构是如何解析的
答:1)垃圾回收算法:
a) 标记-清除算法:分成标记阶段(将要回收的做标记)和清除阶段(将标记的清除)。优点:简单易实现。缺点:碎片多,导致大对象空间不足触发垃圾回收。
b) 标记-整理算法:将内存划分为大小相等的两块,标记并复制到另一块区域。优点:内存利用率高。缺点:空间占用大;如果存活对象很多,复制效率低下。
c) 复制算法:将存活的对象复制到另一个区域
d) 分代收集算法:根据对象生命周期划分为多个区域,新生代(Eden8、Survivor1:1,复制算法)、老年代(标记整理)、永久代。
Java扩展
1、红黑树的实现原理和应用场景;
2、NIO是什么?适用于何种场景?
3、Java9比Java8改进了什么;
4、HashMap内部的数据结构是什么?底层是怎么实现的?
5、说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;
6、说说自定义注解的场景及实现;
7、List和Map区别,Arraylist与LinkedList区别,ArrayList与Vector 区别;
Spring
1、Spring AOP的实现原理和场景;(应用场景很重要)
2、Spring bean的作用域和生命周期;
3、Spring Boot比Spring做了哪些改进?Spring 5比Spring4做了哪些改进;(惭愧呀,我们还在用Spring4,高版本的没关心过)
4、Spring IOC是什么?优点是什么?
5、SpringMVC、动态代理、反射、AOP原理、事务隔离级别;
中间件
1、Dubbo完整的一次调用链路介绍;
2、Dubbo支持几种负载均衡策略?
3、Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?
4、Dubbo启动的时候支持几种配置方式?
5、了解几种消息中间件产品?各产品的优缺点介绍;
6、消息中间件如何保证消息的一致性和如何进行消息的重试机制?
7、Spring Cloud熔断机制介绍;
8、Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?
数据库篇
1、锁机制介绍:行锁、表锁、排他锁、共享锁;
2、乐观锁的业务场景及实现方式
3、事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;
4、MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?
5、MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;
6、分布式事务的原理2阶段提交,同步\异步\阻塞\非阻塞;
7、数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、
8、JDBC如何实现事务、嵌套事务实现、分布式事务实现;
9、SQL的整个解析、执行过程原理、SQL行转列;
Redis
1、Redis为什么这么快?redis采用多线程会有哪些问题?
2、Redis支持哪几种数据结构;
3、Redis跳跃表的问题;
4、Redis单进程单线程的Redis如何能够高并发?
5、Redis如何使用Redis实现分布式锁?
6、Redis分布式锁操作的原子性,Redis内部是如何实现的?
Tomcat
1、Tomcat类加载机制
答案:
1)Tomcat不遵循双亲委派模型;
2)隔离性。同一个Tomcat可同时装载不同版本的jar包,互不影响
2、Tomcat架构 Server >> Service >> *Connector & Container >> Host/Engine/Context
技术四面面试题如下
一面(问了数据结构、jvm、锁等):
HashMap底层如何实现?
Hash一致算法?
说说HashMap和ConcurrentHashMap的区别?treemap和HashMap的区别?
java的内存分区?
java对象的回收方式,回收算法?
CMS和G1了解吗?
CMS解决什么问题,说一下回收的过程?
CMS回收停顿了几次?
java栈什么时候会内存溢出,java堆呢,说一种场景?
集合类如何解决这个问题(软引用和弱引用),讲下这个两个引用的区别?
java里的锁了解哪些?
synchronized锁升级的过程(偏向锁到轻量锁再到重量级锁),分别如何实现的,解决的是哪些问题?
Tomcat的基本架构是什么?
什么是类加载器?
说说双亲委派模型机制?
GC的机制是什么?GC算法和回收策略?
二面(线程、数据库、缓存、协议等):
线程池由哪些组件组成?
有哪些线程池,分别怎么使用?拒绝策略有哪些?
什么时候多线程会发生死锁,写一个例子?
Redis的数据结构是什么?线程模型说一下?
讲讲Redis的数据淘汰机制?
说说Redis的数据一致性问题?
Redis的分布式怎么做?
RPC讲一下?
三次握手和四次挥手?如果没有三次握手有问题吗?
Http请求过程,DNS解析的过程?
InnoDB支持的四种事务隔离级别名称是什么?有什么区别?说说MySQL隔离级别?
事务的特性及慢查询?
BTree机制说一下?
说说MySQL常用的优化方法?
三面(分布式,消息队列等):
cap了解吗,分别指什么?
强一致性和弱一致性有什么方法来实现的?
负载均衡怎么实现?为什么这么做?
缓存雪崩说下?
MySQL主从复制怎么实现的?具体原理是什么?有什么优缺点?
讲讲分布式事务?
消息队列,用到什么场景(削峰,限流,异步)?
zk的性能瓶颈怎么克服?
讲了下kafka,怎么保证数据不丢失?确保消息不会重复消费?
消息送达确认是怎么实现的?