KevinSwift

  • 首页
  • 关于
  • 标签
  • 分类
  • 相册

牛客网错题笔记(2)

发表于 2019-03-09 | 分类于 js相关

1.问题:http302状态表示什么,domContentLoaded表示什么事件
ie6/7/8不支持事件捕获。localStorage存储的数据,在刷新页面后会消失。
解析:http302状态表示被请求的资源暂时转移,然后会给出一个转移后的URL,
而浏览器在处理服务器返回的302状态的时候,原则上会重新建立一个TCP请求,然后再取重定向后的URL的页面;但是如果页面存在于缓存中,则不重新获取;
http各状态码解析:

值 状态
200 一切正常,实体主体中的文档
500(bad request) 客户端方面的问题,实体主题中的文档(若存在的话),是一个错误消息,。希望客户端能够理解此错误消息,并改正问题。
500(“Internal Server Error”) 服务期方面的问题。实体主体中的文档(如果存在的话)是一个错误消息。该错误消息通常无济于事,因为客户端无法修复服务器方面的问题。
301 表示永久性的转移,搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址
302 代表暂时性转移,搜索引擎会抓取新的内容而保存旧的网址。
404 表示找不到资源
401 表示未授权,需要用户身份验证
403 禁止访问,没有权限访问此站

具体解析
onload事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,domContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。

2.问题:

1
2
3
4
5
6
7
8
9
10
11
function Foo(){
var i=0;
return function(){
document.write(i++);
}
}
var f1=Foo(),
f2=Foo();
f1();
f1();
f2();

输出为:
答案:010
解析:f1和f2分别创建了自己的执行环境,所以它们两个是相互独立的,执行完成之后都返回一个匿名函数,这个匿名函数的作用域链被初始化为其包含函数的活动对象(这里就是i)和全局变量对象,f1执行之后i不会被销毁,因为返回的匿名函数还要引用i,i仍然在内存中,所以执行了2次之后i的值变成了1,而f2执行后i值是0。
3.问题:现有如下html的结构:

1
2
3
4
5
6
<ul>
<li>click me</li>
<li>click me</li>
<li>click me</li>
<li>click me</li>
</ul>

运行以下代码:

1
2
3
4
5
6
7
var elements=document.getElementsByTagName('li');
var length=elements.length;
for(var i=0;i<length;i++){
elements[i].onclick=function(){
alert(i);
}
}

依次点击后,弹出值为:
答案:4,4,4,4
解析:这是js的运行机制,事件click,focus,定时器setTimeOut,setInterval,ajax等都是异步,属于异步任务,js是单线程的,一个时间点只能做一个事情,优先处理同步任务,按照代码从上往下的运行,遇到异步任务,首先会挂起,放到异步任务里面去,继续执行同步任务,只有同步任务执行完了,才去执行异步任务,然后按照顺序执行,这里for循环是同步任务,onclick是异步任务,所以只有for循环执行完了,i已经变成4了,因为i是全局变量,最后的一个i++,使得i变成4,后面的click事件,在循环外面,不受i < length的的限制,所以for循环了4次,click都被挂起,共4次,for循环结束后,点击触发了4个onclick函数,所以输出了4个4。
4.问题:js中,document.getElementById返回的值得类型是
a.array b.object c.string d.function
答案:b
解析:可以使用typeof方法来查看document.getElementById返回的是什么值类型。
document.getElementById(“ul”)返回的是object,而document.getElementById是一个方法,因此返回的是function
5.问题:有以下es6的代码:

1
2
3
4
5
function *gen() {
yield 1;
yield 2;
yield 3;
}

说法正确的是:
答案:gen()执行后返回的是一个generator对象。
解析:function *声明(function 关键字后面跟了一个星号),定义了一个生成器函数(generator function),返回一个generator对象。返回一个iterator实例的next()方法,那么这个函数才开始真正执行,并且把yield后面的值包装成固定对象返回,直到运行到函数结尾,最后再返回undefined.
6.问题:在不改变元素的显示属性的情况下,元素都是可以设置宽度的,并且能够设置成功,这句话是否正确。
答案:错误
解析:块状元素:div,p,h1,h6,ol,ul,dl,table,address,form,blockquote等。设置display:block就是将元素设置为块状元素,每个元素都是从新的一行开始的。并且其后的元素也另起一行。元素的高度,宽度,行高和顶,底边距都是可以设置的。
元素宽度在不设置的情况下,是它本身父容器的100%,(和父元素的宽度一致),除非设定一个宽度。
内联元素:a,span,br,i,em,strong,label,q,cite,display:inline来设置。和其他元素在同一行上,元素的高度,宽度,顶部,底部距离不可以设置。元素宽度就是包含的文字或者图片的宽度,不可改变。
内联块状元素:inline-block,同时具备内联元素和块状元素的特征,和其他元素在同一行上,元素的高度,宽度,行高顶部底部距离都可以设置。
7.问题:表单提交时会触发什么dom方法:
答案:submit
解析:在w3中,submit被称为方法,而onsubmit被称为事件。具体可见:onsubmit事件 submit方法
8.问题:css sprites方法错误的是:
答案:css sprites增加了总的图片的字节,但是很好的减少网页的http请求,从而大大的提升网页的性能。
解析:在国内被称为css精灵,是一种网页图片应用处理方式,允许你将一个页面涉及到的所有零星图片都包含到一张大图中,这样一来,访问该页面的时候,载入的图片就不会像以前那样一幅一幅的慢慢显示出来,利用css的backgroud-image,background-repeat,background-position组合进行背景定位,background-position可以用数字精确定位出背景图片的位置。css精灵能很好的减少http请求。css精灵能减少图片的字节,3张合成一张总是小于3张图片的总字节。解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素命名,从而提高了网页的制作效率,更换风格方便,只需要在一张或少张图片上修改图片的颜色或者样式,整个网页的风格就可以改变,维护起来更加方便。
9.问题:下面有关js常见事件的触发情况,描述错误的是:
答案:onmousedown:某个鼠标按键被按下 onkeypress:某个键盘的键被按下或者按住,onblur:元素失去焦点,obchange:用户改变域的内容。
10.问题:w3c指定的js标准事件模型,以下正确的是
答案:事件捕获 到 事件处理 到 事件冒泡
解析:先事件捕获 window > document 往下级直到 特定的事件节点,然后进行事件处理,再事件冒泡,从特定节点往上级,这个完整的过程。
11.问题:下列描述中,关于js函数定义方式,正确的是:
答案:函数声明的语法定义:

1
2
3
function sum(sum1,sum2){
return sum1 + sum2;
}

函数表达式定义函数:

1
2
3
var sum = function(sum1,sum2){
return sum1 + sum2;
}

function构造函数可接受任意数量的参数,但最后一个参数始终被看成函数体:

1
2
var sum = new Function("num1","num2",
"return num1 + num2");

12.问题:使用h1标签会形成什么效果:
答案:加粗,大号字体。
13.问题:L在不涉及样式情况下,页面元素的优先显示与标签选用无关,正确或错误:
答案:正确
解析:优先显示和优先级还是不一样的,优先显示是html文档从上向下加载,只与标签的上下顺序有关,
与优先级无关
14.问题:常见的浏览器端的存储技术有哪些:
答案:cookie,localStorage,session,userData
解析:cookie,localStorage是常用的存储端技术,useData,IE浏览器可以使用userData来存储数据,容量可达到640K,这种方案是很可靠的,不需要安装额外的插件。缺点:它仅在IE下有效。
session 通常是服务器端的。indexDB。localStorage,sessionStorage,cookie通常是浏览器端存储的。
15.问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log(this.foo);
console.log(self.foo);
(function() {
console.log(this.foo);
console.log(self.foo);
}());
}
};
myObject.func();

答案:输出为bar bar undefined bar
解析:1、func是由myObject调用的,this指向 myObject。
2、self指向myObject,相当于myObject的this的副本。
3、这个立即执行匿名函数表达式(IIFE)是由window调用的,this指向window 。
4、IIFE的作用域处于myObject.func的作用域中,本作用域找不到self变量,沿着作用域链向上查找self变量,找到了指向 myObject对象的
16.问题:下面有关javascript内部对象的描述,正确的有?
1.History 对象包含用户(在浏览器窗口中)访问过的 URL
2.Location 对象包含有关当前 URL 的信息
3.Window 对象表示浏览器中打开的窗口
4.Navigator 对象包含有关浏览器的信息
17.问题:攻击者使用无效IP地址,利用TCP连接的三次握手过程,连续发送会话请求,使受害主机处于开放会话的请求之中,直至连接超时,最终因耗尽资源而停止响应。这种攻击被称为:
1.DNS欺骗攻击
2.DDos攻击
3.XSS攻击

