记录面试代码题,持续更新中

总结一下面试的时候遇到的代码题吧,仅供参考,欢迎讨论指正

1、深浅克隆,以及自定义方法实现深克隆

// 浅克隆
Object.assign()
// 深克隆
JSON.parse(JSON.stringify(obj));
// 自定义深克隆
function deepCopy(obj){
    // 接受一个参数 obj
    // 判断传入的 obj 是否为对象类型
    if (typeof obj == 'object') {
        // 根据 obj 的类型构造 result 变量,如果是数组则创建空数组,否则创建空对象
        var result = obj.constructor == Array ? [] : {};
        // 遍历 obj 的属性
        for(let i in obj) {
        // 如果 obj 属性的值还是一个对象,递归调用函数进行深拷贝;否则直接将简单值赋值给 result 对象的同名属性
            result[i] = typeof obj[i] == 'object' ? deepCopy(obj[i]) : obj[i];
        }
    } else {
        // 如果 obj 是简单类型,则将它直接赋值给 result
        var result = obj;
    }
    // 返回赋值后的 result 对象
    return result;
}

2、求两个一维数组的交集

function intersection(arr1, arr2) {
    // 使用 filter() 方法筛选出在两个数组都存在的元素。
    const result = [...arr1].filter(item => arr2.includes(item));
    return result;
}
// 示例:
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];
console.log(intersection(array1, array2)); // [4, 5]
// 此方法有缺陷,无法检测重复存在的元素
// 根据百度大佬的提示 重写一个方法
function arrayIntersection(arr1, arr2) {
  // 使用 Map 存储 arr1 中出现的元素及其出现次数
  const map1 = new Map();
  arr1.forEach((item) => {
    map1.set(item, (map1.get(item) || 0) + 1);
  });
  // 遍历 arr2,并与 map1 中的元素进行匹配
  const result = [];
  arr2.forEach((item) => {
    if (map1.get(item)) {
      result.push(item);
      map1.set(item, map1.get(item) - 1);
    }
  });
  return result;
}
// 示例用法:
const arr1 = ["a", "b", "c", "d", "d", "d"];
const arr2 = ["b","b", "d", "d", "e"];
const intersection = arrayIntersection(arr1, arr2); // ['b', 'd', 'd']

3、数据转换成树状结构

function flattenToTree(data) {
    // 遍历数据数组,生成 ID 到元素映射对象
    const idMap = data.reduce((acc, el) => {
        acc[el.id] = el;
        return acc;
    }, {});

    const roots = [];
    data.forEach((item) => {
        if (item.parentId === null) {
            // 如果没有父级ID,它就是一个顶级节点
            roots.push(item);
            return;
          }
          // 其他情况则将该节点挂载到其父亲下面
          const parent = idMap[item.parentId];
          if (!parent.children) {
            // 检查它是否存在子节点,没有则新建一个空白数组
            parent.children = [];
          }
          parent.children.push(item);
    });
    return roots;
}

4、匹配出 https://www.js.cn/list/show.aspx?version=7&openType=redesign&curid=217541718&nqt=###中的openType

const url = "https://www.js.cn/list/show.aspx?version=7&openType=redesign&curid=217541718&nqt=###";
// 获取问号后面的所有参数 
//version=7&openType=redesign&curid=217541718&nqt=###
const searchParamStr = url.slice(url.indexOf('?') + 1);
// 将参数字符串按照 & 分割成数组
// ['version=7', 'openType=redesign', 'curid=217541718', 'nqt=###']
const searchParamsArr = searchParamStr.split('&');
// 遍历数组,将每个参数拆开并存入对象中
const params = {};
for (let i = 0; i < searchParamsArr.length; i++) {
  const [key, value] = searchParamsArr[i].split('=');
  params[key] = value;
}
console.log(params);
console.log(params.openType);
// 输出 { version: '7', openType: 'redesign', curid: '217541718', nqt: '###' }

5、写一个双色球的算法函数,要求从1~36选出6个不重复的红球,从1~16里选出1个篮球,如返回[[1,3,4,9,21,27],21]

 这题当时直接蒙了,啥是双色球,什么红球篮球。。。等我冷静下来有点超时了,硬着头皮写出的第二种方法,总结的时候想出的第一种方法~

//  方法一:
function pickLotteryNumbers() {
  const redBallsArray = new Array(36).fill(0).map((_, i) => i + 1); // 构造 1~36 的红球数组
  const blueBallsArray = new Array(16).fill(0).map((_, i) => i + 1); // 构造 1~16 的蓝球数组
  const lotteryNumbers = []; // 存放彩票号码的数组

  for (let i = 0; i < 6; i++) {
    const index = Math.floor(Math.random() * redBallsArray.length); // 随机选择一个位置
    const ball = redBallsArray.splice(index, 1)[0]; // 取出该位置上的球,并从数组中删除

    lotteryNumbers.push(ball); // 将选出的红球存入结果数组
  }

  const blueIndex = Math.floor(Math.random() * blueBallsArray.length);
  const blueBall = blueBallsArray[blueIndex]; // 随机选择一个篮球,并记录下来
  lotteryNumbers.sort((a, b) => a - b); // 我不知道双色球是啥,不知道用不用排序
  return [lotteryNumbers, blueBall]; // 返回结果数组
}

