sakila1012 / blog

记录自己学习工作中的心得
10 stars 3 forks source link

美的面试总结 #68

Open sakila1012 opened 3 years ago

sakila1012 commented 3 years ago

写在前面

像很多的印象,对美的的认识,就是这不就是一家制造业公司,怎么还会有前端开发工程师呢,他们在苏州成立了一个美的清洁公司,专门做的是扫地机器人方面的,偏向于物联网。

这次的面试,对我的打击还是挺大的,明显觉得自己的能力不足,回答起问题仅仅是大概,了解,给人的印象是,这个人能力仅仅停留在了解,认识方面,但没有深入,对原理行的内容没有深入的研究和思考,没有真正形成自己的认识。浅尝辄止。印象深刻啊,我现在年龄也不小了,不能在这样下去了。

面试的内容记录

  1. 闭包 闭包有三个特性:

    • 函数嵌套函数
    • 函数内部可以引用函数外部的参数和变量
    • 参数和变量不会被垃圾回收机制回收

    函数作为返回值

    function a() {
     var name = 'dov';
     return function(){
       return name;
     }
    }
    var b = a();
    consoe.log(b())

    这段代码中,a()中的返回值是一个匿名函数,这个函数在a()作用域内部,所以它可以获取a()作用域下变量 name 的值,将这个值作为返回值赋给全局作用域下的变量b,实现了在全局变量下获取到局部变量中的变量值。

    function fn() {
      var num = 3;
      return function() {
        var n = 0;
        console.log(++n);
        console.log(++num)
      }
    }
    var fn1 = fn();
    fn1() // 1 4
    fn1() // 1 5

    一般情况下,在函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为fn的返回值被赋值给了fn1,这个时候,相当于fn1=function(){var n = 0 ...},并且匿名函数内部引用着 fn 里的变量 num,所以变量 num 无法被销毁,而变量 n 是每次被调用时新建的,所以每次fn1 执行完后它属于自己的变量连同自己一起销毁,于是最后就剩下num,于是这里就产生了内存消耗的问题。

    定时器与闭包: 一个for循环,让它按顺序打印当前循环次数

     for(var i=0; i<5; ++i){
       setTimeout(function(){
         console.log(i + ' ')
       }, 100)
     }

    按照预期,它应该依次输出1 2 3 4 5,而且结果它输出了五次5,这是为什么呢?原来由于js是单线程的,所以在执行for循环的时候定时器settTimeout 被安排到任务队列中排队等待执行,而等待过程中for循环就已经执行,等到setTimeout可以执行的时候,for 循环已经结束了,i 的值也已经变成了5,所以打印出来5个5,那么我们为了实现预期结果应该怎么改呢(ps:如果for循环里面的var变成let,也能实现预期结果)

    for(var i=0; i<5; ++i){
     (function(i){
       setTimeout(function(){
         console.log(i + ' ')
       }, 100)
     }(i))
    }

    引入闭包来保存变量i,将setTimeout放入立即执行函数中,将for循环中的循环值i作为参数传递,100毫秒后同时打印出1 2 3 4 5 函数作为参数传递

    优点: 保护函数内的变量安全,实现封装,防止变量流入其他环境发生命名冲突 在内存中维持一个变量,可以做缓存(但使用多了,同时也是一项缺点,消耗内存) 匿名自执行函数可以减少内存消耗 缺点: 其中一点上面已经体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成了内存泄漏,解决方法是使用完变量后,手动为它赋值为null 其次:由于闭包涉及跨作用域访问,会导致性能损失,通常把跨作用域的变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

  2. 设计模式 问到了单例模式和观察者模式 观察者模式和发布订阅的区别 观察者模式是如何实现当被观察者发生变化,通知所有观察者的

  3. webpack的原理

  4. 路由 history模式存在的问题 需要后端配合写对应的路由,不然会出现404问题

  5. vue的响应式原理

  6. Object.defineProperty是如何实现响应式的 对对象进行监听 利用Object.defineProperty(obj, pop, descriptor)对对象的属性进行数据劫持加上发布订阅来实现数据的双向绑定的。

  7. proxy 在目标对象之前架一层拦截,外界对该对象访问,都要经过该拦截。因此,提供了一种机制,可以对外界的访问进行过滤和改写。

  8. ES6 Array 有哪些方法 from,fill,of,find,findIndex,includes,flat,flatMap,entries,keys,values,copyWithin;

  9. TS泛型 不仅能支持当前的数据类型,也能支持未来的数据类型

  10. 静态资源的刷新问题

  11. 事件环,EventLoop

  12. git pull 和 git pull rebase的区别 git pull = git fetch + git merge git pull rebase = git fetch + git rebase

  13. 如何使用git指令合并代码冲突

  14. 为什么代码的管理存在冲突

  15. 数组的map和forEach方向有什么区别么 map 方法返回一个新的数组 不会对空数组进行检测,不会改变原数组 要操作的数组是空数组,返回的也是一个空数组。 forEach 无论数组是不是空的,forEach返回的都是undefined 对数组的每个元素,将元素返回给回调函数 对空数组不会调用回调函数 这个方法只是将数组的每一项作为callback的参数,执行一遍

  16. 如何优化组件

  17. 性能优化方面有哪些 加载优化 渲染优化 构建优化

  18. 项目方面的内容

  19. 判断object的数据类型

    typeof
    instanceof
    constructor
    Object.prototype.String.call()

    19.1 typeof typeof 只能判断区分基本类型,number、string、boolean、undefined 和 object,function;

    
    typeof 0; // number
    typeof true; // boolean
    typeof undefined; // undefined
    typeof "hello world"; // string
    typeof function(){}; // function

