https://www.cnblogs.com/chenpi/p/6395418.html

一、Java基础

  1. String类为什么是final的。
    安全,效率
    2. HashMap的源码,实现原理,底层结构。
    https://www.cnblogs.com/ITtangtang/p/3948406.html
    3. 说说你知道的几个Java集合类:list、set、queue、map实现类咯。。。
    https://blog.csdn.net/bn493235694/article/details/79600330
    4. 描述一下ArrayList和LinkedList各自实现和区别

    都是线程不安全的,但是有方法将这些变成线程安全的
    Collections.synchronizedList(list);
    Collections.synchronizedMap();
    Collections.synchronizedSet();
    Collections.synchronizedCollection() automicrefenrenc()

https://www.cnblogs.com/Alan-Jones/p/6426994.html

  1. Java中的队列都有哪些,有什么区别。
    https://www.cnblogs.com/yufeng218/p/9926465.html
    6. 反射中,Class.forName和classloader的区别

    而Class.forName(),除了会将.class文件加载到jvm内之外,还会对类进行解释,执行类中的static静态代码快。
    classLoader只干一件事,就是将.class加载到jvm之中,并不会对(static)静态代码快中的内容进行解析,只有在new Instance()方法的时候才会对static进行解析

  2. Java7、Java8的新特性(baidu问的,好BT)
    8. Java数组和链表两种结构的操作效率,在哪些情况下(从开头开始,从结尾开始,从中间开始),哪些操作(插入,查找,删除)的效率高

    数组读取快,增删比较慢,尤其是在开始位置或者中间位置增删的时候,需要将元素坐标统统修改; 链表读取慢,无法随机读取,需要通过遍历每个节点来获取需要查询的数据节点的位置;但是增删很快;原因是通过修改上一个节点和下一个节点两个节点的数据就够了;

  3. Java内存泄露的问题调查定位:jmap,jstack的使用等等
    10. string、stringbuilder、stringbuffer区别
    11. hashtable和hashmap的区别
    13 .异常的结构,运行时异常和非运行时异常,各举个例子
    14. String a= “abc” String b = “abc” String c = new String(“abc”) String d = “ab” + “c” .他们之间用 == 比较的结果
    15. String 类的常用方法
    16. Java 的引用类型有哪几种
    17. 抽象类和接口的区别
    18. java的基础类型和字节大小。
    19. Hashtable,HashMap,ConcurrentHashMap 底层实现原理与线程安全问题(建议熟悉 jdk 源码,才能从容应答)
    20. 如果不让你用Java Jdk提供的工具,你自己实现一个Map,你怎么做。说了好久,说了HashMap源代码,如果我做,就会借鉴HashMap的原理,说了一通HashMap实现
    21. Hash冲突怎么办?哪些解决散列冲突的方法?
    22. HashMap冲突很厉害,最差性能,你会怎么解决?从O(n)提升到log(n)咯,用二叉排序树的思路说了一通
    23. rehash
    24. hashCode() 与 equals() 生成算法、方法怎么重写

    二、Java IO

  4. 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。
    2. 讲讲NIO。
    3. String 编码UTF-8 和GBK的区别?
    4. 什么时候使用字节流、什么时候使用字符流?
    5. 递归读取文件夹下的文件,代码怎么实现

    三、Java Web

  5. session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。
    2. servlet的一些相关问题
    3. webservice相关问题
    4. jdbc连接,forname方式的步骤,怎么声明使用一个事务。举例并具体代码
    5. 无框架下配置web.xml的主要配置内容
    6. jsp和servlet的区别

    四、JVM

  6. Java的内存模型以及GC算法
    2. jvm性能调优都做了什么
    3. 介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明
    4. 介绍GC 和GC Root不正常引用。
    5. 自己从classload 加载方式,加载机制说开去,从程序运行时数据区,讲到内存分配,讲到String常量池,讲到JVM垃圾回收机制,算法,hotspot。反正就是各种扩展
    6. jvm 如何分配直接内存, new 对象如何不分配在堆而是栈上,常量池解析
    7. 数组多大放在 JVM 老年代(不只是设置 PretenureSizeThreshold ,问通常多大,没做过一问便知)
    8. 老年代中数组的访问方式
    9. GC 算法,永久代对象如何 GC , GC 有环怎么处理
    10. 谁会被 GC ,什么时候 GC
    11. 如果想不被 GC 怎么办
    12. 如果想在 GC 中生存 1 次怎么办

    五、开源框架

  7. hibernate和ibatis的区别
    2. 讲讲mybatis的连接池。
    3. spring框架中需要引用哪些jar包,以及这些jar包的用途
    4. springMVC的原理
    5. springMVC注解的意思
    6. spring中beanFactory和ApplicationContext的联系和区别
    7. spring注入的几种方式(循环注入)
    8. spring如何实现事物管理的
    9. springIOC
    10. spring AOP的原理
    11. hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)
    12. Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理。

    六、多线程

  8. Java创建线程之后,直接调用start()方法和run()的区别
    2. 常用的线程池模式以及不同线程池的使用场景
    3. newFixedThreadPool此种线程池如果线程数达到最大值后会怎么办,底层原理。
    4. 多线程之间通信的同步问题,synchronized锁的是对象,衍伸出和synchronized相关很多的具体问题,例如同一个类不同方法都有synchronized锁,一个对象是否可以同时访问。或者一个类的static构造方法加上synchronized之后的锁的影响。
    5. 了解可重入锁的含义,以及ReentrantLock 和synchronized的区别
    6. 同步的数据结构,例如concurrentHashMap的源码理解以及内部实现原理,为什么他是同步的且效率高
    7. atomicinteger和Volatile等线程安全操作的关键字的理解和使用
    8. 线程间通信,wait和notify
    9. 定时线程的使用
    10. 场景:在一个主线程中,要求有大量(很多很多)子线程执行完之后,主线程才执行完成。多种方式,考虑效率。
    11. 进程和线程的区别
    12. 什么叫线程安全?举例说明
    13. 线程的几种状态
    14. 并发、同步的接口或方法
    15. HashMap 是否线程安全,为何不安全。 ConcurrentHashMap,线程安全,为何安全。底层实现是怎么样的。
    16. J.U.C下的常见类的使用。 ThreadPool的深入考察; BlockingQueue的使用。(take,poll的区别,put,offer的区别);原子类的实现。
    17. 简单介绍下多线程的情况,从建立一个线程开始。然后怎么控制同步过程,多线程常用的方法和结构
    18. volatile的理解
    19. 实现多线程有几种方式,多线程同步怎么做,说说几个线程里常用的方法

    七、网络通信

  9. http是无状态通信,http的请求方式有哪些,可以自己定义新的请求方式么。
    2. socket通信,以及长连接,分包,连接异常断开的处理。
    3. socket通信模型的使用,AIO和NIO。
    4. socket框架netty的使用,以及NIO的实现原理,为什么是异步非阻塞。
    5. 同步和异步,阻塞和非阻塞。
    6. OSI七层模型,包括TCP,IP的一些基本知识
    7. http中,get post的区别
    8. 说说http,tcp,udp之间关系和区别。
    9. 说说浏览器访问www.taobao.com,经历了怎样的过程。
    10. HTTP协议、 HTTPS协议,SSL协议及完整交互过程;
    11. tcp的拥塞,快回传,ip的报文丢弃
    12. https处理的一个过程,对称加密和非对称加密
    13. head各个特点和区别
    14. 说说浏览器访问www.taobao.com,经历了怎样的过程。

    八、数据库MySql

  10. MySql的存储引擎的不同
    https://blog.csdn.net/keil_wang/article/details/88392433
    2. 单个索引、联合索引、主键索引
    https://www.cnblogs.com/programb/p/13020812.html
    3. Mysql怎么分表,以及分表后如果想按条件分页查询怎么办(如果不是按分表字段来查询的话,几乎效率低下,无解)
    1 读写分离;缺点是主写的压力没有得到减缓
    2 分库分表;连表不方便

    1、设计全局表

    所谓全局表,就是有可能系统中所有模块都可能会依赖到的一些表。比较类似我们理解的“数据字典”。为了避免跨库join查询,我们可以将这类表在其他每个数据库中均保存一份。同时,这类数据通常也很少发生修改(甚至几乎不会),所以也不用太担心“一致性”问题。

    2、数据同步

    假如A库中的tab_a表和B库中tbl_b有关联,可以定时将指定的表做同步。当然,同步本来会对数据库带来一定的影响,需要性能影响和数据时效性中取得一个平衡。这样来避免复杂的跨库查询。有很多优秀的数据同步的中间件可以选择,开发中复杂度不算高,开发中使用也较多。 或者干脆就不要在SQL中进行复杂的关联查询了,直接单表查询在系统层面去组装,同样很流行,而且写起来很爽。笔者之前有写过关于单表查询和join查询的对比建议,可以参考:

  11. 分表之后想让一个id多个表是自增的,效率实现

    1 单独搞一个表做自增序列 2 redis自增数据 3 数据库自增序列修改自增跨度(极不推荐) 4 java代码实现自增;

  12. MySql的主从实时备份同步的配置,以及原理(从库读主库的binlog),读写分离
    读写分离的条件就是主从复制; 实现读写分离两种方式,应用层,自己动态获取不同的数据源(spring的abstractRoutingDatasource);或者中间件(Mycat)
    6. 写SQL语句。。。
    7. 索引的数据结构,B+树 聚簇索引
    8. 事务的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些问题
    9. 数据库的锁:行锁,表锁;乐观锁,悲观锁
    10. 数据库事务的几种粒度;
    行锁 页锁 表锁
    共享锁 排他锁

  13. 关系型和非关系型数据库区别
    https://blog.csdn.net/aaronthon/article/details/81714528
    nosql安装部署方便,查询速度快、键值对存储。。。。

  14. 主从复制的原理,问题呢,如果规避

