前端面试常见问题-持续更新

一、html&css

1.html5新增的标签属性

2.css3新增的属性

3.position定位

4.浮动

5.盒子模型

6.margin问题

7.display的属性值

8.background属性值

9.px、rem、em的区别

10. css动画和js动画的区别

     1.js是帧动画,当js在浏览器主线程运行时,主线程还有其他需要运行的js脚本、样式、计算、布局、交互等一系列任务,对其干扰线程可能出现阻塞,造成丢帧的情况。

     2. js动画通过js引擎解析,css通过 GUI渲染,效果更流畅

二、js相关问题

1.js的基本数据类型和引用数据类型

2.const,let,val的区别

3.说说作用域

在es6的let和const推出之前,js并没有块作用域的概念,只有全局作用域和函数作用域。

4.instanceof和typeof 的区别

5.隐式转换有哪些

6.闭包

7.原型和原型链

(1)、原型

      任何对象都有一个原型对象除了null,这个原型对象由对象的内置属性_proto_指向它的构造函数的prototype

      即任何对象都是由一个构造函数创建的,但是,不是每一个对象都有prototype,只有方法才有prototype。

 (2)、什么是原型链?

      原型链的核心就是依赖对象的_proto_的指向,当查找自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有_proto_指向了。

        因为_proto_实质找的是prototype,所以我们只要找这个链条上的构造函数的prototype。其中Object.prototype是没有_proto_属性的,它==null。

(3)、原型链查找分析:

        当访问一个对象的成员的时候,会先在自身找有没有,如果找到直接使用。

        如果没有找到,则去原型链指向的对象的构造函数的prototype中找,找到直接使用,没找到就返回undifined或报错。

    function Person(name){

      this.name = name;

    }

    var p = new Person();

    p ---> Person.prototype --->Object.prototype---->null


8.call和apply的区别

9.new干了什么

10.this的指向

11.箭头函数

相对于普通函数的区别,新的书写方式 ,this 的改变,不能当构造函数,没有 prototype 属性,没有 arguments 对象

讨论箭头函数的 this 之前,不得不再熟悉一下 执行上下文(Execution Context),因为 this 指针(this value) 就存储在执行上下文中。

    执行上下文保存着函数执行所需的重要信息,其中有三个属性:变量对象(variable object),作用域链(scope chain),this指针(this value),它们影响着变量的解析、变量作用域、函数 this 的指向。执行上下文分为 全局执行上下文 和 函数执行上下文。

    函数预编译的 this 分下面四种情况:

        第一种: 函数自主调用 如 fun() 或者是 普通的立即执行函数(区别于箭头函数方式的立即执行函数), this 指向 window;

        第二种: 函数被调用,当函数被某个对象调用时,函数产生的执行上下文中的 this 指向 该对象;

        第三种: 通过 call() apply() bind() 方法改变 this,this 指向被传入的 第一个参数;

        第四种: 在构造函数中,this 指向被创建的 实例

        箭头函数不会创建自己的 this,它只会从自己的作用域链上找父级执行上下文的 this

        *由于箭头函数是不能通过 call() apply() bind() 方法改变 this,也不能当做构造函数

12.setTimeout、Promise、async/await 三者之间异步解决方案的区别?

13.实现节流和防抖

function throttle(fn){

            let can = true;

            return function(){

                if(!can)return;

                can = false;

                setTimeout(() => {

                    fn.apply(this,arguments);

                    can = true

                }, 2000);

            }

        }

function debounce(fn) {

    let timeout = null; // 创建一个标记用来存放定时器的返回值

    return function () {

      clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉

      timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数

        fn.apply(this, arguments);

      }, 500);

    };

  }

14.对象深拷贝

function deepClone(source){

        const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象

        for(let keys in source){ // 遍历目标

            if(source.hasOwnProperty(keys)){

            if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下

                targetObj[keys] = source[keys].constructor === Array ? [] : {};

                targetObj[keys] = deepClone(source[keys]);

            }else{ // 如果不是,就直接赋值

                targetObj[keys] = source[keys];

            }

            }

        }

        return targetObj;

    } 

15.setTimeout在跳转页面之后是否还会继续执行

16.多页面还单页面的区别

17.说一下设计模式有哪些

19.http缓存原理

20.常见的状态码有哪些

21.js事件流

