第18天-商城业务(商品检索服务,基于Elastic Search完成商品检索)
1.构建商品检索页面
1.1.引入依赖
<!-- thymeleaf模板引擎 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 热更新 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency>
1.2.模板页面
- 将 index.html 拷贝到 templates 目录
- 修改 index.html 为 list.html
1.3.静态资源
1)在nginx\html\static\ 文件下创建 search 文件夹,并将所有静态资源文件上传到 search\ 文件夹
2)修改list.html模板,将所有静态资源链接URL加上前置路径 /static/search/
1.4.域名访问配置
本地映射
192.168.139.10 search.gmall.com
Nginx配置 gmall.conf
server {listen 80;server_name *.gmall.com gmall.com;location /static/ {root /usr/share/nginx/html;}location / {proxy_pass http://gmall;proxy_set_header Host $host;}
}
网关路由配置
- id: gmall_host_routeuri: lb://gmall-productpredicates:- Host=gmall.com- id: gmall_search_routeuri: lb://gmall-searchpredicates:- Host=search.gmall.com
1.5.页面跳转后台接口
SearchController
package com.atguigu.gmall.search.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/*** 商品检索 {@link SearchController}** @author zhangwen* @email: 1466787185@qq.com*/
@Controller
public class SearchController {/*** 商品检索页面* @return*/@GetMapping("/list.html")public String listPage() {return "list";}
}
2.商品检索业务分析
2.1.检索业务分析
2.1.1.商品检索三个入口
输入检索关键字展示检索页
选择分类进入商品检索
选择筛选条件进入(复杂)
根据检索关键字进入检索页面
点击三级分类进入检索页面
2.1.2.检索条件分析
- 全文检索:skuTitle(keyword)
- 排序:saleCount(销量)、hotScore(热度评分/综合排序)、skuPrice(价格)
- 过滤:hasStock(仅显示有货)、skuPrice区间、brandId、catalogId、attrs
- 聚合:attrs
完整查询参数
search.gmall.com/list.html?keyword=华为&sort=saleCount_desc
&hasStock=1&skuPrice=1000_5000&brandId=1&catalog3Id=1&attrs=1
_3G:4G:5G&attrs=2_骁龙845&attrs=3_高清屏
2.2.检索条件和检索结果封装
2.2.1.SearchParamVO
package com.atguigu.gmall.search.vo;import lombok.Data;
import java.util.List;/*** 商品检索条件 {@link SearchParamVO}* ?keyword=华为&sort=saleCount_desc&hasStock=1&skuPrice=1000_5000&brandId=1&catalog3Id=225* &attrs=1_3G:4G:5G&attrs=2_骁龙845&attrs=3_高清屏* @author zhangwen* @email: 1466787185@qq.com*/
@Data
public class SearchParamVO {{// 页码默认值pageNum = 1;}/*** 检索输入框传递过来的检索关键字*/private String keyword;/*** 三级分类id*/private Long catalog3Id;/*** 排序条件,三选一* 销量排序:sort=saleCount_desc/asc* 综合排序:sort=hasStock_desc/asc* 价格排序:sort=skuPrice_desc/asc*/private String sort;/*** 过滤条件* hasStock(仅显示有货)、skuPrice区间(价格区间)、brandId(品牌id)、catalogId(分类id)、attrs(商品属性)* hasStock=0/1* skuPrice=100_500/_500/100_* brandId=1&brandId=2* attrs=1_3G:4G:5G&attrs=2_骁龙845&attrs=3_高清屏*/private Integer hasStock;private String skuPrice;private List<Long> brandId;private List<String> attrs;/*** 当前页码*/private Integer pageNum;/*** 所有查询条件*/private String queryString;
}
2.2.2.SearchResponseVO
package com.atguigua.gmall.search.vo;import com.atguigua.common.to.es.SkuEsModel;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;/*** 商品检索结果 {@link SearchResponseVO}** @author zhangwen* @email: 1466787185@qq.com*/
@Data
public class SearchResponseVO {{navs = new ArrayList<>();attrIds = new ArrayList<>();}/*** 检索到的所有商品信息*/private List<SkuEsModel> products;/*** 当前页面*/private Integer pageNum;/*** 总记录数*/private Long totalCount;/*** 总页码*/private Integer totalPage;/*** 导航页*/private List<Integer> pageNavs;/*** 检索到的结果所涉及的所有品牌*/private List<BrandVO> brands;/*** 检索结果涉及的所有分类*/private List<CatalogVO> catalogs;/*** 检索结果涉及的商品属性*/private List<AttrVO> attrs;/*** 面包屑导航*/private List<NavVO> navs;private List<Long> attrIds;@Datapublic static class NavVO {private String navName;private String navValue;private String link;}@Datapublic static class BrandVO {private Long brandId;private String brandName;private String brandImg;}@Datapublic static class CatalogVO {private Long catalogId;private String catalogName;}@Datapublic static class AttrVO {private Long attrId;private String attrName;private List<String> attrValues;}
}
2.3.ElasticSearch数据迁移
2.3.1.创建新的索引及映射
PUT gmall_product
{"mappings": {"properties": {"attrs": {"type": "nested","properties": {"attrId": {"type": "long"},"attrName": {"type": "keyword","index": false,"doc_values": true},"attrValue": {"type": "keyword"}}},"brandId": {"type": "long"},"brandImg": {"type": "keyword","index": false,"doc_values": true},"brandName": {"type": "keyword","index": false,"doc_values": true},"catalogId": {"type": "long"},"catalogName": {"type": "keyword","index": false,"doc_values": true},"hasScore": {"type": "long"},"hasStock": {"type": "boolean"},"hotScore": {"type": "long"},"saleCount": {"type": "long"},"skuId": {"type": "long"},"skuImg": {"type": "keyword","index": false,"doc_values": true},"skuPrice": {"type": "keyword"},"skuTitle": {"type": "text","analyzer": "ik_smart"},"spuId": {"type": "keyword"}}}
}
2.3.2.迁移数据
POST _reindex
{"source": {"index": "product"},"dest": {"index": "gmall_product"}
}
2.3.3.修改检索服务索引名
package com.atguigu.gmall.search.constant;
/*** ES常量类 {@link EsConstant}** @author zhangwen* @email: 1466787185@qq.com*/
public class EsConstant {/*** sku数据在es中的索引*/public static final String PRODUCT_INDEX = "gmall_product";
}
2.4.分析ES检索DSL
#模糊匹配 must
#过滤 filter
#排序 sort
#分页 from size
#高亮 highlight
#聚合分析 aggs
#如果是嵌入式属性,查询、聚合分析都需要用嵌入式GET gmall_product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}],"filter": [{"term": {"catalogId": "225"}},{"terms": {"brandId": ["4"]}},{"nested": {"path": "attrs","query": {"bool": {"must": [{"term": {"attrs.attrId": {"value": "8"}}},{"terms": {"attrs.attrValue": ["LIO-AN00","158.1"]}}]}}}},{"term": {"hasStock": true}},{"range": {"skuPrice": {"gte": 0,"lte": 6000}}}]}},"sort": [{"skuPrice": {"order": "desc"}}],"from": 0,"size": 5,"highlight": {"fields": {"skuTitle": {}},"pre_tags": "<b style='color:red'>","post_tags": "</b>"},"aggs": {"brand_agg": {"terms": {"field": "brandId","size": 10},"aggs": {"brand_name_agg": {"terms": {"field": "brandName","size": 10}},"brand_img_agg": {"terms": {"field": "brandImg","size": 10}}}},"catalog_agg": {"terms": {"field": "catalogId","size": 10},"aggs": {"catalog_name_agg": {"terms": {"field": "catalogName","size": 10}}}},"attr_agg": {"nested": {"path": "attrs"},"aggs": {"attr_id_agg": {"terms": {"field": "attrs.attrId","size": 10},"aggs": {"attr_name_agg": {"terms": {"field": "attrs.attrName","size": 10}},"attr_value_agg": {"terms": {"field": "attrs.attrValue","size": 10}}}}}}}
}
3.商品检索业务实现
3.1.检索接口实现
3.1.1.检索接口
/*** 商品检索* @param searchParamVO 检索的所有参数* @return*/
@Override
public SearchResponseVO search(SearchParamVO searchParamVO) {SearchResponseVO searchResponseVO = null;//1.准备检索请求SearchRequest searchRequest = buildSearchRequest(searchParamVO);try {//2.执行检索请求SearchResponse searchResponse = restHighLevelClient.search(searchRequest,ElasticSearchConfig.COMMON_OPTIONS);//3.分析检索结果,封装成SearchResponseVOsearchResponseVO = buildSearchResponse(searchResponse, searchParamVO);} catch (IOException e) {e.printStackTrace();}return searchResponseVO;
}
3.1.1.构建检索查询SearchRequest
/*** 准备检索请求* 模糊匹配 must* 过滤 filter* 排序 sort* 分页 from size* 高亮 highlight* 聚合分析 aggs* @return*/
private SearchRequest buildSearchRequest(SearchParamVO param) {// 动态构建检索的DSL语句SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 查询:模糊匹配、过滤(品牌、分类、属性、价格区间、库存)BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 按照商品名称模糊查询if (!StringUtils.isEmpty(param.getKeyword())) {boolQuery.must(QueryBuilders.matchQuery("skuTitle", param.getKeyword()));}// 按照三级分类id查询if (param.getCatalog3Id() != null) {boolQuery.filter(QueryBuilders.termQuery("catalogId", param.getCatalog3Id()));}// 按照品牌id查询if (param.getBrandId() != null && param.getBrandId().size() > 0) {boolQuery.filter(QueryBuilders.termsQuery("brandId", param.getBrandId()));}// 按照所有指定的属性进行查询// attr=1_3G:4G:5G&attr=2_高通骁龙845if (param.getAttrs() != null && param.getAttrs().size() > 0) {for (String attr : param.getAttrs()) {String[] s = attr.split("_");String attrId = s[0];String[] attrValues = s[1].split(":");BoolQueryBuilder query = QueryBuilders.boolQuery();query.must(QueryBuilders.termQuery("attrs.attrId", attrId));query.must(QueryBuilders.termsQuery("attrs.attrValue", attrValues));// 每一个属性都必须生成一个 NestedQueryNestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", query, ScoreMode.None);boolQuery.filter(nestedQuery);}}// 按照是否有库存进行查询if (param.getHasStock() != null) {boolQuery.filter(QueryBuilders.termQuery("hasStock", param.getHasStock() == 1));}// 按照价格区间进行查询:1_100/_100/100_if (!StringUtils.isEmpty(param.getSkuPrice())) {RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");String[] price = param.getSkuPrice().split("_", 2);if (StringUtils.isEmpty(price[0])) {rangeQuery.lte(price[1]);} else if (StringUtils.isEmpty(price[1])) {rangeQuery.gte(price[0]);} else {rangeQuery.gte(price[0]).lte(price[1]);}boolQuery.filter(rangeQuery);}searchSourceBuilder.query(boolQuery);// 排序// sort=saleCount_descif (!StringUtils.isEmpty(param.getSort())) {String[] s = param.getSort().split("_");SortOrder sortOrder = s[1].equalsIgnoreCase("asc") ? SortOrder.ASC : SortOrder.DESC;if ("price".equals(s[0])) {searchSourceBuilder.sort("skuPrice", sortOrder);} else {searchSourceBuilder.sort(s[0], sortOrder);}}// 分页// from = (pageNum - 1) * pageSizesearchSourceBuilder.from((param.getPageNum() - 1) * EsConstant.PRODUCT_PAGE_SIZE);searchSourceBuilder.size(EsConstant.PRODUCT_PAGE_SIZE);// 高亮if (!StringUtils.isEmpty(param.getKeyword())) {HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("skuTitle");highlightBuilder.preTags("<b style='color:red'>");highlightBuilder.postTags("</b>");searchSourceBuilder.highlighter(highlightBuilder);}// 聚合分析// 品牌聚合TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg").field("brandId").size(50);// 品牌子聚合brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));searchSourceBuilder.aggregation(brand_agg);// 分类聚合TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));searchSourceBuilder.aggregation(catalog_agg);// 属性聚合NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(1);attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));attr_agg.subAggregation(attr_id_agg);searchSourceBuilder.aggregation(attr_agg);System.out.println("构建DSL:" + searchSourceBuilder.toString());SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, searchSourceBuilder);return searchRequest;
}
3.1.2.分析检索结果SearchResponse
/*** 返回检索结果数据* @param searchResponse* @return*/
private SearchResponseVO buildSearchResponse(SearchResponse searchResponse, SearchParamVO param) {SearchResponseVO searchResponseVO = new SearchResponseVO();// 返回所有查询到的商品SearchHits hits = searchResponse.getHits();List<SkuEsModel> skuEsModels = new ArrayList<>();if (hits.getHits() != null && hits.getHits().length > 0) {for (SearchHit hit : hits.getHits()) {String sourceAsString = hit.getSourceAsString();SkuEsModel skuEsModel = JsonUtils.jsonToPojo(sourceAsString, SkuEsModel.class);// 设置关键字高亮if (!StringUtils.isEmpty(param.getKeyword())) {String skuTitle = hit.getHighlightFields().get("skuTitle").getFragments()[0].string();skuEsModel.setSkuTitle(skuTitle);}skuEsModels.add(skuEsModel);}}searchResponseVO.setProducts(skuEsModels);// 聚合分析:分类信息、品牌信息、属性信息// 分类信息List<SearchResponseVO.CatalogVO> catalogVOS = new ArrayList<>();ParsedLongTerms catalog_agg = searchResponse.getAggregations().get("catalog_agg");for (Terms.Bucket bucket : catalog_agg.getBuckets()) {SearchResponseVO.CatalogVO catalogVO = new SearchResponseVO.CatalogVO();// 分类IDcatalogVO.setCatalogId(Long.parseLong(bucket.getKeyAsString()));// 分类名ParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");String catalogName = catalog_name_agg.getBuckets().get(0).getKeyAsString();catalogVO.setCatalogName(catalogName);catalogVOS.add(catalogVO);}searchResponseVO.setCatalogs(catalogVOS);// 品牌信息List<SearchResponseVO.BrandVO> brandVOS = new ArrayList<>();ParsedLongTerms brand_agg = searchResponse.getAggregations().get("brand_agg");for (Terms.Bucket bucket : brand_agg.getBuckets()) {SearchResponseVO.BrandVO brandVO = new SearchResponseVO.BrandVO();// 品牌IDbrandVO.setBrandId(bucket.getKeyAsNumber().longValue());// 品牌名称ParsedStringTerms brand_name_agg = bucket.getAggregations().get("brand_name_agg");String brandName = brand_name_agg.getBuckets().get(0).getKeyAsString();brandVO.setBrandName(brandName);// 品牌图片ParsedStringTerms brand_img_agg = bucket.getAggregations().get("brand_img_agg");String brandImg = brand_img_agg.getBuckets().get(0).getKeyAsString();brandVO.setBrandImg(brandImg);brandVOS.add(brandVO);}searchResponseVO.setBrands(brandVOS);// 属性List<SearchResponseVO.AttrVO> attrVOS = new ArrayList<>();ParsedNested attr_agg = searchResponse.getAggregations().get("attr_agg");ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");for (Terms.Bucket bucket : attr_id_agg.getBuckets()) {SearchResponseVO.AttrVO attrVO = new SearchResponseVO.AttrVO();// 属性IDlong attrId = bucket.getKeyAsNumber().longValue();attrVO.setAttrId(attrId);// 属性名String attrName = ((ParsedStringTerms) bucket.getAggregations().get("attr_name_agg")).getBuckets().get(0).getKeyAsString();attrVO.setAttrName(attrName);// 属性所有值List<String> attrValues = ((ParsedStringTerms) bucket.getAggregations().get("attr_value_agg")).getBuckets().stream().map(item -> {String keyAsString = item.getKeyAsString();return keyAsString;}).collect(Collectors.toList());attrVO.setAttrValues(attrValues);attrVOS.add(attrVO);}searchResponseVO.setAttrs(attrVOS);// 分页信息// 当前页码searchResponseVO.setPageNum(param.getPageNum());// 总记录数long totalCount = hits.getTotalHits().value;searchResponseVO.setTotalCount(totalCount);// 总页数int totalPage = (int)totalCount % EsConstant.PRODUCT_PAGE_SIZE == 0? (int)totalCount / EsConstant.PRODUCT_PAGE_SIZE: (int)totalCount / EsConstant.PRODUCT_PAGE_SIZE + 1;searchResponseVO.setTotalPage(totalPage);// 页码导航数List<Integer> pageNavs = new ArrayList<>();for (int i = 1; i <= totalPage; i++) {pageNavs.add(i);}searchResponseVO.setPageNavs(pageNavs);// 构建面包屑导航// 面包屑-属性if (param.getAttrs() != null && param.getAttrs().size() > 0) {List<SearchResponseVO.NavVO> navs = param.getAttrs().stream().map(attr -> {SearchResponseVO.NavVO navVO = new SearchResponseVO.NavVO();String[] s = attr.split("_");searchResponseVO.getAttrIds().add(Long.parseLong(s[0]));navVO.setNavValue(s[1]);// 远程调用耗时,远程查询接口结果加入缓存R r = productFeignService.getAttrInfo(Long.parseLong(s[0]));if (r.getCode() == 0) {AttrResponseVO data = r.getData("attr", new TypeReference<AttrResponseVO>() {});navVO.setNavName(data.getAttrName());} else {log.error("调用远程服务 gmall-product 查询属性信息失败");navVO.setNavName("");}// 取消面包屑以后,需要将请求url里面的当前属性值置空String replace = replaceQueryString(param.getQueryString(), "attrs", attr);navVO.setLink("http://search.gmall.com/list.html?" + replace);return navVO;}).collect(Collectors.toList());searchResponseVO.setNavs(navs);}// 面包屑-品牌if (param.getBrandId() != null && param.getBrandId().size() > 0) {List<SearchResponseVO.NavVO> navs = searchResponseVO.getNavs();SearchResponseVO.NavVO navVO = new SearchResponseVO.NavVO();navVO.setNavName("品牌");// 远程调用耗时,远程查询接口结果加入缓存R r = productFeignService.getBrandInfos(param.getBrandId());if (r.getCode() == 0) {List<BrandResponseVO> brands = r.getData("brands", new TypeReference<List<BrandResponseVO>>() {});String replace = null;StringBuffer buffer = new StringBuffer();for (int i = 0; i < brands.size(); i++) {BrandResponseVO vo = brands.get(i);if (i == 0) {buffer.append(vo.getName());} else {buffer.append("、" + vo.getName());}replace = replaceQueryString(param.getQueryString(), "brandId", vo.getBrandId()+"");}navVO.setNavValue(buffer.toString());navVO.setLink("http://search.gmall.com/list.html?" + replace);} else {log.error("调用远程服务 gmall-product 查询品牌信息失败");}navs.add(navVO);}// TODO:面包屑-分类return searchResponseVO;
}
3.2.检索模板页面实现
3.2.1.模板页面数据渲染
- 商品列表渲染
- 商品筛选条件渲染
- 商品列表分页数据渲染
3.2.2.商品检索页面功能
-
商品筛选条件过滤
-
关键字检索
-
商品价格区间过滤
-
商品排序
1、综合排序
2、按销量排序
3、 按价格排序 -
分页跳转处理
-
面包屑导航
相关文章:
第18天-商城业务(商品检索服务,基于Elastic Search完成商品检索)
1.构建商品检索页面 1.1.引入依赖 <!-- thymeleaf模板引擎 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 热更新 --><…...
5.2 对射式红外传感器旋转编码器计次
对射式红外传感器1.1 接线图VCC GND分别接电源的正负极DO数字输出端,随意选择一个GPIO口1.2 硬件原理当挡光片或者编码盘在对射式红外传感器中间经过时,DO就会输出电平变化信号,电平跳变信号触发STM32 PB14号口中断,在中断函数中执…...
【数据库概论】第九章 关系查询处理和查询优化
第九章 关系查询处理和查询优化 本章主要介绍关系数据库查询管理和查询优化,主要分为代数优化(又称逻辑优化)和物理优化(也称非代数优化)。 9.1 关系型数据库系统的查询处理 查询处理是关系型数据库管理系统执行查询…...
(WIP) my cloud test bed (by quqi99)
作者:张华 发表于:2023-03-10 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 想创建一个local local test bed, 用来方便做各种云实验,如openstack, k8s, ovn, lxd等…...
git | git 2023 详细版
文章目录一、Git命令1.2 设计用户签名1.3 初始化本地库1.4 查看本地库状态1.5 添加至暂存区1.6 从暂存区删除1.7 将暂存区的文件提交到本地库1.8 查看版本信息二、Git分支2.1 查看分支2.2 创建分支2.3 切换分支2.4 合并分支三、GitHub3.1 代码克隆clone3.2 给库取别名3.3 推送本…...
camunda流程引擎基本使用(笔记)
文章目录一、camunda基础1.1 安装与部署流程引擎1.2 流程引擎结构1.3 流程引擎的基本使用1.3.1 创建一个BPMN Diagram1.3.2 实现一个外部工作者1.3.3 部署流程1.3.4 创建一个流程实例并消费1.3.5 向流程中添加用户任务1.3.6 添加网关1.3.7 业务规则二、Java 集成流程引擎2.1 为…...
JS之数据结构与算法
前言数据结构是计算机存储、组织数据的方式,算法是系统描述解决问题的策略。了解基本的数据结构和算法可以提高代码的性能和质量。也是程序猿进阶的一个重要技能。手撸代码实现栈,队列,链表,字典,二叉树,动态规划和贪心算法1.数据结构篇1.1 栈栈的特点:先进后出clas…...
CnOpenData·A股上市企业数字化转型指数数据
一、数据简介 企业数字化转型是近年来中国社会各界重点关注的领域,但基础数据的不完善在很大程度上制约了相关科学研究的开展。构建合理、科学的数字化转型指标体系有利于学者定量地研究企业数字化的相关问题,也有利于衡量企业的数字化水平。广东金融学院…...
VMware16pro虚拟机安装全过程
很多时候需要用到Linux系统,简单的一种方式可以是:Windows系统运行Linux(Windows Subsystem for Linux)不过有些时候还是需要虚拟机来运行Linux,也更方便点,比如在做嵌入式系统的烧录等操作都需要Linux环境…...
阿里云第六代云服务器最新价格表(计算型c6、通用型g6和内存型r6)
目前阿里云第六代云服务器有计算型c6、通用型g6和内存型r6实例。计算型c6实例有2核4G、4核8G、8核16G配置可选,主要适用于网站应用、批量计算、视频编码等场景。通用型g6实例有2核8G、4核16G、8核32G配置可选,适用于各种类型的企业级应用,网站…...
微小目标识别研究(2)——基于K近邻的白酒杂质检测算法实现
文章目录实现思路配置opencv位置剪裁实现代码自适应中值滤波实现代码动态范围增强实现代码形态学处理实现代码图片预处理效果计算帧差连续帧帧差法原理和实现代码实现代码K近邻实现基本介绍实现代码这部分是手动实现的,并没有直接调用相关的库完整的代码——调用ope…...
2022-06-14至2022-08-11 关于复现MKP算法的总结与反思
Prerequisite 自2022年6月14日至2022年8月11日的时间内,我致力于完成A Hybrid Approach for the 0–1 Multidimensional Knapsack problem 论文的复现工作,此次是我第一次进行组合优化方向的学习工作,下面介绍该工作内容发展过程以及该工作结…...
IBMMQ教程二(window版安装)
下载下载地址:https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/我这里选择的是9.1.0.0版本安装将下载完成的压缩包解压双击Setup.exe直接运行点击软件需求查看系统配置是否满足,右边绿色的对号说明满足需求,…...
Java | HashSet 语法
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。 HashSet 允许有 null 值。 HashSet 是无序的,即不会记录插入的顺序。 HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须…...
js学习4(运算符)
### 1.算数运算符: 、-、*、\、%(取余)、**(幂方) ## 优先级 同数学课程,可以加括号 ### 2.自增和自减 、--(即数值变量加一或减一) ### 3.赋值运算符 、、-、*、/、... ### 4.比较运…...
2月更新 | Visual Studio Code Python
我们很高兴地宣布,2023年2月版 Visual Studio Code Python 和 Jupyter 扩展现已推出!此版本包括以下改进:从激活的终端启动 VS Code 时的自动选择环境 使用命令 Python: Create Environmen 时可选择需求文件或可选依赖项 预发布:改…...
C++回顾(十八)—— 文件操作
18.1 I/O流概念和流类库结构 1 概念 程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。 C输入输出包含以下三个方面的内容: (1)对系统指定的标准设备的输入和输出。即从键盘输入数据&am…...
以java编写员工管理系统(测试过 无问题)
一、系统结果的部分展示 二、题目以及相关要求 三、组成 1.该系统由 Employee 类 、commonEmployee类、Testemd类和managerEmployee类组成 2.Employee实现的代码 public class Employee {private String id;private String name;private String job;private int holiday…...
单例模式之懒汉式
在上篇文章中,我们讲了单例模式中的饿汉式,今天接着来讲懒汉式。 1.懒汉式单例模式的实现 public class LazySingleton {private static LazySingleton instance null;// 让构造函数为private,这样该类就不会被实例化private LazySingleto…...
1638_chdir函数的功能
全部学习汇总:GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 今天看一个半生不熟的小函数,chdir。说半生不熟,是因为这个接口一看就知道是什么功能。然而,这个接口如何用可真就没啥想法了。 …...
使用CEF 获得某头条请求,并生成本地文件的方法
目录 一、获得网站请求响应信息 1、响应过滤 2、匹配过滤URL的函数 3、获得请求响应后的处理...
二十、Django-restframework之视图集和路由器
一、视图集和路由器 REST框架包含了一个处理视图集的抽象,它允许开发人员集中精力建模API的状态和交互,并根据通用约定自动处理URL构造。 视图集类与视图类几乎相同,不同之处在于它们提供的是retrieve或update等操作,而不是get或…...
[深入理解SSD系列 闪存实战2.1.2] SLC、MLC、TLC、QLC、PLC NAND_固态硬盘闪存颗粒类型
闪存最小物理单位是 Cell, 一个Cell 是一个晶体管。 闪存是通过晶体管储存电子来表示信息的。在晶体管上加入了浮动栅贮存电子。数据是0或1取决于在硅底板上形成的浮动栅中是否有电子。有电子为0,无电子为1. SSD 根据闪存颗粒区分,固态硬盘有SLC、MLC、TLC、QLC、PLC 五种类型…...
论文阅读-MGTAB: A Multi-Relational Graph-Based Twitter Account DetectionBenchmark
目录 摘要 1. 引言 2. 相关工作 2.1. 立场检测 2.2.机器人检测 3.数据集预处理 3.1.数据收集和清理 3.2.专家注释 3.3. 质量评估 3.4.特征分析 4. 数据集构建 4.1.特征表示构造 4.2.关系图构建 5. 实验 5.1.实验设置 5.2.基准性能 5.3训练集大小的研究 5.4 社…...
基于libco的c++协程实现(时间轮定时器)
在后端的开发中,定时器有很广泛的应用。 比如: 心跳检测 倒计时 游戏开发的技能冷却 redis的键值的有效期等等,都会使用到定时器。 定时器的实现数据结构选择 红黑树 对于增删查,时间复杂度为O(logn),对于红黑…...
java多线程与线程池-04线程池与AQS
第7章 线程池与AQS java.util.concurrent包中的绝大多数同步工具,如锁(locks)和屏障(barriers)等,都基于AbstractQueuedSynchronizer(简称AQS)构建而成。这个框架提供了一套同步管理的通用机制,如同步状态的原子性管理、线程阻塞与解除阻塞,还有线程排队等。 在JD…...
优化模型验证关键代码25:样本均值近似技术处理两阶段随机旅行商问题及Gurobipy代码验证
大多数数学规划模型都会考虑到研究问题中存在的不确定性,针对这些不确定性,两种常用的处理方法是鲁棒优化和随机规划。这篇论文我们关注后者,也就是两阶段随机旅行商问题;利用套期保值算法计算不同规模TSP的可行解,同时比较了样本均值近似技术的解的情况,并计算了该问题的…...
老爸:“你做的什么游戏测试简直是不务正业!”——我上去就是一顿猛如虎的解释。
经常有人问我:游戏测试到底是干什么呢?是游戏代练?每天玩游戏?装备随便造,怪物随便秒,线上GM指令随便用?可以每天玩玩游戏,不用忙工作,太爽了?有时朋友不理解…...
JVM垃圾回收调优知识点整理
目录 1、JVM内存模型 1.2、堆及垃圾回收 1.3、JVM参数设置经验: 1.4、对象逃逸分析:...
linux安装mysql-8.0.31
1)、下载mysql-8.0.31压缩包两种方式 a.本地下载后上传服务器解压,下载地址:https://downloads.mysql.com/archives/community/ b.服务器使用命令下载,注意:路径在那,就下载到那个位置。 wget https://dev.mysql.com/…...
网站建设 科目/广州做网站的公司哪家好
%不同转速下的燃油消耗率与扭矩的曲线拟合clear allbe1[222.8,220.4,232.4,228.5,227.8,232.6,248.5,245.9,272.4,329.7];Ttq1[399.8,354.1,318.5,278.1,236.2,203.6,185.3,157.2,117.2,80.8];T180:320/9:400;%转换矩阵格式Be1interp1(Ttq1,be1,T1,spline);%n1400r/min时燃油消…...
微官网是什么意思呢/东莞百度seo推广公司
一、前言 笔者曾经阅读过周志明的《深入理解Java虚拟机》这本书,阅读完后自以为对jvm有了一定的了解,然而当真正碰到问题的时候,才发现自己读的有多粗糙,也体会到只有实践才能加深理解,正应对了那句话——“Talk is c…...
网站建设从入门到精通+网盘/我想开个网站平台怎么开呢
C/C:构建你自己的插件框架(2)zz2010-06-15 11:07译者 raof01 http://blog.chinaunix.net/u/12783/showart_1086995.html 本文是关于开发跨平台C插件系列的第二篇。第一篇详细描述了问题,探索了一些解决方案,并介绍了插…...
网站百度百科怎么做/网站快速推广
spring:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 commons-logging :所有的Java日志实现”提供一个统一的接口 junit-3.8.2.jar : JUnit是一个Java语言的单元测试框…...
php网站怎么做/百度集团总部在哪里
CISF信息安全专员认证 CISF(Certificated Information Security Foundation)旨在针对国际国内信息安全专员通过系统知识掌握,具备和符合信息化岗位。拥有CISF 资格证书说明持证人具备的实践能力和专业程度。随着对信息化发展,CISF…...
大一html5网页设计代码/南昌seo招聘信息
介绍 把照片变成字母符号软件下载 抖音上特别说的照片变成TXT文档软件 本文这款软件可以把女神的照片变成字母和符号拼成的 去年的时候也发布过这软件 小编随便用了一张小姐姐照片 感觉效果挺好看的 在抖音上面也是曾经很火的 下载链接 http://www.bytepan.com/ztRuDydQqO…...