Redis快速上手篇(三)(事务+Idea的连接和使用)

news2024/12/27 16:14:23

Redis事务

可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

单独的隔离的操作

官网说明

https://redis.io/docs/interact/transactions/

MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。

        1.MULTI 用来组装一个事务;将命令存放到一个队列里面

        2.EXEC 用来执行一个事务;相当于mysql的//commit

        3.DISCARD 用来取消一个事务;相当于mysql的//rollback

        4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。

结束后统一执行

有关事务,经常会遇到的是两类错误:

调用 EXEC 之前的错误 如语法错误,事务不会被执行

调用 EXEC 之后的错误 如重复建,事务不会理睬错误(不会影响接下来的其他命令的执行)

WATCH

“WATCH”可以帮我们实现类似于“乐观锁”的效果,即 CAS(check and set)。

WATCH 本身的作用是“监视 key 是否被改动过”,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。

在 multi 之前 set year 修改了值所以 nil

事务回滚(discard)

事务冲突

比如涉及金钱的操作,导致金额负数

解决方案

悲观锁(Pessimistic Lock)

顾名思义,就是很悲观

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁

这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,

比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

每次都会上锁影响效率

乐观锁(Optimistic Lock)

顾名思义,就是很乐观

每次去拿数据的时候都认为别人不会修改,所以不会上锁,

但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

可以使用版本号等机制。乐观锁适用于多读的应用类型

这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

redis与idea的连接

ssm

添加redis的依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>

Jedis jds = new Jedis("IP")

jds.auth("密码")

jds.select(数据库) <!-- 0-15 -->

spring boot

加入redis的依赖

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


<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.6.0</version>
</dependency>


<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

编写配置文件

#设置reis的索引
spring.redis.database=15
#设置连接redis的密码
spring.redis.password=yyl
#设置的redis的服务器
spring.redis.host=192.168.159.34
#端口号
spring.redis.port=6379
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

设置配置类

package com.example.demo;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
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.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


import java.time.Duration;


