字节面经汇总
实习
日常实习 — 生活服务部门
原链接:
https://www.nowcoder.com/discuss/556123658565992448?sourceSSR=dynamic
操作系统
线程和进程
进程: 是系统运行程序的基本单元 进程是动态的 进程包含了线程
线程: 线程是比进程更小的执行单元 线程共享进程的堆和方法区的资源 但每个线程有自己程序计数器 虚拟机栈和本地方法栈
线程是进程的划分成更小的运行单元 线程和进程最⼤的不同在于基本上各进程是独⽴的,⽽各线程则不⼀定,因为同⼀进程中的线程极有可能会相互影响。线程执⾏开销⼩,但不利于资源的管
理和保护;⽽进程正相反
进程间通信与线程间通信
进程间通信(IPC)是在不同的进程之间进行数据交换,而线程间通信(ITC)是在同一个进程的不同线程之间进行数据交换。
由于线程共享同一进程的内存空间,因此在线程间通信时,可以直接访问共享的内存,而不需要使用像管道、消息队列或套接字这些IPC机制。
- 进程间通信 IPC:
管道 (Pipe):管道是一种半双工的通信机制,用于在具有亲缘关系的进程之间传递数据。它可以是匿名管道 (Anonymous Pipe) 或命名管道 (Named Pipe)。
共享内存 (Shared Memory):共享内存是一种将内存区域映射到多个进程的机制,使它们可以直接访问共享的内存块,从而实现进程间的数据共享。
消息队列 (Message Queue):消息队列是一种在进程之间传递消息的通信机制,它允许一个进程向队列中发送消息,另一个进程从队列中接收消息。
信号量 (Semaphore):信号量是一种用于进程间同步和互斥的机制,它可以用来保护共享资源,避免资源的竞争和冲突。
套接字 (Socket):套接字是一种用于在网络上进行进程间通信的机制,它可以在不同计算机之间传递数据。 - 线程间通信 (ITC):
共享内存 (Shared Memory):与进程间通信相同,线程也可以通过共享内存来实现数据的共享和交换。
互斥锁 (Mutex):互斥锁是一种用于线程间同步的机制,它可以保护共享资源,确保同一时间只有一个线程可以访问该资源。
条件变量 (Condition Variable):条件变量是一种用于线程间等待和通知的机制,它可以使一个线程等待某个特定条件满足后再继续执行。
信号量 (Semaphore):与进程间通信相同,线程也可以使用信号量来实现线程间的同步和互斥。
读写锁怎么实现
读写锁本质上是一种自旋锁 是给一段临界区代码加锁
读写锁(Read-Write Lock)是一种并发控制机制,用于在多线程环境下保护共享资源的访问。读写锁允许多个线程同时读取共享资源,但只允许一个线程进行写操作。
读写锁的实现通常包括以下几个关键组件:
- 读计数器(Read Count):记录当前有多少个线程正在读取共享资源。
- 写计数器(Write Count):记录当前有多少个线程正在进行写操作。
- 互斥锁(Mutex Lock):用于保护读写锁本身的访问,即读写锁的获取和释放。
读操作的实现流程如下:
- 当一个线程请求读取共享资源时,首先需要获取读写锁的互斥锁。
- 在获取互斥锁后,读计数器会自增,表示有一个线程正在读取共享资源。
- 如果有其他线程正在进行写操作(写计数器大于0)或者有写操作请求正在等待,则当前线程需要等待。
- 如果没有写操作正在进行,当前线程可以直接访问共享资源。
- 当一个线程完成读取操作后,读计数器自减。
写操作的实现流程如下:
- 当一个线程请求写操作时,首先需要获取读写锁的互斥锁。
- 在获取互斥锁后,如果读计数器不为0或者写计数器不为0,则当前线程需要等待。
- 如果没有其他线程正在读取或写入,当前线程可以执行写操作。
- 写操作完成后,写计数器归零,并释放互斥锁。
虚拟内存
在操作系统中,虚拟内存是一种技术,它将计算机的物理内存(RAM)扩展到硬盘上的虚拟地址空间。虚拟内存允许每个进程在其自己的地址空间中执行,而不需要实际占用全部物理内存。
硬件提供了地址转换机制,将虚拟地址转换为物理地址。操作系统负责管理虚拟内存的分配、回收、页面置换等。
虚拟内存的主要目的是提供更大的可用内存空间,以满足多进程同时运行的需求。它还提供了以下几个重要的功能:
- 内存管理:虚拟内存将物理内存划分为固定大小的页面(通常为4KB或者8KB),并将进程的虚拟地址空间划分为相应的页面。这样,操作系统可以将页面映射到物理内存中的任意位置,而不需要连续的物理内存空间。
- 内存保护:通过使用虚拟内存,操作系统可以为每个进程分配独立的地址空间,并对其进行保护。每个进程只能访问自己的地址空间,无法直接访问其他进程的地址空间。这提供了更好的安全性和隔离性。
- 内存共享:虚拟内存使得多个进程可以共享同一段内存,从而实现数据共享和进程间通信。多个进程可以将同一文件映射到各自的虚拟地址空间中,从而实现共享数据的访问。
- 虚拟内存交换:当物理内存不足时,操作系统可以将暂时不活跃的页面从物理内存交换到硬盘上的交换空间中。这样,空出的物理内存可以用于加载更需要的页面。这个过程称为页面置换。
堆和栈的区别,为什么既要有堆又要有栈
堆(Heap)和栈(Stack)是计算机内存中的两个主要区域,用于存储程序运行时所需的数据和指令。它们在分配和管理内存方面具有不同的特点和用途。
存储方式:
- 堆:堆是动态分配内存的一种方式,存储的是对象和数据结构,通过new关键字在堆上创建对象。堆的大小由程序运行时动态决定。
- 栈:栈是一种静态分配内存的方式,存储的是方法调用和局部变量。栈的大小在编译时就确定,由系统自动分配和管理(正是因为由系统分配和管理 所以需要在编译时就确定栈的大小以便进行静态内存分配)。
内存分配和回收:
- 堆:堆上的内存分配和回收由程序员手动管理。对象在堆上分配,需要手动释放内存,否则会造成内存泄漏。Java中,垃圾回收器负责自动回收不再使用的对象。
- 栈:栈的内存分配和回收是自动的,由系统在方法调用和返回时进行管理。局部变量的内存在方法执行期间分配,方法返回后自动释放。
存储方式和速度:
- 堆:堆的存储方式是链式存储结构,通过指针进行访问。由于堆的大小不固定,内存分配和回收的效率相对较低。
- 栈:栈的存储方式是顺序存储结构,通过栈指针进行访问。由于栈的大小固定且分配和回收自动完成,访问速度较快。
数据生命周期:
- 堆:堆上的数据生命周期可以比较长,直到程序显式释放或垃圾回收器回收对象。
- 栈:栈上的数据生命周期较短,随着方法的调用和返回而变化,局部变量的生命周期在方法执行期间。
为什么既要有堆又要有栈?
堆和栈的存在都有其特定的用途和优势:
- 堆:堆的动态分配特性使得它适用于存储大量的、生命周期较长的数据,如对象和数据结构。堆的灵活性使得程序可以动态地分配和释放内存,从而满足复杂的内存需求。
- 栈:栈的静态分配特性使得它适用于存储方法的调用和局部变量等具有较短生命周期的数据。栈的自动分配和释放机制使得程序员无需关心内存管理的细节,提高了编程的简洁性和效率。
通过堆和栈的组合使用,程序可以在运行时动态管理内存,同时保证了方法调用和局部变量的高效访问。这种灵活性和效率的结合使得程序能够更好地平衡内存的使用和性能的需求。
计算机网络
OSI七层网络模型,每一层有哪些协议
OSI七层网络模型是一种将计算机网络功能划分为不同层次的标准模型。每一层都有特定的功能和对应的协议。以下是每一层及其对应的协议:
物理层(Physical Layer)
负责传输比特流,提供物理介质传输的基本功能。
协议:Ethernet、RS-232、Fiber Channel等。
(Ethernet:Ethernet协议是一种用于局域网(LAN)的通信协议,它定义了在局域网中计算机之间的通信规则和数据传输方式。Ethernet协议基于CSMA/CD(Carrier Sense Multiple Access with Collision Detection)技术,即带有冲突检测的载波监听多路访问。它允许多台计算机共享同一物理传输介质(如双绞线或光纤)并进行数据传输)数据链路层(Data Link Layer)
负责将比特流组织成帧,并提供可靠的点对点数据传输。
协议:Ethernet、PPP(Point-to-Point Protocol)、HDLC(High-Level Data Link Control)等。网络层(Network Layer)
负责寻址和路由选择,将数据包从源节点传送到目标节点。
协议:IP(Internet Protocol)、ICMP(Internet Control Message Protocol)、ARP(Address Resolution Protocol)等。传输层(Transport Layer)
负责端到端的可靠数据传输和流量控制。
协议:TCP(Transmission Control Protocol)、UDP(User Datagram Protocol)、SCTP(Stream Control Transmission Protocol)等。会话层(Session Layer)
负责建立、管理和终止会话,提供会话层服务。
协议:SSH(Secure Shell)、RPC(Remote Procedure Call)等。表示层(Presentation Layer)
负责数据的格式转换、加密和压缩,提供数据表示和交换的格式。
协议:TLS(Transport Layer Security)、ASCII(American Standard Code for Information Interchange)等。
(会话层和表示层 目前用的很少了 这两个功能其实都已经被其他层所覆盖)
- 应用层(Application Layer)
负责应用程序之间的通信和交互,提供特定的应用服务。
协议:HTTP(Hypertext Transfer Protocol)、FTP(File Transfer Protocol)、SMTP(Simple Mail Transfer Protocol)等。
常见的网络设备有哪些?分别属于哪一层
常见的网络设备包括路由器、交换机、防火墙、网关和无线访问点等。
- 路由器(Router)是一种网络设备,位于网络的边缘,用于连接不同的网络并转发数据包。它根据目标IP地址来决定如何将数据包从一个网络传输到另一个网络,实现网络之间的互联和数据转发。路由器工作在网络层(第3层)。
- 交换机(Switch)是一种用于局域网内部的网络设备,用于在局域网内部不同设备之间进行数据的转发。交换机根据目标MAC地址来决定将数据包转发到哪个端口,实现局域网内部的数据交换和通信。交换机工作在数据链路层(第2层)。
- 防火墙(Firewall)是一种用于保护网络安全的设备,它通过对网络流量进行检查和过滤,控制进出网络的数据包。防火墙可以根据预先设定的安全策略来允许或阻止特定类型的网络流量,从而保护网络免受潜在的威胁。防火墙可以工作在网络层和传输层(第3层和第4层)。
- 网关(Gateway)是网络中连接两个不同网络的设备,可以是硬件设备或软件实现。网关可以将不同的网络协议进行转换,允许不同类型的网络之间进行通信和数据交换。网关通常工作在网络层(第3层)。
- 无线访问点(Wireless Access Point)是一种设备,用于提供无线网络连接。它允许无线设备(如笔记本电脑、智能手机)通过Wi-Fi连接到有线网络,并在局域网内部提供无线网络访问。无线访问点通常具有路由器和交换机的功能,可以工作在网络层和数据链路层(第2层和第3层)
为什么局域网 IP 通常以 192.168 开头
局域网IP通常以192.168开头是因为这个IP地址段被IANA(Internet Assigned Numbers Authority)指定为专门用于私有网络内部的地址范围。
私有IP地址是指在互联网上不可路由的IP地址,只在局域网内部使用。它们允许多个局域网在互联网上使用相同的IP地址范围,而不会产生冲突。
192.168.0.0至192.168.255.255是一个保留的私有IP地址范围,其中包含了65,536个可用的IP地址。这个地址段被广泛接受并用于许多家庭网络和小型企业的局域网。
浏览器输入网址的过程
当用户在浏览器中输入网址并按下回车键时,浏览器会执行以下步骤来获取并显示网页:
- 解析网址:浏览器会解析用户输入的网址,提取出协议(如HTTP、HTTPS)、域名和路径等信息。例如,从网址”https://www.example.com/index.html"中,浏览器会解析出协议为HTTPS,域名为www.example.com,路径为/index.html。
- DNS解析:浏览器将域名发送给DNS(Domain Name System)服务器,以获取对应的IP地址。DNS服务器负责将域名转换为IP地址,使浏览器能够与服务器进行通信。
- 建立TCP连接:浏览器使用HTTP或HTTPS协议与服务器建立TCP连接。TCP协议确保数据可靠传输,建立连接则需要进行三次握手。
- 发送HTTP请求:浏览器向服务器发送HTTP请求,请求包括HTTP方法(GET、POST等)、路径、头部信息(如User-Agent、Accept等)和其他相关参数。
- 服务器处理请求:服务器收到请求后,会根据请求的路径和参数执行相应的处理逻辑。这可能涉及数据库查询、文件读取、业务处理等操作。
- 服务器发送HTTP响应:服务器根据请求的处理结果生成HTTP响应,包括状态码、头部信息和响应体。状态码表示请求的处理结果,如200表示成功,404表示找不到资源等。
- 接收响应:浏览器接收到HTTP响应后,会对响应进行解析。如果响应是HTML页面,浏览器会解析HTML结构,并请求加载HTML中引用的其他资源,如CSS、JavaScript文件和图片等。
- 渲染页面:浏览器使用解析到的HTML、CSS和JavaScript等资源,将网页内容渲染到浏览器窗口中,显示给用户。
- 关闭连接:一旦页面加载完成,浏览器会关闭与服务器的TCP连接,释放资源。
以上是浏览器输入网址的基本过程,不同浏览器可能会有细微的差异,但整体流程大致相同。这个过程使得用户能够通过浏览器访问并浏览互联网上的各种网页。
TCP和UDP,TCP是怎么保证可靠性的?
TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种常见的传输层协议,用于在计算机网络中传输数据。
TCP是一种面向连接的协议,它提供可靠的、有序的数据传输。TCP使用三次握手建立连接,通过序列号和确认机制来保证数据的可靠传输。它还具有流量控制和拥塞控制机制,以避免网络拥塞和数据丢失。TCP适用于对数据完整性要求较高的应用,如文件传输、电子邮件和网页浏览。
UDP是一种无连接的协议,它提供不可靠的、无序的数据传输。UDP不需要建立连接,直接将数据报发送到目标地址。它没有序列号和确认机制,也没有流量控制和拥塞控制。UDP适用于对实时性要求较高的应用,如音频和视频传输、实时游戏等,因为它的低延迟和较小的开销。
相比之下,TCP提供了可靠性和有序性,但会带来更大的开销和延迟,适用于对数据完整性要求较高的场景。而UDP则更为轻量和快速,但在传输过程中可能会丢失、重复或乱序数据,适用于对实时性要求较高的场景
TCP是怎么保证可靠性的
TCP(Transmission Control Protocol)是一种面向连接的协议,它通过一系列的机制来保证数据的可靠传输。
- 应用数据的分割和序列化:TCP将应用层传递给它的数据进行分割,并为每个数据段分配一个序列号。这样可以确保数据能够按照正确的顺序传输,并且可以在接收端重新组装成完整的数据。
- 确认和重传:TCP使用确认机制来确保数据的可靠传输。接收端会向发送端发送确认消息,告知发送端已成功接收到数据。如果发送端在一定时间内没有收到确认消息,它会假定数据丢失,并重新发送该数据段。
- 滑动窗口:TCP使用滑动窗口机制来控制发送和接收数据的速率。发送端和接收端都有一个窗口大小的限制,发送端根据接收端的窗口大小来控制发送数据的数量,接收端根据自己的处理能力来控制接收数据的速率。
- 流量控制:TCP使用流量控制机制来控制发送端发送数据的速率,以避免接收端被过多的数据淹没。接收端可以通过发送窗口大小来告知发送端自己的处理能力,发送端会根据接收端的窗口大小来控制发送数据的数量。
- 拥塞控制:TCP使用拥塞控制机制来避免网络拥塞的发生。发送端和接收端都会根据网络的拥塞程度来调整自己的发送速率,以避免过多的数据造成网络拥塞。
TCP 3次握手 4次挥手
为什么TCP 第3次握手可以携带数据 但前2次不行?
TCP的第三次握手可以携带数据,而前两次握手不能携带数据的原因是因为TCP的连接是双向的。在第一次和第二次握手时,客户端和服务器只是交换了一些必要的连接建立信息,如序列号和标志位等,以确保彼此的通信能力。
在第三次握手时,客户端发送的ACK包实际上是对服务器的确认,表示客户端已收到服务器的SYN-ACK包,并且能够接收数据。此时,连接已经建立,双方都确认了彼此的通信能力。
因为连接已经建立,所以第三次握手可以携带数据。这是因为在第三次握手之后,双方已经同意了连接的建立,并且已经进行了一定的初始化工作,可以开始传输数据。因此,TCP的第三次握手可以携带数据,以便在连接建立后立即传输一些必要的信息或应用数据。
而前两次握手不能携带数据的原因是因为在建立连接之前,双方还没有彼此确认对方的通信能力和可靠性。在第一次和第二次握手时,只是进行了一些最基本的握手操作,用于初始化连接的参数和状态,还没有进行数据传输的准备。
总之,TCP的第三次握手可以携带数据,是因为在这一步之前,连接已经建立并确认了各自的通信能力。而前两次握手不能携带数据,是因为在这些步骤中,双方还没有达到可以进行数据传输的状态。
MySQL
事务是怎么实现的
事务是由 MySQL 的引擎来实现的 主要依靠日志和锁,我们常见的 InnoDB 引擎它是支持事务的。
事务具有4个特性ACID 主要是依靠日志和锁进行实现
持久性是通过 redo log (重做日志)来保证的(redo log 记录某个数据页做了什么修改);
原子性是通过 undo log(回滚日志) 来保证的;(undo log每次记录更新前的数据 一旦发生故障崩溃使用undo log 回滚事务)
隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
一致性则是通过持久性+原子性+隔离性来保证;
redo log 与 undo log的区别:
这两种日志是属于 InnoDB 存储引擎的日志,它们的区别在于:
- redo log 记录了此次事务「完成后」的数据状态,记录的是更新之后的值;
- undo log 记录了此次事务「开始前」的数据状态,记录的是更新之前的值;
索引是怎么实现的
通过B+树实现
介绍B+树,1000w数据需要几层B+树
由分支因子b决定 (分支因子即 一个B树节点可以含有的孩子个数)
每个节点可以容纳的键值对为m
记数据数量为 d
叶子节点数量 = d / m
高度 = logb(d/m) = logb(1000w/m)