java常见问题

文章目录

一、Java 基础

成长地址:大牛之路,走上巅峰

1.JDK 和 JRE 有什么区别?

  • jdk为可编译开发运行,jre只可保证运行

2.== 和 equals 的区别是什么?

java中 = =对于基础类型来说比较的是值,对于引用类型则是比较内存地址

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

不对因为可能会有hash冲突

4.final 在 java 中有什么作用?

不可继承,且设定final的值不可改变

5.java 中的 Math.round(-1.5) 等于多少

     *Math.sqrt()//计算平方根
     *Math.cbrt()//计算立方根
     *Math.pow(a, b)//计算a的b次方
     *Math.max( , );//计算最大值
     *Math.min( , );//计算最小值
     *Math,round(-1.5) //-2 四舍五入值

6.String 属于基础的数据类型吗?

不属于,为英语类型 
基础类型有8种,byte 1字节,short 2字节,char 2字节,int 4字节,float 4字节,long 8字节,double -8字节,boolean 4字节,

7.java 中操作字符串都有哪些类?它们之间有什么区别?

String,StringBuffer,StringBuilder
其中Buffer线程安全其实现采用的synchronized
Builder线程不安全,但是其性能好,操作字符串快

8.String str="i"与 String str=new String(“i”)一样吗?

不一样,new可能创建两个对象,

9.如何将字符串反转?

循环倒序

10.String 类的常用方法都有那些?

1、和长度有关:

返回类型 方法名 作用
int length() 得到一个字符串的字符个数
2、和数组有关:

返回类型 方法名 作用
byte[] getByte() 将一个字符串转换成字节数组
char[] toCharArray() 将一个字符串转换成字符数组
String split(String) 将一个字符串按照指定内容劈开
3、和判断有关:

返回类型 方法名 作用
boolean equals() 判断两个字符串的内容是否一样
boolean equalsIsIgnoreCase(String) 忽略太小写的比较两个字符串的内容是否一样
boolean contains(String) 判断一个字符串里面是否包含指定的内容
boolean startsWith(String) 判断一个字符串是否以指定的内容开头
boolean endsWith(String) 判断一个字符串是否以指定的内容结尾
4、和改变内容有关:

返回类型 方法名 作用
String toUpperCase() 将一个字符串全部转换成大写
String toLowerCase() 将一个字符串全部转换成小写
String replace(String,String) 将某个内容全部替换成指定内容
String replaceAll(String,String) 将某个内容全部替换成指定内容,支持正则
String repalceFirst(String,String) 将第一次出现的某个内容替换成指定的内容
String substring(int) 从指定下标开始一直截取到字符串的最后
String substring(int,int) 从下标x截取到下标y-1对应的元素
String trim() 去除一个字符串的前后空格
5、和位置有关:

返回类型 方法名 作用
char charAt(int) 得到指定下标位置对应的字符
int indexOf(String) 得到指定内容第一次出现的下标
int lastIndexOf(String) 得到指定内容最后一次出现的下标
原文链接:https://blog.csdn.net/sinat_41920065/article/details/107439921

11.抽象类必须要有抽象方法吗?

不必

12.普通类和抽象类有哪些区别?

抽象类只关注对类相同的概念进行提取,为找通性
普通类继承抽象类而实现其抽象方法
抽象类可以有抽象方法和普通方法
普通类不可用有抽象方法

13.抽象类能使用 final 修饰吗?

不能,因为final不能被继承

14.接口和抽象类有什么区别?

接口可以无限实现,但是抽象类只能继承一种

15.java 中 IO 流分为几种?

inputStream,outputStream

16.BIO、NIO、AIO 有什么区别?

bio:同步阻塞IO流,只要当前在操作流,其它就不可操作
nio:同步非阻塞IO流,入netty的线程选择模型,
aio:异步非阻塞IO流,

17.Files的常用方法都有哪些?

Files.exists():检测文件路径是否存在。

Files.createFile():创建文件。

Files.createDirectory():创建文件夹。

Files.delete():删除一个文件或目录。

Files.copy():复制文件。

Files.move():移动文件。

Files.size():查看文件个数。

Files.read():读取文件。

Files.write():写入文件。

原文链接:https://blog.csdn.net/yangzhihong650/article/details/105095517

二、容器

18.java 容器都有哪些?

在这里插入图片描述

19.Collection 和 Collections 有什么区别?

20.List、Set、Map 之间的区别是什么?

list无序数组,
set有序集合
map键值对集合

21.HashMap 和 Hashtable 有什么区别?

hashMap线程不安全允许有空值,hashtable线程安全不允许有空值

22.如何决定使用 HashMap 还是 TreeMap?

根据官方文档的介绍,TreeMap底层是一个红黑树,map是根据keys进行自然排序或者定制排序。

自然排序和定制排序的用法和TreeSet类似。

使用自然排序:需要在类中继承Comparable接口,并重写compareTo方法。

23.说一下 HashMap 的实现原理?

数组 + 链表如容量大于64链表长度大于8会转换红黑树
HashMap在JDK1.7和JDK1.8中的区别
前面一直提到树状结构和红黑树,这是HashMap在JDK1.7和JDK1.8之间最大的区别。数组+链表的结构下,如果一个索引后跟着的链表数量很多时,会很影响查找效率,因此在JDK1.8中,HashMap当满足某种条件(链表长度大于8,table容量大于64)时,会将链表转化为红黑树结构,提高效率。
JDK1.7和JDK1.8区别总结:

1.初始化对象时,JDK1.7直接初始化对象容量为16,JDK1.8仅仅初始化负载因子为0.75

2.table类型:JDK1.7是Entry(映射key和value),JDK1.8是Node类型(为了红黑树)

3.底层结构:JDK1.7数组+链表,JDK1.8数组+链表+红黑树(链表长度大于8,table容量大于64)

4.元素插入方式:JDK1.7 头插法,JDK1.8尾插法

红黑树

