万字解析设计模式之策略模式、命令模式

一、策略模式

1.1概述

先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。

 策略模式(Strategy Pattern)是一个行为型设计模式,它定义了一组算法家族,分别封装起来,让它们之间可以互相替换,且算法的变化不会影响使用算法的客户。通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

1.2结构

策略模式的主要角色如下:

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。定义了所有支持的算法的共同接口,可以是抽象类、接口或抽象类和接口的组合。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
  • 环境(Context)类:持有一个策略类的引用,将具体的算法委托给这些策略对象来处理,最终给客户端调用。

1.3实现

【例】促销活动

一家百货公司在定年度的促销活动。针对不同的节日(春节、中秋节、圣诞节)推出不同的促销活动,由促销员将促销活动展示给客户。类图如下:

 抽象策略(Strategy)类

package com.yanyu.Strategyer;


public interface Strategy {
    void show();
}

具体策略角色(Concrete Strategy)

package com.yanyu.Strategyer;

//为春节准备的促销活动A
public class StrategyA implements Strategy {

    public void show() {
        System.out.println("买一送一");
    }
}
package com.yanyu.Strategyer;

//为中秋准备的促销活动B
public class StrategyB implements Strategy {
    public void show() {
        System.out.println("满200元减50元");
    }
}
package com.yanyu.Strategyer;

//为圣诞准备的促销活动C
public class StrategyC implements Strategy {
    public void show() {
        System.out.println("满1000元加一元换购任意200元以下商品");
    }
}

环境(Context)类

package com.yanyu.Strategyer;

public class SalesMan {
    //持有抽象策略角色的引用
    private Strategy strategy;

    public SalesMan(Strategy strategy) {
        this.strategy = strategy;
    }

    public Strategy getStrategy() {
        return strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    //向客户展示促销活动
    public void salesManShow(){
        strategy.show();
    }
}

客户端类

package com.yanyu.Strategyer;

public class Client {
    public static void main(String[] args) {
        //春节来了, 使用春节促销活动
        SalesMan salesMan = new SalesMan(new StrategyA());
       // 展示促销活动
        salesMan.salesManShow();
        System.out.println("=============");
       // 中秋节到了, 使用中秋节的促销活动
        salesMan.setStrategy (new StrategyB());
        // 展示促销活动
        salesMan.salesManShow();
    }
}

1.4优缺点

1,优点:

  • 策略类之间可以自由切换

    由于策略类都实现同一个接口,所以使它们之间可以自由切换。

  • 易于扩展

    增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“

  • 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。

2,缺点:

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量

1.5使用场景

  • 当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式;

  • 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式;

  • 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来;

  • 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。

