Skip to content

Html 面试篇

Html 面试

  • 理解一个元素语义化就可以了,其他的不太怎么重要
  • 无处不 div 和 span

CSS 面试篇

前端首屏优化操作

  • 该部分的话主要的就是对我们的页面的加载有一定的关系了
    • 内涵的就是问你关于我们的浏览器的渲染原理吧
    • 我们的浏览器的渲染原理的话可以的是
  • 完成我们的动画的时候的性能优化
    • 使用的定位将元素脱标
    • 从而减少对页面加载过程中发生的重绘 reflow 的可能性
    • 定位的话可以生成渲染层,也是合成层,从而不影响标准流的渲染
    • 从而实现性能的优化,提高我们的前端首屏渲染优化吧
  • 前端创建新的渲染层的方法(减少回流)
    • 有明确的定位属性(position: absolute)
    • 透明度的设置(opacity 小于 1)
    • css transform 属性的设置
    • backface-visibility 属性的设置
    • opacity transform filter backdrop-filter等等
      • 合成层的话主要的就是开启我们的 CPU 硬件优化吧
      • 合成层和渲染层开启的优化吧
      • 合成层的出现主要是在我们的 3D 效果中实现的呐
      • 渲染层的实现主要是通过我们的定位实现的呐
    • 但是注意的是创建新的合成层的话,不要滥用,因为这个是以消耗内存为代价实现的性能优化
  • 同时还可以使用我们的 defer 和 async 模式的 script 的引入实现我们的
    • js 文件的引入吧
    • 这样也是可以实现一定的前端的首屏优化吧
    • 因为 js 文件的下载以及解析的话都是会影响页面的加载的呐
  • https://juejin.cn/post/7434162412113723455 浏览器 的渲染原理
  • https://juejin.cn/post/7434178908985901097 浏览器 js的解析原理

JavaScript 面试篇

闭包和内存泄漏

  • 什么是内存泄漏呐??
    • 就是代码中有数据没有被回收,这个就是我们的内存泄漏吧
    • 在我们的 JavaScript 中的话只要数据被引用了,那么数据就不会被回收,这样就导致了内存泄漏
  • 先来一个伪代码
javascript
function createInstance() {
    const doms = new Array(10000).fill(0).map((_, index) => {
        const dom = document.createElement('div')
        dom.innerHTML = index
        return dom
    })
  
    // 副作用函数
    function effectFunc() {
        console.log(doms)
    }

    function instance() {
        doms.forEach((dom) => {
            dom.innerHTML = Number(dom.innerHTML)
        })
    }
    
    return instance
}

const instance = createInstance()
const btn = document.getElementById('btn')
btn.addEventListener('click', () => {
    instance()
})
  • 什么是程序中的垃圾呐??
    • 就是取决于我们的程序中是否使用该数据,那么这个就是我们的代码中的垃圾了
    • 所以说在程序中,我们没有使用的数据尽量进行及时的释放掉吧
    • 如果程序中有垃圾没有被回收,这个就是我们的内存泄漏了
  • 闭包和内存泄漏的关系
    • 函数 + 词法环境就是我们的闭包 (es6的说法了)
      • 所以说我们的一个函数的话,实际上实现了关联了其本身所在的词法环境的,
      • 如果函数还存在的话,那么我们的词法环境以及词法环境中的数据就会一直存在,就不会被回收
      • 同时词法环境是可以被多个函数共享的,所以说,即使是释放掉了一个函数,但是我们的词法环境可能任然存在
      • 释放函数的操作,就是复制为 null
        • instance = null
  • 上面伪代码的优化
javascript
function createInstance() {
    const doms = new Array(10000).fill(0).map((_, index) => {
        const dom = document.createElement('div')
        dom.innerHTML = index
        return dom
    })

    // 副作用函数
    function effectFunc() {
        console.log(doms)
    }

    function instance() {
        doms.forEach((dom) => {
            dom.innerHTML = Number(dom.innerHTML)
        })
    }
    
    // 由于我们的 effectFunc 函数还是依赖于词法环境的,所以说即使是外面的 instance 引用释放掉了
    // 我们的 doms 数据还是无法被释放,这个时候就需要进行的是将其也十分掉吧
    effectFunc = null
    return instance
}

