208道Java常问面试题答案

最近在CSDN的公众号上有这208道面试题目,自己将关于这208道题知道的知识整理如下,希望自己能尽快把这些题都弄清楚。原文题目链接:https://blog.csdn.net/sufu1065/article/details/88051083
题目中涉及到的一些比较高级一点的知识没有学习,以后会补上的,加油加油!!!
Java 基础
1.JDK 和 JRE 有什么区别?
JRE可以支撑Java程序的运行,包括JVM虚拟机和基本的类库。
JDK可以支持Java程序的开发,包括编译器,开发工具和更多的类库。
2.== 和 equals 的区别是什么?
== 如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等。
equals方法不能作用于基本数据类型的变量,两边的操作数必须是同一类型的才能编译通过。
简单来说就是 == 比较数值,equals方法比较的是值和类型。
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
equals相等,则hashcode一定相等,反之则不然。为何会有这样的要求?在集合中,比如HashSet中,要求放入的对象不能重复,怎么判定呢?首先会调用hashcode,如果hashcode相等,则继续调用equals,也相等,则认为重复。
4.final 在 Java 中有什么作用?
final修饰类,这样的类不能被继承。
final修饰方法,这样的方法不能被重写。
final修饰变量,这样的变量的值不能被修改,是常量。
5.Java 中的 Math.round(-1.5) 等于多少?
-1 这个函数就是四舍五入 小数不太一样
Math.round(-1.0) -1
Math.round(-1.4) -1
Math.round(-1.5) -1
Math.round(-1.6) -2
6.String 属于基础的数据类型吗?
不是。String是一个类,是java等编程语言的字符串。
8种基本数据类型是:
boolean char byte short int long float double
1位 16位 8位 16位 32位 64位 32位 64位
8 位的范围是:-2^7 ~ 2^7-1
16位的范围是:-2^15 ~ 2^15-1
……
7.Java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder
区别:String是不可变的对象,对每次对String类型的改变时都会生成一个新的对象,StringBuffer和StringBuilder是可以改变对象的。
 对于操作效率:StringBuilder > StringBuffer > String
 对于线程安全:StringBuffer 是线程安全,可用于多线程;StringBuilder 是非线程安全,用于单线程
 不频繁的字符串操作使用 String。反之,StringBuffer 和 StringBuilder 都优于String
8.String str="i"与 String str=new String(“i”)一样吗?
不一样,因为他们不是同一个对象。
9.如何将字符串反转?
String s1 = “asdfghjkl”;
System.out.println(new StringBuilder(s1).reverse().toString());
10.String 类的常用方法都有那些?
自己瞎掰吧,反正那么多。
11.抽象类必须要有抽象方法吗?
抽象类中不一定要包含抽象(abstrace)方法。也就是,抽象类中可以没有抽象方法。反之,类中含有抽象方法,那么类必须声明为抽象类。
12.普通类和抽象类有哪些区别?
1、抽象类不能被实例
2、抽象类不能有构造函数,抽象方法也不能被声明为静态
3、抽象类可以有抽象方法
4、抽象类的抽象方法必须被非抽象子类继承
13.抽象类能使用 final 修饰吗?
不能,抽象类中的抽象方法是未来继承之后重写方法,而用final修饰的类,无法被继承。
14.接口和抽象类有什么区别?
1、抽象类是被子类继承,接口是被类实现
2、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量
4、接口是设计的结果 ,抽象类是重构的结果
15.Java 中 IO 流分为几种?
可以分4种。
字节输入流(InputStream)
字节输出流(OutputStream)
字符输入流(Reader)
字符输出流(Writer)
16.BIO、NIO、AIO 有什么区别?
BIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。
NIO(reactor模型):线程发起IO请求,立即返回;内核在做好IO操作的准备之后,通过调用注册的回调函数通知线程做IO操作,线程开始阻塞,直到操作完成。
AIO(proactor模型):线程发起IO请求,立即返回;内存做好IO操作的准备之后,做IO操作,直到操作完成或者失败,通过调用注册的回调函数通知线程做IO操作完成或者失败。

17.Files的常用方法都有哪些?
创建:
createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false。
mkdir() 在指定位置创建一个单级文件夹。
删除:
delete() 删除文件或者一个空文件夹,不能删除非空文件夹,马上删除文件,返回一个布尔值。
判断:
exists() 文件或文件夹是否存在。
isFile() 是否是一个文件,如果不存在,则始终为false。
isDirectory() 是否是一个目录,如果不存在,则始终为false。
获取:
getName() 获取文件或文件夹的名称,不包含上级路径。
getAbsolutePath()获取文件的绝对路径,与文件是否存在没关系
文件夹相关:
list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。
容器
18.Java 容器都有哪些?
答:List、Set、Map
19.Collection 和 Collections 有什么区别?
Collection是集合类的顶级接口,其派生了两个子接口 Set 和 List。
Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
总的来说:Collection是一个接口,而Collections是个类。
20.List、Set、Map 之间的区别是什么?
List:可以允许重复对象,可以插入多个null元素,是一个有序容器
Set:不允许重复对象,只允许一个null元素,无序容器
Map:Map不是Collection的子接口或实现类。Map是一个接口,Map 的每个Entry都特有两个对象,也就是一个键一个值,Map可能会持有相同的值对象但键对象必须是唯一的,Map里可以拥有随意个niull值但最多只能有一个null键
21.HashMap 和 Hashtable 有什么区别?
HashMap线程安全,HashTable线程不安全。
22.如何决定使用 HashMap 还是 TreeMap?
HashMap和TreeMap都是Map的实现,HashMap是一个基于HashTable的实现存储的是键值对,无序。TreeMap是在红黑树的基础上实现的,它最大的好处是得到的数据是排好序的。选择谁取决于需不需要排序。
23.说一下 HashMap 的实现原理?
HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表,那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。
24.说一下 HashSet 的实现原理?
HashSet中不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个final的 Object对象。HashSet跟HashMap一样,都是一个存放链表的数组。
25.ArrayList 和 LinkedList 的区别是什么?
ArrayList和LinkedList都是非线程安全的,由于LinkedList是基于链表的数据结构在做链表之间插入数据 或删除数据会比较方便,当读多的时候采取ArrayList,插入和删除多的话选取LinkedList。随机访问,循环的时候ArrayList性能更好,做中部插入,删除的时候LinkedList性能更好。
26.如何实现数组和 List 之间的转换?
List到数组 :String[] array = (String[])list.toArray(new String[size]);
数组到List :List list=Arrays.asList(array);
27.ArrayList 和 Vector 的区别是什么?
Vector的方法都是同步的,是线程安全的,而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
28.Array 和 ArrayList 有何区别?
很明显,Array是数组,而ArrayList是集合,Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。这是最基本的区别。
29.在 Queue 中 poll()和 remove()有什么区别?
1、add()和offer()区别:
add()和offer()都是向队列中添加一个元素。一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。因此就可以在程序中进行有效的判断!
2、poll()和remove()区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。如果队列元素为空,调用remove() 的行为与 Collection 接口的版本相似会抛出异常,但是新的 poll() 方法在用空集合调用时只是返回 null。因此新的方法更适合容易出现异常条件的情况。
3、element() 和 peek() 区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。
下面是Java中Queue的一些常用方法:
add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 如果队列已满,则返回false
poll 移除并返问队列头部的元素 如果队列为空,则返回null
peek 返回队列头部的元素 如果队列为空,则返回null
put 添加一个元素 如果队列满,则阻塞
take 移除并返回队列头部的元素
30.哪些集合类是线程安全的?
线程安全(Thread-safe)就是当多线程访问时,采用了加锁的机制;即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用。防止出现数据不一致或者数据被污染的情况。Java中这样的集合对象有:Vector,HashTable,StringBuffer。
线程不安全就是不提供数据访问时的数据保护,多个线程能够同时操作某个数据,从而出现数据不一致或者数据污染的情况。Java中线程不安全的集合有:ArrayList 、LinkedList,HashMap、HashSet、TreeMap、TreeSet、StringBulider。
对于线程不安全的问题,一般会使用synchronized关键字加锁同步控制。
31.迭代器 Iterator 是什么?
对于Java数据容器,都会有很多操作上的共性,增删改查,Java采用了迭代器来为各种容器提供了公共的操作接口。这样使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。在Iterator接口中定义了三个方法:hasnext(),next(),remove()。
为了实现对其数据的遍历,我们经常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。
32.Iterator 怎么使用?有什么特点?
Iterator遍历集合元素的过程中不允许线程对集合元素进行修改,否则会抛出异常。
Iterator遍历集合元素的过程中可以通过remove方法来移除集合中的元素。
Iterator必须依附某个Collection对象而存在,Iterator本身不具有装载数据对象的功能。
Iterator.remove方法删除的是上一次Iterator.next()方法返回的对象。
next()方法,该方法通过游标指向的形式返回Iterator下一个元素。
33.Iterator 和 ListIterator 有什么区别?

  1. ListIterator有add()方法,可以向List中添加对象,而Iterator不能
  2. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
  3. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
  4. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
    34.怎么确保一个集合不能被修改?
    可以使用Collections.synchronizedList获取一个线程安全的集合,但是这无法保证集合不在循环的时候被其它线程所更改。它的目的就是使在多线程中去保证集合的安全。

