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

Scala第七章节

Scala第七章节

scala总目录

章节目标

  1. 掌握继承和抽象类相关知识点
  2. 掌握匿名内部类的用法
  3. 了解类型转换的内容
  4. 掌握动物类案例

1. 继承

1.1 概述

实际开发中, 我们发现好多类中的内容是相似的(例如: 相似的属性和行为), 每次写很麻烦. 于是我们可以把这些相似的内容提取出来单独的放到一个类中(父类), 然后让那多个类(子类)和这个类(父类)产生一个关系, 从而实现子类可以访问父类的内容, 这个关系就叫: 继承.

因为scala语言是支持面向对象编程的,我们也可以使用scala来实现继承,通过继承来减少重复代码。

1.2 语法
  • scala中使用extends关键字来实现继承
  • 可以在子类中定义父类中没有的字段和方法,或者重写父类的方法
  • 类和单例对象都可以有父类

语法

class/object A类 extends B类 {	..
}

叫法

  • 上述格式中, A类称之为: 子类, 派生类.
  • B类称之为: 父类, 超类, 基类.
1.3 类继承

需求

已知学生类(Student)和老师类(Teacher), 他们都有姓名和年龄(属性), 都要吃饭(行为), 请用所学, 模拟该需求.

  • 方式一: 非继承版.
object ClassDemo01 {//1. 定义老师类.class Teacher{var name = ""var age = 0def eat() = println("老师喝牛肉汤!...")}//2. 定义学生类.class Student{var name = ""var age = 0def eat() = println("学生吃牛肉!...")}//main方法, 程序的主入口def main(args: Array[String]): Unit = {//3. 测试老师类.//3.1 创建对象.val t = new Teacher//3.2 给属性赋值t.name = "刘老师"t.age = 32//3.3 打印属性值.println(t.name, t.age)//3.4 调用方法t.eat()println("-" * 15)//4. 测试学生类.val s = new Students.name = "张三"s.age = 21println(s.name, s.age)s.eat()}
}
  • 方式二: 继承版
object ClassDemo02 {//1. 定义人类.class Person {var name = ""var age = 0def eat() = println("人要吃饭!...")}//2. 定义老师类.class Teacher extends Person//3. 定义学生类.class Student extends Persondef main(args: Array[String]): Unit = {//4. 测试老师类.val t = new Teachert.name = "刘老师"t.age = 32println(t.name, t.age)t.eat()println("-" * 15)//5. 测试学生类.val s = new Students.name = "张三"s.age = 23println(s.name, s.age)s.eat()}
}
1.4 单例对象继承

在Scala中, 单例对象也是可以继承类的.

需求

定义Person类(成员变量: 姓名, 成员方法: sayHello()), 定义单例对象Student继承自Person, 然后测试.

object ClassDemo03 {//1. 定义Person类.class Person {var name = ""def sayHello() = println("Hello, Scala!..")}//2. 定义单例对象Student, 继承Person.object Student extends Person//main方法, 程序的主入口def main(args: Array[String]): Unit = {//3. 测试Student中的成员.Student.name = "张三"println(Student.name)Student.sayHello()}
}
1.5 方法重写
1.5.1 概述

子类中出现和父类一模一样的方法时, 称为方法重写. Scala代码中可以在子类中使用override来重写父类的成员,也可以使用super来引用父类的成员.

1.5.2 注意事项
  • 子类要重写父类中的某一个方法,该方法必须要使用override关键字来修饰

  • 可以使用override来重写一个val字段.

    注意: 父类用var修饰的变量, 子类不能重写.

  • 使用super关键字来访问父类的成员方法

1.5.3 示例

需求

定义Person类, 属性(姓名, 年龄), 有一个sayHello()方法.

然后定义Student类继承Person类, 重写Person类中的字段和方法, 并测试.

参考代码

object ClassDemo04 {//1. 定义父类Person.class Person {var name = "张三"val age = 23def sayHello() = println("Hello, Person!...")}//2. 定义子类Student, 继承Person.class Student extends Person{//override var name = "李四"    //这样写会报错, 子类不能重写父类用var修饰的变量.override val age = 24override def sayHello() = {//通过super调用父类的成员.super.sayHello()println("Hello, Student!...")}}//程序的入口.def main(args: Array[String]): Unit = {//3. 创建学生类型的对象, 然后测试.val s = new Studentprintln(s.name, s.age)s.sayHello()}
}