https://www.cnblogs.com/zhangchaocoming/p/13033064.html

  1. binlog 和中继日志 relay log
  2. 延迟
  3. 强制查主

由于从库从主库拷贝日志以及串行执行SQL的特点,在高并发场景下,从库的数据一定会比主库慢一些,是有延时的。所以经常出现,刚写入主库的数据可能是读不到的,要过几十毫秒,甚至几百毫秒才能读取到。
而且这里还有另外一个问题,就是如果主库突然宕机,然后恰好数据还没同步到从库,那么有些数据可能在从库上是没有的,有些数据可能就丢失了

mysql的两个机制:

一个是半同步复制,用来解决主库数据丢失问题; semi-sync复制,指的就是主库写入binlog日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的relay log之后,接着会返回一个ack给主库,主库接收到至少一个从库的ack之后才会认为写操作完成了
# 一个是并行复制,用来解决主从同步延时问题。 指的是从库开启多个线程,并行读取relay log中不同库的日志,然后并行重放不同库的日志,这是库级别的并行。


九、设计模式

  1. 单例模式:饱汉、饿汉。以及饱汉中的延迟加载, 双重检查
    饱汉:类属性直接new出对象,private static Singleton1 singleton = new Singleton1();

双重检查饱汉:

public class Singleton3 { private static volatile Singleton3 singleton; //防止重排序,因为singleton 的赋值和初始化顺序不能保证 private Singleton3(){ } public static Singleton3 getInstance(){ if(singleton == null){ //减少每次不必要的同步开销 synchronized(Singleton3.class){ if(singleton == null){ singleton = new Singleton3(); } } } return singleton; } }

建议还是使用静态内部类实现单例,简单安全
2. 工厂模式、装饰者模式、观察者模式。
装饰者模式:Java中的IO, 为对象增加行为
观察者模式: 订阅的感觉
3. 工厂方法模式的优点(低耦合、高内聚,开放封闭原则)

十、算法

