大模型专栏--Spring Ai Alibaba介绍和功能演示

Spring AI Alibaba 介绍和功能演示

背景

Spring AI Alibaba 开源项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。

Spring AI Alibaba 生态图如下:

img

演示

在此节中,将演示如何使用 Spring AI Alibaba 提供的接口功能完成和 LLMs 的交互。

框架搭建

pom.xml

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.3.4</version></dependency><!-- 最新版本 Spring AI Alibaba --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M3.1</version></dependency></dependencies><!-- 添加仓库配置,否则报错,如果添加之后仍然报错,刷新 mvn 或者清楚 IDEA 缓存 --><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><!-- 解决报错: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag --><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><parameters>true</parameters></configuration></plugin></plugins></build></project>

application.yml

spring:ai:dashscope:api-key: ${AI_DASHSCOPE_API_KEY}

启动类

@SpringBootApplication
public class AIApplication {public static void main(String[] args) {SpringApplication.run(AIApplication.class, args);}}

到此为止,我们已经搭建好了一个基本的 AI 应用雏形,现在开始和大模型交互 🎉🎉

只演示朴素请求,流式 API 不演示!

Chat 功能

AIChatController.java

@RestController
@RequestMapping("/ai")
public class AIChatController {// 使用高级 Client API,也可以使用低级 ChatModel APIprivate final ChatClient chatClient;public AIChatController(ChatClient.Builder builder) {this.chatClient = builder.build();}@GetMapping("/chat/{prompt}")public String chatWithChatMemory(@PathVariable String prompt) {return chatClient.prompt().user(prompt).call().chatResponse().getResult().getOutput().getContent();}}

如果一切顺利,请求 http://localhost:8080/ai/chat/你好接口,将得到以下输出:

你好!有什么我可以帮助你的吗?

从代码中可以看到,使用 Spring AI Alibaba 之后,和模型交互变得非常简单容易。

但是大模型是无状态的,怎么能让他变得有记忆?Spring AI 提供了 ChatMemory 的接口,只需要调用接口即可(源码将在后续文章中分析)

@RestController
@RequestMapping("/ai")
public class AIChatController {private final ChatClient chatClient;public AIChatController(ChatModel chatModel) {this.chatClient = ChatClient.builder(chatModel).defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())).build();}@GetMapping("/chat/{chatId}/{prompt}")public String chatWithChatMemory(@PathVariable String chatId,@PathVariable String prompt) {return chatClient.prompt().user(prompt).advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)).call().chatResponse().getResult().getOutput().getContent();}}

我们像这样请求接口:

# 1
input: http://localhost:8080/ai/chat/10001/你好,我是牧生
output:你好,牧生!很高兴认识你。你可以叫我Qwen,我是阿里云推出的一种超大规模语言模型。我有强大的语言生成和理解能力,可以进行自然流畅的对话,还能写故事、写公文、写邮件、写剧本等等,也能表达观点,玩游戏等。有什么我可以帮助你的吗?# 2
input:http://localhost:8080/ai/chat/10001/我是谁
output:你刚才提到你的名字是牧生。如果你有任何问题或需要进一步的帮助,随时告诉我,我很乐意为你服务!# 当切换 chatId 时
input:http://localhost:8080/ai/chat/10000/我叫什么名字
output:您还没有告诉我您的名字呢。如果您愿意,可以告诉我您希望被称为什么,或者您想如何介绍自己。

能看到借助 Spring AI 的 ChatMemory 接口,已经使大模型变得聪明了起来。 😀

PS:Spring AI Alibaba 的 Chat Memory 功能已经在规划中了!

Image 功能

本节我们将展示如何使用 Spring AI Alibaba 提供的 Image API 完成和大模型的图像交互功能,包含文生图,多模态等功能。

AIImageController.java
@RestController
@RequestMapping("/ai")
public class AIImageController {private final ImageModel imageModel;public AIImageController(ImageModel imageModel) {this.imageModel = imageModel;}@GetMapping("/image/{input}")public void image(@PathVariable("input") String input, HttpServletResponse response) {String imageUrl = imageModel.call(new ImagePrompt(input)).getResult().getOutput().getUrl();try {URL url = URI.create(imageUrl).toURL();InputStream in = url.openStream();response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);response.getOutputStream().write(in.readAllBytes());response.getOutputStream().flush();} catch (IOException e) {response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);}}}

