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

spring.expression 随笔0 概述

0. 我只是个普通码农,不值得挽留

Spring SpEL表达式的使用
常见的应用场景:分布式锁的切面借助SpEL来构建key
比较另类的的应用场景:动态校验


个人感觉可以用作控制程序的走向,除此之外,spring的一些模块的自动配置类,也会在@Conditional注解中使用SpEL来实现有条件的加载特定的bean.

1. UML

1.1 ExpressionParser

解释器设计模式的体现了
在这里插入图片描述
单纯的(非模板表达式)spel表达式将通过 SpelExpressionParser 创建 InternalSpelExpressionParser, 来实现 parseExpression() 的底层逻辑.

	// org.springframework.expression.spel.standard.InternalSpelExpressionParser#doParseExpression@Overrideprotected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context)throws ParseException {try {this.expressionString = expressionString;// 1.对相关的符号进行分词Tokenizer tokenizer = new Tokenizer(expressionString);this.tokenStream = tokenizer.process();this.tokenStreamLength = this.tokenStream.size();this.tokenStreamPointer = 0;this.constructedNodes.clear();// 2.构建 ASTSpelNodeImpl ast = eatExpression();Assert.state(ast != null, "No node");Token t = peekToken();if (t != null) {throw new SpelParseException(t.startPos, SpelMessage.MORE_INPUT, toString(nextToken()));}Assert.isTrue(this.constructedNodes.isEmpty(), "At least one node expected");// 3. 返回创建好的表达式实例return new SpelExpression(expressionString, ast, this.configuration);}catch (InternalParseException ex) {throw ex.getCause();}}

1.2 ParserContext

在这里插入图片描述

  • 这里前后缀例如:支持模板表达式的实现类TemplateParserContext使用了#{}
  • TemplateAwareExpressionParser(支持模板的ExpressionParser实现类),根据 ParserContext.isTemplate()来决定处理流程
  • 有必要给出模板表达式的定义: 可以理解为多个、多种表达式的组合
	// org.springframework.expression.common.TemplateAwareExpressionParser#parseExpression(java.lang.String, org.springframework.expression.ParserContext)@Overridepublic Expression parseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {if (context != null && context.isTemplate()) {return parseTemplate(expressionString, context);}else {return doParseExpression(expressionString, context);}}

1.3 Expression

在这里插入图片描述

转换并获取表达式对应的数值

1.4 EvaluateContext

  • 支持间接的关联 beanFactory ,来注入spring bean
  • 该功能很好的体现了 spring-expression 的独立性
  • 支持往该上下文中加入静态方法、java bean
  • 与 Expression.getValue() 有较大的关系
    在这里插入图片描述

在这里插入图片描述

2. test-classes

因为要debug beanFactory关联的 parser,便懒得构造applicationContext,直接@SpringbootTest 启动容器了