const instance = createInstance()
const btn = document.getElementById('btn')
btn.addEventListener('click', () => {
    instance()
})
instance = null  // 释放我们的函数

TypeScript 面试篇

Vue 面试篇(vue >= 3)

React 面试篇(react > 18)

Angular 面试篇

Solid 面试篇

Svelte 面试篇

Node 面试篇

Deno 面试篇

Nuxt 面试篇

Next 面试篇

Nest 面试篇

Taro 面试篇

Uniapp 面试篇

Webpack 面试篇

Vite 面试篇

Rollup 面试篇

Visible-end 面试篇

浏览器面试篇

前端模块化开发篇

commonjs 开发规范实质

  • 我们的commonjs 的开发规范的话实际上主要研究的是
    • require 导入函数
    • exports 导出函数
    • 模块中的 this
    • module.exports 导出函数
  • 首先我们先来一个require函数的伪代码吧
javascript
function require(modulePath) {
    // 1.获取得到路径的绝对路径
    var moduleId = getModuleId(modulePath);
    
    // 2.判断导入是否存在缓存
    if (cache[moduleId]) {
        return cache[moduleId]
    }
    
    // 3.运行真真的代码的函数
    // 就是我们的 commonjs 开发规范可以使用的方法
    // __fileName 和 __dirName 就是我们的主要的两个可以实现使用的全局变量吧
    function exeRequiore(exports, require, module, __fileName, __dirName) {
        this.a = 1
        exports.b = 2
        exports = {
            c: 3
        }
        exports.e = 5
        this.f = 6
    }
    
    // 4.准备模块运行的辅助函数
    var module = {
        exports: {
            
        }
    }
    
    var exports = module.exports
    var __fileName = moduleId
    var __dirName = getDirName(__fileName)
    
    // 运行函数了
    exeRequiore.call(exports, exports, require, module, __fileName, __dirName)
    // 运行后直接进行缓存
    cache[moduleId] = module.exports
    // 最后就是实现我们的返回
    return module.exports
}
  • 在我们的社区中的发展中的话,实际上每一个模块的运行的话都是基于我们的函数来实现的
    • 每一个模块文件的话都是我们的一个一个的可运行函数的呐
    • 这个的话和我们的以前的解决模块化开发的 IIFE 一致吧,函数是可以为我们的模块提供一个函数作用域
    • 这个也是为什么我们的模块化开发可以解决变量重名的原因之一吧
  • commonjs 的开发规范中实际上的话导出的就是我们的 module.exports
    • exports 是一个导出函数
javascript
// 开始实现书写我们的第一个模块
this.a = 10
exports.b = 10
exports = {
    c: 3
}
module.exports = {
    d: 5
}
exports.e = 2
this.f = 10

console.log(this, exports, module.exports)
// this: { a:10, f:10 }
// exports: { c: 3, e: 2 }
// module.exports: { d: 5 }
console.log(arguments.length)  // 5
  • 这一点就告诉我们的一点的是,如果想要一个 js 文件之间的作用域不相互干扰
    • 就可以在一个 js 或者 ts 文件中添加 exports 即可
    • commonjs 中含有我们的两个全局可以使用的变量
      • __filename 就是我们的文件路径
      • __dirname 就是我们的目录路径吧
      • require 我们的导入模块函数
      • exports 我们的导出函数,本质上是一个对象的
      • module 我们的默认的导出对象,内部具备我们的 exports 属性的呐
    • 由于每一个模块就是一个一个的函数,所以说
      • 模块内具备 this
      • 模块内具备我们的 arguments,其length是为 5

性能优化面试篇

  • 对于我们的前端首屏渲染优化
  • 前端缓存 cdn 缓存优化
  • react 使用 useMemo 和 useCallback 实现优化
  • 浏览器原理优化
  • 算法优化

前后端交互面试篇

算法面试篇

开发小技巧篇

Released under the MIT License.