【初级】前端开发工程师面试100题(二)

本题库共计包含100题,考察html,css,js,以及react,vue,webpack等基础知识掌握情况。

【初级】前端开发工程师面试100题(一)
【初级】前端开发工程师面试100题(二)
【初级】前端开发工程师的面试100题(速记版)

TypeScript篇

TypeScript和JavaScript有什么区别?

TS是JS的超集,添加了静态类型系统,编译时检查类型错误,适合大型项目。

interface和type有什么区别?

interface主要用于描述对象形状,可extends和implements;type更灵活,可用于联合类型、元组等。

interface User {
              
  name: string;
  age: number;
}

type ID = string | number;

什么是泛型?有什么作用?

泛型让组件支持多种类型,提高复用性。比如一个函数可以处理不同类型的数组。

function identity<T>(arg: T): T {
              
  return arg;
}
identity<string>("hello");

TypeScript中的never类型是什么?

表示永远不会发生的值,如抛出错误的函数返回类型或无限循环。

function error(message: string): never {
              
  throw new Error(message);
}

如何为第三方库添加类型声明?

使用declare声明或安装@types/库名的类型包。也可以自己写.d.ts声明文件。

移动端开发篇

移动端适配有哪些方案?

媒体查询、rem/vw单位、flex布局、响应式框架(如Bootstrap)、1px边框问题处理。

如何处理移动端300ms点击延迟?

使用fastclick库、viewport设置width=device-width、CSS的touch-action: manipulation

什么是Flex布局?常用属性有哪些?

弹性布局,适合一维布局。常用:display: flexflex-directionjustify-contentalign-items

如何实现移动端下拉刷新和上拉加载?

原生scroll事件判断滚动位置、第三方库(pull-to-refresh)、IntersectionObserver API。

什么是PWA?有哪些特性?

渐进式Web应用,特性:离线可用(Service Worker)、添加到主屏、推送通知等。

测试与部署篇

前端单元测试有哪些框架?

Jest(全能)、Mocha+Chai(灵活)、Vue Test Utils、React Testing Library。

如何测试React组件?

渲染测试(组件能否正常渲染)、交互测试(点击等事件)、快照测试(UI是否意外改变)。

test('renders button with text', () => {
              
  render(<Button>Click me</Button>);
  expect(screen.getByText('Click me')).toBeInTheDocument();
});

什么是E2E测试?有哪些工具?

端到端测试,模拟用户操作。工具:Cypress、Playwright、Puppeteer。

前端项目部署流程是怎样的?

代码打包 → 上传到服务器/CDN → 配置Nginx → 配置HTTPS → 配置CI/CD自动化。

如何实现灰度发布?

通过Nginx按比例分流、Cookie或Header标识测试用户、AB测试平台控制。

数据结构与算法篇

常见的数据结构有哪些?

数组、栈、队列、链表、树(二叉树)、图、哈希表等。

实现一个深拷贝函数

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

手写Promise.all

Promise.all = function(promises) {
              
  return new Promise((resolve, reject) => {
              
    const results = [];
    let count = 0;
    promises.forEach((promise, index) => {
              
      Promise.resolve(promise).then(res => {
              
        results[index] = res;
        count++;
        if (count === promises.length) resolve(results);
      }).catch(reject);
    });
  });
}

数组去重的几种方法

// 方法1:Set
[...new Set(arr)]

// 方法2:filter+indexOf
arr.filter((item, index) => arr.indexOf(item) === index)

// 方法3:reduce
arr.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], [])

实现一个事件发布订阅(EventEmitter)

class EventEmitter {
              
  constructor() {
              
    this.events = {
              };
  }
  on(event, listener) {
              
    (this.events[event] || (this.events[event] = [])).push(listener);
  }
  emit(event, ...args) {
              
    (this.events[event] || []).forEach(listener => listener(...args));
  }
  off(event, listener) {
              
    if (!this.events[event]) return;
    this.events[event] = this.events[event].filter(l => l !== listener);
  }
}

设计模式篇

前端常用的设计模式有哪些?

单例模式(全局状态管理)、观察者模式(事件系统)、工厂模式(创建对象)、装饰器模式(高阶组件)、策略模式(表单验证)。

什么是观察者模式?如何实现?

主题对象维护一组观察者,状态变化时通知所有观察者。如DOM事件系统。

class Subject {
              
  constructor() {
              
    this.observers = [];
  }
  subscribe(observer) {
              
    this.observers.push(observer);
  }
  notify(data) {
              
    this.observers.forEach(observer => observer.update(data));
  }
}

什么是高阶组件(HOC)?

接收组件返回新组件的函数,用于逻辑复用。如React的withRouter。

function withLogger(WrappedComponent) {
              
  return function(props) {
              
    console.log('Rendering:', WrappedComponent.name);
    return <WrappedComponent {
              ...props} />;
  }
}

什么是单例模式?前端哪里用到了?

确保一个类只有一个实例。如Redux store、全局模态框、登录弹窗。

什么是策略模式?举个例子

定义一系列算法,使它们可以相互替换。如表单验证规则。

const strategies = {
              
  isNonEmpty(value, errMsg) {
              
    if (!value) return errMsg;
  },
  minLength(value, length, errMsg) {
              
    if (value.length < length) return errMsg;
  }
};

