【Java万花筒】Java脚本之舞:发现动态脚本的神奇力量

脚本大联合:Java生态中的动态脚本执行库详解

前言

在现代软件开发中,动态脚本的使用越来越受到重视。本文将深入探讨Java生态中几个重要的动态脚本执行库,包括Apache Groovy、ScriptEngine API、Nashorn、Kotlin Scripting和JRuby。通过对每个库的概述、特性以及与Java的集成方式进行详细分析,读者将深入了解如何在Java应用中灵活运用动态脚本,为软件开发带来更大的灵活性和表达力。

欢迎订阅专栏:Java万花筒

文章目录

  • 脚本大联合:Java生态中的动态脚本执行库详解
    • 前言
    • 1. Apache Groovy
      • 1.1 概述
      • 1.2 特性
      • 1.3 与Java的集成
      • 1.4 Groovy的领域特定语言(DSL)应用
      • 1.5 Groovy的运算符重载
      • 1.6 Groovy AST转换
      • 1.7 Groovy的多方法(Multi-Methods)
      • 1.8 Groovy的元编程:在运行时操纵类和对象
      • 1.9 Groovy与数据库交互
      • 1.10 Groovy的JSON处理
    • 2. ScriptEngine API
      • 2.1 简介
      • 2.2 在Java应用中的使用
      • 2.3 使用ScriptEngine API执行Python脚本
      • 2.4 ScriptEngine API与Java的互操作性
      • 2.5 使用ScriptEngine API进行动态脚本求值
    • 3. Nashorn (Java 8引入的JavaScript引擎)
      • 3.1 背景
      • 3.2 Nashorn的ECMAScript 6支持
      • 3.3 使用Nashorn调用Java方法
      • 3.4 在Java中使用Nashorn模板字符串
      • 3.5 Nashorn中的Java类互操作
      • 3.6 Nashorn中的脚本缓存
    • 4. Kotlin Scripting
      • 4.1 Kotlin脚本语言概述
      • 4.2 与Java互操作性
      • 4.3 Kotlin脚本中的DSL支持
      • 4.4 Kotlin脚本中的运算符重载
      • 4.5 Kotlin脚本中的DSL应用:Gradle脚本
      • 4.6 Kotlin脚本中的扩展函数
    • 5. JRuby
      • 5.1 Ruby语言在Java平台上的实现
      • 5.2 与Java的深度集成
      • 5.3 JRuby中的Ruby与Java互操作性
      • 5.4 使用JRuby编写Java Swing应用
      • 5.5 JRuby中的Ruby Gems和Java库整合
      • 5.6 JRuby中的并发编程
    • 总结

1. Apache Groovy

1.1 概述

Apache Groovy是一种基于Java平台的动态脚本语言,它允许在运行时执行代码。Groovy具有简洁的语法和强大的动态特性,使得它在脚本编写和扩展现有Java代码方面非常有用。

1.2 特性

  • 动态类型系统: Groovy使用动态类型系统,允许在运行时更改变量类型。
  • 闭包和元编程: 支持闭包,使代码更灵活。同时,它具有强大的元编程能力,可以在运行时操纵类和对象。
  • DSL支持: Groovy支持领域特定语言(DSL),使得定义特定领域的语言更加容易。

1.3 与Java的集成

Groovy可以与Java代码混合使用,直接调用Java类和方法。以下是一个简单的示例:

// Groovy脚本中调用Java类
class Greeter {def greet(name) {"Hello, $name!"}
}def greeter = new Greeter()
println greeter.greet("John")// Java代码中调用Groovy脚本
ScriptEngine engine = new ScriptEngineManager().getEngineByName("groovy");
engine.eval("println 'Hello from Groovy!'");

1.4 Groovy的领域特定语言(DSL)应用

Groovy在领域特定语言(DSL)的支持上表现出色。DSL允许开发者以一种领域相关的语言编写代码,使得代码更加贴近问题领域,提高可读性。以下是一个简单的DSL示例,模拟配置文件的定义:

// 使用DSL定义配置文件
config {server {host = "localhost"port = 8080}database {url = "jdbc:mysql://localhost:3306/mydatabase"username = "user"password = "password"}
}

