字节-抖音基础技术-二面
闲聊时刻:
1.你的专业和计算机科学与技术或者软件工程还是有不小差异,为什么想转来这个领域?
2.了解前端,后端,数据开发, 算法这些岗位都干什么嘛?
前端、后端、数据开发、算法是软件开发和信息技术领域中几个关键的岗位,它们各自承担着不同的职责和任务:
前端(Frontend Developer)
前端开发者主要负责实现用户直接交互的界面部分,也就是网站或应用程序的可视化部分。他们的工作包括:
- 设计与实现:利用HTML、CSS和JavaScript等技术创建网页布局、样式和交互效果。
- 响应式设计:确保应用在不同设备和屏幕尺寸上的适配性。
- 用户体验优化:提升用户界面的可用性和美观性。
- 与后端交互:通过API调用与后端服务器交换数据,实现动态内容加载。
后端(Backend Developer)
后端开发者关注的是服务器端的逻辑、数据处理以及系统架构。他们的主要职责包括:
- 服务器端编程:使用Java、Python、Node.js、PHP等语言编写服务器端代码。
- 数据库管理:设计数据库结构,处理数据存储、检索、更新和删除等操作。
- API开发:构建和维护供前端或其他系统调用的API接口。
- 系统架构:设计系统的整体架构,确保其可扩展性、安全性和稳定性。
数据开发(Data Developer 或 Data Engineer)
数据开发者专注于数据的收集、存储、处理和分析,为数据科学家和分析师提供基础设施支持。他们的工作包括:
- 数据管道建设:建立ETL(提取、转换、加载)流程,确保数据在不同系统间顺畅流动。
- 大数据平台:在Hadoop、Spark等大数据平台上设计和实施数据存储方案。
- 数据仓库:建设和维护数据仓库,支持企业级数据分析需求。
- 数据质量与治理:确保数据的准确性和一致性。
算法(Algorithm Engineer 或 Machine Learning Engineer)
算法工程师专注于算法的设计、实现及优化,特别是在机器学习、数据挖掘和人工智能等领域。他们的职责包括:
- 算法研究:依据项目需求,研究并设计新的或改进现有算法。
- 模型训练与优化:使用深度学习、强化学习等技术训练模型,并优化模型性能。
- 数据分析:对大量数据进行深入分析,提取有价值的信息和洞察。
- 应用开发:将算法应用于实际产品或服务中,如推荐系统、图像识别等。
每个岗位都需要特定的技术栈和专业知识,但它们之间也存在紧密的合作,共同推动项目的成功。
3.你更想去做的岗位是什么?为什么?
4.如果你来做软件开发,你的中短期的个人目标是什么?
计算机网络:
1.在浏览器输入网址后,会发生什么?(用户服务请求的响应过程及释放)
当您在浏览器中输入网址并按下回车键后,一系列复杂而高效的过程随即启动,以帮助您访问目标网页。以下是这一系列步骤的简要概述:
-
域名解析(DNS查询):
- 浏览器首先检查本地缓存和操作系统缓存中是否已存储了该网址对应的IP地址。
- 如果本地没有相关信息,浏览器会向DNS(域名系统)服务器发送请求,询问该网址的IP地址。这个过程可能涉及多个DNS服务器,从本地DNS服务器逐级查询直至根服务器,直到找到负责该域名的权威DNS服务器并获得IP地址。
-
建立TCP连接(三次握手):
- 获取到IP地址后,浏览器使用TCP协议与网站的服务器建立连接。这通常涉及三次握手过程,确保双方都能准备好进行数据传输,保证连接的可靠性。
-
发送HTTP/HTTPS请求:
- 建立连接后,浏览器向服务器发送一个HTTP或HTTPS(安全套接层下的HTTP)请求。请求中包含诸如请求方法(通常是GET)、请求的URL、浏览器信息、接受的内容类型等信息。
-
服务器处理请求:
- 服务器收到请求后,根据请求内容处理请求,这可能包括查询数据库、执行服务器端脚本(如PHP、Python等)、生成动态内容等。
-
服务器响应:
- 处理完成后,服务器将响应数据(状态码、响应头和响应体)通过原TCP连接返回给浏览器。响应体通常是HTML文档,但也可能是图片、视频或其他类型的文件。
-
渲染网页:
- 浏览器接收到响应后,开始解析HTML文档,构建DOM(文档对象模型)树。同时,浏览器会解析CSS文件以确定样式,并执行JavaScript代码来实现交互性。
- 在此过程中,如果遇到外部资源链接(如图片、样式表、脚本文件),浏览器会发起额外的HTTP请求获取这些资源。
- 当所有资源加载完毕,浏览器最终渲染出用户可见的网页。
-
连接关闭:
- HTTP/1.0中,每个请求/响应周期后会关闭TCP连接。但在HTTP/1.1及以后版本中,默认保持连接开启一段时间(Keep-Alive),以便复用同一连接发送多个请求,提高效率。最终,当无更多数据传输时,通过TCP的四次挥手过程优雅地关闭连接。
2.你刚才提到DNS解析,那什么是DNS解析,具体展开说说?(域名系统解析过程)
DNS解析是互联网中一个核心的过程,它将人类可读的域名(比如 example.com
)转换成计算机可以理解的IP地址(如 192.0.2.1
)。
DNS解析的具体步骤如下:
-
查询本地缓存:当用户在浏览器中输入一个网址时,电脑首先会检查自己的本地缓存(包括浏览器缓存和操作系统缓存),看之前是否已经解析过这个域名并存储了相应的IP地址。
-
查询本地DNS服务器:如果没有在本地缓存中找到,那么请求会被送到用户的本地DNS服务器,通常是ISP(互联网服务提供商)提供的或者是局域网内的DNS服务器。这台服务器同样会检查其缓存。
-
递归查询:如果本地DNS服务器也没有相关信息,它会代表客户端发起一个递归查询。这个过程可能涉及多个层级的DNS服务器,从根DNS服务器到顶级域名服务器(如
.com
、.org
),再到权威DNS服务器,后者负责存储特定域名与其IP地址对应关系的正式记录。 -
获取IP地址并返回:一旦权威DNS服务器找到了匹配的域名记录(A记录、AAAA记录等),它会将这个IP地址返回给本地DNS服务器,然后本地DNS服务器再将这个信息返回给用户的电脑,最后电脑使用这个IP地址来建立与目标网站服务器的连接。
-
缓存结果:为了加速未来的请求,本地DNS服务器和用户的电脑都会缓存这个域名到IP地址的映射一段时间,这样下次相同域名的查询就可以直接从缓存中获取结果,而无需再次进行完整的DNS查询流程。
3.服务器的状态码,比如1开头,2开头等等,分别代表什么意思?
HTTP服务器的状态码是HTTP协议中服务器响应客户端请求时使用的三位数字代码,用于传达请求的处理结果。这些状态码被分为五类,每类由一个数字范围表示,具体含义如下:
-
1xx(信息性状态码):
这些状态码表示接收的请求正在处理,需要请求者继续操作。这类响应是临时响应,通常只包含状态行和某些可选的响应头信息。- 例如,
100 Continue
表示客户端应继续其请求的剩余部分。
- 例如,
-
2xx(成功状态码):
表示请求已成功被服务器接收、理解、并接受。200 OK
表示请求成功,服务器已成功处理请求。201 Created
表示请求成功并且服务器创建了新的资源。202 Accepted
表示服务器已接受请求,但尚未处理。204 No Content
表示服务器成功处理了请求,但没有返回任何内容。
-
3xx(重定向状态码):
表示需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向客户端到不同的位置或使用不同的请求方式获取资源。301 Moved Permanently
表示请求的页面已永久移动到新位置。302 Found
(临时重定向)指示请求的资源现在位于另一个URI下,未来同样的请求仍应使用原始URI。304 Not Modified
表示自从上次请求后,请求的资源未修改过,可以直接使用缓存的内容。
-
4xx(客户端错误状态码):
表示客户端的请求有误,服务器无法处理。- 如
400 Bad Request
表示请求无效或无法被服务器理解。 401 Unauthorized
表示请求要求用户的身份认证。403 Forbidden
表示服务器理解请求客户端的请求,但是拒绝执行此请求。
- 如
-
5xx(服务器错误状态码):
表示服务器在处理请求的过程中发生了错误。- 例如,
500 Internal Server Error
表示服务器遇到了不知道如何处理的情况。 502 Bad Gateway
表示作为网关或代理工作的服务器从上游服务器收到了无效的响应。503 Service Unavailable
表示服务器目前无法处理请求,通常是由于服务器过载或维护。
- 例如,
4.URL是什么,具体介绍下每个部分的用处?
URL(Uniform Resource Locator,统一资源定位符)是用于唯一标识互联网上资源的位置及其访问方式的标准化字符串格式。URL使用户能够通过浏览器或其他应用程序访问网页、图片、视频、文档等网络资源。一个典型的URL由以下几个主要部分组成,每个部分都有其特定的用途:
-
协议(Scheme):
- 指定用于访问资源的通信协议,常见的有
http:
(超文本传输协议)、https:
(安全的超文本传输协议)、ftp:
(文件传输协议)等。协议告诉浏览器或客户端应该如何与服务器通信。
- 指定用于访问资源的通信协议,常见的有
-
域名(Domain Name)或 IP 地址:
- 标识资源所在的服务器。域名是一个易读的名称,通过DNS系统解析为IP地址。IP地址是服务器在网络中的唯一标识,形式如
192.0.2.1
。通过域名或IP地址,客户端能找到资源所在的实际物理位置。
- 标识资源所在的服务器。域名是一个易读的名称,通过DNS系统解析为IP地址。IP地址是服务器在网络中的唯一标识,形式如
-
端口(Port)(可选):
- 用于指定服务器上的特定服务或进程。如果不指定,大多数协议会使用默认端口,例如HTTP默认端口为80,HTTPS默认端口为443。如果使用非默认端口,会在域名后面加上冒号
:
和端口号,如example.com:8080
。
- 用于指定服务器上的特定服务或进程。如果不指定,大多数协议会使用默认端口,例如HTTP默认端口为80,HTTPS默认端口为443。如果使用非默认端口,会在域名后面加上冒号
-
路径(Path):
- 显示资源在服务器上的具体位置或路径。路径是从网站的根目录开始的,指向特定的文件或目录,例如
/index.html
。
- 显示资源在服务器上的具体位置或路径。路径是从网站的根目录开始的,指向特定的文件或目录,例如
5.了解Https吗?与Http的区别是什么?
HTTPS(Hypertext Transfer Protocol Secure)是一种基于HTTP的通信协议,旨在提供更加安全的互联网通信。它是HTTP协议的安全版本,通过在HTTP协议基础上加入SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议层,使得数据在传输过程中得以加密,确保数据的完整性、保护数据免遭窃听和篡改,并验证服务器的身份,防止中间人攻击。
与HTTP相比,HTTPS的主要区别在于:
-
安全性:
- 加密传输:HTTPS通过SSL/TLS协议对通信内容进行加密,即使数据在传输过程中被截获,也无法直接阅读,增加了数据的安全性。
- 身份验证:HTTPS要求服务器必须拥有由权威机构颁发的SSL证书,这可以验证服务器的身份,帮助用户避免被欺诈网站误导。
-
端口:
- HTTP默认使用80端口,而HTTPS则使用443端口进行通信。
-
性能开销:
- 由于需要进行加密处理,HTTPS相较于HTTP会有一定的性能开销,包括CPU用于加密解密的计算资源和初始化连接时的握手过程。然而,随着技术进步和优化,这种开销在很多情况下已经大大降低,对用户体验的影响减小。
-
信任度与SEO:
- 使用HTTPS的网站通常被认为更可信,因为证书验证机制提高了网站的真实性和安全性。此外,搜索引擎如Google明确表示HTTPS是其搜索排名算法中的一个因素,使用HTTPS的网站可能在搜索结果中获得更好的排名。
-
成本:
- 虽然HTTP本身不需要额外费用,但HTTPS需要购买和维护SSL证书,尽管现在存在一些免费的证书颁发机构,使得启用HTTPS的成本有所降低。
6.你刚才提到SSL加密,具体讲讲是怎么工作的?
SSL(Secure Sockets Layer)加密是一个复杂的过程,旨在确保数据在客户端(如浏览器)和服务器之间安全传输。虽然SSL已被TLS(Transport Layer Security)协议所取代,但其基本工作原理在现代的HTTPS连接中仍然适用。以下是SSL加密工作的简化步骤:
-
握手阶段:
- 建立连接:客户端通过TCP/IP协议与服务器建立连接。
- 请求开始SSL握手:客户端发送一个“ClientHello”消息给服务器,这个消息中包含了客户端支持的SSL/TLS版本、加密套件列表、随机生成的数据(Client Random)等信息。
- 服务器响应:服务器收到“ClientHello”后,选择一个双方都支持的最高版本的SSL/TLS协议和加密套件,并发送一个“ServerHello”消息,其中包含服务器的随机数据(Server Random)、选定的协议版本和加密套件等信息。
- 证书交换:服务器发送其数字证书给客户端,该证书包含了服务器的公钥和由证书颁发机构(CA)签名的身份信息。客户端验证证书的有效性,包括检查证书是否由受信任的CA签发、是否过期等。
- 密钥交换与验证:客户端使用服务器的公钥生成一个新的随机密钥,这个密钥被称为“会话密钥”,用于后续通信的对称加密。客户端将这个会话密钥用服务器的公钥加密后发送给服务器。
- 握手完成:服务器使用自己的私钥解密得到会话密钥。至此,客户端和服务器都拥有了相同的会话密钥,可以开始加密通信。
-
数据传输阶段:
- 对称加密:使用在握手阶段协商好的会话密钥,客户端和服务器开始使用对称加密算法(如AES)对实际传输的数据进行加密和解密。对称加密效率高,适合大量数据的快速加密和解密。
- 消息完整性:除了加密,还会使用消息认证码(MAC)或者在TLS中使用哈希函数来校验数据的完整性,确保数据在传输过程中未被篡改。
-
连接结束:
- 通信结束后,可以通过简单的关闭通知或等待超时自动断开连接。在某些情况下,如果需要提前终止连接,还会有一个关闭握手的过程来确保双方都知道连接已结束。
SSL加密的核心在于结合了非对称加密(用于安全地交换会话密钥)和对称加密(用于高效地加密大量数据传输),并加入了身份验证和数据完整性验证机制,以此来确保通信的安全性。
7.你刚才提到的Http响应过程中要建立TCP连接,讲讲TCP连接的三次握手,为什么是三次,而不是四次五次呢?
TCP(Transmission Control Protocol)连接的建立过程通常涉及“三次握手”(Three-Way Handshake),这一过程设计的目的在于可靠且有效地初始化通信双方的连接状态,确保数据能够正确无误地传输。下面解释为什么需要三次握手以及为什么不是四次或五次。
三次握手的过程:
-
第一次握手:客户端发送一个带有SYN(Synchronize)标志的数据包到服务器,并附上一个初始序号(Sequence Number),表示客户端希望建立连接。
-
第二次握手:服务器接收到SYN包后,会以自己的SYN包作为应答,同时设置ACK(Acknowledgment)标志位,表示确认收到了客户端的SYN包。服务器的SYN包也包含一个初始序号,并且ACK字段的值是客户端ISN加1,用来确认收到了客户端的SYN。
-
第三次握手:客户端收到服务器的SYN+ACK包后,会再向服务器发送一个ACK包,确认收到了服务器的SYN。此时,ACK的值是服务器ISN加1。这个ACK标志了客户端已经准备好进行数据传输,至此,TCP连接完全建立。
为什么是三次而不是更多次?
- 确保连接请求到达:三次握手首先确保了客户端的连接请求确实到达了服务器,并且服务器愿意并且能够建立连接。
- 双方确认收发能力:通过这三次交互,客户端和服务器都确认了彼此的发送和接收能力。客户端知道服务器收到了它的请求,并且服务器也知道客户端收到了它的确认。
- 防止历史连接请求引起错误:三次握手还解决了所谓的“延迟包”问题,即如果客户端的第一个SYN请求在网络中滞留,然后很晚才到达服务器,而此时客户端已经建立了新的连接或者关闭了旧的连接,那么服务器收到这个滞留的SYN后回复SYN+ACK,但客户端不会回应这个过时的请求,从而避免了无效连接的建立。
为什么不是四次或五次?
- 四次或五次握手会增加延迟:每增加一次握手,就会额外增加一次网络往返时间(RTT),这会降低连接建立的效率。
- 三次握手已满足需求:三次握手已经足够保证连接的可靠性,没有必要通过更多的握手来重复确认已经确认的信息。
- 避免资源浪费:更多的握手意味着更多的网络资源消耗,包括带宽和计算资源,尤其是在高并发场景下,这会直接影响系统的性能。
因此,三次握手是在确保连接可靠性与效率之间的一个平衡点,既不多余也不缺失,是经过实践验证的最合适的连接建立机制。
8.那为什么挥手需要四次呢?三次不行吗?
TCP连接的终止过程,即“四次挥手”(Four-Way Handshake),比建立连接多一次交互,这是因为TCP连接是全双工的,可以同时进行双向的数据传输。因此,在关闭连接时,需要确保两个方向的数据传输都已正确结束,这要求每个方向的关闭都要独立进行确认。下面是详细的解释:
为什么需要四次挥手:
-
第一次挥手:客户端发送一个FIN(Finish)标志的数据包给服务器,表示客户端已经没有数据需要发送了(即客户端到服务器方向的连接需要关闭)。
-
第二次挥手:服务器收到客户端的FIN包后,回复一个ACK确认报文,确认收到了客户端的关闭请求。此时,服务器可能还在向客户端发送数据(服务器到客户端方向的连接依然打开)。
-
第三次挥手:当服务器也完成了数据发送任务,会向客户端发送一个带有FIN标志的数据包,表明服务器到客户端的方向也没有数据需要发送了,请求关闭这个方向的连接。
-
第四次挥手:客户端收到服务器的FIN包后,发送ACK确认报文给服务器,确认收到了服务器的关闭请求。此时,客户端进入TIME_WAIT状态,等待足够长的时间以确保最后一个ACK报文能够到达服务器(防止丢包导致服务器重发FIN),之后关闭连接。
为什么不是三次:
- 如果仅使用三次挥手,当客户端发送了FIN请求后,如果服务器直接发送FIN+ACK(即在第二次挥手时同时表示自己也没有数据发送了,并确认客户端的FIN),可能会导致以下问题:
- 数据丢失:服务器可能仍有数据需要发送给客户端,直接关闭连接会导致这部分数据无法正确传输。
- 资源释放问题:服务器可能需要在发送完所有数据后才能安全地关闭连接,立即响应FIN会导致资源不能及时释放。
- 连接状态不一致:缺少对服务器FIN的独立确认,可能导致客户端和服务器对于连接关闭状态的认知不一致,影响连接的正确关闭和资源的回收。
因此,四次挥手的设计确保了在关闭连接时,两个方向的数据传输都能够被正确且完整地终止,并且双方都能确认对方的关闭意图,保证了连接关闭过程的可靠性和完整性。
操作系统:
1. 内存上的分区有哪些区域?
内存通常划分为以下几个区域:
- 代码区(Code Segment):存储程序的机器指令和只读数据(如字符串常量)。
- 全局/静态数据区(Data Segment):存放全局变量和静态变量,初始化过的全局变量和静态变量存储在这里。
- 堆区(Heap):动态分配的内存区域,程序员通过malloc/new等分配和free/delete释放。
- 栈区(Stack):自动变量(局部变量)存储的地方,函数调用时也会在此保存函数帧信息。
- 只读区(Read-Only Segment):包含常量和程序代码,有时与代码区合并考虑。
2. 如果定义一个变量int a,那么这个变量会一直存在吗?
这取决于变量的存储类型和它所处的作用域。如果是局部变量,它存在于栈区,当其所在的函数执行完毕后,变量就会被销毁。如果是全局变量或静态局部变量,则存储在全局/静态数据区,这样的变量会一直存在直到程序结束。
3. 那如果使用static修饰呢?
使用static
修饰的变量(不论是全局变量还是局部变量)都会存储在全局/静态数据区。这意味着即使定义在函数内部,该静态变量也不会随着函数的调用结束而销毁,而是整个程序运行期间都存在,并且保持其值。
4. 了解内存对齐吗?为什么要用内存对齐?为什么内存对齐能提高效率?
内存对齐是指数据在内存中存储时,地址需要按照某种特定边界对齐。例如,一个4字节整型变量通常需要存储在一个4字节对齐的地址上。这样做有几个原因:
- 性能提升:许多处理器访问内存时,对齐的数据可以一次性读取或写入,而非对齐的数据可能需要两次或更多次操作,降低效率。
- 兼容性:某些硬件架构仅支持对齐访问,非对齐访问可能导致硬件异常。
- 简化编译器和硬件设计:对齐规则简化了寻址逻辑,使得编译器和硬件设计更为直接。
5. 有做过多线程编程吗?进程和线程之间的区别是什么?
多线程编程涉及在单个进程中创建多个线程来同时执行任务。进程与线程的主要区别在于:
- 资源拥有:进程是资源分配的基本单位,拥有独立的地址空间和系统资源;线程是CPU调度的基本单位,共享所属进程的资源。
- 上下文切换开销:进程间上下文切换通常比线程间上下文切换更耗时,因为后者不需要切换地址空间。
- 独立性:进程之间相对独立,一个进程崩溃不会直接影响其他进程;线程之间资源共享,一个线程崩溃可能导致整个进程(及其所有线程)崩溃。
6. 多线程编程中最重要的是什么?
在多线程编程中,最重要的是线程安全和同步机制,确保多个线程访问共享资源时不会引发数据竞争和一致性问题。这通常通过使用锁、信号量、条件变量等同步原语来实现。
7. 了解锁吗?互斥锁和自旋锁的区别是什么?
锁是同步机制中的一种,用于控制多个线程对共享资源的访问。互斥锁(Mutex)和自旋锁都是常用的锁类型,区别在于:
- 互斥锁:如果锁被占用,请求锁的线程会被阻塞,直至锁被释放。它适合锁持有时间较长的情况,但频繁的上下文切换可能影响性能。
- 自旋锁:线程在尝试获取锁时,如果锁被占用,不会立即阻塞,而是循环(自旋)等待锁释放。适用于锁占用时间较短,避免了上下文切换的开销,但如果锁被长时间占用,自旋锁会浪费CPU资源。
8. 了解读写锁吗?和互斥锁之间的区别是什么?为什么要用读写锁?
读写锁(Reader-Writer Lock)允许更高程度的并发,它分为读锁和写锁两种状态:
- 读锁:可以被多个线程同时持有,只要没有写锁存在。
- 写锁:独占锁,一旦被一个线程持有,其他线程(无论是读还是写)都不能获取锁。
与互斥锁相比,读写锁在读多写少的场景下能显著提高并发性能,因为它允许同时进行多个读取操作,而互斥锁在任何时刻只允许一个线程访问资源,无论读写。读写锁的目的是为了在保护数据的同时,最大化并发性能,特别是在读操作远多于写操作的应用中。
编程题:数组中最大的连续严格递增序列。