Spring开发系列教程(26)——异步处理
在Servlet模型中,每个请求都是由某个线程处理,然后,将响应写入IO流,发送给客户端。从开始处理请求,到写入响应完成,都是在同一个线程中处理的。
实现Servlet容器的时候,只要每处理一个请求,就创建一个新线程处理它,就能保证正确实现了Servlet线程模型。在实际产品中,例如Tomcat,总是通过线程池来处理请求,它仍然符合一个请求从头到尾都由某一个线程处理。
这种线程模型非常重要,因为Spring的JDBC事务是基于ThreadLocal
实现的,如果在处理过程中,一会由线程A处理,一会又由线程B处理,那事务就全乱套了。此外,很多安全认证,也是基于ThreadLocal
实现的,可以保证在处理请求的过程中,各个线程互不影响。
但是,如果一个请求处理的时间较长,例如几秒钟甚至更长,那么,这种基于线程池的同步模型很快就会把所有线程耗尽,导致服务器无法响应新的请求。如果把长时间处理的请求改为异步处理,那么线程池的利用率就会大大提高。Servlet从3.0规范开始添加了异步支持,允许对一个请求进行异步处理。
我们先来看看在Spring MVC中如何实现对请求进行异步处理的逻辑。首先建立一个Web工程,然后编辑web.xml
文件如下:
<web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></init-param><init-param><param-name>contextConfigLocation</param-name><param-value>com.itranswarp.learnjava.AppConfig</param-value></init-param><load-on-startup>0</load-on-startup><async-supported>true</async-supported></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/*</url-pattern></servlet-mapping>
</web-app>
和前面普通的MVC程序相比,这个web.xml
主要对DispatcherServlet
的配置多了一个<async-supported>
,默认值是false
,必须明确写成true
,这样Servlet容器才会支持async处理。
下一步就是在Controller中编写async处理逻辑。我们以ApiController
为例,演示如何异步处理请求。
第一种async处理方式是返回一个Callable
,Spring MVC自动把返回的Callable
放入线程池执行,等待结果返回后再写入响应:
@GetMapping("/users")
public Callable<List<User>> users() {return () -> {// 模拟3秒耗时:try {Thread.sleep(3000);} catch (InterruptedException e) {}return userService.getUsers();};
}
第二种async处理方式是返回一个DeferredResult
对象,然后在另一个线程中,设置此对象的值并写入响应:
@GetMapping("/users/{id}")
public DeferredResult<User> user(@PathVariable("id") long id) {DeferredResult<User> result = new DeferredResult<>(3000L); // 3秒超时new Thread(() -> {// 等待1秒:try {Thread.sleep(1000);} catch (InterruptedException e) {}try {User user = userService.getUserById(id);// 设置正常结果并由Spring MVC写入Response:result.setResult(user);} catch (Exception e) {// 设置错误结果并由Spring MVC写入Response:result.setErrorResult(Map.of("error", e.getClass().getSimpleName(), "message", e.getMessage()));}}).start();return result;
}
使用DeferredResult
时,可以设置超时,超时会自动返回超时错误响应。在另一个线程中,可以调用setResult()
写入结果,也可以调用setErrorResult()
写入一个错误结果。
运行程序,当我们访问http://localhost:8080/api/users/1
时,假定用户存在,则浏览器在1秒后返回结果:
访问一个不存在的User ID,则等待1秒后返回错误结果:
使用Filter
当我们使用async模式处理请求时,原有的Filter也可以工作,但我们必须在web.xml
中添加<async-supported>
并设置为true
。我们用两个Filter:SyncFilter和AsyncFilter分别测试:
<web-app ...>...<filter><filter-name>sync-filter</filter-name><filter-class>com.itranswarp.learnjava.web.SyncFilter</filter-class></filter><filter><filter-name>async-filter</filter-name><filter-class>com.itranswarp.learnjava.web.AsyncFilter</filter-class><async-supported>true</async-supported></filter><filter-mapping><filter-name>sync-filter</filter-name><url-pattern>/api/version</url-pattern></filter-mapping><filter-mapping><filter-name>async-filter</filter-name><url-pattern>/api/*</url-pattern></filter-mapping>...
</web-app>
一个声明为支持<async-supported>
的Filter既可以过滤async处理请求,也可以过滤正常的同步处理请求,而未声明<async-supported>
的Filter无法支持async请求,如果一个普通的Filter遇到async请求时,会直接报错,因此,务必注意普通Filter的<url-pattern>
不要匹配async请求路径。
在logback.xml
配置文件中,我们把输出格式加上[%thread]
,可以输出当前线程的名称:
<?xml version="1.0" encoding="UTF-8"?>
<configuration><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><layout class="ch.qos.logback.classic.PatternLayout"><Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern></layout></appender>...
</configuration>
对于同步请求,例如/api/version
,我们可以看到如下输出:
2020-05-16 11:22:40 [http-nio-8080-exec-1] INFO c.i.learnjava.web.SyncFilter - start SyncFilter...
2020-05-16 11:22:40 [http-nio-8080-exec-1] INFO c.i.learnjava.web.AsyncFilter - start AsyncFilter...
2020-05-16 11:22:40 [http-nio-8080-exec-1] INFO c.i.learnjava.web.ApiController - get version...
2020-05-16 11:22:40 [http-nio-8080-exec-1] INFO c.i.learnjava.web.AsyncFilter - end AsyncFilter.
2020-05-16 11:22:40 [http-nio-8080-exec-1] INFO c.i.learnjava.web.SyncFilter - end SyncFilter.
可见,每个Filter和ApiController
都是由同一个线程执行。
对于异步请求,例如/api/users
,我们可以看到如下输出:
2020-05-16 11:23:49 [http-nio-8080-exec-4] INFO c.i.learnjava.web.AsyncFilter - start AsyncFilter...
2020-05-16 11:23:49 [http-nio-8080-exec-4] INFO c.i.learnjava.web.ApiController - get users...
2020-05-16 11:23:49 [http-nio-8080-exec-4] INFO c.i.learnjava.web.AsyncFilter - end AsyncFilter.
2020-05-16 11:23:52 [MvcAsync1] INFO c.i.learnjava.web.ApiController - return users...
可见,AsyncFilter
和ApiController
是由同一个线程执行的,但是,返回响应的是另一个线程。
对DeferredResult
测试,可以看到如下输出:
2020-05-16 11:25:24 [http-nio-8080-exec-8] INFO c.i.learnjava.web.AsyncFilter - start AsyncFilter...
2020-05-16 11:25:24 [http-nio-8080-exec-8] INFO c.i.learnjava.web.AsyncFilter - end AsyncFilter.
2020-05-16 11:25:25 [Thread-2] INFO c.i.learnjava.web.ApiController - deferred result is set.
同样,返回响应的是另一个线程。
在实际使用时,经常用到的就是DeferredResult
,因为返回DeferredResult
时,可以设置超时、正常结果和错误结果,易于编写比较灵活的逻辑。
使用async异步处理响应时,要时刻牢记,在另一个异步线程中的事务和Controller方法中执行的事务不是同一个事务,在Controller中绑定的ThreadLocal
信息也无法在异步线程中获取。
此外,Servlet 3.0规范添加的异步支持是针对同步模型打了一个“补丁”,虽然可以异步处理请求,但高并发异步请求时,它的处理效率并不高,因为这种异步模型并没有用到真正的“原生”异步。Java标准库提供了封装操作系统的异步IO包java.nio
,是真正的多路复用IO模型,可以用少量线程支持大量并发。使用NIO编程复杂度比同步IO高很多,因此我们很少直接使用NIO。相反,大部分需要高性能异步IO的应用程序会选择Netty这样的框架,它基于NIO提供了更易于使用的API,方便开发异步应用程序。
相关文章:
Spring开发系列教程(26)——异步处理
在Servlet模型中,每个请求都是由某个线程处理,然后,将响应写入IO流,发送给客户端。从开始处理请求,到写入响应完成,都是在同一个线程中处理的。 实现Servlet容器的时候,只要每处理一个请求&…...
【2025最新Java面试八股】如何理解MySQL的MVCC机制?
面试回答要点 当面试官问及MySQL的MVCC机制时,可以这样组织回答: "MVCC(Multi-Version Concurrency Control,多版本并发控制)是MySQL实现高并发事务的一种重要机制,它通过保存数据在某个时间点的快照来实现非阻塞读操作。I…...
使用FreeRTOS解决单片机串口异步打印
单片机串口异步打印 文章目录 单片机串口异步打印前言设计思路准备队列创建完整代码 总结 前言 🌊在单片机开发中串口的异步打印异步打印允许单片机在执行其他任务的同时进行打印操作,无需等待打印完成后再继续执行后续代码,避免了在多处调用…...
飞算 JavaAI 与 Spring Boot:如何实现微服务开发效率翻倍?
微服务架构凭借其高内聚、低耦合的特性,成为企业构建复杂应用系统的首选方案。然而,传统微服务开发流程中,从服务拆分、接口设计到代码编写、调试部署,往往需要耗费大量时间与人力成本。Spring Boot 作为 Java 领域最受欢迎的微服…...
Python 列表与元组深度解析:从基础概念到函数实现全攻略
在 Python 编程的广袤天地中,列表(List)和元组(Tuple)是两种不可或缺的数据结构。它们如同程序员手中的瑞士军刀,能高效地处理各类数据。从简单的数值存储到复杂的数据组织,列表和元组都发挥着关…...
vue 修改路由动态选择路由 改文件位置
vue 修改路由动态选择路由 改文件位置 main.jspermission.js...
Nginx openresty web服务 与 Go 原生web服务性能对比
1 概述 Nginx采用的是IO复用模型,能处理超高并发。 Go语言采用协程,能轻量级的处理超高并发。 那么在不考虑业务逻辑复杂的前提下,即假如将Nginx和Go都提供一个/test接口,并在接口逻辑中都只是让其做20毫秒的耗时操作,…...
【音视频】FFmpeg解封装
解封装 复用器,比如MP4/FLV 解复用器,MP4/FLV 封装格式相关函数 avformat_alloc_context(); 负责申请一个AVFormatContext结构的内存,并进行简单初始化avformat_free_context(); 释放该结构里的所有东西以及该结构本身avformat_close_input();关闭解复…...
autohue.js - 基于 JavaScript 开发的图片背景色提取开源库,能让图片和背景融为一体
图片提取主题色的工具库,可以实现一些酷炫的界面效果。 本文不是 AI 生成,大部分文字都是我自己敲键盘,部分文字摘自 autohue.js 作者主页,请各位放心舒适阅读。 autohue.js 是一个图片背景色提取库,基于提出来的颜色…...
bgp实验.包括联盟,隧道相关,以及一个低级错误
实验拓扑 低级错误 在配置隧道时,目标的单词是destination,我自动补全为description了,这个问题花了我40分钟 划分ip AS2内骨干网,一个网段需要两个地址,主机位2位,掩码30 需要6个 172.16.0.000000 00 172.16.0.0/30 172.16.0.000001 00 172.16.0.4/30 172.16.0.000010 00 1…...
科普动画短视频制作:角色塑造的魅力法则
宝子们,在科普动画短视频的世界里,角色塑造可是让作品出彩的关键!今天就来和大家唠唠那些超实用的角色塑造法则,还会给大家推荐一款超好用的工具哦~ 一、独特外形,吸睛第一步 在科普动画短视频制作中,角色…...
【飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南】
飞渡科技数字孪生虚拟环境部署与集成教程 - CloudMaster实战指南 前言 本教程详细记录了飞渡科技的数字孪生平台CloudMaster的配置过程,以及如何将三维数字孪生场景集成到前端项目中。数字孪生技术能够在虚拟环境中精确复现物理实体的数据、特性和行为,…...
MongoDB 集合名称映射问题
项目场景 在使用 Spring Data MongoDB 进行开发时,定义了一个名为 CompetitionSignUpLog 的实体类,并创建了对应的 Repository 接口。需要明确该实体类在 MongoDB 中实际对应的集合名称是 CompetitionSignUpLog 还是 competitionSignUpLog。 问题描述 …...
禁止ubuntu自动更新
由于ubuntu server和desktop版本都默认 启动了,自动更新内核的操作。这对于生 产环境来说是不友好的。容易导致亿赛通 无法启动 默认开启了内核自动更新所以我们关闭自 动内核更新。 1.禁止更新执行 sudo apt-mark hold linux-image-generic linux-headers-generic…...
【C++】——入门基础(一)
前言 这是我C的第一篇文章,如果你想从事入门C行业,可以看看这幅漫画 当然,这只是一个玩笑,但如过你真的想学习C,和我一起学习吧 本人其他博客;恋风诗 本文出现的代码见gitte:mozhengy 这里写目录标题 前言1. C发展历史…...
[原创](现代Delphi 12指南):[macOS 64bit App开发]:在Mac App Store外创建、部署与公证
[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...
美乐迪电玩客户端打包与资源替换实战教程
本篇为《美乐迪电玩全套系统搭建》系列的第二篇,聚焦客户端层的实战操作,主要面向前端开发者、美术资源替换人员及整体项目的打包部署人员。教程将涵盖安卓客户端的构建、资源目录说明、动画素材替换方式及常见适配问题处理等。 一、客户端项目结构说明&…...
多态以及多态底层的实现原理
本章目标 1.多态的概念 2.多态的定义实现 3.虚函数 4.多态的原理 1.多态的概念 多态作为面对三大特性之一,它所指代的和它的名字一样,多种形态.但是这个多种形态更多的指代是函数的多种形态. 多态分为静态多态和动态多态. 静态多态在前面已经学习过了,就是函数重载以及模板,…...
描述城市出行需求模式的复杂网络视角:大规模起点-目的地需求网络的图论分析
描述城市出行需求模式的复杂网络视角:大规模起点-目的地需求网络的图论分析 原文: A complex network perspective for characterizing urban travel demand patterns: graph theoretical analysis of large-scale origin–destination demand networks…...
文件操作函数
本文是小编巩固自身而作,如有错误,欢迎指出! 1.使用文件的原因 我们编写的程序都是有生命周期的,储存在电脑的内存中,如果程序退出,内存回收,数据就会丢失,等程序再次运行…...
Java高频面试之并发编程-05
hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:线程有哪些调度方法? 在Java中,线程的调用方法主要包括以下几种方式,每种方式适用于…...
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
最大正方形边长问题详解 一、问题描述 给定一个大小为 mn 的矩阵 mat 和一个整数阈值 threshold,要求返回元素总和小于或等于阈值的正方形区域的最大边长;如果没有这样的正方形区域,则返回 0。 二、解题思路 前缀和矩阵的概念与构建 前缀…...
测试开发 - Java 自动化测试核心函数详解
目录 1. 元素定位 1.1 By.xpath 1.1.1 //* 1.1.2 //[指定节点] 1.1.3 / 1.1.4 /.. 1.1.5 [...] 1.1.6 指定索引获取对应元素 1.2 By.cssSelector 1.2.1 # 1.2.2 . 1.2.3 > 1.2.4 标签名:nth-child(n) 2. 获取元素 2.1 findElement 2.2 findElements 3. 操…...
【HarmonyOS】ArKUI框架
目录 概述 声明式开发范式 基于ArKUI的项目 • 1.创建资源文件 • 2.引用资源 • 3.引用系统资源: • 系统资源有哪些 • 4. 在配置和资源中引用资源 声明式语法 UI描述规范 UI组件概述 组件化 组件渲染控制语法 修改…...
【MQ篇】RabbitMQ之简单模式!
目录 引言一、 初识 RabbitMQ 与工作模式二、 简单模式 (Simple Queue) 详解:最直接的“点对点快递” 📮三、 Java (Spring Boot) 代码实战:让小兔子跑起来! 🐰🏃♂️四、 深入理解:简单模式的…...
K8S节点出现Evicted状态“被驱逐”
在Kubernetes集群中,Pod状态为“被驱逐(evicted)”表示Pod无法在当前节点上继续运行,已被集群从节点上移除。 问题分析: 节点磁盘空间不足 ,使用df -h查看磁盘使用情况 可以看到根目录 / 已100%满&#x…...
NumPyro:概率编程的现代Python框架深度解析
引言 概率编程作为统计学与机器学习的交叉领域,正在重塑我们构建不确定性模型的方式。在众多概率编程语言(PPL)中,NumPyro凭借其简洁的语法、强大的性能和与PyTorch生态系统的无缝集成,已经成为研究者和数据科学家的首…...
java进阶之git
git git介绍git常用命令代码回滚操作 git 介绍 工作区 改动(增删文件和内容)暂存区 输入命令:git add改动的文件名,此次改动就放到了"暂存区“本地仓库 输入命令:git commit 此次修改的描述,此次改动…...
负载阻尼效应及其作用解析
负载阻尼效应是指负载(如电路、机械系统或控制系统中连接的设备)对系统动态变化(如电压波动、机械振动等)产生的抑制或衰减作用。 其核心是通过消耗或吸收能量,减少系统中的振荡、波动或瞬态响应,从而提高…...
面向组织的网络安全措施
一、安全措施概述 在一个组织中,技术人员可以利用一系列强大的网络安全工具进行安全检测和防范,以保护组织的网络基础设施、数据和资产免受各种威胁。这些工具通常涵盖了从主动防御、威胁检测、漏洞管理到事件响应和安全分析的各个方面。 以下是一些关…...
Unity 跳转资源商店,并打开特定应用
需求: 打开资源商店,并定位到特定应用. 代码: #if UNITY_ANDROIDApplication.OpenURL("market://details?idcom.tencent.mm"); #elif UNITY_IPHONEApplication.OpenURL(“itms-apps://apps.apple.com/app/id333903271”); #end…...
2025年五大ETL数据集成工具推荐
ETL工具作为打通数据孤岛的核心引擎,直接影响着企业的决策效率与业务敏捷性。本文精选五款实战型ETL解决方案,从零门槛的国产免费工具到国际大厂企业级平台,助您找到最适合的数据集成利器。 一、谷云科技ETLCloud:国产数据集成工…...
基于 PaddleOCR对pdf文件中的文字提取
一、基于 PaddleOCR 提取 PDF 文件中的文字流程 1. 安装必要的依赖库:包括 PaddleOCR 和 PyMuPDF pip install paddlepaddle paddleocr pymupdf 2. 将 PDF 转换为图像:使用 PyMuPDF 将 PDF 的每一页转换为图像 3. 使用 PaddleOCR 进行文字识别&a…...
鸿蒙移动应用开发--渲染控制实验
任务:使用“对象数组”、“ForEach渲染”、“Badge角标组件”、“Grid布局”等相关知识,实现生效抽奖卡案例。如图1所示: 图1 生肖抽奖卡实例图 图1(a)中有6张生肖卡可以抽奖,每抽中一张,会通过弹层显示出来…...
【漫话机器学习系列】215.处理高度不平衡数据策略(Strategies For Highly Imbalanced Classes)
处理高度不平衡数据的四大策略详解 在机器学习与数据挖掘任务中,“类别不平衡”问题几乎无处不在。无论是信用卡欺诈检测、医疗异常诊断,还是网络攻击识别,正负样本的比例往往严重失衡。比如一个欺诈检测数据集中,可能只有不到 1…...
在离线 Ubuntu 环境下部署双 Neo4j 实例(Prod Dev)
在许多开发和生产场景中,我们可能需要在同一台服务器上运行多个独立的 Neo4j 数据库实例,例如一个用于生产环境 (Prod),一个用于开发测试环境 (Dev)。本文将详细介绍如何在 离线 的 Ubuntu 服务器上,使用 tar.gz 包部署两个 Neo4j…...
Windows下Golang与Nuxt项目宝塔部署指南
在Windows下将Golang后端和Nuxt前端项目打包,并使用宝塔面板部署的步骤如下 一、Golang后端打包 交叉编译为Linux可执行文件 在Windows PowerShell中执行: powershell复制下载 $env:GOOS "linux" $env:GOARCH "amd64" go build…...
基于贝叶斯优化的Transformer多输入单输出回归预测模型Bayes-Transformer【MATLAB】
Bayes-Transformer 在机器学习和深度学习领域,Transformer模型已经广泛应用于自然语言处理、图像识别、时间序列预测等多个领域。然而,在一些实际应用中,我们面临着如何高效地优化模型超参数的问题。贝叶斯优化(Bayesian Optimiz…...
ibus输入法微软词库分享
链接: https://pan.baidu.com/s/1aC-UvV-UDHEpxg5sZcAS2Q?pwddxpq 提取码: dxpq --来自百度网盘超级会员v8的分享 链接: https://pan.baidu.com/s/1aC-UvV-UDHEpxg5sZcAS2Q?pwddxpq 提取码: dxpq --来自百度网盘超级会员v8的分享 # 更改ibus输入法字体大小 sudo apt insta…...
Sharding-JDBC 系列专题 - 第五篇:分布式事务
Sharding-JDBC 系列专题 - 第五篇:分布式事务 本系列专题旨在帮助开发者全面掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第五篇文章,将深入探讨 分布式事务(Distributed Transactions),包括其概念、支持的事务类型、配置方法、工作原理以及实战…...
力扣每日打卡17 49. 字母异位词分组 (中等)
力扣 49. 字母异位词分组 中等 前言一、题目内容二、解题方法1. 哈希函数2.官方题解2.1 前言2.2 方法一:排序2.2 方法二:计数 前言 这是刷算法题的第十七天,用到的语言是JS 题目:力扣 49. 字母异位词分组 (中等) 一、题目内容 给…...
深入解析C++ STL List:双向链表的特性与高级操作
一、引言 在C STL容器家族中,list作为双向链表容器,具有独特的性能特征。本文将通过完整代码示例,深入剖析链表的核心操作,揭示其底层实现机制,并对比其他容器的适用场景。文章包含4000余字详细解析,适合需…...
在 master 分支上进行了 commit 但还没有 push,怎么安全地切到新分支并保留这些更改
确保你的 commit 确实没有 push(否则会覆盖远程分支): git log --oneline # 查看本地 commit git log --oneline origin/master # 查看远程 master 的 commit 确保你的 commit 只存在于本地,远程 origin/master 没有…...
spark jar依赖顺序
1. 执行顺序 spark-submit --config "spark.{driver/executor}.extraClassPathsomeJar"提交的依赖包SystemClasspath – Spark安装时候提供的依赖包spark-submit --jars 提交的依赖包 2. 依赖解释 提交任务时指定的依赖 Spark-submit --config "spark.{drive…...
docker 国内源和常用命令
Ubuntu | Docker Docs 参考docker官方安装docker # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt…...
【目标检测】对YOLO系列发展的简单理解
目录 1.YOLOv12.YOLOv23.YOLOv34.YOLOv45.YOLOv66.YOLOv77.YOLOv9 YOLO系列文章汇总: 【论文#目标检测】You Only Look Once: Unified, Real-Time Object Detection 【论文#目标检测】YOLO9000: Better, Faster, Stronger 【论文#目标检测】YOLOv3: An Incremental …...
C# AppContext.BaseDirectory 应用程序的启动目录
Application.StartupPath定义与用途局限性示例 Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)定义与用途局限性示例 Directory.GetCurrentDirectory()定义与用途局限性示例 关键区别总结推荐使用场景需要应用程序安装目录需要动态工作目录插件或模块化应用…...
Sentinel数据S2_SR_HARMONIZED连续云掩膜+中位数合成
在GEE中实现时,发现简单的QA60是无法去云的,最近S2地表反射率数据集又进行了更新,原有的属性集也进行了变化,现在的SR数据集名称是“S2_SR_HARMONIZED”。那么: 要想得到研究区无云的图像,可以参考执行以下…...
探索Cangjie Magic:仓颉编程语言原生的LLM Agent开发新范式
引言:智能体开发的革命性突破 2025年3月,仓颉社区开源了Cangjie Magic——这是首个基于仓颉编程语言原生构建的LLM Agent开发平台,标志着智能体开发领域的一次重大突破。作为一名长期关注AI发展的技术爱好者,我有幸第一时间体验了…...
css三大特性
css三大特性:层叠性 继承性 优先性 一.层叠性 二.继承性 子标签会继承父标签的某些样式 恰当地使用继承性,减少代码复杂性子元素会继承父元素地某些样式(text-,font-,line-这些元素开头的可以继承,以及color属性) 2…...