请求接口 http://localhost:8080/ai/image/给我一张AI图片,将会得到以下输出:

多模态

MultiModelController.java

多模态还支持视频解析和 流式 API。

@RestController
@RequestMapping("/ai")
public class AIImageController {private final ImageModel imageModel;// 加入 chatClientprivate final ChatClient client;public AIImageController(ImageModel imageModel, ChatClient.Builder builder) {this.imageModel = imageModel;this.client = builder.build();}@GetMapping("/image/{input}")public void image(@PathVariable("input") String input, HttpServletResponse response) {ImageOptions options = ImageOptionsBuilder.builder().withModel("wanx-v1").build();String imageUrl = imageModel.call(new ImagePrompt(input, options)).getResult().getOutput().getUrl();try {URL url = URI.create(imageUrl).toURL();InputStream in = url.openStream();response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);response.getOutputStream().write(in.readAllBytes());response.getOutputStream().flush();} catch (IOException e) {response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);}}@GetMapping("/image")public String image(@RequestParam(value = "prompt", required = false, defaultValue = "图片里是什么")String prompt) throws Exception {// 图片资源 同时支持读取本地文件作为输入List<Media> mediaList = List.of(new Media(MimeTypeUtils.IMAGE_PNG,new URI("https://dashscope.oss-cn-beijing.aliyuncs.com/images/dog_and_girl.jpeg").toURL()));UserMessage message = new UserMessage(prompt, mediaList);message.getMetadata().put(DashScopeChatModel.MESSAGE_FORMAT, MessageFormat.IMAGE);ChatResponse response = client.prompt(new Prompt(message,DashScopeChatOptions.builder().withModel("qwen-vl-max-latest").withMultiModel(true).build())).call().chatResponse();return response.getResult().getOutput().getContent();}}

请求 http://localhost:8080/ai/image 接口,将得到以下输出:

这张图片展示了一位女士和一只狗在海滩上互动的温馨场景。女士坐在沙滩上,面带微笑,与狗握手。狗戴着项圈,显得非常温顺和友好。背景是广阔的海洋和天空,阳光洒在沙滩上,营造出一种温暖和谐的氛围。

Audio 功能

本节我们将展示如何使用 Spring AI Alibaba 提供的 Audio API 完成和大模型的音频交互功能,包含文生语音,语音转文字等功能。

截止文章发布期间,Spring AI Alibaba 的语音转录接口还没有发版,有关 stt 和 tts 的更多使用,参考官方 example。

https://github.com/alibaba/spring-ai-alibaba/tree/main/spring-ai-alibaba-examples/audio-example/src/main/java/com/alibaba/cloud/ai/example/audio

AIAudioController.java

@RestController
@RequestMapping("/ai")
public class AIAudioController implements ApplicationRunner {private final SpeechSynthesisModel speechSynthesisModel;private static final String TEXT = "白日依山尽,黄河入海流。";private static final String FILE_PATH = "src/main/resources/gen/tts/";private AIAudioController(SpeechSynthesisModel speechSynthesisModel) {this.speechSynthesisModel = speechSynthesisModel;}@GetMapping("/tts")public void tts() throws IOException {SpeechSynthesisResponse response = speechSynthesisModel.call(new SpeechSynthesisPrompt(TEXT));File file = new File(FILE_PATH + "output.mp3");try (FileOutputStream fos = new FileOutputStream(file)) {ByteBuffer byteBuffer = response.getResult().getOutput().getAudio();fos.write(byteBuffer.array());}catch (IOException e) {throw new IOException(e.getMessage());}}@Overridepublic void run(ApplicationArguments args) {File file = new File(FILE_PATH);if (!file.exists()) {file.mkdirs();}}@PreDestroypublic void destroy() throws IOException {FileUtils.deleteDirectory(new File(FILE_PATH));}}

请求接口,将得到一个语音文件的输出。

函数调用

函数调用是为了弥补大模型的训练数据落后的问题,用外部的 API 来补充 LLMs 的知识,给用户最合理的回答。

天气函数注册 MockWeatherService.java

public class MockWeatherService implements Function<MockWeatherService.Request, Response> {@Overridepublic Response apply(Request request) {if (request.city().contains("杭州")) {return new Response(String.format("%s%s晴转多云, 气温32摄氏度。", request.date(), request.city()));}else if (request.city().contains("上海")) {return new Response(String.format("%s%s多云转阴, 气温31摄氏度。", request.date(), request.city()));}else {return new Response(String.format("暂时无法查询%s的天气状况。", request.city()));}}@JsonInclude(JsonInclude.Include.NON_NULL)@JsonClassDescription("根据日期和城市查询天气")public record Request(@JsonProperty(required = true, value = "city") @JsonPropertyDescription("城市, 比如杭州") String city,@JsonProperty(required = true, value = "date") @JsonPropertyDescription("日期, 比如2024-08-22") String date) {}}

紧接着,我们在 AIChatController 中加入函数调用的代码:

@RestController
@RequestMapping("/ai")
public class AIChatController {private final ChatClient chatClient;public AIChatController(ChatModel chatModel) {this.chatClient = ChatClient.builder(chatModel).defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())).build();}@GetMapping("/chat/{chatId}/{prompt}")public String chatWithChatMemory(@PathVariable String chatId,@PathVariable String prompt) {return chatClient.prompt().user(prompt).advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)).call().chatResponse().getResult().getOutput().getContent();}// 函数调用@GetMapping("/weather-service/{city}")public String weatherService(@PathVariable String city) {return chatClient.prompt().function("getWeather", "根据城市查询天气", new MockWeatherService()).user(city).call().content();}}

