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

ShardingSphere数据分片之分表操作

在这里插入图片描述

1、概述

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。

ShardingShpere的两个核心模块:

  1. ShardingSphere-JDBC:ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。
  2. ShardingSphere-Proxy:ShardingSphere-Proxy 定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。

在开发中实现分库分表的操作,我们一般使用的ShardingSphere-JDBC这个模块。

具体详情请参考官网:https://shardingsphere.apache.org/document/current/cn/overview/
说实话,看这个官网需要一定的编码功底,懂的都懂。😄

ShardingSphere的分库分表操作的逻辑图:
在这里插入图片描述
开发者配置了分库分表策略后,我们只需要操作逻辑表名就可以了。

2、数据分片带来的优缺点

数据分片主要是用来解决海量的数据访问的问题,将数据库采用垂直拆分或者水平拆分的方式将海量、复杂的数据分布到不同的数据库、数据表中,以此来实现专库专用、提高访问性能。

优点:

  1. 提高可扩展性:通过将数据拆分成多个小型数据库,每个数据库仅处理一部分数据,可以在数据增长时动态地添加新的分片,从而提高整个系统的可扩展性。
  2. 提升性能:分片后的每个小型数据库只处理部分数据,减轻了单个节点的压力,从而提升了整个系统的性能。

缺点:

  1. 复杂性增加:数据分片意味着需要更多的数据库来存储和管理数据,这增加了系统的复杂性。同时,对于每个查询,可能需要跨多个数据库进行查找,增加了查询的复杂性。
  2. 并发控制:在分布式系统中,并发控制是一个重要的问题。如果多个节点同时更新同一片数据,就可能导致数据不一致的问题。因此,需要采用并发控制技术来保证数据的正确性。
  3. 数据迁移和恢复:当新增或删除分片时,需要进行数据迁移和恢复。这个过程可能会导致数据的不一致或丢失。因此,需要设计合理的迁移和恢复策略来保证数据的正确性。

我们所使用ShardingSphere组件,通过配置Yaml文件来降低我们的编码复杂度。并发控制何数据迁移与恢复都是需要其他的方式来解决。

3、ShardingSphere分表操作

ShardingSphere的分库分表操作都是基于ShardingSphere-JDBC这个模块来实现。在当前开发中一般都需要和Springboot进行整合,而且只要是流行的框架、组件,SpringBoot一般都会有一个集成的依赖。

3.1、依赖

当前JDK已经到了21,当然我这里使用的还是JDK17,因为JDK21对于SpringBoot 3.1 以下的版本都不友好,会出现一个错误,所以今年刚出的JDK21可以作为爱好先了解,毕竟刚出来很多东西都还需要完善。

<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.1.1</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.14</version>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4.1</version>
</dependency>

3.2、操作方式一:Yaml文件配置

在引入了ShardingSphere-JDBC模块后,可以通过YAML文件配置的方式轻松的配置分表操作。

spring:shardingsphere:props:sql-show: true # 是否展示ShardingSphere的SQL日志datasource: # 配置数据源ds0:username: rootpassword: 123456url: jdbc:mysql://127.0.0.1:3306/mysql_test?serverTimezone=Asia/Shanghaitype: com.zaxxer.hikari.HikariDataSource # 这个参数是必须要有的,否则会报错。driver-class-name: com.mysql.cj.jdbc.Drivernames: ds0 # 所有数据源的名称,用逗号隔开rules: # ShardingSphere规则sharding:sharding-algorithms: # 分片算法配置table-inline: # 分片算法名称,自定义的名称type: INLINE # 分片算法类型props: # 分片算法属性配置algorithm-expression: test_$->{id % 2} # 分片规则指定语句tables: # 分片表配置logic_table_name: # 自定义的逻辑表名称actual-data-nodes: ds0.test_0, ds0.test_1 # 真实的表名称,数据源.表名称,多个表之间用逗号隔开,也支持表达式:ds0.test_$->{0..1}table-strategy: # 表分片策略standard: # 标准分片策略sharding-column: id # 分片的列名sharding-algorithm-name: table-inline # 分片算法mode:type: Memory # 运行模式类型。可选配置:内存模式 Memory、单机模式 Standalone、集群模式 Clusterrepository:type: JDBC

在YAML文件中通过rules.sharding.sharding-algorithms属性来配置数据分片的分片方式,比如说test_$->{id % 2},这个就是按照奇偶的方式对数据进行划分数据。

rules.sharding.sharding-algorithms.type参数主要用于指定分片算法的类型。以下是一些常见的 type 选项:

参数名称参数描述
inline行表达式分片算法。该算法允许你使用行表达式来定义分片规则,适用于简单的分片场景。
hintHint 分片算法。该算法允许你使用 Hint 来指定分片规则,适用于一些特殊的分片场景。
mod_sharding取模分片算法。根据指定的分片数量进行取模运算来进行分片,例如 user_id % 8
range_sharding范围分片算法。允许你定义一个范围来进行分片,适用于范围查询等场景。
hash_sharding哈希分片算法。根据指定的哈希算法进行分片,适用于一些需要一致性哈希的场景。

rules.sharding.tables.<logic_table_name>.table-strategy参数用来配置表分片的策略,可配置的属性如下:

1、standard:标准分片策略。

参数名称参数描述
sharding-column分片列名称
precise-algorithm-class-name精确分片算法类名称,用于 = 和 IN 查询。
range-algorithm-class-name范围分片算法类名称,用于 BETWEEN 查询。

2、complex:复合分片策略。

参数名称参数描述
sharding-columns分片列名称列表,多个列以逗号分隔。
algorithm-class-name复合分片算法类名称。

3、inline:行表达式分片策略。

参数名称参数描述
sharding-column分片列名称。
algorithm-expression分片算法行表达式,例如:${column} % 2。

4、hint:Hint 分片策略。

参数名称参数描述
algorithm-class-nameHint分片算法类名称。

3.3、操作方式二:自定义分片算法

使用YAML文件的配置只能用于简单的分表配置,像test_0,test_1这种简单的,而像某些表名不同的复杂分表操作就不方便使用YAML的配置方式了,此时就需要使用自定义分片策略。

3.3.1、实现StandardShardingAlgorithm接口

自定义分表策略需要实现StandardShardingAlgorithm接口。通过doSharding方法来返回要操作的真实表名。

public class TestShardingAlgorithm implements StandardShardingAlgorithm<Integer> {private static Object[] TABLE_NAME_LIST = null;/*** 实现精确分片* @param collection yaml中定义的真实的表名列表* @param preciseShardingValue 分片的信息*      1、getColumnName(): 获取分片策略中的sharding-column参数的值*      2、getValue(): sharding-column参数所对应类的值* @return 真正需要执行的表名*/@Overridepublic String doSharding(Collection<String> collection, PreciseShardingValue<Integer> preciseShardingValue) {if(TABLE_NAME_LIST == null){TABLE_NAME_LIST = collection.toArray();}int index = preciseShardingValue.getValue() % TABLE_NAME_LIST.length;return (String) TABLE_NAME_LIST[index];}// 实现范围分片@Overridepublic Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Integer> rangeShardingValue) {return collection;}@Overridepublic void init() {// 进行初始化的配置}// 分片策略的 key@Overridepublic String getType() {return "TestShardingAlgorithm";}
}

在单体系统中,doSharding和getType两个方法是必须要编写的,ShardingSphere会根据这两个方法来调用分表策略。

我们也可以使用这种方式来实现动态分表策略,将需要分表的表名存放在一张表中,每次的操作都会进行数据库的访问来确定需要操作的表。存储媒介不光是数据库,还可以是Nacos、Zookeeper等。

3.3.2、配置Yaml文件

spring:shardingsphere:props:sql-show: truedatasource:ds0:username: rootpassword: 123456url: jdbc:mysql://127.0.0.1:3306/mysql_test?serverTimezone=Asia/Shanghaitype: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Drivernames: ds0rules:sharding:sharding-algorithms:table-inline:type: TestShardingAlgorithmprops:algorithm-class-name: com.tt.shardingpheredemo.config.TestShardingAlgorithmtables:t_user:actual-data-nodes: ds0.test_0, ds0.test_1# 分表策略table-strategy:standard:sharding-column: idsharding-algorithm-name: table-inlinemode:type: Memoryrepository:type: JDBCmain:banner-mode: off

自定义分片策略的引入需要修改rules.sharding.sharding-algorithms参数中的typeprops.algorithm-class-name两个参数。
type参数的值一定要是自定义策略类中的getType()返回值。

3.3.3、配置分片类载入文件

当我们完成上述的操作后,按照逻辑来说是没问题了的,但是,世事有例外😏,启动项目的时候直接报错:

No implementation class load from SPI `org.apache.shardingsphere.sharding.spi.ShardingAlgorithm` with type `TestShardingAlgorithm`.

如果type这个参数不是和getType()方法的值一致,也会报这个错误。

