SpringCloud(8)— 使用ElasticSearch(RestClient)

news2025/2/6 12:38:54

SpringCloud(8)— 使用ElasticSearch(RestClient)

一 认识RestClient

ES 官方提供了各种语言的客户端用来操作ES,这些客户端的本质就是组创DSL语句,通过 Http 请求发送给ES

官方文档地址:Elasticsearch Clients | Elastic

提示1:ES 中支持两种地理坐标数据类型

  • geo_point:ES中的 mapping 类型中利用经度和纬度确定一个点
  • geo_shape:由多个 geo_point 组成的复杂几何图形

提示2:字段拷贝可以使用 copy_to 属性将当前字段的属性值拷贝到指定的属性上,方便以后搜索,且被指定的字段在查询数据时对外不可见

例如:以下示例中的 all 字段,在后边查询数据时不会返回

{
   "all":{
       "type":"text",
       "analyzer":"ik_max_word"
   },
   "brand":{
       "type":"keyword",
       "copy_to":"all"
   }
}

二 RestClient操作索引库

1.初始化RestClient

在项目中引入 RestClient 的 mavne 依赖坐标,版本需与 ElasticSearch 的版本一致。这里使用的是 7.12.1

<properties>
       <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
<dependencies>
    <dependency>
       <groupId>org.elasticsearch.client</groupId>
       <artifactId>elasticsearch-rest-high-level-client</artifactId>
       <version>${elasticsearch.version}</version>
    </dependency>
</dependencies>

由于 SpringBoot 项目中已经对 elasticsearch 进行管理,所以需要手动定义相同的参数值去覆盖默认的版本号,从而使用我们想使用的版本

编写测试代码,测试 RestHighLevelClient 是否初始化成功

private RestHighLevelClient restHighLevelClient;

//初始化 RestHighLevelClient 对象
@BeforeEach
void setUp(){
    this.restHighLevelClient=new RestHighLevelClient(RestClient.builder(
            HttpHost.create("http://192.168.119.101:9200")
    ));
}

//销毁 RestHighLevelClient 对象
@AfterEach
void tearDown() throws IOException {
    this.restHighLevelClient.close();
}

@Test
void testInit(){
    System.out.println(restHighLevelClient);
}

或者可以使用 Ioc 思想,创建一个 Bean 到内存中,然后使用它即可

@Bean
public RestHighLevelClient restHighLevelClient(){
    return new RestHighLevelClient(RestClient.builder(
          HttpHost.create("http://192.168.119.101:9200")
    ));
}

2.创建索引库

编写一个测试方法,用来测试创建索引库是否成功

@Test
void testCreateIndex() throws IOException {
    //1.创建一个 CreateIndexRequest 对象,指定 indexName(索引库名称)
    CreateIndexRequest request = new CreateIndexRequest("hotel");
     // 这是一段很恶心的 DSL 语句的拼接,为了方便可以将这一块代码提了出来,这里为了方便演示不做优化处理
    String mapping ="{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\"\n" +
            "      },\n" +
            "      \"id\":{\n" +
            "        \"type\": \"long\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"address\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"index\": false, \n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"score\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"city\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"starName\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"business\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"location\":{\n" +
            "        \"type\": \"geo_point\"\n" +
            "      },\n" +
            "      \"pic\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

    //2.定义 DSL
    request.source(mapping, XContentType.JSON);

    //3.创建索引库
    restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
}

运行完成后,可以去浏览器通过 GET 方法访问,如果返回对应的JSON格式信息,则说明创建索引库成功。

# 浏览器访问
http://192.168.119.101:9200/hotel
# kibana 中的 dev tools 中测试
GET /hotel

CreateIndexRequest 对象中的 indices() 对象里,包含了操作索引库的所有方法

3.删除索引库

@Test
void testDeleteIndex() throws IOException {
    // 定义 DeleteIndexRequest 对象
    DeleteIndexRequest request=new DeleteIndexRequest("hotel");
    // 执行删除操作
    restHighLevelClient.indices().delete(request,RequestOptions.DEFAULT);
}

