2022前端面试题!已获字节、拼多多等大厂offer(上)
笔者在2021年末到2022年初面了阿里、百度、字节跳动、微软、拼多多、B站等大厂,本身来说是3-5年经验这个范围。可以看到各大厂对前端的基础知识还是非常重视的,因此想对在这些面试中经常会被问到的题目进行总结,这一篇主要是基础题,希望能够帮助各位一起在前端道路上奋斗的小伙伴获得心仪的offer。
js相关(ts)
箭头函数
- 不可用于构造函数,无prototype
- 无法改变this指向
原型链
- 每个对象的
__proto__
指向创建它的构造函数的prototype,而构造函数的prototype也有__proto__
指向他的父辈或者是Object,当查找一个对象中不存在的属性时,会去它的__proto__
、__proto__
中的__proto__
中进行寻找,直到找到或者是null
为止 instanceof
判断对象的__proto__
和构造函数的prototype是不是同一个地址Object.setPrototypeOf
改变对象的__proto__
- 每个对象的
闭包
- 定义:在一个函数A中,定义函数B访问函数A的变量
- 目的:隐藏变量
Map和Object的区别
- Map的key可以为任何值,而Object只能为string
- Map 元素的顺序遵循插入的顺序,而 Object 的则没有这一特性
Weak map
- Weak map的key是弱引用,不会被垃圾回收的计数计算
- 可以用来做反射的元数据池、保存有关DOM节点的数据
实现一个Partial
type MyPartial<T> = {[K in keyof T]?: T[K]};
输出什么
Promise.reject(2) .catch(err=>console.log("err1,",err)) .then(res=>{console.log("then1",res)}) .catch(err=>console.log("err2,",err))
从浏览器输入地址到呈现出网页的过程
查看是否有有效的service worker缓存
判断是否有强缓存,也就是未过期的资源,靠expire和cache-control判断
DNS域名解析
进行三次握手+TLS握手
- TLS握手
- 客户端请求服务端的证书
- 第一次非对称加密,用CA的公钥去解证书的签名,如果解出来的hash和证书信息hash一致则合法
- 第二次非对称加密,客户端使用服务端公钥加密随机数
- 服务端使用服务端私钥解密随机数
- 使用随机数进行对称加密
- TLS握手
向资源发送请求
协商缓存,使用if-modified-since和etag与服务器对比,或没有改变取本地缓存,返回的状态码是304
取回资源
解析网页资源,下载网页中的资源
- html、css、font这三种类型的资源优先级最高
生成dom树和css树,构造render树
重排、重绘、合成
当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。
首次渲染时一定会执行重排,后续如果不改变元素的外形位置尺寸则可以只执行重绘,不执行重排。
重绘得到的像素使用GPU绘制在页面上,一些特殊的element会单独为一个合成层(比如will-change、或者3D转换等),合理使用合成层可以提高动画效果
触发DOMContentLoaded事件
加载图片等外部文件
触发load事件
下载preload资源(通过标签预加载)
小备注
- async script会在script下载完成时立即执行,和构造render树并行
- defer script会在文档渲染完毕后,DOMContentLoaded事件调用前执行
css相关
实现0.5px
- 直接设置(兼容性问题,firefox、safari可以,其他浏览器不可以)
transform: scaleY(0.5);transform-origin: 50% 100%;
linear-gradient
、box-shadow
(各自有兼容性问题)- svg的描边等属性的1px是物理像素的1px
CSS in JS vs less(scss) vs tailwindCss
- CSS in JS
- 通用组件可用Css in Js
- emotion
- 特点:定义global、source-map、提取css文件
- Style Components
const Button = styled.a` display: inline-block; ${props => props.primary && css` background: white; `} `
- Less & Scss
- Css的预处理器,提供一些避免重复的功能
- 变量
- 现在css也可实现,
--primary: red; color: var(--primary)
- 但是预处理器在转换时替代,比起css在运行时替代,预处理器理论上性能更好
- 但预处理器无法简单的实现在项目运行时动态替代的需求(比如换肤)
- 现在css也可实现,
- 嵌套
- css计划支持但是遥遥无期
- 继承、函数、迭代、条件分支
- TailWindCss
- 原子颗粒写css
- design system
- CSS in JS
换肤
BFC
- 概念:每一个BFC区域只包括其子元素,不包括其子元素的子元素。
- 每一个BFC区域都是独立隔绝的,互不影响
- 计算BFC高度时,浮动元素也参与计算
- BFC不会覆盖浮动元素
- 实现:通过设置body根元素、float、position、display: flex、overflow等形成一个BFC
- 解决问题:
- margin塌陷:把这两个元素各自放在两个BFC中,根据BFC互相独立隔绝可解决问题
- 计算浮动高度、不覆盖浮动
- 概念:每一个BFC区域只包括其子元素,不包括其子元素的子元素。
层叠上下文(z-index)
- https://blog.csdn.net/llll789789/article/details/97562099
- 普通元素的层叠等级优先由其所在的层叠上下文决定。层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
- css3新属性也可以产生层级上下文(偏好文字在上层)
- 两个兄弟元素,一个设置了background,一个设置了z-index:-1,background优先级低
- z-index: auto不生成层叠上下文,z-index:0生成为0的层叠上下文
- 两个为0的z-index,后一个优先级大
移动端适配
- 1px问题,想要精准画出1px物理像素的边
- 使用媒体查询-webkit-min-device-pixel-ratio、scale配合来画
- svg
- viewport
- 媒体查询
- 整体可以是rem、vx为主,px为辅,多用flex和grid
- rem和vw方案的区别
- 1px问题,想要精准画出1px物理像素的边
框架相关(主要是React)
concurrent模式
React新生命周期
hook和class对比
- hook没有生命周期,class有(hook可以使用钩子函数模仿生命周期)
- hook可以把业务逻辑抽离出来做自定义hook
- 比如说我们有一个组件,里面的逻辑是屏幕大小一变化,就输出屏幕当前宽高
- 就可以写一个自定义的hook useWindowSize
- hook缺点
- 写
useEffect
、useMemo
的依赖项比较考验心智 - 状态不同步,容易产生闭包,需要使用useRef去记录
- 写
hook为什么不可以在if、switch等循环中
- 简单来说,hooks就是通过数组实现的,比如当使用setState时,有两个数组去存放state和setState方法
- 在函数组件重新渲染后,state设为初始值时去数组读取缓存值
- 所以不能改变hooks顺序,否则读取数组顺序会有误
React和Vue如何选择
- Vue的更新是数据原子级别,而React是组件级别
- Vue会对需要追踪的状态,把它们转化为getter和setter进行数据代理,可以更细粒度的去做dom diff和预编译优化,但一旦数据流乱了,很难去从中拦截渲染
- React则只关心setState,更加粗粒度但是更好控制
安全相关
- XSS
- XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
- 场景:
- 用户输入
"/></script><img src='1' onerror=alert(1)><name aa="
- 前端渲染用户输入内容时,就会将恶意标签进行渲染
- 导致可以执行任何js(构造恶意链接、盗取用户cookie、伪造用户身份去发起删除请求等)
- 用户输入
- 修复:
- 非富文本场景:进行htmlencode编码操作
- 富文本场景:dom解析、白名单标签过滤、图片上传内网
- CSRF
- CSRF(Cross-site Request Forgery)跨站请求伪造,由于目标站无token/referer 限制,导致攻击者可以用户的身份完成操作达到各种目的。
- 场景:
- 攻击者构造一个页面,在页面中使用ajax构造一次请求
- 用户访问该页面,ajax自动发器请求
- 由于是在用户本地浏览器发器的请求,浏览器默认携带用户的cookie信息,请求发起成功
- 修复:
- 开启框架的CSRF防御机制
- 使用token机制
- Referer验证
- 对Referer来源开启白名单机制
- 白名单匹配完整主域名
- cookie samesite withCredential
- 如何反爬
- 跨域
- CORS 了解一下机制
- jsonp 可用作打点上报
- iframe可用onmessage message
- proxy
构建工具相关
构建工具对比
- 【第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
webpack生命周期
- 使用配置文件中的参数初始化compiler对象,初始化所有插件
- 从入口文件出发,调用所有loader对模块进行处理(链式),再找出该模块依赖的模块进行处理
- 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件加入到输出列表
- 根据配置确定输出的路径和文件名,写入文件系统
- 在以上过程中,Webpack会在特定的时间点广播出特定的事件,插件在监听对应的事件后会执行特定的逻辑
- Webpack以开发模式运行时,每当检测到文件变化,一次新的Compilation被创建。
是否有写过webpack或者babel插件
webpack hmr的原理
超简版:
- 客户端将打包好的代码存储在内存中
- 在浏览端和客户端有一个ws长链接
- 当文件的真实hash值变化时,客户端会将新的hash值推给浏览器端
- 浏览器端向客户端发起请求jsonp请求新的文件
实现题
- 实现一个EventEmitter
- 实现promise
- 实现promise.all