蚂蚁集团前端手撕题目(3+)

代码题目👉

一、计算最长不重复子串

实现思路:
使用滑动窗口(双指针)和哈希表优化时间复杂度。右指针扩展窗口,遇到重复字符时,左指针跳跃到重复字符的下一位,同时用哈希表记录字符的最新位置。

JavaScript实现:

function longestSubstring(s) {
    let map = new Map(), max = 0, left = 0;
    for (let right = 0; right < s.length; right++) {
        const c = s[right];
        if (map.has(c) && map.get(c) >= left) {
            left = map.get(c) + 1; // 左边界跳跃到重复字符后
        }
        map.set(c, right); // 更新字符的最新位置
        max = Math.max(max, right - left + 1);
    }
    return max;
}


复杂度:时间复杂度 O(n),空间复杂度 O(字符集大小)(如ASCII字符集为常数级)。

二、实现防抖函数

核心逻辑:在事件触发后等待固定时间,若期间再次触发则重置计时,最终只执行最后一次触发对应的函数。

JavaScript实现:

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

// 示例:输入框搜索防抖
const inputEl = document.getElementById('search-input');
const debouncedSearch = debounce((query) => {
    console.log('Search:', query);
}, 500);
inputEl.addEventListener('input', (e) => debouncedSearch(e.target.value));


三、实现管道函数 pipe

功能:将多个函数按顺序组合,前一个函数的返回值作为后一个的输入参数。

JavaScript实现:

function pipe(funcs) {
    return function (initialValue) {
        return funcs.reduce((acc, fn) => fn(acc), initialValue);
    };
}

// 示例:计算 (x*2 + 3)*4
const times = (n) => (x) => x * n;
const plus = (n) => (x) => x + n;
const pipeline = pipe([times(2), plus(3), times(4)]);
console.log(pipeline(5)); // 输出:(5*2+3)*4 = 52


四、解析URL

方法:使用浏览器原生 URL 对象和 URLSearchParams API,可高效解析协议、路径、查询参数等。

JavaScript实现:

function parseUrl(urlString) {
    const url = new URL(urlString);
    return {
        protocol: url.protocol,   // 协议(如 "https:")
        hostname: url.hostname,   // 域名(如 "example.com")
        pathname: url.pathname,   // 路径(如 "/path")
        searchParams: Object.fromEntries(url.searchParams) // 查询参数对象
    };
}

// 示例解析
const result = parseUrl("https://example.com/path?name=John&age=30");
console.log(result.searchParams); // 输出:{ name: "John", age: "30" }


关键点总结

1. 滑动窗口优化是解决最长不重复子串的最优方案,避免暴力法的 O(n²) 复杂度。

2. 防抖函数通过延迟执行减少高频事件触发的资源消耗,适用于搜索联想、窗口调整等场景。

3. 管道函数通过函数组合实现声明式编程,提升代码可读性。

4. URL解析推荐使用原生API,兼容性不足时可改用字符串分割或正则表达式。

手撕题目知识框架✍️

一、JavaScript基础与原理

1. 原型链与继承

  • 手写 new 运算符实现

  • 实现 Object.create() 的简化版

  • 继承方式的代码实现(如寄生组合继承)

2. 异步与事件循环

  • 实现 Promise.all/Promise.race

  • 手写 async/await 的Generator模拟

  • 事件循环顺序分析题(宏任务、微任务)

3. 闭包与作用域

  • 闭包陷阱场景题(如循环中延迟打印i的值)

  • 柯里化(Currying)函数实现

二、算法与数据结构

1. 数组与字符串处理

  • 扁平化数组(flatten)的多维处理

  • 最长公共前缀(LeetCode 14)

  • 实现模板字符串解析(类似${data}替换)

2. 树与链表操作

  • 二叉树层序遍历(BFS)

  • 反转链表(迭代/递归)

  • 虚拟DOM树的Diff算法简化实现

三、前端框架相关

1. React/Vue原理实现

  • 实现简易版 useState(状态管理)

  • 虚拟DOM转真实DOM的渲染函数

  • 响应式数据劫持(类似Vue 2的 Object.defineProperty)

2. DOM与事件

  • 事件委托实现动态元素点击监听

  • 拖拽组件的核心逻辑(mousedown/mousemove事件处理)

  • 实现防抖(Debounce)与节流(Throttle)

四、工程化与网络