@DisplayName("Spring Expression Language")
@SpringBootTest
public class SpELTest {@Value("#{testBean.value}")String value;@AutowiredApplicationContext appCtx;SpelExpressionParser parser;StandardEvaluationContext stdEvaCtx;@PostConstructprivate void postConstruct() throws NoSuchMethodException {parser = new SpelExpressionParser();// rootObjectstdEvaCtx = new StandardEvaluationContext(new TestBean("rootValue", null));// variablestdEvaCtx.setVariable("testBean", this.appCtx.getBean("testBean"));Method parseInt = Integer.class.getDeclaredMethod("valueOf", String.class);stdEvaCtx.registerFunction("doValueOf", parseInt);stdEvaCtx.setBeanResolver(new BeanFactoryResolver(this.appCtx));}@DisplayName("注解方式")@Testvoid t0() {// 这个上下文其实就是表达式、变量的容器(缓存)System.err.println(this.value);}@DisplayName("编码方式")@Testvoid t1() {// 不需要 {}// spring security 中也使用编码的方式解析权限注解 @PrePreAuthorizeExpression expression = parser.parseExpression("#testBean.value");System.err.println(expression.getValue(this.stdEvaCtx));}@DisplayName("运算")@Nestedclass Count {@DisplayName("字面量")@Testvoid t0() {// 上下文中找不到这个变量,报错:// spel.SpelEvaluationException: EL1007E: Property or field 'test' cannot be found on null// System.err.println("找不到变量="+parser.parseExpression("test").getValue(String.class));// 字符串System.err.println("字符串1=" + parser.parseExpression("'test'").getValue(String.class));System.err.println("字符串2=" + parser.parseExpression("\"test\"").getValue(String.class));// 数字System.err.println("int=" + parser.parseExpression("1").getValue(Integer.class));System.err.println("long=" + parser.parseExpression("1L").getValue(long.class));System.err.println("float=" + parser.parseExpression("1.1").getValue(Float.class));System.err.println("double=" + parser.parseExpression("1.1E+1").getValue(double.class));System.err.println("hex=" + parser.parseExpression("0xf").getValue(int.class));// 布尔System.err.println("bool=" + parser.parseExpression("false").getValue(boolean.class));// nullSystem.err.println(parser.parseExpression("null").getValue());}@DisplayName("算数")@Testvoid t1() {System.err.println("3+2=" + parser.parseExpression("3+2").getValue(Integer.class));System.err.println("3-2=" + parser.parseExpression("3-2").getValue(Integer.class));System.err.println("3*2=" + parser.parseExpression("3*2").getValue(Integer.class));System.err.println("3/2=" + parser.parseExpression("3/2").getValue(Integer.class));System.err.println("3%2=" + parser.parseExpression("3%2").getValue(Integer.class));System.err.println("3^2=" + parser.parseExpression("3^2").getValue(Integer.class));}@DisplayName("关系运算")@Testvoid t2() {System.err.println("3==2=" + parser.parseExpression("3==2").getValue(Boolean.class));System.err.println("3 == 2=" + parser.parseExpression("3 == 2").getValue(Boolean.class));System.err.println("3 ge 2 =" + parser.parseExpression("3 ge 2").getValue(boolean.class));System.err.println("3 LT 2 = " + parser.parseExpression("3 LT 2").getValue(boolean.class));// SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'NE2'// System.err.println("3NE2 = "+parser.parseExpression("3NE2").getValue(boolean.class));// 并不能返回 int:0、1,会抛出异常System.err.println("2 between {1, 2}=" + parser.parseExpression("2 between {1, 2}").getValue(Boolean.class));// SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'le(<=)'// System.err.println("1<2<=2="+parser.parseExpression("1<2<=3").getValue(Boolean.class));}@DisplayName("逻辑运算")@Testvoid t3() {System.err.println("2>1 and false = " + parser.parseExpression("2>1 and false").getValue(boolean.class));System.err.println("2>1 && false = " + parser.parseExpression("2>1 && false").getValue(Boolean.class));// SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'factory_bean_ref(&)'// System.err.println("2>1 & false = "+parser.parseExpression("2>1 & false").getValue(Boolean.class));System.err.println("2>1 or NOT false and (! NOT false || 1==1) = " + parser.parseExpression("2>1 or NOT false and (! NOT false || 1==1)").getValue(Boolean.class));}@DisplayName("三目运算")@Testvoid t4() {System.err.println("3 > 2 ? true : false = " + parser.parseExpression("3 > 2 ? true : false").getValue(boolean.class));}@DisplayName("elivis")@Testvoid t5() {System.err.println("null ?: 'false' = " + parser.parseExpression("null ?: 'false'").getValue(Boolean.class));System.err.println("null ?: 'false' = " + parser.parseExpression("null ?: 'false'").getValue(String.class));}@DisplayName("正则")@Testvoid t6() {System.err.println("" + parser.parseExpression("'123' matches '\\d{3}'").getValue(boolean.class));System.err.println("" + parser.parseExpression("123 matches '\\d{3}'").getValue(Boolean.class));}@DisplayName("instanceof")@Testvoid t7() {System.err.println("'123' instanceof T(String) = " + parser.parseExpression("'123' instanceof T(String)").getValue(Boolean.class));System.err.println("123 instanceof T(String) = " + parser.parseExpression("123 instanceof T(java.lang.String)").getValue(Boolean.class));}}@DisplayName("类型")@Nestedclass Type {@DisplayName("class")@Testvoid t0() {// java.lang 以外的类均需要全限定名System.err.println(parser.parseExpression("T(String)").getValue(Class.class));System.err.println(parser.parseExpression("T(java.util.Map)").getValue(Class.class));// 访问 静态的属性、方法System.err.println(parser.parseExpression("T(Integer).MAX_VALUE").getValue(int.class));System.err.println(parser.parseExpression("T(Integer).parseInt(3)").getValue(Integer.class));}@DisplayName("instance")@Testvoid t1() {// java.lang 包 同理System.err.println(parser.parseExpression("new String('苹果一样的甜')").getValue(String.class));System.err.println(parser.parseExpression("new java.util.Date()").getValue(Date.class));}@DisplayName("reference")@Testvoid t2() {System.err.println("#testBean.value=" + parser.parseExpression("#testBean.value").getValue(stdEvaCtx, String.class));System.err.println("#this.value=" + parser.parseExpression("#this.value").getValue(stdEvaCtx, String.class));System.err.println("#root.value=" + parser.parseExpression("#root.value").getValue(stdEvaCtx, String.class));// rootObject缺省时,访问其属性,不能加#前缀System.err.println("(root属性可以省略#root)value=" + parser.parseExpression("value").getValue(stdEvaCtx, String.class));}@DisplayName("assign")@Testvoid t3() {System.err.println("#testBean.value=newValue --> " + parser.parseExpression("#testBean.value='newValue'").getValue(stdEvaCtx, String.class));System.err.println("#this.value=newThisValue --> " + parser.parseExpression("#this.value='newThisValue'").getValue(stdEvaCtx, String.class));System.err.println("#root.value=newRootValue --> " + parser.parseExpression("#root.value='newRootValue'").getValue(stdEvaCtx, String.class));System.err.println("value=newValue --> " + parser.parseExpression("value='newValue'").getValue(stdEvaCtx, String.class));}@DisplayName("func")@Testvoid t4() {System.err.println(parser.parseExpression("#doValueOf('20').byteValue()").getValue(stdEvaCtx, Byte.class));}@DisplayName("对象属性获取 及 安全导航")@Testvoid t5() {System.err.println(parser.parseExpression("value").getValue(stdEvaCtx, String.class));// Value 可以,Value 不得行(首字母不敏感)System.err.println(parser.parseExpression("Value").getValue(stdEvaCtx, String.class));// 支持groovy的elivis表达式// 安全导航运算符前面的#root可以省略,但后面的#root不可省略System.err.println(parser.parseExpression("#root?.#root").getValue(stdEvaCtx, TestBean.class));System.err.println(parser.parseExpression("value?.#root.value").getValue(stdEvaCtx, String.class));// SpelParseException: Expression [username?.'核弹拉链'] @8: EL1049E: Unexpected data after '.': ''核弹拉链''// SpEL引入了Groovy语言中的安全导航运算符"(对象|属性)?.属性"// 常量显然不得行// System.err.println(parser.parseExpression("username?.'核弹拉链'").getValue(stdEvaCtx, String.class));}@DisplayName("对象方法调用")@Testvoid t6() {System.err.println(parser.parseExpression("value.substring(1, 6).toUpperCase()").getValue(stdEvaCtx, String.class));System.err.println(parser.parseExpression("toString()").getValue(stdEvaCtx, String.class));}@DisplayName("bean引用(BeanFactoryResolver)")@Testvoid t7() {// @BeanName// EvaluationContext.setBeanResolver() 需要借助 beanFactorySystem.err.println(Jsons.NO_OP.stringify(parser.parseExpression("@systemProperties").getValue(stdEvaCtx, Properties.class)));System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("@testBean").getValue(stdEvaCtx, TestBean.class)));}}@DisplayName("集合")@Nestedclass Collect {@DisplayName("内联数组")@Testvoid t0() {System.err.println(Arrays.toString(parser.parseExpression("new int[2]{1, 2}").getValue(int[].class)));System.err.println(Arrays.toString(parser.parseExpression("new String[2][2]").getValue(String[][].class)));// 不支持多维数组创建同时,做初始化System.err.println(Arrays.toString(parser.parseExpression("new String[2][2]{'1','2'},{'3','4'}").getValue(String[][].class)));}@DisplayName("内联集合")@Testvoid t1() {System.err.println(parser.parseExpression("{}").getValue(List.class));// java.util.Collections$UnmodifiableRandomAccessListSystem.err.println(parser.parseExpression("{1, 2,3}").getValue(List.class).getClass().getName());// 此时的 List<List> .class = java.util.ArrayList// 存在非字面量表达式时,集合类型将转为原始类型(可修改的集合)System.err.println(parser.parseExpression("{{1+2,2+4},{3,4+4}}").getValue(List.class).getClass().getName());}@DisplayName("数组、集合、字典元素访问")@Testvoid t2() {System.err.println(parser.parseExpression("[0]").getValue(new int[]{1, 2, 3}, Integer.class));System.err.println(parser.parseExpression("{1, 2, 3}[0]").getValue(int.class));System.err.println(parser.parseExpression("[0]").getValue(Lists.newArrayList(1, 2, 3), int.class));Map<String, Integer> map = Maps.newHashMap();map.put("weng", 4);map.put("chong", 5);map.put("yu", 2);System.err.println(parser.parseExpression("['chong']").getValue(map, int.class));}// 很像 streamApi.peek().collect(toList())@DisplayName("数组、集合、字典 转换")@Testvoid t3() {// array|list|map.![表达式]System.err.println(Arrays.toString(parser.parseExpression("#root.![#this+1]").getValue(new int[]{1, 2, 3}, int[].class)));System.err.println(parser.parseExpression("#root.![#this+1]").getValue(Lists.newArrayList(1, 2, 3), List.class));Map<String, Integer> map = Maps.newHashMap();map.put("weng", 4);map.put("chong", 5);map.put("yu", 2);System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.![#this.key+1]").getValue(map, List.class)));System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.![#this.value+1]").getValue(map, List.class)));// 报错: cannot convert from java.util.ArrayList<?> to java.util.Map<?, ?>// 集合、数组之间可以随意转换// System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.![#this.value+1]").getValue(map, Map.class)));}// 相当于 streamApi.filter.collect(toList)@DisplayName("数组、集合、字典 选择")@Testvoid t4() {// array|list|map.?[表达式]System.err.println(Arrays.toString(parser.parseExpression("#root.?[#this>=2]").getValue(new int[]{1, 2, 3}, int[].class)));System.err.println(Arrays.toString(parser.parseExpression("#root.?[#this>=2]").getValue(Lists.newArrayList(1, 2, 3), int[].class)));Map<String, Integer> map = Maps.newHashMap();map.put("weng", 4);map.put("chong", 5);map.put("yu", 2);// {"weng":4,"yu":2}System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.?[#this.key!='chong']").getValue(map, Map.class)));// 这里转的集合,有些怪异// [{"weng":4,"yu":2}]System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.?[#this.key!='chong']").getValue(map, List.class)));System.err.println(Jsons.NO_OP.stringify(parser.parseExpression("#root.?[#this.value<=2]").getValue(map, Map.class)));}}
}

附上相关的类

@Component("testBean")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class TestBean {@Value("${angel.spel.key}")public String value;private String username;
}

相关文章:

spring.expression 随笔0 概述

0. 我只是个普通码农&#xff0c;不值得挽留 Spring SpEL表达式的使用 常见的应用场景:分布式锁的切面借助SpEL来构建key 比较另类的的应用场景:动态校验 个人感觉可以用作控制程序的走向&#xff0c;除此之外&#xff0c;spring的一些模块的自动配置类&#xff0c;也会在Cond…...

从Cookie到Session: Servlet API中的会话管理详解

文章目录 一. Cookie与Session1. Cookie与Session2. Servlet会话管理操作 二. 登录逻辑的实现 一. Cookie与Session 1. Cookie与Session 首先, 在学习过 HTTP 协议的基础上, 我们需要知道 Cookie 是 HTTP 请求报头中的一个关键字段, 本质上是浏览器在本地存储数据的一种机制,…...

docker数据管理与网络通信

一、管理docker容器中数据 管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes)和数据卷容器( DataVolumes Containers) 。 1、 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻…...

