美文网首页
2018-04-26 面试题整理

2018-04-26 面试题整理

作者: 何学斌 | 来源:发表于2018-04-28 09:47 被阅读0次

执行上下文、函数调用栈

var a = 1;
function A() {
  a = 3;
  return ;
  function a () { console.log(); };
}
A();
console.log(a);

聪明的你一定觉得这道题so easy,是吗?大笔一挥,答案a等于3.
错!!!
正确答案是1.
函数A()执行时,创建函数A的执行上下文,此时在A的上下文中,因为函数声明提前,变量a被声明为一个函数对象,当代码执行阶段时,a被赋值为3,继续执行return ;函数A结束执行。而全局变量a并未被赋值修改,所以console.log(a);等于1.

当调用一个函数时(激活),一个新的执行上下文就会被创建。而一个执行上下文的生命周期可以分为两个阶段。

  • 创建阶段 在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向。
  • 代码执行阶段 创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。 image.png

变量、赋值

let a = {v: 'temp'};
let b = a;
a = a.x = {v: 'temp'};
console.log(a); 
// {v: 'temp'}
console.log(b);
// {v: 'temp', x: {v: 'temp'}}

说明:引用类型赋值时复制的是引用地址


函数传参

let a= 1;
let b= {a: 1};
function sum(m,n) {
    m= 2;
    n.a= 2;
}
sum(a,b);
console.log(a);
// 1
console.log(b);
// {a: 2};

说明:函数的参数是值传递的,而引用类型赋值的是其引用的内存地址。所以sum函数内,m=1,n与b指向同一块内存地址,函数执行后,console.log(b)打印{a: 2}。


函数调用栈和任务队列

//请写出下面代码段的执行结果
setTimeout( function () { console.log(0)},0);
Promise.resolve().then( function () { console.log(5)});
console.log(3);
for( var i= 10; i< 15; i++) {
  setTimeout( function (){ console.log(i)}, i);
}

浏览器执行js代码永远是一个单线程,除了依靠函数调用栈来搞定函数的执行顺序外,还依靠任务队列(task queue)来搞定另外一些代码的执行。


队列数据结构
  • 一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。
  • 任务队列又分为macro-task(宏任务)与micro-task(微任务),在最新标准中,它们被分别称为task与jobs。
  • macro-task大概包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。
  • micro-task大概包括: process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)
  • setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的具体执行任务。

分析:
浏览器执行js过程中,遇到setTimeout(fn,time)函数,调用浏览器定时线程计时,在time毫秒后将fn加入宏任务队列;
浏览器继续执行后续代码,遇到Promise将.then(fn)中fn加入微任务队列;
继续执行,打印3;
for循环5次,定时器线程分别在10ms、11ms、12ms、13ms、14ms后将function () { console.log(i);}加入宏任务队列;
for循环结束后,本次宏任务队列执行完毕,执行微任务队列中function () { console.log(5);},打印5;
微任务队列执行完毕,继续执行宏任务队列,打印0, 15, 15, 15, 15, 15
所以输出结果为:3, 5, 0, 15, 15, 15, 15, 15


数组随机排序

var a = [1,2,3,4,5,6,7,8,9,10];
a.sort(function(a,b){ return Math.random() > 0.5;});

Array.prototype.sort()
语法
arr.sort()
arr.sort(compareFunction)

  • 参数
    compareFunction
    可选。用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
  • 返回值
    返回排序后的数组。原数组已经被排序后的数组代替。
  • 说明
    如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前。
    如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
    如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
    如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本)
    如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
    compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

如上方法并不是真正意思上的乱序,一些元素并没有机会相互比较, 最终数组元素停留位置的概率并不是完全随机的。

v8在处理sort方法时,使用了插入排序和快排两种方案。
当目标数组长度小于10时,使用插入排序;反之,使用快速排序。
其实不管用什么排序方法,大多数排序算法的时间复杂度介于O(n)到O(n²)之间,
元素之间的比较次数通常情况下要远小于n(n-1)/2,
也就意味着有一些元素之间根本就没机会相比较(也就没有了随机交换的可能),
这些 sort 随机排序的算法自然也不能真正随机。
其实我们想使用array.sort进行乱序,理想的方案或者说纯乱序的方案是数组中每两个元素都要进行比较,
这个比较有50%的交换位置概率。这样一来,总共比较次数一定为n(n-1)。
而在sort排序算法中,大多数情况都不会满足这样的条件。因而当然不是完全随机的结果了。
作者:云中桥
链接:https://juejin.im/post/5d004ad95188257c6b518056

// Fisher–Yates算法,这个算法是由 Ronald Fisher 和 Frank Yates 首次提出的。
// 这个算法其实非常的简单,就是将数组从后向前遍历,然后将当前元素与随机位置的元素进行交换。
function shuffle(arr) {
    let m = arr.length;
    while (m > 1){
        let index = Math.floor(Math.random() * m--);
        [arr[m] , arr[index]] = [arr[index] , arr[m]]
    }
    return arr;
}

数组去重

  1. 利用数组的lastIndexOf()方法。
arr= arr.filter( function (v,i,array) {
  if(array.lastIndexOf(v) === i) {
    return true;
  }
  return false;
});

filter不修改原数组,返回新数组。

  1. 利用ES6 新增Set对象实现
//2.1
arr = Array.from(new Set(arr));
//2.2
arr = [... new Set(arr)];
  1. 利用Object对象键名唯一性实现。
var obj = {},
    del = [];
arr.forEach(function (v) {
  if( !obj[typeof v+''+v]) {
    del.push(v);
    obj[typeof v+''+v] = 1;
  }
});

相关文章

  • 2018-04-26 面试题整理

    执行上下文、函数调用栈 聪明的你一定觉得这道题so easy,是吗?大笔一挥,答案a等于3.错!!!正确答案是1....

  • 2017 Android 面试题分享整理

    第174期:2017 Android 面试题分享整理 深度讨论 2017 Android 面试题分享整理 (欢迎评...

  • Maya撤销、自动保存

    2018-04-26

  • 2018-04-26

    2018-04-26

  • 面试题

    关注的面试题文集 Android面试题整理 Android工程师面试题大全 Android 面试题总结之Andro...

  • 日记-2020-07-27

    早上:学习vim中午:休息白天: 配合测试 修改批量查询bug 整理面试题-多线程2 整理面试题-JVM部分 待完成

  • Android面试总结二

    参考文章 40个Android面试题Java面试题集Android名企面试题及知识点整理Android面试题收集较...

  • 经典面试100题 - 持续更新中

    打算整理100道经典面试题,整理出来的链接都会附录在下面。 经典面试题1:图片占多少内存经典面试题2:时针和分针经...

  • python面试题整理

    python面试题整理 110道Python面试题(真题)[https://zhuanlan.zhihu.com/...

  • 作者心血 整理阿里p4-p6面试题(附带答案)

    前面已经看过我整理的187到面试题合集 最近收集阿里p4-p6面试题整理,筛选比较大众一点的25到面试题(ps:附...

网友评论

      本文标题:2018-04-26 面试题整理

      本文链接:https://www.haomeiwen.com/subject/zvsplftx.html