疫情期间,一个前端妹子的面试小记(含答案),前端开发目录

this变量引用该对象,同时还继承了这个函数的原型

属性和方法被加入到引用的对象里

新创建的对象由this引用,最后隐式返回this

浏览器事件循环和node事件循环
浏览器事件循环:

同步任务在主线程执行,在主线程外还有个任务队列用于存放异步任务

主线程的同步任务执行完毕,异步任务入栈,进入主线程执行

上述的两个步骤循环,形成eventloop事件循环 浏览器的事件循环又跟宏任务和微任务有关,两者都属于异步任务。

js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入任务队列,再执行微任务,将微任务放入任务队列,他俩进入的不是同一个任务队列。往外读取的时候先从微任务里拿这个回调函数,然后再从宏任务的任务队列上拿宏任务的回调函数

宏任务:

script

定时器 setTimeout setInterval setImmediate

微任务:

promise

process.nextTick()

MutationObserver

node事件循环:

timer阶段

I/O 异常回调阶段

空闲预备阶段

poll阶段

check阶段

关闭事件的回调阶段

  • 手写系列
    远程面试没考手写,但我觉得还是要会

  • 手写promise
    我的是简易版本

function myPromise(executor) {
let self=this;
self.status=‘pending’;
self.value=undefined;
self.reason=undefined;

function resolve(value) {
if(self.status===‘pending’){
self.value=value
self.status=“resolved”
}
}
function reject(reason) {
if(self.status===‘pending’){
self.reason=reason
self.status=status
}
}
try{
executor(resolve,reject)
}
catch (e) {
reject(e)
}
}

手写bind
Function.prototype.myBind=function(context,…args){
const fn=this
args=args?args:[]
return function newFn(…newFnArgs) {
if(this instanceof newFn){
return new fn(…args,…newFnArgs)
}
return fn.apply(context,[…args,…newFnArgs])
}
}

手写call、apply
Function.prototype.myCall=function(context,…args){
context=context||window
args=args?args:[]
const key=Symbol()
context[key]=this
const result=contextkey//通过隐式绑定的方式调用函数
delete context[key]//删除添加的属性
return result//返回函数调用的返回值
}

Function.prototype.myApply=function(context,args){
context=context||window
args=args||[]
const key=Symbol()
context[key]=this
const result=contextkey
delete context[key]
return result
}

  • vue部分
    vue的双向绑定原理
    vue的双向绑定是通过数据劫持和发布者-订阅者模式实现的,数据劫持又是通过Object.defineProperty()实现的

Object.defineProperty(data,‘a’,{
enumerable:true,//是否可枚举
writable:true,//是否可写
configurable:true,//是否可配置
get(){
return this.a//读取data对象的a属性时,触发get方法
},
set(val){
this.a=val;//修改data对象的a属性时,触发set方法
}
})

mvvm的数据变化更新视图,是通过Object.defineProperty()实现的;视图更新变化数据,是通过事件监听实现的。

发布者-订阅者的实现过程:

  1. 实现一个监听器Observer,劫持并监听所有属性,如果有变化,就通知订阅者
  2. 实现一个订阅者Watcher,收到属性的变化通知并执行响应的函数,从而更新视图
  3. 实现一个解析器Compiler,可以扫描并解析每个节点的相关指令,初始化模板数据和对应的订阅器

vue的指令有哪些
v-if 用于条件渲染
v-show 用于条件渲染,两者的区别请参考下一个问题
v-for 用于列表渲染
v-on 监听事件
v-bind 动态绑定
v-html 渲染html元素
v-model 数据双向绑定

v-if和v-show区别
v-if 是惰性的,只有条件为真时才会切换,为假时什么也不做。确保切换过程中的事件监听器和子组件适当的被销毁和重建,适用于运行条件很少改变的场景。v-show 不管条件是否为真,总是会被渲染,适用于频繁切换的场景

v-for和v-if为什么不能放于同一级
v-for优先级高于v-if,放于同级可能会重复渲染两次v-if,建议把v-for放于v-if所在的外层元素

nextTick
原理:eventloop事件循环

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

v-for中key的原理
key 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。不指定key时,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试
就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。

vue的生命周期
1.beforeCreate
初始化界面前
2.created
初始化界面后,拿到data,props,methods、computed和watch
3.beforeMount
渲染dom前
4.mounted
渲染dom后,拿到$el
5.beforeUpdate
更新前
6.updated
更新后,拿到更新后的dom
7.beforeDestroy
卸载组件前
8.destroyed
卸载组件后
9.activated
被 keep-alive 缓存的组件激活时调用
10.deactivated
被 keep-alive 缓存的组件停用时调用
11. errorCaptured
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例
以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

父子组件通信
父传子:prop

