ElasticSearch(一)

2023-11-15

分布式搜索引擎01

1.初识elasticsearch

1.1.了解ES

想象下 假设 JD上有上千万商品,现在要求你 说出 包含 手机 的商品有哪些(并说出商品ID,商品图片地址,商品价格,商品的名称)? 也就是说实现JD的搜索的功能你怎么办?

SSM的缺点:
	+ 搜索精度不高
	+ 搜索的速度太慢,主要是正向搜索的方式
可以使用elasticsearch解决上面的问题:
	+分词器 精度提高
	+倒排索引 方式极大提高搜索速度	

1.1.1.elasticsearch的作用

elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容。

例如:

  • 在GitHub搜索代码

  • 在电商网站搜索商品

  • 在百度搜索答案

  • 在打车软件搜索附近的车

1.1.2.ELK技术栈

elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域:

而elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。

1.1.3.elasticsearch和lucene

elasticsearch底层是基于lucene来实现的。

Lucene是一个Java语言的搜索引擎类库,是Apache公司的顶级项目,由DougCutting于1999年研发。官网地址:https://lucene.apache.org/ 。

elasticsearch的发展历史:

  • 2004年Shay Banon基于Lucene开发了Compass
  • 2010年Shay Banon 重写了Compass,取名为Elasticsearch。

1.1.4.为什么不是其他搜索技术?

虽然在早期,Apache Solr是最主要的搜索引擎技术,但随着发展elasticsearch已经渐渐超越了Solr,独占鳌头:

1.1.5.总结

什么是elasticsearch?

  • 一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能

什么是elastic stack(ELK)?

  • 是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch

什么是Lucene?

  • 是Apache的开源搜索引擎类库,提供了搜索引擎的核心API

1.2.倒排索引(原理)

1.2.1.正向索引

那么什么是正向索引呢?例如给下表(tb_goods)中的id创建索引:

如果是根据id查询,那么直接走索引,查询速度非常快。

但如果是基于title做模糊查询,只能是逐行扫描数据,流程如下:

1)用户搜索数据,条件是title符合"%手机%"

2)逐行获取数据,比如id为1的数据

3)判断数据中的title是否符合用户搜索条件

4)如果符合则放入结果集,不符合则丢弃。回到步骤1

逐行扫描,也就是全表扫描,随着数据量增加,其查询效率也会越来越低。当数据量达到数百万时,就是一场灾难。

1.2.2.倒排索引

倒排索引中有两个非常重要的概念:

  • 文档(Document):用来搜索的数据,其中的每一条数据就是一个文档。例如一个网页、一个商品信息
  • 词条(Term):对文档数据或用户搜索数据,利用某种算法分词,得到的具备含义的词语就是词条。例如:我是中国人,就可以分为:我、是、中国人、中国、国人这样的几个词条

创建倒排索引是对正向索引的一种特殊处理,流程如下:

  • 将每一个文档的数据利用算法分词,得到一个个词条
  • 创建表,每行数据包括词条、词条所在文档id、位置等信息
  • 因为词条唯一性,可以给词条创建索引,例如hash表结构索引

倒排索引的搜索流程如下(以搜索"华为手机"为例):

1)用户输入条件"华为手机"进行搜索。

2)对用户输入内容分词,得到词条:华为手机

3)拿着词条在倒排索引中查找,可以得到包含词条的文档id:1、2、3。默认采用的是并集

4)拿着文档id到正向索引中查找具体文档。

虽然要先查询倒排索引,再查询倒排索引,但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。

1.2.3.正向和倒排

那么为什么一个叫做正向索引,一个叫做倒排索引呢?

  • 正向索引是最传统的,根据id索引的方式。但根据词条查询时,必须先逐条获取每个文档,然后判断文档中是否包含所需要的词条,是根据文档找词条的过程

  • 倒排索引则相反,是先找到用户要搜索的词条,根据词条得到保护词条的文档的id,然后根据id获取文档。是根据词条找文档的过程

()类比理解如下:

1.3.es的一些概念

elasticsearch中有很多独有的概念,与mysql中略有差别,但也有相似之处。比如:

