Giter VIP home page Giter VIP logo

day-day-up's People

Contributors

koala-coding avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

day-day-up's Issues

2020年3月3号记录

今日计划完成
1.深蹲50个,
2.投递简历,和hr沟通。获得一个面试机会。
3.背单词100个
4.写成考作业 占据了四个小时
5.读文章2篇。
6.俯卧撑15个。有酸痛感 所以减少。

2019年12月14日你要记录点什么?

今天遇到一个需求,已知月份,得到这个月的第一天和最后一天作为查询条件查范围内的数据

new Date(year, month, date, hrs, min, sec),new Date可以接受这些参数创建一个时间对象
其中当我们把 date 设置为 0 的时候,可以直接通过 getDate() 获取到最后一天的日期然后得到我们要的最后一天

  new Date(2019, 12, 0).getDate() // 31
  new Date(2018, 2, 0).getDate()  // 28
  // 根据这个我们可以得到一个方法
  function getMonthLength(month) {
    const date = new Date(month)
    const year = date.getFullYear()
    // 月份是从 0 开始计算的
    const _month = date.getMonth() + 1
    return new Date(year, _month, 0).getDate()
  }

2019年12月19日你要记录点什么?

ES6 Set 和 Map

Set的结构是类似于数组结构,但是成员都是不重复的值(对象除外)

  • SET的方法和属性

    • add 添加

    • has 查询

    • delete 删除

    • clear 清除

    • size 长度/大小

    • forEach 遍历(第一个参数和第二个参数相同)

      • Set中下个位置的值
      • 与第一个参数相同的值
      • 目标Set本身

Map结构是键值对集合(Hash结构)

  • Map的方法和属性

    • set 设置,添加

    • has 查询

    • delete 删除

    • clear 清除

    • size 长度/大小

    • forEach 遍历

      • key值
      • value值
      • map本身

2020年3月21号 你要记录点什么?

假期学习—— MySQL(二)

↑↑↑ 接昨天

从图中我们可以看出 MySQL 可以分为 Server 层和存储引擎层两部分。

Server 层

连接器

运行 sql 语句的第一步就是连接数据库。连接器就是负责与客户端建立连接、获取权限、维持和管理连接。
连接器在 TCP 握手后,开始认证身份。

开始连接时,验证用户名和密码,如果验证不通过,服务器会收到 Access denied for user 的错误返回。

如果验证通过,连接器会到权限表中查出拥有的权限。
此次连接查到的权限在这次连接失效前一直有效,不会因为权限的更改而受到影响。

连接完成后,如果一直没有对数据库进行操作,则本次连接处于空闲状态。
show processlist 查看所有连接, command 表示连接状态, sleep 表示空闲

客户端如果太长时间没有请求数据库,连接器会自动断开,默认为8小时,可以通过 wait_timeout 自定义。

连接断开后,客户端再次发送请求,会受到错误提醒: Lost connection to MySQL server during query, 需要重新连接服务器。

长连接 数据库连接成功后,客户端持续有请求,使用同一个连接。
短连接 : 一次连接只是执行几次 sql 语句就断开,下次执行再重新创建一个。

由于建立连接过程比较复杂,所以在使用中要尽量减少连接次数,尽量使用长连接。

全部使用长连接,由于 mysql 在执行过程中临时使用的内存是保存在连接对象中的,只有在链接断开的时候才会释放,因此mysql 占用内存会涨的特别快。所以长连接累积下来,会导致内存占用太大,被系统强行杀掉(OOM),mysql 异常重启。
解决方案:

  • 定期断开长连接。使用一段时间后,或者在执行了一个占用内存大的查询后,断开连接,之后查询时再重连。
  • mysql 5.7 或 以后的版本,可以执行 mysql_reset_connection 来初始化连接资源。不需要重新连接,会将连接恢复到刚创建完的状态。

查询缓存

连接数据库后,需要先查询缓存。
如果之前执行过这条查询语句,查询结果可能会以 key-value 的形式保存在内存中。key 是查询的语句, value 是查询到的数据。查询缓存会直接把 value 返回给客户端。
如果查询语句不在查询缓存中,会继续往下执行,获取到的新的查询结果会被存入到查询缓存中。

  • 查询缓存适用于静态表
  • query_cache_type 设置为 DEMAND, 这样就不适用查询缓存了
  • 可以使用 SQL_CACHE 指定某一条语句是否使用查询缓存 select SQL_CACHE * from table
  • mysql 8.0 以后删除了查询缓存模块

分析器

  • 词法分析
    mysql 识别 sql 语句每个字符串代表的意思
  • 语法分析
    分析 sql 语句是否符合语法规则,语法有误则返回Tou have an error in your SQL syntax

优化器

  • 当表中有多个索引的时候,优化器会决定 sql 语句使用哪个索引

  • 当查询语句有多表关联时,决定各个表的连接顺序

    mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
    • 先查t1,再查t2
    • 先查t2,再查t1
    • 查询结果相同,执行效率不同

