网络面试题手册

梳理高频技术问题,帮助你按主题复习和查漏补缺。

前端阅读 685月27日 01:12

TCP 建立连接需要经过哪几步?

TCP 三次握手建立连接:客户端 → SYN:客户端发 SYN=1,seq=x(随机初始序列号)。客户端进入 SYN-SENT 状态服务端 → SYN+ACK:服务端回 SYN=1,ACK=1,seq=y,ack=x+1。服务端进入 SYN-RCVD 状态客户端 → ACK:客户端发 ACK=1,seq=x+1,ack=y+1。双方进入 ESTABLISHED 状态为什么是三次不是两次?因为要防止已失效的连接请求到达服务端。如果只有两次,客户端发了一个 SYN 因为网络延迟没到,客户端超时重发了一个新的 SYN 建立了连接。之后旧的 SYN 到达服务端,服务端以为这是新连接,回 SYN+ACK 就建立了连接——但客户端根本不知道这个连接的存在。追问为什么不是四次握手?理论上四次(SYN → SYN+ACK → ACK → 服务端收到 ACK 确认)更稳妥。但第三步的 ACK 可以和服务端收到 ACK 合并——服务端只需要知道客户端收到了自己的 SYN+ACK 就够。额外的第四次是冗余的。SYN 泛洪攻击是什么?攻击者发送大量 SYN 但不回 ACK,导致服务端大量连接处于 SYN-RCVD 半连接状态,耗尽服务端资源。防御:SYN Cookie(服务端不分配资源,用 Cookie 验证客户端是真的)、减少 SYN-RCVD 超时时间。TCP 四次挥手为什么多一次?因为 TCP 是全双工的——每个方向都要独立关闭。客户端 FIN 表示"我说完了",服务端 ACK 表示"知道了",但如果服务端还有数据要发,发完后再 FIN。所以是 FIN → ACK → FIN → ACK 四步。
计算机基础阅读 925月27日 01:11

GET 和 POST 的区别是什么?何时使用 POST?

从 HTTP 协议本身看,GET 和 POST 只有两个本质区别:语义不同:GET 是"获取"(安全、幂等),POST 是"提交数据以处理"(不幂等)POST 有 body,GET 没有(GET 也可以有 body,但 RFC 不推荐,很多实现不支持)其他所谓的区别——"GET 参数在 URL 里,POST 在 body 里"、"GET 参数长度有限制"、"GET 被浏览器缓存"——要么是实现细节,要么是浏览器的行为,不是协议本身的约束。何时用 POST:创建/修改资源、提交表单、需要传大量数据、需要隐藏敏感参数(虽然 body 也不安全,HTTPS 才是真正保护)。追问GET 请求真的不能有 body 吗?RFC 7231 没有禁止,但建议不要给 GET 加 body。实际上 fetch 和 XMLHttpRequest 都支持带 body 的 GET,但浏览器 <form> 和 <a> 不支持,很多中间件/代理也不处理 GET body。PUT 和 POST 有什么区别?都是提交数据,但语义不同:PUT 是幂等的(多次调用结果相同——替换指定位置的资源),POST 不是(多次调用可能创建多个资源)。PUT 的 URL 通常确定具体资源(/users/1),POST 是集合 URL(/users)。POST 比 GET 更安全吗?不安全。POST body 在 HTTP 下仍然是明文传输,只是 URL 里看不到而已。HTTPS 下二者都加密后才发送,POST 的"安全性"优势在 HTTPS 下不存在。真正的区别是 POST 数据不会出现在日志/浏览器历史/server log 的 URL 中。
计算机基础阅读 1145月27日 01:10

HTTP 有哪些常用的状态码?

