前端面试代码题

本文总结面试过程中遇到的代码题。

1. 变量提升

2. 数组相关的方法

注意返回true值是保留不是过滤,别记反。没啥,就是gap半年在面不写会忘的。。。

arr.filter((item, index, current) => {return arr.indexOf(item) == index});。可以去重

filter本质还是建了一个新的数组,回调函数里返回true则保留。上面一行代码表示重复的只往里面放第一次。

双指针去重:

使用双指针去重排序好的数组,相等的话fast指针右移一位,不相等的话slow右移一位,将fast位置的值保存,fast右移一位比较下一次:

function doublePointer(nums) {
    if(nums.length < 2) {
        return nums;
    }
    let slow = 0;
    let fast = 1;
    let result = [nums[0]];
    while(fast < nums.length) {
        if (result[slow] == nums[fast]) {
            fast++;
        } else {
            slow++;
            result[slow] = nums[fast];
            fast++;
        }
    }
    return result;
}
const arr = [1,1,2,2,4,4];
console.log(doublePointer(arr));

输入[1,1,2,2,4,4]输出[1,2,4]。

如果数组是个对象:

const arr2 = [{id:1,time: 2},{id:1,time: 4},{id:2,time: 2},{id:2,time: 4},{id:3,time: 5},

{id:3,time: 2}];

 现在需要根据id去重,id相等的情况下,只保留time最大的对象,输出:

[ { id: 1, time: 4 }, { id: 2, time: 4 }, { id: 3, time: 5 } ]

function doublePointerByorder(nums) {
    if(nums.length < 2) {
        return nums;
    }
    let slow = 0;
    let fast = 1;
    let result = [nums[0]];
    while(fast < nums.length) {
        if (result[slow].id == nums[fast].id) {
            if(result[slow].time < nums[fast].time) {
                result[slow] = nums[fast];
            }
            fast++;
        } else {
            slow++;
            result[slow] = nums[fast];
            fast++;
        }
    }
    return result;
}

console.log(doublePointerByorder(arr2));即可。

当然这里可以使用空对象去记,每次取对象里id对应的那个time比较,选择是否覆盖。遍历完使用for in循环将对象转数组。不过双指针效率非常高,如果是数据量很大的话,用双指针会比较合适。

3. 引用相关

引用类型变量的等于号赋值,不会相互影响。

但是通过a.b的方式会影响,此时算浅复制,如下所示。

person1 = {name: 3};
members = person1;
members.name = 4;   // person1.name=4

下面看一个引用相关的经典案例,也是面试时第一次遇到时没有写出来的问题,将数组转成树形结构:

function arrayToTree(items) {
    const tree = {};
    const map = {};
    items.forEach((item, index) => {
        const { id, parentId } = item;
        if (!map[id]) map[id] = { children: [] };
        const node = { ...item, children: map[id].children};
        map[id] = node;
        if (parentId) {
            if (!map[parentId]) {
                map[parentId] = { children: [] };
            } map[parentId].children.push(node);
        } else {
            tree[id] = node;
        }
    });
    console.log(map);
}

// 示例数组
const items = [
    { id: 1, parentId: null, value: "A" },
    { id: 2, parentId: 1, value: "B" },
    { id: 3, parentId: 1, value: "C" },
    { id: 4, parentId: 2, value: "D" },
    { id: 5, parentId: 3, value: "E" }
];

// 转换为树
const tree = arrayToTree(items);

可以直接复制看效果,就跟俄罗斯套娃一样,第二层加到第一层好理解,难点在于第三层加到第二层时,第一层的第二层下面也多了第三层的数据, 其实仔细想一想就能明白了,a["1"]下面有个a["1"].children["2"],他的值和a["2"]不仅相等而且引用都相同,且执行a["1"].children.push(a["2"]);。这样的好处时到a["3"]={...item, children:[]}时,执行a["2"].children.push(a["3"]),由于是操作里面的数据,所以有相同引用的地方(例如a=b,b.push也会影响a.push)也会push,所以你会看到a["1"].children["2"].children里面有个a["3"]。这样树结构就对啦。

还不理解可以试试下面的做法:

如上所示:b1看作是a1的一级节点,修改b1会影响a1。尽管上面是循环,但是每个作用域里的引用相同的。

3. 宏任务微任务

2 4 5同步代码,3微任务,1宏任务。唯一的坑就是4会打印,return 3就不会执行 

4. 比较运算符

隐式转换比较时,数组调用了toString方法。

5. 防抖节流手写

自己要写一写,如果看过没写过,面试要手撕,大概率撕不出来。下面分别是:防抖立即执行和延迟执行,节流立即执行和延迟执行

function debounce(fn, delay) {
    let timer = null;
    return function (...args) {
        timer && clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    }
}

function debounce_immediate(fn, delay, immediate = false) {
    let timer = null;
    let flag = true;
    return function (...args) {
        timer && clearTimeout(timer);
        if (immediate) {
            if (flag) {
                fn.apply(this, args);
                flag = false;
            }
            timer = setTimeout(() => {
                flag = true;
            }, delay);

        } else {
            timer = setTimeout(() => {
                fn.apply(this, args);
            }, delay);
        }
    }
}

function throttle(fn, delay) {
    let lastTime = 0;
    let timer = null;
    return function (...args) {
        const nowTime = Date.now();
        if (nowTime - lastTime > delay) {
            fn.apply(this, args);
            lastTime = nowTime;
        }
    }
}

function throttle_D(func, delayTime) {
    let delay = delayTime || 1000;
    let timer = null;
    return function (...args) {
        if (!timer) {
            timer = setTimeout(function () {
                func.apply(this, args);
                timer = null;
            }, delay);
        }
    }
}

记得带上args,防抖和节流本质的区别是防抖一直在重置定时器,节流不是的,节流一直触发的话在一定时间间隔内都会执行且只执行一次。防抖如果一直触发个一分钟,那也只会执行一次(立即执行或者最后一次点击时触发延迟执行)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/792543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端 js 单引号,双引号、斜杠, 表格 tr input、checkbox、、、、

直接上代码 var target (leftOrRight LEFT ? $("#left") : $("#right"));target.empty();// let tbody $("resultRight tbody");// tbody.empty();for (var i 0; i < items.length; i) {debugger// target.append("<option valu…

【数据结构】线性表----队列详解

1. 队列的基本概念 话不多说&#xff0c;直接开始&#xff01; 队列是一种线性数据结构&#xff0c;同栈类似但又不同&#xff0c;遵循先进先出&#xff08;FIFO, First In First Out&#xff09;的原则。换句话说&#xff0c;最先进入队列的元素会最先被移除。这样的特点使得…

【Spring Cloud精英指南】深度探索与实战:网关Gateway的高级应用与最佳实践

1. 前言 Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式&#xff0c;并为它们提供一些网关基本功能&#xff0c;…

IntelliJ IDEA 2024.1.4最新教程!!直接2099!!爽到飞起!!

IntelliJ IDEA 2024.1.4最新破解教程&#xff01;&#xff01;直接2099&#xff01;&#xff01;爽到飞起&#xff01;&#xff01;【资源在末尾】安装馆长为各位看官准备了多个版本&#xff0c;看官可根据自己的需求进行下载和选择安装。https://mp.weixin.qq.com/s/Tic1iR_Xc…

C语言-顺序表

&#x1f3af;引言 欢迎来到HanLop博客的C语言数据结构初阶系列。在这个系列中&#xff0c;我们将深入探讨各种基本的数据结构和算法&#xff0c;帮助您打下坚实的编程基础。本次我将为你讲解。顺序表&#xff08;也称为数组&#xff09;是一种线性表&#xff0c;因其简单易用…

常用录屏软件,分享这四款宝藏软件!

在数字化时代&#xff0c;录屏软件已经成为我们日常工作、学习和娱乐中不可或缺的工具。无论你是需要录制教学视频、游戏过程&#xff0c;还是进行产品演示&#xff0c;一款高效、易用的录屏软件都能让你的工作事半功倍。今天&#xff0c;就为大家揭秘四款宝藏级录屏软件&#…

Ajax从零到实战

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

性价比高充电宝有哪些?充电宝十大最佳品牌大盘点!