22.get,post的区别

 1.post更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中)

 2.post发送的数据量更大(get有url长度限制)

 3.post能发送更多的数据类型(get只能发送ASCII字符)

   4.post支持4种提交格式

    application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml

最重要的一条,post在真正接受数据之前会先将请求头发送给服务器进行确认,然后才真正发送数据

  post请求的过程:

  1.浏览器请求tcp连接(第一次握手)

  2.服务器答应进行tcp连接(第二次握手)

3.浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

  4.服务器返回100 continue响应

  5.浏览器开始发送数据

  6.服务器返回200 ok响应


get请求的过程

    1.浏览器请求tcp连接(第一次握手)

  2.服务器答应进行tcp连接(第二次握手)

  3.浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)

  4.服务器返回200 ok响应

23.js事件循环机制,宏任务与微任务有哪些

常见的微任务有Promise、process.nextTick、MutationObserver

常见的宏任务:script、setTimeout、setInterval、setImmediate

发出疑问:到底是宏任务优先还是微任务优先?(个人观点:微任务优于宏任务)

Event Loop执行顺序为:

先执行宏任务script,并执行里面的同步任务;执行栈为空后查询是否存在微任务,存在就立即执行,然后开始下一轮的事件循环

24.实现响应式数据

var oldArrayProto = Array.prototype;

    var arrProto = Object.create(oldArrayProto);

    ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {

        arrProto[methodName] = function () {

            console.log("进来额")

            update() // 触发视图更新

            oldArrayProto[methodName].call(this, ...arguments)

        }

    })

    function update(val) {

        console.log("数据发生了变化",obj.nums);

    }

    function define(target,key,value){

        observer(value)

        Object.definePrototype(target,key,{

            get(){

                return value;

            },

            set(val){

                if(val !== value){

                    value = val;

                    observer(value);

                    update()

                }

            }

        })

    }

    function observer(obj){

        if(typeof obj !== 'object' || obj === null) {

            reutrn obj;

        }

        if(Array.isArray(obj)){

            obj._proto_ = arrProto;

        }

        for(let key in obj){

            define(obj,key,obj[key]);

        }

    }

25. 0.1+0.2 = ?  js为什么会有精度问题?

JS 数字类型只有number类型,number类型相当于其他强类型语言中的double类型(双精度浮点型),不区分浮点型和整数型。

number 有四种进制表示方法,十进制,二进制,八进制和十六进制

由于Js的所有数字类型都是双精度浮点型(64位)采用 IEEE754 标准

计算机中的数字都是以二进制存储的,如果要计算 0.1 + 0.2 的结果,计算机会先把 0.1 和 0.2 分别转化成二进制,然后相加,最后再把相加得到的结果转为十进制,0.1 和 0.2 在转换为二进制时就发生了一次精度丢失,而对于计算后的二进制又有一次精度丢失 。

26. try catch的作用域

27.获取url ?后的参数

28.jquery的链式调用和promise的链式调用

    jquery的方法都是挂在在原型上的,每次调用内部方法会返回this,返回当前的实例对象

    promise的then,每次都会返回一个新的promise

29.async 和defer的区别

    <script>标签打开defer或async属性,脚本就会异步加载。渲染引擎遇到这一行命令,就会开始下载外部脚本,但不会等它下载和执行,而是直接执行后面的命令。

defer与async的区别是:defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

30.前端性能优化:

        从2个方面来说 1.资源加载优化 2.页面渲染优化

        一:资源加载优化

            (1).减少http请求次数

                合并请求-http缓存-本地缓存-service worker

            (2).减少资源大小

                代码压缩-gzip压缩-图片压缩-代码拆分

            (3).提高http请求响应速度

                cdn,dns,http2

            (4).优化资源加载时机

                按需加载-懒加载-预加载

            (5).优化资源/内容加载方式

                客户端内h5离线化包

        二: 页面渲染优化

            (1).优化html代码

                js外链放在底部-css外链放在顶部-减少dom数量

            (2).优化js/css代码

                长任务分片执行-减少重排重绘-降低css选择器复杂性

            (3).优化动画效果

                使用css动画代替js动画