function validate(value, rules) {
              
  for (let rule of rules) {
              
    const error = strategies[rule.strategy](value, ...rule.args);
    if (error) return error;
  }
}

工程化篇

什么是前端工程化?包含哪些方面?

规范化(代码规范、Git规范)、模块化(组件化)、自动化(构建、测试、部署)、性能优化等。

Git常用命令有哪些?

git clone克隆、git add暂存、git commit提交、git push推送、git pull拉取、git branch分支管理。

如何处理Git冲突?

git pull获取最新代码,手动解决冲突文件中的<<<<<<<标记,然后git addgit commit

什么是CI/CD?前端如何实现?

持续集成/持续部署。用GitHub Actions、Jenkins等工具自动化测试和部署。

如何设计一个组件库?

确定设计规范、按功能划分组件、提供主题定制、完善的文档和示例、按需加载支持。

综合能力篇

如何学习新技术?

官方文档入门、实践小demo、阅读源码、参与社区讨论、写博客总结。

遇到技术难题如何解决?

先独立思考尝试、Google/Stack Overflow搜索、查看GitHub issues、请教同事、最后考虑替代方案。

如何做技术方案选型?

考虑社区活跃度、团队熟悉度、性能需求、维护成本、长期可持续性。

如何与后端工程师高效协作?

定义清晰的接口文档(如Swagger)、约定错误码规范、Mock数据并行开发、定期同步进度。

如何评估前端工作量?

拆解任务模块、评估复杂度、考虑联调测试时间、预留buffer应对风险。

开放性问题篇

你做过最有挑战的项目是什么?如何解决的?

考察实际问题解决能力。可举例性能优化、复杂交互实现、技术攻关等。

如何看待前端技术的发展趋势?

微前端、低代码、WebAssembly、Serverless、智能化等方向。

前端工程师的核心竞争力是什么?

工程化能力、用户体验意识、持续学习能力、业务理解深度。

如何保证代码质量?

代码审查、单元测试、TypeScript类型检查、ESLint规范、性能监控。

未来3-5年的职业规划?

技术深度(如框架原理)和广度(全栈能力)并重,逐步承担架构设计和团队管理。

项目细节追问篇

项目中的权限系统是如何设计的?

路由权限、菜单权限、按钮权限、接口权限的具体实现细节。

如何优化项目中的大型表格渲染?

虚拟滚动、分页加载、按需渲染、Web Worker计算等方案。

如何处理项目中的复杂表单?

表单拆分、动态表单、表单校验库、状态管理方案等。

如何实现项目的多主题切换?

CSS变量动态修改、预处理器的主题变量、单独样式文件切换等。

项目中的错误监控是如何实现的?

前端错误捕获、日志上报、报警机制等具体方案。

代码实操题篇

实现一个简单的Promise

class MyPromise {
              
  constructor(executor) {
              
    this.state = 'pending';
    this.value = undefined;
    this.onResolvedCallbacks = [];
    
    const resolve = (value) => {
              
      if (this.state === 'pending') {
              
        this.state = 'fulfilled';
        this.value = value;
        this.onResolvedCallbacks.forEach(fn => fn());
      }
    };
    
    executor(resolve);
  }
  
  then(onFulfilled) {
              
    return new MyPromise((resolve) => {
              
      if (this.state === 'fulfilled') {
              
        const x = onFulfilled(this.value);
        resolve(x);
      } else {
              
        this.onResolvedCallbacks.push(() => {
              
          const x = onFulfilled(this.value);
          resolve(x);
        });
      }
    });
  }
}

实现数组扁平化

// 递归实现
function flatten(arr) {
              
  return arr.reduce((acc, cur) => 
    Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]
  , []);
}

// ES6 flat方法
arr.flat(Infinity);

实现一个简单的虚拟DOM函数

function createElement(tag, props, ...children) {
              
  return {
              
    tag,
    props: props || {
              },
    children: children.flat()
  };
}

function render(vnode) {
              
  if (typeof vnode === 'string') return document.createTextNode(vnode);
  
  const el = document.createElement(vnode.tag);
  
  // 设置属性
  for (const [key, value] of Object.entries(vnode.props)) {
              
    el.setAttribute(key, value);
  }
  
  // 渲染子节点
  vnode.children.forEach(child => {
              
    el.appendChild(render(child));
  });
  
  return el;
}

实现一个curry函数

function curry(fn) {
              
  return function curried(...args) {
              
    if (args.length >= fn.length) {
              
      return fn.apply(this, args);
    } else {
              
      return function(...args2) {
              
        return curried.apply(this, args.concat(args2));
      }
    }
  };
}

// 使用示例
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
curriedSum(1)(2)(3); // 6

实现一个LRU缓存

class LRUCache {
            
  constructor(capacity) {
            
    this.capacity = capacity;
    this.cache = new Map();
  }
  
  get(key) {
            
    if (!this.cache.has(key)) return -1;
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
    return value;
  }
  
  put(key, value) {
            
    if (this.cache.has(key)) {
            
      this.cache.delete(key);
    } else if (this.cache.size >= this.capacity) {
            
      const oldestKey = this.cache.keys().next().value;
      this.cache.delete(oldestKey);
    }
    this.cache.set(key, value);
  }
}

面试题系列

【初级】前端开发工程师面试100题(一)
【初级】前端开发工程师面试100题(二)
【初级】前端开发工程师的面试100题(速记版)

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容