当前位置: 首页 > news >正文

JavaScript学习记录6

第一节 算数运算符

1. 概述

JavaScript 共提供10个算术运算符,用来完成基本的算术运算。
  • 加法运算符x + y
  • 减法运算符 x - y
  • 乘法运算符 x * y
  • 除法运算符x / y
  • 指数运算符x ** y
  • 余数运算符x % y
  • 自增运算符++x  、x++
  • 自减运算符--x  、x--
  • 数值运算符 +x
  • 负数值运算符-x
减法、乘法、除法运算法比较单纯,就是执行相应的数学运算。下面介绍其他几个算术运算符,重点是加法运算符。

2. 加法运算符

2.1 基本规则

加法运算符( +)是最常见的运算符,用来求两个数值的和。
1 + 1 // 2
JavaScript 允许非数值的相加。
true + true // 2
1 + true // 2
上面代码中,第一行是两个布尔值相加,第二行是数值与布尔值相加。这两种情况,布尔值都会自动转成数值,然后再相加。
比较特殊的是,如果是两个字符串相加,这时加法运算符会变成连接运算符,返回一个新的字符串,将两个原字符串连接在一起。
'a' + 'bc' // "abc"
如果一个运算子是字符串,另一个运算子是非字符串,这时非字符串会转成字符串,再连接在一起。
1 + 'a' // "1a"
false + 'a' // "falsea"
加法运算符是在运行时决定,到底是执行相加,还是执行连接。也就是说,运算子的不同,导致了不同的语法行为,这种现象称为“重载”(overload)。由于加法运算符存在重载,可能执行两种运算,使用的时候必须很小心。
'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"
上面代码中,由于从左到右的运算次序,字符串的位置不同会导致不同的结果。
除了加法运算符,其他算术运算符(比如减法、除法和乘法)都不会发生重载。它们的规则是:所有运算子一律转为数值,再进行相应的数学运算。
1 - '2' // -1
1 * '2' // 2
1 / '2' // 0.5
上面代码中,减法、除法和乘法运算符,都是将字符串自动转为数值,然后再运算。

2.2 对象的相加

如果运算子是对象,必须先转成原始类型的值,然后再相加。
var obj = { p: 1 };
obj + 2 // "[object Object]2"
上面代码中,对象 obj转成原始类型的值是 [object Object],再加 2就得到了上面的结果。
对象转成原始类型的值,规则如下。
首先,自动调用对象的 valueOf方法。
var obj = { p: 1 };
obj.valueOf() // { p: 1 }
一般来说,对象的 valueOf方法总是返回对象自身,这时再自动调用对象的 toString方法,将其转为字符串。
var obj = { p: 1 };
obj.valueOf().toString() // "[object Object]"
对象的 toString方法默认返回 [object Object],所以就得到了最前面那个例子的结果。
知道了这个规则以后,就可以自己定义 valueOf方法或 toString方法,得到想要的结果。
var obj = {valueOf: function () {return 1;}
};obj + 2 // 3
上面代码中,我们定义 obj对象的 valueOf方法返回 1,于是 obj + 2就得到了 3。这个例子中,由于 valueOf方法直接返回一个原始类型的值,所以不再调用 toString方法。
下面是自定义 toString方法的例子。
var obj = {toString: function () {return 'hello';}
};obj + 2 // "hello2"
上面代码中,对象 objtoString方法返回字符串 hello。前面说过,只要有一个运算子是字符串,加法运算符就变成连接运算符,返回连接后的字符串。
这里有一个特例,如果运算子是一个 Date对象的实例,那么会优先执行 toString方法。
var obj = new Date();
obj.valueOf = function () { return 1 };
obj.toString = function () { return 'hello' };obj + 2 // "hello2"
上面代码中,对象 obj是一个 Date对象的实例,并且自定义了 valueOf方法和 toString方法,结果 toString方法优先执行。

3. 余数运算符

