当前位置: 首页 > news >正文

【项目日记(二)】搜索引擎-索引制作

❣博主主页: 33的博客❣
▶️文章专栏分类:项目日记◀️
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你了解更多项目内容

在这里插入图片描述

目录

  • 1.前言
  • 2.索引结构
    • 2.1创捷索引
    • 2.2根据索引查询
    • 2.3新增文档
    • 2.4内存索引保存到磁盘
    • 2.5把磁盘索引加载到内存
  • 3.性能优化
    • 3.1多线程
    • 3.2线程安全
    • 3.3CountDownLatch类
  • 4.总结

1.前言

在上一篇文章中,我们已经介绍了索引解析,那么接下来我们继续完善我们的项目,既然已经有了解析好的索引,那么我们就需要把解析的内容添加到倒排索引和正排索引中。

2.索引结构

创建index类,通过这个类来构建索引结构
基本步骤:

  • 用ArrayList创建正排索引
  • 用HashMap创建倒排索引
  • 1.给定docid在正排索引中,查询详细信息
  • 2.给定一个词,在倒排索引中查与这个词的关联文档
  • 3.往索引中新增文档
  • 4.把内存的索引保存到磁盘
  • 5.把磁盘的索引结构保存到内存

2.1创捷索引

正排索引

private ArrayList<DocInfo> forwardIndex=new ArrayList<>();

倒排索引

private HashMap<String,ArrayList<Weight>> invertedIndex=new HashMap<>();

DocInfo类:

public class DocInfo {private int docID;private String title;private String url;private String content;public int getDocID() {return docID;}public void setDocID(int docID) {this.docID = docID;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}

Weight类:

public class Weight {private int docId;private int weight;public int getDocId() {return docId;}public void setDocId(int docId) {this.docId = docId;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}
}

2.2根据索引查询

//1.根据docId查询文档详情,数组小标就是文档idpublic DocInfo getDocInfo(int docId){return forwardIndex.get(docId);}
//2.给定一个词,查在哪些文档中public List<Weight> getInverted(String term){return invertedIndex.get(term);}   

2.3新增文档