怎么查询电脑的登录记录及密码更改情况?

源头是办公室公用的电脑莫名其妙打不开了&#xff0c;问别人也都不知道密码是多少 因为本来就没设密码啊&#xff01;&#xff08;躺倒&#xff09; 甚至已经想好了如果是50万想攻破电脑&#xff0c;被po抓住要怎么花这笔钱了 是我想太多 当然最后也没解决&#xff0c;莫名…...

《三》TypeScript 中函数的类型

TypeScript 允许指定函数的参数和返回值的类型。 函数声明的类型定义&#xff1a;function 函数名(形参: 形参类型, 形参: 形参类型, ...): 返回值类型 {} function sum(x: number, y: number): number {return x y } sum(1, 2) // 正确 sum(1, 2, 3) // 错误。输入多余的或者…...

深入学习 Mysql 引擎 InnoDB、MyISAM

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…...

【华为OD统一考试B卷 | 100分】阿里巴巴找黄金宝箱(V)(C++ Java JavaScript Python)

题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字。 阿里巴巴念出一个咒语数字k(k<N),找出连续k个宝箱数字和的最大值,并输出该最大值。 输入描述 第一行输入一个数字字串,数字之间…...

六步快速搭建个人网站

目录 第一步、选择搭建平台WordPress 第二步、选域名 1&#xff09;域名在哪买&#xff1f; 2&#xff09;域名怎么选&#xff1f; 3&#xff09;以阿里云为例&#xff0c;讲解怎么买域名 第三步、选择服务器 第四步、申请主机、安装WordPress 第五步、选择WordPress模…...