在如今这个高度数字化的时代&#xff0c;我们的生活离不开各种电子设备&#xff0c;而充电宝作为保障电子设备续航的重要工具&#xff0c;其地位日益凸显。然而&#xff0c;面对市场上琳琅满目的充电宝品牌和产品&#xff0c;要挑选到一款性价比高的充电宝并非易事。在这篇盘点…

java使用easypoi模版导出word详细步骤

文章目录 第一步、引入pom依赖第二步、新建导出工具类WordUtil第三步、创建模版word4.编写接口代码5.导出结果示例 第一步、引入pom依赖 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><…

element-ui操作表格行内容如何获取当前行索引?

需求&#xff1a; 根据每个用户的提交次数、撤回次数&#xff0c;动态计算出实际次数&#xff0c;并且提交次数不能小于撤回次数 <template><div><el-table:data"tableData"style"width: 80%"border><el-table-columnprop"date&…

【IOS】React Native之HelloWorld

RN搭建开发环境 rvm 安装3.2.2 brew install node18 brew install watchman# 使用nrm工具切换淘宝源 npx nrm use taobao# 如果之后需要切换回官方源可使用 npx nrm use npmnpm install -g yarnbrew install cocoapodsnpm uninstall -g react-native-cli react-native-communi…

(c#实现)决策树算法原理和案例

一、引言 决策树&#xff08;Decision Tree&#xff09;是一种常用的监督学习算法&#xff0c;广泛应用于分类和回归任务。它的直观性和可解释性使其成为机器学习和数据挖掘领域的重要工具。本文将详细介绍决策树的原理&#xff0c;并通过一个实际案例展示如何使用C#实现决策树…

【MindSpore学习打卡】应用实践-LLM原理和实践-基于MindSpore实现BERT对话情绪识别

在当今的自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情绪识别是一个非常重要的应用场景。无论是在智能客服、社交媒体分析&#xff0c;还是在情感计算领域&#xff0c;准确地识别用户的情绪都能够极大地提升用户体验和系统的智能化水平。BERT&#xff08;Bidirec…

C++类和对象学习笔记

1.类的定义 1.1类定义的格式 class是定义类的关键字&#xff0c;Date为类的名字&#xff0c;{ }中为类的主体&#xff0c;注意定义类结束时后面的分号不能省略。类中的内容称为类的成员&#xff1b;类中的变量称为类的属性或成员变量&#xff1b;类中的函数称为类的方法或者成…

jdk1.8安装教程及环境变量配置(含jdk8,11,13安装文件)

目录 友情提醒第一章、JVM、JRE、JDK介绍第二章、下载和安装JDK2.1&#xff09;百度网盘直接下载免安装2.2&#xff09;官网下载安装JDK&#xff08;需要收费&#xff09; 第三章、环境变量配置3.1&#xff09;windows环境变量配置3.2&#xff09;验证环境变量是否配置成功 友情…

类和对象——【运算符重载】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件iostream的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

PDA:Prompt-based Distribution Alignment for Unsupervised Domain Adaptation

文章汇总 式中&#xff0c; y s y^s ys表示源域数据的one-hot ground-truth&#xff0c; K K K为类数&#xff0c; w i w_i wi​和 z ~ s \tilde{z}_s z~s​分别表示源域经过提示调优的最终文本表示和最终图像表示的第 i i i类。 同理&#xff0c;为了进一步利用目标领域的数据…

ARMV8安全特性:Pointer Authentication

文章目录 前言一、Introduction二、Problem Definition三、Pointer Authentication3.1 Instructions3.2 Cryptography3.3 Key Management 四、Sample Use Cases4.1 Software Stack Protection4.2 Control Flow Integrity (CFI)4.3 Binding Pointers to Addresses 五、Security …

B2B领域的客户裂变策略:打造行业内的共赢生态

在日益竞争激烈的B2B市场中&#xff0c;客户裂变作为一种高效的增长策略&#xff0c;不仅能够帮助企业快速扩大客户基础&#xff0c;还能促进行业内资源共享与合作&#xff0c;共同构建一个健康、可持续的共赢生态。本文将探讨B2B领域实施客户裂变策略的关键要素&#xff0c;以…