某大厂前端笔试题(一)

2024-04-18 08:23:41 浏览数 (1)

1.判断异步执行顺序

代码语言:javascript复制
console.log(1)
setTimeout(()=>{
    Promise.resolve().then(()=>{
        console.log(2)
    })
    console.log(3)
},0)
new Promise((resolve)=>{
    for(let i =0;i<=1000;i  ){
        if(i===1000){
            resolve();
        }
    }
    console.log(4) 
}).then(()=>{
    console.log(5)
})
console.log(6)

//执行结果
1
4
6
5
3
2

2.服务器api返回给前端的地址数据需要脱敏,用js语言编程。

代码语言:javascript复制
脱敏规则如下:
1位字符,不脱敏
2-4位字符,第1位脱敏(如原数据为"南山区",脱敏后数据为“*山区")
5-9位字符,第3-5位脱敏(如原数据为“南山区科技二路”,脱敏后数据为“南山***二路")
10位以上,倒数3-5位脱敏(如原数据为"南山区海天二路68爱德华小区","南山区海天二路68***小区")请用js语言编程

function desensitizeAddress(address) {  
    const length = address.length;      
    if (length === 1) {  
        // 1位字符,不脱敏  
        return address;  
    } else if (length >= 2 && length <= 4) {  
        // 2-4位字符,第1位脱敏  
        return '*'   address.slice(1);  
    } else if (length >= 5 && length <= 9) {  
        // 5-9位字符,第3-5位脱敏  
        return address.slice(0, 2)   '***'   address.slice(5);  
    } else {  
        // 10位以上,倒数3-5位脱敏  
        const desensitizeLength = Math.min(5, length); // 取脱敏长度和字符串长度的较小值  
        const startDesensitize = length - desensitizeLength   3; // 计算脱敏起始位置  
        return address.slice(0, startDesensitize)   '***'   address.slice(startDesensitize   3);  
    }  
}  
  
// 示例  
console.log(desensitizeAddress("南山区"));           // 输出: *山区  
console.log(desensitizeAddress("南山区科技二路"));    // 输出: 南山***二路  
console.log(desensitizeAddress("南山区海天二路68爱德华小区"));  // 输出: 南山区海天二路68***小区

3.给定一个整数数组 a,其中1≤a[i]≤sn(n为数组长度),其中有些元素出现两次而其他元素出现一次。找到所有出现两次的元素。你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗? function findRepeat2Element (arr: number [ ]) i // TODO:

代码语言:javascript复制
要在不使用额外空间并在O(n)时间复杂度内找到所有出现两次的元素,我们可以使用原地哈希法,但由于给定的元素范围是1到n,我们可以使用数组本身的索引作为哈希表的键。这里的关键在于利用每个元素的值作为数组索引,并利用正负号来标记元素是否出现过。

以下是解决这个问题的算法步骤:

遍历数组中的每个元素num。
取num的绝对值abs(num),将其对应的数组位置上的数取反(如果为正则变为负,如果为负则变为正)。
如果取反后的数已经为负,说明num之前已经出现过,因此num是一个出现两次的元素,打印或记录它。
由于我们修改了数组,所以在后续遍历中需要取绝对值来确保索引正确。
这里需要注意,如果数组中存在负数,直接取反可能会产生错误。因此,我们需要对负数进行特殊处理,或者确保问题定义中不包含负数。在这个特定问题中,由于元素范围是1到n,我们可以安全地使用上述方法。

以下是实现这个算法的JavaScript代码:


function findRepeat2Element(arr) {  
    const n = arr.length;  
    const result = []; // 用于存储出现两次的元素  
  
    for (let i = 0; i < n; i  ) {  
        const num = Math.abs(arr[i]); // 取绝对值以确保索引正确  
        const index = num - 1; // 转换为索引(因为数组索引从0开始)  
  
        // 如果对应位置上的数已经是负数,说明之前已经访问过,即出现了两次  
        if (arr[index] < 0) {  
            result.push(num); // 记录出现两次的元素  
        } else {  
            // 否则,标记该位置上的数为负数,表示已经访问过  
            arr[index] = -arr[index];  
        }  
    }  
  
    return result;  
}  
  
// 示例  
const arr = [4, 3, 2, 7, 8, 2, 3, 1];  
console.log(findRepeat2Element(arr)); // 输出: [2, 3]

请注意,这个算法会修改原始数组。如果原始数组不应该被修改,那么这个问题在O(n)时间复杂度和不使用额外空间的限制下是无法解决的,因为我们需要某种方式来跟踪元素的出现次数,而这通常需要额外的空间。然而,根据题目描述,我们可以假设修改原始数组是允许的。

4.给定一个只包括’(‘,’)‘,’{', ‘}’, ‘[’, ‘]’, 的字符串S,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 示例 1: 输入:s=“()” 输出:true 示例 2: 输入:s=“{[()]}” 输出:true 示例3: 输入:S=“(” 输出:false 示例4: 输入:S=“{(]}” 输出:false function isValid(str) { }

代码语言:javascript复制
解决思路:你可以使用栈来解决这个问题。遍历输入的字符串,每次遇到一个左括号('('、'{' 或 '[')时,将其压入栈中。
每次遇到一个右括号时,检查栈顶元素是否是与该右括号匹配的左括号。
如果是,则从栈中弹出该左括号;如果不是,则字符串无效。
最后,如果栈为空,说明所有括号都正确匹配,字符串有效;否则,字符串无效。


以下是相应的JavaScript实现:

function isValid(str) {  
    const stack = [];  
    const map = {  
        ')': '(',  
        '}': '{',  
        ']': '['  
    };  
  
    for (let i = 0; i < str.length; i  ) {  
        const char = str[i];  
        if (char === '(' || char === '{' || char === '[') {  
            // 如果是左括号,则压入栈中  
            stack.push(char);  
        } else if (char === ')' || char === '}' || char === ']') {  
            // 如果是右括号,则检查栈顶元素是否匹配  
            if (stack.length === 0 || stack.pop() !== map[char]) {  
                return false;  
            }  
        }  
    }  
  
    // 如果栈为空,说明所有括号都正确匹配  
    return stack.length === 0;  
}
这个算法的时间复杂度是O(n),其中n是输入字符串的长度。因为我们只需要遍历一次字符串,并在栈中进行常数时间的操作。
空间复杂度也是O(n),因为在最坏的情况下,我们可能需要将字符串中的所有左括号都压入栈中。

5.实现一个debounce方法 function debounce (fn, wait, immediate) { //TODO: }

代码语言:javascript复制
function debounce(func, wait, immediate) {
    let time
    let debounced = function() {
        let context = this
        if(time) clearTimeout(time)

        if(immediate) {
            let callNow = !time
            if(callNow) func.apply(context, arguments)
            time = setTimeout(
                ()=>{time = null} //见注解
            , wait)
        } else {
            time = setTimeout(
                ()=>{func.apply(context, arguments)}
            , wait) 
        }
    }

    debounced.cancel = function() {
        clearTimeout(time)
        time = null
    }

    return debounced
}

详情可以看看这篇博客:https://blog.csdn.net/Beijiyang999/article/details/79832604?ops_request_misc=&request_id=&biz_id=102&utm_term=用js实现一个debounce方法&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-79832604.142^v99^pc_search_result_base6&spm=1018.2226.3001.4187

6、设计一个简单的红绿灯策略,比如红灯亮分别为console.log(“red”)这种,要求按照红2s-黄1s-绿1s顺序不断循环展示。

代码语言:javascript复制
let lightStatus = "red";
let lightInterval = null;

function changeLightStatus() {
    if (lightStatus === "red") {
        console.log("red");
        lightStatus = "yellow";
        setTimeout(changeLightStatus, 2000); // 红灯亮2秒
    } else if (lightStatus === "yellow") {
        console.log("yellow");
        lightStatus = "green";
        setTimeout(changeLightStatus, 1000); // 黄灯亮1秒
    } else if (lightStatus === "green") {
        console.log("green");
        lightStatus = "red";
        setTimeout(changeLightStatus, 1000); // 绿灯亮1秒
    }
}

function startLights() {
    lightInterval = setInterval(changeLightStatus, 2000); // 初始设置为2秒,但会在changeLightStatus中调整
}

function stopLights() {
    clearInterval(lightInterval);
    lightInterval = null;
}

// 开始红绿灯循环
startLights();

// 如果你想在某个时刻停止红绿灯循环,可以调用stopLights()
// stopLights();

在这个示例中,我们定义了三个状态:red、yellow和green,并使用setTimeout来设置每个灯亮的持续时间。
我们使用setInterval来启动整个循环,但初始间隔设置为2秒(红灯的持续时间)。
在changeLightStatus函数中,我们根据当前状态来改变状态,并设置下一个状态的持续时间。
这样,每次调用changeLightStatus时,都会根据当前状态调整下一个调用的时间间隔。
当你想要停止红绿灯循环时,可以调用stopLights()函数来清除setInterval。

7、完成下面函数,对输入的数组去重,返回新的没有重复项的数组

代码语言:javascript复制
const uniqueArray = (array) => {
   return array.filter((item,index)=>{
    return array.indexOf(item)===index;
   })
}

const a = ['1', '2', '3', 1, '2', undefined, undefined, null, null, 1, 'a','b','b'];
console.log(uniqueArray(a)); // ["1", "2", "3", 1, undefined, null, "a", "b"]

8、分别写出下列输出

代码语言:javascript复制
function fruits() {}
fruits.prototype = {
	color: 'red',
	say: function() {
		console.log(this.color);
	}
};
var apple = new fruits();
apple.say();   // red, 此时方法里面的this 指的是fruits
banana = {color: 'yellow'};
apple.say.call(banana);
apple.say.apply(banana);
apple.say.apply(null);

//red
//yellow
//yellow
//undefined

0 人点赞