前言
首先介绍一下情况,江西双非一本,非科班,一段前端实习经验。
面百度之前有三个offer,不过都是小厂和中厂,百度这次约面试算是接到的第一个大厂面试,属于百度网盘部门。
- 2月18号投简历
- 2月26号百度一面(已过)
- 2月29号百度二面(等结果)
约到面试之后,从26号到29号这几天基本上在看手写题和算法。提前和hr沟通了下,说是一共两轮技术面,另外有个hr面(不会刷人)。
一面
-
时长:70min+
-
开场个人介绍:校园经历 + 实习经历 + 项目实践 + 熟悉的技术栈
-
概括一下面试题
1. 讲讲JS的基本数据类型
JavaScript有七种基本数据类型:
-
Undefined(未定义):表示未定义或未初始化的值。
-
Null(空):表示空值或者没有对象。
-
Boolean(布尔值):表示true或false。
-
Number(数字):表示整数或浮点数(例如:42或3.14159)。
-
String(字符串):表示文本数据(例如:"Hello, World!")。
-
Symbol:表示唯一的、不可变的值,通常用于对象属性。
-
BigInt:表示任意精度的整数,可以表示更大范围的整数值。
以下是面试官继续问的内容:
Symbol和BigInt的特点和用途
-
Symbol:
- 特点:
Symbol
是一种原始数据类型,表示独一无二的值。每个通过Symbol
函数创建的Symbol
值都是唯一的,即使它们的描述相同也是如此。 - 用途:主要用于创建对象的唯一属性键,防止属性名冲突。
Symbol
在定义对象的私有属性或方法时特别有用,因为它们不会被意外访问或覆盖。
- 特点:
-
BigInt:
- 特点:
BigInt
是一种用来表示任意精度的整数的数据类型。它可以表示比Number
类型更大的整数值,但不能使用BigInt
来执行与Number
类型相关的操作,比如混合使用BigInt
和Number
进行算术运算会导致错误。 - 用途:主要用于需要处理非常大整数的情况,例如在加密算法、大型数值计算或与硬件相关的编程中。
- 特点:
如何判断引用类型的数据是对象还是数组
Array.isArray()
方法instanceof
操作符Object.prototype.toString.call()
方法
遍历对象的方法和遍历数组的方法分别说五个
遍历对象的方法有:
- for...in 循环
- Object.keys() 方法配合 forEach()、map() 等方法
- Object.getOwnPropertyNames() 方法配合 forEach()、map() 等方法
- Object.entries() 方法配合 forEach()、map() 等方法
- 使用 JSON.stringify() 将对象转换为字符串后遍历
遍历数组的方法有:
- for 循环
- forEach() 方法
- map() 方法
- filter() 方法
- reduce() 方法
- some() 方法
- every() 方法
- for...of 循环
2. 讲讲Promise
Promise 是处理异步操作的一种方式。一个 Promise 对象有三种状态:Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。当一个 Promise 对象处于 Pending 状态时,可以改变为 Fulfilled 或 Rejected 状态,一旦状态改变就不会再变。
Promise 有两个重要的方法:then() 和 catch()。then() 方法用于处理 Promise 对象的成功和失败状态,catch() 方法用于捕获错误。
通过 Promise 构造函数,可以创建一个新的 Promise 对象。Promise 构造函数接受一个带有 resolve 和 reject 两个参数的函数作为参数。在这个函数中,如果异步操作成功,则调用 resolve,并将结果作为参数传递给 then() 方法;如果异步操作失败,则调用 reject,并将错误作为参数传递给 catch() 方法。
以下是面试官继续问的内容:
Promise的方法你了解多少
-
then():then() 方法用于处理 Promise 对象的成功和失败状态。它接受两个参数:第一个参数是处理成功状态的回调函数,第二个参数是处理失败状态的回调函数。then() 方法返回一个新的 Promise 对象,可以实现链式调用。
-
catch():catch() 方法用于捕获 Promise 对象的错误状态。它接受一个参数,即处理失败状态的回调函数。catch() 方法也返回一个新的 Promise 对象,可以用于链式调用。
-
finally():finally() 方法用于在 Promise 对象结束时无论成功还是失败都执行指定的回调函数。它接受一个回调函数作为参数,这个回调函数不接受任何参数。finally() 方法返回一个新的 Promise 对象,可以用于链式调用。
-
Promise.resolve():Promise.resolve() 方法返回一个已经处于成功状态的 Promise 对象,可以指定一个值作为成功状态的结果。
-
Promise.reject():Promise.reject() 方法返回一个已经处于失败状态的 Promise 对象,可以指定一个错误作为失败状态的原因。
-
Promise.all():Promise.all() 方法接受一个可迭代对象(通常是数组)作为参数,返回一个新的 Promise 对象。这个新的 Promise 对象在可迭代对象中所有的 Promise 对象都成功时才会成功,一旦有一个 Promise 对象失败就会立即失败。
-
Promise.race():Promise.race() 方法接受一个可迭代对象作为参数,返回一个新的 Promise 对象。这个新的 Promise 对象在可迭代对象中有任意一个 Promise 对象状态发生改变时就会改变,状态的值和改变的 Promise 对象相同。
3. 前端缓存的了解
讲了一下浏览器缓存和服务器缓存,面试官继续问:
你了解强缓存和协商缓存吗
localStorage、sessionStorage还有cookie有什么区别
前端缓存可以分为两种类型:浏览器缓存和 Web Storage。
-
浏览器缓存:浏览器缓存是指浏览器在本地保存一些静态资源的副本,以便在下次访问相同资源时可以直接从本地获取,而不需要再次从服务器下载。浏览器缓存主要包括以下几种类型:
-
强缓存:浏览器在请求资源时,会先检查该资源的缓存标识(如 Cache-Control 和 Expires),如果命中强缓存,则直接从缓存中获取资源,不会发送请求到服务器。
-
协商缓存:如果资源的缓存标识表示资源已经过期(如 Cache-Control 中的 max-age 或者 Last-Modified 和 ETag 等),浏览器会发送请求到服务器,服务器会根据请求头中的条件判断来决定是否返回资源内容,如果返回 304 状态码表示资源未发生改变,浏览器可以使用缓存中的资源。
-
-
Web Storage:Web Storage 是 HTML5 提供的一种浏览器本地存储数据的方式,主要包括 localStorage 和 sessionStorage 两种。它们可以存储在浏览器中供网站使用,可以在页面会话结束后依然保留(localStorage),或者在页面会话结束后被清除(sessionStorage)。
-
localStorage:localStorage 存储的数据没有过期时间,除非手动清除,否则会一直保存在浏览器中。
-
sessionStorage:sessionStorage 存储的数据在页面会话结束时被清除,即当页面被关闭时数据也会被清除。
-
4. 浏览器中的事件循环和node.js里的事件循环
这个之前的文章写过,可以去年前的这篇面筋里看看。
5. 讲讲js闭包的了解,包括其定义和适用场景
闭包是指在一个函数内部定义的函数可以访问该函数的作用域,即使在该函数外部调用该内部函数时也可以访问。换句话说,闭包就是函数和其相关的引用环境的组合。在 JavaScript 中,由于函数可以作为值返回,因此函数可以嵌套定义,形成闭包。
以下是面试官继续问的内容:
闭包可能导致内存泄露,如何规避这个问题
- 避免不必要的引用:在编写闭包时,尽量避免将外部函数作用域中不再需要的变量引入闭包中。如果一个变量在闭包中没有被使用,那么就不要将其引入闭包。
- 手动释放引用:在不再需要使用闭包时,可以手动将闭包引用的变量设置为 null,这样可以告诉垃圾回收器可以回收这些变量。
- 使用匿名自执行函数:有时候可以使用匿名自执行函数来代替显式的闭包,因为匿名自执行函数在执行完毕后,其内部的变量会被立即释放,不会造成内存泄露。
- 使用 WeakMap 或 WeakSet:如果闭包中需要引用外部对象,可以考虑使用 WeakMap 或 WeakSet 来存储这些引用,因为 WeakMap 和 WeakSet 中的键是弱引用,当其他地方不再引用这些对象时,这些对象会被垃圾回收器回收,从而避免内存泄露。
- 注意循环引用:避免在闭包中创建循环引用,即闭包引用外部对象,而外部对象也引用闭包,这样会导致这些对象无法被垃圾回收器回收。
6. 讲讲跨域以及解决办法
我提到WebSocket协议,所以面试官让我讲讲WebSocket协议,根据这个问到了很多问题,包括性能问题、解决方案、连接数量限制等,这里草草回答几句就没下文了,所以uu们要回答这一点的话记得去了解一下。
常见的跨域解决办法:
-
JSONP:通过动态创建
<script>
标签,利用<script>
标签的跨域特性来实现跨域请求。 -
CORS(跨域资源共享):在服务端设置响应头部信息,允许指定源的请求访问资源,常用的响应头部信息包括 Access-Control-Allow-Origin、Access-Control-Allow-Methods 等。
-
代理:在同源的服务器上设置一个代理服务器,由代理服务器转发请求,从而绕过浏览器的跨域限制。
-
WebSocket:WebSocket 是一种双向通信协议,可以在不受同源策略限制的情况下进行跨域通信。
-
Nginx 反向代理:通过 Nginx 配置反向代理,将请求转发到目标服务器,从而绕过浏览器的跨域限制。
-
跨文档消息传递(Cross-document Messaging):使用
window.postMessage()
方法在不同窗口之间传递消息,实现跨域通信。 -
利用iframe的src属性:可以使用iframe的src属性加载跨域的页面,然后通过postMessage方法进行通信。
-
跨域资源嵌入:将跨域资源嵌入到页面中,例如使用
<img>
标签的 src 属性、<link>
标签的 href 属性或者<script>
标签的 src 属性加载跨域资源。
7. 浏览器渲染原理
以前写过,可以看这一篇。
😎😎(超详细)从输入url到渲染页面发生了什么,你真的知道吗
以下是面试官继续问的内容:
如何减少重排
8. 讲讲html语义化和好处
举几个html语义化标签的例子。
9. 浏览器对最小字号的限制
通常情况下,浏览器的最小字号限制是 12px 或者 16px,不同浏览器可能会有所不同。
以下是面试官继续问的内容:
要实现比这个限制还要小的字体要怎么做
css里的transform属性缩放
10. css中的垂直水平居中的方式有几种
11. 怎么做移动端适配
12. Node.js的特点你知道多少
13. 关于Node.js多进程的限制以及父子进程之间的通信方式。
14. PM2、koa框架、中间件、JWT鉴权
这几个了解吗,分别讲讲
15. Vue2升级到Vue3,你觉得有哪些变化
另外,面试官详细的问了对于vue2和vue3响应式原理的理解。
16. 父组件怎么调用子组件的方法(并非组件传值)
结语
最后聊天环节面试官说本来准备了算法题,但是问的太久了(到结束大概1个小时20分钟),就没给我写。