Springboot2+vue2+uniapp 小程序端实现搜索联想自动补全功能

目录

一、实现目标

1.1 需求

1.2 实现示例图:

二、实现步骤

2.1 实现方法简述

2.2 简单科普

2.3 实现步骤及代码


 

一、实现目标

1.1 需求

搜索联想——自动补全
        (1)实现搜索输入框,用户输入时能显示模糊匹配结果
        (2)模糊结果在输入框下方浮动显示,并能点击选中
        (3)输入防抖功能(自己手写)

1.2 实现示例图:

      

联想框动画丝滑,整体效果也不错,代码给了超详细的注释 , 感兴趣的小伙伴可以按下面步骤试试

那么我们开始吧 !

二、实现步骤

2.1 实现方法简述

        我们先实现后端根据关键词进行模糊查询的接口,这里会用到mybatis工具,数据库操作部分是基于 MyBatis 实现的,大家需要先去项目里面的pop.xml文件里面引入必要的依赖;

        接着实现前端页面部分,搜索框这我选择自定义组件,原因主要有两点:一是 uni-search-bar 可能存在兼容性问题,部分样式易被覆盖导致显示异常;二是将搜索功能抽象为独立组件后,可在多个页面中复用,提高代码复用性;

        此外,搜索输入的防抖功能是通过自定义逻辑实现的,如果大家是拿来练手或者学习的话,我们自己手写的防抖功能就已经可以完全满足业务需求,相比于使用lodash.debounce来说手写的防抖功能可以减少依赖体积也更适配业务,当然如果咱们的是大型项目或需要处理多种防抖场景的需求的话 lodash.debounce 功能更多会更合适。

2.2 简单科普

(1). 什么是防抖?
        防抖的核心逻辑是:当函数被连续触发时,只有在触发停止后的指定时间内不再有新触发,函数才会执行一次。
        例如:搜索输入框中,用户快速输入文字时,不会每输入一个字符就立即请求接口,而是等用户暂停输入(比如停顿 300ms)后,再执行搜索请求,减少无效请求次数。

(2).lodash.debounce 是什么?

        lodash.debounce 是 JavaScript 工具库 Lodash 提供的一个核心函数,用于实现 防抖(Debounce) 功能。它能控制函数在高频触发场景下的执行时机,避免函数被频繁调用导致的性能问题(如频繁请求接口、频繁渲染等)。

2.3 实现步骤及代码

1.后端部分

新增一个接口可以根据关键词模糊查询商家

我这是模糊查询商家名称大家根据自己的业务需求做相应的更改

Controller层: 
/*** 根据关键词模糊查询商家(搜索联想)* @param keyword 搜索关键词* @return 匹配的商家列表*/
@GetMapping("/searchSuggest")
public Result searchSuggest(String keyword) {// 构建查询条件,根据商家名称模糊匹配Business business = new Business();business.setName(keyword);// 只查询状态为"通过"的商家(与现有逻辑保持一致)business.setStatus("通过");List<Business> list = businessService.selectAll(business);return Result.success(list);
}