红黑树属于平衡二叉树。它不严格是因为它不是严格控制左、右子树高度或节点数之差小于等于1,但红黑树高度依然是平均log(n),且最坏情况高度不会超过2log(n)。

红黑树(red-black tree) 是一棵满足下述性质的二叉查找树:

  1. 每一个结点要么是红色,要么是黑色。

  2. 根结点是黑色的。

  3. 所有叶子结点都是黑色的(实际上都是Null指针,下图用NIL表示)。叶子结点不包含任何关键字信息,所有查询关键字都在非终结点上。

  4. 每个红色结点的两个子节点必须是黑色的。换句话说:从每个叶子到根的所有路径上不能有两个连续的红色结点

  5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点

红黑树相关定理

  1. 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。

    根据上面的性质5我们知道上图的红黑树每条路径上都是3个黑结点。因此最短路径长度为2(没有红结点的路径)。再根据性质4(两个红结点不能相连)和性质1,2(叶子和根必须是黑结点)。那么我们可以得出:一条具有3个黑结点的路径上最多只能有2个红结点(红黑间隔存在)。也就是说黑深度为2(根结点也是黑色)的红黑树最长路径为4,最短路径为2。从这一点我们可以看出红黑树是 大致平衡的。 (当然比平衡二叉树要差一些,AVL的平衡因子最多为1)

  2. 红黑树的树高(h)不大于两倍的红黑树的黑深度(bd),即h<=2bd

    根据定理1,我们不难说明这一点。bd是红黑树的最短路径长度。而可能的最长路径长度(树高的最大值)就是红黑相间的路径,等于2bd。因此h<=2bd。

  3. 一棵拥有n个内部结点(不包括叶子结点)的红黑树的树高h<=2log(n+1)

    下面我们首先证明一颗有n个内部结点的红黑树满足n>=2bd-1。这可以用数学归纳法证明,施归纳于树高h。当h=0时,这相当于是一个叶结点,黑高度bd为0,而内部结点数量n为0,此时0>=20-1成立。假设树高h<=t时,n>=2^bd-1成立,我们记一颗树高 为t+1的红黑树的根结点的左子树的内部结点数量为nl,右子树的内部结点数量为nr,记这两颗子树的黑高度为bd’(注意这两颗子树的黑高度必然一 样),显然这两颗子树的树高<=t,于是有nl>=2bd’-1以及nr>=2bd’-1,将这两个不等式相加有nl+nr>=2(bd’+1)-2,将该不等式左右加1,得到n>=2(bd’+1)-1,很显然bd’+1>=bd,于是前面的不等式可以 变为n>=2bd-1,这样就证明了一颗有n个内部结点的红黑树满足n>=2bd-1。

     在根据定理2,h<=2bd。即n>=2^(h/2)-1,那么h<=2log(n+1)
    
     从这里我们能够看出,红黑树的查找长度最多不超过2log(n+1),因此其查找时间复杂度也是O(log N)级别的。
    

红黑树的操作

因为每一个红黑树也是一个特化的二叉查找树,因此红黑树上的查找操作与普通二叉查找树上的查找操作相同。然而,在红黑树上进行插入操作和删除操作会导致不 再符合红黑树的性质。恢复红黑树的属性需要少量(O(log n))的颜色变更(实际是非常快速的)和不超过三次树旋转(对于插入操作是两次)。 虽然插入和删除很复杂,但操作时间仍可以保持为 O(log n) 次 。

增加一个节点,节点颜色默认为红色,对红黑树进行二分查找,对比,
直至整个红黑树的叶子节点,确定当前节点插入红黑树的初始位置(插入节点
初始位置为整个红黑树的叶子节点)

1、判断插入节点是否为根节点,如果是根节点
	把当前节点置为根节点,并把颜色置为黑色
2、判断父节点的颜色,如果父节点的颜色为黑色
	不用处理,不违反红黑树的性质
3、父节点是红色,叔叔节点也是红色
	3.1、将父节点和叔叔节点设置为黑色,祖父节点设置为红色
	3.2、以祖父节点为插入节点,在进行判断
4、父节点是红色,叔叔节点是黑色
	4.1、左左插入
		父节点变成黑色,祖父节点变成红色,祖父节点右旋
	4.2、左右插入
    	父节左旋,之后父节点就变成了子节点
 	 	按照父节点为当前插入的红色节点,进行左左插入处理
	4.3、右右插入
		父节点变成黑色,祖父节点变成红色,祖父节点左旋
	4.4、右左插入
    	父节点右旋,之后父节点变成了子节点
    	按照父节点为当前插入的红色节点,进行右右插入处理

红黑树的优势

红黑树能够以O(log2(N))的时间复杂度进行搜索、插入、删除操作。此外,任何不平衡都会在3次旋转之内解决。这一点是AVL所不具备的。

而且实际应用中,很多语言都实现了红黑树的数据结构。比如 TreeMap, TreeSet(Java )、 STL(C++)等。

24.说一下 HashSet 的实现原理?

HashSet 的父类接口是Set集合
HashSet 是以Hash表结构存储
HashSet 多线程不安全
HashMap 可以存null值,
HashSet的底层是用HashMap实现的,将HashMap 值的那一列隐藏,就是HashSet (存在键的那一列)
一般子类需要用到HashCode方法,并且进行重写。

25.ArrayList 和 LinkedList 的区别是什么?

一个底层位数组,一个位链表

26.如何实现数组和 List 之间的转换?

27.ArrayList 和 Vector 的区别是什么?

答:

List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。

List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。

主要区别:
同步性:Vector是线程安全的,用synchronized实现线程安全,而ArrayList是线程不安全的。(实现同步需要很高的花费,所以访问Vector比访问ArrayList慢)

数据容量增长:二者都有一个初始容量大小,采用线性连续存储空间,当存储的元素的个数超过了容量时,就需要增加二者的存储空间,Vector增长原来的一倍,ArrayList增加原来的0.5倍。

总结:
LinkedList:增删改快

ArrayList:查询快(有索引的存在)

如果只有一个线程会访问到集合,那最好使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们再去考虑和编写线程安全的代码。

