🇲 🇷 、🇱 🇮 🇺

文章 分类 评论
5 9 4

站点介绍

某人的小破站

前端 30 道精准面试题 冲刺 2024 金三银四

🇲 🇷 、🇱 🇮 🇺 2024-01-24 70 0条评论 面试题

首页 / 正文
  1. 从输入 url 到渲染页面

    1. 浏览器的地址栏输入 URL 并按下回车。
    2. 浏览器查找当前 URL 是否存在缓存,并比较缓存是否过期。
    3. DNS 解析 URL 对应的 IP。
    4. 根据 IP 建立 TCP 连接(三次握手)。
    5. HTTP 发起请求。
    6. 服务器处理请求,浏览器接收 HTTP 响应。
    7. 渲染页面,构建 DOM 树。
    8. 关闭 TCP 连接(四次挥手)
  2. Js 中的单线程和事件循环
     Js 是单线程,但是浏览器是多线程。
     Js 中采用了事件循环(Event Loop)来执行异步任务。
     所以,事件循环是一种异步编程模型,事件循环会不断地从任务队列(Task Queue)
    中取出待处理的任务并执行,直到任务队列为空为止。任务可以分为两类:宏任务
    (Macro Task)和微任务(Micro Task)。
     微任务会优先于宏任务执行
  3. Js 实现继承有哪几种方式?

    1. 原型链继承:将父类的实例作为子类的原型,通过 prototype 进行继承
    2. 构造继承:将父类的实例属性复制给子类,通过 call 进行继承
    3. 实例继承:为父类实例添加新特性,作为子类实例返回
    4. 拷贝继承:将父类实例通过循环拷贝给子类
    5. 组合继承:就是 原型链继承 和 构造继承,一起使用
    6. 寄生组合继承:通过寄生方式,砍掉父类的实例属性,避免了 组合继承中,在调用
      两次父类的构造时,初始化两次实例方法/属性 的缺点
  4. Js 中 bind(),call()和 apply()的区别
    JavaScript 中的 bind()、call() 和 apply() 方法都可以用来改变函数内部的 this
    指向。
    它们有一些重要的区别:
     三种方法最大的区别在于参数传入方式不同:bind() 方法接受一系列参数列表,而
    call() 和 apply() 方法则分别接受一组参数和一个参数列表。具体而言,bind() 将参
    数作为一个个单独的值传入,而 call() 和 apply() 都允许传递一个数组作为参数。
     执行时间不同:bind() 绑定后返回一个新函数,并不会立即执行,需要调用该函数
    才会执行;而 call() 和 apply() 则会立即执行函数。
     返回值不同:bind() 方法返回一个绑定后的新函数,而 call() 和 apply() 则直接执
    行原始函数并返回执行结果。 它们的作用分别如下:
     bind() 方法:bind() 可以指定函数内部的 this 指向,并将其绑定到一个新函数上进
    行返回。该函数并不会立即执行,而是等待调用。bind() 也可以用来实现柯里化
    (currying)
     call() 方法:call() 可以在指定的 this 值和若干个参数(参数的列表)的前提下调用
    某个函数或方法。注意,call() 方法需要将参数逐个传递进去,而不能像 apply() 方
    法一样将所有参数打包成一个数组。
     apply() 方法:apply() 和 call() 的作用非常类似,都是改变函数内部的 this 指向。
    区别在于,apply() 方法需要将参数打包成一个数组传递进去,而 call() 则是将参数
    逐个传递。
  5. Js 中的闭包及其使用场景
     官方说法:闭包就是指有权访问另一个函数作用域中的变量的函数。
     MDN 说法:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环
    境。环境由闭包创建时在作用域中的任何局部变量组成。
     深度回答:浏览器在加载页面会把代码放在栈内存( ECStack )中执行,函数进栈
    执行会产生一个私有上下文( EC ),此上下文能保护里面的使用变量( AO )不
    受外界干扰,并且如果当前执行上下文中的某些内容,被上下文以外的内容占用,
    当前上下文不会出栈释放,这样可以保存里面的变量和变量值,所以我认为闭包是
    一种保存和保护内部私有变量的机制。
  6. Vue2 与 Vue3 中的双向数据绑定
    双向数据绑定就是:数据劫持 + 发布订阅模式(观察者模式)。
    Vue2 中在实例初始化时遍历 data 中的所有属性,并使用 Object.defineProperty
    把这些属性全部转为 getter/setter。并 劫持各个属性 getter 和 setter,在数据
    变化时发布消息给订阅者,触发相应的监听回调,而这之间存在几个问题
     初始化时需要遍历对象所有 key,如果对象层次较深,性能不好
     通知更新过程需要维护大量 dep 实例和 watcher 实例,额外占用内存较多
     Object.defineProperty 无法监听到数组元素的变化,只能通过劫持重写数方法
     动态新增,删除对象属性无法拦截,只能用特定 set/delete API 代替
     不支持 Map、Set 等数据结构
    Vue3 中使用 Proxy 来监控数据的变化。Proxy 是 ES6 中提供的功能,其作用为:
    用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。
  7. Vue 中 template 模版的编译原理

    1. 解析(parse):将模板字符串解析成 AST(抽象语法树)。
    2. 静态分析(static analysis):对 AST 进行静态分析,标记出其中的静态节点(Static
      Node)。
    3. 优化(optimize):遍历 AST,对静态节点进行优化,去掉不必要的操作。
    4. 代码生成(code generation):将 AST 转换成渲染函数(render function)的可执行代
      码。
    5. 最终的渲染:将生成的渲染函数运用到数据上,最终生成视图。
  8. Vue2 中的 diff 流程
    Vue2 中的虚拟 DOM diff 算法,其核心是采用双端比较(Two-Ended Algorithm)。
    具体来说,Vue2 中 diff 算法的步骤如下:

    1. 首先比较新旧虚拟 DOM 树的根节点,如果它们是不同类型的节点,则直接替换整
      个节点树;
    2. 如果根节点相同,则比较它们的子节点,这个过程称之为“Diff Children”;
    3. 在“Diff Children”过程中,使用双端比较算法,即同时从新虚拟 DOM 树和旧虚拟 DOM
      树的两端开始向中间遍历,找到相应的节点进行比较,找到更新的节点后就停止比
      较;
    4. 如果新旧虚拟 DOM 树的子节点数组长度不同,则根据差异进行添加或删除节点;
    5. 对于相同位置的节点,判断它们是否相同,如果不同则进行更新;
    6. 最后返回新的虚拟 DOM 树。
  9. Vue3 中的 diff 流程
    在 Vue3 中,Diff 流程主要分为两个阶段:标记阶段和应用阶段。其中标记阶段
    是用来比较新老 VNode 树的差异,并记录下来需要进行的具体操作;应用阶段
    则是将这些具体操作应用在真实 DOM 上,完成页面的更新。
  10. Vue 中的组件间通信有哪些?

    1. props:父组件通过 props 属性向子组件传递数据。子组件接收该数据后,即可在其
      模板中直接使用。
    2. $emit() 和事件:子组件通过 $emit() 方法触发一个自定义事件,并把需要传递的数
      据作为参数传入。父组件监听该自定义事件,并在回调中处理数据。通过事件可以
      实现任意级别的组件间通信。
    3. $parent 和 $children:父组件可以通过 $children 找到所有的子组件,子组件可以
      通过 $parent 找到其父组件。这种方式属于直接引用和修改组件对象,需要注意和
      谨慎使用。
    4. provide 和 inject:祖先组件通过 provide 属性向子孙组件传递数据,子孙组件通过
      inject 属性来获取这些数据。provide 和 inject 绑定并非响应式的,但是可以将一个
      观察者实例注入到 provide 中,使得组件在 inject 期间发生变化时获得通知。
    5. Vuex 状态管理(Vue3 中的 pinia):Vuex 是一个专门为 Vue.js 应用程序开发的状
      态管理库,提供了一种集中式存储管理应用程序中的所有组件的状态。组件通过调
      用 mutation 方法来改变状态,其他组件通过监听 state 属性来获取最新的状态。
    6. 兄弟组件间的传值:Vue2 中使用 eventBus 中央事件总线 , Vue3 中使用的 mitt 库
  11. Vue-router 中如何实现懒加载?
    在路由配置文件中使用动态导入 import()语句,并用箭头函数返回实现路由懒加
    载。
  12. Vue3 相对于 Vue2 进行了哪些优化?

    1. 更灵活的响应式系统:Vue 2.x 中响应式系统的核心是 Object.defineProperty,劫持
      整个对象,然后进行深度遍历所有属性,给每个属性添加 getter 和 setter,实现响应
      式。Vue 3.x 中使用 Proxy 对象重写响应式系统。
    2. 更快的渲染速度:Vue3 的编译器生成的渲染函数比 Vue2 生成的更高效。
    3. 编译阶段:Vue 2.x 通过标记静态节点,优化 diff 的过程。Vue 3.x 中标记和提升所
      有的静态节点,diff 的时候只需要对比动态节点内容。
    4. 更小的体积:Vue3 将源码拆分为多个独立的模块,这样就可以按需导入所需的模块,
      从而减小了整个库的体积。
    5. 更好的 TypeScript 支持:Vue3 对 TypeScript 的支持更加友好,内部使用了更先进
      的 TypeScript 特性,并为其提供了更好的声明文件。
    6. 更好的组件系统:比如,Vue3 中引入了一个新的 Fragment 组件,它可以替代原来
      的 template 标签作为根节点
    7. 新增了 setup 组合式 API
  13. 介绍一下 React Fiber
    React Fiber 是 React 框架的一种重新实现,旨在改善渲染性能和用户体验。它通
    过引入优先级调度、增量渲染和可中断的工作单元等机制,将渲染任务分解成小
    的可中断的单元,从而使 React 能够更好地处理大型应用程序和高优先级任务,
    提供流畅且响应迅速的用户界面。
  14. React 中常用的高阶组件有哪些?

    1. withRouter:将路由信息注入到组件中,使它们能够访问到路由对象(如 location、
      history 和 match 等)。
    2. connect:将 React 组件与 Redux Store 连接起来,并将 State 和 Dispatch 作为 Props
      传递给组件。这使得组件能够直接从 Store 中读取和操作数据。
    3. memo:对于纯函数组件,使用 memo 可以缓存组件输出,以提高性能。
    4. withStyles:用于添加 CSS 样式到组件中。
    5. redux-thunk:使 Action Creator 返回一个函数而不是一个 Action 对象,从而可以执行
      异步操作并 dispatch 新的 Action。
    6. recompose:提供了一组高阶功能,用于增强函数式 React 组件。例如,compose 函
      数可以将多个 HOC 组合在一起。
    7. react-redux:提供了一组基于 Redux Store 的 React 组件,并简化了 React 与 Redux
      之间的集成。
  15. React Hook 为什么不能放到条件语句中?
    React Hook 不能放到条件语句中的原因是:React 需要使用 Hook 的规则是必
    须确保每次渲染时,Hook 调用的顺序都是一致的。也就是说,在一个组件内部,
    每一次渲染时,Hook 的调用顺序必须是相同的。
    如果将 Hook 放到条件语句中,当条件发生变化时,Hook 的调用顺序就可能被
    打乱,从而导致组件状态不一致、出现错误等问题。因此,React 在运行时会对
    Hook 的调用顺序进行验证,来确保 Hook 的使用符合规范。
  16. React 有哪些常用的 hooks?

    1. useState:该 Hook 用于在函数组件中添加一个状态管理器。通过 useState,可以创
      建一个状态变量及其更新函数,并在组件内使用该变量来保存和更新组件的状态。
    2. useEffect:该 Hook 用于在组件渲染完成后执行一些副作用操作(例如订阅数据、
      更新 DOM 等)。通过 useEffect,可以在组件加载、更新和卸载时设置和清理副作
      用操作,并且可以在副作用操作之间共享状态。
    3. useContext:该 Hook 用于在组件之间共享一些全局的状态或函数,以避免通过多
      层嵌套的 Props 传递进行数据传输。通过 useContext,可以让组件在全局状态或函
      数的上下文中运行,并让它们能够方便地读取或更新全局状态或函数。
    4. useReducer:该 Hook 用于在组件中使用一种“状态容器”模式,以避免通过多层
      Props 传递或 Context 共享进行状态管理。通过 useReducer,可以创建一个状态容
      器及其更新函数,并在组件内使用该容器来保存和更新组件的状态。
    5. useMemo:该 Hook 用于在组件渲染完成后缓存一些计算结果,以避免因为重复计
      算导致的性能问题。通过 useMemo,可以创建一个缓存变量,并在组件内使用该变
      量来保存计算结果并缓存。
    6. useCallback:该 Hook 用于在组件渲染完成后,将一些函数进行缓存,以避免因函
      数重复创建导致的性能问题。通过 useCallback,可以创建一个缓存函数,并在组件
      内使用该函数来代替重复创建的函数。
    7. useRef:该 Hook 用于在组件渲染完成后创建一个引用,以便在组件多次渲染时能
      够保留上一次渲染中的值。通过 useRef,可以创建一个引用变量,并在组件内使用
      该变量来保存一些持久化的数据。
    8. useImperativeHandle:该 Hook 用于在组件中实现一些自定义的 Ref 对象,并且要
      求将一些组件内部的方法或状态暴露给父组件使用。通过 useImperativeHandle,可
      以创建一个自定义的 Ref 对象,并在组件内指定一些公开的方法或属性。
    9. useLayoutEffect:该 Hook 与 useEffect 类似,但它会在浏览器渲染更新之前同步执
      行副作用操作,以确保 React 组件与浏览器同步更新。通常情况下,应该使用
      useEffect,但在需要直接操作 DOM 元素或进行测量布局界面时,应当使用
      useLayoutEffect。
    10. useDebugValue:该 Hook 可以帮助开发者在调试工具中显示额外的信息,以便更好
      地理解 Hook 的使用和行为。通常情况下,这个 Hook 只用于调试过程中,而不是
      实际的应用程序代码中。
  17. 介绍下 React 中的 useEffect
     在 React 中,useEffect 是一个用于处理副作用的 Hook。
     副作用是指在组件生命周期中的某些特定时刻需要执行的操作,例如数据获取、订
    阅事件、手动操作 DOM 等。
     useEffect 的作用就是在组件渲染完成后执行这些副作用操作。
  18. 介绍一下 Promise 的状态及其方法
    在 JavaScript 中,Promise 对象包含三种状态:Pending(进行中)、Fulfilled(已
    成功)和 Rejected(已失败)。
    Promise 的方法如下:

    1. Promise 对象可以通过 then() 方法添加成功(Fulfilled)和失败(Rejected)时的回
      调函数。then() 方法可以链式调用,每次返回一个新的 Promise 对象,因此可以很
      容易地实现异步任务的连续执行。
    2. Promise 对象还提供了 catch() 方法用于捕获错误和 finally() 方法用于在 Promise
      被解析后运行代码块。
    3. Promise.all() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise,只有
      当所有 Promise 都解析成功时才会被解析,否则该 Promise 会被拒绝。
    4. Promise.race() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise,只要
      有一个 Promise 被解析或拒绝就会被解析或拒绝。
    5. Promise.resolve() 和 Promise.reject() 方法分别返回一个已解析和一个已拒绝的
      Promise 对象,可以用于快速创建 Promise。
  19. 介绍一下 async/await 的实现原理
    在 JavaScript 引擎中,async/await 函数的实现原理是基于 Promise 对象和生成
    器函数(Generator Function)的协作。
  20. 介绍一下 let、const、var 的区别
  21. 箭头函数和普通函数有什么区别

    1. 写法不同:箭头函数使用箭头(=>)来定义,而普通函数使用 function 关键字定义。
    2. this 的处理方式不同:在箭头函数中,this 的值与外层作用域的 this 绑定。而在普
      通函数中,this 的值由调用该函数的方式决定。
    3. 箭头函数没有 arguments 对象:箭头函数中没有自己的 arguments 对象,它的参
      数只能通过参数列表来传递。
    4. 箭头函数不能用作构造函数:由于箭头函数中没有自己的 this 值,因此不能用作构
      造函数来创建对象实例。
  22. Css 中常用的垂直居中解决方案有哪些?
    vertical-align 属性用于控制元素内部的行内元素(如文本或图片)的垂直对齐
    方式。通常与 display: table-cell 结合使用,实现单元格内部的元素垂直居中。
    line-height属性
    用于设置行内元素的行高,可以使单行文本元素垂直居中。
    但是如果元素高度超过一行,则无法实现垂直居中。

