面试总结-整理新

基础篇

基本功

一、Hashcode的做用,与 equal 有什么区别?html

  a.一样用于鉴定2个对象是否相等的,java集合中有 list 和 set 两类,其中 set不容许元素重复实现,那个这个不容许重复实现的方法,若是用 equal 去比较的话,若是存在1000个元素,你 new 一个新的元素出来,须要去调用1000次 equal 去逐个和他们比较是不是同一个对象,这样会大大下降效率。hashcode其实是返回对象的存储地址,若是这个位置上没有元素,就把元素直接存储在上面,若是这个位置上已经存在元素,这个时候才去调用equal方法与新元素进行比较,相同的话就不存了,散列到其余地址上。前端

二、cloneable接口实现原理:只有实现了这个接口,才能够调用Object的clone方法,不然CloneNotSupporteddExceptionjava

三、comparable与comparator的区别:前者是内部排序,后者是外部排序mysql

4、什么是泛型、为何要使用以及泛型擦除#react

  泛型,即“参数化类型”。
  建立集合时就指定集合元素的类型,该集合只能保存其指定类型的元素,避免使用强制类型转换。
  Java编译器生成的字节码是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除。泛型擦除能够简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。
  类型擦除的主要过程以下:
  1)将全部的泛型参数用其最左边界(最顶级的父类型)类型替换。
  2)移除全部的类型参数。
nginx

五、Error、Exception区别#git

  Error类和Exception类的父类都是throwable类,他们的区别是:
  Error类通常是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的致使的应用程序中断,仅靠程序自己没法恢复和和预防,遇到这样的错误,建议让程序终止。
  Exception类表示程序能够处理的异常,能够捕获且可能恢复。遇到这类异常,应该尽量处理异常,使程序恢复运行,而不该该随意终止异常。
github

六、Object有哪些公用方法web

  Object是全部类的父类,任何类都默认继承Object
  clone 保护方法,实现对象的浅复制,只有实现了Cloneable接口才能够调用该方法,不然抛出CloneNotSupportedException异常。
  equals 在Object中与==是同样的,子类通常须要重写该方法。
  hashCode 该方法用于哈希查找,重写了equals方法通常都要重写hashCode方法。这个方法在一些具备哈希功能的Collection中用到。
  getClass final方法,得到运行时类型
  wait 使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具备该对象的锁。 wait() 方法一直等待,直到得到锁或者被中断。 wait(long timeout) 设定一个超时间隔,若是在规定时间内没有得到锁就返回。
    调用该方法后当前线程进入睡眠状态,直到如下事件发生
    一、其余线程调用了该对象的notify方法。 二、其余线程调用了该对象的notifyAll方法。 三、其余线程调用了interrupt中断该线程。 四、时间间隔到了。 五、此时该线程就能够被调度了,若是是被中断的话就抛出一个InterruptedException异常。
  notify 唤醒在该对象上等待的某个线程。
  notifyAll 唤醒在该对象上等待的全部线程。
  toString 转换成字符串,通常子类都有重写,不然打印句柄。面试

七、Java的四种引用,强弱软虚,用到的场景

  从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
  1.强引用
    最广泛的一种引用方式,如String s = "abc",变量s就是字符串“abc”的强引用,只要强引用存在,则垃圾回收器就不会回收这个对象。
  2.软引用(SoftReference)
    用于描述还有用但非必须的对象,若是内存足够,不回收,若是内存不足,则回收。通常用于实现内存敏感的高速缓存,软引用能够和引用队列ReferenceQueue联合使用,若是软引用的对象被垃圾回收,JVM就会把这个软引用加入到与之关联的引用队列中。
  3.弱引用(WeakReference)
    弱引用和软引用大体相同,弱引用与软引用的区别在于:只具备弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程当中,一旦发现了只具备弱引用的对象,无论当前内存空间足够与否,都会回收它的内存。
  4.虚引用(PhantomReference)
    就是形同虚设,与其余几种引用都不一样,虚引用并不会决定对象的生命周期。若是一个对象仅持有虚引用,那么它就和没有任何引用同样,在任什么时候候均可能被垃圾回收器回收。 虚引用主要用来跟踪对象被垃圾回收器回收的活动。
  虚引用与软引用和弱引用的一个区别在于:
    虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,若是发现它还有虚引,就会在回收对象的内存以前,把这个虚引用加入到与之关联的引用队列中。

八、Java对象的生命周期

  答:建立阶段 、 应用阶段 、不可见阶段 、不可达阶段 、收集阶段 、终结阶段、 对象空间从新分配阶段等等,具体参照:Java 对象的生命周期

九、Java类的生命周期:加载------》链接(验证-->准备-->解析)------》初始化------》使用------》卸载

九、一个类对象属性发生改变时,如何让调用者知道:Event事件机制

十、statement和preparedStatement的区别

十一、Arraylist的循环删除问题:迭代的时候使用list.remove就会引发ConcurrentModificationException,由于迭代的时候mod是迭代开始时的快照,list.remove时修改了集合的mod,致使迭代时mod快照与集合mod比较不一致就异常了 

集合

 

一、HashMap的实现机制:

  维护一个每一个元素是一个链表的数组,并且链表中的每一个节点是一个Entry[]键值对的数据结构。
  实现了数组+链表(1.8新增红黑树)的特性,查找快,插入删除也快。
  对于每一个key,他对应的数组索引下标是 int i = hash(key.hashcode)&(len-1);
  每一个新加入的节点放在链表首,而后该新加入的节点指向原链表首

二、HashMap的源码,实现原理,JDK8中对HashMap作了怎样的优化。:jdk8中hashmap在单链的基础上,增长了单链超过定长(8)坍缩成红黑树,提升了新增和删除节点的效率,提升了读取节点的效率

三、HaspMap扩容是怎样扩容的,为何都是2的N次幂的大小

六、HashMap 是线程安全的吗,为何不是线程安全的(最好画图说明多线程环境下不安全)?:1.7及之前高并发状况下容易造成环,1.8中也有问题

七、HashMap 的扩容过程:默认初始值16,扩容因子0.75,扩容到原来两倍

四、HashMap冲突:

  友情连接: HashMap冲突的解决方法以及原理分析

八、HashMap 1.7 与 1.8 的 区别,说明 1.8 作了哪些优化,如何优化的?

6三、HashMap 的长度为何是 2 的幂次方?

  经过将 Key 的 hash 值与 length-1 进行 & 运算,实现了当前 Key 的定位,2 的幂次方能够减小冲突(碰撞)的次数,提升 HashMap 查询效率;
  若是 length 为 2 的次幂 则 length-1 转化为二进制一定是 11111……的形式,在于 h 的二进制与操做效率会很是的快,并且空间不浪费;
  若是 length 不是 2 的次幂,好比 length 为 15,则 length-1 为 14,对应的二进制为 1110,在于 h 与操做,最后一位都为 0,而 0001,0011,0101,1001,1011,0111,1101 这几个位置永远都不能存放元素了,空间浪费至关大。
  更糟的是这种状况中,数组能够使用的位置比数组长度小了不少,这意味着进一步增长了碰撞的概率,减慢了查询的效率!这样就会形成空间的浪费。

4八、HashMap和HashTable区别#
  1)HashTable的方法前面都有synchronized来同步,是线程安全的;HashMap未经同步,是非线程安全的。
  2)HashTable不容许null值(key和value都不能够) ;HashMap容许null值(key和value均可以)。
  3)HashTable有一个contains(Object value)功能和containsValue(Object value)功能同样。
  4)HashTable使用Enumeration进行遍历;HashMap使用Iterator进行遍历。
  5)HashTable中hash数组默认大小是11,增长的方式是old*2+1;HashMap中hash数组的默认大小是16,并且必定是2的指数。
  6)哈希值的使用不一样,HashTable直接使用对象的hashCode; HashMap从新计算hash值,并且用与代替求模。

三、HashMap和TreeMap区别:

  友情连接: Java中HashMap和TreeMap的区别深刻理解

五、ConcurrentHashMap原理
  ConcurrentHashMap容许多个修改操做并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对Hash表的不一样Segment进行的修改。
    ConcurrentHashMap的应用场景是高并发,可是并不能保证线程安全,而同步的HashMap和HashTable的是锁住整个容器,而加锁以后ConcurrentHashMap不须要锁住整个容器,只须要锁住对应的segment就行了,因此能够保证高并发同步访问,提高了效率。 
  ConcurrentHashMap可以保证每一次调用都是原子操做,可是并不保证屡次调用之间也是原子操做。
  ConcurrentHashMap是使用了锁分段技术技术来保证线程安全的,锁分段技术:首先把HashMap分红若干个Segmenet,而后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其余段的数据也能被其余线程访问
    1.get时,不加锁,先定位到segment而后在找到头结点进行读取操做。而value是volatile变量,因此能够保证在竞争条件时保证读取最新的值,若是读到的value是null,则可能正在修改,那么就调用ReadValueUnderLock函数,加锁保证读到的数据是正确的。
    2.Put时会加锁,一概添加到hash链的头部。
    3.Remove时也会加锁,因为next是final类型不可改变,因此必须把删除的节点以前的节点都复制一遍。
  在JDK8中对这种实现又进行了修改,JDK8中的ConcurrentHashmap基于CAS和TreeBin实现的,不须要对segment或者全局加锁,只须要对单行枷锁(hashCode相同),后边的链表是链表加红黑树。对于单个值的修改使用CAS。

九、LinkedHashMap的原理及应用:LRU算法

十一、HashSet与TreeSet的比较
  1.TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不容许放入null值 。
  2.HashSet 是哈希表实现的,HashSet中的数据是无序的,能够放入null,但只能放入一个null,二者中的值都不能重复,就如数据库中惟一约束 。
  3.HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码做为标识的,而具备相同内容的String对象,hashcode是同样,因此放入的内容不能重复。可是同一个类的对象能够放入不一样的实例。
  适用场景分析:
    HashSet是基于Hash算法实现的,其性能一般都优于TreeSet。咱们一般都应该使用HashSet,在咱们须要排序的功能时,咱们才使用TreeSet。
十二、HashMap和ConcurrentHashMap的区别
  1。HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。
  2。ConcurrentHashMap采用锁分段技术,将整个Hash桶进行了分段segment,也就是将这个大的数组分红了几个小的片断segment,并且每一个小的片断segment上面都有锁存在,那么在插入元素的时候就须要先找到应该插入到哪个片断segment,而后再在这个片断上面进行插入,并且这里还须要获取segment锁。
  3。ConcurrentHashMap让锁的粒度更精细一些,并发性能更好。
1三、HashTable和ConcurrentHashMap的区别
  它们均可以用于多线程的环境,可是当Hashtable的大小增长到必定的时候,性能会急剧降低,由于迭代时须要被锁定很长的时间。由于ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅须要锁定map的某个部分,而其它的线程不须要等到迭代完成才能访问map。简而言之,在迭代的过程当中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。

1四、极高并发下HashTable和ConcurrentHashMap哪一个性能更好,为何,如何实现的。

