JavaScript性能优化实战:从基础到高级的全面指南
作为前端开发者,掌握JavaScript性能优化是提升用户体验和职业竞争力的关键。本文将系统性地介绍JavaScript性能优化的各个方面,从基础概念到高级技巧,帮助你编写更高效的代码。
一、JavaScript性能优化基础概念
1.1 什么是JavaScript性能优化
JavaScript性能优化是指通过各种技术手段减少代码执行时间、降低内存占用、提高响应速度的过程。优化的核心目标是:
- 减少页面加载时间
- 提高代码执行效率
- 降低内存消耗
- 改善用户体验
1.2 为什么需要性能优化
优化前问题 | 优化后效果 | 用户感知 |
---|---|---|
页面加载慢 | 快速加载 | 无需等待 |
交互卡顿 | 流畅响应 | 操作顺滑 |
内存占用高 | 内存高效 | 设备不发烫 |
耗电量高 | 电量节省 | 续航更长 |
1.3 性能优化的关键指标
// 使用Performance API测量关键指标
const measurePerf = () => {// 页面加载时间const [entry] = performance.getEntriesByType("navigation");console.log(`页面加载耗时: ${entry.loadEventEnd - entry.startTime}ms`);// 首次内容绘制(FCP)const [paintEntry] = performance.getEntriesByType("paint");console.log(`首次内容绘制: ${paintEntry.startTime}ms`);// 交互响应时间const btn = document.getElementById('myButton');let startTime;btn.addEventListener('click', () => {startTime = performance.now();// 执行操作...const duration = performance.now() - startTime;console.log(`点击响应耗时: ${duration}ms`);});
};
二、JavaScript代码层面的优化
2.1 变量与数据类型优化
2.1.1 选择合适的数据类型
// 不推荐:使用对象存储简单键值对
const user = {id: 1,name: 'John',active: true
};// 推荐:使用Map存储频繁增删的键值对
const userMap = new Map();
userMap.set('id', 1);
userMap.set('name', 'John');
userMap.set('active', true);// 当需要频繁检查存在性时,使用Set而不是数组
const tags = ['js', 'css', 'html'];
// 不推荐
if (tags.includes('js')) { /* ... */ }// 推荐
const tagSet = new Set(tags);
if (tagSet.has('js')) { /* ... */ }
2.1.2 变量作用域优化
function processData(data) {// 不推荐:在循环中重复计算不变的量for (let i = 0; i < data.length; i++) {const result = data[i] * Math.PI; // Math.PI每次循环都访问console.log(result);}// 推荐:缓存不变的值const pi = Math.PI;for (let i = 0; i < data.length; i++) {const result = data[i] * pi;console.log(result);}
}
2.2 循环与迭代优化
2.2.1 循环性能对比
循环类型 | 适用场景 | 性能 | 可读性 | 示例 |
---|---|---|---|---|
for | 需要索引/已知长度 | 最高 | 中等 | for(let i=0; i<arr.length; i++) |
for…of | 遍历可迭代对象 | 高 | 好 | for(const item of arr) |
forEach | 函数式编程 | 中 | 好 | arr.forEach(item => {}) |
while | 条件循环 | 高 | 中等 | while(i < 10) { i++ } |
map | 返回新数组 | 低 | 好 | arr.map(x => x*2) |
// 循环优化示例
const largeArray = new Array(1000000).fill(1);// 不推荐:每次访问length属性
for (let i = 0; i < largeArray.length; i++) {// ...
}// 推荐:缓存length
const len = largeArray.length;
for (let i = 0; i < len; i++) {// ...
}// 更推荐:倒序循环(某些引擎更快)
for (let i = largeArray.length; i--; ) {// ...
}
2.3 函数优化
2.3.1 函数节流与防抖
// 防抖:连续触发时只执行最后一次
function debounce(fn, delay) {let timer;return function(...args) {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};
}// 节流:固定时间间隔执行一次
function throttle(fn, interval) {let lastTime = 0;return function(...args) {const now = Date.now();if (now - lastTime >= interval) {fn.apply(this, args);lastTime = now;}};
}// 实际应用:搜索框输入
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function(e) {console.log('发送搜索请求:', e.target.value);
}, 300));// 实际应用:窗口滚动
window.addEventListener('scroll', throttle(function() {console.log('处理滚动事件');
}, 200));
三、DOM操作优化
3.1 重排(Reflow)与重绘(Repaint)优化
3.1.1 什么是重排和重绘
- 重排(Reflow): 当DOM的变化影响了元素的几何属性(如宽高、位置),浏览器需要重新计算元素的几何属性,并重新构建渲染树。
- 重绘(Repaint): 当元素的外观属性(如颜色、背景)发生变化,但不影响布局时,浏览器只需重绘受影响的部分。
3.1.2 减少重排和重绘的策略
// 不推荐:多次单独修改样式
const element = document.getElementById('box');
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';// 推荐1:使用cssText批量修改
element.style.cssText = 'width:100px; height:100px; margin:10px;';// 推荐2:添加类名批量修改样式
// CSS: .big-box { width:100px; height:100px; margin:10px; }
element.classList.add('big-box');// 复杂DOM操作时使用文档片段
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {const div = document.createElement('div');div.textContent = `Item ${i}`;fragment.appendChild(div);
}
document.body.appendChild(fragment);
3.2 事件委托优化
// 不推荐:为每个列表项绑定事件
const items = document.querySelectorAll('.item');
items.forEach(item => {item.addEventListener('click', function() {console.log('点击了:', this.textContent);});
});// 推荐:使用事件委托
document.querySelector('.list-container').addEventListener('click', function(e) {if (e.target.classList.contains('item')) {console.log('点击了:', e.target.textContent);}
});
四、内存管理与垃圾回收
4.1 常见内存泄漏场景
- 意外的全局变量
function leak() {leakedVar = '这是一个全局变量'; // 忘记使用var/let/const
}
- 被遗忘的定时器或回调
const data = fetchData();
setInterval(() => {const node = document.getElementById('node');if (node) {node.innerHTML = JSON.stringify(data);}
}, 1000);
// 即使node被移除,定时器仍在执行且持有data引用
- DOM引用
const elements = {button: document.getElementById('button'),image: document.getElementById('image')
};// 即使从DOM中移除了这些元素,elements对象仍然持有引用
4.2 内存优化技巧
// 1. 使用弱引用
const weakMap = new WeakMap();
let domNode = document.getElementById('node');
weakMap.set(domNode, { data: 'some data' });// 当domNode被移除后,WeakMap中的条目会被自动清除// 2. 及时清理事件监听器
class MyComponent {constructor() {this.handleClick = this.handleClick.bind(this);this.button = document.getElementById('myButton');this.button.addEventListener('click', this.handleClick);}handleClick() {console.log('Button clicked');}cleanup() {this.button.removeEventListener('click', this.handleClick);}
}// 3. 使用requestAnimationFrame替代setInterval
function animate() {// 动画逻辑requestAnimationFrame(animate);
}
animate();// 需要停止时只需不再调用requestAnimationFrame
五、异步代码优化
5.1 Promise优化技巧
// 1. 并行执行不依赖的Promise
async function fetchAllData() {// 不推荐:顺序执行(耗时较长)// const user = await fetchUser();// const posts = await fetchPosts();// const comments = await fetchComments();// 推荐:并行执行const [user, posts, comments] = await Promise.all([fetchUser(),fetchPosts(),fetchComments()]);return { user, posts, comments };
}// 2. 避免Promise嵌套地狱
// 不推荐
getUser(userId).then(user => {getPosts(user.id).then(posts => {getComments(posts[0].id).then(comments => {console.log(comments);});});});// 推荐
getUser(userId).then(user => getPosts(user.id)).then(posts => getComments(posts[0].id)).then(comments => console.log(comments)).catch(error => console.error(error));// 更推荐:使用async/await
async function loadData() {try {const user = await getUser(userId);const posts = await getPosts(user.id);const comments = await getComments(posts[0].id);console.log(comments);} catch (error) {console.error(error);}
}
5.2 Web Worker优化计算密集型任务
// 主线程代码
const worker = new Worker('worker.js');worker.postMessage({ type: 'CALCULATE', data: largeArray
});worker.onmessage = function(e) {console.log('计算结果:', e.data.result);worker.terminate(); // 使用完后关闭worker
};// worker.js
self.onmessage = function(e) {if (e.data.type === 'CALCULATE') {const result = heavyCalculation(e.data.data);self.postMessage({ result });}
};function heavyCalculation(data) {// 执行耗时计算return data.reduce((acc, val) => acc + val, 0);
}
六、网络请求优化
6.1 请求合并与缓存策略
// 1. 请求合并
const requestCache = new Map();async function getData(url) {// 检查缓存if (requestCache.has(url)) {return requestCache.get(url);}// 检查是否有正在进行的相同请求if (window.ongoingRequests && window.ongoingRequests[url]) {return window.ongoingRequests[url];}// 创建新请求if (!window.ongoingRequests) window.ongoingRequests = {};window.ongoingRequests[url] = fetch(url).then(response => response.json()).then(data => {// 缓存结果requestCache.set(url, data);// 清除进行中的请求标记delete window.ongoingRequests[url];return data;}).catch(error => {delete window.ongoingRequests[url];throw error;});return window.ongoingRequests[url];
}// 2. 使用Service Worker缓存
// service-worker.js
self.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(response => {// 缓存命中则返回缓存,否则发起请求return response || fetch(event.request);}));
});
6.2 数据分页与懒加载
// 无限滚动懒加载实现
let isLoading = false;
let currentPage = 1;window.addEventListener('scroll', throttle(async () => {const { scrollTop, clientHeight, scrollHeight } = document.documentElement;const isNearBottom = scrollTop + clientHeight >= scrollHeight - 500;if (isNearBottom && !isLoading) {isLoading = true;try {const data = await fetchPageData(currentPage + 1);if (data.length) {currentPage++;appendItems(data);}} catch (error) {console.error('加载失败:', error);} finally {isLoading = false;}}
}, 200));async function fetchPageData(page) {const response = await fetch(`/api/items?page=${page}`);return response.json();
}function appendItems(items) {const container = document.getElementById('items-container');const fragment = document.createDocumentFragment();items.forEach(item => {const div = document.createElement('div');div.className = 'item';div.textContent = item.name;fragment.appendChild(div);});container.appendChild(fragment);
}
七、高级优化技巧
7.1 WebAssembly性能优化
// 1. 加载并运行WebAssembly模块
async function initWasm() {const response = await fetch('optimized.wasm');const buffer = await response.arrayBuffer();const module = await WebAssembly.compile(buffer);const instance = await WebAssembly.instantiate(module);return instance.exports;
}// 使用WebAssembly执行计算密集型任务
initWasm().then(exports => {const { heavyCalculation } = exports;// 对比JavaScript和WebAssembly性能console.time('JavaScript');const jsResult = jsHeavyCalculation(1000000);console.timeEnd('JavaScript');console.time('WebAssembly');const wasmResult = heavyCalculation(1000000);console.timeEnd('WebAssembly');console.log('结果对比:', { jsResult, wasmResult });
});function jsHeavyCalculation(n) {let result = 0;for (let i = 0; i < n; i++) {result += Math.sqrt(i) * Math.sin(i);}return result;
}
7.2 性能分析工具使用
// 使用console.time和console.timeEnd测量代码执行时间
console.time('arrayOperation');
const largeArray = new Array(1000000).fill(null).map((_, i) => i);
const filtered = largeArray.filter(x => x % 2 === 0).map(x => x * 2);
console.timeEnd('arrayOperation');// 使用performance.mark进行更精确的测量
performance.mark('startProcess');
processData();
performance.mark('endProcess');
performance.measure('processDuration', 'startProcess', 'endProcess');
const measures = performance.getEntriesByName('processDuration');
console.log('处理耗时:', measures[0].duration + 'ms');// 使用PerformanceObserver监控性能指标
const observer = new PerformanceObserver((list) => {for (const entry of list.getEntries()) {console.log(`${entry.name}: ${entry.startTime}`);}
});
observer.observe({ entryTypes: ['measure', 'mark'] });
八、框架特定的优化技巧
8.1 React性能优化
// 1. 使用React.memo避免不必要的渲染
const MyComponent = React.memo(function MyComponent({ data }) {return <div>{data}</div>;
});// 2. 使用useMemo和useCallback
function ParentComponent({ items }) {const [count, setCount] = useState(0);// 避免每次渲染都重新创建函数const handleClick = useCallback(() => {setCount(c => c + 1);}, []);// 避免每次渲染都重新计算const processedItems = useMemo(() => {return items.filter(item => item.active).map(item => ({...item,computed: heavyComputation(item.value)}));}, [items]);return (<div><button onClick={handleClick}>点击 {count}</button><ChildComponent items={processedItems} /></div>);
}// 3. 虚拟列表优化长列表渲染
import { FixedSizeList as List } from 'react-window';const BigList = ({ data }) => (<Listheight={500}itemCount={data.length}itemSize={50}width={300}>{({ index, style }) => (<div style={style}>{data[index].name}</div>)}</List>
);
8.2 Vue性能优化
<template><!-- 1. 使用v-once渲染静态内容 --><div v-once>{{ staticContent }}</div><!-- 2. 使用计算属性缓存结果 --><div>{{ computedData }}</div><!-- 3. 使用虚拟滚动优化长列表 --><RecycleScrollerclass="scroller":items="largeList":item-size="50"key-field="id"v-slot="{ item }"><div>{{ item.name }}</div></RecycleScroller>
</template><script>
export default {data() {return {staticContent: '这段内容不会改变',largeList: [] // 大数据量数组};},computed: {// 只有依赖变化时才会重新计算computedData() {return this.largeList.filter(item => item.active);}},// 4. 使用函数式组件优化无状态组件components: {FunctionalButton: {functional: true,render(h, { props, children }) {return h('button', props, children);}}}
};
</script>
九、性能优化模式对比
9.1 数据获取策略对比
策略 | 优点 | 缺点 | 适用场景 | 代码复杂度 |
---|---|---|---|---|
全量加载 | 实现简单,数据完整 | 首屏慢,资源浪费 | 小数据量 | 低 |
分页加载 | 首屏快,资源节省 | 需要多次请求 | 列表数据 | 中 |
无限滚动 | 无缝体验 | 内存占用增加 | 社交媒体 | 中高 |
按需加载 | 资源最省 | 实现复杂 | 大型应用 | 高 |
预加载 | 体验流畅 | 可能浪费资源 | 关键路径 | 中 |
9.2 状态管理方案对比
方案 | 内存使用 | 执行速度 | 可维护性 | 学习曲线 | 适用场景 |
---|---|---|---|---|---|
本地状态 | 低 | 快 | 简单组件 | 低 | 简单UI状态 |
Context API | 中 | 中 | 中 | 中 | 中小应用 |
Redux | 高 | 慢 | 高 | 高 | 大型复杂应用 |
MobX | 中高 | 快 | 高 | 中高 | 响应式需求 |
Recoil | 中 | 快 | 高 | 中 | 原子状态管理 |
十、性能优化检查清单
10.1 开发阶段检查项
-
代码层面
- 避免不必要的计算和重复操作
- 使用合适的数据结构和算法
- 减少全局变量的使用
- 优化循环和迭代操作
-
DOM操作
- 批量DOM操作使用文档片段
- 使用事件委托减少事件监听器
- 避免强制同步布局(读取offsetTop等)
-
网络请求
- 合并请求减少HTTP请求次数
- 使用缓存策略(Service Worker等)
- 压缩传输数据(JSON、图片等)
10.2 发布前检查项
-
构建优化
- 代码拆分和懒加载
- Tree-shaking移除未使用代码
- 压缩和混淆代码
-
性能测试
- Lighthouse评分检查
- 关键性能指标测量(FCP、TTI等)
- 内存泄漏检查
-
监控准备
- 添加性能监控代码
- 错误跟踪系统集成
- 真实用户监控(RUM)设置
结语
JavaScript性能优化是一个持续的过程,需要开发者从代码编写、框架使用、网络请求、内存管理等多个维度进行考虑。本文涵盖了从基础到高级的各种优化技巧,但实际应用中需要根据具体场景选择合适的优化策略。
收藏?算了算了,这么优秀的文章你肯定记不住!
相关文章:
JavaScript性能优化实战:从基础到高级的全面指南
作为前端开发者,掌握JavaScript性能优化是提升用户体验和职业竞争力的关键。本文将系统性地介绍JavaScript性能优化的各个方面,从基础概念到高级技巧,帮助你编写更高效的代码。 一、JavaScript性能优化基础概念 1.1 什么是JavaScript性能优…...
CertiK创始人顾荣辉出席Unchained Summit,探讨Web3.0安全与合规路径
4月28日,CertiK联合创始人、哥伦比亚大学教授顾荣辉出席迪拜Unchained Summit峰会并发表主题演讲,探讨Web3.0在创新与安全间的平衡,引发网易科技、中国财经时报、腾讯网、新浪财经等多家知名媒体的关注和报道。 作为迪拜最重要的峰会之一&am…...
企业出海降本:如何将应用从 AWS EC2 快速无缝迁移至DigitalOcean Droplet
企业出海已经成为目前最热门的趋势。然而不论你是做跨境电商,还是短剧出海,或处于最热门的AI 赛道,你都需要使用海外的云主机或GPU云服务。海外一线的云服务平台尽管覆盖区域广泛,但是往往费用成本较高。所以降本始终是企业出海关…...
java练习2
package a01_第一次练习.a02_计算输入天数;import java.text.ParseException; import java.time.Duration; import java.time.LocalDateTime; import java.util.Scanner;public class Test {public static void main(String[] args) throws ParseException {//当前时间LocalDat…...
PDM是什么?PDM有什么用?怎么选PDM?2025制造PDM/PLM系统盘点(4000字)
(文章来自CRDE PDM研究中心) 摘要 PDM是制造企业产品数据管理的核心工具,并逐渐发展出了PLM、云PLM等新形态,在功能增加的同时成本也有大幅降低,已经成为企业研发管理的最优选择,并逐渐被有产品创新需求的…...
TiDB 可观测性最佳实践
TiDB 介绍 TiDB,由 PingCAP 公司自主研发的开源分布式关系型数据库,是一款创新的 HTAP 数据库产品,它融合了在线事务处理(OLTP)和在线分析处理(OLAP)的能力,支持水平扩容和缩容&…...
8.idea创建maven项目(使用Log4j日志记录框架+Log4j 介绍)
8.idea创建maven项目(使用Log4j日志记录框架Log4j 介绍) 在 IntelliJ IDEA 的 Maven 项目中引入了 Log4j,并配置了日志同时输出到控制台和文件。 Log4j 提供了灵活的日志配置选项,可以根据项目需求调整日志级别、输出目标和格式。 1. 创建 Maven 项目 …...
Linux 命名管道+日志
一、命名管道 1.1 进程通信的前提:先让不同进程看到同一份资源; 1.2 如何确保两个进程打开的是同一个文件:同路径下同一文件名; 1.3 命名管道:通过路径文件名确保这个份资源的唯一性; 1.4 接口…...
c/c++之信号处理<signal.h>
该库提供了一组用于处理信号的函数和宏。信号是由操作系统或程序本身生成的一种异步事件,用于通知某些事件的发生,例如非法操作、用户中断等。 信号 信号是进程之间通信的重要方式。信号是一种异步通知机制,由操作系统或其他进程发送给当前进…...
基于PyTorch的图像分类特征提取与模型训练文档
概述 本代码实现了一个基于PyTorch的图像特征提取与分类模型训练流程。核心功能包括: 使用预训练ResNet18模型进行图像特征提取 将提取的特征保存为标准化格式 基于提取的特征训练分类模型 代码结构详解 1. 库导入 import torch import torch.nn as nn import…...
DDoS vs CC攻击:哪种对服务器威胁更大?
引言 DDoS(分布式拒绝服务)与CC(Challenge Collapsar)攻击是两种常见的网络攻击手段,均会导致服务器资源耗尽、服务中断。但它们的攻击原理、防御难度及危害程度存在显著差异。本文将从技术原理、攻击效果、防御成本等…...
Weiss Robotics的WPG与WSG系列紧凑型机器人夹爪,精准、灵活、高效
在自动化和智能制造领域,Weiss Robotics 以其创新的智能抓取系统而受到广泛认可。本文将重点介绍 Weiss Robotics 的两大产品系列:WPG 系列和 WSG 系列。这些产品系列凭借其先进的技术特性,为各行各业的自动化需求提供了高效、灵活的解决方案…...
引力透镜效应添加光线弯曲程度可视化层的MATLAB代码
物理实现要点: 雅可比矩阵计算 通过数值梯度计算偏转场的空间导数: 放大率μ反映像的亮度增强倍数 动态范围处理 使用对数压缩μ值范围:μ_vis log10(1μ),避免高放大率区域饱和 多物理量联合显示 红圈标注爱因…...
OpenCV 图形API(71)图像与通道拼接函数-----从图像(GMat)中裁剪出一个矩形区域的操作函数 crop()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 裁剪一个2D矩阵。 该函数根据给定的 cv::Rect 裁剪矩阵。 输出矩阵必须与输入矩阵具有相同的深度,大小由给定的矩形大小指定。 注意…...
tarjan缩点+强联通分量
【模板】缩点https://www.luogu.com.cn/problem/P3387 首先我们要理解这道题为什么要用缩点 题目说的是有向图,如果无环的话就可以用DP来解决了 由于可以走重复的点,所以一个环上的点可以看成是一个点,它的点权就等于该环上所有点的点权之…...
tornado_登录页面(案例)
目录 1.基础知识编辑 2.脚手架(模版) 3.登录流程图(processon) 4.登录表单 4.1后(返回值)任何值:username/password (4.1.1)app.py (4.1.2ÿ…...
Educational Codeforces Round 178 (Rated for Div. 2)
ABC 略 D n个数互质,即n个数都是质数,预处理前4e5个质数,原排列从大到小排序求前缀和,质数求前缀和,从后往前循环第一个前者前缀和能大于等于后者就是留下的i个数。 #include<bits/stdc.h> #define int long …...
从Transformer原理角度来看,prompt设置输出字数限制会生效的原因
从Transformer原理角度来看,prompt设置输出字数限制会生效的原因 1. 生成过程的控制 Transformer在生成文本时是一个自回归的过程,它从起始标记开始,逐个生成下一个单词或标记。在这个过程中,模型会根据已经生成的文本和自身的参数来预测下一个可能的标记的概率分布。当设…...
WEB漏洞--CSRF及SSRF案例
CSRF案例 原理 检测是否存在CSRF(跨站请求伪造)漏洞 1. 手动测试 构造恶意请求:创建一个恶意网页或电子邮件,包含指向目标网站的恶意请求(如更改密码或发送消息的URL)。诱使用户访问该恶意请求,…...
Android开发——实现一个计算器
目录 代码讲解 activity_calculator.xmld代码讲解 1. 根布局(LinearLayout) 2. 显示区域(TextView) 3. 按钮区域(GridLayout) 4. 清除和删除按钮 5. 数字和操作符按钮 6. 其他行的按钮 7. 最后一行…...
23G显存可以跑多大尺寸的Qwen3?
随着阿里Qwen3系列大模型的发布,开发者们对如何在有限显存下部署不同尺寸的模型尤为关注。本文基于Qwen3的技术特性和实际测试数据,探讨在23G显存环境下可运行的模型选择及优化策略。 不过由于咱财力有限,只有一张A100,还不是空的,目前只有23G的显存。 那么这23G显存能跑…...
网络通讯【QTcpServer、QTcpSocket、QAbstractSocket】
目录 QTcpServer class简单描述成员函数和信号 QTcpSocket Class详细描述成员函数和信号 QAbstractSocket Class详细描述成员函数和信号成员函数说明文档 QT实现服务器和客户端通讯服务器端:通讯流程原代码 客户端通信流程原代码 QTcpServer class header: #includ…...
std::functional 类是干什么用的?
author: hjjdebug date: 2025年 04月 29日 星期二 15:54:53 CST description: std::functional 类是干什么用的? 文章目录 1.functional 对象的概念2.functional 对象存在的意义2.1 为什么要把接口再封一层?2.2 c中函数参数可以不用回调函数, 而改用func…...
人事管理系统6
模糊查询 DepartmentMapper.xml : <select id"findDepartmentListByName" resultMap"BaseResultMap"> select <include refid"Base_Column_List"/> from department where dname like %${dname}% /*where dname like con…...
链表的中间节点
这题需要用到快慢指针的思想,快指针叫fast,慢指针是slow,快指针每次往后移两个节点,slow只移动一个节点,这样子fast的速度是slow的两遍,当fast遍历完链表,slow才遍历一半,正好就在中…...
【学习学学】城市群与都市圈是什么?怎么
城市群与都市圈是什么?怎么发展 这些年城市群,都市圈的概念被逐渐提了出来,也是未来我国即将重点发展的对象之一。 因此,身边有一些朋友在问,城市群与都市圈有什么区别?哪个对城市发展影响更大?…...
【深度学习与大模型基础】第14章-分类任务与经典分类算法
Part 1:什么是分类任务? 1.1 分类就是“贴标签” 想象你有一堆水果,有苹果🍎、橘子🍊、香蕉🍌,你的任务是让机器学会自动判断一个新水果属于哪一类——这就是分类(Classification&…...
第十五章:预训练大语言模型
目录 15.1 数据准备 15.1.1 数据预处理 15.1.2 数据调度 15.2 模型架构 15.2.1 主流架构 一、编码器架构(Encoder-only,以 BERT 为代表) 核心特点: 代表模型:BERT、RoBERTa、ALBERT 典型应用: 二…...
万象生鲜配送系统代码2025年4月29日更新日志
亲爱的用户:万象生鲜配送系统始终致力于为您提供更优质、高效的服务体验。经过我们技术团队的不懈努力,万象生鲜配送系统在 2025 年 4 月迎来了一次重大更新。本次更新涵盖了多个方面,包括功能新增、性能优化以及问题修复,旨在进一…...
Mac 创建QT按钮以及一些操作
在创建QT项目好 后我们打开mainwindow.cpp,下面所示的代码都是在这个cpp文件里面因为它是窗口的入口函数 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QPushButton>//按钮的头文件MainWindow::MainWindow(QWidget *pa…...
C++学习之shell高级和正则表达式
目录 1.正则表达式 2.C中使用正则 3.复习 4.sort命令 5.uniq命令 6.wc命令 7.grep命令 8.find命令 9.xargs命令 10.sed命令 11.awk命令 12.crontab 1.正则表达式 1 管道 使用| 将多个命令拼接在一起 原理,就是将前一个命令的标准输出作为后一个…...
SpringBoot获取用户信息常见问题(密码屏蔽、驼峰命名和下划线命名的自动转换)
文章目录 一、不返回password字段二、返回的createTime和updateTime为空原因解决:开启驼峰命名和下划线命名的自动转换 一、不返回password字段 在字段上面添加JsonIgnore注解即可 JsonIgnore // 在把对象序列化成json字符串时,忽略该字段 private Str…...
优化PCB Via Stub系列(2) – 运用U-Turn Via设计破解阻抗匹配困境,改善信号完整性
在PCB设计中,往往透过制程改善如背钻、盲孔或埋孔,来消除不必要的Via stub,可是多出来的制造成本会压低产品的毛利,可是又有什么办法可以不透过制程改善以缩小Via stub带来的SI困扰呢? 本周我们来讲从Layout布局的角度…...
飞鸟游戏模拟器 1.0.3 | 完全免费无广告,内置大量经典童年游戏,重温美好回忆
飞鸟游戏模拟器是一款专为安卓用户设计的免费游戏模拟器,内置了大量经典的童年游戏。该模拟器拥有丰富的游戏资源,目前已有约20,000款游戏,包括多种类型如冒险、动作、角色扮演等。用户可以直接搜索查找想要玩的游戏进行下载并启动。游戏库中…...
钓鱼网页散播银狐木马,远控后门威胁终端安全
在当今网络环境下,许多人都有通过搜索引擎下载应用程序的习惯,虽然这种方式简单又迅速,但这也可能被不法分子所利用,通过设置钓鱼网站来欺骗用户。这些钓鱼网站可能会通过各种方式吸引用户点击,从而进行病毒的传播&…...
一文读懂 JavaScript 中的深浅拷贝
在 JavaScript 编程里,深浅拷贝是处理数据时极为关键的概念。理解它们的差异,能帮我们规避许多数据操作上的 “陷阱”。今天,咱们就借助简单的 “abc” 相关示例,深入探索深浅拷贝的奥秘,并且通过在浏览器控制台输出结…...
5G技术在工业4.0中的应用:连接未来,驱动智能制造
5G技术在工业4.0中的应用:连接未来,驱动智能制造 引言 工业4.0,作为第四次工业革命的核心,已经在全球范围内掀起了智能制造的浪潮。它不仅包括了自动化生产、智能物流、云计算和大数据的应用,更是融合了互联网、物联网…...
驱动开发硬核特训 · Day 25 (附加篇):从设备树到驱动——深入理解Linux时钟子系统的实战链路
一、前言 在嵌入式Linux开发中,无论是CPU、外设控制器,还是简单的GPIO扩展器,大多数硬件模块都离不开时钟信号的支撑。 时钟子系统(Clock Subsystem),作为Linux内核中基础设施的一部分,为设备…...
数据结构---单链表的增删查改
前言: 经过了几个月的漫长岁月,回头时年迈的小编发现,数据结构的内容还没有写博客,于是小编赶紧停下手头的活动,补上博客以洗清身上的罪孽 目录 前言 概念: 单链表的结构 我们设定一个哨兵位头节点给链…...
【codeforces 2104D,E】欧拉筛,字符串上dp
【codeforces 2104D,E】欧拉筛,字符串上dp Problem - D - Codeforces 题意: 给定一个长度为 n n n的数组 a 1 , a 2 , . . . , a n a_1, a_2, ... , a_n a1,a2,...,an,其中 2 ≤ a i ≤ 1 0 9 2 \leq a_i \leq 10^9 2≤…...
UEC++第15天|番茄插件、实现跳跃、实现背景运动
这是flyBird的第二天,做了一些简单的功能,明天继续更新 vs的番茄插件 在visual stdudio里使用可以帮助代码补全,这一篇博客写的不错,大家可以参考一下。VS2019 安装番茄助手(Visual Assist x 插件)攻略_vs…...
论文笔记-基于多层感知器(MLP)的多变量桥式起重机自适应安全制动与距离预测
《IET Cyber-Systems and Robotics》出版山东大学 Tenglong Zhang 和 Guoliang Liu 团队的研究成果,文章题为“Adaptive Safe Braking and Distance Prediction for Overhead Cranes With Multivariation Using MLP”。 摘要 桥式起重机的紧急制动及其制动距离预测是…...
[论文阅读]Adversarial Semantic Collisions
Adversarial Semantic Collisions Adversarial Semantic Collisions - ACL Anthology Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing (EMNLP) 对抗样本是相似的输入但是产生不同的模型输出,而语义冲突是对抗样本的逆…...
Redis Sentinel 和 Redis Cluster 各自的原理、优缺点及适用场景是什么?
我们来详细分析下 Redis Sentinel (哨兵) 和 Redis Cluster (集群) 这两种方案的原理和使用场景。 Redis Sentinel (哨兵) 原理: Sentinel 本身是一个或一组独立于 Redis 数据节点的进程。它的核心职责是监控一个 Redis 主从复制 (Master-Slave) 架构。多个 Sentinel 进程协同…...
面向人工智能、量子科技、人形机器人等产业,山东启动制造业创新中心培育认定
从山东省工业和信息化厅了解到,2025年山东省制造业创新中心培育和认定已启动,重点面向全省传统优势产业、新兴产业及未来产业等领域,鼓励具备条件的龙头企业牵头创建省制造业创新中心。 今年,山东重点面向全省冶金、化工、轻工、…...
无锡哲讯科技:SAP财务系统——赋能企业智慧财务管理
数字化时代,财务管理的新挑战 在全球化竞争和数字经济快速发展的背景下,企业财务管理正面临前所未有的挑战。传统的财务核算方式效率低下、数据孤岛严重、决策滞后,难以满足现代企业高效运营的需求。如何实现财务数据的实时整合࿱…...
Linux命令使用记录(自用)
阿里开源镜像站:https://developer.aliyun.com/mirror/?spma2c6h.13651102.0.0.6c2a1b11I9pmUD&serviceTypemirror&tag top命令 top [选项] -p 只显示某个进程的信息 -d 设置刷新时间,默认是5s -c 显示产生进程的完整命令,默认是进程…...
Spring Security 的 CSRF 防护机制
CSRF:跨站请求伪造(Cross-Site Request Forgery) Spring Security 中的 .csrf() 是用来开启或配置这种保护机制,防止恶意网站“冒充用户”向你的网站发起请求。 一、CSRF 攻击原理简要 CSRF 的典型攻击场景如下: 用…...
跨平台项目部署全攻略:Windows后端+Mac前端在服务器的协同实战
当你的后端(Flask+MySQL,Windows开发)与前端(Vue,Mac开发)需要统一部署到服务器并实现交互时,完全可以通过「跨平台适配+反向代理」方案实现。本文将分步骤讲解如何在 Linux服务器(推荐)或 Windows服务器 上部署,并解决跨平台兼容性、跨域请求等核心问题。 一、技术…...
第八章 磁盘管理未完待续
1.磁盘管理 磁盘简介 名词:磁盘/硬盘/disk 存储设备类型从工作原理区分 机械 机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及 控制电机,磁头控制器,数据转换器,接口&…...