多线程
马上学,别着急。
35.并行和并发有什么区别?

36.线程和进程的区别?

37.守护线程是什么?

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

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

40.线程有哪些状态?

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

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

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

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

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

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

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

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

49.什么是死锁?

50.怎么防止死锁?

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

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

53.Synchronized 和 Volatile 的区别是什么?

54.Synchronized 和 Lock 有什么区别?

55.Synchronized 和 ReentrantLock 区别是什么?

56.说一下 Atomic 的原理?

反射
57.什么是反射?
个人观点:Java中的反射只是Java语言基于RTTI这个概念的一个落地实现。RTTI,(Run Time Type Identification)运行期类型识别。反射也就是运行期间类的信息。如果不知道一个类的确切信息,RTTI会帮助调查,JVM虚拟机首先就会检查那个类型的class对象是否已经载入,如果没有,JVM就会查找同名的.class文件,并且将其载入,一旦那个类型的class进入内存,就会用它去创建那一个类型的所有对象。对于这个类,都能够知道这个类的所有属性和方法;对于这个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
58.什么是 Java 序列化?什么情况下需要序列化?
在《Thinking in Java》本书里面,对象序列化的解释是:那些实现了Serializable接口的对象,可以将他们转换成一系列字节数据,并且在以后可以完全恢复原来的样子,这个过程可以通过网络进行,利用它可以实现“有限的持久化”。“持久化”意味着对象的生存时间并不取决于程序是否在执行,而是存在于每一次程序的调用之间,通过序列化一个对象,以后再程序重新调用的时候就可以恢复那个对象,实现一种持久的效果。当Java语言里面增加了对象序列化的概念之后,就可以提供远程方法调用RMI (Remote Method Invocation),使得本来存在于其他机器上的对象可以表现出好像就在本机上的行为。
将消息发送给远程对象的时候需要通过对象序列化来传输参数和返回值,另外,序列化也是JavaBean锁必须的。当然如果不希望某个字段在序列化的过程中被序列化,可以将这个字段声明为transient(临时),就不会序列化这个字段。
59.动态代理是什么?有哪些应用?
动态代理(dynamic proxy) :利用Java的反射技术在运行时创建一个实现某些给定接口的新类及其实例。
java提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。
1、创建一个InvocationHandler对象
2、使用Proxy类的getProxyClass静态方法生成一个动态代理类stuProxyClass
3、获得stuProxyClass 中一个带InvocationHandler参数的构造器constructor
4、通过构造器constructor来创建一个动态实例stuProxy
当然,上面四个步骤可以通过Proxy类的newProxyInstances方法来简化:

//创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new MyInvocationHandler(stu);
//创建一个代理对象stuProxy,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy= (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);

动态代理的应用:
1、解决特定问题:比如需求是这样,一个接口的实现在编译时无法知道,需要在运行时才能实现
2、实现某些设计模式:适配器(Adapter)或修饰器(Decorator)
3、面向切面编程:如AOP in Spring

不难看出,JDK提供的动态代理使用起来难度确实很大,所以AOP便是在JDK动态代理的基础上添加了一层抽象,使用几个简单的注解就可以完成相同的功能。
60.怎么实现动态代理?
JDK动态代理:
1、People接口:public void sayHello();
2、Chinese 类 :implements People
实现了sayHello方法:
public void sayHello() {
System.out.println(“Chinese say hello.”);
}
3、PeopleInvocationHandler 类实现了:implements InvocationHandler

private Object peolple;
Intermediary(Object people){
    this.people = people;
}
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    Object invoke = method.invoke(people, args);
    System.out.println("-------- end ---------");
    return invoke;
}

4、使用的时候:

People chinese = new People();
//实例化代理类
PeopleInvocationHandler invocationHandler = new PeopleInvocationHandler(chinese);
//生成代理
People proxy = (People) Proxy.newProxyInstance(chinese.getClass().getClassLoader(), chinese.getClass().getInterfaces(), invocationHandler);
//调用代理方法
proxy.sayHello();

第一步:从接口中实现需要代理的方法
第二步:编写接口的代理类,实现InvocationHandler接口,在invoke方法中编写逻辑代码。
第三步:通过Proxy的newProxyInstance方法来创建我们的代理对象,通过反射传入的参数有: 代理对象,真实对象, 和InvocationHandler 这个对象
第四步;通过代理对象去调用方法。

这里难度确实有点大,如果没有实际动手编码过的话,问到的时候回答InvocationHandler和Proxy应该问题不大。
对象拷贝
61.为什么要使用克隆?
clone()方法是java中顶层父类Object中的一个方法,clone是一个native方法,运行起来就是快啊,在底层实现的。克隆的对象可能包含一些已经修改过的属性,保留着你想克隆对象的值,而new出来的对象的属性全是一个新的对象,对应的属性没有值。即当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。我把这个对象的临时属性一个一个的赋值给我新new的对象也是可以的。但是比较麻烦,使用clone就会比较快一点。
62.如何实现对象克隆?
1、对象的类实现Cloneable接口;
2、覆盖Object类的clone()方法 (覆盖clone()方法,访问修饰符设为public,默认是protected);
3、在clone()方法中调用super.clone();
63.深拷贝和浅拷贝区别是什么?
浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

