【鸿蒙 HarmonyOS 4.0】TypeScript开发语言
一、背景
HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScript 本身也是由另一门语言 JavaScript 扩展而来。因此三者的关系如下图所示
二、TypeScript
2.1、运行环境
2.1.1、线上Playground
TypeScript提供了一个线上的 Playground 供练习使用,地址为TypeScript: 演练场 - 一个用于 TypeScript 和 JavaScript 的在线编辑器。
2.1.2、本地运行环境
2.1.2.1、采用的是VSCode 编辑器
2.1.2.2、前提条件
1、安装插件:Code Runner:它提供了简便的代码执行功能,支持多种编程语言,使开发者能够快速运行和调试代码片段。
2、安装Node.js并配置Path
环境变量
说明:我已经安装了Node.js,便不重复安装了
为了方便在终端执行Node.js相关的命令,我们需要将Node.js的安装目录加入到Path
环境变量下
步骤1:首先在DevEco Studio的设置界面查看Node.js的安装目录
步骤2:然后打开环境变量配置面板,按下 Win
+R
,唤起运行窗口,之后运行命令 sysdm.cpl
步骤3:点击高级选项卡,并点击环境变量
步骤4:在系统变量中选中 Path
,并点击编辑
步骤5:点击新建,并填入Node.js的安装目录,完成后点击确定
3、安装ts-node
这是一个 TypeScript 的运行环境,它允许我们直接运行 TypeScript 代码。ts-node的安装和运行依赖于Node.js环境,已经安装了Node.js
npm install -g ts-node
在终端中输入node -v 和ts-node -v后出现各自版本,说明这两个已经安装成功了,如下:
注:完成后需要重新启动VSCode,另其重新加载环境变量和相关依赖。
2.1.2.3、编写程序并运行
首先在合适的位置创建一个工程目录,例如C:\Users\......\hello-ts
,然后使用VSCode打开目录,创建ts文件,并编写Typescript代码运行
问题:运行ts时出现以下错误,百度后发现是由于 ts-node 版本升级导致的兼容性问题
解决:需要在项目中安装 @types/node
npm install --save-dev @types/node
效果: 安装 @types/node 后,再运行就能够正常打印日志了
2.2、声明
2.2.1、变量声明
2.2.2、常量声明
let
用于声明变量,而const
用于声明常量,两者的区别是变量在赋值后可以修改,而常量在赋值后便不能再修改。
const b:number = 200;
2.2.3、类型推断
如果一个变量或常量的声明包含了初始值,TS 便可以根据初始值进行类型推断,此时我们就可以不显式指定其类型,例如
let c = 60;
console.log(typeof c); //number
2.3、常用数据类型
2.3.1、number
number
表示数字,包括整数和浮点数,例如: 100
、-33
、2.5
、-3.9
let a :number = 100
let b :number = -33
let c :number = 2.5
let d :number = -3.9
2.3.2、string
string
表示字符串,例如: 你好
、hello
let a:string = '你好'
let b:string = 'hello'
2.3.3、boolean
boolean
表示布尔值,可选值为:true
、false
let isOpen:boolean = true
let isDone:boolean = false
2.3.4、数组
数组类型定义由两部分组成,元素类型[]
,例如number[]
表示数字数组,string[]
表示字符串数组,数组类型的变量可由数组字面量——[item1,item2,item3]
进行初始化。
let a: number[] = []
let b: string[] = ['你好', 'hello']
2.3.5、对象
在TS中,对象(object)是一种一系列由属性名称和属性值组成的数据结构,例如姓名:'张三', 年龄:10, 性别:'男'
。对象类型的声明需要包含所有属性的名称及类型,例如{name: string, age: number, gender: string}
,对象类型的变量可以通过对象字面量——{name:'张三', age:10, gender:'男'}
进行初始化。
let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};
2.4、函数
2.4.1、函数声明语法
声明函数的基础语法如下
2.4.2、参数
2.4.2.1、特殊语法
①可选参数
可选参数通过参数名后的?
进行标识,如以下案例中的gender?
参数。
function getPersonInfo(name: string, age: number, gender?: string): string {if (gender === undefined) {gender = '未知'}return `name:${name},age:${age},gender:${gender}`;
}let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
注:调用函数时,未传递可选参数,则该参数的值为undefined
。
②默认参数
可在函数的参数列表为参数指定默认值,如以下案例中的gender: string='未知'
参数。
function getPersonInfo(name: string, age: number, gender: string='未知'): string {return `name:${name},age:${age},gender:${gender}`;
}let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
2.4.2.2、 特殊类型
①联合类型
一个函数可能用于处理不同类型的值,这种情况可以使用联合类型,例如以下案例中的message: number | string
function printNumberOrString(message: number | string) {console.log(message)
}printNumberOrString('a')
printNumberOrString(1)
②任意类型
若函数需要处理任意类型的值,则可以使用any
类型,例如以下案例中的message: any
function print(message:any) {console.log(message)
}print('a')
print(1)
print(true)
2.4.3、 返回值
2.4.3.1、特殊类型
若函数没有返回值,则可以使用void
作为返回值类型,其含义为空。
function test(): void {console.log('hello');
}
2.4.3.2、类型推断
函数的返回值类型可根据函数内容推断出来,因此可以省略不写。
function test() {console.log('hello');
}function sum(a: number, b: number) {return a + b;
}
2.4.4、函数声明特殊语法
①匿名函数
匿名函数的语法结构简洁,特别适用于简单且仅需一次性使用的场景。
let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach(function (number) {console.log(number);
})
注意:匿名函数能够根据上下文推断出参数类型,因此参数类型可以省略。
②箭头函数
匿名函数的语法还可以进一步的简化,只保留参数列表和函数体两个核心部分,两者用=>
符号连接。
let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach((num) => { console.log(num) })
2.5、类
2.5.1、类介绍
类(class)是面向对象编程语言中的一个重要概念。
面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。
类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个 Person
类,其对象可以有张三
、李四
等等。
2.5.2、语法说明
2.5.2.1、类的定义
class Person {id: number;name: string;age: number = 18;constructor(id: number, name: string) {this.id = id;this.name = name;}introduce(): string {return `hello,I am ${this.name},and I am ${this.age} years old`}
}
2.5.2.2、对象创建
①语法
创建对象的关键字为new
,具体语法如下
let person = new Person(1,'zhangsan');
②对象属性的访问
console.log(person.name); //读person.name = 'lisi'; //写console.log(person.name);
③对象方法的调用
对象创建后,便可通过对象调用类中声明的方法,如下
let intro = person.introduce();
console.log(intro);
2.5.2.3、静态成员
Typescript 中的类中可以包含静态成员(静态属性和静态方法),静态成员隶属于类本身,而不属于某个对象实例。静态成员通用用于定义一些常量,或者工具方法。
①声明静态成员
定义静态成员需要使用static
关键字。
class Constants{static count:number=1;
}class Utils{static toLowerCase(str:string){return str.toLowerCase();}
}console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));
②使用静态成员
静态成员无需通过对象实例访问,直接通过类本身访问即可。
console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));
2.5.3、继承
继承是面向对象编程中的重要机制,允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以直接使用父类的特性,并根据需要添加新的特性或覆盖现有的特性。这种机制赋予面向对象程序良好的扩展性。
class Student extends Person {classNumber: string;constructor(id: number, name: string, classNumber: string) {super(id, name);this.classNumber = classNumber;}introduce(): string {return super.introduce()+`, and I am a student`;}
}let student = new Student(1,'xiaoming','三年二班');
console.log(student.introduce());
注意:
- 类的继承需要使用关键字
extends
- 子类构造器中需使用
super()
调用父类构造器对继承自父类的属性进行初始化。- 在子类中可以使用
this
关键字访问继承自父类的属性和方法。- 在子类中可以使用
super
关键字访问父类定义的方法。
2.5.4、访问修饰符
访问修饰符(Access Modifiers)用于控制类成员(属性、方法等)的可访问性。TypeScript提供了三种访问修饰符,分别是private、protected和public。
class Person {private id: number;protected name: string;public age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}
}class Student extends Person {}
说明:
- private 修饰的属性或方法是私有的,只能在声明它的类中的被访问。
- protected 修饰的属性或方法是受保护的,只能在声明它的类和其子类中被访问。
- public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的。
2.6、接口
2.6.1、接口介绍
接口(interface)是面向对象编程中的另一个重要概念。接口通常会作为一种契约或规范让类(class)去遵守,确保类实现某些特定的行为或功能。
2.6.2、语法说明
①接口定义
接口使用interface
关键字定义,通常情况下,接口中只会包含属性和方法的声明,而不包含具体的实现细节,具体的细节由其实现类完成。
interface Person {id: number;name: string;age: number;introduce(): void;
}
②接口实现
接口的实现需要用到implements
关键字,实现类中,需要包含接口属性的赋值逻辑,以及接口方法的实现逻辑。
class Student implements Person {id: number;name: string;age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}introduce(): void {console.log('Hello,I am a student');}
}
2.6.3、多态
多态是面相对象编程中的一个重要概念,它可以使同一类型的对象具有不同的行为。下面我们通过一个具体的案例来体会多态这一概念
首先,再创建一个Person
接口的实现类Teacher
,如下
class Teacher implements Person {id: number;name: string;age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}introduce(): void {console.log('Hello,I am a teacher');}
}
然后分别创建一个Student
对象和一个Teacher
对象,注意两个对象的类型均可以设置Person
,如下
let p1: Person = new Student(1, 'zhangsan', 17);
let p2: Person = new Teacher(2, 'lisi', 35);
最后分别调用p1
和p2
的introduce()
方法,你会发现,同样是Person
类型的两个对象,调用同一个introduce()
方法时,表现出了不同的行为,这就是多态。
p1.introduce();//Hello,I am a student
p2.introduce();//Hello,I am a teacher
2.6.4、接口的作用
在传统的面向对象编程的场景中,接口主要用于设计和组织代码,使代码更加容易扩展和维护。
假如现在需要实现一个订单支付系统,按照面向对象编程的习惯,首先需要定义一个订单类(Order),如下
class Order {totalAmount: number;constructor(totalAmount: number) {this.totalAmount = totalAmount;}pay() {console.log(`AliPay:${this.totalAmount}`);}
}
很容易预想到,这个系统将来可能需要支持其他的支付方式,为了方便代码支持新的支付方式,我们可以对代码进行如下改造。
首先定义一个支付策略的接口,接口中声明一个pay
方法,用来规范实现类必须实现支付逻辑。
interface PaymentStrategy {pay(amount: number): void;
}
然后在订单类中增加一个PaymentStrategy
的属性,并且在订单类中的pay
方法中调用PaymentStrategy
的pay
方法,如下
class Order {totalAmount: number;paymentStrategy: PaymentStrategy;constructor(totalAmount: number, paymentStrategy: PaymentStrategy) {this.totalAmount = totalAmount;this.paymentStrategy = paymentStrategy;}pay() {this.paymentStrategy.pay(this.totalAmount);}
}
这样改造完之后,就可以很容易的在不改变现有代码的情况下,支持新的支付方式了。
比如现在需要支持AliPay
,那我们就可以创建AliPay
这个类(class)并实现(implement)PaymentStrategy
这个接口,如下
class AliPay implements PaymentStrategy {pay(amount: number): void {console.log(`AliPay:${amount}`);}
}
这样一来,之后创建的订单就可以使用AliPay
这个支付方式了。
let order = new Order(1000,new AliPay());
order.pay();
2.6.5、TS中接口的特殊性
TypeScript 中的接口是一个非常灵活的概念,除了用作类的规范之外,也常用于直接描述对象的类型,例如,现有一个变量的定义如下
let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};
可以看到变量的值为一个一般对象,变量的类型为{name:string, age:number, gender:string}
,此时就可以声明一个接口来描述该对象的类型,如下
interface Person {name: string;age: number;gender: string;
}let person: Person = {name:'张三', age:10, gender:'男'};
2.7、枚举
2.7.1、枚举介绍
枚举(Enumeration)是编程语言中常见的一种数据类型,其主要功能是定义一组有限的选项,例如,方向(上、下、左、右)或季节(春、夏、秋、冬)等概念都可以使用枚举类型定义。
2.7.2、语法说明
①枚举定义
枚举的定义需使用enum
关键字,如下
enum Season {SPRING,SUMMER,AUTUMN,WINTER
}
②枚举使用
枚举的使用记住两个原则即可
- 枚举值的访问
像访问对象属性一样访问枚举值,例如
Season.SPRING
- 枚举值的类型
枚举值的类型为
enum
的名称,例如Season.SPRING
和Season.SUMMER
等值的类型都是Season
let spring:Season = Season.SPRING;
③使用场景
现需要编写一个函数move
,其功能是根据输入的方向(上、下、左、右)进行移动,此时就可以先使用枚举定义好所有可能的输入选项,如下
enum Direction {UP,BOTTOM,LEFT,RIGHT
}
move
函数的实现如下
function move(direction: Direction) {if(direction===Direction.UP){console.log('向上移动');}else if(direction===Direction.BOTTOM){console.log('向下移动');}else if(direction===Direction.LEFT){console.log('向左移动');}else{console.log('向右移动');}
}move(Direction.UP);
2.7.3、赋值
在TypeScript 中,枚举实际上是一个对象,而每个枚举值都是该对象的一个属性,并且每个属性都有具体的值,属性值只支持两种类型——数字或字符串。
默认情况下,每个属性的值都是数字,并且从 0
开始递增,例如上述案例中的Direction
枚举中,Direction.UP
的值为0
,Direction.BOTTOM
的值为1
,依次类推,具体如下
console.log(Direction.UP) //0
console.log(Direction.BOTTOM) //1
console.log(Direction.LEFT) //2
console.log(Direction.RIGHT) //3
除了使用默认的数字作为属性的值,我们还能手动为每个属性赋值,例如
enum Direction {UP = 1,BOTTOM = 2,LEFT = 3,RIGHT = 4
}console.log(Direction.UP) //1
console.log(Direction.BOTTOM) //2
console.log(Direction.LEFT) //3
console.log(Direction.RIGHT) //4
再例如
enum Direction {UP = 'up',BOTTOM = 'bottom',LEFT = 'left',RIGHT = 'right'
}console.log(Direction.UP) //up
console.log(Direction.BOTTOM) //bottom
console.log(Direction.LEFT) //left
console.log(Direction.RIGHT) //right
通过为枚举属性赋值,可以赋予枚举属性一些更有意义的信息,例如以下枚举
enum Color {Red = 0xFF0000,Green = 0x00FF00,Blue = 0x0000FF
}enum FontSize {Small = 12,Medium = 16,Large = 20,ExtraLarge = 24
}
2.8、模块化
2.8.1、模块化介绍
模块化是指将复杂的程序拆解为多个独立的文件单元,每个文件被称为一个模块。在 TypeScript 中,默认情况下,每个模块都拥有自己的作用域,这意味着在一个模块中声明的任何内容(如变量、函数、类等)在该模块外部是不可见的。为了在一个模块中使用其他模块的内容,必须对这些内容进行导入、导出。
2.8.2、语法说明
①导出
导出须使用export
关键字,语法如下
export function hello() {console.log('hello module A');
}export const str = 'hello world';const num = 1;
②导入
导入须使用import
关键字,语法如下
import { hello, str } from './moduleA';hello();
console.log(str);
2.8.3、避免命名冲突
若多个模块中具有命名相同的变量、函数等内容,将这些内容导入到同一模块下就会出现命名冲突。例如,在上述案例的基础上,又增加了一个 moduleC,内容如下
export function hello() {console.log('hello module C');
}export const str = 'module C';
moduleB 同时引入 moduleA 和 moduleC 的内容,如下,显然就会出命名冲突
import { hello, str } from "./moduleA";
import { hello, str } from "./moduleC";hello() //?
console.log(str); //?
①导入重命名
import { hello as helloFromA, str as strFromA } from "./moduleA";
import { hello as helloFromC, str as strFromC } from "./moduleC";helloFromA();
console.log(strFromA);helloFromC();
console.log(strFromC);
②创建模块对象
上述导入重命名的方式能够很好的解决命名冲突的问题,但是当冲突内容较多时,这种写法会比较冗长。除了导入重命名外,还可以将某个模块的内容统一导入到一个模块对象上,这样就能简洁有效的解决命名冲突的问题了,具体语法如下
import * as A from "./moduleA";
import * as C from "./moduleC";A.hello();
console.log(A.str);C.hello();
console.log(C.str);
2.8.4、默认导入导出
①默认导出
默认导出允许一个模块指定一个(最多一个)默认的导出项,语法如下
export default function hello(){console.log('moduleA');
}
②默认导入
由于每个模块最多有一个默认导出,因此默认导入无需关注导入项的原始名称,并且无需使用{}
。
import helloFromA from "./moduleA";
由于默认导入时无需关注导入项的名称,所以默认导出支持匿名内容,比如匿名函数,语法如下
export default function () {console.log('moduleB');
}
最后:👏👏😊😊😊👍👍
相关文章:

【鸿蒙 HarmonyOS 4.0】TypeScript开发语言
一、背景 HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScrip…...

Android java基础_异常
一.异常的概念 在Java中,异常(Exception)是指程序执行过程中可能出现的不正常情况或错误。它是一个事件,它会干扰程序的正常执行流程,并可能导致程序出现错误或崩溃。 异常在Java中是以对象的形式表示的,…...

高数考研 -- 公式总结(更新中)
1. 两个重要极限 (1) lim x → 0 sin x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0xsinx1, 推广形式 lim f ( x ) → 0 sin f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0f(x)sinf(x)1. (2) lim …...

详解顺序结构滑动窗口处理算法
🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…...
Java 8中使用Stream来操作集合
Java 8中使用Stream来操作集合 在Java 8中,你可以使用Stream API来操作集合,这使得集合的处理变得更加简洁和函数式。Stream API提供了一系列的中间操作(intermediate operations)和终端操作(terminal operations&…...

MATLAB环境下一种改进的瞬时频率(IF)估计方法
相对于频率成分单一、周期性强的平稳信号来说,具有非平稳、非周期、非可积特性的非平稳信号更普遍地存在于自然界中。调频信号作为非平稳信号的一种,由于其频率时变、距离分辨率高、截获率低等特性,被广泛应用于雷达、地震勘测等领域。调频信…...
解决:selenium web browser 的版本适配问题
文章目录 解决方案:使用 webdriver manager 自动适配驱动 使用 selenium 操控浏览器的时候报错: The chromedriver version (114.0.5735.90) detected in PATH at /opt/homebrew/bin/chromedriver might not be compatible with the detected chrome ve…...
pytest.param作为pytest.mark.parametrize的参数进行调用
pytest.param:在 pytest.mark.parametrize 中可以作为一个指定的参数进行调用 获取数据库(网页端)数据,通过pytest.param包装成数据包用于pytest.mark.parametrize 中实现数据驱动调用。 import os import pytest import json fr…...

如何判断一个元素是否在可视区域中?
文章目录 一、用途二、实现方式offsetTop、scrollTopgetBoundingClientRectIntersection Observer创建观察者传入被观察者 三、案例分析参考文献 一、用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标元素是…...

Go Run - Go 语言中的简洁指令
原文:breadchris - 2024.02.21 也许听起来有些傻,但go run是我最喜欢的 Go 语言特性。想要运行你的代码?只需go run main.go。它是如此简单,我可以告诉母亲这个命令,她会立即理解。就像 Go 语言的大部分功能一样&…...

Spring全面精简总结
Spring两大核心功能:IOC控制反转、AOP面向切面的编程 控制反转(loC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是…...
低代码开发如何助力数字化企业管理系统平台构建
随着数字化时代的到来,企业对于管理系统的需求日益增长。高效的管理系统可以提高企业的运作效率,降低成本,提升竞争力。然而,传统的开发方式在应对日益复杂的管理系统需求时,显得力不从心。低代码开发作为一种新兴的开…...

ElasticSearch之零碎知识点
写在前面 本文记录es的零碎知识点,包括但不限于概念,集群方式,等。 1:词项查询 VS 全文查询 词项查询:查询的内容不做分词处理,输入的什么查询什么。 全文查询:查询的内容会做分词处理&…...

【春运抢票攻略浅析】
参考 最全12306放票规则,抢票策略,候补作用2023年12306抢票攻略(纯技巧) 研究放票规则,候补的时候车次进行一下挑选,能够买长乘短的尽量买长,不要候补一些区间票吧,这是一开始放票…...

【Java EE初阶二十五】简单的表白墙(一)
1. 前端部分 1.1 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wid…...
人工智能的新浪潮:探索OpenAI的Sora视频模型及其对未来创作的影响
OpenAI的最新AI视频模型Sora,自发布以来,已成为科技界的热点。Sora的核心能力在于将文本描述转化为高清视频片段,标志着在视频生成领域的一次重大突破。Sora的特点包括使用深度理解语言的能力来准确解释提示,以及生成表达丰富情感…...

【c语言】字符函数和字符串函数(上)
前言 在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了⼀系列库函数~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 1. 字符分…...

React18源码: schedule任务调度messageChannel
React调度原理(scheduler) 在React运行时中,调度中心(位于scheduler包)是整个React运行时的中枢(其实是心脏),所以理解了scheduler调度,就基本掌握了React的核心React两大循环:从宏…...
Jmeter 学习目录
Jmeter 所有内容均以学习为主输出内容,按照最小单位和基础进行输出。 如果有看不懂,或者有不明确的内容,欢迎大家留言说明。 Jmeter系列(1)Mac Jmeter下载安装启动 Jmeter系列(2)Jmeter 目录介…...
计算机网络 数据链路层课后题
1.以太网帧有哪些不同的封装格式?他们有何区别和应用场景? 以太网II封装(Ethernet II):以太网II封装是最常用的以太网封装格式,也被称为DIX封装。它在数据链路层首部使用6个字节的目的MAC地址和6个字节的源…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...