service层

    /*** 查询所有商家信息* @param business 查询条件,可为空对象表示查询所有* @return 符合条件的商家列表*/public List<Business> selectAll(Business business) {List<Business> businesses = businessMapper.selectAll(business);for (Business b : businesses) {wrapBusiness(b); // 我这个函数是用来封装评分、订单数等信息 // 大家根据自己的项目需求写}return businesses;}

Mapper 层支持模糊查询

    List<Business> selectAll(Business business);

Mapper.xml

    <select id="selectAll" parameterType="com.example.entity.Business" resultType="com.example.entity.Business">select * from business<where><if test="id != null">and id = #{id}</if><if test="username != null">and username like concat('%', #{username}, '%')</if><if test="name != null">and name like concat('%', #{name}, '%')</if><if test="status != null">and status = #{status}</if><if test="type != null">and type = #{type}</if></where>order by id desc</select>

当传递 name = keyword 时,会自动生成 name like '%关键词%' 的 SQL,满足模糊查询需求。

2.前端部分

CustomSearchBar.vue组件

<template><view class="custom-search-bar"><view class="search-box" :style="{borderRadius: radius + 'px', backgroundColor: bgColor}" @click="searchClick"><view class="search-icon"><uni-icons color="#c0c4cc" size="18" type="search" /></view><input v-if="show || searchVal" :focus="showSync" :disabled="readonly" :placeholder="placeholderText" :maxlength="maxlength"class="search-input" confirm-type="search" type="text" v-model="searchVal" :style="{color: textColor}"@confirm="confirm" @blur="blur" @focus="emitFocus"/><text v-else class="placeholder-text">{{ placeholder }}</text><view v-if="show && (clearButton === 'always' || clearButton === 'auto' && searchVal !== '') && !readonly"class="clear-icon" @click="clear"><uni-icons color="#c0c4cc" size="20" type="clear" /></view></view><text @click="cancel" class="cancel-text"v-if="cancelButton === 'always' || show && cancelButton === 'auto'">{{ cancelText || '取消' }}</text></view>
</template><script>export default {name: "CustomSearchBar",props: {placeholder: {type: String,default: "请输入搜索商家"},radius: {type: [Number, String],default: 5},clearButton: {type: String,default: "auto"  // 值为 "auto" 时,组件会根据搜索框的状态动态决定是否显示 “取消” 按钮:},cancelButton: {type: String,default: "auto"  // "always":无论搜索框是否激活,始终显示 “取消” 按钮。},cancelText: {type: String,default: ""},bgColor: {type: String,default: "#F8F8F8"},textColor: {type: String,default: "#000000"},maxlength: {type: [Number, String],default: 100},value: {type: [Number, String],default: ""},modelValue: {type: [Number, String],default: ""},focus: {type: Boolean,default: false},readonly: {type: Boolean,default: false}},data() {return {show: false,showSync: false,searchVal: '',isAdvanced: true // 初始为 false,代表“未开启高级模式”}},computed: {placeholderText() {return this.placeholder  // 返回 props 中定义的 placeholder 的值// 在模板中,输入框的占位符使用的是 placeholderText 而非直接使用 this.placeholder// placeholderText 作为中间层,将 props 中的 placeholder 值传递给输入框的占位符属性// 假设未来需要对 placeholder 进行处理(比如根据语言环境翻译、添加动态后缀等),直接修改 placeholderText 即可,无需改动模板和 props// return this.placeholder + (this.isAdvanced ? "(支持模糊搜索)" : "");}},watch: {value: { // 监听父组件通过 value 属性传入的搜索值。immediate: true,  // 初始化时立即执行一次handlerhandler(newVal) {this.searchVal = newVal  // 将外部传入的value同步到组件内部的searchValif (newVal) {this.show = true  // 如果有值,显示搜索框}}},modelValue: {  // 适配 Vue 的 v-model 语法糖(modelValue 是 v-model 的默认绑定属性)immediate: true,handler(newVal) {this.searchVal = newVal   // 同步v-model绑定的值到searchValif (newVal) {this.show = true}}},focus: {  // 监听父组件传入的 focus 属性(控制搜索框是否聚焦)immediate: true,handler(newVal) {if (newVal) {  // 如果父组件要求聚焦if(this.readonly) return  // 只读状态不处理this.show = true;  // 显示搜索框this.$nextTick(() => {this.showSync = true  // 确保在 DOM 更新后再设置聚焦,避免操作还未渲染的元素})}}},searchVal(newVal, oldVal) {  // 监听组件内部的搜索值 searchVal(用户输入的内容)this.$emit("input", newVal)  // 触发input事件,同步值给父组件this.$emit("update:modelValue", newVal)  // 触发v-model更新}},methods: {/*** 搜索框容器点击事件处理* 功能:点击搜索框区域时,激活搜索框并设置聚焦状态* 场景:用户点击搜索框外部容器时触发,用于唤起输入状态*/searchClick() {// 只读状态下不响应点击(禁止交互)if(this.readonly) return// 若搜索框已激活,无需重复操作if (this.show) {return}// 激活搜索框(控制输入框和清除按钮的显示)this.show = true;// 使用$nextTick确保DOM更新后再聚焦,避免操作未渲染的元素this.$nextTick(() => {// 触发输入框聚焦(showSync与input的:focus属性绑定)this.showSync = true})},/*** 清除按钮点击事件处理* 功能:清空搜索框内容并通知父组件* 场景:用户点击搜索框内的清除图标时触发*/clear() {// 清空组件内部的搜索值this.searchVal = ""// 等待DOM更新后再通知父组件(确保值已同步清空)this.$nextTick(() => {// 向父组件发送清除事件,传递空值this.$emit("clear", { value: "" })})},/*** 取消按钮点击事件处理* 功能:取消搜索操作,重置组件状态并通知父组件* 场景:用户点击"取消"按钮时触发,用于退出搜索状态*/cancel() {// 只读状态下不响应取消操作if(this.readonly) return// 向父组件发送取消事件,携带当前搜索值(可能用于后续处理)this.$emit("cancel", {value: this.searchVal});// 清空搜索框内容this.searchVal = ""// 隐藏搜索框(重置激活状态)this.show = false// 取消输入框聚焦this.showSync = false// 关闭键盘(优化移动端体验,避免键盘残留)uni.hideKeyboard()},/*** 搜索确认事件处理* 功能:处理搜索确认逻辑(回车或搜索按钮)并通知父组件* 场景:用户输入完成后点击键盘搜索键或组件内确认按钮时触发*/confirm() {// 关闭键盘(输入完成后隐藏键盘)uni.hideKeyboard();// 向父组件发送确认事件,携带当前搜索值(触发实际搜索逻辑)this.$emit("confirm", {value: this.searchVal})},/*** 输入框失焦事件处理* 功能:输入框失去焦点时通知父组件并关闭键盘* 场景:用户点击输入框外部区域导致输入框失去焦点时触发*/blur() {// 关闭键盘(失焦后自动隐藏键盘)uni.hideKeyboard();// 向父组件发送失焦事件,携带当前搜索值(用于状态同步)this.$emit("blur", {value: this.searchVal})},/*** 输入框聚焦事件处理* 功能:输入框获取焦点时通知父组件* 场景:用户点击输入框或通过代码触发聚焦时触发* @param {Object} e*/emitFocus(e) {// 向父组件发送聚焦事件,传递焦点事件详情(如光标位置等)this.$emit("focus", e.detail)}}};
</script><style scoped>
.custom-search-bar {display: flex;align-items: center;padding: 10rpx;
}.search-box {display: flex;align-items: center;flex: 1;padding: 0 20rpx;height: 75rpx;position: relative;
}.search-icon {margin-right: 14rpx;
}.search-input {flex: 1;height: 100%;font-size: 30rpx;background: transparent;border: none;outline: none;
}.placeholder-text {flex: 1;font-size: 30rpx;color: #c0c4cc;
}.clear-icon {margin-left: 10rpx;padding: 5rpx;
}.cancel-text {margin-left: 20rpx;font-size: 30rpx;color: #007aff;padding: 10rpx;
}
</style> 

父组件 html 模版部分

		<!-- 搜索 --><view class="search-container"><custom-search-bar class="custom-searchbar" @confirm="search" @input="handleInput"  @focus="showSuggest = true"  @blur="hideSuggest"  v-model="searchValue" placeholder="请输入要搜索的商家" ></custom-search-bar><!-- 联想结果浮层 --><view class="suggest-container" v-if="showSuggest && suggestList.length > 0"@click.stop><view class="suggest-item" v-for="(item, index) in suggestList" :key="index"@click="selectSuggest(item)"><view class="suggest-content"><uni-icons type="shop" size="16" color="#666" class="suggest-icon"></uni-icons><text class="suggest-text">{{ item.name }}</text></view><uni-icons type="right" size="14" color="#ccc" class="arrow-icon"></uni-icons></view></view></view><!-- 搜索结束 -->

js部分

<script>import CustomSearchBar from '@/components/CustomSearchBar.vue'export default {components: {CustomSearchBar},data() {return {// 你的项目其他数据searchValue: '',  // 双向绑定到搜索组件的输入框,存储用户输入的搜索关键词suggestList: [],  // 存储根据搜索关键词从接口获取的联想建议数据,用于展示搜索提示showSuggest: false,  // 通过布尔值控制联想结果浮层是否显示debounceTimer: null  // 存储防抖函数中的定时器 ID,用于在用户输入过程中清除未执行的定时器,避免频繁请求}            },onLoad() {// this.load()},methods: {/*** 手写防抖函数* 功能:限制目标函数的执行频率,避免短时间内频繁调用* 原理:每次触发时清除之前的定时器,重新计时,延迟指定时间后执行目标函数* @param {Function} func - 需要防抖的目标函数(如搜索联想请求函数)* @param {Number} delay - 延迟时间(毫秒),默认300ms* @returns {Function} 经过防抖处理的包装函数*/debounce(func, delay) {return function(...args) {// 清除上一次未执行的定时器,避免重复触发clearTimeout(this.debounceTimer)// 设置新定时器,延迟指定时间后执行目标函数this.debounceTimer = setTimeout(() => {// 用apply绑定上下文,确保目标函数中的this指向当前组件func.apply(this, args)}, delay)}.bind(this) //// 绑定当前组件上下文,确保定时器中的this正确},/*** 搜索输入框内容变化处理函数* 功能:监听用户输入,同步搜索值并触发防抖联想请求* @param {String} value - 输入框当前值*/handleInput(value) {// 同步输入值到组件数据,实现双向绑定this.searchValue = value// 输入为空时重置联想状态(清空列表并隐藏浮层)if (!value.trim()) {this.suggestList = []this.showSuggest = falsereturn}// 使用防抖处理后的函数触发联想请求,减少接口调用次数this.debouncedSearch(value)},/*** 获取搜索联想结果* 功能:根据关键词请求接口,获取并更新联想列表数据* @param {String} keyword - 搜索关键词*/async fetchSuggest(keyword) {try {console.log('搜索关键词:', keyword)// 调用接口获取联想结果,传递关键词参数const res = await this.$request.get('/business/searchSuggest', { keyword })console.log('搜索联想结果:', res)// 接口返回成功且有数据时,更新联想列表并显示浮层if (res.code === '200' && res.data) {this.suggestList = res.datathis.showSuggest = true} else {  // 接口返回异常或无结果时,清空列表并隐藏浮层this.suggestList = []this.showSuggest = false}} catch (err) {  // 捕获请求异常(如网络错误),重置联想状态console.error('获取搜索联想失败', err)this.suggestList = []this.showSuggest = false}},/*** 选中联想项处理函数* 功能:用户点击联想项时,同步值到搜索框并关闭联想浮层* @param {Object} item - 选中的联想项数据(包含name等字段)*/selectSuggest(item) {console.log('选中联想项:', item)// 将联想项名称同步到搜索框this.searchValue = item.name// 隐藏联想浮层并清空列表this.showSuggest = falsethis.suggestList = []},/*** 隐藏联想浮层处理函数* 功能:搜索框失焦时延迟隐藏浮层,解决快速交互冲突* 说明:延迟200ms确保点击联想项的事件能正常触发*/hideSuggest() {setTimeout(() => {this.showSuggest = false}, 200)},/*** 搜索确认处理函数* 功能:用户确认搜索时,跳转到搜索结果页并重置搜索状态*/search() {let value = this.searchValue// 搜索值不为空时执行跳转if (value.trim()) {// 跳转到搜索结果页,通过URL传递关键词(encodeURIComponent处理特殊字符)uni.navigateTo({url: '/pages/search/search?name=' + encodeURIComponent(value)})// 重置搜索状态(清空值、列表和浮层)this.searchValue = ''this.suggestList = []this.showSuggest = false}},// 你的项目其他方法},/*** 组件创建生命周期函数* 功能:初始化防抖函数实例,为搜索联想请求添加防抖处理* 说明:在组件创建时生成延迟300ms的防抖函数,绑定到debouncedSearch*/created() {// 创建防抖函数this.debouncedSearch = this.debounce(this.fetchSuggest, 300)}}
</script>

css样式部分

<style>
/* 商家分类项样式 */
.categgory-item {flex: 1; /* 等分父容器宽度 */display: flex; /* 使用flex布局 */flex-direction: column; /* 垂直方向排列子元素(图标在上,文字在下) */justify-content: center; /* 垂直居中对齐 */align-items: center; /* 水平居中对齐 */grid-gap: 10rpx; /* 子元素之间的间距(图标与文字间距) */color: #333; /* 文字颜色(深灰色) */
}/* 全局修改uni-icons图标样式 */
::v-deep .uni-icons {color: #F4683d !important; /* 图标颜色(橙色),!important强制覆盖组件内部样式 */fill: #F4683d !important; /* 图标填充色(与颜色一致,确保图标显示正常) */
}/* 自定义搜索栏样式优化 - 最小化边距 */
::v-deep .custom-searchbar{padding: 0 !important; /* 清除内边距,让搜索栏紧贴容器 */margin: 0 !important; /* 清除外边距,避免额外留白 */
}/* 搜索容器 - 最小化边距 */
.search-container {position: relative; /* 相对定位,用于联想浮层的绝对定位参考 */padding: 0; /* 清除内边距 */margin: 0; /* 清除外边距 */z-index: 1000; /* 设置层级,确保搜索栏在页面上层 */
}/* 联想容器 - 紧贴搜索栏 */
.suggest-container {position: absolute; /* 绝对定位,相对于搜索容器定位 */top: 100%; /* 顶部对齐搜索容器底部,实现“紧贴搜索栏下方”效果 */left: 0; /* 左侧对齐搜索容器 */right: 0; /* 右侧对齐搜索容器,与搜索栏同宽 */background-color: #ffffff; /* 白色背景,与页面区分 */border: 1px solid #e0e0e0; /* 灰色边框,增强边界感 */border-top: none; /* 移除顶部边框,与搜索栏无缝连接 */border-radius: 0 0 8rpx 8rpx; /* 只保留底部圆角,优化视觉效果 */box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15); /* 底部阴影,增强浮层感 */z-index: 1001; /* 层级高于搜索容器,确保浮层显示在最上层 */max-height: 400rpx; /* 限制最大高度,避免内容过多溢出 */overflow-y: auto; /* 内容超出时显示垂直滚动条 */
}/* 联想项 - 美化样式 */
.suggest-item {padding: 16rpx 20rpx; /* 内边距,增加点击区域 */border-bottom: 1px solid #f0f0f0; /* 底部灰色分隔线,区分相邻项 */transition: all 0.2s ease; /* 过渡动画,优化交互体验 */display: flex; /* flex布局,实现内容与箭头左右排列 */align-items: center; /* 垂直居中对齐 */justify-content: space-between; /* 内容靠左,箭头靠右 */
}/* 最后一个联想项移除底部边框 */
.suggest-item:last-child {border-bottom: none; /* 避免最后一项多余边框 */
}/* 联想项点击状态样式 */
.suggest-item:active {background-color: #f8f9fa; /* 点击时背景变浅灰色,反馈交互 */transform: translateX(4rpx); /* 轻微右移,增强点击反馈 */
}/* 联想内容区域 */
.suggest-content {display: flex; /* flex布局,图标与文字横向排列 */align-items: center; /* 垂直居中对齐 */flex: 1; /* 占据剩余空间,确保箭头靠右 */
}/* 联想图标样式 */
.suggest-icon {margin-right: 12rpx; /* 图标与文字间距 */flex-shrink: 0; /* 图标不缩放,保持固定大小 */
}/* 箭头图标样式 */
.arrow-icon {flex-shrink: 0; /* 箭头不缩放,保持固定大小 */
}/* 联想文字样式 */
.suggest-text {font-size: 28rpx; /* 文字大小 */color: #333333; /* 文字颜色(深灰色) */line-height: 1.4; /* 行高,优化多行显示 */flex: 1; /* 占据剩余空间,文字过长时自动换行 */
}/* 定义联想浮层显示动画 */
@keyframes slideIn {from {opacity: 0; /* 初始状态完全透明 */transform: translateY(-10rpx); /* 初始位置向上偏移10rpx */}to {opacity: 1; /* 结束状态完全不透明 */transform: translateY(0); /* 结束位置回归正常 */}
}/* 为联想容器应用动画 */
.suggest-container {animation: slideIn 0.2s ease-out; /* 应用slideIn动画,0.2秒完成,缓出效果 */
}
</style>

好了 , 代码就到这了 , 快去试试吧

每天进步一点点 , 加油 !

 

 

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

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

相关文章

极简 5 步:Ubuntu+RTX4090 源码编译 vLLM

极简 5 步&#xff1a;UbuntuRTX4090 源码编译 vLLM1. 系统依赖&#xff08;一次性&#xff09;2. 进入源码目录 & 激活环境3. 启用 ccache 自动并行度4. 拉代码 编译&#xff08;2 行搞定&#xff09;5. 更新 flash-attn&#xff08;与 vLLM 配套&#xff09;6. 启动 4 …

生产工具革命:定制开发开源AI智能名片S2B2C商城小程序重构商业生态的范式研究

摘要互联网作为信息工具已深刻改变商业生态&#xff0c;但其本质仍停留在效率优化层面。本文提出&#xff0c;基于定制开发开源AI智能名片与S2B2C商城小程序的深度融合&#xff0c;正在引发生产工具层面的革命性变革。该技术架构通过重构"人-货-场"关系&#xff0c;实…

Transformer前传:Seq2Seq与注意力机制Attention

前言 参考了以下大佬的博客 https://blog.csdn.net/v_july_v/article/details/127411638 https://blog.csdn.net/andy_shenzl/article/details/140146699 https://blog.csdn.net/weixin_42475060/article/details/121101749 https://blog.csdn.net/weixin_43334693/article/det…

企业架构工具篇之ArchiMate的HelloWorld(2)

本文通过ArchiMate做一个员工报销流程设计的小demo,按照步骤都可以做出来,在做这个demo之前先简单认识下Archimate的开发界面: 模型树(Models)窗口:通常位于左上方,以树形结构展示一个或多个 ArchiMate 模型。用户可在此浏览模型的整体结构,快速定位到特定的模型元素,…

Docker 详解(保姆级安装+配置+使用教程)

文章目录一、初识 Docker二、Docker 命令1、安装2、配置镜像加速器检查配置是否生效3、服务相关命令4、镜像相关命令5、容器相关命令三、Docker 容器数据卷1、数据卷概念2、数据卷作用3、配置数据卷4、配置数据卷容器四、Docker 应用部署五、备份与迁移六、Dockerfile七、Docke…

做调度作业提交过程简单介绍一下

✅作业提交与执行流程前文提到在 Linux 的 HPC 或超算环境中&#xff0c;可以只在共享存储上安装一次应用程序&#xff0c;然后所有计算节点通过挂载共享目录来访问和执行这些程序&#xff0c;那么作业提交及执行过程是怎么样的流程呢&#xff1f;结构说明&#xff1a;第一行是…

【Altium designer】解决报错“Access violation at address...“

问题现象如上AD9原理图工程所示报错&#xff0c;当我关闭这个“CMM-WEIER-VA”原理图工程以及其他不相关的原理图工程出现报错&#xff1a;Access violation at address 0832A5EC in module WorkspaceManager.DLL. Read of address 00000061 at 0832A5EC&#xff0c;任务管理器…

小杰python高级(three day)——numpy库

1.numpy数组的操作&#xff08;1&#xff09;数组的连接stack该函数可以实现多个数组的堆叠(连接)&#xff0c;会创建新的轴&#xff0c;用于沿着新的轴连接一系列数组&#xff0c;所有数组必须具有相同的形状。可以增加数组的维度。假设输入的每个数组都是 n 维数组&#xff0…

视频剪辑的工作流程

准备素材 1.准备音频&#xff0c;视频、图片等素材 2.准备Pr创建的序列、彩条、字母、倒计时片头等功能性素材 创建项目 创建项目是诗篇剪辑的第一步&#xff0c;创建一个指定名称与存放位置的项目文件&#xff0c;用来通义管理整个视频项目创建序列 序列决定剪辑的尺寸、帧速率…

下一个排列 的 思路总结

文章目录思路分析&#xff1a; 倒序遍历&#xff1a;题目要求的是下一个排列&#xff0c;那么肯定数字的跳跃不能太大&#xff0c;所以可以比较好确定的是&#xff0c;遍历的顺序是倒序遍历比较方向&#xff1a;对于每一个数字&#xff0c;需要找到右边最大的比它小的数字&…

Spring Cloud-面试题(49)

摘要&#xff1a; 1、通俗易懂&#xff0c;适合小白 2、仅做面试复习用&#xff0c;部分来源网络&#xff0c;博文免费&#xff0c;知识无价&#xff0c;侵权请联系&#xff01; 1. 什么是Spring Cloud框架&#xff1f;子项目哪几大类&#xff1f; Spring Cloud是一套分布式系…

资源查看-iostat命令

文章目录 系统中未安装 iostat 命令 1. 监控CPU与磁盘的基础负载 2. 诊断I/O性能瓶颈 3. 实时监控与动态采样 4. 特定设备或分区的精细化监控 5. 性能测试与基准数据生成 6. 结合其他工具进行综合调优 总结 结果输出速查表 第一部分:CPU统计信息 第二部分:设备/磁盘统计信息(…

STM32 HAL库外设编程学习笔记

STM32 HAL库外设编程 1. 概述 本文档是基于STM32 HAL库的外设编程学习笔记&#xff0c;主要包括以下外设的配置和使用方法&#xff1a; GPIO&#xff1a;通用输入输出接口ADC&#xff1a;模数转换器UART&#xff1a;通用异步收发器TIM&#xff1a;定时器I2C&#xff1a;内部…

DHCP服务配置与管理实战指南

DHCP 服务配置与管理笔记 一、DHCP 核心概念 1. DHCP 定义与功能 DHCP (Dynamic Host Configuration Protocol)&#xff1a;动态主机配置协议核心功能&#xff1a; 自动分配 IP 地址提供子网掩码、网关、DNS 等网络参数管理 IP 地址租约周期 典型应用&#xff1a;ADSL拨号、企业…

WebSocket 在多线程环境下处理 Session并发

WebSocket 在多线程环境下处理 Session并发时&#xff0c;常见问题包括状态冲突&#xff08;如 IllegalStateException&#xff09;、消息乱序、连接超时等。以下是综合各技术方案的解决方案&#xff0c;分为单机多线程和分布式集群两类场景&#xff1a;&#x1f512; 一、单机…

JDBC的连接过程(超详细)

JDBC&#xff08;Java Database Connectivity&#xff09;是 Java 用于访问数据库的标准 API&#xff0c;它允许 Java 程序与各种不同类型的数据库进行交互&#xff0c; 其连接数据库的过程主要包含以下几个步骤&#xff1a;1. 导入 JDBC 驱动依赖在使用 JDBC 连接数据库之前&a…

本地WSL部署接入 whisper + ollama qwen3:14b 总结字幕校对增强版

1. 实现功能 M4-4: 校对增强版 (最终完全体) 本脚本是整个 Module 的最终形态&#xff0c;采用了“代码预处理 LLM校对”的终极方案&#xff1a; 代码预处理: 确定性地在每个语音片段后添加逗号&#xff0c;生成一份“标点草稿”。LLM校对: LLM 的任务被简化为“校对和修正”这…

MySQL数据库简介

1 简介 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB公司开发&#xff0c;属于 Oracle 旗下产品&#xff0c;是当今最流行的关系型数据库管理系统之一&#xff0c;在 WEB应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management System&#…

[Oracle] UNPIVOT 列转行

Oracle数据库中的UNPIVOT是一种用于将列转换为行的SQL操作&#xff0c;它允许用户将多个列的数据转换为多行的形式&#xff0c;以便进行更灵活的数据分析和报表生成UNPIVOT主要用于将宽表(多列)转换为长表(多行)&#xff0c;减少表的列数&#xff0c;增加行数语法格式SELECT pi…

node.js 学习笔记3 HTTP

path模块 path模块主要用于操作路径。要使用path&#xff0c;首先需要引入path模块。require(path) path.resolve 用于拼接规范的绝对路径。 如果想拼接一个路径&#xff0c;有时候是使用字符串手动拼接的&#xff0c;但由于系统的规范不同&#xff0c;路径中的\和/无法统一…