深入OceanBase内部机制:分区机制构建高可用、高性能的分布式数据库基石

码到三十五 : 个人主页


在数据库技术的发展历程中,随着数据量的不断增长和业务需求的日益复杂,如何高效地存储、查询和处理数据成为了关键挑战。OceanBase作为一款高性能、高可用的分布式关系数据库,通过其独特的分区机制,为这一挑战提供了有力的解决方案。

分区,作为OceanBase数据库架构中的核心概念,是实现数据高效管理和高性能查询的关键。在OceanBase中,分区不仅仅是对数据的简单切分,更是一种智能化的数据管理策略。通过将数据水平拆分成多个物理上独立的单位,并结合多副本技术,OceanBase确保了数据的高可用性、持久性和容错性。
在这里插入图片描述

在本文中,我们将深入探讨OceanBase的分区机制,包括其设计理念、实现方式以及在实际应用中的优势和效果。通过了解OceanBase的分区,读者将能够更好地理解这款数据库如何为企业提供稳定、可靠的数据服务,满足现代业务对于数据存储和处理的严苛要求。

现在,让我们一同揭开OceanBase分区机制的神秘面纱,探索其背后的技术原理和实践应用。

目录

      • 一、分区的基本概念
        • MySQL中的分区
        • OceanBase中的分区
      • 二、OceanBase分区表的优势与劣势
      • 三、OceanBase分区类别及使用
        • 3.1 RANGE 分区
        • 3.2 List 分区
        • 3.3 Hash 分区
        • 3.4 Key 分区
      • 四、二级分区
      • 五、为什么分区键必须是主键/唯一键的一部分
      • 六、OceanBase分区建议
      • 七、索引分区
        • OceanBase索引分区的类型
        • OceanBase索引分区的优势
        • OceanBase索引分区的使用方法

一、分区的基本概念

在数据库管理系统中,分区是一种将数据水平拆分成多个较小的、更易于管理的部分的技术。这个概念在多个数据库系统中都有应用,但具体的实现和细节可能因系统而异。以下是对分区的详细解释,特别是在OceanBase中的实现:

  1. 定义:分区其实就是根据一定的规则,将一个大的表或索引拆分成多个较小的、物理上独立的单位。这些单位在物理存储上是分离的,但在逻辑上仍然被视为一个整体。
  2. 目的:分区的目的主要是为了提高查询性能、方便数据管理、增强数据的可用性和可维护性。通过将数据分散到多个分区中,可以并行处理更多的查询和数据操作,从而提高整体性能。
MySQL中的分区
  1. 物理文件:在MySQL中,分区通常意味着将数据拆分成多个物理文件。每个文件包含表的一部分数据,这些文件在文件系统上是可见的。
  2. 管理:MySQL提供了丰富的分区类型和管理工具,允许用户根据数据的访问模式和使用情况来优化分区策略。
OceanBase中的分区
  1. 物理副本组:与MySQL不同,OceanBase中的每个分区实际上是一个物理副本组。这意味着每个分区不仅包含数据的一部分,还包含这部分数据的多个副本。
  2. 默认三副本:OceanBase默认采用三副本策略,即每个分区有三个物理副本。这种设计提高了数据的冗余性和可用性,确保在部分硬件故障时数据仍然可用。
  3. 高可用性:三副本的设计还允许OceanBase在保持数据一致性的同时,提供高可用性和容错能力。如果一个副本发生故障,其他两个副本仍然可以保证数据的完整性和可用性。
  4. 分布式架构:OceanBase的分布式架构与分区策略紧密结合,使得数据可以在多个节点之间高效分布和处理。这种架构支持水平扩展,能够轻松应对大规模的数据处理和存储需求。

分区在数据库管理系统中是一个重要的概念和技术,它有助于提高系统的性能、可用性和可维护性。在OceanBase中,分区以物理副本组的形式存在,默认采用三副本策略,为分布式数据库环境提供了强大的支持和保障。

在这里插入图片描述

二、OceanBase分区表的优势与劣势

