Linux操作系统中Redis

1、什么是Redis

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

可以理解成一个大容量的map。

2、Redis的作用

可以做为数据库存储数据,也可以用来做缓存、计数器、分布式锁等。实际工作中很少用它做数据库。

3、Redis常用的五种基本类型【必问】

  • string:字符串数据类型

  • hash:类似于对象,map的形式

  • list:表示一种线性数据结构,队列或栈

  • set:无序不可重复集合

  • zset:有序不可重复集合

另外还有三种数据类型,都不是很常用。Geospatial、Bitmap、Hyperloglog

redis可以操作位(bit),但是工作中几乎不用。

4、安装redis

基于docker的安装

4.1、查询镜像文件【省略】

#可以不操作:
docker search redis

4.2、拉取镜像文件

docker pull redis:6.2.6

4.3、启动redis并设置密码

docker run -d --name redis-6379 -p 6379:6379 redis:6.2.6 --requirepass 123456

requirepass:设置密码

【工作时:】启动redis注意事项:

  • 密码一定要设置,复杂一点

  • 端口映射,redis一定不能用默认端口,用默认端口一定会被攻击

4.3.1、修改redis密码【可以不修改】

# 1/进入redis容器
docker exec -it redis-6379 /bin/bash
# 2/找到redis-cli可执行文件
cd /usr/local/bin
# 3/执行redis-cli
redis-cli
# 4/查看密码
config get requirepass
# 5/授权
auth 密码
# 6/修改密码
config set requirepass 新密码

第一步骤:进入redis容器

第二步骤:找到redis-cli可执行文件

第三步骤:执行redis-cli

第四步骤:查看密码(显示没有授权)

第五步骤:授权

第六步骤:修改密码(最好还是使用123456,后面整合的时候,容易忘记。)

第七步骤:退出容器

4.3.2、删除密码【坚决不推荐】

config set requirepass ''

5、SpringBoot整合

1、添加maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.jsoft</groupId><artifactId>demo-redis</artifactId><version>0.0.1-SNAPSHOT</version>
​<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.13</version></parent>
​<properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version><jwt.version>0.7.0</jwt.version><fastjson.version>1.2.60</fastjson.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>compile</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--json--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies>
​<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><classifier>exec</classifier></configuration></plugin></plugins></build>
</project>

2、添加redis配置

spring:  redis:host: 192.168.2.102port: 6379password: 123456

3、添加redisconfig

package com.jr.config;
​
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
​
@Configuration
public class RedisConfig {
​/*** 配置 RedisTemplate<String, Object>* 设置了键和值的序列化方式,键用字符串序列化,值用JSON序列化** @return RedisTemplate*/@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();StringRedisSerializer keySerialize = new StringRedisSerializer();RedisTemplate<String, Object> result = new RedisTemplate<>();result.setConnectionFactory(redisConnectionFactory);result.setKeySerializer(keySerialize);result.setValueSerializer(valueSerializer);result.setHashKeySerializer(keySerialize);result.setHashValueSerializer(valueSerializer);return result;}
​
}

4、添加SpringBoot启动类:

@SpringBootApplication
public class SpringBootMain {public static void main(String[] args) {SpringApplication.run(SpringBootMain.class);}+
}

5、常用方法介绍【必问,记住3-5方法】

1.redisTemplate