  1. 使用随机算法产生一个数,要求把1-1000W之间这些数全部生成。(考察高效率,解决产生冲突的问题)
    Set存储,根据Set大小来判断循环终止。

    int value = 10000000; Set result = Sets.newHashSetWithExpectedSize(value); Random random = new Random(); long a = System.currentTimeMillis(); while (result.size() < value + 1) { int i = random.nextInt(value + 1); result.add(i); }

  2. 两个有序数组的合并排序
    3. 一个数组的倒序
    4. 计算一个正整数的正平方根
    5. 说白了就是常见的那些查找、排序算法以及各自的时间复杂度
    6. 二叉树的遍历算法
    先序、后序、中序,注意这里的先、中、后针对的是根节点。
    7. DFS, BFS算法
    深度优先:基于栈
    广度优先:基于队列
    9. 比较重要的数据结构,如链表,队列,栈的基本理解及大致实现。
    10. 排序算法与时空复杂度(快排为什么不稳定,为什么你的项目还在用)
    快排:
    46 30 82 90 56 17 95 15

15 30 82 90 56 17 95 46

15 30 82 90 56 17 95 46

15 30 46 90 56 17 95 82

15 30 46 90 56 17 95 82

15 30 17 90 56 46 95 82

15 30 17 46 56 90 95 82

15 30 17 46 56 90 95 82