索引(索引库)

文档

字段

映射

类型(这个已经去掉了,默认采用_doc来使用)

我们经常会用 MySQL 的知识来理解 es 的一些概念,比如将 es 的 index 类比成 database,将 type 类比成 table,但这个比喻实际上是不准确的。在 MySQL 中,table 之间是相互独立的,每个表有自己的 schema,每个表都可以有相同的列名,同时支持不同的类型,比如表 A 的 age 列是 tinyint,而表 B 的 age 列是 varchar(10),但在 es 中,相同名字的字段的 mapping 定义必须是一致的,因为在底层 Lucene 只会存一份。

官方文档说明:

https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html

1.3.1.文档和字段

elasticsearch是面向文档(Document)就是说ES存储的都是JSON数据存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中

而Json文档中往往包含很多的字段(Field),类似于数据库中的列。

1.3.2.索引和映射

索引(Index),就是相同类型的文档的集合。索引类似数据库中的表,都是为了对数据分类。

例如:

  • 所有用户文档,就可以组织在一起,称为用户的索引;
  • 所有商品的文档,可以组织在一起,称为商品的索引;
  • 所有订单的文档,可以组织在一起,称为订单的索引;

因此,我们可以把索引当做是数据库中的表。

数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有**映射(mapping)**这样的概念,是索引中文档的字段约束信息,类似表的结构约束。

1.3.3.elasticsearch核心概念对比理解

我们统一的把mysql与elasticsearch的概念做一下对比:

MySQL Elasticsearch 说明
Table Index 索引(index),就是文档的集合,类似数据库的表(table)
Row Document 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式
Column Field 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column)
Schema(DDL) Mapping Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema)
SQL DSL DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD

DSL 是 Domain Specific Language 的缩写,中文翻译为领域特定语言

是不是说,我们学习了elasticsearch就不再需要mysql了呢?

并不是如此,两者各自有自己的擅长:

  • Mysql:擅长事务类型操作,可以确保数据的安全和一致性

  • Elasticsearch:擅长海量数据的搜索、分析、计算

因此在企业中,往往是两者结合使用:

  • 对安全性要求较高的写操作,使用mysql实现
  • 对查询性能要求较高的搜索需求,使用elasticsearch实现
  • 两者再基于某种方式,实现数据的同步,保证一致性

1.4.安装es、kibana

1.4.1.安装

1.4.2.分词器

1.4.3.总结

分词器的作用是什么?

  • 创建倒排索引时对文档分词
  • 用户搜索时,对输入的内容分词

IK分词器有几种模式?

  • ik_smart:智能切分,粗粒度
  • ik_max_word:最细切分,细粒度,尽可能的分出更多的词,比如 程序员,会分出 程序、程序员、员

IK分词器如何拓展词条?如何停用词条?

  • 利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典
  • 在词典中添加拓展词条或者停用词条,多个之间用分号间隔

2.索引库操作

索引库就类似数据库表,mapping映射就类似表的结构。我们要向es中存储数据,必须先创建“库”和“表”。就需要编写DDL语句实现创建库和表。之前我们对比理解过 mapping等同于数据库中DDL。

2.1.mapping映射属性

mapping是对索引库中文档的约束,具体的映射针对的是字段。常见的mapping属性包括:

属性名 描述
type 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址) long、integer、short、byte、double、float、 boolean 、date 、object
index 是否创建索引,默认为true
analyzer 使用哪种分词器(前提是:要分词 才需要指定分词器)
properties 该字段的子字段
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/mapping-types.html

举例拿常见的属性理解如下:

具体的映射 注意 举例子针对  Field(数据库中的列)来说   包括常见的属性

	+ 是否分词     分词的目的是为了要去建立倒排索引
	+ 分词器是什么  根据需要确定
	+ 数据类型什么  根据需求来确定
	+ 是否要索引    要索引的目的是为了快速的搜索
	
如下商品信息包括:商品ID,商品名称,价格,图片地址. 

需要设置好数据类型,那么商品ID是long	
需要设置是否分词,那么商品ID 不需要分词
需要设置是否要索引,那么商品ID 需要建立索引
需要设置如果要分词,采用什么样的分词器