@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
  /**
     * 连接池的设置
     *
     * @return
     */
    @Bean
    public JedisPoolConfig getJedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        return jedisPoolConfig;
    }


    /**
     * RedisTemplate
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }


    /**
     * 缓存处理
     * @param factory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

编写测试代码

spring-data-redis针对jedis提供了如下功能:

1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类

2. RedisTemplate 对五种数据结构分别定义了操作

操作字符串

redisTemplate.opsForValue();

操作hash

redisTemplate.opsForHash();

操作list

redisTemplate.opsForList();

操作set

redisTemplate.opsForSet();

操作有序set

redisTemplate.opsForZSet();

String类型与List类型

Set类型
添加元素
redisTemplate.opsForSet().add(key, values)
移除元素(单个值、多个值)
redisTemplate.opsForSet().remove(key, values)


删除并且返回一个随机的元素

redisTemplate.opsForSet().pop(key)


获取集合的大小

redisTemplate.opsForSet().size(key)


判断集合是否包含value
redisTemplate.opsForSet().isMember(key, value)


获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
redisTemplate.opsForSet().intersect(key, otherKey)


获取多个集合的交集(Collection var2)


redisTemplate.opsForSet().intersect(key, otherKeys)


key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)


redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey)


key集合与多个集合的交集存储到destKey无序集合中


redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey)


获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)


redisTemplate.opsForSet().union(key, otherKeys)


key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)


redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey)


获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)


redisTemplate.opsForSet().difference(key, otherKeys)


差集存储到destKey中(otherKeys可以为单个值或者集合)


redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey)


随机获取集合中的一个元素


redisTemplate.opsForSet().randomMember(key)


获取集合中的所有元素


redisTemplate.opsForSet().members(key)


随机获取集合中count个元素


redisTemplate.opsForSet().randomMembers(key, count)


获取多个key无序集合中的元素(去重),count表示个数


redisTemplate.opsForSet().distinctRandomMembers(key, count)


遍历set类似于Interator(ScanOptions.NONE为显示所有的)


redisTemplate.opsForSet().scan(key, options)
Hash类型
Long delete(H key, Object... hashKeys);
删除给定的哈希hashKeys
 
    System.out.println(template.opsForHash().delete("redisHash","name"));
    System.out.println(template.opsForHash().entries("redisHash"));
    1
    {class=6, age=28.1}
 
Boolean hasKey(H key, Object hashKey);
确定哈希hashKey是否存在
    System.out.println(template.opsForHash().hasKey("redisHash","666"));
    System.out.println(template.opsForHash().hasKey("redisHash","777"));
    true
    false
 
HV get(H key, Object hashKey);
从键中的哈希获取给定hashKey的值
    System.out.println(template.opsForHash().get("redisHash","age"));
    26
 
 Set<HK> keys(H key);
获取key所对应的散列表的key
    System.out.println(template.opsForHash().keys("redisHash"));
    //redisHash所对应的散列表为{class=1, name=666, age=27}
    [name, class, age]
 
Long size(H key);
获取key所对应的散列表的大小个数
    System.out.println(template.opsForHash().size("redisHash"));
    //redisHash所对应的散列表为{class=1, name=666, age=27}
    3
 
 void putAll(H key, Map<? extends HK, ? extends HV> m);
使用m中提供的多个散列字段设置到key对应的散列表中
 
    Map<String,Object> testMap = new HashMap();
    testMap.put("name","666");
    testMap.put("age",27);
    testMap.put("class","1");
    template.opsForHash().putAll("redisHash1",testMap);
    System.out.println(template.opsForHash().entries("redisHash1"));
    {class=1, name=jack, age=27}
 
 void put(H key, HK hashKey, HV value);
设置散列hashKey的值
 
    template.opsForHash().put("redisHash","name","666");
    template.opsForHash().put("redisHash","age",26);
    template.opsForHash().put("redisHash","class","6");
    System.out.println(template.opsForHash().entries("redisHash"));
    {age=26, class=6, name=666}
 
 List<HV> values(H key);
获取整个哈希存储的值根据密钥
    System.out.println(template.opsForHash().values("redisHash"));
    [tom, 26, 6]
 
 Map<HK, HV> entries(H key);
获取整个哈希存储根据密钥
    System.out.println(template.opsForHash().entries("redisHash"));
    {age=26, class=6, name=tom}

 Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options);
使用Cursor在key的hash中迭代,相当于迭代器。
    Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("redisHash", 
      ScanOptions.ScanOptions.NONE);
        while(curosr.hasNext()){
            Map.Entry<Object, Object> entry = curosr.next();
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    age:27
    class:6
    name:666

命令

操作

返回值

hash.delete(H key, Object... hashKeys)

删除,可以传入多个map的key【hdel】

Long

hash.hasKey(key, hashKey)

查看hash中的某个hashKey是否存在【hexists】

Boolean

hash.get(key, hashKey)

获取值【hget】

Object(HV 泛型约束对象)

hash.multiGet(H key, Collection<HK> hashKeys)

批量获取集合中的key对应的值【hmget】

List<HV>

hash.increment(H key, HK hashKey, long delta)

对值进行+(delta值)操作【】

Long

hash.increment(H key, HK hashKey, double delta)

~

double

hash.keys(key)

返回map内hashKey的集合【hkeys】

Set<HK>

hash.lengthOfValue(H key, HK hashKey)

返回查询键关联的值的长度,为null则返回0【hstrlen】

Long

hash.size(H key)

获取hashKey的个数【hlen】

Long

hash.putAll(H key, Map<? extends HK, ? extends HV> m)

相当于map的putAll【hmset】

void

hash.put(H key, HK hashKey, HV value)

设置值,添加hashKey-value,hashKay相当于map的key 【hset】

void

hash.putIfAbsent(H key, HK hashKey, HV value)

仅当hashKey不存在时设置值

Boolean

hash.values(key)

返回value的集合【hvals】

List<HV>

hase.entries(H key)

获取map【hgetall】

Map<HK, HV>

hash.scan(H key, ScanOptions options)

基于游标的迭代查询【hscan】

Cursor<Map.Entry<HK, HV>>(返回的Cursor要手动关闭,见下面示例2)

hash.getOperations()

返回RedisOperation,它就是redis操作的接口

RedisOperations<H, ?>

ZSet类型
Boolean add(K key, V value, double score);
新增一个有序集合,存在的话为false,不存在的话为true
  
  System.out.println(template.opsForZSet().add("zset1","zset-1",1.0));
  true
 Long add(K key, Set<TypedTuple<V>> tuples);
新增一个有序集合
    ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<>("zset-5",9.6);
    ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("zset-6",9.9);
    Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
    tuples.add(objectTypedTuple1);
    tuples.add(objectTypedTuple2);
    System.out.println(template.opsForZSet().add("zset1",tuples));
    System.out.println(template.opsForZSet().range("zset1",0,-1));
    [zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
Long remove(K key, Object... values);
从有序集合中移除一个或者多个元素
   System.out.println(template.opsForZSet().range("zset1",0,-1));
   System.out.println(template.opsForZSet().remove("zset1","zset-6"));
    System.out.println(template.opsForZSet().range("zset1",0,-1));
    [zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
    1
    [zset-1, zset-2, zset-3, zset-4, zset-5]
 Long rank(K key, Object o);
返回有序集中指定成员的排名,其中有序集成员按分数值递增(从小到大)顺序排列
 
    System.out.println(template.opsForZSet().range("zset1",0,-1));
    System.out.println(template.opsForZSet().rank("zset1","zset-2"));
    [zset-2, zset-1, zset-3, zset-4, zset-5]
    0   //表明排名第一
 
Set<V> range(K key, long start, long end);
通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列
    System.out.println(template.opsForZSet().range("zset1",0,-1));
    [zset-2, zset-1, zset-3, zset-4, zset-5]
Long count(K key, double min, double max);
通过分数返回有序集合指定区间内的成员个数
 
    System.out.println(template.opsForZSet().rangeByScore("zset1",0,5));
    System.out.println(template.opsForZSet().count("zset1",0,5));
    [zset-2, zset-1, zset-3]
    3
 
Long size(K key);
获取有序集合的成员数,内部调用的就是zCard方法

    System.out.println(template.opsForZSet().size("zset1"));
    6

 
 Double score(K key, Object o);
获取指定成员的score值
 
    System.out.println(template.opsForZSet().score("zset1","zset-1"));
    2.2
 
 
Long removeRange(K key, long start, long end);
移除指定索引位置的成员,其中有序集成员按分数值递增(从小到大)顺序排列
 
    System.out.println(template.opsForZSet().range("zset2",0,-1));
    System.out.println(template.opsForZSet().removeRange("zset2",1,2));
    System.out.println(template.opsForZSet().range("zset2",0,-1));
    [zset-1, zset-2, zset-3, zset-4]
    2
    [zset-1, zset-4]
 
 
Cursor<TypedTuple<V>> scan(K key, ScanOptions options);
遍历zset
    Cursor<ZSetOperations.TypedTuple<Object>> cursor = template.opsForZSet().scan("zzset1", ScanOptions.NONE);
        while (cursor.hasNext()){
           ZSetOperations.TypedTuple<Object> item = cursor.next();
           System.out.println(item.getValue() + ":" + item.getScore());
        }
    zset-1:1.0
    zset-2:2.0
    zset-3:3.0
    zset-4:6.0

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

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

相关文章

数据结构,及分类(存储分类、逻辑分类)介绍

一、数据结构&#xff1a; 数据是软件开发的核心。在软件开发过程中基本上就是对数据的新增、删除、修改、查看的操作。 如何合理存储数据&#xff0c;如何有效提升数据操作开发效率&#xff0c;都是软件开发中的重中之重。使用合理的数据结构是非常重要的。 1.1简介&#xff…

【Leetcode】【每日一题】【简单】2520. 统计能整除数字的位数

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/count-the-digits-that-divide-a…

分享53个ASP.NET源码总有一个是你想要的

分享53个ASP.NET源码总有一个是你想要的 链接&#xff1a;https://pan.baidu.com/s/1xvqgPHSty70VGlQHoy9NYw?pwd8888 提取码&#xff1a;8888 项目名称 ASP.Net 4.5 论坛源码&#xff0c;支持多数据库 Asp.Net Core 3.x博客同步应用案例 ASP.NET Core MVC SqlSugerCore…

安防监控项目---概要

文章目录 前言一、项目需求二、环境介绍三、关键点四、主框架分析总结 前言 各位小伙伴&#xff0c;在蛰伏了将近有半年的时间又要和大家分享新的知识了&#xff0c;这次和大家分享的是一个项目&#xff0c;因此呢我准备分项目阶段去和大家分享&#xff0c;希望大家都能够在每…

如何满足TIKTOK直播企业四大网络需求,轻松实现直播无卡顿?

说到企业海外直播&#xff0c;大家脑海里一下就想会想到当下爆火的TIKTOK平台&#xff0c;而随着TIKTOK在全球范围大面积铺开推广&#xff0c;不同国家不同市场的活跃用户数纷纷上涨&#xff0c;让更多的电商企业选择在TIKTOK上进行布局获得商机。 对于已布局TIKTOK直播或者待布…

【Linux】开发工具

目录 Linux编译器-gcc/g使用执行命令&#xff1a;我们的.o和库是如何链接的? make/Makefile依赖关系、依赖方法 Linux编译器-gcc/g使用 gcc只能编译c语言&#xff0c;g可以编译c语言也可以编译g 背景知识&#xff1a; 预处理&#xff08;进行宏替换)编译&#xff08;生成汇编)…

我的Windows10下的WSL的使用经历

微软每年都会举办Build开发者大会&#xff0c;近年来越来越受关注的Linux 子系统Windows Subsystem for Linux&#xff08;WSL&#xff09;已经很完善了&#xff0c;我抱着体验一把的心态&#xff0c;也来使用一下这个功能。 各位新手Linux朋友们&#xff0c;有没有想过怎么在…

ubuntu18.4(后改为20.4)部署chatglm2并进行基于 P-Tuning v2 的微调

下载驱动 NVIDIA显卡驱动官方下载地址 下载好对应驱动并放在某个目录下&#xff0c; 在Linux系统中安装NVIDIA显卡驱动前,建议先卸载Linux系统自带的显卡驱动nouveau。 禁用nouveau 首先&#xff0c;编辑黑名单配置。 vim /etc/modprobe.d/blacklist.conf 在文件的最后添加…

Python实现【亚马逊商品】数据采集

亚马逊作为最大的跨境电商平台之一&#xff0c;其产品一直备受关注&#xff0c;因此采集亚马逊产品功能也是部分卖家所需的&#xff0c;下面我们来了解一下采集亚马逊产品是如何操作的。 l 采集网站 【场景描述】采集亚马逊搜索关键词出来的商品信息。 【入口网址】https://…

MES系统在工业生产中的重要性与功能

MES系统在工业生产中的重要性体现在它的信息化管理能力。传统的生产管理方法主要依靠人工操作和纸质文档记录&#xff0c;效率低下且容易出错。而MES系统利用计算机技术和数据库管理&#xff0c;能够实时记录和监控生产数据&#xff0c;提供准确的生产情况分析报告&#xff0c;…

2023年中国高尔夫服饰市场规模、主要品牌及行业发展方向分析[图]

高尔夫服饰是指高尔夫运动的专用服饰&#xff0c;高尔夫运动作为商务交流的手段和工具&#xff0c;具有较强的商务属性&#xff0c;高尔夫服饰除了具备专业功能属性以外&#xff0c;具备较强的时尚性&#xff0c;适合于商务、日常、休闲等多场景穿戴。高尔夫服饰里的主要类别&a…

快速上手视频下载助手:简单操作,高效下载你心仪的影片

在如今的社交媒体时代&#xff0c;视频已成为人们生活中不可或缺的一部分。微信视频号作为新兴的视频平台&#xff0c;吸引了越来越多的用户。然而&#xff0c;与其他视频平台相比&#xff0c;微信视频号并不支持视频下载功能&#xff0c;给用户带来了不便。但是&#xff0c;不…

React之Jsx如何转换成真实DOM

一、是什么 react通过将组件编写的JSX映射到屏幕&#xff0c;以及组件中的状态发生了变化之后 React会将这些「变化」更新到屏幕上 在前面文章了解中&#xff0c;JSX通过babel最终转化成React.createElement这种形式&#xff0c;例如&#xff1a; <div>< img src&q…

Vue 2 生命周期与 Vue 3 生命周期:介绍与差别对比

目录 引言&#xff1a; 一、Vue 2 生命周期介绍&#xff1a; 二、Vue 3 生命周期介绍&#xff1a; 注册周期钩子​ 生命周期图示 生命周期 三、Vue 2 生命周期与 Vue 3 生命周期的差别对比&#xff1a; 引言&#xff1a; Vue.js 是一款流行的 JavaScript 框架&#xff0…

仿真数字正弦波发生器程序

1&#xff09;构建这个IOC程序的程序框架&#xff1a; orangepiorangepi5:/usr/local/EPICS/program/simScope$ ls bin configure db dbd iocBoot lib Makefile simScopeApp2&#xff09;修改configure下RELEASE文件&#xff0c;添加所需的支持模块&#xff0c;此IOC程…

ThinkPad电脑HDMI接口失灵如何解决?

ThinkPad电脑HDMI接口失灵如何解决&#xff1f; 如果平时正常使用的外接显示器&#xff0c;某天突然无法使用了&#xff0c;重新插拔依然无信号的话&#xff0c;可以打开系统的设备管理器&#xff08;快捷键winx&#xff09;&#xff0c;首先看一下监视器的识别情况&#xff0c…

人声分离神仙网站,用过都说好~

在生活中好听的音乐有千千万的&#xff0c;音乐是非常容易可以找到下载下来的&#xff0c;但是背景音乐相当不容易找的&#xff0c;我们看的某短视频的背景音乐我们觉得不错的&#xff0c;想要下载下来的时候&#xff0c;我们都会无从下手不知道如何才可以找到这个相关的背景音…

内网渗透-内网信息收集

内网信息收集 前言 当我们进行外网信息收集&#xff0c;漏洞探测以及漏洞利用后&#xff0c;获得了主机的权限后&#xff0c;我们需要扩大渗透的战果时&#xff0c;这是我们就要进行内网的渗透了&#xff0c;内网渗透最重要的还是前期的信息收集的操作了&#xff0c;就是我们的…

文件加密丨最值得收藏的3种方法

信息的安全性变得越来越重要。文件加密作为一种有效的信息安全保护手段&#xff0c;广泛应用于各类场景。 今天就分享3种值得小白收藏的文件加密的方法&#xff1a; 方法一 简单加密 简单加密是一种常见的文件加密方法&#xff0c;其原理是通过使用简单的加密算法和密钥&…

YUV格式详解

YUV 可以将亮度信息&#xff08;Y&#xff09;与色度信息&#xff08;UV&#xff09;分离&#xff0c;没有UV信息一样可以显示完整图像&#xff0c;只不过是黑白的,也是一种颜色编码方法&#xff0c;&#xff0c;YUV和RGB可以通过公式互相转换&#xff0c;图片中每一个像素的颜…