当前位置: 首页 > news >正文

AntDB-S流式数据库体验

本文作者:彭冲老师,上一篇彭老师体验了亚信刚发布的社区版AntDB-T数据库,文章如下:
AntDB-T交易型数据库体验

本文继续体验AntDB-S流式数据库的,AntDB-S目前还未开放社区版,可以联系AntDB小助手进行体验。

01

AntDB-S 流式数据库简介

流式数据库是把流处理引擎的能力合并到数据库内核,与数据库SQL引擎、存储引擎融合在一起,完全以数据库的习惯使用流处理引擎,甚至可以和数据库的功能混合使用。比如流对象与表对象联合JOIN。

下面几幅图是流式数据库的架构、以及AntDB-S在PostgreSQL数据库基础上进行改造的说明。

图片

图片

图片

图片

从上面几幅图可以看出AntDB-S是在PostgreSQL内核上加入流处理引擎功能,把流数据的存储融合进PostgreSQL的存储引擎,把流处理的进程体系结构融合进PostgreSQL的进程体系结构中。

这样的融合结构会带来以下的优势:

  1. 技术栈简单,稳定性好。

  2. 学习和维护成本低,只需掌握数据库的使用和维护即可。

  3. 纯SQL操作,使用简单方便,可快速响应业务的复杂多变性。

  4. 流数据处理支持数据UPDATE和DELETE、事务ACID以及流对象与表对象联合JOIN。

02

流处理基本术语

流是一种日益增长(ever-growing)的、并且可能形成无序(但有效)的、本质上无限(essentially infinite)的数据集。

流具有三个特性:数据无边界(Unbounded data)、处理无边界(Unbounded data processing)、低延时(Low-latency)。

流对象

流对象就是流式数据库里用于保存流数据的对象,类似PostgreSQL里的表。流对象具有表的特性,可以对其流数据进行增删改查且满足事务ACID;可以对其流数据进行流式计算;同时具有物化视图的特性,可以从一个流对象的处理结果生成另一个流对象。

PULL和PUSH查询

传统数据库的查询模式称为PULL模式,客户端执行查询语句,数据库把查询结果返回给客户端,结果集全部返回则查询语句执行结束。流对象的查询会长期运行,流数据被处理后实时推送给客户端,这种查询模式不同于传统的数据库查询模式,称之为PUSH模式。

时间概念

对于流式数据处理,最大的特点就是数据具有时间属性。流数据库根据时间产生的位置把时间划分为三钟类型:事件生成时间(Event Time)、事件接入时间(Ingestion Time)和事件处理时间(Processing Time)。用户可以根据具体业务灵活选择时间类型。

  • 事件生成时间

事件生成时间(简称事件时间),是每个独立事件在产生它的设备上发生的时间,这个时间通常在事件进入流数据库前就已经进入事件当中了,即事件时间是从原始的消息中提取的。

  • 事件接入时间

事件接入时间(简称入库时间),是数据进入流数据库的时间,它主要依赖接入节点所在主机的系统时钟。

  • 事件处理时间

事件处理时间(简称处理时间),是指数据在算子计算过程中获取到的所在主机时间,这个时间是由流数据库自己提供的。

在三种时间概念中,事件时间和处理时间是最重要的。在理想情况下,事件时间等于处理时间,也就是事件一发生就立即被处理。但是在现实世界中,这是不可能发生的。由于网络延时、前端数据积压、流处理本身耗时等因素都会导致事件时间和处理时间不一致,甚至有可能会乱序到达。

图片

针对延迟和乱序的情况,一般建议使用事件时间进行流式处理。对于时间计算精度要求不是特别高的计算场景,如延时比较高的日志数据,可使用处理时间。

窗口

窗口操作是流式系统进行数据流处理的核心,通过窗口操作,可以将一个无限的数据流拆分成很多个有限大小的“桶”,然后在这些桶上执行计算。

流式数据库提供了四种窗口定义:滚动窗口、滑动窗口、会话窗口和全局窗口。

  1. 滚动窗口

图片

