Java开发者也能看懂的大模型应用开发实践!!!

前言

做AI大模型应用的开发其实Java也能写,那么本文就一个Java开发者的立场,构建实现一个最基础的大模型应用系统。

而大模型应用系统其实在目前阶段,可能应用最广的还是RAG领域,因此,本文也是通过在RAG领域的基础架构下,来实现应用的开发,主要需求点:让大模型理解文本(知识库)内容,基于知识库范围内的内容进行回答对话

而基于知识库的回答会帮助我们解决哪些问题呢?

  • ✅ **节省大模型训练成本:**我们知道ChatGPT的知识内容停留在2021年,最新的知识它并不知道,而检索增强生成则可以解决大模型无法快速学习的问题,训练大模型代价是非常昂贵的,不仅仅只是金钱,还包括时间,随着模型的参数大小成本成正相关。
  • ✅ **让大模型更聪明:**很多企业内部的私有数据大模型并没有学习,而通过RAG的方式可以让大模型在知识库范围的领域进行回答,避免胡说八道,基于底层大模型的基座,可以让我们的应用系统看上去更加的聪明。

在本文中,你将学习到:

  • ✅ RAG工程的基本处理框架流程(基于Java)
  • ✅ 向量数据库的基础使用及了解

技术栈

考虑到作者也是Java开发者,因此本文所选择的技术栈以及中间件也是Java人员都耳熟能详的,主要技术栈如下:

1、开发框架:Spring BootSpring Shell(命令行对话)

Java开发者对于Spring Boot的生态应该是非常熟悉的,而选择Spring Shell工具包主要是为了演示命令行的交互问答效果,和本次的技术无太大关系,算是一个最小雏形的产品交互体验。

2、HTTP组件:OkHTTPOkHTTP-SSE

此次我们选择的大模型是以智谱AI开放的ChatGLM系列为主,因此我们需要HTTP组件和商业大模型的API进行接口的对接,当然开发者如果有足够的条件,也是可以在本地部署开源大模型并且开放API接口进行调试的,这个并不冲突,本文只是为了方便演示效果,所以使用了智谱的大模型API接口,而智谱AI注册后,默认提供了一个18元的免费Token消费额度,因此接口的API-Key只需要注册一个即可快速获取。

3、工具包:Hutool

非常好用的一个基础工具包组件,封装了很多工具类方法,包含字符、文件、时间、集合等等

本文会使用到Hutool包的文本读取和切割方法。

4、向量数据库:ElasticSearch

向量数据库是RAG应用程序的基础中间件,所有的文本Embedding向量都需要存储在向量数据库中间件中进行召回计算,当然在Java领域并没有类似Python中numpy这类本地化工具组件包,即可快速实现矩阵计算等需求(PS:最近Java21的发布中,不仅仅只是虚拟线程等新特性,提供的向量API相信在未来AI领域,Java也会有一席之地的),所以选择了独立部署的中间件。

本文选择ElasticSearch可能对于Java开发人员也是比较熟悉的一个组件,毕竟ES在Java领域用途还是非常广的,只是可能很多开发者并不知道ElasticSearch居然还有存储向量数据的功能?

对于向量数据库中间件的选择,目前市面上有非常多的向量数据库,包括:MilvusQdrantPostgres(pgvector)Chroma 等等,Java开发者可以在熟悉当前流程后,根据自己的实际需求,选择符合企业生产环境的向量数据库。

5、LLM大模型ChatGLM-Std

为了演示方便,本文直接使用开放API接口的商业大模型,智谱AI提供的ChatGLM-Std

RAG工程的基本处理流程

在RAG检索增强生成领域中,最简单的核心处理流程架构图如下:

该架构图图是一个非常简单的流程图,在RAG领域中其实有非常多的处理细节,当我们深入了解后就会知道

我们后续根据该图来进行Java编码实现。

图1-RAG通用框架流程架构示意图