Java Web
64.JSP 和 Servlet 有什么区别?
Jsp 本质上是servlet,用jsp实现的页面用servlet也能实现。jsp经编译后就变成了Servlet。
Jsp更擅长表现于页面显示,servlet更擅长于逻辑控制。
Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。
而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
JSP侧重于视图,Servlet主要用于控制逻辑
Servlet更多的是类似于一个Controller,用来做控制。
65.JSP 有哪些内置对象?作用分别是什么?
1、request对象
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。
2、response对象
response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。
3、session对象
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据(K/V)。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。
4、application对象
application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。
5、out 对象
out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。
6、pageContext 对象
获取JSP页面的out、request、response、session、application等对象,在JSP页面中可以直接使用 pageContext对象。
7、config 对象
config 对象的主要作用是取得服务器的配置信息。
8、page 对象
page 对象代表JSP本身,类似于Java编程中的 this 指针。
9、exception 对象
exception 对象的作用是显示异常信息。
66.说一下 JSP 的 4 种作用域?
1、page作用域
代表变量只能在当前页面上生效
2、request作用域
request表示一次客户端的请求。一次请求的生命周期从客户端发起到服务器接收并响应该请求,或者将该请求forward到另一个页面或者Servlet进行处理而结束
3、session作用域
当我们向服务器发送第一个请求开始,只要页面不关闭,或者会话未过期接下来的操作都属于同一次会话的范畴
4、application作用域
最广的,它代表着整个Web应用的全局变量,对每一个页面,每一个Servlet都是有效的
67.Session 和 Cookie 有什么区别?
1、Cookie以文本文件格式存储在浏览器中,而session存储在服务端
2、cookie的存储限制了数据量,只允许4KB,而session是无限量的
3、cookie值比session的值更加容易访问到
4、可以设置cookie生存时间,但session只能销毁
68.说一下 Session 的工作原理?
session技术就是一种基于后端有别于数据库的临时存储数据的技术,因为HTTP的无状态性,所以我们没有办法在HTTP发送请求的时候知道当前用户的状态,也就是比如说,当前是哪个用户的之类的这种信息,所以这个时候我们需要session来标识当前的状态。
整个流程大概分成这样的几步:

  1. 第一步将本地的cookie中的session标识和用户名,密码带到后台中
  2. 第二步后台检测有没有对应的session标识
  3. 没有的话直接生成一个新的session。有的话,检测对应的文件是否存在并且有效
  4. 失效的话,我们需要清除session然后生成新的session。不失效,使用当前的session
    69.如果客户端禁止 Cookie 能实现 Session 还能用吗?
    不能。因为Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了。
    70.Spring MVC 和 Struts 的区别是什么?
    两者都是基于MVC的设计理念的经典落地实现。不同的是,SpringMVC将一个请求映射让一个方法去解决,而Struts是让一个Java类去处理。
    Struts2是类级别的拦截,一个类对应一个request上下文,SpringMVC是方法级别的拦截。
    开发性能上,SpringMVC优于Struts2,并且配置文件也比Struts2少得多。
    在Spring3.0之后,SpringMVC已经全面超越了Struts,成为现在最优秀的MVC框架。
    71.如何避免 SQL 注入?
    SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
    防范:
    1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和
    双"-"进行转换等。
    2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
    3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
    4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
    5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
    6.sql注入的检测方法一般采取辅助软件或网站平台来检测。
    72.什么是 XSS 攻击,如何避免?
    XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
    它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。
    避免办法:
    表单提交或者url参数传递前,对需要的参数进行过滤。
    过滤用户输入的 检查用户输入的内容中是否有非法内容。
    <>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)

73.什么是 CSRF 攻击,如何避免?
CSRF(Cross site request forgery),即跨站请求伪造。
一般而且存在XSS漏洞的网站,也极有可能存在CSRF漏洞。因为CSRF攻击中的那个“伪造的请求”的URL地址,一般是通过XSS攻击来注入到服务器中的。所以其实CSRF是以XSS为基础的,也可以看做是XSS攻击的一种。CSRF一般的攻击过程是,攻击者向目标网站注入一个恶意的CSRF攻击URL地址(跨站url),当(登录)用户访问某特定网页时,如果用户点击了该URL,那么攻击就触发了,我们可以在该恶意的url对应的网页中,利用 来向目标网站发生一个get请求,该请求会携带cookie信息,所以也就借用了用户的身份,也就是伪造了一个请求,该请求可以是目标网站中的用户有权限访问的任意请求。也可以使用javascript构造一个提交表单的post请求。比如构造一个转账的post请求。所以CSRF的攻击分为了两步,首先要注入恶意URL地址,然后在该地址中写入攻击代码,利用 等标签或者使用Javascript脚本。
CSRF防御
1、referer
因为伪造的请求一般是从第三方网站发起的,所以第一个防御方法就是判断 referer 头,如果不是来自本网站的请求,就判定为CSRF攻击。但是该方法只能防御跨站的csrf攻击,不能防御同站的csrf攻击(虽然同站的csrf更难)。
2、使用验证码
每一个重要的post提交页面,使用一个验证码,因为第三方网站是无法获得验证码的。还有使用手机验证码,比如转账是使用的手机验证码。
3、使用token
每一个网页包含一个web server产生的token, 提交时,也将该token提交到服务器,服务器进行判断,如果token不对,就判定位CSRF攻击。将敏感操作又get改为post,然后在表单中使用token. 尽量使用post也有利于防御CSRF攻击。
异常
74.throw 和 throws 的区别?
throw是语句抛出异常,需要解决,而throws只是方法可能抛出异常的一个申明。
throws抛出异常出现在 public void function() throws Exception{}; throw抛出异常是在方法内。throws是“抛弃”,一旦出现异常就将其抛到调用该方法的地方去,让其他人解决这个异常,throw是“产生”,一旦出现异常就处理它。
75.final、finally、finalize 有什么区别?
1、final
final关键字可以用于类,方法,变量前,用来表示该关键字修饰的类,方法,变量具有不可变的特性。
2、finally
当代码抛出一个异常时,就会终止方法中剩余代码的处理,并退出这个方法的执行。假如我们打开了一个文件,但在处理文件过程中发生异常,这时文件还没有被关闭,此时就会产生资源回收问题。对此,java提供了一种好的解决方案,那就是finally子句,finally子句中的语句是一定会被执行的,所以我们只要把前面说的文件关闭的语句放在finally子句中无论在读写文件中是否遇到异常退出,文件关闭语句都会执行,保证了资源的合理回收。
3、finalize
finalize方法来自于java.lang.Object,用于回收资源。
可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用。
在实际应用中,不要依赖使用该方法回收任何短缺的资源,这是因为很难知道这个方法什么时候被调用。
76.try-catch-finally 中哪个部分可以省略?
可以的情况组合有:try-catch,try-finally,try-catch-finally。
77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
会执行。
1、不管有没有异常,finally中的代码都会执行
2、当try、catch中有return时,finally中的代码依然会继续执行
3、finally是在return后面的表达式运算之后执行的,此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。
4、如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。
5、finally代码中最好不要包含return,程序会提前退出,也就是说返回的值不是try或catch中的值。
78.常见的异常类有哪些?
NullPointerException 空指针异常
SQLException 数据库访问错误
IndexOutOfBoundsException 数组下标越界
IOException 某种I/O异常
IllegalArgumentException 方法传递了一个不合法或不正确的参数
ClassCastException 强制转换为不是实例的子类时,抛出该异常
RuntimeException Java虚拟机正常运行期间抛出的异常

