【无标题】面试题

​​​​​​​

JDKJREJVM之间的hashCode()equals()之间的关

StringStringBufferStringBuilder泛型extendssuper

==equals重载写的

ListSet

ArrayListLinkedList

谈谈ConcurrentHashMap的扩容

Jdk .  Jdk . HashMap ⽣了什么(底层)? ⼀下HashMapPut

拷 ⻉ 拷 ⻉ HashMap的扩容

CopyOnWriteArrayList的底层什么⽤字码的好处什么Java中的异常体系是

Java的异常处理制中什么候应该抛出异常什么候捕异常?  Java有哪载器

说说载器亲委JVM是线程共享你们项⽬如何排JVM问题

⼀个对象从加JVM再到被GC都经了什么过程怎么确定⼀个对象到底是垃圾

JVM有哪垃圾回算法什么STW

JVM有哪

说说对线程安全的理解对守护线程的理解

ThreadLocal的底层

并⾏串⾏之间的Java如何

线程池的底层⼯作

线程池为什么加列队⽽先创建线程ReentrantLock中的公平⾮公平的底层实现ReentrantLocktryLock()lock()CountDownLatchSemaphore底层Sychronized的偏轻量级锁重量级锁SychronizedReentrantLock

谈谈你对AQS的理解AQS如何实现谈谈你对IOC的理解

Bean和单例模式Spring事务传播

Spring事务什么候会失效?

Spring中的Bean创建的⽣命周期有哪些步骤SpringBean是线程安全的ApplicationContextBeanFactory什么Spring中的事务如何实现的

Spring中什么@Transactional会失效Spring流程是

Spring⽤到了些设计模式

Spring Boot中常⽤其底层实现Spring Boot如何TomcatMybatis的优缺点

#{}${}什么引的基

引设计的

事务的基本特离级别什么MVCC

简述MyISAMInnoDB

Explain结果各个字段分表表什么

引覆盖什么

左前什么Innodb如何实现事务的

BB+为什么Mysql使⽤B+Mysql锁有哪如何理解

Mysql询该如何优化什么RDBAOF

Redis过期键的删除简述Redis事务实现

Redis 主从复制的

Redis有哪些数据结构分别有哪些典的应⽤场景Redis分布式底层如何实现的

Redis主从复制的Redis集群

穿透存击穿存雪崩分别什么RedisMysql如何保证数据

Redis的持久化

Redis线程为什么么快简述Redis事务实现

什么CAP理论什么BASE理论什么RPC

数据致性模型有哪

分布式ID什么有哪些解决⽅

分布式的使⽤场景是什么有哪些实现⽅什么分布式事务有哪些实现⽅

什么ZAB

为什么Zookeeper以⽤作为册中⼼Zookeeper中的领导者举的流程是Zookeeper集群中节点之间数据如何步的Dubbo⽀持些负载均

Dubbo如何完成务导出的

Dubbo如何完成务引⼊的Dubbo架构设计载均算法有哪

分布式架构下,Session 共享什么⽅如何实现接的幂

简述zk命名配置管集群理    Zookeeper中的watchZookeeperEureka

存储拆分如何解决问题雪花算法

如何解决使⽤分询问题

Spring Cloud有哪些常⽤作⽤什么如何穿透存击穿存雪崩?        分布式系统中常⽤的存⽅案有哪

过期都有哪常⻅的淘汰算法

布隆过滤器缺点分布式存寻址算法

Spring CloudDubbo有哪什么是服务雪崩什么是服务限

什么是服什么是服务降?区什么SOA分布式务之间什么关和区怎么拆分微

设计出⾼内聚低耦的微有没有了解DDD领域驱动设计

什么台?

你的项⽬中怎么保证微务敏捷开如何息队列选型

RocketMQ的事务如何实现的

为什么RocketMQ使⽤Zookeeper作为册中⼼呢? RocketMQ的实现

RocketMQ为什么度快

正在上传…重新上传取消息队列如何保证靠传输消息队列有哪些作⽤

死信队列什么队列什么如何保证息的⾼效读写

epollpoll

TCP次握⼿次挥⼿

⼀个请求到收到些步骤跨域请求什么什么问题怎么解决

零拷⻉什么

JDKJREJVM区别

  • JDK(Java SE  Development  Kit)Java标准开发包它提供了编译Java程序所需的各种⼯具和资包括Java编译Java以及常⽤的Java类库等
  • JRE( Java Runtime Environment) Java⾏环境⽤于Java的字节码⽂件JRE中包括了JVM以及JVM⼯作所需要的类库⽤户⽽只需要安装JREJava程序⽽程序开发者必须安装JDK来编译调试程序
  • JVM(Java  Virtual   Mechinal)Java拟机JRE它是整java实现跨平台的最核⼼的负责⾏字节码⽂件

我们写Java代码txt就可以写但是写出来的Java代码想要需要先编译成字节码就需要编译JDK中就包含了编译javac编译之后的字节码想要就需要⼀个可以执⾏字节码的程序程序就是JVMJava拟机),专⻔⽤来执⾏Java字节码的

如果我们要开发Java程序就需要JDK为要编译Java⽂件

如果我们只想⾏已经编译好的Java字节码⽂件也就是*.class⽂件么就只需要JRE。  JDK中包含了JREJRE中包含了JVM

另外JVM执⾏Java字节码时需要把字节码解释为机指令同操作系统的机指令是有可能不⼀样的所以就导致同操作系统JVM不⼀样的所以我们安装JDK时需要择操作系统另外JVM是⽤来执⾏Java字节码的所以凡是某代码编译之后是Java字节码JVM

⽐如Apache Groovy, Scala and Kotlin 等等

hashCode()equals()

正在上传…重新上传取消Java对象可以调⽤⾃⼰的hashCode()得到⾃⼰的哈希(hashCode)相当于对象的        指纹信息常来说有完全相同的两个指纹但是Java中做么绝对但是我们仍然可         以利⽤hashCode来做些提前的判断⽐如

  • 如果两个对象的hashCode相同两个对象肯定同的两个对象
  • 如果两个对象的hashCode相同,不代表两个对象定是同⼀个对象也可能是两个对象
  • 如果两个对象相等么他们的hashCode定相同

Java些集合类的实现中两个对象是否相等时会根据⾯的原则会先调⽤对象的hashCode()得到hashCode⾏⽐如果hashCode相同就可以直接认为两个对象

如果hashCode相同么就会步调⽤equals()法进⾏⽐equals()就是⽤来最终确定两个对象是是相等的equals的实现会⽐逻辑hashCode()主要就是得⼀个哈希实际⼀个数字相对⽽⾔⽐较轻所以两个对象时会先根据hashCode想⽐⼀下

所以我们就需要如果我们重写了equals()么就要hashCode(),⼀定要保证能规则

StringStringBufferStringBuilder区别

  1. String可变的如果尝试去修改会新⽣成⼀个字符串对象StringBufferStringBuilder是可变的
  2. StringBuffer是线程安全的StringBuilder是线程安全的所以单线程环境StringBuilder效率会更⾼

泛型中extendssuper区别

  1. <? extends T>表示包括T内的任何T的⼦类
  2. <? super T>表示包括T内的任何T的⽗类

==equals区别

==如果是基本数据类如果是引⽤类的是引⽤地址

  • equals具体看各类重写equals之后的⽐较逻辑⽐如String然是引⽤类但是String类中重写了equals的是字符串中的各字符是否全相等

正在上传…重新上传取消区别

  • (Overload):        ⼀个类中同名的⽅如果有同的参数列表⽐如参数类参数则视为重
  • 重写(Override)从字⾯重写就是 重新写的意思其实就是⼦类中把⽗类本身有的⽅重新写⼦类继承了⽗类的⽅但有时⼦类并想原封动的继承⽗类中的某所  以参数列表返回型都相同(⼦类中⽅返回值可以是⽗类中⽅法返回值的⼦类)的   情况下, 对⽅⾏修改就是重写但要意⼦类⽅的访问修饰权限能⼩于⽗类的

ListSet区别

  • List有序按对象插⼊的顺序保存对象可重复许多Null元素对象可以使⽤Iterator取出所有元素在逐可以使⽤get(int index)获取指定标的元素
  • Set⽆序,不可重复最多许有⼀个Null元素对象取元素时只能⽤Iterator接⼝取得所有元素在逐历各元素

ArrayListLinkedList区别

  1. ⾸先他们的底层数据结构ArrayList底层是基于数组实现的LinkedList底层是基于链表实现的
  2. 由于底层数据结构他们所⽤的景也ArrayList合随机查找LinkedList合删除和查询删除的时间复杂度
  3. 另外ArrayListLinkedList实现了List接⼝但是LinkedList额外实现了Deque接⼝所以LinkedList可以当做队列来使⽤

谈谈ConcurrentHashMap扩容

    1. 版本
      1. 1.7版本的ConcurrentHashMap是基于Segment分段实现的
      2. Segment相对于⼀个HashMap
      3. Segment⾏扩容HashMap的扩容逻辑类似
      4. 先⽣成新的数组然后移元素到新数组中

      1. 正在上传…重新上传取消扩容的判断也是每Segment单独判断的判断是否超

    1. 版本
      1. 1.8版本的ConcurrentHashMap再基于Segment实现
      2. 当某线程put如果发现ConcurrentHashMap在进⾏扩容么该线程⾏扩容
      3. 如果某线程put发现有正在进⾏扩容则将key-value加到ConcurrentHashMap然后判断是否超了则⾏扩容
      4. ConcurrentHashMap是⽀持多线程同时扩容的
      5. 扩容之前也先⽣成⼀个新的数组
      6. 在转移元素时先将原数组分组将每组分给同的线程来⾏元素的线程负责组或多组的元素移⼯作

Jdk1.7Jdk1.8 HashMap 了什么变化(底层)?

  1. 1.7中底层是数组+链表1.8中底层是数组+链表+红⿊树加红⿊树的⽬的是提⾼HashMap插⼊和查询整体效率
  2. 1.7中链表插⼊使⽤的是头插1.8中链表插⼊使⽤的是尾插1.8中插⼊keyvalue时需要     判断链表元素所以需要历链表统计链表元素所以正好就直接使⽤尾插
  3. 1.7中哈希算复杂各种右移异或1.8⾏了简化为复杂的哈希算的⽬的就是提⾼散列性来提供HashMap的整体效率1.8中新增了红⿊树所以可以当的简化哈希  算节省CPU

⼀下HashMapPut

先说HashMapPut的⼤体

  1. 根据Key通过哈希算与与算得出数组
  2. 如果数组标位置元素为空则将keyvalue封装为Entry对象JDK1.7中是Entry对象JDK1.8中    Node对象并放⼊该位置
  3. 如果数组标位置元素为空则要分情况讨论
    1. 如果是JDK1.7则先判断是否需要扩容如果要扩容就⾏扩容如果⽤扩容就⽣成Entry对象并使⽤头插法添加到当前位置的链表中
    2. 如果是JDK1.8则会先判断当前位置Node的类看是红⿊树Node是链表Node

ⅰ. 如果是红⿊树Node则将keyvalue封装为⼀个红⿊树节点并加到红⿊树中去在这程中会判断红⿊树中是否存当前key如果存则更新value

正在上传…重新上传取消ⅱ.        如果此位置Node对象是链表节点则将keyvalue封装为⼀个链表Node通过尾插插⼊到链表的最后位置去为是尾插所以需要历链表在遍历链表的程中会           判断是否存当前key如果存则更新value历完链表后将新链表Node插⼊到链       表中插⼊到链表后会看当前链表的节点如果⼤于等于8么则会将该链表成        红⿊树

ⅲ. keyvalue封装为Node插⼊到链表或红⿊树中后再判断是否需要⾏扩容如果需要就扩容如果需要就结束PUT

拷⻉和拷⻉

拷⻉和拷⻉就是指对象的拷⻉,⼀个对象中存种类的属性,⼀种是基本数据类,⼀种是实例对象的引⽤

  1. 拷⻉是指只会拷⻉基本数据类以及实例对象的引⽤地址会复制份引⽤地址所指向的对象也就是拷⻉出来的对象的类属性指向的是同⼀个对象
  2. 拷⻉是指既会拷⻉基本数据类也会针对实例对象的引⽤地址所指向的对象⾏复制拷⻉出来的对象的属性指向的是同⼀个对象

HashMap扩容制原

    1. 版本
      1. 先⽣成新数组
      2. 历⽼数组中的每位置的链表的每元素
      3. 取每元素的key并基于新数组⻓度计算出每元素新数组中的
      4. 将元素加到新数组中去
      5. 所有元素移完了之后将新数组赋HashMap对象的table属性

    1. 版本
      1. 先⽣成新数组
      2. 历⽼数组中的每位置的链表或红⿊树
      3. 如果是链表则直接将链表中的每元素重新计算加到新数组中去
      4. 如果是红⿊树则先历红⿊树先计算出红⿊树中每元素对应新数组中的标位置
        1. 统计每个下标位置的元素
        2. 如果该位置的元素数超8则⽣成⼀个新的红⿊树并将根节点的加到新数组的对应位置

        1. 正在上传…重新上传取消如果该位置的元素有超8么则⽣成⼀个链表并将链表的头节点加到新数组的对应位置
      1. 所有元素移完了之后将新数组赋HashMap对象的table属性

CopyOnWriteArrayList底层原

  1. ⾸先CopyOnWriteArrayList也是⽤数组来实现的CopyOnWriteArrayList加元素时会复制⼀个新的数组写操作新数组读操作原数组
  2. 且,写操作会加锁防⽌出现并发写⼊失数据的问题
  3. 写操作结束之后会把原数组指向新数组
  4. CopyOnWriteArrayList写操作时来读取数据⼤⼤提⾼了读的性能合读多写少的应

但是CopyOnWriteArrayList会⽐占内存同时可能读到的数据是实时最新的数据所以合实时性要求很⾼的

什么是码的好处是什么

