ElasticSeach 集成 springboot

news2025/1/10 20:41:42

声明是ElasticSearch?

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,
基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是
当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方
便。
Solr的架构不适合实时搜索的应用。
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值
和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位
置,因而称为倒排索引(inverted index)。

ElasticSearch的基本知识点
在这里插入图片描述

在这里插入图片描述

1、linux环境准备

(1)搭建es集群,开启集群中的三个节点(服务器)
分别进入三个集群的目录,es1,es2,es3,开启节点,搭建集群

bin/elasticsearch

(2)开启elasticSearch-head插件,查看es的运行状态以及数据,它位于集群es的plunings插件中。
在elasticsearch-head目录下执行命令, 运行head插件

 npm run start

(3)Kibana是一个软件,不是插件。它位于和ElasticSearch同级目录。
Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和
Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。
可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
在kibana目录下执行命令,开启kibana

bin/kibana --allow-root

(4)IK Analysis中文分词器
IK Analysis插件将Lucene IK分析器集成到elasticsearch中,支持自定义词典
ik分词器是每一个集群都需要有的,所有每一个es,如es1,es2,es3目录下的plunings目录下都有一个ik目录。
分词器会在节点开启的时候,自动开启,无需自动配置。

Analyzer分词配置解释: ik_smart:粗粒度分词,比如中华人民共和国国歌,会拆分为中华人民共和国,国歌;
ik_max_word:细粒度分词,比如中华人民共和国国歌,会拆分为中华人民共和国,中华人民,
中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌,会穷尽各种可能的组 合。

(5)mysql在linux环境下,有的时候我们搜索引擎查询的数据可能来源于数据库,也就是说搜索引擎需要从数据库中去查询。
因此我们需要在linux环境下开启我们所需要的数据库。
linux环境下安装mysql8.0.30
查看mysql是否被启动

ps -ef|grep mysql

若没有则启动mysql服务

systemctl start mysql

(6)Elasticsearch导入MySQL数据
Logstash 是开源的服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据
发送到您最喜欢的 “存储库” 中。(我们的存储库当然是 Elasticsearch。)
具体操作见文档。。。
因为在这一part我用到了rpc框架,所有我还需要开启zookeeper,也用到了redis缓存,所以我还需要开启zookeeper和redis,redis我设置了开机自启,所有我这里只需要手动开启zookeeper。

bin/zkServer.sh start

ElasticSearch集成springboot

(1)导入依赖

父项目导入依赖的版本号,声明依赖

<properties>
<!-- elasticsearch 依赖 -->
    <elasticsearch.version>7.5.0</elasticsearch.version>
 </properties>
<dependencyManagement>
<dependencies>
<!-- elasticsearch 服务依赖 -->
      <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <!-- rest-client 客户端依赖 -->
      <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
      <!-- rest-high-level-client 客户端依赖 -->
      <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>${elasticsearch.version}</version>
      </dependency>
   </dependencies>
 </denpendencyManagement>

因为ElatiscSearch在前台或者后台系统中都有应用,所有我们可以将它提取出来封装成一个服务,让其他系统充当消费者的角色在需要的时候调用服务。
rpc项目中导入依赖

<!-- elasticsearch 服务依赖 -->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
        </dependency>
        <!-- rest-client 客户端依赖 -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
        </dependency>
        <!-- rest-high-level-client 客户端依赖 -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

配置Es.config和yml文件

我们需要告诉Es.config我们linux的集群的地址,协议,端口号,让这个类文件给我们创建客户端。
application-dec.yml

# Elasticsearch
elasticsearch:
  address: 192.168.186.128:9201, 192.168.186.128:9202, 192.168.186.128:9203

EsConfig java配置类

@Configuration
public class EsConfig {
	//ES服务器地址
	@Value("${elasticsearch.address}")
	private String[] address;
	//ES服务器连接方式
	private static final String SCHEME = "http";

	/**
	 * 根据服务器地址构建HttpHost对象
	 * @param s
	 * @return
	 */
	@Bean
	public HttpHost builderHttpHost(String s){
		String[] address = s.split(":");
		if (2!=address.length){
			return null;
		}
		String host = address[0];
		Integer port = Integer.valueOf(address[1]);
		return new HttpHost(host,port,SCHEME);
	}