 public void addDoc(String title,String url,String content){//给正排索引新增和倒排索引都新增信息//构建正排索引DocInfo docInfo=buildForward(title,url,content);//创建倒排索引buildInverted(docInfo);}

在正排索引中添加文档:

private DocInfo buildForward(String title, String url, String content) {DocInfo docInfo=new DocInfo();docInfo.setTitle(title);docInfo.setUrl(url);docInfo.setContent(content);//巧妙设计:docInfoId的下标和数组下标一一对应docInfo.setDocID(forwardIndex.size());forwardIndex.add(docInfo);return docInfo;}

在倒排索引中新增文档
1.需要统计每一个词在文档中的出现次数,在根据次数算出权重
2.首先进行分词操作,统计每一个不同的词在标题中出现的次数
3.再进行分词操作,统计每一个词在正文出现的次数
4.设置权重为标题次数*10+正文次数

 private void buildInverted(DocInfo docInfo) {class WordCnt{public int titleCount;public int contentCount;}HashMap<String,WordCnt> wordCntHashMap=new HashMap<>();//1.针对标题进行分词操作List<Term> terms= ToAnalysis.parse(docInfo.getTitle()).getTerms();//2.针对分词结果,统计每个词出现的次数for (Term term:terms){String word=term.getName();WordCnt wordCnt=wordCntHashMap.get(word);if (wordCnt==null){WordCnt newwordCnt=new WordCnt();newwordCnt.titleCount=1;newwordCnt.contentCount=0;wordCntHashMap.put(word,newwordCnt);}else {wordCnt.titleCount+=1;}}//3.针对正文进行分词操作List<Term> terms2=ToAnalysis.parse(docInfo.getContent()).getTerms();//4.遍历分词结果,统计每个词出现的次数for (Term term:terms2){String word=term.getName();WordCnt wordCnt=wordCntHashMap.get(word);if (wordCnt==null){WordCnt newWordCnt=new WordCnt();newWordCnt.titleCount=0;newWordCnt.contentCount=1;wordCntHashMap.put(word,newWordCnt);}else {wordCnt.contentCount+=1;}}//5.设置权重为:标题*10+正文//一个对象必须实现了Iterable接口才能使用for each进行遍历,而Map并没有实现该接口,但Set实现了,所以就把Map转换为Setfor(Map.Entry<String,WordCnt> entry:wordCntHashMap.entrySet()) {            List<Weight> invertedList=invertedIndex.get(entry.getKey());if (invertedList==null){ArrayList<Weight> newInvertedList=new ArrayList<>();Weight weight=new Weight();weight.setWeight(entry.getValue().titleCount*10+entry.getValue().contentCount);weight.setDocId(docInfo.getDocID());newInvertedList.add(weight);invertedIndex.put(entry.getKey(),newInvertedList);}else {Weight weight=new Weight();weight.setDocId(docInfo.getDocID());weight.setWeight(entry.getValue().titleCount*10+entry.getValue().contentCount);invertedList.add(weight);}        }}

2.4内存索引保存到磁盘

索引当前是存储在内存中的,构造索引的过程是非常耗时的,因此我们就不应该再服务器启动时才去构造索引,通常就把这些耗时的操作,单独执行完成之后,然后再让线上的服务器加载构造好的索引。
我们就把内存中构造的索引结构,给变成一个字符串,然后写入文件即可,这个操作就叫序列化。适应Jackson中的ObjectMapper来完成此操作。

 private static  String INDEX_PATH="D:/doc_searcher_index/";public void save(){long beg=System.currentTimeMillis();System.out.println("保存索引开始!");File indexPathFile=new File(INDEX_PATH);if(!indexPathFile.exists()){indexPathFile.mkdir();}File forwardIndexFile=new File(INDEX_PATH+"forward.txt");File invertedIndexFile=new File(INDEX_PATH+"inverted.txt");try {//利用ObjectMapperJava对象转换为JSON格式//从内存中读取forwardIndex保存到forwardIndexFileobjectMapper.writeValue(forwardIndexFile,forwardIndex);//从内存中读取nvertedIndex保存到invertedIndexFileforwardIndexFileobjectMapper.writeValue(invertedIndexFile,invertedIndex);}catch (IOException e) {e.printStackTrace();}long end=System.currentTimeMillis();System.out.println("保存索引完成!消耗时间:"+(end-beg)+"ms");}

2.5把磁盘索引加载到内存

public void load(){long beg=System.currentTimeMillis();System.out.println("加载索引开始!");File forwardIndexFile=new File(INDEX_PATH+"forward.txt");File invertedIndexFile=new File(INDEX_PATH+"inverted.txt");try {forwardIndex=objectMapper.readValue(forwardIndexFile, new TypeReference<ArrayList<DocInfo>>() {});invertedIndex=objectMapper.readValue(invertedIndexFile, new TypeReference<HashMap<String, ArrayList<Weight>>>() {});}catch (IOException e){e.printStackTrace();}long end=System.currentTimeMillis();System.out.println("加载引擎结束消耗时间:"+(end-beg)+"ms");}

parser相当于制作索引的入口,对应到一个可执行的程序
index相当于实现了索引的数据结构,提供一些Api
接下来我们就在parser里面调用对应的api
在parser类中解析完Html文件时,应添加到索引中

private  void parseHTML(File f) {//1.解析HTML标题String title=parseTitle(f);//2.解析HTML的URLString url=parseUrl(f);//3.解析HTML的正文long beg=System.nanoTime();//String content=parseContent(f);String content=parseContentByRegex(f);long mid=System.nanoTime();//把解析出来的信息加载到索引index.addDoc(title,url,content);         }

在添加完索引之后,应该把索引保存到磁盘

public void run()  {long beg=System.currentTimeMillis();System.out.println("索引制作开始");//1.枚举出INPUT_PATH下的所有html文件ArrayList<File> fileList=new ArrayList<>();enumFile(INPUT_PATH,fileList);//2.解析文档内容for (File f:fileList){System.out.println("开始解析"+f.getAbsolutePath()+"....");parseHTML(f);}//3.把内存构造的索引保存到磁盘index.save();long end=System.currentTimeMillis();System.out.println("索引制作结束!消耗时间:"+(end-beg)+"ms");}

3.性能优化

此时我们已经完成了文档解析和索引制作模块,那么我们进行验证
在这里插入图片描述
文档内容正确生成:
在这里插入图片描述
在这里插入图片描述
但我们观察索引制作的时间:一个消耗了19973ms就是19s,花费的时间是比较长的,那么有什么办法提高效率呢?方法当然是有的,首先我们得清楚具体是哪一个步骤拖慢了执行效率,我们来分析代码:
在这里插入图片描述
可以看到解析文档的时候从磁盘读文件,循环遍历文件操作,那么显然效率是非常慢的,既然一个线程串行执行效率非常慢,那么我们就采用多线程并发执行来提高效率。

3.1多线程

我们可以使用创建一个线程池来实现并发操作。通过submit往线程池中提价任务,操作极快(只是把Runnable对象放入阻塞队列中)。
把代码改进成多线程的版本,线程池中的线程数目具体设置成多少才合适呢?最好通过实验来确定。

public void run()  {long beg=System.currentTimeMillis();System.out.println("索引制作开始");//1.枚举出INPUT_PATH下的所有html文件ArrayList<File> fileList=new ArrayList<>();enumFile(INPUT_PATH,fileList);ExecutorService executorService= Executors.newFixedThreadPool(6);//2.解析文档内容for (File f:files){executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("解析:"+f.getAbsolutePath());parseHTML(f);                    }});}//3.把内存构造的索引保存到磁盘index.save();long end=System.currentTimeMillis();System.out.println("索引制作结束!消耗时间:"+(end-beg)+"ms");}

3.2线程安全

我们既然引入了多线程就要考虑线程安全问题,要注意修改操作读写操作。当多个线程同时尝试修改同一个共享数据时,需要确保数据的一致性,避免出现竞态条件。读写操作:如果一个线程在读取共享数据的同时另一个线程在修改该数据,可能导致读取到不一致或无效的数据。
那么我们就需要对程序进行加锁操作:
在这里插入图片描述
在这里插入图片描述

3.3CountDownLatch类

添加锁虽然解决了线程安全问题,依然有新的问题,那就是在所有文件提交完成后就会立即执行save()操作,但是可能文件解析还没有完成。为了解决这样的问题,我们就引入 CountDownLatch类。
CountDownLatch类类似于跑步比赛的裁判,只有所有的选手都撞线了,就认为这场比赛结束了。再构造 CountDownLatch的时候指定一下比赛选手的个数,每个选手撞线都要通知一下countDown(),通过await来等待所有的选手都撞线完毕才执行save()操作。

public void runByThread(){long beg=System.currentTimeMillis();System.out.println("索引开始制作");//1.枚举出INPUT_PATH下的所有html文件ArrayList<File> files=new ArrayList<>();enumFile(INPUT_PATH,files);//2.解析文档内容CountDownLatch latch=new CountDownLatch(files.size());ExecutorService executorService= Executors.newFixedThreadPool(6);for (File f:files){executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("解析:"+f.getAbsolutePath());parseHTML(f);latch.countDown();}});}try {//await会阻塞,把所有选手都调用countDown以后才会继续执行latch.await();} catch (InterruptedException e) {throw new RuntimeException(e);}//手动的把线程池里面的线程杀掉executorService.shutdown();//3.把内存构造的索引保存到磁盘index.save();long end=System.currentTimeMillis();System.out.println("索引制作结束!消耗时间:"+(end-beg)+"ms");System.out.println("t1:"+t1+"t2"+t2);}

4.总结

这篇文章主要完成了索引制作模块,以及进行了性能优化,在下一篇文章中将进行搜索模块的制作。

下期预告:项目日记(三)

相关文章:

【项目日记(二)】搜索引擎-索引制作

❣博主主页: 33的博客❣ ▶️文章专栏分类:项目日记◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多项目内容 目录 1.前言2.索引结构2.1创捷索引2.2根据索引查询2.3新增文档2.4内存索引保存到磁盘2.5把…...

K 近邻、K-NN 算法图文详解

1. 为什么学习KNN算法 KNN是监督学习分类算法&#xff0c;主要解决现实生活中分类问题。根据目标的不同将监督学习任务分为了分类学习及回归预测问题。 KNN&#xff08;K-Nearest Neihbor&#xff0c;KNN&#xff09;K近邻是机器学习算法中理论最简单&#xff0c;最好理解的算法…...

Eclipse + GDB + J-Link 的单片机程序调试实践

Eclipse GDB J-Link 的调试实践 本文介绍如何创建Eclipse的调试配置&#xff0c;如何控制调试过程&#xff0c;如何查看修改各种变量。 对 Eclipse 的要求 所用 Eclipse 应当安装了 Eclipse Embedded CDT 插件。从 https://www.eclipse.org/downloads/packages/ 下载 Ecli…...

前端代码生成辅助工具

1&#xff0c;Axure Axure设计的界面如何生成HTML文件 https://blog.csdn.net/qq_43279782/article/details/112387511 Axure 生成HTML 文件&#xff0c;并用Chrome打开 https://blog.csdn.net/qq_30718137/article/details/80621025 2&#xff0c;OpenUI [开源] OpenUI …...

静态库与动态库总结

一、库文件和头文件 所谓库文件&#xff0c;可以将其理解为压缩包文件&#xff0c;该文件内部通常包含不止一个目标文件&#xff08;也就是二进制文件&#xff09;。 值得一提的是&#xff0c;库文件中每个目标文件存储的代码&#xff0c;并非完整的程序&#xff0c;而是一个…...

深入解析tcpdump:网络数据包捕获与分析的利器

引言 在网络技术日新月异的今天&#xff0c;网络数据包的捕获与分析成为了网络管理员、安全专家以及开发人员不可或缺的技能。其中&#xff0c;tcpdump作为一款强大的网络数据包捕获分析工具&#xff0c;广泛应用于Linux系统中。本文将从技术人的角度&#xff0c;详细分析tcpdu…...

【漏洞复现】科立讯通信有限公司指挥调度管理平台uploadgps.php存在SQL注入

0x01 产品简介 科立讯通信指挥调度管理平台是一个专门针对通信行业的管理平台。该产品旨在提供高效的指挥调度和管理解决方案&#xff0c;以帮助通信运营商或相关机构实现更好的运营效率和服务质量。该平台提供强大的指挥调度功能&#xff0c;可以实时监控和管理通信网络设备、…...

什么是自然语言处理(NLP)?详细解读文本分类、情感分析和机器翻译的核心技术

什么是自然语言处理&#xff1f; 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能的一个重要分支&#xff0c;旨在让计算机理解、解释和生成人类的自然语言。打个比方&#xff0c;你和Siri对话&#xff0c;或使用谷歌翻译翻译一…...

【linux】gcc快速入门教程

目录 一.gcc简介 二.gcc常用命令 一.gcc简介 gcc 是GNU Compiler Collection&#xff08;GNU编译器套件&#xff09;。就是一个编译器。编译一个源文件的时候可以直接使用&#xff0c;但是源文件数量太多时&#xff0c;就很不方便&#xff0c;于是就出现了make 工具 二.gcc…...

【多维动态规划】Leetcode 97. 交错字符串【中等】

交错字符串 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串 子字符串 是字符串中连续的 非空 字符序列。 s s1 s2 … snt…...

【JavaScript脚本宇宙】精通前端开发:六大热门CSS框架详解

前端开发的利器&#xff1a;深入了解六大CSS框架 前言 在现代Web开发中&#xff0c;选择适合的前端框架和工具包是构建高效、响应式和美观的网站或应用程序的关键。本文将详细介绍六个广受欢迎的CSS框架&#xff1a;Bootstrap、Bulma、Tailwind CSS、Foundation、Materialize…...

开发技术-Java集合(List)删除元素的几种方式

文章目录 1. 错误的删除2. 正确的方法2.1 倒叙删除2.2 迭代器删除2.3 removeAll() 删除2.4 removeIf() 最简单的删除 3. 总结 1. 错误的删除 在写代码时&#xff0c;想将其中的一个元素删除&#xff0c;就遍历了 list &#xff0c;使用了 remove()&#xff0c;发现效果并不是想…...

c++ 递归

递归函数是指在函数定义中调用自身的函数。C语言也支持递归函数。 下面是一个使用递归函数计算阶乘的例子&#xff1a; #include <iostream> using namespace std;int factorial(int n) {// 基本情况&#xff0c;当 n 等于 0 或 1 时&#xff0c;阶乘为 1if (n 0 || n…...

RedHat9 | podman容器

1、容器技术介绍 传统问题 应用程序和依赖需要一起安装在物理主机或虚拟机上的操作系统应用程序版本比当前操作系统安装的版本更低或更新两个应用程序可能需要某一软件的不同版本&#xff0c;彼此版本之间不兼容 解决方式 将应用程序打包并部署为容器容器是与系统的其他部分…...

边缘计算项目有哪些

边缘计算项目在多个领域得到了广泛的应用&#xff0c;以下是一些典型的边缘计算项目案例&#xff1a; 1. **智能交通系统**&#xff1a;通过在交通信号灯、监控摄像头等设备上部署边缘计算&#xff0c;可以实时分析交通流量&#xff0c;优化交通信号控制&#xff0c;减少拥堵&…...

计算fibonacci数列每一项时所需的递归调用次数

斐波那契数列是一个经典的数列&#xff0c;其中每一项是前两项的和&#xff0c;定义为&#xff1a; [ F(n) F(n-1) F(n-2) ] 其中&#xff0c;( F(0) 0 ) 和 ( F(1) 1 )。 对于计算斐波那契数列的第 ( n ) 项&#xff0c;如果使用简单的递归方法&#xff0c;其时间复杂度是…...

【教学类65-05】20240627秘密花园涂色书(中四班练习)

【教学类65-03】20240622秘密花园涂色书03&#xff08;通义万相&#xff09;&#xff08;A4横版1张&#xff0c;一大 68张纸136份&#xff09;-CSDN博客 背景需求: 打印以下几款秘密花园样式&#xff08;每款10份&#xff09;给中四班孩子玩一下&#xff0c;看看效果 【教学类…...

Python 学习之基础语法(一)

Python的语法基础主要包括以下几个方面&#xff0c;下面将逐一进行分点表示和归纳&#xff1a; 一、基本语法 1. 注释 a. 单行注释&#xff1a;使用#开头&#xff0c;例如# 这是一个单行注释。 b. 多行注释&#xff1a;使用三引号&#xff08;可以是三个单引号或三个双引号&…...

日志分析-windows系统日志分析

日志分析-windows系统日志分析 使用事件查看器分析Windows系统日志 cmd命令 eventvwr 筛选 清除日志、注销并重新登陆&#xff0c;查看日志情况 Windows7和Windowserver2008R2的主机日志保存在C:\Windows\System32\winevt\Logs文件夹下&#xff0c;Security.evtx即为W…...

【ARM】MDK工程切换高版本的编译器后出现error A1137E报错

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决工程从Compiler 5切换到Compiler 6进行编译时出现一些非语法问题上的报错。 2、 问题场景 对于一些使用Compiler 5进行编译的工程&#xff0c;要切换到Compiler 6进行编译的时候&#xff0c;原本无任何报错警告…...

深入 SSH:解锁本地转发、远程转发和动态转发的潜力

文章目录 前言一、解锁内部服务&#xff1a;SSH 本地转发1.1 什么是 SSH 本地转发1.2 本地转发应用场景 二、打开外部访问大门&#xff1a;SSH 远程转发2.1 什么是 SSH 远程转发2.2 远程转发应用场景 三、动态转发&#xff1a;SSH 让你拥有自己的 VPN3.1 什么是 SSH 动态转发3.…...

python如何把一个函数的返回值,当成这个函数的参数值

python如何把一个函数的返回值&#xff0c;当成这个函数的参数值 1. 递归调用 递归是一种函数自己调用自己的方法。在递归调用中&#xff0c;你可以将前一次调用的返回值作为下一次调用的参数。 def recursive_function(x):# 函数逻辑if 条件满足:return 结果else:return rec…...

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域案例应用

随着航空、航天、近地空间遥感平台的持续发展&#xff0c;遥感技术近年来取得显著进步。遥感数据的空间、时间、光谱分辨率及数据量均大幅提升&#xff0c;呈现出大数据特征。这为相关研究带来了新机遇&#xff0c;但同时也带来巨大挑战。传统的工作站和服务器已无法满足大区域…...

SpringBoot: Eureka入门

1. IP列表 公司发展到一定的规模之后&#xff0c;应用拆分是无可避免的。假设我们有2个服务(服务A、服务B)&#xff0c;如果服务A要调用服务B&#xff0c;我们能怎么做呢&#xff1f;最简单的方法是让服务A配置服务B的所有节点的IP&#xff0c;在服务A内部做负载均衡调用服务B…...

Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等

简介 TypeScript 是 JavaScript 的超集&#xff0c;是 JavaScript&#xff08;弱类型语言&#xff09; 的强类型版本。 拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展&#x…...

智慧校园-实训管理系统总体概述

智慧校园实训管理系统&#xff0c;专为满足高等教育与职业教育的特定需求而设计&#xff0c;它代表了实训课程管理领域的一次数字化飞跃。此系统旨在通过革新实训的组织结构、执行流程及评估标准&#xff0c;来增强学生的实践操作技能和教师的授课效率&#xff0c;为社会输送具…...

如何用GPT开发一个基于 GPT 的应用?

原文发自博客&#xff1a;GPT应用开发小记 如何开发一个基于 GPT 的应用&#xff1f;答案就在问题里&#xff0c;那就是用 GPT 来开发基于 GPT 的应用。本文以笔者的一个开源项目 myGPTReader 为例&#xff0c;分享我是如何基于 GPT 去开发这个系统的&#xff0c;这个系统的功能…...

大数据生态体系中各组件的区别面试题(更新)

一、MapReduce与Spark有什么区别&#xff1f; 1、处理方式: MapReduce基于磁盘处理数据&#xff0c;将中间结果保存到磁盘中,减少了内存占用&#xff0c;计算速度慢。 基于内存处理数据&#xff0c;将计算的中间结果保存到内存中&#xff0c;计算速度快。2、资源申请方式&…...

数字信号处理实验一(离散信号及离散系统的MATLAB编程实现)

实验要求&#xff1a; 离散信号及离散系统的MATLAB编程实现&#xff08;2学时&#xff09; 要求&#xff1a; 编写一程序&#xff0c;输出一定长度&#xff08;点数&#xff09;&#xff0c;具有一定幅度、&#xff08;角&#xff09;频率和初始相位的实&#xff08;或复&…...

数字图像处理专栏——introduction

Introduction: 数字图像处理技术是我在深入学习研究的方向之一。本科期间跟随导师做基于AndroidOpenCV的病虫识别app&#xff0c;因此入门&#xff0c;我也对该部分知识有进一步探索的欲望&#xff0c;但更多的是因该脚踏实地一步步记录&#xff0c;一步步成长。 本篇从数字图…...

Django 模版继承

1&#xff0c;设计母版页 Test/templates/6/base.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><!-- 修正了模板标签的全角字符问题 -->{% block title %}<title>这个是母版页</title>{…...

Apipost接口测试工具的原理及应用详解(一)

本系列文章简介&#xff1a; 随着软件行业的快速发展&#xff0c;API&#xff08;应用程序编程接口&#xff09;作为不同软件组件之间通信的桥梁&#xff0c;其重要性日益凸显。API的质量直接关系到软件系统的稳定性、性能和用户体验。因此&#xff0c;对API进行严格的测试成为…...

一款轻量级的通信协议---MQTT (内含Linux环境搭建)

目录 MQTT MQTT的关键特点&#xff1a; 应用场景 Linux环境搭建&#xff1a; 1. 安装mosquitto 2. Linux下客户端进行通信 3. PC端和Linux下进行通信 安装MQTT. fx 4. MQTT.fx的使用 1. 点击连接 ​编辑 2. 连接成功 3. 订阅主题或者给别的主题发送消息 遇到的问…...

记netty本地客户端断线无法自动重连 or 远程客户端自动重连本地服务端

记netty客户端断线无法自动完成重连 or 服务端无法让客户端断线重连 引场景案例bootstrap 引 netty既能开发socket服务端&#xff0c;也可开发客户端&#xff0c;实现连接的全双工通信。在客户端断线重启后&#xff0c;可自动重连服务端。 场景 本地代码既有socket客户端也有…...

UNIAPP_在js文件中使用i18n国际化

导入 import { initVueI18n } from dcloudio/uni-i18n import messages from /locale/index const { t } initVueI18n(messages) 使用 t(config.request.i001)....

第三节:如何理解Spring的两个特性IOC和AOP(自学Spring boot 3.x第一天)

大家好&#xff0c;我是网创有方&#xff0c;接下来教大家如何理解Spring的两个特性IOC和AOP。本节有点难&#xff0c;大家多理解。 IOC&#xff08;控制反转&#xff09; 定义与核心思想&#xff1a; IOC&#xff0c;全称Inversion of Control&#xff0c;即控制反转。 其核…...

【51单片机】串口通信(发送与接收)

文章目录 前言串口通信简介串口通信的原理串口通信的作用串口编程的一些概念仿真图如何使用串口初始化串口串口模式波特率配置 发送与接收发送接收 示例代码 总结 前言 在嵌入式系统的开发中&#xff0c;串口通信是一种常见且重要的通信方式。它以其简单、稳定的特性在各种应用…...

【AI研发工具包】sklearn教程(Scikit-learn)

目录 1. 引言 2. 安装sklearn 3. 导入sklearn 4. 加载数据集 5. 数据预处理 6. 训练模型 7. 评估模型 8. 保存和加载模型 9. 自定义数据 10. 深入sklearn 11. 注意事项 1. 引言 Scikit-learn&#xff08;简称sklearn&#xff09;是Python中一个非常流行的机器学习库…...

数位DP——AcWing 1081. 度的数量

数位DP 定义 数位DP是一种动态规划技巧&#xff0c;特别适用于处理与数字的位操作相关的问题&#xff0c;如数字序列的计数、数字的生成等问题。它通过将问题分解为对每一位数字的独立考虑&#xff0c;从而简化问题复杂度&#xff0c;实现高效求解。 数位DP的核心思想是将原…...

2024下半年必追国漫片单,谁将问鼎巅峰?

随着2024年上半年的落幕&#xff0c;国漫市场再度迎来了百花齐放的盛况。从经典续作到全新IP&#xff0c;从玄幻到科幻&#xff0c;每一部作品都以其独特的魅力吸引着观众的目光。本期为大家盘点下半年值得一看的国漫佳作&#xff0c;大胆预测&#xff0c;谁将成为这场神仙打架…...

信息发布小程序h5 uniapp thinkphp

纯手工uniapp thinkphp 全开源打造 信息发布小程序 一、概述 信息发布小程序是一种基于微信平台的小程序应用&#xff0c;旨在为用户提供便捷的信息发布与展示服务。用户可以通过该小程序快速发布各类信息&#xff0c;如招聘、寻物、公告等&#xff0c;同时也可以浏览和搜索…...

Windows定时任务执行脚本

场景&#xff1a;由于网络波动原因导致云数据库没连接上&#xff0c;从而导致某个流程引擎链接不上数据库从而导致该流程引擎服务挂了&#xff0c;网络恢复后 数据库链接正常&#xff0c;但是该引擎服务还是中止状态。 解决方案&#xff1a;在Windows中新建一个定时任务&#…...

优维“统一开放平台”:开放、开发、集成、客制化

基于丰富完善的产品体系&#xff0c;优维重磅推出了统一开放平台。这款由优维自主设计与研发&#xff0c;集数据开发、能力开放、能力集成、客制化为一体的统一开放平台&#xff0c;具备应用市场、应用开发、连接能力、采控平台、API集市、开发者工具等功能模块&#xff0c;可为…...

ChatGPT新纪元:揭秘GPT-4o的多模态能力

GPT-4o登场 探索ChatGPT的多模态创新 今日凌晨&#xff0c;OpenAI向全球宣布了AI发展的新篇章——GPT-4o&#xff0c;每次OpenAI发布重大更新时&#xff0c;尽管令人兴奋&#xff0c;但也不免使众多初创公司的梦想破灭。 GPT-4o的命名中的“o”象征着“omni”——全能的代表。…...

泰勒斯威夫特2022年纽约大学毕业典礼演讲:NYU‘s 2022 Commencement Speaker Taylor Swift

NYU’s 2022 Commencement Speaker Taylor Swift Link: https://www.youtube.com/watch?vOBG50aoUwlI Singer, songwriter, producer, and director Taylor Swift received a Doctor of Fine Arts, honoris causa, at the Commencement for the Class of 2022 and delivered …...

(四)SvelteKit教程:调用外部 API 获取数据

&#xff08;四&#xff09;SvelteKit教程&#xff1a;调用 API 我们先按照如下的方式来构建api服务&#xff1a; step 1:npm i json-serverstep 2:在根目录下新建 db.json 文件&#xff0c;内部写入如下内容&#xff1a;{"users": [{"id": 1,"name…...

数据结构-分析期末选择题考点(排序)

何似清歌倚桃李 一炉沈水醉红灯 契子 ✨ 上一期给大家提供了大概会考的题型给老铁们复习的大致思路 这一期还会是一样&#xff0c;我将整理一下排序的题型以及解题方法给你们 由于时间还很多&#xff0c;我就慢慢总结吧&#xff0c;一天一章的样子&#xff0c;明天总结串、后天…...

Python:探索高效、智能的指纹识别技术(简单易懂)

目录 概括 导入库 函数一 参数&#xff1a; 函数二 函数三 主函数 运行结果 src&#xff1a; model_base 7.bmp ​编辑 总结 概括 指纹识别是一种基于人体生物特征的身份验证技术。它通过捕捉和分析手指上的独特纹路和细节特征&#xff0c;实现高准确度的身份识别。…...

『SD』AI绘画,不会写提示词怎么办?

提示词 有没有想过&#xff0c;为什么你用 SD 生成的猫是长这样的。 而其他人可以生成这样的猫。 虽然生成的都是猫&#xff0c;但猫与猫之间还是有差距的。 如果你的提示词只是“cat”&#xff0c;那大概率就会出现本文第一张图的那个效果。而如果你加上一些形容词&#xff…...

搭建大型分布式服务(四十二)SpringBoot 无代码侵入实现多Kafka数据源整合插件发布

系列文章目录 文章目录 系列文章目录前言MultiKafkaStarter [V2.2]一、功能特性二、快速开始&#xff08;生产端&#xff09;三、快速开始&#xff08;消费端&#xff09;四、其它特性五、变更记录六、参考文章 前言 在分布式服务的架构演进中&#xff0c;消息队列作为核心组件…...

C++部分复习笔记下

7. C11 范围for 使用格式 vector<int> v { 1,2,3,4,5 }; for (auto e : v) {cout << e << " "; } cout << endl;底层原理&#xff0c;使用迭代器 vector<int> v { 1,2,3,4,5 }; auto it v.begin(); while (it ! v.end()) {cout…...

Hack The Box-Editorial

端口扫描 web 先打开网页&#xff0c;没啥内容&#xff0c;扫个后台。 about没啥东西&#xff0c;主要应该是upload页面。 文件上传功能&#xff0c;上传本地文件&#xff0c;会被重命名&#xff0c;后缀名会被删除并且文件名重命名&#xff0c;若尝试打开链接&#xff0c…...

查看Oracle、MySQL、PostGreSQL中的依赖关系

查看Oracle、MySQL、PostGreSQL中的依赖关系 在有些程序员开发习惯中&#xff0c;喜欢为了应用代码的简洁或复用&#xff0c;而在数据库创建一个复杂关连查询的VIEW&#xff0c;甚至是VIEW套VIEW嵌套使用&#xff0c; 这里就有个问题如果上线后如发现依赖的表字段类型或长度不…...

Linux部署wordpress站点

先安装宝塔面板 yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec 因为wordpress需要php&#xff0c;mysql&#xff0c;apache &#xff0c;httpd环境 参考&#xff1a;Linux 安装宝塔…...

Spring Boot与WebFlux的实战案例

Spring Boot与WebFlux的实战案例 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我们将探讨如何利用Spring Boot和WebFlux构建响应式应用的实战…...

ED01-CMS v20180505 文件上传漏洞(CVE-2022-28525)

前言 CVE-2022-28525 是一个影响 ED01-CMS v20180505 版本的任意文件上传漏洞。该漏洞位于 /admin/users.php?sourceedit_user&id41&#xff0c;攻击者可以利用该漏洞在未经授权的情况下上传任意文件到服务器上&#xff0c;从而可能导致远程代码执行&#xff08;RCE&…...

24万落地,德系标杆SUV上新,标配丰富,诚意不输国产!

5月30日晚,上汽大众途观L Pro正式上市,全系共推出6款车型,售价23.68-26.68万元。新车采用全新外观设计,并且在智能化方面进行了升级,为了更好满足中国消费者需求,途观L Pro提供了部分中国消费者独享配置,并且与国内例如科大讯飞、大疆车载等企业合作,提供更适合中国消费…...

“翼”起降本盈运增效!欧曼星翼PRO自动挡中卡引领区域集散运输发展新趋势

在当前运输行业中,随着运价偏低、燃料价格偏高等因素影响,卡友对性价比更高的运输装备需求越发迫切。这一情况不止在重卡领域备受关注,在中卡行业里也成为卡友的心头大事!积极响应行业发展趋势,欧曼以重卡平台+自动挡双重赋能打造的欧曼星翼PRO自动挡中卡即将上市,深度契合用户…...

安全是对家人最强的守护!看星海V9如何锻造安全壁垒和不破金身

如今国产车的市场前景是越来越好了,特别是东风汽车。凭借着出色的造车技术在市场上混得风生水起。今天我们说的这款车也是来自东风汽车旗下,豪华智电头等舱MPV 星海V9全新上市。东风风行首款豪华新能源旗舰MPV——星海V9全新上市,预售价19.99万起,购车立享九重礼!东风风行…...

手机端如何访问本地vue+vite项目,实现实时调试?

一、应用场景 h5&#xff08;vuevite&#xff09;嵌入app后&#xff0c;出现某种问题时&#xff0c;需要每次发布坏境后&#xff0c;才能才看效果&#xff0c;这种来回很耗时间&#xff0c;本文章在于解决手机端直接访问本地启动应用项目&#xff0c;无需重复发布坏境 二、实…...

狠刹蜻蜓点水式调研虚风

新华社北京5月28日电 《关于在全党大兴调查研究的工作方案》印发以来,不少地方和部门在深化调查研究上务实功、出实招、求实效,用调研推动问题解决。然而在实际中,对调研安排很“上心”、对调研过程极“专注”、把“身入”当“深入”、把“过程”当“解决”的蜻蜓点水式调研…...

transformer的特点

Transformers是一种用于处理序列数据的神经网络架构&#xff0c;最初由Vaswani等人在2017年提出&#xff0c;主要用于自然语言处理任务。与传统的循环神经网络&#xff08;RNN&#xff09;和卷积神经网络&#xff08;CNN&#xff09;不同&#xff0c;Transformers采用了一种全新…...