Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

TypeScript学习笔记

27
Apr
2020

TypeScript学习笔记

By Alex
/ in JavaScript
0 Comments
安装和配置
安装

执行下面的命令安装TypeScript:

Shell
1
npm install -g typescript
语言基础
数据类型

TypeScript支持类型提示,类型提示让代码自动完成更加准确:

基本类型
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 布尔
let isDone: boolean = false;
// 数字
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;
// 字符串
let name: string = "bob";
// 模板字符串
let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.
 
I'll be ${ age + 1 } years old next month.`;
数组和元组
JavaScript
1
2
3
4
5
6
7
8
// 数组
let list: number[] = [1, 2, 3];
// 数组,泛型语法
let list: Array<number> = [1, 2, 3];
 
// 元组
let x: [string, number];
x = ['hello', 10];
枚举
JavaScript
1
2
3
4
5
// 枚举
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
// 默认情况下,枚举值从0开始,可以修改
enum Color {Red = 1, Green, Blue}
any
JavaScript
1
2
3
4
5
6
7
8
// 不限定的类型
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false;
// 你可以假设不限定类型有任何方法,编译器不会检查
notSure.ifItExists();
// 不限定类型数组
let list: any[] = [1, true, "free"];
void
JavaScript
1
2
3
4
5
6
7
// Void类型
// 用于表示没有返回值的函数
function warnUser(): void {
    console.log("This is my warning message");
}
// 只能赋值undefined或null
let unusable: void = undefined;
undefined和null 
JavaScript
1
2
3
// undefined 和 null类型
let u: undefined = undefined;
let n: null = null;

默认情况下 null和 undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给任何类型的变量。但是如果指定了 --strictNullChecks标记,则只能赋值给void或者各自的类型 —— null赋值给null,undefined赋值给undefined。

never 
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// never 永远不存在值的类型,例如:总是抛出异常或者不会有返回值的函数或者箭头函数表达式
// 总是抛出异常
function error(message: string): never {
    throw new Error(message);
}
// 编译器可以推导出返回值为never类型
function fail() {
    return error("Something failed");
}
// 永远不会返回
function infiniteLoop(): never {
    while (true) {
    }
}
object

表示非基本类型:即非number,string,boolean,symbol,null或undefined。

类型断言 

尖括号语法:

JavaScript
1
2
3
let someValue: any = "this is a string";
 
let strLength: number = (<string>someValue).length;

as语法:

JavaScript
1
2
3
let someValue: any = "this is a string";
 
let strLength: number = (someValue as string).length;
操作符
keyof

以一个对象类型为参数,产生字符串或者数字的字面值的联合,这些数字或者字符串来自对象的键:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
type Point = { x: number; y: number };
type P = keyof Point; // "x" | "y"
 
// 如果目标类型具有字符串或数字的索引签名,则keyof操作符会返回对应的类型(而非字面值)的联合
 
type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // type A = number
 
type Mapish = { [k: string]: boolean };
type M = keyof Mapish; // type M = string | number
// 注意这里的M是 string | number的联合,这是因为JavaScript中对象的键,会被强制转换为字符串
// obj[0]和obj["0"]总是一样的 
! 非空断言

后缀的感叹号!表示非空断言操作符,其意义是:

  1. x! 将从 x 值对应的类型集合中排除 null 和 undefined 的类型。比如 x 可能是 string | undefined,则 x! 类型缩窄为 string
  2. null!在类型检测器没法正确推断类型情况下,告知编译器值不可能为undefined或者null
!!强制转布尔

因为一个叹号区反,得到的是布尔值,再次取反相当于恢复“原值”(的布尔转型)。

??空值合并

a ?? b仅仅当a为null或者undefined时,返回操作符右侧表达式即b,否则返回a。

接口

TypeScript的核心原则是,对所有结构基于鸭子类型识别,接口用来定义对象具有哪些字段,或者定义函数的规格。

指定属性
JavaScript
1
2
3
4
5
6
7
8
9
10
interface LabelledValue {
  label: string;
}
 
function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}
 
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
可选属性 
JavaScript
1
2
3
4
interface SquareConfig {
  color?: string;
  width?: number;
}
只读属性 
JavaScript
1
2
3
4
interface Point {
    readonly x: number;
    readonly y: number;
}
函数类型 

接口可以用来描述函数的签名:

JavaScript
1
2
3
4
5
6
7
8
9
interface SearchFunc {
  (source: string, subString: string): boolean;
}
 
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

接口中可以声明多个函数签名,这样的接口表示多个重载函数版本的联合:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
interface Func1 {
    (v1: number, v2: number): number;
    (v1: string, v2: string): string;
}
 
