TypeScript 常见的面试题

文章目录

        • 1. 什么是TypeScript
        • 2. 类型声明和类型推断的区别,并举例应用
        • 3. 什么是接口(interface),它的作用,接口的使用场景。接口和类型别名(Type Alias)的区别
        • 4. 什么是泛型(generic),如何创建泛型函数和泛型类,实际用途
        • 5. 枚举(enum)是什么,它的优势,应用案例。枚举和常量枚举的区别
        • 6. 如何处理可空类型(nullable types)和undefined类型,如何正确处理这些类型以避免潜在错误
        • 7. 什么是联合类型和交叉类型
        • 8. 什么是TypeScript中的声明文件(Declaration Files)
        • 9. 什么是命名空间(Namespace)和模块(Module)
        • 10. 什么是类型断言(Type Assertion)
        • 11. TypeScript中的可选参数和默认参数是什么
        • 12. 类型守卫(Type Guards)是什么
        • 13. 索引类型(Index Types)是什么,好处有什么
        • 14. const和readonly的区别
        • 15. TypeScript 中 any 类型的作用是什么,滥用会有什么后果
        • 16. TypeScript中的this有什么需要注意的
        • 17. TypeScript数据类型
        • 18. interface可以给Function/Array/Class(Indexable)做声明吗
        • 19. TypeScript中的协变、逆变、双变和抗变是什么
        • 20. TypeScript中的静态类型和动态类型有什么区别
        • 21. 介绍TypeScript中的可选属性、只读属性和类型断言
        • 22. TypeScript 中的模块化是如何工作的,举例说明
      • 结尾

在这里插入图片描述

面试题涉及了 TypeScript 语言的各个方面,包括基本语法类型系统函数模块化泛型装饰器等。在面试中,常见的 TypeScript 面试题主要围绕以下几个方面展开:

类型系统:考察对 TypeScript 类型系统的理解,包括基本类型、联合类型、交叉类型、接口、类型别名、类型推断、类型守卫等。

函数和类:涉及函数参数类型、返回值类型、箭头函数、函数重载、类的定义、继承、访问修饰符等概念。

泛型:考察在函数、类和接口中如何使用泛型来增加代码的灵活性和复用性。

模块化:问题可能涉及 ES6 模块化的语法、导入导出方式以及模块解析等内容。

装饰器:了解对装饰器的使用,包括类装饰器、方法装饰器、属性装饰器以及参数装饰器的定义和应用。

编译配置:熟悉 tsconfig.json 中的配置选项,包括编译目标、模块系统、严格模式等。

工程化实践:了解 TypeScript 在项目中的实际应用,如与 JavaScript 的混用、第三方库的声明文件使用、类型声明等。

下面是上述涵盖内容的具体面试题~👇

1. 什么是TypeScript

TypeScript是一种由微软开发的开源编程语言,它是JavaScript的超集。TypeScript通过添加静态类型接口模块等功能,使得在大型应用程序中更容易进行维护和扩展。它可以被编译为纯JavaScript,从而能够在任何支持JavaScript的地方运行。使用TypeScript可以帮助开发人员在编码过程中避免一些常见的错误,并提供更好的代码编辑功能和工具支持。

2. 类型声明和类型推断的区别,并举例应用

类型声明是显式地为变量或函数指定类型,而类型推断是TypeScript根据赋值语句右侧的值自动推断变量的类型。例如:

// 类型声明
let x: number;
x = 10;
// 类型推断
let y = 20; // TypeScript会自动推断y的类型为number
3. 什么是接口(interface),它的作用,接口的使用场景。接口和类型别名(Type Alias)的区别

接口是用于描述对象的形状的结构化类型。它定义了对象应该包含哪些属性和方法。在TypeScript中,接口可以用来约束对象的结构,以提高代码的可读性和维护性。例如:

interface Person {name: string;age: number;
}
function greet(person: Person) {return `Hello, ${person.name}!`;
}

接口类型别名的区别:

  • 接口定义了一个契约,描述了对象的形状(属性和方法),以便在多个地方共享。它可以被类、对象和函数实现。
  • 类型别名给一个类型起了一个新名字,便于在多处使用。它可以用于原始值、联合类型、交叉类型等。与接口不同,类型别名可以用于原始类型、联合类型、交叉类型等,而且还可以为任意类型指定名字。
4. 什么是泛型(generic),如何创建泛型函数和泛型类,实际用途

