迟到的大厂前端面试记录(面试题+部分答案)

10,543 阅读18分钟

本人简要介绍:本科工作两年,之前工作中主要用vue(所以没什么react相关的面试题)。以下均为今年八月初到九月中所经历的面试,现已上岸。前端小白,所写内容如有问题欢迎指正(鞠躬🙇‍♀️),期待一起讨论一起成长~

字节 非中区商业化一面面经

  1. Vue的父子组件传值有哪些方法?详细谈谈。

  2. 手写EventEmitter,实现on/emit/off方法。

  3. Vue的响应式原理。

  4. 既然刚刚聊到响应式原理,那么下面的代码中,一开始foo=true,接着foo=false,这之后再修改a=123,页面会不会重新render?

    <template>
    <div v-if=foo>
    {{ a }}
    </div>
    <div v-else>
    {{ b }}
    </div>
    </tempate>
    
  5. 了解预检请求preflight吗?展开谈谈。

  6. webpack的工作流程了解吗?

  7. 刚刚提到了plugin,现在有两个plugin,plugin1可以派发事件让plugin2监听吗?

  8. 一道事件循环代码题

    async function async1(){
      console.log('async1 start')
      await async2()
      console.log('async1 end')
    }
    async function async2(){
      console.log('async2')
    }
    console.log('script start')
    setTimeout(function(){
      console.log('setTimeout') 
    },0)  
    requestAnimationFrame(function(){
        console.log('requestAnimationFrame') 
    })
    async1();
    new Promise(function(resolve){
      console.log('promise1')
      resolve();
    }).then(function(){
      console.log('promise2')
    })
    
  9. 算法题:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。例如,输入abcabcbb,那么无重复字符的最长子串是 abc,长度为 3

字节 非中区商业化二面面经

  1. 介绍一下https。

  2. 知道https中的http请求怎么处理吗?

  3. 了解http2的特性吗?

  4. 刚刚提到http2有服务器推送功能。http2与websocet都有服务器推送的功能,那么websocket会被http2取代吗?为什么?

  5. 使用Array的reduce方法实现map。

    Array.prototype.myMap(fn,_this) {
       let result = [];
       this.reduce((prev,cur,index,arr) => {
           result[index] = fn.call(_this,arr[index],index,arr);
       },0)
       return result;
    }
    
    //arr.map((item,index,arr) => fn(item),_this);
    //arr.reduce((prev,cur,index,arr) => {},start);
    
  6. 事件循环题

    async function f1() {
        return new Promise((resolve) => {
            console.log(4)
            resolve()
        }).then(() => {
            console.log(5)
        })
    }
    async function run() {
        console.log(1)
        new Promise((resolve) => {
            console.log(2)
            resolve()
        }).then(() => {
            console.log(3)
        })
        await f1()
        setTimeout(() => {
            console.log(6)
        }, 0)
        console.log(7)
    }
    run()
    
  7. 给定一个二进制数组, 找到含有相同数量的0和1的最长连续子数组的长度,例如[0,0,0,1,1,0,1,0,0]=>6

    //先写了个暴力
    // function test(arr) {
    //     let maxLen = 0;
    //     for(let i=0; i<arr.length; i++) {
    //         for(let j=i+1; j<arr.length; i++) {
    //             let temp = arr.slice(i,j+1);
    //             let count0 = 0,count1 = 0;
    //             temp.forEach(item => {
    //                 if(item == 0) {
    //                     count0++;
    //                 } else {
    //                     count1++;
    //                 }
    //             })
    //             if(count0 == count1) {
    //                 maxLen = Math.max(maxLen, j - i + 1);
    //             }
    //         }
    //     }
    //     return maxLen;
    // }
    
    //前缀和
    function test(arr) {
        let len = arr.length;
        let map = new Map();
        let count = 0;
        let res = 0;
        //[0] -> 0
        for(let i=0; i<len; i++) {
            count += arr[i] == 1 ? 1 : -1;
            if(map.has(count)) {
                res = Math.max(res,i-map.get(count));
            }else {
                map.set(count,i);
            }
         }
        return res;
     }
    console.log(test([0, 0, 0,1, 1, 0,1, 0, 0]));
    

字节 非中区商业化三面面经