按分类记:2xx 成功:200 OK:请求成功201 Created:创建资源成功(POST 返回)204 No Content:成功但无响应体(DELETE 后常见)3xx 重定向:301 Moved Permanently:永久重定向(浏览器会缓存,下次直接跳)302 Found:临时重定向304 Not Modified:资源未修改,用缓存(配合 If-Modified-Since/ETag)307/308:和 301/302 类似,但 POST 转 GET 行为不同4xx 客户端错误:400 Bad Request:请求格式错误401 Unauthorized:未认证403 Forbidden:已认证但无权限404 Not Found:资源不存在405 Method Not Allowed:方法不对(比如用 GET 调了 POST 接口)429 Too Many Requests:被限流5xx 服务端错误:500 Internal Server Error:服务端内部错误502 Bad Gateway:网关/代理收到无效上游响应503 Service Unavailable:服务暂不可用(维护/过载)504 Gateway Timeout:网关超时追问301 和 302 的区别?301 是永久的——浏览器会缓存重定向目标,之后相同 URL 直接跳转,不用再请求原地址。SEO 权重转移。302 是临时的——每次都会请求原地址再跳转。语义不同,对 SEO 和缓存影响很大。401 和 403 怎么区分?401 是"你是谁?"——没登录或 token 过期,需要你去认证。403 是"我知道你是谁,但不让你看"——认证通过了但权限不够。502 和 504 的区别?502 是网关从上游收到了无效/不完整的响应(服务崩溃、配置错误)。504 是网关在规定时间内没等到上游响应(超时)。排查方向:502 看服务有没有挂,504 看服务是不是太慢。
计算机基础阅读 865月27日 00:54

HTTPS 和 HTTP 的缓存有什么区别?

HTTPS 和 HTTP 在缓存机制上没有本质区别,缓存规则(Cache-Control、ETag、Expires)在两种协议下都生效。关键差异在安全性导致的行为不同。浏览器对 HTTPS 内容的缓存更谨慎——不会把 HTTPS 资源缓存到磁盘(除非服务端明确允许),隐私模式下 HTTPS 缓存行为也更保守。代理服务器(CDN、中间代理)对 HTTPS 内容无法解密查看,只能根据 URL 和响应头做缓存决策,不能像 HTTP 那样分析内容。HTTPS 的缓存键可以用 Vary 响应头控制。共用缓存(shared cache)场景下,HTTPS 加解密有性能开销,建议配合 CDN 在边缘节点缓存静态资源,减少回源。追问为什么中间代理缓存不了 HTTPS 内容?HTTPS 端到端加密,中间代理看不到内容,只能根据 URL 缓存。所以 HTTPS 更依赖 CDN(CDN 持有证书可以解密后缓存)。HTTPS 对缓存性能有影响吗?加解密有 CPU 开销,但现代硬件都支持硬件加速(AES-NI),影响很小。真正影响首屏的是 TLS 握手多一次 RTT,用 HTTP/2 或 HTTP/3 可以缓解。浏览器对 HTTPS 和 HTTP 缓存策略有什么不同?HTTPS 资源默认不会缓存到磁盘(隐私考虑),HTTP 资源会。如果希望 HTTPS 也磁盘缓存,服务端设 Cache-Control: public。
前端阅读 02月7日 13:25

Ruby 如何将哈希转化为HTTP参数?