拓展:
vector和ArrayList都是通过数组实现。缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的存储空间中。

LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。

28.Array 和 ArrayList 有何区别?

29.在 Queue 中 poll()和 remove()有什么区别?

1、offer()和add()的区别
add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。可以据此在程序中进行有效的判断!

2、peek()和element()的区别
peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element()方法会抛出NoSuchElementException异常。

3、poll()和remove()的区别
poll()和remove()都将移除并且返回对头,但是在poll()在队列为空时返回null,而remove()会抛出NoSuchElementException异常。

30.哪些集合类是线程安全的?

31.迭代器 Iterator 是什么?

首先说一下迭代器模式,它是 Java 中常用的设计模式之一。用于顺序访问集合对象的元素,无需知道集合对象的底层实现。

Iterator 是可以遍历集合的对象,为各种容器提供了公共的操作接口,隔离对容器的遍历操作和底层实现,从而解耦。

缺点是增加新的集合类需要对应增加新的迭代器类,迭代器类与集合类成对增加。

原文链接:https://blog.csdn.net/meism5/article/details/89916501

32.Iterator 怎么使用?有什么特点?

33.Iterator 和 ListIterator 有什么区别?

34.怎么确保一个集合不能被修改?

我们可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map,是不可以修改的。他会报 java.lang.UnsupportedOperationException错。

同理:Collections包也提供了对list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)

三、多线程

35.并行和并发有什么区别?

36.线程和进程的区别?

37.守护线程是什么?

38.创建线程有哪几种方式?

继承Thread
实现callAble
实现runnable

39.说一下 runnable 和 callable 有什么区别?

有返回值和无返回值

40.线程有哪些状态?

  1. 新建(NEW):新创建了一个线程对象。

  2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

  3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

  4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了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()方法,则该线程结束生命周期。死亡的线程不可再次复生。

41.sleep() 和 wait() 有什么区别?

sleep为睡眠一定时间可醒来,wait只能依赖于nitify

42.notify()和 notifyAll()有什么区别?

唤醒全部 和唤醒当前线程

43.线程的 run()和 start()有什么区别?

调用 start() 方法是用来启动线程的,轮到该线程执行时,会自动调用 run();直接调用 run() 方法,无法达到启动多线程的目的,相当于主线程线性执行 Thread 对象的 run() 方法。
一个线程对线的 start() 方法只能调用一次,多次调用会抛出 java.lang.IllegalThreadStateException 异常;run() 方法没有限制

原文链接:https://blog.csdn.net/meism5/article/details/90240272

44.创建线程池有哪几种方式?

一、Executors
Executors是一个线程相关的工具类。主要提供了以下几种创建线程池的方法
二、ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, //核心线程数量
int maximumPoolSize, // 最大线程数量
long keepAliveTime, // 存活时间
TimeUnit unit, // 时间单位
BlockingQueue workQueue, //阻塞队列
ThreadFactory threadFactory) // 拒绝策略

原文链接:https://blog.csdn.net/lyong1223/article/details/105924558

45.线程池都有哪些状态?

RUNNING:线程池一旦被创建,就处于 RUNNING 状态,任务数为 0,能够接收新任务,对已排队的任务进行处理。

SHUTDOWN:不接收新任务,但能处理已排队的任务。调用线程池的 shutdown() 方法,线程池由 RUNNING 转变为 SHUTDOWN 状态。

STOP:不接收新任务,不处理已排队的任务,并且会中断正在处理的任务。调用线程池的 shutdownNow() 方法,线程池由(RUNNING 或 SHUTDOWN ) 转变为 STOP 状态。

TIDYING:

SHUTDOWN 状态下,任务数为 0, 其他所有任务已终止,线程池会变为 TIDYING 状态,会执行 terminated() 方法。线程池中的 terminated() 方法是空实现,可以重写该方法进行相应的处理。

线程池在 SHUTDOWN 状态,任务队列为空且执行中任务为空,线程池就会由 SHUTDOWN 转变为 TIDYING 状态。

线程池在 STOP 状态,线程池中执行中任务为空时,就会由 STOP 转变为 TIDYING 状态。

TERMINATED:线程池彻底终止。线程池在 TIDYING 状态执行完 terminated() 方法就会由 TIDYING 转变为 TERMINATED 状态。
状态转换如图

在这里插入图片描述

46.线程池中 submit()和 execute()方法有什么区别?

两个方法都可以向线程池提交任务,execute()方法的返回类型是 void,它定义在Executor 接口中。

而 submit()方法可以返回持有计算结果的 Future 对象,它定义在ExecutorService 接口中,它扩展了 Executor 接口,其它线程池类像ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 都有这些方法。

47.在 java 程序中怎么保证多线程的运行安全?

加锁

48.多线程锁的升级原理是什么?

49.什么是死锁?

50.怎么防止死锁?

51.ThreadLocal 是什么?有哪些使用场景?

52.说一下 synchronized 底层实现原理?

53.synchronized 和 volatile 的区别是什么?

54.synchronized 和 Lock 有什么区别?

55.synchronized 和 ReentrantLock 区别是什么?

56.说一下 atomic 的原理?

四、反射

57.什么是反射?

58.什么是 java 序列化?什么情况下需要序列化?

59.动态代理是什么?有哪些应用?

60.怎么实现动态代理?

五、对象拷贝

61.为什么要使用克隆?

62.如何实现对象克隆?

63.深拷贝和浅拷贝区别是什么?

六、Java Web

64.jsp 和 servlet 有什么区别?

65.jsp 有哪些内置对象?作用分别是什么?

66.说一下 jsp 的 4 种作用域?

67.session 和 cookie 有什么区别?

68.说一下 session 的工作原理?

69.如果客户端禁止 cookie 能实现 session 还能用吗?

70.spring mvc 和 struts 的区别是什么?

71.如何避免 sql 注入?

72.什么是 XSS 攻击,如何避免?

73.什么是 CSRF 攻击,如何避免?

七、异常

74.throw 和 throws 的区别?