滚动窗口(Tumbling Window),在时间维度上按照固定长度将无边界数据流切片,彼此紧邻而不交叉的出现,对于一个到来的数据,根据时间属性取得其时间戳,即可计算出它所对应的时间窗口。

  1. 滑动窗口

图片

滑动窗口(Hopping Window),也是采用固定相同间隔分配窗口,只不过每个窗口之间有重叠。滑动窗口有两个参数,分别是窗口大小(Window Size)和滑动步长(Slide),后者决定了窗口每次向前滑动的距离。当滑动步长小于窗口大小时,将会发生多个窗口的重叠,即一个元素可能被分配到多个窗口里去。当滑动步长等于窗口大小时,就变成了滚动窗口。当滑动步长大于窗口大小时,就会出现窗口不连续的情况,数据可能不属于任何窗口。

  1. 会话窗口

图片

会话窗口(Session Window)根据会话间隙(Session Gap)切分不同的窗口,当一个窗口在大于会话间隙的时间内没有接收到新数据时,窗口将关闭。在这种模式下,窗口的长度是可变的,每个窗口的开始和结束时间并不是确定的。

  1. 全局窗口

全局窗口(Global Window)只有一个窗口且窗口无限大,也就是无窗口定义,因为没有窗口结束时间所以不能等窗口结束后输出统计结果,一有数据立即计算输出结果。

水位线

前面提到流处理系统为实时计算提供了三种时间,即事件时间、入库时间和处理时间。在进行窗口计算,理想情况下事件时间和处理时间一致,但是在实际应用中,由于网络或者系统等外部因素影响,事件数据往往不能及时到达流处理系统,从而造成数据乱序或者延迟到达等问题。针对这两个问题,流数据库主要采用了以水位线(Watermater)为核心的机制来应对。正确地处理乱序事件,通常是结合窗口和水位线这两种机制来实现的。

在流处理过程中,从时间产生,到流经数据库,到流经算子,中间是有一个过程和时间的。虽然在大部分情况下,流到算子的数据都是按照事件产生的时间顺序到达的,但是也不排除由于网络、系统等原因,导致乱序的产生和迟到数据。但是对于迟到数据,不能无限期地等下去,必须要有个机制来保证在经过一个特定的时间后,触发窗口计算。此时由水位线来发挥作用,它表示当达到水位线后,在水位线之前的数据已经全部到达(即使后面还有延迟的数据),系统可以触发相应的窗口计算。也就是说,只有水位线越过窗口对应的结束时间,窗口才会关闭和计算。只有以下两个条件同时成立,才会触发窗口计算。

  • 条件T1:水位线时间>=窗口结束时间。

  • 条件T2:在[窗口开始时间,窗口结束时间)中有数据存在。

在理想情况下,水位线应该与处理时间一致,并且处理时间与事件时间只相差常数时间甚至为0。当水位线与处理时间完全重合时,就意味着消息产生后马上被处理,不存在消息迟到的情况。然而,由于网络拥塞或系统原因,消息尝尝存在迟到的情况,因此,在设置水位线时,总是考虑一定的延时,从而给予迟到的数据一些机会。具体的延迟大小由用户根据业务情况在流处理SQL语句中指定。

allowedLateness

在默认情况下,当水位线超过窗口结束时间后,再有之前的数据到达时,这些数据会被删除。为了避免有些迟到的数据被删除,产生了allowedLateness的概念。简单来讲,allowedLateness就是针对事件时间而言,对于水位线超过窗口结束时间后,还允许有一段时间(也是以时间来衡量)来等待之前的数据到达,以便再次处理这些数据。在默认情况下,如果没有在流处理SQL语句中指定allowedLateness,那么它的默认值是0,即对于水位线超过窗口结束时间后,如果还有属于此窗口的数据到达时,这些数据就会被删除。

另外,对于窗口计算,如果没有设置allowedLateness,窗口触发计算以后就会被销毁;设置了allowedLateness以后,只有水位线大于“窗口结束时间 + allowedLateness”时,窗口才会被销毁。

03

AntDB-S 流处理示例

1.连接数据库

