Java最全面试宝典
2023-08-25 14:52:12 1 举报
AI智能生成
登录查看完整内容
从基础到分布式的面试,后续继续增加
作者其他创作
大纲/内容
TCP/IP协议是美国国防部高级计划研究局为实现ARPANET互联网而开发的。
网络接口层(链路层):包括操作系统中的设备驱动程序、计算机中对应的网络接口卡网络层(互连层、网际层):处理分组在网络中的活动,比如分组的选路。负责IP寻址,分割和组装数据包,路由选择等。运输层:主要为两台主机上的应用提供端到端的通信应用层:负责处理特定的应用程序细节。
说一下TCP/IP四层模型
物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流。单位:比特、数据位、流、比特流数据链路层:主要将从物理层接收的数据进行 MAC 地址(网卡的地址)的封装与解封装。在这一层工作的设备是交换机,数据通过交换机来传输。单位:帧、数据帧网络层:主要将从下层接收到的数据进行 IP 地址(例 192.168.0.1)的封装与解封装。在这一层工作的设备是路由器。单位:数据报、数据包、分组、包传输层:定义了一些传输数据的协议和端口号(WWW 端口 80 等),如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据),UDP(用户数据报协议,与 TCP 特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如 QQ 聊天数据就是通过这种方式传输的)。主要是将从下层接收的数据进行分段进行传输,到达目的地址后在进行重组。单位:数据段、分段、报文段会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是 IP 也可以是 MAC 或者是主机名)表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够识别的东西转换成人能够能识别的东西(如图片、声音等))应用层:主要是一些终端的应用,比如说FTP(各种文件下载),WEB(IE浏览),QQ等。单位:报文
说一下OSI七层模型
共同点:两个都是以协议栈的概念为基础,协议栈中的协议彼此互相独立;都采用了层次结构的概念,各层功能大体相似。不同点:OSI有7层,TCP/IP有4层。TCP/IP网络层提供无连接通信,传输层支持无连接和面向连接两种;OSI网络层支持面向连接和无连接,传输层只支持面向连接的通信。
OSI参考模型与TCP/IP参考模型对应关系及区别?
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手
介绍一下TCP 三次握手和四次挥手
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境
TCP和UDP的区别?
TCP协议利用窗口机制实现流量控制;TCP连接建立时,双方都为之分配了固定大小的缓冲空间;TCP的接收端只允许另一端发送其缓冲区所能接纳的数据:接收端在给发送端发送确认段时,通告接收窗口大小;发送端在接下来发送数据段时,确保未确认段的应用层数据总量不超过接收端通告的接收窗口大小,从而确保接收端不会发生缓存溢出。
TCP如何进行流量控制?
什么是拥塞控制?TCP是如何进行拥塞控制的?
传输层无法保证数据的可靠传输,只能通过应用层来实现。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。实现确认机制、重传机制、窗口确认机制。如果不利用linux协议栈以及上层socket机制,自己通过抓包和发包的方式去实现可靠性传输,那么必须实现如下功能:发送:包的分片、包确认、包的重发接收:包的调序、包的序号确认注:①给数据包编号,按照包的顺序接收并存储;②接收端接收到数据包后发送确认信息给发送端,发送端接收确认数据以后再继续发送下一个包,如果接收端收到的数据包的编号不是期望的编号,则要求发送端重新发送。目前利用udp实现了可靠的数据传输分别为RUDP、RTP、UDT。
UDP如何实现可靠性传输?
面向连接的服务,通信双方在进行通信之前,要先在双方建立起一个完整的可以彼此沟通的通道,在通信过程中,整个连接的情况一直可以被实时地监控和管理。 非面向连接的服务,不需要预先建立一个联络两个通信节点的连接,需要通信的时候,发送节点就可以往网络上发送信息,让信息自主地在网络上去传,一般在传输的过程中不再加以监控。
面向连接和非面向连接的服务的特点是什么?
Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同:端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443;资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源;开销:Https通信需要证书,而证书一般需要向认证机构购买;Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。
Http和Https的区别?
A类地址(1~126):网络号占前8位,以0开头,主机号占后24位。B类地址(128~191):网络号占前16位,以10开头,主机号占后16位。C类地址(192~223):网络号占前24位,以110开头,主机号占后8位。D类地址(224~239):以1110开头,保留位多播地址。E类地址(240~255):以1111开头,保留位今后使用。
IP地址有哪些分类?
通过IP地址获得物理地址,是设备通过自己知道的IP地址来获得自己不知道的物理地址的协议。过程:每个主机都会在自己的 ARP 缓冲区中建立一个 ARP 列表,以表示 IP 地址和 MAC 地址之间的对应关系当源主机要发送数据时,首先检查 ARP 列表中是否有对应 IP 地址的目的主机的 MAC 地址,如果有,则直接发送数据,如果没有,就向\"本网段\"的所有主机发送 ARP 数据包,该数据包包括的内容有:源主机 IP 地址,源主机 MAC 地址,目的主机的 IP 地址。 当本网络的所有主机收到该 ARP 数据包时,首先检查数据包中的目的主机 IP 地址是否是自己的 IP 地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的 IP 和 MAC 地址写入到 ARP 列表中,如果已经存在,则覆盖,然后将自己的 MAC 地址写入 ARP 响应包中,告诉源主机自己是它想要找的 MAC 地址。 源主机收到 ARP 响应包后。将目的主机的 IP 和 MAC 地址写入 ARP 列表,并利用此信息发送数据。如果源主机一直没有收到 ARP 响应数据包,表示 ARP 查询失败。广播发送ARP请求,单播发送 ARP 响应。
ARP地址解析协议的工作过程?
当 DNS 客户机需要在程序中使用名称时,它会查询 DNS 服务器来解析该名称。客户机发送的每条查询信息包括三条信息:指定的 DNS 域名指定的查询类型DNS 域名的指定类别基于 UDP 服务,端口 53,该应用一般不直接为用户使用,而是为其他应用服务,如 HTTP,SMTP 等在其中需要完成主机名到 IP 地址的转换。
DNS(Domain Name System)域名系统的工作原理?
静态路由是由管理员手工配置的,适合比较简单的网络或需要做路由特殊控制。动态路由则是由动态路由协议自动维护的,不需人工干预,适合比较复杂大型的网络。 路由器能够自动地建立自己的路由表,并且能够根据实际实际情况的变化适时地进行调整。动态路由机制的运作依赖路由器的两个基本功能:对路由表的维护;路由器之间实时的路由信息交换。
静态路由和动态路由有什么区别?
计算机网络
计算机基础
面向对象
面向过程
面向对象和面向过程的区别
封装
继承
简单说就是用同样的对象引用调用同样的方法但是做了不同的事情.主要体现在方法重载和方法重写
多态
将一些类的共同特征总结出来构造一个类
如果面试问4大特性就加上抽象
面向对象有哪些特性
多态主要以重载和重写俩种表现方式
多态的实现机制
简单易学
平台无关性
可靠性
安全性
支持多线程
支持网络编程
编译与解释并存
Java语言有哪些特点
byte
short
int
long
整数类型
float
double
浮点类型
char
字符
boolean
布尔类型
基本数据类型
类
接口
数组
引用类型
数据类型有哪些
访问权限修饰符区别
基本数据类型和访问修饰符
抽象类必须使用extends来继承
接口必须使用implements来实现
实现
抽象类可以有构造函数
接口没有
构造函数
接口不能
main方法
实现数量
抽象可以是任意修饰符
接口只能默认使用public修饰符
访问修饰符
接口和抽象类区别
final
finally
finalize
final/finally/finalize的区别
不能final修饰后不能被继承
抽象类能用final修饰么
为什么不能用浮点型表示金额
Integer是int的封装类
int和Integer区别
按位与
逻辑与
&运算符有俩种用法
&&
&于&&的区别
==与equals区别
1.提高效率
2.保证同一个对象
重写后俩个方法的关系
为什么重写 equals时必须重写 hashCode 方法?
2
四舍五入的原理是在参数上加上0.5然后向下取整
Java中的Math.round(1.5)等于多少?
-1
Java中的Math.round(-1.5)等于多少?
与返回值无关
重载
参数和返回类型必须一致
访问权限不能比父类中被重写的方法的访问权限更低
重写的方法不能抛出比被重写方法更广泛的强制性异常
重写
重载(overload)和重写(override)的区别?
构造方法能不能重写?能不能重载?构造方法能不能显式调用?
静态变量
实例变量
阐述静态变量和实例变量的区别?
隐式转换
显示转换
什么是隐式转换?什么是显式转换?
把包装类型转化为基本数据类型
拆箱
把基本数据类型转化为包装类
装箱
什么是拆装箱?
break 和 continue 的区别?
JavaSE语法
String长度是不可变的
StringBuilder比StringBuffer拥有更好的性能
String、StringBuffer、StringBuilder 的区别?
不一样Sring str = \"aaa\
String str=\"aaa\" 与 String str=new String(\"aaa\")一样吗?
String str=\"aa\" ,String s=\"bb\" ,String aa=aa+s;一共创建了几个对象?
String s = \"Hello\";s = s + \" world!\";这两行代码执行后,原始的 String 对象中的内容到底变了没有?
String类
什么是泛型
E-Element 在集合中使用
T - Type Java类
K - Key 键
V - Value 值
N - Number 数值类型
? - 表示不确定的java类型 无限制通配符类型
Object 所有类的根类 使用的时候需要类型强制转换
泛型中K T V E ?object等的含义 ?
泛型
基础语法
说一下Java中的异常体系?
Error
Exception
Error和Exception的区别
空指针
NullPointerException
找不到指定的类
ClassNotFoundException
字符串转换数字异常
NumberFormatException
数组下标越界
IndexOutOfBoundsException
数据类型转化异常
ClassCastException
写出你最常见的 5 个 RuntimeException?
知道自己如何处理的异常自己捕获处理
如何处理异常?
会执行在return之前执行finall对执行结果不会改变
try()里面有⼀个return语句, 那么后面的finally{}里面的代码会不会被执行?什么时候执行,return前还是return后?
抛出的是一个实例
throw
throws
throw 和 throws 的区别?
异常
ArrayList
LinkedList
Vecotr
List
HashSet
TreeSet
Set
单列集合
HashMap
ConcurrentHashMap
TreeMap
HashTable
双列集合
说下集合的体系
Collection
Collections
Collection 和 Collections的区别?
ArrayList集合加入1万条数据,应该怎么提高效率?
他们都有一个初始的容量大小
说一下ArrayList和Vector的扩容?
List和Set的区别?
底层是TreeMap的keySet()在插入的时候调用compareTo()来判断元素是否重用
Set如何保证元素不重复
3HashSet的其他操作都是基于HashMap的
HashSet实现原理?
将Set放入到一个Lists数组中直接拿坐标0就可以
如何取到Set集合中的第一个元素 ?
TreeSet要求存放的对象的所属类必须事项Comparable接口
TreeMap要求存放的键必须实现Compareble接口
TreeMap和TreeSet在排序时如何比较元素?
子主题
Collection工具类中的sort方法如何比较元素?
集合
一个具有独立功能的程序
进程
一个进程包含多个线程,是CPU调度和分派的基本单位
线程
线程和进程之间的区别
2个主线程:负责main方法的执行垃圾回收线程:负责垃圾回收
一个Java应用程序至少有几个线程?
stop方法,不建议使用
使用一个标志,符合条件时结束线程
interrupt
如何停止一个线程?
等待,不释放锁
sleep
调用后,线程等待线程会立即释放掉锁
wait
sleep() 和 wait() 有什么区别?
继承Thread类
实现Runnable接口
实现Callable接口
多线程的创建方式?
线程池可以提高线程的创建和销毁开销
jdk提供了5中线程池,有单线程的,有固定线程数的,有控制线程池定时周期执行任务的,有可缓存的,开发中常用的是ThreadPoolExecutor
谈谈你对线程池的理解?jdk提供了哪几种线程池?他们有什么区别?
核心线程池大小
corePoolSize
最大线程池大小
maximumPoolSize
线程最大空闲时间
keepAliveTime
时间单位
TimeUnit unit
等待队列
BlockingQueue<Runnable> workQueue
线程创建工厂
ThreadFactory threadFactory
拒绝策略
RejectedExecutionHandler handler
说一下ThreadPoolExecutor各个参数的含义?
当线程对象创建后,进入了新建状态
新建状态
当线程调用start方法进入就绪状态,等待cpu调度,不会立马执行
就绪状态
当cpu调度后进入运行状态,这时候线程才开始运行
运行状态
线程由于某种原因,暂时放弃cpu使用权,停止执行,这是进入了阻塞状态,知道其状态重新进入了就绪状态,才有机会等待cpu调用重新进入运行状态
等待阻塞:调用wait方法使线程进入阻塞状态
同步阻塞:线程在获取synchronized同步锁失败,该锁正在被其他线程使用,他会进入同步阻塞状态
其他阻塞:线程调用sleep或者join或者发出IO请求,线程会进入阻塞状态,当sleep超时或者join等待线程终止或者IO请求结束,线程会重新进入就绪状态
阻塞原因有3种
阻塞状态
线程执行完或者异常退出run方法,线程死亡
死亡状态
线程的生命周期
启动一个线程调用的是start方法,虽然调用了,但是不会立即执行,他会等待Cpu调度,run方法使线程启动后回调的一个方法
启动一个线程是调用 run() 方法还是 start() 方法?
死锁是指因资源被多个线程竞争而导致相互等待,若无外力作用,这些线程无法推行
产生原因
线程队所分配的资源进行一个排他条件,在某个时间段内只允许一个线程执行,若有其他线程请求,则需要等待
互斥条件
线程所获得的资源在不使用完毕之前不允许其他线程请求,该资源只能让使用的线程自主释放
不剥夺条件
线程已获得资源的同时请求其他资源,而其他资源在被其他线程使用,此时请求被等待阻塞,当时已获得资源保持不释放
请求保和条件
循环等待条件
条件
线程按照一定的顺序枷锁
线程尝试获取锁的时候加上时限,如果超过规定的时限放弃请求,同时释放自己已占有的锁
怎么避免
什么情况下导致线程死锁,遇到线程死锁该怎么解决?
jdk1.5之前都是靠synchronized关键字保证同步的,使用synchronized可以确保无论哪个线程持有锁,都采用独有的方式占有资源,独占锁就是悲观锁,所以synchronized就是悲观锁
悲观锁
乐观锁就是假设数据一般情况下不会造成冲突,在数据提交更新的时候,才会对数据的冲突进行检测,如果发生冲突,则返回错误信息让用户自己决定如果处理
乐观锁
什么是乐观锁和悲观锁?
乐观锁只能保证一个变量的原子性
长时间自旋导致开销变大
解决思路是加入版本号,每次更新都把版本号+1
乐观锁避免了悲观锁独占对象的相像,同时也提高了性能,但是也有缺点
乐观锁一定就是好么
线程池刚创建的时候里面是没有线程的,任务队列作为参数传进来,就算队列里面存在任务,线程池也不会马上执行他们
如果正在运行的线程小于corePoolSize,则立马创建线程执行任务
如果正在运行的线程大于或者等于corePoolSize,线程池会将任务放入队列
如果这个时候队列满了,而且正在运行的数量小于maximumPoolSize,那么还是要创建线程运行这个任务
如果队列满了,而且正在运行的数量大于或者等于maximumPoolSize,那么线程池会抛出异常
当调用execute方法添加线程池,线程池会做如下判断
当一个线程运行完毕之后,他会从队列里面取任务去执行
当一个线程无事可做,超过一定的时间keepAliveTime,线程池会判断,如果当前运行的线程数大于CorePoolSize,那么这个线程会被停掉,所以所有线程执行完毕之后,线程池的大小会收缩到CorePoolSize大小
说一下线程池的启动策略?
使一个线程处于等待状态,并且释放持有的锁
是一个正在运行的线程处于休眠状态
唤醒一个处于等待状态的线程,有CPU去决定唤醒哪个
notify
唤醒所有等待的线程,该方法不是将对象的锁给所有线程,而是让他们竞争
nofityAll
Java5通过Look接口提供了显示锁机制,提供了look加锁和unlook解锁
请说出同步线程及线程调度相关的方法?
不是线程池默认不启动Worker,接受到请求的时候才启动
线程池中的线程是怎么创建的?是一开始就随着线程池的启动创建好的吗?
Java提供了volatile关键字来保证可见性。当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。主要的原理是使用了内存指令
volatile关键字的作用?
在volatile变量写操作的前面会加入一个Release屏障,然后在之后会加入一个Store屏障,这样就可以保证volatile写跟Release屏障之前的任何读写操作都不会指令重排,然后Store屏障保证了,写完数据之后,立马会执行flush处理器缓存的操作。在volatile变量读操作的前面会加入一个Load屏障,这样就可以保证对这个变量的读取时,如果被别的处理器修改过了,必须得从其他 处理器的高速缓存(或者主内存)中加载到自己本地高速缓存里,保证读到的是最新数据;在之后会加入一个Acquire屏障,禁止volatile读操作之后的任何读写操作会跟volatile读指令重排序。与volatie读写内存屏障对比一下,是类似的意思。Acquire屏障其实就是LoadLoad屏障 + LoadStore屏障,Release屏障其实就是StoreLoad屏障 + StoreStore屏障
说一下volatile关键字对原子性、可见性以及有序性的保证?
什么是CAS?
AQS,即AbstractQueuedSynchronizer,队列同步器,它是Java并发用来构建锁和其他同步组件的基础框架。同步组件对AQS的使用: AQS是一个抽象类,主是是以继承的方式使用。AQS本身是没有实现任何同步接口的,它仅仅只是定义了同步状态的获取和释放的方法来供自定义的同步组件的使用。查看源码可知,在java的同步组件中,AQS的子类(Sync等)一般是同步组件的静态内部类,即通过组合的方式使用。 抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch 它维护了一个volatile int state(代表共享资源)和一个FIFO(双向队列)线程等待队列(多线程争用资源被阻塞时会进入此队列)
什么是AQS?
Semaphore就是一个信号量,它的作用是限制某段代码块的并发数。 semaphore有一个构造函数,可以传入一个int型整数n,表示某段代码最多只有n个线程可以访问,如果超出了n,那么请等待,等到某个线程执行完毕这段代码块,下一个线程再进入。由此可以看出如果Semaphore构造函数中传入的int型整数n=1,相当于变成了一个synchronized了。
Semaphore是什么?
Synchronized是由JVM实现的一种实现互斥同步的方式,查看被Synchronized修饰过的程序块编译后的字节码,会发现,被Synchronized修饰过的程序块,在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。在虚拟机执行到monitorenter指令时,首先要尝试获取对象的锁:如果这个对象没有锁定,或者当前线程已经拥有了这个对象的锁,把锁的计数器+1;当执行monitorexit指令时,将锁计数器-1;当计数器为0时,锁就被释放了。如果获取对象失败了,那当前线程就要阻塞等待,直到对象锁被另外一个线程释放为止。Java中Synchronize通过在对象头设置标志,达到了获取锁和释放锁的目的。
Synchronized的原理是什么?
非公平主要表现在获取锁的行为上,并非是按照申请锁的时间前后给等待线程分配锁的,每当锁被释放后,任何一个线程都有机会竞争到锁,这样做的目的是为了提高执行性能,缺点是可能会产生线程饥饿现象。
为什么说Synchronized是非公平锁?
JVM对java的原生锁做了哪些优化?
Synchronized和 ReentrantLock的异同?
多线程
什么是IO流
输入流:InputStream
输出流:OutputStream
按照方向
可以从或向一个特定的地方(节点)读写数据。如FileReader
节点流
是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
处理流
实现功能
字节流继承于InputStream和OutputStream
字节流
字符流继承于InputStreamReader和OutputStreamWriter
字符流
按照处理数据的单位
java中有几种类型的流
字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。
字节流和字符流的区别?
字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。
字节流有了为什么还要有字符流?
这是在拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)
FileInputStream和FileOutputStream是什么?
Files. size():查看文件个数。Files. read():读取文件。Files. write():写入文件。Files. exists():检测文件路径是否存在。Files. createFile():创建文件。Files. createDirectory():创建文件夹。Files. delete():删除一个文件或目录。Files. copy():复制文件。Files. move():移动文件。
Files的常用方法都有哪些?
是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化:
将需要被序列化的类实现Serializable接口 ,该接口没有需要 实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj)方法就可以将参数为 obj的对象写出(即保存其状态),要恢复的话则用输入流。
序列化的实现:
什么是 java 序列化,如何实现 java 序列化?
在 java 中能够被序列化的类必须先实现Serializable接口,该接口没有任何抽象方法只是起到一个标记作用。
如何将一个 java 对象序列化到文件里?
实现 Cloneable 接口并重写 Object 类中的 clone()方法;
实现 Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用 Object 类的 clone方法克隆对象。让问题在编译的时候暴露出来总是好过把问题留到运行时
如何实现对象克隆?
基本IO流
同步阻塞式IO,服务端创建一个ServerSocket,然后客户端用一个Socket去连接那个ServerSocket,然后ServerSocket接收到一个Socket的连接请求就创建一个Socket和一个线程去跟那个Socket进行通信。
public class BioServer { public static void main(String[] args) { // 服务端开启一个端口进行监听 int port = 8080; ServerSocket serverSocket = null; //服务端 Socket socket; //客户端 InputStream in = null; OutputStream out = null; try { serverSocket = new ServerSocket(port); //通过构造函数创建ServerSocket,指定监听端口,如果端口合法且空闲,服务器就会监听成功 // 通过无限循环监听客户端连接,如果没有客户端接入,则会阻塞在accept操作 while (true) { System.out.println(\"Waiting for a new Socket to establish\" + \
什么是BIO?
同步非阻塞 包括Selector,这是多路复用器,selector会不断轮询注册的channel,如果某个channel上发生了读写事件,selector就会将这些channel获取出来,我们通过SelectionKey获取有读写事件的channel,就可以进行IO操作。一个Selector就通过一个线程,就可以轮询成千上万的channel,这就意味着你的服务端可以接入成千上万的客户端。
什么是NIO?
异步非阻塞 每个连接发送过来的请求,都会绑定一个buffer,然后通知操作系统去异步完成读,此时你的程序是会去干别的事儿的,等操作系统完成数据读取之后,就会回调你的接口,给你操作系统异步读完的数据。
什么是AIO?
把一个磁盘文件映射到内存里来,然后把映射到内存里来的数据通过socket发送出去 。有一种mmap技术,也就是内存映射,直接将磁盘文件数据映射到内核缓冲区,这个映射的过程是基于DMA引擎拷贝的,同时用户缓冲区是跟内核缓冲区共享一块映射数据的,建立共享映射之后,就不需要从内核缓冲区拷贝到用户缓冲区了。光是这一点,就可以避免一次拷贝,但是这个过程中还是会用户态切换到内核态去进行映射拷贝,接着再次从内核态切换到用户态, 建立用户缓冲区和内核缓冲区的映射 ,接着把数据通过Socket发送出去,还是要再次切换到内核态 ,接着直接把内核缓冲区里的数据拷贝到Socket缓冲区里去,然后再拷贝到网络协议引擎里,发送出去就可以了,最后切换回用户态 。减少一次拷贝,但是并不减少切换次数,一共是4次切换,3次拷贝
什么是epoll?
inux提供了sendfile,也就是零拷贝技术这个零拷贝技术,就是先从用户态切换到内核态,在内核态的状态下,把磁盘上的数据拷贝到内核缓冲区,同时从内核缓冲区拷贝一些 offset和length到Socket缓冲区;接着从内核态切换到用户态,从内核缓冲区直接把数据拷贝到网络协议引擎里去 同时从Socket缓冲区里拷贝一些offset和length到网络协议引擎里去,但是这个offset和length的量很少,几乎可以忽略 只要2次切换,2次拷贝
什么是零拷贝技术?
select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。epoll也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。
说一下select,poll,epoll的区别?
网络IO流
IO
在运行状态,对于任意一个类,都能获取这个类的所有属性和方法,对任意一个对象,都能调用它的任意属性和方法。这种动态获取的信息及动态调用对象的方法即为Java的反射。
说说你对 Java 中反射的理解?
在运行时判断一个类所具有的成员变量和方法在运行时判断任意一个对象所属的类在运行时构造一个类的对象在运行时调用任意一个对象的方法
反射能做什么?
class.forName和classLoader的区别?
区别:静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。动态代理是实现 JDK 里的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是你的业务类必须要实现接口,通过 Proxy 里的 newProxyInstance 得到代理对象。还有一种动态代理 CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的。使用场景:AOP 编程就是基于动态代理实现的,比如著名的 Spring 框架、Hibernate 框架等等都是动态代理的使用例子。
动静态代理的区别,什么场景使用?
1.根类加载器(Bootstrap) --C++写的 ,看不到源码2.扩展类加载器(Extension) --加载位置 :jre\\lib\\ext 中3.系统(应用)类加载器(System\\App) --加载位置 :classpath 中4.自定义加载器(必须继承 ClassLoader)
Java 的类加载器的种类都有哪些?
创建类的实例,也就是 new 一个对象访问某个类或接口的静态变量,或者对该静态变量赋值调用类的静态方法反射(Class.forName(\"com.hcx.load\"))初始化一个类的子类(会首先初始化子类的父类)JVM 启动时标明的启动类,即文件名和类名相同的那个类
类什么时候被初始化?
如果这个类还没有被加载和链接,那先进行加载和链接假如这个类存在直接父类,并且这个类还没有被初始化,那就初始化直接的父类(不适用于接口)加入类中存在初始化语句(如 static 变量和 static块),那就依次执行这些初始化语句。
在一个类加载器中,类只能初始化一次
类的初始化步骤?
类型.class,例如:String.class对象.getClass(),例如:\"hello\".getClass()Class.forName(),例如:Class.forName(\"java.lang.String\")
获得一个类对象有哪些方式?
反射
哪些区域可能会发生oom?
JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java中的类加载器是一个重要的Java运行时系统组件,它负责在运行时查找和装入类文件中的类。由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。最后JVM对类进行初始化,包括:①如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;②如果类中存在初始化语句,就依次执行这些初始化语句。类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从Java 2(JDK 1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。
JVM加载class原理?
Perm Space中保存的是加载class文件。
会引起OutOfMemory,出现异常可以设置 -XX:PermSize 的大小。
JDK 1.8后,字符串常量不存放在永久代,而是在堆内存中,JDK1.8以后没有永久代概念,而是用元空间替代,元空间不存在虚拟机中,二是使用本地内存。
元数据区存放的是什么?会oom吗?
大对象直接进入老年态
经过一次Minor GC,年龄+1,若年龄超过一定限制(15),则被晋升到老年态。即长期存活的对象进入老年态
对象如何晋升到老年代?
新生代中为什么要分为Eden和Survivor?
寄存器:无法控制。
静态域:static定义的静态成员。
非RAM存储:硬盘等永久存储空间。
说一下Java内存分配?
方法区:主要是存储类信息,常量池(static量和 static变量),编译后的代码(字节码)等数据
初始化的对象,成员变量(那种非 static的变量),所有的对象实例和数组都要在堆上分配
栈:栈的结构是栈帧组成的,调用一个方法就压入一帧,帧上面存储局部变量表,操作数栈,方法出口等信息,局部变量表存放的是8大基础类型加上一个引用类型,所以还是一个指向地址的指针
本地方法栈:主要为 Native方法服务
span style=\
总结:初始化的对象放在堆里面,引用放在栈里面,class类信息常量池(static常量和 static变量)等放在方法区
线程私有区(程序计数器、虚拟机栈、本地方法区)
线程共享区(Java堆、方法区)
直接内存
JVM内存区域主要分为:
说一下JVM内存模型及分区,每个区放什么?
JVM内存模型
Java 提供的GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显式操作方法。
System.gc()
算法思路:把所有的对象组成一个集合,或者可以理解为树状结构,从树根开始找,只要可以找到的都是活动对象,如果找不到就应该被回收了。
GC是什么? 为什么要有 GC?
程序计数器(Program Counter Register)
虚拟机栈(VM Stack)
本地方法栈(Native Method Stack)
方法区(Method Area)
堆(Heap)
内存运行时 JVM 会有一个运行时数据区来管理内存。它主要包括 5 大部分:
而其中程序计数器、虚拟机栈、本地方法栈是每个线程私有的内存空间,随线程而生,随线程而亡。例如栈中每一个栈帧中分配多少内存基本上在类结构确定是哪个时就已知了,因此这 3 个区域的内存分配和回收都是确定的,无需考虑内存回收的问题。但方法区和堆就不同了,一个接口的多个实现类需要的内存可能不一样,我们只有在程序运行期间才会知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC 主要关注的是这部分内存。
总结:GC 主要进行回收的内存是 JVM 中的方法区和堆
Java 的 GC 哪些内存需要回收?
Serial收集器:单线程的收集器,收集垃圾时,必须stop the world,使用复制算法。ParNew收集器:Serial收集器的多线程版本,也需要stop the world,复制算法。Parallel Scavenge收集器:新生代收集器,复制算法的收集器,并发的多线程收集器,目标是达到一个可控的吞吐量。如果虚拟机总共运行100分钟,其中垃圾花掉1分钟,吞吐量就是99%。Serial Old收集器:是Serial收集器的老年代版本,单线程收集器,使用标记整理算法。Parallel Old收集器:是Parallel Scavenge收集器的老年代版本,使用多线程,标记-整理算法。CMS(Concurrent Mark Sweep) 收集器:是一种以获得最短回收停顿时间为目标的收集器,标记清除算法,运作过程:初始标记,并发标记,重新标记,并发清除,收集结束会产生大量空间碎片。G1收集器:标记整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选标记。不会产生空间碎片,可以精确地控制停顿。
介绍一些常见的垃圾回收器
CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集器一起使用 ,G1收集器收集范围是老年代和新生代,不需要结合其他收集器使用。CMS收集器以最小的停顿时间为目标的收集器 ,G1收集器可预测垃圾回收的停顿时间。CMS收集器是使用“标记-清除”算法进行的垃圾回收,容易产生内存碎片,G1收集器使用的是“标记-整理”算法,进行了空间整合,降低了内存空间碎片。
CMS收集器和G1收集器的区别?
从根节点开始标记所有可达对象,其余没有标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。标记-清除算法采用从根集合进行扫描,对存活的对象标记,标记完毕后,在扫描整个空间中未被标记的对象,进行回收。标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片。
标记-清除算法
复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,这种算法当控件存活的对象比较少时,极为高效,但是带来的成本是需要一块内存交换空间进行对象的移动。也就是s0,s1等空间。
复制算法
标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时,在回收不存活的对象占用的空间后,会将所有的存活对象网左端空闲空间移动,并更新相应的指针。标记-整理算法是在标记-清除算法的基础上,又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。
标记-整理法
GC的收集方法有哪些?详细说一下每个的原理与特点?
对于堆中的对象,用可达性分析判断一个对象是否还存在引用,如果该对象没有任何引用就应该被回收。根据实际对引用的不同需求,分成了 4 种引用,每种引用的回收机制也是不同的。对于方法区中的常量和类,当一个常量没有任何对象引用它,它就可以被回收了。对于类,如果可以判定它为无用类,就可以被回收了。
Java 的 GC 什么时候回收垃圾?
1. 引用计数法
该算法的思想是:从一个被称为 GC Roots 的对象开始向下搜索,如果一个对象到 GCRoots 没有任何引用链相连时,则说明此对象不可用。在 java 中可以作为 GC Roots 的对象有以下几种:虚拟机栈中引用的对象方法区类静态属性引用的对象方法区常量池引用的对象本地方法栈 JNI 引用的对象虽然这些算法可以判定一个对象是否能被回收,但是当满足上述条件时,一个对象比不一定会被回收。当一个对象不可达 GC Root 时,这个对象并不会立马被回收,而是出于一个死缓的阶段,若要被真正的回收需要经历两次标记:如果对象在可达性分析中没有与 GC Root 的引用链,那么此时就会被第一次标记并且进行一次筛选,筛选的条件是是否有必要执行 finalize()方法。当对象没有覆盖 finalize()方法或者已被虚拟机调用过,那么就认为是没必要的。如果该对象有必要执行 finalize()方法,那么这个对象将会放在一个称为 F-Queue 的对队列中,虚拟机会触发一个 Finalize()线程去执行,此线程是低优先级的,并且虚拟机不会承诺一直等待它运行完,这是因为如果 finalize()执行缓慢或者发生了死锁,那么就会造成 F-Queue 队列一直等待,造成了内存回收系统的崩溃。GC 对处于 F-Queue 中的对象进行第二次被标记,这时,该对象将被移除”即将回收”集合,等待回收。
可达性算法(引用链法)
如何判断一个对象是否存活?
JVM之垃圾回收
JVM
javaSE
JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。JDBC接口及相关类在java.sql包和javax.sql包里。我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。
什么是JDBC?
Class.forName()加载数据库连接驱动;
DriverManager.getConnection()获取数据连接对象;
执行 SQL 处理结果集,执行 SQL 前如果有参数值就设置参数值 setXXX();
关闭结果集、关闭会话、关闭连接。
原生 JDBC操作数据库流程?
PreparedStatement 继承于 Statement,PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。作为Statement的子类 , PreparedStatement 继承了 Statement 的所有功能 。三 种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数Statement 一般用于执行固定的没有参数的SQLPreparedStatement 一般用于执行有 ?参数预编译的SQL语句。PreparedStatement支持?操作参数,相对于Statement更加灵活。PreparedStatement可以防止SQL注入,安全性高于Statement。
①代码的可读性和可维护性.Statement 需要不断地拼接,而 PreparedStatement 不会。②PreparedStatement 尽最大可能提高性能.DB 有缓存机制,相同的预编译语句再次被调用不会再次需要编译。③最重要的一点是极大地提高了安全性.Statement 容易被 SQL 注入,而PreparedStatementc 传入的内容不会和 sql 语句发生任何匹配关系。
JDBC中的Statement 和PreparedStatement的区别?
前提:为数据库连接建立一个缓冲池。
1:从连接池获取或创建可用连接
2:使用完毕之后,把连接返回给连接池
3:在系统关闭前,断开所有连接并释放连接占用的系统资源
4:能够处理无效连接,限制连接池中的连接总数不低于或者不超过某个限定值
关系数据库中连接池的机制是什么?
通过制定接口,数据库厂商来实现。我们只要通过接口调用即可。驱动只有在通过的Class.forName反射机制来加载的时候才会出现
JDBC是如何实现的Java程序和JDBC驱动的松耦合的?
ResultSet.TYPE_FORWARD_ONLY:这是默认的类型,它的游标只能往下移。ResultSet.TYPE_SCROLL_INSENSITIVE:游标可以上下移动,一旦它创建后,数据库里的数据再发生修改,对它来说是透明的。ResultSet.TYPE_SCROLL_SENSITIVE:游标可以上下移动,如果生成后数据库还发生了修改操作,它是能够感知到的。
一共有三种ResultSet对象。
ResultSet.CONCUR_READ_ONLY:ResultSet是只读的,这是默认类型。ResultSet.CONCUR_UPDATABLE:我们可以使用的ResultSet的更新方法来更新里面的数据。
ResultSet中有两种并发类型。
有哪些不同的结果集?
java.sql.SQLException:JDBC异常的基类。java.sql.BatchUpdateException:当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException中。java.sql.SQLWarning:SQL操作出现的警告信息。java.sql.DataTruncation:字段值由于某些非正常原因被截断了
常见的JDBC异常有哪些?
缓存PreparedStatement以便更快的执行可以设置连接超时时间提供日志记录的功能ResultSet大小的最大阈值设置通过JNDI的支持,可以为servlet容器提供连接池的功能
DataSource即数据源,它是定义在javax.sql中的一个接口,跟DriverManager相比,它的功能要更强大。我们可以用它来创建数据库连接,当然驱动的实现类会实际去完成这个工作。除了能创建连接外,它还提供了如下的特性:
JDBC的DataSource是什么,有什么好处?
execute可以用来执行任意SQL语句,返回一个boolean的值,表明该语句是否返回了一个结果集对象ResultSet。executeUpdate 用来执行修改,插入,删除操作,执行SELECT会抛出异常executeQuery只能进行SELECT,从而得到结果集对象,DELETE、UPDATE、INSERT操作都会抛出异常
通常我们不使用execute,如果你不知道要执行的SQL语句是什么类型的,就可以使用execute。
execute,executeQuery,executeUpdate的区别是什么?
p style=\
数据库连接池的原理。为什么要使用连接池?
JDBC的DriverManager是一个工厂类,我们通过它来创建数据库连接。当JDBC的Driver类被加载进来时,它会自己注册到DriverManager类里面,然后我们会把数据库配置信息传成DriverManager.getConnection()方法,DriverManager会使用注册到它里面的驱动来获取数据库连接,并返回给调用的程序。
JDBC的DriverManager是用来做什么的?
RowSet继承自ResultSet,因此它有ResultSet的全部功能,同时它自己添加了些额外的特性。RowSet一个最大的好处是它可以是离线的,这样使得它更轻量级,同时便于在网络间进行传输。
RowSet和ResultSet的区别?
JDBC
1、域名解析2、发起TCP的三次握手3、建立TCP连接后发起http请求4、服务器响应http请求,浏览器得到HTML代码5、浏览器解析HTML代码,并请求HTML代码中的资源6、浏览器对页面进行渲染呈现给用户7、连接结束
HTTP流程?
get重点是从服务器上获取资源get传输数据是通过URL请求,以field(字段) = value的形式,置于URL后,并用“?”连接,多个请求数据间用“&”连接get传输数据量小,因为受URL长度限制,但是效率高get是不安全的,因为URL是可见的,可能会泄漏私密信息get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码
GET:
post重点是向服务器发送数据。post传输数据是通过HTTP的post机制。将字段和对应值封存在请求实体中发送给服务器。这个过程用户是不可见的post可以传输大量数据,所以上传文件时只能用postpost支持标准字符集,可以正确传递中文字符post 较get安全性高
POST:
GET和POST的区别?
1xx:指示信息--表示请求已接收,继续处理2xx:成功--表示请求已被成功接收、理解、接受3xx:重定向--要完成请求必须进行更进一步的操作4xx:客户端错误--请求有语法错误或请求无法实现5xx:服务器端错误--服务器未能实现合法的请求
200:请求被正常处理204:请求被受理但没有资源可以返回206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。301:永久性重定向302:临时重定向303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上304:发送附带条件的请求时,条件不满足时返回,与重定向无关307:临时重定向,与302类似,只是强制要求使用POST方法400:请求报文语法有误,服务器无法识别401:请求需要认证403:请求的对应资源禁止被访问404:服务器无法找到对应资源500:服务器内部错误503:服务器正忙
常见的状态码:
HTTP常见的状态码有哪些?
转发是服务器行为重定向是客户端行为
本质区别:
两次请求,浏览器地址发生变化,可以访问自己 web 之外的资源,传输的数据会丢失。
重定向特点:
一次强求,浏览器地址不变,访问的是自己本身的 web 资源,传输的数据不会丢失。
请求转发特点:
HTTP中重定向和请求转发的区别?
HTTPS = HTTP + SSL
https有ca证书,http一般没有http是超文本传输协议,信息是明文传输。https则是具有安全性的ssl加密传输协议http默认80端口,https默认443端口
HTTP和HTTPS的区别?
二进制协议代替文本协议,更加简洁高效针对每个域只使用一个多路复用的连接压缩头部信息减小开销允许服务器主动推送应答到客户端的缓存中
HTTP/2 与 HTTP/1.x 的主要区别?
a、请求行:包含请求方法、URI、HTTP版本信息b、请求首部字段c、请求内容实体
请求报文:
a、状态行:包含HTTP版本、状态码、状态码的原因短语b、响应首部字段c、响应内容实体
响应报文:
HTTP请求报文与响应报文格式?
无状态协议对于事物处理没有记忆能力。缺少状态意味着后续的处理需要前面的信息。通过cookie和session解决
什么是HTTP协议无状态协议?怎么解决http协议无状态协议?
1、客户使用HTTPS的URL访问web服务器,要求与web服务器建立SSL连接2、web服务器收到客户端请求后,将网站的证书信息(证书中包含公钥)传送一份给客户端3、客户端的浏览器与web服务器开始协商SSL连接的安全等级,也就是信息的加密等级4、客户端的浏览器根据双方同意的安全等级,建立会话秘钥,然后利用网站的公钥将会话秘钥加密,并传送给网站5、web服务器利用自己的私钥解密出会话秘钥6、web服务器利用会话秘钥加密与客户端之间的通信
HTTPS方式与web服务器通信的步骤?
Date:创建报文时间Connection:连接的管理Cache-Control:缓存的控制Transfer-Encoding:报文主体的传输编码方式
通用首部字段(请求报文与响应报文都会使用的首部字段)
Host:请求资源所在服务器Accept:可处理的媒体类型Accept-Charset:可接收的字符集Accept-Encoding:可接受的内容编码Accept-Language:可接受的自然语言
请求首部字段(请求报文会使用的首部字段)
Accept-Ranges:可接受的字节范围Location:令客户端重新定向到的URIServer:HTTP服务器的安装信息
响应首部字段(响应报文会使用的首部字段)
Allow:资源可支持的HTTP方法Content-Type:实体主类的类型Content-Encoding:实体主体适用的编码方式Content-Language:实体主体的自然语言Content-Length:实体主体的的字节数Content-Range:实体主体的位置范围,一般用于发出部分请求时使用
实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)
说说常见的常见HTTP首部字段?
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境
注意:若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包
三次握手:
断开一个TCP连接则需要四次挥手
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手
四次挥手:
说说TCP传输的三次握手四次挥手策略
HTTP协议
HTTP Cookie(也叫 Web Cookie或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
什么是Cookie?
什么是 Session?
Cookie:是 web 服务器发送给浏览器的一块信息,浏览器会在本地一个文件中给每个 web 服务器存储 cookie。以后浏览器再给特定的 web 服务器发送请求时,同时会发送所有为该服务器存储的 cookie。
Session:是存储在 web 服务器端的一块信息。session 对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
①存在的位置cookie 存在于客户端,临时文件夹中; session存在于服务器的内存中,一个session域对象为一个用户浏览器服务②安全性cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放; session存放于服务器的内存中,所以安全性好③网络传输量cookie会传递消息给服务器; session本身存放于服务器,不会有传送流量④生命周期(以30分钟为例)cookie的生命周期是累计的,从创建时,就开始计时,30分钟后,cookie生命周期结束;session的生命周期是间隔的,从创建时,开始计时如在30分钟,没有访问session,那么session生命周期被销毁。但是,如果在30分钟内(如在第29分钟时)访问过session,那么,将重新计算session的生命周期。关机会造成session生命周期的结束,但是对cookie没有影响。⑤访问范围cookie为多个用户浏览器共享; session为一个用户浏览器独享
区别:
简单来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。
Cookie 和 Session 的区别?
当用户在某个网站注册后,就会收到一个唯一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。
如何利用实现自动登录?
1、调用request.getCookie2、对数组进行循环,调用每个cookie的getName方法
如何获取Cookie?
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识,称为session id;如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
说一下session的机制?
Cookie的过期和Session的超时(过期),都是对某个对象设置一个时间,然后采用轮训机制(或者首次访问时)检查当前对象是否超时(当前对象会保存一个开始时间),如果超时则进行移除。cookie保存在浏览器中,不安全。而session是保存在服务端的。cookie的生命周期很长,而session很短,一般也就几十分钟。cookie是保存在客户端,session保存在服务器端,cookie保存着session相关信息。如果cookie没有超时,那么浏览器每次请求都会带上该cookie信息,服务器端根据cookie信息从session缓存中获取相对应的session。这两个信息有一个超时,用户连接即宣告关闭。会话的超时由服务器来维护,它不同于Cookie的失效日期。首先,会话一般基于驻留内存的cookie,不是持续性的cookie,因而也就没有截至日期。即使截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。
Cookie的过期和Session的超时有什么区别?
Nginx ip_hash策略 ,服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。Session 复制,任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。共享 Session,服务端无状态话,将用户的 Session 等信息使用缓存中间件来统一管理,保障分发到每一个服务器的响应结果都一致。
如何解决分布式 Session 问题?
单点登录的原理是后端生成一个 session ID,然后设置到 cookie,后面的所有请求浏览器都会带上 cookie,然后服务端从 cookie 里获取 session ID,再查询到用户信息。所以,保持登录的关键不是 cookie,而是通过cookie 保存和传输的 session ID,其本质是能获取用户信息的数据。除了 cookie,还通常使用 HTTP 请求头来传输。但是这个请求头浏览器不会像 cookie 一样自动携带,需要手工处理。
在单点登录中,如果 cookie 被禁用了怎么办?
程序调用HttpSession.invalidate()距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间服务器进程被停止
session在下列情况下被删除:
session何时被删除?
Cookie/Session
Jsp 本质上就是一个 Servlet,它是 Servlet 的一种特殊形式(由 SUN 公司推出),每个 jsp 页面都是一个 servlet实例。Servlet 是由 Java 提供用于开发 web 服务器应用程序的一个组件,运行在服务端,由 servlet 容器管理,用来生成动态内容。一个 servlet 实例是实现了特殊接口 Servlet 的 Java 类,所有自定义的 servlet 均必须实现 Servlet 接口。
定义:
jsp 是 html 页面中内嵌的 Java 代码,侧重页面显示;Servlet 是 html 代码和 Java 代码分离,侧重逻辑控制,mvc 设计思想中 jsp 位于视图层,servlet 位于控制层
JVM 只能识别 Java 类,并不能识别 jsp 代码;web 容器收到以.jsp 为扩展名的 url 请求时,会将访问请求交给tomcat 中 jsp 引擎处理,每个 jsp 页面第一次被访问时,jsp 引擎将 jsp 代码解释为一个 servlet 源程序,接着编译servlet 源程序生成.class 文件,再由web 容器 servlet 引擎去装载执行 servlet 程序,实现页面交互。
Jsp 运行机制:
什么是 jsp?什么是Servlet?jsp 和Servlet 有什么区别?
pageContext page 域:指当前页面,在当前 jsp 页面有效,跳到其它页面失效request request 域:指一次请求范围内有效,从 http 请求到服务器处理结束,返回响应的整个过程。在这个过程中使用 forward(请求转发)方式跳转多个 jsp,在这些页面里你都可以使用这个变量session session 域:指当前会话有效范围,浏览器从打开到关闭过程中,转发、重定向均可以使用application context 域:指只能在同一个 web 中使用,服务器未关闭或者重启,数据就有效
jsp 有哪些域对象?
jsp有哪些内置对象?
<%…%>用于在JSP页面中嵌入Java脚本<%!…%>用于在JSP页面中申明变量或方法,可以在该页面中的<%…%>脚本中调用,声明的变量相当于Servlet中的定义的成员变量。
<%…%>和<%!…%>的区别?
forward是把另一个页面加载到本页面,不改变浏览器的路径redirect是跳转到另一个页面,会改变浏览器的路径
重定向: response.sendRedirect(\"重定向的路径\")转发: request.getRequestDispatcher(\"转发路径\").forward(request, response);
实现方式:
forward与redirect 的区别?有哪些方式实现?
1.JSP与Java Servlet一样,是在服务器端执行的,通常返回该客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览2.在大多数Browser/Server结构的Web应用中,浏览器直接通过HTML或者JSP的形式与用户交互,响应用户的请求3.JSP在服务器上执行,并将执行结果输出到客户端浏览器,我们可以说基本上与浏览器无关
浏览器与jsp,html之间的关系?
1、JSP页面显示乱码 <%@ page contentType=”text/html; charset=gb2312″%>2、表单提交中文时出现乱码request.seCharacterEncoding(\"gb2312″)对请求进行统一编码3、数据库连接出现乱码 要涉及中文的地方全部是乱码,解决办法:在数据库的数据库URL中加上useUnicode=true&characterEncoding=GBK就可以了。4、通过过滤器完成5、在server.xml中的设置编码格式
jsp乱码如何解决,给出对应解决方案
Servlet处于服务器进程中,只会有一个servlet实例,每个请求都会产生一个新的线程,而且servlet实例一般不会销毁CGI:来一个请求就创建一个进程,用完就销毁,效率低于servlet
Servlet和CGI的区别?
<%@ page session=\"false\" %>
如何避免jsp页面自动生成session对象?
当客户端向一个jsp页面发送请求时,Web Container将jsp转化成servlet的源代码(只在第一次请求时),然后编译转化后的servlet并加载到内存中执行,执行的结果response到客户端jsp只在第一次执行的时候会转化成servlet,以后每次执行,web容器都是直接执行编译后的servlet,所以jsp和servlet只是在第一次执行的时候不一样,jsp慢一点,以后的执行都是相同的。
JSP是如何被执行的?执行效率比SERVLET低吗?
JSP
依赖于servlet容器;在实现上基于函数回调,可以对几乎所有请求进行过滤;缺点是一个过滤器实例只能在容器初始化时调用一次;
用来做一些过滤操作,获取我们想要获取的数据;在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
strong style=\
什么是过滤器?
实现了javax.servlet.ServletContextListener 接口的服务器端程序;随web应用的启动而启动;只初始化一次;随web应用的停止而销毁;
做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。如SpringMVC的监听器org.springframework.web.context.ContextLoaderListener,实现了SpringMVC容器的加载、Bean对象创建、DispatchServlet初始化等。
作用:
什么是监听器?
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架;在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用;缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理;
什么是拦截器?
过滤器和拦截器的区别?
Filter是一种特别的Servlet,它们的作用是完全不一样的。Servlet是用来处理请求的Filter是用来过滤检查请求的
Servlet与Filter的区别?
用于配置Web应用的相关信息如:监听器(listener)、过滤器(filter)、 Servlet、相关参数、会话超时时间、安全验证方式、错误页面等。
web.xml 的作用?
启动服务器时加载过滤器的实例,并调用init()方法来初始化实例;每一次请求时都只调用方法doFilter()进行处理;停止服务器时调用destroy()方法,销毁实例。
需要实现javax.servlet包的Filter接口的三个方法init()、doFilter()、destroy()
filter的生命周期?
Filter/Listener
Git是分布式的,而SVN不是分布式的Git把内容按元数据方式存储,而SVN是按文件Git的内容的完整性要优于SVNSVN只能有一个指定中央版本库。而 Git可以有无限个版本库。
Git和SVN有什么区别?
管理方便,逻辑明确,符合一般人思维习惯。易于管理,集中式服务器更能保证安全性。代码一致性非常高。适合开发人数不多的项目开发。
优点:
服务器压力太大,数据库容量暴增。如果不能连接到服务器上,就不能提交,还原,对比等等。不适合开源开发。但是一般集中式管理的有非常明确的权限管理机制(例如分支访问限制),可以实现分层管理,从而很好的解决开发人数众多的问题。
缺点:
SVN优缺点?
适合分布式开发,强调个体。公共服务器压力和数据量都不会太大。速度快、灵活。任意两个开发者之间可以很容易的解决冲突。离线工作。
代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息。
Git优缺点?
Git branch test 创建test的branchGit checkout dev 切换到dev分支Git pull 远程分支拉到本地Git checkout -b main 创建并切换到main分支Git push origin main 推到远程分支
说一下Git创建分支的步骤?
这种合并方式是将两个分支的历史合并到一起,现在的分支不会被更改,它会比对双方不同的文件缓存下来,生成一个commit,去push。
Git Merge:
这种合并方法通常被称为“衍合”。他是提交修改历史,比对双方的commit,然后找出不同的去缓存,然后去push,修改commit历史。
Git ReBase:
说一下Git合并的两种方法以及区别?
使用git log命令
Git如何查看文件的提交历史和分支的提交历史?
用于临时保存和恢复修改,可跨分支。使用场景:写着代码,别人告诉我bug修好了,我就要去更新一下代码,如果更新冲突,应该把当前代码保存起来,此时可以使用git stash命令。命令的本质帮我们做了两件事:①把所有改动做了一个快照,然后保存起来,并还原原来的文件。②在需要的时候,可以把之前的修改恢复。
什么是 git stash?
删除保存的存储。
什么是git stash drop?
配置或读取相应的环境变量。这些环境变量,主要保存了 Git 在各个环节的具体工作方式和行为。位置:用户主目录的.gitconfig工作目录的.git下面的.gitconfig/etc/.gitconfig
git config 的作用?
控制版本工具
Maven是基于POM(工程对象模型),通过一小段描述来对项目的代码、报告、文件进管理的工具。Maven是一个跨平台的项目管理工具,它是使用java开发的,它要依赖于jdk1.6及以上Maven主要有两大功能:管理依赖、项目构建。(依赖指的是jar包)
什么是maven?
优点:简化了项目构建,依赖管理:易于上手便于与持续集成工具(Jenkins)整合便于项目升级,无论是项目本身升级还是项目使用的依赖升级。有助于多模块项目的开发,一个模块开发好后,发布到仓库,依赖该模块时可以直接从仓库更新,而不用自己去编译。maven有很多插件,便于功能扩展,比如生产站点,自动发布版本等
缺点:maven是一个庞大的构建系统,学习难度大。maven采用约定优于配置的策略(convention over configuration),虽然上手容易,但是一旦出了问题,难于调试。中国的网络环境差,很多repository无法访问,比如google code, jboss 仓库无法访问等。
maven优缺点?
maven常见的依赖范围有哪些?
groupId :定义当前 Maven 项目隶属的实际项目。artifactId :该元素定义当前实际项目中的一个 Maven 项目(模块)。推荐的做法是使用实际项目名称作为 artifactId 的前缀。比如上例中的 junit ,junit 就是实际的项目名称,方便而且直观。在默认情况下,Maven 生成的构件,会以 artifactId 作为文件头。例如 junit-3.8.1.jar ,使用实际项目名称作为前缀,就能方便的从本地仓库找到某个项目的构件。version :该元素定义了使用构件的版本。packaging :定义 Maven 项目打包的方式,使用构件的什么包。打包方式通常与所生成构件的文件扩展名对应。classifier :该元素用来帮助定义构建输出的一些附件。附属构件与主构件对应。
maven 坐标的含义?
mvn archetype:create :创建 Maven 项目。mvn compile :编译源代码。mvn deploy :发布项目。mvn test-compile :编译测试源代码。mvn test :运行应用程序中的单元测试。mvn site :生成项目相关信息的网站。mvn clean :清除项目目录中的生成结果。mvn package :根据项目生成的 jar/war 等。mvn install :在本地 Repository 中安装 jar 。mvn clean package -Dmaven.test.skip=true :清除以前的包后重新打包,跳过测试类。
maven 常用命令?
清理 ->编译 ->测试 ->报告 ->打包 ->部署
maven构建的过程?
Maven有三套相互独立的生命周期,分别是 Clean、Default 和 Site。每个生命周期包含一些阶段,阶段是有顺序的,后面的阶段依赖于前面的阶段。
Clean 生命周期:清理项目:pre-clean:执行清理前需要完成的工作。clean:清理上一次构建生成的文件。post-clean:执行清理后需要完成的工作
Default 生命周期:构建项目:validate:验证工程是否正确,所有需要的资源是否可用。compile:编译项目的源代码。test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。package:把已编译的代码打包成可发布的格式,比如 jar、war 等。integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。verify:运行所有检查,验证包是否有效且达到质量标准。install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
Site 生命周期:建立和发布项目站点:pre-site:生成项目站点之前需要完成的工作site:生成项目站点文档post-site:生成项目站点之后需要完成的工作site-deploy:将项目站点发布到服务器
各个生命周期相互独立,一个生命周期的阶段前后依赖。mvn clean :调用 Clean 生命周期的 clean 阶段,实际执行 pre-clean 和 clean 阶段mvn test :调用 Default 生命周期的 test 阶段,实际执行 test 以及之前所有阶段mvn clean install :调用 Clean 生命周期的 clean 阶段和 Default 生命周期 的 install 阶段,实际执行 pre-clean 和 clean ,install 以及之前所有阶段。
maven的生命周期?
使用清理插件:maven-clean-plugin执行清理删除已有target目录;使用资源插件:maven-resources-plugin执行资源文件的处理;使用编译插件:maven-compiler-plugin编译所有源文件生成class文件至target\\classes目录下;使用资源插件:maven-resources-plugin执行测试资源文件的处理;使用编译插件:maven-compiler-plugin编译测试目录下的所有源代码;使用插件:maven-surefire-plugin运行测试用例;
使用“mvn clean package”命令进行项目打包,该命令具体做了什么?
第一步,要找到 Maven 加载的到时是什么版本的 jar 包,通过mvn dependency:tree 查看依赖树,或者使用 IDEA Maven Helper 插件。第二步,通过 Maven 的依赖原则来调整坐标在 pom 文件的申明顺序是最好的办法,或者使用将冲突中不想要的 jar 引入的 jar删掉。
如何解决冲突?
依赖路径最短优先原则项目依赖了两个jar包,其中A-B-C-D , A-D。由于第二条路径最短,所以项目使用的是第二个D。
pom文件中申明顺序优先项目依赖了两个jar包,A-B-D ,A-C-D。maven会根据加载顺序。如果先申明了B,在申明了C,那么最后依赖就用A-C-D。
覆写优先子pom内声明的优先于父pom中的依赖。
maven依赖原则?
Maven仓库有2种本地仓库远程仓库
Maven 会先搜索本地仓库(repository),发现本地没有然后从远程仓库(中央仓库)获取。私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的 Maven 用户使用。当 Maven 需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为 Maven 的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上。
说一下maven仓库?
项目管理工具
创建型工厂模式与抽象工厂模式 (Factory Pattern)(Abstract Factory Pattern)单例模式 (Singleton Pattern)建造者模式 (Builder Pattern)原型模式 (Prototype Pattern)
结构型适配器模式 (Adapter Pattern)装饰器模式 (Decorator Pattern)桥接模式 (Bridge Pattern)外观模式 (Facade Pattern)代理模式 (Proxy Pattern)过滤器模式 (Filter、Criteria Pattern)组合模式 (Composite Pattern)享元模式 (Flyweight Pattern)
行为型责任链模式(Chain of Responsibility Pattern)观察者模式(Observer Pattern)模板模式(Template Pattern)命令模式(Command Pattern)解释器模式(Interpreter Pattern)迭代器模式(Iterator Pattern)中介者模式(Mediator Pattern)策略模式(Strategy Pattern)状态模式(State Pattern)备忘录模式(Memento Pattern)空对象模式(Null Object Pattern)
设计模式有哪些?
工厂模式适配器模式代理模式单例模式装饰器模板方法模式
JDK 类库常用的设计模式有哪些?
代理模式:在 AOP 中有使用单例模式:Bean 默认是单例模式模板方法模式:JdbcTemplate工厂模式:BeanFactory观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用,比如,ContextStartedEvent 就是 ApplicationContext 启动后触发的事件适配器模式:Spring MVC 中也是用到了适配器模式适配 Controller
Spring 中都使用了哪些设计模式?
单例模式重点在于在整个系统上共享一些创建时较耗资源的对象。整个应用中只维护一个特定类实例,它被所有组件共同使用。Java.lang.Runtime 是单例模式的经典例子。
静态内部类:JVM提供了同步控制功能:static final,利用JVM进行类加载的时候保证数据同步。在内部类中创建对象实例,只要应用中不使用内部类,JVM就不会去加载该类,就不会创建我们要创建的单例对象。
Java中什么叫单例设计模式?请用 Java 写出线程安全的单例模式
使用工厂模式最主要的好处是什么?在哪里使用?
观察者模式是定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式
优点观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色;观察者模式在观察目标和观察者之间建立一个抽象的耦合;观察者模式支持广播通信;观察者模式符合开闭原则(对拓展开放,对修改关闭)的要求。
缺点如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃;观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
什么是观察者设计模式(observer design pattern )?实现一个观察者设计模式。
设计模式
JavaWeb
tomcat是一个web应用服务器。比如,我们写的项目打包成war包以后需要放到tomcat指定的目录下。在启动tomcat就可以访问。
Tomcat是什么?
Tomcat缺省端口是8080;修改tomcat 端口:1、找到tomcat目录下的conf文件夹;2、进入conf文件夹找到server.xml文件3、在server.xml文件里面找到Connector 标签,把port=\"8080\",改成需求端口即可。
Tomcat缺省端口是多少,如何修改?
bio<Connector port=\"8080\" redirectPort=\"8443\" connectionTimeout=\"20000\" protocol=\"HTTP/1.1\"/>nio<Connector port=\"8080\" redirectPort=\"8443\" connectionTimeout=\"20000\" protocol=\"org.apache.coyte.http11.Http11NioPortocol\"/>aio<Connector port=\"8080\" redirectPort=\"8443\" connectionTimeout=\"20000\" protocol=\"org.apache.coyte.http11.Http11NioPortocol\"/>
Tomcat 有那几种Connector 运行模式?
Servlet(Servlet Applet),全称Java Servlert 。是用Java编写的服务器端程序。其主要功能在与交互式的浏览和修改数据,生成动态Web内容。狭义的servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet的类,一般情况下,人们将Servlet理解为后者。比如HttpServlet类继承自Servlet类,可以利用继承Http Servlet 来实现Http请求,当不是Http请求的时候,也可以定义其他形式的Servlet。
什么是Servlet?
Tomcat容器中通过web.xml加载所有的Servlet。用户在浏览器输入不同的地址,向Tomcat容器请求资源。Tomcat容器根据地址首先在容器内找到应用ServletTest。Tomcat容器再根据地址去web.xml找到相应的servlet地址。Tomcat容器根据找到的servlet地址去web.xml找到相应的Servlet类,并实例化。Tomcat容器实例化相应的Servlet,首先调用init方法。Tomcat容器实例化相应的Servlet,首先调用service方法处理用户请求,比如post或者是get。Servlet处理完成之后,先将数据给Tomcat容器,Tomcat容器再把处理结果给浏览器客户端。Tomcat容器调用servlet实例的destory方法销毁这个实例。
Servlet请求过程?
请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得2.Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应3.Engine获得请求localhost/项目/页面.jsp,匹配它所拥有的所有虚拟主机Host4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)5.localhost Host获得请求/项目/页面.jsp,匹配它所拥有的所有Context6.Host匹配到路径为/项目的Context(如果匹配不到就把该请求交给路径名为””的Context去处理)7.path=\"/项目\"的Context获得请求/页面.jsp,在它的mapping table中寻找对应的servlet8.Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类9.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法10.Context把执行完了之后的HttpServletResponse对象返回给Host11.Host把HttpServletResponse对象返回给Engine12.Engine把HttpServletResponse对象返回给Connector13.Connector把HttpServletResponse对象返回给客户browser
Tomcat执行流程?
1.直接把Web项目放在webapps下,Tomcat会自动将其部署2.在server.xml文件上配置<Context>\\节点,设置相关的属性即可3.通过Catalina来进行配置:进入到conf\\Catalina\\localhost文件下,创建一个xml文件,该文件的名字就是站点的名字。
Tomcat部署方式?
JBoss 是一个基于J2EE的开放源代码的应用服务器
什么是JBoss ?
默认端口为9990
在JBoss 7中访问管理控制台的默认端口是什么?
独立模式和域模式有什么区别?
<validate-on-match>和<background-validation>有什么区别?
.dodeploy –指示部署.deployed –表示文件已部署.pending –部署仍在等待中.undeployed-确认应用程序已取消部署.failed –由于某种原因部署失败.skipdeploy –指示JBoss忽略文件以进行自动部署
可用于标记文件部署的重要类型有哪些?
WAR – Web应用程序档案SAR –服务档案JAR – Java存档EAR –企业应用程序档案
JBoss中可以部署哪些文件类型?
Jetty是一个提供HTTP服务器、HTTP客户端和javax.servlet容器的开源项目
什么是Jetty?
首先启动设置到Server的Handler这些Handler将组成一个Handler链Server会启动链上所有的Handler启动Connector,打开端口,接受客户端请求。
Jetty启动过程?
架构Jetty的架构比Tomcat的更为简单 Jetty的架构是基于Handler来实现的,主要的扩展功能都可以用Handler来实现,扩展简单。Tomcat的架构是基于容器设计的,进行扩展是需要了解Tomcat的整体设计结构,不易扩展。性能Jetty和Tomcat性能方面差异不大 Jetty可以同时处理大量连接而且可以长时间保持连接,适合于web聊天应用等等。Jetty的架构简单,因此作为服务器,Jetty可以按需加载组件,减少不需要的组件,减少了服务器内存开销,从而提高服务器性能。Jetty默认采用NIO结束在处理I/O请求上更占优势,在处理静态资源时,性能较高处理能力Tomcat适合处理少数非常繁忙的链接,也就是说链接生命周期短的话,Tomcat的总体性能更高。Tomcat默认采用BIO处理I/O请求,在处理静态资源时,性能较差。其它Jetty的应用更加快速,修改简单,对新的Servlet规范的支持较好。Tomcat目前应用比较广泛,对JavaEE和Servlet的支持更加全面,很多特性会直接集成进来。
Jetty和Tomcat的区别?
Web应用服务器
JavaEE
java基础
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
什么是Spring MVC?
①用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet 捕获;②DispatcherServle 对请求 URL 进行解析,得到请求资源标识符(URL),然后根据该 URL 调用 HandlerMapping,将请求映射到处理器 HandlerExcutionChain;③DispatchServlet 根据获得 Handler 选择一个合适的 HandlerAdapter 适配器处理;④Handler 对数据处理完成以后将返回一个 ModelAndView()对象给 DisPatchServlet;⑤Handler 返回的 ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet 通过ViewResolver 试图解析器将逻辑视图转化为真正的视图 View;⑥DispatcherServle 通过 model 解析出 ModelAndView()中的参数进行解析最终展现出完整的 view 并返回给客户端;
SpringMVC 的工作原理?
1.前端控制器 DispatcherServlet作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。2.处理器映射器HandlerMapping作用:根据请求的URL来查找Handler3.处理器适配器HandlerAdapter注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。4.处理器Handler5.视图解析器 ViewResolver作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)6.视图ViewView是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
说说Spring MVC的几个重要组件?
@requestMapping 用于请求 url 映射。@RequestBody 注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。@ResponseBody 注解实现将 controller 方法返回对象转化为 json 响应给客户。@PathVariable URL 中占位符参数绑定到控制器处理方法的入参中
SpringMVC 常用注解都有哪些?
在 springmvc.xml 中通过开启 <mvc:annotation-driven>来实现注解处理器和适配器的开启。
如何开启注解处理器和适配器?
post 请求乱码:在 web.xml 里边配置一个 CharacterEncodingFilter 过滤器。设置为 utf-8。get 请求的乱码:两种方法:①修改 tomcat 配置文件添加编码与工程编码一致。②对参数进行重新编码 String userName = New String(Request.getParameter(\"userName\").getBytes(\"ISO8859-1\
如何解决 get 和 post 乱码问题?
1、转发:在返回值前面加\"forward:\"2、重定向:在返回值前面加\"redirect:\"
SpringMVC怎么样设定重定向和转发的?
将异常抛给Spring框架,由Spring框架来处理;我们只需要配置简单的异常处理器
Spring MVC是如何进行异常处理?
基于View框架的无缝集成,采用IOC便于测试典型的纯MVC架构,Struts是不完全基于MVC框架的
Spring MVC的优点?
springMVC
1、Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高2、MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集3、通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回
什么是Mybatis?
1.Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员编写Sql语句。2.Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。3.Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。
MyBatis与Hibernate有哪些不同?
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。解决:在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数一一对应。解决:Mybatis 自动将 java 对象映射至 sql 语句。对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如何能将数据库记录封装成 pojo 对象解决:Mybatis 自动将 sql 执行结果映射至 java 对象。
JDBC 编程有哪些不足之处,MyBatis 是如何解决这些问题的?
#{}是预编译处理,${}是字符串替换Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;Mybatis在处理${}时,就是把{}替换成变量的值。
使用#{}可以有效的防止SQL注入,提高系统安全性
#{}和${}的区别是什么?
使用resultMap
当实体类中的属性名和表中的字段名不一样如何解决?
Dao接口即Mapper接口。接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在Mybatis中,每一个select、insert、update、delete标签,都会被解析为一个MapperStatement对象。
通常一个Xml映射文件,都会写一个Dao接口与之对应,这个Dao接口的工作原理是什么?
Mybatis是如何进行分页的?分页插件的原理是什么?
1<insert id=\"xxx\" usegeneratedkeys=\"true\" keyproperty=\"id\">2 insert into xxxx (xxx) values (#{xxxx})3</insert>
如何获取自动生成的id?
1、对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数2、使用 @param 注解3、使用map封装参数
在mapper中如何传递多个参数?
mybatis有哪些动态标签?
1、Mapper接口方法名和mapper.xml中定义的每个sql的id相同2、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同3、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同4、Mapper.xml文件中的namespace即是mapper接口的类路径。
MyBatis的mapper接口调用时有那些限定?
介绍一下mybatis缓存?
Myabis
Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等。公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。
Spring 容器的主要核心是:
谈谈你对 Spring 的理解?
Spring 中的设计模式有哪些?
@Required:该注解应用于设值方法@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。@Qualifier:该注解和@Autowired 搭配使用,用于消除特定 bean 自动装配的歧义
Spring 的常用注解?
Bean 定义:在配置文件里面用来进行定义。Bean 初始化:有两种方式初始化:①在配置文件中通过指定 init-method 属性来完成②实现 org.springframwork.beans.factory.InitializingBean 接口Bean 调用:有三种方式可以得到 bean 实例,并进行调用Bean 销毁:销毁有两种方式①使用配置文件指定的 destroy-method 属性②实现 org.springframwork.bean.factory.DisposeableBean 接口
Spring bean 的生命周期?
编程式事务:在代码中硬编码。声明式事务:在配置文件中配置声明式事务又分为:①基于XML的声明式事务②基于注解的声明式事务
Spring 管理事务的方式?
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。
Spring的事务传播行为有哪些?
1、ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。2、ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个事务未提交的数据。3、ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。4、ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。5、ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。
Spring事务的隔离级别?
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过 SpringAOP 框架触发的代码段。
before:前置通知,在一个方法执行前被调用。after: 在方法执行之后调用的通知,无论方法执行是否成功。after-returning: 仅当方法成功完成后执行的通知。after-throwing: 在方法抛出异常退出时执行的通知。around: 在方法执行之前和之后调用的通知。
Spring 切面可以应用五种类型的通知:
Spring 的通知是什么?有哪几种类型?
Spring
用来简化spring应用的初始搭建以及开发过程,使用特定的方式来进行配置(properties或yml文件)创建独立的spring引用程序 main方法运行,嵌入的Tomcat 无需部署war文件,简化maven配置,自动配置spring添加对应功能starter自动化配置。
什么是SpringBoot?
1、SpringSpring最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就是 IOC 控制反转。当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。2、Spring MVC提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。3、Spring 和 SpringMVC 的问题在于需要配置大量的参数。4、Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
Spring Boot、Spring MVC 和 Spring 有什么区别?
1、@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。2、@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能。3、@ComponentScan:Spring组件扫描。
Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
1、面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的@Bean 方法等。2、减少或消除 XML 配置。基于依赖注入原则的外化配置的好处已被证明。但是,许多开发人员不希望在 XML 和 Java 之间来回切换。JavaConfig 为开发人员提供了一种纯 Java 方法来配置与 XML 配置概念相似的 Spring 容器。从技术角度来讲,只使用 JavaConfig 配置类来配置容器是可行的,但实际上很多人认为将JavaConfig 与 XML 混合匹配是理想的。3、类型安全和重构友好。JavaConfig 提供了一种类型安全的方法来配置 Spring容器。由于 Java 5.0 对泛型的支持,现在可以按类型而不是按名称检索 bean,不需要任何强制转换或基于字符串的查找。
什么是 JavaConfig?
YAML是一种人类可读的数据序列化语言。它通常用于配置文件。与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML文件就更加结构化,而且更少混淆。可以看出YAML具有分层配置数据。
什么是YAML?
1、Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application。2、application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。3、bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。4、bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。5、这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。6、bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖。7、boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载8、boostrap 里面的属性不能被覆盖
bootstrap.yml和application.yml有什么区别?
1、spring-boot-starter-web (嵌入tomcat和web开发需要servlet与jsp支持)2、spring-boot-starter-data-jpa (数据库支持)3、spring-boot-starter-data-redis (redis数据库支持)4、spring-boot-starter-data-solr (solr搜索应用框架支持)5、mybatis-spring-boot-starter (第三方的mybatis集成starter)
springboot常用的starter有哪些?
1、properties文件2、YAML文件3、系统环境变量4、命令行参数
Spring Boot 配置加载顺序?
@PropertySource@Value@Environment@ConfigurationPropertie
Spring Boot 有哪几种读取配置的方式?
SpringControllerAdvice提供了一种使用处理异常的非常有用的方法。通过实现一个 ControllerAdvice类,来处理控制器类抛出的所有异常。
如何使用Spring Boot实现异常处理?
使用DEV工具来实现。通过这种依赖关系,可以节省任何更改,嵌入式 tomcat将重新启动。使用Spring Boot有一个开发工具Dev Tools模块,可以重新加载 Spring Boot上的更改,而无需重新启动服务器。消除每次手动部署更改的需要。Spring Boot在发布它的第一个版本时没有这个功能。该模块将在生产环境中被禁用。它还提供H2数据库控制台以更好地测试应用程序。
如何重新加载 Spring Boot上的更改,而无需重新启动服务器?
Spring boot actuatorspring是启动框架中的重要功能之一。Spring boot监视器可访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 http url rest访问的REST端点来检查状态。
Spring Boot中的监视器是什么?
在 application.properties中指定端口serverport=8090。
如何在自定义端口上运行 Spring Boot应用程序?
1、通过app.addListeners注册进入2、初始化一个SpringApplicationRunListeners进行处理3、从spring.factories中读取监听器处理类EventPublishingRunListener4、通过createSpringFactoriesInstances创建监听器处理类实例5、调用监听器listeners.starting()的方法来启动。6、底层把事件处理交给线程池去处理
Spring Boot监听器流程?
1、调用prepareEnvironment方法去设置环境变量2、接下来有三个方法getOrCreateEnvironment,configureEnvironment,environmentPrepared3、getOrCreateEnvironment去初始化系统环境变量4、configureEnvironment去初始化命令行参数5、environmentPrepared当广播到来的时候调用onApplicationEnvironmentPreparedEvent方法去使用postProcessEnvironment方法load yml和properties变量
Spring Boot初始化环境变量流程?
1、调用run方法中的refreshContext方法2、用AbstractApplicationContext中的refresh方法3、委托给invokeBeanFactoryPostProcessors去处理调用链4、其中一个方法postProcessBeanDefinitionRegistry会去调用processConfigBeanDefinitions解析beandefinitions5、在processConfigBeanDefinitions中有一个parse方法,其中有componentScanParser.parse的方法,这个方法会扫描当前路径下所有Component组件
Spring Boot扫描流程?
默认情况下,所有敏感的HTTP端点都是安全的,只有具有 http ACTUATOR角色的用户才能访问它们。安全性是使用标准的 httpservletrequest. isuserinrole..isusernrole方法实施的。可以使用 management. security. enabled= false来禁用安全性。只有在执行机构端点在防火墙后访问时,才建议禁用安全性。
如何在 Spring Boot中禁用 Actuator端点安全性?
使用 spring--startersecurityboot--依赖项,并且必须添加安全配置。配置类将必须扩展 WebSecurityConfigurerAdapter并覆盖其方法。
如何实现 Spring Boot应用程序的安全性?
Spring Boot Batch提供可重用的函数,这些函数在处理大量记录时非常重要;包括日志/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更先进的技术服务和功能,通过优化和分区技术,可以实现极高批量和高性能批处理作业。简单以及复杂的大批量批处理作业可以高度可扩展的方式利用框架处理重要大量的信息。
什么是 Spring Batch?
SpringBoot
Spring Security
Dubbo 是一个分布式、高性能、透明化的 RPC 服务框架,提供服务自动注册、自动发现等高效服务治理方案。
Dubbo是什么?
接口服务层(Service):该层与业务逻辑相关,根据 provider 和 consumer 的业务设计对应的接口和实现配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为中心服务代理层(Proxy):服务接口透明代理,生成服务的客户端 Stub 和 服务端的 Skeleton,以 ServiceProxy 为中心,扩展接口为 ProxyFactory服务注册层(Registry):封装服务地址的注册和发现,以服务 URL 为中心,扩展接口为 RegistryFactory、Registry、RegistryService路由层(Cluster):封装多个提供者的路由和负载均衡,并桥接注册中心,以Invoker 为中心,扩展接口为 Cluster、Directory、Router和LoadBlancce监控层(Monitor):RPC调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory、Monitor和MonitorService远程调用层(Protocal):封装 RPC 调用,以 Invocation 和 Result 为中心,扩展接口为 Protocal、Invoker和Exporter信息交换层(Exchange):封装请求响应模式,同步转异步。以 Request 和 Response 为中心,扩展接口为 Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer网络传输层(Transport):抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为Channel、Transporter、Client、Server和Codec数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool
Dubbo 的整体架构设计有哪些分层?
dubbo://rmi://hessian://http://webservice://thrift://memcached://redis://rest://
Dubbo有哪些协议?
dubbo:service 服务提供者暴露服务配置dubbo:reference 服务消费者引用服务配置dubbo:protocol 服务提供者协议配置dubbo:registry 注册中心配置dubbo:monitor 监控中心配置dubbo:application 应用信息配置dubbo:module 模块信息配置dubbo:provider 服务提供者缺省值配置dubbo:consumer 服务消费者缺省值配置dubbo:method 方法级配置dubbo:argument 方法参数配置dubbo:parameter 选项参数配置dubbo:config-center 配置中心
Dubbo配置有哪些?
广播直连使用 zookeeper 注册中心
Dubbo 的连接方式有哪些?
1、ServiceConfig 类拿到对外提供服务的实际类 ref(如:HelloWorldImpl)2、通过 ProxyFactory 类的 getInvoker 方法使用 ref 生成一个 AbstractProxyInvoker 实例,到这一步就完成具体服务到 Invoker 的转化
ProxyFactory 是动态代理,用来创建 Invoker 对象,实现代理使用 JavassistProxyFactory和 JdkProxyFactory。Invoker 是一个服务对象实例,Dubbo 框架的实体域。它可以是一个本地的实现,一个远程的实现或一个集群的实现,可以向它发起 Invoker 调用。Protocol 是服务域,负责 Invoker 的生命周期管理,是 Invoker 暴露和引用的主要功能入口,对应该类的 export和 refer方法。Exporter 是根据不同协议暴露 Invoker 进行封装的类,它会根据不同的协议头进行识别(比如:registry://和 dubbo://),调用对应 XXXProtocol的 export()方法。
3、接下来就是 Invoker 转换到 Exporter 的过程:
说说Dubbo暴露过程?
1、随机模式。按权重设置随机概率。在一个截面上碰撞的概率较高,但调用越大分布越均匀2、轮询模式。按公约后的权重设置轮询比例。但存在响应慢的服务提供者会累积请求3、最少活跃调用数。响应快的提供者接受越多请求,响应慢的接受越少请求4、一致hash。根据服务提供者ip设置hash环,携带相同的参数总是发送的同一个服务提供者,若服务挂了,则会基于虚拟节点平摊到其他提供者上
Dubbo有哪些均衡负载的方法?
1、Failover Cluster:失败重试 当服务消费方调用服务提供者失败后自动切换到其他服务提供者服务器进行重试2、Failfast Cluster:快速失败 当服务消费方调用服务提供者失败后,立即报错,也就是只调用一次。通常这种模式用于非幂等性的写操作。3、Failsafe Cluster:失败安全 当服务消费者调用服务出现异常时,直接忽略异常。这种模式通常用于写入审计日志等操作。4、Failback Cluster:失败自动恢复 当服务消费端用服务出现异常后,在后台记录失败的请求,并按照一定的策略后期再进行重试。这种模式通常用于消息通知操作。5、Forking Cluster:并行调用 当消费方调用一个接口方法后,Dubbo Client会并行调用多个服务提供者的服务,只要一个成功即返回。这种模式通常用于实时性要求较高的读操作,但需要浪费更多服务资源6、Broadcast Cluster:广播调用 当消费者调用一个接口方法后,Dubbo Client会逐个调用所有服务提供者,任意一台调用异常则这次调用就标志失败。这种模式通常用于通知所有提供者更新缓存或日志等本地资源信息。
Dubbo有哪些集群容错方案?
jdk SPI SPI :全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。SPI是一种动态替换发现的机制, 比如有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。我们经常遇到的就是java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,mysql和postgresql都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。在jdk6里面引进的一个新的特性ServiceLoader,从官方的文档来说,它主要是用来装载一系列的service provider。而且ServiceLoader可以通过service provider的配置文件来装载指定的service provider。当服务的提供者,提供了服务接口的一种实现之后,我们只需要在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入
dubbo SPI:Dubbo对JDK SPI进行了扩展,对服务提供者配置文件中的内容进行了改造,由原来的提供者类的全限定名列表改成了KV形式的列表,这也导致了Dubbo中无法直接使用JDK ServiceLoader,所以,与之对应的,在Dubbo中有ExtensionLoader,ExtensionLoader是扩展点载入器,用于载入Dubbo中的各种可配置组件Duboo SPI可以根据接口类名和key值获取具体一个实现可以对扩展类实例的属性进行依赖注入,即IOC可以采用装饰器模式实现AOP功能
jdk SPI和dubbo SPI的区别?
Provider(提供者)绑定指定端口并启动服务指供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心注册中心根据消费者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存。Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用。Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer
Dubbo服务注册与发现的流程?
Dubbo中 zookeeper做注册中心,如果注册中心集群都挂掉,发布者和订阅者之间还能通信吗?
Dubbo
微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分为一组小的服务,每个服务运行在其独立的自己的进程中,服务之间相互协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API),每个服务都围绕着具体的业务进行构建,并且能够被独立的构建在生产环境、类生产环境等。另外,应避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储。
什么是微服务?
Eureka:服务注册与发现Zuul:服务网关Ribbon:客户端负载均衡Feign:声明性的Web服务客户端Hystrix:断路器Config:分布式统一配置管理等20几个框架,开源一直在更新
Spring Cloud由哪些组件组成?
服务调用方式:dubbo是 RPCspringcloud 是Rest Api注册中心:dubbo是 zookeeper;springcloud是 eureka,也可以是 zookeeper服务网关:dubbo本身没有实现,只能通过其他第三方技术整合;springcloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发;springcloud支持断路器,与git完美集成配置文件支持版本控制,事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。
Spring Cloud和 dubbo区别?
Eureka:服务注册中心(可以是一个集群),对外暴露自己的地址提供者:启动后向Eureka注册自己信息(地址,提供什么服务)消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态(每30s定时向EurekaServer发起请求)
Eureka的工作原理?
当一个服务未按时进行心跳续约时,在生产环境下,因为网络延迟等原因,此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。但是有可能会造成一些挂掉的服务被剔除有延迟。
说说Eureka的自我保护机制?
1、ZooKeeper中的节点服务挂了就要选举,在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的, 选举就是改微服务做了集群,必须有一台主其他的都是从。2、Eureka各个节点是平等关系,服务器挂了没关系,只要有一台Eureka就可以保证服务可用,数据都是最新的。如果查询到的数据并不是最新的,就是因为Eureka的自我保护模式导致的。3、Eureka本质上是一个工程,而ZooKeeper只是一个进程。4、Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper 一样使得整个注册系统瘫痪。5、ZooKeeper保证的是CP,Eureka保证的是AP
CAP:C:一致性Consistency (取舍:强一致性、单调一致性、会话一致性、最终一致性、弱一致性)A:可用性 AvailabilityP:分区容错性Partition tolerance
Eureka和ZooKeeper的区别?
zuul是对SpringCloud提供的成熟对的路由方案,他会根据请求的路径不同,网关会定位到指定的微服务,并代理请求到不同的微服务接口,他对外隐蔽了微服务的真正接口地址。三个重要概念: 动态路由表:Zuul支持Eureka路由,手动配置路由,这俩种都支持自动更新路由定位:根据请求路径,Zuul有自己的一套定位服务规则以及路由表达式匹配反向代理:客户端请求到路由网关,网关受理之后,在对目标发送请求,拿到响应之后在 给客户端
什么是zuul?
在Spring Cloud Netflix中,Zuul巧妙的整合了Eureka来实现面向服务的路由。实际上,API网关将自己注册到Eureka服务注册中心上,也会从注册中心获取所有服务以及它们的实例清单。在Eureka的帮助下,API网关已经维护了系统中所有serviceId与实例地址的映射关系。当有外部请求到达API网关的时候,根据请求的URL找到最匹配的path,API网关就可以知道要将该请求\"路由\"到哪个具体的serviceId上去。最终通过Ribbon的负载均衡策略实现请求的路由。
zuul的工作流程?
1.feign采用的是基于接口的注解2.feign整合了ribbon,具有负载均衡的能力3.整合了Hystrix,具有熔断的能力
什么是feign?
1、通过动态代理生成实现类2、根据接口类的注解生命规则,解析出底层的methodhandler3、拦截器负责对请求和返回进行包装和处理4、通过均衡负载http去访问远程服务
feign的工作流程?
什么是Hystrix?
1、构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数;2、执行命令,Hystrix提供了4种执行命令的方法;3、判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动;4、判断熔断器是否打开,如果打开,跳到第8步;5、判断线程池/队列/信号量是否已满,已满则跳到第8步;6、执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步;7、统计熔断器监控指标;8、走Fallback备用逻辑9、返回请求响应
Hystrix流程?
集群:注册多台 Eureka,把 SpringCloud服务互相注册,客户端从 Eureka获取信息时,按照 Eureka的顺序来访问。
Eureka怎么实现高可用?
run():过滤器的具体业务逻辑shouldFilter():判断过滤器是否有效filterOrder():过滤器执行顺序filterType():过滤器拦截位置
ZuulFilter常用有哪些方法?
通过path配置拦截请求,通过 Serviceld到配置中心获取转发的服务列表,zuul内部使用 Ribbon实现本地负载均衡和转发。
如何实现动态Zuul网关路由转发?
使用Nginx的 upstream设置Zuul服务集群,通过location拦截请求并转发到 upstream,默认使用轮询机制对Zuul集群发送请求。
Zuul网关如何搭建集群?
通俗易懂的理解:集群:是把一个的事情交给多个人去做,假如要做1000个产品给一个人做要10天,叫10个人做就是一天;负载均衡:用来控制集群,他把做的最多的人让他慢慢做休息会,把做的最少的人让他加量让他做多点。在计算中:负载平衡可以改善跨计算机计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布,负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载,使用多个组件进行负载平衡,而不是单个组件,可能会通过冗余来提高可靠性和可用性,负载平衡通常及专用软件或硬件,例如多层交换机或域名系统服务器进程。
负载平衡的意义什么?
服务降级底层是如何实现的?
Spring Cloud Bus就像个分布式执行器,用于扩展的 Spring Boot应用程序的配置文件,但也可以用作应用程序之间的通信通道。Spring Cloud Bus不能单独完成通信,需要配合MQ支持Spring Cloud Bus一般是配合Spring Cloud Config做配置中心的Spring Cloud config实时刷新也必须采用 SpringCloud Bus消息总线
什么是 Spring Cloud Bus?
发送端(endpoint)构造事件event,将其publish到context上下文中(spring cloud bus有一个父上下文,bootstrap),然后将事件发送到channel中(json串message),接收端从channel中获取到message,将message转为事件event,然后将event事件publish到context上下文中,最后接收端(Listener)收到event,调用服务进行处理。整个流程中,只有发送/接收端从context上下文中取事件和发送事件是需要我们在代码中明确写出来的,其它部分都由框架封装完成。
Spring Cloud Bus 原理?
springcloud config实时刷新采用 SpringCloud Bus消息总线
SpringCloud Config可以实现实时刷新吗?
熔断机制:是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。服务降级:一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值
什么是服务熔断?什么是服务降级?
雪崩效应是在大型互联网项目中,当某个服务发生宕机时,调用这个服务的其他服务也会发生宕机,大型项目的微服务之间的调用是互通的,这样就会将服务的不可用逐步扩大到各个其他服务中,从而使整个项目的服务宕机崩溃
什么是服务雪崩效应?
SprigCloud
ZooKeeper是一个开放源码的分布式协调服务,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。Zookeeper保证了如下分布式一致性特性:顺序一致性原子性单一视图可靠性实时性(最终一致性)客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理。对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后,请求才会返回成功。因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降。有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid。
ZooKeeper是什么?
ZooKeeper和dubbo的区别?
zk自带的 zkclientApache开源的 Curator
Zookeeper的java客户端都有哪些?
文件系统通知机制
ZooKeeper提供了什么?
说说ZooKeeper文件系统
ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。ZAB协议包括两种基本的模式:崩溃恢复和消息广播。当整个zookeeper集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式,首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行数据同步,当集群中超过半数机器与该Leader服务器完成数据同步之后,退出恢复模式进入消息广播模式,Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。
说说ZAB协议?
PERSISTENT-持久节点除非手动删除,否则节点一直存在于Zookeeper上EPHEMERAL-临时节点临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与zookeeper连接断开不一定会话失效),那么这个客户端创建的所有临时节点都会被移除。PERSISTENT_SEQUENTIAL-持久顺序节点基本特性同持久节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。EPHEMERAL_SEQUENTIAL-临时顺序节点基本特性同临时节点,增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。
Znode有哪些类型?
Zookeeper本身也是集群,推荐配置不少于3个服务器。Zookeeper自身也要保证当一个节点宕机时,其他节点会继续提供服务。如果是一个Follower宕机,还有2台服务器提供访问,因为Zookeeper上的数据是有多个副本的,数据并不会丢失;如果是一个Leader宕机,Zookeeper会选举出新的Leader。ZK集群的机制是只要超过半数的节点正常,集群就能正常提供服务。只有在ZK节点挂得太多,只剩一半或不到一半节点能工作,集群才失效。所以:3个节点的cluster可以挂掉1个节点(leader可以得到2票>1.5)2个节点的cluster不能挂掉任何1个节点(leader可以得到1票<=1)
Zookeeper节点宕机如何处理?
三种部署模式:单机部署:一台集群上运行集群部署:多台集群运行伪集群部署:一台集群启动多个 Zookeeper实例运行
Zookeeper有哪几种几种部署模式?
Zookeeper是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布和订阅。通过对 Zookeeper中丰富的数据节点进行交叉使用,配合 Watcher事件通知机制,可以非常方便的构建一系列分布式应用,会涉及的核心功能:数据发布/订阅负载均衡命名服务分布式协调/通知集群管理Master选举分布式锁分布式队列
Zookeeper的典型应用场景?
Zookeeper允许客户端向服务端的某个Znode注册个Watcher监听,当服务端的一些指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,客户端根据 Watcher通知状态和事件类型做出业务上的改变。工作机制:客户端注册 watcher服务端处理watcher客户端回调 watcher
说一下Zookeeper Watcher机制
1、客户端注册Watcher实现2、调用getData()/getChildren()/exist()三个API,传入Watcher对象3、标记请求request,封装Watcher到WatchRegistration4、封装成Packet对象,发服务端发送request5、收到服务端响应后,将Watcher注册到ZKWatcherManager中进行管理6、请求返回,完成注册。
客户端注册Watcher的流程?
1、服务端接收Watcher并存储接收到客户端请求,处理请求判断是否需要注册Watcher,需要的话将数据节点的节点路径和ServerCnxn(ServerCnxn代表一个客户端和服务端的连接,实现了Watcher的process接口,此时可以看成一个Watcher对象)存储在WatcherManager的WatchTable和watch2Paths中去。2、Watcher触发以服务端接收到 setData() 事务请求触发NodeDataChanged事件为例:封装WatchedEvent将通知状态(SyncConnected)、事件类型(NodeDataChanged)以及节点路径封装成一个WatchedEvent对象查询Watcher从WatchTable中根据节点路径查找Watcher没找到;说明没有客户端在该数据节点上注册过Watcher找到;提取并从WatchTable和Watch2Paths中删除对应Watcher(从这里可以看出Watcher在服务端是一次性的,触发一次就失效了)3、调用process方法来触发Watcher这里process主要就是通过ServerCnxn对应的TCP连接发送Watcher事件通知。
服务端处理Watcher的流程?
1、客户端SendThread线程接收事件通知,交由 EventThread线程回调 Watcher。2、客户端的Watcher机制同样是一次性的,一旦被触发后,该 Watcher就失效了。
客户端回调 Watcher流程?
不是永久的。官方声明:一个 Watch事件是一个次性的触发器,当被设置了 Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch的客户端,以便通知它们。原因:如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,给网络和服务器造成很大压力。一般是客户端执行getData(“/节点”,true),如果节点A发生了变更或删除,客户端会得到它的 watch事件,但是在之后节点A又发生了变更,而客户端又没有设置 watch事件,就不再给客户端发送。
Zookeeper对节点的 watch监听通知是永久的吗?为什么不是永久的?
1、权限模式(Scheme)IP:从IP地址粒度进行权限控制Digest:最常用,用类似于 username:password 的权限标识来进行权限配置,便于区分不同应用来进行权限控制World:最开放的权限控制方式,是一种特殊的digest模式,只有一个权限标识“world:anyone”Super:超级用户2、授权对象授权对象指的是权限赋予的用户或一个指定实体,例如IP地址或是机器灯。3、权限 PermissionCREATE:数据节点创建权限,允许授权对象在该Znode下创建子节点DELETE:子节点删除权限,允许授权对象删除该数据节点的子节点READ:数据节点的读取权限,允许授权对象访问该数据节点并读取其数据内容或子节点列表等WRITE:数据节点更新权限,允许授权对象对该数据节点进行更新操作ADMIN:数据节点管理权限,允许授权对象对该数据节点进行ACL相关设置操作
说说ACL权限控制机制
1、Leader事务请求的唯一调度和处理者,保证集群事务处理的顺序性集群内部各服务的调度者2、Follower处理客户端的非事务请求,转发事务请求给Leader服务器参与事务请求Proposal的投票参与Leader选举投票3、Observer处理客户端的非事务请求,转发事务请求给Leader服务器不参与任何形式的投票
服务器有哪些角色?
1、LOOKING:寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举状态。2、FOLLOWING:跟随者状态。表明当前服务器角色是Follower。3、LEADING:领导者状态。表明当前服务器角色是Leader。4、OBSERVING:观察者状态。表明当前服务器角色是Observer。
Zookeeper 下 Server工作状态有哪些?
其实就是水平扩容,Zookeeper在这方面不太好。两种方式:全部重启:关闭所有 Zookeeper服务,修改配置之后启动。不影响之前客户端的会话。逐个重启:在过半存活即可用的原则下一台机器重启不影响整个集群对外提供服务。(这是比较常用的方式)
集群支持动态添加机器吗?
3.2.0版本后,添加了该特性,该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot,那么该客户端对服务器的任何操作,都将会被限制在其自己的命名空间下。
什么是Chroot?
Zookeeper
主流框架
1、from 子句组装来自不同数据源的数据;2、where 子句基于指定的条件对记录行进行筛选;3、group by 子句将数据划分为多个分组;4、使用聚集函数进行计算;5、使用 having 子句筛选分组;6、计算所有的表达式;7、select 的字段;8、使用 order by 对结果集进行排序。
SQL 的 select 语句完整的执行顺序?
外连接:左连接(左外连接):以左表作为基准进行查询,左表数据会全部显示出来,右表如果和左表匹配的数据则显示相应字段的数据,如果不匹配则显示为 null。右连接(右外连接):以右表作为基准进行查询,右表数据会全部显示出来,左表如果和右表匹配的数据则显示相应字段的数据,如果不匹配则显示为 null。全连接:先以左表进行左外连接,再以右表进行右外连接内连接:显示表之间有连接匹配的所有行。
左连接和右连接的区别?
sql注入通过在 Web 表单中输入(恶意)SQL 语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行 SQL 语句。举例:当执行的 sql 为 select * from user where username = \"admin\" or \"a\"=\"a\"时,sql 语句恒成立,参数 admin 毫无意义。防止 sql 注入的方式:预编译语句:如,select * from user where username = ?,sql 语句语义不会发生改变,sql 语句中变量用?表示,即使传递参数时为\"admin or 'a'= 'a'\",也会把这整体当做一个字符创去查询。Mybatis 框架中的 mapper 方式中的 # 也能很大程度的防止 sql 注入($无法防止 sql 注入)。
什么是sql注入?如何防止sql注入?
1、当只要一行数据时使用 limit 1查询时如果已知会得到一条数据,这种情况下加上 limit 1 会增加性能。因为 mysql 数据库引擎会在找到一条结果停止搜索,而不是继续查询下一条是否符合标准直到所有记录查询完毕。2、选择正确的数据库引擎Mysql 中有两个引擎 MyISAM 和 InnoDB,每个引擎有利有弊。MyISAM 适用于一些大量查询的应用,但对于有大量写功能的应用不是很好。甚至你只需要update 一个字段整个表都会被锁起来。而别的进程就算是读操作也不行要等到当前 update 操作完成之后才能继续进行。另外,MyISAM 对于 select count(*)这类操作是超级快的。InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用会比 MyISAM 还慢,但是支持“行锁”,所以在写操作比较多的时候会比较优秀。并且,它支持很多的高级应用,例如:事务。3、用 not exists 代替 not inNot exists 用到了连接能够发挥已经建立好的索引的作用,not in 不能使用索引。Not in 是最慢的方式要同每条记录比较,在数据量比较大的操作时不建议使用这种方式。4、对操作符的优化,尽量不采用不利于索引的操作符如:in not in is null is not null <>等某个字段总要拿来搜索,为其建立索引:Mysql 中使用 alter table 语句来为表中的字段添加索引:alter table 表明 add index (字段名);
有哪些sql优化方法?
1.InnoDB 存储引擎InnoDB 是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键,InnoDB 是默认的MySQL引擎。2.MyISAM 存储引擎MyISAM 基于 ISAM 存储引擎,并对其进行扩展。它是在 Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事物。3.MEMORY 存储引擎MEMORY 存储引擎将表中的数据存储到内存中,未查询和引用其他表数据提供快速访问。4.NDB 存储引擎DB 存储引擎是一个集群存储引擎,类似于 Oracle 的 RAC,但它是 Share Nothing 的架构,因此能提供更高级别的高可用性和可扩展性。NDB 的特点是数据全部放在内存中,因此通过主键查找非常快。关于 NDB,有一个问题需要注意,它的连接(join)操作是在 MySQL 数据库层完成,不是在存储引擎层完成,这意味着,复杂的 join 操作需要巨大的网络开销,查询速度会很慢。5.Memory (Heap) 存储引擎Memory 存储引擎(之前称为 Heap)将表中数据存放在内存中,如果数据库重启或崩溃,数据丢失,因此它非常适合存储临时数据。6.Archive 存储引擎正如其名称所示,Archive 非常适合存储归档数据,如日志信息。它只支持 INSERT 和 SELECT 操作,其设计的主要目的是提供高速的插入和压缩功能。7.Federated 存储引擎Federated 存储引擎不存放数据,它至少指向一台远程 MySQL 数据库服务器上的表,非常类似于 Oracle 的透明网关。8.Maria 存储引擎Maria 存储引擎是新开发的引擎,其设计目标是用来取代原有的 MyISAM 存储引擎,从而成为 MySQL 默认的存储引擎。
Mysql 存储引擎有哪些?
数据库事务 transanction 正确执行的四个基本要素。ACID,原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
事务的四大特征是什么?
MySQL 索引的“使用”要注意什么?
1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引。如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引。如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。2、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上,这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放。因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)3、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。4、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
为什么mysql建议使用自增主键?
该隔离级别是 MySQL 默认的隔离级别,在同一个事务里,select 的结果是事务开始时时间点的状态,因此,同样的 select 操作读到的结果会是一致的,但是,会有幻读现象。MySQL 的 InnoDB 引擎可以通过 next-key locks 机制来避免幻读。InnoDB 存储引擎使用三种行锁的算法用来满足相关事务隔离级别的要求:Record Locks该锁为索引记录上的锁,如果表中没有定义索引,InnoDB 会默认为该表创建一个隐藏的聚簇索引,并使用该索引锁定记录。Gap Locks该锁会锁定一个范围,但是不括记录本身。可以通过修改隔离级别为 READ COMMITTED 或者配置 innodb_locks_unsafe_for_binlog 参数为 ON。Next-key Locks该锁就是 Record Locks 和 Gap Locks 的组合,即锁定一个范围并且锁定该记录本身。InnoDB 使用 Next-key Locks 解决幻读问题。需要注意的是,如果索引有唯一属性,则 InnnoDB 会自动将 Next-key Locks 降级为 Record Locks
mysql rr级别如何解决幻读问题?
1、Master 上面的 binlog dump 线程,该线程负责将 master 的 binlog event 传到 slave。2、Slave 上面的 IO 线程,该线程负责接收 Master 传过来的 binlog,并写入 relay log 。3、Slave 上面的 SQL 线程,该线程负责读取 relay log 并执行。4、如果是多线程复制,无论是 5.6 库级别的假多线程还是 MariaDB 或者 5.7 的真正的多线程复制, SQL 线程只做 coordinator ,只负责把 relay log 中的 binlog 读出来然后交给 worker 线程, woker 线程负责具体 binlog event 的执行。
MySQL 主从复制的流程是怎么样的?
1、InnoDB支持事务,MyISAM不支持对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;2、InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;3、InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。4、InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;5、Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;表并优化填充页面。
Mysql 中 MyISAM 和 InnoDB 的区别有哪些?
Read Uncommitted(读取未提交内容)在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。Read Committed(读取提交内容)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。Repeatable Read(可重读)这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。Serializable(可串行化)这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
mysql事务隔离级别?
mvcc根据undo log来实现RR级别下,事务中的第一个SELECT请求才开始创建read view;RC级别下,事务中每次SELECT请求都会重新创建read view;ReadView 中是当前活跃的事务 ID 列表,称之为 m_ids,其中最小值为 up_limit_id,最大值为 low_limit_id,事务 ID 是事务开启时 InnoDB 分配的,其大小决定了事务开启的先后顺序,因此我们可以通过 ID 的大小关系来决定版本记录的可见性,具体判断流程如下:如果被访问版本的 trx_id 小于 m_ids 中的最小值 up_limit_id,说明生成该版本的事务在 ReadView 生成前就已经提交了,所以该版本可以被当前事务访问。如果被访问版本的 trx_id 大于 m_ids 列表中的最大值 low_limit_id,说明生成该版本的事务在生成 ReadView 后才生成,所以该版本不可以被当前事务访问。需要根据 Undo Log 链找到前一个版本,然后根据该版本的 DB_TRX_ID 重新判断可见性。如果被访问版本的 trx_id 属性值在 m_ids 列表中最大值和最小值之间(包含),那就需要判断一下 trx_id 的值是不是在 m_ids 列表中。如果在,说明创建 ReadView 时生成该版本所属事务还是活跃的,因此该版本不可以被访问,需要查找 Undo Log 链得到上一个版本,然后根据该版本的 DB_TRX_ID 再从头计算一次可见性;如果不在,说明创建 ReadView 时生成该版本的事务已经被提交,该版本可以被访问。此时经过一系列判断我们已经得到了这条记录相对 ReadView 来说的可见结果。此时,如果这条记录的 delete_flag 为 true,说明这条记录已被删除,不返回。否则说明此记录可以安全返回给客户端。
MVCC的流程?
1、有一个参数是innodb_read_ahead_threshold,他的默认值是56,意思就是如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,此时就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去2、如果Buffer Pool里缓存了一个区里的13个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会 直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去 这个机制是通过参数innodb_random_read_ahead来控制的,他默认是OFF,也就是这个规则是关闭的3、全表扫描
mysql什么时候会出现数据页预读?
statement,statement模式下,记录单元为语句。即每一个sql造成的影响会记录。由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。row,row级别下,记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。mixed,一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。
mysql有哪些binlog录入格式?
Mysql
存储过程(Stored Procedure )是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。优点:允许模块化程序设计,就是说只需要创建一次过程,以后在程序中就可以调用该过程任意次。允许更快执行,如果某操作需要执行大量 SQL 语句或重复执行,存储过程比 SQL 语句执行的要快。减少网络流量,例如一个需要数百行的 SQL 代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。好的安全机制,对于没有权限执行存储过程的用户,也可授权他们执行存储过程。
什么是存储过程,使用存储过程的好处?
存储过程创建语法:create or replace procedure 存储过程名(param1 in type,param2 out type)as变量 1 类型(值范围);变量 2 类型(值范围);Begin Select count(*) into 变量 1 from 表 A where 列名=param1; If (判断条件) then Select 列名 into 变量 2 from 表 A where 列名=param1; Dbms_output Put_line(‘打印信息’); Elsif (判断条件) then Dbms_output Put_line(‘打印信息’); Else Raise 异常名(NO_DATA_FOUND); End if;Exception When others then Rollback;End;
注意事项:存储过程参数不带取值范围,in 表示传入,out 表示输出变量带取值范围,后面接分号在判断语句前最好先用 count(*)函数判断是否存在该条操作记录用 select …into…给变量赋值在代码中抛异常用 raise+异常名
Oracle 存储过程怎么创建?
Oracle 中使用 rownum 来进行分页,这个是效率最好的分页方法,hibernate 也是使用 rownum 来进行 Oralce分页的
Oracle 中是如何进行分页查询的?
1、可以理解函数是存储过程的一种2、函数可以没有参数,但是一定需要一个返回值;存储过程可以没有参数,不需要返回值3、函数return返回值没有返回参数模式,存储过程通过out参数返回值,如果需要返回多个参数则建议使用存储过程4、在sql数据操纵语句中只能调用函数而不能调用存储过程
Oracle中function和procedure的区别?
使用 || 符号连接字符串, 如 'abc' || 'd' 的结果是 abcd。
Oracle 中字符串用什么连接?
特点:一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。对于存储过程来说可以返回参数,而函数只能返回值或者表对象。存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于 FROM 关键字的后面。区别:函数必须有返回值;而过程没有函数可以单独执行;而过程必须通过 execute 执行函数可以嵌入到 SQL 语句中执行;而过程不行
存储过程和存储函数的特点和区别?
Oracle 中的游标分为显示游标和隐式游标显示游标:显示游标是用 cursor...is 命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;显式游标的操作:打开游标、操作游标、关闭游标;隐式游标:隐式游标是在执行插入 (insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由 PL/SQL 自动定义的。PL/SQL 隐式地打开 SQL 游标,并在它内部处理 SQL语句,然后关闭它。
如何使用 Oracle 的游标?
触发器可通过数据库中的相关表实现级联更改;通过级联引用完整性约束可以更有效地执行这些更改。触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。与 CHECK 约束不同,触发器可以引用其它表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或显示用户定义错误信息。触发器还可以强制执行业务规则触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
触发器的作用有哪些?
Oracle 能存储 clob、nclob、 blob、 bfileClob 可变长度的字符型数据,也就是其他数据库中提到的文本型数据类型Nclob 可变字符类型的数据,不过其存储的是Unicode字符集的字符数据Blob 可变长度的二进制数据Bfile 数据库外面存储的可变二进制数据
Oralce怎样存储文件,能够存储哪些文件?
Oracle的分区可以分为:列表分区、范围分区、散列分区、复合分区。1、增强可用性:如果表的一个分区由于系统故障而不能使用,表的其余好的分区仍可以使用;2、减少关闭时间:如果系统故障只影响表的一部份分区,那么只有这部份分区需要修复,可能比整个大表修复花的时间更少;3、维护轻松:如果需要得建表,独产管理每个公区比管理单个大表要轻松得多;4、均衡I/O:可以把表的不同分区分配到不同的磁盘来平衡I/O改善性能;5、改善性能:对大表的查询、增加、修改等操作可以分解到表的不同分区来并行执行,可使运行速度更快6、分区对用户透明,最终用户感觉不到分区的存在。
Oracle分区是怎样优化数据库的?
数据库设计方面:1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null 可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,然后这样查询:select id from t where num=03.并不是所有索引对查询都有效,SQL 是根据表中数据来进行查询优化的,当索引列有大量数据重复时,查询可能不会去利用索引,如一表中有字段 sex,male、female 几乎各一半,那么即使在 sex 上建了索引也对查询效率起不了作用。4.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过 6 个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。5.应尽可能的避免更新索引数据列,因为索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新索引数据列,那么需要考虑是否应将该索引建为索引。6.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。7.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。8.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。9.避免频繁创建和删除临时表,以减少系统表资源的消耗。10.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。11.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先 create table,然后 insert。12.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
java 方面:1.尽可能的少造对象。2.合理摆正系统设计的位置。大量数据操作,和少量数据操作一定是分开的。大量的数据操作,肯定不是 ORM框架搞定的。3.使用 JDBC 链接数据库操作数据4.控制好内存,让数据流起来,而不是全部读到内存再处理,而是边读取边处理;5.合理利用内存,有的数据要缓存
其他方面:1.Oracle的运行环境(网络,硬件等)2.使用合适的优化器3.合理配置oracle实例参数4.建立合适的索引(减少IO)5.将索引数据和表数据分开在不同的表空间上(降低IO冲突)6.建立表分区,将数据分别存储在不同的分区上(以空间换取时间,减少IO)
在千万级的数据库查询中,如何提高效率?
冷备份发生在数据库已经正常关闭的情况下,将关键性文件拷贝到另外位置的一种说法热备份是在数据库运行的情况下,采用归档方式备份数据的方法冷备的优点:是非常快速的备份方法(只需拷贝文件)容易归档(简单拷贝即可)容易恢复到某个时间点上(只需将文件再拷贝回去)能与归档方法相结合,作数据库“最新状态”的恢复。低度维护,高度安全。冷备份缺点:单独使用时,只能提供到“某一时间点上”的恢复。在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。不能按表或按用户恢复。
解释冷备份和热备份的不同点以及各自的优点?
1、data block 数据块,是oracle最小的逻辑单位,通常oracle从磁盘读写的就是块2、extent 区,是由若干个相邻的block组成3、segment段,是有一组区组成4、tablespace表空间,数据库中数据逻辑存储的地方,一个tablespace可以包含多个数据文件
Oracle
String常规的set/get操作,value可以是String也可以是数字。应用:一般做一些复杂的计数功能的缓存。hash这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。应用:单点登录,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。listList的数据结构应用:可以做简单的消息队列的功能。另外,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。生产者和消费者的场景,LIST可以很好的完成排队,先进先出的原则。set因为set堆放的是一堆不重复值的集合。应用:可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。sorted setsorted set多了一个权重参数score,集合中的元素能够按score进行排列。应用:可以做排行榜应用,取TOP N操作。
redis的数据类型有哪些?
dict本质上是为了解决算法中的查找问题(Searching)是一个用于维护key和value映射关系的数据结构,与很多语言中的Map或dictionary类似。本质上是为了解决算法中的查找问题(Searching)。sdssds就等同于char * 它可以存储任意二进制数据,不能像C语言字符串那样以字符’\\0’来标识字符串的结束,因此它必然有个长度字段。skiplist 跳跃表跳表是一种实现起来很简单,单层多指针的链表,它查找效率很高,堪比优化过的二叉平衡树,且比平衡树的实现。ziplist 压缩表ziplist是一个编码后的列表,是由一系列特殊编码的连续内存块组成的顺序型数据结构。
Redis 内部结构有哪些?
存储方式不同:Memcache 是把数据全部存在内存中,数据不能超过内存的大小,断电后数据库会挂掉。Redis 有部分存在硬盘上,这样能保证数据的持久性。数据支持的类型不同:memcahe 对数据类型支持相对简单redis 有复杂的数据类型。使用底层模型不同:它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。支持的 value 大小不一样:redis 最大可以达到 1GB而 memcache 只有 1MB
Memcache 与 Redis 的区别都有哪些?
Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以 redis 具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘 I/O 速度为严重影响 redis 的性能。在内存越来越便宜的今天,redis 将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。
为什么 redis 需要把所有数据放到内存中?
Redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当Redis重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目的。实现:单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。方式:RDB是Redis默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即Snapshot快照存储,对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。( 快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。)AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。
Redis 如何进行持久化?
RDB持久化优点:RDB文件紧凑,体积小,网络传输快,适合全量复制;恢复速度比AOF快很多。当然,与AOF相比,RDB最重要的优点之一是对性能的影响相对较小。缺点:RDB文件的致命缺点在于其数据快照的持久化方式决定了必然做不到实时持久化,而在数据越来越重要的今天,数据的大量丢失很多时候是无法接受的,因此AOF持久化成为主流。此外,RDB文件需要满足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。AOF持久化优点:支持秒级持久化、兼容性好缺点:文件大、恢复速度慢、对性能影响大。
RDB和AOF的优缺点有哪些?
缓存穿透一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力,就叫做缓存穿透。避免对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。
什么是缓存穿透?如何避免?
缓存雪崩当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。避免在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。做二级缓存,A1为原始缓存,A2为拷贝缓存;A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
什么是缓存雪崩?何如避免?
noeviction:不删除策略,达到最大内存限制时,如果需要更多内存,直接返回错误信息。大多数写命令都会导致占用更多的内存(有极少数会例外)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。
redis的淘汰策略有哪些?
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;4、使用多路I/O复用模型,非阻塞IO;这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
Redis是单线程的,但为什么这么快?
数据作为数据库,数据是最主要的部分;这部分占用的内存会统计在used_memory中。进程本身运行需要的内存Redis主进程本身运行肯定需要占用内存,如代码、常量池等等;这部分内存大约几兆,在大多数生产环境中与Redis数据占用的内存相比可以忽略。这部分内存不是由jemalloc分配,因此不会统计在used_memory中。缓冲内存缓冲内存包括客户端缓冲区、复制积压缓冲区、AOF缓冲区等;客户端缓冲存储客户端连接的输入输出缓冲;复制积压缓冲用于部分复制功能;AOF缓冲区用于在进行AOF重写时,保存最近的写入命令。在了解相应功能之前,不需要知道这些缓冲的细节;这部分内存由jemalloc分配,因此会统计在used_memory中。内存碎片内存碎片是Redis在分配、回收物理内存过程中产生的。例如,如果对数据的更改频繁,而且数据之间的大小相差很大,可能导致redis释放的空间在物理内存中并没有释放,但redis又无法有效利用,这就形成了内存碎片。内存碎片不会统计在used_memory中。
Redis的内存分为哪些?
Redis事务功能是通过MULTI、EXEC、DISCARD和WATCH 四个原语实现的Redis会将一个事务中的所有命令序列化,然后按顺序执行。redis 不支持回滚“Redis 在事务失败时不进行回滚,而是继续执行余下的命令”, 所以 Redis 的内部可以保持简单且快速。如果在一个事务中的命令出现错误,那么所有的命令都不会执行;如果在一个事务中出现运行错误,那么正确的命令会被执行。命令MULTI命令用于开启一个事务,它总是返回OK。MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil 。DISCARD:通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务, 并且客户端会从事务状态中退出。WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。
说说Redis事务?
Redis 常见的性能问题都有哪些?如何解决?
会话缓存(Session Cache)全页缓存(FPC)队列排行榜/计数器发布/订阅
Redis 适合的场景有哪些?
Redis
MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库。采用BSON存储文档数据。BSON()是一种类json的一种二进制形式的存储格式,简称Binary JSON. 相对于json多了date类型和二进制数组。
什么是MongoDB?
关系型数据库优点:数据之间有关系,进行数据的增删改查的时候是非常方便的关系型数据库是有事务操作的,保证数据的完整性和一致性。缺点:因为数据和数据是有关系的,底层是运行了大量的算法,大量算法会降低系统的效率,会降低性能面对海量数据的增删改查的时候会显的无能为力海量数据对数据进行维护变得非常的无力非关系型数据库优点:海量数据的增删改查是可以的海量数据的维护和处理非常轻松缺点:数据和数据没有关系,他们之间就是单独存在的非关系数据库没有关系,没有强大的事务关系,没有保证数据的完整性和安全性
关系型数据库和非关系性数据库的区别?
String 字符串Integer 整型数值Double 双精度浮点值Boolean 布尔值Object 用于内嵌文档Object ID 对象 IDArrays 用于将数组或列表或多个值存储为一个键Min/Max Keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比Code 代码类型Regular Expression
MongoDB支持哪些数据类型?
mongodb存储bson对象在丛集(collection)中。数据库名字和丛集名字以句点连结起来叫做命名空间(namespace)。一个集合命名空间又有多个数据域(extent),集合命名空间里存储着集合的元数据,比如集合名称,集合的第一个数据域和最后一个数据域的位置等等。而一个数据域由若干条文档(document)组成,每个数据域都有一个 头部,记录着第一条文档和最后一条文档的为知,以及该数据域的一些元数据。extent之间,document之间通过 双向链表连接。索引的存储数据结构是B树,索引命名空间存储着对B树的根节点的指针。
什么是命名空间?
Mongodb没有使用传统的锁或者复杂的带回滚的事务,因为他设计的宗旨是轻量级,快速以及可预计的高性能,可能把它类比成mysql myisam的自动提交模式,通过精简对事务的支持,性能得到了提升,特别是在一个可能会穿过多个服务器的系统里。
MongoDB如何执行事务?
不会,磁盘写操作默认是延迟执行的,写操作可能在量三秒后到达磁盘,例如,如果一秒内数据库收到一千个对一个对象递增的操作,仅刷新磁盘一次。
mongoDB会同步刷新数据到磁盘吗?
mongoDB使用索引要注意什么?
MongoDB支持存储过程,它是javascript写的,保存在db.system.js表中。
MongoDB支持存储过程吗?
MongoDB中包括了一个可以显示数据库中每个操作性能特点的数据库分析器。通过这个分析器你可以找到比预期慢的查询(或写操作);利用这一信息,可以确定是否需要添加索引等。
分析器在MongoDB中的作用是什么?
是的,用户移除属性然后对象会重新保存(re-save())。
如果用户移除对象的属性,该属性是否从存储层中删除?
对于对象成员而言,允许。但是用户不能够添加空值(null)到数据库丛集(collection),因为空值不是对象。但是用户能够添加空对象{}。
MongoDB允许空值null吗?
MongoDB 的应用已经渗透到各个领域,比如游戏、物流、电商、内容管理、社交、物联网、视频直播等,以下是几个实际的应用案例:游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来。社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析视频直播,使用 MongoDB 存储用户信息、礼物信息等
mongoDB 主要使用在什么场景?
MongoDB
RabbitMQerlang开发,对消息堆积的支持并不好,当大量消息积压的时候,会导致 RabbitMQ 的性能急剧下降。每秒钟可以处理几万到十几万条消息。RocketMQjava开发,面向互联网集群化,功能丰富,对在线业务的响应时延做了很多的优化,大多数情况下可以做到毫秒级的响应,每秒钟大概能处理几十万条消息。KafkaScala开发,面向日志,功能丰富,性能最高。当你的业务场景中,每秒钟消息数量没有那么多的时候,Kafka 的时延反而会比较高。所以,Kafka 不太适合在线业务场景。ActiveMQjava开发,简单,稳定,性能不如前面三个。不推荐。
多个MQ如何选型?
Nameserver无状态,动态列表;这也是和zookeeper的重要区别之一。zookeeper是有状态的。Producer消息生产者,负责发消息到Broker。Broker就是MQ本身,负责收发消息、持久化消息等。Consumer消息消费者,负责从Broker上拉取消息进行消费,消费完进行ack。
RocketMQ组成部分有哪些?
集群消费一条消息只会被同Group中的一个Consumer消费多个Group同时消费一个Topic时,每个Group都会有一个Consumer消费到数据广播消费消息将对一个Consumer Group 下的各个 Consumer 实例都消费一遍。即即使这些 Consumer 属于同一个Consumer Group ,消息也会被 Consumer Group 中的每个 Consumer 都消费一次。
RocketMQ消费模式有几种?
出现原因正常情况下在consumer真正消费完消息后应该发送ack,通知broker该消息已正常消费,从queue中剔除当ack因为网络原因无法发送到broker,broker会认为词条消息没有被消费,此后会开启消息重投机制把消息再次投递到consumer。消费模式:在CLUSTERING模式下,消息在broker中会保证相同group的consumer消费一次,但是针对不同group的consumer会推送多次解决方案数据库表:处理消息前,使用消息主键在表中带有约束的字段中insertMap:单机时可以使用map做限制,消费时查询当前消息id是不是已经存在Redis:使用分布式锁。
消息重复消费如何解决?
首先多个queue只能保证单个queue里的顺序,queue是典型的FIFO,天然顺序。多个queue同时消费是无法绝对保证消息的有序性的。可以使用同一topic,同一个QUEUE,发消息的时候一个线程去发送消息,消费的时候 一个线程去消费一个queue里的消息。
RocketMQ如何保证消息的顺序消费?
Producer端采取send()同步发消息,发送结果是同步感知的。发送失败后可以重试,设置重试次数。默认3次。Broker端修改刷盘策略为同步刷盘。默认情况下是异步刷盘的。集群部署Consumer端完全消费正常后在进行手动ack确认
RocketMQ如何保证消息不丢失?
1、生产者向MQ服务器发送half消息。2、half消息发送成功后,MQ服务器返回确认消息给生产者。3、生产者开始执行本地事务。4、根据本地事务执行的结果(UNKNOW、commit、rollback)向MQ Server发送提交或回滚消息。5、如果错过了(可能因为网络异常、生产者突然宕机等导致的异常情况)提交/回滚消息,则MQ服务器将向同一组中的每个生产者发送回查消息以获取事务状态。6、回查生产者本地事物状态。7、生产者根据本地事务状态发送提交/回滚消息。8、MQ服务器将丢弃回滚的消息,但已提交(进行过二次确认的half消息)的消息将投递给消费者进行消费。Half Message:预处理消息,当broker收到此类消息后,会存储到RMQ_SYS_TRANS_HALF_TOPIC的消息消费队列中检查事务状态:Broker会开启一个定时任务,消费RMQ_SYS_TRANS_HALF_TOPIC队列中的消息,每次执行任务会向消息发送者确认事务执行状态(提交、回滚、未知),如果是未知,Broker会定时去回调在重新检查。超时:如果超过回查次数,默认回滚消息。也就是他并未真正进入Topic的queue,而是用了临时queue来放所谓的half message,等提交事务后才会真正的将half message转移到topic下的queue。
RocketMQ如何实现分布式事务?
1、如果可以添加消费者解决,就添加消费者的数据量2、如果出现了queue,但是消费者多的情况。可以使用准备一个临时的topic,同时创建一些queue,在临时创建一个消费者来把这些消息转移到topic中,让消费者消费。
RocketMQ的消息堆积如何处理?
RocketMQ
ISR:In-Sync Replicas 副本同步队列AR:Assigned Replicas 所有副本ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度,当前最新的版本0.10.x中只支持replica.lag.time.max.ms这个维度),任意一个超过阈值都会把follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中。AR=ISR+OSR。
Kafka中的ISR、AR代表什么?ISR的伸缩指什么?
broker 是消息的代理,Producers往Brokers里面的指定Topic中写消息,Consumers从Brokers里面拉取指定Topic的消息,然后进行业务处理,broker在中间起到一个代理保存消息的中转站。
kafka中的broker 是干什么的?
zookeeper 是一个分布式的协调组件,早期版本的kafka用zk做meta信息存储,consumer的消费状态,group的管理以及 offset的值。考虑到zk本身的一些因素以及整个架构较大概率存在单点问题,新版本中逐渐弱化了zookeeper的作用。新的consumer使用了kafka内部的group coordination协议,也减少了对zookeeper的依赖。
kafka中的 zookeeper 起到什么作用?
Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率。异步复制方式下,Follower异步的从Leader复制数据,数据只要被Leader写入log就被认为已经commit,这种情况下,如果leader挂掉,会丢失数据;kafka使用ISR的方式很好的均衡了确保数据不丢失以及吞吐率。Follower可以批量的从Leader复制数据,而且Leader充分利用磁盘顺序读以及send file(zero copy)机制,这样极大的提高复制性能,内部批量写磁盘,大幅减少了Follower与Leader的消息量差。
kafka follower如何与leader同步数据?
Cache Filesystem Cache PageCache缓存顺序写:由于现代的操作系统提供了预读和写技术,磁盘的顺序写大多数情况下比随机写内存还要快。Zero-copy:零拷技术减少拷贝次数Batching of Messages:批量量处理。合并小的请求,然后以流的方式进行交互,直顶网络上限。Pull 拉模式:使用拉模式进行消息的获取消费,与消费端处理能力相符。
kafka 为什么那么快?
增加线程提高 batch.size增加更多 producer 实例增加 partition 数设置 acks=-1 时,如果延迟增大:可以增大 num.replica.fetchers(follower 同步数据的线程数)来调解;跨数据中心的传输:增加 socket 缓冲区设置以及 OS tcp 缓冲区设置。
kafka producer如何优化打入速度?
1(默认) 数据发送到Kafka后,经过leader成功接收消息的的确认,就算是发送成功了。在这种情况下,如果leader宕机了,则会丢失数据。0 生产者将数据发送出去就不管了,不去等待任何返回。这种情况下数据传输效率最高,但是数据可靠性确是最低的。-1producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。当ISR中所有Replica都向Leader发送ACK时,leader才commit,这时候producer才能认为一个请求中的消息都commit了。
kafka producer发送数据,ack为0,1,-1分别是什么意思?
一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成header部分由一个字节的magic(文件格式)和四个字节的CRC32(用于判断body消息体是否正常)构成。当magic的值为1的时候,会在magic和crc32之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果magic的值为0,那么不存在attributes属性body是由N个字节构成的一个消息体,包含了具体的key/value消息
kafka的message格式是什么样的?
同样是逻辑上的概念,是Kafka实现单播和广播两种消息模型的手段。同一个topic的数据,会广播给不同的group;同一个group中的worker,只有一个worker能拿到这个数据。换句话说,对于同一个topic,每个group都可以拿到同样的所有数据,但是数据进入group后只能被其中的一个worker消费。group内的worker可以使用多线程或多进程来实现,也可以将进程分散在多台机器上,worker的数量通常不超过partition的数量,且二者最好保持整数倍关系,因为Kafka在设计时假定了一个partition只能被一个worker消费(同一group内)。
kafka中consumer group 是什么概念?
消息发送Kafka消息发送有两种方式:同步(sync)和异步(async),默认是同步方式,可通过producer.type属性进行配置。Kafka通过配置request.required.acks属性来确认消息的生产0---表示不进行消息接收是否成功的确认;1---表示当Leader接收成功时确认;-1---表示Leader和Follower都接收成功时确认;综上所述,有6种消息生产的情况,消息丢失的场景:acks=0,不和Kafka集群进行消息接收确认,则当网络异常、缓冲区满了等情况时,消息可能丢失;acks=1、同步模式下,只有Leader确认接收成功后但挂掉了,副本没有同步,数据可能丢失;消息消费Kafka消息消费有两个consumer接口,Low-level API和High-level API:Low-level API:消费者自己维护offset等值,可以实现对Kafka的完全控制;High-level API:封装了对parition和offset的管理,使用简单;如果使用高级接口High-level API,可能存在一个问题就是当消息消费者从集群中把消息取出来、并提交了新的消息offset值后,还没来得及消费就挂掉了,那么下次再消费时之前没消费成功的消息就“诡异”的消失了;解决办法:针对消息丢失:同步模式下,确认机制设置为-1,即让消息写入Leader和Follower之后再确认消息发送成功;异步模式下,为防止缓冲区满,可以在配置文件设置不限制阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态;针对消息重复:将消息的唯一标识保存到外部介质中,每次消费时判断是否处理过即可。
Kafka中的消息是否会丢失和重复消费?
在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从 而实现的是一种主写主读的生产消费模型。Kafka 并不支持主写从读,因为主写从读有 2 个很明 显的缺点:数据一致性问题。数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。延时问题。类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经历网络→主节点内存→网络→从节点内存这几个阶段,整个过程会耗费一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历网络→主节点内存→主节点磁盘→网络→从节点内存→从节点磁盘这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。
为什么Kafka不支持读写分离?
KafKa
RabbitMQ是一款开源的,Erlang编写的,基于AMQP协议的,消息中间件;可以用它来:解耦、异步、削峰。优点:解耦、异步、削峰;缺点:降低了系统的稳定性:系统中使用了消息队列,如果消息队列挂了,那么系统也会挂掉。因此,系统可用性会降低;加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。因此,需要考虑的东西更多,复杂性增大。
什么是RabbitMQ?为什么使用RabbitMQ?有什么好处?
Broker:消息队列服务器实体Exchange:消息交换机,它指定消息按特定规则,路由到哪个队列Queue:消息队列载体,每个消息都会被投入到一个或多个队列Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来Routing Key:路由关键字,exchange根据这个关键字进行消息投递VHost:vhost 可以理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的 queue、exchange 和 binding 等,拥有独立的权限系统,可以做到 vhost 范围的用户控制。Producer:消息生产者Consumer:消息消费者Channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务
RabbitMQ基本概念有哪些?
正常情况下,消费者在消费消息的时候,消费完毕后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除;但是因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将消息分发给其他的消费者。解决思路:保证消息的唯一性,就算是多次传输,不要让消息的多次消费带来影响;保证消息等幂性;比如:在写入消息队列的数据做唯一标识,消费消息时,根据唯一标识判断是否消费过;
如何保证RabbitMQ不被重复消费?
queue 具有自己的 erlang 进程;exchange 内部实现为保存 binding 关系的查找表;channel 是实际进行路由工作的实体,即负责按照 routing_key 将 message 投递给 queue 。由 AMQP 协议描述可知,channel 是真实 TCP 连接之上的虚拟连接,所有 AMQP 命令都是通过 channel 发送的,且每一个 channel 有唯一的 ID。一个 channel 只能被单独一个操作系统线程使用,故投递到特定 channel 上的 message 是有顺序的。但一个操作系统线程上允许使用多个 channel 。
RabbitMQ 概念里的 channel、exchange 和 queue 是逻辑概念,还是对应着进程实体?分别起什么作用?
从概念上来说,消息路由必须有三部分:交换器、路由、绑定。生产者把消息发布到交换器上;绑定决定了消息如何从路由器路由到特定的队列;消息最终到达队列,并被消费者接收。消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。通过队列路由键,可以把队列绑定到交换器上。消息到达交换器后,RabbitMQ会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则)。如果能够匹配到队列,则消息会投递到相应队列中;如果不能匹配到任何队列,消息将进入 “黑洞”。常用的交换器主要分为一下三种:direct:如果路由键完全匹配,消息就被投递到相应的队列fanout:如果交换器收到消息,将会广播到所有绑定的队列上topic:可以使来自不同源头的消息能够到达同一个队列。使用topic交换器时,可以使用通配符,比如:“*” 匹配特定位置的任意文本, “.” 把路由键分为了几部分,“#” 匹配所有规则等。特别注意:发往topic交换器的消息不能随意的设置选择键(routing_key),必须是由\".\"隔开的一系列的标识符组成。
RabbitMQ消息是如何路由的?
消息不可靠的情况可能是消息丢失,劫持等原因丢失又分为:生产者丢失消息消息列表丢失消息消费者丢失消息生产者丢失消息:从生产者弄丢数据这个角度来看,RabbitMQ提供transaction机制和confirm模式来确保生产者不丢消息;transaction机制:发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())。confirm模式(用的居多):一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;RabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;如果RabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。消息队列丢数据:消息持久化,处理消息队列丢数据的情况,一般是开启持久化磁盘的配置:将队列的持久化标识durable设置为true,则代表是一个持久的队列 发送消息的时候将 deliveryMode=2 这样设置以后,即使RabbitMQ挂了,重启后也能恢复数据消费者丢失消息:消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息;如果这时处理消息失败,就会丢失该消息;解决方案:处理消息成功后,手动回复确认消息。
如何保证RabbitMQ消息的可靠传输?
1、单线程消费保证消息的顺序性;2、对消息进行编号,消费者处理消息是根据编号处理消息;
如何保证RabbitMQ消息的顺序性?
死信队列:死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer将消息投递到broker或者直接到queue里了,consumer从queue取出消息进行消费,但某些时候由于特定的原因导致queue中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信,自然就有了死信队列;死信消息:1、消息被拒绝(Basic.Reject或Basic.Nack)并且设置 requeue 参数的值为 false2、消息过期了3、队列达到最大的长度过期消息:在 rabbitmq 中存在2种方可设置消息的过期时间,第一种通过对队列进行设置,这种设置后,该队列中所有的消息都存在相同的过期时间,第二种通过对消息本身进行设置,那么每条消息的过期时间都不一样。如果同时使用这2种方法,那么以过期时间小的那个数值为准。当消息达到过期时间还没有被消费,那么那个消息就成为了一个 死信 消息。队列设置:在队列申明的时候使用 x-message-ttl 参数,单位为 毫秒单个消息设置:是设置消息属性的 expiration 参数的值,单位为 毫秒延时队列:在rabbitmq中不存在延时队列,但是我们可以通过设置消息的过期时间和死信队列来模拟出延时队列。消费者监听死信交换器绑定的队列,而不要监听消息发送的队列。
死信队列和延迟队如何使用?
RebbitMQ
数据库/中间件
Java最全常见面试题
0 条评论
回复 删除
下一页