DIY 3 种分库分表分片算法,自己写的轮子才吊!

大家好,我是小富~

前言

本文是《ShardingSphere5.x分库分表原理与实战》系列的第六篇,书接上文实现三种自定义分片算法。通过自定义算法,可以根据特定业务需求定制分片策略,以满足不同场景下的性能、扩展性或数据处理需求。同时,可以优化分片算法以提升系统性能,规避数据倾斜等问题。

在这里,自定义分片算法的类型(Type)统一为CLASS_BASED,包含两个属性:strategy 表示分片策略类型,目前支持三种:STANDARDCOMPLEXHINTalgorithmClassName 表示自定义分片算法的实现类路径。此外,还可以向算法类内传入自定义属性。

自定义 STANDARD 算法

要实现自定义 STANDARD 标准算法,需要实现StandardShardingAlgorithm<T>接口( T 代表接收的分片健值类型),并重写接口中的四个方法。其中,有两个 doSharding() 方法为处理分片的核心逻辑;getProps() 方法用于获取分片算法的配置信息;init() 方法则用于初始化分片算法的配置信息,支持动态修改。

5.X 以后的版本,实现自定义标准算法的精准分片和范围分片,不在需要实现多个接口。只用实现 StandardShardingAlgorithm 标准算法接口,重写两个 doSharding() 方法。 doSharding(availableTargetNames,rangeShardingValue) 处理含有 >、<、between and 等操作符的 SQL,doSharding(availableTargetNames,preciseShardingValue) 处理含有 = 、in 等操作符的 SQL。

精准分片

精准分片用于SQL中包含 in、= 等操作符的场景,支持单一分片健。

重写方法 doSharding(Collection availableTargetNames, PreciseShardingValue preciseShardingValue),该方法返回单一的分片数据源或分片表数据。有两个参数:一个是可用目标分库、分表的集合,另一个是精准分片属性对象。

PreciseShardingValue 对象属性数据格式如下:

{
  "columnName": "order_id", // 分片健
  "dataNodeInfo": {  
    "paddingChar": "0",
    "prefix": "db",   // 数据节点信息前缀,例如:分库时为db,分表时为分片表t_order_
    "suffixMinLength": 1
  },
  "logicTableName": "t_order", // 逻辑表
  "value": 1 // 分片健值
}

范围分片

范围分片用于 SQL中包含 >、< 等范围操作符的场景,支持单一分片健。

重写方法 doSharding(Collection availableTargetNames, RangeShardingValue rangeShardingValue),该方法可以返回多个分片数据源或分片表数据。有两个参数:一个是可用目标分库、分表的集合,另一个是精准分片属性对象。

RangeShardingValue 对象属性数据格式如下:

{
  "columnName": "order_id", // 分片健
  "dataNodeInfo": {
    "paddingChar": "0",
    "prefix": "db",  // 数据节点前缀,分库时为数据源,分表时为分片表t_order_
    "suffixMinLength": 1
  },
  "logicTableName": "t_order", // 逻辑表
  "valueRange": [0,]  // 分片健值的范围数据
}

精准分片算法的 doSharding() 执行流程:从PreciseShardingValue.getValue()中获取分片键值,然后经过计算得出相应编号,最终在availableTargetNames可用目标分库、分片表集合中选择以一个符合的返回。

范围分片算法的 doSharding() 执行流程:从RangeShardingValue.getValueRange()方法获取分片键的数值范围,然后经过计算得出相应编号,最终在availableTargetNames可用目标分库、分片表集合中选择多个符合的返回。

下面是具体实现分片的逻辑:

/**
 * 自定义标准分片算法
 *
 * @author 公众号:程序员小富
 * @date 2024/03/22 11:02
 */
@Slf4j
public class OrderStandardCustomAlgorithm implements StandardShardingAlgorithm<Long> {

    /**
     * 精准分片进入 sql中有 = 和 in 等操作符会执行
     *
     * @param availableTargetNames 所有分片表的集合
     * @param shardingValue        分片健的值,SQL中解析出来的分片值
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames,
                             PreciseShardingValue<Long> shardingValue) {
        /**
         * 分库策略使用时:availableTargetNames 参数数据为分片库的集合 ["db0","db1"]
         * 分表策略使用时:availableTargetNames 参数数据为分片库的集合 ["t_order_0","t_order_1","t_order_2"]
         */
        log.info("进入精准分片 precise availableTargetNames:{}", JSON.toJSONString(availableTargetNames));