4.判断指定索引库是否存在

@Test
void testDeleteExist() throws IOException {
    // 定义 GetIndexRequest 对象
    GetIndexRequest request=new GetIndexRequest("hotel");
    // 发送请求
    restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
}

三 RestClient操作文档

1.添加文档

编写测试方法,从数据库查询到指定数据,并且格式化为 Json,然后将数据存储到 特定的索引库中

Hotel 实体对象示例:

@Data
public class Hotel implements Serializable {

    private final static Long serialVersionUID=1L;

    private Long id;

    private String name;

    private String address;

    private Integer price;

    private Integer score;

    private String city;

    private String starName;

    private String brand;

    private String business;

    private String latitude;
    private String longitude;

    private String pic;
}

HotelDoc 文档实体对象:

注意:文档的实体应该与创建时的 mapping 字段完全一致

@Data
public class HotelDoc implements Serializable {

    public HotelDoc() {
    }

    public HotelDoc(Hotel hotel) {

        BeanUtils.copyProperties(hotel,this);
        // 主要是此处处理了经纬度的格式,使用字符串格式时,要求 纬度在前,经度在后
        this.location=hotel.getLatitude()+","+hotel.getLongitude();
    }

    private final static Long serialVersionUID = 1L;

    private Long id;

    private String name;

    private String address;

    private Integer price;

    private Integer score;

    private String city;

    private String starName;

    private String brand;

    private String business;

    private String pic;

    private String location;

}

添加一条文档到索引库中:

@Test
void testAddDocument() throws IOException {
    Long id = 36934L;
    Hotel hotel = hotelService.getById(id);
    if (Objects.nonNull(hotel)) {
        // 1.创建 IndexRequest 对象,指定文档要存入的【索引库】及【文档Id】,此处的【文档Id】使用数据库的【主键Id】
        IndexRequest request = new IndexRequest("hotel").id(id.toString());
        // 2.准备 JSON 数据
        HotelDoc hotelDoc = new HotelDoc(hotel);
        String jsonString = JSON.toJSONString(hotelDoc);
        request.source(jsonString, XContentType.JSON);
        // 3.发送请求
        restHighLevelClient.index(request, RequestOptions.DEFAULT);
        return;
    }
    System.out.println("id=" + id + "的信息不存在");
}

踩坑底:对于 mapping 类型为 geo_point 的经纬度,使用字符串格式时,需要“纬度在前经度在后

运行成功后,数据将被存入到 ES 中

2.查看文档

编写查看文档的示例代码,重点API 【GetRequest】

@Test
void testGetDocument() throws IOException {
    Long id = 36934L;
    // 1.创建 GetRequest 对象,指定【索引库】和【文档ID】
    GetRequest request = new GetRequest("hotel", id.toString());
    // 2.发送请求,读取到数据
    GetResponse documentFields = restHighLevelClient.get(request, RequestOptions.DEFAULT);
    String sourceStr = documentFields.getSourceAsString();
    //3. 使用fastJson转为实体对象
    HotelDoc hotelDoc = JSON.parseObject(sourceStr, HotelDoc.class);
    System.out.println(hotelDoc);
}

3.修改文档

编写修改文档的示例代码,重点API 【UpdateRequest】

@Test
void testUpdateDocument() throws IOException {
    Long id=36934L;
    // 1.创建 UpdateRequest 对象,指定【索引库】和 【文档Id】
    UpdateRequest request=new UpdateRequest("hotel",id.toString());
    // 2.准备要更新的参数和值,每两个参数为一对 key value
    request.doc(
            "price",200,
            "name","8天假日酒店"
    );
    // 3.发送请求
    restHighLevelClient.update(request,RequestOptions.DEFAULT);
}

4.删除文档

编写删除文档的示例代码,重点API 【DeleteRequest】

@Test
void testDeleteDocument() throws IOException {
    Long id=36934L;
    // 1.创建 DeleteRequest 对象,指定【索引库】和 【文档Id】
    DeleteRequest deleteRequest=new DeleteRequest("hotel",id.toString());
    // 2.发送请求
    restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
}