报这个错误的原因是TestShardingAlgorithm这个类没有被加载进程序,ShardingSphere的底层基于Java SPI机制。

我们不妨来看看StandardShardingAlgorithm其他的实现类是如何实现的。
在这里插入图片描述
StandardShardingAlgorithm的实现类还是不少的,其中就有上面说的几种分片策略。

在ShardingSphere的源码中,我们看到这几种分片策略都不是通过SpringBoot的注入方式来加载入项目的,而是通过SPI机制来加载入项目,在源码中有一个org.apache.shardingsphere.sharding.spi.ShardingAlgorithm文件,这个文件存放着ShardingSphere所提供的分片策略方式。

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#org.apache.shardingsphere.sharding.algorithm.sharding.inline.InlineShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.mod.ModShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.mod.HashModShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.range.VolumeBasedRangeShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.range.BoundaryBasedRangeShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.datetime.AutoIntervalShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.datetime.IntervalShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.classbased.ClassBasedShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.complex.ComplexInlineShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.hint.HintInlineShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.cosid.CosIdModShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.cosid.CosIdIntervalShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.cosid.CosIdSnowflakeIntervalShardingAlgorithm

所以我们想要使用自定义的分片策略,那么就要使用源码中的方式将自定义的分片策略类加载入系统,使用Spring Boot的@Component方式是没有用的。

我们需要在项目的resources目录下创建一个同名的properties文件,来存放自定义的分片策略类的全限定名。
在这里插入图片描述
org.apache.shardingsphere.sharding.spi.ShardingAlgorithm文件一定要在META_INF.services目录下,因为源码中的文件就在这个目录下。

3.4、测试

3.4.1、实体类配置

因为系统中集成了Mybatis-plus这个组件,所以在编码上也会轻松很多,Dao层、Service层都和日常开发一样的,唯一不同的就是Entity上。

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "logic_table_name")
public class Test{@TableId(type = IdType.AUTO)private int id;private String testName;private int abc;}

实体类的主要不同就在于@TableName的value值。
value值不再指向的是数据库中的真实表名,而是指向ShardingSphere配置中的逻辑表名。
在这里插入图片描述

3.4.2、数据库

两张表:test_1和test_1。

