Spring Boot默认缓存管理
Spring框架支持透明地向应用程序添加缓存,以及对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法,从而减少操作数据的执行次数,同时不会对程序本身造成任何干扰。Spring Boot继承了Spring框架的缓存管理功能,下面将对Spring Boot内置的缓存方案进行讲解。
Spring的缓存机制将提供的缓存作用于Java 方法上,基于缓存中的可用信息,可以减少方法的执行次数。每次目标方法调用时,抽象使用缓存行为来检查执行方法,即检查执行方法是否给定了缓存的执行参数,如果是,则返回缓存结果,不执行具体方法;如果否,则执行方法,并将结果缓存后,返回给用户。
Spring的默认的缓存方案通过org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术。
Cache接口:缓存的组件定义规范,包含缓存的各种操作集合。Spring中为Cache接口提供了各种缓存的实现:RedisCache,EhCache,ConcurrentMapCache等
CacheManager接口:缓存管理器,基于缓存名称对缓存进行管理,并制定了管理Cache的规则。
在项目中添加某个缓存管理组件(如Redis)后,Spring Boot项目会选择并启用对应的缓存管理器。如果项目中同时添加了多个缓存组件,且没有定义类型为CacheManager的Bean组件或者名为cacheResolver的缓存解析器,Spring Boot将尝试按以下列表的顺序查找有效的缓存组件进行缓存管理。 (1)Generic (2)JCache (EhCache 3、Hazelcast、Infinispan等) (3)EhCache 2.x (4)Hazelcast (5)Infinispan (6)Couchbase (7)Redis (8)Caffeine (9)Simple
声明式缓存注解
要想使用Spring提供的默认缓存,需要对缓存进行声明,也就是标志缓存的方法及缓存策略。对于缓存声明,Spring提供了一系列的注解,使用这些注解可以实现Spring 默认的基于注解的缓存管理。
1.@EnableCaching注解
@EnableCaching是Spring框架提供的用于开启基于注解的缓存支持的注解,当配置类上使用@EnableCaching注解,会默认提供CacheManager的实现,并通过AOP将缓存行为添加到应用程序。执行操作时,会检查是否已经存在注解对应的缓存。如果找到了,就会自动创建一个代理拦截方法调用,使用缓存的Bean执行处理。
2.@Cacheable注解
@Cacheable注解用于标注可缓存的方法,通常标注的方法为数据查询方法。标注@Cacheable注解的方法在执行时,会先查询缓存,如果查询到的缓存为空,则执行该方法,并将方法的执行结果添加到缓存;如果查询到缓存数据,则不执行该方法,而是直接使用缓存数据。
@Cacheable注解提供了多个属性,用于对缓存进行相关配置。
属性名 | 说明 |
value/cacheNames | 指定缓存的名称,必备属性,这两个属性二选一使用 |
key | 指定缓存数据的key,默认使用方法参数值,可以使用SpEL表达式 |
keyGenerator | 指定缓存数据的key的生成器,与key属性二选一使用 |
cacheManager | 指定缓存管理器 |
cacheResolver | 指定缓存解析器,与cacheManager属性二选一使用 |
condition | 指定在符合某条件下进行数据缓存 |
unless | 指定在符合某条件下不进行数据缓存 |
sync | 指定是否使用异步缓存,默认为false |
(1)value/cacheNames属性
value和cacheNames属性作用相同,用于指定缓存的名称,方法的返回结果会存放在指定名称的缓存中。这两个属于必备选项,且要二选一使用。如果@Cacheable注解只配置value或者cacheNames属性,那么属性名可以省略。
@Cacheable("book")
public Book findById(Integer id){return bookDao.findById(id).get();
}
@Cacheable注解中可以指定多个缓存的名称,以便使用多个缓存。
@Cacheable({"book","hotBook"})
public Book findById(Integer id){return bookDao.findById(id).get();
}
(2)key属性
缓存的本质是键值对存储,key用于指定唯一的标识,value用于指定缓存的数据,所以每次调用缓存方法都会转换为访问缓存的键。缓存的键通过key属性进行指定,进行数据缓存时,如果没有指定key属性,Spring Boot默认配置类SimpleKeyGenerator中的generateKey(Object... params)方法会根据方法参数生成key值。对于没有参数的方法,其key是默认创建的空参SimpleKey[]对象;对于只有一个参数的方法,其key默认是参数值;对于有多个参数的方法,其key是包含所有参数的SimpleKey对象。
如果方法有多个参数,但是部分参数对缓存没有任何用处,通常会选择手动指定key属性的值,key属性的值可以通过SpEL表达式选择所需要的参数。
@Cacheable(cacheNames="book", key="#id")
public Book findBookById(Integer id, boolean includeUsed){return bookDao.findById(id).get();
}
Cache缓存支持的SpEL表达式及说明
参数名 | 位置 | 描述 | 示例 |
methodName | root对象 | 当前被调用的方法名 | #root.methodName |
method | root对象 | 当前被调用的方法 | #root.method.name |
target | root对象 | 当前被调用的目标对象实例 | #root.target |
targetClass | root对象 | 当前被调用的目标对象的类 | #root.targetClass |
args | root对象 | 当前被调用的方法的参数列表 | #root.args[0] |
caches | root对象 | 当前被调用的方法的缓存列表 | #root.caches[0].name |
argumentName | 执行上下文 | 当前被调用的方法参数,可以用#参数名或者#a0、#p0的形式(0代表参数索引,从0开始) | #comment_id、#a0、#p0 |
result | 执行上下文 | 当前方法执行后的返回结果 | #result |
(3)keyGenerator属性
keyGenerator属性与key属性本质作用相同,都是用于指定缓存数据的key,只不过keyGenerator属性指定的不是具体的key值,而是key值的生成器规则,由其中指定的生成器生成具体的key。使用时,keyGenerator属性与key属性要二者选一。关于自定义key值生成器的定义,可以参考Spring Boot默认配置类SimpleKeyGenerator的定义方式,这里不再做具体说明。
(4)cacheManager/cacheResolver属性
cacheManager和cacheResolver属性分别用于指定缓存管理器和缓存解析器,这两个属性也是二选一使用,默认情况不需要配置,对于需要使用多个缓存管理器(如Redis、Ehcache等)的应用,可以为每个操作设置一个缓存管理器或缓存解析器。
(5)condition属性
condition属性用于对数据进行有条件的选择性存储,只有当指定条件为true时才会对查询结果进行缓存,可以使用SpEL表达式指定属性值。
@Cacheable(cacheNames="book", condition="#id > 1")
public Book findBook(Integer id){return bookDao.findById(id).get();
}
(6)unless属性
unless属性的作用与condition属性相反,当指定的条件为true时,方法的返回值不会被缓存,也可以使用SpEL表达式指定。
@Cacheable(cacheNames="book", unless = "#result==null")
public Book findBook(Integer id){return bookDao.findById(id).get();
}
(7)sync属性
在多线程程序中,某些操作可能会同时引用相同的参数,导致相同的对象被计算好几次,从而达不到缓存的目的。对于这种情况,可以使用sync属性,sync属性表示数据缓存过程中是否使用同步模式,默认值为false,通常不会使用该属性。
3.@CachePut注解
@CachePut注解的作用是更新缓存数据,当需要更新缓存且不影响方法执行时,可以使用@CachePut注解,通常用在数据更新方法上。@CachePut注解的执行顺序是,先进行方法调用,然后将方法结果更新到缓存中。
@CachePut注解也提供了多个属性,这些属性与@Cacheable注解的属性完全相同。通常不建议在同一个方法同时使用@CachePut和@Cacheable注解,这两个注解关注不同的行为,@CachePut注解会强制执行方法并进行缓存更新,使用@Cacheable 注解时,如果请求能够在缓存中获取到对应的数据,就不会执行当前被@Cacheable 注解标注的方法。
4.@CacheEvict注解
@CacheEvict注解的作用删除缓存中的数据,通常标注在数据删除方法上。@CacheEvict注解的默认执行顺序是先进行方法调用,然后将缓存清除。 @CacheEvict注解也提供了多个属性,这些属性与@Cacheable注解的属性基本相同,除此之外,还额外提供了两个特殊属性allEntries和beforeInvocation,下面对这两个属性分别进行讲解。
(1)allEntries属性 allEntries属性表示是否清除指定缓存空间中的所有缓存数据,默认值为false,即默认只删除指定key对应的缓存数据。
@CacheEvict(cacheNames = "book",allEntries = true)
public void delById(Integer id){bookDao.deleteById(id);
}
(2)beforeInvocation属性 beforeInvocation属性表示是否在方法执行之前进行缓存清除,默认值为false,即默认在执行方法后再进行缓存清除。
@CacheEvict(cacheNames = "book",beforeInvocation = true)
public void delById(Integer id){bookDao.deleteById(id);
}
5.@Caching注解
如果不同缓存之间的条件或者键表达式不同,就需要指定相同类型的多个注解,例如需要同时指定多个@CacheEvict或@CachePut,这个时候可以使用@Caching注解。@Caching注解用于针对复杂规则的数据缓存管理,@Caching注解中允许使用多个嵌套的 @Cacheable 、@CachePut 或 @CacheEvict。在@Caching注解内部包含有Cacheable、put和evict三个属性,分别对应于@Cacheable、@CachePut和@CacheEvict三个注解。
@Caching(evict = { @CacheEvict("primary"),
@CacheEvict(cacheNames="secondary", key="#date")})
public void delById(Integer id, Date date){bookDao.deleteById(id);
}
@Caching(cacheable={@Cacheable(cacheNames ="comment",key = "#id")},put = {@CachePut(cacheNames = "comment",key = "#result.author")})public Comment getComment(int comment_id){return commentRepository.findById(comment_id).get();}
6.@CacheConfig注解
@CacheConfig注解使用在类上,主要用于统筹管理类中所有使用@Cacheable、@CachePut和@CacheEvict注解标注方法中的公共属性。
@CacheConfig(cacheNames = "book")
@Service
public class BookService {@Autowiredprivate BookRepository bookRepository;@Cacheablepublic Book findById(Integer id){return bookRepository.findById(id).get();}
}
声明式缓存注解的应用
1.创建项目
2.配置依赖
<!-- springboot默认应该有,不配应该没关系-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-jpa
</artifactId>
</dependency>
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
</dependency>
3.设置配置信息
spring:datasource:url:"jdbc:mysql://localhost:3306/springbootdata?characterEncoding=utf-8&serverTimezone=Asia/Shanghai"username:rootpassword:rootjpa:show-sql:true
4.创建实体类
@Entity
@Table(name="book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; //图书编号
@Column(name="name")
private String name; //图书名称
private String author; //图书作者
private String press; //图书出版社
private String status; //图书状态public Integer getId() {
return id;
}public void setId(Integer id) {
this .id = id;
}public String getName() {
return name;
}public void setName(String name) {
this .name = name;
}public String getPress() {
return press;
}public void setPress(String press) {
this .press = press;
}public String getAuthor() {
return author;
}public void setAuthor(String author) {
this .author = author;
}public String getStatus() {
return status;
}public void setStatus(String status) {
this .status = status;
}public Book() {
}public Book(Integer id, String name, String author, String press, String status) {
this .id = id;
this .name = name;
this .author = author;
this .press = press;
this .status = status;
}@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + ''' +
", author='" + author + ''' +
", press='" + press + ''' +
", status='" + status + ''' +
'
}';
}
}
5.创建Repository接口
@Repository
public interface BookRepository extends JpaRepository<Book,Integer> {
}
6.创建Service接口和实现类
public interface BookService {
public Book findById(Integer id);
public Book updateById(Integer id,String name);
public void delById(Integer id);
}
@Service
@CacheConfig(cacheNames = "book")
@Transactional
public class BookServiceImpl implements BookService{
@Autowired
private BookRepository bookRepository;@Cacheable(key = "#id")
public Book findById(Integer id){
//根据id查找图书信息
return bookRepository.findById(id).get();
}
@CachePut(key = "#id")
public Book updateById(Integer id,String name){
Book book=this .findById(id);
book.setName(name);
//更新图书信息
return bookRepository.save(book);
}
@CacheEvict(key = "#id")
public void delById(Integer id){
//根据id删除图书信息
bookRepository.deleteById(id);
}
}
7.创建控制器类
@RestController
@RequestMapping("book")
public class BookController {
@Autowired
private BookService bookService;@RequestMapping("/findById/{id}")
public Book findById(@PathVariable Integer id){
//根据id查询图书信息
return bookService.findById(id);
}
@RequestMapping("/editById/{id}/{name}")
public Book editById(@PathVariable Integer id,@PathVariable String name){
//根据id修改图书的名称
return bookService.updateById(id,name);
}
@RequestMapping("/delById/{id}")
public void delById(@PathVariable Integer id){
//根据id删除图书信息
bookService.delById(id);
}
}
8.在启动类上开启缓存
@SpringBootApplication
@EnableCaching
public class Chapter06Application {
public static void main(String[] args) {
SpringApplication.run(Chapter06Application.class , args);
}
}
9.测试缓存效果
启动项目,在浏览器中访问http://localhost:8080/book/findById/3,查询图书信息,控制台输出信息。
查询图书信息后,浏览器中查询到图书信息。
再次在浏览器中访问http://localhost:8080/book/findById/3,查询id为3的图书信息,控制台输出信息。
在浏览器中访问http://localhost:8080/book/editById/3/西游释厄传,将id为3的图书名称更新为“西游释厄传”,此时控制台输出信息。
更新图书信息后,浏览器中查询图书信息。
浏览器中访问http://localhost:8080/book/delById/3,删除id为3的图书信息,控制台输出信息。
在浏览器中再次访问http://localhost:8080/book/findById/3,查询id为3的图书信息,控制台输出信息。
动手试一试 Spring Boot默认缓存管理
测试发生一万次请求需要的时间(jdk11以上)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;public class HttpRequestBenchmark {public static void main(String[] args) throws Exception {String url = "http://localhost:8081/get/1"; // 替换为你要请求的URLint numRequests = 10000; // 请求次数HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(new URI(url)).build();long startTime = System.nanoTime();// 使用CompletableFuture来异步发送请求,并等待所有请求完成CompletableFuture<Void>[] futures = IntStream.range(0, numRequests).mapToObj(i -> CompletableFuture.runAsync(() -> {try {HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());// 在这里可以处理响应,例如检查状态码等System.out.println("xiangying------------------");// 这里只是简单发送请求并忽略响应内容} catch (Exception e) {e.printStackTrace();}})).toArray(CompletableFuture[]::new);// 等待所有请求完成CompletableFuture.allOf(futures).join();long endTime = System.nanoTime();Duration duration = Duration.ofNanos(endTime - startTime);System.out.println("发送" + numRequests + "次HTTP请求需要的时间:" + duration.toMillis() + "毫秒");}
相关文章:

Spring Boot默认缓存管理
Spring框架支持透明地向应用程序添加缓存,以及对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法,从而减少操作数据的执行次数,同时不会对程序本身造成任何干扰。Spring Boot继承了Spring框架的缓存管理功能ÿ…...

XYNU2024信安杯-REVERSE(复现)
前言 记录记录 1.Can_you_find_me? 签到题,秒了 2.ea_re 快速定位 int __cdecl main_0(int argc, const char **argv, const char **envp) {int v4; // [esp0h] [ebp-1A0h]const char **v5; // [esp4h] [ebp-19Ch]const char **v6; // [esp8h] [ebp-198h]char v7;…...

MySQL的MVCC【学习笔记】
MVCC 事务的隔离级别分为四种,其中Read Committed和Repeatable Read隔离级别,部分实现就是通过MVCC(Multi-Version Concurrency Control,多版本并发控制) 版本链 版本链是通过undo日志实现的, 事务每次修改…...
罗德FSP13 FSP40频谱分析仪频率13.6GHz
罗德FSP13 FSP40频谱分析仪频率13.6GHz 附加的功能: 分辨率带宽:1 Hz 至 10 MHz 显示的平均噪音水平:-155 dBm (1 Hz) 相位噪声:10 kHz 时 -113 dB (1 Hz) 附加滤波器:100 Hz 至 5 MHz 的通道滤波器和 RRC 滤波器、…...
腾讯PC客户端面经
1.有关虚函数调用问题 空指针可以在特定的情况下去调用非虚函数,因为非虚函数在编译阶段就可以确定地址,调用的时候this指针传的是nullptr没有问题,不需要依赖对象的创建。 空指针不可以去调用虚函数,因为虚函数的调用需要虚表&…...

达梦数据库压力测试报错超出全局hash join空间,适当增加HJ_BUF_GLOBAL_SIZE解决
1.名词解释:达梦数据库中的HJ_BUF_GLOBAL_SIZE是所有哈希连接操作可用的最大哈希缓冲区大小,单位为兆字节(MB) 2.达梦压测报错: 3.找到达梦数据库安装文件 4.压力测试脚本 import http.client import multiprocessi…...

Oracle--SQL性能优化与提升策略
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 一、导致性能问题的内在原因 系统性能问题的底层原因主要有三个方面: CPU占用率过高导致资源争用和等待内存使用率过高导致内存不足并需…...
如何在Spring Boot中配置自定义端口运行应用程序
Spring Boot 应用程序默认在端口 8080 上运行嵌入式 Web 服务器(如 Tomcat、Jetty 或 Undertow)。然而,在开发、测试或生产环境中,开发者可能需要将应用程序配置为在自定义端口上运行,例如避免端口冲突、适配微服务架构…...

六个能够白嫖学习资料的网站
一、咖喱君的资源库 地址:https://flowus.cn/galijun/share/de0f6d2f-df17-4075-86ed-ebead0394a77 这是一个学习资料/学习网站分享平台,包含了英语、法语、德语、韩语、日语、泰语等几十种外国语言的学习资料及平台,这个网站的优势就是外语…...
破界出海:HR SaaS平台的全球化实践与组织效能跃升
全球化浪潮下的HR SaaS破局实践 在全球化与数字化双重浪潮的推动下,中国企业出海已从战略选择演变为生存刚需。然而,跨文化管理冲突、多国法律合规风险、复杂薪酬体系与人才发展需求,构成了企业国际化的四大核心挑战。据艾瑞咨询数据&#x…...

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤
以下是在 IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤: 步骤 1:创建 Maven Web 项目 新建项目 File -> New -> Project → 选择 Maven → 勾选 Create from archetype → 选择 maven-archetype-webapp。输入 GroupId(如 com.examp…...

手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段
手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段 --本地AI电话机器人 前言 书接上一篇,《手机打电话通话时如何向对方播放录制的IVR引导词声音》中介绍了【蓝牙电话SDK示例App】可以实现手机app在电话通话过程中插播预先录制的开场白等语音片段的功能。…...

SpringCloud——负载均衡
一.负载均衡 1.问题提出 上一篇文章写了服务注册和服务发现的相关内容。这里再提出一个新问题,如果我给一个服务开了多个端口,这几个端口都可以访问服务。 例如,在上一篇文章的基础上,我又新开了9091和9092端口,现在…...
Python Transformers 库介绍
Hugging Face 的 Transformers 库是一个用于自然语言处理(NLP)的强大 Python 库,它提供了对各种预训练模型的访问和使用接口。该库具有以下特点和功能: 主要特点 丰富的预训练模型:Transformers 库包含了大量的预训练模型,如 BERT、GPT - 2、RoBERTa、XLNet 等。这些模型…...

string的基本使用
string的模拟实现 string的基本用法string的遍历(三种方式):关于auto(自动推导):范围for: 迭代器普通迭代器(可读可改)const迭代器(可读不可改) string细小知识点string的常见接口引…...

深入解析Mlivus Cloud核心架构:rootcoord组件的最佳实践与调优指南
作为大禹智库的向量数据库高级研究员,同时也是《向量数据库指南》的作者,我在过去30年的向量数据库和AI应用实战中见证了这项技术的演进与革新。今天,我将以专业视角为您深入剖析Mlivus Cloud的核心组件之一——rootcoord,这个组件在系统架构中扮演着至关重要的角色。如果您…...
docker 代理配置冲突问题
问题描述 执行 systemctl show --property=Environment docker 命令看到有如下代理配置 sudo systemctl show --property=Environment docker Environment=HTTP_PROXY=http://127.0.0.1:65001 HTTPS_PROXY=http://127.0.0.1:65001 NO_PROXY=127.0.0.1,docker.io,ghcr.io,uhub…...
Nginx 配置参数全解版:Nginx 反向代理与负载均衡;Nginx 配置规范与 Header 透传实践指南;Nginx 配置参数详解
Nginx 配置参数全解版:Nginx 反向代理与负载均衡;Nginx 配置规范与 Header 透传实践指南;Nginx 配置参数详解 Nginx 反向代理与负载均衡配置,Header 透传到后端应用(参数全解版)一、Nginx 反向代理与负载均…...

Python常用的第三方模块之【pymysql库】操作数据库
pymysql是在Python3.x版本中用于连接MySQL服务器的一个实现库,Python2中则是使用musqldb。 PyMySQL 是一个纯 Python 实现的 MySQL 客户端库,它允许我们直接在 Python 中执行 SQL 语句并与 MySQL 数据库进行交互。下面我们将详细介绍如何使用 PyMySQL 进…...

【Python数据分析】Pandas模块之pd.concat 函数
💭 写在前面:合并多个数据框,收集各种数据,并将其合并为一个数据框进行分析。本章我们介绍 Pandas 库中数据框合并的函数 —— concat。 0x00 引入:数据框的合并操作 合并多个数据框:收集各种数据,并将其合并为一个数据框进行分析。 下面介绍一些常用的 Pandas 库中数…...
矫平机深度解析:操作实务、行业标准与智能化升级
一、精细操作指南:不同材料的矫平参数设定 1. 常见金属矫平参数参考表 材料类型 厚度范围(mm) 辊缝初始值(mm) 矫平速度(m/min) 压力系数(k值) 低碳钢(…...
【高频考点精讲】CSS accent-color属性:如何快速自定义表单控件的颜色?
用CSS accent-color属性3分钟搞定表单控件换肤,原来这么简单! 前几天有个学员问我,checkbox和radio这些表单控件默认样式太丑了,有没有什么办法能快速改颜色?" 我一看这问题就乐了——这不正是CSS accent-color属性的拿手好戏吗?今天咱们就来好好聊聊这个被低估的C…...

C# 综合示例 库存管理系统7 主界面(FormMain)
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的 图99A-22 主界面窗口设计 主界面是多文档界面容器,需要将窗体属性IsMdiContainer设置为True。关于多文档界面编程请参看教程第7.12节《多文档界面》。 主界面并不提…...
vue项目中axios统一或单独控制接口请求时间
先说统一 这里将请求时间统一控制在12秒 // 使用由库提供的配置的默认值来创建实例 // 此时超时配置的默认值是 0 const axiosInstance axios.create()// 覆写库的超时默认值 // 现在,在超时前,所有请求时间统一控制在10秒 axiosInstance.defaults.ti…...
Codeforces Round 1020 (Div. 3) A-D
A. Dr. TC https://codeforces.com/contest/2106/problem/A 题目大意: 对输入字符串每个位置字符依次翻转(1->0 , 0->1) 比如: 101 001 翻转位置1 111 2 100 3 题解: 观察数学特征:ansn…...

系统思考:看清问题背后的结构
组织的挑战,往往不是因为不努力,而是“看不清” 结束了为期两天系统思考课程的第一天,被学员的全情投入深深打动。我们用系统结构图,一步步揭示那些表面看起来“习以为常”的问题: 什么原因跨部门协作总是磕磕绊绊&am…...
netlist
在电子设计自动化(EDA)中,网表(Netlist) 是描述电路设计连接关系的核心数据结构,本质上是电路元件(如逻辑门、晶体管、模块)及其互连关系的 文本化或结构化表示。它是从抽象设计&…...
如何实现Android屏幕和音频采集并启动RTSP服务?
技术背景 在移动直播和视频监控领域,实现高效的屏幕和音频采集并提供流媒体服务是关键技术之一。本文将详细介绍如何基于大牛直播SDK实现Android屏幕和麦克风/扬声器采集,并启动轻量级RTSP服务以对外提供拉流的RTSP URL。在Android平台上,轻…...

Langchain_Agent+数据库
本处使用Agent数据库,可以直接执行SQL语句。可以多次循环查询问题 前文通过chain去联系数据库并进行操作; 通过链的不断内嵌组合,生成SQL在执行SQL再返回。 初始化 import os from operator import itemgetterimport bs4 from langchain.ch…...

QT6 源(45):分隔条 QSplitter 允许程序的用户修改布局,程序员使用 IDE时,就是分隔条的用户,以及其 QSplitter 源代码
(1) (2)本类的继承关系如下,所以说分隔条属于容器: (3)本类的属性: (4) 这是一份 QSplitter 的举例代码,注意其构造函数时候的传参&am…...