const f1: Func1 = (v1, v2): any => {
    return v1 + v2;
};
 
console.log(f1("1", "2"));
console.log(f1(1, 2));
可索引类型 

可以用来指定数组的值类型、映射的键值类型:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface StringArray {
  [index: number]: string;
}
 
let myArray: StringArray;
myArray = ["Bob", "Fred"];
 
let myStr: string = myArray[0];
 
// 防止给索引赋值
interface ReadonlyStringArray {
    readonly [index: number]: string;
}
 
 
interface User {
  id: string;
  name: string;
  [key: string]: any;
}
 
let user: User = {
  id: "alex",
  name: "Alex"
  prop1: 1,
  "prop2": 2
};

TypeScript允许字符串、数字作为索引。 

类类型 

接口可以用来限制一个类必须满足的规约:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
interface ClockInterface {
    currentTime: Date;
}
 
class Clock implements ClockInterface {
    currentTime: Date;
    constructor(h: number, m: number) { }
}
 
 
 
interface ClockInterface {
    currentTime: Date;
    // 定义方法
    setTime(d: Date);
}
 
class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}
接口的继承
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Shape {
    color: string;
}
 
interface PenStroke {
    penWidth: number;
}
// 支持多重继承
interface Square extends Shape, PenStroke {
    sideLength: number;
}
 
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
混合类型 

接口可以描述一个函数,在限定函数签名的同时,指定函数具有的额外属性: 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}
 
function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}
 
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
让接口继承类

当让接口继承一个类时,它会获得所有类的成员,但是不会获得这些成员的实现。

包括私有、保护成员,都会被继承。这种情况下,只有接口所继承的那个类的子类,才能实现该接口:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Control {
    private state: any;
}
 
interface SelectableControl extends Control {
    select(): void;
}
 
class Button extends Control implements SelectableControl {
    select() { }
}
 
 
// 错误:“Image”类型缺少“state”属性。
class Image implements SelectableControl {
    select() { }
}
类
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 抽象类
abstract class Greeter {
    // 静态属性
    static cname: string = "Greeter";
    // 实例变量
    greeting: string;
    // 可选的访问限定符 private protected public
    private name: string;
    // 只读成员
    readonly age: number;
    // 构造函数
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
 
let greeter = new Greeter("world");
 
// 继承
class Dog extends Greeter {
    greet() {
        console.log('Woof! Woof!');
        // 调用父类的方法
        super.greet();
    }
}
函数 
函数类型提示
JavaScript
1
2
//         类型提示
let myAdd: (x: number, y: number) => number =  function(x: number, y: number): number { return x + y; };
可选参数 
JavaScript
1
2
3
4
5
6
7
8
9
function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}
 
let result1 = buildName("Bob");  // works correctly now
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
默认参数 
JavaScript
1
2
3
function buildName(firstName: string, lastName = "Smith") {
    return firstName + " " + lastName;
}

当调用该函数的时候,传入undefined或者没有传递,则默认参数生效。

在所有必须参数之后的,带有默认值的参数,都是可选参数。

函数重载

给予不同的类型提示,即可实现函数重载。 

泛型
泛型函数
JavaScript
1
2
3
4
5
6
7
8
9
10
11
// 函数参数的泛型化
function identity<T>(arg: T): T {
    return arg;
}
// 泛型函数的类型提示
let myIdentity: <T>(arg: T) => T = identity;
 
// 显式指定类型参数
let output = identity<string>("myString");
// 自动推导类型参数
let output = identity("myString");
泛型接口 
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 某个函数泛型化
interface GenericIdentityFn {
    <T>(arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn = identity;
 
 
// 整个接口泛型化
interface GenericIdentityFn<T> {
    (arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型类
JavaScript
1
2
3
4
5
6
7
8
class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}
 
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
泛型约束 
JavaScript
1
2
3
4
5
// 规定实际类型必须继承自Lengthwise
function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
} 
枚举
字符串枚举
JavaScript
1
2
3
4
5
6
enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}
异构枚举
JavaScript
1
2
3
4
enum BooleanLikeHeterogeneousEnum {
    No = 0,
    Yes = "YES",
}
外部枚举 

用于描述已经存在的枚举类型的规格:

JavaScript
1
2
3
4
5
declare enum Enum {
    A = 1,
    B,
    C = 2
}
高级类型
交叉类型

交叉类型包含所有指定的类型的特征,例如, Person & Serializable & Loggable同时是 Person 和 Serializable 和 Loggable。

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function extend<T, U>(first: T, second: U): T & U {
    let result = <T & U>{};
    for (let id in first) {
        (<any>result)[id] = (<any>first)[id];
    }
    for (let id in second) {
        if (!result.hasOwnProperty(id)) {
            (<any>result)[id] = (<any>second)[id];
        }
    }
    return result;
}
 
class Person {
    constructor(public name: string) { }
}
interface Loggable {
    log(): void;
}
class ConsoleLogger implements Loggable {
    log() {
        // ...
    }
}
var jim = extend(new Person("Jim"), new ConsoleLogger());
var n = jim.name;
jim.log();
联合类型 

允许是指定类型集合中的任何一个: 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
interface Bird {
    fly();
    layEggs();
}
interface Fish {
    swim();
    layEggs();
}
 
function isFish(pet: Fish | Bird): {
    return (<Fish>pet).swim !== undefined;
}
类型别名 

可以用于任何类型:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    }
    else {
        return n();
    }
}

