当前位置: 首页 > news >正文

Elasticsearch 处理地理信息

1、GeoHash

​ GeoHash是一种地理坐标编码系统,可以将地理位置按照一定的规则转换为字符串,以方便对地理位置信息建立空间索引。首先要明确的是,GeoHash代表的不是一个点而是一个区域。GeoHash具有两个显著的特点:一是通过改变 GeoHash的长度,我们可以表示任意精度的位置:GeoHash越短,其表示的区域越大,位置精度越低;相反,GeoHash越长,其表示的区域越小,位置精度越高。Elasticsearch 支持GeoHash字符串长度是12,这个精度已经达到了厘米级别;二是如果不同位置的GeoHash字符串前缀相同,那他们一定在同一个区域中。

​ GeoHash将地理坐标编码为字符串的方法与二分查找有几分相识。它将经纬度范围一分为二,分成左右两个区间;坐标落入左区间为0,落入右区间为1。按照此方法,分别对精度和维度不停地地柜逼近实际坐标值,就会得到两组由0,1组成的数字字符串。然后按照偶数位放经度,奇数位放纬度的方法,将两组数据串联组合起来。最后将组合的数字串转换成十进制,并用Base32对数字进行编码就得到GeoHash最终编码了。

​ 根据经纬度的定义,经度整体范围为: [ -180 , 180 ] ,纬度整体范围为:[ -90 , 90 ]。所以第一次递归分割坐标后,经度的左右区间为 **[ -180 , 0 ) **和

[ 0 , 180 ],即西半球和东半球 纬度的左右区间为 **[ -90 , 0 ) [ 0 , 90 ],即南半球和北半球。以山东济南某地坐标( 117.15838 , 36.74038 )**为例,经纬度第一次递归后都落入到右区间,则他们第一位数字都是1。由于落入了右区间,所以经纬第二次递归就是针对右区间分割:经度为 **[ 0 , 90 ) **和 [ 90 , 180 ],纬度为

[ 0 , 45 ) [ 45 , 90 ] 。这次经度落入到了右区间,二纬度落入了左区间,所以他们的第二位数字分别为10。按照此方法不停的递归下去,就能无线的接近于实际坐标。

​ 可以看出,GeoHash时间上是将地球假设为一个平面,然后在这个平面上划分网格的过程。在这个递归的过程中,每一次都是将整个区域一分为二,区域面积也就约分越小,而且在相同区域的位置他们的前缀数字一定是相同的。表1-1列出了经度 117.15838经过十次递归运算过程及结果。

表1-1 GeoHash经度 117.15838

次数经度范围左区间 - 0右区间 - 1117.15838
1[ -180 , 180 ][ -180 , 0 )[ 0 , 180 ]1
2[ 0 , 180 ][ 0 , 90 )[ 90 , 180 ]1
3[ 90 , 180 ][90 , 135 )[ 135 , 180 ]0
4[ 90 , 135 )[ 90, 112.5 )[ 112.5 , 135 )1
5[ 112.5 , 135 )[ 112.5 , 123.75 )[ 123.75 , 135 )0
6[ 112.5 , 123.75 )[ 112.5 , 118.125 )[ 118.125 , 123.75)0
7[ 112.5 , 118.125 )[ 112.5 , 115.3125 )[ 115.3125 , 118.125)1
8[ 115.3125 , 118.125)[ 115.3125 , 116.71875 )[ 116.71875 , 118.125 )1
9[ 116.71875 , 118.125 )[ 116.71875 , 117.421875 )[ 117.421875 , 118.125 )0
10[ 116.71875 , 117.421875 )[ 116.71875 ,117.0703125 )[ 117.0703125, 117.421875 )1

​ 经过10次递归,经度为117.15838得到的数字字符串为1101001101,以同样的方式对纬度做GeoHash运算,表1-2列出了纬度 36.74038经过十次递归运算过程及结果。

表1-2 GeoHash纬度 36.74038

