租号网站怎么做的/谷歌浏览器下载
Table API 和 DataStream API 在定义数据处理管道时同样重要。DataStream API 提供了流处理的基本操作(即时间、状态和数据流管理),并且是一个相对低级的命令式编程 API。而 Table API 抽象了许多内部实现,提供了一个结构化和声明式的 API。这两个 API 都可以处理有界流和无界流。
有界流需要在处理历史数据时进行管理。无界流通常出现在实时处理场景中,可能会先通过历史数据初始化。为了高效执行,两个 API 都提供了通过优化的批处理执行模式来处理有界流。然而,由于批处理只是流处理的一个特殊情况,处理有界流的管道也可以在常规流处理模式下运行。在一个 API 中可以定义端到端的管道,而无需依赖另一个 API。然而,混合使用这两个 API 在某些情况下可能会有益:
- 在实现 DataStream API 的主要管道之前,使用 Table API 访问目录或连接外部系统。
- 在实现 DataStream API 的主要管道之前,使用一些 SQL 函数进行无状态的数据归一化和清洗。
- 如果需要更低级的操作(例如自定义定时器处理),可以切换到 DataStream API,因为 Table API 中没有提供这些功能。
- Flink 提供了特别的桥接功能,使得与 DataStream API 的集成尽可能顺畅。
1. Converting between DataStream and Table
Flink 提供了一个专门的 StreamTableEnvironment 用于与 DataStream API 集成。这个环境在常规的 TableEnvironment 基础上扩展了额外的方法,并以 DataStream API 中使用的 StreamExecutionEnvironment 作为参数。
以下代码展示了如何在两个 API 之间来回转换。表的列名和类型会自动从 DataStream 的 TypeInformation 中推导出来。由于 DataStream API 本身不支持变更日志处理,因此在流到表和表到流的转换过程中,假设使用的是仅追加/仅插入的语义。
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;// create environments of both APIs
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// create a DataStream
DataStream<String> dataStream = env.fromElements("Alice", "Bob", "John");// interpret the insert-only DataStream as a Table
Table inputTable = tableEnv.fromDataStream(dataStream);// register the Table object as a view and query it
tableEnv.createTemporaryView("InputTable", inputTable);
Table resultTable = tableEnv.sqlQuery("SELECT UPPER(f0) FROM InputTable");// interpret the insert-only Table as a DataStream again
DataStream<Row> resultStream = tableEnv.toDataStream(resultTable);// add a printing sink and execute in DataStream API
resultStream.print();
env.execute();// prints:
// +I[ALICE]
// +I[BOB]
// +I[JOHN]
根据查询的类型,在许多情况下,结果动态表是一个管道,在将 Table 转换为 DataStream 时,不仅会生成仅插入的变化,还可能生成撤回和其他类型的更新。在表到流的转换过程中,这可能会导致类似的异常。表接收器 'Unregistered_DataStream_Sink' 不支持消费更新变化 [...] ,在这种情况下,需要重新审查查询或切换到 toChangelogStream
。
以下示例展示了如何转换更新表。每个结果行表示变更日志中的一条记录,变更标志可以通过调用 row.getKind()
来查询。在示例中,Alice 的第二个分数会在变更前创建一个更新标志 (-U),并在变更后创建一个更新标志 (+U)。
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;// create environments of both APIs
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// create a DataStream
DataStream<Row> dataStream = env.fromElements(Row.of("Alice", 12),Row.of("Bob", 10),Row.of("Alice", 100));// interpret the insert-only DataStream as a Table
Table inputTable = tableEnv.fromDataStream(dataStream).as("name", "score");// register the Table object as a view and query it
// the query contains an aggregation that produces updates
tableEnv.createTemporaryView("InputTable", inputTable);
Table resultTable = tableEnv.sqlQuery("SELECT name, SUM(score) FROM InputTable GROUP BY name");// interpret the updating Table as a changelog DataStream
DataStream<Row> resultStream = tableEnv.toChangelogStream(resultTable);// add a printing sink and execute in DataStream API
resultStream.print();
env.execute();// prints:
// +I[Alice, 12]
// +I[Bob, 10]
// -U[Alice, 12]
// +U[Alice, 112]
上面的示例展示了如何通过持续地逐行发布更新来增量地计算最终结果。然而,在输入流是有限的(即有界)的情况下,可以利用批处理原则更高效地计算结果。
在批处理处理中,操作符可以在多个阶段中执行,这些阶段会先消费整个输入表,然后再发出结果。例如,连接操作符可以在执行实际连接之前对两个有界输入进行排序(即排序合并连接算法),或者在消费另一个输入之前从一个输入构建哈希表(即哈希连接算法的构建/探测阶段)。
DataStream API 和 Table API 都提供了专门的批处理运行时模式。
以下示例说明了通过简单地切换标志,统一管道能够同时处理批处理和流数据。
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;// setup DataStream API
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();// set the batch runtime mode
env.setRuntimeMode(RuntimeExecutionMode.BATCH);// uncomment this for streaming mode
// env.setRuntimeMode(RuntimeExecutionMode.STREAMING);// setup Table API
// the table environment adopts the runtime mode during initialization
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// define the same pipeline as above// prints in BATCH mode:
// +I[Bob, 10]
// +I[Alice, 112]// prints in STREAMING mode:
// +I[Alice, 12]
// +I[Bob, 10]
// -U[Alice, 12]
// +U[Alice, 112]
一旦变更日志应用到外部系统(例如键值存储),可以看到两种模式都能够产生完全相同的输出表。通过在发出结果之前消费所有输入数据,批处理模式的变更日志仅包含插入类型的变化。
1.1 Dependencies and Imports
结合 Table API 和 DataStream API 的项目需要添加以下其中一个桥接模块。这些模块包括了 flink-table-api-java
或 flink-table-api-scala
的传递依赖,以及相应语言特定的 DataStream API 模块。
<dependency><groupId>org.apache.flink</groupId><artifactId>flink-table-api-java-bridge_2.12</artifactId><version>1.20.0</version><scope>provided</scope>
</dependency>
以下导入是声明使用 Java 或 Scala 版本的 DataStream API 和 Table API 的公共管道所必需的。
// imports for Java DataStream API
import org.apache.flink.streaming.api.*;
import org.apache.flink.streaming.api.environment.*;// imports for Table API with bridging to Java DataStream API
import org.apache.flink.table.api.*;
import org.apache.flink.table.api.bridge.java.*;
1.2 Configuration
TableEnvironment 将采用传入的 StreamExecutionEnvironment 的所有配置选项。然而,在实例化之后,无法保证对 StreamExecutionEnvironment 配置的进一步更改会传播到 StreamTableEnvironment。建议在切换到 Table API 之前,尽早在 DataStream API 中设置所有配置选项。
import java.time.ZoneId;
import org.apache.flink.core.execution.CheckpointingMode.CheckpointingMode;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;// create Java DataStream APIStreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();// set various configuration earlyenv.setMaxParallelism(256);env.getConfig().addDefaultKryoSerializer(MyCustomType.class, CustomKryoSerializer.class);env.getCheckpointConfig().setCheckpointingConsistencyMode(CheckpointingMode.EXACTLY_ONCE);// then switch to Java Table APIStreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// set configuration earlytableEnv.getConfig().setLocalTimeZone(ZoneId.of("Europe/Berlin"));// start defining your pipelines in both APIs...
1.3 Execution Behavior
两个 API 都提供了执行管道的方法。换句话说:如果需要,它们会编译一个作业图并提交到集群,触发执行。结果将被流式传输到声明的接收器。通常,两个 API 都在方法名称中使用 execute
来标识这种行为。然而,Table API 和 DataStream API 之间的执行行为略有不同。
1.3.1 DataStream API
DataStream API 的 StreamExecutionEnvironment 使用构建器来构建复杂的管道。该管道可能会拆分成多个分支,这些分支可能会或可能不会以Sink结束。执行环境会缓冲所有这些定义的分支,直到提交作业为止。StreamExecutionEnvironment.execute()
提交整个构建的管道,并在之后清除构建器。换句话说:不再声明Source和Sink,可以将新的管道添加到构建器中。因此,每个 DataStream 程序通常以调用 StreamExecutionEnvironment.execute()
结束。或者,DataStream.executeAndCollect()
会隐式地为结果流式传输到本地客户端定义一个Sink
1.3.2 Table API
在 Table API 中,分支管道仅在 StatementSet 中受到支持,其中每个分支必须声明一个最终的Sink。TableEnvironment 和 StreamTableEnvironment 都不提供专门的通用 execute()
方法。相反,它们提供了提交单个Source到Sink管道或StatementSet的方法:
// execute with explicit sink
tableEnv.from("InputTable").insertInto("OutputTable").execute();tableEnv.executeSql("INSERT INTO OutputTable SELECT * FROM InputTable");tableEnv.createStatementSet().add(tableEnv.from("InputTable").insertInto("OutputTable")).add(tableEnv.from("InputTable").insertInto("OutputTable2")).execute();tableEnv.createStatementSet().addInsertSql("INSERT INTO OutputTable SELECT * FROM InputTable").addInsertSql("INSERT INTO OutputTable2 SELECT * FROM InputTable").execute();// execute with implicit local sinktableEnv.from("InputTable").execute().print();tableEnv.executeSql("SELECT * FROM InputTable").print();
为了结合这两种执行行为,每次调用 StreamTableEnvironment.toDataStream
或 StreamTableEnvironment.toChangelogStream
时,会将 Table API 子管道物化(即编译)并插入到 DataStream API 管道构建器中。这意味着之后必须调用 StreamExecutionEnvironment.execute()
或 DataStream.executeAndCollect
。在 Table API 中的执行不会触发这些“外部部分”。
// (1)// adds a branch with a printing sink to the StreamExecutionEnvironment
tableEnv.toDataStream(table).print();// (2)// executes a Table API end-to-end pipeline as a Flink job and prints locally,
// thus (1) has still not been executed
table.execute().print();// executes the DataStream API pipeline with the sink defined in (1) as a
// Flink job, (2) was already running before
env.execute();
2. Batch Runtime Mode
批处理运行时模式是针对有界 Flink 程序的专门执行模式。一般来说,有界性是数据源的一个属性,它告诉我们该数据源中所有记录在执行前是否已知,或者是否会出现新的数据,可能是无限期的。一个作业,如果其所有数据源都是有界的,则该作业是有界的,否则就是无界的。另一方面,流处理运行时模式可以用于有界和无界作业。Table API 和 SQL planner为这两种模式提供了一组专门的优化器规则和运行时操作符。目前,运行时模式不会自动从数据源推导出来,因此,必须显式设置,或者在实例化 StreamTableEnvironment
时从 StreamExecutionEnvironment
继承。
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;// adopt mode from StreamExecutionEnvironment
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setRuntimeMode(RuntimeExecutionMode.BATCH);
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// or// set mode explicitly for StreamTableEnvironment
// it will be propagated to StreamExecutionEnvironment during planning
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env, EnvironmentSettings.inBatchMode());
在将运行时模式设置为 BATCH 之前,必须满足以下前提条件:
- 所有数据源必须声明自己为有界的。
- 当前,表数据源必须仅发出插入(insert-only)变化。
- 操作符需要足够的堆外内存来进行排序和处理其他中间结果。
- 所有表操作必须在批处理模式下可用。当前,某些操作仅在流处理模式下可用。
批处理执行具有以下含义(其中包括但不限于):
- 操作符中不会生成或使用渐进watermarks。然而,数据源在关闭之前会发出一个最大watermarks。
- 任务之间的交换可能是阻塞的,这取决于
execution.batch-shuffle-mode
。这也意味着与在流处理模式下执行相同管道相比,可能会需要更少的资源。 - 检查点(Checkpointing)被禁用。插入了人工状态后端(Artificial state backends)。
- 表操作不会产生增量更新,而是只生成一个完整的最终结果,并转换为一个仅插入的变更日志流。
由于批处理可以视为流处理的特例,我们建议首先实现一个流处理管道,因为它是有界和无界数据的最通用实现。理论上,流处理管道可以执行所有操作符。然而,实际上,某些操作可能没有太大意义,因为它们会导致状态不断增长,因此不被支持。全局排序就是一个例子,它仅在批处理模式下可用。简而言之:应该可以在批处理模式下运行一个正常工作的流处理管道,但不一定能够反过来运行。
以下示例展示了如何使用 DataGen 表数据源在批处理模式下进行操作。许多数据源提供的选项可以隐式地使连接器变为有界,例如通过定义终止偏移量或时间戳。在我们的示例中,我们通过 number-of-rows
选项限制了行数。
import org.apache.flink.table.api.DataTypes;
import org.apache.flink.table.api.Schema;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.TableDescriptor;Table table =tableEnv.from(TableDescriptor.forConnector("datagen").option("number-of-rows", "10") // make the source bounded.schema(Schema.newBuilder().column("uid", DataTypes.TINYINT()).column("payload", DataTypes.STRING()).build()).build());// convert the Table to a DataStream and further transform the pipeline
tableEnv.toDataStream(table).keyBy(r -> r.<Byte>getFieldAs("uid")).map(r -> "My custom operator: " + r.<String>getFieldAs("payload")).executeAndCollect().forEachRemaining(System.out::println);// prints:
// My custom operator: 9660912d30a43c7b035e15bd...
// My custom operator: 29f5f706d2144f4a4f9f52a0...
// ...
2.1 Changelog Unification
在大多数情况下,从流处理模式切换到批处理模式,反之亦然,管道定义本身在 Table API 和 DataStream API 中可以保持不变。然而,如前所述,由于批处理模式避免了增量操作,最终的变更日志流可能会有所不同。依赖于事件时间并利用水印作为完整性标记的基于时间的操作,能够生成一个仅插入的变更日志流,这与运行时模式无关。
以下 Java 示例展示了一个 Flink 程序,它不仅在 API 层面上是统一的,而且在最终生成的变更日志流中也是统一的。该示例使用基于两张表(UserTable 和 OrderTable)中时间属性(ts)的区间连接(interval join)来连接两张表。它使用 DataStream API 实现了一个自定义操作符,该操作符通过 KeyedProcessFunction 和值状态去重用户名。
import org.apache.flink.api.common.functions.OpenContext;
import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.table.api.DataTypes;
import org.apache.flink.table.api.Schema;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;
import org.apache.flink.util.Collector;
import java.time.LocalDateTime;// setup DataStream API
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();// use BATCH or STREAMING mode
env.setRuntimeMode(RuntimeExecutionMode.BATCH);// setup Table API
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);// create a user stream
DataStream<Row> userStream = env.fromElements(Row.of(LocalDateTime.parse("2021-08-21T13:00:00"), 1, "Alice"),Row.of(LocalDateTime.parse("2021-08-21T13:05:00"), 2, "Bob"),Row.of(LocalDateTime.parse("2021-08-21T13:10:00"), 2, "Bob")).returns(Types.ROW_NAMED(new String[] {"ts", "uid", "name"},Types.LOCAL_DATE_TIME, Types.INT, Types.STRING));// create an order stream
DataStream<Row> orderStream = env.fromElements(Row.of(LocalDateTime.parse("2021-08-21T13:02:00"), 1, 122),Row.of(LocalDateTime.parse("2021-08-21T13:07:00"), 2, 239),Row.of(LocalDateTime.parse("2021-08-21T13:11:00"), 2, 999)).returns(Types.ROW_NAMED(new String[] {"ts", "uid", "amount"},Types.LOCAL_DATE_TIME, Types.INT, Types.INT));// create corresponding tables
tableEnv.createTemporaryView("UserTable",userStream,Schema.newBuilder().column("ts", DataTypes.TIMESTAMP(3)).column("uid", DataTypes.INT()).column("name", DataTypes.STRING()).watermark("ts", "ts - INTERVAL '1' SECOND").build());tableEnv.createTemporaryView("OrderTable",orderStream,Schema.newBuilder().column("ts", DataTypes.TIMESTAMP(3)).column("uid", DataTypes.INT()).column("amount", DataTypes.INT()).watermark("ts", "ts - INTERVAL '1' SECOND").build());// perform interval join
Table joinedTable =tableEnv.sqlQuery("SELECT U.name, O.amount " +"FROM UserTable U, OrderTable O " +"WHERE U.uid = O.uid AND O.ts BETWEEN U.ts AND U.ts + INTERVAL '5' MINUTES");DataStream<Row> joinedStream = tableEnv.toDataStream(joinedTable);joinedStream.print();// implement a custom operator using ProcessFunction and value state
joinedStream.keyBy(r -> r.<String>getFieldAs("name")).process(new KeyedProcessFunction<String, Row, String>() {ValueState<String> seen;@Overridepublic void open(OpenContext openContext) {seen = getRuntimeContext().getState(new ValueStateDescriptor<>("seen", String.class));}@Overridepublic void processElement(Row row, Context ctx, Collector<String> out)throws Exception {String name = row.getFieldAs("name");if (seen.value() == null) {seen.update(name);out.collect(name);}}}).print();// execute unified pipeline
env.execute();// prints (in both BATCH and STREAMING mode):
// +I[Bob, 239]
// +I[Alice, 122]
// +I[Bob, 999]
//
// Bob
// Alice
相关文章:

Flink (十三) :Table API 与 DataStream API 的转换 (一)
Table API 和 DataStream API 在定义数据处理管道时同样重要。DataStream API 提供了流处理的基本操作(即时间、状态和数据流管理),并且是一个相对低级的命令式编程 API。而 Table API 抽象了许多内部实现,提供了一个结构化和声明…...

Android --- handler详解
handler 理解 handler 是一套Android 消息传递机制,主要用于线程间通信。 tips: binder/socket 用于进程间通信。 参考: Android 进程间通信-CSDN博客 handler 就是主线程在起了一个子线程,子线程运行并生成message ,l…...

[EAI-023] FAST,机器人动作专用的Tokenizer,提高VLA模型的能力和训练效率
Paper Card 论文标题:FAST: Efficient Action Tokenization for Vision-Language-Action Models 论文作者:Karl Pertsch, Kyle Stachowicz, Brian Ichter, Danny Driess, Suraj Nair, Quan Vuong, Oier Mees, Chelsea Finn, Sergey Levine 论文链接&…...

关于贪心学习的文笔记录
贪心,顾名思义就是越贪越好,越多越有易,他给我的感觉是,通常是求最大或最小问题,相比于动态规划贪心让人更加琢磨不透,不易看出方法,为此在这记录我所见过的题型和思维方法,以便回头…...

