基础面试题

  • HashMap和Hashtable的区别
答案:1.继承的父类不同 2.Hashtable线程安全,HashMap不安全 3.Hashtable key不能为空,HashMap可以
HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75。
HashMap扩容时是当前容量翻倍即:capacity*2,Hashtable扩容时是容量翻倍+1即:capacity*2+1。
  • ArrayList、LinkedList、Vector的区别
答案: ArrayList:数组 Vector:数组 LinkedList:双向链表
Vector:线程安全,ArrayList:非线程安全,LinkedList:非线程安全
在需要频繁读取集合中的元素时,更推荐使用 ArrayList, 而在插入和删除操作较多时,更推荐使用 LinkedList。
  • HashMap和LinkedHashMap的区别
答案:LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的。
HashMap无序;LinkedHashMap有序 , LinkedHashMap是线程不安全的。
一般情况下,我们用的最多的是HashMap,在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,
那么TreeMap会更好。如果需要输出的顺序和输入的相同,那么用LinkedHashMap 可以实现,它还可以按读取顺序来排列.
  • 创建线程的3种方式
答案:继承Thread类创建线程,实现Runnable接口,通过Callable和Future创建线程
  • wait方法和sleep方法的区别
答案:sleep()睡眠时,保持对象锁,仍然占有该锁;     而wait()睡眠时,释放对象锁。
  • synchronized、Lock、ReentrantLock、ReadWriteLock
答案:synchronized 用于同步方法和代码块,执行完后自动释放锁
Lock是一个锁的接口,提供获取锁和解锁的方法(lock,trylock,unlock)
ReentrantLock 重入锁
ReadWriteLock 读写锁 它可以实现读写锁,当读取的时候线程会获得read锁,其他线程也可以获得read锁同时并发的去读取,但是写程序运行获取到write锁的时候,其他线程是不能进行操作的,因为write是排它锁,而上面介绍的两种不管你是read还是write没有抢到锁的线程都会被阻塞或者中断,它也是个接口,里面定义了两种方法readLock()和writeLock(),
  • 介绍下CAS(无锁技术),什么是悲观锁和乐观锁
答案:
乐观锁:总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作实现。
悲观锁:总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在Java中,synchronized的思想也是悲观锁
CAS 无锁模式:CAS算法的过程是这样:它包含三个参数CAS(V,E,N): V表示要更新的变量,,N表示新值。仅当V值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后,CAS返回当前V的真实值。
CAS操作是抱着乐观的态度进行的,它总是认为自己可以成功完成操作。当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败。失败的线程不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。基于这样的原理,CAS操作即使没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。
  • volatile关键字的作用和原理
答案: 1 保证内存可见性 , 当对非volatile变量进行读写的时候,每个线程先从主内存拷贝变量到CPU缓存中,如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以拷贝到不同的CPU cache中。
volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,保证了每次读写变量都从主内存中读,跳过CPU cache这一步。当一个线程修改了这个变量的值,新值对于其他线程是立即得知的。
2 禁止指令重排
1为instance分配内存
2初始化instance 初始值 0
3将instance变量指向分配的内存空间 赋值 8
由于JVM可能存在重排序,上述的二三步骤没有依赖的关系,可能会出现先执行第三步,后执行第二步的情况。也就是说可能会出现instance变量还没初始化完成,其他线程就已经判断了该变量值不为null,结果返回了一个没有初始化完成的半成品的情况。而加上volatile关键字修饰后,可以保证instance变量的操作不会被JVM所重排序,每个线程都是按照上述一二三的步骤顺序的执行,这样就不会出现问题。
  • 分布式环境下,怎么保证线程安全
避免并发,时间戳,串行化,数据库,行锁
  • synchronized和lock区别以及volatile和synchronized的区别
  • MQ作用
答案:解耦,异步,销峰