2.2.索引库的CRUD

这里我们统一使用Kibana编写DSL的方式来演示。

2.2.1.创建索引库和映射

基本语法:
  • 请求方式:PUT
  • 请求路径:/索引库名,可以自定义
  • 请求参数:mapping映射

格式:

PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "字段名2":{
        "type": "keyword",
        "index": "false"
      },
      "字段名3":{
        "properties": {
          "子字段": {
            "type": "keyword"
          }
        }
      },
      // ...略
    }
  }
}

2.2.2.查询索引库

基本语法

  • 请求方式:GET

  • 请求路径:/索引库名

  • 请求参数:无

格式

GET /索引库名

2.2.3.修改索引库

倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping

虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。

语法说明

PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

2.2.4.删除索引库

语法:

  • 请求方式:DELETE

  • 请求路径:/索引库名

  • 请求参数:无

格式:

DELETE /索引库名

在kibana中测试

2.2.5.总结

索引库操作有哪些?

  • 创建索引库:PUT /索引库名
  • 查询索引库:GET /索引库名
  • 删除索引库:DELETE /索引库名
  • 添加字段:PUT /索引库名/_mapping

3.文档操作

3.1.新增文档

语法:

POST /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    "字段3": {
        "子属性1": "值3",
        "子属性2": "值4"
    },
    // ...
}

注意,文档都会有一个唯一标识,我们把它叫做_id (文档ID) 类似于数据库的一行都会有一个主键来作为唯一标识一样。

3.2.根据ID查询文档

根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把文档id带上。

语法:

GET /{索引库名称}/_doc/{id}

3.3.根据ID删除文档

删除使用DELETE请求,同样,需要根据id进行删除:

语法:

DELETE /{索引库名}/_doc/id值

3.4.根据ID修改文档

修改有两种方式:

  • 修改全部:直接覆盖原来的文档,实际上当有存在的ID的时候,修改便是(先删除再添加,版本号进行叠加)
  • 修改部分:修改文档中的部分字段

3.4.1.修改全部

全量修改是覆盖原来的文档,其本质是:

  • 根据指定的id删除文档
  • 新增一个相同id的文档

注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。

语法:

PUT /{索引库名}/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    // ... 略
}

3.4.2.修改部分

增量修改是只修改指定id匹配的文档中的部分字段。

语法:

POST /{索引库名}/_update/文档id
{
    "doc": {
         "字段名": "新的值",
    }
}

3.5.总结

文档操作有哪些?

  • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }
  • 查询文档:GET /{索引库名}/_doc/文档id
  • 删除文档:DELETE /{索引库名}/_doc/文档id
  • 修改文档:
    • 修改全部:PUT /{索引库名}/_doc/文档id { json文档 } ,不管是多少数据,都会将之前的数据删除,并再次添加
    • 修改部分:POST /{索引库名}/_update/文档id { “doc”: {字段}}

4.RestClient操作索引

​ 刚才使用的是Kibana这种可视化界面来实现,在实际开放过程中,将来需要用到java代码来实现操作。就像我们学习SQL ,可以在navicat上执行,但是JAVA代码实现操作数据库,不会直接使用,而是需要用到JDBC一样。

​ ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

其中的Java Rest Client又包括两种:

  • Java Low Level Rest Client
  • Java High Level Rest Client

4.0.导入工程

整体步骤说明:

1.创建数据库以及表结构 模拟数据

2.通过springboot建立工程(导入依赖,配置yaml 创建启动类)

3.针对ES的映射进行分析(到底需要搜索哪些,在ES中应该使用什么数据类型,是否分词,是否索引,如果要分词分词器是什么)

4.创建索引库
	4.1 配置链接到es中
	4.2 使用restclient的API实现操作

4.0.1.导入数据

首先导入数据库数据:

4.0.2.导入项目

4.0.3.mapping映射分析

创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:

  • 字段名
  • 字段数据类型
  • 是否参与搜索
  • 是否需要分词
  • 如果分词,分词器是什么?

