Lucene(3):Lucene全文检索的流程

news2024/11/24 4:03:34

1 Lucene准备

Lucene可以在官网上下载:Apache Lucene - Welcome to Apache Lucene。我们使用的是7.7.2版本,文件位置如下图:

 使用这三个文件的jar包,就可以实现lucene功能

2 开发环境准备

JDK: 1.8 (Lucene7以上,必须使用JDK1.8及以上版本)

数据库: MySQL

数据库脚本:https://download.csdn.net/download/u013938578/87806726

导入结果如下:

3 创建java工程

创建maven工程不依赖骨架, 测试即可,效果如下:

引用maven

    <dependencies>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
            <version>7.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
            <version>7.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-queryparser</artifactId>
            <version>7.7.2</version>
        </dependency>

        <!-- 测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- mysql数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- IK中文分词器 -->
        <dependency>
            <groupId>org.wltea.ik-analyzer</groupId>
            <artifactId>ik-analyzer</artifactId>
            <version>8.1.0</version>
        </dependency>

        <!--web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 引入thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Json转换工具 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.51</version>
        </dependency>
    </dependencies>

4 索引流程

4.1 数据采集

在电商网站中,全文检索的数据源在数据库中,需要通过jdbc访问数据库中tb_sku 表的内容。

4.1.1 创建数据持久层

package com.example.demo.domain;

public class Sku {
    //商品主键id
    private String id;
    //商品名称
    private String name;
    //价格
    private Integer price;
    //库存数量
    private Integer num;
    //图片
    private String image;
    //分类名称
    private String categoryName;
    //品牌名称
    private String brandName;
    //规格
    private String spec;
    //销量
    private Integer saleNum;

    public Sku(String id, String name, Integer price, Integer num, String image, String categoryName, String brandName, String spec, Integer saleNum) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.num = num;
        this.image = image;
        this.categoryName = categoryName;
        this.brandName = brandName;
        this.spec = spec;
        this.saleNum = saleNum;
    }

    public Sku() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec;
    }

    public Integer getSaleNum() {
        return saleNum;
    }

    public void setSaleNum(Integer saleNum) {
        this.saleNum = saleNum;
    }
}

4.1.2 创建Service接口

package com.example.demo.Service;

import com.example.demo.domain.Sku;

import java.util.List;

public interface SkuService {
    /**
     * 查询所有的Sku数据
     * @return
     **/
    public List<Sku> querySkuList();
}

4.1.3 创建DAO接口实现类

使用jdbc实现

package com.example.demo.Service.Impl;

