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

工程化与框架系列(23)--前端性能优化(下)

前端性能优化(用户体验) 🎨

引言

用户体验(UX)性能优化是前端性能优化的重要组成部分。本文将探讨如何通过优化用户体验相关的性能指标,提升用户对应用的满意度,包括感知性能、交互响应、视觉反馈等关键方面。

用户体验性能概述

用户体验性能优化主要关注以下方面:

  • 感知性能:用户对应用速度的主观感受
  • 交互响应:用户操作的即时反馈
  • 视觉反馈:加载状态和过渡动画
  • 错误处理:优雅的错误提示和恢复
  • 离线体验:网络不稳定时的应用表现

感知性能优化

骨架屏实现

// 骨架屏组件
class SkeletonScreen {private container: HTMLElement;private template: string;constructor(container: HTMLElement, template: string) {this.container = container;this.template = template;}// 显示骨架屏show(): void {this.container.innerHTML = this.template;this.container.querySelectorAll('.skeleton-item').forEach(item => {item.classList.add('skeleton-animation');});}// 隐藏骨架屏hide(): void {this.container.querySelectorAll('.skeleton-item').forEach(item => {item.classList.remove('skeleton-animation');});}// 创建骨架屏样式static createStyles(): void {const style = document.createElement('style');style.textContent = `.skeleton-item {background: #f0f0f0;border-radius: 4px;}.skeleton-animation {animation: skeleton-loading 1.5s infinite;}@keyframes skeleton-loading {0% {background-position: -200px 0;}100% {background-position: calc(200px + 100%) 0;}}`;document.head.appendChild(style);}
}// 使用示例
const container = document.getElementById('content')!;
const template = `<div class="skeleton-item" style="width: 100%; height: 200px;"></div><div class="skeleton-item" style="width: 60%; height: 20px; margin-top: 20px;"></div><div class="skeleton-item" style="width: 80%; height: 20px; margin-top: 10px;"></div>
`;const skeleton = new SkeletonScreen(container, template);
SkeletonScreen.createStyles();// 显示骨架屏
skeleton.show();// 加载完成后隐藏
setTimeout(() => {skeleton.hide();container.innerHTML = '实际内容';
}, 2000);

进度反馈

// 进度反馈管理器
class ProgressManager {private progressBar: HTMLElement;private progressText: HTMLElement;constructor() {this.createProgressElements();}// 创建进度条元素private createProgressElements(): void {this.progressBar = document.createElement('div');this.progressBar.className = 'progress-bar';this.progressText = document.createElement('div');this.progressText.className = 'progress-text';document.body.appendChild(this.progressBar);document.body.appendChild(this.progressText);const style = document.createElement('style');style.textContent = `.progress-bar {position: fixed;top: 0;left: 0;width: 0;height: 3px;background: #4CAF50;transition: width 0.3s ease;z-index: 9999;}.progress-text {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);background: rgba(0, 0, 0, 0.7);color: white;padding: 10px 20px;border-radius: 4px;display: none;z-index: 9999;}`;document.head.appendChild(style);}// 更新进度updateProgress(progress: number, text?: string): void {this.progressBar.style.width = `${progress}%`;if (text) {this.progressText.textContent = text;this.progressText.style.display = 'block';}if (progress >= 100) {setTimeout(() => {this.progressBar.style.width = '0';this.progressText.style.display = 'none';}, 500);}}// 模拟进度simulateProgress(duration: number = 2000): Promise<void> {return new Promise(resolve => {let progress = 0;const interval = setInterval(() => {progress += Math.random() * 10;if (progress >= 100) {progress = 100;clearInterval(interval);this.updateProgress(progress);resolve();} else {this.updateProgress(progress);}}, duration / 20);});}
}// 使用示例
const progress = new ProgressManager();// 模拟文件上传进度
async function uploadFile(file: File): Promise<void> {const total = file.size;let loaded = 0;const reader = new FileReader();reader.onprogress = (event) => {if (event.lengthComputable) {const percentage = (event.loaded / event.total) * 100;progress.updateProgress(percentage,`上传中... ${Math.round(percentage)}%`);}};reader.onload = () => {progress.updateProgress(100, '上传完成!');};reader.readAsArrayBuffer(file);
}