1五、TreeMap、HashMap、LindedHashMap的区别

  LinkedHashMap能够保证HashMap集合有序,存入的顺序和取出的顺序一致。
  TreeMap实现SortMap接口,可以把它保存的记录根据键排序,默认是按键值的升序排序,也能够指定排序的比较器,当用Iterator遍历TreeMap时,获得的记录是排过序的。
  HashMap不保证顺序,即为无序的,具备很快的访问速度。 HashMap最多只容许一条记录的键为Null;容许多条记录的值为 Null。 HashMap不支持线程的同步。

  咱们在开发的过程当中使用HashMap比较多,在Map中在Map 中插入、删除和定位元素,HashMap 是最好的选择。
  但若是您要按天然顺序或自定义顺序遍历键,那么TreeMap会更好。
  若是须要输出的顺序和输入的相同,那么用LinkedHashMap 能够实现,它还能够按读取顺序来排列。

 

十、Arraylist与LinkedList的比较
  1.ArrayList是实现了基于动态数组的数据结构,由于地址连续,一旦数据存储好了,查询操做效率会比较高(在内存里是连着放的)。
  2.由于地址连续, ArrayList要移动数据,因此插入和删除操做效率比较低。
  3.LinkedList基于链表的数据结构,地址是任意的,因此在开辟内存空间的时候不须要等一个连续的地址,对于新增和删除操做add和remove,LinedList比较占优点。
  4.由于LinkedList要移动指针,因此查询操做性能比较低。
  适用场景分析:
    当须要对数据进行随机访问的状况下选用ArrayList,当须要对数据进行屡次增长删除修改时采用LinkedList。
十一、ArrayList与Vector的比较
  1.Vector的方法都是同步的,是线程安全的,而ArrayList的方法不是,因为线程的同步必然要影响性能。所以,ArrayList的性能比Vector好。
  2.当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增长50%的大小,这样。ArrayList就有利于节约内存空间。
  3.大多数状况不使用Vector,由于性能很差,可是它支持线程的同步,即某一时刻只有一个线程可以写Vector,避免多线程同时写而引发的不一致性。
  4.Vector能够设置增加因子,而ArrayList不能够。
  适用场景分析:
    1.Vector是线程同步的,因此它也是线程安全的,而ArrayList是线程异步的,是不安全的。若是不考虑到线程的安全因素,通常用ArrayList效率比较高。
    2.若是集合中的元素的数目大于目前集合数组的长度时,在集合中使用数据量比较大的数据,用Vector有必定的优点。

十二、CopyOnWriteArrayList : 写时加锁,当添加一个元素的时候,将原来的容器进行copy,复制出一个新的容器,而后在新的容器里面写,写完以后再将原容器的引用指向新的容器,而读的时候是读旧容器的数据,因此能够进行并发的读,但这是一种弱一致性的策略。
  使用场景:CopyOnWriteArrayList适合使用在读操做远远大于写操做的场景里,好比缓存。

1四、Arrays和Collections 对于sort的不一样实现原理?

  1。Arrays.sort()
    该算法是一个通过调优的快速排序,此算法在不少数据集上提供N*log(N)的性能,这致使其余快速排序会下降二次型性能。
  2。Collections.sort()
    该算法是一个通过修改的合并排序算法(其中,若是低子列表中的最高元素效益高子列表中的最低元素,则忽略合并)。此算法可提供保证的N*log(N)的性能,此实现将指定列表转储到一个数组中,而后再对数组进行排序,在重置数组中相应位置处每一个元素的列表上进行迭代。

1五、说说常见的集合有哪些吧?

  Map 接口和 Collection 接口是全部集合框架的父接口:
  Collection 接口的子接口包括:Set 接口和 List 接口;
  Map 接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;
  Set 接口的实现类主要有:HashSet、TreeSet、LinkedHashSet 等;
  List 接口的实现类主要有:ArrayList、LinkedList、Stack 以及 Vector 等。

6五、List、Set 和 Map 的初始容量和加载因子

  1. List
    ArrayList 的初始容量是 10;加载因子为 0.5; 扩容增量:原容量的 0.5 倍 +1;一次扩容后长度为 16。
    Vector 初始容量为 10,加载因子是 1。扩容增量:原容量的 1 倍,如 Vector 的容量为 10,一次扩容后是容量为 20。
  2. Set
    HashSet,初始容量为 16,加载因子为 0.75; 扩容增量:原容量的 1 倍; 如 HashSet 的容量为 16,一次扩容后容量为 32
  3. Map
    HashMap,初始容量 16,加载因子为 0.75; 扩容增量:原容量的 1 倍; 如 HashMap 的容量为 16,一次扩容后容量为 32

6七、Java 集合的快速失败机制 “fail-fast”
  它是 java 集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操做时,有可能会产生 fail-fast 机制。
  例如 :假设存在两个线程(线程 一、线程 2),线程 1 经过 Iterator 在遍历集合 A 中的元素,在某个时候线程 2 修改了集合 A 的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生 fail-fast 机制。
  缘由: 迭代器在遍历时直接访问集合中的内容,而且在遍历过程当中使用一个 modCount 变量。集合在被遍历期间若是内容发生变化,就会改变 modCount 的值。

  每当迭代器使用 hashNext()/next() 遍历下一个元素以前,都会检测 modCount 变量是否为 expectedmodCount 值,是的话就返回遍历;不然抛出异常,终止遍历。
  解决办法:
  在遍历过程当中,全部涉及到改变 modCount 值得地方所有加上 synchronized;
  使用 CopyOnWriteArrayList 来替换 ArrayList。

 

多线程

一、建立线程的方式及实现:Thread,Runnable,Callable

6二、 wait/notify/notifyAll⽅法需不须要被包含在synchronized块中?这是为什 么?:须要,不然会抛出异常

81.、wait和sleep的区别
  1。sleep()方法是属于Thread类中的,而wait()方法,则是属于Object类中的。
  2。sleep()方法致使了程序暂停执行指定的时间,让出cpu给其余线程,可是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。因此在调用sleep()方法的过程当中,线程不会释放对象锁。
  3。调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

6八、Thread 类中的start() 和 run() 方法有什么区别?

 

7二、 如何避免死锁?

7三、Java中活锁和死锁有什么区别?饿死?:活锁是都让别人去获取锁,结果都不获取锁,解决方式为只让一我的释放资源 | 死锁是都本身去获取锁,结果都获取不到锁 | 饿死是任务一直获取不到资源,解决为采用队列 

  

二、CountDownLatch,CyclicBarrier, Semaphore,Exchanger的原理

4八、CountDownLatch 和 CyclicBarrier 的用法,以及相互之间的差异?:前者是等全部线程完成后另一个线程作一件事情,后者是等全部线程完成后一块儿作一件事情

3五、怎么实现全部线程在等待某个事件的发生才会去执行?:CyclicBarrier

四、ThreadLocal(线程变量副本)

  Thread包含一个Map结构,key就是ThreadLocal变量,value就是变量值|使用时注意线程池状况下,线程被复用的问题
  ThreadLocal在Spring中发挥着巨大的做用,在管理Request做用域中的Bean、事务管理、任务调度、AOP等模块都出现了它的身影。
  Spring中绝大部分Bean均可以声明成Singleton做用域,采用ThreadLocal进行封装,所以有状态的Bean就可以以singleton的方式在多线程中正常工做了。

五、Volatile和Synchronized四个不一样点:

  1。粒度不一样,前者针对变量 ,后者锁对象和类
  2。syn阻塞,volatile线程不阻塞
  3。syn保证三大特性(可见性,原子性,有序性),volatile不保证原子性
  4。syn编译器优化,volatile不优化

六、同步,异步,阻塞,非阻塞

  同步:就是一个任务的完成须要依赖另一个任务,只有等待被依赖的任务完成后,依赖任务才能完成。
  异步:不须要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工做,只要本身任务完成了就算完成了,被依赖的任务是否完成会通知回来。(异步的特色就是通知)。 打电话和发短信来比喻同步和异步操做。
  阻塞:CPU停下来等一个慢的操做完成之后,才会接着完成其余的工做。
  非阻塞:非阻塞就是在这个慢的执行时,CPU去作其余工做,等这个慢的完成后,CPU才会接着完成后续的操做,非阻塞会形成线程切换增长,增长CPU的使用时间能不能补偿系统的切换成本须要考虑。

9三、Volatile的特征:
    A、禁止指令重排(有例外)
    B、可见性
  Volatile的内存语义:
    当写一个volatile变量时,JMM会把线程对应的本地内存中的共享变量值刷新到主内存。
    当读一个volatile变量时,JMM会把线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量。
  Volatile的重排序
    1。当第二个操做为volatile写操作时,无论第一个操做是什么(普通读写或者volatile读写),都不能进行重排序。这个规则确保volatile写以前的全部操做都不会被重排序到volatile以后;
    2。当第一个操做为volatile读操做时,无论第二个操做是什么,都不能进行重排序。这个规则确保volatile读以后的全部操做都不会被重排序到volatile以前;
    3。当第一个操做是volatile写操做时,第二个操做是volatile读操做,不能进行重排序。
  这个规则和前面两个规则一块儿构成了:两个volatile变量操做不可以进行重排序;

  除以上三种状况之外能够进行重排序。
  好比:
    1。第一个操做是普通变量读/写,第二个是volatile变量的读;
    2。第一个操做是volatile变量的写,第二个是普通变量的读/写;

3一、synchronized 的实现原理以及锁优化? 

6一、synchronized关键字锁住的是什么东⻄?在字节码中是怎么表示的?在内 存中的对象上表现为何?

13八、synchronized 关键字:
  底层实现:
  进入时,执行 monitorenter,将计数器 +1,释放锁 monitorexit 时,计数器-1;
  当一个线程判断到计数器为 0 时,则当前锁空闲,能够占用;反之,当前线程进入等待状态。
  含义:(monitor 机制)
  Synchronized 是在加锁,加对象锁。对象锁是一种重量锁(monitor),synchronized 的锁机制会根据线程竞争状况在运行时会有偏向锁(单一线程)、轻量锁(多个线程访问 synchronized 区域)、对象锁(重量锁,多个线程存在竞争的状况)、自旋锁等。
  该关键字是一个几种锁的封装。

13九、synchronized锁膨胀原理:自旋锁?无锁->偏向锁->轻量级锁(cas)->重量级锁

3二、volatile 的实现原理?

3三、双检锁DCL问题:线程安全问题,其余线程获取到的单例实例可能还未初始化完(happens-before原理引发的),解决方案为单例实例改成volatile,或者不要采用懒加载,或者用枚举,或者用holder模式

3六、CAS?CAS 有什么缺陷,如何解决?:ABA问题,AtomicStampedReference经过版本号来解决

3七、ABA 问题:AtomicStampedReference经过版本号来解决

3七、synchronized 和 lock 有什么区别?

7四、Java中synchronized 和 ReentrantLock 有什么不一样?

4一、AQS

4九、LockSupport工具

50、Condition接口及其实现原理

 