//  方法二:
function getBall(){
    function selectNum(n, min, max){
        const num = new Set()
        while (num.size < n) {
            const number = Math.floor(Math.random()*(max-min+1)+min)
            num.add(number)
        }
        return Array.from(num)
    }
    const redBall = selectNum(6,1,36)
    const blueBall = selectNum(1,1,16)[0]
    return [redBall, blueBall]
}
/*
*首先创建了一个空白的 Set,然后进入一个 while 循环。
*循环体会反复执行,直到 Set 的大小达到预设的随机选数目 n。
*每轮循环中我们用 Math.random() 生成介于指定区间 [min, max] 范围内的随机整数
*数字去重使用 Set 来处理,确保了结果中不会有重复的数字。
*/

6、this指向问题

// 面试题 第一题

const a = {
  b:()=>{
    console.log(this)
  }
}
a.b()
const c = a.b
c()

// 第二题

const a2 = {
  b:function(){
    console.log(this)
  },
  function(){
    console.log(this)
  }
}
a2.b()
const c2 = a.b
c2()

7、写一个按钮基于antd,写个通用组件,按一下3秒内disable

const newBtn = ({ children, onClick, ...restProps }) => {
  const [disabled, setDisabled] = useState(false);

  const handleClick = e => {
    if (disabled) return;
    setDisabled(true);
    onClick(e);
    setTimeout(() => {
      setDisabled(false);
    }, 3000);
  };

  // 面试官提到了useCallback,优化一下,脑子空白,结束了才反应过来
  // onClick 和 disabled 发生变化时, handleClick 函数会重新生成
  // 在父级组件更新而导致该组件重新渲染时,可以直接复用之前所生成的同一个事件处理函数
  const handleClick = useCallback(e => {
    if (disabled) return;
    setDisabled(true);
    onClick(e);
    setTimeout(() => {
      setDisabled(false);
    }, 3000);
  }, [onClick, disabled]);

  return (
    <Button {...restProps} disabled={disabled} onClick={()=>handleClick(e)}>
      {children}
    </Button>
  );
};

8、用Promise封装一个settimeout

// 实现以下功能
// cosnt obj = delay(2000, 1) 两秒后输出1
// obj.then(console.log)
// obj.cancel()  这一步是终止输出(问终止后promise状态:pending[待定]初始状态)
// 考点:resolve() 后修改promise的状态为fullfiled
function delay(time, data) {
  let timeout;
  const promise = new Promise((resolve)=>{
    timeout = setTimeout(()=>{
      resolve(data)
    },time)
  })
  promise.cancel = function () {
    clearTimeout(timeout);
  };
  return promise;
}

 9、写个倒计时页面

const App = () => {
  const [time, setTime] = useState(60);
  useEffect(() => {
    const timer = setInterval(() => {
      // 检查是否已到 0,若到 0 则立即清除定时器,避免多触发更新
      if (time - 1 <= 0) {
        clearInterval(timer);
      } else {
        setTime(time - 1);
      }
    }, 1000);
    // 清理函数:在下一次副作用或组件卸载前,清除定时器
    return () => clearInterval(timer);
  }, [time]);

  return (
    <div>
      {time}
    </div>
  );
};

10、多维数组对象,将 "name" 属性更改为 "title"

const data = [
  {
    name: 'a',
    children: [
      {
        name: 'b',
        children: [
            {
              name: 'a',
              children: []
            },
            {
              name: 'a',
              children: []
            }
        ]
      }
    ]
  },
  {
    name: 'a',
    children: [
      {
        name: 'b',
        children: []
      }
    ]
  }
];
// 根据面试官的提示优化了一下方法
function updateList(data) {
  return data.map(item => {
    const { name, children } = item;
    const newItem = { title: name };

    if (children && children.length > 0) {
      newItem.children = updateList(children);
    } else {
      newItem.children = [];
    }
    return newItem;
  });
}

 11、回文字符串

function isPalindrome(inputString) {
  // 提取所有字母并全部转换成小写,转换成数组,过滤出数字字母
  const strArray = inputString
    .toLowerCase()
    .split('')
    .filter(char => char >= 'a' && char <= 'z');

  // 将字符数组转为字符串以便于比较。
  const str = charactersArray.join('');

  // 倒序的字符数组
  const reversedStrArray  = strArray .reverse();

  // 将倒序的字符数组转为字符串以便于比较。
  const reversedStr = strArray .join('');

  // 比较原字符串和倒序字符串是否相等。
  return str === reversedStr;
}
console.log(isPalindrome("A man, a plan, a canal: Panama")); // 输出 true

12、原形原型链

Function.prototype.a() = alart(1)
Object.prototype.b() = alart(2)
function a(){}
let a = new a()

a.a()
a.b()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值