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

JavaScript性能优化实战(13):性能测试与持续优化

在前面的系列文章中,我们探讨了各种JavaScript性能优化的方法和实战案例。然而,优化工作不应仅是一次性的努力,而应当成为开发流程中的常态。本篇将聚焦于如何建立系统化的性能测试体系,并实现持续的性能优化机制,确保应用长期保持出色的性能表现。

前端性能测试体系构建

随着前端应用日益复杂,系统性能对用户体验和业务成功的影响越来越大。然而,许多团队仍然采用临时性的、非系统化的方式进行性能测试和优化。建立一个完善的前端性能测试体系,对于持续交付高性能应用至关重要。

性能测试的核心维度

完整的前端性能测试体系应当覆盖以下几个核心维度:

  1. 加载性能:衡量应用从请求到可用所需的时间
  2. 运行时性能:评估应用在用户交互过程中的响应性和流畅度
  3. 内存使用:监控应用的内存占用情况和潜在的内存泄漏
  4. 网络效率:测量应用的网络请求数量、体积和时序
  5. 能耗性能:特别是在移动设备上,应用对电池寿命的影响

建立性能指标体系

性能测试的第一步是确定关键指标,这些指标应当既有技术维度的客观数据,也有用户体验的主观反映。

核心Web Vitals指标

Google的Core Web Vitals提供了衡量用户体验的标准化指标:

// 使用Web Vitals库收集核心指标
import {getCLS,getFID,getLCP,getFCP,getTTFB
} from 'web-vitals';// 发送性能数据到分析服务
function sendToAnalytics({name, delta, value, id}) {const analyticsData = {metric: name,value: delta, // 增量值finalValue: value, // 最终值id: id, // 唯一标识符page: window.location.pathname,timestamp: Date.now()};// 发送到分析服务navigator.sendBeacon('/analytics', JSON.stringify(analyticsData));
}// 监测并报告各项指标
getCLS(sendToAnalytics);  // 累积布局偏移
getFID(sendToAnalytics);  // 首次输入延迟
getLCP(sendToAnalytics);  // 最大内容绘制时间
getFCP(sendToAnalytics);  // 首次内容绘制时间
getTTFB(sendToAnalytics); // 首字节时间
自定义业务相关指标

除了标准化指标外,还应针对业务特点建立自定义指标,例如:

  • 关键业务流程性能:如电商网站的商品浏览到下单完成的全流程时间
  • 特定交互响应性:如复杂数据可视化应用中图表渲染和交互的响应时间
  • 长任务频率:应用中阻塞主线程超过50ms的任务数量和分布
// 自定义业务流程性能监测
class BusinessFlowPerformance {constructor(flowName) {this.flowName = flowName;this.steps = {};this.startTime = 0;this.endTime = 0;}startFlow() {this.startTime = performance.now();console.log(`Flow ${this.flowName} started`);}recordStep(stepName) {this.steps[stepName] = performance.now() - this.startTime;console.log(`Step ${stepName} completed at ${this.steps[stepName]}ms`);}endFlow() {this.endTime = performance.now();const totalDuration = this.endTime - this.startTime;console.log(`Flow ${this.flowName} completed in ${totalDuration}ms`);// 发送完整流程数据this.sendFlowData({flowName: this.flowName,totalDuration,steps: this.steps});}sendFlowData(data) {// 发送到数据分析服务fetch('/api/performance/business-flow', {method: 'POST',body: JSON.stringify(data),headers: { 'Content-Type': 'application/json' }});}
}// 使用示例
const checkoutFlow = new BusinessFlowPerformance('checkout');
checkoutFlow.startFlow();// 在各关键步骤调用
// 用户点击结算按钮
checkoutFlow.recordStep('cart_to_checkout');// 地址填写完成
checkoutFlow.recordStep('address_completed');// 支付方式选择完成
checkoutFlow.recordStep('payment_selected');// 订单确认
checkoutFlow.recordStep('order_confirmed');// 流程完成
checkoutFlow.endFlow();

性能测试环境构建

有效的性能测试需要在标准化、可控的环境中进行,以确保结果的可重复性和可比性。

实验室测试环境设置

实验室测试环境应模拟真实的用户设备和网络条件:

// 使用Puppeteer进行性能测试的示例配置
const puppeteer = require('puppeteer');async function runPerformanceTest(url, devicePreset, networkPreset) {// 启动浏览器const browser = await puppeteer.launch({headless: true,args: ['--no-sandbox', '--disable-setuid-sandbox']});// 创建新页面const page = await browser.newPage();// 设置设备模拟await page.emulate(puppeteer.devices[devicePreset]);// 模拟网络条件const client = await page.target().createCDPSession();await client.send('Network.enable');// 预设的网络配置const networkConfigs = {'3G': {'offline': false,'downloadThroughput': 750 * 1024 / 8,'uploadThroughput': 250 * 1024 / 8,'latency': 100},'4G': {'offline': false,'downloadThroughput': 4 * 1024 * 1024 / 8,'uploadThroughput': 2 * 1024 * 1024 / 8,'latency': 50}};await client.send('Network.emulateNetworkConditions', networkConfigs[networkPreset] || networkConfigs['4G']);// 收集性能指标await page.evaluateOnNewDocument(() => {window.performanceMetrics = {FCP: 0,LCP: 0,CLS: 0,TTI: 0};// 首次内容绘制new PerformanceObserver((entryList) => {const entries = entryList.getEntries();const fcpEntry = entries[entries.length - 1];window.performanceMetrics.FCP = fcpEntry.startTime;}).observe({ type: 'paint', buffered: true });// 最大内容绘制new PerformanceObserver((entryList) => {const entries = entryList.getEntries();const lcpEntry = entries[entries.length - 1];window.performanceMetrics.LCP = lcpEntry.startTime;}).observe({ type: 'largest-contentful-paint', buffered: true });// 累积布局偏移new PerformanceObserver((entryList) => {let cumulativeScore = 0;for (const entry of entryList.getEntries()) {// 只计算没有用户输入的布局偏移if (!entry.hadRecentInput) {cumulativeScore += entry.value;}}window.performanceMetrics.CLS = cumulativeScore;}).observe({ type: 'layout-shift', buffered: true });});// 访问目标页面并等待网络空闲const response = await page.goto(url, {waitUntil: 'networkidle2'});// 等待页面完全加载并可交互await page.waitForSelector('#main-content', { visible: true });// 提取性能指标const metrics = await page.evaluate(() => {// 等待TTI计算完成return new Promise(resolve => {// 模拟TTI计算setTimeout(() => {const navigationStart = performance.timing.navigationStart;const loadEventEnd = performance.timing.loadEventEnd;window.performanceMetrics.TTI = loadEventEnd - navigationStart;resolve(window.performanceMetrics);}, 1000);});});// 截图以备记录await page.screenshot({ path: `${devicePreset}-${networkPreset}.png` });// 关闭浏览器await browser.close();return {url,devicePreset,networkPreset,metrics,statusCode: response.status()};
}// 使用实例
async function runBatchTests() {const results = [];// 测试不同设备和网络组合const devices = ['iPhone X', 'Pixel 2', 'Desktop Chrome'];const networks = ['3G', '4G'];const urls = ['https://example.com','https://example.com/products','https://example.com/checkout'];for (const url of urls) {for (const device of devices) {for (const network of networks) {const result = await runPerformanceTest(url, device, network);results.push(result);}}}// 生成性能测试报告generatePerformanceReport(results);
}#### 真实用户监测(RUM)设置实验室测试需要与真实用户数据相结合,才能全面反映应用性能:```javascript
// 真实用户监测脚本示例
(function() {// 避免在非浏览器环境运行if (typeof window === 'undefined') return;// 确保Performance API可用if (!window.performance || !window.performance.timing || !window.performance.getEntriesByType) {console.warn('Performance API不完全支持,RUM数据可能不完整');}// 基础配置const config = {sampleRate: 0.1, // 采样率10%beaconEndpoint: '/analytics/rum',appVersion: '1.2.3',environment: 'production'};// 只对采样用户进行监测if (Math.random() > config.sampleRate) return;// 收集设备和浏览器信息const deviceInfo = {userAgent: navigator.userAgent,viewport: {width: window.innerWidth,height: window.innerHeight},devicePixelRatio: window.devicePixelRatio || 1,connection: navigator.connection ? {effectiveType: navigator.connection.effectiveType,downlink: navigator.connection.downlink,rtt: navigator.connection.rtt} : null};// 收集导航性能数据function collectNavigationTiming() {// 使用Performance Timeline APIconst navEntry = performance.getEntriesByType('navigation')[0];if (navEntry) {return {startTime: navEntry.startTime,domContentLoaded: navEntry.domContentLoadedEventEnd,loadTime: navEntry.loadEventEnd,domInteractive: navEntry.domInteractive,redirectCount: navEntry.redirectCount,redirectTime: navEntry.redirectEnd - navEntry.redirectStart,dnsTime: navEntry.domainLookupEnd - navEntry.domainLookupStart,tcpTime: navEntry.connectEnd - navEntry.connectStart,ttfb: navEntry.responseStart - navEntry.requestStart,responseTime: navEntry.responseEnd - navEntry.responseStart,domBuildingTime: navEntry.domComplete - navEntry.domInteractive,};}// 回退到旧APIconst timing = performance.timing;return {startTime: 0,domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,loadTime: timing.loadEventEnd - timing.navigationStart,domInteractive: timing.domInteractive - timing.navigationStart,redirectCount: 0,redirectTime: timing.redirectEnd - timing.redirectStart,dnsTime: timing.domainLookupEnd - timing.domainLookupStart,tcpTime: timing.connectEnd - timing.connectStart,ttfb: timing.responseStart - timing.requestStart,responseTime: timing.responseEnd - timing.responseStart,domBuildingTime: timing.domComplete - timing.domInteractive,};}// 收集并发送性能数据function sendPerformanceData() {const performanceData = {timestamp: Date.now(),page: window.location.pathname,referrer: document.referrer,deviceInfo,navigationTiming: collectNavigationTiming(),metrics: window.performanceMetrics || {},sessionId: getSessionId(),appVersion: config.appVersion,environment: config.environment};// 使用信标API发送数据if (navigator.sendBeacon) {navigator.sendBeacon(config.beaconEndpoint, JSON.stringify(performanceData));} else {// 回退到XHRconst xhr = new XMLHttpRequest();xhr.open('POST', config.beaconEndpoint, true);xhr.setRequestHeader('Content-Type', 'application/json');xhr.send(JSON.stringify(performanceData));}}// 获取或创建会话IDfunction getSessionId() {let sessionId = sessionStorage.getItem('performance_session_id');if (!sessionId) {sessionId = generateUUID();sessionStorage.setItem('performance_session_id', sessionId);}return sessionId;}// 生成UUIDfunction generateUUID() {return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {const r = Math.random() * 16 | 0;const v = c === 'x' ? r : (r & 0x3 | 0x8);return v.toString(16);});}// 页面内容加载完毕后发送数据window.addEventListener('load', () => {// 延迟发送,等待其他指标收集完成setTimeout(sendPerformanceData, 1000);});// 页面卸载前尝试再次发送数据window.addEventListener('beforeunload', sendPerformanceData);
})();

性能测试工具集成

构建完整的前端性能测试体系需要集成多种专业工具,形成协同工作的工具链。

核心工具选择

不同的性能测试场景需要匹配相应的工具:

测试类型推荐工具主要场景
页面加载性能Lighthouse, WebPageTest整体页面加载分析和评分
运行时性能Chrome DevTools, PuppeteerJavaScript执行和渲染性能分析
内存分析Chrome Memory Panel, Heap Snapshot内存泄漏和占用分析
真实用户监测Google Analytics, New Relic, Sentry生产环境中的性能数据收集
压力测试k6, Artillery高负载下的前端性能表现测试
工具链自动化集成

将这些工具整合到自动化测试流程中:

// 集成Lighthouse到CI/CD流程的示例脚本
const { exec } = require('child_process');
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const fs = require('fs');
const path = require('path');// 定义性能预算
const performanceBudgets = {'first-contentful-paint': 1800,  // ms'largest-contentful-paint': 2500, // ms'cumulative-layout-shift': 0.1,'total-blocking-time': 300,      // ms'speed-index': 3000,             // ms'interactive': 3500,             // ms'max-js-size': 350 * 1024,       // bytes'max-css-size': 70 * 1024,       // bytes'max-total-size': 1500 * 1024    // bytes
};async function runLighthouseTest(url, options = {}) {// 启动Chromeconst chrome = await chromeLauncher.launch({chromeFlags: ['--headless', '--disable-gpu', '--no-sandbox']});// 设置Lighthouse选项const opts = {port: chrome.port,output: 'json',logLevel: 'info',...options};// 运行Lighthouse测试const results = await lighthouse(url, opts);// 关闭Chromeawait chrome.kill();return results;
}async function checkPerformanceBudgets(results, budgets) {const { audits } = results.lhr;const violations = [];// 检查FCPif (audits['first-contentful-paint'].numericValue > budgets['first-contentful-paint']) {violations.push({metric: 'First Contentful Paint',value: Math.round(audits['first-contentful-paint'].numericValue),budget: budgets['first-contentful-paint'],unit: 'ms'});}// 检查LCPif (audits['largest-contentful-paint'].numericValue > budgets['largest-contentful-paint']) {violations.push({metric: 'Largest Contentful Paint',value: Math.round(audits['largest-contentful-paint'].numericValue),budget: budgets['largest-contentful-paint'],unit: 'ms'});}// 检查CLSif (audits['cumulative-layout-shift'].numericValue > budgets['cumulative-layout-shift']) {violations.push({metric: 'Cumulative Layout Shift',value: audits['cumulative-layout-shift'].numericValue.toFixed(3),budget: budgets['cumulative-layout-shift'],unit: ''});}// 检查TBTif (audits['total-blocking-time'].numericValue > budgets['total-blocking-time']) {violations.push({metric: 'Total Blocking Time',value: Math.round(audits['total-blocking-time'].numericValue),budget: budgets['total-blocking-time'],unit: 'ms'});}// 检查Speed Indexif (audits['speed-index'].numericValue > budgets['speed-index']) {violations.push({metric: 'Speed Index',value: Math.round(audits['speed-index'].numericValue),budget: budgets['speed-index'],unit: 'ms'});}// 检查TTIif (audits['interactive'].numericValue > budgets['interactive']) {violations.push({metric: 'Time to Interactive',value: Math.round(audits['interactive'].numericValue),budget: budgets['interactive'],unit: 'ms'});}// 检查JS大小const jsSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'script').transferSize;if (jsSize > budgets['max-js-size']) {violations.push({metric: 'JavaScript Transfer Size',value: Math.round(jsSize / 1024) + ' KB',budget: Math.round(budgets['max-js-size'] / 1024) + ' KB',unit: ''});}// 检查CSS大小const cssSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'stylesheet').transferSize;if (cssSize > budgets['max-css-size']) {violations.push({metric: 'CSS Transfer Size',value: Math.round(cssSize / 1024) + ' KB',budget: Math.round(budgets['max-css-size'] / 1024) + ' KB',unit: ''});}// 检查总资源大小const totalSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'total').transferSize;if (totalSize > budgets['max-total-size']) {violations.push({metric: 'Total Transfer Size',value: Math.round(totalSize / 1024) + ' KB',budget: Math.round(budgets['max-total-size'] / 1024) + ' KB',unit: ''});}return violations;
}// 主测试流程
async function runPerformanceTest() {try {console.log('启动性能测试...');// 测试环境URLconst targetUrl = process.env.TEST_URL || 'https://staging.example.com';// 运行Lighthouse测试const results = await runLighthouseTest(targetUrl, {onlyCategories: ['performance']});// 保存测试报告const reportPath = path.join(__dirname, 'lighthouse-report.json');fs.writeFileSync(reportPath, JSON.stringify(results.lhr, null, 2));console.log(`测试报告已保存至: ${reportPath}`);// 验证性能预算const violations = await checkPerformanceBudgets(results, performanceBudgets);if (violations.length > 0) {console.error('性能预算违反警告:');violations.forEach(v => {console.error(`  - ${v.metric}: ${v.value}${v.unit} (预算: ${v.budget}${v.unit})`);})<

相关文章:

JavaScript性能优化实战(13):性能测试与持续优化

在前面的系列文章中,我们探讨了各种JavaScript性能优化的方法和实战案例。然而,优化工作不应仅是一次性的努力,而应当成为开发流程中的常态。本篇将聚焦于如何建立系统化的性能测试体系,并实现持续的性能优化机制,确保应用长期保持出色的性能表现。 前端性能测试体系构建…...

nbufxz动态规划1

草药题 dp[i][j]&#xff0c;考虑i个草药&#xff0c;j个时间&#xff0c;能获得的最大价值。这i个草药中&#xff0c;你不一定全部都采集了。你可能有的采了&#xff0c;有的没采。然后你最终得到了一个最优的结果。 状态转移方程无非就是&#xff1a; dp[i][j] max(dp[i …...

PostgreSQL 初体验

目录 一、PostgreSQL 1. 简介 2. 特点 &#xff08;1&#xff09; 开源免费&#xff08;Open Source&#xff09; &#xff08;2&#xff09;标准兼容&#xff08;SQL Compliance&#xff09; &#xff08;3&#xff09; 丰富的数据类型&#xff08;Data Types&#xff09…...

北斗导航 | 基于matlab的多波束技术的卫星通信系统性能仿真

基于多波束技术的低轨(LEO)卫星通信系统 **1. 仿真场景建模**1.1 LEO卫星轨道参数设置1.2 地面终端分布**2. 多波束天线模型**2.1 波束方向图生成2.2 频率复用方案**3. 链路预算与干扰分析**3.1 自由空间路径损耗3.2 信噪比(SNR)计算**4. 动态资源调度算法**4.1 基于流量需…...

数据结构与算法学习笔记(Acwing 提高课)----动态规划·状态机模型

数据结构与算法学习笔记----动态规划状态机模型 author: 明月清了个风 first publish time: 2025.5.20 ps⭐️背包终于结束了&#xff0c;状态机模型题目不多。状态机其实是一种另类的状态表示方法&#xff0c;将某一个点扩展为一个状态进行保存并在多个状态之间转移&#xf…...

Vue 3.0 中 Teleport 详解

Teleport 是 Vue 3.0 引入的一个非常有用的特性&#xff0c;它允许你将组件的一部分模板"传送"到 DOM 中的其他位置&#xff0c;而不改变组件的逻辑层次结构。 1. 基本概念 Teleport 的主要用途是将某些 DOM 元素渲染到 Vue 应用之外的 DOM 节点中&#xff0c;这在…...

Linux在防火墙中添加开放端口

例如&#xff1a;安装docker时启动报错&#xff1a; Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details. 此时开放对应端口号就可以咯 在防…...

day24:零基础学嵌入式之系统编程

一、系统编程包含 文件的读写、和常用操作&#xff0c;操作系统已经进入多任务时代&#xff0c;在同一时刻同时运行多个程序。 二、标准io&#xff1b;stdio.h&#xff08;以计算机为中心&#xff09; 1.头文件路径&#xff1a;/usr/include/stdio.h so动态库&#xff1a;st…...

2.10 财务分析

10.1 财务报告构成及列报基本要求 10.1.1 财务报告 1.财务报告的构成 资产负债表、利润表、现金流量表、所有者权益变动表和附注小型企业可不编现金流量表。 2.财务报表及其作用 1.资产负债表的内容及其作用 内容 资产类、流动性大小顺序排序。流动资产、非流动资产负债和…...

docker容器知识

一、docker与docker compose区别&#xff1a; 1、docker是创建和管理单个容器的工具&#xff0c;适合简单的应用或服务&#xff1b; 2、docker compose是管理多容器应用的工具&#xff0c;适合复杂的、多服务的应用程序&#xff1b; 3、docker与docker compose对比&#xff…...

国标GB28181视频EasyGBS视频监控平台搭建城市交通道路可视化管理/道路视频巡检/应急监控指挥

一、方案背景​ 随着城市人口与车辆激增&#xff0c;交通管理面临严峻挑战&#xff1a;高峰期道路拥堵、事故处理滞后、违法取证低效&#xff0c;传统管理模式难以为继。智慧交通依托信息技术&#xff0c;成为破局关键&#xff0c;其中视频监控是实现精细化管理的核心。国标GB…...

【LeetCode 热题 100】有效的括号 / 最小栈 / 字符串解码 / 柱状图中最大的矩形

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;LeetCode 热题 100 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 栈有效的括号最小栈字符串解码每日温度柱状图中最大的矩形 堆数组中的第K个最大元素 栈 有效的括号 有效的括号 cl…...

Oracle中如何解决BUFFER BUSY WAITS

和BUFFER CACHE相关的常见等待事件还有BUFFER BUSY WAITS。顾名思义&#xff0c;BUFFER BUSY WAITS等待事件指的是多个会话不能共享缓冲区中的数据块而引发的等待事件。 发生BUFFER BUSY WAITS事件时&#xff0c;P1值代表数据文件号&#xff0c;P2值代表数据块号&#xff0c;P3…...

LeetCode 93.复原IP地址 LeetCode 78.子集 LeetCode 90.子集II

LeetCode 93.复原IP地址 其实思想跟回文字符串那道题是类似的&#xff0c;但难点在于这道题的终止条件和判断是否IP地址进行划分后是否合理&#xff1f; 思路&#xff1a; 通过一个int类型的全局变量来记载 " . " 的数目 / 记录你当前所获得的小数组的数目&#x…...

Java转Go日记(四十一):Gorm删除

1.1.1. 删除/软删除 警告删除记录时&#xff0c;需要确保其主要字段具有值&#xff0c;GORM将使用主键删除记录&#xff0c;如果主要字段为空&#xff0c;GORM将删除模型的所有记录 // 删除存在的记录db.Delete(&email)DELETE from emails where id10;// 为Delete语句添加…...

Java基于SpringBoot的公交智能化系统,附源码+文档说明

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…...

电子电器架构 --- 汽车高性能计算

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...

Journal of Real-Time Image Processing 投稿过程

投稿要求双栏12页以内(包括参考文献)&#xff0c;这个排版要求感觉不是很严格&#xff0c;我当时就是用普通的双栏的格式去拍的版&#xff0c;然后就提交了&#xff0c;也没单独去下载模版。 投稿过程 12.12 Submission received 12.12 Submission is under technical check 1…...

利用basee64特性 -- BYUCTF 2025 JWTF

题目信息: Unfortunately one of our JWTs was compromised by attackers, so we created a JWT Revocation List to ensure they can’t use it anymore. 代码量很少 # 导入必要的模块 # 从 flask 模块导入 Flask, request, redirect, make_response, jsonify 类和函数 from f…...

湖北理元理律师事务所:科学债务规划如何平衡还款与生活

在债务压力普遍加剧的背景下&#xff0c;如何通过专业规划实现“还款不停生活”&#xff0c;成为许多债务人关注的核心问题。湖北理元理律师事务所基于多年实务经验&#xff0c;总结出一套兼顾法律合规性与人性化需求的债务管理方案&#xff0c;其核心逻辑在于通过法律工具优化…...

1.1HarmonyOS NEXT技术架构深度解析:微内核架构与系统分层

HarmonyOS NEXT技术架构深度解析&#xff1a;微内核架构与系统分层 摘要 作为面向万物互联时代的全场景操作系统&#xff0c;HarmonyOS NEXT通过革命性的星核架构&#xff08;Star Kernel&#xff09;重构了系统底层架构。本文将深入解析HarmonyOS NEXT的微内核设计原理、系统…...

考研系列-408真题计算机组成原理篇(2015-2019)

写在前面 此文章是本人在备考过程中408真题计算机组成原理部分(2015年-2019年)的易错题及相应的知识点整理,后期复习也常常用到,对于知识提炼归纳理解起到了很大的作用,分享出来希望帮助到大家~ # 2015年 1.IO端口 接口电路中可以被CPU直接访问的寄存器 IO控制方式-中断…...

HarmonyOS Next 关键资产的解释

关键资产的安全存储与管理&#xff1a;HarmonyOS Asset Store Kit 深度解析 一、关键资产的定义与重要性 关键资产&#xff08;Critical Asset&#xff09;是指应用运行过程中涉及的短敏感数据&#xff0c;包括但不限于用户密码、身份令牌&#xff08;Token&#xff09;、银行…...

Awesome ChatGPT Prompts:释放AI对话潜力的开源利器

项目概览 Awesome ChatGPT Prompts 是由土耳其开发者 Fatih Kadir Akın 发起的开源项目,托管于 GitHub,旨在通过精心设计的提示词模板(Prompts)优化用户与 ChatGPT 的交互体验。项目以 Markdown 和 CSV 格式管理模板,无需复杂编程语言,但需文本处理能力,目前已在 GitH…...

第6章 C控制语句:循环

目录 6.1 再探while 循环6.2 while语句6.3 比较大小&#xff1a;使用关系运算符和表达式6.4 不确定的循环与计数循环6.5 for循环6.6 更多赋值运算符&#xff1a;、-、*、/和%6.7 逗号运算符6.8 退出条件循环&#xff1a;do while6.9 选择哪种循环6.10 嵌套循环6.11 数组6.12 使…...

海盗王客户端更换横版任务面板的实现

海盗王的任务面板&#xff0c;采用的是竖长设计&#xff0c;上半部分显示任务列表&#xff0c;下半部分显示任务详情。 这样的设计会带来一个问题&#xff1a;就是任务多的时候&#xff0c;不能完整显示&#xff0c;只能显示前面几个&#xff0c;后面的会隐藏到滚动条里面&…...

【git】在Windows上搭建git服务器

1、简述 常用的搭建git服务器的工具有&#xff1a;Gogs、Gitblit、Gitea、GitLab 它们的区别如下&#xff1a; 功能GogsGitblitGiteaGitLab界面语言中文、英文等多语言英文为主中文、英文等多语言英文为主权限管理基础分支权限详细分支权限基础 详细分支权限非常完善代码审查…...

leetcode hot100刷题日记——6.和为 K 的子数组

解答&#xff1a;前缀和思想&#xff0c;见灵茶山艾府大大题解。 &#xff08;1&#xff09;前缀和思想&#xff1a; 前缀和数组prefix_sum的定义是prefix_sum[i] nums[0] nums[1] … nums[i]。如果存在两个前缀和prefix_sum[j]和prefix_sum[i]满足prefix_sum[i] - prefi…...

人工智能的“歧视”:“她数据”在算法运行中隐形

纵观人类的发展史&#xff0c;每一次科技进步都将对性别平等产生深刻影响。尤其是当下&#xff0c;人们对于借助人工智能技术快速发展来弥合性别不平等寄予厚望。 但很多人没想过&#xff0c;人工智能技术本身是客观中立、不存在“算法歧视”“性别偏见的吗&#xff1f; 弗吉…...

Java数组列表 - ArrayList

在Java中&#xff0c;ArrayList是一种非常实用的数据结构&#xff0c;它允许开发者动态地管理数组大小。通过ArrayList&#xff0c;可以轻松地添加、删除和修改元素&#xff0c;以及获取元素和列表的大小。例如&#xff0c;创建一个ArrayList来存储字符串&#xff0c;然后通过a…...

跨境外贸电商供应链一体化ERP管理系统

项目介绍: 跨境外贸电商供应链一体化ERP管理系统 高清视频演示: 跨境外贸电商供应链一体化ERP管理系统_哔哩哔哩_bilibili 系统说明: 外贸电商产品ERP系统包含多个角色&#xff08;客户、客服、工厂、供应商&#xff09;和多个功能模块&#xff0c;以下是系统功能的详细说明…...

数据库表连接结构详解

数据库表连接结构详解 介绍 本文基于提供的SQL表结构&#xff0c;解释了表之间的连接关系。这些表主要涉及AI系统配置&#xff0c;如客户端、顾问和智能体等。通过外键&#xff08;如client_id、agent_id&#xff09;&#xff0c;这些表形成关联网络。 表连接概述 以下是主…...

Vue3.0教程005:watch监视ref定义的【基本类型】数据和【对象类型】数据

文章目录 4、watch监视4.1 前言4.2 情况一4.3 情况二 4、watch监视 4.1 前言 作用&#xff1a;监视数据的变化&#xff08;和vue2中的watch作用一致&#xff09;特点&#xff1a;Vue3中的watch只能监视以下四种数据&#xff1a; ref定义的数据。reactive定义的数据。函数返回…...

【Java的批量操作】

系列文章目录 Java知识点 文章目录 系列文章目录&#x1f449;前言&#x1f449;一、常见批量操作方法&#x1f449;1-1、JDBC 批量操作&#xff08;数据库&#xff09;&#x1f449;1-2、MyBatis 批量操作&#x1f449;1-3、Java 8 Stream 批量处理集合&#x1f449;1-4、多线…...

流复备机断档处理

文章目录 环境症状问题原因解决方案 环境 系统平台&#xff1a;UOS&#xff08;海光&#xff09;,UOS &#xff08;飞腾&#xff09;,UOS&#xff08;鲲鹏&#xff09;,UOS&#xff08;龙芯&#xff09;,UOS &#xff08;申威&#xff09;,银河麒麟svs&#xff08;X86_64&…...

PostgreSQL架构

目录 一、PostgreSQL核心特性与优势 1.PostgreSQL简介 2.PostgreSQL的核心特点 &#xff08;1&#xff09;开源与自由 &#xff08;2&#xff09;高度符合SQL标准 &#xff08;3&#xff09;丰富的数据类型 &#xff08;4&#xff09;事务与并发控制 &#xff08;5&…...

苍穹外卖系统结构与功能报告

一、系统简介 苍穹外卖系统是为餐饮企业定制的数字化解决方案&#xff0c;包含管理端后台和用户端小程序两部分。管理端面向餐饮企业员工&#xff0c;支持菜品、套餐、订单等核心业务的数字化管理&#xff1b;用户端面向消费者&#xff0c;提供在线点餐、支付、订单跟踪等功能…...

CAU数据库class3 关系型数据库基础

关系数据库模型的3个要素 数据结构 二维表 数据操作 特点 操作的对象为元组&#xff0c;操作的结果为元组高度非过程化&#xff0c;用户不关系是怎么实现的 完整性约束 数据完整性是指保证数据真确的特性 实体完整性参照完整性用户定义完整性 关系的形式定义 例子&…...

【Qt】在OrinNX上,使用命令安装qtmultimedia5-dev时报错

1、问题描述 在OrinNX+Ubuntu20.04上,使用命令安装qtmultimedia5-dev时报错 sudo apt install qtmultimedia5-devThe following packages have unmet dependencies: qtmultimedia5-dev : Depends: libpulse-dev but it is not going to be installed E: Unable to correct p…...

阿里云CDN刷新预热--刷新URL

文章目录 一、全英文URL刷新预热二、掺杂中文的URL刷新预热2.1 对带中文URL进行编码2.2 预热刷新 三、CDN刷新-核心作用与价值3.1 核心作用3.2 核心价值3.3 典型使用场景 *最后我想说&#xff1a;请你不要相信我说的每一句话&#xff0c;这只是我的个人经验* 一、全英文URL刷新…...

anaconda、miniconda、conda的关系及miniconda安装

anaconda、miniconda、conda的关系及miniconda安装 文章目录 前言正文定义关系Linux安装miniconda新建一个python3.8环境 参考 前言 本文用于记录关于Anaconda、conda和Miniconda的定义及其关系的总结123&#xff1a; 正文 定义 conda 一个跨平台的开源包管理和环境管理工具…...

SpringBoot实现本地对象存储【minio、阿里云、七牛云】

引入依赖 <!-- minio --> <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.12</version> </dependency><!-- 阿里云oss --> <dependency><groupId>com.aliyun.…...

阿里云百炼(1) : 阿里云百炼应用问答_回答图片问题_方案1_提问时上传图片文件

直接用于拍照答题不大理想, 可能适用其他用途, 更好的方案: 阿里云百炼(1) : 阿里云百炼应用问答_回答图片问题_方案2_提取题目再提问-CSDN博客 1.实现代码 package cn.nordrassil.ly.test.拍照答题;import com.alibaba.dashscope.app.Application; import com.alibaba.dashsc…...

理解阿里云的MQTT

一、阿里云的mqtt分几种 阿里云提供的MQTT服务主要分为‌标准MQTT协议‌和‌P2P模式MQTT‌两种类型&#xff0c;二者在通信模式及适用场景上有显著差异&#xff1a; 1、标准MQTT与P2P MQTT的区别 ‌特性‌‌标准MQTT‌‌P2P模式MQTT‌‌通信模式‌发布/订阅&#xff08;Pub/S…...

HarmonyOS5云服务技术分享--云缓存快速上手指南

大家好&#xff0c;今天我们来聊聊如何快速上手华为AppGallery Connect&#xff08;AGC&#xff09;的云缓存服务。作为一款基于Serverless架构的Key-Value型缓存服务&#xff0c;它不仅能自动弹性伸缩&#xff0c;还能免去运维烦恼&#xff0c;非常适合高并发场景下的数据快速…...

FreeSWITCH rtcp-mux 测试

rtcp 跟 rtp 占用同一个端口&#xff0c;这就是 rtcp 复用 Fs 呼出是这样的&#xff1a; originate [rtcp_muxtrue][rtcp_audio_interval_msec5000]user/1001 &echo 需要同时指定 rtcp_audio_interval_msec&#xff0c;否则 rtcp_mux 不能生效 Fs 呼入不需要配置&#xf…...

浏览器播放 WebRTC 视频流

源码&#xff08;vue&#xff09; <template><video ref"videoElement" class"video" autoplay muted playsinline></video> </template><script setup lang"ts">import { onBeforeUnmount, onMounted, ref } fr…...

SpringBoot3+Vue3(1)-后端 请求头校验,jwt退出登录,mybaits实现数据库用户校验

1.后端&#xff1a;jwt请求头校验 解析 工具类jwtUtils 解析token 令牌是否过期&#xff0c;验证 正常、异常、运行时错误 倒入工具类是resource 工具类中添加解析用户的方法&#xff1a; 在 在工具类添加id解析 此处调用 添加controller做测试 测试&…...

Oracle RAC 中的 RBAL 进程

Oracle RAC 中的 RBAL 进程 RBAL 进程概述 RBAL&#xff08;ReBalancer&#xff09;是 Oracle RAC 和 ASM&#xff08;Automatic Storage Management&#xff09;环境中的一个关键后台进程&#xff0c;主要负责 ASM 磁盘组的重新平衡操作。 主要功能 磁盘组监控&#xff1a…...

mac上将 Excel 文件的扩展名从 .xls 改为 .xlsx 后,打开时报错:“文件格式或文件扩展名无效”。

方法一&#xff1a;使用 Excel for Mac 打开并另存为 打开 Excel 应用程序。 打开你的 .xls 文件&#xff1a; 如果 Excel 能正常打开它&#xff0c;说明文件没问题。 在菜单栏点击&#xff1a;文件 → 另存为。 在文件格式中选择&#xff1a;Excel 工作簿 (.xlsx)。 点击保存…...