5.批量导入文档

编写批量导入测试方法,重点API 【BulkRequest】

@Test
void tesBulkDocument() throws IOException {
    // 1.定义 BulkRequest 对象
    BulkRequest request=new BulkRequest();
    List<Hotel> list = hotelService.list();
    // 2.查询所有数据并且转换为 List<HotelDoc>
    List<HotelDoc> listDoc=list.stream().map(t->{
        HotelDoc doc=new HotelDoc(t);
        return doc;
    }).collect(Collectors.toList());
    // 3.遍历 List<HotelDoc> 对象,创建 IndexRequest 并且通过 add() 添加到 BulkRequest 对象中
    for (HotelDoc doc: listDoc) {
        IndexRequest indexRequest=new IndexRequest("hotel").id(doc.getId().toString());
        indexRequest.source(JSON.toJSONString(doc),XContentType.JSON);
        request.add(indexRequest);
    }
    // 4.发送 ES 请求
    restHighLevelClient.bulk(request,RequestOptions.DEFAULT);
}

在 kibana 控制台通过查询命令可以查询到已经导入数据

#1.hotel为索引库名称
GET /hotel/_search

四 RestClient查询

RestClient 所有解析的归根结底是逐层解析 Json 结构

1.快速入门(match_all)

通过 match_all 演示 RestClient 的基本API

编写以下测试代码,实现 match_all 的使用

@Test
void testMatchAll() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request=new SearchRequest("hotel");

    //2.组织 DSL 参数
    request.source()
            .query(QueryBuilders.matchAllQuery())
            .from(0)
            .size(3);	

    //3.发送请求,得到响应结果
    SearchResponse response=restHighLevelClient.search(request, RequestOptions.DEFAULT);

    //4. 通过 SearchResponse 对象的 getHits 拿到数据结果集,然后进行处理
    SearchHits hits = response.getHits();
    //5.获取数据总条数
    Long totalHits  = hits.getTotalHits().value;
    System.out.println(totalHits);
    //6.处理结果
    for (SearchHit hit : hits) {
        HotelDoc doc = JSON.parseObject(hit.getSourceAsString(), HotelDoc.class);
        System.out.println(doc.toString());
    }
}

RestClient 与 DSL 语法对比:

在这里插入图片描述

  • 使用 QueryBuilders 实现各种查询方式
  • 通过 SearchRequest 对象的 source() 对象实现链式编程,从而设置分页,排序,高亮,复合查询等操作
  • 通过 RestHighLevelClient 对象的 search() 方法发送查询请求,实现查询
  • 通过 SearchResponse 对象接受查询结果并进行处理
  • 通过 SearchHits 对象拿到结果集和数据总行数

主要通过解析 DSL 语法返回结果集中的 hits 对象,获取到总条数及数据内容,从而对数据进行处理

2.全文检索

全文检索 与 match_all 的API基本一致,差别在于 match 有了查询条件,即 DSL 语句中的 query 部分。

1.match(特定字段)

//1.创建 SearchRequest 对象,指定索引库名称
SearchRequest request = new SearchRequest("hotel");

//2.组织 DSL 参数
request.source()
        .query(QueryBuilders.matchQuery("all", "如家"));

//3.发送请求,得到响应结果
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

2.multi_match(多字段)

//1.创建 SearchRequest 对象,指定索引库名称
SearchRequest request = new SearchRequest("hotel");

//2.组织 DSL 参数
request.source()
        .query(QueryBuilders.multiMatchQuery("如家","name","brand"))

//3.发送请求,得到响应结果
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

match 和 multi_match 的区别主要在于 QueryBuilders 类的调用方法不同

match 中 QueryBuilders 使用了 matchQuery()

multi_match 中 QueryBuilders 使用了 multiMatchQuery()

3.term(精准查询)

与 前面的相比,唯一的区别是使用了 termQuery()

@Test
void testMatch() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");
    //2.组织 DSL 参数
    request.source().query(QueryBuilders.termQuery("brand","如家"));
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}

3.boolean query(组合)

