SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)
SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)
- 前言
- 添加maven依赖
- yml配置
- ElasticsearchConfig 连接配置类
- EsUtil 工具类
- 开始测试
前言
- 由ES官方提供,代码语法和DSL语法相似(即Json格式的ES操作语法);
- 用法灵活,可以自由使用;
- SpringBoot 和 ES 版本的关联性较小;
比较推荐使用这种方式
添加maven依赖
<!--Elasticsearch的核心库-->
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.15.2</version>
</dependency>
<!--Elasticsearch 低级别REST客户端-->
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.15.2</version>
</dependency>
<!--Elasticsearch 高级别REST客户端-->
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.15.2</version>
</dependency>
依赖解释
-
elasticsearch
Elasticsearch的核心库,只是在客户端应用中与Elasticsearch集群交互,通常不需要直接包含这个依赖 -
elasticsearch-rest-client
低级别的REST客户端,提供了基础的HTTP请求构建和执行能力,但不包括高级抽象,如索引、搜索等操作的封装 -
elasticsearch-rest-high-level-client
高级REST客户端,它建立在elasticsearch-rest-client之上,提供了更高级别的抽象,如索引、搜索、更新等操作的封装。这使得与Elasticsearch的交互变得更加简单和直接。
yml配置
# es集群名称
elasticsearch.clusterName=single-node-cluster
#es用户名
elasticsearch.userName=elastic
#es密码
elasticsearch.password=elastic
# es host ip 地址(集群):本次使用的是单机模式
elasticsearch.hosts=127.0.0.1:9200
# es 请求方式
elasticsearch.scheme=http
# es 连接超时时间
elasticsearch.connectTimeOut=1000
# es socket 连接超时时间
elasticsearch.socketTimeOut=30000
# es 请求超时时间
elasticsearch.connectionRequestTimeOut=500
# es 最大连接数
elasticsearch.maxConnectNum=100
# es 每个路由的最大连接数
elasticsearch.maxConnectNumPerRoute=100
ElasticsearchConfig 连接配置类
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.ArrayList;
import java.util.List;/*** restHighLevelClient 客户端配置类*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticsearchConfig {// es host ip 地址(集群)private String hosts;// es 用户名private String userName;// es 密码private String password;// es 请求方式private String scheme;// es 集群名称private String clusterName;// es 连接超时时间private int connectTimeOut;// es socket 连接超时时间private int socketTimeOut;// es 请求超时时间private int connectionRequestTimeOut;// es 最大连接数private int maxConnectNum;// es 每个路由的最大连接数private int maxConnectNumPerRoute;/*** 如果@Bean没有指定bean的名称,那么这个bean的名称就是方法名*/@Bean(name = "restHighLevelClient")public RestHighLevelClient restHighLevelClient() {RestHighLevelClient restHighLevelClient = null;try {// 集群,拆分地址List<HttpHost> hostLists = new ArrayList<>();String[] hostList = hosts.split(",");for (String addr : hostList) {String host = addr.split(":")[0];String port = addr.split(":")[1];hostLists.add(new HttpHost(host, Integer.parseInt(port), scheme));}// 转换成 HttpHost 数组HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});// 构建连接对象RestClientBuilder builder = RestClient.builder(httpHost);// 设置用户名、密码CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));// 连接延时配置builder.setRequestConfigCallback(requestConfigBuilder -> {requestConfigBuilder.setConnectTimeout(connectTimeOut);requestConfigBuilder.setSocketTimeout(socketTimeOut);requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);return requestConfigBuilder;});// 连接数配置builder.setHttpClientConfigCallback(httpClientBuilder -> {httpClientBuilder.setMaxConnTotal(maxConnectNum);httpClientBuilder.setMaxConnPerRoute(maxConnectNumPerRoute);httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);return httpClientBuilder;});restHighLevelClient = new RestHighLevelClient(builder);} catch (NumberFormatException e) {log.error("ES 连接池初始化异常");}return restHighLevelClient;}
}
EsUtil 工具类
工具类中,讲到的 index 其实就是 表名称
package com.example.springbootfull.elasticsearchclient.util;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;/*** es 的工具类** @author*/
@Slf4j
@Component
public class EsUtil {@Autowiredprivate RestHighLevelClient restHighLevelClient;/*** 关键字*/public static final String KEYWORD = ".keyword";/*** 创建索引** @param index 索引* @return*/public boolean createIndex(String index) throws IOException {if (isIndexExist(index)) {log.error("Index is exits!");return false;}//1.创建索引请求CreateIndexRequest request = new CreateIndexRequest(index);//2.执行客户端请求CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);log.info("创建索引{}成功", index);return response.isAcknowledged();}/*** 删除索引** @param index* @return*/public boolean deleteIndex(String index) throws IOException {if (!isIndexExist(index)) {log.error("Index is not exits!");return false;}//删除索引请求DeleteIndexRequest request = new DeleteIndexRequest(index);//执行客户端请求AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);log.info("删除索引{}成功", index);return delete.isAcknowledged();}/*** 判断索引是否存在** @param index* @return*/public boolean isIndexExist(String index) throws IOException {GetIndexRequest request = new GetIndexRequest(index);boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);return exists;}/*** 数据添加,正定ID** @param jsonObject 要增加的数据* @param index 索引,类似数据库* @param id 数据ID, 为null时es随机生成* @return*/public String addData(JSONObject jsonObject, String index, String id) throws IOException {//创建请求IndexRequest request = new IndexRequest(index);//规则 put /test_index/_doc/1request.id(id);request.timeout(TimeValue.timeValueSeconds(1));//将数据放入请求 jsonIndexRequest source = request.source(jsonObject, XContentType.JSON);//客户端发送请求IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);log.info("添加数据成功 索引为: {}, response 状态: {}, id为: {}", index, response.status().getStatus(), response.getId());return response.getId();}/*** 数据添加 随机id** @param jsonObject 要增加的数据* @param index 索引,类似数据库* @return*/public String addData(JSONObject jsonObject, String index) throws IOException {return addData(jsonObject, index, UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());}/*** 通过ID删除数据** @param index 索引,类似数据库* @param id 数据ID*/public void deleteDataById(String index, String id) throws IOException {//删除请求DeleteRequest request = new DeleteRequest(index, id);//执行客户端请求DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);log.info("索引为: {}, id为: {}删除数据成功", index, id);}/*** 通过ID 更新数据** @param object 要增加的数据* @param index 索引,类似数据库* @param id 数据ID* @return*/public void updateDataById(Object object, String index, String id) throws IOException {//更新请求UpdateRequest update = new UpdateRequest(index, id);//保证数据实时更新//update.setRefreshPolicy("wait_for");update.timeout("1s");update.doc(JSON.toJSONString(object), XContentType.JSON);//执行更新请求UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT);log.info("索引为: {}, id为: {}, 更新数据成功", index, id);}/*** 通过ID 更新数据,保证实时性** @param object 要增加的数据* @param index 索引,类似数据库* @param id 数据ID* @return*/public void updateDataByIdNoRealTime(Object object, String index, String id) throws IOException {//更新请求UpdateRequest update = new UpdateRequest(index, id);//保证数据实时更新update.setRefreshPolicy("wait_for");update.timeout("1s");update.doc(JSON.toJSONString(object), XContentType.JSON);//执行更新请求UpdateResponse update1 = restHighLevelClient.update(update, RequestOptions.DEFAULT);log.info("索引为: {}, id为: {}, 更新数据成功", index, id);}/*** 通过ID获取数据** @param index 索引,类似数据库* @param id 数据ID* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)* @return*/public Map<String, Object> searchDataById(String index, String id, String fields) throws IOException {GetRequest request = new GetRequest(index, id);if (StringUtils.isNotEmpty(fields)) {//只查询特定字段。如果需要查询所有字段则不设置该项。request.fetchSourceContext(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY));}GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);Map<String, Object> map = response.getSource();//为返回的数据添加idmap.put("id", response.getId());return map;}/*** 通过ID判断文档是否存在** @param index 索引,类似数据库* @param id 数据ID* @return*/public boolean existsById(String index, String id) throws IOException {GetRequest request = new GetRequest(index, id);//不获取返回的_source的上下文request.fetchSourceContext(new FetchSourceContext(false));request.storedFields("_none_");return restHighLevelClient.exists(request, RequestOptions.DEFAULT);}/*** 获取低水平客户端** @return*/public RestClient getLowLevelClient() {return restHighLevelClient.getLowLevelClient();}/*** 高亮结果集 特殊处理* map转对象 JSONObject.parseObject(JSONObject.toJSONString(map), Content.class)** @param searchResponse* @param highlightField*/public List<Map<String, Object>> setSearchResponse(SearchResponse searchResponse, String highlightField) {//解析结果ArrayList<Map<String, Object>> list = new ArrayList<>();for (SearchHit hit : searchResponse.getHits().getHits()) {Map<String, HighlightField> high = hit.getHighlightFields();HighlightField title = high.get(highlightField);hit.getSourceAsMap().put("id", hit.getId());Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果//解析高亮字段,将原来的字段换为高亮字段if (title != null) {Text[] texts = title.fragments();String nTitle = "";for (Text text : texts) {nTitle += text;}//替换sourceAsMap.put(highlightField, nTitle);}list.add(sourceAsMap);}return list;}/*** 查询并分页** @param index 索引名称* @param query 查询条件* @param size 文档大小限制* @param from 从第几页开始* @param fields 需要显示的字段,逗号分隔(缺省为全部字段)* @param sortField 排序字段* @param highlightField 高亮字段* @return*/public List<Map<String, Object>> searchListData(String index,SearchSourceBuilder query,Integer size,Integer from,String fields,String sortField,String highlightField) throws IOException {SearchRequest request = new SearchRequest(index);SearchSourceBuilder builder = query;if (StringUtils.isNotEmpty(fields)) {//只查询特定字段。如果需要查询所有字段则不设置该项。builder.fetchSource(new FetchSourceContext(true, fields.split(","), Strings.EMPTY_ARRAY));}from = from <= 0 ? 0 : from * size;//设置确定结果要从哪个索引开始搜索的from选项,默认为0builder.from(from);builder.size(size);if (StringUtils.isNotEmpty(sortField)) {//排序字段,注意如果proposal_no是text类型会默认带有keyword性质,需要拼接.keywordbuilder.sort(sortField + ".keyword", SortOrder.ASC);}//高亮HighlightBuilder highlight = new HighlightBuilder();highlight.field(highlightField);//关闭多个高亮highlight.requireFieldMatch(false);highlight.preTags("<span style='color:red'>");highlight.postTags("</span>");builder.highlighter(highlight);//不返回源数据。只有条数之类的数据。//builder.fetchSource(false);request.source(builder);SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);log.error("==" + response.getHits().getTotalHits());if (response.status().getStatus() == 200) {// 解析对象return setSearchResponse(response, highlightField);}return null;}
}
开始测试
实体类
package com.example.springbootfull.elasticsearchclient.bean;import java.math.BigDecimal;
import java.util.Date;public class EmployeeInfo2 {private Long id;/*** 工号*/private String jobNo;/*** 姓名*/private String name;/*** 英文名*/private String englishName;/*** 工作岗位*/private String job;/*** 性别*/private Integer sex;/*** 年龄*/private Integer age;/*** 薪资*/private BigDecimal salary;/*** 入职时间*/private Date jobDay;/*** 备注*/private String remark;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getJobNo() {return jobNo;}public void setJobNo(String jobNo) {this.jobNo = jobNo;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEnglishName() {return englishName;}public void setEnglishName(String englishName) {this.englishName = englishName;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public Integer getSex() {return sex;}public void setSex(Integer sex) {this.sex = sex;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public BigDecimal getSalary() {return salary;}public void setSalary(BigDecimal salary) {this.salary = salary;}public Date getJobDay() {return jobDay;}public void setJobDay(Date jobDay) {this.jobDay = jobDay;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark = remark;}public EmployeeInfo2() {}public EmployeeInfo2(Long id, String jobNo, String name, String englishName, String job, Integer sex, Integer age, BigDecimal salary, Date jobDay, String remark) {this.id = id;this.jobNo = jobNo;this.name = name;this.englishName = englishName;this.job = job;this.sex = sex;this.age = age;this.salary = salary;this.jobDay = jobDay;this.remark = remark;}@Overridepublic String toString() {return "EmployeeInfo{" +"id=" + id +", jobNo='" + jobNo + '\'' +", name='" + name + '\'' +", englishName='" + englishName + '\'' +", job='" + job + '\'' +", sex=" + sex +", age=" + age +", salary=" + salary +", jobDay=" + jobDay +", remark='" + remark + '\'' +'}';}
}
Controller类
package com.example.springbootfull.elasticsearchclient.controller;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.example.springbootfull.elasticsearchclient.bean.EmployeeInfo2;
import com.example.springbootfull.elasticsearchclient.util.EsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;
import java.text.SimpleDateFormat;@RestController
@RequestMapping("/employeeInfo")
public class EmployeeElasticController {@Autowiredprivate EsUtil esUtil;//==========esUtil================@RequestMapping("/createIndex")public String createIndex() throws Exception {esUtil.createIndex("employee_info_2");return "success";}@RequestMapping("/deleteIndex")public String deleteIndex() throws Exception {esUtil.deleteIndex("employee_info_2");return "success";}@RequestMapping("/save")public String save() throws Exception {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");EmployeeInfo2 employeeInfo = new EmployeeInfo2(6001L, "2001", "我去", "zhangsan", "Java", 1, 19, new BigDecimal("12500.01"), simpleDateFormat.parse("2019-09-10"), "备注");//可以帮我把驼峰命名的属性转成下划线格式的(如果你需要的话)SerializeConfig config = new SerializeConfig();config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;String json1 = JSON.toJSONString(employeeInfo, config);esUtil.addData(JSONObject.parseObject(json1), "employee_info_2", null);//不然直接//esUtil.addData((JSONObject) JSONObject.toJSON(employeeInfo), "employee_info_2", null);return "success";}}
执行save 方法后,可以看到 es 可视化页面上面 出现了 一条数据
(其中的id,由于我给了null,es就随机帮我生成了)
参考文章:
【1】SpringBoot整合ElasticSearch的两种方式
【2】elasticsearch7.9 java工具类restHighLevelClient精华整理JavaRESTClient
【3】三种方式实现Java对象转json下划线格式
相关文章:

SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)
SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式) 前言添加maven依赖yml配置ElasticsearchConfig 连接配置类EsUtil 工具类开始测试 前言 由ES官方提供,代码语法和DSL语法相似…...

【Vue3】常用的响应式数据类型
ref 定义基本类型 <template><div>{{ sum }}</div> </template><script setup> import { ref } from vuelet sum ref(10)const btn () > {sum.value 200 } </srcipt>reactive 定义复杂类型 <template><div>{{ sum }…...

搭建本地DVWA靶场教程 及 靶场使用示例
1. DVWA简介 DVWA(Damn Vulnerable Web Application)一个用来进行安全脆弱性鉴定的PHP/MySQL Web 应用平台,旨在为网络安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。 DVW…...

60. n 个骰子的点数【难】
comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9860.%20n%E4%B8%AA%E9%AA%B0%E5%AD%90%E7%9A%84%E7%82%B9%E6%95%B0/README.md 面试题 60. n 个骰子的点数 题目描述 把n个骰子扔在地上,所…...

高性能编程:无锁队列
目录 1. 无锁队列 1.1 无锁 1.1.1 阻塞(Blocking) 1.1.2 无锁(Lock-Free) 1.1.3 无等待(Wait-Free) 1.2 队列 1.2.1 链表实现的队列 1.2.2 数组实现的队列 1.2.3 混合实现的队列 1.3 多线程中的先…...

word标题排序编号错误
1.问题:word中有时会出现当前编号是2.1、3.1、4.1,下级编号却从1.1.1开始的情况,类似情况如下: 2.原因:此问题多为编号4.1、4.2和编号4.1.1使用的多级编号模板不一样,可以选中4.2,看下使用的多级…...

力扣---80. 删除有序数组中的重复项 II
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明&…...

一篇文章,讲清SQL的 joins 语法
SQL 中的不同 JOIN 类型: 1. (INNER)JOIN(内连接):返回两个表中具有匹配值的记录。 2. LEFT(OUTER)JOIN(左外连接):返回左表中的所有记录&#…...

设计模式之建造者模式(通俗易懂--代码辅助理解【Java版】)
文章目录 设计模式概述1、建造者模式2、建造者模式使用场景3、优点4、缺点5、主要角色6、代码示例:1)实现要求2)UML图3)实现步骤:1)创建一个表示食物条目和食物包装的接口2)创建实现Packing接口的实体类3&a…...

