前端代码分析题(选择题、分析题)——this指向、原型链分析

  this指向

  • 普通函数this 的指向由调用方式决定,可以是全局对象、调用该函数的对象,或者显式指定的对象。
  • 箭头函数this 的指向在定义时确定,始终继承自外层函数作用域的 this,不会被调用方式影响。
var obj = {print: function() {var test = () =>  {console.log("yupi", this);}test();},rap: {doRap:() =>  {console.log(this);}}
}
var copyPrint = obj.print;
copyPrint();
obj.print();
obj.rap.doRap();//直接在 obj.rap 对象中定义,并没有包裹在任何外层函数中,会继承全局作用域的 this

var obj = {name: "yupi",func: function() {var self = this;console.log(this.name);console.log(self.name);(function() {console.log(this.name);console.log(self.name);}());}
};
obj.func();
//输出
yupi
yupi
undefined
yupi
var num = 2;
function print() {console.log(this.num);
}var obj = {num: 4,test1: print,test2: function () {print();},
};
obj.test1();
obj.test2();
var foo = obj.test1;
foo();
//输出结果
4
2
2
function test(num){this.value = num;return this;
}
var value = test(5);
var obj = test(6);console.log(value.value);
console.log(obj.value);
//输出结果
**undefined**6
function test(value) {this.num = value;
}var obj1 = {test: test,
};
obj1.test(1);
console.log(obj1.num);var obj2 = {};
obj1.test.call(obj2, 2);
console.log(obj2.num);var foo = new obj1.test(3);
console.log(obj1.num);
console.log(foo.num);//输出结果
1213function test(value){this.num = value;
}var obj1 = {};
var testBind = test.bind(obj1);
testBind(1);
console.log(obj1.num);var foo = new testBind(2);
console.log(obj1.num);
console.log(foo.num);
//输出结果
1
1
2

 优先级:new 绑定>显示绑定( apply/call/bind )>

               隐式绑定( obj.foo())>默认绑定( 独立函数调用 )

立即执行函数表达式 IIFE

什么是 IIFE(立即执行函数表达式)?

