[Spring Boot]09 Spring Boot集成和使用Redis

news2025/8/12 16:02:58

目录

    • 前言
      • Spring Boot如何集成Redis
      • Spring Boot如何使用Redis
      • 小结

前言

在这里插入图片描述

Redis全称Remote Dictionary Server(远程字典服务),它是一个基于内存实现的键值型非关系(NoSQL)数据库,由意大利人 Salvatore Sanfilippo 使用C语言编写。

Redis的性能极高,可以用来缓存一些经常被访问的数据或者需要耗费大量资源的内容,把这些内容放到Redis中时,能够让应用程序快速地读取它们,从而降低应用的压力,减少访问的延迟。

Spring Boot如何集成Redis

在项目pom.xml文件中引入Redis,依赖内容如下:

<!--redis-->
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
<!-- redis需要配合commons-pool2 对象池依赖 -->
  <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
  </dependency>

对应application.yml配置文件的配置:

//*******为redis的密码
  redis:
    host: 127.0.0.1
    port: 6379
    password: *******
    timeout: 5000
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        max-wait: 5000
        min-idle: 0

默认数据库0,如果要指定数据库,使用配置:

//指定使用数据库1,redis自带16(0—15)个数据库(默认使用0库)
database: 1

Spring Boot如何使用Redis

先准备2个文件:Redis配置文件和Redis工具类。
Redis配置文件,一般放在api项目里面,文件名为RedisConfig,源码如下:

package com.***.api.conf;// ***为自己的项目

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author /
 */
@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // 配置连接工厂
        lettuceConnectionFactory.setValidateConnection(true);
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        // 设置序列化
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(jsonRedisSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);
        return redisTemplate;
    }
}

Redis工具类,一般放在common项目里面,文件名为RedisUtil,源码如下:

package com.***.common.util;// ***为自己的项目

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redis 工具类
 *
 * @author /
 */
@Component
public class RedisUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return true / false
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据 key 获取过期时间
     *
     * @param key 键
     * @return /
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断 key 是否存在
     *
     * @param key 键
     * @return true / false
     */
    public Boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 键(一个或者多个)忽略类型转换警告
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
            //  传入一个 Collection<String> 集合
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    /**
     * 删除缓存集合
     *
     * @param keys 传入一个 Collection<String> 集合
     */
    public void del(List<String> keys) {
        redisTemplate.delete(keys);
    }
//    ============================== String ==============================

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true / false
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒),如果 time < 0 则设置无限时间
     * @return true / false
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 递增大小
     * @return /
     */
    public Long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 递减大小
     * @return /
     */
    public Long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