flexbox 布局使用display: flex 和相关属性可以实现容器内元素的水平和垂直居中。

grid布局使用display: grid和相关属性可以实现网格布局中元素的水平和垂直居中。

绝对定位 + 负边距将需要垂直居中的元素绝对定位到容器中心,然后通过负边距调整元素位置。

  1. 什么是 BFC?
    BFC(Block Formatting Context)是 CSS 中一个很重要的概念。它是指一个块级
    容器,其中的元素按照特定规则布局和渲染,同时也影响着其内部和外部元素的
    布局。
  2. Css 中移动端适配有哪些方案?

    1. 首先,通过 meta 标签设置 viewport
    2. rem 单位搭配@media 媒体查询:可以通过使用 rem 单位,它以 HTML 元素的 font-size
      为比例,也可以搭配 postcss-pxtorem 搭建项目
    3. vw/vh 布局:也可以通过使用 vw/vh 布局,vw/vh 方案与 rem 方案类似,都是将
      页面分成一份一份的,只不过 vw/vh 是将页面分为 100 份,也可以搭配
      postcss-px-to-viewport 搭建项目
    4. 百分比布局:也可以使用百分比来实现布局,但是需要特定宽度时,这个百分比的
      计算对开发者来说并不友好,且元素百分比参考的对象为父元素,元素嵌套较深时
      会有问题。
  3. 什么是 Css 中的回流(重排)与重绘?
    回流(重排)(reflow)和重绘(repaint)是浏览器渲染页面时的两个核心概念。
     回流(重排)指的是当页面中的元素发生布局或几何属性发生变化时,浏览器需要
    重新计算这些元素的位置和大小,然后重新构建页面的渲染树,这个过程称为回流。
    由于需要重新计算布局,回流的代价很大,会对页面的性能产生负面影响。
     重绘指的是当页面中的元素样式发生改变时,浏览器会重新绘制这些元素的外观,
    但不会改变它们在页面中的位置和大小。重绘的代价相对较小,但仍然会对页面性
    能产生一定的影响。
  4. 常用的跨域解决方案有哪些?

    1. CORS:跨域资源共享(Cross-Origin Resource Sharing),是一种允许浏览器向跨域服
      务 器 发 送 Ajax 请 求 的 机 制 , 支 持 现 代 浏 览 器 , 服 务 器 端 需 要 设 置
      Access-Control-Allow-Origin 头信息,指定允许的源或通配符,从而实现跨域请求。
    2. 代理:在同源页面内部发送 AJAX 请求到同域服务器,由服务器代理转发请求到跨
      域服务器,最后再将结果返回给同源页面。
    3. WebSocket:WebSocket 是一种 HTML5 协议,它使得浏览器和服务器之间可以建立
      持久化的连接,可以直接使用 Socket 进行通信,避免了浏览器的跨域限制。
  5. Webpack 中有哪些核心概念?

    1. Entry(入口):Webpack 在打包时需要从哪个文件开始构建依赖关系图,就是入口。
      可以设置多个入口文件,以生成多个输出文件。
    2. Output(输出):打包后的文件放在哪里,以及如何命名这些文件。可以指定输出
      目录、文件名、公共路径等。
    3. Loader(模块加载器):Webpack 只能处理 JavaScript 文件,而其他类型的文件如 CSS、
      图片等需要通过 Loader 转换才能被 Webpack 处理。Loader 用于对模块内容进行转换
      处理。
    4. Plugin(插件):Plugin 可以用于执行各种任务,例如打包优化、错误处理和环境变
      量注入等。Webpack 本身只提供了一些基本的 Plugin,但社区中有很多第三方 Plugin
      可供使用。
    5. Mode(模式):Webpack 提供了三种模式:development、production 和 none。不
      同的模式会启用不同的 Webpack 内置 Plugin 和 Loader,以便于开发和生产环境的优
      化。
    6. Chunk(代码块):Webpack 在打包时会把所有相关联的模块组成一个 Chunk。可以
      通过 Code Splitting 技术将代码拆分成多个 Chunk,以实现按需加载。
    7. Module(模块):Webpack 把每个文件都看作一个模块,它可以是 JavaScript、CSS、
      图片等。这些模块通过依赖关系进行组合,构成整个应用程序。
  6. Vite 和 Webpack 的区别
     优点:快速的冷启动: 采用 No Bundle 和 esbuild 预构建,速度远快于 Webpack 高效
    的热更新:基于 ESM 实现,同时利用 HTTP 头来加速整个页面的重新加载,增加缓
    存策略真正的按需加载: 基于浏览器 ESM 的支持,实现真正的按需加载
     缺点生态:目前 Vite 的生态不如 Webapck,不过我觉得生态也只是时间上的问题。
    生产环境由于 esbuild 对 css 和代码分割不友好使用 Rollup 进行打包
  7. Webpack 常见的优化方案有哪些?

    1. 升级 webpack 版本,3 升 4,实测是提升了几十秒的打包速度
    2. 使用 Tree Shaking 和 Scope Hoisting 来减少代码体积和模块构建时间,其中 Tree
      Shaking 可以去除未使用的代码,而 Scope Hoisting 可以将模块内的代码尽量合并到
      一个函数(单一作用域)中,以减少函数声明和闭包的数量。
    3. 使用 splitChunksPlugin 插件来将公共代码抽离成单独的 chunk,以减少代码重复和提
      高缓存命中率。
    4. 合理配置 resolve.alias 和 resolve.extensions 选项来减少 Webpack 查找文件的时间。
    5. 针对生产环境,可以开启代码压缩以及多进程并行处理等优化方式,以减少构建时
      间和服务器负载。
    6. 使用 DLLPlugin 和 DllReferencePlugin 来预先编译一些稳定不变的代码,以减少每次构
      建的时间。
    7. 使用 HappyPack 来启用多线程并发处理,以加速代码构建和增强开发体验。
    8. 对于图片、字体等资源文件,可以通过 url-loader 和 file-loader 等 loader 设置较小的
      limit 值,将文件转换成 base64 编码的字符串内嵌在 js 文件中,以减少 http 请求次
      数。
  8. 浏览器中强缓存与协商缓存的缓存机制
    强缓存和协商缓存是两种不同的缓存策略。
    强缓存通过设置响应头中的 Cache-Control 或 Expires 字段,告诉浏览器在一定时
    间内直接使用本地缓存,不需要发送请求到服务器。只有当缓存过期或被清除时,
    浏览器才会发送请求到服务器获取新的资源。
    协商缓存通过设置响应头中的 ETag 和 Last-Modified 字段,浏览器在每次请求时
    携带 If-None-Match 和 If-Modified-Since 字段,与服务器进行比较。如果资源未发
    生变化,则服务器返回 304 Not Modified 状态码,并告知浏览器继续使用缓存;
    如果资源发生变化,则服务器返回新的资源。
    强缓存是基于时间的缓存控制,而协商缓存则是通过与服务器进行交互来判断是
    否使用缓存,更加灵活。

来源:牛客网
链接:https://www.nowcoder.com/discuss/576490235048050688

评论(0)

最新评论

  • 奶爸博客

    恭喜

  • 🇲 🇷 、🇱 🇮 🇺

    111

  • 🇲 🇷 、🇱 🇮 🇺

    1111

  • Typecho

    欢迎加入 Typecho 大家族

日历

2024年07月

 123456
78910111213
14151617181920
21222324252627
28293031   

文章目录

推荐关键字: 美女 mysql php 前端 后端 闲聊