次数经度范围左区间 - 0右区间 - 136.74038
1[ -90, 90][ -90 , 0 )[ 0 , 90]1
2[ 0 , 90][ 0 , 45)[ 45, 90]0
3[ 0 , 45)[0, 22.5)[ 22.5, 45 )1
4[ 22.5, 45)[ 22.5, 33.75 )[ 33.75 , 45)1
5[ 33.75 , 45)[ 33.75, 39.375 )[ 39.375 , 45 )0
6[ 33.75, 39.375 )[ 33.75, 36.5625 )[ 36.5625 , 39.375)1
7[ 36.5625 , 39.375)[ 36.5625 , 37.96875)[ 37.96875 , 39.375)0
8[ 36.5625 , 37.96875)[ 36.5625 , 37.265625 )[ 37.265625 , 37.96875 )0
9[ 36.5625 , 37.265625 )[ 36.5625, 36.9140625 )[ 36.9140625 , 37.265625 )0
10[ 36.5625, 36.9140625 )[ 36.5625 ,36.7385625 )[ 36.7385625 , 36.9140625 )1

同样经过十次递归,纬度得到的数字串为1011010001 ,下面按偶数位经度,奇数位纬度的方法合并两个数字串,注意位数是从0开始,或者理解为先经度后纬度,各区一位交叉合并。

经度:1101001101

纬度:1011010001

合并:11100 11100 01101 00011

合并后结果按照每五位一组,一次转换成十进制数 28、28、13、3,并使用表1-3对应的Base32编码转为字符串。

表 1- 3
在这里插入图片描述

​ 最终结果为wwe34,可以到 http://geohash.org/ 网站上输入"36.74038,117.15838" 验证结果为:wwe3402hhp5z 这个结果为12位,说明做了30次递归。

表1-4列出了GeoHash字符串长度与实际位置误差关系。

表 1- 4 GeoHash字符串长度与实际位置关系

GeoHash长度纬度位数经度位数纬度误差经度误差区域面积
123±23±235009.4km*4992.6km
255±2.8±5.61252.3km*624.1km
378±0.70±0.70156.5km*156km
41010±0.087±0.1839.1km*19.5km
51213±0.022±0.0224.9km*4.9km
61515±0.0027±0.00551.2km*609.4m
71718±0.00068±0.00068152.9m*152.4m
82020±0.000085±0.0001738.2m*19m
92223±0.000021±0.0000214.8m*4.8m
102525±0.00000268±0.000005361.2m*59.5cm
112728±0.00000067±0.000000674.9cm*14.9cm
123030±0.00000008±0.000000173.7cm*1.9cm

​ 根据图1-4表示,当GeoHash字符串长度达到12位时,位置经度误差可以控制在不到8cm²的范围内。

2、地理类型字段

​ Elasticsearch 提供了两种地理相关的数据类型geo_pointgeo_shape,前者用于保存地理位置,即具体的某一个坐标;而后者用于保存地理形状,如矩形和多边形。

1. geo_point 类型

​ 地理位置由经度和维度共同定义,所以geo_point定义地理位置坐标最基本的形式也是通过提供经度和纬度来实现的。

如下:存储了数据的日期、主键、地理位置信息