  1. 逆波兰计算器
    12. Hoffman编码
    带权路径长度最小的二叉树,常用于数据压缩。
    根据出现的概率进行编码,出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码;

  2. 查找树与红黑树

    十一、并发与性能调优

  3. 有个每秒钟5k个请求,查询手机号所属地的笔试题(记得不完整,没列出),如何设计算法?请求再多,比如5w,如何设计整个系统?
    ,使用缓存,查询服务集群部署,
    2. 高并发情况下,我们系统是如何支撑大量的请求的
    使用缓存,性能调优,服务器集群。。。
    3. 集群如何同步会话状态
    1、利用数据库
    2、利用缓存服务器
    3、利用cookie
    4. 负载均衡的原理
    负载均衡算法:
    1、轮询法
    将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
    2、随机法
    通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,
    其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。
    3、源地址哈希法
    源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。
    4、加权轮询法
    不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。
    5、加权随机法
    与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。
    6、最小连接数法
    最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。
    5 .如果有一个特别大的访问量,到数据库上,怎么做优化(DB设计,DBIO,SQL优化,Java优化)
    分库分表、读写分离、SQL优化…
    6. 如果出现大面积并发,在不增加服务器的基础上,如何解决服务器响应不及时问题。
    乐观锁??性能调优?
    7. 假如你的项目出现性能瓶颈了,你觉得可能会是哪些方面,怎么解决问题。
    数据库?并发太大?分库分表,读写分离,负载均衡,代码优化。
    8. 如何查找 造成 性能瓶颈出现的位置,是哪个位置照成性能瓶颈。
    使用性能负载测试工具,如loadrunner;
    各个模块进行性能测试,添加日志,分析….;
    9. 你的项目中使用过缓存机制吗?有没有用过非本地缓存?
    Spring的方法级别缓存,一般需要提供一个key,这个key可以是方法入参,一般像用户的增删改查,可以是用户id,使用@Cacheable、@CachePut、@CacheEvict对缓存进行查、更新、删除。
    非本地缓存:单独一个redis服务,通过API访问redis服务器上的数据,存放一些实时数据很历史数据(若干条);

    十二、其他

    1.常用的linux下的命令
    ls 显示文件或目录
    mkdir 创建目录
    cd 切换目录
    cat 查看文件内容
    cp 拷贝
    rm 删除文件(参数:-r 递归 -f 强制删除)
    tail 查看文件后几行(参数:-f 不停的更新 -n 多少行)

head 查看文件前几行



十三 实际

1 数据库优化
2 数据库索引结构,聚簇索引
3 锁类型,原理 aqs原理 volitile作用
https://www.cnblogs.com/dolphin0520/p/3920373.html

volatile 一:禁止指令重排:1当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行; 2 在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行 ;下图为详解 image.png 二: 保证内存可见性,降至将线程的工作内存作废,取主存中读取最新数据,并且第一时间更新到主存中,从而保证了这个数据对于所有线程都是最新的; 三: 保证原子性;(只有直接赋值(int x = 1; )是原子操作; y = x; x++;++x; x=x+1等都不是原子操作;都是先从读取x,然后再赋值; 1 以上三点换成官方的总结 下面这段话摘自《深入理解Java虚拟机》: “观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令” lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能: 1)它确保指令重排序时不会把其后面的指令排到内存屏障(有volatile命令修饰的变量的代码行)之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成; 2)它会强制将对缓存的修改操作立即写入主存; 3)如果是写操作,它会导致其他CPU中对应的缓存行无效。