4.SYN Flooding攻击
答案:4.
解析:各种攻击要去了解一下。
18.问题 以下js执行结果为:
以下Javascript代码执行后的输出结果依次是:()

1
2
3
4
5
6
7
8
9
10
11
12
var tmp = {};
var A = function() {};
A.prototype = tmp;

var a = new A();
A.prototype = {};

var b = Object.create(tmp);
b.constructor = A.constructor;

console.log(a instanceof A);
console.log(b instanceof A);

答案:false,false
解析:
19.问题:
a.inline-block可以设置高度,inline不可以设置高度
b.inline-block和inline都可以设置padding-left
c.inline-block可以设置margin-left,inline不可以
d.block会独占一行,inline-block不会。
答案:abd
解析:行内元素是不自动换行的,设置宽高无效,设置 上下margin和上下padding无效。
20.问题:
a.let声明的变量值和类型都可以改变
b.const声明的常量不可以改变
c.两者都不存在变量提升,同时存在暂时性死区,只能在声明的位置后面使用
d.const可以先声明再初始化,可以后赋值
答案:abc
21.问题:
对以下Javascript代码运行结果的描述错误的是:()

1
2
3
4
5
6
7
 
var a = {},
b = { key: 'b' },
c = { key: 'c' };

a[b] = 123;
a[c] = 456;

a.变量 a 有两个属性
b.console.log(a[b]) 输出 123
c.console.log(a[c]) 输出 456
d.console.log(a[a]) 输出 undefined
解析:对象添加属性有2种方式,第一种是采用点语法,例如采用obj.a = 1;第二种采用[] 的方法,obj[a] = ‘Joe’,题目中传入的是一个对象,所以会隐式的调用对象的toString()方法,把对象转换成字符串,执行 a[b] = 123 时 , a对象里是这样的 { ‘[object Object]’ : 123 } 。同理, a[c] = 345 , 把[object Object]重新赋值 。所以a对象只有一个属性,输出a[b] 相当于输出a的[object Object]456, a[a]同样得到456。

红皮书笔记

发表于 2019-03-06 | 分类于 js相关

第二章 在 HTML 中使用 JavaScript

scrpit加载的方式

async:可选,表示应该立即下载脚本,但不妨碍页面中的其他操作,比如下载其他资源或者或者等待加载其他脚本,只对外部脚本文件有效。
charest:表示通过src属性指定的代码的字符集。
defer:表示脚本可以延迟到文档完全被解析和显示以后再执行。只对外部脚本有效。
src:可选。路径。
type:可选,表示编写代码所使用的脚本语言的内容类型。也称为MIME类型。text/javascript属性。
js在head中与body中的加载不同。
在文档的head中包含所有js文件,意味着必须等到全部js代码被下载,解析,执行后才会显示页面的内容,
浏览器遇到body标签才开始呈现内容。这会导致浏览器呈现时候出现明显的延迟。
而延迟期间浏览器将会是一片空白,为了避免这个问题,现代web一般将全部js引用放到body中。
在head的script标签中加入defer属性defer = “defer”,脚本会被延迟到整个页面解析完毕再被执行。
head中的部分是代码在整个body前预先被加载,所以希望那些被调用的代码可以在这里写,例如按钮的点击事件等。
而body中的代码是html被加载完成之后再被执行。所以有用到body中的一些属性的,放在这里写。

第三章 js中的基本概念

label标签语句:

使用label标签语句可以在代码中添加标签,以便将来使用

1
2
3
4
5
start:for(var i = 0; i < 4;i++) {
if (i == 2)
break start;
alert(i);
}

如上所示,start标签标示的for循环语句可由break或continue引用,
break和continue可以和label联合起来使用,从而返回特定的代码,这种联合使用通常发生在循环嵌套的情况下。

1
2
3
4
5
6
7
8
9
10
11
var num = 0;
outermost:
for(var i = 0; i < 10;i++){
for(var j = 0; j < 10;j++){
if(i == 5 && j == 5)
break outermost;
num++;
}

}
console.log(num);

上述例子中,outermost标签代表外部的for语句,如果循环正常执行10次,则num最终的值时100,但内部循环中break带了一个参数,表示要返回的标签,添加这个标签的结果是break不仅会内部退出,也会外部退出循环。
这样,num的值刚好是55.

with语句

with语句的作用是将代码的作用域设置到一个特定的对象中,
with语句结构如下:
with (expression) statement;
定义with语句的主要目的是为了简化多次编写同一个对象的麻烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
var dic = {
a:1,
b:2,
c:3
};
with(dic){
var out_a = a;
var out_b = b;
var out_c = c;
}
console.log(out_a);
console.log(out_b);
console.log(out_c);

使用with语句关联了dic对象,这意味着with语句的代码快中,每个变量首先被认为是一个局部变量,而如果在局部变量中找不到该对象,就会查询dic中是否有该对象,严格模式下是不允许使用with语句的。
‘use strict’;with语句会报错。with语句会导致性能的降低,同时也会给调试代码造成困难,因此
在开发大型应用程序时,不建议使用 with 语句。

switch语句中可以合并多个case.

1
2
3
4
5
6
7
8
9
10
11
switch (i) {
case 25:
/* 合并两种情形 */ case 35:
alert("25 or 35");
break;
case 45:
alert("45");
break;
default:
break;
}

case中的变量可以是一个表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var num = 25;
switch (true) {
case num < 0:
alert("Less than 0.");
break;
case num >= 0 && num <= 10:
alert("Between 0 and 10.");
break;
case num > 10 && num <= 20:
alert("Between 10 and 20.");
break;
default:
alert("More than 20.");
}

函数

ecmascript函数不介意传递进去多少个参数,也不在乎传递进来的参数是什么类型的,也就是说,即使你定义的函数接收2个参数,但实际传进来3个,1个都是可以的。之所以这样, 是因为js中参数在内部是以数组形式表示的,函数接收到的始终是一个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过arguments对象访问这个参数数组,从而获取传递给函数的每一个参数。
arguments对象只是与数组类似(并不是array的实例),因为可以使用方括号语法访 问它的每一个元素(即第一个元素是 arguments[0],第二个元素是 argumetns[1],以此类推),使 用 length 属性来确定传递进来多少个参数。

1
2
3
4
function add(num1,num2) {
return num1 + num2;
}
console.log(add(1));

这样是不会报错的。只是会返回NaN,因为num2没有传递进去。

1
2
3
4
function add(num1,num2) {
return arguments[0] * arguments[1];
}
console.log(add(1,2));

可以用argument来访问其中的参数。

1
2
3
4
5
function doAdd(num1, num2) {
arguments[1] = 10;
alert(arguments[0] + num2);
}
console.log(doAdd(1,2));

在以上代码中,doAdd函数每次都会重写第二个参数,将第二个参数的值改为10,因为argument对象中的值会自动反映到对应的命名参数中,所以修改arguments[1],也就修改了num2,结果它们的值都会变成10,不过,这并不是说读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步。另外需记住,如果只传入了一个参数,那么arguments[1]的值修改不会反映到对应的num2中,,这是因为argument对象的长度是由传入的参数个数决定的,不是由定义时候的命名参数决定的。
**没有传递值得命名参数将自动被赋予undefined,这就跟定义了变量但是没有初始化时一样的。例如,如果只给 doAdd()函数传递了一个参数,则 num2 中就会保存 undefined 值。
严格模式对如何使用 arguments 对象做出了一些限制。首先,像前面例子中那样的赋值会变得无效。也就是说,即使把 arguments[1]设置为 10,num2 的值仍然还是 undefined。其次,重写 arguments 的值会导致语法错误(代码将不会执行)。

js中函数是没有重载的概念的。像其他语言中,定义了函数名字,即签名,但只要接收的参数不同,就会被重载,注意,js中是没有这个的。js中函数没有签名,因为其参数是由包含零或多个值的数组来表示的,而如果没有函数签名,重载也是做不到的。
相同名字的第二个函数定义会覆盖第一个。