7六、 如何在Java中建立Immutable对象?:final,集合类的unmodified。。。

 

9四、内存屏障/内存栅栏
  内存屏障(Memory Barrier,或有时叫作内存栅栏,Memory Fence)是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。(也就是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术。)
  内存屏障能够被分为如下几种类型:
    LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操做要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
    StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操做执行前,保证Store1的写入操做对其它处理器可见。
    LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操做被刷出前,保证Load1要读取的数据被读取完毕。
    StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续全部读取操做执行前,保证Store1的写入对全部处理器可见。它的开销是四种屏障中最大的。
  在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能。
  内存屏障阻碍了CPU采用优化技术来下降内存操做延迟,必须考虑所以带来的性能损失。为了达到最佳性能,最好是把要解决的问题模块化,这样处理器能够按单元执行任务,而后在任务单元的边界放上全部须要的内存屏障。采用这个方法可让处理器不受限的执行一个任务单元。合理的内存屏障组合还有一个好处是:缓冲区在第一次被刷后开销会减小,由于再填充改缓冲区不须要额外工做了。

 

9五、happens-before原则

 

9六、Java 线程有哪些状态,这些状态之间是如何转化的?

      

  1。新建(new):新建立了一个线程对象。
  2。可运行(runnable):线程对象建立后,其余线程(好比main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
  3。运行(running):可运行状态(runnable)的线程得到了cpu 时间片(timeslice) ,执行程序代码。
  4。阻塞(block):阻塞状态是指线程由于某种缘由放弃了cpu 使用权,也即让出了cpu timeslice,暂时中止运行。直到线程进入可运行(runnable)状态,才有机会再次得到cpu timeslice 转到运行(running)状态。阻塞的状况分三种:
    (一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
    (二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
    (三). 其余阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程从新转入可运行(runnable)状态。
  5。死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

4一、Blocked和Waiting的区别 

4二、Java 内存模型?

 

3八、HashMap 的并发问题?

40、ConcurrenHashMap 介绍?1.8 中为何要用红黑树?

4三、如何保证多线程下 i++ 结果正确?:加锁,或者用AtomicInteger 

5二、分段锁的原理,锁力度减少的思考

5三、八种阻塞队列以及各个阻塞队列的特性

55. 多个线程同时读写,读线程的数量远远⼤于写线程,你认为应该如何解决 并发的问题?你会选择加什么样的锁?:读写锁

5一、Fork/Join框架的理解

13四、如何指定多个线程的执行顺序?
  解析:面试官会给你举个例子,如何让 10 个线程按照顺序打印 0123456789?(写代码实现)
  答:设定一个 orderNum,每一个线程执行结束以后,更新 orderNum,指明下一个要执行的线程。而且唤醒全部的等待线程。
  在每个线程的开始,要 while 判断 orderNum 是否等于本身的要求值!!不是,则 wait,是则执行本线程。

13六、多线程产生死锁的 4 个必要条件?
  互斥条件:一个资源每次只能被一个线程使用;
  请求与保持条件:一个线程因请求资源而阻塞时,对已得到的资源保持不放;
  不剥夺条件:进程已经得到的资源,在未使用完以前,不能强行剥夺;
  循环等待条件:若干线程之间造成一种头尾相接的循环等待资源关系。

13七、如何避免死锁?
  指定获取锁的顺序,举例以下:
  好比某个线程只有得到 A 锁和 B 锁才能对某资源进行操做,在多线程条件下,如何避免死锁?
  得到锁的顺序是必定的,好比规定,只有得到 A 锁的线程才有资格获取 B 锁,按顺序获取锁就能够避免死锁

13八、悲观锁和乐观锁的区别,怎么实现
  悲观锁:一段执行逻辑加上悲观锁,不一样线程同时执行时,只能有一个线程执行,其余的线程在入口处等待,直到锁被释放。|select for update
  乐观锁:一段执行逻辑加上乐观锁,不一样线程同时执行时,能够同时进入执行,在最后更新数据的时候要检查这些数据是否被其余线程修改了(版本和执行初是否相同),没有修改则进行更新,不然放弃本次操做。|版本号

 

六、线程池的做用: 在程序启动的时候就建立若干线程来响应处理,它们被称为线程池,里面的线程叫工做线程
  第一:下降资源消耗。经过重复利用已建立的线程下降线程建立和销毁形成的消耗。
  第二:提升响应速度。当任务到达时,任务能够不须要等到线程建立就能当即执行。
  第三:提升线程的可管理性。
  经常使用线程池:ExecutorService 是主要的实现类,其中经常使用的有 Executors.newSingleThreadPool(),newFixedThreadPool(),newcachedTheadPool(),newScheduledThreadPool()。

4四、线程池的种类,区别和使用场景?

4六、线程池如何调优,最大数目如何确认?:有个公式

4五、分析线程池的实现原理和线程的调度过程?

5九、线程池内的线程若是所有忙,提交⼀个新的任务,会发⽣什么?队列所有塞满了以后,仍是忙,再提交会发⽣什么?

七、说说阻塞队列的实现:能够参考ArrayBlockingQueue的底层实现(锁和同步都行)

七、线程池原理:

  等待任务队列和工做集:

  

  线程池的主要状态锁:

  

  线程池的存活时间和大小:

  

  ThreadPoolExecutor 的内部工做原理

   1.若是当前池大小 poolSize 小于 corePoolSize ,则建立新线程执行任务。
   2.若是当前池大小 poolSize 大于 corePoolSize ,且等待队列未满,则进入等待队列
   3.若是当前池大小 poolSize 大于 corePoolSize 且小于 maximumPoolSize ,且等待队列已满,则建立新线程执行任务。
   4.若是当前池大小 poolSize 大于 corePoolSize 且大于 maximumPoolSize ,且等待队列已满,则调用拒绝策略来处理该任务。
   5.线程池里的每一个线程执行完任务后不会马上退出,而是会去检查下等待队列里是否还有线程任务须要执行,若是在 keepAliveTime 里等不到新的任务了,那么线程就会退出。

 

 

60. Tomcat自己的参数你⼀般会怎么调整?:调整线程池大小

 

 

 

 

JVM

一、Java内存模型:
  Java虚拟机规范中将Java运行时数据分为六种。
  1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。Java虚拟机的多线程就是经过线程轮流切换并分配处理器时间来实现的,为了线程切换后能恢复到正确的位置,每条线程都须要一个独立的程序计数器,互不影响,该区域为“线程私有”。
  2.Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操做栈,方法返回值。局部变量表放着基本数据类型,还有对象的引用。
  3.本地方法栈:跟虚拟机栈很像,不过它是为虚拟机使用到的Native方法服务。
  4.Java堆:全部线程共享的一块内存区域,对象实例几乎都在这分配内存。
  5.方法区:各个线程共享的区域,储存虚拟机加载的类信息,常量,静态变量,编译后的代码。
  6.运行时常量池:表明运行时每一个class文件中的常量表。包括几种常量:编译时的数字常量、方法或者域的引用

2二、OOM错误,stackoverflow错误,permgen space错误

二、“你能不能谈谈,java GC是在何时,对什么东西,作了什么事情?”
  在何时:
  1.新生代有一个Eden区和两个survivor区,首先将对象放入Eden区,若是空间不足就向其中的一个survivor区上放,若是仍然放不下就会引起一次发生在新生代的minor GC,将存活的对象放入另外一个survivor区中,而后清空Eden和以前的那个survivor区的内存。在某次GC过程当中,若是发现仍然又放不下的对象,就将这些对象放入老年代内存里去。
  2.大对象以及长期存活的对象直接进入老年区。
  3.当每次执行minor GC的时候应该对要晋升到老年代的对象进行分析,若是这些立刻要到老年区的老年对象的大小超过了老年区的剩余大小,那么执行一次Full GC以尽量地得到老年区的空间。

  对什么东西:从GC Roots搜索不到,并且通过一次标记清理以后仍没有复活的对象。
  作什么: 新生代:复制清理; 老年代:标记-清除和标记-压缩算法; 永久代:存放Java中的类和加载类的类加载器自己。
  GC Roots都有哪些: 1. 虚拟机栈中的引用的对象 2. 方法区中静态属性引用的对象,常量引用的对象 3. 本地方法栈中JNI(即通常说的Native方法)引用的对象。

三、类加载器工做机制:
  1。装载:将Java二进制代码导入jvm中,生成Class文件。
  2。链接:a)校验:检查载入Class文件数据的正确性 b)准备:给类的静态变量分配存储空间 c)解析:将符号引用转成直接引用
  3。初始化:对类的静态变量,静态方法和静态代码块执行初始化工做。
  双亲委派模型:类加载器收到类加载请求,首先将请求委派给父类加载器完成 用户自定义加载器->应用程序加载器->扩展类加载器->启动类加载器。

1六、类加载为何要使用双亲委派模式,有没有什么场景是打破了这个模式?:有,Thread.currentThread能够设置classloader,以及osgi

25. JAVA类加载器包括⼏种?它们之间的⽗⼦关系是怎么样的?双亲委派机 制是什么意思?有什么好处?

5四、Java类加载的过程。

5五、双亲委派模型的过程以及优点。 

6四、Java类加载器及如何加载类(双亲委派)#
  阅读文章:
  https://www.ibm.com/developerworks/cn/java/j-lo-classloader/(推荐)
  http://blog.csdn.net/zhoudaxia/article/details/35824249

6五、Class.forName 和 ClassLoader.loadClass的区别 

 

四、Java的四种引用,强弱软虚,以及用到的场景
  a.强引用:若是一个对象具备强引用,它就不会被垃圾回收器回收。即便当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。若是想中断强引用和某个对象之间的关联,能够显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。
  b.软引用:在使用软引用时,若是内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
  c.弱引用:具备弱引用的对象拥有的生命周期更短暂。由于当 JVM 进行垃圾回收,一旦发现弱引用对象,不管当前内存空间是否充足,都会将弱引用回收。不过因为垃圾回收器是一个优先级较低的线程,因此并不必定能迅速发现弱引用对象。
  d.虚引用:顾名思义,就是形同虚设,若是一个对象仅持有虚引用,那么它至关于没有引用,在任什么时候候均可能被垃圾回收器回收。

