JavaScript全面指南(四)

news2024/11/30 6:48:31

​🌈个人主页:前端青山
🔥系列专栏:JavaScript篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来JavaScript篇专栏内容:JavaScript全面指南

目录

61、如何防止XSRF攻击

62、如何判断一个对象是否为数组,函数

63、JavaScript中如何使用事件处理程序?

64、解释延迟脚本在JavaScript中的作用?

65、实现一个函数clone,可以对javascript中的5种主要数据类型进行值复制。

66、decodeURI()和encodeURI()是什么?

67、解释JavaScript中的pop()方法?

68、解释什么是回调函数,并提供一个简单的例子。

69、面向对象编程与面向过程编程的区别

70、eval是做什么的?性能怎么样?安全如何?

71、函数节流、防抖

72、“use strict”的作用是什么?

73、了解ES6 的 Proxy吗?

74、深拷贝是什么?

75、解释 JavaScript 中的 null 和 undefined。

76、解释 JavaScript 中的值和类型。

77、scroll resize 使用函数节流实现不要频繁触发事件的需求

78、解释事件冒泡以及如何阻止它?

79、JavaScript 中的 let 关键字有什么用?

80、 jQuery 优点和缺点


61、如何防止XSRF攻击

一 CSRF是什么? 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

二、CSRF的原理

img

image.png

三、CSRF的防范措施

1、验证 HTTP Referer 字段

HTTP头中的Referer字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,而如果黑客要对其实施 CSRF 攻击,他一般只能在他自己的网站构造请求。因此,可以通过验证Referer值来防御CSRF 攻击。

2、验证码。 验证码 利用验证码将用户收到的信息与后台服务器进行比对,每次用户提交都需要用户在表单中填写一个图片上的随机字符串,不符则进行拒绝。 3、添加token验证

CSRF攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都存在cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的cookie来通过安全验证。要防止CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于cookie之中。可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器建立一个拦截器来验证这个token,如果请求中没有token或者token不正确,则认为可能是CSRF攻击而拒绝该请求。 现在业界一致的做法就是使用Anti CSRF Token来防御CSRF。

用户访问某个表单页面。
服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。
在页面表单附带上Token参数。
用户提交请求后,服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。

这个Token值必须是随机的,不可预测的。由于Token的存在,攻击者无法再构造一个带有合法Token的请求实施CSRF攻击。另外使用Token应注意Token的保密性,尽量把敏感操作由GET改成POST,以form或者AJAX形式提交,避免Token泄露。

4、尽量使用POST,限制GET

GET接口能够直接将请求地址暴露给攻击者,所以要防止CSRF一定最好不要用GET。当然POST并不是万无一失,攻击者只需要构造一个form表单就可以,但需要在第三方页面做,这样就增加了暴露的可能性。

62、如何判断一个对象是否为数组,函数

在js中判断数据类型通常使用typeof,但是typeof在判断数组和对象时的结果都是object。

那么,怎么才能区分对象和数组呢?

  1. 判断原型

var obj = {};

var arr = [];

console.log(arr);

console.log(obj); 数组和对象的原型对象不一样,由此可以通过判断原型来判断一个对象是否为数组

var obj = {};

var arr = [];

console.log(Object.getPrototypeOf(obj) === Object.prototype);

console.log(Object.getPrototypeOf(obj) === Array.prototype); 但是这种方法虽然通过检查原型来判断是否为数组,不是特别稳定,因为原型可以人为改变的一旦原型改变就可能会失效。

var obj = {};

var arr = [];

Object.setPrototypeOf(obj, Array.prototype);

console.log(Object.getPrototypeOf(obj) === Object.prototype);//false

console.log(Object.getPrototypeOf(obj) === Array.prototype);//true 此时arr的原型不是Array.prototype第一个返回的结果为false,如此,不能判断是否为数组。

判断构造函数

创建对象和创建数组的构造函数不同可以通过此种方法判断一个对象是否为数组。

var obj = {};

var arr = [];

