DataStream编程模型之数据源、数据转换、数据输出
Flink之DataStream数据源、数据转换、数据输出(scala)
0.前言–数据源
在进行数据转换之前,需要进行数据读取。
数据读取分为4大部分:
(1)内置数据源;
又分为文件数据源;
socket数据源;

集合数据源三类

(2)Kafka数据源






第二个参数用到的SimpleStringSchema对象是一个内置的DeserializationSchema对象,可以把字节数据反序列化程一个String对象。
另外,FlinkKafkaConsumer开始读取Kafka消息时,可以配置他的 读 起始位置,有如下四种。

import java.util.Properties
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.windowing.time.Time
object KafkaWordCount {def main(args: Array[String]): Unit = {val kafkaProps = new Properties()//Kafka的一些属性kafkaProps.setProperty("bootstrap.servers", "localhost:9092")//所在的消费组kafkaProps.setProperty("group.id", "group1")//获取当前的执行环境val evn = StreamExecutionEnvironment.getExecutionEnvironment
//创建Kafka的消费者,wordsendertest是要消费的Topicval kafkaSource = new FlinkKafkaConsumer[String]("wordsendertest",new SimpleStringSchema,kafkaProps)//设置从最新的offset开始消费kafkaSource.setStartFromLatest()//自动提交offset
kafkaSource.setCommitOffsetsOnCheckpoints(true)//绑定数据源val stream = evn.addSource(kafkaSource)//设置转换操作逻辑val text = stream.flatMap{ _.toLowerCase().split("\\W+")filter{ _.nonEmpty} }.map{(_,1)}.keyBy(0).timeWindow(Time.seconds(5)).sum(1)//打印输出text.print()//程序触发执行evn.execute("Kafka Word Count")}
}
(3)HDFS数据源

(4)自定义数据源

一个例子:
import java.util.Calendar
import org.apache.flink.streaming.api.functions.source.RichSourceFunction
import org.apache.flink.streaming.api.functions.source.SourceFunction.SourceContext
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import scala.util.Randomcase class StockPrice(stockId:String,timeStamp:Long,price:Double)
object StockPriceStreaming {def main(args: Array[String]) { //设置执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设置程序并行度
env.setParallelism(1)
//股票价格数据流val stockPriceStream: DataStream[StockPrice] = env//该数据流由StockPriceSource类随机生成.addSource(new StockPriceSource)//打印结果stockPriceStream.print()//程序触发执行env.execute("stock price streaming")}class StockPriceSource extends RichSourceFunction[StockPrice]{ var isRunning: Boolean = trueval rand = new Random()//初始化股票价格var priceList: List[Double] = List(10.0d, 20.0d, 30.0d, 40.0d, 50.0d)var stockId = 0var curPrice = 0.0d
override def run(srcCtx: SourceContext[StockPrice]): Unit = {while (isRunning) {//每次从列表中随机选择一只股票stockId = rand.nextInt(priceList.size)val curPrice = priceList(stockId) + rand.nextGaussian() * 0.05priceList = priceList.updated(stockId, curPrice)val curTime = Calendar.getInstance.getTimeInMillis//将数据源收集写入SourceContextsrcCtx.collect(StockPrice("stock_" + stockId.toString, curTime, curPrice))Thread.sleep(rand.nextInt(10))}
} override def cancel(): Unit = {isRunning = false}}
}
1.数据转换之map操作
1.数据转换算子的四种类型
基于单条记录:fliter、map
基于窗口:window
合并多条数据流:union,join,connect
拆分多条数据流:split
2.map(func)操作将一个DataStream中的每个元素传递到函数func中,并将结果返回为一个新的DataStream。输出的数据流DataStream[OUT]类型可能和输入的数据流DataStream[IN]不同
理解:一 一对应的关系,一个x得到一个y
val dataStream = env.fromElements(1,2,3,4,5)
val mapStream = dataStream.map(x=>x+10)

3.演示代码
import org.apache.flink.api.common.functions.RichMapFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironmentcase class StockPrice(stockId:String,timeStamp:Long,price:Double)
object MapFunctionTest {def main(args: Array[String]): Unit = {//设定执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设定程序并行度env.setParallelism(1)//创建数据源val dataStream: DataStream[Int] = env.fromElements(1, 2, 3, 4, 5, 6, 7)//设置转换操作逻辑val richFunctionDataStream = dataStream.map {new MyMapFunction()}//打印输出richFunctionDataStream.print()//程序触发执行env.execute("MapFunctionTest")}//自定义函数,继承RichMapFunctionclass MyMapFunction extends RichMapFunction[Int, String] {override def map(input: Int): String =("Input : " + input.toString + ", Output : " + (input * 3).toString)}
}
2.数据转换之flatMap操作
1.flatMap和map相似,每个输入元素都可以映射到0或多个输出结果。
val dataStream = env.fromElements("Hadoop is good","Flink is fast","Flink is better")
val flatMapStream = dataStream.flatMap(line => line.split(" "))

可以理解为flatMap比map多了flat操作。如图。map是将输入数据映射成数组,flat是将数据拍扁,成为一个个元素。把元素映射成了多个。
2.代码演示
import org.apache.flink.api.common.functions.FlatMapFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.util.Collectorcase class StockPrice(stockId:String,timeStamp:Long,price:Double)
object FlatMapFunctionTest {def main(args: Array[String]): Unit = {//设定执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment//设定程序并行度
env.setParallelism(1)
//设置数据源
val dataStream: DataStream[String] = env.fromElements("Hello Spark", "Flink is excellent“) //针对数据集的转换操作逻辑
val result = dataStream.flatMap(new WordSplitFlatMap(15)) //打印输出
result.print()
//程序触发执行env.execute("FlatMapFunctionTest")} //使用FlatMapFunction实现过滤逻辑,只对字符串长度大于threshold的内容进行切词class WordSplitFlatMap(threshold: Int) extends FlatMapFunction[String, String] {override def flatMap(value: String, out: Collector[String]): Unit = {if (value.size > threshold) {value.split(" ").foreach(out.collect)}}}
}
预计输出:
Flink
is
excellent
这里只对字符长度超过15的做切割。threshold是阈值,少于15的不做切割。
3.数据转换之filter和keyBy操作
1.filter(func)操作会筛选出满足函数func的元素,并返回一个新的数据集
2.代码举例
val dataStream = env.fromElements("Hadoop is good","Flink is fast","Flink is better")
val filterStream = dataStream.filter(line => line.contains("Flink"))
如图所示

3.keyBy(注意方法里k小写B大写):将相同Key的数据放置在相同的分区中。
keyBy算子根据元素的形状对数据进行分组,相同形状的元素被分到了一起,可被后续算子统一处理
比如在词频统计时:
hello flink hello hadoophello zhangsan
这里 词频(hello,1),(hello,1),(hello,1)统计出来之后,通过keyBy,就可以聚合,放在了相同的分区里进行统一计算。

通过聚合函数后又可以吧KeyedStream转换成DataStream。
4.在使用keyBy算子时,需要向keyBy算子传递一个参数, 可使用数字位置来指定Key
比如刚才词频统计时,keyBy(0)就是hello这个单词。
val dataStream: DataStream[(Int, Double)] =env.fromElements((1, 2.0), (2, 1.7), (1, 4.9), (3, 8.5), (3, 11.2))
//使用数字位置定义Key 按照第一个字段进行分组
val keyedStream = dataStream.keyBy(0)
这里keyby 是第一个字段1或者2或者3分组(分类)。
5.keyBy代码举例:
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment//声明一个样例类,包含三个字段:股票ID、交易时间、交易价格
case class StockPrice(stockId:String,timeStamp:Long,price:Double)object KeyByTest{def main(args: Array[String]): Unit = {//获取执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设置程序并行度env.setParallelism(1)
//创建数据源val stockList = List(StockPrice("stock_4",1602031562148L,43.4D),StockPrice("stock_1",1602031562148L,22.9D),StockPrice("stock_0",1602031562153L,8.2D),StockPrice("stock_3",1602031562153L,42.1D),StockPrice("stock_2",1602031562153L,29.2D),StockPrice("stock_0",1602031562159L,8.1D),StockPrice("stock_4",1602031562159L,43.7D),StockPrice("stock_4",1602031562169L,43.5D))val dataStream = env.fromCollection(stockList) //设定转换操作逻辑val keyedStream = dataStream.keyBy("stockId“) //打印输出keyedStream.print() //程序触发执行env.execute("KeyByTest")}
}

这里看起来没什么变换 ,因为没进行聚合操作,所以什么变化都没有,原样输出。
我加上聚合函数,看起来就有变化了。
//简写上面的代码 加上聚合函数val keyedStream = dataStream.keyBy("stockId")val aggre = keyedStream.sum(2) //这里相加的是价格price(第三个字段)// keyedStream.print()aggre.print()//聚合后打印
结果

对比上面哪里变化了呢?
stcok_id顺序,4-1-0-3-2-0(这里之前也有0,就会加上之前的0,变为16.299,后面的4也在累加前面的price了
4.数据转换之reduce操作和聚合操作
1.reduce:reduce算子将输入的KeyedStream通过传入的用户自定义函数滚动地进行数据聚合处理,处理以后得到一个新的DataStream,如下实例
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment//声明一个样例类,包含三个字段:股票ID、交易时间、交易价格
case class StockPrice(stockId:String,timeStamp:Long,price:Double)object ReduceTest{def main(args: Array[String]): Unit = {//获取执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设置程序并行度env.setParallelism(1)//创建数据源val stockList = List(StockPrice("stock_4",1602031562148L,43.4D),StockPrice("stock_1",1602031562148L,22.9D),StockPrice("stock_0",1602031562153L,8.2D),StockPrice("stock_3",1602031562153L,42.1D),StockPrice("stock_2",1602031562153L,29.2D),StockPrice("stock_0",1602031562159L,8.1D),StockPrice("stock_4",1602031562159L,43.7D),StockPrice("stock_4",1602031562169L,43.5D))val dataStream = env.fromCollection(stockList)//设定转换操作逻辑val keyedStream = dataStream.keyBy("stockId")val reduceStream = keyedStream.reduce((t1,t2)=>StockPrice(t1.stockId,t1.timeStamp,t1.price+t2.price))//打印输出reduceStream.print()//程序触发执行env.execute("ReduceTest")}
}
reduce结果和上面的一样,就是累加

2.flink也支持自定义的reduce函数
import org.apache.flink.api.common.functions.ReduceFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment//声明一个样例类,包含三个字段:股票ID,交易时间,交易价格
case class StockPrice(stockId:String,timeStamp:Long,price:Double)object MyReduceFunctionTest{def main(args: Array[String]): Unit = {//获取执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设置程序并行度env.setParallelism(1)//创建数据源val stockList = List(StockPrice("stock_4",1602031562148L,43.4D),StockPrice("stock_1",1602031562148L,22.9D),StockPrice("stock_0",1602031562153L,8.2D),StockPrice("stock_3",1602031562153L,42.1D),StockPrice("stock_2",1602031562153L,29.2D),StockPrice("stock_0",1602031562159L,8.1D),StockPrice("stock_4",1602031562159L,43.7D),StockPrice("stock_4",1602031562169L,43.5D))val dataStream = env.fromCollection(stockList) //设定转换操作逻辑val keyedStream = dataStream.keyBy("stockId")val reduceStream = keyedStream.reduce(new MyReduceFunction)//打印输出reduceStream.print()//程序触发执行env.execute("MyReduceFunctionTest")}class MyReduceFunction extends ReduceFunction[StockPrice] {override def reduce(t1: StockPrice,t2:StockPrice):StockPrice = {StockPrice(t1.stockId,t1.timeStamp,t1.price+t2.price)}}
}
主要不同的就是创建了MyReduceFunction ().
3.聚合算子

和excel一样。
代码举例:
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment//声明一个样例类,包含三个字段:股票ID、交易时间、交易价格
case class StockPrice(stockId:String,timeStamp:Long,price:Double)
object AggregationTest{def main(args: Array[String]): Unit = {//获取执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//设置程序并行度env.setParallelism(1)
//创建数据源val stockList = List(StockPrice("stock_4",1602031562148L,43.4D),StockPrice("stock_1",1602031562148L,22.9D),StockPrice("stock_0",1602031562153L,8.2D),StockPrice("stock_3",1602031562153L,42.1D),StockPrice("stock_2",1602031562153L,29.2D),StockPrice("stock_0",1602031562159L,8.1D),StockPrice("stock_4",1602031562159L,43.7D),StockPrice("stock_4",1602031562169L,43.5D))val dataStream = env.fromCollection(stockList)//设定转换操作逻辑val keyedStream = dataStream.keyBy("stockId")val aggregationStream = keyedStream.sum(2) //区别在这里 sum聚合 2表示第三个字段//打印输出aggregationStream.print()//执行操作env.execute(" AggregationTest")}
}
运行结果

5.数据输出
1.基本数据输出包括:文件输出,客户端输出,socket网络端口输出。
文件输出具体代码
val dataStream = env.fromElements("hadoop","spark","flink")
//文件输出
dataStream.writeAsText("file:///home/hadoop/output.txt")
//hdfs输出//把数据写入HDFS
dataStream.writeAsText("hdfs://localhost:9000/output.txt“) //通过writeToSocket方法将DataStream数据集输出到指定socket端口
dataStream.writeToSocket(outputHost,outputPort,new SimpleStringSchema())
2.输出到kafka
代码举例:
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducerobject SinkKafkaTest{def main(args: Array[String]): Unit = {//获取执行环境val env = StreamExecutionEnvironment.getExecutionEnvironment//加载或创建数据源val dataStream = env.fromElements("hadoop","spark","flink")//把数据输出到Kafka
dataStream.addSink(new FlinkKafkaProducer [String]("localhost:9092", "sinkKafka", new SimpleStringSchema()))//程序触发执行env.execute()}
}
相关文章:
DataStream编程模型之数据源、数据转换、数据输出
Flink之DataStream数据源、数据转换、数据输出(scala) 0.前言–数据源 在进行数据转换之前,需要进行数据读取。 数据读取分为4大部分: (1)内置数据源; 又分为文件数据源; socket…...
海康IPC接入TRTC时,从海康中获取的数据显示时色差不正确
2021/1 记录海康IPC接入TRTC时的历史日志 从海康sdk接口获取数据,进行解码 org.MediaPlayer.PlayM4.Player.T_YV12;private void setDecodeCB() {Player.getInstance().setDecodeCB(m_iPort, (nPort, data, nDataLen, nWidth, nHeight, nFrameTime, nDataType,…...
『VUE』31. 生命周期的应用(详细图文注释)
目录 在合适的时间进行操作取dom元素利用生命周期模拟网络数据发送代码示例 总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 在合适的时间进行操作 假设网页一颗果树,我们要取dom(果实),一定要在渲染完成后才能取(果实) 通常…...
Mybatis框架之建造者模式 (Builder Pattern)
MyBatis 框架中大量使用了 建造者模式 (Builder Pattern) 来构建复杂的对象,尤其是在 SQL 语句的解析、配置对象的创建以及动态 SQL 的生成 等方面。建造者模式使得 MyBatis 能够更灵活、清晰地构建对象,尤其是那些需要多步创建和配置的复杂对象。 1. 什…...
Java从入门到精通笔记篇(十三)
与流处理 ambda表达式 定义 lambda表达式不能被独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。 可将其语法用下列的方式理解 误区警示 “->”符号是由英文状态下的“-”和“>”组成的,符号之间没有空格。 lambd…...
嵌入式:STM32的启动(Startup)文件解析
相关阅读 嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html?spm1001.2014.3001.5482 启动文件(Startup File)是嵌入式系统开发中的核心组件之一,它用于初始化系统并为主程序的运行做好准备。在大多数情况下,启动文件是用汇编语言编…...
ElasticSearch学习笔记四:基础操作(二)
一、前言 上一篇文章中我们学习了ES中的基础操作,包括索引和映射,同时也学习了ES中的基础数据类型,今天我们继续学习其他的数据类型。 二、复杂数据类型 1、数组(Array) 在ES中没有特别指定数据类型,换…...
ODA-em-application.log太大处理
检查oda时发现u01使用率很高,层层排查到是em-application.log文件太大 orcl2:/u01/app/oracle/product/11.2.0.4/dbhome_1/oc4j/j2ee/OC4J_DBConsole_oda1_orcl/logoda1>du -sh * 57G em-application.log 2.2M global-application.log 92M …...
基于现金红包营销活动的开源 AI 智能名片与 S2B2C 商城小程序融合发展研究
摘要:本文深入剖析现金红包这一平台补贴的营销利器在消费场景中的多元应用,并将其与开源 AI 智能名片、S2B2C 商城小程序相融合,探讨其中蕴含的创新模式与商业价值。通过详尽解析各类现金红包的使用条件,阐述如何巧妙运用这些营销…...
远程管理不再难!树莓派5安装Raspberry Pi OS并实现使用VNC异地连接
前言:大家好!今天我要教你们如何在树莓派5上安装Raspberry Pi OS,并配置SSH和VNC权限。通过这些步骤,你将能够在Windows电脑上使用VNC Viewer,结合Cpolar内网穿透工具,实现长期的公网远程访问管理本地树莓派…...
React中 setState 是同步的还是异步的?调和阶段 setState 干了什么?
React中 setState 是同步的还是异步的 1. React 的 setState 是异步的2. 为什么 setState 在合成事件和生命周期函数中是异步的3. 为什么 setState 在原生事件和定时器中是同步的4. 为什么要这样设计?调和阶段是什么setState在调和阶段干了什么?总结&…...
【D3.js in Action 3 精译_040】4.4 D3 弧形图的绘制方法
当前内容所在位置: 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建(上篇) 4.1.1 D3 中的边距约定(中篇)4.1.2 坐标轴的生成(中篇) 4.1.2.1 比例尺的声明(中篇)4.1…...
C++设计模式:抽象工厂模式(风格切换案例)
抽象工厂模式(Abstract Factory)是一种创建型设计模式,其核心思想是:为一组相关或相互依赖的对象提供一个创建接口,而无需指定它们具体的类。简单来说,就是一个工厂可以生产一系列相关的对象。 我们接下来…...
搜维尔科技:Xsens随时随地捕捉,在任何环境下实时录制或捕捉
Xsens随时随地捕捉,在任何环境下实时录制或捕捉 搜维尔科技:Xsens随时随地捕捉,在任何环境下实时录制或捕捉...
爬虫基础总结 —— 附带爬取案例
Crawler —— Learning experience 数据的传输: 在OSI七层模型中,传输层为源主机和目标主机之间提供可靠的数据传输和通信服务,在该层中,有两个重要的协议—— TCP与 UDP协议。 TCP协议(传输控制协议) …...
图像处理学习笔记-20241118
文章目录 霍夫变换基本原理霍夫变换的步骤使用 OpenCV 实现直线检测示例:标准霍夫变换 示例:概率霍夫变换参数解释霍夫变换检测圆 基于GAN的样本生成GAN的基本原理基于GAN的数据增广流程实现代码示例 同态滤波(Homomorphic Filtering…...
不能打开网页,但能打开QQ、微信(三种方式)
1.VPN错误 下面三个开关全关闭 2.DNS问题 WINR 输入CMD打开命令行 命令行输入 ipconfig/flushdns 重启电脑 3.直接火绒(一键修复)...
使用 start-local 脚本在本地运行 Elasticsearch
警告:请勿将这些说明用于生产部署 本页上的说明仅适用于本地开发。请勿将此配置用于生产部署,因为它不安全。请参阅部署选项以获取生产部署选项列表。 使用 start-local 脚本在 Docker 中快速设置 Elasticsearch 和 Kibana 以进行本地开发或测试。 此设…...
计算机网络:概述知识点及习题练习
网课资源: 湖科大教书匠 1、因特网 网络之间需要路由器进行互联,互联网是网络的网络,因特网是最大的互联网,连接到网络的设备称为主机,一般不叫路由器为主机。 因特网发展:ARPNET->三级结构因特网&am…...
python蓝桥杯刷题2
1.最短路 题解:这个采用暴力枚举,自己数一下就好了 2.门牌制作 题解:门牌号从1到2020,使用for循环遍历一遍,因为range函数无法调用最后一个数字,所以设置成1到2021即可,然后每一次for循环&…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
