当前位置: 首页 > news >正文

重学SpringBoot3-集成Redis(二)之注解驱动

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-集成Redis(二)之注解驱动

  • 1. 为什么选择 Redis 作为缓存?
  • 2. 如何在 Spring Boot 中启用 Redis 缓存?
    • 2.1 添加 Redis 依赖
    • 2.2 配置 Redis 连接
    • 2.3 启用缓存支持
  • 3. 注解驱动的缓存机制
    • 3.1 @Cacheable示例
    • 3.2 @CachePut示例
    • 3.3 @CacheEvict示例
  • 4. 自定义缓存管理
    • 4.1 RedisCacheConfiguration 类
      • 4.1.1. 过期时间(TTL - Time To Live)
      • 4.1.2. 键序列化方式
      • 4.1.3. 值序列化方式
      • 4.1.4. 禁用缓存空值(Disable Caching Null Values)
      • 4.1.5. 使用前缀(Use Cache Key Prefixes)
      • 4.1.6. 设置空闲时间(Idle Time)
      • 4.1.7. 组合多种配置
      • 4.1.8. 设置自定义的过期策略
    • 4.2 自定义缓存配置
  • 5. Redis 缓存的常见问题和优化建议
  • 6. 总结

Spring Boot 提供了对缓存的简便支持,使得开发者能够通过简单的注解实现缓存操作,减少重复代码的编写。本文将详细介绍如何在 Spring Boot 3 中使用 Redis 作为缓存,并通过注解驱动的方式进行缓存操作。

1. 为什么选择 Redis 作为缓存?

Redis 是一个高效的键值对存储系统,特别适合于构建高性能、可扩展的缓存层。其优点包括:

  • 高吞吐量:Redis 使用内存作为存储介质,读取和写入性能极快,能够支撑高并发的访问需求。
  • 数据持久化:尽管 Redis 是内存数据库,它也支持将数据持久化到磁盘,防止数据丢失。
  • 丰富的数据结构:Redis 不仅支持简单的字符串存储,还支持哈希、列表、集合等丰富的数据结构,适用于多种应用场景。
  • 易于扩展:通过 Redis 的集群功能,可以很容易地扩展 Redis 实例,处理更大规模的数据和请求。

2. 如何在 Spring Boot 中启用 Redis 缓存?

Spring Boot 提供了对缓存的开箱即用支持,开发者只需简单配置即可使用。具体参考上一章 重学SpringBoot3-集成Redis(一)。

2.1 添加 Redis 依赖

pom.xml 中引入 Redis 和 Spring Cache 相关依赖:

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

2.2 配置 Redis 连接

application.yml 中,配置 Redis 服务器地址及相关连接池配置:

spring:cache:type: redis     	 	# 使用 Redis 作为缓存类型data:redis:host: localhostport: 6379            # Redis 端口password: 			# 如果有密码可以在这里配置lettuce:pool:max-active: 100    # 最大并发连接数max-idle: 50       # 最大空闲连接数min-idle: 10       # 最小空闲连接数

2.3 启用缓存支持

在 Spring Boot 项目中,使用 @Cacheable 注解前,需要通过 @EnableCaching 注解启用缓存功能。可以在主应用类或者任何配置类中加上这个注解:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@EnableCaching
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

3. 注解驱动的缓存机制

Spring 提供了一组注解用于操作缓存,这些注解可以直接应用于方法上,使得代码更简洁。常用注解包括:

  • @Cacheable:用于标记一个方法的返回值是可缓存的。下一次调用该方法时,Spring 会直接从缓存中返回结果,而不是再次执行方法。
  • @CachePut:在方法执行后将返回值放入缓存。它与 @Cacheable 的区别在于,@CachePut 不会跳过方法执行,而是始终执行方法并更新缓存。
  • @CacheEvict:用于清除缓存中的某些条目,可以指定缓存的 key 或清空整个缓存空间。

3.1 @Cacheable示例

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;@Service
public class UserService {// 当方法第一次调用时,结果将被缓存起来,之后相同参数的调用将直接从缓存中获取数据@Cacheable(value = "user", key = "#p0")public User getUserById(Long id) {// 模拟数据库查询操作System.out.println("Fetching user with id: " + id);return new User(id, "User" + id);}
}

解释:

  • @Cacheable 用于缓存方法的返回值。
  • value = "user" 指定了缓存的名称,即 “user”。
  • key = "#p0" 指定了缓存的键值。这里的 #p0 是一个 SpEL 表达式,表示方法的第一个参数。

在这个例子中,方法 getUserById 第一次被调用时,结果会缓存到 Redis 中,并与 user::id 作为 key 存储。后续相同 id 的请求将直接从缓存返回,而无需执行方法。

@Cacheable添加缓存

3.2 @CachePut示例

