本系列文章由@浅墨_毛星云 出品,转载请注明出处。  
文章链接: http://blog.csdn.net/poem_qianmo/article/details/52663057
作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442


这篇文章起源于《Game Programming Patterns》第二章第一节,将与大家一起探索游戏开发中命令模式的用法。

命令模式的成名应用是实现诸如撤消,重做,回放,时间倒流之类的功能。如果你想知道《Dota2》中的观战系统、《魔兽争霸3》中的录像系统、《守望先锋》的全场最佳回放系统可能的一些实现思路,这篇文章或许就能给你一些启示。


 




一、本文涉及知识点思维导图

 


还是国际惯例,先放出这篇文章所涉及内容知识点的一张思维导图,就开始正文。大家若是疲于阅读文章正文,直接看这张图,也是可以Get到本文的主要知识点的大概。单看总结的这些概念还是太抽象,关键还是在于文中三、四、五节中的代码与图示。

 


 



二、命令模式的定义


 

在许多大型游戏中,都可以见到命令模式(Command Pattern)的身影。设计模式界的扛鼎之作《Design Patterns: Elements ofReusable Object-Oriented Softwar》(中译版《设计模式:可复用面向对象软件的基础》) 一书的作者四人帮Gang of Four对命令模式这样概括:


命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。Encapsulate a request as an object, therebyletting you parameterizeclients with different requests, queue or log requests,and support undoable operations.

 

这句话解读版本应该是这样:将一组行为抽象为对象,这个对象和其他对象一样可以被存储和传递,从而实现行为请求者与行为实现者之间的松耦合,这就是命令模式。

接着看看Gang of Four随后提出的另一个阐述:


 命令模式是回调机制的面向对象版本。Commands are an object-oriented replacementfor callbacks.

 

这句话从另一个方面道出了命令模式的思想,它是回调的面向对象版本。

OK,定义都给出了,不妨我们举一些栗子,在实际例子中看看命令模式到底能带给我们哪些惊喜。

 

 

 

 

三、引例



每个游戏都有一些代码块用来读取用户的输入操作,按钮点击,键盘事件,鼠标点击,或者其他输入。这些代码记录每次的输入,并将之转换为游戏中一个有意义的动作(action),如下图:

 

一种最简单粗暴的实现大概是这样:

void InputHandler::handleInput()
{if(isPressed(BUTTON_X)) jump();else if (isPressed(BUTTON_Y)) fireGun();else if (isPressed(BUTTON_A)) swapWeapon();else if (isPressed(BUTTON_B)) lurchIneffectively();
}

我们知道,这个函数通常会通过游戏循环被每帧调用。这段代码在我们想将用户的输入和程序行为硬编码在一起时,是完全可以胜任自身的工作的。但如果想实现用户自定义配置他们的按钮与动作的映射,就需要进行修改了。

为了支持自定义配置,我们需要把那些对 jump() 和 fireGun() 的直接调用转换为我们可以换出(swap out)的东西。”换出“(swapping out)听起来很像分配变量,所以我们需要个对象来代表一个游戏动作。这就用到了命令模式。

于是,我们定义了一个基类用来代表一个可激活的游戏命令:

class Command
{
public:virtual ~Command() {}virtual void execute() = 0;
};

然后我们为每个不同的游戏动作创建一个子类,public继承自我们的Command类:

class JumpCommand : public Command
{
public:virtual void execute() { jump(); }
};class FireCommand : public Command
{
public:virtual void execute() { fireGun(); }
};

在负责输入处理的InputHandler中,我们为为每个键存储一个指向Command的指针。

class InputHandler
{
public:void handleInput();//Methods to bind commands...private:Command* buttonX_;Command* buttonY_;Command* buttonA_;Command* buttonB_;
}; 

那么现在,InputHandler就可以该写成这样:

void InputHandler::handleInput()
{if(isPressed(BUTTON_X)) buttonX_->execute();else if (isPressed(BUTTON_Y)) buttonY_->execute();else if (isPressed(BUTTON_A)) buttonA_->execute();else if (isPressed(BUTTON_B)) buttonB_->execute();
}

不难理解,以前每个输入都会直接调用一个函数,现在则会有一个间接调用层。那么图示看起来就是这样:

 

这就是命令模式的最基础的实现,按照其思路画了一个大概的型出来。

简而言之,命令模式的关键在于引入了抽象命令接口(execute( )方法),且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。而且命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。

 




四、进一步地使用命令模式

 


我们刚才定义的命令类在上个例子中可以跑得起来,但很受限。问题在于,他们假设存在jump() , fireGun() 等这样的函数能与玩家关联并控制玩家。这种假设耦合限制了这些命令的的效用。JumpCommand类唯一能做的事情就是控制玩家的跳跃。让我们放宽限制,传进去一个我们想要控制的对象进去,而不是用命令对象自身来调用函数:

class Command
{
public:virtual ~Command() {}virtual void execute(GameActor& actor) = 0;
};

这里GameActor是代表游戏世界中角色的“游戏对象”类。 我们将其传给execute(),这样可以在它的子类中添加函数,来与我们选择的角色关联,就像这样:

class JumpCommand : public Command
{
public:virtual void execute(GameActor& actor){actor.jump();}
};

现在,我们可以使用这个类控制游戏中的任何角色。 还少了一块在输入控制和在正确的对象上起作用之间的代码。 首先,我们修改handleInput()这样它可以返回命令:

Command* InputHandler::handleInput()
{if(isPressed(BUTTON_X)) return buttonX_;if(isPressed(BUTTON_Y)) return buttonY_;if(isPressed(BUTTON_A)) return buttonA_;if(isPressed(BUTTON_B)) return buttonB_;//Nothing pressed, so do nothing.return NULL;
}

这段代码不能直接执行命令,因为它并不知道该传入那个角色对象。命令是一个对象化的调用,是回调的面向对象版本,这里正是我们可以利用的地方——我们可以延迟调用。我们需要一些代码来保存命令并且执行对玩家角色的调用。像下面这样:

Command* command =inputHandler.handleInput();
if (command)
{command->execute(actor);
}

假设 actor 是玩家角色的一个引用,这将会基于用户的输入来驱动角色,所以我们可以赋予角色与前例一致的行为。在命令和角色之间加入的间接层使得我们可以让玩家控制游戏中的任何角色,只需通过改变命令执行时传入的角色对象即可。

目前我们只考虑了玩家驱动角色(player-driven character),但是对于游戏世界中的其他角色呢?他们由游戏的AI来驱动。我们可以使用相同的命令模式来作为AI引擎和角色的接口;AI代码部分提供命令(Command)对象用来执行。代码如下:

command->execute(AI对象);

AI选择命令,角色执行命令,它们之间的解耦给了我们很大的灵活性。我们可以为不同的角色使用不同的AI模块。或者我们可以为不同种类的行为混合AI。你想要一个更加具有侵略性的敌人?只需要插入一段更具侵略性的AI代码来为它生成命令即可。

事实上,我们甚至可以将AI使用到玩家的角色身上,这对于像游戏需要自动运行的demo模式是很有用的。

通过将控制角色的命令作为对象,我们便去掉了直接调用指定函数这样的紧耦合。我们不妨将这样的方式理解成一个队列或者一个命令流(queue or stream of commands):

 

如图,一些代码(输入控制器或者AI)产生一系列指令然后将其放入流中。 另一些指令(调度器或者角色自身)消耗指令并调用他们。这样,通过在中间加入了一个队列,我们解耦了行为请求者和行为实现者。

而且,如果我们把这些命令序列化,便可以通过互联网来发送数据流。可以把玩家的输入通过网络发送到另外一台机器上,然后进行回放,这就是多人网络游戏里面非常重要的一块。

 



 

五、实现撤消与重做功能

 

 

