1. IPV4 和 IPV6 的区别
回答:
IPv4和IPv6是两个版本的互联网协议,主要区别在于:
1. 地址长度和空间:IPv4使用32位地址,理论上约有43亿个地址,现已基本耗尽。IPv6使用128位地址,地址空间巨大,几乎不可能用完。
2. 地址表示:IPv4地址通常写作点分十进制(如192.168.1.1)。IPv6地址通常写作冒分十六进制(如2001:0db8:85a3:0000:0000:8a2e:0370:7334),并可以进行零压缩。
3. 报文头部:IPv6的报头是固定的40字节,比IPv4的20字节(不含选项)要长,但移除了不必要的字段并采用扩展头的形式,使得路由器处理效率更高。
4. 地址配置:IPv6支持无状态地址自动配置(SLAAC),无需DHCP服务器即可自动配置IP地址,简化了网络管理。
5. 安全性:IPv6在设计上就强制要求支持IPSec,提供了网络层的端到端安全,而IPv4中IPSec是可选的。
6. 路由和网络:IPv6取消了广播,改用更高效的组播和任播。其简化的报头也使得路由器的转发效率更高。
---
2. TCP 的拥塞控制与流量控制的功能和区别比较 TCP 与 UDP
回答:
拥塞控制 vs 流量控制:
- 流量控制(Flow Control):是一个端到端的问题。它确保发送方发送数据的速率不会超过接收方处理数据的能力,防止接收方缓冲区溢出。这是通过接收方通告的滑动窗口大小(rwnd)来实现的。
- 拥塞控制(Congestion Control):是一个全局性问题。它防止过多的数据注入到网络中,导致网络中的路由器或链路过载。这是发送方通过感知网络状况(如丢包、延迟)来动态调整其发送速率实现的,主要算法包括慢启动、拥塞避免、快重传和快恢复。
区别:
- 作用对象不同:流量控制关心的是“接收方”的承受能力,拥塞控制关心的是“网络”的承受能力。
- 实现方式不同:流量控制由接收方的窗口大小决定,拥塞控制由发送方根据网络状况动态调整的拥塞窗口(cwnd)决定。发送方的实际发送窗口取min(rwnd, cwnd)。
TCP vs UDP:
- TCP (Transmission Control Protocol):
- 连接性:面向连接的。通信前必须建立连接(三次握手)。
- 可靠性:可靠的。通过序列号、确认应答、重传机制保证数据不丢、不重、不乱。
- 数据形式:面向字节流。数据没有明显的边界。
- 控制:有流量控制和拥塞控制。
- 速度:相对较慢,开销较大。
- 应用场景:要求高可靠性的应用,如HTTP网页浏览、FTP文件传输、Email。
- UDP (User Datagram Protocol):
- 连接性:无连接的。随时可以发送数据。
- 可靠性:不可靠的。尽最大努力交付,不保证数据到达。
- 数据形式:面向报文。每个数据报都是独立的,有边界。
- 控制:没有流量控制和拥塞控制。
- 速度:快,开销小。
- 应用场景:对实时性要求高、能容忍少量丢包的应用,如DNS查询、视频直播、在线游戏。
---
3. 集线器,路由器和交换机有什么区别
回答:
这三者是不同网络层次的设备,主要区别如下:
- 集线器(Hub):
- 工作层次:物理层(OSI第1层)。
- 工作原理:对接收到的信号进行放大和整形,然后广播到所有其他端口。它不识别MAC地址或IP地址。
- 冲突域:所有连接到集线器的设备都在同一个冲突域和广播域中,容易产生网络风暴和冲突,效率低下。
- 交换机(Switch):
- 工作层次:数据链路层(OSI第2层)。
- 工作原理:内部维护一张MAC地址表。它能识别数据帧中的源和目的MAC地址,只将数据帧转发到目的MAC地址所在的端口,实现了点对点通信。
- 冲突域:每个端口都是一个独立的冲突域,大大减少了冲突。但所有端口仍在一个广播域内。
- 路由器(Router):
- 工作层次:网络层(OSI第3层)。
- 工作原理:根据IP地址进行路径选择和数据包转发。它连接不同的网络(如LAN与WAN),并隔离广播域。
- 冲突域/广播域:每个端口连接一个独立的广播域和冲突域。路由器的主要功能是实现不同网络之间的通信。
总结:集线器是广播,交换机是基于MAC地址的智能转发,路由器是基于IP地址的跨网络寻址。
---
4. ARP 协议的过程
回答:
ARP(Address Resolution Protocol,地址解析协议)的作用是将一个已知的IP地址解析为对应的MAC地址。过程如下:
1. 检查缓存:主机A想给同一局域网内的主机B(IP地址为IP_B)发送数据。主机A首先会检查自己的ARP缓存表,看是否存在IP_B对应的MAC地址。
2. 发送ARP请求:如果缓存中没有找到,主机A会构建一个ARP请求报文,该报文包含:
- 源IP地址:IP_A
- 源MAC地址:MAC_A
- 目的IP地址:IP_B
- 目的MAC地址:00:00:00:00:00:00 (广播地址)
然后,主机A将此ARP请求报文在局域网内进行广播。
3. 网络中主机响应:局域网内所有主机都会收到这个广播。
- 其他主机(如主机C)发现目的IP地址不是自己的,会丢弃该报文。
- 主机B发现目的IP地址是自己的,就会响应该请求。
4. 发送ARP响应:主机B构建一个ARP响应报文,该报文包含:
- 源IP地址:IP_B
- 源MAC地址:MAC_B
- 目的IP地址:IP_A
- 目的MAC地址:MAC_A
然后,主机B将此ARP响应报文以单播的方式发送给主机A。
5. 更新缓存并发送数据:主机A收到ARP响应后,会将IP_B和MAC_B的映射关系存入自己的ARP缓存表,并用获取到的MAC_B作为目的MAC地址封装数据帧,发送给主机B。
---
5. P2P 网络编程的特点
回答:
P2P(Peer-to-Peer)网络编程的特点主要体现在其去中心化的结构上:
1. 去中心化:网络中没有中心服务器,所有节点(Peer)的地位都是对等的,既是客户端(请求服务)也是服务器(提供服务)。
2. 可扩展性好:随着节点数量的增加,整个系统的服务能力和资源也会相应增加,不会像C/S架构那样因服务器瓶颈而限制扩展。
3. 健壮性高:网络中不存在单点故障。单个或部分节点的离线不会导致整个系统瘫痪。
4. 负载均衡:任务和资源分布在各个节点上,自然地实现了负载均衡。
5. 资源利用率高:可以充分利用网络中闲置的计算、存储和带宽资源。
6. 隐私和安全问题:由于其开放和分布式的特性,P2P网络在数据安全、版权保护和节点身份认证方面面临更大的挑战。
---
6. DNS 的递归查询与迭代查询
回答:
DNS查询分为递归查询和迭代查询,这两种方式描述了DNS服务器之间如何协同工作来解析域名。
- 递归查询 (Recursive Query):
- 过程:客户端向本地DNS服务器发起查询请求,本地DNS服务器必须返回最终的查询结果(IP地址或“查询不到”)。如果本地DNS服务器没有缓存,它会代替客户端去向其他DNS服务器(根、顶级域、权威DNS)进行查询,直到得到结果再返回给客户端。
- 特点:“你帮我查,给我最终结果就行”。客户端只用发起一次请求。
- 典型场景:客户端主机到本地DNS服务器的查询。
- 迭代查询 (Iterative Query):
- 过程:DNS服务器向另一个DNS服务器发起查询,如果对方没有权威答案,它会返回一个“我不知道,但你可以去问XXX”的线索(另一个DNS服务器的地址)。发起查询的服务器必须自己再去向这个新的服务器发起查询,如此循环往复,直到找到权威DNS服务器并获得结果。
- 特点:“我问你,你不知道就告诉我下一步该问谁”。服务器需要多次发起请求。
- 典型场景:本地DNS服务器到根、顶级域、权威DNS服务器之间的查询。
---
7. 校验和检验出来是对的,能不能确定没发生 bit 错误?dma 发生了什么?讲一下网络嗅探
回答:
1. 校验和(Checksum)
不能100%确定没有发生bit错误。校验和是一种差错检测机制,但它不是完美的。
- 原理:发送方将数据包中的数据按一定位数(如16位)分段,然后对所有段进行反码求和,将结果存放在校验和字段。接收方用同样方法计算,如果结果一致,则认为数据没有出错。
- 局限性:如果数据在传输过程中发生了“偶数个”位的反转,且这些反转恰好相互抵消(例如,一个1变为0,另一个0变为1,或者两个不同的16位字段中,一个加1,另一个减1),计算出的校验和可能依然是正确的。所以,校验和正确只能说明数据“大概率”没有出错,但不能完全排除错误的可能性。
2. DMA(Direct Memory Access,直接内存访问)
DMA是允许外部硬件设备(如网卡、硬盘控制器)直接与主内存进行数据交换,而无需CPU介入的一种机制。
- 在网络中的作用:当网卡接收到数据包时,它可以触发DMA控制器,将数据包从网卡的缓冲区直接拷贝到内存中指定的位置。同样,当要发送数据包时,CPU准备好数据后,可以命令DMA控制器将数据从内存直接拷贝到网卡的发送缓冲区。
- 好处:这个过程极大地减轻了CPU的负担。如果没有DMA,CPU需要亲自执行每一次从设备到内存或从内存到设备的拷贝操作,这将耗费大量的CPU周期。DMA使得CPU可以去做其他计算任务,提高了系统整体效率。
3. 网络嗅探(Network Sniffing)
网络嗅探是指在网络上捕获、监视和分析数据包的技术。
- 原理:通过将网卡设置为“混杂模式”(Promiscuous Mode),网卡会接收所有流经它的数据包,而不仅仅是发给它自己的数据包。嗅探软件(如Wireshark、tcpdump)就是利用这个模式来抓取网络流量。
- 用途:
- 合法用途:网络管理员用于网络故障排查、性能分析、安全监控。
- 非法用途:黑客用于窃取敏感信息,如未加密的用户名、密码、邮件内容等。
---
8. 网络协议的三个核心要素及概念,各起什么作用?什么是网络延时
回答:
网络协议的三个核心要素:
1. 语法(Syntax):定义了数据与控制信息的结构或格式。规定了通信双方交换的信息的种类、格式、顺序以及各个字段的含义。例如,IP数据报的头部格式就是一个语法规则。
2. 语义(Semantics):定义了需要发出何种控制信息,完成何种动作以及做出何种应答。它解释了语法元素的含义,规定了通信双方的行为和要执行的操作。例如,HTTP协议中GET请求的语义就是“获取一个资源”。
3. 时序(Timing):也称为同步,定义了事件实现顺序的详细说明。它规定了通信双方的速度匹配和排序关系。例如,TCP的三次握手就是对连接建立过程中的时序进行了严格规定。
什么是网络延时(Latency)
网络延时是指一个数据包从发送端发送,到它成功被接收端接收所需要的时间。它由以下几个部分组成:
1. 发送/传输时延:数据包从主机或路由器发送到链路上的时间。时延 = 数据包大小 / 带宽。
2. 传播时延:信号在物理介质(如光纤、铜缆)中传播所需的时间。时延 = 链路长度 / 传播速度。
3. 处理时延:路由器或主机接收到数据包后,进行差错校验、查找转发表、决定输出链路等操作所需的时间。
4. 排队时延:数据包在路由器输出队列中等待被发送到链路上的时间。这个时延取决于网络的拥塞程度。
总延时 = 发送时延 + 传播时延 + 处理时延 + 排队时延
---
9. 点对点和端到端工作在哪层?工作机制网络时延由哪几部分组成?各产生于何处TCP的拥塞控制与流量控制的功能和区别
回答:
点对点和端到端:
- 点对点(Point-to-Point):主要工作在**数据链路层(第2层)**。它描述的是相邻两个直接连接的节点之间的通信。数据链路层的协议(如PPP, Ethernet)负责将网络层的数据包封装成帧,在两个相邻节点之间可靠或不可靠地传输。
- 端到端(End-to-End):主要工作在**传输层(第4层)和应用层(第7层)**。它描述的是源主机和目的主机之间的通信,中间可能经过多个路由器。传输层协议(如TCP, UDP)负责为两台主机上的应用程序提供通信服务,例如分段、重组、差错控制等。
工作机制:
- 点对点:通过MAC地址寻址,在单一链路(如一段网线或一个交换机连接)上进行帧的传输。
- 端到端:通过IP地址和端口号,在整个互联网上定位到具体的应用程序,并建立逻辑上的连接。
网络时延的组成部分(已在上一题回答):
1. 发送时延:产生于主机或路由器的网络接口,与数据包大小和带宽有关。
2. 传播时延:产生于物理链路,与距离和介质有关。
3. 处理时延:产生于路由器和主机内部,与设备性能有关。
4. 排队时延:产生于路由器的输出队列,与网络拥塞程度有关。
TCP的拥塞控制与流量控制的功能和区别(已在第2题回答)。
---
10. 发送序号和确认序号的作用
回答:
发送序号(Sequence Number)和确认序号(Acknowledgement Number)是TCP协议实现可靠数据传输的两个核心机制。
- 发送序号 (Sequence Number, SEQ):
- 作用:
1. 数据排序:由于网络传输可能导致数据包乱序,接收方可以根据SEQ对数据包进行重新排序,恢复成原始的数据流。
2. 重复数据检测:接收方可以根据SEQ识别并丢弃重复接收的数据包。
- 机制:在TCP连接中,通信双方各自维护一个发送序号。SEQ字段指的是本次发送的数据的第一个字节在整个字节流中的序号。
- 确认序号 (Acknowledgement Number, ACK):
- 作用:
1. 确认接收:ACK用于告知发送方,哪些数据已经被成功接收。
2. 请求数据:ACK的值是“期望收到的下一个字节的序号”。例如,如果接收方发送的ACK为N,则表示序号N-1之前的所有数据都已成功收到,并请求发送方从序号N开始发送数据。
- 机制:ACK只有在ACK标志位为1时才有效。通过ACK机制,TCP实现了可靠的、累积的确认。
---
11. 回退 N 帧滑动窗口跟 CR 协议的区别
回答:
这里您可能指的是**选择重传协议(Selective Repeat, SR)**,而不是CR。我将比较回退N帧(Go-Back-N, GBN)和选择重传(SR)。
- 回退N帧协议 (Go-Back-N, GBN):
- 发送窗口:发送窗口大小可以大于1。
- 接收窗口:接收窗口大小恒等于1。
- 确认机制:采用累积确认。接收方只按序接收数据帧,如果收到了一个失序的帧(例如,收到了帧5,但还在等帧4),则会丢弃该帧并重新发送对最后一个按序收到的帧的确认。
- 重传机制:当发送方发生超时或收到重复的ACK时,它会重传所有已发送但未被确认的帧(从出错的那个帧开始)。
- 优点:接收方逻辑简单,无需缓存失序帧。
- 缺点:当网络丢包率高时,重传效率低,因为一个错误会导致大量正确的帧也被重传。
- 选择重传协议 (Selective Repeat, SR):
- 发送窗口:发送窗口大小可以大于1。
- 接收窗口:接收窗口大小也大于1,通常等于发送窗口大小。
- 确认机制:对每个正确接收的帧进行单独确认。接收方会缓存失序到达的正确帧。
- 重传机制:当发送方发生超时时,它只重传那个未被确认的、超时的帧。
- 优点:重传效率高,只重传真正丢失的帧,信道利用率高。
- 缺点:接收方需要更大的缓存和更复杂的逻辑来管理失序的帧。
总结区别:GBN的接收窗口为1,采用累积确认,重传时回退N帧;SR的接收窗口大于1,采用逐个确认,只重传丢失的帧。
---
12. 交换机的工作方式有哪些,区别是什么 MAC 地址和 IP 地址
回答:
交换机的工作方式(学习、转发、过滤、泛洪):
1. 学习(Learning):交换机通过检查流入帧的源MAC地址来建立和维护其内部的MAC地址表。它会将源MAC地址和接收该帧的端口号关联起来,记录在表中。
2. 转发(Forwarding):当交换机收到一个数据帧时,它会查看帧的目的MAC地址。然后在MAC地址表中查找这个地址。如果找到了对应的端口,并且该端口不是源端口,交换机就会将该帧只从这个目标端口发送出去。
3. 过滤(Filtering):如果交换机在MAC地址表中查找到目的MAC地址,并且发现其对应的端口就是该数据帧的来源端口,那么交换机就会将该帧丢弃(过滤掉),因为目标设备和源设备在同一个网段,无需转发。
4. 泛洪(Flooding):如果目的MAC地址在MAC地址表中找不到(未知单播),或者目的MAC地址是广播地址(FF:FF:FF:FF:FF:FF),交换机就会将该帧向除了源端口之外的所有其他端口进行广播(泛洪)。
区别是什么 MAC 地址和 IP 地址
- MAC地址 (Media Access Control Address):
- 层次:工作在数据链路层(第2层)。
- 作用:在局域网(LAN)内唯一标识一个网络接口(网卡)。用于在同一广播域内的设备之间进行寻址。
- 格式:48位,通常表示为6组十六进制数,如 00-1A-2B-3C-4D-5E。
- 特性:物理地址,通常由硬件制造商在生产时固化在网卡上,理论上是全球唯一的。
- IP地址 (Internet Protocol Address):
- 层次:工作在网络层(第3层)。
- 作用:在整个互联网范围内唯一标识一台主机或网络设备。用于在不同网络之间进行寻址和路由。
- 格式:IPv4是32位,表示为点分十进制;IPv6是128位,表示为冒分十六进制。
- 特性:逻辑地址,由网络管理员分配,可以改变。它具有网络号和主机号两部分,体现了网络拓扑结构。
关系:IP地址用于跨网络寻址,找到目标网络;MAC地址用于在目标网络内部(局域网)找到具体的设备。数据传输时,IP地址(逻辑寻址)和MAC地址(物理寻址)协同工作,通过ARP协议进行转换。
---
13. 假设网络中的计算机和路由器一切正常,是否有可能一个数据包本该发往 A 却发往了 B,为什么?
回答:
是的,有可能。最常见的原因是 **ARP 欺骗(ARP Spoofing)**或称为 **ARP 缓存中毒(ARP Cache Poisoning)**。
为什么:
在一个局域网中,当一台主机(例如发送方 S)想要发送数据给另一台主机(目标 A)时,它需要知道目标 A 的 MAC 地址。这个 IP 到 MAC 的映射关系是通过 ARP 协议获取并存储在 ARP 缓存中的。
1. 攻击者介入:一个攻击者(主机 B 或 C)可以向发送方 S 发送一个伪造的 ARP 响应报文。
2. 伪造信息:这个伪造的报文声称“主机 A 的 IP 地址对应的 MAC 地址是我的(攻击者的)MAC 地址”。
3. 缓存中毒:发送方 S 信任了这个伪造的响应,并用这个错误的映射关系(IP_A -> MAC_Attacker)更新或覆盖了自己的 ARP 缓存。
4. 数据包重定向:此后,当 S 要发送数据包给 A 时,它会从 ARP 缓存中查找 IP_A,得到的是攻击者的 MAC 地址。于是,它将数据包封装在一个目标 MAC 地址为攻击者 MAC 的数据帧中。网络中的交换机会根据这个 MAC 地址,将数据帧正确地转发给攻击者,而不是预期的目标 A。
在这个过程中,所有的计算机、路由器和协议本身都在“正常”工作,但它们所依赖的数据(ARP 缓存)被恶意篡改了,导致了数据包的错误转发。
---
14. 传统子网掩码和 CIDR 的区别
回答:
主要区别在于对 IP 地址的划分方式,CIDR 是对传统方式的改进,更加灵活高效。
- 传统子网掩码(Classful Addressing):
- 基于分类:IP 地址被预先划分为 A、B、C、D、E 五类。A、B、C 类有固定的网络位和主机位(A类8位网络位,B类16位,C类24位)。
- 掩码作用:子网掩码用于在固定的分类网络内部再划分出更小的子网,但不能跨越类别边界。
- 缺点:非常不灵活,容易造成大量的 IP 地址浪费。例如,一个需要 300 个地址的组织必须申请一个 B 类地址(65534个主机位),会浪费掉绝大多数地址。
- CIDR (Classless Inter-Domain Routing, 无类域间路由):
- 无类别:废除了 A、B、C 类的概念,IP 地址被看作是一个连续的地址空间。
- 可变长子网掩码 (VLSM):使用“前缀长度”表示法(如 /24)来指定网络部分的位数,前缀可以是任意长度(1-32)。
- 优点:
1. 灵活性和地址利用率:可以根据实际需求精确分配任意大小的地址块,极大地减少了 IP 地址的浪费。
2. 路由聚合(超网):可以将多个小的连续网络地址块聚合成一个大的地址块(如将8个 /24 的网络聚合成一个 /21 的路由),这大大减少了全球互联网路由表的大小,提高了路由效率。
总结:传统方式是固定的、有类的、浪费的;CIDR 是灵活的、无类的、高效的,并且支持路由聚合。
---
15. 以太网组成广播域,网络变大会出现什么问题?怎么解决
回答:
当一个由以太网(主要通过交换机连接)组成的广播域变得非常大时,会出现以下问题:
1. 广播风暴 (Broadcast Storm):网络中的设备会发送广播帧(如 ARP 请求、DHCP 请求)。在大型网络中,设备数量众多,大量的广播帧会充斥整个网络,消耗掉巨大的网络带宽。
2. 性能下降:网络中的每台主机都需要花费 CPU 资源来处理接收到的每一个广播帧,即使这个广播帧与自己无关。当广播流量过大时,会严重影响主机的性能。
3. 安全问题:广播域内的任何设备都可以轻易地监听到其他设备的通信(如通过 ARP 欺骗),增大了安全风险。
4. 管理困难:单一巨大的广播域使得网络结构不清晰,故障排查和网络管理变得非常困难。
解决方法:
核心思想是**分割广播域**。
1. 使用路由器 (Router):路由器是分割广播域最基本和最有效的方式。路由器的每个接口都连接一个独立的广播域,它默认不会转发广播包。
2. 划分 VLAN (Virtual LAN, 虚拟局域网):在交换机上配置 VLAN 是现代网络中最常用的方法。VLAN 可以在逻辑上将一个物理的局域网划分为多个独立的广播域。不同 VLAN 之间的通信需要通过三层设备(如三层交换机或路由器)进行路由。这样既实现了广播域的隔离,又保持了物理连接的灵活性。
---
16. 有的视频运营商用 tcp 而不是 udp,为什么?
回答:
虽然 UDP 因其低延迟和无连接的特性通常被认为是视频直播和实时通信的首选,但在某些场景下,视频运营商选择 TCP 是基于以下考虑:
1. 可靠性需求:对于非实时的视频点播(VOD)服务,如观看 YouTube、Netflix 等,用户体验更看重画面的完整和清晰,而不是极低的延迟。TCP 的可靠传输机制能确保视频数据块无差错、按顺序地到达,避免了花屏、卡顿等问题。
2. 穿越防火墙和 NAT:TCP 使用的知名端口(如 HTTP 的 80 端口和 HTTPS 的 443 端口)几乎被所有网络防火墙所允许。而 UDP 流量,尤其是使用非标准端口的,很容易被防火墙或 NAT 设备阻止。使用基于 HTTP 的流媒体协议(如 HLS、DASH)可以方便地利用现有网络基础设施。
3. 利用现有的 Web 生态系统:现代许多视频服务都构建在 HTTP 协议之上。这些协议(如 HLS、MPEG-DASH)将视频切分成小的文件块(TS 文件或 MP4 文件),客户端通过标准的 HTTP GET 请求来下载这些文件块。这种方式可以充分利用现有的 CDN 网络、Web 服务器和缓存技术,易于部署和扩展。
4. 自适应比特率流 (Adaptive Bitrate Streaming):基于 TCP/HTTP 的流媒体协议能够轻松实现自适应码率。客户端可以根据测量的网络带宽(TCP 的拥塞控制机制可以提供相关信息)来动态选择请求最高质量的视频分片,从而在不同的网络条件下提供最流畅的观看体验。
---
17. tcp 初始序号为何随机
回答:
TCP 的初始序列号(Initial Sequence Number, ISN)是随机生成的,主要目的是为了**网络安全**,防止 **TCP 序列号预测攻击 (TCP Sequence Prediction Attack)**。
攻击原理:
如果 ISN 是一个固定的或者可预测的数值(例如从0开始),攻击者就可以轻易地预测出 TCP 连接中的后续序列号。这样,攻击者就可以:
1. 伪造连接:攻击者可以伪造一个源 IP 地址为可信主机 A 的 TCP 段,并准确地预测出服务器 B 期望收到的序列号,从而冒充 A 与 B 建立连接或劫持现有的连接。
2. 注入恶意数据:在 A 和 B 的一个已建立的连接中,攻击者可以伪造一个来自 A 的数据包,只要序列号落在 B 的接收窗口内,B 就会接收这个恶意数据包,导致连接中断或数据被篡改。
随机化的作用:
通过让 ISN 在一个巨大的范围内(通常是 32 位,约 40 亿)随机生成,攻击者几乎不可能在短时间内猜中合法的序列号。这大大增加了伪造和劫持 TCP 连接的难度,从而保护了 TCP 通信的安全性。
---
18. mtu 是什么解释一下
回答:
MTU(Maximum Transmission Unit,最大传输单元)指的是网络层(OSI 第三层)所能传输的数据报(Packet)的最大长度,单位是字节。它规定了在一个数据链路(如以太网)上单次能够传输的最大数据包大小。
- 作用:MTU 的存在是为了匹配数据链路层的限制。例如,标准的以太网数据链路层(OSI 第二层)的帧(Frame)有最大长度限制,其数据载荷部分(Payload)最大为 1500 字节。因此,连接到以太网的设备的 IP 层 MTU 通常被设置为 1500 字节。
- IP 分片 (IP Fragmentation):如果要传输的 IP 数据报的大小超过了出接口所在链路的 MTU,路由器就会对该数据报进行**分片**。它会将原始数据报分割成多个较小的数据报,使得每个分片的大小都不超过 MTU,然后在每个分片上都加上 IP 头部,再进行传输。最终,这些分片会在目的主机被重新组装。
- 影响:
- 效率:设置过小的 MTU 会导致每个数据包的头部开销占比过大,降低传输效率。
- 性能:IP 分片和重组会消耗路由器和目的主机的 CPU 资源,并可能增加丢包的风险(一个分片丢失会导致整个原始数据包丢失)。因此,在网络通信中应尽量避免分片,这一过程也称为 **路径 MTU 发现 (Path MTU Discovery, PMTUD)**。
---
19. 简述一下 windows 下的 tracert
回答:
tracert(Trace Route)是 Windows 系统下的一个命令行网络诊断工具,用于追踪一个数据包从源主机到目的主机所经过的路由器路径。
工作原理:
tracert 的工作原理基于 IP 协议头中的 TTL (Time To Live) 字段和 ICMP (Internet Control Message Protocol) 协议。
1. 发送探测包:
- tracert 首先向目标主机发送一个 UDP 包(在 Linux/Unix 下的 traceroute 通常使用 UDP,而 Windows 的 tracert 使用 ICMP Echo 请求),并将该数据包的 TTL 值设为 1。
2. 第一跳响应:
- 数据包到达路径上的第一个路由器时,该路由器会将 TTL 值减 1。此时 TTL 变为 0。
- 根据 IP 协议规定,TTL 为 0 的数据包不能再被转发,必须被丢弃。同时,该路由器会向源主机发送一个 ICMP "Time Exceeded" (超时) 消息,消息中包含了该路由器的 IP 地址。
3. 记录并增加 TTL:
- 源主机收到这个 ICMP 超时消息后,就知道了路径上第一个路由器的地址,并记录下往返时间。
- 接着,tracert 会发送第二个探测包,并将 TTL 值设为 2。
4. 后续跳响应:
- 这个数据包会成功通过第一个路由器(TTL 减为 1),但在到达第二个路由器时,TTL 会变为 0。第二个路由器同样会返回一个 ICMP 超时消息。
5. 循环往复:
- tracert 重复这个过程,每次将 TTL 值加 1,直到数据包最终到达目的主机。
6. 到达目的地:
- 当数据包到达目的主机时,由于端口未开放(UDP)或收到了 Echo 请求(ICMP),目的主机不会因为 TTL 超时而丢弃包,而是会返回一个 ICMP "Port Unreachable" (端口不可达) 或 ICMP "Echo Reply" (回显应答) 消息。
- 当源主机收到这个消息时,就知道追踪过程已经完成。
通过这个过程,tracert 就能按顺序列出数据包从源到目的所经过的每一跳路由器的 IP 地址以及每次探测的往返时间。
---
20. tcp 四次挥手,等待 2 倍报文传送时间的原因
回答:
在 TCP 四次挥手的最后阶段,主动关闭连接的一方(假设为 A)在发送了最后一个 ACK 确认报文后,会进入 TIME_WAIT 状态,并等待 2 倍的 MSL(Maximum Segment Lifetime,报文最大生存时间)。这主要是基于两个原因:
1. 保证被动关闭方能可靠地接收到最后的 ACK:
- A 发送的最后一个 ACK 报文可能会在网络中丢失。
- 如果这个 ACK 丢失,被动关闭方 B 在发送了 FIN 报文后会收不到确认,于是会触发超时重传机制,重新向 A 发送 FIN 报文。
- 如果 A 发完 ACK 后立即关闭连接,它将无法接收到 B 重传的 FIN,也不会做出任何响应。这会导致 B 无法正常关闭连接。
- 通过维持 TIME_WAIT 状态,A 可以确保在此期间如果再次收到 B 的 FIN,能够重新发送一次 ACK,帮助 B 正常关闭。2MSL 的时间足以让一个 FIN 报文及其对应的 ACK 报文在网络中往返。
2. 防止“已失效的连接请求报文段”出现在本连接中:
- MSL 是网络中任何报文段能存在的最长时间。超过这个时间,报文段将被丢弃。
- 等待 2MSL 可以确保本次连接中产生的所有报文段都已从网络中消失。
- 这样,当稍后在相同的套接字(源IP、源端口、目的IP、目的端口)上建立一个新的连接时,不会收到旧连接中延迟到达的、已经失效的报文段,从而避免了数据混乱。
---
21. tcp 没有第三次握手,会不死锁
回答:
如果 TCP 连接建立只有两次握手,不会导致“死锁”,但会引发严重的问题,主要是**资源浪费**和**连接可靠性**问题。
场景描述(两次握手的问题):
1. 客户端 A 向服务器 B 发送一个 SYN 连接请求报文。
2. 这个 SYN 报文由于网络拥堵,在某个节点滞留了很长时间,没有及时到达 B。
3. A 因为超时,重传了一个新的 SYN 报文。
4. 这个新的 SYN 成功到达 B,B 回复 SYN+ACK,然后 A 和 B 正常建立连接、传输数据、最后断开连接。
5. 此时,那个之前滞留在网络中的、早已失效的 SYN 报文终于到达了服务器 B。
问题出现:
- 在两次握手的模型下,服务器 B 收到这个失效的 SYN 后,会误认为 A 又发起了一个新的连接请求。
- B 会立即为这个“新连接”分配资源(如内存、文件句柄等),并向 A 发送 SYN+ACK 报文,然后进入 ESTABLISHED 状态,等待 A 发送数据。
- 但是,客户端 A 此时根本没有发起新连接的意图,它会忽略或丢弃这个来自 B 的 SYN+ACK 报文。
- 结果就是,服务器 B 单方面地建立了一个连接,并一直空等着,白白浪费了服务器资源,直到超时后才关闭。如果大量这种失效的 SYN 到达服务器,会迅速耗尽服务器资源,导致其无法为正常的用户提供服务,这也就是一种 SYN 泛洪攻击 (SYN Flood) 的雏形。
三次握手如何解决:
有了第三次握手,服务器 B 在发送 SYN+ACK 后会进入 SYN_RCVD 状态,而不是直接 ESTABLISHED。它必须收到客户端 A 的第三次握手报文(ACK)后,才能确认客户端确实收到了自己的响应,并真正建立连接。在上述场景中,B 收不到 A 的 ACK,就会在超时后释放为该连接分配的资源,从而避免了资源浪费。
---
22. 什么是 web 缓存
回答:
Web 缓存是一种用于临时存储(缓存)Web 文档(如 HTML 页面、图片、CSS、JS 文件等)的技术,目的是为了减少网络延迟、降低带宽消耗和减轻源服务器的负载。当用户请求一个资源时,请求可以由就近的缓存服务器来响应,而不是直接从源服务器获取。
Web 缓存的主要类型:
1. 浏览器缓存 (Browser Cache):
- 存储在用户个人电脑的硬盘或内存中。当用户访问一个网站后,浏览器会将一些静态资源存储起来。当用户再次访问该网站时,浏览器可以直接从本地加载这些资源,无需再次请求服务器,速度最快。
2. 代理缓存 (Proxy Cache):
- 位于客户端和源服务器之间的一个服务器。它可以被多个用户共享。例如,一个公司或 ISP 可能会部署一个代理缓存服务器。当一个用户请求某个资源时,代理缓存会保存一份副本。之后,该公司或该 ISP 内的其他用户请求相同资源时,就可以直接从代理缓存获取。
3. 网关缓存 (Gateway Cache) / 反向代理缓存 (Reverse Proxy Cache):
- 也称为 CDN (Content Delivery Network)。它部署在源服务器端或网络中的关键节点,由网站所有者控制。它缓存了源服务器内容的副本。当用户请求时,请求会被导向地理位置上离用户最近的 CDN 节点,由该节点提供缓存的内容。这极大地加快了全球用户的访问速度,并保护了源服务器。
工作原理:
缓存的工作依赖于 HTTP 头部信息,如 Cache-Control, Expires, Last-Modified, ETag 等。服务器通过这些头部告诉客户端或代理服务器该资源是否可以被缓存、能缓存多久。当缓存过期后,客户端会向服务器发起验证请求,如果资源未改变,服务器会返回 304 Not Modified 状态码,客户端继续使用本地缓存,只传输了很小的头部信息。
---
23. 组合逻辑控制器和微程序控制器的区别
回答:
组合逻辑控制器和微程序控制器是计算机组成原理中实现CPU控制器(Control Unit, CU)的两种不同方式。它们的主要区别在于控制信号的产生方式和设计思想。
- 组合逻辑控制器 (Hardwired Controller):
- 原理:控制信号是由一个纯粹的硬件逻辑电路(通常由门电路和触发器组成)根据当前的指令码、时钟信号和状态标志直接产生的。整个控制器是一个复杂的组合逻辑网络。
- 特点:
- 速度快:因为是纯硬件实现,没有取指和译码微指令的过程,执行速度非常快。
- 设计复杂:对于复杂指令系统(CISC),设计和实现这样的逻辑电路非常困难和复杂。
- 难以修改和扩展:一旦设计完成,如果需要增加或修改一条指令,几乎需要重新设计整个控制器。
- 应用:主要用于指令系统比较简单的精简指令集计算机(RISC)中,例如 ARM、MIPS 架构的 CPU。
- 微程序控制器 (Microprogrammed Controller):
- 原理:将每一条机器指令的功能分解成一系列最基本的操作,这些基本操作称为“微操作”,由“微命令”来控制。将一组实现特定功能的微命令序列(即一条机器指令的执行流程)编写成“微程序”,并存放在一个专门的存储器——**控制存储器 (Control Store)** 中。控制器工作时,根据当前机器指令的地址,从控制存储器中取出对应的微指令,并根据微指令中的信息产生相应的控制信号。
- 特点:
- 设计规整、简单:将复杂的硬件逻辑问题转化为相对简单的微程序编写问题,设计思路清晰,易于实现。
- 灵活、易于修改和扩展:增加或修改一条指令,只需要在控制存储器中增加或修改一段微程序即可,无需改动硬件电路。
- 速度较慢:相比组合逻辑控制器,它需要从控制存储器中读取微指令,多了一级访存操作,因此速度较慢。
- 应用:主要用于指令系统比较复杂的复杂指令集计算机(CISC)中,例如 Intel x86 架构的 CPU。
总结:组合逻辑控制器是“硬连线”的,速度快但设计复杂且不灵活;微程序控制器是“存储程序”的,设计简单灵活但速度稍慢。
---
24. 解释 tcp 头部字节 URG\ACK\PSH\RST\FIN 的其中三个
回答:
TCP 头部中包含一个 6 位的控制字段(Flags),用于表示 TCP 段的特定状态或功能。以下是其中三个常见标志位的解释:
1. ACK (Acknowledgement):
- 含义:确认位。
- 作用:当 ACK=1 时,TCP 头部中的“确认序号”字段才有效。这个标志位用来告知对方,我已经成功收到了你发送的数据。在 TCP 连接建立后,所有传输的 TCP 段都应将 ACK 位置为 1。
2. FIN (Finish):
- 含义:结束位。
- 作用:当 FIN=1 时,表示发送方的数据已经全部发送完毕,并请求释放这个方向的 TCP 连接。它用于 TCP 连接的正常关闭过程(四次挥手)。一个 FIN 段即使不携带数据,也要消耗一个序列号。
3. RST (Reset):
- 含义:复位位。
- 作用:当 RST=1 时,表示 TCP 连接出现了严重错误(如端口不存在、连接异常等),必须强制释放连接,然后重新建立。它用于异常地中断一个连接。收到 RST 段的一方不需要回复任何信息,应立即关闭连接。
---
25. DHCP 租用过程
回答:
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)允许网络中的计算机自动获取 IP 地址、子网掩码、默认网关、DNS 服务器等网络配置信息。其租用过程通常包含四个步骤,简称为 DORA:
1. Discover (发现):
- 新接入网络的客户端(DHCP Client)需要 IP 地址,但它不知道网络中有哪些 DHCP 服务器。
- 客户端会以广播的方式发送一个 DHCP Discover 报文。该报文的源 IP 地址为 0.0.0.0,目的 IP 地址为 255.255.255.255。
2. Offer (提供):
- 网络中所有收到 Discover 报文的 DHCP 服务器,会从自己的地址池中选择一个可用的 IP 地址,并连同其他配置信息(如租期、网关、DNS等)一起,构建一个 DHCP Offer 报文。
- 服务器以广播(或在某些情况下是单播)的方式将 Offer 报文发送出去,响应客户端的请求。网络中可能有多台服务器都提供 Offer。
3. Request (请求):
- 客户端可能会收到多个 Offer 报文。它会选择其中一个(通常是第一个收到的),然后再次以广播的方式发送一个 DHCP Request 报文。
- 这个报文中会包含它所选择的 DHCP 服务器的标识以及它希望使用的 IP 地址。
- 发送广播的目的是为了通知所有 DHCP 服务器(包括那些未被选中的),它已经做出了选择。未被选中的服务器可以收回它们提供的 IP 地址,分配给其他客户端。
4. Acknowledge (确认):
- 被选中的 DHCP 服务器收到 Request 报文后,会进行最后的确认。
- 如果该 IP 地址仍然可用,服务器会发送一个 DHCP ACK 报文,正式将该 IP 地址和配置信息租用给客户端。
- 客户端收到 ACK 报文后,就完成了网络配置,并可以使用该 IP 地址进行通信了。如果在 Request 后,服务器发现该 IP 已被占用,则会返回一个 DHCP NAK (Negative Acknowledge) 报文,客户端需要重新开始 Discover 过程。
---
26. 单播,组播,广播的区别
回答:
单播、组播和广播是网络中三种主要的数据传输方式,区别在于数据包的目标接收者数量。
- 单播 (Unicast):
- 通信方式:一对一(1 to 1)。
- 描述:数据包从一个源主机发送到网络中一个唯一的目标主机。这是网络中最常见的通信方式。
- 例子:浏览网页 (HTTP)、收发邮件 (SMTP/POP3)、文件传输 (FTP)。
- 广播 (Broadcast):
- 通信方式:一对所有(1 to All)。
- 描述:数据包从一个源主机发送到同一广播域内的所有其他主机。
- 缺点:会消耗大量的网络带宽和主机 CPU 资源,因为网络中的每台设备都必须接收并处理广播包。
- 例子:ARP 请求、DHCP Discover 过程、局域网游戏中的设备发现。
- 组播 (Multicast):
- 通信方式:一对一组(1 to Many)。
- 描述:数据包从一个源主机发送到一个特定的“组”,只有加入了这个组的主机才能接收到该数据包。它介于单播和广播之间。
- 优点:相比广播,它只将数据发送给感兴趣的接收者,大大节省了网络带宽。相比为每个接收者进行单播,它也节省了发送方的带宽和处理资源。
- 例子:IPTV (网络电视)、在线视频会议、多人在线游戏的数据同步。
总结:
特性
单播
广播
组播
目标
单个特定主机
广播域内所有主机
特定组内的主机
效率
对源和网络压力大(当接收者多时)
对网络和无关主机造成浪费
高效,节省带宽
应用
普通网页、邮件
地址解析、服务发现
视频会议、IPTV
---
27. spooling 组成
回答:
SPOOLing (Simultaneous Peripheral Operations On-Line,即外部设备联机并行操作) 是一种用于管理慢速外部设备(如打印机)的数据传输技术。它的核心思想是在高速设备(如磁盘)上建立一个缓冲区(称为“spool”或“后台打印队列”),以协调 CPU 与慢速 I/O 设备之间的速度差异。
SPOOLing 系统的主要组成部分:
1. 输入/输出井 (Spooling Buffer Area):
- 这是在磁盘上开辟的一块专用存储区域。它分为“输入井”和“输出井”。
- 输入井:用于暂存从输入设备(如键盘、读卡器)输入的数据,等待 CPU 处理。
- 输出井:用于暂存由用户程序产生、准备输出到输出设备(如打印机)的数据。
2. 输入/输出队列 (Spooling Queues):
- 系统为输入和输出任务维护相应的队列。例如,“打印队列”管理着所有等待被打印的作业。这些队列记录了作业的信息和它们在输入/输出井中数据的位置。
3. 输入/输出进程 (Spooling Daemons/Processes):
- 这是两个独立的、在后台运行的守护进程。
- 输入进程 (Reader Process):负责模拟脱机输入,将数据从物理输入设备读取并存放到磁盘的“输入井”中。
- 输出进程 (Writer Process):负责模拟脱机输出,从磁盘的“输出井”中读取数据,并将其发送到物理输出设备上。
工作流程(以打印为例):
1. 用户程序请求打印。
2. 操作系统拦截该请求,并不直接将数据送给打印机,而是启动一个“假脱机输出”进程。
3. 该进程将用户要打印的数据高速地写入到磁盘的“输出井”中,并为该打印任务在打印队列中创建一个条目。
4. 对于用户程序来说,打印操作瞬间完成,它可以继续执行其他任务。
5. 后台的“输出进程”(打印守护进程)会不断检查打印队列。当打印机空闲时,它会从队列中取出一个任务,并从“输出井”中读取相应的数据,缓慢地将其发送给打印机进行物理打印。
通过 SPOOLing 技术,多个用户的打印任务可以并发进行(数据并发写入输出井),而打印机可以连续不断地工作,从而提高了 I/O 设备的利用率和系统的吞吐量。
---
28. 简述操作系统中进程和线程的区别与联系, 多线程编程的优势是什么?
回答:
区别与联系:
- 联系:
1. 归属关系:线程是进程的一部分,一个进程可以包含一个或多个线程。
2. 资源共享:同一进程内的所有线程共享该进程的资源,包括地址空间(代码段、数据段)、全局变量、打开的文件、信号处理器等。
- 区别:
1. 资源拥有:**进程是操作系统进行资源分配和调度的基本单位**。每个进程都有自己独立的地址空间和系统资源。进程间的资源是隔离的。
2. 执行单位:**线程是CPU调度的基本单位**(也被称为轻量级进程)。它基本上不拥有系统资源,只有一个线程ID、程序计数器、寄存器集合和栈。
3. 创建和切换开销:创建或销毁一个进程,系统需要分配或回收资源(如内存空间、文件描述符),开销很大。而创建或销毁线程的开销很小,因为资源是共享的。同样,线程之间的切换(上下文切换)比进程切换快得多,因为它只需要保存和恢复少量寄存器状态,而不需要切换内存管理单元(MMU)。
4. 并发性:在多核CPU上,一个进程中的多个线程可以真正地并行执行。
5. 健壮性:进程间相互独立,一个进程的崩溃不会影响到其他进程。而一个线程的崩溃(如非法内存访问)会导致整个进程退出。
多线程编程的优势:
1. 提高程序响应速度:在需要用户交互的程序中(如GUI应用),可以将耗时的操作(如文件读写、网络请求)放在一个工作线程中处理,而主线程继续负责UI的响应,避免界面卡死。
2. 充分利用多核处理器:在多核CPU环境下,多线程可以将计算密集型任务分解到多个线程中,实现真正的并行计算,从而显著提高程序的执行效率。
3. 资源开销小:相比于创建多个进程来实现并发,多线程的创建和切换开销要小得多,占用的系统资源也更少。
4. 数据共享方便:由于同一进程的线程共享内存和全局变量,线程间通信(数据交换)非常方便,无需像进程间通信(IPC)那样需要复杂的机制。
---
29. 数据库事务的 ACID 特性具体指什么? 在数据库管理系统中如何保证这些特性?
回答:
ACID 特性:
ACID 是数据库事务正确执行的四个基本要素,确保了即使在并发访问和系统故障的情况下,数据也能保持一致性。
1. 原子性 (Atomicity):一个事务是一个不可分割的工作单元,事务中的所有操作要么都成功执行,要么都失败回滚。数据库不会处于一个“中间状态”。
2. 一致性 (Consistency):事务必须使数据库从一个一致性状态转变到另一个一致性状态。也就是说,事务的执行不能破坏数据库的完整性约束(如主键、外键、数据类型约束等)。
3. 隔离性 (Isolation):多个并发事务之间是相互隔离的。一个事务所做的修改在最终提交之前,对其他事务是不可见的。这防止了多个事务并发执行时由于交叉执行而导致的数据不一致问题。隔离级别有多种,如读未提交、读已提交、可重复读、串行化。
4. 持久性 (Durability):一旦事务被成功提交,它对数据库的改变就是永久性的,即使后续系统发生故障(如断电、崩溃),也应该能够恢复。
如何保证这些特性:
- 保证原子性 (Atomicity):主要通过 事务日志 (Transaction Log) 来实现。
- 回滚日志 (Undo Log):在执行修改操作之前,先把原始数据记录到Undo Log中。如果事务需要回滚,系统可以利用Undo Log中的信息将数据恢复到事务开始前的状态。
- 保证一致性 (Consistency):
- 一致性是最终目标,由其他三个特性共同保证。
- 数据库本身通过**完整性约束**(如类型检查、主键唯一性、外键引用)来强制。
- 应用层面也需要程序员编写正确的事务逻辑来维护业务上的一致性。
- 原子性、隔离性和持久性的实现是保证一致性的基础。
- 保证隔离性 (Isolation):主要通过 锁机制 (Locking) 和 多版本并发控制 (MVCC) 来实现。
- 锁机制:在事务访问数据时,对其加锁(如共享锁、排他锁),防止其他事务进行不恰当的访问。不同的隔离级别对应不同的加锁策略。
- MVCC:为数据维护多个版本。当一个事务修改数据时,它会创建一个新的版本,而不是直接覆盖旧版本。读事务可以读取在其开始之前已经提交的版本,从而实现了读写不加锁,大大提高了并发性能。InnoDB存储引擎就使用了MVCC。
- 保证持久性 (Durability):主要通过 重做日志 (Redo Log) 和 数据备份 来实现。
- 重做日志 (Redo Log):当事务提交时,首先会将事务所做的所有修改(以物理或逻辑方式)写入到Redo Log中,并确保日志已落盘。这个过程称为 Write-Ahead Logging (WAL)。即使数据还没来得及写入磁盘数据库就崩溃了,在重启后,系统可以通过Redo Log来重放这些修改,恢复到崩溃前的状态。
---
30. 什么是数据库的三大范式?违反范式会带来哪些问题?请举例说明。
回答:
数据库的三大范式 (Normal Forms, NF):
三大范式是设计关系型数据库表结构时所遵循的基本准则,目的是为了减少数据冗余,保证数据的一致性。
1. 第一范式 (1NF):**属性不可再分**。要求数据库表中的每一列(字段)都是不可分割的原子值。
2. 第二范式 (2NF):**消除部分函数依赖**。在满足1NF的基础上,要求表中的非主键列必须完全依赖于整个主键,而不是主键的一部分。这个范式主要针对联合主键。
3. 第三范式 (3NF):**消除传递函数依赖**。在满足2NF的基础上,要求表中的非主键列不能依赖于其他非主键列,即不能存在传递依赖关系。
违反范式带来的问题:
违反范式的主要问题是数据冗余,并由此引发数据不一致、插入异常、更新异常和删除异常。
举例说明:
假设有一个 **学生选课表 (Student_Course)**,设计如下:
学号 (S_ID)
姓名 (S_Name)
院系 (S_Dept)
院系负责人 (Dept_Head)
课程号 (C_ID)
成绩 (Grade)
101
张三
计算机
王教授
C01
95
101
张三
计算机
王教授
C02
88
102
李四
物理
赵教授
C03
92
问题分析:
- 违反第二范式:主键是(学号, 课程号)。姓名、院系、院系负责人都只依赖于学号(主键的一部分),而不是整个主键。这导致:
- 数据冗余:张三选了两门课,他的姓名、院系、院系负责人信息就重复存储了两次。
- 更新异常:如果计算机系的负责人换了,需要修改所有计算机系学生的记录,容易遗漏导致数据不一致。
- 插入异常:如果一个新生刚入学还没选课,他的信息(学号、姓名、院系)就无法插入到这张表中,因为主键(课程号)不能为空。
- 删除异常:如果张三只选了一门课 C01,后来他退掉了这门课。删除这条记录的同时,张三这个学生的基本信息也丢失了。
- 违反第三范式:院系负责人依赖于院系,而院系依赖于学号,存在传递依赖(学号 -> 院系 -> 院系负责人)。
规范化设计:
应该将上表拆分为三张表:
1. 学生表 (Student):(学号, 姓名, 院系号)
2. 院系表 (Department):(院系号, 院系名, 院系负责人)
3. 选课表 (Score):(学号, 课程号, 成绩)
这样,每部分信息只存储一次,消除了冗余和各种异常,符合了第三范式。
---
31. 操作系统中的页面置换算法有哪些?比较 LRU、FIFO 和 OPT 算法的特点与性能。
回答:
页面置换算法是在内存满时,操作系统需要从内存中选择一个页面调出到外存,以便为新的页面腾出空间。
常见的页面置换算法有:
- OPT (Optimal) 算法:最优置换算法。
- FIFO (First-In, First-Out) 算法:先进先出算法。
- LRU (Least Recently Used) 算法:最近最少使用算法。
- Clock 算法(或称 NRU, Not Recently Used)。
- LFU (Least Frequently Used) 算法:最不经常使用算法。
LRU、FIFO 和 OPT 的比较:
- OPT (最优置换算法):
- 策略:置换未来最长时间内不会被访问的页面。
- 特点:这是一种理想化的算法,因为它需要预知未来的页面访问序列。
- 性能:具有最低的缺页率,性能是最好的。它不能被实际实现,通常作为衡量其他算法性能的基准。
- FIFO (先进先出算法):
- 策略:置换在内存中驻留时间最长的页面。它维护一个队列,新调入的页面放在队尾,置换时淘汰队首的页面。
- 特点:实现简单,开销小。
- 性能:性能较差。因为它没有考虑页面的访问频率和近期使用情况,可能会置换掉一个经常被访问的页面。此外,FIFO 存在 **Belady 异常**,即分配给进程的物理页框数增加,缺页率反而可能上升的现象。
- LRU (最近最少使用算法):
- 策略:置换最近最长时间内没有被访问过的页面。它基于程序的局部性原理,认为过去最少使用的页面在未来也最不可能被访问。
- 特点:需要记录每个页面的访问历史,实现起来比较复杂,硬件开销大(需要维护一个访问时间戳或一个栈)。
- 性能:性能非常好,非常接近于 OPT 算法。它不会产生 Belady 异常。由于其良好的性能,它是许多实际系统中被广泛考虑和模拟的算法(例如通过 Clock 算法来近似实现 LRU)。
总结:
算法
策略
性能
实现复杂度
OPT
置换未来最久不用的
最好(理论基准)
无法实现
FIFO
置换最先进入的
较差,有 Belady 异常
简单
LRU
置换最近最少使用的
很好,接近 OPT
复杂,开销大
---
32. 简述软件测试的主要阶段(如单元测试、集成测试等)及其目标和方法。
回答:
软件测试通常遵循一个由小到大、从内到外的顺序,主要分为以下几个阶段:
1. 单元测试 (Unit Testing):
- 目标:验证软件中最小的可测试单元(如一个函数、一个方法或一个类)是否按预期工作。
- 方法:通常由开发人员自己进行,属于白盒测试。开发者会编写测试用例(或使用自动化测试框架如 JUnit, PyTest)来调用被测单元,并断言其输出或状态是否符合预期。通常需要使用**桩(Stub)**和**驱动(Driver)**来隔离被测单元,模拟其依赖的模块和调用环境。
2. 集成测试 (Integration Testing):
- 目标:将已经通过单元测试的模块组合在一起,测试它们之间的接口和交互是否存在问题。
- 方法:可以是白盒测试、黑盒测试或灰盒测试。
- 大爆炸式集成:一次性将所有模块集成起来测试,问题定位困难。
- 增量式集成:
- 自顶向下:从主控模块开始,逐步向下集成子模块,需要使用**桩(Stub)**来模拟尚未集成的底层模块。
- 自底向上:从最底层的模块开始,逐步向上集成,需要使用**驱动(Driver)**来模拟调用该模块的上层模块。
3. 系统测试 (System Testing):
- 目标:将整个软件系统作为一个整体,在接近真实运行的环境中,验证其是否满足《软件需求规格说明书》中定义的所有功能和非功能性需求。
- 方法:通常是黑盒测试,由专门的测试团队进行。测试内容包括功能测试、性能测试、负载测试、安全性测试、兼容性测试、可靠性测试等。
4. 验收测试 (Acceptance Testing):
- 目标:在软件部署之前,由最终用户或客户来验证系统是否满足他们的业务需求和期望。
- 方法:是黑盒测试,站在用户的角度进行。
- Alpha 测试:在开发环境下,由内部用户或测试人员模拟最终用户进行测试。
- Beta 测试:将软件发布给外部的一批真实用户,在他们的实际环境中进行测试,并收集反馈。
这四个阶段是一个逐步验证的过程,确保了从最小的代码单元到最终交付给用户的完整产品,其质量都得到了有效的控制。
---
33. 什么是死锁?死锁产生的必要条件有哪些?如何预防、避免和检测死锁?
回答:
什么是死锁?
死锁是指在多道程序环境下,两个或多个进程因竞争资源而造成的一种互相等待的僵局,若无外力作用,它们都将无法继续推进。
死锁产生的四个必要条件(缺一不可):
1. 互斥条件 (Mutual Exclusion):资源在同一时刻只能被一个进程所使用。
2. 请求与保持条件 (Hold and Wait):一个进程因请求资源而阻塞时,对自己已获得的资源保持不放。
3. 不可剥夺条件 (No Preemption):进程已获得的资源,在未使用完之前,不能被强行剥夺,只能由进程自己主动释放。
4. 循环等待条件 (Circular Wait):存在一种进程资源的循环等待链,链中每个进程已获得的资源同时被链中下一个进程所请求。
处理死锁的方法:
1. 死锁预防 (Prevention):
通过破坏死锁产生的四个必要条件中的一个或多个来预防死锁的发生。
- 破坏互斥条件:允许资源共享。但对于打印机这类本身就是互斥的资源,此法不可行。
- 破坏请求与保持条件:采用**静态分配**策略,即进程在运行前一次性申请所有需要的资源,若无法满足则不投入运行。这种方法资源利用率低,可能导致进程饥饿。
- 破坏不可剥夺条件:允许系统强行剥夺进程已占有的资源。当一个进程请求新资源得不到满足时,它必须释放已持有的所有资源。实现复杂,且可能导致前段工作失效。
- 破坏循环等待条件:采用**资源有序分配法**,对所有资源类型进行线性排序,并规定所有进程必须按序号递增的顺序申请资源。
2. 死锁避免 (Avoidance):
在资源分配过程中,使用某种算法来判断本次分配是否会导致系统进入不安全状态,如果会,则不予分配,让进程等待。这是一种动态策略。
- 银行家算法 (Banker's Algorithm) 是最著名的死锁避免算法。它通过检查是否存在一个安全的执行序列,来决定是否批准一个进程的资源请求。
3. 死锁检测与解除 (Detection and Recovery):
允许系统进入死锁状态,但能通过检测机制及时发现死锁,然后采取措施解除死锁。
- 死锁检测:通过**资源分配图**或类似银行家算法的检测算法,定期检查系统中是否存在循环等待。
- 死锁解除:
- 资源剥夺法:挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。
- 撤销进程法:强制撤销部分甚至全部死锁进程,并剥夺这些进程的资源。
- 进程回退法:让一个或多个进程回退到足以避免死锁的地步。
---
34. 解释软件工程中的瀑布模型、敏捷开发模型的特点及适用场景,两者的主要区别是什么?
回答:
瀑布模型 (Waterfall Model):
- 特点:
1. 线性顺序:模型将软件生命周期划分为一系列严格按顺序连接的阶段(如需求分析、系统设计、编码、测试、部署、维护)。
2. 阶段驱动:必须完成前一阶段的所有工作并经过评审,才能进入下一阶段。
3. 文档驱动:每个阶段都会产生大量的、详细的文档。
4. 强调早期规划:在项目早期就要求有完整和明确的需求。
- 适用场景:
- 需求非常明确、稳定,且在项目周期内基本不会发生变化的项目。
- 项目规模较小,或者技术非常成熟、风险较低的项目。
- 例如:一些传统的、需求固化的嵌入式系统或政府项目。
敏捷开发模型 (Agile Development Model):
- 特点:
1. 迭代与增量:将项目分解成多个小的、可管理的迭代周期(通常是2-4周的Sprint)。每个迭代都会产出一个可工作的、增量的软件产品。
2. 拥抱变化:欢迎并能够快速响应需求的变化。
3. 以人为本:强调团队成员之间的紧密协作、沟通和自组织。
4. 客户协作:客户或产品负责人深度参与整个开发过程,持续提供反馈。
5. 轻文档:更注重可工作的软件,而不是繁重的文档。
- 适用场景:
- 需求不明确、复杂或变化频繁的项目。
- 创新型项目,需要不断探索和试错。
- 大多数现代互联网产品、移动应用开发。
两者的主要区别:
1. 流程:瀑布是**线性的、顺序的**;敏捷是**迭代的、循环的**。
2. 对需求变化的态度:瀑布**抵制变化**,认为需求变更会带来高昂的代价;敏捷**拥抱变化**,认为变化是项目成功的常态。
3. 交付周期:瀑布在项目**最后**才交付一个完整的最终产品;敏捷在**每个迭代结束**时都会交付一个可用的增量产品。
4. 客户参与度:瀑布模型中客户主要在项目**初期和末期**参与;敏捷开发中客户**持续参与**整个过程。
5. 风险管理:瀑布模型的风险集中在项目后期,问题可能到测试阶段才暴露;敏捷开发通过短迭代**尽早暴露和应对风险**。
---
35. 简述 HTTP 与 HTTPS 协议的区别,HTTPS 如何保证通信安全?
回答:
HTTP 与 HTTPS 的区别:
1. 安全性:HTTP(超文本传输协议)是明文传输的,数据在传输过程中不加密,容易被窃听和篡改,是不安全的。HTTPS(超文本传输安全协议)是在 HTTP 的基础上加入了 SSL/TLS 协议层,对传输的数据进行加密,是安全的。
2. 端口号:HTTP 默认使用 80 端口,HTTPS 默认使用 443 端口。
3. 连接过程:HTTPS 在建立 TCP 连接后,需要进行 SSL/TLS 的握手过程,协商加密算法、交换密钥等,然后才能开始传输加密的 HTTP 报文。HTTP 则直接传输报文。
4. 证书要求:HTTPS 需要向证书颁发机构(CA)申请数字证书,以证明服务器身份的真实性,这通常需要一定的费用。
5. 资源消耗:HTTPS 的加密解密过程会消耗更多的服务器和客户端 CPU 及内存资源,握手过程也会增加一定的延迟。
HTTPS 如何保证通信安全:
HTTPS 通过 SSL/TLS 协议层,结合**对称加密**、**非对称加密**和**数字证书**三大技术来保证通信安全,主要实现了以下三点:
1. 机密性 (Confidentiality):
- 实现方式:使用**对称加密**算法(如 AES)对传输的报文内容进行加密。
- 作用:即使数据包被第三方截获,由于没有密钥,也无法解密出其中的内容。
2. 完整性 (Integrity):
- 实现方式:使用**消息摘要算法(哈希函数,如 SHA-256)**生成报文的摘要(MAC),并将摘要连同报文一起发送。
- 作用:接收方收到后,用同样的方法计算摘要,并与收到的摘要进行比对。如果一致,说明数据在传输过程中没有被篡改。
3. 身份认证 (Authentication):
- 实现方式:使用**数字证书**和**非对称加密**算法(如 RSA)。
- 作用:
- 服务器身份认证:客户端通过验证服务器发来的数字证书(由权威 CA 机构签发),来确认自己正在通信的服务器是真实可信的,而不是一个伪造的“钓鱼”网站。证书中包含了服务器的公钥。
- 密钥交换:在 SSL/TLS 握手阶段,客户端生成一个用于对称加密的“会话密钥”,然后用从服务器证书中获取的**公钥**对其进行加密,再发送给服务器。服务器用自己的**私钥**解密,从而安全地获得了这个“会话密钥”。后续的通信就使用这个会话密钥进行对称加密。
---
36. 什么是分布式系统?分布式系统面临的主要挑战有哪些(如一致性、可用性等)?
回答:
什么是分布式系统?
分布式系统是一个由多台独立的计算机组成的集合,这些计算机通过网络互联,并协同工作来完成一个共同的任务。从外部用户的角度来看,这个系统就像是一台单一的、功能强大的计算机。
分布式系统面临的主要挑战:
1. 异构性 (Heterogeneity):系统中的计算机可能具有不同的硬件、操作系统和网络协议。如何让它们协同工作是一个挑战。
2. 并发性 (Concurrency):系统中的多个组件可以同时对共享资源进行操作,必须有合适的并发控制机制(如分布式锁、事务)来保证数据的一致性。
3. 缺乏全局时钟 (Absence of a Global Clock):由于网络延迟和时钟漂移,很难精确地确定系统中不同节点上事件发生的绝对顺序。这给协调和同步带来了困难。
4. 故障与容错 (Faults and Fault Tolerance):
- 节点故障:单个节点可能会崩溃或下线。系统必须能够容忍部分节点的失败而不影响整体服务。
- 网络分区 (Network Partitions):网络可能发生故障,导致系统被分割成多个无法通信的子集。
5. 一致性 (Consistency):
- 在分布式系统中,数据通常有多个副本,分布在不同的节点上。如何保证这些副本之间的数据在任何时候都是一致的,是一个核心挑战。这引出了一致性模型的概念,如强一致性、弱一致性、最终一致性等。
6. 可用性 (Availability):
- 系统需要在任何时候都能对用户的请求做出响应(即使部分节点发生故障)。高可用性是分布式系统的一个关键目标。
- CAP 定理指出,在一个分布式系统中,**一致性(C)**、**可用性(A)**和**分区容错性(P)** 这三者不可同时兼得,最多只能满足其中两项。在现代分布式系统中,分区容错性(P)是必须保证的,因此系统设计者通常需要在一致性(C)和可用性(A)之间做出权衡。
7. 可扩展性 (Scalability):
- 系统应能够在不显著降低性能的情况下,通过增加更多的机器来处理不断增长的负载。
---
37. 操作系统中虚拟内存的概念和作用是什么?页面置换和页面调度的过程是怎样的?
回答:
虚拟内存的概念和作用:
- 概念:虚拟内存是一种内存管理技术,它为每个进程提供了一个巨大的、连续的、私有的地址空间(称为“虚拟地址空间”),而这个地址空间的大小可以远大于实际的物理内存。它将虚拟地址空间映射到物理内存和磁盘上的存储空间(如交换文件)。
- 作用:
1. 扩大地址空间:使得程序可以使用的内存远大于物理内存的限制,从而能够运行非常大的程序。
2. 内存保护:每个进程都有自己独立的虚拟地址空间,一个进程无法直接访问另一个进程的内存,提供了进程间的隔离和保护。
3. 共享内存:不同的进程可以通过映射同一块物理内存到各自的虚拟地址空间,来实现高效的内存共享。
4. 提高内存利用率和并发度:程序运行时,只需将当前需要执行的部分装入物理内存,其他部分可以暂时存放在磁盘上。这使得有限的物理内存可以同时容纳更多的进程,提高了系统的并发度。
页面置换和页面调度的过程:
这里的“页面调度”通常指的是“请求调页”的过程。
- 请求调页 (Page Fault Handling):
1. 产生缺页中断:当CPU试图访问一个虚拟地址,而通过MMU(内存管理单元)查询页表发现,该地址对应的页面不在物理内存中时(页表项的“存在位”为0),会产生一个**缺页中断 (Page Fault)**。
2. 中断处理:CPU将控制权转交给操作系统的缺页中断处理程序。
3. 合法性检查:操作系统检查该虚拟地址是否合法,以及进程是否有权访问它。如果非法,则终止该进程。
4. 查找页面位置:如果访问合法,操作系统需要到磁盘的交换空间中找到该页面。
5. 调入内存:
- 在物理内存中查找一个空闲的页框。
- 将磁盘上的目标页面读入到这个空闲的页框中。
- 更新该进程的页表,设置对应的页表项(填入物理页框号,并将“存在位”置为1)。
6. 恢复执行:缺页中断处理完毕后,返回到产生中断的指令处,重新执行该指令。此时,所需的页面已经在内存中,可以正常访问了。
- 页面置환 (Page Replacement):
页面置换是请求调页过程中的一个特殊步骤。
- 触发时机:当步骤5中,操作系统**找不到空闲的物理页框**时,就需要进行页面置换。
- 过程:
1. 选择牺牲页:操作系统必须按照某种**页面置换算法**(如LRU、FIFO等)从当前已在内存的页面中选择一个“牺牲页”。
2. 写回磁盘(如果需要):检查牺牲页的“修改位”(Dirty Bit)。如果该位为1,说明页面在内存中被修改过,必须先将它写回到磁盘的交换空间,以保证数据的一致性。如果为0,则无需写回。
3. 更新页表:修改牺牲页对应的页表项,将“存在位”置为0。
4. 调入新页:现在牺牲页所占用的物理页框变为空闲,可以将新的页面调入到这个页框中,并更新新页的页表项。
5. 继续执行:流程回到请求调页的后续步骤。
---
38. 数据库索引的作用是什么?常见的索引类型(如 B 树索引、哈希索引)有何区别?
回答:
数据库索引的作用:
索引是一种特殊的数据结构,它存储了数据表中一个或多个列的值以及这些值所在行的物理地址。其主要作用是**大大加快数据库的查询速度**。
- 工作原理:类似于书籍的目录。没有索引时,查询数据需要对整张表进行全表扫描。有了索引,数据库可以直接通过索引结构(如B+树)快速定位到数据所在的物理位置,从而避免了全表扫描,显著提高了检索效率。
- 副作用:
- 空间开销:索引本身需要占用额外的磁盘空间。
- 维护开销:当对表中的数据进行增、删、改操作时,数据库系统也需要动态地维护索引,这会带来一定的性能开销。
常见索引类型的区别:
- B树索引 (通常是B+树索引):
- 结构:一种多路平衡查找树。它的特点是所有叶子节点都在同一层,并且叶子节点之间通过指针相连,形成一个有序链表。非叶子节点只存储键值(索引列的值),而所有的数据记录指针都存储在叶子节点中。
- 优点:
1. 支持范围查询:由于叶子节点是有序的且相互连接,B+树非常适合进行范围查找(如 WHERE age > 20)和排序操作。
2. 查询性能稳定:由于树是平衡的,任何键值的查找路径长度都基本相同,查询性能稳定。
- 适用场景:绝大多数关系型数据库(如MySQL的InnoDB)的默认索引类型。适用于等值查询、范围查询、排序和分组等各种场景。
- 哈希索引 (Hash Index):
- 结构:基于哈希表实现。它通过一个哈希函数将索引列的值计算成一个哈希码,然后将哈希码与数据行的指针存放在哈希表中。
- 优点:
1. 等值查询极快:在没有哈希冲突的情况下,进行等值查询(如 WHERE id = 123)的时间复杂度是O(1),速度非常快。
- 缺点:
1. 不支持范围查询:哈希后的值是无序的,无法进行范围查找。
2. 不支持排序:无法利用索引进行排序操作。
3. 哈希冲突问题:当多个键值计算出相同的哈希码时,会产生哈希冲突,查询性能会下降到O(n)。
- 适用场景:主要用于内存数据库(如Redis)或对等值查询有极高性能要求的场景。MySQL的Memory存储引擎支持哈希索引。
总结:B+树索引是一种通用的、支持范围查询的高效索引;哈希索引则是在等值查询场景下的速度之王,但功能受限。
---
39. 简述敏捷开发中的 Scrum 框架,包括其核心角色、会议和工件(如产品待办列表)。
回答:
Scrum 是敏捷开发中最流行的一种框架,它通过短周期的迭代来增量式地交付产品。
核心角色 (Roles):
1. 产品负责人 (Product Owner, PO):
- 职责:代表客户和业务方的利益。负责定义产品的愿景、管理和维护“产品待办列表(Product Backlog)”,并对其进行优先级排序,确保开发团队的工作能够最大化产品价值。
2. 开发团队 (Development Team):
- 职责:一个跨职能的、自组织的团队,负责在每个 Sprint 中将产品待办列表中的项转化为可交付的产品增量。团队成员共同拥有完成工作所需的所有技能。
3. Scrum Master:
- 职责:是 Scrum 框架的“仆人式领导”和教练。他负责确保团队正确理解和实施 Scrum,帮助团队移除工作中的障碍,并引导团队进行各种 Scrum 会议,保护团队不受外界干扰。
工件 (Artifacts):
1. 产品待-办列表 (Product Backlog):
- 一个动态的、按优先级排序的需求列表,包含了所有对产品期望的功能、特性、修复等。它由产品负责人维护。
2. Sprint 待-办列表 (Sprint Backlog):
- 在 Sprint 计划会议上,开发团队从产品待办列表中选择的一组任务。它是开发团队在本个 Sprint 中需要完成的工作计划。
3. 产品增量 (Increment):
- 每个 Sprint 结束时产出的所有产品待办列表项的总和,它必须是“可交付的”(Done),意味着它达到了预先定义的完成标准,理论上可以发布给用户。
会议/事件 (Events):
1. Sprint:
- Scrum 的核心,是一个固定时长的迭代周期(通常为1-4周),在此期间,团队创建一个“可交付的”产品增量。
2. Sprint 计划会议 (Sprint Planning):
- 在每个 Sprint 开始时举行。团队共同决定本 Sprint 的目标,并从产品待办列表中选取相应的工作项放入 Sprint 待办列表。
3. 每日站会 (Daily Scrum):
- 每天固定时间举行的短会(不超过15分钟)。团队成员同步进展,分享昨天完成了什么、今天计划做什么以及遇到了什么障碍。
4. Sprint 评审会议 (Sprint Review):
- 在 Sprint 结束时举行。开发团队向产品负责人、客户等利益相关者演示本 Sprint 完成的产品增量,并收集反馈。
5. Sprint 回顾会议 (Sprint Retrospective):
- 在 Sprint 评审会议之后、下一个 Sprint 开始之前举行。团队内部回顾这个 Sprint 在流程、工具、协作等方面做得好的地方和可以改进的地方,并制定改进计划。
---
40. 什么是软件设计模式?请列举几种常见的设计模式(如单例模式、工厂模式)并说明其应用场景。
回答:
什么是软件设计模式?
软件设计模式是在软件设计过程中,针对特定问题或场景的、经过反复验证的、可复用的解决方案。它不是一段可以直接使用的代码,而是一种解决问题的思想和模板。使用设计模式可以使代码更易于理解、更具可重用性、可靠性和可维护性。
常见设计模式及其应用场景:
1. 单例模式 (Singleton Pattern):
- 定义:确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
- 应用场景:当系统中某个组件只需要一个实例来协调全局行为时。
- 日志记录器 (Logger):整个应用通常只需要一个日志对象来记录日志。
- 数据库连接池:管理数据库连接,避免频繁创建和销毁连接的开销。
- 配置文件读取器:读取应用的配置信息,只需加载一次即可。
2. 工厂模式 (Factory Pattern):
- 定义:定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂模式使一个类的实例化延迟到其子类。
- 类型:包括简单工厂、工厂方法和抽象工厂。
- 应用场景:当创建对象的过程比较复杂,或者需要根据不同的输入来创建不同类型的对象,并且不希望客户端代码与具体对象的创建过程耦合时。
- 数据库驱动加载:根据配置(如"MySQL", "Oracle")创建不同的数据库连接对象。
- UI 控件创建:根据操作系统类型(Windows, macOS)创建风格不同的按钮、文本框等控件。
- 支付方式选择:根据用户选择(支付宝、微信支付、信用卡)创建相应的支付处理对象。
3. 观察者模式 (Observer Pattern):
- 定义:定义了对象之间的一对多依赖关系,当一个对象(被观察者/主题)的状态发生改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新。
- 应用场景:当一个对象的改变需要同时触发其他多个对象发生改变,但又不希望这些对象之间紧密耦合时。
- 事件监听器:GUI 中按钮的点击事件。按钮是被观察者,多个监听器是观察者,点击时所有监听器都会被调用。
- 消息队列/发布-订阅系统:发布者发布消息,所有订阅了该主题的订阅者都会收到消息。
- MVC 架构:Model是被观察者,View是观察者。当Model层数据变化时,会通知所有相关的View层更新显示。
---
41. 计算机网络中,IP 协议与 ARP 协议的关系是什么?ARP 协议的工作原理和过程是怎样的?
回答:
IP 协议与 ARP 协议的关系:
IP 协议和 ARP 协议是 TCP/IP 协议栈中紧密协作的两个协议,它们工作在不同的层次,共同完成数据包的寻址和传输。
- IP 协议:工作在**网络层(第3层)**。它负责在整个互联网范围内,根据 **IP 地址**将数据包从源主机路由到目的主机。它解决的是“宏观”的、跨网络的寻址问题。
- ARP 协议 (地址解析协议):工作在**数据链路层(第2层)**和网络层之间。它的作用是在一个**局域网(LAN)**内部,将一个已知的 **IP 地址**解析(转换)为对应的**硬件地址(MAC 地址)**。它解决的是“微观”的、在单一网络段内的寻址问题。
关系总结:当一台主机要向同一局域网内的另一台主机发送 IP 数据包时,IP 协议提供了目的地的 IP 地址,但数据包在链路层最终需要封装成帧,帧的头部需要填写目的地的 MAC 地址。ARP 协议就是 IP 协议用来查找这个 MAC 地址的“工具人”。IP 协议负责“去哪”,ARP 协议负责“怎么到门口”。
ARP 协议的工作原理和过程(这个在第4题已经详细回答过,这里再简述一遍):
1. 检查缓存:主机 A 想给主机 B (IP_B) 发送数据,先检查自己的 ARP 缓存表,看是否有 IP_B 对应的 MAC 地址。
2. 发送 ARP 请求:如果缓存中没有,主机 A 会在局域网内广播一个 ARP 请求报文,内容是:“谁的 IP 地址是 IP_B?请告诉我你的 MAC 地址。”
3. 主机响应:局域网内所有主机都收到这个请求。
- 其他主机发现请求的 IP 地址不是自己的,就忽略它。
- 主机 B 发现请求的 IP 地址是自己的,就构建一个 ARP 响应报文。
4. 发送 ARP 响应:主机 B 以单播的方式向主机 A 发送 ARP 响应报文,内容是:“我的 IP 地址是 IP_B,我的 MAC 地址是 MAC_B。”
5. 更新缓存并通信:主机 A 收到响应后,将 (IP_B, MAC_B) 的映射关系存入自己的 ARP 缓存,然后就可以用这个 MAC 地址来封装数据帧,开始与主机 B 通信了。
---
42. 操作系统中的进程调度算法有哪些?比较先来先服务(FCFS)、最短作业优先(SJF)和优先级调度算法的优缺点。
回答:
操作系统中的进程调度算法负责从就绪队列中选择一个进程,并将 CPU 分配给它。常见的调度算法有:
- 先来先服务 (FCFS)
- 最短作业优先 (SJF) / 最短剩余时间优先 (SRTN)
- 优先级调度 (Priority Scheduling)
- 时间片轮转 (Round Robin, RR)
- 多级队列调度 (Multilevel Queue Scheduling)
- 多级反馈队列调度 (Multilevel Feedback Queue Scheduling)
算法比较:
- 先来先服务 (First-Come, First-Served, FCFS):
- 策略:按照进程到达就绪队列的先后顺序进行调度。
- 优点:
- 实现简单,公平。
- 缺点:
- 平均周转时间长:如果一个长作业先到达,后面许多短作业就需要长时间等待,导致平均等待时间和周转时间很长。
- 对I/O密集型进程不利:CPU 密集型进程会长时间占用 CPU,导致 I/O 密集型进程无法及时运行和发出 I/O 请求,降低了 I/O 设备的利用率。
- 属于非抢占式算法。
- 最短作业优先 (Shortest Job First, SJF):
- 策略:从就绪队列中选择估计运行时间最短的进程进行调度。可以是抢占式(最短剩余时间优先,SRTN)或非抢占式。
- 优点:
- 平均等待时间和平均周转时间最短:在所有进程同时可用的情况下,SJF 算法被证明是平均周转时间最短的,吞吐量高。
- 缺点:
- 难以预测作业时长:实际运行时间很难被精确预测,这限制了它的实用性。
- 对长作业不公平(饥饿):如果不断有新的短作业到来,长作业可能永远得不到调度,产生“饥饿”现象。
- 优先级调度 (Priority Scheduling):
- 策略:为每个进程分配一个优先级,调度器总是选择优先级最高的进程来运行。可以是抢占式或非抢占式。
- 优点:
- 灵活性高:可以根据进程的重要性或紧急程度来分配优先级,满足不同的系统需求(如实时系统要求高优先级的任务能被立即执行)。
- 缺点:
- 可能导致饥饿:低优先级的进程可能长时间得不到执行。
- 解决方法:可以采用**老化(Aging)**技术,即随着等待时间的增加,动态提升低优先级进程的优先级,以防止饥饿。
---
43. 什么是软件配置管理?版本控制工具(如 Git、SVN)的核心功能和工作原理是什么?
回答:
什么是软件配置管理 (Software Configuration Management, SCM)?
软件配置管理是一套用于在软件产品的整个生命周期内,系统地管理、组织和控制其配置项(如源代码、文档、测试用例、库文件等)的变更的规程和技术。其目标是确保软件产品的完整性、一致性和可追溯性,支持团队协作,并能够可靠地构建和发布软件。
版本控制工具的核心功能:
版本控制工具是 SCM 的核心工具,其主要功能包括:
1. 版本跟踪:记录文件和目录的每一次修改,可以随时查看历史版本。
2. 协作开发:允许多个开发者在同一个项目上并行工作,而不会互相干扰。
3. 分支与合并:支持创建代码的独立分支(Branch)来进行新功能开发或 bug 修复,完成后再将分支合并(Merge)回主线。
4. 可恢复性:如果代码改动引入了错误,可以轻松地将文件或整个项目回滚(Revert)到之前的某个稳定版本。
5. 可追溯性:记录了每一次变更的作者、时间、原因等信息,便于问题排查和审计。
工作原理区别 (Git vs. SVN):
- SVN (Subversion) - 集中式版本控制系统 (CVCS):
- 工作原理:有一个单一的中央服务器,保存着所有文件的所有版本。开发者从这个中央服务器“检出(checkout)”一份代码的最新版本到本地进行工作。当完成修改后,再将变更“提交(commit)”回中央服务器。
- 特点:
- 优点:管理简单,权限控制方便。
- 缺点:必须联网才能提交和查看历史。如果中央服务器宕机,所有人都无法工作。
- Git - 分布式版本控制系统 (DVCS):
- 工作原理:每个开发者都拥有一个完整的代码仓库(repository)的克隆(clone),包含了项目的全部历史记录。开发者在自己的本地仓库中进行提交(commit)、创建分支等操作。当需要协作时,再将本地的变更“推送(push)”到一个共享的远程仓库(如 GitHub),或从远程仓库“拉取(pull)”他人的变更。
- 特点:
- 优点:支持离线工作。分支和合并操作非常快速和强大。每个克隆都是一个完整的备份,更安全。
- 缺点:上手门槛比 SVN 稍高。
---
44. 简述数据库的并发控制机制,如锁机制、时间戳排序等,如何解决并发访问中的问题?
回答:
数据库并发控制是为了解决多个事务同时访问同一数据时可能出现的**脏读**、**不可重复读**和**幻读**等问题,以保证事务的隔离性和数据的一致性。
主要的并发控制机制:
1. 锁机制 (Locking):
- 原理:在事务访问数据之前,先对数据对象(如行、页、表)加锁。锁分为多种类型,最基本的是**共享锁(S锁,读锁)**和**排他锁(X锁,写锁)**。
- S锁:多个事务可以同时对一个数据加S锁(允许多个事务同时读)。
- X锁:只允许一个事务对一个数据加X锁,且此时其他任何事务都不能再对该数据加任何锁(只允许一个事务写,且写时不能读)。
- 如何解决问题:
- 写操作:事务在修改数据前必须获得X锁。这可以防止其他事务读取到未提交的“脏”数据(**解决脏读**)或同时修改该数据。
- 读操作:事务在读取数据时获得S锁。这可以防止在读取过程中,其他事务修改该数据,从而保证了在同一次事务中多次读取同一数据的结果是一致的(**解决不可重复读**)。
- 两段锁协议 (2PL):为了保证事务的可串行化,通常采用两段锁协议。即事务分为“加锁阶段”和“解锁阶段”,一旦开始解锁,就不能再申请任何新的锁。
2. 时间戳排序 (Timestamp Ordering):
- 原理:为每个事务分配一个唯一的、递增的时间戳。当事务要读写数据时,系统会比较事务的时间戳和数据项上记录的(最后被成功读/写的)时间戳,以决定是否允许该操作。
- 基本规则:
- 读操作:如果事务的时间戳小于数据项的写时间戳,说明数据已被一个“更晚”的事务修改,此时读取会读到不该看到的数据,操作被拒绝(事务回滚)。
- 写操作:如果事务的时间戳小于数据项的读时间戳或写时间戳,说明一个“更晚”的事务已经读取或写入了该数据,此时写入会覆盖新数据,操作被拒绝(事务回滚)。
- 如何解决问题:通过强制所有冲突操作都按照时间戳的顺序执行,来保证事务的可串行化。
3. 多版本并发控制 (Multi-Version Concurrency Control, MVCC):
- 原理:一种乐观的并发控制方法。它不对数据加锁,而是为数据维护多个版本(快照)。写操作会创建数据的新版本,而不是直接覆盖旧版本。读操作则根据事务的开始时间戳,去读取那个时间点可见的、已提交的数据版本。
- 如何解决问题:
- 读写不冲突:读操作读取旧版本,写操作创建新版本,两者互不干扰,大大提高了并发性能。
- 解决脏读和不可重复读:由于每个事务都有自己的一致性数据快照,它不会读到其他未提交事务的修改(解决脏读),并且在事务期间多次读取,看到的数据版本也是一致的(解决不可重复读)。
- 应用:被广泛用于现代数据库系统,如 PostgreSQL、Oracle 和 MySQL 的 InnoDB 引擎。
---
45. 计算机网络中的路由选择算法有哪些?比较距离向量算法(如 RIP)和链路状态算法(如 OSPF)的特点。
回答:
路由选择算法是路由器用来决定数据包最佳转发路径的算法。主要分为两大类:距离向量算法和链路状态算法。
- 距离向量算法 (Distance-Vector Algorithm):
- 代表协议:RIP (Routing Information Protocol)
- 工作原理:
- 每个路由器只维护一张包含**到所有目的网络的距离(跳数)和下一跳路由器**的路由表。
- 路由器定期地与**相邻**的路由器交换**整个路由表**。
- 路由器根据从邻居那里收到的路由信息,使用 **Bellman-Ford 算法**来更新自己的路由表。它相信邻居的路由信息是正确的(“听信邻居”)。
- 特点:
- 优点:实现简单,配置容易,对路由器资源要求低。
- 缺点:
- 收敛慢:网络拓扑发生变化时,消息需要逐跳转发,全网达到一致状态(收敛)的速度很慢。
- 路由环路问题:容易产生路由环路,“好消息传得快,坏消息传得慢”。
- 规模限制:由于收敛慢和广播整个路由表(占用带宽),不适用于大型网络。RIP 规定最大跳数为 15。
- 链路状态算法 (Link-State Algorithm):
- 代表协议:OSPF (Open Shortest Path First)
- 工作原理:
- 每个路由器都负责发现它的邻居,并测量到邻居的链路成本(如延迟、带宽)。
- 每个路由器将自己了解到的链路状态信息(我有哪些邻居,到它们的成本是多少)打包成 **LSA (链路状态通告)**,并向网络中的**所有其他路由器**进行**泛洪(Flooding)**。
- 每个路由器都收集来自全网的所有 LSA,从而在本地构建出一张**完整的网络拓扑图**。
- 最后,每个路由器使用 **Dijkstra 算法**在自己的拓扑图上计算出到所有目的地的最短路径。
- 特点:
- 优点:
- 收敛快:一旦拓扑变化,LSA 会被迅速泛洪到全网,每个路由器可以独立重新计算路径。
- 无路由环路:由于每个路由器都掌握全局拓扑信息,计算出的路径是无环的。
- 扩展性好:适用于大型、复杂的网络。
- 缺点:
- 实现复杂,配置要求高。
- 对路由器的 CPU 和内存资源消耗较大。
总结:距离向量是“听邻居说”,只看局部,易产生环路,收敛慢;链路状态是“自己画图”,掌握全局信息,无环路,收敛快。
---
46. 什么是软件体系结构?常见的软件体系结构风格(如分层架构、微服务架构)有何特点?
回答:
什么是软件体系结构 (Software Architecture)?
软件体系结构(或称软件架构)是构建一个计算系统所需的一组结构。这些结构包括软件的**构件**(Components,如模块、类、服务)、构件之间的**关系**(Connectors,如调用、消息传递),以及指导其设计和演化的**原则和规范**。它定义了系统的宏观框架,是关于软件高层结构的决策。
常见的软件体系结构风格特点:
- 分层架构 (Layered Architecture):
- 结构:将系统划分为若干个水平层次,每一层都有明确的角色和职责。典型的分层如:表现层 (UI)、业务逻辑层 (Business Logic)、数据访问层 (Data Access)。
- 特点:
- 关注点分离:每层只关心自己的职责,降低了系统的复杂度。
- 可维护性和可重用性:层的独立性使得修改某一层不会影响到其他层。
- 依赖约束:通常规定上层只能依赖于其紧邻的下层。
- 缺点:对于简单的应用可能过于臃肿。性能上可能会因为跨越多层调用而有所损耗。
- 微服务架构 (Microservices Architecture):
- 结构:将一个大型的单体应用(Monolithic Application)拆分成一组小型的、独立部署的服务。每个服务都围绕着特定的业务能力构建,并运行在自己的进程中。
- 特点:
- 独立开发与部署:每个服务都可以由一个小型团队独立开发、测试、部署和扩展。
- 技术异构性:不同的服务可以采用最适合其业务场景的技术栈(编程语言、数据库等)。
- 高可用性和弹性:单个服务的故障不会导致整个系统瘫痪。
- 易于扩展:可以只对需要更高吞吐量的服务进行水平扩展。
- 缺点:
- 分布式系统复杂性:引入了服务发现、配置管理、分布式事务、服务间通信等复杂问题。
- 运维成本高:需要强大的自动化部署和监控体系。
- 数据一致性挑战:跨服务的业务操作需要处理最终一致性问题。
---
47. 操作系统中的文件系统有哪些主要功能?文件的物理结构和逻辑结构有什么区别?
回答:
文件系统的主要功能:
文件系统是操作系统中负责管理和组织持久性数据(文件)的部分。其主要功能包括:
1. 文件管理:提供创建、删除、打开、关闭、读写文件等基本操作。
2. 目录管理:实现对文件目录(或文件夹)的管理,如创建、删除目录,以及文件和目录的组织(如树形结构)。
3. 存储空间管理:负责管理外存(如磁盘)的存储空间,包括分配空闲空间给新文件,以及回收已删除文件所占用的空间。
4. 文件共享与保护:提供访问控制机制(如读、写、执行权限),允许多个用户安全地共享文件,并保护文件不被未授权的访问。
5. 数据一致性与恢复:在系统崩溃等意外情况下,保证文件系统的完整性和数据的一致性(如通过日志技术)。
文件的物理结构与逻辑结构的区别:
- 逻辑结构 (Logical Structure):
- 定义:从**用户视角**看到的文件组织形式。它描述的是文件内部由什么构成,以及这些构成部分之间的关系。
- 类型:
- 流式文件 (无结构文件):文件被看作是一个连续的字节序列(a stream of bytes),如文本文件、可执行文件。
- 记录式文件 (有结构文件):文件由一系列具有相同或不同长度的记录组成,每条记录有其内部结构,如数据库文件。
- 关注点:用户如何组织和访问文件内容。
- 物理结构 (Physical Structure):
- 定义:从**操作系统视角**看到的文件在外部存储设备(如磁盘)上的存放方式。它描述的是文件如何被组织成物理块并存储在磁盘上。
- 类型:
- 连续分配:文件占用的磁盘块是连续的。优点是读写速度快,缺点是容易产生外部碎片,文件不易扩展。
- 链接分配 (链式分配):文件的磁盘块通过指针链接起来,可以是不连续的。优点是无外部碎片,文件易于扩展。缺点是只支持顺序访问,可靠性差(指针丢失则文件损坏)。
- 索引分配:为每个文件创建一个“索引块”,其中存放了该文件所有数据块的地址。优点是支持随机访问,无外部碎片。缺点是索引块本身需要占用额外空间。
- 关注点:操作系统如何管理磁盘空间和实现文件到物理块的映射。
---
48. 简述 Web 开发中的 MVC 设计模式,各组件的职责是什么?有哪些实际应用案例?
回答:
MVC 设计模式:
MVC (Model-View-Controller) 是一种软件设计模式,它将应用程序强制分为三个基本部分,每个部分处理不同的功能,以实现**关注点分离**。
- 各组件的职责:
1. Model (模型):
- 负责应用程序的**业务逻辑**和**数据**。它处理数据的存取、处理和状态管理。
- 当数据发生变化时,它会通知相关的视图(View)。
- 它不关心数据如何被展示。
2. View (视图):
- 负责**用户界面**的展示。它从模型中获取数据,并将其呈现给用户。
- 它不包含任何业务逻辑,只是一个数据的可视化表现。
- 用户的操作(如点击按钮)会由视图捕获并传递给控制器。
3. Controller (控制器):
- 作为**模型和视图之间的协调者**。它接收用户的输入(来自视图),解析输入,然后调用相应的模型来处理业务逻辑。
- 处理完后,它会选择一个合适的视图来展示结果。
工作流程:
1. 用户在**视图**上进行操作。
2. 控制器接收到请求。
3. 控制器调用**模型**来更新数据或执行业务逻辑。
4. 模型更新完毕后,可能会通知**视图**数据已发生变化。
5. 视图从**模型**获取最新的数据,并更新自己的显示,呈现给用户。
实际应用案例:
MVC 是一种非常经典和广泛使用的模式,许多Web框架都是基于它或其变体(如MVP, MVVM)构建的。
- Java:Spring MVC 框架。
- Python:Django, Flask 框架。
- Ruby:Ruby on Rails 框架。
- PHP:Laravel, Symfony 框架。
- 前端:早期的 AngularJS (MVW, Model-View-Whatever),以及 React (通常被认为是V,但常与Flux/Redux等架构配合,形成类似MVC的模式) 和 Vue.js (MVVM模式)。
---
49. 数据库中的视图是什么?视图与基本表的区别是什么?视图的作用和应用场景有哪些?
回答:
什么是视图 (View)?
视图是一个**虚拟表**,它的内容由一个 SQL 查询语句定义。视图本身不存储任何数据,它包含的行和列数据来自于其定义所引用的一个或多个基本表。
视图与基本表的区别:
1. 数据存储:**基本表 (Base Table)**是真实存在的、物理上存储数据的表。而**视图**是一个虚拟表,它不实际存储数据,数据仍然存放在基本表中。
2. 操作:对基本表的操作(增删改)是直接作用于物理数据的。对视图的增删改操作最终会转化为对基本表的操作,但并非所有视图都是可更新的(例如,包含聚合函数、JOIN操作的视图通常不可更新)。
3. 依赖性:视图依赖于基本表,如果基本表的结构发生改变,可能会导致视图失效。
视图的作用和应用场景:
1. 简化复杂查询:可以将一个复杂的、涉及多表连接的查询定义成一个视图。之后,用户就可以像查询一个单表一样来查询这个视图,大大简化了操作。
2. 数据安全性:可以通过视图向用户暴露表的特定列,而隐藏其他敏感列(如薪资、个人身份信息),从而实现基于列的访问控制。
3. 逻辑数据独立性:当基本表的结构发生变化时(如增加列、拆分表),只要视图的定义不变,面向视图的应用程序代码就无需修改,从而提供了一定程度的逻辑数据独立性。
4. 提供定制化数据:可以为不同的用户或应用创建不同的视图,让他们看到符合自己需求的数据格式和内容。
---
50. 计算机网络中的 TCP 协议如何实现可靠传输?请从序列号、确认机制、重传机制等方面说明。
回答:
TCP 通过多种机制协同工作,来保证数据在不可靠的网络上实现可靠的传输。
1. 序列号 (Sequence Number):
- TCP 是面向字节流的,它会为要发送的每一个字节都进行编号。在发送 TCP 段时,头部中的**序列号**字段会标记该段数据中第一个字节的编号。
- 作用:
- 保证有序性:接收方可以根据序列号对乱序到达的 TCP 段进行重新排序,组装成正确的字节流。
- 去除重复:接收方可以根据序列号识别并丢弃重复接收的数据段。
2. 确认机制 (Acknowledgement):
- 接收方每成功收到一个 TCP 段,都会向发送方发送一个确认(ACK)报文。
- 报文头部中的**确认号**字段表示“期望收到的下一个字节的序列号”。这是一种**累积确认**机制,例如,确认号为 N 表示序列号 N-1 之前的所有数据都已正确无误地收到了。
- 作用:让发送方明确知道哪些数据已经被对方成功接收。
3. 重传机制 (Retransmission):
- 当发送方在规定时间内没有收到对某个数据段的确认时,就认为该数据段可能在网络中丢失了,于是会重新发送这个数据段。
- 主要方式:
- 超时重传 (Timeout Retransmission):发送方为每个已发送但未被确认的数据段设置一个计时器(RTO, Retransmission Time-Out)。如果计时器超时,就会触发重传。RTO 的值是根据网络延迟动态计算的。
- 快速重传 (Fast Retransmission):当发送方连续收到**三个或以上**的重复 ACK 时(例如,收到了三个对序列号 N 的确认),它会不等超时计时器到期,就立即重传序列号为 N 的数据段。因为重复 ACK 表明接收方确实收到了后续的数据,但中间的某个数据段丢失了。
4. 流量控制 (Flow Control):
- 通过**滑动窗口机制**,接收方可以告知发送方自己还有多少缓冲区空间(通过 ACK 报文中的窗口大小字段)。发送方根据这个窗口大小来控制自己的发送速率,防止发送过快导致接收方缓冲区溢出。
5. 拥塞控制 (Congestion Control):
- 通过**慢启动、拥塞避免、快重传、快恢复**等算法,发送方可以感知网络的拥塞状况,并动态调整发送速率,防止因注入过多数据而导致网络崩溃。
通过以上这些机制的紧密配合,TCP 能够在 IP 协议“尽力而为”的不可靠服务之上,构建出面向连接的、可靠的数据传输服务。
---
51. 什么是软件工程中的需求工程?需求分析的主要任务和方法有哪些?如何处理需求变更?
回答:
什么是需求工程?
需求工程是软件工程中的一个关键过程,它涵盖了与发现、分析、定义、记录和维护软件需求相关的所有活动。其目标是确保开发出的软件系统能够真正满足用户、客户和其他利益相关者的需求和期望。
需求分析的主要任务:
1. 需求获取 (Elicitation):与客户、用户等进行沟通,通过访谈、问卷、观察、会议等方式,收集和发掘他们对软件系统的原始需求。
2. 需求分析与建模 (Analysis and Modeling):对收集到的模糊、不完整甚至矛盾的需求进行整理、分类、协商和精化,构建需求模型(如用例图、数据流图、实体关系图等)来清晰地描述系统功能和约束。
3. 需求规格说明 (Specification):将经过分析和确认的需求,以清晰、准确、无歧义的方式编写成《需求规格说明书》(SRS),作为开发、测试和验收的依据。
4. 需求验证 (Validation):评审需求规格说明书,检查其是否正确、完整、一致、可行,确保所有利益相关者对需求的理解达成一致。
5. 需求管理 (Management):在整个软件生命周期中,跟踪和控制需求的状态,处理需求的变更。
需求分析的常用方法:
- 结构化分析 (Structured Analysis, SA):使用数据流图 (DFD)、数据字典 (DD) 和处理逻辑规格说明等工具,对系统进行自顶向下的功能分解。
- 面向对象分析 (Object-Oriented Analysis, OOA):识别问题域中的对象、类及其关系,使用 UML(统一建模语言)中的用例图、类图、时序图等来建立系统模型。
- 原型法 (Prototyping):快速构建一个可工作的系统原型,让用户进行试用和评估,通过反馈来澄清和完善需求。
如何处理需求变更?
需求变更是不可避免的,必须通过一个规范的流程来管理:
1. 建立变更控制流程:成立一个变更控制委员会 (CCB),或指定专人(如产品负责人)来负责审批所有变更请求。
2. 提交变更请求:所有需求变更都必须以正式的书面形式(变更请求单)提交。
3. 影响分析:对变更请求进行评估,分析它对项目范围、成本、进度、资源和技术风险等方面的影响。
4. 评审与决策:变更控制委员会或负责人根据影响分析的结果,决定是批准、拒绝还是推迟该变更。
5. 实施与跟踪:如果变更被批准,则更新需求文档、设计、代码和测试用例,并将变更通知到所有相关人员。
6. 版本控制:所有与需求相关的文档都应纳入版本控制系统,以跟踪变更历史。
---
52. 操作系统中的中断和异常有什么区别?中断处理的过程是怎样的?
回答:
中断和异常的区别:
中断和异常都是改变 CPU 正常执行流程的事件,但它们的来源和处理方式有所不同。
- 来源不同:
- 中断 (Interrupt):通常是**来自外部设备**的异步事件,与 CPU 当前执行的指令无关。例如,键盘输入、鼠标移动、网卡收到数据包、定时器到时等。
- 异常 (Exception):是**由 CPU 内部**执行指令时产生的同步事件。它与当前正在执行的指令密切相关。例如,除以零、非法指令、缺页、访问越界内存等。
- 触发时机不同:
- 中断的发生是**随机的、不可预测的**。
- 异常的发生是**可预测的**,只要执行到特定的指令就会触发。
- 处理方式:
- 中断处理程序通常是处理外部 I/O 事件。
- 异常处理程序则根据异常类型采取不同措施:**修复**(如缺页异常)、**终止进程**(如非法指令)、或将异常**报告给应用层**(如除零异常)。
中断处理的过程:
1. 中断请求:外部设备完成操作后,向 CPU 发送一个中断信号。
2. 中断响应:CPU 在每条指令执行周期的末尾,会检查是否有中断请求。如果有,并且中断是允许的,CPU 会暂停当前执行的程序。
3. 保护现场 (保存上下文):
- CPU 将当前程序的**程序计数器 (PC)** 和 程序状态字 (PSW) 等关键寄存器的内容压入内核栈。
- 这样做是为了在中断处理完毕后,能够准确地返回到被打断的地方继续执行。
4. 寻找中断处理程序:
- CPU 根据中断源提供的**中断向量**(一个唯一的编号),到**中断向量表 (IVT)** 中查找到对应的**中断服务程序 (ISR)** 的入口地址。
5. 执行中断服务程序:
- CPU 跳转到中断服务程序的地址开始执行。
- 中断服务程序会处理中断事件,例如,从网卡缓冲区读取数据到内存。
6. 恢复现场 (恢复上下文):
- 中断服务程序执行完毕后,会从内核栈中弹出之前保存的 PC 和 PSW 等寄存器的值,恢复到 CPU 中。
7. 返回原程序:CPU 回到之前被中断的指令的下一条,继续执行原来的程序,仿佛中断从未发生过。
---
53. 简述大数据处理中的分布式文件系统(如 HDFS)的架构和特点,与传统文件系统有何不同?
回答:
HDFS (Hadoop Distributed File System) 架构和特点:
HDFS 是为在商用硬件上运行而设计的、高容错、高吞吐量的分布式文件系统。
- 架构:采用主/从(Master/Slave)架构。
- NameNode (主节点):整个文件系统的“大脑”。它负责管理文件系统的**元数据 (Metadata)**,包括文件目录树、文件与数据块的映射关系、数据块在各个 DataNode 上的位置信息等。系统中通常只有一个活动的 NameNode。
- DataNode (从节点):文件系统的“肌肉”。它们负责存储实际的**数据块 (Block)**。DataNode 会定期向 NameNode 发送心跳和块报告,告知自己的存活状态和存储信息。
- Client (客户端):与 NameNode 交互获取文件元数据,然后直接与 DataNode 交互来读写数据。
- 特点:
1. 为大数据设计:专为存储超大文件(GB、TB 甚至 PB 级别)而设计,采用大的数据块(默认128MB或256MB)来最小化寻址开销。
2. 高容错性:通过**数据副本 (Replication)** 机制保证可靠性。默认情况下,每个数据块会在不同的 DataNode 上存储 3 个副本。当某个 DataNode 故障时,系统可以从其他副本恢复数据。
3. 高吞吐量:通过“一次写入,多次读取”的模型优化,支持大规模数据的并行处理和流式访问,适合 MapReduce 等计算框架。
4. 运行于商用硬件:设计之初就考虑了硬件故障是常态,因此可以在廉价的通用服务器集群上运行。
5. 不适合低延迟访问:HDFS 追求的是高吞吐量,不适合对单个文件进行低延迟的随机读写操作。
与传统文件系统(如 NTFS, ext4)的不同:
1. 规模与分布:传统文件系统通常是单机的,管理一块或多块本地磁盘。HDFS 是分布式的,管理一个由成百上千台机器组成的集群的存储资源。
2. 数据块大小:传统文件系统的数据块通常很小(如 4KB),以优化小文件的存储效率。HDFS 的数据块非常大(如 128MB),以提高大文件传输的吞吐量。
3. 容错机制:传统文件系统依赖于硬件(如 RAID)来保证可靠性。HDFS 在软件层面通过数据多副本来实现容错。
4. 数据访问模式:传统文件系统支持任意文件的随机读写。HDFS 主要针对大文件的顺序读写进行优化,对随机写和文件修改的支持很弱(通常只支持追加写)。
5. 元数据管理:传统文件系统的元数据和数据都存在本地磁盘。HDFS 的元数据集中由 NameNode 管理,数据则分布在各个 DataNode 上。
---
54. 软件测试中的白盒测试和黑盒测试有什么区别?各有有哪些常用的测试方法?
回答:
白盒测试与黑盒测试的区别:
主要区别在于**测试时是否需要了解和利用程序的内部结构和逻辑**。
- 白盒测试 (White-box Testing):
- 定义:也称为结构测试或逻辑驱动测试。测试人员能够看到程序的内部源代码和逻辑结构。测试用例的设计基于代码的逻辑路径、分支、循环等。
- 测试对象:程序的内部逻辑、代码结构。
- 目标:确保程序内部的每一条路径都能够被正确地执行。
- 执行者:通常是开发人员。
- 黑盒测试 (Black-box Testing):
- 定义:也称为功能测试或数据驱动测试。测试人员完全不关心程序的内部实现,只把程序看作一个“黑盒子”。测试用例的设计基于软件的需求规格说明,只关注程序的输入和输出是否符合预期。
- 测试对象:程序对外提供的功能。
- 目标:验证软件的功能是否满足需求。
- 执行者:通常是独立的测试人员。
常用的测试方法:
- 白盒测试常用方法:
1. 语句覆盖 (Statement Coverage):设计测试用例,确保代码中的每一条可执行语句至少被执行一次。
2. 判定覆盖 (Decision Coverage) / 分支覆盖 (Branch Coverage):设计测试用例,确保程序中每个判断语句的“真”和“假”分支都至少被执行一次。
3. 条件覆盖 (Condition Coverage):设计测试用例,确保判断语句中每个子条件的“真”和“假”结果都至少出现一次。
4. 路径覆盖 (Path Coverage):设计测试用例,覆盖程序中所有可能的执行路径。这是最强的覆盖标准,但在实践中往往难以完全实现。
5. 循环覆盖 (Loop Coverage):针对循环结构,测试其零次、一次和多次执行的情况。
- 黑盒测试常用方法:
1. 等价类划分法 (Equivalence Class Partitioning):将程序的输入数据划分为若干个等价类,从每个等价类中选取一个代表性的数据作为测试用例。
2. 边界值分析法 (Boundary Value Analysis):等价类划分的补充,重点测试输入范围的边界值(如最大值、最小值、刚好超过边界的值)。
3. 因果图法 (Cause-Effect Graphing):分析输入条件(因)和输出结果(果)之间的逻辑关系,设计测试用例。
4. 判定表法 (Decision Table Testing):适用于逻辑判断条件组合复杂的场景,列出所有可能的条件组合和对应的操作。
5. 场景法 (Use Case Testing):模拟用户实际使用软件的场景,设计测试用例来覆盖主要业务流程。
---
55. 什么是计算机网络中的 NAT(网络地址转换)?NAT 的作用和类型(如静态 NAT、动态 NAT)有哪些?
回答:
什么是 NAT?
NAT (Network Address Translation) 是一种在 IP 包通过路由器或防火墙时,重写源或目的 IP 地址的技术。它最常见的应用是允许多台处于私有网络(使用私有IP地址,如 192.168.x.x)的主机共享一个或少数几个公网 IP 地址来访问互联网。
NAT 的作用:
1. 缓解 IPv4 地址耗尽:这是 NAT 最主要的作用。一个公司或家庭只需要一个公网 IP,就可以让内部所有设备都上网,极大地节省了公网 IP 地址。
2. 增强网络安全:NAT 隐藏了内部网络的结构和私有 IP 地址。外部网络无法直接访问内部主机,起到了一定的防火墙作用。
NAT 的类型:
1. 静态 NAT (Static NAT):
- 原理:将一个私有 IP 地址与一个公网 IP 地址进行**一对一**的、永久性的映射。
- 应用场景:当需要让外部网络主动访问内部的某台特定服务器(如 Web 服务器、邮件服务器)时使用。
2. 动态 NAT (Dynamic NAT):
- 原理:定义一个公网 IP 地址池。当内部主机需要访问外部网络时,NAT 设备会从地址池中**临时选择一个未使用的公网 IP 地址**与其进行映射。当通信结束后,该公网 IP 地址会被回收,可供其他内部主机使用。这是一个**多对多**的映射。
- 缺点:如果公网 IP 地址池中的地址数量少于同时需要上网的内部主机数量,后来的主机将无法上网。
3. NAPT (Network Address Port Translation) / PAT (Port Address Translation):
- 原理:这是目前最常用的一种 NAT 形式,也常被称为“IP 伪装”。它将多个私有 IP 地址映射到**同一个公网 IP 地址的不同端口号**上。NAT 设备维护一张转换表,记录了 (私有IP:私有端口) 到 (公网IP:公网端口) 的映射关系。
- 应用场景:家庭宽带路由器、企业网关等。它实现了**多对一**的地址转换,最大程度地节省了公网 IP。
---
56. 操作系统中的管程 (Monitor) 是什么?管程如何解决进程同步问题?与信号量机制有何区别?
回答:
什么是管程?
管程是一种高级的进程同步机制,它将共享资源和所有对该资源进行操作的过程(方法)封装在一个模块(或类)内部。进程只能通过调用管程提供的过程来访问共享资源。管程在语言层面保证了在任何时候,**最多只有一个进程**能在管程内执行,从而实现了对共享资源的互斥访问。
管程如何解决进程同步问题?
管程通过以下三个核心组件来解决同步问题:
1. 互斥访问:管程的特性保证了其内部代码的互斥执行。当一个进程进入管程执行一个过程时,其他试图进入的进程都必须等待。
2. 共享数据结构:所有需要同步的共享变量都被封装在管程内部,外部进程无法直接访问。
3. 条件变量 (Condition Variables):当一个进程在管程内因为某个条件不满足而无法继续执行时(例如,生产者发现缓冲区已满),它不能一直占用管程。此时,它可以在一个**条件变量**上执行 wait() 操作,将自己阻塞并释放对管程的互斥访问权,让其他进程可以进入管程。当另一个进程进入管程并改变了条件(例如,消费者取走数据使缓冲区不满)后,它可以对同一个条件变量执行 signal() 操作,唤醒一个之前因该条件而等待的进程。
与信号量机制的区别:
1. 封装性:**管程**是更高级的抽象,它将共享资源和操作封装在一起,同步逻辑由编译器或语言运行时实现,程序员只需调用 wait() 和 signal()。而**信号量**只是一种简单的计数器,其 P (wait) 和 V (signal) 操作分散在各个进程的代码中,同步逻辑需要程序员自己小心编写,容易出错。
2. 互斥实现:在管程中,**互斥是隐式的**,由管程的定义保证。在使用信号量时,**互斥是显式的**,需要程序员手动使用一个互斥信号量(mutex)来保护临界区。
3. 安全性:管程的封装性使得它比信号量更安全,更不容易出错(如忘记执行 V 操作导致死锁)。信号量机制则更加灵活,但对程序员的要求更高。
4. 抽象层次:管程是面向过程或对象的,更符合结构化编程思想。信号量是更底层的同步原语。
---
57. 简述云计算的三种服务模式(IaaS、PaaS、SaaS),并举例说明每种模式的典型应用。
回答:
云计算的三种服务模式是根据云服务提供商为用户提供的服务层次来划分的。可以把它们比作吃披萨:
- IaaS (自己做披萨):提供商提供厨房、烤箱、面粉。
- PaaS (外卖披萨):提供商把做好的披萨送到你家。
- SaaS (去餐厅吃披萨):直接去餐厅,什么都不用管。
三种服务模式:
1. IaaS (Infrastructure as a Service) - 基础设施即服务:
- 提供内容:提供最底层的计算、存储、网络等**基础设施资源**。用户可以租用虚拟机、服务器、存储空间、负载均衡器等。
- 用户责任:用户需要自己管理操作系统、中间件、运行时环境以及应用程序和数据。
- 特点:灵活性最高,用户拥有最大的控制权。
- 典型应用/厂商:
- Amazon Web Services (AWS):提供 EC2 (虚拟机)、S3 (对象存储) 等。
- Microsoft Azure:提供 Virtual Machines, Blob Storage 等。
- Google Cloud Platform (GCP):提供 Compute Engine 等。
- 阿里云、腾讯云:提供 ECS (云服务器) 等。
2. PaaS (Platform as a Service) - 平台即服务:
- 提供内容:在 IaaS 的基础上,提供了一个完整的**应用程序开发和部署平台**,包括操作系统、数据库、Web 服务器、编程语言运行时等。
- 用户责任:用户只需要关注自己的**应用程序代码和数据**的开发和管理,无需关心底层的硬件和平台维护。
- 特点:大大简化了开发和部署流程,让开发者可以专注于业务逻辑。
- 典型应用/厂商:
- Heroku:一个流行的应用托管平台。
- Google App Engine (GAE)
- AWS Elastic Beanstalk
- 各种数据库服务如 **Amazon RDS**, Azure SQL Database 也属于 PaaS。
3. SaaS (Software as a Service) - 软件即服务:
- 提供内容:提供一个**可以直接使用的、完整的软件应用**。用户通过网络浏览器或客户端访问软件,按需(通常是订阅制)使用。
- 用户责任:用户几乎不需要进行任何技术管理,只需使用软件即可。
- 特点:开箱即用,无需安装和维护,对用户最友好。
- 典型应用/厂商:
- 办公协作:Google Workspace (Gmail, Docs), Microsoft Office 365。
- 客户关系管理 (CRM):Salesforce。
- 项目管理:Trello, Jira。
- 云存储:Dropbox, Google Drive。