编译(javac)Java⽂件(*.java)⽂件编译成为字节码⽂件(*.class)可以做到次编译到处windows编译好的class⽂件可以直接linux通过这种⽅式做到跨平台,不Java的跨平台有⼀个前提条件就是同的操作系统安装的JDKJRE不⼀样的然字节码是⽤的但是需要把字节码解释成各操作系统的机码是需要同的解释所以针对各操作系统需要有各⾃ 的JDKJRE

采⽤字节码的好处,⼀⽅⾯实现了跨平台另外⽅⾯也提⾼了代码执⾏的性能编译器在编译代码 时可以做些编译期的优化⽐如锁标量替换内联等

Java异常体系是

  • Java中的所有异常来⾃顶级⽗类Throwable
  • Throwable两个⼦类ExceptionError
  • Error表示⾮常重的错误⽐如java.lang.StackOverFlowErrorJava.lang.OutOfMemoryError,   些错误出现时仅仅想靠程序⾃⼰是解决了的可能是拟机磁盘操作系统层⾯出现    的问题了所以常也建议代码中去捕获Error为捕获的意义为程序可能已经 根本了了
  • Exception表示异常表示程序出现Exception是可以靠程序⾃⼰来解决的⽐如NullPointerExceptionIllegalAccessException我们可以捕获些异常来做特殊处理

  • 正在上传…重新上传取消Exception的⼦类常⼜可以分为RuntimeException和⾮RuntimeException
  • RunTimeException表示⾏期异常表示异常是代码程中抛出的这些异常是⾮检查

异常,程序中可以选择捕获处理,也可以不处理。这些异常⼀般是由程序逻辑错误引起的,程序应该从逻辑⻆度尽可能避免这类异常的发⽣,⽐如NullPointerException、IndexOutOfBoundsException等。

  • RuntimeException表示⾮⾏期异常也就是我们常说的检查异常,是必须进⾏处理的异常,如果

正在上传…重新上传取消不处理,程序就不能检查异常通过。如IOException、SQLException等以及⽤户⾃定义的Exception异

Java异常处什么时候应该抛出异常什么时候异常

异常相当于种提示如果我们抛出异常就相当于告诉层⽅我抛了⼀个异常我处理异常交给你来处理⽽对于层⽅来说它也需要决定⾃⼰能能处理异常是否也需要交给它的

所以我们⼀个我们需要考的就是本⽅能否合理的处理该异常如果处理了就继续 向抛出异常包括本⽅调⽤另外⼀个发现出现了异常如果异常应该由⾃⼰来处理就捕获该异常并⾏处理

Java中有哪些类载器

JDK⾃带有三个类加载器bootstrap ClassLoaderExtClassLoaderAppClassLoader

  • BootStrapClassLoaderExtClassLoader的⽗类加载器默认负责加%JAVA_HOME%lib的   jar包和class⽂件
  • ExtClassLoaderAppClassLoader的⽗类加载器负责加%JAVA_HOME%/lib/ext⽂件夹

jar包和class

  • AppClassLoader是⾃定义类加载器的⽗类负责加classpath的类⽂件

说说载器派模型

JVM中存三个默认的类加载器

  1. BootstrapClassLoader

  1. 正在上传…重新上传取消ExtClassLoader
  2. AppClassLoader

AppClassLoader的⽗加载器ExtClassLoaderExtClassLoader的⽗加载器BootstrapClassLoader

JVM⼀个类时会调⽤AppClassLoaderloadClass来加载这,不过在这会      先使⽤ExtClassLoaderloadClass来加同样ExtClassLoaderloadClass中会先使⽤BootstrapClassLoader来加如果BootstrapClassLoader到了就直接成功如果BootstrapClassLoader有加ExtClassLoader就会⾃⼰尝试加该类如果有加么则会由AppClassLoader来加载这

所以双亲委指得是JVM类时会委ExtBootstrap⾏加如果到才由⾃⼰⾏加

JVM中哪些是线程

堆区和⽅区是所有线程共享的程序计数是每线程独有的

正在上传…重新上传取消你们JVM问题

对于还在正常⾏的系统

  1. 可以使⽤jmap来查看JVM中各区域的使⽤情况
  2. 可以通过jstack来查看线程的⾏情况⽐如些线程阻塞是否出现了死锁
  3. 可以通过jstat命令来查看垃圾回收的情况特别是fullgc如果发现fullgc频繁么就得⾏ 调优了
  4. 通过命令的结果或者jvisualvm⼯具来进⾏分
  5. ⾸先初步猜频繁发fullgc的原如果频繁发⽣fullgc但是⼜有出现内存么表   示fullgc实际收了很多对象了所以些对象最好能younggc程中就直接收掉些对象⼊到⽼年代对于种情况就要考虑这些存时间⻓的对象是是⽐导致年轻  代放不下,直接⼊到了⽼年代尝试加⼤年代的⼤⼩如果改完之后fullgc减少则证明修改有效
  6. 同时可以找到占⽤CPU最多的线程定位到具体的⽅优化的执⾏看是否能免某些对象的创建从⽽节省内存

对于已经发⽣了OOM的系统

  1. 般⽣产系统中会设置当系统发⽣了OOM⽣成当时的dump⽂件- XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/base
  2. 我们可以利⽤jsisualvm等⼯具来分析dump⽂件
  3. 根据dump⽂件找到异常的实例对象和异常的线程占⽤CPU),定位到具体的代码
  4. 然后再⾏详细的分析和调试

总之调优蹴⽽就的需要分析推理实践总结再分析最终定位到具体的问题

⼀个对象JVM再到被GC都经了什么过程

  1. ⾸先把字节码⽂件内容加到⽅
  2. 然后再根据类信息堆区创建对象
  3. 对象⾸先会分配在堆区中年代的EdenMinor GC对象如果存就会

Suvivor后续的每次Minor GC如果对象直存就会Suvivor区来拷⻉每移动

年龄加1

  1. 当年龄超15对象依然存对象就会⼊⽼年代
  2. 如果经Full GC被标记为垃圾对象么就会被GC线程理掉

正在上传…重新上传取消⼀个对象到底是垃圾

  1. 引⽤计数算种⽅式是给堆内存当中的每对象记录⼀个引⽤引⽤数为0的就认为是垃圾是早期JDK中使⽤的⽅式引⽤计数⽆解决循环引⽤的问题
  2. 性算种⽅式是内存中从根对象向下⼀直找引⽤找到的对象就垃圾找到的对象就是垃圾

JVM有哪些垃圾回算法

  1. 标记除算
    1. 标记阶段垃圾内存标记出来
    2. 除阶段直接将垃圾内存
    3. 种算是⽐简单的但是有重的问题就是会产⽣⼤量的内存碎⽚
  2. 复制算为了解决标记除算的内存碎⽚问题就产⽣了复制算复制算将内存分为⼤⼩ 相等的每次只使⽤其中垃圾回收时将当前的存对象全拷⻉到另然后当前半内存就可以直接种算法没有内存碎⽚但是他的问题就费空间⽽      且,他的效率跟存对象的数有关
  3. 标记压缩算为了解决复制算的缺陷就提出了标记压缩算种算法在标记阶段跟标记除算样的但是完成标记之后,不是直接垃圾内存⽽是将存对象往端移动然后将界以外的所有内存直接

什么是STW

STW: Stop-The-World在垃圾回收算执⾏程当中需要将JVM内存冻结的种状态STW 状态下,JAVA的所有线程是停⽌执⾏的-GC线程除外native可以执⾏但是,不JVMGC各种算优化的重点就是减少STW同时也是JVM调优的重点

JVM参数有哪些

JVM参数⼤致可以分为

  1. 指令-开头些是所有的HotSpot⽀持的参数可以⽤java -help 打印出来
  2. ⾮标准指令-X开头些指令常是跟特定的HotSpot版本对应的可以⽤java -X 打印出来
  3. 稳定参数-XX 开头类参数是跟特定HotSpot版本对应的变化⾮常⼤

正在上传…重新上传取消说说对线程安全的理

线程安全指的是我们写的某段代码线程同时执⾏段代码时,不会产⽣依然能够得到  正常的结果⽐如i++i初始化0两个线程来同时执⾏⾏代码如果代码是线程安全的么最终的结果应该就是⼀个线程的结果为1,⼀个线程的结果为2如果出现了两个线程的结果1则表示段代码是线程安全的

所以线程安全主要指的是段代码线程同时执⾏的情况下,能否得到正确的结果

对守护线程的理

线程分为⽤户线程和守护线程⽤户线程就是普线程守护线程就是JVM的后台线程⽐如垃圾回收 线程就是⼀个守护线程守护线程会其他普线程停⽌⾏之后⾃动关闭我们可以通过设置thread.setDaemon(true)来把⼀个线程设置为守护线程

ThreadLocal底层原

  1. ThreadLocalJava中所提供的线程本存储机制可以利⽤该机制将数据缓存线程内该线程可以任意时刻任意⽅中获取缓存的数据
  2. ThreadLocal底层是通过ThreadLocalMap来实现的Thread对象ThreadLocal对     象⼀个ThreadLocalMapMapkeyThreadLocal对象Mapvalue为需要缓存的

  1. 如果线程池中使⽤ThreadLocal成内存为当ThreadLocal对象使⽤完之后应该要把设置的keyvalue也就是Entry对象但线程池中的线程⽽线程对象是通过强引⽤指向ThreadLocalMapThreadLocalMap也是通过强引⽤指向Entry对象线程Entry对象也就会被从⽽出现内存解决办使⽤了ThreadLocal对象之后⼿动调⽤ThreadLocalremove⼿动Entry对象
  2. ThreadLocal经典的应⽤景就是接管理(⼀个线程持有⼀个接对象可以同的⽅之间⾏传线程之间共享同⼀个

正在上传…重新上传取消

并发并⾏区别

  1. 串⾏:⼀个任务执⾏完才能执⾏下⼀个任务
  2. 并⾏(Parallelism):两个任务同时执⾏
  3. 并发(Concurrency):两个任务整体看去是同时执⾏底层,两个任务被拆成了很多份然后

⼀个⼀个执⾏更⾼的⻆度看来两个任务是同时执⾏的

Java何避

成死锁的⼏

  1. ⼀个每次只能被⼀个线程使⽤
  2. ⼀个线程阻塞等待某,不释放已占有资
  3. ⼀个线程已经获得的资未使⽤完之前,不能被强⾏剥夺
  4. 若⼲线程形成头尾相接的循环等待资关系

成死锁必须要到的4条件如果要免死锁只需要满⾜其中某⼀个条件即可⽽其中前3 条件是作为锁要符合的条件所以要免死锁就需要打破第4条件,不出现循环等待锁的关系

开发程中

  1. 意加锁顺序保证每线程按同样的顺序⾏加锁
  2. 意加锁时限可以针对所设置⼀个超时时间
  3. 意死锁检查种预防机制确保时间发现死锁并⾏解决

正在上传…重新上传取消

线程池底层⼯

线程池内通过队列+线程实现的当我们利⽤线程池执⾏任务时

  1. 如果此时线程池中的线程数量⼩于corePoolSize即使线程池中的线程处于空闲状态也要创建新的线程来处理被加的任务
  2. 如果此时线程池中的线程数量等于corePoolSize但是缓冲队列workQueue未满么任务被放⼊缓冲队列
  3. 如果此时线程池中的线程数量⼤于等于corePoolSize缓冲队列workQueue线程池中的数量⼩于maximumPoolSize建新的线程来处理被加的任务
  4. 如果此时线程池中的线程数量⼤于corePoolSize缓冲队列workQueue线程池中的数量等于maximumPoolSize通过 handler所指定的策略来处理此任务
  5. 当线程池中的线程数量⼤于 corePoolSize如果某线程空闲时间超keepAliveTime线程将被终⽌线程池可以动态的调整池中的线程数

线程池为什么是加列队⽽先创建线程

当线程池中的核⼼线程都在忙时如果继续往线程池中加任务么任务会先放⼊队列队列满了之 后才会新开线程就相当于,⼀个公司本来有10程序员本来10程序员能正常的处理各种需求但是随着公司的发展需求慢慢的增加但是开始些需求只会增加待开发列表中然后10程序员加班加点的从待开发列表中获取需求并⾏处理但是某天待开发列表满了公司发现现有的10程序员是真的处理来了所以就开始新招员⼯了

ReentrantLock公平和⾮公平底层实

⾸先管是公平锁和⾮公平锁它们的底层实现会使⽤AQS⾏排队它们的区别线程使

lock()加锁时如果是公平锁会先检查AQS队列中是否存线程排队如果有线程排队则当前线程也⾏排队如果是⾮公平锁会去检查是否有线程排队⽽是直接竞争锁

管是公平锁是⾮公平锁,⼀竞争到锁⾏排队当锁释放时醒排最前⾯的线 程所以⾮公平锁只是体现了线程加锁阶段有体现线程被醒阶段

另外ReentrantLock是可重⼊锁,不管是公平锁是⾮公平锁是可重⼊的

正在上传…重新上传取消

ReentrantLocktryLock()lock()区别

  1. tryLock()表示尝试加锁可能加到也可能加该⽅会阻塞线程如果加到锁则返回true有加到则返回false
  2. lock()表示阻塞加锁线程会阻塞直到加到锁返回值

CountDownLatchSemaphore区别和底层原

CountDownLatch表示计数可以给CountDownLatch设置⼀个数字,⼀个线程调⽤CountDownLatchawait()将会阻塞其他线程可以调CountDownLatchcountDown()来对CountDownLatch中的数字减⼀,当数字被减成0所有await的线程将被

正在上传…重新上传取消对应的底层原理就是调⽤await()法的线程会利AQS,⼀旦数字被减为0则会将AQS队的线程依次唤醒

Semaphore表示信号量可以设置许可的表示同时允许最多多少线程使该信号量通 过acquire()来获取许可如果没有许可可则线程阻塞并通过AQS可以通过release()

正在上传…重新上传取消法来释许可当某线程释了某许可后会从AQS中正在队的第⼀个线程开始依次唤 醒直到没有空闲许可

Sychronized偏向重量

  1. 偏向锁锁对象的对象头中记录⼀下当前获取到该锁的线程ID该线程次如果⼜来获取该锁就可以直接获取到了
  2. 量级锁由偏向锁升级⽽来⼀个线程获取到锁后此时把锁是偏向锁此时如果有第⼆线程来竞争锁偏向锁就会升级为量级锁之所以叫量级锁是为了和重量级锁区分开来量级锁底层是通过⾃旋来实现的会阻塞线程
  3. 如果⾃旋次数多仍然有获取到锁则会升级为重量级锁重量级锁会导致线程阻塞
  4. ⾃旋锁⾃旋锁就是线程获取锁的程中,不会去阻塞线程也就⽆所谓醒线程阻塞和两个步骤是需要操作系统去⾏的较消耗时间⾃旋锁是线程通过CAS获取预期的⼀个标记如果有获取到则继续循环获取如果获取到了则表示获取到了锁程线程在运

⾏中相对⽽⾔有使⽤太多的操作系统资较轻

SychronizedReentrantLock区别

  1. sychronized⼀个关键字ReentrantLock⼀个
  2. sychronized会⾃动的加锁释放锁ReentrantLock需要程序员⼿动加锁释放锁
  3. sychronized的底层是JVM层⾯的锁ReentrantLockAPI层⾯的锁
  4. sychronized是⾮公平锁ReentrantLock可以择公平锁或⾮公平锁
  5. sychronized锁的是对象锁信息保存对象头中ReentrantLock通过代码中intstate标识来标识锁的状态
  6. sychronized底层有⼀个锁升级的

谈谈AQS的理AQS

  1. AQS⼀个JAVA线程同步的框架JDK中很多锁⼯具的核⼼实现框架
  2. AQS维护了⼀个信号量state⼀个线程组成的双向链表队列其中线程队列就是⽤来给线程排队的state就像是⼀个红绿灯⽤来控制线程排队或者放⾏的。  同的下, ⽤的意义
  3. 可重⼊锁下,state就⽤来表示加锁的次数0标识⽆锁每加次锁state就加1放锁state就减1

正在上传…重新上传取消谈谈IOC的理

我们认为Spring⼤特性IoCAOP到底该如何理解IoC

对于很多初学者来说IoC概念给⼈的感觉就是我好但是我

IoC到底是什么来来说说我的理解实际⼀个⾮常⼤的问题所以我们就把它拆细了来IoC表示控制反

  1. 什么是控制控制了什么
  2. 什么是反之前是谁控制的之后是谁控制的如何控制的
  3. 为什么要反之前有什么问题之后有什么好处就是解决类⼤问题的思路⼤⽽化⼩

我们先来解决第⼀个问题什么是控了什么我们Spring的时候我们需要做什么

  1. 些类⽐如UserServiceOrderService
  2. ⽐如@Autowired

但是我们也知当程序⾏时⽤的是具体的UserService对象OrderService对象那这些对象是什么时候创建的谁创建的包括对象⾥的属性是什么时候赋的谁赋的所有是我们程序 员做的以为我们只是写了类⽽已所有的Spring做的它才是幕后⿊⼿

就是

  1. 控制对象的创建
  2. 控制对象内属性的赋

如果我们Spring我们得⾃⼰来做件事我们⽤Spring件事情就⽤我们做了我们要做的仅仅是定义类以及定义些属性需要Spring来赋⽐如某属性@Autowired),其实就是第⼆问题的答案就是反转表示种对象控