记不太清了,当时觉得面得一般就没记录题目,三面完泡在池子快一星期才被捞起来23333

  1. deepclone

  2. vue-router有几种模式?有什么区别?history模式下404后台应该配置什么?

  3. 算法题:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    var maxSubArray = function(nums) {
        // let res = nums[0];
        // let sum = 0;
        // for(let num of nums) {
        //     if(sum > 0) {
        //         sum += num;
        //     } else {
        //         sum = num;
        //     }
        //     res = Math.max(res,sum);
        // }
        // return res;
        // let res = nums[0];
        // let tep = 0;
        // nums.forEach(num => {
        //     tep = Math.max(num+tep,num);
        //     res = Math.max(res,tep);
        // })
        // return res;
    
        let n = nums.length;
        if(n == 0) return 0;
        let dp = new Array(n);
        dp[0] = nums[0];
        for(let i = 1; i < n; i++) {
            dp[i] = Math.max(nums[i], dp[i-1]+nums[i]);
        }
        let res = dp[0];
        for(let i = 0; i < dp.length; i++) {
            res = Math.max(res,dp[i]);
        }
        return res;
    };
    

Shopee food一面面经

  1. 一道闭包输出的问题。

  2. 写一个防抖。你现在写的是非立即执行的版本,可以再写一个立即执行的版本吗?

  3. 一道事件循环代码输出的题,并说出理由。

  4. 介绍一下跨域。

  5. 介绍一下预检请求。

  6. 算法题:将对象的属性全部提升到第一层。

function transfor(obj,stack,result) {
    for(let key in obj) {
        if(parseInt(key).toString() == 'NaN') {
            stack.push(key);
        } else {  
            stack.push(`[${key}]`);
        }
        if(typeof obj[key] == 'object' && obj[key] !== null) {
            transfor(obj[key],stack,result);
        } else {
            let stackStr = stack.join('.');
            console.log(result)
            result[stackStr] = obj[key];
            stack.pop();
        }
    }
    return result;
}

let testObj = {
    a: {
        b: 1,
        c: [0, {d: 1}]
    }
}

console.log(transfor(testObj,[],{}))
  1. 介绍一下vue的响应式原理

  2. a === 1 && a === 2什么情况下会出现

Shopee food二面面经

挂了,不知道为什么面试的时候表达欲望不强......问题没记,自己觉得比较感兴趣的才去了解了一下。

  1. 代码题:实现一个compose函数

  2. 虚拟列表的原理。 相关文章:聊聊前端开发中的长列表

    首先非完整渲染的长列表一般有两种方式:懒渲染以及可视区域渲染。

    懒渲染就是大家平常说的无限滚动,指的就是在滚动到页面底部的时候,再去加载剩余的数据,是一种前后端共同优化的方式,后端一次加载比较少的数据可以节省流量,前端首次渲染更少的数据速度会更快,这种优化要求产品方必须接受这种形式的列表,否则就无法使用这种方式优化。实现的思路非常简单:监听父元素的scroll事件(一般是window),通过父元素的scrollTop判断是否到了页面底部,如果到了页面底部,就加载更多的数据。如果要应用在生产上,建议使用成熟的类库,可以通过“框架名+infinite scroll”来进行搜索。

    可视区域渲染指的是只渲染可视区域的列表项目,非可见区域的完全不渲染,在滚动条滚动时动态更新列表项。可视区域渲染适合下面这种场景:

    • 每个数据的展现形式的高度需要一致(非必须,但是最小高度需要确定)。
    • 产品设计上,一次需要加载的数据量比较大(1000条以上),滚动条需要挂载在一个固定高度的区域(在windows上也可以,但是需要整个区域都只显示这个列表)。

    可见区域渲染列表的方式一般叫做Virtual List,即虚拟列表。什么是虚拟列表?先对虚拟列表做一个简单的定义。因为Dom元素的创建和渲染需要的时间成本很高,在大数据的情况下,完整渲染列表所需要的时间不可接受。其中一个解决思路就是在任何情况下只对可见区域进行渲染,可以达到极高的初次渲染性能。虚拟列表指的就是可视区域渲染的列表,重要的基本就是两个概念:

    • 可滚动区域:假设有1000条数据,每个列表项的高度是30,那么可滚动的区域的高度就是1000*30。当用户改变列表的滚动条的当前滚动值的时候会造成可见区域的内容的变更。
    • 可见区域:比如列表的高度是300,右侧有纵向的滚动条可以滚动,那么视觉可见的区域就是可见区域。

    实现虚拟列表就是处理滚动条滚动后的可见区域的变更,其中具体的步骤如下:

    1. 计算当前可见区域起始数据的startIndex;
    2. 计算当前可见区域结束数据的endIndex;
    3. 计算当前可见区域的数据,并渲染到页面中;
    4. 计算startIndex对应的数据在整个列表中的偏移位置startOffset,并设置到列表上。

    相关文章:「前端进阶」高性能渲染十万条数据(虚拟列表)