交互响应优化

即时反馈

// 交互反馈管理器
class InteractionFeedback {// 点击波纹效果static addRippleEffect(element: HTMLElement): void {element.style.position = 'relative';element.style.overflow = 'hidden';element.addEventListener('click', (e: MouseEvent) => {const rect = element.getBoundingClientRect();const ripple = document.createElement('div');ripple.className = 'ripple';ripple.style.position = 'absolute';ripple.style.left = `${e.clientX - rect.left}px`;ripple.style.top = `${e.clientY - rect.top}px`;element.appendChild(ripple);setTimeout(() => ripple.remove(), 1000);});const style = document.createElement('style');style.textContent = `.ripple {width: 20px;height: 20px;background: rgba(255, 255, 255, 0.7);border-radius: 50%;transform: scale(0);animation: ripple-animation 1s ease-out;}@keyframes ripple-animation {to {transform: scale(20);opacity: 0;}}`;document.head.appendChild(style);}// 按钮状态管理static enhanceButton(button: HTMLButtonElement,action: () => Promise<void>): void {const originalText = button.textContent;button.addEventListener('click', async () => {button.disabled = true;button.classList.add('loading');try {await action();button.classList.add('success');button.textContent = '成功!';} catch (error) {button.classList.add('error');button.textContent = '失败';}setTimeout(() => {button.disabled = false;button.className = button.className.replace(/(loading|success|error)/g,'');button.textContent = originalText;}, 2000);});}// 表单验证反馈static enhanceFormValidation(form: HTMLFormElement): void {const inputs = form.querySelectorAll('input, textarea');inputs.forEach(input => {input.addEventListener('input', () => {const isValid = input.checkValidity();if (isValid) {input.classList.remove('invalid');input.classList.add('valid');} else {input.classList.remove('valid');input.classList.add('invalid');}});});}
}// 使用示例
const button = document.querySelector('button')!;
InteractionFeedback.addRippleEffect(button);InteractionFeedback.enhanceButton(button as HTMLButtonElement,async () => {await new Promise(resolve => setTimeout(resolve, 1000));}
);const form = document.querySelector('form')!;
InteractionFeedback.enhanceFormValidation(form);

视觉反馈优化

加载状态管理

// 加载状态管理器
class LoadingManager {private static overlay: HTMLElement;private static spinner: HTMLElement;// 初始化加载状态管理器static initialize(): void {this.createElements();this.createStyles();}// 创建加载状态元素private static createElements(): void {this.overlay = document.createElement('div');this.overlay.className = 'loading-overlay';this.spinner = document.createElement('div');this.spinner.className = 'loading-spinner';this.overlay.appendChild(this.spinner);document.body.appendChild(this.overlay);}// 创建样式private static createStyles(): void {const style = document.createElement('style');style.textContent = `.loading-overlay {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background: rgba(255, 255, 255, 0.8);display: none;justify-content: center;align-items: center;z-index: 9999;}.loading-spinner {width: 40px;height: 40px;border: 4px solid #f3f3f3;border-top: 4px solid #3498db;border-radius: 50%;animation: spin 1s linear infinite;}@keyframes spin {0% { transform: rotate(0deg); }100% { transform: rotate(360deg); }}`;document.head.appendChild(style);}// 显示加载状态static show(): void {this.overlay.style.display = 'flex';}// 隐藏加载状态static hide(): void {this.overlay.style.display = 'none';}// 包装异步操作static async wrap<T>(operation: () => Promise<T>,delay: number = 300): Promise<T> {const startTime = Date.now();this.show();try {const result = await operation();const elapsed = Date.now() - startTime;if (elapsed < delay) {await new Promise(resolve => setTimeout(resolve, delay - elapsed));}return result;} finally {this.hide();}}
}// 使用示例
LoadingManager.initialize();// 包装异步操作
async function fetchData(): Promise<any> {return LoadingManager.wrap(async () => {const response = await fetch('/api/data');return response.json();});
}

错误处理优化

错误提示管理