执行器

执行 sql 语句时,先判断对这个表有没有查询的权限,没有权限会返回没有权限的错误。如果有权限就继续执行,使用存储引擎,

存储引擎

  • ID 字段没有索引:
    • 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 是不是1,如果不是跳过,如果是则将这行存在结果集中
    • 调用引擎接口取下一行,重复相同的判断逻辑,知道最后
    • 将所有的结果组成结果集返回给客户端
  • ID 字段有索引:
    • 取满足条件的第一行,直到最后一行保存为结果集,返回给客户端

2020年3月13号 你要记录点什么?

假期学习——再看 JavaScript 面向对象三大特性(一)

封装

JavaScript 是一种基于对象的语言,但是由于语法中没有 ==class== (类),所以它不是一种真正的面向对象编程语言。

生成实例对象的原始模式

假设把人看成一个对象,他拥有 "姓名" 、 "性别" 、 "年龄" 等属性。

    let person = {
        name: "",
        sex: "",
        age: ""
    }

按照以上方式创建 Bob 和 Mary 两个人

    let person1 = {
        name: "Bob",
        sex: "man",
        age: 18
    };
    let person2 = {
        name: 'Mary',
        sex: 'woman',
        age: 17
    };

这种方法特别的低效,而且 Bob、Mary 和 person原型 之间没有任何关联

改进原始模式

通过函数的方式传入参数,并返回对象

    function person(name, sex, age) {
        return {
            name, sex, age
        }
    }
    
    let person1 = person("Bob", "man", 18);
    let person2 = person("Mary", "woman", 17);

这种方法虽然不用一个一个创建对象,但是他们之间没有内在联系,不能反映是统一个原型对象的实例。

构造函数模式

