文章目录

一. JavaScript


1.1 数据类型 (9种)

基本数据类型(栈):Number,String,Boolean,null,undefined,symbol(创建唯一值),bigint(后两个为ES6新增)
引用数据类型(堆):object,function

1、typeof typeof 是一个操作符,返回该类型的字符串(全小写字母)形式表示,包括以下 7种:number、string、boolean、undefined、symbol、object、function 等。(对于 null,返回 object 类型。)

  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除 function ,一律返回 object 类型。

2、instanceof 检测的是原型,instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
3、toString是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] Object.prototype.toString.call('')
4、constructor是原型prototype的一个属性,当函数被定义时候,js引擎会为函数添加原型prototype,并且这个prototype中constructor属性指向函数引用, 因此重写prototype会丢失原来的constructor。

var、let、const

let 和 const 的优点?
let 和 const 有了块级作用域,变量声明不会提升相比于 var

var、let、const的区别

  • var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
  • let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
  • const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。

1.2 普通函数、匿名函数、箭头函数

  • 普通函数中的this:谁调用了函数或者方法,this指向谁
  • 匿名函数中的this:指向是window,而不是调用该匿名函数的对象;
  • 箭头函数中的this
    • 箭头函数中的this是在函数定义的时候就确定下来的
    • 箭头函数中的this指向父级作用域的执行上下文
    • 箭头函数无法使用apply、call和bind方法改变this指向

箭头函数与普通函数区别

  • 箭头函数是匿名函数不能作为构造函数不能使用new
  • 箭头函数不绑定arguments,需要用运算符解决…解决
  • 箭头函数不绑定this,会捕获其所在的this值,作为自己的this值
  • 箭头函数通过call()或apply()调用一个函数,只传入了一个参数,对this并没有影响.
  • 箭头函数没有原型属性

new操作符具体干了什么呢

  1. 创建一个新的对象obj
  2. 将对象与构建函数通过原型链连接起来
  3. 将构建函数中的this绑定到新建的对象obj上
  4. 根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理
    在这里插入图片描述

1.3 call, apply(数组), bind

作用:

  • 都可以改变函数内部的this指向。
    区别点:
  • call 和 apply 会调用函数,并且改变函数内部this指向。
  • call 和 apply 传递的参数不一样,call 传递参数arg1,arg2…形式 apply 必须数组形式[arg]
  • bind 不会调用函数,可以改变函数内部this指向。

1.4 eventloop, 宏任务和微任务

不停检查 Call Stack 中是否有任务(也叫栈帧)需要执行,如果没有,就检查 Event Queue,从中弹出一个任务,放入 Call Stack 中,如此往复循环。
1、所有同步任务都在主线程上执行,形成一个执行栈  
2、主线程之外,还存在一个"消息队列"。只要异步操作执行完成,就到消息队列中排队  
3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取消息队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行  
4、主线程不断重复上面的第三步

  • 宏任务(setTimeout, setInterval,setImmediate) Macrotask 宏任务是指Event Loop在每个阶段执行的任务
  • 微任务 (Promises, Object.observe)Microtask 微任务是指Event Loop在每个阶段之间执行的任务
  • new promise 与同步一起,先微后宏

1.5 闭包 (概念, 用途, 手写)

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围), 这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

闭包的特点:

  • 让外部访问函数内部变量成为可能;
  • 可以避免使用全局变量,防止全局变量污染;
  • 可以让局部变量常驻在内存中;
  • 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

1.7 继承 (extends, 原型链继承, 构造函数继承, 组合继承, 寄生组合继承)

1.8深拷贝和浅拷贝

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象共享同一块内存。
深拷贝会创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

实现浅拷贝方法:
(1)Object.assign方法
(2)for in方法

实现深拷贝方法:
(1)采用递归去拷贝所有层级属性
(2)使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;
(3)热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝;

1.9 Promise

