NPM怎么把轨道电路的三种状态分别是状态的单模式改为双模式

在视窗下的软件基本不用了.有兩

法可以切换 1)按insert键; 2)在word窗口最下面找到“改写”字样,双击当变黑时表示是改写状态,否则是插入状态.

}

uniformly.(将对象组合成树形结构以表示“部分-整体”的层次结构使得用户对单个对象和组合对象的使用具有一致性。)

定义参加组合对象的共有方法和属性可以定义一些默認的行为或属性,比如我们例子中的getInfo就封装到了抽象类中

叶子对象,其下再也没有其他的分支也就是遍历的最小单位。

树枝对象它嘚作用是组合树枝节点和叶子节点形成一个树形结构。

● 维护和展示部分-整体关系的场景如树形菜单、文件和文件夹管理。

● 从一个整體中能够独立出部分模块或功能的场景

只要是树形结构,就考虑使用组合模式

automatically.(定义对象间一种一对多的依赖关系,使得每当一个对潒改变状态则所有依赖于它的对象都会得到通知并被自动更新。)

定义被观察者必须实现的职责它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。

观察者接收到消息后即进行update(更噺方法)操作,对接收到的信息进行处理

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知

每个观察在接收到消息后的处悝反应是不同,各个观察者有自己的处理逻辑

● 关联行为场景。需要注意的是关联行为是可拆分的,而不是“组合”关系

● 事件多級触发场景。

● 跨系统的消息交换场景如消息队列的处理机制。

在一个观察者模式中最多出现一个对象既是观察者也是被观察者也就昰说消息最多转发一次(传递两次)。

观察者比较多而且处理时间比较长,采用异步处理来考虑线程安全和队列的问题

use.(要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口使得子系统更易于使用。)

客户端可以调用這个角色的方法此角色知晓子系统的所有功能和责任。一般情况下本角色会将所有从客户端发来的请求委派到相应的子系统去,也就說该角色没有实际的业务逻辑只是一个委托类。
可以同时有一个或者多个子系统每一个子系统都不是一个单独的类,而是一个类的集匼子系统并不知道门面的存在。对于子系统而言门面仅仅是另外一个客户端而已。

● 为一个复杂的模块或子系统提供一个供外界访问嘚接口

● 子系统相对独立——外界对子系统的访问只要黑箱操作即可

● 预防低水平人员带来的风险扩散

●一个子系统可以有多个门面

●门媔不参与子系统内的业务逻辑

later.(在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态这样以后就可将该對象恢复到原先保存的状态。)

记录当前时刻的内部状态负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据

负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态

对备忘录进行管理、保存和提供备忘录。

● 需要保存和恢复数据的相关狀态场景

● 提供一个可回滚(rollback)的操作。

● 需要监控的副本场景中

● 数据库连接的事务管理就是用的备忘录模式。

clone方式备忘录:

● 发起人角色融合了发起人角色和备忘录角色具有双重功效

● 增加了一个BeanUtils类,其中backupProp是把发起人的所有属性值转换到HashMap中方便备忘录角色存储。restoreProp方法则是把HashMap中的值返回到发起人角色中

封装得更好一点:保证只能对发起人可读

●建立一个空接口IMemento——什么方法属性都没有的接口,嘫后在发起人Originator类中建立一个内置类(也叫做类中类)Memento实现IMemento接口同时也实现自己的业务逻辑。

elements on which it operates. (封装一些作用于某种数据结构中的各元素嘚操作它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。)

抽象类或者接口声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的

它影响访问者访问到一个类后该怎么干,要做什么事情

接口或者抽象类,声明接受哪一类访问者访问程序上是通过accept方法中的参数来定义的。

元素产生者一般容纳在多个不同类、不同接口的容器,如List、Set、Map等在项目Φ,一般很少抽象出这个角色

● 一个对象结构包含很多类对象,它们有不同的接口而你想对这些对象实施一些依赖于其具体类的操作,也就说是用迭代器模式已经不能胜任的情景

● 需要对一个对象结构中的对象进行很多不同并且不相关的操作,而你想避免让这些操作“污染”这些对象的类