文生视频算法
文生视频 Sora解决问题:解决思路: CogVideoX解决问题:解决思路: Stable Video Diffusion(SVD)解决问题:解决思路: 主流AI视频技术框架: Sora Sora: A Review on Backg…...

LoRA: Low-Rank Adaptation Abstract
LoRA: Low-Rank Adaptation Abstract LoRA 论文的摘要介绍了一种用于减少大规模预训练模型微调过程中可训练参数数量和内存需求的方法,例如拥有1750亿参数的GPT-3。LoRA 通过冻结模型权重并引入可训练的低秩分解矩阵,减少了10,000倍的可训练参数…...

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编
文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、…...

Unreal Engine——AI生成高精度的虚拟人物和环境(虚拟世界构建、电影场景生成)(一)
一、Unreal Engine 介绍 Unreal Engine(虚幻引擎)是由Epic Games开发的强大3D游戏开发引擎,自1998年首次发布以来,已经历了多个版本的迭代。虚幻引擎主要用于制作高品质的3D游戏,但也广泛用于电影、建筑、仿真等其他领…...

Emlog程序屏蔽用户IP拉黑名单插件
插件介绍 在很多时候我们需要得到用户的真实IP地址,例如,日志记录,地理定位,将用户信息,网站数据分析等,其实获取IP地址很简单,感兴趣的可以参考一下。 今天给大家带来舍力写的emlog插件:屏蔽…...

