2021年3月最新前端面试题(含泪整理)(二)

295 阅读13分钟

介绍一下HTTP的发展史

  • HTTP/0.9 – 单行协议 ,只有GET
  • HTTP/1.0 – 构建可扩展性,协议版本信息、状态码、http头部信息
  • HTTP/1.1 – 标准化的协议,连接可以复用,缓存控制机制,内容协商机制,Host头(能够使不同域名配置在同一个IP地址的服务器上)
http

超文本传输协议,是以无状态的请求应答方式运行的协议,明文传输

无状态是因为它本身不存储任何信息

https

加密的http,由于http天生明文的特点,整个传输过程完全透明数据,所以产生了https。

所有的http请求和响应在发送到网络前都要进行加密,相当于在http和tcp之间增加了SSL/TCL 全层

了解一下
1.摘要算法 md5
2.加密算法:
	对称加密:编解码时使用相同的密钥,异或
    	非对称加密:公钥和私钥
输入一个url访问网站?
  • 域名解析:把域名解析成ip地址
1.先检查浏览器缓存
2.本机域名解析
3.DNS请求获取ip
  • 网络请求
1.TCP三次握手(tls握手)
2.发送http请求
3.http响应
4.浏览器解析响应报文,渲染页面
5.TCP四次挥手

http常见状态码

1xxs状态码

信息性:服务器正在处理请求

2xxs状态码

请求成功

  • 200 OK:请求成功。成功的含义取决于HTTP方法
  • 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息
3xxs状态码

重定向

  • 302: 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-ControlExpires中进行了指定的情况下,这个响应才是可缓存的
  • 303:对当前的请求的响应可以在另一个URI上被找到,而且客户端应该采用GET的方式访问那个链接。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源
  • 304:如果客户端在发送GET请求时附上了一个值为Sunday的If-Modified-Since报头,而客户端所请求的表示在服务器端自星期日(Sunday)以来一直没有改变过,那么服务器可以返回一个304响应
  • 307: 请求还没有被处理,因为所请求的资源不在本地:它在另一个URI处。客户端应该向那个URI重新发送请求。
4xxs状态码

客户端出现错误

  • 401:这意味着你的登录凭证无效。服务器不知道你是谁,这时,你需要尝试重新登录
  • 403:服务器已经理解请求,但是拒绝执行它。与401不同,403知道是你登录了,但是还是拒绝了你。
  • 404:请求失败,你请求所希望得到的资源未在服务器上发现。
  • 405:客户端试图使用一个本资源不支持的HTTP方法
  • 409:你请求的操作会导致服务器的资源处于一种不可能或不一致的状态
5xxs状态码

服务端错误

  • 500:服务器内部错误,服务器遇到了不知道如何处理的情况。
  • 503:服务器没有准备好处理请求。常见的原因是服务器因维护或重载而停机。
  • 504:网关超时,服务器未能快速的做出反应 参考 小结HTTP状态码

restful API是什么?

REST描述的是在网络中client和server的一种交互的形式,REST不是一种协议本身没有太大的作用,实用的是如何设计 RESTful API(REST风格的接口)

web标准

W3C标准:一系列标准的合集

网页主要由三部分组成:

  • 结构:结构化标准主要包括XHTML和XML
  • 表现:表现标准语言主要包括CSS
  • 行为:行为标准主要包括(如W3C DOM、ECMAScript)

ajax实现原理

XMLHttpRequest对象

XMLHttpRequest 对象是 Ajax 的核心,该对象是一种支持异步请求的技术。简而言之,XMLHttpRequest 对象可以让我们使用 JavaScript 向服务器发起请求并处理响应,而不阻塞用户。 通过 XMLHttpRequest 对象,Web 开发人员可以在页面加载后对页面进行局部更新。

创建流程
  • 创建一个 XMLHttpRequest 对象
  • 创建一个新的 HTTP 请求,并指定该请求的方法、URL 以及是否为异步请求
  • 设置响应 HTTP 请求状态变化的函数
  • 发送 HTTP 请求
  • 对异步返回的数据进行处理
// 创建 XMLHttpRequest 对象
var xhr
if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest()
} else if (window.ActiveXObject) {
    xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
// 创建一个新的请求
xhr.open('GET', 'http://www.example.com', true)
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 监听 HTTP 请求状态变化
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var res = xhr.responseText
    }
}
// 发送 HTTP 请求
xhr.send()

用es5实现promise