其中:

  • 字段名、字段数据类型,可以参考数据表结构的名称和类型
  • 是否参与搜索要分析业务来判断,例如图片地址,就无需参与搜索
  • 是否分词呢要看内容,内容如果是一个整体就无需分词,反之则要分词
  • 分词器,我们可以统一使用ik_max_word

4.0.4.初始化RestClient

在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。 可以直接参考工程即可。

分为三步:

1)引入es的RestHighLevelClient依赖:

2)因为SpringBoot默认的ES版本是7.6.2,所以我们可以覆盖默认的ES版本,当然也可以不用管,如果要改如下:

3)初始化RestHighLevelClient:

这里为了单元测试方便,我们创建一个测试类HotelIndexTest,然后将初始化的代码编写在@BeforeEach方法中:

import java.io.IOException;

public class HotelIndexTest {
    private RestHighLevelClient client;

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://localhost:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

4.1.创建索引库

4.1.1.代码解读

代码分为三步:

  • 1)创建Request对象。因为是创建索引库的操作,因此Request是CreateIndexRequest。
  • 2)添加请求参数,其实就是DSL的JSON参数部分。因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅。
  • 3)发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。

4.2.删除索引库

删除索引库的DSL语句非常简单:

DELETE /hotel

在hotel-demo中的HotelIndexTest测试类中,编写单元测试,实现删除索引:

4.3.判断索引库是否存在

判断索引库是否存在,本质就是查询,对应的DSL是:

HEAD hotel
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/indices-exists.html

4.4.总结

JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()方法来获取索引库的操作对象。

索引库操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxIndexRequest。XXX是Create、Get、Delete
  • 准备DSL( Create时需要,其它是无参)
  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete

5.RestClient操作文档

为了与索引库操作分离,我们再次参加一个测试类,做两件事情:

  • 初始化RestHighLevelClient
  • 我们的酒店数据在数据库,需要利用IHotelService去查询,所以注入这个接口

5.1.新增文档

我们要将数据库的酒店数据查询出来,写入elasticsearch中。

5.1.1.索引库实体类

数据库查询后的结果是一个Hotel类型的对象。结构如下:

数据库表与我们的索引库结构存在差异:longitude和latitude需要合并为location,按照ES的要求进行设置

因此,我们需要定义一个新的类型,与索引库结构吻合,并通过构造函数进行设置。

5.1.2.语法说明

新增文档的DSL语句如下:

POST /{索引库名}/_doc/1
{
    "name": "Jack",
    "age": 21
}

可以看到与创建索引库类似,同样是三步走:

  • 1)创建Request对象
  • 2)准备请求参数,也就是DSL中的JSON文档
  • 3)发送请求

变化的地方在于,这里直接使用client.xxx()的API,不再需要client.indices()了。

5.1.3.完整代码

我们导入酒店数据,基本流程一致,但是需要考虑几点变化:

  • 酒店数据来自于数据库,我们需要先查询出来,得到hotel对象
  • hotel对象需要转为HotelDoc对象
  • HotelDoc需要序列化为json格式

因此,代码整体步骤如下:

  • 1)根据id查询酒店数据Hotel
  • 2)将Hotel封装为HotelDoc
  • 3)将HotelDoc序列化为JSON
  • 4)创建IndexRequest,指定索引库名和id
  • 5)准备请求参数,也就是JSON文档
  • 6)发送请求

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

5.2.查询文档

5.2.1.语法说明

查询的DSL语句如下:

GET /hotel/_doc/{id}

非常简单,因此代码大概分两步:

  • 准备Request对象
  • 发送请求

不过查询的目的是得到结果,解析为HotelDoc,因此难点是结果的解析。

可以看到,结果是一个JSON,其中文档放在一个_source属性中,因此解析就是拿到_source,反序列化为Java对象即可。

与之前类似,也是三步走:

  • 1)准备Request对象。这次是查询,所以是GetRequest
  • 2)发送请求,得到结果。因为是查询,这里调用client.get()方法
  • 3)解析结果,就是对JSON做反序列化

5.3.删除文档

删除的DSL为是这样的:

DELETE /hotel/_doc/{id}

与查询相比,仅仅是请求方式从DELETE变成GET,可以想象Java代码应该依然是三步走:

  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
  • 2)准备参数,无参
  • 3)发送请求。因为是删除,所以是client.delete()方法

5.4.修改文档

5.4.1.语法说明

修改我们讲过两种方式:

  • 全量修改:本质是先根据id删除,再新增
  • 增量修改:修改文档中的指定字段值

在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:

  • 如果新增时,ID已经存在,则修改
  • 如果新增时,ID不存在,则新增

这里不再赘述,我们主要关注增量修改。

代码示例如图:

与之前类似,也是三步走:

  • 1)准备Request对象。这次是修改,所以是UpdateRequest
  • 2)准备参数。也就是JSON文档,里面包含要修改的字段
  • 3)更新文档。这里调用client.update()方法

5.5.批量导入文档

案例需求:利用BulkRequest批量将数据库数据导入到索引库中。

步骤如下:

  • 利用mybatis-plus查询酒店数据

  • 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)

  • 利用JavaRestClient中的BulkRequest批处理,实现批量新增文档

注意:批量操作一次的数据大小为15MB比较合适,太大了不行。

5.5.1.JAVA代码说明

批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。

其中提供了一个add方法,用来添加其他请求

可以看到,能添加的请求包括:

  • IndexRequest,也就是新增
  • UpdateRequest,也就是修改
  • DeleteRequest,也就是删除

因此Bulk中添加了多个IndexRequest,就是批量新增功能了。

步骤:

  • 1)创建Request对象。这里是BulkRequest
  • 2)准备参数。批处理的参数,就是其它Request对象,这里就是多个IndexRequest
  • 3)发起请求。这里是批处理,调用的方法为client.bulk()方法

我们在导入酒店数据时,将上述代码改造成for循环处理即可。

5.5.小结

文档操作的基本步骤:

  • 初始化RestHighLevelClient
  • 创建XxxRequest。XXX是Index、Get、Update、Delete、Bulk
  • 准备参数(Index、Update、Bulk时需要)
  • 发送请求。调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
  • 解析结果(Get时需要)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch(一) 的相关文章

