今日面试汇总

1. 当项目的某个模块发生问题了,你是怎么定位错误的? 你常用的调试工具是什么?

1) 查看错误信息

2) 使用console

调试工具:

Chrome的debugger

抓包工具Fidder

Vue开发时的Chrome插件vue-devtools

2. 项目测试没问题,但是放到线上就有问题了,你是怎么解决的??

1) 使用sourceMap,可以查看原始代码

2) 项目回滚,本地解决问题后,合并

3. 编写一个方法去掉数组里面重复的内容, var arr = [1,2,3,4,5,1,2,3]

4. 简述 jq的原理, vue的基本框架原理

5. js 怎么模拟类的继承

6. 下面代码会输出什么:

var test = (function (a) {
    this.a = a;
    return function (b) {
        return this.a+b;
    }
}(
    function (a,b) {
        return a;
    }(1,2)
));

7.什么是前端工程化?

概念如下:前端工程化是使用软件工程的技术和方法来进行前端项目的开发、维护和管理。

这里顺带说下软件工程的概念:应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度,实现

满足用户要求的软件产品的定义、开发、和维护的工程或进行研究的学科。

前端工程化包含如下:

1) 代码规范:保证团队所有成员以同样的规范开发代码。

2) 分支管理:不同的开发人员开发不同的功能或组件,按照统一的流程合并到主干。

3) 模块管理:一方面,团队引用的模块应该是规范的;另一方面,必须保证这些模块可以正确的

加入到最终编译好的包文件中。(以上两点可以总结为模块化或者组件化开发)

4) 自动化测试:为了保证和并进主干的代码达到质量标准,必须有测试,而且测试应该是自动化的,可以回归的。

5) 构建:主干更新以后,自动将代码编译为最终的目标格式,并且准备好各种静态资源。

6) 部署:将构建好的代码部署到生产环境。


8.前端的设计模式


算法题:

1. 冒泡排序

冒泡排序的原理:

2. 去重

数组的去重

1) [...new Set(arr)]

function unique(arr) {
    return [...new Set(arr)];
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

2) 利用ES6的Set方法

//利用ES6的Set方法
function unique(arr) {
    //Set数据结构,它类似于数组,其成员的值都是唯一的
    return Array.from(new Set(arr));
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4])); // [1,2,3,5,6,7,4]

3)  定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中。

function unique(arr) {
    let newArr = [arr[0]];
    for (let i = 1; i <arr.length; i++) {
        let repeat = false;
        for (let j=0; j<newArr.length; j++) {
            if (arr[i] === newArr[j]) {
                repeat = true;
                break;
            } else {

            }
        }
        if (!repeat) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

 4) 先将原数组排序,在与相邻的进行比较,如果不同则存入新数组。

function unique(arr) {
    var formArr = arr.sort()
    var newArr = [formArr[0]]
    for (let i=1; i<formArr.length; i++) {
        if (formArr[i] !== formArr[i-1]) {
            newArr.push(formArr[i])
        }
    }
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,4,5,6,7]

5) 利用对象属性存在的特性,如果没有该属性则存入新数组。

function unique (arr) {
    var obj = {}
    var newArr = []
    for (let i=0; i<arr.length; i++) {
        if (!obj[arr[i]]) {
            obj[arr[i]] = 1
            newArr.push(arr[i])
        }
    }
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

6) 利用数组的 indexOf 下标属性来查询

function unique (arr) {
    var newArr = []
    for (var i=0; i<arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i])
        }
    }
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

7) 利用数组原型对象上的 includes 方法

function unique (arr) {
    var newArr = []
    for (var i=0; i<arr.length; i++) {
        if (!newArr.includes(arr[i])) {
            newArr.push(arr[i])
        }
    }
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

8)  利用数组原型对象上的 filter 和 includes 方法。

function unique (arr) {
    var newArr = []
    newArr = arr.filter(function (item) {
        return newArr.includes(item) ? '' : newArr.push(item)
    })
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

9) 利用数组原型对象上的 forEach 和 includes 方法。

function unique (arr) {
    var newArr = []
    arr.forEach(item => {
        return newArr.includes(item) ? '' : newArr.push(item)
    });
    return newArr
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

10) 利用数组原型对象上的 splice 方法。