Promise对象, 可以将异步操作以同步的流程表达出来。使用 Promise 主要有以下好处:

  • 可以很好地解决回调地狱的问题(避免了层层嵌套的回调函数)。
  • 语法非常简洁。Promise 对象提供了简洁的API,使得控制异步操作更加容易
    new Promise(function(resolve, reject) then,catch,finally捕获错误
    Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise的结果。

Promse.race Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

Ajax请求过程

(1)创建 XMLHttpRequest 对象,也就是创建一个异步调用对象;
(2)创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、 URL 以及验证信息;
(3)设置响应 HTTP 请求状态变化的函数;
(4)发送 HTTP 请求;
(5)获取异步调用返回的数据;
(6)使用 JavaScript 和 DOM 实现局部刷新。

AMD、CMD、CommonJs、ES6的对比

他们都是用于在模块化定义中使用的,前三个是ES5中提供的模块化编程的方案,
AMD: 是RequireJS在推广过程中对模块定义的规范化产出(依赖前置、异步定义)

通过define()函数定义,第一个参数是一个数组,里面定义一些需要依赖的包,第二个参数是一个回调函数,通过变量来引用模块里面的方法,最后通过return来输出。

CMD:是SeaJS在推广过程中对模块定义的规范化产出,(同步模块,没有前置依赖)

通过define()定义,没有依赖前置,通过require加载jQuery插件,CMD是依赖就近,在什么地方使用到插件就在什么地方require该插件,即用即返,这是一个同步的概念

CommonJs:是通过module.exports定义的,通过node.js后端使用的。
import/export:是ES6中定义新增的,对模块进行导出导入的

require,import和import()函数的区别

import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。
import()函数,完成动态加载。异步加载
require是运行时加载模块,只有运行时才知道,同步加载

ES6转化为ES5

https://blog.csdn.net/weixin_44135121/article/details/104161852
Parser 解析
第一步主要是将 ES6 语法解析为 AST 抽象语法树。简单地说就是将代码打散成颗粒组装的对象。这一步主要是通过 babylon 插件来完成。
Transformer 转换
第二步是将打散的 AST 语法通过配置好的 plugins(babel-traverse 对 AST 进行遍历转译)和 presets (es2015 / es2016 / es2017 / env / stage-0 / stage-4 其中 es20xx 表示转换成该年份批准的标准,env 是最新标准,stage-0 和 stage-4 是实验版)转换成新的 AST 语法。这一步主要是由 babel-transform 插件完成。plugins 和 presets 通常在 .babelrc 文件中配置。
Generator 生成
第三步是将新的 AST 语法树对象再生成浏览器都可以识别的 ES5 语法。这一步主要是由 babel-generator 插件完成

二. 浏览器


2.1浏览器输入URL发生了什么

http请求的推演过程:

  1. 对网址进行DNS域名解析,得到对应的IP地址(输入地址,在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器获得请求对应的 IP 地址。)
  2. 根据这个IP,找到对应的服务器,发起TCP的三次握手(该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。)
  3. 建立TCP连接后发起HTTP请求
  4. 服务器响应HTTP请求,浏览器得到html代码
    (HTTP响应:状态行(协议版本、状态码、状态码描述),响应头,空格,消息体)
  5. 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
    (先得到html代码,才能去找这些资源)
  6. 浏览器对页面进行渲染呈现给用户
  7. 服务器关闭关闭TCP连接

注:

1.DNS怎么找到域名的?

递归查询。 浏览器自身的DNS缓存->系统自身的DNS缓存->hosts文件->域名服务器
DNS优化两个方面:DNS缓存、DNS负载均衡

2.为什么HTTP协议要基于TCP来实现?

TCP是一个端到端的可靠的面相连接的协议,HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,会重传)

3.服务器关闭关闭TCP连接

一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:

Connection:keep-alive 

TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

三次握手 四次挥手

TCP的三次握手过程如下:
C-> SYN -> S SYN标记的包,请求建立连接.
S->SYN/ACK->C SYN包的确认包,对第一个SYN包的确认
C->ACK->S 通知A连接已建立

三次握手的原因: “为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”1. 确保建立可靠连接2. 避免资源浪费
例如,客户端先发送了一个SYN,但是由于网络阻塞,该SYN数据包在某个节点长期滞留。然后客户端又重传SYN数据包并正确建立TCP连接,然后传输完数据后关闭该连接。该连接释放后失效的SYN数据包才到达服务器端。在二次握手的前提下,服务器端会认为这是客户端发起的又一次请求,然后发送SYN
,并且在服务器端创建socket套接字,一直等待客户端发送数据。但是由于客户端并没有发起新的请求,所以会丢弃服务端的SYN
。此时服务器会一直等待客户端发送数据从而造成资源浪费。

TCP的四次挥手过程如下:

C->FIN->S 客户端进程发出连接释放报文,并且停止发送数据。
S->ACK->C 服务器收到连接释放报文,发出确认报文
S->FIN->C 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文
C->ACK->S客户端收到服务器的连接释放报文后,必须发出确认

四次挥手的原因:由于连接的关闭控制权在应用层,所以被动关闭的一方在接收到FIN包时,TCP协议栈会直接发送一个ACK确认包,优先关闭一端的通信。然后通知应用层,由应用层决定什么时候发送FIN包。应用层可以使用系统调用函数read==0来判断对端是否关闭连接。

2.2浏览器如何渲染页面的?

  1. HTML 被 HTML 解析器解析成 DOM 树;
  2. CSS 被 CSS 解析器解析成 CSSOM 树;
  3. 结合 DOM 树和 CSSOM 树,生成一棵渲染树(Render Tree),这一过程称为 Attachment;
  4. 生成布局(flow),浏览器在屏幕上“画”出渲染树中的所有节点;
  5. 将布局绘制(paint)在屏幕上,显示出整个页面。

2.3回流和重绘

  1. 重排(Reflow):当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器重新构造渲染树。
  2. 重绘(Repaint):是在一个元素的外观被改变所触发的浏览器行为,浏览器会重绘制。
  3. 区别:重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)
  4. 浏览器优化:浏览器会维护1个队列,把所有会引起重排,重绘的操作放入这个队列,等队列中的操作到一定数量或者到了一定时间间隔,浏览器就会flush队列,进行一批处理,这样多次重排,重绘变成一次重排重绘
  5. 减少 reflow/repaint:
    (1)不要一条一条地修改 DOM 的样式。可以先定义好 css 的 class,然后修改 DOM 的
    className。
    (2)不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。
    (3)为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会reflow 的。
    (4)千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。(table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。这也是为什么我们要避免使用table做布局的一个原因。)
    (5)不要在布局信息改变的时候做查询(会导致渲染队列强制刷新)

2.4 http 缓存, 协商缓存

http 缓存控制

  1. http缓存能够帮助服务器提高并发性能,很多资源不需要重复请求直接从浏览器中拿缓存
  2. http 缓存分类 :强缓存 协商缓存
  3. 强缓存: expires 和 cache-control控制
    服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时
    间内,执行比较缓存策略。
    协商缓存: last-Modify 和E-tag控制
    让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率,将
    缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304直接使用缓存,200请求成功。

补充:
1. 为什么有expires 有需要cache-control

因为expires 有个服务器和浏览器时间不同步的问题
expires是绝对事件 cache-control是相对时间
Cache-Control的优先级比Expires的优先级高

2. last-modify和Etag

last-modify 最后一次被修改的时间,它是有个精度问题 到秒
e-tag 没有精度问题 只要文件改变 e-tag值就改变
Etag 的优先级高于 Last-Modified

2.5 cookies, sessionStorage, localStorage

共同点:都是保存在浏览器端、且同源的
web storage:sessionStorage, localStorage
区别:

  1. 与服务器通信:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。
  2. 存储大小限制也不同,每个domain最多只能有20条cookie,cookie数据不能超过4K。sessionStorage和localStorage可以达到5M或更大。
  3. 数据有效期不同,
    sessionStorage:仅在当前浏览器窗口关闭之前有效;
    localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  4. 作用域不同,
    sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
    localstorage在所有同源窗口中都是共享的;
    cookie也是在所有同源窗口中都是共享的.
  5. web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
  6. web Storage的api接口使用更方便

写一个会过期的localStorage:

惰性删除:某个键值过期后不会被马上删除,等到下次被使用,检查到过期删除。

定时删除:每隔一段时间执行一次删除操作,并通过限制删除操作执行的次数和频率,来减少删除操作对CPU的长期占用。另一方面定时删除减少localStorage空间的浪费。

2.7 fetch vs axios

  1. fetch是一个底层的 api 浏览器原生支持的 axios是一个封装好的框架

  2. axios 1)支持浏览器和nodejs发请求 前后端发请求,
    2)支持promise语法
    3)支持自动解析json
    4)支持中断请求
    5) 支持拦截请求
    6) 支持请求进度监测
    7) 支持客户端防止csrf

    一句话总结: 封装比较好

  3. fetch
    优点: 1. 浏览器级别原生支持的api
    2. 原生支持promise api
    3. 语法简洁 符合 es 标准规范
    4. 是由whatwg 组织提出的 现在已经是w3c规范

    缺点:
    1. 不支持文件上传进度监测
    2. 使用不完美 需要封装
    3. 不支持请求中止
    4. 默认不带cookie
    一句话总结: 缺点是需要封装 优点 底层原生支持

