Git Product home page Git Product logo

progress's Introduction

progress's People

Contributors

alisagaoliwei avatar cjjlovedsn avatar dayuy avatar dependabot[bot] avatar foxnickfox avatar germanabc avatar imaxue avatar jianxiaobai avatar kingpengzero avatar lhnfromtj avatar liaohainan avatar mrpenta avatar mylooksback avatar pettyfish avatar shanguan avatar victoria-kola avatar wangsen1989 avatar wangxueting1993 avatar xihuihui avatar zengkaiwang avatar zhangyingying66666 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

progress's Issues

Dart 语法笔记

目录

Dart 概念

  • 任何 保存在变量中的都是一个 对象, 并且所有对象都是 对应类 的实例.
  • 尽管 Dart 是强类型的, 但是 Dart 可以 推断类型(就是可以根据 value 推断类型), 所以类型注释可可选的.
  • 如果明确说明 不需要任何类型, 需要使用特殊类型声明 dynamic.
  • 支持泛型. 如: List <dynamic>.
  • 支持顶级函数. 如: main()
    • 同样函数绑定在类或对象上(静态/实例)函数.
    • 支持(嵌套/局部)函数.
    • 顶级函数就是在最外层定义的函数.
  • 支持顶级变量
    • 同样变量绑定在类或对象上(静态/实例)变量.
    • 实例变量有时成为字段或属性.
  • 如果标识符以下划线(_)开头, 则是私有库/变量/方法等, 外部不可访问.
  • 风格指南中 var 变量仅存储对象引用.
  • 实例变量可以是 final 类型但不能是 const 类型.
  • == 运算符用来测试两个对象是否相等.
  • .. 语法为 级联调用 (cascade)。 使用级联调用, 可以简化在一个对象上执行的多个操作。

变量

  • var: 变量
  • dynamic: 动态类型
  • final: 常量
  • const: 编译时常量
  • null: 未初始化的变量默认值

内建类型

  • Number(int/double)
    • int: 整数值不大于 64 位
    • double: 64(双精度)浮点数
  • String(string)
    • 'hello ${表达式} world $标识符'
    • 连续三个单引号可实现多行字符串的创建, 需 toString() 转换
    • 使用 r 前缀, 可以创建 原始 raw 字符串
  • Boolean(bool)
  • List(List)
  • Map
    • Map 是用来关联 keys 和 values 的对象
  • Set
    • 是一个元素唯一且无需的集合
    • var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
  • Rune(用于在字符串中标识 Unicode 字符)
  • Symbol
    • 表示 Dart 程序中声明的运算符或者标识符

可选参数

  • {}内的参数为 命名可选参数
  • []内的参数为 位置可选参数
  • 参数的用 = 来赋值默认值
  • 一个参数只能选择其中一种方式修饰
void doStuff(
    {List<int> list = const [1, 2, 3],
    Map<String, String> gifts = const {
      'first': 'paper',
      'second': 'cotton',
      'third': 'leather'
    }}) {
  print('list:  $list');
  print('gifts: $gifts');
}

doStuff(list: [123, 344], gifts: {
'first': 'zhangsan'
})

命名

printPerson(String name,{int age = 14,String gender}){
  print("name=$name,age=$age,gender=$gender");
}

printPerson("李四");
printPerson("李四",age: 20);
printPerson("李四",age: 20,gender: "Male");
printPerson("李四",gender: "Male");

位置

printPerson2(String name,[int age = 15,String gender]){
  print("name=$name,age=$age,gender=$gender");
}

printPerson2("张三");
printPerson2("张三",18);
printPerson2("张三",18,"Female");

运算符

相对JS没有的运算符

// 除后向下取整
10 ~/ 2.1 = 2; 

if (emp is Person) {
  // Type check
  emp.firstName = 'Bob';
}

// 使用 as 运算符进行缩写:
(emp as Person).firstName = 'Bob';

// 当 value 为 null 时, 才会赋值给 b
b ??= value;

// 如果实例类 p 成员变量 y 为非 null,则设置它变量 y 的值为 4
p?.y = 4;

级联运算符

示例:

querySelector('#confirm') // 获取对象
  ..text = 'Confirm' // 调用成员变量
  ..classes.add('important') // 添加类名
  ..onClick.listen((e) => window.alert('Confirmed!')); // 注册事件

嵌套:

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = '[email protected]'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