SLAM技术栈 ——《视觉SLAM十四讲》学习笔记(一)
《视觉SLAM十四讲》学习笔记(一) 第2讲 初识SLAM习题部分 第3讲 三维空间刚体运动3.1 左手系与右手系3.2 齐次坐标3.3 旋转矩阵与变换矩阵3.4 正交群与欧式群3.5 旋转向量与欧拉角3.6 实践Eigen线性代数库3.6.1 QR分解(QR decomposition) 3.7 四元数到其…...

【ChatGPT:开启人工智能新纪元】
一、ChatGPT 是什么 最近,ChatGPT 可是火得一塌糊涂,不管是在科技圈、媒体界,还是咱们普通人的日常聊天里,都能听到它的大名。好多人都在讨论,这 ChatGPT 到底是个啥 “神器”,能让大家这么着迷?今天咱就好好唠唠。 ChatGPT,全称是 Chat Generative Pre-trained Trans…...

1. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--前言
在我们的专栏《单体开发》中,我们实现了一个简单的记账软件的服务端,并且成功上线。随着用户数量的不断增长,问题逐渐开始显现。访问量逐渐增加,服务端的压力也随之加大。随着访问量的攀升,服务端的响应时间变得越来越…...

量子力学初步:微观领域的科学之旅
飞书📚链接:量子力学篇 长尾 - 什么是量子力学 (未完成… 等有时间再看,前面的内容可以参考下,比如了解自旋、以及斯特恩-盖拉赫实验) 【量子力学篇-01期】经典物理学的终结,量子力学的开端 量…...