1. 模块化与打包

  • 实现 require 的简化版(CommonJS模块加载)

  • 按需加载(Dynamic Import)的Promise封装

2. HTTP与浏览器

  • 手写 XMLHttpRequest 请求封装

  • Cookie与LocalStorage的读写工具函数

  • 跨域解决方案代码(如JSONP实现)

五、综合实战题

1. 组件设计题

  • 实现一个可配置的模态框组件(支持动画、遮罩层)

  • 封装表单校验工具(支持异步校验规则)

2. 性能优化场景

  • 长列表虚拟滚动(Virtual Scroll)核心逻辑

  • 图片懒加载的IntersectionObserver实现

考察重点与建议

1. 代码规范:变量命名、边界条件处理、可读性

2. 思维表达:解题思路的口头或注释说明

3. 底层原理:对JavaScript引擎、框架设计理念的理解。

 

一、JavaScript基础与原理

1. 手写 new 运算符

function myNew(constructor, ...args) {
  const obj = Object.create(constructor.prototype);
  const result = constructor.apply(obj, args);
  return result instanceof Object ? result : obj;
}


考察点:原型链继承、构造函数逻辑。
扩展:可结合寄生组合继承实现类继承场景。

2. 实现 Promise.all

function myPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let completed = 0;
    promises.forEach((p, i) => {
      Promise.resolve(p)
        .then(res => {
          results[i] = res;
          if (++completed === promises.length) resolve(results);
        })
        .catch(reject);
    });
  });
}


应用场景:并发请求处理、批量数据加载。

二、算法与数据结构

1. 数组分块(Chunk)

根据搜索结果中提到的真题,实现数组分块:

function chunk(arr, size) {
  const res = [];
  for (let i = 0; i < arr.length; i += size) {
    res.push(arr.slice(i, i + size));
  }
  return res;
}
// 测试:chunk(['a','b','c','d'], 2) → [['a','b'], ['c','d']]


考察点:数组操作、边界条件处理。

2. 文件路径转树形结构

真题高频题:

function buildTree(paths) {
  const tree = {};
  paths.forEach(path => {
    const parts = path.split('/');
    let current = tree;
    parts.forEach(part => {
      if (!current[part]) current[part] = {};
      current = current[part];
    });
  });
  return tree;
}
// 测试:buildTree(['src/index.js', 'src/utils.js']) → { src: { 'index.js': {}, 'utils.js': {} } }


关键点:递归或迭代处理层级结构、对象引用。

三、前端框架与工程化

1. 实现简易 useState

let state;
function useState(initialValue) {
  state = state ?? initialValue;
  const setState = (newValue) => {
    state = typeof newValue === 'function' ? newValue(state) : newValue;
    // 触发重渲染(此处简化为直接更新)
  };
  return [state, setState];
}


扩展:结合虚拟DOM的Diff算法实现更完整的状态更新逻辑。

2. 防抖与节流

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

// 节流
function throttle(fn, interval) {
  let last = 0;
  return (...args) => {
    const now = Date.now();
    if (now - last >= interval) {
      fn.apply(this, args);
      last = now;
    }
  };
}


应用场景:搜索联想输入、滚动事件优化。

四、综合实战题

1. 虚拟滚动核心逻辑

function virtualScroll(items, containerHeight, itemHeight) {
  const visibleCount = Math.ceil(containerHeight / itemHeight);
  let startIndex = 0;
  return function updateScroll(scrollTop) {
    const newStart = Math.floor(scrollTop / itemHeight);
    startIndex = Math.max(0, newStart - 2); // 预加载2项
    return items.slice(startIndex, startIndex + visibleCount + 4);
  };
}


优化点:动态计算渲染区间、DOM复用。

高频考察方向总结(根据补充)

1. CSS布局

  • 左侧定宽右侧弹性布局:display: flex; + flex: 1;

2. TypeScript

  • 类型推断与接口设计:interface User { id: number; name: string; }

3. HTTP/TCP

  • 三次握手、状态码(如304缓存)、HTTP/2多路复用。

投递建议与准备资源

1. 内推通道:通过官方内推链接(https://u.alipay.cn/_2YehV2IUVPjoPN3pYfcpzf)投递技术类岗位。

2. 重点复习:根据真题,强化 数组操作、树形结构处理、框架原理手写。

3. 模拟训练:使用在线OJ平台(如LeetCode、CodeFun)练习高频算法题。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GISer_Jinger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值