腾讯前端面经
一面(8.29 1h45min)
八股
- 实习经历
- js基础,闭包,原型,事件循环xxx
- webpack、vite区别,模块化方案,用过哪些插件,写过哪些插件
webpack与vite区别
-
构建方式:
- webpack:基于配置文件进行构建,需要配置各种loader和plugin,比较复杂。
- Vite:基于现代浏览器原生 ES 模块的开发服务器,利用浏览器的原生模块加载速度快的特性,不需要打包,开发时即时编译。
-
启动速度:
- webpack:由于需要进行打包,启动速度较慢,尤其是在大型项目中。
- Vite:由于不需要打包,启动速度非常快,几乎是即时的。
-
热更新:
- webpack:热更新依赖于webpack-dev-server,需要重新构建并刷新浏览器页面。
- Vite:利用ES模块的特性,支持快速的热更新,只更新修改的模块,不需要刷新整个页面。
-
生态支持:
- webpack:成熟的生态系统,有大量的loader和plugin,可以满足各种需求。
- Vite:相对较新,生态系统还在发展阶段,部分webpack的loader和plugin可能不兼容。
-
打包输出:
- webpack:支持生成生产环境的打包文件,适用于传统的构建场景。
- Vite:开发时不进行打包,生产环境需要使用其他工具进行打包(如rollup等)。
模块化方案
常见的模块化方案有CommonJS、ES6 Module、AMD、UMD等,其中:
- CommonJS 是Node.js的模块化方案,通过
require和module.exports来导入和导出模块。 - ES6 Module 是JavaScript的官方模块化方案,通过
import和export来导入和导出模块。 - AMD (Asynchronous Module Definition) 是RequireJS的模块化方案,用于浏览器端异步加载模块。
- UMD (Universal Module Definition) 是一种通用模块定义规范,兼容CommonJS、AMD和全局变量的模块导入方式。
使用过的插件
常见的webpack插件有:
- HtmlWebpackPlugin:用于生成HTML文件,并自动注入打包后的资源。
- MiniCssExtractPlugin:用于将CSS提取为独立的文件。
- CleanWebpackPlugin:用于清理输出目录。
- CopyWebpackPlugin:用于复制文件或目录到构建目录。
- DefinePlugin:用于定义全局变量。
- ProvidePlugin:自动加载模块,无需使用import或require。
写过的插件
编写webpack插件的方式可以扩展webpack的功能,常见的插件包括loader和plugin。
- Loader是用于加载资源文件的转换器,例如将ES6转换为ES5、将SCSS转换为CSS等。
- Plugin是用于扩展webpack功能的插件,可以在构建过程中的各个阶段执行自定义操作,例如文件压缩、代码分割、自动引入CDN等。
编写webpack插件需要了解webpack的内部原理和钩子机制,常见的钩子包括compiler和compilation,通过这些钩子可以在合适的时机执行自定义操作。
- vue2、vue3区别,nextTick原理
缓存,service worker,延伸至移动端弱网环境下如何优化,具体没听懂
在移动端弱网环境下,优化缓存和使用Service Worker可以有效提高网页加载速度和用户体验。以下是一些优化策略:
-
优化缓存策略:
- 使用合适的缓存策略,可以减少网络请求次数,降低页面加载时间。对于移动端弱网环境,应当尽量减少对服务器的请求,可以通过合理设置缓存头部来实现。
- 将静态资源(如图片、样式表、脚本文件)进行本地缓存,减少网络请求的依赖。
- 使用浏览器缓存机制,将不经常变动的资源进行缓存,减少重复下载。
-
使用Service Worker进行离线缓存:
- Service Worker 是运行在浏览器背后的一段脚本,可以拦截和处理网络请求,实现离线缓存和资源预加载。
- 在移动端弱网环境下,可以通过Service Worker将页面所需的资源缓存到本地,以便在网络不可用时能够快速加载页面。
- 使用Service Worker的缓存策略,可以根据不同的资源类型和更新频率,动态地调整缓存策略,以满足页面的实时性和性能需求。
-
优化页面加载速度:
- 减少页面的体积和请求次数,可以通过压缩资源、合并文件、异步加载等方式来减小页面的加载时间。
- 使用图片懒加载和延迟加载技术,优化页面中图片资源的加载顺序和时间,提高页面加载速度。
-
使用WebP等优化图片格式:
- 在移动端环境下,可以使用WebP等现代图片格式来替代传统的图片格式,以减小图片体积,提高加载速度。
-
优化网络请求:
- 减少不必要的网络请求,可以通过合并请求、使用CDN等方式来减少页面加载时的网络开销。
- 使用HTTP/2协议等新一代网络协议,可以提高网络请求的并发性和传输效率。
综上所述,通过优化缓存策略、使用Service Worker、优化页面加载速度和网络请求等方式,可以在移动端弱网环境下提高网页加载速度和用户体验。这些优化策略可以根据实际情况进行灵活调整,以达到最佳的性能优化效果。
设计一个通用缓存方案(具体忘了,牛客上应该有朋友记录过)
设计一个通用的缓存方案可以涵盖多种场景和需求,以下是一个简单的缓存方案设计示例:
缓存方案设计
-
缓存策略:
- 根据业务需求和数据特性选择合适的缓存策略,常见的缓存策略包括:FIFO(先进先出)、LRU(最近最少使用)、LFU(最不经常使用)等。
- 可以结合缓存的大小、数据更新频率、访问模式等因素来确定缓存策略。
-
缓存层级:
- 可以设计多层缓存结构,根据数据的访问频率和重要性进行分层管理。
- 比如可以使用内存缓存(如Redis、Memcached)作为一级缓存,将常用的数据缓存到内存中,以提高访问速度;而较少使用的数据可以缓存到磁盘中作为二级缓存。
-
缓存更新机制:
- 设计缓存更新机制,确保缓存数据的及时更新。
- 可以采用定时更新、手动更新或根据数据变化自动更新等方式来更新缓存数据。
-
缓存失效策略:
- 设计缓存失效策略,根据数据的特性和业务需求确定缓存的失效时间。
- 可以根据数据的更新频率和重要性来设置缓存的过期时间,以避免缓存数据过期而导致数据不一致的问题。
-
缓存监控和管理:
- 设计缓存监控和管理机制,实时监控缓存的使用情况和缓存命中率。
- 可以使用监控工具或自定义监控系统来监控缓存的运行状态,并根据监控数据进行缓存的优化和调整。
实现思路
-
选择合适的缓存技术:
- 根据业务需求和数据特性选择合适的缓存技术,比如使用Redis、Memcached等内存缓存技术,或使用文件系统、数据库等持久化缓存技术。
-
设计缓存接口:
- 设计统一的缓存接口,包括数据的读取、写入、更新和删除等操作,以便在不同的缓存技术之间进行切换和扩展。
-
实现缓存管理模块:
- 编写缓存管理模块,负责缓存的初始化、配置和管理,包括缓存策略的选择和调整、缓存的监控和管理等功能。
-
实现缓存存储模块:
- 根据选择的缓存技术,实现相应的缓存存储模块,负责数据的读取、写入、更新和删除等操作。
-
实现缓存更新机制:
- 根据缓存更新策略,实现缓存的更新机制,包括定时更新、手动更新或根据数据变化自动更新等方式。
-
实现缓存失效策略:
- 根据缓存失效策略,实现缓存的失效机制,包括设置缓存的过期时间、监控缓存的使用情况并根据需要进行缓存的清理和更新等操作。
-
实现缓存监控和管理:
- 根据缓存监控和管理需求,实现缓存的监控和管理模块,包括监控缓存的运行状态、命中率和使用情况,并根据监控数据进行缓存的优化和调整等操作。
通过以上设计和实现,可以构建一个通用的缓存方案,满足不同场景下的缓存需求,并提高系统的性能和可扩展性。
- 计网八股
手写
- HardMan
- promise并发
对象的key下划线转驼峰
将对象的键名中的下划线格式转换为驼峰格式是一个常见的需求,可以通过编写一个函数来实现。以下是一个 JavaScript 函数示例:
function convertKeysToCamelCase(obj) {
// 检查参数是否为对象
if (typeof obj !== 'object' || obj === null) {
throw new Error('Input must be an object');
}
// 创建一个新的对象,用于存储转换后的键值对
const newObj = {};
// 遍历对象的键值对
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 将下划线格式的键名转换为驼峰格式
const camelCaseKey = key.replace(/_([a-z])/g, function(match, group1) {
return group1.toUpperCase();
});
// 将转换后的键值对存入新对象中
newObj[camelCaseKey] = obj[key];
}
}
return newObj;
}
// 示例
const obj = {
user_name: 'John',
age: 30,
address_info: {
street_name: 'Main St',
postal_code: '12345'
}
};
const newObj = convertKeysToCamelCase(obj);
console.log(newObj);
在上面的示例中,convertKeysToCamelCase 函数接受一个对象作为参数,并返回一个新的对象,其中的键名已经转换为驼峰格式。这里使用了正则表达式来匹配下划线后面的字母,并将其转换为大写字母。
二面(8.31 45min)
- 项目拷打
- 实习拷打
写一个时针分针夹角
要计算时针和分针之间的夹角,可以通过以下步骤来实现:
- 计算时针和分针分别与12点钟方向的夹角。
- 计算两个夹角之间的差值,即时针与分针之间的夹角。
以下是一个 JavaScript 函数示例:
function calcClockAngle(hour, minute) {
// 小时制转换为角度制,每小时30度,每分钟0.5度
const hourAngle = (hour % 12) * 30 + minute * 0.5;
const minuteAngle = minute * 6; // 每分钟6度
// 计算夹角
let angle = Math.abs(hourAngle - minuteAngle);
// 如果角度大于180度,则取360度减去角度
if (angle > 180) {
angle = 360 - angle;
}
return angle;
}
// 示例
const hour = 3; // 时针指向3点
const minute = 15; // 分针指向3点的方向,即15分钟
const angle = calcClockAngle(hour, minute);
console.log("时针和分针夹角为:" + angle + "度");
在这个示例中,calcClockAngle 函数接受两个参数:hour 表示小时数(取值范围为0到11),minute 表示分钟数(取值范围为0到59)。函数首先将小时和分钟转换为角度制,然后计算时针和分针的夹角,并返回结果。
第二天挂, 二面答得确实差,整体面试体验良好,部门是QQ
作者:IpKKpi
链接:www.nowcoder.com/discuss/527…
来源:牛客网