2023年web前端开发之JavaScript进阶(一)

news2024/11/18 14:37:44

接上篇博客进行学习,通俗易懂,详细

博客地址: 2023年web前端开发之JavaScript基础(五)基础完结_努力的小周同学的博客-CSDN博客

学习内容

学习 作用域、变量提升、 闭包等语言特征,加深对 JavaScript 的理解,掌握变量赋值、函数声明的简洁语法, 降低代码的冗余度
  • 理解作用域对程序执行的影响

  • 能够分析程序执行的作用域范围

  • 理解闭包本质,利用闭包创建隔离作用域 (重要)

  • 了解什么变量提升及函数提升

  • 掌握箭头函数、解析剩余参数等简洁语法 ( 重点 )

一.作用域

了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免全局变量污染。

作用域(scope) 规定了变量能够被访问的"范围" 离开这个"范围" 变量便不能被访问

作用域分为 全局作用域 和 局部作用域.

1.1局部作用域

局部作用域分为函数作用域和块作用域.

1.2函数作用域

在函数内部声明的变量只能在函数内部被访问,外部无法直接访问

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //声明conunter 函数
        function conunter(x,y){
            //函数内部声明的变量
            const s = x + y
            console.log(s)  // 输出18
        }

        //调用counter 函数
        conunter(10,8)  // 传入实参
        //直接在外部访问 函数内部的变量s
        console.log(s)  // 报错 
    </script>
</body>
</html>

总结:

  1. 函数内部声明的变量,在函数外部无法被访问

  1. 函数的参数也是函数内部的局部变量

  1. 不同函数内部声明的变量无法互相访问

  1. 函数执行完毕后,函数内部的变量实际被清空了

1.3 块作用域

在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。

代码实现效果如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //代码块
        {
            //内部声明变量
            let age = 12
            console.log(age) //12 
        }
        //代码块外部使用 变量age
        console.log(age) // 报错




        
        let flag = true
        if(flag){
            //str 只能在该代码块中被访问
            let  str = "代码块内部"
            console.log(str) // 正常输出 代码块内部
        }
        //外部访问str 变量  
        console.log(str) //报错






        for(let t = 1; t<=6;t++){
            //t 只能在该代码块中被访问
            console.log(t); //正常输出 
        }

        //变量t 定义在for循环里 
        //在外部访问 t
        console.log(t) //报错  
    </script>
</body>
</html>

JavaScript中除了变量外还有产量, 常量与变量本质的区别是 [常量必须要有值且不允许被重新赋值 ], 常量值为对象尤其属性和方法允许重新赋值

<script>
  // 设置常量 必须要有值
  const version = '1.0.0'; 

  // 常量 不能重新赋值
  // version = '1.0.1';

  // 常量值为对象类型
  const user = {
    name: '小明',
    age: 18
  }

  // 不能重新赋值
  user = {};

  // 属性和方法允许被修改
  user.name = '小小明';
  user.gender = '男';
</script>

总结:

  1. let 声明的变量会产生块作用域, var 不会产生块作用域 当var设置变量外部也能访问

  1. const 声明的常量也会产生块作用域

  1. 不同代码块之间的变量无法互相访问

  1. 推荐使用 let 或 const

注:开发中 let 和 const 经常不加区分的使用,如果担心某个值会不小被修改时,则只能使用 const 声明成常量。

1.4 全局作用域

<script> 标签和 .js 文件的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。

<script>
  // 此处是全局
  
  function sayHi() {
    // 此处为局部
  }

  // 此处为全局
</script>

全局作用域中声明的变量,任何其它作用域都可以被访问,如下代码所示:

<script>
    // 全局变量 name
    const name = '小明'
  
      // 函数作用域中访问全局
    function sayHi() {
      // 此处为局部
      console.log('你好' + name)
    }

    // 全局变量 flag 和 x
    const flag = true
    let x = 10
  
      // 块作用域中访问全局
    if(flag) {
      let y = 5
      console.log(x + y) // x 是全局的
    }
</script>

总结:

  1. 为 window 对象动态添加的属性默认也是全局的,不推荐!

  1. 函数中未使用任何关键字声明的变量为全局变量,不推荐!!!

  1. 尽可能少的声明全局变量,防止全局变量被污染

JavaScript 中的作用域是程序被执行时的底层机制,了解这一机制有助于规范代码书写习惯,避免因作用域导致的语法错误。

1.5 作用域链

在解释什么是作用域链前先来看一段代码:

<script>
  // 全局作用域
  let a = 1
  let b = 2
  // 局部作用域
  function f() {
    let c
    // 局部作用域
    function g() {
      let d = 'yo'
    }
  }
</script>

函数内部允许创建新的函数,f 函数内部创建的新函数 g,会产生新的函数作用域,由此可知作用域产生了嵌套的关系。

如下图所示,父子关系的作用域关联在一起形成了链状的结构,作用域链的名字也由此而来。

作用域链本质上是底层的变量查找机制,在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域,如下代码所示:

这里多理解实验

<script>
  // 全局作用域
  let a = 1
  let b = 2

  // 局部作用域
  function f() {
    let c
    // let a = 10;
    console.log(a) // 1 或 10
    console.log(d) // 报错
    
    // 局部作用域
    function g() {
      let d = 'yo'
      // let b = 20;
      console.log(b) // 2 或 20
    }
    
    // 调用 g 函数
    g()
  }

  console.log(c) // 报错
  console.log(d) // 报错
  
  f();
</script>

总结:

  1. 嵌套关系的作用域串联起来形成了作用域链

  1. 相同作用域链中按着从小到大的规则查找变量

  1. 子作用域能够访问父作用域,父级作用域无法访问子级作用域

思考:

1. 作用域链本质是什么? Ø 作用域链本质上是底层的变量查找机制 2. 作用域链查找的规则是什么? Ø 会优先查找当前函数作用域中查找变量 Ø 查找不到则会依次逐级查找父级作用域直到全局作用域

二. JS垃圾回收机制(重点理解)

2.1 什么是垃圾回收机制

垃圾回收机制(Garbage Collection) 简称 GC

JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收.

正因为垃圾回收器的村寨,许多人认为JS不用太关心内存管理问题

但如果不了解JS内存管理机制,我们同样容易层内存泄漏(内存无法被回收) 的情况

不在用到的内存,没有及时释放,就叫做内存泄漏

2.2内存的生命周期

JS环境中分配的内存,一般有如下生命周期:

  1. 内存分配:当我们声明变量, 函数, 对象的时候,系统会自动为他们分配内存

  1. 内存使用: 及读写内存,也就是使用变量,函数等

  1. 内存回收: 使用完毕,由垃圾回收自动回收不再使用的内存

  1. 说明:

  • 全局变量一般不会回收(关闭页面回收)

  • 一般情况下局部变量的值不用了会被自动回收掉

总结:

1. 什么是垃圾回收机制? Ø 简称 GC Ø JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾 回收器自动回收

2. 什么是内存泄漏? Ø 不再用到的内存,没有及时释放,就叫做内存泄漏

3. 内存的生命周期是什么样的? Ø 内存分配、内存使用、内存回收 Ø 全局变量一般不会回收; 一般情况下局部变量的值, 不用了, 会被自动 回收掉

拓展-JS垃圾回收机制-算法说明:

  1. 堆栈空间分配区别:

1.1 栈 (操作系统) : 由操作系统自动分配释放函数的参数值,局部变量等,基本数据类型放到栈里面

1.2 堆 (操作系统) : 一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收. 复杂数据类型放到堆里面.

下面介绍两种常见的浏览器垃圾回收算法: 引用计数法 标记清除法

1.1引用计数法:

IE采用的引用计数算法, 定义“内存不再使用”,就是看一个对象是否有指向它的引用,没有引用了就回收对象 算法: 1. 跟踪记录被引用的次数 2. 如果被引用了一次,那么就记录次数1,多次引用会累加 ++ 3. 如果减少一个引用就减1 -- 4. 如果引用次数是0 ,则释放内存

let a = new Object() // 引用次数初始化为1
let b = a // 引用次数2,即obj被a和b引用
a=null // 引用次数1
b=null // 引用次数0,
... // GC回收此引用类型在堆空间中所占的内存

但是这种方法也存在一些问题,就是嵌套引用(循环引用)

如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄漏

function fn(){ // fn引用次数为1,因为window.fn = fn,会在window=null即浏览器关闭时回收
    let A = new Object() // A: 1
    let B = new Object() // B: 1
    A.b = B // B: 2
    B.a = A // A: 2
}
// A对象中引用了B,B对象中引用了A,两者引用计数都不为0,永远不会被回收。
// 若执行无限多次fn,那么内存将会被占满,程序宕机
fn();
// 还有就是这种方法需要一个计数器,这个计数器可能要占据很大的位置,因为我们无法知道被引用数量多少。

因为他们的引用次数永远不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄露

1.2 标记清除法