Throw:

作用在方法内,表示抛出具体异常,由方法体内的语句处理。
具体向外抛出的动作,所以它抛出的是一个异常实体类。若执行了Throw一定是抛出了某种异常。
Throws:

作用在方法的声明上,表示如果抛出异常,则由该方法的调用者来进行异常处理。
主要的声明这个方法会抛出会抛出某种类型的异常,让它的使用者知道捕获异常的类型。
出现异常是一种可能性,但不一定会发生异常。

75.final、finally、finalize 有什么区别?

76.try-catch-finally 中哪个部分可以省略?

77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

78.常见的异常类有哪些?

八、网络

79.http 响应码 301 和 302 代表的是什么?有什么区别?

80.forward 和 redirect 的区别?

81.简述 tcp 和 udp的区别?

82.tcp 为什么要三次握手,两次不行吗?为什么?

不行因为如b可能发的慢会造成a的意外

83.说一下 tcp 粘包是怎么产生的?

由于发送端过快,接收端处理没那么快都存在缓冲区

84.OSI 的七层模型都有哪些?

在这里插入图片描述

85.get 和 post 请求有哪些区别?

86.如何实现跨域?

87.说一下 JSONP 实现原理?

九、设计模式

88.说一下你熟悉的设计模式?

89.简单工厂和抽象工厂有什么区别?

十、Spring/Spring MVC

90.为什么要使用 spring?

spring 是一个开源的轻量级 JavaBean 容器框架。使用 JavaBean 代替 EJB ,并提供了丰富的企业应用功能,降低应用开发的复杂性。

轻量:非入侵性的、所依赖的东西少、资源占用少、部署简单,不同功能选择不同的 jar 组合
容器:工厂模式实现对 JavaBean 进行管理,通过控制反转(IOC)将应用程序的配置和依赖性与应用代码分开
松耦合:通过 xml 配置或注解即可完成 bean 的依赖注入
AOP:通过 xml 配置 或注解即可加入面向切面编程的能力,完成切面功能,如:日志,事务…的统一处理
方便集成:通过配置和简单的对象注入即可集成其他框架,如 Mybatis、Hibernate、Shiro…
丰富的功能:JDBC 层抽象、事务管理、MVC、Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service…

91.解释一下什么是 aop?

切面,对原有方法不修改增强

92.解释一下什么是 ioc?

控制反转,将对象资源交于spring控制需要找spring拿

93.spring 有哪些主要模块

  1. Spring Core
    框架的最基础部分,提供 IoC 容器,对 bean 进行管理。

2.Spring Context
基于 bean,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化、校验和调度等功能。

3.Spring DAO
提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码,还提供了声明性事务管理方法。

4.Spring ORM
提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate、MyBatis 等。

5.Spring AOP
提供了符合AOP Alliance规范的面向方面的编程实现。

6.Spring Web
提供了基础的 Web 开发的上下文信息,可与其他 web 进行集成。

7.Spring Web MVC
提供了 Web 应用的 Model-View-Controller 全功能实现。

94.spring 常用的注入方式有哪些?

构造方法注入,setter注入,基于注解的注入

95.spring 中的 bean 是线程安全的吗?

不是

96.spring 支持几种 bean 的作用域?

5种
singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例
prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例

只有在 Web 应用中使用Spring时,request、session、global-session 作用域才有效

request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个新实例,即每次 HTTP 请求将会产生不同的 bean 实例。
session:同一个 Session 共享一个 bean 实例。
global-session:同 session 作用域不同的是,所有的Session共享一个Bean实例。

97.spring 自动装配 bean 有哪些方式?

no
byname
bytype
注解

98.spring 事务实现方式有哪些?

99.说一下 spring 的事务隔离?

100.说一下 spring mvc 运行流程?

在这里插入图片描述

101.spring mvc 有哪些组件?

102.@RequestMapping 的作用是什么?

@RequestMapping 是一个注解,用来标识 http 请求地址与 Controller 类的方法之间的映射。

103.@Autowired 的作用是什么?

注如bean资源

十一、Spring Boot/Spring Cloud

104.什么是 spring boot?

1.什么是Spring Boot?
springboot就是Spring开源框架下的子项目,是Spring的一站式解决方案,主要是简化了spring的使用难度,降低了对配置文件的要求,使得开发人员能够更容易得上手。
2.为什么使用Spring Boot?
SpringBoot有很多得优点

简化了Spring配置文件,
没有代码和XML文件的生成
内置TomCat
能够独立运行
简化监控

105.为什么要用 spring boot?

106.spring boot 核心配置文件是什么?

Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
bootstrap 配置文件有以下几个应用场景。
使用 Spring Cloud Config 配置中心时,
这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
一些固定的不能被覆盖的属性;
一些加密/解密的场景;

107.spring boot 配置文件有哪几种类型?它们有什么区别?

properties,xml

108.spring boot 有哪些方式可以实现热部署?

109.jpa 和 hibernate 有什么区别?

110.什么是 spring cloud?

111.spring cloud 断路器的作用是什么?

防止服务爆炸

112.spring cloud 的核心组件有哪些?

十二、Hibernate

113.为什么要使用 hibernate?

114.什么是 ORM 框架?

115.hibernate 中如何在控制台查看打印的 sql 语句?

116.hibernate 有几种查询方式?

117.hibernate 实体类可以被定义为 final 吗?

118.在 hibernate 中使用 Integer 和 int 做映射有什么区别?

119.hibernate 是如何工作的?

120.get()和 load()的区别?

121.说一下 hibernate 的缓存机制?

122.hibernate 对象有哪些状态?

123.在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?

124.hibernate 实体类必须要有无参构造函数吗?为什么?

十三、Mybatis

125.mybatis 中 #{}和 ${}的区别是什么?

#{}是占位符,?代替,${}直接拼接字符串

126.mybatis 有几种分页方式?

1数组分页,先查出所有,之后对list进行操作
2sql分页 limit
3拦截器分页,实现interceprtor
4rowbounds分页

