阅读 12151

一年经验前端 杭州几家二线厂面试题梳理

交代下背景

在掘金群比较活跃的群友应该都认识我,我就是那个每天吹水的管理员,最近赶上秋招之际,毕业刚满一年,就打算试下杭州的几家厂,因为本身也是二线厂出身,所以投的也都是二线厂以上,拿到的offer也还ok,现在还是找工作的状态,如果有杭、沪有理想有技术氛围不修福报当然福利待遇不能太差的团队可以联系我,P5等级。 下面是我遇到的面试题汇总,由于问题实在太多了,只简述思路和答案。

面试问题总结

http方面

现在发现越来越多的公司喜欢问前端http的基础,我觉得无可厚非,前端人员本身就要了解很杂的东西,http跟我们的性能优化息息相关。

描述网页从输入url到渲染的过程

1.首先获取url 解析出ip地址 如果本地hosts中有配置优先取出配置  若没有则进行dns解析
2.tcp 三次挥手 建立连接
3.客户端发送http请求
4.服务器处理请求并响应
5.浏览器处理资源文件进行渲染
6.tcp的四次挥手
复制代码

简述三次握手和四次挥手

下面符号的含义 SYN(联机) ACK(确认) FIN(结束)

三次握手

第一次握手:客户端采用TCP协议将带有SYN标志的数据包发送给服务器,等待服务器的确认。

第二次握手:服务器端在收到SYN的数据包后,必须确认SYN,并发送的ACK标志,同时,自己也将会向客户端发送一个SYN标志。

第三次握手:客户端在接收到服务器段的SYN+ACK包后,自己会向服务器发送ACK包,完成三次握手。那么客户端和服务器正式建立了连接,开始传输数据。
复制代码

四次挥手

1. 当客户端的数据传输到尾部时,客户端向服务器发送带有FIN标志的数据包,使其明白自己准备断开通信了。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2. 因为TCP的通信是使用全双工通信的,所以在断开连接的时候也应该是双向的;当服务器收到带有FIN标志的数据包时,
   其必不会直接发送FIN标志断开通信的请求,而是先发送一个带有ACK标志的应答信息,使客户端明白服务器还有数据要进行发送。
   
3. 服务器的数据发送完成后,向客户端发送带有FIN标志的数据包,通知客户端断开连接。

4. 当客户端收到FIN后,担心某些不可控制的因素导致服务器不知道他要断开连接,会发送ACK进行确认,同时把自己设置成TIME_WAIT状态并启动定时器,在TCP的定时器到达后客户端并没有接收到请求,会重新发送;当服务器收到请求后就断开连接;当客户端等待2MLS(两倍报文最大生存时间)后,没有收到请求重传的请求后,客户端这边就断开连接,整个TCP通信就结束了。
复制代码

为什么握手是三次,挥手是四次

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文。
只有等到我Server端所有的报文都发送完了,才能发送FIN报文,因此不能一起发送。故需要四步握手。
复制代码

为什么不能进行两次握手链接

如果是两次握手,在第二次结束后,服务器并不能保证客户端已经收到了第二次的请求,如此一来的话,服务器会一直保存着这个通信过程,
因为TCP通信都是要占用端口的,造成了一定的资源浪费。所以,就一定要让客户端来发送ACK的确认请求。
复制代码

https的传输过程

1.在服务器端存在一个公钥及私钥

2.客户端从服务器取得这个公钥

3.客户端产生一个随机的密钥

4.客户端通过公钥对密钥加密(非对称加密)

5.客户端发送到服务器端

6.服务器端接受这个密钥并且以后的服务器端和客户端的数据全部通过这个密钥加密
复制代码

https和http的区别

1.https需要证书。
2.http是超文本传输协议,是明文传输,https则是具有安全性的ssl加密传输协议。
3.http和https使用的端口不同,前者是80,后者是443。
4.http的连接很简单,无状态;HTTPS是由SSL+HTTP构建的可进行加密传输、身份认证的网络协议,比http协议安全。
复制代码