有什么⽤为什么要反

如果我们⾃⼰来负责创建对象⾃⼰来给对象中的属性赋会出现什么情况

⽐如三个

  1. 正在上传…重新上传取消AA类⾥有⼀个属性C c
  2. BB类⾥也有⼀个属性C c
  3. C

程序要三个类的对象需要创建出来相应的属性需要有么除开定义三个类之外我们得写

  1. A a = new A();
  2. B b = new B();
  3. C c = new C();
  4. a.c = c;
  5. b.c  = c;

五⾏代码是Spring的情况多出来的代码且,如果类类中的属性相应的代码会更多代码会更复杂所以我们可以发现我们⾃⼰来控制⽐交给Spring来控制我们 的代码量以及代码复杂度是要⾼很多的反⾔之将对象交给Spring来控制了程序员的负担

总结⼀下,IoC表示控制反表示如果⽤SpringSpring会负责来创建对象以及给对象内的属        性赋也就是如果⽤Spring么对象的控制权会交给Spring

Bean和单例模

单例模式表示JVM中某类的对象只会存在唯⼀⼀个

⽽单例Bean表示JVM中只能存在唯的某类的Bean对象

Spring

事务⽅相互调⽤时事务如何在这些⽅间传播A⼀个事务的⽅A执⾏程中调

⽤了⽅B么⽅B有⽆事务以及⽅B对事务的要求会对⽅A的事务具体执⾏成影响,   同时⽅A的事务对⽅B的事务执⾏也有影响种影响具体是什么就由两个所定义的事务传播类 所决定

  1. REQUIRED(Spring默认的事务传播类)如果当前有事务则⾃⼰新建⼀个事务如果当前存事务则加⼊事务
  2. SUPPORTS当前存事务则加⼊当前事务如果当前有事务就以⾮事务⽅执⾏
  3. MANDATORY当前存事务则加⼊当前事务如果当前事务则抛出异常
  4. REQUIRES_NEW创建⼀个新事务如果存当前事务则挂起该事务

  1. 正在上传…重新上传取消NOT_SUPPORTED以⾮事务⽅式执⾏,如果当前存事务则挂起当前事务
  2. NEVER:不使⽤事务如果当前事务存则抛出异常
  3. NESTED如果当前事务存嵌套事务中执⾏否则REQUIRED的操作开启⼀个事    

Spring什么时候会失效?

spring事务的原理是AOP⾏了切⾯增强么失效的根本原AOP起作⽤了常⻅情况有如⼏种

1发⽣⾃调⽤类⾥⾯使⽤this调⽤本类的⽅this常省略),此时this对象是代理类⽽是UserService对象本身

解决⽅很简单this变成UserService的代理类即可

2public@Transactional 只能⽤于 public 的⽅上,否则事务会失效如果要⽤

public 上,可以开启 AspectJ 代理模式3数据库⽀持事务

4有被spring管理

5异常被吃掉事务(或者抛出的异常有被定义默认为RuntimeException)

SpringBean创建的⽣命周期有哪些步

Spring⼀个Bean的创建⼤概分为以步骤

  1. 推断构
  2. 实例化
  3. 属性也就是依赖
  4. 处理Aware
  5. 初始化前处理@PostConstruct
  6. 初始化处理InitializingBean接⼝
  7. 初始化后AOP

当然其实真正的步骤更加细致可以看⾯的

正在上传…重新上传取消

SpringBean是线程安全

Spring本身并有针对Bean做线程安全的处理所以

  1. 如果Bean是⽆状态的Bean则是线程安全的
  2. 如果Bean是有状态的Bean是线程安全的

另外Bean是线程安全Bean的作⽤域有关系Bean的作⽤域只是表示Bean的⽣命周期范对于任何⽣命周期的Bean⼀个对象对象是是线程安全的是得看Bean对象本

ApplicationContextBeanFactory有什么区别

BeanFactorySpring中⾮常核⼼的组件表示Bean⼯⼚可以⽣成Bean维护BeanApplicationContext继承了BeanFactory所以ApplicationContext拥有BeanFactory所有的特点也是⼀个Bean⼯⼚但是ApplicationContext除开继承了BeanFactory之外继承了诸如EnvironmentCapableMessageSourceApplicationEventPublisher等接⼝从⽽ApplicationContext有获取系统环境变量际化事件发布等功能BeanFactory具备的

Spring现的

  1. 正在上传…重新上传取消Spring事务底层是基于数据库事务和AOP机制的
  2. ⾸先对于使⽤了@Transactional解的BeanSpring会创建⼀个代理对象作为Bean
  3. 当调⽤代理对象的⽅会先判断该⽅是否加了@Transactional
  4. 如果加了么则利⽤事务管理创建⼀个数据库
  5. 修改数据库接的autocommit属性为false禁⽌此接的⾃动提交是实现Spring事务⾮常重要的
  6. 然后执⾏当前⽅中会执⾏sql
  7. 执⾏完当前⽅如果有出现异常就直接提交事务
  8. 如果出现了异常异常是需要滚的就会滚事务否则仍然提交事务
  9. Spring事务的隔离级别对应的就是数据库的隔离级别
  10. Spring事务的传播机制是Spring事务⾃⼰实现的也是Spring事务中最复杂的
  11. Spring事务的传播机制是基于数据库接来做的,⼀个数据库⼀个事务如果传播机制置为需要新开⼀个事务么实际就是先建⽴⼀个数据库此新数据库执⾏sql

Spring中什么时候@Transactional失效

Spring事务是基于代理来实现的所以某加了@Transactional的⽅只有是被代理对象调⽤时解才会⽣效所以如果是被代理对象来调⽤@Transactional会失效的

同时如果某private@Transactional也会失效为底层cglib是基于⽗⼦类来实现 的⼦类是能重⽗类的private所以⽆很好的利⽤代理也会导致@Transactianal失效

Spring启动流程是

    1. 创建Spring也就是启动Spring
    2. ⾸先会⾏扫描扫描得到所有的BeanDefinition对象并存⼀个Map

    1. 正在上传…重新上传取消然后筛出⾮懒加的单例BeanDefinition⾏创建Bean对于多例Bean需要启动程中去

⾏创建对于多例Bean每次获取Bean时利⽤BeanDefinition去创建

    1. 利⽤BeanDefinition创建Bean就是Bean的创建⽣命周期期间包括了合并BeanDefinition推断构实例化属性填初始化前初始化初始化后等步骤其中AOP就是发⽣初始化    后步骤中
    2. 单例Bean创建完了之后Spring会发布⼀个启动事件
    3. Spring启动结束
    4. 在源码中会更复杂⽐如码中会提供些模板⽅让⼦类来实现⽐如码中还涉及到BeanFactoryPostProcessorBeanPostProcessorSpring的扫描就是通过BenaFactoryPostProcessor来实现的依赖⼊就是通过BeanPostProcessor来实现的
    5. Spring启动程中会去处理@Import

正在上传…重新上传取消Spring了哪些设计

Spring Boot解及其底层实

  1. @SpringBootApplication解标识了⼀个SpringBoot⼯程它实际是另外三个解的组合三个解是

    1. 正在上传…重新上传取消@SpringBootConfiguration解实际就是⼀个@Configuration表示启动类也是⼀个置类
    2. @EnableAutoConfigurationSpring中导⼊了⼀个Selector⽤来加ClassPathSpringFactories中所定义的⾃动置类些⾃动加Bean
    3. @ComponentScan标识扫描路径为默认是置实际扫描路径所以SpringBoot扫描的路径是启动类所的当前⽬录
  1. @Bean⽤来定义Bean类似于XML中的<bean>标签Spring启动时会对加了@Bean注  解的⽅法进⾏解析将⽅的名字做为beanName通过执⾏⽅得到bean对象
  2. @Controller@Service@ResponseBody@Autowired可以说

Spring Boot启动Tomcat

  1. ⾸先SpringBoot启动时会先创建⼀个Spring
  2. 创建Spring器过程中会利⽤@ConditionalOnClass技术来判断当前classpath中是否存Tomcat依赖如果存则会⽣成⼀个启动TomcatBean
  3. Spring创建完之后就会获取启动TomcatBean并创建Tomcat对象并绑定端⼝等然后启动Tomcat

Mybatis优缺点

优点

  1. 基于 SQL 语句编程相当灵,不会对应⽤程序或者数据库的现有设计成任何影响SQL XML 解除 sql 程序代码的耦合便于统管理提供 XML 标签⽀持编写动态 SQL 语句并可重⽤
  2. JDBC 相⽐减少了 50%的代码量除了 JDBC ⼤量冗余的代码,不需要⼿动开关
  3. 很好的各种数据库兼容 MyBatis 使⽤ JDBC 接数据库所以只要JDBC ⽀持的数据MyBatis ⽀持
  4. 能够Spring 很好的集成
  5. 提供映射标签⽀持对象数据库的 ORM 字段关系映射提供对象关系映射标签⽀持对象关系组件维护

缺点

  1. 正在上传…重新上传取消SQL 语句的编写⼯作量尤其当字段多关联表多时对开发⼈员编写SQL 语句的功底有定要求
  2. SQL 语句依赖于数据库导致数据库移植性差, 不能随意更换数据库

#{}${}区别是什么

#{}是预编译处理是占位符${}是字符串替换是拼接符

Mybatis处理#{}会将sql中的#{}替换为?调⽤ PreparedStatement 来赋Mybatis处理${}会将sql中的${}替换成变量的调⽤ Statement 来赋

使⽤#{}可以有效的防⽌ SQL 提⾼系统安全性

索引⽤来快速地寻找些具有特定的记录如果有索引,⼀般来说执⾏查询时历整张表索引的原理就是把⽆序的数据变成有序的查询

  1. 把创建了索引的列的内容⾏排序
  2. 对排序结果⽣成倒排表
  3. 倒排表内容数据地址
  4. 查询的时候先拿到倒排表内容再取出数据地址从⽽拿到具体数据

引设计原则

查询更快占⽤空间更⼩

  1. 合索引的列是出现where⼦句中的列或者接⼦句中指定的列
  2. 基数⼩的表索引效果有必要此列建⽴索引

  1. 正在上传…重新上传取消使⽤短索引如果对⻓字符串列⾏索引应该指定⼀个前缀⻓度样能够节省⼤量索引空间如果搜索词超索引前缀⻓度则使⽤索引排除的⾏然后检查其余⾏是否可能匹
  2. 度索引索引需要额外的磁盘空间并降低写操作的性能修改表内容的时候索引会

