[本周五題]Javascript面試常考題手撕場景UR緩存、new關鍵字、大數相加、最長遞增子序列、高并發請求、大文件上傳和WebWorks

LUR緩存實現

以下是 JavaScript 實現 LRU 緩存的詳細解析,結合核心原理與代碼實現,并標注來源:


一、LRU 緩存核心原理

LRU(Least Recently Used)緩存淘汰策略的核心思想是:當緩存容量滿時,優先淘汰最久未使用的數據。其實現需滿足以下要求:

  1. 快速訪問getput 操作需達到 O(1) 時間復雜度。
  2. 動態調整順序:訪問數據時需將其移動到“最近使用”位置。

class LRUCache {constructor(capacity) {this.cache = new Map();this.capacity = capacity;}get(key) {if (!this.cache.has(key)) return -1;const value = this.cache.get(key);this.cache.delete(key); // 刪除后重新插入保證順序this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) this.cache.delete(key);this.cache.set(key, value);if (this.cache.size > this.capacity) {// 刪除最久未使用的鍵(Map的迭代順序保證)this.cache.delete(this.cache.keys().next().value);}}
}

二、JavaScript 實現方案

1. 基于 Map 的實現(推薦)

JavaScript 的 Map 對象天然保持鍵的插入順序,迭代時按插入順序返回鍵。利用這一特性,可實現簡潔的 LRU 緩存。

代碼實現

class LRUCache {constructor(capacity) {this.capacity = capacity;this.cache = new Map();}get(key) {if (!this.cache.has(key)) return -1;// 訪問后移動到尾部(最近使用)const value = this.cache.get(key);this.cache.delete(key);this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) {// 更新值并移動到尾部this.cache.delete(key);} else if (this.cache.size >= this.capacity) {// 緩存滿時刪除頭部(最久未使用)this.cache.delete(this.cache.keys().next().value);}// 插入新鍵到尾部this.cache.set(key, value);}
}

關鍵操作解析
? get 方法:若鍵存在,刪除舊值并重新插入到尾部,表示最近訪問過。
? put 方法:若鍵存在,更新值并調整位置;若不存在,插入新鍵。若超出容量,刪除頭部鍵。

2. 基于雙向鏈表 + Map 的實現

通過自定義雙向鏈表節點和鏈表類,可更直觀地維護節點順序。

代碼實現

class Node {constructor(key, value) {this.key = key;this.value = value;this.prev = null;this.next = null;}
}class LRUCache {constructor(capacity) {this.capacity = capacity;this.map = new Map();this.head = new Node(0, 0); // 頭哨兵this.tail = new Node(0, 0); // 尾哨兵this.head.next = this.tail;this.tail.prev = this.head;}get(key) {if (!this.map.has(key)) return -1;const node = this.map.get(key);this.moveToHead(node);return node.value;}put(key, value) {if (this.map.has(key)) {const node = this.map.get(key);node.value = value;this.moveToHead(node);} else {const newNode = new Node(key, value);this.map.set(key, newNode);this.addToHead(newNode);if (this.map.size > this.capacity) {const lruNode = this.removeTail();this.map.delete(lruNode.key);}}}moveToHead(node) {this.removeNode(node);this.addToHead(node);}removeNode(node) {node.prev.next = node.next;node.next.prev = node.prev;}addToHead(node) {node.next = this.head.next;node.prev = this.head;this.head.next.prev = node;this.head.next = node;}removeTail() {const node = this.tail.prev;this.removeNode(node);return node;}
}

關鍵操作解析
? 雙向鏈表:維護節點順序,addToHeadremoveNode 操作均為 O(1)
? get 方法:訪問節點后將其移動到頭部。
? put 方法:插入新節點到頭部,超出容量時刪除尾部節點。


三、性能分析

? 時間復雜度getput 均為 O(1),因 Map 和雙向鏈表的插入/刪除操作均為常數時間。
? 空間復雜度O(capacity),需存儲所有緩存項。


四、擴展與優化

  1. 惰性刪除:結合 WeakMap 實現惰性過期,自動清理過期數據。
  2. 并發控制:在高并發場景中,使用鎖機制或線程安全容器(如 synchronized 包)。
  3. 容量動態調整:根據系統負載動態調整緩存容量。

總結

JavaScript 實現 LRU 緩存的核心在于 Map + 雙向鏈表 的組合,或直接利用 Map 的有序特性。推薦使用第一種方案(基于 Map),代碼簡潔且性能高效。如需更復雜的緩存策略(如 TTL),可參考 Node.js 的 lru-cache 庫。

new關鍵字實現

以下是 JavaScript 實現 new 操作符的詳細解析,結合核心原理與代碼實現,并標注來源:


一、new 操作符的核心作用

new 操作符用于創建一個構造函數的實例對象,并完成以下任務:

  1. 創建新對象:生成一個空對象。
  2. 綁定原型鏈:將新對象的原型指向構造函數的 prototype
  3. 綁定 this:將構造函數內部的 this 綁定到新對象。
  4. 處理返回值:若構造函數返回對象,則返回該對象;否則返回新創建的對象。

二、new 的執行流程

  1. 創建新對象

    const obj = {}; // 或 Object.create(Constructor.prototype)
    

    生成一個空對象,后續通過原型鏈繼承構造函數的方法。

  2. 設置原型鏈

    obj.__proto__ = Constructor.prototype; // 或 Object.setPrototypeOf(obj, Constructor.prototype)
    

    使新對象可訪問構造函數原型上的屬性和方法。

  3. 綁定 this 并執行構造函數

    const result = Constructor.apply(obj, args);
    

    將構造函數的 this 綁定到新對象,并傳入參數執行。

  4. 返回結果

    return result instanceof Object ? result : obj;
    

    若構造函數返回對象,則返回該對象;否則返回新創建的對象。


三、手寫 new 操作符的實現

基礎版本
function myNew(Constructor, ...args) {const obj = Object.create(Constructor.prototype); // const result = Constructor.apply(obj, args);    // return result instanceof Object ? result : obj; // 
}
優化版本

增加類型檢查與錯誤處理:

function myNew(Constructor, ...args) {if (typeof Constructor !== 'function') {throw new TypeError('Constructor must be a function');}const obj = Object.create(Constructor.prototype);try {return Constructor.apply(obj, args);} catch (error) {throw error;}
}

四、特殊情況與注意事項

  1. 構造函數返回值的影響
    ? 若返回原始值(如數字、字符串),new 會忽略并返回新對象。
    ? 若返回對象,則直接返回該對象(原型鏈斷裂)。

    function Test() { return { foo: 'bar' }; }
    const t = new Test(); // t 是 { foo: 'bar' }, 而非 Test 的實例
    
  2. 忘記使用 new 的問題
    直接調用構造函數會導致 this 指向全局對象(如 window),引發全局變量污染。

    function Person() { this.name = '張三'; }
    Person(); // window.name = '張三'
    
  3. 箭頭函數的限制
    箭頭函數沒有自己的 this,無法作為構造函數使用。

    const Person = (name) => { this.name = name; };
    new Person(); // TypeError: Person is not a constructor
    

五、實際應用場景

  1. 創建對象實例

    function User(name, role) { this.name = name; this.role = role; }
    const admin = new User('admin', 'administrator');
    
  2. 實現繼承

    function Animal(name) { this.name = name; }
    function Dog(name, breed) {Animal.call(this, name); // 調用父類構造函數this.breed = breed;
    }
    Dog.prototype = Object.create(Animal.prototype); // 設置原型鏈
    

總結

new 操作符通過 創建對象→綁定原型→綁定 this→處理返回值 四步實現實例化。手寫實現時需注意類型檢查、錯誤處理及返回值判斷。理解其原理有助于掌握 JavaScript 的面向對象編程,并在面試中應對相關問題。

大數相加

  1. 字符串逐位相加:將大數轉換為字符串,逐位相加并處理進位。這在多個網頁中都有提到,比如網頁[1]、[6]、[7]、[8]都詳細描述了這種方法。特別是網頁[7]和[8]提供了具體的代碼示例,應該引用這些網頁。

  2. 使用BigInt類型:網頁[5]和[4]提到,BigInt可以處理任意精度的整數,但只能用于整數,不能處理小數。需要指出這一點,并引用相關網頁。

  3. 第三方庫:網頁[1]、[2]、[3]、[4]、[5]都推薦了decimal.js、bignumber.js等庫,這些庫專門處理高精度計算,適合復雜場景。需要引用這些網頁中的例子,比如網頁[1]提到的bignumber.js和網頁[2]中的decimal.js。

  4. 轉換為整數計算:網頁[2]、[3]、[4]提到將小數轉換為整數進行計算,適用于固定小數位數的場景。例如,網頁[2]中的示例代碼展示了這種方法,需要引用網頁[2]。

  5. 處理特殊情況:比如進位處理和結果反轉,這在網頁[6]、[7]、[8]的代碼示例中都有體現,需要指出這些細節并引用對應的網頁。

以下是 JavaScript 實現大數相加(精度處理) 的詳細解決方案,結合不同場景需求與實現原理:


一、核心問題與解決方案分類

JavaScript 的 Number 類型基于 IEEE 754 雙精度浮點數表示,無法精確處理超過 2^53-1 的整數或高精度小數。大數相加的精度問題主要表現為:
? 整數溢出:如 9007199254740992 + 1 = 9007199254740992(超出安全整數范圍)。
? 浮點數精度丟失:如 0.1 + 0.2 = 0.30000000000000004


二、主要實現方案

1. 字符串逐位相加(推薦)

原理:將大數轉換為字符串,逐位模擬手工加法,處理進位。
代碼實現

function addLargeNumbers(num1, num2) {const a = num1.toString().split('').reverse();const b = num2.toString().split('').reverse();let carry = 0;const maxLength = Math.max(a.length, b.length);const result = [];for (let i = 0; i < maxLength; i++) {const digit1 = parseInt(a[i] || 0, 10);const digit2 = parseInt(b[i] || 0, 10);const sum = digit1 + digit2 + carry;result.push(sum % 10);carry = Math.floor(sum / 10);}if (carry > 0) result.push(carry);return result.reverse().join('');
}

特點
? 支持任意長度整數相加。
? 時間復雜度 O(n),性能高效。
? 需手動處理進位與結果反轉。


2. 使用 BigInt 類型

原理:ES6 引入的 BigInt 可表示任意精度整數,但僅支持整數運算。
代碼示例

const num1 = BigInt("9007199254740992");
const num2 = BigInt("1");
console.log(num1 + num2); // 輸出: 9007199254740993n

特點
? 無需手動處理進位,語法簡潔。
? 無法直接與 Number 類型運算,需顯式轉換。


3. 第三方高精度庫

推薦庫
? decimal.js:支持任意精度十進制運算,適合金融場景。

const Decimal = require('decimal.js');
const result = new Decimal('0.1').plus('0.2');
console.log(result.toString()); // 輸出: 0.3

? bignumber.js:提供豐富的 API,支持科學計算。

const BigNumber = require('bignumber.js');
const num1 = new BigNumber('9999999999999999999999999999999999999999999999999999999999999');
console.log(num1.plus(1).toString()); // 輸出: 10000000000000000000000000000000000000000000000000000000000000

優勢
? 內置四舍五入、指數運算等復雜功能。
? 避免手動實現進位邏輯的復雜性。


4. 轉換為整數計算(固定小數位數)

適用場景:需精確控制小數位數(如貨幣計算)。
實現方法

function addWithPrecision(num1, num2, precision = 2) {const factor = Math.pow(10, precision);return (Math.round(num1 * factor) + Math.round(num2 * factor)) / factor;
}
console.log(addWithPrecision(0.1, 0.2)); // 輸出: 0.3

特點
? 通過整數運算避免浮點數誤差。
? 需提前確定精度,靈活性較低。


三、性能與場景選擇

方案適用場景性能代碼復雜度
字符串逐位相加任意長度整數相加中等
BigInt任意長度整數(僅整數運算)
第三方庫復雜運算(金融、科學計算)中等
轉換為整數固定小數位數計算

推薦選擇
? 簡單場景:字符串逐位相加。
? 金融/科學計算:使用 decimal.jsbignumber.js
? 大整數運算:直接使用 BigInt


四、擴展與注意事項

  1. 處理負數:需在逐位相加前統一符號,并單獨處理負號。
  2. 結果格式化:使用 toFixed() 或庫內置方法控制小數位數。
  3. 性能優化:對超長數字可分段并行計算(如 Web Worker)。

通過以上方案,可靈活應對 JavaScript 中的大數精度問題。如需完整代碼示例或庫的安裝指南,可參考對應網頁。

最長遞增子序列(Vue3 Diff)

動態規劃

以下是 JavaScript 實現最長遞增子序列(LIS) 的詳細解析,結合動態規劃與優化算法,并標注來源:


一、問題描述

給定一個整數數組 nums,找到其中最長嚴格遞增子序列的長度。子序列無需連續,但必須保持元素順序。例如:
? 輸入 [10,9,2,5,3,7,101,18],輸出 4(子序列 [2,3,7,101])。


二、動態規劃解法(O(n2))

核心思路
  1. 定義狀態dp[i] 表示以 nums[i] 結尾的最長遞增子序列長度。
  2. 狀態轉移:遍歷數組,若 nums[i] > nums[j]j < i),則更新 dp[i] = max(dp[i], dp[j] + 1)
  3. 結果:遍歷 dp 數組,取最大值即為 LIS 長度。
代碼實現
function lengthOfLIS(nums) {const n = nums.length;if (n === 0) return 0;const dp = new Array(n).fill(1); // 初始化為1,每個元素自身構成子序列let maxLen = 1;for (let i = 1; i < n; i++) {for (let j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}maxLen = Math.max(maxLen, dp[i]);}return maxLen;
}

三、優化解法(O(nlogn))

核心思路
  1. 維護有序數組tails[i] 表示長度為 i+1 的所有遞增子序列的最小尾部元素。
  2. 二分查找:遍歷數組,通過二分查找找到 tails 中第一個大于等于當前元素的位置,更新或插入元素。
代碼實現
function lengthOfLIS(nums) {const tails = [];for (const num of nums) {const pos = binarySearch(tails, num);if (pos === tails.length) {tails.push(num);} else {tails[pos] = num;}}return tails.length;
}function binarySearch(arr, target) {let left = 0, right = arr.length;while (left < right) {const mid = Math.floor((left + right) / 2);if (arr[mid] < target) left = mid + 1;else right = mid;}return left;
}

四、性能對比

算法時間復雜度空間復雜度適用場景
動態規劃O(n2)O(n)小規模數據(n ≤ 1000)
優化算法(二分)O(nlogn)O(n)大規模數據(n ≥ 1000)

五、擴展與注意事項

