《异步江湖:XHR、Promise 与 Event Loop 的恩怨情仇》

XMLHttpRequest 

XMLHttpRequest(简称 XHR)是浏览器提供的一个 JavaScript 对象,用于在客户端和服务器之间发送 HTTP 请求。它是实现 AJAX(Asynchronous JavaScript and XML) 技术的核心工具,允许网页在不重新加载的情况下与服务器交换数据并更新部分页面内容。。


1. 基本用法

创建 XHR 对象

const xhr = new XMLHttpRequest();

配置请求

使用 open() 方法初始化请求:

xhr.open(method, url, async);
  • method:HTTP 方法(如 GETPOST)。

  • url:请求的目标 URL。

  • async:是否异步(默认为 true)。

示例
xhr.open('GET', 'https://api.example.com/data', true);

发送请求

使用 send() 方法发送请求:

xhr.send();
  • 对于 POST 请求,可以在 send() 中传递请求体数据:

    xhr.send(JSON.stringify({ key: 'value' }));

处理响应

通过 onreadystatechange 事件监听请求状态变化:

xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log('响应数据:', xhr.responseText);}
};
 

2. XHR 对象的属性和方法

属性

属性说明
readyState请求状态:
- 0:未初始化
- 1:已打开
- 2:已发送
- 3:接收中
- 4:完成
statusHTTP 状态码(如 200、404、500)。
statusTextHTTP 状态文本(如 OKNot Found)。
responseText服务器返回的文本数据(字符串形式)。
responseXML服务器返回的 XML 数据(如果响应内容是 text/xml)。
responseType设置响应类型(如 jsontextblob)。
response根据 responseType 返回的响应数据。

方法

方法说明
open(method, url)初始化请求。
send(body)发送请求,body 是可选的请求体数据。
setRequestHeader(header, value)设置请求头(如 Content-Type)。
abort()取消请求。

3. 完整示例

GET 请求

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log('响应数据:', xhr.responseText);}
};
xhr.send();

POST 请求

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log('响应数据:', xhr.responseText);}
};
xhr.send(JSON.stringify({ username: 'john', password: '123456' }));

4. 事件监听

除了 onreadystatechange,XHR 还支持以下事件:

事件说明
onload请求成功完成时触发。
onerror请求失败时触发。
onprogress请求正在处理中时触发(用于监控上传/下载进度)。
示例

xhr.onload = function() {if (xhr.status === 200) {console.log('响应数据:', xhr.responseText);}
};
xhr.onerror = function() {console.error('请求失败');
};
xhr.onprogress = function(event) {if (event.lengthComputable) {console.log(`已接收 ${event.loaded} / ${event.total} 字节`);}
};

5. 跨域请求

XHR 默认受 同源策略 限制,无法直接访问不同源的资源。可以通过以下方式解决跨域问题:

  1. CORS(跨域资源共享)
    服务器设置 Access-Control-Allow-Origin 响应头。

  2. JSONP
    通过 <script> 标签加载跨域数据(仅支持 GET 请求)。

  3. 代理服务器
    通过同源服务器转发请求。


6. 与 Fetch API 的对比