127.RowBounds 是一次性查询全部结果吗?为什么?

不是
RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据。因为 MyBatis 是对 JDBC 的封装,在 JDBC 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在执行 next() 的时候,去查询更多的数据。 就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,要取 4 次才能把钱取完。对于 JDBC 来说也是一样,这样做的好处是可以有效的防止内存溢出。

128.mybatis 逻辑分页和物理分页的区别是什么?

1.物理分页
物理分页就是数据库本身提供了分页方式,如MySQL的limit,oracle的rownum ,好处是效率高,不好的地方就是不同数据库有不同的搞法。

2.逻辑分页
逻辑分页利用游标分页,好处是所有数据库都统一,坏处就是效率低。

129.mybatis 是否支持延迟加载?延迟加载的原理是什么?

mybatis运行原理

在这里插入图片描述

链接: mybatis.

jdbc常用

try {
//加载驱动
Class.forName(“com.mysql.jdbc.Driver”);
String url=“jdbc:mysql://127.0.0.1:3306/test”;
//通过DriverManager获取连接
Connection conn=DriverManager.getConnection(url,“root”,“hello”);
System.out.println(“conn:”+conn);
//准备操作数据库
//Statement:用于执行静态SQL语句并返回它所生产结果的对象
Statement stm=conn.createStatement();
String sql=“insert into test.new_table(t1,t2) values(‘t11’,‘t22’);”;
Boolean ret =stm.execute(sql);
conn.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

130.说一下 mybatis 的一级缓存和二级缓存?

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是多个SqlSession共享的。

UserMapper有一个二级缓存区域(按namespace分,如果namespace相同则使用同一个相同的二级缓存区),其它mapper也有自己的二级缓存区域(按namespace分)。

也是就是说拥有相同的namespace的UserMapper共享一个二级缓存

131.mybatis 和 hibernate 的区别有哪些?

132.mybatis 有哪些执行器(Executor)?

1.mybatis有三种executor执行器,分别为simpleexecutor、reuseexecutor、batchexecutor。
simpleexecutor执行器:在每执行一次update或select,就开启一个statement对象,用完后就关闭。
reuseexecutor执行器:在执行update或select时以sql作为key去查找statement,有就直接使用,没有就创建,使用完毕后不关闭,放入Map<String,Statement>中,供下次使用。重复使用statement。
batchexecutor执行器:执行update(jdbc批处理不支持select),会把所有sql添加到批处理中addbatch();等待统一批处理executorbatch();它缓存了·多个statement,每一个statement都是addbatch(),后等待进行executorbatch()批处理。
作用范围:统一限制在sqlsession生命周期范围内。

133.mybatis 分页插件的实现原理是什么?

在这里插入图片描述

134.mybatis 如何编写一个自定义插件?

实现Interceptor,加注解interceptors(signature=type拦截类型,args=参数类型)

十四、RabbitMQ

135.rabbitmq 的使用场景有哪些?

  1. 解耦,比如说系统A会交给系统B去处理一些事情,通过将A,B中间加入消息队列,A将要处理的事情交给消息队列 ,B的输入来源于与消息队列

2.有序性。先来先处理,比如一个系统处理某件事需要很长一段时间,但是在处理这件事情时候,有其他人也发出了请求,可以把请求放在消息队里,一个一个来处理

3.消息路由:按照不同的规则,将队列中消息发送到不同的其他队列中

4.异步处理: 处理一件事情,需要 甲先做A , 然后做乙丙丁分别处理B C D ,B C D这三件事情在A之后,但是相互之间没有关联。此时甲处理A1之后,把事件发送到消息队列里边,乙丙丁接受到事件之后 分别处理B1 C1 D1。在甲处理能力比较大,BCD处理能力比较小的时候,这样做,对于A的提升能力比较大

136.rabbitmq 有哪些重要的角色?

生产者:消息的创建者,负责创建和推送数据到消息服务器

消费者:消息的接收方,用于处理数据和确认消息

代理:就是RabbitMQ本身,用于扮演快递的角色,本身并不生产消息

137.rabbitmq 有哪些重要的组件?

ConnectionFactory(连接管理器):应用程序与RabbitMQ之间建立连接的管理器

Channel(信道):消息推送使用的通道

Exchange(交换器):用于接受、分配消息

Queue(队列):用于存储生产者的消息

RoutingKey(路由键):生产者将消息发送给交换器的时候,会指定一个RoutingKey,用来指定这个消息的路由规则,这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。

BindKey(绑定键):用于把交换器的消息绑定到队列上

138.rabbitmq 中 vhost 的作用是什么?

139.rabbitmq 的消息是怎么发送的?

如上图,RabbitMQ结构如下

Server:又称为broker,接受客户端连接,RabbitMQ 节点;
Connection: 连接,应用程序与brokder建立网络连接;
channel:网络通道,几乎所有的操作都是在channel中进行的,是进行消息对象的通道,客户端可以建立 多个通道,每一个channel表示一个会话任务
Virtual Host:虚拟机,一个节点由若干个虚拟机组成;
Exchange:交换机,一个虚拟机由若干个交换机组成;
Queue:消息队列,和交换机通过routing key绑定
在这里插入图片描述
消息发送流程:
生产者把生产的小心通过channel发送到Exchange上,Exchange通过绑定的router key来选择Queue,消费者监听到Queue上有新的消息,就消费调此消息;

Exchange类型
Direct exchange(直接交换机):exchange根据routing key来找queue的时候,使用的是equals;
Topic Exchange(主题交换机):exchange根据routing key来找queue的时候,使用的是模糊匹配,分为*和# ;
Fanout Exchange(扇形交换机):默认的不匹配queue,随机发送信息;
Headers Exchange:基于消息的header数据进行路由,而不是通过routing key。

140.rabbitmq 怎么保证消息的稳定性?

RabbitMQ如何保证消息的可靠性
1、保证消息不丢失(三步)
1.1、开启事务(不推荐)
1.2、开启confirm(推荐)
1.3、开启RabbitMQ持久化(交换机、队列、消息)
1.4、关闭RabbitMQ自动ack(改成手动)

2、保证消息不重复消费
2.1、幂等性(每个消息用一个唯一标识来区分,消费前先判断标识有没有被消费过,若已消费过,则直接ACK)

3、RabbitMQ如何保证消息的顺序性
将消息放入同一个交换机,交给同一个队列,这个队列只有一个消费者,消费者只允许同时开启一个线程

4、RabbitMQ消息重试机制
消费者在消费消息的时候,如果消费者业务逻辑出现程序异常,这时候应该如何处理?
答案:使用消息重试机制(SpringBoot默认3次消息重试机制)

如何合适选择重试机制
消费者取到消息后,调用第三方接口,接口无法访问,需要使用重试机制
消费者取到消息后,抛出数据转换异常,不需要重试机制,需要发布者进行解决。

141.rabbitmq 怎么避免消息丢失?

1.1、开启事务(不推荐)
1.2、开启confirm(推荐)
1.3、开启RabbitMQ持久化(交换机、队列、消息)
1.4、关闭RabbitMQ自动ack(改成手动)

142.要保证消息持久化成功的条件有哪些?

声明队列必须设置持久化 durable 设置为 true.

消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。

消息已经到达持久化交换器。

消息已经到达持久化队列。

143.rabbitmq 持久化有什么缺点?

持久化的缺地就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储,从而降低了吞吐量。可尽量使用 ssd 硬盘来缓解吞吐量的问题。

144.rabbitmq 有几种广播类型?

direct(默认方式):最基础最简单的模式,发送方把消息发送给订阅方,如果有多个订阅者,默认采取轮询的方式进行消息发送。

headers:与 direct 类似,只是性能很差,此类型几乎用不到。

fanout:分发模式,把消费分发给所有订阅者。

topic:匹配订阅模式,使用正则匹配到消息队列,能匹配到的都能接收到。

https://www.cnblogs.com/linyufeng/p/9885020.html

145.rabbitmq 怎么实现延迟消息队列?

146.rabbitmq 集群有什么用?

147.rabbitmq 节点的类型有哪些?

148.rabbitmq 集群搭建需要注意哪些问题?

149.rabbitmq 每个节点是其他节点的完整拷贝吗?为什么?

150.rabbitmq 集群中唯一一个磁盘节点崩溃了会发生什么情况?

151.rabbitmq 对集群节点停止顺序有要求吗?

十五、Kafka

152.kafka 可以脱离 zookeeper 单独使用吗?为什么?

153.kafka 有几种数据保留的策略?

154.kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?

155.什么情况会导致 kafka 运行变慢?

156.使用 kafka 集群需要注意什么?

十六、Zookeeper

157.zookeeper 是什么?

ZooKeeper主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理。
使用分布式系统就无法避免对节点管理的问题(需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper作为一个能够通用解决这些问题的中间件就应运而生了。

158.zookeeper 都有哪些功能?

159.zookeeper 有几种部署模式?

160.zookeeper 怎么保证主从节点的状态同步?

161.集群中为什么要有主节点?

162.集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗?

163.说一下 zookeeper 的通知机制?

十七、MySql

164.数据库的三范式是什么?

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?

8

166.如何获取当前数据库版本?

167.说一下 ACID 是什么?

ACID 一般是指数据库事务的ACID

一个事务一般是指多个操作的集合,比如插入数据库分两段插入,第二次插入错误,第一次插入操作也需要回退

ACID的翻译

1.Atomicity 原子性

2.Consistency 一致性

3.Isolation 隔离性

4.Durability 耐久性

原子性,指的是整个事务是一个独立的单元,要么操作成功,要么操作不成功

一致性,事务必须要保持和系统处于一致的状态(如果不一致会导致系统其它的方出现bug)

隔离性,事务是并发控制机制,他们的交错也需要一致性,隔离隐藏,一般通过悲观或者乐观锁实现

耐久性,一个成功的事务将永久性地改变系统的状态,所以在它结束之前,所有导致状态的变化都

          记录在一个持久的事务日志中

168.char 和 varchar 的区别是什么?

169.float 和 double 的区别是什么?

170.mysql 的内连接、左连接、右连接有什么区别?

171.mysql 索引是怎么实现的?

172.怎么验证 mysql 的索引是否满足需求?

173.说一下数据库的事务隔离?

174.说一下 mysql 常用的引擎?

175.说一下 mysql 的行锁和表锁?

176.说一下乐观锁和悲观锁?

177.mysql 问题排查都有哪些手段?

178.如何做 mysql 的性能优化?

十八、Redis

179.redis 是什么?都有哪些使用场景?

非关系型数据库
应用场景:
内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
模拟类似于HttpSession这种需要设定过期时间的功能
发布、订阅消息系统
定时器、计数器

180.redis 有哪些功能?

基于本机内存的缓存

为了解决调用API依然需要2秒的问题,经过排查,其主要原因在于使用SQL获取热点新闻的过程中消耗了将近2秒的时间,于是乎,我们又想到了一个简单粗暴的解决方案,即把SQL查询的结果直接缓存在当前api服务器的内存中(设置缓存有效时间为1分钟)。后续1分钟内的请求直接读缓存,不再花费2秒去执行SQL了。假如这个api每秒接收到的请求时100个,那么一分钟就是6000个,也就是只有前2秒拥挤过来的请求会耗时2秒,后续的58秒中的所有请求都可以做到即使响应,而无需再等2秒的时间。

服务端的Redis

在API服务器的内存都被缓存塞满的时候,我们发现不得不另想解决方案了。最直接的想法就是我们把这些缓存都丢到一个专门的服务器上吧,把它的内存配置的大大的。然后我们就盯上了redis。。。至于如何配置部署redis这里不解释了,redis官方有详细的介绍。随后我们就用上了一台单独的服务器作为Redis的服务器,API服务器的内存压力得以解决。

持久化(Persistence)

单台的Redis服务器一个月总有那么几天心情不好,心情不好就罢工了,导致所有的缓存都丢失了(redis的数据是存储在内存的嘛)。虽然可以把Redis服务器重新上线,但是由于内存的数据丢失,造成了缓存雪崩,API服务器和数据库的压力还是一下子就上来了。所以这个时候Redis的持久化功能就派上用场了,可以缓解一下缓存雪崩带来的影响。redis的持久化指的是redis会把内存的中的数据写入到硬盘中,在redis重新启动的时候加载这些数据,从而最大限度的降低缓存丢失带来的影响。

哨兵(Sentinel)和复制(Replication)

Redis服务器毫无征兆的罢工是个麻烦事。那么怎办办?答曰:备份一台,你挂了它上。那么如何得知某一台redis服务器挂了,如何切换,如何保证备份的机器是原始服务器的完整备份呢?这时候就需要Sentinel和Replication出场了。Sentinel可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能;Replication则是负责让一个Redis服务器可以配备多个备份的服务器。Redis也是利用这两个功能来保证Redis的高可用的。此外,Sentinel功能则是对Redis的发布和订阅功能的一个利用。

集群(Cluster)

单台服务器资源的总是有上限的,CPU资源和IO资源我们可以通过主从复制,进行读写分离,把一部分CPU和IO的压力转移到从服务器上。但是内存资源怎么办,主从模式做到的只是相同数据的备份,并不能横向扩充内存;单台机器的内存也只能进行加大处理,但是总有上限的。所以我们就需要一种解决方案,可以让我们横向扩展。最终的目的既是把每台服务器只负责其中的一部分,让这些所有的服务器构成一个整体,对外界的消费者而言,这一组分布式的服务器就像是一个集中式的服务器一样

181.redis 和 memecache 有什么区别?

182.redis 为什么是单线程的?

转载链接:redis

1)以前一直有个误区,以为:高性能服务器 一定是多线程来实现的

原因很简单因为误区二导致的:多线程 一定比 单线程 效率高,其实不然!

在说这个事前希望大家都能对 CPU 、 内存 、 硬盘的速度都有了解了,这样可能理解得更深刻一点,不了解的朋友点:CPU到底比内存跟硬盘快多少

2)redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 就是效率最高的,为什么呢,因为多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的系统来说,它没有上下文的切换就是效率最高的。redis 用 单个CPU 绑定一块内存的数据,然后针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成的,所以它是单线程处理这个事。在内存的情况下,这个方案就是最佳方案 —— 阿里 沈询