泛型是一种在定义函数、类或接口时使用类型参数的方式,以增加代码的灵活性和重用性。在TypeScript中,可以使用来创建泛型。例如:

function identity<T>(arg: T): T {return arg;
}
// 调用泛型函数
let output = identity<string>("hello");
5. 枚举(enum)是什么,它的优势,应用案例。枚举和常量枚举的区别

枚举是一种对数字值集合进行命名的方式。它们可以增加代码的可读性,并提供一种便捷的方式来使用一组有意义的常量。例如:

enum Color {Red,Green,Blue
}let selectedColor: Color = Color.Red;

枚举和常量枚举的区别:

  • 枚举可以包含计算得出的值,而常量枚举则在编译阶段被删除,并且不能包含计算得出的值,它只能包含常量成员。
  • 常量枚举在编译后会被删除,而普通枚举会生成真实的对象。
6. 如何处理可空类型(nullable types)和undefined类型,如何正确处理这些类型以避免潜在错误

在TypeScript中,可空类型是指一个变量可以存储特定类型的值,也可以存储nullundefined。(通过使用可空类型,开发者可以明确表达一个变量可能包含特定类型的值,也可能不包含值(即为nullundefined)。这有助于提高代码的可读性,并使得变量的可能取值范围更加清晰明了)。

为了声明一个可空类型,可以使用联合类型(Union Types),例如 number | nullstring | undefined。 例如:

let numberOrNull: number | null = 10; 
numberOrNull = null; // 可以赋值为null let stringOrUndefined: string | undefined = "Hello"; 
stringOrUndefined = undefined; // 可以赋值为undefined
7. 什么是联合类型和交叉类型

联合类型表示一个值可以是多种类型中的一种,而交叉类型表示一个新类型,它包含了多个类型的特性。

  • 联合类型示例:
// typescript
let myVar: string | number;
myVar = "Hello"; // 合法
myVar = 123; // 合法
  • 交叉类型示例:
interface A {a(): void;
}
interface B {b(): void;
}
type C = A & B; // 表示同时具备 A 和 B 的特性
8. 什么是TypeScript中的声明文件(Declaration Files)

声明文件(通常以 .d.ts 扩展名结尾)用于描述已有 JavaScript 代码库的类型信息。它们提供了类型定义和元数据,以便在 TypeScript 项目中使用这些库时获得智能感知和类型安全。

9. 什么是命名空间(Namespace)和模块(Module)

模块

  • 在一个大型项目中,可以将相关的代码组织到单独的文件,并使用模块来导入和导出这些文件中的功能。
  • 在一个 Node.js 项目中,可以使用 import 和 export 关键字来创建模块,从而更好地组织代码并管理依赖关系。

命名空间

  • 在面向对象的编程中,命名空间可以用于将具有相似功能或属性的类、接口等进行分组,以避免全局命名冲突。
  • 这在大型的 JavaScript 或 TypeScript 应用程序中特别有用,可以确保代码结构清晰,并且不会意外地重复定义相同的名称。

模块提供了一种组织代码的方式,使得我们可以轻松地在多个文件中共享代码,

命名空间则提供了一种在全局范围内组织代码的方式,防止命名冲突。

模块示例:

// greeter.ts
export function sayHello(name: string) {return `Hello, ${name}!`;
}
// app.ts
import { sayHello } from './greeter';
console.log(sayHello('John'));

命名空间示例:

// greeter.ts
namespace Greetings {export function sayHello(name: string) {return `Hello, ${name}!`;}
}
// app.ts
<reference path="greeter.ts" />
console.log(Greetings.sayHello('John'));

在上面的示例中:

  • 使用模块时,我们可以使用 exportimport 关键字来定义和引入模块中的函数或变量。

  • 而在命名空间中,我们使用 namespace 来创建命名空间,并且需要在使用之前使用 <reference path="file.ts" /> 来引入命名空间。

10. 什么是类型断言(Type Assertion)

类型断言允许程序员手动指定一个值的类型。这在需要明确告诉编译器某个值的类型时非常有用。

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
11. TypeScript中的可选参数和默认参数是什么
  • 可选参数允许函数中的某些参数不传值,在参数后面加上问号?表示可选。
  • 默认参数允许在声明函数时为参数指定默认值,这样如果调用时未提供参数值,则会使用默认值。

可选参数示例:

function greet(name: string, greeting?: string) {if (greeting) {return `${greeting}, ${name}!`;} else {return `Hello, ${name}!`;}
}

默认参数示例:

function greet(name: string, greeting: string = "Hello") {return `${greeting}, ${name}!`;
}
12. 类型守卫(Type Guards)是什么

类型守卫是一种用于在运行时检查类型的技术,它允许开发人员在特定的作用域内缩小变量的范围,以确保正确推断类型。

function isString(test: any): test is string {return typeof test === "string";
}
if (isString(input)) {// input 在此代码块中被收窄为 string 类型
}
13. 索引类型(Index Types)是什么,好处有什么

索引类型允许我们在 TypeScript 中创建具有动态属性名称的对象,并且能够根据已知的键来获取相应的属性类型。 好处:

1.动态属性访问

在处理动态属性名的对象时,可以使用索引类型来实现类型安全的属性访问。例如,当从服务器返回的 JSON 数据中提取属性时,可以利用索引类型来确保属性名存在并获取其对应的类型。

2.代码重用

当需要创建通用函数来操作对象属性时,索引类型可以帮助我们实现更加通用和灵活的代码。例如,一个通用的函数可能需要根据传入的属性名称获取属性值,并进行特定的处理。

interface ServerData {id: number;name: string;age: number;// 可能还有其他动态属性
}
function getPropertyValue(obj: ServerData, key: keyof ServerData): void {console.log(obj\[key]); // 确保 obj\[key] 的类型是正确的 // 这里可以直接使用索引类型来获取属性值
}

3.动态扩展对象

当需要处理来自外部来源(比如 API 响应或数据库查询)的动态数据时,索引类型可以让我们轻松地处理这种情况,而不必为每个可能的属性手动定义类型。