在RAG应用工程领域,其实整个程序的处理包含两部分:

  • **问答:**对用户提问的问题通过向量Embedding模型处理,然后通过查询向量数据库(ElasticSearch)进行相似度计算获取和用户问题最相似的知识库段落内容,获取成功后,构建Prompt,最终发送给大模型获取最终的答案。
  • **数据处理:**数据的处理是将用户私有的数据进行提取,包括各种结构化及非结构化数据(例如PDF/Word/Text等等),提取文本数据后进行分割处理,最终通过向量Embedding模型将这些分割后的段落进行向量化,最终向量数据存储在基础设施向量数据库组件中,以供后续的问答流程使用。

从图中我们可以知道,在我们所需要的大模型处于什么位置,以及它的作用,主要是两个模型的应用:

  • **向量Embedding模型:**对我们本地知识的向量表征处理,将文本内容转化为便于计算机理解的向量表示
  • **LLM问答大模型:**大模型负责将我们通过语义召回的段落+用户的问题结合,构建的Prompt送给大模型以获取最终的答案,问答大模型在这里充当的角色是理解我们送给他的内容,然后进行精准回答

Java编码实践

我们理解了基础的架构流程,接下来就是编码实现了

环境准备

**Java:**JDK 1.8

**ElasticSearch:**7.16.1

对于ElasticSearch的安装,可以通过docker-compose在本地快速部署一个

编写docker-compose.yml配置文件,当前部署目录建data文件夹挂载数据目录

version: "3"
services:elasticsearch:image: elasticsearch:7.16.1ports:- "9200:9200"- "9300:9300"environment:node.name: escluster.name: elasticsearchdiscovery.type: single-node  ES_JAVA_OPTS: -Xms4096m -Xmx4096mvolumes:- ./data:/usr/share/elasticsearch/datadeploy:resources:limits:cpus: "4"memory: 5Greservations:cpus: "1"memory: 2Grestart: always

启动Es:docker-compose up -d

应用初体验

先来看整个程序的应用效果,通过Spring Shell环境下,程序启动后,如下图所示:

图2-程序启动效果

程序启动后,在命令行终端,我们可以看到一个可交互的命令行,此时,我们可以通过addchat两个命令完成图1中的整个流程

先使用add命令加载文档,在data目录下分别存储了001.txt002.txt两个文件,通过命令加载向量处理,如下图:

图3-ADD命令加载文件

当日志显示保存向量成功后,此时,我们即可以通过chat命令进行对话了,我们先来看看002.txt的文本主要说了什么内容?

data目录下的文本,开发者在调试时可以自己随意添加,网上随便找的文章都可以

图4-知识文本内容

文章内容是一篇非常具有代表性的时政人物介绍新闻,那么我们就根据该文章的内容进行问答!

问题1:苏州2022年全市的GDP是多少?

图5-问答调试

问题2:吉林省宣传部部长现在是谁?

图6-问答调试1

通过第一个问题,你是否可以发现问题呢?,如果你问ChatGPT一样的问题,它能准确回答吗?

以下是ChatGPT的回答

图7-ChatGPT回答内容

通过对比ChatGPT,开发者应该能看到一个基础的对比效果,主要体现:

  • 我们都知道ChatGPT大模型的内容日期截止到2021年,之后世界发生了什么,它并不知道,同类的GPT大模型也会出现一样的问题,因为训练大模型的代价是非常昂贵的,不可能按周、月,甚至是年的频率去更新大模型。
  • 基于现有的知识回答内容(RAG),能够有效的避免大模型胡说八道,而且回答的更精准

技术实现

进行问答体验后,我们来看具体的Java代码实现。

新建Spring Boot项目,工程目录如下:

图8-Java代码目录结构

从上文的RAG流程图中,我们知道了主要分两个步骤来实现,分别是数据的向量处理问答

由于是通过Spring Shell进行实现,因此这里我也分开,主要实现了两个Command命令:

  • add:在data目录下,为了演示需要,存放了两个txt内容,可以通过add file名称来实现文档的向量化流程加载处理,数据的处理开发者在实际的生产过程中可以通过定时任务、MQ消息等方式进行异步处理。
  • chat:通过命令chat 问题即可在Spring Shell的命令行终端进行对话,可以问data目录下相关的问题

为了方便后续的处理,程序启动时即会自动构建向量数据库的索引集合,代码如下:

/*** 初始化向量数据库index* @param collectionName 名称* @param dim 维度*/public boolean initCollection(String collectionName,int dim){log.info("collection:{}", collectionName);// 查看向量索引是否存在,此方法为固定默认索引字段IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(IndexCoordinates.of(collectionName));if (!indexOperations.exists()) {// 索引不存在,直接创建log.info("index not exists,create");//创建es的结构,简化处理Document document = Document.from(this.elasticMapping(dim));// 创建indexOperations.create(new HashMap<>(), document);return true;}return true;}

Es中的Index的Mapping结构如下:

图9-ES向量Index-Mapping结构

开发者需要注意vector字段,字段类型时dense_vector,并且指定向量维度为1024

向量维度的长度指定是和最终向量Embedding模型息息相关的,不同的模型有不同的维度,比如ChatGPT的向量模型维度是1536,百度文心一言也有368的,因此根据实际情况进行选择。

而这里因为我们选择的是智谱AI的向量模型,该模型返回的维度为1024,那么我们在向量数据库的维度就设置为1024

首先是add命令实现文档的向量化过程处理,代码如下:

@Slf4j
@AllArgsConstructor
@ShellComponent
public class AddTxtCommand {final TxtChunk txtChunk;final VectorStorage vectorStorage;final ZhipuAI zhipuAI;@ShellMethod(value = "add local txt data")public String add(String doc){log.info("start add doc.");// 加载List<ChunkResult> chunkResults= txtChunk.chunk(doc);// embeddingList<EmbeddingResult> embeddingResults=zhipuAI.embedding(chunkResults);// store vectorString collection= vectorStorage.getCollectionName();vectorStorage.store(collection,embeddingResults);log.info("finished");return "finished docId:{}"+doc;}
}

我们完全按照图1RAG的流程架构图进行代码的变现,主要的步骤:

1、加载指定的文档,并且将文档内容进行分割处理(按固定size大小进行分割处理),得到分割集合chunkResults,代码如下:

@Slf4j
@Component
@AllArgsConstructor
public class TxtChunk {public List<ChunkResult> chunk(String docId){String path="data/"+docId+".txt";log.info("start chunk---> docId:{},path:{}",docId,path);// 读取data目录下的文件流ClassPathResource classPathResource=new ClassPathResource(path);try {// 读取为文本String txt=IoUtil.read(classPathResource.getInputStream(), StandardCharsets.UTF_8);//按固定字数分割,256String[] lines=StrUtil.split(txt,256);log.info("chunk size:{}", ArrayUtil.length(lines));List<ChunkResult> results=new ArrayList<>();//此处给每个文档一个固定的chunkIdAtomicInteger atomicInteger=new AtomicInteger(0);for (String line:lines){ChunkResult chunkResult=new ChunkResult();chunkResult.setDocId(docId);chunkResult.setContent(line);chunkResult.setChunkId(atomicInteger.incrementAndGet());results.add(chunkResult);}return results;} catch (IOException e) {log.error(e.getMessage());}return new ArrayList<>();}}

2、将分块的集合通过智谱AI提供的向量Embedding模型进行向量化处理,代码实现如下:

/*** 批量* @param chunkResults 批量文本* @return 向量*/public List<EmbeddingResult> embedding(List<ChunkResult> chunkResults){log.info("start embedding,size:{}",CollectionUtil.size(chunkResults));if (CollectionUtil.isEmpty(chunkResults)){return new ArrayList<>();}List<EmbeddingResult> embeddingResults=new ArrayList<>();for (ChunkResult chunkResult:chunkResults){//分别处理embeddingResults.add(this.embedding(chunkResult));}return embeddingResults;}public EmbeddingResult embedding(ChunkResult chunkResult){//获取智谱AI的开发KeyString apiKey= this.getApiKey();// 初始化http客户端OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(20000, TimeUnit.MILLISECONDS).readTimeout(20000, TimeUnit.MILLISECONDS).writeTimeout(20000, TimeUnit.MILLISECONDS).addInterceptor(new ZhipuHeaderInterceptor(apiKey));OkHttpClient okHttpClient = builder.build();EmbeddingResult embedRequest=new EmbeddingResult();embedRequest.setPrompt(chunkResult.getContent());embedRequest.setRequestId(Objects.toString(chunkResult.getChunkId()));// 智谱embedding模型接口Request request = new Request.Builder().url("https://open.bigmodel.cn/api/paas/v3/model-api/text_embedding/invoke").post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), GSON.toJson(embedRequest))).build();try {Response response= okHttpClient.newCall(request).execute();String result=response.body().string();ZhipuResult zhipuResult= GSON.fromJson(result, ZhipuResult.class);EmbeddingResult ret= zhipuResult.getData();ret.setPrompt(embedRequest.getPrompt());ret.setRequestId(embedRequest.getRequestId());return  ret;} catch (IOException e) {throw new RuntimeException(e);}}

3、向量处理成功后,我们即可将向量数据存储在向量数据库中间件(ElasticSearch)中,调用vectorStorage.store处理,代码如下:

public void store(String collectionName,List<EmbeddingResult> embeddingResults){//保存向量log.info("save vector,collection:{},size:{}",collectionName, CollectionUtil.size(embeddingResults));List<IndexQuery> results = new ArrayList<>();for (EmbeddingResult embeddingResult : embeddingResults) {ElasticVectorData ele = new ElasticVectorData();ele.setVector(embeddingResult.getEmbedding());ele.setChunkId(embeddingResult.getRequestId());ele.setContent(embeddingResult.getPrompt());results.add(new IndexQueryBuilder().withObject(ele).build());}// 构建数据包List<IndexedObjectInformation> bulkedResult = elasticsearchRestTemplate.bulkIndex(results, IndexCoordinates.of(collectionName));int size = CollectionUtil.size(bulkedResult);log.info("保存向量成功-size:{}", size);}
}

至此,整个文本数据的Embedding处理就完成了。

数据处理完成后,接下来我们需要实现问答chat命令,来看代码实现:

@AllArgsConstructor
@Slf4j
@ShellComponent
public class ChatCommand {final VectorStorage vectorStorage;final ZhipuAI zhipuAI;@ShellMethod(value = "chat with files")public String chat(String question){if (StrUtil.isBlank(question)){return "You must send a question";}//句子转向量double[] vector=zhipuAI.sentence(question);// 向量召回String collection= vectorStorage.getCollectionName();String vectorData=vectorStorage.retrieval(collection,vector);if (StrUtil.isBlank(vectorData)){return "No Answer!";}// 构建PromptString prompt= LLMUtils.buildPrompt(question,vectorData);zhipuAI.chat(prompt);// 大模型对话//return "you question:{}"+question+"finished.";return StrUtil.EMPTY;}}

Chat命令主要包含的步骤如下:

1、将用户的问句首先通过向量Embedding模型转化得到一个多维的浮点型向量数组,代码如下:

/*** 获取句子的向量* @param sentence 句子* @return 向量*/public double[] sentence(String sentence){ChunkResult chunkResult=new ChunkResult();chunkResult.setContent(sentence);chunkResult.setChunkId(RandomUtil.randomInt());EmbeddingResult embeddingResult=this.embedding(chunkResult);return embeddingResult.getEmbedding();}

2、根据向量数据查询向量数据库召回相似的段落内容,vectorStorage.retrieval方法代码如下:

public String retrieval(String collectionName,double[] vector){// Build the script,查询向量Map<String, Object> params = new HashMap<>();params.put("query_vector", vector);// 计算cos值+1,避免出现负数的情况,得到结果后,实际score值在减1再计算Script script = new Script(ScriptType.INLINE, Script.DEFAULT_SCRIPT_LANG, "cosineSimilarity(params.query_vector, 'vector')+1", params);ScriptScoreQueryBuilder scriptScoreQueryBuilder = new ScriptScoreQueryBuilder(QueryBuilders.boolQuery(), script);// 构建请求NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(scriptScoreQueryBuilder).withPageable(Pageable.ofSize(3)).build();SearchHits<ElasticVectorData> dataSearchHits = this.elasticsearchRestTemplate.search(nativeSearchQuery, ElasticVectorData.class, IndexCoordinates.of(collectionName));//log.info("检索成功,size:{}", dataSearchHits.getTotalHits());List<SearchHit<ElasticVectorData>> data = dataSearchHits.getSearchHits();List<String> results = new LinkedList<>();for (SearchHit<ElasticVectorData> ele : data) {results.add(ele.getContent().getContent());}return CollectionUtil.join(results,"");}

这里主要利用了ElasticSearch提供的cosineSimilarity余弦相似性函数,计算向量得到相似度的分值,分值会在区间[0,1]之间,如果无限趋近于1那么代表用户输入的句子和之前我们存储在向量中的句子是非常相似的,越相似代表我们找到了语义相近的文档内容,可以作为最终构建大模型Prompt的基础内容。

向量矩阵的计算除了余弦相似性,还有IP点积、欧几里得距离等等,根据实际情况选择不同的算法实现。

3、向量召回Top3得到相似的语义文本内容后,我们就可以构建Prompt了,并且发送给大模型,Prompt如下:

public static String buildPrompt(String question,String context){return "请利用如下上下文的信息回答问题:" + "\n" +question + "\n" +"上下文信息如下:" + "\n" +context + "\n" +"如果上下文信息中没有帮助,则不允许胡乱回答!";}

而在构建Prompt时,我们可以遵循一个最简单的框架范式,RTF框架(Role-Task-Format)

  • R-Role:指定GPT大模型担任特定的角色
  • T-Task:任务,需要大模型做的事情
  • F-Format:大模型返回的内容格式(常规情况下可以忽略)

4、最后是调用大模型,实现sse流式调用输出,代码如下:

 public void chat(String prompt){try {OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(20000, TimeUnit.MILLISECONDS).readTimeout(20000, TimeUnit.MILLISECONDS).writeTimeout(20000, TimeUnit.MILLISECONDS).addInterceptor(new ZhipuHeaderInterceptor(this.getApiKey()));OkHttpClient okHttpClient = builder.build();ZhipuChatCompletion zhipuChatCompletion=new ZhipuChatCompletion();zhipuChatCompletion.addPrompt(prompt);// 采样温度,控制输出的随机性,必须为正数// 值越大,会使输出更随机,更具创造性;值越小,输出会更加稳定或确定zhipuChatCompletion.setTemperature(0.7f);zhipuChatCompletion.setTop_p(0.7f);EventSource.Factory factory = EventSources.createFactory(okHttpClient);ObjectMapper mapper = new ObjectMapper();String requestBody = mapper.writeValueAsString(zhipuChatCompletion);Request request = new Request.Builder().url("https://open.bigmodel.cn/api/paas/v3/model-api/chatglm_std/sse-invoke").post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody)).build();CountDownLatch countDownLatch=new CountDownLatch(1);// 创建事件,控制台输出EventSource eventSource = factory.newEventSource(request, new ConsoleEventSourceListener(countDownLatch));countDownLatch.await();} catch (Exception e) {log.error("llm-chat异常:{}", e.getMessage());}}

SSE流式的调用我们使用了okhttp-sse组件提供的功能快速实现。

好了,整个工程层面的Java代码实现就已经全部完成了。

最后

以上就是本片分享的全部内容了,通过Java开发语言,实现一个最小可用级别的RAG大模型应用!相信你看完本文后,也能够对AI大模型应用的开发有一个基本的了解。

那么,我们该如何学习大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一、大模型全套的学习路线

学习大型人工智能模型,如GPT-3、BERT或任何其他先进的神经网络模型,需要系统的方法和持续的努力。既然要系统的学习大模型,那么学习路线是必不可少的,下面的这份路线能帮助你快速梳理知识,形成自己的体系。

L1级别:AI大模型时代的华丽登场

L2级别:AI大模型API应用开发工程

L3级别:大模型应用架构进阶实践

L4级别:大模型微调与私有化部署

一般掌握到第四个级别,市场上大多数岗位都是可以胜任,但要还不是天花板,天花板级别要求更加严格,对于算法和实战是非常苛刻的。建议普通人掌握到L4级别即可。

以上的AI大模型学习路线,不知道为什么发出来就有点糊,高清版可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

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

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

相关文章

PostgreSql中使用to_char函数、date()函数可能会导致索引无法充分利用,导致查询速度无法提升

今天在处理接口请求速度慢的问题&#xff0c;惊奇的发现加了索引&#xff0c;但还是请求很忙。由于card_stop_info表有300w条数据&#xff0c;这时候关联查询非常慢&#xff0c;于是我加上匹配项索引&#xff0c;但是发现依然没有改变速度。。这时候去搜了一下才知道pgsql的to_…

Python提取PowerPoint演示文稿表格保存到文本及Excel文件

PowerPoint作为广泛使用的演示工具&#xff0c;常被用于展示各类数据报告和分析结果&#xff0c;其中&#xff0c;表格以其直观性和结构性成为阐述数据关系的不二之选。然而&#xff0c;在数据分析、文档归档或跨平台分享的场景下&#xff0c;幻灯片中的表格功能难以满足需求&a…

Qt全局快捷键QGlobalHotKey的自研之路

这两天对Qt的快捷键格外感兴趣。 前两天在使用QHotKey的过程中&#xff0c;发现不能定义小键盘键盘码&#xff0c;自己二次修改了该库之后已经可以设置小键盘快捷键了。文章在这里&#xff1a;Qt第三方库QHotKey设置小键盘数字快捷键。 昨天突发奇想&#xff1a;目前所有的快…

# RocketMQ 实战:模拟电商网站场景综合案例(十一)

RocketMQ 实战&#xff1a;模拟电商网站场景综合案例&#xff08;十一&#xff09; 一、RocketMQ 实战&#xff1a;模拟电商网站场景综合案例-- web 端项目开发 1、在 shop-order-web 工程模块中&#xff0c;创建 Controller 类 OrderControllre.java /*** shop\shop-order…

DBeaverUE Mac版:数据库管理新纪元,一键掌控所有数据

DBeaverUE for Mac是一款卓越的数据库管理软件&#xff0c;专为Mac用户设计&#xff0c;提供了一套高效、稳定且全面的数据库解决方案。以下是关于这款插件的详细介绍&#xff1a; 1. 强大的数据库支持 DBeaverUE for Mac支持多种数据库系统&#xff0c;包括但不限于MySQL、Po…

电脑自带录屏在哪?电脑录屏,4个详细方法

在现代社会中&#xff0c;越来越多的人需要在电脑上录制视频&#xff0c;比如录制游戏操作、制作教学视频、演示文稿等等。因此&#xff0c;电脑录屏成为了一项非常重要的功能。那么电脑自带录屏在哪&#xff1f;本文将带领大家看看可以使用哪些方法进行录屏。 录屏方法一&…

比人工快100倍!给3D模型用上轻量化,老爷机也能起飞!!!!!!

3D可视化开发&#xff0c;考虑最多的要素&#xff0c;当属模型加载流畅度和应用性。但面对单位的电脑、不能升级硬盘的笔记本等&#xff0c;可能还是无法体会到模型丝滑加载的畅快。 况且3D模型数据、格式等&#xff0c;也在不断发展扩充&#xff0c;昔日手工就能“调教”的3D…

centos7.5安装Node.js 20.5.1后报段错误(吐核)

centos7.5安装Node.js 20.5.1后报段错误 缘起 开发要求安装Node.js 20.5.1以解决dependencyCheck扫描出来的各种安全问题。安装过程 1、 下载安装Node.js 20.5.1 wget https://nodejs.org/download/release/v20.5.1/node-v20.5.1-linux-x64.tar.gztar -xzf node-v20.5.1-li…

linxu-Ubuntu系统上卸载Kubernetes-k8s

如果您想从Ubuntu系统上卸载Kubernetes集群&#xff0c;您需要执行以下步骤&#xff1a; 1.关闭Kubernetes集群&#xff1a; 如果您的集群还在运行&#xff0c;首先您需要使用kubeadm命令来安全地关闭它&#xff1a; sudo kubeadm reset在执行该命令后&#xff0c;系统会提示…

【OceanBase诊断调优】 —— DDL时报磁盘不足问题排查

1. 背景 由于在4.x的部分版本中&#xff0c;我们对于一些ddl操作还存在磁盘空间放大问题&#xff0c;本文主要介绍了这一类问题的排查。 2. 问题排查 2.1 整体排查链路 2.2 问题现象 DDL过程中报磁盘空间不足&#xff0c;需要确认是否符合预期&#xff0c;如果是符合预期&a…

客厅3d模型素材下载哪家好?

客厅是家庭生活中最重要的空间之一&#xff0c;承载着家人的欢聚、交流和休息。而客厅3D模型让家居设计师更好的完成设计布局和设计规划&#xff0c;为用户呈现出一个更加真实的家居空间。那么客厅3d模型素材下载哪家好? 1、建e网的3D模型库不仅数量庞大&#xff0c;而且质量上…

高考后志愿填报信息采集系统制作指南

在高考的硝烟散去之后&#xff0c;每位学生都面临着一个重要的任务——志愿填报。老师们如何高效、准确地收集和整理这些信息&#xff0c;成为了一个棘手的问题。难道我们只能依赖传统的手工登记方式&#xff0c;忍受其繁琐和易错吗&#xff1f; 易查分是一个简单易用的在线工具…

Kaggle -- Multi-Class Prediction of Obesity Risk

使用简单的决策树进行分类&#xff0c;代码如下&#xff1a; import pandas as pd import numpy as np from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_splitdf pd.read_csv("train.csv")df[Gender] df[Gender…

Word同行内的文字如何左右分别对齐

先打开标尺&#xff08;视图-标尺&#xff09; 开右边&#xff0c;选一个制表位置&#xff0c;比如我选34 切回开始&#xff0c;点段落段落右下角 然后 然后 我修改为35&#xff08;因为“6月13日”总共3个字符&#xff09; 在文字中间按下Tab键&#xff0c;效果如下

流程设计的基本步骤

背景 公司为什么要流程&#xff0c;已经有专门章节进行阐述&#xff1b; 什么是流程&#xff0c;已经有专门章节进行专门阐述&#xff1b; 那么接下来这个章节讨论&#xff0c;流程设计的基本步骤&#xff0c;那么谁来设计流程呢&#xff0c;让一个部门的员工来设计一份流程…

【嵌入式DIY实例】-Nokia 5110显示DHT11/DHT22传感器数据

Nokia 5110显示DHT11/DHT22传感器数据 文章目录 Nokia 5110显示DHT11/DHT22传感器数据1、硬件准备2、代码实现2.1 显示DHT11数据2.2 显示DHT22数据本文介绍如何将 ESP8266 NodeMCU 开发板 (ESP-12E) 与 DHT11 数字湿度和温度传感器以及诺基亚 5110 LCD 连接。 NodeMCU 从 DHT11…

某国资集团数据治理落地,点燃高质量发展“数字引擎”

​某国有资产经营控股集团为快速提升集团的内控管理能力和业务经营能力&#xff0c;以数字化促进企业转型的信息化建设势在必行。集团携手亿信华辰开启数据治理项目&#xff0c;在数据方面成功解决“哪里来、怎么盘、怎么管、怎么用”的问题&#xff0c;不断推动企业数字化转型…

Kali Linux 2022.2 发布,包含 10 个新工具和WSL 改进

Offensive Security发布了Kali Linux 2022.2&#xff0c;这是2022年的第二个版本&#xff0c;具有桌面增强功能&#xff0c;有趣的愚人节屏幕保护程序&#xff0c;WSL GUI改进&#xff0c;终端调整&#xff0c;最重要的是&#xff0c;新的工具&#xff01; Kali Linux是一个Li…

element 树组件 tree 横向纵向滚动条

Html <el-cardshadow"hover"class"solo flex-2"style"height: calc(100vh - 1.6rem); border: 1px solid #ebeef5"><div slot"header" class"clearfix"><span>问题分类</span></div><div …

uniapp地图导航

我们只需要给图标加一个点击事件 我这里的数据都是动态的&#xff0c;想测试的朋友可以写固定值 然后跳转之后首先会调到选择软件导航 点击导航之后会显示使用哪个app 最后我们选择之后将会直接跳转到app进行导航