引言在Ruby开发中,将哈希(Hash)转化为HTTP参数(如查询字符串或表单数据)是构建Web请求的核心操作。这一过程常见于API调用、表单提交或URL构建场景,其核心目标是将Ruby对象结构转换为符合HTTP协议的编码格式(如key1=value1&key2=value2)。如果处理不当,可能导致特殊字符未正确编码(如空格转为%20),引发安全漏洞(如XSS攻击)或请求失败。本文将深入探讨Ruby中专业的转换方法,结合代码示例和最佳实践,确保开发过程高效可靠。主体内容基础方法:使用URI.encode_www_formRuby标准库提供了URI模块的encode_www_form方法,这是最推荐的方案。它能自动处理哈希的扁平化和URL编码,支持嵌套结构,且兼容RFC 3986规范。核心优势在于:自动编码:将特殊字符(如空格、&)转换为百分号编码(例如John Doe → John%20Doe)。嵌套处理:对于嵌套哈希,会生成多级键(如user[name]=John)。安全可靠:避免手动编码的陷阱,减少安全风险。代码示例:require 'uri'# 创建示例哈希hash = { name: "John Doe", age: 30, address: { city: "New York", zip: "10001" }}# 转换为HTTP参数params = URI.encode_www_form(hash)# 输出结果: name=John%20Doe&age=30&address[city]=New%20York&address[zip]=10001puts params关键解析:URI.encode_www_form(hash) 直接处理哈希,返回字符串。嵌套哈希会被自动扁平化,键路径用方括号分隔(address[city])。特殊字符如空格被编码为%20,确保浏览器和服务器正确解析。替代方案:使用CGI.escape(需谨慎)在Ruby 2.0之前,CGI模块的escape方法是常见选择,但不推荐用于现代项目,原因如下:仅处理单值:CGI.escape针对字符串,需手动遍历哈希。嵌套不友好:无法直接处理多级结构,需自定义逻辑。安全风险:对特殊字符处理不如URI严格(例如&未被转义,可能破坏查询字符串)。代码示例:require 'cgi'# 手动处理哈希(不推荐)hash = { name: "John Doe", age: 30 }params = hash.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v)}" }.join('&')# 输出结果: name=John%20Doe&age=30puts params实践建议:仅在遗留系统中使用此方法。优先选择URI.encode_www_form,因为它更简洁、安全。重要注意事项1. 特殊字符编码HTTP参数要求对非ASCII字符和特殊符号进行编码(如&、=、空格),否则会导致解析错误。URI.encode_www_form自动处理,但需注意:空格:转换为%20(而非空格字符)。&和=:这些字符在查询字符串中作为分隔符,必须编码以避免语法错误。2. 嵌套哈希的处理若哈希包含嵌套结构,URI.encode_www_form会生成key[inner_key]=value格式。但需确保:避免循环引用:在大型数据中,检查哈希是否包含循环引用(如{ user: { id: 1 } }会转换为user[id]=1)。自定义键路径:如需调整键名(例如user.name),需手动扁平化哈希。3. 安全最佳实践防止XSS:始终对用户输入进行编码,避免恶意数据注入。验证参数:在接收端,使用CGI.unescape或URI.decode_www_form解码后验证,防止攻击。测试边界:使用工具(如minitest)测试边缘案例(例如包含%或+的值)。实际应用场景在Web框架中(如Ruby on Rails),此转换常用于:API客户端:发送POST请求时,将数据转换为application/x-www-form-urlencoded格式。表单处理:在params对象中,直接使用哈希生成查询字符串。示例:require 'net/http'uri = URI.parse('https://api.example.com/users')# 使用哈希生成请求参数params = URI.encode_www_form({ name: 'Alice', age: 25 })# 发送HTTP请求response = Net::HTTP.post_form(uri, params)实践建议:在API调用中,确保URI.encode_www_form与Net::HTTP集成顺畅。对于JSON数据,使用JSON.generate而非此方法(HTTP参数特指表单格式)。结论将Ruby哈希转化为HTTP参数是Web开发中的基础技能,核心在于选择安全、高效的工具。本文推荐使用URI.encode_www_form,因其能自动处理编码、嵌套结构和安全边界,避免手动编码的常见错误。在实际项目中,务必遵循以下原则:优先使用标准库:URI模块是Ruby的官方推荐,无需额外依赖。验证输入:在转换前检查哈希内容,防止恶意数据。测试全面性:覆盖空值、特殊字符和嵌套场景。掌握此技巧,能显著提升API交互的可靠性和安全性。作为开发者,持续关注Ruby更新(如Ruby 3.x的改进),并结合测试框架确保代码健壮性。记住:编码是Web安全的基石,细节决定成败。参考资源:Ruby URI DocumentationRFC 3986: URI Syntax注:本文聚焦于HTTP参数转换,不涉及其他协议(如JSON)。
计算机基础阅读 1222024年8月5日 12:53

UDP 和 TCP 有什么区别?