function promise (fn) {
           if (typeof this !== 'object') { 
              throw new TypeError('Promises must be constructed via new');
           }
           if (typeof fn !== 'function') {
               throw new TypeError('Promise constructor\'s argument is not a function');
            }
            this.state = "pending"; //定义状态
            this.msg="";
            var process=arguments[0];
            var that=this;
            process(function(){
                that.state="resolve"
                that.msg=arguments[0]
            },function(){
                that.state="reject"
                that.msg=arguments[0]
            })
            return this
      }
      promise.prototype.then=function(){
          constructor:promise
          if(this.state == "resolve"){
              arguments[0](this.msg)
          }else if(this.status=='reject'&&arguments[1]){
              arguments[1](this.msg)
          }
          promise=new this.constructor(function (resolve,reject) {resolve("2")}) //每次调用then之后重新返回一个新的promise实例进行下一步then的调用
        //   console.log(this)
        //   console.log(promise)
          return promise
      }
    var mm =  new promise(function(resolve,reject){
          resolve("1")
      })
      mm.then(function(res){ //then回调
          console.log(res)
      }).then(function(res){
          console.log(res)
      })

列举ES6中新增的一些东西

1.let const
2.模版字符串
3.扩展运算符
4.数值的扩展:isNaN
5.数组的扩展
6.函数的扩展:箭头函数、rest参数
7.对象的扩展:遍历 for inobject.keys;对象的扩展运算符等
8.Symbol
9.SetMap
10.Promise
11.Class
12.Module
13.async

Set WeakSet Map WeakMap对比

小程序页面传值方式

  • 通过EventChannel 传值
  • getCurrentPages() (页面栈)

Object.freeze()和Object.seal()

Object.freeze():冻结一个对象,冻结后不可修改、删除属性,该对象的原型也不能修改

Object.freeze()过程
1.设置Object.preventExtension(),禁止添加新属性(绝对存在)
2.设置writable为false,禁止修改(绝对存在)
3.设置configurable为false,禁止配置(绝对存在)
4.禁止更改访问器属性(getter和setter)

Object.seal():方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要可写就可以改变

1.设置Object.preventExtension(),禁止添加新属性(绝对存在)
2.设置configurable为false,禁止配置(绝对存在)
3.禁止更改访问器属性(getter和setter)

使用Object.freeze()冻结的对象中的现有属性是不可变的。用Object.seal()密封的对象可以改变其现有属性

Object.create()

使用Object.create()是将对象继承到原型链上,然后可以通过对象实例的__proto__属性进行访问原型链上的属性

script标签中的async和defer

  • 没有defer或async属性,浏览器会立即加载并执行相应的脚本,阻塞后续文档的加载
  • async: 表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的
  • defer: 加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前

JS中ready和onload的区别

  • onload:等待网页资源全部加载完毕;只能执行一次,多次执行会覆盖;
  • ready:等待网页中的DOM结构加载完毕;可执行多次并且不会覆盖;

iframe的优缺点

优点

  • 重载页面时不需要重载整个页面,只需要重载页面中的一个框架页
  • 技术易于掌握,使用方便,使用者众多,可主要应用于不需搜索引擎来搜索的页面

缺点

  • 会产生很多页面,不容易管理

HTTP的请求头都包括哪些?请求方法都有哪些?

http协议报文包括

  • 请求报文:请求行(请求方法和协议版本)、请求头、请求体
  • 响应报文:状态行、消息报头、响应正文

请求方法

  • OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法
  • HEAD: 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
  • GET
  • POST
  • PUT:向指定资源位置上传其最新内容
  • DELETE:请求服务器删除Request-URL所标识的资源
  • TRACE:回显服务器收到的请求,主要用于测试或诊断
  • CONNECT:预留给能够将连接改为管道方式的代理服务器

请求头

Host:主机地址
Accept:客户端可识别的内容类型列表。
Accept-Encoding:告诉服务器能接受什么编码格式
User-Agent:产生请求的浏览器类型。
Cache-Control:对缓存进行控制
Referer:表示这是请求是从哪个URL进来的

请求头中强制缓存和协商缓存

  • 强制缓存:当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件做了缓存配置,缓存的时间、缓存类型
  • 协商缓存:就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

get和post的区别

  • GET在浏览器回退时是无害的,而POST会再次提交请求
  • GET请求会被浏览器主动cache,而POST不会,除非手动设置
  • GET产生的URL地址可以被Bookmark,而POST不可以
  • GET请求只能进行url编码,而POST支持多种编码方式。
  • GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留

简述跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

代码题

for(var i=0;i<3;i++){
setTimeout((function(){
    console.log(i)
})(i),0)
}
//输出0 1 2
var a=10;b=20;c=4
++b+c+a++//输出35

continue和break

typeof null的输出及原因

object