CREATE TABLE `test_0` (`id` int NOT NULL AUTO_INCREMENT,`test_name` varchar(255) NOT NULL,`abc` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;CREATE TABLE `test_1` (`id` int NOT NULL AUTO_INCREMENT,`test_name` varchar(255) NOT NULL,`abc` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

3.4.3、测试结果

本次测试采用奇偶分片策略,分片键为id
在这里插入图片描述
test_0表中存放了id为偶数的数据,test_1表中存放了id为奇数的数据。

4、总结

ShardingSphere虽然支持市面上大部分的分库分表方式,也是市面上当前最火的分库分表组件之一,但是:

  • ShardingSphere的配置相对复杂,需要用户具备一定的数据库和中间件知识。配置过程中需要考虑分片键的选择、分片算法的设计、数据的迁移等因素,这些都需要用户进行深入的思考和规划。
  • 学习成本高:由于ShardingSphere是一个相对复杂的系统,用户需要花费一定的时间和精力来学习它的原理、配置和使用方法。这对于一些新手来说可能是一个挑战。

在这里插入图片描述

相关文章:

ShardingSphere数据分片之分表操作

1、概述 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上…...

基于ssm鲸落文化线上体验馆论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本鲸落文化线上体验馆就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信…...

LeetCode Hot100 131.分割回文串

题目&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 方法&#xff1a;灵神-子集型回溯 假设每对相邻字符之间有个逗号&#xff0c;那么就看…...

SAP UI5 walkthrough step9 Component Configuration

在之前的章节中&#xff0c;我们已经介绍完了MVC的架构和实现&#xff0c;现在我们来讲一下&#xff0c;SAPUI5的结构 这一步&#xff0c;我们将所有的UI资产从index.html里面独立封装在一个组件里面 这样组件就变得独立&#xff0c;可复用了。这样&#xff0c;无所什么时候我…...

【数据结构和算法】--- 栈

目录 栈的概念及结构栈的实现初始化栈入栈出栈其他一些栈函数 小结栈相关的题目 栈的概念及结构 栈是一种特殊的线性表。相比于链表和顺序表&#xff0c;栈只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的…...

CentOS7.0 下rpm安装MySQL5.5.60

下载 下载路径: MySQL :: Download MySQL Community Server -->looking for the latest GA version-->5.5.60 此压缩包中有多个rpm包 有四个不是必须的,只需安装这三个 MySQL-server-5.5.60-1.el6.x86_64 MySQL-devel-5.5.60-1.el6.x86_64 MySQL-client-5.5.60-1.el6.x8…...

智慧能源:数字孪生压缩空气储能管控平台

压缩空气储能在解决可再生能源不稳定性和提供可靠能源供应方面具有重要的优势。压缩空气储能&#xff0c;是指在电网负荷低谷期将电能用于压缩空气&#xff0c;在电网负荷高峰期释放压缩空气推动汽轮机发电的储能方式。通过提高能量转换效率、增加储能密度、快速启动和调节能力…...

【链表OJ—反转链表】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 1、反转链表题目&#xff1a; 2、方法讲解&#xff1a; 解法一&#xff1a; 解法二&#xff1a; 总结 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太…...

TCP一对一聊天

客户端 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io…...

基于Java的招聘系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…...

spring boot整合mybatis进行部门管理管理的增删改查

部门列表查询&#xff1a; 功能实现&#xff1a; 需求&#xff1a;查询数据库表中的所有部门数据&#xff0c;展示在页面上。 准备工作&#xff1a; 准备数据库表dept&#xff08;部门表&#xff09;&#xff0c;实体类Dept。在项目中引入mybatis的起步依赖&#xff0c;mysql的…...

微软 Power Platform 零基础 Power Pages 网页搭建高阶实际案例实践(四)

微软 Power Platform 零基础 Power Pages 网页搭建教程之高阶案例实践学习&#xff08;四&#xff09; Power Pages 实际案例学习进阶 微软 Power Platform 零基础 Power Pages 网页搭建教程之高阶案例实践学习&#xff08;四&#xff09;1、新增视图&#xff0c;添加List页面2…...

如何在任何STM32上面安装micro_ros

就我知道的&#xff1a;micro-ros只能在特定的昂贵的开发板上面运行&#xff0c;但是偶然发现了这个文章&#xff0c;似乎提供了一个全新的方式来在ros2和单片机之间通讯&#xff0c;如果能够这样肯定也能够提高效率&#xff0c;但即使不行&#xff0c;使用串口库也应该比较简单…...

肖sir__ 项目讲解__项目数据

项目时间&#xff1a; 情况一&#xff1a;项目时间开始到上线的时间&#xff0c;这个时间一般比较长&#xff08;一年&#xff0c;二年&#xff0c;三年&#xff09; 情况二&#xff1a;项目的版本的时间或则是周期&#xff08;1个月&#xff0c;2个月&#xff0c;3个月&…...

微服务实战系列之J2Cache

前言 经过近几天陆续发布Cache系列博文&#xff0c;博主已对业界主流的缓存工具进行了基本介绍&#xff0c;当然也提到了一些基本技巧。相信各位盆友看见这么多Cache工具后&#xff0c;在选型上一定存在某些偏爱&#xff1a; A同学说&#xff1a;不管业务千变万化&#xff0c;…...

12.ROS导航模块:gmapping、AMCL、map_server、move_base案例

目录 1 导航概述 2 导航简介 2.1 导航模块简介 1.全局地图 2.自身定位 3.路径规划 4.运动控制 5.环境感知 2.2 导航坐标系odom、map 1.简介 2.特点 3.坐标系变换 2.3 导航条件说明 1.硬件 2.软件 3 导航实现 3.1 创建本篇博客的功能包 3.2 建图--gmapping 3.…...

C++中string类的使用

一.string类 1.1为什么学习string类&#xff1f; C 语言中&#xff0c;字符串是以 \0 结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c; C 标准库中提供了一些 str 系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合OOP 的思想&#x…...

LeeCode每日刷题12.8

搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: …...

硕士毕业论文格式修改要点_word

目录 0、最开始要做的事情1、更改样式&#xff08;先善器&#xff09;2、多级标题&#xff08;解决自动更新问题必要的基础设置&#xff09;2、插入图片&#xff08;1&#xff09;设置一个图片样式——“无间隔”&#xff08;2&#xff09;插入题注&#xff08;3&#xff09;修…...

远红外温和护理,一贴缓解痛风不适

在冬天&#xff0c;很多人都会因为痛风等原因引起的关节炎症而感到不适&#xff0c;因为关节疼痛、肢体麻木等问题会对生活质量造成很大的影响。市场上缓解关节酸痛的护理品很多&#xff0c;常见的应该还是关节贴&#xff0c;我现在用的就是何浩明关节痛风贴。 相比于同类产品&…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...