五、JAVA 中堆和栈的区别,说下java 的内存机制
  a.基本数据类型比变量和对象的引用都是在栈分配的
  b.堆内存用来存放由new建立的对象和数组
  c.类变量(static修饰的变量),程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中
  d.实例变量:当你使用java关键字new的时候,系统在堆中开辟并不必定是连续的空间分配给变量,是根据零散的堆内存地址,经过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”,实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并非立刻就释放堆中内存
  e.局部变量: 由声明在某方法,或某代码段里(好比for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离做用域,内存当即释放

六、JAVA多态的实现原理
  a.抽象的来说,多态的意思就是同一消息能够根据发送对象的不一样而采用多种不一样的行为方式。(发送消息就是函数调用)
  b.实现的原理是动态绑定,程序调用的方法在运行期才动态绑定,追溯源码能够发现,JVM 经过参数的自动转型来找到合适的办法。

九、数组在内存中如何分配:简单类型数组在栈上分配,引用类型在堆上分配

九、Java内存模型 : http://blog.csdn.net/zhaojw_420/article/details/70477903

1四、JVM 年轻代到年老代的晋升过程的判断条件是什么呢?

1八、JVM垃圾回收机制,什么时候触发MinorGC等操做:eden区没法为对象分配空间

1九、JVM 中一次完整的 GC 流程(从 ygc 到 fgc)是怎样的

 

4五、JVM方法栈的工做过程,方法栈和本地方法栈有什么区别。

4六、JVM的栈中引用如何和堆中的对象产生关联。

4四、JVM的内存结构。 

50、eden survivor区的比例,为何是这个比例,eden survivor的工做过程。

 

4九、标记清除和标记整理算法的理解以及优缺点。

6九、垃圾回收算法有哪些?
  引用计数 :原理是此对象有一个引用,即增长一个计数,删除一个引用则减小一个计数。垃圾回收时,只用收集计数为 0 的对象。此算法最致命的是没法处理循环引用的问题;
  标记-清除 :此算法执行分两阶段。第一阶段从引用根节点开始标记全部被引用的对象,第二阶段遍历整个堆,把未标记的对象清除;此算法须要暂停整个应用,同时,会产生内存碎片;
  复制算法 :此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另一个区域中;此算法每次只处理正在使用中的对象,所以复制成本比较小,同时复制过去之后还能进行相应的内存整理,不会出现“碎片” 问题。固然,此算法的缺点也是很明显的,就是须要两倍内存空间;
  标记-整理 :此算法结合了 “标记-清除” 和 “复制” 两个算法的优势。也是分两阶段,第一阶段从根节点开始标记全部被引用对象,第二阶段遍历整个堆,把清除未标记对象而且把存活对象 “压缩” 到堆的其中一块,按顺序排放。此算法避免了 “标记-清除” 的碎片问题,同时也避免了 “复制” 算法的空间问题。

4八、GC的常见算法,CMS以及G1的垃圾回收过程,CMS的各个阶段哪两个是Stop the world的,CMS会不会产生碎片,G1的优点。

20、各类回收器,各自优缺点,重点CMS、G1

2一、各类回收算法

5三、Java是否能够GC直接内存。:不能够,是在ByteBuffer分配内存时设置了清理器

5八、Java有没有主动触发GC的方式(没有)。

6三、Java内存管理及回收算法#
  阅读这篇文章:http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html

70、root 搜索算法中,哪些能够做为 root?
  被启动类(bootstrap 加载器)加载的类和建立的对象;
  JavaStack 中的引用的对象 (栈内存中引用的对象);
  方法区中静态引用指向的对象;
  方法区中常量引用指向的对象;
  Native 方法中 JNI 引用的对象。

7一、GC 何时开始?
  GC 常常发生的区域是堆区,堆区还能够细分为新生代、老年代,新生代还分为一个 Eden 区和两个 Survivor 区。
  对象优先在 Eden 中分配,当 Eden 中没有足够空间时,虚拟机将发生一次 Minor GC,由于 Java 大多数对象都是朝生夕灭,因此 Minor GC 很是频繁,并且速度也很快;
  Full GC,发生在老年代的 GC,当老年代没有足够的空间时即发生 Full GC,发生 Full GC 通常都会有一次 Minor GC。
  大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个;XX:PretenureSizeThreadhold 参数,令大于这个参数值的对象直接在老年代中分配,避免在 Eden 区和两个 Survivor 区发生大量的内存拷贝;
  发生 Minor GC 时,虚拟机会检测以前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,若是大于,则进行一次 Full GC,若是小于,则查看 HandlePromotionFailure 设置是否容许担保失败,若是容许,那只会进行一次 Minor GC,若是不容许,则改成进行一次 Full GC。

 

5六、经常使用的JVM调优参数。

6八、相似-Xms、-Xmn 这些参数的含义:
  堆内存分配:
    JVM 初始分配的内存由-Xms 指定,默认是物理内存的 1/64;
    JVM 最大分配的内存由-Xmx 指定,默认是物理内存的 1/4;
    默认空余堆内存小于 40% 时,JVM 就会增大堆直到-Xmx 的最大限制;空余堆内存大于 70% 时,JVM 会减小堆直到 -Xms 的最小限制;
    所以服务器通常设置-Xms、-Xmx 相等以免在每次 GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
  非堆内存分配:
    JVM 使用-XX:PermSize 设置非堆内存初始值,默认是物理内存的 1/64;
    由 XX:MaxPermSize 设置最大非堆内存的大小,默认是物理内存的 1/4;
    -Xmn2G:设置年轻代大小为 2G;
    -XX:SurvivorRatio,设置年轻代中 Eden 区与 Survivor 区的比值。

29. 1.8以后Perm Space有哪些变更? MetaSpace⼤⼩默认是⽆限的么? 仍是大家会经过什么⽅式来指定⼤⼩?:不是,默认20M,XX:MetaspaceSize=200m;-XX:MaxMetaspaceSize=256m

31. StackOverFlow异常有没有遇到过?⼀般你猜想会在什么状况下被触发?如何指定⼀个线程的堆栈⼤⼩?⼀般大家写多少?:xss来指定

5七、dump文件的分析。

5九、内存溢出和内存泄漏的区别#
  内存溢出是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory。
  内存泄漏是指分配出去的内存再也不使用,可是没法回收。

60、Java内存模型及各个区域的OOM,如何重现OOM#
  这部份内容很重要,详细阅读《深刻理解Java虚拟机》,也能够详细阅读这篇文章http://hllvm.group.iteye.com/group/wiki/2857-JVM

  线程共享部分:方法区,又名永久代,无GC(常量池内存不足OOM)。堆区,分配时内存不足则OOM。

  线程私有部分:虚拟机栈,线程请求栈深度超过阈值则SOF,分配时内存不足OOM。本地方法栈,同虚拟机栈同样。程序计数器,没有OOM。

  直接内存,空间不足则OOM  

 

6一、出现OOM如何解决#
  一. 可经过命令按期抓取heap dump或者启动参数OOM时自动抓取heap dump文件。
  二. 经过对比多个heap dump,以及heap dump的内容,分析代码找出内存占用最多的地方。
  三. 分析占用的内存对象,是不是由于错误致使的内存未及时释放,或者数据过多致使的内存溢出。

 

1五、JVM 出现 fullGC 很频繁,怎么去线上排查问题?:

24. 你知道哪些或者大家线上使⽤什么GC策略? 它有什么优点,适⽤于什么 场景?

28. 你有没有遇到过OutOfMemory问题?你是怎么来处理这个问题的?处理过程当中有哪些收获?

30. Jstack是⼲什么的? Jstat呢? 若是线上程序周期性地出现卡顿,你怀疑多是gc致使的,你会怎么来排查这个问题?线程⽇志⼀般你会看其中的什么 部分?:jstack查看线程堆栈|查看fullgc/minor时间和频率|线程日志通常看blocked-->waiting-->timed_waiting

3五、请写一段栈溢出、堆溢出的代码
  递归调用能够致使栈溢出
  不断建立对象能够致使堆溢出

 

 

 

 

 

 

NIO

二、BIO、NIO和AIO的区别
  Java BIO : 同步并阻塞,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善。
  Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有I/O请求时才启动一个线程进行处理。
  Java AIO : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
  NIO比BIO的改善之处是把一些无效的链接挡在了启动线程以前,减小了这部分资源的浪费(由于咱们都知道每建立一个线程,就要为这个线程分配必定的内存空间)
  AIO比NIO的进一步改善之处是将一些暂时可能无效的请求挡在了启动线程以前,好比在NIO的处理方式中,当一个请求来的话,开启线程进行处理,但这个请求所须要的资源尚未就绪,此时必须等待后端的应用资源,这时线程就被阻塞了。
  适用场景分析:
    BIO方式适用于链接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4之前的惟一选择,但程序直观简单易理解,如以前在Apache中使用。
    NIO方式适用于链接数目多且链接比较短(轻操做)的架构,好比聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持,如在 Nginx,Netty中使用。
    AIO方式使用于链接数目多且链接比较长(重操做)的架构,好比相册服务器,充分调用OS参与并发操做,编程比较复杂,JDK7开始支持,在成长中,Netty曾经使用过,后来放弃。

 三、Java IO与NIO

  NIO是为了弥补IO操做的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道。管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征。
  概念解释
    Channel——管道实际上就像传统IO中的流,到任何目的地(或来自任何地方)的全部数据都必须经过一个 Channel 对象。一个 Buffer 实质上是一个容器对象。
    Selector——选择器用于监听多个管道的事件,使用传统的阻塞IO时咱们能够方便的知道何时能够进行读写,而使用非阻塞通道,咱们须要一些方法来知道何时通道准备好了,选择器正是为这个须要而诞生的。

    每一种基本 Java 类型都有一种缓冲区类型:
    ByteBuffer——byte
    CharBuffer——char
    ShortBuffer——short
    IntBuffer——int
    LongBuffer——long
    FloatBuffer——float
    DoubleBuffer——double
  NIO和传统的IO有什么区别呢?
    IO是面向流的,NIO是面向块(缓冲区)的:
      IO面向流的操做一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。,致使了数据的读取和写入效率不佳。
      NIO面向块的操做在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多,同时数据读取到一个它稍后处理的缓冲区,须要时可在缓冲区中先后移动。这就增长了处理过程当中的灵活性。通俗来讲,NIO采起了“预读”的方式,当你读取某一部分数据时,他就会猜想你下一步可能会读取的数据而预先缓冲下来。
    IO是阻塞的,NIO是非阻塞的:
      对于传统的IO,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据彻底写入。该线程在此期间不能再干任何事情了。
      而对于NIO,使用一个线程发送读取数据请求,没有获得响应以前,线程是空闲的,此时线程能够去执行别的任务,而不是像IO中那样只能等待响应完成。
  NIO和IO适用场景:
    NIO是为弥补传统IO的不足而诞生的,可是尺有所短寸有所长,NIO也有缺点,由于NIO是面向缓冲区的操做,每一次的数据处理都是对缓冲区进行的,那么就会有一个问题,在数据处理以前必需要判断缓冲区的数据是否完整或者已经读取完毕,若是没有,假设数据只读取了一部分,那么对不完整的数据处理没有任何意义。因此每次数据处理以前都要检测缓冲区数据。
  那么NIO和IO各适用的场景是什么呢?
    若是须要管理同时打开的成千上万个链接,这些链接每次只是发送少许的数据,例如聊天服务器,这时候用NIO处理数据多是个很好的选择。
    而若是只有少许的链接,而这些链接每次要发送大量的数据,这时候传统的IO更合适。使用哪一种处理数据,须要在数据的响应等待时间和检查缓冲区数据的时间上做比较来权衡选择。
  通俗解释,最后,对于NIO和传统IO
  有一个网友讲的生动的例子:

  之前的流老是堵塞的,一个线程只要对它进行操做,其它操做就会被堵塞,也就至关于水管没有阀门,你伸手接水的时候,无论水到了没有,你就都只能耗在接水(流)上。
  nio的Channel的加入,至关于增长了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各个水管里流出来的水,均可以获得妥善接纳,这个关键之处就是增长了一个接水工,也就是Selector,他负责协调,也就是看哪根水管有水了的话,在当前水管的水接到必定程度的时候,就切换一下:临时关上当前水龙头,试着打开另外一个水龙头(看看有没有水)。
  当其余人须要用水的时候,不是直接去接水,而是事前提了一个水桶给接水工,这个水桶就是Buffer。也就是,其余人虽然也可能要等,但不会在现场等,而是回家等,能够作其它事去,水接满了,接水工会通知他们。
  这其实也是很是接近当前社会分工细化的现实,也是统分利用现有资源达到并发效果的一种很经济的手段,而不是动不动就来个并行处理,虽然那样是最简单的,但也是最浪费资源的方式。

四、Netty的Reactor模型

 

 

 

 

算法

20、一致性Hash算法,一致性Hash算法的应用:

  咱们把服务器集群分红n段,每一个服务器负责一段路由key。

  若是其中一台挂了,只是影响这一段路由key失效,不影响其余。

  若是要加一台机器的话,咱们加在其中一个分段中,那么这个分段也只有一小段路由key会失效,另一小段不影响。

  这样就在很大程度上减少了影响范围,主要应用在缓存集群中

1八、B+树:树结构就是索引结构,采用B+树跟磁盘有关,磁盘会预读树结点附近的数据,这样就会很容易命中须要查询的数据,而且减小了磁盘IO次数

2八、如何判断一个单链表是否有环:采用list来存放全部元素,有重复则存在环|采用不一样步长的指针来遍历,步长较长的会遇上较短的

2九、红黑树:由于红黑树的结构能够用不多的旋转开销就能完成插入和删除,减少了红黑树结构的维护成本

  参考:https://blog.csdn.net/mmshixing/article/details/51692892

 

其余 

10四、三次握手、四次挥手示意图:

  握手阶段:C告诉S我要连接--->S回答C说已经准备好了--->C回答S说我收到你准备好了

  挥手阶段:C告诉S我要断开--->S回答C说我准备断开了,可是等我发送完数据--->S告诉C说我发完最后一波数据了--->C回答S说我收到你最后一波数据

  挥手阶段比握手阶段多了一个服务端发送最后数据的过程

  详解:https://blog.csdn.net/qzcsu/article/details/72861891

总共有四种状态:主动创建链接、主动断开链接、被动创建连和被动断开链接
  两两组合仍是 4 种组合:
  1.主动创建链接、主动断开链接会经历的状态:
  SYNC_SENT——ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT
  2.主动创建链接、被动断开链接会经历的状态:
  SYNC_SENT——ESTABLISHED—-CLOSE_WAIT—-LAST_ACK
  3.被动创建链接、主动断开链接会经历的状态:
  LISTEN—-SYN_RCVD—-ESTABLISHED—-FIN_WAIT_1—-FIN_WAIT_2—-TIME_WAIT
  4.被动创建链接、被动断开链接会经历的状态:
  LISTEN—-SYN_RCVD—-ESTABLISHED—-CLOSE_WAIT—-LAST_ACK

10五、滑动窗口机制
  由发送方和接收方在三次握手阶段,互相将本身的最大可接收的数据量告诉对方。也就是本身的数据接收缓冲池的大小。这样对方能够根据已发送的数据量来计算是否能够接着发送。
在处理过程当中,当接收缓冲池的大小发生变化时,要给对方发送更新窗口大小的通知。

 

 

 

核心篇

数据存储------(死锁,索引,事务,优化,分库分表,读写分离)

六、MySQL 遇到的死锁问题

 参考:http://www.kissyu.org/2017/02/19/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1Mysql%E6%AD%BB%E9%94%81%E6%8E%92%E6%9F%A5%E8%BF%87%E7%A8%8B/

2九、悲观锁、乐观锁:版本号检测为乐观锁,其余为悲观锁

6一、产生死锁的必要条件:互斥条件|请求与保持条件|不剥夺条件|循环等待条件
  参考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

6二、死锁预防:确保获取锁的顺序一致
  参考http://blog.sina.com.cn/s/blog_5e3604840100ddgq.html

8四、数据库中的锁有哪几种?:独占锁、排他锁以及更新锁。

8五、如何解除死锁状态:查看在锁的事务--->kill线程id

8七、MyISAM 和 InnoDB 的区别有哪些?:MyISAM 表不支持事务、不支持行级锁、不支持外键。 InnoDB 表支持事务、支持行级锁、支持外键

5四、各个数据库引擎区别:http://www.jb51.net/article/38004.htm

 

一、MySQL 索引使用的注意事项

八、数据库索引的原理:B+树

十、索引:B+,B-,全文索引

  Mysql的索引是一个数据结构,旨在使数据库高效的查找数据。
  经常使用的数据结构是B+Tree,每一个叶子节点不但存放了索引键的相关信息还增长了指向相邻叶子节点的指针,这样就造成了带有顺序访问指针的B+Tree,作这个优化的目的是提升不一样区间访问的性能。
十一、何时使用索引:
    常常出如今group by,order by和distinc关键字后面的字段
    常常与其余表进行链接的表,在链接字段上应该创建索引
    常常出如今Where子句中的字段
    常常出现用做查询选择的字段

2三、mysql的索引分类:B+,hash;什么状况用什么索引:hash索引不支持范围查询

30、组合索引,最左原则

3一、mysql 的表锁、行锁、页锁

3六、若是查询很慢,你会想到的第⼀个⽅式是什么?索引是⼲嘛的?:加索引,索引是为数据保持了一个有序的映射,相似于TreeMap

3七、若是建了⼀个单列索引,查询的时候查出2列,会⽤到这个单列索引吗?:会

3八、若是建了⼀个包含多个列的索引,查询的时候只⽤了第⼀列,能不能⽤上 这个索引?查三列呢?:最左原则

40、怎么看是否⽤到了某个索引?:explain执行计划看type

5二、MySQL为何使用B+树做为索引?:由于B+树能够预读,减小磁盘IO次数,提升数据查询速度

  参考:https://blog.csdn.net/bigtree_3721/article/details/73650601

5五、索引的使用注意事项:http://www.javashuo.com/article/p-cubihmaj-cn.html 

5八、索引的优缺点,什么字段上创建索引:order by, where ,group by,distinct,join等字段

6九、数据库索引的实现(B+树介绍、和B树、R树区别)#

7一、数据库索引的优缺点以及何时数据库索引失效#:not in,!=不会命中索引

7二、当数据表中A、B字段作了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)
  答:A、B两字段作组合索引的时候,谁在前面,谁在后面,若是A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,若是只是使用前面%,那么有索引效果,若是使用双%号匹配,那么则无索引效果