boolean query 查询 与 前面的查询略有不同,需要先创建 BoolQueryBuilder 对象,然后通过 BoolQueryBuilder 对象添加过滤条件

@Test
void testBooleanQuery() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");
    //2.创建 BoolQueryBuilder 对象,通过链式编程方式添加查询条件
    BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
    queryBuilder
            .should(QueryBuilders.matchQuery("city", "上海"))
            .must(QueryBuilders.termQuery("brand", "如家"))
            .filter(QueryBuilders.rangeQuery("price").gte(200).lte(300));

    //3.组织 DSL 参数,填充 BoolQueryBuilder对象到 query中
    request.source()
            .query(queryBuilder);
    //4.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}

或者可以直接一步到位

@Test
void testBooleanQuery() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");

    //2.组织 DSL 参数
    request.source()
            .query(new BoolQueryBuilder()
                    .should(QueryBuilders.matchQuery("city", "上海"))
                    .must(QueryBuilders.termQuery("brand", "如家"))
                    .filter(QueryBuilders.rangeQuery("price").gte(200).lte(300))
            );
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}

4.排序和分页

DSL 语句中,排序和分页 在 query 同级,RestClient 中与 DSL 一样,也是在 query() 之后

@Test
void testPageAndOrder() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");
    
    //2.组织 DSL 参数
    request.source()
            .query(new BoolQueryBuilder()
                    .should(QueryBuilders.matchQuery("city", "上海"))
                    .must(QueryBuilders.termQuery("brand", "如家"))
                    .filter(QueryBuilders.rangeQuery("price").gte(200).lte(300))
            )
            .from(0)
            .size(3)
            .sort("score", SortOrder.DESC)
            .sort("price",SortOrder.ASC);
    
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}
  • from:开始位置,默认为0
  • size:获取的数据数量,默认为10
  • sort:使用 sort() 方法来进行排序,传入 字段名 和 排序方式

在这里插入图片描述

5.highlight(高亮显示)

高亮API包括 请求DSL构建 和 结果解析 两部分

在这里插入图片描述

测试代码实现如下:

@Test
void testHighLight() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");
    //2.组织 DSL 参数
    request.source()
            .query(QueryBuilders.matchQuery("all", "如家"))
            .highlighter(
                    //高亮字段是否和查询字段匹配
                    new HighlightBuilder().field("name").requireFieldMatch(false).preTags("<em>").postTags("</em>")
            );
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
    //4. 通过 SearchResponse 对象的 getHits 拿到数据结果集,然后进行处理
    SearchHits hits = response.getHits();
    //5.获取数据总条数
    Long totalHits = hits.getTotalHits().value;
    System.out.println(totalHits);
    for (SearchHit hit : hits) {
        HotelDoc doc = JSON.parseObject(hit.getSourceAsString(), HotelDoc.class);
        // 获取高亮区域的值
        Map<String, HighlightField> fields = hit.getHighlightFields();
        if (fields != null) {
            // 获取指定字段的高亮内容对象
            HighlightField highlightField = fields.get("name");
            String highLightName = highlightField.getFragments()[0].toString();

            // 替换原有的值
            doc.setName(highLightName);
        }
        System.out.println(doc);
    }
}

6.距离排序

按照距离排序,需要提供一组经纬度作为中心点,然后按照距离远近进行排序

距离排序中使用到一个新的对象,即 SortBuilders,以下是测试示例代码:

@Test
void testDistanceSort() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");
    //2.组织 DSL 参数
    request.source()
            .query(QueryBuilders.matchQuery("all", "如家"))
            .sort(
                    SortBuilders.geoDistanceSort("location", new GeoPoint("31.251433,121.47522"))
                            .order(SortOrder.ASC)
                            .unit(DistanceUnit.KILOMETERS)
            );
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}

7.相关性算分

使用 RestClient 实现相关性算分时代码较为复杂,先看对照示例:

在这里插入图片描述

实现方式是基于 FunctionScoreQueryBuilder 对象

以下是测试代码,用于过滤 isAD=true 时,增加权重分值为10,且与原始分值相乘

