2026-06-03 23:11:51
Minimax秋招一面主要围绕前端技术栈展开,涉及框架原理、布局、事件处理、项目实现、工程化、Git操作以及算法手撕等多个方面。
具体问题及解答回答时需根据自身实际情况,清晰表明对其中某一个框架更熟悉,并简要阐述熟悉的原因,例如参与过基于该框架的大型项目开发,深入了解其核心概念、生命周期、状态管理等。若都较为熟悉,可分别列举掌握的各自优势特性,如react的虚拟DOM和函数式编程思想,vue的渐进式框架和简洁的模板语法等。
事件绑定:React并不是将事件直接绑定到真实的DOM节点上,而是在文档根节点(document)上统一绑定事件。当组件挂载时,React会将组件内的事件处理函数按照一定的规则进行封装和存储,同时为对应的DOM元素添加一个自定义的属性来标识事件类型和相关信息。
事件冒泡与捕获:当真实DOM元素触发事件时,事件会按照DOM的冒泡或捕获阶段向上传播。在传播过程中,React会拦截这些事件,并根据自定义属性找到对应的事件处理函数。
合成事件创建:React会创建一个合成事件对象(SyntheticEvent),该对象是对原生浏览器事件的跨浏览器封装,统一了不同浏览器之间的事件对象属性和方法,例如preventDefault()和stopPropagation()等。
事件调用:React将合成事件对象传递给之前封装存储的事件处理函数进行调用。在调用完成后,React会对合成事件对象进行回收和复用,以提高性能。
执行时机
useEffect:在浏览器完成布局(layout)和绘制(paint)之后,也就是在DOM更新后异步执行。这意味着它不会阻塞浏览器的渲染过程,适合执行一些不依赖DOM立即更新的副作用操作,如数据获取、订阅事件等。
useLayoutEffect:在浏览器执行布局(layout)和绘制(paint)之前同步执行。它会在DOM更新后立即调用,此时浏览器还没有进行实际的绘制,因此可以读取到更新后的DOM布局信息。适合在需要基于最新的DOM布局进行一些操作时使用,例如测量DOM元素的尺寸、位置等。
性能影响
useEffect:由于其异步执行的特性,不会阻塞页面的渲染,对性能影响较小。
useLayoutEffect:同步执行可能会阻塞浏览器的渲染过程,如果其中的操作比较耗时,会导致页面渲染延迟,出现卡顿现象,因此需要谨慎使用。
Flex布局:父容器设置display: flex; justify-content: center; align-items: center;,子元素会自动在水平和垂直方向上居中。
Grid布局:父容器设置display: grid; place-items: center;,同样可以实现子元素的水平和垂直居中。
绝对定位与transform:子元素设置position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);,通过绝对定位将子元素的左上角定位到父容器的中心,再使用transform将其自身向左和向上移动自身宽度和高度的一半,从而实现居中。
使用order属性,该属性用于指定弹性项目中元素的排列顺序,数值越小,排列越靠前,可以为负值。例如,给某个项目设置order: 1;,其他项目默认order: 0;,则该项目会排列在其他项目之后。
移动端的键盘事件与桌面端存在一些差异,例如键盘类型不同(虚拟键盘)、事件触发时机和频率等。为了解决兼容性问题,可以采取以下措施:
监听不同的事件类型:除了常见的keydown、keyup等事件,还需要关注移动端特有的事件,如input事件,因为虚拟键盘的输入可能不会触发keydown和keyup事件。
处理虚拟键盘的显示和隐藏:可以通过监听focus和blur事件来判断输入框是否获得焦点,从而推测虚拟键盘的显示和隐藏状态,进而进行相应的布局调整或操作。
测试不同设备和浏览器:在不同的移动设备和浏览器上进行充分的测试,了解它们对键盘事件的处理差异,并针对性地进行兼容性处理。
使用图标字体:如Font Awesome、Iconfont等,通过引入图标字体文件,使用CSS类名来显示对应的图标。优点是体积小、加载快,支持通过CSS进行样式调整,如颜色、大小等。
SVG图标:可以直接将SVG代码嵌入到HTML中,或者将SVG文件作为组件引入。SVG图标具有矢量特性,可以无损缩放,适合各种尺寸的显示需求。
图片图标:将图标保存为图片文件(如PNG、JPG等),通过<img>标签引入。这种方式简单直接,但图片在不同分辨率下可能会出现模糊问题,且不利于样式的灵活调整。
事件监听与处理:为a组件添加点击事件监听器,当a组件被点击时,触发相应的事件处理函数。
状态管理:使用状态管理工具(如Redux、Vuex等)或组件自身的状态来控制b组件的显示和隐藏。在事件处理函数中,更新状态值,例如将表示b组件显示状态的状态变量设置为false。
条件渲染:根据状态变量的值,在渲染b组件时进行条件判断。如果状态变量为false,则不渲染b组件,从而实现点击a组件时b组件消失的效果。
Quick BI是一款商业智能(BI)工具,它提供了数据可视化、数据分析、数据报表等功能,帮助用户快速地将数据转化为有价值的洞察和决策依据。用户可以通过简单的拖拽操作,将数据源中的数据字段拖放到仪表盘中,生成各种类型的图表和报表,如柱状图、折线图、饼图等,同时支持数据的筛选、排序、钻取等交互操作,方便用户进行深入的数据分析。
HTML5拖放API:
为被拖拽元素(a)设置draggable="true"属性,使其可拖拽。
监听dragstart事件,在事件处理函数中设置拖拽数据(如元素的ID、类型等),可以通过event.dataTransfer.setData()方法实现。
为目标区域(b)监听dragover事件,在事件处理函数中调用event.preventDefault(),允许元素被放置在该区域。
监听drop事件,在事件处理函数中获取拖拽数据,并根据数据进行相应的操作,如将a元素添加到b元素中。
使用第三方库:如React DnD、Vue.Draggable等,这些库提供了更简洁的API和丰富的功能,可以更方便地实现拖拽效果。
判断元素是否在可视区内:创建一个IntersectionObserver对象,并指定回调函数。将需要观察的元素添加到观察列表中。当元素与视口的交叉状态发生变化时,回调函数会被触发,通过回调函数中的IntersectionObserverEntry对象可以获取元素与视口的交叉比例等信息,从而判断元素是否在可视区内。
懒加载:在页面滚动时,使用Intersection Observer观察图片等资源的容器元素。当容器元素进入可视区时,动态加载对应的资源,如图片的src属性,从而实现懒加载效果,提高页面的加载性能。
实现原理:虚拟滚动只渲染当前视口内可见的元素以及少量的缓冲元素,而不是渲染整个列表的所有元素。通过监听滚动事件,根据滚动位置和元素的高度计算出当前应该显示的元素范围,然后只对这些元素进行渲染和布局,从而大大减少了DOM节点的数量,提高页面性能。
不定高度问题:在不定高度的情况下,确实可能会出现渲染两次的情况。第一次渲染时,由于不知道元素的具体高度,会先使用一个估计高度进行初始渲染和布局。当元素的实际高度确定后(例如图片加载完成),会重新计算布局并进行第二次渲染。为了减少这种情况的影响,可以采取一些优化措施,如提前获取元素的高度信息、使用占位元素等。
原理:Vite利用ES Modules的静态分析特性,在构建过程中对代码进行依赖分析,将不同的模块按照一定的规则划分到不同的包中。通过分包可以将代码拆分成多个较小的文件,减少单个文件的体积,提高加载速度,同时可以利用浏览器的并行加载机制,加快资源的加载速度。
分包方法:
手动配置:在vite.config.js文件中,通过build.rollupOptions.output.manualChunks选项手动指定将哪些模块打包到同一个文件中。例如:
开发环境:
基于原生ES Modules,无需打包,启动速度快。
提供热模块替换(HMR)功能,修改代码后页面无需刷新即可实时更新。
开发服务器支持丰富的功能,如代理、跨域处理等。
生产环境:
会对代码进行打包和优化,生成适合生产环境部署的文件,如压缩代码、去除注释等。
支持更多的构建配置选项,如代码分割、分包、资源处理等,以优化页面性能。
文件指纹:文件指纹是通过在文件名中添加哈希值等方式,使得每次构建后文件的名称发生变化。当页面引用的资源文件(如CSS、JS等)的指纹发生变化时,浏览器会重新加载这些资源,从而避免了缓存导致的问题。如果希望页面的渲染元素不被修改,可以通过确保相关资源文件的指纹不变来实现。例如,在构建工具中配置固定的文件命名规则,或者将不需要更新的资源文件单独管理,不参与构建过程中的指纹生成。
撤销此次推送:如果刚刚推送到远程仓库,可以使用git push -f origin <commit-hash>^:main命令强制将远程的main分支回退到指定提交的前一个状态,从而撤销此次推送。但这种方法比较危险,会改变远程仓库的历史记录,不建议在多人协作的项目中频繁使用。更安全的方法是先在本地进行回退操作,然后再重新推送正确的提交。例如:
使用git log查看提交历史,找到要回退到的提交的哈希值。
使用git reset --hard <commit-hash>将本地main分支回退到指定提交。
使用git push -f origin main将本地的回退操作推送到远程仓库。
利用git cherry-pick转移提交到另外一个分支:
使用git checkout切换到目标分支。
使用git cherry-pick <commit-hash>将指定的提交应用到当前分支。