该策略分为Mark(标记)Sweep(清除)两个阶段。

Mark阶段:
  • 运行时,将内存中的所有变量标记为0(垃圾)

  • 从各个根对象遍历,将非垃圾变量标记为1

Sweep阶段:
  • 将所有标记为0的变量的内存释放

function fn(a){ // 开始执行此函数时,将其作用域中a、B以及匿名函数标记为0
    alert(a) // 0
    let B = new Object() // 0
    return function (){ // 由于这里return出去会被其他变量引用,故标记变为1
        altert(B) // 由于这里的闭包,B的标记变为1
    }
    ... // 执行函数完毕,销毁作用域,在某个GC回收循环时会清理标记为0的变量a,B和匿名函数被保留了下来即非垃圾变量
}

let fn2 = fn(new Object()) 
// 补充一下:fn和fn2作为window.fn和window.fn2,标记一直为1,仅仅当手动设置fn=null和fn2=null才会标记为0

三. 闭包(重要)

闭包是一种比较特殊和函数,使用闭包能够访问函数作用域中的变量。从代码形式上看闭包是一个做为返回值的函数,如下代码所示:

闭包含义 : 内层函数 + 外层函数变量

闭包的应用: 实现数据的私有。统计函数的调用次数

闭包的写法 统计函数的调用次数

<body>
  <script>
    // 1. 闭包含义 : 内层函数 + 外层函数变量
    // function outer() { 
    //   const a = 1  //外层函数变量
    //
    //   function f() {  //内层函数 
    //     console.log(a)
    //   }
    //  
    //   f()
    //  
    // }
    // outer()

      
    // 2. 闭包的应用: 实现数据的私有.统计函数的调用次数
    // let count = 1
    // function fn() {
    //   count++
    //   console.log(`函数被调用${count}次`)
    // }
    // 不影响外部count = 1 的值,实现数据的私有

      
      
    // 3. 闭包的写法  统计函数的调用次数
    function outer() {
      let count = 1
      function fn() {
        count++
        console.log(`函数被调用${count}次`)
      }
      return fn
    }
    const re = outer()
    // const re = function fn() {
    //   count++
    //   console.log(`函数被调用${count}次`)
    // }
    re()
    re()
    // const fn = function() { }  函数表达式
    // 4. 闭包存在的问题: 可能会造成内存泄漏
  </script>
</body>

总结:

1.怎么理解闭包?

  • 闭包 = 内层函数 + 外层函数的变量

恍然大悟如下:

2.闭包的作用?

  • 封闭数据,提供操作,外部也可以访问函数内部的变量

  • 闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来, 实现数据私

3.闭包可能引起的问题?

  • 内存泄漏

四. 变量提升

目标:了解什么是变量提升 说明:

  • JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6 引入了块级作用域, 用let 或者 const声明变量,让代码写法更加规范和人性化

  • 变量提升是 JavaScript 中比较“奇怪”的现象,它允许在变量声明之前即被访问,(仅存在于var声明变量)

<script>
  // 访问变量 str
  console.log(str + 'world!');

  // 声明变量 str
  var str = 'hello ';
</script>

注意: 1. 变量在未声明即被访问时会报语法错误 2. 变量在var声明之前即被访问,变量的值为 undefined 3. let / const 声明的变量不存在变量提升 4. 变量提升出现在相同作用域当中 5. 实际开发中推荐先声明再访问变量

提问:

1. 用哪个关键字声明变量会有变量提升?

  • var

2. 变量提升是什么流程?

  • 先把var 变量提升到当前作用域于最前面

  • 只提升变量声明, 不提升变量赋值

  • 然后依次执行代码

我们不建议使用var声明变量

五.函数进阶

知道函数参数默认值、动态参数、剩余参数的使用细节,提升函数应用的灵活度,知道箭头函数的语法及与普通函数的差异

1.函数提升

函数提升与变量提升比较类似,是指函数在声明之前即可被调用

<script>
  // 调用函数
  foo()
  // 声明函数
  function foo() {
    console.log('声明之前即被调用...')
  }

  // 不存在提升现象
  bar()  // 错误
  var bar = function () {
    console.log('函数表达式不存在提升现象...')
  }
</script>

总结: 1. 函数提升能够使函数的声明调用更灵活 2. 函数表达式不存在提升的现象 3. 函数提升出现在相同作用域当中

2.函数参数

函数参数的使用细节,能够提升函数应用的灵活度。

2.1默认值