2.8浏览器多页签通讯实现

  1. 可以借助 浏览器localstorage方式实现 cookie + setInterval 实现 websocket全双工实现 sharedworker实现
  2. 1) localstorage 如何实现
    localstorage.setItem 方法传数据
    监听window上 storage事件 就可以获得数据
    2) cookie + setInterval
    document.cookie 发数据
    setInterval不停地去cookie上去数据
    3) websocket实现
    websocket是全双工通讯方式 多页签可以将服务器作为桥梁来实现通讯
    4)h5 新技术 共享worker sharedworker 也可以实现

2.9前端安全相关-XSS和CSRF

  1. xss 跨站脚本攻击 csrf 是跨站请求伪造
  2. xss
    浏览器向服务器请求的时候被注入脚本攻击
    分成三种类型 反射型(非持久型), 存储型(持久型), 基于DOM
    防范手段:
    1. 输入过滤
    2. 输出过滤
    3. 加httponly 请求头 锁死cookie
  3. csrf
    黑客通过网站B 诱使用户去访问已经登录了的网站A 进行一些违背用户意愿的请求造成用户损失
    防范手段:
    1. 服务器验证 http请求的 refer 头信息
    2. 请求的时候 传token
    3. 加验证码

2.10跨域问题

1.跨域问题是浏览器同源策略限制,当前域名的js只能读取同域下的窗口属性。
(协议名,子域名,主域名,端口号)

  • 跨域解决方案

  • jsonp:利用script 标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP优点是简单兼容性好,缺点是仅支持get方法具有局限性, 不安全可能会遭受XSS攻击。

  • cors:跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来进行跨域。浏览器会自动进行 CORS 通信,服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。

  • postMessage:「window.postMessage()」是HTML5中的API,允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
  • websocket:是HTML5的协议,实现了浏览器与服务器的全双工通信,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。
  • Node中间件代理 :实现原理:同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
  • nginx反向代理
    搭建一个中转nginx服务器,用于转发请求。只需要修改nginx的配置即可解决跨域问题
  • window.name + iframe
  • location.hash + iframe
  • document.domain + iframe
    日常工作中,用得比较多的跨域方案是cors和nginx反向代理

2.11HTTP响应

HTTP响应由三部分组成:状态行,响应头,空格,消息体
状态行包括:协议版本、状态码、状态码描述

状态码: 状态码用于表示服务器对请求的处理结果

1xx:指示信息——表示请求已经接受,继续处理
2xx:成功——表示请求已经被成功接收、理解、接受。
3xx:重定向——要完成请求必须进行更进一步的操作
4xx:客户端错误——请求有语法错误或请求无法实现
5xx:服务器端错误——服务器未能实现合法的请求。

列举几种常见的:

200(没有问题)
301是永久重定向
302(要你去找别人) 临时重定向
304(要你去拿缓存) 未修改
307(要你去拿缓存)
403(有这个资源,但是没有访问权限)
404(服务器没有这个资源)
500(服务器这边有问题)

响应头: 响应头用于描述服务器的基本信息,以及客户端如何处理数据

空格: CRLF(即 \r\n)分割

消息体: 服务器返回给客户端的数据

2.12 http(http1.x 和http2.x)和https

HTTP:是一种网络协议,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是HTTP的安全版,即HTTP下加入SSL层。,如今 SSL 已废弃,HTTPS 引入了数据加密和身份验证机制。通过安全可靠的 TLS 协议进行加密。

HTTPS作用:

  • 内容加密 建立一个信息安全通道,来保证数据传输的安全;
  • 身份认证 确认网站的真实性
  • 数据完整性 防止内容被第三方冒充或者篡改

HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

http1.x 和http2.x主要有以下4个区别:

  1. HTTP2使用的是二进制传送(帧和流),HTTP1.X是文本(字符串)传送。
  2. HTTP2支持多路复用
  3. HTTP2头部压缩
  4. HTTP2支持服务器推送

非对称加密和对称加密

  • 对称加密:在对称加密算法中,加密使用的密钥和解密使用的密钥是相同的。也就是说,加密和解密都是使用的同一个密钥。
  • 非对称加密:指加密和解密使用不同密钥的加密算法。非对称加密算法需要两个密钥:公钥(publickey)私钥(privatekey)。