redisTemplate.hasKey(key);              //判断是否有key所对应的值,有则返回true,没有则返回false
redisTemplate.opsForValue().get(key);   //有则取出key值所对应的值
redisTemplate.delete(key);              //删除单个key值
redisTemplate.delete(keys);             //其中keys:Collection<K> keys
redisTemplate.dump(key);                //将当前传入的key值序列化为byte[]类型
redisTemplate.expire(key, timeout, unit);   //设置过期时间
redisTemplate.expireAt(key, date);      //设置过期时间
redisTemplate.keys(pattern);            //查找匹配的key值,返回一个Set集合类型
redisTemplate.rename(oldKey, newKey);   //返回传入key所存储的值的类型
redisTemplate.renameIfAbsent(oldKey, newKey);   //如果旧值存在时,将旧值改为新值
redisTemplate.randomKey();              //从redis中随机取出一个key
redisTemplate.getExpire(key);           //返回当前key所对应的剩余过期时间
redisTemplate.getExpire(key, unit);     //返回剩余过期时间并且指定时间单位
redisTemplate.persist(key);             //将key持久化保存
redisTemplate.move(key, dbIndex);       //将当前数据库的key移动到指定redis中数据库当中

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​@Testpublic void testCommon() {testCommon(KEY);}
​public void testCommon(String key) {boolean hasKey = redisTemplate.hasKey(key); //hasKey(key);log.info("hasKey {}", hasKey);boolean delete = redisTemplate.delete(key); //delete(key);log.info("delete {}", delete);}
​public void delete(String key) {boolean delete = redisTemplate.delete(key);}
}  

2.ValueOperations=>String

ValueOperations opsForValue = redisTemplate.opsForValue();
​
opsForValue.set(key, value);    //设置当前的key以及value值
opsForValue.set(key, value, offset);//用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
opsForValue.set(key, value, timeout, unit);  //设置当前的key以及value值并且设置过期时间
opsForValue.setBit(key, offset, value); //将二进制第offset位值变为value
opsForValue.setIfAbsent(key, value);//重新设置key对应的值,如果存在返回false,否则返回true
opsForValue.get(key, start, end);   //返回key中字符串的子字符
opsForValue.getAndSet(key, value);  //将旧的key设置为value,并且返回旧的key
opsForValue.multiGet(keys);         //批量获取值
opsForValue.size(key);              //获取字符串的长度
opsForValue.append(key, value); //在原有的值基础上新增字符串到末尾
opsForValue.increment(key,double increment);//以增量的方式将double值存储在变量中
opsForValue.increment(key,long  increment); //通过increment(K key, long delta)方法以增量方式存储long值(正值则自增,负值则自减)Map valueMap = new HashMap();  
valueMap.put("valueMap1","map1");  
valueMap.put("valueMap2","map2");  
valueMap.put("valueMap3","map3");  
opsForValue.multiSetIfAbsent(valueMap);     //如果对应的map集合名称不存在,则添加否则不做修改
opsForValue.multiSet(valueMap);             //设置map集合到redis
​

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​/*** - string:字符串数据类型*/@Testpublic void testString() {String key = "test:string";String key2 = "test:increment";String key3 = "test:object";delete(key);delete(key2);delete(key3);redisTemplate.opsForValue().set(key, "zhangsan");  // set(key, "zhangsan");Object value = redisTemplate.opsForValue().get(key); // get(key);log.info("value {}", value);redisTemplate.opsForValue().set(key, "lisi");value = redisTemplate.opsForValue().get(key);log.info("value {}", value);testCommon(key);boolean hasKey = redisTemplate.hasKey(key);log.info("hasKey {}", hasKey);redisTemplate.opsForValue().increment(key2, 10);// increment(key2, 10);计数器value = redisTemplate.opsForValue().get(key2);log.info("value {}", value);redisTemplate.opsForValue().increment(key2); // increment(key2); 涨1;increment(key2,10);涨10value = redisTemplate.opsForValue().get(key2);log.info("value {}", value);User user = new User();user.setName("zhangsan");user.setPassword("123456");redisTemplate.opsForValue().set(key3, user);value = redisTemplate.opsForValue().get(key3);log.info("value {}", value);}
}    

3.HashOperations=>Hash

