TypeScript 与 JavaScript 的区别

TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(ES6 教程)。TypeScript 由微软开发的自由和开源的编程语言。TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

TypeScript 是一种给 JavaScript 添加特性的语言扩展。增加的功能包括:

  • 类型批注和编译时类型检查
  • 类型推断
  • 类型擦除
  • 接口
  • 枚举
  • Mixin
  • 泛型编程
  • 名字空间
  • 元组
  • Await 

从 ECMA 2015 反向移植而来:

  • 模块
  • lambda 函数的箭头语法
  • 可选参数以及默认参数

TypeScript 与 JavaScript 的区别

TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。

TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

 第一个TypeScript实例:

const greet : string = "Hello World!"
console.log(greet)

为了演示方便,本文中的例子均在vue3项目运行。

TypeScript基础语法

第一个TypeScript程序(之后的代码演示省略<script>标签,也不展示控制台截图)

<script lang="ts">const greet : string = "hello world!"console.log(greet);
</script>

对比一下JavaScript的代码

const greet = "hello world!"
console.log(greet);

TypeScript中的保留字与JavaScript基本一致

TypeScript 会忽略程序中出现的空格、制表符和换行符。空格、制表符通常用来缩进代码,使代码易于阅读和理解。TypeScript 区分大写和小写字符。每行指令都是一段语句,你可以使用分号或不使用, 分号在 TypeScript 中是可选的,建议使用。注释与JavaScript使用一致。

TypeScript基础类型

any(任意类型):声明为 any 的变量可以赋予任意类型的值。

number(数字类型):双精度 64 位浮点值。它可以用来表示整数和分数。

string(字符串类型):一个字符系列,使用单引号(')或双引号(")来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式。

boolean(布尔类型):表示逻辑值:true 和 false。

数组类型、元组。

enum(枚举类型):枚举类型用于定义数值集合。

void:用于标识方法返回值的类型,表示该方法没有返回值。

null:表示对象值缺失。

undefined:用于初始化变量为一个未定义的值。

never:never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

Any

任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型,它常用于以下情况。

1、变量的值会动态改变时,比如来自用户的输入,任意值类型可以让这些变量跳过编译阶段的类型检查,示例代码如下:

let flag: any = 1;    // 数字类型
flag = 'my name is leo';    // 字符串类型
flag = true;    // 布尔类型

2、定义存储各种类型数据的数组时,示例代码如下:

let list: any[] = ['leo',25,true];
list[1] = 'lion';

Null Undefined

null,在 JavaScript 中 null 表示 "什么都没有"。null是一个只有一个值的特殊类型。表示一个空对象引用。用 typeof 检测 null 返回是 object。

undefined,在 JavaScript 中, undefined 是一个没有设置值的变量。typeof 一个没有值的变量会返回 undefined。Null 和 Undefined 是其他任何类型(包括 void)的子类型,可以赋值给其它类型,即其他类型可以转成这两种类型,如字符串类型,此时,赋值后的类型会变成 null 或 undefined。

let num: number;
num = 1; // 运行正确
num = undefined;    // 运行正确,此时为undefined类型
num = null;    // 运行正确,此时为null类型

Never

never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。这意味着声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环),示例代码如下:

let n: never;
let num: number;// 运行错误,数字类型不能转为never类型
n = 123;// 运行正确,never 类型可以赋值给never类型
n = (()=>{ throw new Error('exception')})();// 运行正确,never 类型可以赋值给数字类型
num = (()=>{ throw new Error('exception')})();// 返回值为never的函数可以是抛出异常的情况
function error(message: string): never {throw new Error(message);
}// 返回值为never的函数可以是无法被执行到的终止点的情况
function loop(): never {while (true) {}
}

TypeScript变量声明

TypeScript 变量的命名规则:

1、变量名称可以包含数字和字母。

2、除了下划线 _ 和美元 $ 符号外,不能包含其他特殊字符,包括空格。

3、变量名不能以数字开头。

以下为四种声明变量的方式