import com.example.demo.Service.SkuService;
import com.example.demo.domain.Sku;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class SkuServiceImpl implements SkuService {
    public List<Sku> querySkuList() {
        // 数据库链接
        Connection connection = null;
        // 预编译statement
        PreparedStatement preparedStatement = null;
        // 结果集
        ResultSet resultSet = null;
        // 商品列表
        List<Sku> list = new ArrayList<Sku>();
        try {
            // 加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 连接数据库
            connection = DriverManager.getConnection("jdbc:mysql://192.168.222.132:3306/lucene?useUnicode=true&characterEncoding=utf-8&useSSL=false", "root","123456");
            // SQL语句
            String sql = "SELECT * FROM tb_sku";
            // 创建preparedStatement
            preparedStatement = connection.prepareStatement(sql);
            // 获取结果集
            resultSet = preparedStatement.executeQuery();
            // 结果集解析
            while (resultSet.next()) {
                Sku sku = new Sku();
                sku.setId(resultSet.getString("id"));
                sku.setName(resultSet.getString("name"));
                sku.setSpec(resultSet.getString("spec"));
                sku.setBrandName(resultSet.getString("brand_name"));
                sku.setCategoryName(resultSet.getString("category_name"));
                sku.setImage(resultSet.getString("image"));
                sku.setNum(resultSet.getInt("num"));
                sku.setPrice(resultSet.getInt("price"));
                sku.setSaleNum(resultSet.getInt("sale_num"));
                list.add(sku);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}

4.2 实现索引流程

  1. 采集数据
  2. 创建Document文档对象
  3. 创建分析器(分词器)
  4. 创建IndexWriterConfig配置信息类
  5. 创建Directory对象,声明索引库存储位置
  6. 创建IndexWriter写入对象
  7. 把Document写入到索引库中
  8. 释放资源

package com.example.test;

import com.example.demo.Service.Impl.SkuServiceImpl;
import com.example.demo.Service.SkuService;
import com.example.demo.domain.Sku;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
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 java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class testManager {
    @Test
    public void createIndexTest() throws Exception {
        // 1. 采集数据
        SkuService skuDao = new SkuServiceImpl();
        List<Sku> skuList = skuDao.querySkuList();
        // 2. 创建Document文档对象
        List<Document> documents = new ArrayList<Document>();
        for (Sku sku : skuList) {
            Document document = new Document();
            // Document文档中添加Field域
            // 商品Id
            // Store.YES:表示存储到文档域中
            document.add(new TextField("id", sku.getId(), Field.Store.YES));
            // 商品名称
            document.add(new TextField("name", sku.getName(), Field.Store.YES));
            // 商品价格
            document.add(new TextField("price", sku.getPrice().toString(),
                    Field.Store.YES));
            // 品牌名称
            document.add(new TextField("brandName", sku.getBrandName(),
                    Field.Store.YES));
            // 分类名称
            document.add(new TextField("categoryName", sku.getCategoryName(),
                    Field.Store.YES));
            // 图片地址
            document.add(new TextField("image", sku.getImage(),
                    Field.Store.YES));
            // 把Document放到list中
            documents.add(document);
        }
        // 3. 创建Analyzer分词器,分析文档,对文档进行分词
        Analyzer analyzer = new StandardAnalyzer();
        // 4. 创建Directory对象,声明索引库的位置
        Directory directory = FSDirectory.open(Paths.get("E:\\dir"));
        // 5. 创建IndexWriteConfig对象,写入索引需要的配置
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        // 6.创建IndexWriter写入对象
        IndexWriter indexWriter = new IndexWriter(directory, config);
        // 7.写入到索引库,通过IndexWriter添加文档对象document
        for (Document doc : documents) {
            indexWriter.addDocument(doc);
        }
        // 8.释放资源
        indexWriter.close();
    }
}

执行效果:

代码里面设置了索引库的位置,如下:

在索引库中出现了以下文件,表示创建索引成功

4.5 使用Luke查看索引

Luke作为Lucene工具包中的一个工具(http://www.getopt.org/luke/),可以通过界面来进行索引文件的查询、修改。

将luke-swing-8.0.0里面的内容, 放到一个硬盘根目录的文件夹下, 不能有空格和中文名称。

运行luke.bat

打开后,使用如下图:

下图是索引域的展示效果:

下图是文档域展示效果

4.6 搜索流程

4.6.1 输入查询语句

Lucene可以通过query对象输入查询语句。同数据库的sql一样,lucene也有固定的查询语法:

最基本的有比如:AND, OR, NOT 等(必须大写)

举个栗子:

用户想找一个 name 域中包括 手 或 机 关键字的文档。

它对应的查询语句:name:手 OR name:机

如下图是使用luke搜索的例子:

搜索分词

和索引过程的分词一样,这里要对用户输入的关键字进行分词,一般情况索引和搜索使用的分词器一致。

比如:输入搜索关键字“java学习”,分词后为java和学习两个词,与java和学习有关的内容都搜索出来了,如下:

 

4.6.2 代码实现

  • 创建Query搜索对象
  • 创建Directory流对象,声明索引库位置
  • 创建索引读取对象IndexReader
  • 创建索引搜索对象IndexSearcher
  • 使用索引搜索对象,执行搜索,返回结果集TopDocs
  • 解析结果集
  • 释放资源

IndexSearcher搜索方法如下:

方法说明
indexSearcher.search(query, n)根据Query搜索,返回评分最高的n条记录
indexSearcher.search(query, filter, n)根据Query搜索,添加过滤策略,返回评分最高的n条记录
indexSearcher.search(query, n, sort)

根据Query搜索,添加排序策略,返回评分最高的n条记录

indexSearcher.search(booleanQuery,filter,n, sort)

根据Query搜索,添加过滤策略,添加排序策略,返回评分最高的n条记录

代码实现

package com.example.test;


import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试搜索过程
 */
public class TestSearch {

    @Test
    public void testIndexSearch() throws Exception {

        //1. 创建分词器(对搜索的关键词进行分词使用)
        //注意: 分词器要和创建索引的时候使用的分词器一模一样
        Analyzer analyzer = new StandardAnalyzer();

        //2. 创建查询对象,
        //第一个参数: 默认查询域, 如果查询的关键字中带搜索的域名, 则从指定域中查询, 如果不带域名则从, 默认搜索域中查询
        //第二个参数: 使用的分词器
        QueryParser queryParser = new QueryParser("name", analyzer);

        //3. 设置搜索关键词
        //华 OR  为   手   机
        Query query = queryParser.parse("华为手机");

        //4. 创建Directory目录对象, 指定索引库的位置
        Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
        //5. 创建输入流对象
        IndexReader indexReader = DirectoryReader.open(dir);
        //6. 创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //7. 搜索, 并返回结果
        //第二个参数: 是返回多少条数据用于展示, 分页使用
        TopDocs topDocs = indexSearcher.search(query, 10);

        //获取查询到的结果集的总数, 打印
        System.out.println("=======count=======" + topDocs.totalHits);

        //8. 获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //9. 遍历结果集
        if (scoreDocs != null) {
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
                int  docID = scoreDoc.doc;
                //通过文档id, 读取文档
                Document doc = indexSearcher.doc(docID);
                System.out.println("==================================================");
                //通过域名, 从文档中获取域值
                System.out.println("===id==" + doc.get("id"));
                System.out.println("===name==" + doc.get("name"));
                System.out.println("===price==" + doc.get("price"));
                System.out.println("===image==" + doc.get("image"));
                System.out.println("===brandName==" + doc.get("brandName"));
                System.out.println("===categoryName==" + doc.get("categoryName"));

            }
        }
        //10. 关闭流
    }


    /**
     * 数值范围查询
     * @throws Exception
     */
    @Test
    public void testRangeQuery() throws Exception {
        //1. 创建分词器(对搜索的关键词进行分词使用)
        //注意: 分词器要和创建索引的时候使用的分词器一模一样
        Analyzer analyzer = new StandardAnalyzer();

        //2. 创建查询对象,
        Query query = IntPoint.newRangeQuery("price", 100, 1000);

        //4. 创建Directory目录对象, 指定索引库的位置
        Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
        //5. 创建输入流对象
        IndexReader indexReader = DirectoryReader.open(dir);
        //6. 创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //7. 搜索, 并返回结果
        //第二个参数: 是返回多少条数据用于展示, 分页使用
        TopDocs topDocs = indexSearcher.search(query, 10);

        //获取查询到的结果集的总数, 打印
        System.out.println("=======count=======" + topDocs.totalHits);

        //8. 获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //9. 遍历结果集
        if (scoreDocs != null) {
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
                int  docID = scoreDoc.doc;
                //通过文档id, 读取文档
                Document doc = indexSearcher.doc(docID);
                System.out.println("==================================================");
                //通过域名, 从文档中获取域值
                System.out.println("===id==" + doc.get("id"));
                System.out.println("===name==" + doc.get("name"));
                System.out.println("===price==" + doc.get("price"));
                System.out.println("===image==" + doc.get("image"));
                System.out.println("===brandName==" + doc.get("brandName"));
                System.out.println("===categoryName==" + doc.get("categoryName"));

            }
        }
        //10. 关闭流
    }

    /**
     * 组合查询
     * @throws Exception
     */
    @Test
    public void testBooleanQuery() throws Exception {

        //1. 创建分词器(对搜索的关键词进行分词使用)
        //注意: 分词器要和创建索引的时候使用的分词器一模一样
        Analyzer analyzer = new StandardAnalyzer();

        //2. 创建查询对象,
        Query query1 = IntPoint.newRangeQuery("price", 100, 1000);

        QueryParser queryParser = new QueryParser("name", analyzer);
        //3. 设置搜索关键词
        //华 OR  为   手   机
        Query query2 = queryParser.parse("华为手机");

        //创建布尔查询对象(组合查询对象)
        /**
         *  BooleanClause.Occur.MUST 必须相当于and, 也就是并且的关系
         *  BooleanClause.Occur.SHOULD 应该相当于or, 也就是或者的关系
         *  BooleanClause.Occur.MUST_NOT 不必须, 相当于not, 非
         *  注意: 如果查询条件都是MUST_NOT, 或者只有一个查询条件, 然后这一个查询条件是MUST_NOT则
         *  查询不出任何数据.
         */
        BooleanQuery.Builder query = new BooleanQuery.Builder();
        query.add(query1, BooleanClause.Occur.MUST);
        query.add(query2, BooleanClause.Occur.MUST);


        //4. 创建Directory目录对象, 指定索引库的位置
        Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
        //5. 创建输入流对象
        IndexReader indexReader = DirectoryReader.open(dir);
        //6. 创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //7. 搜索, 并返回结果
        //第二个参数: 是返回多少条数据用于展示, 分页使用
        TopDocs topDocs = indexSearcher.search(query.build(), 10);

        //获取查询到的结果集的总数, 打印
        System.out.println("=======count=======" + topDocs.totalHits);

        //8. 获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;


        //9. 遍历结果集
        if (scoreDocs != null) {
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
                int  docID = scoreDoc.doc;
                //通过文档id, 读取文档
                Document doc = indexSearcher.doc(docID);
                System.out.println("==================================================");
                //通过域名, 从文档中获取域值
                System.out.println("===id==" + doc.get("id"));
                System.out.println("===name==" + doc.get("name"));
                System.out.println("===price==" + doc.get("price"));
                System.out.println("===image==" + doc.get("image"));
                System.out.println("===brandName==" + doc.get("brandName"));
                System.out.println("===categoryName==" + doc.get("categoryName"));

            }
        }
        //10. 关闭流
    }


    /**
     * 测试相关度排序
     * @throws Exception
     */
    @Test
    public void testIndexSearch2() throws Exception {

        //1. 创建分词器(对搜索的关键词进行分词使用)
        //注意: 分词器要和创建索引的时候使用的分词器一模一样
        Analyzer analyzer = new IKAnalyzer();

        //需求: 不管是名称域还是品牌域或者是分类域有关于手机关键字的查询出来
        //查询的多个域名
        String[] fields = {"name", "categoryName", "brandName"};

        //设置影响排序的权重, 这里设置域的权重
        Map<String, Float> boots = new HashMap<>();
        boots.put("categoryName", 10000000000f);

        //从多个域查询对象
        MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(fields, analyzer, boots);
        //设置查询的关键词
        Query query = multiFieldQueryParser.parse("手机");

        //4. 创建Directory目录对象, 指定索引库的位置
        Directory dir = FSDirectory.open(Paths.get("E:\\dir"));
        //5. 创建输入流对象
        IndexReader indexReader = DirectoryReader.open(dir);
        //6. 创建搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //7. 搜索, 并返回结果
        //第二个参数: 是返回多少条数据用于展示, 分页使用
        TopDocs topDocs = indexSearcher.search(query, 10);

        //获取查询到的结果集的总数, 打印
        System.out.println("=======count=======" + topDocs.totalHits);

        //8. 获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        //9. 遍历结果集
        if (scoreDocs != null) {
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取查询到的文档唯一标识, 文档id, 这个id是lucene在创建文档的时候自动分配的
                int  docID = scoreDoc.doc;
                //通过文档id, 读取文档
                Document doc = indexSearcher.doc(docID);
                System.out.println("==================================================");
                //通过域名, 从文档中获取域值
                System.out.println("===id==" + doc.get("id"));
                System.out.println("===name==" + doc.get("name"));
                System.out.println("===price==" + doc.get("price"));
                System.out.println("===image==" + doc.get("image"));
                System.out.println("===brandName==" + doc.get("brandName"));
                System.out.println("===categoryName==" + doc.get("categoryName"));

            }
        }
        //10. 关闭流
    }

}