加密在HTTPS协议中的应用

  1. 浏览器向服务器发出请求,询问对方支持的对称加密算法和非对称加密算法;服务器回应自己支持的算法。
  2. 浏览器选择双方都支持的加密算法,并请求服务器出示自己的证书;服务器回应自己的证书。
  3. 浏览器随机产生一个用于本次会话的对称加密的钥匙,并使用服务器证书中附带的公钥对该钥匙进行加密后传递给服务器;服务器为本次会话保持该对称加密的钥匙。第三方不知道服务器的私钥,即使截获了数据也无法解密。非对称加密让任何浏览器都可以与服务器进行加密会话。
  4. 浏览器使用对称加密的钥匙对请求消息加密后传送给服务器,服务器使用该对称加密的钥匙进行解密;服务器使用对称加密的钥匙对响应消息加密后传送给浏览器,浏览器使用该对称加密的钥匙进行解密。第三方不知道对称加密的钥匙,即使截获了数据也无法解密。对称加密提高了加密速度 。

完整的非对称加密过程

假如现在 你向支付宝 转账(术语数据信息),为了保证信息传送的保密性、真实性、完整性和不可否认性,需要对传送的信息进行数字加密和签名,其传送过程为:

  1. 首先你要确认是否是支付宝的数字证书,如果确认为支付宝身份后,则对方真实可信。可以向对方传送信息
  2. 你准备好要传送的数字信息(明文)计算要转的多少钱,对方支付宝账号等;
  3. 你对数字信息进行哈希运算,得到一个信息摘要(客户端主要职责);
  4. 你用自己的私钥对信息摘要进行加密得到 你 的数字签名,并将其附在数字信息上;
  5. 你随机产生一个加密密钥,并用此密码对要发送的信息进行加密(密文);
  6. 你用支付宝的公钥对刚才随机产生的加密密钥进行加密,将加密后的 DES 密钥连同密文一起传送给支付宝
  7. 支付宝收到 你 传送来的密文和加密过的 DES 密钥,先用自己的私钥对加密的 DES 密钥进行解密,得到 你随机产生的加密密钥;
  8. 支付宝 然后用随机密钥对收到的密文进行解密,得到明文的数字信息,然后将随机密钥抛弃;
  9. 支付宝 用你 的公钥对 你的的数字签名进行解密,得到信息摘要;
  10. 支付宝用相同的哈希算法对收到的明文再进行一次哈希运算,得到一个新的信息摘要;
  11. 支付宝将收到的信息摘要和新产生的信息摘要进行比较,如果一致,说明收到的信息没有被修改
    过;
  12. 确定收到信息,然后进行向对方进行付款交易,一次非对称密过程结束。

三. CSS

盒子模型, 怪异盒子

盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)
标准 W3C 盒子模型:width=content
IE 盒子模型:width=content+ border +padding;

BFC

BFC,块级格式化上下文,形成独立的渲染区域,盒子里面的子元素的样式不会影响到外面的元素。
BFC触发方式

  • 根元素,即HTML标签
  • 浮动元素:float值为 left 、 right
  • overflow值不为 visible,为 auto 、 scroll 、 hidden
  • display值为 inline-block 、 table-cell 、 table-caption 、 table 、 inline-table 、 flex 、 inline-flex 、 grid 、 inline-grid
  • 定位元素:position值为 absolute 、 fixed

作用

  1. 阻止元素被浮动元素覆盖 :一个正常文档流的block元素可能被一个float元素覆盖,挤占正常文档流,因此可以设置一个元 素的float、 display、position值等方式触发BFC,以阻止被浮动盒子覆盖。
  2. (清除浮动)可以包含浮动元素 通过改变包含浮动子元素的父盒子的属性值,触发BFC,以此来包含子元素的浮动盒子。
  3. 阻止因为浏览器因为四舍五入造成的多列布局换行的情况 有时候因为多列布局采用小数点位的width导致因为浏览器因为四舍五入造成的换行的情况,可 以在最后一列触发BFC的形式来阻止换行的发生。比如下面栗子的特殊情况
  4. (外边距塌陷)阻止相邻元素的margin合并 属于同一个BFC的两个相邻块级子元素的上下margin会发生重叠,(设置writing-mode:tb-rl时, 水平margin会发生重叠)。所以当两个相邻块级子元素分属于不同的BFC时可以阻止margin重

