笔者在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
1type MyPartial<T> = {[K inkeyof T]?: T[K]}; -
输出什么
1234Promise.reject(2).catch(err=>console.log("err1,",err)).then(res=>{console.log("then1",res)}).catch(err=>console.log("err2,",err)) -
从浏览器输入地址到呈现出网页的过程
-
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相关
-
实现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
-
design system
-
Css的预处理器,提供一些避免重复的功能
-
变量
-
嵌套
-
继承、函数、迭代、条件分支
-
现在css也可实现,--primary: red; color: var(--primary)
-
但是预处理器在转换时替代,比起css在运行时替代,预处理器理论上性能更好
-
但预处理器无法简单的实现在项目运行时动态替代的需求(比如换肤)
-
css计划支持但是遥遥无期
-
通用组件可用Css in Js
-
emotion
-
Style Components
12345constButton = styled.a`display: inline-block;${props => props.primary && css`background: white; `}` -
特点:定义global、source-map、提取css文件
-
CSS in JS
-
Less & Scss
-
TailWindCss
-
换肤
-
BFC
-
margin塌陷:把这两个元素各自放在两个BFC中,根据BFC互相独立隔绝可解决问题
-
计算浮动高度、不覆盖浮动
-
每一个BFC区域都是独立隔绝的,互不影响
-
计算BFC高度时,浮动元素也参与计算
-
BFC不会覆盖浮动元素
-
概念:每一个BFC区域只包括其子元素,不包括其子元素的子元素。
-
实现:通过设置div根元素、float、position、display: flex、overflow等形成一个BFC
-
解决问题:
-
层叠上下文(z-index)
-
两个为0的z-index,后一个优先级大
-
普通元素的层叠等级优先由其所在的层叠上下文决定。层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
-
css3新属性也可以产生层级上下文(偏好文字在上层)
-
两个兄弟元素,一个设置了background,一个设置了z-index:-1,background优先级低
-
z-index: auto不生成层叠上下文,z-index:0生成为0的层叠上下文
-
移动端适配
-
rem和vw方案的区别
-
使用媒体查询-webkit-min-device-pixel-ratio、scale配合来画
-
svg
-
1px问题,想要精准画出1px物理像素的边
-
viewport
-
媒体查询
-
整体可以是rem、vx为主,px为辅,多用flex和grid
框架相关(主要是React)
-
concurrent模式
-
React新生命周期
-
hook和class对比
-
写useEffect、useMemo的依赖项比较考验心智
-
状态不同步,容易产生闭包,需要使用useRef去记录
-
比如说我们有一个组件,里面的逻辑是屏幕大小一变化,就输出屏幕当前宽高
-
就可以写一个自定义的hook useWindowSize
-
hook没有生命周期,class有(hook可以使用钩子函数模仿生命周期)
-
hook可以把业务逻辑抽离出来做自定义hook
-
hook缺点
-
hook为什么不可以在if、switch等循环中
-
简单来说,hooks就是通过数组实现的,比如当使用setState时,有两个数组去存放state和setState方法
-
在函数组件重新渲染后,state设为初始值时去数组读取缓存值
-
所以不能改变hooks顺序,否则读取数组顺序会有误
-
React和Vue如何选择
-
Vue的更新是数据原子级别,而React是组件级别
-
Vue会对需要追踪的状态,把它们转化为getter和setter进行数据代理,可以更细粒度的去做dom diff和预编译优化,但一旦数据流乱了,很难去从中拦截渲染
-
React则只关心setState,更加粗粒度但是更好控制
安全相关
-
XSS
-
非富文本场景:进行htmlencode编码操作
-
富文本场景:dom解析、白名单标签过滤、图片上传内网
-
XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
-
场景:
-
修复:
-
用户输入 "/></script><img src='1' onerror=alert(1)><name aa="
-
前端渲染用户输入内容时,就会将恶意标签进行渲染
-
导致可以执行任何js(构造恶意链接、盗取用户cookie、伪造用户身份去发起删除请求等)
-
CSRF
-
CSRF(Cross-site Request Forgery)跨站请求伪造,由于目标站无token/referer 限制,导致攻击者可以用户的身份完成操作达到各种目的。
-
场景:
-
修复:
-
开启框架的CSRF防御机制
-
使用token机制
-
Referer验证
-
cookie samesite withCredential
-
对Referer来源开启白名单机制
-
白名单匹配完整主域名
-
攻击者构造一个页面,在页面中使用ajax构造一次请求
-
用户访问该页面,ajax自动发器请求
-
由于是在用户本地浏览器发器的请求,浏览器默认携带用户的cookie信息,请求发起成功
-
如何反爬
-
研究一下大厂怎么做反爬-你可能不知道的反爬虫知识 - 掘金 (juejin.cn)
-
跨域
-
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原理-编写Plugin - SegmentFault 思否
-
webpack hmr的原理
-
客户端将打包好的代码存储在内存中
-
在浏览端和客户端有一个ws长链接
-
当文件的真实hash值变化时,客户端会将新的hash值推给浏览器端
-
浏览器端向客户端发起请求jsonp请求新的文件
实现题
-
实现一个EventEmitter
-
EventEmitter的前端实现 - 知乎 (zhihu.com)
-
实现promise
-
从零开始手写Promise - 知乎 (zhihu.com)
-
实现promise.all
-
Promise.all手动实现 - 知乎 (zhihu.com)需要的小伙伴可【点击此处】免费获取