TypeScript 中的 type 关键字有什么用?

创建类型别名 在 TypeScript 中&#xff0c;type 关键字用于创建类型别名&#xff08;Type Alias&#xff09;。类型别名可以给一个类型起一个新的名字&#xff0c;使代码更具可读性和可维护性。 类型别名可以用于定义各种类型&#xff0c;包括基本类型、复合类型和自定义类型…...

27 getcwd 的调试

前言 同样是一个 很常用的 glibc 库函数 不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 获取当前路径 不过 我们这里是从 具体的实现 来看一下 测试用例 就是简单的使用了一下 getcwd rootubuntu:~/Desktop/linux/HelloWorld# cat Test04Getcwd.c #inc…...

使用IDEA使用Git:Git使用指北——实际操作篇

Git使用指北——实际操作 &#x1f916;:使用IDEA Git插件实际工作流程 &#x1f4a1; 本文从实际使用的角度出发&#xff0c;以IDEA Git插件为基座讲述了如果使用IDEA的Git插件来解决实际开发中的协作开发问题。本文从 远程仓库中拉取项目&#xff0c;在本地分支进行开发&…...

java boot将一组yml配置信息装配在一个对象中

其实将一组yml数据封进一个对象中才是以后的主流开发方式 我们创建一个springboot项目 找到项目中的启动类所在目录 在同目录下创建一个类 名字你们可以随便取 我这里直接叫 dataManager 然后 在yml中定义这样一组数据信息 然后 我们在类中定义三个和这个配置信息相同的字段…...