  • 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。
  • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为

二、 命令模式

2.1概述

日常生活中,我们出去吃饭都会遇到下面的场景。

命令模式是一种行为设计模式,将请求或操作封装成对象,从而使请求者和接收者松耦合,使发出请求的责任和执行请求的责任分割开。在命令模式中,命令就像是一个对象,可以被存储、重复、撤销、恢复等操作,因此它可以通过队列、日志等方式来管理和操作。

为什么需要命令模式

假如你正在开发一款新的文字编辑器, 当前的任务是创建一个包含多个按钮的工具栏, 并让每个按钮对应编辑器的不同操作。 你创建了一个非常简洁的 按钮类, 它不仅可用于生成工具栏上的按钮, 还可用于生成各种对话框的通用按钮。

最简单的解决方案是在使用按钮的每个地方都创建大量的子类。 这些子类中包含按钮点击后必须执行的代码。

zeren

你很快就意识到这种方式有严重缺陷。 首先, 你创建了大量的子类, 当每次修改基类 按钮时, 你都有可能需要修改所有子类的代码。 简单来说, GUI 代码以一种拙劣的方式依赖于业务逻辑中的不稳定代码。 还有一个部分最难办。 复制/粘贴文字等操作可能会在多个地方被调用。 例如用户可以点击工具栏上小小的 “复制” 按钮, 或者通过上下文菜单复制一些内容, 又或者直接使用键盘上的 Ctrl+C 。

最简单的解决方案是在使用按钮的每个地方都创建大量的子类。 这些子类中包含按钮点击后必须执行的代码。

zeren

你很快就意识到这种方式有严重缺陷。 首先, 你创建了大量的子类, 当每次修改基类 按钮时, 你都有可能需要修改所有子类的代码。 简单来说, GUI 代码以一种拙劣的方式依赖于业务逻辑中的不稳定代码。 还有一个部分最难办。 复制/粘贴文字等操作可能会在多个地方被调用。 例如用户可以点击工具栏上小小的 “复制” 按钮, 或者通过上下文菜单复制一些内容, 又或者直接使用键盘上的 Ctrl+C 。

用命令模式解决问题

软件设计通常会将关注点进行分离。 最常见的例子: 一层负责用户图像界面; 另一层负责业务逻辑。 GUI 层负责在屏幕上渲染美观的图形, 捕获所有输入并显示用户和程序工作的结果。 当需要完成一些重要内容时 (比如计算月球轨道或撰写年度报告), GUI 层则会将工作委派给业务逻辑底层。

这在代码中看上去就像这样: 一个 GUI 对象传递一些参数来调用一个业务逻辑对象。 这个过程通常被描述为一个对象发送请求给另一个对象。

 2.2结构

命令模式包含以下主要角色:

  • 抽象命令类(Command)角色: 定义命令的接口,声明执行的方法。
  • 具体命令(Concrete Command)角色:具体的命令,实现命令接口;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
  • 实现者/接收者(Receiver)角色: 负责执行具体的命令操作。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
  • 调用者/请求者(Invoker)角色: 负责调用命令并执行。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。

2.3实现

将上面的案例用代码实现,那我们就需要分析命令模式的角色在该案例中由谁来充当。

服务员: 就是调用者角色,由她来发起命令。

资深大厨: 就是接收者角色,真正命令执行的对象。

订单: 命令中包含订单。

类图如下:

抽象命令类

package com.yanyu.Commander;

public interface Command {
    void execute();//只需要定义一个统一的执行方法
}

具体命令(Concrete Command)角色

package com.yanyu.Commander;

import java.util.Set;

public class OrderCommand implements Command {

    //持有接受者对象
    private SeniorChef receiver; // 命令模式中的接收者对象
    private Order order; // 命令的参数

    public OrderCommand(SeniorChef receiver, Order order){
        this.receiver = receiver; // 初始化接收者对象
        this.order = order; // 初始化命令的参数
    }

    public void execute()  {
        System.out.println(order.getDiningTable() + "桌的订单:"); // 输出订单信息
        Set<String> keys = order.getFoodDic().keySet(); // 获取订单中食物的键集合
        for (String key : keys) {
            receiver.makeFood(order.getFoodDic().get(key),key); // 调用接收者对象的方法执行制作食物的操作
        }

        try {
            Thread.sleep(100); // 停顿一下 模拟做饭的过程
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(order.getDiningTable() + "桌的饭弄好了"); // 输出制作完成的信息
    }
}

接收者(Receiver)角色

package com.yanyu.Commander;

// 资深大厨类 是命令的Receiver
public class SeniorChef {
    public void makeFood(int num,String foodName) {
        System.out.println(num + "份" + foodName);
    }
}

调用者

package com.yanyu.Commander;

import java.util.ArrayList;

public class Waitor {

    private ArrayList<Command> commands;//可以持有很多的命令对象

    public Waitor() {
        commands = new ArrayList();
    }

    public void setCommand(Command cmd){
        commands.add(cmd);
    }

