计算机基础面试题手册

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

计算机基础阅读 05月27日 22:21

CDN 如何防御 DDoS 攻击?有哪些安全防护机制?

CDN 能防住 DDoS 吗?核心机制是什么CDN 确实能防御 DDoS,但靠的不是单点硬扛,而是分布式架构把攻击流量"化整为零"。核心思路:隐藏源站 IP + 全球节点分散流量 + 智能清洗恶意请求。DDoS 防护:流量清洗是关键CDN 防御 DDoS 的核心是流量清洗——在边缘节点识别并过滤恶意流量,只把正常请求回源。清洗分三层:L3/L4 网络层:过滤 SYN Flood、UDP Flood、ICMP Flood 等协议级攻击。边缘节点直接丢弃不符合 TCP/IP 规范的畸形包,对特定攻击源 IP 在骨干网层面封禁L7 应用层:分析 User-Agent、Cookie、TLS 指纹等,用 JS Challenge 或滑块验证判断请求是否来自真人。AI 行为分析会给每个请求打信誉分,低分直接拦截Anycast 架构:攻击流量根据地理位置被吸引到最近的边缘节点,把大规模分布式攻击拆成多个小流量就地处理,不集中到单点限流是清洗的辅助手段:# 单 IP 限流limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;location /api/ { limit_req zone=api burst=20 nodelay;}WAF:应用层攻击的防火墙WAF(Web Application Firewall)防护 SQL 注入、XSS、CSRF、文件包含等 Web 攻击:输入验证:过滤用户输入中的恶意载荷输出编码:对响应内容编码,防止 XSS 执行规则匹配:基于正则或签名库拦截已知攻击模式# 防注入和 XSSif ($args ~* "union.*select.*from") { return 403; }if ($args ~* "<script|javascript:") { return 403; }WAF 部署模式:反向代理(CDN 作为代理入口)、透明代理(旁路拦截)、DNS 模式(通过 DNS 重定向引流)。访问控制:限源、限地、防盗链IP 黑白名单——直接放行或封禁特定 IP 段:allow 192.168.1.0/24;deny all;地理位置限制——仅允许特定国家/地区访问,或屏蔽高风险地区:geo $allowed_country { default no; CN yes;}if ($allowed_country = no) { return 403; }Referer 检查——防盗链,阻止第三方直接引用你的资源:valid_referers none blocked example.com *.example.com;if ($invalid_referer) { return 403; }加密传输与 Token 鉴权HTTPS + HSTS 保证传输层安全。Token 认证防止资源被非法访问——服务端用密钥、路径、时间戳生成签名,CDN 边缘校验签名合法性:import hashlib, timedef generate_token(secret, path, ts): return hashlib.sha256(f"{secret}{path}{ts}".encode()).hexdigest()爬虫防护识别合法爬虫(如 Googlebot)放行,恶意爬虫限流或封禁。方法:User-Agent 分析、行为模式识别、访问频率监控。分层防御才是正确姿势单一机制防不住复杂攻击,生产环境必须分层:用户 → CDN 边缘节点(流量清洗) → WAF(应用层防护) → 源站(深度防御)边缘节点:基础过滤、限流、清洗WAF:应用层攻击拦截源站:最小权限、定期审计、应急响应面试回答时记住:CDN 防御 DDoS 靠分布式 + 智能清洗,不是硬扛;应用安全靠 WAF + 访问控制组合拳;生产环境必须分层,没有银弹。追问:CDN 能防住多大规模的 DDoS? 看厂商能力。主流高防 CDN 的 Anycast 网络总带宽可达 10Tbps+,远超单机高防的 1Tbps 上限。关键在于 Anycast 架构能把流量分散到全球节点,不是靠一台机器硬抗。
计算机基础阅读 05月27日 22:19

CDN 性能监控有哪些核心指标?怎么搭建监控体系?