网络
79.HTTP 响应码 301 和 302 代表的是什么?有什么区别?
301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址
301 redirect: 301 代表永久性转移(Permanently Moved)
302 redirect: 302 代表暂时性转移(Temporarily Moved )
80.Forward 和 Redirect 的区别?
Forward服务器内部转发:是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
Redirect重新定向:就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。
81.简述 TCP 和 UDP 的区别?
TCP:可靠,稳定。在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP的缺点: 慢,效率低,占用系统资源高,易被攻击。
UDP:快,比TCP稍安全。没有的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。UDP的缺点: 不可靠,不稳定,会很容易丢包。
82.TCP 为什么要三次握手,两次不行吗?为什么?
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
如果把三次握手改成仅需要两次握手,死锁是可能发生的。相互猜疑。一个在认为连接可能还未建立,忽略分组包。一个则又一直在发送分组包。
83.说一下 TCP 粘包是怎么产生的?
1、什么是粘包现象
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
2、为什么出现粘包现象
(1)发送方原因
TCP默认会使用Nagle算法。而Nagle算法主要做两件事:
1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。
所以,正是Nagle算法造成了发送方有可能造成粘包现象。
(2)接收方原因
TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。
84.OSI 的七层模型都有哪些?
1、物理层协议有:EIA/TIA-232, EIA/TIA-499,V.35, V.24,RJ45, Ethernet, 802.3
2、数据链路层协议有:Frame Relay,HDLC,PPP, IEEE 802.3/802.2
3、网络层协议有:IP,IPX,AppleTalk DDP
4、传输层协议有:TCP,UDP,SPX
5、会话层协议有:RPC,SQL,NFS,NetBIOS,names,AppleTalk
6、表示层协议有:TIFF,GIF,JPEG,PICT,ASCII,EBCDIC,encryption
7、应用层协议有:FTP,WWW,Telnet,NFS,SMTP,Gateway,SNMP
85.Get和 Post 请求有哪些区别?
Get请求有长度限制,参数会显示在URL地址栏。
Post请求没有长度显示,参数隐藏。
所以Get请求一般用于获取数据,Post请求一般用于提交数据。
86.如何实现跨域?
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题。localhost和127.0.0.1虽然都指向本机,但也属于跨域。说到底就是客户端浏览器的一种保护策略,但是我们又需要获取到其他域名下的数据。
常用的跨域方法有JSONP,CORS,postmessage等。
87.说一下 JSONP 实现原理?
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
设计模式
88.说一下你熟悉的设计模式?
设计模式三杰:单例、工厂、观察者。
单例模式Singleton
说出来你可能不信,设计模式最简单的单例模式据说总共有6种写法,这些神仙啊,真是阿西吧!
先凑合着看看最简单的懒汉饿汉吧。
它的意图是保证一个类只有一个实例,并且提供一个访问它的全局访问点。
将属性私有,构造方法私有,再提供一个全局的共有方法给使用者。这样一个最简单的懒汉式的单例模式就写完了。在暴露的方法上加上synchronized关键字,就变成了线程安全的。

直接将属性声明为static final 并且new一个空值,就能保证它是线程安全的了。

饿汉模式,加载慢,获取快,线程安全
懒汉模式,加载快,获取慢,线程不安全
观察者模式 Observer
它的意图是定义一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都得到通知并且自动被更新。简单来说,就是四个字“触发联动”。
举个例子,在Spring Cloud Config配置服务中,将配置文件提交到github上,新建了Config Server去获取在github上的配置文件,在这个module里面只需要修改bootstrap.yml这个系统级别的资源配置项,这样各个微服务只需要关注自身的业务逻辑,而无需再自己手动去配置各个繁琐的配置。在这例子中,Config Server就是一个观察的目标,而各个微服务项目都是观察者,当观察目标的配置文件修改了数据库用户,环境变更,域名等等这些信息变更的时候,各个微服务不用再一个个的去修改。
观察者模式也成为发布-订阅模式,它有推模型和拉模型。
责任链模式 Chain Of Responsibility
它的意图就是使得多个对象之间都会有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并且沿着这条链传递该请求,直到有一个对象能够处理它为止。
最常见的例子就是Java语言中异常的掷出(抛出异常)try-cach-finally,还有对用户输入数据的层层校验,不合法的、带有攻击型的这类数据会先被程序执行判断,如果校验的足够严密,才会将正确的数据交给主要的业务逻辑代码。
89.简单工厂和抽象工厂有什么区别?
简单工厂、工厂方法、抽象工厂,头疼。没啥区别,那个类图看起来都挺头疼的。
https://www.jianshu.com/p/4523dcb131c8

Spring/Spring MVC
90.为什么要使用 Spring?
拆分功能模块和非业务模块。使得各个模块耦合更松散,可以在业务逻辑之外进行增强代理,用起来更加的得心应手。在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库,达到一站式的开发便利程度。另外从2004年3月spring发布以来,它的发展业内有目共睹,在社区活跃程度、给开发带来的便捷程度来说,也必须使用啊。(感觉这问题问的有点措手不及,凭什么不用啊?)
91.解释一下什么是 AOP?
由实际问题而引入的面向切面的编程思想,代码混乱且分散。原来JDK的动态代理和Cglib的动态代理使用起来难度太大了,Spring添加了往上面抽象了一层。将编程对象转移为切面,切面模块化横切关注点,每个事务的业务逻辑位于一个位置,代码不分散,便于维护和升级,同时也使得业务模块更加的简洁,只去关注核心业务代码。
92.解释一下什么是 IOC?
反转资源获取的方向,传统的资源查找方式要求资源主动的向容器发起请求查找资源作为回应。而有力IOC之后,则会变成容器主动的将资源推送给它所管理的组件,组件需要做的事情仅仅是选择一种合适的方式来接受资源。所以IOC也更加确切的称之为DI依赖注入。
93.Spring 有哪些主要模块?
Spring有七大功能模块,分别是Spring Core,AOP,ORM,DAO,MVC,WEB,Context。
1,Spring Core
Core模块是Spring的核心类库,Spring的所有功能都依赖于该类库,Core主要实现IOC功能,Sprign的所有功能都是借助IOC实现的。
2,AOP
AOP模块是Spring的AOP库,提供了AOP(拦截器)机制,并提供常用的拦截器,供用户自定义和配置。
3,ORM
Spring 的ORM模块提供对常用的ORM框架的管理和辅助支持,Spring支持常用的Hibernate,ibtas,jdao等框架的支持,Spring本身并不对ORM进行实现,仅对常见的ORM框架进行封装,并对其进行管理
4,DAO模块
Spring 提供对JDBC的支持,对JDBC进行封装,允许JDBC使用Spring资源,并能统一管理JDBC事物,并不对JDBC进行实现。(执行sql语句)
5,WEB模块
WEB模块提供对常见框架如Struts1,WEBWORK(Struts 2),JSF的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器。
6,Context模块
Context模块提供框架式的Bean访问方式,其他程序可以通过Context访问Spring的Bean资源,相当于资源注入。
7,MVC模块
WEB MVC模块为Spring提供了一套轻量级的MVC实现,在Spring的开发中,我们既可以用Struts也可以用Spring自己的MVC框架,相对于Struts,Spring自己的MVC框架更加简洁和方便。
94.Spring 常用的注入方式有哪些?
接口注入:
接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。
Setter 注入:
对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。
构造器注入:
在构造期间完成一个完整的、合法的对象。所有依赖关系在构造函数中集中呈现。依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。
95.Spring 中的 Bean 是线程安全的吗?
因为Spring的Bean默认是单实例的,如果在不定义成员变量的情况下,spring默认是线程安全的
否则就会出现线程不安全的情况,这时候就需要设置scope=“prototype”
96.Spring 支持几种 Bean 的作用域?
五种:
singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
97.Spring 自动装配 Bean 有哪些方式?
3种:
byName 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
byType 按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
constructor 在构造函数参数的byType方式。
98.Spring 事务实现方式有哪些?