//var [变量名] : [类型] = 值; 声明变量的类型及初始值
var uname:string = "leo";//var [变量名] : [类型]; 声明变量的类型,但没有初始值,变量值会设置为undefined
var uname:string;//var [变量名] = 值; 声明变量并初始值,但不设置类型,该变量可以是任意类型
var uname = "leo";//var [变量名]; 声明变量没有设置类型和初始值,类型可以是任意类型,默认初始值为undefined
var uname;//总结:声明时,没有类型,类型就是any;没有初始值,初始值就是undefined

实例:

var uname:string = "leo";
var age:number = 25;//对应js
var uname = "leo";
var age = 25;

TypeScript 遵循强类型,如果将不同的类型赋值给变量会编译错误,而JavaScript则不会,因为她是弱类型语言,如下实例:

var num:number = "leo"     // 编译错误//对应的js
var num = 100
num = "leo"     // 编译不报错

类型推断

当类型没有给出时,TypeScript 编译器利用类型推断来推断类型。如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。

var num = 100;    // 类型推断为 number
num = "leo";      // 编译错误,相当于上例 var num:number = "leo"

变量作用域

TypeScript 有以下几种作用域:

全局作用域 − 全局变量定义在程序结构的外部,它可以在你代码的任何位置使用。

类作用域 − 这个变量也可以称为 字段。类变量声明在一个类里头,但在类的方法外面。 该变量可以通过类的对象来访问。类变量也可以是静态的,静态的变量可以通过类名直接访问。

局部作用域 − 局部变量,局部变量只能在声明它的一个代码块(如:方法)中使用。

如以下例子:

var global_num = 10          // 全局变量
class Person { age = 18;                 // 实例变量static score = 100;       // 静态变量eat():void { var food = 'apple';    // 局部变量} 
}console.log("全局变量为: " + global_num)  
console.log(Person.score)    // 静态变量,直接通过类名访问
var person = new Person(); 
console.log("实例变量: " + person.age)

TypeScript的运算符、条件语句、循环与JavaScript基本一致。

TypeScript函数

function function_name()
{// 执行代码
}//调用函数
function_name()

函数返回值 

TypeScript的函数返回值与JavaScript的函数返回值略有不同。TypeScript的函数返回值的格式:

function function_name():return_type { // 语句return value; 
}//与js相比,ts的函数返回值需要指定 return_type返回值的类型。

如下实例:

//ts
function greet():string { // 返回一个字符串return "Hello World!" 
}//js
function greet() {return "Hello World!" 
}

带参数函数

语法格式如下所示:

function func_name( param1 [:datatype], param2 [:datatype]) {   //datatype为参数类型//执行代码  
}

实例:

//ts
function add(x: number, y: number): number {  //函数返回值为number,参数的数据类型也为numberreturn x + y;
}//js
function add(x, y) {return x + y;
}

可选参数和默认参数

可选参数,在 TypeScript 函数里,如果我们定义了几个参数,则我们必须传入几个参数,除非将这些参数设置为可选,可选参数使用问号标识 ?。

function fullName(firstName: string, lastName: string) {  //调用函数必须传入两个参数,否则报错return firstName + " " + lastName;
}let name1 = buildName("leo");                  // 错误,缺少参数
let name2 = buildName("leo", "lion", "gao");   // 错误,参数太多了
let name3 = buildName("leo", "lion");          // 正确

修改为可选参数之后

function fullName(firstName: string, lastName?: string) { //此时lastName为可选参数,非必传if(lastName){return firstName + " " + lastName;}else {return firstName;}}let name1 = buildName("leo");                  // 正确
let name2 = buildName("leo", "lion", "gao");   // 错误,参数太多了
let name3 = buildName("leo", "lion");          // 正确//ts函数设置可选参数时,只能少传,不能多传,相比之下,js函数的参数可以多传,按顺序取参数。

默认参数,可以设置参数的默认值,这样在调用函数的时候,如果不传入该参数的值,则使用默认参数,语法格式为:

function function_name(param1[:type],param2[:type] = default_value) {//执行代码
}//default_value为默认值,当不传入该参数时,取默认值。

注意:参数不能同时设置为可选和默认。 

以下实例函数的参数lastName设置了默认值为'lion',调用该函数时如果未传入参数则使用该默认值:

function fullName(firstName:string,lastName:string = 'lion') {  console.log(firstName + " " + lastName); 
}fullName('leo')         //leo lion,lastName取默认值
fullName('leo','gao')   //leo gao

剩余参数

有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义。剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。

function fullName(firstName: string, ...restOfName: string[]) {return firstName + " " + restOfName.join(" ");
}let uname = fullName("leo", "lion", "ggj", "gao");

匿名函数

匿名函数是一个没有函数名的函数。匿名函数在程序运行时动态声明,除了没有函数名外,其他的与标准函数一样。我们可以将匿名函数赋值给一个变量,这种表达式就成为函数表达式。

var greet = function() {  //不带参数的匿名函数return "hello world!";  
} 
console.log(msg())var add = function(a,b) {  //带参数的匿名函数return a + b;  
} 
console.log(add(2,3))

匿名函数自调用

(function () { var str = "Hello World!";   console.log(str)     })()

构造函数

TypeScript 也支持使用 JavaScript 内置的构造函数 Function() 来定义函数:

var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)
var myFunction = new Function("a", "b", "return a * b"); 
var x = myFunction(4, 3); 
console.log(x);

