运维 系统转换系统维护系统评价练习题 系统转换 新老系统的转换
系统转换是指:新系统开发完毕,投入运行,取代现有系统的过程,需要考虑多方面的问题,以实现与老系统的交接,有一下三种转换计划:
直接转换:就是在确定新系统运行无误时立刻启用新系统,终止旧系统运行,风险很大。这种方式很节省人员、设备费用。一般适用于一些处理过程不太复杂、数据不太重要的场合。并行转换:是新旧系统并行工作一段时间,经过一段时间的考验以后,新系统正式替代旧系统,风险较小。它的主要特点是安全、可靠,但费用和工作量都很大,因为在相当长的时间内系统要新、旧两套并行工作。对于较复杂的大型系统,它提供了一个与旧系统运行结果进行比较的机会,可以对新旧两个系统的时间要求、出错次数和工作效率给予公正的评价。当然,由于与旧系统并行工作,消除了尚未认识新系统之前的紧张和不安。分段转换:分期分批逐步转换,是直接和并行转换的集合,将大型系统分为多个子系统,依次试运行每个字系统,成熟一个子系统就转换一个子系统。同样适用于大型项目,只是更耗时,而且现有系统和新系统间混合使用,需要协调
好接口等问题。数据转换与迁移:将数据从日数据库迁移到新数据库中。有三种方法:系统切换前通过工具迁移、系统切换前采用手工录入、系统切换后通过新系统生成。 系统维护 系统的可维护性可以定义为维护人员理解、改正、改动和改进这个软件的难易程度,可维护性是所有软件都应具有的基本特点,必须在开发阶段和其他软件工程阶段保证软件具有可维护的特点。其评价指标如下:
可理解性。指别人能理解系统的结构、界面、功能和内部过程的难易程度。模块化、详细设计文档、结构化设计和良好的高级程序设计语言等都有助于提高可理解性。可测试性。诊断和测试的容易程度取决于易理解的程度。为此,开发人员在系统设计和编程阶段就应尽力把程序设计成易诊断和测试的。此外,在进行系统维护时,应该充分利用在系统测试阶段保存下来的测试用例。可修改性。诊断和测试的容易程度与系统设计所制定的设计原则有直接关系。模块的耦合、内聚、作用范围与控制范围的关系等都对可修改性有影响。 系统维护主要包括硬件维护、软件维护和数据维护。
软件维护:软件维护主要是指根据需求变化或硬件环境的变化对应用程序进行部分或全部修改,其包含内容如下:
正确性维护:是指改正在系统开发阶段已发生而系统测试阶段尚未发现的错误。适应性维护:是指使应用软件适应信息技术变化和管理需求变化而进行的修改。完善性维护:是指对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征。预防性维护:为了改进应用软件的可靠性和可维护性,为了适应未来的软/硬件环境的变化,应主动增加预防性的新的功能,以使应用系统适应各类变化而不被淘汰。 系统评价 按评价的时间与信息系统所处的阶段的关系又可从总体上把广义的信息系统评价分成立项评价、中期评价和结项评价。 立项评价:指信息系统方案在系统开发前的预评价,即系统规划阶段中的可行性研究。中期评价:项目开发中期每个阶段的阶段评审,或者项目在开发中途遇到重大变故,评价是否还要继续。结项评价:系统投入正式运行后,了解系统是否达到预期的目的和要求而对系统进行的综合评价。 系统评价的指标 从信息系统的组成部分出发,信息系统是一个由人机共同组成的系统,所以可以**按照运行效果和用户需求(人)、系统质量和技术条件(机)**这两条线案构造指标。从信息系统的评价对象出发,对于开发方来说,他们所关心的是系统质量和技术水平;对于用户方而言,关心的是用户需求和运行质量;系统外部环境则主要通过社会效益指标来反映。从经济学角度出发,分别按系统成本、系统效益和财务指标3条线索建立指标。 练习题 系统可维护性是指维护人员理解、改正、改动和改进软件系统的难易程度,其评价指标不包括()。
A.可理解性
B.可测试性
C.可修改性
D.一致性
答案:D
软件交付给用户之后进入维护阶段,根据维护具体内容的不同将维护分为不同的类型,其中“采用专用的程序模块对文件或数据中的记录进行增加、修改和删除等操作”的维护属于()。
A.程序维护
B.数据维护
C.代码维护
D,设备维护
答案:B
目录
一、今日目标
二、🎈SpringBoot部分类的添加
2.1 使用逆向工程新增User模块
2.2 UserQueryParam添加
2.3 UserSaveParam添加
2.4 UserResetPasswordParam添加
2.5 UserQueryVo添加
2.6 SnowFlake工具类
三、🚆后端新增接口 3.1 /user/list接口添加
3.2 /user/save接口添加
3.3 /user/delete接口添加
3.4 /user/reset-password接口添加
一、今日目标 上一篇文章我把前端部分的代码给大家了,这篇文章就来实现上一篇文章没有完成的接口。
二、🎈SpringBoot部分类的添加 2.1 使用逆向工程新增User模块 这一块的代码和之前的相同,我们找到逆向工程的工具类后,把类的部分改为user即可。
2.2 UserQueryParam添加 这个类看名字也知道是用来用户查询的,要继承之前的分页类。
@Data public class UserQueryParam extends PageParam { private String loginName; } 2.3 UserSaveParam添加 这个类是用来作为用户新增参数接收用的。这个类作为用户信息保存的参数类,在这个类中对于属性的值做了一些限制。用户名、昵称和密码不能为空,同时密码要匹配正则表达式,这个正则表达式限制了密码由数字和字母组成,并且长度在6-32位,如果上边有条件不满足,那么就会抛出message中的错误。
@Data public class UserSaveParam { private Long id; @NotNull(message = "【用户名】不能为空") private String loginName; @NotNull(message = "【昵称】不能为空") private String name; @NotNull(message = "
制作一款DIY的‘植物大战僵尸’游戏引起了很多人的兴趣。在这里,我将分享一个使用Python语言在PyCharm环境中开发的初始状态版本。这个版本主要应用了pygame库来完成,是一个充满创意和趣味的魔改版本。
文章目录 前言一、开发环境准备二、代码1.main方法2.敌人角色(示例)2.我方角色(示例) 总结 前言 近期,《植物大战僵尸杂交版》的热度确实高涨,这主要得益于其独特的创意、对经典游戏的致敬与创新,以及玩家社区的积极反馈与传播。《植物大战僵尸杂交版》由B站UP主“潜艇伟伟迷”开发制作,游戏中引入了杂交植物的概念,如豌豆向日葵、火焰花女王等,这些杂交植物结合了多种植物的特性,拥有独特的攻击方式和能力,极大地丰富了游戏的策略性和可玩性。除了杂交植物外,游戏中还加入了多种新奇的僵尸类型,如武装舞王僵尸、冰车巨人等,以及全新的地图设计,为玩家带来更加刺激和挑战性的游戏体验。游戏不仅保留了原版的经典模式,还增加了抽奖盒子无尽模式等Roguelike玩法,以及多种有趣的小游戏和挑战模式,让玩家在重复游玩中也能保持新鲜感。
制作一款DIY的‘植物大战僵尸’游戏引起了很多人的兴趣。在这里,我将分享一个使用Python语言在PyCharm环境中开发的初始状态版本。这个版本主要应用了pygame库来完成,是一个充满创意和趣味的魔改版本。
在这篇博文我将源代码以及运行程序压缩包: 运行程序
(解压后可直接运行)一并分享出来,并给出源码链接: 源码供免费下载。
里面的所有角色图片来自网络资源都来自于网络资源,由本人一张一张裁剪制作而成,制作不易,希望喜欢并使用的小伙伴可以为我点一个star。
提示:以下是本篇文章正文内容,下面案例可供参考
一、开发环境准备 实现上述描述的DIY“植物大战僵尸”游戏,你需要准备以下代码环境:
1.Python语言:
确保你的计算机上安装了Python。可以从Python的官方网站下载并安装最新版本的Python。
2.PyCharm IDE:
PyCharm是一个流行的Python集成开发环境(IDE),它提供了代码编辑、调试、测试等功能。你可以从JetBrains的官方网站下载并安装PyCharm。
3.pygame库:
pygame是一个用于创建游戏的Python库,它提供了图形、声音、事件处理等游戏开发所需的功能。你可以使用pip命令来安装pygame库:pip install pygame。
二、代码 1.main方法 代码如下:
# -*- codeing = utf-8 -*- # @Time : 2023/1/14 15:59 # @Author : 小马 # @File: plant_vs_zoomie_game_normal_main.py # @Software : PyCharm import time import pygame import random import os from Adc import Adc from shooter import shoot from Ap import Ap from tank import tank from Sun import Sun from Zombie import Zombie from badmanmini import badmanmini from Bullet import Bullet from bulletshooter import bulletshooter from enemy import enemy from Carman import Carman from Boss import Boss from pythonExtend import pythonExtend pygame.
一、点运算 概念:点运算(也称为像素级运算或单像素操作)是指对图像中每一个像素点进行独立、相同的操作,而这些操作不会考虑像素点之间的空间关系。点处理优势也称对比度拉伸、对比度增强或灰度变换等。
目的:点运算在图像处理中广泛应用于对比度增强、亮度调整、直方图均衡化、图像阈值化等方面。通过点运算,可以改善图像的视觉效果,使其更适合于后续的处理和分析。
分类:点运算可分为灰度变换和直方图修正两大方法,其中直方图修正包括直方图均衡化和直方图规范化。
特点:可逆、无法增强图像细节
应用:光度学标定、对比度增强(对比度扩展)、显示标定、轮廓线(例如用点处理进行图像阈值化处理,根据图像的灰度等级把一幅图像划分成一些不连接的区域,这有助于确定图像中对象的边界或定义蒙版)、裁剪(对于8位的灰度图像,在存储每一像素前输出图像的灰度级一定要被裁剪到0~255的范围内)
二、灰度化 概念:灰度化是图像处理中的一个基本步骤,其目的是将彩色图像转换为灰度图像。灰度图像是一种仅包含亮度信息而不包含颜色信息的图像,其像素值通常用一个字节(即0-255的范围)来表示,这个值代表了该像素的灰度等级,也就是亮度。灰度化是许多图像处理任务的第一步,如边缘检测、图像分割、特征提取等,因为灰度图像相对于彩色图像来说,计算量更小,处理速度更快,同时保留了图像的大部分重要信息。
方法:加权平均值法、取最大值法、平均值法等,加权平均值法最为常用
D=0.299R+0.587G+0.114BD=max(R,G,B)D=(R+G+B)/3 示例:
import cv2 import numpy as np # 绘图展示 def cv_show(name, img): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows() image = cv2.imread('img\\1.png') image_cut = image[0:500, 0:500] cv_show("image_cut", image_cut) image_cut[:, :, 0] = image_cut[:, :, 0] * 0.114 image_cut[:, :, 1] = image_cut[:, :, 1] * 0.587 image_cut[:, :, 2] = image_cut[:, :, 2] * 0.299 image_cut_gray = np.sum(image_cut, axis=2, dtype=np.uint8) cv_show('image_copy_cut', image_cut_gray) 结果展示:
文章目录 C语言数据类型和变量1. 数据类型介绍1.1 字符型1.2 整形1.3 浮点型1.4 布尔类型1.5 各种类型数据长度1.5.1 sizeof操作符1.5.2 数据类型长度1.5.3 sizeof表达式不计算 2. signed和unsigned3. 数据类型的取值范围4. 变量4.1变量的创建4.2 变量的分类 5.强制类型转换 C语言数据类型和变量 1. 数据类型介绍 C语⾔提供了丰富的数据类型来描述⽣活中的各种数据。
使⽤整型类型来描述整数使⽤字符类型来描述字符使⽤浮点型类型来描述小数 所谓“类型”,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才知道怎么操作数据。下⾯盘点⼀下C语⾔提供的各种数据类型,本文主要探讨内置数据类型。
1.1 字符型 char //character [signed] char //有符号的 unsigned char //⽆符号的 1.2 整形 //短整型 short [int] [signed] short [int] unsigned short [int] //整型 int [signed] int unsigned int //⻓整型 long [int] [signed] long [int] unsigned long [int] //更⻓的整型 //C99中引⼊ long long [int] [signed] long long [int] unsigned long long [int] 1.
目录 实操案例:利用 IPIDEA 进行数据采集步骤一:注册和获取代理IP步骤二:编写数据采集添加错误处理数据存储到 CSV 文件多线程采集数据 步骤三:处理和分析数据 总结 实操案例:利用 IPIDEA 进行数据采集 我们今天用一个具体的案例来展示IPIDEA的功能。该案例可以帮助电商企业在市场竞争中更好地了解竞争对手的产品和定价策略,优化自己的产品选择和定价,最终维持和提升市场竞争力。
步骤一:注册和获取代理IP 首先,我们需要在 IPIDEA官网 注册一个账号,并购买适合我们的代理服务套餐。注册和购买步骤通常包括:
1.IPIDEA 官网:进入官网,点击注册按钮,填写必要的信息创建账号。(ps:他们官网有免费试用哦,想要了解的伙伴可以试用看看)
2.选择合适的代理服务套餐:根据需求选择套餐,通常包括不同数量的代理IP和使用时长。
然后我们需要生成链接,将API加入我们的Python代码中,获取到全球各地的代理IP。以下是具体步骤的截图示例:
步骤二:编写数据采集 接下来,我们将编写一个 Python ,通过 IPIDEA 提供的代理IP来采集亚马逊网站中笔记本电脑商品的数据:https://www.amazon.com/s?k=laptop 。以下是一段详细的示例代码:
import requests from bs4 import BeautifulSoup import csv import time from random import randint # 获取代理IP列表 def get_proxies(): proxies = [] for _ in range(5): # 获取5个代理IP response = requests.get('http://api.proxy.ipidea.io/getBalanceProxyIp?num=1&return_type=txt&lb=1&sb=0&flow=1®ions=&protocol=http') proxies.append(response.text.strip()) return proxies # 轮换代理IP def rotate_proxy(proxies): return {'http': proxies[randint(0, len(proxies)-1)]} # 数据采集函数 def fetch_data(url, proxies): headers = { 'User-Agent': 'Mozilla/5.
134 加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
class Solution: def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int: for i in range(len(cost)): rest = gas[i] - cost[i] # 记录剩余油量 index = (i + 1) % len(cost) # 下一个加油站的索引 while rest > 0 and index != i: # 模拟以i为起点行驶一圈(如果有rest==0,那么答案就不唯一了) rest += gas[index] - cost[index] # 更新剩余油量 index = (index + 1) % len(cost) # 更新下一个加油站的索引 if rest >= 0 and index == i: # 如果以i为起点跑一圈,剩余油量>=0,并且回到起始位置 return i # 返回起始位置i return -1 # 所有起始位置都无法环绕一圈,返回-1 135 分发糖果 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
【C++】—— 类与对象(二) 1、类的默认成员函数2、构造函数2.1、初见构造2.2、深入构造2.3、初始化列表2.3.1、什么是初始化列表2.3.2、初始化列表和函数体关系2.3.3、必须使用初始化列表的情况2.3.3.1、 c o n s t const const 成员变量2.3.3.2、引用成员变量2.3.3.3、没有默认构造的类 2.3.4、变量声明时给缺省值(默认值)2.3.5、初始化列表初始化顺序2.3.6、总结2.3.6.1、构造函数特点总结2.3.6.1、初始化列表知识点总结2.3.6.2、初始化列表行为脉络 3、析构函数3.1、初见析构3.2、深入析构 1、类的默认成员函数 类的默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数被称为默认成员函数。一个类,我们不写的情况下编译器会默认生成 6 个默认成员函数。
需要注意的是这 6 个最重要的默认成员函数是前 4 个,最后两个取地址重载不重要,我们稍微了解一下即可。
其次就是 C++11 以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们以后再讲解。
默认成员函数是学习 C++ 的基础,很重要,但也比较复杂,我们学习默认成员函数时要从以下两个方面取学习:
我们不写时,编译器默认生成的函数行为是什么,是否满足我们的需求编译器默认生成的 函数不满足我们的需求,我们需要自己实现,那么如何自己实现。 2、构造函数 2.1、初见构造 构造函数虽然名字叫构造,但它并不是用来开空间创建对象的。对象的空间在函数创建栈帧时就一次性开辟好了(不仅是对象,所有变量都是如此)。
构造函数的功能是对象实例化时初始化对象。构造函数的本质是要替代我们以前 S t a c k Stack Stack 和 D a t e Date Date 类中写的 I n i t Init Init 函数的功能,构造函数一系列的特点完美的替代了 Init
构造函数的特点:
函数名与类名相同无返回值(返回值啥都不需要给,也不需要写void)对象实例化时系统会自动调用对应的构造函数构造函数可以重载 我们来看日期类的构造函数
注:实际运行代码时全缺省的构造函数不能与无参的或带参的构造函数同时存在,并且全缺省的构造函数的功能已经包括了无参构造和带参构造,我们只需保留全缺省构造函数即可,这里只是为了演示。
可以看到,上述构造函数可以重载;函数名与类名相同;无返回值
构造函数的调用也与一般的函数调用不同,我们一起来看看:
int main() { Date d1; Date d2(2025, 1, 1); d1.
前言 在SpringBoot使用RedisTemplate、StringRedisTemplate操作Redis中,我们介绍了RedisTemplate以及如何SpringBoot如何通过RedisTemplate、StringRedisTemplate操作Redis。
RedisTemplate的好处就是基于SpringBoot自动装配的原理,使得整合redis时比较简单。
那既然SrpingBoot可以通过RedisTemplate操作Redis,为何又出现了Redisson呢?Rddisson 中文文档
Reddissin也是一个redis客户端,其在提供了redis基本操作的同时,还具备其他客户端一些不具备的高精功能,例如:分布式锁+看门狗、分布式限流、远程调用等等。Reddissin的缺点是api抽象,学习成本高。
一、概述 从 spring-boot 2.x 版本开始,spring-boot-data-redis 默认使用 Lettuce 客户端操作数据。
1.1 Lettuce SpringBoot2之后,默认就采用了lettuce。
是高级Redis客户端,基于Netty框架的事件驱动的通信层,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。
Lettuce的API是线程安全的,可以操作单个Lettuce连接来完成各种操作,连接实例(StatefulRedisConnection)可在多个线程间并发访问。
1.2 Reddisson 基于Netty框架的事件驱动的通信层,方法是异步的,API线程安全,可操作单个Redisson连接来完成各种操作。
实现了分布式和可扩展的Java数据结构,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。
提供很多分布式相关操作服务,如,分布式锁,分布式集合,可通过 Redis支持延迟队列。
总结:优先使用Lettuce,需要分布式锁,分布式集合等分布式的高级特性,添加Redisson结合使用。
二、Spring-Boot整合Redisson 2.1 引入依赖 <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.13.6</version> </dependency> 注意:引入此依赖后,无需再引入spring-boot-starter-data-redis,其redisson-spring-boot-starter内部已经进行了引入,且排除了 Redis 的 Luttuce 以及 Jedis 客户端。因此,在 application.yaml 中 Luttuce 和 Jedis 的配置是不会生效的。
在项目使用 Redisson 时,我们一般会使用 RedissonClient 进行数据操作,但有朋友或许觉得 RedissonClient 操作不方便,或者更喜欢使用 RedisTemplate 进行操作,其实这两者是可以共存的,我们只需要再定义RedisTemplate的配置类即可。参考SpringBoot使用RedisTemplate、StringRedisTemplate操作Redis。
发现项目引入 Redisson 后,RedisTemplate底层所用的连接工厂也是 Redisson。
2.2 配置文件 在application.yaml中添加redis的配置信息。
spring: data: redis: mode: master # 地址 host: 30.
目录
ONNX Runtime 的作用
主要功能
跨平台支持
性能优化
易于集成
如何使用 ONNX Runtime
ONNX Runtime 的优缺点
优点
缺点
应用领域
1. 自然语言处理 (NLP)
2. 计算机视觉 (CV)
3. 语音识别和处理
4. 推荐系统
5. 医疗健康
6. 金融科技 (FinTech)
具体应用案例
微软产品与服务
性能对比
1. 推理速度
2. 内存使用
易用性对比
1. 开发环境
2. 文档和社区支持
ONNX Runtime 是一个跨平台的机器学习模型加速器,具有灵活的接口,可以集成硬件特定的库。无论是 PyTorch、Tensorflow/Keras、TFLite 还是 scikit-learn 等框架训练的模型,ONNX Runtime 都可以高效运行。
ONNX Runtime 的作用 ONNX Runtime 的主要目标是加速深度学习模型的推理过程,并在各种硬件和操作系统上运行。它支持从不同框架导出的 ONNX 格式模型,为多种机器学习模型提供推理性能的提升。ONNX Runtime 目前已经在微软的关键产品和服务中广泛应用,包括 Office、Azure、Bing 以及众多社区项目。
主要功能 跨平台支持 ONNX Runtime 支持在不同硬件(如 CPU、GPU、FPGA)和操作系统(如 Windows、Linux、macOS)上运行。这种灵活性使得开发者可以在不同环境中部署机器学习模型,而无需担心兼容性问题。
文章目录
阿里云Flink的应用场景
一、背景信息
二、部门场景
三、技术领域
1、实时ETL和数据流
2、实时数据分析
3、事件驱动应用
4、风控监测系统
阿里云Flink的应用场景 这里将以部门场景和技术领域场景为例,为我们介绍实时计算Flink版的大数据是实时化场景。
一、背景信息 作为流式计算引擎,Flink可以广泛应用于实时数据处理领域,例如ECS在线服务日志,IoT场景下传感器数据等。同时Flink还能订阅云上数据库RDS、PolarDB等关系型数据库中Binlog的更新,并利用DataHub、SLS、Kafka等产品将实时数据收集到实时计算产品中进行分析和处理。最终,分析结果可写入不同的数据服务中,例如MaxCompute、MaxCompute-Hologres交互式分析、PAI机器学习、Elasticsearch等,以提高数据利用率,满足业务需求。
二、部门场景 从企业部门职能的角度,可以将实时计算Flink版划分为以下场景:
业务部门:实时风控、实时推荐、搜索引擎的实时索引构建等。数据部门:实时数仓、实时报表、实时大屏等。运维部门:实时监控、实时异常检测和预警、全链路Debug等。 三、技术领域 从技术领域的角度,实时计算Flink版主要用于以下场景:
1、实时ETL和数据流 实时ETL和数据流的目的是实时地把数据从A点投递到B点。在投递的过程中可能添加数据清洗和集成的工作,例如实时构建搜索系统的索引、实时数仓中的ETL过程等。
2、实时数据分析 数据分析指的是根据业务目标,从原始数据中抽取对应信息并整合的过程。例如,查看每天销量前10的商品、仓库平均周转时间、文档平均单击率、推送打开率等。实时数据分析则是上述过程的实时化,通常在终端体现为实时报表或实时大屏。
3、事件驱动应用 事件驱动应用是对一系列订阅事件进行处理或作出响应的系统。事件驱动应用通常需要依赖内部状态,例如欺诈检测、风控系统、运维异常检测系统等。当用户行为触发某些风险控制点时,系统会捕获这个事件,并根据用户当前和之前的行为进行分析,决定是否对用户进行风险控制。
4、风控监测系统 实时计算Flink版可以处理复杂的流处理和批处理任务,也提供了强大的API,执行复杂的数学计算并执行复杂事件处理规则,帮助企业对实时数据进行实时分析,提高企业的风控能力。例如检测APP中的点击行为、识别loT数据流不规则变化等。
📢博客主页:https://lansonli.blog.csdn.net📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢本文由 Lansonli 原创,首发于 CSDN博客🙉📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis (已更完)Kafka(正在更新…) 章节内容 上节我们完成了如下的内容,基本都是特性概念相关的:
分区相关介绍副本机制同步节点宕机恢复Leader选举 基础概念、选举过程、为何不少数服从多数 分区重分配 向已经部署好的Kafka集群里添加机器,我们需要从已经部署好的Kafka节点中复制相应的配置文件,然后把里边的 BrokerID 修改为全局唯一的,最后启动这个节点即可让它加入到现有的Kafka集群中。
当前问题 新添加的Kafka节点并不会自动的分配数据,无法分担集群的负载,除非我们新建一个Topic。
在重新分布Topic分区之前,我们先来看看现在Topic的各个分区的分布位置。
启动服务 如果你的Kafka服务还未启动,需要先启动,再进行后续的测试实验。
我这里启动:
kafka-server-start.sh /opt/servers/kafka_2.12-2.7.2/config/server.properties 启动结果如下图:
创建主题 kafka-topics.sh --zookeeper h121.wzk.icu:2181 --create --topic wzk_topic_test --partitions 5 --replication-factor 1 我们的配置:
创建一个5个分区的主题Kafka此时的算法会保证所有分区都分配到现有的Kafka代理节点上 创建的结果如下:
查看主题 kafka-topics.sh --zookeeper h121.wzk.icu:2181 --describe --topic wzk_icu_test 创建的结果如下图,可以观察到5个分区。
新增Kafka 在新的机器上部署Kafka服务,记得修改BrokerID。
刚才我们是单节点的,Kafka在 h121 节点上。
# 配置内容参考 h121 中的配置 # 但是注意要修改 BrokerID vim config/server.properties h121 broker 1h122 broker 2h123 broker 3 (暂时还不配置3节点) 此时我们来到 h122 用如下的命令启动Kafka,我启动的是临时的,如果你有需要,请用守护方式启动。
# 环境变量别忘了配置 kafka-server-start.
要深入的理解节点与场景,我们需要跳出这两个概念来看他。说的再直白一些godot本质就是一个场景编辑器!
场景的概念应该在我们平时看电影看电视时会经常提到,比如某一个打斗的场景,这个场景可能会被设在某一个街道,那么这个街道上肯定有路人,有房子,有商店,有过往的汽车等等一些元素!那么这些元素就是构成这个场景的节点!但是这些元素又可能是另外的独立的场景,比如路上的这个商店里有售货员,有货架,有收银台等等,这些元素又构成了一个房子的场景!
所以,场景就是一个树状结构!有网页开发经验的开发者可能会更能明白这一点!
创建场景 创建场景之前肯定是要先创建项目,如何创建项目请参照上一节!
如图所示左上角部分就是创建场景的入口模块,2D场景、3D场景、用户界面是godot为我们预设的基本的几个场景节点快速入口,更多的场景节点我们可以点击其他节点来创建!
点击其他节点会弹出如下图所示的弹窗!
①处是搜索框可以模糊匹配检索需要的节点②处是检索到的节点树,这个树状结构就清晰的表达出了每个节点之间的继承关系,他们是一个一个类(class),如果你有python编程基础,对类的概念应该并不陌生!③处是对你选中节点的一个基本介绍,可以快速让你了解该节点的一个作用及使用场景!④处按钮点击即可创建一个以节点名称为名字的节点出现在1图中的场景入口模块 创建好的节点,windos系统可以按F2键对其重命名,我们可以将其命名为一个Main的名称!
重命名完之后我们按Ctrl+s即可实现保存场景,第一次保存场景时会弹出以下弹窗!
这里我们可以点击①处的创建文件夹为我们的场景创建一个目录,会弹出如②所示的弹窗,输入screen名称点击确定即可在项目目录下新建一个该名称的文件夹,我们选中该文件夹,点击③处的保存即可将该场景加入到该目录下!
文件系统模块此时如下图所示:
添加子节点的三种方式
第一种就是在节点名称处点击鼠标右键则会弹出菜单,菜单第一项就是创建子节点,默认就会归属到该节点! 第二种就是点击如下图所示的加号,也可以为选中的节点创建子节点! 第三就是点击菜单中的场景,选择新建场景,那么场景模块哪里就会初始化为最开始1图中所示的那样,我们可以自由选择创建一个新的场景,这个场景是完全独立于刚才创建的Main场景的! 创建实例 实例的概念大家就简单的理解为一个有真实意义含义的场景就可以,比如我们第一次创建的场景Main,他可能是我们游戏的主入口,那么这个场景中开场部分是不是还会有其他的东西,比如开始游戏按钮、退出游戏按钮、游戏设置等元素,那么这些就是构成该场景的一个一个实例,这个实例其实也是一个独立的场景!
这里我们就可以看出Godot游戏其实就是由长江构成的树状结构,而每一个场景又是一个由节点构成的树状结构!
这里我们添加节点方式中的第三种创建一个新的2D场景,名称设为Hub,再在其中创建一个UI的子节点!
将Hub场景保存,文件系统如下图所示!
在Hub的UI节点下创建一个Label节点,Label节点是用于显示纯文本的控件!
①处输入你想写入的文案,则会出现在编辑器中间的位置,注意中间顶部需切换到2D选项
②处如果选中的是箭头则可以鼠标左键点击屏幕中间的文字框随意拖动位置,这个绿色十字交叉的地方是我们打开界面的左上角起始位置
编辑器右上角的位置是运行场景的几个按钮,①是运行主场景,第一次点击时会弹出一个弹窗提示你设置一个主场景,那么我们这里选择Main场景作为主场景!
选择Main成为主场景后我们点击①处按钮运行起来应该是什么都看不到,因为Main节点中并还没有任何实例!
点击②处则会运行当前看到的场景,那么我们目前处在Hub场景中,则会看到我们刚才设置的文案文字!
如果说我们想让每次运行游戏时玩家首先就能看到Hub场景,那么我们就要将该场景实例化到Main中!实例化的方法如下按顺序操作即可,或者也可以直接拖动hub.tscn到Main也可以完成实例化!
实例化之后如下图所示,注意场景右侧的两个图标,这些也都是有意义的!
那么,这样我们就实现了每次进入游戏,玩家都可以首先看到我们设置的文案信息!
文章目录 一,119-全文检索-ElasticSearch-映射-mapping创建1,Elasticsearch7开始不支持类型type。2,mapping2.1 Elasticsearch的Mapping 二,120-全文检索-ElasticSearch-映射-添加新的字段映射三,121-全文检索-ElasticSearch-映射-修改映射&数据迁移1,创建新索引newbank2,将旧索引数据迁移到新索引3,为新索引指定别名 一,119-全文检索-ElasticSearch-映射-mapping创建 1,Elasticsearch7开始不支持类型type。 这意味着,在创建索引时,不需要指定type
2,mapping 索引就像是MySQL等关系数据库的表一样,而表是有表结构的,表结构有字段名词和自动类型组成。
Elasticsearch的索引也有类似的概念,但和MySQ的表结构有些区别:
索引的结构称之为mappingmapping不必提前创建,Elasticsearch会在导入数据时,依据具体的数据进行类型推断,自动创建mapping 2.1 Elasticsearch的Mapping 定义:映射是Elasticsearch中定义索引的模式,它指定了索引中每个字段的数据类型和属性,如分析器(Analyzers)、是否可索引(index)、是否可存储(store)等。目的:映射用于优化搜索性能和定义数据如何被索引和搜索。类型:Elasticsearch支持多种字段类型,包括text、keyword、date、integer、float、boolean等。分析器:Elasticsearch是为全文搜索优化的,字段可以指定不同的分析器来处理文本数据,如标准分析器、简单分析器等。动态映射:Elasticsearch支持动态映射,即在索引新类型的数据时,可以自动推断字段类型并创建映射。 示例:在创建索引时指定mapping:
PUT /my-index { "mappings": { "properties": { "name": { "type": "text" }, "age": { "type": "integer" }, "date": { "type": "date", "format": "yyyy-MM-dd" } } } } 二,120-全文检索-ElasticSearch-映射-添加新的字段映射 这一节的主要内容是如何修改索引的mapping。
但我们要修改一个已经存在的索引的mapping时,可用使用如下方式。
PUT /my_index/_mapping { "properties": { "employee-id": { "type": "keyword", "index": false } } } PUT /my_index/_mapping:这是一个HTTP PUT请求,用于指定名为my_index的索引的映射。如果索引不存在,这个请求将创建索引并定义其映射;如果索引已经存在,它将更新现有的映射。
properties:这是映射定义中的一个关键部分,它包含了索引中所有字段的定义。
'employee-id:这是字段的名称。
type:指定字段的数据类型。在这个例子中,keyword类型被指定,这意味着这个字段将用于精确匹配,并且不会进行全文搜索的分析。
index:这个属性指定字段是否应该被索引。在这个例子中,index被设置为false,表示employee-id字段的数据将不会被索引,因此不能被搜索,也即是这个字段不能作为搜索条件。这通常用于存储元数据或在文档中作为唯一标识符,但不需要进行搜索。
需要注意的是,对于mapping的更新,仅限于增加新的字段,不能修改已有字段的任何属性。
三,121-全文检索-ElasticSearch-映射-修改映射&数据迁移 正如前面所说,index索引的mapping是不能修改的。
hello,又见面了!
目录
1. 栈的概念与结构
2、栈的实现
Stack.h
Stack.c
test.c
3、习题
正文开始——
1. 栈的概念与结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守先进后出的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫出栈,出数据也在栈顶。
【图解】
栈的底层结构
内存比较:双向链表比单链表多了一种指针,内存占用就相对多一些;数组和单链表,数组每次都以2倍大小增容,正因如此,无需多次增容,而单链表每次增加数据都要申请空间,删除数据要释放空间,较为繁琐。
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更好一些,因为数组在尾插数据时代价更小。
2、栈的实现 栈里的数据不能被遍历,不能被随机访问。每次取数据只能取栈顶数据
Stack.h #pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h> #include<stdbool.h> //定义栈的结构 typedef int STDataType; typedef struct Stack { STDataType* arr; int capacity; //栈的容量 int top; //栈顶 }ST; //初始化 void STInit(ST* ps); //销毁 void STDestroy(ST* ps); //入数据 void StackPush(ST* ps, STDataType x); //出数据 void StackPop(ST* st); //取栈顶元素 STDataType StackTop(ST* ps); //判空 bool StackEmpty(ST* ps); //获取栈中有效的数据个数 int STsize(ST* ps); Stack.
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis (已更完)Kafka(正在更新…) 章节内容 上节我们完成了如下的内容,基本都是特性概念相关的:
kafka-topics.sh 的基本参数和基本使用,涉及到创建、查看、修改、主题,增加分区等。KafkaAdminClientKafka偏移量管理 副本机制 Kafka在一定数量的服务器上对主题分区进行复制,当集群中一个Broker宕机之后们可以自动故障转移到其他可用的副本上,不会造成数据丢失。
将复制因子为1的未复制主题称为复制主题主题的分区是复制的最小单元在非故障的情况下,Kafka中的每个分区都由1个Leader副本,0个或N个Follower副本。包括Leader副本在内的副本总数构成复制因子所有读取和写入都是由Leader副本负责通常分区比Broker多,并且Leader分区在Broker之间平均分配 Follower分区像普通的Kafka消费者一样,消费者来自Leader分区的消息,并将其持久化到自己的日志中,允许Follower对日志条目拉取进行批处理。
同步节点 节点必须能够维持ZooKeeper的会话(通过ZooKeeper的心跳机制)对于Follower副本分区,它复制在Leader分区上的写入,并且不要延迟太多 Kafka提供的保证是:只要至少有一个同步副本处于活动状态,提交的消息就不会丢失。
宕机恢复 少副本宕机 当Leader宕机了,会从Follower选择一个作为Leader,当宕机重新恢复时,会把之前的commit清空,重新从Leader中Pull数据。
全副本宕机 恢复方式1:等待ISR中的一个恢复后,选为Leader(时间久,可用性低)恢复方式2:选择一个恢复的副本作为新的Leader,无论是否在ISR中(可能未包含提交commit,会丢失数据) Leader选举 3个分区3个Broker 基础概念 生产者和消费者的请求都由Leader副本处理,Follower副本只负责Leader副本的数据和Leader保持同步。
Leader副本和Follower副本之间的关系并不是固定不变的,在Leader所在的Broker发生故障的时候,就需要进行分区的Leader副本和Follower副本之间的切换,需要选举Leader副本。
如何选举 如果某个分区所在的服务器出了问题导致不可用,Kafka会从该分区的其他副本中选择一个成为新的Leader,之后所有的读写就会转移到这个新的Leader上。
那么如何选择Leader呢?
只有那些跟Leader保持同步的Follower才应该被选择为新的LeaderKafka会在ZooKeeper上针对每个Topic维护一个成为ISR(in-sync replica,已同步的副本)的集合,该集合中是一些分区的副本。只有当这些副本都跟Leader中的副本同步了之后,Kafka才会认为消息已提交,并反馈给消息的生产者如果这个集合有增有减,Kafka会更新ZOoKeeper上的记录如果某个分区的Leader不可用,Kakfa就会从ISR集合中选择一个副本作为新的Leader 显然通过ISR,Kafka需要的冗余度是较低的,可以容忍的失败度较高。
假设某个Topic有N+1个副本,Kafka可以容忍N个服务器不可用。
为何不用少数服从多数 少数服从多数是一种比较常见的一致性算法和Leader选举法它的含义是只有超过半数的副本同步了,系统才会认为数据已经同步选择Leader时也是超过半数的同步副本中选择这种算法需要较高的冗余度,更Kafka比起来,浪费资源譬如:允许一台机器失败,则要三个副本。允许两台机器失败,则需要五个副本 而在Kafka的ISR集合中,允许一台机器失败,要两个副本。允许三台机器失败,需要五个副本。
若ISR全部失败 此时有两种方案可以选择:
等待ISR集合中的副本复活选择任何一个立即可用的副本,而这个副本不一定是在ISR集合中(需要设置:unclean.leader.election.enable=true) 这两种方法各有利弊,实际生产中按需选择即可。
如果要等待ISR副本复活,虽然保证一致性,但可能需要很长的时间。如果选择立即可用的副本,虽然保证可用性,但是数据可能会丢失。
文章目录 一,基本概念主要聚合类型 二,实战1,搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄,但不显示这些人的详情2,按照年龄聚合,并且请求每个年龄的平均薪资 Elasticsearch 的聚合(Aggregations)功能允许用户对数据集进行聚合分析,从而获得数据的摘要信息。 聚合应用于搜索结果,帮助用户理解数据的分布、统计和模式。
一,基本概念 聚合提供了从数据中分组和提取数据的能力。聚合类似于 SQL GROUPBY 和 SQL 聚合函数。
桶(Buckets):桶是聚合的基础,用于将数据分组。每个桶代表一个分组,可以基于不同的标准,如日期范围、数值范围、术语等。度量(Metrics):度量聚合用于计算数值字段的统计数据,如总和、平均值、最小值、最大值、计数等。管道聚合(Pipeline Aggregations):管道聚合是对其他聚合结果进行二次处理的聚合,如计算移动平均值、百分比变化等。子聚合(Sub-Aggregations):子聚合允许在桶内部进一步细分数据,可以嵌套使用。 主要聚合类型 terms:基于字段的术语进行分组,并为每个术语提供度量(如计数)。histogram:基于数值字段创建数值区间(桶),并计算每个区间内的文档数量。date_histogram:类似于histogram,但是专门用于日期字段,可以按照年、月、日等时间单位分组。range:基于指定的范围表达式对数值或日期字段进行分组。significant_terms:找出在特定数据集中出现的显著术语,与常规terms聚合不同,它基于统计测试来确定哪些术语是显著的。cardinality:提供一个字段中唯一值的近似计数,这个聚合类型对于大数据集很有用,因为它比普通的unique计数更高效。avg、sum、min、max:这些聚合类型分别计算数值字段的平均值、总和、最小值和最大值。stats 和 extended_stats:提供数值字段的多种统计信息,包括平均值、总和、最小值、最大值、标准差等。 二,实战 以下Demo都是基于对索引bank的搜索。
1,搜索 address 中包含 mill 的所有人的年龄分布以及平均年龄,但不显示这些人的详情 GET bank/_search { "query": { "match": { "address": "mill" } }, "aggs": { "group_by_state": { "terms": { "field": "age" } }, "avg_age": { "avg": { "field": "age" } } }, "size": 0 } query:定义了搜索的具体条件。
match:这是一个全文搜索查询,用于搜索address字段中包含"mill"的文档。 aggs:定义了聚合操作,用于对搜索结果进行分组和统计分析。
group_by_state:这是一个terms聚合,命名为group_by_state(注意,则个名称是自定义的,不是标准字段),它将结果基于age字段的术语进行分组,并为每个年龄提供计数。 terms:指定使用age字段进行分组并统计文档数量。 avg_age:这是一个度量聚合,命名为avg_age(也是自定义名称),用于计算所有匹配文档的age字段的平均值。 avg:指定聚合类型为平均值。 size:指定返回的文档数量。在这里设置为0,表示不返回任何匹配的文档,只返回聚合结果。
在 WPF 中的 DataGrid 中,如果希望在选中某一行后让该行的第一列中的 CheckBox 选中,可以通过绑定和事件处理来实现。以下是具体的步骤:
绑定数据:确保 DataGrid 的数据源绑定到一个支持 INotifyPropertyChanged 接口的集合。模板列定义:定义一个带有 CheckBox 的 DataGridTemplateColumn,并绑定 CheckBox 的 IsChecked 属性。事件处理:处理 DataGrid 的 SelectionChanged 事件,在事件处理程序中设置 CheckBox 的选中状态。 以下是一个示例实现:
1. 数据模型 首先,定义一个数据模型,包含一个 IsChecked 属性,并实现 INotifyPropertyChanged 接口:
using System.ComponentModel; public class Item : INotifyPropertyChanged { private bool _isChecked; public bool IsChecked { get { return _isChecked; } set { if (_isChecked != value) { _isChecked = value; OnPropertyChanged("IsChecked"); } } } public string Name { get; set; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { PropertyChanged?
目录
一、用法精讲
241、pandas.Series.view方法
241-1、语法
241-2、参数
241-3、功能
241-4、返回值
241-5、说明
241-6、用法
241-6-1、数据准备
241-6-2、代码示例
241-6-3、结果输出
242、pandas.Series.compare方法
242-1、语法
242-2、参数
242-3、功能
242-4、返回值
242-5、说明
242-6、用法
242-6-1、数据准备
242-6-2、代码示例
242-6-3、结果输出
243、pandas.Series.update方法
243-1、语法
243-2、参数
243-3、功能
243-4、返回值
243-5、说明
243-6、用法
243-6-1、数据准备
243-6-2、代码示例
243-6-3、结果输出
244、pandas.Series.asfreq方法
244-1、语法
244-2、参数
244-3、功能
244-4、返回值
244-5、说明
244-6、用法
244-6-1、数据准备
244-6-2、代码示例
244-6-3、结果输出
245、pandas.Series.asof方法
245-1、语法
245-2、参数
245-3、功能
245-4、返回值
245-5、说明
245-6、用法
245-6-1、数据准备
245-6-2、代码示例
245-6-3、结果输出
二、推荐阅读
1、Python筑基之旅
2、Python函数之旅
3、Python算法之旅
4、Python魔法之旅
5、博客个人主页
一、用法精讲 241、pandas.Series.view方法 241-1、语法 # 241、pandas.Series.view方法 pandas.Series.view(dtype=None) Create a new view of the Series.
目录
一、用法精讲
236、pandas.Series.explode方法
236-1、语法
236-2、参数
236-3、功能
236-4、返回值
236-5、说明
236-6、用法
236-6-1、数据准备
236-6-2、代码示例
236-6-3、结果输出
237、pandas.Series.searchsorted方法
237-1、语法
237-2、参数
237-3、功能
237-4、返回值
237-5、说明
237-6、用法
237-6-1、数据准备
237-6-2、代码示例
237-6-3、结果输出
238、pandas.Series.ravel方法
238-1、语法
238-2、参数
238-3、功能
238-4、返回值
238-5、说明
238-6、用法
238-6-1、数据准备
238-6-2、代码示例
238-6-3、结果输出
239、pandas.Series.repeat方法
239-1、语法
239-2、参数
239-3、功能
239-4、返回值
239-5、说明
239-6、用法
239-6-1、数据准备
239-6-2、代码示例
239-6-3、结果输出
240、pandas.Series.squeeze方法
240-1、语法
240-2、参数
240-3、功能
240-4、返回值
240-5、说明
240-6、用法
240-6-1、数据准备
240-6-2、代码示例
240-6-3、结果输出
二、推荐阅读
1、Python筑基之旅
2、Python函数之旅
3、Python算法之旅
4、Python魔法之旅
5、博客个人主页
一、用法精讲 236、pandas.Series.explode方法 236-1、语法 # 236、pandas.Series.explode方法 pandas.Series.explode(ignore_index=False) Transform each element of a list-like to a row.