@Test
void testFunctionScore() throws IOException {
    //1.创建 SearchRequest 对象,指定索引库名称
    SearchRequest request = new SearchRequest("hotel");

    // 原始查询,可以是一般查询,也可以是复合查询 BooleanQuery
    QueryBuilder queryBuilder = QueryBuilders.matchQuery("all", "如家");
    // 构建 FunctionScoreQueryBuilder 对象
    FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
                    //方式查询
                    queryBuilder,
                    //functionScore 数组
                    new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                            // 其中一个 function score
                            new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                    //过滤条件
                                    QueryBuilders.termQuery("isAD", true),
                                    //算分函数,这里使用加权重
                                    ScoreFunctionBuilders.weightFactorFunction(20)
                            )
                    }
            )// 加权模式
            .boostMode(CombineFunction.MULTIPLY);
    ;
    //2.组织 DSL 参数
    request.source().query(QueryBuilders.matchQuery("all", "如家"))
    ;
    //3.发送请求,得到响应结果
    SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
}

注意:后边的 “isAD” 字段 是为了做相关性算分增加的新字段,前边的 索引库 和 实体类 中没有,需要手动增加。

本结知识点梳理完成,完结撒花。

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

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

相关文章

运维基础(上部)

运维基础【&#xff08;上部&#xff09;】 因为笔记所记内容太多&#xff0c;所以我分成了上下两部分来分享给大家查看学习&#xff01;同时我会持续更新博客发布更加优质的文章&#xff0c;希望大家多多支持与关注&#xff01;感谢&#xff01; 一、运维概述 1、运维岗位的收…

[附源码]计算机毕业设计Python港口集团仓库管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

GitLab Runner的使用

一、初次使用GitLab Runner 特别说明:前面已经将本地项目成功推送到了GitLab中,并且已经注册了一个GitLab Runner,接下来就是使用GitLab Runner。 触发GitLab Runner以完成GitLab的CI(持续集成)/CD(持续部署),需满足下述两个条件: 仓库根目录下面存在有.gitlab-ci.yml文…

[ Linux ] 互斥量实现原理,线程安全

上篇文章我们对抢票系统做了加锁处理&#xff0c;对互斥量tickets进行加锁。而本篇博文来谈谈互斥量实现的原理以及相关问题。 目录 1.上篇遗留问题 我们在临界资源对应的临界区中加锁了&#xff0c;就不是多行代码了吗&#xff1f;如果还是多行代码&#xff0c;难道不会被切…

