Redis专题-基础篇

news2025/6/8 18:19:52

题记

本文涵盖了Redis的各种数据结构和命令,Redis的各种常见Java客户端的应用和最佳实践

jedis案例github地址:https://github.com/whltaoin/fedis_java_demo

SpringbootDataRedis案例github地址:https://github.com/whltaoin/springbootDataRedis_demo

一、初始Redis

SQL与NoSQL对比

  1. 结构化(Structured)对比
    1. SQL具有严格的结构化格式(左图)
    2. NoSQL的数据存储格式相对随意(右图)

  1. 关系对比
    1. SQL在表和表间**可能存在联系**,在操作一张表时,需要考虑对应关联表的完整性。

2. NoSQL数据间是**<font style="color:#DF2A3F;">无关联</font>**的,(下图为存储方式)

  1. 查询对比
    1. SQL查询有**固定的语法**,只要是SQL都可以使用相同的语句查询。

2. NoSQL没有固定的语法,每个NoSQL都有自己的语法糖(下图为查询同一个东西,出现了不同的语法)

  1. SQL需要满足**事务的ACID特性**(原子性、一致性、隔离性、持久性)
  2. NoSQL只是**基本满足事务的ACID**
  3. 差异总结:

初始Redis

  1. 简介

Redis(远程词典服务器),是一个基于内存的**键值型NoSQL**数据库

  1. 特征:
    1. 键值型:key-value
    2. 单线程:命令具有原子性
    3. 低延迟、数据块原因:(基于**内存**、IO多路复用、良好的编码)
    4. 支持数据持久化
    5. 支持主从集群(主服务器和副服务器)、分片集群(将数据拆分,分别存在不同的服务器上)
    6. 支持多语言客户端(java、C…)

安装Redis(Linux安装)

忽略…

二、Redis常见命令

数据类型介绍

  1. String
    1.
  2. Hash
    1. 哈希表
  3. List
    1. 有序集合,本质是链表
  4. Set
    1. 无序集合,不可重复
  5. SortedSet
    1. 有序集合,不可重复
  6. GEO
    1. 地理坐标

通用命令

  1. 查询所有通用命令:
help @generic

  1. 查看符合模版的所有key
    1. 注意:不建议在生产环境设备上使用该命令,因为模糊查询,效率不高且浪费资源

# 语法
keys +[pattern]

  1. 删除key
    1. 可以单个删除,也可以多个一起删除
del [key]

删除一个或多个示例

  1. 判断key是否存在
    1. 可以判断单个,也可以判断多个
exists [key]

判断单个和多个示例

  1. 给key设置有效期,到期后自动删除(单位秒)
    1. TTL查看可以的有效时间
expire [key] [seconds]
ttl key

示例:设置age1的有效期为10s,到期后自动删除

  1. 总结

String类型

  1. set

  1. get

  1. mset

  1. mget

  1. incr

  1. incrby

  1. incrbyfloat

  1. setnx(新增,存在则不创建)
    1. 等价于:set [key value] nx

  1. setex
    1. 等价于:set

Key的层级格式

  1. 思考:

  1. 解决方法

  1. 示例

heima:user:1
herma:product:1

层级结构:

Hash类型

  1. Hash类型(散列),其中的value是一个**无序字典**
    1. 类似于java 中的HashMap结构
  2. 使用场景:
    1. 当要修改JSON数据中某个属性的值时,使用String存储的需要重新覆盖数据,而我们的需求只是**想要修改某个值**
  3. 常用命令

  1. 示例
    1. hset

2. hget

3. hmset

4. hmget

5. hgetall

6. hkeys

7. hvals 

8. hincrby

9. hsetnx(已存在,不新建)

List类型

  1. Redis中的List类型于java中的LinkedList类似,可以当它是一个双向链表结构。
    1. 既可以支持正向检索也可以支持反向检索。
  2. 特征:
    1. 有序
    2. 元素可重复
    3. 插入和删除快
    4. 查询速度一般
  3. 使用场景举例:
    1. 朋友圈点赞列表,评论列表等
  4. 常用命令:

1. 示例:

Set类型

  1. Redis的Set结构和Java中的HashSet类似,可以看做一个value为null的HashMap。
  2. 特征:
    1. 无序
    2. 元素不可重复
    3. 查找快
    4. 支持交集、并集、差集等功能
  3. 单个set常见命令

1. 示例

  1. 多个set操作命令
    1. 求交集(sinter):两集合公共的

2. 求并集(sunion):所有元素合并

3. 求差集(sdiff):set中有,但是set2中没有

  1. 练习题:

1. 张三的好友人数

2. 张三和李四的共同好友

3. 查询那些人是张三的好友但是不是李四的好友

4. 查询张三和李四的共同好友

5. 判断李四是否是张三的好友

6. 判断张三是否是李四的好友

7. 将李四从张三的好友列表中移除

SortedSet类型

  1. 特性:
    1. 可排序
    2. 元素不可重复
    3. 查询快
  2. 应用场景:
    1. 因为可排序,常用于实现**排行榜**功能
  3. 常用命令

  1. 练习题:

1. 添加数据

2. 删除Tom

3. 获取Amy分数

4. 获取Rose排名

5. 查询80分以上人数

6. 给Amy加2分

7. 查询排名前三的同学

8. 查询80以下的同学

三、Redis的Java客户端

常用Java客户端的优缺点对比

Jedis使用(单线程)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用Jedis分为了四步骤:
    1. 导入依赖
    2. 初始化Jedis对象
    3. 执行Jedis中的操作方法
    4. 释放Jedis对象
  2. 具体实现
    1. 导入依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jedis-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
  <dependencies>
<!--    核心-->
      <dependency>
          <groupId>redis.clients</groupId>
          <artifactId>jedis</artifactId>
          <version>6.0.0</version>
      </dependency>
<!--      测试类-->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.2</version>
          <scope>test</scope>
      </dependency>
  </dependencies>


</project>
b. 测试类方法内容
package cn.varin;


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 init(){
        jedis = new Jedis("ip",6379);
        jedis.auth("密码");
        jedis.select(0);
    }
    @Test
    public void StringTest(){
        String set = jedis.set("name", "varin");
        System.out.println("执行set后结果为:"+set);
        String name = jedis.get("name");
        System.out.println("key为name的value为:"+name);

    }

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

}

3. 执行结果

Jedis使用(使用连接池)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用步骤:
    1. 创建连接池
    2. 获取Jedis对象
    3. 操作Jedis对象
    4. 归还连接池对象
  2. 具体代码
    1. 创建连接池对象
package cn.varin.jedis.utils;

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

// Jedis连接池对象
public class JedisConnectionFactory {
    //
    static  public final JedisPool jedisPool;
    static {
        // 创建配置
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接数
        jedisPoolConfig.setMaxTotal(10);
        // 最大空闲数
        jedisPoolConfig.setMaxIdle(10);
        // 最小空闲数
        jedisPoolConfig.setMinIdle(2);
        // 空闲等待时间
        jedisPoolConfig.setMaxWaitMillis(1000);

        jedisPool = new JedisPool(jedisPoolConfig,"host",6379,100,"password");
    }
    public static Jedis getResource(){
       return jedisPool.getResource();
    }
}

2. 测试类代码
package cn.varin;


import cn.varin.jedis.utils.JedisConnectionFactory;
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 init(){
        jedis = JedisConnectionFactory.getResource();
        jedis.select(0);
    }
    @Test
    public void StringTest(){
        String set = jedis.set("name", "varya");
        System.out.println("执行set后结果为:"+set);
        String name = jedis.get("name");
        System.out.println("key为name的value为:"+name);

    }

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

}

3. 执行结果:

SpringDataRedis使用