第四章 变量、作用域和内存问题

基本类型和引用类型

js包含两种不同数据类型的值,基本类型值和引用类型值,基本类型值有string,boolean,number,undefined,null,这5种数据类型是按照值访问的。因为可以操作保存在变量中的实际的值。引用类型的值是保存在内存中的对象,js不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。 为此,引用类型的值是按引用访问的。当复制保存对象的某个变量时,操作的是对象的引用,但是在为对象添加属性时,操作的是实际的对象。
如下代码

1
2
3
var person = new Object();
person.name = "jack";
alert(person.name);

注意:我们不能给基本数据类型值添加属性,尽管不会导致任何错误。

1
2
3
var name = "jack";
name.age = 27;
alert(name.age);

输出为undefined.
复制的问题:从一个变量向另一个变量复制基本类型的值时,会在变量对象上创建一个新值,然后把该值复制 到为新变量分配的位置上。来看一个例子:

当复制引用类型的时候,同样也会将存储在变量对象中的值复制一份放到 为新变量分配的空间中。不同的是,这个副本实质上是一个指针,而这个指针指向存储在堆中的一个对象,复制操作结束以后,两个变量实际上将引用同一个对象,因此,改变其中的一个变量值,会影响另外一个变量的值。

1
2
3
4
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "ckq";
alert(obj2.name);//ckq

输出的第二个obj2的name也为ckq。
如下图所示:

传递参数

js中所有函数都是按照值传递的,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
基本数据类型是值传递容易理解。引用数据类型传值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。

1
2
3
4
5
6
7
8
function addTen(num) {
num += 10;
return num;
}
var count = 20;
var result = addTen(count);
alert(count);//20
alert(result);//30

传递给addTen中的num和count是独立的,没有关系。
如果传递的是引用类型:则函数内部产生的变化会影响到外部

1
2
3
4
5
6
function set(obj) {
obj.name = "cpp";
}
var obj = new Object();
set(obj);
alert(obj.name);//cpp

复制给set中的obj是外部的一个拷贝。实际上是一个指针,所以内部引起的变化会影响到外部。
下面是一个特殊的例子:

1
2
3
4
5
6
7
8
function set(obj) {
obj.name = "cpp";
obj = new Object();
obj.name = "ckq";
}
var obj = new Object();
set(obj);
alert(obj.name);//cpp

在上述例子中,首先将obj复制给函数,随后obj.name设置成cpp.当obj = new Object()的时候,在这时候obj已经指向了新的内存空间,与前面的指向无关,此时将obj设置成了ckq,所以后面的弹出obj依然是cpp。

检测类型

typeof只能检测基本的数据类型,例如字符串,数值,布尔值,还是undefined的最佳工具,如果变量的值是一个obj或者null的时候,则会返回object类型。可以采用instance of类型来检测更加具体的类型。

1
2
3
4
5
6
7
8
9
10
11
12
var a = "abc";
var b = true;
var c = 22;
var d;
var e = null;
var f = new Object();
console.log(typeof a);//string
console.log(typeof b);//boolean
console.log(typeof c);//number
console.log(typeof d);//undefined
console.log(typeof e);//object
console.log(typeof f);//object

根据规定,所有引用类型的值都是object的实例,因此,在检测一个基本数据类型的时候,会返回false,因为不是对象,检测对象的时候,会返回true.

1
2
3
4
5
var person = new Object();
console.log(person instanceof Object);//true
console.log(person instanceof Array); //false
var a = "11";
console.log(a instanceof String);//false

因为基本数据类型不是引用类型。

1
2
3
var a = new Array(1,2,3);
console.log(a);//1,2,3
console.log(a instanceof Array);//true

执行环境和作用域

执行环境是js中重要的一个概念,执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之关联的变量对象,环境中所有的变量和函数都保存在这里,虽然我们编写的代码无法访问,但解析器会在后台处理。
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。 而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。ECMAScript 程序中的执行流 正是由这个方便的机制控制着。
当代码在一个环境中执行时,会创建变量对象的一个作用域链,作用域链的用途,是保证对执行环节有权访问的所有变量和函数的有序访问,作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对 象在最开始时只包含一个变量,即 arguments 对象(这个对象在全局环境中是不存在的)。作用域链中 的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延 续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 这里可以访问color、anotherColor和tempColor }
// 这里可以访问color和anotherColor,但不能访问tempColor
swapColors();
}
// 这里只能访问color changeColor();

有如下作用域链:

内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何函数和变量,这些环境的联系是有序的,线性的。

延长作用域链

虽然执行环境总共只有2种,全局和局部的,但还是有其他办法来延长作用域链。有些语句可以在作用域的前端临时增加一个变量对象,该变量对象会在代码执行后自动销毁,在两种情况下会发生这种现象。具体来说,就是当执行流进入下列任何一个语句时,作用域链就会 得到加长:
**try-catch模块和with语句。
这两个语句都会在作用域链的前端添加一个变量对象。对 with 语句来说,会将指定的对象添加到
作用域链中。对 catch 语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。 下面看一个例子。

1
2
3
4
5
6
7
function buildUrl() {
var qs = "?debug=true";
with(location){
var url = href + qs;
}
return url;
}

在此,with 语句接收的是 location 对象,因此其变量对象中就包含了 location 对象的所有属 性和方法,而这个变量对象被添加到了作用域链的前端。

没有块级作用域

js中是没有块级作用域的 例如如下会输出true