⾏更新甚⾄重构索引列越多时间就会越⻓所以只保持需要的索引有利于查询即可

  1. 定义有外键的数据列定要建⽴索引
  2. 更新频繁字段合创建索引
  3. 若是能有效区分数据的列合做索引列(如性别男⼥未知最多也就区分度实太低)
  4. 尽量的扩展索引,不要新建索引⽐如表中已经有a的索引要加(a,b)的索引么只需要修改原来的索引即可
  5. 对于些查询中很少及的列重复多的列要建⽴索引
  6. 对于定义为textimagebit的数据类的列要建⽴索引

本特性和隔离级

事务基本特性ACID分别是

⼦性指的是⼀个事务中的操作要么全成功要么全失败

性指的是数据库总是从⼀个⼀致性的状态换到另外⼀个⼀致性的状态⽐如A账给B100假设A只有90⽀付之前我们数据库⾥的数据是符合约束的,但是如果事务执⾏成功了,我们的数据库 数据就破约束了,此事务能成功,⾥我们说事务提供了致性的保证

隔离性指的是⼀个事务的修改最终提交前对其他事务是可⻅的持久性指的是旦事务提交所做的修改就会永久保存到数据库中。  隔离性有4隔离级别分别是

  • read uncommit 读未提交可能会读到其他事务未提交的数据也叫做脏读

⽤户本来应该读取到id=1的⽤户age应该是10结果读取到了其他事务还没有提交的事务结果读取结果age=20就是脏读

  • read commit 读已提交,两次读取结果不⼀叫做可重复读可重复读解决了脏读的问题他只会读取已经提交的事务

⽤户开启事务读取id=1⽤户查询到age=10再次读取发现结果=20⼀个事务⾥同⼀个查询读取到同的结果叫做可重复读

  • 正在上传…重新上传取消repeatable read 可重复复读mysql的默认级别就是每次读取结果但是有可能产

⽣幻读

  • serializable 串⾏,⼀般是会使⽤的他会给每⾏读取的数据加锁会导致⼤量超时和锁竞争的问题

什么是MVCC

MVCCMulti-Version Concurrency Control 多 版 本 并 发 控 制 指 的 就 是 使 ⽤ READ COMMITTDREPEATABLE    READ种隔离级别的事务执⾏普SEELCT操作时访问记录的版本链的可以使同事务的读--读操作并发执⾏从⽽提升系统性能READ

COMMITTDREPEATABLE     READ两个隔离级别的⼀个很⼤同就是⽣成ReadView的时机READ COMMITTD⾏普SELECT操作前会⽣成⼀个ReadViewREPEATABLE READ⾏普SELECT操作前⽣成⼀个ReadView之后的查询操作重复使⽤ReadView就好了

简述MyISAMInnoDB区别

MyISAM

  • ⽀持事务但是每次查询是原⼦的
  • ⽀持表级锁即每次操作是对整表加锁
  • 存储表的总⾏数
  • ⼀个MYISAM表有三个⽂件索引⽂件表结构⽂件数据⽂件
  • 采⽤⾮聚集索引索引⽂件的数据域存储指向数据⽂件的指针索引主索引基本但是索引⽤保证

InnoDb

  • ⽀持ACID的事务⽀持事务的种隔离级别
  • ⽀持⾏级锁及外键约束此可以⽀持写并发
  • 存储总⾏数
  • ⼀个InnoDb引擎存储⼀个⽂件空间共享表空间表⼤⼩受操作系统控制,⼀个表可能分布⽂件⾥),也有可能为多个(设置为独⽴表空表⼤⼩受操作系统⽂件⼤⼩限制,⼀般为2G),受操作系统⽂件⼤⼩的限制

  • 正在上传…重新上传取消主键索引采⽤聚集索引索引的数据域存储数据⽂件本身),索引的数据域存储主键的

索引查找数据需要先通过辅索引找到主键再访问索引最好使⽤⾃增主键防⽌插⼊ 数据时为维持B+树结构⽂件的⼤调整

Explain语句结果中分表表示什么

列名

id

查询语句中每出现⼀个SELECT关键字MySQL 就会为它分⼀个id某些⼦查询会被优化为join查询么出现的id

select_type

SELECT关键字对应的查询的类

table

表名

partitions

的分区信息

type

针对单表的查询⽅式全表扫描索引

possible_keys

可能⽤到的索引

key

实际使⽤的索引

key_len

实际使⽤到的索引⻓度

ref

当使⽤索引列等查询时,与索引列⾏等的对象信息

rows

预估的需要读取的记录条数

filtered

表经搜索条件滤后剩余记录条数的百分

Extra

些额外的信息⽐如排序等

引覆是什么

索引覆盖就是⼀个SQL执⾏时可以利⽤索引来快查找SQL所要查询的字段当前索引对应的字段中包含了么就表示此SQL⾛完索引后表了所需要的字段都在当前索引的叶⼦节点可以直接作为结果返回

正在上传…重新上传取消左前原则是什么

⼀个SQL想要利⽤索引是定要提供该索引所对应的字段中最左的字段也就是排最前⾯的 字段⽐如针对a,b,c三个字段建⽴了⼀个联合索引⼀个sql时就定要提供a字段的条件样才能⽤到联合索引是由于建⽴a,b,c三个字段的联合索引时底层的B+树是按照a,b,c三个字段 从左往右去⽐⼤⼩⾏排序的所以如果想要利⽤B+⾏快查找也得符合规则

Innodb

Innodb通过Buffer PoolLogBufferRedo LogUndo Log来实现事务⼀个update语句为例

    1. Innodb收到⼀个update语句后会先根据条件找到数据所的⻚并将该⻚缓存Buffer Pool
    2. 执⾏update语句修改Buffer Pool中的数据也就是内存中的数据
    3. 针对update语句⽣成⼀个RedoLog对象并存⼊LogBuffer
    4. 针对update语句⽣成undolog⽇志⽤于事务
    5. 如果事务提交么则把RedoLog对象⾏持久化后续有其他机制将Buffer Pool中所修改的数据⻚持久化到磁盘中
    6. 如果事务则利⽤undolog⽇志

BB+区别为什么Mysql使B+

B树的特点

  1. 节点排序
  2. ⼀个节点了可以存多元素元素也排序了

B+树的特点

  1. 拥有B树的特点
  2. 叶⼦节点之间有指针
  3. ⾮叶⼦节点的元素叶⼦节点冗余了也就是叶⼦节点中存储了所有的元素排好顺序

Mysql索引使⽤的是B+为索引是⽤来加快查询的B+通过对数据⾏排序所以是可以提⾼查询度的然后通过⼀个节点中可以存储多元素从⽽可以使得B+树的⾼度会太⾼MysqlInnodb⻚就是⼀个B+树节点,⼀个Innodb⻚默认16kb所以般情况下⼀层的B+树可以存2000

正在上传…重新上传取消⾏左右的数据然后通过利⽤B+树叶⼦节点存储了所有数据并⾏了排序叶⼦节点之间有指针可以很好的⽀持全表扫描查找等SQL语句

Mysql有哪些

按锁粒度分类

  1. ⾏锁锁某⾏数据锁粒度最⼩并发度⾼
  2. 表锁锁整张表锁粒度最⼤并发度低
  3. 间隙锁锁的是⼀个区间

可以分为

  1. 共享锁也就是读锁,⼀个事务给某⾏数据加了读锁其他事务也可以读但是能写
  2. 排它锁也就是写锁,⼀个事务给某⾏数据加了写锁其他事务能读能写

可以分为

  1. 乐观锁会真正的去锁某⾏记录⽽是通过⼀个版本号来实现的
  2. 悲观锁:上⾯所的⾏锁表锁等是悲观锁

事务的隔离级别实现中就需要利⽤锁来解决幻读

Mysql询该如何优

  1. 检查是否⾛了索引如果有则优化SQL利⽤索引
  2. 检查所利⽤的索引是否是最优索引
  3. 检查所查字段是否是必须的是否查询了多字段查出了多余数据
  4. 检查表中数据是否是否应该⾏分库分表了
  5. 检查数据库实例所的性能是否太低是否可以当增加资

什么是RDBAOF

正在上传…重新上传取消RDBRedis      DataBase指定的时间间隔内将内存中的数据集快照写⼊磁盘实际操作程是fork⼀个先将数据集写⼊临时⽂件写⼊成功后再替换之前的⽂件⽤⼆制压缩存储

优点

  1. Redis数据库将只包含⼀个⽂件 dump.rdb⽅便持久化
  2. 容灾性好⽅便备份
  3. 性能最⼤化fork 程来完成写操作让主程继续处理命令所以是 IO 最⼤化使⽤单独⼦程来⾏持久化⾏任何 IO 操作保证了 redis 的⾼性能
  4. 相对于数据集⼤时AOF 的启动效率更⾼

  1. 数据安全性低RDB 是间隔段时间⾏持久化如果持久化之间 redis 发⽣故障会发⽣数据所以种⽅式更合数据要求不严谨的时候)
  2. 由于RDB通过fork程来协助完成数据持久化⼯作的如果当数据集⼤时可能会导致整服务停⽌服务⼏百毫秒甚⾄是1秒钟

AOFAppend Only File以⽇志的形式记录服务所处理的每⼀个删除操作查询操作会记以⽂本的⽅式记录可以打开⽂件看到详细的操作记录

优点

  1. 数据安全Redis中提供了3中同步策略即每秒同步每修改同步和同步事实上,每秒同步也是异步完成的其效率也是⾮常⾼的所差的是旦系统出现宕机现象秒钟之内修改的 数据将会⽽每修改同步我们可以将其视为同步持久化即每次发⽣的数据变化会被⽴即  记录到磁盘中。。
  2. 通过 append 模式写⽂件即使中服务宕机也会破已经存的内容可以通过 redis- check-aof ⼯具解决数据致性问题
  3. AOF 机制的 rewrite 模式定期对AOF⽂件⾏重写到压缩的⽬的

  1. AOF ⽂件⽐ RDB ⽂件⼤,且恢复度慢
  2. 数据集⼤的时候rdb 启动效率低
  3. ⾏效率RDB

AOF⽂件⽐RDB更新频率⾼优先使⽤AOF原数据AOFRDB更安全也更⼤RDB性能⽐AOF,   如果两个都配了优先加AOF

正在上传…重新上传取消Redis过期删除

Rediskey-value数据库我们可以设置Redis中缓存的key期时间Redis期策略就是指当Redis中缓存的key期了Redis如何处理

  • 过期只有当访问⼀个key才会判断该key是否已期则该策略可以最⼤化节省CPU却对内存⾮常友好极端情况可能出现⼤量的key有再次被访问从⽽不  会被占⽤⼤量内存
  • 期过期每隔定的时间会扫描定数量的数据库的expires字典中定数量的key除其  中已期的key该策略是⼀个折中⽅案通过调整定时扫描的时间间隔和每次扫描的限定耗时可 以同情况使得CPU和内存资源达到最优的平衡效果

(expires字典会保存所有设置了期时间的key期时间数据其中key是指向键空间中的某键的         指针value是该键的毫秒精度的UNIX时间戳表示的期时间键空间是指该Redis集群中保存的所有          键)

Redis中同时使⽤了惰性期和定期期策略

简述Redis务实

1务开

MULTI命令的执⾏标识着⼀个事务的开始MULTI命令会将客户端状态的 flags 属性中打开

REDIS_MULTI 标识来完成的2命令

⼀个客户端切换到事务状态之后服务会根据客户端发来的命令来执⾏同的操作如果客 户端发的命令为MULTIEXECWATCHDISCARD中的⼀个,⽴即执⾏命令否则将命令放

⼀个事务队列⾥⾯然后向客户端返回 QUEUED 

  • 如果客户端发的命令为 EXECDISCARDWATCHMULTI 命令的其中⼀个,么服务⽴即执⾏命令
  • 如果客户端发的是命令以外的其他命令么服务⽴即执⾏命令

⾸先检查此命令的格式是否正确如果正确服务客户端状态redisClientflags

正在上传…重新上传取消性关闭 REDIS_MULTI 标识返回错误信息给客户端

如果正确命令放⼊⼀个事务队列⾥⾯然后向客户端返回 QUEUED 复事务队列是按照FIFO的⽅式保存⼊队的命令

3

客户端发EXEC 命令服务执⾏ EXEC 命令逻辑

  • 如果客户端状态的 flags 属性包含 REDIS_MULTI 标识或者包含 REDIS_DIRTY_CAS 或者REDIS_DIRTY_EXEC 标识么就直接取事务的执⾏
  • 否则客户端处于事务状态flags REDIS_MULTI 标识),服务历客户端的事务队列然后执⾏事务队列中的所有命令最后将返回结果全部返回给客户端

redis ⽀持事务滚机制但是它会检查每⼀个事务中的命令是否错误

Redis 事务⽀持检查些程序员⾃⼰逻辑错误例如对 String 的数据库键执⾏对 HashMap 的操作

  • WATCH 命令是⼀个乐观锁可以为 Redis 事务提供 check-and-set CAS⾏为可以监控⼀个或多,⼀旦其中有⼀个键被修改或删除),之后的事务就会执⾏监控直持续到EXEC 命令
  • MULTI命令⽤于开启⼀个事务它总是返回OKMULTI执⾏之后客户端可以继续向服务任意多条命令些命令会⽴即被执⾏⽽是被放到⼀个队列中EXEC命令被调⽤时所有队列中的命令才会被执⾏
  • EXEC执⾏所有事务内的命令返回事务内所有命令的返回值按命令执⾏的先后顺序排列当操作被打断时返回nil 
  • 通过调⽤DISCARD客户端可以空事务队列并放弃执⾏事务客户端会从事务状态中退

  • UNWATCH命令可以取watch对所有key的监控

Redis 主从复制⼼原