CDN 性能监控的五个核心指标缓存命中率——CDN 监控的第一指标。命中率 = 缓存命中请求数 / 总请求数 × 100%,静态资源目标 95% 以上,整体 90% 以上。命中率骤降往往意味着缓存键配置错误或 TTL 过短,这是面试最爱追问的点。TTFB(首字节时间)——从请求发出到收到第一个字节的耗时,包含 DNS 解析、TCP 连接、TLS 握手和服务器处理。静态内容 P95 应低于 100ms,动态内容低于 500ms。注意:要分开统计命中和未命中的 TTFB,否则平均值会掩盖问题。回源率——回源请求数占总请求的比例,目标低于 10%。回源率高直接导致源站压力大、用户延迟高。面试常见追问:缓存命中率突然从 95% 掉到 60%,你怎么排查?思路:检查是否有大范围缓存失效(批量 purge)、缓存键是否冲突、TTL 是否被改短。错误率——4xx 和 5xx 占总请求比例,4xx 目标低于 0.1%,5xx 低于 0.01%。5xx 飙升通常意味着源站过载或 CDN 节点异常,4xx 激增则可能是配置错误(如回源 URL 改了但 CDN 规则没更新)。带宽与 QPS——带宽监控分边缘带宽和回源带宽,QPS 关注峰值和均值。流量突增需要区分是正常业务高峰还是攻击,结合错误率和延迟一起判断。监控体系怎么搭三层架构:数据采集 → 存储/计算 → 可视化/告警。采集层用 CDN 厂商的日志流(Cloudflare Logs、AWS CloudFront 实时日志)或自建 Nginx 日志,关键字段包括 request_time、upstream_cache_status、upstream_response_time。存储计算层用 Prometheus 做指标聚合,ELK 做日志检索。可视化用 Grafana 搭看板,按地域、ISP、内容类型分维度展示。告警规则要设置三个:TTFB P95 超阈值持续 5 分钟、缓存命中率低于 80% 持续 10 分钟、5xx 错误率超 1% 持续 3 分钟。告警通道走企业 IM + 值班电话,5xx 告警级别必须高于延迟告警。面试追问方向缓存命中率低怎么优化? 检查缓存键是否包含不必要的动态参数、TTL 是否合理、是否需要分层缓存(parent cache + edge cache)。如何区分 CDN 问题还是源站问题? 对比命中请求和未命中请求的 TTFB,如果命中请求也慢,问题在 CDN 层;如果只有未命中慢,问题在源站或回源链路。多 CDN 怎么监控? 统一指标口径,用同一套 Grafana 看板对比各厂商的命中率、延迟和错误率,按地域做流量调度。掌握五个核心指标(命中率、TTFB、回源率、错误率、带宽/QPS)加一套采集-存储-告警的完整方案,面试基本够用。
计算机基础阅读 05月27日 22:18

CDN 故障排查的流程是什么?有哪些常用工具?

直接回答CDN 故障排查的核心流程:确认范围 → 检查DNS → 检查网络连通性 → 检查缓存状态 → 检查源站 → 定位修复。第一步,确认故障范围。 问三个问题:是全量用户还是部分地域?是持续报错还是间歇性?是从什么时候开始的?范围判断决定后续排查方向——全局故障看CDN节点和DNS,局部故障看网络链路和缓存。第二步,检查DNS解析。 CDN 依赖 DNS 将用户调度到最近的边缘节点,DNS 出问题一切白搭。用 dig 或 nslookup 确认域名是否正确解析到 CDN CNAME,检查不同地域 DNS 服务器的解析结果是否一致。常见坑:DNS 缓存未更新导致调度到已下线节点。第三步,检查网络连通性。 ping 看延迟,traceroute 或 mtr 看链路丢包,curl -v 看 HTTP 握手各阶段耗时。重点关注 SSL 握手时间——如果证书链不完整或配置错误,握手会失败或变慢。第四步,检查缓存状态。 看响应头里的 X-Cache 字段,HIT 还是 MISS。缓存命中率骤降是最常见的性能劣化原因。排查缓存键配置是否合理、TTL 是否过长导致内容不更新、是否有绕过缓存的请求头。第五步,检查源站。 绕过 CDN 直接访问源站,如果源站也慢,问题在源站不在CDN。看源站负载、响应时间、错误日志。核心工具速查| 场景 | 工具 | 用法 ||------|------|------|| DNS排查 | dig/nslookup | dig @8.8.8.8 example.com || 网络延迟 | ping/mtr | mtr -r -c 10 cdn.example.com || HTTP调试 | curl | curl -w "@format.txt" -o /dev/null -s URL || SSL检查 | openssl | openssl s_client -connect host:443 || 缓存分析 | 日志+响应头 | grep "X-Cache" access.log \| sort \| uniq -c || 日志分析 | ELK Stack | Kibana 看错误率趋势和地域分布 |# curl 计时模板 curl-format.txttime_namelookup: %{time_namelookup}time_connect: %{time_connect}time_starttransfer: %{time_starttransfer}time_total: %{time_total}追问:缓存刷新后用户仍看到旧内容怎么办?先确认刷新是否生效——用 curl -I 检查响应头的 X-Cache 和 Last-Modified。如果刷新成功但用户仍看到旧内容,三个可能:本地浏览器缓存、中间运营商缓存、多CDN节点同步延迟。对应措施:版本化URL(app.js?v=2)、缩短TTL、检查CDN供应商的刷新接口是否覆盖全部节点。追问:如何预防CDN故障?三件事:监控告警(节点可用性、缓存命中率、错误率)、健康检查(定时探测各节点)、容灾预案(多CDN切换、源站冗余、DNS快速切流量)。面试中能讲出"监控+容灾"两条线,基本过关。
计算机基础阅读 05月27日 21:46