1
2
3
4
if (true) {
var color = "blue";

alert(color); //"blue"

在c或者java中,花括号后,color便会自动销毁,但在js中,if语句中的变量声明会将变量添加到当前的执行环境(在这里是全局环境),在用for语句时要尤其记住这一点。

1
2
3
4
for (var i=0; i < 10; i++){
doSomething(i);
}
alert(i); //10

对于js来说,由for语句创建的变量i即使在for循环后,也会存在于循环外部的执行环境中。
声明变量。
使用var声明的变量会被自动添加到最接近的环境中,在函数内部,最接近的环境就是函数的局部环境;在 with语句中,最接近的环境是函数环境,**如果初始化变量时候没有使用var,该变量会被自动添加到全局环境中。

1
2
3
4
5
6
 function add(num1, num2) {
sum = num1 + num2;
return sum;
}
var result = add(10, 20); //30
alert(sum); //sum是全局变量,因此会弹出sum.

js中,不声明而直接初始化是一个非常严重的错误,所以,我们建议在初始化之前,一定要先声明,这样会避免许多错误,在严格模式下,初始化未经声明的变量会导致错误。

1
2
3
'use strict'
sum = 4;
console.log(sum);

上述代码会报错。

第五章 引用类型

object类型

直接创建

1
2
var person = new Object();
person.name = "nichoload";

使用对象字面量的方法

1
2
3
4
5
var p = {
name:'load',
age:28,
5:true
}

推荐使用对象字面量。
用方括号或者点来进行访问

1
2
console.log(p['name']); //load
console.log(p.name); //load

array类型

创建 ecmscript的每一项都可以存储任何数据类型

1
2
3
4
5
6
7
var color = new Array();
//长度为20的
var colors = new Array(20);
//包含3个字符串的
var colors = new Array("red","blue","green");
//或者直接创建
var colors = ["red","blue","green"];

如下创建最后一个可能会包含undefined

1
2
var values = [1,2,];
console.log(values[2]);//undefined

可以直接修改数组的length,修改后末尾会自动添加上undefined

1
2
3
var values = [1,2];
values.length = 3;
console.log(values[2]); //undefined

检测数组

可以使用isArray方法来检测数组 或者使用 isstanceof方法

1
2
3
4
5
6
var values = [1,2];
if(values instanceof Array){
console.log(true);
}
if(Array.isArray(values))
console.log(true);

转换方法

toString() 方法返回拼接后的字符串,逗号分隔

1
2
3
var values = [1,2];
console.log(values.toString()); //1,2
console.log(values.valuesOf());//[1,2]

join方法

join方法表示使用不同的字符进行拼接数组

1
console.log(values.join("||"));//1||2

如果不给 join()方法传入任何值,或者给它传入 undefined,则使用逗号作为分隔 符。IE7 及更早版本会错误的使用字符串”undefined”作为分隔符。
类似栈的方法

1
2
3
var values = [1,2];
values.push(3);
console.log(values); //1,2,3

在末尾添加
获得末尾的最后一项

1
2
var item = values.pop();
console.log(item);

类似队列的方法

shift方法表示从最前面移除一个数组

1
2
var item = values.shift();
console.log(item); //1

重排序方法

reverse表示翻转,sort表示排序,默认升序

1
2
3
4
var values = [1,4,3];
values.reverse();
console.log(values); //3,4,1
console.log(values.sort()); //1,3,4

sort方法调用每个数组项toString()方法,然后进行比较

1
2
var values = [1,10,5];
console.log(values.sort()); //1,10,5

典型例子
所以需要自己传入一个compare函数进行比较。

1
2
3
4
5
6
7
8
9
10
11
function compare(value1,value2) {
if(value1 < value2)
return -1;
else if(value1 > value2)
return 1;
else
return 0;
}

var values = [1,10,5];
console.log(values.sort(compare)); //1,5,10

表示升序排列。
第二个表示降序排列

1
2
3
4
5
6
7
8
9
10
11
function compare(value1,value2) {
if(value1 < value2)
return 1;
else if(value1 > value2)
return -1;
else
return 0;
}

var values = [1,10,5];
console.log(values.sort(compare)); //10,5,1

Array的基本方法

concat方法,基于当前数组创建一个副本,随后再将新的参数添加到这个副本的末尾,最后返回新的构建的数组

1
2
3
4
var color = [1,2];
var color1 = color.concat("yellow");
console.log(color); //1,2
console.log(color1);//1,2,'yellow'

slice方法,接收一个或两个参数,返回项的起始和结束为止,只有一个参数时,方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项。slice不会影响原来的数组

1
2
3
4
var color = [1,2,3,4,5];
var color1 = color.slice(2);
console.log(color); //1,2,3,4,5
console.log(color1);//3,4,5

1
2
3
4
var color = [1,2,3,4,5];
var color1 = color.slice(1,3);
console.log(color); //1,2,3,4,5
console.log(color1);//2,3 不包含末尾

splice方法是最强大的,
删除方法 只需指定2个参数,要删除的第一个位置和要删除的项数。

1
2
3
4
var color = [1,2,3,4,5];
var color1 = color.splice(0,2);
console.log(color); //3,4,5
console.log(color1);//1,2

返回的不是新数组,而是在原数组的基础上修改。
插入方法 起始位置,要删除的项数,和插入的项。

1
2
3
4
var color = [1,2,3,4,5];
color1 = color.splice(0,2,7,5);
console.log(color);//1,2 表示删除的2项
console.log(color1); //7,5,3,4,5

位置方法 indexOf表示从开始找起,lastIndexof表示从末尾找起
indexof有2个参数可选,array.indexOf(item,start),item必须查找的元素,start规定开始查找的元素位置
可选的整数参数。规定在数组中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。

1
2
3
4
5
6
var color = [1,2,3,3,5];
console.log(color.indexOf(3));//2
console.log(color.indexOf(3,4));//-1
console.log(color.lastIndexOf(3));//3
console.log(color.lastIndexOf(3));//3
console.log(color.lastIndexOf(3,4));//表示从数组下标4,也就是5开始找,随后找到的是数组下标3.

表示从前向后,和从后向前,但是返回的index依然是从左往右的

迭代方法
every,对数组中的每一项都运行给定的函数,如果该函数每一项都返回true,则返回true.
filter,最数组的每一项运行给定函数,返回函数true的项形成的数组
forEach,每一项运行函数,但是没有返回值。
map,每一项运行函数,返回每次函数调用的结果形成的数组
some,对数组每一项运行函数,如果函数对任一一项返回true,则返回true.
以上的方法都不会修改数组找那个的包含的值

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
var color = [1,2,3,3,5];
var every = color.every(function (item,index,array) {
return item > 2;
})
console.log(every);//false

var color = [1,2,3,3,5];
var some = color.some(function (item,index,array) {
return item > 2;
})
console.log(some);//true

var color = [1,2,3,3,5];
var filters = color.filter(function (item,index,array) {
return item > 2;
})
console.log(filters);//3,3,5

var color = [1,2,3,3,5];
var filters = color.map(function (item,index,array) {
return item * 2;
})
console.log(filters);//2,4,6,6,10

var color = [1,2,3,3,5];
var filters = color.forEach(function (item,index,array) {
console.log(item * 2);
})
console.log(filters);//undefined forEach没有返回值,因此没有filter

js基础学习

发表于 2019-03-03 | 分类于 js相关

js基础

1.标识符中可以含有字母,数字,_,$
2.标识符不能以数字开头
3.标识符不能是es中的关键字或者保留字
4.标识符采用驼峰式命名法
js底层保存标识符时实际上是采用unicode编码,
所以理论上讲,所有的utf-8中含有的内容都可以作为标识符。
中文也能当做标识符

1
var 锄禾日当午 = 789;

js中共有6种数据类型,string,number,boolean,undefined(未定义),null(空置),基本类型
object对象,引用数据类型。
转义字符,前面加\ \”表示一个双引号。\n换行 \t表示按了一下tab键。
输出斜杠\,表示斜杠。
number类型,整数和浮点数都是number类型。
typeof可以用来检查类型。

1
console.log(typeof(a));

number可以表示的最大值。

1
console.log(Number.MAX_VALUE); //科学计数法

如果表示的数字超过了最大值max_value,表示为infinity,表示正无穷。
表示一个字面量 infinity. infinity是一个number类型。
NaN是一个特殊的数字,表示一个not a number。不会算了。
a = NaN;

1
console.log(typeof a); //表示返回number.

表示0以上的最小值。

1
2
a = Number.MIN_VALUE;
console.log(a); //表示最小值 大于0的最小值 最小的正直。

如果使用js进行浮点元素加法,可能得到一个不精确的结果。

1
2
var c = 0.1 + 0.2;
console.log(c);

可能出现c后面有好几位值。
null和undefined
null类型的值只有一个,就是null

1
2
3
var a = null;
console.log(a);
console.log(type a);

null这个值专门用来表示一个为空的对象。不存在
null值是一个object类型。
undefined值只有一个,也为undefined.当声明一个变量,但是并不给变量赋值的时候,它的值就是undefined.

1
2
3
var b;
console.log(b);
console.log(typeof b); //typeof输出的时候也是为undefined.

牛客网错题笔记(1)

发表于 2019-03-03 | 分类于 js相关 , html相关 , css相关

1.问题:js加载html代码中的哪一部分,会导致页面在加载的时候自身被执行。
答案:body标签部分
解析:head标签是设计用于一些静态资源的预加载,与解析没有关系,浏览器会先加载head标签内的静态元素(css与js),这时候的js并没有被执行,而是被UI线程阻塞了,然后浏览器就开始构建DOM树,然后开始构建css dom树,(即题目中的加载页面),最后才会执行head中的js部分。
浏览器在解析body内的样式以及script标签的时候是串行的,就是说script标签内的代码会即时执行,然后再去解析下面标签的内联样式。
详细解析:在HTML body部分中的JavaScripts会在页面加载的时候被执行。
在HTML head部分中的JavaScripts会在被调用的时候才执行。
放在head中的JS代码会在页面加载完成之前就读取,而放在body中的JS代码,会在整个页面加载完成之后读取。
这就说明了,如果我们想定义一个全局对象,而这个对象是页面中的某个按钮时,我们必须将其放入body中,道理很明显:如果放入head,那当你定义的时候,那个按钮都没有被加载,可能获得的是一个undefind。
2.问题:要运用css动画,需要运用什么规则:
答案:keyframes
解析:要运用css动画,需要运用@keyframes规则和animation属性。
3.问题:自闭和标签有
答案:<br/>是换行 <hr/>是水平线 <img/>是图片文件
4.问题:嵌入在html文档中的图像格式可以是
答案:gif,bmp,jpg,png。gif和png图片格式特点体积小,bmp内存较大。
5.问题:alert(undefined == null)的输出结果是:
答案:true
解析:== 仅判断值是否相同,undefined和null是相同的,所以为true,===在判断值是否相同的同时还判断类型是否相同,undefined类型为undefined,null的类型为object,因此为false.
6.问题:js的基本数据类型有:
答案:string,boolean,number,undefined,null,es6新增了symbol.object为复合类型。
7.问题:有如下代码:

1
2
3
4
5
6
7
8
9
10
var a,b;
(function(){
alert(a);
alert(b);
var a = b = 3;
alert(a);
alert(b);
})();
alert(a);
alert(b);

输出是什么结果:
答案:undefined,undefined,3,3,undefined,3;
解析:以上代码等同于:

1
2
3
4
5
6
7
8
9
10
11
12
var a,b;//undefined
(function(){
var a;//undefined
alert(a);//undefined
alert(b);//undefined
b = 3;//3
a = b;//3
alert(a);
alert(b);
})();
alert(a);//undefined
alert(b);//3

要注意var a = b = 3的时候,a是局部变量,b是全局变量的赋值。
8.问题:number(null)上面的代码将返回:
答案:0
解析:空字符串,null,empty,0, Number([0]),N
number默认都会把他们转化成0,Number(undefined)会转换成NaN,
console.log(null == 0) 为false console.log(undefined == 0)为false
详细解析:
number的转换:
1.如果是boolean,true和false将转换成1和0
2.如果是undefined,转换成NaN,
3.如果是字符串则遵循如下规则:
a.字符串只包含数字(包含前面带正号或者负号,则将其转换成十进制数字,前导0会忽略)。011会变成11
b.字符串包含有效的浮点格式,则将其转换为相应的浮点数值,前导0会被忽略。
c。字符串包含十六进制格式,转换为相同大小的十进制数。//number(“01f”) = 31;
d.字符串是空的,转换成0,//number(“”) = 0
e.字符串包含除以上格式之外的字符,则将其转换为NaN,//number(“helloworld”) = NaN;
f.如果是数值,不用说当然返回什么
e.如果是对象,则调用对象的valueof()方法,然后依照前面的规则转换返回的值,如果转换的结果是NaN,
则调用对象的toString()方法,然后再次按照前面的规则转换返回的字符串值。
9.问题:下面的jsx语法,哪一个无法达到预期:
答案:在用class的时候,必须用className,class是js的关键字,会重复。
10.问题:js中,call和apply的描述,错误的是:
a.call和apply都属于function.prototype的一个方法。每个function都有call和apply.
b.两者传递的参数不同,call函数第一个参数都是要传入给当前的对象,apply不是。
c.apply传入的是一个参数数组,也就是将多个参数组合成一个数组传入。
d.call传入的则是直接的参数列表,call方法可将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象。
答案:b.
解析:call和apply作用相同,区别在于接收参数的方式不同,call方法中,传递给函数的参数必须逐个列举出来,使用apply方法时,传递给函数的是参数数组。

1
2
3
4
5
6
function add(c,d) {
return this.a + this.b + c + d;
}
var o = {a:1,b:2};
console.log(add.call(o,5,7));
console.log(add.apply(o,[10,20]));

转换成上下文对象。
11.问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var A = {n:4399};
var B = function () {
this.n = 9999;
}
var C = function () {
var n = 8888;
}
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++;
console.log(b.n);
console.log(c.n);

以上代码的输出是:
答案:9999 4400
解析:console.log(b.n)中,查找b.n是首先查找b对象自身是否有n属性,如果没有会去原型(prototype)上找,当执行var b = new B()时,函数内部this.n =9999(此时this指向b),所以返回的是b对象,b对象自身有n这个属性,
同理。当执行var c = new C()时,c对象没有自身的n属性,向上查找,找到原型(prototype)上的n属性,因为A.n++(所以此时对象中的n为4400)。所以返回4400.
12.问题:语句var arr = [a,b,c,d]执行后,可以得到最大值得是。
a.math.max(arr),b.math.max(arr[0],arr[1],arr[2],arr[3]),
c.math.max.call(Math,arr[0],arr[1],arr[2],arr[3])
d.math.max.apply(math,arr);
解析:math.max传入参数是任意数量的值,b是可以的,c中,call可以传入任意多个参数,d中apply第二个参数以数组的形式进行传递。
13.问题:下面哪种方式不能改变作用域链:
a.while,b.try catch,c.eval
答案:a
解析:while只在函数局部环境或者全局环境运行,并不会改变作用域链。
红皮书中提到,虽然执行环境的类型总共只有2中,全局和函数(局部),但还是有其他办法来延长作用域链的。
是因为有些语句可以在作用域链前部临时增加一个一个变量对象,该对象在代码执行完毕后会被移除,具体来说,就是执行流进入下列任何一个语句时,作用域链会加强。try catch这种的catch块,with语句。
详细解析:链接 emm 现在还看不懂
14.问题:下面代码存在几个变量没有被回收:

1
2
3
4
5
6
7
8
9
10
var i = 1;
var i = 2;
var add = function(){
var i = 0;
return function(){
i++;
console.log(i);
}
}();
add();

答案:3个。
解析:代码回收的规则如下:1。全局变量不会被回收 2。局部变量会被回收,也就是函数一旦执行完毕以后,函数内部的东西都会被销毁。3.只要被另外一个作用域引用就不会被回收。
这里有3个没有被回收。全局变量中的i,第二行会覆盖掉第一个,因此只有1个,第二个是add(),变量也不会被回收,它定义了一个匿名函数,并将它赋值给了add(),第三个就是闭包中的i,闭包中的局部变量也不会被回收,因此3个变量没有被回收。
15.问题:localStorage,sessionStorage和cookie的区别
解析:

特性 cookie localStorage sessionStorage
数据生命周期 一般由服务器生成,可设置失效时间,如果在浏览器端生成cookie,默认是浏览器关闭后消失 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除。
存放数据大小 4k左右 一般5MB 一般5MB
与服务器端通信 每次都会携带在HTTP头部中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器端)中保存,不参与和服务器的通信 仅在客户端(即浏览器端)中保存,不参与和服务器的通信
易用性 需要程序员自己封装,源生的cookie接口不友好 源生接口也可以接受,也可以自己封装,object和array有更好的支持 源生接口也可以接受,也可以自己封装,object和array有更好的支持