github示例案例地址:https://github.com/whltaoin/springbootDataRedis_demo

springData介绍
  1. 项目地址:https://spring.io/projects/spring-data-redis#learn

  1. Redis模版版本信息

SpringDataRedis快速入门

SpringbootDataRedis使用步骤

基本示例
  1. 导入依赖
<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.varin</groupId>
	<artifactId>springbootDataRedis_demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springbootDataRedis_demo</name>
	<description>springbootDataRedis_demo</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
<!--		springbootDataRedis-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
<!--		pool2-->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

  1. 配置yml
spring:
  data:
    redis:
      port: 6379
      password: password
      database: 0
      lettuce:
        pool:
          max-active: 10
          max-idle: 10
          min-idle: 0
          max-wait: 100ms
      host: address

  1. 编写测试类
package cn.varin.springbootdataredis_demo;

import cn.varin.springbootdataredis_demo.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;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {

	@Autowired
	RedisTemplate redisTemplate;
	@Test
	void setTest() {

		ValueOperations valueOperations = redisTemplate.opsForValue();
		valueOperations.set("user:1",new User("varin",1).toString());
		Object o = valueOperations.get("user:1");
		System.out.println(o);


	}

}

  1. 结果:

重构redisTemplate序列化和反序列化工具
  1. 问题

1. 在我们直接使用redisTemplate时,存入到redis的内容,是经过编译的字节,
2. 影响阅读性
3. 增加了存储空间
  1. 解决方案:
    1. 自定义序列化和反序列话的编码格式
  2. 步骤
    1. 建立template
    2. 设置连接工厂
    3. 设置序列化工具
    4. 分别对key和value设置不同的格式
package cn.varin.springbootdataredis_demo.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.RedisSerializer;

@Configuration
public class RedisTamplateConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(factory);
        // 创建序列化工具

        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 对key
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());

        // 对value
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);

        return  template;

    }
}

测试类

package cn.varin.springbootdataredis_demo;

import cn.varin.springbootdataredis_demo.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;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {

	@Autowired
	RedisTemplate redisTemplate;
	@Test
	void setTest() {

		ValueOperations valueOperations = redisTemplate.opsForValue();
        // value为user对象
		valueOperations.set("user:2",new User("varin",1));
		Object o = valueOperations.get("user:1");
		System.out.println(o);


	}

}

  1. 测试结果

StringRedisTamplate类使用
  1. 问题:
    1. 虽然自定义序列化工具可以解决上一问题,但是修改后在JSON字符串中会多存储一个类的包名
      1. 导致增大存储的空间
  2. 解决方法,
    1. 使用StringRedisTamplate类,在加上自己使用第三方的序列化工具进行存储。
      1. 优点:在存储时不会增加额外的数据
      2. 缺点:增加少许的代码量
  3. 示例代码
@Autowired
	StringRedisTemplate stringRedisTemplate;
	// 用于转Json格式
	private static  final ObjectMapper mapper = new ObjectMapper();
	@Test
	void StringRedisTamplateTest() throws JsonProcessingException {
		User user = new User("varya",1);
		// 转JSON格式
		String s = mapper.writeValueAsString(user);
		// 写入数据
		stringRedisTemplate.opsForValue().set("user:3",s);

		// 读取数据
		String s1 = stringRedisTemplate.opsForValue().get("user:3");
		// 反序列化
		User user1 = mapper.readValue(s1, User.class);
		System.out.println(user1);


	}

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

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

相关文章

springMVC-11 中文乱码处理

前言 本文介绍了springMVC中文乱码的解决方案&#xff0c;同时也贴出了本人遇到过的其他乱码情况&#xff0c;可以根据自身情况选择合适的解决方案。 其他-jdbc、前端、后端、jsp乱码的解决 Tomcat导致的乱码解决 自定义中文乱码过滤器 老方法&#xff0c;通过javaW…

