.hljs-comment,.hljs-quote{color:#d4d0ab}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ffa07a}.hljs-built_in,.hljs-builtin-name,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5ab35}.hljs-attribute{color:gold}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#abe338}.hljs-section,.hljs-title{color:#00e0e0}.hljs-keyword,.hljs-selector-tag{color:#dcc6e0}.markdown-body pre,.markdown-body pre>code.hljs{background:#2b2b2b;color:#f8f8f2}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-builtin-name,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}}
Map、Set 和 Object 区别
特性/对比项 | Map | Set | Object |
---|---|---|---|
数据结构 | 键值对集合 | 唯一值的集合 | 键值对集合(键通常是字符串或符号) |
键类型 | 任意类型(包括对象、函数等) | 不适用 | 字符串或符号(数字会被隐式转换为字符串形式的键。) |
值唯一性 | 键唯一,值可重复 | 所有值都是唯一的 | 允许重复值 |
插入顺序 | 保持插入顺序 | 保持插入顺序 | ES6之后保持插入顺序(数字键除外) |
查询大小 | .size 属性 | .size 属性 | 需要手动计算属性数量 |
性能 | 更适合频繁增删操作 | 适合存储唯一值 | 动态增删键值对效率较低 |
迭代支持 | 直接支持迭代 (forEach , for...of ) | 直接支持迭代 (forEach , for...of ) | 需要使用 Object.keys() , Object.values() , 或 Object.entries() |
浏览器沙盒
浏览器沙盒(Browser Sandbox)是一种安全机制,旨在限制网页内容对用户系统的访问权限,从而保护用户免受恶意软件、网络钓鱼和其他在线威胁的侵害。通过将网页内容和脚本运行在一个隔离的环境中,即使这些内容存在安全隐患,也能有效防止它们对系统造成损害。
沙盒的主要功能和特性包括:
- 隔离性:沙盒技术确保了每个标签页或每个网页都在其自己的独立环境中运行,这减少了不同网页之间以及网页与操作系统之间的潜在交互,降低了恶意代码利用漏洞进行攻击的风险。
- 权限控制:沙盒可以严格控制网页能够访问的资源类型和数量。例如,它可以阻止网页未经允许就访问用户的文件系统、摄像头或麦克风等硬件设备。
- 安全性增强:通过限制网页执行某些操作的能力,沙盒有效地增加了额外的安全层,使得即便浏览器本身存在漏洞,攻击者也难以利用这些漏洞执行有害操作。
- 崩溃隔离:如果某个网页或插件导致浏览器崩溃,沙盒可以确保这种崩溃不会影响到其他正在运行的网页或其他浏览器组件,提高了整体稳定性和用户体验。
Promise的静态方法
-
Promise.resolve
返回一个以给定值为成功状态的
Promise
对象 -
Promise.reject
返回一个以给定值为失败状态的
Promise
对象 -
Promise.all
全部成功才成功,只要有一个失败就失败。
Promise.all
返回的结果数组会按照传入的 Promise 顺序排列,而不是按照完成的顺序。 -
Promise.race
Promise.race
会返回第一个被解决(无论是成功还是失败)的 Promise 的结果。Promise.race
通常用于需要快速响应的场景。 -
Promise.allSettled
Promise.allSettled
是 ES2020 引入的新方法。它接受一个 Promise 实例数组作为参数,并返回一个新的 Promise。这个新的 Promise 会在所有传入的 Promise 都完成(无论是成功还是失败)时被解决,返回一个包含所有结果的数组。Promise.allSettled
非常适合用于需要处理多个异步任务,并且希望获取所有任务的结果(无论成功还是失败)的场景。Promise.allSettled
返回的结果数组中的每个元素都是一个对象,包含status
和value(成功)
或reason(失败)
属性。 -
Promise.any
Promise.any
是 ES2021 引入的新方法。它接受一个 Promise 实例数组作为参数,并返回一个新的 Promise。这个新的 Promise 会在第一个成功的 Promise 完成时被解决,返回该 Promise 的结果。如果所有 Promise 都失败,Promise.any
会返回一个AggregateError
。Promise.any
非常适合用于需要获取第一个成功结果的场景。如果所有 Promise 都失败,Promise.any
会返回一个AggregateError
,包含所有失败的原因。
虚拟列表
虚拟列表是一种用于优化长列表渲染的技术,特别适用于那些包含大量数据项的应用场景。通过只渲染当前可见区域的数据项,可以显著减少DOM元素的数量,从而提升应用的性能和响应速度。
webSocket 断开之后怎么办
断网重连
-
监听连接状态:首先,您需要监听WebSocket的
onclose
事件来检测连接何时关闭。这可以帮助您了解是否由于网络问题导致了连接中断。 -
设置重连尝试逻辑:
- 在检测到连接关闭后,可以立即尝试重新连接,或者等待一段时间后再尝试。
- 使用指数退避算法(例如首次等待2秒,然后4秒、8秒等)增加每次重试前的等待时间,以避免对服务器造成过大压力。
- 设置最大重试次数限制,防止在无法恢复的情况下无限重试。
-
成功重连后的处理:一旦成功重连,可能需要重新发送在断开期间未能成功发送的消息,或者同步客户端与服务器之间的状态。
let ws = null;
// 是否正在尝试重新连接
let isReconnecting = false;
// 重连尝试次数
let reconnectAttempts = 0;
// 最大重连次数
const MAX_RECONNECT_ATTEMPTS = 5;
/**
* 初始化WebSocket连接
*/
function initWebSocket() {
// 替换为你的WebSocket服务器地址
const wsUrl = 'ws://yourserver.com/socket';
ws = new WebSocket(wsUrl);
// 当WebSocket连接成功打开时触发
ws.onopen = function(event) {
console.log('WebSocket连接已打开', event);
reconnectAttempts = 0; // 成功连接后重置重连计数器
};
// 当收到消息时触发
ws.onmessage = function(event) {
console.log('收到消息:', event.data);
};
// 当WebSocket连接关闭时触发
ws.onclose = function(event) {
console.log('WebSocket连接关闭:', event);
// 如果不是主动重连且未达到最大重试次数,则进行重连
if (!isReconnecting && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
setTimeout(() => { // 等待一段时间后尝试重新连接
isReconnecting = true;
reconnectAttempts++;
initWebSocket(); // 尝试重新初始化WebSocket连接
}, 2000); // 等待2秒
} else {
console.error('达到最大重连次数,停止尝试');
}
};
// 当发生错误时触发
ws.onerror = function(event) {
console.error('WebSocket错误:', event);
};
}
// 页面加载完成后初始化WebSocket
window.onload = function() {
initWebSocket();
};
自动心跳
-
目的:心跳机制的主要目的是保持客户端和服务器之间的连接活跃,避免由于长时间没有数据传输而导致的连接被中间设备(如防火墙或代理服务器)自动断开。
-
实现方法:
- 客户端定期向服务器发送“ping”消息,服务器接收到后回复一个“pong”响应。
- 如果客户端在设定的时间间隔内没有收到“pong”响应,则认为连接已失效,并触发重连逻辑。
- 同样,服务器也可以主动发送“ping”,客户端回应“pong”来确保双向通信的有效性。
-
注意事项:
- 选择合适的心跳间隔非常重要。如果间隔太短,会增加不必要的网络流量;如果间隔太长,则可能不足以维持连接的活跃状态。
- 确保心跳消息尽可能简单,以减少带宽消耗和服务器负载。
// 心跳定时器
let heartbeatTimer = null;
// 心跳间隔时间(毫秒),比如30秒
const HEARTBEAT_INTERVAL = 30000;
// 开始心跳检测
function startHeartbeat() {
if (heartbeatTimer) return; // 如果已经有定时器在运行,则不创建新的定时器
sendPing(); // 立即发送一次ping
// 设置定期发送ping消息的定时器
heartbeatTimer = setInterval(sendPing, HEARTBEAT_INTERVAL);
}
// 停止心跳检测
function stopHeartbeat() {
if (heartbeatTimer) { // 如果存在定时器,则清除它
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
}
// 发送ping消息
function sendPing() {
if (ws.readyState === WebSocket.OPEN) { // 检查WebSocket是否处于打开状态
ws.send('ping'); // 实际应用中可能需要发送特定格式的消息
} else {
console.error('WebSocket连接未打开,无法发送ping');
}
}
// 在WebSocket连接成功建立时启动心跳
ws.onopen = function(event) {
console.log('WebSocket连接已打开', event);
reconnectAttempts = 0; // 成功连接后重置重连计数器
startHeartbeat(); // 启动心跳检测
};
// 在WebSocket连接关闭时停止心跳
ws.onclose = function(event) {
console.log('WebSocket连接关闭:', event);
stopHeartbeat(); // 连接关闭时停止心跳检测
// ... 继续之前的重连逻辑 ...
};
通过结合使用断网重连和心跳机制,可以大大提高WebSocket应用的稳定性和可靠性,确保即使在网络条件不佳的情况下也能提供良好的用户体验。
响应式失效(toRefs 和 toRef)
- 范围:
toRefs
适用于整个响应式对象,将其所有属性转化为响应式引用;而toRef
仅针对单一属性。 - 目标:当你想要解构一个响应式对象并保留每个属性的响应性时,应使用
toRefs
。如果你只想专注于某个特定属性,则使用toRef
更合适。
排序算法
冒泡排序
通过重复遍历列表,比较相邻元素并交换它们的位置来排序列表。每次遍历后,最大的元素会“冒泡”到列表的末尾。
function bubbleSort(arr) {
let n = arr.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 交换
}
}
}
return arr;
}
选择排序
从未排序部分中找到最小(或最大)元素,将其与未排序部分的第一个元素交换位置。
function selectionSort(arr) {
const n = arr.length;
for (let i = 0; i < n; i++) {
let minIndex = i;
for (let j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex !== i) {
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // 交换
}
}
return arr;
}
插入排序
构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
let current = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = current;
}
return arr;
}
希尔排序
基于插入排序的改进版,通过使用增量间隔逐步减少的方式来排序数组。
function shellSort(arr) {
let n = arr.length;
for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
for (let i = gap; i < n; i++) {
let temp = arr[i];
let j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
return arr;
}
归并排序
采用分治法策略,首先递归分解数组直到每个子数组只有一个元素,然后合并这些子数组形成最终的有序数组。
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const middle = Math.floor(arr.length / 2);
const left = arr.slice(0, middle);
const right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
let result = [];
let leftIndex = 0;
let rightIndex = 0;
while (leftIndex < left.length && rightIndex < right.length) {
if (left[leftIndex] < right[rightIndex]) {
result.push(left[leftIndex++]);
} else {
result.push(right[rightIndex++]);
}
}
return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}
快速排序
采用分治法策略,选定一个“基准”,将数组分为两部分,使得一部分的所有元素都小于另一部分的所有元素,然后递归地对这两部分进行排序。
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr[pivotIndex];
const left = [];
const right = [];
for (let i = 0; i < arr.length; i++) {
if (i === pivotIndex) continue;
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
堆排序
利用堆这种数据结构设计的排序算法,首先将待排序序列构造成一个大顶堆,然后依次取出堆顶元素(最大值),再调整剩余元素重新成为堆。
function heapSort(arr) {
buildMaxHeap(arr);
for (let i = arr.length - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
maxHeapify(arr, 0, i);
}
return arr;
}
function buildMaxHeap(arr) {
const n = arr.length;
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
maxHeapify(arr, i, n);
}
}
function maxHeapify(arr, i, heapSize) {
const left = 2 * i + 1;
const right = 2 * i + 2;
let largest = i;
if (left < heapSize && arr[left] > arr[largest]) largest = left;
if (right < heapSize && arr[right] > arr[largest]) largest = right;
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
maxHeapify(arr, largest, heapSize);
}
}
计数排序
适用于一定范围内的整数排序,通过统计每个整数出现的次数来确定各个数字的位置。注意: 此函数仅适用于非负整数
function countingSort(arr) {
const max = Math.max(...arr);
const count = new Array(max + 1).fill(0);
const output = new Array(arr.length);
for (const num of arr) {
count[num]++;
}
for (let i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
for (let i = arr.length - 1; i >= 0; i--) {
output[count[arr[i]] - 1] = arr[i];
count[arr[i]]--;
}
return output;
}
桶排序
将数组分到有限数量的桶里,每个桶内再进行排序(通常使用快速排序或其他排序算法)。
function bucketSort(arr, bucketSize = 5) {
if (arr.length === 0) return arr;
const minValue = Math.min(...arr);
const maxValue = Math.max(...arr);
const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
const buckets = Array.from({ length: bucketCount }, () => []);
arr.forEach(val => {
const bucketIndex = Math.floor((val - minValue) / bucketSize);
buckets[bucketIndex].push(val);
});
return buckets.reduce((prev, curr) => prev.concat(curr.sort((a, b) => a - b)), []);
}
基数排序
按位排序,从最低有效位开始逐位对所有数字进行排序。
function radixSort(arr) {
const maxDigitLength = getMaxDigits(arr);
for (let digitPlace = 0; digitPlace < maxDigitLength; digitPlace++) {
const buckets = Array.from({ length: 10 }, () => []);
arr.forEach(num => {
const digit = getDigit(num, digitPlace);
buckets[digit].push(num);
});
arr = [].concat(...buckets);
}
return arr;
function getDigit(num, place) {
return Math.floor(Math.abs(num) / Math.pow(10, place)) % 10;
}
function getMaxDigits(nums) {
let maxDigits = 0;
nums.forEach(num => {
maxDigits = Math.max(maxDigits, num.toString().length);
});
return maxDigits;
}
}
部分方法还有一些能够优化的地方,可以去看看这位大佬整理的文章。
重温前端10大排序算法(长文建议收藏)通过相邻元素的比较和交换,使得每一趟循环都能找到未有序数组的最大值或最小值。 - 掘金
webpack 和 vite 区别
特性 | Webpack | Vite |
---|---|---|
启动速度 | 较慢,需打包整个项目才能启动开发服务器。 | 非常快,基于ESM按需加载,启动迅速。 |
热更新(HMR) | 支持,但随项目规模增大可能变慢。 | 支持,且通常比Webpack更快。 |
配置复杂度 | 复杂,高度可定制,适合复杂项目。 | 简单,默认配置满足多数需求,易于上手。 |
构建效率 | 生产环境构建优化好,但首次构建时间长。 | 生产环境使用Rollup高效构建;开发环境快速响应。 |
适用场景 | 大型、复杂项目,需要高级定制化构建流程。 | 追求开发体验和速度的新项目,特别是现代框架。 |
核心理念 | 一切皆模块,通过loader和plugin扩展功能。 | 利用浏览器ESM支持,实现极速冷启动和编译。 |
路由传参
query
query
参数是通过URL的查询字符串传递的数据,形式为?key=value&key2=value2
。
- 数据直接显示在URL中,因此可以通过浏览器地址栏直接访问。
- 刷新页面不会丢失参数。
- 适合用于需要共享链接并且希望接收方能够直接看到参数的情况。
// 跳转并传递query参数
this.$router.push({ path: '/user', query: { id: '123', name: 'Zhang' }})
// http://yourdomain.com/user?id=123&name=Zhang
// 获取query参数
console.log(this.$route.query.id) // 输出: '123'
params
params
参数是嵌入到路由路径中的动态段,例如:id
。
- 参数不直接显示在URL的查询字符串部分,而是作为路径的一部分。
- 如果刷新页面,且路由配置中没有设置永久重定向或其他保持参数的策略,参数可能会丢失。
- 更加美观,适合于那些不需要直接通过URL分享的状态信息。
- 使用 path 属性时,不能使用 params
// 定义路由时使用动态段
const routes = [{ path: '/user/:id', component: User }]
// 跳转并传递params参数
this.$router.push({ name: 'user', params: { id: '123' }})
// 获取params参数
console.log(this.$route.params.id) // 输出: '123'
props
props
是一种将数据作为属性传递给组件的方式。当与路由结合使用时,可以更灵活地向目标组件传递数据。
- 提供了更高的灵活性,允许你选择如何处理路由参数(如直接作为props传递、转换后再传递等)。
- 可以使组件更加独立,因为它们不再直接依赖于$route对象。
// 路由
const routes = [
{ path: '/user/:id', component: User, props: true }
]
// 接收:id参数
export default {
props: ['id'],
// ...
}
html5 新特性
-
语义化标签:header nav main footer section aside article
好处:内容语义化 + 代码语义化
语义化是指根据内容使用合适的标签,就是用标签做正确的事 对机器友好,文字表现力丰富,有利于搜索引擎爬虫爬取有效信息,有利于seo(搜索引擎优化),支持读屏软件,可以根据文章自动生成目录
对开发者友好,增强了可读性,结构更加清晰,便于团队的开发与维护
-
音频和视频:audio video
-
audio
<audio controls> <source src="example.mp3" type="audio/mpeg"> 您的浏览器不支持 audio 元素。 </audio>
属性
- autoplay:自动播放音频(注意:某些移动浏览器可能出于用户体验考虑限制此属性的效果)。
- loop:循环播放音频。
- muted:静音播放。
- preload:规定是否/如何预加载音频文件(可选值:
auto
,metadata
,none
)。
-
video
<video width="320" height="240" controls> <source src="example.mp4" type="video/mp4"> <source src="example.ogg" type="video/ogg"> 您的浏览器不支持 video 标签。 </video>
除了与
<audio>
标签共享的一些属性还提供了一些特有的属性:-
poster:指定视频加载前显示的图像。
-
defaultMuted:设置默认静音状态。
-
-
-
表单
- 表单类型:number date time email …
- 表单属性:placeholder(提示信息) required(必填) pattern(正则) min max autofocus(页面加载时自动获取焦点)等
-
存储方式:
- localStorage:永久保存,除非手动删除
- sessionStorage:关闭浏览器后清空
-
dom获取
document.querySelector/all -
canvas画布 可以通过JavaScript进行绘制图形、动画、图表等的强大工具
-
Geolocation
允许用户与网站或应用分享他们地理位置的信息。if ("geolocation" in navigator) { console.log("Geolocation is supported!"); } else { console.log("Geolocation is not supported."); } // 获取用户的当前位置 navigator.geolocation.getCurrentPosition(function(position) { console.log("Latitude is :", position.coords.latitude); console.log("Longitude is :", position.coords.longitude); });
-
全双工通信协议Websoket
WebSocket 提供了一种在浏览器和服务器之间进行实时双向通信的机制,适用于实时聊天、实时数据更新等场景。
// server.js
// 服务器
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (socket) => {
console.log('New client connected');
// 当收到消息时
socket.on('message', (message) => {
console.log(`Received message => ${message}`);
// 向客户端发送消息
socket.send('Message received');
});
// 当断开连接时
socket.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server is running on ws://localhost:8080');
// 客户端
const socket = new WebSocket('ws://localhost:8080');
socket.onopen = function() {
console.log('Connected to the server');
};
socket.onmessage = function(event) {
console.log(`Message from server: ${event.data}`);
};
socket.onclose = function() {
console.log('Disconnected from server');
};
function sendMessage() {
console.log('Sending message to server');
socket.send('Hello, Server!');
}
- Web Worker 在浏览器中创建后台线程,执行 JavaScript 代码而不影响页面的响应性能。
Web Worker
-
Web Worker
允许在 js 主线程之外开辟新的 Worker 线程。利用 js 操作多线程的能力
-
在我们有大量运算任务时,可以把运算任务交给 Worker 线程去处理 当 Worker 线程计算完成,再把结果返回给 js 主线程 js 主线程只用专注处理业务逻辑,不用耗费过多时间去处理大量复杂计算 减少了阻塞时间,也提高了运行效率,页面流畅度和用户体验自然而然也提高了
-
Worker 在另一个全局上下文中运行,与当前的 window 不同!
Worker 线程是在浏览器环境中被唤起的
在 Worker 线程上下文中, window, parent, document 等属性都不可用
-
但是可以使用 self 来代替 window
可以使用 self.postMessage() 方法来向 js 主线程发送消息
可以使用 self.onmessage 来监听 js 主线程发送的消息
-
主线程与 worker 线程之间的数据传递是传值而不是传地址。所以你会发现,即使你传递的是一个Object,并且被直接传递回来,接收到的也不是原来的那个值了
-
监听错误信息
error // 当worker内部出现错误时触发
messageerror // 当 message 事件接收到无法被反序列化的参数时触发
-
关闭
myWorker.terminate() // 主线程终止 worker 线程
self.close() // worker 线程终止自身
- 无论谁关闭 worker,worker 线程当前的 Event Loop 中的任务会继续执行。但下一个 Event Loop 不会继续执行
- 主线程关闭,worker 线程会继续执行,但是主线程不会收到消息
- worker 线程关闭,Event Loop 执行完之前 主线程还能收到消息
-
importScripts() 在 worker 线程中导入其他 js 文件
-
const myWorker = new Worker(aURL, options);
- options
- type: ‘classic’ | ‘module’ // 表示 worker 线程的类型,默认为 classic
- credentials: ‘omit’ | ‘same-origin’ | ‘include’ // 表示 worker 线程的凭证,默认为 omit
- name: string // 表示 worker 线程的名称,默认为空字符串
- options
-
postMessage() 主线程和 worker 线程之间传递数据 可以是由结构化克隆算法处理的任何值或 JavaScript 对象,包括循环引用。 不能处理:
- Error 以及 Function 对象;
- DOM 节点
- 对象的某些特定参数不会被保留
- RegExp 对象的 lastIndex 字段不会被保留
- 属性描述符,setters 以及 getters(以及其他类似元数据的功能)同样不会被复制。例如,如果一个对象用属性描述符标记为 read-only,它将会被复制为 read-write
- 原形链上的属性也不会被追踪以及复制。
// main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const myWorker = new Worker('./worker.js', {
type: 'module', // 指定 worker.js 的类型
name: 'myWorker', // 给worker线程命名
}); // 创建worker
// const obj = { name: '小明'}
// 利用self判断是否在主线程
// if (self === window) {
// console.log('代码运行在主线程');
// } else {
// console.log('代码运行在一个工作线程');
// }
myWorker.addEventListener('message', e => { // 接收消息
console.log(e.data); // worker线程发送的消息
// myWorker.terminate(); // 关闭 worker
});
// 这种写法也可以
// myWorker.onmessage = e => { // 接收消息
// console.log(e.data);
// };
myWorker.postMessage('Greeting from Main.js'); // 向 worker 线程发送消息,对应 worker 线程中的 e.data
// myWorker.postMessage(obj);
// myWorker.terminate(); // 终止worker线程
</script>
</body>
</html>
// worker.js(worker线程)
// self.addEventListener('message', e => { // 接收到消息
// console.log(self);
// console.log(e.data); // Greeting from Main.js,主线程发送的消息
// self.postMessage('Greeting from Worker.js'); // 向主线程发送消息
// // self.postMessage(e.data)
// self.close(); // 关闭worker线程
// });
// 主线程关闭
// self.addEventListener('message', e => {
// postMessage('Greeting from Worker');
// setTimeout(() => {
// console.log('setTimeout run');
// postMessage('Greeting from SetTimeout');
// });
// Promise.resolve().then(() => {
// console.log('Promise run');
// postMessage('Greeting from Promise');
// })
// for (let i = 0; i < 1001; i++) {
// if (i === 1000) {
// console.log('Loop run');
// postMessage('Greeting from Loop');
// }
// }
// });
// worker线程关闭
// setTimeout 宏任务 会放在下一个EventLoop中执行 下一个EventLoop 关闭worker,不执行
// for循环为当前宏任务中的一部分 Promise.resolve().then 微任务
self.addEventListener('message', e => {
postMessage('Greeting from Worker');
self.close(); // 关闭 worker
setTimeout(() => {
console.log('setTimeout run');
postMessage('Greeting from SetTimeout');
});
Promise.resolve().then(() => {
console.log('Promise run');
postMessage('Greeting from Promise');
})
for (let i = 0; i < 3; i++) {
if (i === 2) {
console.log('Loop run');
postMessage('Greeting from Loop');
}
}
});
// importScripts 导入其他js文件
importScripts('./utils.js');
// import add from './utils.js';
// console.log(self);
// console.log(add(1, 2));
// export default self;
// utils.js
// worker线程引用其他js文件
// const add = (a, b) => a + b;
export default function add(a, b){
return a + b;
}
作用域 和 作用域链
作用域
作用域是定义变量可访问范围的一套规则,决定了程序中哪里可以访问或使用这些变量。 分为词法作用域和动态作用域。
按查找规则分为:
- 词法作用域(Lexical Scope) :在代码编写时确定,由代码嵌套结构决定。变量查找是从当前作用域向上查找,直到全局作用域。
- 动态作用域(Dynamic Scope) :变量查找是在函数调用时根据调用栈来决定,而不是代码结构。比如this。
按作用域的范围分为:
-
全局作用域
在代码的最外层定义的变量拥有全局作用域,它们可以在代码的任何地方被访问。在浏览器环境下,全局作用域通常绑定到
window
对象上。在node环境下,全局作用域通常绑定到global
对象上注意: 使用
let
和const
声明的变量不会挂载到window
对象上。这一改变是ES6引入块级作用域的一个重要特性,旨在解决变量声明提升和变量污染问题。解决方案是TDZ。 -
函数作用域 在函数内部定义的变量拥有函数作用域,它们只在该函数内部及嵌套的函数内部可见。
-
块级作用域(ES6引入) 使用
let
和const
声明的变量具有块级作用域,这意味着它们只在定义它们的代码块(如if语句或for循环)内部可见。
暂时性死区(TDZ, Temporal Dead Zone) 在使用let
和const
声明变量之前,该变量在其声明之前的区域被称为暂时性死区,任何访问该变量的尝试都将导致错误。
作用域链
-
当JavaScript引擎需要查找一个变量的值时,它会遵循一定的规则去查找,这个查找路径就是作用域链。作用域链是由当前执行环境的作用域与其所有外部作用域组成的链式结构。
-
每个函数在创建时,都会生成一个新的执行上下文,这个执行上下文中会包含一个指向其外部作用域的引用,这样就形成了一个链式结构。
-
查找变量时,引擎首先会在当前作用域查找,如果找不到,就会向上一级作用域继续查找,直到全局作用域。如果在全局作用域也未找到,则认为该变量未定义。
-
作用域链确保了函数可以访问其自身作用域以及包含它的所有外部作用域中的变量,但外部作用域无法访问函数内部的变量,体现了JavaScript的词法作用域特性。
原型 和 原型链
原型(Prototype)
每个JavaScript对象都有一个内部属性,称为[[Prototype]]
,它指向另一个对象,即该对象的原型,用于存放所有实例共享的属性和方法,当一个函数作为构造函数创建实例时,这个实例的内部将有一个隐式链接(proto)指向构造函数的prototype
对象,这就是原型链的基础。
原型链(Prototype Chain)
原型链是JavaScript实现继承的基础,形成了一种链式的继承结构。当试图访问对象的一个属性时,如果没有在该对象本身找到此属性,则会在其原型对象中继续寻找,依次向上直到原型链的末端。如果在整个原型链中都没有找到该属性,则返回undefined
。
new 操作符(原理 + 手写)
在 JavaScript 中,new
是一个关键字,用于创建用户定义对象的实例或内置对象的实例。它主要用于面向对象编程(OOP)中,通过构造函数来创建新对象。
工作过程
- 创建新对象
- 设置原型链
- 绑定this值
- 执行构造函数
- 返回值处理
-
如果构造函数没有明确返回一个对象(或者返回
null
、undefined
),那么new
操作符会自动返回新创建的对象。 -
如果构造函数返回了一个对象,那么这个返回的对象将会替代步骤1中创建的新对象成为最终的结果。如果返回的是非对象值(如数字、字符串等),则忽略返回值,仍然返回新创建的对象。
-
手写 new
function Person(name, age) {
this.name = name;
this.age = age;
return {
name:this.name,
age:this.age,
tag:'haha'
}
}
Person.prototype.sayName = function () {
console.log(this.name);
}
// 手写new
function objectFactory(fn, ...args) {
// arguments 所有参数 类数组
// 1. 空对象创建
// const obj = new Object();
const obj = {};
// 2. 设置原型链
obj.__proto__ = fn.prototype;
// 3. 绑定this值 + 4. 执行构造函数
const result = fn.apply(obj, args); // 返回值
// 5. 返回值处理
// 如果返回对象 返回对象
// 如果返回简单数据类型或者没有 就返回 obj 可以是null(空对象)
return typeof result === "object" ? result : obj;
}
// 检测
let awei = objectFactory(Person, 'awei', 20)
// console.log(awei.name);
// awei.sayName();
console.log(awei);
setTimeout/setInterval 不准的原因
setTimeout/setInterval
setTimeout()
方法用于在指定的毫秒数后调用函数或计算表达式。 setInterval()
方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
返回一个 定时器ID(数字),可以将这个ID传递给clearTimeout()
或clearInterval()
来关闭定时器。
setTimeout(functionRef, delay, param1, param2, /* …, */ paramN)
setInterval(func, delay, arg1, arg2, /* …, */ argN)
都是有三个参数
functionRef
:(必填)当定时器经过delay
后要执行的函数delay
:(可选)定时器在执行指定的函数或代码之前应该等待的时间,单位是毫秒。如果省略该参数,则使用值 0,意味着“立即”执行,或者更准确地说,在下一个事件循环执行。(是宏任务)param1/arg1
、paramN/argN
:(可选)会被传递给由functionRef
指定的函数的附加参数。
延时比指定值更长的原因
造成setTimeout
和setInterval
不准确的原因,MDN官方已经帮我们详细的整理好了,可以通过下面的链接查看详细内容
Window:setTimeout() 方法 - Web API | MDN
在这里,我将 MDN 中的原因再做了一个整理
-
嵌套超时
HTML标准
中规定,setTimeout
如果被嵌套调用5次,从第五次开始,浏览器将强制执行4ms
的最小超时。 -
非活动标签的超时(失活页面)
为了优化后台标签的加载损耗(以及降低耗电量),浏览器会在非活动标签中强制执行一个最小的超时延迟。如果一个页面正在使用 Web 音频 API
AudioContext
播放声音,也可以不执行该延迟。不同的浏览器具体延迟并不相同。 -
追踪型脚本的限流
浏览器对它识别为追踪型脚本的脚本实施额外的限流。当在前台运行时,限流的最小延迟仍然是 4 ms。然而,在后台标签中,限流的最小延迟是 10000 ms(即 10 s),在文档首次加载后 30 s开始生效。
-
超时延迟(JS单线程)
如果页面(或操作系统/浏览器)正忙于其他任务(比如正在处理一个大的循环或复杂的操作),超时也可能比预期的晚。
JavaScript 的执行是基于事件循环(Event Loop)的。
setTimeout
并不立即执行,而是将回调函数放入事件队列中,直到当前执行栈清空。所以即使设定了精确的延迟,回调的执行时间也可能因为事件循环的队列处理和任务调度的顺序而有所不同。也可以理解为设置setTimeout后的执行时间=执行栈清空的时间+duration
-
在加载页面时推迟超时
当前标签页正在加载时,浏览器将推迟触发
setTimeout()
计时器。直到主线程被认为是空闲的(类似于Window.requestIdleCallback()
,或者直到加载事件触发完毕,才开始触发。 -
WebExtension 背景页面和定时器
WebExtensions 是一种用于开发浏览器扩展的跨浏览器系统。它提供了一种标准化的方式来创建可以在多个浏览器上运行的扩展。在 WebExtension中,
setTimeout()
不会可靠工作。 -
最大延时值
浏览器内部以 32 位带符号整数存储延时。
// 浏览器中 // 2 ** 32 - 5000 => -5000 => 0 立即执行 setTimeout(() => console.log("你好!"), 2 ** 32 - 5000); // 2 ** 32 + 5000 => 5000 5秒后执行 setTimeout(() => console.log("hi!"), 2 ** 32 + 5000);
注:Node.js中任何大于 (2^31)-1 ms 都会立即执行,并且会报错
-
系统或硬件影响
不同操作系统和硬件的性能差异也会影响
setTimeout
的精确度。如果系统负载较高,或者操作系统有时间调度策略,setTimeout
可能会稍微延迟执行。
代码输出题
来三道腾讯的事件循环的代码输出题结尾
第一题
console.log('1');
setTimeout(function () {
console.log('2');
process.nextTick(function () {
console.log('3');
})
new Promise(function (resolve) {
console.log('4');
resolve();
}).then(function () {
console.log('5')
})
})
process.nextTick(function () {
console.log('6');
})
new Promise(function (resolve) {
console.log('7');
resolve();
}).then(function () {
console.log('8')
})
setTimeout(function () {
console.log('9');
process.nextTick(function () {
console.log('10');
})
new Promise(function (resolve) {
console.log('11');
resolve();
}).then(function () {
console.log('12')
})
})
先执行宏任务script,打印1
第一个setTimeout放入宏任务队列
process.nextTick是微任务,放入微任务队列
Promise执行打印7,then放入微任务
第二个setTimeout放入宏任务队列
执行所有的微任务,打印6,8
执行第一个宏任务,打印2,4
执行微任务,打印3,5
执行第二个宏任务,打印9,11
执行微任务,打印10,12
注:本例中mjs与js的打印顺序不相同,在mjs下会先打印8,再打印6.
第二题
console.log(1);
const p = new Promise(r => setTimeout(r, 1000))
setTimeout(() => {
console.log(2);
})
await p
console.log(3);
先打印1,
第一个setTimeout放入宏任务队列,
第二个setTimeout放入宏任务队列,
把 await p 之后的代码放入微任务队列
第二个setTimeout先执行掉,打印2
执行第一个setTimeout
执行微任务, 打印3
第三题
// 将时间改为0
console.log(1);
const p = new Promise(r => setTimeout(r, 0))
setTimeout(() => {
console.log(2);
})
await p
console.log(3);
先打印1
第一个setTimeout放入宏任务队列,
第二个setTimeout放入宏任务队列,
第一个宏任务立即执行掉,打印微任务3
第二个宏任务,打印2
黑客/网络安全学习路线
对于从来没有接触过黑客/网络安全的同学,目前网络安全、信息安全也是计算机大学生毕业薪资相对较高的学科。
大白也帮大家准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
这也是耗费了大白近四个月的时间,吐血整理,文章非常非常长,觉得有用的话,希望粉丝朋友帮忙点个**「分享」「收藏」「在看」「赞」**
网络安全/渗透测试法律法规必知必会****
今天大白就帮想学黑客/网络安全技术的朋友们入门必须先了解法律法律。
【网络安全零基础入门必知必会】什么是黑客、白客、红客、极客、脚本小子?(02)
【网络安全零基础入门必知必会】网络安全专业术语全面解析(05)
【网络安全入门必知必会】《中华人民共和国网络安全法》(06)
【网络安全零基础入门必知必会】《计算机信息系统安全保护条例》(07)
【网络安全零基础入门必知必会】《中国计算机信息网络国际联网管理暂行规定》(08)
【网络安全零基础入门必知必会】《计算机信息网络国际互联网安全保护管理办法》(09)
【网络安全零基础入门必知必会】《互联网信息服务管理办法》(10)
【网络安全零基础入门必知必会】《计算机信息系统安全专用产品检测和销售许可证管理办法》(11)
【网络安全零基础入门必知必会】《通信网络安全防护管理办法》(12)
【网络安全零基础入门必知必会】《中华人民共和国国家安全法》(13)
【网络安全零基础入门必知必会】《中华人民共和国数据安全法》(14)
【网络安全零基础入门必知必会】《中华人民共和国个人信息保护法》(15)
【网络安全零基础入门必知必会】《网络产品安全漏洞管理规定》(16)
网络安全/渗透测试linux入门必知必会
【网络安全零基础入门必知必会】什么是Linux?Linux系统的组成与版本?什么是命令(01)
【网络安全零基础入门必知必会】VMware下载安装,使用VMware新建虚拟机,远程管理工具(02)
【网络安全零基础入门必知必会】VMware常用操作指南(非常详细)零基础入门到精通,收藏这一篇就够了(03)
【网络安全零基础入门必知必会】CentOS7安装流程步骤教程(非常详细)零基入门到精通,收藏这一篇就够了(04)
【网络安全零基础入门必知必会】Linux系统目录结构详细介绍(05)
【网络安全零基础入门必知必会】Linux 命令大全(非常详细)零基础入门到精通,收藏这一篇就够了(06)
【网络安全零基础入门必知必会】linux安全加固(非常详细)零基础入门到精通,收藏这一篇就够了(07)
网络安全/渗透测试****计算机网络入门必知必会****
【网络安全零基础入门必知必会】TCP/IP协议深入解析(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】什么是HTTP数据包&Http数据包分析(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】计算机网络—子网划分、子网掩码和网关(非常详细)零基础入门到精通,收藏这一篇就够了(03)
网络安全/渗透测试入门之HTML入门必知必会
【网络安全零基础入门必知必会】什么是HTML&HTML基本结构&HTML基本使用(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础入门必知必会】VScode、PhpStorm的安装使用、Php的环境配置,零基础入门到精通,收藏这一篇就够了2
【网络安全零基础入门必知必会】HTML之编写登录和文件上传(非常详细)零基础入门到精通,收藏这一篇就够了3
网络安全/渗透测试入门之Javascript入门必知必会
【网络安全零基础入门必知必会】Javascript语法基础(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】Javascript实现Post请求、Ajax请求、输出数据到页面、实现前进后退、文件上传(02)
网络安全/渗透测试入门之Shell入门必知必会
【网络安全零基础入门必知必会】Shell编程基础入门(非常详细)零基础入门到精通,收藏这一篇就够了(第七章)
网络安全/渗透测试入门之PHP入门必知必会
【网络安全零基础入门】PHP环境搭建、安装Apache、安装与配置MySQL(非常详细)零基础入门到精通,收藏这一篇就够(01)
【网络安全零基础入门】PHP基础语法(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】PHP+Bootstrap实现表单校验功能、PHP+MYSQL实现简单的用户注册登录功能(03)
网络安全/渗透测试入门之MySQL入门必知必会
【网络安全零基础入门必知必会】MySQL数据库基础知识/安装(非常详细)零基础入门到精通,收藏这一篇就够了(01)
【网络安全零基础入门必知必会】SQL语言入门(非常详细)零基础入门到精通,收藏这一篇就够了(02)
【网络安全零基础入门必知必会】MySQL函数使用大全(非常详细)零基础入门到精通,收藏这一篇就够了(03)
【网络安全零基础入门必知必会】MySQL多表查询语法(非常详细)零基础入门到精通,收藏这一篇就够了(04)
****网络安全/渗透测试入门之Python入门必知必会
【网络安全零基础入门必知必会】之Python+Pycharm安装保姆级教程,Python环境配置使用指南,收藏这一篇就够了【1】
【网络安全零基础入门必知必会】之Python编程入门教程(非常详细)零基础入门到精通,收藏这一篇就够了(2)
python入门教程python开发基本流程控制if … else
python入门教程之python开发可变和不可变数据类型和hash
【网络安全零基础入门必知必会】之10个python爬虫入门实例(非常详细)零基础入门到精通,收藏这一篇就够了(3)
****网络安全/渗透测试入门之SQL注入入门必知必会
【网络安全渗透测试零基础入门必知必会】之初识SQL注入(非常详细)零基础入门到精通,收藏这一篇就够了(1)
【网络安全渗透测试零基础入门必知必会】之SQL手工注入基础语法&工具介绍(2)
【网络安全渗透测试零基础入门必知必会】之SQL注入实战(非常详细)零基础入门到精通,收藏这一篇就够了(3)
【网络安全渗透测试零基础入门必知必会】之SQLmap安装&实战(非常详细)零基础入门到精通,收藏这一篇就够了(4)
【网络安全渗透测试零基础入门必知必会】之SQL防御(非常详细)零基础入门到精通,收藏这一篇就够了(4)
****网络安全/渗透测试入门之XSS攻击入门必知必会
【网络安全渗透测试零基础入门必知必会】之XSS攻击基本概念和原理介绍(非常详细)零基础入门到精通,收藏这一篇就够了(1)
网络安全渗透测试零基础入门必知必会】之XSS攻击获取用户cookie和用户密码(实战演示)零基础入门到精通收藏这一篇就够了(2)
【网络安全渗透测试零基础入门必知必会】之XSS攻击获取键盘记录(实战演示)零基础入门到精通收藏这一篇就够了(3)
【网络安全渗透测试零基础入门必知必会】之xss-platform平台的入门搭建(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试入门】之XSS漏洞检测、利用和防御机制XSS游戏(非常详细)零基础入门到精通,收藏这一篇就够了5
****网络安全/渗透测试入门文件上传攻击与防御入门必知必会
【网络安全渗透测试零基础入门必知必会】之什么是文件包含漏洞&分类(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之cve实际漏洞案例解析(非常详细)零基础入门到精通, 收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之PHP伪协议精讲(文件包含漏洞)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之如何搭建 DVWA 靶场保姆级教程(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之Web漏洞-文件包含漏洞超详细全解(附实例)5
【网络安全渗透测试零基础入门必知必会】之文件上传漏洞修复方案6
****网络安全/渗透测试入门CSRF渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之CSRF漏洞概述和原理(非常详细)零基础入门到精通, 收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之CSRF攻击的危害&分类(非常详细)零基础入门到精通, 收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之XSS与CSRF的区别(非常详细)零基础入门到精通, 收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之CSRF漏洞挖掘与自动化工具(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之CSRF请求伪造&Referer同源&置空&配合XSS&Token值校验&复用删除5
****网络安全/渗透测试入门SSRF渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之SSRF漏洞概述及原理(非常详细)零基础入门到精通,收藏这一篇就够了 1
【网络安全渗透测试零基础入门必知必会】之SSRF相关函数和协议(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之SSRF漏洞原理攻击与防御(非常详细)零基础入门到精通,收藏这一篇就够了3**
**
****网络安全/渗透测试入门XXE渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之XML外部实体注入(非常详细)零基础入门到精通,收藏这一篇就够了1
网络安全渗透测试零基础入门必知必会】之XXE的攻击与危害(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之XXE漏洞漏洞及利用方法解析(非常详细)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之微信XXE安全漏洞处理(非常详细)零基础入门到精通,收藏这一篇就够了4
****网络安全/渗透测试入门远程代码执行渗透与防御必知必会
【网络安全渗透测试零基础入门必知必会】之远程代码执行原理介绍(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础入门必知必会】之CVE-2021-4034漏洞原理解析(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全零基础入门必知必会】之PHP远程命令执行与代码执行原理利用与常见绕过总结3
【网络安全零基础入门必知必会】之WEB安全渗透测试-pikachu&DVWA靶场搭建教程,零基础入门到精通,收藏这一篇就够了4
****网络安全/渗透测试入门反序列化渗透与防御必知必会
【网络安全零基础入门必知必会】之什么是PHP对象反序列化操作(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全零基础渗透测试入门必知必会】之php反序列化漏洞原理解析、如何防御此漏洞?如何利用此漏洞?2
【网络安全渗透测试零基础入门必知必会】之Java 反序列化漏洞(非常详细)零基础入门到精通,收藏这一篇就够了3
【网络安全渗透测试零基础入门必知必会】之Java反序列化漏洞及实例解析(非常详细)零基础入门到精通,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之CTF题目解析Java代码审计中的反序列化漏洞,以及其他漏洞的组合利用5
网络安全/渗透测试**入门逻辑漏洞必知必会**
【网络安全渗透测试零基础入门必知必会】之一文带你0基础挖到逻辑漏洞(非常详细)零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门暴力猜解与防御必知必会
【网络安全渗透测试零基础入门必知必会】之密码安全概述(非常详细)零基础入门到精通,收藏这一篇就够了1
【网络安全渗透测试零基础入门必知必会】之什么样的密码是不安全的?(非常详细)零基础入门到精通,收藏这一篇就够了2
【网络安全渗透测试零基础入门必知必会】之密码猜解思路(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之利用Python暴力破解邻居家WiFi密码、压缩包密码,收藏这一篇就够了4
【网络安全渗透测试零基础入门必知必会】之BurpSuite密码爆破实例演示,零基础入门到精通,收藏这一篇就够了5
【网络安全渗透测试零基础入门必知必会】之Hydra密码爆破工具使用教程图文教程,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之暴力破解medusa,零基础入门到精通,收藏这一篇就够了7
【网络安全渗透测试零基础入门必知必会】之Metasploit抓取密码,零基础入门到精通,收藏这一篇就够了8
****网络安全/渗透测试入门掌握Redis未授权访问漏洞必知必会
【网络安全渗透测试零基础入门必知必会】之Redis未授权访问漏洞,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Redis服务器被攻击后该如何安全加固,零基础入门到精通,收藏这一篇就够了**
**
网络安全/渗透测试入门掌握**ARP渗透与防御关必知必会**
【网络安全渗透测试零基础入门必知必会】之ARP攻击原理解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之ARP流量分析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之ARP防御策略与实践指南,零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握系统权限提升渗透与防御关****必知必会
【网络安全渗透测试零基础入门必知必会】之Windows提权常用命令,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Windows权限提升实战,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之linux 提权(非常详细)零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握Dos与DDos渗透与防御相关****必知必会
【网络安全渗透测试零基础入门必知必会】之DoS与DDoS攻击原理(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Syn-Flood攻击原理解析(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之IP源地址欺骗与dos攻击,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之SNMP放大攻击原理及实战演示,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之NTP放大攻击原理,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之什么是CC攻击?CC攻击怎么防御?,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之如何防御DDOS的攻击?零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握无线网络安全渗透与防御相关****必知必会
【网络安全渗透测试零基础入门必知必会】之Aircrack-ng详细使用安装教程,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之aircrack-ng破解wifi密码(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之WEB渗透近源攻击,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之无线渗透|Wi-Fi渗透思路,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之渗透WEP新思路Hirte原理解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之WPS的漏洞原理解析,零基础入门到精通,收藏这一篇就够了
网络安全/渗透测试入门掌握木马免杀问题与防御********必知必会
【网络安全渗透测试零基础入门必知必会】之Metasploit – 木马生成原理和方法,零基础入门到精通,收藏这篇就够了
【网络安全渗透测试零基础入门必知必会】之MSF使用教程永恒之蓝漏洞扫描与利用,收藏这一篇就够了
网络安全/渗透测试入门掌握Vulnhub靶场实战********必知必会
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶机Prime使用指南,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶场Breach1.0解析,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之vulnhub靶场之DC-9,零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶机Kioptrix level-4 多种姿势渗透详解,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之Vulnhub靶场PWNOS: 2.0 多种渗透方法,收藏这一篇就够了
网络安全/渗透测试入门掌握社会工程学必知必会
【网络安全渗透测试零基础入门必知必会】之什么是社会工程学?定义、类型、攻击技术,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社会工程学之香农-韦弗模式,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社工学smcr通信模型,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之社会工程学之社工步骤整理(附相应工具下载)收藏这一篇就够了
网络安全/渗透测试入门掌握********渗透测试工具使用******必知必会**
2024版最新Kali Linux操作系统安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
【网络安全渗透测试零基础入门必知必会】之渗透测试工具大全之Nmap安装使用命令指南,零基础入门到精通,收藏这一篇就够了
2024版最新AWVS安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新burpsuite安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新owasp_zap安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Sqlmap安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Metasploit安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Nessus下载安装激活使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
2024版最新Wireshark安装使用教程(非常详细)零基础入门到精通,收藏这一篇就够了
觉得有用的话,希望粉丝朋友帮大白点个**「分享」「收藏」「在看」「赞」**
黑客/网络安全学习包
资料目录
-
成长路线图&学习规划
-
配套视频教程
-
SRC&黑客文籍
-
护网行动资料
-
黑客必读书单
-
面试题合集
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
1.成长路线图&学习规划
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
2.视频教程
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
3.SRC&黑客文籍
大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录
SRC技术文籍:
黑客资料由于是敏感资源,这里不能直接展示哦!
4.护网行动资料
其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!
5.黑客必读书单
**
**
6.面试题合集
当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。
更多内容为防止和谐,可以扫描获取~
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
****************************************************************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享