本题库共计包含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: flex、flex-direction、justify-content、align-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 add和git 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题(速记版)




















暂无评论内容