<script>
  // 设置参数默认值
  function sayHi(name="小明", age=18) {
    document.write(`<p>大家好,我叫${name},我今年${age}岁了。</p>`);
  }
  // 调用函数
  sayHi();
  sayHi('小红');
  sayHi('小刚', 21);
</script>

总结:

  1. 声明函数时为形参赋值即为参数的默认值

  1. 如果参数未自定义默认值时,参数的默认值为 undefined

  1. 调用函数时没有传入对应实参时,参数的默认值被当做实参传入

2.2动态参数

arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。

<script>
  // 求生函数,计算所有参数的和
  function sum() {
    // console.log(arguments)
    let s = 0
    for(let i = 0; i < arguments.length; i++) {
      s += arguments[i]
    }
    console.log(s)
  }
  // 调用求和函数
  sum(5, 10)// 两个参数
  sum(1, 2, 4) // 三个参数
</script>

总结:

  1. arguments 是一个伪数组

  1. arguments 的作用是动态获取函数的实参

2.3 剩余参数

<script>
  function config(baseURL, ...other) {
    console.log(baseURL) // 得到 'http://baidu.com'
    console.log(other)  // other  得到 ['get', 'json']
  }
  // 调用函数
  config('http://baidu.com', 'get', 'json');
</script>

总结:

  1. ... 是语法符号,置于最末函数形参之前,用于获取多余的实参

  1. 借助 ... 获取的剩余实参,是个真数组

3. 展开运算符

展开运算符( … ),将一个数组进行展开 典型运用场景: 求数组最大值(最小值)、合并数组等

展开运算符 or 剩余参数

剩余参数:函数参数使用,得到真数组 展开运算符:数组中使用,数组展开

3.箭头函数( 重点 )

箭头函数是一种声明函数的简洁语法,它与普通函数并无本质的区别,差异性更多体现在语法格式上。

3.1基本写法

<body>
  <script>
    // const fn = function () {
    //   console.log(123)
    // }
    // 1. 箭头函数 基本语法
    // const fn = () => {
    //   console.log(123)
    // }
    // fn()
    // const fn = (x) => {
    //   console.log(x)
    // }
    // fn(1)
      
      
      
    // 2. 只有一个形参的时候,可以省略小括号
    // const fn = x => {
    //   console.log(x)
    // }
    // fn(1)
      
      
      
    // // 3. 只有一行代码的时候,我们可以省略大括号
    // const fn = x => console.log(x)
    // fn(1)
      
      
    // 4. 只有一行代码的时候,可以省略return
    // const fn = x => x + x
    // console.log(fn(1))
      
      
      
    // 5. 箭头函数可以直接返回一个对象
    // const fn = (uname) => ({ uname: uname })
    // console.log(fn('刘德华'))

  </script>
</body>

总结:

  1. 箭头函数属于表达式函数,因此不存在函数提升

  1. 箭头函数只有一个参数时可以省略圆括号 ( )

  1. 箭头函数函数体只有一行代码时可以省略花括号{ }, 并自动作为返回值被返回

  1. 如图所示:

代码如下:

<body>
  <script>
    // const fn = function () {
    //   console.log(123)
    // }
    // 1. 箭头函数 基本语法
    // const fn = () => {
    //   console.log(123)
    // }
    // fn()
    // const fn = (x) => {
    //   console.log(x)
    // }
    // fn(1)
      
      
      
    // 2. 只有一个形参的时候,可以省略小括号
    // const fn = x => {
    //   console.log(x)
    // }
    // fn(1)
      
      
      
    // // 3. 只有一行代码的时候,我们可以省略大括号
    // const fn = x => console.log(x)
    // fn(1)
      
      
    // 4. 只有一行代码的时候,可以省略return
    // const fn = x => x + x
    // console.log(fn(1))
      
      
      
    // 5. 箭头函数可以直接返回一个对象
    // const fn = (uname) => ({ uname: uname })
    // console.log(fn('刘德华'))

  </script>
</body>

3.2箭头函数参数

箭头函数中没有 arguments,只能使用 ... 动态获取实参

<body>
  <script>
    // 1. 利用箭头函数来求和
    const getSum = (...arr) => {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      return sum
    }
    const result = getSum(2, 3, 4)
    console.log(result) // 9
  </script>

