【Redis入门篇】| Redis的Java客户端

news2024/11/26 14:46:12

目录

一: Redis的Java客户端

1. Jedis快速入门

2. Jedis连接池

3. SpringDataRedis快速入门

4. RedisSerializer配置

5. StringRedisTemplate

图书推荐


一: Redis的Java客户端

在Redis官网中提供了各种语言的客户端,地址:https://redis.io/resources/clients/

Jedis:Redis命令作为方法名称,学习成本低,简单实用。但是Jedis实例是线程不安全的,多线程环境下需要基于连接池来使用。

lettuce:lettuce是基于Netty实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。

Redission:Redisson是一个基于Redis实现的分布式、可伸缩的Java数据结构集合。包含了诸如MapQueueLock SemaphoreAtomicLong等强大功能。

1. Jedis快速入门

Jedis的官网地址: https://github.com/redis/jedis,我们先来个快速入门:

(1)引入依赖

<!--jedis依赖-->
<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>3.7.0</version>
</dependency>
<!--单元测试依赖-->
<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
   <scope>test</scope>
</dependency>

(2)建立连接:直接alt+insert生成setUp方法

创建Jedis对象,输入IP和port;调用auth()方法输入密码,调用select()方法选择数据库!

@Before
public void setUp() throws Exception {
    // 建立接连
    jedis = new Jedis("192.168.2.129",6379);
    // 设置密码
    jedis.auth("123456");
    // 选择库
    jedis.select(0);
}

(3)进行操作测试:直接alt+insert生成测试方法,手动修改方法名即可

注:对于Jedis,方法体中所调用的方法,其实就是redis中的命令!

@Test
public void testString() {
   // 存数据
   String set = jedis.set("name", "张三");
   System.out.println("set = " + set);
   // 取数据
   String name = jedis.get("name");
   System.out.println("name = " + name);
}

(4)释放资源:直接alt+insert生成tearDown方法

@After
public void tearDown() throws Exception {
   if (jedis != null) {
        jedis.close();
   }
}

具体代码:

package com.zl.jedis;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {
    private Jedis jedis;

    // 建立连接
    @Before
    public void setUp() throws Exception {
        // 建立接连
        jedis = new Jedis("192.168.2.129",6379);
        // 设置密码
        jedis.auth("123456");
        // 选择库
        jedis.select(0);
    }

    // 操作
    @Test
    public void testString() {
        // 存数据
        String set = jedis.set("name", "张三");
        System.out.println("set = " + set);
        // 取数据
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }

    @After
    public void tearDown() throws Exception {
        if (jedis != null) {
            jedis.close();
        }
    }
}

执行结果:


2. Jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此推荐大家使用Jedis连接池代替Jedis的直连方式!

①首先定义一个工具类JedisConnectionFactory类,用来获取Jedis连接池对象;

②定义一个静态的成员变量JedisPool(jedis连接池);

③在静态代码块中,创建JedisPoolConfig对象(jedis的一些配置),并配置一些基本信息;

④创建jedis连接池对象JedisPool,参数就是JedisPoolConfig对象、IP、端口、密码等信息;

⑤最终调用JedisPool对象的getResource方法,获取连接池对象。

package com.zl.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {
    private static final JedisPool jedisPool;

    static {
        // 配置连接池
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接
        jedisPoolConfig.setMaxTotal(8);
        // 最大空闲连接
        jedisPoolConfig.setMaxIdle(8);
        // 最小空闲连接
        jedisPoolConfig.setMinIdle(0);
        // 设置最长等待时间
        jedisPoolConfig.setMaxWaitMillis(1000);
        // 创建连接池
        jedisPool = new JedisPool(jedisPoolConfig, "192.168.2.129", 6379, 1000, "123456");
    }

    // 获取Jedis对象
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}


3. SpringDataRedis快速入门

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis

①提供了对不同Redis客户端的整合(Lettuce和Jedis);

②提供了RedisTemplate统一API来操作Redis;

③支持Redis的发布订阅模型;

④支持Redis哨兵和Redis集群;

⑤支持基于Lettuce的响应式编程;

⑥支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化;

⑦支持基于Redis的JDKCollection实现;

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中(相对于直接使用jredis进行分组了):

API

返回值类型

说明

redisTemplate.opsForValue()

ValueOperations

操作String类型数据

redisTemplate.opsForHash()

HashOperations

操作Hash类型数据

redisTemplate.opsForList()