        /**
         * 分库策略使用时: shardingValue 参数数据:{"columnName":"order_id","dataNodeInfo":{"paddingChar":"0","prefix":"db","suffixMinLength":1},"logicTableName":"t_order","value":1}
         * 分表策略使用时: shardingValue 参数数据:{"columnName":"order_id","dataNodeInfo":{"paddingChar":"0","prefix":"t_order_","suffixMinLength":1},"logicTableName":"t_order","value":1}
         */
        log.info("进入精准分片 preciseShardingValue:{}", JSON.toJSONString(shardingValue));
        int tableSize = availableTargetNames.size();
        // 真实表的前缀
        String tablePrefix = shardingValue.getDataNodeInfo().getPrefix();
        // 分片健的值
        long orderId = shardingValue.getValue();
        // 对分片健取模后确定位置
        long mod = orderId % tableSize;
        return tablePrefix + mod;
    }

    /**
     * 范围分片进入 sql中有 between 和  < > 等操作符会执行
     *
     * @param availableTargetNames 所有分片表的集合
     * @param shardingValue        分片健的值,SQL中解析出来的分片值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                         RangeShardingValue<Long> shardingValue) {
        /**
         * 分库策略使用时:availableTargetNames 参数数据为分片库的集合 ["db0","db1"]
         * 分表策略使用时:availableTargetNames 参数数据为分片库的集合 ["t_order_0","t_order_1","t_order_2"]
         */
        log.info("进入范围分片:range availableTargetNames:{}", JSON.toJSONString(availableTargetNames));


        /**
         * 分库策略使用时 shardingValue 参数数据:{"columnName":"order_id","dataNodeInfo":{"paddingChar":"0","prefix":"db","suffixMinLength":1},"logicTableName":"t_order","valueRange":{"empty":false}}
         * 分表策略使用时 shardingValue 参数数据:{"columnName":"order_id","dataNodeInfo":{"paddingChar":"0","prefix":"t_order_","suffixMinLength":1},"logicTableName":"t_order","valueRange":{"empty":false}}
         */
        log.info("进入范围分片:rangeShardingValue:{}", JSON.toJSONString(shardingValue));
        // 分片健值的下边界
        Range<Long> valueRange = shardingValue.getValueRange();
        Long lower = valueRange.lowerEndpoint();
        // 分片健值的上边界
        Long upper = valueRange.upperEndpoint();
        // 真实表的前缀
        String tablePrefix = shardingValue.getDataNodeInfo().getPrefix();
        if (lower != null && upper != null) {
            // 分片健的值
            long orderId = upper - lower;
            // 对分片健取模后确定位置
            long mod = orderId % availableTargetNames.size();
            return Arrays.asList(tablePrefix + mod);
        }
        //
        return Collections.singletonList("t_order_0");
    }

    @Override
    public Properties getProps() {
        return null;
    }

    /**
     * 初始化配置
     *
     * @param properties
     */
    @Override
    public void init(Properties properties) {
        Object prop = properties.get("prop");
        log.info("配置信息:{}", JSON.toJSONString(prop));
    }
}

配置算法

在实现了自定义分片算法的两个 doSharding() 核心逻辑之后,接着配置并使用定义的算法。配置属性包括strategy分片策略类型设置成standardalgorithmClassName自定义标准算法的实现类全路径。需要注意的是:策略和算法类型必须保持一致,否则会导致错误

spring:
  shardingsphere:
    rules:
      sharding:
        # 分片算法定义
        sharding-algorithms:
          t_order_database_mod:
            type: MOD
            props:
              sharding-count: 2 # 指定分片数量
          # 12、自定义 STANDARD 标准算法
          t_order_standard_custom_algorithm:
            type: CLASS_BASED
            props:
              # 分片策略
              strategy: standard
              # 分片算法类
              algorithmClassName: com.shardingsphere_101.algorithm.OrderStandardCustomAlgorithm
              # 自定义属性
              prop:
                aaaaaa: 123456
                bbbbbb: 654321
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_database_mod
            # 分表策略
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_standard_custom_algorithm

测试算法

在插入测试数据时,默认会自动进入精确分片的 doSharding() 方法内,看到该方法会获取分片键的数值,根据我们的计算规则确定返回一个目标分片表用于路由。

