面试时间:2023年2月3日14:00 前端实习
感想:第一次面试,没想到就面了个大厂(非头部大厂),0面试经验也非常紧张,看了一上午面经也没记住多少东西。其实问的问题非常简单,但是计算机基础不会,有一些前端基础也不记得了没答出来(虽然有看八股文但是还是不记得),算法题问的也很简单(但是我可能紧张什么的,只能记得最关键的那条dp代码)。很庆幸没让我写JS的代码。
目录
一、自我介绍
二、介绍项目
三、浏览器输入URL到整个页面加载完成的一个过程
四、浏览器的强缓存和协商缓存(http的缓存方式)
五、ES6新增的Set和Map的用法
六、weakSet和weakMap的了解
七、JS的拖拽功能了解吗
八、CORS实现跨域请求
九、Vue生命周期
十、与路由有关的生命周期是否了解
十一、Vue的diff算法的了解
十二、CommonJS和ES模块化的差异
十三、webpack5了解吗
十四、算法题
十五、反问环节
一、自我介绍
二、介绍项目
随便说了一下项目有什么功能,也没下一步问项目细节
三、浏览器输入URL到整个页面加载完成的一个过程
总体来说分为以下几个过程:
-
DNS解析:查找以查找 IP 地址
-
-
发送HTTP请求:浏览器向 We 服务器发送 HTTP 请求,通信开始(请求响应过程)
-
-
浏览器解析渲染页面
-
四、浏览器的强缓存和协商缓存(http的缓存方式)
总体来说分为以下几个过程:
-
DNS解析:查找以查找 IP 地址
-
发送HTTP请求:浏览器向 We 服务器发送 HTTP 请求,通信开始(请求响应过程)
-
浏览器解析渲染页面
浏览器缓存分为强缓存和协商缓存,当存在缓存时,客户端第一次向服务器请求数据时,客户端会缓存到内存或者硬盘当中,当第二次获取相同的资源,强缓存和协商缓存的应对方式有所不同。
强缓存:当客户端第二次向服务器请求相同的资源时,不会向服务器发送请求,而是直接从内存/硬盘中间读取
协商缓存:当客户端第二次向服务器请求相同的资源时,先向服务器发送请求"询问"该请求的文件缓存在本地与服务器相比是否更改,如果更改,则更新文件,如果没有就从内存/硬盘中读取
五、ES6新增的Set和Map的用法
方法 | 说明 | |
Set | add(value): | 添加某个值,返回 Set 结构本身(可以链式调用)。 |
delete(value): | 删除某个值,删除成功返回true,否则返回false。 | |
has(value): | 返回一个布尔值,表示该值是否为Set的成员。 | |
clear(): | 清除所有成员,没有返回值。 | |
size | 得到当前Set的value个数 | |
Map | set(key, val): | 向Map中添加新元素 |
get(key): | 通过键值查找特定的数值并返回 | |
has(key): | 判断Map对象中是否有Key所对应的值,有返回true,否则返回false | |
delete(key): | 通过键值从Map中移除对应的数据 | |
clear(): | 将这个Map中的所有元素删除 | |
size | 得到当前Map的键值对个数 |
<补充>Set和Map区别
1. Map是键值对,Set是值的集合,当然键和值可以是任何的值;
2. Map可以通过get方法获取值,而set不能因为它只有值;
3. 都能通过迭代器进行for...of遍历;
4. Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储
5. map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关
系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序。
六、weakSet和weakMap的了解
WeakMap
WeakMap
对象的 key 只能是 Object
实例化的对象或者派生类的对象,如果不是的话,则会报错;WeakMap
对象的 value 可以是任意类型
WeakMap与Map的区别是:①不可遍历,②API 基本和 Map对象是一样的,但注意,并没有 size 属性和 clear() 方法
WeakSet
WeakSet
和 WeakMap
基本相同,存放的 value
只能是 Object
实例化的对象或者派生类的对象
与Set的区别:①并且不能迭代, ②没有 clear()
方法、size
属性。
七、JS的拖拽功能了解吗
主要依靠3个事件,分别是onousedown鼠标按下、onmousemove鼠标移动和onmouseup鼠标抬起。
并且它们具体是按照这样的一个顺序执行的:event.clientX和event.clientY分别是鼠标当前的横坐标和纵坐标,offsetX 和 offsetY 分别表示元素的初始横坐标和纵坐标,移动的过程改变的是绝对定位下的left和top值。
八、CORS实现跨域请求
1、CORS需要浏览器和服务器同时支持,才可以实现跨域请求,目前几乎所有浏览器都支持CORS,IE则不能低于IE10。CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。实现CORS的关键在于服务器,只要服务器实现CORS接口,就可以实现跨域通信。
2、CORS分为简单请求和非简单请求(需预检请求)两类
3、对于简单请求,浏览器会直接发送CORS请求,具体说来就是在header中加入origin请求头字段。同样,在响应头中,返回服务器设置的相关CORS头部字段,Access-Control-Allow-Origin字段为允许跨域请求的源。请求时浏览器在请求头的Origin中说明请求的源,服务器收到后发现允许该源跨域请求,则会成功返回
4、当发生符合非简单请求(预检请求)的条件时,浏览器会自动先发送一个options请求,如果发现服务器支持该请求,则会将真正的请求发送到后端,反之,如果浏览器发现服务端并不支持该请求,则会在控制台抛出错误。如果非简单请求(预检请求)发送成功,则会在头部多返回以下字段:
Access-Control-Allow-Origin: http://localhost:3001 该字段表明可供那个源跨域
Access-Control-Allow-Methods: GET, POST, PUT 该字段表明服务端支持的请求方法
Access-Control-Allow-Headers: X-Custom-Header 实际请求将携带的自定义请求首部字段
九、Vue生命周期
系统自带:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
如果加入keep-alive会多两个生命周期:activated deactivated
十、与路由有关的生命周期是否了解
原文链接:https://blog.csdn.net/weixin_43221910/article/details/123228541
1. beforeRouteLeave => 2. beforeEach => 3. beforeRouteUpdate => 4. beforeEnter =>
5. beforeRouteEnter => 6.beforeResolve => 7.afterEach
(组件路由:1,3,5 独享路由:4 全局路由:2,6,7)
路由的钩子函数,根据配置的地方不同,大致分为三种
第一种:全局路由
包含:①全局前置防守:router.beforeEach,(每次路由跳转前的处理,可以用来判断当前用户是否在登录状态,开始进度条等...);② 全局解析守卫:router.beforeResolve,(每次路由跳转完毕的处理,可以用来结束进度条等...);③全局后置防守:router.afterEach,(每次路由跳转完毕的处理,可以用来结束进度条等...)
第二种:独享路由
独享路由防守:beforeEnter (在进入路由时触发)
第三种:组件路由
包含:①组件路由:beforeRouteEnter(在渲染该组件的对应路由被验证前触发);②组件路由:beforeRouteUpdate (在当前路由改变,但是该组件被复用时调用);③组件路由:beforeRouteLeave(在导航离开渲染该组件的对应路由时调用)
十一、Vue的diff算法的了解
1、diff算法是一种通过同层的树节点进行比较的高效算法
2、有2个特点:①比较只会在同层级进行,不会跨层级比较,②在diff比较过程中,循环从两边向中间比较
3、应用场景:在vue中,作用于虚拟dom渲染成真实dom的新旧VNode节点比较
十二、CommonJS和ES模块化的差异
-
为CommonJS的require
语法是同步的,所以就导致了CommonJS模块规范只适合用在服务端,而ES6模块无论是在浏览器端还是服务端都是可以使用的,但是在服务端中,还需要遵循一些特殊的规则才能使用 ;
-
CommonJS 模块输出的是一个值的拷贝,而ES6 模块输出的是值的引用;
-
CommonJS 模块是运行时加载,而ES6 模块是编译时输出接口,使得对JS的模块进行静态分析成为了可能
-
因为两个模块加载机制的不同,所以在对待循环加载的时候,它们会有不同的表现。CommonJS遇到循环依赖的时候,只会输出已经执行的部分,后续的输出或者变化,是不会影响已经输出的变量。而ES6模块相反,使用import
加载一个变量,变量不会被缓存,真正取值的时候就能取到最终的值;
-
关于模块顶层的this
指向问题,在CommonJS顶层,this
指向当前模块;而在ES6模块中,this
指向undefined
;
-
关于两个模块互相引用的问题,在ES6模块当中,是支持加载CommonJS模块的。但是反过来,CommonJS并不能require
ES6模块,在NodeJS中,两种模块方案是分开处理的。
十三、Webpack5了解吗
为CommonJS的require
语法是同步的,所以就导致了CommonJS模块规范只适合用在服务端,而ES6模块无论是在浏览器端还是服务端都是可以使用的,但是在服务端中,还需要遵循一些特殊的规则才能使用 ;
CommonJS 模块输出的是一个值的拷贝,而ES6 模块输出的是值的引用;
CommonJS 模块是运行时加载,而ES6 模块是编译时输出接口,使得对JS的模块进行静态分析成为了可能
因为两个模块加载机制的不同,所以在对待循环加载的时候,它们会有不同的表现。CommonJS遇到循环依赖的时候,只会输出已经执行的部分,后续的输出或者变化,是不会影响已经输出的变量。而ES6模块相反,使用import
加载一个变量,变量不会被缓存,真正取值的时候就能取到最终的值;
关于模块顶层的this
指向问题,在CommonJS顶层,this
指向当前模块;而在ES6模块中,this
指向undefined
;
关于两个模块互相引用的问题,在ES6模块当中,是支持加载CommonJS模块的。但是反过来,CommonJS并不能require
ES6模块,在NodeJS中,两种模块方案是分开处理的。
Webpack 5 超详细解读(一)_webpack5 --config传参_5coder的博客-CSDN博客
十四、算法题
62. 不同路径 - 力扣(LeetCode)
var uniquePaths = function(m, n) {const dp = Array(m).fill().map(item => Array(n)); //创建一个二维数组//初始化向下走for (let i = 0; i < m; i++) {dp[i][0] = 1; }//初始化向右走for (let i = 0; i < n; i++) {dp[0][i] = 1;}for (let i = 1; i<m; i++) {for (let j = 1; j<n; j++) {dp[i][j] = dp[i-1][j] + dp[i][j-1];}}return dp[m-1][n-1];
};
十五、反问环节
1、部门重视的技术:对于实习生,计算机基础,前端基础
2、使用的框架:Vue3
3、公司目前的业务
4、简历看中什么:实习生优先看学历,基本上也是看学历,因为投递的人太多,知道个人做不了什么大项目,筛选学历好的之后查看计算机基础和前端基础
5、多久后才能再次投递简历:半年后,因为简历一旦投递就被锁死了,换个部门投也是一样的