interface DynamicObject {[key: string]: number | string; // 允许任意属性名,但属性值必须为 number 或 string 类型}
function processDynamicData(data: DynamicObject): void {for (let key in data) {console.log(key + ": " + data\[key]); // 对任意属性进行处理}
}

4.类型安全性

索引类型可以增强代码的类型安全性,因为它们可以捕获可能的属性名拼写错误或键不存在的情况。

5.映射类型

TypeScript 还提供了映射类型(Mapped Types)的概念,它们利用索引类型可以根据现有类型自动生成新类型。这在创建新类型时非常有用,特别是当需要在现有类型的基础上添加或修改属性时。

14. const和readonly的区别

当在TypeScript中使用constreadonly时,它们的行为有一些显著的区别:

  • const:

    • const用于声明常量值。一旦被赋值后,其值将不能被重新赋值或修改。
    • 常量必须在声明时就被赋值,并且该值不可改变。
    • 常量通常用于存储不会发生变化的值,例如数学常数或固定的配置值。
const PI = 3.14;
PI = 3.14159; // Error: 无法重新分配常量
  • readonly:

    • readonly关键字用于标记类的属性,表明该属性只能在类的构造函数或声明时被赋值,并且不能再次被修改。
    • readonly属性可以在声明时或构造函数中被赋值,但之后不能再被修改。
    • readonly属性通常用于表示对象的某些属性是只读的,防止外部代码修改这些属性的值。
class Person {readonly name: string;constructor(name: string) {this.name = name; // 可以在构造函数中赋值}
}let person = new Person("Alice");
person.name = "Bob"; // Error: 无法分配到"name",因为它是只读属性

总结来说,const主要用于声明常量值,而readonly则用于标记类的属性使其只读。

15. TypeScript 中 any 类型的作用是什么,滥用会有什么后果

在TypeScript中,any类型的作用是允许我们在编写代码时不指定具体的类型,从而可以接受任何类型的值。使用any类型相当于放弃了对该值的静态类型检查,使得代码在编译阶段不会对这些值进行类型检查。

主要情况下,any类型的使用包括以下几点:

  • 当我们不确定一个变量或表达式的具体类型时,可以使用any类型来暂时绕过类型检查。

  • 在需要与动态类型的JavaScript代码交互时,可以使用any类型来处理这些动态类型的值。

  • 有时候某些操作难以明确地定义其类型,或者需要较复杂的类型推导时,也可以使用any类型。

滥用的后果:

尽管any类型提供了灵活性,但由于它会放弃TypeScript的静态类型检查,因此滥用any类型可能会降低代码的健壮性和可维护性。当滥用any类型时,可能会导致以下后果:

1.代码可读性下降:

let data: any;
// 代码中的使用方式
data.someUnknownMethod(); // 在编译阶段不会报错,但实际上可能是一个错误

2.潜在的运行时错误:

let myVariable: any = 123;
myVariable.toUpperCase(); // 在编译阶段不会报错,但在运行时会引发错误

3.类型安全受损:

function add(x: any, y: any): any {return x + y; // 编译器无法推断返回值的具体类型
}

滥用any类型会导致代码失去了TypeScript强大的类型检查功能,带来了如下问题:

  • 可能引入未知的运行时行为和错误。
  • 降低了代码的可维护性和可读性,因为难以理解某些变量或参数的具体类型。

因此,在实际开发中,应尽量避免过度使用any类型。可以通过合适的类型声明、接口定义和联合类型等方式,提高代码的健壮性和可维护性。

16. TypeScript中的this有什么需要注意的

在TypeScript中,与JavaScript相比,this的行为基本上是一致的。然而,TypeScript提供了类型注解和类型检查,可以帮助开发者更容易地理解和处理this关键字的使用。

在noImplicitThis为true 的情况下,必须声明 this 的类型,才能在函数或者对象中使用this。

Typescript中箭头函数的 this 和 ES6 中箭头函数中的 this 是一致的。

在TypeScript中,当将noImplicitThis设置为true时,意味着在函数或对象中使用this时,必须显式声明this的类型。这一设置可以帮助开发者更明确地指定this的类型,以避免因为隐式的this引用而导致的潜在问题。

具体来说,如果将noImplicitThis设置为true,则在下列情况下必须显式声明this的类型:

  • 在函数内部使用this时,需要使用箭头函数或显示绑定this。
  • 在某些类方法或对象方法中,需要明确定义this的类型。

示例代码如下所示:

class MyClass {private value: number = 42;public myMethod(this: MyClass) {console.log(this.value);}public myMethod2 = () => {console.log(this.value);}
}let obj = new MyClass();
obj.myMethod(); // 此处必须传入合适的 this 类型

通过将noImplicitThis设置为true,TypeScript要求我们在使用this时明确指定其类型,从而在编译阶段进行更严格的类型检查,帮助避免一些可能出现的错误和不确定性。

注:noImplicitThis是TypeScript编译器的一个配置选项,用于控制在函数或对象方法中使用this时的严格性。当将noImplicitThis设置为true时,意味着必须显式声明this的类型,否则会触发编译错误。

17. TypeScript数据类型

在TypeScript中,常见的数据类型包括以下几种:

  • 基本类型

    • number: 表示数字,包括整数和浮点数。
    • string: 表示文本字符串。
    • boolean: 表示布尔值,即truefalse
    • nullundefined: 分别表示null和undefined。
    • symbol: 表示唯一的、不可变的值。
  • 复合类型

    • array: 表示数组,可以使用number[]Array<number>来声明其中元素的类型。
    • tuple: 表示元组,用于表示固定数量和类型的数组。
    • enum: 表示枚举类型,用于定义具名常量集合。
  • 对象类型

    • object: 表示非原始类型,即除number、string、boolean、symbol、null或undefined之外的类型。
    • interface: 用于描述对象的结构,并且可以重复使用。
  • 函数类型

    • function: 表示函数类型。
    • void: 表示函数没有返回值。
    • any: 表示任意类型。
  • 高级类型

    • union types: 表示一个值可以是几种类型之一。
    • intersection types: 表示一个值同时拥有多种类型的特性。
18. interface可以给Function/Array/Class(Indexable)做声明吗

在TypeScript中,interface可以用来声明函数、数组和类(具有索引签名的类)。下面是一些示例代码:

1. Interface 声明函数

interface MyFunc {(x: number, y: number): number;
}let myAdd: MyFunc = function(x, y) {return x + y;
};

在上述示例中,MyFunc接口描述了一个函数类型,该函数接受两个参数并返回一个数字。

2. Interface 声明数组

interface StringArray {[index: number]: string;
}let myArray: StringArray;
myArray = ["Bob", "Alice"];

上面的示例中,StringArray接口描述了一个具有数字索引签名的字符串数组。意味着我们可以通过数字索引来访问数组元素。

3. Interface 声明类(Indexable)

interface StringDictionary {[index: string]: string;
}let myDict: StringDictionary = {"name": "John","age": "30"
};

在这个例子中,StringDictionary接口用于描述具有字符串索引签名的类或对象。这使得我们可以像操作字典一样使用对象的属性。

综上:TypeScript中的interface可以被用来声明函数、数组和具有索引签名的类,从而帮助我们定义和限定这些数据结构的形式和行为。

19. TypeScript中的协变、逆变、双变和抗变是什么

在TypeScript中,协变(Covariance)逆变(Contravariance)双变(Bivariance)抗变(Invariance 是与类型相关的概念,涉及到参数类型的子类型关系。下面对这些概念进行解释,并提供示例代码。

协变(Covariance)

  • 区别:协变意味着子类型可以赋值给父类型。
  • 应用场景:数组类型是协变的,因此可以将子类型的数组赋值给父类型的数组。

协变表示类型T的子类型可以赋值给类型U,当且仅当T是U的子类型。在TypeScript中,数组是协变的,这意味着可以将子类型的数组赋值给父类型的数组。

let subtypes: string[] = ["hello", "world"];
let supertype: Object[] = subtypes; // 数组是协变的,这是合法的

逆变(Contravariance)

  • 区别:逆变意味着超类型可以赋值给子类型。
  • 应用场景:函数参数类型是逆变的,因此可以将超类型的函数赋值给子类型的函数。

逆变表示类型T的超类型可以赋值给类型U,当且仅当T是U的子类型。在TypeScript中,函数参数是逆变的,这意味着可以将超类型的函数赋值给子类型的函数。

type Logger<T> = (arg: T) => void;
let logNumber: Logger<number> = (x: number) => console.log(x);
let logAny: Logger<any> = logNumber; // 函数参数是逆变的,这是合法的

双变(Bivariance)

  • 区别:双变允许参数类型既是协变又是逆变的。
  • 应用场景:对象类型是双变的,这意味着可以将子类型的对象赋值给父类型的对象,同时也可以将超类型的对象赋值给子类型的对象。

双变允许参数类型既是协变又是逆变的。在TypeScript中,普通对象类型是双变的,这意味着可以将子类型的对象赋值给父类型的对象,并且可以将超类型的对象赋值给子类型的对象。

interface Animal {name: string;
}interface Dog extends Animal {breed: string;
}let animal: Animal = { name: "Animal" };
let dog: Dog = { name: "Dog", breed: "Labrador" };animal = dog; // 对象类型是双变的,这是合法的
dog = animal; // 对象类型是双变的,这也是合法的

抗变(Invariance)

  • 区别:抗变表示不允许类型之间的任何赋值关系。
  • 应用场景:通常情况下,基本类型和类类型是抗变的。

抗变表示不允许类型T和U之间的任何赋值关系,即T既不是U的子类型,也不是U的超类型。在TypeScript中,一般情况下,基本类型类类型是抗变的。

let x: string = "hello";
let y: string = x; // 这是合法的let a: Animal = { name: "Animal" };
let b: Animal = a; // 这也是合法的
20. TypeScript中的静态类型和动态类型有什么区别
  • 静态类型是在 编译期间 进行类型检查,可以在编辑器或 IDE 中发现大部分类型错误。
  • 动态类型是在 运行时 才确定变量的类型,通常与动态语言相关联。

静态类型(Static Typing)

  • 定义:静态类型是指在编译阶段进行类型检查的类型系统,通过类型注解或推断来确定变量、参数和返回值的类型。
  • 特点:静态类型能够在编码阶段就发现大部分类型错误,提供了更好的代码健壮性和可维护性。
  • 优势:可以在编辑器或 IDE 中实现代码提示、自动补全和类型检查,帮助开发者减少错误并提高代码质量。

动态类型(Dynamic Typing)

  • 定义:动态类型是指在运行时才确定变量的类型,通常与动态语言相关联,允许同一个变量在不同时间引用不同类型的值。
  • 特点:动态类型使得变量的类型灵活多变,在运行时可以根据上下文或条件动态地改变变量的类型。
  • 优势:动态类型可以带来更大的灵活性,适用于一些需要频繁变化类型的场景。

区别总结

  • 时机差异:静态类型在编译期间进行类型检查,而动态类型是在运行时才确定变量的类型。
  • 代码稳定性:静态类型有助于在编码阶段发现大部分类型错误,提高代码稳定性;动态类型对类型的要求较为灵活,但可能增加了代码的不确定性。
  • 使用场景:静态类型适合于大型项目和团队,能够提供更强的类型安全性;动态类型适用于快速原型开发和灵活多变的场景,能够更快地迭代和测试代码。
21. 介绍TypeScript中的可选属性、只读属性和类型断言
  • 可选属性 使用 ? 来标记一个属性可以存在,也可以不存在。
  • 只读属性 使用 readonly 关键字来标记一个属性是只读的。
  • 类型断言 允许将一个实体强制指定为特定的类型,使用 <Type>value as Type

代码示例:

// 可选属性
interface Person {name: string;age?: number; // 可选属性
}// 只读属性
interface Point {readonly x: number;readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // Error: 只读属性无法重新赋值// 类型断言
let someValue: any = "hello";
let strLength: number = (someValue as string).length;
22. TypeScript 中的模块化是如何工作的,举例说明

答案:

  • TypeScript 中使用 ES6 模块系统,可以使用 importexport 关键字来导入和导出模块。
  • 可以通过 export default 导出默认模块,在导入时可以使用 import moduleName from 'modulePath'

代码示例:

// math.ts
export function sum(a: number, b: number): number {return a + b;
}
export function subtract(a: number, b: number): number {return a - b;
}// app.ts
import { sum, subtract } from './math';
console.log(sum(3, 5)); // 输出 8

结尾

本文整理了一些ts的常见面试问题,希望对你的理解有所帮助。

❤️ 未来也会继续更新文章,欢迎围观!如有不足与错误也欢迎指正! 如果这篇文章对您有帮助麻烦 点赞、收藏 + 关注,与我一起成长!❤️

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

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

相关文章

【Linux】nmcli命令详解

目录 ​编辑 一、概述 二、常用参数使用 2.1 nmcli networking 1.显示NM是否接管网络 2.查看网络连接状态 3.开/关网络连接 2.2 general ​编辑 1.显示系统网络状态 2.显示主机名 3.更改主机名 2.3 nmcli connection ​编辑1.显示所有网络连接 2.显示某个网卡的…

【数据结构】快速排序(用递归)

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解快速排序&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一. 基本思想二. 快速排序2.1 hoare版本2.2 挖坑法2.3 前后指针法2.4 快速排序优化三数取中法…

【Android】【Bluetooth Stack】蓝牙电话协议之接听电话分析(超详细)

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待&#xff0…

MySQL详解

本笔记源于【狂神说Java】 B站收UP主&#xff1a;遇见狂神说。即可看见教程 或者点击链接MySQL最新教程 目录 1、初始MySQL 1.1、数据库简介 1.2、数据库管理系统 1.3、MySQL简介及安装 1.4、SQLyog 2、操作数据库 2.1、操作数据库&#xff08;了解&#xff09; 2.2、数…

WM8978 —— 带扬声器驱动程序的立体声编解码器(2)

接前一篇文章&#xff1a;WM8978 —— 带扬声器驱动程序的立体声编解码器&#xff08;1&#xff09; 六、引脚详细说明 引脚&#xff08;PIN&#xff09;名称&#xff08;NAME&#xff09;类型&#xff08;TYPE&#xff09;描述&#xff08;DESCRIPTION&#xff09;1LIP模拟输入…

006、Dynamo Python 之Revit元素类别

今天我们来聊聊 Revit 元素这点事&#xff0c;不仅仅是在 Dynamo Python 之中涉及&#xff0c;我们在日常使用 Revit 的时候&#xff0c;也涉及这个问题&#xff0c;只是对我们日常画图没什么影响&#xff0c;所以很多人并没太在意这块。 Revit Elements 分为六个组&#xff1a…

Redis实战篇-4

实战篇Redis 1.3 、实现发送短信验证码功能 页面流程 具体代码如下 贴心小提示&#xff1a; 具体逻辑上文已经分析&#xff0c;我们仅仅只需要按照提示的逻辑写出代码即可。 发送验证码 Overridepublic Result sendCode(String phone, HttpSession session) {// 1.校验手机…

算法打卡day15

今日任务&#xff1a; 1&#xff09;110.平衡二叉树 2&#xff09;257. 二叉树的所有路径 3&#xff09;404.左叶子之和 110.平衡二叉树 题目链接&#xff1a;110. 平衡二叉树 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树…

基于大数据的空气质量预测和可视化分析

城市空气质量数据采集系统设计与实现 &#x1f3d9;️ 研究背景 &#x1f32c;️ 城市化与环境挑战&#xff1a;随着城市化进程的加快&#xff0c;环境污染问题&#xff0c;尤其是空气质量问题&#xff0c;已成为公众关注的焦点。数据监测的重要性&#xff1a;城市空气质量数…

控价其实是对品牌市场的保护

品牌发展过程中&#xff0c;如果有越来越多的经销商加入&#xff0c;必然要做好控价&#xff0c;否则渠道的混乱&#xff0c;会使得品牌价值受损&#xff0c;比如低价的出现&#xff0c;会影响正规经销商的出货&#xff0c;使其竞争力增加&#xff0c;同时价格的不稳定会连带产…

小游戏-扫雷

扫雷大多人都不陌生&#xff0c;是一个益智类的小游戏&#xff0c;那么我们能否用c语言来编写呢&#xff0c; 我们先来分析一下扫雷的运行逻辑&#xff0c; 首先&#xff0c;用户在进来时需要我们给与一个菜单&#xff0c;以供用户选择&#xff0c; 然后我们来完善一下&#…

Vue 实现带拖动功能的时间轴

1.效果图 2. 当使用timeline-slider-vue组件时&#xff0c;你可以设置以下属性&#xff1a; date&#xff1a;用于设置时间轴滑块的初始日期&#xff0c;格式通常为 YYYY-MM-DD。 mask&#xff1a;一个布尔值&#xff0c;用于控制是否显示背景遮罩。 markDate&#xff1a;一…

Java 面试宝典:什么是大 key 问题?如何解决?

大家好&#xff0c;我是大明哥&#xff0c;一个专注「死磕 Java」系列创作的硬核程序员。 本文已收录到我的技术网站&#xff1a;https://skjava.com。有全网最优质的系列文章、Java 全栈技术文档以及大厂完整面经 回答 Redis 大 key 问题是指某个 key 对应的 value 值很大&am…

C语言——sizeof与strlen的对比

一.sizeof 我们在学习操作符的时候&#xff0c;就了解到了sizeof操作符&#xff0c;它的作用是求参数所占内存空间的大小&#xff0c;单位是字节。如果参数是一个类型&#xff0c;那就返回参数所占的字节数。 #include <stdio.h>int main() {int a 10;size_t b sizeo…

Mamba 基础讲解【SSM,LSSL,S4,S5,Mamba】

文章目录 Mamba的提出动机TransformerRNN Mama的提出背景状态空间模型 (The State Space Model, SSM)线性状态空间层 (Linear State-Space Layer, LSSL)结构化序列空间模型 &#xff08;Structured State Spaces for Sequences, S4&#xff09; Mamba的介绍Mamba的特性一&#…

美团2024届秋招笔试第二场编程真题

要么是以0开头 要么以1开头 选择最小的答案累加 import java.util.Scanner; import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和…

C# 右键快捷菜单(上下文菜单)的两种实现方式

在C#中&#xff0c;ContextMenuStrip是一种用于创建右键菜单的控件。它提供了一种方便的方式来为特定的控件或窗体添加自定义的上下文菜单选项。有两种实现方式&#xff0c;如下&#xff1a; 一.通过ContextMenuStrip控件实现 1.从工具箱中拖一个ContextMenuStrip控件到窗体上…

LLM - 大语言模型的分布式训练 概述

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/136924304 大语言模型的分布式训练是一个复杂的过程&#xff0c;涉及到将大规模的计算任务分散到多个计算节点上。这样做的目的是为了处…

领域、系统和组织-《实现领域驱动设计》中译本评点-第2章(4)

相关链接 DDD领域驱动设计批评文集>> 汪峰哭晕在厕所-《实现领域驱动设计》中译本评点-第2章&#xff08;1&#xff09; 可不是乱打的-《实现领域驱动设计》中译本评点-第2章&#xff08;2&#xff09; “领域”的错误定义-《实现领域驱动设计》中译本评点-第2章&…

Tomcat介绍,Tomcat服务部署

目录 一、Tomcat 介绍 二、Tomcat 核心技术和组件 2.1、Web 容器&#xff1a;完成 Web 服务器的功能 2.2、Servlet 容器&#xff0c;名字为 catalina&#xff0c;用于处理 Servlet 代码 2.3、JSP 容器&#xff1a;用于将 JSP 动态网页翻译成 Servlet 代码 Tomcat 功能组件…