接着执行一个范围查询的 SQL,此时将进入范围分片的 doSharding() 方法。通过观察 shardingValue.getValueRange() 方法中分片键的数值范围,可以发现这些数值范围是从SQL查询中解析得到的。

select * from t_order where order_id > 1 and order_id < 10

自定义 COMPLEX 算法

复合分片算法支持包含 >,>=, <=,<,=,IN 和 BETWEEN AND 等操作符的SQL,支持多分片健。

自定义COMPLEX复合分片算法,需要我们实现 ComplexKeysShardingAlgorithm<T> 接口(其中 T 代表接收的分片键值类型),并重写该接口内部的 3 个方法。其中,主要关注用于处理核心分片逻辑的 doSharding()方法,可以返回多个分片数据源或分片表数据;其他两个配置方法与上述类似,这里不再赘述。

重写复合分片方法 doSharding(Collection availableTargetNames, ComplexKeysShardingValue shardingValues) 实现定制的多分片健逻辑,该方法有两个参数:一个是可用目标分库、分表的集合;另一个是多分片健属性对象。

logicTableName为逻辑表名,columnNameAndShardingValuesMap用于存储多个分片键和对应的键值,columnNameAndRangeValuesMap用于存储多个分片键和对应的键值范围。

ComplexKeysShardingValue数据结构如下:

public final class ComplexKeysShardingValue<T extends Comparable<?>> implements ShardingValue {
    // 逻辑表
    private final String logicTableName;
    // 多分片健及其数值
    private final Map<String, Collection<T>> columnNameAndShardingValuesMap;
    // 多分片健及其范围数值
    private final Map<String, Range<T>> columnNameAndRangeValuesMap;
}

核心流程:通过循环 Map 得到多个分片健值进行计算,从 availableTargetNames 可用目标分库、分片表集合中选择多个符合条件的返回。

/**
 * 自定义复合分片算法
 *
 * @author 公众号:程序员小富
 * @date 2024/03/22 11:02
 */
@Slf4j
public class OrderComplexCustomAlgorithm implements ComplexKeysShardingAlgorithm<Long> {

    /**
     * 复合分片算法进入,支持>,>=, <=,<,=,IN 和 BETWEEN AND 等操作符
     *
     * @param availableTargetNames 所有分片表的集合
     * @param complexKeysShardingValue        多个分片健的值,并SQL中解析出来的分片值
     */
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                         ComplexKeysShardingValue<Long> complexKeysShardingValue) {

        /**
         * 分库策略使用时:availableTargetNames 参数数据为分片库的集合 ["db0","db1"]
         * 分表策略使用时:availableTargetNames 参数数据为分片库的集合 ["t_order_0","t_order_1","t_order_2"]
         */
        log.info("进入复合分片:complex availableTargetNames:{}", JSON.toJSONString(availableTargetNames));

        // 多分片健和其对应的分片健范围值
        Map<String, Range<Long>> columnNameAndRangeValuesMap = complexKeysShardingValue.getColumnNameAndRangeValuesMap();
        log.info("进入复合分片:columnNameAndRangeValuesMap:{}", JSON.toJSONString(columnNameAndRangeValuesMap));

        columnNameAndRangeValuesMap.forEach((columnName, range) -> {
            // 分片健
            log.info("进入复合分片:columnName:{}", columnName);
            // 分片健范围值
            log.info("进入复合分片:range:{}", JSON.toJSONString(range));
        });

        // 多分片健和其对应的分片健值
        Map<String, Collection<Long>> columnNameAndShardingValuesMap = complexKeysShardingValue.getColumnNameAndShardingValuesMap();
        log.info("进入复合分片:columnNameAndShardingValuesMap:{}", JSON.toJSONString(columnNameAndShardingValuesMap));
        columnNameAndShardingValuesMap.forEach((columnName, shardingValues) -> {
            // 分片健
            log.info("进入复合分片:columnName:{}", columnName);
            // 分片健值
            log.info("进入复合分片:shardingValues:{}", JSON.toJSONString(shardingValues));
        });

        return null;
    }
}

配置算法

处理完复合分片算法的doSharding()核心逻辑,接着配置使用定义的算法,配置属性包括strategy分片策略类型设置成complexalgorithmClassName自定义算法的实现类全路径。

需要注意:配置分片键时,一定要使用 sharding-columns 表示复数形式,很容易出错。