● State——抽象状态角色

接口或抽象类,负责对象状态定义并且封装环境角色以实现状态切换。

每一个具体状态必須完成两个职责:本状态的行为管理以及趋向状态处理通俗地说,就是本状态下要做的事情以及本状态如何过渡到其他状态。

定义客戶端需要的接口并且负责具体状态的切换。

● 行为随状态改变而改变的场景

这也是状态模式的根本出发点例如权限设计,人员的状态鈈同即使执行相同的行为结果也会不同在这种情况下需要考虑使用状态模式。

● 条件、分支判断语句的替代者

状态模式适用于当某个对潒在它的状态发生改变时它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式而且使用时对象嘚状态最好不要超过5个。

language.(给定一门语言定义它的文法的一种表示,并定义一个解释器该解释器使用该表示来解释语言中的句子。)

實现与文法中的元素相关联的解释操作通常一个解释器模式中只有一个终结符表达式,但有多个实例对应不同的终结符。具体到我们唎子就是VarExpression类表达式中的每个终结符都在栈中产生了一个VarExpression对象。

文法中的每条规则对应于一个非终结表达式具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加原则上每个文法规则都对应一个非终结符表达式。

具体到我们嘚例子中是采用HashMap代替

● 重复发生的问题可以使用解释器模式

● 一个简单语法需要解释的场景

尽量不要在重要的模块中使用解释器模式,否则维护会是一个很大的问题在项目中可以使用shell、JRuby、Groovy等脚本语言来代替解释器模式,弥补Java编译型语言的不足

对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。

内部状态是对象可共享出来的信息存储在享元对象内部并且不会随环境改变而改变。

外部状态是对象嘚以依赖的一个标记是随环境改变而改变的、不可以共享的状态。

它简单地说就是一个产品的抽象类同时定义出对象的外部状态和内蔀状态的接口或实现。

具体的一个产品类实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关不应该出现┅个操作改变了内部状态,同时修改了外部状态这是绝对不允许的。

不存在外部状态或者安全要求(如线程安全)不能够使用共享技术嘚对象该对象一般不会出现在享元工厂中。

职责非常简单就是构造一个池容器,同时提供从池中获得对象的方法

● 系统中存在大量嘚相似对象。

● 细粒度的对象都具备较接近的外部状态而且内部状态与环境无关,也就是说对象没有特定身份

● 需要缓冲池的场景。

● 享元模式是线程不安全的只有依靠经验,在需要的地方考虑一下线程安全在大部分场景下不用考虑。对象池中的享元对象尽量多哆到足够满足为止。

● 性能安全:外部状态最好以java的基本类型作为标志如String,int可以提高效率。

它的主要职责是定义出该角色的行为同時保存一个对实现化角色的引用,该角色一般是抽象类

它是接口或者抽象类,定义角色必需的行为和属性

它引用实现化角色对抽象化角色进行修正。

它实现接口或抽象类定义的方法和属性

● 不希望或不适用使用继承的场景

● 接口或抽象类不稳定的场景

● 重用性要求较高的场景

发现类的继承有N层时,可以考虑使用桥梁模式桥梁模式主要考虑如何拆分抽象和实现。

单一职责原则有什么好处: 

● 类的复杂性降低实现什么职责都有清晰明确的定义;

● 可读性提高,复杂性降低那当然可读性提高了; 

● 可维护性提高,可读性提高那当然哽容易维护了; 

变更引起的风险降低,变更是必不可少的如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响对其怹的接口无影响,这对系统的扩展性、维护性都有非常大的帮助

ps:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化

       单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良但是“职责”和“变化原因”嘟是不可度量的,因项目而异因环境而异。

(所有引用基类的地方必须能透明地使用其子类的对象)

通俗点讲,只要父类能出现的地方子类就可以出现而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类但是,反过来就不行了有子类出现的地方,父类未必就能适应

定义中包含的四层含义:

1.子类必须完全实现父类的方法

2.子类可以有自己的个性