typeof null; // object typeof {}; // object typeof []; // object

从上例我们可以看出,typeof 判断对象和数组都返回object,因此无法区分数组和对象;

19.2 instanceof

var a={} a instanceof Object // true a instanceof Array // false

var b = []; b instanceof Array // true b instanceof Object // true

因为数组属于object中的一种,所以数组instanceof object也是 true

var c='abc'; c instanceof String; // false var d = new String(); d instanceof String // true

instanceof 不能区分基本数据类型string和Boolean,除非是字符串对象和布尔对象。

19.3 constructor

var o={} o.constructor === Object // true var arr = [] arr.constructor === Array // true arr.constructor === Oject // false

var n = true; n.constructor === Boolean; // true var num = 1; num.constructor === Number; // true var str = 'hello world'; str.constructor === String // true var num = new Number(); num.constructor === Number // true



可以看出constructor 可以区分Array  和 Object
不过,需要注意的是,constructor属性是可以被修改的,会导致检测的结果不正确。

除了undefined和null,其他类型的变量均可以使用construtor判断出类型

19.4 Object.prototype.toString 方法在被调用时,会执行如下的操作步骤

   - 获取对象的类名
   - 内部属性,[[class]] 一个字符串值,表明了该对象的类型
   - 然后将[Object 获取的对象类型的名]组合为字符串
   - 返回字符串"[Object Array]"

19.5 jQuery中的$.type 接口

19.6 为什么typeof null 返回的结果是object
        第一版的JavaScript 是用32位比特来存储值的,且通过值的低1位或3位来识别类型的(有点哈夫曼的味道)
        1、1: 整形(int)
        2、000:引用类型(object)
        3、010:双精度浮点型(double)
        4、100:字符串(string)
        5、110:布尔型(boolean)

         另外还有两个特殊的值
         1、undefined,用整数-2^30(负2的30次方,不在整形的范围)
         2、null,机器码空指针(C/C++宏定义),第三位也是000
         在 ES6 中,曾有提案为历史平反,将 typeof null 的值纠正为 null,但最后提案被拒了,理由是历史遗留代码太多了,不想得罪人。就继续保留了。 
20. vue 组件的通信有哪些
21. vuex的理解
22. 如何实现音视频边缓冲边播放的

美的的这次面试给我的印象还是很深刻的,打破了我之前对他们的认识,这样的公司还是真正做实际的,只有这样的公司才能锻炼人和培养人,能让我在未来的变化中保持着前进的状态和时时刻刻的上进心。都是干活,不能让自己颓废,这才是我应该有的状态。

拿出之前奋斗时所保留的状态,向前走。

还是要感谢美的的这次面试,让我认清了自己,也让我对未来有了更一步的认识和理解。
在任何时候都应该保持学习和相应的技术分享,推广自己,让更多的人知道自己。