【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链

【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链

文章目录

  • 【力扣】2619. 数组原型对象的最后一个元素——认识原型与原型链
    • 题目
    • 解决方案
      • 概述
        • 全局上下文
        • 函数上下文
        • 事件处理程序
        • 构造函数上下文
        • 类上下文
        • 显式 / 隐式绑定
        • 绑定方法和永久 this 上下文
      • 方法 1:扩展数组原型以包含 .last() 方法
        • 概述
        • 算法步骤
        • 实现
          • 实现 1:常规 if 检查
          • 实现 2:三元运算符
          • 实现 3:Nullish 合并运算符
          • 实现 4:使用数组 pop() 方法
          • 实现 5:将 Nullish 合并运算符与 Array.prototype.at() 方法结合使用
          • 实现 6:使用 Array.prototype.slice() 方法
          • 实现 7:使用默认参数
          • 实现 8:findLast 方法(适用于 ECMAScript 2022 及之后版本)
        • 复杂度分析
      • 方法 2:使用 ES6 Getters
        • 概述
        • 算法
        • 实现
        • 复杂度分析

题目

请你编写一段代码实现一个数组方法,使任何数组都可以调用 array.last() 方法,这个方法将返回数组最后一个元素。如果数组中没有元素,则返回 -1

你可以假设数组是 JSON.parse 的输出结果。

示例 1 :

输入:nums = [null, {}, 3]
输出:3
解释:调用 nums.last() 后返回最后一个元素: 3。

示例 2 :

输入:nums = []
输出:-1
解释:因为此数组没有元素,所以应该返回 -1。

提示:

  • arr 是一个有效的 JSON 数组
  • 0 <= arr.length <= 1000

解决方案

概述

这个问题引导我们进入 JavaScript 编程的一个有趣部分:向内置原型添加新功能。尽管这因为可能会有潜在风险,通常不是推荐做法,但它确实提供了对 JavaScript 灵活和动态特性的深刻理解。在这个挑战中,我们需要向Array原型添加一个last()方法。这个新方法将返回应用到它的任何数组的最后一个元素,如果数组为空则返回 -1。

在 JavaScript 中,数组是对象,所有对象都从它们的原型继承属性和方法。原型是一种用作创建其他对象基础的“模板对象”。在这个上下文中,JavaScript 的 Array 对象是一个全局对象,包含用于操作数组的方法,这个对象可以通过自定义方法或属性来扩展。

例如,让我们看一下内置的push()方法,它可以将新的项添加到数组的末尾并返回新的长度。这个方法是Array原型的一部分,对 JavaScript 中的所有数组都可用:

let arr = [1, 2, 3];console.log(Array.prototype.hasOwnProperty('push')); // 这将返回 true,因为数组有 push 方法arr.push(4); // 现在 arr 是 [1, 2, 3, 4]

现在,如果你想向所有数组添加一个新的方法,例如 last(),你可以将它添加到 Array 原型中:

Array.prototype.last = function() {// 这里放置 last 方法的实现
};

你创建的所有数组现在都可以访问这个last()方法:

let arr = [1, 2, 3];
console.log(arr.last()); // 你的实现将决定这将输出什么

扩展内置原型,如Array的原型,可能会有潜在风险,因为如果你的方法名称与未来的 JavaScript 更新或其他库的方法名称冲突,可能会导致意想不到的行为。例如,考虑尝试覆盖Array原型上的push()方法:

Array.prototype.push = function() {console.log('push 方法已被覆盖!');
};let nums = [1, 2, 3];
nums.push(4); // push 方法已被覆盖!

在这种情况下,push() 方法不再将元素附加到数组的末尾。相反,它仅仅在控制台上记录一条消息。

通常不鼓励覆盖内置方法,push() 方法广泛用于 JavaScript,改变其功能可能导致大量的错误和问题。这在处理第三方库或其他开发者的代码时尤其麻烦,因为他们期望push()方法按预期工作。

如果需要一个内置方法的修改版本,通常建议创建一个单独的方法或函数。例如,你可以开发一个新的函数,将元素附加到数组中,然后记录一条消息:

function pushAndLog(array, element) {array.push(element);console.log('元素 ' + element + ' 已添加到数组中。');
}let nums = [1, 2, 3];
pushAndLog(nums, 4); // 元素 4 已添加到数组中。
console.log(nums); // [1, 2, 3, 4]