ListOperations

操作List类型数据

redisTemplate.opsForSet()

SetOperations

操作Set类型数据

redisTemplate.opsForZSet()

ZSetOperations

操作SortedSet类型数据

redisTemplate

通用的命令

SpringBoot已经提供了对SpringDataRedis的支持,SpringDataRedis的使用步骤:

①引入spring-boot-starter-data-redis起步依赖;

②在application.yml配置Redis信息;

③注入RedisTemplate;

(1)引入依赖

<!--Redis起步依赖-->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
<!--连接池依赖,无论是Jedis还是lettcue都是基于连接池的-->
  <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
  </dependency>

(2)application.yml配置文件

注:Spring默认引入的是lettuce,要想使用jedis还要引入jedis的依赖;但是无论是lettuce还是jedis都是基于连接池创建连接的,所以需要前面的commons-pool2连接池依赖。

spring:
  redis:
    host: 192.168.2.129
    port: 6379
    password: 123456
    lettuce:
      pool:
        max-active: 8 #最大连接
        max-idle: 8 #最大空闲连接
        min-idle: 0 #最小空闲连接
        max-wait: 100 #连接等待时间

(3)注入RedisTemplate并测试

package com.zl;

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

@SpringBootTest
class SpringDataRedisApplicationTests {
    // 注入RedisTemplate
    @Autowired
    private RedisTemplate redisTemplate;


    @Test
    void testString() {
        // 插入数据,参数不仅仅是字符串,Java对象也可以
        redisTemplate.opsForValue().set("name","小红");
        // 获取数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);

    }

}

执行结果:


4. RedisSerializer配置

SpringDataRedis的序列化方式:RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:

实际上这个key和value就是我们前面存入的小红(序列化后的结果);SpringDataRedis可以接收任何对象,怎么实现的?就是通过对象的数据进行序列化及反序列化!

从哪里可以看出是使用了JDK的序列化方式

缺点:

①可读性差;

②内存占用较大;

有其它的序列化方式吗?

①JdkSerializationRedisSerializer:使用JDK的序列化方式,前面我们已经用过了!

②StringRedisSerializer:专门处理字符串的类型,例如key基本上都是字符串!

③GenericJackson2JsonRedisSerializer:如果value是对象,建议使用这个!

怎样做到,所存即所得呢?我们可以自定义RedisTemplate的序列化方式,代码如下:

package com.zl.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
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.RedisSerializer;

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        // 创建RedisTemplate对象
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        // 连接工厂,这个工厂springboot会帮我们创建好
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }

}

其中RedisSerializer的string()方法就是使用了StringRedisSerializer的一个常量

因为使用了JSON序列化工具,所以还要引入JSON依赖

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

再次进行测试

package com.zl;

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

@SpringBootTest
class SpringDataRedisApplicationTests {
    // 注入RedisTemplate
    @Autowired
    private RedisTemplate<String,Object> redisTemplate; // 引用泛型


    @Test
    void testString() {
        // 插入数据,参数不仅仅是字符串,Java对象也可以
        redisTemplate.opsForValue().set("name","小红");
        // 获取数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);

    }

}

执行结果:

思考:如果使用Java对象呢? 

 给定一个User对象

package com.zl.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


// 使用以下注解需要引入lombok依赖
@Data // setter and getter
@NoArgsConstructor // 无参构造
@AllArgsConstructor  // 有参构造
public class User {
    private String name;
    private Integer age;
    
}

进行测试

package com.zl;

import com.zl.pojo.User;
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.core.RedisTemplate;

@SpringBootTest
class SpringDataRedisApplicationTests {
    // 注入RedisTemplate
    @Autowired
    private RedisTemplate redisTemplate; // 引用泛型


    @Test
    void testSaveUser() {
        // 插入数据
        redisTemplate.opsForValue().set("user",new User("张三",18));
        // 取出数据
        User user = (User) redisTemplate.opsForValue().get("user");
        System.out.println("user = " + user);
    }
}

执行结果:

图形界面客户端:

自动的把Java对象转换为JSON写入,当获取结果的时候也能反序列化为User对象;实际上在写入JSON的同时,把User的字节码名称也写进去了com.zl.pojo.User,通过这个属性在反序列化的时候转换成User对象!

注:为了在反序列化时知道对象的类型,不仅仅写了User对象的属性,还把类的class类型写入了Json结果中,存入redis,会带来额外的内存开销。