TCP(传输控制协议)和UDP(用户数据报协议)都是互联网协议套件中的传输层协议,它们在网络中传输数据有着本质的区别:连接性:TCP 是面向连接的协议。在数据传输之前,它需要建立连接。一个TCP连接需要经过三次握手过程,确保双方准备好进行数据传输。UDP 是无连接的协议。它不需要预先建立连接,数据可以直接发送给接收方,不必等待建立连接。可靠性:TCP 提供可靠的数据传输服务。通过序列号、确认应答、重传控制、流量控制和拥塞控制等机制,确保数据的正确性和顺序性。UDP 不保证数据的可靠传输。它发送的数据包可能会丢失或者顺序错乱,且没有内建的机制来纠正这些错误。速度和效率:TCP 由于其确保数据准确性和顺序性的机制,通常比UDP慢。这些机制使TCP非常可靠,但也增加了通信的开销。UDP 由于缺少复杂的控制机制,能够提供更快的数据传输速度,适用于对实时性要求高的应用,如视频会议和在线游戏。数据流:TCP 提供字节流服务。通过TCP连接发送的数据是按照字节流方式进行传输的,接收方会按照发送时的顺序来接收数据。UDP 提供数据报服务。每个UDP用户数据报是独立传输的,每个数据报都有明确的边界。头部开销:TCP 的头部开销比UDP大。TCP头部至少20字节,包含许多用于保障可靠传输的信息。UDP 的头部开销小,仅有8字节,适合传输小量数据。用例示例:TCP 的典型应用包括Web浏览(HTTP/HTTPS)、电子邮件(SMTP/POP/IMAP)和文件传输(FTP)等,这些应用都需要数据的准确传输。UDP 常用于流媒体传输(如视频和音频流)、在线游戏、语音通话(VoIP)等,这些应用更注重速度而非每个数据包的完整性。总结来说,TCP和UDP各有优缺点,适用于不同的网络应用场景。TCP通过复杂的机制保证数据的可靠性,适合需要高可靠性的应用。UDP则因其低延迟特性,适用于需要快速数据传输但可以容忍一定数据丢失的应用。
计算机基础阅读 1152024年8月5日 12:51

HTTP 协议 1.0 和 1.1 和 2.0 有什么区别?

HTTP(超文本传输协议)是 Web 上交换数据的基础协议,随着 Web 技术的发展,HTTP 也经历了多个版本的迭代。下面我会详细介绍 HTTP 1.0、1.1 和 2.0 这三个版本的区别:HTTP 1.0无状态连接:HTTP 1.0 是无状态的,也就是说每次请求都需要建立一个新的TCP连接,完成数据传输后连接就会关闭。这种方式在每次请求都需要经历 TCP 连接的建立和断开过程,导致性能上的不足。限制性能:由于每次请求都要建立新的连接,所以并发多个请求会导致大量的延迟和性能问题。无宿主名(Host)字段:HTTP 1.0 不支持 Host 头部。这意味着同一个物理服务器上无法托管多个域名的网站。HTTP 1.1持久连接:HTTP 1.1 默认采用持久连接(也称为“keep-alive”),允许在一个TCP连接上发送和接收多个HTTP请求/响应,从而减少了TCP连接的开销。管线化:HTTP 1.1 引入了请求的管线化,理论上客户端可以在收到前一个响应之前发送下一个请求,减少了请求的延迟。但实际上,由于某些浏览器和服务器的实现问题,这个特性并未广泛使用。新增头部字段:例如 Host(它允许在同一物理服务器上虚拟托管多个域名)、Etag(实体标签,可以协助缓存验证)、Accept-Encoding(指定客户端可以接收的内容编码类型)等。缓存控制:更复杂和灵活的缓存控制机制,使得客户端和服务器可以更有效地协商数据的缓存,减少不必要的数据传输。分块传输编码:允许服务器开始发送响应而不需要先知道全部内容的总大小。HTTP 2.0二进制协议:HTTP/1.x 是文本协议,而 HTTP/2 是二进制协议,提供了更高效的解析和网络传输。多路复用:在同一个连接上并行交错地发送多个请求和响应,而不会互相影响,极大地提高了传输效率和减少了延迟。流优先级:可以为 HTTP/2 连接上的流设置优先级,允许更重要的资源先被发送。服务器推送:服务器可以对一个客户端请求发送多个响应,允许服务器主动推送资源给客户端,进一步提升页面加载效率。头部压缩:HTTP/2 引入了 HPACK 压缩格式,用于减小头部大小,以减少传输延迟。举例来说,一个明显的性能改进是在使用HTTP/2时浏览一个网站:由于多路复用和头部压缩等特性,相比于 HTTP/1.1,网页的加载时间可以显著减少,尤其是在网络条件较差或加载资源较多的场景下。此外,HTTP/2 的服务器推送功能允许服务器预先推送静态资源,比如 CSS 或 JavaScript 文件,这可以进一步提高加载速度,因为浏览器不必等待解析 HTML 再去请求这些资源。
前端阅读 1392024年6月24日 16:43

