SeaTunnel扩展Source插件,自定义connector-webservice

代码结构

在seatunnel-connectors-v2中新建connector-webservice模块,可以直接赋值connector-http-base模块,webservice和http的方式比较类似,有些类直接复制了http中的代码。

核心类有WebserviceConfig,WebserviceParameter,WebserviceSource,WebserviceSourceReader

配置文件

env {
  # You can set engine configuration here STREAMING BATCH
  execution.parallelism = 1
  job.mode = "BATCH"

  #execution.checkpoint.data-uri = "hdfs://localhost:9000/checkpoint"
}

source {
  # This is a example source plugin **only for test and demonstrate the feature source plugin**
   Webservice {
            url = "http://www.xxx.com.cn/xxx/WeatherWebService.asmx?wsdl"
            method = "getSupportCity"
            namespaceUri = "http://xxx.com.cn/"
            params = {
                "byProvinceName"="xxx"
            }
            result_table_name="table_3"
        }
}
transform {

    Sql {
      source_table_name = "table_3"
      result_table_name = "table_4"
      query = "select content  as fname from table_3"
    }
}
sink {
    Jdbc {
            removeDatabase="true"
            code="target"
            _compsName="sss"
            description=""
            mapType="1"
            source_table_name="table_4"
            writeMode="0"
            type="5"
            database="xxx"
            password="xxx"
            driver="com.mysql.cj.jdbc.Driver"
            url="jdbc:mysql://192.168.xxx:3306/xxx_test"
            pluginName="Jdbc"
            datasource="197"
            emptyType="2"
            user="xxx"
            table="xxx"
        generate_sink_sql="true"
    }
}

代码说明

WebserviceConfig
package org.apache.seatunnel.connectors.seatunnel.webservice.config;

import lombok.Data;
import org.apache.seatunnel.api.configuration.Option;
import org.apache.seatunnel.api.configuration.Options;

import java.io.Serializable;
import java.util.Map;

@Data
public class WebserviceConfig  implements Serializable {

    public static final boolean DEFAULT_ENABLE_MULTI_LINES = false;
    public static final Option<String> FORMAT =
            Options.key("format").stringType()
                    .defaultValue("JSON")
                    .withDescription("Http response format");
    public static final Option<String> URL =
            Options.key("url").stringType().noDefaultValue().withDescription("Webservice request url");
    public static final Option<String> METHOD =
            Options.key("method")
                    .stringType().noDefaultValue().withDescription("Webservice request method");
    public static final Option<String> NAMESPACE_URI =
            Options.key("namespaceUri")
                    .stringType().noDefaultValue().withDescription("Webservice request namespaceUri");
    public static final Option<Map<String, String>> PARAMS =
            Options.key("params").mapType().noDefaultValue().withDescription("Webservice request params");

}

WebserviceParameter

package org.apache.seatunnel.connectors.seatunnel.webservice.config;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.seatunnel.shade.com.typesafe.config.Config;
@Data
public class WebserviceParameter implements Serializable {

    protected String url;
    protected String method;
    protected String namespaceUri;
    protected Map<String, String> params;
    protected String body;

    public void buildWithConfig(Config pluginConfig) {
        this.setUrl(pluginConfig.getString(WebserviceConfig.URL.key()));
        this.setMethod(pluginConfig.getString(WebserviceConfig.METHOD.key()));
        this.setNamespaceUri(pluginConfig.getString(WebserviceConfig.NAMESPACE_URI.key()));
        if (pluginConfig.hasPath(WebserviceConfig.PARAMS.key())) {
            this.setParams(
                    pluginConfig.getConfig(WebserviceConfig.PARAMS.key()).entrySet().stream()
                            .collect(
                                    Collectors.toMap(
                                            Map.Entry::getKey,
                                            entry -> String.valueOf(entry.getValue().unwrapped()),
                                            (v1, v2) -> v2)));
        }
    }

}