趣味Python100例初学者练习01
1. 1 抓交通肇事犯 一辆卡车违反交通规则,撞人后逃跑。现场有三人目击该事件,但都没有记住车号,只记下了车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前…...

postgresql的用户、数据库和表
在 PostgreSQL 中,用户、数据库和表是关系型数据库系统的基本组成部分。理解这些概念对数据库管理和操作至关重要。下面是对这些概念的详细解释: 1. 用户(User) 在 PostgreSQL 中,用户(也称为 角色&#…...

对游戏宣发的粗浅思考
1.两极分化 认真观摩了mgs系列制作人的x账号, 其更新频率吓死人,一天能发几十条之多,吓死人。大部分都是转发相关账号的ds2或mgs相关内容, 每日刻意的供给这些内容来满足几十万粉丝需求,维护热情。 幕后是专业的公…...

【Java基础-42.3】Java 基本数据类型与字符串之间的转换:深入理解数据类型的转换方法
在 Java 开发中,基本数据类型与字符串之间的转换是非常常见的操作。无论是从用户输入中读取数据,还是将数据输出到日志或界面,都需要进行数据类型与字符串之间的转换。本文将深入探讨 Java 中基本数据类型与字符串之间的转换方法,…...

(9) 上:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同
(1)经过之前的学习。俺认为结论是这样的,因为三次握手到四次挥手,到 RST 报文,都是 tcp 连接上收到了报文,这都属于读事件。所以: EPOLLIN : 包含了读事件, FIN 报文的正常四次挥手、…...

webpack传输性能优化
手动分包 基本原理 手动分包的总体思路是:先打包公共模块,然后再打包业务代码。 打包公共模块 公共模块会被打包成为动态链接库(dll Dynamic Link Library),并生成资源清单。 打包业务代码 打包时,如果…...

智能小区物业管理系统打造高效智能社区服务新生态
内容概要 随着城市化进程的不断加快,智能小区物业管理系统的出现,正逐步改变传统物业管理的模式,为社区带来了崭新的管理理念和服务方式。该系统不仅提升了物业管理效率,还加强了业主与物业之间的互动,为每位居民提供…...

(done) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)
网页:https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html (任务1教会了你如何用 C 语言调用汇编,编译后链接即可) 任务1:Uthread: switching between threads (完成) 在这个练习中,你将设计一个用户级线程系统中的上下文切…...