31.DNS预解析(dns-prefetch)

        通过 DNS 预解析来告诉浏览器未来我们可能从某个特定的 URL 获取资源,当浏览器真正使用到该域中的某个资源时就可以尽快地完成 DNS 解析。

        第一步:打开或关闭DNS预解析

            你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头。或是在文档中使用值为 http-equiv 的meta标签:

            <meta http-equiv="x-dns-prefetch-control" content="on">

            需要说明的是,在一些高级浏览器中,页面中所有的超链接(<a>标签),默认打开了DNS预解析。但是,如果页面中采用的https协议,很多浏览器是默认关闭了超链接的DNS预解析。如果加了上面这行代码,则表明强制打开浏览器的预解析。

        第二步:对指定的域名进行DNS预解析

            如果我们将来可能从 smyhvae.com 获取图片或音频资源,那么可以在文档顶部的 标签中加入以下内容:

            <link rel="dns-prefetch" href="http://www.smyhvae.com/">

            当我们从该 URL 请求一个资源时,就不再需要等待 DNS 解析的过程。该技术对使用第三方资源特别有用。

32.预加载

    1.Prerendering pages

        预先渲染页面,这是更牛的预加载方式了,他的作用就类似打开一个隐藏的tab差不多:

        <link rel=”prerender” href=”http://css-tricks.com”>

    2.Preloading

        和prefetching不同的是,preloading会让浏览器无论如何都下载指定的资源:

        <link rel=”preload” href=”image.png”>

    3.H5音乐预加载 preload=”auto”

        <audio src=”music.mp3″ autoplay=”autoplay” loop preload=”auto” id=”sendid2″></audio>

33.JavaScript中使用局部变量是否比使用全局变量高效?

    当读取一个变量的时候,就会从当前域中(具体说,是当前执行上下文的活动对象,Active Object)中查找这个变量,查找不到就继续往上找,直到全局。查找层级少,所以快。

34.位与位或

先把10进制数转成二进制,然后二进制从个位开始依次比对 位与& 都对true为1 不对false为0;位或|如果不相等取后面的数,如果相等取1 

    10 & 15

    1010  &  1111

    比对后得1010 

    10 | 15

    1010  |   1111

    比对后得1111

35. 离线功能对比:service worker和applicationCache

        appCache仅仅在离线的时候才能发挥用处(无法解决网络慢的用户体验问题),而SW不是,可以通过拦截请求,并且返回合适的数据,如果发现网络较慢。

36. 收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢?

如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用 HTTP2,如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输。不过也未必会所有挂在这个域名的资源都会使用一个 TCP 连接去获取,但是可以确定的是 Multiplexing 很可能会被用到。

如果发现用不了 HTTP2 呢?或者用不了 HTTPS(现实中的 HTTP2 都是在 HTTPS 上实现的,所以也就是只能使用 HTTP/1.1)。那浏览器就会在一个 HOST 上建立多个 TCP 连接,连接数量的最大限制取决于浏览器设置,这些连接会在空闲的时候被浏览器用来发送新的请求,如果所有的连接都正在发送请求呢?那其他的请求就只能等等了。

37.前端如何解决跨域的?

    1. 跨域资源共享cors

        服务端设置Access-Control-Allow-Origin:浏览器请求头的orgin信息/ * ,代表允许指定的请求来访问或者允许所有请求都可访问

    2. jsonp

       jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。

         缺点:不安全,只支持get

  3.nginx反向代理

        通过Nginx配置一个代理服务器域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域访问

4.vue proxy

利用webpack-dev-serve,webpack-dev-server是一个采用Node.js Express实现的微型服务器, 利用他来做代理在本地开启一个服务器,同源策略仅是针对浏览器的安全策略。因此服务器之间也就不存在跨域问题。

5.postMessage跨域

 postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一,它可用于解决以下方面的问题: 页面和其打开的新窗口的数据传递、多窗口之间消息传递、页面与嵌套的iframe消息传递、上面三个场景的跨域数据传递

6. WebSocket协议跨域

    WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

38. 小程序如何在app里运行的,如何在多端app里运行?

        App 里包含 javascript 运行引擎,比如用户点击打开一个小程序,微信App从微信服务器下载这个小程序,分析 app.json 得到应用程序的配置信息(导航栏,窗口样式,包含的页面列表等)

        加载并运行 app.js,展示在 app.json 里配置的第一个页面,会调用app原生的接口

        多端运行,通过嵌套webview来实现。

39. 为什么javascript是解释型语言

解释型语言:不需要事先编译,通过解释器一边解释一边执行,启动快,但执行慢。