    // 发出命令 喊 订单来了,厨师开始执行
    public void orderUp() {
        System.out.println("美女服务员:叮咚,大厨,新订单来了.......");
        for (int i = 0; i < commands.size(); i++) {
            Command cmd = commands.get(i);
            if (cmd != null) {
                cmd.execute();
            }
        }
    }
}

命令的请求

package com.yanyu.Commander;

import java.util.HashMap;
import java.util.Map;

public class Order {
    // 餐桌号码
    private int diningTable;

    // 用来存储餐名并记录份数
    private Map<String, Integer> foodDic = new HashMap<String, Integer>();

    public int getDiningTable() {
        return diningTable; // 获取餐桌号码
    }

    public void setDiningTable(int diningTable) {
        this.diningTable = diningTable; // 设置餐桌号码
    }

    public Map<String, Integer> getFoodDic() {
        return foodDic; // 获取食物名称和数量的映射
    }

    public void setFoodDic(String name, int num) {
        foodDic.put(name,num); // 添加食物名称和数量的映射
    }
}

客户端类

package com.yanyu.Commander;

public class Client {
    public static void main(String[] args) {
        //创建2个order
        Order order1 = new Order();
        order1.setDiningTable(1);
        order1.getFoodDic().put("西红柿鸡蛋面",1);
        order1.getFoodDic().put("小杯可乐",2);

        Order order2 = new Order();
        order2.setDiningTable(3);
        order2.getFoodDic().put("尖椒肉丝盖饭",1);
        order2.getFoodDic().put("小杯雪碧",1);

        //创建接收者
        SeniorChef receiver=new SeniorChef();
        //将订单和接收者封装成命令对象
        OrderCommand cmd1 = new OrderCommand(receiver, order1);
        OrderCommand cmd2 = new OrderCommand(receiver, order2);
        //创建调用者 waitor
        Waitor invoker = new Waitor();
        invoker.setCommand(cmd1);
        invoker.setCommand(cmd2);

        //将订单带到柜台 并向厨师喊 订单来了
        invoker.orderUp();
    }
}

2.4 优缺点

1,优点:

  • 降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。
  • 增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。
  • 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
  • 方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。

2,缺点:

  • 使用命令模式可能会导致某些系统有过多的具体命令类。
  • 系统结构更加复杂。

2.5使用场景

  • 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
  • 系统需要在不同的时间指定请求、将请求排队和执行请求。
  • 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。

2.6源码分析

在JDK中,命令模式的经典实现是Runnable接口和java.util.concurrent包中的Executor框架。Runnable接口定义了一个执行动作的协议,而Executor框架则提供了一些实现Runnable接口的类(如ThreadPoolExecutor),以及执行Runnable对象的方法。

以下是一个简单的示例,我们将使用Runnable接口和Executor框架来实现命令模式:

public class CommandPatternJDKExample {

    public static void main(String[] args) {
        // 创建一个命令对象
        Runnable command = new ConcreteCommand();

        // 创建一个执行器对象
        Executor executor = Executors.newSingleThreadExecutor();

        // 执行命令
        executor.execute(command);
    }
}

// 具体命令类
class ConcreteCommand implements Runnable {

    @Override
    public void run() {
        System.out.println("命令被执行了");
    }
}

在上面的示例中,我们创建了一个ConcreteCommand类,它实现了Runnable接口,并且在run()方法中执行了一个简单的命令。然后,我们使用Executors类创建了一个执行器对象,并调用了它的execute()方法来执行这个命令。

三、策略模式实验

任务描述

在多个裁判负责打分的单人跳水比赛中,每位裁判给选手一个得分,选手的最后得分是根据全体裁判的得分计算出来的。现有5名裁判和7人裁判两种评分计算方案,以后可能会有更多计算方案。

  • 5名裁判员评分规则:5名裁判员打出分数以后,先删去最高和最低的无效分,余下3名裁判员的分数之和乘以运动员所跳动作的难度系数,便得出该动作的实得分;
  • 7名裁判员评分规则:方法与5名裁判员评分方法相同,但7人裁判员算出的得分最后还应除以5,再乘以3。

本关任务:请设计一种能兼容多种评分策略的架构,且用户可以自主选择其中一种策略作为比赛的评分方案。

实现方式

