跳槽人速来,记录一下大厂的前端面经

1.算法题:实现一个连接,能够新增节点,删除节点

function insert(head, n ,val) {
    var node = {
        val: val,
        next: null
    }
    if (head == null) {
        return node
    }
    if (n === 0) {
        node.next = head;
        return node;
    }

    var p = head;
    for(var i=0; i<n-1; i++){
        p = p.next;
    }
    node.next = p.next;
    p.next = node;
    return head;
}
复制代码
function remove(head, n) {
    if (!head) {
        return null;
    }
    if (head === 0) {
        return head.next;
    }
    var p = head;
    for(var i=0; i<n-1; i++) {
        p = head.next;
    }
    p.next = p.next.next;
    return head;
}
复制代码

2.实现一个instanceof方法

function myInstanceOf(left, right) {
    if (typeof left !== 'object' || left == null) {
        return false;
    }
    
    let pro = Object.getPrototypeOf(left);
    while(true) {
        if (pro === null) {
            return false;
        }
        if (pro === right.prototype) {
            return true;
        }
        pro = Object.getPrototypeOf(pro);
    }
}
复制代码

3.响应式布局怎么实现 rem布局 flex布局

remcss

(function(doc, win) {
   var docE1 = doc.documentElement,
       resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
       recalc = function() {
           var clientWidth = docE1.clientWidth;
           if (!clientWidth) return;
           docE1.style.fontSize = clientWidth / 7.5 + 'px';
       }
   
   if(!doc.addEventListener) return;
   win.addEventListener(resizeEvt, recalc, false);
   doc.addEventListener('DOMContentLoaded', recalc, false);  
})(document, window)
复制代码

4.事件循环机制

  • 1.一开始整段脚本做为第一个宏任务执行
  • 2.执行过程当中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
  • 3.当前宏任务执行完出队,检查微任务队列,若是有则依次执行,直到微任务队列为空
  • 4.执行浏览器 UI 线程的渲染工做
  • 5.检查是否有Web worker任务,有则执行
  • 6.执行队首新的宏任务,回到2,依此循环,直到宏任务和微任务队列都为空

5.设计模式:观察-订阅者模式 与 观察者模式的区别

6. https过程

HTTPS协议=HTTP协议+SSL/TLS协议,数据传输的过程当中,须要使用SSl/TLS协议对数据进行加密和解密,须要用HTTP对加密后的数据进行传输,由此能够看出HTTPS是由HTTP和SSL/TLS一块儿合做完成的。html

  • HTTPS为了兼顾安全与效率,同时使用了对称加密和非对称加密。
  • 数据是被对称加密传输的,对称加密过程须要客户端的一个密钥, 为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,
  • 总的来讲,对数据进行对称加密,对称加密所要使用的密钥经过非对称加密传输。

为何要使用对称加密?

缘由:非对称加密基于大数运算,好比大素数或者椭圆曲线,是复杂的数学难题,因此消耗计算量,运算速度慢。除了慢,可能还有一个缺点就是须要更多的位数,相同强度的对称密钥要比非对称密钥短。对称密钥通常都128位、256位,而rsa通常要2048位,不过椭圆曲线的会短一点前端

7.http2的优化点

  1. 头部压缩: 采用HPACK算法,在客户端和服务端两端创建“字典”,用索引号表示重复的字符串, 还采用哈夫曼编码来压缩整数和字符串,能够到达50%-90%的高压缩率。vue

  2. 多路复用: 采用二进制分帧传输,不存在前后关系, 所以也就不会有等待排队,也就没有了HTTP 的对头阻塞问题。 通讯双方均可以给对分发送二进制帧, 这种二进制帧的双向传输的序列,也叫作流。 HTTP/2用流来在一个TCP链接上来进行数据帧的通讯, 这就是多路复用的概念。node

  3. 设置请求优先级: 在二进制帧当中还有其它的一些字段, 实现了优先级和流量控制等功能webpack

  4. 服务器推送 服务器再也不是彻底被动地响应请求,也能够新建“流”主动向客户端发送消息。web

8.介绍csrf以及应对手段

CSRF 攻击就是黑客利用了用户的登陆状态,并经过第三方的站点来作一些坏事面试