运行结果如下:

 

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

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

相关文章

python 面向对象--类,对象,属性,方法,魔法方法

1.理解面向对象思想 面向过程思想: 遇到问题,分析步骤.按照步骤解决问题.(复杂,重复) 面向对象思想: 遇到问题,找到能解决问题的对象去解决.(简单,复用) 2.类和对象 # 定义类的格式: # class 类名(): # 代码 # ......class Student(): ​def study(self):print(学生好…

【连续介质力学】Voigt符号

Voigt符号 一个对称二阶张量有6个独立的分量&#xff0c;那么就可以将他表示成列向量的形式&#xff1a; 这种表示方式为Voigt符号&#xff0c;也可以将二阶张量表示成&#xff1a; 正如minor对称的四阶张量C&#xff0c; C i j k l C j i k l C i j l k C j i l k C_{ij…

hive函数

函数 Hive的函数分为两大类∶内置函数(Built-in Functions )、用户定义函数UDF (User-Defined Functions ) . 内置函数可分为︰数值类型函数、日期类型函数、字符串类型函数、集合函数、条件函数等; 用户定义函数根据输入输出的行数可分为3类:UDF、UDAF、UDTF。 UDF:普通函…

一图看懂 charset_normalizer 模块:字符集规范化,真正的第一个通用字符集检测器,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 charset_normalizer 模块&#xff1a;字符集规范化&#xff0c;真正的第一个通用字符集检测器&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&a…

