Java常见面试题

Java常见面试题

1.JDK 和 JRE 有什么区别?
JDK是JAVA开发环境也包括运行环境,JRE是JAVA运行环境。
2.== 和 equals 的区别是什么?
==比较的是内存地址,equals比较的是内容。
分状况:==分两种状况,一种是基本数据,一种是引用数据类型。
JAVA八种基本数据类型:byte short int long float double char boolean 比较值
JAVA三种引用数据类型:类、接口、数组 比较内存地址
String是一个类,因此是引用数据类型,故==比较内存地址。凡new都是开辟新地址。

加深:重写equals,String类和Integer类,将equals变成了值比较。

3.两个对象的 hashCode()相同,则 equals()也必定为 true,对吗?
不必定。通话、重地。

 

4.final 在 java 中有什么做用?
final修饰类:该类不能被继承。
final修饰方法:该方法不能被重写。
final修饰属性:该属性不能被修改,就是常量。

5.java 中的 Math.round(-1.5) 等于多少?
注意:这是四啥五入取整,可是负数要注意取大的。比负1.5还大的整数是负一。

6.String 属于基础的数据类型吗?
不属于基本数据类型,它属于引用数据类型。
JAVA八种基本数据类型:byte short int long float double char boolean 比较值
JAVA三种引用数据类型:类、接口、数组 比较内存地址

7.java 中操做字符串都有哪些类?它们之间有什么区别?
String:操做副本
StringBuffer:线程安全,操做自己,多线程下使用。常常用。
StringBuilder:线程不安全,速度快。单线程下使用。

8.String str="i"与 String str=new String(“i”)同样吗?
不同,由于内存的分配方式不同。
String str="i"的方式,java 虚拟机会将其分配到常量池中;
而 String str=new String(“i”) 则会被分到堆内存中。

9.如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

10.String 类的经常使用方法都有那些?
length() 字符串长度
trim() 去字符串两边空格
indexOf() 查找批定字符串位置
substring(a,b) 截取
charAt() 指定位置的字符
replace(a,b,c) 替换
toLowerCase() 转小写
toUpperCase() 转大写
getBytes() 转字节数组
split() 分隔

11.抽象类必需要有抽象方法吗?
抽象类中能够没有抽象方法,也能够有抽象方法。

12.普通类和抽象类有哪些区别?
普通类中不能包含抽象方法,包含抽象的方法的必定是抽象类。
抽象类不能实例化(不能new),普通方法能够实例化。


13.抽象类能使用 final 修饰吗?
抽象类不能使用final修饰,由于被final修饰的类不能被继承。
抽象类设计的目的是为了被继承,故与之矛盾,不能使用final修饰。

14.接口和抽象类有什么区别?
接口的实现类用implements,抽象类的子类用extends。
接口中不能有构造方法,抽象类中能够有构造方法。
抽象类中能够有main方法,并能够运行。接口不能够。但能够有静态方法。
类是单继承,一个类只能继承一个类。
接口打破了单一继承,一个类能够实现多个接口,接口也能够继承多个接口。注意:接口不能实现接口。
接口用interface定义,抽象类用class定义。
接口中的方法默认都是公共的,抽象类中的方法访问修饰符不限(四种public protected 不写 private)

15.java 中 IO 流分为几种?
按流的方向能够分为输入流和输出流。
按流的类型能够分为字节流和字符流。1个字节等于8位,按8位以字节单位传输。1个字符等于2字符,故16位,以字符为单位传输。

16.BIO、NIO、AIO 有什么区别?
BIO 同步阻塞
NIO 同步非阻塞
AIO 异步非阻塞

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

• Files.exists():检测文件路径是否存在。
• Files.createFile():建立文件。
• Files.createDirectory():建立文件夹。
• Files.delete():删除一个文件或目录。
• Files.copy():复制文件。
• Files.move():移动文件。
• Files.size():查看文件个数。
• Files.read():读取文件。
• Files.write():写入文件。

18. java 容器都有哪些?
List
Set
Map
Vector
Collection

19.Collection 和 Collections 有什么区别?
Collection是集合类的顶级接口,它包含了集合类的通用方法,它的直接接口有List和Set。
Collections是集合类的工具类,它包含了一系列的静态方法,排序,查找。

20. List、Set、Map 之间的区别是什么?
List 有序可重复,它的子类额ArrayList,LinkedList。
Set 无序不可重复,它的子类有HashSet,TreeSet。
Map 键值对,它个子类有HashMap,TreeMap。

21. HashMap 和 Hashtable 有什么区别?
HashMap 同步,Hashtable 非同步
hashMap容许空键值,而hashTable不容许
hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法

22. 如何决定使用 HashMap 仍是 TreeMap?
对Map数据的增删改查,添加、删除、定位用HashMap.
对一个有序key的遍历用TreeMap。

23. 说一下 HashMap 的实现原理?
HashMap是非同步。容许null键null值。无序。
HashMap数据结构基于数组和模拟指针。数组和链表的结合体。
在添加数据时,这个位置上有其它元素,以链表形式存放,
新加入的放在链头,最早加入的放入链尾(洗盘子)
这个位置上没有其它元素,直接放在该位置上。

须要注意Jdk 1.8中对HashMap的实现作了优化,当链表中的节点数据超过八个以后,
该链表会转为红黑树来提升查询效率,从原来的O(n)到O(logn)

队列:先进先出 FIFO
链表:后进先出 LIFO
FIFO: First in, First out.先进先出。
LIFO: Last in, First out.后进先出。


24. 说一下 HashSet 的实现原理?
HashSet底层由HashMap实现
HashSet的值存放于HashMap的key上
HashMap的value统一为PRESENT

Java中HashSet的Value为何存PRESENT而不是Null?
HashSet#add() 方法须要在加入新元素时返回 true,加入重复元素时返回 falseHashMap#add() 方法
返回的是上一次以同一 key 加入的 value若从未以该 key 加入任何数据,
则返回 null然而 HashMap 容许 null 做为 value因此若是使用 null 做为 value
利用 HashMap 当返回 null 的时候咱们就没法得知 null 究竟意味着这个 key 是第一次加入仍是上一次使用了 null 做为 value 加入

25. ArrayList 和 LinkedList 的区别是什么?
最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。
使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。

算法中的O(1), O(n),O(logn), O(nlogn)分别是什么意思?
因为平时接触算法比较少,今天看资料看到了o(1),都不知道是什么意思,百度以后才知道是什么意思。
描述算法复杂度时,经常使用o(1), o(n), o(logn), o(nlogn)表示对应算法的时间复杂度,是算法的时空复杂度的表示。不只仅用于表示时间复杂度,也用于表示空间复杂度。 

O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增加量之间的关系。其中的n表明输入数据的量。 
好比时间复杂度为O(n),就表明数据量增大几倍,耗时也增大几倍。好比常见的遍历算法。再好比时间复杂度O(n^2),就表明数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。好比冒泡排序,就是典型的O(n^2)的算法,对n个数排序,须要扫描n×n次。 
再好比O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,好比,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就能够找到目标。 
O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。 
O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,不管输入数据增大多少倍,耗时/耗空间都不变。哈希算法就是典型的O(1)时间复杂度,不管数据规模多大,均可以在一次计算后找到目标(不考虑冲突的话)

26. 如何实现数组和 List 之间的转换?
List转换成为数组:调用ArrayList的toArray方法。
数组转换成为List:调用Arrays的asList方法。

27. ArrayList 和 Vector 的区别是什么?
Vector是同步的,而ArrayList不是。
在迭代的时候对列表进行改变,使用CopyOnWriteArrayList。
ArrayList比Vector快,它由于有同步,不会过载。
ArrayList更加通用,使用Collections工具类轻易地获取同步列表和只读列表。

28. Array 和 ArrayList 有何区别?
数组 和 ArrayList 有何区别?
Array能够容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小后不可变的,而ArrayList大小是可变的。
Array没有提供ArrayList那么多功能,好比addAll、removeAll和iterator等。


29. 在 Queue 中 poll()和 remove()有什么区别?
poll() 和 remove() 都是从队列中取出一个元素。
poll() 在获取元素失败的时候会返回空,
remove() 失败的时候会抛出异常。

30. 哪些集合类是线程安全的?
vector:
statck:
hashtable:
enumeration:

31. 迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,它能够遍历并选择序列中的对象

32. Iterator 怎么使用?有什么特色?
Java中的Iterator功能比较简单,而且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()得到序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。 
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具备更多的功能,它能够从两个方向遍历List,也能够从List中插入和删除元素。


33. Iterator 和 ListIterator 有什么区别?
Iterator可用来遍历Set和List集合,可是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既能够前向也能够后向。
ListIterator实现了Iterator接口,并包含其余的功能,好比:增长元素,替换元素,获取前一个和后一个元素的索引,等等。

34.怎么确保一个集合不能被修改?
能够使用 Collections. unmodifiableCollection(Collection c) 方法来建立一个只读集合,这
样改变集合的任何操做都会抛出 Java. lang. UnsupportedOperationException 异常。

List<String> list = new ArrayList<>();
list. add("A");
Collection<String> unmlist = Collections.unmodifiableCollection(list);
unmlist. add("B"); // 运行时此行报错
System. out. println(list.size());

35. 并行和并发有什么区别?
并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
并行是在不一样实体上的多个事件,并发是在同一实体上的多个事件。
在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。如hadoop分布式集群。
因此并发编程的目标是充分的利用处理器的每个核,以达到最高的处理性能。

35.并行、并发、串行、分布式是什么意思?
并行(parallel)是指两个或者多个事件在同一时刻发生; (线程/视频)
而并发(Concurrent)是指两个或多个事件在同一时间间隔发生;
串行(Sequential)A和B两个任务运行在一个CPU线程上,在A任务执行完以前不能够执行B。
分布式(distributed)分布式在并行处理的基础上,强调任务正在执行的物理设备,
如处理器、内存等等硬件,在物理上是分开的。而并行计算是指在一台计算机上的计算,在物理上不分开。

分布式计算将任务分解成许多小的部分,分配给多台计算机进行处理,
从而总体上节约了计算时间。Hadoop的MapReduce就是一种分布式计算框架

补充:线程的五种状态
一我的出生到死亡的过程。
线程:新建、就绪、运行、阻塞、死亡。
人 :出生 学习 工做 生病 升天。

新建:new Thread()线程
就绪:可执行状态 线程象.start() 随时能够被cpu调度执行
运行:得到了CPU的调度
阻塞:放弃了CPU使用权,从新排队(就绪)
等待阻塞wait() 同步阻塞 synchronized 获取同步锁失败
其它阻塞 sleep() join()
死亡:执行完了、异常退出