99.说一下 Spring 的事务隔离?
4种事务特性,5种隔离级别,7种传播行为
事务用来确保数据的完整性和一致性。而Spring在不同的事务管理API上都增加了一层抽象。
事务指的是逻辑上的一组操作,要么都成功,要么全部失败。事务的隔离性,主要是防止数据的脏读,不可重复读和幻读。
事务特性(4种):
原子性 (atomicity) :强调事务的不可分割.
一致性 (consistency):事务的执行的前后数据的完整性保持一致.
隔离性 (isolation) :一个事务执行的过程中,不应该受到其他事务的干扰
持久性 (durability) :事务一旦结束,数据就持久到数据库

如果不考虑隔离性引发安全性问题:
脏读 :一个事务读到了另一个事务的未提交的数据
不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
虚幻读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致.

解决读问题: 设置事务隔离级别(5种)
未提交读(read uncommited) :脏读,不可重复读,虚读都有可能发生
已提交读 (read commited):避免脏读。但是不可重复读和虚读有可能发生
可重复读 (repeatable read) :避免脏读和不可重复读.但是虚读有可能发生.
串行化的 (serializable) :避免以上所有读问题.
default 这是一个默认的隔离级别,使用数据库默认的事务隔离级别.
Mysql 默认:可重复读 Oracle 默认:读已提交
事务的传播行为
PROPAGION_XXX :事务的传播行为

  • 保证同一个事务中
    PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
    PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
    PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
  • 保证没有在同一个事务中
    PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
    PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
    PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
    PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行
    100.说一下 Spring MVC 运行流程?

Reqest – dispatcherServlet – RequestMapping (静态资源,404) – HandllerExecutionChain异常链 – HandllerAdapter – 拦截器的前置方法 – Controller的逻辑 返回ModelAndView – 拦截器的post方法对结果的属性或试图进行修改 – 异常处理定制异常返回一个新的ModelAndView 如果没有异常就返回正常的视图 – 找到ViewResolve组件解析ModelAndView得到实际的View – 渲染视图 – 调用拦截器的after方法释放资源。
流程图画起来老麻烦了。
101.Spring MVC 有哪些组件?

  1. 前端控制器组件(DispatcherServlet)
  2. 处理器组件(Controller)
  3. 处理器映射器组件(HandlerMapping)
  4. 处理器适配器组件(HandlerAdapter)
  5. 拦截器组件(HandlerInterceptor)
  6. 视图解析器组件(ViewResolver)
  7. 视图组件(View)
  8. 数据转换组件(DataBinder)
  9. 消息转换器组件(HttpMessageConverter)
    102.@RequestMapping 的作用是什么?
    用于映射url到控制器类或一个特定的处理程序方法上。
    103.@Autowired 的作用是什么?
    将一个已经被Spring管理的功能组件注入进程序中来提供给我们使用。
    高频注解:
    (包含但不仅限于此)
    @RequestMapping 映射请求
    @Autowired将一个组件注入进入程序使用
    @Component 基本注解,表示这是一个Spring管理的组件
    @Respository 标识持久层组件
    @Service标识服务层组件
    @Controller标识控制层组件
    @Transactional标识声明式的事务管理
    @PathVariable映射URL绑定的占位符
    @RequestParam 将请求中的参数作为方法的参数传递给Controller
    @ModelAttribute 传递一些参数,对象之类的,塞在一个Map里面
    @ResponseBody标注这个方法返回的是Json字符串
    @RestController @ResponseBody和@Controller可以替换成@RestController

SpringData:
@Query注解去写一条SQL语句
@Modifying去标注这条SQL语句需要事务

注解驱动,放弃了xml配置文件之后:
@Bean标注这个组将被Spring管理
@ComponentScan 扫描包的路径,可以指定扫描规则
@Impot导入Bean
@Conditional按照条件给容器中添加组件
@Configuration标注这是一个配置类

AOP的:
@Before前置通知
@After后置通知
@AfterReturning返回通知
@AfterThrowing异常通知
@Around环绕通知
@Pointcut切点方法

SpringBoot的:
@ApplicationBootApplication 主启动类
@AutoConfigurationPackage 自动配置的包,将主启动类所在的包及其子包全部扫描到Spring容器中

Spring Boot/Spring Cloud
104.什么是 Spring Boot?
Spring Boot是J2EE的一站式整体解决方案。使用各种各种的场景启动器,去繁从简。
105.为什么要用 Spring Boot?
1、快速创建独立运行的Spring项目,搭建微服务简洁高效
2、提供嵌入式的servlet容器,应用不需要打成war包都能运行
3、大量的自动配置,无需xml
4、starters自动依赖,版本控制更加简单
5、社区活跃度极高
6、SpringBoot可以作为单个应用独立运行,SpringCloud离不开SpringBoot所构建的微服务
106.Spring Boot 核心配置文件是什么?
boostrap.yml boostrap.properties
application.yml application.properties