【iOS安全】iPhone X iOS 16.7.11 (20H360) WinRa1n 越狱教程

前言 越狱iPhone之后&#xff0c;一定记得安装一下用于屏蔽更新的描述文件&#xff08;可使用爱思助手&#xff09; 因为即便关闭了自动更新&#xff0c;iPhone仍会在某些时候自动更新系统&#xff0c;导致越狱失效&#xff1b;更为严重的是&#xff0c;更新后的iOS版本可能是…

智能标志桩图像监测装置如何守护地下电缆安全

在现代城市基础设施建设中&#xff0c;大量电缆、管道被埋设于地下&#xff0c;这虽然美化了城市景观&#xff0c;却也带来了新的安全隐患。施工挖掘时的意外破坏、自然灾害的影响&#xff0c;都可能威胁这些"城市血管"的安全运行。 传统的地下设施标识方式往往只依…

【网站建设】网站 SEO 中 meta 信息修改全攻略 ✅

在做 SEO 优化时,除了前一篇提过的Title之外,meta 信息(通常指 <meta> 标签)也是最基础、最重要的内容之一,主要包括: <meta name="description"> <meta name="keywords"> 搜索引擎重点参考这些信息,决定你网页的展示效果与排名。…

计算机视觉处理----OpenCV(从摄像头采集视频、视频处理与视频录制)

一、采集视频 VideoCapture 用于从视频文件、摄像头或其他视频流设备中读取视频帧。它可以捕捉来自 多种源的视频。 cv2.VideoCapture() 打开摄像头或视频文件。 cap cv2.VideoCapture(0) # 0表示默认摄像头&#xff0c;1是第二个摄像头&#xff0c;传递视频文件路径也可以 …

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- 第一篇:MIPI CSI-2基础入门

第一篇&#xff1a;MIPI CSI-2基础入门 1. 为什么需要CSI-2&#xff1f; 痛点场景对比 &#xff08;用生活案例降低理解门槛&#xff09; 传统并行接口CSI-2接口30根线传输720P图像仅需5根线&#xff08;1对CLK4对DATA&#xff09;线距&#xff1e;5cm时出现重影线缆可长达1…

变幻莫测:CoreData 中 Transformable 类型面面俱到(一)

概述 各位似秃似不秃小码农们都知道&#xff0c;在苹果众多开发平台中 CoreData 无疑是那个最简洁、拥有“官方认证”且最具兼容性的数据库框架。使用它可以让我们非常方便的搭建出 App 所需要的持久存储体系。 不过&#xff0c;大家是否知道在 CoreData 中还存在一个 Transfo…

开源技术驱动下的上市公司财务主数据管理实践

开源技术驱动下的上市公司财务主数据管理实践 —— 以人造板制造业为例 引言&#xff1a;财务主数据的战略价值与行业挑战 在资本市场监管日益严格与企业数字化转型的双重驱动下&#xff0c;财务主数据已成为上市公司财务治理的核心基础设施。对于人造板制造业而言&#xff0…

Java建造者模式(Builder Pattern)详解与实践

一、引言 在软件开发中&#xff0c;我们经常会遇到需要创建复杂对象的场景。例如&#xff0c;构建一个包含多个可选参数的对象时&#xff0c;传统的构造函数或Setter方法可能导致代码臃肿、难以维护。此时&#xff0c;建造者模式&#xff08;Builder Pattern&#xff09;便成为…

win32相关(IAT HOOK)

IAT HOOK 什么是IAT Hook&#xff1f; IAT Hook&#xff08;Import Address Table Hook&#xff0c;导入地址表钩子&#xff09;是一种Windows平台下的API钩取技术&#xff0c;通过修改目标程序的导入地址表(IAT)来拦截和重定向API调用 在我们之前学习pe文件结构的导入表时&am…

零基础玩转物联网-串口转以太网模块如何快速实现与TCP服务器通信

