前端面试常见问答
本文为笔者整理的前端面试的常见问答,持续更新中,如有错误敬请批评指正!
1.谈一谈http状态码
常见http状态码
- 200 : 请求成功
- 301 : 资源(网页等)被永久转移到其它URL
- 404 : 请求的资源(网页等)不存在
- 500 : 内部服务器错误
HTTP状态码分类
- 1** 信息,服务器收到请求,需要请求者继续执行操作
- 2** 成功,操作被成功接收并处理
- 3** 重定向,需要进一步的操作以完成请求
- 4** 客户端错误,请求包含语法错误或无法完成请求
- 5** 服务器错误,服务器在处理请求的过程中发生了错误
2.GET和POST的区别
-
get是从服务器上获取数据的请求,post是向服务器传送数据的请求
-
get传送的数据量较小,post可以传递的数据量比get大
-
get安全性低,post安全性较高,但get执行效率比post高
3.什么是XHTML
XHTML 是以 XML 格式编写的 HTML。
- XHTML 指的是可扩展超文本标记语言
- XHTML 与 HTML 4.01 几乎是相同的
- XHTML 是更严格更纯净的 HTML 版本
- XHTML 得到所有主流浏览器的支持
XHTML 与 HTML 相比最重要的区别
- 文档结构
- XHTML DOCTYPE 是强制性的
- <html> 中的 XML namespace 属性是强制性的
- <html>、<head>、<title> 以及 <body> 也是强制性的
- 元素语法
- XHTML 元素必须正确嵌套
- XHTML 元素必须始终关闭
- XHTML 元素必须小写
- XHTML 文档必须有一个根元素
- 属性语法
- XHTML 属性必须使用小写
- XHTML 属性值必须用引号包围
- XHTML 属性最小化也是禁止的
4.介绍一下Ajax
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- AJAX = Asynchronous JavaScript and XML.
- AJAX 是一种用于创建快速动态网页的技术。
- AJAX 通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重载整个页面的情况下,对网页的某些部分进行更新。
Ajax工作流程
5.Http和Https的区别
- HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
- 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
- HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
6.介绍一下TCP三次握手
在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接
- 第一次握手:客户端尝试连接服务器,向服务器发送 syn 包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入 SYN_SEND 状态等待服务器确认
- 第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个 SYN包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态
- 第三次握手:第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
7.介绍一下TCP四次挥手
终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。 在Socket编程中,这一过程由客户端或服务端任一方执行close来触发,具体流程图如下:
- 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入 FIN_WAIT_1状态
- 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同, 一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
- 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK 状态。
- 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
Client和Server同时发起主动关闭
8.为什么建立连接是三次挥手,而关闭连接是四次挥手
因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了。所以己方可以立即close,或者发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接。因此,己方ACK和FIN一般都会分开发送。
9.JavaScript的三大组成部分是什么
JavaScript的三大组成部分是:1、ECMAscript;2、文档对象模型DOM;3、浏览器对象模型BOM。其中,ECMAscript是javascript的核心,描述了语言的基本语法和数据类型。
- ECMAScript:JavaScript的核心,描述了语言的基本语法(var、for、if、array等)和数据类型(数字、字符串、布尔、函数、对象、未定义)。ECMAScript是一套标准,定义了一种语言(比如JS)是什么样子。
- 文档对象模型(DOM):DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。DOM 将把整个页面规划成由节点层级构成的文档。HTML 或 XML 页面的每个部分都是一个节点的衍生物。通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素。
- 浏览器对象模型(BOM):对浏览器窗口进行访问和操作。例如弹出新的浏览器窗口,移动、改变和关闭浏览器窗口,提供详细的网络浏览器信息(navigator object),详细的页面信息(location object),详细的用户屏幕分辨率的信息(screen object),对cookies的支持等。
10.什么是跨域
由于浏览器同源策略,凡是发送请求url的协议、域名、端口号三者之间任意一个与当前页面地址不同即为跨域。
存在跨域的情况:
- 网络协议不同:如http协议访问https协议。
- 端口不同:如80端口访问8080端口。
- 域名不同:如qianduanblog.com访问baidu.com。
- 子域名不同:如abc.qianduanblog.com访问def.qianduanblog.com。
11.如何解决跨域
1.jsonp
jsonp是一种借助于 script 标签发送跨域请求的方案。浏览器对script的资源引用没有同源限制(即同源和非同源都可以访问到),script的src属性可以访问网络上的资源,并且script标签可以拿到响应体,获取的数据一般为json格式。
核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
缺点:只支持get请求,不支持post请求。
注意:script、img、link、iframe都不存在跨域请求的限制 ,并且它们的src请求都是资源文件请求(即get请求)
2.CORS跨域资源共享
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
3.设置document.domain
因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)
// 两个页面都设置
document.domain = 'test.com';
4. http proxy
5. nginx反向代理
12.谈一谈CSS盒子模型
所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。
盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。
下面的图片说明了盒子模型(Box Model):
- Margin(外边距) - 清除边框外的区域,外边距是透明的。
- Border(边框) - 围绕在内边距和内容外的边框。
- Padding(内边距) - 清除内容周围的区域,内边距是透明的。
- Content(内容) - 盒子的内容,显示文本和图像。
总元素的宽度=宽度+左填充+右填充+左边框+右边框+左边距+右边距
总元素的高度=高度+顶部填充+底部填充+上边框+下边框+上边距+下边距
13.简述一下src与href的区别
src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。
<script src =”js.js”></script>
href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加
<link href=”common.css” rel=”stylesheet”/>
14.前端性能如何优化
前端性能优化可以分为三个方面:接口访问优化、静态资源优化和页面渲染速度优化。
1.接口访问优化
1.1 减少http请求,合理设置 HTTP缓存
http协议是无状态的应用层协议,每次发送http请求时,都需要建立连接、通信、断开连接,在服务器端每个http都需要开启独立的线程去处理。所以尽量减少http请求,尽可能地提高访问性能。
1.2 减少cookie传输
cookie 存在于 http 头,在客户端与服务器之间交换,尽可能地控制 cookie 的大小,cookie越小,响应速度越快,减少 cookie 传输,响应速度更快。
1.3 使用CDN提供静态文件
使用 CDN 可以更快地在全球范围内获取到你的静态文件,加快网页加载。
1.4 分域存放资源
HTTP 客户端一般对同一个服务器的并发连接个数都是有限制的,通常最大并行连接为四了,剩下的会进入等待队列,等前边的执行完毕,等待的才会执行。所以利用多域名主机存放资源,增加并行连接量,缩短资源加载时间。
1.5 减少页面重定向
1.6 避免使用iframe
iframe 相当于本页面又嵌套了一个页面,消耗性能,还要加载嵌套页面的资源,所以更消耗时间。
1.7 借用浏览器缓存
ajax 请求到的数据,可以缓存到浏览器,下次使用的时候无需再次获取,直接取缓存数据就可以。这个会根据具体的项目来做,比如常用的角色类型就会缓存,获取到的普通数据为了保证实时性,不能使用缓存。
2.静态资源优化
2.1 压缩 html、css、js 等文件
2.2 在 js 之前引用 css
js 执行的时候会进入阻塞,如果放入 js 之后加载,会等待 js 执行完成之后才能加载 css,渲染页面,此时就会出现布局错乱。所以 css 文件需要非阻塞引入,以防DOM 花费更多时间才能渲染。
2.3 非阻塞 js
js 会阻止 html 文档的正常解析,当解析器到达 script 标记时,它会停止解析并执行脚本。所以我们经常把 script 引入的 js,放到 html 中最底下。如果需要让脚本位于页面顶部,建议添加非阻塞属性。经常使用 defer 和 async 来异步加载js文件。
2.4 图片压缩
2.5 矢量图替代位图
3.页面渲染速度优化
3.1 懒加载
素材类的网站,页面一屏展示很多图片,而且图片还不能失真,图片加载太多,网页加载慢得很。因此引用懒加载,只加载可视区的图片,避免加载可以能不需要或不必要的图像,从而改善页面的响应时间。
3.2 设置大小,避免重绘
遇到 img 标签,会立马发送一个 http 请求,下载图片,页面继续向下渲染,等图片加载成功了,发现图片的宽高大小发生变化,影响后边排版,所以页面会重新再绘制一次这部分。所以尽可能设置图片的大小。
3.3 减少DOM元素
解析 html 内容,将标签转化为DOM节点,之后再解析其他文件,DOM元素越少,也就是标签越少,文件转化得越快,加载速度也就越快。
15.浏览器访问一个URL的完整流程
打开浏览器,在地址栏输入URL,回车,出现网页内容。
整个过程可以概括为几下几个部分:
- 利用DNS协议将域名解析成IP地址;
- 与目的主机进行TCP连接(三次握手);
- 发送与接收数据(浏览器与目的主机开始HTTP访问过程);
- 与目的主机断开TCP连接(四次挥手);
16.谈一谈渐进增强和优雅降级
渐进增强 (progressive enhancement):针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级 (graceful degradation):一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。
17.JavaScript 变量声明提升
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
JavaScript变量的初始不会提升。
var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x + " " + y; // 显示 x 和 y
var y = 7; // 初始化 y
y 输出了 undefined,这是因为变量声明 (var y) 提升了,但是初始化(y = 7) 并不会提升,所以 y 变量是一个未定义的变量。
18.介绍一下JavaScript严格模式
JavaScript 严格模式(strict mode)即在严格的条件下运行。
“use strict” 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。
“use strict” 的目的是指定代码在严格条件下执行。
严格模式下不能使用未声明的变量。
为什么使用严格模式?
为了消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的Javascript做好铺垫。
严格模式有哪些不同?
- 将过失错误转成异常
在严格模式下,某些先前被接受的过失错误将会被认为是异常。- 严格模式下无法再意外创建全局变量。
- 严格模式会使引起静默失败 (silently fail,注:不报错也没有任何效果) 的赋值操作抛出异常。
- 在严格模式下,试图删除不可删除的属性时会抛出异常 。
- 严格模式要求函数的参数名唯一。在正常模式下,最后一个重名参数名会掩盖之前的重名参数。
- 简化变量的使用
不允许不使用 var 关键字去创建全局变量,抛出 ReferenceError
不允许对变量使用 delete 操作符,抛 ReferenceError - 让eval和arguments变的简单
在函数内部对修改参数不会反映到 arguments 中
淘汰 arguments.callee 和 arguments.caller - 对象属性名必须唯一
- 函数中不可有重名参数
- 不可在 if 内部声明函数
- 抛弃 with 语句
19.实现盒子水平垂直居中的方式
初始化测试代码:
<body>
<div class="parent">
<div class="children"></div>
</div>
<style>
.parent {
width: 100%;
height: 50%;
background-color: skyblue;
}
.children {
width: 20%;
height: 20%;
background-color: pink;
}
</style>
</body>
父子元素宽高未知时
- table-cell(使用表格样式)
.parent {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.children {
display: inline-block;
}
- flex 布局
1)只设置父元素:
.parent {
display: flex;
justify-content: center;
align-items: center;
}
2)同时设置父子元素:
.parent {
display: flex;
}
.children {
align-self: center;
margin: auto;
}
- absolute + transform(定位的上、左为 50%,translate 上、左负 50%)
.parent {
position: relative;
}
.children {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
- absolute + margin: auto(定位的上下左右为 0)
.parent {
position: relative;
}
.children {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
- Grid 网格布局
.parent {
display: grid;
}
.children {
align-self: center;
justify-self: center;
}
子元素固定宽高已知时(假设子元素宽高为 200px)
- absolute + calc(定位上、左负50%时减去子元素宽、高)
.parent {
position: relative;
}
.children {
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
- absolute + 负margin(定位的上、左为 50%,margin 的上、左负子元素的一半)
.parent {
position: relative;
}
.children {
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -100px;
}
父元素高度已知(假设为 400px),子元素宽高未知
- text-align + vertical-align
.parent {
text-align: center;
line-height: 400px;
}
.children {
display: inline-block;
vertical-align: middle;
line-height: initial;
}
20.var、let、const的区别
使用 var 关键字声明的变量不具备块级作用域的特性,它在 {} 外依然能被访问到。
{
var x = 2;
}
// 这里可以使用 x 变量
let 声明的变量只在 let 命令所在的代码块内有效。
{
let x = 2;
}
// 这里不能使用 x 变量
const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改:
重新声明变量
使用 var 关键字重新声明变量可能会带来问题。
在块中重新声明变量也会重新声明块外的变量:
var x = 10;
// 这里输出 x 为 10
{
var x = 2;
// 这里输出 x 为 2
}
// 这里输出 x 为 2
let 关键字就可以解决这个问题,因为它只在 let 命令所在的代码块 {} 内有效。
21.介绍一下JavaScript的Array数组
数组对象的作用是:使用单独的变量名来存储一系列的值。
创建数组
- 常规方式
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
- 简洁方式
var myCars=new Array("Saab","Volvo","BMW");
- 字面
var myCars=["Saab","Volvo","BMW"];
一个数组中可以有不同的对象
所有的JavaScript变量都是对象。数组元素是对象。函数是对象。
因此,可以在数组中有不同的变量类型,如对象元素、函数、数组:
22.介绍一下JavaScript的forEach() 方法
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
注意: forEach() 对于空数组是不会执行回调函数的。
array.forEach(callbackFn(currentValue, index, arr), thisValue)
23.介绍一下Html5
HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定。
HTML5的设计目的是为了在移动设备上支持多媒体。
HTML5的改进
- 新元素
- 新属性
- 完全支持 CSS3
- Video 和 Audio
- 2D/3D 制图
- 本地存储
- 本地 SQL 数据
- Web 应用
24.介绍一下有哪些语义标签
标签 | 描述 |
---|---|
<article> | 定义页面独立的内容区域 |
<aside> | 定义页面的侧边栏内容 |
<details> | 用于描述文档或某个部分的细节 |
<dialog> | 定义对话框 |
<figure> | 规定独立的流内容(图像、图表、照片等) |
<footer> | 定义section 或 document 的页脚 |
<header> | 定义文档的头部区域 |
<nav> | 定义导航链接的部分 |
<section> | 定义文档中的节 |
<time> | 定义日期或时间 |
25.有哪些方法可以使元素消失
- display:none 不生成盒子,在结构中,不占据空间,不响应事件
- visibility:hidden 元素会被隐藏,但不会消失,占据空间,会被子元素继承(可通过设置子元素visibility:visible来显示子元素),不会触发绑定事件
- opacity:0 透明度(取值为0~1),元素隐藏,占据空间,会被子元素继承(不能设置子元素opacity:0来重新显示),能触发绑定事件
- z-index=-1 改变当前dom的层叠上下文,使其置于其他元素之下,达到被隐藏的目的。被其他元素遮挡部分,无法响应事件
- position移除到窗口外面
26.谈一谈v-show和v-if
共同点
- 作用效果相同,都能控制元素在页面是否显示
- 用法相同:
<Model v-show="isShow" />
<Model v-if="isShow" />
- 当表达式为true的时候,都会占据页面的位置
- 当表达式都为false时,都不会占据页面位置
区别
- 控制手段:v-show隐藏则是为该元素添加css–display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除
- 编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换
- 编译条件:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染
- 性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗
27.浏览器存储数据方式有哪些
1.cookie
Cookie的又称是HTTP Cookie,最初是在客户端用于存储会话信息。Cookie数据会自动在浏览器和web服务器之间传输。Cookie通常用于存储一些通用的数据,比如用户的登陆状态,首选项等。
优点:兼容性好
缺点:
- 存储量小。虽不同浏览器的存储量不同,但基本上都是在4kb左右。
- 影响性能。由于Cookie会由浏览器作为请求头发送,因此当Cookie存储信息过多时,会影响特定域的资源获取的效率,增加文档传输的负载。
- 只能储存字符串。
- 安全问题。存储在Cookie的任何数据可以被他人访问,因此不能在Cookie中储存重要的信息。
2.localStorage
localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。可通过locaStorage在浏览器端存储键值对数据。
优点:
- 可存储数据量更大(2.5~10M)
- 提供了简单明了的API来进行操作
- 更加安全
缺点:
- localStorage的值类型限定为string类型,面对JSON对象类型需要进行转换
- localStorage在浏览器的隐私模式下面是不可读取的。
4.sessionStorage
localStorage 与 sessionStorage 的唯一区别就是 localStorage 属于永久性存储,而 sessionStorage 属于当会话结束的时候,sessionStorage 中的键值对会被清空。
5.IndexedDB
IndexedDB是一种本地存储,用于在浏览器中储存较大数据结构的 Web API,并提供索引功能以实现高性能查找。它一般用于保存大量用户数据并要求数据之间有搜索需要的场景,当网络断开时,用户就可以做一些离线的操作。它较之SQL更为方便,不需要写一些特定的语法对数据进行操作,数据格式是JSON。
28.介绍一下CSS3动画
CSS动画指元素从一种样式逐渐过渡为另一种样式的过程。
常见的动画效果有很多,如平移、旋转、缩放等,复杂动画则是多个简单动画的组合
css实现动画的方式,有如下几种:
- transition 实现渐变动画
- transform 转变动画
- animation 实现自定义动画
transition 实现渐变动画
transition的属性如下:
- property:填写需要变化的css属性
- duration:完成过渡效果需要的时间单位(s或者ms)
- timing-function:完成效果的速度曲线
- delay: 动画效果的延迟触发时间
transform 转变动画
包含四个常用的功能:
- translate:位移
- scale:缩放
- rotate:旋转
- skew:倾斜
29.谈一谈vue的双向绑定
Vue数据双向绑定原理:通过数据劫持结合发布者-订阅者模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图。
MVVM模式
MVVM模式就是Model–View–ViewModel模式。对于双向绑定的理解,就是用户更新了View,Model的数据也自动被更新了。