不同的对象在底层都表示为二进制,在javascript中二进制前三位都为0的话会被判断为object类型, null的二进制表示全0,自然前三位也是0,所以执行typeof时会返回“object”

用flex实现一个九宫格

列举几个合并对象的方法,object.assign的特点

  • 遍历赋值
  • Object.assign():将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性

call apply bind三者的区别

  • call与apply传参不同,apply参数是数组,call和bind是分开传
  • bind返回一个新的函数,调用时才执行;call和apply是立即执行

Promise和async await的区别,运用场景

  • Promise是链式调用,在一些复杂的业务场景上不美观
  • async/await是基于Promise实现的,不能用于一个普通的回调函数

用localStorage做日志监控

window.dispatchEvent()这个方法来派发一个事件,让window去监听。新实例出来的这个事件会被绑定到window上来监听它的调用,当调用的时候可以拿到setItem的新值,直接赋值就可以

1.document.createEvent() //创建实例
2.event.initEvent() //初始化实例
3.element.dispatchEvent() //触发事件

dispatchEventStroage () {
  const signSetItem = localStorage.setItem
  localStorage.setItem = function (key, val) {
      let setEvent = new Event('setItemEvent')
      setEvent.key = key
      setEvent.newValue = val
      window.dispatchEvent(setEvent)
      signSetItem.apply(this, arguments)
  }
}

数组哪些方法可以跳出循环

  • for循环可以用break
  • forEach可以用try...catch来跳出循环
  • every可以用return false /return true
  • some可以用return true

promise如何中断

参考

git命令行操作,回滚到一个commit并修改,但是不影响其他commit

1.回滚代码

1. git log // 查询要回滚的 commit_id
2. git reset --hard commit_id // HEAD 就会指向此次的提交记录
3. git push origin HEAD --force // 强制推送到远端

2.撤销提交

1. git log // 查找要删除的前一次提交的 commit_id
2. git rebase -i commit_id // 将 commit_id 替换成复制的值

3.放弃某次提交

1. git log // 查找需要撤销的 commit_id
2. git revert commit_id  // 撤销这次提交

web端,移动端响应式布局

  • 媒体查询
  • 百分比
  • vw/vh
  • rem
  • 利用UI框架实现响应式布局

一个页面可以嵌入几个webview

["1", "2", "3"].map(parseInt)的输出结果是什么

[1,NaN,NaN]

原因:

  • map方法接收一个callBack函数,第一个参数是当前处理的元素,第二个参数是索引值
  • parseInt是用来解析字符串,将字符串解析成指定基数的整数
  • radix是一个介于2-36之间的整数,返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回 NaN
parseInt(string, radix)

parseInt(‘1’, 0); // radix为0时,使用默认的10进制。
parseInt(‘2’, 1); // radix值在2-36,无法解析,返回NaN
parseInt(‘3’, 2); // 基数为2,2进制数表示的数中,最大值小于3,无法解析,返回NaN

React相关

vue和react有没有相互没有的优点

react render什么时候会执行

state和props数据更新的时候

React最新的两个生命周期

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

react和vue怎么做到强制刷新?

this.forceUpdate()

mobx和redux区别

列举React父子组件传值取值的方式

  • props
  • ref

React key的作用?

用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识

调用 setState 之后发生了什么?

  • React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程
  • 经过调和过程,React会以相对高效的方式根据新的状态构建React元素树并且着手重新渲染整个 UI 界面。
  • 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。
  • 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

触发多次setstate,那么render会执行几次

  • 多次setState会合并为一次render,因为setState并不会立即改变state的值,而是将其放到一个任务队列里,最终将多个setState合并,一次性更新页面。
  • 所以我们可以在代码里多次调用setState,每次只需要关注当前修改的字段即可 思考setState为什么是异步?
当批量执行state的时候可以让DOM渲染的更快,也就是说多个setstate在执行的过程中还需要被合并

this.setState之后react做了哪些操作?

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

简述一下virtual DOM (虚拟dom)如何工作?

  • 当数据发生变化,比如setState时,会引起组件重新渲染,整个UI都会以virtual dom的形式重新渲染
  • 然后收集差异也就是diff新的virtual dom和老的virtual dom的差异
  • 最后把差异队列里的差异,比如增加节点、删除节点、移动节点更新到真实的DOM上 diff算法相关

简述diff算法

从根结点开始遍历所有节点,将同级的节点进行对比,设置给对应老节点开始-结束的索引,新节点开始-结束的索引,进行遍历,更新位置,或是删除的一个过程

React 中 refs 的作用是什么?

<button ref="myBtn"></button>
  • 给元素定义ref属性,后续可以通过 this.refs.myBtn 来获取这个真实DOM对象
  • 给组件定义ref属性,后续可以通过 this.refs.myBtn 来获取这个组件的实例对象