上述DSL代码定义了一个简单的配置文件结构,通过Groovy的DSL支持,使得配置信息更加清晰和易于理解。

1.5 Groovy的运算符重载

Groovy允许对运算符进行重载,以便于在特定场景下定义自定义的行为。以下是一个运算符重载的示例:

// 运算符重载示例
class Point {int x, yPoint plus(Point other) {new Point(x + other.x, y + other.y)}
}def point1 = new Point(x: 1, y: 2)
def point2 = new Point(x: 3, y: 4)
def result = point1 + point2println "Result: (${result.x}, ${result.y})"

在上述例子中,通过对plus方法的重载,实现了+运算符的自定义行为,使得点的相加操作更加直观。

1.6 Groovy AST转换

Abstract Syntax Tree(AST)转换是Groovy中强大的元编程特性之一。通过AST转换,开发者可以在编译阶段对代码进行修改。以下是一个简单的AST转换示例:

// AST转换示例
class LoggingMethodCallTransformation {@groovy.transform.CompileStaticdef beforeCall() {println "Before method call"}
}// 在方法调用前插入日志
@LoggingMethodCallTransformation
def exampleMethod() {println "Inside exampleMethod"
}// 调用带有AST转换的方法
exampleMethod()

在上述例子中,通过AST转换,成功在exampleMethod方法调用前插入了日志输出。

1.7 Groovy的多方法(Multi-Methods)

Groovy支持多方法,即相同方法名但参数类型或个数不同的方法可以共存。这使得在同一类中根据参数的不同选择合适的方法变得更加灵活。以下是一个多方法的示例:

// 多方法示例
class MathOperations {def multiply(int a, int b) {a * b}def multiply(double a, double b) {a * b}
}def mathOps = new MathOperations()
println mathOps.multiply(2, 3)
println mathOps.multiply(2.5, 3.5)

在上述例子中,multiply方法通过参数的不同类型进行了重载,实现了整数和浮点数的乘法运算。

1.8 Groovy的元编程:在运行时操纵类和对象

Groovy的元编程特性允许在运行时操纵类和对象的结构。以下是一个简单的元编程示例,动态地在类中添加新的方法:

// 元编程示例:在运行时添加新方法
class DynamicMethodsExample {def greet() {"Hello, Dynamic Methods!"}
}def dynamicInstance = new DynamicMethodsExample()// 动态添加新方法
DynamicMethodsExample.metaClass.newMethod = {"This is a dynamically added method."
}// 调用动态添加的方法
println dynamicInstance.newMethod()

上述例子中,通过metaClass对象,成功在运行时动态地为类添加了一个新的方法。

1.9 Groovy与数据库交互

Groovy提供了方便的数据库交互能力,通过内置的Sql类可以轻松进行数据库操作。以下是一个简单的数据库查询示例:

// Groovy与数据库交互示例
@Grab('com.h2database:h2:1.4.200')
import groovy.sql.Sql// 连接到H2数据库
def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")// 创建表并插入数据
sql.execute("create table users(id int primary key, name varchar(255))")
sql.execute("insert into users values(1, 'John')")
sql.execute("insert into users values(2, 'Jane')")// 查询数据
def result = sql.rows("select * from users")
println result

在上述例子中,通过Groovy的Sql类,成功连接到H2数据库,并执行了表的创建、数据插入和查询操作。

1.10 Groovy的JSON处理

Groovy对JSON的处理非常方便,通过内置的JsonSlurperJsonBuilder类,可以轻松地解析和生成JSON数据。以下是一个简单的JSON处理示例:

// Groovy的JSON处理示例
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder// 解析JSON字符串
def jsonText = '{"name": "John", "age": 30, "city": "New York"}'
def jsonSlurper = new JsonSlurper()
def jsonData = jsonSlurper.parseText(jsonText)println "Name: ${jsonData.name}, Age: ${jsonData.age}, City: ${jsonData.city}"// 生成JSON字符串
def jsonBuilder = new JsonBuilder()
def jsonOutput = jsonBuilder {name "Jane"age 25city "San Francisco"
}println jsonOutput.toString()