8六、数据库的索引有什么做用?(必考) 底层数据结构是什么,为何使用这种数据结构?

  索引 是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息;
  底层数据结构是 B+ 树;
  使用 B+ 树的缘由:查找速度快、效率高,在查找的过程当中,每次都能抛弃掉一部分节点,减小遍历个数。( 此时,你应该在白纸上画出什么是 B+ 树 )
8七、聚簇索引和非聚簇索引的区别?

 

2五、说说事务的特性和隔离级别;

  做为单个逻辑工做单元执行的一系列操做,知足四大特性:
    原子性(Atomicity):事务做为一个总体被执行 ,要么所有执行,要么所有不执行;
    一致性(Consistency):保证数据库状态从一个一致状态转变为另外一个一致状态;
    隔离性(Isolation):多个事务并发执行时,一个事务的执行不该影响其余事务的执行;
    持久性(Durability):一个事务一旦提交,对数据库的修改应该永久保存。

   Mysql的事物隔离级别?

    Read Uncommitted(读取未提交内容)

    Read Committed(读取提交内容)

    Repeatable Read(可重读)

    Serializable(可串行化)

8三、事务的并发问题有哪几种?

  丢失更新、脏读、不可重复读以及幻读。

8五、事务的隔离级别有哪几种?MySQL 事务默认隔离级别是哪一个?
  答:读未提交、读已提交、可重复读和序列化。可重复读。

 

十二、MySQL数据库优化总结

1三、MYSQL 优化经常使用方法

5三、mysql优化经验

  1。对查询进行优化,应尽可能避免全表扫描,首先应考虑在 where 及 order by 涉及的列上创建索引。
  2。应尽可能避免在 where 子句中使用!=或<>操做符,不然引擎将放弃使用索引而进行全表扫描。
  3。尽可能使用数字型字段,若只含数值信息的字段尽可能不要设计为字符型,这会下降查询和链接的性能,并会增长存储开销。这是由于引擎在处理查询和链接时会逐个比较字符串中每个字符,而对于数字型而言只须要比较一次就够了。
  4。任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
  5。避免频繁建立和删除临时表,以减小系统表资源的消耗。诸如此类,等等等等......

5七、常见的数据库优化手段

7七、一条sql执行过长的时间,你如何优化,从哪些方面?
  1。查看sql是否涉及多表的联表或者子查询,若是有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)
  2。涉及链表的查询,是否能进行分表查询,单表查询以后的结果进行字段整合
  3。若是以上两种都不能操做,非要链表查询,那么考虑对相对应的查询条件作索引。加快查询速度
  4。针对数量大的表进行历史表分离(如交易流水表)
  5。数据库主从分离,读写分离,下降读写针对同一表同时的压力,至于主从同步,mysql有自带的binlog实现 主从同步
  6。explain分析sql语句,查看执行计划,分析索引是否用上,分析扫描行数等等
  7。查看mysql执行日志,看看是否有其余方面的问题

 

2八、mysql分页有什么优化

十一、limit 20000 加载很慢怎么解决:采用id排序,经过id来限制范围

45. 大家的数据库单表数据量是多少?⼀般多⼤的时候开始出现查询性能急剧降低?:1000万

4六、mysql的最大写入速度?:7500(4G内存+20G硬盘+1个CPU,4核)

  

 

三、说说分库与分表设计:用户中心,经过用户id(手机号索引表,邮箱索引表)路由打散到4个DB,每一个DB把表切分红8张分表,一共有4×8=32张表

四、分库与分表带来的分布式困境与应对之策:分布式事务,子查询,关联查询,分页查询|分布式事务中间件(分布式事务),把全部分库分表数据同步汇总到一个库,在这个库上进行操做(分页查询),拆分为单表查询(子查询,关联查询)

十二、选择合适的分布式主键方案

  基于数据库方案:auto_increment | 多个库相同步长间隔auto_increment | 数据库单条记录+ID批量生成服务 | 数据库单条记录+ID批量生成服务+灾备模式 | 数据库单条记录+去中心化ID批量生成服务

  基于中间件方案:Tair/Redis原子操做|

  本地化方案:UUID | 当前时间 | snowflake

1四、ObjectId 规则

1三、选择合适的数据存储方案

