SpringBoot使用Redis(事务异步add + 更新)

1,简单介绍redis

Redis(Remote Dictionary Server)是一个开源的内存中数据结构存储系统。

主要特点:

  • 内存存储: Redis 主要将数据存储在内存中,因此读写速度非常快,适合需要高性能的应用场景。

  • 持久化: Redis 支持将内存中的数据持久化到磁盘,可以通过RDB快照(Snapshotting)或者日志(Append-only file, AOF)的方式实现数据持久化,保证数据在服务重启后不丢失。

  • 数据结构多样性: Redis 不仅仅是键值存储(key-value store),还支持多种复杂的数据结构,每种数据结构都有专门的操作命令,使得开发者可以根据需求选择合适的数据结构存储数据。

  • 原子操作: Redis 提供的命令支持原子操作,可以确保复杂操作的原子性,避免并发问题。

  • 分布式: Redis 提供了主从复制(Replication)和分片(Sharding)等功能,支持构建高可用、高扩展性的分布式系统。

  • 高性能: Redis 使用单线程模型来处理请求,避免了多线程间的锁竞争和上下文切换开销,因此能够达到很高的单实例性能。

  • 丰富的扩展功能: Redis 提供了许多扩展功能,如事务(Transaction)、发布订阅(Pub/Sub)、Lua 脚本扩展、过期自动删除等,使其在不同场景下有更广泛的应用。

2,如何在实际项目中使用

正常项目中使用思路

  • 使用redis目的是为了提高我们接口响应速度,所以经常用于查询的数据可以用redis
  • 必须考虑保证redis与数据库的数据一致性
  • 作为辅助提升响应的手段,redis故障不能影响服务自身的业务,也就是不能导致服务故障
  • 主要是为了获取而用,所以redis数据的add,delete等操作应该由多线程进行

redis与数据库的数据一致性,后面会有出别的文章。这里主要展示如何使用

引入依赖

根据自己springBoot的版本选择合适的版本

 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <version>2.5.4</version>
    </dependency>
    <!-- 使用连接池进行管理redis -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.11.1</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.8.0</version>
    </dependency>

编写配置文件

# redis 连接信息
spring.redis.host=127.0.0.1
spring.redis.port=6379
# 这里为了信息安全使用了加密
spring.redis.password={decrypt}cm9qZXIxMjM0
# redis 连接池的配置信息
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.min-idle=2
spring.redis.jedis.pool.max-wait=1500ms

关于如何在springboot中使用配置文件的加解密请查看

SpringBoot启动自动解密加密配置项_springboot environment 配置项解密-CSDN博客

编写config类

package com.luojie.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    @Value("${spring.redis.password}")
    private String redisPassword;

    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxTotal;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private Duration maxWaitMillis;

    /**
     * Redis 连接工厂配置
     * @return
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        if (redisHost.contains(",")) {
            // 配置集群 Redis 连接工厂
            return clusterConnectionFactory();
        } else {
            //  配置单机 Redis 连接工厂
            return standaloneConnectionFactory();
        }
    }

    /**
     * 当redis为单机情况时
     * @return
     */
    private RedisConnectionFactory standaloneConnectionFactory() {
        // RedisStandaloneConfiguration 设置单机 Redis 配置
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(redisHost);
        config.setPort(redisPort);
        config.setPassword(redisPassword);

        // JedisClientConfiguration 配置 Jedis 连接
        JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofMillis(3500)); // connection timeout
        // JedisPoolConfig 配置连接池参数
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis.toMillis());

        jedisClientConfiguration.usePooling().poolConfig(poolConfig);
        // 使用 JedisConnectionFactory 创建连接工厂
        return new JedisConnectionFactory(config, jedisClientConfiguration.build());
    }

    private RedisConnectionFactory clusterConnectionFactory() {
        // RedisClusterConfiguration 设置集群 Redis 配置
        RedisClusterConfiguration config = new RedisClusterConfiguration();
        for (String node : redisHost.split(",")) {
            String[] parts = node.split(":");
            config.clusterNode(parts[0], Integer.parseInt(parts[1]));
        }
        config.setPassword(redisPassword);

        // JedisClientConfiguration 配置 Jedis 连接
        JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofMillis(3500)); // connection timeout

        // JedisPoolConfig 配置连接池参数
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis.toMillis());

        jedisClientConfiguration.usePooling().poolConfig(poolConfig);

        // 使用 JedisConnectionFactory 创建连接工厂
        return new JedisConnectionFactory(config, jedisClientConfiguration.build());
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        
        // 使用StringRedisSerializer序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 使用GenericJackson2JsonRedisSerializer序列化和反序列化redis的value值
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        template.afterPropertiesSet();
        return template;
    }
}