在上述例子中,通过JsonSlurper解析了一个JSON字符串,并使用JsonBuilder生成了新的JSON数据。

2. ScriptEngine API

2.1 简介

ScriptEngine API是Java中用于与各种脚本引擎交互的标准API。它允许Java应用程序在运行时执行各种脚本语言,如JavaScript、Python等。

2.2 在Java应用中的使用

以下是一个使用ScriptEngine执行JavaScript脚本的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class ScriptEngineExample {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("JavaScript");// 执行JavaScript脚本engine.eval("print('Hello from JavaScript!')");}
}

2.3 使用ScriptEngine API执行Python脚本

除了JavaScript,ScriptEngine API还支持执行其他脚本语言,例如Python。以下是一个使用ScriptEngine执行Python脚本的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class PythonScriptExample {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("python");// 执行Python脚本engine.eval("print('Hello from Python!')");}
}

上述示例中,通过更改脚本引擎的名称为"python",成功执行了一个简单的Python脚本。

2.4 ScriptEngine API与Java的互操作性

ScriptEngine API提供了良好的Java与脚本语言的互操作性。在脚本中直接调用Java类和方法是非常常见的使用场景。以下是一个展示Java与JavaScript互操作性的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class JavaScriptInteropExample {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("JavaScript");// 在JavaScript中调用Java类和方法engine.eval("var ArrayList = Java.type('java.util.ArrayList');" +"var list = new ArrayList();" +"list.add('Java');" +"list.add('JavaScript');" +"print(list);");}
}

上述例子中,通过在JavaScript中使用Java.type调用了Java的ArrayList类,并成功在JavaScript中创建了一个ArrayList对象并添加了元素。

2.5 使用ScriptEngine API进行动态脚本求值

ScriptEngine API提供了一个方便的方法来在运行时执行动态脚本。以下是一个动态脚本求值的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class DynamicScriptEvaluationExample {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("JavaScript");// 动态脚本求值String expression = "2 * 3 + Math.sqrt(16)";Object result = engine.eval(expression);System.out.println("Result: " + result);}
}

在上述例子中,通过engine.eval方法,成功对一个包含数学表达式的动态脚本进行求值,并输出了结果。

3. Nashorn (Java 8引入的JavaScript引擎)

3.1 背景

Nashorn是Java 8引入的新一代JavaScript引擎,用于替代先前的Rhino引擎。它提供更好的性能和支持现代JavaScript语法。

3.2 Nashorn的ECMAScript 6支持

Nashorn作为Java 8引入的JavaScript引擎,不仅带来了性能提升,还支持现代JavaScript语法,包括ECMAScript 6标准。以下是一个展示Nashorn支持ECMAScript 6的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class NashornES6Example {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("nashorn");// Nashorn支持ECMAScript 6String script = "let greet = (name) => `Hello, ${name}!`;" +"greet('Nashorn ES6')";engine.eval(script);}
}

在上述例子中,通过Nashorn引擎执行了一个使用ECMAScript 6语法的JavaScript脚本。

3.3 使用Nashorn调用Java方法

Nashorn引擎与Java的集成非常紧密,可以直接调用Java方法。以下是一个展示Nashorn调用Java方法的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class NashornJavaInterop {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("nashorn");// Nashorn调用Java方法engine.put("javaVariable", "Hello from Java!");engine.eval("print(javaVariable)");}
}

上述例子中,通过engine.put方法将Java变量传递给Nashorn引擎,并在脚本中使用print输出。

3.4 在Java中使用Nashorn模板字符串

Nashorn引擎支持ECMAScript 6的模板字符串,这使得在Java中使用JavaScript的模板字符串变得更加方便。以下是一个在Java中使用Nashorn模板字符串的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class NashornTemplateString {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("nashorn");// 在Java中使用Nashorn模板字符串String name = "Java";String script = "let message = `Hello, ${name}!`;" +"message";Object result = engine.eval(script);System.out.println(result);}
}

在上述例子中,通过Nashorn引擎执行了一个包含模板字符串的JavaScript脚本,其中${name}会被替换为Java中的变量值。