47. 读写分离是怎么作的?你认为中间件会怎么来操做?这样操做跟事务有什么关系?:mysql主从复制,读所有打到从,写所有打到主|中间件会解析sql分析读写操做|主从同步延迟引发的事务一致性问题?

14. 分库分表有没有作过?线上的迁移过程是怎么样的?如何肯定数据是正 确的?:在老库上挂上精卫,订阅精卫任务将数据写入分库分表

5九、数据库链接池。:原理?

6五、.数据库链接池的原理#
参考http://blog.csdn.net/shuaihj/article/details/14223015

7四、简单说说数据库集群和负载均衡、分布式(我不懂这块)

 

 

1六、倒排索引

1七、聊聊 ElasticSearch 使用场景

 80、MySQL 和 MongoDB 的区别有哪些?如何选择?

 8一、MongoDB 的优缺点有哪些?

 

 

缓存

十一、Redis数据结构:String,Hash,List,Set,Sorted Set

 二、Redis 内部结构

七、Redis 为何是单线程的:缓存主要是io密集型,对cpu需求不大,因此单线程已经知足要求

20、Redis用过哪些数据数据,以及Redis底层怎么实现

 

四、Redis 持久化机制:rdb和aof

六、Redis 集群方案与实现:

八、缓存奔溃:缓存过时,所有穿透到后端的状况,能够种一个缓存(60s)和一个缓存标识(30s),访问的时候先访问缓存标识,发现过时后触发异步更新缓存,并返回当前60s的缓存

九、缓存降级:丢卒保帅,通常错误-->警告-->错误-->严重错误

1五、redis集群如何同步:数据复制,slave发起请求,master push数据

1六、redis的数据添加过程是怎样的:哈希槽

1七、redis的淘汰策略有哪些:volatile-lru,volatile-ttl,volatile-random,allkeys-lru,allkeys-random,no-enviction

2一、Redis缓存穿透,缓存雪崩:没有命中缓存,方案有加锁穿透并种缓存,异步种全量缓存,布隆过滤器

2二、如何使用Redis来实现分布式锁:setnx

2四、Redis持久化的几种方式,优缺点是什么,怎么实现的:aof(每一个操做一个脚本),rdb(定时全两快照)

2三、Redis的并发竞争问题,以及如何解决:乐观锁,watch

2五、Redis的缓存失效策略:按期删除(随机检查删除)+ 惰性删除(get的时候再去检查删除)+ 内存淘汰机制(lru)

2六、Redis集群,高可用,原理:sentinal

2七、Redis缓存分片:客户端分片(jedis),基于代理的分片(codis),路由查询(redis cluster)

  参考:https://www.jianshu.com/p/14835303b07e

3一、渐进式rehash过程?:同时持有两个hash,逐渐迁移

3五、事务与事件:事件IO多路复用,reactor模型

3六、主从复制:

3七、启动过程

3八、集群

3九、redis哨兵机制

40、redis高可用方案:哨兵机制

4二、redis的两个持久化策略:http://blog.csdn.net/u010785685/article/details/52366977

4三、redis如何事务支持:https://www.cnblogs.com/kyrin/p/5967620.html
4四、redis哨兵机制:http://blog.csdn.net/zbw18297786698/article/details/52891695
4五、redis集群方案:https://www.zhihu.com/question/21419897
4六、redis主从同步策略:http://blog.csdn.net/sk199048/article/details/50725369
4六、redis是单线程的么,全部的工做都是单线程么。
4七、redis如何存储一个String的:char数组
4九、redis的哨兵模式,一个key值如何在redis集群中找到存储在哪里。

  

三、聊聊 Redis 使用场景:缓存,队列

1三、用redis作过什么:cache,队列

十二、redis和memcache的区别:数据结构不同|redis单线程|mc读性能更高

十、使用缓存的合理性问题:

 

 

消息队列

二、消息的重发补偿解决思路

三、消息的幂等性解决思路

四、消息的堆积解决思路

五、本身如何实现消息队列

六、如何保证消息的有序性:根据业务id肯定路由到哪一个broker,保证同一个业务id路由到同一个broker

七、mq的原理是什么:有点大。。均可以说;

八、mq如何保证明时性;

九、mq的持久化是怎么作的;

 

一、消息队列的使用场景:解耦,异步,削峰|发邮件,发短信

 

 

框架篇

Spring

九、如何自定义注解实现功能:声明注解,注解解析器

2一、BeanFactory 和 FactoryBean?:BeanFactory是Spring的bean容器,FactoryBean是工厂bean,能够来生成Bean的一种Bean

1四、Spring Bean的做用域:
  Singleton:Spring IOC容器中只有一个共享的Bean实例,通常都是Singleton做用域。
  Prototype:每个请求,会产生一个新的Bean实例。
  Request:每一次http请求会产生一个新的Bean实例。

3六、 若是⼀个接⼝有2个不一样的实现, 那么怎么来Autowire⼀个指定的实现?:Qualifier | @Autowire是byType,@Resource是ByName-->ByType

3七、 Spring的声明式事务 @Transaction注解⼀般写在什么位置? 抛出了异常会⾃动回滚吗?有没有办法控制不触发回滚? | 通常在接口实现的方法上,会自动回滚,在注解上配置属性noRollbackFor

3八、 若是想在某个Bean⽣成并装配完毕后执⾏⾃⼰的逻辑,能够什么⽅式实现?:Intialization接口afterProperties方法

3九、SpringBoot没有放到web容器⾥为何能跑HTTP服务?:自带嵌入式tomcat

4三、怎样拦截SpringMVC的异常,而后作⾃定义的处理,⽐如打⽇志或者包装成JSON

4五、struts2和springMVC的区别

4六、spring框架中须要引用哪些jar包,以及这些jar包的用途:spring-core,spring-bean,spring-context 

50、spring注入的几种方式:@Setter,@Constructor,@Autowire,@Resource

90、Spring 的 IOC 和 AOP 有了解吗?
  IOC:控制反转,(解耦合)将对象间的依赖关系交给 Spring 容器,使用配置文件来建立所依赖的对象,由主动建立对象改成了被动方式;
  AOP:面向切面编程,将功能代码从业务逻辑代码中分离出来。

9一、AOP 的实现方式有哪几种?如何选择?(必考)

答:JDK 动态代理实现和 cglib 实现。有接口定义则能够使用jdk,没有则用cglib。

   spring对aop的实现原理:ProxyFactoryBean | AbstractAutoProxyCreator | AspectJ语法 | XML方式

 

一、BeanFactory 和 ApplicationContext 有什么区别:Application支持父子容器,支持web。。。

二、Spring Bean 的生命周期:

三、Spring IOC 如何实现:扫描源码解析出BeanDefination,管理BeanDefination的依赖,反射生成Bean实例,根据BeanDefination的依赖注入bean

五、Spring AOP 实现原理:动态代理,拦截器

六、动态代理(cglib 与 JDK):有接口定义则能够使用jdk,没有则用cglib。

八、Spring 事务底层原理:底层是AOP实现的

十二、Spring 的单例实现原理:采用Map实现的单例

1三、Spring 框架中用到了哪些设计模式:工厂模式,观察者模式,动态代理。。。

1七、SpringMVC运行原理
  1.客户端请求提交到DispatcherServlet
  2.由DispatcherServlet控制器查询HandlerMapping,找到并分发到指定的Controller中。
  3.Controller调用业务逻辑处理后,返回ModelAndView
  4.DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
  5.视图负责将结果显示到客户端

2四、Spring Bean 的生命周期,如何被管理的?

2五、Spring Bean 的加载过程是怎样的?

2六、若是要你实现Spring AOP,请问怎么实现?

2七、若是要你实现Spring IOC,你会注意哪些问题?:对象依赖管理,继承,反射

2八、Spring 是如何管理事务的,事务管理机制?

2九、Spring 的不一样事务传播行为有哪些,干什么用的?

    PROPAGATION_REQUIRED:外部没有事务,就新开一个事务

    PROPAGATION_SUPPORTS:外部有事务,就用这个事物,没有就算了

    PROPAGATION_MANDATORY:外部没有事物,就不干(异常)

    PROPAGATION_REQUIRES_NEW:无论外部有没有事务,都新开独立的一个事务

    PROPAGATION_NOT_SUPPORTED:无论外部有没有事物,都不使用事务

    PROPAGATION_NEVER:外部有事务,就不干(异常)

    PROPAGATION_NESTED:外部有事务,就新开一个子事务,savepoint

3二、Spring 循环注入的原理?:

3三、Spring AOP的理解,各个术语,他们是怎么相互工做的?:Advice,PointCut,Advisor

3四、Spring 如何保证 Controller 并发的安全?:Spring针对Controller能够配置scope,用来制定是request,session,prototype,仍是singleton

51. spring如何实现事物管理的:基于AOP实现的

52. springIOC和AOP的原理

55. springmvc的核心是什么,请求的流程是怎么处理的,控制反转怎么实现的
  核心:控制反转和面向切面
  请求处理流程:
    1。首先用户发送请求到前端控制器,前端控制器根据请求信息(如URL)来决定选择哪个页面控制器进行处理并把请求委托给它,即之前的控制器的控制逻辑部分;
    2。页面控制器接收到请求后,进行功能处理,首先须要收集和绑定请求参数到一个对象,并进行验证,而后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);
    3。前端控制器收回控制权,而后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;
    4。前端控制器再次收回控制权,将响应返回给用户。
  控制反转如何实现:
    咱们每次使用spring框架都要配置xml文件,这个xml配置了bean的id和class。
    spring中默认的bean为单实例模式,经过bean的class引用反射机制能够建立这个实例。
    所以,spring框架经过反射替咱们建立好了实例而且替咱们维护他们。
    A须要引用B类,spring框架就会经过xml把B实例的引用传给了A的成员变量。

5九、spring循环依赖及解决办法:http://blog.csdn.net/caomiao2006/article/details/46511123
60、springmvc工做流程和原理:http://blog.csdn.net/liangzi_lucky/article/details/52459378
6一、spring注解原理:http://blog.csdn.net/u010987379/article/details/52152795

6二、Spring AOP 实现原理?
  参考 :http://blog.csdn.net/moreevan/article/details/11977115/

6三、@transactional注解在什么状况下会失效,为何?:调用同一个类的方法的时候,spring容器经过aop提供为bean提供事务管理功能,方法内部调用是调用的对象自己的方法,不是调用的spring容器的bean

6四、SpringMVC的Controller是如何将参数和前端传来的数据一一对应的。
6五、Quartz是如何完成定时任务的。
6八、Spring的IOC有什么优点。
6九、Spring如何维护它拥有的bean。:BeanDefination集合来管理。。

7二、Springmvc与Struts区别#
  参考文章:
  http://blog.csdn.net/tch918/article/details/38305395
  http://blog.csdn.net/chenleixing/article/details/44570681

7六、Springbean的加载过程(推荐看Spring的源码)#
参考文章http://geeekr.com/read-spring-source-1-how-to-load-bean/