流程控制语句

  • if-else 判断条件必须是 布尔值
  • assert 语句中的布尔条件为 false, 会中断程序(只在开发环境有效).

  • 在 Dart 2 中 new 关键字为可选.

使用构造函数

var a = const ImmutablePoint(1, 1); // 创建一个常量对象
var b = ImmutablePoint(1, 1); // 创建一个非常量对象

assert(!identical(a, b)); // 两者不是同一个实例!

实例变量

class Point {
  num x; // 声明示例变量 x,初始值为 null 。
  num y; // 声明示例变量 y,初始值为 null 。
  num z = 0; // 声明示例变量 z,初始值为 0 。
}

构造函数

通过创建一个与其类同名的函数来声明构造函数.

最常见的构造函数形式, 即生成构造函数, 创建一个类的实例:

// 传统方式
class Point {
  num x, y;

  Point(num x, num y) {
    // 还有更好的方式来实现下面代码,敬请关注。
    this.x = x;
    this.y = y;
  }
}

// Dart 自身的语法糖精简了这些代码
class Point {
  num x, y;

  // 在构造函数体执行前,
  // 语法糖已经设置了变量 x 和 y。
  Point(this.x, this.y);
}

默认构造函数

在没有生命构造函数的情况下, Dart 会提供一个默认的构造函数.

构造函数不被继承

子类不会继承父类的构造函数.

命名构造函数

使用命名构造函数可为一个类实现多个构造函数, 也可以使用早含函数来更清晰的表明函数意图.

class Point {
  num x, y;

  Point(this.x, this.y);

  // 命名构造函数
  Point.origin() {
    x = 0;
    y = 0;
  }
}

切记, 构造函数不能够被继承, 这意味着 子类不能继承.

调用父类非默认构造函数

class Person {
  String firstName;
  // 命名构造函数
  Person.fromJson(Map data) {
    print('in Person');
  }
}
// Employee 类的构造函数调用了父类 Person 的命名构造函数
class Employee extends Person {
  // Person 没有默认的构造函数, 所以必须要用 super.fromJson(data)手动继承一下
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

main() {
  var emp = new Employee.fromJson({});

  // Prints:
  // in Person
  // in Employee
  if (emp is Person) {
    // Type check
    emp.firstName = 'Bob';
  }
  (emp as Person).firstName = 'Bob';
}

初始化列表

import 'dart:math';

class Point {
  // 定义构造函数参数
  final num x;
  final num y;
  final num distanceFromOrigin;
  // 初始化参数
  Point(x, y)
      : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

main() {
  var p = new Point(2, 3);
  print(p.distanceFromOrigin);
}

重定向构造函数

有时构造函数的唯一目的是重定向到 同一个类 中的另一个构造函数.

class Point {
  num x, y;

  // 类的主构造函数。
  Point(this.x, this.y);

  // 指向主构造函数
  Point.alongXAxis(num x) : this(x, 0);
}

常量构造函数

如果该类生成的对象是固定不变的, 那么就可以把这些对象定义为编译时常量。

工厂构造函数

当执行构造函数 并不总是创建 这个类的一个 新实例时,则使用 factory 关键字。

Getter和Setter

Getter和Setter 是用于对象属性读和写的特殊方法。

class Rectangle {
  num left, top, width, height;

  Rectangle(this.left, this.top, this.width, this.height);

  // 定义两个计算属性: right 和 bottom。
  num get right => left + width;
  set right(num value) => left = value - width;
  num get bottom => top + height;
  set bottom(num value) => top = value - height;
}

void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

抽象类

使用 abstract 修饰符来定义, 抽象类通常用来定义接口,以及部分实现。

隐式接口...

每个类都 隐式的定义 了一个接口, 接口包含了该类所有的实例成员及其实现的接口.

一个类可以通过 implements 关键字来实现一个或者多个接口, 并实现每个接口要求的API.

// person 类。 隐式接口里面包含了 greet() 方法声明。
class Person {
  // 包含在接口里,但只在当前库中可见。
  final _name;

  // 不包含在接口里,因为这是一个构造函数。
  Person(this._name);

  // 包含在接口里。
  String greet(String who) => 'Hello, $who. I am $_name.';
}

// person 接口的实现。
class Impostor implements Person {
  get _name => '';

