《JAVA核心知识点整理.docx》由会员分享,可在线阅读,更多相关《JAVA核心知识点整理.docx(283页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1. 目录1. 目录12. JVM192.1.线程202.2. JVM 内存区域212.2.1. 程序计数器(线程私有)222.2.2. 虚拟机栈(线程私有)222.2.3. 本地方法区(线程私有)232.2.4. 堆(Heap-线程共享)-运行时数据区232.2.5. 方法区/永久代(线程共享)232.3. JVM 运行时内存242.3.1. 新生代242.3.1.1. Eden 区242.3.1.2. ServivorFrom242.3.1.3. ServivorTo242.3.1.4. MinorGC 的过程(复制-清空-互换)241:eden、servicorFrom 复制到 Serv
2、icorTo,年龄+1252:清空 eden、servicorFrom253:ServicorTo 和 ServicorFrom 互换252.3.2. 老年代252.3.3. 永久代252.3.3.1. JAVA8 与元数据252.4. 垃圾回收与算法262.4.1. 如何确定垃圾262.4.1.1. 引用计数法262.4.1.2. 可达性分析262.4.2. 标记清除算法(Mark-Sweep)272.4.3. 复制算法(copying)272.4.4. 标记整理算法(Mark-Compact)282.4.5. 分代收集算法292.4.5.1. 新生代与复制算法292.4.5.2. 老年代与
3、标记复制算法292.5. JAVA 四中引用类型302.5.1. 强引用302.5.2. 软引用302.5.3. 弱引用302.5.4. 虚引用302.6. GC 分代收集算法 VS 分区收集算法302.6.1. 分代收集算法302.6.1.1. 在新生代-复制算法302.6.1.2. 在老年代-标记整理算法302.6.2. 分区收集算法312.7. GC 垃圾收集器312.7.1. Serial 垃圾收集器(单线程、复制算法)312.7.2. ParNew 垃圾收集器(Serial+多线程)312.7.3. Parallel Scavenge 收集器(多线程复制算法、高效)322.7.4.
4、Serial Old 收集器(单线程标记整理算法)322.7.5. Parallel Old 收集器(多线程标记整理算法)332.7.6. CMS 收集器(多线程标记清除算法)332.7.6.1. 初始标记332.7.6.2. 并发标记342.7.6.3. 重新标记342.7.6.4. 并发清除342.7.7. G1 收集器342.8. JAVA IO/NIO342.8.1. 阻塞 IO 模型342.8.2. 非阻塞 IO 模型352.8.3. 多路复用 IO 模型352.8.4. 信号驱动 IO 模型362.8.5. 异步 IO 模型362.8.1. JAVA IO 包362.8.2. JA
5、VA NIO372.8.2.1. NIO 的缓冲区382.8.2.2. NIO 的非阻塞382.8.3. Channel402.8.4. Buffer402.8.5. Selector402.9. JVM 类加载机制412.9.1.1. 加载412.9.1.2. 验证412.9.1.3. 准备412.9.1.4. 解析412.9.1.5. 符号引用422.9.1.6. 直接引用422.9.1.7. 初始化422.9.1.8. 类构造器422.9.2. 类加载器422.9.2.1. 启动类加载器(Bootstrap ClassLoader)432.9.2.2. 扩展类加载器(Extension
6、ClassLoader)432.9.2.3. 应用程序类加载器(Application ClassLoader):432.9.3. 双亲委派432.9.4. OSGI(动态模型系统)442.9.4.1. 动态改变构造442.9.4.2. 模块化编程与热插拔443. JAVA 集合453.1. 接口继承关系和实现453.2. LIST473.2.1. ArrayList(数组)473.2.2. Vector(数组实现、线程同步)473.2.3. LinkList(链表)473.3. SET483.3.1.1. HashSet(Hash 表)483.3.1.2. TreeSet(二叉树)493.3
7、.1.3. LinkHashSet(HashSet+LinkedHashMap)493.4. MAP503.4.1. HashMap(数组+链表+红黑树)503.4.1.1. JAVA7 实现503.4.1.2. JAVA8 实现513.4.2. ConcurrentHashMap513.4.2.1. Segment 段513.4.2.2. 线程安全(Segment 继承 ReentrantLock 加锁)513.4.2.3. 并行度(默认 16)523.4.2.4. Java8 实现 (引入了红黑树)523.4.3. HashTable(线程安全)533.4.4. TreeMap(可排序)5
8、33.4.5. LinkHashMap(记录插入顺序)534. JAVA 多线程并发544.1.1. JAVA 并发知识库544.1.2. JAVA 线程实现/创建方式544.1.2.1. 继承 Thread 类544.1.2.2. 实现 Runnable 接口。544.1.2.3. ExecutorService、Callable、Future 有返回值线程554.1.2.4. 基于线程池的方式564.1.3. 4 种线程池564.1.3.1. newCachedThreadPool574.1.3.2. newFixedThreadPool574.1.3.3. newScheduledThr
9、eadPool584.1.3.4. newSingleThreadExecutor584.1.4. 线程生命周期(状态)584.1.4.1. 新建状态(NEW)584.1.4.2. 就绪状态(RUNNABLE):594.1.4.3. 运行状态(RUNNING):594.1.4.4. 阻塞状态(BLOCKED):59等待阻塞(o.wait-等待对列):59同步阻塞(lock-锁池)59其他阻塞(sleep/join)594.1.4.5. 线程死亡(DEAD)59正常结束59异常结束59调用 stop594.1.5. 终止线程 4 种方式604.1.5.1. 正常运行结束604.1.5.2. 使用
10、退出标志退出线程604.1.5.3. Interrupt 方法结束线程604.1.5.4. stop 方法终止线程(线程不安全)614.1.6. sleep 与 wait 区别614.1.7. start 与 run 区别624.1.8. JAVA 后台线程624.1.9. JAVA 锁634.1.9.1. 乐观锁634.1.9.2. 悲观锁634.1.9.3. 自旋锁63自旋锁的优缺点63自旋锁时间阈值(1.6 引入了适应性自旋锁)63自旋锁的开启644.1.9.4. Synchronized 同步锁64Synchronized 作用范围64Synchronized 核心组件64Synchr
11、onized 实现644.1.9.5. ReentrantLock66Lock 接口的主要方法66非公平锁66公平锁67ReentrantLock 与 synchronized67ReentrantLock 实现67Condition 类和 Object 类锁方法区别区别68tryLock 和 lock 和lockInterruptibly 的区别684.1.9.6. Semaphore 信号量68实现互斥锁(计数器为 1)68代码实现68Semaphore 与 ReentrantLock694.1.9.7. AtomicInteger694.1.9.8. 可重入锁(递归锁)694.1.9.9
12、. 公平锁与非公平锁70公平锁(Fair)70非公平锁(Nonfair)704.1.9.10. ReadWriteLock 读写锁70读锁70写锁704.1.9.11. 共享锁和独占锁70独占锁70共享锁704.1.9.12. 重量级锁(Mutex Lock)714.1.9.13. 轻量级锁71锁升级714.1.9.14. 偏向锁714.1.9.15. 分段锁714.1.9.16. 锁优化71减少锁持有时间72减小锁粒度72锁分离72锁粗化72锁消除724.1.10. 线程基本方法724.1.10.1. 线程等待(wait)734.1.10.2. 线程睡眠(sleep)734.1.10.3.
13、线程让步(yield)734.1.10.4. 线程中断(interrupt)734.1.10.5. Join 等待其他线程终止744.1.10.6. 为什么要用 join()方法?744.1.10.7. 线程唤醒(notify)744.1.10.8. 其他方法:744.1.11. 线程上下文切换754.1.11.1.进程754.1.11.2. 上下文754.1.11.3. 寄存器754.1.11.4. 程序计数器754.1.11.5. PCB-“切换桢”754.1.11.6. 上下文切换的活动:764.1.11.7. 引起线程上下文切换的原因764.1.12. 同步锁与死锁764.1.12.1
14、. 同步锁764.1.12.2.死锁764.1.13. 线程池原理764.1.13.1. 线程复用764.1.13.2. 线程池的组成764.1.13.3. 拒绝策略784.1.13.4. Java 线程池工作过程784.1.14. JAVA 阻塞队列原理794.1.14.1. 阻塞队列的主要方法80插入操作:80获取数据操作:814.1.14.2. Java 中的阻塞队列814.1.14.3. ArrayBlockingQueue(公平、非公平)824.1.14.4. LinkedBlockingQueue(两个独立锁提高并发)824.1.14.5. PriorityBlockingQueu
15、e(compareTo 排序实现优先)824.1.14.6. DelayQueue(缓存失效、定时任务 )824.1.14.7. SynchronousQueue(不存储数据、可用于传递数据)834.1.14.8. LinkedTransferQueue834.1.14.9. LinkedBlockingDeque834.1.15. CyclicBarrier、CountDownLatch、Semaphore 的用法844.1.15.1. CountDownLatch(线程计数器 )844.1.15.2. CyclicBarrier(回环栅栏-等待至 barrier 状态再全部同时执行)844
16、.1.15.3. Semaphore(信号量-控制同时访问的线程个数)854.1.16. volatile 关键字的作用(变量可见性、禁止重排序)87变量可见性87禁止重排序87 sychronized 更轻量级的同步锁87适用场景874.1.17. 如何在两个线程之间共享数据88将数据抽象成一个类,并将数据的操作作为这个类的方法88Runnable 对象作为一个类的内部类894.1.18. ThreadLocal 作用(线程本地存储)90ThreadLocalMap(线程的一个属性)90使用场景914.1.19. synchronized 和 ReentrantLock 的区别914.1.1
17、9.1. 两者的共同点:914.1.19.2. 两者的不同点:924.1.20. ConcurrentHashMap 并发924.1.20.1. 减小锁粒度924.1.20.2. ConcurrentHashMap 分段锁92ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成934.1.21. Java 中用到的线程调度934.1.21.1. 抢占式调度:934.1.21.2. 协同式调度:934.1.21.3. JVM 的线程调度实现(抢占式调度)944.1.21.4. 线程让出 cpu 的情况:944.1.22. 进程调度算法944.1.
18、22.1. 优先调度算法944.1.22.2. 高优先权优先调度算法954.1.22.3. 基于时间片的轮转调度算法964.1.23. 什么是 CAS(比较并交换-乐观锁机制-锁自旋)964.1.23.1. 概念及特性964.1.23.2. 原子包 java.util.concurrent.atomic(锁自旋)974.1.23.3. ABA 问题984.1.24. 什么是 AQS(抽象的队列同步器)98Exclusive 独占资源-ReentrantLock99Share 共享资源-Semaphore/CountDownLatch99同步器的实现是 ABS 核心(state 资源状态计数)1
19、00ReentrantReadWriteLock 实现独占和共享两种方式1005. JAVA 基础1015.1.1. JAVA 异常分类及处理1015.1.1.1.概念1015.1.1.2. 异常分类101Error101Exception(RuntimeException、CheckedException)1015.1.1.3. 异常的处理方式102遇到问题不进行具体处理,而是继续抛给调用者 (throw,throws)102try catch 捕获异常针对性处理方式1025.1.1.4. Throw 和 throws 的区别:102位置不同102功能不同:1025.1.2. JAVA 反射
20、1035.1.2.1. 动态语言1035.1.2.2. 反射机制概念 (运行状态中知道类所有的属性和方法)1035.1.2.3. 反射的应用场合103编译时类型和运行时类型103的编译时类型无法获取具体方法1045.1.2.4. Java 反射 API104反射 API 用来生成JVM 中的类、接口或则对象的信息。1045.1.2.5. 反射使用步骤(获取 Class 对象、调用对象方法)1045.1.2.6. 获取 Class 对象的 3 种方法104调用某个对象的 getClass()方法104调用某个类的 class 属性来获取该类对应的 Class 对象104使用 Class 类中的
21、forName()静态方法(最安全/性能最好)1045.1.2.7. 创建对象的两种方法105Class 对象的 newInstance()105调用 Constructor 对象的newInstance()1055.1.3. JAVA 注解1065.1.3.1. 概念1065.1.3.2. 4 种标准元注解106Target 修饰的对象范围106Retention 定义 被保留的时间长短106Documented 描述-javadoc106Inherited 阐述了某个被标注的类型是被继承的1065.1.3.3. 注解处理器1075.1.4. JAVA 内部类1095.1.4.1. 静态内部
22、类1095.1.4.2. 成员内部类1105.1.4.3. 局部内部类(定义在方法中的类)1105.1.4.4. 匿名内部类(要继承一个父类或者实现一个接口、直接使用 new 来生成一个对象的引用)1115.1.5. JAVA 泛型1125.1.5.1.泛型方法()1125.1.5.2. 泛型类1125.1.5.3. 类型通配符?1135.1.5.4. 类型擦除1135.1.6. JAVA 序列化(创建可复用的 Java 对象)113保存(持久化)对象及其状态到内存或者磁盘113序列化对象以字节数组保持-静态成员不保存113序列化用户远程对象传输113Serializable 实现序列化113
23、ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化113writeObject 和 readObject 自定义序列化策略113序列化 ID113序列化并不保存静态变量114序列化子父类说明114Transient 关键字阻止该变量被序列化到文件中1145.1.7. JAVA 复制1145.1.7.1. 直接赋值复制1145.1.7.2. 浅复制(复制引用但不复制引用的对象)1145.1.7.3. 深复制(复制对象和其应用对象)1155.1.7.4. 序列化(深 clone 一中实现)1156. SPRING 原理1166.1.1. Spr
24、ing 特点1166.1.1.1.轻量级1166.1.1.2. 控制反转1166.1.1.3. 面向切面1166.1.1.4.容器1166.1.1.5.框架集合1166.1.2. Spring 核心组件1176.1.3. Spring 常用模块1176.1.4. Spring 主要包1186.1.5. Spring 常用注解1186.1.6. Spring 第三方结合1196.1.7. Spring IOC 原理1206.1.7.1. 概念1206.1.7.2. Spring 容器高层视图1206.1.7.3. IOC 容器实现120BeanFactory-框架基础设施1201.1.1.1.1
25、 BeanDefinitionRegistry 注 册表1211.1.1.1.2 BeanFactory 顶层接口1211.1.1.1.3 ListableBeanFactory1211.1.1.1.4 HierarchicalBeanFactory 父子级联1211.1.1.1.5 ConfigurableBeanFactory1211.1.1.1.6 AutowireCapableBeanFactory 自动装配1221.1.1.1.7 SingletonBeanRegistry 运行期间注册单例 Bean1221.1.1.1.8 依赖日志框框122ApplicationContext 面
26、向开发应用122WebApplication 体系架构1236.1.7.4. Spring Bean 作用域123singleton:单例模式(多线程下不安全)123prototype:原型模式每次使用时创建124Request:一次 request 一个实例124session124global Session1246.1.7.5. Spring Bean 生命周期124实例化124IOC 依赖注入124setBeanName 实现124BeanFactoryAware 实现124ApplicationContextAware 实现125postProcessBeforeInitializa
27、tion 接口实现-初始化预处理125init-method125postProcessAfterInitialization125Destroy 过期自动清理阶段125destroy-method 自配置清理1256.1.7.6. Spring 依赖注入四种方式126构造器注入126setter 方法注入127静态工厂注入127实例工厂1276.1.7.7. 5 种不同方式的自动装配1286.1.8. Spring APO 原理1296.1.8.1. 概念1296.1.8.2. AOP 核心概念1296.1.8.1. AOP 两种代理方式130JDK 动态接口代理130CGLib 动态代理1
28、316.1.8.2. 实现原理1316.1.9. Spring MVC 原理1326.1.9.1. MVC 流程132Http 请求到 DispatcherServlet133HandlerMapping 寻找处理器133调用处理器 Controller133Controller 调用业务逻辑处理后,返回 ModelAndView133DispatcherServlet 查询 ModelAndView133ModelAndView 反馈浏览器 HTTP1336.1.9.1. MVC 常用注解1336.1.10. Spring Boot 原理1341. 创建独立的 Spring 应用程序1342
29、. 嵌入的 Tomcat,无需部署WAR 文件1343. 简化 Maven 配置1344. 自动配置 Spring1345. 提供生产就绪型功能,如指标,健康检查和外部配置1346. 绝对没有代码生成和对 XML 没有要求配置 11346.1.11. JPA 原理1346.1.11.1.事务1346.1.11.2.本地事务1346.1.11.1.分布式事务1356.1.11.1.两阶段提交1361 准备阶段1362 提交阶段:1366.1.12. Mybatis 缓存1376.1.12.1. Mybatis 的一级缓存原理(sqlsession 级别)1386.1.12.2. 二级缓存原理(m
30、apper 基本)138具体使用需要配置:1396.1.13. Tomcat 架构1397.微服务1407.1.1. 服务注册发现1407.1.1.1. 客户端注册(zookeeper)1407.1.1.2. 第三方注册(独立的服务 Registrar)1407.1.1.3. 客户端发现1417.1.1.4. 服务端发现1427.1.1.5. Consul1427.1.1.6. Eureka1427.1.1.7. SmartStack1427.1.1.8. Etcd1427.1.2. API 网关1427.1.2.1. 请求转发1437.1.2.2. 响应合并1437.1.2.3. 协议转换1
31、437.1.2.4. 数据转换1437.1.2.5. 安全认证1447.1.3. 配置中心1447.1.3.1. zookeeper 配置中心1447.1.3.2. 配置中心数据分类1447.1.4. 事件调度(kafka)1447.1.5. 服务跟踪(starter-sleuth)1447.1.6. 服务熔断(Hystrix)1457.1.6.1. Hystrix 断路器机制1467.1.7. API 管理1468.NETTY 与 RPC1478.1.1. Netty 原理1478.1.2. Netty 高性能1478.1.2.1. 多路复用通讯方式1478.1.2.1. 异步通讯 NIO1
32、488.1.2.2. 零拷贝(DIRECT BUFFERS 使用堆外直接内存)1498.1.2.3. 内存池(基于内存池的缓冲区重用机制)1498.1.2.4. 高效的 Reactor 线程模型149Reactor 单线程模型149Reactor 多线程模型150主从 Reactor 多线程模型1508.1.2.5. 无锁设计、线程绑定1518.1.2.6. 高性能的序列化框架151小包封大包,防止网络阻塞152软中断 Hash 值和 CPU 绑定1528.1.3. Netty RPC 实现1528.1.3.1. 概念1528.1.3.2. 关键技术1528.1.3.3. 核心流程1528.1
33、.3.1. 消息编解码153息数据结构(接口名称+方法名+参数类型和参数值+超时时间+ requestID)153序列化1548.1.3.1. 通讯过程154核心问题(线程暂停、消息乱序)154通讯流程154requestID 生成-AtomicLong154存放回调对象 callback 到全局 ConcurrentHashMap154synchronized 获取回调对象 callback 的锁并自旋 wait154监听消息的线程收到消息,找到 callback 上的锁并唤醒1558.1.4. RMI 实现方式1558.1.4.1. 实现步骤1558.1.5. Protoclol Buff
34、er1568.1.5.1. 特点1578.1.6. Thrift1579.网络1599.1.1. 网络 7 层架构1599.1.2. TCP/IP 原理1609.1.2.1. 网络访问层(Network Access Layer)1609.1.2.2. 网络层(Internet Layer)1609.1.2.3. 传输层(Tramsport Layer-TCP/UDP)1609.1.2.4. 应用层(Application Layer)1609.1.3. TCP 三次握手/四次挥手1619.1.3.1. 数据包说明1619.1.3.2. 三次握手1629.1.3.3. 四次挥手1639.1.4
35、. HTTP 原理1649.1.4.1. 传输流程1641:地址解析1642:封装 HTTP 请求数据包1653:封装成 TCP 包并建立连接1654:客户机发送请求命1655:服务器响应1656:服务器关闭 TCP 连接1659.1.4.2. HTTP 状态1659.1.4.3. HTTPS166建立连接获取证书167证书验证167数据加密和传输1679.1.5. CDN 原理1679.1.5.1. 分发服务系统1679.1.5.2. 负载均衡系统:1689.1.5.3. 管理系统:16810.日志16910.1.1. Slf4j16910.1.2. Log4j16910.1.3. LogB
36、ack16910.1.3.1. Logback 优点16910.1.4. ELK17011. ZOOKEEPER17111.1.1. Zookeeper 概念17111.1.1. Zookeeper 角色17111.1.1.1. Leader17111.1.1.2. Follower17111.1.1.3. Observer17111.1.1.1. ZAB 协议172事务编号 Zxid(事务请求计数器+ epoch)172epoch172Zab 协议有两种模式-恢复模式(选主)、广播模式(同步)172ZAB 协议 4 阶段172Leader election(选举阶段-选出准 Leader)1
37、72Discovery(发现阶段-接受提议、生成 epoch、接受 epoch)173Synchronization(同步阶段-同步 follower 副本)173Broadcast(广播阶段-leader 消息广播)173ZAB 协议 JAVA 实现(FLE-发现阶段和同步合并为 Recovery Phase(恢复阶段)17311.1.1.2. 投票机制17311.1.2. Zookeeper 工作原理(原子广播)17411.1.3. Znode 有四种形式的目录节点17412. KAFKA17512.1.1. Kafka 概念17512.1.2. Kafka 数据存储设计17512.1.2
38、.1. partition 的数据文件(offset,MessageSize,data)17512.1.2.2. 数据文件分段 segment(顺序读写、分段命令、二分查找)17612.1.2.3. 数据文件索引(分段索引、稀疏存储)17612.1.3. 生产者设计17612.1.3.1. 负载均衡(partition 会均衡分布到不同 broker 上)17612.1.3.2. 批量发送17712.1.3.3. 压缩(GZIP 或 Snappy)17712.1.1. 消费者设计17712.1.1.1. Consumer Group17813. RABBITMQ17913.1.1. 概念179
39、13.1.2. RabbitMQ 架构17913.1.2.1. Message18013.1.2.2. Publisher18013.1.2.3. Exchange(将消息路由给队列 )18013.1.2.4. Binding(消息队列和交换器之间的关联)18013.1.2.5. Queue18013.1.2.6. Connection18013.1.2.7. Channel18013.1.2.8. Consumer18013.1.2.9. Virtual Host18013.1.2.10. Broker18113.1.3. Exchange 类型18113.1.3.1. Direct 键(r
40、outing key)分布:18113.1.3.2. Fanout(广播分发)18113.1.3.3. topic 交换器(模式匹配)18214. HBASE18314.1.1. 概念18314.1.2. 列式存储18314.1.3. Hbase 核心概念18414.1.3.1. Column Family 列族18414.1.3.2. Rowkey(Rowkey 查询,Rowkey 范围扫描,全表扫描)18414.1.3.3. Region 分区18414.1.3.4. TimeStamp 多版本18414.1.4. Hbase 核心架构18414.1.4.1. Client:18514.1
41、.4.2. Zookeeper:18514.1.4.3. Hmaster18514.1.4.4. HregionServer18514.1.4.5. Region 寻址方式(通过 zookeeper .META)18614.1.4.6. HDFS18614.1.5. Hbase 的写逻辑18714.1.5.1. Hbase 的写入流程187获取 RegionServer187请求写 Hlog187请求写 MemStore18714.1.5.2. MemStore 刷盘187全局内存控制188MemStore 达到上限188RegionServer 的 Hlog 数量达到上限188手工触发188
42、关闭 RegionServer 触发188Region 使用 HLOG 恢复完数据后触发18814.1.6. HBase vs Cassandra18815. MONGODB19015.1.1. 概念19015.1.2. 特点19016. CASSANDRA19216.1.1. 概念19216.1.2. 数据模型192Key Space(对应 SQL 数据库中的 database)192Key(对应 SQL 数据库中的主键)192column(对应 SQL 数据库中的列)192super column(SQL 数据库不支持)192Standard Column Family(相对应 SQL 数
43、据库中的 table)192Super Column Family(SQL 数据库不支持)19216.1.3. Cassandra 一致 Hash 和虚拟节点192一致性 Hash(多米诺 down 机)192虚拟节点(down 机多节点托管)19316.1.4. Gossip 协议193Gossip 节点的通信方式及收敛性194Gossip 两个节点(A、B)之间存在三种通信方式(push、pull、push&pull)194gossip 的协议和 seed list(防止集群分列)19416.1.5. 数据复制194Partitioners(计算 primary key token 的hash 函数)194两种可用的复制策略:194SimpleStrategy:仅用于单数据中心,194将第一个 replica 放在由 partitioner 确定的节点中,其余的replicas 放在上述节点顺时针方向的后续节点中。194NetworkTopologyStrategy:可用于较复杂的多数据中心。194可以指定在每个数据中心分别存储多少份 r