有时候,我们希望方法执行后,不仅返回结果,还更新缓存,这时可以使用 @CachePut 注解。

import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;@Service
public class UserService {// 无论缓存中是否存在数据,该方法都会被执行,并且返回值会更新缓存@CachePut(value = "user", key = "#p0.id")public User updateUser(User user) {System.out.println("Updating user with id: " + user.getId());// 模拟数据库更新操作user.setName("Updated " + user.getName());return user;}
}

解释:

  • @CachePut 用于更新缓存中的值。
  • value = "user" 指定了缓存的名称,即 “user”。
  • key = "#p0.id" 指定了缓存的键值。这里的 #p0 是一个 SpEL 表达式,表示方法的第一个参数,即 User 对象。.id 表示取 User 对象的 id 属性作为缓存键。

连续两次调用 curl "http://localhost:8080/api/redis/updAndSave?id=2" ,可以从日志中看到,每次方法都执行了,并且 user 对象加入到了缓存中。

@CachePut更新缓存

3.3 @CacheEvict示例

为了保持缓存数据的准确性,某些情况下需要手动清除缓存中的数据。@CacheEvict 注解允许我们在数据修改或删除时,移除缓存中的旧数据。

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;@Service
public class UserService {// 清除缓存中的指定用户数据@CacheEvict(value = "user", key = "#p0")public void deleteUser(Long id) {System.out.println("Deleting user with id: " + id);// 模拟数据库删除操作}// 清空整个缓存空间@CacheEvict(value = "user", allEntries = true)public void clearCache() {System.out.println("Clearing all user cache");}
}

调用 curl "http://localhost:8080/api/redis/delUser?id=1" ,删除 key 为 user::1 的缓存。

@CacheEvict删除缓存

调用 curl "http://localhost:8080/api/redis/delAllUser" ,删除所有前缀为 user:: 的缓存。

@CacheEvict删除所有缓存

4. 自定义缓存管理

以上缓存名称、过期时间和序列化方式都是默认设置,Spring 允许我们自定义缓存管理器。在大多数情况下,默认配置足够使用,但如果需要定制化的缓存行为,我们可以自定义缓存配置。通过实现 RedisCacheConfiguration,我们可以设置缓存的过期时间、序列化方式等。

4.1 RedisCacheConfiguration 类

Spring Boot 3 中,RedisCacheConfiguration 类是用于配置 Redis 缓存行为的核心组件之一。它提供了多种方法,用于自定义 Redis 缓存的各类设置,比如缓存过期时间、序列化策略等。以下是一些常用的配置选项:

4.1.1. 过期时间(TTL - Time To Live)

设置缓存条目的默认生存时间(TTL)。这决定了缓存数据在 Redis 中保留的时间。

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)); // 设置缓存10分钟后过期

4.1.2. 键序列化方式

默认情况下,Redis 使用二进制存储键和值。RedisCacheConfiguration 提供了设置键(key)序列化方式的方法。常见的序列化方式包括 StringRedisSerializer,可以使用它来确保键以字符串格式存储:

import org.springframework.data.redis.serializer.StringRedisSerializer;RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));

4.1.3. 值序列化方式

同样,值(value)的序列化方式也可以自定义。常用的序列化方式有 GenericJackson2JsonRedisSerializer,它将对象序列化为 JSON 格式:

import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

4.1.4. 禁用缓存空值(Disable Caching Null Values)

你可以配置不缓存空值,避免 Redis 存储 null,减少缓存的无效占用。

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues();

4.1.5. 使用前缀(Use Cache Key Prefixes)

Redis 中默认会为缓存键值加上一个命名空间的前缀,以防止不同缓存键冲突。可以自定义这个前缀,也可以关闭它:

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().prefixCacheNameWith("myApp::")  // 自定义缓存键前缀.computePrefixWith(cacheName -> "customPrefix::" + cacheName + "::");  // 使用自定义逻辑

要禁用前缀:

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().disableKeyPrefix();

4.1.6. 设置空闲时间(Idle Time)

你可以设置一个键的空闲时间,Redis 将会在指定的时间内删除不再被访问的键。

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)).enableTimeToIdle();

4.1.7. 组合多种配置

可以将多个配置组合到一起:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration
public class CacheConfig {@Beanpublic RedisCacheConfiguration redisCacheConfiguration() {return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10))  // 缓存的过期时间.disableCachingNullValues()        // 不缓存 null 值.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))  // 自定义 key 序列化.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); // 自定义 value 序列化}
}

4.1.8. 设置自定义的过期策略

可以为不同的缓存区域设置不同的过期策略。例如:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;@Configuration
public class CacheConfig {@Beanpublic RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5));RedisCacheConfiguration longLivedConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();cacheConfigurations.put("shortLivedCache", defaultConfig);cacheConfigurations.put("longLivedCache", longLivedConfig);return RedisCacheManager.builder(connectionFactory).withInitialCacheConfigurations(cacheConfigurations).build();}
}

