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

Spring提供的SPEL表达式

SPEL

1. 概述

SpEL是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言,用于在运行时计算值或执行特定任务。
SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法,以及实现运算、条件判断等操作。它可以被用于XML和注解配置中,可以用于许多Spring框架中的特性,如依赖注入、AOP、配置文件等。
SpEL表达式可以在字符串中进行定义,使用特殊的语法和符号来表示特定的操作。例如,可以使用${expression}来表示一个SpEL表达式,其中expression是具体的SpEL语句。
SpEL支持各种操作和函数,包括算术运算、逻辑运算、条件判断、正则表达式匹配、集合操作等。它还支持访问上下文中的变量和参数,以及调用对象的方法

2. 基础语法学习案例


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;import java.util.*;/*** SPEL表达式案例** @author xuyuan* @see EvaluationContext* @see SimpleEvaluationContext 定制化提供特定的上下文对象,控制读写权限,可以只读如下的SimpleEvaluationContext.forReadOnlyDataBinding().build()* SimpleEvaluationContext.forReadOnlyDataBinding().build():* 适用于简单的、只读的数据绑定场景。* 性能较好,但功能有限。* 不支持复杂的表达式操作。* <p>* new StandardEvaluationContext(obj):* 适用于复杂的表达式求值场景。* 功能全面,支持所有SPEL特性。* 可以设置根对象和其他上下文信息,灵活性高。*/
public class SpelExam {/*** 操作字面量*/@Testpublic void test() {ExpressionParser parser = new SpelExpressionParser();// 获取字符串 "Hello World"String helloWorld = parser.parseExpression("'Hello World'").getValue(String.class);System.out.println(helloWorld);// double类型 6.0221415E23double avogadrosNumber = parser.parseExpression("6.0221415E+23").getValue(Double.class);System.out.println(avogadrosNumber);// int类型 2147483647int maxValue = parser.parseExpression("0x7FFFFFFF").getValue(Integer.class);System.out.println(maxValue);// trueboolean trueValue = parser.parseExpression("true").getValue(Boolean.class);System.out.println(trueValue);// nullObject nullValue = parser.parseExpression("null").getValue();System.out.println(nullValue);}/*** 操作对象*/@Testpublic void test2() {// 定义Parser,可以定义全局的parserExpressionParser parser = new SpelExpressionParser();// 注意!属性名的第一个字母不区分大小写。 birthdate.year等效于Birthdate.Year// 取出Inventor 中,birthdate属性的year属性Inventor zhangsan = new Inventor("zhangsan", new Date(), "China");// 定义StandardEvaluationContext ,传入一个操作对象StandardEvaluationContext zhangsanContext = new StandardEvaluationContext(zhangsan);int year = parser.parseExpression("birthdate.year + 1900").getValue(zhangsanContext, Integer.class);System.out.println(year); // 2025// 取出Inventor的placeOfBirth的city属性PlaceOfBirth placeOfBirth = new PlaceOfBirth("长沙", "中国");zhangsan.setPlaceOfBirth(placeOfBirth);String city = parser.parseExpression("placeOfBirth.City").getValue(zhangsanContext, String.class);System.out.println(city); // 长沙}/*** 操作数组和List*/@Testpublic void test3() {// 定义Parser,可以定义全局的parserExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();// 省略数据初始化Society ieee = new Society();Inventor tesla = new Inventor("Tesla", "USA");ieee.getMembers().add(tesla);ieee.getMembers().add(new Inventor("BYD", "CN"));ieee.getMembers().add(new Inventor("BMW", "GE"));ieee.getMembers().add(new Inventor("FLL", "FR"));tesla.setInventions(new String[]{"Lightning", "Telephone", "Computer", "Electricity", "Electric Motor", "Electric Engine", "Electric Car"});String value = parser.parseExpression("inventions[3]").getValue(context, tesla, String.class);System.out.println("取出tesla对象的inventions 第四个数据:" + value);String name = parser.parseExpression("Members[0].Name").getValue(context, ieee, String.class);System.out.println("取出ieee对象的第一个Member的name属性:" + name);String invention = parser.parseExpression("Members[0].Inventions[6]").getValue(context, ieee, String.class);System.out.println("取出ieee对象的第一个Member的第七个Inventions:" + invention);}/*** 操作Map*/@Testpublic void test4() {ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();Society ieee = new Society();ieee.getOfficers().put("president", new Inventor("Tesla", "USA"));ieee.getOfficers().put("advisors", new Inventor("BYD", "CN"));ieee.getOfficers().put("secretary", new Inventor("BMW", "GE"));ieee.getOfficers().put("treasurer", new Inventor("FLL", "FR"));String name = parser.parseExpression("officers['advisors'].name").getValue(context, ieee, String.class);System.out.println("取出ieee对象的advisors的name属性:" + name);}/*** 内嵌List/Map*/@Testpublic void test5() {// 定义Parser,可以定义全局的parserExpressionParser parser = new SpelExpressionParser();// [1, 2, 3, 4]List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue();System.out.println(numbers);// 嵌套: [[a, b], [x, y]]List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue();System.out.println(listOfLists);// {name=Nikola, dob=10-July-1856}Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue();System.out.println(inventorInfo);// 嵌套:{name={first=Nikola, last=Tesla}, dob={day=10, month=July, year=1856}}Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue();System.out.println(mapOfMaps);// List与Map可以嵌套使用,互相结合。// 嵌套:[{name={first=Nikola, last=Tesla}}, {dob={day=10, month=July, year=1856}}]List listOfMaps = (List) parser.parseExpression("{{name:{first:'Nikola',last:'Tesla'}},{dob:{day:10,month:'July',year:1856}}}").getValue();System.out.println(listOfMaps);}/*** 构建数组*/@Testpublic void test6() {ExpressionParser parser = new SpelExpressionParser();int[] numbers1 = parser.parseExpression("new int[4]").getValue(int[].class);// 数组并初始化int[] numbers2 = parser.parseExpression("new int[]{1,2,3}").getValue(int[].class);// 多维数组int[][] numbers3 = parser.parseExpression("new int[4][5]").getValue(int[][].class);}/*** 调用方法*/@Testpublic void test7() {ExpressionParser parser = new SpelExpressionParser();// 调用substring方法System.out.println(parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class));// 调用societyContext中对象的isMember方法,并传值。StandardEvaluationContext societyContext = new StandardEvaluationContext(new Society());boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class);}/*** 关系运算* 每个符号操作符也可以被指定为纯字母的等价物。这避免了所使用的符号对于嵌入表达式的文档类型具有特殊含义的问题(例如在XML文档中)。所有文本操作符都不区分大小写。对应的文本是:* lt (<)* gt (>)* le (<=)* ge (>=)* eq (==)* ne (!=)* div (/)* mod (%)* not (!)*/@Testpublic void test8() {ExpressionParser parser = new SpelExpressionParser();boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);boolean trueValue1 = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);}/*** instanceof 和 正则表达式的匹配操作符* 使用基本类型时要小心,因为它们会立即被装箱为包装器类型,所以1 instanceof T(int)会计算为false,而1 instanceof T(Integer)会计算为true。*/@Testpublic void test9() {ExpressionParser parser = new SpelExpressionParser();boolean value = parser.parseExpression("'xyz' instanceof T(Integer)").getValue(Boolean.class);boolean trueValue = parser.parseExpression("'5.00' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);boolean falseValue = parser.parseExpression("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'").getValue(Boolean.class);}/*** 逻辑运算符:and, or, not*/@Testpublic void test10() {ExpressionParser parser = new SpelExpressionParser();StandardEvaluationContext societyContext = new StandardEvaluationContext(new Society());boolean value = parser.parseExpression("true and false").getValue(Boolean.class);String expression1 = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";boolean value1 = parser.parseExpression(expression1).getValue(societyContext, Boolean.class);boolean value2 = parser.parseExpression("true or false").getValue(Boolean.class);String expression2 = "isMember('Nikola Tesla') or isMember('Albert Einstein')";boolean valu3 = parser.parseExpression(expression2).getValue(societyContext, Boolean.class);boolean value4 = parser.parseExpression("!true").getValue(Boolean.class);String expression3 = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";boolean value5 = parser.parseExpression(expression3).getValue(societyContext, Boolean.class);}/*** 数学计算符*/@Testpublic void test11() {ExpressionParser parser = new SpelExpressionParser();parser.parseExpression("1 + 1").getValue(Integer.class);  // 2parser.parseExpression("'test' + ' ' + 'string'").getValue(String.class);  // 'test string'parser.parseExpression("1 - -3").getValue(Integer.class);  // 4parser.parseExpression("1000.00 - 1e4").getValue(Double.class);  // -9000parser.parseExpression("-2 * -3").getValue(Integer.class);  // 6parser.parseExpression("6 / -3").getValue(Integer.class);  // -2parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class);  // 1.0parser.parseExpression("7 % 4").getValue(Integer.class);  // 3parser.parseExpression("8 / 5 % 2").getValue(Integer.class);  // 1parser.parseExpression("1+2-3*8").getValue(Integer.class);  // -21}/*** 类型获取符:T()* T(Type):用于引用静态类型。* T(Type).staticMethod():用于调用静态方法。* T(Type).STATIC_FIELD:用于访问静态字段。* instanceof T(Type):用于类型检查。*/@Testpublic void test12() {ExpressionParser parser = new SpelExpressionParser();Class dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class);Class stringClass = parser.parseExpression("T(String)").getValue(Class.class);boolean trueValue = parser.parseExpression("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR").getValue(Boolean.class);}/*** 调用构造函数*/@Testpublic void test13() {System.out.println(Inventor.class.getName());ExpressionParser parser = new SpelExpressionParser();StandardEvaluationContext societyContext = new StandardEvaluationContext(new Society());Inventor einstein = parser.parseExpression("new com.xuyuan.spring.spel.SpelExam.Inventor('Albert Einstein', 'German')").getValue(Inventor.class);// 创建一个新的Inventor,并且添加到members的list中parser.parseExpression("Members.add(com.xuyuan.spring.spel.SpelExam.Inventor('Albert Einstein', 'German'))").getValue(societyContext);System.out.println(societyContext.getRootObject().getValue());}/*** Spel变量* #variableName语法在表达式中引用变量*/@Testpublic void test14() {ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();context.setVariable("newName", "Mike Tesla"); // 设置变量Inventor tesla = new Inventor("Nikola Tesla", "Serbian");// 获取变量newName,并将其赋值给name属性parser.parseExpression("Name = #newName").getValue(context, tesla);System.out.println(tesla.getName());  // "Mike Tesla"}/*** #this变量引用当前的评估对象(根据该评估对象解析非限定引用)。* #root变量总是被定义并引用根上下文对象。虽然#this可能会随着表达式的组成部分的计算而变化,但是#root总是指根。*/@Testpublic void test15() {// 创建一个Integer数组List<Integer> primes = new ArrayList<Integer>();primes.addAll(Arrays.asList(2, 3, 5, 7, 11, 13, 17));ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();context.setVariable("primes", primes);List<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression("#primes.?[#this>10]").getValue(context);System.out.println(primesGreaterThanTen);}/*** 三元表达式*/@Testpublic void test16() {ExpressionParser parser = new SpelExpressionParser();String expression = "10 > 5 ? 'ten is greater than five' : 'ten is not greater than five'";parser.parseExpression(expression).getValue(String.class);}/*** Elvis操作符*/@Testpublic void test17() {ExpressionParser parser = new SpelExpressionParser();String name = "Elvis Presley";String displayName = (name != null ? name : "Unknown");String name1 = parser.parseExpression("name?:'Unknown'").getValue(String.class);System.out.println(name1);  // 'Unknown'}/*** 安全导航运算符:obj?.prop* 安全导航操作符用于避免NullPointerException,来自Groovy语言。* 通常,当引用一个对象时,可能需要在访问该对象的方法或属性之前验证它不为null。为了避免这种情况,安全导航运算符返回null,而不是引发异常。以下示例显示了如何使用安全导航运算符*/@Testpublic void test18() {ExpressionParser parser = new SpelExpressionParser();EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();Inventor tesla = new Inventor("Nikola Tesla", "Serbian");tesla.setPlaceOfBirth(new PlaceOfBirth("Smiljan", "Croatia"));String city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class);System.out.println(city);  // Smiljantesla.setPlaceOfBirth(null);city = parser.parseExpression("PlaceOfBirth?.City").getValue(context, tesla, String.class);System.out.println(city);  // null - does not throw NullPointerException!!!}/*** 集合选择:?[predicate]*/@Testpublic void test19() {Society ieee = new Society();ieee.getMembers().add(new Inventor("Tesla", "USA"));ieee.getMembers().add(new Inventor("BYD", "CN"));ieee.getMembers().add(new Inventor("BMW", "GE"));ieee.getMembers().add(new Inventor("FLL", "FR"));ExpressionParser parser = new SpelExpressionParser();StandardEvaluationContext context = new StandardEvaluationContext(ieee);// 语法.?[selectionExpression]List<Inventor> list = parser.parseExpression("Members.?[Nationality == 'Serbian']").getValue(context, List.class);Map<String, Integer> map = new HashMap<>();context.setVariable("map", map);map.put("Tesla0", 28);map.put("Tesla1", 26);map.put("Tesla2", 25);// 返回value小于27的值// 使用参数化的 Map 类型Map<String, Integer> newMap = parser.parseExpression("#map.?[value < 27]").getValue(context, Map.class);System.out.println(newMap);  // 输出符合条件的键值对}/*** 集合投影:![expression]*/@Testpublic void test20() {Society ieee = new Society();ieee.getMembers().add(new Inventor("Tesla", "USA"));ieee.getMembers().add(new Inventor("BYD", "CN"));ieee.getMembers().add(new Inventor("BMW", "GE"));ieee.getMembers().add(new Inventor("FLL", "FR"));ExpressionParser parser = new SpelExpressionParser();StandardEvaluationContext context = new StandardEvaluationContext(ieee);List placesOfBirth = parser.parseExpression("Members.![placeOfBirth?.city]").getValue(context, List.class);}/*** 表达式模板:#{expression}* 通常使用#{}作为模板,与字符串拼接*/@Testpublic void test21() {ExpressionParser parser = new SpelExpressionParser();// 通常使用#{}作为模板,与字符串拼接起来String randomPhrase = parser.parseExpression("random number is #{T(java.lang.Math).random()}", new TemplateParserContext()).getValue(String.class);System.out.println(randomPhrase); // "random number is 0.7038186818312008"}@Data@AllArgsConstructor@NoArgsConstructorclass PlaceOfBirth {private String city;private String country;}@Data@AllArgsConstructor@NoArgsConstructorclass Society {private String name;public String Advisors = "advisors";public String President = "president";private List<Inventor> members = new ArrayList<>();private Map officers = new HashMap();public boolean isMember(String name) {for (Inventor inventor : members) {if (inventor.getName().equals(name)) {return true;}}return false;}}@Data@NoArgsConstructor@AllArgsConstructorclass Inventor {private String name;private String nationality;private String[] inventions;private Date birthdate;private PlaceOfBirth placeOfBirth;public Inventor(String name, String nationality) {GregorianCalendar c = new GregorianCalendar();this.name = name;this.nationality = nationality;this.birthdate = c.getTime();}public Inventor(String name, Date birthdate, String nationality) {this.name = name;this.nationality = nationality;this.birthdate = birthdate;}}}

相关文章:

Spring提供的SPEL表达式

SPEL 1. 概述 SpEL是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言&#xff0c;用于在运行时计算值或执行特定任务。 SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法&#xff0c;以及实现运算、条件判断等操作。它可以…...

Pytorch xpu环境配置 Pytorch使用Intel集成显卡

1、硬件集显要为Intel ARC并安装正确驱动 2、安装Intel oneAPI Base Toolkit &#xff08;https://www.intel.cn/content/www/cn/zh/developer/tools/oneapi/base-toolkit-download.html&#xff09;安装后大约20G左右&#xff0c;注意安装路径 3、安装Visual Studio Build To…...

uploadlabs通关思路

目录 靶场准备 复现 pass-01 代码审计 执行逻辑 文件上传 方法一&#xff1a;直接修改或删除js脚本 方法二&#xff1a;修改文件后缀 pass-02 代码审计 文件上传 1. 思路 2. 实操 pass-03 代码审计 过程&#xff1a; 文件上传 pass-04 代码审计 文件上传 p…...

优选算法的智慧之光:滑动窗口专题(二)

专栏&#xff1a;算法的魔法世界​​​​​​ 个人主页&#xff1a;手握风云 目录 一、例题讲解 1.1. 最大连续1的个数 III 1.2. 找到字符串中所有字母异位词 1.3. 串联所有单词的子串 1.4. 最小覆盖子串 一、例题讲解 1.1. 最大连续1的个数 III 题目要求是二进制数组&am…...

【蓝桥杯单片机】第十二届省赛

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 由Y5C控制 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器…...

剑指 Offer II 047. 二叉树剪枝

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20047.%20%E4%BA%8C%E5%8F%89%E6%A0%91%E5%89%AA%E6%9E%9D/README.md 剑指 Offer II 047. 二叉树剪枝 题目描述 给定一个二叉树 根节点 root &#xff0c;树的每…...

【自学笔记】OpenStack基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 OpenStack基础知识点总览一、OpenStack概述1.1 OpenStack起源1.2 OpenStack的目标与优势1.3 OpenStack的常见核心项目 二、OpenStack的节点类型2.1 控制节点2.2 网络…...

第5章:vuex

第5章&#xff1a;vuex 1 求和案例 纯vue版2 vuex工作原理图3 vuex案例3.1 搭建vuex环境错误写法正确写法 3.2 求和案例vuex版细节分析源代码 4 getters配置项4.1 细节4.2 源代码 5 mapState与mapGetters5.1 总结5.2 细节分析5.3 源代码 6 mapActions与mapMutations6.1 总结6.2…...

视觉在协作机器人上的场景应用

看了UR、ABB等协作机器人公司的一些视觉方面的应用&#xff0c;总结大概有下面几个方面。 1.工业制造领域 3C 产品生产 外观检测&#xff1a;可精确检测电子元件的划痕、污渍、凹陷等外观缺陷&#xff0c;如手机屏幕的微小划痕、芯片表面的瑕疵等&#xff0c;确保产品高质量&a…...

C#数据类型及相互转换

C#数据类型及相互转换 一、C#常用的基础数值类型二、C#常用的引用类型三、数据类型转换之拆箱装箱四、常量变量定义及使用规范五、C#运算符六、字符串拼接及格式化方法六、数值类型1. 自动转换2. 强制转换3. 字符串与数值类型的相互转换七、Nuget安装及西门子PLC通信1. Nuget安…...

Vue进阶之Vue3源码解析(二)

Vue3源码解析 运行runtime-coresrc/createApp.tssrc/vnode.ts.tssrc/renderer.ts runtime-domsrc/index.ts 总结 运行 runtime-core src/createApp.ts vue的创建入口 import { createVNode } from "./vnode";export function createAppAPI(render) {return funct…...

MyBatis-Plus开发流程:Spring Boot + MyBatis-Plus 实现对 book_tab 表的增删改查及Redis缓存

前言 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;旨在简化开发、减少工作量。本文将介绍如何使用 Spring Boot 集成 MyBatis-Plus 来操作数据库&#xff0c;并结合 Redis 实现数据的缓存功能。 1项目搭建 1.1 创建 Spring Boot 项目 可以通过 Spring Initializr 快…...

mpi 和nccl 之间是什么关系 (来自deepseek)

MPI&#xff08;Message Passing Interface&#xff09;和 NCCL&#xff08;NVIDIA Collective Communications Library&#xff09;都是用于并行计算和分布式计算的通信库&#xff0c;但它们的应用场景和设计目标有所不同。 MPI 设计目标&#xff1a;MPI 是一个通用的消息传递…...

从开源大模型工具Ollama存在安全隐患思考企业级大模型应用如何严守安全红线

近日&#xff0c;国家网络安全通报中心通报大模型工具Ollama默认配置存在未授权访问与模型窃取等安全隐患&#xff0c;引发了广泛关注。Ollama作为一款开源的大模型管理工具&#xff0c;在为用户提供便捷的同时&#xff0c;却因缺乏有效的安全管控机制&#xff0c;存在数据泄露…...

通过Docker搭个游戏——疯狂大陆(Pkland)

最近在研究我的服务器&#xff0c;在服务器上搭了很多docker的项目&#xff0c;然后找着找着发现一个能用Docker配置环境的游戏叫Pkland。 项目地址&#xff1a;GitHub - popkarthb/pkland: 疯狂大陆是一款多人在线的战略游戏。 游戏操作简捷,您仅需要使用浏览器就可以在任何时…...

hive之LEAD 函数详解

1. 函数概述 LEAD 是 Hive 中的窗口函数&#xff0c;用于获取当前行之后指定偏移量处的行的值。常用于分析时间序列数据、计算相邻记录的差异或预测趋势。 2. 语法 LEAD(column, offset, default) OVER ([PARTITION BY partition_column] [ORDER BY order_column [ASC|DESC]…...

springboot429-基于springboot的教务管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…...

深入理解指针与回调函数:从基础到实践

引言 在C语言中&#xff0c;指针和回调函数是两个非常重要的概念。指针为我们提供了直接操作内存的能力&#xff0c;而回调函数则为我们提供了一种灵活的编程方式&#xff0c;使得我们可以将函数作为参数传递给其他函数&#xff0c;从而实现更加模块化和可复用的代码。本文将深…...

linux磁盘非lvm分区

linux磁盘非lvm分区 类似于windows划分C盘、D盘&#xff0c;并且不需要多个磁盘空间合一 图形化直接分区 通过gparted 这个提供直观的图形化分区&#xff0c;类似windows的磁盘管理工具 下载方式&#xff1a; 乌班图/debian系列&#xff1a; sudo apt install gparted红帽…...

Linux:文件描述符与重定向

目录 一、文件描述符 1.文件内核对象 2.文件描述符分配原则 二、文件重定向 1.重定向的现象 输出重定向 输入重定向 dup2 2.重定向的使用 三、标准输出和标准错误 继上篇文章中&#xff0c;我们了解了fd打印的值为文件描述符&#xff0c;那么它还有什么作用呢&…...

【原创】C# HttpClient 读取流数据的问题

默认情况下HttpClient中有缓存&#xff0c;在读取流数据的时候&#xff0c;往往要等一小会儿&#xff0c;然后读出一大堆。 我们在请求OpenAI类的大模型的时候&#xff0c;往往要一边读取一边显示&#xff08;输出&#xff09;&#xff0c;这时候需要禁止HttpClient 中内置的缓…...

C# 开发工具Visual Studio下载和安装

开发环境与工具 C#的主要开发环境是Visual Studio&#xff0c;这是一个功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;集成了代码编辑、调试、项目管理、版本控制等功能。此外&#xff0c;Visual Studio Code也是一个轻量级的跨平台代码编辑器&#xff0c;支…...

3-7 WPS JS宏 工作表移动复制实例-2(多工作簿的多工作表合并)学习笔记

************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...

Python在机器学习与数据分析领域的深度应用:从基础到实战

在当今数字化时代&#xff0c;数据如同宝贵的矿产资源&#xff0c;蕴含着无尽的价值等待挖掘。Python作为一门强大而灵活的编程语言&#xff0c;凭借其丰富的库和工具&#xff0c;在机器学习和数据分析领域扮演着举足轻重的角色。它不仅为数据科学家和开发者提供了高效处理和分…...

网络安全ctf试题 ctf网络安全大赛真题

MISC 1 签到 难度 签到 复制给出的flag输入即可 2 range_download 难度 中等 flag{6095B134-5437-4B21-BE52-EDC46A276297} 0x01 分析dns流量&#xff0c;发现dns && ip.addr1.1.1.1存在dns隧道数据&#xff0c;整理后得到base64: cGFzc3dvcmQ6IG5zc195eWRzIQ 解…...

分布式和微服务的理解

分布式系统和微服务是现代化软件架构中两个关键概念&#xff0c;它们共同支撑了高可用、高扩展的互联网应用&#xff0c;但侧重点和解决的问题有所不同。以下是它们的核心理解&#xff1a; ​一、分布式系统&#xff08;Distributed System&#xff09;​ 定义&#xff1a; 分…...

Embedding技术:DeepWalkNode2vec

引言 在推荐系统中&#xff0c;Graph Embedding技术已经成为一种强大的工具&#xff0c;用于捕捉用户和物品之间的复杂关系。本文将介绍Graph Embedding的基本概念、原理及其在推荐系统中的应用。 什么是Graph Embedding&#xff1f; Graph Embedding是一种将图中的节点映射…...

基于IMM算法的目标跟踪,四模型IMM|三维环境|4个模型分别是:CV、左转CT、右转CT、CA(基于EKF,订阅专栏后可获得完整源代码)

这段MATLAB代码实现了基于交互多模型(IMM)算法的目标跟踪,结合了四种运动模型(匀速直线、左转圆周、右转圆周和匀加速直线)。通过定义状态方程、生成带噪声的测量数据,以及执行IMM迭代,该代码有效地实现了多模型的状态估计和融合。最终,用户可以通过可视化结果观察目标…...

大模型工程师日记(十三):检索增强生成(RAG)

Document loaders和Text splitters Document loaders(文档加载器) Document loaders(文档加载器) 这些类加载文档对象。LangChain与各种数据源有数百个集成&#xff0c;可以从中加载数据&#xff1a;Slack、Notion、Google Drive等。 每个文档加载器都有自己特定的参数&#…...

HOW - React 如何在在浏览器绘制之前同步执行 - useLayoutEffect

目录 useEffect vs useLayoutEffectuseEffectuseLayoutEffect主要区别总结选择建议注意事项 useLayoutEffect 使用示例测量 DOM 元素的尺寸和位置示例&#xff1a;自适应弹出框定位 同步更新样式以避免闪烁示例&#xff1a;根据内容动态调整容器高度 图像或 Canvas 绘制前的准备…...