typeScript

分章节阅读目录链接:typeScript系列学习文章目录

  • typeScript数据类型

    • 解释
  • typeScript函数
    • 函数定义
    • 参数
    • 函数重载
    • Lambda函数
  • typeScript类
    • 类的定义
    • 继承
    • 类里面的修饰符
    • 静态属性静态方法
    • 多态
    • 抽象类
  • typeScript接口
    • 属性接口
    • 函数类型接口
    • 可索引接口
    • 类类型接口
    • 接口扩展
  • typeScript中的泛型
    • 泛型的定义
    • 泛型函数
    • 泛型类
    • 泛型接口
  • 模块
    • 模块的的概念
    • 模块导出的几种方法
    • 命名空间
  • 装饰器
    • 类装饰器
    • 属性装饰器
    • 方法装饰器
    • 参数装饰器
  • 声明文件

typeScript数据类型

布尔类型(boolean)

数字类型(number)

字符串类型(string)

数组类型(array)

元组类型(tuple)

枚举类型(enum)

任意类型(any)

null 和 undefined

void类型

never类型

解释

字符串类型(string)

var str:string = "fur"
str = "furfur"
console.log(str)//furfur

数组类型(array)

//写法一
var arr:number[] = [1,2,3]
console.log(arr)//[ 1, 2, 3 ]//写法二
var arr:Array<number> = [1,2,3]
console.log(arr)//[ 1, 2, 3 ]

元组类型(tuple) 属于数组的一种。

var arr:[string,number] = ["fur",1]
console.log(arr)//[ "fur", 1 ]

枚举类型(enum)

枚举方法:事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,用这种方法定义的类型称枚举类型。(就是起一个通俗易懂的别名)

enum 枚举名{ 标识符[=整型常数], 标识符[=整型常数], ... 标识符[=整型常数], } ;
enum Flag{success = 1,error = 0,
}
let s:Flag = Flag.success
console.log(s)//1

任意类型(any):相当于没有类型限制

var num:any=123;
num='str';
num=true;
console.log(num)

null 和 undefined是其他(never类型)数据类型的子类型

var num1:number
var num2:undefined
var num3:null=null
console.log(num1)//编译器报错
console.log(num2)//undefined
console.log(num3)//null

void类型:表示没有任何类型,一般用于定义方法的时候方法没有返回值。

function play():void{console.log("fur")
}
play()

never类型:表示的是那些永不存在的值的类型。

never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。通常表现为抛出异常或无法执行到终止点(例如无线循环)。

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

上述never部分的理解参考自文章:https://segmentfault.com/a/1190000008893626

联合类型

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

var val:string|number
val = 1
console.log(typeof(val)) //number
val = "fur"
console.log(typeof(val)) //string

typeScript函数

函数的定义

可选参数,默认参数,剩余参数

函数重载

箭头函数 es6

函数定义

函数就是包裹在花括号中的代码块,前面使用了关键词 function:

语法格式如下所示:

function run():void{// 执行代码
}var run = function ():void{// 执行代码
}

参数

方法传参

var run = function (name:string):string{// 执行代码return`${name}在跑步`
}
console.log(run("fur"))//fur在跑步

可选参数

es5里面方法的实参和行参可以不一样,但是ts中必须一样,如果不一样就需要配置可选参数

注意:可选参数必须配置到参数的最后面

var run = function (name:string,sex?:string):string{// 执行代码if(sex){return`${name}在跑步---${sex}`}else{return`${name}在跑步`}
}
console.log(run("fur"))//fur在跑步
console.log(run("fur","女"))//fur在跑步---女

默认参数

es5里面没法设置默认参数,es6和ts中都可以设置默认参数

var run = function (name:string,sex:string="女"):string{// 执行代码if(sex){return`${name}在跑步---${sex}`}else{return`${name}在跑步`}
}
console.log(run("fur"))//fur在跑步---女
console.log(run("fur","男"))//fur在跑步---男

剩余参数

...三点运算符,接受新参传过来的值