在 MySQL 中,如果让我们在分区表和分库分表之间做选择,肯定很多人会毫不犹豫的选择分库分表,因为分区表虽然底层拆封出了多个物理文件,但是很多的操作其实还是表级,比如DDL,当表切换过程中,锁表影响的是所有分区。而分库分表只会影响部分表;第二就是分区表的负载其实还是集中在独立的实例上,并不能够做打散,而且当对应节点挂掉以后,所有分区都会收到影响,只能依赖后续的高可用。

而 OceanBase 因为本身是分布式数据库,所以它的分区其实更像 MySQL 的分库分表,因为底层通过将分区作为分片副本打散到不同的实例中,对于上层业务来说,并不需要关注底层分区的分布,而底层分区可以通过打散,来实现存储以及负载的均衡,并且某个实例(存在分区leader)宕机,也不会影响其他分区的读写。

所以分区表在分布式数据库中,有如下优势:

  • 1、 负载均衡,可以将分区副本打散到多个节点,并且节点数量越多,越分散。

  • 2、提高可用性,虽然本身集群有高可用机制,但是分区打散以后可以保证在故障恢复的阶段其他的分区请求不受影响。

  • 3、便于数据管理,对于一些类似 TTL 的场景,可以通过 Truncate 分区来快速的清理数据。

  • 4、提高性能,当正确使用分区时,可以使我们每次扫描/加载更少的数据,提高性能以及降低资源利用。

当然,分区表其实也是有隐患的,尤其是当分区使用不合理的时候,那么不仅有可能导致性能下降,甚至导致业务异常。比如 TP 的业务并且基本只会读取当天的数据,创建了天或者月级别的range分区,那么就会导致所有的请求集中到一个分区,出现热点问题。

所以创建合适的分区非常重要。

三、OceanBase分区类别及使用

OceanBase 数据库的基本分区策略包括范围(Range/Range Columns)分区、列表(List/List Columns)分区、哈希(Hash)/Key 分区以及它们之间的组合。

3.1 RANGE 分区

Range 分区是按照某个连续的范围来划分数据区间,每个分区都包含分区表达式值位于给定范围内的行。常用于按年、月或日等时间维度进行分区。

特点:

根据分区键值的范围把数据行存储到表的不同分区中
多个分区的范围是连续的但不重叠。
默认情况下使用VALUES LESS THAN属性,每个分区不包括指定的那个值

适用场景
定期按分区范围清理历史数据
并发不高并且请求范围集中
范围查询

需要注意

  • 1、如果业务的请求会集中在某几个范围内,比如只查当天的数据,并且请求量比较高,那么很容易产生热点问题。

  • 2、如果范围是持续增加而不是固定的,一定不要设置 MAXVALUE分区。因为很可能导致大部分数据聚集在这个分区,并且无法拆分新的分区。

  • 3、如果没有设置MAXVALUE分区,要插入分区表达式内不包含的值,那么一定要提前创建对应的分区,否则会报错。

  • 4、RANGE 分区默认情况下只支持 int 类型

  • 5、如果想要对非整型或者多列分区(比如时间范围),可以使用 Range Columns 分区。

常用的Range定义有下面几种:

直接根据字段范围:PARTITION BY RANGE(store_id)

根据时间年份:PARTITION BY RANGE ( YEAR(purchased))

根据时间戳:PARTITION BY RANGE(UNIX_TIMESTAMP(report_updated))

根据天:PARTITION BY RANGE(TO_DAYS(order_date))

根据时间字段范围:PARTITION BY RANGE COLUMNS(joined)

创建 Range 分区表

CREATE TABLE r (
    id INT NOT NULL,
    ctime DATE NOT NULL DEFAULT '2000-12-31'
)
PARTITION BY RANGE ( YEAR(ctime) ) (
    PARTITION p0 VALUES LESS THAN (1991),
    PARTITION p1 VALUES LESS THAN (1996),
    PARTITION p2 VALUES LESS THAN (2001)
);