2. 类型判断

有时候,我们设计的程序,要根据变量的类型来执行对应的逻辑, 如下图:
在这里插入图片描述

在scala中,如何来进行类型判断呢?

有两种方式:

  • isInstanceOf
  • getClass/classOf
2.1 isInstanceOf, asInstanceOf

概述

  • isInstanceOf: 判断对象是否为指定类的对象
  • asInstanceOf: 将对象转换为指定类型

格式

// 判断对象是否为指定类型
val trueOrFalse:Boolean = 对象.isInstanceOf[类型]// 将对象转换为指定类型
val 变量 = 对象.asInstanceOf[类型]

示例代码:

​ val trueOrFalse = p.isInstanceOf[Student]

​ val s = p.asInstanceOf[Student]

2.2 案例

需求

  • 定义一个Person类
  • 定义一个Student类继承自Person类, 该类有一个sayHello()方法.
  • 创建一个Student类对象, 并指定它的类型为Person类型
  • 判断该对象是否为Student类型,如果是,将其转换为Student类型并调用sayHello()方法.

参考代码

object ClassDemo05 {//1. 定义一个Person类.class Person//2. 定义一个Student类, 继承Person.class Student extends Person {def sayHello() = println("Hello, Scala!...")}//main方法, 作为程序的主入口def main(args: Array[String]): Unit = {//3. 通过多态的形式创建Student类型的对象.val p: Person = new Student//s.sayHello()      //这样写会报错, 因为多态的弊端是: 父类引用不能直接访问子类的特有成员.//4. 判断其是否是Student类型的对象, 如果是, 将其转成Student类型的对象.if (p.isInstanceOf[Student]) {val s = p.asInstanceOf[Student]//5. 调用Student#sayHello()方法s.sayHello()}}
}
2.3 getClass和classOf

isInstanceOf 只能判断对象是否为指定类以及其子类的对象,而不能精确的判断出: 对象就是指定类的对象。如果要求精确地判断出对象的类型就是指定的数据类型,那么就只能使用 getClass 和 classOf 来实现.

用法

  • p.getClass可以精确获取对象的类型
  • classOf[类名]可以精确获取数据类型
  • 使用==操作符可以直接比较类型

示例

示例说明

  • 定义一个Person类
  • 定义一个Student类继承自Person类
  • 创建一个Student类对象,并指定它的类型为Person类型
  • 测试使用isInstance判断该对象是否为Person类型
  • 测试使用getClass/classOf判断该对象是否为Person类型
  • 测试使用getClass/classOf判断该对象是否为Student类型

参考代码

object ClassDemo06 {//1. 定义一个Person类.class Person//2. 定义一个Student类, 继承自Person类.class Student extends Persondef main(args: Array[String]): Unit = {//3. 创建Student类型的对象, 指定其类型为Person.val p:Person = new Student//4. 通过isInstanceOf关键字判断其是否是Person类型的对象.println(p.isInstanceOf[Person])       	//true, //5. 通过isInstanceOf关键字判断其是否是Person类型的对象.println(p.isInstanceOf[Student])     	//true//6. 通过getClass, ClassOf判断其是否是Person类型的对象.println(p.getClass == classOf[Person])    //false//7. 通过getClass, ClassOf判断其是否是Student类型的对象.println(p.getClass == classOf[Student])   //true}
}

3. 抽象类

scala语言是支持抽象类的, , 通过abstract关键字来实现.

3.1 定义

如果类中有抽象字段或者抽象方法, 那么该类就应该是一个抽象类.

  • 抽象字段: 没有初始化值的变量就是抽象字段.
  • 抽象方法: 没有方法体的方法就是一个抽象方法.
3.2 格式
// 定义抽象类
abstract class 抽象类名 {// 定义抽象字段val/var 抽象字段名:类型// 定义抽象方法def 方法名(参数:参数类型,参数:参数类型...):返回类型
}
3.3 抽象方法案例