Shopee marketplace一面

和面试官很聊得来!

  1. 大数相加(比起leetcode上的题目稍微改了点,需要考虑有符号的情况:++/--/+-/-+)

  2. compose实现(老虾皮题了hh,和面试官反映之前面过这道题后面试官给换了题1)

  3. 事件总线实现

  4. js实现浅拷贝和深拷贝的区别

    相关文章:www.jb51.net/article/192…

    浅拷贝是按位拷贝对象,它会创建一个新对象,对原有对象的成员进行依次拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是引用类型,拷贝的就是内存地址。因此如果新对象中的某个对象成员改变了地址,就会影响到原有的对象。

  5. object.assign()是浅拷贝还是深拷贝?

    Object.assign()方法可以把源对象自身的任意多个的可枚举属性拷贝给目标对象,然后返回目标对象,但是Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。此方法对于Array和Object均可适用。Array.prototype.concat()和Array.prototype.slice()也为浅拷贝,只适用于Array。

  6. JSON.parse(JSON.stringify(obj))有什么不足之处?当object内存在循环引用时会报错吗?

    JSON.parse(JSON.stringify(obj))可以实现数组和对象和基本数据类型的深拷贝,但不能处理函数。因为JSON.stringify()方法是将一个javascript值转换我一个JSON字符串,不能接受函数。其他影响如下:

    • 如果对象中有时间对象,那么用该方法拷贝之后的对象中,时间是字符串形式而不是时间对象
    • 如果对象中有RegExp、Error对象,那么序列化的结果是空
    • 如果对象中有函数或者undefined,那么序列化的结果会把函数或undefined丢失
    • 如果对象中有NAN、infinity、-infinity,那么序列化的结果会变成null
    • JSON.stringfy()只能序列化对象的可枚举自有属性,如果对象中有是构造函数生成的,那么拷贝后会丢弃对象的constructor
    • 如果对象中存在循环引用也无法正确实现深拷贝,会报错
  7. 当object内存在循环引用时怎么进行深拷贝?

    相关文章:blog.csdn.net/weixin_3373…

    创建一个在整个函数执行期间一直存在的 Map 类型变量(Map 可以设置除 string 以外的类型作为 key,也是键值对的结构,这一点比 object 要灵活),每一次函数执行把这一轮传入的对象作为 key 新的创建对象作为值,在函数开头执行判断传入的对象是否已经存在 map 的 keys 中,如果存在那代表着传入的对象在之前已经遍历过了。

  8. 聊聊函数式编程。

    • 是一种编程风格、亦或是一种思维模式,和面向对象编程是并列关系
    • 抽象出细粒度的函数,可以组合为更强大的函数
    • 函数指的不是程序中的方法,而是数学中的映射关系
    • 相同的输入得到相同的输出
    • 函数式编程是运算过程的抽象

    函数式编程要求函数必须是纯的,不能有副作用。因为它是一种数学运算,原始目的就是求值,不做其他事情,否则就无法满足函数运算法则了。总之,在函数式编程中,函数就是一个管道(pipe)。这头进去一个值,那头就会出来一个新的值,没有其他作用。(详细可以看看阮一峰老师相关的文章)

  9. 聊聊mvvm和mvc的理解、区别。

    这个问题一直没有找到好的文章(或者是我能理解得比较深的= =),相关文章:juejin.cn/post/696198…

  10. 了解https吗?

  11. 说说http中的缓存机制

  12. 了解http2新特性吗?

  13. 了解浏览器的同源机制吗?谈谈你对跨域的理解。

  14. 了解浏览器中分层的优点吗?

  15. 谈谈你对作用域链的理解,闭包呢?

  16. 聊聊原型链,你觉得原型链这种形式有什么优点吗?

    说实话没什么优点。构造函数原型上的属性在所有该构造函数构造的实例上是共享的,即属性没有私有化,原型上属性的改变会作用到所有实例上。

  17. 箭头函数和普通函数的区别是什么?

    箭头函数没有自己的this对象。——对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。因此还有以下几种不同:

    • 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。(也是因为没有自己的this)
    • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。
    • 不可以使用yield命令,因此箭头函数不能用作generator函数。
    • 以下三个变量在箭头函数之中也是不存在的:arguments\super\new.target
    • 由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。
  18. js的值类型有几种?有什么区别?

    原始类型/引用类型。区别是值的存储方式的差别(栈、堆)。

  19. 有什么方法可以区分js的数据类型?

    typeof/instanceof/construtor/isPrototypeOf/Object.getPrototypeOf()/Object.prototype.toString.call()

    Number/String/Boolean/Null/undefined/Object/symbol/bigInt

  20. object.is()和===的区别了解吗?

    ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。

    ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。 object.is()在严格等于的基础上修复了一些特殊情况下的失误,具体来说就是+0和-0,NAN和NAN。

    if (x === y) {
        // 针对+0 不等于 -0的情况
        return x !== 0 || 1 / x === 1 / y;
      }
      // 针对NaN的情况
      return x !== x && y !== y;
    
  21. js的垃圾回收机制是怎样的?

    主要围绕v8的垃圾回收机制回答。

  22. es6 class和es5构造函数之间的区别与联系?

    基本上,ES6的class可以看作只是一个语法糖,它的绝大部份功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更加像面向对象编程的语法而已。class中有一个constructor()方法,这就是构造方法,而this关键字则代表实例对象。使用typeof可以发现,类的数据类型就是函数,类本身就指向构造函数,使用的时候,也是直接对类使用new命令,与构造函数的用法完全一致。构造函数的prototype属性,在es6的class上面继续存在。事实上,类的所有方法都定义在prototype属性上面。因此,在类的实例上面调用方法其实就是调用原型上的方法。由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign()方法可以很方便地一次向类添加多个方法。prototype对象的constructor()属性直接指向类本身,这与ES5的行为是一致的。但是,类的内部所有定义的方法,都是不可枚举的,这一点与ES5的行为不一致。类必须使用new调用,否则会报错,这是它跟普通构造函数的一个区别,后者不用new也可以执行。

    Object.keys(Point.prototype)
    // []
    Object.getOwnPropertyNames(Point.prototype)
    // ["constructor","toString"]
    

    具体文章·:es6.ruanyifeng.com/#docs/class

  23. js异步加载有哪几种方式?有何区别?

    defer:发生的时刻为整个页面全部解析完(dom树构建完)才会执行,ie9以下可用,可以将js代码写在内部

    async:加载完脚本就会执行,ie9以上都可以用,只能加载外部脚本,不能把js写在script标签里

    以上两者不能写在同一个标签里。

    如果要做到浏览器兼容可以使用script的onreadystatechange事件监听script的readyState状态(loading/complete/loaded),此方法ie可用;除了ie,别的浏览器可以监听script的onload事件设置设置回调函数。

  24. 事件处理模型了解吗?它们的先后顺序是怎样的?

    事件处理模型有事件捕获和事件冒泡。结构上(非视觉上)嵌套关系的元素,会存在事件捕获及事件冒泡功能,即同一事件,自子元素冒泡向父元素;自父元素捕获至子元素。触发顺序是先捕获后冒泡,注意事件触发的地方不存在冒泡和捕获,它只正常的事件执行,执行顺序依照代码书写顺序,focus、blur、change、submit、reset、select等事件不冒泡。

  25. 谈谈对requestAnimationFrame的理解

  26. cookie/localstorage/sessionstorage/indexDB之间的区别?

    相关文章:www.cnblogs.com/fundebug/p/…

  27. cookie有哪些可以设置的字段?

    相关文章:blog.csdn.net/qq_39834073…

    name和value:name和value是一个键值对。name是cookie的名称,cookie一旦创建,名称便不可修改,一般名称不区分大小写;value是该名称对应的cookie的值,如果值为unicode字符,需要为字符编码。如果值为二进制数据,则需要使用base64编码。

    Domain:Domain决定cookie在哪个域是有效的,也就是决定在向该域发送请求时是否携带此cookie。Domain的设置是对子域生效的,例如Domain设置为.a.com,则b.a.com和c.a.com均可以使用该cookie,但如果设置为b.a.com则c.a.com不可使用该cookie。Domain参数必须以点(“.”)开始。

    Path:Path是Cookie的有效路径,和Domain类似,也对子路径生效,如Cookie1和Cookie2的Domain均为a.com,但Path不同,Cookie1的Path为 /b/,而Cookie的Path为 /b/c/,则在a.com/b页面时只可以访问Cookie1,在a.com/b/c页面时,可访问Cookie1和Cookie2。Path属性需要使用符号“/”结尾。

    Expires/Max-age: Expires和Max-age均为Cookie的有效期,Expires是该Cookie被删除时的时间戳,格式为GMT,若设置为以前的时间,则该Cookie立刻被删除,并且该时间戳是服务器时间,不是本地时间!若不设置则默认页面关闭时删除该Cookie。Max-age也是Cookie的有效期,但它的单位为秒,即多少秒之后失效,若Max-age设置为0,则立刻失效,设置为负数,则在页面关闭时失效。Max-age默认为 -1。

    Size:Szie是此Cookie的大小。在所有浏览器中,任何cookie大小超过限制都被忽略,且永远不会被设置。各个浏览器对Cookie的最大值和最大数目有不同的限制,整理为下表(数据来源网络,未测试):

    浏览器Cookie最大条数Cookie最大长度/单位:字节
    IE504095
    Chrome1504096
    FireFox504097
    Opera304096
    Safari无限 4097

    HttpOnly: HttpOnly值为 true 或 false,若设置为true,则不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见,但在发送请求时依旧会携带此Cookie。

    Secure: Secure为Cookie的安全属性,若设置为true,则浏览器只会在HTTPS和SSL等安全协议中传输此Cookie,不会在不安全的HTTP协议中传输此Cookie。

    SameSite: SameSite用来限制第三方 Cookie,从而减少安全风险。它有3个属性,分别是:Scrict最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie;Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外;

    None,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。关闭SameSite的方法:操作方法谷歌浏览器地址栏输入:chrome://flags/找到:SameSite by default cookies、Cookies without SameSite must be secure设置上面这两项设置成 Disable。

    Priority:优先级,chrome的提案,定义了三种优先级,Low/Medium/High,当cookie数量超出时,低优先级的cookie会被优先清除。在360极速浏览器和FireFox中,不存在Priority属性,不清楚在此类浏览器中设置该属性后是否生效。

  28. css的匹配顺序了解吗?

    css的匹配顺序是从右向左。因为从右到左会更加高效。

  29. vue3有了解吗