  1. 嚴格遞增 vs 非嚴格遞增
    ? 嚴格遞增:nums[i] > nums[j](如示例1)。
    ? 非嚴格遞增:nums[i] ≥ nums[j](需調整條件)。

  2. 返回子序列本身
    ? 動態規劃可記錄路徑,但需額外空間。
    ? 優化算法需逆向重建路徑。

  3. 邊界條件處理
    ? 空數組返回0,單個元素返回1。


總結

? 簡單場景:優先使用動態規劃(代碼簡潔,易理解)。
? 高效場景:選擇 O(nlogn) 優化算法(處理大規模數據)。
? 理解兩種算法的原理差異,可應對不同性能需求。

高并發請求控制

高并發請求控制

大文件分片上傳實現(斷點續傳)

核心流程(網頁)

1.文件切片:將文件按固定大小(如5MB)分割
2. 哈希生成:使用SparkMD5等庫生成文件唯一標識
3. 分片上傳:并發控制上傳切片(通常限制5個并發)
4. 斷點續傳:通過本地存儲記錄已上傳切片
5.服務端合并:所有切片上傳完成后觸發合并請求

// 文件切片(網頁5)
function sliceFile(file, chunkSize = 5 * 1024 * 1024) {const chunks = [];let start = 0;while (start < file.size) {chunks.push(file.slice(start, start + chunkSize));start += chunkSize;}return chunks;
}// 分片上傳(網頁6)
async function uploadChunks(fileHash, chunks) {const maxConcurrent = 5; // 最大并發數const uploaded = await checkUploadedChunks(fileHash);for (let i = 0; i < chunks.length; i += maxConcurrent) {await Promise.all(chunks.slice(i, i + maxConcurrent).map(async (chunk, index) => {if (!uploaded.includes(i + index)) {const formData = new FormData();formData.append('chunk', chunk);formData.append('hash', `${fileHash}-${i + index}`);await fetch('/upload', { method: 'POST', body: formData });}}));}await mergeChunks(fileHash, file.name);
}

以下是 JavaScript 實現大文件分片上傳(斷點續傳) 的詳細解析,結合核心原理與代碼實現,并標注來源:


一、核心實現步驟