什么是CDN?CDN的工作原理是什么?

CDN 是什么?CDN(Content Delivery Network,内容分发网络)是一组分布在不同地理位置的服务器集群,核心目标是将内容缓存到离用户最近的边缘节点,减少网络延迟,加速资源访问。CDN 的工作原理用户请求资源时,完整流程如下:DNS 解析:用户访问域名,本地 DNS 向权威 DNS 查询,发现该域名配置了 CNAME 记录,指向 CDN 服务商域名GSLB 调度:请求到达 CDN 的 GSLB(全局负载均衡),根据用户 IP、节点负载、网络状况等综合判定,返回最优边缘节点 IP边缘响应:用户向该边缘节点发起请求,节点检查缓存——命中则直接返回;未命中则回源获取,缓存后返回给用户关键在于 CNAME + GSLB 这套调度机制,它让用户无感知地被路由到最近节点。核心技术点缓存策略缓存键:由 URL、Query String、请求头等生成,决定哪些请求命中同一份缓存TTL:控制缓存过期时间,过期后需回源验证或重新获取缓存层级:边缘缓存 → 区域缓存 → 源站,逐级回源缓存预热:主动将内容推送到边缘节点,避免首次访问回源缓存刷新:源站更新后,主动清除 CDN 缓存,保证内容时效性负载均衡GSLB:全局调度,决定用户访问哪个节点健康检查:实时监控节点状态,自动剔除故障节点CDN 与反向代理的区别| | CDN | 反向代理 ||---|---|---|| 部署位置 | 多地分布式边缘节点 | 通常部署在源站前面 || 核心目的 | 就近加速、降低延迟 | 安全防护、请求转发 || 缓存范围 | 面向全球用户 | 面向单一入口 |常见面试追问CDN 缓存命中率低怎么办? 检查缓存键设计是否合理、TTL 是否过短、是否有大量动态参数干扰缓存CDN 回源风暴怎么处理? 设置回源限流、使用缓存预热、配置请求合并(同回源请求合并为一次)HTTPS 场景下 CDN 如何工作? CDN 节点与用户之间 HTTPS 加密,CDN 与源站之间也可 HTTPS,支持证书部署在 CDN 侧动态内容能否用 CDN? 可以,通过动态加速(DCDN)优化路由和传输协议,但不走缓存
计算机基础阅读 05月27日 21:17

ASCII 码中数字字符怎么和整数互相转换?

数字字符和 ASCII 码怎么互相转换?数字字符 '0'-'9' 的 ASCII 值是 48-57,连续排列。核心转换就一个公式:数字字符的 ASCII 值 = 数字值 + 48(即 ord('0'))。字符转整数: 用字符减去 '0' 的 ASCII 值即可。int num = ch - '0'; // C/Javaint num = ord(ch) - ord('0') # Python整数转字符: 数字加上 '0' 的 ASCII 值。char ch = num + '0'; // C/Javachar = chr(num + ord('0')) # Python判断是否为数字字符:// C/Javaif (ch >= '0' && ch <= '9')// Pythonif '0' <= ch <= '9'为什么是减 '0' 而不是减 48?语义清晰。ch - '0' 直接表达"求这个字符代表的数字",而 ch - 48 需要读者心算 48 是什么。另外,ASCII 并非唯一编码标准,用 '0' 做基准在 EBCDIC 等编码下逻辑不变(虽然值不同),代码可移植性更好。实战:手写字符串转整数不用 parseInt / int(),手动实现:def str_to_int(s): num = 0 for c in s: if not ('0' <= c <= '9'): break num = num * 10 + (ord(c) - ord('0')) return num每一轮把已有结果左移一位(乘 10),再加上新数字位。追问:负数怎么处理?跳过开头的 '-',按正数转换,最后取反即可。注意 "-0" 和溢出的边界情况,这是面试中常见的 follow-up。
计算机基础阅读 05月27日 21:17