AI人工智能决策树分类器的原理、优缺点、应用场景和实现方法

决策树分类器&#xff08;Decision Tree Classifier&#xff09;是一种常用的机器学习算法&#xff0c;它被广泛应用于分类和回归问题中。在人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;领域中&#xff0c;决策树分类器是一种简单而有效的算法&…

DETR3D 论文学习

1. 解决了什么问题&#xff1f; 对于低成本自动驾驶系统&#xff0c;仅凭视觉信息进行 3D 目标检测是非常有挑战性的。目前的多相机 3D 目标检测方法有两类&#xff0c;一类直接对单目图像做预测&#xff0c;没有考虑 3D 场景的结构或传感器配置。这类方法需要多步后处理&…

tcpdump 抓包和记录、tshark 过滤抓包

目录 tcpdump 一、包名 二、可用参数 tcpdump -nn tcpdump -nn -i 网卡名 —— 指定显示的网卡 tcpdump -nn -i 网卡名 port 端口名 —— 指定显示的端口 tcpdump -nn -i 网卡名 not port 端口名 —— 排除指定的端口不显示 tcpdump -nn -i …

JavaWeb15 - web 应用常用功能 -文件上传下载

1. 基本介绍 文件的上传和下载&#xff0c;是常见的功能。后面项目就使用了文件上传下载。如果是传输大文件&#xff0c;一般用专门工具或者插件文件上传下载需要使用到两个包 , 需要导入说明: 2. 文件上传 2.1 文件上传的基本原理 ● 文件上传原理示意图, 一图胜千言 …