特性XMLHttpRequestFetch API
语法基于回调,代码冗长基于 Promise,语法简洁
流式数据处理不支持支持
请求取消支持(abort()支持(AbortController
兼容性支持所有浏览器(包括 IE)不支持 IE
错误处理需手动检查状态码自动处理网络错误

7.查询参数

  1. 什么是查询参数:携带额外信息给服务器,返回匹配想要的数据

  2. 查询参数原理要携带的位置和语法:http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2

  3. 所以,原生 XHR 需要自己在 url 后面携带查询参数字符串,没有 axios 帮助我们把 params 参数拼接到 url 字符串后面了

特性XMLHttpRequestAxios
语法需要手动拼接 URL 或使用 URLSearchParams提供 params 配置项,自动处理查询参数
代码复杂度代码冗长,需手动处理细节代码简洁,封装了底层细节
错误处理需手动检查状态码和错误基于 Promise,支持 catch 捕获错误
兼容性支持所有浏览器(包括 IE)不支持 IE
功能扩展功能有限,需自行封装提供拦截器、请求取消等高级功能

Promise

1. 什么是 Promise?

Promise 是 JavaScript 提供的一种用于 处理异步操作 的对象。它用于解决 回调地狱 问题,使异步代码更易读、可维护。

Promise 对象表示一个 尚未完成但预计会在未来完成的操作,它可以是:

  • 进行中(pending):初始状态,既没有成功也没有失败。
  • 已完成(fulfilled):操作成功,返回一个值(由 resolve() 处理)。
  • 已拒绝(rejected):操作失败,返回一个错误(由 reject() 处理)。
2. Promise 语法
const myPromise = new Promise((resolve, reject) => {setTimeout(() => {let success = true; // 模拟成功或失败if (success) {resolve("操作成功!");} else {reject("操作失败!");}}, 1000);
});// 处理 Promise 结果
myPromise.then((result) => console.log(result)) // 操作成功!.catch((error) => console.error(error)) // 操作失败!.finally(() => console.log("操作完成")); // 无论成功或失败都会执行
3. Promise 链式调用

支持多个 .then() 串联执行,避免回调地狱

new Promise((resolve) => resolve(1)).then((num) => num * 2).then((num) => num * 3).then(console.log); // 6
4. 常用 Promise 方法
方法作用
Promise.all()同时执行多个 Promise,全部成功返回数组,否则返回第一个失败的
Promise.race()返回第一个完成的 Promise(无论成功或失败)
Promise.allSettled()等待所有 Promise 结束,无论成功或失败,返回所有结果
Promise.any()返回第一个成功的 Promise,如果全部失败,则返回 AggregateError
Promise.all([Promise.resolve("A"),Promise.resolve("B"),
]).then(console.log); // ["A", "B"]
5. async/await(Promise 的语法糖)
async function fetchData() {try {let data = await new Promise((resolve) => setTimeout(() => resolve("数据返回"), 1000));console.log(data); // 数据返回} catch (error) {console.error(error);}
}fetchData();

6.myAxios制作

基于 Promise 和 XHR 封装 myAxios 函数
核心语法:
function myAxios(config) {return new Promise((resolve, reject) => {// XHR 请求// 调用成功/失败的处理程序})
}myAxios({url: '目标资源地址'
}).then(result => {}).catch(error => {})
步骤:
 
  1. 定义 myAxios 函数,接收配置对象,返回 Promise 对象

  2. 发起 XHR 请求,默认请求方法为 GET

  3. 调用成功/失败的处理程序

  4. 使用 myAxios 函数,获取省份列表展示

整体代码:
function myAxios({ url, method = "GET", data = null, headers = {}, timeout = 5000 }) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();xhr.open(method.toUpperCase(), url, true);xhr.timeout = timeout; // 设置超时时间// 设置请求头for (let key in headers) {xhr.setRequestHeader(key, headers[key]);}// 监听请求完成事件xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {try {const responseData = JSON.parse(xhr.responseText); // 解析 JSON 数据resolve(responseData);} catch (error) {reject("JSON 解析失败");}} else {reject(`请求失败,状态码:${xhr.status}`);}}};// 监听错误xhr.onerror = function () {reject("网络错误");};// 监听超时xhr.ontimeout = function () {reject("请求超时");};// 发送请求if (method.toUpperCase() === "GET" || data === null) {xhr.send();} else {xhr.setRequestHeader("Content-Type", "application/json");xhr.send(JSON.stringify(data));}});
}

同步代码和异步代码的区别

1. 同步代码(Synchronous)

同步代码按 顺序执行,当前任务完成后才执行下一个任务。如果某个任务耗时较长(如文件读取、网络请求等),整个程序都会被 阻塞

示例:
console.log("任务 1");
console.log("任务 2");
console.log("任务 3");

执行顺序:

任务 1
任务 2
任务 3

遇到阻塞的情况

console.log("开始");
for (let i = 0; i < 1e9; i++) {} // 模拟耗时操作
console.log("结束");

如果 for 循环运行了 3 秒,那么程序会 卡 3 秒,直到循环结束才继续执行后面的代码。


2. 异步代码(Asynchronous)

异步代码不会阻塞程序,它 不会等待任务完成,而是继续执行后续代码,等任务完成后再 通知(回调、Promise、async/await)

示例(setTimeout 异步执行):
console.log("任务 1");
setTimeout(() => console.log("任务 2(延迟 1 秒)"), 1000);
console.log("任务 3");

执行顺序:

任务 1
任务 3
任务 2(延迟 1 秒后执行)

👉 异步任务(setTimeout)不会阻塞后续代码的执行。


3. 常见的异步操作

  • 定时器(setTimeout, setInterval)
  • DOM 事件(click, input, scroll)
  • 网络请求(fetch, XMLHttpRequest, axios)
  • 文件读取(fs.readFile - Node.js)
  • 数据库操作(MongoDB, MySQL)
回调函数(Callback)
function fetchData(callback) {setTimeout(() => {callback("数据加载完成");}, 1000);
}console.log("开始请求数据");
fetchData((data) => console.log(data));
console.log("代码执行完毕");

执行顺序

开始请求数据
代码执行完毕
数据加载完成(1 秒后)

4. 现代异步方案

(1)Promise
开始请求数据
代码执行完毕
数据加载完成(1 秒后)

执行顺序

开始请求数据
代码执行完毕
数据加载完成(1 秒后)
(2)async/await
 
async function fetchData() {return new Promise((resolve) => {setTimeout(() => resolve("数据加载完成"), 1000);});
}async function main() {console.log("开始请求数据");let data = await fetchData();console.log(data);console.log("代码执行完毕");
}main();

执行顺序

开始请求数据
数据加载完成(1 秒后)
代码执行完毕

👉 await 让异步代码看起来像同步代码,增强可读性。


5. 总结

对比项同步代码异步代码
执行方式按顺序执行先执行后续代码,任务完成后再执行回调
是否阻塞是(遇到耗时任务会卡住)否(不会影响后续代码执行)
使用场景计算、变量赋值、DOM 操作等I/O 操作、网络请求、定时任务等
实现方式普通代码回调函数、Promise、async/await

Promise 链式调用

Promise.then() 方法会返回一个新的 Promise,这样就可以链式调用多个 .then(),实现 异步流程控制,避免回调地狱。

1. 基本链式调用

每个 .then() 处理上一个 .then() 返回的值:

new Promise((resolve) => {setTimeout(() => resolve(1), 1000); // 1秒后返回 1
}).then((num) => {console.log(num); // 1return num * 2;}).then((num) => {console.log(num); // 2return num * 3;}).then((num) => {console.log(num); // 6return num * 4;}).then(console.log); // 24

 ✅ 执行顺序

1
2
6
24

👉 每个 .then()

2. 链式调用处理异步操作

如果 .then() 返回一个 Promise,下一个 .then() 会等待这个 Promise 解析完成:

都返回一个新的值,供下一个 .then() 使用

new Promise((resolve) => {setTimeout(() => resolve("数据 1"), 1000);
}).then((data) => {console.log(data);return new Promise((resolve) => setTimeout(() => resolve("数据 2"), 1000));}).then((data) => {console.log(data);return new Promise((resolve) => setTimeout(() => resolve("数据 3"), 1000));}).then(console.log);

执行顺序(每步间隔 1 秒)

数据 1
数据 2
数据 3

👉 每个 .then() 返回一个 Promise,下一个 .then() 需等待前一个 Promise 解析完成

3. 处理异常

链式调用中,catch() 捕获前面所有 Promise 的错误:

new Promise((resolve, reject) => {setTimeout(() => reject("出错了!"), 1000);
}).then((data) => {console.log("不会执行", data);return "继续";}).catch((error) => {console.error("捕获错误:", error);return "错误已处理"; // catch() 可以返回新值}).then(console.log); // "错误已处理"

执行顺序

捕获错误: 出错了!
错误已处理

👉 catch() 捕获错误后,链式调用不会中断,后续 .then() 仍会执行

4. finally()

无论 Promise 成功或失败finally() 都会执行

new Promise((resolve, reject) => {setTimeout(() => reject("失败了"), 1000);
}).then(console.log).catch(console.error).finally(() => console.log("操作完成"));

 ✅ 执行顺序

失败了
操作完成

👉 finally() 适合做清理操作,比如关闭加载动画等

方法作用
.then()处理成功结果,可链式调用
.catch()处理 Promise 失败(捕获错误)
.finally()无论成功或失败都会执行

JavaScript 事件循环(Event Loop)

1. 什么是事件循环?

JavaScript 是 单线程 的,它使用 事件循环(Event Loop) 机制来执行同步和异步代码,确保不会阻塞主线程。

  • 同步任务:立即执行,放入 主线程(调用栈 Call Stack) 运行。
  • 异步任务:放入 任务队列(Task Queue),等主线程空闲后执行。

2. 事件循环执行流程

  1. 执行同步代码(放在主线程)。
  2. 遇到异步任务(如 setTimeoutPromisefetch,将它交给 Web APIs 处理。
  3. 同步代码执行完毕后,检查任务队列
    • 微任务队列(Microtask Queue):执行 Promise.then()queueMicrotask()MutationObserver
    • 宏任务队列(Macrotask Queue):执行 setTimeoutsetIntervalsetImmediate(Node.js)、I/O 任务等。
  4. 先执行所有微任务,再执行宏任务,然后进入下一个循环。

3. 示例解析

示例 1:基本事件循环
 
console.log("同步 1");setTimeout(() => console.log("setTimeout"), 0);Promise.resolve().then(() => console.log("Promise 1"));console.log("同步 2");

执行顺序

 
同步 1
同步 2
Promise 1  (微任务)
setTimeout  (宏任务)

📌 解释

  1. 同步 1、同步 2:立即执行。
  2. Promise微任务,优先执行。
  3. setTimeout宏任务,等微任务执行完才运行。

示例 2:多个宏任务和微任务
 
console.log("同步 1");setTimeout(() => console.log("setTimeout 1"), 0);
setTimeout(() => console.log("setTimeout 2"), 0);Promise.resolve().then(() => {console.log("Promise 1");return Promise.resolve();
}).then(() => console.log("Promise 2"));console.log("同步 2");

执行顺序

 
同步 1
同步 2
Promise 1  (微任务)
Promise 2  (微任务)
setTimeout 1  (宏任务)
setTimeout 2  (宏任务)

📌 解释

  1. 同步代码 先执行("同步 1" → "同步 2")。
  2. Promise 微任务 依次执行("Promise 1" → "Promise 2")。
  3. setTimeout 宏任务 最后执行("setTimeout 1" → "setTimeout 2")。

示例 3:复杂情况
 
console.log("A");setTimeout(() => {console.log("B");Promise.resolve().then(() => console.log("C"));
}, 0);Promise.resolve().then(() => console.log("D"));console.log("E");

执行顺序

 
A
E
D   (微任务)
B   (宏任务)
C   (B 里的微任务)

📌 解释

  1. 执行同步代码:"A"、"E"。
  2. Promise 微任务:"D" 先执行。
  3. setTimeout 宏任务:"B" 进入队列,等同步 & 微任务执行完毕后运行。
  4. "B" 里面的 Promise(C)微任务,执行优先级高于新的宏任务。

Promise.all() 静态方法

Promise.all() 用于 并行执行多个异步任务,并且 等待所有 Promise 都成功,才会返回 所有结果。如果 任何一个 Promise 失败Promise.all() 立即 reject,不会等待其他任务完成。

1. 基本用法

 
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);Promise.all([p1, p2, p3]).then((results) => {console.log(results); // [1, 2, 3]
});

执行顺序

 
[1, 2, 3]

📌 解释

  • Promise.all() 需要 等待所有 Promise 解析,返回 [1, 2, 3]

2. 异步任务示例

 
const p1 = new Promise((resolve) => setTimeout(() => resolve("数据 1"), 1000));
const p2 = new Promise((resolve) => setTimeout(() => resolve("数据 2"), 2000));
const p3 = new Promise((resolve) => setTimeout(() => resolve("数据 3"), 3000));console.log("开始请求");Promise.all([p1, p2, p3]).then((results) => {console.log("所有数据加载完成:", results);
});

执行顺序

 
开始请求
(等待 3 秒)
所有数据加载完成: [ '数据 1', '数据 2', '数据 3' ]

📌 解释

  • Promise.all() 等待所有任务完成(最大耗时任务 3 秒)。
  • 3 秒后,返回 ["数据 1", "数据 2", "数据 3"]

3. 处理失败(任何一个失败都会触发 reject)

 
const p1 = Promise.resolve("成功 1");
const p2 = Promise.reject("失败 2");
const p3 = Promise.resolve("成功 3");Promise.all([p1, p2, p3]).then(console.log).catch((error) => console.error("发生错误:", error));

执行顺序

 
发生错误: 失败 2

📌 解释

  • p2 失败,Promise.all 立即 reject,不会等待 p3

4. 结合 map() 批量请求

📌 批量请求 5 个 API

 
const urls = ["https://jsonplaceholder.typicode.com/todos/1","https://jsonplaceholder.typicode.com/todos/2","https://jsonplaceholder.typicode.com/todos/3",
];Promise.all(urls.map((url) => fetch(url).then((res) => res.json()))).then(console.log).catch(console.error);

执行结果

 
[{ "userId": 1, "id": 1, "title": "...", "completed": false },{ "userId": 1, "id": 2, "title": "...", "completed": false },{ "userId": 1, "id": 3, "title": "...", "completed": false }
]

📌 解释

  • map() 遍历 URL 数组,创建 fetch() 请求。
  • Promise.all() 并行执行所有请求,加速响应。

5. 解决 Promise.all() 失败问题

如果希望即使某些 Promise 失败,仍然获得结果,可以使用 Promise.allSettled()

 
const p1 = Promise.resolve("成功 1");
const p2 = Promise.reject("失败 2");
const p3 = Promise.resolve("成功 3");Promise.allSettled([p1, p2, p3]).then(console.log);

执行结果

 
[{ "status": "fulfilled", "value": "成功 1" },{ "status": "rejected", "reason": "失败 2" },{ "status": "fulfilled", "value": "成功 3" }
]

📌 解释

  • Promise.allSettled() 不会因为某个 Promise 失败而中断
  • 返回 每个 Promise 的状态(fulfilled / rejected)

总结

方法作用
Promise.all()全部成功才返回数组,任意失败立即 reject
Promise.allSettled()所有任务完成后返回数组(包含成功和失败)

 

医学、法律、商业、工程 都是崇高的追求,足以支撑人的一生。但诗歌、美丽、浪漫、爱情这些才是我们生活的意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/72610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++课程设计【宿舍管理查询软件】

宿舍管理查询软件 一、题目描述二、源码以及说明宿舍管理查询软件设计与实现1. 系统设计思路1.1 功能需求1.2 数据结构2. 系统实现3. 代码说明3.1 数据结构3.2 功能实现3.3 文件存储4. 示例运行输入输出5. 总结其他QT文章推荐一、题目描述 (一)问题描述 为宿舍管理人员编写一…

MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流

在无人零售市场蓬勃发展的浪潮中&#xff0c;自动售货机正经历着从传统机械式操作向AI视觉技术的重大跨越。 移远通信作为全球领先的物联网整体解决方案供应商&#xff0c;精准把握行业趋势&#xff0c;在2025世界移动通信大会&#xff08;MWC&#xff09;上宣布推出全新AI智能…

C语言常用的头文件,include文件

常用头文件功能速览 1 &#xff0c;通用常用头文件 01. stdio.h——标准输入输出 02. stdlib.h——内存管理与分配、随机数、字符串转换 03. string.h——字符串处理 04. math.h——数学 05. time.h——时间和日期 06. ctype…

[MySQL初阶]MySQL(4)基本查询

标题&#xff1a;[MySQL初阶]MySQL&#xff08;4&#xff09;基本查询 水墨不写bug 文章目录 一. 数据表设计二、对数据表的操作1. Create 操作&#xff08;插入数据&#xff09;查看最近受影响的行数&#xff1a; 2. Retrieve 操作&#xff08;读取数据&#xff09;&#xff0…

小米智能音箱Pro搭载“超级小爱”,支持远程控车

大家好,今天我要给大家好好唠唠小米智能音箱Pro,尤其是它搭载的“超级小爱”,那功能可太强大了,还支持远程控车,真的是给我们的生活带来了超多便利和惊喜。 先来说说这小米智能音箱Pro的外观。它的设计非常简约时尚,整体造型方方正正,线条流畅,放在家里任何一个角落都…

react中的useContext--为什么使用(一)

React 的数据传递流程 在 React 中&#xff0c;数据传递通常是自上而下的&#xff0c;也就是父组件把数据通过 props 传递给子组件&#xff0c;子组件无法直接修改父组件的数据。 例子&#xff1a;父组件向子组件传递数据 const Parent () > {const user { name: &quo…

如何使用 LLM 生成的术语自动在搜索应用程序上构建 autocomplete 功能

作者&#xff1a;来自 Elastic Michael Supangkat 了解如何在 Elastic Cloud 中&#xff0c;通过使用 LLM 生成的词汇&#xff0c;为搜索应用增强自动补全功能&#xff0c;实现更智能、更动态的搜索建议。 自动补全是搜索应用中的一项关键功能&#xff0c;它通过在用户输入时实…

MAVEN手动配置(阿里云)全教程

介于网上各种各样的MAVEN配置过程中方法大致相同却细节参差不齐&#xff0c;我总结了我遇见的一些问题&#xff0c;来完全的解决MAVEN手动配置的全过程&#xff0c;以及分享解决小毛病的经验。 所需材料&#xff1a; MAVEN3.9.9&#xff08;下载适合自己的版本即可&#xff09…

DeepSeek 3FS:端到端无缓存的存储新范式

在 2025 年 2 月 28 日&#xff0c;DeepSeek 正式开源了其高性能分布式文件系统 3FS【1】&#xff0c;作为其开源周的压轴项目&#xff0c;3FS 一经发布便引发了技术圈的热烈讨论。它不仅继承了分布式存储的经典设计&#xff0c;还通过极简却高效的架构&#xff0c;展现了存储技…

HarmonyOS:如何将图片转为PixelMap并进行图片缓存策略

前言&#xff1a;在HarmonyOS项目开发中&#xff0c;我们使用Ark-Ts语言开发项目。我们有个功能是拍照&#xff0c;除了正常显示出来&#xff0c;并且上传服务器。我在开发过程中&#xff0c;遇到的问题是&#xff0c;如果离开这个页面再回到当前页面仍要显示图片&#xff0c;那…

2025.3.9机器学习笔记:文献阅读

2025.3.9周报 一、文献阅读题目信息摘要Abstract创新点网络架构实验结论不足以及展望 一、文献阅读 题目信息 题目&#xff1a; Time-series generative adversarial networks for flood forecasting期刊&#xff1a; Journal of Hydrology作者&#xff1a; Peiyao Weng, Yu …

linux固定IP并解决虚拟机无法ping其他电脑问题

linux固定IP并解决虚拟机无法ping其他电脑问题 1.找到网卡文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 2.编辑文件信息 BOOTPROTO 这个dhcp改为static#添加以下内容IPADDR<你的IP地址>NETMASK<子网掩码>&#xff0c;例如255.255.255.0。GATEWAY<网…

Spring实战spring-ai运行

目录 1. 配置 2 .搭建项目 3. 查看对应依赖 3.1 OpenAI 依赖 3.2 配置 OpenAI API 密钥 application.properties application.yml 4. openai实战 5. 运行和测试 6. 高级配置 示例&#xff1a;配置模型和参数 解释&#xff1a; 7. 处理异常和错误 示例&#xff1a;…

docker:配置 Docker 镜像加速器

1 镜像加速器介绍 默认情况下&#xff0c;将来从docker hub&#xff08;https://hub.docker.com/&#xff09;上下载docker镜像&#xff0c;太慢。一般都会配置镜像加速器&#xff1a; USTC&#xff1a;中科大镜像加速器&#xff08;https://docker.mirrors.ustc.edu.cn&…

[内网安全] Windows 本地认证 — NTLM 哈希和 LM 哈希

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;SAM 文件 & Windows 本地认证流程 0x0101&#xff1a;SAM 文件简介 Windows 本地账户的登录密码是存储在系统本地的 SAM 文件中的&#xff0c;在登录 Windows 的时候&am…

算法-图-dijkstra 最短路径

理论知识 dijkstra三部曲 朴素版dijkstra 模拟过程 堆优化版dijksra 经典模版例题 Dijkstra求最短路 I 参加科学大会&#xff08;第六期模拟笔试&#xff09;--模版题 网络延迟 ref 理论知识 最短路是图论中的经典问题即&#xff1a;给出一个有向图&#xff0c;一…

Qt添加MySql数据库驱动

文章目录 一. 安装MySql二.编译mysql动态链接库 Qt版本&#xff1a;5.14.2 MySql版本&#xff1a;8.0.41 一. 安装MySql 参考这里进行安装&#xff1a;https://blog.csdn.net/qq_30150579/article/details/146042922 将mysql安装目录里的bin&#xff0c;include和lib拷贝出来…

浅论数据库聚合:合理使用LambdaQueryWrapper和XML

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库聚合替代内存计算&#xff08;关键优化&#xff09;二、批量处理优化四、区域特殊处理解耦五、防御性编程增强 前言 技术认知点&#xff1a;使用 XM…

Ubuntu 22.04安装NVIDIA A30显卡驱动

一、安装前准备 1.禁用Nouveau驱动 Ubuntu默认使用开源Nouveau驱动&#xff0c;需要手动禁用&#xff1a; vim /etc/modprobe.d/blacklist-nouveau.conf # 添加以下内容&#xff1a; blacklist nouveau options nouveau modeset0 # 更新内核并重启&#xff1a; update-initr…

Docker Desktop 4.38 安装与配置全流程指南(Windows平台)

一、软件定位与特性 Docker Desktop 是容器化应用开发与部署的一体化工具&#xff0c;支持在本地环境创建、管理和运行Docker容器。4.38版本新增GPU加速支持、WSL 2性能优化和Kubernetes 1.28集群管理功能&#xff0c;适用于微服务开发、CI/CD流水线搭建等场景。 二、安装环境…