ShardingSphere-JDBC 之数据分片详细讲解

news2024/9/23 5:19:47

文章目录

    • 单一节点存储问题
    • 数据分片
      • 垂直分片
      • 水平分片
    • ShardingSphere-JDBC 数据分片核心概念
      • 表相关概念
      • 数据节点
      • 分片
      • 行表达式
      • 分布式主键
    • ShardingSphere-JDBC 数据分片原理
    • ShardingSphere-JDBC 数据分片实现示例
      • 1、数据库表创建
      • 2、引入依赖
      • 3、配置参数
      • 4、代码示例

ShardingSphere 数据分片模块的主要设计目标是尽量像使用一个数据库表一样使用 水平分片之后的数据库表集群。

原文链接:ShardingSphere-JDBC 之数据分片
文中示例源码请关注 “Qin的学习营地”,回复:【ShardingShpere-JDBC之数据分片

单一节点存储问题

传统数据存储方案是将数据集中存储至单一节点,在性能、可用性和运维成本这三方面已经难于满足海量数据的场景。

  1. 从性能方面来说,由于关系型数据库大多采用 B+ 树类型的索引,在数据量超过阈值的情况下,索引深度的增加也将使得磁盘访问的 IO 次数增加,进而导致查询性能的下降;同时,高并发访问请求也使得集中式数据库成为系统的最大瓶颈。
  2. 从可用性的方面来讲,服务化的无状态性,能够达到较小成本的随意扩容,这必然导致系统的最终压力都落在数据库之上。 而单一的数据节点,或者简单的主从架构,已经越来越难以承担。数据库的可用性,已成为整个系统的关键。
  3. 从运维成本方面考虑,当一个数据库实例中的数据达到阈值以上,对于 DBA 的运维压力就会增大。 数据备份和恢复的时间成本都将随着数据量的大小而愈发不可控。一般来讲,单一数据库实例的数据的阈值在 1TB 之内,是比较合理的范围。

数据分片

数据分片指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。

  • 分库是按照一定规则将整个数据库中的数据划分到不同的物理数据库中。分库能够有效的分散对数据库单点的访问量,提高数据库的性能和扩展性。
  • 分表是按照一定规则将一张表中的数据划分到不同的物理表中(分表都在同一个物理数据库中),分表的目标是通过将大表拆分成多个小表,以便更容易地管理和维护索引,提高索引的效率,减轻单一表的负担,优化对大表的查询性能,提高数据库查询性能。

通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。 数据分片的拆分方式又分为垂直分片和水平分片。

垂直分片

按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。 下图展示了根据业务需要,将用户表和订单表垂直分片到不同的数据库的方案。

垂直分片往往需要对架构和设计进行调整。通常来讲,是来不及应对互联网业务需求快速变化的;而且,它也并无法真正的解决单点瓶颈。 垂直拆分可以缓解数据量和访问量带来的问题,但无法根治。如果垂直拆分之后,表中的数据量依然超过单节点所能承载的阈值,则需要水平分片来进一步处理。

水平分片

水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将所有数据分散至多个库或表中。 例如:根据主键分片,偶数主键的记录放入 0 库(或表),奇数主键的记录放入 1 库(或表),如下图所示。
在这里插入图片描述
水平分片从理论上突破了单机数据量处理的瓶颈,并且扩展相对自由,是数据分片的标准解决方案。

ShardingSphere-JDBC 数据分片核心概念

表相关概念

逻辑表

  • 单表水平拆分后的所有分表的逻辑名称,是 SQL 中表的逻辑标识。 例:订单数据根据主键尾数拆分为 10 张表,分别是 t_order_0t_order_9,他们的逻辑表名为 t_order

真实表

  • 数据库中在水平拆分后的真实存在的物理表。 上述示例中的 t_order_0t_order_9 就是真实表。

