个人总结
个人瞎写,仅供参考;部分转载,逐渐完善。
- Java基础
- Java 并发
- Spring
- Netty
- 分布式相关
- 数据库
- 缓存
- JVM
Java基础
1. List、Set、Map的区别
list和set是实现了collection接口,map不是collection的子接口或者实现类,Map是一个接口。
List:
1.可以允许重复的对象。
2.可以插入多个null元素。
3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。
Set:
1.不允许重复对象
2. 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
3. 只允许一个 null 元素
4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。
Map:
1.Map不是collection的子接口或者实现类。Map是一个接口。
2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
2. HashSet 是如何保证不重复的
首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素;
如果已存在则调用Object对象的equals方法判断是否返回true,如果为true则说明元素已经存在,如为false则插入元素。
3.HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)?
不是线程安全的,当A、B两个线程,将数据同时put到同一个HashMap中,会引起碰撞,造成数据被覆盖。
4.HashMap 的扩容过程
5.HashMap 1.7 与 1.8 的 区别,说明 1.8 做了哪些优化,如何优化的?
switch支持String类型;
int、short、long、byte 可以用二进制表示;
新增Lambda表达式;
HashMap中,1.7中当HashCode值相同时,会将数据排成链表,查询时间复杂度比较高,需要遍历链表;1.8中当链表过长时,会将链表扩展成红黑树,使查询效率变高。
6.final finally finalize
final关键字,可以修饰类、方法、变量。修饰类,这个类不能被继承;修饰方法,这个方法不能被重写;修饰变量,需要在声明变量时,赋初始值,之后不能修改。
finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。
finalize是方法名。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
7.强引用 、软引用、 弱引用、虚引用
强引用实际使用中大多数是强引用,String str = “abc”; list.add(str);
软引用,jvm在内存中有高速缓存,将对象放到里面,读取数据时,提高运行效率;
8.Java反射
Java利用现有对象方法,获取当前对象的某些属性,例如:Object类的getClass()方法
9.Arrays.sort 实现原理和 Collection 实现原理
10.LinkedHashMap的应用
LinkedHashMap是在HashMap基础上新增了双向链表,用于保存迭代顺序。
下图红线是双向链表,去除红线以外的结构,是HashMap的结构。
12、异常分类以及处理机制
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。
runtimeException子类:
java.lang.ArrayIndexOutOfBoundsException数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.NullPointerException空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等
java.lang.ClassNotFoundException找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
IOException子类:
IOException:操作输入流和输出流时可能出现的异常。
FileNotFoundException 文件未找到异常
其他类:
SQLException:操作数据库异常类
StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
13、wait和sleep的区别
wait()方法属于Object类;sleep()方法属于Thread类;
调用wait()方法的过程中,线程会释放对象锁;调用sleep()方法的过程中,线程不会释放对象锁。
14、数组在内存中如何分配
//定义第一个数组
int[] arr=new int[3];
arr[0]=10;
arr[1]=20;
arr[2]=70;
第一步:栈存储局部变量(在方法定义中或方法声明上的变量),所以int[] arr 存放在了栈中;
第二步:new出的变量放在堆中,所以new int【3】在堆中。
第三步:每一个new出来的东西都有地址值(系统随机分配),所以new int【3】的地址值为0x001;把0x001赋给arr,在栈中的数组通过地址值找到堆中相应的地址。用数组名和编号的配合就可以找到数组中指定编号的元素,这种方法就叫做索引。
第四步:int类型的数据默认值为0
第五步:给数组中的每个元素赋值,把原先的默认值0干掉。
Java 并发
1、synchronized 的实现原理以及锁优化?
2、volatile 的实现原理?
4、synchronized 在静态方法和普通方法的区别?
5、怎么实现所有线程在等待某个事件的发生才会去执行?
闭锁CountDownLatch
闭锁是典型的等待事件发生的同步工具类,将闭锁的初始值设置1,所有线程调用await方法等待,当事件发生时调用countDown将闭锁值减为0,则所有await等待闭锁的线程得以继续执行。
7、synchronized 和 lock 有什么区别?
synchronized是java关键字;Lock是一个类;
synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象;
多个线程进行读操作,用synchronized锁,当一个线程在进行读操作时,其他线程只能等待无法进行读操作;用lock锁,线程之间不会发生冲突,可以进行读操作;
通过Lock可以知道线程有没有成功获取到锁,synchronized没办法知道;
9、HashMap 的并发问题?
HashMap在高并发下可能引起死循环,造成cpu占用过高。
假如有两个线程P1、P2,以及链表 a=》b=》null
P1先运行,运行完"Entry<K,V> next=e.next;"代码后发生堵塞,或者其它情况不再运行下去,此时e=a。next=b
而P2已经运行完整段代码,于是当前的新链表newTable[i]为b=》a=》null
P1又继续运行"Entry<K,V> next=e.next;
"之后的代码,则运行完"e=next;"后,newTable[i]为a《=》b。则造成回路,while(e!=null)一直死循环
10、ConcurrenHashMap 介绍?1.8 中为什么要用红黑树?
ConcurrenHashMap锁方式是稍微细粒度的,内部采用分离锁(分段锁)的设计。它默认将Hash表分为16个分段,get,put,remove等常用操作只锁当前需要用到的分段;
JDK1.8相较1.7,当链表长度大于8时,会将链表结构转成红黑树,便于大数据量的查询,使时间复杂度由O(n)变成O(logN)
12、如何检测死锁?怎么预防死锁?
分析代码;
用jstack工具查找,jstack是java虚拟机自带的一种堆栈跟踪工具;
加锁顺序(线程按照一定的顺序加锁)
加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
死锁检测
13、Java 内存模型?
14、如何保证多线程下 i++ 结果正确?
使用锁机制,实现i++原子操作:
public static ReentrantLock lock = new ReentrantLock();
或者
synchronized (SynchronizedTest.class) {
count++;
}
15、线程池的种类,区别和使用场景?
newCachedThreadPool:执行很多短期异步的小程序或者负载较轻的服务器
newFixedThreadPool:执行长期的任务,性能好很多
newSingleThreadExecutor:一个任务一个任务执行的场景
NewScheduledThreadPool:周期性执行任务的场景
16、分析线程池的实现原理和线程的调度过程?
17、线程池如何调优,最大数目如何确认?
N为CPU核心数
CPU密集型:N + 1
IO密集型:2N + 1
18、ThreadLocal原理,用的时候需要注意什么?
19、CountDownLatch 和 CyclicBarrier 的用法,以及相互之间的差别?
23、分段锁的原理,锁力度减小的思考
Spring
1、BeanFactory 和 FactoryBean?
2、Spring IOC 的理解,其初始化过程?
3、BeanFactory 和 ApplicationContext?
4、Spring Bean 的生命周期,如何被管理的?
5、Spring Bean 的加载过程是怎样的?
6、如果要你实现Spring AOP,请问怎么实现?
7、如果要你实现Spring IOC,你会注意哪些问题?
8、Spring 是如何管理事务的,事务管理机制?
9、Spring 的不同事务传播行为有哪些,干什么用的?
10、Spring 中用到了那些设计模式?
11、Spring MVC 的工作原理?
12、Spring 循环注入的原理?
13、Spring AOP的理解,各个术语,他们是怎么相互工作的?
14、Spring 如何保证 Controller 并发的安全?
Netty
1、BIO、NIO和AIO
BIO:同步阻塞I/O 1.4之前只有BIO 适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中
NIO:同步非阻塞I/O 1.4开始有NIO 适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器
AIO:异步非阻塞I/O 1.7开始有AIO 适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器