笔者在2021年末到2022年初面了阿里、百度、字节跳动、微软、拼多多、B站等大厂,本身来说是3-5年经验这个范围。可以看到各大厂对前端的基础知识还是非常重视的,因此想对在这些面试中经常会被问到的题目进行总结,这一篇主要是基础题,希望能够帮助各位一起在前端道路上奋斗的小伙伴获得心仪的offer。

js相关(ts)

  1. 箭头函数

    • 不可用于构造函数,无prototype

    • 无法改变this指向

  2. 原型链

    • 每个对象的__proto__指向创建它的构造函数的prototype,而构造函数的prototype也有__proto__指向他的父辈或者是Object,当查找一个对象中不存在的属性时,会去它的__proto__、__proto__中的__proto__中进行寻找,直到找到或者是null为止

    • instanceof判断对象的__proto__和构造函数的prototype是不是同一个地址

    • Object.setPrototypeOf改变对象的__proto__

  3. 闭包

    • 定义:在一个函数A中,定义函数B访问函数A的变量

    • 目的:隐藏变量

  4. Map和Object的区别

    • Map的key可以为任何值,而Object只能为string

    • Map 元素的顺序遵循插入的顺序,而 Object 的则没有这一特性

  5. Weak map

    • Weak map的key是弱引用,不会被垃圾回收的计数计算

    • 可以用来做反射的元数据池、保存有关DOM节点的数据

  6. 实现一个Partial

    1
    type MyPartial<T> = {[K inkeyof T]?: T[K]};
  7. 输出什么

    1
    2
    3
    4
    Promise.reject(2)
    .catch(err=>console.log("err1,",err))
    .then(res=>{console.log("then1",res)})
    .catch(err=>console.log("err2,",err))
  8. 从浏览器输入地址到呈现出网页的过程

    • async script会在script下载完成时立即执行,和构造render树并行

    • defer script会在文档渲染完毕后,DOMContentLoaded事件调用前执行

    • html、css、font这三种类型的资源优先级最高

    • TLS握手

    • 客户端请求服务端的证书

    • 第一次非对称加密,用CA的公钥去解证书的签名,如果解出来的hash和证书信息hash一致则合法

    • 第二次非对称加密,客户端使用服务端公钥加密随机数

    • 服务端使用服务端私钥解密随机数

    • 使用随机数进行对称加密

    • 查看是否有有效的service worker缓存

    • 判断是否有强缓存,也就是未过期的资源,靠expire和cache-control判断

    • DNS域名解析

    • 进行三次握手+TLS握手

    • 向资源发送请求

    • 协商缓存,使用if-modified-since和etag与服务器对比,或没有改变取本地缓存,返回的状态码是304

    • 取回资源

    • 解析网页资源,下载网页中的资源

    • 生成dom树和css树,构造render树

    • 重排、重绘、合成

    • 当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。

    • 首次渲染时一定会执行重排,后续如果不改变元素的外形位置尺寸则可以只执行重绘,不执行重排。

    • 重绘得到的像素使用GPU绘制在页面上,一些特殊的element会单独为一个合成层(比如will-change、或者3D转换等),合理使用合成层可以提高动画效果

    • 触发DOMContentLoaded事件

    • 加载图片等外部文件

    • 触发load事件

    • 下载preload资源(通过标签预加载)

    • 小备注

css相关

  1. 实现0.5px

    • 直接设置(兼容性问题,firefox、safari可以,其他浏览器不可以)

    • transform: scaleY(0.5);transform-origin: 50% 100%;

    • linear-gradient、box-shadow(各自有兼容性问题)

    • svg的描边等属性的1px是物理像素的1px

  2. CSS in JS vs less(scss) vs tailwindCss

    • 原子颗粒写css

    • design system

    • Css的预处理器,提供一些避免重复的功能

    • 变量

    • 嵌套

    • 继承、函数、迭代、条件分支

    • 现在css也可实现,--primary: red; color: var(--primary)

    • 但是预处理器在转换时替代,比起css在运行时替代,预处理器理论上性能更好

    • 但预处理器无法简单的实现在项目运行时动态替代的需求(比如换肤)

    • css计划支持但是遥遥无期

    • 通用组件可用Css in Js

    • emotion

    • Style Components

      1
      2
      3
      4
      5
      constButton = styled.a`
          display: inline-block;
          ${props => props.primary && css`
          background: white; `}
      `
    • 特点:定义global、source-map、提取css文件

    • CSS in JS

    • Less & Scss

    • TailWindCss

  3. 换肤

  4. BFC

    • margin塌陷:把这两个元素各自放在两个BFC中,根据BFC互相独立隔绝可解决问题

    • 计算浮动高度、不覆盖浮动

    • 每一个BFC区域都是独立隔绝的,互不影响

    • 计算BFC高度时,浮动元素也参与计算

    • BFC不会覆盖浮动元素

    • 概念:每一个BFC区域只包括其子元素,不包括其子元素的子元素。

    • 实现:通过设置div根元素、float、position、display: flex、overflow等形成一个BFC

    • 解决问题:

  5. 层叠上下文(z-index)

    • 两个为0的z-index,后一个优先级大

    • https://blog.csdn.net/llll789789/article/details/97562099

    • 普通元素的层叠等级优先由其所在的层叠上下文决定。层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。

    • css3新属性也可以产生层级上下文(偏好文字在上层)

    • 两个兄弟元素,一个设置了background,一个设置了z-index:-1,background优先级低

    • z-index: auto不生成层叠上下文,z-index:0生成为0的层叠上下文

  6. 移动端适配

    • rem和vw方案的区别

    • 使用媒体查询-webkit-min-device-pixel-ratio、scale配合来画

    • svg

    • 1px问题,想要精准画出1px物理像素的边

    • viewport

    • 媒体查询

    • 整体可以是rem、vx为主,px为辅,多用flex和grid