DeserializationCollector

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import lombok.AllArgsConstructor;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.format.json.JsonDeserializationSchema;

import java.io.IOException;

@AllArgsConstructor
public class DeserializationCollector {

    private DeserializationSchema<SeaTunnelRow> deserializationSchema;

    public void collect(byte[] message, Collector<SeaTunnelRow> out) throws IOException {
        if (deserializationSchema instanceof JsonDeserializationSchema) {
            ((JsonDeserializationSchema) deserializationSchema).collect(message, out);
        } else {
            SeaTunnelRow deserialize = deserializationSchema.deserialize(message);
            out.collect(deserialize);
        }
    }
}

SimpleTextDeserializationSchema

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import lombok.AllArgsConstructor;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;

@AllArgsConstructor
public class SimpleTextDeserializationSchema implements DeserializationSchema<SeaTunnelRow> {

    private SeaTunnelRowType rowType;

    @Override
    public SeaTunnelRow deserialize(byte[] message) {
        return new SeaTunnelRow(new Object[] {new String(message)});
    }

    @Override
    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {
        return rowType;
    }
}

WebserviceSource

package org.apache.seatunnel.connectors.seatunnel.webservice.source;

import com.google.auto.service.AutoService;
import org.apache.seatunnel.api.common.JobContext;
import org.apache.seatunnel.api.common.PrepareFailException;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Boundedness;
import org.apache.seatunnel.api.source.SeaTunnelSource;
import org.apache.seatunnel.api.table.catalog.CatalogTableUtil;
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.api.table.type.SeaTunnelRowType;
import org.apache.seatunnel.common.config.CheckConfigUtil;
import org.apache.seatunnel.common.config.CheckResult;
import org.apache.seatunnel.common.constants.PluginType;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitSource;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceConfig;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceParameter;
import org.apache.seatunnel.format.json.JsonDeserializationSchema;
import org.apache.seatunnel.shade.com.typesafe.config.Config;


@AutoService(SeaTunnelSource.class)
public class WebserviceSource extends AbstractSingleSplitSource<SeaTunnelRow> {
    protected final WebserviceParameter webserviceParameter = new WebserviceParameter();
    protected SeaTunnelRowType rowType;
    protected JobContext jobContext;
    protected String contentField;

    protected DeserializationSchema<SeaTunnelRow> deserializationSchema;
    @Override
    public String getPluginName() {
        return "Webservice";
    }

    @Override
    public void prepare(Config pluginConfig) throws PrepareFailException {
        CheckResult result = CheckConfigUtil.checkAllExists(pluginConfig, WebserviceConfig.URL.key());
        if (!result.isSuccess()) {
            throw new RuntimeException(
                    String.format(
                            "PluginName: %s, PluginType: %s, Message: %s",
                            getPluginName(), PluginType.SOURCE, result.getMsg()));
        }
        this.webserviceParameter.buildWithConfig(pluginConfig);
        buildSchemaWithConfig(pluginConfig);
    }

    protected void buildSchemaWithConfig(Config pluginConfig) {
        if (pluginConfig.hasPath(CatalogTableUtil.SCHEMA.key())) {
            this.rowType = CatalogTableUtil.buildWithConfig(pluginConfig).getSeaTunnelRowType();
            // default use json format
            String format = WebserviceConfig.FORMAT.defaultValue();
            if (pluginConfig.hasPath(WebserviceConfig.FORMAT.key())) {
                format = pluginConfig
                        .getString(WebserviceConfig.FORMAT.key());
            }
            switch (format.toLowerCase()) {
                case "json":
                    this.deserializationSchema =
                            new JsonDeserializationSchema(false, false, rowType);
                    break;
                default:
                    // TODO: use format SPI
                    throw new RuntimeException(
                            String.format(
                                    "Unsupported data format [%s], http connector only support json format now",
                                    format));
            }
        } else {
            this.rowType = CatalogTableUtil.buildSimpleTextSchema();
            this.deserializationSchema = new SimpleTextDeserializationSchema(this.rowType);
        }
    }