4 线程池的关键参数 拒绝策略 队列类型区别
线程池类型

1. newSingleThreadExecutor 创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。 2.newFixedThreadPool 创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 3. newCachedThreadPool 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程, 那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。 4.newScheduledThreadPool 创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

队列类型

1、ArrayBlockingQueue
是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
2、LinkedBlockingQueue
一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
3、SynchronousQueue
一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool(5)使用了这个队列。
4、PriorityBlockingQueue
一个具有优先级的无限阻塞队列

5 es理解;
6 全局id获取方式

  1. redis为什么要有淘汰机制?
  2.   redis淘汰机制的存在是为了更好的使用内存,用一定的缓存丢失来换取内存的使用效率。
  3. redis的过期策略
  4.   redis有两种过期策略,定期删除和惰性删除
  5. 定期删除:redis每个100ms随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。
  6. 惰性删除:在获取某个key的时候,redis检查一下,如果该key设置了过期时间则判断该过期时间是否已经过期,如果过期了就直接删掉并不返回任何东西。
  7. redis的内存淘汰机制
  8.   redis内存快耗尽时,redis会启动内存淘汰机制,将部分key清掉以腾出内存。
  9. redis提供6中数据淘汰策略,可在redis.conf中配置:maxmemory-policy noeviction
  10. noeviction:禁止驱逐数据。默认配置都是这个。当内存使用达到阀值的时候,所有引起申请内存的命令都会报错。
  11. volatile-lru:从设置了过期时间的数据集中挑选最近最少使用的数据淘汰。
  12. volatile-ttl:从已设置了过期时间的数据集中挑选即将要过期的数据淘汰。
  13. volatile-random:从已设置了过期时间的数据集中任意选择数据淘汰。
  14. allkeys-lru:从数据集中挑选最近最少使用的数据淘汰。
  15. allkeys-random:从数据集中任意选择数据淘汰。
  16.   Redis确定好要驱逐某个键值对后,会删除这个数据,并将这个数据变更消息同步到本地和从机。

7 redis持久化
rdb 15分钟 1次
5分钟 10次
1分钟 1w次
aof allways 每次
everysec 每秒
no 从不
8 redis为什么快
基于内存实现(避免了磁盘io)
高效的树结构
合理的编码
合适的线程模型
i/o多路复用
避免上下文切换
单线程模型

—I/O多路复用,I/O就是指的我们网络I/O,多路指多个TCP连接(或多个Channel),复用指复用一个或少量线程。串起来理解就是很多个网络I/O复用一个或少量的线程来处理这些连接;多路复用的本质是同步非阻塞I/O,多路复用的优势并不是单个连接处理的更快,而是在于能处理更多的连接。 redis内部有个“文件事件分配器”
image.png

9 倒排索引
Elasticsearch中的倒排索引是什么

10 aop ioc 动态代理 循环依赖解决
AOP的核心思想就是“将应用程序中的商业逻辑对其提供支持的通用服务进行分离。” 切面编程 日志 权限 事务
ioc 控制反转 依赖注入
ioc详解:https://www.cnblogs.com/ITtangtang/p/3978349.html
https://zhuanlan.zhihu.com/p/29344811
11 分布式锁 分布式事务
12 sychronized lock 原理 对比
https://www.cnblogs.com/aspirant/p/11470858.html