console.log(Object.getPrototypeOf(obj).constructor === Object);

console.log(Object.getPrototypeOf(obj).constructor === Array); 由此可见,两个输出结果并不一样,并且也符合我们的认知,通过此种方法也可以判断一个对象是否为数组。

但该种方法与上一种方法的问题一样即当构造函数被修改之后就无法判断真正的数组。

var obj = {};

var arr = [];

Object.getPrototypeOf(obj).constructor = Array;

console.log(Object.getPrototypeOf(obj).constructor === Object);//false

console.log(Object.getPrototypeOf(obj).constructor === Array);//true

console.log(Object.getPrototypeOf(arr).constructor === Array);//true 由此可见,该方法的缺点与上一种方法的一样。

在判断构造函数方法中除了直接判断外还可以使用 instanceof 判断一个对象是否为一个构造函数的实例

var obj = {};

var arr = [];

console.log(obj instanceof Array);//false

console.log(arr instanceof Array);//true 由此可见,该方法也可以判断是否为数组。

Array.isArray()

通过Array.isArray()可以判断一个对象是否为数组。

var obj = {};

var arr = [];

console.log(Array.isArray(obj));//false

console.log(Array.isArray(arr));//true 由此可见此种方法可行,那么当我们把其构造函数改变后还会出现和上面一样的情况吗?

var obj = {};

var arr = [];

Object.getPrototypeOf(obj).constructor = Array;//false

console.log(Array.isArray(obj));//true

console.log(Array.isArray(arr)); 由此可见,即便将obj的构造函数改为Array也能判断出真正的数组。

用Object.toString()方法判断

var obj = {};

var arr = [];

console.log(obj.toString());//[object Object]

console.log(arr.toString());// 由此可见对象是Object创建的,但是数组的toString()返回的是空。

这是因为js中每个对象都有toString()方法,该方法继承自Object.toString()方法,但数组被重写了,但是我们可以使用call()来调用数组的toString的原始方法来判断。

var obj = {};

var arr = [];

console.log(obj.toString());//[object Object]

console.log(Object.prototype.toString.call(arr));//[object Array] 由此可见,也可以通过此种方法判断一个对象是否为数组。

那么,如果改变构造函数是否会发生类似之前的情况呢?

var obj = {};

var arr = [];

Object.getPrototypeOf(obj).constructor = Array;

console.log(obj.toString());//[object Object]

console.log(Object.prototype.toString.call(arr));//[object Array] 由此可见,此时还能正常判断并不会发生此前出现的情况。

使用场景

判断一个对象是否为数组在什么地方使用呢

在进行克隆时,需要判断对象的属性是否为数组,根据结果采取不同的操作。

总结

  1. 判断原型和判断构造函数的方法的结果会因为原型和构造函数的改变发生改变,并不十分稳定。

  2. Array,isArray()和Object.toString()方法较为稳定,较为推荐。

  3. 通常在进行克隆时会用到判断一个对象是否为数组。

63、JavaScript中如何使用事件处理程序?

事件是由用户生成活动(例如单击链接或填写表单)导致的操作。需要一个事件处理程序来管理所有这些事件的正确执行。事件处理程序是对象的额外属性。此属性包括事件的名称以及事件发生时采取的操作。

64、解释延迟脚本在JavaScript中的作用?

默认情况下,在页面加载期间,HTML代码的解析将暂停,直到脚本停止执行。这意味着,如果服务器速度较慢或者脚本特别沉重,则会导致网页延迟。在使用Deferred时,脚本会延迟执行直到HTML解析器运行。这减少了网页加载时间,并且它们的显示速度更快。

65、实现一个函数clone,可以对javascript中的5种主要数据类型进行值复制。