二面内容没印象了。

富途三面面经

一面二面没什么印象了,富途不怎么写算法,但基本上每面都有智力题/代码题。不太给得起涨幅

  1. 智力题:猴子吃桃子
  2. 概率题:扑克牌概率
  3. 代码题:切分url取出参数
  4. 介绍一下浏览器xss攻击和xsrf攻击
  5. 介绍一下防抖和节流的区别

crypto一面面经

猎头介绍是做区块链的公司,每年20+年假。面试前做了一场5道算法题的笔试才发的面试通知,一面面试下来感觉面试官挺有水平,but由于个人原因放弃了后面的面试。

  1. flex/grid了解吗;如何实现自适应布局(多个块间隔相同)
  2. 了解css层叠上下文吗?子元素设置了position:fixed的时候相对于什么定位,当父元素设置了translate的时候,子元素又相对于什么定位?
  3. 介绍一下跨域和预检请求;
  4. 介绍一下xmlhttprequest的步骤;
  5. 介绍一下es6模块与commonjs模块的差异;
  6. 介绍一下事件循环,微任务的一个执行时间点了解吗?
  7. 介绍一下http中的缓存处理机制。了解expires有什么缺点吗?expires中存放的是什么数据类型?cache-contorl的max-age中存放的又是什么数据类型?协商缓存讲一讲?
  8. map和weakmap的区别了解吗;
  9. 介绍一下你对前端工程化的理解;