// 错误提示管理器
class ErrorManager {private static container: HTMLElement;// 初始化错误管理器static initialize(): void {this.createContainer();this.createStyles();this.setupGlobalErrorHandler();}// 创建错误提示容器private static createContainer(): void {this.container = document.createElement('div');this.container.className = 'error-container';document.body.appendChild(this.container);}// 创建样式private static createStyles(): void {const style = document.createElement('style');style.textContent = `.error-container {position: fixed;top: 20px;right: 20px;z-index: 9999;}.error-message {background: #ff5252;color: white;padding: 15px 20px;border-radius: 4px;margin-bottom: 10px;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);animation: slide-in 0.3s ease-out;}@keyframes slide-in {from { transform: translateX(100%); }to { transform: translateX(0); }}`;document.head.appendChild(style);}// 设置全局错误处理private static setupGlobalErrorHandler(): void {window.onerror = (message, source, line, column, error) => {this.showError(`发生错误: ${message}`);};window.onunhandledrejection = (event) => {this.showError(`未处理的Promise错误: ${event.reason}`);};}// 显示错误信息static showError(message: string, duration: number = 5000): void {const errorElement = document.createElement('div');errorElement.className = 'error-message';errorElement.textContent = message;this.container.appendChild(errorElement);setTimeout(() => {errorElement.style.animation = 'slide-out 0.3s ease-in forwards';setTimeout(() => errorElement.remove(), 300);}, duration);}// 处理API错误static handleApiError(error: any): void {if (error.response) {switch (error.response.status) {case 400:this.showError('请求参数错误');break;case 401:this.showError('未授权,请重新登录');break;case 403:this.showError('没有权限访问该资源');break;case 404:this.showError('请求的资源不存在');break;case 500:this.showError('服务器内部错误');break;default:this.showError('发生未知错误');}} else if (error.request) {this.showError('网络请求失败,请检查网络连接');} else {this.showError(`发生错误: ${error.message}`);}}
}// 使用示例
ErrorManager.initialize();// 显示错误信息
ErrorManager.showError('操作失败,请重试');// 处理API错误
try {await fetch('/api/data');
} catch (error) {ErrorManager.handleApiError(error);
}

离线体验优化

Service Worker管理

// Service Worker管理器
class ServiceWorkerManager {private static registration: ServiceWorkerRegistration | null = null;// 注册Service Workerstatic async register(scriptUrl: string): Promise<void> {if ('serviceWorker' in navigator) {try {this.registration = await navigator.serviceWorker.register(scriptUrl);console.log('Service Worker注册成功');this.setupUpdateFlow();} catch (error) {console.error('Service Worker注册失败:', error);}}}// 设置更新流程private static setupUpdateFlow(): void {if (!this.registration) return;// 检查更新this.registration.addEventListener('updatefound', () => {const newWorker = this.registration!.installing;if (newWorker) {newWorker.addEventListener('statechange', () => {if (newWorker.state === 'installed' &&navigator.serviceWorker.controller) {this.showUpdateNotification();}});}});}// 显示更新提示private static showUpdateNotification(): void {const notification = document.createElement('div');notification.className = 'update-notification';notification.innerHTML = `<p>有新版本可用</p><button onclick="location.reload()">立即更新</button>`;document.body.appendChild(notification);}// 预缓存资源static async precacheResources(resources: string[]): Promise<void> {const cache = await caches.open('app-cache-v1');await cache.addAll(resources);}// 清理旧缓存static async cleanupOldCaches(): Promise<void> {const cacheNames = await caches.keys();const currentCaches = ['app-cache-v1'];for (const cacheName of cacheNames) {if (!currentCaches.includes(cacheName)) {await caches.delete(cacheName);}}}
}// Service Worker脚本示例
const serviceWorkerScript = `const CACHE_NAME = 'app-cache-v1';const OFFLINE_PAGE = '/offline.html';self.addEventListener('install', (event) => {event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.add(OFFLINE_PAGE)));});self.addEventListener('fetch', (event) => {event.respondWith(fetch(event.request).catch(() => {return caches.match(event.request).then(response => {if (response) {return response;}return caches.match(OFFLINE_PAGE);});}));});self.addEventListener('activate', (event) => {event.waitUntil(caches.keys().then(cacheNames => {return Promise.all(cacheNames.filter(cacheName => cacheName !== CACHE_NAME).map(cacheName => caches.delete(cacheName)));}));});
`;// 使用示例
// 注册Service Worker
ServiceWorkerManager.register('/sw.js');// 预缓存资源
ServiceWorkerManager.precacheResources(['/','/index.html','/styles.css','/app.js','/offline.html'
]);