function unique (arr) {
    var i,j,len = arr.length;
    for (i=0; i<len; i++) {
        for (j=i+1; j<len;j++) {
            if (arr[i] == arr[j]) {
                arr.splice(j, 1);
                len--;
                j--;
            }
        }
    }
    return arr;
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

11) 利用数组原型对象上的 lastIndexOf 方法。

function unique (arr) {
    var res = [];
    for (var i=0; i< arr.length; i++) {
        res.lastIndexOf(arr[i]) !== -1 ? '' : res.push(arr[i]);
    }
    return res;
}
console.log(unique([1,1,2,3,5,3,1,5,6,7,4]));  // [1,2,3,5,6,7,4]

3. 数组展平

数组中可以嵌套数组,要嵌套多少层都可以,比如 [1,2,[[3], 4]]

这样看起来很不爽,所以要把它展开,只留下一层数组:[1,2,3,4]

展开结果:

flatten([1,2,3])             // [1,2,3]
flatten([1,2,[3]]) // [1,2,3]
flatten([1,2,[[3], 4]]) // [1,2,3,4]
flatten([1,[2,[[3], [4]]]]) // [1,2,3,4]

1) 方法一:普通方法

function flattenMd(arr) {
    var result = []
    function flatten(arr) {
        for (var i=0; i<arr.length; i++) {
            if (Array.isArray(arr[i])) {
                flatten(arr[i]);
            } else {
                result.push(arr[i]);
            }
        }
    }
    flatten(arr);
    return result;
}
var arr = [1, [2,3,[4,5],6],7,8]
console.log(flattenMd(arr));   // [1,2,3,4,5,6,7,8]

2)方法二:数组concat方法,以及迭代

传递给 concat 方法的参数序列中如果包含数组,则会将这个数组的每一项添加到结果数组中,这就使数组的这个方法具有了天然的展开二维数组的能力。

function flattenMd(arr) {
    var result = [];
    for (var i=0; i<arr.length; i++) {
        if (arr[i] instanceof Array) {
            result = result.concat(flattenMd(arr[i]));
        } else {
            result.push(arr[i]);
        }
    }
    return result;
}
var arr = [1,[2,3,[4,5],6],7,8]
console.log(flattenMd(arr));   // [1,2,3,4,5,6,7,8]

3)方法三:使用递归

function flatten(arr) {
    return arr.reduce(function (plane, toBeFlatten) {
        return plane.concat(Array.isArray(toBeFlatten) ? flatten(toBeFlatten) : toBeFlatten);
    }, []);
}
var arr = [1,[2,3,[4,5],6],7,8]
console.log(flatten(arr));   // [1,2,3,4,5,6,7,8]

递归方法的简化版:

let flatten = function (arr) {
    return arr.reduce((plane, toBeFlatten) => (plane.concat(Array.isArray(toBeFlatten) ? flatten(toBeFlatten) : toBeFlatten)), []);
}
var arr = [1,[2,3,[4,5],6],7,8]
console.log(flatten(arr));   // [1,2,3,4,5,6,7,8]

再简化:

let flatten = arr => arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
var arr = [1,[2,3,[4,5],6],7,8]
console.log(flatten(arr));   // [1,2,3,4,5,6,7,8]

4)利用ES6的展开运算符,以及递归

function deepFlatten(arr) {
    flatten = (arr)=> [].concat(...arr);
    return flatten(arr.map(x=>Array.isArray(x)? deepFlatten(x): x));
}
var arr = [1,[2,3,[4,5],6],7,8]
console.log(deepFlatten(arr));   // [1,2,3,4,5,6,7,8]

4.十大排序算法

1) 冒泡排序 (Bubble Sort)

冒泡排序:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

2)选择排序(Selection Sort)

3)插入排序 (Insertion Sort)

4)  希尔排序(Shell Sort)

5)归并排序 (Merge Sort)

6)  快速排序 (Quick Sort)

7)  堆排序 (Heap Sort)

8)  计数排序 (Counting Sort)

9)  桶排序 (Bucket Sort)

10)  基数排序 (Radix Sort)

参考:

https://www.cnblogs.com/dushao/p/6004883.html

http://graph.jm47.com/example/sort.html


参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax 


如果2009年选择的是计算机专业,现在应是另外一番光景。

现在招高级工程师的多,不管是高级Java,还是高级前端。

原文地址:https://www.cnblogs.com/still1/p/10810737.html