无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态锁可以从偏向锁升级到轻量级锁,再升级的重量级锁。但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级
image.png
偏向锁就是一般只有一个线程来执行,没有并发,那么上一个偏向锁,节省资源;但是如果这个时候有了另一个并发线程了,就需要锁撤销,然后升级轻量锁,这个是内部自旋,默认占有资源的线程将很快结束,我这边轻量级锁虽然没有获取到资源但是也不挂起仍不断的尝试去获取;
重量级锁就是不用自旋;进来就直接阻塞,获取不到就等待唤起;

13 hashmap hashtable concurrentMap 的区别
https://www.cnblogs.com/heyonggang/p/9112731.html
14 redis 过期策略 删除策略

  • noeviction:不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,这种策略下可以保证数据不丢失,它也是 Redis 默认的内存淘汰策略。
  • allkeys-lru:淘汰整个键值中最久未使用的键值,这也就是我们常说的LRU算法。
  • allkeys-random:随机淘汰任意键值。
  • volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值。
  • volatile-random:随机淘汰设置了过期时间的任意键值。
  • volatile-ttl:优先淘汰设置了过期时间中更早过期的键值。

15 对象的初始化过程 Dog dog = new Dog();
1 加载class文件;
2 jvm装在class文件,生成class对象;这个时候如果有静态的方法或者变量,静态初始化动作都会被执行
3 分配内存空间,所有属性方法给默认值
4 执行构造方法,
5 检查是否有父类,如果没有,执行构造方法;完事儿了;

如果有父类:1 加载过程中发现他有一个基类(通过 extends 关键字),于是先执行 基类(父类)的第一二步,加载其静态变量和方法,加载结束之后再加载子类 Dog 的静态变量和方法。 如果 Animal 类还有父类就以此类推,最终的基类叫做根基类。 注意:因为子类的 static 初始化可能会依赖于父类的静态资源,所以要先加载父类的静态资源。 2、接着要 new Dog 对象,先为 Dog 对象分配存储空间 -> 到 Dog 的构造函数 -> 创建默认的属性。这里其构造函数里面的第一行有个隐含的 super(),即父类构造函数,所以这时会跳转到父类 Animal 的构造函数。 3.父类 Animal 执行构造函数前也是分配存储空间 -> 到其构造函数 -> 创建默认的属性 -> 发现挖槽我已经没有父类了,这个时候就给它的默认的属性赋值和方法的初始化。 4、接着执行构造函数余下的部分,结束后跳转到子类 Dog 的构造函数。 5、子类 Dog 对默认属性和方法分别进行赋值和初始化,接着完成构造函数接下来的部分。

<br />16  mysql 事务  spring事务的关系

17 juc 包 常用类 线程交替执行 有序执行 线程通信
conditional countdownLatch cycleBerrie 回环栅栏 samaphore 信号量 都能实现交替
补充一下 thread.join(这个也是阻塞主线程的) future.get(这个是阻塞的) 两种方式适用于synchornized的方式;别的方式都是用lock包的方式

AQS 框架 callable接口 阻塞队列接口 ArrayBlockQueue 线程池 concurrentHashMap concurrentLinkedQueue locks包 atomic包 reentrantLock countdonwLatch 信号量 cyclicBarrier回环 future

线程循序执行:https://www.cnblogs.com/wenjunwei/p/10573289.html 1 利用线程的join方法 等待该线程结束才继续 2 利用线程的wait (这个需要创建多个线程、多个标识位,线程线程之间根据标识位来回互相) 3 利用单线程池,将多个线程submit到线程池里; 4 使用线程的Conditional(条件变量)方法 Condition是一个多线程间协调通信的工具类,使得某个,或者某些线程一起等待某个条件(Condition),只有当该条件具备( signal 或者 signalAll方法被带调用)时 ,这些等待线程才会被唤醒,从而重新争夺锁。