  1. 文件切片
    將大文件分割成固定大小的塊(如 5MB),使用 File.slice() 方法實現。

    function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {const chunks = [];let start = 0;while (start < file.size) {chunks.push(file.slice(start, start + chunkSize));start += chunkSize;}return chunks;
    }
    
  2. 生成文件唯一標識
    通過文件名、大小和最后修改時間生成唯一標識(避免 MD5 計算耗時)。

    function calculateFileHash(file) {return `${file.name}-${file.size}-${file.lastModified}`;
    }
    
  3. 檢查已上傳切片
    通過本地存儲(localStorage)或服務器查詢已上傳的切片索引,跳過已上傳部分。

    const uploadedChunks = JSON.parse(localStorage.getItem(fileHash)) || [];
    
  4. 并發上傳切片
    使用 Promise.all 并發上傳未上傳的切片,控制并發數(如 5 個)。

    const maxConcurrent = 5;
    const uploadQueue = chunks.filter((_, index) => !uploadedChunks.includes(index)).map((chunk, index) => uploadChunk(chunk, index));
    await Promise.all(uploadQueue);
    
  5. 合并切片與清理進度
    所有切片上傳完成后,調用服務器合并接口,并清理本地進度記錄。

    await fetch('/merge', {method: 'POST',body: JSON.stringify({ fileHash, filename: file.name })
    });
    localStorage.removeItem(fileHash);
    

二、關鍵技術點

