JavaScript重难点突破:期约与异步函数
同步和异步
- 同步(Synchronous)
-
定义:任务按顺序依次执行,前一个任务完成前,后续任务必须等待。
-
特点:阻塞性执行,程序逻辑直观,但效率较低
- 异步(Asynchronous)
-
定义:任务发起后无需等待结果,程序继续执行其他操作,待任务完成后通过回调或事件通知处理结果。
-
特点:非阻塞性执行,支持并发,资源利用率高
简单来说,同步就是刷牙然后煮面,异步就是让面在一边煮着一边跑去刷牙。
期约
期约是对尚不存在结果的一个替身。
在ES6中,期约是一种引用类型(Promise),使用new操作符实例化。
期约状态机
期约对象有三种状态,这些状态是期约对象内置的,除了调用相应的API,否则不能对其进行更改。
-
pending(待定)
-
fulfilled(兑现)
-
rejected(拒绝)
新建一个期约对象,并且期约对象还没进行任何操作时,期约对象的状态为pending
,当期约对象已经被成功解决后,则转为fulfilled
,而解决失败则转为rejected
,具体让期约状态转换的函数后面介绍。
待定(pending)是期约的最初始状态。在待定状态下,期约可以落定(settled)为代表成功的兑现(fulfilled)状态,或者代表失败的拒绝(rejected)状态。
无论落定为哪种状态都是不可逆的。只要从待定转换为兑现或拒绝,期约的状态就不再改变。而且,也不能保证期约必然会脱离待定状态。因此,组织合理的代码无论期约解决(resolve)
还是拒绝(reject),甚至永远处于待定(pending)状态,都应该具有恰当的行为。
重要的是,期约的状态是私有的,不能直接通过JavaScript检测到。这主要是为了避免根据读取到的期约状态,以同步方式处理期约对象。
另外,期约的状态也不能被外部JavaScript代码修改。这与不能读取该状态的原因一样:【期约故意将异步行为封装起来,从而隔离外部的同步代码】《JavaScript高级程序设计第四版》
如何理解期约对象
正如前面介绍的,期约对象是专门为异步编程而设计的,期约对象是对尚不存在结果的一个替身。
举个例子,你参加了一场考试,试卷由他人进行批改(异步操作),而你在试卷批改的过程中是自由的,你可以吃饭睡觉,你也可以尝试查询试卷批改的状态。
如果试卷还在批改当中,则返回pending
,如果已经批改结束,并且你已经通过了考试,返回fulfilled
,如果未通过考试,则返回rejected
。
理解了上述的场景,我们就能够理解期约对象和期约对象的状态机了。
-
期约对象代表了某一个异步操作。
-
期约状态机代表了异步操作的完成状态。
如何控制期约对象的状态机
期约对象的状态是私有的,只能通过期约对象内部的API进行操作。
向期约对象中传入一个执行器函数(回调函数),期约对象会向执行器函数传入两个参数resolve
和reject
,调用resolve()
使期约状态变为fulfilled
,调用reject()
使期约状态变为rejected
const waiter1 = new Promise((resolve, reject) => { });const waiter2 = new Promise((resolve, reject) => resolve());const waiter3 = new Promise((resolve, reject) => reject());// 其中undefined表示期约对象在完成后期待一个返回值,但这里没有给返回值console.log('waiter1:', waiter1); // waiter1: Promise {<pending>}console.log('waiter2:', waiter2); // waiter2: Promise {<fulfilled>:undefined}console.log('waiter3:', waiter3); // waiter1: Promise {<rejected>:undefined}
期约对象的静态方法
-
Promise.resolve()
这个方法可以直接创建一个
fulfilled
状态的期约对象,这个期约对象的值由传入的参数指定。const settled1 = Promise.resolve(3)const settled2 = Promise.resolve('我是字符串')const settled3 = Promise.resolve(new Promise(() => {}))console.log(settled1) // Promise {<fulfilled>: 3}console.log(settled2) // Promise {<fulfilled>: '我是字符串'}console.log(settled3) // Promise {<pending>}
可以看到,我们传入什么值,期约对象就会返回什么值。
但是如果我们传入的是另一个期约对象,则会直接返回传入的期约对象。
-
Promise.reject()
这个方法可以直接创建一个
rejected
状态的期约对象,这个期约对象的值由传入的参数指定。const settled1 = Promise.reject(3)const settled2 = Promise.reject('我是字符串')const settled3 = Promise.reject(new Promise(() => {}))console.log(settled1) // Promise {<rejected>: 3}console.log(settled2) // Promise {<rejected>: '我是字符串'}console.log(settled3) // Promise {<rejected>: Promise {<pending>}}
这个方法和
Promise.resolve()
类似,也会将传入的值作为期约对象的值返回。但不同的是,如果传入一个期约对象,那么这个期约对象也会作为期约对象的值返回。
调用reject()或者
Promise.reject()
都会抛出一个异步错误。同步代码块中的trycatch结构无法捕获到异步错误,只有异步结构中才能捕获异步错误期约的实例方法
-
实现Thenable方法
在ECMAScript暴露的异步结构中,任何对象都有一个then()方法。
-
Promise.prototype.then()
then()方法挂载在Promise的原型上,所以被所有Promise实例对象共享。
then()方法接收两个回调函数参数,第一个参数在Promise对象的状态落定为
fulfilled
时执行,第二个参数在Promise对象的状态落定为rejected
时执行。如何理解then()方法
在平时写js方法时,我们都是使用的同步代码块,也就是说,写在后面的代码一定后执行,比如我们在前面一行计算
let sum = 10 + 1
,那么我们就可以在这一行后面的任意位置输出sum
,因为sum
的计算是写在前面的,在同步代码块中,他已经被计算完毕了。现在我们使用了异步编程,我们已经知道Promise对象内置了一个状态机,它用于通知自己是否执行完毕。
由于Promise是异步执行的,假如我们在同步代码块中读取Promise对象,我们有可能获取3种结果。如果我们需要打印Promise的返回值,我们不可能在同步代码块中不停的检测Promise的状态,这样会导致后面的代码无法执行,这就违背了异步编程的初衷。
所以我们使用then()方法,then()方法可以想象为一个触发器,设置好then()方法后,只要Promise对象
settled
到了任意一种状态,就会触发then()方法中设定好的函数,这样我们就可以异步的处理Promise的返回值而无需再在同步代码块中处理Promise的返回值了。const p1 = new Promise((resolve, reject) => {// 1秒后返回10 + 1的计算结果setTimeout(() => resolve(10 + 1), 1000);});p1.then(() => {console.log('我计算完成,被触发了');console.log('我是then中的p1:',p1)}, () => { console.log('我计算失败,被触发了'); });console.log('我是同步代码块中的p1:',p1)
可以看到,同步代码块由于执行的比较快,已经运行到输出Promise对象的值了,但是此时Promise对象还没执行完,状态为
pending
,而then中却可以正常输出Promise的返回值11,这是因为then()中的第一个参数只有在Promise对象状态为fulfilled时才被调用。我们将then()方法的第一个参数称为onResolved处理程序,第二个参数称为onRejected处理程序。
-
.then()
返回的 Promise 状态如何确定?回调返回值类型决定状态
-
返回普通值(非 Promise 对象):新 Promise 会被
Promise.resolve()
包装为 fulfilled 状态p.then(() => 42); // 新 Promise 状态:fulfilled,值:42
-
抛出异常:新 Promise 变为 rejected 状态,异常对象作为拒绝原因
p.then(() => { throw new Error("fail"); }); // 状态:rejected,原因:Error对象
-
返回 Promise 对象:新 Promise 将 继承该 Promise 的状态和值
p.then(() => Promise.reject("error")); // 新 Promise 状态:rejected,原因:"error"
因此通过.then()方法返回的也是Promise对象,所以也有.then()方法,.then()方法可以进行链式调用
const p1 = new Promise((resolve, reject) => {// 3秒后返回10 + 1的计算结果setTimeout(() => resolve(double(1)), 1000);});p1.then(value => {return value}).then(value => {return double(value)}).then(value => {return double(value)}).then(value => console.log(value)) // 8
-
-
Promise.prototype.catch()
等于
then(null,() => {})
,也就是onRejected处理程序。 -
Promise.prototype.finally()
传入finally()的回调函数能保证一定被执行,和try-catch-finally中的finally用法一致。
-
Promise.all()和Promise.race()
这两个方法都可以传入一个包含多个期约的可迭代对象,常见方法是传入一个包含多个期约的数组。
-
Promise.all()
:会等待传入的期约全部兑现后才兑现,如果有一个期约待定或者拒绝,则返回待定或者拒绝 -
Promise.race()
:会返回根据第一个兑现或者拒绝的期约决定状态的新期约对象。
-
异步函数
通过刚刚期约对象的学习我们了解到,期约对象是异步执行的,因此如果想操作期约对象的流程必须要使用then()
方法。
但是这样同样导致了一个问题,同步代码块和异步代码块被完全的区分开了,从使用了期约对象开始,所有和这个期约对象有关的流程都要在then中实现,这会使得then()方法的函数体变得很大,并不好维护。
于是,从ES8开始引入了一组新的关键字async/await
用于解决这个问题。
基本概念
-
async
函数-
声明方式:在函数前添加
async
关键字,如async function fetchData() {}
。 -
返回值:始终返回一个
Promise
对象。若函数返回非Promise
值(如字符串、数值),该值会被自动包装为resolve
状态的Promise
async function example() { return "Hello"; } example().then(console.log); // 输出 "Hello"
-
-
await
关键字-
使用范围:仅能在
async
函数内部使用。 -
功能:暂停当前
async
函数的执行,等待右侧的Promise
完成(resolve
或reject
),并返回解析后的值async function fetchUser() {const response = await fetch('/api/user'); // 等待请求完成return response.json(); }
简单来说,关键字
async
声明了这个函数应该被异步执行,关键字await
表明被async
声明的函数应该被停止执行,等到await
右侧的表达式返回值后才被继续执行。 -
async
被async
关键字标记的函数会返回一个Promise对象,如果返回的值不是Promise对象,则会使用Promise.resolve()对返回的值进行包装。
async
函数的执行流程
- 同步代码的立即执行
-
未遇到
await
时:async
函数内部的代码会按照同步顺序立即执行,与普通函数的行为完全一致。例如:async function demo() {console.log("A"); // 同步执行console.log("B"); // 同步执行 } demo(); console.log("C");
输出顺序为:
A → B → C
-
本质:
async
函数被调用时,其函数体内的同步代码会直接进入主线程的同步任务队列,立即执行。
- **
await
对执行流程的干预**
-
遇到
await
时:函数会暂停当前执行,将await
后的表达式(通常是Promise
)放入微任务队列,并交出主线程控制权。此时,外部同步代码会继续执行。例如:async function demo() {console.log("A");await new Promise(resolve => setTimeout(resolve, 1000)); // 暂停console.log("B"); // 异步执行(微任务) } demo(); console.log("C");
输出顺序为:
A → C → (1秒后) B
-
关键机制:
await
后的代码会被封装为微任务,等待当前同步代码执行完毕后才会继续执行。
async function heavyTask () {console.log("开始耗时操作");// 没有awaitfor (let i = 0; i < 1e9; i++); console.log("耗时操作完成");}heavyTask();console.log("外部代码");
async function heavyTask () {console.log("开始耗时操作");// 有awaitawait '123'for (let i = 0; i < 1e9; i++); console.log("耗时操作完成");}heavyTask();console.log("外部代码");
可以看到,在await后的代码才会作为异步代码执行,否则async修饰的代码会像普通函数一样同步执行。
await
await关键字期待右侧是一个实现了Thenable接口的对象。
但如果不是,则await不会等待,而是将右侧视为一个已经fulfilled
的期约对象,直接返回。不会将值包装为Promise对象
const func = async () => {console.log(await '123') }// 注意,123没有被包装为Promise对象func() // '123'
如果await右侧是一个Promise对象,并且尚未settled,那么异步程序会在await处阻塞,停止运行直到右侧的Promise对象已经fulfilled
或者rejected
。
异步函数的特质不会扩展到嵌套函数,await只能在async标记的函数中使用
如果需要进行并行优化,不要每调用一次async函数就等待await返回值,而是一次性将async函数全部调用后,再按照需要的顺序等待await的返回值。
const asyncFunc1 = async () => { console.log(1); return 'a' }const asyncFunc2 = async () => { console.log(2); return 'b' }const asyncFunc3 = async () => { console.log(3); return 'c' }const asyncFunc4 = async () => { console.log(4); return 'd' }// 错误示范const run1 = async () => {console.log(await asyncFunc1()) console.log(await asyncFunc2()) console.log(await asyncFunc3()) console.log(await asyncFunc4()) }// 正确示范const run2 = async () => {const res1 = asyncFunc1()const res2 = asyncFunc2()const res3 = asyncFunc3()const res4 = asyncFunc4()console.log(await res1) console.log(await res2) console.log(await res3) console.log(await res4) }
在错误示范中,每次调用async函数都等到async函数返回后才执行下一个async函数。
而正确示范中,将所有async函数全部执行后,再等待async函数的返回值。
正确示范也可以通过Promise.all()来实现。
相关文章:
JavaScript重难点突破:期约与异步函数
同步和异步 同步(Synchronous) 定义:任务按顺序依次执行,前一个任务完成前,后续任务必须等待。 特点:阻塞性执行,程序逻辑直观,但效率较低 异步(Asynchron…...
Spring事务的传播机制
目录 Spring 中事务的实现编程式事务(了解即可):声明式事务(利用注解自动开启和提交事务):事务回滚注意事项: Spring 事务传播机制:1.Propagation.REQUIRED:7.Propagation.NESTED:Propagation.NESTED和1.Pr…...
LlamaIndex实现RAG增强:融合检索(Fusion Retrieval)与混合检索(Hybrid Search)
🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…...
什么是向量搜索Vector Search?
🧠 向所有学习者致敬! “学习不是装满一桶水,而是点燃一把火。” —— 叶芝 我的博客主页: https://lizheng.blog.csdn.net 🌐 欢迎点击加入AI人工智能社区! 🚀 让我们一起努力,共创…...
【接口重复请求】axios通过AbortController解决页面切换过快,接口重复请求问题
处理网络请求时,我们经常会遇到需要中途取消请求的情况,比如用户在两个tab之间反复横跳的场景,如果每个接口都从头请求到结束,那必然会造成很大的服务压力。 AbortController是一个Web API,它提供了一个信号对象&…...
GitHub与Gitee各是什么?它们的区别与联系是什么?
李升伟 整理 GitHub 介绍 GitHub 是一个基于 Git 的代码托管平台,主要用于版本控制和协作开发。它支持多人协作,提供代码托管、问题跟踪、代码审查、项目管理等功能。GitHub 是全球最大的开源社区,许多知名开源项目都在此托管。 主要功能&…...
OpenCV图像形态学:原理、操作与应用详解
一、引言 图像形态学(Image Morphology)是图像处理领域的一个重要分支,它基于集合论、格论、拓扑学和随机函数理论,主要用于分析和处理图像的几何结构。形态学操作通过特定的结构元素(Structuring Element)…...
ubuntu git cola gui
直接的方法, samba, win 里用 tortoiseSVN 需要先在命令行,运行 git 命令,看到操作提示, 按照提示做 然后右键看 git diff 其它的方法 linux下可视化git工具git-cola安装与使用(HTTP方式)_git…...
RTX5080 安装torch,torchvision ,torchaudio 指南
一、前置准备 5080 显卡 是sm120 架构,只有torch的preview版本可以使用,而且该版本仅支持cuda12.8. 请你放弃下载以及使用低版本cuda cudnn torch 的想法。 请你学习conda 创建环境,激活环境,在虚拟环境里使用pip ,…...
ubuntu开发mcu环境
# 编辑 vim或者vscode # 编译 arm-none-eabi # 烧写 openocd 若是默认安装,会在/usr/share/openocd/scripts/{interface,target} 有配置接口和目标版配置 示例: openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg 启动后,会…...
《UNIX网络编程卷1:套接字联网API》第5章 TCP客户服务器程序示例
《UNIX网络编程卷1:套接字联网API》第5章 TCP客户/服务器程序示例 5.1 本章目标与示例程序概述 本章通过一个完整的TCP回射(Echo)客户/服务器程序,深入解析TCP套接字编程的核心流程与关键问题。示例程序的功能为:客户…...
花洒洗澡完毕并关闭后过段时间会突然滴水的原因探究
洗澡完毕后的残留水 在洗澡的过程中,我们通常会使用到大量的水。这些水会通过花洒管子到达花洒顶喷流出。由于大顶喷花洒的喷头较大,关闭后里面的存水会更多。 气压失衡后的滴水 当花洒关闭后,内部的水管和花洒头中仍存有一定量的水。由于…...
子组件使用:visible.sync=“visible“进行双向的绑定导致该弹窗与其他弹窗同时显示的问题
问题描述:最近写代码时遇到了一个问题:点击A弹窗后关闭,继续点击B弹窗,这时会同时弹窗A、B两个弹窗。经过排查后发现在子组件定义时使用了:visible.sync"visible"属性进行双向的数据绑定 <template> <el-dial…...
TTL 值 | 在 IP 协议、ping 工具及 DNS 解析中的作用
注:本文为 “TTL” 相关文章合辑。 未整理去重。 如有内容异常,请看原文。 TTL 值的意义 2007-10-18 11:33:17 TTL 是 IP 协议包中的一个值,用于标识网络路由器是否应丢弃在网络中停留时间过长的数据包。数据包可能因多种原因在一定时间内…...
代码调试:VS调试实操
1.什么是BUG? BUG原意是“虫子”,在计算机领域是指未被发现的错误,又叫程序漏洞 2.什么是调试? 当你在写完代码时需要去找代码中的问题,这个过程就叫调试 我们必须承认有这个问题并且去修复问题,可以透…...
IGMP(Internet Group Management Protocol)与组播技术深度解析
一、组播技术核心概念 1. 组播 vs 单播/广播 传输类型目标地址网络负载典型应用场景单播单一明确IP随接收者数量线性增长网页浏览、文件下载广播全网段(如255.255.255.255)强制全网设备处理ARP请求、DHCP发现组播D类地址(224.0.0.0~239.255…...
JWT(JSON Web Token)
目录 一 JWT简单介绍 二、JWT 的组成结构 1 Header(头部) 2 Payload(载荷) 三、JWT 工作原理 好文分享 session、cookie、token 详解_token session cookie-CSDN博客 一 JWT简单介绍 概念:是一种开放标准&#…...
深入理解多线程编程:从基础概念到实战应用
二进制信号量:线程同步的基础 什么是二进制信号量? 二进制信号量是一种特殊的信号量,其值只能是0或1。它是最简单的线程同步机制之一,常用于线程间的简单协调。 #include <semaphore.h>sem_t sem; // 声明二进制信号量 se…...
【STM32设计】基于STM32的智能门禁管理系统(指纹+密码+刷卡+蜂鸣器报警)(代码+资料+论文)
本课题为基于单片机的智能门禁系统,整个系统由AS608指纹识别模块,矩阵键盘,STM32F103单片机,OLED液晶,RFID识别模块,继电器,蜂鸣器等构成,在使用时,用户可以录入新的指纹…...
【MVP 和 MVVM 相比 MVC 有哪些优化点?】
MVP 和 MVVM 相比 MVC 的优化及原因 1. MVC 的痛点 在传统 MVC 模式中: 视图(View)和模型(Model)直接交互:View 可能直接监听 Model 的变化(如观察者模式),导致耦合。…...
蓝桥云客 刷题统计
刷题统计 问题描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n 题? 输入格式 输入一行包含三个整数 a, b 和 …...
【28BYJ-48】STM32同时驱动4个步进电机,支持调速与正反转
资料下载:待更新。。。。 先驱动起来再说,干中学!!! 1、实现功能 STM32同时驱动4个步进电机,支持单独调速与正反转控制 需要资源:16个任意IO口1ms定时器中断 目录 资料下载:待更…...
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】【代码篇】A题解题全流程(持续更新)
【第十三届“泰迪杯”数据挖掘挑战赛】【2025泰迪杯】【代码篇】A题解题全流程(持续更新) 环境配置: 显存>24GBPyTorch 2.3.0Python 3.12(ubuntu22.04)CUDA 12.1autoDL服务器平台,(好处:可以分享镜像&…...
迅为RK3568开发板驱动开发指南helloworld驱动实验-驱动的基本框架
Linux 驱动的基本框架主要由模块加载函数,模块卸载函数,模块许可证声明,模块参数,块导出符号,模块作者信息等几部分组成,其中模块参数,模块导出符号,模块作者信息是选的部分…...
Spring Boot 3.4.3 基于 JSqlParser 和 MyBatis 实现自定义数据权限
前言 在企业级应用中,数据权限控制是保证数据安全的重要环节。本文将详细介绍如何在 Spring Boot 3.4.3 项目中结合 JSqlParser 和 MyBatis 实现灵活的数据权限控制,通过动态 SQL 改写实现多租户、部门隔离等常见数据权限需求。 一、环境准备 确保开发环境满足以下要求: …...
软件工程面试题(二十三)
1、public class Test {public static void add(Integer i){int val=i.intValue(); val+=3; i=new Integer(val); } public static void main(String[] args) {Integer i=new Integer(0); add(i); System.out.println(i.intValue());...
spring boot 集成redis 中RedisTemplate 、SessionCallback和RedisCallback使用对比详解,最后表格总结
对比详解 1. RedisTemplate 功能:Spring Data Redis的核心模板类,提供对Redis的通用操作(如字符串、哈希、列表、集合等)。使用场景:常规的Redis增删改查操作。特点: 支持序列化配置(如String…...
leetcode-热题100(3)
leetcode-74-搜索二维矩阵 矩阵最后一列升序排序,在最后一列中查找第一个大于等于target的元素 然后在该元素所在行进行二分查找 bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {int n matrixSize;int m matrixColSize[0];in…...
【大模型系列篇】大模型基建工程:使用 FastAPI 构建 SSE MCP 服务器
今天我们将使用FastAPI来构建 MCP 服务器,Anthropic 推出的这个MCP 协议,目的是让 AI 代理和你的应用程序之间的对话变得更顺畅、更清晰。FastAPI 基于 Starlette 和 Uvicorn,采用异步编程模型,可轻松处理高并发请求,尤…...
基于大模型预测风湿性心脏病二尖瓣病变的多维度诊疗研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、大模型技术概述 2.1 大模型的原理与架构 2.2 在医疗领域的应用现状 三、术前评估与预测 3.1 患者数据收集与分析 3.1.1 临床数据收集 3.1.2 影像数据处理 3.2 大模型预测模型建立 3.2.1 数据预处理 3.…...
5.模型训练-毕设篇
vgg: base_model_vgg13 models.vgg13(pretrainedTrue) base_model_vgg13.classifier[-1] nn.Linear(4096, num_classes) base_model_vgg13.to(device)(b_img_rgb.to(device)).shapebase_model_vgg13 models.vgg13(pretrainedTrue) 作用:加载预训练的…...
[物联网iot]对比WIFI、MQTT、TCP、UDP通信协议
第一步:先理解最基础的关系(类比快递) 假设你要给朋友寄快递: Wi-Fi:相当于“公路和卡车”,负责把包裹从你家运到快递站。 TCP/UDP:相当于“快递公司的运输规则”。 TCP:顺丰快递&…...
【含文档+PPT+源码】基于Python的股票数据可视化及推荐系统的设计与实现
项目介绍 本课程演示的是一款基于Python的股票数据可视化及推荐系统的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Python学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行…...
LeetCode算法题(Go语言实现)_23
题目 给你一个下标从 0 开始、大小为 n x n 的整数矩阵 grid ,返回满足 Ri 行和 Cj 列相等的行列对 (Ri, Cj) 的数目。 如果行和列以相同的顺序包含相同的元素(即相等的数组),则认为二者是相等的。 一、代码实现 func equalPairs…...
Windows家庭版如何开启Hyper-V与关闭Hyper-V
在Windows中如果要安装桌面版Docker,那么Hyper-V一定是需要开启的,在专业版操作系统上,这个功能直接就可以勾选开启,重启之后就即可生效,但在家庭版的操作系统上,默认是没有这个选择项的,这时候我们就需要借助于命令去开启它。本文,整理了一键开启Hyper-V服务和一键关闭…...
C# 中充血模型和贫血模型
在C#中,充血模型(Rich Domain Model)和贫血模型(Anemic Domain Model)是两种截然不同的领域建模方式,核心区别在于业务逻辑的归属。以下是通俗易懂的解释: 1. 贫血模型ÿ…...
C++中的继承
#include <iostream> using namespace std;// 武器类(基类) class Weapon { protected:int atk; // 攻击力public:// 构造函数Weapon(int atk 0) : atk(atk) {}// 虚拟析构函数virtual ~Weapon() {}// set 和 get 接口void setAtk(int atk) {this…...
Uubuntu20.04复现SA-ConvONet步骤
项目地址: tangjiapeng/SA-ConvONet: ICCV2021 Oral SA-ConvONet: Sign-Agnostic Optimization of Convolutional Occupancy Networks 安装步骤: 一、系统更新 检查系统是否已经更新到最新版本: sudo apt-get update sudo apt-get upgra…...
Blender模型导入虚幻引擎设置
单位系统不一致 Blender默认单位是米(Meters),而虚幻引擎默认使用**厘米(Centimeters)**作为单位。 当模型从Blender导出为FBX或其他格式时,如果没有调整单位,虚幻引擎会将1米(Blen…...
大数据Spark(五十五):Spark框架及特点
文章目录 Spark框架及特点 一、Spark框架介绍 二、Spark计算框架具备以下特点 Spark框架及特点 一、Spark框架介绍 Apache Spark 是一个专为大规模数据处理而设计的快速、通用的计算引擎。最初由加州大学伯克利分校的 AMP 实验室(Algorithms, Machines, and Pe…...
深入理解Python asyncio:从入门到实战,掌握异步编程精髓
文章目录 前言一、asyncio基础概念1.1 什么是异步编程?1.2 asyncio核心组件 二、asyncio核心用法详解2.1 事件循环管理2.2协程与任务2.3 异步上下文管理器 三、asyncio高级特性3.1 异步生成器3.2异步队列3.3 异步锁和信号量 四、asyncio实战项目4.1 高性能Web爬虫4.…...
线段树,单点,区间修改查阅
#PermanentNotes/algorithm 思想 首先关于树有许多类型,这里我们主要首线段树,整体思想就是将一个大区间进行拆分,拆分成各个小区间,在我们进行查找,更新时,就是对区间的查找更新 类型 初始化,构建树 代码 const int Z 1e7; const ll INF 1e18; const int maxn 1e5 10…...
音视频(二)ffmpeg编译及推流
FFmpeg 大名鼎鼎,就不多介绍了 1:环境 win11_amd64 ffpmeg download:https://git.ffmpeg.org/ffmpeg.git ffmpeg msys2 download:https://www.msys2.org/ vs2022 (c 写demo用) 用别的也行 usb2.0 摄像头(有点老) opencv 看上传的…...
syslog 与 Linux 内核日志系统全面解析
在 Linux 系统中,日志是进行系统调试、故障排查和系统安全分析的重要手段。syslog 和内核日志是 Linux 日志组成的核心组件。本文将从原理、实现、配置、常见问题分析等综合解析,全面解读 Linux 下的日志机制。 一、syslog 系统概述 1.1 什么是 syslog …...
SQL问题分析与诊断(8)——关键信息(2)
8.2. 关键信息 8.2.2. 警告 查询计划中,可能会看到出现于操作符上的小图标,特别是黄色或红色的感叹号。这些图标都是警告。并非每个警告都指示一个严重问题,但发现时请检查该图标的属性窗口,其将包含该警告图标的具体细节。 8.…...
HCIA/HCIP基础知识笔记汇总
HCIA/HCIP基础知识笔记汇总 ICT产业链: 上游:芯片制造、元器件生产、光纤光缆制造 中游:硬件组装、软件开发、网络建设维护 下游:电信服务、互联网服务、终端产品 VLAN端口类型: access :…...
vue3 动态路由
定义: 对路由的添加通常是通过 routes 选项来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由 1. 动态添加路由规则 场景 在应用初始化时,可能需要根据用户的角色或权限动态添加路由规则。 实现 im…...
《Linux内存管理:实验驱动的深度探索》大纲
《Linux内存管理:实验驱动的深度探索》 ——通过递进式实验与问题剖析,从入门到精通 第一部分:初探内存——基础概念与简单实验 目标:理解内存的基本行为,学会观察和提问 第1章 内存初体验:从"free…...
【C语言】深入理解指针(五):sizeof、strlen与数组指针的那些事儿
前言 在C语言的学习中,指针始终是一个让人又爱又恨的话题。它强大而灵活,但同时也充满了陷阱。今天,我们就来深入探讨一下指针相关的几个重要知识点:sizeof和strlen的区别,以及数组和指针在笔试题中的那些常见问题。希…...
CMake学习-- install 指令详细说明
目录 CMake中install命令的用法背景知识使用方法项目结构示例代码CMakeLists.txt构建和安装 详细介绍安装库和头文件安装可执行文件安装额外的文件安装目录结构使用安装的库 总结 CMake中install命令的用法 背景知识 在软件开发过程中,构建和安装是两个重要的环节…...