最佳实践与建议

  1. 感知性能优化

    • 使用骨架屏提供视觉占位
    • 实现渐进式加载
    • 提供明确的进度反馈
    • 优化首屏加载体验
  2. 交互响应优化

    • 提供即时视觉反馈
    • 实现平滑的动画过渡
    • 优化表单交互体验
    • 减少输入延迟
  3. 视觉反馈优化

    • 使用合适的加载指示器
    • 实现优雅的状态转换
    • 提供清晰的操作结果反馈
    • 保持界面的视觉连续性
  4. 错误处理优化

    • 提供友好的错误提示
    • 实现优雅的错误恢复
    • 保持用户数据不丢失
    • 提供问题解决建议
  5. 离线体验优化

    • 实现离线功能支持
    • 优化弱网络下的体验
    • 提供数据同步机制
    • 实现渐进式Web应用

总结

用户体验性能优化是一个持续的过程,需要从用户的角度出发,关注以下几个方面:

  1. 提升感知性能
  2. 优化交互响应
  3. 改进视觉反馈
  4. 完善错误处理
  5. 增强离线体验

通过这些优化策略的综合运用,可以显著提升用户对应用的满意度和使用体验。

学习资源

  1. 用户体验设计指南
  2. 前端性能优化最佳实践
  3. Progressive Web Apps开发指南
  4. 交互设计模式
  5. 离线应用开发策略

如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

工程化与框架系列(23)--前端性能优化(下)

前端性能优化&#xff08;用户体验&#xff09; &#x1f3a8; 引言 用户体验&#xff08;UX&#xff09;性能优化是前端性能优化的重要组成部分。本文将探讨如何通过优化用户体验相关的性能指标&#xff0c;提升用户对应用的满意度&#xff0c;包括感知性能、交互响应、视觉…...

使用 Elasticsearch 进行集成测试初始化​​数据时的注意事项

作者&#xff1a;来自 Elastic piotrprz 在创建应该使用 Elasticsearch 进行搜索、数据聚合或 BM25/vector/search 的软件时&#xff0c;创建至少少量的集成测试至关重要。虽然 “模拟索引” 看起来很诱人&#xff0c;因为测试甚至可以在几分之一秒内运行&#xff0c;但它们实际…...

自然语言模型(NLP)介绍

一、自然语言模型概述 自然语言模型&#xff08;NLP&#xff09;通过模拟人类语言理解和生成能力&#xff0c;已成为人工智能领域的核心技术。近年来&#xff0c;以DeepSeek、GPT-4、Claude等为代表的模型在技术突破和应用场景上展现出显著优势。例如&#xff0c;DeepSeek通过…...

解决:Word 保存文档失败,重启电脑后,Word 在试图打开文件时遇到错误

杀千刀的微软&#xff0c;设计的 Word 是个几把&#xff0c;用 LaTex 写完公式&#xff0c;然后保存&#xff0c;卡的飞起 我看文档卡了很久&#xff0c;就关闭文档&#xff0c;然后 TMD 脑抽了重启电脑 重启之后&#xff0c;文档打不开了&#xff0c;显示 杀千刀的&#xff…...

Android进程间通信方式之AIDL

Android 进程间通信&#xff08;IPC&#xff09;有多种方式&#xff0c;其中 AIDL&#xff08;Android Interface Definition Language&#xff09; 是最常用的一种&#xff0c;特别适用于 客户端-服务端&#xff08;Client-Server&#xff09;模型&#xff0c;当多个应用或进程…...

基于MD5分块哈希的前端图片重复检测方案

一、需求背景 在Web应用中处理用户图片上传时&#xff0c;我们需要解决两个核心问题&#xff1a; 避免重复文件占用存储空间 提升上传效率减少带宽消耗 传统方案直接上传后校验&#xff0c;存在以下缺陷&#xff1a; 重复文件仍然消耗上传时间 服务器重复校验增加计算压力…...

【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题

【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题 1、HarmonyOS 有关webview Header无法更新的问题&#xff1f; 业务A页面 打开 webivew B页面&#xff0c;第一次打开带了header请求&#xff0c;然后退出webview B页面…...