余数运算符( %)返回前一个运算子被后一个运算子除,所得的余数。
12 % 5 // 2
需要注意的是,运算结果的正负号由第一个运算子的正负号决定。
-1 % 2 // -1
1 % -2 // 1
所以,为了得到负数的正确余数值,可以先使用绝对值函数。
// 错误的写法
function isOdd(n) {return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false// 正确的写法
function isOdd(n) {return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false
余数运算符还可以用于浮点数的运算。但是,由于浮点数不是精确的值,无法得到完全准确的结果。
6.5 % 2.1
// 0.19999999999999973

4. 自增和自减运算符

自增和自减运算符,是一元运算符,只需要一个运算子。它们的作用是将运算子首先转为数值,然后加上1或者减去1。它们会修改原始变量。
var x = 1;
++x // 2
x // 2--x // 1
x // 1
上面代码的变量 x自增后,返回 2,再进行自减,返回 1。这两种情况都会使得,原始变量 x的值发生改变。
运算之后,变量的值发生变化,这种效应叫做运算的副作用(side effect)。自增和自减运算符是仅有的两个具有副作用的运算符,其他运算符都不会改变变量的值。
自增和自减运算符有一个需要注意的地方,就是放在变量之后,会先返回变量操作前的值,再进行自增/自减操作;放在变量之前,会先进行自增/自减操作,再返回变量操作后的值。
var x = 1;
var y = 1;x++ // 1
++y // 2
上面代码中, x是先返回当前值,然后自增,所以得到 1y是先自增,然后返回新的值,所以得到 2

5. 数值运算符,负数值运算符

数值运算符( +)同样使用加号,但它是一元运算符(只需要一个操作数),而加法运算符是二元运算符(需要两个操作数)。
数值运算符的作用在于可以将任何值转为数值(与 Number函数的作用相同)。
+true // 1
+[] // 0
+{} // NaN
上面代码表示,非数值经过数值运算符以后,都变成了数值(最后一行 NaN也是数值)。具体的类型转换规则
负数值运算符( -),也同样具有将一个值转为数值的功能,只不过得到的值正负相反。连用两个负数值运算符,等同于数值运算符。
var x = 1;
-x // -1
-(-x) // 1
上面代码最后一行的圆括号不可少,否则会变成自减运算符。
数值运算符号和负数值运算符,都会返回一个新的值,而不会改变原始变量的值。

6. 指数运算符

指数运算符( **)完成指数运算,前一个运算子是底数,后一个运算子是指数。
2 ** 4 // 16
注意,指数运算符是右结合,而不是左结合。即多个指数运算符连用时,先进行最右边的计算。
// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2
// 512
上面代码中,由于指数运算符是右结合,所以先计算第二个指数运算符,而不是第一个。

7. 赋值运算符

赋值运算符(Assignment Operators)用于给变量赋值。
最常见的赋值运算符,当然就是等号( =)。
// 将 1 赋值给变量 x
var x = 1;// 将变量 y 的值赋值给变量 x
var x = y;
赋值运算符还可以与其他运算符结合,形成变体。下面是与算术运算符的结合。
// 等同于 x = x + y
x += y// 等同于 x = x - y
x -= y// 等同于 x = x * y
x *= y// 等同于 x = x / y
x /= y// 等同于 x = x % y
x %= y// 等同于 x = x ** y
x **= y
下面是与位运算符的结合
// 等同于 x = x >> y
x >>= y// 等同于 x = x << y
x <<= y// 等同于 x = x >>> y
x >>>= y// 等同于 x = x & y
x &= y// 等同于 x = x | y
x |= y// 等同于 x = x ^ y
x ^= y
这些复合的赋值运算符,都是先进行指定运算,然后将得到值返回给左边的变量。

第二节 比较运算符

1. 概述

比较运算符用于比较两个值的大小,然后返回一个布尔值,表示是否满足指定的条件。
2 > 1 // true
上面代码比较 2是否大于 1,返回 true
注意,比较运算符可以比较各种类型的值,不仅仅是数值。
JavaScript 一共提供了8个比较运算符。
  • <= 
  • >= 
  • == 
  • === 
  • != 
  • !== 
这八个比较运算符分成两类:相等比较和非相等比较。两者的规则是不一样的,对于非相等的比较,算法是先看两个运算子是否都是字符串,如果是的,就按照字典顺序比较(实际上是比较 Unicode 码点);否则,将两个运算子都转成数值,再比较数值的大小。

2. 非相等运算符:字符串的比较

字符串按照字典顺序进行比较。
'cat' > 'dog' // false
'cat' > 'catalog' // false
JavaScript 引擎内部首先比较首字符的 Unicode 码点。如果相等,再比较第二个字符的 Unicode 码点,以此类推。
'cat' > 'Cat' // true'
上面代码中,小写的 c的 Unicode 码点( 99)大于大写的 C的 Unicode 码点( 67),所以返回 true
由于所有字符都有 Unicode 码点,因此汉字也可以比较。
'大' > '小' // false
上面代码中,“大”的 Unicode 码点是22823,“小”是23567,因此返回 false

3. 非相等运算符:非字符串的比较

如果两个运算子之中,至少有一个不是字符串,需要分成以下两种情况。
(1)原始类型值
如果两个运算子都是原始类型的值,则是先转成数值再比较。
5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 02 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1
上面代码中,字符串和布尔值都会先转成数值,再进行比较。
这里需要注意与 NaN的比较。任何值(包括 NaN本身)与 NaN使用非相等运算符进行比较,返回的都是 false
1 > NaN // false
1 <= NaN // false
'1' > NaN // false
'1' <= NaN // false
NaN > NaN // false
NaN <= NaN // false
(2)对象
如果运算子是对象,会转为原始类型的值,再进行比较。
对象转换成原始类型的值,算法是先调用 valueOf方法;如果返回的还是对象,再接着调用 toString方法
var x = [2];
x > '11' // true
// 等同于 [2].valueOf().toString() > '11'
// 即 '2' > '11'x.valueOf = function () { return '1' };
x > '11' // false
// 等同于 (function () { return '1' })() > '11'
// 即 '1' > '11'
两个对象之间的比较也是如此。
[2] > [1] // true
// 等同于 [2].valueOf().toString() > [1].valueOf().toString()
// 即 '2' > '1'[2] > [11] // true
// 等同于 [2].valueOf().toString() > [11].valueOf().toString()
// 即 '2' > '11'({ x: 2 }) >= ({ x: 1 }) // true
// 等同于 ({ x: 2 }).valueOf().toString() >= ({ x: 1 }).valueOf().toString()
// 即 '[object Object]' >= '[object Object]'

4. 严格相等运算符

JavaScript 提供两种相等运算符: =====
简单说,它们的区别是相等运算符( ==)比较两个值是否相等,严格相等运算符( ===)比较它们是否为“同一个值”。如果两个值不是同一类型,严格相等运算符( ===)直接返回 false,而相等运算符( ==)会将它们转换成同一个类型,再用严格相等运算符进行比较。
本节介绍严格相等运算符的算法。
(1)不同类型的值
如果两个值的类型不同,直接返回 false
1 === "1" // false
true === "true" // false
上面代码比较数值的 1与字符串的“1”、布尔值的 true与字符串 "true",因为类型不同,结果都是 false
(2)同一类的原始类型值
同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回 true,值不同就返回 false
1 === 0x1 // true
上面代码比较十进制的 1与十六进制的 1,因为类型和值都相同,返回 true
需要注意的是, NaN与任何值都不相等(包括自身)。另外,正 0等于负 0
NaN === NaN  // false
+0 === -0 // true
(3)复合类型值
两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个地址。
{} === {} // false
[] === [] // false
(function () {} === function () {}) // false
上面代码分别比较两个空对象、两个空数组、两个空函数,结果都是不相等。原因是对于复合类型的值,严格相等运算比较的是,它们是否引用同一个内存地址,而运算符两边的空对象、空数组、空函数的值,都存放在不同的内存地址,结果当然是 false
如果两个变量引用同一个对象,则它们相等。
var v1 = {};
var v2 = v1;
v1 === v2 // true
注意,对于两个对象的比较,严格相等运算符比较的是地址,而大于或小于运算符比较的是值。
var obj1 = {};
var obj2 = {};obj1 > obj2 // false
obj1 < obj2 // false
obj1 === obj2 // false
上面的三个比较,前两个比较的是值,最后一个比较的是地址,所以都返回 false
(4)undefined 和 null
undefinednull与自身严格相等。
undefined === undefined // true
null === null // true
由于变量声明后默认值是 undefined,因此两个只声明未赋值的变量是相等的。
var v1;
var v2;
v1 === v2 // true

5. 严格不相等运算符

严格相等运算符有一个对应的“严格不相等运算符”( !==),它的算法就是先求严格相等运算符的结果,然后返回相反值。
1 !== '1' // true
// 等同于
!(1 === '1')
上面代码中,感叹号 !是求出后面表达式的相反值。

6. 相等运算符

相等运算符用来比较相同类型的数据时,与严格相等运算符完全一样。
1 == 1.0
// 等同于
1 === 1.0
比较不同类型的数据时,相等运算符会先将数据进行类型转换,然后再用严格相等运算符比较。下面分成几种情况,讨论不同类型的值互相比较的规则。
(1)原始类型值
原始类型的值会转换成数值再进行比较。
1 == true // true
// 等同于 1 === Number(true)0 == false // true
// 等同于 0 === Number(false)2 == true // false
// 等同于 2 === Number(true)2 == false // false
// 等同于 2 === Number(false)'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1'' == 0 // true
// 等同于 Number('') === 0
// 等同于 0 === 0'' == false  // true
// 等同于 Number('') === Number(false)
// 等同于 0 === 0'1' == true  // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 1'\n  123  \t' == 123 // true
// 因为字符串转为数字时,省略前置和后置的空格
上面代码将字符串和布尔值都转为数值,然后再进行比较。
(2)对象与原始类型值比较
对象(这里指广义的对象,包括数组和函数)与原始类型的值比较时,对象转换成原始类型的值,再进行比较。
具体来说,先调用对象的 valueOf()方法,如果得到原始类型的值,就按照上一小节的规则,互相比较;如果得到的还是对象,则再调用 toString()方法,得到字符串形式,再进行比较。
下面是数组与原始类型值比较的例子。
// 数组与数值的比较
[1] == 1 // true// 数组与字符串的比较
[1] == '1' // true
[1, 2] == '1,2' // true// 对象与布尔值的比较
[1] == true // true
[2] == true // false
上面例子中,JavaScript 引擎会先对数组 [1]调用数组的 valueOf()方法,由于返回的还是一个数组,所以会接着调用数组的 toString()方法,得到字符串形式,再按照上一小节的规则进行比较。
下面是一个更直接的例子。
const obj = {valueOf: function () {console.log('执行 valueOf()');return obj;},toString: function () {console.log('执行 toString()');return 'foo';}
};obj == 'foo'
// 执行 valueOf()
// 执行 toString()
// true
上面例子中, obj是一个自定义了 valueOf()toString()方法的对象。这个对象与字符串 'foo'进行比较时,会依次调用 valueOf()toString()方法,最后返回 'foo',所以比较结果是 true
(3)undefined 和 null
undefinednull只有与自身比较,或者互相比较时,才会返回 true;与其他类型的值比较时,结果都为 false
undefined == undefined // true
null == null // true
undefined == null // truefalse == null // false
false == undefined // false0 == null // false
0 == undefined // false
(4)相等运算符的缺点
相等运算符隐藏的类型转换,会带来一些违反直觉的结果。
0 == ''             // true
0 == '0'            // true2 == true           // false
2 == false          // falsefalse == 'false'    // false
false == '0'        // truefalse == undefined  // false
false == null       // false
null == undefined   // true' \t\r\n ' == 0     // true
上面这些表达式都不同于直觉,很容易出错。因此建议不要使用相等运算符( ==),最好只使用严格相等运算符( ===)。

7. 不相等运算符

相等运算符有一个对应的“不相等运算符”( !=),它的算法就是先求相等运算符的结果,然后返回相反值。
1 != '1' // false// 等同于
!(1 == '1')

相关文章:

JavaScript学习记录6

第一节 算数运算符 1. 概述 JavaScript 共提供10个算术运算符&#xff0c;用来完成基本的算术运算。 加法运算符x y减法运算符 x - y乘法运算符 x * y除法运算符x / y指数运算符x ** y余数运算符x % y自增运算符x 、x自减运算符--x 、x--数值运算符 x负数值运算符-x 减法、…...

如何在没有 iCloud 的情况下将数据从 iPhone 传输到 iPhone

概括 您可能会遇到将数据从 iPhone 转移到 iPhone 的情况&#xff0c;尤其是当您获得新的 iPhone 15/14 时&#xff0c;您会很兴奋并希望将数据转移到它。 使用iCloud最终可以做到这一点&#xff0c;但它的缺点也不容忽视&#xff0c;阻碍了你选择它。例如&#xff0c;您需要…...

Doris安装部署

Doris 概述 Apache Doris由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018年贡献到 Apache 社区后&#xff0c;更名为 Doris &#xff09;&#xff0c;在百度内部&#xff0c;有超过200个产品线在使用&#xff0c;部署机器超过1000台&#xff0c;单一业务最大可…...

[服务器][教程]Ubuntu24.04 Server开机自动挂载硬盘教程

1. 查看硬盘ID ls -l /dev/disk/by-uuid可以看到对应的UUID所对应的分区 2. 创建挂载文件夹 创建好文件夹即可 3. 修改配置文件 sudo vim /etc/fstab把对应的UUID和创建的挂载目录对应即可 其中# Personal mount points下面的是自己新添加的 &#xff1a;分区定位&#xff…...

io多路复用, select, poll, epoll

系列文章目录 异步I/O操作函数aio_xxx函数 https://blog.csdn.net/surfaceyan/article/details/134710393 文章目录 系列文章目录前言一、5种IO模型二、IO多路复用APIselectpollepoll 三、两种高效的事件处理模式Reactor模式Proactor模式模拟 Proactor 模式基于事件驱动的非阻…...

k8s-1.28.2 部署prometheus

一、prometheus helm仓库 ## 网站地址 # https://artifacthub.io/## prometheus 地址 # https://artifacthub.io/packages/helm/prometheus-community/prometheus. # helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # helm repo …...

记录第一次跑YOLOV8做目标检测

今天是24年的最后一天&#xff0c;终于要向新世界开始破门了&#xff0c;开始深度学习&#xff0c;YOLO来敲门~ 最近做了一些皮肤检测的功能&#xff0c;在传统的处理中经历了反复挣扎&#xff0c;终于要上YOLO了。听过、看过&#xff0c;不如上手体会过~ 1、YOLO是什么&#x…...

使用Python爬取BOSS直聘职位数据并保存到Excel

使用Python爬取BOSS直聘职位数据并保存到Excel 在数据分析和挖掘中&#xff0c;爬取招聘网站数据是一项常见的任务。本文将详细介绍如何使用Python爬取BOSS直聘上与“测试工程师”相关的职位数据&#xff0c;并将其保存到Excel文件中。通过逐步分解代码和添加详细注释&#xf…...

node.js之---集群(Cluster)模块

为什么会有集群&#xff08;Cluster&#xff09;模块&#xff1f; 集群&#xff08;Cluster&#xff09;模块的作用 如何使用集群&#xff08;Cluster&#xff09;模块&#xff1f; 为什么会有集群&#xff08;Cluster&#xff09;模块 Node.js 是基于 单线程事件驱动 模型的…...

SSM-Spring-IOC/DI对应的配置开发

目录 一、IOC 控制反转 1.什么是控制反转呢 2. Spring和IOC之间的关系是什么呢? 3.IOC容器的作用以及内部存放的是什么? 4.当IOC容器中创建好service和dao对象后&#xff0c;程序能正确执行么? 5.Spring 容器管理什么内容&#xff1f; 6.如何将需要管理的对象交给 …...

一文大白话讲清楚CSS元素的水平居中和垂直居中

文章目录 一文大白话讲清楚CSS元素的水平居中和垂直居中1.已知元素宽高的居中方案1.1 利用定位margin:auto1.2 利用定位margin负值1.3 table布局 2.未知元素宽高的居中方案2.1利用定位transform2.2 flex弹性布局2.3 grid网格布局 3. 内联元素的居中布局 一文大白话讲清楚CSS元素…...

航顺芯片推出HK32A040方案,赋能汽车矩阵大灯安全与智能化升级

汽车安全行驶对整车照明系统的要求正在向智能化方向发展。车灯位于汽车两侧&#xff0c;前期有各种各样的实现包括氙气灯、LED灯等等光源技术。矩阵大灯对汽车照明系统朝着安全性和智能化兼具的方向发展起到了重要推动作用。矩阵大灯可以精细控制到每一个小灯珠&#xff0c;从而…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之12 方案再探:特定于领域的模板 之2 首次尝试和遗留问题解决

本文提要 现在就剩下“体”本身的 约定了--这必然是 自律自省的&#xff0c;或者称为“戒律” --即“体”的自我训导discipline。完整表述为&#xff1a; 严格双相的庄严“相” (<head>侧&#xff09;&#xff0c;完全双性的本质“性”&#xff08;<boot>侧&…...

redis zset底层实现

1.Redis zset底层实现 转载自&#xff1a;https://marticles.github.io/2019/03/19/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Redis-Zset%E5%8E%9F%E7%90%86/ zset底层是压缩列表 跳表实现的。 跳表里面又由字典hash表 跳表实现。 什么时候用压缩列表&#xff1f;什么时候用…...

go.Bar如何让hovertext显示为legend

在 Plotly 的 go.Bar 图中&#xff0c;如果你想让鼠标悬停时 (hover) 显示的文本 (hovertext) 与图例 (legend) 一致&#xff0c;可以通过 hovertemplate 来控制悬停时的显示内容。 实现方法 hovertemplate 是一种自定义工具&#xff0c;允许你完全控制悬停时的文本显示格式。…...

【Vue】分享一个快速入门的前端框架以及如何搭建

先上效果图: 登录 菜单: 下载地址: 链接&#xff1a;https://pan.baidu.com/s/1m-ZlBARWU6_2n8jZil_RAQ 提取码&#xff1a;ui20 … 主要是可以自定义设置token,更改后端请求地址较为方便。 应用设置: 登录与token设置: 在这里设置不用登录,可以请求的接口: request.js i…...

Flink源码解析之:如何根据JobGraph生成ExecutionGraph

Flink源码解析之&#xff1a;如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中&#xff0c;我们介绍了Flink如何根据StreamGraph生成JobGraph的流程&#xff0c;并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…...

UE(虚幻)学习(三) UnrealSharp插件中调用非托管DLL

上一篇文章中我使用UnrealSharp成功使用了我的一个C#控制台程序中的网络模块&#xff0c;这个程序是基于KCP网络了&#xff0c;其中调用了Cmake 编译的一个C的DLL&#xff0c;在虚幻中DLL需要放在Binaries目录中才可以。Unity中只要放在任意Plugins目录中就可以。 但是Binaries…...

leetcode 3219. 切蛋糕的最小总开销 II

题目&#xff1a;3219. 切蛋糕的最小总开销 II - 力扣&#xff08;LeetCode&#xff09; 排序贪心。 开销越大的越早切。 注意m或n为1的情况。 class Solution { public:long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>&…...

vant 地址记录

vant ui 的官网地址记录 vant 4 Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. vant2 https://vant-ui.github.io/vant/v2/ vant3 Vant 3 - Lightweight Mobile UI Components built on Vue...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...