Springboot整合全文检索引擎Lucene
文章目录
- 前言
- Lucene的介绍
- springboot项目中如何整合Lucene简单用法
- 1. 引入依赖
- 2. 其它用到的类
- 2. 创建索引
- 3. 简单搜索
- 4. 更新索引
- 5. 删除索引
- 6. 删除全部索引
- Springboot整合Lucene复杂搜索
- 1. 同时标题和内容中查找关键词
- 2. 搜索结果高亮显示关键词
- 3. 分页搜索
- 4. 多关键词联合搜索
- 关于IK扩展分词
- 什么分词?什么是扩展分词?
- 自定义分词和停止分词
前言
如何自己构建一个单机的博客检索引擎?
本章代码已分享至Gitee: https://gitee.com/lengcz/springbootlucene01
Lucene的介绍
Lucene是一个开源的全文搜索引擎工具包,它提供了用于创建、索引和搜索大量文本的API和工具。Lucene最初是由Doug Cutting于1999年创建,目的是提供一个高效、可扩展的搜索引擎。
Lucene的主要特点包括:
-
高性能:Lucene使用倒排索引来加速搜索,这使得它能够快速地检索和排序文档。
-
可扩展性:Lucene支持大规模文本索引和搜索操作,并可以通过水平扩展来处理更大量级的数据。
-
多语言支持:Lucene支持多种语言的文本索引和搜索,包括中文。
-
高级搜索功能:除了基本的文本搜索,Lucene还提供了许多高级搜索功能,例如模糊搜索、通配符搜索、范围搜索等。
-
定制化:Lucene提供了丰富的API和工具,可以根据需求进行定制化开发。
在Lucene中进行中文搜索时,需要注意以下几点:
-
分词:中文文本通常不用空格进行分词,因此需要使用中文分词器来对文本进行切分。Lucene提供了一些中文分词器,例如IK Analyzer、SmartChineseAnalyzer等。
-
中文编码:Lucene默认使用Unicode编码进行搜索,但是如果要处理中文文本,需要使用UTF-8编码。
-
中文排序:中文的排序规则与英文不同,Lucene提供了一些中文排序器来处理中文排序。
总之,Lucene是一个功能强大、灵活可定制的全文搜索引擎工具包,可以用于构建各种类型的中文搜索应用。
springboot项目中如何整合Lucene简单用法
1. 引入依赖
<!-- Lucene核心库 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>7.6.0</version></dependency><!-- Lucene的查询解析器 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-queryparser</artifactId><version>7.6.0</version></dependency><!-- Lucene的默认分词器库 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-common</artifactId><version>7.6.0</version></dependency><!-- Lucene的高亮显示 --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-highlighter</artifactId><version>7.6.0</version></dependency><!-- ik分词器 --><dependency><groupId>com.jianggujin</groupId><artifactId>IKAnalyzer-lucene</artifactId><version>8.0.0</version></dependency>
2. 其它用到的类
import lombok.Data;
import lombok.Getter;
import lombok.Setter;import java.io.Serializable;@Setter
@Getter
public class BlogTitle implements Serializable {private Long id;private String title;private String description;public BlogTitle() {}public BlogTitle(Long id, String title, String description) {this.id = id;this.title = title;this.description = description;}
}
2. 创建索引
/*** 模拟数据源,正常需要读取数据库或者其它数据源内容* @return*/private List<BlogTitle> getBlogList() {List<BlogTitle> list = new ArrayList<>();list.add(new BlogTitle(1000L, "Springboot 零基础入门", "springboot基础(1):IDEA构建Springboot项目"));list.add(new BlogTitle(1001L, "springboot基础(1):IDEA构建Springboot项目", "IDEA 构建Springboot项目\n" +"第一种、普通方法构建Springboot项目"));list.add(new BlogTitle(1002L, "springboot基础(2):IDEA查看当前项目的依赖结构图", "pom文件里,右键>>Diagrams>>Show dependencies"));list.add(new BlogTitle(1003L, "Mysql核心教程", "初始化MySQL 在命令提示符窗口中运行mysqld --initialize-insecure,如果没有出现报错,则证明data目录初始化成功。 mysqld --initialize-insecure 1 此时当我们再打开查看MyS..."));list.add(new BlogTitle(1004L, "SqlServer2000如何安装", "SQL Server是微软公司开发的数据库产品,SQL Server 2000被广泛使用,很多电子商务网站、企业内部信息化平台等都是基于SQL Server产品上。 今天的商业环境要求不同类型的数据库解决方案。性能、可伸缩性及可靠性是基本要求,而进入市场时间也非常关键。除这些"));list.add(new BlogTitle(1005L, "明朝那点事儿", "明朝(1368年―1644年),中国历史上的朝代,由明太祖朱元璋所建。初期建都南京,明成祖时期迁都北京。传十六帝,共计276年。元末爆发红巾军起义,朱元璋加入郭子兴起义军。1364年称吴王。1368年初称帝,国号大明,定都南京。1421年朱棣迁都北京,以南京为陪.."));list.add(new BlogTitle(1006L, "厨房日记", "不过,我没做过饭呀!对了,找妈妈帮忙。我找来妈妈,一起走进厨房。我想做西红柿炒鸡蛋,便从冰箱里拿出两个鸡蛋、两个西红柿,又从柜子里取出一个碗和一个盘子。做菜的..."));list.add(new BlogTitle(1007L, "一往无前", "从底层技术自研到全场景覆盖,重估小米新十年|雷军|苹果|小...\n" +"2024年7月23日 2020年,雷军在小米集团成立十周年的演讲上,为小米定下“技术为本、性价比为纲、做最酷的产品”三大铁律。随后的三年,尽管小米短暂陷入低谷,但集团上下的动作未.."));list.add(new BlogTitle(1008L, "百草园", "著名武术巨星马保国喜欢吃苹果,西瓜,葡萄,热爱传扬武术,具有良好的武德"));return list;}/*** 构架一条记录,更新索引时候用* @param id* @return*/private BlogTitle getBlogListById(Long id) {return new BlogTitle(1000L, "Springboot 零基础入门", "springboot基础(1):IDEA构建Springboot项目的操作步骤如下");}/*** 查询指定id* @param id* @return*/private BlogTitle selectById(Long id) {List<BlogTitle> blogList = getBlogList();for (BlogTitle blogTitle : blogList) {if (blogTitle.getId().equals(id)) {return blogTitle;}}return null;}/*** 查询指定id* @param id* @return*/private BlogTitle selectById(String id) {return selectById(Long.parseLong(id));}/*** 创建索引** @return*/@GetMapping("/createIndex")public String createIndex() {List<BlogTitle> list = getBlogList();//查询数据源,这里直接构造一些数据// 创建文档的集合Collection<Document> docs = new ArrayList<>();for (BlogTitle blogTitle : list) {// 创建文档对象Document document = new Document();// StringField: 这个 Field 用来构建一个字符串Field,不分析,会索引,Field.Store控制存储// LongPoint、IntPoint 等类型存储数值类型的数据。会分析,会索引,不存储,如果想存储数据还需要使用 StoredField// StoredField: 这个 Field 用来构建不同类型,不分析,不索引,会存储// TextField: 如果是一个Reader, 会分析,会索引,,Field.Store控制存储document.add(new StringField("id", String.valueOf(blogTitle.getId()), Field.Store.YES));// Field.Store.YES, 将原始字段值存储在索引中。这对于短文本很有用,比如文档的标题,它应该与结果一起显示。// 值以其原始形式存储,即在存储之前没有使用任何分析器。document.add(new TextField("title", blogTitle.getTitle(), Field.Store.YES));// Field.Store.NO,可以索引,分词,不将字段值存储在索引中。// 个人理解:说白了就是为了省空间,如果回表查询,其实无所谓,如果不回表查询,需要展示就要保存,设为YES,无需展示,设为NO即可。document.add(new TextField("description", blogTitle.getDescription(), Field.Store.NO));docs.add(document);}// 引入IK分词器,如果需要解决上面版本冲突报错的问,使用`new MyIKAnalyzer()`即可Analyzer analyzer = new IKAnalyzer();// 索引写出工具的配置对象IndexWriterConfig conf = new IndexWriterConfig(analyzer);// 设置打开方式:OpenMode.APPEND 会在索引库的基础上追加新索引。OpenMode.CREATE会先清空原来数据,再提交新的索引conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE);// 索引目录类,指定索引在硬盘中的位置,我的设置为D盘的indexDir文件夹// 创建索引的写出工具类。参数:索引的目录和配置信息try (Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));IndexWriter indexWriter = new IndexWriter(directory, conf)) {// 把文档集合交给IndexWriterindexWriter.addDocuments(docs);// 提交indexWriter.commit();} catch (Exception e) {log.error("创建索引失败", e);return "创建索引失败";}return "创建索引成功";}
3. 简单搜索
这里示例只搜索了title标题部分的内容,改成description则搜索内容部分
/*** 简单搜索*/@RequestMapping("/searchText")public List<BlogTitle> searchText(String text) throws IOException, ParseException {Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));// 索引读取工具IndexReader reader = DirectoryReader.open(directory);// 索引搜索工具IndexSearcher searcher = new IndexSearcher(reader);// 创建查询解析器,两个参数:默认要查询的字段的名称,分词器QueryParser parser = new QueryParser("title", new IKAnalyzer());// 创建查询对象Query query = parser.parse(text);// 获取前十条记录TopDocs topDocs = searcher.search(query, 10);// 获取总条数log.info("本次搜索共找到" + topDocs.totalHits + "条数据");// 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分ScoreDoc[] scoreDocs = topDocs.scoreDocs;List<BlogTitle> list = new ArrayList<>();for (ScoreDoc scoreDoc : scoreDocs) {// 取出文档编号int docId = scoreDoc.doc;// 根据编号去找文档Document doc = reader.document(docId);String id = doc.get("id");BlogTitle content = selectById(id);list.add(content);}return list;}
4. 更新索引
当有记录发生变化时,需要更新某条记录
/*** 更新索引** @return*/@GetMapping("/updateIndex")public String update() {// 创建配置对象IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());// 创建目录对象// 创建索引写出工具try (Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));IndexWriter writer = new IndexWriter(directory, conf)) {// 获取更新的数据,这里只是演示BlogTitle blogTitle = getBlogListById(1001L);// 创建新的文档数据Document doc = new Document();doc.add(new StringField("id", blogTitle.getId()+"", Field.Store.YES));doc.add(new TextField("title", blogTitle.getTitle(), Field.Store.YES));doc.add(new TextField("description", blogTitle.getDescription(), Field.Store.YES));writer.updateDocument(new Term("id", blogTitle.getId()+""), doc);// 提交writer.commit();} catch (Exception e) {log.error("更新索引失败", e);return "更新索引失败";}return "更新索引成功";}
5. 删除索引
某条记录不存在了,需要删除
/*** 删除索引** @return*/@GetMapping("/deleteIndex")public String deleteIndex() {// 创建配置对象IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());// 创建目录对象// 创建索引写出工具try (Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));IndexWriter writer = new IndexWriter(directory, conf)) {// 根据词条进行删除writer.deleteDocuments(new Term("id", "1001"));// 提交writer.commit();} catch (Exception e) {log.error("删除索引失败", e);return "删除索引失败";}return "删除索引成功";}
6. 删除全部索引
想要废弃全部索引,删除全部索引
/*** 删除全部索引** @return*/@GetMapping("/deleteAllIndex")public String deleteAllIndex() {// 创建配置对象IndexWriterConfig conf = new IndexWriterConfig(new IKAnalyzer());// 创建目录对象// 创建索引写出工具try (Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));IndexWriter writer = new IndexWriter(directory, conf)) {// 删除全部索引writer.deleteAll();// 提交writer.commit();} catch (Exception e) {log.error("删除索引失败", e);return "删除索引失败";}return "删除索引成功";}
Springboot整合Lucene复杂搜索
1. 同时标题和内容中查找关键词
例如 想要搜索关键词,而关键词既可能在标题中,也可能在文本内容中。
/*** 一个关键词,在多个字段里面搜索*/@RequestMapping("/searchTextMore")public List<BlogTitle> searchTextMore(String text) throws IOException, ParseException {String[] str = {"title", "description"};Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));// 索引读取工具IndexReader reader = DirectoryReader.open(directory);// 索引搜索工具IndexSearcher searcher = new IndexSearcher(reader);// 创建查询解析器,两个参数:默认要查询的字段的名称,分词器MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new IKAnalyzer());// 创建查询对象Query query = parser.parse(text);// 获取前十条记录TopDocs topDocs = searcher.search(query, 100);// 获取总条数log.info("本次搜索共找到" + topDocs.totalHits + "条数据");// 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分ScoreDoc[] scoreDocs = topDocs.scoreDocs;List<BlogTitle> list = new ArrayList<>();for (ScoreDoc scoreDoc : scoreDocs) {// 取出文档编号int docId = scoreDoc.doc;// 根据编号去找文档Document doc = reader.document(docId);String id = doc.get("id");BlogTitle content = selectById(id);list.add(content);}return list;}
2. 搜索结果高亮显示关键词
/*** 搜索结果高亮显示*/@RequestMapping("/searchTextHighlighter")public List<BlogTitle> searchTextHighlighter(String text) throws IOException, ParseException, InvalidTokenOffsetsException {String[] str = {"title", "description"};Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));// 索引读取工具IndexReader reader = DirectoryReader.open(directory);// 索引搜索工具IndexSearcher searcher = new IndexSearcher(reader);// 创建查询解析器,两个参数:默认要查询的字段的名称,分词器MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new IKAnalyzer());// 创建查询对象Query query = parser.parse(text);// 获取前100条记录TopDocs topDocs = searcher.search(query, 100);// 获取总条数log.info("本次搜索共找到" + topDocs.totalHits + "条数据");//高亮显示SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));//高亮后的段落范围在100字内Fragmenter fragmenter = new SimpleFragmenter(100);highlighter.setTextFragmenter(fragmenter);// 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分ScoreDoc[] scoreDocs = topDocs.scoreDocs;List<BlogTitle> list = new ArrayList<>();for (ScoreDoc scoreDoc : scoreDocs) {// 取出文档编号int docId = scoreDoc.doc;// 根据编号去找文档Document doc = reader.document(docId);String id = doc.get("id");BlogTitle content = selectById(id);//处理高亮字段显示String title = highlighter.getBestFragment(new IKAnalyzer(), "title", doc.get("title"));if (title == null) {title = content.getTitle();}// 因为创建索引的时候description设置的Field.Store.NO,所以这里doc没有description数据,取不出来值,设为YES则可以,可以断点看一下,直接设置content.getDescription()也可以高亮显示
// String description = highlighter.getBestFragment(new IKAnalyzer(), "description", doc.get("description"));
// if (description == null) {
// description = content.getDescription();
// }
// content.setDescription(description);content.setDescription(content.getDescription());content.setTitle(title);list.add(content);}return list;}
3. 分页搜索
/*** 分页搜索*/@RequestMapping("/searchTextPage")public List<BlogTitle> searchTextPage(String text) throws IOException, ParseException, InvalidTokenOffsetsException {String[] str = {"title", "description"};int page = 1;int pageSize = 5;Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));// 索引读取工具IndexReader reader = DirectoryReader.open(directory);// 索引搜索工具IndexSearcher searcher = new IndexSearcher(reader);// 创建查询解析器,两个参数:默认要查询的字段的名称,分词器MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new IKAnalyzer());// 创建查询对象Query query = parser.parse(text);// 分页获取数据TopDocs topDocs = searchByPage(page, pageSize, searcher, query);// 获取总条数log.info("本次搜索共找到" + topDocs.totalHits + "条数据");//高亮显示SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));//高亮后的段落范围在100字内Fragmenter fragmenter = new SimpleFragmenter(100);highlighter.setTextFragmenter(fragmenter);// 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分ScoreDoc[] scoreDocs = topDocs.scoreDocs;List<BlogTitle> list = new ArrayList<>();for (ScoreDoc scoreDoc : scoreDocs) {// 取出文档编号int docId = scoreDoc.doc;// 根据编号去找文档Document doc = reader.document(docId);BlogTitle content = selectById(doc.get("id"));//处理高亮字段显示String title = highlighter.getBestFragment(new IKAnalyzer(), "title", doc.get("title"));if (title == null) {title = content.getTitle();}String description = highlighter.getBestFragment(new IKAnalyzer(), "description", content.getDescription());content.setDescription(description);content.setTitle(title);list.add(content);}return list;}private TopDocs searchByPage(int page, int perPage, IndexSearcher searcher, Query query) throws IOException {TopDocs result;if (query == null) {log.info(" Query is null return null ");return null;}ScoreDoc before = null;if (page != 1) {TopDocs docsBefore = searcher.search(query, (page - 1) * perPage);ScoreDoc[] scoreDocs = docsBefore.scoreDocs;if (scoreDocs.length > 0) {before = scoreDocs[scoreDocs.length - 1];}}result = searcher.searchAfter(before, query, perPage);return result;}
4. 多关键词联合搜索
/*** 多关键词搜索*/@GetMapping("/searchTextMoreParam")public List<BlogTitle> searchTextMoreParam(String text) throws IOException, ParseException, InvalidTokenOffsetsException {String[] str = {"title", "description"};Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("d:\\indexDir"));// 索引读取工具IndexReader reader = DirectoryReader.open(directory);// 索引搜索工具IndexSearcher searcher = new IndexSearcher(reader);//多条件查询构造BooleanQuery.Builder builder = new BooleanQuery.Builder();// 条件一MultiFieldQueryParser parser = new MultiFieldQueryParser(str, new IKAnalyzer());// 创建查询对象Query query = parser.parse(text);builder.add(query, BooleanClause.Occur.MUST);// 条件二// TermQuery不使用分析器所以建议匹配不分词的Field域(StringField, )查询,比如价格、分类ID号等。这里只能演示个ID了。。。Query termQuery = new TermQuery(new Term("id", "1001"));builder.add(termQuery, BooleanClause.Occur.MUST);// 获取前十条记录TopDocs topDocs = searcher.search(builder.build(), 100);// 获取总条数log.info("本次搜索共找到" + topDocs.totalHits + "条数据");//高亮显示SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));//高亮后的段落范围在100字内Fragmenter fragmenter = new SimpleFragmenter(100);highlighter.setTextFragmenter(fragmenter);// 获取得分文档对象(ScoreDoc)数组.SocreDoc中包含:文档的编号、文档的得分ScoreDoc[] scoreDocs = topDocs.scoreDocs;List<BlogTitle> list = new ArrayList<>();for (ScoreDoc scoreDoc : scoreDocs) {// 取出文档编号int docId = scoreDoc.doc;// 根据编号去找文档Document doc = reader.document(docId);BlogTitle content = selectById(doc.get("id"));//处理高亮字段显示String title = highlighter.getBestFragment(new IKAnalyzer(), "title", doc.get("title"));if (title == null) {title = content.getTitle();}String description = highlighter.getBestFragment(new IKAnalyzer(), "description", content.getDescription());content.setDescription(description);content.setTitle(title);list.add(content);}return list;}
关于IK扩展分词
什么分词?什么是扩展分词?
什么是分词?
例如“书上的苹果掉下来砸中了牛顿”。句子中的苹果就构成一个分词,苹和前面的文字的不能组词构成“的苹”,也不能组词叫“果掉”,但是苹和果构成一个组词,叫做苹果。
什么是扩展分词?
就是希望增加分词,而分词器本身不带有的,例如我市的著名武术巨星马保国同志在巴黎奥运会取得了马拉松金牌的好成绩。分词器并不会提前内置马保国的名字,但是马保国是一个人名,构成一个分词,在搜索的时候单独搜索其中任何一个字都没有意义,需要搜索整个关键词,才构成实际价值。因此分词中添加马保国,搜索时IK分词会将其解释为一个分词。
自定义分词和停止分词
- 需要在resources目录下新建文件IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties><comment>IKAnalyzer扩展配置</comment><!--用户的扩展字典 --><entry key="ext_dict">extend.dic</entry><!--用户扩展停止词字典 --><entry key="ext_stopwords">stop.dic</entry>
</properties>
- 添加分词文件
extend.dic
马保国
王小羽
- 添加停止分词
与分词的意思相反,就是破坏构成的分词,不希望既有分词构建分词
stop.dic
的
地
吗
相关文章:
Springboot整合全文检索引擎Lucene
文章目录 前言Lucene的介绍springboot项目中如何整合Lucene简单用法1. 引入依赖2. 其它用到的类2. 创建索引3. 简单搜索4. 更新索引5. 删除索引6. 删除全部索引 Springboot整合Lucene复杂搜索1. 同时标题和内容中查找关键词2. 搜索结果高亮显示关键词3. 分页搜索4. 多关键词联合…...
【深度学习】【语音】TTS, 如何使用Python分析WAV的采样率、比特深度、通道数
文章目录 使用Python分析WAV文件的属性与可视化简介所需环境代码解析可视化音频数据结论使用Python分析WAV文件的属性与可视化 WAV文件录音要求 为了确保录制的音频文件符合TTS模型训练的质量标准,请遵循以下录音要求: 采样率要求:44.1 kHz说明:采样率44.1 kHz(即每秒采样…...
Linux的安装和使用
Linux 第一节 Linux 优势 1. 开源 为什么这么多的的设备都选择使用 Linux?因为它是开源软件(open source software),具有不同的含义。使用一个安全的操作系统工作变得必不可少的事,而 Linux 恰好满足了这个需求。因…...
查看一个exe\dll文件的依赖项
方法 使用一个Dependencies工具,检测exe文件的所有依赖项 工具使用 下载压缩包之后解压,解压后如下图所示 在命令行中运行Dependencies.exe程序会得到帮助菜单 查询某exe的所有依赖项,使用命令 Dependencies.exe -chain <查询文件> …...
高校科研信息管理系统pf
TOC springboot364高校科研信息管理系统pf 第1章 绪论 1.1 研究背景 互联网概念的产生到如今的蓬勃发展,用了短短的几十年时间就风靡全球,使得全球各个行业都进行了互联网的改造升级,标志着互联网浪潮的来临。在这个新的时代,…...
Linux 开机自动挂载共享文件设置
选择一个要共享的文件 点击确定 -> 确定 启动虚拟机 执行下面的命令 /YumSource 是我选择的共享文件夹,自行替换自已选择的文件夹 mkdir -p /mnt/hgfs cat >> /etc/fstab << EOF .host:/YumSource /mnt/hgfs fuse.vmhgfs-fuse allow_other defaul…...
c_cpp_properties.json、launch.json、 tasks.json
在 Visual Studio Code 中,c_cpp_properties.json、launch.json 和 tasks.json 是三个重要的配置文件,它们的作用如下: c_cpp_properties.json: 这个文件用于配置 C/C 扩展的 IntelliSense、编译器路径和包括路径等。它帮助 VS Co…...
mysql 一些知识点 面试用
mysql 1、4个隔离级别与3个现象2、快照读与当前读2.1 可重复读的情况下出现幻读问题的两种情况 3 数据库 常用引擎4、InnoDB存储引擎对MVCC的实现5、索引(重点)5.1 什么是索引5.2 索引的创建与删除5.2.1 查看表中有哪些索引5.2.2 添加索引5.2.3 删除索引 5.3 索引的分类5.4 树数…...
STM32之点亮LED灯
使用固件库实现LED点灯 LED灯: LED灯,是一种能够将电能转化为可见光的半导体器件 控制LED灯: LED灯的正极接到了3.3V,LED灯的负极接到了PA1,也就是GPIOA1引脚 只需要控制PA1为相对应的低电平,即可点亮对…...
Java 多线程练习2 (抽奖比较Runnable写法)
MultiProcessingExercise2 package MultiProcessingExercise120240814;import java.util.ArrayList; import java.util.Collections;public class MultiProcessingExercise1 {public static void main(String[] args) {// 需求:// 在此次抽奖过程中,抽奖…...
使用fastboot更新部分系统
使用fastboot更新部分系统 获取分区信息 > part list sunxi_flash 0Partition Map for UNKNOWN device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00008000 0x000097c5 "boot-r…...
windows 加载portch遇到的错误
import torch 遇到如下错误 File "<stdin>", line 1, in <module> File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\torch\__init__.py", line 148, in <module> raise err OSError: [W…...
如何将 CICD 模版重构为 CICD component?
极狐GitLab 是 GitLab 在中国的发行版,专门面向中国程序员和企业提供企业级一体化 DevOps 平台,用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规,而且所有的操作都是在一个平台上进行,省事省心省钱。可以一键安装极狐GitL…...
数学建模——评价决策类算法(层次分析法、Topsis)
一、层次分析法 概念原理 通过相互比较确定各准则对于目标的权重, 及各方案对于每一准则的权重,这些权重在人的思维过程中通常是定性的, 而在层次分析法中则要给出得到权重的定量方法. 将方案层对准则层的权重及准则层对目标层的权重进行综合, 最终确定方案层对目标…...
KEEPALIVED 全csdn最详细----理论+实验(干货扎实,包教会的)
环境准备 主机名IP虚拟IP(VIP)功能ka1172.25.254.10172.25.254.100keepalived服务ka2172.25.254.20172.25.254.100keepalived服务realserver1172.25.254.110web服务realserver2172.25.254.120web服务 注意一定要关闭selinux,和防火墙,不然在…...
微信云开发云存储全部下载
一、安装 首先按照这个按照好依赖 安装 | 云开发 CloudBase - 一站式后端云服务 npm i -g cloudbase/cli 二、登录 tcb login 下载 首先在你要下载到的本地文件内创建一个名为:cloudbaserc.json 的json文件。 填入你的id {"envId":"你的云开发环…...
vos3000怎样对接voip落地语音网关呢?卡机和O口网关的配置技巧有哪些?
很多朋友没有接触过vos系统的使用,那么vos3000如何对接voip落地网关呢?卡机的配置技巧有哪些? VOS3000系统是针对中小等规模VoIP运营业务提供的支撑系统。 语音网关 落地网关分O口网关,S口网关,和全网通GOIP语音网关。…...
MySQL数据库专栏(四)数据库操作
1、创建数据库 create database if not exists [数据库名称] character set [字符集] COLLATE [排序规则]; 例如:create database if not exists db_demo character set utf8mb4 COLLATE utf8mb4_general_ci; if not exists:判断数据库是否存在&#x…...
Python编写Word文档
目录 0. 安装依赖 1. 创建word文档 2. 添加标题、居中、字体16大小 3. 添加标题一 4. 添加一段话并设置字体颜色 封装函数 5. 换页 6. 插入表格 0. 安装依赖 python-docx1.1.2 1. 创建word文档 from docx import Documentdoc Document() 2. 添加标题、居中、字体1…...
聚星文社AI工具
聚星文社AI工具是一款基于人工智能技术的文学创作辅助工具。聚星文社AI工具https://docs.qq.com/doc/DRU1vcUZlanBKR2xy 它能够帮助作者生成文字内容、自动校对、提供创作灵感等功能。 通过聚星文社AI工具, 作者可以更快速地完成文学作品的创作,提高创…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...
轻量级Docker管理工具Docker Switchboard
简介 什么是 Docker Switchboard ? Docker Switchboard 是一个轻量级的 Web 应用程序,用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器,使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
