RedisTemplate详解

一、SpringDataRedis简单介绍及引入

SpringData是Spring中数据操作的模块,包括对各种数据库的集成,其中对Redis的集成模块就叫SpringDataRedis

官网地址:https://spring.io/projects/spring-data-redis

1.1 特点:

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring独享的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同的数据类型的操作API封装到了不同的类型中:
在这里插入图片描述

二、SpringDataRedis的使用

2.1 依赖注入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!--        连接池依赖-->
<dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-pool2</artifactId>
<dependency>

2.2配置文件


#我们不用再自己写编码了,直接配置就好了
spring:
  redis:
    host: 127.0.0.1
    port: 6379
#   database: 0   #默认就是0号库
#   password: 有密码的就可以设置 设置密码
    lettuce:
      pool:
        max-active: 8 #最大连接
        max-idle: 8   #最大控线连接
        min-idle: 0   #最小空闲连接
        max-wait: 100 #连接等待时间

RedisTemplate是Spring 自动装配的,在Spring框架载入的时候就自动装配了,所以我们不需要在取额外定义RedisTemplate了。
在这里插入图片描述

所以使用时我们只需要自动注入即可

@Autowired
private RedisTemplate redisTemplate

三、RedisTemplate的序列化问题

3.1 问题描述

比如说:

 valueOperations.set("city","beijing");

等价于在redis客户端执行

 set city "beijing"

但是实际我们去本地redis客户端去查看,发现并不是这样
在这里插入图片描述(注:这里使用的是Another redis destop manager),这是一个可视化redis内容和结构的软件,和navicat一样

这是因为在使用ValueOperations.set的时候,会进行序列化,上述结果实际是存储的是序列化之后的结果。所以即使在客户端使用 get city 也是得不到任何值的
在这里插入图片描述

这里的key实际存储的是\xac\xed等。

3.2 问题原因

这是为什么呢?

只是因为默认redisTemplate.opsForValue的set的形参类型都是Object类型
在这里插入图片描述

因为SpringDataRedis可以接受任何类型的对象,然后帮我们转化成Redis可以处理的字节

所以我们当我们存入String的值时会被当做了Java对象,注意哦!是java对象,而不是基本的数据类型。
所以你传入String类型,RedisTemplate默认是会将其作为对象进行处理而我们都知道java对象在传输的时候,会进行序列化。
而RedisTemplate底层对这些对象的处理方式就是使用JDK的序列化工具,序列化为字节形式
但是很遗憾,JDK自带的序列化工具不够“智能”。我们需要更加智能的序列化工具。我们知道在SpringMVC中也有序列化问题,
没错JSON它又来了。

3.3 问题解决

因为实际应用中对于key,基本都以字符串类型进行存储,所以对于key的序列化,我们常常使用StringRedisSerializer这一序列化器即可。
但是对于value的序列化要复杂很多。在实际开发中value的值可能时基本数据类型,可能时java对象等

所以这里可以使用Jackson2JsonRedisSerializer这个序列化器。

我们需要引入

<!--        引入Jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

当然,如果你是SpringBoot项目,那么SpringBoot自带Jackson序列化器,所以不需要显示引入。

@Configuration
public class RedisConfig {
    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(factory);
        //默认的Key序列化器为:JdkSerializationRedisSerializer
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer); // key的序列化类型

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        	redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // value的序列化类型
     redisTemplate.setHashKeySerializer(stringRedisSerializer);
		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

这样再测试一遍

会得到这样的key value
在这里插入图片描述

上图中配置的内容就是下图中的属性

在这里插入图片描述
默认的序列化器会在aftersetProperties方法里面设置。
在这里插入图片描述

四、几个Operations的使用

4.1 ValueOperations

下面是一些set方法

在这里插入图片描述

 /**
     * 对String类型的操作
     */
    @Test
    public void testString(){
        //获取ValueOperations对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //set city ""beijing"
        valueOperations.set("city","beijing");

        //get city
        String city = (String)valueOperations.get("city");//默认返回Object类型
        System.out.println(city);

        //set student "李明“ ex 10
        valueOperations.set("student","李明",10l, TimeUnit.SECONDS);

        //setnx city shanghai
        Boolean aBoolean = valueOperations.setIfAbsent("city", "shanghai");
        System.out.println(aBoolean);
    }