<button ref="{ (sl) => { this.myBtn = sl } }"></button>
  • 给元素定义ref属性,后续可以通过 this.myBtn 来获取这个真实DOM对象
  • 给组件定义ref属性,后续可以通过 this.myBtn 来获取这个组件的实例对象

为什么列表循环渲染的key最好不要用index?

当key值对应的子元素相同时,不删除并更新,只做移动操作;当key值对应的子元素不同,就删除并重新创建,影响性能

什么是状态提升

状态提升,即将两个组件需要共享的数据保存在共同的父组件中,然后子组件通过 props 获取父组件数据

useCallback useMemo

提高性能

useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都返回缓存的值,useMemo返回缓存的变量,useCallback返回缓存的函数

  • useMemo
  • useCallBack:通常而言,如果父组件更新了,子组件也会执行更新;我们可以借助useCallback来返回函数,然后把这个函数作为props传递给子组件;这样,子组件就能避免不必要的更新。 useMemo与useCallback使用指南

频繁设置setState优化

react-hooks

react的生命周期有哪些
  • componentWillMount
  • render
  • componentDidMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate
  • componentWillUnmount
useEffect包含的生命周期?

componentDidMount、componentWillUnmount、componentDidUpdate

react-hooks的优点
  • useEffect可以让相同逻辑在同一个地方进行处理
  • 更容易拆分组件
  • 不用考虑this指向
  • 更容易复用
react-hooks的Api

使用hooks需要注意的

react性能优化

react的优化方法,提升性能?

  • 使用key来帮助React识别列表中所有子组件的最小变化
  • 重写shouldComponentUpdate来避免不必要的dom操作
  • 组件尽可能进行拆分

props和state的区别

state:用来存储组件内的数据状态,可以通过setState来修改,只存在于有状态组件中

props:父子组件沟通的桥梁,子组件不能直接修改他,可以存在有或者无状态组件中

VUE相关

单页面应用的优缺点

1.优点

  • 页面内容改变不需要重新加载整个页面,获取数据也是异步,不会出现白屏现象
  • 良好的前后端分离
  • 减轻服务器压力

2.缺点

  • 首屏加载慢 解决方案:1.vue-router懒加载 2.使用CDN加速 3.异步加载组件 4.服务端渲染
  • 不利于SEO
  • 不适合大型项目

mvvm

双向数据绑定

v-model的原理

一方面modal层通过defineProperty来劫持每个属性,一旦监听到变化通过相关的页面元素更新。另一方面通过编译模板文件,为控件的v-model绑定input事件,从而页面输入能实时更新相关data属性值

vue常用的指令

v-if、v-show、v-for、v-on、v-bind、v-model

vue的生命周期有哪些?vue中props的值是在哪个生命周期拿到的

beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed

vue的计算属性和方法区别

  • 不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值,多次访问 getAge 计算属性会立即返回之前的计算结果,而不必再次执行函数
  • methods方法,每当触发重新渲染时,调用方法将总会再次执行函数

vue的事件修饰符有哪些

  • .prevent
  • .stop

vue子组件向父组件传值

prop向下传递,事件向上传递 $emit

route和router的区别

  • route对象表示当前的路由信息
  • router对象全局路由的实例

路由传值的两种方式

  • params
  • query

router-view注册

scoped及如何修改公共组件的样式

1.穿透scoped

<style scoped>
    外层 >>> 第三方组件 {
        样式
    }
</style>

2.再定义一个不含有scoped属性的style标签

为什么会出现修改数据,但是页面没有变化的情况?

  • Vue 无法检测对象 property 的添加或移除
  • Vue 不能检测通过数组索引直接修改一个数组项
  • Vue 不能监测直接修改数组长度的变化
  • 在异步更新执行之前操作 DOM 数据不会变化 解决方法 Vue.set,vm.$set

如何封装一个表单组件

后台做一个面包屑

import和require的区别

vuex,取vuex值的方法有哪些

vuex

  • state
  • mutations
  • getters 加工state成员给外界
  • actions:实际提交的是mutation,异步操作
  • modules 模块化状态管理
取值方式:
1.
computed:{
   count(){
      return this.$store.state.count
   }
}
2.
import { mapState } from"vuex"
computed:mapState({
    count : 'count',
    count1 : 'count1'
})

set get

两个互不相干的组件怎么调用对方的方法

$emit $on

nextTick的原理,怎么修改表单数据

nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

vue组件缓存原理

webpack的性能配置 热更新

git项目上的运用

pwa

前端开发有哪些优化问题