    @Override
    public void setJobContext(JobContext jobContext) {
        this.jobContext = jobContext;
    }

    @Override
    public Boundedness getBoundedness() {
        return Boundedness.BOUNDED;
    }

    @Override
    public SeaTunnelDataType<SeaTunnelRow> getProducedType() {
        return this.rowType;
    }

    @Override
    public AbstractSingleSplitReader<SeaTunnelRow> createReader(SingleSplitReaderContext readerContext) throws Exception {
        return new WebserviceSourceReader(webserviceParameter, readerContext,
                deserializationSchema,
                contentField);
    }
}

WebserviceSourceReader

package org.apache.seatunnel.connectors.seatunnel.webservice.source;


import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.http.webservice.SoapClient;
import cn.hutool.http.webservice.SoapProtocol;
import lombok.extern.slf4j.Slf4j;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import org.apache.seatunnel.api.serialization.DeserializationSchema;
import org.apache.seatunnel.api.source.Boundedness;
import org.apache.seatunnel.api.source.Collector;
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
import org.apache.seatunnel.common.utils.JsonUtils;
import org.apache.seatunnel.connectors.seatunnel.common.source.AbstractSingleSplitReader;
import org.apache.seatunnel.connectors.seatunnel.common.source.SingleSplitReaderContext;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.ReadContext;
import org.apache.seatunnel.connectors.seatunnel.webservice.config.WebserviceParameter;

import java.io.IOException;
import java.util.HashMap;

@Slf4j
public class WebserviceSourceReader extends AbstractSingleSplitReader<SeaTunnelRow> {

    protected final SingleSplitReaderContext context;
    private static final Option[] DEFAULT_OPTIONS = {
            Option.SUPPRESS_EXCEPTIONS, Option.ALWAYS_RETURN_LIST, Option.DEFAULT_PATH_LEAF_TO_NULL
    };
    private final String contentJson;
    private final Configuration jsonConfiguration =
            Configuration.defaultConfiguration().addOptions(DEFAULT_OPTIONS);

    protected final WebserviceParameter webserviceParameter;

    private final DeserializationCollector deserializationCollector;

    public WebserviceSourceReader(
            WebserviceParameter webserviceParameter,
            SingleSplitReaderContext context,
            DeserializationSchema<SeaTunnelRow> deserializationSchema,
            String contentJson) {
        this.webserviceParameter = webserviceParameter;
        this.context = context;
        this.contentJson = contentJson;
        this.deserializationCollector = new DeserializationCollector(deserializationSchema);
    }
    @Override
    public void open() throws Exception {
        log.info("WebserviceSourceReader open");
    }

    @Override
    public void close() throws IOException {
        log.info("WebserviceSourceReader close");
    }

    @Override
    public void pollNext(Collector<SeaTunnelRow> output) throws Exception {
        try {
            SoapClient client = SoapClient.create(webserviceParameter.getUrl())
                    .setMethod(webserviceParameter.getMethod(), webserviceParameter.getNamespaceUri());
            for (String key : webserviceParameter.getParams().keySet()) {
                String param = webserviceParameter.getParams().get(key);
                client = client.setParam(key, param);
            }
            String result = client.send(false);
//        deserializationCollector.collect(result.getBytes(), output);
            SeaTunnelRow seaTunnelRow = new SeaTunnelRow(new Object[]{getSoapBody(result)});
            output.collect(seaTunnelRow);
            log.info("WebserviceSourceReader pollNext");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (Boundedness.BOUNDED.equals(context.getBoundedness())) {
                // signal to the source that we have reached the end of the data.
                log.info("Closed the bounded http source");
                context.signalNoMoreElement();
            }
        }
    }