需求
在这里插入图片描述

  • 设计4个类,表示上述图中的继承关系
  • 每一个形状都有自己求面积的方法,但是不同的形状计算面积的方法不同

步骤

  1. 创建一个Shape抽象类,添加一个area抽象方法,用于计算面积
  2. 创建一个Square正方形类,继承自Shape,它有一个边长的主构造器,并实现计算面积方法
  3. 创建一个长方形类,继承自Shape,它有一个长、宽的主构造器,实现计算面积方法
  4. 创建一个圆形类,继承自Shape,它有一个半径的主构造器,并实现计算面积方法
  5. 编写main方法,分别创建正方形、长方形、圆形对象,并打印它们的面积

参考代码

// 创建形状抽象类
abstract class Shape {def area:Double
}// 创建正方形类
class Square(var edge:Double /*边长*/) extends Shape {// 实现父类计算面积的方法override def area: Double = edge * edge
}// 创建长方形类
class Rectangle(var length:Double /*长*/, var width:Double /*宽*/) extends Shape {override def area: Double = length * width
}// 创建圆形类
class Circle(var radius:Double /*半径*/) extends Shape {override def area: Double = Math.PI * radius * radius
}object ClassDemo07 {def main(args: Array[String]): Unit = {val s1:Shape = new Square(2)val s2:Shape = new Rectangle(2,3)val s3:Shape = new Circle(2)println(s1.area)println(s2.area)println(s3.area)}
}
3.4 抽象字段

在scala的抽象类中,不仅可以定义抽象方法, 也可以定义抽象字段。如果一个成员变量是没有初始化,我们就认为它是抽象的。

语法

abstract class 抽象类 {val/var 抽象字段:类型
}

示例

示例说明

  1. 创建一个Person抽象类,它有一个String抽象字段occupation
  2. 创建一个Student类,继承自Person类,重写occupation字段,初始化为学生
  3. 创建一个Teacher类,继承自Person类,重写occupation字段,初始化为老师
  4. 添加main方法,分别创建Student/Teacher的实例,然后分别打印occupation

参考代码

object ClassDemo08 {//1. 定义抽象类Person, 有一个抽象字段occupation(职业)abstract class Person {val occupation:String}//2. 定义Student类继承Person, 重写抽象字段occupation.class Student extends Person{override val occupation: String = "学生"}//3. 定义Teacher类继承Person, 重写抽象字段occupation.class Teacher extends Person{override val occupation: String = "老师"}//main方法, 作为程序的主入口def main(args: Array[String]): Unit = {//4. 创建Student类的对象, 打印occupation的值.val s = new Studentprintln(s.occupation)//5. 创建Teacher类的对象, 打印occupation的值.val t = new Teacherprintln(t.occupation)}
}

4. 匿名内部类

匿名内部类是继承了类的匿名的子类对象,它可以直接用来创建实例对象。Spark的源代码中大量使用到匿名内部类。学完这个内容, 对我们查看Spark的底层源码非常有帮助.

4.1 语法
new 类名() {//重写类中所有的抽象内容
}

注意: 上述格式中, 如果的类的主构造器参数列表为空, 则小括号可以省略不写.

4.2 使用场景
  • 当对对象方法(成员方法)仅调用一次的时候.
  • 可以作为方法的参数进行传递.
4.3 示例

需求

  1. 创建一个Person抽象类,并添加一个sayHello抽象方法
  2. 定义一个show()方法, 该方法需要传入一个Person类型的对象, 然后调用Person类中的sayHello()方法.
  3. 添加main方法,通过匿名内部类的方式来创建Person类的子类对象, 调用Person类的sayHello()方法.
  4. 调用show()方法.

参考代码

object ClassDemo09 {//1. 定义Person类, 里边有一个抽象方法: sayHello()abstract class Person{def sayHello()}//2. 定义一个show()方法, 该方法需要传入一个Person类型的对象.def show(p:Person) = p.sayHello()//main方法是程序的主入口def main(args: Array[String]): Unit = {//3. 通过匿名内部类创建Person的子类对象, 并调用sayHello()方法.new Person {override def sayHello(): Unit = println("Hello, Scala, 当对成员方法仅调用一次的时候.")}.sayHello()//4. 演示: 匿名内部类可以作为方法的参数进行传递.val p = new Person {override def sayHello(): Unit = println("Hello, Scala, 可以作为方法的实际参数进行传递")}show(p)}
}

