【面试题】三道面试题让你掌握JavaScript中的执行上下文与作用域以及闭包

前言
大厂面试题分享 面试题库
前后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
大家好,笔者呢最近再回顾JavaScript知识时,又看到了JavaScript的一些较为常见的内容,仔细看了之后发现之前理解的并不深,所以给记录了下来,加深印象。执行上下文与执行栈、作用域与作用域链、闭包。
执行上下文
例题
大家先来看一道较为简单的题,看下是否能看出来结果
var a = 10;
functionfn(b) {b = 20;console.log(a, b);
}
functionfn1() {a = 100;fn(a);
}
fn(200); //输出结果fn1(); // 输出结果复制代码
大家可以看出来输出结果是什么吗?
如果你已经算出来的话,那么说明你对执行上下文还是有一些理解的,欢迎继续往下看加深印象
如果你没算出来或者输出结果与你算的不相符,那也先不要着急,先看下边内容,看完后再回来算
概念
大家都知道,JavaScript代码的在运行的时候都是自上而下按顺序执行的,但是呢实际并非是一行一行的执行,那大家有没有了解过它在执行代码的时候做过哪些准备,做过哪些事情,比如代码解析、分配内容都是在哪处理的,那这个地方呢就是执行上下文,是准备工作的所在环境
执行上下文类型
执行上下文呢有三种类型,分别是
全局执行上下文
函数执行上下文
还有就是eval函数执行上下文
那么我们继续,执行上下文呢是在代码编译阶段创建的,来看看执行上下文的生命周期
执行上下文生命周期
创建阶段
执行阶段
创建阶段
执行上下文的创建阶段具体做了什么事呢,又分为三部分
ExecutionContext = {ThisBinding = <thisvalue>,LexicalEnvironment = { ... },VariableEnvironment = { ... },
}
复制代码
确定this指向
在全局执行上下文中,this指向的是全局对象
在函数执行上下文中,this指向取决于该函数是如何被调用的
看下这个demo
const obj = {fn: function(){console.log(this)}
}
obj.fn(); //fn: f();
const func = obj.fn;
func(); // Window复制代码
词法环境
官方的 ES6 文档把词法环境定义为
词法环境是一种规范类型,基于 ECMAScript 代码的词法嵌套结构来定义标识符和具体变量和函数的关联。一个词法环境由环境记录器和一个可能的引用外部词法环境的空值组成。
简单来说词法环境是一种持有标识符—变量映射的结构。(这里的标识符指的是变量/函数的名字,而变量是对实际对象[包含函数类型对象]或原始数据的引用)。
现在,在词法环境的内部有两个组件:(1) 环境记录器和 (2) 一个外部环境的引用。
环境记录器是存储变量和函数声明的实际位置。
外部环境的引用意味着它可以访问其父级词法环境(作用域)。
词法环境有两种类型:
全局环境(在全局执行上下文中)是没有外部环境引用的词法环境。全局环境的外部环境引用是 null。它拥有内建的 Object/Array/等、在环境记录器内的原型函数(关联全局对象,比如 window 对象)还有任何用户定义的全局变量,并且 this的值指向全局对象。
在函数环境中,函数内部用户定义的变量存储在环境记录器中。并且引用的外部环境可能是全局环境,或者任何包含此内部函数的外部函数。
环境记录器也有两种类型(如上!):
声明式环境记录器存储变量、函数和参数。
对象环境记录器用来定义出现在全局上下文中的变量和函数的关系。
简而言之,
在全局环境中,环境记录器是对象环境记录器。
在函数环境中,环境记录器是声明式环境记录器。
注意 — 对于函数环境,声明式环境记录器还包含了一个传递给函数的 arguments 对象(此对象存储索引和参数的映射)和传递给函数的参数的 length。
抽象地讲,词法环境在伪代码中看起来像这样:
GlobalExectionContext = {LexicalEnvironment: {EnvironmentRecord: {Type: "Object",// 在这里绑定标识符}outer: <null>}
}
FunctionExectionContext = {LexicalEnvironment: {EnvironmentRecord: {Type: "Declarative",// 在这里绑定标识符}outer: <Globalorouterfunctionenvironmentreference>}
}
复制代码
变量环境
它同样是一个词法环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。
如上所述,变量环境也是一个词法环境,所以它有着上面定义的词法环境的所有属性。
在 ES6 中,词法环境组件和变量环境的一个不同就是前者被用来存储函数声明和变量(let 和 const)绑定,而后者只用来存储 var 变量绑定。
我们看点样例代码来理解上面的概念:
let a = 20;
const b = 30;
var c;
functionmultiply(e, f) {var g = 20;return e * f * g;
}
c = multiply(20, 30);
复制代码
执行上下文看起来像这样:
GlobalExectionContext = {
ThisBinding: <Global Object>,
LexicalEnvironment: {EnvironmentRecord: {Type: "Object",// 在这里绑定标识符a: < uninitialized >,b: < uninitialized >,multiply: < func >}outer: <null>},
VariableEnvironment: {EnvironmentRecord: {Type: "Object",// 在这里绑定标识符c: undefined,}outer: <null>}
}
FunctionExectionContext = {ThisBinding: <Global Object>,
LexicalEnvironment: {EnvironmentRecord: {Type: "Declarative",// 在这里绑定标识符Arguments: {0: 20, 1: 30, length: 2},},outer: <GlobalLexicalEnvironment>},
VariableEnvironment: {EnvironmentRecord: {Type: "Declarative",// 在这里绑定标识符g: undefined},outer: <GlobalLexicalEnvironment>}
}
复制代码
注意 — 只有遇到调用函数 multiply 时,函数执行上下文才会被创建。
可能你已经注意到 let 和 const 定义的变量并没有关联任何值,但 var 定义的变量被设成了 undefined。
这是因为在创建阶段时,引擎检查代码找出变量和函数声明,虽然函数声明完全存储在环境中,但是变量最初设置为 undefined(var 情况下),或者未初始化(let 和 const 情况下)。
这就是为什么你可以在声明之前访问 var 定义的变量(虽然是 undefined),但是在声明之前访问 let 和 const 的变量会得到一个引用错误。
这就是我们说的变量声明提升。
执行阶段
这是整篇文章中最简单的部分。在此阶段,完成对所有这些变量的分配,最后执行代码。
注意 — 在执行阶段,如果 JavaScript 引擎不能在源码中声明的实际位置找到 let 变量的值,它会被赋值为 undefined。
执行栈
那根据上述执行上下文的理解,那我们知道在执行代码中会有很多的执行上下文,那么执行上下文是怎么确定执行顺序的。
执行上下文存放的位置就是在执行上下文栈,也叫调用栈。具有LIFO(Last In First Out后进先出,也就是先进后出)的特性。
那我们来看下之前的例题,来分析下
var a = 10;
functionfn(b) {b = 20;console.log(a, b);
}
functionfn1() {a = 100;fn(a);
}
fn(200); //输出结果fn1(); // 输出结果复制代码
首先进入全局执行环境,创建全局执行上下文环境并加入栈中
fn()函数被调用,进入对应的函数执行环境,创建函数执行环境并加入栈
执行 console.log(a, b);代码
console.log(a, b);代码出栈
fn()函数执行完毕后出栈
fn1()函数被调用,进入对应的函数执行环境,创建函数执行环境并加入栈
继续fn()函数被调用,进入对应的函数执行环境,创建函数执行环境并加入栈
执行 console.log(a, b);代码
console.log(a, b);代码出栈
fn()函数执行完毕后出栈
fn1()函数出栈
全局执行上下文出栈

题解
那我们再来分析下例题的答案
var a = 10;
functionfn(b) {b = 20;console.log(a, b);
}
fn(200);
复制代码
在执行fn函数时,此fn活动对象为
AO : {a: 10,b: 20,arguments: {0 : 20, length:0}
}
复制代码
所以此时输出结果为10,20
继续看
var a = 10;
functionfn(b) {b = 20;console.log(a, b);
}
functionfn1() {a = 100;fn(a);
}
fn1();
复制代码
在执行fn1函数时,此fn1活动对象为
AO : {a: 100,fn: reference to functionfn(){}arguments: {length: 0}
}
复制代码
在继续执行fn函数时,此fn活动对象为
AO : {a: 100,b: 20,arguments: {0 : 20, length:0}
}
复制代码
所以此时输出结果为100,20
作用域
例题
大家先来看下下边的题,看下是否能看出来结果
var a = 1;
functionfn() {var b = 10;c = 100;let d = 20;console.log(1000)returnfunction() {console.log(a); console.log(b);console.log(d)}
}
var func = fn();
func();
console.log(b);
console.log(d);
复制代码
大家可以看出来输出结果是什么吗?
概念
作用域是可访问的变量,对象,函数的结合,同时也决定了这些变量的可访问性。JavaScript中有三种作用域,分别是全局作用域,函数作用域,块级作用域。那就来聊聊这三种作用域
全局作用域
什么是全局作用域呢,先来看下概念
最外层的函数和在最外层函数外面定义的变量是拥有全局作用域的
所有的未声明的变量自动声明为拥有全局作用域的变量
我们开来接着看下上边例题
var a = 1;
functionfn() {var b = 10;c = 100;console.log(1000)returnfunction() {console.log(a); console.log(b);}
}
fn();
console.log(c)
复制代码
那我们根据上述概念来分析下
变量a呢是拥有全局作用域的全局变量,是可以在程序任何位置都可以访问到的
函数fn也是拥有全局作用域的函数
接着来看下输出结果
fn(); // 1000console.log(c); //100复制代码
这个就很简单了吧。相信99%的前端 应该都会吧
函数作用域
来看下函数作用域的概念
函数作用域呢也被称为局部作用域,因为一般只有在固定的代码片段中可以访问到,也就是说只能在函数内部访问,函数外部是访问不到的。
那我们接着来看下上述例题,相信小部分人是卡在console.log(b)这个输出结果上了,没关系继续往下看
var a = 1;
functionfn() {var b = 10;c = 100;console.log(1000)returnfunction() {console.log(a); console.log(b);}
}
var func = fn();
func();
console.log(b)
复制代码
来继续根据函数作用域的概念来分析下
变量b呢是在函数内部,所以称为局部变量,只能在函数内部访问,外部是无法访问的
那根据这个解释看的话,这个输出结果就很明显了吧
var func = fn(); //1000func(); //1, 10console.log(b); //b is not defined复制代码
那么现在知道为什么console.log(b);输出结果是b is not defined了吗
块级作用域
我们来看看块级作用域的概念
简单来说变量是存在于一个大括号之内,在大括号之外是不能访问这些块级作用域中的变量,当然是有局限性的只针对于ES6 中的const与let来说
因为呢在ES6之前呢,JavaScript是没有块级作用域的
那继续看例题,例题中有let声明的变量
var a = 1;
functionfn() {let d = 20;returnfunction() {console.log(d)}
}
var func = fn();
func();
console.log(d);
复制代码
看上述块级作用域的解释
那我们知道let d = 20;是在大括号中的变量,那根据概念括号外是无法访问的,那也应该知道答案是什么了吧
console.log(d); //d is not defined复制代码
那最后在回头看初始例题,是不是一切都变的很简单
最后输出结果
var func = fn(); // 1000func(); // 1,10,20console.log(b); // b is not defined// 不过console.log(d); 是输出不了结果的,因为上一步已经报错了console.log(d); // d is not defined复制代码
作用域链
那我们继续看上述例题
var a = 1;
functionfn() {var b = 10;c = 100;let d = 20;console.log(1000)returnfunction() {console.log(a); console.log(b);console.log(d)}
}
var func = fn();
func();
console.log(b);
console.log(d);
复制代码
其中console.log(a)输出a,那这个a是在哪里来的,因为在一般的情况下会在当前作用域中取值,那在当前作用域没找到的话,会去上级作用域中寻找,一直到找到全局作用域。这么一个寻找的过程中呢就会形成一个链条,就叫做作用域链
总结
作用域是可访问的变量,对象,函数的结合,同时也决定了这些变量的可访问
全局作用域是说在最外层的函数以及不在任何函数或者打括号中声明的变量,都在全局作用域下,程序中任务位置都可以访问的变量
函数作用域呢是变量声明在函数中只能在函数内部访问,函数外部是访问不到的
块级作用域呢是说对于ES6 中的const与let来说,在大括号之内的变量是存在于块级作用域中的,大括号之外不能访问这些块级作用域中的变量
作用域链在寻找变量值的时候,层层往上形成的链条
闭包
例题
大家先来看下这道题,看下是否能看出来输出结果
var data = [];
for (var i = 0; i < 3; i++) {data[i] = function () {console.log(i);};
}
data[0](); // 输出结果
data[1](); // 输出结果
data[2](); // 输出结果复制代码
优雅永不过时,答对了说明你对闭包还是有一定研究的,没答对的继续往下看
概念
那我们先来看看闭包的概念,什么是闭包,看看MDN与高级程序设计给出的概念
能够访问其它函数内部变量的函数,称为闭包
能够访问自由变量的函数,称为闭包
分析
那我们来分析下上边的例题
在分析之前你需要对作用域以及执行上下文有一定的了解,如果不太明确的话,可以优先看下这两篇文章
再继续阅读下面内容
var data = [];
for (var i = 0; i < 3; i++) {data[i] = function () {console.log(i);};
}
data[0](); // 输出结果
data[1](); // 输出结果
data[2](); // 输出结果复制代码
首先我们记录下这道例题的执行上下文栈的变化
首先进入了全局执行上下文,然后创建全局执行上下文,将全局上下文放入执行上下文栈中
然后继续初始化执行全局上下文,创建作用域链以及变量对象等
那么此时的全局上下文VO为
globalContext = {VO: {data: [...],i: 3}
}
复制代码
执行data[0](),然后创建data[0]()执行上下文,继续放入执行上下文栈内
然后呢初始化data[0]()执行上下文,创建作用域链以及变量对象等
那么此时的data[0]()AO为
data[0]Context = {AO: {arguments: {length: 0} }
}
复制代码
那么此时的data[0]()作用域链为
data[0]Context = {Scope: [AO, globalContext.VO]
}
复制代码
因为在data[0]Context活动对象AO中是没有i值的,所以去全局上下文的变量对象中查找,此时全局上下文的变量对象中i值为3
所以data[0]()输出结果为3
执行完毕后在data[0]()执行上下文在执行上下文栈给弹出
至于data[1]()与data[2]()与步骤3-5是一样的,所以在这就不多说了
场景
至于闭包的使用场景,其实在日常开发中使用到是非常频繁的
防抖节流函数
定时器回调
等就不一一列举了
优缺点
优点
闭包帮我们解决了什么问题呢
内部变量是私有的,可以做到隔离作用域,保持数据的不被污染性
缺点
同时闭包也带来了不小的坏处
说到了它的优点内部变量是私有的,可以做到隔离作用域,那也就是说垃圾回收机制是无法清理闭包中内部变量的,那最后结果就是内存泄漏
大厂面试题分享 面试题库
前后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
相关文章:

【面试题】三道面试题让你掌握JavaScript中的执行上下文与作用域以及闭包
前言大厂面试题分享 面试题库前后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库大家好,笔者呢最近再回顾JavaScript知识时,又看到了JavaScript的一些较为常见的内容,仔细看了之后发现…...

计算机网络-- 应用层(day08)
计算机网络两种方式 网络应用程序运行再处于网络边缘的不同端系统上,通过彼此间的通信来共同完成某项任务。 开发一种新的网络应用首先要考虑的问题就是网络应用程序在各种端系统上的组织方式和它们之间的关系。 目前流行的主要有以下两种: 客户/服务器…...

English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一
English Learning - L2-5 英音地道语音语调 弹力双元音 [ɪə] [ʊə] [eə] 2023.03.6 周一朗读节奏元音的长度元音发音在清辅音和浊辅音前的区别元音发音跟后面浊辅音节数的区别元音在重读音节中复习大小元音发音对比/ʌ/ 舌中音/ɒ/ 舌后音/ʊ/ 舌后音/ɪ/ 舌前音[ɑ:] VS […...

SpringBoot——统一功能处理
处理登陆拦截 上一片博客中讲到SpringAOP可以对页面进行拦截,我们可以用SpringAOP实现对登陆的拦截 但是由于拦截需要HttpSession对象,并且之后还需要页面重定向,因此在实际应用中,并不用SpringAOP进行登陆拦截,而是…...

ORACLE SQL格式化小数点
ORACLE SQL格式化小数点 select CONCAT(TO_CHAR(0.00100,‘990.999’),‘%’) as a0 , CONCAT(TO_CHAR(1100,‘990.999’),‘%’) as a1 , CONCAT(TO_CHAR(0.236100,‘990.999’),‘%’) as a2 , CONCAT(TO_CHAR(0.0200100,‘990.999’),‘%’) as a3 , CONCAT(TO_CHAR(1.0310…...
【信息学奥数】—— 第一部分 C++语言 知识总结
【信息学奥数】—— 第一部分 C语言 知识总结C语言一、C语言入门二、顺序结构程序设计运算符和表达式常量和变量标准数据类型数据输入输出三、控制结构程序设计if语句switch语句四、循环结构程序设计for语句while语句do-while语句五、数组一维数组二维数组字符数组六、函数七、…...
video层级过高,以及界面使用多个video时,在安卓APP上同时播放的问题(uniapp)
1、video层级过高的问题 问题一: 我的界面由于是自定义导航栏,所以使用video时,上滑界面video会直在最上层,盖着 头部导航栏 解决方法:使用cover-view,自定义头部使用cover-view替换view 问题二:自定义…...

C++基础了解-14-C++ 字符串
C 字符串 一、C 风格字符串 C 风格的字符串起源于 C 语言,并在 C 中继续得到支持。字符串实际上是使用 null 字符 \0 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 RUNOOB …...
浅谈几种网络攻击及攻防原理
HTTP Flood攻击 https://zhuanlan.zhihu.com/p/337399808 HTTP Flood攻击是针对Web服务在第七层协议发起的攻击。第七层主要是应用层,是一些终端的应用,比如(各种文件下载)、浏览器、QQ等,可以将其理解为在电脑屏幕上可…...

Kafka消息中间件(Kafka与MQTT区别)
文章目录KafkaKafka重要原理Topic 主题Partition 分区Producer 生产者Consumer 消费者Broker 中间件Offset 偏移量Kafka与mqtt区别Kafka Kafka是一个分布式流处理平台,它可以快速地处理大量的数据流。Kafka的核心原理是基于发布/订阅模式的消息队列。Kafka允许多个…...

Go垃圾回收原理
术语介绍 赋值器:说白了就是你写的程序代码,在程序的执行过程中,可能会改变对象的引用关系,或者创建新的引用。 回收器:垃圾回收器的责任就是去干掉那些程序中不再被引用得对象。 STW:全称是stop the word,GC期间某个阶段会停止…...
Coredump-N: stack 空间被临时变量吃满,导致内存访问出现问题
文章目录 代码寄存器汇编代码 int main() {fun(0); #define S 0x0019fd08UL 、、 乘5 等0x81F128 char buff4[S]; char buff3[S]; char buff2[S]; char buff1[S]; char buff[S]; memset(buff, 0, sizeof(buff)); memset(buff4, 0, sizeof(buff)); memset(buff3, 0, sizeof(buf…...
GO中使用viper读取配置文件
文章目录 viper的使用例子一:例子二:viper的使用 viper的源码地址https://github.com/spf13/viper,它是一个可以用来读取配置文件的工具。在项目中可以通过下面指令安装: go get github.com/spf13/viper 下面我们通过两个例子,来介绍一下viper在项目中应该如何使用…...

webpack dll 提升构建速度
DLL,动态链接库(Dynamic Link Library 或者 Dynamic-link Library),由微软公司提出。目的是为了节约应用程序所需的磁盘和内存空间。 在一个传统的非共享库中,如果两个程序调用同一个子程序,就会出现两份那…...

C++面向对象编程之三:初始化列表、类对象作为类成员、静态成员
初始化列表C提供了初始化列表语法,可以用于成员属性初始化。语法规则:无参构造函数():属性1(值1), 属性2(值2), ... { }有参构造函数(形参1, 形参2, ...):属性1(形参1), 属性2(形参2), ... { }example:写一个怪物类,有怪物id和血量…...

跨域问题解决方案
目录 1.同源策略 2.解决方案(后端) (1)在后端方法添加CrossOrigin (2)添加CORS过滤器 (3)实现WebMvcConfigure接口,重写addCorsMappings方法 3.解决方案(前端) (1)前端配置代理 1.同源策略 同源策略(Same origin policy)是一种约定&am…...
Vue3电商项目实战-购物车模块7【20-登录后-批量删除、21-登录后-选中状态修改数量、22-登录后-全选反选、23-登录后-修改规格、24-下单结算】
文章目录20-登录后-批量删除21-登录后-选中状态&修改数量22-登录后-全选反选23-登录后-修改规格24-下单结算20-登录后-批量删除 目标:完成批量删除选中商品,完成清空失效的商品 大概步骤: 完成cart.js模块中的批量删除actions的登录状态…...

软件测试之快速熟悉项目
快速熟悉项目 1、了解项目架构 C/S架构 C/S 代表的是客户端/服务器(client/server),这类软件的使用者需要在本地电脑安装客户端程序,例如:QQ。 优点:安全性高。 缺点:一旦软件有更新,用户需要手动下载&am…...
软考高级信息系统项目管理师系列之二十一:项目风险管理
软考高级信息系统项目管理师系列之二十一:项目风险管理 一、项目风险管理内容整理二、项目风险管理1.风险及项目风险管理定义2.项目风险的特点3.风险的分类4.风险成本5.项目风险管理与其他管理的关系三、规划风险管理1.规划风险管理2.输入3.工具与技术4.输出四、识别风险1.识别…...

打包成JAR文件和WAR文件,到底有什么区别?
Spring Boot是一种基于Spring框架的快速开发应用程序的工具,可以轻松地构建可部署的独立应用程序。在使用Spring Boot时,你可能会注意到有两种不同的部署选项:打包成JAR文件和WAR文件。在这篇文章中,我们将深入探讨这两种部署选项…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...