进程调度策略

1 先进先出 FIFO 2 最短任务优先 SJF https://blog.51cto.com/u_13064014/5079546?btotalstatistic

机器学习和大数据:如何利用机器学习算法分析和预测大数据

第一章&#xff1a;引言 近年来&#xff0c;随着科技的迅速发展和数据的爆炸式增长&#xff0c;大数据已经成为我们生活中无法忽视的一部分。大数据不仅包含着海量的信息&#xff0c;而且蕴含着无数的商机和挑战。然而&#xff0c;如何从这些海量的数据中提取有价值的信息并做…

【CANN训练营0基础赢满分秘籍】昇腾AI入门课(PyTorch)

1 昇腾AI全栈架构 昇腾计算产业是基于昇腾系列处理器和基础软件构睫的全栈Al计算基础设施&#xff0e;行业应用及服务&#xff0c;包括昇腾系列处理器、Atlas系列硬件、CANN (Compute Architecture for Neural Networks&#xff0c;异构计算架构》、Al计算框架、应用使能、全流…

LeetCode_Day4 | 好有难度的一个环形链表啊(在最后)!

LeetCode_链表 24. 两两交换链表中的节点1.题目描述2.虚拟头节点法1.思路2.代码实现 3.递归法1.思路2.代码实现 19. 删除链表的倒数第n个节点1.题目描述2.思路&#xff1a;双指针法3.代码实现 面试题 02.07. 链表相交1.题目描述2.思路3.代码实现 142. 环形链表 II1. 题目描述2.…