随机推荐

  • python 运行时出现fixture xxx not found

    一 问题 在pycharm中运行带有pytest包的代码会出现如下错误 E fixture a not found gt available fixtures cache capfd capfdbinary caplog capsys ca
  • Obsidian 常用插件记录+typora 转移过来问题记录

    Typora 转 Obsidian 一些常用插件记录 插件目录 一 插件 1 obsidian custom attachment location 2 obsidian editing toolbar 3 待续 二 问题 1 图片展示问题
  • 比较器

    Comparator比较器 Collcetion工具集中的sort public static
  • cc2530:<3>ADC采集光照度案例

    之前我们讲到了串口的收发数据 我们使用到了数据结构的环形对列 就是一个追赶模型 前面一个人在放数据 后面一个人在捡数据 定义两个变量来存储这两个人所走的步数 在定义一个库存变量 也就是用来表示前面一个人放数据的量减去后面一个人捡数据的量 我
  • 8086汇编指令查询小工具,JavaScript编写,浏览器直接运行

    程序界面 汇编语言还是在大学的时候学的 汇编语言有个特点是语句短 条数多 很难可以把全部指令都背熟 当时就想编写一个软件可以随时查阅汇编语言的各类指令 而且软件不需要编译可以随时更新 可惜当时用javascript语言写只写了一半 现在终于
  • JS逆向解析案例-巨潮证券市场数据库(python)

    目标网址 http webapi cninfo com cn marketDataZhishu 这篇文章是用来对该网站进行js解析用的 解析完后爬取数据操作可看这篇文章 Scrapy实战案例 将股票数据存入SQL数据库 解析重点 目标网址在
  • VS2017 Nuget找不到包的问题处理

    重新安装系统之后 发现新安装的VS2017在用Nuget搜索SDK时 一直提示找不到包 如下图 解决方法 1 点击右侧的设置按钮 2 弹出窗中左侧树形结构选择 程序包源 再点击右上方的添加按钮 输入以下信息 https api nuget
  • STM32H7串口IAP实现

    1 概述 通过IAP原理一文我们大概知道了IAP的工作原理和工作流程 但是现在要通过串口来将这个功能实现 我们应该怎么做呢 总体上整个代码可以分为4个部分 串口功能初始化 串口不定长数据接收 Flash写入以及IAP跳转 接下来我将一一解释
  • 图解通信原理与案例分析-22:4G LTE-A如何把速率提升到1G--多载波聚合技术与授权频谱辅助接入LAA

    TBD
  • druid监控的使用

    新建springboot项目 pom xml
  • RK3568平台开发系列:HX711调试 Android

    RK3568平台开发系列 HX711调试 Android 在本文中 我们将重点讲解如何在RK3568平台上调试HX711传感器 并将其与Android应用程序集成 我们将详细介绍HX711的工作原理 并提供相应的源代码示例 HX711是一款
  • C语言力扣第50题之Pow(x,n),求x的n次幂。递归算法

    50 Pow x n 实现 pow x n 即计算 x 的整数 n 次幂函数 即 xn 示例 1 输入 x 2 00000 n 10 输出 1024 00000 示例 2 输入 x 2 10000 n 3 输出 9 26100 示例 3 输
  • 【动态规划】最长公共子序列和最长公共子串(python)

    编写用时 2020年3月12日12 02 28 1h 动态规划经典例题 最长公共子序列和最长公共子串 python 很久之前大概是高中的时候写过这种题目 使用动态规划的方法求解的 现读研究生了 要把过去的拾起来的呢 1 最长公共子序列 LC
  • 机器学习之卷积操作

    很多好主意一旦踏上语义鸿沟 就再也听不到 卷积 在图像 视觉领域乃老生常谈的内容 但是对于具体工作细节仍然值得我去学习 卷积原理 卷积 就是利用一个小的矩阵 或者更高维向量 作用于图像矩阵 或者特征矩阵 然后输出特定且有意义的值 具体来讲
  • el-table滚动到指定行并触发鼠标移入效果

    获取相应的列表数据 指定需要滚动到的行 scrollToTopAndHover tableElement any rowIndex any 获取表格 const theTableRows tableElement bodyWrapper q
  • 微服务知识点

    容器化部署 当我们使用了微服务架构后 我们将一个原本完整的系统 按照业务逻辑拆分成一个个可独立运行的子系统 为了降低系统间的耦合度 我们希望这些子系统能够运行在独立的环境中 这些环境之间能够相互隔离 在Docker出现之前 若使用虚拟机来实
  • 一款很好用的国产静态源代码扫描工具-DMSCA

    端玛企业级静态源代码扫描分析服务平台 英文简称 DMSCA 是一个独特的源代码安全漏洞 质量缺陷和逻辑缺陷扫描分析服务平台 该平台可用于识别 跟踪和修复在源代码中的技术和逻辑上的缺陷 让软件开发团队及测试团队快速 准确定位源代码中的安全漏洞
  • 蛤蟆吃服务器显示无网络,hamachi创建网络时服务器报告了一个错误.doc

    hamachi创建网络时服务器报告了一个错误 hamachi创建网络时服务器报告了一个错误 蛤蟆吃无法连接到服务器怎么办 蛤蟆吃无法连接到服务器 如果出现这样的情况 先打开运行 后输入 services msc 后点击确定跳出 右键logM
  • 《C++ Primer Plus》学习随记3---引用变量

    int rats int rodents rats rodents就是一个引用变量 他是rats的别名 指向相同的值和内存单元 int 是类型名 引用变量必须在声明时将其初始化 引用变量一旦与某个变量关联起来 就将一直效忠于它 也就是没法再
  • ElasticSearch(一)

    分布式搜索引擎01 1 初识elasticsearch 1 1 了解ES 想象下 假设 JD上有上千万商品 现在要求你 说出 包含 手机 的商品有哪些 并说出商品ID 商品图片地址 商品价格 商品的名称 也就是说实现JD的搜索的功能你怎么办