function sum(...arr:number[]):number{var item = 0;var sum = 0;for(item of arr){sum+=item}return sum;
}
console.log(sum(1,2,3,4,5,6))//21
console.log(sum(1,2,3))//6

函数重载

java中方法的重载:重载指的是两个或者两个以上同名函数,但它们的参数不一样,这时会出现函数重载的情况。

typescript中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的。

注意: 必须要把精确的定义放在前面,最后函数实现时,需要使用 |操作符或者?操作符,把所有可能的输入类型全部包含进去,以具体实现。即最下面的方法需要兼容上面的方法

function run(num:number):void;
function run(str:string,flag:boolean):void;
function run(str:string,flag?:boolean):void;
function run(str:number|string,flag?:boolean):void{if(typeof str === 'string'){console.log("fur")}else{console.log(1)}
}
run(1)
run("fur")
run("fur",true);

常见报错:This overload signature is not compatible with its implementation signature

意思:此重载签名与其实现签名不兼容,即没有满足最后的函数实现时,把所有可能输入的函数全部包含进去。

Lambda 函数

Lambda 函数也称之为箭头函数。箭头函数表达式的语法比函数表达式更短。

( [param1, parma2,…param n] )=>statement;

最简写法

var result = (num:number)=>num+1
console.log(result(2))//3

正常写法

var result = (num:number)=>{//执行代码console.log(num+1)
}
result(2)//3

typeScript 类

类描述了所创建的对象共同的属性和方法。

类的定义

继承

类里面的修饰符

静态属性 静态方法

抽象类 继承 多态

类的定义

class person {name:string;  //属性,省略publicconstructor(n:string){this.name = n}run():void{console.log(this.name+"在跑步")}
}
var p = new person("fur");
console.log(p.name)//fur
p.run()//fur在跑步

继承

关键词:extends super

run方法说明:子类继承父类方法

study方法说明:子类重写父类方法

class person {name:string;  //属性,省略publicconstructor(n:string){this.name = n}run():void{console.log(this.name+"在跑步")}study():void{console.log(this.name+"在学习")}
}
class man extends person{constructor(name:string){super(name) /*初始化父类的构造函数*/}study():void{console.log(this.name+"在学习-子类")}
}
var p = new person("fur");
console.log(p.name)//fur
p.run()//fur在跑步
var m = new man("furfur");console.log(m.name)//furfur
m.run()//furfur在跑步(继承父类的run)
m.study()//furfur在学习-子类(重写父类study)

对比es5的继承有很大的改善,es5继承

类里面的修饰符

类里面的修饰符 typescript里面定义属性的时候给我们提供了 三种修饰符

  • public : 公有,在当前类里面、 子类 、类外面都可以访问

  • protected:保护类型,在当前类里面、子类里面可以访问 ,在类外部没法访问

  • private :私有,在当前类里面可以访问,子类、类外部都没法访问

例子:

class person {private name:string;  constructor(n:string){this.name = n}protected run():void{console.log(this.name+"在跑步")//正确,private只能在类“person”中访问}public study():void{console.log(this.name+"在学习")}}
class man extends person{constructor(name:string){super(name) /*初始化父类的构造函数*/   }protected run():void{super.run() // 正确,protected只能在类“person”及其子类中访问。}
}
var p = new person("fur");
// console.log(p.name)//报错:属性“name”为私有属性,只能在类“person”中访问。
// p.run()//报错:属性“run”受保护protected,只能在类“person”及其子类中访问。
p.study()//furfur在学习var m = new man("furfur");
// console.log(m.name)//报错:属性“name”为私有属性,只能在类“person”中访问。
// m.run()//报错:属性“run”受保护protected,只能在类“man”及其子类中访问。
m.study()//furfur在学习

静态属性 静态方法

关键词:static

class person {name:string; static age = 1constructor(n:string){this.name = n}// static run():void{//     console.log(this.name+"在跑步")//静态方法  里面没法直接调用类里面的非静态属性// }static getAge():void{console.log(this.age)}
}
person.age=1
person.getAge()

多态

多态:父类定义一个方法不去实现,让继承它的子类去实现 每一个子类有不同的表现,多态属于继承

例子:person中的paly方法,子类man和woman有各自的具体方法

class person {name:string; age = 1constructor(n:string){this.name = n}play():void{console.log("玩法")}
}
class man extends person{constructor(name:string){super(name)}play():void{console.log(`${this.name} lol`)}
}
class woman extends person{constructor(name:string){super(name)}play():void{console.log(`${this.name} shopping`)}
}
var m = new man("boy")
m.play()//boy lol
var w = new woman("girl")
w.play()//girlshopping

抽象类

typescript中的抽象类:抽象类和抽象方法用来定义标准 。它是提供其他类继承的基类,不能直接被实例化。

用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。abstract抽象方法只能放在抽象类里面。

抽象类的子类必须实现抽象类里面的抽象方法,否则仍然要作为一个抽象类。

abstract class person {name:string; age = 1constructor(n:string){this.name = n}abstract play():void;
}
class man extends person{constructor(name:string){super(name)}play():void{console.log(`${this.name} lol`)}
}
class woman extends person{constructor(name:string){super(name)}play():void{console.log(`${this.name} shopping`)}
}
var m = new man("boy")
m.play()//boy lol
var w = new woman("girl")
w.play()//girlshopping

typeScript接口

属性类接口

函数类型接口

可索引接口

类类型接口

接口扩展

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

接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。

接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。

typescrip中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

接口:行为和动作的规范,对批量方法进行约束

属性接口

对json的约束

interface Person {name:string;age:number;sex?:string//可选属性
}
function printPerson (p:Person){if(p.sex){console.log(`${p.name}年龄${p.age} 性别${p.sex}`)}else{console.log(`${p.name}年龄${p.age}`)}
}var obj:Person = {name:"furfur",age:2,sex:"girl"
}
printPerson(obj)//furfur年龄2 性别girlrfur年龄2 性别girl

函数类型接口

对方法传入的参数 以及返回值进行约束,批量约束

interface encrypt{(key:string,value:string):string;
}
var md5:encrypt=function(key:string,value:string):string{//模拟操作return key+value;
}
console.log(md5('name','fur'));//namefur

可索引接口

数组、对象的约束

//对数组的约束
interface Arr  {[index:number]:string;
}
var arr1:Arr = ["1","2","3"]//对对象的约束
interface Obj {[index:string]:string
}
var arr2:Obj = {name:"fur",age:"1"}

类类型接口

对类的约束和抽象类抽象有点相似

class person {name:string; constructor(n:string){this.name = n}play():void{}
}
class man implements person{name: string;constructor(name:string){this.name = name;}play():void{console.log(`${this.name} lol`)}
}
class woman implements person{name: string;constructor(name:string){this.name = name;}play():void{console.log(`${this.name} shopping`)}
}
var m = new man("boy")
m.play()//boy lol
var w = new woman("girl")
w.play()//girlshopping

接口扩展

接口可以继承接口

例子:接口person继承接口Animal,man实现接口person同时也要实现Animal

class Animal{eat():void{}
}
class person extends Animal{play():void{}
}class man implements person{eat():void {console.log('吃粮食')}play():void{console.log('玩游戏')}
}

typeScript中的泛型

泛型的定义

泛型函数

泛型类

泛型接口

泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

泛型的定义

泛型:可以支持不特定的数据类型, 要求:传入的参数和返回的参数一致

可以用T表示泛型,具体什么类型是调用这个方法的时候决定的

泛型函数

function getData<T>(val:T):T{return val
}
console.log(getData<number>(1))//1
console.log(getData<string>("fur"))//fur
console.log(getData<boolean>(true))//true

泛型类

class MinClass<T>{public list:T[] = []add(val:T):void{this.list.push(val)}min():T{var minNum = this.list[0]for(var i=0;i<this.list.length;i++){if(minNum>this.list[i]){minNum=this.list[i];}}return minNum;}
}
var mNum = new MinClass<number>();
mNum.add(8);
mNum.add(6);
mNum.add(11);
console.log(mNum.min())//6
var mStr = new MinClass<string>();
mStr.add("fur")
mStr.add("kfc")
mStr.add("mdl")
console.log(mStr.min())//fur

泛型接口

interface config<T> {(value:T):T
}
function getData<T>(val:T):T{return val;
}
var myData:config<string> = getData;
console.log(myData("fur"))//fur

模块

模块的的概念

“外部模块”现在则简称为“模块” 模块在其自身的作用域里执行,而不是在全局作用域里;

“内部模块”现在称做“命名空间”。

​ 这意味着定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出它们。

​ 相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用 import形式之一。

模块导出的几种方法

由于浏览器端无法解析export,可以使用node运行或者用webpack打包工具打包。

导入导出方法一

export导出:

var url='xxx';
function getData():void{console.log('fur');
}
export {url,getData};

import导入:

import {url,getData as get } from './modules/db'
//as可以更换名字,地址是export的文件的地址
console.log(url)//xxx
get()//fur

导入导出方法二

导出方法:export default 默认导出

每个模块都可以有一个default导出。 默认导出使用 default关键字标记;并且一个模块只能够有一个default导出。 需要使用一种特殊的导入形式来导入 default导出。

export导出:

function getData():void{console.log('fur');
}
export default getData;

import导入:

import getData from './modules/db';
getData();//fur

命名空间

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内,typeScript的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。

命名空间内的对象通过export关键字对外暴露。

命名空间和模块的区别:

  • 命名空间:内部模块,主要用于组织代码,避免命名冲突。

  • 模 块:ts的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。

命名空间使用 namespace 来定义:

空间A和B内代码一模一样,可以共存,调用时还需要命名空间的名字调用

namespace A{interface Person {name:string;paly():void;}export class man implements Person {name: string;constructor(n: string) {this.name = n;}paly():void{console.log("玩游戏")}}
}
namespace B{interface Person {name:string;paly():void;}export class man implements Person {name: string;constructor(n: string) {this.name = n;}paly():void{console.log("跑步")}}
}
var p1 = new A.man("fur")
p1.paly()//玩游戏
var p2 = new B.man("fur")
p2.paly()//跑步

装饰器

装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。

通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。

常见的装饰器有:类装饰器、属性装饰器、方法装饰器、参数装饰器

装饰器的写法:普通装饰器(无法传参) 、 装饰器工厂(可传参)

注意:使用装饰器会报以下错误,点击快速修复或者手动在json文件里增加以下代码

"experimentalDecorators": true,

对修饰器的实验支持是一项将在将来版本中更改的功能。设置 "experimentalDecorators" 选项以删除此警告。

运行顺序:属性>方法>方法参数>类 如果有多个同样的装饰器,它会先执行后面的

类装饰器

类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。

类装饰器:普通装饰器(无法传参)

function logClass(params:any){console.log(params)// 动态扩展属性egparams.prototype.name = "fur"//动态扩展方法params.prototype.run =function(){console.log("run")}
}
@logClass
class  Person { study(){console.log("study")}
}var p:any = new Person()
p.study()//study
console.log(p.name)//fur
p.run()//run

类装饰器:装饰器工厂(可传参)

function logClass(params:any){return function(target:any){target.prototype.name=params;}
}
@logClass('furfur')
class  Person { study(){console.log("study")}
}
var p:any = new Person()
p.study()//study
console.log(p.name)//furfur

属性装饰器

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:

​ 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。

​ 2、成员的名字。

function logProperty(params:any){return function(target:any,attr:any){target[attr]=params;console.log(attr)console.log(target)}
}class  Person {@logProperty("fur") name:string|undefined;constructor(){}study(){console.log("study")}
}var p:any = new Person()
p.study()//study
console.log(p.name)//fur

方法装饰器

它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。

方法装饰会在运行时传入下列3个参数:

​ 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。

​ 2、成员的名字。

​ 3、成员的属性描述符

function get(params:any){return function(target:any,methodName:any,desc:any){console.log(methodName);//getDatatarget.apiUrl='fur';target.run=function(){console.log('run');}}
}class HttpClient{  public url:any |undefined;constructor(){}@get('http://www.fur.com')getData(){console.log(this.url);}
}var http:any=new HttpClient();
console.log(http.apiUrl);//fur
http.run();//run

方法参数装饰器

方法参数装饰器表达式会在运行时当作函数被调用,传入下列3个参数:

​ 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。

​ 2、参数的名字。

​ 3、参数在函数参数列表中的索引。

function logParams(params:any){return function(target:any,methodName:any,paramsIndex:any){console.log(params);//furconsole.log(target);//objectconsole.log(methodName);//getDataconsole.log(paramsIndex);//0target.apiUrl=params;}
}class HttpClient{  public url:any |undefined;constructor(){}           getData(@logParams('fur') uuid:any){               console.log(uuid);}}var http:any = new HttpClient();
http.getData("furfur");//furfur
console.log( http.apiUrl);//fur

声明文件

在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。

为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。

假如我们想使用第三方库,比如 jQuery,我们通常这样获取一个 id 是 foo 的元素:

$('#foo');
// 或
jQuery('#foo');

但是在 TypeScript 中,我们并不知道 $ 或 jQuery 是什么东西:

jQuery('#foo');// index.ts(1,1): error TS2304: Cannot find name 'jQuery'.

这时,我们需要使用 declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对:

declare var jQuery: (selector: string) => any;jQuery('#foo');

declare 定义的类型只会用于编译时的检查,编译结果中会被删除。

上例的编译结果是:

jQuery('#foo');

声明文件

声明文件以 .d.ts 为后缀;

fur.d.ts

声明文件或模块的语法格式如下:

declare module Module_Name {}

TypeScript 引入声明文件语法格式:

/// <reference path = " fur.d.ts" />

当然,很多流行的第三方库的声明文件不需要我们定义了,比如 jQuery 已经有人帮我们定义好了:jQuery in DefinitelyTyped。

实例

以下定义一个第三方库来演示:

CalcThirdPartyJsLib.js 文件代码:

var Runoob;
(function(Runoob) {    var Calc = (function () {         function Calc() {         }     })    Calc.prototype.doSum = function (limit) {        var sum = 0;          for (var i = 0; i <= limit; i++) {            sum = sum + i;         }        return sum;     }    Runoob.Calc = Calc;     return Calc;
})(Runoob || (Runoob = {}));
var test = new Runoob.Calc();

如果我们想在 TypeScript 中引用上面的代码,则需要设置声明文件 Calc.d.ts,代码如下:

Calc.d.ts 文件代码:

declare module Runoob {    export class Calc {       doSum(limit:number) : number;    }
}

声明文件不包含实现,它只是类型声明,把声明文件加入到 TypeScript 中:

CalcTest.ts 文件代码:

/// <reference path = "Calc.d.ts" />
var obj = new Runoob.Calc();
// obj.doSum("Hello"); // 编译错误
console.log(obj.doSum(10));

生成的 JavaScript 代码如下:

CalcTest.js 文件代码:

/// <reference path = "Calc.d.ts" />
var obj = new Runoob.Calc();
//obj.doSum("Hello"); // 编译错误
console.log(obj.doSum(10));

最后我们编写一个 runoob.html 文件,引入 CalcTest.js 文件及第三方库 CalcThirdPartyJsLib.js:

浏览器打开该文件输出结果如下:


声明文件这一篇来自菜鸟教程

一文带你了解typeScript相关推荐

  1. 如何进阶TypeScript功底?一文带你理解TS中各种高级语法

    引言 TypeScript 的重要性我不在强调了,我相信仍然会有大多数前端开发者碰到复杂类型一概使用 any 处理. 我写这篇文章的目的就是为了让你告别 AnyScript ,文章告别晦涩的概念结合实 ...

  2. 还不会ts?一文带你打开ts的大门

    一文带你打开ts的大门 序言 一.什么是TypeScript? 1.编程语言的类型 2.TypeScript究竟是什么? 二.为什么要学习TypeScript? 1.程序更容易理解 2.效率更高 3. ...

  3. linux awk语法格式,Awk是什么?一文带运维小白快速掌握Linux Awk用法

    原标题:Awk是什么?一文带运维小白快速掌握Linux Awk用法 作者:a8 Awk.sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以 ...

  4. DNN、RNN、CNN.…..一文带你读懂这些绕晕人的名词

    DNN.RNN.CNN.-..一文带你读懂这些绕晕人的名词 https://mp.weixin.qq.com/s/-A9UVk0O0oDMavywRGIKyQ 「撞脸」一直都是娱乐圈一大笑梗. 要是买 ...

  5. 一文带你深入理解JVM内存模型

    一文带你深入理解JVM内存模型 一.JAVA的并发模型 共享内存模型 在共享内存的并发模型里面,线程之间共享程序的公共状态,线程之间通过读写内存中公共状态来进行隐式通信 该内存指的是主内存,实际上是物 ...

  6. 训练的神经网络不工作?一文带你跨过这37个坑

    近日,Slav Ivanov 在 Medium 上发表了一篇题为<37 Reasons why your Neural Network is not working>的文章,从四个方面(数 ...

  7. 一文带你了解Java Agent

    转载自  一文带你了解Java Agent Java Agent这个技术,对于大多数同学来说都比较陌生,像个黑盒子.但是多多少少又接触过,实际上,我们平时用的很多工具,都是基于Java Agent实现 ...

  8. 一文带你理解Java中Lock的实现原理

    转载自   一文带你理解Java中Lock的实现原理 当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题.java提供了两种方式来加锁,一种是关键字:synchron ...

  9. pyecharts对于经纬度_一文带你掌握Pyecharts地理数据可视化的方法

    本文主要介绍了Pyecharts地理数据可视化,分享给大家,具体如下: 一.Pyecharts简介和安装 1. 简介 Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计, ...

最新文章

  1. linux 跑cpu负载工具,CPU负载查看工具
  2. Linux的shell脚本实战之检查主机IP是否存在
  3. Python中最常用十大图像处理库详细介绍
  4. Python字典的setdefault() 和get()方法比较
  5. 安装Zabbix过程中出现的问题集
  6. 1/3 常用符号:类型说明符
  7. 31岁博士副县长拟提任正处,3年前毕业被人才引进
  8. mysql 日期间隔_mysql比较两个日期间隔
  9. 接收list对象_PyTorch入门视频笔记从数组、列表对象中创建Tensor
  10. 视觉SLAM——ORB-SLAM3运行本地视频文件
  11. WF4.0 Beta1 CancellationScope 取消容器
  12. Eclipse快捷键大全(同样适用基于Eclipse开发的IDE)
  13. 《数据结构》二叉查找树
  14. php过滤excel文件,phpexcel读取excel内存释放怎么处理
  15. STC12C5A60S2获取GPS信息(LCD1602显示)(一)
  16. ios功耗测试软件,iOS 性能优化 Instruments 检测 App 耗电量实战
  17. 动态拼接LINQ查询条件
  18. 大学C语言 算法的定义及特点教案,第2章 算法的概念和特性介绍_福州大学数计学院:C语言程序设计(韩晓芸)_ppt_大学课件预览_高等教育资讯网...
  19. 传奇开服技术服务端各文件代表着什么意思
  20. 利用Regsvr32绕过Applocker的限制策略

热门文章

  1. cmd命令查看路由器上记录的IP地址与MAC地址(ARP表)
  2. php时间函数不准确,PHP中DATE函数与实际时间相差8小时的解决办法
  3. 死锁的预防、避免、检测、解除
  4. excel缩字间距_“EXCEL中如何调整字间距?“excel缩小字符间距
  5. netty通讯--tcp心跳异常断开问题排查
  6. 为什么你关不掉手机里的广告?
  7. Eclipse中出现-访问限制由于对必需的库XX具有一定限制,因此无法访问类型
  8. 机器学习实战——决策树(二)
  9. scratch编程密室逃脱
  10. VMware 12虚拟机win7中添加摄像头