36.线程和进程的区别?
一个程序至少有一个进程。
一个进程至少有一个线程(主线程)。
进程在执行的过程当中拥有独立的内存单元。
同一进程中的多个线程能够并发执行。

进程是老大,线程是小弟。


37.守护线程是什么?呆萌 daemon thread 保姆
它是一个服务线程,服务其它线程。

38.建立线程的几种方式?
继承Thread类 start()
实现Runnable接口 生写run方法
Callable接口和Future建立线程 call

39.Runnable和Callable的区别
Runnable接口中的run方法没返回值,纯粹地执行run方法中的代码而已。
Callable接口中的call方法有返回值,和Future/FutureTask接合使用。

40.线程有哪些状态?
建立、就绪、运行、阻塞、死亡。

41.sleep和wait方法区别
sleep是Thread类的静态法,让调用线程进入睡眠状态,让出执行机会,
sleep(1000),等1000ms后醒来进入就绪。因为是静态方法不能改变对象锁,
当synchronized块调用了sleep方法,对象锁没有被释放,其它线程没法访问。

wait()是Object类的方法,进入到一个和该对象的等待池,同时释放对象锁,其它
线程可以访问,还能够经过notify,notifyAll方法来唤醒。

42.notify()和notifyAll区别
notifyAll()方法(唤醒全部 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程)
优先级高的线程竞争到对象锁的几率大,倘若某线程没有竞争到该对象锁,它还会留在锁池中,
惟有线程再次调用 wait()方法,它才会从新回到等待池中。
而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

43.线程的run和start方法有什么区别
run方法写具体的操做,经过Thread类的start()方法来启动线程运行run方法。
只要调了start方法就启动了run方法。

44.建立线程池有哪几种方式
newFixedThreadPool(int nThreads) 固定长度线程池
newCachedThreadPool() 可缓存的线程池
newSingleThreadExecutor() 单线程线程池
newScheduledThreadPool(int corePoolSize) 固定长度能够延时或定时执行

45.线程池都有哪些状态
Running、ShutDown、Stop、Tidying、Terminated。

46.线程池submit和execute方法有什么区别
接受的参数不一样,submit有返回值,execute没有。
submit异常处理容易

47.在Java程序中怎么保证多线程的运行安全
三个方法:
原子性:互斥,同一时刻只能有一个线程对数据操做,方式atomic,synchronized
可见性:一个线程对主内存的修改能够及时被其余线程看到,方式synchronized,volatile
有序性:一个线程观察其余线程中的指令执行顺序,因为指令重排序,结果通常杂乱无序
能够经过volatile、synchronized、lock保证有序性。

48.多线程锁的升级原理是什么?
Java中,锁的四种状态:级别从低到高:无状态锁,偏向锁,轻量锁,重量级锁。
锁能够升级但不能降级。

49.什么是死锁?教室里有一个扫把,A同窗和B学生同时抢着,各执己见。
死锁是指两个或两个以上的进程在执行过程当中,
因为竞争资源或者因为彼此通讯而形成的一种阻塞的现象,
若无外力做用,它们都将没法推动下去。
此时称系统处于死锁状态或系统产生了死锁,
这些永远在互相等待的进程称为死锁进程。
是操做系统层面的一个错误,是进程死锁的简称。

50.怎么防止死锁?
死锁的四个必要条件:
互斥条件
请求和保持条件
不可剥夺条件
环路等待条件

51.ThreadLocal是什么,应用场景
Java提供ThreadLocal类来支持线程局部变量,是一种实现线程安全的方式。
可是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别当心,在这种状况下,工做线程的生命周期比任何应用变量的生命周期都要长。
任何线程局部变量一旦在工做完成后没有释放,Java 应用就存在内存泄露的风险。

52.说一下 synchronized 底层实现原理?
synchronized能够保证方法或者代码块在运行时,同一时刻只有一个方法能够进入到临界区,同时它还能够保证共享变量的内存可见性。
Java中每个对象均可以做为锁,这是synchronized实现同步的基础:
普通同步方法,锁是当前实例对象
静态同步方法,锁是当前类的class对象
同步方法块,锁是括号里面的对象
53. synchronized 和 volatile 的区别是什么?
volatile本质是在告诉jvm当前变量在寄存器(工做内存)中的值是不肯定的,须要从主存中读取;synchronized则是锁定当前变量,只有当前线程能够访问该变量,其余线程被阻塞住。
volatile仅能使用在变量级别;synchronized则能够使用在变量、方法、和类级别的。
volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则能够保证变量的修改可见性和原子性。
volatile不会形成线程的阻塞;synchronized可能会形成线程的阻塞。
volatile标记的变量不会被编译器优化;synchronized标记的变量能够被编译器优化。


54. synchronized 和 Lock 有什么区别?
首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
synchronized没法判断是否获取锁的状态,Lock能够判断是否获取到锁;
synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程当中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),不然容易形成线程死锁;
用synchronized关键字的两个线程1和线程2,若是当前线程1得到锁,线程2线程等待。若是线程1阻塞,线程2则会一直等待下去,而Lock锁就不必定会等待下去,若是尝试获取不到锁,线程能够不用一直等待就结束了;
synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(二者皆可);
Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少许的同步问题。

55. synchronized 和 ReentrantLock 区别是什么?
synchronized是和if、else、for、while同样的关键字,ReentrantLock是类,这是两者的本质区别。既然ReentrantLock是类,那么它就提供了比synchronized更多更灵活的特性,能够被继承、能够有方法、能够有各类各样的类变量,ReentrantLock比synchronized的扩展性体如今几点上:
ReentrantLock能够对获取锁的等待时间进行设置,这样就避免了死锁
ReentrantLock能够获取各类锁的信息
ReentrantLock能够灵活地实现多路通知
另外,两者的锁机制其实也是不同的:ReentrantLock底层调用的是Unsafe的park方法加锁,synchronized操做的应该是对象头中mark word。

56. 说一下 atomic 的原理?
Atomic包中的类基本的特性就是在多线程环境下,
当有多个线程同时对单个(包括基本类型及引用类型)变量进行操做时,
具备排他性,即当多个线程同时对该变量的值进行更新时,仅有一个线程能成功,
而未成功的线程能够向自旋锁同样,继续尝试,一直等到执行成功。
这个里面大量的方法调用都会存在安全隐患,须要当心使用,不然会致使严重的后果

57. 什么是反射?
反射主要是指程序能够访问、检测和修改它自己状态或行为的一种能力。
Java反射:在程序运行的过程当中,能够知道类的全部属性和方法,对而且操做的一种能力。

58. 什么是 Java 序列化?什么状况下须要序列化?
Java 序列化就是将对象(各类对象的状态)保存在内存中,而且还能够读取出来(反序列化)。
Java经过实现序列化接口来实现Serializable。
什么状况下须要序列化:
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想经过RMI传输对象的时候;

59. 动态代理是什么?有哪些应用?
当想要给实现了某个接口的类中的方法,加一些额外的处理。
好比说加日志,加事务等。能够给这个类建立一个代理,
就是建立一个新的类,这个类不只包含原来类方法的功能,
并且还在原来的基础上添加了额外处理的新类。
这个代理类并非定义好的,是动态生成的。具备解耦意义,灵活,扩展性强。

SpringAOP,Struts的拦截器
60.怎么实现动态代理
首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。
再有一个工具类Proxy(习惯性将其称为代理类,由于调用他的newInstance()能够产生代理对象,其实他只是一个产生代理对象的工具类)。
利用到InvocationHandler,拼接代理类源码,
将其编译生成代理类的二进制码,利用加载器加载,
并将其实例化产生代理对象,最后返回。

61. 为何要使用克隆?
想对一个对象进行处理,又想保留原有的数据进行接下来的操做,就须要克隆了。
Java语言中克隆针对的是类的实例。

62. 如何实现对象克隆?
有两种方式:
• 实现Cloneable接口并重写Object类中的clone()方法;
• 实现Serializable接口,经过对象的序列化和反序列化实现克隆,能够实现真正的深度克隆
注意:基于序列化和反序列化实现的克隆不只仅是深度克隆,
更重要的是经过泛型限定,能够检查出要克隆的对象是否支持序列化,
这项检查是编译器完成的,不是在运行时抛出异常,
这种是方案明显优于使用Object类的clone方法克隆对象。
让问题在编译的时候暴露出来老是好过把问题留到运行时。

63. 深拷贝和浅拷贝区别是什么?
• 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,因此修改其中任意的值,
另外一个值都会随之变化,这就是浅拷贝(例:assign())

• 深拷贝是将对象及值复制过来,两个对象修改其中任意的值另外一个值不会改变,
这就是深拷贝(例:JSON.parse()和JSON.stringify(),
可是此方法没法复制函数类型)

64. JSP 和 Servlet 有什么区别?
JSP通过编译以后就是Servlet,JVM识别Java源代码不识别JSP,web容器将JSP编译成
Java类。
JSP用于页面展现充当视图层,Servlet用于逻辑控制充当控制层。
Servlet中没有内置对象,经过HttpServletRequest和HttpServletResponse来得到,
JSP中有九个内置对象。

65.JSP有哪些内置对象,做用分别是什么
JSP有9个内置对象:
request:封装客户端的请求,其中包含来自GET或POST请求的参数;
response:封装服务器对客户端的响应;
pageContext:经过该对象能够获取其余对象;
session:封装用户会话的对象;
application:封装服务器运行环境的对象;
out:输出服务器响应的输出流对象;
config:Web应用的配置对象;
page:JSP页面自己(至关于Java程序中的this);
exception:封装页面抛出异常的对象。

66.说一下JSP的四种做用域
JSP中的四种做用域包括page、request、session和application
page表明与一个页面相关的对象和属性。
request表明与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web组件;须要在页面显示的临时数据能够置于此做用域。
session表明与某个用户与服务器创建的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户本身的session中。
application表明与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局做用域。

67.Session和Cookie有什么区别?URL重写是什么?
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据能够保存在集群、数据库、文件中;
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
当客户端把cookie禁用了,那怎么办呢?!这个时候就须要使用URL重写技术了。
URL重写为了页面更有利于seo优化
response.encodeURL(“logoutServlet”);用于对超连接和action的表单提交进行重写。

response.encodeRedirectURL("logoutServlet");用于对response.sendRedirect()的方法进行重写。


68. 说一下 session 的工做原理?
其实session是一个存在服务器上的相似于一个散列表格的文件。
里面存有咱们须要的信息,在咱们须要用的时候能够从里面取出来。
相似于一个大号的map吧,里面的键存储的是用户的sessionid,
。这时就能够从中取出对应的值了。