psql -h x.x.x.x -d postgres -P pager=off

-P pager=off表示关闭翻页显示,流式查询需要加上。

下面创建测试库demodb

create database mydb; \c mydb

2.创建流对象

流对象为流数据的入口点,下面创建流对象instructor

STREAM instructor (id text, name text, dept_name text, salary float);

STREAM关键字表示创建流对象,流对象也具备流式物化视图的能力。
例如从流对象instructor过滤年薪80000美元的流数据物化成super_instructor:

ructor AS SELECT * FROM instructor WHERE salary >= 80000 EMIT CHANGES;

使用元命令\dt查看流对象或表

             List of relationsSchema |       Name       |  Type  | Owner 
--------+------------------+--------+-------public | instructor       | stream | demopublic | super_instructor | stream | demo
(2 rows)

3.删除流对象
删除流对象super_instructor

DROP STREAM super_instructor;

4.往流对象插入数据

INSERT INTO instructor VALUES('12121', 'Wu', 'Finance', 90000);
INSERT INTO instructor VALUES('15151', 'Mozart', 'Music', 40000);
INSERT INTO instructor VALUES('22222', 'Einstein', 'Physics', 95000);
INSERT INTO instructor VALUES('32343', 'El Said', 'History', 60000);

5.查询流对象
流对象的查询操作包括:传统的PULL模式查询以及新增的PUSH模式查询。
PULL模式把流对象当做表对象处理,查询语法和表的查询一样。
PUSH模式查询,流对象的查询长期运行着,一旦有增量数据立即执行后续的查询操作。
流对象instructor 的PULL查询

SELECT * FROM instructor;

流对象instructor的PUSH查询

SELECT * FROM instructor WHERE salary >= 80000 EMIT CHANGES;

image.png

当其它进程往instructor流对象插数据,PUSH查询会实时显示增量处理结果。
image.png

6.修改流对象数据
先使用带pg_state(xmax)的PUSH查询显示流数据状态

T pg_state(xmax),* FROM instructor WHERE salary >= 80000 EMIT CHANGES;

image.png

修改instructor流对象

UPDATE instructor SET salary = 98000 WHERE id='22222';

image.png
此时PUSH查询显示两条增量数据,一条pg_state状态为’-‘的老数据,表示删除的老数据;一条pg_state状态为’+'的新数据,表示新增的数据。

7.删除流对象数据
同样使用pg_state(xmax)的PUSH查询显示流数据状态
image.png
此时PUSH查询显示一条pg_state状态为’-'的老数据,表示删除老数据。

8.常规聚合
常规聚集就是全局窗口聚集,和普通窗口聚集表现形式不一样,常规聚集因为窗口无限大,所以聚集结果无需显示窗口开始时间和结束时间。
例如:实时统计各个科系教师的人数和薪资总额

SELECT count(id), sum(salary), dept_name 
FROM instructor 
GROUP BY dept_name 
EMIT CHANGES;

image.png

常规聚集的结果也可以物化成其它流对象。
例如:把各个各个科系教师的人数和薪资总额实时统计结果物化成dept_cost流对象

CREATE STREAM dept_cost 
AS 
SELECT count(id), sum(salary), dept_name 
FROM instructor 
GROUP BY dept_name EMIT CHANGES;

9.窗口聚合
前面流处理基本术语介绍过窗口操作,可以将一个无限的数据流拆分成很多个有限大小的“桶”,然后在这些桶上执行计算。根据窗口定义可以分为:滚动窗口、滑动窗口、会话窗口、全局窗口。
全局窗口上面已经介绍过,会话窗口暂不支持,滚动窗口和滑动窗口的流式聚集语法如下:

put_name ] [, ...] ,window_begin(*) [[ AS ] output_name, window_end(*) [[AS] output_name] 
FROM <stream_name> [ WHERE condition ] 
GROUP BY grouping_element 
[ HAVING condition ] 
[ { TUMBLE ( event_time_field, <window_size> ) | HOP ( event_time_field, <window_size>, <slide> ) } 
[ { WATERMARK | DELAY } <watermark_size>] 
EMIT CHANGES]
<window_size> <slide> <watermark_size> are interval 'quantity unit'

其中窗口的大小、步长、水位线都是以INTERVAL ‘quantity unit’ 间隔时长表示,单位支持如下简称或全称:
image.png
滚动窗口示例:每隔10秒实时统计各个科系新增教师的人数、薪资总额和平均薪资,延后5秒输出结果。
创建带事件时间的流对象instructor2

CREATE STREAM instructor2 (
id text, 
name text, 
dept_name text, 
salary float, 
evt_time timestamp with time zone default now()
);

指定滚动窗口大小为10秒,水位线5秒,按科系统计每个窗口周期内新增教师的人数、薪资总额和平均薪资。

SELECT count(id), sum(salary), avg(salary), dept_name, window_begin(*), window_end(*) 
FROM instructor2 
GROUP BY dept_name 
TUMBLE('evt_time', INTERVAL '10 seconds') 
WATERMARK INTERVAL '5s' 
EMIT CHANGES;

image.png

模拟流数据接入,一条一条往instructor2插入数据,看窗口聚集的输出结果。

ame, dept_name, salary) VALUES('33456', 'Gold', 'Physics', 87000);SELECT pg_sleep(3);INSERT INTO instructor2(id, name, dept_name, salary) VALUES('45565', 'Katz', 'Comp. Sci.', 75000);SELECT pg_sleep(11);INSERT INTO instructor2(id, name, dept_name, salary) VALUES('22222', 'Einstein', 'Physics', 95000);

image.png

滑动窗口示例如下:
创建带事件时间的流对象instructor3

CREATE STREAM instructor3 (
id text, name text, 
dept_name text, 
salary float, 
evt_time timestamp with time zone default now()
);

指定滑动窗口大小为3秒(第一个间隔类型参数),滑动步长为3秒(第二个间隔类型参数),按科系统计每个窗口周期内新增教师的人数、薪资总额和平均薪资。

SELECT count(id), sum(salary), avg(salary), dept_name, window_begin(*), window_end(*) 
FROM instructor3 
GROUP BY dept_name 
HOP('evt_time', INTERVAL '2 seconds', INTERVAL '3 seconds')  
EMIT CHANGES;

模拟流数据接入,每秒一条往instructor3插入数据,看窗口聚集的输出结果。

INSERT INTO instructor3(id, name, dept_name, salary) VALUES('001', 'name1', 'dept1', 100);
SELECT pg_sleep(1);
INSERT INTO instructor3(id, name, dept_name, salary) VALUES('002', 'name2', 'dept1', 200);
SELECT pg_sleep(1);
INSERT INTO instructor3(id, name, dept_name, salary) VALUES('003', 'name3', 'dept1', 300);
SELECT pg_sleep(1);
INSERT INTO instructor3(id, name, dept_name, salary) VALUES('004', 'name4', 'dept1', 400);
SELECT pg_sleep(1);
INSERT INTO instructor3(id, name, dept_name, salary) VALUES('005', 'name5', 'dept1', 500);

第二个间隔类型参数滑动步长与第一个间隔类型参数窗口大小相等时,滑动窗口变成了滚动窗口。

image.png
第二个间隔类型参数滑动步长小于第一个间隔类型参数窗口大小时,数据元素可能被分配到多个窗口,窗口会出现重叠。
image.png
第二个间隔类型参数滑动步长大于第一个间隔类型参数窗口大小时,数据元素可能不属于任何窗口,窗口可能会不连续。
image.png

10.流对象和表对象JOIN

流式数据库的JOIN包括流对象与表对象JOIN、流对象与流对象JOIN,当前版本仅支持流表JOIN。
示例:实时查询新增的教师所属的科系以及所在办公楼信息。
创建科系表,并插入数据

CREATE TABLE department(id text, dept_name text, building text, budget float);INSERT INTO department VALUES('01', 'Biology', 'Watson', 90000), ('02', 'Comp. Sci.', 'Taylor', 100000), ('03', 'Elec. Eng.', 'Taylor', 85000), ('04', 'Finance', 'Painter', 120000), ('05', 'History', 'Painter', 50000), ('06', 'Music', 'Packard', 80000), ('07', 'Physics', 'Watson', 70000);