框架相关(主要是React)

  1. concurrent模式

  2. React新生命周期
    react

  3. hook和class对比

    • 写useEffect、useMemo的依赖项比较考验心智

    • 状态不同步,容易产生闭包,需要使用useRef去记录

    • 比如说我们有一个组件,里面的逻辑是屏幕大小一变化,就输出屏幕当前宽高

    • 就可以写一个自定义的hook useWindowSize

    • hook没有生命周期,class有(hook可以使用钩子函数模仿生命周期)

    • hook可以把业务逻辑抽离出来做自定义hook

    • hook缺点

  4. hook为什么不可以在if、switch等循环中

    • 简单来说,hooks就是通过数组实现的,比如当使用setState时,有两个数组去存放state和setState方法

    • 在函数组件重新渲染后,state设为初始值时去数组读取缓存值

    • 所以不能改变hooks顺序,否则读取数组顺序会有误

  5. React和Vue如何选择

    • Vue的更新是数据原子级别,而React是组件级别

    • Vue会对需要追踪的状态,把它们转化为getter和setter进行数据代理,可以更细粒度的去做dom diff和预编译优化,但一旦数据流乱了,很难去从中拦截渲染

    • React则只关心setState,更加粗粒度但是更好控制
      React和Vue如何选择

安全相关

  1. XSS

    • 非富文本场景:进行htmlencode编码操作

    • 富文本场景:dom解析、白名单标签过滤、图片上传内网

    • XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。

    • 场景:

    • 修复:

    1. 用户输入 "/></script><img src='1' onerror=alert(1)><name aa="

    2. 前端渲染用户输入内容时,就会将恶意标签进行渲染

    3. 导致可以执行任何js(构造恶意链接、盗取用户cookie、伪造用户身份去发起删除请求等)

  2. CSRF

    • CSRF(Cross-site Request Forgery)跨站请求伪造,由于目标站无token/referer 限制,导致攻击者可以用户的身份完成操作达到各种目的。

    • 场景:

    • 修复:

    1. 开启框架的CSRF防御机制

    2. 使用token机制

    3. Referer验证

    4. cookie samesite withCredential

    5. 对Referer来源开启白名单机制

    6. 白名单匹配完整主域名

    7. 攻击者构造一个页面,在页面中使用ajax构造一次请求

    8. 用户访问该页面,ajax自动发器请求

    9. 由于是在用户本地浏览器发器的请求,浏览器默认携带用户的cookie信息,请求发起成功

  3. 如何反爬

    • 研究一下大厂怎么做反爬-你可能不知道的反爬虫知识 - 掘金 (juejin.cn)

  4. 跨域

    • CORS 了解一下机制

    • jsonp 可用作打点上报

    • iframe可用onmessage message

    • proxy

构建工具相关

  1. 构建工具对比

    • 【第2258期】新一代构建工具对比 (qq.com)

    • Rollup不支持HMR,在对js以外的模块的支持上不如webpack,但是如果是打包纯js库例如react,前期的vue的话,使用rollup是很合适的,打包的产物比较干净,没有webpack那么多工具函数

    • Rollup 的插件机制设计得相对更干净简洁,单个模块的 resolve / load / transform 跟打包环节完全解耦,所以 Vite 才能在开发时模拟 Rollup 的插件机制,并且兼容大部分 Rollup 插件

    • 现在webpack支持es6module输出并且webpack5能有更好的tree-shaking

    • 在开发应用时使用 Webpack,开发库时使用 Rollup

  2. webpack生命周期

    • 使用配置文件中的参数初始化compiler对象,初始化所有插件

    • 从入口文件出发,调用所有loader对模块进行处理(链式),再找出该模块依赖的模块进行处理

    • 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件加入到输出列表

    • 根据配置确定输出的路径和文件名,写入文件系统

    • 在以上过程中,Webpack会在特定的时间点广播出特定的事件,插件在监听对应的事件后会执行特定的逻辑

    • Webpack以开发模式运行时,每当检测到文件变化,一次新的Compilation被创建。

  3. 是否有写过webpack或者babel插件

    • Webpack原理-编写Plugin - SegmentFault 思否

  4. webpack hmr的原理

    1. 客户端将打包好的代码存储在内存中

    2. 在浏览端和客户端有一个ws长链接

    3. 当文件的真实hash值变化时,客户端会将新的hash值推给浏览器端

    4. 浏览器端向客户端发起请求jsonp请求新的文件

实现题

  1. 实现一个EventEmitter

    • EventEmitter的前端实现 - 知乎 (zhihu.com)

  2. 实现promise

    • 从零开始手写Promise - 知乎 (zhihu.com)

  3. 实现promise.all

    • Promise.all手动实现 - 知乎 (zhihu.com)需要的小伙伴可【点击此处】免费获取