Redis数据库 | 事务、持久化

在这里插入图片描述

💗wei_shuo的个人主页

💫wei_shuo的学习社区

🌐Hello World !


Redis事务操作

Redis事务是一组命令的集合,这些命令会作为一个整体被执行,要么全部执行成功,要么全部执行失败;Redis事务通过MULTI、EXEC、DISCARD和WATCH四个命令来实现

MULTI:开启一个新的事务

EXEC:提交事务

DISCARD:取消事务

WATCH:监控一个或多个键,当这些键被其他客户端修改时,当前事务会被中断

Redis乐观锁

乐观锁是一种并发控制机制,它假设冲突的概率比较小,因此不会在访问共享资源时加锁,而是在更新时检查数据是否被其他进程修改过

Redis悲观锁

悲观锁是指在对共享资源进行操作时,认为其他线程或进程会对该资源进行修改,因此在操作前先加锁,以防止其他线程或进程的干扰

Jedis

Jedis是一个Java语言编写的Redis客户端库,用于在Java应用程序中连接和操作Redis数据库;Jedis库是开源的,可以通过Maven或Gradle等构建工具进行引入和使用

<dependency>
   <groupId>com.github.luues.boot</groupId>
   <artifactId>spring-boot-starter-jedis</artifactId>
   <version>1.0.3.5.RELEASE</version>
</dependency>

Springboot集成Redis

  • 依赖导入
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
  • application.properties
#配置Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
  • 测试
package com.wei;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class SpringbootRedisApplicationTests {

    @Autowired(required = false)
    private RedisTemplate redisTemplate;


    @Test
    void contextLoads() {
        /**
         * RedisTemplate    操作不同是数据类型
         * opsForValue  操作String
         * opsForList   操作List
         * opsForHash   操作Hash
         * ……
         */

        /**
         * 操作数据库连接
         * redisTemplate.getConnectionFactory().getConnection();
         */
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        /*
            connection.flushDb(); 用于刷新查询缓存和结果集合,以提高查询性能
            connection.flushAll(); 用于刷新整个数据库,包括所有的表、视图、存储过程和触发器等
         */
        connection.flushDb();
        connection.flushAll();

    }

}
package com.wei;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class SpringbootRedisApplicationTests {

    @Autowired(required = false)
    private RedisTemplate redisTemplate;


    @Test
    void contextLoads() {
        /**
         * RedisTemplate    操作不同是数据类型
         * opsForValue  操作String
         * opsForList   操作List
         * opsForHash   操作Hash
         * ……
         */

        redisTemplate.opsForValue().set("mykey","weishuo");
        System.out.println(redisTemplate.opsForValue().get("mykey"));

    }

}

源码

  • RedisAutoConfiguration.java
package org.springframework.boot.autoconfigure.data.redis;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

@AutoConfiguration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}
  • RedisProperties.java
public class RedisProperties {
    private int database = 0;
    private String url;
    private String host = "localhost";
    private String username;
    private String password;
    private int port = 6379;
    private boolean ssl;
    private Duration timeout;
    private Duration connectTimeout;
    private String clientName;
    private RedisProperties.ClientType clientType;
    private RedisProperties.Sentinel sentinel;
    private RedisProperties.Cluster cluster;
    private final RedisProperties.Jedis jedis = new RedisProperties.Jedis();
    private final RedisProperties.Lettuce lettuce = new RedisProperties.Lettuce();
    ……
}

自定义配置类

  • config/RedisConfig.java
package com.wei.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

@Configuration
@SuppressWarnings("all")
//镇压所有警告
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
//      默认的连接配置,和源码保持一致即可
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

//        序列化配置
//        json序列化配置--Jackson
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper);

//       string的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

//       string的key和hash的key都采用string的序列化
//        value都采用Jackson的序列化

        //key采用string序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //hash的key采用string序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        //value采用Jackson序列化方式
        template.setValueSerializer(objectJackson2JsonRedisSerializer);
        //hash的value采用Jackson序列化方式
        template.setHashValueSerializer(objectJackson2JsonRedisSerializer);

        return template;
    }
}

Redis工具类封装

utils/RedisUtil.java

