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循环&…...
2PG450x500双齿辊破碎机CAD装配图
2PG450x500双齿辊破碎机CAD装配图是机械设计领域中用于呈现设备整体结构的关键学习资料。该设备通过两个同步旋转的齿辊实现物料的破碎功能,其核心作用在于将大块物料均匀破碎至指定粒度,满足后续加工或输送需求。装配图以二维工程语言精准描述各部件的相…...
基于FreeSWITCH ESL构建高并发智能客服系统的实战指南
在构建智能客服系统时,通信层的稳定与高效是基石。传统的WebSocket或直接SIP处理在高并发场景下,常常面临连接管理复杂、事件处理混乱、资源消耗大等问题。FreeSWITCH作为成熟的软交换平台,其ESL(Event Socket Library)…...
避坑指南:在ZYNQ上调试PCIe设备时,如何手动验证枚举与BAR空间配置是否正确
ZYNQ平台PCIe设备调试实战:手动验证枚举与BAR配置的工程方法论 当你在ZYNQ平台上调试PCIe设备时,是否遇到过这样的场景:Vivado中精心设计的PCIe链路通过了硬件测试,但系统启动后lspci却看不到设备踪影?或者设备虽然被识…...
概率神经网络的分类预测:基于PNN网络的变压器故障诊断应用研究及对比实验(附Matlab源代码...
概率神经网络的分类预测 基于pnn网络变压器故障诊断 应用研究及对比实验 matlab源代码 代码有详细注释,完美运行变压器故障诊断这事儿听起来挺玄乎,但用概率神经网络(Probabilistic Neural Network)来处理就跟开挂似的。我最近在M…...
告别文档迁移困境:3个关键场景解锁飞书文档批量备份新方案
告别文档迁移困境:3个关键场景解锁飞书文档批量备份新方案 【免费下载链接】feishu-doc-export 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 还在为团队协作平台切换带来的文档迁移难题而烦恼吗?当企业从飞书切换到其他办公…...
开发者专属配置:OpenClaw+GLM-4-7-Flash优化命令行工作效率
开发者专属配置:OpenClawGLM-4-7-Flash优化命令行工作效率 1. 为什么开发者需要AI增强命令行? 作为每天与终端打交道的开发者,我经常遇到这样的困境:忘记复杂的grep参数组合、需要反复查阅历史命令、或是面对一长串docker compo…...
哈尔滨全屋定制厂家:值得信赖的筛选逻辑深度解析
哈尔滨全屋定制厂家筛选逻辑深度解析:5步找到值得信赖的本地品牌 “哈尔滨全屋定制厂家选择,不是看广告多响,而是这5个筛选逻辑能帮你避开90%的坑”。对于准备在哈尔滨做全屋定制的业主来说,选对厂家直接决定了最终效果与性价比&…...
本地部署Qwen3大模型+OpenClaw接入实战教程:从零实现私有化AI助手
> **标签**: AI开发,大模型,Ollama,OpenClaw,Python,本地部署 > **阅读时间**: 约15分钟 > **难度**: 中级## 一、引言本地部署大模型可确保**数据不出境、不上云**,满足金融、医疗等行业的合规要求;同时长期使用成本更低,适合高频…...
SDMatte提示词(Prompt)高级使用技巧:引导模型优化抠图边缘
SDMatte提示词(Prompt)高级使用技巧:引导模型优化抠图边缘 1. 为什么提示词对抠图质量至关重要 你可能已经发现,同样的图片在不同提示词下,SDMatte生成的蒙版质量会有明显差异。这就像给修图师不同的工作指令——说&…...
机器人抓手设计必看:用CATIA有限元分析确保Base板刚度的5个关键步骤
机器人抓手设计进阶指南:CATIA有限元分析在Base板刚度优化中的实战应用 在工业自动化领域,机器人抓手的性能直接影响生产效率和产品质量。作为承载整个抓取机构的核心部件,Base板的设计不仅需要考虑强度,更要确保足够的刚度以避免…...
