鸿蒙开发新视角:用ArkTS解锁责任链模式
责任链模式:概念与原理
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它将多个处理者对象连接成一条链,并将请求沿着链传递,直到有一个处理者能够处理该请求。这种模式的核心思想是将请求的发送者和接收者解耦,使得系统更加灵活和可扩展。
举个生活中的例子,在公司的请假流程中,员工提交请假申请后,可能需要经过组长、部门经理、总经理等多个层级的审批。如果请假天数较少,组长就可以直接批准;如果请假天数较多,则需要依次向上级领导传递,直到找到能够处理该请求的领导。这个过程就像是一条责任链,每个领导都是链上的一个节点,负责处理自己职责范围内的请求。
再比如,在报销流程中,不同金额的报销申请需要由不同的审批人进行处理。小额报销可能由部门经理直接审批,大额报销则需要经过财务部门、总经理等多个环节。通过责任链模式,可以将这些审批环节组织成一条链,实现灵活的审批流程。
从代码实现的角度来看,责任链模式包含以下几个核心角色:
- 抽象处理者(Handler):定义处理请求的接口,通常包含一个指向下一个处理者的引用,用于将请求传递给下一个处理者。
- 具体处理者(ConcreteHandler):实现抽象处理者的接口,具体处理请求。如果当前处理者无法处理请求,则将请求传递给下一个处理者。
- 客户端(Client):创建处理者对象并组成责任链,然后将请求发送给责任链的第一个处理者。
下面是一个简单的责任链模式的代码示例,用 ArkTS 实现:
// 抽象处理者(责任链模式核心)
// 定义处理请求的接口,维护后继处理者的引用
abstract class Handler {protected nextHandler: Handler | null = null;// 设置责任链中的下一个处理者,支持链式调用public setNext(handler: Handler): Handler {this.nextHandler = handler;return handler;}// 抽象处理方法,需要子类具体实现public abstract handle(request: number): void;
}// 具体处理者A(处理0-10的请求)
class ConcreteHandlerA extends Handler {public handle(request: number): void {if (request < 10) { // 处理范围:小于10的请求console.log(`ConcreteHandlerA 处理请求: ${request}`);} else if (this.nextHandler) { // 传递给链中的下一个处理者this.nextHandler.handle(request);}}
}// 具体处理者B(处理10-20的请求)
class ConcreteHandlerB extends Handler {public handle(request: number): void {if (request >= 10 && request < 20) { // 处理范围:10到20(不含)的请求console.log(`ConcreteHandlerB 处理请求: ${request}`);} else if (this.nextHandler) { // 超出处理范围则传递请求this.nextHandler.handle(request);}}
}// 具体处理者C(处理20及以上的请求)
class ConcreteHandlerC extends Handler {public handle(request: number): void {if (request >= 20) { // 处理范围:20及以上的请求console.log(`ConcreteHandlerC 处理请求: ${request}`);} else if (this.nextHandler) { // 责任链末端处理this.nextHandler.handle(request);}}
}// 客户端代码(构建责任链并发送请求)
function clientCode() {// 创建具体处理者实例const handlerA = new ConcreteHandlerA();const handlerB = new ConcreteHandlerB();const handlerC = new ConcreteHandlerC();// 构建责任链:A -> B -> ChandlerA.setNext(handlerB).setNext(handlerC);// 测试不同范围的请求值const requests = [5, 15, 25];requests.forEach(request => {console.log(`客户端发送请求: ${request}`);handlerA.handle(request); // 从责任链头部开始处理});
}// 执行客户端测试代码
clientCode();
在这个示例中,Handler是抽象处理者,定义了handle方法和setNext方法。ConcreteHandlerA、ConcreteHandlerB和ConcreteHandlerC是具体处理者,分别处理不同范围的请求。客户端创建了这三个具体处理者,并将它们组成责任链,然后发送请求。请求会沿着责任链传递,直到找到能够处理它的处理者。
鸿蒙与 ArkTS 简介
鸿蒙系统(HarmonyOS)是华为公司自主研发的一款面向全场景的分布式操作系统 ,具备以下特点和优势:
- 分布式架构:这是鸿蒙系统的核心特性之一,通过分布式软总线、分布式数据管理、分布式任务调度等技术,实现了跨设备的无缝协同体验。例如,用户可以在手机、平板、智能手表、智慧屏等设备之间自由流转任务,就像使用一个设备一样方便。以华为的多屏协同功能为例,用户可以将手机屏幕投射到电脑上,在电脑上直接操作手机应用,实现文件的快速传输和共享,大大提高了工作效率。
- 强大的兼容性:鸿蒙系统采用了微内核设计,具有良好的扩展性和兼容性,能够适配各种不同类型的设备,包括智能家居、智能穿戴、车机等。这使得开发者可以基于鸿蒙系统开发出适用于多种设备的应用,为用户提供全场景的服务。
- 出色的性能表现:鸿蒙系统通过确定时延引擎和高性能的 IPC(进程间通信)机制,确保了系统的流畅性和响应速度。在资源调度方面,鸿蒙系统能够根据应用的需求进行精准分配,提高了资源利用率,降低了系统的能耗。
ArkTS(Ark TypeScript)是专为鸿蒙系统开发的一种编程语言,它基于 TypeScript,并针对鸿蒙系统的特性进行了优化和扩展。与其他语言相比,ArkTS 在鸿蒙开发中具有以下独特之处:
- 声明式 UI 开发:ArkTS 采用了声明式的 UI 编程模型,开发者可以通过简洁的代码描述界面的结构和样式,而不需要像传统命令式编程那样繁琐地操作 UI 组件。这种方式使得代码更加简洁、易读,同时也提高了开发效率。例如,使用 ArkTS 和 ArkUI 框架可以轻松创建一个包含按钮、文本框等组件的登录界面,代码量相比传统方式大大减少。
- 对鸿蒙特性的深度支持:ArkTS 提供了丰富的 API,方便开发者调用鸿蒙系统的分布式能力、硬件资源等。通过这些 API,开发者可以实现如分布式数据同步、设备发现与连接等功能,充分发挥鸿蒙系统的优势。例如,在开发一个智能家居应用时,利用 ArkTS 的分布式数据管理 API,可以实现不同设备之间的状态同步,用户在手机上控制智能灯泡的开关后,智能手表等其他设备上也能实时显示灯泡的状态。
- 静态类型检查:继承自 TypeScript,ArkTS 支持静态类型检查,这有助于在开发过程中提前发现类型错误,提高代码的稳定性和可维护性。在大型项目中,静态类型检查可以减少因类型错误导致的调试时间,使代码更加健壮。
ArkTS 实现责任链模式的具体步骤
定义抽象处理者
在 ArkTS 中,我们可以通过定义一个抽象类来表示抽象处理者。这个抽象类包含一个处理请求的抽象方法handle,以及一个设置下一个处理者的方法setNext。如下是代码示例:
abstract class Handler<T> { protected nextHandler: Handler<T> | null = null;public setNext(handler: Handler<T>): Handler<T> { this.nextHandler = handler;return handler;}public abstract handle(request: T): void;
}
在这段代码中,Handler类的handle方法是抽象的,需要由具体的处理者类来实现。nextHandler属性用于存储下一个处理者的引用,setNext方法则用于设置下一个处理者,并返回该处理者,以便于链式调用。
创建具体处理者
具体处理者类继承自抽象处理者类,并实现抽象方法handle。每个具体处理者根据自身的条件来判断是否能够处理请求,如果能处理则进行处理,否则将请求传递给下一个处理者。例如,我们创建三个具体处理者类ConcreteHandlerA、ConcreteHandlerB和ConcreteHandlerC:
class ConcreteHandlerA extends Handler<number> {public handle(request: number): void {if (request < 10) {console.log(`ConcreteHandlerA 处理请求: ${request}`);} else if (this.nextHandler) {this.nextHandler.handle(request);}}}class ConcreteHandlerB extends Handler<number> {public handle(request: number): void {if (request >= 10 && request < 20) {console.log(`ConcreteHandlerB 处理请求: ${request}`);} else if (this.nextHandler) {this.nextHandler.handle(request);}}}class ConcreteHandlerC extends Handler<number> {public handle(request: number): void {if (request >= 20) {console.log(`ConcreteHandlerC 处理请求: ${request}`);} else if (this.nextHandler) {this.nextHandler.handle(request);}}
}
在ConcreteHandlerA中,如果请求的数值小于 10,则由它自己处理;否则,将请求传递给下一个处理者。ConcreteHandlerB和ConcreteHandlerC也类似,分别处理不同范围的请求。
构建责任链
在客户端代码中,我们需要创建具体处理者对象,并将它们按照特定顺序连接起来,形成责任链。例如:
const handlerA = new ConcreteHandlerA();const handlerB = new ConcreteHandlerB();const handlerC = new ConcreteHandlerC();handlerA.setNext(handlerB).setNext(handlerC);
上述代码首先创建了ConcreteHandlerA、ConcreteHandlerB和ConcreteHandlerC的实例,然后通过setNext方法将它们连接起来,形成了一条责任链,其中handlerA是责任链的起始处理者。
提交请求
最后,我们向责任链的起始处理者提交请求,请求会在责任链中传递,直到被某个处理者处理。例如:
const requests = [5, 15, 25];requests.forEach(request => {console.log(`客户端发送请求: ${request}`);handlerA.handle(request);});
这段代码定义了一个请求数组requests,然后通过forEach方法遍历该数组,向handlerA提交每个请求。当handlerA接收到请求时,会根据请求的数值判断是否由自己处理,如果不能处理则传递给handlerB,以此类推,直到请求被处理。
案例实战:基于责任链模式的鸿蒙应用开发
应用场景描述
假设我们正在开发一个鸿蒙应用,其中包含文件上传功能。在文件上传之前,需要进行一系列的预处理操作,例如文件格式检查、文件大小限制检查、文件内容合法性检查等。不同的检查操作由不同的模块负责,我们可以使用责任链模式来组织这些检查操作,使得代码结构更加清晰,易于维护和扩展。
实现过程
- 定义抽象处理者:首先,我们定义一个抽象处理者类FileUploadHandler,它包含一个处理文件上传请求的抽象方法handleUpload和一个设置下一个处理者的方法setNext。
export interface FileInfo {name: string;size: number;content: string;
}abstract class FileUploadHandler {protected nextHandler: FileUploadHandler | null = null;public setNext(handler: FileUploadHandler): FileUploadHandler {this.nextHandler = handler;return handler;}public abstract handleUpload(file: FileInfo): void;
}
- 创建具体处理者:接下来,创建具体的处理者类,分别实现文件格式检查、文件大小限制检查和文件内容合法性检查。
class FileFormatHandler extends FileUploadHandler {public handleUpload(file: FileInfo): void {const allowedFormats = ['.jpg', '.png', '.pdf'];const fileExtension = file.name.split('.').pop() as string;if (allowedFormats.includes('.' + fileExtension)) {console.log(`文件格式 ${fileExtension} 合法`);if (this.nextHandler) {this.nextHandler.handleUpload(file);}} else {console.log(`文件格式 ${fileExtension} 不合法,上传终止`);}}
}class FileSizeHandler extends FileUploadHandler {private maxSize: number;constructor(maxSize: number) {super();this.maxSize = maxSize;}public handleUpload(file: FileInfo): void {if (file.size <= this.maxSize) {console.log(`文件大小 ${file.size} 符合限制`);if (this.nextHandler) {this.nextHandler.handleUpload(file);}} else {console.log(`文件大小 ${file.size} 超过限制 ${this.maxSize},上传终止`);}}
}class FileContentHandler extends FileUploadHandler {public handleUpload(file: FileInfo): void {// 模拟文件内容合法性检查,这里假设文件内容中不能包含敏感词“敏感信息”const fileReader = new FileReader();fileReader.onload = (e) => {const content = e.target?.result as string;if (!content.includes('敏感信息')) {console.log('文件内容合法');if (this.nextHandler) {this.nextHandler.handleUpload(file);}} else {console.log('文件内容包含敏感信息,上传终止');}};fileReader.readAsText(file);}
}
- 构建责任链:在客户端代码中,创建具体处理者对象,并将它们组成责任链。
const formatHandler = new FileFormatHandler();const sizeHandler = new FileSizeHandler(10 * 1024 * 1024); // 10MB限制const contentHandler = new FileContentHandler();formatHandler.setNext(sizeHandler).setNext(contentHandler);
- 提交请求:最后,创建一个文件对象,并向责任链的起始处理者提交文件上传请求。
class File {constructor(File:FileInfo) {}
}const sampleFile = new File({name: 'example.jpg',size: 8 * 1024 * 1024, // 8MBcontent: '这是一个示例文件,内容中包含敏感信息',
}) as FileInfo;formatHandler.handleUpload(sampleFile);
代码解析
- 抽象处理者FileUploadHandler:定义了处理文件上传请求的抽象方法handleUpload,以及设置下一个处理者的方法setNext。nextHandler属性用于存储下一个处理者的引用,通过setNext方法可以将处理者连接成一条链。
- 具体处理者FileFormatHandler:在handleUpload方法中,首先获取文件的扩展名,然后检查扩展名是否在允许的格式列表中。如果格式合法,则将请求传递给下一个处理者;否则,打印错误信息并终止上传。
- 具体处理者FileSizeHandler:在构造函数中接收一个最大文件大小的参数maxSize。在handleUpload方法中,比较文件的实际大小和最大限制大小,如果文件大小符合限制,则将请求传递给下一个处理者;否则,打印错误信息并终止上传。
- 具体处理者FileContentHandler:在handleUpload方法中,使用FileReader读取文件内容,并检查文件内容中是否包含敏感词。如果不包含敏感词,则将请求传递给下一个处理者;否则,打印错误信息并终止上传。
- 客户端代码:创建了FileFormatHandler、FileSizeHandler和FileContentHandler的实例,并通过setNext方法将它们连接成责任链。然后创建一个示例文件对象sampleFile,并将其传递给formatHandler的handleUpload方法,开始文件上传的预处理流程。
优势与应用场景拓展
在鸿蒙开发中使用责任链模式,有着诸多显著优势。从代码结构角度来看,责任链模式将请求的处理逻辑分散到多个处理者中,使得代码结构更加清晰、解耦。以文件上传预处理的案例来说,如果不使用责任链模式,所有的检查逻辑可能会集中在一个方法中,导致代码冗长且难以维护。而采用责任链模式后,每个检查操作都由独立的处理者负责,代码的可读性和可维护性大大提高。当需要新增或修改某个检查逻辑时,只需在对应的处理者类中进行操作,不会影响其他部分的代码。
从可扩展性方面分析,责任链模式具有很强的灵活性。当系统需求发生变化,需要添加新的处理环节时,只需要创建一个新的具体处理者类,并将其加入到责任链中即可,无需对原有代码进行大规模修改。例如,在文件上传案例中,如果后续需要增加一个文件版权检查的环节,只需要创建一个FileCopyrightHandler类,实现handleUpload方法,然后将其添加到责任链中,就可以轻松实现新的功能扩展。这种方式使得系统能够更好地适应不断变化的业务需求,降低了系统的维护成本。
在应用场景拓展方面,责任链模式在鸿蒙开发中还有很多潜在的应用场景。在事件处理机制中,鸿蒙系统中的各种用户事件(如点击事件、触摸事件等)可以通过责任链模式进行处理。不同的组件或模块可以作为处理者,根据自身的逻辑来决定是否处理该事件。例如,在一个复杂的界面中,可能存在多个嵌套的组件,当用户点击屏幕时,点击事件可以沿着组件层级组成的责任链进行传递,每个组件都有机会处理该事件。如果某个组件能够处理该事件,则事件处理结束;否则,事件继续传递给下一个组件,直到被处理为止。
在权限控制方面,责任链模式也能发挥重要作用。在鸿蒙应用中,不同的功能模块可能需要不同的权限才能访问。可以将权限检查的逻辑封装在不同的处理者中,形成一条责任链。当用户请求访问某个功能时,请求会沿着责任链传递,每个处理者检查用户是否具备相应的权限。如果用户权限不足,处理者可以拒绝请求并给出相应的提示;如果用户权限足够,则将请求传递给下一个处理者,直到请求被处理。这样可以实现灵活的权限管理,提高系统的安全性。
总结与展望
通过本文的介绍,我们深入了解了责任链模式在鸿蒙开发中的应用,从责任链模式的基本概念和原理,到使用 ArkTS 实现责任链模式的具体步骤,再到基于责任链模式的鸿蒙应用开发实战,以及该模式在鸿蒙开发中的优势和应用场景拓展。责任链模式为鸿蒙开发者提供了一种强大的工具,能够有效地解耦请求的发送者和接收者,提高代码的可维护性和可扩展性。
随着鸿蒙系统的不断发展和应用场景的日益丰富,责任链模式有望在更多的领域得到应用。在未来的鸿蒙开发中,我们可以进一步探索责任链模式与其他设计模式的结合使用,以实现更加复杂和高效的系统架构。同时,随着 ArkTS 语言的不断演进和完善,我们也可以期待责任链模式在 ArkTS 中的实现方式会更加简洁和优雅,为开发者带来更好的开发体验。希望本文能够对广大鸿蒙开发者有所帮助,激发大家在鸿蒙开发中积极应用责任链模式,创造出更加优秀的鸿蒙应用 。
相关文章:
鸿蒙开发新视角:用ArkTS解锁责任链模式
责任链模式:概念与原理 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它将多个处理者对象连接成一条链,并将请求沿着链传递,直到有一个处理者能够处理该请求。这种模式的核心思想是将…...
Linux的用户与权限--第二天
认知root用户(超级管理员) root用户用于最大的系统操作权限 普通用户的权限,一般在HOME目录内部不受限制 su与exit命令 su命令: su [-] 用户名 -符号是可选的,表示切换用户后加载环境变量 参数为用户名,…...
【Unity】搭建HTTP服务器并解决IP无法访问问题解决
一、核心目标与背景 在Unity中搭建本地HTTP服务器,可以用于实现Web与游戏交互、本地数据接口测试、跨设备通信等场景。但在实际部署中,开发者常遇到以下问题: 本机IP无法访问:服务绑定localhost时,局域网设备无法连…...
【C语言】结构体自动对齐问题 解析与解决方案
【C语言】结构体自动对齐问题 解析与解决方案 文章目录 【C语言】结构体自动对齐问题 解析与解决方案一、引言:问题背景二、结构体对齐机制详解2.1 对齐规则2.2 示例分析 三、实际案例与错误复现3.1 问题代码修正 四、 解决方案对比与实现4.1 禁用自动对齐ÿ…...
安卓开发相机功能
相机功能 安卓中的相机调用功能也经历了很多的方案升级,目前可选的官方方案是CameraX、Camera2、Camera(废弃),还有一些第三方免费或者是付费的相机库。对于大多数开发者,建议使用 CameraX。 CameraX CameraX 是 An…...
Zookeeper 及 基于ZooKeeper实现的分布式锁
1 ZooKeeper 1.1 ZooKeeper 介绍 ZooKeeper是一个开源的分布式协调服务,它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。 原语:操作系统或…...
Ubuntu20.04双系统安装及软件安装(五):VSCode
Ubuntu20.04双系统安装及软件安装(五):VSCode 打开VScode官网,点击中间左侧的deb文件下载: 系统会弹出下载框,确定即可。 在文件夹的**“下载”目录**,可看到下载的安装包,在该目录下…...
【计算机网络入门】初学计算机网络(十一)重要
目录 1. CIDR无分类编址 1.1 CIDR的子网划分 1.1.1 定长子网划分 1.1.2 变长子网划分 2. 路由聚合 2.1 最长前缀匹配原则 3. 网络地址转换NAT 3.1 端口号 3.2 IP地址不够用? 3.3 公网IP和内网IP 3.4 NAT作用 4. ARP协议 4.1 如何利用IP地址找到MAC地址…...
Android Flow操作符分类
Flow操作符分类...
经验分享:用一张表解决并发冲突!数据库事务锁的核心实现逻辑
背景 对于一些内部使用的管理系统来说,可能没有引入Redis,又想基于现有的基础设施处理并发问题,而数据库是每个应用都避不开的基础设施之一,因此分享个我曾经维护过的一个系统中,使用数据库表来实现事务锁的方式。 之…...
C#项目文件.csproj 文件结构解析
以下是对提供的 .csproj 文件内容的详细解析: 1. 项目根元素 <Project ToolsVersion"12.0" DefaultTargets"Build" xmlns"http://schemas.microsoft.com/developer/msbuild/2003"> ToolsVersion"12.0": 指定使…...
C++-第二十章:智能指针
目录 第一节:std::auto_ptr 第二节:std::unique_ptr 第三节:std::shared_ptr 第四节:std::shared_ptr的缺陷 4-1.循环引用 4-2.删除器 下期预告: 智能指针的作用是防止指针出作用域时忘记释放内存而造成内存泄漏&…...
chrome Vue.js devtools 提示不支持该扩展组件,移除
可能是版本不兼容,可以重新安装,推荐网址极简插件官网_Chrome插件下载_Chrome浏览器应用商店 直接搜索vue,下载旧版,vue2、vue3都支持,上面那个最新版本试了下,vue2的肯定是不能用...
C# 中的Action和Func是什么?Unity 中的UnityAction是什么? 他们有什么区别?
所属范围:Action 和 Func 是 C# 语言标准库中的委托类型,可在任何 C# 项目里使用;UnityAction 是 Unity 引擎专门定义的委托类型,只能在 Unity 项目中使用。 返回值:Action 和 UnityAction 封装的方法没有返回值&…...
【流行病学】Melodi-Presto因果关联工具
title: “[流行病学] Melodi Presto因果关联工具” date: 2022-12-08 lastmod: 2022-12-08 draft: false tags: [“流行病学”,“因果关联工具”] toc: true autoCollapseToc: true 阅读介绍 Melodi-Presto: A fast and agile tool to explore semantic triples derived from …...
Stream在Swift 和 Flutter上的对比
Swift 和 Flutter 都是跨平台开发框架,它们各自提供了强大的工具来处理数据流,尤其是在移动应用开发中。虽然 Swift 主要用于 iOS 开发,而 Flutter 主要用于移动应用的开发(包括 iOS 和 Android),但它们各自…...
Vue3 TransitionGroup组件深入解析:结合Element Plus实践指南
引言 在动态列表交互场景中,元素的增删排序需要优雅的过渡效果。Vue3的TransitionGroup组件为这类需求提供了专业解决方案。本文将通过Element Plus等流行UI库的实战案例,深入剖析TransitionGroup的应用技巧。 一、TransitionGroup核心特性 1.1 与Tran…...
关于opencv中solvepnp中UPNP与DLS与EPNP的参数
The methods SOLVEPNP_DLS and SOLVEPNP_UPNP cannot be used as the current implementations are unstable and sometimes give completely wrong results. If you pass one of these two flags, SOLVEPNP_EPNP method will be used instead.、 由于当前的实现不稳定&#x…...
Versal - XRT(CPP) 2024.1
目录 1.简介 2. XRT 2.1 XRT vs OpenCL 2.2 Takeways 2.3 XRT C APIs 2.4 Device and XCLBIN 2.5 Buffers 2.5.1 Buffer 创建 2.5.1.1 普通 Buffer 2.5.1.2 特殊 Buffer 2.5.1.3 用户指针 Buffer 2.5.2 Data Transfer 2.5.2.1 read/write API 2.5.2.2 map API 2…...
【零基础到精通Java合集】第十八集:多线程与并发编程-线程池与Callable/Future应用
课程标题:线程池与Callable/Future应用(15分钟) 目标:掌握线程池的创建与管理,理解Callable任务与Future异步结果处理机制 0-1分钟:课程引入与线程池意义 以“银行窗口服务”类比线程池:复用固定资源(柜员)处理多任务(客户)。说明线程池的核心价值——避免频繁创建…...
windows下安装Open Web UI
windows下安装openwebui有三种方式,docker,pythonnode.js,整合包. 这里我选择的是第二种,非docker. 非Docker方式安装 1. 安装Python: 下载并安装Python 3.11,建议安装路径中不要包含中文字符,并勾选“Add python 3.11 to Path”选项。 安…...
【自用】NLP算法面经(4)
一、deepseek 1、MLA (1)LLM推理过程 prefill阶段:模型对全部的prompt tokens一次性并行计算,最终生成第一个输出token。decode阶段:每次生成一个token,直到生成EOS(end-of-sequence…...
LeetCode热题100JS(20/100)第四天|41. 缺失的第一个正数|73. 矩阵置零|54. 螺旋矩阵|48. 旋转图像
41. 缺失的第一个正数 题目链接:41. 缺失的第一个正数 难度:困难 刷题状态:1刷 新知识: 解题过程 思考 示例 1: 输入:nums [1,2,0] 输出:3 解释:范围 [1,2] 中的数字都在数组中…...
【银河麒麟高级服务器操作系统实际案例分享】数据库资源重启现象分析及处理全过程
更多银河麒麟操作系统产品及技术讨论,欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer…...
开源架构与人工智能的融合:开启技术新纪元
最近五篇文章推荐: 开源架构的自动化测试策略优化版(New) 开源架构的容器化部署优化版(New) 开源架构的微服务架构实践优化版(New) 开源架构中的数据库选择优化版(New) 开…...
缓存那些事儿
为什么要使用缓存 性能 我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。 并发 在大并发的情况下,所有的请求直接访问数…...
【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景
《弹性裸金属服务器》系列,共包含以下文章: 弹性裸金属服务器和神龙虚拟化(一):功能特点弹性裸金属服务器和神龙虚拟化(二):适用场景弹性裸金属服务器和神龙虚拟化(三&a…...
通往 AI 之路:Python 机器学习入门-语法基础
第一章 Python 语法基础 Python 是一种简单易学的编程语言,广泛用于数据分析、机器学习和人工智能领域。在学习机器学习之前,我们需要先掌握 Python 的基本语法。本章将介绍 Python 的变量与数据类型、条件语句、循环、函数以及文件操作,帮助…...
FastGPT 引申:信息抽取到知识图谱的衔接流程
文章目录 信息抽取到知识图谱的衔接流程步骤1:原始信息抽取结果步骤2:数据标准化处理(Python示例)步骤3:Cypher代码动态生成(Python驱动) 关键衔接逻辑说明1. 唯一标识符生成规则2. 数据映射策略…...
计算机毕业设计SpringBoot+Vue.js保险合同管理系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