编写redisTemplateUtil工具类

package com.luojie.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * redis 工具类
 */
@Component
@Slf4j
public class RedisServiceUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 普通string类型,设置值
     *
     * @param key
     * @param value
     */
    public void set(String key, String value) {
        try {
            redisTemplate.opsForValue().set(key, value);
        } catch (Exception e) {
            log.error("fail set redis key:{},value:{}, errorMsg:{}", key, value, e.getMessage());
        }
    }

    /**
     * 普通string类型,设置值并设置超时时间
     *
     * @param key
     * @param value
     */
    public void setWithExpire(String key, String value, int time, TimeUnit timeUnit) {
        try {
            redisTemplate.opsForValue().set(key, value, time, timeUnit);
        } catch (Exception e) {
            log.error("fail set redis key with expire:{},value:{}, errorMsg:{}", key,
                    value, e.getMessage());
        }
    }

    /**
     * 普通string类型,获取值
     *
     * @param key
     */
    public String get(String key) {
        try {
            return (String) redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("fail get redis key:{}, errorMsg:{}", key, e.getMessage());
        }
        return null;
    }

    /**
     * 普通string类型,删除key
     *
     * @param key
     */
    public void delete(String key) {
        try {
            redisTemplate.delete(key);
        } catch (Exception e) {
            log.error("fail delete redis key:{}, errorMsg:{}", key, e.getMessage());
        }
    }

    /**
     * 普通string类型,判断key是否存在
     *
     * @param key
     */
    public boolean exists(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("fail exists redis key:{}, errorMsg:{}", key, e.getMessage());
        }
        return false;
    }

    /**
     * 普通string类型,为某个key单独设置超时时间
     *
     * @param key
     */
    public void expire(String key, int seconds, TimeUnit timeUnit) {
        try {
            redisTemplate.expire(key, seconds, timeUnit);
        } catch (Exception e) {
            log.error("fail expire redis key:{}, errorMsg:{}", key, e.getMessage());
        }
    }

    /**
     * 普通string类型,获取key的超时时间
     *
     * @param key
     */
    public Long getExpire(String key) {
        try {
            return redisTemplate.getExpire(key);
        } catch (Exception e) {
            log.error("fail getExpire redis key:{}, errorMsg:{}", key, e.getMessage());
        }
        return null;
    }

    /**
     * hash类型,设置值
     *
     * @param key
     * @param value
     */
    public void setHash(String key, String field, String value) {
        try {
            redisTemplate.opsForHash().put(key, field, value);
        } catch (Exception e) {
            log.error("fail setHash redis key:{}, errorMsg:{}", key, e.getMessage());
        }
    }

    /**
     * hash类型,设置值
     *
     * @param key
     * @param value
     */
    public void setHashWithExpire(String key, String field, String value, int time, TimeUnit timeUnit) {
        try {
            redisTemplate.opsForHash().put(key, field, value);
            redisTemplate.expire(key, time, timeUnit);
        } catch (Exception e) {
            log.error("fail setHash with expire redis key:{}, errorMsg:{}", key, e.getMessage());
        }
    }

    /**
     * hash类型,获取值
     *
     * @param key
     */
    public String getHash(String key, String field) {
        try {
            return (String) redisTemplate.opsForHash().get(key, field);
        } catch (Exception e) {
            log.error("fail getHash redis key:{}, errorMsg:{}", key, e.getMessage());
        }
        return null;
    }

    /**
     * hash类型,删除
     *
     * @param key
     */
    public void deleteHash(String key, String field) {
        try {
            redisTemplate.opsForHash().delete(key, field);
        } catch (Exception e) {
            log.error("fail deleteHash redis key:{}, errorMsg:{}", key, e.getMessage());
        }
    }
}

------往上为基本功能线------