4.2 自定义缓存配置

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.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration
public class CacheConfig {@Beanpublic RedisCacheConfiguration cacheConfiguration() {return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10))  // 设置缓存过期时间为 10 分钟.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // 自定义 Key 序列化器.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); // 自定义 Value 序列化器}
}

通过这种方式,我们可以对缓存的过期时间、序列化方式进行更细粒度的控制。

自定义配置

5. Redis 缓存的常见问题和优化建议

尽管 Redis 是一个高效的缓存解决方案,但在实际应用中,仍然有一些需要注意的问题:

  • 缓存穿透:大量请求查询缓存中不存在的 key,导致所有请求都直接打到数据库上,降低系统性能。解决方案是使用布隆过滤器来拦截非法请求。
  • 缓存雪崩:当大量缓存同时过期时,可能会导致瞬间的大量请求直接涌入数据库,造成系统崩溃。可以通过设置不同的过期时间(TTL)来缓解这一问题。
  • 缓存击穿:某个热点 key 在缓存过期后,大量并发请求直接打到数据库上。解决方案是使用互斥锁,避免大量请求同时加载缓存。

6. 总结

通过本文,我们学习了如何在 Spring Boot 3Java 17 中使用 Redis 作为缓存。Spring 提供了注解驱动的缓存操作方式,使得缓存操作变得非常简单易用。通过合理配置和使用缓存,我们能够极大地提升系统的性能和响应速度。在生产环境中,合理的缓存策略、过期时间和缓存层优化将会进一步提高系统的稳定性和扩展能力。

相关文章:

重学SpringBoot3-集成Redis(二)之注解驱动

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;二&#xff09;之注解驱动 1. 为什么选择 Redis 作为缓存&#xff1f;2. 如何在 Spring Boot 中启用 Redis 缓存&#xff1f;2.1 …...

【React】入门Day04 —— 项目搭建及登录与表单校验、token 管理、路由鉴权实现

项目搭建 创建项目 # 使用npx创建项目 npx create-react-app my-react-app # 进入项目目录 cd my-react-app # 创建项目目录结构 mkdir -p src/{apis,assets,components,pages,store,utils} touch src/{App.js,index.css,index.js} 使用npx create-react-app创建项目&#xff0…...

CMake 属性之目录属性

【写在前面】 CMake 的目录属性是指在特定目录&#xff08;及其子目录&#xff09;范围内有效的设置。 这些属性不同于全局变量或目标&#xff08;Target&#xff09;属性&#xff0c;它们提供了一种机制&#xff0c;允许开发者为项目中的不同部分定义不同的构建行为。 通过目录…...

ChatGPT:引领人工智能新潮流!

一、ChatGPT 是什么&#xff1f; 1. ChatGPT 的强大功能和广泛应用。 ChatGPT 作为一款先进的 AI 语言模型&#xff0c;拥有众多强大功能。它可以进行文本生成、文本分类、情感分析、机器翻译等多种自然语言处理任务。同时&#xff0c;ChatGPT 还能进行对话式交互&#xff0c;…...

【银河麒麟高级服务器操作系统】安全配置基线相关分析全过程及解决方案

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 服务器环境以及配置 【机型】物理机或虚机 【…...

用Python实现图片转ASCII艺术:图像处理与字符艺术的完美结合

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 ASCII艺术是一种通过字符来表现图像的艺术形式,最早用于早期计算机显示器,它仅支持字符显示。如今,尽管图像分辨率和显示技术得到了极大的提升,ASCII艺术作为一种复古而别具一格的图像表现形式,仍然受到许多…...

大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

Redis-缓存过期淘汰策略

缓存淘汰策略 生产上redis内存设置为多少 设置为最大内存的 3/4 redis 会占用物理机多少内存 默认大小是 0&#xff0c;64 位系统下表示不限制内存大小&#xff0c;32位系统表示 3G 如何设置修改redis内存大小 config get maxmemory 查看修改方式 配置文件 单位是字节 2.…...

如何设置LED电子显示屏的屏幕参数?

LED电子显示屏因其高亮度、低能耗和长寿命等优点&#xff0c;在广告、信息显示等领域得到了广泛应用。正确设置屏幕参数对于确保显示屏的最佳性能至关重要。以下是LED电子显示屏设置屏幕参数的步骤&#xff1a; 1. 确定屏幕参数 在开始设置之前&#xff0c;需要了解显示屏的基本…...

Spring Boot Starter Parent介绍

引言 spring-boot-starter-parent 是一个特殊的项目&#xff0c;为基于 Spring Boot 的应用程序提供默认配置和默认依赖。 在本 Spring Boot 教程中&#xff0c;我们将深入了解所有 Spring Boot 项目内部使用的 spring-boot-starter-parent 依赖项。我们将探讨此依赖项所提供…...