线程交替执行https://www.cnblogs.com/c1024/p/11012008.html 1 利用conditional 循环唤起 conditional.await() conditional.sigal() 2 利用信号量private static Semaphore s1 = new Semaphore(1); //关键点就是,设置多个信号量,每个信号量的许可数分别设置为1,开始线程之前随便锁定(n-1)个,然后起n个线程,每个线程用一个信号量,这样的话,其中N-1个再获取许可的时候阻塞了,只有一个启动了,然后逐个线程中分别释放别的信号量,循环释放的的话,可以实现交替循环执行,如果最后一个信号量释放之后,不在释放第一个,那就退出了; s2.acquire(); 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞 s2.release(); 释放一个许可,将其返回给信号量

18 kafaka 五大核心api

send

19 主键索引 唯一索引区别 索引类型(普通 唯一 主键(特殊的唯一索引)组合索引)

主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。 唯一性索引列允许空值,而主键列不允许为空值。 主键列在创建时,已经默认为空值 + 唯一索引了。 主键可以被其他表引用为外键,而唯一索引不能。 一个表最多只能创建一个主键,但可以创建多个唯一索引。 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。 在 RBO 模式下,主键的执行计划优先级要高于唯一索引。 两者可以提高查询的速度。

19.1 聚簇索引 非聚簇索引

InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分; 一般建表会用一个自增主键做聚簇索引,没有的话MySQL会默认创建,但是这个主键如果更改代价较高,故建表时要考虑自增ID不能频繁update这点。 我们日常工作中,根据实际情况自行添加的索引都是辅助索引,辅助索引就是一个为了需找主键索引的二级索引,现在找到主键索引再通过主键索引找数据;

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式
20 数据库引擎对比

myism 不支持事务 表锁 select insert很快 innodb 事务 外键 表锁 行锁
memory 储存介质内存 断电很麻烦 该文件中只存储表的结构。而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。 MERGE MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须完全相同,尽管其使用不如其它引擎突出,但是在某些情况下非常有用。说白了,Merge表就是几个相同MyISAM表的聚合器;Merge表中并没有数据,对Merge类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行操作。Merge存储引擎的使用场景。

21 redis 持久化
22 为什么用shardingphere 不用shrdingjdbc mycat
https://www.jianshu.com/p/ae694707689e
http://www.javashuo.com/article/p-tuwyvtvg-nx.html(这个讲的不错)

总结: shardingsphere 是apache顶级项目了; shardingjdbc jar 放在项目中的; sharding proxy mycat 这是中间件,单独的客户端; Mycat 和 ShardingSphere 都是很是流行的开源分布式数据库中间件,各自具备一些独特的功能,也有不少企业成功应用的案例。经过我的比较这二者的官方文档、社区活跃度等信息,目前 Apache ShardingSphere 体系更加完善,社区更加活跃。这二者都是国人开源产品中的佼佼者,但愿可以愈来愈好! 另外,还有一款值得关注的分布式数据库中间件 DBLE(专一于 MySQL),能够看作 Mycat 加强版。

23 springboot 核心注解 start编写要素

@Configuration @ComponentScan 开启组件扫描,即自动扫描包路径下的 @Component 注解进行注册 bean 实例到 context 中 @EnableAutoConfiguration

@SpringBootApplication 启动类
@EnableCoreConfiguration
@EnablePermission
@EnableAsync
@EnableOperateLogger
@ComponentScan({“com.yjyz.erp.trans.api”,“com.yjyz.core.utils”})

手写start 1 新建项目,导入springboot autoconfig springboot config process依赖 2 创建一个properties,与配置文件的属性对应 @ConfigurationProperties(prefix = “spring.person”) 3 创建要给要自动注入的类 **service.java 这个类里注入上一步骤写的properties 拿到配置 4 写一个自己的autoConfigure类; @Configuration @EnableConfigurationProperties(PersonProperties.class) @ConditionalOnClass(PersonService.class) @ConditionalOnProperty(prefix = “spring.person”, value = “enabled”, matchIfMissing = true) 用 @bean 和 @configureOnMissingBean(service.class)档容器中没有**service类的时候自动注入 5 自己编写 meta_inf/spring.factories 文件 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.cnbi.PersonServiceAutoConfiguration 把自己写的自动配置类的全类名配置进去

24 component service区别