16.问题:下列哪个操作是W3C标准定义的阻止事件向父容器传递:
a e.preventDefault(); b e.cancelBubble = true; c c.stopPropagation(); d e.stopImmediatePropagation()
答案:c
解析:dom中的事件对象:
preventDefault(),取消事件默认行为,
stopImmediatePropagation,防止对事件流中当前节点中和后续节点中的事件侦听器处理,此方法会立即生效,并且会影响当前节点中的事件侦听器。 取消事件冒泡同时阻止当前节点上的事件处理程序被调用。

stopPropagation 防止对事件流中当前节点的后续节点中的所有事件侦听器进行处理,此方法不会影响当前节点的任何侦听事件
取消事件冒泡,对当前节点无影响。cancelBubble 取消事件冒泡。
returnValue() 取消事件默认行为。
17.问题:取得id为rapper中的全部项的集合:
答案:$(“#wrapper”).contents()
解析:$(“#wrapper”).children()//只沿着DOM树向下遍历单一层级,查询直接的子元素,而不管子元素的子元素。$(“#wrapper”).html()//返回的是dom结构,而不是集合。$(“#wrapper”).content()//返回集合。
$(“#wrapper”).find(“all”),并没有all这个元素。contents()方法获得匹配元素集合中每个元素的子节点,包括文本和注释,
find()方法获得当前元素集合中每个元素的后代,通过选择器,jquery对象或元素来筛选,html返回或设置元素内容,children()方法返回匹配元素集合中每个元素的子元素。添加可选参数可通过选择器进行过滤。
18.问题:运行以下程序:

1
2
3
4
5
6
7
8
9
10
11
<script>
var m = 1,j =k = 0;
function add(n){
return n = n + 1;
}
y = add(m);
function add(n){
return n = n + 3;
}
z = add(m);
</script>

y和z的最终结果是:
答案:4.4
解析:js里面没有函数重载的概念,在其他语言中,可以存在同名函数,只要传入的参数不同,java中可以重载。
在js中,定义了2个同名函数后,后面的函数会覆盖前面定义的函数,结合这道题,由于函数的声明会提升,所以函数的声明会提前,由于存在同名函数,所以后面的add会覆盖前面的add函数,所以两次调用add返回的值时相同的。y和z都是4
19.问题:浏览器中go(),back(),forward(),都代表什么
答案:length 返回浏览器历史记录列表中url的数量,back表示加载history列表中前一个url,forward表示加载history中下一个url,go表示加载History中的某个具体页面。
20.问题:css中的overflow属性定义:
答案:参数式scroll时,必会出现滚动条,参数式auto时,子元素内容大于父元素时出现滚动条,参数是visible时,溢出的内容出现在父元素之外,参数式hidden时,溢出隐藏。
21.问题:当margin-top,padding-top的值时百分比时,分别是如何计算的。
答案:相对最近父级块级元素的width,相对最近父级块级元素的width.
css百分比的参照问题:参照父元素宽度的元素:padding,margin,width,text-indent
参照父元素高度的元素:height 参照父元素属性:font-size,line-height,
特殊:相对定位的时候,top(bottom),left(right)参照的是父元素的内容区域的高度与宽度,而绝对定位的时候参照的是最近的定位元素包括padding的高度和宽度。
22.问题.br hr分别代表什么
解析:hr定义水平线,br定义换行,还有自闭和标签有br,hr,img,input,link
23.问题:下列事件哪个不是由鼠标触发的事件()
a.click b.contextmenu c.mouseout d.keydown
答案:d
解析:click是鼠标点击事件。contextmenu是当浏览者按下鼠标右键出现菜单时或者通过键盘的按键触发页面菜单时触发的事件,onContextMenu = “return false”可得出禁止鼠标右键的操作。
mouseout事件会在鼠标指针移除指定的对象时发生。keydown事件会在用户按下一个键盘按键时发生,由键盘触发。
24.问题:

1
2
3
4
5
6
7
8
9
10
11
function A() {
this.do = function(){
return 'foo';
};
}
A.prototype = function() {
this.do = function(){
return 'bar';
}
}
var x = new A().do();

x的值是
答案:foo
解析:首先从自己的实例对象里面去找该属性,找到了就不会再向上继续的查找。a.prototype是原型链上,所以不会查找。所以返回foo
25.

1
2
3
4
var F = function(){};
Object.prototype.a = function(){};
Function.prototype.b = function(){};
var f = new F();

关于这段代码正确的结论是:
答案:F能取到a,不能取到b.
解析:所有普通对象都源于这个object.prototype对象,只要是对象,都能访问到a,而f通过new关键词进行函数调用,之后无论如何都会返回一个与F关联的普通对象(因为不是通过函数构造创建的对象,所以不是函数对象,也就取不到b了)。
f.instanceof object 是true,f.instanceof Function是false,由此可见用new操作符创建的f只是对象,所以只能继承于object.prototype.
26.问题:新窗口打开网页,用到以下哪个值()
答案:_blank
解析:

1
<a href = "http://www.baidu.com" target = "_blank">表示打开一个新的网页。

target值 说明
_blank 在新窗口中打开被链接文档
_self 默认,在相同的框架中打开被链接的文档
_parent 在父框架集中打开被链接的文档
_top 在整个窗口中打开被链接的文档
framename 在指定的框架中打开被链接文档

27.问题:boostrap中,一个元素需要在被打印的时候隐藏的是
答案:hidden-print
解析.visible-print-block -visilbe-print-inline -visible-print-inline-block浏览器隐藏,打印机可见,.hidden-print浏览器可见,打印机隐藏

RNN基础

发表于 2019-03-02 | 分类于 深度学习相关

RNN与LSTM

中文分词,词性标注,命名实体识别,机器翻译等都是属于序列挖掘的范畴,序列挖掘的特点是某一步的输出不仅依赖于这一步的输入,还依赖于其他步的输入或输出,序列挖掘领域的机器算法有HMM(隐马尔科夫模型),和CRF(条件随机场)模型,近年来又开始流行RNN
RNN的网络结构:

比如一个句子有5个词,要给5个词做词性标注,那相应的RNN就是5层的神经网络,每一层的输入时一个词,输出就是这个词的词性,
xt是第t层的输入,它可以是一个词的one-hot向量,也可以是分布表示(distributed repressentation)向量。
st是第t层的隐藏状态,负责整个神经网络的记忆功能,st是由上一层的隐藏状态和这一层的输入来共同决定的。
st = f(Uxt + Wst-1) f通常是个非线性的激活函数,比如tanh或者relu
由于每层的st都会向后一直传递,所以理论上st能够捕获到前面每一层发生的事情。
ot是第t层的输出,比如我们预测下一个词是什么的时候,ot就是一个长度为V的向量,V是所有词的总数,ot[i]表示下一个词是wi的概率,我们用softmax函数对这些概率进行归一化,ot = softmax(Vst)
每一层的U,W,V是共享的,这样极大的缩小了参数空间。
值得注意的是**每一层并不一定都有输入和输出,隐藏单元是RNN的必备武器,比如句子进行情感分析的时候,只需要最后一层给一个输出即可。
LSTM结构:

  1. 忘记阶段。这个阶段主要是对上一个节点传进来的输入进行选择性忘记。简单来说就是会 “忘记不重要的,记住重要的”。

具体来说是通过计算得到的 z^f (f表示forget)来作为忘记门控,来控制上一个状态的 c^{t-1} 哪些需要留哪些需要忘。

  1. 选择记忆阶段,这个阶段将这个阶段的输入有选择性地进行’记忆’,主要是会对输入xt进行选择性的记忆,哪些重要的就记录下来,哪些不重要的,就不要记录下来,当前的输入内容由前面计算得到的z表示。而选择的门控信号则是由 z^i (i代表information)来进行控制。
  2. 输出阶段。这个阶段将决定哪些将会被当成当前状态的输出。主要是通过 z^o 来进行控制的。并且还对上一阶段得到的 c^o 进行了放缩(通过一个tanh激活函数进行变化)。

与普通RNN类似,输出 y^t 往往最终也是通过 h^t 变化得到。
主要就是忘记阶段,将前面的哪些部分进行遗忘,记忆阶段,将现阶段的哪些部分进行记录,输出部分,这个阶段决定哪些将会被当成当前状态进行输出。
知乎上链接为https://zhuanlan.zhihu.com/p/32085405

CNN基础

发表于 2019-02-28 | 分类于 深度学习相关

CNN由输入和输出层以及多个隐藏层组成,隐藏层可分为卷积,池化,relu层和全连接层。
输入层:
CNN的输入一般是二维向量,可以有高度,比如RGB图像。
卷积层:
卷积层是CNN的核心,层的参数由一组可学习的滤波器(filter)或内核(kernels)组成,
每个滤波器对输入进行卷积,计算滤波器和输入之间的点积,并产生该滤波器的二维激活图(输入一般二维向量,但可能有高度(即RGB))。 简单来说,卷积层是用来对输入层进行卷积,提取更高层次的特征。
池化层:
又称为采样层,它的作用是减小数据处理量同时保留有用信息,
通常池化层是每邻域四个像素中的最大值变为一个像素(这就是下一讲要降的max_pooling),为什么可以这么做呢?这是因为卷积已经提取出特征,相邻区域的特征是类似,近乎不变,这时池化只是选出最能表征特征的像素,缩减了数据量,同时保留了特征,何乐而不为呢?池化层的作用可以描述为模糊图像,丢掉了一些不是那么重要的特征.

RELU层
这个RELU我们之前讲过,全名将修正线性单元,是神经元的激活函数,对输入值x的作用是max(0,x),当然RELU只是一种选择,还有选Leak-Relu等等,一般都是用Relu!
全连接层
这个层就是一个常规的神经网络,它的作用是对经过多次卷积层和多次池化层所得出来的高级特征进行全连接(全连接就是常规神经网络的性质),算出最后的预测值。
2.6 输出层
输出层就不用介绍了,就是对结果的预测值,一般会加一个softmax层。

深度学习-基本概念(1)

发表于 2019-02-28 | 分类于 深度学习相关

过拟合与欠拟合

欠拟合指的是模型不能在训练集上获得足够低的训练误差。
过拟合指的是训练误差和测试误差(泛化误差)的差距比较大。
在评价指标上,就是模型在训练集上表现比较好,但是在测试集或者新数据上则表现比较差。

减少测试误差(泛化误差,过拟合)的方法统称为正则化,这些方法以增大训练误差为代价。
降低模型复杂度:
1.神经网络:减少网络层,神经元个数
决策树:降低树的深度,剪枝。
权重约束:
L1,L2正则化。
集成学习:
神经网络:Dropout
决策树:随机森林,GBDT。

反向传播算法

概述:梯度下降法需要利用损失函数对所有参数的梯度来寻找局部最小值。
反向传播算法就是用于计算该梯度的具体方法,其本质是利用链式法则对每个参数求偏导。

激活函数

使用激活函数的目的是为了向网络中加入非线性因素,加强网络的表示能力,解决线性模型无法解决的问题。
整流线性单元 ReLU
RELU 通常是激活函数较好的默认选择

sigmoid与tanh激活函数

relu的优势
1.避免梯度消失 2.减缓过拟合 3.加速计算

正则化(Batch Normalization 批标准化)

BN是一种正则化方法(减少泛化误差),
加速网络的训练,防止过拟合,降低了参数初始化的要求。
动机
训练的本质是学习数据分布,如果训练数据和测试数据的分布不同会降低模型的泛化能力,因此,在开始训练前要对所有输入数据做归一化处理,其实质是让他们分布在同一个区间上,例如(-1,1)内
基本原理:
BN 方法会针对每一批数据,在网络的每一层输入之前增加归一化处理,使输入的均值为 0,标准差为 1。目的是将数据限制在统一的分布下。

BN也可以看做在各层之间加入了一个新的计算层,对数据分布进行额外的约束,从而增强模型的泛化能力。
L1/L2范数正则化
作用:限制模型的学习能力-通过限制参数的规模,使模型偏好于权重比较小的目标函数,防止过拟合
不同点

L1 正则化可以产生更稀疏的权值矩阵,可以用于特征选择,同时一定程度上防止过拟合;L2 正则化主要用于防止模型过拟合
L1 正则化适用于特征之间有关联的情况;L2 正则化适用于特征之间没有关联的情况。
L1/L2正则化优点
L1 & L2 正则化会使模型偏好于更小的权值。
更小的权值意味着更低的模型复杂度;添加 L1 & L2 正则化相当于为模型添加了某种先验,限制了参数的分布,从而降低了模型的复杂度。
模型的复杂度降低,意味着模型对于噪声与异常点的抗干扰性的能力增强,从而提高模型的泛化能力。——直观来说,就是对训练数据的拟合刚刚好,不会过分拟合训练数据(比如异常点,噪声)——奥卡姆剃刀原理

nlp基础描述

发表于 2019-02-27 | 分类于 nlp相关

解决nlp问题的一般思路

这个问题人类可以做好吗?

  • 可以 -> 记录自己的思路 -> 设计流程让机器完成你的思路
  • 很难 -> 尝试从计算机的角度来思考问题

    nlp的历史进程

    1.正则表达式/自动机
    2.规则是固定的
    搜索引擎
    xx 用英语怎么说? -> translate(XX,english);
    我饿死了 -> recommend(饭店,地址);

可以用概率系统
一般的工作方式
预处理 -> 特征工程 -> 分类器(机器学习的算法) -> 预测
最重要的部分:数据收集,预处理和特征工程
任务:
“豆瓣酱用英语怎么说” => translate(豆瓣酱,Eng)

流程设计(序列标注):
子任务1: 找出目标语言 “豆瓣酱用 英语 怎么说”
子任务2: 找出翻译目标 “ 豆瓣酱 用英语怎么说”

收集训练数据:
(子任务1)
“豆瓣酱用英语怎么说”
“茄子用英语怎么说”
“黄瓜怎么翻译成英语”

预处理:
分词:“豆瓣酱 用 英语 怎么说”

抽取特征:
(前后各一个词)
0 茄子: < _ 用
0 用: 豆瓣酱 _ 英语
1 英语: 用 _ 怎么说
0 怎么说: 英语 _ >

分类器:
SVM/CRF/HMM/RNN

预测:
0.1 茄子: < _ 用
0.1 用: 豆瓣酱 _ 英语
0.7 英语: 用 _ 怎么说
0.1 怎么说: 英语 _ >

评价:
准确率
大部分自然语言问题都可以使用seq2seq模型来解决

seq2seq的模型将在后面进行介绍

评价机制

在信息论中,perplexity用于度量一个概率分布或概率模型预测样本的好坏程度
各种数学公式 在这里不做展开
机器翻译的评价指标-BLEU

语言模型
如果能使用某个方法对XX打分(Score),那么就可以把这个方法称之为XX模型。
例如篮球明星模型:Score(库里),Score(詹姆斯)
话题模型-对一段话是否在谈论某一个话题打分
Score(NLP | “什么是语言模型?”) –> 0.8
Score(ACM | “什么是语言模型?”) –> 0.05

可用的概率语言模型
统计语言模型实际上是一个概率模型,所以常见的概率模型通常用于求这些参数
常见的概率模型有:N-gram模型,决策时,最大熵模型,隐马尔科夫模型,条件随机场,神经网络
目前常用于语言模型的是 N-gram 模型和神经语言模型(下面介绍)

专题-句嵌入

基于统计的词袋模型(Bow)
单个词的One-Hot表示
基于频数的词袋模型
基于TF-IDF的词袋模型

词向量

词向量:是一个固定长度的实值向量
词向量是神经语言模型的副产品
词向量是针对”词”提出的,事实上,也可以针对更细或者更广的粗度来进行推广——比如字向量、句向量、文档向量等
nlp任务中,机器无法直接理解自然语言问题,所以首先要做的就是将语言数学化,词向量就是一种将自然语言数学化的方法。**将词转化成稠密向量,并且对于相似的词,其对应的词向量也相对接近。
word2vec提供了2套模型 CBOW和skip-gram模型
CBOW:在已知context(w)的情况下,预测w
SKIP_GRAM模型:在已知w的情况下预测context(w)

词的表示

词的表示通常有2种表示方法 one-hot representation和distribution representation。
1.1离散表示(one-hot representation)
传统的基于规则或基于统计的自然语义处理方法将单词看作一个原子符号
one-hot representation把每个词表示成一个长向量,这个向量的维度是词表的大小,向量中只有一个维度为1,其余的维度为0,这个维度就代表了当前的词。
例如:苹果:苹果 [0,0,0,1,0,0,0,0,0,……]
one-hot representation相当于给每个词分配一个id,这就导致这种表示方式不能展示词与词之间的关系。另外,one-hot representation将会导致特征空间非常大,但也带来一个好处,就是在高维空间中,很多应用任务线性可分。
1.2 分布式表示(distribution representation)
词转化成一种分布式表示,又称词向量。分布式表示将词表示成一个定长的连续的稠密向量。
分布式表示优点:
(1)词之间存在相似关系:
是词之间存在“距离”概念,这对很多自然语言处理的任务非常有帮助。
(2)包含更多信息:
词向量能够包含更多信息,并且每一维都有特定的含义。在采用one-hot特征时,可以对特征向量进行删减,词向量则不能。
生成词向量:任何一个词的含义都可以用它的周边词来进行表示。方式有基于统计的方法和基于语言模型的方法。
CBOW模型是预测上下文已知的情况下,当前词出现的概率。上下文的选取采用窗口方式,即只将当前词窗口范围内的词作为上下文。中心词概率公式如下:
P(wt|wt-k,wt-(k-1)…,wt-1,wt+1,wt+2…,wt+k)= P(wt|context)
CBOW采用了一种层次化softmax技术,利用哈夫曼树对词表进行分类,用一连串的二分类来表示多分类。
参考链接
词向量使用

react-redux学习(1)

发表于 2019-02-23 | 分类于 js相关

redux简介

react组件间的通信往往只能是子组件和父组件之间的通信,如果一个子组件要与和父组件同级的其他组件的子组件通信。通俗意义上说是子组件与自己的堂兄弟通信,那么就要通过父组件通信等,较麻烦,而redux的出现就是为了解决这个,将数据全部放在redux中,react只负责渲染,这样,组件只需要改变redux中的数据,其余组件便能够得到响应。如下图所示

以前facebook也出过一个数据层框架名为flux,实际上redux = reducer + flux 来进行辅助编程和扩展

redux工作流程

redux的整体工作流程如下

我们可以进行这样的想象,把整个流程看做一个借书的管理过程
react component是借书的用户,当他要借书的时候,通过action creatures来说一句话,来创建动作,随后store便是一个图书馆,他接收到action说以后,自己不能执行,便通过reducer,reducer相当于一个图书管理员,通过他进行图书的登记借阅和归还等操作。

redux的实现

通过npm install redux –save-dev来加载redux库,随后创建store文件夹,在下面创建index.js函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { createStore,applyMiddleware,compose } from 'redux';
//applyMiddleware表示可以使用中间件
import thunk from 'redux-thunk';
//引入reducer
import reducer from './reducer';
//创建公共存储仓库 使用redux-dev-tools
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
}) : compose;
//使用thunk中间件
const enhancer = composeEnhancers(
applyMiddleware(thunk),
// other store enhancers if any
);

const store = createStore(reducer,
enhancer
);

export default store;

这里我们使用了redux的调试工具和redux-thunk的中间件,实际上thunk这个中间件工作在action和store之间。
随后再component组件文件中导入
通过reducer.js文件引入默认的state

1
2
3
4
5
6
7
//state指的是我整个图书馆书籍信息,仓库数据
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM,INIT_LIST_DATA} from './actionTypes';
const defaultState = {
inputValue:'',
list:[]

};