3.5 Nashorn中的Java类互操作

Nashorn不仅可以调用Java方法,还可以直接实例化Java类并与之互操作。以下是一个展示Nashorn中与Java类互操作的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class NashornJavaInterop {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("nashorn");// 在Nashorn中与Java类互操作engine.eval("var ArrayList = Java.type('java.util.ArrayList');" +"var list = new ArrayList();" +"list.add('Nashorn');" +"list.add('Java');" +"print(list);");}
}

在上述例子中,通过Nashorn引擎执行了一个JavaScript脚本,其中实例化了Java的ArrayList类,并成功进行了添加元素和输出。

3.6 Nashorn中的脚本缓存

Nashorn引擎支持脚本的缓存,这在执行相同脚本多次时能够提高性能。以下是一个展示Nashorn脚本缓存的示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;public class NashornScriptCaching {public static void main(String[] args) throws ScriptException {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("nashorn");// Nashorn脚本缓存String script = "print('Hello from Nashorn!')";for (int i = 0; i < 5; i++) {engine.eval(script);}}
}

在上述例子中,通过Nashorn引擎执行相同的脚本多次,利用脚本缓存提高了执行效率。

4. Kotlin Scripting

4.1 Kotlin脚本语言概述

Kotlin是一种现代的、静态类型的编程语言,也可以作为脚本语言使用。它与Java的无缝集成使得在Java应用中使用Kotlin非常方便。

4.2 与Java互操作性

Kotlin可以与Java代码直接互操作,调用Java类和方法。以下是一个简单的示例:

// Kotlin脚本中调用Java类
class Greeter {fun greet(name: String): String {return "Hello, $name!"}
}val greeter = Greeter()
println(greeter.greet("John"))// Java代码中调用Kotlin脚本
val engine = ScriptEngineManager().getEngineByExtension("kts")
engine.eval("println(\"Hello from Kotlin!\")")

4.3 Kotlin脚本中的DSL支持

Kotlin在脚本编写中提供了强大的DSL支持,使得定义领域特定语言更加简洁和易读。以下是一个展示Kotlin脚本中DSL支持的示例,模拟配置文件的定义:

// 使用DSL定义配置文件
fun config(action: Config.() -> Unit): Config {val config = Config()config.action()return config
}class Config {var server: Server? = nullvar database: Database? = nullfun server(action: Server.() -> Unit) {server = Server().apply(action)}fun database(action: Database.() -> Unit) {database = Database().apply(action)}
}class Server {var host: String? = nullvar port: Int? = null
}class Database {var url: String? = nullvar username: String? = nullvar password: String? = null
}// 使用DSL定义配置
val myConfig = config {server {host = "localhost"port = 8080}database {url = "jdbc:mysql://localhost:3306/mydatabase"username = "user"password = "password"}
}println("Server Host: ${myConfig.server?.host}, Database URL: ${myConfig.database?.url}")

上述例子中,通过Kotlin的DSL支持,定义了一个简单的配置文件结构,使得配置信息更加清晰和易于理解。

4.4 Kotlin脚本中的运算符重载

Kotlin允许对运算符进行重载,以便在特定场景下定义自定义的行为。以下是一个运算符重载的示例:

// 运算符重载示例
data class Point(val x: Int, val y: Int)operator fun Point.plus(other: Point): Point {return Point(x + other.x, y + other.y)
}val point1 = Point(1, 2)
val point2 = Point(3, 4)
val result = point1 + point2println("Result: (${result.x}, ${result.y})")

在上述例子中,通过重载plus运算符,实现了点的相加操作。

4.5 Kotlin脚本中的DSL应用:Gradle脚本

Kotlin DSL在Gradle构建脚本中得到了广泛应用。以下是一个简单的Gradle构建脚本的示例:

plugins {kotlin("jvm") version "1.5.10"
}application {mainClassName = "com.example.MainKt"
}repositories {mavenCentral()
}dependencies {implementation(kotlin("stdlib"))testImplementation(kotlin("test"))
}

在上述例子中,通过Kotlin DSL编写了一个Gradle构建脚本,定义了项目的插件、仓库、依赖等信息。

4.6 Kotlin脚本中的扩展函数

Kotlin支持扩展函数,使得在不修改类的情况下为其添加新的功能成为可能。以下是一个展示Kotlin脚本中扩展函数的示例:

// 扩展函数示例
fun String.isPalindrome(): Boolean {val cleanString = this.toLowerCase().replace(Regex("[^a-z0-9]"), "")return cleanString == cleanString.reversed()
}val palindromeString = "A man, a plan, a canal, Panama"
val nonPalindromeString = "Hello, World!"println("\"$palindromeString\" is a palindrome: ${palindromeString.isPalindrome()}")
println("\"$nonPalindromeString\" is a palindrome: ${nonPalindromeString.isPalindrome()}")

在上述例子中,通过扩展函数isPalindromeString类添加了判断回文的功能。

5. JRuby

5.1 Ruby语言在Java平台上的实现

JRuby是Ruby语言在Java平台上的实现,通过JVM(Java虚拟机)执行Ruby代码。它提供了Ruby语法和Java的强大功能。

5.2 与Java的深度集成

JRuby可以直接调用Java类,与Java代码无缝集成。以下是一个简单的示例:

# Ruby代码中调用Java类
java_import 'java.util.ArrayList'
list = ArrayList.new
list.add('Ruby')
list.add('JRuby')
puts list# Java代码中调用JRuby脚本
ScriptingContainer container = new ScriptingContainer(LocalContextScope.SINGLETHREAD);
container.runScriptlet("puts 'Hello from JRuby!'")

5.3 JRuby中的Ruby与Java互操作性

JRuby提供了强大的Ruby与Java互操作性,可以直接调用Java类和方法。以下是一个展示JRuby中Ruby与Java互操作性的示例:

# JRuby中Ruby与Java互操作性示例
java_import 'java.util.HashMap'# 调用Java方法
java_hash_map = HashMap.new
java_hash_map.put('key', 'value')
puts "Java HashMap size: #{java_hash_map.size}"# 在Ruby中调用Java方法
def print_messageputs 'Hello from Ruby!'
endjava_import 'JRubyInteropExample'
JRubyInteropExample.printMessage

在上述例子中,通过java_import导入Java类,成功调用了Java的HashMap类和JRubyInteropExample类中的printMessage方法。

5.4 使用JRuby编写Java Swing应用

JRuby不仅可以与Java类互操作,还可以使用Java的GUI库,如Swing,来编写图形界面应用程序。以下是一个使用JRuby编写Java Swing应用的示例:

# 使用JRuby编写Java Swing应用
java_import javax.swing.JFrame
java_import javax.swing.JButton
java_import java.awt.event.ActionListenerclass HelloWorldAppinclude ActionListenerdef initialize@frame = JFrame.new("Hello World Swing App")@button = JButton.new("Click me!")@button.add_action_listener(self)@frame.add(@button)@frame.set_default_close_operation(JFrame::EXIT_ON_CLOSE)@frame.set_size(300, 200)@frame.set_visible(true)enddef actionPerformed(event)puts 'Button clicked!'end
endHelloWorldApp.new

上述例子中,通过JRuby编写了一个简单的Swing应用程序,当按钮被点击时,输出消息。

5.5 JRuby中的Ruby Gems和Java库整合

JRuby允许使用Ruby Gems(Ruby的包管理器)并整合Java库。以下是一个展示JRuby中整合Ruby Gems和Java库的示例:

# JRuby中整合Ruby Gems和Java库示例
require 'java'
require 'rubygems'
require 'bundler/setup'
require 'sinatra'get '/' do'Hello from JRuby Sinatra app!'
end

在上述例子中,通过使用sinatra Ruby Gem和Java库的整合,成功创建了一个简单的Sinatra应用。

5.6 JRuby中的并发编程

JRuby充分利用了Java平台的并发编程能力。以下是一个展示JRuby中并发编程的示例:

# JRuby中的并发编程示例
java_import 'java.util.concurrent.Executors'# 使用Java Executor框架
executor = Executors.newFixedThreadPool(2)# 创建并发任务
tasks = []
tasks << executor.submit { puts 'Task 1 executed' }
tasks << executor.submit { puts 'Task 2 executed' }# 等待所有任务完成
tasks.each(&:get)# 关闭Executor
executor.shutdown

在上述例子中,通过java_import导入Java的Executor框架,成功创建了一个并发任务池,并执行了两个并发任务。

总结

通过深入研究这些动态脚本执行库,我们发现它们为Java开发者提供了多样的选择,无论是为了编写更灵活的脚本还是与其他脚本语言无缝集成。在选择合适的动态脚本执行库时,需要根据项目需求和开发团队的技能集进行权衡。这些库的强大功能使得Java开发者能够更加轻松地应对不同的开发场景和需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全需要对网络风险有独特的理解

迷失在翻译中&#xff1a;网络风险解释的脱节现实 在古印度的一个经典故事中&#xff0c;几个蒙住眼睛的人接近一头大象&#xff0c;每个人检查不同的部位。有人触摸树干&#xff0c;认为它像一条蛇。另一个摸到了一条腿&#xff0c;认为它是一棵树。还有一个拿着象牙的人&…

云平台性能测试之存储性能测试

一、认识存储磁盘IO 磁盘IO测试是指在性能测试过程中&#xff0c;对系统的磁盘读写操作进行测试和评估的过程。磁盘是计算机系统中重要的存储介质&#xff0c;对于许多应用程序来说&#xff0c;磁盘IO的性能影响着系统的整体性能。 在性能测试中&#xff0c;磁盘IO测试通常有…

高级编程,JavaScript笔记-字符串的常用方法

一、操作方法 我们也可将字符串常用的操作方法归纳为增、删、改、查&#xff0c;需要知道字符串的特点是一旦创建了&#xff0c;就不可变 增 这里增的意思并不是说直接增添内容&#xff0c;而是创建字符串的一个副本&#xff0c;再进行操作 除了常用以及${}进行字符串拼接之…

Java中打印图案最常用的25个图案程序

Java是公认的最流行的编程语言&#xff0c;因为它的简单性和多功能性。还可以使用它开发各种应用程序&#xff0c;包括Web、移动和桌面应用程序。此外&#xff0c;Java为开发人员提供了强大的工具来轻松高效地创建复杂的程序。Java最有前途的特性之一是它能够创建可以以特定格式…

《向量数据库指南》——为什么说向量数据库是更适合AI体质的“硬盘”

其“AI原生”的体质,具体表现在几个方面: 1.更高的效率。 AI算法,要从图像、音频和文本等海量的非结构化数据中学习,提取出以向量为表示形式的“特征”,以便模型能够理解和处理。因此,向量数据库比传统基于索引的数据库有明显优势。 2.更低的成本。 大模型要从一种新…

美易平台:美国阿特拉斯航空公司波音747 8型货机因发动机故障安全降落

正文&#xff1a; 据路透社报道&#xff0c;美国阿特拉斯航空公司的一架波音747 8型货机在从迈阿密国际机场起飞后不久&#xff0c;发动机出现故障&#xff0c;但幸运的是飞机成功安全降落。这一事件引起了人们对航空安全的关注。 根据航空信息网站Flightaware的数据显示&…

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器(超详细!)

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器 注&#xff1a;本学习笔记基于stm32f4系列 使用的开发板为正点原子stmf407ZGT6探索者开发板 GPIO引脚使用时&#xff0c;可输入或输出数字信号 例如: 检测按键输入信号&#xff08;Read_Pin&#xff09;输出信号&#xff08;W…

敏捷开发之开发流程

敏捷开发流程 一、迭代周期 我们团队的迭代周期一般是2周&#xff0c;如果研发评估时间过长的话也会将周期延长至一个月&#xff0c;但是大多数我们是2周的迭代周期。 这里说的2周是研发开始coding、提测、测试、上线&#xff0c;也就是说2周以后要上线相应的能力。并不包括…

flink operator 拉取阿里云私有镜像(其他私有类似)

创建 k8s secret kubectl --namespace flink create secret docker-registry aliyun-docker-registry --docker-serverregistry.cn-shenzhen.aliyuncs.com --docker-usernameops_acr1060896234 --docker-passwordpasswd --docker-emailDOCKER_EMAIL注意命名空间指定你使用的 我…

从0开始python学习-50.pytest之多接口用例封装

1. yaml用例设计--一个yaml中多个用例&#xff0c;且互相存在关联关系 - # 第一个用例request:method: posturl: http://192.168.0.1:8010/apijson:accounts: adminpwd: 123type: usernameheaders:Content-Type: application/json- # 第二个用例request:method: posturl: http:…

Linux:多线程

目录 1.线程的概念 1.1线程的理解 1.2进程的理解 1.3线程如何看待进程内部的资源? 1.4进程 VS 线程 2.线程的控制 2.1线程的创建 2.2线程的等待 2.3线程的终止 2.4线程ID 2.5线程的分离 3.线程的互斥与同步 3.1相关概念 3.2互斥锁 3.2.1概念理解 3.2.2操作理解…

分类预测 | Matlab实现WOA(海象)-XGboost分类【24年新算法】基于海象优化算法(WOA)优化XGBoost的数据分类预测

分类预测 | Matlab实现WOA(海象)-XGboost分类【24年新算法】基于海象优化算法(WOA)优化XGBoost的数据分类预测 目录 分类预测 | Matlab实现WOA(海象)-XGboost分类【24年新算法】基于海象优化算法(WOA)优化XGBoost的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本…

js控制浏览器前进、后退、页面跳转

在JavaScript中&#xff0c;你可以使用 window 对象的 history 对象来控制浏览器的历史记录。以下是一些常用的方法&#xff1a; 前进和后退&#xff1a; window.history.forward(): 前进到历史记录中的下一个页面。window.history.back(): 返回历史记录中的上一个页面。window…

模型的召回率(Recall)

召回率&#xff08;Recall&#xff09;&#xff0c;也称为灵敏度&#xff08;Sensitivity&#xff09;或真正例率&#xff08;True Positive Rate&#xff09;&#xff0c;是用于评估二分类模型性能的指标之一。召回率衡量了模型正确识别正例的能力&#xff0c;即在所有实际正例…

ctfshow php特性(web89-web101)

目录 web89 web90 web91 web92 web93 web94 web95 web96 web97 web98 web99 web100 web101 php特性(php基础知识) web89 <?php include("flag.php"); highlight_file(_FILE_);if(isset($_GET[num])){$num$_GET[num];if(preg_match("/[0-9]/&…

Debezium发布历史77

原文地址&#xff1a; https://debezium.io/blog/2019/12/13/externalized-secrets/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. 使用 Debezium 连接器实现秘密外部化 十二月 13, 2019 作者&#xff1a; Jir…

Docker项目部署()

1.创建文件夹tools mkdir tools 配置阿里云 Docker Yum 源 : yum install - y yum - utils device - mapper - persistent - data lvm2 yum - config - manager -- add - repo http://mirrors.aliyun.com/docker- ce/linux/centos/docker - ce.repo 更新 yum 缓存 yum makec…

【机器学习理论】2023 Spring Homework 1

Please login to Gradescope via your CUHK account and use the entry code: 6ZWGYD Problem 1 (Gaussian Distribution as an Exponential Family): We showed Gaussian distribution N ( μ , σ 2 ) \mathcal{N}\left(\mu, \sigma^{2}\right) N

军事课堂MR情景仿真实训教学

一、课堂应用场景 1、战术模拟&#xff1a;MR系统可以模拟各种战场环境&#xff0c;让学生在实际操作中了解和掌握各种战术技巧。通过模拟实战场景&#xff0c;学生可以在短时间内获得丰富的实战经验&#xff0c;提高他们的应变能力和团队协作能力。 2、武器操作训练&#xf…

Kafka-消费者-KafkaConsumer分析-PartitionAssignor

Leader消费者在收到JoinGroupResponse后&#xff0c;会按照其中指定的分区分配策略进行分区分配&#xff0c;每个分区分配策略就是一个PartitionAssignor接口的实现。图是PartitionAssignor的继承结构及其中的组件。 PartitionAssignor接口中定义了Assignment和Subscription两个…