@Component, @Service, @Controller, @Repository是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理
@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能
@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能
@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层
用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发

25 spring事务控制实现原理
https://zhuanlan.zhihu.com/p/228451195 这个很不错,就是有点长
26 cms jone
27 一个数据库只能有一个存储引擎嘛
28 springmvc 组件

DispatcherServlet DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自己定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。 DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。 HandlerMapping HandlerMapping 是处理器映射,它的作用是请求派发,负责请求和控制器建立对应的关系。它是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler。也就是说,DispatcherServlet要将一个请求交给哪个特定的Controller,它需要咨询一个Bean,这个Bean的名字为“HandlerMapping”。 Controller 控制器,负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。 ModelAndView
封装数据信息和视图信息的模型。使用ModelAndView类用来存储处理完后的结果数据,以及显示该数据的视图。从名字上看ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用。业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该Spring MVC框架。框架通过调用配置文件中定义的视图解析器,对该对象进行解析,最后把结果数据显示在指定的页面上。 ViewResolver
视图解析器,ViewResolver 的主要作用是把一个逻辑上的视图名称解析为一个真正的视图。 五大组件的关系 DispatcherServlet收到请求后,依据HandlerMapping的配置,调用相应的Controller来处理,Controller将处理结果封装成ModelAndView对象,返回给DispatcherServlet,DispatcherServlet依据ViewResolver的解析,调用相应的视图对象,(如jsp)来生成相应的页面。

29 springcloud 组件介绍 nocos

30 redis常用命令
springboot中使用redis 的客户端 我们用redisTemplate 底层是 “SpringBoot2集成redis,使用lettuce客户端”
https://blog.csdn.net/qq_28474017/article/details/103470308

jedis采用的是直连redis server,在多个线程之间共用一个jedis实例时,是线程不安全的。如果想避免线程不安全,可以使用连接池pool,这样每个线程单独使用一个jedis实例。由此带来的问题时,如果线程数过多,带来redis server的负载加大。有点类似于BIO的模式。

lettuce采用netty连接redis server,实例可以在多个线程间共享,不存在线程不安全的情况,这样可以减少线程数量。当然,在特殊情况下,lettuce也可以使用多个实例。有点类似于NIO的模式。

31 线程池拒绝策略

丢弃不报错 丢弃抛出异常 丢弃最前面的,然后重新提交最后这个 由调用线程处理该任务 如果任务被拒绝了,则由调用线程(提交任务的线程)直接执行此任务

32 守护线程

public static void main(String [] args) throws InterruptedException { Thread thread = new Thread(new DaemonThreadDemo()); //开启守护线程 调用start之前调用 会随着主线程休眠退出 thread.setDaemon(true); thread.start(); Thread.sleep(2000L); } 任何一个守护线程都是整个程序中所有用户线程的守护者,只要有活着的用户线程,守护线程就活着 建议:尽量少使用守护线程,因为不可控不要在守护线程里进行读写操作、执行计算逻辑

33 双路排序 单路排序

双路排序(又叫回表排序模式):先根据相应的条件取出相应的排序字段和可以直接定位行 数据的行 ID,然后在 sort buffer 中进行排序,排序完后需要再次取回其它需要的字段; 两次io
单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序; sort buffer 足够大的话,一次io 如果sort buff不够,这里就会分多次读取;反而更慢 至于mysql优化器使用双路排序还是单路排序是有自己的算法判断的,如果查询的列字段大于max_length_for_sort_data变量,则会使用双路排序,反之则会使用单路排序,单路排序速度是更快的,不过比较占据内存,如果在内存空间允许的情况下想要使用单路排序的话,可以增加max_length_for_sort_data变量的大小,max_length_for_sort_data变量默认为1024字节。

数据库优化 : sql 优化 配置优化: 内存呀 sort buffer size啊 max_length_for_sort_data(决定了是双路排序还是单路排序)read rnd buffer size 随机对缓冲区大小

34 链表快速定位到某个位置(双指针)
35 mybatis 实现原理

=25 增驾,买车

补偿机制