如何判断字符串是否为纯 ASCII 字符串

核心思路ASCII 字符的编码值范围是 0–127(0x00–0x7F),共 128 个字符。判断一个字符串是否为纯 ASCII,本质就是检查其中每个字符的编码值是否都小于 128。任何编码值 ≥ 128 的字符都是非 ASCII 字符(如中文、emoji、法文重音字母等)。最简实现Python 一行搞定:s.isascii() # Python 3.7+内部等价于 all(ord(c) < 128 for c in s),发现非 ASCII 字符立即返回 False,时间复杂度 O(n)。JavaScript 用正则:/^[\x00-\x7F]*$/.test(str)\x00-\x7F 就是 0–127 的十六进制表示,正则引擎会逐字符匹配,命中非 ASCII 即失败。Java 17+ 用内置方法:str.chars().allMatch(Character::isAscii)Go 逐 rune 判断:func isASCII(s string) bool { for _, r := range s { if r > 127 { return false } } return true}C 逐字节判断(注意必须用 unsigned char,否则高位字符会被当作负数):bool is_ascii(const char *s) { for (size_t i = 0; s[i]; i++) if ((unsigned char)s[i] > 127) return false; return true;}面试追问Q: 空字符串算 ASCII 吗?算。空集合不包含非 ASCII 字符,逻辑上为真,isascii() 和正则方式也返回 True。Q: UTF-8 编码下 ASCII 字符有什么特殊性?ASCII 字符在 UTF-8 中只占 1 字节,且编码值与 ASCII 完全一致。因此可以用 len(s) == len(s.encode("utf-8")) 间接判断:长度不等说明存在多字节字符。Q: 如何用 SIMD 加速?对长字符串,可以将每 16 字节加载到 SIMD 寄存器,与 127 做比较,一次判断 16 个字符是否都在 ASCII 范围内,比逐字符快一个数量级。Rust 的 bstr 库已内置此优化。边界注意控制字符(0–31)也是合法 ASCII,别误判C/C++ 中 char 是否有符号由实现定义,必须强转 unsigned charUnicode 组合字符(如 é = e + \u0301)各部分均在 ASCII 范围内,但视觉上是非 ASCII 外观,需根据业务场景决定是否额外处理
计算机基础阅读 05月27日 10:50

XML 中的 CDATA 是什么?什么时候需要用 CDATA?