var clone = function (type) {
    var o;
    var typeA = typeof type;
    switch (typeA){
        case 'string':
        o = typeA+'';
            break;
        case 'number':
        o = typeA-0;
            break;
        case 'undefined':
            break;
        case 'boolean':
            o = typeA;
            break;
        case 'object':
            if(type===null){
             o = null;
            }else {
              if(Object.prototype.toString.call(type).slice(8,-1)==='Array'){
                   o = [];
                    for(var i = 0;i<type.length;i++){
                        o.push(clone(type[i]));
                    }
              }else {
                  o = {};
                  for(var key in type){
                      o[key] = clone(type[key]);
                  }
              }
            }
            break;
        default:
            break;
    }
    return o;
}

66、decodeURI()和encodeURI()是什么?

EncodeURl()用于将URL转换为十六进制编码。而DecodeURI()用于将编码的URL转换回正常。

67、解释JavaScript中的pop()方法?

pop()方法与shift()方法类似,但不同之处在于Shift方法在数组的开头工作。此外,pop()方法将最后一个元素从给定的数组中取出并返回。然后改变被调用的数组。
​
例:
var cloths = [“Shirt”, “Pant”, “TShirt”];
​
cloths.pop();
​
//Now cloth becomes Shirt,Pant

68、解释什么是回调函数,并提供一个简单的例子。

回调函数是可以作为参数传递给另一个函数的函数,并在某些操作完成后执行。下面是一个简单的回调函数示例,这个函数在某些操作完成后打印消息到控制台。

function modifyArray(arr, callback) {
 // 对 arr 做一些操作
 arr.push(100);
 // 执行传进来的 callback 函数
 callback();
}
var arr = [1, 2, 3, 4, 5];
modifyArray(arr, function() {
 console.log("array has been modified", arr);
});

69、面向对象编程与面向过程编程的区别

面向过程考虑数据变换; 面向过程的世界是以目标问题规定的I/O为中心的

面向对象考虑功能分工; 面向对象的世界是以内部实现的可理解性为中心的

70、eval是做什么的?性能怎么样?安全如何?

eval方法是在运行时对脚bai本进行解du释执行,而普通的javascript会有一个zhi预处dao理的过程。所以会有一些性能上zhuan的损失,但是通常通过一些手段能将这些性能损失降低到非常少。不至于谈虎色变。 eval通常用在一些需要动态执行字符串,或将字符串转为javascript对象的场景,比如将json字符串转为javascript对象。 至于eval容易被XSS攻击是属于想当然的说法吧,XSS攻击就是在你的页面上嵌入html或javascript代码,我觉得与是否使用eval方法没有什么关系。

71、函数节流、防抖

函数防抖(debounce)

概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。 生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流(throttle)

概念: 规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。 生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。

分析图 假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。 如果触发事件的频率是 0.5s/次,那么 函数防抖如图

img

因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。 函数节流如图

img

因为控制了最多一秒一次,频率为0.5s/次,所以每一秒钟就有一次事件作废。最终控制成1s/次 如果触发事件的频率是 2s/次,那么 函数防抖如图

img

因为2s/次已经大于了规定的最小时间,所以每计时两秒便触发一次。 函数节流如图

同样,2s/次 大于了最小时间规定,所以每一次触发都生效。 应用场景 对于函数防抖,有以下几种应用场景:

给按钮加函数防抖防止表单多次提交。 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。 判断scroll是否滑到底部,滚动事件+函数防抖

总的来说,适合多次事件一次响应的情况

对于函数节流,有如下几个场景:

游戏中的刷新率 DOM元素拖拽 Canvas画笔功能

总的来说,适合大量事件按时间做平均分配触发。

函数防抖:

function debounce(fn, wait) {
  var timer = null;
  return function () {
      var context = this
      var args = arguments
      if (timer) {
          clearTimeout(timer);
          timer = null;
      }
      timer = setTimeout(function () {
          fn.apply(context, args)
      }, wait)
  }
}
var fn = function () {
  console.log('boom')
}
setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次
setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)

之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是timer。

函数节流

function throttle(fn, gapTime) {
  let _lastTime = null;
  return function () {
    let _nowTime = + new Date()
    if (_nowTime - _lastTime > gapTime || !_lastTime) {
      fn();
      _lastTime = _nowTime
    }
  }
}
let fn = ()=>{
  console.log('boom')
}
setInterval(throttle(fn,1000),10)