HashOperations opsForHash = redisTemplate.opsForHash();
​
opsForHash.get(key, field); //获取变量中的指定map键是否有值,如果存在该map键则获取值,没有则返回null
opsForHash.entries(key);    //获取变量中的键值对
opsForHash.put(key, hashKey, value);    //新增hashMap值
opsForHash.putAll(key, maps);   //以map集合的形式添加键值对
opsForHash.putIfAbsent(key, hashKey, value);    //仅当hashKey不存在时才设置
opsForHash.delete(key, fields); //删除一个或者多个hash表字段
opsForHash.hasKey(key, field);  //查看hash表中指定字段是否存在
opsForHash.increment(key, field, long increment);   //给哈希表key中的指定字段的整数值加上增量increment
opsForHash.increment(key, field, double increment); //给哈希表key中的指定字段的整数值加上增量increment
opsForHash.keys(key);               //获取所有hash表中字段
opsForHash.values(key);             //获取hash表中存在的所有的值
opsForHash.scan(key, options);      //匹配获取键值对,ScanOptions.NONE为获取全部键对

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​/*** - hash:类似于对象,map的形式*/@Testpublic void testHash() {String key = "test:hash";redisTemplate.opsForHash().put(key, "name", "zhangsan");redisTemplate.opsForHash().put(key, "age", 12);Object name = redisTemplate.opsForHash().get(key, "name");Object age = redisTemplate.opsForHash().get(key, "age");log.info("name {}", name);log.info("age {}", age);}
}    

4.ListOperations=>List

ListOperations opsForList = redisTemplate.opsForList();
​
opsForList.index(key, index);   //通过索引获取列表中的元素
opsForList.range(key, start, end);  //获取列表指定范围内的元素(start开始位置, 0是开始位置,end 结束位置, -1返回所有)
opsForList.leftPush(key, value);    //存储在list的头部,即添加一个就把它放在最前面的索引处
opsForList.leftPush(key, pivot, value);     //如果pivot处值存在则在pivot前面添加
opsForList.leftPushAll(key, value);     //把多个值存入List中(value可以是多个值,也可以是一个Collection value)
opsForList.leftPushIfPresent(key, value);   //List存在的时候再加入
opsForList.rightPush(key, value);   //按照先进先出的顺序来添加(value可以是多个值,或者是Collection var2)
opsForList.rightPushAll(key, value);    //在pivot元素的右边添加值
opsForList.set(key, index, value);      //设置指定索引处元素的值
opsForList.trim(key, start, end);       //将List列表进行剪裁
opsForList.size(key);   //获取当前key的List列表长度//移除并获取列表中第一个元素(如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止)
opsForList.leftPop(key);                
opsForList.leftPop(key, timeout, unit); //移除并获取列表最后一个元素
opsForList.rightPop(key);
opsForList.rightPop(key, timeout, unit);    //从一个队列的右边弹出一个元素并将这个元素放入另一个指定队列的最左边
opsForList.rightPopAndLeftPush(sourceKey, destinationKey);  
opsForList.rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit);//删除集合中值等于value的元素(index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素)
opsForList.remove(key, index, value);

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​/*** - list:表示一种线性数据结构,队列或栈*/@Testpublic void testList() {String key = "test:list";log.info("----------------------- {}", "模拟队列");/*模拟队列*/for (int i = 0; i < 5; i++) {redisTemplate.opsForList().leftPush(key, i);}long listSize = redisTemplate.opsForList().size(key);log.info("listSize {}", listSize);for (int i = 0; i < listSize; i++) {log.info("test:list {}", redisTemplate.opsForList().rightPop(key));}listSize = redisTemplate.opsForList().size(key);log.info("listSize {}", listSize);log.info("----------------------- {}", "模拟栈");/*模拟栈*/for (int i = 0; i < 5; i++) {redisTemplate.opsForList().leftPush(key, i);}listSize = redisTemplate.opsForList().size(key);log.info("listSize {}", listSize);for (int i = 0; i < listSize; i++) {log.info("test:list {}", redisTemplate.opsForList().leftPop(key));}listSize = redisTemplate.opsForList().size(key);log.info("listSize {}", listSize);}
}   

5.SetOperations=>Set