【裸机开发】链接脚本(.lds文件)的基本语法

目录 一、什么是链接脚本&#xff1f; 二、链接脚本的基本语法格式 1、常用命令 2、内置变量 三、链接脚本的简单案例 一、什么是链接脚本&#xff1f; 一段程序的编译需要经历四个阶段&#xff08;预处理—编译—汇编—链接&#xff09;&#xff0c;而链接脚本管理的就是…...

Java 进阶 -- 集合(三)

4、实现 实现是用于存储集合的数据对象&#xff0c;它实现了接口部分中描述的接口。本课描述了以下类型的实现: 通用实现是最常用的实现&#xff0c;是为日常使用而设计的。它们在标题为“通用实现”的表格中进行了总结。特殊目的实现是为在特殊情况下使用而设计的&#xff0…...

【华为OD机试真题 C语言】5、TLV解析 | 机试真题+思路参考+代码解析

文章目录 一、题目&#x1f383;题目描述&#x1f383;输入输出&#x1f383;样例1 二、思路参考三、代码参考&#x1f3c6;C语言 作者&#xff1a;KJ.JK &#x1f342;个人博客首页&#xff1a; KJ.JK &#x1f342;专栏介绍&#xff1a; 华为OD机试真题汇总&#xff0c;定期…...

(七)CSharp-刘铁锰版-事件

