111.哈夫曼编码
简易的理解就是,假如我有A,B,C,D,E五个字符,出现的频率(即权值)分别为5,4,3,2,1,那么我们第一步先取两个最小权值作为左右子树构造一个新树,即取1,2构成新树,其结点为1+2=3,如图:
虚线为新生成的结点,第二步再把新生成的权值为3的结点放到剩下的集合中,所以集合变成{5,4,3,3},再根据第二步,取最小的两个权值构成新树,如图:
再依次建立哈夫曼树,如下图:
其中各个权值替换对应的字符即为下图:
所以各字符对应的编码为:A->11,B->10,C->00,D->011,E->010
112.说说Runnable与Callable
Callable接口:public interface Callable{ V call() throws Exception;}
Runnable接口:public interface Runnable { public abstract void run();}
相同点:
1.两者都是接口;(废话)
2.两者都可用来编写多线程程序;
3.两者都需要调用Thread.start()启动线程;
不同点:
1.两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;
2.Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;
注意点:Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞
Callable工作的Demo:
Runnable工作的Demo:
113.java线程池
https://www.cnblogs.com/aspirant/p/6920418.html
114.synchronized与Lock的区别
两者区别:
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
3.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
115.synchronized锁升级过程
https://www.cnblogs.com/kubidemanong/p/9520071.html
https://blog.csdn.net/mmoren/article/details/79185862#commentBox
116.hashmap 在JDK1.7 和1.8为什么数组下标拉链时候是一个头插入,一个尾叉?
https://blog.csdn.net/qq_36520235/article/details/82417949
117.线程池shumdown 时候还有线程跑的话发生了什么
对shutdown方法的调用,可以防止新任务的被提交给这个Executor,当前线程将继续运行在shutdown()被调用之前提交的所有任务。这个程序将在Executor中的所有任务完成中之后尽快退出。
线程池文章:
https://www.jianshu.com/p/210eab345423
118.B树B+树的区别?
http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html
119.浅谈AVL树,红黑树,B树,B+树原理及应用
https://blog.csdn.net/whoamiyang/article/details/51926985
https://blog.csdn.net/guoziqing506/article/details/64122287
120.如何理解valatile保证内存有序性
http://www.360doc.com/content/18/0311/23/14567867_736238973.shtml