根据上面的,直接使用controller进行访问调用已经可以用了。往下这里做一下功能升级。

主要用到异步 + event

如果想详细了解异步,了解event监听器请参考

Spring的监听器使用(实用,直接拿去修改可用)-CSDN博客

创建数据module类

package com.luojie.moudle;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

import java.util.concurrent.TimeUnit;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class RedisEventModule {

    @NonNull
    private String key;

    private String value;

    private String field;

    private int timeout;

    private TimeUnit timeoutUnit;
}

创建event类

BaseRedisEvent
package com.luojie.event;

import org.springframework.context.ApplicationEvent;

public abstract class BaseRedisEvent extends ApplicationEvent {
    public BaseRedisEvent(Object source) {
        super(source);
    }
}
RedisAddEvent
package com.luojie.event;

import com.luojie.moudle.RedisEventModule;
import org.apache.commons.lang3.StringUtils;

public class RedisAddEvent extends BaseRedisEvent {

    public RedisEventModule eventModule;

    public RedisAddEvent(RedisEventModule source) {
        super(source);
        if (StringUtils.isBlank(source.getValue())) {
            throw new IllegalArgumentException("redis value can't be empty");
        }
        this.eventModule = source;
    }
}
RedisDeleteEvent
package com.luojie.event;

import com.luojie.moudle.RedisEventModule;

public class RedisDeleteEvent extends BaseRedisEvent{

    public RedisEventModule eventModule;

    public RedisDeleteEvent(RedisEventModule source) {
        super(source);
        this.eventModule = source;
    }
}

创建监听类

package com.luojie.config.eventListener;

import com.luojie.event.BaseRedisEvent;
import com.luojie.event.RedisAddEvent;
import com.luojie.event.RedisDeleteEvent;
import com.luojie.moudle.RedisEventModule;
import com.luojie.util.RedisServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class RedisListener implements ApplicationListener<BaseRedisEvent> {

    @Autowired
    private RedisServiceUtil redisServiceUtil;

    @Override
    @Async("asyncExecutor") // 使用异步线程池进行处理
    public void onApplicationEvent(BaseRedisEvent redisEvent) {
        if (redisEvent instanceof RedisAddEvent) {
            handleAddEvent((RedisAddEvent) redisEvent);
        } else if (redisEvent instanceof RedisDeleteEvent) {
            handleDeleteEvent((RedisDeleteEvent) redisEvent);
        }
    }

    private void handleAddEvent(RedisAddEvent redisEvent) {
        log.info("RedisAddEvent:{}", redisEvent);
        RedisEventModule module = redisEvent.eventModule;
        if (StringUtils.isNotBlank(module.getField()) && module.getTimeout() != 0) {
            redisServiceUtil.setHashWithExpire(module.getKey(), module.getField(), module.getValue(),
                    module.getTimeout(), module.getTimeoutUnit());
        } else if (StringUtils.isNotBlank(module.getField())) {
            redisServiceUtil.setHash(module.getKey(), module.getField(), module.getValue());
        } else if (module.getTimeout() != 0){
            redisServiceUtil.setWithExpire(module.getKey(), module.getValue(),
                    module.getTimeout(), module.getTimeoutUnit());
        } else {
            redisServiceUtil.set(module.getKey(), module.getValue());
        }
    }

    private void handleDeleteEvent(RedisDeleteEvent redisEvent) {
        log.info("RedisDeleteEvent:{}", redisEvent);
        RedisEventModule module = redisEvent.eventModule;
        if (StringUtils.isNotBlank(module.getField()) ) {
            redisServiceUtil.deleteHash(module.getKey(), module.getField());
        } else {
            redisServiceUtil.delete(module.getKey());
        }
    }

}

异步线程池类

package com.luojie.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class AsyncPools {

    @Bean(name = "asyncExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10); // 设置核心线程数
        executor.setMaxPoolSize(20); // 设置最大线程数
        executor.setQueueCapacity(100); // 设置队列容量
        executor.setThreadNamePrefix("async-executor-"); // 设置线程名前缀
        executor.setKeepAliveSeconds(5000);// 设置线程最大等待时间
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());// 设置线程拒绝策略
        executor.initialize();
        return executor;
    }

}

3,创建controller测试使用

controller