5. StringRedisTemplate

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

Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程!

所以,现在最重要的就是处理Java对象,手动序列化和反序列

(1)使用JSON工具ObjectMapper(SpringMVC处理Json工具):调用ObjectMapper对象writeValuesString()方法手动完成序列化,转换成json格式的字符串存入redis;调用ObjectMapper对象的readValue()方法手动完成反序列化,转换成Java对象!

(2)也可以使用fastjson是阿里巴巴的开源JSON解析库,需要引入fastjon依赖。然后调用JSONtoJSONString()方法,转换成json格式的字符串;调用JSON的parseObject()方法,转换成Java对象!

package com.zl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zl.pojo.User;
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.core.StringRedisTemplate;


@SpringBootTest
class ApplicationTest {
    // 注入StringRedisTemplate
    @Autowired
    private StringRedisTemplate stringredisTemplate;
    // JSON工具
    private static final ObjectMapper mapper = new ObjectMapper(); // ObjectMapper是SpringMVC处理Json的工具
    // fastjson是阿里巴巴的开源JSON解析库


    @Test
    void testString() {
        // 对于普通字符串步骤不变
        stringredisTemplate.opsForValue().set("name","小红");
        Object name = stringredisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);

    }

    @Test
    void testSaveUser() throws JsonProcessingException {
        // 对于Java对象加上手动转步骤
        // 准备Java对象
        User user = new User("虎哥", 18);
        // 手动序列化
        // String json = mapper.writeValueAsString(user); // 把Java对象转换成Json格式的字符串
        String json = JSON.toJSONString(user);
        // 写入redis
        stringredisTemplate.opsForValue().set("user",json);
        // 读取数据
        String val = stringredisTemplate.opsForValue().get("user"); // 读出来的是Json格式的字符串
        // 反序列化
        // User user1 = mapper.readValue(val, User.class);
        User user1 = JSON.parseObject(val, User.class);
        System.out.println("user1 = " + user1);


    }
}

执行结果:

图形界面客户端:

补充:对于其它类型结构可能就更偏向于JavaAPI的编写方式,例如:Hash结构

①对于存数据,不是使用hset()方法,在Spring中不是以命令名作为方法名,因为类似于Java中的HashMap结构,所以方法名与HashMap结构的保持一致,使用put()方法进行存取。

②对于取数据,不使用hget,使用的是get()方法取单个,如果取多个使用entrys()方法。

@Test
void testHash() {
    // 插入数据
    stringredisTemplate.opsForHash().put("user:100","name","张三");
    stringredisTemplate.opsForHash().put("user:100","age","18");
    // 取出数据
    Object name = stringredisTemplate.opsForHash().get("user:100", "name"); // 取一个
    Map<Object, Object> entries = stringredisTemplate.opsForHash().entries("user:100");
    System.out.println("entries = " + entries); // 取所有

}

总结RedisTemplate的两种序列化实践方案:

方案一:

①自定义RedisTemplate

②修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二:

①使用StringRedisTemplate

②写入Redis时,手动把对象序列化为JSON;读取Redis时,手动把读取到的JSON反序列化为对象

图书推荐

本期图书:《元宇宙Ⅱ:图解元技术区块链、元资产与Web3.0、元人与理想国(全三册)》、《产业链金融平台设计与实现》

参与方式:

本次送书 1 本(二选一哦)! 
活动时间:截止到 2023-05-09 00:00:00。

抽奖方式:利用程序进行抽奖。

参与方式:关注博主(只限粉丝福利哦)、点赞、收藏,评论区随机抽取,最多三条评论!

        看半小时漫画,通元宇宙未来100年,300幅手绘插图轻松读懂虚实共生的未来世界。剖析元宇宙三大定律、大统一方程、熵增定律、Web3.0、万亿元资产、元人与区块链文明,构建元宇宙大楼。讲透元技术区块链、元宇宙基石Web3.0到穿越未来的技术大革命。厘清8大产业规律和11大投资方向,从元宇宙经济学到财富自由2.0,构建NO.1无限∞世界的数字空间,从元人到理想国。

        这是一个全新的时代:Web3.0构建的经济体系,DID身份的跨平台操作,数字NFT的原子级镜像,以及DeFi的无摩擦元资产再分配......2022年,奇点出现:元人即将诞生;元资产即将分配;元宇宙正在成形。本套书通过元宇宙三大定律、大统一方程、熵增定律、Web3.0、万亿元资产、元人与区块链文明构建了元宇宙第一大楼。第1-80层:数字人展位、电子宠物、数字藏品、3D沉侵式旅游、DeFi。第81-160层:AI、VR、AR、MR、DAO、Web3.0、边缘计算。第161-214+层:多场景阅读、4K空间、跨链许可、维度转换、无限∞世界。