7七、Springbean的实例化(推荐看Spring的源码)#
参考文章http://geeekr.com/read-spring-source-two-beans-initialization/

7八、Spring如何实现AOP和IOC(推荐看Spring的源码)#
参考文章http://www.360doc.com/content/15/0116/21/12385684_441408260.shtml

7九、Springbean注入方式#
参考文章http://blessht.iteye.com/blog/1162131

80、Spring的事务管理#
这个主题的参考文章没找到特别好的,http://blog.csdn.net/trigl/article/details/50968079这个还能够。

8一、Spring事务的传播特性#
参考文章http://blog.csdn.net/lfsf802/article/details/9417095

80、springmvc原理
参考文章http://blog.sina.com.cn/s/blog_7ef0a3fb0101po57.html

8二、Spring 事务的隔离性,并说说每一个隔离性的区别

解答:Spring事务详解

8五、Struts跟Spring mvc的优缺点,让你选会如何选

解答:Spring MVC 与 Struts的区别

8六、简单说说Spring 事务机制

解答:Spring事务机制

8九、Spring的原理

答:Spring的核心是IOC和AOP  ,IOC是依赖注入和控制反转, 其注入方式可分为set注入、构造器注入、接口注入等等。IOC就是一个容器,负责实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。简单理解就是:JAVA每一个业务逻辑处理至少须要两个或者以上的对象协做进行工做,可是每一个对象在使用它的合做对象的时候,都须要频繁的new 对象来实现,你就会发现,对象间的耦合度高了。而IOC的思想是:Spring容器来管理这些,对象只须要处理自己业务关系就行了。至于什么是控制反转,就是得到依赖对象的方式反转了。
AOP呢,面向切面编程,最直接的体现就是Spring事物管理。至于Spring事物的相关资料,就不细说了,参考:Spring注解式事物管理

 90、JDK 动态代理如何实现?(加分点)

答:JDK 动态代理,只能对实现了接口的类生成代理,而不是针对类,该目标类型实现的接口都将被代理。原理是经过在运行期间建立一个接口的实现类来完成对目标对象的代理。

  1. 定义一个实现接口 InvocationHandler 的类;
  2. 经过构造函数,注入被代理类;
  3. 实现 invoke( Object proxy, Method method, Object[] args)方法;
  4. 在主函数中得到被代理类的类加载器;
  5. 使用 Proxy.newProxyInstance( ) 产生一个代理对象;
  6. 经过代理对象调用各类方法。

9二、Spring MVC 的核心控制器是什么?消息处理流程有哪些?

答:核心控制器为 DispatcherServlet。消息流程以下:

 

 

1五、代理的共有优势:业务类只须要关注业务逻辑自己,保证了业务类的重用性。
  Java静态代理:
    代理对象和目标对象实现了相同的接口,目标对象做为代理对象的一个属性,具体接口实现中,代理对象能够在调用目标对象相应方法先后加上其余业务处理逻辑。
    缺点:一个代理类只能代理一个业务类。若是业务类增长方法时,相应的代理类也要增长方法。
  Java动态代理:
    Java动态代理是写一个类实现InvocationHandler接口,重写Invoke方法,在Invoke方法能够进行加强处理的逻辑的编写,这个公共代理类在运行的时候才能明确本身要代理的对象,同时能够实现该被代理类的方法的实现,而后在实现类方法的时候能够进行加强处理。
  实际上:代理对象的方法 = 加强处理 + 被代理对象的方法
 

1六、JDK和CGLIB生成动态代理类的区别:
  JDK动态代理只能针对实现了接口的类生成代理(实例化一个类)。此时代理对象和目标对象实现了相同的接口,目标对象做为代理对象的一个属性,具体接口实现中,能够在调用目标对象相应方法先后加上其余业务处理逻辑
  CGLIB是针对类实现代理,主要是对指定的类生成一个子类(没有实例化一个类),覆盖其中的方法 。

 

1七、Spring AOP应用场景
  性能检测,访问控制,日志管理,事务等。

8七、Spring 4.0新特性

解答:Spring4新特性

 

 

 

 

Netty

一、为何选择 Netty:由于netty是nio实现的,高并发的状况下比mina表现要好

二、说说业务中,Netty 的使用场景:通讯组件,rpc通讯组件,mq通讯组件

三、原生的 NIO 在 JDK 1.7 版本存在 epoll bug:空转,若是不到超时时间唤醒了,则记录1次,超过512次则从新建立SelectionKey从新注册全部事件

四、什么是TCP 粘包/拆包:链路层对数据进行拆分数据包和合并数据包

五、TCP粘包/拆包的解决办法:业务曾手动拆分数据包

七、说说 Netty 的零拷贝:内核态,不用在用户态之间切换

1四、了解哪几种序列化协议?包括使用场景和如何去选择

1六、Netty的高性能表如今哪些方面:nio

18.NIO的组成?:Channel(通道),Selector(选择器),ByteBuffer(各类缓冲器)

26.NIOEventLoopGroup源码?

六、Netty 线程模型:Reactor模型

八、Netty 内部执行流程:

九、Netty 重连实现:在final里重现链接

十一、Netty 的各大组件:

  Channel、EventLoop和ChannelFuture

  ChannelHandler和ChannelPipeline

  Bootstrapping

十二、Netty的线程模型:BossGroup,WorkerGroup

1三、TCP 粘包/拆包的缘由及解决方法

 

 

Mybatis

一、Mybatis流程
  每个Mybatis的应用程序都以一个SqlSessionFactory对象的实例为核心。首先用字节流经过Resource将配置文件读入,而后经过SqlSessionFactoryBuilder().build方法建立SqlSessionFactory,而后再经过SqlSessionFactory.openSession()方法建立一个SqlSession为每个数据库事务服务。
  经历了Mybatis初始化 –>建立SqlSession –>运行SQL语句,返回结果三个过程

三、mybatis如何处理结果集
  MyBatis的结果集是经过反射来实现的。并非经过get/set方法。在实体类中不管是否认义get/set()方法,都是能够接收到的。

五、mybatis分页及分页插件原理:http://blog.csdn.net/jaryle/article/details/52315565

六、mybatis插件原理:http://blog.csdn.net/hupanfeng/article/details/9247379
七、mybatis动态sql原理:http://www.importnew.com/24160.html
八、mybatis延迟加载:http://blog.csdn.net/eson_15/article/details/51668523

九、Mybatis如何找到指定的Mapper的,如何完成查询的。

 

Dubbo

1.什么是rcp框架:http://www.javashuo.com/article/p-hpqomuon-ge.html
2.序列化方式方式及做用:http://blog.csdn.net/u012554102/article/details/51902697
3.dubbo底层协议实现:http://www.javashuo.com/article/p-kfsehtfq-gt.html
4.dubbo注册中心如何设置:http://blog.csdn.net/u011659172/article/details/51491518
5.dubbo负载均衡的理解:http://www.javashuo.com/article/p-knztwfmj-gp.html
6.dubbo容错机制:https://www.2cto.com/kf/201612/572681.html
7.服务调用超时的实现原理:http://www.javashuo.com/article/p-vasdlwnk-mv.html
8.服务注册与发现的流程:http://doc.okbase.net/661116/archive/241946.html

1七、Dubbo的底层实现原理和机制

2二、Dubbo的服务请求失败怎么处理:

  集群容错策略

  failover:失败则尝试访问其余provider

  failfast:失败立马返回

  failsafe:失败直接忽略

  failback:失败定时重发

  forking:并行调用多个provider,只要有一个返回则返回

  broadcast:全部provider都调一遍

4一、dubbo的组件有哪些,各有什么做用。

  dubbo-rpc:提供rpc以及序列化功能

  dubbo-registry:提供服务注册订阅相关功能

  dubbo-remoting:提供rpc访问通讯功能

4三、dubbo是如何利用接口就能够通讯的。:动态代理,封装了rpc,序列化,通讯等复杂性

五、说说 Dubbo 的实现原理:

  服务提供方暴露本身的服务,并注册到zk上,服务消费者在zk上订阅服务

  消费者订阅到服务后,将客户端访问参数组装成一个消息对象,加密传输到服务提供方,服务提供方解密参数并调用本地方法,将返回结果加密返回,客户端再解密返回结果

 

 

 

 

微服务篇

微服务

一、先后端分离是如何作的:m站,先后端同窗统一制定好接口定义,APP前端同窗页面展现效果,后端提供业务接口功能,并经过mtop平台暴露给前端团队使用

二、微服务哪些框架:eurke

三、你怎么理解 RPC 框架:业务提供者暴露服务,并提供一个访问地址,客户端经过访问地址访问暴露的服务,涉及到数据传输和数据序列化 | 序列化、反序列化,IO传输,服务注册和订阅,服务路由

四、说说 RPC 的实现原理:客户端调用 => 消息对象 => 数据加密 => 网络传输 => 服务端数据解密成消息对象 => 服务端调用服务 => 返回结果数据加密 => 网络传输回写 => 客户端解密成返回结果

  参考:https://liuzhengyang.github.io/2016/12/16/rpc-principle/

六、你怎么理解 RESTful

七、说说如何设计一个良好的 API

  可读性:一眼就能看出接口含义

  。。。

八、如何理解 RESTful API 的幂等性

   同一个请求访问屡次系统的影响与访问一次相同,好比查询

九、如何保证接口的幂等性

  查询,删除,惟一索引校验,token机制防止重复提交,访问带seq作惟一索引

十、说说 CAP 定理、 BASE 理论

十一、怎么考虑数据一致性问题

  因为分布式环境下,CAP只能知足俩,因此能够采用弱一致性的方案来解决一致性问题,好比弹外添加观演人,采用谈外异步更新到弹内,保证了分区容忍性和有效性,弱一致性方案

十二、说说最终一致性的实现方案

  好比数据同步,或者分库分表数据汇总到一个库

1三、你怎么看待微服务

  

1四、微服务与 SOA 的区别

  

1五、如何拆分服务

  按照业务拆分,高内聚低耦合

1六、微服务如何进行数据库管理

  

1七、如何应对微服务的链式调用异常:调用链路跟踪,全链路日志

1八、对于快速追踪与定位问题

1九、微服务的安全

 

 

 

分布式---------------zk,dubbo,消息中间件|分布式session,分布式锁,分布式事务,负载均衡,分库分表,分布式ID

一、谈谈业务中使用分布式的场景

  业务层分布出去造成分布式服务,消息队列分布出去造成分布式消息队列,数据访问分布出去造成分布式数据存储。。。 

十一、zookeeper是什么;

   分布式协调服务,经常使用在分布式系统中,屏蔽分布式系统访问底层的复杂配置

十二、zookeeper哪里用到;

  分布式服务的服务注册+订阅

1三、zookeeper的选主过程;:zab协议

1四、zookeeper集群之间如何通信;

  zab协议  

1五、大家的zookeeper的节点加密是用的什么方式;

2六、Zookeeper的用途,选举的原理是什么?

  分布式协调服务,屏蔽分布式访问的复杂细节

2八、zookeeper原理和适用场景