	/**
	 * 创建RestClientBuilder对象
	 * @return
	 */
	@Bean
	public RestClientBuilder restClientBuilder(){
		HttpHost[] hosts = Arrays.stream(address)
				.map(this::builderHttpHost)
				.filter(Objects::nonNull)
				.toArray(HttpHost[]::new);
		return RestClient.builder(hosts);
	}

	/**
	 * 创建RestHighLevelClient对象
	 * @param restClientBuilder
	 * @return
	 */
	@Bean
	public RestHighLevelClient restHighLevelClient(@Autowired RestClientBuilder restClientBuilder){
		return new RestHighLevelClient(restClientBuilder);
	}

}

解释:
1、只要是配置类都需要加上@Configuration注解
2、配置ElasticSearch的节点,我们首先需要获取结点的地址和端口号,也就是获取HttpPost对象,通过传进来的地址获取HtppPost对象

HttpHost对象是Apache HttpComponents库提供的一种数据类型,用于表示一个HTTP主机地址,包括主机名、端口号和协议类型等信息。
在Elasticsearch的Java客户端中,HttpHost对象常用于配置Elasticsearch服务器的主机地址和端口号,创建连接到Elasticsearch服务器的RestClientBuilder和RestHighLevelClient对象等。

在yml文件中我们可以进行配置,然后再Config类中取出来就好了。从配置文件yml中取数据用@Value("${elasticsearch.address}"),赋值给数组。
已知String[] address={“192.168.186.128:9201”,“192.168.186.128:9202”,“192.168.186.128:9201”};
创建HttpPost对象的函数为new HttpHost(host,port,SCHEME)
获取host,post可以获取address的每一个元素然后对他进行分隔,得到host和post。SCHEME是协议。

SCHEME常量用于构建HttpHost对象时指定HTTP协议的类型,即"http"或"https"。定义的是一个私有的静态常量,因此它只能被本类中的其他方法调用,而且它不需要基于任何实例化对象而存在,不能被修改。

@Bean
public HostPost bulderHostPost(String s){
	String[] address=s.split(":");
	if(2!=address.length()){
		return null;
	}
	String host = address[0];
	int post = Integer.valueOf(address[1]);
	return new HttpPost(host,post,Scheme);
}

用@Bean是要把HostPost对象放入spring容器中进行管理。

RestClient是Elasticsearch官方提供的RESTful风格的Java客户端,封装了对Elasticsearch服务器的REST API的访问。它提供了更高层次的API,对JSON数据格式和HTTP请求和响应进行了更好的封装和管理。RestClient同时又支持低级别的查询和索引操作。RestClient分为Low Level REST Client和High Level REST Client两种,Low Level REST Client提供基础的 REST API 操作,而High Level REST Client提供了更加高级的 API 接口以及更强的可扩展性。
接下来就是HostPost创建连接到ElasticSearch服务器的客户端了。
创建客户端直接调用RestClient.builder(HttpPost)
通过传进来的所有地址和端口号,获取一个RestClient客户端

利用java8新特性,我们可以将传过来的数组进行改造,返回一个HttpPost类型的数组。

@Bean
	public RestClientBuilder restClientBuilder(){
		HttpHost[] hosts = Arrays.stream(address)
				.map(this::builderHttpHost)
				.filter(Objects::nonNull)
				.toArray(HttpHost[]::new);
		return RestClient.builder(hosts);
	}

创建RestHighLevelClient对象

/**
	 * @param restClientBuilder
	 * @return
	 */
	@Bean
	public RestHighLevelClient restHighLevelClient(@Autowired RestClientBuilder restClientBuilder){
		return new RestHighLevelClient(restClientBuilder);
	}

后端代码调用