一、初步了解事件 定义&#xff1a;单词 Event &#xff0c;译为“事件” 《牛津词典》中的解释是“a thing that happens,especially something important”通顺的解释就是“能够发生的什么事情” 角色&#xff1a; 使对象或类具备通知能力的成员 &#xff08;中译&#x…...

【ROS】郭老二博文之:ROS目录

1、ROS2 【ROS】Ubuntu22.04安装ROS2&#xff08;Humble Hawksbill&#xff09; 【ROS】ROS2命令行工具详解 【ROS】ROS2中的概念和名词解释 【ROS】ROS2编程示例&#xff1a;话题订阅-发布-C版 【ROS】ROS2编程示例&#xff1a;服务和客户端-C版 【ROS】ROS2编程示例&#xf…...

Android应用程序进程的启动过程

Android应用程序进程的启动过程 导语 到这篇文章为止&#xff0c;我们已经简要地了解过了Android系统的启动流程了&#xff0c;其中比较重要的内容有Zygote进程的启动和SystemService以及Launcher的启动&#xff0c;接下来我们将要学习的是Android应用程序的启动过程&#xff…...

【2】Midjourney注册

随着AI技术的问世&#xff0c;2023年可以说是AI爆炸性成长的一年&#xff0c;近期最广为人知的AI服务除了chatgpt外&#xff0c;就是从去年五月就已经问世的AI绘画工具mid journey了。 ▲几个AI工具也代表了人工智能的热门阶段 只要输入一段文字&#xff0c;AI就会根据语意计算…...

第六十八天学习记录:高等数学:导数(宋浩板书)

导数是微积分中的一个概念&#xff0c;描述了函数在某一个点上的变化率。具体地说&#xff0c;函数 f ( x ) f(x) f(x)在 x a xa xa处的导数为 f ′ ( a ) f(a) f′(a)&#xff0c;表示当 x x x在 a a a处发生微小的变化 Δ x \Delta x Δx时&#xff0c; f ( x ) f(x) f(x)对…...

unreal 5 实现角色拾取功能

要实现角色拾取功能&#xff0c;我们需要实现蓝图接口功能&#xff0c;蓝图接口主要提供的是蓝图和蓝图之间可以通信&#xff0c;接下来&#xff0c;跟着教程&#xff0c;实现一下角色的拾取功能。 首先&#xff0c;我们要实现一个就是可视区的物品在朝向它的时候&#xff0c;会…...

chatgpt赋能python:如何使用Python升序排列一个列表?

如何使用Python升序排列一个列表&#xff1f; 在Python编程中&#xff0c;我们经常需要对列表进行排序。列表排序是一种常见的操作&#xff0c;可以帮助我们对数据进行分析和管理。在这篇文章中&#xff0c;我们将学习如何使用Python对一个列表进行升序排列。 什么是升序排列…...

Lecture 20 Topic Modelling

目录 Topic ModellingA Brief History of Topic ModelsLDAEvaluationConclusion Topic Modelling makeingsense of text English Wikipedia: 6M articlesTwitter: 500M tweets per dayNew York Times: 15M articlesarXiv: 1M articlesWhat can we do if we want to learn somet…...

ThreadPoolExecutor线程池

文章目录 一、ThreadPool线程池状态二、ThreadPoolExecutor构造方法三、Executors3.1 固定大小线程池3.2 带缓冲线程池3.3 单线程线程池 四、ThreadPoolExecutor4.1 execute(Runnable task)方法使用4.2 submit()方法4.3 invokeAll()4.4 invokeAny()4.5 shutdown()4.6 shutdownN…...

chatgpt赋能python:Python实践:如何升级pip

Python实践&#xff1a;如何升级pip Python作为一门高效的脚本语言&#xff0c;被广泛应用于数据分析、人工智能、Web开发等领域。而pip则是Python的包管理工具&#xff0c;是开发Python应用的必备工具。但是pip在使用过程中&#xff0c;有时候会出现版本不兼容或者出现漏洞等…...

