2.14号收到了字节跳动国际化电商HR小姐姐的面试邀请,约的时间是3.1号面试,感觉很荣幸。
面试流程
开始面试的时候简单做了一下自我介绍,面试官简单的说了一下要面试的内容:根据你简历上写的内容以及一些项目的细节点来考察你
开始问问题
怎么理解进程和线程
上来就是操作系统,但是很久没有去看操作系统相关的知识点了,回答的时候很不官方,这里给上鼎鼎有名的CS-notes的文章。简单来说,进程就是资源分配的基本单位,线程是独立调度的基本单位
什么是死锁
通过一个经典问题---哲学家就餐问题,引出了死锁的基本概念:当两个以上的运算单元,双方都在等待对方停止执行,以获取系统资源,但是没有一方提前退出时,就称为死锁。个人觉得死锁的解决问题还是要说出来的,但是当时我连死锁的基本概念也说得模糊🤣,面试官也没再深问了。
关于死锁的基本概念和解决方法在这里
还有一点我觉得很重要,如果想更深入的了解操作系统比起CS-notes我更推荐的是看现代操作系统这本书,比起干枯的知识点,我更觉得(举例子|抛出问题 + 知识点)是更好去记忆和理解的
HTTP是在网络的哪一层,数据是怎么进行传递的
这道题考察网络模型,引用计算机网络自顶而下方法的图就是
从上到下分别为应用层(HTTP,DNS,SMTP)--运输层(TCP,UDP)--网络层(IP)--链路层--物理层,数据的传输就是类似于上图搭乘某个航班的流程,回答完以后面试就开始问TCP 的三次握手四次挥手的问题
TCP三次握手四次挥手
三次握手
第一次握手
客户端给服务器发送一个SYN (Synchronize 同步)报文,并指明客户端的初始化序列号ISN(Initial Sequence Number) ,此时客户端处于SYN_SEND 状态,首部的同步位SYN=1,初始序号seq=x,SYN=1 的报文段不能携带数据,但是要消耗掉一个序号
这样服务器得出了结论:客户端的发送能力,服务端的接受能力是正常的
第二次握手
服务器接收到客户端的SYN报文之后,会以自己的SYN报文作为应答,并且也是制定了自己的初始化序列号ISN,同时会把客户端的ISN + 1 作为ACK(Acknowledge character)的值,表示自己已经收到了客户端的SYN,此时服务器处于SYN_RCVD(半连接)的状态
这样客户端得出的结论是:服务端的接收,发送能力,客户端的接收,能力是正常的,不过此时服务器并不能确认客户端的接收能力是否正常
第三次握手
客户端收到SYN报文之后,会发送一个ACK(Acknowledge character)报文,当然,也是一样把服务器的ISN+1作为ACK的值,包是已收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态,服务器收到ACK报文之后,也处于ESTABLISHED状态,此时,双方已经建立起了联系
这样服务端就能得出结论:客户端的接收,发送能力正常,服务器自己的发送,接收能力也正常
四次挥手
第一次挥手:连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
第二次挥手: 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
第三次挥手: 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥手:即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
上一张眼花缭乱的图🤣
说说你了解的状态码
- 1XX 表示消息
- 2XX 表示成功
- 3XX 表示重定向
- 4XX 表示客户端错误
- 5XX 表示服务器错误
状态码最好是配合业务场景来说,不然显得你只是死记硬背
201 created 表示资源创建成功:比如我给一个文章点赞了,在后端看来那就要在相应的点赞数据库进行加一操作,操作成功则返回201,给下伪代码
try {
const data = await createUserLikePost(userId, parseInt(postId, 10));// 进行数据库操作
// 201 created
response.status(201).send(data);
} catch (error) {
next(error);
}
301 Moved Permanently:永久重定向,请求的网页已被永久移动到新的位置,会自动跳转到新位置
302 Found:临时重定向,资源临时失效,跳转到一个临时的代替页上
简单说了以下301和302的区别: 关键在于资源是否存在有效性,301表示资源还在,但只是换了一个位置,返回新位置的内容;302表示资源暂时失效,返回一个临时的代替页,如果资源永久失效,使用404 Not Found
304 Not Modified:脑子抽了,没有讲强缓存和协商缓存🤐!
400 Bad Request:表示服务器无法理解的参数,比如输入账号密码的时候输错了,服务端经过验证后发现数据错误,就会返回400
401 Unauthorized:没有权限的用户请求需要带有权限的资源时,返回401,比如我以游客登录的身份游览掘金的网站时,想点赞,突然弹出一个需要登录的窗口,这就是服务端给你返回的401,因为只有登录的用户才能点赞🤣
403 Forbbidden:不管你做什么都没有权限访问,天王老子来了都没用!
很可惜没有说到409 Conflict,写项目的时候用到了一次,简单来说就是如果你想改密码的时候,你传了一个和原密码一样的密码给服务器,服务器再经过对比之后发现两条数据是一样的,就会返回409表示新密码于密码一致,请重新输入
502 Bad Getaway:很尴尬当时把英文忘了,Nginx上常见,表示上游应用层未返回响应,挂掉了
504 Gateway Timeout:网关超时,上游应用层迟迟未响应
你了解HTTPS吗
这个问题我回答的相当诚实🤣,我只知道HTTPS是在HTTP和TCP之间增加了一层SSL/TLS
面试官:......
具体看这篇文章吧
说一说position布局
答案都在MDN
简单说了一下几个属性: static,relative,absolute,fixed,sticky(当时也把这个属性名忘记了🤣)
然后问了给了我一个场景,假如给你div标签
div {
position: relative;
width: 100px;
height: 100px;
top: 20px;
left: 20px;
}
这个div标签在页面上是怎么布局的?
JS 的基本数据类型
- Number
- String
- Boolean
- Null
- Undefined
- Bigint
- Smybol
然后面试官就问有什么方法可以判断基本数据类型吗?
-
typeof这个方法有一个问题,就是typeof null='object',这是JS一个悠久的bug,JS是32位比特来赋值的,且是通过值的低三位未判断类型的,null32位全是0,object低三位也全是0,就导致JS引擎判断错误 -
Object.prototype.tostring.call(target)不用多说,直接看冴羽大大的文章,然后说完这两个,面试官问我还有吗?我就想到了instanceof -
instanceof这个我答的不好,instanceof是判断一个对象是否是另一个对象的实例object instanceof constructor
let a = '1';
let b = new String('1');
a instanceof String; // false
b instanceof String; // true
能判断基本类型是有条件的,要将原有的方法重定义,如果你不知道Symbol,可以看看MDN上关于hasInstance的解释
class PrimitiveNumber {
static [Symbol.hasInstance](x) {
return typeof x === 'number'
}
}
console.log(1 instanceof PrimitiveNumber) // true
讲一讲new的实现过程
function _new(obj, ...rest) {
// 基于obj的原型创建一个新的对象
const newObj = create(obj);
// 添加属性到新创建的newObj上, 并获取obj函数执行的结果.
const result = obj.apply(newObj, rest);
// 如果执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象
return (typeof result === 'object' && result !== null) ? result : newObj;
}
function create(obj) {
const target = {};
target.__proto__ = obj.prototype;
return target;
}
怎么判断一个链表是否为环形链表
function isCircle(head) {
let fast = head;
let slow = head;
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if(slow == fast) return true;
}
return false;
}
一开始说了一下思路,用快慢指针,之后开始动手了,太久没刷链表相关的题了,一道很简单的题面试官提醒了两次才把代码完全写正确,还是要多加练习算法🤣
总结
到这里面试结束了,轮到我问问题的时候,我也是简单的问了一下面试官的学习过程,简单来说就是一些JS,HTML的这种定死的基础知识点在MDN或者W3C这种权威的网站上看,还有像React源码的这类的技术文章可以去掘金上找,但是更推荐的是看React油管上的英文视频,而且一定要有自己的理解,要从源码的设计理念中学到知识(比如设计模式这一块)并运用于自己的实战中。考八股文最重要的一点是,考察你的代码能力,有没有把所背的,所学的,熟练地运用到业务场景中,这一点是最重要的
对自己的评价
首先很感谢面试官在百忙之中抽出时间来面试,可以看出大厂对基础的要求很高,自己一定要把基础打好,自己应该重拾现代操作系统和计算机网络自顶而下方法这两本书了,如果想走的更远,就一直保持一个学习的心吧,希望对各位的面试能有一点帮助吧