Easy Rules规则引擎(2-细节篇)

目录

  • 一、序言
  • 二、规则引擎参数配置实例
    • 1、skipOnFirstAppliedRules示例
      • (1) FizzRule
      • (2) BuzzRule
      • (3) FizzBuzzRule
      • (4) NonFizzBuzzRule
      • (5) FizzBuzzRulesLauncher
    • 2、skipOnFirstNonTriggeredRule示例
    • 3、skipOnFirstFailedRule示例
  • 三、组合规则
    • 1、UnitRuleGroup组合规则
    • 2、ActivationRuleGroup组合规则
    • 3、ConditionalRuleGroup组合规则

一、序言

在 Easy Rules规则引擎(1-基础篇) 中我们已经简单介绍了Easy Rules规则引擎的使用示例,这节我们详解介绍一下规则引擎的相关参数配置实例还有组合规则。


二、规则引擎参数配置实例

Easy Rules规则引擎支持下面参数配置:

参数名称参数类型必选默认值
rulePriorityThresholdintInteger.MAX_VALUE
skipOnFirstAppliedRulebooleanfalse
skipOnFirstFailedRulebooleanfalse
skipOnFirstNonTriggeredRulebooleanfalse
  • skipOnFirstAppliedRule: 当规则被触发并且成功执行行为后是否跳过下条规则。
  • skipOnFirstFailedRule : 当判断规则是否触发抛出异常或者触发成功但行为执行后抛出异常是否跳过下条规则。
  • skipOnFirstNonTriggeredRule : 当规则未被触发是否跳过下条规则。
  • rulePriorityThreshold : 如果规则优先级超过默认阈值,则跳过下条规则。

1、skipOnFirstAppliedRules示例

(1) FizzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;/*** 被5整除的规则* @author Nick Liu* @date 2023/8/4*/
@Rule
public class FizzRule {@Conditionpublic boolean isFizz(@Fact("number") Integer number) {return number % 5 == 0;}@Actionpublic void printFizz(@Fact("number") Integer number) throws Exception {System.out.println("能被5整除的数为: " + number);}@Prioritypublic int getPriority() {return 1;}}

(2) BuzzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;/*** 被7整除的规则* @author Nick Liu* @date 2023/8/4*/
@Rule
public class BuzzRule {@Conditionpublic boolean isBuzz(@Fact("number") Integer number) {return number % 7 == 0;}@Actionpublic void printBuzz(@Fact("number") Integer number) throws Exception {System.out.println("能被7整除的数为: " + number);}@Prioritypublic int getPriority() {return 2;}
}

(3) FizzBuzzRule

import org.jeasy.rules.support.composite.UnitRuleGroup;import java.util.Arrays;/*** 既能被5整除也能被7整除的规则* @author Nick Liu* @date 2023/8/4*/
public class FizzBuzzRule extends UnitRuleGroup {public FizzBuzzRule(Object... rules) {Arrays.stream(rules).forEach(super::addRule);}@Overridepublic int getPriority() {return 0;}
}

(4) NonFizzBuzzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;/*** 既不能被5整除也不能被7整除的规则* @author Nick Liu* @date 2023/8/4*/
@Rule
public class NonFizzBuzzRule {@Conditionpublic boolean isNotFizzOrBuzz(@Fact("number") Integer number) {return number % 5 != 0 || number % 7 != 0;}@Actionpublic void printInput(@Fact("number") Integer number) throws Exception {System.out.println("既不能被5整除也不能被7整除的数字: " + number);}@Prioritypublic int getPriority() {return 3;}}