请求 http://localhost:8080/ai/weather-service/杭州2024年11月29日天气怎么样 接口,将得到如下响应:

2024年11月29日,杭州的天气预报为晴转多云,气温为32摄氏度。请根据天气情况做好相应的准备。如果您有其他问题,欢迎随时询问!

RAG

本节中我们将使用 ES 作为 RAG 的实现,演示 Spring AI Alibaba RAG 的实现。

在 resource 目录下准备一个 system-qa.st

Context information is below.
---------------------
{question_answer_context}
---------------------
Given the context and provided history information and not prior knowledge,
reply to the user comment. If the answer is not in the context, inform
the user that you can't answer the question.

之后准备一个 df 文件,点击这里下载:https://github.com/alibaba/spring-ai-alibaba/blob/main/spring-ai-alibaba-examples/rag-example/src/main/resources/data/spring_ai_alibaba_quickstart.pdf

使用 docker compose up -d 启动一个 es:

准备配置文件:

config/es.yaml

cluster.name: docker-es
node.name: es-node-1
network.host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9200
http.cors.enabled: true
http.cors.allow-origin: "*"
bootstrap.memory_lock: true# 关闭认证授权 es 8.x 默认开启
# 如果不关闭,spring boot 连接会 connection closed
xpack.security.enabled: false

docker-compose.yaml

version: '3.3'services:elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1container_name: elasticsearchprivileged: trueenvironment:- "cluster.name=elasticsearch"- "discovery.type=single-node"- "ES_JAVA_OPTS=-Xms512m -Xmx1096m"- bootstrap.memory_lock=truevolumes:- ./config/es.yaml:/usr/share/elasticsearch/config/elasticsearch.ymlports:- "9200:9200"- "9300:9300"deploy:resources:limits:cpus: "2"memory: 1000Mreservations:memory: 200M

application.yml 中加入 rag 相关配置:

server:port: 9097spring:ai:dashscope:api-key: ${AI_DASHSCOPE_API_KEY}vectorstore:elasticsearch:index-name: spring-ai-alibaba-indexsimilarity: cosinedimensions: 1536initialize-schema: true

pom.xml 中加入如下配置:

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pdf-document-reader</artifactId><version>1.0.0-M3</version>
</dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-elasticsearch-store-spring-boot-starter</artifactId><version>1.0.0-M3</version>
</dependency>

AIRagController.java