IIFE(Immediately Invoked Function Expression)是一种 JavaScript 编程模式,它使一个函数在定义时立即执行。IIFE 的格式通常如下所示:

  • (function() { // 函数体 })();
  • (() => { // 函数体 })();

立即执行函数的执行机制

  • 在上面的代码中,IIFE 是通过 (function() {...})() 形式定义的。它是一个 函数表达式并且在定义后立即执行。也就是说,IIFE 在 初始化时 执行一次,并且其作用域内的代码也只会执行一次。

对应到您的代码中的 IIFE

在您提供的代码中,IIFE 部分是:

window.num = 2;
var obj = {num: 4,test: (function(){console.log(this);this.num *= 6;return function(){console.log(this);this.num *= 8;}})()
}
var test = obj.test;
test();
obj.test();
console.log(obj.num);
console.log(window.num);//输出结果
Window 对象
Window 对象
{num: 4, test: ƒ} // obj 对象
32
96
  • 这段代码中的 IIFE 会在 定义 test 属性时立即执行console.log(this) 在 IIFE 执行时打印的是 全局对象 window,然后 this.num *= 6; 会修改 window.num 的值。
  • 该 IIFE 返回了一个匿名函数,这个匿名函数会赋值给 obj.test

总结:IIFE 是立即执行的,因此它的代码块只会执行一次,并且返回的函数会被赋给 obj.test。这个返回的函数之后会被调用,但 IIFE 本身只在定义时执行一次。

解释执行顺序

  1. 在执行到 var obj = { ... } 这一行时,IIFE 被立即执行:

    • console.log(this) 打印 window 对象。
    • this.num *= 6 修改了 window.num2 * 6 = 12)。
    • 然后,IIFE 返回一个匿名函数,该匿名函数被赋给 obj.test
  2. 之后,obj.test 就是 IIFE 返回的匿名函数,该函数在后面的调用中会执行:

    • 第一次调用 test() 时,this 指向 windowwindow.num 被修改为 96
    • 第二次调用 obj.test() 时,this 指向 objobj.num 被修改为 32

IIFE 的核心特性:

  • 只执行一次:IIFE 在定义时立即执行,并且它的作用域只会被创建一次。
  • 返回值:IIFE 可以返回任何值,在您的代码中,它返回了一个函数,这个函数被赋值给 obj.test
  • 默认this指向windows(非严格模式) 

⭐⭐进阶题

var length = 10;
function func() {console.log(this.length);
}var obj = {length: 5,test: function(func) {console.log(this.length)//5func();//相当于window.func(),被window对象调用this指向window对象//func.call(this)//这样修改this指向,this就是指向objarguments[0]();//类似于func(),但是调用方式不同,this不同,含义大不相同,这个可以看作函数被arguments对象调用,而arguments对象本省就有length属性,即为参数的个数,所以this.length输出为2(参数个数)}
};
obj.test(func, 1);

 输出为

  • 10
  • 2

刚看到一道JS面试题,关于this指向的问题

var length = 10;
function func() {
  console.log(this.length);
}

var obj = {
  length: 5,
  test: function(func) {
    console.log(this.length)//5
    func();//相当于window.func(),被window对象调用this指向window对象
    //func.call(this)//修改this指向,this就是指向obj
    arguments[0]();//类似于func(),但是调用方式不同,this不同,含义大不相同,这个可以看作函数被arguments对象调用,而arguments对象本身就有length属性,即为参数的个数,所以this.length输出为2(参数个数)
  }
};
obj.test(func, 1);
 

⭐扩展知识:词法作用域

在 JavaScript 中,**词法作用域(Lexical Scope)**是指函数的作用域(即变量的可访问范围)是根据函数定义的位置来确定的而不是根据函数调用的位置来决定的。这意味着 JavaScript 中的作用域链是静态的,它依赖于代码在编写时的结构。

1. 什么是词法作用域?

词法作用域(也叫静态作用域)是指一个函数在定义时决定了它能访问哪些变量。即,函数访问外部变量的规则与它们的定义位置有关,而与函数如何被调用时的调用位置无关。

- **函数的作用域链**是由函数定义时外部的作用域链决定的,而不是调用时的执行环境。

 2. 如何理解词法作用域?

- 在 JavaScript 中,**变量的作用域**决定了变量的可访问范围。
- **函数的作用域**决定了函数内部可以访问哪些变量。

当你定义一个函数时,它会记住外部的作用域链,并且无论何时调用它,函数总是能访问到它定义时可访问的那些变量。

举个简单的例子:

function outer() {var outerVar = 'I am from outer!';function inner() {console.log(outerVar); // 访问外部函数的变量}inner(); // 调用 inner 函数
}outer(); // 输出 "I am from outer!"

在这个例子中:
- `inner` 函数定义在 `outer` 函数内部,因此它可以访问 `outer` 函数中定义的变量 `outerVar`。
- 这就是**词法作用域**,因为 `inner` 函数的作用域是由它定义的位置(即在 `outer` 函数内部)决定的,而不是由它调用的位置决定的。

 3. 词法作用域与 `this`

在 JavaScript 中,`this` 的指向和作用域是两个不同的概念。虽然 `this` 和作用域链都与上下文相关,但它们的行为方式不同。理解词法作用域有助于理解 **箭头函数** 中 `this` 的行为。

普通函数和箭头函数的区别

- **普通函数**中的 `this` 是根据**调用时的上下文**来确定的。
- **箭头函数**中的 `this` 是在**定义时继承**外层作用域的 `this`,这就是箭头函数不同于普通函数的一大特点。

4. 箭头函数中的 `this`

箭头函数中的 `this` 绑定规则与普通函数不同。普通函数的 `this` 是动态绑定的,而箭头函数的 `this` 是静态的,指向定义时外层的 `this`。

例子:

function Outer() {this.name = 'Outer';// 普通函数this.printName = function() {console.log(this.name); // this 指向调用它的对象};// 箭头函数this.arrowPrintName = () => {console.log(this.name); // this 会继承自 Outer 函数的 this};
}var obj = new Outer();
obj.printName();      // 输出 'Outer',this 指向 obj
obj.arrowPrintName(); // 输出 'Outer',this 仍然指向 Outer 函数的 this

在上面的例子中:
- `printName` 是普通函数,它的 `this` 会根据调用时的上下文来确定。
- `arrowPrintName` 是箭头函数,它的 `this` 会继承外层 `Outer` 函数中的 `this`,即指向创建它时的 `this`,而不受 `obj` 的影响。

5. 作用域链

每个 JavaScript 函数都会创建一个作用域链,用于查找变量。当一个函数内部访问变量时,JavaScript 会沿着作用域链查找这个变量。如果函数内部没有定义某个变量,JavaScript 会查找函数外部的作用域,直到全局作用域为止

- **作用域链**是由多个作用域组成的,最里层的是当前函数的作用域,外层是它的外部作用域,一直到全局作用域。```javascript

function outer() {var outerVar = 'outer';function inner() {var innerVar = 'inner';console.log(outerVar); // 在内层函数中访问外层函数的变量}inner();
}outer(); // 输出 'outer'

在上面的例子中:
- `inner` 函数在 `outer` 函数内部定义,它访问了外层的 `outerVar`。这是因为 `inner` 函数的作用域链包含了 `outer` 函数的作用域。

6. 词法作用域和闭包

https://gisjing.blog.csdn.net/article/details/143593869?spm=1001.2014.3001.5502&ydreferer=aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU1MDQ5NjU1P3R5cGU9YmxvZw%3D%3D

闭包是指函数能够"记住"并访问它定义时的作用域,即使这个函数在定义时的作用域已经执行完毕。`

function outer() {var outerVar = 'outer';function inner() {console.log(outerVar); // 访问 outer 的变量}return inner;
}var closure = outer(); // 返回 inner 函数
closure(); // 输出 'outer'

在这个例子中,`inner` 函数是一个闭包,因为它记住了定义时的作用域(即 `outer` 函数的作用域),即使在外部调用时,`outerVar` 仍然是可以访问的。

7. 词法作用域与变量提升

JavaScript 中的**变量提升**(hoisting)指的是在执行代码之前,所有的 `var` 声明会被提升到作用域的顶部,但它们的赋值并不会被提升。```javascript

function example() {console.log(myVar); // undefined,因为声明被提升了,但赋值在后面var myVar = 10;
}example();

在这个例子中,`myVar` 的声明被提升了,但是它的值 `10` 是在执行到那行代码时才赋值的。所以输出是 `undefined`,而不是 `10`。

♥8. 总结

- **词法作用域**决定了变量和函数的可访问范围,它是由函数的定义位置而不是调用位置来确定的。
- **作用域链**:函数查找变量时,会沿着作用域链从内到外查找,直到全局作用域。
- **箭头函数的 `this`**:箭头函数的 `this` 不是根据调用方式决定的,而是继承自它定义时的外层作用域。
- **闭包**:函数可以记住并访问它定义时的作用域,即使外层函数已经执行完毕。

原型链

Javascript原型链-CSDN博客

  • boy.prototype->undefined
  • null.__proto__->TypeError

⭐⭐⭐JS中new关键字实例化对象,具体做了什么⭐⭐⭐

  1. 创建一个空对象

    • new关键字被调用时,JavaScript引擎首先会创建一个空白的对象。这个对象没有任何属性和方法,但它会继承自构造函数的prototype属性所向的原型对指象。
  2. 设置原型链

    • 接下来,JavaScript引擎会将新创建的对象的内部原型(__proto__)设置为构造函数的prototype属性。这一步是原型链继承的关键,它允许新对象访问构造函数原型中定义的方法和属性。
  3. 绑定this并执行构造函数

    • 然后,JavaScript引擎会将构造函数作为普通函数调用,但此时this关键字的值会被设置为新创建的对象。这意味着在构造函数内部,你可以通过this来引用新对象,并向其添加属性和方法。
    • 构造函数中的代码会执行,可能会初始化对象的属性、调用其他方法等。
  4. 返回新对象

    • 最后,如果构造函数没有显式地返回一个对象(即返回的不是一个非原始值),那么new表达式会默认返回新创建的对象。如果构造函数返回了一个对象,那么new表达式会返回这个对象,而不是新创建的那个空对象。需要注意的是,这种情况下,原型链的链接会失去作用,因为返回的对象与构造函数的原型没有直接联系。
  • 创建一个新的空对象,并将这个对象的原型设置为函数的 prototype 属性。
  • 绑定函数内部的 this 到这个新对象,即在函数内 this 指向新创建的对象
  • 执行函数,将函数内部的代码与新对象的作用域绑定。
  • 返回值处理:如果函数返回一个非 null 的对象,则 new 表达式会返回这个对象;否则,它会返回创建的对象。

实现继承的几种方式

1.原型链继承

子类prototype指向父类实例。缺:所有实例共享父类属性,修改子类实例会影响到所有实例 

function Coder() {this.type = 'Coder';
}Coder.prototype.rap = function () {console.log('yo yo yo');
};function Yupi(name) {this.name = name;this.age = 18;
}// 原型链继承
Yupi.prototype = new Coder();
Yupi.prototype.constructor = Yupi;// 测试
const yupi = new Yupi('Yupi');
console.log(yupi.type); // 输出: Coder
yupi.rap(); // 输出: yo yo yo
2.构造函数

子类构造函数调用父类构造函数实现,可继承父类属性,但不能继承父类原型方法

function Coder() {this.type = 'Coder';
}Coder.prototype.rap = function () {console.log('yo yo yo');
};function Yupi(name) {Coder.call(this); // 调用父类构造函数this.name = name;this.age = 18;
}// 测试
const yupi = new Yupi('Yupi');
console.log(yupi.type); // 输出: Coder
// yupi.rap(); // 这行代码会报错,因为构造函数继承无法继承原型链上的方法
3.组合继承(组合1和2)

开销较大,两次调用父类构造函数

function Coder() {this.type = 'Coder';
}Coder.prototype.rap = function () {console.log('yo yo yo');
};function Yupi(name) {Coder.call(this); // 调用父类构造函数this.name = name;this.age = 18;
}// 组合继承
Yupi.prototype = new Coder();
Yupi.prototype.constructor = Yupi;// 测试
const yupi = new Yupi('Yupi');
console.log(yupi.type); // 输出: Coder
yupi.rap(); // 输出: yo yo yo
4.寄生组合(推荐⭐)

避免组合继承两次调用父类构造函数

function Coder() {this.type = 'Coder';
}Coder.prototype.rap = function () {console.log('yo yo yo');
};function Yupi(name) {Coder.call(this); // 调用父类构造函数this.name = name;this.age = 18;
}// 寄生组合继承
Yupi.prototype = Object.create(Coder.prototype);
Yupi.prototype.constructor = Yupi;// 测试
const yupi = new Yupi('Yupi');
console.log(yupi.type); // 输出: Coder
yupi.rap(); // 输出: yo yo yo
5.ES6 class语法
class Coder {constructor() {this.type = 'Coder';}rap() {console.log('yo yo yo');}
}class Yupi extends Coder {constructor(name) {super(); // 调用父类构造函数this.name = name;this.age = 18;}
}// 测试
const yupi = new Yupi('Yupi');
console.log(yupi.type); // 输出: Coder
yupi.rap(); // 输出: yo yo yo

**基础补充**

function Father(){this.a=11;this.b=[1,2,this.a];this.print=function(){console.log(this.a,this.b,typeof(this.b[2]));}
}
const father=new Father();
father.print();
father.a=13;
father.print();
//输出
//11 [1,2,11] number
//13 [1,2,11] number
//b中的this.a是复制a的值,类型为原始类型

自己身上没有才去原型链上找

function Obj1() {}
function Obj2(value) {this.value = value;
}
function Obj3(value) {if (value) {this.value = value;}
}Obj1.prototype.value = 1;
Obj2.prototype.value = 1;
Obj3.prototype.value = 1;console.log(new Obj1().value);
console.log(new Obj2().value);
console.log(new Obj3(666).value);1
undefined
666

函数原型与对象原型 

var FuncObj = function () {};
Object.prototype.foo = function () {console.log('foo');
};
Function.prototype.bar = function () {console.log('bar');
};
FuncObj.foo();
FuncObj.bar();var f = new FuncObj();
f.foo();
f.bar();//输出结果
foo
bar
foo
TypeError: f.bar is not a function

⭐⭐**进阶题1**⭐⭐

前端分享一经典有难度易错的Javascript题目

function Father() {this.a = 1;this.b = [1, 2, this.a];this.c = { field: 5 };this.print = function () {console.log(this.a, this.b, this.c.field);};
}function Son() {this.a = 2;this.update = function () {this.b.push(this.a);this.a = this.b.length;this.c.field = this.a++;};
}Son.prototype = new Father();
var father = new Father();
var son1 = new Son();
var son2 = new Son();
son1.a = 11;
son2.a = 12;
father.print();
son1.print();
son2.print();
son1.update();
son2.update();
father.print();
son1.print();
son2.print();
1 [ 1, 2, 1 ] 5
11 [ 1, 2, 1 ] 5
12 [ 1, 2, 1 ] 5
1 [ 1, 2, 1 ] 5
5 [ 1, 2, 1, 11, 12 ] 5
6 [ 1, 2, 1, 11, 12 ] 5

代码执行过程及结果分析

  1. 定义 FatherSon 构造函数

    • Father 构造函数初始化属性 a(值为1),b(值为 [1, 2, this.a],即 [1, 2, 1]),c(对象 { field: 5 }),以及 print 方法。
    • Son 构造函数初始化属性 a(值为2)和 update 方法。Son.prototype = new Father(); 使得 Son 的实例对象能够继承 Father 中定义的 abcprint
  2. 实例化对象

    • var father = new Father(); 创建了一个 Father 的实例 father,其属性值为 a = 1b = [1, 2, 1]c = { field: 5 }
    • var son1 = new Son();var son2 = new Son(); 创建了两个 Son 的实例 son1son2。由于继承了 Father,它们各自拥有独立的 a 值(由 Son 构造函数初始化为2)和独立的 bc 的引用(通过继承 Father 的实例化对象)。因此,son1son2 的初始属性为 a = 2b = [1, 2, 1]c = { field: 5 }
  3. 修改属性

    • son1.a = 11;son1a 属性设置为11。
    • son2.a = 12;son2a 属性设置为12。
  4. 调用 print 方法

    • father.print(); 输出 father 的属性:a = 1b = [1, 2, 1]c.field = 5。结果为:1 [1, 2, 1] 5
    • son1.print(); 输出 son1 的属性:a = 11b = [1, 2, 1]c.field = 5。结果为:11 [1, 2, 1] 5
    • son2.print(); 输出 son2 的属性:a = 12b = [1, 2, 1]c.field = 5。结果为:12 [1, 2, 1] 5
  5. 调用 update 方法

    • son1.update(); 执行以下操作:

      • this.b.push(this.a);son1.a(即11)添加到 b 中,因此 son1.b 变为 [1, 2, 1, 11]
      • this.a = this.b.length;son1.a 更新为 b 的长度(4)。
      • this.c.field = this.a++;son1.c.field 设置为 a(即4),然后自增 a 为5。
      • 更新后,son1.a = 5son1.b = [1, 2, 1, 11]son1.c = { field: 4 }
    • son2.update(); 执行以下操作:

      • this.b.push(this.a);son2.a(即12)添加到 b 中,因此 son2.b 变为 [1, 2, 1, 11, 12]
      • this.a = this.b.length;son2.a 更新为 b 的长度(5)。
      • this.c.field = this.a++;son2.c.field 设置为 a(即5),然后自增 a 为6。
      • 更新后,son2.a = 6son2.b = [1, 2, 1, 11, 12]son2.c = { field: 5 }
  6. 再次调用 print 方法

    • father.print(); 仍然输出原始的 father 属性:a = 1b = [1, 2, 1]c.field = 5。结果为:1 [1, 2, 1] 5
    • son1.print(); 输出更新后的 son1 属性:a = 5b = [1, 2, 1, 11, 12]c.field = 5。结果为:5 [1, 2, 1, 11, 12] 5
    • son2.print(); 输出更新后的 son2 属性:a = 6b = [1, 2, 1, 11, 12]c.field = 5。结果为:6 [1, 2, 1, 11, 12] 5

在这个示例中,son1son2 实例共享了 Father 原型中的 bc 引用,因此 update 方法对 b 数组的修改会影响到所有 Son 实例

⭐⭐**进阶题2**⭐⭐

function FuncObj() {print = function () {console.log(1);};//重新给print变量赋值return this;//返回了this
}FuncObj.print = function () {console.log(2);
};FuncObj.prototype.print = function () {console.log(3);
};var print = function () {console.log(4);
};function print() {console.log(5);
}FuncObj.print();
print();
FuncObj().print();//相当于调用windows.print()
print();
new FuncObj.print();//调用静态方法FuncObj.print()
new FuncObj().print();//构造方法FuncObj()实例化对象,对象的print()没找到->原型上找
new new FuncObj().print();//构造方法FuncObj()实例化对象找原型上print(),再调用此方法-》仍输出3
//输出结果
2
4(变量提升,var与函数声明同名时,var声明会在提升阶段覆盖函数声明)
1
1
2
3
3
调用和输出分析
1. FuncObj.print();
  • 这是调用 FuncObj 的静态方法 print
  • 输出:2
2. print();
  • 此时 print 是定义为 var print = function () { console.log(4); }
  • 输出:4
3. FuncObj().print();
  • 调用 FuncObj(),由于 FuncObj 返回 this(即全局对象 window),它会将 print 重新定义为 function () { console.log(1); },覆盖了全局的 print
  • 然后调用 print(),即 function () { console.log(1); }
  • 输出:1
4. print();
  • 上一步中 print 被重新赋值为 function () { console.log(1); }
  • 输出:1
5. new FuncObj.print();
  • new FuncObj.print() 调用的是 FuncObj 的静态方法 print,而非实例化 FuncObjnew 操作符在此上下文中无意义,但会正常执行【简单来讲就是不涉及原型链和this使用】
  • 输出:2

为什么 new 在这里无意义

在这个过程中,new 仅仅用来调用 FuncObj.print,并没有创建 FuncObj 的实例。它的主要效果仅是创建一个与 FuncObj 无关的空对象,作为 FuncObj.printthis,并执行了 FuncObj.print 函数体。

  • new 在此无意义,因为 FuncObj.print 并不使用 this,返回的空对象也没有用。
  • 效果等同于 FuncObj.print(),唯一的区别是返回一个空对象,但对 FuncObj.print 的执行没有任何影响。
6. new FuncObj().print();
  • new FuncObj() 创建了一个 FuncObj 的实例,该实例继承了 FuncObj.prototype.print 方法。
  • 调用实例的 print 方法,即 FuncObj.prototype.print
  • 输出:3
7. new new FuncObj().print();
  • new FuncObj() 创建了一个 FuncObj 的实例,且 new FuncObj().print 返回 FuncObj.prototype.print 方法。
  • 最外层 new 调用 FuncObj.prototype.print 方法,仍然输出 3
  • 输出:3

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

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

相关文章

【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)

Git仓库 https://gitee.com/Lin_DH/system 介绍 使用 Thymeleaf 写的页面&#xff0c;将&#xff08;txt、jpg、png&#xff09;格式文件上传到 MySQL 数据库中。 依赖 pom.xml <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><depende…

手动搭建 Ghost 博客

操作场景 Ghost 是使用 Node.js 语言编写的开源博客平台&#xff0c;您可使用 Ghost 快速搭建博客&#xff0c;简化在线出版过程。本文档介绍如何在腾讯云云服务器&#xff08;CVM&#xff09;上手动搭建 Ghost 个人网站。 进行 Ghost 网站搭建&#xff0c;您需要熟悉 Linux …

类型转换指令及方法调用与返回指令

我的后端学习大纲 JVM学习大纲 4.类型转换指令&#xff1a; 类型转换指令说明 ①类型转换指令可以将两种不同的数值类型进行相互转换。 这些转换操作一般用于实现用户代码中的显式类型转换操作&#xff0c;或者用来处理字节码指令集中数据类型相关指令无法与数据类型一一对应的…

【LLM Agents体验 3】利用Open-WebUI+Ollama本地部署Qwen2.5:7B大模型的安装指南

Open WebUI是一种基于 Web 的用户界面&#xff0c;用于管理和操作各种本地和云端的人工智能模型。它提供了一个直观的图形化界面&#xff0c;使用户可以方便地加载、配置、运行和监控各种 AI 模型&#xff0c;而无需编写代码或使用命令行界面。 Open-WebUI 是一款功能强大且易于…

动态规划 —— dp 问题-买卖股票的最佳时机IV

前言 在开始之前先说一下本题与 买卖股票的最佳时机Ill 的解法很相似&#xff0c;也可以去参考lll 动态规划 —— dp 问题-买卖股票的最佳时机III-CSDN博客https://blog.csdn.net/hedhjd/article/details/143671809?spm1001.2014.3001.5501 1. 买卖股票的最佳时机IV 题目链接&…

软件测试学习记录 Day1

根据黑马程序员最新版的软件测试课程所做的笔记&#xff0c;需要原件后台私信&#xff1a; 练习提取测试点&#xff1a; 博主的答案&#xff0c;有不一样看法的可评论区讨论&#xff1a;

Kafka 快速入门(一)

1.1安装部署 1.1.1 集群规划 bigdata01bigdata02bigdata03zookeeperzookeeperzookeeperkafkakafkakafka 1.1.2 集群部署 官方下载地址&#xff1a;http://kafka.apache.org/downloads.html 检查三台虚拟机的zk是否启动&#xff1a;zkServer.sh start 默认启动方式 1)解压…

wordpress实用功能A5资源网同款 隐藏下载框 支付框 需要登录才能查看隐藏的内容

实用功能 隐藏下载框 支付框 需要登录才能查看隐藏的内容, 个人网站防天朝申查实测有效 。 登录前&#xff0c;未登录&#xff1a; 登录后&#xff0c;已登录&#xff1a; 功能说明 该代码段的主要功能是隐藏支付框并为未 登录用户显示一条提示信息&#xff0c;告知他们需要…

SQL HAVING子句

SQL 是一种基于“面向集合”思想设计的语言。HAVING 子句是一个聚合函数&#xff0c;用于过滤分组结果。 1 实践 1.1 缺失的编号 图 连续编号记录表t_seq_record 需求&#xff1a;判断seq 列编号是否有缺失。 SELECT 存在缺失的编号 AS res FROM t_seq_record HAVING COUN…

TCP可靠连接的建立和释放,TCP报文段的格式,UDP简单介绍

TCP连接的建立&#xff08;三次握手&#xff09; 建立连接使用的三报文 SYN 报文仅用于 TCP 三次握手中的第一个和第二个报文&#xff08;SYN 和 SYN-ACK&#xff09;&#xff0c;用于初始化连接的序列号。数据传输阶段不再使用 SYN 标志。 SYN 报文通常只携带连接请求信息&a…

【量化交易笔记】14.模拟盘效果

说明 距离上一篇的量化文章有一段时间&#xff0c;应小伙伴要求&#xff0c;继续写下去&#xff0c;我思考了一下&#xff0c;内容有很多&#xff0c;绝大多数是研究的过程&#xff0c;并且走的是弯路&#xff0c;分享了怕影响大伙&#xff0c;之前因为行情不好&#xff0c;研…

FPGA实现以太网(二)、初始化和配置PHY芯片

系列文章目录 FPGA实现以太网&#xff08;一&#xff09;、以太网基础知识 文章目录 系列文章目录一、MDIO协议介绍二、PHY芯片管脚以及结构框图三、MDIO帧时序介绍3.1 MDIO帧格式3.2 MDIO写时序3.3 MDIO读时序 四、PHY芯片常用寄存器描述4.1 基本模式控制寄存器&#xff08;0…

【韩老师零基础30天学会Java 】06章 数组、排序和查找

第六章 数组、排序和查找 1. 数组&#x1f6a9;&#x1f6a9; 数组介绍&#xff1a; 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。即:数组就是一组数据。 示例&#xff1a; double [] hens{3,5,1,3,4,2,50,7.8,88.8,1.1,5}; double totalWe…

基于Zynq FPGA对雷龙SD NAND的测试

文章目录 SD NAND特征SD卡简介1.2 SD卡块图 SD卡样片Zynq测试平台搭建测试流程SOC搭建软件搭建 测试结果总结 SD NAND特征 SD卡简介 雷龙的SD NAND有很多型号&#xff0c;在测试中使用的是CSNP4GCR01-AMW与CSNP32GCR01-AOW。芯片是基于 NAND FLASH 和 SD控制器实现的SD卡。具…

在Linux上部署(MySQL Redis Elasticsearch等)各类软件

实战章节&#xff1a;在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c…

电脑不显示wifi列表怎么办?电脑不显示WiF列表的解决办法

有用户会遇到电脑总是不显示wifi列表的问题&#xff0c;但是不知道要怎么解决。随着无线网络的普及和使用&#xff0c;电脑无法显示WiFi列表的问题有时会让人感到困扰。电脑不显示WiFi列表是很常见的问题&#xff0c;但这并不意味着你无法连接到网络。不用担心&#xff0c;这个…

Android中Activity启动的模式

在 Android 开发中&#xff0c;Activity 的启动模式&#xff08;Launch Mode&#xff09;定义了当启动一个 Activity 时&#xff0c;系统会如何处理它的实例。不同的启动模式可以影响 Activity 在任务栈中的管理方式&#xff0c;对用户的使用体验产生直接影响。下面详细介绍四种…

Xshell 7 偏好设置

1 Xshell7 工具——更改用户数据文件夹 就是此电脑目录下的文档 该目录下的7 Xshell下的 applog ColorScheme Files 配色方案文件目录 HighlightSet Files 突出显示集目录 Logs 日志 QuickButton Files 快速命令集 Scripts 脚本文件 Sessions 会话文件 会话文件目录就…

丹摩征文活动 | 丹摩智算:大数据治理的智慧引擎与实践探索

丹摩DAMODEL&#xff5c;让AI开发更简单&#xff01;算力租赁上丹摩&#xff01; 目录 一、引言 二、大数据治理的挑战与重要性 &#xff08;一&#xff09;数据质量问题 &#xff08;二&#xff09;数据安全威胁 &#xff08;三&#xff09;数据管理复杂性 三、丹摩智算…

企业级容器技术docker之一键生成 Docker Compose

案例: 一键生成 Docker Compose 利用网站将docker 命令自动生成 Docker Compse Composerizehttps://www.composerize.com/ 基于docker-compose编译多服务镜像并启动容器案例 输入docker命令就可以自动转换为 docker-compose的格式