(5) FizzBuzzRulesLauncher

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.api.RulesEngineParameters;
import org.jeasy.rules.core.DefaultRulesEngine;/*** @author Nick Liu* @date 2023/8/4*/
public class FizzBuzzRulesLauncher {public static void main(String[] args) {// 如果第一条规则满足条件且行为执行成功后则跳过执行后面的规则RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);RulesEngine rulesEngine = new DefaultRulesEngine(parameters);// 规则注册Rules rules = new Rules();rules.register(new FizzRule());rules.register(new BuzzRule());rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));rules.register(new NonFizzBuzzRule());// 触发规则Facts facts = new Facts();for (int count = 0; count < 100; count++) {facts.put("number", count);rulesEngine.fire(rules, facts);}}
}

上面我们设置了默认规则引擎的skipOnFirstAppliedRule属性为true,优先级最高的规则是FizzBuzzRule,这是一个组合规则,也就是说当满足该组合规则的条件,且规则行为执行成功后,就会跳过后面低优先级的所有规则。

简单来说,上面规则的执行顺序是FizzBuzzRuleFizzRuleBuzzRuleNonFizzBuzzRule,语义就是先判断数字是否能被5和7同时整除,再判断是否能被5整除,再判断是否能被7整除,最后判断是否不能被5或7整除。

程序的运行结果如下:

能被5整除的数为: 0
能被7整除的数为: 0
既不能被5整除也不能被7整除的数字: 1
既不能被5整除也不能被7整除的数字: 2
既不能被5整除也不能被7整除的数字: 3
既不能被5整除也不能被7整除的数字: 4
能被5整除的数为: 5
既不能被5整除也不能被7整除的数字: 6
能被7整除的数为: 7
既不能被5整除也不能被7整除的数字: 8
既不能被5整除也不能被7整除的数字: 9
能被5整除的数为: 10
既不能被5整除也不能被7整除的数字: 11
既不能被5整除也不能被7整除的数字: 12
既不能被5整除也不能被7整除的数字: 13
能被7整除的数为: 14
能被5整除的数为: 15
既不能被5整除也不能被7整除的数字: 16
既不能被5整除也不能被7整除的数字: 17
既不能被5整除也不能被7整除的数字: 18
既不能被5整除也不能被7整除的数字: 19
能被5整除的数为: 20
能被7整除的数为: 21
既不能被5整除也不能被7整除的数字: 22
既不能被5整除也不能被7整除的数字: 23
既不能被5整除也不能被7整除的数字: 24
能被5整除的数为: 25
既不能被5整除也不能被7整除的数字: 26
既不能被5整除也不能被7整除的数字: 27
能被7整除的数为: 28
既不能被5整除也不能被7整除的数字: 29
能被5整除的数为: 30
既不能被5整除也不能被7整除的数字: 31
既不能被5整除也不能被7整除的数字: 32
既不能被5整除也不能被7整除的数字: 33
既不能被5整除也不能被7整除的数字: 34
能被5整除的数为: 35
能被7整除的数为: 35
既不能被5整除也不能被7整除的数字: 36
既不能被5整除也不能被7整除的数字: 37
既不能被5整除也不能被7整除的数字: 38
既不能被5整除也不能被7整除的数字: 39
能被5整除的数为: 40
既不能被5整除也不能被7整除的数字: 41
能被7整除的数为: 42
既不能被5整除也不能被7整除的数字: 43
既不能被5整除也不能被7整除的数字: 44
能被5整除的数为: 45
既不能被5整除也不能被7整除的数字: 46
既不能被5整除也不能被7整除的数字: 47
既不能被5整除也不能被7整除的数字: 48
能被7整除的数为: 49
能被5整除的数为: 50
既不能被5整除也不能被7整除的数字: 51
既不能被5整除也不能被7整除的数字: 52
既不能被5整除也不能被7整除的数字: 53
既不能被5整除也不能被7整除的数字: 54
能被5整除的数为: 55
能被7整除的数为: 56
既不能被5整除也不能被7整除的数字: 57
既不能被5整除也不能被7整除的数字: 58
既不能被5整除也不能被7整除的数字: 59
能被5整除的数为: 60
既不能被5整除也不能被7整除的数字: 61
既不能被5整除也不能被7整除的数字: 62
能被7整除的数为: 63
既不能被5整除也不能被7整除的数字: 64
能被5整除的数为: 65
既不能被5整除也不能被7整除的数字: 66
既不能被5整除也不能被7整除的数字: 67
既不能被5整除也不能被7整除的数字: 68
既不能被5整除也不能被7整除的数字: 69
能被5整除的数为: 70
能被7整除的数为: 70
既不能被5整除也不能被7整除的数字: 71
既不能被5整除也不能被7整除的数字: 72
既不能被5整除也不能被7整除的数字: 73
既不能被5整除也不能被7整除的数字: 74
能被5整除的数为: 75
既不能被5整除也不能被7整除的数字: 76
能被7整除的数为: 77
既不能被5整除也不能被7整除的数字: 78
既不能被5整除也不能被7整除的数字: 79
能被5整除的数为: 80
既不能被5整除也不能被7整除的数字: 81
既不能被5整除也不能被7整除的数字: 82
既不能被5整除也不能被7整除的数字: 83
能被7整除的数为: 84
能被5整除的数为: 85
既不能被5整除也不能被7整除的数字: 86
既不能被5整除也不能被7整除的数字: 87
既不能被5整除也不能被7整除的数字: 88
既不能被5整除也不能被7整除的数字: 89
能被5整除的数为: 90
能被7整除的数为: 91
既不能被5整除也不能被7整除的数字: 92
既不能被5整除也不能被7整除的数字: 93
既不能被5整除也不能被7整除的数字: 94
能被5整除的数为: 95
既不能被5整除也不能被7整除的数字: 96
既不能被5整除也不能被7整除的数字: 97
能被7整除的数为: 98
既不能被5整除也不能被7整除的数字: 99

2、skipOnFirstNonTriggeredRule示例

public class FizzBuzzRulesLauncher {public static void main(String[] args) {RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstNonTriggeredRule(true);RulesEngine rulesEngine = new DefaultRulesEngine(parameters);// 规则注册Rules rules = new Rules();rules.register(new FizzRule());rules.register(new BuzzRule());rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));rules.register(new NonFizzBuzzRule());// 触发规则Facts facts = new Facts();for (int count = 0; count < 100; count++) {facts.put("number", count);rulesEngine.fire(rules, facts);}}
}

这里我们把规则引擎参数调整为skipOnFirstNonTriggeredRule,意味着当优先级最高的规则没有被触发后就跳过下面的规则,执行结果如下:

能被5整除的数为: 0
能被7整除的数为: 0
能被5整除的数为: 0
能被7整除的数为: 0
能被5整除的数为: 35
能被7整除的数为: 35
能被5整除的数为: 35
能被7整除的数为: 35
能被5整除的数为: 70
能被7整除的数为: 70
能被5整除的数为: 70
能被7整除的数为: 70

3、skipOnFirstFailedRule示例

***5整除的规则* @author Nick Liu* @date 2023/8/4*/
@Rule
public class FizzRule {@Conditionpublic boolean isFizz(@Fact("number") Integer number) {return number % 5 == 0;}@Actionpublic void printFizz(@Fact("number") Integer number) throws Exception {System.out.println("能被5整除的数为: " + number);throw new RuntimeException("该数字能被5整除");}@Prioritypublic int getPriority() {return 1;}}

这里我们修改了FizzRule规则触发后的执行行为,当数字能被5整除时,执行行为后抛出异常。

public class FizzBuzzRulesLauncher {public static void main(String[] args) {RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstFailedRule(true);RulesEngine rulesEngine = new DefaultRulesEngine(parameters);// 规则注册Rules rules = new Rules();rules.register(new FizzRule());rules.register(new BuzzRule());rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));rules.register(new NonFizzBuzzRule());// 触发规则Facts facts = new Facts();for (int count = 0; count < 100; count++) {facts.put("number", count);rulesEngine.fire(rules, facts);}}
}

这里我们设置了规则引擎的参数skipOnFirstFailedRule,也就是当判断规则是否触发时发生异常或者执行行为时发生异常后,就跳过下一条规则,程序运行结果如下:

能被5整除的数为: 0
既不能被5整除也不能被7整除的数字: 1
既不能被5整除也不能被7整除的数字: 2
既不能被5整除也不能被7整除的数字: 3
既不能被5整除也不能被7整除的数字: 4
能被5整除的数为: 5
既不能被5整除也不能被7整除的数字: 6
能被7整除的数为: 7
既不能被5整除也不能被7整除的数字: 7
既不能被5整除也不能被7整除的数字: 8
既不能被5整除也不能被7整除的数字: 9
能被5整除的数为: 10
既不能被5整除也不能被7整除的数字: 11
既不能被5整除也不能被7整除的数字: 12
既不能被5整除也不能被7整除的数字: 13
能被7整除的数为: 14
既不能被5整除也不能被7整除的数字: 14
能被5整除的数为: 15
既不能被5整除也不能被7整除的数字: 16
既不能被5整除也不能被7整除的数字: 17
既不能被5整除也不能被7整除的数字: 18
既不能被5整除也不能被7整除的数字: 19
能被5整除的数为: 20
能被7整除的数为: 21
既不能被5整除也不能被7整除的数字: 21
既不能被5整除也不能被7整除的数字: 22
既不能被5整除也不能被7整除的数字: 23
既不能被5整除也不能被7整除的数字: 24
能被5整除的数为: 25
既不能被5整除也不能被7整除的数字: 26
既不能被5整除也不能被7整除的数字: 27
能被7整除的数为: 28
既不能被5整除也不能被7整除的数字: 28
既不能被5整除也不能被7整除的数字: 29
能被5整除的数为: 30
既不能被5整除也不能被7整除的数字: 31
既不能被5整除也不能被7整除的数字: 32
既不能被5整除也不能被7整除的数字: 33
既不能被5整除也不能被7整除的数字: 34
能被5整除的数为: 35
既不能被5整除也不能被7整除的数字: 36
既不能被5整除也不能被7整除的数字: 37
既不能被5整除也不能被7整除的数字: 38
既不能被5整除也不能被7整除的数字: 39
能被5整除的数为: 40
既不能被5整除也不能被7整除的数字: 41
能被7整除的数为: 42
既不能被5整除也不能被7整除的数字: 42
既不能被5整除也不能被7整除的数字: 43
既不能被5整除也不能被7整除的数字: 44
能被5整除的数为: 45
既不能被5整除也不能被7整除的数字: 46
既不能被5整除也不能被7整除的数字: 47
既不能被5整除也不能被7整除的数字: 48
能被7整除的数为: 49
既不能被5整除也不能被7整除的数字: 49
能被5整除的数为: 50
既不能被5整除也不能被7整除的数字: 51
既不能被5整除也不能被7整除的数字: 52
既不能被5整除也不能被7整除的数字: 53
既不能被5整除也不能被7整除的数字: 54
能被5整除的数为: 55
能被7整除的数为: 56
既不能被5整除也不能被7整除的数字: 56
既不能被5整除也不能被7整除的数字: 57
既不能被5整除也不能被7整除的数字: 58
既不能被5整除也不能被7整除的数字: 59
能被5整除的数为: 60
既不能被5整除也不能被7整除的数字: 61
既不能被5整除也不能被7整除的数字: 62
能被7整除的数为: 63
既不能被5整除也不能被7整除的数字: 63
既不能被5整除也不能被7整除的数字: 64
能被5整除的数为: 65
既不能被5整除也不能被7整除的数字: 66
既不能被5整除也不能被7整除的数字: 67
既不能被5整除也不能被7整除的数字: 68
既不能被5整除也不能被7整除的数字: 69
能被5整除的数为: 70
既不能被5整除也不能被7整除的数字: 71
既不能被5整除也不能被7整除的数字: 72
既不能被5整除也不能被7整除的数字: 73
既不能被5整除也不能被7整除的数字: 74
能被5整除的数为: 75
既不能被5整除也不能被7整除的数字: 76
能被7整除的数为: 77
既不能被5整除也不能被7整除的数字: 77
既不能被5整除也不能被7整除的数字: 78
既不能被5整除也不能被7整除的数字: 79
能被5整除的数为: 80
既不能被5整除也不能被7整除的数字: 81
既不能被5整除也不能被7整除的数字: 82
既不能被5整除也不能被7整除的数字: 83
能被7整除的数为: 84
既不能被5整除也不能被7整除的数字: 84
能被5整除的数为: 85
既不能被5整除也不能被7整除的数字: 86
既不能被5整除也不能被7整除的数字: 87
既不能被5整除也不能被7整除的数字: 88
既不能被5整除也不能被7整除的数字: 89
能被5整除的数为: 90
能被7整除的数为: 91
既不能被5整除也不能被7整除的数字: 91
既不能被5整除也不能被7整除的数字: 92
既不能被5整除也不能被7整除的数字: 93
既不能被5整除也不能被7整除的数字: 94
能被5整除的数为: 95
既不能被5整除也不能被7整除的数字: 96
既不能被5整除也不能被7整除的数字: 97
能被7整除的数为: 98
既不能被5整除也不能被7整除的数字: 98
既不能被5整除也不能被7整除的数字: 99

可以看到,既能被5整除也能被7整除的数,如3570只打印了一次。


三、组合规则

Easy Rules允许我们创建复杂的组合规则,所谓组合规则由多个单条规则组成,实际上就是组合设计模式的一种实现。

组合规则是一种抽象概念,因为组合规则可以通过不同的方式出发。Easy Rules提供了三种组合规则的实现,这些实现可以在easy-rules-support模块中可以找到,首先介绍一下3种组合规则:

  • UnitRuleGroup: 单元规则组,里面的所有规则都会被应用。
  • ActivationRuleGroup: 激活规则组,只会触发第一条适用的规则,该规则组中的所有规则默认根据优先级排序。
  • ConditionalRuleGroup: 条件式规则则,如果最高优先级的规则可以被触发,那么才会触发其它规则组中的规则。

1、UnitRuleGroup组合规则

该组合规则判断规则是否触发的代码如下,可以看到,所有的规则如果被触发,相应的行为就会被执行。

@Override
public boolean evaluate(Facts facts) {if (!rules.isEmpty()) {for (Rule rule : rules) {if (!rule.evaluate(facts)) {return false;}}return true;}return false;
}@Override
public void execute(Facts facts) throws Exception {for (Rule rule : rules) {rule.execute(facts);}
}

2、ActivationRuleGroup组合规则

从该组合规则的源代码可以看到,该规则组中只有第一条可以被触发的规则才会执行相应的规则行为。

@Override
public boolean evaluate(Facts facts) {for (Rule rule : rules) {if (rule.evaluate(facts)) {selectedRule = rule;return true;}}return false;
}@Override
public void execute(Facts facts) throws Exception {if (selectedRule != null) {selectedRule.execute(facts);}
}

3、ConditionalRuleGroup组合规则

该组合规则的源代码如下,可以看到只有最高优先级的规则可以被触发,才会继续应用其它规则中的规则。