在这个问题中,你的任务是扩展Array原型,包含一个last()方法,如果存在,它应该返回数组的最后一个元素,如果数组为空,则返回 -1。

理解这个任务涉及到理解 JavaScript 中的this关键字。在这里,JavaScript 中的this关键字的行为与其他编程语言略有不同。this 的值取决于函数调用时的上下文。在这个问题中,this 将引用当前调用last()方法的对象,它将是一个数组。

在 JavaScript 中,this 的行为与其他编程语言稍有不同。它的值由它的使用上下文决定,这对初学者来说可能会让人感到困惑。因此,了解上下文和this在不同情况下所指的对象是至关重要的。

全局上下文

在全局执行上下文中(即,在任何函数之外),this 无论在严格模式还是非严格模式下,都引用全局对象。

web浏览器中,全局对象是 window,所以 this 将引用window对象:

console.log(this); // 在浏览器上下文中会记录 "[object Window]"

Node.js环境中,全局对象不是window而是 global。因此,如果在Node.js上下文中运行相同的代码,this 将引用全局对象:

console.log(this); // 在 Node.js 上下文中会记录 "[object global]"
函数上下文

在普通函数内部,this 的值取决于函数的调用方式。如果函数在全局上下文中调用,this 在严格模式下将为 undefined,在非严格模式下将引用全局对象。

function func() {console.log(this);
}func(); // 在非严格模式的浏览器上下文中记录 "[object Window]",在严格模式下会记录 "undefined"

但是,当函数充当对象的方法时,this 将引用调用该方法的对象。这展示了this的值不绑定于函数本身,而是由函数被调用的方式和位置决定,这个概念称为执行上下文:

let obj = {prop: "Hello",func: function() {console.log(this.prop);}
}obj.func(); // 记录 "Hello"

然而,箭头函数不具有自己的 this。相反,它们从创建时的父作用域继承 this。换句话说,箭头函数内部的 this 值不由它的调用方式决定,而是由它的定义时的外部词法上下文决定:

let obj = {prop: "Hello",func: () => {console.log(this.prop);}
}obj.func(); // 记录 "undefined",因为箭头函数内部的 `this` 不绑定到 `obj`,而是绑定到其外部词法上下文

这在某些情况下可能很有用,但它也使得箭头函数不适合需要访问它们被调用的对象的其他属性的方法。

事件处理程序

在事件处理程序的上下文中,this 引用附加了事件监听器的元素,与event.currentTarget相同。

button.addEventListener('click', function() {console.log(this); // 记录按钮的整个 HTML 内容
});