创建教师信息流对象instructor3

CREATE STREAM instructor3 (id text, name text, dept_name text, salary float);

教师信息流对象instructor3和科系表department做流表join。

SELECT instructor3.id, name,salary, department.dept_name, building FROM instructor3 JOIN department ON instructor3.dept_name = department.dept_name EMIT CHANGES;

往教师信息流对象instructor3中插数据,看流表join的结果显示

INSERT INTO instructor3 VALUES('12121', 'Wu', 'Finance', 90000);
INSERT INTO instructor3 VALUES('15151', 'Mozart', 'Music', 40000);

image.png

04

总结

AntDB-S流式数据库上手比较容易,技术栈简单,纯SQL操作,简单方便,支持数据UPDATE、DELETE、事务ACID以及流表JOIN。

关于AntDB数据库

AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。

相关文章:

AntDB-S流式数据库体验

本文作者&#xff1a;彭冲老师&#xff0c;上一篇彭老师体验了亚信刚发布的社区版AntDB-T数据库&#xff0c;文章如下&#xff1a; AntDB-T交易型数据库体验 本文继续体验AntDB-S流式数据库的&#xff0c;AntDB-S目前还未开放社区版&#xff0c;可以联系AntDB小助手进行体验。…...

CentOS 和 Windows 上添加和删除路由

在 CentOS 上添加和删除路由 要在 CentOS 上添加和删除路由,你可以使用 ip 命令或修改网络配置文件。以下是使用 ip 命令的方法: 添加路由: ip route add <目标网络> via <网关> dev <接口>例如: ip route add 192.168.10.0/24 via 192.168.1.1 dev eth…...

2023年电大秋季招生截止日期 什么时候开始报名

2023年电大网上报名时间为3月份和9月份截止报考&#xff0c;电大每年可以报考两次&#xff0c;春季开始报名时间为12月份左右开始&#xff0c;秋季报名时间预计在6月份左右开始。 2023电大网上报名时间是什么时候 电大报名分为春季和秋季两个季节&#xff0c;一般春季招生时间为…...

滑动窗口问题

给定一个大小为 n≤106 的数组。 有一个大小为 k的滑动窗口&#xff0c;它从数组的最左边移动到最右边。 你只能在窗口中看到 k 个数字。 每次滑动窗口向右移动一个位置。 以下是一个例子&#xff1a; 该数组为 [1 3 -1 -3 5 3 6 7]&#xff0c;k为 3。 窗口位置最小值最…...

电子合同网页预览盖章效果实现

电子合同在现在应用越来越广&#xff0c;需求也就随之产生。 本篇文章主要记录两种网页盖章效果实现方式&#xff0c;自己记录一下&#xff0c; 也给需要的人提供一点思路和帮助。 效果 目录 JqueryCSS实现 原理 1.设置印章图片并隐藏 2.标记盖章位置元素 3.获取目标元素位…...

棋盘覆盖问题

文章目录 棋盘覆盖程序设计程序分析棋盘覆盖 【问题描述】 在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方…...

[CISCN2023]unzip

[CISCN2023]unzip 环境搭建 1.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><form method"post" action"1.php" en…...

基于Html5的在线资料库的设计与实现(asp.NET,SQLServer)

在线资料库系统采用.NET开发平台进行开发&#xff0c;开发工具采用Microsoft Visual Studio 2010集成开发环境&#xff0c;后台编程语言采用C#编程语言来进行编程开发&#xff0c;数据库我们采用当下流行的SQL Server 2008数据库管理系统来存放平台中的数据信息&#xff0c;整个…...

【Vue】二:Vue核心处理---计算属性 监视属性

文章目录 1.计算属性示例2. 监听属性3.补充 1.计算属性示例 实际上计算属性与methods中定义方法基本上没有什么区别&#xff0c;只是计算属性基于响应式依赖缓存&#xff0c;只要数据没有发生改变&#xff0c;计算属性从缓存中取值&#xff0c;只有当数据发送改变&#xff0c;才…...