【SNAT和DNAT的原理与应用】

目录 一、SNAT原理与应用1、SNAT概述2、SNAT的应用环境3、进行SNAT转换后的情况 二、SNAT实验三、DNAT1、DNAT策略概述2、DNAT 实验 一、SNAT原理与应用 1、SNAT概述 SNAT 应用环境&#xff1a;局域网主机共享单个公网IP地址接入Internet&#xff08;私有不能早Internet中正常…

网络知识点之-静态路由

静态路由&#xff08;英语&#xff1a;Static routing&#xff09;是一种路由的方式&#xff0c;路由项&#xff08;routing entry&#xff09;由手动配置&#xff0c;而非动态决定。与动态路由不同&#xff0c;静态路由是固定的&#xff0c;不会改变&#xff0c;即使网络状况已…

进程控制(总)

目录 进程创建 fork函数初识&#xff1a; 写时拷贝&#xff1a; fork常规用法&#xff1a; fork调用失败的原因&#xff1a; 进程终止 进程退出场景&#xff1a; 进程常见退出方法&#xff1a; _exit函数 exit函数 return退出&#xff1a; 进程等待 进程等待的必…

UE5实现模型压平效果

文章目录 1.实现目标2.实现过程2.1 实现原理2.2 蓝图实现2.3 闪面问题与压平精度3.参考资料1.实现目标 模型压平功能是GIS系统中的一个常用功能,可以用于模型的替换,数据的对比等。本文在UE5中通过修改材质的方式实现,实现模型压平的功能,包括常规建模的StaticMesh,以及C…

2023年网络安全竞赛——Windows操作系统渗透测试Server2124

任务五:Windows操作系统渗透测试 任务环境说明: 服务器场景:Server2124(关闭链接)服务器场景操作系统:Windows(版本不详)通过本地PC中渗透测试平台Kali对服务器场景Server2124进行系统服务及版本扫描渗透测试,并将该操作显示结果中1433端口对应的服务版本信息作为Fla…

【C++ 学习 ⑥】- C++ 动态内存管理详解

目录 一、new 表达式和 delete 表达式的工作机理 二、operator new 和 operator delete 函数 2.1 - 标准库定义 2.2 - 重载 三、定位 new 表达式 四、常见面试题 4.1 - malloc/free 和 new/delete 的区别 4.2 - 内存泄漏 在 C 中&#xff0c;new 和 delete 既是关键字&…

Linux系统c语言socket实现TCP通信

socket通信用到的函数 int socket( int af, int type, int protocol); af&#xff1a;一个地址描述。仅支持AF_INET格式&#xff0c;也就是说ARPA Internet地址格式。 type&#xff1a;指定socket类型。新套接口的类型描述类型&#xff0c;如TCP&#xff08;SOCK_STREAM&#…

IMX6ULL裸机篇之DDR3参数配置分析

一. DDR3L 初始化简介 上一篇博文进行了 DDR参数的初始化&#xff0c;通过一个 execl表进行配置&#xff0c;生成脚本文件。文章网址如下&#xff1a; IMX6ULL裸机篇之DDR3初始化_凌雪舞的博客-CSDN博客 本文对 DDR的参数配置进行详细的说明。即对 "Register Configur…