类型别名也可以是泛型的:

JavaScript
1
type Container<T> = { value: T };

甚至可以在类型别名的属性中,引用自己:

JavaScript
1
2
3
4
5
type Tree<T> = {
    value: T;
    left: Tree<T>;
    right: Tree<T>;
}

可以将字符值联合起来,形成类似于枚举的效果:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement {
    animate(dx: number, dy: number, easing: Easing) {
        if (easing === "ease-in") {
            // ...
        }
        else if (easing === "ease-out") {
        }
        else if (easing === "ease-in-out") {
        }
        else {
            // error! should not pass null or undefined.
        }
    }
}

可以为联合类型定义别名:

JavaScript
1
type Shape = Square | Rectangle | Circle;
模块 

从TypeScript 1.5开始, “内部模块”称做“命名空间”。 “外部模块”简称为“模块”。

TypeScript与ECMAScript 2015一样,任何包含顶级import或者export的文件都被当成一个模块。相反地,如果一个文件不带有顶级的import或者export声明,那么它的内容被视为全局可见的(因此对模块也是可见的)。

导出 

任何声明都可以通过export关键字来导出:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
 
export const numberRegexp = /^[0-9]+$/;
 
export class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
 
 
 
// 先定义再导出
class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export { ZipCodeValidator };
 
// 导出时指定导出名
export { ZipCodeValidator as mainValidator };
 
 
 
// 重新导出其它模块中的对象
export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";
// 全部重新导出
export * from "./StringValidator"; // exports interface StringValidator
导入 
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
import { ZipCodeValidator } from "./ZipCodeValidator";
let myValidator = new ZipCodeValidator();
 
 
// 导入并重命名
import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();
 
 
// 将整个模块导入到一个变量
import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();
默认导出 

每个模块可有最多一个默认导出:

JavaScript
1
2
declare let $: JQuery;
export default $;

默认导出在导入时,可以使用任何名字:

JavaScript
1
2
3
import jq from "JQuery";
 
jq("button.continue").html( "Next Step..." );

默认导出可以的可以是匿名函数,因为它的名字不重要:

JavaScript
1
2
3
4
5
const numberRegexp = /^[0-9]+$/;
 
export default function (s: string) {
    return s.length === 5 && numberRegexp.test(s);
}

你甚至可以导出一个字面值:

JavaScript
1
export default "123";
命名空间

命名空间(以前称为内部模块)可以用来组织代码。

命名空间可以分散在多个文件中: 

Validation.ts
JavaScript
1
2
3
4
5
namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}

需要利用引用标签,来说明不同文件之间的依赖关系:

LettersOnlyValidator.ts
JavaScript
1
2
3
4
5
6
7
8
9
/// <reference path="Validation.ts" />
namespace Validation {
    const lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}

使用命名空间中定义的对象的语法:

JavaScript
1
2
3
let validators: { [s: string]: Validation.StringValidator; } = {};
 
validators["Letters only"] = new Validation.LettersOnlyValidator();
别名 

可以为命名空间设置别名,简化访问:

JavaScript
1
2
3
4
5
6
7
8
namespace Shapes {
    export namespace Polygons {
        export class Triangle { }
        export class Square { }
    }
}
 
import polygons = Shapes.Polygons;
JSX 

JSX是一种源于React的类似于XML的语法,可以嵌入在JavaScript的源码中。

要在TypeScript中使用JSX,你需要:

  1. 给文件一个.tsx扩展名
  2. 启用jsx选项,利用--jsx命令行标记或者在tsconfig.json中配置

TypeScript具有三种JSX模式:preserve,react和react-native。 这些模式只在代码生成阶段起作用 - 类型检查并不受影响:

  1. preserve:生成代码中会保留JSX以供后续的转换操作(例如Babel)使用
  2. react:生成React.createElement。注意React这个标识符是写死的,不能被占用
  3. react-native:相当于preserve,它也保留了所有的JSX,但是输出文件的扩展名是.js
