springboot整合MeiliSearch轻量级搜索引擎
一、Meilisearch与Easy Search点击进入官网了解,本文主要从小微型公司业务出发,选择meilisearch来作为项目的全文搜索引擎,还可以当成来mongodb来使用。
二、starter封装
1、项目结构展示
2、引入依赖包
<dependencies><dependency><groupId>cn.iocoder.boot</groupId><artifactId>yudao-common</artifactId></dependency><!-- meilisearch 轻量级搜索 --><!-- https://mvnrepository.com/artifact/com.meilisearch.sdk/meilisearch-java --><dependency><groupId>com.meilisearch.sdk</groupId><artifactId>meilisearch-java</artifactId><version>0.11.2</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.40</version><scope>provided</scope></dependency><!-- Web 相关 --><dependency><groupId>cn.iocoder.boot</groupId><artifactId>yudao-spring-boot-starter-web</artifactId><scope>provided</scope> <!-- 设置为 provided,只有 OncePerRequestFilter 使用到 --></dependency></dependencies>
3、yml参数读取代码参考
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;/*** MeiliSearch 自动装配参数类* 2023年9月21日*/
@ConfigurationProperties("yudao.meilisearch")
@Data
@Validated
public class MeiliSearchProperties {/*** 主机地址*/private String hostUrl = "";/*** 接口访问标识*/private String apiKey = "123456";}
4、自动配置类代码参考
import com.meilisearch.sdk.Client;
import com.meilisearch.sdk.Config;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;import javax.annotation.Resource;/*** MeiliSearch 自动装配类* 2023年9月21日*/
@AutoConfiguration
@EnableConfigurationProperties({MeiliSearchProperties.class})
@EnableCaching
public class MeiliSearchAutoConfiguration {@ResourceMeiliSearchProperties properties;@Bean@ConditionalOnMissingBean(Client.class)Client client() {return new Client(config());}@Bean@ConditionalOnMissingBean(Config.class)Config config() {return new Config(properties.getHostUrl(), properties.getApiKey());}}
5、数据处理类参考
import com.meilisearch.sdk.json.GsonJsonHandler;import java.util.List;/*** MeiliSearch json解析类* 2023年9月21日*/
public class JsonHandler {private com.meilisearch.sdk.json.JsonHandler jsonHandler = new GsonJsonHandler();public <T> SearchResult<T> resultDecode(String o, Class<T> clazz) {Object result = null;try {result = jsonHandler.decode(o, SearchResult.class, clazz);} catch (Exception e) {e.printStackTrace();}return result == null ? null : (SearchResult<T>) result;}public <T> List<T> listDecode(Object o, Class<T> clazz) {Object list = null;try {list = jsonHandler.decode(o, List.class, clazz);} catch (Exception e) {e.printStackTrace();}return list == null ? null : (List<T>) list;}public String encode(Object o) {try {return jsonHandler.encode(o);} catch (Exception e) {e.printStackTrace();return null;}}public <T> T decode(Object o, Class<T> clazz) {T t = null;try {t = jsonHandler.decode(o, clazz);} catch (Exception e) {e.printStackTrace();}return t;}
}import java.util.List;
import java.util.Map;/*** MeiliSearch* 2023年9月21日*/
public class MatchedBean<T> {private T _formatted;private Map<String, List<Matching>> _matchesInfo;public T get_formatted() {return _formatted;}public void set_formatted(T _formatted) {this._formatted = _formatted;}public Map<String, List<Matching>> get_matchesInfo() {return _matchesInfo;}public void set_matchesInfo(Map<String, List<Matching>> _matchesInfo) {this._matchesInfo = _matchesInfo;}private class Matching {long start;long length;public long getStart() {return start;}public void setStart(long start) {this.start = start;}public long getLength() {return length;}public void setLength(long length) {this.length = length;}}
}import java.util.List;/*** MeiliSearch* 2023年9月21日*/
public class SearchResult<T> {private String query;private long offset;private long limit;private long processingTimeMs;private long nbHits;private boolean exhaustiveNbHits;private List<T> hits;public String getQuery() {return query;}public void setQuery(String query) {this.query = query;}public long getOffset() {return offset;}public void setOffset(long offset) {this.offset = offset;}public long getLimit() {return limit;}public void setLimit(long limit) {this.limit = limit;}public long getProcessingTimeMs() {return processingTimeMs;}public void setProcessingTimeMs(long processingTimeMs) {this.processingTimeMs = processingTimeMs;}public long getNbHits() {return nbHits;}public void setNbHits(long nbHits) {this.nbHits = nbHits;}public boolean isExhaustiveNbHits() {return exhaustiveNbHits;}public void setExhaustiveNbHits(boolean exhaustiveNbHits) {this.exhaustiveNbHits = exhaustiveNbHits;}public List<T> getHits() {return hits;}public void setHits(List<T> hits) {this.hits = hits;}@Overridepublic String toString() {return "SearchResult{" +"query='" + query + '\'' +", offset=" + offset +", limit=" + limit +", processingTimeMs=" + processingTimeMs +", nbHits=" + nbHits +", exhaustiveNbHits=" + exhaustiveNbHits +", hits=" + hits +'}';}
}
6、自定义注解代码参考
import java.lang.annotation.*;/*** MeiliSearch* 2023年9月21日*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MSFiled {/*** 是否开启过滤*/boolean openFilter() default false;/*** 是否不展示*/boolean noDisplayed() default false;/*** 是否开启排序*/boolean openSort() default false;/*** 处理的字段名*/String key() ;
}import java.lang.annotation.*;/*** MeiliSearch* 2023年9月21日*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MSIndex {/*** 索引*/String uid() default "";/*** 主键*/String primaryKey() default "";/*** 分类最大数量*/int maxValuesPerFacet() default 100;/*** 单次查询最大数量*/int maxTotalHits() default 1000;
}
7、基础操作接口封装
import cn.iocoder.yudao.framework.meilisearch.json.SearchResult;
import com.meilisearch.sdk.SearchRequest;
import com.meilisearch.sdk.model.Settings;
import com.meilisearch.sdk.model.Task;
import com.meilisearch.sdk.model.TaskInfo;import java.util.List;/*** MeiliSearch 基础接口* 2023年9月21日*/
interface DocumentOperations<T> {T get(String identifier);List<T> list();List<T> list(int limit);List<T> list(int offset, int limit);long add(T document);long update(T document);long add(List<T> documents);long update(List<T> documents);long delete(String identifier);long deleteBatch(String... documentsIdentifiers);long deleteAll();SearchResult<T> search(String q);SearchResult<T> search(String q, int offset, int limit);SearchResult<T> search(SearchRequest sr);Settings getSettings();TaskInfo updateSettings(Settings settings);TaskInfo resetSettings();Task getUpdate(int updateId);
}
8、基本操作实现
import cn.iocoder.yudao.framework.meilisearch.json.JsonHandler;
import cn.iocoder.yudao.framework.meilisearch.json.MSFiled;
import cn.iocoder.yudao.framework.meilisearch.json.MSIndex;
import cn.iocoder.yudao.framework.meilisearch.json.SearchResult;
import com.alibaba.fastjson2.JSON;
import com.meilisearch.sdk.*;
import com.meilisearch.sdk.model.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.*;/*** MeiliSearch 基本操作实现* 2023年9月21日*/
public class MeilisearchRepository<T> implements InitializingBean, DocumentOperations<T> {private Index index;private Class<T> tClass;private JsonHandler jsonHandler = new JsonHandler();@Resourceprivate Client client;@Overridepublic T get(String identifier) {T document;try {document = index.getDocument(identifier, tClass);} catch (Exception e) {throw new RuntimeException(e);}return document;}@Overridepublic List<T> list() {List<T> documents;try {documents = Optional.ofNullable(index.getDocuments(tClass)).map(indexDocument -> indexDocument.getResults()).map(result -> Arrays.asList(result)).orElse(new ArrayList<>());} catch (Exception e) {throw new RuntimeException(e);}return documents;}@Overridepublic List<T> list(int limit) {List<T> documents;try {DocumentsQuery query = new DocumentsQuery();query.setLimit(limit);documents = Optional.ofNullable(index.getDocuments(query, tClass)).map(indexDocument -> indexDocument.getResults()).map(result -> Arrays.asList(result)).orElse(new ArrayList<>());} catch (Exception e) {throw new RuntimeException(e);}return documents;}@Overridepublic List<T> list(int offset, int limit) {List<T> documents;try {DocumentsQuery query = new DocumentsQuery();query.setLimit(limit);query.setOffset(offset);documents = Optional.ofNullable(index.getDocuments(query, tClass)).map(indexDocument -> indexDocument.getResults()).map(result -> Arrays.asList(result)).orElse(new ArrayList<>());} catch (Exception e) {throw new RuntimeException(e);}return documents;}@Overridepublic long add(T document) {List<T> list = Collections.singletonList(document);return add(list);}@Overridepublic long update(T document) {List<T> list = Collections.singletonList(document);return update(list);}@Overridepublic long add(List documents) {int taskId;try {taskId = index.addDocuments(JSON.toJSONString(documents)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}@Overridepublic long update(List documents) {int updates;try {updates = index.updateDocuments(JSON.toJSONString(documents)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return updates;}@Overridepublic long delete(String identifier) {int taskId;try {taskId = index.deleteDocument(identifier).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}@Overridepublic long deleteBatch(String... documentsIdentifiers) {int taskId;try {taskId = index.deleteDocuments(Arrays.asList(documentsIdentifiers)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}@Overridepublic long deleteAll() {int taskId;try {taskId = index.deleteAllDocuments().getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}@Overridepublic cn.iocoder.yudao.framework.meilisearch.json.SearchResult<T> search(String q) {String result;try {result = JSON.toJSONString(index.search(q));} catch (Exception e) {throw new RuntimeException(e);}return jsonHandler.resultDecode(result, tClass);}@Overridepublic cn.iocoder.yudao.framework.meilisearch.json.SearchResult<T> search(String q, int offset, int limit) {SearchRequest searchRequest = SearchRequest.builder().q(q).offset(offset).limit(limit).build();return search(searchRequest);}@Overridepublic SearchResult<T> search(SearchRequest sr) {String result;try {result = JSON.toJSONString(index.search(sr));} catch (Exception e) {throw new RuntimeException(e);}return jsonHandler.resultDecode(result, tClass);}@Overridepublic Settings getSettings() {try {return index.getSettings();} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic TaskInfo updateSettings(Settings settings) {try {return index.updateSettings(settings);} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic TaskInfo resetSettings() {try {return index.resetSettings();} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic Task getUpdate(int updateId) {try {return index.getTask(updateId);} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic void afterPropertiesSet() throws Exception {initIndex();}public Index getIndex() {return index;}/*** 初始化索引信息** @throws Exception*/private void initIndex() throws Exception {Class<? extends MeilisearchRepository> clazz = getClass();tClass = (Class<T>) ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0];MSIndex annoIndex = tClass.getAnnotation(MSIndex.class);String uid = annoIndex.uid();String primaryKey = annoIndex.primaryKey();if (StringUtils.isEmpty(uid)) {uid = tClass.getSimpleName().toLowerCase();}if (StringUtils.isEmpty(primaryKey)) {primaryKey = "id";}int maxTotalHit=1000;int maxValuesPerFacet=100;if (Objects.nonNull(annoIndex.maxTotalHits())){maxTotalHit=annoIndex.maxTotalHits();}if (Objects.nonNull(annoIndex.maxValuesPerFacet())){maxValuesPerFacet=100;}List<String> filterKey = new ArrayList<>();List<String> sortKey = new ArrayList<>();List<String> noDisPlay = new ArrayList<>();//获取类所有属性for (Field field : tClass.getDeclaredFields()) {//判断是否存在这个注解if (field.isAnnotationPresent(MSFiled.class)) {MSFiled annotation = field.getAnnotation(MSFiled.class);if (annotation.openFilter()) {filterKey.add(annotation.key());}if (annotation.openSort()) {sortKey.add(annotation.key());}if (annotation.noDisplayed()) {noDisPlay.add(annotation.key());}}}Results<Index> indexes = client.getIndexes();Index[] results = indexes.getResults();Boolean isHaveIndex=false;for (Index result : results) {if (uid.equals(result.getUid())){isHaveIndex=true;break;}}if (isHaveIndex){client.updateIndex(uid,primaryKey);this.index = client.getIndex(uid);Settings settings = new Settings();settings.setDisplayedAttributes(noDisPlay.size()>0?noDisPlay.toArray(new String[noDisPlay.size()]):new String[]{"*"});settings.setFilterableAttributes(filterKey.toArray(new String[filterKey.size()]));settings.setSortableAttributes(sortKey.toArray(new String[sortKey.size()]));index.updateSettings(settings);}else {client.createIndex(uid, primaryKey);}}
}
9、指定自动配置类所在
10、项目有统一版本管理的设置下版本管理
二、项目引用
1、引入starter依赖(没有版本统一管理的要把version加上)
2、基本使用
2.1、建立索引(宽表)
import cn.iocoder.yudao.framework.meilisearch.json.MSFiled;
import cn.iocoder.yudao.framework.meilisearch.json.MSIndex;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@MSIndex(uid = "com_baidu_main", primaryKey = "id")
public class MainDO {private Long id;private String seedsName;@MSFiled(openFilter = true, key = "isDelete")private Integer isDelete;@MSFiled(openFilter = true, key = "status")private Integer status;@MSFiled(openFilter = true, key = "classFiledId")private Integer classFiledId;private String classFiledName;@MSFiled(openFilter = true, key = "tags")private List<TageInfo> tags;
}
2.2、集成starter里边的mapper对milisearch进行基本操作
import cn.iocoder.yudao.framework.meilisearch.core.MeilisearchRepository;
import org.springframework.stereotype.Repository;@Repository
public class MeiliSearchMapper extends MeilisearchRepository<MainDO> {
}
2.3、基本使用
@Resource
private MeiliSearchMapper meiliSearchMapper;//根据标签分页查询
SearchRequest searchRequest4 = SearchRequest.builder().limit(pageParam.getPageSize().intValue()).sort(new String[]{"createTime:desc"}).offset(pageParam.getPageNo().intValue() == 0 ? pageParam.getPageNo().intValue() : (pageParam.getPageNo().intValue() - 1) * pageParam.getPageSize().intValue()).filter(new String[]{"tags.id=" + "10010" + " AND status=1 AND isDelete=0"}).build();
SearchResult<MainDO> search4 = meiliSearchMapper.search(searchRequest4);//保存Or编辑
List<SeedsDO> articleCardDTOS = new ArrayList<>();
Boolean aBoolean = meiliSearchMapper.add(articleCardDTOS) > 0 ? Boolean.TRUE : Boolean.FALSE;
//按id删除
meiliSearchMapper.delete(String.valueOf(10085));//根据类目分页查询
SearchRequest searchRequest3 = SearchRequest.builder().limit(pageParam.getPageSize().intValue()).offset(pageParam.getPageNo().intValue() == 0 ? pageParam.getPageNo().intValue() : (pageParam.getPageNo().intValue() - 1) * pageParam.getPageSize().intValue()).build();
StringBuffer sb1 = new StringBuffer();
sb.append("status =1 AND isDelete=0").append(" AND ").append("categoryId =").append(10086L);
searchRequest.setFilter(new String[]{sb.toString()});
searchRequest.setSort(new String[]{"createTime:desc"});
SearchResult<SeedsDO> search3 = meiliSearchMapper.search(searchRequest3);
相关文章:
springboot整合MeiliSearch轻量级搜索引擎
一、Meilisearch与Easy Search点击进入官网了解,本文主要从小微型公司业务出发,选择meilisearch来作为项目的全文搜索引擎,还可以当成来mongodb来使用。 二、starter封装 1、项目结构展示 2、引入依赖包 <dependencies><dependenc…...
禁用鼠标的侧边按键
新买了个鼠标,整体都不错,就是鼠标左侧有两个按键,大拇指经常无意触碰到,造成误操作。 就想着关闭侧边按键功能。以下这批文章帮了大忙! 鼠标侧键屏蔽,再也不用担心按到侧键了。_禁用鼠标侧键_挣扎的蓝藻…...
【C语言】数组和指针刷题练习
指针和数组我们已经学习的差不多了,今天就为大家分享一些指针和数组的常见练习题,还包含许多经典面试题哦! 一、求数组长度和大小 普通一维数组 int main() {//一维数组int a[] { 1,2,3,4 };printf("%d\n", sizeof(a));//整个数组…...
2023年中国研究生数学建模竞赛D题解题思路
为了更好的帮助大家第一天选题,这里首先为大家带来D题解题思路,分析对应赛题之后做题阶段可能会遇到的各种难点。 稍后会带来D题的详细解析思路,以及相关的其他版本解题思路 成品论文等资料。 赛题难度评估:A、B>C>E、F&g…...
在编译源码的环境下,搭建起Discuz!社区论坛和WordPress博客的LNMP架构
目录 一.编译安装nginx 二.编译安装MySQL 三.编译安装PHP 四.安装论坛 五.安装wordpress博客 六.yum安装LNMP架构(简要过程参考) 一.编译安装nginx 1)关闭防火墙,将安装nginx所需软件包传到/opt目录下 systemctl stop fire…...
腾讯面试题:无网络环境,如何部署Docker镜像?
亲爱的小伙伴们,大家好!我是小米,很高兴再次和大家见面。今天,我要和大家聊聊一个特别有趣的话题——腾讯面试题:无网络环境,如何部署Docker镜像?这可是一个技术含量颇高的问题哦!废…...
医学影像信息(PACS)系统软件源码
PACS系统是PictureArchivingandCommunicationSystems的缩写,与临床信息系统(ClinicalInformationSystem,CIS)、放射学信息系统(RadiologyInformationSystem,RIS)、医院信息系统(HospitalInformationSystem,HIS)、实验室信息系统(L…...
【01】FISCOBCOS的系统环境安装
我们选择ubuntu系统 01 https://www.ubuntu.org.cn/global 02 03下载最新版 04等待下载 00提前准备好VM,点击创建新的虚拟机 01选择自定义安装 02一直下一步到 03 04 05其他的默认即可 06 07 08 09 10 11一直默认到下面 12 13等待安装 安装后重启即可…...
flutter 权限和图片权限之前的冲突
权限插件 permission_handler: ^9.2.0想调起相册和视频,这个插件只有Permission.storage.request().,获取存储权限。 问题是android 13的一些手机,系统设置没有存储权限,用了上面这个权限,三次拒绝后就永久拒绝了&…...
OpenCV(四十八):读取视频和保存视频
OpenCV(Open Source Computer Vision Library)是一个功能强大的开源计算机视觉库,它提供了丰富的功能,包括读取和保存视频。下面分别演示如何使用OpenCV来读取视频和保存视频。 1. 读取视频: 在OpenCV中我们要获取一…...
如何在react/next.js app中的同级组件间传递数据
这篇文章也可以在我的博客中查看 问题 为什么会有这么奇怪的需求?在事情真正发生前真的难说,但真遇到一个需要这么做的情况。 最近想做一个网页时钟,它的结构如下: 时钟(计算时间,组织各个要素ÿ…...
软件需求文档、设计文档、开发文档、运维文档大全
在软件开发过程中,文档扮演着至关重要的角色。它不仅记录了项目的需求、设计和开发过程,还为项目的维护和管理提供了便利。本文将详细介绍软件开发文档的重要性和作用,以及需求分析、软件设计、开发过程、运维管理和项目管理等方面的文档要求…...
排序算法-----归并排序
目录 前言: 归并排序 1. 定义 2.算法过程讲解 2.1大致思路 2.2图解示例 拆分合成步骤 编辑 相关动态图 3.代码实现(C语言) 4.算法分析 4.1时间复杂度 4.2空间复杂度 4.3稳定性 前言: 今天我们就开始学习新的排序算法…...
docker 配置 gpu版pytorch环境--部署缺陷检测--Anomalib
目录 一、docker 配置 gpu版pyhorch环境1、显卡驱动、cuda版本、pytorch cuda版本三者对应2、拉取镜像 二、部署Anomalib1、下载Anomalib2、创建容器并且运行3、安装Anomalib进入项目路径安装依赖测试: 一、docker 配置 gpu版pyhorch环境 1、显卡驱动、cuda版本、p…...
为什么定时发朋友圈会更有效呢?
这是因为在同一时段 发送的好友朋友圈 无法有效分散用户的注意力 导致曝光度难以提升 而通过推广定时发朋友圈 可根据自己的粉丝活跃度 设置发圈时间 让每一条朋友圈都能高效 传递到更多的好友手中 这样,曝光度自然而然地就大大提升了! 1.多个号…...
【跟小嘉学 PHP 程序设计】一、PHP 开发环境搭建
系列文章目录 【跟小嘉学 PHP 程序设计】一、PHP 开发环境搭建 文章目录 系列文章目录@[TOC](文章目录)前言一、PHP介绍二、Centos 安装 PHP2.1、安装并启动 Nginx2.2、安装并启动 mariadb2.3、安装 rh-php2.4、添加 Nginx 配置2.5、Nginx 服务三、使用 Docker 为 PHP 部署开发…...
【zookeeper】zk选举、使用与三种节点简介,以及基于redis分布式锁的缺点的讨论
这里我准备了4台虚拟机,从node1到node4,其myid也从1到4. 一,zk server的启动和选举 zk需要至少启动3台Server,按照配置的myid,选举出参与选举的myid最大的server为Leader。(与redis的master、slave不同&a…...
Unity截图生成图片 图片生成器 一键生成图片
使用Unity编辑器扩展技术实现快速截图功能 效果: 里面没有什么太难的技术,直接上源码吧 注意!代码需要放在Editor文件下才能正常运行 using System; using UnityEditor; using UnityEngine;[ExecuteInEditMode] public class Screenshot …...
Matlab图像处理-区域特征
凹凸性 设P是图像子集S中的点,若通过的每条直线只与S相交一次,则称S为发自P的星形,也就是站在P点能看到S的所有点。 满足下列条件之一,称此为凸状的: 1.从S中每点看,S都是星形的; 2.对S中任…...
golang 自动生成文件头
安装koroFileHeader控件 打开首选项,进入设置,配置文件头信息"fileheader.customMade": {"Author": "lmy","Date": "Do not edit", // 文件创建时间(不变)// 文件最后编辑者"LastEditors"…...
Excel中的宏、VBA
一、宏是什么? EXCEL MACRO 是一种记录和播放工具,它仅记录您的 Excel 步骤,并且宏将根据需要播放任意多次。 VBA 宏可自动执行重复任务,从而节省了时间。 这是一段可在 Excel 环境中运行的编程代码,但您无需成为编码…...
2023华为杯数学建模研赛思路分享——最全版本A题深度解析
问题回顾: WLAN网络信道接入机制建模 1. 背景 无线局域网(WLAN, wireless local area network)也即Wi-Fi广泛使用,提供低成本、高吞吐和便利的无线通信服务。基本服务集(BSS, basic service set)是WLAN的…...
【校招VIP】测试方案之测试需求分析
考点介绍: 需求分析就是要弄清楚用户需要的是什么功能,用户会怎样使用系统。这样我们测试的时候才能更加清楚的知道系统该怎么样运行,才能更好的设计测试用例,才能更好的测试。 测试方案之测试需求分析-相关题目及解析内容可点击…...
滚珠螺母的清洁方式
滚珠螺母是一种通过滚珠与螺杆进行螺旋运动转换的机械零件,主要用于控制螺杆的运动轨迹和方向,把原来的滑动摩擦利用滚珠的滚动变成滚动摩擦,因此滚珠螺母的摩擦系数大大降低,从而提高了传动效率,要想滚珠螺母达到预期…...
leetcode做题笔记148. 排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 思路一:归并排序 c语言解法 struct ListNode* merge(struct ListNode* head1, struct ListNode* head2) {struct ListNode* dummyHead malloc(sizeof(struct ListNode));dummyHead…...
多线程学习
并发:交替运行 并行:一起运行 多线程实现方式 继承Thread类 ①自己定义一个类继承Thread public class MyThread extends Thread{public void run(){}} ②重写run方法 public class MyThread extends Thread{public void run(){"重写的内容&…...
软件测试/测试开发丨ChatGPT在测试计划中的应用策略
点此获取更多相关资料 简介 测试计划是指描述了要进行的测试活动的范围、方法、资源和进度的文档。它主要包括测试项、被测特性、测试任务和风险控制等。 所以在使用ChatGPT输出结果之前,我们需要先将文档的内容框架梳理好,以及将内容范围划定好&…...
链表oj3(Leetcode)——相交链表;环形链表
一,相交链表 相交链表(Leetcode) 1.1分析 看到这个我们首先想到的就是一个一个比较他们的值有相等的就是交点,但是如果a1和b2的值就相等呢?所以这个思路不行,第二种就是依次比较链表,但是这…...
nginx反向代理
nginx反向代理8.反向代理8.1 实现http反向代理8.1.1 反向代理配置参数8.1.2 反向代理单台web服务器8.1.2.1 端口号后加"/"8.1.2.2 端口号后不加"/" 8.1.3指定location 实现反向代理,动静分离8.1.4 反向代理实例:缓存功能8.1.4.1 举例 8.1.5 实现…...
基于eBPF的安卓逆向辅助工具——stackplz
前言 stackplz是一款基于eBPF技术实现的追踪工具,目的是辅助安卓native逆向,仅支持64位进程,主要功能如下: hardware breakpoint 基于pref_event实现的硬件断点功能,在断点处可读取寄存器信息,不会被用户…...
长沙做网站开发价格多少/seo搜索是什么
正数在内存的存储是以最高位为符号位,其余为数值的二进制序列,那么浮点数在内存中是怎么进行存储的呢,接下来我们一起看一看; 假设一个数为1154,那么用科学记数法可以表示为1.154*10^3,同理在计算机中也可…...
怎样做网站开发/网站搭建平台
开源前夕先给大家赞赏一下我用C语言开发的移动、手机、PC自己主动兼容云贴吧 - 涨知识属马超懒散,属虎太倔强.十二生肖全了!-转自云寻觅贴吧 转: 涨知识属马超懒散,属虎太倔强.十二生肖全了! -转自云寻觅贴吧 转自:http://tieba.yunxunmi.com/tieba-%25E9%25A9%25AC%25E8%25B6…...
官方网站、门户网站是什么意思?/怎么寻找网站关键词并优化
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼我要做个rolldice的小游戏,然后这是我的完整的code,我想直接把bank method 里面的那几个variable用在下面的checkwin method里面,但是总是显示找不到variable,应该是超过scope了。我想…...
网站制作书籍推荐/开网店哪个平台靠谱
1.ios离线打包配置appid 和 cer证书 和 描述文件2.iOS离线打包-支付插件配置主要注意打包:在info.plist root 节点添加 UniversalLinks 项,值和微信开放平台配置的一致,(微信开放平台配置的域名地址)3.本次核心处理微信支付链接的配置(微信…...
wordpress首页只能是page/关键词指数查询
别人文章参考:https://blog.csdn.net/kkevinyang/article/details/80539940 第三类错误:supervisord进程被占用的错误 查询进程,kill掉在重启 ps -ef | grep supervisord 报错信息: Exited too quickly (process log may have…...
做邀请函的网站/网站推广的平台
为什么要使用构建器(Buildle模式) 静态工厂和构造方法都有共同的局限性:不能很好的扩展到大量的可选参数。 模拟一个场景: 一个Person对象,它有2个必要的参数(name,age),2个可选参数(sex,address),我们来获取它的实例。 1、静态工厂方法实现 - 重叠构造方…...