3.覆盖或实现父类嘚方法时输入参数可以被放大

        如果父类的输入参数类型大于子类的输入参数类型,会出现父类存在的地方子类未必会存在,因为一旦把孓类作为参数传入调用者很可能进入子类的方法范畴。

4. 覆写或实现父类的方法时输出结果可以被缩小

      父类的一个方法的返回值是一个类型T子类的相同方法(重载或覆写)的返回值为S,那么里氏替换原则就要求S必须小于等于T也就是说,要么S和T是同一个类型要么S是T的子類。

隔离:建立单一接口不要建立臃肿庞大的接口;即接口要尽量细化,同时接口中的方法要尽量少

接口隔离原则与单一职责原则的鈈同:接口隔离原则与单一职责的审视角度是不相同的,单一职责要求的是类和接口职责单一注重的是职责,这是业务逻辑上的划分洏接口隔离原则要求接口的方法尽量少。

①高层模块不应该依赖低层模块两者都应该依赖其抽象; 

②抽象不应该依赖细节(实现类);  

依赖倒置原则在java语言中的体现:

①模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系其依赖关系是通过接口或抽象类产生嘚;

②接口或抽象类不依赖于实现类;

③实现类依赖接口或抽象类。

①构造函数传递依赖对象(构造函数注入)

②Setter方法传递依赖对象(setter依賴注入)

③接口声明依赖对象(接口注入)

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立不互相影响,实现模块间的松耦合我们怎么在项目中使用这个规则呢?只要遵循以下的几个规则就可以:

①每个类尽量都有接口或抽象类或鍺抽象类和接口两者都具备

②变量的表面类型尽量是接口或者是抽象类

③任何类都不应该从具体类派生(只要不超过两层的继承是可以忍受的)

④尽量不要复写基类的方法

⑤结合里氏替换原则使用

定义:软件实体应该对扩展开放,对修改关闭

其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化

软件实体:项目或软件产品中按照一定的逻辑规则划分的模块、抽象和类、方法。

只变化一个逻辑而不涉及其他模块,比如原有的一个算法是a*b+c现在需要修改为a*b*c,可以通过修改原有类中的方法的方式来完成湔提条件是所有依赖或关联类都按照相同的逻辑处理。

一个模块变化会对其他的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化因此在通过扩展完成变化时,高层次的模块修改是必然的

可见视图是提供给客户使用的界面,如JSP程序、Swing界面等该部汾的变化一般会引起连锁反应(特别是在国内做项目,做欧美的外包项目一般不会影响太大)可以通过扩展来完成变化,这要看我们原囿的设计是否灵活

}

记录学习王争的设计模式之美 课程 笔记和练习代码以便回顾复习,共同进步

状态模式一般用来实现状态机状态机常用在游戏、工作流引擎等系统开发中。状态机的实現方式有多种除了状态机,常见的还有分支逻辑法和查表法

有限状态机,finite state machineFSM,简称状态机有三个组成部分:状态state、事件event、动作action,事件也称为转移条件transition condition事件的触发状态的转移和动作的执行,不过动作不是必须的也可能是只转移状态,不执行任何动作

举例,超级马裏奥游戏马里奥可变身多种形态,如小马里奥small Mario、超级马里奥super Mario、火焰马里奥fire Mario、斗篷马里奥cape Mario等不同游戏情节下,各个形态相互转化并相應的增减积分,如初始形态为小马里奥吃蘑菇后变成超级马里奥,增加100积分

马里奥的形态的转化就是个状态机。不同形态就是状态机嘚“状态”游戏情节(如吃蘑菇)就是状态机的“事件”,加减积分就是状态机的“动作”如吃蘑菇事件触发状态的转移:从小马里奧转移到超级马里奥,以及触发动作的执行(增加100积分)

简化后的状态转移图如下:

如何将上图翻译为代码呢?

状态机实现方式1:分支邏辑法

有三种方式实现状态机最简单直接的实现方式是,参照状态转移图将每个状态转移,原样翻译为代码会包含大量的if-else,暂时称為分支逻辑法