面试经典150题——栈
文章目录 1、有效的括号1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、最小栈3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、逆波兰表达式求值4.1 题目链接4.2 题目描述4.3 解题代码4.4 解题思路 5、基本…...

openmv的端口被拆分为两个 导致电脑无法访问openmv文件系统解决办法 openmv USB功能改动 openmv驱动被更改如何修复
我之前误打误撞遇到一次,直接把openmv的全部端口删除卸载然后重新插上就会自动重新装上一个openmv端口修复成功,大家可以先试试不行再用下面的方法 全部卸载再重新插拔openmv 要解决OpenMV IDE中出现的两个端口问题,可以尝试以下步骤&#x…...

自制虚拟机(C/C++)(三、做成标准GUI Windows软件,扩展指令集,直接支持img软盘)
开源地址:VMwork 要使终端不弹出, #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") 还要实现jmp near 0x01类似的 本次的main.cpp #include <graphics.h> #include <conio.h> #include <windows.h> #includ…...

算法题(56):旋转链表
审题: 我们需要根据k的大小把链表向右移动对应次数,并返回移动后的链表的头结点指针 思路: 根据提示中的数据大小我们发现:k的值可以远大于节点数。 也就是说我们对链表的操作存在周期,如果k%len0,说明我们…...

解决PyG安装中torch-sparse安装失败问题:详细指南
1 问题描述 最近在学习GNN,需要使用PyTorch Geometric(PyG)库。在安装PyG的过程中,遇到了torch-sparse安装失败的问题,错误提示为: ERROR: Failed building wheel for torch-sparse本文将详细记录问题的解…...