通过执⾏slaveof命令或设置slaveof⼀个服务去复制另⼀个服务的数据主数据库可以

⾏读写操作当写操作导致数据变化时会⾃动将数据同步给从数据库⽽从数据库般是只读的并接

正在上传…重新上传取消受主数据库同步来的数据⼀个主数据库可以拥有多从数据库⼀个从数据库只能拥有⼀个主数

据库

全量复制

  1. 主节点通过bgsave命令forkRDB持久化程是⾮常CPU内存(⻚表复制)IO
  2. 主节点通过⽹络将RDB⽂件发给从节点对主从节点的带宽会带来很⼤的
  3. 从节点空⽼数据⼊新RDB⽂件的程是阻塞的响应客户端的命令如果从节点执⾏bgrewriteaof也会带来额外的

分复制

  1. 复制偏移量执⾏复制的双⽅主从节点分别会维护⼀个复制偏移量offset
  2. 复制积压缓冲区主节点内维护了⼀个定⻓度的先出(FIFO)队列 作为复制积压缓冲区当主从节点offset的差距⼤超缓冲区⻓度时将⽆执⾏分复制只能执⾏全量复制
  3. 服务器运ID(runid)Redis节点有其IDID由节点启动时⾃动⽣成主节点会将⾃⼰的ID给从节点从节点会将主节点的ID存起来从节点Redis断开重的时

就是根据ID来判断同步的

    • 如果从节点保存的runid主节点现runid相同说明主从节点之前同步主节点会继续尝试使⽤分复制(到底能分复制要看offset和复制积压缓冲区的情况)
    • 如果从节点保存的runid主节点现runid说明从节点断线前同步的Redis节点并是当前的主节点只能⾏全量复制

Redis有哪些数据结构分别有哪些场景

Redis的数据结构有

  1. 字符串可以⽤来做最简单的数据可以缓存某简单的字符串也可以缓存某json格式的字符 串Redis分布式锁的实现就利⽤了种数据结构包括可以实现计数Session共享分布式ID
  2. 哈希表可以⽤来存储key-value合⽤来存储对象
  3. 列表Redis的列表通过命令的组合既可以当做栈也可以当做队列来使⽤可以⽤来缓存类似微信公众号微博等数据
  4. 集合和列表类似也可以存储多元素但是能重复集合可以⾏交集并集差集操作从⽽可以实现类似我和某⼈共同关的⼈朋友点赞等功能
  5. 有序集合集合是⽆序的有序集合可以设置顺序可以⽤来实现排⾏榜功能

正在上传…重新上传取消Redis分布式底层现的

  1. ⾸先利⽤setnx来保证如果key才能获取到锁如果key则获取到锁
  2. 然后要利⽤lua脚本来保证多redis操作的原⼦性
  3. 同时要考到锁所以需要额外的⼀个看⻔狗定时任务来监听锁是否需要续约
  4. 同时要考redis节点挂掉后的情况所以需要采⽤红锁的⽅式来同时向N/2+1节点申请锁申请到了才证明获取锁成功样就算其中某redis节点挂掉了锁也能被其他客户端获取到

Redis主从复制⼼原

Redis的主从复制是提⾼Redis的可靠性的有效措施主从复制的程如下:

  1. 集群启动时主从库间会先建⽴为全量复制做准备
  2. 主库将所有数据同步给从库从库收到数据后完成数据加程依赖于内存快照RDB
  3. 在主库将数据同步给从库的过程中,主库不会阻塞,仍然可以正常接收请求。否则,redis的服务就被中断 了。但是,这些请求中的写操作并没有记录到刚刚⽣成的RDB⽂件中。为了保证主从库的数据⼀致性,主     库会在内存中⽤专⻔的replication buffer,记录RDB⽂件⽣成收到的所有写操作。
  4. 最后,也就是第三个阶段,主库会把第⼆阶段执⾏过程中新收到的写命令,再发送给从库。具体的操作

是,当主库完成RDB⽂件发送后,就会把此时replocation buffer中修改操作发送给从库,从库再执⾏这些操作。这样⼀来,主从库就实现同步了

  1. 后续主库和从库都可以处理客户端读操作,写操作只能交给主库处理,主库接收到写操作后,还会将写操作发送给从库,实现增量同步

Redis集群

Redis提供了种集群策略

  1. 主从模式种模式⽐简单主库可以读写会和从库⾏数据同步种模式下,客户端直接主库或某从库但是但主库或从库宕机后客户端需要⼿动修改IP另外种模式也⽐⾏扩容集群所能存储的数据受到某台机的内存容量所以可能⽀持特⼤数据量
  2. 哨兵模式种模式主从的基础新增了哨兵节点但主库节点宕机后哨兵会发现主库节点宕            机然后从库中⼀个库作为的主库另外哨兵也可以做集群从⽽可以保证但某⼀个哨兵            节点宕机后有其他哨兵节点可以继续⼯作种模式可以⽐好的保证Redis集群的⾼可⽤但         是仍然能很好的解决Redis的容量限问题
  3. Cluster模式Cluster模式是⽤得⽐多的模式它⽀持多主多从种模式会按照key⾏槽位的 分可以使得同的key分散到同的主节点上,利⽤种模式可以使得整集群⽀持更⼤的数据

正在上传…重新上传取消容量同时每主节点可以拥有⾃⼰的多从节点如果该主节点宕机会从它的从节点中⼀个新的主节点

对于种模式如果Redis要存的数据量可以择哨兵模式如果Redis要存的数据量⼤需要持续的扩容Cluster模式

正在上传…重新上传取消穿透 存击穿 存雪崩分别是什么

缓存中存放的⼤多是热点数据⽬的就是防⽌请求可以直接从缓存中获取到数据⽤访问Mysql

  1. 缓存雪崩如果缓存中某时刻⼤批热点数据同时么就可能导致⼤量请求直接访问Mysql   解决办就是在过期时间增加点随机另外如果搭建⼀个⾼可⽤的Redis集群也是防⽌缓存雪崩的有效⼿段
  2. 缓存击穿和缓存雪崩类似缓存雪崩是⼤批热点数据失效⽽缓存击穿是指某⼀个热点key突然失效也导致了⼤量请求直接访问Mysql数据库就是缓存击穿解决⽅案就是考虑这热点key期时间
  3. 缓存穿假如某时刻访问redis的⼤量key都在redis⽐如⿊客故意伪些乱⼋糟 的key),么也会给数据成压⼒就是缓存穿解决⽅案是使⽤布隆它的作⽤就是如果它认为⼀个keykey就肯定所以可以缓存之前加层布隆来 拦截key

RedisMysql何保证数据

  1. 先更新Mysql再更新Redis如果更新Redis失败可能仍然不⼀
  2. 先删除Redis缓存数据再更新Mysql再次查询的时候将数据加到缓存中种⽅案能解决1

⽅案的问题但是⾼并发性能仍然会出现数据不⼀致的问题⽐如线程1删除了   Redis缓存数据更新Mysql此时另外⼀个查询再查询么就会把Mysql中⽼数据⼜查到Redis

  1. 延时双删步骤是先删除Redis缓存数据再更新Mysql⼏百毫秒再删除Redis缓存数据样就算更新Mysql有其他线程读了Mysql把⽼数据读到了Redis么也会被删除掉从⽽把数据保持

Redis

RDBRedis DataBase 将某⼀个时刻的内存快照Snapshot),以⼆制的⽅式写⼊磁盘

⼿动触发

  • 正在上传…重新上传取消save命令使 Redis 处于阻塞状态直到 RDB 持久化完成才会响应其他客户端发来的命令

⽣产环境定要慎⽤

  • bgsave命令fork⼀个程执⾏持久化程只fork程中有短暂的阻塞程创建之后程就可以响应客户端请求了
  • ⾃动触发
  • save m n m 秒内如果有 n 键发⽣改变则⾃动触发持久化通过bgsave执⾏如果设置只要满⾜其就会触发置⽂件有默认(可以释掉)
  • flushall⽤于redis所有的数据库flushdb空当前redis库数据(默认是0号数据库)RDB⽂件同时也会⽣成dump.rdb内容为空
  • 主从同步全量同步时会⾃动触发bgsave命令⽣成rdb给从节点

优点

  1. Redis数据库将只包含⼀个⽂件 dump.rdb⽅便持久化
  2. 容灾性好⽅便备份
  3. 性能最⼤化fork 程来完成写操作让主程继续处理命令所以是 IO 最⼤化使⽤单独⼦程来⾏持久化⾏任何 IO 操作保证了 redis 的⾼性能
  4. 相对于数据集⼤时AOF的启动效率更⾼缺点
  1. 数据安全性低RDB 是间隔段时间⾏持久化如果持久化之间 redis 发⽣故障会发⽣数据所以种⽅式更合数据要求不严谨的时候)
  2. 由于RDB通过fork程来协助完成数据持久化⼯作的如果当数据集⼤时可能会导致整服务停⽌服务⼏百毫秒甚⾄是1秒钟会占⽤cpu

AOFAppend Only File 以⽇志的形式记录服务所处理的每⼀个删除操作查询操作会记录以⽂本的⽅式记录可以打开⽂件看到详细的操作记录调操作系统命令程刷盘

  1. 所有的写命令会加到 AOF 缓冲中
  2. AOF 缓冲区根据对应的策略向硬盘⾏同步操作
  3. 随着 AOF ⽂件越来越⼤需要定期对 AOF ⽂件⾏重写到压缩的⽬的
  4. Redis 重启时可以加AOF ⽂件⾏数据恢复同步策略

每秒同步异步完成效率⾮常⾼,⼀旦系统出现宕机现象秒钟之内修改的数据将会丢    失每修改同步同步持久化每次发⽣的数据变化会被⽴即记录到磁盘中最多丢⼀同步由操作系统控制可能多数据

优点

  1. 数据安全

  1. 正在上传…重新上传取消通过 append 模式写⽂件即使中服务宕机也会破已经存的内容可以通过 redis- check-aof ⼯具解决数据致性问题
  2. AOF 机制的 rewrite 模式定期对AOF⽂件⾏重写到压缩的⽬的缺点
  1. AOF ⽂件⽐ RDB ⽂件⼤,且恢复度慢
  2. 数据集⼤的时候rdb 启动效率低
  3. ⾏效率RDB

对⽐

  • AOF⽂件⽐RDB更新频率⾼优先使⽤AOF原数据AOFRDB更安全也更⼤
  • RDB性能⽐AOF
  • 如果两个都配了优先加AOF

Redis线程为什么这么

Redis基于Reactor模式开发了⽹络事件处理⽂件事件处理fileeventhandler它是单线程的所以 Redis才叫做单线程的模它采⽤IO多路复⽤机制来同时监听多Socket根据Socket的事件类择对应的事件处理来处理事件可以实现⾼性能的⽹络信模⼜可以跟内其他单

线程的模块进⾏对接保证了 Redis的线程模的简单性

⽂件事件处理的结构包含4SocketIO多路复⽤程序⽂件事件分派器以及事件处理

命令请求处理命令复处理接应答处理

Socket 可能并发的产⽣同的事件IO多路复⽤程序会监听多Socket会将 Socket 放⼊⼀个队列中排队每次从队列中有序同步取出⼀个 Socket 给事件分派器事件分派器Socket 给对应 的事件处理

然后⼀个 Socket 的事件处理完之后IO多路复⽤程序才会将队列中的下⼀个 Socket 给事件分派器

⽂件事件分派器会根据每Socket 当前产⽣的事件择对应的事件处理来处理

  1. Redis启动初始化时接应答处理AE_READABLE事件关联
  2. ⼀个客户端发起会产⽣⼀个AE_READABLE事件然后由接应答处理负责和客户端建

创建客户端对应的socket同时将socketAE_READABLE事件和命令请求处理     关联使 得客户端可以向主服务命令请求

  1. 当客户端向Redis发请求时(不管读是写请求),客户端socket会产⽣⼀个AE_READABLE事    触发命令请求处理处理读取客户端的命令内容然后传给相关程序执⾏
  2. Redis服务准备好给客户端的响应数据后会将socketAE_WRITABLE事件和命令复处理关联当客户端准备好读取响应数据时socket产⽣⼀个AE_WRITABLE事件由对应命令

正在上传…重新上传取消复处 理处理即将准备好的响应数据写⼊socket供客户端读取

  1. 命令复处理写完到 socket 就会删除该socketAE_WRITABLE事件和命令复处理的映射

单线程快的原

  1. 纯内存操作
  2. 核⼼是基于⾮阻塞的IO多路复⽤机制
  3. 单线程反⽽免了多线程的频繁上下⽂切换带来的性能问题

简述Redis务实

  • 事务开始MULTI命令的执⾏标识着⼀个事务的开始MULTI命令会将客户端状态的 flags属性中打开REDIS_MULTI标识来完成的
  • 命令⼊队⼀个客户端切换到事务状态之后服务会根据客户端发来的命令来执⾏同  的操作如果客 户端发的命令为MULTIEXECWATCHDISCARD中的⼀个,⽴即执⾏命令否则将命令放⼊ 事务队列⾥⾯然后向客户端返回QUEUED如果客户端发的命令为 EXECDISCARDWATCHMULTI 命令的其中⼀个,么服务⽴即执⾏命令如果客户端发的是命令以外的其他命令么服务⽴即执⾏命令⾸先检查   此命令的格式是否正确如果正确服务客户端状态redisClient flags 属性关闭REDIS_MULTI 标识返回错误信息给客户端如果正确命令放⼊⼀个事务队列⾥

然后向客户端返回 QUEUED 复事务队列是按照FIFO的⽅式保存⼊队的命令

  • 事务执⾏客户端发EXEC 命令服务执⾏ EXEC 命令逻辑如果客户端状态的 flags 属性包含 REDIS_MULTI 标识或者包含 REDIS_DIRTY_CAS 或者REDIS_DIRTY_EXEC 标识么就直接取事务的执⾏否则客户端处于事务状态flagsREDIS_MULTI  标识),服务历客户端的事务队列然后执⾏事务队列中的所有命令最后将返回结果全部返回给客户端Redis