  String greet(String who) => 'Hi $who. Do you know who I am?';
}

String greetBob(Person person) => person.greet('Bob');

void main() {
  print(greetBob(Person('Kathy')));
  print(greetBob(Impostor()));
}

扩展类(继承)

使用 extends 关键字来创建子类, 使用 super 关键字来引用父类.

重写类成员

子类可以重写实例方法, getter和setter. 可以使用 @override 注解指出想要重写的成员:

noSuchMethod()

当代码尝试使用不存在的方法或实例变量时, 通过重写 noSuchMethod() 方法, 来实现检测和应对处理:

枚举类型

枚举类型也成为 enumerationsenums, 是一种特殊的类, 用于表示 数量固定的常量值.

使用枚举

枚举中的每个值都有一个 index getter 方法, 该方法的返回值是 所在枚举类型定义中的位置 (从0开始).

枚举类型具有以下限制:

  • 不能被子类化, 混合或实现.
  • 枚举不能被显示实例化.
void main() {
  var currentSeason  = Season.spring;

  print(currentSeason.index);
  print(Season.values);
  // 如果不处理所有枚举值, 会受到警告:
  switch(currentSeason){
    case Season.spring:
      print("1-3月");
      break;
    case Season.summer:
      print("4-6月");
      break;
    case Season.autumn:
      print("7-9月");
      break;
    case Season.winter:
      print("10-12月");
      break;
  }
}

enum Season{
  spring,
  summer,
  autumn,
  winter
}

为类添加功能 Mixin

Mixin复用类代码 的一种途径, 复用的类可以在不同层级可以不存在 继承关系.

静态变量

静态变量(类变量)对于类级别的状态是非常有用的

class Queue {
  static const initialCapacity = 16;
  // ···
}

void main() {
// 静态变量直到它们被使用的时候才会初始化.
  assert(Queue.initialCapacity == 16);
}

静态方法

静态方法(类方法) 不能再实例上使用, 因此不能访问 this.

  • 对于常见或广泛使用的工具和函数, 应该考虑使用顶级函数而不是静态方法.
  • 静态函数可以当做编译时常用使用.
    • 例如, 可以将 静态方法作为参数传递给常量构造函数.

泛型

在类型安全上通常需要泛型支持, 它的好处不仅仅是保证代码的正常运行:

  • 正确指定泛型类型可以 提高代码质量.
  • 使用泛型可以 减少重复的代码.
// T 是一个备用类型, 属于类型占位符, 在开发者调用该接口的时候会指定具体类型.
abstract class Cache<T> {
  T getByKey(String key);
  void setByKey(String key, T value);
}

使用集合字面量

var names = <String>['Seth', 'Kathy', 'Lars'];
var ages = <num>[1,21,2,3];
var aaa = <dynamic>[1,21,2,3, 'sad', {'name': 'zhang'}, [12,21,3]];
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
var pages = <String, String>{
  'index.html': 'Homepage',
  'robots.txt': 'Hints for web robots',
  'humans.txt': 'We are people, not machines'
};

使用泛型类型的构造函数

// 定义 Set 数据接口中类型为 string
var nameSet = Set<String>.from(names);
// 创建了一个 key 为 integer, value 为 View 的 map 对象:
var views = Map<int, View>();

运行时的泛型集合

Dart 中泛型类型是 固化的, 也就是说在 运行时是携带者类型信息的.

限制泛型类型

使用泛型类型的时候, 可以使用 extends 实现参数类型的限制.

使用泛型函数

T first<T>(List<T> ts) {
  // 做一些初始化工作, 然后...
  T tmp = ts[0];
  // 做一些额外的处理和检查, 然后...
  return tmp;
}
  • 函数的返回值类型(T)
  • 参数的类型(List<T>)
  • 局部变量的类型(T tep)

在import语句后面输入库文件的URI

// 引入第三方库文件
import 'package:flutter/material.dart';
// 引入项目中的文件
import './animated_cross_fade_demo.dart';
// 引入 dart 提供的库文件
import 'dart:html

设置库前缀

// 当不同库出现同样标识符, 可以用库前缀解决解决命名冲突
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

只导入库的一部分

import 'package:lib1/lib1.dart' show foo; // 仅导入 foo
import 'package:lib2/lib2.dart' hide foo; // 除了 foo 外都导出

懒加载库

// 当使用的时候在加载
import 'package:deferred/hello.dart' deferred as hello;

// 使用的时候
hello.loadLibrary();

实现一个库

使用 `library` 加上一个标识符 `point` 定义当前库的名字
library point;

part&part of

如果一个库的所有代码都卸载一个文件中, 会导致文件太大不好维护, 可以用 part & part of 关键字拆分文件.

library 语句所在的主文件中可以使用 importpart 语句, 但是 part of 所在的实现文件中不能使用任何 import/library/part语句. 库使用的所有 import 和 part 语句都必须放在主文件中声明.

// 主文件 定义一个 math 库。它由 base,random 两部分组成
library math;
part 'base.dart';
part 'random.dart';
// 在 base.dart 文件的开头
part of math
// 在 random.dart 文件的开头
part of math;

export

可以使用 export 语句重新导出库.
比如:
把多个较小的库组合为一个较大的库或者重新导出库的一部分作为一个新的库.
既可以导出库的全部, 也可以导出库的一部分(使用 show 和 hide).

Typedefs

// 定义函数参数类型与返回值
typedef int CalFunc(int num1, int num2);
main() {
    int num1 = 1;
    int num2 = 2;
    // 参数调用与传递
    int calculate(CalFunc func) {
        return func(num1, num2);
    };
    int result = calculate((int num1, int num2) {
        return num1 - num2;
    });
    print(result);
}

Type Script 笔记 - 草稿

原始数据类型

let myName: string = 'Tom';
let myAge: number = 25;
let isDone: boolean = false;
let unusable: void = undefined;
let u: undefined = undefined;
let n: null = null;
let myFavoriteNumber: any = 'seven';
function sayHello(person:string): any {
  console.log('===');
  return {
    age: '12312',
    name: 'asds a'
  };
}
  • 如果定义的时候没有赋值,都会被推断成 any 类型而完全不被类型检查.

联合类型

let myFavoriteNumber: string | number;
// myFavoriteNumber 既可以是 string 也可以是 number

访问联合类型的属性或方法

// 报错
function getLength(something: string | number): number {
    return something.length;
}
// 正确

function getString(something: string | number): string {
    return something.toString();
}

对象的类型

在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。

什么是接口

在面向对象语言中, 接口(interfaces)是对象行为的抽象, 而具体如何行动需要由类(classes) 去实现(implements)

在 TS 中接口是一个非常灵活的概念, 除了可用于对类的一部分行为进行抽象, 也常用于对 对象的形状(Shape) 进行描述

interface Person {
  // 只读属性初始化时必须赋值, 赋值后不可更改
  readonly id: number,
  name: string,
  age?: number,
  gender?: string,
  [propName: string]: any

}

let tom: Person = {
  name: 'Tom',
  age: 12,
  gender: 'man',
  hobby: '奥术大师多',
  lll: '123撒大声地'
}

一旦定义了任意属性,那么确定属性和 可选属性 的类型都必须是它的类型的子集

interface Person {
  age?: number,
  [propName: string]: string

}
// age 可选属性的类型是 number 与任意属性的类型产生了冲突就是报错
let tom: Person = {
  age: 12,
  hobby: '奥术大师多',
  lll: '123撒大声地'
}

数组的类型

// 报错, 参数必须都是 number
let fibonacci: number [] = [1, 1, 2, 3, 5, '啊'];
// 通过, 参数可以是 number 或则是 string
let fibonacci: (number | string) [] = [1, 1, 2, 3, 5, '啊'];
// 报错, 不可以通过各种方式加入其它类型数据
fibonacci.push([213,12,3])

数组泛型

// 通过
let fibonacci : Array<number|string> = [123,123,12,3, '1231'];

用接口表示数组

// 只要 index 的类型是 number, 那么值得类型必须是 number
interface MyArray {
  [index: number]: number
}

let aaa : MyArray = [123,12,412]

any 在数组中的应用

let list: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];

函数的类型

函数声明

// 这只定义了俩个函数, 多传参数或者少传参数都会报错
function sum(x: number, y: number): number {
    return x + y;
}

函数表达式

let mySum = function (x: number, y: number): number {
    return x + y;
};

用接口定义函数的形状

interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  return source.search(subString) !== -1;
}

可选参数

