kotlin的密封类

引言

密封类是一种特殊的类,它用来表示受限的类继承结构,即一个类只能有有限的几种子类,而不能有任何其他类型的子类。

这不就是JAVA的枚举么。

概念

密封类使用sealed关键字声明,

在Kotlin 1.0中,密封类的所有子类必须嵌套在密封类内部;

在Kotlin 1.1中,这个限制放宽了,允许将子类定义在同一个文件中;

在Kotlin 1.5中,这个限制进一步放宽了,允许将子类定义在任何地方,只要保证子类可见性不高于父类。

密封类通常用于代替枚举类。密封类的优点在于可以更灵活地定义子类,而枚举类的每个成员都是固定的。密封类还可以帮助你编写更加类型安全的代码

密封类最大的优点是可以配合when表达式实现完备性检查(exhaustive check),即编译器可以检测出是否覆盖了所有可能的分支情况,如果没有则会报错或提示警告。这样可以避免遗漏某些情况导致逻辑错误或运行时异常。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

很抽象。

密封类和枚举的区别是什么?

相同点:所有成员都属于本类本身

不同点:枚举只能有一个实例,而密封类的子类可以有多个实例。

密封类的子类可以携带自己独有的状态参数以及行为方法来记录更多的实现信息以完成更多的功能,这是枚举类所不具备的。

例子:

sealed class MyScore {object FAIL_A_GRADE : MyScore()//分数差object PASS_THE_MARK : MyScore()//分数及格object SCORE_WELL : MyScore()//分数良好class EXCELLENT_MARKS(val name: String) : MyScore()//分数优秀}

密封类的所有成员都继承本类MyScore ,但是允许个别成员拥有自己特殊属性如 EXCELLENT_MARKS 。

三、使用

密封类的代数数据类型

密封类与 when结合,使用 is 进行判断类型,跟枚举类相似

fun show() = when (myScore) {is MyScore.FAIL_A_GRADE -> "分数差"is MyScore.PASS_THE_MARK -> "分数及格"is MyScore.SCORE_WELL -> "分数良好"is MyScore.EXCELLENT_MARKS -> "分数优秀,name=${myScore.name}"}

密封类实例

当某个成员需要特殊属性的时候,用枚举就比较难实现这个需求,密封类就是为了解决这个问题而出现的。

如下实例:当我们想知道优秀学生的名字的时候,只用枚举去实现就不好实现

//密封类,所有成员都继承本类
//当某个成员需要特殊属性的时候,用枚举就比较难实现这个需求
sealed class MyScore {object FAIL_A_GRADE : MyScore()//分数差object PASS_THE_MARK : MyScore()//分数及格object SCORE_WELL : MyScore()//分数良好class EXCELLENT_MARKS(val name: String) : MyScore()//分数优秀}class Teachers(private val myScore: MyScore) {fun show() = when (myScore) {is MyScore.FAIL_A_GRADE -> "分数差"is MyScore.PASS_THE_MARK -> "分数及格"is MyScore.SCORE_WELL -> "分数良好"is MyScore.EXCELLENT_MARKS -> "分数优秀,name=${myScore.name}"}}//todo kotlin语言的密封类学习
fun main() {println(Teachers(MyScore.FAIL_A_GRADE).show())println(Teachers(MyScore.EXCELLENT_MARKS("kotlin")).show())}

输出:

分数差
分数优秀,name=kotlin

四、密封类与设计模式

1.状态模式

状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。状态模式将状态封装成独立的类,并将请求委托给当前的状态对象,从而实现状态的切换和行为的变化。

1.1kotlin实现

密封类可以表示一个有限的状态集合,而且可以在when表达式中进行完备的检查,不需要使用else分支。例如,假设有一个电灯类,它有两种状态:开和关,每种状态下可以执行不同的操作。可以用以下的代码来实现:

// 定义一个密封类表示状态
sealed class State {// 定义一个抽象方法表示操作abstract fun operate()
}// 定义一个开状态的子类,继承自State
class On : State() {// 重写操作方法,打印信息并切换到关状态override fun operate() {println("The light is on, turn it off.")Light.state = Off()}
}// 定义一个关状态的子类,继承自State
class Off : State() {// 重写操作方法,打印信息并切换到开状态override fun operate() {println("The light is off, turn it on.")Light.state = On()}
}// 定义一个电灯类,它有一个状态属性,初始为关状态
object Light {var state: State = Off()// 定义一个方法,根据当前状态执行操作fun switch() {state.operate()}
}// 测试代码
fun main() {// 创建一个电灯对象val light = Light// 调用switch方法,根据当前状态执行操作light.switch() // The light is off, turn it on.light.switch() // The light is on, turn it off.light.switch() // The light is off, turn it on.
}
1.2java实现

在java中,实现状态模式的一种方式是使用枚举类,因为枚举类也可以表示一个有限的状态集合,而且可以实现接口或抽象类,从而定义不同的行为。例如,用java实现上面的例子,可以用以下的代码:

// 定义一个接口表示状态
interface State {// 定义一个抽象方法表示操作void operate();
}// 定义一个枚举类表示状态,实现State接口
enum LightState implements State {// 定义两个枚举常量,分别表示开和关状态// 在每个枚举常量的构造器中,传入一个State对象,表示该状态下的行为ON(new State() {// 重写操作方法,打印信息并切换到关状态@Overridepublic void operate() {System.out.println("The light is on, turn it off.");Light.state = OFF;}}),OFF(new State() {// 重写操作方法,打印信息并切换到开状态@Overridepublic void operate() {System.out.println("The light is off, turn it on.");Light.state = ON;}});// 定义一个私有的State属性,表示该枚举常量对应的状态对象private final State state;// 定义一个私有的构造器,接收一个State对象作为参数,赋值给state属性private LightState(State state) {this.state = state;}// 定义一个公共的方法,调用state属性的operate方法public void operate() {state.operate();}
}// 定义一个电灯类,它有一个状态属性,初始为关状态
class Light {// 定义一个静态的LightState属性,表示电灯的状态,初始为OFFpublic static LightState state = LightState.OFF;// 定义一个方法,根据当前状态执行操作public void switch() {state.operate();}
}// 测试代码
public class Main {public static void main(String[] args) {// 创建一个电灯对象Light light = new Light();// 调用switch方法,根据当前状态执行操作light.switch(); // The light is off, turn it on.light.switch(); // The light is on, turn it off.light.switch(); // The light is off, turn it on.}
}

可以看出,使用kotlin的密封类实现状态模式的优点是:

  • 代码更简洁,不需要定义接口或抽象类,也不需要使用匿名内部类
  • 代码更安全,不需要担心在其他地方出现未知的状态,也不需要使用else分支处理默认情况
  • 代码更易读,可以清楚地看出状态之间的层次关系和转换逻辑

使用java的枚举类实现状态模式的优点是:

  • 代码更统一,不需要在不同的类中定义状态,也不需要使用对象来表示状态
  • 代码更高效,不需要创建多个状态对象,也不需要使用多态来调用操作方法

2. 访问者模式

访问者模式是一种行为型设计模式,它允许在不修改已有类的结构的情况下,定义作用于这些类的新操作。访问者模式将元素的结构和元素的操作分离,使得操作可以根据不同的元素类型而变化。

2.1kotlin实现

在kotlin中,可以使用密封类来实现访问者模式,因为密封类可以表示一个有限的元素集合,而且可以在when表达式中进行完备的检查,不需要使用else分支。例如,假设有一个表达式类,它有两种子类:数字和加法,每种子类都可以被访问者访问,执行不同的操作。可以用以下的代码来实现:

// 定义一个密封类表示表达式
sealed class Expr {// 定义一个抽象方法表示接受访问者的访问abstract fun <R> accept(visitor: Visitor<R>): R
}// 定义一个数字的子类,继承Expr类,有一个value属性表示数字的值data class Num(val value: Int) : Expr() {// 重写accept方法,调用访问者的visitNum方法,传入自己作为参数override fun <R> accept(visitor: Visitor<R>): R {return visitor.visitNum(this)}}// 定义一个加法的子类,继承Expr类,有两个Expr属性表示左右操作数data class Sum(val left: Expr, val right: Expr) : Expr() {// 重写accept方法,调用访问者的visitSum方法,传入自己作为参数override fun <R> accept(visitor: Visitor<R>): R {return visitor.visitSum(this)}}// 定义一个访问者接口,泛型参数R表示访问的结果类型interface Visitor<R> {// 定义一个访问数字的方法,接收一个Num对象作为参数,返回一个R类型的结果fun visitNum(num: Num): R// 定义一个访问加法的方法,接收一个Sum对象作为参数,返回一个R类型的结果fun visitSum(sum: Sum): R}// 定义一个求值的访问者类,实现Visitor接口,泛型参数为Intclass EvalVisitor : Visitor<Int> {// 重写访问数字的方法,返回数字的值override fun visitNum(num: Num): Int {return num.value}// 重写访问加法的方法,返回左右操作数的求值结果的和override fun visitSum(sum: Sum): Int {return sum.left.accept(this) + sum.right.accept(this)}}// 定义一个打印的访问者类,实现Visitor接口,泛型参数为Stringclass PrintVisitor : Visitor<String> {// 重写访问数字的方法,返回数字的字符串表示override fun visitNum(num: Num): String {return num.value.toString()}// 重写访问加法的方法,返回加法的字符串表示,用括号括起来override fun visitSum(sum: Sum): String {return "(${sum.left.accept(this)} + ${sum.right.accept(this)})"}}// 测试代码fun main() {// 创建一个表达式对象,表示1 + (2 + 3)val expr = Sum(Num(1), Sum(Num(2), Num(3)))// 创建一个求值的访问者对象val evalVisitor = EvalVisitor()// 创建一个打印的访问者对象val printVisitor = PrintVisitor()// 调用表达式的accept方法,传入求值的访问者,打印求值的结果println(expr.accept(evalVisitor)) // 6// 调用表达式的accept方法,传入打印的访问者,打印表达式的字符串表示println(expr.accept(printVisitor)) // (1 + (2 + 3))}

可以看出,使用kotlin的密封类实现访问者模式的优点是:

  • 代码更简洁,不需要定义抽象方法或接口,也不需要使用类型转换或类型检查
  • 代码更安全,不需要担心在其他地方出现未知的表达式类型,也不需要使用else分支处理默认情况
  • 代码更易读,可以清楚地看出表达式之间的层次关系和访问者的操作逻辑
2.2 java实现
// 抽象元素
interface Animal {void accept(Visitor visitor); // 接受一个抽象访问者
}// 具体元素Lion
class Lion implements Animal {@Overridepublic void accept(Visitor visitor) {visitor.visit(this); // 调用具体访问者对自己进行操作}public String roar() {return "Roar!";}
}// 具体元素Tiger
class Tiger implements Animal {@Overridepublic void accept(Visitor visitor) {visitor.visit(this); // 调用具体访问者对自己进行操作}public String growl() {return "Growl!";}
}// 具体元素Elephant
class Elephant implements Animal {@Overridepublic void accept(Visitor visitor) {visitor.visit(this); // 调用具体访问者对自己进行操作}public String trumpet() {return "Trumpet!";}
}// 抽象访问者
interface Visitor {void visit(Lion lion); // 访问具体元素Lionvoid visit(Tiger tiger); // 访问具体元素Tigervoid visit(Elephant elephant); // 访问具体元素Elephant
}// 具体访问者Feed
class Feed implements Visitor {@Override public void visit(Lion lion) { System.out.println("Feed the lion with meat.");} @Override public void visit(Tiger tiger) { System.out.println("Feed the tiger with chicken.");} @Override public void visit(Elephant elephant) { System.out.println("Feed the elephant with banana.");} 
}// 具体访问者Observe
class Observe implements Visitor { @Override public void visit(Lion lion) { System.out.println("Observe the lion: " + lion.roar());} @Override public void visit(Tiger tiger) { System.out.println("Observe the tiger: " + tiger.growl());} @Override public void visit(Elephant elephant) { System.out.println("Observe the elephant: " + elephant.trumpet());}  
}// 具体访问者Train
class Train implements Visitor {  @Override  public void visit(Lion lion) {  System.out.println("Train the lion to jump through a hoop.");  }  @Override  public void visit(Tiger tiger) {  System.out.println("Train the tiger to stand on a ball.");  }  @Override  public void visit(Elephant elephant) {  System.out.println("Train the elephant to sit on a stool.");  }   
}  // 对象结构类Zooclass Zoo {private List<Animal> animals = new ArrayList<>();// 添加一个新动物   
public void add(Animal animal) {   animals.add(animal);   
}   // 移除一个已有动物   
public void remove(Animal animal) {   animals.remove(animal);   
}   // 接受一个抽象访问者,并将所有动物传递给它进行处理    
public void accept(Visitor visitor) {    for (Animal animal : animals) {    animal.accept(visitor);    }    
}   
}

测试代码:

public class Test {public static void main(String[] args) {Zoo zoo = new Zoo();zoo.add(new Lion());zoo.add(new Tiger());zoo.add(new Elephant());Visitor feed = new Feed();Visitor observe = new Observe();Visitor train = new Train();zoo.accept(feed);zoo.accept(observe);zoo.accept(train);}
}

运行测试代码并显示输出结果:

Feed the lion with meat.
Feed the tiger with chicken.
Feed the elephant with banana.
Observe the lion: Roar!
Observe the tiger: Growl!
Observe the elephant: Trumpet!
Train the lion to jump through a hoop.
Train the tiger to stand on a ball.
Train the elephant to sit on a stool.

五、与final类对比

特性密封类final类
可继承性部分可继承,只能被指定的类继承不可继承
受保护成员或虚成员不允许,因为密封类的子类必须是密封类或final类允许,因为final类没有子类
抽象性允许,因为密封类可以是抽象的或具体的不允许,因为抽象类必须被继承
相似之处都是限制类的继承,都不能声明为抽象的,都可以继承别的类或接口都是限制类的继承,都不能声明为抽象的,都可以继承别的类或接口
不同之处可以指定哪些类可以作为其子类,可以实现多态性,可以用于一些特定的设计模式不能有任何子类,不能实现多态性,不能用于一些特定的设计模式
优点可以保证封装性和多态性,可以提高代码的可读性和可维护性,可以避免不必要的继承或实现可以保证封装性和不变性,可以提高代码的执行效率,可以避免类的滥用
缺点可能增加代码的复杂度和冗余,可能限制类的扩展性和灵活性,可能与一些框架或库不兼容可能增加代码的耦合度和僵化度,可能限制类的扩展性和灵活性,可能与一些框架或库不兼容
应用场景可以用于实现一些特定的设计模式,例如状态模式、策略模式、访问者模式等,这些模式需要明确地定义一组有限的子类或实现类可以用于实现一些不需要继承的类,例如工具类、常量类、单例类等,这些类需要保证其不变性和唯一性


六、应用

如果说,我们一个需求,控制档位,有两种模式,一种是inch 一种是mm。怎么表达?

我们想到是两个数组一一对应,如果java写就是枚举。

public class Test {public static void main(String[] args) {System.out.println("根据英文描述获取中文描述:" + ColorEnum.getDescriptionByCode(ColorEnum.YELLOW.getCode()));System.out.println("根据输入字符获取中文描述(有):" + ColorEnum.getDescriptionByCode("RED"));System.out.println("根据输入字符获取中文描述(无):" + ColorEnum.getDescriptionByCode("PURPLE"));}
}enum ColorEnum {YELLOW("YELLOW", "黄色"),WHITE("WHITE", "白色"),GREEN("GREEN", "绿色"),BLUE("BLUE", "蓝色"),RED("RED", "红色");//枚举标识码(中文描述)private final String description;//这个必须定义,且成员变量的类型及个数必须对应于上边枚举的定义//枚举标识码(英文描述)private final String code;ColorEnum(String code, String description) {this.code = code;this.description = description;}public String getCode() {return code;}public String getDescription() {return description;}public static String getDescriptionByCode(String code) {for (ColorEnum value : ColorEnum.values()) {if (value.getCode().equals(code)) {return value.getDescription();}}return null;}
}执行结果:
根据英文描述获取中文描述:黄色
根据输入字符获取中文描述(有):红色
根据输入字符获取中文描述(无):null

那么kotlin怎么写:

用data数据类+密封类

sealed class OrderStatus {abstract val orderId: Stringdata class Pending(override val orderId: String) : OrderStatus()data class Shipped(override val orderId: String, val trackingNumber: String) : OrderStatus()data class Delivered(override val orderId: String, val deliveryDate: String) : OrderStatus()object Cancelled : OrderStatus()fun getDescription(): String {return when (this) {is Pending -> "Order $orderId is pending"is Shipped -> "Order $orderId has been shipped with tracking number $trackingNumber"is Delivered -> "Order $orderId has been delivered on $deliveryDate"Cancelled -> "Order $orderId has been cancelled"}}
}fun main() {val pendingOrder = OrderStatus.Pending("12345")val shippedOrder = OrderStatus.Shipped("67890", "XYZ123")val deliveredOrder = OrderStatus.Delivered("23456", "2023-09-25")val cancelledOrder = OrderStatus.Cancelledprintln(pendingOrder.getDescription())println(shippedOrder.getDescription())println(deliveredOrder.getDescription())println(cancelledOrder.getDescription())
}

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

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

相关文章

OpenCV特征检测(4)检测图像中的角点函数cornerHarris()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 Harris 角点检测器。 该函数在图像上运行 Harris 角点检测器。类似于 cornerMinEigenVal 和 cornerEigenValsAndVecs&#xff0c;对于每个像素 (…

如何将生物序列tokenization为token?

原理讲解 tokenization是自然语言处理领域非常成熟的一项技术&#xff0c;tokenization就是把我们研究的语言转换成计算机能够识别的数字——token。 在生物领域&#xff0c;如何把核苷酸或氨基酸序列tokenization成token呢&#xff1f; 我们可以使用k-mer技术&#xff1a; k-m…

网络设备登录——《路由与交换技术》实验报告

目录 一、实验目的 二、实验设备和环境 三、实验记录 1.通过 Console 登录 步骤1:连接配置电缆。 步骤2:启动PC,运行超级终端。 步骤3:进入Console 配置界面 2.通过 Telnet 登录 步骤1:通过 Console 接口配置 Telnet 用户。 步骤2:配置 super 口令 步骤3:配置登录欢迎…

神经网络构建原理(以MINIST为例)

神经网络构建原理(以MINIST为例) 在 MNIST 手写数字识别任务中&#xff0c;构建神经网络并训练模型来进行分类是经典的深度学习应用。MNIST 数据集包含 28x28 像素的手写数字图像&#xff08;0-9&#xff09;&#xff0c;任务是构建一个神经网络&#xff0c;能够根据输入的图像…

吉首大学--23级题目讲解

7-1 单链表基本操作 在 C/C 中&#xff0c;.&#xff08;点&#xff09;和 ->&#xff08;箭头&#xff09;运算符用于访问结构体或类的成员&#xff0c;但它们的使用场景不同。 1. . 运算符 . 运算符用于访问结构体或类的成员&#xff0c;通过对象或结构体变量直接访问。…

es的封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前…

Element Plus 中Input输入框

通过鼠标或键盘输入字符 input为受控组件&#xff0c;他总会显示Vue绑定值&#xff0c;正常情况下&#xff0c;input的输入事件会正常被响应&#xff0c;他的处理程序应该更新组件的绑定值&#xff08;或使用v-model&#xff09;。否则&#xff0c;输入框的值将不会改变 不支…

windows环境下配置MySQL主从启动失败 查看data文件夹中.err发现报错unknown variable ‘log‐bin=mysql‐bin‘

文章目录 问题解决方法 问题 今天在windows环境下配置MySQL主从同步&#xff0c;在修改my.ini文件后发现MySQL启动失败了 打开my.ini检查参数发现没有问题 [mysqld] #开启二进制日志&#xff0c;记录了所有更改数据库数据的SQL语句 log‐bin mysql‐bin #设置服务id&#x…

[数据集][目标检测]不同颜色的安全帽检测数据集VOC+YOLO格式7574张5类别

重要说明&#xff1a;数据集里面有2/3是增强数据集&#xff0c;请仔细查看图片预览&#xff0c;确认符合要求在下载&#xff0c;分辨率均为640x640 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件…

Python 二级考试

易错点 电脑基础知识 定义学生关系模式如下&#xff1a;Student &#xff08;S#&#xff0c; Sn&#xff0c; Ssex&#xff0c;class&#xff0c;monitorS#&#xff09;&#xff08;其属性分别为学号、学生名、性别、班级和班长学号&#xff09; 在关系模式中&#xff0c;如果…

python-SZ斐波那契数列/更相减损数

一&#xff1a;SZ斐波那契数列题目描述 你应该很熟悉斐波那契数列&#xff0c;不是吗&#xff1f;现在小理不知在哪里搞了个山寨版斐波拉契数列&#xff0c;如下公式&#xff1a; F(n) { $\ \ \ \ \ \ \ \ \ \ \ \ $ a,( n1) $\ \ \ \ \ \ \ \ \ \ \ \ $ b,( n2) $\ \ \ \ \ \ …

【优选算法之双指针】No.2--- 经典双指针算法(下)

文章目录 前言一、双指针示例&#xff1a;1.1 ⽔果成篮1.2 和为s的两个数字1.3 三数之和1.4 四数之和 二、双指针总结&#xff1a; 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&#x1f31d; &#x1f4cb;专…

安装黑群晖系统,并使用NAS公网助手访问教程(好文)

由于正版群晖系统的价格不菲&#xff0c;对于预算有限的用户来说&#xff0c;安装黑群晖系统成为了一个不错的选择&#xff08;如果您预算充足&#xff0c;建议选择白群晖&#xff09;。如您对宅系科技比较感兴趣&#xff0c;欢迎查看本文&#xff0c;将详细介绍如何安装黑群晖…

allWebPlugin中间件自定义alert、confirm及prompt使用

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

跨游戏引擎的H5渲染解决方案(腾讯)

本文是腾讯的一篇H5 跨引擎解决方案的精炼。 介绍 本文通过实现基于精简版的HTML5&#xff08;HyperText Mark Language 5&#xff09;来屏蔽不同引擎&#xff0c;平台底层的差异。 好处&#xff1a; 采用H5的开发方式&#xff0c;可以将开发和运营分离&#xff0c;运营部门自…

代码随想录Day 51|题目:99.岛屿数量、100.岛屿的最大面积

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 题目一&#xff1a;99. 岛屿数量思路深度优先搜索DFS广度优先搜索BFS 题目二&#xff1a;100. 岛屿的最大面积DFSBFS 总结 题目一&#xff1a;99. 岛屿数量 99. 岛屿数量 (kamacoder.com) 思路 …

Tomcat服务器—Windows下载配置详细教程

一、关于 1.1 简介 Tomcat是一个开源的Java Servlet容器和Web服务器&#xff0c;由Apache软件基金会维护。它实现了Java Servlet和JavaServer Pages (JSP) 规范&#xff0c;用于运行Java Web应用程序。Tomcat支持多种Java EE功能&#xff0c;并提供了高效的性能和可扩展性&am…

华为OD机试 - 分解正整数 - 数学推导(Python/JS/C/C++ 2024 D卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

Redisson实现分布式锁(看门狗机制)

目录 可重入锁&#xff1a; 锁重试和看门狗机制&#xff1a; 主从一致性&#xff1a; 首先引入依赖&#xff0c;配置好信息 3.使用Redisson的分布式锁 可重入锁&#xff1a; 可重入锁实现是通过redsi中的hash实现的&#xff0c;key依旧是业务名称加id&#xff0c;然后第一个…

如何成立一家自己的等级保护测评机构?需要哪些条件?有哪些要求?

给大家的福利&#xff0c;点击下方蓝色字 即可免费领取↓↓↓ &#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 各省、自治区、直辖市公安厅、局网络安全保卫总队&#xff0c;新疆生产建设兵团公安局网络安…