面试题

689 阅读3分钟

面向切面编程

Function.prototype.before = function (beforeFn) {
    let _self = this; //保存原函数引用
    return () => { //返回包含了原函数和新函数的"代理函数"
         beforeFn.apply(this, arguments); //执行新函数,修正this
        return _self.apply(this, arguments) //执行原函数
    }
}
Function.prototype.after = function (afterFn) {
    let _self = this;
    return () => {
        let set = _self.apply(this, arguments);
        afterFn.apply(this, arguments);
        return set
    }
}
//测试
let func = function () {
    console.log('func')
};
func = func.before(() => {
     console.log("============before============")
}).after(() => {
    console.log("============after==============")
})
func();

//结果
============before============
func
============after==============

斐波那契数列

斐波那契数列从第三项开始,每一项都等于前两项之和,指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55......

//方案1  递归
function fib(n) {
    if (n === 1 || n === 2) return n - 1;
    return fib(n - 1) + fib( n - 2)
}
时间复杂度为o(2 ^ n)
//方案2 非递归 
function fib1(n) {
    let a = 0;
    let b = 1;
    let c = a + b;
    for (let i = 3; i < n; i++) {
        a = b;
        b = c;
        c = a + b
    }
    return c;
}
时间复杂度为o(n)
console.log(fib(10))

在一个数组中,找出里面其中两项相加后和为num同,如果存在返回这两个索引位置,否则为false

function fn(num = 0, ary = []) {
    for(let i = 0; i < ary.length; i++) {
        let diff = num - ary[i];
        let diffIndex = ary.indexOf(diff);
        if (diffIndex !== -1) {
            return [i, diffIndex]
        }
    }
    return false;
}
let num = 5;
let arr = [-1, 4, 6, 2];
console.log(fn(num, arr)) // [0, 2]

将两个有序数组合并为一个排好序的大数组

function meraeAry(left = [], right = []) {
    let result = [];
    while(left.length && right.length) {
        result.push(left[0] <= right[0] ? left.shift() : right.shift())
    }
    return result.concat(left, right)
}
console.log(meraeAry([1, 2, 3], [1, 3, 4, 9])) 
//[ 1, 1, 2, 3, 3, 4, 9 ]

字符串repeat的实现

//原生repeat
'ni'.repeat(3) //ninini

//方法1
String.prototype.repeat1 = function (n) {
    return Array(n + 1).join(this)
}
console.log('ni'.repeat1(2))//ninini

//方法2
String.prototype.repeat2 = function (n) {
    return Array(n).fill(this).join('')
}
console.log('ni'.repeat2(2))//ninini

实现函数CodingMan,此函数可以按照如下调用

CodingMan('Peter') 输出: Hi! This is Peter!

CodingMan('Peter').sleep(3).eat('dinner') 输出: Hi! This is Peter! //等待3秒 Wake up after 3 Eat dinner

CodingMan('Peter').eat('dinner').eat('supper'); 输出: Hi! This is Peter! Eat dinner Eat supper

CodingMan('Peter').sleepFirst(5).eat('supper'); 输出: //等待5秒 Wake up after 5 Hi! This is Peter! Eat supper

function CodingMan(name) {
    function Man (name) {
        setTimeout(() => {
            console.log(`Hi! This is ${name}`)
        }, 0)
    }
    Man.prototype.sleep = function (time) {
        let curTime = new Date();
        let delay = time * 1000;
        setTimeout(() => {
            while(new Date() - curTime < delay) {}
            console.log(`Work up after ${time}`)
        }, 0);
        return this;
    }
    Man.prototype.sleepFirst = function (time) {
        let curTime = new Date();
        let delay = time * 1000;
        while(new Date() - curTime < delay) {}
            console.log(`Work up after ${time}`);
        return this;
    }
    Man.prototype.eat = function (food) {
        setTimeout(() => {
            console.log(`Eat ${food}`)
        }, 0);
         return this;
    }
    return new Man(name)
}
CodingMan('Peter');
CodingMan('Peter').sleep(3).eat('dinner');
CodingMan('Peter').eat('dinner').eat('supper');
CodingMan('Peter').sleepFirst(5).eat('supper')=

[1, 2, 3].map(parseInt)

[1, 2, 3].map(parseInt)

参数
string 要解析的值。如果string参数不是字符串,则将其转换为字符串(使用ToString抽象操作)。字符串参数中的前导空格将被忽略。 radix 2到36之间的整数(进制),表示上述字符串的基数,以这个进制去转化。如果是0是以10进制

返回值
从给定字符串解析的整数。如果第一个字符无法转换为数字,NaN则返回

[1, 2, 3].map(parseInt) //1 NaN NaN
['10','10','10','10','10'].map(parseInt); //10, NaN 2 3 4
['10','10','111','210','310'].map(parseInt);  //[10, NaN, 7, 21, 52]

要求写出这样一个函数,给的数字r,经过此函数处理之后能够输出所有连续数字和为r的情况

例如,给定数字15,则最终输出三个组合:[7,8],[4,5,6],[1,2,3,4,5]

function findArray(r) {
    //结果数组,存放连续数字的起始数字和结尾数字
    var resArr = []; 
    //q带表连续数字的个数
    for (var q = 2; 2 * r / q - q >= 1; q++) { 
        //n为起始位置数字
        //n+q-1 结束位置数字
        var n = (2 * r / q - q + 1) / 2; 
        //如果n为整数则存放此次结果
        n === ~~n && resArr.push([n, n + q - 1]); 
    }
    return resArr;
}