PUT /obd
{"mapping":{"properties":{"datadate": {  //数据日期"type": "date"},"id": {   //数据主键"type": "long"},"location": {  //地理位置信息"type": "geo_point"},"name": {  //名称(编号)"type": "text"}}}
}

​ 如上,location的数据类型为geo_point,这种类型有四种表示形式

​ 例如:

# 格式1 对象
PUT /obd/_doc/1
{"location": { "lat": 41.12,"lon": -71.34}
}
# 格式2 数组
PUT /obd/_doc/2
{"location": [ -71.34, 41.12 ] 
}
# 格式3 字符串
PUT /obd/_doc/3
{"location": "41.12,-71.34" 
}
# 格式4 geohash
PUT /obd/_doc/4
{"location": "wwe3402hhp5z" 
}

2、基于geo_point类型的查询(java)

  • 按距离搜索

  • 按距离排序

  • 按时间范围

maven依赖

   <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent from repository --></parent>
<dependencies><!--必备: spring boot web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--es--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><!--测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>mssql-jdbc</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--mybatis--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version></dependency><!-- druid 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.5</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 动态数据源 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.5.4</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency></dependencies

配置文件yml

spring:elasticsearch:rest:uris: 192.168.254.190:9200,192.168.254.191:9200,192.168.254.192:9200datasource:druid:stat-view-servlet:# 默认true 内置监控页面首页/druid/index.htmlenabled: falseinitial-size: 20max-active: 60min-idle: 20max-wait: 30000dynamic:primary: masterstrict: falsedatasource:master: ***driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: ***url: jdc:url: ***driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriverusername: sapassword: ***

数据库实体

@Data
@EqualsAndHashCode()
@TableName("carPosition")
public class CarPosition {@TableId(value = "id")private Long id;@TableField("vehicleIdentificationNumber")private String vehicleIdentificationNumber;@TableField("collectionTime")private LocalDateTime collectionTime;/*** 经度*/private String longitude;/*** 纬度*/private String latitude;}

es实体

@Data
@FieldNameConstants
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "#{@dynamicIndex.getIndex()}", createIndex = false)
public class ObdModel implements Serializable {@Idprivate Long id;@Field(type = FieldType.Text)private String name;@GeoPointFieldprivate GeoPoint location;@Field(type = FieldType.Date, format = DateFormat.custom, pattern ="yyyy-MM-dd HH:mm:ss:SSS")private LocalDateTime datadate;
}

将数据库数据存储到es


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import com.sunfeng.elasticsearch.entity.CarPosition;
import com.sunfeng.elasticsearch.es.model.ObdModel;
import com.sunfeng.elasticsearch.es.repository.ObdModelRepository;
import com.sunfeng.elasticsearch.es.utils.DynamicIndex;
import com.sunfeng.elasticsearch.service.CarPositionService;import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.common.geo.GeoPoint;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;import javax.annotation.Resource;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.yyyy_MM_dd_HH_mm_ss;@Slf4j
@SpringBootTest
class ElasticsearchSpringdataApplicationTests {@Resourceprivate ObdModelRepository obdModelRepository;@Resourceprivate DynamicIndex dynamicIndex;@Resourceprivate ElasticsearchRestTemplate restTemplate;@Resourceprivate CarPositionService carPositionService;@Testpublic void createIndex() {//生成索引名称String obdIndex = "obd2";Document mapping = restTemplate.indexOps(IndexCoordinates.of(obdIndex)).createMapping(ObdModel.class);//判断索引库中是否存在该索引if (!restTemplate.indexOps(IndexCoordinates.of(obdIndex)).exists()) {restTemplate.indexOps(IndexCoordinates.of(obdIndex)).create();//创建映射restTemplate.indexOps(IndexCoordinates.of(obdIndex)).putMapping(mapping);}}@Testpublic void contextLoads() {dynamicIndex.setIndex("obd");Iterable<ObdModel> all = obdModelRepository.findAll();all.forEach(System.out::println);dynamicIndex.setIndex("");}//纬度正则private static String latReg = "^[\\-\\+]?((0|([1-8]\\d?))(\\.\\d{1,6})?|90(\\.0{1,6})?)$";//经度正则private static String lonReg = "^[\\-\\+]?(0(\\.\\d{1,6})?|([1-9](\\d)?)(\\.\\d{1,6})?|1[0-7]\\d{1}(\\.\\d{1,6})?|180(\\.0{1,6})?)$";public static void main(String[] args) {System.out.println(LocalDateTime.parse("2023-08-04 19:00:00", yyyy_MM_dd_HH_mm_ss).toInstant(ZoneOffset.of("+8")).toEpochMilli());}@Testpublic void dbToEs() {log.info("开始统计!!");LambdaQueryWrapper<CarPosition> lambdaQueryWrapper = new LambdaQueryWrapper<CarPosition>();dynamicIndex.setIndex("obd202308");List<CarPosition> carPositionList = carPositionService.list(lambdaQueryWrapper);/*** 获取分页数据*/log.info("需要处理的数据量为:{}", carPositionList.size());carPositionList = carPositionList.parallelStream().filter(carPosition -> ObjectUtil.isNotEmpty(carPosition.getLatitude()) &&ObjectUtil.isNotEmpty(carPosition.getLongitude()) &&ReUtil.isMatch(latReg, carPosition.getLatitude()) &&ReUtil.isMatch(lonReg, carPosition.getLongitude())).collect(Collectors.toList());log.info("排除部分脏数据后为:{}", carPositionList.size());ArrayList<ObdModel> obdModels = new ArrayList<>();//批量保存提高效率for (int i = 0; i < carPositionList.size(); i++) {CarPosition carPosition = carPositionList.get(i);ObdModel obdModel = new ObdModel();obdModel.setId(carPosition.getId());obdModel.setName(carPosition.getVehicleIdentificationNumber());obdModel.setDatadate(carPosition.getCollectionTime());GeoPoint geoPoint = new GeoPoint(Double.parseDouble(carPosition.getLatitude()), Double.parseDouble(carPosition.getLongitude()));obdModel.setLocation(geoPoint);obdModels.add(obdModel);if (obdModels.size() % 10000 == 0) {log.info("开始保存");obdModelRepository.saveAll(obdModels);log.info("结束保存");obdModels.clear();}}obdModelRepository.saveAll(obdModels);}}

es数据查询

package com.sunfeng.elasticsearch;import com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.getDateTimeOfTimestamp;
import static com.sunfeng.elasticsearch.es.utils.DateTimeFormatterUtil.yyyy_MM_dd_HH_mm_ss;@Slf4j
@SpringBootTest
public class TestSearchDocument {@Resourceprivate RestHighLevelClient restHighLevelClient;@Testpublic void contextLoads() throws IOException {//创建查询请求SearchRequest searchRequest = new SearchRequest();searchRequest.indices("obd202308");GeoPoint geoPoint = new GeoPoint(36.508270D, 117.848530D);//条件1、设置搜索半径GeoDistanceQueryBuilder distanceQueryBuilder = QueryBuilders.geoDistanceQuery("location").point(geoPoint).distance(10000, DistanceUnit.METERS).geoDistance(GeoDistance.ARC); //设置查询精度//条件3、设置搜索区间 时间区间//注意: 时间格式要用 yyyy-MM-dd HH:mm:ss:SSSRangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("datadate").gt("2023-08-04 19:00:00:000").lte("2023-08-04 20:00:00:000");// 组合查询条件BoolQueryBuilder must = QueryBuilders.boolQuery().must(rangeQueryBuilder).must(distanceQueryBuilder);//条件2:按照距离排序//构建GeoDistanceSortBuilder设置按距离排序参数GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location", geoPoint);//升序排序sort.order(SortOrder.ASC);//构建检索SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource().from(0).size(10000).query(must).sort(sort);// 设置SearchRequest搜索参数searchRequest.source(sourceBuilder);log.info("开始搜索");// 执行ES请求SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);log.info("结束搜索");SearchHits hits = searchResponse.getHits();log.info("检索结果数量为:{}", "" + hits.getHits().length);//结果打印hits.forEach(hit -> {Map<String, Object> sourceAsMap = hit.getSourceAsMap();// 获取坐标Object location = sourceAsMap.get("location");String datadate = sourceAsMap.get("datadate").toString();Long id = Long.valueOf(sourceAsMap.get("id").toString());//获取距离值,并保留两位小数点BigDecimal geoDis = BigDecimal.valueOf((Double) hit.getSortValues()[0]);System.out.println("获取坐标:" + location + ",时间:" + datadate + ",距离:" + geoDis + ",id:" + id);});}
}
2023-08-20 23:16:51.745  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 开始搜索
2023-08-20 23:16:52.705  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 结束搜索
2023-08-20 23:16:52.706  INFO 8624 --- [           main] c.s.elasticsearch.TestSearchDocument     : 检索结果数量为:1401

索引数据规模大概1124W,搜索大概只需1秒左右 还可以进一步优化
在这里插入图片描述

相关文章:

Elasticsearch 处理地理信息

1、GeoHash ​ GeoHash是一种地理坐标编码系统&#xff0c;可以将地理位置按照一定的规则转换为字符串&#xff0c;以方便对地理位置信息建立空间索引。首先要明确的是&#xff0c;GeoHash代表的不是一个点而是一个区域。GeoHash具有两个显著的特点&#xff1a;一是通过改变 G…...

ARM开发,stm32mp157a-A7核IIC实验(采集温湿度传感器值)

1.实验目标&#xff1a;采集温湿度传感器值&#xff1b; 2.分析框图&#xff08;模拟IIC控制器&#xff09;&#xff1b; 3.代码&#xff1b; ---iic.h封装时序协议头文件--- #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "st…...

021-从零搭建微服务-短信服务(一)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…...

基于jenkins自动化部署PHP环境

实验环境 操作系统 IP地址 主机名 角色 CentOS7.5 192.168.147.141 git git服务器 CentOS7.5 192.168.147.142 Jenkins git客户端 jenkins服务器 CentOS7.5 192.168.147.143 web web服务器 具体环境配置见上一篇&#xff01; 准备git仓库 [rootgit ~]# su -…...

数据库表结构导出为word、html、markdown【转载,已解决,已验证,开源】

注&#xff1a;本文为gitcode代码验证&#xff0c;转载gitcode gitcode&#xff1a;https://gitcode.net/mirrors/pingfangushi/screw?utm_sourcecsdn_github_accelerator 整理数据库文档&#xff1a;https://mp.weixin.qq.com/s/Bo_U5_cl82hfQ6GmRs2vtA <!--数据库文档核…...

【计算机视觉|生成对抗】用于高保真自然图像合成的大规模GAN训练用于高保真自然图像合成的大规模GAN训练(BigGAN)

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Large Scale GAN Training for High Fidelity Natural Image Synthesis 链接&#xff1a;[1809.11096] Large Scale GAN Training for High Fidelity Natural Image Synthesis (arxiv.org…...

三维重建_体素重建_空间雕刻法/体素着色法

目录 1. 三角化和体素重建的区别 2. 空间雕刻法 空间雕刻法的一致性定义 空间雕刻法具体实现 基于八叉树的空间雕刻法具体实现​编辑 空间雕刻法效果展示 3. 体素着色法 体素着色法的缺点&#xff1a;不唯一性​编辑 体素着色法不唯一性解决措施​编辑 体素着色发实验环境与…...

4-redis哨兵搭建安装

1.先决条件 1.1.OS基础配置 CentOS为了能够正常安装redis,需要对CentOS进行常规的一些基础配置,主要有:关闭防火墙与selinux,设置主机名,配置虚拟机IP地址使其能够与外网ping通,配置IP地址与主机名映射,配置yum源。具体配置参见: Linux常规基础配置_小黑要上天的博客…...

架构评估-架构师之路(十二)

软件系统质量属性 软件系统质量熟悉分为 开发期质量属性 和 运行期质量属性。 质量属性 性能&#xff1a;指 系统的响应能力&#xff0c;如 响应时间&#xff0c;吞吐率。 设计策略&#xff1a;优先级队列、增加计算资源、减少计算开销、引入并发机制、采用资源调度。 可靠…...

手写模拟SpringBoot核心流程(二):实现Tomcat和Jetty的切换

实现Tomcat和Jetty的切换 前言 上一篇文章我们聊到&#xff0c;SpringBoot中内置了web服务器&#xff0c;包括Tomcat、Jetty&#xff0c;并且实现了SpringBoot启动Tomcat的流程。 那么SpringBoot怎样自动切换成Jetty服务器呢&#xff1f; 接下来我们继续学习如何实现Tomcat…...

Python土力学与基础工程计算.PDF-土的三项组成

5.3 Python求解 Python 求解代码如下&#xff1a; 1. # 定义已知参数 2. G_s 2.7 # 比重 3. w 0.2 # 含水量 4. e 0.6 # 孔隙比 5. gamma_w 9.81 # 水的重度 6. 7. # 根据公式计算饱和度 8. S_r G_s * w / e 9. print("饱和度为", S_r) 10. 11.…...

危化安全生产信息化平台在煤化领域的应用

一、背景介绍 煤化工行业是一个集煤炭、石油、化工等多种产业于一体的综合性行业&#xff0c;其特点是工艺流程复杂、设备繁多、安全隐患大。近年来&#xff0c;随着煤化工行业的快速发展&#xff0c;安全生产问题日益凸显。为了有效提高危化安全生产水平&#xff0c;某煤化工…...

Linux(CentOS)运维脚本工具集合

使用说明 备份指定目录 # 备份指定目录文件到指定目录,备份文件名称为&#xff1a;备份目录最后一层目录"_"日期.tar.gz # 第一个参数&#xff1a;backdir 第二参数&#xff1a;备份文件保存目录 第三个参数&#xff1a;备份目录/文件 sh script.sh backdir /root/…...

【Java alibabahutool】JSON、Map、实体对象间的相互转换

首先要知道三者的互转关系&#xff0c;可以先将JSON理解成是String类型。这篇博文主要是记录阿里巴巴的JSONObject的两个方法。toJSONString()以及parseObject()方法。顺便巩固Map与实体对象的转换技巧。 引入依赖 <!-- 阿里巴巴 JSON转换 以下二选一即可 没有去细研究两者…...

按软件开发阶段的角度划分:单元测试、集成测试、系统测试、验收测试

1.单元测试&#xff08;Unit Testing&#xff09; 单元测试&#xff0c;又称模块测试。对软件的组成单位进行测试&#xff0c;其目的是检验软件基本组成单位的正确性。测试的对象是软件里测试的最小单位&#xff1a;模块。 测试阶段&#xff1a;编码后或者编码前&#xff08;…...

【python】Leetcode(primer-dict-list)

文章目录 260. 只出现一次的数字 III&#xff08;字典 / 位运算&#xff09;136. 只出现一次的数字&#xff08;字典&#xff09;137. 只出现一次的数字 II&#xff08;字典&#xff09;169. 求众数&#xff08;字典&#xff09;229. 求众数 II&#xff08;字典&#xff09;200…...

网络安全(黑客)入门

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…...

在CSS中,盒模型中的padding、border、margin是什么意思?

在CSS中&#xff0c;盒模型&#xff08;Box Model&#xff09;是用来描述和布局HTML元素的基本概念。它将每个HTML元素看作是一个矩形的盒子&#xff0c;这个盒子包括了内容&#xff08;content&#xff09;、内边距&#xff08;padding&#xff09;、边框&#xff08;border&a…...

有线耳机插入电脑没声音

有线耳机插入电脑没声音 首先确保耳机和电脑都没问题&#xff0c;那就有可能是声音输出设备设置错误 右击任务栏的声音图标-打开声音设置-选择输出设备。...

【面试 反思】Retrofit源码与设计 7 连问

前言 在实际项目中往往是使用Retrofit来做网络请求工作。Retrofit采用RESTful风格&#xff0c;本质上只是对OkHttp进行封装&#xff0c;今天我们根据几个问题来进一步学习一下Retrofit的源码与设计思想。 1. 使用方法 直接看一下官方介绍的使用方法。 public final class S…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...