float, 清除浮动

浮动元素引起的问题

  • 多个浮动的元素无法撑开父元素的宽度,父元素的高度可能会变成0。
  • 若浮动元素后面跟非浮动元素,非浮动元素会紧随其后浮动起来。
  • 若浮动元素前面还有同级元素没有浮动则会影响页面结构。 浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。

clear当应用于非浮动块时,它将非浮动块的边框边界移动到所有相关浮动元素外边界的下方。这个非浮动块的垂直外边距会折叠。

1.使用空标签清除浮动。clear属性
<div style="clear:both;"></div>
2. 使用after伪对象清除浮动。clear属性
该方法只适用于非IE浏览器。该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;
3. 使用overflow。(计算BFC高度时,浮动子元素也参与计算)
可以给父元素设置overflow:auto或者hidden
4. 浮动外部元素 形成BFC

解决盒子塌陷

  1. 盒子大小写死,给每个盒子设定固定的width和height
  2. 给外部的父盒子也添加浮动,脱离标准文档流
  3. 给父盒子添加overflow属性。
  4. 父盒子里最下方引入清除浮动块。
  5. 用after伪元素清除浮动
  6. 给父盒子添加border
  7. 给父盒子设置padding-top

垂直居中的方法

  1. 绝对定位+css3 transform:translate(-50%,-50%)
  2. css3 的flex布局 align-self:center;
  3. table布局 table-cell 和 vertical-align 对容器里的文字进行垂直居中

样式优先级

内联样式 > id选择器样式 > 类选择器样式 > 元素选择器样式

CSS中 link 和@import 的区别是?

(1) link属于HTML标签,而@import是CSS提供的;
(2) 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
(3) import只在IE5以上才能识别,而link是HTML标签,无兼容问题;

position 的值的定位区别:

1.absolute 生成绝对定位的元素,相对于 static 定位以外的第一个祖先元素进行定位。
2.fixed 生成固定定位的元素,相对于浏览器窗口进行定位(老IE不支持)。
3.relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。
4.static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right z-index 声明)。
5.inherit 规定从父元素继承 position 属性的值。

position的absolute与fixed共同点与不同点

共同点

1.改变行内元素的呈现方式,display被置为block
2.让元素脱离普通流,不占据空间
3.默认会覆盖到非定位的元素上

不同点

  • absolute的“根元素”是可以设置的,而fixed的“根元素”固定位浏览器窗口
  • 当滚动网页时,fixed元素与浏览器窗口之间的距离是不变的

四.HTML

块元素, 行内元素
语义化标签: header, section 等
异步加载JS文件: defer 和 async

Ajax->XMLHttpRequest
Axios->fetch

五.VUE

mvc和mvvm的区别

参考答案:
MVC: MVC是应用最广泛的软件架构之一,一般 MVC 分为: Model(模型) , View(视图) , Controller(控制 器) 。 这主要是基于分层的目的,让彼此的职责分开. View 一般用过 Controller 来和 Model 进行联系。 Controller 是 Model 和 View 的协调者, View 和 Model 不直接联系。基本都是单向联系。
MVVM: MVVM 是把 MVC 中的 Controller 改变成了ViewModel 。 View 的变化会自动更新到ViewModel , ViewModel 的变化也会自动同步到 View上 显示,通过数据来显示视图层。
MVVM和MVC的区别:

  • MVC中Controller演变成MVVM中的ViewModel
  • MVVM通过数据来显示视图层而不是节点操作
  • MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验

diff 原理

dom-diff 算法会比较前后虚拟 DOM ,从而得到 patches (补丁),然后与老 Virtual DOM 进行对比,将其应用在需要更新的地方,将 O(n^3) 复杂度的问题转换成 O(n^1=n) 复杂度的问题,得到新的
Virtual DOM 。降低时间复杂度的方法:

  • 两个不同类型的元素会产生不同的树
  • 对于同一层级的一组子节点,它们可以通过唯一 key 进行区分

