文章目录

  • 1. Kotlin 有哪些可用的列表
    • 1.1 使用持久数据结构
    • 1.2 实现不可变的、持久的单链表
  • 2. 列表操作中的数据共享
    • 2.1 使用递归对具有高阶函数的列表进行折叠
    • 2.2 使用型变
    • 2.3 创建 foldRight 的栈安全递归的版本
  • 3. 小结

1. Kotlin 有哪些可用的列表

Kotlin 提供 可变、不可变列表。 在 Java 中也支持,但是得益于 Kotlin 的扩展函数特性, 列表拥有了大量增强性能的函数。

  • 可变列表
    像 Java 列表一样,可以通过添加、插入或者删除元素来改变列表, 这样一来,列表的早期版本将会丢失
  • 不可变列表
    又称只读列表,不能被修改的列表。 如果向其添加一个元素,则会创建一个添加了新元素的原始列表的副本。不可变列表的思想是避免数据就地更新,是一种防御拷贝的技术,可以防止其他线程的并发突变

本篇重点的学习都是在不可变列表 上,因为它避免就地更新的优点,体现了编程中数据不可变的原则,是一种出于安全编程考虑更优的列表选择。

但是它是有局限性的,争议点主要是在添加元素上:

  • 如果使用添加的元素,来创建列表的新副本是 一个耗时且栈内存的过程,则不可变的数据结构是会导致性能低下

这个观点确实是正确的,因为每次修改列表,就需要面对一个完整的数据结构,并将其复制。 这也是 Kotlin 不可变列表的情况。但是也有解决的办法,我们下面就是来解决这些问题。

为了处理不可变持久化列表,Kotlin 创建了很多高性能的函数, 我们可以通过学习这些函数,来了解高效的思想。

1.1 使用持久数据结构

这里的持久数据结构并不是指 SharedPreferences 这种持久化技术, 而是一种提高列表性能的技术。

对于不可变列表,在插入元素之前复制数据结构是一项耗时的操作,这会导致性能低下,但是如果使用了 数据共享(data sharing) 则会优化这种操作。

下图就展示了如果删除、添加元素,以创建一个新的具有最佳新能的不可变单链表:
在这里插入图片描述
上图中的过程中,没有数据复制发生,这样的列表对于删除和插入元素可能比可变列表更高效,但是实际上还要看情况而定的。

1.2 实现不可变的、持久的单链表

上图的单链表结构是理论上的,列表无法实现这种形式,因为元素之间无法连接。但是我们可以通过定义递归的数据结构来设计一个单链表。对列表结构定义如下:

  1. 将列表的第一个元素,称为头元素
  2. 列表的其余部分,本身就是列表,称为尾部
  3. 空列表表示 Nil ,既没有头部也没有尾部

使用密封类,因为它是隐私抽象的,而且能限制不被他人继承,只用定义我们想要的结构就好:

sealed class List<A> {abstract fun isEmpty(): Boolean// 扩展类在列表类内定义,并成为私有类private object Nil : List<Nothing>() {override fun isEmpty(): Boolean = trueoverride fun toString(): String = "[NIL]"}private class Cons<A>(internal val head: A,internal val tail: List<A>): List<A>() {override fun isEmpty(): Boolean = falseoverride fun toString(): String = "[${toString("", this)}NIL]"tailrec fun toString(acc: String, list: List<A>): String = when(list) {is Nil -> accis Cons -> toString("$acc${list.head}, ", list.tail)}}companion object {// foldRight 的第一个参数是将 Nil 显示转化为 list<A>operator fun <A> invoke(vararg az: A): List<A> =az.foldRight(Nil as List<A>) { a, acc ->// 使用反向递归从后包到前Cons(a, acc)}}
}

接下来就可以直接使用:

val list = MyList("a","b","c","d","e")
print(list)
// 打印
[a, b, c, d, e, NIL]

2. 列表操作中的数据共享

使用单链表的一个巨大好处,就是数据共享带来的性能提升, 例如访问列表的第一个元素、删除一个元素等。下面将举几个例子。

1. 添加头元素
我们来实现一个函数 cons(), 在列表的开头添加元素,答案很简单,我们其实在前面就已经实现了:

fun cons(a: A): MyList<A> = Cons(a, this)

2. 设置头元素
接下来,实现一个函数 setHead, 一个用新值替换 List 的第一个元素的函数,其实就是对第一个元素的尾部设置头元素:

    fun setHead(a: A): MyList<A> = when(this) {Nil -> throw IllegalStateException("setHead called on an empty list")is Cons -> tail.cons(a)}

