【this详解】学习JavaScript的this的使用和原理这一篇就够了,超详细,建议收藏!!!

news2024/11/27 16:44:14

在这里插入图片描述

😁 作者简介:一名大四的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:前端js专栏
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气

​🔥​前言:

this如果理解的不够清晰,对开发者来说完全就是魔法一样,接下来我会为大家从词法作用域和调用栈,真正的this原理出发,让大家更好的理解到位this,希望可以帮助到大家,欢迎大家的补充和纠正

文章目录

  • 关于this
    • 1 this出现的意义
    • 2 误解
      • 2.1 指向自身
      • 2.2 它的作用域
    • 3 this到底是什么
    • 4 调用位置
    • 5 绑定规则
      • 5.1 默认绑定
      • 5.2 隐式绑定
      • 5.3 显示绑定
      • 5.4 new绑定
    • 6 优先级
    • 7 绑定例外
      • 7.1 被忽略的this
      • 7.2 间接引用
    • 8 this词法

关于this

1 this出现的意义

在正式学习this之前,我们心中肯定有一些疑惑,为什么要学习this?,this的好处是什么?

下面我来解释一下为什么要使用this:

function identify() {
	return this.name.toUpperCase();
}
function speak() {
	var greeting = " 你好,我是" + identify.call( this );
	console.log( greeting );
}
var me = {
	name: "小七"
};
var you = {
	name: "小画"
};
identify.call( me ); // 小七
identify.call( you ); // 小画
speak.call( me ); // 你好,我是小七
speak.call( you ); // 你好,我是小画

上面的代码中,我们使用this来指代参数,假如我们不使用this,那我们就需要给identify()和speak()显式传入一个上下文对象

function identify(context) {
	return context.name.toUpperCase();
}
function speak(context) {
	var greeting = " 你好,我是" + identify.call( context );
	console.log( greeting );
}

identify(you) //小画
speak(me) //你好,我是小七

所以,this提供一种更加优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用

🌴 随着你的使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用 this则不会这样。当我们介绍对象和原型时,就会明白函数可以自动引用合适的上下文对象有多重要。

2 误解

在真正了解this之前,有两种“自然而然”得对于this得解释,但是它们都是错误的

以下的两个代码请大家在浏览器的环境中去运行,如果在Node的环境中运行,得到的结果会很不同,会影响大家理解this

这是因为两种环境下的全局对象不同,声明函数的行为不同

在浏览器的环境中,声明的函数会成为全局对象的属性

在Node的环境中,声明的函数不会成为全局对象的属性,会单独存在

2.1 指向自身

我们很容易把this理解成指向函数自身,在书写递归的时候,我们就需要从函数内部引用函数自身

🤔 请思考以下的代码:

<script>
function foo(num) {
	console.log( "foo: " + num );
	// 记录 foo 被调用的次数
	this.count++;
}
foo.count = 0;

var i;