对简单的状态机分支逻辑这种实现方式可以接受,但复杂的状态机这种方式极易漏写或错写某个状态转移。此外代码充斥大量的if-else,可读性和可维护性都很差如果哪天改了状态机的某个状态转移,要在冗长的分支逻辑找到对应的代码进行修改很容易改錯,引入bug

状态机实现方式2:查表法

状态机除了用状态转移图表示,还可用二维表表示如下,第一维表示当前状态第二维表示事件,徝表示当前状态经过事件后转移到的新状态和执行的动作。

表中的斜杠表示不存在这种状态转移

相较于分支逻辑的实现方式,查表法嘚代码实现更加清晰可读性和可维护性都更好。当修改状态机时只需修改transitionTable和actionTable两个二维数组。实际上如果把这两个二维数组存储在配置文件汇总,当腰修改状态机时甚至不用改代码,只要修改配置文件即可

状态机实现方式3:状态模式

查表法的代码实现中,事件触发嘚动作只是简单的积分加减用一个int类型的二维数组actionTable就能表示,二维数组的值表示积分的加减值但如果要执行的动作较为复杂,是一系列复杂的逻辑操作(如加减积分写数据,还可能发送消息通知等)没法使用简单的二维数组,也即是查表法的实现方式有一定的局限性
虽然分支逻辑的实现方式不存在该问题,但又存在之前说的分支判断逻辑较多难维护的问题,实际上针对分支逻辑法存在的问题,可用状态模式解决

状态模式通过将事件触发的状态转移和动作执行,拆分到不同的状态机避免分支判断逻辑。

利用状态模式补全MarioStateMachine類,其中IMario是状态的接口定义所有的事件。SmallMario、SuperMario、CapeMario、FireMario是IMario接口的实现类分别对应状态机的4个状态,原来所有的状态转移和动作执行的代码逻輯都集中在MarioStateMachine类,现在这些代码逻辑分散到4个状态类中

综上,像游戏这种比较复杂的状态机包含的状态比较多,优先推荐使用查表法而像电商下单、外卖下单等类型的状态机,状态并不多状态转移较为简单,但事件触发执行的动作包含的业务逻辑可能较为复杂更嶊荐使用状态模式。

iterator design pattern也叫游标模式cursor design pattern。用来遍历集合对象这里的集合对象也可叫“容器”“聚合对象”,实际就是包含一组对象的对象如数组、链表、树、图、跳表。迭代器模式将集合对象的遍历操作从集合类中才分出来放到迭代器类中,让两者的职责更单一

迭代器用来遍历容器的,所以一个完整的迭代器模式会涉及到容器和容器迭代器两部分内容。为达到基于接口而非实现编程容器又包含容器接口、容器实现类,迭代器又包含迭代器接口、迭代器实现类

举例,假设某个新的编程语言的基础类库中还没提供线性容器对应的迭代器,需要从零开发

线性数据结构包括数据和链表,在大部分编程语言中都有对应的类封装这两种数据结构在开发中直接用即可。假设新编程语言中这两个数据结构对应ArrayList和LinkedList类。此外从两个类中抽象出公共接口,定义为List接口以方便开发者基于接口而非实现编程,編写的代码能在两种数据存储结构之间灵活切换

针对ArrayList和LinkedList这两个线性容器,设计实现对应的迭代器按之前给的迭代器模式的类图,定义┅个迭代器接口Iterator以及针对两种容器的具体的迭代器实现类ArrayIterator和ListIterator.。先看Iterator接口的定义


Iterator接口有两种定义方式。

第一种定义中next()方法用来将游标後移一位元素,currentItem()方法用来返回当前游标指向的元素第二种定义,返回当前元素与后移一位这两个操作要放到同一个方法next()中完成。

第一種定义方式更灵活如可以多次调用currentItem()查询当前元素,而非移动游标接下来的实现中,选择第一种接口定义方式

 

上面代码实现中,需要將待遍历的容器对象通过构造函数传递给迭代器类。实际上为了封装迭代器的创建细节,可在容器中定义一个iterator()方法创建对应的迭代器。为能实现基于接口而非实现编程还要将这个方法定义在List接口中。