3. 删除前n个元素
现在需要在不改变或创建任何内容的情况下删除列表的前n个元素:

    // 这里使用共递归优化堆栈,并且对类型做判断fun drop(n: Int): MyList<A> {tailrec fun drop(n: Int, list: MyList<A>): MyList<A> =if (n <= 0) listelse when (list) {is Cons -> drop(n - 1, list.tail)is Nil -> list}return drop(n, this)}

4. 从头删除元素直到条件为false
我们可以把辅助函数放到伴生对象中,这样可以使得内部其他地方也可以访问辅助函数,增强重用性。 但是不放也行,视情况而定,取决于代码风格或需求:

    fun dropWhile(p: (A) -> Boolean): MyList<A> = dropWhile(this, p)companion object {private tailrec fun <A> dropWhile(list: MyList<A>, p: (A) -> Boolean): MyList<A> = when (list) {Nil -> listis Cons -> if (p(list.head)) dropWhile(list.tail, p) else list}}

5. 连接列表
列表上的常见操作包括向另一个列表添加一个列表,形成包含两个列表所有元素的新表。
两个列表无法直接连接,但是可以通过将 前面列表的尾部元素 作为后面列表的头部元素,递归到前面列表的最前面,就可以得到新列表。如下图所示:
在这里插入图片描述
可以看到,列表1、2都被保留了,结果列表共享了列表2,由于我们要从尾巴访问列表1,所以可以使用递归的形式
代码如下:

    fun concat(list: MyList<A>): MyList<A> = concat(this, list)companion object {private fun <A> concat(list1: MyList<A>, list2: MyList<A>): MyList<A> = when (list1) {Nil -> list2is Cons -> concat(list1.tail, list2).cons(list1.head)}}    

这种写法的缺点是,函数本身的复杂度是依赖 list1 的长度的,如果list1过长,会爆栈,由于连接列表是一个比较常规的操作,所以它还有更进一步的抽象空间,我们会在下面学习到。

6. 从列表末尾删除元素
虽然单链表不是这种操作的理想数据结构,但仍然能够实现它。
这里将 函数命名为 init , 而不是 dropLast,为什么这样命名,是遵循哈斯卡尔的风格:wiki:
在这里插入图片描述
我们可以通过反转列表去删除第一个再反转列表,代码如下:

   fun reverse(): MyList<A> {tailrec fun <A> reverse(acc: MyList<A>, list: MyList<A>): MyList<A> = when(list) {Nil -> accis Cons -> reverse(acc.cons(list.head), list.tail)}return reverse(MyList.invoke(), this)}fun init(): MyList<A> = reverse().drop(1).reverse()

这是 Cons 类的实现, 在 Nil 类,init 函数会抛出异常。

2.1 使用递归对具有高阶函数的列表进行折叠

之前有学习过对列表进行折叠, 折叠同样也适用于持久化列表,对对于可变列表,可以选择通过迭代或递归实现操作。而对于持久化列表却不适合这种迭代方法,接下来考虑对数字列表进行常见的折叠操作。

下面编写一个函数,使用递归计算持久化整数列表中所有元素的和。

    fun sum(ints: MyList<Int>): Int = when (ints) {Nil -> 0is Cons -> ints.head + sum(ints.tail)}

但这是不会通过编译的,因为 Nil 不是 MyList<Int> 的子类型

2.2 使用型变

上面遇到的问题是 ,尽管 Nothing 类型是所有类型的子类型, 始终可以将 Nothing 向其它任何类型转化,但是不能将 MyList<Nothing> 强制转化成 List<Int>,这是因为 Java 的机制。

不过 Kotlin 提供了协变,我们要使 泛型A 在 MyList 中协变, 这就意味着需要声明其为 MyList<out A>

sealed class MyList<out A> {...
}

但是这样会引来报错:
在这里插入图片描述
使用协变后, 意味着 MyList 类不能所包含具有 类型A 入参的函数, 参数是函数的输入,所以它在 “in” 的位置,函数的返回则是 out 的位置。深入了解可以看这篇文章:深入理解Kotlin中的泛型(协变、逆变)

使用了协变后,我们不能在 in 的位置使用泛型A, 那这样我们可能就会认为很不合理或者疑惑:那我们该怎么样向 MyList 汇总添加元素呢?

假如我们实现一个抽象方法,并让每个子类来继承:

sealed class MyList<out A> {abstract fun cons(a: A): MyList<A>internal object Nil : MyList<Nothing>() {..override fun cons(a: Nothing): MyList<Nothing> = Cons(a, this)}internal class Cons<out A>() : MyList<A>() {...}

会出现两种问题:

  • cons 函数不能在 in 位置使用泛型A,编译不通过, 是前面已经遇到的
  • Nil 类的 cons 函数被编译器标记为 Unrechable code, 即不可访问的函数。 这是因为 Nil 类中的 this 引用了一个 MyList<Nothing>,假设调用了 Nil.cons(1) 将导致 1 强制转化为 Nothing, 这是不可行的,因为 Nothing 是 Int 的子类型

要理解 Nil 中发生了什么, 必须记住 Kotlin 是一门严格的语言,这意味着无论是否使用函数参数,都要对他们进行检查。

上面的主要的问题出现在了函数的参数, 即 override fun cons(a: Nothing), 当函数接收到 A 参数时,它会立即强制转化为接受者的参数类型 Nothing ,这会导致错误。 紧接着,元素就会被添加到一个 MyList<A> 中。我们不需要将参数向下强制转化为 Nothing,所以为了解决这个问题,技巧是:

  1. 可以使用 @unsafevariance 注释,通过 in 位置使用 A 来避免编译报错:
abstract fun cons(a: @UnsafeVariance A): MyList<A>
  1. 通过将实现放在父类中,避免向下强制转化:
    fun cons(a: @UnsafeVariance A): MyList<A> = Cons(a, this)

这是告诉编译器,无需担心 cons 函数中的型变问题,出了问题由编程者来处承担。现在可以对 setHead、concat 函数使用这个注解:

fun setHead(a: @UnsafeVariance A)..
fun concat(list: MyList<@UnsafeVariance A>)...

这样我们有了更大的自由,但是责任也更大了,我们要确保使用这个技巧时,任何不安全的转换都不会失败。

此外,还有一种情况,就是创建一个 Empty<A> 抽象类来表示空列表, 然后创建一个 Nil<Nothing> 单例对象。可以在 父类 MyList 中定义抽象函数, Cons 或 Empty 中具体实现, 例如这样:

sealed class EmptyMyList<A> {fun cons(a: A): EmptyMyList<A> = Cons(a, this)abstract class Empty<A> : EmptyMyList<A>() {}object Nil: Empty<Nothing>() {}class Cons<A>(...) : EmptyMyList<A>()fun concat(list: EmptyMyList<A>): EmptyMyList<A> = concat(this, list)companion object {private fun <A> concat(list1: EmptyMyList<A>, list2: EmptyMyList<A>): EmptyMyList<A> = when (list1) {Nil -> list2is Cons -> concat(list1.tail, list2).cons(list1.head)}}
}

这样 concat 函数就会报错
在这里插入图片描述
这个时候因为考虑 Empty 是抽象类,为了避免类型检查,我们就需要使用多态的形式来实现 concat 函数了:

    object Nil: Empty<Nothing>() {override fun funconcat(list: EmptyMyList<Nothing>): EmptyMyList<Nothing> = list}class Cons<A>() : EmptyMyList<A>() {override fun funconcat(list: EmptyMyList<A>): EmptyMyList<A> = Cons(this.head, list.concat(this.tail))}

下面继续来编写几个函数。

7. 编写函数使用递归计算双精度列表中所有元素的乘积
空列表的乘积元素应该是1, 就和 sum 累加元素中的0是一样的。代码如下所示:

    private fun product(ints: MyList<Double>): Double = when (ints) {Nil -> 1.0is Cons -> ints.head * product(ints.tail)}

现在来看看 sum 和 product 的定义,我们能够抽出一个抽象的模型公式吗? 他们函数如下:

fun product(ints: MyList<Double>): Double ... 上面的fun sum(ints: MyList<Int>): Int = when (ints) {MyList.Nil -> 0is MyList.Cons -> ints.head + sum(ints.tail)
}

我们先消除他们的差异,用一个通用符号来替换:

fun product(ints: MyList<Type>): Type = when (ints) {MyList.Nil -> identityis MyList.Cons -> ints.head operator operation(ints.tail)
}fun sum(ints: MyList<Type>): Type = when (ints) {MyList.Nil -> identityis MyList.Cons -> ints.head operator operation(ints.tail)
}

这两个函数的 Type、operation、 identity、operator 的值有所不同,如果能找到一种方法来抽象这些公共部分,那么必须提供变量信息,以便在不重复的情况下实现这两个函数值。 这个常见的操作就是折叠(fold),之前也有学习过。下面实现一个 foldRight 并将其应用于求和与求积:

fun <A, B> foldRight(list: MyList<A>, identity: B, f: (A) -> (B) -> B): B =when (list) {MyList.Nil -> identityis MyList.Cons -> f(list.head)(foldRight(list.tail, identity, f))}fun sum(list: MyList<Int>): Int = foldRight(list, 0) { x -> { y -> x + y } }
fun product(list: MyList<Double>): Double = foldRight(list, 1.0) { x -> { y -> x * y } }

因为结果与输入元素的类型相同, 所以这种情况下, 应该被称为 减少(reduce) , 而不是 折叠(fold)。 我们可以将 foldRight 函数放在伴生对象中,然后添加一个函数为参数的实例函数,该函数在 MyList 类中调用 foldRight:

class MyList{
...
fun <B> foldRight(identity: B, f: (A) -> (B) -> B): B = foldRight(this, identity, f)

8. 编写一个函数,来计算列表长度, 使用 foldRight 函数

// 没有用到的第一个参数是可以省略的
fun length(): Int = foldRight(0) { { it + 1 } }

由于 foldRight 是递归的而非尾递归的,所以可能会有爆栈的情况,我们需要优化成在恒定时间内获取列表的长度,所以需要使用性能更优的 foldLeft 函数。

        tailrec fun <A, B> foldLeft(acc: B, list:MyList<A>, f: (B) -> (A) -> B): B = when(list) {Nil -> accis Cons -> foldLeft(f(acc)(list.head), list.tail, f)}...fun <B> foldLeft(identity: B, f: (B) -> (A) -> B): B = foldLeft(identity, this, f)

好的,这样我们来使用 foldLeft 来把 sum、 product、length、reverse、foldRight 优化成新的栈安全的版本:

fun sum(list: MyList<Int>): Int = list.foldLeft(0) { x -> { y -> x + y } }
fun product(list: MyList<Double>): Double = list.foldLeft(1.0) { x -> { y -> x * y } }
fun length(): Int = foldLeft(0) { i -> { i + 1 } }
fun reverse(): MyList<A> = foldLeft(invoke()) { acc -> { acc.cons(it) } }
fun <B> foldRightViaFoldLeft(identity: B, f: (A) -> (B) -> B) = this.reverse().foldLeft(identity) { x -> { y -> f(y)(x) } }

2.3 创建 foldRight 的栈安全递归的版本

之前说的 foldRight 的实现是基于栈的,不应该在实际项目中实现,性能不够优秀, 那我们是否可以优化成共递归的版本,并且不显示的使用 foldLeft 呢? 答案是可以的。

我们可以使用反转列表来处理:

// 在伴生对象中编写辅助函数,在 List 类中编写主函数private tailrec fun <A, B> coFoldRight(acc: B, list: MyList<A>, identity: B, f: (A) -> (B) -> B): B =when (list) {Nil -> accis Cons -> coFoldRight(f(list.head)(acc), list.tail, identity, f)}....fun <B> coFoldRight(identity: B, f: (A) -> (B) -> B): B = coFoldRight(identity, this.reverse(), identity, f)

但这种做法是有缺陷的,它强制处理了列表(反转),这掩盖了向右折叠的优点

9. 根据 foldLeft 或 foldRight 来实现 concat
通过 foldRight 我们可以轻松实现:

    fun <A> concatViaFoldRight(list1: MyList<A>, list2: MyList<A>): MyList<A> =foldRight(list1, list2, { x -> { y -> Cons(x, y) } })

而 foldLeft 则要反转列表,实现效率比较低:

    fun <A> concatViaLeft(list1: MyList<A>, list2: MyList<A>): MyList<A> =list1.reverse().foldLeft(list2) { x -> x::cons }
// 上面 { x -> x::cons } 等价于: { x -> { y -> x.cons(y) } }

10. 编写一个函数, 将一个列表组扁平化为包含每个子类表所有元素的列表
使用 foldRight 来实现也很轻松:

fun <A> flatten(list: MyList<A>): MyList<A> = list.foldRight(Nil) { x -> x::concat }

3. 小结