胜软科技冲刺北交所一年多转港股:由盈转亏,毛利率大幅下滑

《港湾商业观察》施子夫 近期&#xff0c;山东胜软科技股份有限公司&#xff08;以下简称&#xff0c;胜软科技&#xff09;递表港交所获受理&#xff0c;独家保荐机构为广发证券&#xff08;香港&#xff09;。 在赴港上市之前&#xff0c;胜软科技还曾谋求过A股上市&#x…...

【JavaSE-7】方法的使用

1、方法的概念和使用 1.1、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元&#xff0c;类似于 C语言中的函数&#xff0c;方法存在的意义&#xff1a; 是能够模块化的组织代码(当代码规模比较复杂的时候).做到代码被重复使用, 一份代码可以在多个位置…...

Modbus TCP转Profibus DP协议转换网关赋能玻璃生产企业设备协同运作

一、案例背景 在玻璃生产行业&#xff0c;自动化控制对提升生产效率与保障产品质量起着决定性作用。一家玻璃生产企业为实现生产过程的精细化管控&#xff0c;引入了先进的自动化控制系统。其中&#xff0c;上位机电脑配备了WINCC组态软件&#xff0c;作为Modbus TCP主站&#…...

Java 大视界 -- Java 大数据在智能政务公共服务资源优化配置中的应用(118)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

C++学习之路,从0到精通的征途:入门基础

目录 一.C的第一个程序 二.命名空间 1.namespace的价值 2.命名空间的定义 3.命名空间使用 三.C的输入与输出 1.<iostream> 2.流 3.std(standard) 四.缺省参数 1.缺省参数的定义 2.全缺省/半缺省 3.声明与定义 ​五.函数重载 1.参数个数不同 2.参数类型不…...

ADC采集模块与MCU内置ADC性能对比

2.5V基准电压源&#xff1a; 1. 精度更高&#xff0c;误差更小 ADR03B 具有 0.1% 或更小的初始精度&#xff0c;而 电阻分压方式的误差主要来自电阻的容差&#xff08;通常 1% 或 0.5%&#xff09;。长期稳定性更好&#xff0c;分压电阻容易受到温度、老化的影响&#xff0c;长…...

Gartner发布2025年网络安全六大预测

文章目录 前言趋势1&#xff1a;生成式AI推动数据安全计划趋势2&#xff1a;管理机器身份趋势3&#xff1a;战术型AI趋势4&#xff1a;优化网络安全技术趋势5&#xff1a;扩大安全行为与文化计划的价值趋势6&#xff1a;应对网络安全倦怠 前言 Gartner发布2025年网络安全六大预…...

C#批量压缩并上载CSV数据文件到Box企业云盘

C# .NET 8实现Windows下批量压缩csv文件为zip文件&#xff0c;然后异步上传到box企业云服务网盘路径&#xff0c;实现异常处理和写入运行状态日志&#xff0c;参数来自ini配置文件。 C# .NET 8代码示例&#xff0c;包含INI配置读取、CSV文件压缩、Box上传、异步处理和日志记录…...

C++常见概念

第一个 C 程序 #include<iostream>using namespace std;int main() {cout << "helloworld" << endl;return 0; }命名空间 #include<stdio.h>int rand 10;int main() {printf("%d", rand);return 0; }#include<stdio.h> #…...

结构型模式---享元模式

概念 享元模式是一种结构型设计模式&#xff0c;他摒弃了在每个对象中保存所有数据的方式&#xff0c;通过共享多个对象所共有的相同状态&#xff0c;让你能在有限的内存容量中载入更多对象。享元模式将原始类中的数据分为内在状态数据和外在状态数据。 内在状态&#xff1a;就…...