package indi.yuluo.controller;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.DenseVectorProperty;
import co.elastic.clients.elasticsearch._types.mapping.KeywordProperty;
import co.elastic.clients.elasticsearch._types.mapping.ObjectProperty;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TextProperty;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.IndexSettings;
import com.alibaba.cloud.ai.advisor.RetrievalRerankAdvisor;
import com.alibaba.cloud.ai.model.RerankModel;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;import org.springframework.ai.autoconfigure.vectorstore.elasticsearch.ElasticsearchVectorStoreProperties;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.document.Document;
import org.springframework.ai.document.DocumentReader;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @author yuluo* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>*/@RestController
@RequestMapping("/ai")
public class AIRagController implements ApplicationRunner {private static final Logger logger = LoggerFactory.getLogger(AIRagController.class);@Value("classpath:/data/spring_ai_alibaba_quickstart.pdf")private Resource PdfResource;@Value("classpath:/prompts/system-qa.st")private Resource systemResource;private static final String textField = "content";private static final String vectorField = "embedding";private final ChatModel chatModel;private final VectorStore vectorStore;private final RerankModel rerankModel;private final ElasticsearchClient elasticsearchClient;private final ElasticsearchVectorStoreProperties options;public AIRagController(ChatModel chatModel,VectorStore vectorStore,RerankModel rerankModel,ElasticsearchClient elasticsearchClient,ElasticsearchVectorStoreProperties options) {this.chatModel = chatModel;this.vectorStore = vectorStore;this.rerankModel = rerankModel;this.elasticsearchClient = elasticsearchClient;this.options = options;}@GetMapping("/rag")public Flux<String> generate(@RequestParam(value = "message", defaultValue = "how to get start with spring ai alibaba?")String message,HttpServletResponse response) throws IOException {// 不设置返回值会乱码response.setCharacterEncoding(StandardCharsets.UTF_8.name());return this.retrieve(message).map(x -> x.getResult().getOutput().getContent());}private Flux<ChatResponse> retrieve(String message) throws IOException {// Enable hybrid search, both embedding and full text searchSearchRequest searchRequest = SearchRequest.defaults().withFilterExpression(new FilterExpressionBuilder().eq(textField, message).build());// Step3 - Retrieve and llm generateString promptTemplate = systemResource.getContentAsString(StandardCharsets.UTF_8);;ChatClient chatClient = ChatClient.builder(chatModel).defaultAdvisors(new RetrievalRerankAdvisor(vectorStore,rerankModel,searchRequest,promptTemplate,0.1)).build();return chatClient.prompt().user(message).stream().chatResponse();}@Overridepublic void run(ApplicationArguments args) throws Exception {// 1. parse documentDocumentReader reader = new PagePdfDocumentReader(PdfResource);List<Document> documents = reader.get();logger.info("{} documents loaded", documents.size());// 2. split trunksList<Document> splitDocuments = new TokenTextSplitter().apply(documents);logger.info("{} documents split", splitDocuments.size());// 3. create embedding and store to vector storelogger.info("create embedding and save to vector store");createIndexIfNotExists();vectorStore.add(splitDocuments);}private void createIndexIfNotExists() {try {String indexName = options.getIndexName();Integer dimsLength = options.getDimensions();if (Objects.isNull(indexName) || indexName.isEmpty()) {throw new IllegalArgumentException("Elastic search index name must be provided");}boolean exists = elasticsearchClient.indices().exists(idx -> idx.index(indexName)).value();if (exists) {logger.debug("Index {} already exists. Skipping creation.", indexName);return;}String similarityAlgo = options.getSimilarity().name();IndexSettings indexSettings = IndexSettings.of(settings -> settings.numberOfShards(String.valueOf(1)).numberOfReplicas(String.valueOf(1)));Map<String, Property> properties = new HashMap<>();properties.put(vectorField, Property.of(property -> property.denseVector(DenseVectorProperty.of(dense -> dense.index(true).dims(dimsLength).similarity(similarityAlgo)))));properties.put(textField, Property.of(property -> property.text(TextProperty.of(t -> t))));Map<String, Property> metadata = new HashMap<>();metadata.put("ref_doc_id", Property.of(property -> property.keyword(KeywordProperty.of(k -> k))));properties.put("metadata",Property.of(property -> property.object(ObjectProperty.of(op -> op.properties(metadata)))));CreateIndexResponse indexResponse = elasticsearchClient.indices().create(createIndexBuilder -> createIndexBuilder.index(indexName).settings(indexSettings).mappings(TypeMapping.of(mappings -> mappings.properties(properties))));if (!indexResponse.acknowledged()) {throw new RuntimeException("failed to create index");}logger.info("create elasticsearch index {} successfully", indexName);}catch (IOException e) {logger.error("failed to create index", e);throw new RuntimeException(e);}}}

之后,请求 http://localhost:8080/ai/rag 接口,将得到如下响应:

根据提供的上下文信息,以下是开始使用 Spring AI Alibaba 的步骤: ### 概述 Spring AI Alibaba 实现了与阿里云通义模型的完整适配。下面将介绍如何使用 Spring AI Alibaba 开发一个基于通义模型服务的智能聊天应用。 ### 快速体验示例 #### 注意事项 - **JDK 版本**:因为 Spring AI Alibaba 基于 Spring Boot 3.x 开发,所以本地 JDK 版本要求为 17 及以上。 #### 步骤 1. **下载项目** - 运行以下命令下载源码,并进入 `helloworld` 示例目录: ```sh git clone --depth=1 https://github.com/alibaba/spring-ai-alibaba.git cd spring-ai-alibaba/spring-ai-alibaba-examples/helloworld-example ```2. **运行项目** - 首先,需要获取一个合法的 API-KEY 并设置 `AI_DASHSCOPE_API_KEY` 环境变量。你可以跳转到 [阿里云百炼平台](https://sca.aliyun.com/) 了解如何获取 API-KEY。 ```sh export AI_DASHSCOPE_API_KEY=${REPLACE-WITH-VALID-API-KEY} ```- 启动示例应用: ```sh ./mvnw compile exec:java -Dexec.mainClass="com.alibaba.cloud.ai.example.helloworld.HelloWorldExample" ```3. **访问应用** - 打开浏览器,访问 `http://localhost:8080/ai/chat?input=给我讲一个笑话吧`,向通义模型提问并得到回答。 希望这些步骤能帮助你快速上手 Spring AI Alibaba!如果有任何问题,可以随时提问。

总结

Spring AI Alibaba 基于 Spring AI 开发,并在上层提供更多高级的抽象 API。帮助开发者构建 Java LLMs 应用。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿&#xff0c;数据挖掘的小伙伴们&#xff01;今天我要给你们介绍一本超级实用的书——《数据挖掘&#xff1a;概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作&#xff0c;由该领域的知名专家编写&#xff0c;系统性地介绍了在高维数据空间中分析和提取大量…

AOSP的同步问题

repo sync同步时提示出错: error: .repo/manifests/: contains uncommitted changesRepo command failed due to the following UpdateManifestError errors: contains uncommitted changes解决方法&#xff1a; 1、cd 进入.repo/manifests cd .repo/manifests2、执行如下三…

AI开发:逻辑回归 - 实战演练- 垃圾邮件的识别(二)

接上一篇AI开发&#xff1a;逻辑回归 - 实战演练- 垃圾邮件的识别&#xff08;一&#xff09; new_email 无论为什么文本&#xff0c;识别结果几乎都是垃圾邮件,因此我们需要对源码的逻辑进行梳理一下&#xff1a; 在代码中&#xff0c;new_email 无论赋值为何内容都被识别为…

Scratch游戏推荐 | 星际前线:帝国逆袭——揭开帝国野心,挑战星际极限!

今天推荐一款充满科幻与冒险元素的Scratch作品——《星际前线&#xff1a;帝国逆袭》&#xff01;由theChAOTiC制作&#xff0c;这款游戏让你踏入危险的星际前线&#xff0c;与暴虐的Terran帝国展开激烈对抗。在这里&#xff0c;你将探索未知的星域&#xff0c;击败强大的Boss&…

【语音识别】Zipformer

Zipformer 是kaldi 团队于2024研发的序列建模模型。相比较于 Conformer、Squeezeformer、E-Branchformer等主流 ASR 模型&#xff0c;Zipformer 具有效果更好、计算更快、更省内存等优点。并在 LibriSpeech、Aishell-1 和 WenetSpeech 等常用数据集上取得了当时最好的 ASR 结果…

《Vue零基础入门教程》第十五课:样式绑定

往期内容 《Vue零基础入门教程》第六课&#xff1a;基本选项 《Vue零基础入门教程》第八课&#xff1a;模板语法 《Vue零基础入门教程》第九课&#xff1a;插值语法细节 《Vue零基础入门教程》第十课&#xff1a;属性绑定指令 《Vue零基础入门教程》第十一课&#xff1a;事…

buuctf-[SUCTF 2019]EasySQL 1解题记录

把你的旗帜给我&#xff0c;我会告诉你这面旗帜是对的。 堆叠注入查询数据库 1; show databases; ​ 查询表名 1; show tables; 获取flag 1;set sql_modepipes_as_concat;select 1

Git的基本使用操作

文章目录 Git 全局配置基本操作Git 常用命令版本回退根据版本号回滚分支远端分支 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Git专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月1日12点50分 Git 全局配置 虽然说是全局配置&am…

飞凌嵌入式受邀亮相OpenHarmony人才生态大会2024

2024年11月27日&#xff0c;OpenHarmony人才生态大会2024在武汉洲际酒店举行。在这场汇聚了行业精英、技术大咖及生态伙伴的年度盛会上&#xff0c;飞凌嵌入式作为OpenHarmony社区的重要成员受邀出席&#xff0c;并展示了其在OpenHarmony 4.1系统适配方面的最新成果。 在大会的…

45 基于单片机的信号选择与温度变化

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DS18B20检测温度&#xff0c;通过三种LED灯代表不同状态。 采用DAC0832显示信号脉冲&#xff0c;通过8位数码管显示温度。 信号脉冲可以根据两个按键分别调整为正弦…

大数据新视界 -- Hive 基于 MapReduce 的执行原理(上)(23 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Qt 2D绘图之三:绘制文字、路径、图像、复合模式

参考文章链接: Qt 2D绘图之三:绘制文字、路径、图像、复合模式 绘制文字 除了绘制图形以外,还可以使用QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::fontInfo()函数可以获取字体的信息,它返回QFontInfo类对象…

React-状态管理详解

1、传统MVC框架的缺陷 什么是MVC&#xff1f; MVC的全名是Model View Controller&#xff0c;是模型(model)&#xff0d;视图(view)&#xff0d;控制器(controller)的缩写&#xff0c;是一种软件设计典范。 V即View视图是指用户看到并与之交互的界面。 M即Model模型是管理数…

PH热榜 | 2024-12-02

1. Muku.ai 标语&#xff1a;AI网红广告代理公司 介绍&#xff1a;木库AI是家AI网红营销机构&#xff0c;利用AI虚拟形象创作用户原创视频广告。只需提供产品链接&#xff0c;就能生成吸引人的内容&#xff0c;从而提升各大平台的销售额。 产品网站&#xff1a; 立即访问 P…

Flink学习连载文章9--状态(State)

State state 可以理解为-- 历史计算结果 有状态计算和无状态计算 无状态计算: 不需要考虑历史数据, 相同的输入,得到相同的输出!如:map, 将每个单词记为1, 进来一个hello, 得到(hello,1),再进来一个hello,得到的还是(hello,1) 有状态计算: 需要考虑历史数据, 相同的输入,可…

嵌入式硬件面试题【经验】总结----会不断添加更新

目录 引言 一、电阻 1、电阻选型时一般从那几个方面考虑 2、上拉电阻的作用 3、PTC热敏电阻作为电源电路保险丝的工作原理 4、如果阻抗不匹配&#xff0c;有哪些后果 二、电容 1、电容选型一般从哪些方面进行考虑? 2、1uf的电容通常来滤除什么频率的信号 三、三极管…

Linux——基础命令(2) 文件内容操作

目录 ​编辑 文件内容操作 1.Vim &#xff08;1&#xff09;移动光标 &#xff08;2&#xff09;复制 &#xff08;3&#xff09;剪切 &#xff08;4&#xff09;删除 &#xff08;5&#xff09;粘贴 &#xff08;6&#xff09;替换,撤销,查找 &#xff08;7&#xff…

Stable Diffusion 3详解

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

微信小程序——文档下载功能分享(含代码)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

开源的跨平台SQL 编辑器Beekeeper Studio

一款开源的跨平台 SQL 编辑器&#xff0c;提供 SQL 语法高亮、自动补全、数据表内容筛选与过滤、连接 Web 数据库、存储历史查询记录等功能。该编辑器支持 SQLite、MySQL、MariaDB、Postgres 等主流数据库&#xff0c;并兼容 Windows、macOS、Linux 等桌面操作系统。 项目地址…