package com.luojie.controller;

import com.luojie.event.RedisAddEvent;
import com.luojie.event.RedisDeleteEvent;
import com.luojie.event.RojerEvent;
import com.luojie.moudle.RedisEventModule;
import com.luojie.util.RedisServiceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedisTestController {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Autowired
    private RedisServiceUtil redisServiceUtil;

    @PostMapping("/redis/test1")
    public Object redisTest1(@RequestBody RedisEventModule module) throws InterruptedException {
        // 测试普通string
        eventPublisher.publishEvent(new RedisAddEvent(module));
        // 获取刚存入的value
        Thread.sleep(3000);
        String re = redisServiceUtil.get(module.getKey());
        System.out.println(re);
        // 测试删除
        eventPublisher.publishEvent(new RedisDeleteEvent(module));
        Thread.sleep(3000);
        System.out.println("删除之后re的值: " + redisServiceUtil.get(module.getKey()));
        return re;
    }

    @PostMapping("/redis/test2")
    public Object redisTest2(@RequestBody RedisEventModule module) throws InterruptedException {
        // 测试普通string
        eventPublisher.publishEvent(new RedisAddEvent(module));
        // 获取刚存入的value
        Thread.sleep(3000);
        String hash = redisServiceUtil.getHash(module.getKey(), module.getField());
        System.out.println(hash);
        eventPublisher.publishEvent(new RedisDeleteEvent(module));
        Thread.sleep(3000);
        System.out.println("删除之后re的值: " + redisServiceUtil.getHash(module.getKey(),
                module.getField()));
        return hash;
    }
}

测试字符串存入删除情况

存入值已获取

已存入值删除

测试成功

测试hash测存入和删除

存入后正常获取

存入值删除成功

测试成功

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

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

相关文章

整洁架构SOLID-里氏替换原则(LSP)

文章目录 定义LSP继承实践正例反例 LSP软件架构实践反例 小结 定义 1988年&#xff0c;Barbara Liskov在描述如何定义子类型时写下了这样一段话&#xff1a; 这里需要的是一种可替换性&#xff1a;如果对于每个类型是S的对象o1都存在一个类型为T的对象o2&#xff0c;能使操作T…

牛客TOP101:合并k个已排序的链表

文章目录 1. 题目描述2. 解题思路3. 代码实现 1. 题目描述 2. 解题思路 多个链表的合并本质上可以看成两个链表的合并&#xff0c;只不过需要进行多次。最简单的方法就是一个一个链表&#xff0c;按照合并两个有序链表的思路&#xff0c;循环多次就可以了。   另外一个思路&a…

PySide(PyQt),csv文件的显示

1、正常显示csv文件 import sys import csv from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QWidgetclass CSVTableWidgetDemo(QMainWindow):def __init__(self):super().__init__()# 创建显示控件self.widget QWidget(self)sel…

improve-前端运行项目内存溢出解决

1.场景 运行项目时&#xff0c;out of memory&#xff0c;内存溢出。导致前端运行需要重启项目。 2.解决 2.1删除缓存 删除依赖包中的cacle临时缓存 2.2 更改项目配置 "scripts": {"serve": "node --max_old_space_size5120 node_modules/vue/cli-s…

C++基础知识:C++内存分区模型,全局变量和静态变量以及常量,常量区,字符串常量和其他常量,栈区,堆区,代码区和全局区

1.C内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区:存放函数体的二进制代码&#xff0c;由操作系统进行管理的&#xff08;在编译器中所书写的代码都会存放在这个空间。&#xff09; 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分…

最优控制公式推导(代数里卡提方程,李雅普诺夫方程,HJB方程)

本文探讨了线性时不变系统&#xff08;LTI系统&#xff09;的最优控制问题&#xff0c;特别是线性二次调节器&#xff08;LQR&#xff09;问题。通过Hamilton-Jacobi-Bellman (HJB) 方程的推导&#xff0c;求得了系统的最优控制律&#xff0c;并进一步推导了代数里卡提方程&…

书生浦语-大模型平台学习-环境搭建01

任务&#xff1a;完成SSH连接与端口映射并运行hello_world.py 详细步骤详见&#xff1a;https://github.com/InternLM/Tutorial/blob/camp3/docs/L0/Linux/readme.md 1、InternStudio介绍 InternStudio 是大模型时代下的云端算力平台。基于 InternLM 组织下的诸多算法库支持…