因为把搜索引擎抽取出来当做服务了,因此需要用到Dubbo。
首先我们要清楚搜索引擎的入参和出参是什么。当我们输入关键字,点击搜索按钮的时候,出来的一个个的框框,这个框框里面有分页,还有List集合,我们把他砍成一个对象,结合在一起,我们需要把List集合中的对象抽取出来写一个实体类,还需要定义一个相关的分页对象,返回一个分页对象到前端,渲染页面。因为要在网络中传输,所以这个对象要实现序列化。
》实体类,List集合中的类

public class GoodsVo implements Serializable {
	private static final long serialVersionUID = -1905915184535584387L;
	private Integer goodsId;
	private String goodsName;
	private String goodsNameHl;
	private BigDecimal marketPrice;
	private String originalImg;

	public GoodsVo() {
	}

	public GoodsVo(Integer goodsId, String goodsName, String goodsNameHl, BigDecimal marketPrice, String originalImg) {
		this.goodsId = goodsId;
		this.goodsName = goodsName;
		this.goodsNameHl = goodsNameHl;
		this.marketPrice = marketPrice;
		this.originalImg = originalImg;
	}

	public Integer getGoodsId() {
		return goodsId;
	}

	public void setGoodsId(Integer goodsId) {
		this.goodsId = goodsId;
	}

	public String getGoodsName() {
		return goodsName;
	}

	public void setGoodsName(String goodsName) {
		this.goodsName = goodsName;
	}

	public String getGoodsNameHl() {
		return goodsNameHl;
	}

	public void setGoodsNameHl(String goodsNameHl) {
		this.goodsNameHl = goodsNameHl;
	}

	public BigDecimal getMarketPrice() {
		return marketPrice;
	}

	public void setMarketPrice(BigDecimal marketPrice) {
		this.marketPrice = marketPrice;
	}

	public String getOriginalImg() {
		return originalImg;
	}

	public void setOriginalImg(String originalImg) {
		this.originalImg = originalImg;
	}

	@Override
	public String toString() {
		return "GoodsVo{" +
				"goodsId=" + goodsId +
				", goodsName='" + goodsName + '\'' +
				", goodsNameHl='" + goodsNameHl + '\'' +
				", marketPrice=" + marketPrice +
				", originalImg='" + originalImg + '\'' +
				'}';
	}
}

》分页对象中里面有页数,总记录条数等等,还有一个List<T> result来存储分页查询出来的对象,这个之前我们在写商品列表的时候实现过,这里就不赘述了。可见他是经常用到,所以放在了common系统中。

public class ShopPageInfo<T> implements Serializable {
    // 当前页
    private int currentPage;
    // 每页显示条数
    private int pageSize;
    // 总页数
    private int total;
    // 总记录数
    private int count;
    // 上一页
    private int prePage;
    // 下一页
    private int nextPage;
    // 是否有上一页
    private boolean hasPre;
    // 是否有下一页
    private boolean hasNext;
    // 返回结果
    private List<T> result;

    // 构造函数1
    public ShopPageInfo() {
        super();
    }

    // 构造函数2
    public ShopPageInfo(int currentPage, int pageSize) {
        super();
        this.currentPage = (currentPage < 1) ? 1 : currentPage;
        this.pageSize = pageSize;
        // 是否有上一页
        this.hasPre = (currentPage == 1) ? false : true;
        // 是否有下一页
        this.hasNext = (currentPage == total) ? false : true;
        // 上一页
        if (hasPre) {
            this.prePage = (currentPage - 1);
        }
        // 下一页
        if (hasNext) {
            this.nextPage = currentPage + 1;
        }

    }

    // 构造函数3
    public ShopPageInfo(int currentPage, int pageSize, int count) {
        super();
        this.currentPage = (currentPage < 1) ? 1 : currentPage;
        this.pageSize = pageSize;
        this.count = count;
        // 计算总页数
        if (count == 0) {
            this.total = 0;
        } else {
            this.total = (count % pageSize == 0) ? (count / pageSize) : (count / pageSize + 1);
        }
        // 是否有上一页
        this.hasPre = (currentPage == 1) ? false : true;
        // 是否有下一页
        this.hasNext = (currentPage == total) ? false : true;
        // 上一页
        if (hasPre) {
            this.prePage = (currentPage - 1);
        }
        // 下一页
        if (hasNext) {
            this.nextPage = currentPage + 1;
        }
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getPrePage() {
        return prePage;
    }

    public void setPrePage(int prePage) {
        this.prePage = prePage;
    }

    public int getNextPage() {
        return nextPage;
    }

    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }

    public boolean isHasPre() {
        return hasPre;
    }

    public void setHasPre(boolean hasPre) {
        this.hasPre = hasPre;
    }

    public boolean isHasNext() {
        return hasNext;
    }

    public void setHasNext(boolean hasNext) {
        this.hasNext = hasNext;
    }

    public List<T> getResult() {
        return result;
    }

    public void setResult(List<T> result) {
        this.result = result;
    }
}

在进行搜索的时候,我需要传进去一个关键字,还有分页查询的关键字眼pageNum,pageSize
ServerImp

@Service(interfaceClass = SearchService.class)
@Component
public class SearchServiceImpl implements com.wll.shoprpc.service.SearchService {

	@Resource
	private RestHighLevelClient client;

	/**
	 * 搜索
	 * @param searchStr
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	@Override
	public ShopPageInfo<GoodsVo> doSearch(String searchStr, Integer pageNum, Integer pageSize) {
		//构建分页对象
		ShopPageInfo<GoodsVo> shopPageInfo;
		try {
			//指定索引库
			SearchRequest searchRequest = new SearchRequest("shop");
			//构建查询对象
			SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
			//设置分页条件
			searchSourceBuilder.from((pageNum-1)*pageSize).size(pageSize);
			//构建高亮对象
			HighlightBuilder highlightBuilder = new HighlightBuilder();
			//设置高亮字段及高亮样式
			highlightBuilder.field("goodsName")
					.preTags("<span style='color:red'>")
					.postTags("</span>");
			searchSourceBuilder.highlighter(highlightBuilder);
			//添加查询条件
			searchSourceBuilder.query(QueryBuilders.multiMatchQuery(searchStr,"goodsName"));
			searchRequest.source(searchSourceBuilder);
			//执行请求
			List<GoodsVo> list = new ArrayList<>();
			SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
			//总条数
			Long total = response.getHits().getTotalHits().value;
			if (0>total){
				return null;
			}
			SearchHit[] hits = response.getHits().getHits();
			for (SearchHit hit : hits) {
				Integer goodsId = Integer.valueOf((Integer) hit.getSourceAsMap().get("goodsId"));
				String goodsName = String.valueOf(hit.getSourceAsMap().get("goodsName"));
				String goodsNameHl = String.valueOf(hit.getHighlightFields().get("goodsName").fragments()[0]);
				BigDecimal marketPrice = new BigDecimal(String.valueOf(hit.getSourceAsMap().get("marketPrice")));
				String originalImg = String.valueOf(hit.getSourceAsMap().get("originalImg"));
				GoodsVo goodsVo = new GoodsVo(goodsId,goodsName,goodsNameHl,marketPrice,originalImg);
				list.add(goodsVo);
			}
			shopPageInfo = new ShopPageInfo<GoodsVo>(pageNum,pageSize,total.intValue());
			shopPageInfo.setResult(list);
			return shopPageInfo;
			//处理数据
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
这是一个搜索商品的方法,可以根据搜索关键字进行商品搜索。该方法使用Elasticsearch进行搜索,根据搜索结果返回一个ShopPageInfo对象,包含符合条件的商品列表和分页信息。

参数说明:

- searchStr: 搜索关键字
- pageNum: 当前页码
- pageSize: 每页显示条目数

方法实现:

该方法首先构造了一个SearchRequest对象,并指定搜索的索引库为 "shop",然后构建一个SearchSourceBuilder对象,用于设置搜索条件。通过设置from()size()方法实现分页功能,并使用highlighter()方法设置高亮字段及高亮样式。接着,使用multiMatchQuery()方法构建查询条件,指定需要匹配的字段和搜索关键字,将查询条件添加到SearchSourceBuilder对象中。

然后将SearchSourceBuilder对象设置到SearchRequest对象中,并通过Elasticsearch的Java客户端的search()方法执行搜索请求,并获取响应结果SearchResponse。从SearchResponse中获取到搜索结果的总条数total和匹配了查询条件的商品列表hits。遍历hits列表,从中获取商品信息,构造GoodsVo对象并添加到list中。

最后,构造ShopPageInfo对象,将list设置为结果列表,返回ShopPageInfo对象。

如果发生异常,返回null。

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

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

相关文章

大数据 | (五)通过Sqoop实现从MySQL导入数据到HDFS

知识目录 一、前言二、导入前的准备2.1 Hadoop集群搭建2.2 Hadoop启停脚本 三、docker安装MySQL四、安装Sqoop4.1 Sqoop准备4.2 Sqoop连接Mysql数据测试 五、导入MySQL数据到hdfs5.1 准备MySQL数据5.2 导入数据 六、Sqoop现状七、结语 一、前言 各位CSDN的朋友们大家好&#x…

5.11组会衍生总结:train/eval/BN、CNN与特征图、极大似然与EM、方差n与n-1(有偏估计/无偏估计)

目录组会问题:1.关于模型的train/eval与batchnorm1-1.理论1-2.实际运用(包含loss反向传播)2.CNN详解,特征图是什么CNN处理过程特征图(也叫通道)(num_features)总结(包含CNN图片的规律分析):3.极大似然估计与EM最大期望4.方差的n与n-1(有偏估计与无偏估计) 组会问题:…

企业文化和品牌文化是两回事

商业通常谈两类文化&#xff1a;企业文化&#xff0c;品牌文化 1&#xff09;组织内部的文化 2&#xff09;品牌以产品为依托&#xff0c;给消费群体营造的文化 “积极稳定”的文化氛围打造是个慢活 企业文化&#xff0c;既要挂在墙上&#xff0c;又要挂在嘴上&#xff0c;最终…

二叉查找树和平衡二叉树

二叉查找树 下面是一张数据库的表,有两列,分别是 Col1 和 Col2 我们来查找一下col289的这行数据,SQL语句如下: select * from a where col2 87没有用索引时执行上面的查询 , 数据从磁盘一条一条拿来对比最终找到结果&#xff0c;如果数据表很大,数据又在表尾的话,需要花费非…

Open3D点云数据处理(一):VSCode配置python,并安装open3d教程

文章目录 1 python下载与安装1.1 python下载1.2 python安装1.3 验证python是否安装成功 2 VSCode下载与安装2.1 下载2.2 安装2.3 安装汉化插件2.4 vscode安装python扩展2.5 编写一个简单的python程序并运行2.6 在外部终端中打印运行结果2.7 测试代码&#xff1a;使用python画一…

常用的网页设计工具,有哪些比较推荐

网页设计并不容易&#xff0c;易于使用的网页设计工具更难找到。随着网络的快速发展&#xff0c;网站迅速崛起&#xff0c;网页设计也很流行。本文收集了7款易于使用的网页设计工具&#xff0c;每一种近年来都受到网页设计师的广泛欢迎&#xff0c;以确保实用和易于使用。我希望…

背包九讲(dp问题详解)

一、01背包问题 首先了解一下题目&#xff1a; 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。…

Java中的抽象类介绍

Java中的抽象类介绍 抽象类可以包含普通类的成员&#xff0c;它可以包含普通的属性、方法和内部类等成员。这些成员既可以被抽象类的子类继承和使用&#xff0c;也可以被抽象类自身使用。抽象类中的非抽象方法必须要有具体实现&#xff0c;否则无法通过编译。抽象类中也可以拥…

Leetcode2379. 得到 K 个黑块的最少涂色次数

Every day a Leetcode 题目来源&#xff1a;2379. 得到 K 个黑块的最少涂色次数 解法1&#xff1a;滑动窗口 首先题目给出一个下标从 0 开始长度为 n 的字符串 blocks&#xff0c;其中 blocks[i] 是 ‘W’ 或者 ‘B’ &#xff0c;分别表示白色块要么是黑色块。 现在我们可…

抗体偶联药物都有哪些?(详细名单)

抗体偶联药物ADC简介 抗体-药物偶联物或ADC是一类生物制药药物&#xff0c;设计用于治疗癌症的靶向疗法。与化学疗法不同&#xff0c;ADC 旨在靶向并杀死肿瘤细胞&#xff0c;同时保留健康细胞。截至 2023 年5月&#xff0c;约有 433 家制药公司正在开发 ADC。 ADC 是由与具有…

SPI基础

SPI硬件接口 SPI协议使用3条总线以及片选线。3条总线分别是SCK、MOSI、MISO&#xff0c;片选线为SS(NSS、CS) SPI基础属性 主从模式&#xff1a;主机模式&#xff0c;从机模式 通讯频率&#xff1a;不定&#xff0c;根据设备速率确定 数据位数&#xff1a;4位、7位&#xff…

基于狮群算法优化的核极限学习机(KELM)分类算法-附代码

基于狮群算法优化的核极限学习机(KELM)分类算法 文章目录 基于狮群算法优化的核极限学习机(KELM)分类算法1.KELM理论基础2.分类问题3.基于狮群算法优化的KELM4.测试结果5.Matlab代码 摘要&#xff1a;本文利用狮群算法对核极限学习机(KELM)进行优化&#xff0c;并用于分类 1.KE…

【华为机试】——每日刷题经验分享

【华为机试】——每日刷题经验分享&#x1f60e; 前言&#x1f64c;题目&#xff1a;HJ9 提取不重复的整数 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &a…

被ChatGPT“抢饭碗”的人

ChatGPT问世至今&#xff0c;互联上讨论声绵延不绝。有人说&#xff0c;AI会替代基础性工作。 一名金融从业者对《橡果商业评论》表示&#xff0c;这实际上是对人类经验的替代&#xff0c;那些引以为傲的经验&#xff0c;来源于对历史的总结&#xff0c;AI出现后&#xff0c;“…

【C++STL】红黑树(更新中)

前言 上篇博客学习了平衡二叉搜索树(AVLTree)&#xff0c;了解到AVL树的性质&#xff0c;二叉搜索树因为其独特的结构&#xff0c;查找、插入和删除在平均和最坏情况下都是O(logn)。AVL树的效率就是高在这个地方。 但是在AVL树中插入或者删除结点&#xff0c;使得高度差的绝对…

【GO 编程语言】数组

数组 文章目录 数组一、数组是什么二、初始化数组三、数组的遍历四、数组类型五、数组排序 一、数组是什么 Go 语言提供了数组类型的 数据结构。 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型。例如整型、字符串或者自定义类型。 …

HTTP第八讲——请求方法

目前 HTTP/1.1 规定了八种方法&#xff0c;单词都必须是大写的形式 GET&#xff1a;获取资源&#xff0c;可以理解为读取或者下载数据&#xff1b;HEAD&#xff1a;获取资源的元信息&#xff1b;POST&#xff1a;向资源提交数据&#xff0c;相当于写入或上传数据&#xff1b;P…

echarts 如何保存为图片时,如何同时保存滚动条隐藏的数据

echarts 如何保存为图片&#xff0c;如何保存滚动条隐藏的数据 效果展示上代码内容讲解面临的问题解决思路&#xff08;当前代码的思路&#xff09; 效果展示 这是直接将保存的图片显示在网页下方了 上代码 <!DOCTYPE html> <html><head><meta charse…

【2023/05/11】Edsger Dijkstra

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第6天。 Share Sorrow is hushed into peace in my heart like the evening among thr silent trees. 译文&#xff1a; 忧思在我的心里平静下去&#xff0c;正如暮色降临在寂静的山林中。 Some unsee…

【报告回顾】精、稳、敏、融,步入人民金融时代

易观分析&#xff1a;2022年&#xff0c;在深化金融供给侧结构性改革和高质量增长要求的指引下&#xff0c;赋能实体、公平普惠、审慎经营成为银行业转型发展的关键词。一方面面临内外部复杂的经济环境和不确定性风险&#xff0c;银行主打稳健策略&#xff0c;数字化转型仍在持…