如图是实现的一个简单的函数节流,结果是一秒打出一次boom

小结

函数防抖和函数节流是在时间轴上控制函数的执行次数。防抖可以类比为电梯不断上乘客,节流可以看做幻灯片限制频率播放电影。

72、“use strict”的作用是什么?

use strict 出现在 JavaScript 代码的顶部或函数的顶部,可以帮助你写出更安全的 JavaScript 代码。如果你错误地创建了全局变量,它会通过抛出错误的方式来警告你。例如,以下程序将抛出错误:

function doSomething(val) {
 "use strict"; 
 x = val + 10;
}

它会抛出一个错误,因为 x 没有被定义,并使用了全局作用域中的某个值对其进行赋值,而 use strict 不允许这样做。下面的小改动修复了这个错误:

function doSomething(val) {
 "use strict"; 
 var x = val + 10;
}

73、了解ES6 的 Proxy吗?

概述

  • Proxy用于修改某些操作的默认行为,等同于在语言层面上做出修改,所以属于一种“元编程”,即对编程语言进行编程。

  • Proxy可以理解成在目标对象前架设一层拦截层,外界访问该对象都必须先通过这层拦截,因此提供一种机制可以对外界的访问进行拦截或过滤。

实例的方法

1.get()

  • get方法用于拦截某个属性的读取操作。

let person = {
    name : '张三'
}
​
let proxy = new Proxy(person,{
    get : function(target,property){
        if(property in target){
            return target[property];
        }else{
            throw new Error('property ' + property + ' no found!')
        }
    }
})
​
proxy.name;     //'张三'
proxy.age;      //property age no found!
12345678910111213141516

以上的实例当获取对象没有的属性age时,就会抛出错误;若不通过代理,则会返回undefined;

  • get方法可以继承

let proto = new Proxy({},{
    get(target,propertykey,receiver){
        console.log('get '+ propertykey);
        return target[propertykey];
    }
});
​
let obj = Object.create(proto);
obj.lalala;         //get lalala
123456789
  • 利用Proxy对象,可以将读取属性的操作变为执行某个函数,从而实现函数的链式操作;

let pipe = (function(){
    return function(value){
        //创建函数执行栈
        let funcStack = [];
        //创建拦截器
        let oproxy = new Proxy({},{
            get: function(pipeObj,fnName){
                //当属性为get,返回函数栈一次执行函数后的结果
                if(fnName === 'get'){
                    return funcStack.reduce(function(val,fn){
                        return fn(val);
                    },value)
                }
                //否则将函数置入函数执行栈中,并返回又一个拦截器
                else{
                    funcStack.push(window[fnName]);
                    return oproxy;
                }
            }
        });
       // 将拦截器返回给pipe 
        return oproxy;
    }
}())
​
let double = n=>n*2;
let pow = n=>n*n;
​
pipe(2).double.pow.get;     //16
1234567891011121314151617181920212223242526272829

2.set()

  • set方法用户拦截某个属性的赋值操作

let ageLimit = {
    set : function(obj,prop,val){
        if(prop === 'age'){
            if(!Number.isInteger(val)){
                throw new TypeError('the age must be a integer')
            }
            if(val > 150 || val < 0){
                throw new RangeError('the age must be from 0 to 150')
            }
        }
        
        obj[prop] = val;
    }
}

let person = new Proxy({},ageLimit);
person.age = 200;	//the age must be from 0 to 150;
person.age = 'abc'	//the age must be a integer;
person.age = 20;	//正常
person.age;			// 20;
1234567891011121314151617181920
  • 通过ageLimit拦截器,可以及时对用户的数据输入做数据验证,以保证数值规范;

  • 有时候,我们会在对象上设置内部属性,属性名的第一个字符为下划线’_’,表示该属性不能被外部访问或使用。结合get和set方法,就可以做到防止内部属性被外部读写;