5. 案例: 动物类

5.1 需求

已知有猫类和狗类, 它们都有姓名和年龄, 都会跑步, 而且仅仅是跑步, 没有什么不同. 它们都有吃饭的功能, 不同的是猫吃鱼, 狗吃肉. 而且猫类独有自己的抓老鼠功能, 狗类独有自己的看家功能, 请用所学模拟该需求.

5.2 目的
  • 考察继承, 抽象类, 类型转换这些知识点.
5.3 步骤
  1. 定义抽象动物类(Animal), 属性: 姓名, 年龄, 行为: 跑步, 吃饭.
  2. 定义猫类(Cat)继承自动物类, 重写吃饭的方法, 并定义该类独有的抓老鼠的方法.
  3. 定义狗类(Dog)继承自动物类, 重写吃饭的方法, 并定义该类独有的看家的方法.
5.4 参考代码
object ClassDemo10 {//1. 定义抽象动物类(Animal), 属性: 姓名, 年龄, 行为: 跑步, 吃饭.abstract class Animal{//1.1 属性var name = ""var age = 0//1.2 行为def run() = println("动物会跑步!...")//吃饭的方法.def eat():Unit}//2. 定义猫类(Cat)继承自动物类, 重写吃饭的方法, 并定义该类独有的抓老鼠的方法.class Cat extends Animal {//2.1 重写父类的抽象方法override def eat(): Unit = println("猫吃鱼")//2.2 定义自己的独有方法def catchMouse() = println("猫会抓老鼠")}//3. 定义狗类(Dog)继承自动物类, 重写吃饭的方法, 并定义该类独有的看家的方法.class Dog extends Animal {//3.1 重写父类的抽象方法override def eat(): Unit = println("狗吃肉")//3.2 定义自己的独有方法def lookHome() = println("狗会看家")}//main方法, 作为程序的入口def main(args: Array[String]): Unit = {//4. 测试猫类.//4.1 创建猫类对象.val c = new Cat//4.2 给成员变量赋值.c.name = "汤姆"c.age = 13//4.3 打印成员变量值println(c.name, c.age)//4.4 调用方法.c.eat()//4.5 调用猫类的独有功能: 抓老鼠if (c.isInstanceOf[Cat]) {val cat = c.asInstanceOf[Cat]cat.catchMouse()} else if(c.isInstanceOf[Dog]) {val dog = c.asInstanceOf[Dog]dog.lookHome()} else{println("您传入的不是猫类, 也不是狗类对象")}//5. 测试狗类, 自己完成.}
}

= println(“狗会看家”)
}

//main方法, 作为程序的入口
def main(args: Array[String]): Unit = {
//4. 测试猫类.
//4.1 创建猫类对象.
val c = new Cat
//4.2 给成员变量赋值.
c.name = “汤姆”
c.age = 13
//4.3 打印成员变量值
println(c.name, c.age)
//4.4 调用方法.
c.eat()
//4.5 调用猫类的独有功能: 抓老鼠
if (c.isInstanceOf[Cat]) {
val cat = c.asInstanceOf[Cat]
cat.catchMouse()
} else if(c.isInstanceOf[Dog]) {
val dog = c.asInstanceOf[Dog]
dog.lookHome()
} else{
println(“您传入的不是猫类, 也不是狗类对象”)
}

//5. 测试狗类, 自己完成.

}
}

相关文章:

Scala第七章节

Scala第七章节 scala总目录 章节目标 掌握继承和抽象类相关知识点掌握匿名内部类的用法了解类型转换的内容掌握动物类案例 1. 继承 1.1 概述 实际开发中, 我们发现好多类中的内容是相似的(例如: 相似的属性和行为), 每次写很麻烦. 于是我们可以把这些相似的内容提取出来单…...

C语言进程的相关操作

C语言进程的相关操作 进程简介 每个进程都有一个非负整数形式到的唯一编号,即PID(Process Identification,进程标识)PID在任何时刻都是唯一的,但是可以重用,当进程终止并被回收以后,其PID就可…...