  1. 文件哈希計算
    使用 spark-md5 庫計算文件全量哈希,實現秒傳功能。

    // 主線程
    calculateHash(chunkList).then(hash => {if (serverFileExists(hash)) return; // 秒傳
    });
    
  2. 進度存儲
    通過 localStorage 記錄已上傳切片索引,支持斷點續傳。

    uploadProgress.save(fileHash, uploadedChunks);
    
  3. 并發控制
    通過隊列機制限制同時上傳的切片數量,避免瀏覽器崩潰。

    let activeUploads = 0;
    function processQueue() {if (activeUploads < maxConcurrent && uploadQueue.length > 0) {// 上傳邏輯}
    }
    
  4. 錯誤處理與重試
    捕獲上傳失敗切片,支持自動重試或手動重傳。

    try {await uploadChunk(chunk);
    } catch (error) {retryUpload(chunk);
    }
    
  5. 秒傳功能
    服務器端校驗文件哈希,若存在則直接返回成功,避免重復上傳。

    if (serverFileExists(fileHash)) {return { success: true, message: '秒傳成功' };
    }
    

三、完整代碼示例

<input type="file" id="fileInput" />
<button id="uploadBtn">上傳</button>
<progress id="progressBar" value="0" max="100"></progress><script>const fileInput = document.getElementById('fileInput');const progressBar = document.getElementById('progressBar');const axios = require('axios');document.getElementById('uploadBtn').onclick = async () => {const file = fileInput.files[0];const chunkSize = 10 * 1024 * 1024; // 10MBconst chunks = fileToChunks(file, chunkSize);const fileHash = calculateFileHash(file);// 檢查已上傳切片const uploadedChunks = JSON.parse(localStorage.getItem(fileHash)) || [];// 并發上傳未上傳切片const promises = chunks.map((chunk, index) => {if (uploadedChunks.includes(index)) return Promise.resolve();return uploadChunk(chunk, index, fileHash);});await Promise.all(promises);// 合并切片await axios.post('/merge', { fileHash, filename: file.name });localStorage.removeItem(fileHash);progressBar.value = 100;};function fileToChunks(file, size) {const chunks = [];for (let start = 0; start < file.size; start += size) {chunks.push(file.slice(start, start + size));}return chunks;}function calculateFileHash(file) {return `${file.name}-${file.size}-${file.lastModified}`;}async function uploadChunk(chunk, index, fileHash) {const formData = new FormData();formData.append('chunk', chunk);formData.append('index', index);formData.append('fileHash', fileHash);try {await axios.post('/upload', formData);localStorage.setItem(fileHash, JSON.stringify([...JSON.parse(localStorage.getItem(fileHash) || '[]'), index]));progressBar.max = chunks.length;progressBar.value++;} catch (error) {console.error(`Chunk ${index} 上傳失敗`);}}
</script>

四、注意事項

  1. 切片大小選擇
    建議 2-10MB,太小增加請求次數,太大增加重試成本。

  2. 服務器端配合
    需提供以下接口:
    ? /upload:上傳單個切片
    ? /merge:合并切片
    ? /check:查詢已上傳切片

  3. 瀏覽器兼容性
    File.slice() 在 IE10+ 支持,低版本需使用 Blob.slice()

  4. 網絡中斷處理
    可結合 visibilitychange 事件暫停/恢復上傳。


五、性能優化建議

方案效果實現復雜度
分片大小動態調整平衡上傳速度與穩定性
上傳進度可視化提升用戶體驗
錯誤重試機制減少因網絡波動導致的失敗
壓縮切片數據減少傳輸數據量

通過以上方案,可實現高效、可靠的大文件分片上傳。實際開發中需結合具體業務場景選擇優化策略,并確保前后端接口的兼容性。

Web Worker

以下是 JavaScript Web Worker 通信機制 的詳細解析,結合主線程與 Worker 交互的核心原理與實現方法,并標注來源:


一、Web Worker 核心概念

Web Worker 是瀏覽器提供的多線程解決方案,允許在后臺線程中執行 JavaScript 代碼,避免阻塞主線程。其核心特點包括:

  1. 線程隔離:Worker 線程與主線程完全隔離,無法直接訪問 DOM、window 等全局對象。
  2. 消息傳遞:通過 postMessageonmessage 實現異步通信,數據通過結構化克隆算法傳輸。
  3. 類型分類
    ? Dedicated Worker:僅服務于創建它的主線程。
    ? Shared Worker:跨頁面共享,支持多標簽頁通信。

二、主線程與 Worker 交互流程

1. 創建 Worker 實例

主線程通過 new Worker(url) 創建 Worker,url 指向 Worker 腳本文件(需同源):

const worker = new Worker('worker.js'); // 
2. 發送消息(postMessage)

主線程通過 postMessage 發送數據到 Worker,支持復雜數據類型(對象、數組等):

worker.postMessage({ type: 'calculate', data: [1,2,3] }); // 
3. 接收消息(onmessage)

Worker 通過 self.onmessage 監聽主線程消息,并通過 postMessage 返回結果:

// Worker 線程 (worker.js)
self.onmessage = (event) => {const result = event.data.data.reduce((sum, num) => sum + num, 0);self.postMessage(result); // 
};
4. 終止 Worker

任務完成后,主線程調用 terminate() 釋放資源:

worker.terminate(); // 

三、通信機制關鍵點

1. 數據傳輸機制

? 結構化克隆算法:支持大多數數據類型(如對象、數組、Date),但無法處理函數、DOM 節點等。
? Transferable Objects:通過 transfer 參數直接轉移數據所有權,避免復制開銷(如 ArrayBuffer):

// 主線程
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]); // 
2. 消息傳遞特性

? 異步非阻塞:消息處理不會阻塞線程。
? 事件驅動:通過 onmessageonerror 處理消息和異常。

3. 共享數據與跨域限制

? 數據隔離:Worker 與主線程無法共享內存,需通過消息傳遞交換數據。
? 同源策略:Worker 腳本需與主線程同源,跨域需通過 CORS 或代理。


四、高級應用場景

