流计算需要框架吗?SPL 可能是更好的选择
流数据源通常是动态、无界的,看起来与静态、有限的批数据源区别较大,传统的数据库技术在架构上难以直接处理流数据源,只能让位于后来者。heron\samza\storm\spark\flink等计算框架最先完成突破,在流计算技术中占得先发优势。这些框架非常成功,以至于一说到流计算,应用程序员通常都会去转头寻找某种框架,而不宣称是某种框架的计算技术,则通常被认为不适合实现流计算。
虽然计算框架最先突破流计算,但框架本身对流计算的意义不大。框架是针对特定的应用场景,事先准备的结构性代码,比如扩展方式(分布式、集中式)、主控流程(异步、同步)等,具体的应用程序只需往框架里填业务逻辑代码。框架优点鲜明,可以用较低的代码量建立成熟稳定的程序结构,但缺点也不能忽视,应用程序无法脱离框架的结构性束缚,只适用于框架预设的场景,这种预设场景很难面面俱到(否则太复杂太难用),通常只能针对单一场景。实际的应用场景多种多样日日有新,往往与预设场景不符,比如让spark被jasperReport报表调用,或让flink应用于小集群或边缘计算。这种场景下使用框架,开发者除了尽力适应预设场景,就只能对框架做出一定的修补,前者经常要牺牲计算性能或浪费硬件成本,后者则会付出巨大的工作量。如果针对实际场景设计结构性代码(并引入流计算类库),则可避免牺牲浪费和付出。即使实际场景恰好符合预设的场景,流计算框架也不一定是最优方案,比如分布式场景下,在降低结构性代码和计算代码的耦合性方面,分布式流计算框架就不如分布式服务框架(如Zookeeper、HSF、Dubbo)+流计算类库。
对流计算有意义的是访问能力和计算能力。流计算由流数据源和计算组成,也就是流数据访问能力和数据计算能力。访问能力指流数据源接口和流入机制。流数据源的种类很多,包括狭义的字符流和字节流,如http流、文件流、消息流(如kafka),也包括广义的流数据,如RDB的记录流(游标)、NoSQL的文档流。流入机制分为主动和被动两种,即系统主动从外界获取数据,以及系统被动等待外界输入数据。计算能力的门槛较高,作为流计算技术,至少应提供基本的结构化计算函数、基本的流程控制语法、基本的半结构化数据处理能力,即过滤、去重、排序、分组汇总、关联、归并等计算函数;分支结构(如if),循环结构(如for);将json\xml等半结构化数据解析为记录。
访问能力是基础,计算能力是核心。流计算还是计算,只不是数据源是流式的,那么计算能力本身才是根本,尤其是高级计算能力。访问能力的门槛较低,容易复制扩展,同质化严重,并非流计算的核心。高级计算能力的门槛很高,在根本上决定了流计算的开发效率和计算性能,是流计算的核心,比如流批混算、简化复杂计算、高性能计算。很多流计算框架往往将重点放在访问能力上(甚有的连这都不足),计算能力反倒不足,不能简化业务逻辑的复杂度,普遍还不如传统数据库。
高级计算能力:流批混算、简化复杂计算、高性能计算。除了监控等特殊场景外,单纯的流计算在现实中很少见,流数据和批数据的混合计算才是常态,实际上,监控类计算通常也要将批量数据(分钟小时级)和实时数据(秒级)合并后再计算。在实际项目中,虽然存在很多简单的计算逻辑如过滤、去重等,但更有价值的计算逻辑通常较复杂,需要流计算技术提供丰富的计算函数和自由的表达语法,从而直观快速地实现计算目标。流技术的实时性都不差,甚至超过人类感知范围,毫秒级对大多数应用意义并不大,但因为流批混算是常态,且很多流计算技术的批计算性能较弱(远不如RDB),导致整体性能较差,这种情况下必须提供丰富的高性能计算类库,才能提升整体计算性能。流数据经常要写出去再计算,比如暂存成温数据或长存成冷数据,流数据体积普遍偏大,再计算的时间普遍偏长,这种情况下也需要提供高性能的内外存存储格式,才能提升再计算(以及写读)的性能。流计算框架是对计算本身提供的支持并不丰富,专业性不足,高级计算能力还不成熟。
好的流计算技术,应当将重点放在流计算上,从而简化业务逻辑开发的复杂度,同时弱化框架,把结构性代码留给应用程序去做,从而适应各类应用场景。并在保证访问能力的基础上,重点提高计算能力,尤其是高级计算能力。
esProc SPL正是符合这些条件的流计算技术。
SPL是基于JVM的轻量级开源计算类库,支持灵活简单的JDBC集成接口,提供了方便的流数据访问能力和基本的计算能力,支持流批混算、简化复杂计算、高性能计算,是更加专业的计算语言。
灵活简单的集成接口
方便易用的JDBC接口。SPL计算代码以脚本文件的形式存于操作系统目录,Java代码通过JDBC调用SPL脚本文件,调用方法同存储过程。SPL的集成接口灵活简单,适用于广泛的应用场景,比如报表、桌面、Web、单机环境、分布式集群、手机应用、边缘计算。
例子:先编写SPL脚本。
A | B | |
1 | =connect("ORCL") | Oracle连接 |
2 | =A1.cursor@x("select OrderID,Amount,Client,SellerID,OrderDate from orders where OrderDate>? && OrderDate<=?",arg1,arg2) | Oracle有界流 |
3 | … |
将上面SPL脚本存为mix.splx,Java通过JDBC调用脚本:
Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn =DriverManager.getConnection("jdbc:esproc:local://");
CallableStatement statement = conn.prepareCall("{call mix(?, ?)}");
statement.setObject(1, "2022-01-01");
statement.setObject(2, "2022-12-31");
statement.execute();
计算外置降低耦合性。SPL没有采用计算代码与非计算代码混合的框架,相反,SPL的计算代码外置于Java的非计算代码,两者各司其职专业互补,一方改动不影响另一方,程序员不用借助框架,就可以用简单代码实现计算逻辑和前端应用的解耦。
解释型语言支持热切换。SPL是解释型语言,修改后可立即执行,无须编译无须停机无须重启 JAVA 应用,程序员无需编写结构性代码,就能实现计算逻辑的热切换。
方便的流数据访问能力
SPL支持丰富的流数据源,既包括狭义的字符流和字节流,如http流、文件流、消息流(如kafka),也包括广义的流数据,如RDB的记录流(游标)、NoSQL的文档流。
例子:过滤Kafka的无界流:
A | B | C | |
1 | =kafka_open("D://kafka.properties","topic-test") | kafka连接 | |
2 | for | =kafka_poll(A1).(json(value)) | 循环取数 |
3 | =B2.news(Datas;~.TagFullName, round(Time,-3):Time, ~.Type, ~.Qualitie, ~.Value) | 转为记录 | |
4 | =B3.select(Value>3.0 && Value<=4.0) | 过滤 | |
5 | … |
SPL支持的流数据源还有:任意RDB、Cassandra、InfluxDB、Redis、Dynamodb、ElasticSearch、HBase、Hive、HDFS、MongoDB、SAP、S3、阿里云等。除了读取,SPL也支持将计算结果写入这些数据源。
主动和被动的流入机制。主动流入机制,即在SPL脚本中通过流数据源接口获取数据并完成计算。参考前面过滤kafka的例子。
被动流入,即SPL脚本被动接收数据并完成计算。例子,实时发现异常工况。部分SPL脚本如下:
A | B | |
1 | =func(A12,learn_interval,extrem_interval) | 调用A12格的子函数,计算极值序列 |
2 | =func(A16,A1.(~(1)), learn_interval,extrem_interval,seq,"up") | 调用A16格的子函数,计算阈值上限 |
3 | … | 余下代码略 |
先在Java中通过API访问工厂设备的传感器,获取实时的时间序列;再通过JDBC调用SPL脚本,主要参数是时间序列Seq,次要参数有学习区间learn_interval、极值区间extrem_interval、报警间隔warn_interval;最后在SPL中接收参数,利用流入的时间序列完成异常发现。
基本计算能力
SPL内置基本结构化计算函数,可以轻松完成日常的SQL式计算。
过滤:data.select(Amount>1000 && Amount<=3000 && like(Client,"*s*"))
排序:data.sort(Client,-Amount)
去重:data.id(Client)
分组汇总:data.groups(year(OrderDate);sum(Amount))
关联:join(T ("D:/data/Orders.csv"):O,SellerId; T("D:/data/Employees.txt"):E,EId)
TopN:data.top(-3;Amount)
SPL还提供了符合SQL92标准的语法,支持集合计算、case when、with、嵌套子查询等。
SPL提供基本流程控制语法,可以方便地实现日常业务逻辑。
分支结构:
A | B | |
2 | … | |
3 | if T.AMOUNT>10000 | =T.BONUS=T.AMOUNT*0.05 |
4 | else if T.AMOUNT>=5000 && T.AMOUNT<10000 | =T.BONUS=T.AMOUNT*0.03 |
5 | else if T.AMOUNT>=2000 && T.AMOUNT<5000 | =T.BONUS=T.AMOUNT*0.02 |
循环结构:
A | B | |
3 | for T | =A3.BONUS=A3.BONUS+A3.AMOUNT*0.01 |
4 | =A3.CLIENT=CONCAT(LEFT(A3.CLIENT,4), "co.,ltd.") | |
5 | … |
SPL具有基本的半结构化数据处理能力,可以方便地处理Json\XML或不规则文本,尤其适合kafka等消息队列或mongoDB等NoSQL。
例如:对多层Json串进行条件查询,并用Json串返回计算结果:
A | B | |
1 | =json(arg_JsonStr) | 解析参数Json串 |
2 | =A1.conj(Orders) | 合并下层记录 |
3 | =A2.select(Amount>1000 && Amount<=2000) | 条件查询 |
4 | =json(A3) | 结果转为Json串 |
高级计算能力:流批混算
计算能力不强的流计算技术往往不支持流批混算,即使表面支持,底层也是批、流两套引擎各算各的,需要事先转为同一类数据(通常是流数据),再用单一引擎(通常是流数据)进行伪混算。
SPL是专业的计算语言,流数据和批数据底层模型统一,单一引擎既能算流数据也能算批数据,自然也能直接进行混合计算,不必事先转为同类数据。
例子:Oracle与txt左关联,其中Oracle表太大无法读入内存。
A | B | |
1 | =connect("ORCL") | Oracle连接 |
2 | =A1.cursor@x("select OrderID,Amount,Client,SellerID,OrderDate from orders where OrderDate>? && OrderDate<=?",arg1,arg2) | Oracle有界流 |
3 | =T("d:/data/Employees.txt") | txt内存表 |
4 | =A2.join(SellerID,A3:EID,Dept) | oracle关联txt |
5 | =A4.groups(Dept, Client; sum(Amount),count(1)) | 分组汇总 |
有些混算在原理上必须转为同类数据再算,比如流+批的归并、批+流(量小且有界)的外关联,这种情况下需要进行流批间的类型转换。计算能力不强的流计算技术有多种流式结构化数据类型和批量结构化数据类型,转换关系繁多且互相难以直接转换,通常要硬编码实现。
SPL是专业的计算语言,只有序表(批)、游标(流)两种结构化数据类型,互相可以方便地转化。例子:将Oracle的流记录与外部传入的Json串进行归并关联。
A | B | |
1 | =connect("ORCL").cursor@x("select * from Orders Order by SellerID") | 有序流数据 |
2 | =json(arg_JsonStr).sort(EID) | 有序批数据 |
3 | =A2.cursor() | 批转流 |
4 | =joinx(A1,SellerID;A3,EID) | 双流归并 |
5 | =A4.groups(#2.Dept;sum(#1.Amount)) | 分组汇总 |
高级计算能力:简化复杂计算
SPL支持有序计算、集合计算、分步计算、关联计算,可以简化复杂的结构化数据计算。例子:计算每个传感器电压最高的3条记录:
data.group(SensorID).(~.top(3;V))
SPL有真正的行号字段,支持有序集合,可以用直观的代码进行计算,即先按SensorID分组,再对各组(即符号~)计算TopN。SPL的集合化更加彻底,可以实现真正的分组,即只分组不汇总,这就可以直观地计算组内数据。
例子:最大连续上涨天数:
A | |
1 | =tbl.sort(day) |
2 | =t=0,A1.max(t=if(price>price[-1],t+1,0)) |
SPL容易表达连续上涨的概念,先按日期排序;再遍历记录,发现上涨则计数器加1。代码中的max是循环函数,可依次遍历每条记录;代码中的[-1]是有序集合的用法,表示上一条,是相对位置的表示方法,price[-1]表示上一个交易日的股价,比整体移行(如SQL中的lag函数)更直观。
例子:求销售额占到一半的前n个客户:
A | B | |
2 | =sales.sort(amount:-1) | /销售额逆序排序,可在SQL中完成 |
3 | =A2.cumulate(amount) | /计算累计序列 |
4 | =A3.m(-1)/2 | /最后的累计即总额 |
5 | =A3.pselect(~>=A4) | /超过一半的位置 |
6 | =A2(to(A5)) | /按位置取值 |
SPL集合化成更彻底,可以用变量方便地表达集合,并在下一步用变量引用集合继续计算,因此特别适合多步骤计算。将大问题分解为多个小步骤,可以方便地实现复杂的计算目标,代码不仅简短,而且易于理解。此外,多步骤计算天然支持调试,无形中提高了开发效率。
SPL还支持游离记录,可以用点号直观地引用关联表,从而简化复杂的关联计算。
SPL有丰富的日期和字符串函数,能有效简化相关计算。
季度增减:elapse@q("2020-02-27",-3) //返回2019-05-27
N个工作日之后的日期:workday(date("2022-01-01"),25) //返回2022-02-04
字符串类函数,判断是否全为数字:isdigit("12345") //返回true
取子串前面的字符串:substr@l("abCDcdef","cd") //返回abCD
按竖线拆成字符串数组:"aa|bb|cc".split("|") //返回["aa","bb","cc"]
SPL还支持年份增减、求季度、按正则表达式拆分字符串、拆出单词、按标记拆HTML等大量函数。
值得一提的是,为了进一步提高开发效率,SPL还创造了独特的函数语法。比如用选项区分类似的函数,只过滤出符合条件的第1条记录,可使用选项@1:
T.select@1(Amount>1000)
从后往前查找第1条记录,可以使用@z:
T.select@z1(Amount>1000)
高级计算能力:高性能计算
SPL提供了大量高性能计算函数。有些函数(及语法)是独创的,可以用更低的时间复杂度达到同样的计算目标,比如遍历复用、倍增分段;有些函数是通用的,代码更简单用法更方便,比如二分查找、哈希索引。
SPL提供了高性能存储格式。高性能算法通常要基于高性能存储,像有序归并、单边分堆都要求数据有序才能实施,SPL 提供了名为组表的高性能外存存储格式,支持列存、有序、压缩、并行、分段、主键、索引等数据特征,信息密度和计算性能远高于普通格式,可极大提升加载速度,可充分释放高性算法的能力。SPL还提供了名为内表的高性能内存存储格式,支持内存压缩,可以与组表方便地互转,允许将更多的数据加载到内存,进行高性能内存计算。参考《SPL 计算性能系列测试:TPCH》
SPL支持温度分层和冷热路由。很多流数据产生的速度很快,计算涉及的数据又太多,必须先按温度(通常是时间)分层存储,并逐级溢出到下一层;计算时再按参数(通常是时间)路由到不同温度的数据,并进行混合计算。SPL支持并可简化这种计算结构,比如:计算涉及历史冷数据+近期温数据+实时热数据;秒/分钟级的热数据用内表存储,定期写入温数据;分钟/小时级的温数据用组表存储,定期写入冷数据;小时/天/月级的冷数据用RDB/数仓/数据湖存储,在必要时参与大跨度的混合计算。实际的项目结构更复杂分层更多,参考《超多位点高频时序数据的实时存储和统计》
SPL已开源免费,欢迎前往乾学院下载试用!
相关文章:
流计算需要框架吗?SPL 可能是更好的选择
流数据源通常是动态、无界的,看起来与静态、有限的批数据源区别较大,传统的数据库技术在架构上难以直接处理流数据源,只能让位于后来者。heron\samza\storm\spark\flink等计算框架最先完成突破,在流计算技术中占得先发优势。这些框…...
Vue-Router之嵌套路由
在路由配置中,配置children import Vue from vue import VueRouter from vue-routerVue.use(VueRouter)const router new VueRouter({mode: history,base: import.meta.env.BASE_URL,routes: [{path: /,redirect: /home},{path: /home,name: home,component: () &…...
MySQL 读写分离
MySQL 读写分离 一、配置主库(Master) 1.修改主库的配置文件 修改主库的 my.cnf 配置文件,生成二进制日志 (binary log) 和服务器唯一ID,这是实现主从复制的必要配置 [mysqld] # skip-grant-tables userroot port3306 basedir/usr/local/mysql datad…...
记一次音频无输出的解决方案
啊啊啊,刷个抖音就发现个死电脑死都不出声,捣鼓了一天才解决 打开wav文件时,提示错误找不到音频播放设备 0xc00d36fa 起初以为是声卡坏了,就到官网下载、更新了声卡驱动。无用什么驱动精灵也检测了,但也测不出啥来。…...
3D数学基础2
矩阵的行列式 在任意方阵中都存在至少一个标量,称作该方阵的行列式。在线性代数中,行列式有很多有用的性质 线性运算法则 方阵 M M M的行列式记作 ∣ M ∣ |M| ∣M∣或“det M”。非方阵矩阵的行列式是未定义的。 注意,在书写行列式时&…...
Java开发生态2024年度总结报告
1 关键要点 尽管数据显示 Java 17 是最常用 JDK,但其用户占比并未超过半数。根据 New Relic 2024 Java 生态系统状态报告,Java 17、11 和 8 的用户比例分别为 35%、33% 和 29%。New Relic 数据中所谓“快速采用”指 Java 21 的采用率仅为 1.4%。虽相较 J…...
1月第三讲:Java子线程无法获取Attributes的解决方法
在Java多线程编程中,开发者经常会遇到子线程无法获取主线程设置的Attributes的问题。Attributes通常用于存储与当前线程相关的数据,尤其在Web应用中,它们常用于请求上下文的管理。然而,由于Java线程是独立运行的,每个线…...
更新金碟云星空单据供应商和币别
--应付单 select FSUPPLIERID from [dbo].[T_AP_PAYABLE] where FBILLNO=AP2024121670 select FSUPPLIERID,FCURRENCYID,* from [dbo].[T_AP_PAYABLE] where FBILLNO=AP2024121670 -- update T_AP_PAYABLE set FSUPPLIERID=100567 where FBILLNO=AP2024121670 -- update T_…...
from memory cache 修复记录
背景 浏览器的页签图标,不想要了 改代码:设置浏览器页签的代码 本地环境测试,没有问题,一次性修改成功 于是打包,部署到测试环境,然而,还是有 接下的解决方法: 1、清除浏览器缓…...
spring入门程序
安装eclipse https://blog.csdn.net/qq_36437991/article/details/131644570 新建maven项目 安装依赖包 pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&quo…...
用于实现无缝滚动效果的vue-seamless-scroll插件
它通常用于在网页或应用中实现内容的自动滚动效果,如新闻公告、图片轮播等,支持横向和纵向滚动,并且可以自定义滚动速度、方向等参数,适合展示一些需要持续循环展示的信息。 在Vue2项目中使用vue-seamless-scroll插件的步骤如下&…...
借助 FinClip 跨端技术探索鸿蒙原生应用开发之旅
在当今数字化浪潮汹涌澎湃的时代,移动应用开发领域正经历着深刻的变革与创新。鸿蒙操作系统的崛起,以其独特的分布式架构和强大的性能表现,吸引了众多开发者的目光。而FinClip 跨端技术的出现,为开发者涉足鸿蒙原生应用开发提供了…...
【机器学习】机器学习的基本分类-自监督学习-对比学习(Contrastive Learning)
对比学习是一种自监督学习方法,其目标是学习数据的表征(representation),使得在表征空间中,相似的样本距离更近,不相似的样本距离更远。通过设计对比损失函数(Contrastive Loss)&…...
python之eval函数
功能:将字符串str当成有效的表达式来求值并返回计算结果 语法:eval(source,[,globals[,locals]])->value 参数: source:一个python表达式或函数compile()返回的代码对象globals:可选。必须是dictionarylocals&am…...
NXP i.MX8系列平台开发讲解 - 5.3 调试篇(二) - 掌握Dynamic debug调试
专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 文章目录 目录 掌握Dynamic debug调试 1. 认识Dynamic debug 2. 内核配置 3. 使用Dynamic debug 3.1 查看当前的…...
QT----------常用界面组件的使用
一、QComboBox 类 主要功能:提供一个下拉列表,用户可以从中选择一个或多个选项。 #include <QApplication> #include <QComboBox> #include <QVBoxLayout> #include <QWidget> #include <QMessageBox>int main(int argc…...
重新整理机器学习和神经网络框架
本篇重新梳理了人工智能(AI)、机器学习(ML)、神经网络(NN)和深度学习(DL)之间存在一定的包含关系,以下是它们的关系及各自内容,以及人工智能领域中深度学习分支对比整理。…...
AJAX详解
AJAX是前后端交互的重要工具 结合前后端交互基础理解:前后端交互详解(建议收藏)-CSDN博客 1. AJAX - 到底什么是Ajax? ajax 全名 async javascript and XML(异步JavaScript和XML),是一种用于向服务器异步发送 HTTP 请求并接收响应的技术。 XML 指可扩…...
golang中的异常处理机制
今天是2024最后一天,祝大家新年梦想成真,继续我的魅力golang,昨天发的错误处理,是明显的可预见、可恢复的问题,然而,不可预见的问题,往往更多,golang也有自己的一套,完全…...
HTML5 开关(Toggle Switch)详细讲解
HTML5 开关(Toggle Switch)详细讲解 1. 任务概述 开关(Toggle Switch)是一种用于表示二元状态(如开/关)的用户界面控件。用户可以通过点击开关来切换状态,常见于设置选项、开关功能等场景。 2…...
【前端】Node.js使用教程
目录 一、?Node.js开发环境和编译 1.1 安装Node.js 1.2 创建一个Node.js项目 1.3 编写Node.js程序 1.4 运行Node.js程序 1.5 使用Node.js模块 二、高级的Node.js编程概念和示例 2.1 异步编程 2.2 错误处理 2.3 网络请求 2.4 构建Web服务器 2.5 数据库交互 三、No…...
在CodeBlocks搭建SDL2工程构建TFT彩屏模拟器虚拟TFT彩屏幕显示
在CodeBlocks搭建SDL2工程构建TFT彩屏模拟器虚拟TFT彩屏幕显示 参考文章源码下载地址一、SDL2的创建、初始化、退出二、系统基本Tick、彩屏刷新、按键事件三、彩屏获取与设置颜色四、彩屏填充颜色及清屏五、彩屏显示中文和英文字符串六、彩屏显示数字七、彩屏初始化八、主函数测…...
BurstAttention:高效的分布式注意力计算框架
BurstAttention:高效的分布式注意力计算框架 在现代大型语言模型(LLMs)的应用中,提升注意力机制的计算效率已成为研究的热点。当前,提升计算效率主要有两种方法:一种是优化单设备的计算和存储能力…...
sentinel集成nacos启动报[check-update] get changed dataId error, code: 403错误排查及解决
整合nacos报403错误 因为平台写的一个限流代码逻辑有问题,所以准备使用sentinel来限流。平台依赖里面已经引入了,之前也测试过,把sentinel关于nacos的配置加上后,启动一直输出403错误 [fixed-10.0.20.188_8848-test] [check-upda…...
[TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器
背景:自己或者公司用一些谷歌身份验证器或者microsoft身份验证器,下载来源不明,或者有广告,使用不安全。于是自己写一个,安全放心使用。 代码已开源:shixiaotian/sxt-android-totp: android totp authenti…...
IDEA+Docker一键部署项目SpringBoot项目
文章目录 1. 部署项目的传统方式2. 前置工作3. SSH配置4. 连接Docker守护进程5. 创建简单的SpringBoot应用程序6. 编写Dockerfile文件7. 配置远程部署 7.1 创建配置7.2 绑定端口7.3 添加执行前要运行的任务 8. 部署项目9. 开放防火墙的 11020 端口10. 访问项目11. 可能遇到的问…...
【发票提取明细+发票号改名】批量提取PDF电子发票明细导出Excel表格并改名技术难点,批量PDF多区域内容识别提取明细并用内容改名的小结
1、图片版的发票提取表格改名 【批量图片发票识别表格】批量图片发票的提取Excel表格和提取字段改名,扫描发票识别表格,拍照发票识别表格,图片发票识别改名我们在工作中很多扫描发票,拍照发票,需要整理成excel表格&am…...
pyQT + OpenCV相关练习
一、设计思路 1、思路分析与设计 本段代码是一个使用 PyQt6 和 OpenCV 创建的图像处理应用程序。其主要功能是通过一个图形界面让用户对图片进行基本的图像处理操作,如灰度化、翻转、旋转、亮度与对比度调整,以及一些滤镜效果(模糊、锐化、边…...
石岩路边理发好去处
周末带娃去罗租公园玩,罗租公园旁边就是百佳华和如意豪庭小区,发现如意豪庭小区对面挺多路边理发摊点 理发摊点聚焦在这里的原因是刚好前面城管来了暂时避避,例如还有一个阿姨剪到一半就跟着过来。这里的城管只是拍了一处没有摊位的地方&…...
音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件
一、错误的命令 通过FFmpeg命令可以将mp4文件转换为ps文件,PS文件中包含PS流数据。 由于PS流/PS文件对应的FFInputFormat结构为: const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL…...
整合版canal ha搭建--基于1.1.4版本
开启MySql Binlog(1)修改MySql配置文件(2)重启MySql服务,查看配置是否生效(3)配置起效果后,创建canal用户,并赋予权限安装canal-admin(1)解压 canal.admin-1…...
[python SQLAlchemy数据库操作入门]-15.联合查询,跨表获取股票数据
哈喽,大家好,我是木头左! 在开始探讨如何利用SQLAlchemy实现复杂的联合查询之前,首先需要深入理解其核心组件——对象关系映射(ORM)。ORM允许开发者使用Python类来表示数据库中的表,从而以一种更直观、面向对象的方式来操作数据库。 SQLAlchemy中的JOIN操作详解 在SQLA…...
PTA数据结构作业一
6-1 链表的插入算法 本题要求实现一个插入函数,实现在链表llist中的元素x之后插入一个元素y的操作。 函数接口定义: int InsertPost_link(LinkList llist, DataType x, DataType y); 其中 llist是操作的链表,x是待插入元素y的前驱节点元素…...
前端(九)js介绍(2)
js介绍(2) 文章目录 js介绍(2)一、函数1.1函数的两种形式1.2函数的作用域1.3声明与提升 二、bom操作三、dom操作 一、函数 1.1函数的两种形式 //有参函数 //js中的函数只能返回一个值,如果要返回多个需要放在数组或对象中 function func(a,b){return ab } func(1,…...
CUTLASS:高性能 CUDA 线性代数模板库详解
CUTLASS:高性能 CUDA 线性代数模板库详解 引言什么是 CUTLASS?CUTLASS 的主要特点: CUTLASS 的用途如何安装 CUTLASS1. 环境准备2. 下载 CUTLASS3. 构建 CUTLASS4. 设置环境变量5. 验证安装 使用 CUTLASSCUTLASS 的优势总结 引言 在深度学习…...
关于CISP报名费用详情
CISP即“注册信息安全专业人员”,是中国信息安全测评中心实施的国家认证项目,旨在培养信息安全领域的专业人才。对于有意报考CISP的考生而言,了解报名考试费用是备考过程中不可或缺的一环。 CISP的报名考试费用主要包括培训费用、考试费用、…...
css 关于flex布局中子元素的属性flex
css flex布局中子元素的属性flex 1. flex 是 flex-grow、flex-shrink 和 flex-basis 的简写 语法格式: flex: [flex-grow] [flex-shrink] [flex-basis];各属性解析: flex-grow: 子元素如何按比例分配父元素的 剩余空间。 默认值:0&#…...
功率器件热设计基础(四)——功率半导体芯片温度和测试方法
/ 前言 / 功率半导体热设计是实现IGBT、碳化硅SiC高功率密度的基础,只有掌握功率半导体的热设计基础知识,才能完成精确热设计,提高功率器件的利用率,降低系统成本,并保证系统的可靠性。 功率器件热设计基础系列文章会…...
OpenStack系列第四篇:云平台基础功能与操作(Dashboard)
文章目录 1. 镜像(Image)添加镜像查看镜像删除镜像 2. 卷(Volume)创建卷查看卷删除卷 3. 网络(虚拟网络)创建网络查看网络删除网络 4. 实例类型创建实例类型查看实例类型删除实例类型 4. 密钥对(…...
WebSocket封装
提示:记录工作中遇到的需求及解决办法 文章目录 前言二、背景三、WebSocket3.1 什么是 WebSocket ?为什么使用他?四、封装 WebSocket4.1 Javascript 版本4.2 Typescript 版本4.3 如何使用?五、我的痛点如何处理前言 本文将介绍 WebSocket 的封装,比如:心跳机制,重连和一…...
面试题解,JVM的运行时数据区
一、请简述JVM运行时数据区的组成结构及各部分作用 总览 从线程持有的权限来看 线程私有区 虚拟机栈 虚拟机栈是一个栈结构,由许多个栈帧组成,一个方法分配一个栈帧,线程每执行一个方法时都会有一个栈帧入栈,方法执行结束后栈帧…...
【Ubuntu使用技巧】Ubuntu22.04无人值守Crontab工具实战详解
一个愿意伫立在巨人肩膀上的农民...... Crontab是Linux和类Unix操作系统下的一个任务调度工具,用于周期性地执行指定的任务或命令。Crontab允许用户创建和管理计划任务,以便在特定的时间间隔或时间点自动运行命令或脚本。这些任务可以按照分钟、小时、日…...
Caffeine Cache Java缓存组件
缓存组件Caffeine Cache 定义介绍整合springboot用法整合spring-boot-starter-cache用法 定义介绍 特性 高性能:基于高效并发设计和 TinyLFU 算法,命中率高。 丰富策略:支持容量限制、过期时间、异步加载、自定义清理策略。 统计监控&#x…...
电子电气架构 --- 什么是自动驾驶技术中的域控制单元(DCU)?
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...
Redis核心技术知识点全集
Redis数据结构和常用命令 1. String字符串2. Hash哈希3. List列表4. Set集合5. Sorted Set有序集合6. Redis常用命令参考Redis事务机制...
【每日学点鸿蒙知识】文件读写、屏幕宽度亮度、扫一扫权限、编码器问题、wlan设置
1、参照文档,在操作文件时,读取不到内容或出现程序闪退? 参照文档,进行文件写入和读取时,出现读取不到或闪退 export function createFile() {// 获取应用文件路径let context getContext(this) as common.UIAbilit…...
后端开发-Maven
环境说明: windows系统:11版本 idea版本:2023.3.2 Maven 介绍 Apache Maven 是一个 Java 项目的构建管理和理解工具。Maven 使用一个项目对象模型(POM),通过一组构建规则和约定来管理项目的构建…...
LiteFlow 流程引擎引入Spring boot项目集成pg数据库
文章目录 官网地址简要项目引入maven 所需jar包配置 PostgreSQL 数据库表使用LiteFlow配置 yml 文件通过 代码方式使用 liteflow数据库sql 数据在流程中周转 官网地址 https://liteflow.cc/ 简要 如果你要对复杂业务逻辑进行新写或者重构,用LiteFlow最合适不过。…...
电子电气架构 --- 汽车电子电器设计概述
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...
API 设计:从基础到最佳实践
https://levelup.gitconnected.com/api-design-101-from-basics-to-best-practices-a0261cdf8886 在本次深入研究中,我们将从基础开始,逐步了解 API 设计,并逐步实现定义卓越 API 的最佳实践。 作为开发人员,您可能熟悉其中的许多…...