子传父:$emit

父子通信:

  • eventbus
  • vuex
  • ref结合$parent或 $children

跨层级较多:provide/inject

computed和watch区别
computed用于计算属性,只有它依赖的值改变才会触发,且这个值有缓存

watch用于监听一个属性的变化,属性变化就会触发

vnode的diff算法原理
虚拟dom是对真实dom的一种映射,新旧Vnode比较同层级的节点,然后根据两者的差异只更新有差异的部分,生成新的视图,而不是对树进行逐层搜素遍历,因此时间复杂度是O(n)。虚拟dom可以减少页面的回流和重绘,提升性能

webpack相关
webpack运行流程
分为初始化、编译、输出三个阶段.

  • 初始化:

从配置文件和shell文件读取、合并参数;

加载plugin

实例化compiler

  • 编译

从entry发出,针对每个module串行调用对应loader翻译文件内容

找到module依赖的module,递归进行编译处理

  • 输出:

把编译后module组合成chunk

把chunk转换成文件,输出到文件系统

  • webpack性能优化
    优化可以从两个方面考虑,一个是优化开发体验,一个是优化输出质量。

  • 优化开发体验

缩小文件搜索范围。涉及到webpack如何处理导入文件,不再赘述,不会的可以自行搜索。由于loader对文件转换操作很耗时,应该尽量减少loader处理的文件,可以使用include命中需要处理的文件,缩小命中范围。

使用DllPlugin,提升构建速度

使用happyPack开启多线程

使用UglifyJs压缩代码(只支持es5),uglifyes支持es6,两个插件不能同时开启。使用ParalellUgifyPlugin开启多个子进程压缩,既支持UglifyJs又支持uglifyes

使用自动刷新:监听到代码改变后,自动编译构建可运行代码并刷新页面

开启模块热替换:在不刷新网页的同时实现实时预览

优化输出质量减少首屏加载时间

区分环境

压缩代码

CDN加速

使用Tree shaking

提取公共代码

按需加载

提升流畅度,即代码性能:

使用PrePack优化代码运行时的效率

开启Scope Hoisting,让webpack打包出来的代码更小、运行更快

  • loader的原理
    loader能把源文件翻译成新的结果,一个文件可以链式经过多个loader编译。以处理scss文件为例:

sass-loader把scss转成css

css-loader找出css中的依赖,压缩资源

style-loader把css转换成脚本加载的JavaScript代码

plugin原理
plugin用于扩展webpack功能。

webpack启动后,在读取配置时会先执行new BasicPlugin(options)初始化一个BasicPlugin获得它的实例

调用BasicPlugin.apply(compiler)给插件实例传递compiler对象

插件实例获取compiler对象后,通过compiler.plugin(事件名,回调函数)监听webpack广播出的事例

http相关
url从输入到输出的过程1. 构建请求
构建请求行,请求行包括请求方法、请求http版本、URI
Get/Http/1.0
2. 查找强缓存
检查强缓存,命中则直接使用,否则检查协商缓存
3. DNS解析
域名与IP地址映射
4.建立tcp连接
chrome限制同一域名下最多6个tcp连接

  • 通过三次握手建立连接
    三次握手过程:
    1.客户端向服务器发送连接请求,传递一个数据包syn,此时客户端处于SYN_SEND状态
    2.服务器接收syn报文后,会以自己的syn报文作为应答,传递数据包syn+ack,此时服务器处于SYN-REVD状态
    3.客户端接收syn报文后,发送一个数据包ack,此时客户端处于ESTABLISHED状态,双方已建立连接
  • 进行数据传输
  • 通过四次挥手断开连接
    四次挥手过程:
  1. 客户端发送一个FIN报文,报文中指定一个序列号,此时客户端处于FIN_WAIT1状态,等待服务器确认
  2. 服务器接收到FIN后,会发送ACK确认报文,表明已经收到客户端报文,此时服务端处于CLOSE_WAIT2状态
  3. 服务器发送FIN,告诉客户端想断开连接,此时服务端处于LAST_CHECK阶段
  4. 客户端收到FIN后,一样发送一个ACK作为应答,此时客户端处于TIME_WAIT阶段。需要过一段时间确认服务端收到自己的ACK报文
    后才会进入CLOSED状态
    5.发送http请求
    6.网络响应
    7.浏览器解析和渲染
    分为构建dom树、样式计算、生成布局树。
    8.生成布局
    触发回流和重绘

介绍下半连接队列
服务器第一次接收到客户端的SYN后,会处于SYN-REVD阶段,此时双方还没有建立完全的连接,
服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称为半连接队列

已经完成三次握手并建立连接,就叫全连接队列

http和https区别
http基于TCP/IP协议,https基于SSL/TLS协议