绑定表

  • 指分片规则一致的一组分片表。 使用绑定表进行多表关联查询时,必须使用分片键进行关联,否则会出现笛卡尔积关联或跨库关联,从而影响查询效率。 例如:t_order 表和 t_order_item 表,均按照 order_id 分片,并且使用 order_id 进行关联,则此两张表互为绑定表关系。 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
  • 比如两张主表 t_order_0 和 t_order_1 表,两张子表 t_order_item_0 和 t_order_item_1。绑定之后关联只会出现 t_order_0 和 _order_item_0 关联,t_order_1 和 t_order_item_1 关联,不会出现 t_order_0 和 _order_item_1 关联,t_order_1 和 t_order_item_0 关联的情况。

广播表

  • 指所有的数据源(库)中都存在的表,表结构及其数据在每个数据库中均完全一致。 适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

单表

  • 指所有的分片数据源中仅唯一存在的表。 适用于数据量不大且无需分片的表。

  • 注意:符合以下条件的单表会被自动加载:

    • 数据加密、数据脱敏等规则中显示配置的单表

    • 用户通过 ShardingSphere 执行 DDL 语句创建的单表

  • 其余不符合上述条件的单表,ShardingSphere 不会自动加载,用户可根据需要配置单表规则进行管理。

数据节点

数据节点是数据分片的最小单元,由数据源(库)名称和真实表组成。 例:ds_0.t_order_0。可分为均匀分布和自定义分布两种形式。

均匀分布

  • 指数据表在每个数据源内呈现均匀分布的形式, 例如:

    db0
      ├── t_order0
      └── t_order1
    db1
      ├── t_order0
      └── t_order1
    
  • 数据节点的配置如下:

    db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
    

自定义分布

  • 指数据表呈现有特定规则的分布, 例如:

    db0
      ├── t_order0
      └── t_order1
    db1
      ├── t_order2
      ├── t_order3
      └── t_order4
    
  • 数据节点的配置如下:

    db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4
    

分片

分片规则中配置的真实表、分片列和分布式序列需要和数据库中的列保持大小写一致。

分片键

  • 用于将数据库(表)水平拆分的数据库字段。 例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL 中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,Apache ShardingSphere 也支持根据多个字段进行分片。

分片算法

用于数据分片的算法,支持 =>=<=><BETWEENIN 进行分片。 分片算法可由开发者自行实现,也可使用 Apache ShardingSphere 内置的分片算法语法糖,灵活度非常高。

  • 自动化分片算法

    分片算法语法糖,用于便捷的托管所有数据节点,使用者无需关注真实表的物理分布。 已实现的分片算法包括取模、哈希、范围、时间等常用分片算法。

  • 自定义分片算法

    提供接口让应用开发者自行实现与业务实现紧密相关的分片算法,并允许使用者自行管理真实表的物理分布。 自定义分片算法又分为:

    • 标准分片算法:用于处理使用单一键作为分片键的 =INBETWEEN AND><>=<= 进行分片的场景。
    • 复合分片算法:用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。
    • Hint 分片算法:用于处理使用 Hint 行分片的场景。

分片策略

  • 包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。 真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。

强制分片路由

  • 对于分片字段并非由 SQL 主键而是其他外置条件决定的场景,可使用 SQL Hint 注入分片值。 例:按照员工登录主键分库,而数据库中并无此字段。 SQL Hint 支持通过 Java API 和 SQL 注释两种方式使用。

行表达式

  • 行表达式是为了解决配置的简化与一体化这两个主要问题,通过行表达式可以有效地简化数据节点配置工作量。
  • 行表达式作为字符串由两部分组成,分别是字符串开头的对应 SPI 实现的 Type Name 部分和表达式部分。 以 <GROOVY>t_order_${1..3} 为例,其被 <> 符号包裹GROOVY 为 Type Name,字符串 t_order_${1..3} 为表达式部分。当行表达式不指定 Type Name 时,例如 t_order_${1..3},行表示式默认将使用 InlineExpressionParser SPI 的 GROOVY 实现来解析表达式。
  • 行表达式的使用非常直观,只需要在配置中使用 ${ expression }$->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。行表达式的内容使用的是 Groovy 的语法,Groovy 能够支持的所有操作,行表达式均能够支持。