for (i=0; i<10; i++) {
	if (i > 5) {
		foo( i );
	}
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9
// foo 被调用了多少次?
console.log( foo.count ); // 0 -- 额?
</script>

console.log 语句产生了 4 条输出,证明 foo(…) 确实被调用了 4 次,但是 foo.count 仍然是 0。显然从字面意思来理解 this 是错误的。

执行 foo.count = 0 时,的确向函数对象 foo 添加了一个属性 count。但是函数内部代码this.count 中的 this 并不是指向那个函数对象,所以虽然属性名相同,根对象却并不相同,其this指向的是全局对象,之后我们会详细解释具体的原理。

📝 补充:解决这种代码的方法有两个

  • 直接使用foo标识符替代this来引用函数对象

    function foo(num) {
    	console.log( "foo: " + num );
    	// 记录 foo 被调用的次数
    	foo.count++;
    }
    
  • 强制this指向foo函数对象

    for (i=0; i<10; i++) {
    	if (i > 5) {
    	// 使用 call(..) 可以确保 this 指向函数对象 foo 本身
    	foo.call( foo, i );
    	}
    }
    

2.2 它的作用域

第二种常见的误解是,this 指向函数的作用域。这个问题有点复杂,因为在某种情况下它是正确的,但是在其他情况下它却是错误的。

需要明确的是,this 在任何情况下都不指向函数的词法作用域。在 JavaScript 内部,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过 JavaScript代码访问,它存在于 JavaScript 引擎内部。

🤔 思考以下代码:

<script>
    function foo() {
        var a = 2;
        this.bar();
    }
    function bar() {
        console.log(this.a);
    }
    foo(); // ReferenceError: a is not defined
</script>

这段代码试图通过 this.bar() 来引用 bar() 函数。这是有问题的。调用 bar() 最自然的方法是省略前面的 this,直接使用词法引用标识符。

此外,编写这段代码的开发者还试图使用 this 联通 foo() 和 bar() 的词法作用域,从而让bar() 可以访问 foo() 作用域里的变量 a。这是不可能实现的,你不能使用 this 来引用一个词法作用域内部的东西。

每当你想要把 this 和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。

3 this到底是什么

排除了一些错误理解之后,我们来看看 this 到底是一种什么样的机制。

之前我们说过 this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

this的指向什么完全取决于函数在哪里调用

当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this 就是记录的其中一个属性,会在函数执行的过程中用到。

4 调用位置

上一节中,我们提到了调用位置,要理解this的绑定和指向就要先理解调用位置,也就是函数在代码中被调用的位置(而不是声明的位置)。

通常来说,寻找调用位置就是寻找“函数被调用的位置”,但是做起来并没有这么简单,因为某些编程模式可能会隐藏真正的调用位置。

最重要的是要分析调用栈(就是为了到达当前执行位置所调用的所有函数)。我们关心的调用位置就在当前正在执行的函数的前一个调用中。

function baz() {
	// 当前调用栈是:baz
	// 因此,当前调用位置是全局作用域
	console.log( "baz" );
	bar(); // <-- bar 的调用位置
}

function bar() {
	// 当前调用栈是 baz -> bar
	// 因此,当前调用位置在 baz 中
	console.log( "bar" );
	foo(); // <-- foo 的调用位置
}

function foo() {
	// 当前调用栈是 baz -> bar -> foo
	// 因此,当前调用位置在 bar 中
	console.log( "foo" );
}

baz(); // <-- baz 的调用位置

5 绑定规则

当我们找到调用位置后,只要判断需要应用下面四条规则中的哪一条,就可以决定this的绑定对象

5.1 默认绑定

首先要介绍的是最常用的函数调用类型:独立函数调用。可以把这条规则看作是无法应用其他规则时的默认规则

🤔 思考以下代码:

function foo() {
	console.log( this.a );
}

var a = 2;

foo(); // 2

我们可以注意到,声明在全局作用域中的变量(比如var a= 2)就是全局对象的一个同名属性,

接下来可以看到当调用foo()时,this.a被解析成了全局变量a。为什么?因为在本例中,函数调用时应用了this的默认绑定,因此this指向全局对象。

那么我们怎么知道这里应用了默认绑定呢?可以通过分析调用位置来看看 foo() 是如何调用的。在代码中,foo() 是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定,无法应用其他规则。

❗️ 如果使用严格模式的话,那么全局对象将无法默认绑定,因此this会绑定到undefined

5.2 隐式绑定

另一条需要考虑的规则是调用位置是否有上下文对象,或者说是否被某一个对象拥有或者包含

🤔 思考下面的代码:

function foo() {
	console.log( this.a );
}

var obj = {
	a: 2,
	foo: foo
};

obj.foo(); // 2

首先我们需要注意的是foo()的声明方式,及其之后是如何被当作引用属性添加到obj中的 但是无论是直接在obj中定义还是先定义再添加这个属性,这个函数严格来说都不属于obj对象

然而,调用位置会使用obj上下文来引用函数,**因此可以说函数被调用时obj对象“拥有” 或者 “ 包含” **

隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象。因为调用 foo() 时 this 被绑定到 obj,因此 this.a 和 obj.a 是一样的。

❗️ 一些注意点

  1. 对象属性引用链只有最顶层或者说最后一层会影响调用位置

    function foo() {
    	console.log( this.a );
    }
    var obj2 = {
    	a: 42,
    	foo: foo
    };
    var obj1 = {
    	a: 2,
    	obj2: obj2
    };
    obj1.obj2.foo(); //42
    
  2. ⭐️ 隐式丢失:因为函数可能会丢失绑定对象,导致应用默认绑定,从而把this绑定到全局对象或者undefined上(取决于是否严格模式)

    function foo() {
    	console.log( this.a );
    }
    
    var obj = {
    	a: 2,
    	foo: foo
    };
    
    var bar = obj.foo; // 函数别名!
    var a = "我是全局a呢"; // a 是全局对象的属性
    bar(); // "我是全局a呢"
    

    虽然 bar 是 obj.foo 的一个引用,但是实际上,它引用的是 foo 函数本身,因此此时的bar() 其实是一个不带任何修饰的函数调用,因此应用了默认绑定

    还有一种更微妙,更常见的就是发生在传入回调函数时

    function foo() {
    	console.log( this.a );
    }
    function doFoo(fn) {
    	// fn 其实引用的是 foo
    	fn(); // <-- 调用位置!
    }
    var obj = {
    	a: 2,
    	foo: foo
    };
    var a = "我是全局a呢"; // a 是全局对象的属性
    doFoo( obj.foo ); // "我是全局a呢"
    

    参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值,所以结果和上一个例子一样。

5.3 显示绑定

就像我们刚才看到的那样,在分析隐式绑定时,我们必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把 this 间接(隐式)绑定到这个对象上。

那么如果我们不想在对象内部包含函数引用,而想在某个对象上强制调用函数,该怎么做呢?

JavaScript 中的“所有”函数都有一些有用的特性,可以用来解决这个问题。具体点说,可以使用函数的 call(…) 和apply(…) 方法。还有bind(…)方法

如果有不了解这三个方法是什么,怎么样的小伙伴可以查看我的另外一篇博客

function foo() {
console.log( this.a );
}
var obj = {
a:2
};
foo.call( obj ); // 2

通过foo.call(…),我们可以在调用foo时强制把它的this绑定到obj上

显式绑定仍然无法解决我们之前提出的丢失绑定问题

var obj = {
  name: "John",
  func: function() {
    setTimeout(function() {
      console.log(this.name); // 这里的 this 会丢失绑定
    }.call(this), 1000);
  }
};
obj.func();

但是显示绑定中的一个变种bind可以解决这个问题

function foo() {
	console.log( this.a );
}
var obj = {
	a:2
};
var bar = foo.bind(obj)
bar(); // 2
setTimeout( bar, 100 ); // 2

5.4 new绑定

这是第四条也是最后一条 this 的绑定规则,在讲解它之前我们首先需要澄清一个非常常见的关于 JavaScript 中函数和对象的误解。

在传统的面向类的语言中,“构造函数”是类中的一些特殊方法,使用 new 初始化类时会调用类中的构造函数。通常的形式是这样的:

something = new MyClass(..);

JavaScript 也有一个 new 操作符,使用方法看起来也和那些面向类的语言一样,绝大多数开发者都认为 JavaScript 中 new 的机制也和那些语言一样。然而,JavaScript 中 new 的机制实际上和面向类的语言完全不同。

首先我们重新定义一下 JavaScript 中的“构造函数”。在 JavaScript 中,构造函数只是一些使用 new 操作符时被调用的函数。它们并不会属于某个类,也不会实例化一个类。实际上,它们甚至都不能说是一种特殊的函数类型,它们只是被 new 操作符调用的普通函数而已。

举例来说,思考一下 Number(…) 作为构造函数时的行为,ES5.1 中这样描述它:

15.7.2 Number 构造函数
当 Number 在 new 表达式中被调用时,它是一个构造函数:它会初始化新创建的对象。

所以,包括内置对象函数(比如 Number(…),详情请查看第 3 章)在内的所有函数都可以用 new 来调用,这种函数调用被称为构造函数调用。这里有一个重要但是非常细微的区别:实际上并不存在所谓的“构造函数”,只有对于函数的“构造调用”。

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

  1. 创建(或者说构造)一个全新的对象。

  2. 这个新对象会被执行 [[ 原型 ]] 连接。

  3. 这个新对象会绑定到函数调用的 this。

  4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。

我们现在关心的是第 1 步、第 3 步、第 4 步,所以暂时跳过第 2 步,下一节会介绍它

function foo(a) {
	this.a = a;
}
var bar = new foo(2);
console.log( bar.a ); // 2

使用 new 来调用 foo(…) 时,我们会构造一个新对象并把它绑定到 foo(…) 调用中的 this上。new 是最后一种可以影响函数调用时 this 绑定行为的方法,我们称之为 new 绑定

6 优先级

现在我们已经了解了函数调用中的this绑定的四条规则,接下来我们需要知道就是找到函数的调用位置并判断应用哪一条规则

但是,如果某个调用位置可以应用多条规则该怎么办?为了解决这个问题就必须给这些规则设定优先级

下面的优先级由高到低

  1. new绑定
  2. 显示调用
  3. 隐式调用
  4. 默认调用

new绑定的优先级最高,默认调用的优先级最低

⭐️ 现在我们可以根据优先级来判断使用哪条规则,可以按照下面的顺序来进行判断:

  1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。var bar = new foo()
  2. . 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是指定的对象。var bar = foo.call(obj2)
  3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上下文对象。var bar = obj1.foo()
  4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。var bar = foo()

就是这样,对于正常的函数调用来说,拥有这些知识就可以明白this的绑定原理。

不过凡是总是有例外的…

7 绑定例外

在某些场景下this的绑定会出乎意料,与你认为的大大不同

7.1 被忽略的this

如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则:

function foo() {
	console.log( this.a );
}

var a = 2;

foo.call( null ); // 2

那么什么情况下会传入null呢

一种非常常见的使用就是使用bind(…)对参数进行柯里化

function foo(a,b) {
	console.log( "a:" + a + ", b:" + b );
}

var bar=foo.bind(null,2)
bar(3) //a:2,b:3

然而,总是使用 null 来忽略 this 绑定可能产生一些副作用。如果某个函数确实使用了this(比如第三方库中的一个函数),那默认绑定规则会把 this 绑定到全局对象(在浏览器中这个对象是 window),这将导致不可预计的后果(比如修改全局对象)

更安全的this

一种“更安全”的做法是传入一个特殊的对象,把 this 绑定到这个对象不会对你的程序产生任何副作用

如果我们在忽略 this 绑定时总是传入一个 DMZ 对象,那就什么都不用担心了,因为任何对于 this 的使用都会被限制在这个空对象中,不会对全局对象产生任何影响。

function foo(a,b) {
	console.log( "a:" + a + ", b:" + b );
}
// 我们的 DMZ 空对象
var ø = Object.create( null );

// 使用 bind(..) 进行柯里化
var bar = foo.bind( ø, 2 );
bar( 3 ); // a:2, b:3

7.2 间接引用

另一个需要注意的是,你有可能(有意或者无意地)创建一个函数的“间接引用”,在这种情况下,调用这个函数会应用默认绑定规则。

间接引用最容易在赋值时发生

function foo() {
	console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };

o.foo(); // 3
(p.foo = o.foo)(); // 2

赋值表达式 p.foo = o.foo 的返回值是目标函数的引用,因此调用位置是 foo() 而不是p.foo() 或者 o.foo()。根据我们之前说过的,这里会应用默认绑定。

❗️ 注意:对于默认绑定来说,决定 this 绑定对象的并不是调用位置是否处于严格模式,而是函数体是否处于严格模式。如果函数体处于严格模式,this 会被绑定到 undefined,否则this 会被绑定到全局对象。

8 this词法

我们之前介绍的四条规则已经可以包含所有正常的函数。但是 ES6 中介绍了一种无法使用这些规则的特殊函数类型:箭头函数

箭头函数并不是使用 function 关键字定义的,而是使用被称为“胖箭头”的操作符 => 定义的。箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决定 this。

我们来看看箭头函数的词法作用域

function foo() {
	// 返回一个箭头函数
	return (a) => {
	//this 继承自 foo()
	console.log( this.a );
	};
}
var obj1 = {
	a:2
};
var obj2 = {
	a:3
};

var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是 3 !

foo() 内部创建的箭头函数会捕获调用时 foo() 的 this。由于 foo() 的 this 绑定到 obj1,bar(引用箭头函数)的 this 也会绑定到 obj1,箭头函数的绑定无法被修改。(new 也不行!)

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

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

相关文章

IS200EPSMG1AED 使用Lua创建逻辑脚本或完整程序

IS200EPSMG1AED 使用Lua创建逻辑脚本或完整程序 IS200EPSMG1AED 是一种支持网络的I/O控制器&#xff0c;它执行类似于可编程逻辑控制器(PLC)的控制、逻辑和监控功能。然而&#xff0c;与PLC不同&#xff0c;X-600M是为基于网络的应用而设计的。X-600M可以使用内置网络服务器和…

094基于web+springboot的酒店客房管理系统

欢迎大家关注&#xff0c;一起好好学习&#xff0c;天天向上 文章目录 一项目简介技术介绍 二、功能组成三、效果图四、 文章目录 一项目简介 本酒店客房管理系统有管理员&#xff0c;用户&#xff0c;会员&#xff0c;清洁人员。管理员功能有个人中心&#xff0c;用户管理&am…

2023年最新CUDA安装教程,看完就会(windows版)。

目录 前言 注意&#xff1a;本教程建立在您已经正确安装了显卡驱动的基础上 第一步&#xff0c;找到对应的CUDA版本 第二步&#xff0c;查看你要安装的pytorch版本对应的cuda版本&#xff08;如果只需要安装cuda可以跳过&#xff09; 第二步,下载cuda 第三步&#xff0c;…

PointNet++ 论文阅读

论文链接 PointNet 0. Abstract **背景&#xff1a;**PointNet的设计并未捕捉到度量空间中存在的局部结构&#xff0c;限制了其识别细粒度模式和适用于复杂场景的能力 解决思路&#xff1a; 引入了一种分层神经网络&#xff0c;该网络在输入点集的嵌套分割上递归地应用Poin…

[PHP]禅道项目管理软件ZenTaoPMS源码包 v16.4

禅道项目管理软件ZenTaoPMS一键安装包是一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体&#xff0c;是一款专业的研发项目管理软件&#xff0c;完整地覆盖了项目管理的核心流程。注重实效的管理思想&#xff0c;合理的软件…

C语言,数据结构指针,结构构体操作符 •,->,*的区别,看这篇就够了

在朋友们学习指针和数据结构这一章的时候&#xff0c;对各种操作符云里雾里。当你看到这么文章之后你就会明白了。 一 • 和 ->运算符 • 运算符&#xff1a;是结构变量访问结构体成员时用的操作符 -> 运算符&#xff1a;这是结构体指针访问结构体成员时调用的运算符。 …

GCN火车票识别项目 P1 火车票识别项目介绍 Pytorch LSTM/GCN

从本节开始&#xff0c;我将带大家完成一个深度学习项目&#xff1a;用图卷积神经网络(GCN)&#xff0c;实现一个「火车票文字信息提取」的项目&#xff0c;由于火车票上每个节点文字不是等长的&#xff0c;所以还需要添加一个前置的 LSTM 来提取句子特征。 课前说明 1、这是…

VScode + opencv + c++ + win配置教程

准备&#xff1a; 1、下载opencv 2、下载MinGw 3、 3、下载CMake 下载完解压放到一个文件夹里面&#xff0c;便于环境管理&#xff0c;文件夹我重命名了&#xff0c;解压出来文件名不一样正常 环境变量配置 C:\Users\wuxulong\cpp_env\MinGw\mingw64\bin C:\Users\wuxulon…

联想服务器-HTTP boot安装Linux系统

HTTP boot与传统PXE的主要差异 HTTP不再需要使用UDP协议的tftp服务&#xff08;连接不可靠、不支持大文件&#xff09;了&#xff0c;只需要dhcp 和http 两个服务即可&#xff0c;支持较稳定的大文件传输。 实验环境 ThinkSystem服务器SR650V2 SR660V2 通过HTTP boot安装Cen…

Android java Handler sendMessage使用Parcelable传递实例化对象,我这里传递Bitmap 图片数据

一、Bundle给我们提供了一个putParcelable(key,value)的方法。专门用于传递实例化对象。 二、我这里传递Bitmap 图片数据&#xff0c;实际使用可以成功传统图像数据。 发送&#xff1a;Bundle bundle new Bundle();bundle.putParcelable("bitmap",bitmap);msg.setD…

YOLO算法改进5【中阶改进篇】:添加SENet注意力机制

SE-Net 是 ImageNet 2017&#xff08;ImageNet 收官赛&#xff09;的冠军模型&#xff0c;是由WMW团队发布。具有复杂度低&#xff0c;参数少和计算量小的优点。且SENet 思路很简单&#xff0c;很容易扩展到已有网络结构如 Inception 和 ResNet 中。 我们可以看到&#xff0c;已…

NLP 模型中的偏差和公平性检测

一、说明 近年来&#xff0c;自然语言处理 &#xff08;NLP&#xff09; 模型广受欢迎&#xff0c;彻底改变了我们与文本数据交互和分析的方式。这些基于深度学习技术的模型在广泛的应用中表现出了卓越的能力&#xff0c;从聊天机器人和语言翻译到情感分析和文本生成。然而&…

IntelliJ IDEA2023旗舰版和社区版下载安装教程(图解)

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【C语法学习】14 - 流和文件

文章目录 1 流1.1 概念1.2 优点1.3 分类1.3.1 输入流和输出流1.3.2 标准流和文件流1.3.2.1 标准流1.3.2.2 文件流 1.3.3 文本流和二进制流 4 文件4.1 分类4.2 区别 1 流 1.1 概念 "流"的概念比较抽象&#xff0c;经典C语言书籍《C Primer Plus》中是这样描述的&…

两分钟搞定MySQL安装——极速mysql5.7安装教程

一、下载mysql mysql官网传送带&#xff1a; MySQL :: Download MySQL Community Server 选择好版本后直接下载即可&#xff0c;版本格式为zip格式。 二、安装mysql 1、解压zip安装包 ps&#xff1a;解压缩的路径里面不要出现中文哦&#xff01; 2、设置配置文件 新建data…

字节10年经验,花3个月熬夜整理的超全面试真题(附答案)

软件测试工程师&#xff0c;和开发工程师相比起来&#xff0c;虽然前期可能不会太深&#xff0c;但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位&#xff0c;问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

一、修改Ubuntu的IP

1、配置虚拟机 三台虚拟机&#xff0c;分别为node1、node2、node3&#xff0c;内存分别为4G、2G、2G&#xff0c;现存最好为&#xff08;>40G&#xff09;&#xff0c;如下&#xff1a; 2、修改主机名 分别打开三台虚拟机&#xff0c;root用户输入一下命令&#xff1a; no…

too many open files(打开的文件过多)解决办法

我们java服务报java.net.SocketException: 打开的文件过多 由于我们文件服务用的是minio 所以排查思路应该是进入文件服务器查看minio的pid ps -ef |grep minio lsof -p 11956 | wc -l 由此可以看出已经打开数为1950了 所以我们要提升打开文件数&#xff08;openfile&#…

matlab矩阵的输入

一段时间不操作感觉有些模糊&#xff1b;下面复习一下&#xff1b; 矩阵的数字之间用空格分开&#xff0c;每一行以分号结尾&#xff1b; 空格多几个也是可以识别的&#xff1b; 数字也可以用逗号隔开&#xff0c;只要一行的结尾是分号即可&#xff1b; 空格多输入几个是可…

Rust编程基础核心之所有权(上)

1.什么是所有权? Rust 的核心功能&#xff08;之一&#xff09;是 所有权&#xff08;ownership&#xff09;。虽然该功能很容易解释&#xff0c;但它对语言的其他部分有着深刻的影响。 所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制&#x…