如何创建折叠式Title
文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了SliverGrid组件相关的内容,本章回中将介绍SliverAppBar组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的SliverAppBar和普通的AppBar类似,它们的…...

go-zero学习笔记(三)
利用goctl生成rpc服务 编写proto文件 // 声明 proto 使用的语法版本 syntax "proto3";// proto 包名 package demoRpc;// golang 包名(可选) option go_package "./demo";// 如需为 .proto 文件添加注释,请使用 C/C 样式的 // 和 /* ... */…...

Wildcard工具详解:从入门到精通
1. Wildcard基础知识 什么是Wildcard? Wildcard(通配符)是一种用于匹配文件名或字符串的特殊字符。它允许用户使用简单的符号来表示复杂的匹配规则,从而快速定位目标文件或数据。 常见的Wildcard符号 *:匹配任意数量…...

冰蝎v3.0 beta7来啦
我用了一台kali,一台centos,一台windows,做了一个文件上传和一个反弹shell实验,载荷是AES加密的,终于感受到了对加密流量的无可奈何~ kali(php8.1)centos(php7.1)window…...

React中使用箭头函数定义事件处理程序
React中使用箭头函数定义事件处理程序 为什么使用箭头函数?1. 传递动态参数2. 避免闭包问题3. 确保每个方块的事件处理程序是独立的4. 代码可读性和维护性 示例代码总结 在React开发中,处理事件是一个常见的任务。特别是当我们需要传递动态参数时&#x…...