spring:
  shardingsphere:
    rules:
      sharding:
        sharding-algorithms:
          t_order_database_mod:
            type: MOD
            props:
              sharding-count: 2 # 指定分片数量
          # 13、自定义 complex 标准算法
          t_order_complex_custom_algorithm:
            type: CLASS_BASED
            props:
              # 分片策略
              strategy: complex
              # 分片算法类
              algorithmClassName: com.shardingsphere_101.algorithm.OrderComplexCustomAlgorithm
              # 自定义属性
              aaaaaa: aaaaaa
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_database_mod
            # 分表策略
            table-strategy:
              complex:
                sharding-columns: order_id , user_id
                sharding-algorithm-name: t_order_complex_custom_algorithm

测试算法

插入测试数据,debug 进入 doSharding() 方法,看到columnNameAndShardingValuesMap内获取到了 user_id
、order_id 两个分片键及健值。

当执行范围查询的SQL,columnNameAndRangeValuesMap属性内获取到了 user_id、order_id 两个分片键及健值范围,通过range.upperEndpoint()、lowerEndpoint()得到上下界值。

select * from t_order where order_id > 1 and user_id > 1;

自定义 HINT 算法

要实现自定义HINT强制路由分片算法,需要实现 HintShardingAlgorithm<T> 接口( T 代表接收的分片键值类型)。在实现过程中,需要重写接口中的3个方法。其中,核心的分片逻辑在 doSharding() 方法中处理,可以支持返回多个分片数据源或分片表数据。另外,其他两个prop配置方法的使用方式与上述相同,这里不赘述。

重写 HINT 核心分片方法 doSharding(Collection availableTargetNames, HintShardingValue shardingValue),以实现我们的定制逻辑。该方法接受两个参数:一个是可用目标分库、分表的集合,另一个是 Hint 分片属性对象。

方法内执行流程:我们首先获取 HintManager API 设置的分库或分表的分片值,经过计算后得到合适的分片数据源或分片表集合,然后直接路由到目标位置,无需再关注SQL本身的条件信息。

/**
 * 自定义强制路由分片算法
 *
 * @author 公众号:程序员小富
 * @date 2024/03/22 11:02
 */
