原文链接:征服前端面试,仅供学习使用
前端知识集锦2
1. JavaScript
1.1 原型
我们创建的每一个函数,都可以有一个prototype属性,该属性指向一个对象。这个对象,就是原型。
当我们在创建对象时,可以根据自己的需求,选择性的将一些属性和方法通过prototype属性,挂载在原型对象上。而每一个new出来的实例,都有一个proto属性,该属性指向构造函数的原型对象,通过这个属性,让实例对象也能够访问原型对象上的方法。因此,当所有的实例都能够通过proto访问到原型对象时,原型对象的方法与属性就变成了共有方法与属性。
// 声明构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 通过prototye属性,将方法挂载到原型对象上
Person.prototype.getName = function() {
return this.name;
}
var p1 = new Person('tim', 10);
var p2 = new Person('jak', 22);
console.log(p1.getName === p2.getName); // true
通过图示我们可以看出,构造函数的prototype与所有实例对象的proto都指向原型对象。而原型对象的constructor指向构造函数。
1.2 原型链
我们知道所有的函数都有一个叫做toString的方法。那么这个方法到底是在哪里的呢?
先随意声明一个函数:
function foo() {}
其中foo是Function对象的实例。而Function的原型对象同时又是Object的实例。这样就构成了一条原型链。原型链的访问,其实跟作用域链有很大的相似之处,他们都是一次单向的查找过程。因此实例对象能够通过原型链,访问到处于原型链上对象的所有属性与方法。这也是foo最终能够访问到处于Object原型对象上的toString方法的原因。
1.3 作用域链
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。
1.4 闭包
- 第一种理解(红宝书):是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量。
- 第二种理解(你不知道的javascript):当函数可以记住并访问所在的词法作用域时,就产生了闭包,这个函数持有对该词法作用域的引用,这个引用就叫做闭包。
- 闭包本质还是函数,只不过这个函数绑定了上下文环境(函数内部引用的所有变量)。
缺点:常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
作用(使用场景):可以用来管理私有变量和私有方法,将对变量(状态)的变化封装在安全的环境中,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。
闭包有三个特性:
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
题外话
:
- JavaScript的作用域就是词法作用域而不是动态作用域;
- 词法作用域最重要的特征是它的定义过程发生在代码的书写阶段;
- 动态作用域的作用域链是基于调用栈的 词法作用域的作用域链是基于代码中的作用域嵌套。
1.4 this
JavaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。
this的指向:
- 作为普通函数调用(this指向全局对象window对象)
- 作为对象的方法调用(this指向该对象)
- 构造器调用(this指向用new返回的这个对象)
- call、apply、bind的调用(this指向第一个参数对象)
1.5 高阶函数
- 函数作为参数传递
- 函数作为返回值输出
1.6 new操作符具体干了什么呢?
- 创建一个新对象;
- 将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
- 执行构造函数中的代码(为这个新对象添加属性)
- 返回新对象
1.7 继承
简单原型链继承:
function Super(){
this.name = 'hzzly';
}
function Sub(){
// ...
}
Sub.prototype = new Super(); // 核心
缺点:
修改sub1.name后sub2.name也变了,因为来自原型对象的引用属性是所有实例共享的。
构造函数式继承:
function Super(val){
this.val = val;
this.fun = function(){ // 实例函数
// ...
}
}
function Sub(val){
Super.call(this, val); // 核心
// ...
}
缺点:
无法实现函数复用,每个子类实例都持有一个新的fun函数,太多了就会影响性能,内存爆炸。
组合式继承
function Super(){
this.name = 'hzzly';
}
// 原型函数
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
Super.call(this); // 核心
// ...
}
Sub.prototype = new Super(); // 核心
缺点:
子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上父类的。又是内存浪费。
寄生组合式继承
function Super(){
this.name = 'hzzly';
}
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};
//Super.prototype.fun3...
function Sub(){
Super.call(this); // 核心
// ...
}
Sub.prototype=Object.create(Super.prototype) // 核心
Sub.prototype.constructor=Sub // 核心
es6的class继承方式
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
es6引入了class
、extends
、super
、static
(部分为ES2016标准)
1.8 null和undefined的区别?
- null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。
- undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。
- null表示”没有对象”,即该处不应该有值。
1.9 call、apply、bind的区别
- 三者都是用来改变函数的this对象的指向的。
- 三者第一个参数都是this要指向的对象,也就是想指定的上下文。
- call 传入的参数数量不固定,第二部分参数要一个一个传,用,隔开。
- apply 接受两个参数,第二个参数为一个带下标的集合,可以为数组,也可以为类数组。
- bind 是返回一个改变了上下文的函数副本,便于稍后调用;apply 、call 则是立即调用。
1.10 本地存储
- sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
- localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
1.11 cookie 和session
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。每次请求一个新的页面的时候Cookie都会被发送过去,与服务器进行交互。
1.12 XML和JSON的区别?
- 数据体积方面:JSON相对于XML来讲,数据的体积小,传递的速度更快些。
- 列表项目:JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
- 数据描述方面:JSON对数据的描述性比XML较差。
- 传输速度方面:JSON的速度要远远快于XML。
1.13 如何实现浏览器内多个标签页之间的通信?
调用localstorge、cookies等本地存储方式
1.14 线程与进程的区别
- 一个程序至少有一个进程,一个进程至少有一个线程。
- 线程的划分尺度小于进程,使得多线程程序的并发性高。
- 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
- 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
1.15 渐进增强和优雅降级
- 渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
- 优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
1.16 性能优化
-
网页内容
- 减少 http请求次数
- 减少 DNS查询次数
- 避免页面跳转
- 缓存 Ajax
- 延迟加载
- 提前加载
- 减少 DOM元素数量
- 避免 404
-
服务器
- 使用CDN(内容分发网络)
- 添加Expires或Cache-Control报文头
- Gzip压缩传输文件
-
CSS
- 将样式表置顶
- 用代替@import
-
JavaScript
- 把脚本置于页面底部
- 使用外部JavaScript和CSS
- 精简JavaScript和CSS
- 去除重复脚本
- 减少DOM访问
-
图片
- 优化图像
- 优化CSS Spirite
- 不要在HTML中缩放图片
- favicon.ico要小而且可缓存
1.17 如何解决跨域问题?
- jsonp
- CORS
- document.domain+iframe
- window.name
- window.postMessage
- jsonp的原理是动态插入script标签
1.18 请解释一下 JavaScript 的同源策略。
这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。
指一段脚本只能读取来自同一来源的窗口和文档的属性。
1.19 哪些操作会造成内存泄漏?
- 内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
- 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
1.20 Javascript垃圾回收方法
- 标记清除:这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
- 引用计数:引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
1.21 事件、IE与火狐的事件机制有什么区别? 如何阻止冒泡?
事件处理机制:IE是事件冒泡、firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件。
阻止冒泡:ev.stopPropagation()
1.22 说说严格模式的限制
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 禁止this指向全局对象
- 不能使用with语句
- 增加了保留字
- arguments不会自动反映函数参数的变化
设立”严格模式”的目的:
- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
1.23 请解释什么是事件代理
事件代理(Event Delegation),又称之为事件委托。即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能。
1.24 Event Loop、消息队列、事件轮询
异步函数在执行结束后,会在事件队列中添加一个事件(回调函数)(遵循先进先出原则),主线程中的代码执行完毕后(即一次循环结束),下一次循环开始就在事件队列中“读取”事件,然后调用它所对应的回调函数。这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
主线程运行的时候,产生堆(heap)
和栈(stack)
,栈中的代码(同步任务)调用各种外部API,它们在”任务队列”中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取”任务队列”,依次执行那些事件所对应的回调函数。
执行栈中的代码(同步任务),总是在读取”任务队列”(异步任务)之前执行。
1.25 缓存
浏览器缓存(Browser Caching)是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据。
- http缓存:http缓存是基于HTTP协议的浏览器文件级缓存机制。即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从本地读取文件判断expires,如果未过期,直接读取http缓存文件
- indexDB:是一个在客户端存储可观数量的结构化数据,并且为这些数据添加索引进行高性能检索。
- cookie:指一般网站为了辨别用户身份、储存在用户本地终端上的数据(通常经过加密)。cookie一般通过http请求中在头部一起发送到服务器端。一条cookie记录主要由键、值、域、过期时间、大小组成,一般用户保存用户的认证信息。
- localstorage:localStorage是h5的一种新的本地缓存方案,加快下次页面打开时的渲染速度,除非主动删除数据,否则数据是永远不会过期的。
- sessionstorage:也是h5的一种本地缓存方案,数据的存储仅特定于某个会话中,也就是说数据只保持到浏览器关闭,当浏览器关闭后重新打开这个页面时, 之前的存储已经被清除。
2. ES6
2.1 ES6的了解
es6是一个新的标准,它包含了许多新的语言特性和库,是JS最实质性的一次升级。比如’箭头函数’、’字符串模板’、’generators(生成器)’、’async/await’、’解构赋值’、’class’等等,还有就是引入module模块的概念。 箭头函数
可以让this指向固定化,这种特性很有利于封装回调函数。
(1) 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2) 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3) 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
(4) 不可以使用yield命令,因此箭头函数不能用作Generator函数。
- async/await是写异步代码的新方式,以前的方法有回调函数和Promise。
- async/await是基于Promise实现的,它不能用于普通的回调函数。
- async/await与Promise一样,是非阻塞的。
- async/await使得异步代码看起来像同步代码,这正是它的魔力所在。
2.2 说说你对Promise的理解
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件监听——更合理和更强大。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
Promise对象有以下两个特点:
- 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。
2.3 说说你对AMD和Commonjs的理解
CommonJS是服务器端模块的规范,Node.js采用了这个规范。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。
AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对module.exports或exports的属性赋值来达到暴露模块对象的目的。
3. Gulp、Webpack比较
3.1 Gulp
- Gulp就是为了规范前端开发流程,实现前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等功能的一个前端自动化构建工具。
- Gulp就像是一个产品的流水线,整个产品从无到有,都要受流水线的控制,在流水线上我们可以对产品进行管理。
- Gulp是通过task对整个开发过程进行构建。
3.2 Webpack
- 当下最热门的前端资源模块化管理和打包工具
- 可以很好的管理模块以及各个模块之间的依赖
- 对js、css、图片等资源文件都支持打包
- 有独立的配置文件webpack.config.js
- 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间
- 可以生成优化且合并后的静态资源
两大特色:
- 代码可以自动完成编译
- loader 可以处理各种类型的静态文件,并且支持串联操作
4. CSS
4.1 display:none和visibility:hidden的区别?
display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。
visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。
4.2 position:absolute和float属性的异同
A:共同点:
对内联元素设置float
和absolute
属性,可以让元素脱离文档流,并且可以设置其宽高。
B:不同点:
float仍会占据位置,position会覆盖文档流中的其他元素。
4.3 box-sizing属性
- content-box:让元素维持W3C的标准盒模型。元素的宽度/高度由border + padding + content的宽度/高度决定,设置width/height属性指的是content部分的宽/高,一旦修改了元素的边框或内距,就会影响元素的盒子尺寸,就不得不重新计算元素的盒子尺寸,从而影响整个页面的布局。
- border-box:让元素维持IE传统盒模型(IE6以下版本和IE6~7的怪异模式)。设置width/height属性指的是border + padding + content
4.4 position的值
- static 默认值。没有定位,元素出现在正常的流中。
- relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。
- absolute 生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。
- fixed (老IE不支持)生成绝对定位的元素,相对于浏览器窗口进行定位。
4.5 解释下浮动和它的工作原理?清除浮动的技巧
浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。
- 使用空标签清除浮动:这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。
- 使用overflow:设置overflow为hidden或者auto,给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1; zoom:1用于兼容IE6。
- 使用after伪对象清除浮动:该方法只适用于非IE浏览器。该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素。
#box:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
}
4.6 浮动元素引起的问题
- 父元素的高度无法被撑开,影响与父元素同级的元素
- 与浮动元素同级的非浮动元素(内联元素)会跟随其后
- 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构
5. CSS3新特性
- CSS3实现圆角(border-radius)
- 阴影(box-shadow)
- 对文字加特效(text-shadow、)
- 线性渐变(gradient)
- 旋转(transform)
- transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);//旋转,缩放,定位,倾斜
- 增加了更多的CSS选择器
- 多背景
- rgba
- 在CSS3中唯一引入的伪元素是::selection.
- 媒体查询
- 多栏布局
- border-image
6. CSS sprites
CSS Sprites 其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。这样可以减少很多图片请求的开销,因为请求耗时比较长;请求虽然可以并发,但是也有限制,一般浏览器都是6个。对于未来而言,就不需要这样做了,因为有了http2。
7. HTML
7.1 说说你对语义化的理解
- 去掉或者丢失样式的时候能够让页面呈现出清晰的结构;
- 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
- 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
- 便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化。
7.2 Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
-
<!DOCTYPE>
告知浏览器的解析器用什么文档标准解析这个文档。 - 严格模式的排版和 JS 运作模式是以该浏览器支持的最高标准运行。
- 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
-
<!DOCTYPE>
不存在或格式不正确会导致文档以混杂模式呈现。
7.3 你知道多少种Doctype文档类型?
该标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。
HTML 4.01 规定了三种文档类型:Strict、Transitional 以及 Frameset。
XHTML 1.0 规定了三种 XML 文档类型:Strict、Transitional 以及 Frameset。
Standards (标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页,而 Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。
7.4 HTML与XHTML——二者有什么区别
- 所有的标记都必须要有一个相应的结束标记;
- 所有标签的元素和属性的名字都必须使用小写;
- 所有的XML标记都必须合理嵌套;
- 所有的属性必须用引号””括起来;
- 把所有<和&特殊符号用编码表示;
- 给所有属性赋一个值;
- 不要在注释内容中使“–”;
- 图片必须有说明文字。
7.5 html5有哪些新特性
- 语义化更好的内容标签(header,nav,footer,aside,article,section)
- 音频、视频API(audio,video)
- 画布(Canvas) API
- 地理(Geolocation) API
- 拖拽释放(Drag and drop) API
- 本地离线存储
- 表单控件,calendar、date、time、email、url、search
8. 计算机网络
8.1 HTTP请求四部分
- HTTP请求的方法或动作,比如是get还是post请求;
- 正在请求的URL(请求的地址);
- 请求头,包含一些客户端环境信息、身份验证信息等;
- 请求体(请求正文),可以包含客户提交的查询字符串信息、表单信息等。
8.2 请求头字段:
- Accept:text/html,image/*(告诉服务器,浏览器可以接受文本,网页图片)
- Accept-Charaset:ISO-8859-1 [接受字符编码:iso-8859-1]
- Accept-Encoding:gzip,compress[可以接受 gzip,compress压缩后数据]
- Accept-Language:zh-cn[浏览器支持的语言]
- Host:localhost:8080[浏览器要找的主机]
- If-Modified-Since:Tue, 09 May 2017 01:34:02 GMT[告诉服务器我这缓存中有这个文件,该文件的时间是…]
- User-Agent:Nozilla/4.0(Com…)[告诉服务器我的浏览器内核,客户端环境信]
- Cookie:[身份验证信息]
- Connection:close/Keep-Alive [保持链接,发完数据后,我不关闭链接]
8.3 HTTP响应三部分
(1) 一个数字和文字组成的状态码,用来显示请求是成功还是失败;
(2) 响应头,响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等;
(3) 响应体(响应正文)。
响应头字段:
- Cache-Control:[告诉浏览器如何缓存页面(因为浏览器的兼容性最好设置两个)]
- Connection:close/Keep-Alive [保持链接,发完数据后,我不关闭链接]
- Content-Type:text/html;charset=gb2312[内容格式和编码]
- Last-Modified:Tue,11 Juj,2017 18 18:29:20[告诉浏览器该资源上次更新时间是多少]
- ETag:”540-54f0d59b8b680”
- Expires:Fri, 26 May 2017 13:28:33 GMT [失效日期]
- server:apache tomcat nginx [哪种服务器]
8.4 说说TCP传输的三次握手
第一次握手,客户端给服务器发送数据包(带SYN标志的数据包
)。此时服务器确认自己可以接收客户端的包,而客户端不确认服务器是否接收到了自己发的数据包。
第二次握手,服务器端回复(回传一个带有SYN/ACK标志的数据包以示传达确认信息
)客户端。此时客户端确认自己发的包被服务器收到,也确认自己可以正常接收服务器包,客户端对此次通信没有疑问了。服务器也可以确认自己能接收到客户端的包,但不能确认客户端能否接收自己发的包。
第三次握手,客户端回复(发送端再回传一个带ACK标志的数据包,代表“握手”结束
)服务器。 客户端已经没有疑问了,服务器也确认刚刚客户端收到了自己的数据包。两边都没有问题,开始通信。
为什么要三次握手:
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。也防止了服务器端的一直等待而浪费资源;
TCP作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高传输的效率,而用三次恰恰可以满足以上两方面的需求!
8.5 四次挥手
- 主机向服务器发送一个断开连接的请求( 不早了,我该走了 ),
发送一个FIN报文段
; - 服务器接到请求后发送确认收到请求的信号( 知道了 )
回一个ACK报文段
; - 服务器向主机发送断开通知( 我也该走了 )
发送FIN报文段,请求关闭连接
; - 主机接到断开通知后断开连接并反馈一个确认信号( 嗯,好的 ),服务器收到确认信号后也断开连接;
8.6 TCP和UDP的区别
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!
UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。
8.7 HTTP和HTTPS
- HTTP协议通常承载于TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS
- 默认HTTP的端口号为80,HTTPS的端口号为443
HTTPS 相对于 HTTP 性能上差点,因为多了 SSL/TLS 的几次握手和加密解密的运算处理,但是加密解密的运算处理已经可以通过特有的硬件来加速处理。
8.8 什么是Etag?
把Last-Modified和ETag请求的http报头一起使用,可利用客户端(例如浏览器)的缓存。ETag用于标识资源的状态,当资源发生变更时,如果其头信息中一个或者多个发生变化,或者消息实体发生变化,那么ETag也随之发生变化。浏览器下载组件的时候,会将它们存储到浏览器缓存中。如果需要再次获取相同的组件,浏览器将检查组件的缓存时间,假如已经过期,那么浏览器将发送一个条件GET请求到服务器,服务器判断缓存还有效,则发送一个304响应,告诉浏览器可以重用缓存组件。
8.9 Expires和Cache-Control
Expires
用来控制缓存的失效日期Cache-Control
用来控制网页的缓存 常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
8.10 关于Http 2.0 你知道多少?
- HTTP/2引入了“服务端推(server push)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。
- HTTP/2提供更多的加密支持
- HTTP/2使用多路技术,允许多个消息在一个连接上同时交差。
- 它增加了头压缩(header compression),因此即使非常小的请求,其请求和响应的header都只会占用很小比例的带宽。
8.11 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
- 浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求(TCP三次握手);
- 服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
- 浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
- 载入解析到的资源文件,渲染页面,完成。
8.12 浏览器的渲染过程
- 浏览器请求到HTML代码后,在生成DOM的最开始阶段,并行发起css、图片、js的请求,无论他们是否在HEAD里。浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
- CSS文件下载完成,开始构建CSSOM
- 所有CSS文件下载完成,CSSOM构建结束后,和 DOM 一起生成 Render Tree。
- 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作就是计算出每个节点在屏幕中的位置。
- 最后一步,按照算出来的规则,把内容渲染到屏幕上。
以上五个步骤前3个步骤因为DOM、CSSOM、Render Tree都可能在第一次Painting后又被更新多次,比如JS修改了DOM或者CSS属性。Layout 和 Painting 也会被重复执行,除了DOM、CSSOM更新的原因外,图片下载完成后也需要调用Layout 和 Painting来更新网页。
display:none 的节点不会被加入 Render Tree,而 visibility: hidden 则会,所以,如果某个节点最开始是不显示的,设为 display:none 是更优的。
8.13 一个完整的URL包括以下几部分
- 协议部分
- 域名部分
- 端口部分
- 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止
- 文件名部分:从域名后的最后一个“/”开始到“?”为止
- 参数部分:从“?”开始到“#”为止之间的部分
- 锚部分:从“#”开始到最后
8.14 GET和POST的区别
GET:
一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在1024字节,Get是通过地址栏来传值。
POST:
一般用于修改服务器上的资源,对所发送的信息没有限制。(常用于发送表单数据,新建、修改等),Post是通过提交表单来传值。
8.15 常见HTTP状态码
1xx(临时响应)
:表示临时响应并需要请求者继续执行操作的状态码。2xx(成功)
:表示成功处理了请求的状态码。200(成功)
:服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。3xx(重定向)
:要完成请求,需要进一步操作。301(永久移动)
:请求的网页已永久移动到新位置。302(临时移动)
:服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。304(未修改)
:自从上次请求后,请求的网页未修改过。4xx(请求错误)
:这些状态码表示请求可能出错,妨碍了服务器的处理。400(错误请求)
:服务器不理解请求的语法。404(未找到)
:服务器找不到请求的网页。5xx(服务器错误)
:这些状态码表示服务器在处理请求时发生内部错误。500(服务器内部错误)
:服务器遇到错误,无法完成请求。503(服务不可用)
:服务器目前无法使用(由于超载或停机维护)。
8.16 说说网络分层里七层模型是哪七层
- 应用层
- 表示层
- 会话层(从上往下)(HTTP、FTP、SMTP、DNS)
- 传输层(TCP和UDP)
- 网络层(IP)
- 物理层
- 数据链路层(以太网)
8.17 304缓存
服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
304是HTTP状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件
8.18 http keep-alive与tcp keep-alive
http keep-alive是为了让tcp活得更久一点,以便在同一个连接上传送多个http,提高socket的效率。而tcp keep-alive是TCP的一种检测TCP连接状况的保鲜机制。
8.19 常见web安全及防护原理
sql注入原理
就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
XSS
指的是攻击者往Web页面里插入恶意html标签或者javascript代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点。
CSRF
CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次CSRF攻击,受害者必须依次完成两个步骤:1、登录受信任网站A,并在本地生成Cookie。2、在不登出A的情况下,访问危险网站B。
9. 算法
9.1 数组去重
建一个空对象和空数组,循环遍历需要去重的数组,判断对象有没有此属性,没有的话就给对象添加此属性,并向空数组中push这个值。
//es5
function unique(arr){
var obj = {}
var result = []
for(var i in arr){
if(!obj[arr[i]]){
obj[arr[i]] = true;
result.push(arr[i]);
}
}
return result;
}
//es6
[...new Set(arr)]
9.2 排序
请参考专栏相关文章
10. 其他
10.1 对前端界面工程师这个职位是怎么样理解的?
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好
- 实现界面交互
- 提升用户体验
10.2 谈谈你对重构的理解
在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。
- 减少代码间的耦合
- 让代码保持弹性
- 严格按规范编写代码
- 设计可扩展的API
- 代替旧有的框架、语言(如VB)
- 增强用户体验
- 通常来说对于速度的优化也包含在重构中
10.3 你遇到过比较难的技术问题是?你是如何解决的?
10.4 平时是如何学习前端开发的?
10.5 平时如何管理你的项目?
- 先期团队必须确定好全局样式(globe.css),编码模式(utf-8) 等;
- 编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
- 标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
- 页面进行标注(例如 页面 模块 开始和结束);
- CSS跟HTML 分文件夹并行存放,命名都得统一(例如style.css);
- JS 分文件夹存放 命名以该JS功能为准的英文翻译。
- 图片采用整合的 images.png png8 格式文件使用尽量整合在一起使用方便将来的管理
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。