因为一次CPU上下文的切换大概在 1500ns 左右。

从内存中读取 1MB 的连续数据,耗时大约为 250us,假设1MB的数据由多个线程读取了1000次,那么就有1000次时间上下文的切换,

那么就有1500ns * 1000 = 1500us ,我单线程的读完1MB数据才250us ,你光时间上下文的切换就用了1500us了,我还不算你每次读一点数据 的时间,

3)那什么时候用多线程的方案呢?

【IOPS(Input/Output Operations Per Second)是一个用于计算机存储设备(如硬盘(HDD)、固态硬盘(SSD)或存储区域网络(SAN))性能测试的量测方式】

【吞吐量是指对网络、设备、端口、虚电路或其他设施,单位时间内成功地传送数据的数量(以比特、字节、分组等测量)】

答案是:下层的存储等慢速的情况。比如磁盘

内存是一个 IOPS 非常高的系统,因为我想申请一块内存就申请一块内存,销毁一块内存我就销毁一块内存,内存的申请和销毁是很容易的。而且内存是可以动态的申请大小的。

磁盘的特性是:IPOS很低很低,但吞吐量很高。这就意味着,大量的读写操作都必须攒到一起,再提交到磁盘的时候,性能最高。为什么呢?

如果我有一个事务组的操作(就是几个已经分开了的事务请求,比如写读写读写,这么五个操作在一起),在内存中,因为IOPS非常高,我可以一个一个的完成,但是如果在磁盘中也有这种请求方式的话,

