ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

HTTP底层原理与实战排错:从状态码到HTTPS性能优化

HTTP底层原理与实战排错:从状态码到HTTPS性能优化 做后端和前端这几年我发现自己和身边的人翻车最频繁的地方从来不是业务逻辑写不对而是搞不定那些看着眼熟的HTTP报错。什么502 Bad Gateway、HTTP 400、401 Unauthorized平时都能背出来可真到线上出问题的时候还是一头雾水。HTTP这东西太基础了基础到我们默认自己已经会了可越是这样越没人愿意花整块时间把它彻底理一遍。这篇我就把HTTP从底层逻辑到实际排错、从老版本到新协议一次性讲透适合刚入行的前端后端新手也适合写了几年代码但一直靠搜索引擎零散救火的朋友。我会尽量用实际开发中会遇到的问题来反推原理带着为什么去读而不是背文档。你会发现状态码不用死记请求头也不用全背只要把HTTP的工作机制理解到位绝大多数问题都能自己推理出来。1. HTTP到底在解决什么问题先建立整体认知1.1 从一次网页请求说起在浏览器里输入一个网址按下回车到网页显示出来中间发生了什么这个问题我在面试里问过很多人能完整答上来的不多。大多数人会说浏览器发了请求服务器返回HTML话没错但太笼统了。实际过程大致是这样的浏览器先解析域名通过DNS拿到服务器IP然后基于TCP建立连接连接建好之后浏览器会按照HTTP协议格式组织一条请求消息发给服务器服务器解析请求、处理业务、再按HTTP协议格式返回响应浏览器拿到HTML之后开始解析渲染遇到CSS、JS、图片再分别发请求去取。整个过程中HTTP负责的是客户端和服务器之间怎么对话这件事也就是约定好消息的格式和交互规则。有一个很关键的点容易被忽略HTTP本身不传输数据它依赖TCP。TCP保证数据可靠到达HTTP则定义到达之后怎么理解这些数据。你可以把TCP想象成一根水管HTTP是水管两头的人约定好的说话方式。如果水管本身是堵的或者断的HTTP报什么错都没用先查网络通不通才是正经事。1.2 必须分清的四层概念URL、URI、HTTP、TCP这四个词几乎每个开发都会碰到但很多人混着用。我尽量用一句话讲清URI统一资源标识符是一个宽泛的概念用来标识某个资源URL是它的子集还额外给出了访问方式协议 地址。URL就是平时说的网址比如https://example.com/api/users?id1它包含了协议、主机、端口、路径、查询参数这些信息。HTTP是这个URL里https部分所对应的协议规定了消息格式。TCP是HTTP底层依赖的传输协议负责把HTTP消息可靠地送到对方手里。访问一个URL时实际上浏览器做的事是域名解析-TCP握手-发送HTTP请求-等待HTTP响应-关闭或复用连接。这五个步骤里HTTP只负责第三步和第四步的消息组织其他步骤都不是HTTP的职责范围。很多刚开始学网络的同学有一个误区以为HTTP请求发出去了服务器就一定收得到。其实不是HTTP只是一个应用层约定它自己不能保证送达。如果TCP层断了HTTP请求根本发不出去或者发出去了也没人回应这时候超时、Connection refused之类的错误就出来了。理解了这一层后续看各种报错会清晰很多。HTTP还有一个重要特性是无状态。服务器不会默认记住你上一次请求是谁。每个请求都是独立的像两个陌生人第一次见面。为了弥补这个缺陷后来才出现了Cookie、Session、Token这些机制。这部分后面细讲。2. 请求与响应HTTP最核心的消息结构2.1 请求行方法、路径、协议版本一条HTTP请求消息结构其实非常朴素。开头第一行叫请求行内容大致长这样POST /api/login HTTP/1.1三个部分从左到右分别是请求方法、请求路径、协议版本。请求方法代表你想对资源做什么操作。用得最多的是GET和POST。GET表示获取资源POST表示提交数据。这里有一个很重要的语义差异GET应该是幂等的意思是发多少次结果都是一样的不会改变服务器状态POST则通常不幂等每次执行都可能产生新的副作用比如创建一条订单。接口设计规范里常说的GET不做事、POST才做事根源就在这里。其他方法也值得了解PUT表示整体更新资源、DELETE表示删除、PATCH表示部分更新、HEAD只取响应头不取内容。这些方法虽然在实际业务中不一定都用得上但RESTful接口设计是以它们为基础的。理解了方法的语义看别人的接口文档就不会觉得奇怪自己设计接口时也有依据。协议版本是HTTP/1.1、HTTP/2这样的格式。为什么请求行里要带协议版本因为服务器需要知道客户端用什么版本的协议跟自己对话不同版本的报文格式有些差异。一个HTTP/1.1的报文和HTTP/2的报文二进制层面长得完全不一样服务器必须根据版本号决定用哪种方式解析。2.2 状态码三秒定位问题状态码是服务器处理完请求后告诉客户端这次结果怎么样的代码。它是三位数字按首位数字分成五类。我做了这么多年开发发现真的不用背理解分类逻辑就够了状态码含义说明1xx信息性服务器还在处理或协议切换等2xx成功请求被正确处理200是标准成功3xx重定向资源地址变了需要去新的位置访问4xx客户端错误你发的请求有问题服务器不想处理5xx服务器错误请求本身没问题服务器自己崩了或挂了看到4xx优先检查自己的请求是不是缺参数、没带鉴权、路径写错看到5xx优先检查服务器程序是不是抛异常、服务是不是挂了。这个思路可以解决日常80%的状态码问题。几个高频状态码单独说一下301和302区别。301是永久重定向搜索引擎会更新索引302是临时重定向每次都要走一遍重新定位。涉及登录跳转、支付回调的时候用错了会出很诡异的线上问题。401和403的区别。401是你没登录或者登录态失效需要先去认证403是你登录了但没有权限访问这个资源。场景完全不同排查方向也不同。408是请求超时客户端花太长时间没把完整请求发给服务器服务器主动断开了。429是请求太频繁服务端限流了。遇到这个状态码要做指数退避重试而不是疯狂刷。2.3 头部字段HTTP的元信息交换区请求行下面是一堆键值对叫请求头或响应头。它们负责承载请求本身之外的元信息。常用的请求头有Host目标主机名和端口。HTTP/1.1开始是必填的因为一个服务器上可能跑多个站点靠Host区分。User-Agent客户端标识。服务器通过它判断是浏览器还是爬虫是手机还是桌面。Content-Type请求体的媒体类型。表单提交是application/x-www-form-urlencodedJSON是application/json文件上传是multipart/form-data。Accept客户端能理解哪些返回格式。服务器会尽量按客户端能接受的格式返回。Authorization通常携带Token或者账号密码做认证用。Cookie携带之前服务器种下来的身份凭证。常用的响应头有Content-Type响应体的媒体类型。Content-Length响应体的字节长度。Set-Cookie服务器要求浏览器种下Cookie。Cache-Control缓存策略后面讲性能优化时细说。Location配合3xx状态码告诉客户端去哪个新地址。有一个在实际调试中非常实用的技巧出问题的时候先用浏览器开发者工具或者curl把请求头和响应头完整拉出来看一眼往往问题就一目了然。比如某个接口返回乱码先看响应头的Content-Type是不是缺了charsetutf-8某个接口返回401先看Authorization头有没有传对。头部字段就是HTTP的病历本排查问题先翻它。3. 从1.0到3.0协议版本演进背后的设计逻辑3.1 HTTP/1.1连接复用与管道化如果要给HTTP版本排个里程碑HTTP/1.1绝对是最关键的一个。它解决了HTTP/1.0时期最大的痛点每次请求都要重新建立TCP连接。HTTP/1.0时代每请求一个资源就建立一次TCP连接请求完立即关闭。一个网页有10张图片就要建立10次连接每次都有TCP三次握手和四次挥手。这种开销放在今天的网页密度下根本没法用。HTTP/1.1引入了持久连接也就是Keep-Alive。TCP连接建立之后不马上关闭多个请求可以复用同一条连接等一段时间空闲再关。这个改进直接把网页加载效率提升了几个量级。你在响应头里看到的Connection: keep-alive就是服务器在表示这个连接可以继续用。HTTP/1.1还支持管道化客户端可以在一个连接上连续发多个请求不用等上一个响应回来。但这里有一个著名的队头阻塞问题虽然请求可以连续发响应却必须按顺序返回如果第一个请求的响应很慢后面所有响应都被堵住哪怕服务器早就处理完了。这个问题的根源在于HTTP/1.1的文本协议里消息边界是靠连续回车换行来分割的顺序乱了就无法解析。3.2 HTTP/2多路复用与头部压缩HTTP/2把表示方式从文本改成了二进制分帧。一条请求被拆成多个二进制帧可以交错发送在同一个TCP连接上同时跑多个请求接收方再按帧里的标识重组。这叫多路复用直接解决了HTTP/1.1的队头阻塞。比如页面同时在加载HTML、CSS、JS、图片在HTTP/1.1里要么并行开多个连接浏览器一般一个域名开6个左右要么串行排队在HTTP/2里所有资源都在同一条连接上同时传输每个资源之间互不等待。实际体验上HTTP/2对大量小文件的加载场景提升非常明显。还有一个优化是头部压缩。HTTP/1.1里每次请求都会带上完整的头部Cookie多的时候光头部就有几百上千字节而且这些信息每个请求都一模一样。HTTP/2在客户端和服务器端维护一张静态表加一张动态表重复的头部字段只传索引号不需要重复传全文。做过移动端开发的应该深有体会弱网环境下这个压缩能省不少流量和时间。HTTP/2还有一个特性叫服务器推送服务器可以主动把客户端还没请求但必然会用到的资源推过来比如HTML页面里引用的CSS和JS。不过这个功能实际用得不算多因为搞不好反而浪费流量CDN厂商很多都默认关闭它。3.3 HTTP/3基于UDP的QUIC协议HTTP/3是一个更彻底的改动它把底层传输协议从TCP换成了基于UDP实现的QUIC。为什么要换TCP是实打实的有序可靠传输协议但也正因为这点TCP层面的丢包重传也会导致队头阻塞。HTTP/2虽然在应用层解决了请求之间的队头阻塞但如果底层TCP自己丢了一个包这个TCP连接上的所有HTTP/2请求都要等这个包重传完成因为TCP保证字节流有序。网络环境越差这个问题越明显。QUIC的做法是把原来TCP承担的连接管理、拥塞控制、可靠传输能力实现在用户态UDP之上不同请求的数据流之间互不影响某个流丢包只重传这个流其他流照常走。另外QUIC还优化了连接建立过程首次连接可以做到1-RTT完成握手如果之前连接过甚至可以0-RTT非常快。实际开发中HTTP/3目前主要集中在浏览器和CDN层面。Nginx、Caddy、Cloudflare等都支持但自建的内部服务要切换到HTTP/3还需要一定的改造成本。我的建议是了解它的原理生产环境如果对弱网体验要求高可以逐步上不用盲目跟风。4. HTTPS与安全为什么现代Web默认必须是加密的4.1 明文HTTP的危险与TLS握手HTTP报文默认是明文传输的。意味着在网络上任何一个中间节点——路由器、运营商、WiFi热点——理论上都能看到你发送的全部内容。没有加密的登录请求里用户名密码就那样赤裸裸地躺在报文里抓包一眼就能看到。这不是危言耸听公共WiFi环境下抓包工具半分钟就能捕获大量明文密码。HTTPS就是HTTP加上TLS加密层。它做的事情用一句话概括把HTTP报文加密之后再交给TCP传输。但这背后的密码学设计很有意思值得稍微深入一点。TLS握手大致经历以下步骤客户端发出ClientHello携带支持的TLS版本、加密套件列表、随机数。服务器回复ServerHello选定加密套件带上自己的证书、另一个随机数。客户端验证证书是否可信信任链验证。双方通过非对称加密协商出一个对称密钥密钥交换。之后所有应用数据都用对称密钥加密传输速度远快于非对称加密。这里的核心思想是混合加密用非对称加密协商密钥用对称加密传输数据。非对称加密慢但安全适合小数据量对称加密快适合大数据量。两者结合既安全又高效。4.2 证书链与常见HTTPS报错服务器证书不是随便自签一个就行的。浏览器内置了一些受信任的根证书机构服务器证书必须由这些受信任机构直接或间接签发浏览器才会认为可信。如果证书过期、域名不匹配、或者签发机构不受信任浏览器就会拦下请求提示连接不安全。开发中经常会遇到自签名证书的报错。本地联调用https://localhost或者内网IP时浏览器会提示证书无效。这其实是正常的因为自签名证书不在信任链里。调试时可以在开发环境暂时关闭证书校验或者把自签名证书手动导入系统信任库。但生产环境一定不要这么做否则等于裸奔。还有一个和HTTPS紧密相关的概念是HSTS。服务器通过Strict-Transport-Security响应头告诉浏览器以后只能通过HTTPS访问我不要用HTTP。浏览器收到这个头之后就会自动把HTTP请求升级成HTTPS。有了HSTS用户手输http://example.com浏览器会直接变成https://example.com中间那一次明文请求就被省掉了。很多安全要求高的站点都会启用HSTS。4.3 需要警惕的HTTP层安全问题加密解决的是传输安全问题但HTTP层面还有一些攻击手法值得了解。热搜词里提到的HTTP头注入就是一个典型。头注入的原理是有些应用会把用户输入直接拼进HTTP响应头里比如重定向地址、Cookie值。如果用户输入里包含\r\n换行符攻击者就能在响应里注入额外的头部字段甚至伪造响应体实现XSS、会话劫持等攻击。防御方法很简单任何写入响应头的内容都必须经过校验不允许包含换行符等控制字符。其他常见的还有CSRF跨站请求伪造攻击者在第三方页面构造一个请求诱导已登录用户浏览器发出利用用户的登录态操作有权限的功能。防御方式是加CSRF Token或校验Referer、SameSite Cookie。XSS跨站脚本攻击者把脚本注入到页面中在别的用户浏览器里执行。这本质上也是数据与代码没有严格区分。点击劫持通过透明iframe覆盖页面诱导用户点击不可见的按钮。这些攻击手法看着很多但防御思路是相通的所有的输入都不可信所有的输出都要编码认证和授权要做严格区分。HTTP只是载体安全问题的根子还是应用代码。5. 那些年我们踩过的HTTP报错实战排查手册5.1 502 Bad Gateway最经典的网关报错502应该是我职业生涯里见过最多的报错。热搜词里就有unexpected status 502 bad gateway: unknown error这种格式。很多人一看到502就慌其实它表达的含义非常明确中间有个网关或者代理通常是Nginx它没能从上游服务器拿到有效响应。我大概描述一下典型链路浏览器 - Nginx - 后端服务。Nginx收到了浏览器的请求转头向后端服务发起请求结果后端服务连接不上、响应超时、或者直接返回一个非法响应Nginx就会返回502。排查502我的习惯是按下层链路一步步来先确认后端服务本身是不是活着。在服务器上本地curl一下后端服务的健康检查接口。确认Nginx配置里的proxy_pass地址和端口是否正确。我踩过一次很隐蔽的坑Nginx里配的是域名但服务器上的hosts解析被改乱了导致Nginx找不到上游。确认后端服务的超时设置。如果后端程序处理慢超出了Nginx的proxy_read_timeoutNginx也会报502。找后端日志。Nginx错误日志和后端应用日志要对应着看。有一次我排查一个线上502从晚上八点查到十一点最后发现是后端服务的内存被打满进程被杀Nginx自然拿不到响应。所以502排查的顺序建议是服务进程是否存活 - 网络是否能通 - 超时参数 - 应用日志由粗到细不要一上来就翻代码。和502容易混淆的是504 Gateway Timeout。504表示Nginx把请求转给了上游但上游在超时时间内没返回结果连接还挂着。502和504的排查方向不同502更像根本没有有效响应504更像响应太慢没等到。5.2 400与401客户端问题与认证问题HTTP 400 Bad Request表示服务器觉得你的请求格式有问题但又不想具体告诉你是哪里不对。常见的400原因请求行格式不对路径里有非法字符。请求头缺失或格式错误比如Host头丢了。请求体不是合法的JSONContent-Type却写的是application/json。请求行里的URL太长服务器有限制。热搜词里有一条http error 400. the request hostname is invalid.就是典型的Host头校验失败。很多应用会做域名白名单校验请求里的Host不在白名单内直接400。排查时先检查请求的Host头是不是正确写全了。401就明确多了没有有效的认证凭证。服务器不认识你或者你传的Token过期、格式错误。排查401的核心是看Authorization头传的是什么、服务端期望的是什么。这里有一个非常常见的坑是Token里有特殊字符在拼接请求头的时候被截断或者转义了导致服务端解析失败。建议把请求头完整打印出来比对。如果说401是没登录那403就是没权限了。403的排查方向是当前账号的角色权限、IP白名单、接口访问控制配置跟认证凭证不再有关联。很多新手在403的时候还在反复检查Token这是南辕北辙。5.3 服务端5xx报错的具体案例从500到500.19500 Internal Server Error是服务器内部异常具体原因必须看服务端日志。但有个细节值得注意有时候服务端配置本身的问题也会以5xx形式出现。热搜词里的HTTP 错误 500.19 - Internal Server Error就是一个典型常见于Windows的IIS服务器。500.19的核心原因是配置格式有问题IIS读不到或无法解析web.config等配置文件。常见触发场景web.config文件里XML语法错误。配置里引用了不存在的模块或处理程序。应用程序池没启动。文件访问权限不对IIS进程无法读取配置目录。排查方向是先看IIS事件日志中的详细错误信息再检查web.config的XML格式最后确认文件夹的权限。Windows服务器的这类问题和Linux系的Nginx报错思路很不一样本质是平台特有的配置问题不要跑到应用代码里去找。5.4 环境类报错镜像源、连接超时与Docker拉取失败热搜词里出现了一类非常普遍的问题condahttperror: http 000 connection failed for url和get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection。这类报错的共同点是工具conda、docker要从远程源下载数据但网络请求失败。常见原因有三个默认源在国外访问不稳定。系统代理设置有问题工具请求走了错误的代理。防火墙拦截了特定域名的访问。解决方案优先级最高的就是换国内镜像源。以conda为例通过channels配置指向清华或阿里云的conda镜像速度可以提升几十倍。Docker也是同理把registry-mirrors配置成国内镜像加速器。这类问题是每个开发者都会遇见的环境杂症不是HTTP本身的知识不够而是网络链路的现实约束。遇到这类问题时我的经验是不要死磕默认配置优先检查源头是否可达、代理是否正确再决定是否换源。net/http: request canceled while waiting for connection这个报错翻译成人话就是连接还没建立客户端就等不下去了超时设置、防火墙拦截、目标不可达都有可能不要只看字面意思。5.5 用curl和DevTools做一次完整排错排查HTTP问题最好用的工具是curl的verbose模式curl -v https://example.com/api/users这个命令会把整个交互过程打印出来。你需要关注的点是* TCP_NODELAY set * Connected to example.com (93.184.216.34) port 443 GET /api/users HTTP/1.1 Host: example.com User-Agent: curl/8.0.1 Accept: */*带星号的是连接阶段信息带大于号的是请求头带小于号的是响应头这样能非常直观地看到请求从发起到响应的全过程。如果连接阶段就卡住基本是网络问题而不是应用问题如果请求头发出了但没响应可能是超时或服务端问题如果响应头返回了但状态码是4xx、5xx再看协议层细节。浏览器的DevTools也是排查利器。Network面板里点开任意一条请求Headers、Payload、Response、Timing四个Tab各有用处Headers看状态码和请求响应头Payload看提交的数据Response看返回内容Timing看耗时分布。每次排查问题的时候我的习惯是先拉curl -v把请求头和响应头摊开在面前。很多问题在信息摆齐之后答案是显而易见的。6. 连接复用与性能优化让HTTP跑得更快6.1 Keep-Alive与连接池HTTP/1.1引入的连接复用机制在实际工程里很讲究。浏览器端同一个域名会维持一定的并发连接数空闲超过一段时间会主动关闭。服务端则可以根据自己的负载情况配置Keep-Alive的超时时间。但服务端开发的时候连接管理不只是协议层面的事。比如用Java的HttpClient、Go的net/http、Python的requests它们都有连接池的概念。连接池的作用是复用底层TCP连接避免每个请求都走一遍三次握手和慢启动。我在实际项目中踩过一个比较隐蔽的坑某个服务调用第三方接口每次请求都新建一个HTTP客户端没有复用连接池导致高并发下文件描述符被打满出现一堆SocketException: Too many open files。解决办法很简单把HTTP客户端做成单例共享连接池。这个问题的字面报错看起来是操作系统资源问题根子却在HTTP连接没有复用上。连接池还有几个参数需要关注最大空闲连接数、最大连接数、空闲连接存活时间。这些参数要根据业务并发量和平均请求耗时来调不是越大越好。连接数开太多反而会占用大量端口和内存。6.2 HTTP缓存让请求从源头变少HTTP缓存是性能优化里成本最低、收益最高的一招。它的核心思想是如果资源没变就不需要重新下载。Cache-Control是控制缓存行为最关键的响应头。常用的指令public任何节点都可以缓存包括CDN。private只能浏览器缓存CDN不能缓存。no-cache不是不缓存而是每次使用前必须向服务器确认资源是否过期。no-store完全不缓存。max-age3600资源在3600秒内有效期间直接用缓存。配合Cache-Control的是两种重新验证机制ETag和Last-Modified。ETag是资源的唯一标识资源内容变了标识就变。浏览器缓存过期之后会带上If-None-Match头把ETag发给服务器服务器比对发现没变就返回304 Not Modified浏览器继续用缓存变了就返回200和新的资源。实际优化网站性能时记住一个口诀静态资源尽量长缓存动态接口尽量不缓存缓存失效时用版本号而不是禁用缓存。前端打包工具给文件名加hash本质就是利用了这个机制文件内容变了文件名就变浏览器自然认为是新资源。6.3 减少请求数页面性能的关键指标优化HTTP性能最实在的思路其实是减少请求次数。一个页面要发几十个HTTP请求不管连接复用做得多好每多看一张图、多加载一个脚本都是一次额外的往返。常见手段合并CSS、JS文件减少文件数量。图片使用雪碧图虽然现在用得少了但原理还在。小图片转Base64内联进HTML或CSS。使用CDN让资源从地理上离用户更近。合理设置缓存重复访问时直接命中本地缓存。我参与过的一个老项目优化前首屏要发60多个请求优化后压到十几个加载时间直接降了一多半。没有改任何业务代码只是把缓存策略调对、把资源做了合并和CDN化。所以HTTP性能优化的优先级应该是先减少请求数量再做连接复用最后才考虑协议升级。弱网环境的优化逻辑也类似。请求数少一个就少一次往返时延。移动端开发里经常强调的弱网优化很大一部分工作就是在把HTTP请求次数降下来或者把关键数据合并成一个接口返回。7. 动手实践与学习建议读完前面的原理和排错案例你会发现HTTP的知识点并不难难的是把零散的信息串成一条线。我推荐三条动手路径每一条都不用花太长时间但对理解的帮助非常大。7.1 用Python写一个最小HTTP服务器自己从头写一遍HTTP解析逻辑比看十遍文档都管用。用Python的socket库绑定端口接收TCP连接然后手动解析HTTP请求行和头再拼一个HTTP响应回去import socket def handle_client(conn): data conn.recv(1024).decode(utf-8) print(data) response ( HTTP/1.1 200 OK\r\n Content-Type: text/html; charsetutf-8\r\n Content-Length: 15\r\n \r\n h1Hello/h1 ) conn.sendall(response.encode(utf-8)) conn.close() server socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((127.0.0.1, 8080)) server.listen(5) while True: conn, addr server.accept() handle_client(conn)跑起来后用浏览器访问http://127.0.0.1:8080再配合curl -v观察请求响应全过程。亲手拼一遍响应报文之后\r\n为什么不能省、Content-Length为什么要精确、状态行为什么长那样就全明白了。7.2 在项目里主动做一次HTTP依赖审计翻一下项目里所有依赖外部接口的地方逐个检查三件事有没有设置正确的超时时间、有没有复用连接池、有没有做重试以及重试是否考虑了幂等。这个审计做完你对项目的健壮性会有全新的认识。我发现很多线上事故都出在这三件事上超时没设置导致线程池被打满连接不复用导致端口耗尽盲目重试放大故障。7.3 把状态码表贴在案头不用刻意背但建议把状态码分类逻辑放在手边。遇到没见过的状态码先判断它是4xx还是5xx再查具体含义。看多了自然就记住了。真实业务里的状态码来来去去就那么二十来个频繁用到的会更少根本不需要背整张表。技术学习有个规律原理性的东西绕不过去早学晚学都要学越早学后面省的时间越多。HTTP就是这样它不性感不热门但它是你排查问题、设计接口、优化性能的地基。地基扎实了上面盖什么楼都稳。
返回列表