1
import store from './store/index';

比如input输入框中,当input内容发生改变,自动更新state,就需要创建action,这里已经进行了封装
actionCreators.js函数是用来创建动作的
actionTypes.js函数是用来定义每个动作的类型的,如下

1
2
3
4
5
//actionTypes.js文件
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
export const INIT_LIST_DATA = 'init_list_data';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//actionCreators.js文件
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM,INIT_LIST_DATA} from "./actionTypes";
import axios from 'axios';
export const getInputChangeAction = (value) => ({
type:CHANGE_INPUT_VALUE,
value
});
export const getAddItemAction = () => ({
type:ADD_TODO_ITEM

});
export const getDeleteTodoItem = (index) => ({
type:DELETE_TODO_ITEM,
index

});
1
2
const action = getAddItemAction();
store.dispatch(action);

随后通过store的dispatch方法来通知store
随后在reducer文件中便可以进行修改。通过传递过来的先前的state和最新的action,要注意不能修改state,只能通过拷贝state产生的拷贝对象后,通过修改拷贝对象的值,再返回拷贝对象,便可以反馈给store,store自动进行修改。

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
32
33
34
35
36
37
38
39
40
//reducer必须返回函数 负责数据的存储 reducer必须是纯函数 纯函数指的是
//给定固定的输入 就一定会有固定的输出 而且不会有任何的副作用 例如new Date等就根据时间来了 不能改变state
export default (state = defaultState,action) => {
//将上一次的state和action都传递过来


if(action.type === CHANGE_INPUT_VALUE){
//reducer的原则 可以接受state 但是不能改变state
//将之前的state进行深拷贝 然后将newState改变
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState; //替换数据
}
if(action.type === ADD_TODO_ITEM){
//reducer的原则 可以接受state 但是不能改变state
//将之前的state进行深拷贝 然后将newState改变 将inputValue拿来
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState; //替换数据
}
if(action.type === DELETE_TODO_ITEM){

//reducer的原则 可以接受state 但是不能改变state
//将之前的state进行深拷贝 然后将newState改变 将inputValue拿来
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index,1);
return newState; //替换数据
}
if(action.type === INIT_LIST_DATA){

//reducer的原则 可以接受state 但是不能改变state
//将之前的state进行深拷贝 然后将newState改变 将inputValue拿来
const newState = JSON.parse(JSON.stringify(state));
newState.list = action.data;
return newState; //替换数据
}
return state;

}