  1. 从上下文类中找出修改频率较高的算法 (也可能是用于在运行时选择某个算法变体的复杂条件运算符);

  2. 声明该算法所有变体的通用策略接口;

  3. 将算法逐一抽取到各自的类中, 它们都必须实现策略接口;

  4. 在上下文类中添加一个成员变量用于保存对于策略对象的引用。 然后提供设置器以修改该成员变量。 上下文仅可通过策略接口同策略对象进行交互, 如有需要还可定义一个接口来让策略访问其数据;

  5. 客户端必须将上下文类与相应策略进行关联, 使上下文可以预期的方式完成其主要工作。

编程要求

根据提示,在右侧编辑器 Begin-End 内补充代码:

  • PlayerScore:上下文环境类;
  • Codepoints:抽象策略;
  • Codepoints5:5人裁判评分策略类;
  • Codepoints7:7人裁判评分策略类;
  • Client:客户端类。

测试说明

平台会对你编写的代码进行测试,第一行给出一个正整数 n(表示裁判人数)和一个实数 k(表示跳水难度系数)。第二行给出 n 个实数(评分成绩),中间以空格进行分隔。输出最后结果,格式为 The final score is XX.XX,保留小数点后两位。

测试输入: 5 2.0 5 5.5 5 5 4.5 预期输出: The final score is 30.00

测试输入: 7 2.0 5 5.5 5 5 4.5 5 5 预期输出: The final score is 30.00

抽象策略(Strategy)类

package step1;

/********** Begin *********/
public interface Codepoints{
    double computerScore(double []a,double difficulty);

}
/********** End *********/

 具体策略(Concrete Strategy)类

package step1;

/********** Begin *********/
import java.util.Arrays;

public class Codepoints5 implements Codepoints{
    
    public double computerScore(double[]a,double difficulty){
        if(a.length<=2)
            return 0;
        double score,sum=0;
        Arrays.sort(a);//排序数组
        for (int i=1;i<a.length-1;i++){
            sum=sum+a[i];
        }
        score=sum*difficulty;
        return score;
    }
}

/********** End *********/
package step1;

/********** Begin *********/
import java.util.Arrays;

public class Codepoints7 implements Codepoints{
    
    public double computerScore(double[]a,double difficulty){
        if(a.length<=2)
            return 0;
        double score,sum=0;
        Arrays.sort(a);//排序数组
        for (int i=1;i<a.length-1;i++){
            sum=sum+a[i];
        }
        score=sum/5.0*3*difficulty;
        return score;
    }
}

/********** End *********/

环境(Context)类

package step1;

/********** Begin *********/

public class PlayerScore{
    private Codepoints codepoints;
    public void setStrategy(Codepoints codepoints){
    this.codepoints=codepoints;
    }
    public double Calculate(double []a,double difficulty){
        return codepoints.computerScore(a,difficulty);
    }
}
/********** End *********/

客户端类


package step1;

import java.util.Scanner;

public class Client {
    public static void main(String[] args) {
        /********** Begin *********/
        PlayerScore player=new PlayerScore ();
        Scanner scanner = new Scanner(System.in);
        int n =scanner.nextInt();// 裁判人数
        double diff=scanner.nextDouble();//动作的难度系数
        double[] array=new double [n];// 裁判的评分
        for (int i=0 ; i<n ; i++){
            array[i] = scanner.nextDouble();
        }
        if (n==5){
            player.setStrategy(new Codepoints5());
        }
        else if (n==7) {
            player.setStrategy(new Codepoints7());
        }
       
        System.out.println("The final score is "+ String.format("%.2f", player.Calculate(array,diff)));
        /********** End *********/
    }
}

四、命令模式实验

任务描述

zeren

在植物大战僵尸的游戏设计中,植物战士是兵营生产的,玩家通过点击界面上“图片按钮”向兵营发出生产命令,兵营接受命令后每生产一个植物战士需要冷却一定的时间才能继续生产。

本关任务:本模拟程序中只需要实现一种植物战士的生产,请你用命令模式实现。

实现方式