  1. 通过自定义一个单链表的数据结构,了解列表操作,如 sum、product、length、reverse等等
  2. 单链表是一个高效的数据结构,具有不可变列表的有点,同时允许修改,因为列表不可变,所以性能有所提高
  3. 可以通过递归引用函数来折叠列表
  4. 使用共递归处理列表,不会有栈溢出的风险
  5. 一旦定义了 foldLeft、foldRight 就不需要再次使用递归来处理列表了,因为它们已经抽象了递归。
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 项目出现循环依赖的解决方案

    在注入的bean上面添加Lazy注解既可解决 import org.springframework.context.annotation.Lazy; Autowired Lazy private DirectoryService directoryService ;...

    2024/4/13 2:24:38
  2. 一级建造师考哪个专业好?

    一建有哪些专业 一级建造师目前分为10类专业方向&#xff1a;建筑工程、公路工程、水利水电工程、市政公用工程、矿业工程、机电工程、公路工程、铁路工程、通信与广电工程、港口与航道工程、民航机场工程。 从考试通过率看难度排名&#xff1a; 1.建筑&#xff1a;通过率较…...

    2024/4/13 2:24:13
  3. 2020年中国灾备市场需求强劲,多活数据中心成为发展趋势[图]

    灾备是指组织的灾难备援。在信息化的IT系统中&#xff0c;灾备是指在灾难未发生前&#xff0c;利用IT技术对信息系统的数据和应用程序进行保护&#xff0c;包括本地及异地的数据备份、应用和场所的接管等&#xff0c;确保系统遭受灾难时数据的安全&#xff0c;以及业务的快速恢…...

    2024/5/4 1:16:17
  4. 中国录音制品出版情况分析:2020年中国共出版录音制品5312种,出版数量共计12194.67万盒(张)[图]

    2020年中国共出版录音制品5312种&#xff0c;较2019年减少了1259种&#xff0c;同比减少19.16%&#xff0c;出版数量共计12194.67万盒&#xff08;张&#xff09;&#xff0c;较2019年减少了4737.26万盒&#xff08;张&#xff09;&#xff0c;同比减少27.98%。 2019-2020年中…...

    2024/4/13 2:24:33
  5. 动态规划(背包问题)---(韩顺平数据结构)笔记

    动态规划算法-背包问题 核心思想 将大问题划分为小问题进行解决&#xff0c;从而一步步获取最优解动态规划算法和分治算法类似&#xff0c;基本思想也是将待求解的问题分解为若干个子问题&#xff0c;然后从这些子问题的解得到原问题的解但是与分治算法不同的是&#xff0c;适…...

    2024/4/13 2:24:28
  6. window10+paddleseg+C++部署

    部署环境&#xff1a;VS2019cuda10.2cmake3.17.0 v2.0.0参考 兼容并包的PaddleX-Inference部署方式 按照官方步骤基于PaddleInference的推理-Windows环境编译下载paddleX和cuda10.2版本的paddle_inference.zip&#xff0c;将PaddleX中的cpp拷贝出来并新建build_out文件夹 将…...

    2024/4/13 2:24:28
  7. 2022年全球及中国半导体石英坩埚行业发展现状及市场竞争格局分析:预计2022年全球半导体石英坩埚需求将突破15亿元[图]

    一、全球市场 自2020年下半年以来&#xff0c;全球缺芯潮带动半导体行业景气度高涨&#xff0c;直接带动了行业对上游硅片需求增长&#xff0c;相继也带动了石英坩埚市场需求的的快速增长&#xff0c;2021年第二季度全球硅晶圆出货面积再创新高&#xff0c;达到3534百万平方英…...

    2024/4/13 2:24:13
  8. 全球及中国反射全息光栅行业发展态势及前景动态预测报告*2022-2027

    全球及中国反射全息光栅行业发展态势及前景动态预测报告*2022-2027 【报告编号】: BG417130 【出版时间】: 2022年2月 【出版机构】: 中智正业研究院 内容简介&#xff1a; 1 反射全息光栅市场概述 1.1 反射全息光栅行业概述及统计范围 1.2 按照不同产品类型&#xff0c;反射…...

    2024/4/20 9:27:22
  9. 最新jsp/java计算机程序设计选题(题目)(一)

    第一章&#xff08;1~~25&#xff09; &#xff08;java&#xff0c;jsp&#xff09;1.学籍管理系统 &#xff08;java&#xff0c;jsp&#xff09;2.Java远程通信及应用的研究 &#xff08;java&#xff0c;jsp&#xff09;3.JAVA游戏 &#xff08;java&#xff0c;jsp…...