【Web服务器集群】Nginx网站服务

文章目录 一、Nginx 概述1.什么是 Nginx2.Nginx 的特点3.Nginx 应用场景 二、Nginx 服务基础1.编译安装 Nginx 服务1.1 布置环境1.2 安装依赖包1.3 创建运行用户、组1.4 编译安装 2.Nginx 的运行控制2.1 检查配置文件2.2 启动、停止 Nginx2.3 日志分割以及升级 Nginx 服务2.4 添…...

开始第一个vue项目,环境搭建+html项目运行

【用vue.js&#xff0c;通过script标签导入】 1. 搭建vue脚手架 安装node js安装cnpm&#xff08;淘宝源&#xff09; 【vue】在windows中搭建vue开发环境&#xff08;全网最详细&#xff09;_vue环境搭建_一起来学吧的博客-CSDN博客2a 2. 官网下载地址&#xff1a; 安装 …...

Redis 的数据类型和命令帮助

文章结构 Redis 数据类型1. Redis全局命令&#xff08;跟key有关系&#xff0c;而跟value无关&#xff09;2. StringsGetting and setting StringsManaging counters 3. Lists(L)Basic commandsBlocking commands 4. Sets(S)Basic commands 5. Hashes(H)Basic commands 6. Sort…...

【C++11】智能指针

什么是智能指针&#xff1a; 智能指针是一个类&#xff0c;用来存储指向动态分配对象的指针&#xff0c;负责自动释放动态分配的对象&#xff0c;防止堆内存泄漏。动态分配的资源&#xff0c;交给一个类对象去管理&#xff0c;当类对象声明周期结束时&#xff0c;自动调用析构函…...

三、Go的常用命令以及Go的执行原理

Go的执行原理以及Go的命令 一、Go的源码文件 Go 的源码文件分类&#xff1a; 如上图&#xff0c;分为三类&#xff1a; 1、命令源码文件&#xff1a; 声明自己属于 main 代码包、包含无参数声明和结果声明的 main 函数。 命令源码文件被安装以后&#xff0c;GOPATH 如果…...

ESP32 CAM 模块和 OpenCV 的二维码扫描器

概述 该项目是关于使用 ESP32 CAM 模块和 OpenCV 设计的二维码扫描仪或阅读器。我们将使用 ESP32 摄像头模块和 python 库开发一个程序和设备,我们可以用它来扫描二维码。使用 ESP32 CAM,项目变得更便宜。 QR 码现在已经成为我们日常生活的一部分,因为我们几乎在任何地方都…...

多链路传输技术在火山引擎 RTC 的探索和实践

动手点关注 干货不迷路 传统的数据传输方式大多是利用一个链路、选择设备的默认网卡进行传输&#xff0c;使用这种方式实现实时音视频通话时&#xff0c;如果默认网络出现问题&#xff08;如断网、弱网等&#xff09;&#xff0c;用户的通信就会发生中断或者卡顿&#xff0c;影…...

在Flask中构建API接口

重定向行为 斜杠 以下两个路由的不同之处在于是否使用尾部的斜杠。 第一个路由的URL尾部有一个斜杠&#xff0c;看起来就像一个文件夹&#xff0c;访问一个没有斜杠结尾的URL时&#xff0c;Flask会自动进行重定向&#xff0c;在结尾加上一个斜杠。 第二个路由的URL没有尾部…...

Postgres vs MySQL

主要区别及示例 简而言之&#xff0c;Postgres 和 MySQL 之间的主要区别实际上归结为主索引和辅助索引的实现方式以及数据的存储和更新方式。 让我们进一步探讨这个问题。 但首先... 基础知识 索引是一种数据结构&#xff08;主要是 B 树&#xff09;&#xff0c;允许通过…...

02.IP地址以及静态路由配置