我第一个写操作是这样完成的:我先在硬盘中寻址,大概花费10ms,然后我读一个数据可能花费1ms然后我再运算(忽略不计),再写回硬盘又是10ms ,总共21ms

第二个操作去读花了10ms, 第三个又是写花费了21ms ,然后我再读10ms, 写21ms ,五个请求总共花费83ms,这还是最理想的情况下,这如果在内存中,大概1ms不到。

所以对于磁盘来说,它吞吐量这么大,那最好的方案肯定是我将N个请求一起放在一个buff里,然后一起去提交。

方法就是用异步:将请求和处理的线程不绑定,请求的线程将请求放在一个buff里,然后等buff快满了,处理的线程再去处理这个buff。然后由这个buff 统一的去写入磁盘,或者读磁盘,这样效率就是最高。java里的 IO不就是这么干的么~

对于慢速设备,这种处理方式就是最佳的,慢速设备有磁盘,网络 ,SSD 等等,

多线程 ,异步的方式处理这些问题非常常见,大名鼎鼎的netty 就是这么干的。

终于把 redis 为什么是单线程说清楚了,把什么时候用单线程跟多线程也说清楚了,其实也是些很简单的东西,只是基础不好的时候,就真的尴尬。。。。

4)补一发大师语录:来说说,为何单核cpu绑定一块内存效率最高

“我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以我们可以手动地为其分配CPU核,而不会过多地占用CPU”,默认情况下单线程在进行系统调用的时候会随机使用CPU内核,为了优化Redis,我们可以使用工具为单线程绑定固定的CPU内核,减少不必要的性能损耗!

redis作为单进程模型的程序,为了充分利用多核CPU,常常在一台server上会启动多个实例。而为了减少切换的开销,有必要为每个实例指定其所运行的CPU。

Linux 上 taskset 可以将某个进程绑定到一个特定的CPU。你比操作系统更了解自己的程序,为了避免调度器愚蠢的调度你的程序,或是为了在多线程程序中避免缓存失效造成的开销。

顺便再提一句:redis 的瓶颈在网络上 。。。。