CDATA(Character Data)是 XML 里的一个特殊标记,告诉解析器"这段内容别解析,原样保留"。当你需要在 XML 中放代码、HTML 片段或包含大量 <、>、& 的文本时,CDATA 省去逐个转义的麻烦。基本语法<code> <![CDATA[ if (x < 10 && y > 5) { return "ok"; } ]]></code><![CDATA[ 和 ]]> 之间的内容,XML 解析器不会尝试解析标签或实体引用,全部当作原始文本处理。什么时候需要 CDATA嵌入代码:JavaScript、SQL、CSS 里大量使用 <、>、&&,不用 CDATA 就得写成 <、>、&&,可读性极差。<script> <![CDATA[ function check() { if (count < 10 && status === "active") { return true; } } ]]></script>嵌入 HTML 片段:RSS feed 里经常包含 HTML 内容,CDATA 是标准做法。<description> <![CDATA[ <p>这是一段<strong>HTML</strong>内容</p> ]]></description>嵌入 SQL 查询:MyBatis、Hibernate 的 XML 映射文件里写 SQL,比较运算符必须转义或用 CDATA。<select id="findActive"> <![CDATA[ SELECT * FROM users WHERE age > 18 AND score >= 60 ]]></select>CDATA 的限制不能嵌套:CDATA 内部不能出现 ]]>,因为解析器会把第一个 ]]> 当作 CDATA 结束标记。如果内容里确实需要 ]]>,得拆成两个 CDATA 节:]]]><![CDATA[>。大小写敏感:必须是 CDATA,写成 cdata 或 Cdata 都不对。空白保留:CDATA 里的换行和缩进会原样保留,包括你不想保留的。格式化 XML 时注意别误改 CDATA 内的空白。不能做部分转义:CDATA 是全有或全无的——整个内容都不解析。如果只需要转义个别字符,用实体引用 < > 更精确。CDATA vs 实体引用| 特性 | CDATA | 实体引用 ||------|-------|----------|| 语法 | <![CDATA[...]]> | < > & || 适用范围 | 大段文本 | 单个字符 || 可读性 | 高,原文可读 | 低,需要还原 || 灵活性 | 低,整个块不解析 | 高,精确控制 |经验法则:超过 3 个特殊字符就用 CDATA,少于 3 个用实体引用。常见误区CDATA 不是数据类型:CDATA 只是告诉解析器别解析,它不改变数据的含义。解析后 <![CDATA[hello]]> 和 hello 是等价的——应用程序拿到的是同样的字符串。CDATA 不影响验证:XSD 验证时,CDATA 内的内容同样会被检查是否符合类型约束。CDATA 只跳过解析,不跳过验证。浏览器中的 CDATA:XHTML 里曾经用 //<![CDATA[ 包裹 JavaScript,但 HTML5 不需要——<script> 标签的内容本身就不被当作 XML 解析。这个用法已经过时了。
计算机基础阅读 05月27日 10:49

XML 和 JSON 有什么区别?什么时候该用 XML?

XML 和 JSON 是两种最常用的数据交换格式,但它们的定位不同:XML 是标记语言,擅长表达文档结构;JSON 是数据格式,擅长表达结构化数据。现代 Web 开发 90% 的场景用 JSON,但 XML 在特定领域仍然不可替代。核心区别| 特性 | XML | JSON ||------|-----|------|| 定位 | 标记语言,面向文档 | 数据格式,面向数据 || 语法 | 标签闭合 <name>值</name> | 键值对 "name": "值" || 数据类型 | 无内置类型,都是字符串 | string、number、boolean、null、array、object || 注释 | 支持 <!-- --> | 不支持 || 命名空间 | 支持,避免标签冲突 | 不支持 || 验证 | DTD / XSD 成熟方案 | JSON Schema(较新,工具链不完善) || 冗余度 | 高(开闭标签重复) | 低 || 解析速度 | 慢(DOM/SAX) | 快(原生支持) |一句话概括:XML 能做文档,JSON 只能做数据;JSON 传输快,XML 验证强。什么时候必须用 XML包含文档内容:XML 的标签能表达语义和层级(标题、段落、列表),JSON 的键值对做不到。Office 文档(docx、xlsx)底层是 XML,RSS/Atom feed 也是 XML——这些场景需要混合内容和结构。需要严格验证:XSD 可以定义精确的类型约束(值范围、正则模式、枚举),JSON Schema 功能弱得多。金融、医疗、政府数据交换标准(如 HL7、FHIR 的 XML 格式)依赖 XSD 验证。命名空间:多个词汇表组合时,命名空间避免标签冲突。SOAP、XHTML、SVG 都用命名空间。JSON 没有这个能力。遗留系统集成:企业里大量旧系统只认 XML。SAP、Oracle、银行接口——你不想用也得用。JSON 的优势场景Web API:RESTful API 用 JSON 是事实标准。体积小、解析快、前端原生支持,没有理由用 XML。配置文件:package.json、tsconfig.json、.eslintrc——开发工具链已经全面倒向 JSON(以及 JSON 超集如 JSON5、YAML)。移动端和低带宽场景:JSON 比 XML 小 30-50%,解析快 2-3 倍。移动网络下这个差距很实际。NoSQL 数据库:MongoDB、CouchDB 存储 JSON 文档,查询天然适配。同一数据的格式对比<!-- XML --><book id="1" category="web"> <title>XML Guide</title> <price>39.95</price> <tags> <tag>XML</tag> <tag>Programming</tag> </tags></book>{ "id": 1, "category": "web", "title": "XML Guide", "price": 39.95, "tags": ["XML", "Programming"]}XML 版本 156 字节,JSON 版本 98 字节。数据量大的时候,这个差距更明显。格式互转XML 和 JSON 互转不是无损的——XML 的属性、命名空间、混合内容在 JSON 里没有对应概念:XML 属性(<book id="1">)转 JSON 时变成普通字段,丢失"这是属性"的语义XML 混合内容(<p>文字<b>加粗</b>继续</p>)转 JSON 需要特殊处理JSON 的数组类型转 XML 时只能用重复标签模拟所以别指望"先写 XML 再转 JSON"或反过来——两种格式的数据模型不同,互转会丢信息。选型决策简单判断:如果数据是给人读的文档,用 XML;如果是给程序消费的结构化数据,用 JSON。如果两者都涉及(比如带格式的富文本数据),考虑用 JSON 做传输、XML 做存储,或者直接用 Markdown + JSON 元数据的组合方案。
计算机基础阅读 05月27日 10:49

XML Schema 和 DTD 有什么区别?XSD 为什么取代了 DTD?

XML Schema(XSD)和 DTD 都用来定义 XML 文档的结构和约束,但能力差距很大。XSD 是 DTD 的现代替代方案——基于 XML 语法、支持数据类型、支持命名空间、可扩展可继承。DTD 语法简单但功能有限,新项目几乎不再使用。核心区别| 特性 | XML Schema (XSD) | DTD ||------|------------------|-----|| 语法 | XML 格式,可用 XML 解析器处理 | 自有语法,不是 XML || 数据类型 | 丰富内置类型(string、int、date、boolean 等) | 只有字符串,没有类型区分 || 命名空间 | 原生支持 | 不支持 || 类型继承 | 支持 extension 和 restriction | 不支持 || 可重用性 | 支持类型导入和引用 | 难以复用 || 约束精度 | 可定义值范围、正则模式、枚举 | 只能定义元素出现次数 |简单说:XSD 能做的 DTD 做不了(类型约束、命名空间),DTD 能做的 XSD 都能做且做得更好。XSD 基础结构XSD 本身是 XML 文档,根元素是 <xs:schema>:<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="book" type="BookType"/> <xs:complexType name="BookType"> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="price" type="xs:decimal"/> <xs:element name="publishDate" type="xs:date"/> </xs:sequence> <xs:attribute name="id" type="xs:string" use="required"/> </xs:complexType></xs:schema>complexType 定义包含子元素或属性的复杂类型,simpleType 定义带约束的简单类型。XSD 的约束能力XSD 比 DTD 强的地方在于精确约束:<!-- 值范围约束 --><xs:simpleType name="AgeType"> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="120"/> </xs:restriction></xs:simpleType><!-- 正则约束 --><xs:simpleType name="EmailType"> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"/> </xs:restriction></xs:simpleType><!-- 枚举约束 --><xs:simpleType name="StatusType"> <xs:restriction base="xs:string"> <xs:enumeration value="active"/> <xs:enumeration value="inactive"/> </xs:restriction></xs:simpleType>DTD 只能声明元素存在和出现次数,无法约束值的格式和范围。类型继承和扩展XSD 支持两种继承方式:extension:在基础类型上添加新元素或属性restriction:在基础类型上收紧约束<!-- 扩展:在 PersonType 上加 department --><xs:complexType name="EmployeeType"> <xs:complexContent> <xs:extension base="PersonType"> <xs:sequence> <xs:element name="department" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent></xs:complexType>这是 DTD 完全做不到的——DTD 没有类型体系,每个元素定义都是独立的。在 XML 中引用 XSD<book xmlns="http://www.example.com/books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/books books.xsd"> <title>XML Guide</title> <price>49.99</price> <publishDate>2024-01-15</publishDate></book>schemaLocation 属性成对出现:命名空间 URI + XSD 文件路径。解析器会根据 XSD 验证文档内容。什么时候还在用 DTD?DTD 在 2025 年基本只剩这些场景:维护遗留系统(改 DTD 风险比替换小)HTML5 的 DOCTYPE 声明(严格说是简化版 DTD)简单的配置文件验证(不值得写 XSD 的场景)新项目用 XSD,没有理由选 DTD。如果嫌 XSD 太啰嗦,可以考虑 RelaxNG——更简洁的替代方案。
计算机基础阅读 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 中。