let handler = {
    get (target , key){
        invariant(key,'get');
        return target[key];
    },
    set (target , key , value){
        invatiant(key,'set');
        taget[key] = value;
        return true;
    }
}
​
​
function invariant(key,action){
    if(key[0] === '_'){
        throw new Error('no allowed to ' + action + ' the property');
    }
}
​
let target = {
    _name : '张三',
    _age : 20
};
let proxy = new Proxy(target,handler);
proxy._name;    // no allowed to get the property
proxy._age = 12 // no allowed to set the property
1234567891011121314151617181920212223242526

3.apply()

  • apply方法拦截函数的调用、call、apply操作

  • apply方法接收三个参数:目标对象、目标对象的上下文的this、目标对象的参数数组

let target = function(){
    console.log('I am the target');
}
​
let handler = {
    apply : function(){
        console.log('I am the apply');
    }
}
​
let p = new Proxy(target,handler);
​
p();    //I am the apply;
12345678910111213

4.其他方法

  1. has(target,propkey)

    • 拦截hasProperty()propkey in proxy操作,返回一个布尔值;

  2. deleteProperty(target,propkey)

    • 拦截delete proxy[propkey]操作,返回一个布尔值;

  3. ownKeys(target)

    • 拦截Object.getOwnPropertyNarnes(proxy)Object.getOwnPropertySyrnbols (proxy)Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身属性的属 性名,而 Object .keys()的返回结果仅包括目标对象自身的可遍历属性;

  4. getOwnPropertyDescriptor(target,propkey)

    • 拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象;

  5. defineProperty(target,propkey)

    • 拦截 Object.defineProperty(proxy, propKey, propDesc)Object.define Properties(proxy, propDescs),返回一个布尔值;

  6. preventExtensions(target)

    • 拦截 Object . preventExtensions (proxy) ,返回一个布尔值;

  7. getPrototypeOf(target)

    • 拦截Object.getPrototypeOf(proxy),返回一个对象;

  8. isExtensible(target)

    • 拦截Object.isExtensible(proxy),返回一个布尔值;

  9. setPrototypeOf(target)

    • 拦截Object.setPrototypeOf(proxy,proto),返回一个布尔值;若对象为函数,则还有二外两种操作可以拦截(apply,construct)

  10. construct(target,args)

    • 拦截Proxy实例作为构造函数调用的操作,比如 new proxy(…args);

74、深拷贝是什么?

变量存储类型分两类

①基本类型:直接存储在栈中的数据。(字符串、布尔值、未定义、数字、null)

②引用类型:将该对象引用地址存储在中,然后对象里面的数据存放在中。(数组、对象、函数)

这里解释一下为什么null是基本类型:有人说他用type of打印出来不是oject吗?

null只是一个空指针对象,没有数据。根据引用类型特点可以看一下是否符合。

=================

回到我们的问题上

说说深拷贝和浅拷贝还有赋值的区别,这样好理解

浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象

深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)

赋值:获得该对象的引用地址

img

浅拷贝和深拷贝的区别

img

三者的区别

下面用实例来说明

赋值特点说明:

img

赋值,疑惑点来自于下图。

img

赋值打印图

浅拷贝特点说明:

img

obj还是上面的

深拷贝说明:

img

第一种方法的缺陷在于函数不能拷贝

img

75、解释 JavaScript 中的 null 和 undefined。

JavaScript 中有两种底层类型:null 和 undefined。它们代表了不同的含义:

  • 尚未初始化:undefined;

  • 空值:null。

null和undefined是两个不同的对象, 有图为证:

img

76、解释 JavaScript 中的值和类型。

JavaScript提供两种数据类型: 基本数据类型和引用数据类型 基本数据类型有:

  • String

  • Number

  • Boolean

  • Null

  • Undefined

  • Symbol

引用数据类型有:

  • Object

  • Array

  • Function

77、scroll resize 使用函数节流实现不要频繁触发事件的需求