分布式主键

  • 传统数据库软件开发中,主键自动生成技术是基本需求。而各个数据库对于该需求也提供了相应的支持,比如 MySQL 的自增键,Oracle 的自增序列等。 数据分片后,不同数据节点生成全局唯一主键是非常棘手的问题。同一个逻辑表内的不同实际表之间的自增键由于无法互相感知而产生重复主键。 虽然可通过约束自增主键初始值和步长的方式避免碰撞,但需引入额外的运维规则,使解决方案缺乏完整性和可扩展性。
  • 目前有许多第三方解决方案可以完美解决这个问题,如 UUID 等依靠特定算法自生成不重复键,或者通过引入主键生成服务等。为了方便用户使用、满足不同用户不同使用场景的需求, Apache ShardingSphere 不仅提供了内置的分布式主键生成器,例如 UUID、SNOWFLAKE,还抽离出分布式主键生成器的接口,方便用户自行实现自定义的自增主键生成器。

ShardingSphere-JDBC 数据分片原理

ShardingSphere 的 3 个产品的数据分片主要流程是完全一致的,按照是否进行查询优化,可以分为 Standard 内核流程和 Federation 执行引擎流程。 Standard 内核流程由 SQL 解析 => SQL 路由 => SQL 改写 => SQL 执行 => 结果归并 组成,主要用于处理标准分片场景下的 SQL 执行。 Federation 执行引擎流程由 SQL 解析 => 逻辑优化 => 物理优化 => 优化执行 => Standard 内核流程 组成,Federation 执行引擎内部进行逻辑优化和物理优化,在优化执行阶段依赖 Standard 内核流程,对优化后的逻辑 SQL 进行路由、改写、执行和归并。
在这里插入图片描述

SQL 解析

  • 分为词法解析和语法解析。 先通过词法解析器将 SQL 拆分为一个个不可再分的单词。再使用语法解析器对 SQL 进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。

SQL 路由

  • 根据解析上下文匹配用户配置的分片策略,并生成路由路径(定位到物理分库分表)。目前支持分片路由和广播路由。

SQL 改写

  • 将 SQL 改写为在真实数据库中可以正确执行的语句(逻辑表 sql —> 物理表 sql)。SQL 改写分为正确性改写和优化改写。

SQL 执行

  • 通过多线程执行器异步执行。

结果归并

  • 将多个执行结果集归并以便于通过统一的 JDBC 接口输出。结果归并包括流式归并、内存归并和使用装饰者模式的追加归并这几种方式。

查询优化

  • 由 Federation 执行引擎(开发中)提供支持,对关联查询、子查询等复杂查询进行优化,同时支持跨多个数据库实例的分布式查询,内部使用关系代数优化查询计划,通过最优计划查询出结果。

ShardingSphere-JDBC 数据分片实现示例

以搭建 spring-boot 项目为例。

