• 作为面试官,中级应用级Web前端我会问什么问题


    前序

    首先就我本人而言,我主要会考察如下

        1. 让候选人介绍一个自己觉得做过的最值得一说的项目,这可以考察他/她的表达能力和自信心。
    
        2. 让候选人用代码实现一个实际功能,这可以考察他/她的编码能力和解决问题能力;
    
        3. 给候选人一个极端情境的设计问题,这可以考察他/她的工程思维和权衡能力。
    

    但往往公司给我的指标确实需要一个能够快速做事的指标,所以有了如下的题目 薪资10k-15k 坐标长沙 有兴趣可以发送简历到我的邮箱shundong106@gmail.com

    题目如下,一般是从上自下,题目均选自网络,本人只是挑选

    1.实现一个new的伪代码

    创建一个对象
    连接原型
    绑定this
    返回该对象
    
    function _new(){
      let obj = new Object();
      let Con = [].shift.call(arguments);
      obj.__proto__ = Con.prototype;
      let result = Con.apply(obj,arguments);
      return typeof result === 'object' ? result : obj
    }
    

    2.原型、原型链

    原型链:每个被实例对象都有__proto__对象,它指向了构造该对象的构造函数的prototype属性。同时该对象可以通过__proto__对象来寻找不属于自身的属性,
    原型:就是实现继承过程中产生的一个概念。
    

    3.继承

    原理是:复制父类的属性和方法来重写子类的原型对象
    
    原型继承
    构造函数继承
    组合继承
    寄生继承
    寄生组合继承
    class
    等等
    
    // 寄生组合继承方法
    function Father(...arr) {
        this.some = '父类属性';
        this.params = arr;
    }
    Father.prototype.someFn = function() {
        console.log(1);
    }
    Father.prototype.someValue = '2';
    function Son() {
        Father.call(this, 'xxxx');
        this.text = '2222';
    }
    Son.protptype = Object.create(Father.prototype);
    Son.prototype.constructor = Son;
    

    4.Object,create做了什么

    Object._create = function(obj){
      function F(){}; // 创建了一个新的构造函数F
      F.prototype = obj; // 然后将构造函数F的原型指向了参数对象obj
      return new F(); // 返回构造函数F的实例对象,从而实现了该实例继承obj的属性。
    }
    

    5.闭包

    闭包就是有权访问一个函数内部变量的函数,也就是常说的函数内部嵌套函数,
    内部函数访问外部函数变量,从而导致垃圾回收机制没有将当前变量回收掉。
    这样的操作,有可能会带来内存泄漏。好处就是可以设计私有的方法和变量。
    

    6.垃圾回收机制(闭包的延伸)

    js拥有特殊的垃圾回收机制,当一个变量在内存中失去引用,js会通过特殊的算法将其回收,并释放内存。
    分为以下两个阶段:
    
    标记阶段:垃圾回收器,从根对象开始遍历,访问到的每一个对象都会被标示为可到达对象。
    清除阶段:垃圾回收器在对内存当中进行线性遍历,如果发现该对象没有被标记为可到达对象,那么就会被垃圾回收机制回收。
    这里面牵扯到了引用计数法,每次引用都被会‘➕1’ 如果标记清零,那么就会被回收掉。
    

    7.简述深浅拷贝

    浅拷贝
    	通常需要拷贝的对象内部只有一层的这种对象。
    	常用的方法
    
    	Object.assign方法来实现
    	扩展运算符 ...obj
    
    深拷贝
    	通常是嵌套二层或以上的复杂对象
    	常用方法
    
    	JSON.parse(JSON.stringfy(object)); 该方法忽略掉undefined、忽略Symbol、忽略function。只适合简单深拷贝
    	手写递归方法去实现。
    	通过第三方库提供的深拷贝实现。
    

    8.函数的节流和防抖

    防抖函数:将多次触发变成最后一次触发;
    
    
    function debounce(fn,wait){
      let timer = null;
      return function (){
        let arg = arguments;
        if(timer){
          clearTimeout(timer);
          timer = null;
        }
        timer = setTimeout(()=>{
           fn.apply(this,arg)
        },wait)
      }
    }
    function clg(){
      console.log('clg')
    }
    window.addEventListener('resize',debounce(clg,1000))
    

    9.节流函数:将多次执行变成每隔一个时间节点去执行的函数

    function throttle(fn,time){
      let lastTime = null;
      return function(){
        let nowTime = Date.now();
        if(nowTime - lastTime > time || !lastTime){
          fn();
          last = nowTime
        }
      }
    }
    function sayHi(){
      console.log('hi')
    }
    setInterval(throttle(sayHi,1000),500)
    

    10.js跨域如何解决

    目前暂时已知的跨域方法是:
    
    jsonp跨域,原理:script标签没有跨域限制的漏洞实现的一种跨域方法,只支持get请求。安全问题会受到威胁。
    cors跨域,通过后端服务器实现,Access-Control-Allow-Origin。
    postMessage window的一个属性方法。
    websocket
    nginx反向代理
    iframe跨域
    

    11.webpack配置入口

    module.exports={    
      //入口文件的配置项    
      entry:{},    
      //出口文件的配置项    
      output:{},    
      //模块:例如解读CSS,图片如何转换,压缩    
      module:{},    
      //插件,用于生产模版和各项功能    
      plugins:[],    
      //配置webpack开发服务功能    
      devServer:{} 
    } 
    简单描述了一下这几个属性是干什么的。
    

    12.URL输入浏览器回车后的过程

    1.读取缓存:
            搜索自身的 DNS 缓存。(如果 DNS 缓存中找到IP 地址就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。)
    2.DNS 解析:将域名解析成 IP 地址
    3.TCP 连接:TCP 三次握手,简易描述三次握手
               客户端:服务端你在么?
               服务端:客户端我在,你要连接我么?
               客户端:是的服务端,我要链接。
               连接打通,可以开始请求来
    4.发送 HTTP 请求
    5.服务器处理请求并返回 HTTP 报文
    6.浏览器解析渲染页面
    7.断开连接:TCP 四次挥手
    
    关于第六步浏览器解析渲染页面又可以聊聊如果返回的是html页面
    根据 HTML 解析出 DOM 树
    根据 CSS 解析生成 CSS 规则树
    结合 DOM 树和 CSS 规则树,生成渲染树
    根据渲染树计算每一个节点的信息
    根据计算好的信息绘制页面
    

    13.陈述一下http

    基本概念:
    
    HTTP,全称为 HyperText Transfer Protocol,即为超文本传输协议。是互联网应用最为广泛的一种网络协议
    所有的 www 文件都必须遵守这个标准。
    
    http特性:
    
    HTTP 是无连接无状态的
    HTTP 一般构建于 TCP/IP 协议之上,默认端口号是 80
    HTTP 可以分为两个部分,即请求和响应。
    
    http请求:
    
    HTTP 定义了在与服务器交互的不同方式,最常用的方法有 4 种
    分别是 GET,POST,PUT, DELETE。URL 全称为资源描述符,可以这么认为:一个 URL 地址
    对应着一个网络上的资源,而 HTTP 中的 GET,POST,PUT,DELETE
    就对应着对这个资源的查询,修改,增添,删除4个操作。
    
    HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。
    
    HTTP 响应由 3 个部分构成,分别是:状态行,响应头(Response Header),响应正文。
    
    HTTP 响应中包含一个状态码,用来表示服务器对客户端响应的结果。
    状态码一般由3位构成:
    
    1xx : 表示请求已经接受了,继续处理。
    2xx : 表示请求已经处理掉了。
    3xx : 重定向。
    4xx : 一般表示客户端有错误,请求无法实现。
    5xx : 一般为服务器端的错误。
    
    比如常见的状态码:
    
    200 OK 客户端请求成功。
    301 Moved Permanently 请求永久重定向。
    302 Moved Temporarily 请求临时重定向。
    304 Not Modified 文件未修改,可以直接使用缓存的文件。
    400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
    401 Unauthorized 请求未经授权,无法访问。
    403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因。
    404 Not Found 请求的资源不存在,比如输入了错误的URL。
    500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。
    503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
    
    大概还有一些关于hhtp请求和响应头信息的介绍。
    

    14.说一下Vue的原理

    Vue是采用数据劫持配合发布者-订阅者模式,通过Object.defineProperty来()来劫持各个属性的getter和setter
    在数据发生变化的时候,发布消息给依赖收集器,去通知观察者,做出对应的回调函数去更新视图。
    
    具体就是:
    MVVM作为绑定的入口,整合Observe,Compil和Watcher三者,通过Observe来监听model的变化
    通过Compil来解析编译模版指令,最终利用Watcher搭起Observe和Compil之前的通信桥梁
    从而达到数据变化 => 更新视图,视图交互变化(input) => 数据model变更的双向绑定效果。
    

    15.说一下Vue的路由守卫

    常用的两个路由守卫:router.beforeEach 和 router.afterEach
    
    每个守卫方法接收三个参数:
    
    to: Route: 即将要进入的目标 路由对象
    
    from: Route: 当前导航正要离开的路由
    
    next: Function: 一定要调用该方法来 resolve 这个钩子。
    
    在项目中,一般在beforeEach这个钩子函数中进行路由跳转的一些信息判断。
    判断是否登录,是否拿到对应的路由权限等等。
    

    16.数据去重-检验日常经典算法和数据结构

    第一种:通过ES6新特性Set()
    例如:var arr = [1, 2, 3, 1, 2]; var newArr= [...new Set(arr)]
    
    第二种:封装函数利用 {} 和【】
    function uniqueEasy(arr) {
        if(!arr instanceof Array) {
            throw Error('当前传入的不是数组')
        }
        let list = []
        let obj = {}
        arr.forEach(item => {
            if(!obj[item]) {
                list.push(item)
                obj[item] = true
            }
        })
        return list
    }
    ... 还要很多方式 例如转set数据结构等。
    
    

    17.Set,Map数据结构-检验日常经典算法和数据结构

    ES6 提供了新的数据结构 Set。
    它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。
    
    ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
    

    18.简单算法的手写-检验日常经典算法和数据结构

    1. 说一下个工作中使用到的api排序方法
    2. 首页一个冒泡排序
    3. 有时间可以写一个递归版的小算法,涉及到Vue的双向绑定原理
    

    19. ES6的新特性

    1.ES6引入来严格模式
        变量必须声明后在使用
        函数的参数不能有同名属性, 否则报错
        不能使用with语句 (说实话我基本没用过)
        不能对只读属性赋值, 否则报错
        不能使用前缀0表示八进制数,否则报错 (说实话我基本没用过)
        不能删除不可删除的数据, 否则报错
        不能删除变量delete prop, 会报错, 只能删除属性delete global[prop]
        eval不会在它的外层作用域引入变量
        eval和arguments不能被重新赋值
        arguments不会自动反映函数参数的变化
        不能使用arguments.caller (说实话我基本没用过)
        不能使用arguments.callee (说实话我基本没用过)
        禁止this指向全局对象
        不能使用fn.caller和fn.arguments获取函数调用的堆栈 (说实话我基本没用过)
        增加了保留字(比如protected、static和interface)
    
    2.关于let和const新增的变量声明
    
    3.变量的解构赋值
    
    4.字符串的扩展
        includes():返回布尔值,表示是否找到了参数字符串。
        startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
        endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
    5.数值的扩展
        Number.isFinite()用来检查一个数值是否为有限的(finite)。
        Number.isNaN()用来检查一个值是否为NaN。
    6.函数的扩展
        函数参数指定默认值
    7.数组的扩展
        扩展运算符
    8.对象的扩展
        对象的解构
    9.新增symbol数据类型
    
    10.Set 和 Map 数据结构
        ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。
        
        Map它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
    11.Proxy
        Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问
        都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
        Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
        Vue3.0使用了proxy
    12.Promise
        Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
        特点是:
            对象的状态不受外界影响。
            一旦状态改变,就不会再变,任何时候都可以得到这个结果。
    13.async 函数
        async函数对 Generator 函数的区别:
        (1)内置执行器。
        Generator 函数的执行必须靠执行器,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。
        (2)更好的语义。
        async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
        (3)正常情况下,await命令后面是一个 Promise 对象。如果不是,会被转成一个立即resolve的 Promise 对象。
        (4)返回值是 Promise。
        async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
    14.Class
        class跟let、const一样:不存在变量提升、不能重复声明...
        ES6 的class可以看作只是一个语法糖,它的绝大部分功能
        ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
    15.Module
        ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。
        import和export命令以及export和export default的区别
    

    20.CSS3的新特性

    1.过渡 transition
    2.动画 animation
    3.形状转换 transform
    4.阴影 box-shadow
    5.滤镜 Filter
    6.颜色 rgba
    7.栅格布局 gird
    8.弹性布局 flex
    等等还多...
    
    

    21.说一说SessionStorage和localStorage还有cookie

    共同点:都是保存在浏览器端、且同源的
    不同点:
        1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。
        cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
        sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。
        2.存储大小限制也不同,cookie数据不能超过4K,sessionStorage和localStorage可以达到5M
        3.sessionStorage:仅在当前浏览器窗口关闭之前有效;
        localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;
        cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
        4.作用域不同
        sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;
        localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在
        cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在
    

    22.说一下你用过的CSS布局有哪些

    gird布局,layout布局,flex布局,双飞翼,圣杯布局等 
    

    23. Promise是什么,解决了什么,之前怎么实现的

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
    解决来之前在请求中回调请求产生的回调地狱,使得现在的代码更加合理更加优雅,也更加容易定位查找问题。
    之前多用setTimeOut实现,过程较为复杂。
    

    24.说一下浏览器缓存

    缓存可以减少网络 IO 消耗,提高访问速度。浏览器缓存是一种操作简单、效果显著的前端性能优化手段
    很多时候,大家倾向于将浏览器缓存简单地理解为“HTTP 缓存”。
    但事实上,浏览器缓存机制有四个方面,它们按照获取资源时请求的优先级依次排列如下:
    
    Memory Cache
    Service Worker Cache
    HTTP Cache
    Push Cache
    
    缓存它又分为强缓存和协商缓存。优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存
        实现强缓存,过去我们一直用 expires。
        当服务器返回响应时,在 Response Headers 中将过期时间写入 expires 字段,现在一般使用Cache-Control 两者同时出现使用Cache-Control
        
        协商缓存,Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回:每次请求去判断这个时间戳是否发生变化。
        从而去决定你是304读取缓存还是给你返回最新的数据
    
    

    25.待续 gwshshundong106@gmail.com

  • 相关阅读:
    N天学习一个linux命令之lsof
    N天学习一个linux命令之ps
    N天学习一个linux命令之yum
    N天学习一个linux命令之rsync
    N天学习一个linux命令之ss
    N天学习一个linux命令之netstat
    N天学习一个linux命令之vmstat
    N天学习一个linux命令之sort
    N天学习一个linux命令之rpm
    跨域问题
  • 原文地址:https://www.cnblogs.com/shundong106/p/15094323.html
Copyright © 2020-2023  润新知