一、什么是全文检索

1.数据的分类

我们生活中的数据总体分为两种:结构化数据和非结构化数据。
结构化数据:指具有固定格式或有限长度的数据,是由二维表结构来逻辑表达和实现的数据,简单来说就是数据库
非结构化数据:指不定长或无固定格式的数据,不方便用数据库二维逻辑表来表现的数据,如邮件,word,pdf,html,txt文档等磁盘上的文件

2.结构化数据搜索(通常使用sql语句查询)

常见的结构化数据也就是数据库中的数据。在数据库中搜索很容易实现,通常都是使用sql语句进行查询,而且能很快的得到查询结果。

3.为什么数据库搜索很容易?

因为数据库中的数据存储是有规律的,有行有列而且数据格式、数据长度都是固定的。

但是如果我要查询非结构化的数据呢?(比如找出内容中包含spring的文档)

4.非结构化数据搜索:顺序扫描法和全文检索

(1) 顺序扫描法(Serial Scanning)所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢。(2) 全文检索(Full-text Search)将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。虽然创建索引的过程也是非常耗时的,但是索引一旦创建就可以多次使用,全文检索主要处理的是查询,所以耗时间创建索引是值得的。

5.如何实现全文检索:可以使用Lucene实现全文检索

Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎,部分文本分析引擎。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。
对于数据量大、数据结构不固定的数据可采用全文检索方式搜索,比如百度、Google等搜索引擎、论坛站内搜索、电商网站站内搜索等。

二、Lucene实现全文检索的流程


1.创建索引

(1) 获得文档原始文档:要基于哪些数据进行搜索,那么这些数据就是原始文档搜索引擎:使用爬虫技术获取原始文档站内搜索:数据库中的数据
(2) 构建文档对象---每个文档都有一个唯一的编号,就是文档id。对应每个原始文档创建一个文档(Document)对象注意:每个Document可以有多个Field(相当于一条记录有多个字段),不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域值都相同)
(3) 分析文档---分词的过程1.根据空格进行字符串拆分,得到一个单词列表2.把单词统一转换成小写或者大写3.去除标点符号4.去除停用词(没有意义的词)。每个关键词都封装到一个term对象中,Term中包含两部分内容,一部分是关键词所在的域,一部分是关键词本身。不同的域中拆分出来的相同的关键词是不同的term对象。new TextField("content",fileContent,Field.Store.YES);//将所有的内容生成关键词,保存在content域中new Term("content", "spring") //直接通过域名+需要搜索的关键字得到term对象
(4) 创建索引基于关键词列表来创建一个索引,保存在索引库中(磁盘上)。索引库中包含3部分内容:1.索引、2.Document对象、3.关键词和文档的对应关系



2.查询索引

(1) 用户查询接口用户输入查询条件的地方  例如百度搜索框、京东商品搜索框
(2) 把关键词封装成一个查询对象要查询的域---field(域):name-file_Content:value:具体的关键词列表要搜索的关键词---springmvc
(3) 执行查询根据要查询的关键词到对应的域上进行搜索
(4) 渲染结果根据文档的id找到文档对象,对关键词进行高亮显示;分页处理;最终展示给用户看

三、Lucene入门案例

实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来。还可以根据中文词语进行查询,并且需要支持多个条件查询。
本案例中的原始内容就是磁盘上的文件,如下图:

1.1 创建索引

创建一个java工程,并引入相关jar包

步骤:
(1)创建一个Directory对象,指定索引库保存的位置
(2)基于Directory对象创建一个IndexWriter对象
(3)读取磁盘上的文件,对应每个文件创建一个文档对象
(4)向文档对象中添加域
(5)把文档对象写入索引库
(6)关闭IndexWriter对象

1.2 代码实现