当当自营购买链接:http://product.dangdang.com/29513251.html

         本书从产业链金融的起源讲起,结合实际案例讲解产业链金融平台的前台设计、技术中台设计、数据平台设计、风控设计及信息安全的核心要点,既体现了传统行业的业务创新、数字转型的探索过程,又介绍了当前主流银行的开放性建设成果。读者不但能全方位地了解产业链金融平台的建设过程,还能针对自己感兴趣的方面进行深入学习。

        本书共6章,第1章介绍了产业链金融的发展、变革历程,以及对传统企业的核心价值;第2章介绍了系统核心功能的设计及在线签约、实名认证等技术的原理;第3章介绍了结合容器云技术、微服务技术与DevOps技术构建技术中台的过程,以及对接开放银行、央行征信的过程;第4章介绍了开源大数据平台的建设及数据仓库的设计思路;第5章基于Python的机器学习库介绍了智能风控的开发过程;第6章介绍了在产业链金融平台建设过程中如何规避信息安全的法律风险。

        本书内容全面,且围绕开源技术展开介绍,实用性极强,特别适合建设产业链金融平台的传统企业架构师、开发人员及产品人员阅读,也适合对开源的技术中台、大数据平台及信用风控感兴趣的开发人员阅读。

京东自营购买链接:https://item.jd.com/13797946.html

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

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

相关文章

chatgpt赋能python:Python阶乘算法——快速、高效的算法实现!

Python阶乘算法 —— 快速、高效的算法实现&#xff01; Python作为一门高级编程语言&#xff0c;在众多领域都得到了广泛应用&#xff0c;尤其在算法领域更是拥有着举足轻重的地位。阶乘算法作为计算领域中的一种经典算法&#xff0c;也是Python中不可或缺的一部分。 什么是…

尚硅谷大数据hadoop教程_HDFS

P40 hdfs产生背景和定义 p41 优缺点 p42 组成 p43 文件块大小 p 44 45 shell命令 p46 api环境准备

单链表—C语言实现数据结构

本期带大家一起用C语言实现单链表&#x1f308;&#x1f308;&#x1f308; 文章目录 一、链表的概念&#x1f30e;二、链表中数据元素的构成&#x1f30e; &#x1f30d;三、链表的结构&#x1f30e; &#x1f30d; &#x1f30f;四、 单链表的实现✅✅二、接口的实现✅✅1.单…

SAP-MM-采购申请-价值特性

采购申请审批在维护价值特性时要注意是抬头价值还是行价值&#xff0c;要确定选择哪个&#xff0c;配置时对应配置。 1、创建价值特性CT04 字段名称&#xff1a;CEBAN-GSWRT&#xff0c;和CEBAN-GFWRT 抬头总价值&#xff1a;CEBAN-GFWRT&#xff1b;如果选择的是抬头审批&am…

WPF界面设计

目录 1.设计一个优美的注册界面1.实现效果2.代码展示 2.简易登录按钮设计1.实现效果2.代码展示 3.设计一个优美的注册登录界面&#xff08;连接数据库&#xff09;1.实现效果2.代码展示 4.设计一个简单的在线教育系统界面1.实现效果2.代码展示 5. 设计一个Dashboard1.实现效果2…

linux线程创建等待及退出总结

线程操作 线程操作分线程的创建&#xff0c;退出&#xff0c;等待 3 种 1. 线程创建 #include <pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg); // 返回&#xff1…

chatgpt赋能python:Python中的逆序数

Python中的逆序数 介绍逆序数 在数学中&#xff0c;逆序数指的是一个序列中逆序对的个数。逆序对指一个序列中的两个元素&#xff0c;其中较大的元素在前而较小的元素在后。例如&#xff0c;序列 [2, 4, 1, 3] 中逆序对的个数是 2&#xff1a;(2,1) 和 (4,1)。 逆序数常用于…

chatgpt赋能python:Python逆序遍历-解决问题的神奇方式