一些面试题整理

之前记录的时候只记了少部分印象比较深的题目,也忘记记公司了,下面的题目大部分来自于平安/微众/百度。btw,百度的面试体验个人觉得非常好,微众有个性格测评大家一定要好好做(三面过了后被猎头告知性格测评挂了一年无法捞起的痛谁懂),平安就不说了......

  1. promise,async/await的区别,使用场景

  2. 原型链/继承

    原型链是实现继承的主要方法,其思想是利用原型让一个引用类型继承另一个引用类型的属性和方法,如果我们让一个原型对象等于另一个类型的实例,那么该原型对象就会包含指向另一个原型的指针,而如果另一个原型对象又是另一个原型的实例,那么上述关系依然成立,层层递进,就构成了实例与原型的链条,这就是原型链的概念。

    继承:原型链继承、构造函数继承、组合继承、原型式继承(object.create())寄生组合式继承、class类

  3. function上的方法有哪些?call/apply/bind了解吗?手写能否写出?

    //call
        Function.prototype.myCall = function(context, ...arr) {
          if(context === null || context === undefined) {
            context = window;
          } else {
            context = Object(context);
          }
          const fn = Symbol('fn');
          context[fn] = this;
          let result = context[fn](...arr);
          delete context[fn];
          return result;
        }
    
    
        //bind
        Function.prototype.myBind = function(objThis,...params) {
          let thisFn = this;
          let fToBind = function(...secondParams) {
            let isNew = this instanceof fToBind;
            let context = isNew ? this : Object(objThis);
            return thisFn.call(context,...params,...secondParams);
          }
          if(thisFn.prototype) {
            fToBind.prototype = Object.create(thisFn.prototype);
          }
          return fToBind;
        }
    
  4. 讲一下http缓存处理机制?强制缓存协商缓存返回的状态码分别是?了解expires有什么缺点吗?expires中存放的是什么数据类型?cache-contorl的max-age中存放的又是什么数据类型?

    http缓存分为强制缓存和协商缓存,其中强制缓存:http1.0——expired,http1.1——cache- control:private/public/no-cache/no-store/max-age。协商缓存:http1.0——last-modified(响应头)/if-modify-since(请求头), http1.1——etag(响应头)/if-none-match(请求头)。expires和max-age都可以用来指定文档的过期时间,但两者有一些细微差别。expires中存放的是一个绝对的过期时间,这么做会导致至少2个问题:1.客户端和服务器时间不同步导致expires的配置出现问题;2.很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象;max-age指定的是从文档被访问后的存活时间,这个时间是个相对值(比如3600s),相对的是文档第一次被请求时服务器记录的request_time(请求时间)。另外,expires指定的时间其实可以是相对文件的最后访问时间(atime)或者修改时间(atime)。

  5. 谈谈tcp三次握手四次挥手。

  6. vue修饰符有哪些?

    事件修饰符:stop、prevent、capture、self、once、passive

    按键修饰符:enter、tab、delete、esc、space、down、up、left、right、exact

    鼠标修饰符:left、right、middle

    sync

    表单修饰符:lazy、number、trim

  7. 常见的http请求头

    例如缓存系列请求头,accept系列请求头(accept,accept-encoding,accept-Charset,accept-language),user-agent,host,cookie,connection,origin,referer,

  8. 一个页面有多个表单,提交的时候怎么解决校验

    可以使用promise.all

  9. 一维数组构建树结构