package com.bianyiit.test;import org.apache.commons.io.FileUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.FSDirectory;import java.io.File;public class testLuncene {public static void main(String[] args) throws Exception {//1.创建一个Directory对象,指定索引库保存的位置(原始文档提取的索引库所在的磁盘位置)FSDirectory direcotory= FSDirectory.open(new File("D:\\suoyin\\syml").toPath());//2.创建IndexWriter对象  作用:负责将document写入索引库 IndexWriterConfig:负责引用分词器(关键词的获取都是使用分词器完成的),底层默认使用的是标准分词器IndexWriter indexWriter=new IndexWriter(direcotory,new IndexWriterConfig());//3.读取磁盘上的文件(原始文件所在的位置),对应每一个文件创建一个文档对象File file=new File("D:\\suoyin\\searchsource");File[] files = file.listFiles();//获取指定目录下面的文件对象的集合for (File f : files) {Document document= new Document();//获取文件名称String fileName = f.getName();//获取文件大小long fileSize= FileUtils.sizeOf(f);//获取文件路径String path = f.getPath();//获取文件内容String fileContent=FileUtils.readFileToString(f,"utf-8");//创建Filed域对象TextField fieldName=new TextField("name",fileName, Field.Store.YES);TextField fieldSize=new TextField("size",fileSize+"",Field.Store.YES);TextField fieldPath=new TextField("path",path,Field.Store.YES);TextField fieldContent=new TextField("content",fileContent,Field.Store.YES);//将域添加到Document对象中去document.add(fieldName);document.add(fieldSize);document.add(fieldPath);document.add(fieldContent);//将document对象写入索引库中indexWriter.addDocument(document);}//6.关闭IndexWriter对象indexWriter.close();}
}


2.1 查询索引库

实现步骤:
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
package com.bianyiit.test;import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;import java.io.File;/*查询索引库的步骤*/
public class searchLuncene {public static void main(String[] args) throws Exception {//1.创建一个Directory对象,指定索引库保存的位置FSDirectory direcotory= FSDirectory.open(new File("D:\\suoyin\\syml").toPath());//2.创建IndexReader对象IndexReader indexReader= DirectoryReader.open(direcotory);//3.创建IndexSearch对象IndexSearcher indexSearcher=new IndexSearcher(indexReader);//4.封装一个查询对象TermQuery query=new TermQuery(new Term("content","spring"));//5.执行查询的操作:封装了查询出来的所有的document对象的集合TopDocs topDocs=indexSearcher.search(query,10);ScoreDoc[] scoreDocs = topDocs.scoreDocs;//获取文档编号id的集合//6.根据文档编号获取对应的文档对象for (ScoreDoc scoreDoc : scoreDocs) {Document document=indexSearcher.doc(scoreDoc.doc);System.out.println("文件名称:"+document.get("name"));}indexReader.close();}
}


3.1 使用luke查看索引库中的内容


四、分词器

1.标准分词器 StandardAnalyzer

Lucene默认使用的是标准分析器: StandardAnalyzer.这种分析器分析英文内容是没有问题的
package com.bianyiit.test;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;public class TestTokenStream {public static void main(String[] args) throws Exception {//创建一个标准分析器对象Analyzer analyzer = new StandardAnalyzer();//获得tokenStream对象//第一个参数:域名,可以随便给一个//第二个参数:要分析的文本内容TokenStream tokenStream = analyzer.tokenStream("test", "The Spring Framework provides a comprehensive programming and configuration model.");//添加一个引用,可以获得每个关键词(相当于一根指针,指向每个关键词)CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);//添加一个偏移量的引用,记录了关键词的开始位置以及结束位置// OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);//将指针调整到列表的头部tokenStream.reset();//遍历关键词列表,通过incrementToken方法判断列表是否结束while (tokenStream.incrementToken()) {//关键词的起始位置// System.out.println("start->" + offsetAttribute.startOffset());//取关键词System.out.println(charTermAttribute.toString());//结束位置// System.out.println("end->" + offsetAttribute.endOffset());}tokenStream.close();}
}

1.1 原始文档

1.2 分词结果

2.中文分词器 IKAnalyzer

链接:https://pan.baidu.com/s/19b6F7N_y41IsVr_Pqr07Og
提取码:i9b6使用IKAnalyzer的步骤:
1.将IKAnalyzer的jar包添加到工程中---IK-Analyzer-1.0-SNAPSHOT.jar
2.把配置文件和扩展词典添加到工程的classpath下,也就是普通Java项目的src下面
注意:扩展词典严禁使用windows记事本编辑,保证扩展词典的编码格式是utf-8扩展词典:添加一些新词进来
停用词词典:没有意义的词汇

package com.bianyiit.test;import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;import java.io.File;
import java.io.IOException;public class IKTokenStream {public static void main(String[] args) throws Exception {//创建一个标准分析器对象Analyzer analyzer = new IKAnalyzer();//获得tokenStream对象//第一个参数:域名,可以随便给一个//第二个参数:要分析的文本内容TokenStream tokenStream = analyzer.tokenStream("test", "今天天气很好,适合户外运动,汤姆");//添加一个引用,可以获得每个关键词(相当于一根指针,指向每个关键词)CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);//添加一个偏移量的引用,记录了关键词的开始位置以及结束位置// OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);//将指针调整到列表的头部tokenStream.reset();//遍历关键词列表,通过incrementToken方法判断列表是否结束while (tokenStream.incrementToken()) {//关键词的起始位置// System.out.println("start->" + offsetAttribute.startOffset());//取关键词System.out.println(charTermAttribute.toString());//结束位置// System.out.println("end->" + offsetAttribute.endOffset());}tokenStream.close();}
}

2.1 原始中文文档

2.2 中文分词结果

五、建立中文索引库,并查询中文关键词

1.使用中文分词器建立索引库

@Test
public void testMyIKTokenStream() throws IOException {//创建Directory对象,将索引库保存在磁盘Directory directory = FSDirectory.open(new File("D:\\suoyin\\syml").toPath());//基于Directory对象创建一个IndexWriter对象IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());//创建一个indexwriter对象IndexWriter indexWriter = new IndexWriter(directory, config);//3.读取磁盘上的文件,对应每一个文件创建一个文档对象File file=new File("D:\\suoyin\\searchsource");File[] files = file.listFiles();//获取指定目录下面的文件对象的集合for (File f : files) {Document document= new Document();//获取文件名称String fileName = f.getName();//获取文件大小long fileSize= FileUtils.sizeOf(f);//获取文件路径String path = f.getPath();//获取文件内容String fileContent=FileUtils.readFileToString(f,"utf-8");//创建Filed域对象TextField fieldName=new TextField("name",fileName, Field.Store.YES);TextField fieldSize=new TextField("size",fileSize+"",Field.Store.YES);TextField fieldPath=new TextField("path",path,Field.Store.YES);TextField fieldContent=new TextField("content",fileContent,Field.Store.YES);//将域添加到Document对象中去document.add(fieldName);document.add(fieldSize);document.add(fieldPath);document.add(fieldContent);//将document对象写入索引库中indexWriter.addDocument(document);}//6.关闭IndexWriter对象indexWriter.close();
}

2.根据中文关键词去索引库中查询索引

package com.bianyiit.test;import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;import java.io.File;/*查询索引库的步骤*/
public class searchLuncene {public static void main(String[] args) throws Exception {//1.创建一个Directory对象,指定索引库保存的位置FSDirectory direcotory= FSDirectory.open(new File("D:\\suoyin\\syml").toPath());//2.创建IndexReader对象IndexReader indexReader= DirectoryReader.open(direcotory);//3.创建IndexSearch对象IndexSearcher indexSearcher=new IndexSearcher(indexReader);//4.封装一个查询对象TermQuery query=new TermQuery(new Term("content","索引"));//5.执行查询的操作:封装了查询出来的所有的document对象的集合TopDocs topDocs=indexSearcher.search(query,10);ScoreDoc[] scoreDocs = topDocs.scoreDocs;//获取文档编号id的集合//6.根据文档编号获取对应的文档对象for (ScoreDoc scoreDoc : scoreDocs) {Document document=indexSearcher.doc(scoreDoc.doc);System.out.println("文件名称:"+document.get("name"));}indexReader.close();}
}


六、索引库的维护

1. Field域的属性

是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。
是否存储的标准:是否要将内容展示给用户


2.添加索引

public class AddIndex {public static void main(String[] args) throws Exception{//索引库存放路径Directory directory = FSDirectory.open(new File("D:\\temp\\index").toPath());IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());//创建一个indexwriter对象IndexWriter indexWriter = new IndexWriter(directory, config);//创建一个Document对象Document document = new Document();//向document对象中添加域。//不同的document可以有不同的域,同一个document可以有相同的域。document.add(new TextField("filename", "新添加的文档", Field.Store.YES));document.add(new TextField("content", "新添加的文档的内容", Field.Store.NO));//LongPoint创建索引document.add(new LongPoint("size", 1000l));//StoreField存储数据document.add(new StoredField("size", 1000l));//不需要创建索引的就使用StoreField存储document.add(new StoredField("path", "d:/temp/1.txt"));//添加文档到索引库indexWriter.addDocument(document);//关闭indexwriterindexWriter.close();}
}

3.删除索引

private IndexWriter getIndexWriter() throws IOException {//创建Directory对象,将索引库保存在磁盘Directory directory = FSDirectory.open(new File("D:\\甲骨文视频2\\suoyin\\syml").toPath());//基于Directory对象创建一个IndexWriter对象IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());IndexWriter indexWriter = new IndexWriter(directory, config);return indexWriter;
}
//删除全部索引
@Test
publicvoid deleteAllIndex() throws Exception {IndexWriter indexWriter = getIndexWriter();//删除全部索引indexWriter.deleteAll();//关闭indexwriterindexWriter.close();
}

4.根据查询条件删除索引

//根据查询条件删除索引
@Test
public void deleteIndexByQuery() throws Exception {IndexWriter indexWriter = getIndexWriter();//创建一个查询条件TermQuery query = new TermQuery(new Term("name", "apache"));//根据查询条件删除indexWriter.deleteDocuments(query);//关闭indexwriterindexWriter.close();
}

5.修改索引库

//修改索引库
@Test
public void updateIndex() throws Exception {IndexWriter indexWriter = getIndexWriter();//创建一个Document对象Document document = new Document();//向document对象中添加域。//不同的document可以有不同的域,同一个document可以有相同的域。document.add(new TextField("filename", "要更新的文档", Field.Store.YES));document.add(new TextField("content", " Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包,"+"它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。",Field.Store.YES));indexWriter.updateDocument(new Term("content", "java"), document);//关闭indexWriterindexWriter.close();
}


6.根据数值范围进行索引查询

package com.bianyiit.test;import org.apache.lucene.document.Document;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;import java.io.File;public class SearchIndex {private IndexReader indexReader;private IndexSearcher indexSearcher;@Beforepublic void init() throws Exception{indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\suoyin\\syml").toPath()));indexSearcher = new IndexSearcher(indexReader);}@Testpublic void searchIndex() throws Exception{//创建一个Query对象Query query = LongPoint.newRangeQuery("size", 0, 100);TopDocs topDocs = indexSearcher.search(query, 10);System.out.println("总记录数:"+topDocs.totalHits);ScoreDoc[] scoreDocs = topDocs.scoreDocs;for(ScoreDoc scoreDoc:scoreDocs){int doc = scoreDoc.doc;Document document = indexSearcher.doc(doc);System.out.println(document.get("name"));System.out.println(document.get("path"));System.out.println(document.get("size"));}indexReader.close();}
}

7.使用queryparser查询:对查询的内容先分词,然后基于分词的结果进行查询

此时需要添加一个名为lucene-queryparser-7.4.0.jar的jar包。
注意:创建索引的时候,使用IK分词器
@Test
public void testQueryPaser()  throws Exception {QueryParser queryParser = new QueryParser("name",new IKAnalyzer());Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");printResult(query);}
public void printResult(Query query) throws Exception{//1.创建一个Directory对象,指定索引库保存的位置FSDirectory direcotory= FSDirectory.open(new File("D:\\suoyin\\syml").toPath());//2.创建IndexReader对象IndexReader indexReader= DirectoryReader.open(direcotory);//3.创建IndexSearch对象IndexSearcher indexSearcher=new IndexSearcher(indexReader);TopDocs topDocs = indexSearcher.search(query, 10);System.out.println("总记录数:"+topDocs.totalHits);ScoreDoc[] scoreDocs = topDocs.scoreDocs;for(ScoreDoc scoreDoc:scoreDocs){int doc = scoreDoc.doc;Document document = indexSearcher.doc(doc);System.out.println(document.get("name"));System.out.println(document.get("path"));System.out.println(document.get("size"));}indexReader.close();
}

Lucene实现全文检索相关推荐

  1. lucene教程--全文检索技术详解

    一 什么是全文检索 1.1 全文检索概念 全文检索是一种将文件中所有文本与检索项匹配的检索方法.它可以根据需要获得全文中有关章.节.段.句.词等信息.计算机程序通过扫描文章中的每一个词,对每一个词建立 ...

  2. Apache Lucene与Lucene.Net——全文检索服务器

    lucene学习教程 1.1 什么是lucene Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一 ...

  3. lucene解决全文检索word2003,word2007的办法

    在上一篇文章中 ,lucene只能全文检索word2003,无法检索2007,并且只能加载部分内容,无法加载全文内容.为解决此问题,找到了如下方法 POI 读取word (word 2003 和 wo ...

  4. Apache Lucene Java 全文检索引擎架构

    Apache Lucene Java 全文检索引擎架构 Apache Lucene 8.9.0 已发布,Lucene 是完全用 Java 编写的高性能.功能齐全的全文检索引擎架构,提供了完整的查询引擎 ...

  5. Lucene(全文检索)入门

    1.搜索技术理论基础 1.1. 搜索引擎的发展历史 l萌芽:Archie.Gopher l起步:Robot(网络机器人)的出现与spider(网络爬虫) l发展:excite.galaxy.yahoo ...

  6. Lucene实现全文检索的流程

    索引和搜索流程图 1.绿色表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括: 确定原始内容即要搜索的内容采集文档创建文档分析文档索引文档 2.红色表示搜索过程,从索引库中搜索内容, ...

  7. SpringCloud学习笔记024---SpringBoot集成Lucene实现全文检索_分词_索引_更新_删除文档_词条搜索_多条件查询

    JAVA技术交流QQ群:170933152 先看代码实现,下面有lucene介绍: 测试用例 Github 代码 代码我已放到 Github ,导入spring-boot-lucene-demo 项目 ...

  8. Lucene开源全文检索引擎快速入门

    Lucene是一个用Java开发的开源全文检索引擎,官网是:http://lucene.apache.org/ ,Lucene不是一个完整的全文索引应用(与之对应的是solr),而是是一个用Java写 ...

  9. lucene实现全文检索(四):分词器

    关于分词器的比较和选择,可以看这篇文章:Lucene的各中文分词比较 doToken()方法可以对传入的字符串进行分词 /***** @param ts 需要拆词的字符串* @return* @thr ...

  10. Lucene:基于Java的全文检索引擎简介(转载)

    Lucene是一个基于Java的全文索引工具包. 基于Java的全文索引引擎Lucene简介:关于作者和Lucene的历史 全文检索的实现:Luene全文索引和数据库索引的比较 中文切分词机制简介:基 ...

最新文章

  1. java中基本字节输出流类是_java中基本输入输出流的解释
  2. 五大经常使用算法 之 动态规划法
  3. EasyUI中Numberbox的简单使用
  4. python sqlite3事务_python使用上下文管理器实现sqlite3事务机制
  5. 【算法基础笔记】常用的排序算法的时间、空间复杂度,部分排序算法原理
  6. SSM+easyUI(框架的搭建)
  7. phpstudy 启动mysql服务问题
  8. python常用第三方库(转载)
  9. oracle并发执行max,oracle max processes and sessions
  10. 表单里面能不能套表单_抽奖+表单,居然还能这么玩?
  11. python基础代码大全-Python-基础汇总
  12. 《和平精英》:新军需山经魅狐、滑板小狐今日正式上线,很帅气!
  13. stvd watch 实时变量查看
  14. Vue-多个Vue实例、注册全局组件,Fetch、axios
  15. 成功解决3dmax中,旋转时透视图可以看穿物体
  16. java计算机毕业设计游泳馆信息管理系统源程序+mysql+系统+lw文档+远程调试
  17. Vufroia相机对焦问题
  18. 点阵墨水屏的使用以及图像预处理
  19. H5 六边形消除游戏开发 1
  20. windows11编译OpenCV4.5.0 with CUDA(附注意事项)

热门文章

  1. 生活账本怎么记不会乱,用哪一记账工具才能让账目更清晰
  2. Git cherry-pick 详解
  3. 色彩管理实验 matlab,EFI色彩管理实验指导手册.doc
  4. memcpy和memmove以及memcmp
  5. python语音库_python音频库dejavu原理浅析
  6. 父级fixed_子元素使用position:fixed,导致他的宽度不能和父元素保持一致的解决方案...
  7. jxd android 4.1刷机包,金星JXD V3固件
  8. 2011-2012世界大学排行榜(前200)
  9. 1995-2013年RSA大会历届主题回顾
  10. Retrofit详解