3.3箭头函数 this

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this。

 <script>
    // 以前this的指向:  谁调用的这个函数,this 就指向谁
    // console.log(this)  // window
    // // 普通函数
    // function fn() {
    //   console.log(this)  // window
    // }
    // window.fn()
    // // 对象方法里面的this
    // const obj = {
    //   name: 'andy',
    //   sayHi: function () {
    //     console.log(this)  // obj
    //   }
    // }
    // obj.sayHi()

    // 2. 箭头函数的this  是上一层作用域的this 指向
    // const fn = () => {
    //   console.log(this)  // window
    // }
    // fn()
    // 对象方法箭头函数 this
    // const obj = {
    //   uname: 'pink老师',
    //   sayHi: () => {
    //     console.log(this)  // this 指向谁? window
    //   }
    // }
    // obj.sayHi()

    const obj = {
      uname: 'pink老师',
      sayHi: function () {
        console.log(this)  // obj
        let i = 10
        const count = () => {
          console.log(this)  // obj 
        }
        count()
      }
    }
    obj.sayHi()

  </script>

箭头函数不会创建自己的this ,他只会从自己的作用域链的上一层沿用this

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

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

相关文章

rs485转tcp网关盒子怎么用(rs485协议转以太网tcp/ip)

随着工业自动化技术的不断发展&#xff0c;越来越多的工业设备在使用时需要进行数据通信。其中&#xff0c;RS485通信协议是一种常见的工业通信协议&#xff0c;而TCP/IP协议则是互联网通信的标准协议。为了实现RS485协议与TCP/IP协议之间的通信&#xff0c;可以使用RS485转TCP…

【Java】面试常问知识点(Java基础—2)

Java基础 多线程的状态 新建状态 当用new操作符创建一个线程时&#xff0c; 例如new Thread(r)&#xff0c;线程还没有开始运行&#xff0c;此时线程处在新建状态。 当一个线程处于新生状态时&#xff0c;程序还没有开始运行线程中的代码 就绪状态 一个新创建的线程并不自动…

ChatGLM-6B微调与部署

文章目录 基于ChatGLM-6B的推理与部署配置环境与准备配置环境模型文件准备 代码运行 Demo命令行 Demo基于 Gradio 的网页版 Demo基于 Streamlit 的网页版 Demo 基于peft框架的LoRA微调ChatGLM-6B配置环境与准备配置环境模型文件准备数据准备数据处理 微调过程 基于P-Tuning v2微…

stm32影子寄存器、预装载寄存器,TIM_OC1PreloadConfig和TIM_ARRPreloadConfig的作用

一直没搞清楚stm32定时器的TIM_OC1PreloadConfig、TIM_ARRPreloadConfig函数的作用&#xff0c;影子寄存器、预装载寄存器、重载寄存器的概念。今天来研究一下&#xff1a; 首先看定时器的框图&#xff1a; 图中有阴影的小方框&#xff0c;代表该功能对应的寄存器有影子寄存器&…

Canal实战使用(集群部署)和原理解析