箭头函数

( [param1, parma2,…param n] )=>statement;
var add = (x:number)=> {    x = 10 + x console.log(x)  
} 
foo(100)

我们可以不指定函数的参数类型,通过函数内来推断参数类型:

var func = (x)=> { if(typeof x=="number") { console.log(x+" 是一个数字") } else if(typeof x=="string") { console.log(x+" 是一个字符串") }  
} 
func(12) 
func("Tom")

 更多例子

var display = x => {      //单个参数 () 是可选的console.log("输出为 "+x) 
} 
display(12)var disp =()=> {     //无参数时可以设置空括号console.log("Function invoked"); 
} 
disp();

函数重载

重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

//参数类型与参数数量不同
function disp(s1:string):void; 
function disp(n1:number,s1:string):void; function disp(x:any,y?:any):void { console.log(x); console.log(y); 
}

TypeScript中的Number、String、Array(数组)类型语JavaScript基本一致。

TypeScript Map对象

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。Map 是 ES6 中引入的一种新的数据结构,可以参考 ES6 Map 与 Set。

TypeScript 使用 Map 类型和 new 关键字来创建 Map:

let myMap = new Map();

初始化 Map,可以以数组的格式来传入键值对:

let myMap = new Map([["key1", "value1"],["key2", "value2"]
]); 

let nameSiteMapping = new Map();// 设置 Map 对象
nameSiteMapping.set("Google", 1);
nameSiteMapping.set("Runoob", 2);
nameSiteMapping.set("Taobao", 3);// 获取键对应的值
console.log(nameSiteMapping.get("Runoob"));     // 2// 判断 Map 中是否包含键对应的值
console.log(nameSiteMapping.has("Taobao"));       // true
console.log(nameSiteMapping.has("Zhihu"));        // false// 返回 Map 对象键/值对的数量
console.log(nameSiteMapping.size);                // 3// 删除 Runoob
console.log(nameSiteMapping.delete("Runoob"));    // true
console.log(nameSiteMapping);
// 移除 Map 对象的所有键/值对
nameSiteMapping.clear();             // 清除 Map
console.log(nameSiteMapping);

使用for...of来迭代Map对象。

let nameSiteMapping = new Map();nameSiteMapping.set("Google", 1);
nameSiteMapping.set("Runoob", 2);
nameSiteMapping.set("Taobao", 3);// 迭代 Map 中的 key
for (let key of nameSiteMapping.keys()) {console.log(key);                  
}// 迭代 Map 中的 value
for (let value of nameSiteMapping.values()) {console.log(value);                 
}// 迭代 Map 中的 key => value
for (let entry of nameSiteMapping.entries()) {console.log(entry[0], entry[1]);   
}

TypeScript元组

我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。元组中允许存储不同类型的元素,元组可以作为参数传递给函数。

创建元组的语法格式如下:

var tuple_name = [value1,value2,value3,…value n]

实例

//声明一个元组并初始化
var mytuple = [10,'leo',25,true];//也可以先声明一个空元组,然后再初始化
var mytuple = []; 
mytuple[0] = 10
mytuple[1] = 'leo'
mytuple[2] = 25
mytuple[3] = true//访问元组,使用索引来访问
tuple_name[index]

元组运算