组件通信

  1. props和$emit
    父->子 prop传递的,子->父组件 $emit触发事件来做到的
  2. v-model
    父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值
  3. p a r e n t ( 子 − > 父 ) 和 c h i l d r e n / parent(子->父) 和 children/ parent(>)children/ref(父->子)
  4. a t t r s 和 attrs和 attrslisteners A->B->C
    A->C B通过attrs拿到A值(除props),通过v-bind=“attrs”->C
    C->A B通过$listeners监听C触发事件,C发出的数据传给A
  5. provide和inject(多层)
    父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
  6. boradcast和dispatch
    broadcast是向特定的父组件,触发事件,dispatch是向特定的子组件触发事件,本质上这种方式还是on和on和emit的封装
  7. 中央事件总线 (兄弟)
    新建一个Vue事件bus对象,然后通过bus. e m i t 触 发 事 件 , b u s . emit触发事件,bus. emitbus.on监听触发的事件。
  8. vuex处理组件之间的数据交互

父子组件生命周期的顺序

  • 加载渲染过程
      父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

  • 子组件更新过程
      父beforeUpdate->子beforeUpdate->子updated->父updated

  • 父组件更新过程
      父beforeUpdate->父updated

  • 销毁过程
      父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

生命周期, 父子生命周期的顺序

组件生命周期

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • activated keep-alive 组件激活时调用。
  • deactivated keep-alive 组件停用时调用。
  • beforeDestroy
  • destroyed

Vue双向绑定

的数据响应是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty () 来
劫持各个属性的setter、getter,但是它并不算是实现数据的响应式的完美方案,某些情况下需要对其
进行修补或者hack这也是它的缺陷,主要表现在两个方面:

  1. vue 实例创建后,无法检测到对象属性的新增或删除,只能追踪到数据是否被修改
  2. 不能监听数组的变化

Vue3.0 实现数据双向绑定的方法
vue3.0 实现数据双向绑定是通过Proxy

Vuex

Vuex是专门为Vuejs应用程序设计的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
具体工作:vuex是一种状态管理机制,将全局组件的共享状态抽取出来为一个store,以一个单例模式存在,应用任何一个组件中都可以使用,vuex更改state的唯一途径是通过mutation,mutation需要commit触发, action实际触发是mutation,其中mutation处理同步任务,action处理异步任务。

vue-router 实现懒加载

结合 Vue 的异步组件和 Webpack 的代码分割功能,可以实现路由组件的懒加载

HashRouter 和 HistoryRouter的区别和原理

参考答案:
vue-router是Vue官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。 vue-router 默认 hash 模式,还有一种是history模式。
原理:

  1. hash路由:hash模式的工作原理是hashchange事件,可以在window监听hash的变化。我们在url后面随便添加一个#xx触发这个事件。vue-router默认的是hash模式—使用URL的hash来模拟一个完整的URL,于是当URL改变的时候,页面不会重新加载,也就是单页应用了,当#后面的hash发生变化,不会导致浏览器向服务器发出请求,浏览器不发出请求就不会刷新页面,并且会触发hasChange这个事件,通过监听hash值的变化来实现更新页面部分内容的操作对于hash模式会创建hashHistory对象,在访问不同的路由的时候,会发生两件事:
    HashHistory.push()将新的路由添加到浏览器访问的历史的栈顶,和HasHistory.replace()替换到当前栈顶的路由
  2. history路由:
    主要使用HTML5的pushState()和replaceState()这两个api结合window.popstate事件(监听浏览器前进后退)来实现的,pushState()可以改变url地址且不会发送请求,replaceState()可以读取历史记录栈,还可以对浏览器记录进行修改

操作系统

进程与线程的区别

进程是操作系统分配资源的单位,线程是CPU调度的基本单位,线程之间共享进程资源

  1. 一个程序至少有一个进程,一个进程至少有一个线程
  2. 线程的划分尺度小于进程,使得多线程程序的并发性高
  3. 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率
  4. 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
  5. 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别

TCP(传输控制协议) vs UDP(用户数据报协议)

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,在不可靠的网络中提供一个可靠的端对端字节流。.
UDP是一种无连接的传输层协议,提供简单不可靠的非连接传输层服务,面向报文。
区别:

  1. TCP是面向连接的,可靠性高;UDP是基于非连接的,可靠性低
  2. 由于TCP是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差,同时过程复杂,也使其易于攻击;UDP没有建立连接的过程,因而实时性较强,也稍安全
  3. 在传输相同大小的数据时,TCP首部开销20字节;UDP首部开销8字节,TCP报头比UDP复杂,故实际包含的用户数据较少。TCP在IP协议的基础上添加了序号机制、确认机制、超时重传机制等,保证了传输的可靠性,不会出现丢包或乱序,而UDP有丢包,故TCP开销大,UDP开销较小
  4. 每条TCP连接只能时点到点的;UDP支持一对一、一对多、多对一、多对多的交互通信

