Redis与SpringBoot的集成:自定义RedisTemplate类,创建一个工具类:可以帮助我们更好的使用redis中的API

news2024/11/24 17:44:35

这里使用的环境是在windows环境下,也可以放在服务器中,只要知道端口号和ip即可,如果有不知道怎么部署环境的可以看这篇文章去在Windows环境下去部署redis环境redis之jedis:通过redis的API与Java的集成_不想睡醒的梦的博客-CSDN博客

 开启redis服务

 创建一个spring boot项目

导入依赖

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

配置连接数据库的端口号和ip

spring.redis.host=127.0.0.1
spring.redis.port=6379

通过测试类,测试与redis数据库的连接,是否正常能够连接

@SpringBootTest
class RedisApplicationTests {

	@Resource
	private RedisTemplate redisTemplate;

	@Test
	void contextLoads() {

//		//获取数据库的连接
		RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
		System.out.println(connection.ping());
	}

}

运行测试类,看输出结果:成功连接

 

在测试类通过命令实现key的创建


@SpringBootTest
class RedisApplicationTests {

	@Resource
	private RedisTemplate redisTemplate;


	@Test
	void contextLoads() {
		//获取数据库的连接
		RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
		connection.flushDb();
		redisTemplate.opsForValue().set("key1","myc");
		System.out.println(redisTemplate.opsForValue().get("key1"));

	}

}

运行结果:

注意:redis中的命令有很多,在springboot中也都能够使用:如果有想要了解更多的朋友可以看这篇文章redis与Java的集成

通过客户端查看创建的key 

 出现了问题

问题原因:这是因为序列化产生的结果

 通过源码可以知道

  1. // 默认的 RedisTemplate 没有过多的设置,Redis 对象都是需要序列化的
  2. // 两个泛型都是 Object 的类型,我们使用需要强制转换,很不方便,预期是 <String, Object>

 通过@ConditionalOnMissingBean(name = "redisTemplate")我们能够知道,只有在系统中没有这个bean名字为redisTemplate才会调用这个bean所以我们可以通过自定义配置类redisTemplate通过自定义的序列化内容,可以让我们使用起来更加方便:这个类定义者各种方法的序列化方法

注意:这个类可以收藏起来,当作一个类的模板,因为在开发过程中,肯定会能够用到。

package com.redis.configure;


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.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;

@Configuration
public class Redis_Template {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 定义泛型为 <String, Object> 的 RedisTemplate
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        // 定义 Json 序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        // Json 转换工具
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 定义 String 序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

通过这种方法去创建key,看看能否被调用

重新执行测试类中的方法:

通过客户端看是否能够访问