Win10+Docker环境使用YOLOv8 TensorRT推理加速

这一部分内容和WSL-Ubuntu20.04环境使用YOLOv8 TensorRT推理加速-CSDN博客 是基本相同的,有细微差别我也会在文中指出来。 1.TensorRTX下载 这里使用Wang-xinyu大佬维护的TensorRTX库来对YOLOv8进行推理加速的演示,顺便也验证一下前面环境配置的成果。 github地址:GitHub -…

推荐系统之MIND用户多兴趣网络

目录 引言MIND算法原理1. 算法概述2. 模型结构3. 多兴趣提取层4. 标签感知注意力层 实践应用应用场景1. 电商平台2. 社交媒体3. 视频流媒体4. 内容分发平台 结论 引言 随着大数据和人工智能技术的快速发展&#xff0c;推荐系统已成为电商平台、社交媒体和内容分发平台的重要组成…

写给大数据开发:为什么我们容易不信任数据

目录 1. 产品经理视角&#xff1a;数据优先级低故事与示例伪代码示例 2. 开发者视角&#xff1a;数据任务缺乏技术挑战故事与示例伪代码示例 3. 测试人员视角&#xff1a;数据的不可见性和逻辑复杂性故事与示例伪代码示例 4. 组织文化视角&#xff1a;缺乏数据意识故事与示例伪…

国外UI设计赏析—汽车行业

国外汽车网页设计界面往往展现出几个显著的优点&#xff0c;这些优点不仅提升了用户体验&#xff0c;还增强了品牌形象与产品吸引力。首先&#xff0c;它们注重界面设计的直观性与互动性&#xff0c;通过高清大图、动态效果以及简洁明了的布局&#xff0c;让用户能够一目了然地…

etime:拓展time

拓展C库的time模块&#xff0c;时间格式转换、代码块计时器。

35+打工人:岁月不是枷锁,是经验的徽章

即将8月份上映的电影《逆行人生》以其独特的视角&#xff0c;深刻揭示了一位45岁程序员面对职场年龄歧视的心酸历程&#xff0c;最终选择投身外卖行业的生存抉择。影片不仅触动了观众的心弦&#xff0c;更映射出当下社会就业市场的一隅现实&#xff0c;尤其是在今年应届毕业生人…

[Spring] Spring Web MVC案例实战

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

Qt会议室项目

在Qt中编写会议室应用程序通常涉及到用户界面设计、网络通信、音频/视频处理等方面。以下是创建一个基本会议室应用程序的步骤概述&#xff1a; 项目设置&#xff1a; 使用Qt Creator创建一个新的Qt Widgets Application或Qt Quick Application项目。 用户界面设计&#xff1…

明日周刊-第16期

最近很想去看一场蔡健雅的演唱会&#xff0c;以前从来没去过演唱会。原先是想把第一次机会留给周杰伦的演唱会&#xff0c;但是周董的票太难抢了。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 一、经济与市场 北京二手房价环比上涨&#xff1a; 6月份&#xff0c;北京二…

【Diffusion学习】【生成式AI】Diffusion Model 原理剖析 (2/4) (optional)【公式推导】

文章目录 影像生成模型本质上的共同目标【拟合分布】Maximum Likelihood Estimation VAE 影像生成模型本质上的共同目标【拟合分布】 Maximum Likelihood Estimation VAE

19.x86游戏实战-创建MFC动态链接库

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

【智能算法改进】改进的麻雀搜索算法及其求解旅行商问题

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】麻雀搜索算法&#xff08;SSA&#xff09;原理及实现 2.改进点 改进发现者更新位置 为了使 SSA 算法能够避开向原点收敛的弊端, 将算法向最优位置跳跃的操作转换为向最优位置的移动: X i ,…

[Java IO] 流原理及流的分类

Java IO 流概念 Java IO&#xff08;输入/输出&#xff09;流是Java用于处理输入和输出操作的一种方式。 Java IO 系统主要基于流&#xff08;Stream&#xff09;的概念&#xff0c;流是一组有序的数据序列&#xff0c;可以是输入流&#xff08;从数据源读取数据&#xff09;或…