1.mysql数据同步工作原理 MySQL master将数据变更写入二进制日志(binary log&#xff0c;其中记录叫做二进制日志事件binary log events&#xff0c;可以通过 show binlog events 进行查看) MySQL slave将master的binary log events拷贝到它的中继日志(relay log) MySQL slav…

Java基础(十八)网络编程

1. 网络编程概述 Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库&#xff0c;可以实现无痛的网络连接&#xff0c;联网的底层细节被隐藏在 Java 的本机安装系统里&am…

软件测试培训了几个月,找到工作了,面试经验分享给各位

面试问的一些基本问题 功能方面&#xff1a;问的最多的就是测试流程&#xff0c;测试计划包含哪些内容&#xff0c;公司人员配置&#xff0c;有bug开发认为不是 bug怎么处理&#xff0c;怎样才算是好的用例&#xff0c;测试用例设计方法&#xff08;等价类&#xff0c;边界值等…

无线之红外线技术的组网方式详解

红外线(Infrared rays)也是一种光线&#xff0c;由于它的波长比红色光750nm)还长&#xff0c;超出了人眼可以识别的可见光&#xff09;范围&#xff0c;所以我们看不见它&#xff0c;又称为红外热辐射(Infrared radiation)&#xff0c;通常把波长为0.75&#xff5e;1000μm的光…

腾讯高工手写13W字“Netty速成手册”,3天走向实战

前言 在java界&#xff0c;netty无疑是开发网络应用的拿手菜。你不需要太多关注复杂的nio模型和底层网络的细节&#xff0c;使用其丰富的接口&#xff0c;可以很容易的实现复杂的通讯功能。 作为当前最流行的NIO框架&#xff0c;Netty在互联网领域、大数据分布式计算领域、游…

【Linux0.11代码分析】02 之 bootsect.s 启动流程

【Linux0.11代码分析】02 之 bootsect.s 启动流程 一、boot\bootsect.s1.1 将bootsect.s 从0x7c00 移动到 0x90000 &#xff08;512byte&#xff09;1.2 使用 int 0x13 中断加载 setup.s 程序到 0x902001.3 获取并解析磁盘驱动器的参数1.4 开始加载 System模块到 0x10000 地址1…

计算机网络之应用层

文章目录 应用层1. 应用层协议原理1.1 网络应用程序体系结构1.2 进程通信1.3 可供程序使用的运输服务1.4 因特网提供的运输服务1.5 应用层协议 2.Web应用和HTTP协议2.1 HTTP概况2.2 非持久连接和持久连接2.3 HTTP报文格式2.4 用户服务器的交互&#xff1a;cookie2.5 Web缓存器 …

数字医疗算法应用创新大赛-食品与疾病关系预测算法赛道top5方案分享

一、比赛地址和背景 1.1 比赛地址 比赛地址 1.2 数据说明及任务 本次算法赛将提供超过 23.5W 的食物、疾病对应关系及其量化得分&#xff0c;其中食物特征超过 200 个&#xff0c;疾病特征由 3 种不同的方式抽取&#xff0c;累积超过 4000 个特征信息。初赛为 0、1 二分类预…

递归递推练习题

1.用递归的方法123…N的值&#xff08;in:5,out:15&#xff09; 2.输出斐波那契数列的第N项&#xff0c;0&#xff0c;1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8&#xff0c;13…(in:3,out:1) 3.求n!&#xff08;in:5,out:120&#xff09;n!123……

STM32启动/下载模式

启动模式 主闪存存储器区存放用户设计的代码&#xff0c;代码烧录到这里&#xff0c;一般情况在正常工作时需要把STM32设置为从这里启动。 系统存储器区用来实现ISP功能的。 内嵌SRAM区用来实现调试器调试功能的。 ISP ISP一般由PC机通过串口把bin/hex文件直接烧写到单片机内…

java并发编程之美第五章读书笔记

java并发包中并发List源码剖析 介绍 CopyOnWriteArrayList 线程安全的ArrayList,对其进行的修改操作都是在底层的一个复制的数组(快照)进行的,也就是写时复制策略 类图 每一个对象里面有一个array数组进行存放具体的元素,ReentrantLock独占锁对象用来保证同时只有一个线程对…

Maven中optional标签详解

这一篇文章应该是全网讲解optional最细致的&#xff0c;因为我都是拿我自己的试验来证明&#xff0c;从试验当中也发现了很多出乎意外的知识&#xff01;感兴趣的跟着小编一块来学习呀&#xff01; 目录 一、前言二、依赖传递代码演示三、是否会影响父子工程之间的依赖继承呢&a…

精致女孩必备的6款APP,内外兼修,提升气质

自立自强、敢于追求、内外兼修&#xff0c;这样的女孩不管在哪个时代都是非常有魅力的&#xff01; 在我看来&#xff0c;自律、上进、情商高、会打扮、会赚钱、独立、落落大方&#xff0c;这才是精致女孩该有的样子。 不墨迹&#xff0c;速速揭开6款宝藏APP的面纱&#xff0…

石头科技2022年营收实现双位数增长,以技术实力打响创新价值战

近日&#xff0c;石头科技披露了2022年度财务报告&#xff0c;报告显示&#xff0c;在在较大内外部压力下&#xff0c;石头科技2022年营收依然实现双位数增长&#xff0c;且境内外销售收入平稳增长。 该公司在近年来不断完善其产品矩阵&#xff0c;目前已推出手持无线吸尘、商…

数据结构 (入门必看)

一、 预备知识 &#xff08;一&#xff09;数据结构前言 1、学习C语言是如何写程序,学习数据结构如何简洁高效的写程序 2、遇到一个实际问题&#xff0c;需要写程序&#xff0c;需要解决两个方面的问题 1)如何表达数据之间的逻辑规律以及如何将数据存储到计算机中 数据结构…

多数据源 使用 flyWay 进行数据库管理

文章目录 前言多数据源 使用 flyWay 进行数据库管理1. 环境2. flyway版本 与 MySQL 版本 对应关系3. flyway 脚本文件命名方式4. flyway工作流程5. 知识点补充6. 集成的时候常见错误6.1. user_variables_by_thread没有访问权限6.2. MySQL不支持Flyway社区版&#xff0c;只支持F…