// 可选参数必选在必须参数后面, 否则会报错
function buildName(firstName: string, lastName?: string) {
  if (lastName) {
      return firstName + ' ' + lastName;
  } else {
      return firstName;
  }
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

参数默认值

function buildName(firstName: string = 'Tom', lastName: string) {
    return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName(undefined, 'Cat');

剩余参数

function push(array: any[], ...items: any[]) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, 3);

函数重载

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

类型断言

比如我们访问一个不确定类型的属性或方法时, 比如:

function getLength(something: string | number): number {
    if ((<string>something).length) {
        return (<string>something).length;
    } else {
        return something.toString().length;
    }
}

声明文件

当使用第三方库时, 需引用其声明文件, 才能获得对应的代码补全和接口提示等功能

比如在 ts 中使用 jQuery, 需要使用 declare var 来定义其类型:

// 定义 jQuery, 参数是字符串, 返回值是任意类型
declare var jQuery: (selector: string) => any;
/**
 * declare var 并没有真的定义一个变量,
 * 只是定义了全局变量 `jQuery` 的类型,
 * 仅仅回用于编译时的检查.
 */

什么是声明文件

  • 声明的文件必需以 .d.ts 为后缀。
  • 一般来说, ts 会解析项目中所有的 *.ts 文件, 当将 jQuery.d.ts 放到项目中时, 其它所有的 *.ts 文件就都可以获得 jQuery 的类型定义.
  • 通常会把生命语句放到一个单独的文件(jQuery.d.ts)中, 这就是声明文件:
// src/jQuery.d.ts
declare var jQuery: (selector: string) => any;
/path/to/project
├── README.md
├── src
|  ├── index.ts
|  └── jQuery.d.ts
└── tsconfig.json

假如仍然无法解析,那么可以检查下 tsconfig.json 中的 filesincludeexclude 配置,确保其包含了 jQuery.d.ts 文件。

这只是全局变量模式的声明文件形式.

第三方声明文件

推荐的是使用 @types 统一管理第三方库的声明文件.
@types 的使用方式很简单, 直接用 npm 安装对应的声明模块即可, 类似:

npm install @types/jquery --save-dev

书写声明文件

当一个第三方库没有提供声明文件时, 我们就需要自己书写声明文件了.
在不同的场景下, 声明文件的内容和使用方式会所区别.

库的使用场景主要有以下几种:

  • 全局变量:通过 <script> 标签引入第三方库,注入全局变量
  • npm 包:通过 import foo from 'foo' 导入,符合 ES6 模块规范
  • UMD 库:既可以通过 <script> 标签引入,又可以通过 import 导入
  • 模块插件:通过 import 导入后,可以改变另一个模块的结构
  • 直接扩展全局变量:通过 <script> 标签引入后,改变一个全局变量的结构。比如为 String.prototype 新增了一个方法
  • 通过导入扩展全局变量:通过 import 导入后,可以改变一个全局变量的结构

全局变量

使用全局变量的声明文件时, 如果是以 npm install @types/xxx --save-dev 安装的, 则不需要任何配置.

全局变量的声明文件主要有一下几种语法

  • declare var 声明全局变量
  • declare function 声明全局方法
  • declare class 声明全局类
  • declare enum 声明全局枚举类型
  • declare namespace 声明全局对象(含有子属性)
  • interfacetype 声明全局类型

深度阅读

export {
    name,
    getName,
    Animal,
    Directions,
    Options
}

export namespace foo {
    const name: string;
    namespace bar {
        function baz(): string;
    }
}

export default function foo(): string;

// 整体导出
module.exports = foo;
// 单个导出
exports.bar = bar;

// 整体导入
const foo = require('foo');
// 单个导入
const bar = require('foo').bar;

// 整体导入
import * as foo from 'foo';
// 单个导入
import { bar } from 'foo';

// 整体导入
import foo = require('foo');
// 单个导入
import bar = require('foo').bar;

注意,只有 functionclassinterface 可以直接默认导出,其他的变量需要先定义出来,再默认导出:

类型别名

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

泛型

以输入值得类型作为输出值得类型

// 函数名后的 <T>, 其中 T 用来指任意输入的类型, 在后面的输入 value: T 和输出 Array<T> 中即可使用.
function createArray<T>(length: number, value: T): Array<T> {
    let result: T[] = [];
    for (let i = 0; i < length; i++) {
        result[i] = value;
    }
    return result;
}

createArray<string>(3, 'x'); // ['x', 'x', 'x']

算法 笔记-待续

关于算法

  • 什么是算法?
    • 算法的本质是寻找规律并实现
  • 如何发现规律?
    • 发现输入和输出的关系, 寻找突破点
  • 如何实现?
    • 实现是程序+数据结构的结合体
  • 什么是时间复杂度?
    • 时间复杂度是按照最大执行次数计算的
  • 什么是空间复杂度?
    • 空间复杂度是按照占用最大内存空间计算的

关于大O的概念?

  • n表示数据规模
  • O(f(n)) 表示运行算法所需要执行的指令数, 和f(n)成正比

关于大O的提现

二分查找法 O(logn)          => 所执行指令书: a * logn
寻找数组中的最大/最小值 O(n)  => 所执行指令书: b * n
归并排序算法 O(nlogn)       => 所执行指令书: c * nlogn
选择排序法 O(n^2)           => 所执行指令书: d * n^2

举例

算法A: O(n) 所需执行指令数: 10000*n
算法B: O(n^2) 所需之星指令数: 10 * n^2

n A指令数 10000n B指令数 10n^2 倍数
10 10^5 10^3 100
100 10^6 10^5 10
1000 10^7 10^7 1
10000 10^8 10^9 0.1
10^5 10^9 10^11 0.01
10^6 10^10 10^13 0.001
时间复杂度 O 衡量的是量级上的差距,
这种量级上的差距表现在,当数据达到一个临界点时,
时间复杂度低的算法,就一定比时间复杂度高的算法要快,
而且n越大,差距就越大

再有一些复杂度很高的算法可能有常数级小的优势, 数据规模小的时候是有意义的.

对于所有的高级排序算法, 当数据规模小到一定程度时可选择插入排序法来进行优化, 优化的效率大约能有10%-15%左右.

算法复杂度比较

O(Cn) -> O(n2) -> O(n) -> O(logn) -> O(1)

符号 名称
O (1) 常数(阶,下同)
O (logn) 对数
O [(logn)] 多对数
O (n) 线性,次线性
O (n log* n) log* n 为迭代对数
O (nlogn) 线性对数,或对数线性、拟线性、超线性
O (n2) 平方
O (n%), Integer (c> 1) 多项式,有时叫作'代数'(阶)
O (cn) 指数,有时叫作'几何'(阶)
O (n!) 阶乘,有时叫做'组合'(阶)

关于大O在各领域的不同 ?

学术界,严格的讲, O(f(n)) 表示算法执行的上界

什么是算法执行的上界?
归并排序算法的时间复杂度是O(nlogn)的, 同时也是O(n^2)

业界,我们就是用O来表示算法执行的最低上界.
虽然在学术界归并排序算法复杂度是O(n^2)是对的, 但是在业界我们一般不会说你归并排序是O(n^2)的, 而是O(nlogn).

这不是一个严谨不严谨的问题, 是在业界约定俗成的问题, 世界各大公司都是默认这样的

如果我们设计了一个算法,我们以量级最高的时间复杂度作为主导

比如
O (nlogn + n) = O(nlogn)
O (nlogn + n^2) = O(n^2)

Flutter 笔记-待续

概念

  • StatelessWidget 只负责显示的

  • StatefulWidget 组件是可以拥有状态的

  • 在Dart中 甚至连 数字、方法和null都是对象

  • 所有的对象都继承于Object类

  • Dart动态类型语言, 尽量给变量定义一个类型,会更安全,没有显示定义类型的变量在 debug 模式下会类型会是dynamic(动态的)

  • Dart会在运行之前解析你的所有代码,指定数据类型和编译时的常量,可以提高运行速度

  • Dart中的类和接口是统一的,类即接口,你可以继承一个类,也可以实现一个类(接口),自然也包含了良好的面向对象和并发编程的支持
    Dart函数

  • 支持顶级函数 (例如main())

  • 支持在类中定义函数, 如静态函数和实例函数

  • 还可以在方法中定义方法(嵌套方法或者局部方法)

  • 类似的,Dart支持顶级变量,以及依赖于类或对象(静态变量和实例变量)变量。实例变量有时被称为域或属性
    Dart不具备关键字public,protected和private。如果一个标识符以下划线()开始,那么它和它的库都是私有的
    标识符可以字母或(
    )开始,或者是字符加数字的组合开头

变量

声明变量

var name = 'name';
dynamic name1 = 'name1';
String name2 = 'name2';

// 变量的赋值
name = 'a';
name1 = 'a1';
name2 = 'a2';
var name;
dynamic name1;
String name2;

在声明变量的时候,你可以选择加上具体的类型:

String name2 = 'name2';

常量

  • 常量使用final或者const
  • 一个final变量只能赋值一次
  • 一个const变量是编译时常量
  • 实例变量可以为final但是不能是const

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.