Proxy 的代理原理,以及 Proxy 是如何使用的?

代理原理:Proxy,也称为代理服务器,其基本原理是作为客户端和服务器之间的中介角色。当客户端请求网页或其他网络服务时,代理服务器会接收这个请求,然后代表客户端向真正的服务器发送请求。代理服务器收到服务器的响应后,再将数据转发给客户端。这个过程实现了数据的中转,可以用于多种用途,如内容缓存、过滤请求、负载均衡、隐私保护等。使用Proxy的方式:Proxy 的使用可以根据不同的需求和场景分为几种方式:客户端配置:在客户端(如浏览器、操作系统)中设置代理服务器的地址和端口,使得所有通过客户端发出的请求都经过代理服务器。例如,在浏览器的网络设置中,可以填入代理服务器的IP地址和端口,之后浏览器发出的所有请求都会通过这个代理服务器。系统级别的代理:在操作系统中设置代理,那么所有的网络请求都可以被代理。在Windows系统中,可以通过“Internet选项”设置全局代理。在UNIX-like系统中,可以设置环境变量http_proxy和https_proxy。应用级别的代理:某些应用程序允许用户配置代理,仅该应用程序的数据流量会通过代理服务器。例如,可以在Telegram客户端中单独设置代理。透明代理:客户端不需要做特别配置,所有的网络流量都会自动通过代理服务器,通常是由网络管理员在网络的出口处设置。这通常用在企业或学校网络中,用于监控和过滤流量。反向代理:对于服务端而言,反向代理服务器接收来自客户端的请求,然后转发到内部服务器,并将服务器的响应返回给客户端。反向代理常用于负载均衡、SSL终结和缓存静态内容。例如,Nginx和Apache都可以配置为反向代理。编程中使用Proxy:在编写软件时,可以使用编程语言提供的库通过代理发送请求。例如,在Python中,可以使用requests库并配置proxies参数来发送请求。示例:假设我们有一台位于美国的代理服务器,其IP地址是12.34.56.78,端口是8080。如果我们在中国,并希望通过这台美国的代理服务器来访问一个通常在中国无法访问的网站,我们可以这样做:在浏览器设置中,我们输入代理服务器的IP地址和端口。我们尝试访问目标网站,如https://www.example.com.浏览器不会直接连接到example.com,而是将请求发送到代理服务器12.34.56.78的8080端口。代理服务器接收到请求后,将其代理到example.com.example.com将响应发送回代理服务器。代理服务器再将这些信息转发回我们的浏览器。通过这种方式,我们就可以访问原本无法访问的网站,同时也隐藏了我们的真实IP地址。
计算机基础阅读 1232024年6月24日 16:43

WebSocket和HTTP协议有什么区别?