<script>
        function throttle(fun,delay){
            let timer = null;
            if(timer){
                clearTimeout(timer);
            }
            return function(){
                setTimeout(function(){
                    fun();
                },delay);
            }
        } 
        var firstResize = true;
        window.onresize = function(){
            if(firstResize){
                throttle(function(){
                    alert(1)
                },30)();
            }
            firstResize = false;
        }
    </script>

78、解释事件冒泡以及如何阻止它?

事件冒泡是指嵌套最深的元素触发一个事件,然后这个事件顺着嵌套顺序在父元素上触发。

防止事件冒泡的一种方法是使用 event.cancelBubble 或 event.stopPropagation()(低于 IE 9)。

79、JavaScript 中的 let 关键字有什么用?

用let声明变量只在块级作用域起作用,适合在for循环使用,也不会出现变量提升现象。同一个代码块内,不可重复声明的相同变量,不可重复声明函数内的参数。

80、 jQuery 优点和缺点

具体而言,jQuery有如下优势:

1,提供了用css选择符来选择dom元素的api(现在已经被浏览器内置支持) 2,提供了浏览器的检测api 3,提供了兼容的功能性api 4,提供了DOM的批处理操作(批处理思想永远都不会过时) 5,提供了dom操作的链式操作 6,提供了插件机制(代码复用变得容易,也不容易过时)

缺点 现在已经很少操作DOM了 现代框架VUE中 jquery代码工程化 可维护性差vue很远

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

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

相关文章

科研绘图系列:R语言散点相关系数图(scatter plot)

文章目录 介绍加载R包数据函数画图系统信息介绍 散点相关系数图是一种数据可视化图表,它结合了散点图和相关系数来展示两个连续变量之间的关系。这种图表通常用于相关性分析,以判断两个变量之间是否存在某种关联,并总结坐标点的分布模式。 在散点相关系数图中,横轴和纵轴…