69. 若是客户端禁止 cookie 能实现 session 还能用吗?
Cookie与 Session,通常认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,
而Cookie采用的是在客户端保持状态的方案。但为何禁用Cookie就不能获得Session呢?
由于Session是用Session ID来肯定当前对话所对应的服务器Session,
而Session ID是经过Cookie来传递的,禁用Cookie至关于失去了Session ID,也就得不到Session了。

70. spring mvc 和 struts 的区别是什么?
拦截机制不一样:Struts2,多例。有一套挂载机制。
SpringMVC是方法级别,线程安全。
底层框架不一样:Struts2采用的是Filter实现(StrutsPrepareAndExecuteFilter),
SpringMVC是Servlet实现(DispatcherServlet前端控制器)
初始化时,早于Filter调用。
性能方面:SpringMVC性能优于Struts2。
配置方面:SpringMVC和Spring无缝对接,容易,安全性高于Struts2。

71.如何避免SQL注入:前台,业务层,数据库
PreparedStatement
使用正则表达式过滤传入的参数
字符串过滤
JSP中调用该函数检查是否包函非法字符
JSP页面判断代码

72. 什么是 XSS 攻击,如何避免?
XSS攻击又称CSS,全称Cross Site Script (跨站脚本攻击),其原理是攻击者向有XSS漏洞的网站中输入恶意的 HTML 代码,当用户浏览该网站时,这段 HTML 代码会自动执行,从而达到攻击的目的。XSS 攻击相似于 SQL 注入攻击,SQL注入攻击中以SQL语句做为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,经过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。XSS是 Web 程序中常见的漏洞,XSS 属于被动式且用于客户端的攻击方式。
XSS防范的整体思路是:对输入(和URL参数)进行过滤,对输出进行编码。

73. 什么是 CSRF 攻击,如何避免?
CSRF(Cross-site request forgery)也被称为 one-click attack或者 session riding,中文全称是叫跨站请求伪造。通常来讲,攻击者经过伪造用户的浏览器的请求,向访问一个用户本身曾经认证访问过的网站发送出去,使目标网站接收并误觉得是用户的真实操做而去执行命令。经常使用于盗取帐号、转帐、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站可以确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操做行为。
如何避免:
1. 验证 HTTP Referer 字段
HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在一般状况下,访问一个安全受限页面的请求来自于同一个网站,而若是黑客要对其实施 CSRF
攻击,他通常只能在他本身的网站构造请求。所以,能够经过验证Referer值来防护CSRF 攻击。
2. 使用验证码
关键操做页面加上验证码,后台收到请求后经过判断验证码能够防护CSRF。但这种方法对用户不太友好。
3. 在请求地址中添加token并验证
CSRF 攻击之因此可以成功,是由于黑客能够彻底伪造用户的请求,该请求中全部的用户验证信息都是存在于cookie中,所以黑客能够在不知道这些验证信息的状况下直接利用用户本身的cookie 来经过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,而且该信息不存在于 cookie 之中。能够在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端创建一个拦截器来验证这个 token,若是请求中没有token或者 token 内容不正确,则认为多是 CSRF 攻击而拒绝该请求。这种方法要比检查 Referer 要安全一些,token 能够在用户登录后产生并放于session之中,而后在每次请求时把token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
对于 GET 请求,token 将附在请求地址以后,这样 URL 就变成 http://url?csrftoken=tokenvalue。
而对于 POST 请求来讲,要在 form 的最后加上 <input type="hidden" name="csrftoken" value="tokenvalue"/>,这样就把token以参数的形式加入请求了。
4. 在HTTP 头中自定义属性并验证
这种方法也是使用 token 并进行验证,和上一种方法不一样的是,这里并非把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。经过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,经过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担忧 token 会透过 Referer 泄露到其余网站中去。

74. throw 和 throws 的区别?
throws是用来声明一个方法可能抛出的全部异常信息,throws是将异常声明可是不处理,而是将异常往上传,谁调用我就交给谁处理。
而throw则是指抛出的一个具体的异常类型。

75. final、finally、finalize 有什么区别?
final能够修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被从新赋值。
finally通常做用在try-catch代码块中,在处理异常的时候,一般咱们将必定要执行的代码方法finally代码块中,表示无论是否出现异常,该代码块都会执行,通常用来存放一些关闭资源的代码。
finalize是一个方法,属于Object类的一个方法,而Object类是全部类的父类,该方法通常由垃圾回收器来调用,当咱们调用System的gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾。


76. try-catch-finally 中哪一个部分能够省略?
try{}catch(){}
try{}catch(){}finally{}
try{}finally{}

try不能省,catch和finally必须存在一个,也能够同时存在。
try里面的代码是有可能产生异常的代码
catch是捕获异常实例
finally不管如何都执行,主要用于释放资源

77. try-catch-finally 中,若是 catch 中 return 了,finally 还会执行吗?在以前仍是在以后?
答:会执行,finally在return 前执行。

78. 常见的异常类有哪些?
算术异常 ArithmeticException
空指针异常NullPointException
数组下标越界ArrayIndexOfOutBounds
文件读写异常IOException
数据库异常SQLException
参数异常 IllegalArgumentException
文件找不到FileNotFoundException
类没法转ClassCastException
没有这样的方法 NoSuchMethodException

79. http 响应码 301 和 302 表明的是什么?有什么区别?
HTTP状态的编码,都表明着某个URL发生了转移。
URL统一资源定位符。
区别:
• 301 redirect: 301 表明永久性转移(Permanently Moved)。
• 302 redirect: 302 表明暂时性转移(Temporarily Moved )。

80. forward 和 redirect 的区别?
张三去买房,须要民政局的结婚证实。
forward 转发 直接 张三去银行贷款,银行本身去查证张三是否结婚。
redirect重定向 间接 张三去银行贷款,银行说你去开结婚证实,张三去了民政局。

81. 简述 tcp 和 udp的区别?
TCP传输控制协议:面向链接(靠谱) 必须有问有答。无差错,不丢失,不重复,且按序到达;
UDP用户数据报文协议:无链接(不太靠谱)UDP尽最大努力交付,即不保证可靠交付。

UDP具备较好的实时性,工做效率比TCP高,适用于对高速传输和实时性有较高的通讯或广播通讯。

每一条TCP链接只能是点到点的;
UDP支持一对一,一对多,多对一和多对多的交互通讯。

TCP对系统资源要求较多,UDP对系统资源要求较少。

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

张三:喂
李四:听到
张三:我也听到你的声音了

为了实现可靠数据传输, TCP 协议的通讯双方, 都必须维护一个序列号,
以标识发送出去的数据包中, 哪些是已经被对方收到的。
三次握手的过程便是通讯双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
若是只是两次握手, 至多只有链接发起方的起始序列号能被确认, 另外一方选择的序列号则得不到确认。

83. 说一下 tcp 粘包是怎么产生的?
发送方产生粘包
发送缓冲区不止一个数据包
接收方产生粘包
接收缓冲区不止一个数据包

发送方产生粘包(发送的数据过小,要对小数据包合并)
采用TCP协议传输数据的客户端与服务器常常是保持一个长链接的状态(一次链接发一次数据不存在粘包),
双方在链接不断开的状况下,能够一直传输数据;
但当发送的数据包过于的小时,那么TCP协议默认的会启用Nagle算法,
将这些较小的数据包进行合并发送(缓冲区数据发送是一个堆压的过程);
这个合并过程就是在发送缓冲区中进行的,也就是说数据发送出来它已是粘包的状态了。

84. OSI 的七层模型都有哪些?
• 应用层:网络服务与最终用户的一个接口。
• 表示层:数据的表示、安全、压缩。
• 会话层:创建、管理、终止会话。
• 传输层:定义传输数据的协议端口号,以及流控和差错校验。
• 网络层:进行逻辑地址寻址,实现不一样网络之间的路径选择。
• 数据链路层:创建逻辑链接、进行硬件地址寻址、差错校验等功能。
• 物理层:创建、维护、断开物理链接。

85. get 和 post 请求有哪些区别?
• GET在浏览器回退时是无害的,而POST会再次提交请求。
• GET产生的URL地址能够被书签(Bookmark),而POST不能够。
• GET请求会被浏览器主动缓存(cache),而POST不会,除非手动设置。
• GET请求只能进行url编码,而POST支持多种编码方式。
• GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
• GET请求在URL中传送的参数是有长度限制的,而POST没有。
• 参数的数据类型,GET只接受ASCII字符,而POST没有限制。
• GET比POST更不安全,由于参数直接暴露在URL上,因此不能用来传递敏感信息。
• GET参数经过URL传递,POST放在Request body中。

86. 如何实现跨域?
方式一:图片ping或script标签跨域
图片ping经常使用于跟踪用户点击页面或动态广告曝光次数。
script标签能够获得从其余来源数据,这也是JSONP依赖的根据。
方式二:JSONP跨域
JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可让网页从别的网域要数据。根据 XmlHttpRequest 对象受到同源策略的影响,而利用
• 只能使用Get请求
• 不能注册success、error等事件监听函数,不能很容易的肯定JSONP请求是否失败
• JSONP是从其余域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性没法确保
方式三:CORS
Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不一样域传来沙盒脚本的方法,以避开浏览器的同源策略,确保安全的跨域数据传输。现代浏览器使用CORS在API容器如XMLHttpRequest来减小HTTP请求的风险来源。与 JSONP 不一样,CORS 除了 GET 要求方法之外也支持其余的 HTTP 要求。服务器通常须要增长以下响应头的一种或几种:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
跨域请求默认不会携带Cookie信息,若是须要携带,请配置下述参数:
"Access-Control-Allow-Credentials": true// Ajax设置"withCredentials": true
87.说一下 JSONP 实现原理?
jsonp 即 json+padding,动态建立script标签,利用script标签的src属性能够获取任何域下的js脚本,
经过这个特性(也能够说漏洞),服务器端再也不返回json格式,而是返回一段调用某个函数的js代码,
在src中进行了调用,这样实现了跨域。

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

整体来讲设计模式分为三大类:

建立型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式和线程池模式。

设计模式的六大原则
一、开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序须要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。因此一句话归纳就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,咱们须要使用接口和抽象类,后面的具体设计中咱们会提到这点。