    public String getSoapBody(String xml) {
        if (xml.indexOf("<soap:Body>") != -1) {
            return StrUtil.subBetween(xml, "<soap:Body>", "</soap:Body>");
        } else {
            return StrUtil.subBetween(xml, "<soap12:Body>", "</soap12:Body>");
        }
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.apache.seatunnel</groupId>
        <artifactId>seatunnel-connectors-v2</artifactId>
        <version>2.3.3-SNAPSHOT</version>
    </parent>

    <artifactId>connector-webservice</artifactId>
    <name>SeaTunnel : Connectors V2 : Webservice</name>

    <properties>
        <rabbitmq.version>5.9.0</rabbitmq.version>
        <json-path.version>2.7.0</json-path.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.seatunnel</groupId>
            <artifactId>connector-common</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.seatunnel</groupId>
            <artifactId>seatunnel-format-json</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>${json-path.version}</version>
        </dependency>
    </dependencies>

  <scm>
    <tag>2.3.2</tag>
  </scm>
</project>

执行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构 / 队列 / 循环队列 / 概念

1. 定义 为充分利用向量空间&#xff0c;克服假溢出现象的方法是&#xff1a;将向量空间想象为一个首尾相接的圆环&#xff0c;并称这种向量为循环向量。存储在其中的队列称为循环队列&#xff08;Circular Queue&#xff09;。循环队列是把顺序队列首尾相连&#xff0c;把存储…

思维模型 逆向思维

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。弱者道之用反者道之动。 1 逆向思维的应用 1.1 历史典故 1 曹冲称象 这个故事讲述的是曹操的儿子曹冲如何利用逆向思维解决了称大象重量的难题。曹冲没有直接去称大象的重量&#xff0c;…

30秒搞定一个属于你的问答机器人,快速抓取网站内容

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 文章目录 简介运行效果GitHub地址 简介 爬取一个网站的内容&#xff0c;然后让这个内容变成你自己的私有知识库&#xff0c;并且还可以搭建一个基于私有知识库的问…

大三上oracle数据库期末复习

1、创建表空间 2、创建用户 3、用户授权 oracle数据库逻辑存储结构&#xff1a; 1、表空间&#xff08;最大的逻辑存储单元&#xff09; 创建表空间 2、段 3、盘区&#xff08;最小的磁盘空间分配单元&#xff09; 4、数据块&#xff08;最小的数据读写单元&#xff09; 用…

应用于智慧工厂的AI边缘计算盒子+AI算法软硬一体化方案

智慧工厂解决方案&#xff0c;传统工厂/生产管理&#xff0c;普遍存在运营粗放、效率低、应变能力差、安全隐患突出、资源不平衡等“行业症状”&#xff1b; 以英码产品为核心的智能化场景解决方案&#xff0c;可以从本质上根治这些“症状”&#xff0c;如企业可利用智能预测系…

次世代建模纹理贴图怎么做?

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 1、什么是次时代建模&#xff1f; "次世代建模"是一个术语&#xff0c;通常用来描述…

ChatGPT一周年,奥特曼官宣 OpenAI 新动作!

大家好&#xff0c;我是二狗。 今天是11月30日&#xff0c;一转眼&#xff0c;ChatGPT 发布已经一周年了&#xff01; 而就在刚刚&#xff0c;ChatGPT一周年之际。 OpenAI 正式宣布Sam Altman回归重任CEO, Mira Murati 重任CTO&#xff0c;Greg Brockman重任总裁&#xff0c;O…

一起学docker系列之十四Dockerfile微服务实践

目录 1 前言2 创建微服务模块2.1 **创建项目模块**2.2 **编写业务代码** 3 编写 Dockerfile4 构建 Docker 镜像5 运行 Docker 容器6 测试微服务7 总结8 参考地址 1 前言 微服务架构已经成为现代软件开发中的一种重要方式。而 Docker 提供了一种轻量级、便携式的容器化解决方案…

【高效开发工具系列】驼峰下划线互转

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

设计模式-结构型模式之组合、享元设计模式

文章目录 四、组合模式五、享元模式 四、组合模式 组合模式&#xff08;Composite Pattern&#xff09;&#xff0c;又叫部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。 组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。它创建了…

类数组对象是什么?

类数组对象是指具有索引和长度属性&#xff08;通常是 length 属性&#xff09;的对象&#xff0c;但它不具备数组的方法&#xff0c;比如push、pop、forEach等。 常见的类数组对象有哪些&#xff1f; 让我们来看看~ 1. arguments 对象 函数中的 arguments 对象是一个类数组对…

MySQL导出ER图为图片或PDF

目录 1、Navicat 生成ER图 1、选择数据库&#xff0c;逆向数据库到模型 2、查看ER图 3、导出ER图 2、使用MySQL官方工具&#xff1a;MySQL Workbench 1、首先连接MySQL数据库 2、点击Database&#xff0c;选择Reverse Engineer 3、填写数据库信息&#xff0c;点Next …

【解决方案】基于物联网表计的综合能源管理方案

安科瑞顾强 为加快推进国家“双碳”战略和新型能源体系建设&#xff0c;努力实现负荷准确控制和用户精细化管理&#xff0c;按照“政府主导、电网组织、政企协同、用户实施”的指导原则&#xff0c;多地成立市/县级电力负荷管理中心&#xff0c;包括浙江宁波、慈溪、辽宁大连、…

数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)

目录 一.什么是链表 二.链表的实现 节点的插入 头插法 尾插法 指定位置插入 节点的删除 删除第一次出现的关键字节点 删除所有关键字节点 节点的查找 链表的清空 链表的长度 前言&#xff1a;在上一篇文章中&#xff0c;我们认识了线性数据结构中的顺序表&#xff0…

TLSF算法概念,原理,内存碎片问题分析

TLSF算法介绍 TLSF&#xff08;Two-Level Segregated Fit&#xff0c;两级分割适应算法&#xff09;。 第一级&#xff08;first level,简称fl&#xff09;&#xff1a;将内存大小按2的幂次方划分一个粗粒度的范围&#xff0c;如一个72字节的空闲内存的fl是6&#xff08;72介…

Tomcat-安装与基础配置

Tomcat-安装与基础配置 下载 下载Tomcat9 选择适合自己系统位数的版本下载 Tomcat-目录 bin: 存放启动与关闭Tomcat的脚本文件conf: 存放Tomcat的各种配置文件,其中最主要的配置文件就是server.xml【如果端口冲突,就可以将 8080 端口修改】lib: 存放Tomcat运行时所需的j…

vue使用elementui的el-menu的折叠菜单collapse

由于我的是在el-menu所在组件外面的兄弟组件设置是否折叠的控制&#xff0c;我用事件总线bus进行是否折叠传递 参数说明类型可选值默认值collapse是否水平折叠收起菜单&#xff08;仅在 mode 为 vertical 时可用&#xff09;boolean—falsebackground-color菜单的背景色&#…

编程实战:类C语法的编译型脚本解释器(系列)

“脚本”始终是个具有独特魅力的领域&#xff0c;能够随时方便地解决一些问题&#xff0c;但脚本的随意性同时带来别的问题&#xff0c;所以脚本始终属于让人又爱又恨的存在。 很多大型系统都会嵌入一些小型的解释器&#xff0c;用来让用户亲自编写简单的逻辑规则。不幸的是&am…

Meta推出了一套开源AI语言翻译模型,这些模型不仅能保留说话的表达方式,还能提升流式翻译的效果

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

LeetCode算法题解(动态规划)|LeetCode1143. 最长公共子序列、LeetCode1035. 不相交的线、LeetCode53. 最大子数组和

一、LeetCode1143. 最长公共子序列 题目链接&#xff1a;1143. 最长公共子序列 题目描述&#xff1a; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一…