发送成绩的app或小程序推荐
老师们,新学期的第一次月考马上开始,是不是还在为如何高效、便捷地发布成绩而头疼呢?别担心,都2024年了,我们有更智能的方式来解决这个问题! 给大家安利一个超级实用的工具——易查分小程序。这个小程序简…...

51单片机-AT24C02(IIC总线介绍及其时序编写步骤)-第一节(下一节实战)
IIC开始通信(6大步) 我以前的文章也有对基本常用的通信协议讲解,如SPI UART IIC RS232 RS485 CAN的讲解,可前往主页查询,(2024.9.12,晚上20:53,将AT24C02存储芯片,掉电不…...

<<编码>> 第 11 章 逻辑门电路--或非门, 与非门, 缓冲器 示例电路
继电器或非门 info::操作说明 鼠标单击开关切换开合状态 闭合任意一个开关可使电路断开 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/code-hlchs-examples/assets/circuit/code-hlchs-ch11-19-nor-gate-by-relay.txt 或非门 i…...

股票api接口程序化报备,程序化交易监管对个人量化交易者有何影响
炒股自动化:申请官方API接口,散户也可以 python炒股自动化(0),申请券商API接口 python炒股自动化(1),量化交易接口区别 Python炒股自动化(2):获取…...

如何自己搭建一个网站?
今天的文章总结适合0基础,网站搭建的技巧和流程,哪怕你是小白,不会编程,也可以制作非常漂亮且实用的企业网站,如果想做个人博客更是不在话下。希望我的经验能帮助更多没有过多的经费、没有建站基础的朋友。用户跟着我的…...

虚拟化数据恢复—断电导致虚拟机目录项被破坏的数据恢复案例
虚拟化数据恢复环境: 某品牌服务器(部署VMware EXSI虚拟机)同品牌存储(存放虚拟机文件)。 虚拟化故障: 意外断电导致服务器上某台虚拟机无法正常启动。查看虚拟机配置文件发现这台故障虚拟机除了磁盘文件以…...

[机器学习]聚类算法
1 聚类算法简介 # 导包 from sklearn.datasets import make_blobs import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.metrics import calinski_harabasz_score # 构建数据 x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1…...

JVM面试真题总结(七)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 解释GC的引用计数算法及其局限性 引用计数算法是一种非常直观、简…...

深入理解CASAtomic原子操作类详解
1.CAS介绍 什么是 CAS CAS(Compare And Swap,比较与交换),是非阻塞同步的实现原理,它是CPU硬件层面的一种指令,从CPU层面能保证"比较与交换"两个操作的原子性。CAS指令操作包括三个参数&#x…...

C51单片机-单按键输入识别,键盘消抖
【实验目的】 独立按键的识别方法、键盘消抖等。 【实验现象】 每按一次独立键盘的S2键,与P1口相连的八个发光二极管中点亮的一个往下移动一位。 【实验说明】 关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因…...

基于CNN卷积神经网络迁移学习的图像识别实现
基于CNN卷积神经网络迁移学习的图像识别实现 基于CNN卷积神经网络迁移学习的图像识别实现写在前面一,原理介绍迁移学习的基本方法1.样本迁移(Instance based TL)2.特征迁移(Feature based TL)3.模型迁移(Pa…...

【iOS】push和present的区别
【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中,我们经常性的会用到界面的一个切换的问题,这里我们需要理清…...

在Linux服务器上添加用户并设置自动登录
需要在Linux服务器上添加一个新用户,可以使用以下命令 # 这个命令会创建一个新的用户账户,默认情况下不会设置密码,不会在 /home 目录下为新用户创建home目录: # sudo useradd 用户名 # # 如果希望同时为新用户创建家目录&#…...

网站被爬,数据泄露,如何应对不断强化的安全危机?
近年来,众多传统零售商和互联网企业借助大数据、人工智能等先进技术手段,通过场景化设计、优化客户体验、融合线上线下渠道,推动了网络电商行业的消费方式变革,成为电商领域新的增长动力。 但值得注意的是,网络电商带来…...

为什么HTTPS会引入SSL/TLS协议
这时我面试遇到过的问题,整理了一下,希望对大家有帮助! 祝大家秋招顺利! 首先 SSL/TLS 协议通过使用数字证书来实现服务器身份认证, 当用户访问一个 HTTPS 网站时,浏览器会验证服务器的数字证书, 1.首先他对验证整证书是否在有效期 2.其次他会看证书中的服务器域名…...

Spring AOP,通知使用,spring事务管理,spring_web搭建
spring AOP AOP概述 AOP面向切面编程是对面向对象编程的延续(AOP (Aspect Orient Programming),直译过来就是 面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。) 面向切面编…...