记忆化搜索和动态规划 --最长回文子串为例
记忆化搜索 记忆化搜索是一种优化递归算法的方法,通过将已经计算过的子问题的结果存储起来(通常使用哈希表或数组),避免重复计算相同的子问题。 本质上是通过缓存中间结果来减少计算的重复性。 动态规划 动态规划是通过将问题分…...

Tree Compass( Codeforces Round 934 (Div. 2) )
Tree Compass( Codeforces Round 934 (Div. 2) ) You are given a tree with n n n vertices numbered 1 , 2 , … , n 1, 2, \ldots, n 1,2,…,n. Initially, all vertices are colored white. You can perform the following two-step operation: …...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.17 掩码数组:缺失值处理的优雅方案
2.17 掩码数组:缺失值处理的优雅方案 目录 #mermaid-svg-12vjJJbyudPnkYBO {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-12vjJJbyudPnkYBO .error-icon{fill:#552222;}#mermaid-svg-12vjJJbyudPnkYBO…...

PHP 常用函数2025.02
PHP implode() 函数 语法 implode(separator,array) 参数描述separator可选。规定数组元素之间放置的内容。默认是 ""(空字符串)。array必需。要组合为字符串的数组。 技术细节 返回值:返回一个由数组元素组合成的字符串。PHP 版…...