目录 1 前言 2 环境搭建 2.1 硬件准备 2.2 软件准备 2.3 驱动检查 3 TCP服务器通信配置与交互 3.1 硬件连接 3.2 开启TCP服务器 3.3 打开配置工具读取基本信息 3.4 填写连接参数进行连接 3.5 通信测试 4 总结 1 前言 TCP是TCP/IP体系中的传输层协议&#xff0c;全称为Transmiss…

ESP32开发之LED闪烁和呼吸的实现

硬件电路介绍GPIO输出模式GPIO配置过程闪烁灯的源码LED PWM的控制器(LEDC)概述LEDC配置过程及现象整体流程 硬件电路介绍 电路图如下&#xff1a; 只要有硬件基础的应该都知道上图中&#xff0c;当GPIO4的输出电平为高时&#xff0c;LED灯亮&#xff0c;反之则熄灭。如果每间…

【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录

【产品业务设计】支付业务设计规范细节记录&#xff0c;含订单记录、支付业务记录、支付流水记录 前言 我为什么要写这个篇文章 总结设计经验生成设计模板方便后期快速搭建 一个几张表 一共5张表&#xff1b; 分别是&#xff1a; 订单主表&#xff1a;jjy_orderMain订单产…

2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践

项目背景&#xff1a;近年来&#xff0c;云计算、AI人工智能、大数据等信息技术的不断发展、各行各业的信息电子化的步伐不断加快、信息化的水平不断提高&#xff0c;网络安全的风险不断累积&#xff0c;金融证券行业面临着越来越多的威胁挑战。特别是近年以来&#xff0c;开源…

WebRTC通话原理与入门难度实战指南

波煮的实习公司主要是音视频业务&#xff0c;所以最近在补习WebRTC的相关内容&#xff0c;会不定期给大家分享学习心得和笔记。 文章目录 WebRTC通话原理进行媒体协商&#xff1a;彼此要了解对方支持的媒体格式网络协商&#xff1a;彼此要了解对方的网络情况&#xff0c;这样才…

N元语言模型 —— 一文讲懂!!!

目录 引言 一. 基本知识 二.参数估计 三.数据平滑 一.加1法 二.减值法/折扣法 ​编辑 1.Good-Turing 估计 ​编辑 2.Back-off (后备/后退)方法 3.绝对减值法 ​编辑4.线性减值法 5.比较 三.删除插值法(Deleted interpolation) 四.模型自适应 引言 本章节讲的…

.NET 9中的异常处理性能提升分析:为什么过去慢,未来快

一、为什么要关注.NET异常处理的性能 随着现代云原生、高并发、分布式场景的大量普及&#xff0c;异常处理&#xff08;Exception Handling&#xff09;早已不再只是一个冷僻的代码路径。在高复杂度的微服务、网络服务、异步编程环境下&#xff0c;服务依赖的外部资源往往不可…

Mac 安装git心路历程(心累版)

省流版&#xff1a;直接安装Xcode命令行工具即可&#xff0c;不用安Xcode。 git下载官网 第一部分 上网初步了解后&#xff0c;打算直接安装Binary installer&#xff0c;下载完安装时&#xff0c;苹果还阻止安装&#xff0c;只好在“设置–安全性与隐私”最下面的提示进行安…

计算机网络第2章(下):物理层传输介质与核心设备全面解析

目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线&#xff08;Twisted Pair&#xff09;1.2.2 同轴电缆&#xff08;Coaxial Cable&#xff09;1.2.3 光纤&#xff08;Optical Fiber&#xff09;1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…

C# 类和继承(扩展方法)

扩展方法 在迄今为止的内容中&#xff0c;你看到的每个方法都和声明它的类关联。扩展方法特性扩展了这个边 界&#xff0c;允许编写的方法和声明它的类之外的类关联。 想知道如何使用这个特性&#xff0c;请看下面的代码。它包含类MyData&#xff0c;该类存储3个double类型 的…