这样store便可以自动进行更新和修改。
在component中,通过store.getState()方法可以获取store内的值,赋值给每个component的自身state

1
this.state = store.getState();

通过store.subscribe订阅store,在函数体中实现方法,当store更新后,自动更新state的值

1
store.subscribe(this.handleStoreChange);

handlStoreChange的实现

1
2
3
console.log("store change");
//进行替换state
this.setState(store.getState());

通过setState的方法来更新state。
整体的流程大致如上。

boostrap学习(1)

发表于 2019-02-03 | 分类于 html相关

boostrap的基本使用

boostrap网页的基本使用html如下

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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>Bootstrap 101 Template</title>

<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
<!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>你好,世界!</h1>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
</body>
</html>

boostrap使用到的某些html和css属性需要将页面设置为html5的文档类型,
所以需添加如下代码

1
2
3
4
<!DOCTYPE html>
<html lang="zh-CN">
...
</html>

移动设备优先
确保适当的绘制和触屏缩放,需要在中添加viewport元数据标签

1
<meta name="viewport" content="width=device-width, initial-scale=1">

在移动设备浏览器上,通过为视口(viewport)设置 meta 属性为 user-scalable=no 可以禁用其缩放(zooming)功能。这样禁用缩放功能后,用户只能滚动屏幕,就能让你的网站看上去更像原生应用的感觉。注意,这种方式我们并不推荐所有网站使用,还是要看你自己的情况而定!