http默认端口号为80,https默认端口号为443

https安全性更强,需要CA证书

https可以防止运营商劫持

可以介绍https的通信过程,涉及对称加密和非对称加密

tcp和udp区别
tcp只能一对一通信,udp可以一对一、一对多、多对多通信,即支持多播和广播

tcp首部开销消耗32字节,udp仅消耗8个字节

tcp适合对数据安全性要求高的场景,比如文件传输,udp适合对数据实时性要求高的场景,比如视频通话、语音通话

tcp是有状态连接,udp是无状态的连接

tcp-可靠传输 udp-不可靠传输

tcp-面向字节流 udp-面向报文

tcp怎么保证可靠性

  1. 超时重传机制
  2. 对失序数据进行重排序
  3. 应答机制
  4. 滑动窗口
  5. 拥塞控制

http请求有哪几种
http1.0:get、post、head

http1.1:put、delete、connect、trace、options

简单请求:

请求method只能是get、post、head

请求头只能是accept/accept-language/content-language/content-Type

content-Type只能是text/plain、multipart/form-data、application/x-www-form-urlencoded

介绍http1.0|http1.1|http2.0
http1.0:

完成连接即断开,导致重新慢启动和三次握手

线头阻塞,导致请求间相互影响

http1.1:

用keep-alive支持长连接

用host字段指定对应的虚拟站点

新增功能: 断点续传、身份认证、状态管理、cache缓存->cache-control、expires、last-modified、etag

http2.0:

二进制分帧层:应用层和传输层

header头部压缩

服务端推送

多路复用

二进制分帧层可以扩展到计算机网络的OSI参考模型

客户端缓存
客户端缓存分为cookie、localStorage、sessionStorage、indexedDB,网上有关的文章很多,就不详细说了

浏览器缓存
强缓存

不向http发送请求,返回状态码304.

检查强缓存有两个字段: http1.0使用expires,代表过期时间,但是服务器时间和客户端时间可能不一致。为了弥补这个缺点,http1.1使用cache-control的max-age字段,cache-control有多个指令

public 允许客户端和代理服务器缓存

private 允许客户端缓存

no-store 不使用缓存

no-cache 使用协商缓存 两个字段都存在,cache-control优先级高于expires

协商缓存向http发送请求,返回状态码200

检查协商缓存有两个字段: http1.0使用last-modified,即最后修改时间。

在浏览器向服务器发送请求后,服务器会在响应头上加上这个字段

浏览器接收后,如果再次请求,会在请求头上携带If-Modified-Since

服务器拿到If-Modified-Since字段后,会和服务器中该资源的最后修改时间对比,如果请求头中这个值小于最后修改时间,更新资源;否则返回304,告诉浏览器直接使用缓存

http1.1使用etag,etag是服务器根据当前文件内容,给文件生成的唯一标识,只要内容改变,这个值就会变。etag优先级高于last-modifed

缓存位置,按优先级从高到低分别是:

service worker

memory cache

disk cache

push cache

http状态码
列举一些常见状态码即可

200-请求成功
301-永久重定向
302和307-临时重定向
400-当前请求不能被服务器理解或请求参数有误
401-请求需要认证或认证失败
403-服务器禁止访问
404-资源未找到
405-方法未允许
500-内部服务器错误
502-网关错误
503-服务器处于超负载或停机维护

了解nginx吗
ngnix是个高性能反向代理服务器,有以下作用:

解决跨域

请求过滤

配置gzip

负载均衡

静态资源服务器

ngnix解决跨域的原理:

把后端域名设为前端服务的域名,然后设置相应的location拦截前端需要跨域的请求,最后将请求代理回服务端的域名

ngnix实现负载均衡的策略:轮询、最小链接数、最快响应时间

web安全
xss
跨站脚本攻击,指攻击者在网页上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时, 对客户端浏览器进行控制或获取用户隐私数据的方式

防范:

httpOnly防止截取cookie

用户输入检查

用户输出检查

利用CSP(浏览器的内容安全策略)

csrf
跨站请求伪造,劫持受信任用户向服务器发送非预期请求的方式。

防范:

验证码

referer check

增加token验证

二次封装axios
1.新建一个axios对象,定义好字段并设置默认值,比如超时时间、请求头
2.定义过滤字符串方法,过滤服务端为空字符串或null的属性
3.请求拦截器调用过滤字符串方法,遍历url上的字段,如果为数组或对象转为JSON对象
4.响应拦截器捕获错误,根据http状态码进行不同的处理,比如401跳转登陆页面,403返回您没有权限,502返回系统正在升级中,请稍后重试,
504返回系统超时,并弹出对应的消息提示框。消息提示框自定义

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

总结一下

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-JtL4D5iL-1712786288283)]

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值