WebSocket 和 HTTP 都是网络协议,它们在 Web 应用中承担着数据交换的角色,但是它们在设计上有着根本的差别,满足不同的应用场景。HTTP 协议HTTP(HyperText Transfer Protocol)是一种无状态的请求/响应协议,通常用于客户端和服务器之间的传统网页数据传输。它在 1991 年被发明,用来在互联网上传输超文本(HTML 文档),并随着时间进化到现在的 HTTP/1.1 和 HTTP/2 版本。特点:无状态: 每次请求之间相互独立,服务器不保存之前的请求信息。请求/响应模式: 客户端发送请求,服务器响应该请求,完成一次交互。短连接: 传统的 HTTP/1.1 协议在每次请求完成后都会关闭连接(虽然现在有持久连接的选项Connection: keep-alive)。不双向: 客户端发起请求,服务器响应,服务器不能主动向客户端发送消息。例子:一个典型的 HTTP 交互场景是,用户在浏览器中点击一个链接,浏览器发送一个 HTTP GET 请求到服务器,服务器处理请求并返回一个 HTML 页面,浏览器接收并显示给用户。WebSocket 协议WebSocket 是一个相对较新的协议,它在 2011 年成为国际标准。WebSocket 协议旨在通过单个长期连接提供全双工通信渠道,以支持实时和双向交互。特点:全双工: 客户端和服务器都可以随时向对方发送消息,无需等待响应。长连接: 一旦客户端和服务器之间的 WebSocket 连接打开,它将保持打开状态,直到任何一方显式关闭。低延迟: 数据包头部信息少,减少了发送消息的开销,适合需要快速通信的场景。例子:在一个实时聊天应用中,服务器可以在接收到一条新消息时立即将其推送给所有连接的客户端,而客户端也可以随时发送消息给服务器。所有这些通信都是在同一个 WebSocket 连接上完成的,并且可以非常迅速地进行。总结总得来说,WebSocket 通常用于需要服务器和客户端进行实时、双向和交互式通信的应用(如在线游戏、实时聊天室和协作工具),而 HTTP 更适合于传统的请求/响应模式的应用,比如网页浏览等。WebSocket 与 HTTP 的主要区别在于其持久的连接和低延迟的通信能力。虽然它们可以在相同的端口上运行(WebSocket 常常在 HTTP 的基础上握手建立连接,然后升级到 WebSocket 协议),但它们的设计目标和优化点大相径庭。
计算机基础阅读 932024年6月24日 16:43

谈一谈 HTTP 是如何数据传输

HTTP (HyperText Transfer Protocol) 是用于分布式、协作式、超媒体信息系统的应用层协议。它是互联网上数据通信的基础。其数据传输流程大致如下:建立连接:客户端到服务器的连接:当用户通过浏览器或应用程序请求一个网页时,浏览器首先需要与服务器建立连接。在HTTP/1.1协议中,每次请求通常都会创建一个新的TCP连接,而在HTTP/2中,多个请求可以在同一个连接上复用。发送请求:组建HTTP请求:客户端(如浏览器)会创建一个HTTP请求消息,这个消息包括请求行(包括请求方法如GET或POST,请求的资源路径,以及HTTP版本),请求头部(包括各种元数据如Accept, User-Agent, Host等),以及请求正文(通常在POST请求中携带数据)。发送请求到服务器:客户端将这个请求通过TCP连接发送给服务器。服务器处理请求:服务器解析请求:服务器接收请求消息,并解析请求行和头部,确定请求的资源和操作。处理请求:服务器根据请求类型,调用相关的服务或脚本,如数据库查询、文件读取等,来处理这个请求。发送响应:组建HTTP响应:服务器处理完请求后,会创建一个HTTP响应消息,包括状态行(HTTP版本,状态码,状态文本),响应头部(包括内容类型、内容长度、缓存控制等元数据)和响应正文(请求的资源内容)。发送响应到客户端:服务器通过TCP连接将响应消息发送回客户端。客户端接收响应:解析响应:客户端收到响应后,会解析状态码以了解请求是否成功,以及如何处理返回的数据。显示内容:如果是网页请求,浏览器会解析响应正文中的HTML、CSS和JavaScript内容,并在屏幕上渲染显示网页。关闭连接:断开连接:在HTTP/1.0中,通常每个请求/响应之后连接即关闭。而在HTTP/1.1中,引入了持久连接(keep-alive),允许在一个连接上发送、接收多个请求/响应。不过,最终这个连接也会在一定时间后或按照客户端或服务器的需求被关闭。例子:假设您在浏览器的地址栏输入了一个URL http://example.com 并按下了回车键:建立连接:浏览器通过DNS解析获得 example.com的IP地址,然后向这个地址的80端口发起TCP连接(HTTP默认端口)。发送请求:浏览器构建一个GET请求消息,请求行为 GET / HTTP/1.1,请求头部包含了浏览器类型、接受的内容类型等。服务器处理请求:example.com的服务器接收请求,解析路径 /,找到首页的内容。发送响应:服务器构建响应消息,状态行可能为 HTTP/1.1 200 OK,响应头部包含内容类型为 text/html,然后是响应正文,即HTML内容。客户端接收响应:浏览器接收到响应,解析HTML内容,并在屏幕上渲染出来。关闭连接:如果没有更多的请求,或服务器/客户端决定关闭连接,TCP连接将被关闭。