  1. 声明仅有一个执行方法的命令接口;

  2. 抽取请求并使之成为实现命令接口的具体命令类。 每个类都必须有一组成员变量来保存请求参数和对于实际接收者对象的引用。 所有这些变量的数值都必须通过命令构造函数进行初始化;

  3. 找到担任发送者职责的类。 在这些类中添加保存命令的成员变量。 发送者只能通过命令接口与其命令进行交互。 发送者自身通常并不创建命令对象, 而是通过客户端代码获取;

  4. 修改发送者使其执行命令, 而非直接将请求发送给接收者;

  5. 客户端必须按照以下顺序来初始化对象:

    •  创建接收者;
    •  创建命令, 如有需要可将其关联至接收者;
    •  创建发送者并将其与特定命令关联。

编程要求

根据提示,在右侧编辑器 Begin-End 内补充 “CampInvokers.java”和 “ProduceCommand.java” 文件代码,其它地方不要修改。

测试说明

平台会对你编写的代码进行测试,请输入发出生产命令的个数和兵营冷却时间(毫秒)。 输入结束后,为了模拟界面操作,系统会在 1000 毫秒内持续监控兵营接到的命令。 测试输入:6 200 预期输出: 豌豆射手生产出来了 豌豆射手生产出来了 豌豆射手生产出来了 豌豆射手生产出来了 豌豆射手生产出来了

测试输入:6 500 预期输出: 豌豆射手生产出来了 豌豆射手生产出来了

抽象命令类

package step1;

public abstract class Commands{
    public abstract void Execute();
}

具体命令

package step1;

public class ProduceCommand extends Commands{
    @Override
    public void Execute() {
        /********** Begin *********/
        //生产植物战士
        new Peashooter();
       
        /********** End *********/
    }
}
package step1;
//所有战士的基类
public interface IBotany {
}
package step1;
//植物战士
public class Peashooter implements IBotany {
    public Peashooter()
    {
        System.out.println("豌豆射手生产出来了");
    }
}

接收者(Receiver)角色

调用者

package step1;

import java.util.ArrayList;
import java.util.List;

// 兵营就是命令的管理者
public class CampInvokers {
    private final List<Commands> commands = new ArrayList<>(); // 命令队列
    private final long TrainTimer; // 训练冷却时间
    private long timer; // 当前时间
    
    // 构造函数,初始化训练冷却时间和当前时间
    public CampInvokers(long trainTime){
        TrainTimer=trainTime;
        timer=0;
    }
    
    // 添加训练命令到命令队列
    public void Train()
    {
        // 将生产命令加入到命令队列
        commands.add(new ProduceCommand());
    }
    
    // 执行命令队列中的命令
    public void ExecuteCommand()
    {
        if (commands.size() <= 0) return;
        if (timer+TrainTimer <= System.currentTimeMillis())
        {
            // 执行队列里最上面的命令
            commands.get(0).Execute(); 
            // 移除最上面的命令
            commands.remove(0); 
            // 重置冷却时间
            timer = System.currentTimeMillis(); 
        }
    }
    
    // 取消训练命令
    public void CancelTrainCommand()
    {
        if (commands.size() > 0)
        {
            commands.remove(commands.size() - 1);
            if (commands.size() == 0)
            {
                timer = System.currentTimeMillis();
            }
        }
    }
}

客户端类 

package step1;

import java.util.Scanner;

// 客户端类,用于演示命令模式
public class Client {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        
        // 从用户输入获取训练次数和训练冷却时间
        int number = scanner.nextInt();
        long traintime = scanner.nextLong();
        long currtime= System.currentTimeMillis();

        // 创建兵营管理者对象
        CampInvokers camp = new CampInvokers(traintime);
        