撤消和重做是命令模的成名应用了。如果一个命令对象可以做(do) 一些事情,那么应该可以很轻松的撤消(undo)它们。撤销这个行为经常在一些策略游戏中见到,在游戏中如果你不喜欢的话可以回滚一些步骤。在创建游戏时这是必不可少的的工具之一。

如果你想让游戏策划同事们喷你,最可靠的办法就是在关卡编辑器中不提供撤消功能,让他们不能撤消不小心犯的错误,我保证他们会打你。

利用命令模式,撤消和重做功能实现起来非常容易。假设我们在制作单人回合制游戏,想让玩家能撤消移动,这样他们就可以集中注意力在策略上而不是猜测上,而之前我们已经使用了命令来抽象输入控制,所以每个玩家的举动都已经被封装其中。举个例子,移动一个单位的代码可能如下:

class MoveUnitCommand : public Command
{
public:MoveUnitCommand(Unit* unit, int x, int y): unit_(unit),x_(x),y_(y){}virtual void execute(){unit_->moveTo(x_, y_);}private:Unit* unit_;int x_, y_;
};

注意这和前面的命令模式有些许不同。 在前面的例子中,我们需要从修改的角色那里抽象命令。而在这个例子中,我们将命令绑定到要移动的单位上。这条命令的实例不是通用的“移动某物”指令,而是游戏回合中特殊的一次移动。

这边就可以展示出命令模式的几种形态。 在某些情况下,指令是可重用的对象,代表了可执行的事件。我们在文章开头展示的输入控制将其实现为一个命令对象,然后在按键按下时调用其execute()方法。而这里的命令代表了特定时间点能做的特定事件。这意味着输入控制代码可以在玩家下决定时创造一个实例。就像这样:

Command* handleInput()
{Unit* unit = getSelectedUnit();if (isPressed(BUTTON_UP)) {// Move the unit up one.int destY = unit->y() - 1;return new MoveUnitCommand(unit, unit->x(), destY);}if (isPressed(BUTTON_DOWN)) {// Move the unit down one.int destY = unit->y() + 1;return new MoveUnitCommand(unit, unit->x(), destY);}// Other moves...return NULL;
}

而为了撤消命令,我们定义了一个undo的操作,每个命令类都需要来实现它:

class Command
{
public:virtual ~Command() {}virtual void execute() = 0;virtual void undo() = 0;
};

当然,在像C++这样没有垃圾回收的语言,这意味着执行命令的代码也要负责释放内存。

undo()方法用于回滚execute()方法造成的游戏状态改变。下面我们针对上一个移动命令加入撤消支持:

class MoveUnitCommand : public Command
{
public:MoveUnitCommand(Unit* unit, int x, int y): unit_(unit),xBefore_(0),yBefore_(0),x_(x),y_(y){}virtual void execute(){// Remember the unit's position before the move// so we can restore it.xBefore_ = unit_->x();yBefore_ = unit_->y();unit_->moveTo(x_, y_);}virtual void undo(){unit_->moveTo(xBefore_, yBefore_);}private:Unit* unit_;int xBefore_, yBefore_;int x_, y_;
};

需要注意的是,我们为类添加了更多状态。 当单位移动时,它忘记了它之前是什么样的。 如果我们想要撤销这个移动,我们需要记得单位之前的状态,也就是xBefore_和yBefore_做的事。

其实,这样的实现看起来挺像备忘录模式(https://en.wikipedia.org/wiki/Memento_pattern)的,但是你会发现备忘录模式用在这里并不能愉快地工作。因为命令试图去修改一个对象状态的一小部分,而为对象的其他数据创建快照是浪费内存。只手动存储被修改的部分相对来说就节省很多内存了。

持久化数据结构是另一个选择。通过它们,每次对一个对象进行修改都会返回一个新的对象,保留原对象不变。通过这样的实现,新对象会与原对象共享数据,所以比拷贝整个对象的代价要小得多。使用持久化数据结构,每个命令存储着命令执行前对象的一个引用,所以撤销意味着切换到原来老的对象。

为了让玩家能够撤销一次移动,我们保留了他们执行的上一个命令。当他们敲击Control+Z 时,我们便会调用 undo() 方法。(如果已经撤消了,那么会变为”重做“,我们会再次执行那个命令。)

支持多次撤消也很容易实现。也就是我们不再保存最后一个命令,取而代之保存了一个命令列表和”current“(当前)命令的一个引用。当玩家执行了某个命令时,我们将此命令添加到列表中,并将”current“指向它即可。思路如下图:

 

当玩家选择”撤消“时,我们撤消掉当前的命令并且将当前的指针移回去。当他们选择”重做“,我们将指针前移然后执行命令。如果他们在撤消之后选择了一个新的命令,就把列表中位于当前命令之后的所有命令进行舍弃。

若你是第一次在游戏关卡编辑器中用命令模式实现撤消重做的功能,或许你会惊叹它是如此的简单、高效而且优雅。

 




六、录像与回放系统的实现思路



上文刚刚讲到了如何用命令模式实现撤消与重做。重做在游戏中并不常见,但回放(replay)、录像、观战系统却很常见。一个简单粗暴的实现方法就是记录每一帧的游戏状态以便能够回放,但是这样会占用大量的内存。

所以,许多游戏会记录每一帧每个实体所执行的一系列命令,就可以轻松的实现回放功能。而为了回放游戏,引擎只需要运行正常游戏的模拟,执行预先录制的命令即可。

那我们便可以这样理解,录像与回放等功能,可以基于命令模式实现,也就是执行并解析一系列经过预录制的序列化后的各玩家操作的有序命令集合。以下只是提供一些分析的思路,并不代表这三款游戏当时就是这样实现的:

  • 《魔兽争霸3》中的replay录像,大概就是通过将所有玩家的操作命令,序列化到一个.rep后缀的文件中,然后在游戏中进行解析后回放来实现。
  • 《Dota2》中的录像功能也大致如此,而观战功能也就是通过在线不断获取该局比赛中各个玩家经过序列化后的有序命令流,然后在自己的客户端中解析并重放。
  • 《守望先锋》的回放系统,大概也就是将各个玩家的一系列操作命令通过网络发送到其他玩家的机器上(其实对战过程中就已经在实时发送),然后进行解析后进行模拟回放。(在这篇文章发布近一年以后,通过GDC上的《守望先锋》的talk了解到,《守望先锋》采用的是ECS架构,和本文讲述的命令模式的实现有所不同,但基本设计思想其实也是一致的。


这大致就是各种游戏中录像、回放、观战系统所用的一些设计思路。

 





七、命令模式的要点总结



OK,例子讲完了,下面对命令模式进行一些要点的总结。

 


7.1 命令模式的要点


首先,给出命令模式的UML图:

 

然后,让我们再次看看文章开头给出的GOF对于命令模式的定义:


"命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。"


接着是对命令模式的一些解读与思考:

  • 将一组行为抽象为对象,这个对象和其他对象一样可以被存储和传递,从而实现行为请求者与行为实现者之间的松耦合,这就是命令模式。
  • 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
  • 命令模式是回调机制的面向对象版本。
  • 每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
  • 命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
  • 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
  • 命令模式很适合实现诸如撤消,重做,回放,回退一步,时间倒流之类的功能。



7.2 命令模式的优点


1.对类间解耦。调用者角色与接受者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法即可,不需要了解到底是哪个接收者在执行。

2.可扩展性强。Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client之间不会产生严重的代码耦合。

3.易于命令的组合维护。可以比较容易地设计一个组合命令,维护所有命令的集合,并允许调用同一方法实现不同的功能。

4.易于与其他模式结合。命令模式可以结合责任链模式,实现命令族的解析;而命令模式结合模板方法模式,则可以有效减少Command子类的膨胀问题。

 

 

7.3 命令模式的缺点


会导致类的膨胀。使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,这将导致类的膨胀。上文讲解优点时已经提到了应对之策,我们可以将命令模式结合模板方法模式,来有效减少Command子类的膨胀问题。也可以定义一个具体基类,包括一些能定义自己行为的高层方法,将命令的主体execute()转到子类沙箱中,往往会有一些帮助。

 


 

八、本文涉及知识点提炼整理

 


本文涉及知识点提炼整理如下:

  • GOF对命令模式的定义是,命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持可撤消的操作。命令模式是回调机制的面向对象版本。
  • 将一组行为抽象为对象,这个对象和其他对象一样可以被存储和传递,从而实现行为请求者与行为实现者之间的松耦合,这就是命令模式。
  • 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
  • 命令模式很适合实现诸如撤消,重做,回放,时间倒流之类的功能。而基于命令模式实现录像与回放等功能,也就是执行并解析一系列经过预录制的序列化后的各玩家操作的有序命令集合。
  • 命令模式的优点有:对类间解耦、可扩展性强、易于命令的组合维护、易于与其他模式结合,而缺点是会导致类的膨胀。
  • 命令模式有不少的细分种类,实际使用时应根据当前所需来找到合适的设计方式。
当然,单看以上的这些概念也许太过于抽象,关键还是在于理解文中三、四、五节的代码与图示。


 

九、参考文献



[1] http://gameprogrammingpatterns.com/command.html

[2] Gamma E. Design patterns: elements of reusable object-oriented software[M]. Pearson Education India, 1995.

[3] Freeman E, Robson E, Bates B, et al. Head first design patterns[M]. " O'Reilly Media, Inc.", 2004.

[4] https://en.wikipedia.org/wiki/Command_pattern

[5] https://en.wikipedia.org/wiki/Memento_pattern

 


本文就此结束,系列文章未完待续。

With Best Wishes.

 



查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 实现gridview 固定gridview列字符串的长度,多余的以...表示

    下面是源码:先添加js和CSS<script type="text/javascript" language="javascript"> function DoCheck(flag)// 全选 flag=1 反选 flag=0 { var inputs = document.forms[0].elements; for (var i=0; i < inputs.leng…...

    2024/4/16 23:49:44
  2. 数据库备份的分类

    一、按数据库备份的本质划分逻辑备份物理备份逻辑备份:指通过逻辑导出对数据进行备份。将数据库中的用户对象导出到一个二进制文件中,逻辑备份使用导入导出工具:EXPDP/IMPDP或EXP/IMP,由于将数据库对象导出到操作系统二进制文件中,或由二进制文件中把数据导入到数据库中。…...

    2024/4/3 1:56:45
  3. 手把手教你用python实现一个简单用户管理系统

    Overview:0.环境1.前言2.效果图3.代码涉及知识点4.代码实现思路5.小技巧6.总结0.环境操作系统:WindowsPython版本:3.6.01.前言同学们知道用户管理系统么?用户管理系统可以存储用户的各种信息,比如用户名字,年龄,手机号等等。这里自己实现了个命令行版本的用户管理系统,…...

    2024/4/16 23:49:44
  4. 【Cocos游戏实战】功夫小子第八课之游戏打包和相关问题说明

    至此,功夫小子系列的Cocos2d-x的实战文章就结束了。源码地址: https://github.com/SuooL/KungfuBoy如需要资源请邮件我 1020935219@qq.com再次贴个目录以便检索: 功夫小子专栏地址:http://blog.csdn.net/column/details/suoolcocoshit.html点击打开链接【Cocos游戏实战】功夫…...

    2024/4/17 23:25:22
  5. findbugs ant 代码审核工具

    Findbugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。利用这个工具,就可以在不实际运行程序的情况对软件进行分析。它可以帮助改进代码的质量。 Findbugs提供了方便操作的可视化界面,同时也可以作为Eclipse的一个插件来使…...

    2024/4/17 23:38:23
  6. 【SQL Server】关于报错“备份集中的数据库备份与现有的数据库"xxx"不同”的解决方案

    在做数据库备份与还原的过程中可能因为一下小的细节导致通过备份文件还原的时候报错:备份集中的数据库备份与现有的数据库"xxx"不同导致这种报错的原因是:备份文件与现有数据库的结构不一致因此要恢复数据库就需要去“选项”中勾选“覆盖现有数据库”这样备份就搞定…...

    2024/4/28 21:51:00
  7. 开发实战:基于深度学习+maven+SSM+EasyUI的高校共享汽车管理系统(一)

    基于深度学习+maven+SSM+EasyUI的高校共享汽车管理系统 1.项目简介在现在,共享汽车在中国各地方开始热起来,于是本人想做一个基于maven+SSM+EasyUI的高校共享汽车管理系统,当然该项目是博主本人2019年的毕业设计,除了javaweb部分,本项目还融入了深度学习下的车标识别功能。…...

    2024/4/16 23:50:08
  8. 电磁兼容设计的基本要求!给你科普一下

    随着科学技术的不断发展,电子设备的数量及应用逐渐增多,结果必将造成电磁干扰越来越严重。 在日趋恶劣的电磁环境中,如若不采取恰当的电磁屏蔽措施,会导致设备之间的电磁干扰日益严重,电子设备的性能下降,甚者会危及到信息的安全。为了保证电子设备在复杂的电磁环境中既不…...

    2024/4/16 23:52:51
  9. 用 opengl 写一个小游戏 (1)

    用 opengl 写一个小游戏 (1)用 opengl 写一个小游戏 1 环境搭建 freetype soil glm 注意事项基本组件 shader texture 资源加载渲染器 主游戏类 游戏窗口本节代码 github 环境搭建基本的环境搭建可以参考我之前的文章在 Eclipse或CLion 中集成 opengl 环境 (windows+mingw) 在…...

    2024/4/20 8:37:58
  10. vue2.0中.vue文件的post请求

    在.vue文件中如何发送post请求呢?以下是博主开发中用到的方法,先引入:import util from util;再定义方法:postImg (numParam) {//这边写图片的上传var imgData_1;if(numParam == 1){imgData_1 = this.headerImage;}else if(numParam == 2){imgData_1 = this.headerImage_2;…...

    2024/4/16 23:50:57
  11. 常用的数据库备份类型有哪些?

    对数据库的备份是网站管理人员的必修课,那么常用的数据库备份方式有哪些呢?应如何选择?数据库备份有四种类型,分别应用于不同的场合,下面简要介绍一下。 1、完全备份 这是大多数人常用的方式,它可以备份整个数据库,包含用户表、系统表、索引、视图和存储过程等所…...

    2024/4/16 23:51:03
  12. 车载电子设备电磁兼容设计的基本要求及方法

    随着科学技术的不断发展,电子设备的数量及应用逐渐增多,结果必将造成电磁干扰越来越严重。 在日趋恶劣的电磁环境中,如若不采取恰当的电磁屏蔽措施,会导致设备之间的电磁干扰日益严重,电子设备的性能下降,甚者会危及到信息的安全。为了保证电子设备在复杂的电磁环境中既不…...

    2024/4/20 7:52:07
  13. 基于C51单片机的万年历设计(LCD1602显示)

    C51单片机万年历设计 注:该程序基于普中科技C51 V2.2开发板设计,库函数和硬件资料均来自普中科技,侵删。main.c大部分为原创,如有雷同,纯属巧合。 名称:C51万年历。 硬件:以C51芯片为核心,LCD1602作为显示,DS18B20获取温度信息,按键设置。 软件:可以显示年、月、日、…...

    2024/4/4 22:02:09
  14. 元胞自动机及生命游戏

    数模美赛里面用到元胞自动机比较多,这两天主要下研究这个。 何谓自动机,说白了就是给定输入状态和前一个状态和下一个状态的转移方式,然后程序自己跑。 所以运用元胞自动机的生命游戏就是一个无玩家游戏,也就是不需要人工介入,自己跑的游戏。 元胞就类似遗传算法里的基因,…...

    2024/4/29 5:08:45
  15. Java实现MySQL数据库备份(一)

    下班了,利用闲暇时间总结一下如何使用Java语言实现MySQL数据库备份:import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import ja…...

    2024/4/20 8:31:38
  16. 学生宿舍管理系统类图设计

    需求文档 面对庞大的学生信息量,一套适合学生公寓使用的管理软件,能够非常方便地管理公寓,包括公寓内员工基本信息管理,学生信息管理,公寓信息管理等,还能便捷的查询公寓内的各种信息,提高了工作人员的工作效率。 通过使用学生公寓管理系统,可以做到规范管理、科学统计…...

    2024/4/22 21:17:58
  17. 屏蔽机房设计方案知识

    屏蔽机房基本原理来自法拉第笼设计。在没有做屏蔽的情况下,我们的电子设备会受到直击雷或间接雷等强电磁干扰源的影响导致设备无法工作或工作出现异常,最严重时出现损坏,这是比较常见的电磁干扰显现,另外一种现象就是,我们在打雷的时候听收音机,看电视,使用电脑,收音机…...

    2024/4/17 23:37:17
  18. 如何将远程数据库备份到本地

    今天遇到一个问题,同事到客户那里去部署系统,系统与数据库不在一台电脑上,同事在系统软件的电脑上通过数据库电脑的IP地址,用户名和密码访问数据库。然后,同事又通过QQ与我这边相连,我通过远程协助控制同事的电脑(有点儿复杂!)。 系统运行的过程中出现点儿问题,但是在…...

    2024/3/28 20:16:30
  19. 不同按钮form跳转时改变控件的值

    $header<script type="text/javascript" language="javascript"> function DoCheck(flag)// 全选 flag=1 反选 flag=0 取消 flag=2 { var inputs = document.myform.elements; for (var i=0; i < inputs.length; i++)…...

    2024/4/18 6:08:42
  20. 在线万年历

    在线万年历1.概述在计算机没有普及的年代,要查找多年前某天对应的农历日期,就不得不翻阅一本厚厚的万年历进行查询。如今,随着计算机网络的普及,只要利用任意搜索引擎搜索“在线万年历”就可以搜索出很多功能强大的万年历。本实例向大家介绍的是在线万年历的实现过程,通过…...

    2024/3/28 20:16:28

最新文章

  1. 在Mac上恢复已删除文件夹的最佳方法

    “嗨&#xff0c;我从我的Mac Documents文件夹中删除了很多文件夹。已删除的文件夹包含我的重要文档和文件&#xff0c;是否可以取回它们&#xff1f;垃圾桶已被清洁软件清空。如何在我的Mac上恢复已删除的文件夹&#xff1f; 当您在 Mac 上删除 1 或 2 个文件夹时&#xff0c…...

    2024/5/3 5:13:21
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Golang Gin框架

    1、这篇文章我们简要讨论一些Gin框架 主要是给大家一个基本概念 1、Gin主要是分为路由和中间件部分。 Gin底层使用的是net/http的逻辑&#xff0c;net/http主要是说&#xff0c;当来一个网络请求时&#xff0c;go func开启另一个协程去处理后续(类似epoll)。 然后主协程持续…...

    2024/5/2 2:34:23
  4. Linux中的shell脚本之流程控制循环遍历

    3 条件判断 4 流程控制语句 1&#xff09;if 语句 案例&#xff0c;用户输入用户名和密码&#xff0c;判断用户名是否是admin,密码是否是123,如果正确&#xff0c;则显示登录成功 首先我创建了shell文件&#xff0c;touch getpawer 其中getpawer 是我自己命的名 #!/bin/bas…...

    2024/5/1 13:38:30
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/2 9:28:15
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57