在这里插入图片描述

4.2 HashOperations

/**
     * 操作Hash类型的元素
     */
    @Test
    public void testHash(){
        //HashOperations是操作Hash结构的api集合
        HashOperations hashOperations = redisTemplate.opsForHash();

        hashOperations.put("user1","name","xiaoming");
        hashOperations.put("user1", "age",10);

        Map map = new HashMap();
        map.put("name,","lihua");
        map.put("age,",12);
        hashOperations.putAll("user2",map);

        System.out.println((String)hashOperations.get("user1", "name"));

        //获取所有的key
        Set user1 = hashOperations.keys("user1");
        for (Object key : user1) {
            System.out.println( key);
        }

        //获取所有的value
        List values = hashOperations.values("user1");
        for (Object value : values) {
            System.out.println( value);
        }
    }

在这里插入图片描述

4.3 ListOperations

/**
     * 操作list类型的元素
     */
    @Test
    public void testList(){

        ListOperations listOperations = redisTemplate.opsForList();

        listOperations.leftPush("key", "value1");
        listOperations.leftPushAll("key","value2","value3");

        List list = listOperations.range("key", 0, -1);
        for (Object o : list) {
            System.out.println(o);
        }

        Long size = listOperations.size("key");
        int lsize = size.intValue();
        for (int i = 0; i < lsize; i++) {
            Object value = listOperations.leftPop("key");
            System.out.println(value);

        }
    }

在这里插入图片描述

上述只是对redisTemplateAPI列举几个例子

更详细的API的使用可以去看这篇博客
https://blog.csdn.net/zzvar/article/details/118388897?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170486848716800180683954%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=170486848716800180683954&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogtop_positive~default-1-118388897-null-null.nonecase&utm_term=redistemplate%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95&spm=1018.2226.3001.4450

五、Redis存储对象的方案

5.1StringRedisTemplate序列化方案

StringRedisTemplate 是专门用来处理字符串的工具类

5.1.1 RedisTemplate序列化的问题

尽管JSON的序列化方式可以满足我们的需求,但依然存在着下图的问题:

当我们向Redis数据库存入一个实体类型的数据后

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private Integer age;
}
 向Redis中存一下数据
    @Test
    void testSaveUser(){
//      写入数据
        redisTemplate.opsForValue().set("user:100",new User("虎哥",21));
//      获取数据
        User o = (User) redisTemplate.opsForValue().get("user:100");
        System.out.println(o);
    }

为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入到JSON结果中并存入Redis,会带来额外的内存开销

在这里插入图片描述

为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key哈value,当要存储Java对象时,手动完成对象的序列化和反序列化

在这里插入图片描述

5.1.2 StringRedisTemplate序列化演示

Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式,省去了我们自定义RedisTemplate的过程(记得注释掉我们自定义的redisTemplate)

之前我们定义的那个配置文件也完全可以删除不要了

下面的程序比RedisTemplate多了一个序列化和反序列化,其他四一个样子的(前提value存储的是对象)

private static final ObjectMapper mapper = new ObjectMapper();

是SpringMVC中默认使用的JSON工具

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
//  JSON工具
    private static final ObjectMapper mapper = new ObjectMapper();
 
    @Test
    void testStringTemplate() throws JsonProcessingException {
//      准备对象
        User user = new User("虎哥", 18);
//      手动序列化
        String json = mapper.writeValueAsString(user);
//      写入一条数据到Redis
        stringRedisTemplate.opsForValue().set("user:200",json);
 
//      读取数据
        String s = stringRedisTemplate.opsForValue().get("user:200");
//      反序列化
        User user1 = mapper.readValue(s,User.class);
        System.out.println(user1);
    }

5.2 自定义RedisTemplate序列化