SpringBoot+Vue+Uniapp智能社区服务小程序系统(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

截图贴图工具 | PixPin v1.9.0 绿色版

PixPin是一款功能强大且使用简单的截图和贴图工具&#xff0c;它旨在帮助用户提高工作效率。PixPin的主要功能包括截图、贴图、标注、文本识别、长截图和截动图。它允许用户自由选择或自动探测窗口来设定截图范围&#xff0c;精准截取所需内容&#xff0c;并将所截取的图像“贴…

D37【python 接口自动化学习】- python基础之函数

day37 函数的参数 学习日期&#xff1a;20241014 学习目标&#xff1a;输入输出与文件操作&#xfe63;-50 函数的参数&#xff1a;怎样实现函数与外部数据通信&#xff1f; 学习笔记&#xff1a; 实参与形参 代码实现 # 实参与形参 def foo(number):print(number)n1123 n…

redis与springBoot整合

前提 要实现,使用Redis存储登录状态 需要一个完整的前端后端的项目 前端项目搭建 解压脚手架 安装依赖 配置请求代理 选做: 禁用EsLint语法检查 Vue Admin Template关闭eslint校验&#xff0c;lintOnSave&#xff1a;false设置无效解决办法_lintonsave: false-CSDN博客 …

【前端】如何制作一个简单的网页(3)

接下来我们为html元素添加网页内容。网页内容按照功能的不同可以区分为网页头与网页体两个部分。 先来说说什么是网页头。 网页头 网页头&#xff08;又称为网页头部信息&#xff09;向浏览器提供文档的一些信息。 这些信息包括网页的名称、编码方式、样式、JS代码等。 &…

java项目之纺织品企业财务管理系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的纺织品企业财务管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于spring boot…

Thread类的基本用用法

1.创建线程 1.1继承Thread类 线程创建需要Thread类但是不需要import导入是为什么&#xff1f; 因为java.lang默认import不需要导入&#xff0c;java.lang中包含Thread 为什么在MyThread类中只能使用try catch 无法使用throws&#xff1f; 因为父类Thread run中没有throws …

Java 日志打印

使用日志打印&#xff1a; private static Logger log LoggerFactory.getLogger(DeptController.class);RequestMapping("/depts")public Result list() { // System.out.println("查询全部部门数据");log.info("查询全部部门数据");ret…

Spring Boot:为中小型医院网站提速

3 系统分析 3.1 可行性分析 通过对本基于Spring Boot的中小型医院网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、操作可行性、经济可行性和时间可行性四方面进行分析。 3.1.1 技术可行性 本基于Spring Boot的中小型…

[LeetCode] 118. 杨辉三角

给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1…

【计网】从零开始理解UDP协议 --- 理解端口号和UDP结构

我依旧敢和生活顶撞&#xff0c; 敢在逆境里撒野&#xff0c; 直面生活的污水&#xff0c; 永远乐意为新一轮的月亮和日落欢呼。 --- 央视文案 --- 从零开始理解UDP协议 1 再谈端口号2 理解UDP 报头结构3 UDP 的特点4 UDP 的缓冲区5 UDP 使用注意事项 1 再谈端口号 之前我…

个性化图像生成新SOTA!阿里开源MIP-Adapter,可将无需微调的IP-Adapter推广到同时合并多个参考图像。

今天给大家介绍阿里最近开源的个性化图像生成的新方法MIP-Adapter&#xff0c;将无需微调的预训练模型&#xff08;IP-Adapter&#xff09;推广到同时合并多个参考图像。MIP-Adapter会根据每个参考图像与目标对象的相关性来给这些图像分配不同的“重要性分数”。这样&#xff0…

OpenShift 4 - 云原生备份容灾 - Velero 和 OADP 基础篇

《OpenShift 4.x HOL教程汇总》 说明&#xff1a; 本文主要说明能够云原生备份容灾的开源项目 Velero 及其红帽扩展项目 OADP 的概念和架构篇。操作篇见《OpenShift 4 - 使用 OADP 对容器应用进行备份和恢复&#xff08;附视频&#xff09; 》 Velero 和 OADP 包含的功能和模…

十、Python基础语法(循环-while循环)

什么是循环&#xff1f;在满足条件的情况下,让指定的代码重复执行 。 一、while循环 while是python中的关键字&#xff0c;作用是用来实现循环的。 语法&#xff1a; 需求&#xff1a; 打印10次“我爱学习” a 0while a < 10:print(我爱学习)a 1运行结果&#xff1a;…

C++(类和对象—对象特性)

对象的初始化和清理 生活中我们买的电子产品都基本会有出厂设置&#xff0c;在某一天我们不用时候也会删除一些自己信息数据保证安全。 C中的面向对象来源于生活&#xff0c;每个对象也都会有初始设置以及对象销毁前的清理数据的设置。 1.构造函数和析构函数 对象的初始化和清理…

ROS理论与实践学习笔记——5 ROS机器人系统仿真之URDF、Gazebo与Rviz综合应用

6.1 机器人运动控制以及里程计信息显示 &#xff08;1&#xff09;ros_control 简介 场景&#xff1a;如何在不同的机器人系统上实现同一套 ROS 程序的部署&#xff1f;例如&#xff0c;在开发阶段&#xff0c;为了提高测试效率&#xff0c;程序通常在仿真平台&#xff08;如 …

vue2 Canvas 多边形区域绘制组件封装

效果预览&#xff1a; CanvasBox组件 <!-- 区域设置canvas --> <template><div class"all" ref"divideBox"><!-- <div><button click"test">清空</button></div> --><img id"img"…

FineReport 标题冻结,冻结表头,冻结行列

先进行重复标题行和重复标题列设置&#xff0c;然后再进行分页冻结设置 1、冻结列 SELECT * FROM S人员花名册选定列 – 右击 – 设置重复标题列 2、冻结行 选定行 – 右击 – 设置重复标题行 3、重复与冻结设置 模板 – 重复与冻结设置 冻结重复标题有分页冻结和填报…

Leecode刷题之路第20天之有效的括号

题目出处 20-有效的括号-题目出处 题目描述 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 1.左括号必须用相同类型的右括号闭合…