1、push() 向元组添加元素,添加在最后面。

2、pop() 从元组中移除元素(最后一个),并返回移除的元素。

var mytuple = [10,"Hello","World","typeScript"];mytuple.push(25)  // [10,"Hello","World","typeScript",25]mytuple.pop()  // [10,"Hello","World","typeScript"]

更新元组

元组是可变的,这意味着我们可以对元组进行更新操作:、

var mytuple = [10, "leo", "lion"]; // 创建一个元组// 更新元组元素
mytuple[0] = 25     // [25, "leo", "lion"]

解构元组

我们也可以把元组元素赋值给变量,如下所示:

var user =[25,"leo"] 
var [age,uname] = user
console.log( age )       // 25
console.log( uname )     // 'leo'

TypeScript联合类型

联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值。

注意:只能赋值指定的类型,如果赋值其它类型就会报错。

Type1|Type2|Type3

实例

//声明一个联合类型
var flag:string|number|booleanflag = 25
console.log("数字为 ", flag)   // 数字为 25flag = 'leo' 
console.log("字符串为 ", flag)   // 字符串为 leoflag = true 
console.log("布尔值为 ", flag)   //布尔值为 true

如果赋值其它类型就会报错:

var flag:string|numberflag = true  //报错,联合类型不包括boolean

也可以将联合类型作为函数参数使用:

function fullName(name:string|string[]) {  //此时参数类型可以是字符串,也可以是字符串数组if(typeof name == "string") { console.log(name) } else {var i; for(i = 0;i<name.length;i++) { console.log(name[i])} } 
}fullName("leo")
fullName(["leo","lion","ggj","gao"])

也可以将数组声明为联合类型:

var arr:number[]|string[];  //数字数组或者字符串数组

TypeScript接口

接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。

TypeScript 接口定义如下:

interface interface_name {}

实例

以下实例中,我们定义了一个接口 IPerson,接着定义了一个变量 customer,它的类型是 IPerson。customer 实现了接口 IPerson 的属性和方法。

interface IPerson { firstName:string, lastName:string, sayHi: ()=>string 
} //实现接口
var customer:IPerson = { firstName:"Tom",lastName:"Hanks", sayHi: ():string =>{return "Hi there"} 
}//实现接口
var employee:IPerson = { firstName:"Jim",lastName:"Blakes", sayHi: ():string =>{return "Hello!!!"} 
}

联合类型和接口

以下实例演示了如何在接口中使用联合类型:

interface RunOptions { program:string; commandline:string[]|string|(()=>string); 
} // commandline 是字符串
var options:RunOptions = {program:"test1",commandline:"Hello"}; 
console.log(options.commandline)  // commandline 是字符串数组
options = {program:"test1",commandline:["Hello","World"]}; 
console.log(options.commandline[0]); 
console.log(options.commandline[1]);

接口继承

接口继承就是说接口可以通过其他接口来扩展自己。Typescript 允许接口继承多个接口。继承使用关键字 extends。

//单接口继承
Child_interface_name extends super_interface_name//多接口继承,继承的各个接口使用逗号 , 分隔。
Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name

单实例继承 

interface Person { age:number 
} interface Musician extends Person { instrument:string 
} var drummer = <Musician>{}; 
drummer.age = 25 
drummer.instrument = "Drums" 
console.log("年龄:  "+drummer.age)
console.log("喜欢的乐器:  "+drummer.instrument)// 年龄:  25
// 喜欢的乐器:  Drums

多实例继承

interface IParent1 { v1:number 
} interface IParent2 { v2:number 
} interface Child extends IParent1, IParent2 { } 
var Iobj:Child = { v1:12, v2:23} 

TypeScript类

TypeScript 是面向对象的 JavaScript。类描述了所创建的对象共同的属性和方法。TypeScript 支持面向对象的所有特性,比如 类、接口等。

TypeScript 类定义方式如下:

class class_name { // 类作用域
}

定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):

1、字段 − 字段是类里面声明的变量。字段表示对象的有关数据。

2、构造函数 − 类实例化时调用,可以为类的对象分配内存。

3、方法 − 方法为对象要执行的操作。

实例,创建类的数据成员:

class Car { // 字段 color:string; // 构造函数 constructor(color:string) { this.color = color}  // 方法 show():void {console.log("颜色为 :   " + this.color) } 
}

我们使用 new 关键字来实例化类的对象,类实例化时会调用构造函数,例如:

var obj = new Car("blue")

类中的字段属性和方法可以使用 . 号来访问:

// 访问属性
obj.color // 访问方法
obj.show()

类的继承

TypeScript 支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。类继承使用关键字 extends,子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承。TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)。

实例

类的继承:实例中创建了 Shape 类,Circle 类继承了 Shape 类,Circle 类可以直接使用 Area 属性:

class Shape { Area:number constructor(a:number) { this.Area = a } 
} class Circle extends Shape { show():void { console.log("圆的面积:  "+this.Area) } 
}var obj = new Circle(223); 
obj.show()        // 圆的面积:  223

需要注意的是子类只能继承一个父类,TypeScript 不支持继承多个类,但支持多重继承,如下实例:

class Root { str:string; 
} class Child extends Root {} 
class Leaf extends Child {} // 多重继承,继承了 Child 和 Root 类

继承类的方法重写

类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写。其中 super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法。

class PrinterClass { doPrint():void {console.log("父类的 doPrint() 方法。") } 
} class StringPrinter extends PrinterClass { doPrint():void { super.doPrint() // 调用父类的函数console.log("子类的 doPrint()方法。")   //此处对父类方法进行重写} 
}

static关键字

上面提到,static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。

class StaticMem {  static num:number; static disp():void { console.log("num 值为 "+ StaticMem.num) } 
} //直接通过类名调用静态属性和方法
StaticMem.num = 12     // 初始化静态变量
StaticMem.disp()       // 调用静态方法

扩展:instanceof 运算符用于判断对象是否是指定的类型,如果是返回 true,否则返回 false。

class Person { } 
var obj = new Person() 
var isPerson = obj instanceof Person;    //true

访问控制修饰符

TypeScript 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。TypeScript 支持 3 种不同的访问权限。

1、public(默认) : 公有,可以在任何地方被访问。

2、protected : 受保护,可以被其自身以及其子类和父类访问。

3、private : 私有,只能被其定义所在的类访问。

以下实例定义了两个变量 str1 和 str2,str1 为 public,str2 为 private,实例化后可以访问 str1,如果要访问 str2 则会编译错误。

class Encapsulate { str1:string = "Hello" private str2:string = "World"
}var obj = new Encapsulate() 
console.log(obj.str1)     // 可访问 
console.log(obj.str2)   // 编译错误, str2 是私有属性

类和接口

类可以实现接口,使用关键字 implements,并将 interest 字段作为类的属性使用。

以下实例红 AgriLoan 类实现了 ILoan 接口:

interface ILoan { interest:number 
} class AgriLoan implements ILoan { interest:number rebate:number constructor(interest:number,rebate:number) { this.interest = interest this.rebate = rebate } 
} var obj = new AgriLoan(10,1) 
console.log("利润为 : "+obj.interest+",抽成为 : "+obj.rebate )   // 利润为 : 10,抽成为 : 1

TypeScript与JavaScript中的对象基本一致。

TypeScript命名空间

命名空间一个最明确的目的就是解决重名问题。命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。

TypeScript 中命名空间使用 namespace 来定义,语法格式如下:

namespace SomeNameSpaceName { export interface ISomeInterfaceName {      }  export class SomeClassName {      }  
}

以上定义了一个命名空间 SomeNameSpaceName,如果我们需要在外部可以调用 SomeNameSpaceName 中的类和接口,则需要在类和接口添加 export 关键字。

要在另外一个命名空间调用语法格式为:

SomeNameSpaceName.SomeClassName;

总结:以上为TypeScript的基础知识,可以看出TypeScript与JavaScript其中一些区别

1、TypeScript是JavaScript的超集,即你可以TypeScript在中使用原生JavaScript语法。

2、TypeScript是静态类语言(强类型),编译时进行类型检查;而JavaScript是动态类语言(弱类型)在运行时进行类型判断,相对更灵活。

3、TypeScript在JavaScript基础类型上,增加了void、never、any、元组、枚举、以及一些高级类型,还有类、接口、命名空间与更多面向对象的内容等。

4、JavaScript没有重载概念,TypeScript可以重载。

5、TypeScript最终仍要编译为弱类型,基于对象的原生的JavaScript,再运行。

参考链接:TypeScript 教程 | 菜鸟教程


---------------------
作者:前端不释卷leo
来源:CSDN
原文:https://blog.csdn.net/qq_41809113/article/details/121107014
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

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

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

相关文章

IO 和NIO的区别

1.IO和NIO的区别 NIO就是New IO在JDK1.4中引入。 IO和NIO有相同的作用和目的&#xff0c;但实现方式不同&#xff0c;NIO主要用到的是块&#xff0c;所以NIO的效率要比IO快不少。 在Java API中提供了两套NIO&#xff0c;一套针对标准输入输出NIO&#xff0c;另一套就是网络编程…

PerfView专题 (第四篇):如何寻找 C# 中程序集泄漏

一&#xff1a;背景 前两篇我们都聊到了非托管内存泄漏&#xff0c;一个是 HeapAlloc &#xff0c;一个是 VirtualAlloc&#xff0c;除了这两种泄漏之外还存在其他渠道的内存泄漏&#xff0c;比如程序集泄漏&#xff0c;这一篇我们就来聊一聊。二&#xff1a;程序集也会泄漏&am…

站立会议第九天

1.站立会议内容 昨天我们成功的将图片插进去了&#xff0c;在这里&#xff0c;图片是使用的png格式&#xff0c;长知识了。我们今天要继续把界面再优化一下。 照片&#xff1a; 2.任务展板 3.燃尽图 转载于:https://www.cnblogs.com/bk1246788/p/6852935.html

学习nginx 下面只是简单的配置文件

2019独角兽企业重金招聘Python工程师标准>>> #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } …

实现城市治理一网统管,必须这 4 个关键技术

导读&#xff1a;要实现城市治理一网统管&#xff0c;必须具备以下四个关键技术&#xff1a;城市状态一网感知、城市数据一网共享、信息流转三屏联动、虚实映射数字孪生。 作者&#xff1a;郑宇 来源&#xff1a;大数据DT&#xff08;ID&#xff1a;hzdashuju&#xff09; 01…

实现生成订单30分钟未支付,则自动取消

目录 了解需求 方案 1&#xff1a;数据库轮询 思路 实现 优点 缺点 方案 2&#xff1a;JDK 的延迟队列 思路 实现 优点 缺点 方案 3&#xff1a;时间轮算法 思路 实现 优点 缺点 方案 4&#xff1a;redis 缓存 思路一 实现一 解决方案 思路二 实现二 优…

CA周记-.NET MAUI in GCR 月报(2022年8月)

.NET MAUI 正式版本发布已经三个月了&#xff0c;有小伙伴希望我们有一些关于 .NET MAUI 相关的本地化内容以及开源项目介绍&#xff0c;接下来从8月开始&#xff0c;我希望用月报的形式和大家分享 .NET MAUI 在中国的活动&#xff0c;学习资源&#xff0c;优秀的开源项目&…

一文读懂研发效能洞察的五大流动指标

作者 | 张乐 目录 1 数字化时代&#xff0c;软件研发本身也要数字化 2 流框架及五大流动指标 1. 流动速率 2. 流动时间 3. 流动负载 4. 流动效率 5. 流动分布 3 研发过程中的常见瓶颈及解决思路 1. 稀缺的专家或资源&#xff0c;导致流动受阻 2. 缺乏自动化或工程能…

RabbitMQ队列

RabbitMQ是什么&#xff1f; RabbitMQ是一个在AMQP基础上完整的&#xff0c;可复用的企业消息系统。他遵循Mozilla Public License开源协议。 MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息&…

《ASP.NET Core 6框架揭秘实例》演示[14]:日志的进阶用法

为了对各种日志框架进行整合&#xff0c;微软创建了一个用来提供统一的日志编程模式的日志框架。《ASP.NET Core 6框架揭秘》实例演示[13]&#xff1a;日志的基本编程模式》以实例演示的方式介绍了日志的基本编程模式&#xff0c;现在我们来补充几种“进阶”用法。[本文节选《A…

什么是云原生,云原生技术为什么这么火?

文章目录 一、开篇浅谈二、云计算是什么三、云原生是什么四、云计算的四个层次 4.1 IaaS&#xff08;基础架构即服务&#xff09;4.2 PaaS&#xff08;平台即服务&#xff09;4.3 SaaS&#xff08;软件即服务&#xff09;4.4 DaaS&#xff08;数据即服务&#xff09;五、云原生…

PerfView专题 (第五篇):如何寻找 C# 托管内存泄漏

一&#xff1a;背景 前几篇我们聊的都是 非托管内存泄漏&#xff0c;这一篇我们再看下如何用 PerfView 来排查 托管内存泄漏 &#xff0c;其实 托管内存泄漏 比较好排查&#xff0c;尤其是用 WinDbg&#xff0c;毕竟C#是带有丰富的元数据&#xff0c;不像C下去就是二进制。二&a…

DevOps及DevOps常用的工具介绍

目录 1. 什么是 DevOps2. DevOps 概念的起源 2.1. 单体架构 瀑布模式2.2. 分布式架构 敏捷开发模式 2.2.1. 多人协同开发问题2.2.2. 多机器问题2.2.3. 开发和运维角色的天生对立问题2.3. 微服务架构 DevOps3. DevOps 到底是什么4. DevOps 常用的工具 4.1. Jenkins4.2. Kuber…

2018年SIAF 广州国际工业自动化技术及装备展览会下周隆重开幕

同期研讨活动聚焦行业未来趋势&#xff0c;探索技术发展及实际应用层面。 华南最重要的工业自动化行业盛会之一&#xff0c;SIAF广州国际工业自动化技术及装备展览会&#xff0c;将于2018年3月4至6日在广州中国进出口商品交易会展馆隆重开幕。为期三天的展会将再度与广州国际模…

相约现在,遇见未来

# 遇见未来这个世界很小&#xff0c;我们就这样遇见。这个世界很大&#xff0c;分开就很难再见。大家好&#xff0c;我是 chait&#xff0c;很高兴我们在这里《遇见》。今天是我申请公众号通过后的第一天&#xff0c;也是在该平台发表的第一篇文章&#xff0c;唠嗑点啥呢&#…

有关并行的两个重要定律

本文摘自 葛一鸣 老师的《实战java高并发程序设计》一书。因为觉得写得好就摘下来了 将串行程序改造成并发程序&#xff0c;一般来说可以提高程序的整体性能&#xff0c;但是究竟能提升多少&#xff0c;甚至说究竟是否真的可以提高&#xff0c;还是一个需要研究的问题。目前&am…

IT圈中的Bug的类型与历史

美国计算机科学家、图灵奖获得者詹姆斯尼古拉格雷(Jim Gray)&#xff0c;在他的著名的论文“Why do computers stop and what can be done about it?”中首次提出了程序bug的类型&#xff0c;比如玻尔bug(Bohrbug)、 海森堡bug(Heisenbugs)等用著名科学家名称命名的bug。后来又…

Windows Nano Server安装配置详解03:远程管理Nano Server

远程管理Nano Server主要是通过使用远程powershell的方式。首先&#xff0c;我们把Nano Server的登录凭据保存到$cred变量之中&#xff0c;如图。其次&#xff0c;把远程Nano Server服务器添加到远程管理机本地的trustedHosts中&#xff0c;否则会报下面的错误&#xff0c;如图…

你和阿里资深架构师之间,差的不仅仅是年龄(进阶必看)

导读&#xff1a;阅读本文需要有足够的时间&#xff0c;笔者会由浅到深带你一步一步了解一个资深架构师所要掌握的各类知识点&#xff0c;你也可以按照文章中所列的知识体系对比自身&#xff0c;对自己进行查漏补缺&#xff0c;觉得本文对你有帮助的话&#xff0c;可以点赞关注…

[luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)

传送门 很蒙蔽&#xff0c;不知道怎么搞。 网上看题解有说可以哈希二分搞&#xff0c;也有的人说用Manacher搞&#xff0c;Manacher是什么鬼&#xff1f;以后再学。 对于这个题&#xff0c;可以从矩阵4个角hash一遍&#xff0c;然后枚举矩阵中的点&#xff0c;再二分半径。 但是…