 @Overridepublic boolean evaluate(Facts facts) {successfulEvaluations = new HashSet<>();conditionalRule = getRuleWithHighestPriority();if (conditionalRule.evaluate(facts)) {for (Rule rule : rules) {if (rule != conditionalRule && rule.evaluate(facts)) {successfulEvaluations.add(rule);}}return true;}return false;}/*** When a conditional rule group is executed, all rules that evaluated to true* are performed in their natural order, but with the conditional rule * (the one with the highest priority) first.** @param facts The facts.** @throws Exception thrown if an exception occurs during actions performing*/@Overridepublic void execute(Facts facts) throws Exception {conditionalRule.execute(facts);for (Rule rule : sort(successfulEvaluations)) {rule.execute(facts);}}private Rule getRuleWithHighestPriority() {List<Rule> copy = sort(rules);// make sure we only have one rule with the highest priorityRule highest = copy.get(0);if (copy.size() > 1 && copy.get(1).getPriority() == highest.getPriority()) {throw new IllegalArgumentException("Only one rule can have highest priority");}return highest;}private List<Rule> sort(Set<Rule> rules) {return new ArrayList<>(new TreeSet<>(rules));}

在这里插入图片描述

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

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

相关文章

基于Java的基数排序(详述)

基于Java的基数排序&#xff08;详述&#xff09; 原理介绍Java实现文献参考 原理介绍 一、什么是基数排序 &#xff08;1&#xff09;通过键值得各个位的值&#xff0c;将要排序的元素分配至一些桶中&#xff0c;达到排序的作用 &#xff08;2&#xff09;基数排序法是属于稳…

Unity Meta Quest MR 开发教程:(二)自定义透视 Passthrough【透视功能进阶】

文章目录 &#x1f4d5;教程说明&#x1f4d5;动态开启和关闭透视⭐方法一&#xff1a;OVRManager.instance.isInsightPassthroughEnabled⭐方法二&#xff1a;OVRPassthroughLayer 脚本中的 hidden 变量 &#x1f4d5;透视风格 Passthrough Styling⭐Inspector 面板控制⭐代码…

固定资产台账怎么管理

固定资产台账是指企业对固定资产进行登记、分类、统计和管理的账簿。固定资产管理系统是一款专业的固定资产管理软件&#xff0c;可以帮助企业实现资产全生命周期管理&#xff0c;包括资产采购、入库、领用、归还、维修、报废等环节。系统具有实时监控、预警提醒、报表分析等功…

App Inventor 2 开发 ChatGPT 对话App

ChatGPT大家应该不会陌生&#xff0c;它的回答内容非常的专业及深入&#xff0c;具有实际的可指导性。我们通过App Inventor 2开发一个简单的对话App&#xff0c;先看效果&#xff1a; App Inventor 2 ChatGPT教育领域对话演示 代码块如下&#xff1a; 用到的核心组件“ChatBot…

6.oracle中listagg函数使用

1. 作用 可以实现行转列&#xff0c;将多列数据聚合为一列&#xff0c;实现数据的压缩 2. 语法 listagg(measure_expr&#xff0c;delimiter) within group ( order by order_by_clause); 解释&#xff1a; measure_expr可以是基于任何列的表达式 delimiter分隔符&#xff0c…

HTML学习笔记02

HTML笔记02 页面结构分析 元素名描述header标题头部区域的内容&#xff08;用于页面或页面中的一块区域&#xff09;footer标记脚部区域的内容&#xff08;用于整个页面或页面的一块区域&#xff09;sectionWeb页面中的一块独立区域article独立的文章内容aside相关内容或应用…

红黑树(AVL树的优化)上

红黑树略胜AVL树 AVL树是一颗高度平衡搜索二叉树&#xff1a; 要求左右高度差不超过1&#xff08;严格平衡&#xff09; 有的大佬认为AVL树太过严格&#xff0c;对平衡的要求越严格&#xff0c;会带来更多的旋转&#xff08;旋转也还是会有一定的消耗&#xff01;&#xff01;…

WordPress使用子主题插件 Child Theme Wizard,即使主题升级也能够保留以前主题样式

修改WordPress网站样式&#xff0c;主题升级会导致自己定义设置的网站样式丢失&#xff0c;还需要重新设置&#xff0c;很繁琐工作量大&#xff0c;发现在WordPress 中有Child Theme Wizard子主题插件&#xff0c;使用Child Theme Wizard子主题插件&#xff0c;即使主题升级&am…

2023年下半年西安/广州/深圳软考(中/高级)开班啦!!!

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成项…

智慧校园用电安全解决方案

随着科技的不断发展&#xff0c;智慧校园建设逐渐成为了教育行业的一大趋势。在这个过程中&#xff0c;电力系统作为校园基础设施的重要组成部分&#xff0c;其安全、稳定、高效的运行显得尤为重要。下面小编来为大家介绍下智慧校园用电安全解决方案吧! 一、智慧校园电力系统现…

抖店无货源和工厂直发有什么区别?聊下无货源的概念和做店思路

我是王路飞。 最近收到了几条私信&#xff0c;都是关于做抖店的&#xff0c;其中有一条吸引了我的兴趣。 他问的是&#xff1a;抖店的无货源和工厂直发有什么区别吗&#xff1f; 说实话&#xff0c;这个问题&#xff0c;我一开始是不打算回复的&#xff0c;因为没有意义。 …

C# task多线程创建,暂停,继续,结束使用

1、多线程任务创建 private void button1_Click(object sender, EventArgs e) //创建线程{CancellationToken cancellationToken tokensource.Token;Task.Run(() > //模拟耗时任务{for (int i 0; i < 100; i){if (cancellationToken.IsCancellationRequested){return;…

[C++ 网络协议] 多进程服务器端

具有代表性的并发服务器端实现模型和方法&#xff1a; 多进程服务器&#xff1a;通过创建多个进程提供服务。✔ 多路复用服务器&#xff1a;通过捆绑并统一管理I/O对象提供服务。 多线程服务器&#xff1a;通过生成与客户端等量的线程提供服务。 目录 1. 进程的概念及应用 1.…

CTFhub-文件上传-前端验证

burp 抓包 --> 重发--> 查看源代码 用 GodZilla 生成木马 文件名为 1.php.jsp 上传-->抓包-->改包 (删掉 .jpg) --> 点击 放行 木马文件位置为&#xff1a;http://challenge-f0531d0c27641130.sandbox.ctfhub.com:10800/upload/1.php 用 蚁剑连接 ctfhub{4743b…

数组中的第K个最大元素

题目链接 数组中的第K个最大元素 题目描述 注意点 需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素 解答思路 本题可以使用快速排序、堆排序或优先队列解决&#xff0c;快排可以比较快速找到某个元素在数组中排序后的位置&#xff0c;所以找…

Linux内核数据结构 散列表

1、散列表数据结构 在Linux内核中&#xff0c;散列表&#xff08;哈希表&#xff09;使用非常广泛。本文将对其数据结构和核心函数进行分析。和散列表相关的数据结构有两个&#xff1a;hlist_head 和 hlist_node //hash桶的头结点 struct hlist_head {struct hlist_node *first…

最简单vue获取当前地区天气--高德开放平台实现

目录 前言 一、注册成为高德平台开发者 二、注册天气key 1.点击首页右上角打开控制台 2.创建新应用 三、vue项目使用 1.打开vue项目找到public下的index.html&#xff0c;如果是vue3的话直接在主目录打开index.html文件就行&#xff0c;主要就是打开出口文件 ​编辑 2.根据高德…

HTTPS协议原理

目录 前言 1.理解加密和解密 2.为什么要加密 3.常见的加密方式 3.1对称加密 3.2非对称加密 4.数据摘要和数据指纹 5. 数字签名 6.HTTPS的加密策略 6.1只使用对称加密 6.2使用非对称加密 6.2.1服务端使用非对称加密 6.2.2双方都使用非对称加密 6.3对称加密非对称加…

OLED透明屏显示技术:未来显示科技的领航者

OLED透明屏显示技术是一种创新性的显示技术&#xff0c;它的特殊性质使其成为未来显示科技的领航者。 OLED透明屏具有高对比度、快速响应时间、广视角和低功耗等优势&#xff0c;同时&#xff0c;其透明度、柔性和薄型设计使其成为创新设计的理想选择。 本文将深入探讨OLED透…

【爬虫】5.6 Selenium等待HTML元素

任务目标 在浏览器加载网页的过程中&#xff0c;网页的有些元素时常会有延迟的现象&#xff0c;在HTML元素还没有准备好的情况下去操作这个HTML元素必然会出现错误&#xff0c;这个时候Selenium需要等待HTML元素。例如&#xff1a;上节实例中出现的select的下拉框元素&#xff…