⽀持事务滚机制但是它会检查每⼀个事务中的命令是否错误Redis事务⽀持检查些程序员

⾃⼰逻辑错误例如对 String 的数据库键执⾏对 HashMap 的操作

什么是CAP

CAP理论是分布式领域中⾮常重要的⼀个指导理论CConsistency表示强致性A

Availability表示可⽤性PPartition Tolerance表示分区容错性CAP理论指出⽬前的硬件

正在上传…重新上传取消条件下,⼀个分布式系统是必须要保证分区容错性的在这前提下,分布式系统要么保证CP要么保证AP同时保证CAP

分区容错性表示,⼀个系统然是分布式的但是对外看去应该是⼀个整体,不能由于分布式系统内的某结点挂点或⽹络出现了故障⽽导致系统对外出现异常所以对于分布式系统⽽⾔是定 要保证分区容错性的

致性表示,⼀个分布式系统中各结点之间能及时的同步数据数据同步程中能对外提供服务的,不然就会成数据不⼀所以强致性和可⽤性是能同时满⾜的

可⽤性表示,⼀个分布式系统对外要保证可⽤

什么是BASE

由于能同时满⾜CAP所以出现了BASE理论

  1. BABasically Available表示基本可⽤表示可以定程度的可⽤⽐如由于系统故障请求时间变⻓或者由于系统故障导致分⾮核⼼功能可⽤许的
  2. SSoft state表示分布式系统可以处于种中间状态⽐如数据正同步
  3. EEventually consistent表示最终致性,不要求分布式系统数据实时段时间后再在达程中系统也是可⽤的

什么是RPC

RPC表示程调⽤对于Java种⾯试对象语⾔也可以理解为程⽅调⽤RPC调⽤和HTTP调⽤是有区别的RPC表示的是种调⽤程⽅的⽅式可以使⽤HTTP协议或直接基于TCP 协议来实现RPCJava我们可以通过直接使⽤某服务接⼝的代理对象来执⾏⽅⽽底层则通过HTTP请求来调⽤端的⽅所以种说RPC协议是HTTP协议之种协议也是可以理解的

数据致性模型有哪些

  • 致性当更新操作完成之后任何多后续程的访问返回最新的更新种是对

⽤户 最友好的就是⽤户上⼀次写什么,下⼀次就保证能读到什么根据  CAP理论种实现需要牺牲可⽤性

  • 致性系统数据写⼊成功之后,不承诺⽴即可以读到最新写⼊的会具体的承诺多久 之后 可以读到⽤户读到某操作对系统数据的更新需要段时间我们称段时间为不⼀致性

正在上传…重新上传取消窗⼝

  • 最终致性最终致性是弱致性的特例强调的是所有的数据副本段时间的同步之,   最终能够⼀个⼀致的状态最终致性的本质是需要系统保证最终数据能够⽽  需要实时保证系统数据的强致性最终致性的时间   就是不⼀致窗⼝时在没有故障发⽣的前提下,不⼀致窗⼝的时间主要受信延系统负和复制副本的数影最终致性模根据其提供的同保证可以划分为更多的模包括致性和会话致性

分布式ID是什么有哪些解决⽅

开发中我们常会需要⼀个ID来标识数据如果是单体架构我们可以通过数据库的主键或直接内存中维护⼀个⾃增数字来作为ID是可以的但对于⼀个分布式系统就会有可能会出现ID冲突此时有以解决⽅案

  1. uuid种⽅案复杂度最低但是会影响存储空间和性能
  2. 利⽤单机数据库的⾃增主键作为分布式ID的⽣成复杂度ID⻓度uuid更短但是受到单机数据库性能的限制并发量⼤的时候此⽅案也是最优⽅案
  3. 利⽤rediszookeeper的特性来⽣成id⽐如redis的⾃增命令zookeeper的顺序节点种⽅案和单机数据库(mysql)相⽐性能有所提⾼可以
  4. 雪花算,⼀切问题如果能直接⽤算解决就是最合利⽤雪花算也可以⽣成分布式 ID底层原理就是通过某台机器在毫秒内对某⼀个数字⾃增种⽅案也能保证分布式架构中的系统id⼀,但是只能保证趋势界存tinyidleaf等开中间件实现了雪花算

分布式使场景是什么有哪些

单体架构中线程是属于同⼀个程的所以线程并发执⾏时到资竞争时可以利⽤ReentrantLocksynchronized等技术来作为锁来控制共享资的使⽤

分布式架构中线程是可能处于程中的些线程并发执⾏到资竞争时利⽤ReentrantLocksynchronized等技术是来控制多程中的线程的所以需要分布式锁意思就是需要⼀个分布式锁⽣成分布式系统中的应⽤程序可以来使⽤⽣成所提供的锁从⽽ 到多程中的线程使⽤同把锁

⽬前主的分布式锁的实现⽅案有

  1. 正在上传…重新上传取消zookeeper利⽤的是zookeeper的临时节点顺序节点watch机制来实现的zookeeper分布式锁的特点是⾼致性zookeeper保证的是CP所以由它实现的分布式锁更可靠,不会出现
  2. redis利⽤redissetnxlua脚本费订阅等机制来实现的redis分布式锁的特点是⾼可⽤redis保证的是AP所以由它实现的分布式锁可能可靠,不稳定(⼀redis中的数据出现了不⼀),可能会出现多客户端同时加到锁的情况

什么是分布式有哪些

分布式系统中,⼀务处理可能需要多应⽤来实现⽐如⽤户发单请求及到订单系统创建订单库存系统减库存⽽对于订单创建减库存应该是要同时成功或同时失败     的分布式系统中如果做处理就很有可能出现订单创建成功但是减库存失败么解决类问题就需要⽤到分布式事务常⽤解决⽅案有

  1. 地消息表创建订单时将减库存息加⼊事务中,⼀起提交到数据库存⼊本地消息表然后调⽤库存系统如果调⽤成功则修改本地消息状态为成功如果调⽤库存系统失败则由后台 定时任务从本地消息表中取出未成功的重试调⽤库存系统
  2. 息队列⽬前RocketMQ中⽀持事务它的⼯作原理是
    1. ⽣产者订单系统先发half息到Brokerhalf息对费者⽽⾔是可⻅的
    2. 再创建订单根据创建订单成功Brokercommitrollback
    3. ⽣产者订单系统可以提供Broker调接⼝Broker发现段时间half有收到任何操作命令则会主动调此接⼝来查询订单是否创建成功
    4. halfcommit费者库存系统就会来如果费成功息销毁分布式事务成功结束
    5. 如果费失败则根据重试策略⾏重试最后失败则⼊死信队列等待步处理
  3. Seata阿⾥开的分布式事务框架⽀持ATTCC等多种模式底层是基于阶段提交理论来实现的

什么是ZAB协议

ZAB协议是Zookeeper⽤来实现致性的原⼦⼴播协议该协议描Zookeeper是如何实现致性的分为三个阶段

  1. 领导者举阶段Zookeeper集群中⼀个节点作为Leader所有的写请求会由Leader节点来处理
  2. 数据同步阶段集群中所有节点中的数据要和Leader节点保持如果不⼀致则要⾏同步
  3. 请求⼴播阶段Leader节点接收到写请求时会利⽤阶段提交来⼴播该写请求使得写请求像事务其他节点执⾏到节点的数据实时

正在上传…重新上传取消意的是Zookeeper只是尽量的在达到强致性实际仍然只是最终致性的

为什么Zookeeper来作为注

可以利⽤Zookeeper的临时节点和watch机制来实现册中⼼的⾃动册和发现另外Zookeeper中的  数据是存内存中的Zookeeper底层采⽤了nio多线程模所以Zookeeper的性能也是⽐

⾼的所以可以⽤来作为册中⼼但是如果考册中⼼应该是册可⽤性的话Zookeeper 太合ZookeeperCP重的是致性所以集群数据不⼀致时集群将可⽤所以⽤RedisEurekaNacos来作为册中⼼将更合

Zookeeper领导者选举流程是

对于Zookeeper集群集群需要从集群节点中⼀个节点作为Leader⼤体程如下:

  1. 集群中各节点⾸先是观望状态LOOKING),⼀开始会投票给⾃⼰认为⾃⼰⽐较适合作为leader
  2. 然后相互交互投票节点会收到其他节点发来的然后pk先⽐zxidzxid⼤者获胜zxid如果相等则⽐myidmyid⼤者获胜
  3. ⼀个节点收到其他节点发来的PK如果PK则改票此节点就会投给zxidmyid更⼤的节点并将票放⼊⾃⼰的投票箱中并将新的票发给其他节点
  4. 如果pk是平局则将接收到的票放⼊⾃⼰的投票箱中
  5. 如果pk赢了则忽略所接收到的
  6. 当然⼀个节点将票放⼊到⾃⼰的投票箱之后就会从投票箱中统计票数看是否超半的节点和⾃⼰所投的节点是样的如果超半数么则认为当前⾃⼰所投的节点是leader
  7. 集群中每节点会经同样的pk的规则也是样的,⼀旦改票就会告诉给其他服务所以最终各节点中的投票箱中的票也将是样的所以各节点最终出来的leader也是

样集群的leader举出来了

Zookeeper集群点之间数据

  1. ⾸先集群启动时会先⾏领导者确定节点是Leader些节点是FollowerObserver
  2. 然后Leader会和其他节点⾏数据同步采⽤发快照和发Diff⽇志的⽅式
  3. 集群⼯作程中所有的写请求会交给Leader节点来⾏处理从节点只能处理读请求
  4. Leader节点收到⼀个写请求时通过阶段机制来处理

  1. 正在上传…重新上传取消Leader节点会将该写请求对应的⽇志发给其他Follower节点并等待Follower节点持久化⽇志成功
  2. Follower节点收到⽇志后会⾏持久化如果持久化成功则发⼀个AckLeader节点
  3. Leader节点收到半数以Ack就会开始提交先更新Leader节点本的内存数据
  4. 然后发commit命令给Follower节点Follower节点收到commit命令后就会更新各⾃本内存数据
  5. 同时Leader节点是将当前写请求直接发Observer节点Observer节点收到Leader来的写请求后直接执⾏更新本内存数据
  6. 最后Leader节点返回客户端写请求响应成功
  7. 通过同步机制和阶段提交机制来到集群中节点数据

Dubbo⽀持哪些载均

    1. 随机从多服务提供者随机⼀个来处理本次请求调⽤量越⼤则分布越并⽀持按权重设置随机概率
    2. 依次择服务提供者来处理请求并⽀持按权重底层采⽤的是平滑加权询算
    3. 最⼩跃调⽤数统计服务提供者当前正处理的请求,下次请求来则交给跃数最⼩的服务来处理
    4. 致性哈希相同参数的请求总是发到同⼀个服务提供者

Dubbo完成务导出

  1. ⾸先Dubbo会将程序员所使⽤的@DubboService解或@Service⾏解析得到程序员所定义的     服务参数包括定义的服务名服务接⼝服务超时时间服务协议等等得到⼀个

ServiceBean

  1. 然后调⽤ServiceBeanexport法进⾏服务导出
  2. 然后将服务信息册到册中⼼如果有多协议册中⼼就将服务按单协议册中⼼
  3. 将服务信息册到册中⼼后会绑定些监听监听动态置中⼼的变更
  4. 会根据服务协议启动对应的Web服务或⽹络框架⽐如TomcatNetty

Dubbo完成务引⼊

  1. 当程序员使⽤@Reference解来引⼊⼀个服务时Dubbo会将解和服务的信息解析出来得到当前所引⽤的服务名服务接⼝是什么
  2. 然后从册中⼼⾏查询服务信息得到服务的提供者信息并存在消费端的服务⽬录中
  3. 并绑定些监听⽤来监听动态置中⼼的变更
  4. 然后根据查询得到的服务提供者信息⽣成⼀个服务接⼝的代理对象并放⼊Spring中作为Bean

Dubbo架构设计

Dubbo中的架构设计是⾮常优秀的分为了很多层次每层是可以扩展的⽐如

  1. Proxy服务代理层⽀持JDK动态代理javassist等代理机制
  2. Registry册中⼼层⽀持ZookeeperRedis等作为册中⼼
  3. Protocol程调⽤层⽀持DubboHttp等调⽤协议
  4. Transport⽹络传⽀持nettymina等⽹络传框架
  5. Serialize数据序列化层⽀持JSONHessian等序列化机制

正在上传…重新上传取消层说

  • 正在上传…重新上传取消config 置层对外置接⼝ , 始化置类也可以通过 spring 解析置⽣成置类

为中⼼可以直接初

  • proxy 理层服务接⼝明代理⽣成服务的客户端 Stub 和服务Skeleton,

正在上传…重新上传取消ServiceProxy 为中⼼扩展接⼝为

  • registry ⼼层封装服务地址发现以服务 URL 为中⼼扩展接⼝为

正在上传…重新上传取消RegistryFactory , Registry ,

  • 正在上传…重新上传取消cluster 由层封装多提供者的路由及负载均并桥接册中⼼ 为中⼼

正在上传…重新上传取消展接⼝为 ,

, Router ,

  • 正在上传…重新上传取消monitor  RPC  调⽤次数和调⽤时间监控 为中⼼扩展接⼝为

正在上传…重新上传取消MonitorFactory , ,

  • protocol 远程调⽤层封装 RPC 调⽤

, Result 为中⼼扩展接⼝为

正在上传…重新上传取消Protocol , , Exporter

  • exchange 交换封装请求响应模式同步异步

, Response 为中⼼

正在上传…重新上传取消展接⼝为 , , ,

  • 正在上传…重新上传取消transport ⽹络传输抽象 mina  netty 为统接⼝ 为中⼼扩展接⼝为

正在上传…重新上传取消Channel , , Client , Server ,

  • 正在上传…重新上传取消serialize   数据序列化层可复⽤的些⼯具扩展接⼝为 , ,