布局容器

boostrap需要为页面内容和栅格系统包裹一个.container容器,为此,我们提供了2个作用于此处的类,注意,由于padding等属性的原因,这两种容器不能互相的嵌套。
.container类用于固定宽度并且支持响应式布局的容器

1
2
3
<div class="container">
...
</div>

.container-fluid类用于100%宽度,占据全部视口(viewport)的容器

1
2
3
<div class="container-fluid">
...
</div>

栅格系统

提供了一套响应式,移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会最多分配为12列。
栅格同通过一系列的行(row)和列(column)来创建页面布局,你的内容会放入这些创建好的布局里。
1.行(row)必须包含在.container(固定宽度)或(.container-fluid)中
2.通过“行(row)”在水平方向创建一组“列(column)”。
3.你的内容应当放置于“列(column)”内,并且,只有“列(column)”可以作为行(row)”的直接子元素。
col-xs,col-sm,col-md和col-lg的定义如下。

表格

col-xs col-sm col-md col-lg
超小屏幕手机(<768px) 小屏幕平板(>=768px) 中等屏幕桌面显示器(>=992px) 大屏幕大桌面显示器(>=1200px)

注意:当屏幕宽度在某一个宽度值以内的时候,某个class属性会起作用,而其余的则会失效
例子
.c0l-xs-  无论屏幕宽度如何,单元格都在一行,宽度按照百分比设置;试用于手机;
.col-sm-  屏幕大于768px时,单元格在一行显示;屏幕小于768px时,独占一行;试用于平板;
.col-md-  屏幕大于992px时,单元格在一行显示;屏幕小于992px时,独占一行;试用于桌面显示器;
.col-lg-  屏幕大于1200px时,单元格在一行显示;屏幕小于1200px时,独占一行;适用于大型桌面显示器;

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

<div class="row">
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
<div class="col-md-1">.col-md-1</div>
</div>
<div class="row">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
</div>
<div class="row">
<div class="col-md-6">.col-md-6</div>
<div class="col-md-6">.col-md-6</div>
</div>

由于没有定义lg属性,因此在大于992px的时候,容器会水平排列,按照栅格系统的分列,而在小于992px的时候,则会排列成竖直型

1
2
3
4
5
6
7
<div class="row">
<div class="col-sm-3 col-xs-12">1</div>
<div class="col-sm-3 col-xs-12">2</div>
<div class="col-sm-3 col-xs-12">3</div>
<div class="col-sm-3 col-xs-12">4</div>

</div>

如上所示,在大于768px的时候,是水平排列的,在小于768px的时候,则会竖直排列。

1
2
3
4
5
6
7
8
9
10
11
<div class="container">
  <div class="row">
    <div class="col-xs-12 col-sm-6 col-md-8">.col-xs-12 .col-sm-6 .col-md-8</div>
    <div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
  </div>
  <div class="row">
    <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
    <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
    <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
  </div>
</div>

屏幕大于992px的时,col-md-8和col-md4还处于作用范围内。
屏幕在769px~992px时,col-md失效,col-sm还处于作用范围内。
屏幕小于768px的时候,col-sm失效,col-xs还处于作用范围内。

1…456
KevinSwift

KevinSwift

58 日志
28 分类
64 标签
© 2020 KevinSwift
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4