一、编程题实战

1. 实现 lodash 中的 get 函数(难度:🌟)

需求:根据路径字符串(如'a[3].b')获取数据中对应的值,无对应值时返回默认值。
实现思路:

 

 

javascript
 
 
 
 
 
const get = (data, path, defaultValue = void 0) => {
  // 解析路径为数组(处理 . 和 [] 分隔)
  const keys = path.replace(/\[(\d+)\]/g, '.$1').split('.').filter(k => k);
  let result = data;
  for (const key of keys) {
    // 若当前结果不存在,直接返回默认值
    if (result === null || result === undefined) return defaultValue;
    // 访问当前键(支持对象和数组)
    result = result[key];
  }
  // 最终结果不存在时返回默认值
  return result ?? defaultValue;
};
 

2. 实现 add (1)(2)(3)(难度:🌟)

需求:实现函数柯里化,支持add(1)(2)(3)或add(1,2)(3)等调用方式,返回累加结果。
基础版(固定参数):
javascript
 
 
 
 
 
const curry = (fn) => {
  const argLength = fn.length; // 原函数参数长度
  return function curried(...args) {
    // 若参数足够,执行原函数;否则返回新函数继续接收参数
    return args.length >= argLength 
      ? fn(...args) 
      : (...rest) => curried(...args, ...rest);
  };
};

// 使用:
const add = curry((a, b, c) => a + b + c);
console.log(add(1)(2)(3)); // 6
console.log(add(1, 2)(3)); // 6
 
进阶版(不定参数):
javascript
 
 
 
 
 
const curry = (fn) => {
  return function curried(...args) {
    // 若调用时无参数,执行累加;否则继续收集参数
    if (args.length === 0) {
      return fn(...args);
    } else {
      return (...rest) => curried(...args, ...rest);
    }
  };
};

// 使用:
const add = curry((...args) => args.reduce((a, b) => a + b, 0));
console.log(add(1)(2)(3)()); // 6
console.log(add(1, 2)(3, 4)()); // 10
 

3. 简单实现 async(难度:🌟🌟)

核心原理:async函数本质是返回 Promise 的语法糖,可基于 Generator 函数 + 自动执行器模拟,await对应yield的 Promise 处理。

 

javascript
 
 
 
 
 
// 自动执行Generator函数
function runGenerator(gen) {
  const iterator = gen();
  return new Promise((resolve, reject) => {
    function step(nextValue) {
      const { value: promise, done } = iterator.next(nextValue);
      if (done) {
        return resolve(promise); // 迭代完成,返回最终结果
      }
      // 处理yield的Promise
      Promise.resolve(promise).then(
        res => step(res), // 成功:将结果传入下一次迭代
        err => reject(err) // 失败:直接reject
      );
    }
    step(); // 启动迭代
  });
}

// 模拟async函数
const async = (fn) => {
  return (...args) => runGenerator(() => fn(...args));
};

// 使用示例:
const fetchData = (val) => new Promise(resolve => setTimeout(() => resolve(val), 100));
const test = async(function* () {
  const a = yield fetchData(1);
  const b = yield fetchData(2);
  return a + b;
});
test().then(console.log); // 3(100ms后)
 

二、工程化问题实战

1. 如何优化 node 镜像制作(难度:🌟)

2. webpack 热更新原理(难度:🌟🌟)

核心流程:

 

  1. 内存文件系统:webpack 编译结果存于内存(而非磁盘),加速读写;
  2. 监听变化:通过watch模式监控文件修改,触发增量编译(仅更新变化模块);
  3. 服务器通信:devServer 通过 WebSocket 向浏览器发送更新通知(包含hash和chunkId);
  4. 浏览器更新:
    • 下载更新清单(hash.hot-update.json)和更新模块(hash.hot-update.js);
    • 调用hotAddUpdateChunk替换旧模块;
    • 触发hotUpdateDownloaded完成更新,不刷新页面。

 

优化思考:

 

三、开放性问题实战

1. obj.a.b.c 和 obj['a']['b']['c'] 哪一个性能更好?

两者性能差异极小,主要区别在于使用场景:

 

2. 如何突破 localStorage 的大小限制?

四、算法题实战

1. 最短编辑距离(难度:🪐)

问题:计算将word1转换为word2的最少操作次数(插入、删除、替换)。

 

解法:动态规划(DP)

 

 

javascript
 
 
 
 
 
const levenshtein = (s1, s2) => {
  const m = s1.length, n = s2.length;
  // 初始化DP表
  const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
  for (let i = 0; i <= m; i++) dp[i][0] = i;
  for (let j = 0; j <= n; j++) dp[0][j] = j;
  
  // 填充DP表
  for (let i = 1; i <= m; i++) {
    for (let j = 1; j <= n; j++) {
      if (s1[i - 1] === s2[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1];
      } else {
        dp[i][j] = 1 + Math.min(
          dp[i - 1][j],    // 删除
          dp[i][j - 1],    // 插入
          dp[i - 1][j - 1] // 替换
        );
      }
    }
  }
  return dp[m][n];
};
 

 

与 React 的联系:React 的虚拟 DOM Diff 算法需计算两棵树的最小更新成本,核心思想与编辑距离类似(通过层级对比、列表 key 优化,减少操作次数)。

五、如何写好个人简历

核心原则

具体建议

  1. 标题与格式:
    • 标题需含姓名、学历、经验、岗位(如:“张三 - 本科 - 4 年 - 高级前端开发工程师.pdf”);
    • 采用 PDF 格式,避免花哨设计(便于 OCR 识别和跨设备查看)。
  2. 个人介绍:
    简洁列出联系方式(电话、邮箱)、意向地、岗位、学历,排版整齐。
  3. 技术部分:
    • 避免罗列常识(如 “熟练使用 Git”)或不精通的领域;
    • 措辞准确:
      • 了解:知晓基本原理;
      • 熟悉:有 Demo 或 1-2 个项目实践;
      • 熟练掌握:工业级项目中灵活应用核心原理;
      • 精通:深度研究,能解决复杂问题。
  4. 项目部分(占比 60%+):
    按STAR 原则描述(情境 - 任务 - 行动 - 结果):
    • 坏案例:“负责 XXX 需求,使用 A、B 技术”;
    • 好案例:“XXX 项目中,因 [问题] 导致 [影响],我作为 [角色],通过 [技术方案] 解决,使 [指标] 提升 X%,[业务] 增长 Y%”。
  5. 加分项:
    • 高质量技术博客(高转发 / 点赞);
    • Github 活跃贡献(主导开源项目、代码级 PR);
    • 跨领域技能(如 Rust 开发 Wasm、C++ 等)。