构造函数,即在一个普通函数内部使用 ==this== , 然后对该函数使用 ==new== 运算符,生成实例。

    function Person(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    let person1 = new Person("Bob", "man", 18);
    let person2 = new Person("Mary", "woman", 17);

person1 和 person2 都有一个共同的 ==constructor== 属性, 且都是 Person

构造函数模式的缺点

假如所有对象实例都有相同的属性或方法

    function Person(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.career = "teacher";
        this.skill = function(){console.log(("传道受业解惑")}
    }
    let person1 = new Person("Bob", "man", 18);
    let person2 = new Person("Mary", "woman", 17);

这里 Bob 和 Mary 都具有相同的属性 career 和相同的方法 skill;
如果使用构造函数的方法则会造成内存的浪费。

prototype 原型模式

JavaScript 中,每一个构造函数都有一个 prototype 属性,它指向另一个对象,这个对象的所有属性和方法都会没构造函数生成的实例所继承

    function Person(name, sex, age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    Person.prototype.career = "teacher";
    Person.prototype.skill = function(){console.log("传道受业解惑")};
    let person1 = new Person("Bob", "man", 18);
    let person2 = new Person("Mary", "woman", 17);

这里 person1 和 person2 都具有 career 属性和 skill 方法;

prototype 模式的验证

  • isPrototypeOf()
    // 这个方法用来检测 prototype 和某个实例之间的关系
    console.log(Person.prototype.isPrototypeOf(person1); // true
  • hasOwnProperty()
    // 每个实力对象都有 hasOwnProperty() 方法, 用来判断某个属性属于自身还是属于 prototype
    console.log(person1.hasOwnProperty("name")); // true
    console.log(person1.hasOwnProperty("career")); // false
  • in运算符
    // in 运算符可以用来判断某个实例是否含有某个属性或方法,不管是自身的还是prototype的
    console.log("name" in person1); // true
    console.log("skill" in person1); // true
    console.log('color' in person1); // false

in 运算符可以用来遍历某个对象的所有属性,即 for in 循环

2020年01月13日你要记录点什么?

分享一个 bind 的实现

bind 基本用法

bind 用法和 call 很类似,但是 bind 不会立即执行函数,而是返回一个绑定了 this 的新函数

const obj = {name: 'cym'}
function fn(age) {
  console.log(this.name + '今年' + age + '岁了')
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind(obj)
bindFn(24) // cym今年24岁了

基本功能的实现

根据上面的用法,我们不难 bind 的方法不仅可以绑定 this 还可以绑定参数,我们来简单实现一下

Function.prototype.bind2 = function(ctx = globalThis) {
  // 取到我们要绑定的参数
  const args = [...arguments].slice(1)
  // 缓存 this,因为返回一个函数 this 就会变成新的函数
  const that = this
  // 返回一个函数
  return function() {
    // 返回函数里面的 arguments 是返回函数传入的参数哦,别搞混了
    that.apply(ctx, args.concat([...arguments]))
  }
}

返回函数作为构造函数

bind 方法的实现其实蛮有意思的,因为 bind 方法返回一个函数,那么返回的这个函数如果被当做构造函数怎么办

const obj = {name: 'cym'}
function fn() {
  console.log(this)
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind(obj)
const instance = new bindFn(24) // fn {}

根据上面的代码返回结果来看,我们发现当绑定的函数作为构造函数来用的话,this 指向了原来的函数的实例,那么我们来实现一下完整的 bind 方法

Function.prototype.bind2 = function(ctx = globalThis) {
  // 取得参数
  const args = [...arguments].slice(1)
  // 取得函数
  const that = this
  // 要返回一个函数,还要判断是否有进行实例化的操作
  function Fn() {
    const allArgs = args.concat([...arguments])
    // 如果被实例化了
    if (this instanceof Fn) {
      that.apply(this, allArgs)
    } else {
      that.apply(ctx, allArgs)
    }
  }
  // 但是我们需要保证原型不能丢失,还得是原来函数的实例
  // 这种写法可能不雅观,因为直接让两个原型指向了同一个地址,一般情况下我们会使用一个临时性构造函数来处理一下
  // Fn.prototype = this.prototype
  Fn.prototype = Object.create(this.prototype)
  // 返回这个绑定好 this 的函数
  return Fn
}

来看下用法

const obj = {name: 'cym'}
function fn() {
  console.log(this)
}
// 如上代码,我们要让 this 指向 obj
const bindFn = fn.bind2(obj)
const instance = new bindFn()   // fn {}
bindFn()  // {name: 'cym'}

2020年3月2号记录

今日所做:
1.看书半小时《刻意练习》
2.背单词100个。
3.深蹲50个。
4.打扫卫生。
5.投递简历大概150份。沟通人少于10人。
6.俯卧撑30个。
7.阅读文章五篇。
所列2020年3月2号。

2020年3月16号 你要记录点什么?

假期学习——再看 JavaScript 面向对象三大特性(三)

多态

多态通俗的讲就是一个接口多种实现方法,有时在程序设定之初,肯能会根据程序需求不同,不确定使用哪个函数实现,通过多天不需要修改源码,就可以实现

表现形式为 ==重写== 、 ==重载== 、 ==接口==

重写(运行时多态)

重写指子类重新定义父类方法。

    function Person(name) {
        this.name = name;
        this.sayHello = function () {
            console.log("Hello !!")
        }
        this.getName = function () {
            console.log(this.name)
        }
    }
    
    function Teacher(name) {
        Person.apply(this, arguments);
        this.sayHello = function () {
            console.log("Hello, everyone. I am " + name + " !!")
        }
    }
    
    let teacher = new Teacher("Lily");
    console.log(teacher.sayHello()); // Hello, everyone. I am Lily !!
    console.log(teacher.name); // Lily
    console.log(teacher.getName()); // Lily

上边这段代码中,Teacher 继承了 Person 的 name 属性和 getName 方法,并且对 sayHello 方法进行了修改,即重写。

重载(编译时多态)

重载是指多个同名但参数不同的方法,在JS中,判断arguments的个数和类型,然后具体判断。

    function foo1(a) {
        console.log(a)
    }
    function foo2(a, b) {
        console.log("a: " + a, "b: " + b)
    }
    
    function foo () {
        if(arguments.length === 1) {
            foo1.apply(null, arguments)
        } 
        if(arguments.length === 2) {
            foo2.apply(null, arguments)
        }
    }
    
    foo(1); // 1
    foo(1, 22); // a: 1 b: 22

接口

将父对象的方法抛出异常,如果没有被实现就会报错

    function Person() {
        this.sayHello = function(){throw '没有定义该方法'}
    };
    
    function Teacher() {
        this.sayHello = function(){
            console.log("Hello everyone, I am a teacher.")
        }
    };
    
    function Worker() {
        this.sayHello = function(){
            console.log("Hello, I am a worker.")
        }
    };
    
    function Doctor(){};
    
    Teacher.prototype = new Person();
    Teacher.prototype.constructor = Teacher;
    
    Worker.prototype = new Person();
    Worker.prototype.constructor = Worker;
    
    Doctor.prototype = new Person();
    Doctor.prototype.constructor = Doctor;
    
    let teacher = new Teacher();
    console.log(teacher.sayHello()); // Hello everyone, I am a teacher.
    
    let worker = new Worker();
    console.log(worker.sayHello()); // Hello, I am a worker.
    
    let doctor = new Doctor();
    console.log(doctor.sayHello()); // error: Uncaught 没有定义该方法

结论: JS是无态的,或者说JS天生支持多态

参考文章

Aaron: 面向对象之三个基本特征(javaScript)

aaronchu: JS多态

2020年3月18号 你要记录点什么?

↑↑↑ 接昨天

数值类型(浮点数)

  • FLOAT
  • DOUBLE
  • DECIMAL

日期和时间类型

  • DATE
    • date 是指日期
    • 格式为 YYYY-MM-DD
    • 范围是 1000-01-01 ~ 9999-12-31
    • 占用存储空间为 3 字节
  • TIME
    • time 是指时间 或者 持续时间
    • 格式为 HH:MM:SS
    • 范围是 -838:59:59 ~ 838:59:59
    • 占用存储空间为 3 字节
  • YEAR
    • year 是指年份值
    • 格式为 YYYY
    • 范围是 1901 ~ 2155
    • 占用存储空间为 1 字节
  • DATETIME
    • datetime 是指日期时间混合值
    • 格式为 YYYY-MM-DD HH:MM:SS
    • 范围是 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
    • 占用存储空间为 8 字节
  • TIMESTAMP
    • timestamp 是指时间戳
    • 格式为 YYYYMMDDHHMMSS
    • 范围是 19700101080000 ~ 20380119111407 (北京时间)
    • 占用存储空间为 4 字节

字符串类型

  • CHAR
    • 定长字符串
    • 大小 0 - 255 字节
    • 长度必须在创建时指定,否则会嘉定长度为1
    • 长度不足指定的大小时,会补空;长度大于指定大小时,会截取
    • 主要用作标题、作者
  • VARCHAR
    • 边长字符串
    • 大小 0 - 65535 字节
    • 创建时指定字符串的最大长度
    • 主要用于文章内容不确定长度的数据
  • BLOB
    • 二进制形式的长文本数据
    • 大小为 0 - 65535 字节
    • 不区分大小写
    • 通常用来存储文字、图像、多媒体
  • TINYBLOB
    • 不超过 255 个字符的二进制字符串
    • 大小为 0 - 255 字节
  • MEDUIMBLOB
    • 中等长度二进制形式文本数据
    • 大小为 0 - 16777215 字节
  • LONGBLOB
    • 二进制形式的极大文本数据
    • 大小为 0 - 4294967295 字节
  • TEXT
    • 长文本数据
    • 大小为 0 - 65535 字节
    • 最大长度为 64k
    • 通常用于文章内容,会区分大小写
  • TINYTEXT
    • 短文本字符串
    • 大小为 0 - 255 字节
  • MEDIUMTEXT
    • 中等长度文本数据
    • 大小为 0 - 16777215 字节
  • LONGTEXT
    • 极大文本数据
    • 大小为 0 - 4294867295 字节
    • 最大长度为4GB

Blob 是指二级制大对象

2020年3月14号 你要记录点什么?

假期学习——再看 JavaScript 面向对象三大特性(二)

继承

参考文章
阮一峰:Javascript面向对象编程(二):构造函数的继承
阮一峰:Javascript面向对象编程(三):非构造函数的继承

构造函数的继承

假设有一个"动物"的构造函数 和 一个"猫"的构造函数

    function Animal() {
        this.species = "动物";
    }
    function Cat(name, breed) {
        this.name = name;
        this.breed = breed;
    }
    let cat1 = new Cat("咪咪", "加菲猫")

要求:使猫继承动物的属性和方法

call 或 apply 修改this指向

将父对象的构造函数绑定在子对象上

    function Cat(name,breed){
    Animal.apply(this, arguments);
    this.name = name;
    this.breed = breed;
  }
  let cat1 = new Cat("咪咪", "加菲猫")
  console.log(cat1.species); // 动物

prototype 模式

将猫的prototype 对象指向 Animal 的实例,那么猫的实例就能继承 Animal 的属性和方法了。

    Cat.prototype = new Animal();
    console.log(cat1.species); // 动物
    console.log(cat1.constructor); // Animal

这时 Cat 生成的 cat1 就会继承 Animal 的 species 属性,但是此时 cat1 的 constructor 属性也随之发生了改变,会导致继承链混乱,所以需要我们手动修改回来

    Cat.prototype.constructor = Cat;
    console.log(cat1.constructor); // Cat

==结论:如果替换了构造函数的 prototype 对象,那么必须要给新的 prototype 对象加上 constructor 属性, 并将这个属性指向原来的构造函数==

直接继承 prototype

构造函数中所有不变的属性都可以直接写入 prototype 中,所以可以使 Cat 继承 Animal 的prototype。

    // 改写Animal
    function Animal() {}
    Animal.prototype.species = "动物";
    Cat.prototype = Animal.prototype;
    Cat.prototype.constructor = Cat;
    let cat1 = new Cat("咪咪", "加菲猫")
    console.log(cat1.species); // 动物

==优点:效率高,不用建立 Animal 实例, 比较省内存==
==缺点:由于 Cat 和 Animal 的 prototype 属性指向同一个对象,所以修改Cat 的 prototype ,Animal 的 prototype 也会随之改变==

    Cat.prototype.constructor = Cat;
    console.log(Animal.constructor); // Cat
    // 这段代码同时也会修改 Animal 的 constructor

使用空对象作为中介

此方法解决了上一种方法的缺点。

    let Foo = function(){};
    Foo.prototype = Animal.prototype;
    Cat.prototype = new F();
    at.prototype.constructor = Cat;
    let cat1 = new Cat("咪咪", "加菲猫");
    console.log(cat1.species); // 动物
    console.log(Animal.constructor); // Animal

拷贝继承

这种方法是将父对象的属性和方法拷贝进子对象实现继承

    function Animal() {};
    Animal.prototype.species = "动物";
    function extend_1 (Child, Parent) {
        let p = Parent.prototype;
        let c = Child.prototype;
        for (let i in p) {
            c[i] = p[i]
        }
    }
    extent_1(Cat, Animal);
    let cat1 = new Cat("咪咪", "加菲猫");
    console.log(cat1.species); // 动物

非构造函数的继承

使用空对象作为中介

    let Chinese = {
        nation: '**'
    };
    let Foo = function(){};
    Foo.prototype = Chinese;
    let Doctor = new F();
    Doctor.career = "医生";

浅拷贝

仅适用于拷贝基本数据类型,引用数据类型只会获得一个引用地址,不会实现拷贝

深拷贝

可以实现引用数据类型的拷贝,比如对象和数组

2020年3月17号 你要记录点什么?

假期学习—— MySQL(一)

MySQL 的数据类型

参考文章:

数值类型(整数)

MySQL 支持偶有标准SQL数值数据类型。
以下范围取值 前者是有符号的范围,后者是无符号的范围(unsigned)

  • TINYINT

    • tinyint 是指非常小的整数
    • 范围是(-128, 127) 和 (0, 255)
    • 占用存储空间为 1 字节
    • 常用来表示 boolean 、年龄
    • 在 mysql 中 boolean = tinyint[1],这里的 1 是指 tinyint 的长度
    • 如果需要表示数字可以增加 tinyint 的长度
  • SMALLINT

    • smallint 是指小型整数
    • 范围是(-32768, 32767) 和 (0, 65535)
    • 占用存储空间为 2 字节
    • 常用作类目的 id
  • MEDIUMINT

    • mediumint 是指中型整数
    • 范围是(-8388608, 8388607) 和 (0, 16777215)
    • 占用存储空间为 3 字节
    • 常用作文章 id
  • INT/INTEGER

    • int/integer 是指一般的整数
    • 范围是(-2147683648, 2147683647) 和 (0, 4294967295)
    • 占用存储空间为 4 字节
    • 常用于日期
  • BIGINT

    • bigint 是指大型整数
    • 范围是(-9223372036854775808, 9223372036854775807) 和 (0, 18446744073709551615)
    • 占用存储空间为 8 字节

2020年3月15号 你要记录点什么?

假期学习——call,apply,bind三者的异同点

相同点

bind,call,apply都可以改变this的指向,且第一个参数都是this要指向的对象,即指定的上下文(上下文就是指调用函数的那个对象)

不同点

  • bind
    • 返回的是一个函数,需要调用执行
    • 参数从第二个起,为传给调用函数的参数,用逗号隔开一次排列
  • call
    • Function对象的方法, 每个函数都能调用,且调用以后立即执行
    • 同bind第二条
  • apply
    • 同call第一条
    • 第二个参数为一个数组,调用函数的参数需要将所有的参数拼成一个数组

实际开发中的使用

  • bind
    • react 开发组件时,经常会遇到 this 指向问题,可以采用在组件的 constructor 属性中绑定 this
  • call
    • 验证数据类型
function checkDataType(obj){ 
    if(Object.prototype.toString.call(obj) === '[object Array]') return "Array";
    if(Object.prototype.toString.call(obj) === '[object Object]') return "Object";
    if(Object.prototype.toString.call(obj) === '[object Function]') return "Function";
    if(Object.prototype.toString.call(obj) === '[object String]') return "String";
    if(Object.prototype.toString.call(obj) === '[object Number]') return "Number";
    if(Object.prototype.toString.call(obj) === '[object Boolean]') return "Boolean";
    if(Object.prototype.toString.call(obj) === '[object Symbol]') return "Symbol";
    if(Object.prototype.toString.call(obj) === '[object Undefined]') return "Undefined";
    if(Object.prototype.toString.call(obj) === '[object Date]') return "Date";
    if(Object.prototype.toString.call(obj) === '[object Math]') return "Math";
    if(Object.prototype.toString.call(obj) === '[object Set]') return "Set";
    if(Object.prototype.toString.call(obj) === '[object Map]') return "Map";
}    
  • apply
    • 实现构造函数的继承(call方法也可以)

参考文章

菜鸟教程:JavaScript 中 call()、apply()、bind() 的用法

2019年12月16日你要记录点什么?

何如部署一个express项目,并通过域名或公网IP访问

1、clone一个express项目,进入项目并安装依赖

git clone https://github.com/weblixin/learn_serve.git
cd learn_serve
npm i

2、在服务器后台配置安全组,加入需要的端口号

key value
规则方向 入方向
端口范围 3000/3000
授权对象 0.0.0.0/0

3、使用pm2启动项目

pm2 start bin/www -n learn

这样就能使用公网IP访问了

4、解析域名

key value
主机记录 www
记录值 公网IP

访问配置好的域名就可以访问啦,这里配置的是www的

2020年3月19号 你要记录点什么?

↑↑↑ 接昨天

参考文章

数值类型(浮点数)

  • FLOAT
    • float 是指单精度浮点数值
    • 范围是(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 和 0,(1.175 494 351 E-38,3.402 823 466 E+38)
    • 占用存储空间为 4 字节
    • 单精度float类型使用32比特存储,其中1位表示符号,8位表示指数,23位表示尾数;
  • DOUBLE
    • double 是指双精度浮点数值
    • 范围值(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 和 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)
    • 占用存储空间为 8 字节
    • 双精度double类型使用64比特存储,1位符号位,11位指数位,52位尾数位。
  • DECIMAL
    • decimal 是指小数值
    • 范围依赖于M和D的值
    • 占用存储空间,对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2
    • 精度M表示值存储的有效位数,小数位数D表示小数点后可以存储的位数。

2019年12月28日你要记录点什么?

字位反转操作符 ~

~ 返回 2 的补码,~x 大致等同于 -(x+1)

~42 // -(42+1) ===> -43

-(x+1) 中唯一能够得到 0(或者严格来说时候 -0)的 x 值是 -1,也就是说 ~ 和一些数字在一起会返回一个假值 0,其他情况下则返回真值

-1 是一个 哨位值,哨位值是那些在各个类型中被赋予了特殊含义的值。在 C 语言中 -1 代表函数执行失败,大于等于 0 的值代表函数执行成功

比如在 JavaScript 中字符串的 indexOf 方法也遵循这一惯例,该方法在字符串中搜索指定的字符串,如果找到就返回该子字符串所在的位置,否则返回 -1

~ 的用途

我们知道在 JavaScript 中假值有:undefined、null、false、+0、-0、NaN、'',其他都为真值,所以负数也是真值,那么我们就可以拿着 ~indexOf 一起检结果强制类型转换为 真/假 值

const str = 'hello world'
~str.indexOf('lo') // -4,真值
if (~str.indexOf('lo')) {
  // true
  // 找到匹配
}
~str.indexOf('ol') // 0,假值
!~str.indexOf('ol') // true
if (!~str.indexOf('ol')) {
  // true
  // 没有找到匹配
}

~ 要比 >=0== -1 更简洁

字位截除

我们经常使用 ~~ 来截取数字值的小数部分,以为这是和 Math.floor 效果是一样的,实际上并非如此

~~ 中第一个 ~ 执行 ToInt32 并反转字位,然后第二个在进行一次字位反转,就是将所有的字位反转回原值,最后得到的结果仍是 ToInt32 的结果

~~ 只适用于 32 位的数字,更重要的是他对负数的处理与 Math.floor 不同,所以使用时要多加注意

Math.floor(1.9) // 1
~~1.9 // 1
// 操作负数
Math.floor(-1.9) // -2
~~-1.9 // -1

~~x 能将值截除为一个 32 位的整数,x | 0 也可以,而且看起来更简洁哦,不过出于对运算符优先级的考虑,我们更倾向于使用 ~~x

~~1.9 // 1
1.9 | 0 // 1

~~-1.9 // -1
;-1.9 | 0 // -1

2019年12月17日你要记录点什么?

需求: 将下边的数据根据 name 字段的 - 转成 element-ui 树形控件需要的格式,最后一级数据添加 iddisabled字段,所有层级都有 label 字段

const data = {code: 200, data: [{"id":1,"name":"地球","status":1},{"id":2,"name":"埃及-金字塔","status":0},{"id":3,"name":"美国-洛杉矶-女神像","status":1},{"id":4,"name":"**-河北-唐山-路北区","status":0}]}
// 取数据
let {data: arr} = data;
// 取出name, 转成数组
let nameArr = arr.map(item => item.name.split("-"))
// 将name的数组转换为需要的格式
let cc = nameArr.map(item => mapArrToObj(item))
// 合并相同name的数组
let dd = composeRepeatItem(cc)
// 将其他字段添加到数据当中
let eee = appendOtherKeys(arr, dd)
console.log(eee, "eee")

// 将数组转化为树状对象格式
function mapArrToObj(arr) {
    let obj = {}, i= 0;
    obj.label = arr[i];
    i++;
    if(i < arr.length) {
        loopChild(obj, arr, i)
    }
    return obj
}
// 判断对象中是否存在children,不存在则添加
function loopChild(obj ,arr, i) {
	if (!obj.children) {
        obj.children = [{label:arr[i]}];
        i++;
        if(i < arr.length) {
            loopChild(obj.children[0], arr, i)
        }
    }
}
// 合并相同label的数组
function composeRepeatItem(arr) {
    let newArr1 = [],  o = [], s = [];
    for (var i = 0; i < arr.length; i++) {
	let item = arr[i];
	if(newArr1.indexOf(item.label) === -1) {
	    newArr1.push(item.label)
	    o.push(item)
	}
    }
    for (var m = 0; m < arr.length; m++) {
	let arr_item = arr[m];
	for (var n = 0; n < o.length; n++) {
	    let o_item = o[n]
	    if(arr_item.label === o_item.label) {
		if(o_item.children) {
		    o_item.children.push(arr_item.children[0])
		}
	    }
	}
    }
    for (var k = 0; k < o.length; k++) {
	o[k].children && o[k].children.splice(0, 1);
	let o_item1 = o[i];
	if(o[k].children) {
	    o[k].children = composeRepeatItem(o[k].children)
	}
        s.push(o[k])
    }
    return s
}
// 将其他字段添加到数组中
function appendOtherKeys(arr, newArr) {
    for (var i = 0; i < arr.length; i++) {
    let arr_item = arr[i];
    let names = arr_item.name.split("-");
    for (var l = 0; l < newArr.length; l++) {
	    let new_arr_item = newArr[l];
            let index = 0;
 	    if(new_arr_item.label === names[index]) {
                loopToAppend(new_arr_item, names, index, arr_item)
            }
        }
    }
    return newArr
}
// 判断是否有children,有则继续执行函数,没有则添加字段
function loopToAppend(obj, names, index, arr_item) {
    if(obj.children) {
	    index ++;
	    for (var i = 0; i < obj.children.length; i++) {
                if(obj.children[i].label === names[index]) {
                loopToAppend(obj.children[i], names, index, arr_item)
            }
        }
    } else if(!obj.children) {
        obj.id = arr_item.id
        obj.disabled = arr_item.status !== 1
    }
}

总结: 以上代码还有待优化,性能较差

2019年12月18日你要记录点什么?

服务器安装nginx

1、安装 pcreopenssl 依赖

yum -y install pcre* yum -y install openssl*

2、下载 nginx 压缩包

wget http://nginx.org/download/nginx-1.16.1.tar.gz

3、解压 nginx 压缩包

tar -zcvf nginx-1.16.1.tar.gz

4、进入 nginx-1.16.1 文件夹,执行配置文件,编译,安装依赖

cd nginx-1.16.1
./configure
make -j4
make install

5、进行软连接

ln -s /usr/local/nginx  nginx-1.16.1

6、进入nginx/conf文件夹下检查nginx.conf是否正确

cd /usr/local/nginx/conf
nginx -t

7、如果出现successfully,启动nginx

nginx

8、如果提示命令无效,修改环境变量

vim /etc/profile

9、在文件底部添加

PATH=$PATH:/usr/local/nginx/sbin
export PATH

10、保存修改文件,并重新编译该文件

source /etc/profile

11、启动nginx

nginx

2019年12月13日你要记录点什么?

装饰器的学习

之前一直听到装饰器这个词, 一直觉得是什么高深的东西, 这次打算尝试学习一下.

开始学习之前, 需要准备一下怎么让写的代码直接能运行起来, 一种方式在是babel官网提供的 try it out; 另一种就是本地配置babel的方式, 我选择本地编译

配置babel

安装babel

安装babel以及需要支持装饰器(Decorator)的插件

npm init 

npm install --save-dev @babel/core @babel/cli

npm install --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties

配置.babelrc文件

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", {
      "legacy": true
    }],
    ["@babel/plugin-proposal-class-properties", {
      "loose": true
    }]
  ]
}

下面就可以编译指定的文件了
babel decorator.js --out-file decorator-dist.js

装饰器是什么

简单来说, 装饰器是一个函数, 他的用法比较特殊。写成 @ + 函数名的方式,放在类和方法的前面,用来对类和类方法进行注释或者修改
先来一段代码简单的认识一下:

@addProperty
class Person {}

function addProperty(target) {
  target.age = 18;
}
console.log(Person.age) // 18

这段代码@addProperty就是一个装饰器, 给类Person添加了一个静态属性age。打印装饰器的参数target,可以发现它就是Person这个类本身

后续继续更新ing....

关于最近工作心得

因为最近有一个新项目比较急,而且是前后端不分离的,对我说还是比较难得。首先,接触了java模板:Thymeleaf,语法类似与vue的模板语法。这类模板语法主要使用[[${}]]这类标记。其他的与vue模板语法上没有太大的差异。可以使用switch,text,if之类的判断。但是这个语法的<script th:inline="javascript">一定要这样写。

2019年12月12日你要记录点什么?

函数柯里化

这个概念一直都只有听说过,但是并不太理解到底是怎么一回事,今天就让咱们来学一学吧

var curry = (fn,...args) => {
    var func = args.length<fn.length?
    (...arguments) => curry(fn,...args,...arguments):
	fn(...args);
    return func;
}
	
function sumFn(a,b,c) {return a+b+c;}
var sum = curry(sumFn)
console.log(sum(2)(3)(5))

2020年01月03日你要记录点什么?

Promise 添加 Promise.map 方法

有时候需要在一列 Promise 中迭代,并对所有的 Promise 都执行某个任务,非常类似于数组可以做的那样(比如 forEach、map 等),如果这些任务是同步的那这些任务就可以做,但是从根本上上来说 Promise 任务是异步的,所以我们需要一个类似的工具方法

// Promise.map 的实现
if (!Promise.map) {
  Promise.map = function(vals, cb) {
    return Promise.all(
      vals.map(val => {
        return new Promise((resolve, reject) => {
          cb(val, resolve, reject)
        })
      })
    )
  }
}

// 测试
const p1 = Promise.resolve(21)
const p2 = 42
// const p3 = Promise.reject('failed')
Promise.map([p1, p2], function(val, done, failed) {
  // 保证 val 是 Promise,统一格式
  Promise.resolve(val).then(res => {
   done(res * 2)
  //  捕获失败的情况
  }, failed)
}).then(result => {
  console.log(result, 'result')
}).catch(error => {
  console.log(error, 'error')
})

// 最终输出结果是,如果加上一个失败的 promise 该函数也是可以捕获的哦
// [42, 84]

2020年3月4号记录

1.面试失败
2.和好友沟通面试环节。
3.查找面试答案。
4.深蹲50个。俯卧撑10个。
5.单词76个,阅读文章5篇。
6.面试总结。

2019年12月25日你要记录点什么?Node.js初学者的一些全局变量和全局变量的见解~

学习过JavaScript的童鞋们都知道,在javascript中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。小编在node面前完全是小白,那么在最近学习node.js中,全局变量当然是必须也要学。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:
*** 在最外层定义的变量;

  • 全局对象的属性;
  • 隐式定义的变量(未定义直接赋值的变量)。**
    在node中也有一个全局对象global,它的作用和网页中window类似;
    值得注意:在 Node.js 中你不可能在最外层定义变量,node的代码都是属于当前模块的, 而模块本身不是最外层上下文。
    在node中全局创建的变量都会作为global的属性保存,通俗点说就是:定义一个全局变量时,这个变量就会成为全局对象的属性,对程序任何地方都可以访问了。
    当node在执行模块中的代码时,它会首先在代码的最顶部,添加如下外层函数代码。
    arguments.callee  这个属性保存的是当前执行的函数对象
    arguments.callee + “”,加一个空字符串,会把函数结构调用出来(内部调用机制)。
function (exports, require, module, __filename, __dirname) {
//     var a = 1;
//     console.log(arguments.length);
//     console.log(arguments.callee + "");
 }

实际上模块中的代码都是包装在一个函数中执行,在函数中的都是局部的变量,并且在函数执行的同时传了5个实参。
image

1,Exports:该对象用来将变量或者函数暴露到外部
2,Require:函数,用来引入外部的模块
3, Module:module代表的是当前模块本身,实际上exports就是module的属; 当你console.log(module.exports == exports); 输出为:true
 4,__filename:当前模块完整的路径
,5,__dirname:当前模块文件夹的完整路径

github 删除项目

挺久没有使用github, 删除一个项目都花了我几分钟, 在此记录一下

点击删除后弹出确认删除, 需要输入项目名字:

这里要注意是的创库的地址,刚开始我只输入创库名称,怎么都不好使

2019年12月20日你要记录点什么?

服务器mysql安装

1、下载安装包, 并解压 /usr/local/src

wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
tar -zxvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz

2、将解压后的文件夹移动到 /usr/local/mysql-5.7.26

mv mysql-5.7.26-linux-glibc2.12-x86_64 /usr/local
cd ../
mv mysql-5.7.26-linux-glibc2.12-x86_64 mysql-5.7.26

3、创建组和用户

groupadd mysql
useradd -r -g mysql mysql

4、创建mysql数据目录

cd /
mkdir -p data
cd data/
mkdir -p mysql

5、赋予权限

chown mysql:mysql -R /data/mysql

6、配置参数

vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql-5.7.26
datadir=/data/mysql
socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
#character config
character_set_server=utf8mb4
symbolic-links=0

7、初始化mysql

cd /usr/local/mysql-5.7.26/bin/
 ./mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql-5.7.26/ --datadir=/data/mysql/ --user=mysql --initialize

8、添加权限,开启自启

cp ./support-files/mysql.server /etc/init.d/mysqld
chown 777 /etc/my.cnf 
chmod +x /etc/init.d/mysqld

9、查看初始密码并复制

vim /data/mysql/mysql.err

root@localhost:后边的就是密码

10、启动mysql,并修改密码

service mysqld start
cd /usr/local/mysql-5.7.26/bin
./mysql -u root -p

回车,输入密码

mysql> set password=password('admin');

11、退出,停止mysql服务

mysql > quit
service mysqld stop

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.