2024暑期实习前端面试手撕代码篇(自用)(更新中)

226 阅读4分钟

JS基础题


写一个带使用场景的防抖和节流操作

防抖

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>防抖设计</title>
    </head>
    <body>
        <button id="btn">Click Me</button>
        <script>
            //防抖函数
            function debounce(fn,wait){
                let setTime=0;
                return function(){
                    clearTimeout(setTime)
                    let args=arguments;
                    let content=this;
                    setTime=setTimeout(()=>{
                        fn.apply(content,args)
                    },wait)
                }
            }

            //搜索框输入时触发防抖函数
            function search(){
                // 模拟发送搜索请求
                console.log('Searching...')
            }

            const debouncedSearch=debounce(search,300)

            document.getElementById('btn').addEventListener('click',debouncedSearch)
        </script>
    </body>
</html>

节流 使用vue.js

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>节流设计</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="searchText" @input="throttledSearch">
            <p>Searching for {{ searchText }}</p>
        </div>
        
        <script>
        new Vue({
            el:'#app',
            data:{
                searchText:''
            },
            methods:{
                //节流函数
                throttle(fn,wait){
                    let setTime=0;
                    return function(){
                        let content=this;
                        let args=arguments;
                        let curTime=Date.now()
                        if(curTime-setTime>=wait){
                            fn.apply(content,args)
                            setTime=curTime
                        }
                    }
                },
                // 使用场景:搜索框输入时触发搜索请求
                search(){
                    console.log('Searching for:', this.searchText)
                },               
            },   
            computed: {
                // 节流搜索方法作为计算属性
                throttledSearch() {
                    return this.throttle(this.search, 1000);
                }
            }
                 
        })
        </script>
    </body>
</html>

实现深拷贝

function deepClone(obj){
    if(typeof obj!=='object'||obj===null) return obj
    let newObj;
    newObj=Array.isArray(obj)?[]:{}
    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            newObj[key]=typeof obj[key]==="object"?deepClone(obj[key]):obj[key]
        }
    }
    return newObj
}

let obj={
    'name':"汪汪",
    'age':"2",
    'message':{
        'height':'10',
        'weight':'100'
    },
    'date':Date.now()
}
let obj1=deepClone(obj)
obj.name="咪咪"
obj.message.height="12"
console.log(obj1)

输出:{ name: '汪汪', age: '2', message: { height: '10', weight: '100' }, date: 1713017041224 }

解析url地址栏参数

function parseParam(url){
    //将?之后的字符取出来
    const paramStr=/.+\?(.+)$/.exec(url)[1]
    // 将字符串以 & 分割后存到数组中
    const paramsArr=paramStr.split('&');
    let paramsObj={}
    // 将 params 存到对象中
    paramsArr.forEach(param=>{

        // 处理有 value 的参数
        if(/=/.test(param)){
            // 分割 key 和 value
            let [key,val]=param.split('=')
            // 解码
            val=decodeURIComponent(val);
            // 判断是否转为数字
            val=/^\d+$/.test(val)?parseFloat(val):val;
            
            if(paramsObj.hasOwnProperty(key)){
                // 如果对象有 key,则添加一个值
                paramsObj[key]=[].concat(paramsObj[key],val)
            }else{
                // 如果对象没有这个 key,创建 key 并设置值
                paramsObj[key] = val;
            }
        }else{
            // 处理没有 value 的参数
            paramsObj[param]=true
        }
    })
    return paramsObj
}
const url = new URL('https://example.com/?q=123456&a=b&a=c&a=%E5%AD%97%E7%AC%A6%E4%B8%B2split%E6%96%B9%E6%B3%95');
const paramObj = parseParam(url);
console.log(paramObj);

输出:{ q: 123456, a: [ 'b', 'c', '字符串split方法' ] }

Promise的基本用法

数据处理题


写一个最熟悉的排序算法

求后序遍历

已知前序遍历和中序遍历结果,求后序遍历结果。

求链表的倒数第k个(难度:简单)

(LCR 140. 训练计划 II) 给定一个头节点为 head 的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt 个训练项目编号。

示例 1:

输入:head = [2,4,7,8], cnt = 1

输出:8

思路: 双指针,先让快指针走k步,然后让快慢指针一起走。当快指针指向链表尾部的空节点时,慢指针所指向的就是倒数第k个。

var trainingPlan = function(head, cnt) {
    let left=head,right=head;
    for(let i=0;i<cnt;i++){
        right=right.next;
    }
    while(right){
        left=left.next
        right=right.next
    }
    return left
};

大数相加(难度:简单)

(415. 字符串相加 - 力扣(LeetCode))

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和,并同样以字符串形式返回。

你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。

示例 1:

输入:num1 = "11", num2 = "123"

输出:"134"

示例 2:

输入:num1 = "456", num2 = "77"

输出:"533"

最接近的三数之和(难度:中等)

(16. 最接近的三数之和 - 力扣(LeetCode))

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

示例 1:

输入:nums = [-1,2,1,-4], target = 1

输出:2

解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

示例 2:

输入:nums = [0,0,0], target = 1

输出:0

找到两个数组的公共元素(难度:简单)

(2956. 找到两个数组中的公共元素 - 力扣(LeetCode))

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,它们分别含有 n 和 m 个元素。

请你计算以下两个数值:

统计 0 <= i < n 中的下标 i ,满足 nums1[i] 在 nums2 中 至少 出现了一次。 统计 0 <= i < m 中的下标 i ,满足 nums2[i] 在 nums1 中 至少 出现了一次。 请你返回一个长度为 2 的整数数组 answer ,按顺序 分别为以上两个数值。

示例 1:

输入:nums1 = [4,3,2,3,1], nums2 = [2,2,5,2,3,6]

输出:[3,4]

解释:分别计算两个数值:

  • nums1 中下标为 1 ,2 和 3 的元素在 nums2 中至少出现了一次,所以第一个值为 3 。
  • nums2 中下标为 0 ,1 ,3 和 4 的元素在 nums1 中至少出现了一次,所以第二个值为 4 。

示例 2:

输入:nums1 = [3,4,2,3], nums2 = [1,5]

输出:[0,0]

解释:两个数组中没有公共元素,所以两个值都为 0 。

var findIntersectionValues = function(nums1, nums2) {
    let set1=new Set(nums1);
    let set2=new Set(nums2);

    let res1=0,res2=0;
    nums1.forEach(item=>{
        if(set2.has(item)){
            res1++
        }
    })
    nums2.forEach(item=>{
        if(set1.has(item)){
            res2++
        }
    })
    return [res1,res2]
};

场景题


设计页面布局:有一个头部、有一个侧边栏