Python逆序遍历 - 解决问题的神奇方式 Python是一种简单易学的编程语言&#xff0c;依靠其强大的功能和可扩展性&#xff0c;已成为数据科学、人工智能和Web开发的首选语言之一。Python的核心优点之一是其非常方便的列表操作&#xff0c;而逆序遍历列表是Python的又一个实用而…

chatgpt赋能python:Python虚拟环境移植:为何以及如何

Python虚拟环境移植&#xff1a;为何以及如何 在Python项目开发过程中&#xff0c;管理项目依赖关系是一个很重要的问题。一个有效的解决方案是使用Python虚拟环境。虚拟环境是Python的一个工具&#xff0c;允许您在隔离的环境中管理Python包和依赖&#xff0c;从而避免不同开…

期末复习总结【MySQL】五种约束类型, 主键和外键的使用方式(重点)

文章目录 前言一、约束类型二、NOT NULL三、UNIQUE四、DEFAULT五、PRIMARY KEY(重点)1, 自增主键 六、FOREIGN KEY (重点)1, 插入数据2, 删除数据3, 关于外键约束下删除数据的思考 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5;…

chatgpt赋能python:Python词法分析:理解语言的起点

Python词法分析&#xff1a;理解语言的起点 在计算机科学中&#xff0c;词法分析&#xff08;也称为词法分析器&#xff09;是解析编程语言时的重要步骤之一。词法分析器将程序代码转换为由单词组成的序列&#xff08;称为标记或词法单元&#xff09;&#xff0c;为编译器和解…

chatgpt赋能python:Python转变为大写:学习如何使用Python中的str.upper()

Python 转变为大写&#xff1a;学习如何使用 Python 中的 str.upper() 作为一名有10年python编程经验的工程师&#xff0c;我可以肯定地说&#xff0c;Python 作为一门流行的编程语言&#xff0c;在全球范围内得到了广泛的应用。除了成为数据科学和机器学习的首选语言之外&…

设置ssh免密码登陆linux的配置步骤

概述 生成私钥文件 在客户端终端下输入以下命令 ssh-keygen -t rsa每次执行 ssh-keygen -t rsa 产生的私钥文件都会不同 如果文件"~/.ssh/id_rsa"存在&#xff0c;会提示是否覆盖该文件&#xff0c;此时可选择"n"不覆盖该文件而使用已有的id_rsa文件 如…

钉钉群通过短信转发器接收手机短信消息

1.短信转发器官网下载 下载地址 首发地址&#xff1a;https://github.com/pppscn/SmsForwarder/releases国内镜像&#xff1a;https://gitee.com/pp/SmsForwarder/releases网盘下载&#xff1a;https://wws.lanzoui.com/b025yl86h 访问密码&#xff1a;pppscn 使用文档 首发…

计算机网络 - 网络层的控制平面

Introduction 控制平面设计很多路由的算法, 然后计算出路由表给数据平面转发跟路由的, 传统方式的控制平面是每一个路由器都有一个控制平面, SDN方式的话通常是集中的remote管理, 一个控制平面控制多个本地代理CA - (Control Agent) 路由选择算法 路由route的概念 按照某种…

chatgpt赋能python:Python词性分析:一步步了解自然语言处理技术

Python词性分析&#xff1a;一步步了解自然语言处理技术 Python是一种高级编程语言&#xff0c;拥有广泛的应用领域。自然语言处理技术是其中一个重要的领域&#xff0c;它包含了词性分析、命名实体识别、句法分析等多项任务。词性分析是自然语言处理中的基本任务之一&#xf…

chatgpt赋能python:Python请求头——让你的网络请求更有效率

Python请求头——让你的网络请求更有效率 网络请求是现代应用程序的核心。但是&#xff0c;如果你不了解Python请求头的概念和用途&#xff0c;那么你可能会面临一些棘手的问题。在本文中&#xff0c;我们将深入探讨Python请求头&#xff0c;了解其作用、语法和最佳实践。 什…

计算机毕业论文选题推荐|软件工程|系列十一

文章目录 导文题目导文 计算机毕业论文选题推荐|软件工程 (***语言)==使用其他任何编程语言 例如:基于(***语言)门窗账务管理系统的设计与实现 得到:基于JAVA门窗账务管理系统的设计与实现 基于vue门窗账务管理系统的设计与实现 等等 题目 基于(***语言)系统的校园社交…

如何在华为OD机试中获得满分?Java实现【字符串重新排序】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1、题目描述2、输入描述3、输出描述…

如何在华为OD机试中获得满分?Java实现【静态代码扫描服务】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…