关于as操作符

由于尖括号风格的断言 var foo = <foo>bar;和JSX语法冲突,因而在.tsx文件中,这种风格的断言不被支持,必须使用as操作符。

ts-node

要使用TypeScript编写Node.js程序,可以借助ts-node。ts-node是Node.js的TypeScript执行引擎,它能够JIT的将TypeScript编译为JavaScript,你不需要预先编译就可以在Node.js运行时上执行TypeScript。

ts-node的特性包括:

  1. 为stacktrace自动生成sourcemap
  2. 自动解析tsconfig.json
  3. 自动设置匹配Node.js版本的默认值
  4. 类型检查
  5. REPL
  6. 原生ESM模块加载器支持
  7. 支持使用第三方transpiler
  8. 和debugger集成
安装
Shell
1
2
3
4
5
6
7
8
9
10
# Locally in your project.
npm install -D typescript
npm install -D ts-node
 
# Or globally with TypeScript.
npm install -g typescript
npm install -g ts-node
 
# Depending on configuration, you may also need these
npm install -D tslib @types/node
命令行
Shell
1
2
3
4
5
6
7
8
9
10
11
# 执行脚本
ts-node script.ts
 
# 启动解释器
ts-node
 
# 执行命令行提供的脚本
ts-node -e 'console.log("Hello, world!")'
 
# 执行并打印
ts-node -p -e '"Hello, world!"'
Shebang
JavaScript
1
2
3
#!/usr/bin/env ts-node
 
console.log("Hello, world!")
编程式使用 

可以通过下面的代码请求ts-node模块并注册它的loader,此loader会影响后续的requires。ts-node的工作原理就是挂钩到Node的模块加载API。

JavaScript
1
require('ts-node').register({ /* options */ })

或者使用命令行参数:

Shell
1
2
node -r ts-node/register
node -r ts-node/register/transpile-only
配置

ts-node会自动查找并加载tsconfig.json文件。命令行选项 --skipProject可以跳过当前项目的tsconfig.json, --project则用于明确指定项目配置文件的位置。 

tsconfig.json
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  // This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases
  "extends": "ts-node/node12/tsconfig.json",
 
  // 大部分配置在此
  "ts-node": {
    // 如果要跳过类型检查,去除下面这一行
    "transpileOnly": true,
 
    "files": true,
 
    "compilerOptions": {
      // 覆盖下面的编译选项
    }
  },
  "compilerOptions": {
    // typescript编译选项
  }
}
使用CommonJS模块加载 

TypeScript基本上都会使用import语法,但是可以在执行期间转换为CommonJS的require()或者保持ESM风格的import不变。

如果要转换为CommonJS风格,在package.json配置:

JSON
1
2
3
4
{
  // This can be omitted; commonjs is the default
  "type": "commonjs"
}

在tsconfig.json中配置:

JSON
1
2
3
4
5
{
  "compilerOptions": {
    "module": "CommonJS"
  }
}

如果需要为tsc,webpack等工具保留"module": "ESNext",你可以:

JSON
1
2
3
4
5
6
7
8
9
10
{
  "compilerOptions": {
    "module": "ESNext"
  },
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  }
}
使用原生ESM模块加载

NodeJS的原生ESM加载器钩子还处于试验阶段,可能改变。ts-node的ESM支持会尽量保持稳定,但是它依赖于底层的Node API。

你需要在package.json中设置:

JSON
1
2
3
{
  "type": "module"
}

在tsconfig.json中设置:

JSON
1
2
3
4
5
6
7
8
9
{
  "compilerOptions": {
    "module": "ESNext" // or ES2015, ES2020
  },
  "ts-node": {
    // Tell ts-node CLI to install the --loader automatically, explained below
    "esm": true
  }
}

同时,你还需要确保--loader被传递给Node。如果使用ts-node命令行,会自动传递: 

Shell
1
2
3
# 等价于上面配置文件中的"esm": true
ts-node --esm
ts-node-esm

如果你直接使用Node的命令行,则需要手工传递: 

Shell
1
2
3
node --loader ts-node/esm ./index.ts
# 或者
NODE_OPTIONS="--loader ts-node/esm" node ./index.ts
配合WebStorm 

安装ts-node:

Shell
1
npm install --save-dev ts-node

创建Node.js运行配置,增加Node Parameters: --require ts-node/register。 

使用ESM时,参考上文,即增加Node Parameters: --loader ts-node/esm。

← 重温iptables
团泊湖野餐 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • jQuery知识集锦
  • ExtJS 4常用组件之树面板
  • ExtJS 4元素与组件查询
  • 基于Kurento搭建WebRTC服务器
  • 浅析ExtJS新特性

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2