收获成长的一次面试---字节跳动🙆‍♀️

1,111 阅读9分钟

2.14号收到了字节跳动国际化电商HR小姐姐的面试邀请,约的时间是3.1号面试,感觉很荣幸。

面试流程

开始面试的时候简单做了一下自我介绍,面试官简单的说了一下要面试的内容:根据你简历上写的内容以及一些项目的细节点来考察你

开始问问题

怎么理解进程和线程

上来就是操作系统,但是很久没有去看操作系统相关的知识点了,回答的时候很不官方,这里给上鼎鼎有名的CS-notes的文章。简单来说,进程就是资源分配的基本单位,线程是独立调度的基本单位

什么是死锁

通过一个经典问题---哲学家就餐问题,引出了死锁的基本概念:当两个以上的运算单元,双方都在等待对方停止执行,以获取系统资源,但是没有一方提前退出时,就称为死锁。个人觉得死锁的解决问题还是要说出来的,但是当时我连死锁的基本概念也说得模糊🤣,面试官也没再深问了。

关于死锁的基本概念和解决方法在这里

还有一点我觉得很重要,如果想更深入的了解操作系统比起CS-notes我更推荐的是看现代操作系统这本书,比起干枯的知识点,我更觉得(举例子|抛出问题 + 知识点)是更好去记忆和理解的

HTTP是在网络的哪一层,数据是怎么进行传递的

这道题考察网络模型,引用计算机网络自顶而下方法的图就是

image.jpeg
从上到下分别为应用层(HTTP,DNS,SMTP)--运输层(TCP,UDP)--网络层(IP)--链路层--物理层,数据的传输就是类似于上图搭乘某个航班的流程,回答完以后面试就开始问TCP 的三次握手四次挥手的问题

TCP三次握手四次挥手

三次握手

第一次握手 客户端给服务器发送一个SYN (Synchronize 同步)报文,并指明客户端的初始化序列号ISN(Initial Sequence Number) ,此时客户端处于SYN_SEND 状态,首部的同步位SYN=1,初始序号seq=xSYN=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

然后面试官就问有什么方法可以判断基本数据类型吗?

  1. typeof 这个方法有一个问题,就是typeof null='object',这是JS一个悠久的bug,JS是32位比特来赋值的,且是通过值的低三位未判断类型的,null32位全是0,object低三位也全是0,就导致JS引擎判断错误

  2. Object.prototype.tostring.call(target) 不用多说,直接看冴羽大大的文章,然后说完这两个,面试官问我还有吗?我就想到了instanceof

  3. 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油管上的英文视频,而且一定要有自己的理解,要从源码的设计理念中学到知识(比如设计模式这一块)并运用于自己的实战中。考八股文最重要的一点是,考察你的代码能力,有没有把所背的,所学的,熟练地运用到业务场景中,这一点是最重要的

对自己的评价

首先很感谢面试官在百忙之中抽出时间来面试,可以看出大厂对基础的要求很高,自己一定要把基础打好,自己应该重拾现代操作系统计算机网络自顶而下方法这两本书了,如果想走的更远,就一直保持一个学习的心吧,希望对各位的面试能有一点帮助吧