JavaScript性能优化(上)
1. 减少 DOM 操作
减少 DOM 操作是优化 JavaScript 性能的重要方法,因为频繁的 DOM 操作会导致浏览器重绘和重排,从而影响性能。以下是一些具体的策略和技术,可以帮助有效减少 DOM 操作:
1.1. 批量更新 DOM
-
亲切与母体:将多个 DOM 更新合并为一个操作。例如,可以创建一个空的容器,先在内存中构建所有需要的子元素,最后一次性将这个容器添加到主 DOM 树中。
const fragment = document.createDocumentFragment(); // 假设我们要添加多个元素
for (let i = 0; i < 100; i++) { const newElement = document.createElement('div'); newElement.textContent = `Item ${i}`; fragment.appendChild(newElement);
} document.getElementById('container').appendChild(fragment); // 一次性添加
1.2. 使用文档片段(DocumentFragment)
-
文档片段 是一个轻量级的容器,用于存放要添加到 DOM 的元素。使用文档片段可以避免多次操作 DOM,因为它不会引起浏览器的重绘,直到片段被插入到 DOM 中。
const fragment = document.createDocumentFragment();
// 构建元素
for (let i = 0; i < 10; i++) { const div = document.createElement('div'); div.textContent = 'Item ' + i; fragment.appendChild(div);
} document.getElementById('parent').appendChild(fragment); // 插入 DOM
1.3. 最小化 CSS 修改
-
合并样式更改:在对样式进行多次更改时,尽量将这些更改合并进行一次操作,以避免多次计算和重绘。
const element = document.getElementById('myElement'); // 不推荐:多次修改可能会导致多次计算和重绘
element.style.width = '100px';
element.style.height = '100px';
element.style.backgroundColor = 'red'; // 推荐:合并设置
element.style.cssText = 'width: 100px; height: 100px; background-color: red;';
1.4. 使用 CSS 类切换
-
类替换:通过添加或删除 CSS 类来批量应用样式更改,而不是单独设置每个样式属性。这样可以提高性能,因为浏览器对类的应用通常比对每个属性的应用更高效。
const element = document.getElementById('myElement');
element.classList.add('new-style');
1.5. 延迟 DOM 操作
-
使用
requestAnimationFrame
:对于动画和复杂的布局计算,可以在下一个重绘周期之前推迟 DOM 更改,避免在同一帧中进行多次修改。
requestAnimationFrame(() => { // 在下一帧中更新 DOM element.style.transform = 'translateY(100px)';
});
1.6. 减少不必要的查找
-
缓存 DOM 查询结果:如果需要多次访问同一 DOM 元素,建议将其缓存到变量中,避免重复查询。
const container = document.getElementById('container');
// 使用 container 变量替代多次查找
const items = container.getElementsByTagName('div');
1.7. 使用虚拟 DOM(在框架中)
- 框架支持:像 React 这样的前端框架使用虚拟 DOM,把对 DOM 的操作批量合并,优化性能。虽然这种方式不是原生的 JavaScript 优化技术,但了解其原理可以帮助开发者更好地利用这些框架。
1.8.总结
减少 DOM 操作不仅可以提高页面性能,还能改善用户体验。通过批量更新、使用文档片段、最小化样式修改以及合理利用缓存等方法,你就可以显著提升应用的响应速度和执行效率。
2. 使用合适的数据结构
使用合适的数据结构是优化 JavaScript 性能的关键之一。选择合适的数据结构可以提高代码的执行效率、降低内存使用,甚至改善代码的可读性和可维护性。以下是一些常见的数据结构及其适用场景,帮助你在 JavaScript 中做出更好的选择。
2.1. 数组 (Array)
-
用途:用于存储有序的数据集合。
-
特性:支持按索引访问,插入和删除操作相对简单,但在中间插入或删除元素时可能较慢,因为需要移动元素。
const arr = [1, 2, 3, 4];
arr.push(5); // 添加元素
arr.splice(2, 1); // 删除元素
console.log(arr); // 输出: [1, 2, 4, 5]
2.2. 对象 (Object)
-
用途:用于存储键值对,不保证键的顺序。
-
特性:适合存储属性和关系型数据,可以通过对象的属性快速访问和修改值。
const person = { name: 'Alice', age: 30
};
console.log(person.name); // 输出: Alice
person.age = 31; // 修改属性
2.3. Map
-
用途:用于存储键值对,支持任意类型的键。
-
特性:与对象相比,Map 保持插入的顺序,并且可以更高效地进行查找、添加和删除操作。
const map = new Map();
map.set('name', 'Alice');
map.set('age', 30);
console.log(map.get('name')); // 输出: Alice
2.4. Set
-
用途:用于存储唯一值的集合。
-
特性:适合需要去重的场景,支持任意类型的值,且保持插入顺序。Set 的内存占用通常比数组要小。
const set = new Set();
set.add(1);
set.add(2);
set.add(2); // 重复的值不会被添加
console.log(set.has(1)); // 输出: true
2.5. WeakMap
-
用途:与 Map 类似,但键是弱引用。
-
特性:适用于需要管理内存的场景,因为当键不再被引用时,WeakMap 中能自动清理这些条目。
const weakMap = new WeakMap();
let obj = {};
weakMap.set(obj, 'data');
console.log(weakMap.get(obj)); // 输出: data
obj = null; // obj 不再存在,WeakMap 也能释放内存
2.6. WeakSet
-
用途:与 Set 类似,但值是弱引用。
-
特性:适合存储需要被垃圾回收的对象,能够帮助管理内存,提高性能
const weakSet = new WeakSet();
let obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj)); // 输出: true
obj = null; // obj 不再存在,WeakSet 也能释放内存
2.7. 链表 (Linked List) 和自定义数据结构
-
用途:适合频繁进行插入和删除操作的场景。
-
特性:相较于数组,链表在中间插入和删除元素的效率更高,但随机访问性能较差。不常用,但在特定场景下非常有效。
class Node { constructor(data) { this.data = data; this.next = null; }
} class LinkedList { constructor() { this.head = null; } insert(data) { const newNode = new Node(data); newNode.next = this.head; this.head = newNode; // 头部插入 }
} const list = new LinkedList();
list.insert(1);
list.insert(2);
选择合适的数据结构的考虑因素
- 操作类型:根据需要进行的操作(如添加、删除、查找)选择数据结构。
- 性能需求:不同数据结构在不同操作下的性能表现会有所不同,选择适合的可以减少性能瓶颈。
- 内存使用:在内存使用方面,Set 和 Map 等结构通常更高效,尤其是在处理大量数据时。
- 语义:选择有助于理解和维护代码的结构,使代码更具可读性。
2.8.总结
选择合适的数据结构可以显著提高 JavaScript 应用的性能。根据具体的使用场景,考虑操作性能、内存效率和代码可读性来选择最适合的数据结构。
3. 减少内存使用
减少内存使用是 JavaScript 性能优化的重要方面,尤其对于需要处理大量数据或运行在资源有限环境中的应用程序等场景。以下是一些减少 JavaScript 中内存使用的具体策略:
3.1. 避免内存泄漏
内存泄漏是指不再需要的对象仍被引用,导致它们无法被垃圾回收。为避免内存泄漏,可以采取以下策略:
-
解除引用:确保不再使用的对象的引用被解除,特别是在事件处理器中。
function setup() { const element = document.getElementById('myElement'); element.addEventListener('click', () => { // 处理点击事件 }); // 离开时,要移除事件监听 return () => { element.removeEventListener('click', handler); };
}
使用弱引用:使用 WeakMap
和 WeakSet
来存储对象,这样当对象不再被使用时,内存可以自动释放。
const weakMap = new WeakMap(); function storeData(obj, data) { weakMap.set(obj, data);
} function clearData(obj) { weakMap.delete(obj); // 解除引用,允许回收
}
3.2. 限制全局变量
-
尽量减少全局变量:全局变量在 JavaScript 中生命周期较长,容易导致内存泄漏和命名冲突。可以将变量封装在函数内部或使用模块化的方式。
(function() { const myVariable = 'local value'; // 局部变量
})(); // 立即执行函数,封闭变量
3.3. 优化数据结构
-
选择合适的数据结构:如前所述,使用适当的数据结构(如
Set
、Map
等),可以减少不必要的数据存储,节省内存负担。 -
避免不必要的数组和对象:如果只需要存储简单类型,尽量避免使用复杂的对象或数组。
3.4. 使用数组和对象的原型
-
减少重复对象:对于重复使用的对象,可以复用同一个实例,而不是每次都创建新实例。
const sharedInstance = { prop: 'value' };
const dataArray = [sharedInstance, sharedInstance]; // 复用对象实例
利用原型链:通过方式将方法放在对象的原型上,而不是每个实例中,减少内存占用。
function MyObject() {}
MyObject.prototype.method = function() { // 方法实现
}; const instance1 = new MyObject();
const instance2 = new MyObject();
// method 共享而不会重复存储
3.5. 避免过大的数据集
-
分页加载:避免一次加载大量数据,采用分页或懒加载的方式,以降低内存使用。
-
优化数据存储:使用数据压缩基础库(如
lz-string
)来减少存储使用的内存,适合大数据集的场景。
3.6. 控制闭包
-
限制闭包的使用:闭包会保留其外部环境,确保不被使用的闭包不再引用外部变量。尽量不要在长期存在的数据结构中保存长时间运行的闭包。
function createCounter() { let count = 0; return function() { count++; return count; };
} const counter = createCounter(); // 适当使用闭包
3.7. 定期清理不再使用的资源
-
手动清理:对于大型应用程序,能够手动清理不再需要的对象(如终止数据处理、清除缓存、解除事件监听等)可以有效降低内存使用。
-
使用浏览器的开发者工具:定期监控内存使用情况,使用 Chrome DevTools 的 Memory 面板分析内存快照,查找潜在的内存泄漏。
3.8. 优化算法和逻辑
-
避免重复计算:使用缓存或记忆化来保存计算的结果。减少重复计算既能提升性能,也能降低内存使用。
const cache = {};
function memoizedFunction(arg) { if (cache[arg]) return cache[arg]; const result = computeHeavy(arg); cache[arg] = result; return result;
}
3.9. 适当关闭连接
- 关闭不必要的连接:在网络请求、数据库连接等场景中,及时关闭连接,以避免不必要的资源占用。
3.10总结
通过执行上述策略,可以有效减少 JavaScript 的内存使用并提升应用的性能。管理内存是优化应用的关键,需要持续关注和监控,以确保应用在不同环境下运行良好。
4. 异步编程
异步编程是 JavaScript 中处理任务的一种方式,允许代码在等待某些操作(如网络请求、文件读取、定时器等)完成时继续执行其他代码。这种方式能够提高应用的响应性和性能,使得用户体验更加流畅。以下是有关 JavaScript 异步编程的详细说明。
4.1. 什么是异步编程?
异步编程允许在执行某个操作时不阻塞其他代码的执行。这意味着您可以在等待某些任务完成时,执行其他任务。常见的异步操作包括:
- 网络请求(AJAX)
- 文件读取
- 定时器(
setTimeout
和setInterval
)
4.2. 异步编程的传统方式
在 JavaScript 中,最早的异步编程是通过 回调函数(Callbacks) 来实现的。回调函数是当某个操作完成时调用的函数。
2.1 使用回调
function fetchData(callback) { setTimeout(() => { // 模拟异步操作 const data = { message: 'Hello, World!' }; callback(data); }, 2000); // 2秒后执行回调
} fetchData((data) => { console.log(data.message); // 输出: Hello, World!
});
缺点:这种方式容易导致“回调地狱”,代码结构变得混乱,难以维护。
4.3. Promise
为了解决回调地狱的问题,JavaScript 引入了 Promise,它表示一个可能在未来某个时间完成的操作。
3.1 使用 Promise
function fetchData() { return new Promise((resolve, reject) => { setTimeout(() => { const data = { message: 'Hello, World!' }; resolve(data); // 任务成功时调用 resolve }, 2000); });
} fetchData() .then((data) => { console.log(data.message); // 输出: Hello, World! }) .catch((error) => { console.error('Error:', error); // 处理错误 });
3.2 Promise 的链式调用
Promise 支持链式调用,可以链式处理多个异步操作:
function fetchUser() { return new Promise((resolve) => { setTimeout(() => { resolve({ id: 1, name: 'Alice' }); }, 1000); });
} function fetchPosts(userId) { return new Promise((resolve) => { setTimeout(() => { resolve([ { userId, id: 1, title: 'Post 1' }, { userId, id: 2, title: 'Post 2' }, ]); }, 1000); });
} fetchUser() .then((user) => { console.log('User:', user); return fetchPosts(user.id); // 获取用户的帖子 }) .then((posts) => { console.log('Posts:', posts); }) .catch((error) => { console.error('Error:', error); });
4.4. async/await 语法
async/await 是基于 Promise 的更简化的异步编程方法,使代码更具可读性。async
修饰函数,使其返回一个 Promise;await
用于等待 Promise 完成。
4.1 使用 async/await
async function fetchData() { return new Promise((resolve) => { setTimeout(() => { resolve({ message: 'Hello, World!' }); }, 2000); });
} async function main() { const data = await fetchData(); // 等待 Promise 完成 console.log(data.message); // 输出: Hello, World!
} main();
4.5. 错误处理
使用 Promise 和 async/await 时,处理异步操作中的错误是很重要的。
5.1 用 Promise 处理错误
fetchData() .then((data) => { console.log(data.message); }) .catch((error) => { console.error('Failed to fetch data:', error); });
5.2 用 async/await 处理错误
async function main() { try { const data = await fetchData(); console.log(data.message); } catch (error) { console.error('Failed to fetch data:', error); }
} main();
4.6. 并发处理
可以使用 Promise.all
来同时处理多个异步操作。
async function fetchData() { // 模拟多个异步操作 const userPromise = fetchUser(); const postsPromise = fetchPosts(1); const [user, posts] = await Promise.all([userPromise, postsPromise]); console.log('User:', user); console.log('Posts:', posts);
} fetchData();
4.7. 小结
异步编程在 JavaScript 中至关重要,适当地使用回调、Promise 和 async/await 可以提高应用的性能和用户体验。每种方法都有其优缺点,选择合适的异步编程风格可以减少代码复杂性,提高可读性。
5. 减少网络请求
减少网络请求是优化网页应用性能的一个重要方面。这不仅能提高加载速度,还能降低服务器负载和用户的带宽使用,最终改善用户体验。以下是一些减少网络请求的有效策略和技巧:
5.1. 合并请求
1.1 合并 CSS 和 JavaScript 文件
- 将多个 CSS 文件合并为一个文件,这样可以减少请求数量。例如,将所有样式文件(style1.css、style2.css 等)合并成一个 main.css 文件。
- 将多个 JavaScript 文件合并为一个文件,如将所有脚本文件(script1.js、script2.js 等)合并成一个 main.js 文件。
<!-- 之前的方式: -->
<link rel="stylesheet" href="style1.css">
<link rel="stylesheet" href="style2.css">
<script src="script1.js"></script>
<script src="script2.js"></script> <!-- 合并后: -->
<link rel="stylesheet" href="main.css">
<script src="main.js"></script>
1.2 合并图像
- 使用 CSS Sprites:将多个小图像合并为一个大图像,通过 CSS 背景定位来显示所需的部分,这样只需要一个请求来加载所有图像。
.sprite { background-image: url('sprite.png'); width: 50px; /* 单个图像的宽度 */ height: 50px; /* 单个图像的高度 */
}
.icon1 { background-position: 0 0; /* 第一个图像的位置 */
}
.icon2 { background-position: -50px 0; /* 第二个图像的位置 */
}
5.2. 使用内容分发网络(CDN)
- 将静态资源托管在 CDN 上。CDN 是分布在多个地理位置的服务器网络,可以更快速地提供用户所需的静态资源(如图像、CSS、JavaScript),从而减少请求延迟并提高加载速度。
5.3. 延迟加载资源
3.1 惰性加载
- 只在需要时加载资源。用于图像、视频等非首次可见的内容,直到用户滚动到这些元素为止,可以显著减少初始网络请求。
<img data-src="image.jpg" class="lazy" alt="Lazy Loaded Image">
const lazyImages = document.querySelectorAll('.lazy');
const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; // 设置实际的 src img.classList.remove('lazy'); observer.unobserve(img); // 停止观察 } });
}); lazyImages.forEach(image => { observer.observe(image); // 观察每个懒加载图像
});
3.2 使用 Preload
- 预加载关键资源。可以通过
<link rel="preload">
标签来告诉浏览器优先加载重要的资源。
<link rel="preload" href="important-script.js" as="script">
5.4. 缓存策略
- 利用浏览器缓存:通过 HTTP 头(如
Cache-Control
和Expires
)来配置资源的缓存策略,能够减少重复请求。
//http
Cache-Control: max-age=3600 // 资源可以被缓存 1 小时
- ETag 和 Last-Modified:使用 ETag 和 Last-Modified 头部,让浏览器在请求资源时能验证是否可以使用缓存内容。
5.5. 使用合适的请求方法
- 选择 GET 和 POST 等的合适方法,对于一些不需要修改服务器状态的请求,可以使用
GET
,这样可以利用浏览器缓存。 - 简化请求参数,尽可能减少 URL 中的查询参数数量,以减少请求大小。
5.6. 避免重复请求
- 检查不会重复发送的请求:在必要时,使用状态变量来确保请求只有在所需时才会发送。
let isFetching = false; function fetchData() { if (isFetching) return; isFetching = true; fetch('/api/data') .then(response => response.json()) .then(data => { // 处理数据 }) .finally(() => { isFetching = false; // 请求完成,允许新的请求 });
}
5.7. 使用 GraphQL
- 使用 GraphQL:GraphQL 允许客户端请求所需的数据,而不是获取整个数据集,可以减少不必要的数据传输。
5.8. 采用现代前端框架
- 使用 React、Vue 或 Angular 等框架,它们通常会有优化网络请求的机制,如自动批量请求和状态管理工具,让异步数据请求更高效和简化。
5.9总结
减少网络请求不仅能加快页面加载速度,还能提高用户体验。采用合并请求、CDN、懒加载、缓存策略等方法,你将能够有效优化应用的性能。
相关文章:
JavaScript性能优化(上)
1. 减少 DOM 操作 减少 DOM 操作是优化 JavaScript 性能的重要方法,因为频繁的 DOM 操作会导致浏览器重绘和重排,从而影响性能。以下是一些具体的策略和技术,可以帮助有效减少 DOM 操作: 1.1. 批量更新 DOM 亲切与母体ÿ…...
数据结构与算法——链表OJ题详解(1)
文章目录 一、前言二、OJ题分享2.1移除链表元素——非val尾插法2.2反转链表2.2.1头插法2.2.2三指针法 2.3链表的中间结点——快慢指针法2.4合并两个有序链表2.4.1空链表法2.4.2非空链表法 2.5链表的回文结构2.5.1投机取巧数组法2.5.2反转链表法 三、总结 一、前言 前几天博主已…...
sedex认证2025年变化重点
近日,SEDEX突然宣布:2025年7月1日起,全通知审核正式退出历史舞台,取而代之的是至少3周窗口期的半通知突击审核。这场被业内称为“供应链透明化革命”的调整,或将重塑全球工厂合规生态。 三大变化划重点: 1…...
Scala课后总结(8)
集合计算高级函数 过滤(filter) 从集合里挑出符合特定条件元素组成新集合 。比如从整数集合里选出偶数, list.filter(x > x % 2 0) ,就是筛选出能被2整除的元素。 转化/映射(map) 对集合每个元素应…...
老硬件也能运行的Win11 IoT LTSC (OEM)物联网版
#记录工作 Windows 11 IoT Enterprise LTSC 2024 属于物联网相关的版本。 Windows 11 IoT Enterprise 是为物联网设备和场景设计的操作系统版本。它通常针对特定的工业控制、智能设备等物联网应用进行了优化和定制,以满足这些领域对稳定性、安全性和长期支持的需求…...
蓝桥杯冲刺题单--二分
二分 知识点 二分: 1.序列二分:在序列中查找(不怎么考,会比较难?) 序列二分应用的序列必须是递增或递减,但可以非严格 只要r是mid-1,就对应mid(lr1)/2 2.答…...
计网 2025/4/8
CDMA? CRC循环冗余检验 PPP协议的帧格式 字节填充(异步传输、7E->7D5E)零比特填充(同步传输、确保不会出现连续6个1) CSMA/CD协议 多点接入载波监听碰撞检测 一些概念: 争用期 一些公式: 最短有效帧…...
java设计模式-工厂模式
工厂模式 简单工厂模式 请看类: org.xwb.springcloud.factory.simple.PizzaStore 1、简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实力。简单来工厂模式就是工厂模式家族中最简单最…...
2025年客运从业资格证备考刷题题库
题库中通常包含大量的题目,以全面覆盖考试的知识点。通过做大量的题目,考生可以熟悉各种考试题型和命题方式,提高答题的速度和准确性,同时也能发现自己在知识掌握上的薄弱环节,有针对性地进行复习和强化训练。 1、驾驶…...
Zephyr、FreeRTOS、RT-Thread 任务创建对比分析
一、任务模型与核心概念 特性ZephyrFreeRTOSRT-Thread任务术语线程(Thread)任务(Task)线程(Thread)执行单元线程(单地址空间)任务(共享内存空间)线程&#x…...
RK-realtime Linux
rk3562实时性数据:最大76us rk3568实时性数据:最大126us rk3588实时性数据:最大30us 注意事项 (1)RK3568 需要使用RT版本的BL31,实时性能更好 a)rkbin需要更新到最新,且包含这个补丁:...
Ubuntu 22 Linux上部署DeepSeek+RAG知识库操作详解(Dify方式)之1
一、安装Docker 1. 更新你的包索引 首先,确保你的包列表是最新的。打开终端并运行以下命令: sudo apt update 2. 安装必要的依赖项 安装Docker之前,你需要安装一些必要的依赖项。运行以下命令来安装它们: sudo apt install apt…...
将飞帆制作的网页作为 div 集成到自己的网页中
并且自己的网页可以和飞帆中的控件相互调用函数。效果: 上链接 将飞帆制作的网页作为 div 集成到自己的网页中 - 文贝 进入可以复制、运行代码...
【C++游戏引擎开发】《几何算法》(3)AABB/OBB碰撞检测
一、AABB(轴对齐包围盒) 1.1 定义 最小点: m i n = ( x min , y min , z min ) \mathbf{min} = (x_{\text{min}}, y_{\text{min}}, z_{\text{min}}) min=(xmin,ymin,zmin)最大点: m a x = ( x max , y max , z max ) \mathbf{max} = (x_{\text{max}}, y_{\text{…...
基于人工智能的高中教育评价体系重构研究
基于人工智能的高中教育评价体系重构研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能技术已广泛渗透至各个领域,教育领域亦不例外。人工智能凭借其强大的数据处理能力、智能分析能力和个性化服务能力,为教育评价体系的创新与发…...
【C++游戏引擎开发】数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南
写在前面 两天都没手搓实现可用的凸包生成算法相关的代码,自觉无法手搓相关数学库,遂改为使用成熟数学库。 一、GLM库安装与介绍 1.1 vcpkg安装GLM 跨平台C包管理利器vcpkg完全指南 在PowerShell中执行命令: vcpkg install glm# 集成到系…...
Python 字典和集合(常见的映射方法)
本章内容的大纲如下: 常见的字典方法 如何处理查找不到的键 标准库中 dict 类型的变种set 和 frozenset 类型 散列表的工作原理 散列表带来的潜在影响(什么样的数据类型可作为键、不可预知的 顺序,等等) 常见的映射方法 映射类型…...
Qt 自带的QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本(sqlite.org)对比
Qt 自带的 QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本(sqlite.org)在核心功能上是相同的,但它们在集成方式、API 封装、功能支持以及版本更新上存在一些区别。以下是主要区别: 1. 核心 SQLite 引擎 Qt 的…...
按键长按代码
这些代码都存放在定时器中断中。中断为100ms中断一次。 数据判断,看的懂就看吧...
zk源码—3.单机和集群通信原理一
大纲 1.单机版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 2.集群版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 (3)Leader选举阶段 (4)Leader和Follower启动阶段 1.单机版的zk服务端的启动过程 (1)预启动阶段 (2)初始化阶段 单机版zk服务端的启动&…...
车企数字化转型:从“制造工厂”到“移动科技平台”的升维路径
一、战略重构:政策与产业变革的双重倒逼 中国《智能网联汽车技术路线图2.0》明确要求2030年L4级自动驾驶新车渗透率达20%,而麦肯锡数据显示,全球车企数字化投入占比已从2018年的7%跃升至2025年的18%。当前车企面临三大核心挑战:用…...
C++-Mongoose(2)-https-server-openssl
OpenSSL生成HTTPS自签名证书 - 简书 1.Openssl windowsubuntu下载http://www.openssl.vip/download1.VS2019编译OpenSSL 2.VS2019编译第一个OpenSSL项目 1.ubuntu编译OpenSSL 3.0 2.编写第一个OpenSSL 1.windows下编译OpenSSL 安装vs2019 perl nasm安装activePerl…...
nginx正向代理https
一、需求 公司内部服务器向外访问腾讯接口:https://qyapi.weixin.qq.com/cgi-bin,不能使用http直接访问。并且不支持域名,还需要设置互联网出口-出向白名单ip。 如何在尽量少改动代码的情况下实现应用的出向访问链接,考虑使用正向…...
Flask中的蓝图(Blueprint)浅讲
BluePrint Flask中的蓝图(Blueprint)是一种强大的组织工具,能够将大型应用拆分为可重用的模块化组件 1. 模块化组织 用途:将应用按功能拆分为独立模块,提升代码可维护性。示例: # user/views.py fr…...
虚拟表、TDgpt、JDBC 异步写入…TDengine 3.3.6.0 版本 8 大升级亮点
近日,TDengine 3.3.6.0 版本正式发布。除了此前已亮相的时序数据分析 AI 智能体 TDgpt,本次更新还带来了多个针对性能与易用性的重要增强:虚拟表全面上线,支持更灵活的一设备一表建模;JDBC 写入机制全新升级࿰…...
大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具
大型语言模型智能应用Coze、Dify、FastGPT、MaxKB 对比,选择合适自己的LLM工具 Coze、Dify、FastGPT 和 MaxKB 都是旨在帮助用户构建基于大型语言模型 (LLM) 的智能应用的平台。它们各自拥有独特的功能和侧重点,以下是对它们的简要对比: Coz…...
WEB安全--XSS--DOM破坏
一、前言 继XSS基础篇后,我们知道了三种类型的XSS,这篇文章主要针对DOM型XSS的原理进行深入解析。 二、DOM型XSS原理 2.1、什么是DOM 以一个形象的比喻: 网页就像是一座房子,而 **DOM** 就是这座房子的“蓝图”或者“结构图”。…...
持续集成:GitLab CI/CD 与 Jenkins CI/CD 的全面剖析
一、引言 在当今快速迭代的软件开发领域,持续集成(Continuous Integration,CI)已成为保障软件质量、加速开发流程的关键实践。通过频繁地将代码集成到共享仓库,并自动进行构建和测试,持续集成能够尽早发现并解决代码冲突和缺陷。而 GitLab CI/CD 和 Jenkins CI/CD 作为两…...
Go语言sync.Mutex包源码解读
互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段,对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型,对外暴露Lock()、Unlock()、TryLock()三种方法,分别用于阻塞加锁、解锁、非阻塞加锁操作(加锁失败…...
FreeRTOS软件定时器
软件定时器就是"闹钟",你可以设置闹钟, 用软件定时器的话USE_TIMER要设置为1 在30分钟后让你起床工作每隔1小时让你例行检查机器运行情况 软件定时器也可以完成两类事情: 在"未来"某个时间点,运行函数周期…...
Selenium三大等待
一、强制等待 1.设置完等待后不管有没有找到元素,都会执行等待,等待结束后才会执行下一步 2.实例: driver webdriver.Chrome()driver.get("https://www.baidu.com")time.sleep(3) # 设置强制等待driver.quit() 二、隐性等待 …...
【Ansible自动化运维】一、初步了解,开启自动化运维之旅
在当今数字化时代,随着企业 IT 基础设施规模的不断扩大,传统的手工运维方式逐渐显得力不从心。自动化运维技术应运而生,其中 Ansible 凭借其简洁易用、功能强大的特点,成为众多运维工程师和开发人员的首选工具。本篇文章将从基础概…...
雪花算法、md5加密
雪花算法生成ID是一个64位长整型(但是也可以通过优化简短位数) 组成部分: 时间戳 机器ID 序列号 用途: 分布式系统唯一ID生成:解决数据库自增ID在分布式环境下的唯一性问题、避免UUID的无序性和性能问题 有序性…...
micro介绍
micro介绍 Micro 的首要特点是易于安装(它只是一个静态的二进制文件,没有任何依赖关系)和易于使用Micro 支持完整的插件系统。插件是用 Lua 编写的,插件管理器可自动为你下载和安装插件。使用简单的 json 格式配置选项࿰…...
电视盒子 刷armbian
参考 中兴电视盒子中兴B860AV3.2-M刷Armbian新手级教程-CSDN博客 1.刷安卓9 带root版本 a. 下载安卓线刷包 链接:https://pan.baidu.com/s/1hz87_ld2lJea0gYjeoHQ8A?pwdd7as 提取码:d7as b.拆机短接 3.安装usbburning工具 使用方法 ,…...
(七)lerobot开源项目so100新版本全流程操作(操作记录)
目录 《项目简介》 一、环境配置 1、创建虚拟环境 2、克隆项目并安装所需包 二、主从臂硬件准备 1、舵机配置 (1)分别查看主从臂的开发板端口号 (2)分别设置主从臂的舵机 2、组装主从臂 3、查看主从臂端口号和相机端…...
智慧景区能源管理解决方案,为旅游“升温”保驾护航
景区能源管理 当下痛点 1 高峰期用电负荷大 节假日和旅游旺季等高峰期用电需求增大,电力供应不足、电网负荷过大; 2 设备维护困难 景区内电力设备多且散,包括发电机组、变电站、配电设备等,维护和管理困难,特别是…...
LCR 056. 两数之和 IV - 输入二叉搜索树
文章目录 题意思路代码 题意 题目链接 思路 代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), …...
AI搜索+法律咨询:在「事实重构」与「程序正义」的博弈场
已经写了股票和医疗相关的内容,今天聊一下AI搜索和法律结合的应用场景。AI搜索不替用户做选择,却让我们握住了法律武器的说明书。 一、AI重构事实:技术理想与法律现实的碰撞 1、案例切入:AI能否还原车祸责任比…...
多模态大模型重塑自动驾驶:技术融合与实践路径全解析
目录 1、 引言:AI与自动驾驶的革命性融合 2、五大领先多模态模型解析 2.1 Qwen2.5-Omni:全模态集大成者 2.2. LLaVA:视觉语言理解专家 2.3. Qwen2-VL:长视频理解能手 2.4. X-InstructBLIP:跨模态理解框架 2.5. …...
海阳科技IPO:业务独立性、业绩稳定性、财务规范性存致命缺陷
三角形是最稳定的结构,它既是完美的相互制衡,又是有力的彼此支撑。 ——佚名 引 言 IPO审议指标、要求、规定众多,有无一个直接简单的公式?该公式可以直接将造假等“低劣”IPO项目排除在外? 在《奕泽财经》看来…...
PyTorch 与 Python 装饰器及迭代器的比较与应用
在深度学习和 Stable Diffusion(SD)训练过程中,PyTorch 不仅依赖于 Python 的基础特性,而且通过扩展和封装这些特性,提供了更高效、便捷的训练和推理方式。本文将从装饰器和迭代器两个方面详细解释 Python 中的原生实现…...
大数据(5)(基础概念)Spark从入门到实战:核心原理与大数据处理实战案例
目录 一、背景介绍1. 为什么需要Spark?2. Spark的诞生: 二、Spark核心原理1. 四大核心特性2. 核心架构3. 执行流程 三、Spark实战案例案例1:单词计数(WordCount)案例2:实时流处理&…...
Ubuntu小练习
文章目录 一、远程连接1、通过putty连接2、查看putty运行状态3、通过Puuty远程登录Ubuntu4、添加新用户查看是否添加成功 5、用新用户登录远程Ubuntu6、使用VNC远程登录树莓派 二、虚拟机上talk聊天三、Opencv1、简单安装版(适合新手安装)2、打开VScode特…...
运行Spark会出现恶问题
1. 依赖冲突问题:Spark依赖众多组件,如Scala、Hadoop等。不同版本的依赖之间可能存在兼容性问题,导致Spark无法正常运行。比如,特定版本的Spark可能要求与之匹配的Scala版本,若使用了不兼容的Scala版本,会在…...
uniapp大文件分包
1. 在pages.json中配置 "subPackages":[{"root":pagesUser,"pages":[{"path":mine/xxx,"style":xxx },{"path":mine/xxx,"style":xxx}]},{"root":pagesIndex,"pages":[{"p…...
Git 源码打包、迁移、恢复和备份
介绍 Git 项目打包方式,适用于源码交付、迁移、备份等场景。 一 Git 仓库的两种类型 在实际项目开发与交付中,常接触 的 两种 Git 仓库: 仓库类型是否包含源码适用场景普通仓库是本地开发、运行、构建裸仓库否代码托管、只读交付、备份 普…...
Linux 内核网络协议栈中的 struct packet_type:以 ip_packet_type 为例
在 Linux 内核的网络协议栈中,struct packet_type 是一个核心数据结构,用于注册特定协议类型的数据包处理逻辑。它定义了如何处理特定协议的数据包,并通过协议类型匹配机制实现协议分发。本文将通过分析 ip_packet_type 的定义和作用,深入探讨其在网络协议栈中的重要性。 …...
LeetCodeHot100-第三章:数学
面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台 目录 🎈1、双指针:9. 回文数 🎈2、逻辑题 :66. 加一 🎈3、逻辑题:172. 阶乘后的零 🎈4、…...
JavaScript 错误处理:理解和应对异常
在编程中,错误是不可避免的,特别是在进行复杂的逻辑操作、与外部系统交互或处理用户输入时。错误处理是软件开发中非常重要的一部分,它可以帮助开发者提高应用的稳定性和可用性。本文将深入探讨JavaScript中的错误处理机制,如何利…...