@Slf4j
public class OrderHintCustomAlgorithm implements HintShardingAlgorithm<Long> {

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Long> hintShardingValue) {

        /**
         * 获取到设置的分表或者分库的分片值
         * 指定分表时的分片值  hintManager.addTableShardingValue("t_order",2L);
         * 指定分库时的分片值  hintManager.addDatabaseShardingValue("t_order", 100L);
         */
        Collection<Long> values = hintShardingValue.getValues();
        Collection<String> result = new ArrayList<>();
        // 从所有分片表中得到合适的分片表
        for (String each : availableTargetNames) {
            for (Long value : values) {
                Long mod = value % availableTargetNames.size();
                if (each.endsWith(String.valueOf(mod))) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}

配置算法

配置自定义Hint算法,配置属性包括strategy分片策略类型设置成hintalgorithmClassName自定义Hint算法的实现类全路径。使用该算法时无需指定分片健!

spring:
  shardingsphere:
    # 具体规则配置
    rules:
      sharding:
        # 分片算法定义
        sharding-algorithms:
          t_order_database_mod:
            type: MOD
            props:
              sharding-count: 2 # 指定分片数量
          # 14、自定义 hint 标准算法
          t_order_hint_custom_algorithm:
            type: CLASS_BASED
            props:
              # 分片策略
              strategy: hint
              # 分片算法类
              algorithmClassName: com.shardingsphere_101.algorithm.OrderHintCustomAlgorithm
              # 自定义属性
              bbbbbb: bbbbbb
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              hint:
                sharding-algorithm-name: t_order_database_mod
            # 分表策略
            table-strategy:
              hint:
                sharding-algorithm-name: t_order_hint_custom_algorithm

测试算法

在执行SQL操作之前,使用 HintManager APIaddDatabaseShardingValueaddTableShardingValue方法来指定分库或分表的分片值,这样算法内通过 HintShardingValue 可以获取到分片值。注意:如果在执行 SQL 时没有使用 HintManager 指定分片值,那么执行SQL将会执行全库表路由

@DisplayName("Hint 自动义分片算法-范围查询")
@Test
public void queryHintTableTest() {

    HintManager hintManager = HintManager.getInstance();
    // 指定分表时的分片值
    hintManager.addTableShardingValue("t_order",2L);
    // 指定分库时的分片值
    hintManager.addDatabaseShardingValue("t_order", 100L);

    QueryWrapper<OrderPo> queryWrapper = new QueryWrapper<OrderPo>()
            .eq("user_id", 20).eq("order_id", 10);
    List<OrderPo> orderPos = orderMapper.selectList(queryWrapper);
    log.info("查询结果:{}", JSON.toJSONString(orderPos));
}

到这关于 shardingsphere-jdbc 的 3种自定义分片算法实现就全部结束了。

总结

本文介绍了 STANDARD、COMPLEX 和 HINT 三种自定义分片算法的实现,和使用过程中一些要注意的事项。ShardingSphere 内置的十几种算法,其实已经可以满足我们绝大部分的业务场景,不过,如果考虑到后续的性能优化和扩展性,定制分片算法是个不错的选择。

全部demo案例 GitHub 地址:https://github.com/chengxy-nds/Springboot-Notebook/tree/master/shardingsphere101/shardingsphere-algorithms

我是小富~ 下期见

技术书籍公众号内回复[ pdf ] Get。

面试笔记、springcloud进阶实战PDF,公众号内回复[ 1222 ] Get。

在这里插入图片描述

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

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

相关文章

常见微服务的组件?

注册中心&#xff1a;就是一个服务注册的地方&#xff0c;我们可以把拆分的服务注册到注册中心&#xff0c;这样注册中心就能管理这些服务&#xff0c;服务之间的调用就会很方便&#xff0c;通过服务名就能相互调用。 负载均衡&#xff1a;被调用放的负载均衡&#xff0c;比如…

单位K与ROM/RAM地址转化的关系?

文章目录 如题如图 如题 在单片机开发中&#xff0c;经常会见到多少K空间这样的字眼&#xff1f;我经常会忘记两者之间的关系&#xff0c;每次都要回想一下&#xff0c;才能明白&#xff0c;这次作为笔记记录一下 如图 这是我以前的笔记&#xff0c;平常所说的多少K是指多少K…

如何在jmeter中快速开发性能脚本?这个功能你需要知道。

在使用jmeter做性能测试时 &#xff0c;基本都是针对以下的两种类型的性能测试&#xff1a; 对web系统页面的性能测试 对系统的接口进行性能测试 有页面的可以优先测试页面 &#xff0c;但是如果是APP或小程序的性能测试 &#xff0c;更多的是对接口进行性能测试 。那么接下来…

学会这几点,是搭建产品知识库的关键

现如今&#xff0c;企业都特别看重产品知识库&#xff0c;因为有了它&#xff0c;企业就能更好地管理产品信息&#xff0c;提升客户服务水平&#xff0c;还能帮企业做决策。但是&#xff0c;搭建一个好用、高效的产品知识库&#xff0c;也难倒了不少人。下面&#xff0c;我们一…

记录何凯明在MIT的第一堂课:神经网络发展史

https://www.youtube.com/watch?vZ5qJ9IxSuKo 目录 表征学习 主要特点&#xff1a; 方法和技术&#xff1a; LeNet 全连接层​ 主要特点&#xff1a; 主要特点&#xff1a; 网络结构&#xff1a; AlexNet 主要特点&#xff1a; 网络结构&#xff1a; Sigmoid Re…

设备物联网关在某制造企业中的应用-天拓四方

随着物联网技术的迅猛发展&#xff0c;设备物联网关作为连接物理世界与数字世界的核心组件&#xff0c;其应用已经渗透到工业、农业、医疗等多个领域。本案例将聚焦于设备物联网关在某制造企业中的应用&#xff0c;详细解析其在实际生产中的重要作用。 案例背景 某制造企业面…

代码随想录阅读笔记-二叉树【平衡二叉树】

题目 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a;一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 返回 true 。 示例 2: 给定二叉树 [1,2,…

【Entity Framework】EF中的增删改查

【Entity Framework】EF中的增删改查 文章目录 【Entity Framework】EF中的增删改查一、概述二、DbContext数据上下文三、EntityState五个状态值四、EF添加数据4.1 EF Add方式4.2 EF 通过改变对象的状态为 Added4.3 调用方sql4.4 调用存储过程 五、EF修改数据5.1 不查询数据库&…

【SpringCloud】一文详谈Nacos

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …

陀螺仪传感器,IMU和加速度计的产品和选型

爱普生陀螺仪传感器是一种角速度传感器&#xff0c;作为一种石英电子式陀螺仪芯片&#xff0c;具有温度特性好、功耗低、成本低、稳定性好等特点。目前EPSON主力单轴陀螺仪传感器型号为XV7001BB、XV7011BB、XV7021BB和XV7181BB。针对扫地机器人传感器模组等领域的需要&#xff…

享道出行:容器弹性技术驱动下的智慧出行稳定性实践

作者&#xff1a;郑嘉扬、何杉 前言 享道出行是一家专注于出行服务的专业品牌&#xff0c;是上汽集团实现汽车产业“新四化”&#xff08;即“电动化、智能网联化、共享化、国际化”&#xff09;的重要组成部分。作为上汽集团移动出行战略品牌&#xff0c;享道出行充分利用全…

4、jvm基础知识(四)

有哪些常见的垃圾回收算法&#xff1f; ⚫1960年John McCarthy发布了第一个GC算法&#xff1a;标记-清除算法。 ⚫1963年Marvin L. Minsky 发布了复制算法。 本质上后续所有的垃圾回收算法&#xff0c;都是在上述两种算法的基础上优化而来。 垃圾回收算法-标记清除算法 标记清…

“星际畅聊”来了!电子开启光通信,量子技术领航远程快速通讯

科学家们最近通过使用电脉冲将磁信息成功转换为偏振光信号&#xff0c;开启了一项革命性的量子技术。这一进展预示着未来包括地球与火星间长距离星际光通信在内的通信方式将发生翻天覆地的变化。 这项研究成果于3月27日在《自然》杂志上发表。研究聚焦于自旋电子学领域&#xf…

Gerrit学习

安装Gerrit 以Ubuntu 20.04为例&#xff0c;安装Gerrit容器2.15版本 docker-compose.yml version: 3 services:gerrit:image: gerritcodereview/gerrit:2.15ports:- 8080:8080- 29418:29418volumes:- ./review_site:/var/gerrit/review_siteenvironment:- CANONICAL_WEB_URL…

算法——距离计算

距离计算常用的算法包括欧氏距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、余弦相似度等。这些算法在数据挖掘、机器学习和模式识别等领域中被广泛应用。 1.欧氏距离 欧式距离也称欧几里得距离&#xff0c;是最常见的距离度量&#xff0c;衡量的是多维空间中两个点之间的…

Docker容器、Serverless与微服务:腾讯云云原生架构技术实践案例集解析

前言 随着云原生技术的飞速发展&#xff0c;容器化和函数计算正成为企业和开发者关注的焦点。在这一潮流中&#xff0c;腾讯云凭借其卓越的技术实力和深厚的行业积累&#xff0c;发布了《2023腾讯云容器和函数计算技术实践精选集》&#xff0c;为我们提供了一份深入探索云原生…

【编译分析】MSVC编译器函数修饰的返回值问题

在阅读一篇关于函数重载的文章时&#xff0c;作者提到了MSVC进行函数修饰的结果比较gcc更加复杂。 通过查阅GPT发现可以使用vs提供的dumpbin工具查看编译之后的汇编程序相关信息&#xff0c;可以通过下面这条指令进行查看&#xff1a; dumpbin /all test.exe在结果中查看可以找…

[网鼎杯 2020 朱雀组]Nmap1

打开题目 在源代码中看到了提示 先随便输入127.0.0.1 那我们试试输入 127.0.0.1 | ls 可以看到 | 被转义符号\所转义 那我们输入 127.0.0.1 /| ls 得到三条反斜线 我们猜测&#xff0c;我们输入的东西是被escapeshellarg和escapeshellcmd处理过后的结果 我们输入的东西必须…

干懵过Intel、AMD的外星科技,又要再次降临了

2020年苹果 M1 芯片的横空出世&#xff0c;不光盘活了自家的Mac 产品&#xff0c;也让大家意识到 ARM 架构也能发挥出恐怖的实力。 为了涵盖各个定位&#xff0c;随后又是 M1 Pro、M1 Max &#xff0c;最终还诞生了完全体 - M1 Ultra 。 两块 M1 Max 粘一起的规模带来了怪兽级…

skywalking idea中启动调试报错Output path is shared between the same module error

报错信息 简单描述&#xff1a;就是多个moudle一样用了一样的输出路径&#xff0c;这样容易造成冲突 Output path is shared between the same module error 参考&#xff1a;scala - Output path is shared between the same module error - Stack Overflow 解决方法&…
最新文章