重要的是注意,它不引用常用的event.target属性。让我们澄清event.currentTarget和 event.target `之间的区别。

event.currentTarget:该属性引用附加了事件处理程序(如 addEventListener)的元素。这是在事件处理程序函数的上下文中this引用的内容。

event.target:该属性引用引发事件的实际 DOM 元素。对于会冒泡的事件特别重要。如果你点击内部元素,事件将冒泡到外部元素,触发它们的事件监听器。对于这些外部元素,event.target 将是实际被点击的最内层元素,而 event.currentTarget(或 this)将是当前处理程序附加到的元素。

<div id="outer">点击我<div id="inner">或者点击我</div>
</div><script>
document.getElementById('outer').addEventListener('click', function(event) {console.log("currentTarget: ", event.currentTarget.id);console.log("this: ", this.id);console.log("target: ", event.target.id);
});
</script>

在这种情况下,如果你点击外部 div,所有三个日志都将打印 "outer",因为点击的元素(target)和处理程序附加的元素(currentTarget 或 this)是相同的。但是,如果你点击内部 div 中的 “或者点击我” 文本,event.target 将是 "inner"(因为这是你点击的元素),而 event.currentTarget(或 this)仍将是 "outer"(因为这是事件处理程序附加的元素)。

构造函数上下文

在构造函数内部,this 引用新创建的对象。但是,这里的“新创建”是什么意思呢?要理解这一点,我们需要探讨 JavaScript 中的new关键字。当你在函数调用之前使用 new 时,它告诉 JavaScript 进行四个操作:

创建一个新的空对象。这不是一个函数、数组或 null,只是一个空对象。
使函数内部的this引用这个新对象。新对象与构造函数内的this关联起来。这就是为什么Person(name)内的this.name实际上修改了新对象。
正常执行函数。它像通常情况下执行函数代码一样执行。
如果函数没有返回自己的对象,则返回新对象。如果构造函数返回一个对象,那个对象将被返回,而不是新对象。如果返回其他任何内容,将返回新对象。
new 关键字允许 JavaScript 开发者以面向对象的方式使用语言,从构造函数中创建实例,就像其他语言中的类一样。这也意味着构造函数内部的this关键字将像从基于类的语言中转换的开发者所期望的那样引用对象的新实例。

function Person(name) {// 当使用 `new` 调用时,这是一个新的、空的对象this.name = name; // `this` 现在有一个 `name` 属性// 函数结束后,将返回 `this`,因为没有其他对象被函数返回
}let john = new Person('John'); // `john` 现在是函数 `Person` 返回的对象,包含一个值为 'John' 的 `name` 属性
console.log(john.name); // 记录 "John"
类上下文

在类中,方法内部的this引用类的实例:

class ExampleClass {constructor(value) {this.value = value;}logValue() {console.log(this.value);}
}const exampleInstance = new ExampleClass('Hello');
exampleInstance.logValue(); // 记录 "Hello"
显式 / 隐式绑定

你还可以使用函数上的 .call().apply() .bind()方法来明确设置 this 的上下文:

function logThis() {console.log(this);
}const obj1 = { number: 1 };
const obj2 = { number: 2 };logThis.call(obj1); // 记录 obj1
logThis.call(obj2); // 记录 obj2const boundLogThis = logThis.bind(obj1);
boundLogThis(); // 记录 obj1
绑定方法和永久 this 上下文

JavaScript 提供了一个名为bind的内置方法,允许我们设置方法中的this值。这个方法创建一个新函数,当调用时,将其this关键字设置为提供的值,以及在调用新函数时提供的一系列参数。

bind 方法的独特之处在于它创建了一个永久绑定的this值,无论后来如何调用该函数,都不会更改this的值。下面的示例演示了bind如何提供一种锁定函数中的this值的方法,在各种情况下都很有帮助,例如在设置事件处理程序时,希望this值始终引用特定对象,或者在使用调用回调函数的库或框架时,希望在回调中控制this引用的对象。

function greet() {return `你好,我是 ${this.name}`;
}let person1 = { name: 'Alice' };
let person2 = { name: 'Bob' };// 创建一个与 `person1` 绑定的函数
let greetPerson1 = greet.bind(person1);console.log(greetPerson1()); // 你好,我是 Alice// 尝试使用 `call` 方法更改上下文;但是,它仍然使用 `person1` 作为 `this` 上下文
console.log(greetPerson1.call(person2)); // 你好,我是 Alice// 相比之下,正常函数调用允许使用 `call` 方法设置 `this` 上下文
console.log(greet.call(person2)); // 你好,我是 Bob

在 JavaScript 中,了解this 关键字的上下文对于操作和与对象交互非常重要,特别是在处理面向对象编程、事件处理程序和函数调用的某些方面。了解this的行为有助于改善代码的结构,并使其更可预测和更容易调试。此外,某些设计模式,如工厂模式和装饰器模式,大量使用 this,因此了解其行为对于有效实现这些模式至关重要。

JavaScript 中的一个关键概念是函数对象中的 this 值通常不是固定的 - 它通常是根据函数的执行上下文而确定的,而不是根据其定义的时刻。然而,也有例外情况。使用函数上的 bind()call() apply()方法时,这些方法允许你显式设置函数调用的this值,从而覆盖其默认行为。此外,JavaScript 中的箭头函数行为不同。它们不绑定自己的this值。相反,它们从定义它们的外部词法环境中捕获this的值,并且这个值在函数的整个生命周期内保持不变。这些差异使得理解和使用 JavaScript 中的this既具有挑战性又非常重要。

方法 1:扩展数组原型以包含 .last() 方法

概述

根据问题陈述,您需要增强所有数组,使其具有返回数组最后一个元素的方法 .last()。如果数组中没有元素,则应返回-1。

为此,您可以向数组原型添加一个新方法。这个新方法可以通过访问这个this[this.length-1]简单地返回数组的最后一个元素。

添加到数组原型的方法中的this关键字引用调用该方法的数组。

注意:扩展原生原型是 JavaScript 的一个强大功能,但应该谨慎使用。如果其他代码(或更高版本的 JavaScript)添加了同名的方法,则可能会导致冲突。在扩展本机原型时始终保持谨慎。

算法步骤

在名为 last 的数组原型上定义一个新方法。
在这个方法中,检查数组是否为空。如果是,返回 -1。
如果数组不为空,则返回数组的最后一个元素。最后一个元素可以通过以下方式访问:this[this.length - 1]。

实现

这种方法可以通过各种方式实现。

实现 1:常规 if 检查
Array.prototype.last = function() {if (this.length === 0) {return -1;}return this[this.length - 1];
}
实现 2:三元运算符
Array.prototype.last = function() {return this.length === 0 ? -1 : this[this.length - 1];
}

这个版本使用了一个三元运算符,代码更简洁。? 和 : 就像一个简短 if/else。

实现 3:Nullish 合并运算符
Array.prototype.last = function() {return this[this.length - 1] ?? -1;
}

此版本使用空合并运算符(??)。如果不为null undefined,则返回左侧操作数,否则返回右侧操作数。
请注意,此实现假定数组只包含数字。如果数组的最后一个元素为空或未定义,则此方法将返回-1,这可能会掩盖最后一个元素的实际值。它可能不适合包含其他数据类型的数组,在这些数组中,null undefined 是有效且不同的值。始终确保使用适合数组中包含的数据类型的方法。

实现 4:使用数组 pop() 方法
Array.prototype.last = function() {let val = this.pop();return val !== undefined ? val : -1;
}

此版本使用数组pop()方法,该方法从数组中移除最后一个元素并返回它。如果数组为空,则pop()返回 undefined,我们检查它并将其替换为 -1。需要注意的是,该操作会改变原始数组,这可能并不理想,具体取决于您的用例。

实现 5:将 Nullish 合并运算符与 Array.prototype.at() 方法结合使用
Array.prototype.last = function() {return this.at(-1) ?? -1;
}

在此版本中,我们使用ECMAScript 2021中引入的 Array.prototype.at() 方法。此方法接受一个整数值,并返回该索引处的元素,允许使用正整数和负整数。负整数从数组末尾开始计数。如果数组为空,则at(-1)将是未定义的,因此我们提供 -1 作为备用。

实现 6:使用 Array.prototype.slice() 方法
Array.prototype.last = function() {return this.length ? this.slice(-1)[0] : -1;
}

在这种方法中,我们使用Array.prototype.slice()方法。此方法提取数组的一部分并返回新数组。我们通过提供 -1 作为参数来请求最后一个元素。如果数组为空,则slice(-1)[0]将为 undefined,因此我们提供 -1 作为备用。需要注意的是,该方法不会改变原始数组,这与我们前面提到的pop()方法不同。

实现 7:使用默认参数
Array.prototype.last = function() {const [lastElement = -1] = this.slice(-1);return lastElement;
}

此实施使用带缺省值的 ES6 解构。它本质上与slice(-1)[0]版本相同,但具有不同的语法。

实现 8:findLast 方法(适用于 ECMAScript 2022 及之后版本)

此版本使用 Array.prototype.findLast(),这是为 ECMAScript 2022 建议的一种方法,用于查找数组中满足所提供测试函数的最后一个元素。在这里,我们提供了一个始终返回 true 的函数,因此它将返回最后一个元素,如果数组为空,则返回 -1。

请注意,此解决方案可能在某些情况下不起作用,因为findLast()尚未得到广泛支持。请始终查看当前的 JavaScript 文档,了解其可用性和兼容性。如果要在不支持findLast()的环境中使用 findLast(),可以创建 polyfill

if (!Array.prototype.findLast) {Array.prototype.findLast = function(predicate) {for (let i = this.length - 1; i >= 0; i--) {if (predicate(this[i], i, this)) {return this[i];}}return undefined;};
}

以下是完整的解决方案,我们还包括findLast() polyfill,根据您的环境可能不需要:

if (!Array.prototype.findLast) {Array.prototype.findLast = function(predicate) {for (let i = this.length - 1; i >= 0; i--) {if (predicate(this[i], i, this)) {return this[i];}}return undefined;};
}Array.prototype.last = function() {return this.findLast(() => true) ?? -1;
}
复杂度分析

时间复杂度:O(1)。无论数组的大小如何,我们只访问数组的最后一个元素,这是一个恒定的时间操作。
空间复杂度:O(1)。这是因为我们没有使用任何随输入数组大小而扩展的额外空间。在空间复杂性分析中不考虑数组本身,因为它是函数的输入。我们只考虑该函数使用的任何额外空间。

需要注意的是,就时间和空间复杂性而言,将方法添加到阵列原型不会影响其他阵列,因为它不会为每个阵列重复该方法。相反,该方法驻留在原型中,并且可以由所有数组访问。这使得它成为一种高度节省空间的操作。

方法 2:使用 ES6 Getters

概述

在 JavaScript 中,getter 是获取特定属性的值的方法。在这里,我们将为最后一个属性创建一个 getter

算法
  1. 通过为最后一个属性定义一个 getter来增强数组原型。
  2. getter 函数将返回另一个函数,该函数返回数组的最后一个元素,如果数组为空,则返回 -1。
实现
Object.defineProperty(Array.prototype, 'last', {get: function() {return () => this.length ? this[this.length - 1] : -1;}
});

当你定义一个getter时,你实际上是把 last 当作一个属性而不是一个函数。因此,它是通过array.last而不是array.last()访问的。如果您将数组的最后一个元素视为该数组的属性,而不是函数的结果,则这种观点在语义上会更清晰。Getter可以提供一种更精炼的、类似于属性的语法,以增强可读性,特别是当您要实现的操作不需要任何参数并且在概念上是一个属性时。

此外,当在大量使用gettersetter的代码库中工作时,使用getter可以提高一致性。然而,在您的特定问题的上下文中注意到这一点很重要:因为getter被视为一个属性,所以需要一个嵌套的函数来通过在线判断。这个附加层提供了一种与属性交互的方法,使评测机能够实现预期的适当功能。

复杂度分析

时间复杂度:O(1)。在 JavaScript 中,访问数组中特定索引处的元素是一个恒定的时间操作。

空间复杂度:O(1)。不会使用额外的空间。

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

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

相关文章

ubuntu终端指令集 shell编程基础(一)

磁盘指令 连接与查看&#xff1a;磁盘与 Ubuntu 有两种连接方式&#xff1b;使用ls /dev/sd*查看是否连接成功&#xff0c;通过df系列指令查看磁盘使用信息。若 U 盘已挂载&#xff0c;相关操作可能失败&#xff0c;需用umount取消挂载。磁盘操作&#xff1a;使用sudo fdisk 磁…

基于Spark的电商供应链系统的设计与实现

目录 1.研究背景与意义 2、国内外研究现状 3、相关理论与技术 &#xff08;一&#xff09;分布式计算系统Spark &#xff08;二&#xff09;数据仓库Hive &#xff08;三&#xff09;读取服务器本地磁盘的日志数据Flume &#xff08;四&#xff09;分布式消息队列Kafka …

使用TortoiseGit配合BeyondCompare实现在Git仓库中比对二进制文件

使用TortoiseGit的比对工具可以直接右键&#xff0c;点击选择比对和上一版本的变化差异&#xff1a; 但是TortoiseGit只能支持比对纯文本文件的变化差异&#xff0c;如果尝试比对二进制文件&#xff0c;会提示这不是一个有效的文本文件&#xff1a; BeyondCompare可以比对二进制…

BladeX框架接口请求跨域

前端使用代理请求接口&#xff0c;接口可以正常访问。如果换全路径请求就跨域。 除了后端要配置跨域 还需要修改配置文件对OPTIONS请求的限制

Vue.js响应式基础

响应式基础​ API 参考 本页和后面很多页面中都分别包含了选项式 API 和组合式 API 的示例代码。现在你选择的是 组合式 API。你可以使用左侧侧边栏顶部的“API 风格偏好”开关在 API 风格之间切换。 声明响应式状态​ ref()​ 在组合式 API 中,推荐使用 ref() 函数来声明…

选开源CMS建站系统时,插件越多越好吗?

在选择开源CMS建站系统时&#xff0c;插件数量并不是唯一的衡量标准&#xff0c;更不能简单地说“插件越多就越好”&#xff0c;还是需要综合评估来考虑选择结果&#xff0c;以下是有关选择开源CMS系统时对插件数量的考量。 插件数量的优势插件数量可能带来的问题功能丰富性&a…

在VSCode中使用MarsCode AI最新版本详解

如何在VSCode中使用MarsCode AI&#xff1a;最新版本详解与使用场景 在当今快速发展的软件开发领域&#xff0c;人工智能&#xff08;AI&#xff09;技术的应用已经变得越来越普遍。ByteDance推出的MarsCode AI是一款强大的AI编程助手&#xff0c;旨在帮助开发者更高效地编写代…

mac修改docker的daemon.json 镜像文件

1、找到daemon.json文件的位置 docker info 可以看出位置在&#xff1a; /Users/spuer/.docker 2. 进入daemon.json 所在的目录&#xff1a; cd /Users/spuer/.docker3. 查看daemon.json的内容&#xff1a; more daemon.json可以看出&#xff0c;没有配置registry-mirrors&…

5.10 P-Tuning v2:多层级提示编码的微调革新

P-Tuning v2:多层级提示编码的微调革新 一、技术架构解析 #mermaid-svg-4Wy6vkXZi67hY9PZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4Wy6vkXZi67hY9PZ .error-icon{fill:#552222;}#mermaid-svg-4Wy6vkXZi67h…

Eclipse 编译项目指南

Eclipse 编译项目指南 引言 Eclipse 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;广泛用于Java、C/C、Python等多种编程语言的开发。在Eclipse中编译项目是进行软件开发的基础步骤。本文将详细介绍如何在Eclipse中编译项目&#xff0c;包括项目设置…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…

【缓存】缓存雪崩与缓存穿透:高并发系统的隐形杀手

缓存雪崩与缓存穿透&#xff1a;高并发系统的隐形杀手 在高并发系统中&#xff0c;缓存是提升性能的重要手段。然而&#xff0c;缓存使用不当也会带来一系列问题&#xff0c;其中最常见的就是缓存雪崩和缓存穿透。这两个问题如果不加以解决&#xff0c;可能会导致系统崩溃&…

additional-spring-configuration-metadata.json实现springboot自定义提示

在配置additional-spring-configuration-metadata.json文件后&#xff0c;在开发人员的IDE工具使用个人编写的配置读取很有效的在application.properties或application.yml文件下完成提示。 配置元数据文件位于jar下面。 META-INF/spring-configuration-metadata.json它们使用简…

Dify在Ubuntu20.04系统的部署

文章目录 一、dify 介绍1.核心功能优势2.应用场景 二、dify 安装(docker方式)1.代码库下载2.配置文件修改3.启动docker 容器 三、遇到问题与解决1.使用sudo docker compose up -d报错2.使用service docker start报错 一、dify 介绍 Dify 是一款开源的大语言模型&#xff08;LL…

kafka-关于ISR-概述

一. 什么是ISR &#xff1f; Kafka 中通常每个分区都有多个副本&#xff0c;其中一个副本被选举为 Leader&#xff0c;其他副本为 Follower。ISR 是指与 Leader 副本保持同步的 Follower 副本集合。ISR 机制的核心是确保数据在多个副本之间的一致性和可靠性&#xff0c;同时在 …

1_安装JDK和Hadoop

一、解压jdk和hadoop安装包 下载 通过百度网盘分享的文件&#xff1a;jdk-8u172-linux-x64.tar.gz 链接&#xff1a;https://pan.baidu.com/s/1VjhdpfyqdC7ivEBIjTn8tA 提取码&#xff1a;iz25 二、配置环境变量 vi /root/.bashrc添加 #set java environment export JAVA_H…

.Net 9下使用Tensorflow.net---DNN_Keras

.Net 9下使用Tensorflow.net---DNN_Keras 1、创建应用&#xff0c;导入依赖2、编写代码1&#xff09;添加引用2&#xff09;创建基础对象3&#xff09;初始化数据集4&#xff09;重点步骤&#xff1a;创建 Keras下的DNN模型5&#xff09;训练模型得到评估值6&#xff09;结果输…

边缘计算收益低的三大指标

边缘计算收益低的三大指标主要包括以下方面&#xff1a; 1. 资源贡献不足&#xff1a; 边缘计算的收益通常基于所提供的带宽、存储和计算资源来计算。如果设备的网络带宽有限、在线时间短或提供的存储容量较小&#xff0c;可能无法满足平台设定的最低贡献标准&#xff0c;从而导…

重大更新!锂电池剩余寿命预测新增 CALCE 数据集

往期精彩内容&#xff1a; 单步预测-风速预测模型代码全家桶-CSDN博客 半天入门&#xff01;锂电池剩余寿命预测&#xff08;Python&#xff09;-CSDN博客 超强预测模型&#xff1a;二次分解-组合预测-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;BiLSTM-Attention预测模型…

开发一个交易所需要哪些技术?

在当今数字化时代&#xff0c;交易所作为金融市场的重要组成部分&#xff0c;其技术架构和功能的复杂性日益增加。无论是传统的股票、期货交易所&#xff0c;还是新兴的数字货币交易所&#xff0c;开发一个高效、安全、可靠的交易所系统都是一个复杂而系统的工程。本文将深入探…