2025年渗透测试面试题总结- 深某服-漏洞研究员实习(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 深信服-漏洞研究员实习 1. 在XX实习时做了什么 2. 渗透测试的思路简单描述 3. 护网中承担什么角色 4…...

(13)Anaconda 安装配置详解

1. Anaconda 简介 Anaconda 是一个用于科学计算和数据分析的 Python 发行版,它集成了 Python 解释器、大量常用的科学计算库以及强大的包管理工具。 2. Anaconda 主要特点 丰富的库集合:包含了超过 1500 个用于科学计算、数据分析、机器学习等领域的常用 Python 库,例如 N…...

MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革

随着人工智能、大模型等技术的蓬勃发展&#xff0c;生成式AI应用全面爆发。在此背景下&#xff0c;服务机器人作为大模型技术在端侧落地的关键场景&#xff0c;迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备&#xff0c;服务机器人需要应对复杂场景下的感知、决策和…...

[内网安全] Windows 域认证 — Kerberos 协议认证

&#x1f31f;想系统化学习内网渗透&#xff1f;看看这个&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;Kerberos 协议简介 Kerberos 是一种网络认证协议&#xff0c;其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。该认证过…...

[Computer Vision]实验七:图像检索

目录 一、实验内容 二、实验过程 2.1 准备数据集 2.2 SIFT特征提取 2.3 学习“视觉词典”&#xff08;vision vocabulary&#xff09; 2.4 建立图像索引并保存到数据库中 2.5 用一幅图像查询 三、实验小结 一、实验内容 实现基于颜色直方图、bag of word等方法的以图搜…...

C++之thread_local变量

C之thread_local变量_c threadlocal-CSDN博客 thread_local简介 thread_local 是 C11 为线程安全引进的变量声明符。表示对象的生命周期属于线程存储期。 线程局部存储(Thread Local Storage&#xff0c;TLS)是一种存储期(storage duration)&#xff0c;对象的存储是在…...

【国产Linux | 银河麒麟】麒麟化龙——KylinOS下载到安装一条龙服务,起飞!

&#x1f5fa;️博客地图 &#x1f4cd;一、下载地址 &#x1f4cd;二、 系统安装 本文基于Windows操作系统vmware虚拟机安装 一、下载地址 官网&#xff1a;产品试用申请国产操作系统、麒麟操作系统——麒麟软件官方网站 下载自己需要的版本&#xff0c;完成后&#xff0c…...

(接“使用js去复制网页内容的方法”)js中的execCommand怎么复制富文本内容解析

document.execCommand(copy) 是传统的剪贴板操作方法&#xff0c;但它主要用于复制纯文本内容。如果你想复制富文本内容&#xff08;包括 HTML 标签和样式&#xff09;&#xff0c;需要结合一些技巧来实现。以下是具体方法&#xff1a; 方法&#xff1a;通过创建隐藏的富文本元…...

npm ERR! code 128 npm ERR! An unknown git error occurred

【问题描述】 【问题解决】 管理员运行cmd&#xff08;右键window --> 选择终端管理员&#xff09; 执行命令 git config --global url.“https://”.insteadOf ssh://git cd 到项目目录 重新执行npm install 个人原因&#xff0c;这里执行npm install --registryhttps:…...

解决Leetcode第3470题全排列IV

3470.全排列IV 难度&#xff1a;困难 问题描述&#xff1a; 给你两个整数n和k&#xff0c;一个交替排列是前n个正整数的排列&#xff0c;且任意相邻两个元素不都为奇数或都为偶数。 返回第k个交替排列&#xff0c;并按字典序排序。如果有效的交替排列少于k个&#xff0c;则…...

MyBatis 配置文件核心

MyBatis 配置文件核心标签解析 以下是针对你的笔记中的三个核心标签的详细解析&#xff0c;帮助你全面理解它们的用途和配置逻辑。 1. properties 标签&#xff1a;动态加载外部配置 功能 将环境相关的配置&#xff08;如数据库连接、密钥等&#xff09;与 MyBatis 核心配置…...

bert模型笔记

1.各预训练模型说明 BERT模型在英文数据集上提供了两种大小的模型&#xff0c;Base和Large。Uncased是意味着输入的词都会转变成小写&#xff0c;cased是意味着输入的词会保存其大写&#xff08;在命名实体识别等项目上需要&#xff09;。Multilingual是支持多语言的&#xff0…...

微信小程序接入deepseek

先上效果 话不多说&#xff0c;直接上代码&#xff08;本人用的hbuilder Xuniapp&#xff09; <template><view class"container"><!-- 聊天内容区域 --><scroll-view class"chat-list" scroll-y :scroll-top"scrollTop":…...