创建 Range COLUMNS 分区表

CREATE TABLE rc(
    ctime DATE NOT NULL
)
PARTITION BY RANGE COLUMNS(ctime) (
    PARTITION p0 VALUES LESS THAN ('1960-01-01'),
    PARTITION p1 VALUES LESS THAN ('1970-01-01'),
    PARTITION p2 VALUES LESS THAN ('1980-01-01'),
    PARTITION p3 VALUES LESS THAN ('1990-01-01')
);

现有表创建 Range 分区

ALTER TABLE r PARTITION BY RANGE ( YEAR(ctime) ) (
    PARTITION p0 VALUES LESS THAN (1991),
    PARTITION p1 VALUES LESS THAN (1996),
    PARTITION p2 VALUES LESS THAN (2001)
);

查询分区数据

select * from r partition(p0);

增加分区

ALTER TABLE r ADD PARTITION (PARTITION p3 VALUES LESS THAN(2006));

新增 MAXVALUE 分区

alter table r ADD PARTITION(PARTITION p4 VALUES less than (MAXVALUE));

清空分区

alter table r truncate partition p0;

删除分区

alter table r drop partition p0;
3.2 List 分区

故名思义,List分区是根据给定的值列表将表进行分区,每个分区对应一个列表中的值。它跟range分区有些类似,每个分区都必须显式定义。

特点:

跟range分区有些类似,各分区的列表值不能重复,但是 List 分区数据不需要连续。

适用场景:

定期清理分区内的历史数据
并发不高并且请求范围集中

注意:

  • 1、同range分区,如果业务的请求会集中在某几个值/列表内,并且并发量比较高,那么很容易产生热点问题。

  • 2、如果没有定义的值比较多,一定不要设置 DEFAULT分区。因为很可能导致大部分数据聚集在这个分区,并且无法拆分新的分区。

  • 3、如果没有设置DEFAULT分区,要插入分区表达式内不包含的值,那么一定要提前创建对应的分区,否则会报错,所以一定要提前规划好。

  • 4、如果分区使用表达式,那么结果必须是整型,并且只能引用一列。

  • 5、如果想要对非整型或者多列分区,可以使用 List Columns 分区。

创建 List 分区表

CREATE TABLE l (
    id INT NOT NULL,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION p0 VALUES IN (3,5),
    PARTITION p1 VALUES IN (1,2),
    PARTITION p2 VALUES IN (4,6)
);

创建 List Columns 分区表

CREATE TABLE lc (
    id INT NOT NULL,
    store_id varchar(10)
)
PARTITION BY LIST COLUMNS(store_id) (
    PARTITION p0 VALUES IN ("3","5"),
    PARTITION p1 VALUES IN ("1","2"),
    PARTITION p2 VALUES IN ("4","6")
);

现有表创建 List 分区

alter table l PARTITION BY LIST(store_id) (
    PARTITION p0 VALUES IN (3,5),
    PARTITION p1 VALUES IN (1,2),
    PARTITION p2 VALUES IN (4,6)
);

新增分区

alter table l ADD PARTITION(PARTITION p3 VALUES IN (7,8));

新增 DEFAULT 分区

alter table l ADD PARTITION(PARTITION p3 VALUES IN (DEFAULT));

其他操作等同。

3.3 Hash 分区

Hash 分区是数据库根据用户指定的分区键的哈希算法将行映射到分区,它跟 Range、List 不同,不再需要指定列值存储在哪个分区,这种方式一般情况下会将数据打散的更加均衡。

常规的 HASH 分区非常的简便,通过取模(N = MOD(expr, num))的方式可以让数据更加平均的分布每一个分区。比如4个分区,101会落在P1分区,因为 MOD( 101 , 4 ) = 1。

特点:

HASH 分区通常能消除热点查询,可以充分利用每台机器的资源。

适用场景:

  • 1、没有明显可以分区的特征字段,但数据又非常庞大的表。

  • 2、业务请求是点查或者少量的查询数据。

注意:

1、如果业务有大量的范围查询,那么可能会造成大量的分区扫描,此时分区只会起到反效果。

2、HASH分区的键值必须是一个INT类型的值,或是通过函数可以转为INT类型

创建 Hash 分区表

CREATE TABLE h (
    id INT NOT NULL,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

已有表创建 Hash 分区

alter table h PARTITION BY HASH(store_id) PARTITIONS 4;
3.4 Key 分区

KEY分区其实跟HASH分区差不多,不同点如下:

  • KEY分区允许多列,而HASH分区只允许一列。
  • 如果在有主键或者唯一键的情况下,KEY分区的分区列可不指定,默认为主键或者唯一键,如果没有,则必须显性指定列。
  • KEY分区对象必须为列,而不能是基于列的表达式。
  • KEY分区和HASH分区的算法不一样,PARTITION BY HASH (expr),MOD取值的对象是expr返回的值,而PARTITION BY KEY (column_list),基于的是列的MD5值。

创建 Key 分区

默认不指定列,以主键或者唯一键自动分区

CREATE TABLE k (
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;

指定列创建

CREATE TABLE k2 (
    id INT NOT NULL,
    store_id varchar(10)
)
PARTITION BY KEY(`id`,`store_id`)
PARTITIONS 2;

四、二级分区

二级分区是指在分区表中每个一级分区的基础上,再做一层分区。二级分区和一级分区可以是同一个列,也可以是不同的列。可以实现在一级分区的基础上二次打散的效果。

对于模板化二级分区表来说,定义二级分区后,每个二级分区的命名规则为

( p a r t n a m e ) s ( part_name)s( partname)s(subpart_name)。

例如:p0sp1。

创建二级分区表

CREATE TABLE ts (id INT, purchased DATE)
    PARTITION BY RANGE( YEAR(purchased) )
    SUBPARTITION BY HASH( TO_DAYS(purchased) )
    SUBPARTITIONS 2 (
        PARTITION p0 VALUES LESS THAN (1990),
        PARTITION p1 VALUES LESS THAN (2000),
        PARTITION p2 VALUES LESS THAN MAXVALUE
    );

查询二级分区数据(二级分区创建表达式是 to_days)

obclient [test]> select * from ts partition(p0);
+------+------------+
| id   | purchased  |
+------+------------+
|    1 | 1980-01-20 |
|    3 | 1980-01-22 |
|    2 | 1980-01-21 |
+------+------------+
3 rows in set (0.025 sec)

obclient [test]> select * from ts partition(p0sp0);
+------+------------+
| id   | purchased  |
+------+------------+
|    2 | 1980-01-21 |
+------+------------+
1 row in set (0.014 sec)

obclient [test]> select * from ts partition(p0sp1);
+------+------------+
| id   | purchased  |
+------+------------+
|    1 | 1980-01-20 |
|    3 | 1980-01-22 |
+------+------------+
2 rows in set (0.006 sec)

查询分区明细

SELECT table_name,partition_name,subpartition_name FROM information_schema.partitions;

分区的限制以及常见问题

限制

  • 如果表中存在主键或者唯一键,那么分区键必须是主键或者唯一键或者其中的部分列,主键或者唯一键必须包含分区键。
  • 单表限制 8192 个
  • 集群分区数量限制跟租户内存成正比,大概1G内存能建6000个分区
  • 单分区大小建议不超过 100G

常见问题

A PRIMARY KEY must include all columns in the table’s partitioning function:分区键必须是主键或者唯一键或者其中的部分列,主键或者唯一键必须包含分区键,否则会创建失败。

比如下面两个例子都会失败

案例 1

CREATE TABLE t1 (s1 CHAR(32) PRIMARY KEY, s2 CHAR(32) ) PARTITION BY KEY(s2) PARTITIONS 4;

案例 2

CREATE TABLE t1 (s1 CHAR(32) PRIMARY KEY,  s2 CHAR(32) ) PARTITION BY KEY(s2,s1) PARTITIONS 4;

当主键为 (s1,s2)这样的组合主键时,上面的两个sql可以执行成功。

  • VALUES LESS THAN value must be strictly increasing for each partition:RANGE分区如果指定MAXVALUE分区,增加分区会失败。

  • cannot add partition when DEFAULT partition exists:List 分区如果指定 DEFAULT 分区,增加分区会失败。

  • Table has no partition for value :分区的范围没有包含要插入的值,那么将插入失败。

五、为什么分区键必须是主键/唯一键的一部分

简单来说,这个是索引组织表的限制。之所以对索引组织表有这样的限制,还是基于性能考虑。

假设分区键和主键是两个不同的列或者分区键不包含在主键中,在进行插入操作时,虽然也指定了分区键,但还是需要扫描所有分区才能判断插入的主键值是否违反了唯一性约束。这样的话,效率会比较低下,违背了分区表的初衷。

六、OceanBase分区建议

上面的分区类别中提到了各类分区的使用场景,其实分区怎么用,还是要看业务逻辑。

下面有一些分区使用的建议:

  • 如果是请求量比较高的 TP 业务,不建议使用 range 或者 List 分区,因为很容易产生热点问题。通常建议使用 hash/key 分区,来将请求打散。
  • 如果本身业务逻辑需要根据范围过滤一部分数据(比如时间),那么建议在一级 Range 分区的基础上,再做一层 hash/key 的二级分区。二级分区的数量建议是租户所占用节点数量的倍数。
  • 对分区表进行查询的时候,一定要指定分区键,否则的话没办法用到分区裁剪,会造成分区扫描,这样的话分区不但没有性能提升,反而起到了反效果。
  • hash/key 分区不合适范围扫描,如果这类业务请求比较多,不建议使用 hash/key分区,或者一级分区用 range,二级分区再做 hash/key 分区。
  • 表的数据量不大的话,可以不分区。
  • MAXVALUE 分区和 DEFAULT 分区定义要谨慎,因为后续将无法再扩展新的分区。

七、索引分区

索引分区是指在OceanBase数据库中,根据一定的规则将索引数据拆分成多个部分,每个部分称为一个分区。这些分区可以独立存储、查询和管理,从而提高了数据库的整体性能。

OceanBase索引分区的类型

OceanBase支持多种类型的索引分区,以适应不同的应用场景和需求。主要包括:

    1. 局部分区索引:在创建索引时指定关键字LOCAL的索引为局部索引。它无须指定分区规则,分区属性和主表的属性一致,会跟随主表的分区操作而发生变更。
    1. 全局分区索引:全局索引在创建时指定关键字GLOBAL,可以按照分区规则进行分表。这意味着,不同于局部分区索引依赖于主表的分区方式,全局索引有自己的分区规则。

此外,根据索引键值是否具有唯一性,索引还可以分为唯一索引和非唯一索引。同时,如果分区索引表的分区键是索引列的左前缀,那么该索引被称为前缀索引;反之,则称为非前缀索引。

OceanBase索引分区的优势
  1. 提高查询性能:通过将索引数据分区,OceanBase可以并行处理多个查询请求,从而提高查询性能。同时,分区索引还可以减少数据扫描的范围,进一步加速查询速度。

  2. 方便数据管理:索引分区使得数据管理更加灵活和高效。例如,对于大量的历史数据,可以将其存储在较低的访问频率的分区中,而将经常访问的数据放在更高的访问频率的分区中,从而实现数据的分层管理和优化存储。

  3. 增强数据的可用性:由于每个分区都是独立的存储单位,因此当某个分区发生故障时,其他分区的数据仍然可用。这种设计提高了数据的可用性和容错能力。

OceanBase索引分区的使用方法

下面以一个简单的示例来介绍OceanBase分布式索引的使用方法。

创建分布式表和索引

CREATE TABLE t_user (
  id INT,
  name VARCHAR(50),
  age INT,
  PRIMARY KEY(id)
) DISTRIBUTE BY HASH(id);
CREATE INDEX idx_name ON t_user(name) LOCAL;

上述代码创建了一个名为t_user的分布式表,其中id字段作为主键,并采用哈希算法进行数据分布。同时,创建了一个名为idx_name的分布式索引,它只在本地节点上存储索引数据。



听说...关注下面公众号的人都变牛了,纯技术,纯干货 !

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

03 spring-boot+mybatis+jsp 的增删改查的入门级项目

前言 主要是来自于 朋友的需求 项目概况 就是一个 用户信息的增删改查然后 具体到业务这边 使用 mybatis xml 来配置的增删改查 后端这边 springboot mybatis mysql fastjson 的一个基础的增删改查的学习项目, 简单容易上手 前端这边 jsp 的 基础的试题的增删改查 学习项…

Shell脚本学习记录

0.理解Linux文件权限 0.1 Linux安全性 用户的权限是通过创建用户时分配的用户ID(UID)来追踪的,UID是个数值,每个用户都有一个唯一的UID 0.1.1 /etc/passwd文件 Linux系统使用一个专门的文件/etc/passwd来匹配登录名与对应的UID值,该文件包…

本地体验最强开源模型Llama3+Qnw(支持Windows和Mac)

一键运行大模型本地软件(含模型):点击下载 Meta放出Llama3模型了,也应该是这段时间里的一个科技大新闻了。 Llama一直都是开源大语言模型的领头羊驼。 而Llama3又是所有羊驼中最新的领头羊。 可以简单地来看一下官方的对比数据…

Open-Sora:开源版的Sora

项目简介 本项目希望通过开源社区的力量复现Sora,由北大-兔展AIGC联合实验室共同发起,当前我们资源有限仅搭建了基础架构,无法进行完整训练,希望通过开源社区逐步增加模块并筹集资源进行训练,当前版本离目标差距巨大&…

FSMC读取FPGA的FIFO

一、硬件说明 FSMC配置 单片机的代码如下: #define VALUE_ADDRESS_AD1 (__IO uint16_t *)0x60400000while (1){if(!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_8)) //数据非空{data *(__IO uint16_t *)VALUE_ADDRESS_AD1;data2 *(__IO uint16_t *)VALUE_ADDRESS_AD1…

C语言:插入排序

插入排序 1.解释2.步骤3.举例分析示例结果分析 1.解释 插入排序是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采…

Qt中的 tableView 设置 二进制 十六进制 序号表头

二 进制序号 因为QTableView的垂直表头并不支持使用委托来自定义。 相反&#xff0c;可以通过将自定义的QWidget作为QHeaderView的标签来实现这一目标。 代码&#xff1a; #include <QApplication> #include <QMainWindow> #include <QVBoxLayout> #include …

使用LSTM模型对心跳时间序列数据预测(Python代码,ipynb环境)

所用模块版本&#xff1a; matplotlib3.7.1 numpy1.24.4 pandas1.5.3 scikit_learn1.2.2 scipy1.10.1 seaborn0.12.2 statsmodels0.14.0 torch1.13.1 torch2.0.1 wfdb4.1.2 主代码&#xff1a; import itertools import pandas as pd import matplotlib.pyplot as plt #完整…

elasticsearch 常用语法汇总

文章目录 前言elasticsearch 常用语法汇总1. 创建索引2. 检索索引信息3. 删除索引4. 文档操作4.1. 对blog_new索引指定文档ID新增4.2. 对blog_new索引不指定文档ID新增&#xff0c;随机文档ID:4.3. 获取文档4.4. 更新文档4.5. 删除文档 5. 查询5.1. 匹配查询5.2. 范围查询5.3. …

计算机视觉的应用29-卷积神经网络(CNN)中的变种:分组卷积、转置卷积、空洞卷积的计算过程

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用29-卷积神经网络(CNN)中的变种&#xff1a;分组卷积、转置卷积、空洞卷积的计算过程。分组卷积将输入通道分为几组&#xff0c;对每组独立进行卷积操作&#xff0c;以减少计算量和模型参数。转置卷…

vue如何发送请求给后端(包括前后端跨域)

目录 有哪些方法可以发送请求要请求先解决跨域问题代理服务器后端解决跨域问题 axios发送请求vue-resource发送请求 有哪些方法可以发送请求 以前可能了解过&#xff1a; xhr 即&#xff1a;new XMLHttpRequest()jQuery 即&#xff1a;$.get $.postaxios fetch 在vue中特有的…

Leetcode 剑指 Offer II 075.数组的相对排序

题目难度: 简单 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定两个数组&#xff0c;arr1 和 arr2&#xff0c; arr2 中的元…

Java NIO

1. IO分类概述 1.1 阻塞与非阻塞 阻塞&#xff08;Blocking&#xff09;和非阻塞&#xff08;Nonblocking&#xff09;是在计算机编程中用于描述I/O操作的两个重要概念。阻塞与非阻塞描述的是线程在访问某个资源时&#xff0c;在该资源没有准备就绪期间的处理方式。 1、阻塞&a…

Android使用AlertDialog实现弹出菜单

最近又开始捣鼓APP&#xff0c;许多api , class都忘记怎么用了&#xff0c;楼下使用AlertDialog实现个弹出菜单&#xff0c;结果直接crash&#xff0c;查了半天&#xff0c;终于即将&#xff0c;记录一下…… 1 实现代码 AlertDialog.Builder mBuilder new AlertDialog.Builde…

后端工程师——C++工程师如何准备面试?

相比 Java 语言方向,C++ 入门简单,精通难,找工作竞争压力更小,但 C++ 依然是近年来招聘的热门岗位之一。本文将从以下三个方面进行详细讲解,帮助你对 C++ 相关岗位的就业前景、岗位要求、学习路线等有更充分的了解。 C++工程师面试准备 上两篇文章对 C++ 工程师的招聘需求…

SpringCloud系列(17)--将服务消费者Consumer注册进Zookeeper

前言&#xff1a;在上一章节中我们把服务提供者Provider注册进了Zookeeper&#xff0c;而本章节则是关于如何将服务消费者Consumer注册进Zookeeper 1、再次创建一个服务提供者模块&#xff0c;命名为consumerzk-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并…

HPE Aruba Networking推出新一代Wi-Fi 7接入点 助力企业高效应对安全、AI与物联网挑战

HPE ArubaNetworking推出的全新Wi-Fi 7接入点&#xff0c;提供全面的AI就绪边缘IT解决方案&#xff0c;旨在为用户和物联网设备提供安全、高性能的连接服务&#xff0c;以实现数据的捕获和路由&#xff0c;从而满足AI训练和推理需求 休斯顿-2024年4月23日-慧与科技(NYSE: HPE)近…

【golang学习之旅】深入理解字符串string数据类型

系列文章 【golang学习之旅】报错&#xff1a;a declared but not used 【golang学习之旅】Go 的基本数据类型 目录 系列文章使用示例string的底层数据结构关于字符串复制字符串是不可变的如何高效的进行字符串拼接&#xff1f; 使用示例 Go 语言中的字符串只是一个只读的字节…

Spring boot + Redis + Spring Cache 实现缓存

学习 Redis 的 value 有 5 种常用的数据结构 Redis 存储的是 key-value 结构的数据。key 是字符串类型&#xff0c;value 有 5 种常用的数据结构&#xff1a; Redis 的图形化工具 Another Redis Desktop Manager Spring Data Redis Redis 的 Java 客户端。 Spring Cache Spr…

AI工具集:解锁智能新境界,一站式解决你的所有需求!

在这个信息爆炸的时代&#xff0c;我们每天都在与大量的数据和信息打交道。如何高效地处理这些信息&#xff0c;提高工作效率和生活品质&#xff0c;成为了我们亟待解决的问题。而AI工具集(AI-321.com)的出现&#xff0c;无疑为我们提供了一把解锁智能新境界的钥匙。 AI-321 | …
最新文章