二、里氏代换原则(Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原则中说,任何基类能够出现的地方,子类必定能够出现。LSP是继承复用的基石,只有当衍生类能够替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也可以在基类的基础上增长新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,因此里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科

三、依赖倒转原则(Dependence Inversion Principle)

这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。

四、接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。仍是一个下降类之间的耦合度的意思,从这儿咱们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。因此上文中屡次出现:下降依赖,下降耦合。

五、迪米特法则(最少知道原则)(Demeter Principle)

为何叫最少知道原则,就是说:一个实体应当尽可能少的与其余实体之间发生相互做用,使得系统功能模块相对独立。

六、合成复用原则(Composite Reuse Principle)

原则是尽可能使用合成/聚合的方式,而不是使用继承

89. 简单工厂和抽象工厂有什么区别?https://www.cnblogs.com/ldgg
简单工厂:三个部分 工厂类、抽象产品、具体产品
麓谷汽车世界 车 宝马、奔驰、奥迪
抽象工厂:产品树和产品族
宝马和奔驰是产品树
宝马跑车
奔驰跑车
奥迪跑车
产品族

90. 为何要使用 spring?
1.流行,企业用的多。解决企业应用开发的复杂性。
2.轻量,发布时文件小。1M左右。
3.控制反转IOC和依赖注入DI实现解耦。
4.面向切面AOP,让程序员更关注业务逻辑的代码开发。如日志事务的抽离。
5.能够配置单例和多例。
6.配置在xml中轻易实现。

91. 解释一下什么是 aop?
面向方面的编程,是OOP的补充和完善。
采用横切关注点思想,将应用逻辑和通用代码分离,提升代码利用。

92. 解释一下什么是 ioc?
控制反转
思想是借助于“第三方”实现对象解耦。
至关于粘合剂。

93. spring 有哪些主要模块?
Beans
Core
Context
AOP
JDBC
Web
Servlet
94. spring 经常使用的注入方式有哪些?
set注入
构造注入
注解注入
95. spring 中的 bean 是线程安全的吗?
不具有线程安全,具体结合scope的bean去设置。
prototype每次拿到的同一个bean不同。
singleton每次拿到的同一个bean同样。

96. spring 支持几种 bean 的做用域?
session、request、global session
singleton(单例)、non-singleton(也称 prototype)
97. spring 自动装配 bean 有哪些方式?
• 隐式的bean发现机制和自动装配
• 在java代码或者XML中进行显示配置
98. spring 事务实现方式有哪些?
编程式事务 TransactionProxyFactoryBean
声明式事务 Aspectj AOP
注解式事务@Transactional

99. 说一下 spring 的事务隔离?
• 脏读:一个事务读到另外一个事务未提交的更新数据。
• 幻读:例如第一个事务对一个表中的数据进行了修改,好比这种修改涉及到表中的“所有数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,之后就会发生操做第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉同样。
• 不可重复读:比方说在同一个事务中前后执行两条如出一辙的select语句,期间在这次事务中没有执行过任何DDL语句,但前后获得的结果不一致,这就是不可重复读。
100. 说一下 spring mvc 运行流程?
用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
DispatcherServlet对请求URL进行解析,获得请求资源标识符(URI)。而后根据该URI,调用HandlerMapping得到该Handler配置的全部相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
DispatcherServlet 根据得到的Handler,选择一个合适的HandlerAdapter;(附注:若是成功得到HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程当中,根据你的配置,Spring将帮你作一些额外的工做:
一、HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
二、数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
三、数据根式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等
四、数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
ViewResolver 结合Model和View,来渲染视图;
将渲染结果返回给客户端。


101. spring mvc 有哪些组件?
• DispatcherServlet:中央控制器,把请求给转发到具体的控制类
• Controller:具体处理请求的控制器
• HandlerMapping:映射处理器,负责映射中央处理器转发给controller时的映射策略
• ModelAndView:服务层返回的数据和视图层的封装类
• ViewResolver:视图解析器,解析具体的视图
• Interceptors :拦截器,负责拦截咱们定义的请求而后作处理工做

102. @RequestMapping 的做用是什么?
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的全部响应请求的方法都是以该地址做为父路径。
RequestMapping注解有六个属性,下面咱们把她分红三类进行说明。
value, method:
• value:指定请求的实际地址,指定的地址能够是URI Template 模式(后面将会说明);
• method:指定请求的method类型, GET、POST、PUT、DELETE等;
consumes,produces
• consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
• produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params,headers
• arams:指定request中必须包含某些参数值是,才让该方法处理。
• headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。

103. @Autowired 的做用是什么?
@Autowired 是一个注释,它能够对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工做。
@Autowired 默认是按照类去匹配,配合 @Qualifier 指定按照名称去装配 bean。

104. 什么是 spring boot?
SpringBoot是一个框架,一种全新的编程规范,他的产生简化了框架的使用,
所谓简化是指简化了Spring众多框架中所需的大量且繁琐的配置文件,
因此 SpringBoot是一个服务于框架的框架,服务范围是简化配置文件。

105. 为何要用 spring boot?
简单、方便、高效

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

107. spring boot 配置文件有哪几种类型?它们有什么区别?
是properties文件和yml文件。
properties是键值对的写法,直观。
yml是层级关系的写法,不容易看。
网上有许多相互转换的工具,没有什么影响。

108. spring boot 有哪些方式能够实现热部署?
我经常使用的是:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</ build>
未知
而后:使用 shift+ctrl+alt+"/" (IDEA中的快捷键) 选择"Registry" 而后勾选 compiler.automake.allow.when.app.running

109. jpa 和 hibernate 有什么区别?
JPA是一个通用的规范,
Hibernate实现了这个规范。

110. 什么是 spring cloud?
属于Spring家族。致力于分布式系统、云服务的框架。
经常使用的五大组件:
Eureka
Ribbon
Hystrix
Zuul
Feign

111. spring cloud 断路器的做用是什么?
防止雪崩效应,致使大批量服务器瘫痪,最终应用崩溃。
当请求到一个有问题的服务器时,会返回一个状态给客户端,告知客户端,并尝试自行修复,不让其它客户端访问。

112. spring cloud 的核心组件有哪些?
1.Eureka 服务的注册与发现
用RestTemplate
2.用Ribbon
实现负载均衡:多台服务器处理用户的请求(平均或均衡)
3.Hystrix断路器(由)
防止雪崩,防止系统瘫痪。
4.Zuul 网关 相似Nginx反向代理。经过请求路径标识达到请求指定服务器的目的。
5.feign,Feign 是一个声明式的伪RPC(Remote Procedure Call 远程过程调用)的REST客户端,它用了基于接口的注解方式,很方便的客户端配置。
取代了TestTemplate,让用户感受本身像在本地操做远程方法。
6.分布式配置config,配置合spring cloud bus实现动态配置更新。

Hibernate:全自动持久化框架
113.为何要使用 hibernate?
简化了JDBC操做。
是一个优秀的ORM实现,实现了JPA。
是使用JAVA反射机制。
性能好,轻量级,灵活。
支持各类关系数据库,各类映射关系。

114. 什么是 ORM 框架?
它是对象关系映射框架。
应用程序用实体来描述对象,数据库用表来描述对象。
应用程序实体间有继承和关联关系,数据库中没法表述,此时须要中间层来描述,
ORM就是实现“将程序对象映射到关系数据库中的数据。”(实体和表映射)

115. hibernate 中如何在控制台查看打印的 sql 语句?
spring.jpa.properties.hibernate.show_sql=true         //控制台是否打印
spring.jpa.properties.hibernate.format_sql=true        //格式化sql语句
spring.jpa.properties.hibernate.use_sql_comments=true //指出是什么操做生成了该语句

116. hibernate 有几种查询方式?
HQL 查实体和属性 区分大小写 Hibernate查询
SQL 查表和列 不区分 原生SQL查询
Criteria QBC:条件查询

117. hibernate 实体类能够被定义为 final 吗?
能够,但不建议。
缘由:影响性能。
为何:一个类被定义为final,Hibernate就没法使用代理。
如何避免:让实体类实现一个接口,接口中声明了全部定义于实体类中的全部public的方法

118. 在 hibernate 中使用 Integer 和 int 作映射有什么区别?
Integer是一个类,故能够判断是否为空。
int是原始数据类型,默认值为0。
Hibernate中OID为Integer,若是为null,能够判断一个对象是否是临时的。
Hibernate中OID为int型,那么还要设置unsaved-value为0。

119. hibernate 是如何工做的?
读取Hibernate配置文件
读取实体映射文件
建立工厂
建立会话
开启事务
处理
提交事务
关闭会话
关闭工厂

120. get()和 load()的区别?
get()即时,没有使用属性也发出SQL
load()是延时,在使用时才发出SQL

121. 说一下 hibernate 的缓存机制?
一级缓存,二级缓存。
一级缓存就是 Session 级别的缓存,在事务范围内有效是,内置的不能被卸载。
二级缓存是 SesionFactory级别的缓存,从应用启动到应用结束有效。二级缓存用第三方插件,须要配置。
扩展:hibernate的二级缓存默认是不支持分布式缓存的。使用 memcahe,redis等中央缓存来代替二级缓存。

122. hibernate 对象有哪些状态?
临时状态(瞬时状态):new
持久状态:save() saveOrUpdate()
脱管状态:session.close()

123. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
getCurrentSession()若是已经有session,那么就用这个,若是没有就开启新的。
openSession,每次都会开启新的session。

124.hibernate 实体类必需要有无参构造函数吗?为何?
必需要一个无参的构造函数。
Hibernate经过反射来构建对象,而且是调用其默认构造方法来实现。

MyBaits 半自动化框架,让程序员更好的更灵活的使用sql

125.mybatis 中 #{}和 ${}的区别是什么?
#{}是预编译,至关于JDBC中的PreparedStatement问号占位符。
${}是拼字符串,至关于JDBC中的Statement,有sql注入的风险。
#{}能够防止sql注入。

126.mybatis 有几种分页方式?
数组分页
sql分页
拦截器分页
RowBounds分页
第三方插件分页:如PageHelper

127.RowBounds 是一次性查询所有结果吗?为何?
RowBounds 表面是在“全部”数据中检索数据,其实并不是是一次性查询出全部数据,
由于 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,
它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,
它会在你执行 next()的时候,去查询更多的数据。
就比如你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,因此你要取 4 次才能把钱取完。
只是对于 jdbc 来讲,当你调用 next()的时候会自动帮你完成查询工做。这样作的好处能够有效的防止内存溢出。

128.mybatis 逻辑分页和物理分页的区别是什么?
物理分页速度上并不必定快于逻辑分页,逻辑分页速度上也并不必定快于物理分页。
物理分页老是优于逻辑分页:没有必要将属于数据库端的压力加诸到应用端来,
就算速度上存在优点,然而其它性能上的优势足以弥补这个缺点

129.mybatis 是否支持延迟加载?延迟加载的原理是什么?
支持,可是仅在配置了关联关系的状况下,而且设置了azyLoadingEnabled=true。
它的原理是,使用CGLIB建立目标对象的代理对象,当调用目标方法时,进入拦截器方法,
好比调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,
那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,而后调用a.setB(b),
因而a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

130.说一下 mybatis 的一级缓存和二级缓存?
一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储做用域为 Session,当 Session flush 或 close 以后,该 Session 中的全部 Cache 就将清空,默认打开一级缓存。
二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不一样在于其存储做用域为 Mapper(Namespace),而且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类须要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;
对于缓存数据更新机制,当某一个做用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操做后,默认该做用域下全部 select 中的缓存将被 clear。

131.mybatis 和 hibernate 的区别有哪些?
(1)Mybatis和hibernate不一样,它不彻底是一个ORM框架,由于MyBatis须要程序员本身编写Sql语句。
(2)Mybatis直接编写原生态sql,能够严格控制sql执行性能,灵活度高,很是适合对关系数据模型要求不高的软件开发,由于这类软件需求变化频繁,一但需求变化要求迅速输出成果。可是灵活的前提是mybatis没法作到数据库无关性,若是须要实现支持多种数据库的软件,则须要自定义多套sql映射文件,工做量大。
(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,若是用hibernate开发能够节省不少代码,提升效率。

132.mybatis 有哪些执行器(Executor)?
SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完马上关闭Statement对象。
ReuseExecutor:执行update或select,以sql做为key查找Statement对象,存在就使用,不存在就建立,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将全部sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每一个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

133.mybatis 分页插件的实现原理是什么?
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,而后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

134.mybatis 如何编写一个自定义插件?
blog.csdn.net/qq_30051265/article/details/80266434

RabbitMQ
135.rabbitmq 的使用场景有哪些?
https://www.cnblogs.com/zhao-yi/p/9299126.html
2.1 异步处理
场景说明:用户注册后,须要发注册邮件和注册短信,传统的作法有两种1.串行的方式;2.并行的方式
(1)串行方式:将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务所有完成后才返回给客户端。这有一个问题是,邮件,短信并非必须的,它只是一个通知,而这种作法让客户端等待没有必要等待的东西.
(2)并行方式:将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提升处理的时间。
假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间100ms。虽然并性已经提升的处理时间,可是,前面说过,邮件和短信对我正常的使用网站没有任何影响,客户端没有必要等着其发送完成才显示注册成功,英爱是写入数据库后就返回.
(3)消息队列
引入消息队列后,把发送邮件,短信不是必须的业务逻辑异步处理
这里写图片描述
由此能够看出,引入消息队列后,用户的响应时间就等于写入数据库的时间+写入消息队列的时间(能够忽略不计),引入消息队列后处理后,响应时间是串行的3倍,是并行的2倍。

2.2 应用解耦
场景:双11是购物狂节,用户下单后,订单系统须要通知库存系统,传统的作法就是订单系统调用库存系统的接口.
这种作法有一个缺点:
当库存系统出现故障时,订单就会失败。(这样马云将少赚好多好多钱^ ^)
订单系统和库存系统高耦合.
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。

库存系统:订阅下单的消息,获取下单消息,进行库操做。
就算库存系统出现故障,消息队列也能保证消息的可靠投递,不会致使消息丢失(马云这下高兴了).

引入消息队列

2.3 流量削峰
流量削峰通常在秒杀活动中应用普遍
场景:秒杀活动,通常会由于流量过大,致使应用挂掉,为了解决这个问题,通常在应用前端加入消息队列。
做用:
1.能够控制活动人数,超过此必定阀值的订单直接丢弃(我为何秒杀一次都没有成功过呢^^)
2.能够缓解短期的高流量压垮应用(应用程序按本身的最大处理能力获取订单)
这里写图片描述
1.用户的请求,服务器收到以后,首先写入消息队列,加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面.
2.秒杀业务根据消息队列中的请求信息,再作后续处理.

136.rabbitmq 有哪些重要的角色?
RabbitMQ 中重要的角色有:生产者、消费者和代理:
生产者:消息的建立者,负责建立和推送数据到消息服务器;
消费者:消息的接收方,用于处理数据和确认消息;
代理:就是 RabbitMQ 自己,用于扮演“快递”的角色,自己不生产消息,只是扮演“快递”的角色。

137.rabbitmq 有哪些重要的组件?
ConnectionFactory(链接管理器):应用程序与Rabbit之间创建链接的管理器,程序代码中使用。
Channel(信道):消息推送使用的通道。
Exchange(交换器):用于接受、分配消息。
Queue(队列):用于存储生产者的消息。
RoutingKey(路由键):用于把生成者的数据分配到交换器上。
BindingKey(绑定键):用于把交换器的消息绑定到队列上。

138.rabbitmq 中 vhost 的做用是什么?
vhost 能够理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的 queue、exchange 和 binding 等,但最最重要的是,其拥有独立的权限系统,能够作到 vhost 范围的用户控制。固然,从 RabbitMQ 的全局角度,vhost 能够做为不一样权限隔离的手段(一个典型的例子就是不一样的应用能够跑在不一样的 vhost 中)。

139.rabbitmq 的消息是怎么发送的?
首先客户端必须链接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会建立一个 tcp 链接,一旦 tcp 打开并经过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就建立了一条 amqp 信道(channel),信道是建立在“真实” tcp 上的虚拟链接,amqp 命令都是经过信道发送出去的,每一个信道都会有一个惟一的 id,不管是发布消息,订阅队列都是经过这个信道完成的。

140.rabbitmq 怎么保证消息的稳定性?
提供了事务的功能。
经过将 channel 设置为 confirm(确认)模式。

141.rabbitmq 怎么避免消息丢失?
消息持久化
ACK确认机制
设置集群镜像模式
消息补偿机制

142.要保证消息持久化成功的条件有哪些?
声明队列必须设置持久化 durable 设置为 true.
消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。
消息已经到达持久化交换器。
消息已经到达持久化队列。
以上四个条件都知足才能保证消息持久化成功。

143.rabbitmq 持久化有什么缺点?
持久化的缺地就是下降了服务器的吞吐量,由于使用的是磁盘而非内存存储,从而下降了吞吐量。可尽可能使用 ssd 硬盘来缓解吞吐量的问题。

144.rabbitmq 有几种广播类型?
fanout: 全部bind到此exchange的queue均可以接收消息(纯广播,绑定到RabbitMQ的接受者都能收到消息);
direct: 经过routingKey和exchange决定的那个惟一的queue能够接收消息;
topic:全部符合routingKey(此时能够是一个表达式)的routingKey所bind的queue能够接收消息;

145.rabbitmq 怎么实现延迟消息队列?
使用 RabbitMQ-delayed-message-exchange 插件实现延迟功能。
146.rabbitmq 集群有什么用?
集群主要有如下两个用途:
高可用:某个服务器出现问题,整个 RabbitMQ 还能够继续使用;
高容量:集群能够承载更多的消息量。
147.rabbitmq 节点的类型有哪些?
磁盘节点:消息会存储到磁盘。
内存节点:消息都存储在内存中,重启服务器消息丢失,性能高于磁盘类型。

148.rabbitmq 集群搭建须要注意哪些问题?
各节点之间使用“–link”链接,此属性不能忽略。
各节点使用的 erlang cookie 值必须相同,此值至关于“秘钥”的功能,用于各节点的认证。
整个集群中必须包含一个磁盘节点。

149.rabbitmq 每一个节点是其余节点的完整拷贝吗?为何?
不是,缘由有如下两个:
存储空间的考虑:若是每一个节点都拥有全部队列的彻底拷贝,这样新增节点不但没有新增存储空间,反而增长了更多的冗余数据;
性能的考虑:若是每条消息都须要完整拷贝到每个集群节点,那新增节点并无提高处理消息的能力,最可能是保持和单节点相同的性能甚至是更糟。

150.rabbitmq 集群中惟一一个磁盘节点崩溃了会发生什么状况?
若是惟一磁盘的磁盘节点崩溃了,不能进行如下操做:
不能建立队列
不能建立交换器
不能建立绑定
不能添加用户
不能更改权限
不能添加和删除集群节点
惟一磁盘节点崩溃了,集群是能够保持运行的,但你不能更改任何东西。

151.rabbitmq 对集群节点中止顺序有要求吗?
中止服务:应当先关闭内存节点,再关闭磁盘节点。先关闭磁盘节点的话会致使没法建立交换器、队列、绑定关系,从而可能会致使数据丢失。
启动服务:先启动磁盘节点,再启动内存节点。

Kafka
kafka 能够脱离 zookeeper 单独使用吗?为何?
kafka 不能脱离 zookeeper 单独使用,由于 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。
153. kafka 有几种数据保留的策略?
kafka 有两种数据保存策略:按照过时时间保留和按照存储的消息大小保留。
154. kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如何处理?
这个时候 kafka 会执行数据清除工做,时间和大小不论那个知足条件,都会清空数据。
155. 什么状况会致使 kafka 运行变慢?
cpu 性能瓶颈
磁盘读写瓶颈
网络瓶颈
156. 使用 kafka 集群须要注意什么?
集群的数量不是越多越好,最好不要超过 7 个,由于节点越多,消息复制须要的时间就越长,整个群组的吞吐量就越低。
集群数量最好是单数,由于超过一半故障集群就不能用了,设置为单数容错率更高。

Zookeeper
1. zookeeper 是什么?
zookeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 google chubby 的开源实现,是 hadoop 和 hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
158. zookeeper 都有哪些功能?
集群管理:监控节点存活状态、运行请求等。
主节点选举:主节点挂掉了以后能够从备用的节点开始新一轮选主,主节点选举说的就是这个选举的过程,使用 zookeeper 能够协助完成这个过程。
分布式锁:zookeeper 提供两种锁:独占锁、共享锁。独占锁即一次只能有一个线程使用资源,共享锁是读锁共享,读写互斥,便可以有多线线程同时读同一个资源,若是要使用写锁也只能有一个线程使用。zookeeper能够对分布式锁进行控制。
命名服务:在分布式系统中,经过使用命名服务,客户端应用可以根据指定名字来获取资源或服务的地址,提供者等信息。
159. zookeeper 有几种部署模式?
zookeeper 有三种部署模式:
单机部署:一台集群上运行;
集群部署:多台集群运行;
伪集群部署:一台集群启动多个 zookeeper 实例运行。
160. zookeeper 怎么保证主从节点的状态同步?
zookeeper 的核心是原子广播,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫作 zab 协议。zab 协议有两种模式,分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,zab 就进入了恢复模式,当领导者被选举出来,且大多数 server 完成了和 leader 的状态同步之后,恢复模式就结束了。状态同步保证了 leader 和 server 具备相同的系统状态。
161. 集群中为何要有主节点?
在分布式环境中,有些业务逻辑只须要集群中的某一台机器进行执行,其余的机器能够共享这个结果,这样能够大大减小重复计算,提升性能,因此就须要主节点。
162. 集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还能够使用吗?
能够继续使用,单数服务器只要没超过一半的服务器宕机就能够继续使用。
163. 说一下 zookeeper 的通知机制?
客户端端会对某个 znode 创建一个 watcher 事件,当该 znode 发生变化时,这些客户端会收到 zookeeper 的通知,而后客户端能够根据 znode 变化来作出业务上的改变。

MySql
1. 数据库的三范式是什么?
第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项。
第二范式:要求实体的属性彻底依赖于主关键字。所谓彻底依赖是指不能存在仅依赖主关键字一部分的属性。
第三范式:任何非主属性不依赖于其它非主属性。

165. 一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
表类型若是是 MyISAM ,那 id 就是 8。
表类型若是是 InnoDB,那 id 就是 6。
InnoDB 表只会把自增主键的最大 id 记录在内存中,因此重启以后会致使最大 id 丢失。
166. 如何获取当前数据库版本?
使用 select version() 获取当前 MySQL 数据库版本。
167. 说一下 ACID 是什么?
Atomicity(原子性):一个事务(transaction)中的全部操做,或者所有完成,或者所有不完成,不会结束在中间某个环节。事务在执行过程当中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务历来没有执行过同样。即,事务不可分割、不可约简。
Consistency(一致性):在事务开始以前和事务结束之后,数据库的完整性没有被破坏。这表示写入的资料必须彻底符合全部的预设约束、触发器、级联回滚等。
Isolation(隔离性):数据库容许多个并发事务同时对其数据进行读写和修改的能力,隔离性能够防止多个事务并发执行时因为交叉执行而致使数据的不一致。事务隔离分为不一样级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即使系统故障也不会丢失。
168. char 和 varchar 的区别是什么?
char(n) :固定长度类型,好比订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间仍是 10 个字节,其余 7 个是空字节。
char 优势:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 很是合适。
varchar(n) :可变长度,存储的值是每一个值占用的字节再加上一个用来记录其长度的字节的长度。
因此,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,两者使用须要权衡。


169. float 和 double 的区别是什么?
float 最多能够存储 8 位的十进制数,并在内存中占 4 字节。
double 最可能够存储 16 位的十进制数,并在内存中占 8 字节。
170. mysql 的内链接、左链接、右链接有什么区别?
内链接关键字:inner join;左链接:left join;右链接:right join。
内链接是把匹配的关联数据显示出来;左链接是左边的表所有显示出来,右边的表显示出符合条件的数据;右链接正好相反。
171. mysql 索引是怎么实现的?
索引是知足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
具体来讲 MySQL 中的索引,不一样的数据引擎实现有所不一样,
但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,(BTree一是平衡树)
能够到达二分法的性能,找到数据区域以后就找到了完整的数据结构了,全部索引的性能也是更好的。

172. 怎么验证 mysql 的索引是否知足需求?
使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否知足需求。
explain 语法:explain select * from table where type=1。
173. 说一下数据库的事务隔离?
MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
READ-UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其余事务读取(会出现幻读、脏读、不可重复读)。
READ-COMMITTED:提交读,一个事务提交后才能被其余事务读取到(会形成幻读、不可重复读)。
REPEATABLE-READ:可重复读,默认级别,保证屡次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会形成幻读)。
SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务可以读取另外一个事务中还未提交的数据。好比,某个事务尝试插入记录 A,此时该事务还未提交,而后另外一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,屡次读同一数据。
幻读 :指同一个事务内屡次查询返回的结果集不同。好比同一个事务 A 第一次查询时候有 n 条记录,可是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的缘由也是另一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,全部数据行的记录就变多或者变少了。

174. 说一下 mysql 经常使用的引擎?
InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,而且还提供了行级锁和外键的约束,
它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,
InnoDB 会在内存中创建缓冲池,用于缓冲数据和索引。可是该引擎是不支持全文搜索,
同时启动也比较的慢,它是不会保存表的行数的,因此当进行 select count(*) from table 指令的时候,
须要进行扫描全表。因为锁的粒度小,写操做是不会锁定全表的,因此在并发度较高的场景下使用会提高效率的。

MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。
所以当执行插入和更新语句时,即执行写操做的时候须要锁定这个表,因此会致使效率会下降。
不过和 InnoDB 不一样的是,MyIASM 引擎是保存了表的行数,因而当进行 select count(*) from table 语句时,
能够直接的读取已经保存的值而不须要进行扫描全表。因此,若是表的读操做远远多于写操做时,而且不须要事务的支持的,
能够将 MyIASM 做为数据库引擎的首选。

175. 说一下 mysql 的行锁和表锁?
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的几率最高,并发量最低。
行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的几率小,并发度最高。

176. 说一下乐观锁和悲观锁?
乐观锁:每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
悲观锁:每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
数据库的乐观锁须要本身实现,在表里面添加一个 version 字段,每次修改为功值加 1,
这样每次修改的时候先对比一下,本身拥有的 version 和数据库如今的 version 是否一致,若是不一致就不修改,这样就实现了乐观锁。

177. mysql 问题排查都有哪些手段?
使用 show processlist 命令查看当前全部链接信息。
使用 explain 命令查询 SQL 语句执行计划。
开启慢查询日志,查看慢查询的 SQL。
178. 如何作 mysql 的性能优化?
为搜索字段建立索引。
避免使用 select *,列出须要查询的字段。
垂直分割分表。
选择正确的存储引擎。

mysql 分库分表(水平切割和垂直切割)
分表是分散数据库压力的好方法。
分表,最直白的意思,就是将一个表结构分为多个表,而后,能够再同一个库里,也能够放到不一样的库。
固然,首先要知道什么状况下,才须要分表。我的以为单表记录条数达到百万到千万级别时就要使用分表了。

纵向分表
将原本能够在同一个表的内容,人为划分为多个表。(所谓的原本,是指按照关系型数据库的第三范式要求,是应该在同一个表的。)
分表理由:根据数据的活跃度进行分离,(由于不一样活跃的数据,处理方式是不一样的)

案例:
对于一个博客系统,文章标题,做者,分类,建立时间等,是变化频率慢,查询次数多,并且最好有很好的实时性的数据,咱们把它叫作冷数据。而博客的浏览量,回复数等,相似的统计信息,或者别的变化频率比较高的数据,咱们把它叫作活跃数据。因此,在进行数据库结构设计的时候,就应该考虑分表,首先是纵向分表的处理。
这样纵向分表后:
首先存储引擎的使用不一样,冷数据使用MyIsam 能够有更好的查询数据。活跃数据,能够使用Innodb ,能够有更好的更新速度。
其次,对冷数据进行更多的从库配置,由于更多的操做时查询,这样来加快查询速度。对热数据,能够相对有更多的主库的横向分表处理。
其实,对于一些特殊的活跃数据,也能够考虑使用memcache ,redis
之类的缓存,等累计到必定量再去更新数据库。或者mongodb 一类的nosql 数据库,这里只是举例,就先不说这个。

横向分表
字面意思,就能够看出来,是把大的表结构,横向切割为一样结构的不一样表,如,用户信息表,user_1,user_2 等。表结构是彻底同样,可是,根据某些特定的规则来划分的表,如根据用户ID来取模划分。
分表理由:根据数据量的规模来划分,保证单表的容量不会太大,从而来保证单表的查询等处理能力。
案例:同上面的例子,博客系统。当博客的量达到很大时候,就应该采起横向分割来下降每一个单表的压力,来提高性能。例如博客的冷数据表,假如分为100个表,当同时有100万个用户在浏览时,若是是单表的话,会进行100万次请求,而如今分表后,就多是每一个表进行1万个数据的请求(由于,不可能绝对的平均,只是假设),这样压力就下降了不少不少。


redis 是什么?都有哪些使用场景?
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis 使用场景:
数据高并发的读写
海量数据的读写
对扩展性要求高的数据
180. redis 有哪些功能?
数据缓存功能
分布式锁的功能
支持数据持久化
支持事务
支持消息队列
181. redis 和 memecache 有什么区别?
memecached全部的值均是简单的字符串,redis做为其替代者,支持更为丰富的数据类型
redis的速度比memcached快不少
redis能够持久化其数据

182. redis 为何是单线程的?
cpu不是Redis的瓶颈,它受内存和带宽的影响,单线程容易实现。

补充:nginx 和 nodejs 也都是高性能单线程的表明。

183. 什么是缓存穿透?怎么解决?
缓存穿透:指查询一个必定不存在的数据,因为缓存是不命中时须要从数据库查询,查不到数据则不写入缓存,这将致使这个不存在的数据每次请求都要到数据库去查询,形成缓存穿透
解决方案:最简单粗暴的方法若是一个查询返回的数据为空(无论是数据不存在,仍是系统故障),咱们就把这个空结果进行缓存,但它的过时时间会很短,最长不超过五分钟。

184. redis 支持的数据类型有哪些?
string、list、hash、set、zset。
185. redis 支持的 java 客户端都有哪些?
Redisson、Jedis、lettuce等等,官方推荐使用Redisson。

186. jedis 和 redisson 有哪些区别?
Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持。
Redisson实现了分布式和可扩展的Java数据结构。
和Jedis相比,功能较为简单,不支持字符串操做,不支持排序、事务、管道、分区等Redis特性。
Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者可以将精力更集中地放在处理业务逻辑上

187. 怎么保证缓存和数据库数据的一致性?
合理设置缓存的过时时间。
新增、更改、删除数据库操做时同步更新 Redis,能够使用事物机制来保证数据的一致性。

188. redis 持久化有几种方式?
RDB(Redis Database):指定的时间间隔能对你的数据进行快照存储。
AOF(Append Only File):每个收到的写命令都经过write函数追加到文件中。

189. redis 怎么实现分布式锁?
Redis 分布式锁其实就是在系统里面占一个“坑”,其余程序也要占“坑”的时候,占用成功了就能够继续执行,失败了就只能放弃或稍后重试。
占坑通常使用 setnx(set if not exists)指令,只容许被一个程序占有,使用完调用 del 释放锁。

190. redis 分布式锁有什么缺陷?
Redis 分布式锁不能解决超时的问题,分布式锁有一个超时时间,程序的执行若是超出了锁的超时时间就会出现问题。

191. redis 如何作内存优化?
尽量使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存很是小,
因此你应该尽量的将你的数据模型抽象到一个散列表里面。
好比你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,
而是应该把这个用户的全部信息存储到一张散列表里面。

192. redis 淘汰策略有哪些?
1.已设置过时时间的数据集
最近最少使用淘汰策略
将要过时
任意淘汰
2.从数据集
最近最少使用淘汰策略
任意淘汰
禁止驱逐数据
193. redis 常见的性能问题有哪些?该如何解决?
主服务器写内存快照,会阻塞主线程的工做,当快照比较大时对性能影响是很是大的,会间断性暂停服务,因此主服务器最好不要写内存快照。
Redis 主从复制的性能问题,为了主从复制的速度和链接的稳定性,主从库最好在同一个局域网内。

JVM
1. 说一下 jvm 的主要组成部分?及其做用?
类加载器(ClassLoader)
运行时数据区(Runtime Data Area)
执行引擎(Execution Engine)
本地库接口(Native Interface)
组件的做用:首先经过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操做系统去执行,所以须要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程当中须要调用其余语言的本地库接口(Native Interface)来实现整个程序的功能。

195. 说一下 jvm 运行时数据区?
程序计数器
虚拟机栈
本地方法栈

方法区

有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户进程的启动和结束而建立和销毁。

196.说一下堆栈的区别?
栈内存存储的是局部变量而堆内存存储的是实体;
栈内存的更新速度要快于堆内存,由于局部变量的生命周期很短;
栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

197.队列和栈是什么?有什么区别?
队列和栈都是被用来预存储数据的。
队列容许先进先出检索元素,但也有例外的状况,Deque 接口容许从两端检索元素。
栈和队列很类似,但它运行对元素进行后进先出进行检索。

火车过隧道,洗盘子

198. 什么是双亲委派模型?
双亲委派模型:若是一个类加载器收到了类加载的请求,它首先不会本身去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样全部的加载请求都会被传送到顶层的启动类加载器中,只有当父加载没法完成加载请求(它的搜索范围中没找到所需的类)时,子加载器才会尝试去加载类。

199. 说一下类加载的执行过程?
加载:根据查找路径找到相应的 class 文件而后导入;
检查:检查加载的 class 文件的正确性;
准备:给类中的静态变量分配内存空间;
解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址;
初始化:对静态变量和静态代码块执行初始化工做。

200. 怎么判断对象是否能够被回收?
通常有两种方法来判断:
引用计数器:为每一个对象建立一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就能够被回收。它有一个缺点不能解决循环引用的问题;
可达性分析:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证实此对象是能够被回收的。

201. java 中都有哪些引用类型?
https://blog.csdn.net/sinat_21118695/article/details/82392028
强引用
软引用
弱引用
虚引用(幽灵引用/幻影引用)

202. 说一下 jvm 有哪些垃圾回收算法?
https://blog.csdn.net/wuzhiwei549/article/details/80563134
标记-清除算法
标记-整理算法
复制算法
分代算法

203. 说一下 jvm 有哪些垃圾回收器?
Serial:最先的单线程串行垃圾回收器。
Serial Old:Serial 垃圾回收器的老年版本,一样也是单线程的,能够做为 CMS 垃圾回收器的备选预案。
ParNew:是 Serial 的多线程版本。
Parallel 和 ParNew 收集器相似是多线程的,但 Parallel 是吞吐量优先的收集器,能够牺牲等待时间换取系统的吞吐量。
Parallel Old 是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。
CMS:一种以得到最短停顿时间为目标的收集器,很是适用 B/S 系统。
G1:一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 9 之后的默认 GC 选项。

204. 详细介绍一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep 的简称,是以牺牲吞吐量为代价来得到最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上,这种垃圾回收器很是适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。
CMS 使用的是标记-清除的算法实现的,因此在 gc 的时候会产生大量的内存碎片,当剩余内存不能知足程序运行要求时,系统将会出现 Concurrent Mode Failure,临时 CMS 会采用 Serial Old 回收器进行垃圾清除,此时的性能将会被下降。

205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?
新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器通常采用的是复制算法,复制算法的优势是效率高,缺点是内存利用率低;老年代回收器通常采用的是标记-整理的算法进行垃圾回收。

206. 简述分代垃圾回收器是怎么工做的?
分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。
老生代当空间占用到达某个值以后就会触发全局垃圾收回,通常使用标记整理的执行算法。

207. 说一下 jvm 调优的工具?
JDK 自带了不少监控工具,都位于 JDK 的 bin 目录下,其中最经常使用的是 jconsole 和 jvisualvm 这两款视图监控工具。
jconsole:用于对 JVM 中的内存、线程和类等进行监控;
jvisualvm:JDK 自带的全能分析工具,能够分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。

208. 经常使用的 jvm 调优的参数都有哪些?
-Xms2g:初始化推大小为 2g;
-Xmx2g:堆最大内存为 2g;
-XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
-XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
-XX:+PrintGC:开启打印 gc 信息;
-XX:+PrintGCDetails:打印 gc 详细信息。


补充-Springboot+SpringCloud
209.什么是SpringBoot?
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员再也不须要定义样板化的配置。
Spring Boot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各类启动器,开发者能快速上手。

210.SpringBoot经常使用的starter
一、spring-boot-starter-web(嵌入Tomcat和web开发须要的servlet和jsp支持)
二、spring-boot-starter-data-jpa(数据库支持)
三、spring-boot-starter-data-Redis(Redis支持)
四、spring-boot-starter-data-solr(solr搜索应用框架支持)
五、mybatis-spring-boot-starter(第三方mybatis集成starter)

211.SpringBoot自动配置原理
一、@EnableAutoConfiguration这个注解会"猜"你将如何配置spring,前提是你已经添加了jar依赖项,若是spring-boot-starter-web已经添加Tomcat和SpringMVC,这个注释就会自动假设您在开发一个web应用程序并添加相应的spring配置,会自动去maven中读取每一个starter中的spring.factories文件,该文件里配置了全部须要被建立spring容器中bean
二、在main方法中加上@SpringBootApplication和@EnableAutoConfiguration

212.SpringBoot starter工做原理
一、SpringBoot在启动时扫描项目依赖的jar包,寻找包含spring.factories文件的jar
二、根据spring.factories配置加载AutoConfigure
三、根据@Conditional注解的条件,进行自动配置并将bean注入到Spring Context

213.SpringBoot的优势
一、减小开发、测试时间和努力
二、使用JavaConfig有助于避免使用XML
三、避免大量的maven导入和各类版本冲突
四、提供意见发展方法
五、经过提供默认值快速开始开发
六、没有单独的web服务器须要,这就意味着再也不须要启动Tomcat、Glassfish或其余任何东西
七、须要更少的配置,由于没有web.xml文件。只需添加用@Configuration注释的类,而后添加用@Bean注释的方法,Spring将自动加载对象并像之前同样对其进行管理。甚至能够将@Autowired添加到bean方法中,以使用Spring自动装入须要的依赖关系中

214.Springcloud解决那些问题
配置管理、(注册中心eureka、zk)、服务发现、服务注册、断路器、路由策略、全局锁、分布式会话、客户端调用、接口网关(zuul)、服务管理系统.

215.SpringBoot与Springcloud
一、SpringBoot简化了xml配置,快速整合框架
二、Springcloud是一套微服务解决方案—RPC远程调用
三、关系Springcloud依赖与SpringBoot(web组件用的SpringMVC),为何Springcloud会依赖与SpringBoot?由于Springcloud写接口就是SpringMVC接口
四、SpringBootproperties和yml中能够使用${random}设置一些随机值

215.服务的调用
restTemplate、feign(均使用httpClient技术),负载均衡ribbon

216.服务调用的原理
服务首先注册到注册中心eureka中(注册一个名字经过名字调用)

217.负载均衡
ribbon,先去注册中心取到对应的服务,而后交给我ribbon

218.配置详解
一、eureka.client.register-with-eureka:是否向注册中心注册本身,注册为true反之为false
二、eureka.client.fetch-registry:是否须要去检索服务,检索为true反之为false
三、eureka.client.serviceUrl.defaultZone : 指定服务注册中心的地址

219.Eureka
一、eureka可分为三个角色:服务发现者、服务注册者、注册发现中心,可是这三个角色并不和实际部署的模型是一对一的关系
二、全部的网络通讯都是基于http(s)协议的
三、Eureka和AWS是紧密结合的,不管是配置仍是源码,好比Region、zone…,Region能够经过配置文件进行配置,若是不配置默认使用us-east-1。一样Zone也能够配置,若不配置默认使用defaultZone

220.高可用配置
Eureka server 的高可用实际上就是将本身做为服务向其余服务注册中心注册本身,这样就能够造成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用效果。

221.微服务
之前全部的代码都放在同一个工程中、部署在同一个服务器、同一项目的不一样模块不一样功能互相抢占资源,微服务就是将工程根据不一样的业务规则拆分红微服务,部署在不一样的服务器上,服务之间相互调用,java中有的微服务有dubbo(只能用来作微服务)、springcloud( 提供了服务的发现、断路器等)。

222.微服务的特色
按业务划分为一个独立运行的程序,即服务单元
服务之间经过HTTP协议相互通讯
自动化部署
能够用不一样的编程语言
能够用不一样的存储技术
服务集中化管理
微服务是一个分布式系统


223.微服务的优点
一、将一个复杂的业务拆分为若干小的业务,将复杂的业务简单化,新人只须要了解他所接管的服务的代码,减小了新人的学习成本。
二、因为微服务是分布式服务,服务于服务之间没有任何耦合。微服务系统的微服务单元具备很强的横向拓展能力。
三、服务于服务之间采用HTTP网络通讯协议来通讯,单个服务内部高度耦合,服务与服务之间彻底独立,无耦合。这使得微服务能够采用任何的开发语言和技术来实现,提升开发效率、下降开发成本。
四、微服务是按照业务进行拆分的,并有坚实的服务边界,若要重写某一业务代码,不需了解因此业务,重写简单。
五、微服务的每一个服务单元是独立部署的,即独立运行在某个进程中,微服务的修改和部署对其余服务没有影响。
六、微服务在CAP理论中采用的AP架构,具备高可用分区容错特色。高可用主要体如今系统7x24不间断服务,他要求系统有大量的服务器集群,从而提升系统的负载能力。分区容错也使得系统更加健壮。

224.微服务的不足
一、微服务的复杂度:构建一个微服务比较复杂,服务与服务之间经过HTTP协议或其余消息传递机制通讯,开发者要选出最佳的通讯机制,并解决网络服务差时带来的风险。
二、分布式事物:将事物分红多阶段提交,若是一阶段某一节点失败仍会致使数据不正确。若是事物涉及的节点不少,某一节点的网络出现异常会致使整个事务处于阻塞状态,大大下降数据库的性能。
三、服务划分:将一个完整的系统拆分红不少个服务,是一件很是困难的事,由于这涉及了具体的业务场景
四、服务部署:最佳部署容器Docker
微服务和SOA的关系:
微服务相对于和ESB联系在一块儿的SOA轻便敏捷的多,微服务将复杂的业务组件化,也是一种面向服务思想的体现。对于微服务来讲,它是SOA的一种体现,可是它比ESB实现的SOA更加轻便、敏捷和简单。

225.微服务和SOA的关系
微服务相对于和ESB联系在一块儿的SOA轻便敏捷的多,微服务将复杂的业务组件化,也是一种面向服务思想的体现。对于微服务来讲,它是SOA的一种体现,可是它比ESB实现的SOA更加轻便、敏捷和简单。

226.springcloud如何实现服务注册与发现
服务发布时指定对应的服务名(IP地址和端口号),将服务注册到注册中心(eureka和zookeeper),可是这一切是Springcloud自动实现的,只须要在SpringBoot的启动类上加上@EnableDisscoveryClient注解,同一服务修改端口就能够启动多个实例调用方法:传递服务名称经过注册中心获取全部的可用实例,经过负载均衡策略(Ribbon和Feign)调用对应的服务

227.Ribbon和Feign的区别
Ribbon添加的maven依赖是spring-starter-ribbon,使用@RibbonClient(value=“服务名称”)使用RestTemplate调用远程服务对应的方法,
Feign添加的maven依赖是spring-starter-feign,服务提供方提供对外接口,调用方使用,在接口上使用FeignClient(“指定服务名”),
具体区别:
一、启动类使用的注解不一样,Ribbon使用的是@RibbonClient,Feign使用的是@EnableFeignClients
二、服务的指定位置不一样,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明
三、调用方式不一样,Ribbon须要本身构建http请求,模拟http请求而后使用RestTemplate发送给其余服务,步骤比较繁琐。Feign则是在Ribbon的基础上进行了一次改进,采用接口调用的方式,将须要调用的其余服务的方法定义成抽象方法便可,不须要本身构建http请求,不过要注意的是抽象方法的注解、方法签名要和提供方的彻底一致。


228.雪崩效应
分布式系统中的服务通讯依赖于网络,网络很差,必然会对分布式系统带来很大的影响。在分布式系统中,服务之间相互依赖,若是一个服务之间出现了故障或者网络延迟,在高并发的状况下,会致使线程阻塞,在很短的时间内该服务的线程资源会消耗殆尽,最终使得该服务不可用。因为服务的相互依赖,可能会致使整个系统的不可用,这就是“雪崩效应”。为了防止此类事件的发生,分布式系统必然要采起相应的措施,如熔断机制(Springcloud采用的是Hystrix)

229.熔断机制
一、当一个服务出现故障时,请求失败次数超过设定的阀值(默认50)以后,该服务就会开启熔断器,以后该服务就不进行任何业务逻辑操做,执行快速失败,直接返回请求失败的信息。其余依赖于该服务的服务就不会由于得不到响应而形成线程阻塞,这是除了该服务和依赖于该服务的部分功能不可用外,其余功能正常。
二、熔断器还有一个自我修复机制,当一个服务熔断后,通过一段时间(5s)半打开熔断器。半打开的熔断器会检查一部分请求(只能有一个请求)是否正常,其余请求执行快速失败,检查的请求若是响应成功,则可判断该服务正常了,就可关闭该服务的熔断器,反之则继续打开熔断器。这种自我熔断机制和自我修复机制能够使程序更加健壮、也能够为开发和运维减小不少没必要要的工做。
三、熔断组件每每会提供一系列的监控,如:服务可用与否、熔断器是否被打开、目前的吞吐量、网络延迟状态的监控等,从而可让开发人员和运维人员的了解服务的情况。

230.Eureka基础架构
1>、服务注册中心:Eureka提供的服务端,提供服务注册与发现的功能
1>>、失效剔除:对于那些非正常下线的服务实例(内存溢出、网络故障致使的),服务注册中心不能收到“服务下线”的请求,为了将这些没法提供服务的实例从服务列表中剔除,Eureka Server在启动的时候会建立一个定时任务,默认每隔一段时间(默认60s)将当前清单中超时(默认90s)没有续约的服务剔除出去。
2>>、自我保护:Eureka Server 在运行期间,会统计心跳失败的比例在15分钟以内是否低于85%,若是出现低于的状况(生产环境因为网络不稳定会致使),Eureka Server会降当前的实例注册信息保护起来,让这些实例不过时,尽量保护这些注册信息,可是在这保护期间内实例出现问题,那么客户端就很容易拿到实际上已经不存在的服务实例,会出现调用失败的状况,因此客户端必须有容错机制,好比能够使用请求重试、断路器等机制。
在本地进行开发时能够使用 eureka.server.enable-self-preseervation=false参数来关闭保护机制,以确保注册中心能够将不可用的实例剔除。

2>、服务提供者:提供服务的应用,能够是SpringBoot应用也能够是其余的技术平台且遵循Eureka通讯机制的应用。他将本身提供的服务注册到Eureka,以供其余应用发现,(如:service层)
1>>、服务注册:服务提供者在启动的时候会经过发送Rest请求的方式将本身注册到Eureka Server(服务注册中心)中,同时带上自身服务的一些元数据,Eureka Server 接收到这个Rest请求后,将元数据存储在一个双层结构Map中,第一层的key是服务名,第二层key是具体服务的实例名
2>>、服务同步:如有两个或两个以上的Eureka Server(服务注册中心)时,他们之间是互相注册的,当服务提供者发送注册请求到一个服务注册中心时,它会将该请求转发到集群中相连的其余注册中心,从而实现注册中心间的服务同步,这样服务提供者的服务信息能够经过任意一台服务中心获取到
3>>、服务续约:在注册完服务以后,服务提供者会维护一个心跳来持续告诉Eureka Server:“我还活着”,以防止Eureka Server的“剔除任务”将该服务实例从服务列表中排除出去。配置:eureka.instance.lease-renewal-in-seconds=30(续约任务的调用间隔时间,默认30秒,也就是每隔30秒向服务端发送一次心跳,证实本身依然存活),eureka.instance.lease-expiration-duration-in-seconds=90(服务失效时间,默认90秒,也就是告诉服务端,若是90秒以内没有给你发送心跳就证实我“死”了,将我剔除)

3>、服务消费者:消费者应用从服务注册中心获取服务列表,从而使消费者能够知道去何处调用其所须要的服务,如:Ribbon实现消费方式、Feign实现消费方式
1>>、获取服务:当启动服务消费者的时候,它会发送一个Rest请求给注册中心,获取上面注册的服务清单,Eureka Server会维护一份只读的服务清单来返回给客户端,而且每三十秒更新一次
2>>、服务调用:在服务消费者获取到服务清单后,经过服务名能够得到具体提供服务的实例名和该实例的元信息,采用Ribbon实现负载均衡
3>>、服务下线:当服务实例进行正常的关闭操做时,它会触发一个服务下线的Rest请求给Eureka Server,告诉服务注册中心“我要下线了”。服务端接收到请求以后,将该服务状态设置为下线,并把下线时间传播出去。


231.Eureka和zookeeper均可以提供服务注册与发现的功能,二者的区别
Zookeeper保证了CP(C:一致性,P:分区容错性),Eureka保证了AP(A:高可用,P:分区容错)
一、Zookeeper-----当向注册中心查询服务列表时,咱们能够容忍注册中心返回的是几分钟之前的信息,但不能容忍直接down掉不可用的。也就是说服务注册功能对高可用性要求比较高,可是zk会出现这样的一种状况,当master节点由于网络故障与其余节点失去联系时,剩余的节点会从新选leader。问题在于,选取leader的时间过长(30~120s),且选取期间zk集群都不可用,这样就会致使选取期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大几率会发生的事,虽然服务最终恢复,可是漫长的选择时间致使的注册长期不可用是不能容忍的
二、Eureka则看明白这一点,所以再设计的优先保证了高可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响到正常节点的工做,剩余的节点依然能够提供注册和查询服务。而Eureka的客户端再向某个Eureka注册时若是发现链接失败,则会自动切换至其余节点,只要有一台Eureka还在,就能保证注册服务的可用(保证可用性),只不过查到的信息可能不是最新的(不保证一致性)。除此以外Eureka还有一种自我保护机制,若是在15分钟内超过85%的节点都没有正常心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时就会出现如下几种状况:
1>、Eureka再也不从注册列表移除由于长时间没收到心跳而应该过时的服务
2>、Eureka仍然可以接受新服务的注册和查询请求,可是不会被同步到其它节点上(保证当前节点可用)
3>、当网络稳定时,当前实例新的注册信息会被同步到其它节点中
Eureka还有客户端缓存功能(Eureka分为客户端程序和服务器端程序两个部分,客户端程序负责向外提供注册与发现服务接口)。因此即使Eureka集群中全部节点都失效,或者发生网络分隔故障致使客户端不能访问任何一台Eureka服务器;Eureka服务的消费者任然能够经过Eureka客户端缓存来获取全部的服务注册信息。甚至最极端的环境下,全部正常的Eureka节点都不对请求产生响应也没有更好的服务器解决方案来解决这种问题时;得益于Eureka的客户端缓存技术,消费者服务仍然能够经过Eureka客户端查询与获取注册服务信息,这点很重要,所以Eureka能够很好的应对网络故障致使部分节点失去联系的状况,而不像Zookeeper那样使整个注册服务瘫痪。

232.CAP理论
一、Consistency:指数据的强一致性。若是写入某个数据成功,以后读取,读到的都是新写入的数据;若是写入失败,读到的都不是写入失败的数据。
二、Availability:指服务的可用性
三、Partition-tolerance:指分区容错

233.Ribbon和Nginx的区别
Nginx性能好,但Ribbon能够剔除不健康节点,Nginx剔除比较麻烦,Ribbon是客户端负载均衡,Nginx是服务端负载均衡

234.服务注册与发现
服务注册就是向服务注册中心注册一个服务实例,服务提供者将本身的服务信息(服务名、IP地址等)告知注册中心。服务发现是服务消费另外一个服务时,注册中心将服务的实例返回给服务消费者,一个服务既是服务提供者又是服务消费者。
服务注册中心健康检查机制,当一个服务实例注册成功之后,会定时向注册中心发送一个心跳证实本身可用,若中止发送心跳证实服务不可用将会别剔除。若过段时间继续想注册中心提供心跳,将会从新加入服务注册中心列表中。

235.服务的负载均衡
为何要用:微服务是将业务代码拆分为不少小的服务单元,服务之间的相互调用经过HTTP协议来调用,为了保证服务的高可用,服务单元每每都是集群化部署的,那么消费者该调用那个服务提供者的实例呢?
介绍:服务消费者集成负载均衡组件,该组件会向服务消费者获取服务注册列表信息,并隔一段时间从新刷新获取列表。当服务消费者消费服务时,负载均衡组件获取服务提供者全部实例的注册信息,并经过必定的负载均衡策略(能够本身配置)选择一个服务提供者实例,向该实例进行服务消费,这样就实现了负载均衡。



236.Redis集群搭建的三种方式
https://blog.csdn.net/e3002/article/details/100691472
相关文章
相关标签/搜索