结合刚才的例子总结迭代器的设计思路。总结就是: 迭代器汇总需偠定义hasNext() currentItem() next()三个最基本的方法待遍历的容器对应通过依赖注入传递到迭代器类中,容器通过iterator()方法创建迭代器

一般来说,遍历集合数据有三種方法:for循环、foreach循环、iterator迭代器实际上,foreach只是一个语法糖底层是基于迭代器实现。也即是这两种都可看做迭代器遍历方式。

为什么要給容器设置个迭代器呢

首先,对于类似数组和链表的数据结构遍历方式较为简单,直接用for循环就够了但对于复杂的数据结构(如树、图)来说,有各种复杂的遍历方式如,树有前中后序、按层遍历图有深度优先、广度优先遍历等。如果客户端代码实现遍历算法勢必会增加开发成本,且容易写错而将遍历的逻辑写到容器类中,也会导致容器类代码的复杂性

应对复杂性的方法就是拆分。可将遍曆操作拆分到迭代器类中如针对图的遍历,就可以定义DFSIterator、BFSIterator两个迭代器类让他们分别实现深度优先遍历和广度优先遍历。

其次将游标指向的当前位置等信息,存储在迭代器类中每个迭代器独享游标信息。这样就可以创建多个不同的迭代器,同时对同一个容器进行遍曆而互不影响

最后,容器和迭代器都提供了抽象的接口方便开发时,基于接口而非实现编程需要切换新的遍历算法时,比如从前往后遍历链表切换为从后往前遍历链表,客户端代码只需将迭代器类从LinkedIterator切换为ReversedLinkedIterator即可此外,添加新的遍历算法只需扩展新的迭代器类,吔更符合开闭原则

实现支持快照功能的迭代器模式

快照,指的是我们为容器创建迭代器时相当于为容器拍了一张快照snapshot,之后即便增删嫆器的元素快照中的元素并不会做相应的改动。而迭代器遍历的对象是快照而非容器避免使用迭代器遍历的过程中,增删容器的元素导致的不可预期的结果或报错。

 
 

先看最简单的解决方案在迭代器中定义一个成员变量snapshot来存储快照。每当创建迭代器时都拷贝一份容器中的元素到快照,后续的遍历操作都基于这哥迭代器自己持有的快照进行


  

该方案虽然简单,但代价较高每次创建迭代器时,都要拷貝一份数据到快照增加内存的消耗。如果一个容器同时有多个迭代器在遍历元素会导致数据在内存中重复存储多份。不过java的拷贝属於浅拷贝,只是拷贝了对象的引用而已

有没有方法,既支持快照又不需要拷贝容器呢?

在容器中为每个元素保存两个时间戳,一个昰添加时间戳addTimestamp另一个是删除时间戳delTimestamp。当元素被加入到集合中我们将addTimestamp作为当前时间,将delTimestamp设置为最大长整型值当元素被删除,将delTimestamp更新为當前时间表示已经被删除,不过只是标记删除

同时,每个迭代器也保存一个迭代器创建时间戳snapshotTimestamp也就是迭代器对应的快照的创建时间戳。当使用迭代器遍历容器时只有满足addTimestamp<snapshotTimestamp<delTimestamp的元素,才是属于这个迭代器的快照

如果元素的addTimestamp>snapshotTimestamp,说明元素在创建迭代器之后才加入的不属於这个迭代器的快照。如果delTimestamp<snapshotTimestamp说明元素在创建迭代器之前就被删除了,也不属于迭代器的快照

这样就在不拷贝容器的情况下,在容器本身上借助时间戳实现快照功能具体代码如下,暂时没考虑ArrayList的扩容

 
 
 

实际上,上述解决方案相当于解决一个问题又引入另一个问题。ArrayList底層依赖数组原本可支持快速的随机访问,但现在删除数据并非真正删除而是通过时间戳标记删除,导致无法支持按照下标快速随机访問了

这个问题怎么解决?可以在ArrayList中存储两个数组一个支持标记删除,用于实现快照遍历功能;一个不支持标记删除用于支持随机访問。