package com.wei.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil {
 @Autowired
 private RedisTemplate<String, Object> redisTemplate;
// =============================common============================
 /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     */
    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 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    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 {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
// ============================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 如果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 要增加几(大于0)
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     * @param key 键
     * @param delta 要减少几(小于0)
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
// ================================Map=================================
    /**
     * HashGet
     * @param key 键 不能为null
     * @param item 项 不能为null
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     * @param key 键
     * @param map 对应多个键值
     */
    public boolean hmset(String key, Map<String, 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<String, 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 键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     *
     * @param key 键 不能为null
     * @param item 项 不能为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)
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * hash递减
     *
     * @param key 键
     * @param item 项
     * @param by 要减少记(小于0)
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
// ============================set=============================
    /**
     * 根据key获取Set中的所有值
     * @param key 键
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根据value从一个set中查询,是否存在
     *
     * @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 sSetAndTime(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 键
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值为value的
     *
     * @param key 键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
// ===============================list=================================
    /**
     * 获取list缓存的内容
     *
     * @param key 键
     * @param start 开始
     * @param end 结束 0 到 -1代表所有值
     */
    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 键
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 通过索引 获取list中的值
     *
     * @param key 键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0
    时,-1,表尾,-2倒数第二个元素,依次类推
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key 键
     * @param value 值
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     */
    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;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key 键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key 键
     * @param value 值
     * @param time 时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引修改list中的某条数据
     *
     * @param key 键
     * @param index 索引
     * @param value 值
     * @return
     */
    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;
        }
    }
    /**
     * 移除N个值为value
     *
     * @param key 键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count,
                    value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

Redis持久化

Redis 持久化的主要作用是将 Redis 的数据持久化到磁盘中,以防止 Redis 在内存中的数据意外丢失或者系统宕机导致的数据丢失,保证数据的可靠性和持久性;Redis 提供了两种持久化方式,分别是 RDB 和 AOF

RDB持久化

RDB 持久化:将 Redis 在内存中的数据定期写入磁盘中的快照文件,可以通过配置定期保存快照的时间间隔,也可以手动执行保存操作;RDB 持久化的优点是占用内存小,恢复数据速度快,适用于数据量较大,但是对数据实时性要求不高的场景

在这里插入图片描述

AOF持久化

AOF 持久化:将 Redis 的所有写操作都记录在一个日志文件中,可以通过配置日志文件的同步方式,确保数据的可靠性和实时性。AOF 持久化的优点是数据实时性高,可靠性强,适用于数据对实时性要求较高的场景

在这里插入图片描述


🌼 结语:创作不易,如果觉得博主的文章赏心悦目,还请——点赞👍收藏⭐️评论📝


在这里插入图片描述

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

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

相关文章

DASCTF 2023 0X401七月暑期挑战赛web复现

目录 <1> Web (1) EzFlask(python原型链污染&flask-pin) (2) MyPicDisk(xpath注入&文件名注入) (3) ez_cms(pearcmd文件包含) (4) ez_py(django框架 session处pickle反序列化) <1> Web (1) EzFlask(python原型链污染&flask-pin) 进入题目 得到源…

VSCode SSH远程连接与删除

1.ubuntu设置 安装SSH服务并获取远程访问的IP地址 在Ubuntu系统中&#xff0c;“CtrlAltT”打开终端工具&#xff0c;执行如下命令安装SSH服务。 sudo apt-get install openssh-server如果安装失败则先安装依赖项。 2.VS Code 设置 2.1安装与设置Remote SSH 打开Windows系…

初识集合和背后的数据结构

目录 集合 Java集合框架 数据结构 算法 集合 集合&#xff0c;是用来存放数据的容器。其主要表现为将多个元素置于一个单元中&#xff0c;用于对这些元素进行增删查改。例如&#xff0c;一副扑克牌(一组牌的集合)、一个邮箱(一组邮件的集合&#xff09;。 Java中有很多种集…

软件测试自动化selenuim的常用方法和属性总结

selenuim其实主要就是使用webdriver实例对象的方法和属性。 常用属性 1 driver.current_url 当前网页的请求地址 2 driver.current_window_handle 句柄&#xff0c;用于页面切换 3 driver.page_source 网页源代码 4 driver.title 网站的title&#xff0c;tab栏上显示的内容…

C# 图表控件库 ScottPlot

推荐使用ScottPlot原因&#xff1a; 1.图形界面简洁&#xff0c;样式丰富 2.代码较少 3.官方提供多种实例源码&#xff0c;并可以直接通过图形界面查看&#xff0c;便于快速开发 Github源码链接&#xff1a;https://github.com/ScottPlot/ScottPlot 官网WindowFrom Demo实例…

132个心理性格趣味测试ACCESS\EXCEL数据库

今天又遇到了一个心理测试的数据库&#xff0c;这个数据库在表结构的设置上很直观&#xff0c;属于那种好的数据库结构&#xff0c;共分三个表&#xff0c;一个是测试项目描述表、一个是测试题选项得分表、一个是根据得分区间解析表&#xff0c;表与表之间通过“question_id”字…

【基础类】—三栏页面布局的方案和优缺点

一、假设高度已知&#xff0c;中间宽度自适应&#xff0c;三栏&#xff08;列&#xff09;布局的方案有哪些&#xff1f; float浮动、absolute绝对定位、flex弹性盒子、table表格布局、grid网格布局 浮动 float <style>* {margin: 0;padding: 0;}.container {width: 1…

pytorch(6)——神经网络基本骨架nn.module的使用

1 神经网络框架 1.1 Module类的使用 NN (Neural network): 神经网络 Containers: 容器 Convolution Layers: 卷积层 Pooling layers: 池化层 Padding Layers: 填充层 Non-linear Activations (weighted sum, nonlinearity): 非线性激活 Non-linear Activations (other): 非线…

Kubernetes (k8s)理论介绍

一&#xff1a;K8s 简介 1、K8s作用 2、K8s 来历 3、为什么要用 K8S? 4、Kubernetes 功能 二&#xff1a;Kubernetes 集群架构与组件 1、Kubernetes 集群架构与组件 2、核心组件 -Master 组件 &#xff08;1&#xff09;Kube-apiserver &#xff08;2&#xff09;Kube…

python爬虫(五)_urllib2:Get请求和Post请求

本篇将介绍urllib2的Get和Post方法&#xff0c;更多内容请参考:python学习指南 urllib2默认只支持HTTP/HTTPS的GET和POST方法 urllib.urlencode() urllib和urllib2都是接受URL请求的相关参数&#xff0c;但是提供了不同的功能。两个最显著的不同如下&#xff1a; urllib仅可以…

【Apollo学习笔记】—— Cyber RT之调度

文章目录 前言相关代码整理 调度介绍Cyber RT的改进实时操作系统资源限制&优先级协程 Cyber RT调度策略任务窃取两种任务类型componen组件自定义任务 Cyber调度实践配置文件DAG文件cyber_launch文件component组件BUILD文件 问题参考 前言 本文是对Cyber RT的学习记录,文章可…

Kafka的零拷贝

传统的IO模型 如果要把磁盘中的某个文件发送到远程服务器需要经历以下几个步骤 (1) 从磁盘中读取文件的内容&#xff0c;然后拷贝到内核缓冲区 (2) CPU把内核缓冲区的数据赋值到用户空间的缓冲区 (3) 在用户程序中调用write方法&#xff0c;把用户缓冲区的数据拷贝到内核下面…

【普通人维护windows的方法,不中毒,不弹窗,不卡顿】

前言 IT人也是普通人&#xff0c;我就说说普通人维护电脑的方法。 我的电脑配置 给大家看看&#xff0c;配置一般&#xff0c;运行软件和游戏&#xff0c;可以保持基本流程 日常维护措施 我不太喜欢设定一些非主流的配置&#xff0c;下了一个360卫士,360其他的套餐可以不用下…

Python开发环境Spyder介绍

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 Spyder简介 Spyder (前身是 Pydee) 是一个强大的交互式 Python 语言开发环境&#xff0c; 提供高级的代码编辑、交互测试、调试等特性&#xff0c;支持包括 Windows、Linux 和 OS X 系统。 &#x1f447; &#x1f44…

备忘录模式——撤销功能的实现

1、简介 1.1、概述 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤。当新的状态无效或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原。当前很多软件都提供了撤销&#xff08;Undo&#xff09;操作&#xf…

Google Search Central (Google搜索支持的结构化数据标记)SEO开发设置

Google会根据结构化数据了解网页上的椰蓉&#xff0c;从而优化SEO排名。搜索引擎优化 (SEO) 是提高网站网页在搜索引擎上的曝光度以吸引更多相关流量的过程。 应用场景 海外独立站新闻网站所有需要SEO排名的网站基本都试用当然众多关于SEO的方法这只是其中一点&#xff0c;合理…

如何用断言帮助检测错误

Java中的断言通过测试我们认为是正确的代码来帮助检测错误。 使用assert关键字进行断言。 其语法为&#xff1a; assert condition; 这里condition是一个布尔表达式&#xff0c;我们假定在程序执行时为真。 启用断言 默认情况下&#xff0c;断言在运行时被禁用并被忽略。…

PHP语言基础知识(超详细)

文章目录 前言第一章 PHP语言学习介绍 1.1 PHP部署安装环境1.2 PHP代码工具选择 第二章 PHP代码基本语法 2.1 PHP函数知识介绍2.2 PHP常量变量介绍 2.2.1 PHP变量知识&#xff1a;2.2.2 PHP常量知识&#xff1a; 2.3 PHP注释信息介绍2.4 PHP数据类型介绍 2.4.1 整形数据类型2.4…

Vault数据备份恢复-MySQL

前言 Vault提供了可靠的功能来保护数据库和其他关键数据。 对于MySQL数据库,Vault提供了一个易于使用的解决方案,可以自动创建和管理定期备份,并支持从备份中快速恢复数据。本文将介绍Vault后端存储MySQL的备份恢复,包括如何设置Vault、如何进行数据备份和还原、如何保护…

day49-Springboot

Springboot 1. Springboot简介 1.1 简介&#xff1a;Springboot来简化Spring应用开发的一个框架&#xff0c;约定大于配置 1.2 优点&#xff1a; 可以快速的构建独立运行的Spring项目&#xff1b; 框架内有Servlet容器&#xff0c;无需依赖外部&#xff0c;所以不需要达成w…