1、数据库表创建

  1. 创建数据库:创建 db_user_0、db_user_1 两个数据库

    CREATE DATABASE db_user
      CHARACTER SET utf8mb4
      COLLATE utf8mb4_general_ci;
    
  2. 创建数据表:分别在每个数据库下创建两张分表:user_info_0、user_info_1

    CREATE TABLE `user_info_1` (
      `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
      `customer_id` bigint(20) NOT NULL COMMENT '外部客户id',
      `user_id` bigint(20) NOT NULL COMMENT '用户id',
      `name` varchar(16) DEFAULT NULL COMMENT '用户名',
      `age` int(8) DEFAULT '0' COMMENT '年龄',
      `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `idx_cid` (`customer_id`),
      UNIQUE KEY `idx_uid` (`user_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';
    
  3. 每个表中插入数据

    INSERT INTO `db_user_0`.`user_info_0` SET `customer_id`=0, `user_id`=0, `name`="00号",`age`=18
    INSERT INTO `db_user_0`.`user_info_1` SET `customer_id`=0, `user_id`=1, `name`="01号",`age`=18
    INSERT INTO `db_user_1`.`user_info_0` SET `customer_id`=1, `user_id`=0, `name`="10号",`age`=18
    INSERT INTO `db_user_1`.`user_info_1` SET `customer_id`=1, `user_id`=1, `name`="10号",`age`=18
    

2、引入依赖

这里学习使用 ShardingSphere-JDBC,引入 ShardingSphere-JDBC 启动器;而这是操作数据库的中间件,需要引入 mysql 数据库的 JDBC 驱动包。使用到数据库,最好还配置数据库连接池,ShardingSphere-JDBC 自带 HikariCP 连接池,这里还是使用 Druid 连接池,所以引入 Druid 依赖包。同时整合mybatis。

最终用到的技术栈为:springboot + mybatis + sharding-jdbc + mysql + druid,引入依赖如下:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.38</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.13</version>
</dependency>

3、配置参数

1、ShardingSphere-JDBC 配置,需要配置 mysql 相关的参数信息,因为 ShardingSphere-JDBC 是增强版 JDBC 驱动,所以会在 ShardingSphere-JDBC 相关配置中配置数据源信息,使用 ShardingSphere-JDBC 进行分库分表设计。主要配置有:

  1. 需要数据源相关配置(包含连接池,驱动,连接地址,用户名,密码);
  2. 分片策略相关配置(包括分库、分表的分片键和分片算法)。
######## 数据源配置  ########
## 数据源(库)起别名,方便后续配置,多个数据源用逗号隔开
spring.shardingsphere.datasource.names=ds0,ds1
## 数据源 ds0 配置
# 数据库连接池配置
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
# 数据库驱动配置
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
# 数据库连接地址配置
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/db_user_0
# 数据库连接用户名
spring.shardingsphere.datasource.ds0.username=root
# 数据库连接密码
spring.shardingsphere.datasource.ds0.password=root
## 数据源 ds01 配置
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/db_user_1
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root

######## 数据分片配置  ########
## 数据节点配置,数据源和分表之间通过 “.” 连接,笛卡尔积组合:ds0.user_info_0、ds0.user_info_1、ds1.user_info_0、ds1.user_info_1
spring.shardingsphere.sharding.tables.user_info.actual-data-nodes=ds$->{0..1}.user_info_$->{0..1}
## 数据源分片策略:分库。这里采用行表达式的形式设置(inline)
# 分片键
spring.shardingsphere.sharding.tables.user_info.database-strategy.inline.sharding-column=customer_id
# 分片算法
spring.shardingsphere.sharding.tables.user_info.database-strategy.inline.algorithm-expression=ds$->{customer_id % 2}
## 表分片策略:分表。这里采用行表达式的形式设置(inline)
spring.shardingsphere.sharding.tables.user_info.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.user_info.table-strategy.inline.algorithm-expression=user_info_$->{user_id % 2}

## 打印 sql 语句
spring.shardingsphere.props.sql.show=true

2、mybatis 配置

# 配置 sql.xml 文件扫描路径
mybatis.mapper-locations=classpath:mapper/**/*.xml

4、代码示例

操作数据库的mapper相关代码不贴上了,使用mybatis插件生成即可。

1、Repository

@Repository
public class UserInfoRepo {

    @Autowired
    private UserInfoMapper userInfoMapper;

    public List<UserInfo> queryUserInfo(Long customerId, Long userId){
        UserInfoExample example = new UserInfoExample();
        UserInfoExample.Criteria criteria = example.createCriteria();
        if (null != customerId){
            criteria.andCustomerIdEqualTo(customerId);
        }
        if (null != userId){
            criteria.andUserIdEqualTo(userId);
        }
        return userInfoMapper.selectByExample(example);
    }
}

2、Service

@Service
public class UserInfoService {

    @Autowired
    private UserInfoRepo userInfoRepo;

    public void queryUserInfo(Long  cutomerId, Long userId){
        List<UserInfo> userInfos = userInfoRepo.queryUserInfo(cutomerId, userId);
        if (null != userInfos && !userInfos.isEmpty()){
            userInfos.stream().forEach(System.out::println);
        } else {
            System.out.println("无记录");
        }
    }
}

3、测试运行

@SpringBootTest
class ShardingDemoApplicationTests {

    @Autowired
    private UserInfoService userInfoService;

    @Test
    public void test(){
        userInfoService.queryUserInfo(0L, 0L);
    }
}

4、运行结果:可以看到逻辑库表sql和最后定位到的物理分库分表sql语句。
在这里插入图片描述
如果入参 customerId 设为 NULL,查看执行结果:没有传入数据库的分片键值时,会扫描每个为物理分库,再定位物理分表查询结果。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA实现平衡小车(文末开源!!)

FPGA平衡小车 一. 硬件介绍 底板资源: TB6612电机驱动芯片 * 2 MPU6050陀螺仪 WS2812 RGB彩色灯 * 4 红外接收头 ESP-01S WIFI 核心板 微相 A7_Lite Artix-7 FPGA开发板 电机采用的是平衡小车之家的MG310(GMR编码器)电机。底板上有两个TB6612芯片&#xff0c;可以驱动…

Python运维监控系统之架构设计

说起Python这门编程语言的作用&#xff0c;可以列举很多方面&#xff0c;其实每一门流行的编程语言都可以列举很多方面&#xff0c;但是要说起Python的主要领域&#xff0c;莫过于运维监控方面&#xff0c;在这方面有大量优秀的开源运维系统。 虽然有很多优秀的开源运维监控系统…

基于springboot实现智能热度分析和自媒体推送平台系统项目【项目源码】

基于springboot实现自媒体社区平台系统演示 系统开发平台 在该自媒体分享网站中&#xff0c;Eclipse能给用户提供更多的方便&#xff0c;其特点一是方便学习&#xff0c;方便快捷&#xff1b;二是有非常大的信息储存量&#xff0c;主要功能是用在对数据库中查询和编程。其功能…

《微信小程序开发从入门到实战》学习十九

3.3 开发创建投票页面 3.3.7 wx:for列表渲染 接下来为创建的投票页面添加一个“添加选项”的功能。需要用户输入文字&#xff0c;应该使用input组件。头投票的数量是不确定的&#xff0c;面对不确定数量的组件的情况时&#xff0c;可以使用wx:for属性对组件进行列表渲染。 使…

windows pgsql 数据库 数据目录更改

一.先停止postgres服务 cmd命令 services.msc找到服务停止 二.修改注册表 cmd命令 regedit找到路径 \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\postgresql-x64-13 将“&#xff0d;D”后的目录名修改为新的数据目录位置即可&#xff0c;如果目录路径中含有…

【C++】泛型编程 ⑦ ( 类模板常用用法 | 类模板声明 | 类模板调用 | 类模板作为函数参数 )

文章目录 一、类模板基础用法1、类模板声明定义2、类模板使用3、类模板做函数参数 二、完整代码示例1、代码示例2、执行结果 一、类模板基础用法 1、类模板声明定义 上一篇博客中 , 【C】泛型编程 ⑥ ( 类模板 | 类模板语法 | 代码示例 ) 讲解了模板类的基础语法 , 模板类声明如…

23 - 如何优化JVM内存分配?

JVM 调优是一个系统而又复杂的过程&#xff0c;但我们知道&#xff0c;在大多数情况下&#xff0c;我们基本不用去调整 JVM 内存分配&#xff0c;因为一些初始化的参数已经可以保证应用服务正常稳定地工作了。 但所有的调优都是有目标性的&#xff0c;JVM 内存分配调优也一样。…

计算机网络的标准化工作及相关组织

一、国际化组织 计算机网络的标准化工作由一些主要的组织来进行管理和推动。以下是几个主要的计算机网络标准化的国际组织及其相关的标准&#xff1a; 1. 国际标准化组织&#xff08;ISO&#xff09;&#xff1a;国际标准化组织负责制定各种行业的标准&#xff0c;包括计算机…

Linux性能分析——TOP命令详解

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强公司&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

网络割接用VRRP替换HSRP

如图3-11所示&#xff0c;C6500作为核心层设备上行连接出口路由器NE40E-X3&#xff0c;下行连接接入层设备CE6800。C6500上配置HSRP实现冗余备份网关&#xff0c;同时在二层网络部署MSTP破除环路。 总体思路 HSRP为CISCO私有协议&#xff0c;CE系列交换机&#xff08;以CE1280…

基于go标准分层架构项目设计实现

基于go标准分层架构项目设计实现 缘起 个人博客网址 最近主要看了两方面知识&#xff0c;一方面是技术相关的&#xff0c;如何设计一个比较好的后端架构项目代码&#xff1b;一方面是非技术相关的&#xff0c;如何写一篇好的技术文章&#xff0c;能够让他人读懂并有收获。因…

C++ 形参传值和传指针的误解

#include <stdio.h>void swap(int *x, int *y);main(){ int a 5, b 9;int *pp &a;int *kk &b;swap(pp, kk);printf("a%d\nb%d\n", *pp, *kk);return 0; } void swap(int *x, int *y) {int *t;t x;x y;y t; } 会发现&#xff0c;输出结果并没有…

iptables详解:常用模块的基本使用

目录 tcp扩展模块 multiport扩展模块 iprange扩展模块 connlimit模块 limit扩展模块 udp扩展模块 icmp扩展模块 state扩展模块 限制每分钟接收10个ICMP数据报文 允许10个数据报文快速通过&#xff0c;然后限制每分钟接收1个个ICMP数据报文 限制网络传输的带宽不可以…

VMware——WindowServer2012R2环境mysql5.7.14解压版安装主从复制(图解版)

目录 一、服务器信息二、192.168.132.33主服务器上安装mysql&#xff08;主&#xff09;2.1、环境变量配置2.2、安装2.2.1、修改配置文件内容2.2.2、初始化mysql并指定超级用户密码2.2.3、安装mysql服务2.2.4、启动mysql服务2.2.5、登录用户管理及密码修改2.2.6、开启远程访问 …

【论文复现】QuestEval:《QuestEval: Summarization Asks for Fact-based Evaluation》

以下是复现论文《QuestEval: Summarization Asks for Fact-based Evaluation》&#xff08;NAACL 2021&#xff09;代码https://github.com/ThomasScialom/QuestEval/的流程记录&#xff1a; 在服务器上conda创建虚拟环境questeval&#xff08;python版本于readme保持一致&…

Open AI开发者大会:AI“科技春晚”

ChatGPT的亮相即将满一年之时&#xff0c;OpenAI举行了自己的首次开发者大会。OpenAI首席执行官Sam Altman宣布推出最新的大模型GPT-4 Turbo。正如“Turbo”一词的中文含义“涡轮增压器”一样&#xff0c;本次发布会上&#xff0c;OpenAI的这款最新大模型在长文本、知识库、多模…

【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 3

1、下图中&#xff0c;乐乐家的位置用数对&#xff08;4,3&#xff09;表示&#xff0c;学校在乐乐家西南方向。下列选项中&#xff0c;学校的位置不可能是 A、&#xff08;5,4&#xff09; B、&#xff08;2,2&#xff09; C、&#xff08;2,1&#xff09; D、&#xff…

进程之理解进程的概念

你必须非常努力&#xff0c;才能看起来毫不费力。文章目录 进程的基本概念描述进程——pcbtest_struct pcb的一种task_struct 内容分类 组织进程查看进程通过系统调用获取进程标示符总结 进程的基本概念 课本概念&#xff1a;进程是一个执行实列&#xff0c;正在执行的程序等。…

数据结构 堆

手写堆&#xff0c;而非stl中的堆 如何手写一个堆&#xff1f; //将数组建成堆 <O(n) for (int i n / 2;i;i--) //从n/2开始down down(i); 从n/2元素开始down&#xff0c;最下面一层元素的个数是n/2&#xff0c;其余上面的元素的个数是n/2&#xff0c;从最下面一层到最高层…

【汇编】[bx+idata]的寻址方式、SI和DI寄存器

文章目录 前言一、[bxidata]寻址方式1.1 [bxidata]的含义1.2 示例代码 二、SI和DI寄存器2.1 SI和DI寄存器是什么&#xff1f;2.2 [bxsi]和[bxdi]方式寻址2.3 [bxsiidata]和[bxdiidata] 总结 前言 在汇编语言中&#xff0c;寻址方式是指指令如何定位内存中的数据。BX寄存器与偏…