SetOperations opsForSet = redisTemplate.opsForSet();
​
opsForSet.add(key, values);         //添加元素
opsForSet.remove(key, values);      //移除元素(单个值、多个值)
opsForSet.pop(key);                 //删除并且返回一个随机的元素
opsForSet.size(key);                //获取集合的大小
opsForSet.isMember(key, value);     //判断集合是否包含value
opsForSet.intersect(key, otherKey); //获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
opsForSet.intersect(key, otherKeys);//获取多个集合的交集(Collection var2)
opsForSet.intersectAndStore(key, otherKey, destKey);    //key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)
opsForSet.intersectAndStore(key, otherKeys, destKey);   //key集合与多个集合的交集存储到destKey无序集合中
opsForSet.union(key, otherKeys);    //获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)
opsForSet.unionAndStore(key, otherKey, destKey);    //key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)
opsForSet.difference(key, otherKeys);   //获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)
opsForSet.differenceAndStore(key, otherKey, destKey);   //差集存储到destKey中(otherKeys可以为单个值或者集合)
opsForSet.randomMember(key);    //随机获取集合中的一个元素
opsForSet.members(key);         //获取集合中的所有元素
opsForSet.randomMembers(key, count);    //随机获取集合中count个元素
opsForSet.distinctRandomMembers(key, count);    //获取多个key无序集合中的元素(去重),count表示个数
opsForSet.scan(key, options);   //遍历set类似于Interator(ScanOptions.NONE为显示所有的)

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​/*** - set:无序不可重复集合*/@Testpublic void testSet() {String key = "test:set";redisTemplate.opsForSet().add(key, "zhangsan", "lisi", "wangwu", 12, 22, 32, "wangwu", 12, "12");long listSize = redisTemplate.opsForSet().size(key);log.info("listSize {}", listSize);for (int i = 0; i < listSize; i++) {log.info("test:set {}", redisTemplate.opsForSet().pop(key));}listSize = redisTemplate.opsForSet().size(key);log.info("listSize {}", listSize);}
}   

6.ZSetOperations=>zSet

ZSetOperations提供了一系列方法对有序集合进行操作
ZSetOperations opsForZSet = redisTemplate.opsForZSet();
​
opsForZSet.add(key, value, score);              //添加元素(有序集合是按照元素的score值由小到大进行排列)
opsForZSet.remove(key, values);                 //删除对应的value,value可以为多个值
opsForZSet.incrementScore(key, value, delta);   //增加元素的score值,并返回增加后的值
opsForZSet.rank(key, value);                    //返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
opsForZSet.reverseRank(key, value);             //返回元素在集合的排名,按元素的score值由大到小排列
opsForZSet.reverseRangeWithScores(key, start,end);  //获取集合中给定区间的元素(start 开始位置,end 结束位置, -1查询所有)
opsForZSet.reverseRangeByScore(key, min, max);  //按照Score值查询集合中的元素,结果从小到大排序
opsForZSet.reverseRangeByScoreWithScores(key, min, max);    //返回值为:Set<ZSetOperations.TypedTuple<V>>
opsForZSet.count(key, min, max);                //根据score值获取集合元素数量
opsForZSet.size(key);                           //获取集合的大小
opsForZSet.zCard(key);                          //获取集合的大小
opsForZSet.score(key, value);                   //获取集合中key、value元素对应的score值
opsForZSet.removeRange(key, start, end);        //移除指定索引位置处的成员
opsForZSet.removeRangeByScore(key, min, max);   //移除指定score范围的集合成员
opsForZSet.unionAndStore(key, otherKey, destKey);//获取key和otherKey的并集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)
opsForZSet.intersectAndStore(key, otherKey, destKey);   //获取key和otherKey的交集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)

【测试代码】