function getTree() {
  let map = new Map();
  arr.forEach(item => {
    map.set(item.id,item);
  })
  let tree;
  arr.forEach(node => {
    let parent = map.get(node.parentId);
    if(parent) {
      if(!parent.children) {
        parent.children = [];
      }
      parent.children.push(node);
    } else {
      tree.push(node)
    }
  })
  return tree;
}
  1. web安全相关,为什么带上token就不会有csrf的问题?

    cookie有一个过期时间,在这段时间内,cookie是存储在客户端的,当再次访问相同的网站时,浏览器会自动在http请求中自动带上该网站用户登录后的cookie。csrf攻击也正是利用这点,借用用户的cookie去执行非用户本意的操作。而token验证的规则是,服务器从请求体或者请求参数重获取设置的token,然后和cookie中的token进行比较,一致则进行后续请求,而csrf攻击只是借用了cookie,也就不能在发送请求时在post或get中设置token,把请求发送到服务器端时,token验证不通过,也就不会处理请求了。(存疑)

  2. vue的模版编译怎么拿到响应式数据

  3. webpack的插件并行还是串行?webpack工作流程及原理讲讲?plugin1可以派发事件让plugin2监听吗?

  4. computed里的函数怎么收集到里面使用所有变量的依赖?watch里面呢?

  5. 有了解过别的生态吗?例如react,小程序为什么那么设计,rn,flutter

  6. 现在webpack中配置了哪些插件?

  7. vue项目里要写jsx要配置什么loader?

  8. 正则了解吗?

  9. webpack热更新原理

有些问题的答案并不是很清晰,欢迎大家一起讨论!