文章目录 IP地址IP地址分类IPV4地址(32位)IPV4地址的分类特殊IP地址 VLSM --- 可变长子网掩码(子网划分)CLDR --- 无类域间路由(汇总)配置静态路由的基础配置静态路由的拓展配置 IP地址 IP地址分类 IPV4(32位二进制构成) — 点分十进制IPV6(128位二进制构成) — 冒分十六进制…...

GD32(STM32)因为中断问题,导致不能进行程序 正常运行

项目中&#xff0c;之前定时器中断就用了个TIM2&#xff0c;但后来程序优化需要再加一个计数定时器TIM6&#xff0c; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // 开启定时器时钟,即内部时钟CK_INT72M RCC_APB1PeriphClockCmd(RCC_APB1Perip…...

华为OD机试真题B卷 Java 实现【统计字符】,附详细解题思路

一、题目描述 输入一行字符&#xff0c;分别统计出包含英文字母、空格、数字和其它字符的个数。 数据范围&#xff1a;输入的字符串长度满足 1 \le n \le 1000 \1≤n≤1000 。 二、输入描述 输入一行字符串&#xff0c;可以有空格。 三、输出描述 统计其中英文字符&#…...

深入理解设计原则之开闭原则(OCP)

系列文章目录 C高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C并发线程编程 OCP&#xff1a;开闭原则 系列文章目录1、开闭原则的定义和解读2、如何理解“对扩展开放&#xff0c;对修改关闭”3、实现开闭原则的方法4、如何在团队协作中保证开闭原则的实…...

【学习随笔】

2022/11/13 HTML :讲完了 css&#xff1a;讲完了 作业&#xff1a;编写登陆界面、整理一下sql优化,对于mybatis不熟练的继续练习 关于MySQL优化的问题? 思路总结&#xff1a;主要考虑数据库优化与SQL语句优化。 1&#xff0c;数据库优化&#xff0c;包括存储引擎的优化&…...

【多路IO复用】select

select: 1.select&#xff1a;当被监听的 fd&#xff08;文件描述符&#xff09;就绪后会返回&#xff0c;但是我们无法知道具体是哪些 fd 就绪了&#xff0c;只能遍历所有的 fd。通常来说某一时刻&#xff0c;就绪的 fd 并不会很多&#xff0c;但是使用 select 必须要遍历所有…...

cuda编程学习——基础知识介绍!干货向(三)

本文主要内容为介绍CUDA编程前的一些基础知识 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 1&#xff1a;并行计算 并行程序可以分为 指令并行&#xff1…...

30 VueComponent 事件的绑定

前言 这是最近的碰到的那个 和响应式相关的问题 特定的操作之后响应式对象不“响应“了 引起的一系列的文章 主要记录的是 vue 的相关实现机制 呵呵 理解本文需要 vue 的使用基础, js 的使用基础 测试用例 用例如下, 我们这里核心关注 事件的处理流程 问题的调试 整个…...

作用域及作用域链

作用域 隔离变量的集合 作用域最大的用处就是隔离变量&#xff0c;不同作用域内的同名变量不会有命名冲突。 作用域类型 全局作用域&#xff0c;函数作用域和块级作用域。 1&#xff09;全局作用域&#xff0c;在整个代码文件中都可以访问的作用域。 2&#xff09;函数作用域…...

深入解析Linux C/C++ 编程中的内存泄漏问题

深入解析Linux C/C 编程中的内存泄漏问题 I. 前言 (Introduction)1.1 文章目的与内容概述 (Purpose and Overview of the Content)1.2 重要性和实用性的说明 (Significance and Practicality Explanation)1.3 数据结构与内存泄漏的基本概念 (Basic Concepts of Data Structure …...

【爬虫第三章】 Python基础

预计更新一、 爬虫技术概述 1.1 什么是爬虫技术 1.2 爬虫技术的应用领域 1.3 爬虫技术的工作原理 二、 网络协议和HTTP协议 2.1 网络协议概述 2.2 HTTP协议介绍 2.3 HTTP请求和响应 三、 Python基础 3.1 Python语言概述 3.2 Python的基本数据类型 3.3 Python的流程控制语句 3…...

电力系统的虚假数据注入攻击和MTD系统研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...