@Slf4j
@SpringBootTest(classes = DemoHelloworldApplication.class)
@SuppressWarnings("all")
public class RedisTest {
​private static final String KEY = "test:commonKey";
​@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
​/*** - zset:有序不可重复集合*/@Testpublic void testZset() {String key = "test:zset";redisTemplate.opsForZSet().add(key, "zhangsan", 12);redisTemplate.opsForZSet().add(key, "lisi", 22);redisTemplate.opsForZSet().add(key, "wangwu", 32);redisTemplate.opsForZSet().add(key, "wangwu1", 121);redisTemplate.opsForZSet().add(key, "wangwu2", 122);redisTemplate.opsForZSet().add(key, "wangwu3", 123);redisTemplate.opsForZSet().add(key, "wangwu4", 124);redisTemplate.opsForZSet().add(key, "wangwu5", 125);redisTemplate.opsForZSet().add(key, "wangwu6", 126);Long zCard = redisTemplate.opsForZSet().zCard(key);//long listSize = redisTemplate.opsForZSet().size(key);log.info("zCard {}", zCard);log.info("listSize {}", listSize);
//        for (int i = 0; i < listSize; i++) {
//            log.info("test:set {}", redisTemplate.opsForZSet().popMax(key));
//        }listSize = redisTemplate.opsForZSet().size(key);log.info("listSize {}", listSize);log.info("----------------------- {}", "华丽的分割线");Set<Object> range = redisTemplate.opsForZSet().range(key, 1, 3);for (Object o : range) {log.info("range {}", o);}listSize = redisTemplate.opsForZSet().size(key);log.info("listSize {}", listSize);}
}

6、面试题:

1、缓存穿透
一、概念

  缓存穿透:缓存和数据库中都没有的数据,可用户还是源源不断的发起请求,导致每次请求都会到数据库,从而压垮数据库。

  如下图红色的流程:

  比如客户查询一个根本不存在的东西,首先从Redis中查不到,然后会去数据库中查询,数据库中也查询不到,那么就不会将数据放入到缓存中,后面如果还有类似源源不断的请求,最后都会压到数据库来处理,从而给数据库造成巨大的压力。

二、解决办法

①、业务层校验

  用户发过来的请求,根据请求参数进行校验,对于明显错误的参数,直接拦截返回。

  比如,请求参数为主键自增id,那么对于请求小于0的id参数,明显不符合,可以直接返回错误请求。

②、不存在数据设置短过期时间

对于某个查询为空的数据,可以将这个空结果进行Redis缓存,但是设置很短的过期时间,比如30s,可以根据实际业务设定。注意一定不要影响正常业务。

③、布隆过滤器

  关于布隆过滤器,后面会详细介绍。布隆过滤器是一种数据结构,利用极小的内存,可以判断大量的数据“一定不存在或者可能存在”。

  对于缓存击穿,我们可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。

2、缓存击穿
一、概念

  缓存击穿:Redis中一个热点key在失效的同时,大量的请求过来,从而会全部到达数据库,压垮数据库。

  这里要注意的是这是某一个热点key过期失效,和后面介绍缓存雪崩是有区别的。比如淘宝双十一,对于某个特价热门的商品信息,缓存在Redis中,刚好0点,这个商品信息在Redis中过期查不到了,这时候大量的用户又同时正好访问这个商品,就会造成大量的请求同时到达数据库。

二、解决办法

①、设置热点数据永不过期

  对于某个需要频繁获取的信息,缓存在Redis中,并设置其永不过期。当然这种方式比较粗暴,对于某些业务场景是不适合的。

②、定时更新

  比如这个热点数据的过期时间是1h,那么每到59minutes时,通过定时任务去更新这个热点key,并重新设置其过期时间。

  ③、互斥锁

这是解决缓存穿透比较常用的方法。

  互斥锁简单来说就是在Redis中根据key获得的value值为空时,先锁上,然后从数据库加载,加载完毕,释放锁。若其他线程也在请求该key时,发现获取锁失败,则睡眠一段时间(比如100ms)后重试。

3、缓存雪崩
一、概念

  缓存雪崩:Redis中缓存的数据大面积同时失效,或者Redis宕机,从而会导致大量请求直接到数据库,压垮数据库。