应对手段:算法

  • 1.充分利用好 Cookie 的 SameSite 属性。 咱们能够针对实际状况将一些关键的 Cookie 设置为 Strict 或者 Lax 模式, 这样在跨站点请求时,这些关键的 Cookie 就不会被发送到服务器,从而使得黑客的 CSRF 攻击失效。element-ui

    1. 验证请求的来源站点。

    HTTP 请求头中的 Referer 和 Origin 属性 服务器的策略是优先判断 Origin,若是请求头中没有包含 Origin 属性, 再根据实际状况判断是否使用 Referer 值

    1. CSRF Token

    第一步,在浏览器向服务器发起请求时,服务器生成一个 CSRF Token。 CSRF Token 其实就是服务器生成的字符串,而后将该字符串植入到返回的页面中。 第二步,在浏览器端若是要发起转帐的请求,那么须要带上页面中的 CSRF Token, 而后服务器会验证该 Token 是否合法。若是是从第三方站点发出的请求, 那么将没法获取到 CSRF Token 的值,因此即便发出了请求, 服务器也会由于 CSRF Token 不正确而拒绝请求。

9.优化白屏的方式

  1. 提取第三方库,第三方依赖文件以及打包文件放进CDN服务器
  2. 对路由进行懒加载
  3. 首页白屏添加骨架屏或loading(仅仅是优化体验)
  4. 优化 webpack 减小模块打包体积,code-split 按需加载
  5. 服务端渲染,在服务端事先拼装好首页所需的 html
  6. 服务端开启gzip压缩
  7. element-ui等UI框架按需引入
  8. 打包文件分包,提取公共文件包
  9. 使用文件名增长hash名,解决新版本须要清除依赖的问题
  10. 代码压缩
  11. 压缩图片文件,减小文件体积
  12. 图片资源放进CDN服务器
  13. 使用CSS精灵图

10.继承与组合的优缺点

11.http缓存

1.先判断强缓存是否生效: 控制强缓存的字段分别是Expires和Cache-Control(优先级较高),

Expires:是HTTP/1.0控制网页缓存的字段, 值为服务器返回该请求结果缓存的到期时间
即再次发起该请求时,若是客户端的时间小于Expires的值时,直接使用缓存结果。
到了HTTP/1.1,Expire已经被Cache-Control替代

Cache-Control:主要取值
。 public:全部内容都将被缓存(客户端和代理服务器均可缓存)
。 private: 全部内容只有客户端能够缓存,Cache-Control的默认取值
。 no-cache:客户端缓存内容,可是是否使用缓存则须要通过协商缓存来验证决定
。 no-store:全部内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
。 max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

内存缓存(from memory cache)和硬盘缓存(from disk cache)
。内存缓存(from memory cache):内存缓存具备两个特色,分别是快速读取和时效性:
。快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,
  占据该进程必定的内存资源,以方便下次运行使用时的快速读取。
。时效性:一旦该进程关闭,则该进程的内存则会清空。
。硬盘缓存(from disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,
  读取缓存须要对该缓存存放的硬盘文件进行I/O操做,而后从新解析该缓存内容,读取复杂,速度比内存缓存慢。
  
  在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,
  那么当刷新页面时只需直接从内存缓存中读取(from memory cache);
  而css文件则会存入硬盘文件中,因此每次渲染页面都须要从硬盘读取缓存(from disk cache)。
复制代码

2.协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求, 由服务器根据缓存标识决定是否使用缓存的过程

控制协商缓存的字段分别有:Last-Modified/If-Modified-Since 和 Etag/If-None-Match(优先级高)

Last-Modified / If-Modified-Since:
    Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。
    If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,
    经过此字段值告诉服务器该资源上次请求返回的最后被修改时间。
    服务器收到该请求,发现请求头含有If-Modified-Since字段,
    则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间作对比,
    若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则从新返回资源,状态码为200;
    不然则返回304,表明资源无更新,可继续使用缓存文件

Etag / If-None-Match :
    Etag是服务器响应请求时,返回当前资源文件的一个惟一标识(由服务器生成)。
    If-None-Match是客户端再次发起该请求时,携带上次请求返回的惟一标识Etag值,
    经过此字段值告诉服务器该资源上次请求返回的惟一标识值。
    服务器收到该请求后,发现该请求头中含有If-None-Match,
    则会根据If-None-Match的字段值与该资源在服务器的Etag值作对比,一致则返回304,表明资源无更新,
    继续使用缓存文件;不一致则从新返回资源文件,状态码为200,

总结: 
    强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,
    若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),
    协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么表明该请求的缓存失效,
    从新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存  
复制代码

12.require 与 import 的区别

  • 1.原生浏览器不支持 require/exports,可以使用支持 CommonJS 模块规范的 Browsersify、webpack 等打包工具,它们会将 require/exports 转换成能在浏览器使用的代码。
  • 2.import/export 在浏览器中没法直接使用,咱们须要在引入模块的
  • 3.即便 Node.js 13.2+ 已经支持 import/export,Node.js官方不建议在正式环境使用,目前可使用 babel 将 ES6 的模块系统编译成 CommonJS 规范(注意:语法同样,但具体实现还 是require/exports)
    1. require/exports 是运行时动态加载,import/export 是静态编译
    1. require/exports 输出的是一个值的拷贝,import/export 模块输出的是值的引用
    1. ES6 模块能够在 import 引用语句前使用模块,CommonJS 则须要先引用后使用
    1. import/export 只能在模块顶层使用,不能在函数、判断语句等代码块之中引用;require/exports 能够
    1. 是否采用严格模式
    • import/export 导出的模块默认调用严格模式。
    • require/exports 默认不使用严格模式,能够自定义是否使用严格模式

