360前端一面~面试题解析(360前端开发面试题)
wxin55 2025-05-05 19:15 2 浏览 0 评论
1. 组件库按需加载怎么做的,具体打包配了什么
- 按需加载实现:借助打包工具(如 Webpack 的 require.context 或 ES 模块动态导入),在使用组件时才引入对应的代码。例如在 Vue 项目中,若用 babel - plugin - import 插件,配置插件指定组件库路径和按需加载规则,就可在编译时只引入使用的组件代码。
- 打包配置:配置打包工具(如 Webpack)的 externals 避免将组件库重复打包进项目代码;使用 Tree - shaking 优化,去除未使用代码;配置 splitChunks 进行代码分割,将组件库代码单独打包成 chunk,实现按需加载时单独请求。
2. tree - shaking 怎么做的
在 Webpack 中,需满足 ES 模块规范,代码中没有副作用(如修改全局变量等)。配置 mode 为 production 时,Webpack 会自动开启 Tree - shaking 优化;还可在 optimization 中配置 usedExports: true ,标记出被使用的模块导出,打包时移除未标记的代码 。
3. 性能优化(深挖)怎么计算 LCP,mutationObserver 触发频繁怎么优化
- 计算 LCP(最大内容绘制):在浏览器中,可通过 PerformanceObserver API 监听 largest - contentful - paint 事件获取 LCP 时间,示例代码:
javascript
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP:', entry.startTime + entry.duration);
}
}).observe({ type: 'largest - contentful - paint', buffered: true });
- mutationObserver 优化:减少不必要的 DOM 监听,精准定位需监听的 DOM 节点;设置合理的 MutationObserverInit 选项,如减少对不必要属性变化的监听;使用节流或防抖函数包装回调函数,控制触发频率 。
1. 图片可视区怎么做,interserobserver
利用 IntersectionObserver API 实现。创建 IntersectionObserver 实例,传入回调函数和配置参数(如 rootMargin 等),回调函数在目标元素进入或离开视口时触发。示例代码:
javascript
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 图片进入可视区操作,如加载图片
}
});
});
const img = document.getElementById('target - img');
observer.observe(img);
1. 图片的优化方式
压缩图片大小,使用工具(如 TinyPNG )降低图片分辨率、去除元数据;使用合适的图片格式,如 WebP 格式在同等画质下体积更小;图片懒加载,利用 IntersectionObserver 或原生的 loading="lazy" 属性,在图片进入可视区时加载;设置图片的 srcset 和 sizes 属性,让浏览器根据设备屏幕选择合适尺寸图片加载 。
2. 浏览器渲染页面过程(深挖),js 是否会阻塞 html 的解析吗,js 为什么会阻塞页面渲染
- 渲染过程:浏览器接收 HTML 文档,解析成 DOM 树;解析 CSS 生成 CSSOM 树;将 DOM 树和 CSSOM 树合并成渲染树;计算渲染树中元素的布局信息(位置、大小等);对渲染树进行绘制,将像素信息输出到屏幕。
- js 阻塞解析:会。因为 JavaScript 可能会修改 DOM 和 CSSOM ,浏览器为保证执行结果正确,遇到 <script> 标签时会暂停 HTML 解析,优先下载和执行 JavaScript 代码。
- 阻塞渲染原因:JavaScript 可操作 DOM 和 CSSOM ,若在渲染过程中执行,可能改变页面结构和样式,为避免渲染错误,浏览器等 JavaScript 执行完再继续渲染 。
3. 大文件上传,返回的状态码是多少
正常上传成功一般返回 200 或 201 Created 。上传过程中若有错误,如文件大小超出限制可能返回 413 Payload Too Large ;服务器内部错误返回 500 Internal Server Error 等 。
4. Webworker 和 shareWorker 的区别,最多几个 worker,cpu 核心数怎么计算
- 区别:Webworker 是为在后台线程执行脚本而设计,与主线程通过消息机制通信,有自己独立的全局上下文;shareWorker 是多个页面共享的 worker ,通过 port 与页面通信,需在不同页面连接到同一个 shareWorker 实例 。
- worker 数量:理论上无严格固定上限,但受系统资源(如内存)限制,实际大量创建会影响性能。
- 计算 cpu 核心数:在 JavaScript 中,可通过
navigator.hardwareConcurrency 获取浏览器可用的逻辑 CPU 核心数 。
5. serviceworker 做缓存应用场景,有大小限制吗
- 应用场景:离线应用,如 PWA 应用,让用户在离线时也能访问页面;拦截网络请求,根据缓存策略判断从缓存取数据还是发起网络请求;后台数据同步,在网络恢复时自动同步数据。
- 大小限制:不同浏览器有差异,一般来说,Service Worker 缓存大小限制在 5MB - 50MB 左右,可通过
navigator.storageQuota.queryInfo() 方法查询当前站点可用的存储配额 。
6. 大模型传输数据 websocket 的数据格式,ws 和 sse 的区别
- WebSocket 数据格式:可以是文本(如 JSON 格式字符串)或二进制数据。发送和接收数据时,可根据需求进行序列化和反序列化操作,例如将 JavaScript 对象序列化为 JSON 字符串发送,接收到后再解析为对象。
- 区别:WebSocket 是全双工通信协议,客户端和服务器可随时双向发送消息;SSE(Server - Sent Events)是单向的,由服务器向客户端推送消息,常用于服务器向客户端实时推送数据场景,如新闻更新、实时日志等 。
7. websocket 心跳具体怎么做,传递用户信息用什么
- 心跳机制:客户端定时(如每隔一段时间,如 30 秒)向服务器发送一个特殊的心跳包(如简单的文本消息 ping ),服务器收到后回复 pong 。通过判断是否按时收到回复来检测连接状态,若超时未收到回复,可尝试重新连接。
- 传递用户信息:一般将用户信息(如用户 ID、用户名等)以 JSON 格式序列化后通过 WebSocket 发送,接收方解析 JSON 数据获取用户信息 。
8. watcheffect 和 watch 原理的区别
- watch:是 Vue 中用于监听数据变化的 API ,可监听一个或多个响应式数据源,当依赖的数据源变化时执行回调函数。它是惰性的,需显式指定监听的数据源。
- watcheffect:也是 Vue 响应式监听 API ,会自动追踪回调函数中使用的响应式数据,只要这些数据变化就会重新执行回调。它更侧重于自动响应数据变化执行副作用操作,无需手动指定依赖 。
9. vue 双向绑定有几类 watcher,为什么 computed 类中 watcher 会反过来收集 dep 类
- watcher 类型:主要有渲染 watcher ,负责在数据变化时重新渲染组件;用户自定义 watcher ,通过 watch 选项创建,用于监听特定数据变化执行自定义逻辑。
- computed 中 watcher 收集 dep 原因:computed 本质是一个惰性求值的 watcher ,当计算属性依赖的数据变化时,会触发其依赖的 dep 通知 computed watcher 重新计算,为了能准确追踪依赖,computed watcher 会反过来收集依赖的 dep ,以便在依赖数据变化时重新计算结果 。
10. diff 算法比对过程,几个指针
在 Vue 或 React 等框架的 diff 算法中,一般有两个指针,一个指向旧节点列表头部,一个指向新节点列表头部。通过不断比较两个指针指向的节点,进行节点的插入、删除、移动等操作。比对过程是先进行同级比较,若节点类型不同则直接替换,类型相同再比较属性等,逐步遍历完新旧节点列表 。
11. vue 路由的原理
- hash 模式:利用 URL 中的 # 及后面的内容作为路由标识,改变 # 后面的内容不会重新加载页面。通过监听 hashchange 事件,获取 # 后的路径,根据路径匹配组件进行渲染 。
- history 模式:借助 HTML5 的 history.pushState() 和 history.replaceState() 方法改变 URL ,不会触发页面重载。通过监听 popstate 事件以及在代码中调用上述方法,实现路由切换和页面组件渲染更新 。
12. 单点登录,拦截是在请求拦截还是路由拦截
都可以。请求拦截可在每次发送 HTTP 请求时,检查请求头(如是否携带有效的 token )判断用户登录状态,未登录则进行处理(如跳转到登录页);路由拦截是在路由导航守卫(如 Vue Router 的 beforeEach 守卫)中检查用户登录状态,未登录阻止进入某些路由页面 。
13. axios 的设计思想,aop 面向切面?
- 设计思想:axios 是基于 Promise 的 HTTP 客户端,设计上支持浏览器和 Node.js 环境。它提供简洁易用的 API ,可配置请求和响应拦截器,方便统一处理请求和响应(如添加请求头、处理错误等),具有良好的扩展性和灵活性 。
- 与 AOP 关系:axios 的拦截器机制类似 AOP(面向切面编程)思想。拦截器可在不修改核心业务逻辑(请求发送和响应处理)的情况下,在请求发送前和响应接收后执行额外操作(如日志记录、权限验证等),将横切关注点从核心业务逻辑中分离出来 。
14. 打包工具 webpack、vite、rollup 的区别,tsup?
- webpack:功能全面强大,支持多种模块类型和加载器,可处理复杂项目,通过插件机制扩展功能,但配置相对复杂,打包速度在大型项目中较慢 。
- vite:基于浏览器原生 ES 模块支持,开发模式下启动快、热更新快,适合现代前端项目。生产模式下也有不错的性能,配置相对简单,对 Vue 等框架有很好的支持 。
- rollup:专注于 ES 模块打包,擅长构建库和应用程序,输出代码更扁平、体积更小,对 Tree - shaking 支持好,但在处理复杂项目依赖和多页面应用时功能相对有限 。
- tsup:是基于 esbuild 构建的零配置打包工具,支持 TypeScript ,打包速度快,配置简单,可快速构建项目,不过功能丰富度上可能不如 webpack 等 。
15. esbuild 的三个流程
解析(Parsing):将代码字符串解析成抽象语法树(AST);转换(Transforming):对 AST 进行转换操作,如类型检查(对于 TypeScript 代码)、语法转换等;生成(Generating):将转换后的 AST 再转换回 JavaScript 代码字符串输出 。
16. webpack 怎么做模块化打包,打包 js 输出什么,怎么开始多进程打包
- 模块化打包:webpack 通过 loader 处理不同类型模块(如 babel - loader 处理 JavaScript 模块, css - loader 处理 CSS 模块),将其转换为可处理的形式,然后根据模块依赖关系构建依赖图,最后将依赖图中的模块打包成一个或多个 bundle 文件 。
- js 输出:通常输出一个或多个包含所有依赖 JavaScript 代码的 bundle 文件,可根据配置进行代码分割等操作,输出多个 chunk 文件,每个 chunk 包含特定功能模块代码 。
- 多进程打包:使用 thread - loader 插件,在 module.rules 中配置 thread - loader ,将耗时的 loader 操作(如 Babel 编译)分配到多个进程中执行,提高打包速度 。
17. New 一个构造函数生成实例的的过程,箭头函数为什么不能 new
- 构造函数实例化过程:创建一个新对象;将新对象的 __proto__ 指向构造函数的 prototype ;将构造函数中的 this 指向新对象,执行构造函数代码;返回新对象 。
- 箭头函数不能 new 原因:箭头函数没有自己的 this 绑定(它的 this 继承自外层作用域),也没有 prototype 属性,而 new 操作符需要构造函数有 prototype 用于设置实例的原型,并且需要正确处理 this 绑定,所以箭头函数不能使用 new 操作符 。
18. 原型链、继承的几种方式,extends
- 原型链:每个 JavaScript 对象都有一个 __proto__ 属性指向其原型对象,原型对象又有自己的原型,这样形成一条链式结构。对象查找属性或方法时,若自身没有,就沿着原型链向上查找 。
- 继承方式:原型链继承,通过将子类的原型指向父类实例实现;构造函数继承,在子类构造函数中调用父类构造函数,通过 call 或 apply 改变 this 指向;组合继承,结合前两种方式;寄生组合继承,优化组合继承,减少不必要的属性复制;ES6 类继承,使用 extends 关键字,语法更简洁清晰 。
- extends:在 ES6 中用于类继承,子类通过 extends 关键字继承父类的属性和方法,例如 class Child extends Parent {} ,子类会自动继承父类的实例方法和属性,还可重写或扩展父类方法 。
19. await async 执行顺序,原理,generator 改变代码顺序的原理(yield 关键字 next 方法?)
- await async 执行顺序和原理: async 函数返回一个 Promise ,函数内部遇到 await 表达式时,会暂停执行,等待 await 后的 Promise 解决(resolved 或 rejected ),然后继续执行 async 函数后续代码。原理是基于 Promise 状态管理,将异步操作以同步写法呈现 。
- generator 原理: generator 函数是一种特殊函数,通过 function* 定义,内部使用 yield 关键字暂停和恢复执行。调用 generator 函数返回一个迭代器对象,通过调用迭代器对象的 next 方法,可让函数从上次 yield 暂停处继续执行,实现代码执行顺序的控制和异步操作的分步执行 。
20. 分别说下浏览器事件循环和 node 事件循环
- 浏览器事件循环:主线程执行同步代码,遇到宏任务(如 setTimeout 回调、DOM 渲染等)放入宏任务队列,遇到微任务(如 Promise.then 回调)放入微任务队列。当前调用栈清空后,先执行微任务队列中所有任务,再从宏任务队列中取出一个任务执行,不断重复 。
- node 事件循环:分为多个阶段(如 timers 阶段处理 setTimeout 、 setInterval 回调; I/O callbacks 阶段处理一些系统底层 I/O 回调; idle, prepare 阶段; poll 阶段检查新的 I/O 事件; check 阶段处理 setImmediate 回调; close callbacks 阶段处理关闭相关回调)。事件循环在这些阶段间切换,执行对应阶段队列中的任务 。
21. node 中进程和线程的通信方式
- 进程通信:通过 child_process 模块,如 spawn 、 exec 、 fork 等方法创建子进程,父子进程间通过 process.send() 和 process.on('message') 进行消息传递 。
- 线程通信:在 Node.js 中,通过 worker_threads 模块创建线程,线程间可通过 postMessage 方法发送消息,接收方通过 on('message') 监听消息 。
22. 怎么做安全防御,vue 底层做了什么,v - html 怎么防御
- 安全防御通用做法:输入验证,对用户输入进行合法性检查,防止恶意输入;防止 XSS(跨站脚本攻击),对输出到页面的内容进行转义,避免执行恶意脚本;防止 CSRF(跨站请求伪造),使用 CSRF 令牌,在表单提交或 AJAX 请求时验证令牌 。
- Vue 底层安全措施:对数据绑定和渲染做了处理,防止 XSS 攻击,例如在插值表达式中自动对数据进行 HTML 转义;在组件化开发中,通过作用域隔离避免样式和脚本冲突 。
- v - html 防御:使用 v - html 时要确保绑定的数据来源可信,若数据不可信,需提前对数据进行 sanitize 处理(如使用 DOMPurify 库),过滤掉恶意的 HTML 标签和脚本 。
23. http1.0,http1.1,http2
- HTTP/1.0:早期版本,每次请求 - 响应需建立新 TCP 连接,性能较低,无持久连接机制,头部信息未压缩 。
- HTTP/1.1:引入持久连接( Connection: keep - alive ),多个请求可复用一个 TCP 连接;支持
相关推荐
- ES6中 Promise的使用场景?(es6promise用法例子)
-
一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...
- JavaScript 对 Promise 并发的处理方法
-
Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...
- Promise的九大方法(promise的实例方法)
-
1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...
- 360前端一面~面试题解析(360前端开发面试题)
-
1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
-
Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
-
看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
-
传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...
- 手写 Promise(手写输入法 中文)
-
前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...
- 什么是 Promise.allSettled()!新手老手都要会?
-
Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...
- 前端面试-关于Promise解析与高频面试题示范
-
Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...
- 宇宙厂:为什么前端离不开 Promise.withResolvers() ?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...
- Promise 新增了一个超实用的 API!
-
在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...
- 一次搞懂 Promise 异步处理(promise 异步顺序执行)
-
PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...
- Promise 核心机制详解(promise机制的实现原理)
-
一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...
- javascript——Promise(js实现promise)
-
1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- ES6中 Promise的使用场景?(es6promise用法例子)
- JavaScript 对 Promise 并发的处理方法
- Promise的九大方法(promise的实例方法)
- 360前端一面~面试题解析(360前端开发面试题)
- 前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?
- 最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式
- 前端分享-Promise可以中途取消啦(promise可以取消吗)
- 手写 Promise(手写输入法 中文)
- 什么是 Promise.allSettled()!新手老手都要会?
- 前端面试-关于Promise解析与高频面试题示范
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)