实际上。如果我们的value如果想用自定义序列化成的方式进行存储在实际开发中可能会遇到很多问题。其中问题主要在序列化本身上。
仔细想想上面使用StringRedisTemplate本质上和自定义没有区别。实际都是转化为String类型进行存储的,只不过,一个是在程序本身使用ObjectMapper这个工具手动序列化好在给redisTemplate。后者是将对象传入,在RedisTemplate内部通过一系列自定义的配置将其序列化为json字符串存入redis.

下面给一个我开发中常用的自定义RedisTemplate的模板

package com.sky.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.annotation.Resource;
import java.util.TimeZone;

/**
 * RedisConfig
 *
 * @author baixian
 * @date 2024-1-4
 *
 * 当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为
 * JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别,故设置为
StringRedisSerializer序列化器以及自己定义的序列化器
 */
@Configuration
@Slf4j
public class RedisConfiguration {

    @Resource
    RedisConnectionFactory redisConnectionFactory;
    @Bean("redisTemplate")
    public RedisTemplate<Object,Object> redisTemplate(){
        log.info("开始创建redis模板对象...");
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate();
        //设置redis的连接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        //redis 的 value的序列化器
        //构造value的序列化器,使用Jackson2JsonRedisSerializer,

        // 这个类是 Spring Data Redis 中提供的 Redis 数据序列化和反序列化的工具类,用于将对象序列化为 JSON 字符串。
        //Jackson2JsonRedisSerializer 的构造函数中传入了 Object.class,这个参数表示 Jackson 库在进行序列化和反序列化时要考虑所有类型的对象。
        // 具体来说,这是因为 Redis 存储的是键值对(key-value),其中值是序列化后的对象。
        //传入 Object.class 的作用是告诉 Jackson 库,当从 Redis 中读取值并进行反序列化时,
        // 它应该尝试将序列化后的 JSON 数据转换为 Object 类型的 Java 对象。这是为了通用性,因为 Redis 存储的值可能是任何类型的对象。

        //然而,这也意味着当你从 Redis 中读取值时,Jackson 会尝试将 JSON 数据转换为通用的 Object 类型。在实际的使用场景中,这可能导致一些问题,因为你可能期望反序列化后的对象是特定的类型,
        // 而不是通用的 Object。如果你知道存储在 Redis 中的值的类型,最好是将 Jackson2JsonRedisSerializer 的构造函数参数指定为具体的类型,而不是 Object.class。
        // 这样可以更精确地控制反序列化后的对象类型,避免潜在的类型转换问题。
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

//        ObjectMapper 是 Jackson 库中的一个关键类,负责执行 JSON 数据与 Java 对象之间的序列化和反序列化。ObjectMapper 的属性配置影响了序列化和反序列化的行为。
        ObjectMapper objectMapper = new ObjectMapper();

//        JsonAutoDetect.Visibility.ANY 表示所有字段都可见,不管其修饰符是什么(private、protected、public)。这样设置确保了对象的所有字段都会被序列化,不论其修饰符是什么。
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        //LaissezFaireSubTypeValidator.instance:这是 Jackson 提供的默认子类型验证器,用于验证类型信息。
        //ObjectMapper.DefaultTyping.NON_FINAL:表示默认情况下,只为非 final 类型保留类型信息。这有助于减少序列化后的 JSON 数据的大小。
        //JsonTypeInfo.As.PROPERTY:表示类型信息将作为 JSON 属性添加到序列化后的数据中。这意味着 JSON 数据中将包含一个字段,用于存储对象的类型信息。
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        //设置时区信息否则java8中的LocalDateTime在遵循jackson2JsonRedisSerializer序列化的时候就会有问题。
        //参考博客:https://blog.csdn.net/xing_hung/article/details/124309758?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170486832516800211595467%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170486832516800211595467&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduend~default-2-124309758-null-null.nonecase&utm_term=%20Could%20not%20write%20JSON%3A%20Java%208%20date%2Ftime%20type%20%60java.time.LocalDateTime%60%20not%20supported%20by%20default%3A%20add%20Module%20com.fasterxml.jackson.datatype%3Ajackson-datatype-jsr310%20to%20enable%20handling%20%28through%20referen&spm=1018.2226.3001.4450
//        objectMapper.registerModule(new JavaTimeModule()).setTimeZone(TimeZone.getDefault());

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

//      表示: value 以 JSON 格式进行序列化。这个序列化器使用了 Jackson 库进行 JSON 序列化。
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        //设置 Hash 结构中的 key 和 value 的序列化器
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        //redisTemplate.afterPropertiesSet() 是在配置 RedisTemplate 完成后进行的一步初始化操作。
        // 在 Spring 中,afterPropertiesSet() 方法是 InitializingBean 接口中定义的方法,在 bean 的属性设置完成后,由 Spring 容器自动调用。
        //在这里的具体场景中,RedisTemplate 在其属性设置完成后,需要进行一些初始化工作,确保它可以正确地与 Redis 进行交互。
        // afterPropertiesSet() 方法是在 Spring 容器完成 bean 的属性注入之后被调用的,用于执行一些初始化逻辑。
        //在 RedisTemplate 的源码中,afterPropertiesSet() 方法通常包含了一些必要的配置检查和初始化步骤。
        // 例如,它可能会检查连接工厂是否已经设置,序列化器是否已经配置等。这确保了在使用 RedisTemplate 进行操作之前,其内部的配置是正确的。
        redisTemplate.afterPropertiesSet();

        return redisTemplate;

这里还有几个问题需要说明一下:

1.不知道有没有小伙伴和我一样:对于

 @Resource
    RedisConnectionFactory redisConnectionFactory;

我一开始使用的是@Autowied注解,或者有的同学使用构造方法

public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)

这样去注入会发现idea报红了。
在这里插入图片描述
但是实际程序可以跑起来,并且没有业务上的错误,redis也正常存储。
这可能是jenkins的打包机制导致的。
在网上看有人windows 打包可以正常运行,所以猜测是加载机制导致对象还没有加载在spring容器导致无法获取。

六、ObjectMapper说明

ObjectMapper 是 Jackson 库中的一个关键类,负责执行 JSON 数据与 Java 对象之间的序列化和反序列化。ObjectMapper 的属性配置影响了序列化和反序列化的行为。
以下是一些 ObjectMapper 的常见属性和它们的影响:

  • SerializationFeature 和 DeserializationFeature:
    这两个枚举类型提供了一系列的特性,用于控制序列化和反序列化的行为。
    例如,SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 可以控制是否将 Date 对象序列化为时间戳。

  • Visibility: 通过设置可见性(visibility),可以控制序列化和反序列化时是否包含私有字段、公有字段、Getter 和 Setter 方法。这是通过 setVisibility() 方法进行配置的。

  • DefaultTyping: 决定是否在序列化时包含类型信息。使用 activateDefaultTyping() 方法,可以配置类型信息的保存方式,例如保存到属性中还是作为 JSON 对象的一个字段。

  • DateFormat 和 Locale: 这两个属性用于配置日期的格式和地区,对于日期类型的序列化和反序列化非常重要。

  • AnnotationIntrospector: 通过设置注解检查器,可以控制 Jackson 在进行序列化和反序列化时如何处理类和字段上的注解。这可以通过 setAnnotationIntrospector() 方法进行配置。

  • TypeFactory: 这个属性用于创建 Java 类型的实例,它影响了 Jackson 如何处理泛型类型和参数化类型。

  • JsonNodeFactory: 用于创建 JsonNode 对象,它影响了 Jackson 对 JSON 树结构的处理。

  • JsonInclude: 决定在序列化时是否包括空值以及如何处理默认值。通过 setSerializationInclusion() 方法进行配置。