    2024/4/19 22:20:20
  10. 基于NDT激光雷达里程计结果

    ...

    2024/4/13 2:24:38
  11. 三层交换

    目录 一、三层交换 1.1、三层交换是什么 1.2、单臂路由的缺陷 1.3、三层交换机的转发 1.3.1、三层交换的转发原理 二、三层交换的应用 2.1、三层交换的配置 一、三层交换 1.1、三层交换是什么 三层交换中的三层指的是OSI七层中的第三层&#xff0c;即网络层。网络层的核心设备…...

    2024/4/18 19:01:44
  12. VK3604A 4按键触摸触控芯片 多种输出方式选择:锁存/直接输出/CMOS输出或者开漏输出

    4通道触摸 1对1输出 型号&#xff1a;VK3604/VK3604A 品牌&#xff1a;VINKA/永嘉微电 封装形式&#xff1a;SOP16 年份&#xff1a;新年份 概述&#xff1a; VK3604/VK3604A具有4个触摸按键&#xff0c;可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的 集成度…...

    2024/4/18 4:58:10
  13. C语言实现广告拦截(广告杀手)

    这里以QQ的腾讯迷你版为拦截对象&#xff0c;项目我已经开源可以到gitee上查看 传送门...

    2024/4/13 4:06:20
  14. vue 点击背景色变色,

    <template><md-page class"zujianlb"><div class"header"><div class"wrap"><span style"float: left">分类</span><div class"total1" v-for"(item, index) in fenLei" …...

    2024/4/13 2:24:33
  15. GBase 8c 全文检索-处理文档(三)

    GBase 8c提供了用来操作tsvector类型的函数和操作符。 length(vector tsvector) returns integer 返回vector中的词素的数量。 strip(vector tsvector) returns tsvector 返回一个tsvector类型&#xff0c;其中包含输入的tsvector的同义词&#xff0c;但不包含任何位置和权…...

    2024/4/13 2:24:33
  16. Linux命令:whoami

    adb shell whoami --help...

    2024/4/20 1:22:16
  17. ES6映射

    8.ES6映射 特点&#xff1a;键名可以不是字符串 一&#xff1a;声明映射 let map new Map(); console.log(map); //Map(0) {}二&#xff1a;方法 1.增 书写方式&#xff1a;映射名.set(键名,键值); map.set("className","aa"); console.log(map); …...

    2024/4/13 17:21:51
  18. 23种常用设计模式

    23种常用设计模式 记录一下这常用的23 种设计模式&#xff0c;以方便日后复习和查阅 分类设计模式简述一句话归纳目的生活案例创建型设计模式 &#xff08;简单来说就是用来创建对象的&#xff09;工厂模式&#xff08;Factory Pattern&#xff09;不同条件下创建不同实例产品…...

    2024/4/17 16:26:48
  19. 杰理之手表获取默认铃声选择列表【篇】

    ...

    2024/4/13 2:24:33
  20. 【JavaScript】一行代码实现二维矩阵的转置

    let matrixT matrix[0].map((item, idx) > matrix.map(row > row[idx]))...

    2024/4/18 11:48:26

最新文章

  1. 从零开始搭建一个vue项目

    从零开始搭建一个vue项目 一、环境准备 1.1 安装node.js 选择合适的LTS版本&#xff0c;然后下载安装&#xff0c;安装地址&#xff1a;https://nodejs.org/en/download 在命令行中查看已安装的node.js版本 node -v v14.14.01.2 切换为淘宝的镜像源 解决国内下载慢的问题,…...

    2024/5/4 12:39:01
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. C# 抽象类、接口

    &#xff08;1&#xff09;、抽象类和抽象方法的定义和实现&#xff1a;abstract override abstract class Vehicle{ public abstract void Run(); } 继承抽象类并且实现抽象方法 class RaceCar : Vehicle{ public override void Run(){ } } &#xff08;2&#xff09;、接口的…...

    2024/5/2 2:42:37
  4. 微信小程序实现左滑删除

    效果 实现思路 使用的是官方提供的movable-area 嵌套movable-view 1、movable-area&#xff1a;注意点&#xff0c;需要设置其高度&#xff0c;否则会出现列表内容重叠的现象。 2、由于movable-view需要向右移动&#xff0c;左滑的时候给删除控件展示的空间&#xff0c;故 mov…...

    2024/5/1 13:30:10
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/3 23:10:03
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/4 2:59:34
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57