  对于一个业务系统,如果Redis宕机或大面积的key同时过期,会导致大量请求同时打到数据库,这是灾难性的问题。

二、解决办法

①、设置有效期均匀分布

  避免缓存设置相近的有效期,我们可以在设置有效期时增加随机值;

  或者统一规划有效期,使得过期时间均匀分布。

②、数据预热

  对于即将来临的大量请求,我们可以提前走一遍系统,将数据提前缓存在Redis中,并设置不同的过期时间。

③、保证Redis服务高可用

  前面我们介绍过Redis的哨兵模式和集群模式,为防止Redis集群单节点故障,可以通过这两种模式实现高可用。

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

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

相关文章

IPS和IDS分别适用于哪些网络环境和安全需求

IPS即入侵防御系统和IDS即入侵检测系统是网络安全中的重要工具。 IPS适用于企业内部网络、数据中心以及云环境等网络环境中。 在企业内部网络中&#xff0c;特别是关键业务系统和数据中心的防护。IPS能够实时监控网络流量、识别和阻止潜在的恶意攻击&#xff0c;如DDoS攻击、SQ…

针对考研的C语言学习(定制化快速掌握重点5)

顺序表 特点&#xff1a; 写代码主要就是增删改查&#xff01;&#xff01;&#xff01; 写代码的边界性非常重要以及考研插入和删除的位置都是从1开始&#xff0c;而数组下标是从0开始 【注】下标和位置的关系 线性表最重要的是插入和删除会涉及边界问题以及判断是否合法 …

nginx的安装和使用

源码安装 1.环境准备&#xff1a;卸载其他方式安装的web应用&#xff0c;防止端口冲突 2.下载nginx源码包 wget https://nginx.org/download/nginx-1.20.2.tar.gz 3.源码编译安装 yum install -y gcc pcre-devel zlib-devel #安装依赖包 useradd -M -s /sbin/nologin ngi…

资质申请中常见的错误有哪些?

在申请建筑资质的过程中&#xff0c;企业可能会犯一些常见的错误&#xff0c;以下是一些需要避免的错误&#xff1a; 1. 资料准备不充分&#xff1a; 申请资质需要提交大量的资料&#xff0c;包括企业法人资料、财务报表、业绩证明等。资料不齐全或不准确都可能导致申请失败。…

RXE RDMA测试学习环境搭建

测试环境信息 在ubuntu20.04.6 LTS (Focal Fossa)上建立RXE学习环境。 安装工具和依赖 sudo apt install automake libtool sudo apt install libibverbs-dev libibmad-dev librdmacm-dev libibumad-dev libpci-dev sudo apt-get install libibverbs1 ibverbs-utils librdmac…

【AI论文精读1】针对知识密集型NLP任务的检索增强生成(RAG原始论文)

目录 一、简介一句话简介作者、引用数、时间论文地址开源代码地址 二、摘要三、引言四、整体架构&#xff08;用一个例子来阐明&#xff09;场景例子&#xff1a;核心点&#xff1a; 五、方法 &#xff08;架构各部分详解&#xff09;5.1 模型1. RAG-Sequence Model2. RAG-Toke…

Python:Pip包的安装与原理(Windows系统)

相关内容 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 pip是Python的包管理工具&#xff0c;用于安装、升级和卸载Python包和依赖。它的全称是“Pip Installs Packages”&#xff0c;是Python生态系统中的标准包管理器。pip…

02Cesium中常用的鼠标事件

文章目录 02Cesium中常用的鼠标事件1、左键单击事件2、左键双击事件3、左键按下事件4、左键弹起事件5、中键按下事件6、中键弹起事件7、鼠标移动事件8、右键单击事件9、右键按下事件10、右键弹起事件11、鼠标滚轮事件具体在代码中的应用如下所示 02Cesium中常用的鼠标事件 Ces…

vue组合式api

一、ref&#xff08;基本类型数据&#xff0c;对象类型数据&#xff09; 1.作用&#xff1a;定义响应式变量 2.语法&#xff1a;let xxx ref(初始值) 3.返回值&#xff1a;一个RefImpl的实例对象&#xff0c;简称ref对象&#xff0c;ref对象的value属性是响应式的。 4.注意…

PCL 快速均匀下采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 快速均匀下采样 2.1.2 可视化原始点云和下采样后的点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#…

【有啥问啥】多目标跟踪SORT算法原理详解

多目标跟踪SORT算法原理详解 引言 多目标跟踪&#xff08;Multiple Object Tracking, MOT&#xff09;是计算机视觉领域的一个重要研究方向&#xff0c;广泛应用于视频监控、自动驾驶、人机交互等多个领域。其核心任务是在视频序列中持续、准确地识别和定位多个目标。SORT&am…

数据网格:数据去中心化的特征

在现代的数据管理架构理念中&#xff0c;常常会谈及数据网格&#xff0c;将它用来解决大规模、复杂数据环境下的数据管理和利用问题。本文将探讨数据网格的概念以及数据去中心化和数据网格的紧密联系。 一数据网格 数据网格定义&#xff1a;数据网格将数据视为一种产品&#x…

tailwindcss快速入门(上篇)

tailwindcss 相关链接 演示地址 演示地址 源码地址 源码地址 什么是 Tailwind Tailwind CSS 是一种 实用优先的 CSS 框架&#xff0c;它通过一组预定义的、基于类名的样式帮助开发者快速构建现代化、响应式的用户界面。与传统的 CSS 框架&#xff08;如 Bootstrap&#xf…

只申请一块sizeofimage的内存能否实现PE文件的拉伸

不能,别试了,浪费时间. 从最后一个节复制,也会被覆盖 BOOL StrechFileBuffer(__in char* m_fileName, __inout char** LPImageBuffer) {FILE* file (fopen(m_fileName, "rb"));if (file NULL){printf("error :%d", GetLastError());return FALSE;}// 从文…

工作日志:nvm版本控制遇到的一系列问题。

1、安装vue3可使用的富文本编辑器。&#xff08;https://www.wangeditor.com/v5/for-frame.html#demo-1&#xff09; npm install wangeditor/editor-for-vuenext --save2、为同时拥有两个类的元素设置样式&#xff0c;组合选择器是通过在选择器中并列写入两个类名来实现的&am…

PL3328CD直插DIP7/24W反激式开关电源芯片

PL3328CD 是一系列高效率、高集成度、原边调节的 PWM功率开关&#xff0c;其主要应用于 AC/DC 反激式开关电源。PL3328C通过去除光耦以及次级控制电路&#xff0c;简化了充电器/适配器等传统的恒流/恒压的设计&#xff0c;从而实现高精度的电压和电流调节&#xff0c;调节波形如…

zy85_C#中文件夹操作,Path,以及Environment类

文章目录 1.文件夹的操作1.1Directory类的部分方法1.2程序代码 2.Path2.1Path类的部分字段和方法2.2程序代码 3.Environment3.1Environment类3.2SpecialFolder类3.3程序代码 1.文件夹的操作 1.1Directory类的部分方法 1.2程序代码 try {string path "D:\01";if (D…

leetcode45:跳跃游戏||

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最小…

低空经济时代:无人机飞行安全要点详解

随着低空经济的蓬勃发展&#xff0c;无人机&#xff08;UAV&#xff09;在农业、航拍、物流、应急救援等多个领域的应用日益广泛。然而&#xff0c;无人机的安全飞行不仅关乎任务的成功与否&#xff0c;更直接关系到地面人员、财产及空中交通的安全。本文将从飞行前检查、环境评…

plt.bar函数介绍及实战

目录 plt.bar() 函数实战 plt.bar() 函数 plt.bar() 函数是 Matplotlib 中用于创建柱状图的函数。它用于在图形中绘制一个或多个柱状图&#xff0c;通常用于展示类别型数据的数量或大小的比较。 基本语法&#xff1a; plt.bar(x, height, width0.8, bottomNone, aligncenter…