13.箭头函数的实现

14.vue的双向绑定

    1. Data经过observer转换成了getter/setter的形式来追踪变化。
    1. 当外界经过Watcher读取数据时,会触发getter从而将Watch添加到依赖中。
    1. 当数据发生了变化时,会触发setter,从而向Dep中的依赖(即Watcher)发送通知
    1. Watcher接收到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,
    也有可能触发用户的某个回调函数等。

二面

1.离职缘由

2.对 ts 的使用状况

3.观察者模式

4.单例模式

5.归并排序

function mergeSort(arr) {
    const len = arr.length;
    if (len <= 1 ) {
        return arr;
    }
    let mid = Math.floor(len / 2);
    let leftArr = mergeSort(arr.slice(0,mid));
    let rightArr = mergeSort(arr.slice(mid, len));
    arr = mergeArr(leftArr, rightArr);
    return arr;
}

function mergeArr(arr1, arr2){
    let i = 0;
    let j = 0;
    let len1 = arr1.length;
    let len2 = arr2.length;
    let res = [];
    while(i<len1 && j<len2) {
        if (arr1[i] < arr2[j]) {
            res.push(arr1[i])
            i++;
        } else {
            res.push(arr2[j])
            j++;
        }
    }
    if (i<len1) {
        return res.concat(arr1.slice(i));
    } else {
        return res.concat(arr2.slice(j));
    }
}
复制代码

6.快速排序

function quickSort(arr, left=0; right=arr.length - 1) {
    if (arr.lenth > 1) {
        const lineIndex = partition(arr,left, right);
        if (left < lineIndex -1) {
            quickSort(arr,left,lineIndex -1);
        }
        if (right > lineIndex) {
            quickSort(arr,lineIndex,right);
        }
    }
    return arr;
}
function partition(arr, left, right) {
    let i = left;
    let j = right;
    let pivotValue = arr[Math.floor(left + (right-left)/2)];
    if (i<=j) {
        while(arr[i] < pivotValue) {
            i++
        }
        while(arr[j] > pivotValue) {
            j++
        }
        if (i<=j) {
            swap(arr,i,j);
            i++;
            j--;
        }    
    }
    return i;
}
function swap(arr,i,j){
    [arr[i],arr[j]] = [arr[j],arr[i]];
}
复制代码

7.this 的使用

  • 1.在普通函数中使用 this, this表明全局对象window。
  • 2.做为一个对象的方法调用,此时this指的是调用它的那个对象。
  • 3.做为一个构造函数被调用,此时this指代new出来的那个对象。
  • 4.call调用 ,call方法的做用是改变函数的调用对象,此方法的第一个参数为改变后调用这个函数的对象,this指的是第一个参数,若是不传参数,默认指的是全局对象window。

8.对 Http3 的了解

采用 QUIC 协议: HTTP/3 选择了一个折衷的方法——UDP 协议, 基于 UDP 实现了相似于 TCP 的多路数据流、传输可靠性等功能,咱们把这套功能称为 QUIC 协议

HTTP/3 中的 QUIC 协议集合了如下几点功能:

  • 1.实现了相似 TCP 的流量控制、传输可靠性的功能
  • 2.集成了 TLS 加密功能
    1. 实现了 HTTP/2 中的多路复用功能。
    和 TCP 不一样,QUIC 实现了在同一物理链接上能够有多个独立的逻辑数据流。 实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

9.http2的优化点

(参考上面的)

10. 网络攻防 1. 主要有哪些问题 2. Xss 主要针对哪些字符进行转化

1.Xss: XSS 攻击就是黑客往页面中注入恶意脚本,而后将页面的一些重要数据上传到恶意服务器。 常见的三种攻击模式:1.存储型XSS攻击 2.反射性XSS攻击 3.基于DOM的XSS攻击

主要有三种防范策略: 第一种是经过服务器对输入的内容进行过滤或者转码, 第二种是充分利用好 CSP, 第三种是使用 HttpOnly 来保护重要的 Cookie 信息

2.Csrf(参看上面)

11.项目网络性能优化

12.主要使用哪一个框架,vue源码相关的了解

13.对前沿技术的了解

最后:分享下本身整理的部分知识点文章连接

相关文章
相关标签/搜索