【JavaEE进阶】mybatis

目录&#xff1a; 一、Mybatis是什么 三个映射关系如下图&#xff1a; 二、mybatis的使用&#xff08;前置工作简单案例&#xff09; 第一步&#xff1a;导入MAVEN依赖 第二步&#xff1a; 在spring项目当中新建数据源 第三步&#xff1a;新建一个实体类&#xff0c;是和…...

Redis的大key

什么是 redis 的大 key redis 的大 key 不是指存储在 redis 中的某个 key 的大小超过一定的阈值&#xff0c;而是该 key 所对应的 value 过大对于 string 类型来说&#xff0c;一般情况下超过 10KB 则认为是大 key&#xff1b;对于set、zset、hash 等类型来说&#xff0c;一般…...

MMPretrain

title: mmpretrain实战 date: 2023-06-07 16:04:01 tags: [image classification,mmlab] mmpretrain实战 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccTl9bOl-1686129437336)(null)] 主要讲解了安装,还有使用教程.安装教程直接参考官网.下面讲…...

栈和队列(数据结构刷题)[一]-python

文章目录 前言一、原理介绍二、用栈实现队列1.操作2.思路 三、关于面试考察栈里面的元素在内存中是连续分布的么&#xff1f; 前言 提到栈和队列&#xff0c;大家可能对它们的了解只停留在表面&#xff0c;再深入一点&#xff0c;好像知道又好像不知道的感觉。本文我将从底层实…...

【备战秋招】JAVA集合

集合 前言 一方面&#xff0c; 面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象 的操作&#xff0c;就要 对对象进行存储。 另一方面&#xff0c;使用Array存储对象方面具有一些弊端&#xff0c;而Java 集合就像一种容器&#xff0c;可以动态地把多…...

wordpress 插件 浮动小人/企业培训机构

一&#xff1a;重启xenserver&#xff0c;待启动界面进入到boot时&#xff0c;键入menu.c32二&#xff1a;待出现以下界面是&#xff0c;在5秒内按下tab键&#xff1a;三&#xff1a;按下tab建后&#xff0c;出现启动参数&#xff0c;然后加入single参数&#xff1a;回车&#…...

泉州模板建站平台/优化网站建设

标签&#xff08;空格分隔&#xff09;&#xff1a; 三省吾身 原文地址&#xff1a;你应当怎样学习C(以及编程) 本人反思自己这些年在学校学得稀里糊涂半灌水。看到这篇文章&#xff0c;感觉收获不少。仿佛有指明自己道路的感觉&#xff0c;当然真正困难的还是坚持学习&#xf…...

北京网站建设公司网络营销外包网络建站报价/免费网站模板网

1.Redis 事务是什么 可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的&#xff0c;所有命令都会序列化&#xff0c;按顺序地串行化执行而不会被其它命令插入&#xff0c;不许加塞。 2.Redis 事务的作用 一个队列中&#xff0c;一次性、顺序性、排他性的执行…...

网站全站模板/正规seo多少钱

我想使用串行com端口进行通信&#xff0c;并且每次调用read函数调用时都想实现超时。int filedesc open("dev/ttyS0", O_RDWR );read( filedesc, buff, len );编辑&#xff1a;我正在使用Linux OS。 如何使用选择函数调用实现&#xff1f;参见linux.die.net/man/2/s…...

周村网站制作首选公司/互联网营销师证书含金量

1 简介这是我的新系列教程PythonDash快速web应用开发的第一期&#xff0c;我们都清楚学习一个新工具需要一定的动力&#xff0c;那么为什么我要专门为Dash制作一个系列教程呢&#xff1f;图1Dash是一个高效简洁的Python框架&#xff0c;建立在Flask、Poltly.js以及React.js的基…...

网站建设企业蛋糕/软文推广经典案例

git add -A和 git add . git add -ugit add . &#xff1a;监控工作区的状态树&#xff0c;运行会把工作时的所有变化提交到暂存区&#xff0c;包括文件内容修改(modified)以及新文件(new)&#xff0c;但不包括被删除的文件。git add -u &#xff1a;仅监控已经被add的文件&…...