如何确定服务端开启了gzip

1、客户端请求中增加Accept-Encoding: gzip表示客户端支持gzip;

2、服务端接收到请求后,将结果通过gzip压缩后返回给客户端并在响应头中增加Content-Encoding:gzip 表示响应数据已被压缩

3、客户端接收请求,响应头中有Content-Encodin:gzip表示数据需解压处理
复制代码

为什么要用缓存

缓存减少了数据传输,对服务器压力减小,提升前端页面性能。
复制代码

强制缓存和协商缓存

强制缓存是我们在第一次请求资源时在http响应头设置一个过期时间,在时效内都将直接从浏览器进行获取,
常见的http响应头字段如Cache-Control 和 Expires

协商缓存是我们通过http响应头字段etag或者Last-Modified等判断服务器上资源是否修改,
如果修改则从服务器重新获取,如果未修改则304指向浏览器缓存中进行获取。
复制代码

css方面

不知宽高的垂直水平居中

1.transform
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
2.flex
    display: flex;//flex布局
    justify-content: center;//使子项目水平居中
    align-items: center;//使子项目垂直居中
3. table
    display: table-cell;
    vertical-align: middle;//使子元素垂直居中
    text-align: center;//使子元素水平居中
4.write-mode
    .wp {
    writing-mode: vertical-lr;
    text-align: center;
}
.wp-inner {
    writing-mode: horizontal-tb;
    display: inline-block;
    text-align: center;
    width: 100%;
}
.box {
    display: inline-block;
    margin: auto;
    text-align: left;
}
5.grid
    .wp {
        display: grid;
    }
    .box {
        align-self: center;
        justify-self: center;
    }
复制代码

如果在图片上面打码

主要通过canvas的合成属性  https://blog.csdn.net/qq_37467034/article/details/92690690 这篇文章上有很好的解释
复制代码

盒模型

标准盒模型的宽高只是内容(content)的宽高,

而在怪异模型中盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高

我们可以通过 box-sizing进行设置 content-box 和 border-box 尤其注意的是padding-box这个属性,width和height属性包括padding的大小,不包括border和margin
复制代码

flex布局

flex布局实现中间自适应  主要考察对flex里的属性的一些了解。flex-grow就可以。
复制代码

重绘和回流

由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, 
color、background-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。


回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。
一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。
复制代码

vue方面

vue data格式

vue中使用return语句返回并不使用{}的原因 是因为 由于组件的复用性,我们并不能把所有组件的属性指向一个地址,而return可以解决掉这个问题。
复制代码

vue中数据监听

1.我们都知道object.defineProperty()可以实现以个对象的get和set监听,那如果对象里是多重对象 深度对象的时候呢,
这个时候我们将通过遍历对象监听的方式 实现对立面每一个子对象的监听
2.vue当前版本的数据监听是由问题的 无法对直接操作数组下标值进行监听
3.所以在vue3中 改用proxy取代了object.defineProperty
复制代码

前端安全方面

xss攻击原理

第一、XSS反射型攻击,恶意代码并没有保存在目标网站,通过引诱用户点击一个链接到目标网站的恶意链接来实施攻击的。

第二、XSS存储型攻击,恶意代码被保存到目标网站的服务器中,这种攻击具有较强的稳定性和持久性。

解决方案
    1. url过滤
    2.提交的符号如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;
    (分号)、()(括号)、&(& 符号)、+(加号)等转义。严格控制输出
复制代码

crsf

 CSRF 跨站请求伪造.CSRF指的是攻击者盗用了你的身份,以你的名义发送恶意的请求,给你造成个人隐私泄露及财产安全.通常指携带你的ck进行请求一些链接。
 
 解决方案
 
 添加refer 改用token
复制代码

js方面

this的指向问题

哪个对象调用函数,函数里面的this指向哪个对象。箭头函数没有this,箭头函数的this是引用箭头函数这层的this。
复制代码