 成功自定义redisTemplate类

还有一个问题,你是否发现redis与Java的集成代码十分的复杂

redisTemplate.opsForValue().set("key1","myc");

如果进入工作之中这可能大大的增加我们的作用量,不同的方法去需要调用不同的方法去执行命令,能不能写一个工具类,让我们更简单的解放双手

下面这个工具类,一定要收藏起来,因为它完全响应spring boot的目标极大的解放双手

package com.redis.tools;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * Redis 工具类
 *
 * @author LiaoHang
 * @date 2022-06-09 22:15
 */
@Component
public class RedisUtil {
    @Resource
    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) {
        // 如果返回值为 null,则返回 0L
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return Boolean.TRUE.equals(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);
    }
    // ===============================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 {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ============================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 {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ================================Hash 哈希=================================
    /**
     * 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);
    }
}

还是以那个创建key为例:看看代码


import javax.annotation.Resource;

@SpringBootTest
class RedisApplicationTests {


	@Autowired
	private RedisUtil redisUtil;

	@Test
	void contextLoads() {
	
		redisUtil.set("toolkey","myc");



	}

}

看运行结果

一行特别简单的代码即可:实现双手的解放 

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

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

相关文章

css的clip-path学习

文章目录 clip-path的几个值polygon多边形circle圆形ellipse椭圆形inset 矩形round后面是四个角的度数 一个简单的应用&#xff0c;比如画一段曲线 参考博文 clip-path的几个值 自己学习后&#xff0c;先把clip-path理解为在原图上绘制轮廓&#xff0c;显示的内容是轮廓内的内…

2023苹果商务管理模式分发app完全指南

随着苹果对企业级开发证书的管控越来越严格&#xff0c;越来越多的企业级证书到期后&#xff0c;苹果不再予以续约&#xff0c;但是很多app都有企业内部分发需求&#xff0c;不希望自己的应用被公开上架。这时候&#xff0c;我们可以参考苹果官方的建议&#xff0c;使用商务管理…

繁华三千如梦散,红尘俗世要释怀

岁月的折痕在眼角盛开&#xff0c;一深&#xff0c;一浅&#xff0c;交错着旧时光的梦。 梦里是累积的回忆&#xff0c;厚厚的凌乱一地。 那些&#xff0c;都是悄悄溜走的充满烟火气的日子。 生活像是流水账一般&#xff0c;就这样过了&#xff0c;一天又一天&#xff0c;一年…

ConcurrentHashMap进阶面试题

ConcurrentHashMap 1.8的优化 存储的时候的优化写数据的时候加锁的优化扩容时的优化&#xff0c;有一个协助扩容的概念计数器的优化&#xff0c;在记录元素个数时&#xff0c;使用的类似与longAdder的形式&#xff0c;不会过度消耗CPU资源 为什么多线程情况下longAdder会比ato…

人体工学椅真的很舒服

前言 人体工学椅是现代办公室中必不可少的家具之一。作为一款专门设计为舒适、健康和高效的椅子&#xff0c;它为人们提供了更好的工作和学习体验。 人体工学椅的设计理念是以人体工程学为基础&#xff0c;根据人体骨骼生理学、生物力学和心理学等多个角度进行科学的设计。它…

公路工程公路bim数据与GIS数据融合应用

摘要&#xff1a; BIM技术因其自身的协同性、可模拟性以及可视化优势&#xff0c;能够补足传统项目管理存在的短板&#xff0c;成为新一代项目管理模式。本文将运用BIM技术打造一体化管理平台&#xff0c;达到项目管理的智能化管理水平&#xff0c;实现更易维、更安全、更节能…

谈一谈数据库设计原则

到开发的时候才发现&#xff0c;原来后端不是最难的&#xff0c;最难得是数据库的设计&#xff0c;往往有时候开发新模块的时候才发现&#xff0c;之前数据库设计的一些问题&#xff0c;今天就来简单谈谈数据库设计方面的一些原则。 数据库范式 ​ 通过将数据结构分解成小的部…

第五十四章 Unity 移动平台输入(下)

本章节我们介绍一个模拟器插件。这种插件比较多&#xff0c;比如EasyTouch&#xff0c;Lean Touch&#xff0c;Joystick Pack等等。EasyTouch是一个使用非常广泛的插件&#xff0c;支持点击&#xff0c;拖拽&#xff0c;遥感等很多常用功能。不过遗憾的是&#xff0c;该插件已经…

[JAVA]直接插入排序

插入排序就像玩扑克牌一样&#xff0c;把元素按照大小插入到一个已经排好序的序列中&#xff0c;直到全部元素排好。 假设我们拿到了一个数组&#xff0c;请问我们该从哪一个元素开始着手于直接插入排序呢&#xff1f; 答案是&#xff1a;第二个元素 我们可以假设&#xff0c;第…

微服务测试如何测试?

本文将讨论微服务测试的重要性、挑战和最佳实践。 微服务架构是一种越来越流行的构建复杂分布式系统的方法。在此体系结构中&#xff0c;大型应用程序被分成较小的、独立的服务&#xff0c;这些服务通过网络相互通信。微服务测试是确保这些服务无缝协同工作的关键步骤。本文将…

《微服务实战》 第五章 Spring Cloud Netflix 之 Ribbon

前言 Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡和服务调用工具&#xff0c;其主要功能是提供客户端的负载均衡算法和服务调用。 1、负载均衡 负载均衡&#xff08;Load Balance&#xff09; &#xff0c;简单点说就是将用户的请求平摊分配到多个…

【论文阅读19】GloVe: Global Vectors for Word Representation

论文十问十答&#xff1a; Q1论文试图解决什么问题&#xff1f; Q2这是否是一个新的问题&#xff1f; Q3这篇文章要验证一个什么科学假设&#xff1f; Q4有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课题在领域内值得关注的研究员&#xff1f; Q5论文中提到的解决方…

Packet Tracer - 使用 CLI 配置并验证站点间 IPsec VPN

Packet Tracer - 使用 CLI 配置并验证站点间 IPsec VPN 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 交换机端口 R1 G0/0 192.168.1.1 255.255.255.0 不适用 S1 F0/1 S0/0/0 (DCE) 10.1.1.2 255.255.255.252 不适用 不适用 R2 G0/0 192.168.2.1 255.…

Oracle数据库安装教程,并实现公网远程连接

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

黑客的真实生活是怎样的?他们真的能挣很多钱么?

作者&#xff1a;l浪费的时间 黑客这一群体&#xff0c;在普通人眼中就是神一般的存在。 黑客差钱吗&#xff1f;他们不差钱。当然是靠装逼活着&#xff0c;很多黑客只想钻研技术攻破个大公司玩玩&#xff0c;搞得轰轰烈烈&#xff0c;就能吹一辈子牛了。 一、黑客靠什么赚钱…

Nginx静态资源防盗链

1.什么是资源盗链 简单地说&#xff0c;就是将别人的资源用到自己的页面展示给用户。 2.效果演示 1&#xff09;准备图片 这两张图片直接在浏览器中访问都是可以打开的。 github图片地址&#xff1a;https://github.githubassets.com/images/modules/site/home-campaign/her…

linux命令sort, uniq ,tr, cut,split,paste,eval

sort 以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序。比较原则是从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;最后将他们按升序输出。 语法格式: 格式1 sort [选项] 参数 格式2 cat file | sort 选顶选项含义-n按照数字进行排序…

MySQL8.0安装教程(很详细)

1.进入mysql官网 2.点击DOWNLOADS去下载页面&#xff0c;页面往下滚动&#xff0c;点击MySQL Community (GPL) Downloads 下载社区版 3.点击MySQL Installer for Windows–>选择window安装版 4.选择下面这一项&#xff0c;点击Download 5.点击No thanks, just start my down…

kali 装pwngdb报错版本不兼容

小白垃圾笔记而已&#xff0c;不建议阅读。 报错是这个&#xff1a; 安装pwndbg的时候报的错。 这个具体不知道啥原因&#xff0c;但是还好有师傅&#xff0c;其实这样装好后是可以用的&#xff0c;只是不兼容&#xff0c;可能有些功能会受限制。 师傅这样说&#xff1a; pwn…

权威报告:2030年企业将全面上云,隐私计算可保障数据上云安全可信

近日&#xff0c;国际权威机构Forrester发布了《亚太地区隐私保护技术&#xff08;PPTs&#xff09;现状》报告&#xff08;简称“报告”&#xff09;。报告显示&#xff0c;隐私保护技术在亚太地区发展强劲&#xff0c;76% 的决策者正在采用隐私计算来保护隐私和数据安全。For…