数据结构学习系列之链式栈

链式栈:即:栈的链式存储结构;分析:为了提高程序的运算效率,应采用头插法和头删法;进栈: int push_link_stack(stack_t *link_stack,int data) {if(NULL link_stack){printf("入参合理性检…...

too many session files in /var/tmp

Linux中Too many open files 问题分析和解决_e929: too many viminfo temp files-CSDN博客...

【7.0】打开未知来源安装应用

默认打开未知来源安装应用 frameworks\base\packages\SettingsProvider\res\values\defaults.xml <bool name"def_install_non_market_apps">false</bool>...

安装ipfs-swarm-key-gen

安装ipfs-swarm-key-gen Linux安装go解释器安装ipfs-swarm-key-gen Linux安装go解释器 https://blog.csdn.net/omaidb/article/details/133180749 安装ipfs-swarm-key-gen # 编译ipfs-swarm-key-gen二进制文件 go get -u github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm…...

BASH shell脚本篇5——文件处理

这篇文章介绍下BASH shell中的文件处理。之前有介绍过shell的其它命令&#xff0c;请参考&#xff1a; BASH shell脚本篇1——基本命令 BASH shell脚本篇2——条件命令 BASH shell脚本篇3——字符串处理 BASH shell脚本篇4——函数 在Bash Shell脚本中&#xff0c;可以使用…...

ElementUI之首页导航及左侧菜单(模拟实现)

目录 ​编辑 前言 一、mockjs简介 1. 什么是mockjs 2. mockjs的用途 3. 运用mockjs的优势 二、安装与配置mockjs 1. 安装mockjs 2. 引入mockjs 2.1 dev.env.js 2.2 prod.env.js 2.3 main.js 三、mockjs的使用 1. 将资源中的mock文件夹复制到src目录下 2. 点击登…...

Java开源工具库使用之Lombok

文章目录 前言一、常用注解1.1 AllArgsConstructor/NoArgsConstructor/RequiredArgsConstructor1.2 Builder1.3 Data1.4 EqualsAndHashCode1.5 Getter/Setter1.6 Slf4j/Log4j/Log4j2/Log1.7 ToString 二、踩坑2.1 Getter/Setter 方法名不一样2.2 Builder 不会生成无参构造方法2…...

uboot启动流程涉及reset函数

一. uboot启动流程中函数 之前了解了uboot链接脚本文件 u-boot.lds。 从 u-boot.lds 中我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start。 本文了解 一下&#xff0c;uboot启动过程中涉及的 reset 函数。本文继上一篇文章学习&#xff0c;地址如下&#xff…...

端口被占用怎么解决

第一步&#xff1a;WinR 打开命令提示符&#xff0c;输入netstat -ano|findstr 端口号 找到占用端口的进程 第二步&#xff1a; 杀死使用该端口的进程&#xff0c;输入taskkill /t /f /im 进程号&#xff08; &#xff01;&#xff01;&#xff01;注意是进程号&#xff0c;不…...

python reportlab 生成多页pdf

多页 from reportlab.pdfgen import canvas from reportlab.platypus import (SimpleDocTemplate, Paragraph, PageBreak, Image, Spacer, Table, TableStyle) from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY from reportlab.lib.styles import P…...

word 多级目录的问题

一、多级标题自动编号 --> 制表符 -> 空格 网址&#xff1a; 【Word技巧】2 标题自动编号——将多级列表链接到样式 - YouTube 二、多级列表 --> 正规形式编号 网址&#xff1a;Word 教学 - 定框架&#xff1a;文档格式与多级标题&#xff01; - YouTube 三、目…...

python使用mitmproxy和mitmdump抓包之拦截和修改包(四)

我认为mitmproxy最强大的地方&#xff0c;就是mitmdump可以结合python代理&#xff0c;灵活拦截和处理数据包。 首先&#xff0c;mitmdump的路径如下&#xff1a;&#xff08;使用pip3 install mitmproxy安装的情况&#xff0c;参考我的文章python使用mitmproxy和mitmdump抓包…...

邓俊辉《数据结构》→ “2.6.5 二分查找(版本A)”之“成功查找长度”递推式推导

【问题描述】 邓俊辉的《数据结构&#xff08;C语言版&#xff09;&#xff08;第3版&#xff09;》&#xff08;ISBN&#xff1a;9787302330646&#xff09;中&#xff0c;开始于第48页的“2.6.5 二分查找&#xff08;版本A&#xff09;”内容在第50页详述了“成功查找长度”的…...

Linux文件查找,别名,用户组综合练习

1.文件查看: 查看/etc/passwd文件的第5行 [rootserver ~]# head -5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologi…...

【MATLAB第77期】基于MATLAB代理模型算法的降维/特征排序/数据处理回归/分类问题MATLAB代码实现【更新中】

【MATLAB第77期】基于MATLAB代理模型算法的降维/特征排序/数据处理回归/分类问题MATLAB代码实现 本文介绍基于libsvm代理模型算法的特征排序方法合集&#xff0c;包括&#xff1a; 1.基于每个特征预测精度进行排序&#xff08;libsvm代理模型&#xff09; 2.基于相关系数corr的…...

第三章 图标辅助元素的定制

第三章 图标辅助元素的定制 1.认识图表常用的辅助元素 ​ 图表的辅助元素是指除了根据数据绘制的图形之外的元素&#xff0c;常用的辅助元素包括坐标轴、标题、图例、网格、参考线、参考区域、注释文本和表格&#xff0c;它们都可以对图形进行补充说明。 ​ 上图中图表常用辅…...

【前端】ECMAScript6从入门到进阶

【前端】ECMAScript6从入门到进阶 1.ES6简介及环境搭建 1.1.ECMAScript 6简介 &#xff08;1&#xff09;ECMAScript 6是什么 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff…...

Android Shape设置背景

设置背景时&#xff0c;经常这样 android:background“drawable/xxx” 。如果是纯色图片&#xff0c;可以考虑用 shape 替代。 shape 相比图片&#xff0c;减少资源占用&#xff0c;缩减APK体积。 开始使用。 <?xml version"1.0" encoding"utf-8"?…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

游戏开发中常见的战斗数值英文缩写对照表

游戏开发中常见的战斗数值英文缩写对照表 基础属性&#xff08;Basic Attributes&#xff09; 缩写英文全称中文释义常见使用场景HPHit Points / Health Points生命值角色生存状态MPMana Points / Magic Points魔法值技能释放资源SPStamina Points体力值动作消耗资源APAction…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图&#xff0c;感觉这题好麻烦&#xff0c;直线不能相交啊&#xff0c;每个数字只属于一条连线啊等等&#xff0c;但我们结合题目所给的信息和例图的内容&#xff0c;这不就是最长公共子序列吗&#xff1f;&#xff0c;我们把最长公共子序列连线起…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...

初级程序员入门指南

初级程序员入门指南 在数字化浪潮中&#xff0c;编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言&#xff0c;明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 &#xff08;一&#xff09;编程语言抉择 编…...

Gitlab + Jenkins 实现 CICD

CICD 是持续集成&#xff08;Continuous Integration, CI&#xff09;和持续交付/部署&#xff08;Continuous Delivery/Deployment, CD&#xff09;的缩写&#xff0c;是现代软件开发中的一种自动化流程实践。下面介绍 Web 项目如何在代码提交到 Gitlab 后&#xff0c;自动发布…...

Q1起重机指挥理论备考要点分析

Q1起重机指挥理论备考要点分析 一、考试重点内容概述 Q1起重机指挥理论考试主要包含三大核心模块&#xff1a;安全技术知识&#xff08;占40%&#xff09;、指挥信号规范&#xff08;占30%&#xff09;和法规标准&#xff08;占30%&#xff09;。考试采用百分制&#xff0c;8…...

n8n:解锁自动化工作流的无限可能

在当今快节奏的数字时代&#xff0c;无论是企业还是个人&#xff0c;都渴望提高工作效率&#xff0c;减少重复性任务的繁琐操作。而 n8n&#xff0c;这个强大的开源自动化工具&#xff0c;就像一位智能的数字助手&#xff0c;悄然走进了许多人的工作和生活&#xff0c;成为提升…...