bind apply call区别

bind apply call虽然都是改变this 指向, 但是首先bind返回的是一个函数,需要执行。而call和apply会自动执行。之后apply接受的参数为一个数组。
复制代码

原型漏洞问题

这个问题主要考察的是一层object.freeze(),通过object的冻结来实现对象的无法修改。由于之前jquery和lodash都爆发了相关漏洞。
复制代码

async和await

主要考察宏任务和微任务 搭配promise 询问一些输出的顺序 木易杨大佬的100道题有很好的解释。
async和await  用了同步的方式去做异步  async定义的函数的返回值都是promise  await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈的代码
复制代码

手写promise

这里不举例了 掘金上有很多很好的手写promise的文章。
复制代码

script标签里 defer和async的区别

defer和async虽然都是异步加载js  但是async是加载完js后立马执行 而defer要等待之前全部渲染完再去进行执行。
复制代码

手写深度遍历节点

function traverseDF(node,nodeList){
    if(node){
    nodeList.push(node);
        for(var i=0;i<node.children.length;i++){
            traverseDF(node.children[i],nodeList);
        } 
    }
}
复制代码

主要考察的是对递归和高阶函数的一个应用。官方概念是“变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数” 常见的map reduce等等就是高阶函数。

简介下promise.all

下面这些拷贝自木易杨大佬的github

Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)作为参数,
数组中不一定需要都是Promise对象,但是一定具有Iterator接口,
如果不是的话,就会调用Promise.resolve将其转化为Promise对象之后再进行处理。
使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的;

1、如果所有的Promise对象(p1,p2,p3)都变成fullfilled状态的话,生成的Promise对象(p)也会变成fullfilled状态,
p1,p2,p3三个Promise对象产生的结果会组成一个数组返回给传递给p的回调函数;
2、如果p1,p2,p3中有一个Promise对象变为rejected状态的话,p也会变成rejected状态,第一个被rejected的对象的返回值会传递给p的回调函数。
Promise.all()方法生成的Promise对象也会有一个catch方法来捕获错误处理,但是如果数组中的Promise对象变成rejected状态时,
并且这个对象还定义了catch的方法,那么rejected的对象会执行自己的catch方法。
并且返回一个状态为fullfilled的Promise对象,Promise.all()生成的对象会接受这个Promise对象,不会返回rejected状态。
复制代码

es6 class和构造函数的区别

1.class 声明会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量。
2.class 声明内部会启用严格模式。
3.class 的所有方法(包括静态方法和实例方法)都是不可枚举的。
4.class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
5.必须使用 new 调用 class。
6.class 内部无法重写类名。
7.ES5 和 ES6 子类 this 生成顺序不同。ES5 的继承先生成了子类实例,再调用父类的构造函数修饰子类实例,ES6 的继承先生成父类实例,再调用子类的构造函数修饰父类实例。这个差别使得 ES6 可以继承内置对象。
复制代码

性能优化方面

webpack优化

1.外部引入模块(CDN)
2.按需引入
3.tree-shaking
4.开启gzip
复制代码

其余的优化

1.前面提到的强制缓存与协商缓存
2.减少不必要的http请求 对资源进行合并
3.使用骨架屏提升用户体验
4.前面提到的defer延迟加载
5.懒加载(项目中没用到 所以面试的时候我很少被问到这个)
复制代码

总结

无论什么公司,面试都是按照你的简历来的,简历上写了什么就会被问到什么这是必然的,好的前端基础+优秀的项目经验 会对面试有很大的提升。其次,面试的时候一定要保持自信,不要被面试官的 “你确定么”这种话语左右,你越不自信,印象分会越差,会就是会,不会也不要不懂装懂。希望即将秋招的各位一起共勉。

最后感谢掘金给我分配了一个可爱的女朋友,顺便帮刚毕业的女朋友发个求职吧,上海有招刚毕业的应届生的团队请联系我。

关注下面的标签,发现更多相似文章
评论