  1. 計算密集型任務:如大數據處理、圖像加密(示例見網頁):

    // Worker 線程加密字符串
    self.onmessage = (e) => {const encrypted = encrypt(e.data);self.postMessage(encrypted);
    };
    
  2. 跨頁面通信:使用 SharedWorker 實現多標簽頁數據同步(網頁):

    // 主線程
    const sharedWorker = new SharedWorker('shared.js');
    sharedWorker.port.onmessage = (e) => console.log(e.data);
    
  3. 性能優化
    ? 合理控制 Worker 數量,避免資源浪費。
    ? 使用 Transferable Objects 減少大數據傳輸開銷。


五、注意事項

  1. 錯誤處理:通過 onerror 監聽 Worker 異常:

    worker.onerror = (error) => console.error('Worker error:', error); // 
    
  2. 調試技巧
    ? 瀏覽器開發者工具的 Sources 面板查看 Worker 代碼。
    ? 在 Worker 中使用 console.log 輸出調試信息。

  3. 適用性評估
    ? 僅處理 CPU 密集型任務,避免因線程創建和通信開銷影響簡單任務。


總結

Web Worker 通過 消息傳遞機制 實現主線程與 Worker 的高效交互,適用于提升復雜計算的性能和頁面響應性。實際開發中需結合任務類型選擇 Worker 類型,并注意數據傳輸優化與錯誤處理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72471.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72471.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72471.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言zixue

該文主要是記錄我學習中遇到的一些重點、易出問題的內容 教材p16.17 先從一個簡單的例子開始吧 #include <stdio.h> //編譯預處理命令 int main() //程序的主函數 {printf("To C"); //輸出語句return 0; //返回語句 } #include <stdio.h>是編譯預…

卷積神經網絡(CNN)的主要架構

卷積神經網絡&#xff08;CNN, Convolutional Neural Networks&#xff09;是深度學習中最重要的模型之一&#xff0c;廣泛應用于計算機視覺、目標檢測、語義分割等任務。自 LeNet 誕生以來&#xff0c;CNN 結構經歷了多個重要發展階段&#xff0c;出現了許多經典架構&#xff…

【開源代碼解讀】AI檢索系統R1-Searcher通過強化學習RL激勵大模型LLM的搜索能力

關于R1-Searcher的報告&#xff1a; 第一章&#xff1a;引言 - AI檢索系統的技術演進與R1-Searcher的創新定位 1.1 信息檢索技術的范式轉移 在數字化時代爆發式增長的數據洪流中&#xff0c;信息檢索系統正經歷從傳統關鍵詞匹配到語義理解驅動的根本性變革。根據IDC的統計…

從0到1入門Docker

一、快速入門 Docker run命令中的常見參數 -d&#xff1a;讓容器后臺運行--name&#xff1a;給容器命名&#xff08;唯一&#xff09;-e&#xff1a;環境變量-p&#xff1a;宿主機端口映射到容器內端口鏡像名稱結構&#xff1a;Repository &#xff1a;TAG&#xff08;鏡像名&…

接口自動化入門 —— Jmeter實現在接口工具中關聯接口處理方案

1. JMeter 接口關聯處理的核心概念 接口關聯是指在多個接口請求之間共享數據&#xff0c;例如將一個接口的返回值作為另一個接口的輸入參數。常見的場景包括&#xff1a; 使用登錄接口返回的 Token 作為后續接口的認證信息。 將一個接口返回的 ID 作為另一個接口的請求參數。…

Flink-學習路線

最近想學習一下Flink&#xff0c;公司的實時需求還是不少的&#xff0c;因此結合ai整理了一份學習路線&#xff0c;記錄一下。 當然&#xff0c;公司也有Scala版本Flink框架&#xff0c;也學習了一下。這里只說Java版本 1. Java基礎 目標: 掌握Java編程語言的基礎知識。 內容…

ranger集成starrock報錯

org.apache.ranger.plugin.client.HadoopException: initConnection: Unable to connect to StarRocks instance, please provide valid value of field : {jdbc.driverClassName}.. com.mysql.cj.jdbc.Driver. 可能的原因 JDBC 驅動缺失&#xff1a;運行環境中沒有安裝 MySQL …

python Jsonpath表達式語法取值

python Jsonpath 語法規則&#xff1a; 演示數據&#xff1a;{"status":"0","msg":"成功","data": [ {"foo1": "bar1"},{"foo1": "bar2"}]} 根節點&#xff1a;$ $.status $.…

Blender-MCP服務源碼2-依賴分析

Blender-MCP服務源碼2-依賴分析 有個大佬做了一個Blender-MCP源碼&#xff0c;第一次提交代碼是【2025年3月7號】今天是【2025年月15日】也就是剛過去一周的時間&#xff0c;所以想從0開始學習這個代碼&#xff0c;了解一下大佬們的開發思路 1-核心知識點 from mcp.server.fas…

反射(第三篇)、代理模式、靜態代理和動態代理、InvocationHandler實際應用

DAY11.3 Java核心基礎 反射&#xff08;第三篇&#xff09; 前兩篇我們學習了反射的概念和基本操作 實際開發中&#xff0c;反射應用于那里&#xff1f; 動態代理 java中的動態代理就是一個重要的作用 代理模式 代理模式是java中常用的設計模式 指的是在處理一個業務邏輯…

Unity 封裝一個依賴于MonoBehaviour的計時器(上) 基本功能

靈感來自下面這本書的協程部分,因此我就自己嘗試寫了一個 我的新書Unity3D游戲開發&#xff08;第3版&#xff09; | 雨松MOMO程序研究院 如果你不知道什么是協程:unity保姆級教程之協同程序_unity協同-CSDN博客 一句話概括:協程就是單線程的異步操作,其作用于Unity的主線程 1…

數學建模 第一節

目錄?????? 前言 一 優化模型的類型 二 線性規劃1 線性規劃2 三 0-1規劃 總結 前言 數學建模主要是將問題轉化為模型&#xff0c;然后再以編程的形式輸出出來 算法都知道&#xff0c;數學建模也需要用到算法&#xff0c;但是不是主要以編程形式展示&#xff0c;而是…

Vulkan視頻解碼decode顯示display之同步

在ReleaseDisplayedPicture函數中消耗圖片資源并且顯示display完成&#xff0c;設置兩個標志m_hasConsummerSignalFence true 和m_hasConsummerSignalSemaphore true virtual int32_t ReleaseDisplayedPicture(DecodedFrameRelease** pDecodedFramesRelease, uint32_t nu…

網絡空間安全(32)Kali MSF基本介紹

前言 Metasploit Framework&#xff08;簡稱MSF&#xff09;是一款功能強大的開源安全漏洞檢測工具&#xff0c;被廣泛應用于滲透測試中。它內置了數千個已知的軟件漏洞&#xff0c;并持續更新以應對新興的安全威脅。MSF不僅限于漏洞利用&#xff0c;還包括信息收集、漏洞探測和…

設計模式學習記錄

設計模式23種 創建型抽象工廠模式工廠模式生成器模式原型模式單例模式 結構型適配器模式橋接模式組合模式裝飾模式外觀模式享元模式代理模式 行為型責任鏈模式命令模式解釋器模式迭代器模式中介者模式備忘錄模式觀察者模式狀態模式策略模式模版方法模式訪問者模式 創建型 與對…

2.5 python接口編程

在現代軟件開發的復雜生態系統中&#xff0c;不同系統、模塊之間的交互協作至關重要。接口編程作為一種關鍵機制&#xff0c;定義了組件之間的通信規范與交互方式。Python 憑借其卓越的靈活性、豐富的庫資源以及簡潔易讀的語法&#xff0c;在接口編程領域占據了重要地位&#x…

mesh開發解析

開源的Mesh網絡協議棧及相關項目&#xff1a; 1.B.A.T.M.A.N.(Better Approach to Mobile Ad-hoc Networking)? 簡介&#xff1a;B.A.T.M.A.N.是一種用于多跳自組織網絡的路由協議&#xff0c;適用于無線Mesh網絡。它通過優化數據傳輸路徑&#xff0c;確保網絡的高可靠性和動…

PyTorch PINN實戰:用深度學習求解微分方程

在人工智能與計算數學的交匯點&#xff0c;物理信息神經網絡&#xff08;Physics-Informed Neural Networks&#xff0c;PINN&#xff09;正引領著一場求解微分方程的革命。傳統上&#xff0c;微分方程是描述自然現象和工程問題中各種關系的重要工具&#xff0c;但其求解往往依…

【WiFi 7核心技術及未來挑戰】

作為剛剛開始從事這一領域的人&#xff0c;淺淺學習了一下WiFi 7&#xff08;IEEE 802.11be&#xff09;。Wi-Fi 7發展迅速&#xff0c;提供前所未有的速度、更低的延遲和更高的可靠性。但從頻譜政策到能效挑戰&#xff0c;再到成本&#xff0c;仍有許多問題亟待解決。 Wi-Fi 7…

Oracle Linux Server 7.9安裝fail2ban

yum search oracle-epel-release yum install oracle-epel-release-el7 search fail2ban yum install fail2ban nano /etc/fail2ban/jail.d/00-firewalld.conf # defalut這里是設定全局設置&#xff0c;如果下面的監控沒有設置就以全局設置的值設置。 [DEFAULT] # 用于指定哪…