2九、zookeeper watch机制

30、redis/zk节点宕机如何处理

3六、zookeeper的选举策略

4二、zookeeper的负载均衡算法有哪些。?zk有负载均衡?zk在集群负载均衡中的协调

    

1八、描述一个服务从发布到被消费的详细过程

  provider暴露服务,注册服务到zk--》consumer订阅在zk上订阅服务

1九、分布式系统怎么作服务治理

  

20、接口的幂等性的概念

 

3三、用过哪些MQ,怎么用的,和其余mq比较有什么优缺点,MQ的链接是线程安全的吗

  ActiveMq,MetaQ,

3四、MQ系统的数据如何保证不丢失

  消息刷盘,消息消费确认

4六、消息队列的原理和实现

4七、Redis实现消息队列

  答:Redis实现消息队列     、参考2

 

  

二、Session 分布式方案:session复制,session粘连,session共享

九、分布式Session框架
  配置服务器,Zookeeper集群管理服务器能够统一管理全部服务器的配置文件
  共享这些Session存储在一个分布式缓存中,能够随时写入和读取,并且性能要很好,如Memcache,Tair。
  封装一个类继承自HttpSession,将Session存入到这个类中而后再存入分布式缓存中
  因为Cookie不能跨域访问,要实现Session同步,要同步SessionID写到不一样域名下。

40、分布式session如何设计。

4四、集群环境中,session如何实现共享

  1.Java集群之session共享    

       二、session多服务器共享方案,还有一种方案就是使用一个固定的服务器专门保持session,其余服务器共享

 

 

三、分布式锁的场景:弹内选座生成静态页,抽奖专题扣减名额和库存

四、分布是锁的实现方案:zookeeper(临时节点),redis(setnx)

1六、分布式锁的实现过程;:setnx成功则视为获取锁成功,释放锁的时候删除key

3九、分布式锁如何设计。

  redis中获取锁时,须要给锁设置一个缓存过时时间,防止当前节点获取到锁后挂了,致使分布式锁没法释放
       释放锁时,须要确保获取到锁的状况下,才能去删除锁节点

五、分布式事务:TCC,1pc,2pc,3pc,txc

2四、对分布式事务的理解:保证分布式系统之间的数据一致性问题

3八、分布式事务的控制。

 

六、集群与负载均衡的算法与实现:dubbo负载均衡算法(roundrobin,random,leastactive,conisistenHash)

2五、如何实现负载均衡,有哪些算法能够实现?

2三、重连机制会不会形成错误:有可能,好比接口超时重连,须要保证接口幂等性,不然对数据有影响

 

 

七、说说分库与分表设计

八、分库与分表带来的分布式困境与应对之策

2七、数据的垂直拆分水平拆分。:垂直拆分为按照业务来拆分,水平拆分是把数据量不少的表拆分红不少个小表,加快读写速度,提升性能

3五、列举出你能想到的数据库分库分表策略;分库分表后,如何解决全表查询的问题

   策略:按照id取模分表,按照字符串hash分表

   将分库分表的数据同步汇总到一个全量库,在全量库上全表查询

3一、分布式集群下如何作到惟一序列号

  数据库单条记录+ID批量生成服务

3七、全局ID

 

4五、分布式、集群环境中,缓存如何刷新,如何保持同步?

  A、缓存如何刷新? 一、定时刷新  二、主动刷新覆盖   ,每一个缓存框架都有自带的刷新机制,或者说缓存失效机制,就拿Redis和 Ehcache举例, 他们都有自带的过时机制,另外主动刷新覆盖时,只需获取对应的key进行数据的覆盖便可

  B、缓存如何保持同步?  这个redis有自带的集群同步机制,即复制功能,具体参考:基于Redis分布式缓存实现      ,Ehcache也有分布式缓存同步的配置,只须要配置不一样服务器地址便可,参照:Ehcache分布式缓存同步

4八、谈谈你对分布式的理解

  我的理解:分布式就是把一个系统/业务 拆分红多个子系统/子业务 去协同处理,这个过程就叫分布式,具体的演变方式参考:Java分布式应用技术架构介绍

 

 

 

 

安全与性能篇

性能优化

一、性能指标有哪些

二、如何发现性能瓶颈

三、性能调优的常见手段

四、说说你在项目中如何进行性能调优

五、web如何项目优化

  解答:web项目性能优化(整理)

六、平常项目中,若是你接手,你准备从哪些方面调优?

  答:这个呢首先是了解哪些须要优化,须要优化确定是项目性能遭遇瓶颈或者猜想即将遭遇了,咱们才会去考虑优化。那么怎么优化?

  a、扩容 ,扩容的理解,就是扩充服务器并行处理的能力,简单来讲就是加服务器,增长处理请求的能力,例如增长nginx 、tomcat等应用服务器的个数,或者物理服务器的个数,还有加大服务器带宽等等,这里考虑的是硬件方面

  b、调优 ,调优,包括系统调优和代码调优 。 系统调优就是说加快处理速度,好比咱们所提到的CDN、ehcache、redis等缓存技术,消息队列等等,加快服务间的响应速度,增长系统吞吐量,避免并发,至于代码调优,这些就须要多积累了,好比重构、工厂等, 数据库调优的话这个我不是很懂,只知道索引和存储过程,具体参考:Mysql数据库调优21个最佳实践  ,其余数据库调优方面就各位本身找找吧

 

 

 

 

 

工程篇

需求分析

一、你如何对需求原型进行理解和拆分

二、说说你对功能性需求的理解

三、说说你对非功能性需求的理解

四、你针对产品提出哪些交互和改进意见

五、你如何理解用户痛点

设计能力

一、说说你在项目中使用过的 UML 图

二、你如何考虑组件化

三、你如何考虑服务化

四、你如何进行领域建模

五、你如何划分领域边界

六、说说你项目中的领域建模

七、说说概要设计

设计模式

一、你项目中有使用哪些设计模式

二、说说经常使用开源框架中设计模式使用分析

三、说说你对设计原则的理解

四、23种设计模式的设计理念

五、设计模式之间的异同,例如策略模式与状态模式的区别

六、设计模式之间的结合,例如策略模式+简单工厂模式的实践

七、设计模式的性能,例如单例模式哪一种性能更好。

业务工程

一、你系统中的先后端分离是如何作的

二、说说你的开发流程

三、你和团队是如何沟通的

四、你如何进行代码评审

五、说说你对技术与业务的理解

六、说说你在项目中常常遇到的 Exception

七、说说你在项目中遇到感受最难Bug,怎么解决的

八、说说你在项目中遇到印象最深困难,怎么解决的

九、你以为大家项目还有哪些不足的地方

十、你是否遇到过 CPU 100% ,如何排查与解决

十一、你是否遇到过 内存 OOM ,如何排查与解决

十二、说说你对敏捷开发的实践

1三、说说你对开发运维的实践

1四、介绍下工做中的一个对本身最有价值的项目,以及在这个过程当中的角色

1五、重构过代码没有?说说经验;

 

场景

1六、一千万的用户实时排名如何实现;:zset的score特性(ZINCRBY修改score) 

1七、五万人并发抢票怎么实现;:反向代理,页面静态化+cdn,限流 | 动静分离,冷热分离,集群+负载均衡,缓存,缓存预热 | 读写分离,分库分表,链接池

1八、大型网站应用之海量数据解决方案 
        http://blog.csdn.net/zhaojw_420/article/details/70881230

1九、大型网站应用之高并发状况下的解决方案 
        http://blog.csdn.net/zhaojw_420/article/details/70881266

20、在一个千万级的数据库查寻中,如何提升查询效率? :

  分库分表,读写分离,创建索引

  或者

  创建索引,避免全表扫描 | 避免not in, !=之类,由于全表扫描|union all 替换 or,避免全表扫描(不一样索引字段or)| like没有知足最左原则也会全表扫描|where中使用参数,等号左边使用表达式,函数也会全表扫描

  避免使用*返回无用的字段| exisits代替in

        http://blog.csdn.net/zhaojw_420/article/details/69367682

2一、用wait-notify 写一段代码来解决生产者-消费者问题,更进一步,在分布式的环境下怎么解决

  wait()和notify()都是线程间通讯的方法,能够直接对线程的行为进行操做。他们的本质实际上是传递生产者-消费者各自的消息,理解了这一点,那么在分布式环境下就很简单了,只要找到一个第三方的能够用来传递消息的媒介(Zookeeper、Redis、Kafka等)就能够了。

  

 1 Object[] list = new Object[10];
 2 
 3 public void produce(){
 4         sychronized(list){
 5             while(true){
 6                if(list.size() >= 10){
 7                    list.wait();//等待消费者消费
 8                 }
 9              //work
10               list.add(new Object());
11               list.notify();//通知消费者
12             }
13         }   
14 }
15 
16 public void consume(){
17         sychronized(list){
18              while(true){
19                  if(list.size() <= 0){
20                       list.wait();//等待生产者生产
21                  }
22                 //work          
23                 list.remove(0);
24                 list.notify();//通知生产者
25              }   
26         }
27 }

 

  

22.、设计一个线程池

  A:能够参考Java线程池的理论与实践

  若是对JDK的线程池java.util.concurrent.ThreadPoolExecutor比较了解,能够把一些简单的特性放上去。若是不了解,能够直接设计一个线程数组,而后加一些业务逻辑。所谓线程池,基本也就如此。

2三、 设计一个IOC容器
  A:用反射,注解,还有IOC的理论
2五、手机扫二维码登陆是怎么实现的?
  参考:http://www.jianshu.com/p/7f072ac61763
2六、如何保证RESTful API安全性 ?

  对客户端作身份验证:参数加签,oauth协议

  对敏感数据加密,防止篡改:https

  身份认证以后的受权

  参考: http://blog.csdn.net/ywk253100/article/details/25654101

2七、项目并发如何处理?(咱们是web项目)

  解答:高并发量网站解决方案,另外,还有数据库乐观锁,数据库读写分离、使用消息队列、多用存储过程等等

2九、平台上的图片如何防盗链:refer字段

  解答: http下载防盗链原理:http协议的字段referer记录来实现

30、如何区分上传的图片是否是木马?

  解答:一、看上传的图片后缀  二、如何后缀是篡改的,那么每一个文件有个魔术数字  文件上传-魔术数字

3一、你的接口服务数据被人截包了,你如何防止数据恶意提交?

  答:咱们能够在接口传输参数里面设置一个业务编号,这个编号用来区分是否重复提交。这样即便数据被抓包了,对方也没法区分每一个字段你的含义,这时,这个业务编号的做用就来了

3二、假设服务器常常宕机,你从哪些方面去排查问题?

  答:先重启,并开启jvm输出gc日志||看是否是系统问题,若是不是则看是否是jvm问题,在看是否是oom,sof等

3三、下单3min还未支付,发短信提醒

  有两种,一种是采用定时任务扫库,时间不必定准确 | 一种是zset,score设置为当前时间+3min,扫描zset发现时间到了,若是该订单未支付,则发送短信

相关文章
相关标签/搜索