正在上传…重新上传取消ObjectOutput ,

关系说

  • 正在上传…重新上传取消RPC Protocol 是核⼼层也就是只要有 Protocol + Invoker + Exporter 就可以完成⾮

RPC 调⽤然后Invoker 的主Filter 拦截点

  • 中的  Consumer   和   Provider   是抽象概念只是想让看者更直观的了解些类分属于客户端服务,不Client Server 的原Dubbo 很多使⽤ Provider, Consumer, Registry, Monitor 划分逻辑拓普节点保持统概念
  • Cluster 是外概念所以 Cluster 的⽬的是将多Invoker 伪装成⼀个 Invoker样其它⼈只要关Protocol Invoker 即可Cluster 或者去掉 Cluster 对其它层成影响为只有⼀个提供者时需要 Cluster 
  • Proxy 层封装了所有接⼝的明化代理其它层Invoker 为中⼼只有到了暴露给⽤户使

⽤时才⽤ Proxy Invoker 成接⼝或将接⼝实现Invoker也就是去掉 Proxy RPC 是可以 Run 只是,不么看起来像调本服务样调程服务

  • Remoting 实现是 Dubbo 协议的实现如果你RMI 协议Remoting 会⽤上, Remoting 再划为 Transport 层和 Exchange 信息交换层Transport 层只负责单向息传是对 Mina, Netty, Grizzly 的抽象它也可以扩展 UDP Exchange 层是层之封装了 Request-Response 语义
  • Registry Monitor 实际上不⽽是⼀个独⽴的节点只是为了全局概览⽤层的⽅式画

正在上传…重新上传取消

载均算法有哪些

1将请求按顺序轮流地到后端服务上,对待后端的每台服务关⼼服   实际的接数和当前的系统负

2随机法通过系统的随机算根据后端服务的列表⼤⼩来随机取其中的台服务器进⾏访由概率统计理论可以得知随着客户端调⽤服务端的次数增多其实际效果越来越接于平调⽤量到后端的每台服务也就是询的结果

3源地址哈源地址哈希的思想是根据获取客户端的IP地址通过哈希函数计算得到的⼀个

⽤该数对服务列表的⼤⼩⾏取模得到的结果便是客服端要访问服务的序号采⽤源地址 哈希法进⾏负载均IP地址的客户端当后端服务列表变时它每次会映射到同台后端服务器进⾏访问

正在上传…重新上传取消4权轮:不同的后端服务可能机置和当前系统的负相同此它们的抗压能⼒      也相同置⾼低的机器配置更⾼的权重让其处理更多的请置低⾼的机,  给其分配较低的权重降低其系统负加权询能很好处理问题并将请求顺序按照权重分 到后端

5权随机法:与加权加权随机也根据后端机系统的负同的权   同的是它是按照权重随机请求后端服务⽽⾮顺序

6连接数法最⼩接数算和智能由于后端服务尽相同对于请求的处      理有快有慢它是根据后端服务当前的接情况动态地选取其中当前积压接数最少的台服务来处理当前的请求尽可能提⾼后端服务的利⽤效率将负责合理到每台服务

分布式架构下,Session 享有什么

1采⽤⽆状态服务抛弃session 2存⼊cookie有安全⻛险

3服务之间⾏  Session   同步样可以保证每服务有全的   Session   信息,不当服务数量⽐多的时候同步是会有延甚⾄同步失败

4IP 绑定策略

使⽤ Nginx 或其他复杂硬件中的 IP 绑定策略⼀个 IP 只能指定的同⼀个访问但是样做失去了负载均衡的意义当挂掉台服务的时候会影响批⽤户的使⽤⻛险很⼤

5使⽤ Redis 存储

Session 放到 Redis 中存储然架构变得复杂需要多访问Redis 但是种⽅案带来的好处也是很⼤的

  • 实现了 Session 共享
  • 可以⽔平扩展增加 Redis 服务);
  • 服务重启 Session 不丢(不也要Session Redis 中的刷新/失效机制);

  • 正在上传…重新上传取消仅可以跨服务Session 共享甚⾄可以跨平台例如⽹⻚端和 APP 

接⼝

  • id每次操作根据操作和内容⽣成id执⾏之前先判断id是否存如果则 执⾏后续操作保存到数据库或者redis
  • 服务端提供发token的接⼝,业务调⽤接⼝前先获取token,然后调⽤务接⼝请求时token携带,判断token是否存redis表示第次请求可以继续执⾏执⾏务完成后最后需要把redis中的token删除
  • 建去重表务中有标识的字段保存到去重表如果表中存则表示已经处理
  • 版本控制增加版本号当版本号符合时才能更新数据
  • 状态控制例如订单有状态已⽀付 未⽀付 ⽀付中 ⽀付失败当处于未⽀付的时候才许修改为⽀

付中等

简述zk命名配置管集群

命名服务

通过指定的名字来获取资或者服务地址Zookeeper可以创建⼀个全局的路径路径就可以         作为⼀个名字被命名的实体可以是集群中的机服务的地址或者是程的对象等些分布式服           务框架RPCRMI中的服务地址列表通过使⽤命名服务客户端应⽤能够根据特定的名字来获取         资的实体服务地址和提供者信息等

置管理

实际项⽬开发中经常使⽤.properties或者xml需要置很多信息如数据库接信息fps地址端⼝等 等程序分布式署时如果把程序的置信息保存zkznode节点下,当你要修改znode会发⽣变化时可以通过改变zk中某⽬录节点的内容利⽤watcher知给各客户端从⽽  更改

集群管理

集群管理包括集群监控和集群控制就是监控集群机状态剔除机和加⼊机zookeeper可以⽅ 便集群机的管理它可以实时监控znode节点的变化,⼀旦发现有机挂了该机就会zk断开

正在上传…重新上传取消对应的临时⽬录节点会被删除其他所有机器都收到新机加⼊也是类似

Zookeeperwatch

客户端可以通过在znode设置watch实现实时监听znode的变化

Watch事件是⼀个⼀次性的触发当被设置了Watch的数据发⽣了改变的时候则服务改变发给设置了Watch的客户端

  • ⽗节点的创建修改删除会触发Watcher事件
  • ⼦节点的创建删除会触发Watcher事件

次性:⼀旦被触发就会移除再次使⽤需要重新为每次变动需要知所有客户端,⼀次性可以减压⼒3.6.0默认持久可以触发多次

知发⽣了事件,不会告知事件内容服务和带宽压⼒

Watcher 机制包括三个⻆⾊客户端线程客户端的 WatchManager 以及 ZooKeeper 服务

  1. 客户端向 ZooKeeper 服务器注⼀个 Watcher 监听
  2. 监听信息存储到客户端的 WatchManager 
  3. ZooKeeper 中的节点发⽣变化时知客户端客户端会调⽤相应 Watcher 对象中的

watch调是串⾏同步的

ZookeeperEureka区别

zkCP设计(致性)⽬标是⼀个分布式的协调系统⽤于⾏资的统管理当节点crash需要leader在这期间内zk服务是可⽤的

eurekaAP设计⾼可⽤),⽬标是⼀个服务册发现系统,专⻔⽤于微服务的服务发现

Eureka节点是平等的节点挂掉会影响正常节点的⼯作剩余的节点依然可以提供册和 查询服务Eureka的客户端向某Eureka册时如果发现接失败会⾃动切换⾄其他节点只要

正在上传…重新上传取消Eureka还在就能保证册服务可⽤保证可⽤性),查到的信息可能是最新的(不保证强致性

同时当eureka的服务端发现85%的服务都没有⼼跳的话它就会认为⾃⼰的⽹络出了问题会         从服务列表中删除些失去⼼跳的服务同时eureka的客户端也会缓存服务信息eureka对于服务册          发现来说是⾮常好的

存储拆分后如解决问题

  • UUID简单性能好有顺序务含义在泄mac地址的⻛险
  • 数据库主键实现简单单调具有定的务可读性强依赖db性能瓶颈暴露务 信息的⻛险
  • redismongodbzk等中间件增加了系统的复杂度和稳定性
  • 雪花算

算法

位符号位定为041位时间戳10workId12位序列号位数可以有同实现

优点毫秒包含的ID很多,不够可以变动位数来增加性能佳依赖workId的实现时间戳值在⾼位中间是定的机⾃增的序列低位ID是趋势增的能够根据景数据库 节点布置灵调整bit位划分度⾼

缺点强依赖于机时钟如果时钟会导致重复的ID⽣成所以般基于此的算发现时钟会抛异常处理阻⽌ID⽣成可能导致服务可⽤

正在上传…重新上传取消解决使分区询问题

  • 映射将查询条件的字段分区键⾏映射张单独的表维护(使⽤覆盖索引)或者缓存中维护
  • 因法分区键的后xbit位由查询字段hash后占⽤分区键直接取xbit位获取分区查询字hash获取分区合⾮分区键查询字段只有⼀个的情况
  • 冗余查询字段冗余存储

Spring Cloud有哪些组件是什么

  1. Eureka册中⼼
  2. Nacos册中⼼置中⼼
  3. Consul册中⼼置中⼼
  4. Spring Cloud Config置中⼼
  5. Feign/OpenFeignRPC调⽤
  6. Kong服务⽹关
  7. Zuul服务⽹关
  8. Spring Cloud Gateway服务⽹关
  9. Ribbon载均
  10. Spring CLoud Sleuth链路
  11. Zipkin链路
  12. Seata分布式事务
  13. DubboRPC调⽤
  14. Sentinel服务熔断
  15. Hystrix服务熔断

何避穿透存击穿存雪崩

缓存雪崩是指缓存同时间⼤⾯积的失效所以后⾯的请求会落到数据库上,成数据库短时间内 承受⼤量请求⽽崩掉

解决⽅案

  • 缓存数据的期时间设置随机防⽌同时间⼤量数据期现象发⽣
  • 给每⼀个缓存数据增加相应的缓存标记记录缓存是否失效如果缓存标记失效则更新数据缓

  • 缓存预热互斥锁

正在上传…重新上传取消缓存穿是指缓存和数据库中都没有的数据导致所有的请求落到数据库上,成数据库短时间内承

受⼤量请求⽽崩掉解决⽅案

  • 接⼝层增加校验如⽤户鉴权校验id做基础校验id<=0的直接拦截
  • 从缓存取到的数据数据库中也有取到时也可以将key-value对写为key-null缓存有效时间可以设置短点30设置太⻓会导致正常情况也没法使⽤样可以防⽌攻击⽤户  反复⽤同⼀个id暴⼒攻击
  • 采⽤布隆将所有可能存的数据哈希到⼀个⾜够⼤的 bitmap ,⼀个⼀的数据会被bitmap 拦截掉从⽽免了对底层存储系统的查询压⼒

缓存击穿是指缓存中有但数据库中有的数据(⼀般是缓存时间到期),时由于并发⽤户特别多同时读缓存读到数据⼜同时去数据库去取数据引起数据库压⼒瞬间增⼤⼤压⼒和缓存雪   同的是缓存击穿指并发查同条数据缓存雪崩是同数据都过期了很多数据到从⽽  查 数据库

解决⽅案

  • 设置热点数据永加互斥锁

分布式系统中⽤的存⽅案有哪些

  • 客户端缓存⻚⾯和缓存APP缓存H5缓存localStorage sessionStorage CDN缓存内容存储数据的缓存内容分发载均
  • nginx缓存静态资
  • 服务端缓存缓存缓存
  • 数据库缓存持久层缓存mybatishibernate多级缓存),mysql查询缓存 操作系统缓存

PageCacheBufferCache

过期都有哪些策

  • 定时设置期时间的key需要创建⼀个定时期时间就会⽴即该策略可以

⽴ 即期的数据对内存很友好但是会占⽤⼤量的CPU去处理期的数据从⽽影响缓存的响应时间和吞吐量

  • 惰性只有当访问⼀个key才会判断该key是否已期则该策略可以最⼤化节省CPU但是很耗内存许多的期数据都还内存中极端情况可能出现⼤量的

正在上传…重新上传取消key有 再次被访问从⽽会被占⽤⼤量内存

  • 定期每隔定的时间会扫描定数量的数据库的expires字典中定数量的key是随机的除其中已期的key该策略是定时期和惰性期的折中⽅案通过调整定时扫描的时间间隔和 每次扫描的限定耗时可以同情况使得CPU和内存资源达到最优的平衡效果
  • 分桶策略定期期的优化期时间点相key按时间扫描分桶

常⻅淘汰算法

  • FIFOFirst In First Out先出),根据缓存被存储的时间离当前最的数据优先被淘汰
  • LRULeastRecentlyUsed最少使⽤),根据最被使⽤的时间离当前最的数据优先被淘汰
  • LFULeastFrequentlyUsed经常使⽤),段时间内缓存数据被使⽤次数最少的会被

淘汰

布隆过滤器优缺点

  • int[10]int的整数是4*8=32bitint[10]共有320 bitbit01初始