183.什么是缓存穿透?怎么解决?

一.缓存穿透:

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决办法:
1.布隆过滤

对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃。还有最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

二.缓存雪崩

如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。

这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。

解决方法

  1. 加锁排队. 限流-- 限流算法. 1.计数 2.滑动窗口 3. 令牌桶Token Bucket 4.漏桶 leaky bucket [1]

在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

 2.数据预热

可以通过缓存reload机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

184.redis 支持的数据类型有哪些?

string list set hash zset

185.redis 支持的 java 客户端都有哪些?

186.jedis 和 redisson 有哪些区别?

187.怎么保证缓存和数据库数据的一致性?

188.redis 持久化有几种方式?

aof:持续写入
rdb:快照某一时刻达到限制

189.redis 怎么实现分布式锁?

Redis分布式锁的基本流程并不难理解,但要想写得尽善尽美,也并不是那么容易。在这里,我们需要先了解分布式锁实现的三个核心要素:

1.加锁

最简单的方法是使用setnx命令。key是锁的唯一标识,按业务来决定命名。比如想要给一种商品的秒杀活动加锁,可以给key命名为 “lock_sale_商品ID” 。而value设置成什么呢?锁的value值为一个随机生成的UUID。我们可以姑且设置成1。加锁的伪代码如下:

setnx(key,1)
当一个线程执行setnx返回1,说明key原本不存在,该线程成功得到了锁;当一个线程执行setnx返回0,说明key已经存在,该线程抢锁失败。

2.解锁

有加锁就得有解锁。当得到锁的线程执行完任务,需要释放锁,以便其他线程可以进入。释放锁的最简单方式是执行del指令,伪代码如下:

del(key)
释放锁之后,其他线程就可以继续执行setnx命令来获得锁。

3.锁超时

锁超时是什么意思呢?如果一个得到锁的线程在执行任务的过程中挂掉,来不及显式地释放锁,这块资源将会永远被锁住,别的线程再也别想进来。

190.redis 分布式锁有什么缺陷?

191.redis 如何做内存优化?

1、缩减键值对象

缩减键(key)和值(value)的长度,

key长度:如在设计键时,在完整描述业务情况下,键值越短越好。

value长度:值对象缩减比较复杂,常见需求是把业务对象序列化成二进制数组放入Redis。首先应该在业务上精简业务对象,去掉不必要的属性避免存储无效数据。其次在序列化工具选择上,应该选择更高效的序列化工具来降低字节数组大小。以JAVA为例,内置的序列化方式无论从速度还是压缩比都不尽如人意,这时可以选择更高效的序列化工具,如: protostuff,kryo等,下图是JAVA常见序列化工具空间压缩对比。

2、共享对象池

对象共享池指Redis内部维护[0-9999]的整数对象池。创建大量的整数类型redisObject存在内存开销,每个redisObject内部结构至少占16字节,甚至超过了整数自身空间消耗。所以Redis内存维护一个[0-9999]的整数对象池,用于节约内存。 除了整数值对象,其他类型如list,hash,set,zset内部元素也可以使用整数对象池。因此开发中在满足需求的前提下,尽量使用整数对象以节省内存。

3、字符串优化

4、编码优化

5、控制key的数量

192.redis 淘汰策略有哪些?

noeviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。 大多数写命令都会导致占用更多的内存(有极少数会例外, 如 DEL )。
allkeys-lru: 所有key通用; 优先删除最近最少使用(less recently used ,LRU) 的 key。
volatile-lru: 只限于设置了 expire 的部分; 优先删除最近最少使用(less recently used ,LRU) 的 key。
allkeys-random: 所有key通用; 随机删除一部分 key。
volatile-random: 只限于设置了 expire 的部分; 随机删除一部分 key。
volatile-ttl: 只限于设置了 expire 的部分; 优先删除剩余时间(time to live,TTL) 短的key

193.redis 常见的性能问题有哪些?该如何解决?

十九、JVM

194.说一下 jvm 的主要组成部分?及其作用?

在这里插入图片描述

堆,栈,方法区,常量池,线程计数器

195.说一下 jvm 运行时数据区?

196.说一下堆栈的区别?

197.队列和栈是什么?有什么区别?

198.什么是双亲委派模型?

199.说一下类加载的执行过程?
https://www.cnblogs.com/jxxblogs/p/12208112.html

200.怎么判断对象是否可以被回收?

方式一:引用计数器:为每个对象创建一个引用计数,当有对象引用时,计数器+1,

当引用释放时,计数器-1,所以,当计数器为0时,就认为可以被回收。

但这种算法,存在一个问题,存在循环引用的问题。

来,看代码,但一般是为

方式二:可达性分析

从GC Roots开始向下搜索,搜索所走过的路径称为引用链。

当一个对象到GC Roots没有任何引用链时,则认为此对象可以被回收。

大家可以认为就是一个树的根节点开始计算引用情况。

201.java 中都有哪些引用类型?
强引用(strong reference)
强引用(strongreference)就是指在程序代码之中普遍存在的,类似“Object obj=new Object()” 这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象实例。

回到顶部(go to top)
软引用(soft reference)
一些有用但是并非必需,用软引用关联的对象,系统将要发生OOM之前,这些对象就会被回收。参见代码:

弱引用(weak reference)
弱引用(weakreference)是一些有用(程度比软引用更低)但是并非必需,用弱引用关联的对象,只能生存到下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收。见代码:

虚引用(phantom reference)
虚引用(phantomreference)幽灵引用,最弱,被垃圾回收的时候收到一个通知

一个对象 实例是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用 来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象 实例被收集器回收时收到一个系统通知。

202.说一下 jvm 有哪些垃圾回收算法?

203.说一下 jvm 有哪些垃圾回收器?

204.详细介绍一下 CMS 垃圾回收器?

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

206.简述分代垃圾回收器是怎么工作的?

207.说一下 jvm 调优的工具?

208.常用的 jvm 调优的参数都有哪些?

链接:https://www.imooc.com/article/281260

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值