diff --git a/README.md b/README.md
index e9bac08..a02d168 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-
-
| 🍏 | 🍎 | 🍐 | 🍈 | 🥑 | 🥔| 🍠 | 🥝 | 🍱 | 🥞 |🌽| 🥦
| :--------: | :---------: | :---------: | :---------: | :---------: | :---------:| :---------: | :-------: | :-------:| :------:|:------:| :--------: |
| [JAVA基础](#JAVA基础) | [JVM知识](#JVM知识)|[开源框架知识](#开源框架知识) | [操作系统知识](#操作系统) |[多线程与并发](#多线程与并发)|[TCP与HTTP](#TCP与HTTP)| [架构设计与分布式](#架构设计与分布式) |[数据结构与算法](#数据结构与算法)|[数据库](#数据库知识)| [消息队列](#消息队列)|[缓存](#缓存) | [搜索](#搜索)
@@ -12,7 +10,7 @@
- [JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。](http://www.importnew.com/28263.html)
- [HashMap, ConcurrentHashMap 原理](https://mp.weixin.qq.com/s/QggmWkrgYrNtVkdSKYuRfg)
- [有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。](https://www.jianshu.com/p/07cceede7b03)
- - 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。
+ - [抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。](https://www.cnblogs.com/dolphin0520/p/3811437.html)
- [IO模型有哪些,讲讲你理解的nio ,他和bio,aio的区别是啥,谈谈reactor模型。](https://www.cnblogs.com/javalyy/p/8882066.html)
- [反射的原理,反射创建类实例的三种方式是什么。](http://blog.51cto.com/4247649/2109128)
- [反射中,Class.forName和ClassLoader区别 。](https://blog.csdn.net/qq_27093465/article/details/52262340)
@@ -20,23 +18,23 @@
- [描述动态代理的几种实现方式,分别说出相应的优缺点。](https://blog.csdn.net/wufaliang003/article/details/79305688/)
- [动态代理与cglib实现的区别。](https://www.cnblogs.com/ygj0930/p/6542259.html)
- 为什么CGlib方式可以对接口实现代理。
- - final的用途。
- - [写出三种单例模式实现](http://tech.hunts.work/2015/09/01/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/#1-%E5%8D%95%E4%BE%8Bsingleton) 。
+ - [final的用途。](https://www.cnblogs.com/dolphin0520/p/3736238.html)
+ - [写出三种单例模式实现](https://mp.weixin.qq.com/s/lZDqy5WatnORY9fEqjjztw) 。
- 如何在父类中为子类自动完成所有的hashcode和equals实现?这么做有何优劣。
- 请结合OO设计理念,谈谈访问修饰符public、private、protected、default在应用设计中的作用。
- [深拷贝和浅拷贝区别](https://blog.csdn.net/wangxueming/article/details/52034841)。
- - 数组和链表数据结构描述,各自的时间复杂度。
+ - [数组和链表数据结构描述,各自的时间复杂度。](https://blog.csdn.net/u013632854/article/details/70338252)
- [error和exception的区别,CheckedException,RuntimeException的区别。](https://blog.csdn.net/iblade/article/details/78196016)
- [在自己的代码中,如果创建一个java.lang.String类,这个类是否可以被类加载器加载?为什么。](https://blog.csdn.net/qq_26807245/article/details/80912026)
- [说一说你对java.lang.Object对象中hashCode和equals方法的理解。在什么场景下需要重新实现这两个方法。](https://blog.csdn.net/qq_21163061/article/details/73606523)
- [在jdk1.5中,引入了泛型,泛型的存在是用来解决什么问题。](https://www.cnblogs.com/panjun-Donet/articles/1131446.html)
- - 这样的a.hashcode() 有什么用,与a.equals(b)有什么关系。
- - 有没有可能2个不相等的对象有相同的hashcode。
+ - [有没有可能2个不相等的对象有相同的hashcode。](https://blog.csdn.net/dalang_1234/article/details/79200889)
- Java中的HashSet内部是如何工作的。
- 什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决。
- - java8的新特性。
+ - [java8的新特性。](http://www.runoob.com/java/java8-new-features.html)
- [强引用、软引用、弱引用、幻象引用有什么区别?](https://github.com/randian666/algorithm-study/blob/master/MD/Reference.md)
- [java运算符 与(&)、非(~)、或(|)、异或(^)](https://www.cnblogs.com/yesiamhere/p/6675067.html)
+ - [集合框架面试题](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/%E8%BF%99%E5%87%A0%E9%81%93Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E9%9D%A2%E8%AF%95%E9%A2%98%E5%87%A0%E4%B9%8E%E5%BF%85%E9%97%AE.md)
- [史上最全Java面试题](https://blog.csdn.net/linzhiqiang0316/article/details/80473906)
- [各大公司Java面试题超详细总结](http://www.cnblogs.com/java1024/p/7685400.html)
@@ -45,13 +43,14 @@
- 什么情况下会发生栈内存溢出。
- [JVM的内存结构,Eden和Survivor比例。](https://blog.csdn.net/bluetjs/article/details/52874852)
- JVM内存为什么要分成新生代,老年代,持久代。新生代中为什么要分为Eden和Survivor。
- - JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的JVM参数。
+ - [JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的JVM参数。](https://www.jianshu.com/p/314272e6d35b)
- [讲下cms和G1,包括原理,流程,优缺点。](https://blog.csdn.net/zhanggang807/article/details/45956325)
- [垃圾回收算法的实现原理。](http://www.cnblogs.com/xiaoxi/p/6486852.html)
- [G1,包括原理,流程,优缺点。](https://www.cnblogs.com/nashiyue/p/5797713.html)
- [CMS收集器学习笔记](https://mp.weixin.qq.com/s/OzE7WrvcGPEcf_UHj2a-lg)
+ - 谈谈你的GC调优思路?
- [垃圾回收算法的实现原理。](http://www.cnblogs.com/aspirant/p/8662690.html)
- - 当出现了内存溢出,你怎么排错。
+ - [当出现了内存溢出,你怎么排错。](https://blog.csdn.net/wtt945482445/article/details/52483944)
- [JVM内存模型的相关知识了解多少,比如重排序,内存屏障,happen-before,主内存,工作内存等。](https://mp.weixin.qq.com/s/rkxcqZCvCnC0Psr0_oJzbQ)
- [简单说说你了解的类加载器,可以打破双亲委派么,怎么打破。](http://blog.csdn.net/javazejian/article/details/73413292)
- [加载时机与加载过程](https://blog.csdn.net/justloveyou_/article/details/72466105)
@@ -59,22 +58,24 @@
- [Java对象的创建过程](http://blog.csdn.net/justloveyou_/article/details/72466416)
- [你们线上应用的JVM参数有哪些。](https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html)
- [g1和cms区别,吞吐量优先和响应优先的垃圾收集器选择。](https://blog.csdn.net/ZYC88888/article/details/80353357)
- - 怎么打出线程栈信息。
+ - [怎么打出线程栈信息。](http://www.cnblogs.com/kongzhongqijing/articles/3630264.html)
### 开源框架知识
- 简单讲讲tomcat结构,以及其类加载器流程,线程模型等。
- tomcat如何调优,涉及哪些参数 。
- - 讲讲Spring加载流程。
+ - [Spring中bean的作用域与生命周期](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484400&idx=2&sn=7201eb365102fce017f89cb3527fb0bc&chksm=fd985591caefdc872a2fac897288119f94c345e4e12150774f960bf5f816b79e4b9b46be3d7f&token=1990180468&lang=zh_CN#rd)
+ - [讲讲Spring加载流程。](https://segmentfault.com/a/1190000012887776)
- [spring循环依赖](http://www.tianxiaobo.com/2018/06/08/Spring-IOC-%E5%AE%B9%E5%99%A8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/)
- [Spring AOP的实现原理。](https://www.jianshu.com/p/7fa3e6ebf0c1)
- [讲讲Spring事务的传播属性。](https://www.cnblogs.com/cnmenglang/p/6410848.html)
- [Spring如何管理事务的。](https://blog.csdn.net/donggua3694857/article/details/69858827)
- - 说说你对Spring的理解,非单例注入的原理?它的生命周期?循环注入的原理。
+ - 说说你对Spring的理解,非单例注入的原理?循环注入的原理。
- [Springmvc 中DispatcherServlet初始化过程。](https://www.cnblogs.com/xiaoxi/p/6164383.html)
+ - [SpringMVC 原理了解吗?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484496&idx=1&sn=5472ffa687fe4a05f8900d8ee6726de4&chksm=fd985231caefdb27fc75b44ecf76b6f43e4617e0b01b3c040f8b8fab32e51dfa5118eed1d6ad&token=1990180468&lang=zh_CN#rd)
- netty的线程模型,netty如何基于reactor模型上实现的。
- 为什么选择netty。
- - 什么是TCP粘包,拆包。解决方式是什么。
+ - [什么是TCP粘包,拆包。解决方式是什么。](https://blog.csdn.net/wxy941011/article/details/80428470)
- netty的fashwheeltimer的用法,实现原理,是否出现过调用不够准时,怎么解决。
- netty的心跳处理在弱网下怎么办。
- netty的通讯协议是什么样的。
@@ -83,31 +84,35 @@
- [Mybatis的底层实现原理。](https://mp.weixin.qq.com/s/AqqSRYPdUbruSAhhmqVneA)
- [69道Spring面试题和答案](http://ifeve.com/spring-interview-questions-and-answers/)
- [Spring 面试问题 TOP 50](https://mp.weixin.qq.com/s/eQ-lpYiW7a437djqliKhmg)
+ - [Spring中用了哪些设计模式](https://mp.weixin.qq.com/s/iGbwKDqB6A0ktNCY8Wd-XQ)
### 操作系统
- Linux系统下你关注过哪些内核参数,说说你知道的。
- [Linux下IO模型有几种,各自的含义是什么。](https://juejin.im/post/5b94e93b5188255c672e901e)
- - epoll和poll有什么区别。
+ - [epoll和poll有什么区别。](https://www.cnblogs.com/Anker/p/3265058.html)
- [平时用到哪些Linux命令。以及如何排查线上问题](https://github.com/randian666/algorithm-study/blob/master/MD/Linux.md)
- 介绍下你理解的操作系统中线程切换过程。
- 进程和线程的区别。
+ - [BATJ面试必会之Linux命令篇](https://mp.weixin.qq.com/s/6ZPNeX9d3avscI642x2kHA)
### 多线程与并发
- 多线程的几种实现方式,什么是线程安全。
- [volatile的原理,作用,能代替锁么。](https://blog.csdn.net/javazejian/article/details/72772461)
- - 画一个线程的生命周期状态图。
+ - [画一个线程的生命周期状态图。](https://blog.csdn.net/houbin0912/article/details/77969563)
- sleep和wait的区别。
- sleep和sleep(0)的区别。
+ - [Java 各种锁的小结](https://mp.weixin.qq.com/s/_xazrXa8MBYaz2WaX6BNew)
- [Lock与Synchronized的区别 。](https://blog.csdn.net/javazejian/article/details/75043422)
- [synchronized的原理是什么](https://blog.csdn.net/javazejian/article/details/72828483)
- [量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁。](https://www.toutiao.com/i6630764198357893646/)
+ - [ReentranLock源码,设计原理,整体过程](https://www.cnblogs.com/chengxiao/p/7255941.html)
- 用过哪些原子类,他们的原理是什么。
- JUC下研究过哪些并发工具,讲讲原理。
- [用过线程池吗,如果用过,请说明原理,并说说newCache和newFixed有什么区别,构造函数的各个参数的含义是什么,比如coreSize,maxsize等。](https://blog.csdn.net/wy11933/article/details/80399562)
- 线程池的关闭方式有几种,各自的区别是什么。
- 假如有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有10个线程同时调用它,如何做到。
- - spring的controller是单例还是多例,怎么保证并发的安全。
+ - [spring的controller是单例还是多例,怎么保证并发的安全。](https://www.cnblogs.com/zxf330301/articles/6105127.html)
- 用三个线程按顺序循环打印abc三个字母,比如abcabcabc。
- [ThreadLocal用过么,用途是什么,原理是什么,用的时候要注意什么。](https://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&mid=2247484994&idx=1&sn=18ff91ffc530f5bf9a016b3e06c17168&chksm=f94a87abce3d0ebd0d23d0cf190777974ef6ba353653071a63ba7b06c417deca59c4279a2171&token=375547551&lang=zh_CN&scene=21#wechat_redirect)
- 如果让你实现一个并发安全的链表,你会怎么做。
@@ -123,7 +128,7 @@
- 非常多个线程(可能是不同机器),相互之间需要等待协调,才能完成某种工作,问怎么设计这种协调方案。
- 用过读写锁吗,原理是什么,一般在什么场景下用。
- 开启多个线程,如果保证顺序执行,有哪几种实现方式,或者如何保证多个线程都执行完再拿到结果。
- - 延迟队列的实现方式,delayQueue和时间轮算法的异同。
+ - [延迟队列的实现方式,delayQueue和时间轮算法的异同。](https://blog.csdn.net/u014634338/article/details/78385603)
- [史上最全 Java 多线程面试题及答案](https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247486721&idx=2&sn=c2058d5ddd7453eb9c39732c114879d5&scene=21#wechat_redirect)
- [Java并发编程73道面试题及答案](https://mp.weixin.qq.com/s/N1YAZmBLX-bC-XkuC7yl_Q)
### TCP与HTTP
@@ -132,25 +137,28 @@
- [TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么。](https://blog.csdn.net/qzcsu/article/details/72861891)
- TIME_WAIT和CLOSE_WAIT的区别。
- [说说你知道的几种HTTP响应码,比如200, 302, 404。](https://blog.csdn.net/ddhsea/article/details/79405996)
- - 当你用浏览器打开一个链接(如:http://www.baidu.cn)的时候,计算机做了哪些工作步骤。
+ - [当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤。](https://segmentfault.com/a/1190000006879700)
- [TCP/IP如何保证可靠性,说说TCP头的结构。](https://blog.csdn.net/liuchenxia8/article/details/80428157)
- 如何避免浏览器缓存。
- - 如何理解HTTP协议的无状态性。
+ - [如何理解HTTP协议的无状态性。](https://blog.csdn.net/tennysonsky/article/details/44562435)
- 简述Http请求get和post的区别以及数据包格式。
- HTTP有哪些method
- 简述HTTP请求的报文格式。
- - HTTP的长连接是什么意思。
- - HTTPS的加密方式是什么,讲讲整个加密解密流程。
+ - [HTTP的长连接是什么意思。](http://www.cnblogs.com/gotodsp/p/6366163.html)
- Http和https的三次握手有什么区别。
+ - HTTP和HTTPS的区别
+ - [http请求过程](https://www.jianshu.com/p/c1d6a294d3c0)
+ - [Https实现原理](https://www.cnblogs.com/zery/p/5164795.html)
- 什么是分块传送。
- Session和cookie的区别。
- [计算机网络面试问题集锦](https://blog.csdn.net/justloveyou_/article/details/78303617)
### 架构设计与分布式
-
- - [用java自己实现一个LRU。](https://github.com/randian666/algorithm-study/blob/master/src/main/java/com/algorithm/study/demo/LRUCache/LRUMap.java)
- - 分布式集群下如何做到唯一序列号。
+ - [ZooKeeper基本原理](https://zhuanlan.zhihu.com/p/30024403)
+ - [分布式锁解决并发的三种实现方式](https://www.jianshu.com/p/8bddd381de06)
+ - [分布式集群下如何做到唯一序列号。](https://blog.csdn.net/hl_java/article/details/78462283)
- 设计一个秒杀系统,30分钟没付款就自动关闭交易。
- [如何使用redis和zookeeper实现分布式锁?有什么区别优缺点,会有什么问题,分别适用什么场景。](https://mp.weixin.qq.com/s/OCIg3TwpmXzqOVqBZ2fSow)
+ - [基于Zookeeper的分布式锁](https://blog.csdn.net/qiangcuo6087/article/details/79067136)
- [如果知道redlock,讲讲他的算法实现](http://www.redis.cn/topics/distlock.html)
- [分布式事务的原理,优缺点,如何使用分布式事务,2pc 3pc 的区别,解决了哪些问题,还有哪些问题没解决,如何解决,你自己项目里涉及到分布式事务是怎么处理的。](https://www.jianshu.com/p/16b1baf015e8)
- [什么是一致性hash。](https://www.cnblogs.com/lpfuture/p/5796398.html)
@@ -163,9 +171,8 @@
- 一个在线文档系统,文档可以被编辑,如何防止多人同时对同
- 一份文档进行编辑更新。
- 线上系统突然变得异常缓慢,你如何查找问题。
- - [说说你平时用到的设计模式](http://tech.hunts.work/2015/09/01/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/#2-%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82simple-factory)。
- - Dubbo的原理,有看过源码么,数据怎么流转的,怎么实现集群,负载均衡,服务注册
- - 和发现,重试转发,快速失败的策略是怎样的 。
+ - [说说你平时用到的设计模式](https://github.com/Snailclimb/JavaGuide/blob/master/Java%E7%9B%B8%E5%85%B3/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md)。
+ - [Dubbo的原理,有看过源码么,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现,重试转发,快速失败的策略是怎样的 。](https://blog.csdn.net/he90227/article/details/70157046/)
- 一次RPC请求的流程是什么。
- [自己实现过rpc么,原理可以简单讲讲。Rpc要解决什么问题。](https://mp.weixin.qq.com/s/kHcbIgMFNB0np6olcPch4w)
- 异步模式的用途和意义。
@@ -188,8 +195,9 @@
- 分布式服务调用方,不依赖服务提供方的话,怎么处理服务方挂掉后,大量无效资源请求的浪费,如果只是服务提供方吞吐不高的时候该怎么做,如果服务挂了,那么一会重启,该怎么做到最小的资源浪费,流量半开的实现机制是什么。
- dubbo的泛化调用怎么实现的,如果是你,你会怎么做。
- 远程调用会有超时现象,如果做到优雅的控制,JDK自带的超时机制有哪些,怎么实现的。
+
### 数据结构与算法
-
+ - [用java自己实现一个LRU。](https://github.com/randian666/algorithm-study/blob/master/src/main/java/com/algorithm/study/demo/LRUCache/LRUMap.java)
- 10亿个数字里里面找最小的10个。
- 有1亿个数字,其中有2个是重复的,快速找到它,时间和空间要最优。
- 2亿个随机生成的无序整数,找出中间大小的值。
@@ -204,11 +212,17 @@
- 一个单向链表,删除倒数第N个数据。
- 200个有序的数组,每个数组里面100个元素,找出top20的元素。
- 单向链表,查找中间的那个元素。
+ - [如何判断一个数是否在40亿个整数中?](https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247484394&idx=1&sn=769e86bd815cf836eaa88a46836e4287&chksm=fd98558bcaefdc9d362f4d0912849924ae2d1f1277147edab7508cd3f1753ea4afd719237fa1&scene=21#wechat_redirect)
- [剑指Offer学习【所有面试题汇总】](https://blog.csdn.net/derrantcm/article/details/46887821)
+ - [Leetcode 题解](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/Leetcode%20%E9%A2%98%E8%A7%A3.md)
+ - [算法](https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/%E7%AE%97%E6%B3%95.md)
+ - [Leetcode-LinkList](https://github.com/Snailclimb/JavaGuide/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/Leetcode-LinkList1.md)
+ - [几道常见的子符串算法题](https://github.com/Snailclimb/JavaGuide/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/%E6%90%9E%E5%AE%9ABAT%E9%9D%A2%E8%AF%95%E2%80%94%E2%80%94%E5%87%A0%E9%81%93%E5%B8%B8%E8%A7%81%E7%9A%84%E5%AD%90%E7%AC%A6%E4%B8%B2%E7%AE%97%E6%B3%95%E9%A2%98.md)
+ - [数据结构](https://github.com/Snailclimb/JavaGuide/blob/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.md)
### 数据库
- [MySQL数据库的索引原理、与慢SQL优化的5大原则](https://www.toutiao.com/i6611390023797309960/)
- [数据库隔离级别有哪些,各自的含义是什么,MYSQL默认的隔离级别是是什么。](http://www.cnblogs.com/huanongying/p/7021555.html)
- - MYSQL有哪些存储引擎,各自优缺点。
+ - [MYSQL有哪些存储引擎,各自优缺点。](https://blog.csdn.net/liu857279611/article/details/51558927)
- 高并发下,如何做到安全的修改同一行数据。
- 乐观锁和悲观锁是什么,INNODB的标准行级锁有哪2种,解释其含义。
- SQL优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义。
@@ -217,15 +231,16 @@
- 聚集索引和非聚集索引的区别。
- select for update 是什么含义,会锁表还是锁行或是其他。
- 为什么要用Btree实现,它是怎么分裂的,什么时候分裂,为什么是平衡的。
- - 数据库的ACID是什么。
+ - [数据库的ACID是什么。](https://www.cnblogs.com/lichunyang321/p/9594196.html)
- 某个表有近千万数据,CRUD比较慢,如何优化。
- Mysql怎么优化table scan的。
- 如何写sql能够有效的使用到复合索引。
- - mysql中in 和exists 区别。
+ - [mysql中in 和exists 区别。](https://www.cnblogs.com/xiaoxiong-kankan/p/7928153.html)
- 数据库自增主键可能的问题。
- MVCC的含义,如何实现的。
- 你做过的项目里遇到分库分表了吗,怎么做的,有用到中间件么,比如sharding jdbc等,他们的原理知道么。
- MYSQL的主从延迟怎么解决。
+ - [MySQL索引背后的数据结构及算法原理](https://www.kancloud.cn/kancloud/theory-of-mysql-index/41846)
- [数据库面试问题集锦](https://blog.csdn.net/justloveyou_/article/details/78308460)
### 消息队列
@@ -245,6 +260,7 @@
### 缓存
- [Redis的高并发和快速原因](https://mp.weixin.qq.com/s/HuwgTvNtmHJ9tpF7V53opg)
- [常见的缓存策略有哪些,如何做到缓存(比如redis)与DB里的数据一致性,你们项目中用到了](https://mp.weixin.qq.com/s/yQjTddLWy-oSYPYxyGVeKw)
+ - [一文揭秘单线程的Redis为什么这么快?](https://mp.weixin.qq.com/s/4ndQI4CyqtjaYJKts8ChdA)
- 什么缓存系统,如何设计的。
- [如何防止缓存击穿和雪崩。](https://mp.weixin.qq.com/s/SQQy6NKvoAgIaeAjzkRpDw)
- 缓存数据过期后的更新如何设计。
@@ -252,21 +268,23 @@
- Redis的数据结构都有哪些。
- Redis的使用要注意什么,讲讲持久化方式,内存设置,集群的应用和优劣势,淘汰策略等。
- 当前redis集群有哪些玩法,各自优缺点,场景。
- - Memcache的原理,哪些数据适合放在缓存中。
- redis和memcached 的内存管理的区别。
- Redis的并发竞争问题如何解决,了解Redis事务的CAS操作吗。
- Redis的选举算法和流程是怎样的。
- - redis的持久化的机制,aof和rdb的区别。
+ - [redis的持久化的机制,aof和rdb的区别。](https://blog.csdn.net/jackpk/article/details/30073097)
- redis的集群怎么同步的数据的。
- 知道哪些redis的优化操作。
- - Reids的主从复制机制原理。
+ - [Reids的主从复制机制原理。](http://www.cnblogs.com/kevingrace/p/5685332.html)
- Redis的线程模型是什么。
- 请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存。
- 如何看待缓存的使用(本地缓存,集中式缓存),简述本地缓存和集中式缓存和优缺点。
- 本地缓存在并发使用时的注意事项。
+ - [Redis过期策略及实现原理](https://www.cnblogs.com/linuxprobe-sarah/p/10386800.html)
- [redis面试49题](https://mp.weixin.qq.com/s/5mLTVpjn_iebsOp60HFU2Q)
### 搜索
-
+ - [es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)?](https://doocs.github.io/advanced-java/#/docs/high-concurrency/es-architecture)
+ - [es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?](https://doocs.github.io/advanced-java/#/docs/high-concurrency/es-write-query-search)
+ - [es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?](https://doocs.github.io/advanced-java/#/docs/high-concurrency/es-optimizing-query-performance)
- elasticsearch了解多少,说说你们公司es的集群架构,索引数据大小,分片有多少,以及一些调优手段 。
- elasticsearch的倒排索引是什么。
- elasticsearch 索引数据多了怎么办,如何调优,部署。
diff --git a/image/931551357495_.pic.jpg b/image/931551357495_.pic.jpg
new file mode 100644
index 0000000..1003422
Binary files /dev/null and b/image/931551357495_.pic.jpg differ
diff --git a/image/WechatIMG2430.jpeg b/image/WechatIMG2430.jpeg
new file mode 100644
index 0000000..297c61e
Binary files /dev/null and b/image/WechatIMG2430.jpeg differ
diff --git a/pom.xml b/pom.xml
index 472abf1..5496700 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,46 @@
cglib
2.2.2
+
+
+
+ org.testng
+ testng
+ 6.14.3
+
+
+
+
+ com.google.guava
+ guava
+ 23.0
+
+
+
+ commons-io
+ commons-io
+ 2.4
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.8
+ provided
+
+
+
+ joda-time
+ joda-time
+ 2.10.1
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.9
+
+
diff --git a/src/main/java/com/algorithm/study/demo/LRUCache/LRUCache.java b/src/main/java/com/algorithm/study/demo/LRUCache/LRUCache.java
new file mode 100644
index 0000000..0fcbb70
--- /dev/null
+++ b/src/main/java/com/algorithm/study/demo/LRUCache/LRUCache.java
@@ -0,0 +1,152 @@
+package com.algorithm.study.demo.LRUCache;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * LRU缓存链表实现思路
+ * 每次写入数据时将数据放入链表头结点。
+ * 使用数据时候将数据移动到头结点。
+ * 缓存数量超过阈值时移除链表尾部数据。
+ * @Author: liuxun
+ * @CreateDate: 2018/7/12 下午6:05
+ * @Version: 1.0
+ */
+public class LRUCache {
+ class Node{
+ private int key;
+ private int value;
+ private Node prev;
+ private Node next;
+
+ public Node(int key,int value){
+ this.key=key;
+ this.value=value;
+ }
+ public Node(){}
+
+ public int getKey() {
+ return key;
+ }
+
+ public void setKey(int key) {
+ this.key = key;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public void setValue(int value) {
+ this.value = value;
+ }
+ }
+ private void moveToHead(Node node){
+ remove(node);
+ addNode(node);
+ }
+ //删除尾节点
+ private Node popTail(){
+ Node prevNode= tail.prev;
+ tail.prev=prevNode.prev;
+ prevNode.prev.next=tail;
+
+ prevNode.next=null;
+ prevNode.prev=null;
+
+ size--;
+ return prevNode;
+ }
+ //删除中间节点
+ private void remove(Node node){
+ Node prevNode=node.prev;
+ Node nextNode=node.next;
+
+ prevNode.next=nextNode;
+ nextNode.prev=prevNode;
+
+ node.next=null;
+ node.prev=null;
+
+ size--;
+ }
+ //添加节点
+ private void addNode(Node node){
+ node.next=head.next;
+ node.prev=head;
+ node.next.prev=node;
+ head.next=node;
+ size++;
+ }
+ private Map cache=new HashMap();
+ private int size=0;
+ private int capacity=0;
+ //头结点
+ private Node head;
+ //尾结点
+ private Node tail;
+ public LRUCache(int capacity) {
+ this.capacity=capacity;
+ //初始化头尾节点
+ this.head=new Node();
+ this.tail=new Node();
+ head.next=tail;
+ tail.prev=head;
+ }
+
+ public int get(int key) {
+ //从缓存获取
+ Node node=cache.get(key);
+ if(null==node){
+ return -1;
+ }
+ //数据移到头结点
+ moveToHead(node);
+ return node.value;
+ }
+
+ public void put(int key, int value) {
+ Node node=cache.get(key);
+ if(null==node){
+ node=new Node(key,value);
+ //写入新节点至头节点
+ addNode(node);
+ cache.put(key,node);
+ //如果容量已满,删除尾节点
+ if(size>capacity){
+ //删除尾节点
+ Node delNode=popTail();
+ cache.remove(delNode.key);
+ }
+ }else{
+ //数据更新并移到头结点
+ node.value=value;
+ moveToHead(node);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder() ;
+ for (Node node = head;node!=null;node=node.next){
+ sb.append(node.getKey()).append(":")
+ .append(node.getValue())
+ .append("-->");
+ }
+ return sb.toString();
+ }
+ public static void main(String[] args) {
+ LRUCache lruMap=new LRUCache(2);
+ lruMap.put(1,1);
+ lruMap.put(2,2);
+ lruMap.get(1);
+ lruMap.put(3,3);
+ lruMap.get(2);
+ lruMap.put(4,4);
+ lruMap.get(1);
+ lruMap.get(3);
+ lruMap.get(4);
+ System.out.println(lruMap.toString());
+ }
+
+}
diff --git a/src/main/java/com/algorithm/study/demo/LRUCache/LRULinked.java b/src/main/java/com/algorithm/study/demo/LRUCache/LRULinked.java
new file mode 100644
index 0000000..46befc4
--- /dev/null
+++ b/src/main/java/com/algorithm/study/demo/LRUCache/LRULinked.java
@@ -0,0 +1,90 @@
+package com.algorithm.study.demo.LRUCache;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 单链表实现LRU缓存
+ * @Author: liuxun
+ * @CreateDate: 2019/1/23 下午4:03
+ * @Version: 1.0
+ */
+public class LRULinked{
+ //缓存
+ private final Map cacheMap = new HashMap<>();
+ //根节点
+ private Node root;
+ private int cacheSize;
+ private int size;
+ public LRULinked(int cacheSize){
+ this.cacheSize=cacheSize;
+ }
+ /**
+ * 插入头结点
+ * @param value
+ */
+ public void put(int key,int value){
+ cacheMap.put(key,value);
+ Node node=new Node(key,value);
+ if (size==cacheSize){//容量满了删除尾节点
+ Node temp=root.next;
+ if (temp==null){
+ root=null;
+ }else{
+ Node current=root;
+ while (temp.next!=null){
+ current=temp;
+ temp=temp.next;
+ }
+ current.next=null;
+ }
+ size--;
+ }
+ node.next=root;
+ root=node;
+ size++;
+ }
+ public int get(int key){
+ if (!cacheMap.containsKey(key)){
+ return -1;
+ }
+ for (Node node = root; node!=null&&!root.key.equals(key); node=node.next){
+ if (node.next.key.equals(key)){
+ Node nodeNew=new Node(node.next.key,node.next.value);
+ node.next=node.next.next;
+ size--;
+ this.put(nodeNew.key,nodeNew.value);//查找的节点放到头结点
+ break;
+ }
+ }
+ return cacheMap.get(key);
+ }
+ @Override
+ public String toString(){
+ StringBuilder sb=new StringBuilder();
+ for (Node temp=root;temp!=null;temp=temp.next){
+ sb.append(temp.value);
+ }
+ return sb.toString();
+ }
+ class Node{
+ private Integer key;
+ private Integer value;
+ private Node next;
+ public Node(Integer key, Integer value){
+ this.key=key;
+ this.value=value;
+ }
+ }
+
+ public static void main(String[] args) {
+ LRULinked linked=new LRULinked(3);
+ linked.put(1,2);
+ linked.put(2,2);
+ linked.put(3,3);
+ System.out.println(linked.get(1));
+ linked.put(4,4);
+ System.out.println(linked.size);
+ System.out.println(linked.toString());
+ }
+}
diff --git a/src/main/java/com/algorithm/study/demo/LRUCache/LRULinkedMap.java b/src/main/java/com/algorithm/study/demo/LRUCache/LRULinkedMap.java
index 18dc367..7f84245 100644
--- a/src/main/java/com/algorithm/study/demo/LRUCache/LRULinkedMap.java
+++ b/src/main/java/com/algorithm/study/demo/LRUCache/LRULinkedMap.java
@@ -1,7 +1,5 @@
package com.algorithm.study.demo.LRUCache;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -11,33 +9,25 @@
* @CreateDate: 2018/7/12 下午8:42
* @Version: 1.0
*/
-public class LRULinkedMap {
+public class LRULinkedMap extends LinkedHashMap {
/**
* 最大缓存大小
*/
- private int cacheSize;
- private LinkedHashMap cacheMap ;
- public LRULinkedMap(int cacheSize) {
- this.cacheSize = cacheSize;
- cacheMap = new LinkedHashMap(16,0.75F,true){
- @Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- if (cacheSize + 1 == cacheMap.size()){
- return true ;
- }else {
- return false ;
- }
- }
- };
+ private int CACHESIZE;
+ public LRULinkedMap(int cacheSize){
+ // true 表示让 linkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。
+ super(cacheSize,0.75f,true);
+ CACHESIZE=cacheSize;
}
- public void put(K key,V value){
- cacheMap.put(key,value) ;
- }
- public V get(K key){
- return cacheMap.get(key) ;
- }
- public Collection> getAll() {
- return new ArrayList>(cacheMap.entrySet());
+
+ /**
+ * 删除元素条件
+ * @param eldest
+ * @return
+ */
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest){
+ return size()>CACHESIZE;
}
public static void main(String[] args) {
LRULinkedMap map = new LRULinkedMap(4) ;
@@ -47,7 +37,7 @@ public static void main(String[] args) {
map.put("4",4);
System.out.println(map.get("1"));
map.put("5",5);
- for (Map.Entry e : map.getAll()){
+ for (Map.Entry e : map.entrySet()){
System.out.print(e.getKey() + " : " + e.getValue() + "\t");
}
}
diff --git a/src/main/java/com/algorithm/study/demo/LRUCache/LRUMap.java b/src/main/java/com/algorithm/study/demo/LRUCache/LRUMap.java
deleted file mode 100644
index f0363a3..0000000
--- a/src/main/java/com/algorithm/study/demo/LRUCache/LRUMap.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package com.algorithm.study.demo.LRUCache;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * LRU缓存链表实现思路
- * 每次写入数据时将数据放入链表头结点。
- * 使用数据时候将数据移动到头结点。
- * 缓存数量超过阈值时移除链表尾部数据。
- * @Author: liuxun
- * @CreateDate: 2018/7/12 下午6:05
- * @Version: 1.0
- */
-public class LRUMap {
- private final Map cacheMap = new HashMap<>();
- /**
- * 最大缓存大小
- */
- private int cacheSize;
- /**
- * 节点大小
- */
- private int nodeCount;
- /**
- * 头结点
- */
- private Node header;
- /**
- * 尾结点
- */
- private Node tailer;
- public LRUMap(int cacheSize) {
- this.cacheSize = cacheSize;
- this.header=null;
- this.tailer=null;
- }
- public void put(K key, V value) {
- cacheMap.put(key, value);
- //双向链表中添加结点
- addNode(key, value);
- }
- public V get(K key){
- Node node = getNode(key);
- //移动到头结点
- moveToHead(node) ;
- return cacheMap.get(key);
- }
- private void moveToHead(Node node){
- //如果是最后的一个节点
- if (node.next == null){
- node.tail.next=null;
- tailer=node.tail;
- nodeCount -- ;
- }
- //如果是本来就是头节点 不作处理
- if (node.tail == null){
- return ;
- }
- //如果处于中间节点
- if (node.tail != null && node.next != null){
- //它的上一节点指向它的下一节点 也就删除当前节点
- node.tail.next=node.next;
- nodeCount -- ;
- }
- //最后在头部增加当前节点
- //注意这里需要重新 new 一个对象,不然原本的node 还有着下面的引用,会造成内存溢出。
- node = new Node<>(node.getKey(),node.getValue()) ;
- addHead(node) ;
- }
- /**
- * 链表查询 效率较低
- * @param key
- * @return
- */
- private Node getNode(K key){
- for (Node node = header;node!=null;node=node.next){
- if (node.getKey().equals(key)){
- return node ;
- }
- }
- return null ;
- }
- /**
- * 写入头结点
- * @param key
- * @param value
- */
- private void addNode(K key, V value) {
- Node node = new Node<>(key, value);
- //容量满了删除最后一个
- if (cacheSize == nodeCount) {
- //删除尾结点
- delTail();
- }
- //写入头结点
- addHead(node);
- }
- /**
- * 添加头结点
- *
- * @param node
- */
- private void addHead(Node node) {
- if (header==null){
- tailer=node;
- }else{
- header.tail=node;
- node.next=header;
- }
- header=node;
- nodeCount++;
- }
- private void delTail() {
- //把尾结点从缓存中删除
- cacheMap.remove(tailer.getKey());
- tailer.tail.next=null;
- tailer=tailer.tail;
- nodeCount--;
- }
- private class Node {
- private K key;
- private V value;
- Node tail;
- Node next;
- public Node(K key, V value) {
- this.key = key;
- this.value = value;
- }
- public Node() {
- }
- public K getKey() {
- return key;
- }
- public void setKey(K key) {
- this.key = key;
- }
- public V getValue() {
- return value;
- }
- public void setValue(V value) {
- this.value = value;
- }
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder() ;
- for (Node node = header;node!=null;node=node.next){
- if (node.getKey()!=null){
- sb.append(node.getKey()).append(":")
- .append(node.getValue())
- .append("-->");
- }
- }
- return sb.toString();
- }
- public static void main(String[] args) {
- LRUMap lruMap=new LRUMap<>(3);
- lruMap.put("1","1");
- lruMap.put("2","2");
- lruMap.put("3","3");
- lruMap.get("1");
- lruMap.put("4","4");
- System.out.println(lruMap.toString());
- System.out.println(lruMap.cacheSize);
- }
-
-}
diff --git a/src/main/java/com/algorithm/study/demo/MainTest.java b/src/main/java/com/algorithm/study/demo/MainTest.java
deleted file mode 100644
index ef0534b..0000000
--- a/src/main/java/com/algorithm/study/demo/MainTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.algorithm.study.demo;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-
-/**
- * @Author: liuxun
- * @CreateDate: 2019/1/2 上午11:29
- * @Version: 1.0
- */
-public class MainTest {
- public static void main(String[] args) {
- Object counter = new Object();
- ReferenceQueue refQueue = new ReferenceQueue<>();
- PhantomReference