高效利用资源:分布式有状态服务的高可靠性设计
在分布式系统设计中,实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时,备服务接管任务,例如通过Keepalive实现VIP的切换以保证可用性。然而,这种方式存在资源浪费的问题,因为备服务始终处于空转状态,未能充分利用系统资源。
程序的本质与分解
程序本质上由函数、对象(在面向对象语言中)和数据组合而成,通过特定的逻辑完成特定的业务目标。为了提升有状态服务的高可靠性和高可用性,我们可以从数据、函数和对象三个方面对程序进行分解:
- 数据持久化:在主备切换时,确保程序中的数据不丢失。通过数据持久化,可以在备服务接管后,基于持久化的数据重新运算,恢复服务状态。
- 纯函数设计:如果函数在相同条件下对相同输入总是产生相同输出,并且只完成其固有功能,具备单一职责,这类函数被称为纯函数。设计成纯函数后,可以基于持久化的数据进行重新计算,增强系统的可恢复性。
- 无状态对象:对象由数据和方法组成。如果对象的方法输出仅依赖于自身的状态,而不依赖外部状态,则该对象为无状态对象。无状态对象可以通过数据持久化进行重建,提升系统的灵活性和可扩展性。
横向扩展有状态服务的方法
为了实现有状态服务的横向扩展,并充分利用所有硬件资源,我们需要针对不同情况采用不同的方案。本文以Redis作为数据持久化方案为例,阐述如何实现有状态服务的横向扩展。
- 有状态对象:通过分布式锁确保同一时间仅有一个实例运行,保证控制逻辑的一致性。
- 纯函数/无状态对象:通过分布式任务调度器将任务分发到多个节点并行运行。
1. 管理有状态对象
如果程序中的对象为有状态对象,即对象的行为不仅依赖自身状态,还依赖外部状态。为了保证状态的一致性与正确性,此类对象只能在一个服务实例中运行。可以通过Redis构建分布式锁来实现这一点。当多个实例同时运行时,只有一个实例能够获取分布式锁并执行计算任务。
Redisson 示例:
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class DistributedLockExample {public static void main(String[] args) {Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);RLock lock = redisson.getLock("myLock");lock.lock();try {// 执行业务逻辑System.out.println("Lock acquired, executing business logic.");} finally {lock.unlock();redisson.shutdown();}}
}
2. 处理纯函数与无状态对象
如果函数是纯函数或对象是无状态的,这意味着函数的执行无副作用,可以在多个实例上并行运行。在这种情况下,尽管多个实例同时处理请求,但由于函数和对象的无状态特性,可以确保结果的正确性。
然而,纯函数和无状态对象的并行计算无法实现运算负载的均衡。为此,可以通过Redisson Executor Service构建分布式执行引擎,将函数和对象分布到不同的节点上计算,以充分利用系统资源。
Redisson 分布式执行引擎示例:
Redisson Executor Service 分布式执行引擎示例:
import org.redisson.Redisson;
import org.redisson.api.RExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ExecutorOptions;
import org.redisson.api.executor.TaskSuccessListener;
import org.redisson.api.executor.TaskFailureListener;import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;public class DistributedExecutionExample {public static void main(String[] args) throws Exception {// 配置Redisson客户端Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);// 定义ExecutorOptionsExecutorOptions options = ExecutorOptions.defaults().taskRetryInterval(10, TimeUnit.MINUTES);// 获取RExecutorService实例RExecutorService executorService = redisson.getExecutorService("myExecutor", options);// 提交Runnable任务executorService.submit(new RunnableTask(123));// 提交Callable任务并获取结果Future<Long> future = executorService.submit(new CallableTask());Long result = future.get();System.out.println("Callable任务结果: " + result);// 提交Lambda任务Future<Long> lambdaFuture = executorService.submit((Callable<Long> & Serializable) () -> {System.out.println("Lambda任务已执行!");return 100L;});Long lambdaResult = lambdaFuture.get();System.out.println("Lambda任务结果: " + lambdaResult);redisson.shutdown();}// 定义Callable任务public static class CallableTask implements Callable<Long>, Serializable {private static final long serialVersionUID = 1L;@org.redisson.api.annotation.RInjectprivate transient RedissonClient redissonClient;@org.redisson.api.annotation.RInjectprivate transient String taskId;@Overridepublic Long call() throws Exception {RMap<String, Integer> map = redissonClient.getMap("myMap");Long result = 0L;for (Integer value : map.values()) {result += value;}return result;}}// 定义Runnable任务public static class RunnableTask implements Runnable, Serializable {private static final long serialVersionUID = 1L;@org.redisson.api.annotation.RInjectprivate transient RedissonClient redissonClient;@org.redisson.api.annotation.RInjectprivate transient String taskId;private long param;public RunnableTask() {}public RunnableTask(long param) {this.param = param;}@Overridepublic void run() {RAtomicLong atomic = redissonClient.getAtomicLong("myAtomic");atomic.addAndGet(param);System.out.println("Runnable任务已执行,参数:" + param);}}
}
Worker 注册示例:
import org.redisson.Redisson;
import org.redisson.api.RExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.api.executor.WorkerOptions;public class WorkerRegistrationExample {public static void main(String[] args) {// 配置Redisson客户端Config config = new Config();config.useSingleServer().setAddress("redis://localhost:6379");RedissonClient redisson = Redisson.create(config);// 定义WorkerOptionsWorkerOptions options = WorkerOptions.defaults().setWorkers(2) // 定义使用的Worker数量.setTaskTimeout(60, TimeUnit.SECONDS) // 设置任务超时时间.addListener(new TaskSuccessListener<Long>() {@Overridepublic void onSucceeded(String taskId, Long result) {System.out.println("任务 " + taskId + " 成功完成,结果: " + result);}}).addListener(new TaskFailureListener() {@Overridepublic void onFailed(String taskId, Throwable exception) {System.out.println("任务 " + taskId + " 失败,异常: " + exception.getMessage());}});// 获取RExecutorService实例并注册WorkersRExecutorService executor = redisson.getExecutorService("myExecutor");executor.registerWorkers(options);// Redisson节点无需包含任务类,任务类由Redisson节点的ClassLoader自动加载redisson.shutdown();}
}
性能与限制
Redisson Executor Service 的性能表现
Redisson Executor Service 通过利用 Redis 作为任务队列,实现了分布式任务的调度与执行。这种架构在以下场景下表现出色:
-
高并发任务处理:
- 优势:Redis 的高吞吐量使得 Redisson Executor Service 能够快速地提交和分发任务,适用于大量短时间内需要处理的任务。
- 优化建议:确保 Redis 服务器具备足够的资源(如内存和网络带宽),以应对高并发需求。使用 Redis 集群来分担负载,提升系统的整体吞吐量。
-
延迟敏感型任务:
- 优势:由于任务调度和执行的低延迟特性,适用于需要快速响应的应用场景,如实时数据处理和即时反馈系统。
- 优化建议:优化网络延迟,部署 Redis 服务器尽量靠近应用服务器。同时,合理配置 Redisson 的线程池,确保任务能够及时被处理。
-
长时间运行的任务:
- 限制:Redisson Executor Service 更适用于短时间内完成的任务。对于长时间运行的任务,可能会占用大量资源,导致其他任务的延迟增加。
- 优化建议:将长时间运行的任务拆分为多个子任务,通过批处理或工作流管理来处理。同时,监控任务的执行时间,设置合理的任务超时时间(
taskTimeout
),避免资源被单个任务长时间占用。
-
任务依赖与复杂流程:
- 限制:Redisson Executor Service 主要适用于独立的任务执行,对于有复杂依赖关系的任务流程管理能力有限。
- 优化建议:结合其他工作流引擎(如 Apache Airflow 或 Spring Batch)来管理复杂的任务依赖关系,同时使用 Redisson Executor Service 处理独立的子任务。
潜在限制
-
单点瓶颈:
- 问题:虽然 Redis 本身支持高性能,但在极端高负载情况下,单个 Redis 节点可能成为性能瓶颈。
- 解决方案:采用 Redis 集群架构,将数据和任务负载分散到多个 Redis 节点,以提升整体性能和可用性。
-
任务持久性与可靠性:
- 问题:如果 Redis 实例发生故障,尚未处理的任务可能会丢失,影响系统的可靠性。
- 解决方案:启用 Redis 持久化(RDB 或 AOF),并配置 Redis 主从复制,确保数据在节点故障时可以快速恢复。此外,结合 Redisson 的任务重试机制,确保任务不因临时故障而丢失。
-
网络依赖性:
- 问题:Redisson Executor Service 依赖于网络连接 Redis,如果网络不稳定,可能导致任务提交失败或执行延迟。
- 解决方案:部署 Redis 服务器和应用服务器在同一数据中心或局域网内,减少网络延迟和抖动。使用高可用的网络架构,确保网络的稳定性和可靠性。
-
任务序列化开销:
- 问题:任务和结果对象需要序列化和反序列化,可能带来性能开销,特别是在任务数据量较大时。
- 解决方案:优化任务对象的序列化方式,选择高效的序列化协议(如 Kryo 或 Protostuff),减少序列化和反序列化的时间开销。
容错与可靠性
故障恢复机制
-
任务重试机制:
- 实现方式:Redisson Executor Service 支持任务的自动重试,当任务执行失败或超时后,可以根据配置的重试间隔(
taskRetryInterval
)自动重新提交任务。 - 优化建议:根据任务的重要性和执行环境,合理配置重试次数和间隔时间,避免过度重试导致系统负载过高。同时,结合幂等性设计,确保任务在多次重试后仍能保证数据一致性。
- 实现方式:Redisson Executor Service 支持任务的自动重试,当任务执行失败或超时后,可以根据配置的重试间隔(
-
任务确认机制:
- 实现方式:通过任务监听器(如
TaskSuccessListener
和TaskFailureListener
),可以实时监控任务的执行状态,及时处理执行成功或失败的任务。 - 优化建议:在任务失败时,结合监控系统(如 Prometheus 和 Grafana)触发告警,快速响应并修复潜在问题。同时,可以根据失败原因,动态调整任务的执行策略。
- 实现方式:通过任务监听器(如
-
数据备份与持久化:
- 实现方式:启用 Redis 的持久化机制(RDB 或 AOF),确保任务队列的数据在 Redis 意外重启或宕机时能够快速恢复。
- 优化建议:结合 Redis 集群和主从复制,部署多副本以提升数据的持久性和可用性。同时,定期备份 Redis 数据,防止数据丢失。
容错机制
-
高可用 Redis 部署:
- 实现方式:通过 Redis Sentinel 或 Redis 集群,实现 Redis 的自动故障转移和主从切换,确保 Redis 服务的高可用性。
- 优化建议:合理配置 Sentinel 或 Redis 集群,设置合适的故障检测和自动恢复策略,确保在 Redis 节点故障时能够迅速切换到健康节点,最小化服务中断时间。
-
分布式锁的健壮性:
- 实现方式:在管理有状态对象时,使用 Redisson 提供的分布式锁机制,确保在多个实例中只有一个实例能够持有锁并执行任务。
- 优化建议:合理设置锁的自动释放时间,防止因实例故障导致锁无法释放。同时,结合锁续租机制,确保在长时间任务执行时锁不会意外过期。
-
冗余服务实例:
- 实现方式:部署多个服务实例,并通过负载均衡器(如 Nginx 或 HAProxy)进行流量分配,避免单点故障导致服务不可用。
- 优化建议:结合自动伸缩(Auto Scaling)策略,根据系统负载动态调整服务实例的数量,确保在高负载时仍能保持高可用性。同时,定期健康检查服务实例,及时处理故障实例。
-
监控与报警:
- 实现方式:部署全面的监控系统,实时监控 Redis 和 Redisson Executor Service 的性能指标(如任务队列长度、任务执行时间、错误率等),并配置告警机制。
- 优化建议:使用 Prometheus 收集指标数据,并通过 Grafana 可视化展示。同时,设置多渠道告警(如邮件、短信、钉钉等),确保在出现异常时能够快速响应和处理。
灾难恢复策略
-
跨数据中心冗余:
- 实现方式:将 Redis 集群部署在多个数据中心,确保在某个数据中心发生灾难性故障时,其他数据中心能够继续提供服务。
- 优化建议:配置异地复制(如 Redis 的跨集群复制),确保数据在不同数据中心同步更新。同时,定期进行跨数据中心的故障演练,确保灾难恢复方案的有效性。
-
备份与恢复测试:
- 实现方式:定期备份 Redis 数据,并在需要时进行恢复测试,确保备份数据的完整性和可用性。
- 优化建议:采用增量备份和全量备份相结合的策略,减少备份时间和存储空间。同时,自动化恢复流程,确保在需要恢复时能够快速执行,最小化系统的停机时间。
通过以上的性能优化和容错机制设计,可以大幅提升 Redisson Executor Service 在分布式有状态服务中的表现和可靠性,确保系统在各种场景下都能稳定、高效地运行。
结论
为了避免传统主备切换中的资源浪费,可以将有状态服务拆分为数据、纯函数和对象,通过数据持久化和分布式计算实现高效扩展。利用 Redis 提供分布式锁和持久化支持,并借助 Redisson 实现分布式任务调度和并行计算,有状态的任务通过加锁在单实例上运行,无状态的任务则在多个实例间并行分发。此策略不仅提升了资源利用率,还增强了系统的可靠性和可扩展性。
相关文章:
高效利用资源:分布式有状态服务的高可靠性设计
在分布式系统设计中,实现有状态服务的高可靠性通常采用主备切换的方式。当主服务停止工作时,备服务接管任务,例如通过Keepalive实现VIP的切换以保证可用性。然而,这种方式存在资源浪费的问题,因为备服务始终处于空转状…...
aws(学习笔记第十六课) 使用负载均衡器(ELB)解耦webserver以及输出ELB的日志到S3
aws(学习笔记第十六课) 使用负载均衡器(ELB)以及输出ELB的日志到S3 学习内容: 使用负载均衡器(ELB)解耦web server输出ELB的日志到S3 1. 使用负载均衡器(ELB) 全体架构 使用ELB(Elastic Load Balancer)能够解耦外部internet访问和web server之间的耦合,…...
关于php://filter过滤器
常规的php://filter过滤器: <?php //index.php include($_REQUEST[file]); ?> <?php //flag.php $flagflag{test_flag}; ?> 同过base64读取flag.php的类容: 常用payload: (这是最常用的payload) ph…...
数据安全法-政务数据安全与开放
第五章 政务数据安全与开放 第三十七条 国家大力推进电子政务建设,提高政务数据的科学性、准确性、时效性,提升运用数据服务经济社会发展的能力。 第三十八条 国家机关为履行法定职责的需要收集、使用数据,应当在其履行法定职责的范围内依…...
MySQL数据库的数据类型
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 MySQL数据库的数据类型 收录于专栏[MySQL] 本专栏旨在分享学习MySQL的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 数据类型分类 …...
前端H5移动端基础框架模板 :Vue3 + Vite5 + Pinia + Vant4 + Sass + 附源码
技术栈选用 Vue3 Vite5 Pinia Vant4 Sass 源码地址: git clone https://gitee.com/gaiya001/h5-APP.git1. 1.vite.config.js文件配置 ** import { defineConfig } from vite // 导入 Vite 的配置函数 import vue from vitejs/plugin-vue // 导入 Vue 插件 i…...
什么是线程安全
🌈🌈🌈今天给大家分享的是:什么是线程安全 目录 线程安全的定义 线程安全的级别 (1)不可变 (2)绝对线程安全 (3)相对线程安全 (4)线程非安全…...
️️️ 避坑指南:如何修复国密gmssl 库填充问题并提炼优秀加密实践20241212
🛡️ 避坑指南:如何修复国密gmssl 库填充问题并提炼优秀加密实践 ✨ 引言 在当下的数据安全环境中,SM4作为中国国家密码算法的代表性选择,被广泛应用于金融、通信和政府领域。然而,在实际开发中,即便是开…...
深度学习实验十四 循环神经网络(1)——测试简单循环网络的记忆能力和梯度爆炸实验
目录 一、数据集构建 1.1数据集的构建函数 1.2加载数据集并划分 1.3 构建Dataset类 二、模型构建 2.1嵌入层 2.2SRN层 2.3模型汇总 三、模型训练 3.1 训练指定长度的数字预测模型 3.2 损失曲线展示 四、模型评价 五、修改 附完整可运行代码 实验大体步骤&#x…...
AWS re:Invent 发布新的数据库产品 Aurora DSQL; NineData SQL编程大赛开始; 腾讯云支持PostgreSQL 17
重要更新 1. AWS re:Invent 发布新的数据库产品 Aurora DSQL ,提供了跨区域、强一致、多区域读写的能力,同时具备99.999%(多区域部署)的可用性,兼容PostgreSQL;同时发布的还有 DynamoDB 也提供类似的跨区域…...
STM32 OLED屏幕驱动详解
一、介绍 OLED是有机发光二极管,又称为有机电激光显示(Organic Electroluminescence Display, OLED)。OLED由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广…...
Python字符串常用操作
Python字符串常用操作 一、字符串的切片 1.1、通过下标及下标范围取值 my_str myNameIsTaichi value1 my_str[2] # 正向 N value2 my_str[-5] # 反向 从 -1 开始 a字符串分割,语法:string[end: step] start:头下标,以0开…...
Redis 生产问题(重要)
缓存穿透 什么是缓存穿透? 缓存穿透说简单点就是大量请求的 key 是不合理的,根本不存在于缓存中,也不存在于数据库中 。这就导致这些请求直接到了数据库上,根本没有经过缓存这一层,对数据库造成了巨大的压力…...
前端 —— Git
Git安装 下载安装包 【免费】前端前置-Git安装包资源-CSDN文库 安装 ‘git‘不是内部或外部命令及Git 的保姆级安装教程(保姆级教程)_git不是内部或外部命令-CSDN博客 vscode添加gitbash终端 setting.json "terminal.integrated.profiles.win…...
【GL006】Linux 之 shell
目录 一、shell 指令 1.1 体验shell指令 1.2 命令格式 1.3 shell中的通配符 1.4 输入输出重定向 1.5 命令置换 1.6 基本系统维护命令 1.7 Linux的进程管理命令 1.8 文件系统相关命令 1.9 Linux网络配置管理 二、shell 编程 2.1 shell 脚本的基础知识 2.2 shell 变…...
JS听到了强运的回响
正则表达式 介绍 正则表达式是用于匹配字符串中字符组合的模式,在JS中,正则表达式也是对象 通常用来查找,替换那些符合正则表达式的文本 就是筛选出符合条件的一类人 比如说 有人喜欢玩艾斯爱慕,那他喜欢的就是这一类人&…...
Linux下MySQL的简单使用
Linux下MySQL的简单使用 导语MySQL安装与配置 MySQL安装密码设置 MySQL管理 命令 myisamchkmysql其他 常见操作 C语言访问MYSQL 连接例程错误处理使用SQL 总结参考文献 导语 这一章是MySQL的使用,一些常用的MySQL语句属于本科阶段内容,然后是C语言和M…...
.net core使用AutoMapper
AutoMapper 是一个用于 .NET 平台的对象映射工具,它简化了不同对象类型之间的转换过程。在软件开发中,尤其是在分层架构的应用程序里,常常需要在不同的对象模型之间进行数据传递,例如从数据库实体到视图模型、DTO(数据…...
nmap详解
Nmap(Network Mapper)是一个开放源代码的网络探测和安全审核的工具。由于它的功能强大,被广泛应用于网络安全领域。以下是Nmap的一些主要功能及其在实战中的应用举例。 Nmap的主要功能: 端口扫描:检测目标主机上开放…...
CentOS7环境安装php
直接安装 yum -y install php CentOS7默认安装是php5,现在php已有8.3版本 先查看php -v 版本 如果是低版本,可以删除 yum remove php yum remove php-fpm yum remove php-common 一、添加REMI存储库 yum install epel-release yum install -y …...
基于深度学习的猫狗识别系统【深度学习课设】
🏆 作者简介:席万里 ⚡ 个人网站:https://dahua.bloggo.chat/ ✍️ 一名后端开发小趴菜,同时略懂Vue与React前端技术,也了解一点微信小程序开发。 🍻 对计算机充满兴趣,愿意并且希望学习更多的技…...
字体子集化实践探索
最近项目rust生成PDF组件printpdf需要内嵌完整字体导致生成的PDF很大,需要做压缩,但是rust的类库allsorts::subset::subset不支持windows,所以做了一些windows下字体子集化的尝试 方案一:node.js做子集化 fontmin 缺点是也需要集…...
A1017 基于Java+JSP+SQL Server+servlet的二手购物平台的设计与实现
二手购物平台 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 计算机以及网络技术的飞速发展,网络的应用在全国乃至全球日益普及,随着人们的思想水平和生活水平的提高,网络已经是人们必不可少的一部分。人们的…...
Simdroid-EC:液冷仿真新星,助力新能源汽车电机控制器高效散热
近年来,新能源电动车的销量呈现出快速增长的态势。据统计,2024 年1-10月中国新能源汽车销量达728万辆,同比增长37.8%。 电机控制器在新能源汽车中对于保障动力和安全性能扮演着至关重要的角色,其核心部件IGBT(绝缘栅双…...
C语言——实现并求出两个数的最大公约数
问题描述:求出两个数的最大公约数 //求两个数的最大公约数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<time.h>int main() {int a,b;printf("请您输入两个数 a 和 b\n");scanf…...
今天你学C++了吗?——C++中的类与对象(日期类的实现)——实践与知识的碰撞❤
♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…...
享元模式的理解和实践
在软件开发中,性能优化是一个永恒的话题。在追求高性能的过程中,减少内存的使用是一项重要的任务。享元模式(Flyweight Pattern)就是一种用于减少内存使用量的设计模式,它特别适用于存在大量重复对象的场景。本文将详细…...
Unreal Engine 中的UI界面开发
推荐的使用方式 轻量级 HUD:使用 Canvas 绘制简单的文本、调试信息或基础 UI(如准星、血量条等)。 复杂 UI:使用 UMG(Unreal Motion Graphics)和 Slate 进行布局和交互,避免手动管理 Canvas 绘制。 避免遮挡场景:仅绘制必要的内容,并利用透明度(如 FLinearColor(1, 1…...
Docker在Ubuntu和CentOS系统下的安装
目录 1. 各版本平台支持情况2. 在Ubuntu系统下安装docker3. 常见报错4. Docker的镜像源修改5. Docker目录修改6. 在CentOS系统下安装docker 1. 各版本平台支持情况 (1)平台支持情况如下: Server 版本 桌面版本 2. 在Ubuntu系统下安装docker…...
EXCEL 关于plot 折线图--频度折线图的一些细节
目录 0 折线图有很多 1 频度折线图 1.1 直接用原始数据做的频度折线图 2 将原始数据生成数据透视表 3 这样可以做出了,频度plot 4 做按某字段汇总,成为累计plot分布 5 修改上面显示效果,做成百分比累计plot频度分布 0 折线图有很多 这…...
如何为wordpress添加音乐播放器/大连网络推广
上周听了tt大神作分享,获益良多。之前一直不知道Windows的域是怎么回事,有点被点拨开悟了一些。趁现在还有记忆,把当时的记录回忆一下。活动目录,即Active Directory,是Windows服务器环境的一个核心服务,对…...
网站整合营销/西安seo排名公司
Description 给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。 0:后接两个整数(x&…...
手机网站建设哪/快速排序优化
平衡二叉树 题目描述: 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。题目链接 /*** Definition for a binary tree node.* p…...
青岛建设管理局网站/美容美发培训职业学校
从回答中选出你认为正确的答案:1. 以下哪些陈述是正确的?a. 在对MySQL Server设置SQL模式后,它会对所有连接到此服务的客户端起作用。b. 如果你需要设置两个SQL模式(如,STRICT_ALL_TABLES和ERROR_FOR_DIVISION_BY_ZERO模式)&#…...
sketch做网站/网络优化工程师工作内容
2019独角兽企业重金招聘Python工程师标准>>> 前言~ 今天莫名的接到一个任务,需要使用oracle定时任务和oracle存储过程来每日创建一个日志表,由于小编呢尚未接触过存储过程和定时任务,所以今天学习了一番,特定来总结一下…...
高端手机网站定制/中小企业网络推广
#include<stdio.h> #include<math.h> #include<string.h> //其他任意进制转换为十进制 int main() { int trans(char a[],int ); char strupr(char ); char arr[100]; int t; printf("请输入进制的类型:"); scanf("%d",&t); printf(…...