【含开题报告+文档+PPT+源码】基于SpringBoot乡村助农益农平台的设计与实现

开题报告 近年来&#xff0c;随着社会经济的快速发展和人民生活水平的提高&#xff0c;人们对优质农产品的需求越来越高。然而&#xff0c;传统的农产品销售管理模式存在一些问题。首先&#xff0c;农产品供应链信息不透明&#xff0c;导致生产者难以了解市场需求和价格变动趋…...

数据中心运维挑战:性能监控的困境与智能化解决方案的探寻

随着数字化进程的加速&#xff0c;数据中心已成为企业信息架构的核心支撑&#xff0c;其运维管理的复杂度和重要性也随之提升。运维团队需应对设备老化、资源分配失衡、性能波动等多重难题&#xff0c;以确保数据中心持续高效运行。 其中&#xff0c;性能监控作为运维管理的关键…...

基于SSM的民宿管理系统【附源码】

基于SSM的民宿管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概要设计 4.2 系统功能结构设计 4.3 数据库设计 4.3.1 数据库E-R图设计 4.3.2 数据库表结构设计 5 系统实现 5.1用户信息管理 5.2 房东信息管理…...

显卡 3090 vs v100

1.3090 Date: 2020 AmperePielines/ Cuda cores: 10496 2.V100 Date: 2018 VoltaPielines/ Cuda cores: 5129 3.结构 & Core比较: v100优点: v100功耗小v100较快的双精度(fp64)和混合精度(fp16fp32)pcie版的NVLink与2080ti完全一致 v100缺点: 不支持整数格式计算&…...

怎么在单片机裸机程序中移植EasyLogger?

1、介绍 EasyLogger 是一款超轻量级、高性能的C日志库&#xff0c;非常适合对资源敏感的软件项目。例如&#xff1a;IoT产品、可穿戴设备、智能家居等等。相比log4c、zlog这些知名的C日志库&#xff0c;EasyLogger的功能更加简单&#xff0c;提供给用户的接口更少&#xff0c;但…...

C/C++解析文件名和目录路径

文章目录 主要函数使用注意事项示例程序总结 #include <libgen.h> 是一个 C/C 语言的头文件&#xff0c;主要用于字符串处理&#xff0c;特别是在处理文件路径时。它提供了一些函数来帮助你解析文件名和目录路径。 主要函数 以下是 libgen.h 中一些常见的函数&#xff…...

Git 基本命令行操作

Git是一个开源的分布式版本控制系统&#xff0c;用于管理源代码和文档的版本。以下是Git的基本命令行操作&#xff1a; 一、配置 安装完成后&#xff0c;需要配置Git的用户名和邮箱&#xff0c;以便在提交记录时记录操作者的信息。 配置全局用户名&#xff1a;git config --g…...

【Rust练习】17.泛型

练习题来自&#xff1a;https://practice-zh.course.rs/generics-traits/generics.html 函数 1 // 填空 struct A; // 具体的类型 A. struct S(A); // 具体的类型 S. struct SGen<T>(T); // 泛型 SGen.fn reg_fn(_s: S) {}fn gen_spec_t(_s: SGen<A&…...

java脚手架系列4--测试用例、拦截器

异常处理、拦截器、数据库连接 1 测试用例 单元测试是一个老生常谈的问题&#xff0c;无论是后端对自己的代码质量把的第一道关也好&#xff0c;也是对测试减缓压力。这里就不过多讲述测试用例的重要性&#xff0c;但是有2个框架我们必须了解一下。 1.1 JUnit和mockito 我们…...

论文推荐 |【Agent】自动化Agent设计系统

论文标题&#xff1a; Automated Design of Agentic Systems 论文地址&#xff1a; https://arxiv.org/abs/2408.08435 GitHub地址&#xff1a; https://github.com/ShengranHu/ADAS 自动化代理设计在性能和通用性方面显著超越了手动方法。 • 引入了自动化代理系统设计&am…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

js 设置3秒后执行

如何在JavaScript中延迟3秒执行操作 在JavaScript中&#xff0c;要设置一个操作在指定延迟后&#xff08;例如3秒&#xff09;执行&#xff0c;可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法&#xff0c;它接受两个参数&#xff1a; 要执行的函数&…...

高端性能封装正在突破性能壁垒,其芯片集成技术助力人工智能革命。

2024 年&#xff0c;高端封装市场规模为 80 亿美元&#xff0c;预计到 2030 年将超过 280 亿美元&#xff0c;2024-2030 年复合年增长率为 23%。 细分到各个终端市场&#xff0c;最大的高端性能封装市场是“电信和基础设施”&#xff0c;2024 年该市场创造了超过 67% 的收入。…...