因为javascript是弱类型语言,我们不需要关心它的类型,并且可以随意的修改,无法像c++那样可以事先提供足够的信息供编译器编译出更加低级的机器代码,它只能在运行阶段收集类型信息,然后根据这些信息进行编译再执行,所以javascript是解释型语言。

三、vue相关

       1.vue的nextTick方法的实现原理:

          首先修改数据,这是同步任务。同一事件循环的所有的同步任务都在主线程上执行,形成一个执行栈,此时还未涉及 DOM 。

           同步任务执行完毕,开始执行异步 watcher 队列的任务,更新 DOM 。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel 方法, 如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。

       2.Vue.use() 有什么作用

            Vue.use(),会调用install方法,让它里面被注册的组件能够被全局使用。

       3.vue组件中的data为什么是函数

             为了保证组件的独立性 和 可 复用性,data 是一个函数,组件实例化的时候这个函数将会被调用,返回一个对象,计算机会给这个对象分配一个内存地址,你实例化几次,就分配几个内存地址,他们的地址都不一样,所以每个组件中的数据不会相互干扰,改变其中一个组件的状态,其它组件不变。

      4.vue-router的两种模式区别

        hash模式的工作原理是hashchange事件,可以在window监听hash的变化

        window.onhashchange = function(event){

            console.log(event);

        }

            history模式,这种模式充分利用 history.pushState API 来完成 通过pushState和replaceState修改浏览器的历史状态,

    区别: hash模式需要加#,history需要nginx配置,如果history刷新找不到路径会出错,hash模式不会

    5. 子组件为什么不可以修改父组件传递的Prop

        Vue是单向数据流,这样来防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解,如果破坏了单向数据流,当应用复杂时,debug 的成本会非常高

   6. vue 是如何监控到上述情况并给出警告的

        在vue 底层,做了一个类似全局标记Flag;它的实现原理,还是Object.defineProperty()API,window.isUpdatingChildComponent = false; 相当于一个Flag;只有当在父组件中修改传递给子组件的Prop值的时候,才会被赋值为True; 在子组件Proxy.vue 中代理父组件传递的Prop值; 使用 this.$forceUpdate(); 强制更新; 这时候,触发代理中的setter;提示不可以在子组件中直接修改父组件传递的Prop值的警告;

7.Vuex 的 mutation 中为什么 不能做异步操作?

    Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

8. vue编译原理:

整体逻辑分为三个过程:

    1.将模板字符串转换成element ASTs(解析器)

    2.对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)

    3.使用element ASTs生成render函数代码字符串(代码生成器)

    Vue源码中虚拟DOM构建经历 template编译成AST语法树 -> 再转换为render函数 最终返回一个VNode(VNode就是Vue的虚拟DOM节点)

9. Vue父子组件,哪个生命周期是子组件先执行的父组件后执行的?

mounted,因为只有所有的子组件全部加载完毕,父组件才能触发mounted

四、webpack

     webpack的loader顺序,为什么?

        webpack选择了函数式编程的方式,所以loader的顺序编程了从右往左

    webpack loader和plugin的区别

       loader: 更像是转换器 像babel-loader,scss-loader style-loader file-loader,

      plugin: 插件压缩文件,分割文件等改变输出的结果

五、项目亮点

一、抢券兜底策略:

    1.首先是当巨大流量进入到这个页面,会不会引发cdn等资源/接口加载失败?

    2.抢的策略,倒计时结束点击按钮发送接口

    针对1的解决方法:1.利用缓存策略减少http请求 2.在每台机器上配置静态资源当cdn资源挂掉的时候访问切换域名路径成当前机器的,

    SSI就是在HTML文件中,可以通过注释行调用的命令或指针。

    针对2的解决方案:用户疯狂点击按钮,为了避免服务器挂掉可以采用防抖策略 1.比如一段时间内只允许发起一次请求,2.设置开关,在上一次请求有所返回时才进行下一次请求

    3.永远只发送一次请求

    如何防止脚本恶意刷抢,可以弹起验证框校验

六、算法

       1.二分查找

function binary_search(arr, key) {

            var left = 0,

                right = arr.length - 1;

            while(left <= right){

                var mid = parseInt((right + left) / 2);

                if(key == arr[mid]){

                    return  mid;

                }else if(key > arr[mid]){

                    left = mid + 1;

                }else if(key < arr[mid]){

                    right = mid -1;

                }else{

                    return -1;

                }

            }

        };

        var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];

        var result = binary_search(arr,10);

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容