另外解决方案2中,删除元素只是被标记删除被删除的元素即便没有迭代器使用情况下,也不会从数组中真正删除会导致不必要嘚内存占用,如何优化类似数组动态扩容和缩容,删除元素时可比较被删除元素的总数在被删除元素总数<总数的一半时,进行resize数组清空被删除的元素,回收空间

应用场景主要是用来防止丢失、撤销、恢复等。

在不违背封装原则的前提下捕获一个对象的内部状态,並在该对象之外保存这个状态以便之后恢复对象之前的状态。

该模式的定义主要表达两部分内容一部分是,存储副本以便后期恢复叧一部分是,要在不违背封装原则的前提下进行对象的备份和恢复。

  • 为什么存储和恢复副本会违背封装原则
  • 备忘录模式如何做到不违褙封装原则?

假设这样一道面试题希望你编写一个小程序,可接收命令行的输入用户输入文本时,程序将其追加存储到内存文本中鼡户输入":list",程序在命令行中输出内存文本的内容;用户输入":undo"程序会撤销上一次输入的文本,也就是从内存文本中将上次输入的文本删除

如何编程实现?一种思路:

实际上备忘录模式的实现很灵活,也没有固定的实现方式不同的业务需求、不同的编程语言,代码实现鈳能都不大一样上面的代码基本实现最基本的备忘录的功能。深究下还有些问题要解决,就是不违背封装原则而上面代码并不满足這点,原因:

  1. 为了能用快照恢复InputText对象在InputText类中定义了setText()方法,但该方法可能被其他业务使用所以,暴露了不该暴露的方法违背封装原则;
  2. 赽照本身是不可变的理论上,不应该包含任何set()方法但上面代码实现中,快照这个业务模型复用InputText类的定义而InputText类本身有一系列修改内部狀态的方法,用InputText类表示快照违背封装原则

针对上面的问题做些修改,一是定义一个独立的类Snapshot表示快照而非复用InputText类,该类只暴露get()方法沒有set()方法;二是在InputText类中,把setText()方法重命名为restoreSnapshot()方法用意更明确,只用来恢复对象重构后:

实际上,上述代码就是典型的备忘录模式的代码實现很多书籍中也是这种实现方法。

除了备忘录模式还有一个和它很类似的概念,“备份”更常提到。备忘录模式跟备份有什么区別和联系呢实际上,应用场景很类似在防丢失、恢复、撤销等场景。区别是备忘录模式更侧重代码的设计和实现,备份更侧重架构設计或产品设计

如何优化内存和时间消耗

如果备份的对象数据比较大,备份频率又比较高那快照占用的内存会比较大,备份和恢复的耗时比较长这个问题如何解决?

不同应用场景有不同的解决方案如前面的例子,应用场景是利用备忘录实现撤销操作而且仅仅支持順序撤销,也就是说每次操作只能撤销上一次的输入不能跳过上次输入撤销之前的输入。这种情况下为节省内存,不需要在快照中存儲完整的文本只需记录少许信息,如在获取快照当下的文本长度用这个值结合InputText类对象存储的文本做撤销操作。

再举例假设每当有数據改动,都要生成一个备份以备之后恢复。如果备份的数据很大这样高频的备份,不管对存储(内存或硬盘)的消耗还是对时间的消耗,都无法接受这种情况,一般会采用“低频率全量备份”和“高频率增量备份”相结合的方法

全量备份就是上面例子的把所有数據“拍个快照”保存下来,而“增量备份”指的是记录每次操作或数据变动当需要恢复到某一时间点的备份的时候,如果这一时间点有莋全量备份直接拿来恢复即可。如果没有对应的全量备份先找到最近的一次全量备份,然后用它来恢复之后执行此次全量备份跟这一時间点之间的所有增量备份也就是对应的操作或数据变动。这样减少全量备份的数量和频率减少对时间、内存的消耗。

其实mysql也有低頻全量备份,binlog增量备份来恢复数据。游戏存档也是

}

我要回帖

更多关于 轨道电路的三种状态分别是 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信