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

news2024/12/24 11:40:21

一、策略模式

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;
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu22.04 安装 jupyterlab

JupyterLab Install JupyterLab with pip: pip install jupyterlabNote: If you install JupyterLab with conda or mamba, we recommend using the conda-forge channel. Once installed, launch JupyterLab with: jupyter lab

C/C++ 运用Npcap发送UDP数据包

Npcap 是一个功能强大的开源网络抓包库&#xff0c;它是 WinPcap 的一个分支&#xff0c;并提供了一些增强和改进。特别适用于在 Windows 环境下进行网络流量捕获和分析。除了支持通常的网络抓包功能外&#xff0c;Npcap 还提供了对数据包的拼合与构造&#xff0c;使其成为实现…

83基于matlab 的时钟时间识别GUI

基于matlab 的时钟时间识别GUI。图像去除背景-转化为二值化图像-找出对应的直线边缘-找到秒针、分针、时针对应的直线&#xff0c;并算出斜率、角度-判断时间&#xff0c;分针与时针 &#xff08;度数&#xff09;。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运…

Shell编程基础 – 变量(Variables)

Shell编程基础 – 变量&#xff08;Variables&#xff09; Shell Scripting Essentials – Variables Bash变量作为shell脚本的重要组成部分&#xff0c;提供了在Unix/Linux命令行界面操作和保存数据的方法。 本文简要介绍Bash Shell脚本变量的基础知识以及应用&#xff0c;包…

Python中classmethod的妙用

更多Python学习内容&#xff1a;ipengtao.com 在Python中&#xff0c;classmethod装饰器为开发者提供了一种强大的工具&#xff0c;使得类方法的定义和使用更加灵活。本文将深入探讨classmethod的妙用&#xff0c;通过丰富的示例代码展示其在不同场景下的实际应用。 类方法与实…

Visual Studio 中文注释乱码解决方案

在公司多人开发项目中经常遇到拉到最新代码&#xff0c;发现中文注释都是乱码&#xff0c;很是emjoy..... 这是由于编码格式不匹配造成的&#xff0c;如果你的注释是 UTF-8 编码&#xff0c;而文件编码是 GBK 或者其他编码&#xff0c;那么就会出现乱码现象。一般的解决办法是…

【鬼鬼鬼iiARPG开发记录】

鬼鬼鬼ARPG开发记录 一、创建项目1、创建3D(URP)项目2、导入新的输入系统&#xff08;input system&#xff09;3、勾选Enter Play Mode Options 二、导入资源1、创建若干文件夹 一、创建项目 1、创建3D(URP)项目 2、导入新的输入系统&#xff08;input system&#xff09; …

lvm 扩容根分区失败记录

lvm 扩容根分区失败记录 1、问题描述2、错误描述3、解决方法重启系统进入grub界面&#xff0c;选择kernel 2.x 启动系统。然后同样的resize2fs命令扩容成功。 1、问题描述 根分区不足。 系统有2个内核版本&#xff0c;一个是kernel 2.x&#xff0c;另一个是kernel 4.x。 这次l…

Leetcode201. 数字范围按位与

Every day a Leetcode 题目来源&#xff1a;201. 数字范围按位与 最直观的解决方案就是迭代范围内的每个数字&#xff0c;依次执行按位与运算&#xff0c;得到最终的结果&#xff0c;但此方法在 [left, right] 范围较大的测试用例中会因超出时间限制而无法通过&#xff0c;因…

Kafka配置SASL认证密码登录

​​​​​​1、修改config/server.properties&#xff0c;添加如下内容 listenersSASL_PLAINTEXT://内网ip:9092 advertised.listenersSASL_PLAINTEXT://外网ip:9092 security.inter.broker.protocolSASL_PLAINTEXT sasl.mechanism.inter.broker.protocolPLAIN sasl.enabled.…

【开源】基于JAVA的森林火灾预警系统

项目编号&#xff1a; S 019 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S019&#xff0c;文末获取源码。} 项目编号&#xff1a;S019&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 系统基础模块2.3 烟…

中职组网络安全-FTPServer20221010.img(环境+解析)

任务环境说明&#xff1a; √服务器场景&#xff1a;FTPServer20221010.img √服务器操作系统&#xff1a;未知&#xff08;关闭链接&#xff09; √FTP用户名&#xff1a;attack817 密码&#xff1a;attack817 1.分析attack.pcapng数据包文件&#xff0c;通过分析数据包attack…

电子学会C/C++编程等级考试2021年06月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:数字放大 给定一个整数序列以及放大倍数x,将序列中每个整数放大x倍后输出。 时间限制:1000 内存限制:65536输入 包含三行: 第一行为N,表示整数序列的长度(N ≤ 100); 第二行为N个整数(不超过整型范围),整数之间以一个空格…

鸿蒙开发-ArkTS 语言-基础语法

1. 初识 ArkTS 语言 ArkTS 是 HarmonyOS 优选主力开发语言。ArkTS 是基于 TypeScript (TS) 扩展的一门语言&#xff0c;继承了 TS 的所有特性&#xff0c;是TS的超集。 主要是扩展了以下几个方面&#xff1a; 声明式UI描述和自定义组件&#xff1a; ArkTS使用声明式的方式描述用…

物联网中基于信任的安全性调查研究:挑战与问题

A survey study on trust-based security in Internet of Things: Challenges and issues 文章目录 a b s t r a c t1. Introduction2. Related work3. IoT security from the one-stop dimension3.1. Output data related security3.1.1. Confidentiality3.1.2. Authenticity …

JSP JSTL引入依赖并演示基础使用

然后 我们来讲 JSTL Java server pages standarded tag library 简称 JSTL 这是 一个 JSP的标准标签库 JSP标准标签的集合 封装了JSP中的通用核心功能 根据JSTL类库提供的标签 可以将他分为5个类 1 核心标签 2 格式化标签 3 SQL标签 4 XML标签 5 函数标签 这边 我们主要将 核…

Linux的gcc,gdb基础

执行详解: 1)如何执行 路径可执行文件名 或者 路径可执行文件名 & (将进程放到后台执行); 可以把可执行文件放到 /usr/bin 就可以省略路径了; 思考:为什么? ps :/usr/bin ps,ls,pwd (先了解,后期写项目就知道为什么了) 2)两步执行与一步执行 a.可以三步合为一步,即…

HTML4总结

一、前序知识 1. 认识两位先驱 2. 计算机基础知识 1. 计算机俗称电脑&#xff0c;是现代一种用于高速计算的电子计算机器&#xff0c;可以进行数值计算、逻辑计算&#xff0c;还 具有存储记忆功能。 2. 计算机由 硬件 软件 成&#xff1a; 硬件&#xff1a;看得见摸得着…

十大排序之归并排序(详解)

文章目录 &#x1f412;个人主页&#x1f3c5;算法思维框架&#x1f4d6;前言&#xff1a; &#x1f380;归并排序 时间复杂度O(n*logn)&#x1f387;1. 算法步骤思想&#x1f387;2、动画演示&#x1f387;3.代码实现 &#x1f412;个人主页 &#x1f3c5;算法思维框架 &#…

如何打造垂直LLM的护城河

B2B人工智能初创企业的一个伟大策略是打造“垂直人工智能”产品&#xff1a;成为特定行业的人工智能助手&#xff0c;比如律师、金融服务、医生。 听起来很简单&#xff1a;你可以利用LLM的超能力&#xff0c;并将其应用于宠物行业的特定数据和用例。 这就是我们在Explain所做的…