//    ============================== Map ==============================

    /**
     * HashGet
     *
     * @param key  键(no null)
     * @param item 项(no null)
     * @return 值
     */
    public Object hGet(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取 key 对应的 map
     *
     * @param key 键(no null)
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmGet(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 值
     * @return true / false
     */
    public boolean hmSet(String key, Map<Object, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  值
     * @param time 时间
     * @return true / false
     */
    public boolean hmSet(String key, Map<Object, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张 Hash表 中放入数据,如不存在则创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true / false
     */
    public boolean hSet(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张 Hash表 中放入数据,并设置时间,如不存在则创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(如果原来的 Hash表 设置了时间,这里会覆盖)
     * @return true / false
     */
    public boolean hSet(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除 Hash表 中的值
     *
     * @param key  键
     * @param item 项(可以多个,no null)
     */
    public void hDel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断 Hash表 中是否有该键的值
     *
     * @param key  键(no null)
     * @param item 值(no null)
     * @return true / false
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * Hash递增,如果不存在则创建一个,并把新增的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   递增大小 > 0
     * @return
     */
    public Double hIncr(String key, String item, Double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * Hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   递减大小
     * @return
     */
    public Double hDecr(String key, String item, Double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

//    ============================== Set ==============================

    /**
     * 根据 key 获取 set 中的所有值
     *
     * @param key 键
     * @return 值
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 从键为 key 的 set 中,根据 value 查询是否存在
     *
     * @param key   键
     * @param value 值
     * @return true / false
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入 set缓存
     *
     * @param key    键值
     * @param values 值(可以多个)
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将数据放入 set缓存,并设置时间
     *
     * @param key    键
     * @param time   时间
     * @param values 值(可以多个)
     * @return 成功放入个数
     */
    public long sSet(String key, long time, Object... values) {
        try {
            long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取 set缓存的长度
     *
     * @param key 键
     * @return 长度
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除 set缓存中,值为 value 的
     *
     * @param key    键
     * @param values 值
     * @return 成功移除个数
     */
    public long setRemove(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

//    ============================== List ==============================

    /**
     * 获取 list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束(0 到 -1 代表所有值)
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取 list缓存的长度
     *
     * @param key 键
     * @return 长度
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 根据索引 index 获取键为 key 的 list 中的元素
     *
     * @param key   键
     * @param index 索引
     *              当 index >= 0 时 {0:表头, 1:第二个元素}
     *              当 index < 0 时 {-1:表尾, -2:倒数第二个元素}
     * @return 值
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将值 value 插入键为 key 的 list 中,如果 list 不存在则创建空 list
     *
     * @param key   键
     * @param value 值
     * @return true / false
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将值 value 插入键为 key 的 list 中,并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间
     * @return true / false
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将 values 插入键为 key 的 list 中
     *
     * @param key    键
     * @param values 值
     * @return true / false
     */
    public boolean lSetList(String key, List<Object> values) {
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将 values 插入键为 key 的 list 中,并设置时间
     *
     * @param key    键
     * @param values 值
     * @param time   时间
     * @return true / false
     */
    public boolean lSetList(String key, List<Object> values, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引 index 修改键为 key 的值
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return true / false
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 在键为 key 的 list 中删除值为 value 的元素
     *
     * @param key   键
     * @param count 如果 count == 0 则删除 list 中所有值为 value 的元素
     *              如果 count > 0 则删除 list 中最左边那个值为 value 的元素
     *              如果 count < 0 则删除 list 中最右边那个值为 value 的元素
     * @param value
     * @return
     */
    public long lRemove(String key, long count, Object value) {
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    
}

Redis使用举例:
比如,把用户登录的token信息放入Redis,从而提高登录访问的性能。
只要使用RedisUtil工具中,有关String字符串的函数来处理即可,可以使用放入缓存set和从缓存获取get这2个函数,代码单独摘出来了,如下:

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    
    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒),如果 time < 0 则设置无限时间
     * @return true / false
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

token信息放入Redis:

//  86400L:token过期时间,单位为秒,如设置为1天 
redisUtil.set("login:token:" + userId, token, 86400L);

从Redis中获取token信息:

Object obj = redisUtil.get("login:token:" + userId);

再比如,APP端,一般都会使用手机号码进行注册和登录,使用手机号码时,都会对接短信服务获取验证码,获取验证码一般都会使用一些限制,比如,一次短信验证码5分钟内有效,同一个号码每天不能发送超过10次等等。
由于,发送验证码的动作可能非常地频繁,我们也可以选择把获取验证码相关的操作放Redis里面来缓存,从而提高短信业务的性能。

短信验证码信息放入Redis:

// 验证码5分钟之内有效
redisUtil.set("sms:code:" + mobile, code, 300L);
// 1分钟之内不能重发
redisUtil.set("sms:resend:" + mobile, new Date(), 60L);
// 每天最多10次
  // 判断是否达到10次 格式 sms:incr:130****8888:20221109
String incrKey = "sms:incr:" + mobile + ":" + DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
redisUtil.incr(incrKey, 1L);
// 1天之后自动过期
redisUtil.expire(incrKey, 86400L);

从Redis中获取短信验证码信息:

// 获取短信验证码
Object obj = redisUtil.get("sms:code:" + mobile);
// 成功后 删除短信缓存,从而解除重发限制
redisUtil.del("sms:code:" + mobile, "sms:resend:" + mobile);
// 判断是否达到10次
String incrKey = "sms:incr:" + mobile + ":" + DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT);
Object obj = redisUtil.get(incrKey);
// 判断是否超过了一分钟
Boolean bResend = redisUtil.hasKey("sms:resend:" + mobile);

小结

Redis使用的好,真的能够帮助我们的项目,解决很多的性能问题,我们要善于去发现能够使用Redis的场景,灵活使用Redis工具类里面的功能。
大家使用起来吧。

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

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

相关文章

Python 基础(二):搭建 Python 开发环境

搭建 Python 开发环境一、下载 Python 安装包二、安装 Python三、Python开始菜单介绍3.1 IDLE3.2 Python 3.113.3 Python 3.11 Manuals3.4 Python 3.11 Manuals Docs四、Hello World大家好&#xff0c;我是水滴~~ 本篇文章主要介绍如何搭建 Python 的开发环境&#xff0c;主要内…

Eolink钉钉webhook使用教程(超详细)

目录 一、操作步骤 1、空间管理 2、添加服务调用 3、填写添加Webhook信息 4、获取DingDing通知URL 1、需要创建一个至少三个人的群 2、需要添加一个群机器人。 3、选择智能群助手 4、添加机器人 5、点击设置 6、选择【自定义】通过Webhook接入自定义服务 7、确认添…

多元统计分析-----例8.1:今有14名学生的身高和体重数据,做相关图以显示相关变量间的关系。

例8.1&#xff1a;今有14名学生的身高和体重数据&#xff0c;做相关图以显示相关变量间的关系。 x1c(147,171,175,159,155,152,158,154,164,168,166,159,164,177) x2c(32,57,64,1,38,35,44,41,54,57,49,47,46,63)plot(x1,x2,xlim c(145,180),ylimc(25,75))出错&#xff1a; …

Android进阶:6、使用okhttp下载图片

因为在网上找到的资源不只是一些字符串或是一些二进制数字&#xff0c;还是有的是可以肉眼看见的图片&#xff0c;那么我们在发送网络请求时拿到的是一张图片该如何显示在组件上面呢&#xff1f; 这就要使用到okhttp的请求返回结果的一个属性&#xff08;byteStream&#xff0…

自动驾驶感知算法实战14——感知算法模型生产线

自动驾驶感知算法实战专栏:https://blog.csdn.net/charmve/category_12097938.html目录 一、感知算法生产流程二、算法模型部署流程二、各个阶段交付物数据选择(数据采集、数据增强)数据标注模型训练模型量化模型部署测试与验证一、感知算法生产流程 二、算法模型部署流程 二…

【JavaWeb从零到一】JSPELJSTL

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【JavaWeb】 &#x1f96d;本文…

通过题目入门python基础1

通过题目入门python基础 简介&#xff1a;本文通过&#xff0c;python的基础题目&#xff0c;带领大家入门python的基础语法&#xff0c;以实用主义为主。 差 读取四个整数 A,B,C,D&#xff0c;并计算 (AB−CD) 的值。 输入格式 输入共四行&#xff0c;第一行包含整数 A&am…

GraphQL 实践与服务搭建

原文链接: GraphQL 实践与服务搭建 GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余&#xff0c;也让 API 更容…

《SystemVerilog Assertion 应用指南》学习01

文章目录0、基于断言的 验证1、SVA 介绍1.1.、什么是断言1.2、为什么使用 SystemVerilog 断言&#xff08;SVA&#xff09;1.3、SystemVerilog 的调度1.4、SVA 术语1.4.1、并发断言1.4.2、即时断言1.5、建立 SVA 块1.6、一个简单的序列1.7、边沿定义的序列1.8、逻辑关系的序列1…

云原生安全:4C~

4C是啥&#xff1f; cloudclustercontainercode 4个C是层的关系&#xff0c;外圈不安全&#xff0c;不能指望里面太安全。。。 目录 Cloud cloud Provider Security 基础架构安全 Cluster cluster的组件 cluster中的组件&#xff08;应用中的&#xff09; Container …

第二章:Pythonocc官方demo 案例44(几何板条)

源代码&#xff1a; ##Copyright 2009-2016 Jelle Feringa (jelleferingagmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC is free software: you can redistribute it and/or modify ##it under the terms of the GNU Lesser General Public License as pub…

数据库 Apache Doris 展开了为期两个月的调研测试

2022 年 3 月开始&#xff0c;我们对符合以上特点的数据库 Apache Doris 展开了为期两个月的调研测试。以下是 Apache Doris 1.1.2 在各个方面的满足情况。 基于上述情况&#xff0c;我们决定采用 Apache Doris&#xff0c;除了可以满足上文提到的几个特点&#xff0c;我们还考…

[信息系统项目管理师-2023备考]信息化与信息系统(一)

1.信息的质量特性 精确性&#xff1a;对事物状态描述的精准程度完整性&#xff1a;对事物状态描述的全面程度&#xff0c;完整信息应该包括所有重要事实可靠性&#xff1a;信息的来源、采集方法、传输过程是可以信任的&#xff0c;符合预期及时性&#xff1a;获取信息的时刻与…

(八)RabbitMQ发布确认

发布确认1、发布确认原理2、发布确认策略2.1、开启发布确认的方法2.2、单个确认发布2.3、批量确认发布2.4、异步确认发布2.5、处理异步未确认消息1、发布确认原理 书面文&#xff1a;生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm 模式&#xff0c;所有在…

Python集合类型详解(一)——集合定义与集合操作符

今天继续给大家介绍Python相关知识&#xff0c;本文主要内容是Python集合类型定义与集合操作符。 一、集合类型定义 在Python中&#xff0c;集合是一种非常重要的组合数据类型。Python中的集合与数学中的集合非常相似&#xff0c;集合中的数据没有顺序&#xff0c;并且每个元…

第二章:Pythonocc官方demo 案例45(几何轴向曲线偏置)

源代码&#xff1a; #!/usr/bin/env python##Copyright 2009-2016 Jelle Feringa (jelleferingagmail.com) ## ##This file is part of pythonOCC. ## ##pythonOCC is free software: you can redistribute it and/or modify ##it under the terms of the GNU Lesser General …

【优化调度】遗传算法求解工件的并行调度组合优化问题【含Matlab源码 2234期】

⛄ 一、 遗传算法简介 1 问题描述 假定一个加工系统有m台机器和n件工件&#xff0c;每个工件包含一道或多道工序,工件的加工顺序是确定的,但每个工件可能有几条可行的加工路线,即每道工序可在多台不同的机床上加工,工序的加工时间和加工费用随机床的性能不同而变化。作业调度的…

并查集解析

文章目录&#x1f6a9;并查集的理解&#x1f6a9;并查集的结构与原理&#x1f6a9;并查集的实现&#x1f341;整体框架&#x1f341;路径压缩&#x1f6a9;总结&#x1f6a9;并查集的理解 并查集是基于数组操作的一个特殊数据结构&#xff0c;和以前学习[数组的堆排序]时有点相…

分析设备树文件

1.设备树是干嘛的 硬件资源有很多&#xff0c;想要实现分类管理&#xff0c;方便驱动去控制它&#xff0c;则需要设备树来管理硬件信息。 所以&#xff0c;设备树主要存放了一些设备节点信息&#xff0c;键值对&#xff0c;和属性&#xff1b;节点中也可以包含子节点。 2.设…

安全架构中的前端安全防护研究

国家互联网应急中心发布的被篡改网站数据让很多人触目惊心&#xff0c;近年来各种Web网站攻击事件频频发生&#xff0c;网站SQL注入&#xff0c;网页被篡改、信息失窃、甚至被利用成传播木马的载体Web安全形势日益严峻&#xff0c;越来越受到人们的关注。 Gartner 对安全架构的…