化时0

  • 加数据时将数据hash得到hash对应到bit将该bit改为1hash函数可以定义多个, 则      ⼀个数据加会将多个(hash函数bit改为1hash函数的⽬的是减少hash碰撞的概率
  • 查询数据hash函数计算得到hash对应到bit如果有⼀个0则说明数据bit如果1则该数据可能bit

优点

  • 占⽤内存⼩
  • 增加和查询元素的时间复杂度为O(K), (K为哈希函数的,⼀般⽐),与数据量⼤⼩⽆关哈希函数相互之间有关系⽅便硬件并⾏
  • 布隆需要存储元素本身某些对保密要求⽐格的合有很⼤优势 数据量很⼤时

可以表示全集

  • 使⽤同组散列函数的布隆可以⾏交

缺点

  • 误判率即存假阳性(False Position),不能准确判断元素是否集合中能获取元素本身

  • 正在上传…重新上传取消般情况下不能从布隆中删除元素

分布式存寻址算法

  • hash根据keyhash函数结果对分⽚数取模确定分⽚ 定分⽚数的扩展分⽚或者减少分⽚时所有数据需要重新计算分⽚存储
  • 致性hash将整hash得区间组织成⼀个闭合的计算每台服务hash映射到使⽤相同的hash计算数据的hash映射到顺时针寻找找到的第⼀个服务就是数据存储的服务新增及减少节点时只会影响节点到他时针最⼀个服务之间的hash环倾斜的问题即服务分布可以通过虚拟节点解决
  • hash  slot将数据服务隔离开数据slot映射slot服务映射数据hash决定存放的slot新增及删除节点时slot移即可

Spring CloudDubbo有哪些区别

Spring Cloud⼀个微服务框架提供了微服务领域中的很多功能组件Dubbo开始是⼀个RPC调⽤框架核⼼是解决服务调⽤间的问题Spring Cloud⼀个⼤⽽全的框架Dubbo则更侧重于服务调

所以Dubbo所提供的功能Spring Cloud全⾯但是Dubbo的服务调⽤性能⽐Spring Cloud, 不Spring CloudDubbo是对⽴的是可以结合起来起使⽤的

什么是服务雪崩什么是服务限

    1. 当服务A调⽤服务B服务B调⽤C此时⼤量请求突然请求服务A假如服务A本身能抗住些请  求但是如果服务C导致服务C请求堆积从⽽服务B请求堆积从⽽服务A可⽤就是服务雪崩解决⽅式就是服务降级和服务熔断
    2. 服务限是指⾼并发请求下,为了保护系统可以对访问服务的请求⾏数量的限制从⽽防

⽌系统被⼤量请求压垮秒杀中是⾮常重要的

什么是服什么是服务降区别是什么

  1. 服务熔断是指当服务A调⽤的某服务B可⽤时,上服务A为了保证⾃⼰受影响从⽽再调⽤服务B直接返回⼀个结果服务A和服务B的压⼒直到服务B恢复

  1. 正在上传…重新上传取消服务降级是指当发现系统压⼒过载可以通过关闭某服务或限服务来减系统压

就是服务降级

相同点

  1. 是为了防⽌系统崩
  2. 让⽤户体验到某些功能暂时可⽤

同点熔断是服务故障触发的降级是为了降低系统负

SOA分布式有什么和区别

  1. 分布式架构是指将单体架构中的各分拆分然后同的机程中去SOA和微服务基本是分布式架构的
  2. SOA种⾯向服务的架构系统的所有服务都注总线上,当调⽤服务时从总线查找服务信息然后调⽤
  3. 微服务是种更彻底的⾯向服务的架构将系统中各功能体抽成⼀个个⼩的应⽤程序基本保持⼀个应⽤对应的⼀个服务的架构

拆分微

拆分微服务的时候为了尽量保证微服务的稳定会有些基本的准则

  1. 微服务之间尽量要有务交叉
  2. 微服务之前只能通过接⼝⾏服务调⽤能绕接⼝直接访问对⽅的数据
  3. ⾼内聚低耦合

设计出内聚耦合

⾼内聚低耦合种从指导微服务设计的⽅实现⾼内聚低耦合的⼯具主要有 同步的接⼝调

⽤ 和 异步的事件驱动 种⽅式

有没有了DDD领域动设计

什么是DDD2004Eric Evans提出了DDD是⾯对件复杂之Domain-Driven- Design Tackling Complexity in the Heart of Software

正在上传…重新上传取消泥团: 不利于微服务的拆分泥团结构拆分出来的微服务依然是泥团机构当服务逐渐复杂泥团⼜会膨胀成为⼤泥团

DDD只是种⽅⼀个稳定的技术框架DDD要求领域是跟技术⽆关跟存储⽆关信⽆关

什么是中

所谓中台就是将各个业务线中可以复⽤的些功能抽取出来剥离提取共性形成些可复⽤的组件

⼤体上,中台可以分为务中台数据中台和技术中台⼤数据杀熟-数据中台

中台跟DDD结合DDD通过限界上下⽂将系统拆分成⼀个⼀个的领域种限界上下天⽣就成了中台之间的逻辑屏障

DDD技术调度⽅⾯能够给中台建设提供错的指导

DDD分为战略设计和战术设计层的战略设计能够很好的指导中台划分,下层的战术设计能够很好的指导微服务搭建

中是么保证微务敏捷开发

  • 开发体化
  • 敏捷开发⽬的就是为了提⾼队的交付效率速迭试错
  • 定发布新版本以分⽀的形式保存到代码仓库中⼊职任务⾯板站⽴会议

⼈员灵活流同时形成各个专家代表

  • 试环境- ⽣产环境 -开发试环境SIT-集成试环境-环境STR-预投产环境-⽣产环境PRD
  • 晨会周会需求拆分会

何进息队列选型

  • Kafka
    • 优点吞吐量⾮常⼤性能⾮常好集群⾼可⽤
    • 缺点数据功能⽐
    • 使⽤⽇志分析⼤数据采集
  • RabbitMQ
    • 优点息可靠性⾼功能全⾯
    • 缺点吞吐量⽐息积累会重影响性能erlang语⾔好定制
    • 使⽤⼩规模

  • 正在上传…重新上传取消RocketMQ
    • 优点⾼吞吐⾼性能⾼可⽤功能⾮常全⾯
    • 缺点版功能如云官⽅⽂档和周⽣态够成熟客户端只⽀持java
    • 使⽤⼏乎是全

RocketMQ现的

    1. ⽣产者订单系统先发half息到Brokerhalf息对费者⽽⾔是可⻅的
    2. 再创建订单根据创建订单成功Brokercommitrollback
    3. ⽣产者订单系统可以提供Broker调接⼝Broker发现段时间half有收到任何操作命令则会主动调此接⼝来查询订单是否创建成功
    4. halfcommit费者库存系统就会来如果费成功息销毁分布式事务成功结束
    5. 如果费失败则根据重试策略⾏重试最后失败则⼊死信队列等待步处理

为什么RocketMQ使Zookeeper作为注⼼呢

根据CAP理论同时最多只能满⾜两个zookeeper满⾜的是CP也就是说zookeeper能保证      服务的可⽤性zookeeper在进举的时候举的时间太⻓期间整集群处于可⽤的状          态对于⼀个册中⼼来说肯定是能接受的作为服务发现来说就应该是为可⽤性⽽设计

基于性能的考NameServer本身的实现⾮常可以通过增加机的⽅式⽔平扩展增加集群的抗压能⼒zookeeper的写是可扩展的zookeeper要解决问题只能通过划分领域

正在上传…重新上传取消分多zookeeper集群来解决⾸先操作起来太复杂其次是⼜反了CAP中的A的设计导致        服务之间是连通

持久化的机制来带的问题ZooKeeper ZAB 协议对每⼀个写请求ZooKeeper 节点保持写⼀个事务⽇志同时再加定期的将内存数据镜像Snapshot到磁盘来保证数据的致性和持久性⽽对于⼀个简单的服务发现的景来说其实有太⼤的必要实现⽅案太重了本身  存储的数据应该是⾼度定制化的

息发应该弱依赖册中⼼RocketMQ的设计理念也正是基于此⽣产者次发送消息的时  候从NameServer获取到Broker地址后缓存到本如果NameServer集群可⽤短时间内对于⽣      产者和费者并会产⽣太⼤影响

RocketMQ

RocketMQNameServer册中⼼集群Producer⽣产者集群Consumer费者集群和若⼲Broker

RocketMQ组成它的架构原理是样的

Broker启动的时候去向所有的NameServer并保持⻓30s次⼼跳

Producer送消息的时候从NameServer获取Broker服务器地址根据负载均衡算法选台服务器    来发送消

Conusmer息的时候同样从NameServer获取Broker地址然后主动拉取息来

RocketMQ为什么速度快

为使⽤了顺序存储Page Cache和异步刷盘我们写⼊commitlog的时候是顺序写⼊的样⽐随机写⼊的性能就会提⾼很多写⼊commitlog的时候并是直接写⼊磁盘⽽是先写⼊操作系统的PageCache最后由操作系统异步将缓存中的数据刷到磁盘

息队列如何保息可靠传输

息可靠传代表了层意思能多也能少

  1. 为了保证也就是能重复也就是⽣产者能重复⽣产或者费者能重复
  2. ⾸先要确保多发个不常出现也⽐难控制为如果出现了多发很⼤的原是⽣产者⾃⼰的原如果要免出现问题就需要在消费端做控制
  3. 重复最保险的机制就是费者实现幂等性保证就算重复会有问题通过幂等性也能解决⽣产者重复发送消息的问题

  1. 正在上传…重新上传取消能少意思就是⽣产者发费者定要能费到对于问题就要考两个⽅⾯
  2. ⽣产者发送消息时要确认broker确实收到并持久化了⽐如RabbitMQconfirm机制Kafkaack机制可以保证⽣产者能正确的将息发broker
  3. broker要等待费者真正确认费到了息时才删除掉常就是费端ack机制费   者接收到息后如果确认问题了就可以给broker⼀个ackbroker接收到ack后才会删除

息队列有哪些作

  1. 解耦使⽤息队列来作为两个系统之间的讯⽅式,两个系统需要相互依赖了
  2. 异步系统A息队列发息之后就可以继续做其他事情了
  3. 量削峰如果使⽤息队列的⽅式来调⽤某系统息将队列中排队费者⾃⼰控 制

死信队列是什么队列是什么

  1. 死信队列也是⼀个息队列它是⽤来存放有成功费的息的常可以⽤来作为息重 试
  2. 延时队列就是⽤来存放需要指定时间被处理的元素的队列常可以⽤来处理些具有期性操 作的⽐如⼗分钟内未⽀付则取订单

何保的⾼效读写

零拷⻉kafkaRocketMQ通过零拷⻉技术来优化⽂件读写传统⽂件复制⽅式需要对⽂件内存中次拷⻉

零拷⻉种⽅式mmaptransfileJava当中对零拷⻉⾏了封装Mmap⽅式通过MappedByteBuffer对象⾏操作transfile通过FileChannel⾏操作Mmap   合⽐⼩的⽂件常⽂件⼤⼩要超1.5G ~2G 之间Transfile有⽂件⼤⼩限制RocketMQ当中使⽤Mmap⽅式来对他的⽂件⾏读写

kafka当中他的index⽇志⽂件也是通过mmap的⽅式来读写的其他⽇志⽂件当中有使⽤零拷⻉的⽅式Kafka使⽤transfile⽅式将硬盘数据加到⽹卡

正在上传…重新上传取消epollpoll区别

  1. select使⽤的是数组来存储Socket接⽂件描容量是定的需要通过轮询来判断是否发⽣了IO事件
  2. poll使⽤的是链表来存储Socket接⽂件描容量是定的同样需要通过轮询来判断是否发⽣了IO事件
  3. epollepollpoll是完全同的epoll种事件知模当发⽣了IO事件时应⽤程序才IO操作,不需要像poll型那样主动去

TCP握⼿和四次挥⼿

TCP协议是7层⽹络协议中的传层协议负责数据的可靠传建⽴TCP接时需要通过次握⼿来建⽴程是

  1. 客户端向服务端发⼀个SYN
  2. 服务端接收到SYN给客户端发⼀个SYN_ACK
  3. 客户端接收到SYN_ACK再给服务端发⼀个ACK

断开TCP接时需要通过四次挥⼿来断开程是

  1. 客户端向服务端发FIN
  2. 服务端接收FIN向客户端发ACK表示我接收到了断开接的请求客户端你可以发数据了,不服务端这边可能有数据正处理
  3. 服务端处理完所有数据后向客户端发FIN表示服务端现可以断开
  4. 客户端收到服务端的FIN向服务端发ACK表示客户端也会断开接了

发出⼀个到收到响应了哪些步

  1. 解析⽤户⼊的URL⽣成⼀个HTTP格式的请求
  2. 先根据URL域名从本hosts⽂件查找是否有映射IP如果有就将域名发给电脑所置的DNS

⾏域名解析得到IP地址

  1. 器通过操作系统将请求通过四层⽹络协议发出去
  2. 中可能会经各种路由交换机最终到服务
  3. 服务收到请求后根据请求所指定的端⼝将请求传给绑定了该端⼝的应⽤程序⽐如8080tomcat占⽤了
  4. tomcat接收到请求数据后按照http协议的格式⾏解析解析得到所要访问的servlet
  5. 然后servlet来处理请求如果是SpringMVC中的DispatcherServlet么则会找到对应的Controller中的⽅并执⾏该⽅得到结果
  6. Tomcat得到响应结果后封装成HTTP响应的格式并再次通过⽹络发的服务

  1. 正在上传…重新上传取消的服务拿到结果后再传则负责解析并

跨域请求是什么有什么问题解决

跨域是指器在发起⽹络请求时会检查该请求所对应的协议域名端⼝和当前⽹⻚是否如    果不⼀致则⾏限制⽐如www.baidu.com的某个⽹⻚中如果使⽤ajax去访问 www.jd.com是不⾏的但是如果是imgiframescript等标签的src属性去访问则是可以的之所以要做层限制是为了⽤户信息安全但是如果开发者想要绕过这层限制也是可以的

  1. responseheader⽐如resp.setHeader("Access-Control-Allow-Origin", "*");表示可以访问所有⽹站,不受是否同的限制
  2. jsonp的⽅式该技术底层就是基于script标签来实现的script标签是可以跨域的
  3. 后台⾃⼰控制先访问同域名的接⼝然后接⼝中再去使⽤HTTPClient等⼯具去调⽤⽬标接⼝
  4. ⽹关和第种⽅式类似是交给后台服务来⾏跨域访问

零拷⻉是什么

零拷⻉指的是应⽤程序需要把内核中的区域数据移到另外内核区域去时,不需要经先 复制到⽤户空间移到⽬标内核区域去了⽽直接实现

正在上传…重新上传取消

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值