[附源码]计算机毕业设计Python公益组织登记与查询系统论文(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

【AI with ML】第 13 章 :在 Android 应用程序中使用 TensorFlow Lite

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

vue的虚拟DOM和diff算法

虚拟DOM和diff算法密不可分&#xff0c; 虚拟dom&#xff0c;它本身就是一个 JavaScript 对象&#xff0c;为解决DOM操作非常耗时&#xff0c;把DOM转换为虚拟DOM&#xff0c;DOM操作转换为js计算&#xff0c;js执行速度较快。 diff算法在vue中被优化为O(n)的时间复杂度&#x…

手机损坏的数据导出方法

主板损坏的症状 手机主板损坏的症状表现一般为系统启动失败、屏幕无显示、启动黑屏死机、无法开机、没有声音、无法打电话、没网络等等。 资料的重要性 手机坏了,怎么把手机里面重要的资料导出来?今天小编就来跟大家说说手机导资料这个事。 手机坏了,具体要看手机是哪里…

java计算机毕业设计ssm基于JavaWeb的公务员招考信息发布平台

项目介绍 随着互联网技术的发发展,计算机技术广泛应用在人们的生活中,逐渐成为日常工作、生活不可或缺的工具,各种管理系统层出不穷。公务员是各国负责统筹管理经济社会秩序和国家公共资源,维护国家法律规定,贯彻执行相关义务的公职人员。每年报考公务员的人数逐渐增加,特为此…

寒假训练营 第一节 时空复杂度分析

一.时空复杂度的分析 1.时间复杂度 时间复杂度&#xff1a;程序运行会消耗多少时间。 在此&#xff0c;为了方便讨论&#xff0c;我们假定每一个语句消耗的时间一样&#xff0c;视为一个时间单元。 #include <iostream> using namespace std; int main() {int n 100;…

国企的设备管理工作如何做好?

国企的设备管理工作如何做好&#xff1f; 在市场经济建设持续深化、经营体制不断转变的过程中&#xff0c;一些企业设备管理工作发生了很大的变化&#xff0c;出现整体水平下降&#xff0c;设备技术状况恶化等现象&#xff0c;这在一定程度上制约了企业技术创新&#xff0c;制…

Transformer实现以及Pytorch源码解读(二)-embedding源码分析

前言 本部分博客需要先阅读博客&#xff1a;《Transformer实现以及Pytorch源码解读&#xff08;一&#xff09;-数据输入篇》 作为知识储备。 Embedding使用方式 如下面的代码中所示&#xff0c;embedding一般是先实例化nn.Embedding(vocab_size, embedding_dim)。实例化的过…

业务安全情报,预知发现黑灰产的企业攻击

业务遭遇欺诈风险&#xff0c;发起攻击的黑灰产主要是为了谋取利益。对于黑灰产利益目的甄别需要多方面情报&#xff0c;再辅助技术和专家经验&#xff0c;然后进行综合判断&#xff0c;进而帮助企业及时响应、精准布控。 安全情报帮助企业提前发现攻击 12月13日&#xff0c;“…

谁代表先进生产力?

互联网企业代表先进生产力方向 做软件项目的时候碰到三类企业 1、 传统企业&#xff0c;以卖货或卖服务为主 2、 互联网类&#xff0c;做个服务工具或平台 3、 分配模式类&#xff0c;以某分配模式为“宝贝” 毫无疑问&#xff1a; 互联网企业代表先进的生产力方向 互联网类…

即时通讯音视频开发之音频基础及编码原理

即时通讯应用中的实时音视频技术&#xff0c;几乎是IM开发中的最后一道高墙。原因在于&#xff1a;实时音视频技术 音视频处理技术 网络传输技术 的横向技术应用集合体&#xff0c;而公共互联网不是为了实时通信设计的。 比特率&#xff1a; 表示经过编码&#xff08;压缩&am…

C#读取Excel文件内容(WPS)

本地安装的WPS版本为 一、下载accessdatabaseengine_X64后安装 网址&#xff1a;https://www.microsoft.com/en-us/download/details.aspx?id54920 二、项目中引用OleDb包 三、代码部分 //excelFilePath为文件路径&#xff08;例如D:\Test.xslx&#xff09; > //strin…

Android---RecyclerView回收复用机制

一、RecyclerView回收复用 回收什么&#xff1f;复用什么&#xff1f; 回收&#xff1a;回收即缓存。当屏幕上的一个itemView滑出屏幕(即不可见了)&#xff0c;RecyclerView就利用回收机制&#xff0c;将该itemView放入内存。当其它itemView出现时&#xff0c;不用每次都去new…

JavaScript-Sass

Sass的基础使用 1.简介 1.1简介 Sass是世界上最成熟&#xff0c;最稳定&#xff0c;最强大的CSS扩展语言Sass是css预编译工具可以更加优雅的书写csssass写出来的东西浏览器不认识需要进行转换VSCode推荐使用Easy Sass插件Sass中可以使用加减乘除&#xff0c;条件分支以及循环…

【Three.js入门】处理动画、尺寸自适应、双击进入/退出全屏(Clock跟踪时间,Gsap动画库,自适应画面,进入/退出全屏)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

Python -- 网络编程

目录 1.网络通信的概念 2.IP地址 3.网络通信方式 3.1 直接通信 3.2 使用集线通信 3.3 通用交换机通信 3.4 使用路由器连接多个网络 3.5 复杂的通信过程 4.端口 4.1 端口号 4.2 知名端口号 4.3 动态端口号 4.4 端口号作用 5.socker概念 5.1 不同电脑上的进程之间…