        // 循环训练指定次数
        for (int i = 0; i < number; i++) {
            camp.Train();
        }
        
        // 循环执行命令直至时间到达1秒后
        while (true)
        {
            camp.ExecuteCommand();
            if(currtime+1000<System.currentTimeMillis())
                break;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/187474.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

今年的校招薪资真的让人咋舌!

秋招接近尾声&#xff0c;各大公司基本也陆续开奖了。这里整理了部分公司的薪资情况&#xff0c;数据来源于 OfferShow 和牛客网。 ps&#xff1a;爆料薪资的几乎都是 211 和 985 的&#xff0c;并不是刻意只选取学校好的。另外&#xff0c;无法保证数据的严格准确性。 淘天 …

【实战】K8S Helm部署Redis Cluster Redisinsight

文章目录 前言部署Redis Cluster安装Redis Insight写在最后 前言 在Web服务的开发过程中&#xff0c;Redis一直以来都有着举足轻重的作用。基本上所有的后端服务都会用这个中间件实现具体的业务场景&#xff0c;比如常作为系统缓存、分布式锁&#xff0c;也可以实现排名、定位…

向量机SVM原理理解和实战

目录 概念场景导入 点到超平面的距离公式 最大间隔的优化模型 硬间隔、软间隔和非线性 SVM 用 SVM 如何解决多分类问题 1. 一对多法 2. 一对一法 SVM主要原理和特点 原理 优点 缺点 支持向量机模型分类 SVM实战如何进行乳腺癌检测 数据集 字段含义 代码实现 参…

apple macbook M系列芯片安装 openJDK17

文章目录 1. 查找openjdk版本2. 安装openjdk3. 多jdk之间的切换 在这里我们使用 brew 命令查找并安装。 1. 查找openjdk版本 执行&#xff1a;brew search openjdk&#xff0c;注意&#xff1a;执行命令后&#xff0c;如果得到的结果中没有红框内容&#xff0c;则需要更新一下…

docker部署phpIPAM

0说明 IPAM&#xff1a;IP地址管理系统 IP地址管理(IPAM)是指的一种方法IP扫描&#xff0c;IP地址跟踪和管理与网络相关的信息的互联网协议地址空间和IPAM系统。 IPAM软件和IP的工具,管理员可以确保分配IP地址仍然是当前和足够的库存先进的IP工具和IPAM服务。 IPAM简化并自动化…

web前端之引入svg图片、html引入点svg文件、等比缩放、解决裁剪问题、命名空间、object标签、阿里巴巴尺量图、embed标签、iframe标签

MENU 前言直接在页面编写svg使用img标签引入通过css引入使用object标签引入其他标签参考资料 前言 web应用开发使用svg图片的方式&#xff0c;有如下几种方式 1、直接在页面编写svg 2、使用img标签引入 3、通过css引入 4、使用object标签引入 直接在页面编写svg 在html页面直接…

Redis-缓存高可用集群

Redis集群方案比较 哨兵模式 性能和高可用性等各方面表现一般&#xff0c;特别是在主从切换的瞬间存在访问瞬断的情况。另外哨兵模式只有一个主节点对外提供服务&#xff0c;没法支持很高的并发&#xff0c;且单个主节点内存也不宜设置得过大&#xff0c;否则会导致持久化文件过…

中国信通院王蕴韬:从“好用”到“高效”,AIGC需要被再次颠覆

当下AIGC又有了怎样的颠覆式技术&#xff1f;处于一个怎样的发展阶段&#xff1f;产业应用如何&#xff1f;以及存在哪些风险&#xff1f;针对这些问题&#xff0c;我们与中国信通院云计算与大数据研究所副总工程师王蕴韬进行了一次深度对话&#xff0c;从他哪里找到了这些问题…

萨科微举办工作交流和业务分享会

萨科微&#xff08;www.slkoric.com&#xff09;举办工作交流和业务分享会&#xff0c;狠抓人才培养团队的基本功建设。萨科微总经理宋仕强先生认为&#xff0c;当下市场经济形势复杂多变&#xff0c;给公司经营带来巨大压力&#xff0c;同时考验着企业自身的发展韧性。萨科微公…

【Linux基础】Linux常见指令总结及周边小知识

前言 Linux系统编程的学习我们将要开始了&#xff0c;学习它我们不得不谈谈它的版本发布是怎样的&#xff0c;谈它的版本发布就不得不说说unix。下面是unix发展史是我在百度百科了解的 Unix发展史 UNIX系统是一个分时系统。最早的UNIX系统于1970年问世。此前&#xff0c;只有…

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码

基于厨师算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于厨师算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于厨师优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络的光滑…

gobuster扫描工具使用教程(简单上手)

gobuster扫描工具使用教程 gobuster是干嘛用的? Gobuster是一个用于网络渗透测试的工具。它主要用于在Web应用程序中发现隐藏的内容或目录枚举&#xff0c;可以扫描子域名以及Web目录&#xff0c;寻找可能存在的漏洞。这个工具使用Go语言编写&#xff0c;具备优异的执行效率…

mac电脑文件比较工具 UltraCompare 中文for mac

UltraCompare是一款功能强大的文件和文件夹比较工具&#xff0c;用于比较和合并文本、二进制和文件夹。它提供了丰富的功能和直观的界面&#xff0c;使用户能够轻松地比较和同步文件内容&#xff0c;查找差异并进行合并操作。 以下是UltraCompare软件的一些主要特点和功能&…

C语言—一维数组

一、一维数组的创建 int arr1[10];char arr2[10];flout arr3[1];double arr4[20]; 数组创建,“[ ]”中要给一个常量&#xff0c;不能使用变量 二、一维数组初始化 int arr1[10]{1,2,3}; //不完全初始化int arr2[4]{3,4,5,6}; //完全初始化char arr3[4]{a,b,99,d};cha…

MYSQL基础知识之【数据类型】

文章目录 前言标题一数值类型日期和时间类型字符串类型后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Mysql &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错…

能让PDF看起来像是扫描件的Look Scanned

什么是 Look Scanned ? Look Scanned 是一个能够让 PDF 看起来就像是扫描件一样的纯前端网站。你再也不需要麻烦地打印之后扫描了&#xff0c;你所需要的就是鼠标点几下。 这是个挺有意思的软件&#xff0c;但是老苏不确定什么场景下会用到这个软件&#xff0c;如果不想自己搭…

通过JMeter压测结果来分析Eureka多种服务下线机制后的服务感知情况

文章目录 前言1. Eureka-Server的设计2. EurekaRibbon感知下线服务机制3.服务调用接口压测模型4.Eureka几种服务下线的方式4.1强制下线压测 4.2 发送delete&#xff08;&#xff09;请求压测 4.3 调用DiscoveryManager压测 4. 三方工具Actuator 总结 前言 上文末尾讲到了Eurek…

Leetcode—1457.二叉树中的伪回文路径【中等】

2023每日刷题&#xff08;四十&#xff09; Leetcode—1457.二叉树中的伪回文路径 实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ int record[10] {0};int accumula…

MyBatis的功能架构,MyBatis的框架架构设计,Mybatis都有哪些Executor执行器,Mybatis中如何指定使用哪一种Executor执行器

文章目录 MyBatis的功能架构是怎样的把Mybatis的功能架构分为三层&#xff1a; **MyBatis的框架架构设计**是怎么样的架构图如下Mybatis都有哪些Executor执行器&#xff1f;它们之间的区别是什么&#xff1f;Mybatis中如何指定使用哪一种Executor执行器&#xff1f; MyBatis的功…

django(千锋教育)

创建一个django项目 官网下载python最新版本 配置到环境变量中 打开intlij编辑器 创建django项目 安装django&#xff1a;pip install django 创建django项目: django-admin startproject django01 创建djangoAPP&#xff1a;python manage.py startapp user 启动&#xff1…