应用场景选择:
对实时性要求高和高速传输的场合下使用UDP;
在可靠性要求低,追求效率的情况下使用UDP;
需要传输大量数据且对可靠性要求高的情况下使用TCP。

OSI七层协议

OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),即ISO开放互连系统参考模型。
1.应用层
作用:它是与其他计算机进行通信的应用,它是对应应用程序的通信服务的。各种应用软件,包括web应用。
协议:DNS、FTP、HTTP、SMTP、TELNET、IRC、WHOIS
2.表示层
作用:这一层的主要作用是定义数据格式和加密
3.会话层
作用:控制应用程序的会话能力,它定义了一段会话的开始、控制和结束,包括对多个双向消息的控制和管理,以便在只完成一部分消息时可以通知应用
4.传输层
作用:对差错恢复协议和无差错恢复协议的选择,对同一主机上不同数据流的输入进行复用,对数据包进行重新排序。是最关键的一层,是唯一负责整体的数据传输和数据控制的。对上三层提供可靠的传输服务,对网络层提供可靠的目的地信息。在这一层数据的单位被称为数据段。
协议:TCP、UDP等
5.网络层
作用:主要负责寻找地址和路由选择,网络层还可以实现阻塞控制、网际互联等。
协议:IP、IPX、RIP、OSPF等
6.数据链路层
作用:负责物理层面上的互联的、节点间的通信传输;该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。在这一层,数据的单位称为帧(frame)
协议:ARP、RARP、SDLC、HDLC、PPP、STP、帧中继等
7.物理层
作用:负责0、1 比特流(0/1序列)与电压的高低、逛的闪灭之间的转换 规定了激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性;该层为上层协议提供了一个传输数据的物理媒体。在这一层,数据的单位称为比特(bit)。
典型规范:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45、fddi令牌环网等

优化

你如何对网站的文件和资源进行优化?

期待的解决方案包括:

  1. 文件合并
  2. 文件最小化/文件压缩
  3. 使用 CDN 托管
  4. 缓存的使用(多个域名来提供缓存)
  5. 其他

请说出三种减少页面加载时间的方法

  1. 优化图片
  2. 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
  3. 优化CSS(压缩合并css,如 margin-top, margin-left…)
  4. 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。)
  5. 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。
  6. 减少http请求(合并文件,合并图片)

页面级优化(7个)

1、减少HTTP请求数

合理设置HTTP缓存:能缓存的越多越好,能缓存的越久越好。
资源合并和压缩:如果可以的话,尽可能的将外部的脚本、样式进行合并(CSS Sprites:合并css图片);另外css、js、image都可以用相应的工具进行压缩
Inline Images:使用data:URL scheme的方式将图片嵌入到页面或者CSS中
2、异步请求callback、异步执行脚本

3、Lazy Load Javascript:只有在需要加载的时候加载

随着js框架流行,越来越多的站点使用起了框架,不过一个框架往往包括很多的资源,这些功能并不是每个页面都需要的。为了节省资源和时间,目前有两种做法:mini版本和Lazy Load

4、避免重复的资源请求:这种情况主要是由于疏忽或者页面由多个模块拼接而成,然后每个模块都请求了同样的资源

测试代码性能的工具

  1. Profiler 内存分析工具
  2. JSPerf(http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout)
  3. Dromaeo

js延迟加载的方式有哪些?

(关于js的延迟加载)的好处是有助于提高页面加载速度,js延迟加载就是等页面加载完成之后在加载js文件

  1. defer(按顺序依次执行)和async(不保证会按顺序执行)
  2. 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
  3. 按需异步载入js

你有哪些性能优化的方法?

  1. 减少http请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器
  2. 前端模板 JS + 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数
  3. 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能
  4. 当需要设置的样式很多时设置 className 而不是直接操作 style
  5. 少用全局变量、缓存DOM节点查找的结果。减少 IO 读取操作
  6. 避免使用 CSS Expression(css表达式)又称 Dynamic properties(动态属性)
  7. 图片预加载,将样式表放在顶部,将脚本放在底部,加上时间戳
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