application 是用户级别的资源配置项
bootstrap 是系统级别的资源配置项,优先级更高
107.Spring Boot 配置文件有哪几种类型?它们有什么区别?
properties文件和yml文件,yml文件是天然的树状结构,更直观一些。
108.Spring Boot 有哪些方式可以实现热部署?
热部署就是修改了一些代码之后不用重新启动项目就能实现页面数据的修改。
以下四种情况,如何能实现热部署:
1、模板引擎
在Spring Boot中开发情况下禁用模板引擎的cache
页面模板改变ctrl+F9可以重新编译当前页面并生效
2、Spring Loaded
Spring官方提供的热部署程序,实现修改类文件的热部署
下载Spring Loaded(项目地址https://github.com/spring-projects/spring-loaded)
添加运行时参数;
-javaagent:C:/springloaded-1.2.5.RELEASE.jar –noverify
3、JRebel
收费的一个热部署软件
安装插件使用即可
4、Spring Boot Devtools(推荐)
引入依赖

org.springframework.boot
spring-boot-devtools
runtime

IDEA使用ctrl+F9 在Eclipse中保存即可
109.JPA 和 Hibernate 有什么区别?
JPA是Java Persistence API,是JavaEE5的标准ORM接口,也是EJB3规范的一部分。
Hibernate是一款很流行的ORM框架,是JPA的一个实现。Hibernate有JPA没有的特性
hibernate 的效率更快,JPA 有更好的移植性,通用性。
110.什么是 Spring Cloud?
SpringCloud是分布式微服务架构下的一站式解决方案,是各种微服务框架落地技术的集合体,俗称微服务全家桶。更多时候指的是整个SpringCLoud技术栈。
111.Spring Cloud 断路器的作用是什么?
Hystrix断路器,也叫熔断器,在SpringCloud里面主要负责做服务熔断,服务降级的处理,思想跟Spring里面环绕通知、前置通知等有相似之处。程序出现异常、长时间调用失败、调用不恰当、超时等。为了避免长时间没有响应而导致全局系统的瘫痪、挂起、死机。
112.Spring Cloud 的核心组件有哪些?
SpringCloud五大神兽:
1、 服务注册与发现
Eureka采用的是C-S 架构。Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统维护人员就可以通过Eureka Server来监控系统中各个微服务是否运行正常。
2、负载均衡
主要有Ribbon和Feign这两种。
Ribbon是一套客户端负载均衡工具,再它的IRule组件里面定义了许多负载均衡策略,轮询,随机,重试等等。自定义负载均衡策略只需要实现它的接口,再添加到容器中即可。
Feign是一个申明式WebService客户端, 使得编写Web服务变得非常容易, Feign通过接口的方法调用Rest服务(之前是使用Ribbon+RestTemplate),该请求发送给Eureka服务器,通过Feign直接找到服务接口,由于在进行服务调用的时候融合了Ribbon,所以也支持负载均衡的作用。
换句话说,Feign更加符合面向接口编程的思想,因为RestTemplate是Spring提供的客户端模板工具,使用Feign的时候不需要去管这个请求会被那个具体的服务去处理,在接口上的调用。
这里还有一个坑没填:Nginx,Ribbin,Feign都能做负载均衡,说说他们的局别是什么?
3、Hystrix断路器
也叫熔断器,在SpringCloud里面主要负责做服务熔断,服务降级的处理,思想跟Spring里面环绕通知、前置通知等有相似之处。程序出现异常、长时间调用失败、调用不恰当、超时等。为了避免长时间没有响应而导致全局系统的瘫痪、挂起、死机。
这里会问的一些概念有:“扇出”、服务降级、服务熔断、服务监控、7色1线1圈也是这里的内容。
4、路由网管zuul
Zuul包含了对请求的路由和过滤两个最主要的功能:其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。而过滤器功能则负责对请求的处理过程和干预,是实现请求校验、服务聚合等功能的基础。Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
Zuul最终还是会注册进Eureka,Zuul提供=代理+路由+过滤三大功能。
这里还会问路由访问映射规则是什么意思?其实就相当于把真实的微服务名字隐藏起来,对外暴露一个虚假的名字。
5、分布式配置中心SpringCloudConfig
微服务意味着要将单体应用中的业务拆分成一个个的子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。Spring Cloud Server来解决这个问题。我们需要一套集中式配置文件的管理和落地。
这里还会问开发环境切换,git的一些东西。

除此之外SpringCloud还有好多问题,都是很容易问到的:

Hibernate
研究不是很深。
113.为什么要使用 Hibernate?

  1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
  2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
  3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
  4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
    114.什么是 ORM 框架?
    将关系数据库映射到Java语言中变成一个Java对象,通过操作这个对象达到操作数据表的目的。
    Object-Relationship-Mapping
    115.Hibernate 中如何在控制台查看打印的 SQL 语句?
    配置文件里面填写show_sql参数为true
    116.Hibernate 有几种查询方式?
    6种:HQL查询、对象化查询Criteria方法、动态查询DetachedCriteria、例子查询、sql查询、命名查询
    117.Hibernate 实体类可以被定义为 final 吗?
    可以,但不建议。Hibernate会使用代理模式在延迟关联的情况下提高性能,如果你把实体类定义成final类之后,因为 Java不允许对final类进行扩展,所以Hibernate就无法再使用代理了。
    118.在 Hibernate 中使用 Integer 和 int 做映射有什么区别?
    1、返回数据库字段值是null的话,int类型会报错。int是基本数据类型,其声明的是变量,而null则是对象。所以hibernate实体建议用integer;
    2、通过jdbc将实体存储到数据库的操作通过sql语句,基本数据类型可以直接存储,对象需要序列化存储。
    119.Hibernate 是如何工作的?
    基本就是问用Hibernate做数据库查询的时候的编程步骤了
    1.通过Configuration config = new Configuration().configure();//读取并解析hibernate.cfg.xml配置文件
    2.由hibernate.cfg.xml中的读取并解析映射信息
    3.通过SessionFactory sf = config.buildSessionFactory();//创建SessionFactory
    4.Session session = sf.openSession();//打开Sesssion
    5.Transaction tx = session.beginTransaction();//创建并启动事务Transation
    6.persistent operate操作数据,持久化操作
    7.tx.commit();//提交事务
    8.关闭Session
    9.关闭SesstionFactory
    120.get()和 load()的区别?
    如果未能发现符合条件的记录,get()方法返回null,而load方法会抛出一个ObjectNotFoundException
    121.说一下 Hibernate 的缓存机制?
    Hibernate缓存的作用:
    Hibernate是一个持久层框架,经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据
    Hibernate缓存分类:
    Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存
    Hibernate一级缓存又称为“Session的缓存”,它是内置的,意思就是说,只要你使用hibernate就必须使用session缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。在第一级缓存中,持久化类的每个实例都具有唯一的OID。
    Hibernate二级缓存又称为“SessionFactory的缓存”,由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。第二级缓存是可选的,是一个可配置的插件,在默认情况下,SessionFactory不会启用这个插件。

什么样的数据适合存放到第二级缓存中?   
1 很少被修改的数据   
2 不是很重要的数据,允许出现偶尔并发的数据   
3 不会被并发访问的数据   
4 常量数据

不适合存放到第二级缓存的数据?   
1经常被修改的数据   
2 .绝对不允许出现并发访问的数据,如财务数据,绝对不允许出现并发   
3 与其他应用共享的数据。

Hibernate查找对象如何应用缓存?
当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;如果都查不到,再查询数据库,把结果按照ID放入到缓存
删除、更新、增加数据的时候,同时更新缓存
122.Hibernate 对象有哪些状态?
 瞬时状态:也称为临时状态,对象被创建时的状态,数据库里面没有与之对应的记录
 持久状态:处于session的管理中,并且数据库里面存在与之对应的记录
 游离状态:对象不处于session的管理中,但是数据库里面存在与之对应的记录
123.在 Hibernate 中 getCurrentSession 和 openSession 的区别是什么?
openSession是打开一个新的session对象。而getCurrentSession 是获取当前上下文一个session对象,如果有已经使用的,就用旧的。没有就新建一个,开发中尽量用getCurrentSession
124.Hibernate 实体类必须要有无参构造函数吗?为什么?
是,必须提供一个无参的构造方法。
因为需要使用反射去生成这个对象。

Mybatis
不好意思,从学完就没摸过,年代久远,忘了。等我重新学一遍再说。
125.Mybatis 中 #{}和 ${}的区别是什么?
依稀记得#{}这种写法能防止SQL注入,因为它类似于JDBC里面的预编译。
${}这种写法不能防止SQL注入,它是作为参数直接填写到SQL语句里面去执行。

126.Mybatis 有几种分页方式?

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

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

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

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

131.Mybatis 和 Hibernate 的区别有哪些?

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

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

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

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

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

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

138.RabbitMQ 中 VHost 的作用是什么?

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

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

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

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

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

144.RabbitMQ 有几种广播类型?

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上注册的观察者并且做出相应的反应,实现集群中类似于master/slave的管理模式。
它的特点是一个领导者,多个跟随者。Leader负责进行投票的发起和决议,更新系统状态。follwer用于接收客户请求并且向客户端返回结果,在选举leader的过程中参与投票。集群中只要有半数以上的节点存货,zookeeper集群就能正常服务。全局数据一致性。
zookeeper=文件系统+监听通知机制
158.ZooKeeper 都有哪些功能?
Zookeeper提供的服务有:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。
统一命名服务:ip不容易记住,但是域名很容易记住,这几台机器提供的服务是同样的,就将他们命名成统一的服务名称。
统一配置管理:保证各个节点的配置信息一致,监听与通知机制就能很好的满足这一点。
统一集群管理:是否有机器的加入或者退出、选举leader。
159.ZooKeeper 有几种部署模式?
单机模式:一般就是用来测试程序能不能走,比如在hadoop里面搭建环境的时候测试一下官方的案例
伪集群模式:整个集群只有一台机器。
集群模式:真实的集群环境。
160.ZooKeeper 怎么保证主从节点的状态同步?
问到就说不知道,脑壳疼,有点偏向大数据了。
161.集群中为什么要有主节点?
主节点负责分发任务,从节点负责处理任务
162.集群中有 3 台服务器,其中一个节点宕机,这个时候 ZooKeeper 还可以使用吗?
根据选举算法,只有两种情况无法选出leader:
整个集群只有2台服务器(注意不是只剩2台,而是集群的总节点数为2)
整个集群超过半数机器挂掉。
这个时候的Zookeeper集群是可以正常使用的。
163.说一下 ZooKeeper 的通知机制?
问到就说不知道,脑壳痛,底层一堆协议算法。 要是问CAP 就使劲吹,在SpringCloud里面。
MySQL
164.数据库的三范式是什么?
第一范式(确保每列保持原子性)如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库满足第一范式。
第二范式(确保表中的每列都和主键相关)需要确保数据库表中每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
第三范式(确保每列都和主键列直接相关,而不是间接相关)

165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 ID 是几?
答案:8 auto_increment自增长列的特性
166.如何获取当前数据库版本?
select version();

查看mysql现在已提供什么存储引擎: show engines;
这里一般是考mysql自带的那种函数。
167.说一下 ACID 是什么?
事务的特性:ACID
原子性:Atomicity 一个事务不可再分割,要么都执行要么都不执行
一致性:Consistency 一个事务执行会使数据从一个一致状态切换到另外一个一致状态
隔离性:lsolation 一个事务的执行不受其他事务的干扰
持久性:durability 一个事务一旦提交,则会永久的改变数据库的数据.
168.Char 和 VarChar 的区别是什么?
char是固定长度的字符,节省存储空间,查询效率较高
varchar是可变长度的字符,比较耗费存储空间,查询效率不如char
169.Float 和 Double 的区别是什么?
我觉得这题不对,精度不同,别的就不知道了,要是问定点型和浮点型还好说。
浮点型:float(M,D) double(M,D)
点点型:dec(M,D) decimal(M,D)
M:整数部位+小数部位
D:小数部位
如果超过范围,则插入临界值
M和D都可以省略
如果是decimal,则M默认为10,D默认为0
如果是float和double,则会根据插入的数值的精度来决定精度
定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用
170.MySQL 的内连接、左连接、右连接有什么区别?
如果不使用连接就会出现笛卡尔积的现象。
内连接,两个表公共部分
左连接,以第一张表为主表,结果是第一张表的全部,查询字段在第二张表不存钻则补为null
右连接,以第二张表为主表,结果是第二张表的全部,查询字段在第一张表不存钻则补为null
左连接右连接可以互相转化。
171.MySQL索引是怎么实现的?
Mysql索引的实质就是排序了快速查找数据结构。一棵B+树。
除了数据本身之外,MySQL数据库还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,这样就可以在这些数据结构的基础上实现高级查找算法,这种数据结构就是索引。

172.怎么验证 MySQL的索引是否满足需求?
进行SQL语句的性能分析,使用explain + sql语句
其中重要的几个属性是:
1、id
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
id相同,执行顺序由上至下,id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行,id相同不同,同时存在
2、type
显示的是访问类型,是较为重要的一个指标,结果值从最好到最坏依次是:system>const>eq_ref>ref>range>index>ALL 一般来说,得保证查询至少达到range级别,最好能达到ref。
3、key
实际使用的查询,如果为null,表示没有使用索引,查询中若使用了覆盖索引,则索引和查询的select字段重叠。
4、rows
显示MySQL认为它执行查询时必须检查的行数。
5、extra:
包含不适合在其他列中显示但十分重要的额外信息:
Using filesort文件内排序 九死一生,就是建立的索引没有全部使用,只是使用了一部分。
Using temporary 新建了临时表 十死无生 使了用临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于排序 order by 和分组查询 group by。
Using Index表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错!
如果同时出现using where,表明索引被用来执行索引键值的查找;如果没有同时出现using where,表明索引只是用来读取数据而非利用索引执行查找。
覆盖索引:建立的索引是col1_col2,查询的列表刚好就是col1 col2或者部分满足。
173.说一下数据库的事务隔离?
数据库事务的隔离性质是为了防止在并发情况下脏读、幻读、不可重复读的发生。
脏读:一个事务读取了另一个事务更新但还没提交的数据,若回滚,读取到的数据就是无效的。
不可重复读:一个事务读取了数据,另一个事务更新了该数据,若第一个事务再次读取,值就不同了
幻读:一个事务读取了数据,另一个事务插入了一些新的数据,第一个事务再次读取就会多出一些来
事务的隔离级别分为四种:
未提交读 read uncommited 脏读,不可重复读,虚读都有可能发生
已提交读 read commited 避免脏读。但是不可重复读和虚读有可能发生
可重复读 repeatable read 避免脏读和不可重复读.但是虚读有可能发生.
串行化的 serializable 避免以上所有读问题.
Oracle 支持read commited,serializable
Mysql支持全部4种,默认是 repeatable read
174.说一下 MySQL常用的引擎?
1、InnoDB存储引擎
InnoDB是MySQL的默认事务型引擎,它被设计用来处理大量的短期(short-lived)事务。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。行级锁,适合高并发情况
2、MyISAM存储引擎
MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务和行级锁(myisam改表时会将整个表全锁住),有一个毫无疑问的缺陷就是崩溃后无法安全恢复。
3、Archive引擎
Archive存储引擎只支持INSERT和SELECT操作,在MySQL5.1之前不支持索引。
Archive表适合日志和数据采集类应用。适合低访问量大数据等情况。
根据英文的测试结论来看,Archive表比MyISAM表要小大约75%,比支持事务处理的InnoDB表小大约83%。
4、Blackhole引擎
Blackhole引擎没有实现任何存储机制,它会丢弃所有插入的数据,不做任何保存。但服务器会记录Blackhole表的日志,所以可以用于复制数据到备库,或者简单地记录到日志。但这种应用方式会碰到很多问题,因此并不推荐。
5、CSV引擎
CSV引擎可以将普通的CSV文件作为MySQL的表来处理,但不支持索引。
CSV引擎可以作为一种数据交换的机制,非常有用。
CSV存储的数据直接可以在操作系统里,用文本编辑器,或者excel读取。
6、Memory引擎
如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表是非常有用。Memory表至少比MyISAM表要快一个数量级。(使用专业的内存数据库更快,如redis)
7、Federated引擎
Federated引擎是访问其他MySQL服务器的一个代理,尽管该引擎看起来提供了一种很好的跨服务器的灵活性,但也经常带来问题,因此默认是禁用的。
175.说一下 MySQL的行锁和表锁?
表级锁:每次操作锁住整张表。开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
行级锁:每次操作锁住一行数据。开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
176.说一下乐观锁和悲观锁?
悲观锁(Pessimistic Concurrency Control,PCC):假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。至于怎么加锁,加锁的范围也没讲。
乐观锁(Optimistic Concurrency Control,OCC):假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。也没具体指定怎么检查。
悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。
乐观锁不能解决脏读,加锁的时间要比悲观锁短(只是在执行sql时加了基本的锁保证隔离性级别),乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。
可见,乐观锁更适合解决冲突概率极小的情况;而悲观锁则适合解决并发竞争激烈的情况,尽量用行锁,缩小加锁粒度,以提高并发处理能力,即便加行锁的时间比加表锁的要长。
177.MySQL问题排查都有哪些手段?
1、看生产环境上的慢SQL,开启慢查询日志,设置阀值,超过某一时间的sql即为慢SQL
show variables like ‘%slow_query_log%’;
set global slow_query_log=1
使用日志分析工具 mysqldumpshow 可以查看一些特定的SQL语句,比如说含有连接查询、访问次数比较多,返回结果集比较多,就可以看到这些SQL语句。
2、拿到了这些可能会导致查询变慢的SQL语句之后,接下来可以使用explain关键字去进行性能分析,从而知道MySQL是如何处理你的SQL语句,分析你的查询语句或是表结构的性能瓶颈。看是不是有索引失效的情况。
从id去排查select字句的操作表的顺序,看是不是小表驱动大表。
从type去排查是不是索引没有用上出现ALL,至少要保证range级别,最好能达到ref级别才可以。
从key去排查有没有使用索引
从rows去看查询检查了多少行
从extra去看有没有出现文件内排序using filesort、新建临时表using temporary这样特别耗费性能的情况出现。
到这个时候基本就可以解决绝大部分的问题了,其他比较棘手的问题需要使用show profile
3、show profile
先用show profiles 命令去查看一下sql语句的执行时间,当然需要开启这个功能,mysql好多牛逼的功能都是默认关闭的。执行时间长的SQL语句在这个命令下面可以很直观的看到,接着载去查看具体的CPU,IO消耗的时间,拿到这些数据去排查,基本就能解决问题了。
4、最后一些查询语句特别难处理的话需要去调整一些系统参数值来进行优化。
举个例子: order by 字句如果出现了filesort文件内排序就有单路排序和双路排序之分,双路排序会进行两次数据的扫描,IO的时间花费比较多,而单路排序会在buffer缓冲区进行排序,能不能一次排完取决于缓冲区的大小,够的话就一次排完,不够就可能是多次,效率反而降低。所以优化策略就是将sort_buffer_size参数和max_length_for_sort_data这两个参数调大。
SQL索引优化总结口诀
全值匹配我最爱,最左前缀要遵守。带头大哥不能死,中间兄弟不能掉。索引列上少计算,范围之后全失效
Like百分写最有,覆盖索引不写星。不等空值还有or, 索引失效要少用。字符引号不能丢,SQL高级也easy

178.如何做 MySQL的性能优化?
上面的177问已回答。
Redis
179.Redis 是什么?都有哪些使用场景?
Redis是一个高性能的K/V分布式内存服务器,支持持久化的NoSQL数据库,是当前比较火热的NoSQL服务器之一,也被称为数据结构服务器。它可以做缓存、持久化工具以及K/V服务器。
180.Redis 有哪些功能?
内存数据存储和持久化、支持分布式事务、支持消息的发布订阅、主从复制,将读写分离,轻松做到数据容灾备份。
181.Redis 和 MemeCache 有什么区别?
1、存储方式上,两者都是将数据存储咋内存中,但是Redis可以持久化,有RDB和AOF文件可以重新恢复数据。
2、数据类型上,Redis支持的跟多一些,有key,string,set,hash,list,和zset.
182.Redis 为什么是单线程的?
官网的解释是因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。
183.什么是缓存穿透?怎么解决?
正常使用缓存的步骤应该是:先从缓存中取数据,如果能取到,则直接返回数据给用户。这样不用访问数据库,减轻数据库的压力。如果缓存中没有数据,就会访问数据库。
缓存穿透则是猜想一个不再缓存中的数据,这样就会去查询数据库,访问的压力会穿透缓存直接给数据库。
缓存穿透可能发生在以下情况:
1、恶意攻击,猜测你的key命名方式,然后估计使用一个你缓存中不会有的key进行访问。
2、第一次数据访问,这时缓存中还没有数据,则并发场景下,所有的请求都会压到数据库。
3、数据库的数据也是空,这样即使访问了数据库,也是获取不到数据,那么缓存中肯定也没有对应的数据。这样也会导致穿透。
针对这些情况那么应对的策略就很好想到:
1、再web服务器启动时,提前将有可能被频繁并发访问的数据写入缓存。—这样就规避大量的请求在第3步出现排队阻塞。
2、规范key的命名,并且统一缓存查询和写入的入口。这样,在入口处,对key的规范进行检测。–这样保存恶意的key被拦截。
3、Synchronized双重检测机制,这时我们就需要使用同步(Synchronized)机制,在同步代码块前查询一下缓存是否存在对应的key,然后同步代码块里面再次查询缓存里是否有要查询的key。 这样“双重检测”的目的,还是避免并发场景下导致的没有意义的数据库的访问(也是一种严格避免穿透的方案)。
这一步会导致排队,但是第一步中我们说过,为了避免大量的排队,可以提前将可以预知的大量请求提前写入缓存。
4、不管数据库中是否有数据,都在缓存中保存对应的key,值为空就行。–这样是为了避免数据库中没有这个数据,导致的平凡穿透缓存对数据库进行访问。

5、第4步中的空值如果太多,也会导致内存耗尽。导致不必要的内存消耗。这样就要定期的清理空值的key。避免内存被恶意占满。导致正常的功能不能缓存数据。
184.Redis 支持的数据类型有哪些?
1、String(字符串)
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M
2、Hash(哈希)
Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里面的Map
3、List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。它的底层实际是个链表
4、Set(集合)
Redis的Set是string类型的无序集合。它是通过HashTable实现实现的。
5、zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
185.Redis 支持的 Java 客户端都有哪些?
我只使用过Jedisz这一个。
186.Jedis 和 Redisson 有哪些区别?

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

188.Redis 持久化有几种方式?
RDB和AOF

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

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

191.Redis 如何做内存优化?

192.Redis 淘汰策略有哪些?

193.Redis 常见的性能问题有哪些?该如何解决?
JVM
194.说一下 JVM 的主要组成部分?及其作用?

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

196.说一下堆栈的区别?

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

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

199.说一下类加载的执行过程?

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

201.Java 中都有哪些引用类型?

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

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

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/XiaoA82/article/details/89213705