  • PropertyNamingStrategy: 用于配置字段命名策略,控制序列化和反序列化时字段名的格式。

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

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

相关文章

观成科技-加密C2框架EvilOSX流量分析

工具简介 EvilOSX是一款开源的&#xff0c;由python编写专门为macOS系统设计的C2工具&#xff0c;该工具可以利用自身释放的木马来实现一系列集成功能&#xff0c;如键盘记录、文件捕获、浏览器历史记录爬取、截屏等。EvilOSX主要使用HTTP协议进行通信&#xff0c;通信内容为特…

公司新来的同事给出了if-else优化的8种方案

我们日常开发的项目中&#xff0c;如果代码中存在大量的if-else语句&#xff0c;阅读起来非常的折磨&#xff08;直接劝退&#xff09;&#xff0c;维护起来也很难&#xff0c;也特别容易出问题。比如说以下&#xff1a; 接下来&#xff0c;本文介绍我们常使用的8种方法去优化…

xinput1_4.dll缺失了怎么办?快速修复xinput1_4.dll文件的方法指南

在快速发展的数字时代&#xff0c;电子设备尤其是电脑成为了我们生活工作中必不可少的工具。然而&#xff0c;在使用过程中&#xff0c;我们可能会遇到各式各样的技术问题&#xff0c;其中一个常见问题是系统提示缺少 xinput1_4.dll文件。这个错误通常会在你尝试运行一个游戏或…

EF Core 在实际开发中,如何分层?

前言&#xff1a;什么是分层&#xff1f; 分层就是将 EF Core 放在单独的项目中&#xff0c;其它项目如 Asp.net core webapi 项目引用它这样的好处是解耦和项目职责的清晰划分&#xff0c;并且可以重用 EF Core 项目但是也会数据库迁移变得复杂起来 Step by step 步骤 创建一…

linux 安装 reids并使用Windows测试结果

要安装两个软件 Windows端安装下面的软件连接虚拟机中的redis Another Redis DeskTop Manager 安装和使用_another redis desktop怎么连接-CSDN博客 redis安装 查找可用版本 选择安装最多点赞的一个 安装完成后创建redis容器 docker run -t --name redis -p 6379:6379 -d r…

这6个设计小白学习网站,海量免费学习教程!

划到最后“阅读原文”——领取工具包&#xff08;超过1000工具&#xff0c;免费素材网站分享和行业报告&#xff09; Hi&#xff0c;我是胡猛夫~&#xff0c;专注于分享各类价值网站、高效工具&#xff01; ​更多资源&#xff0c;更多内容&#xff0c;欢迎交流&#xff01;公…

3d模型显示不出来?3d不显示全模型---模大狮模型网

如果3D模型在显示时不完整或者无法显示&#xff0c;可能有几个原因导致&#xff1a; 缩放问题&#xff1a;检查一下模型的缩放是否正确。有时候模型的缩放比例可能非常大或非常小&#xff0c;导致模型无法正确显示。尝试调整模型的缩放值&#xff0c;使其适合场景。 材质问题&…

主食冻干哪款好?十大放心主食冻干名单推荐

作为养猫的人&#xff0c;我们都知道每天最担心的事情就是如何为心爱的猫咪选择一款高品质的猫粮。我们都希望为猫咪提供最好的营养&#xff0c;让它们健康快乐地成长。然而&#xff0c;近期的一些事件&#xff0c;如百利猫粮生虫和VE主食冻干掰开有虫&#xff0c;让我们不得不…

Django的数据库模型的CharField字段的max_length参数与中文字符数的关系探索(参数max_length的单位是字符个数还是字节数?)

01-清理干净之前的数据库迁移信息 02-根据setting.py中的信息删除掉之前建立的数据库 03-删除之后重新创建数据库 04-models.py中创建数据库模型 from django.db import modelsclass User(models.Model):username models.CharField(max_length4)email models.EmailField(uni…

RabbitMQ安装和快速入门

文章目录 1. RabbitMQ2. 安装RabbitMQ2.1 创建shell文件2.2 编写shell文件2.3 检查rabbitmq状态2.4 设置开机自启动2.5 启动插件2.6 开放端口号2.7 创建用户2.8 登入管理页面 3. SpringBoot中集成RabbitMQ3.1 依赖安装3.2 SpringBoot配置3.3 RabbitMQ的配置类3.4 定义消费者和生…

【Cadence】sprobe的使用

实验目的&#xff1a;通过sprobe测试电路中某个节点的阻抗 这里通过sprobe测试输入阻抗&#xff0c;可以通过port来验证 设置如下&#xff1a; 说明&#xff1a;Z1代表sprobe往left看&#xff0c;Z2代表sprobe往right看 结果如下&#xff1a; 可以看到ZM1I0.Z2 顺便给出了I…

谷歌浏览器打不开设置

场景&#xff1a;谷歌浏览器页面空白&#xff0c;并且点击设置没有反应 忘记我是在哪找的解决方案了&#xff0c;先留个记号在这&#xff0c;方便下次查阅

0x53 区间DP

0x53 区间DP 到目前为止&#xff0c;我们介绍的线性DP一般从初态开始&#xff0c;沿着阶段的扩张向某个方向递推&#xff0c;直至计算出目标状态。区间DP也属于线性DP中的一种&#xff0c;它以“区间长度”作为DP的“阶段”&#xff0c;使用两个坐标&#xff08;区间的左右端点…

MongoDB查找命令find,让数据返回称心如意

业务系统接入数据库后&#xff0c;每天都有大量的数据写入数据库。面对逐日增加的数据&#xff0c;开发人员或数据分析人员&#xff0c;该如何读取数据&#xff0c;怎样设置条件&#xff0c;从数据库中查询数据&#xff1f; 本文基于mongodb的官方文档&#xff0c;整理出find命…

计算机组成原理-程序查询方式(流程图 演示过程 例题 定时查询 独占查询)

文章目录 总览IO方式简介程序查询方式程序查询方式流程图程序查询方式-例题小结 总览 IO方式简介 每次输一个字&#xff0c;就认为状态完成&#xff0c;CPU就会取走数据寄存器的内容 程序查询方式 此时模拟打印三个字符 假设此时三个字符在主存&#xff0c;CPU先从主存读一…

避免重复扣款:分布式支付系统的幂等性原理与实践

这是《百图解码支付系统设计与实现》专栏系列文章中的第&#xff08;6&#xff09;篇。 本文主要讲清楚什么是幂等性原理&#xff0c;在支付系统中的重要应用&#xff0c;业务幂等、全部幂等这些不同的幂等方案选型带来的收益和复杂度权衡&#xff0c;幂等击穿场景及可能的严重…

期末查分系统(c,链表实现)

主要功能&#xff1a; 分为三个身份: 学生:可以通过学号查询个人分数 老师&#xff1a;可以看所有学生成绩&#xff0c;单科排名&#xff08;正序&#xff0c;倒序&#xff09;&#xff0c;统计绩点&#xff0c;查看绩点排名前百分之n的学生 管理员端&#xff1a;可以创建链…

揭秘区块链的奥秘:链上智能如何诊断加密生态系统的健康状况

作者&#xff1a;shellyfootprint.network 数据源&#xff1a;Wallet Profile 在加密市场中&#xff0c;波动是家常便饭。就拿 2022 年来说&#xff0c;像 Terra、Celsius 和 FTX 这样的主要项目相继崩盘&#xff0c;搞得市场一片狼藉。这些情况往往让人措手不及&#xff0c;直…

openGauss学习笔记-192 openGauss 数据库运维-常见故障定位案例-XFS文件系统问题

文章目录 openGauss学习笔记-192 openGauss 数据库运维-常见故障定位案例-XFS文件系统问题192.1 在XFS文件系统中&#xff0c;使用du命令查询数据文件大小大于文件实际大小192.1.1 问题现象192.1.2 原因分析192.1.3 处理办法 192.2 在XFS文件系统中&#xff0c;出现文件损坏192…

工业智能网关如何保障数据通信安全

工业智能网关是组成工业物联网的重要设备&#xff0c;不仅可以起到数据交换、通信、边缘计算的功能&#xff0c;还可以发挥数据安全保障功能&#xff0c;保障工业物联网稳定、可持续。本篇就为大家简单介绍一下工业智能网关增强和确保数据通信安全的几种措施&#xff1a; 1、软…