# 域名系统底层原理概论

**URL:** <https://idcflare.com/t/topic/37206>\
**Category:** 教程\
**Tags:** 域名\
**Created:** [2025 年11 月 2 日 16:43 UTC](https://idcflare.com/t/topic/37206 "2025-11-02T16:43:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

作者： ![MatsuzakaSato](https://idcflare.com/user_avatar/idcflare.com/matsuzakasato/32/19828_2.png) [@MatsuzakaSato](https://idcflare.com/u/MatsuzakaSato)\
发布日期： [2025 年11 月 2 日 16:43 UTC](https://idcflare.com/t/topic/37206/1 "2025-11-02T16:43:15Z")

</div>

> [!warning]说明  
> 由于我对于本站征文投票机制和倾向表达的不满，多次引发某些人群对于我“规则利己主义”的批评，认为我不满于规则没有向自己倾斜。因此我决定不再参与后续的任何征文活动，以便彻底站在利益无关方的立场安静地写作，清理这些阴暗的揣测。
> 
> 我一直相信，触及底层原理的文章，尽管因为晦涩且无法即时起效，不被大多数人看好，但它的价值是长存的，它永远是你在迷茫困惑时的一盏灯塔。  
> 所以我不满足于“给你一个Docker-compose配置”，我要为你讲清楚Docker的基础知识；我不会仅限于告诉你怎样一步一步配置域名，我要让大家了解它到底是怎样工作的。  
> 授人以鱼不如授人以渔。我相信即使不参与征文竞赛，没有社区推流和那几十美元的奖金，我的文章也总是能够被知音发掘，并在很长的一段时间里都能为有需要的人带来帮助。

> 本文考证时间约14天，写作时间约2小时

## 前言

当你在浏览器输入一个域名时，是否有思考过，计算机是如何通过域名查询到服务器IP地址的？全球无数的主机、无数的域名、无数的查询请求，又是如何维持高度的稳定性与可信度的？在这背后，正是域名系统（Domain Name System）这一大互联网基础设施发挥着作用。

## 域名的构成

域名是一个倒置的树状结构，从右向左，层级逐渐细化  
我们常见的域名写法是`www.example.com`，然而更加标准的写法应当在末尾增加一个点：

```auto
www.example.com.

```

这就是完全限定域名（FQDN, Fully Qualified Domain Name）

> [!note]  
> 是的，在Chrome的地址栏里输入`www.example.com.`，也可以访问到正确的站点。
> 
> 你可以理解为`www.example.com`就像是文件系统里的一个相对路径`com/example/www`，只是系统默认了这个相对路径以根目录`/`（在域名系统里叫做搜索域）为参照。而`www.example.com.`相当于直接输入`/com/example/www`这个绝对路径。

让我们从右往左分析其结构：

| 区域 | 级别 | 作用 |
| --- | --- | --- |
| `.` | 根域（ROOT） | 整个域名系统的起点 |
| `com.` | 顶级域（TLD, Top-Level Domain） | `com`由Verisign负责；TLD分为gTLD（通用顶级域）与ccTLD（国家/地区顶级域） |
| `example.com.` | 二级域（Second-Level Domain） | 由组织或个人持有，需要通过注册商购买 |
| `www.example.com.` | 子域 | 可自由创建的前缀 |

## 全球根与权威名称服务器

全球共有13组根服务器（A~M），它们是DNS查询的最高权威。话虽如此，这13“台”服务器实际上通过任播（Anycast）技术，对应着全球数百个镜像节点，中国虽然没有根服务器（至于“雪人计划”我们后面再聊，新坑+1），但有镜像节点。  
全球根服务器对根域（ROOT），也就是我们上文提到的`.`负责。它管理所有的TLD，并指向它们各自的专门的权威服务器，包括`com.`,`net.`,`cn.`,`international.`等等。  
`com.`/`net.`会被指向Verisign，而`cn.`则会被指向CNNIC。

> [!note]  
> 现在，你可以打开电脑，输入以下命令，查看它们究竟指向了哪里。
> 
> ```auto
> dig com. NS +short
> dig net. NS +short
> dig cn. NS +short
> 
> ```

## DNS迭代查询流程

以`www.example.com.`的查询流程为例，我们需要查询这个域名的A记录，就需要向名称服务器（NS, Name Server）发起请求。  
但很遗憾，你现在唯一知道的，就是那13个刻在 ~~大脑~~ 系统里的全球根服务器。你决定向它们之一求助。

> [!note] 用于记录这13个全球根服务器IP的文件，就是根提示文件（Root Hints File）

于是你向`198.41.0.4`，也就是其中一个全球根发起了请求：

- 我想知道`www.example.com.`的A记录

全球根服务器表示很为难：

- 我并不知道`www.example.com.`的A记录是什么，不过`com.`确实归我管，我刚才查询了我的区域（Zone）文件，你现在可以去找`com.`的NS，它的域名是`a.gtld-server.net`，它的IP是`192.5.6.30`

> [!note]  
> `a.gtld-server.net`是威瑞信（Verisign）的一个权威名称服务器。  
> 这里会同时返回一个IP，叫做“胶水记录”，毕竟`.net`的NS也是`a.gtld-server.net`，要是不直接给的IP，那就会出现“想要知道`a.gtld-server.net`在哪，得去问`a.gtld-server.net`，至于`a.gtld-server.net`在哪得问`a.gtld-server.net`”的抽象问题。

言归正传，你决定遵从全球根服务器的信息，向`a.gtld-server.net`询问：

- 我想知道`www.example.com.`的A记录

Verisign也表示很为难：

- 我也不知道`www.example.com.`的A记录是什么，但是我管理着`example.com.`。`com.`的区域文件提示，`example.com.`的NS记录是`a.iana-servers.net.`

于是你继续找`a.iana-servers.net.`询问：

- 我想知道`www.example.com.`的A记录

这下对了！IANA的名称服务器表示：

- 我确实管理着`example.com.`的区域文件，`www`子域的A记录是`95.101.27.204`

就这样，经过多次 **迭代** ，你终于找到了`www.example.com`指向的ipv4地址。

> [!note]  
> 实际上，DNS服务器会递归地帮助你直接完成上述迭代，你只需要向某个DNS服务器发起委派查询，它会自动、高效地帮助你完成上述过程（如果它没有缓存这个域名的记录），这并不需要你的个人电脑向多个NS发起多次查询。
> 
> 这也回答了另一个问题：我用中国移动的DNS服务器上网，解析托管在阿里云DNS的域名，会比解析托管在Cloudflare的域名更快吗？答案是基本没有区别。
> 
> 你发现了吗？无论是`.`根域，还是`com.`TLD、`example.com.`这个你拿到手的SLD，都通过一个预设的NS记录指向其本身以及其子域名的托管服务器。而CNAME则是“优先级高于一切”的别名，这意味着它天然与NS记录冲突，因此你 **不能** 直接在自己购买的域名上为根`@`设置CNAME解析。

## 小芝士：最长匹配原则

我们都知道，`cn.`和`com.cn.`等许多二级ccTLD都归CNNIC管理，并且共用权威名称服务器。  
那么，如果我们向CNNIC的某个权威NS（比如`a.dns.cn`）查询`markdown.com.cn.`的记录，服务器会直接返回`markdown.com.cn.`的NS，还是经历`com.cn.` → `markdown.com.cn.`两跳？

实际答案是前者：

```auto
查询 198.41.0.4
cn NS a.dns.cn
cn NS b.dns.cn
cn NS c.dns.cn
cn NS d.dns.cn
cn NS e.dns.cn
cn NS ns.cernet.net
a.dns.cn A 203.119.25.1
b.dns.cn A 203.119.26.1
c.dns.cn A 203.119.27.1
d.dns.cn A 203.119.28.1
e.dns.cn A 203.119.29.1

查询 a.dns.cn (203.119.25.1)
markdown.com.cn NS sixty.dnspod.net
markdown.com.cn NS medicine.dnspod.net

```

这是因为RFC 1034明确了最特定区域匹配的原则（或者理解为最长匹配原则）。CNNIC的权威NS同时管理着`com.cn.zone`和`cn.zone`两个区域文件，对于`markdown.com.cn.`而言前者显然完全匹配且更加具体。

> [!note]  
> 思考题：假如权威NS没有按照最特定区域匹配的原则进行响应，会出现什么问题？

要注意的是，`edu.cn.`的权威NS与`cn.`不同：

```auto
查询 198.41.0.4
cn NS a.dns.cn
cn NS b.dns.cn
cn NS c.dns.cn
cn NS d.dns.cn
cn NS e.dns.cn
cn NS ns.cernet.net
a.dns.cn A 203.119.25.1
b.dns.cn A 203.119.26.1
c.dns.cn A 203.119.27.1
d.dns.cn A 203.119.28.1
e.dns.cn A 203.119.29.1

查询 a.dns.cn (203.119.25.1)
edu.cn NS dns.edu.cn
edu.cn NS ns2.cernet.net
edu.cn NS ns4.cernet.net
edu.cn NS ns5.cernet.net
edu.cn NS dns2.edu.cn
edu.cn NS dns3.edu.cn
dns.edu.cn A 202.38.109.35
dns.edu.cn TYPE28 20010250c00600000000000000000035
dns2.edu.cn A 202.112.0.13
dns2.edu.cn TYPE28 20010da8000101000000000000000013
dns3.edu.cn A 101.4.62.35
Zone: edu.cn

查询 dns.edu.cn (202.38.109.35)
sysu.edu.cn NS ns3.sysu.edu.cn
sysu.edu.cn NS ns2.sysu.edu.cn
sysu.edu.cn NS ns1.sysu.edu.cn
ns3.sysu.edu.cn A 202.116.64.6
ns2.sysu.edu.cn A 202.116.64.2
ns1.sysu.edu.cn A 202.116.64.1
ns3.sysu.edu.cn TYPE28 20010250300200100000000000000006
ns2.sysu.edu.cn TYPE28 20010250300200100000000000000002
Zone: sysu.edu.cn

查询 ns3.sysu.edu.cn (202.116.64.6)
ns1.sysu.edu.cn A 202.116.64.1
ns2.sysu.edu.cn A 202.116.64.2
ns3.sysu.edu.cn A 202.116.64.6
ns1.sysu.edu.cn TYPE28 20010250300200100000000000000001
ns2.sysu.edu.cn TYPE28 20010250300200100000000000000002

```

## 附录

上述查询记录的源代码（Python原生）：

> **希望它可以作为你亲自动手的开始**
>
> ```python
> import socket
> import struct
> import random
> from typing import List, Tuple, Optional, Dict
> 
> class DNSQuery:
> """DNS查询工具类"""
>     
> # 根服务器列表（使用部分根服务器）
> ROOT_SERVERS = [
> "198.41.0.4", # a.root-servers.net
> "199.9.14.201", # b.root-servers.net
> "192.33.4.12", # c.root-servers.net
> "199.7.91.13", # d.root-servers.net
> ]
>     
> def __init__ (self):
> self.query_log = []
>     
> def build_dns_query(self, domain: str, qtype: int = 2) -> bytes:
> """
> 构建DNS查询包
> :param domain: 要查询的域名
> :param qtype: 查询类型 (1=A, 2=NS, 15=MX, 16=TXT)
> :return: DNS查询包的字节数组
> """
> # 生成随机事务ID
> transaction_id = random.randint(0, 65535)
>         
> # DNS Header (12字节)
> # ID (2字节) + Flags (2字节) + 4个计数字段 (各2字节)
> flags = 0x0100 # 标准查询，期望递归
> header = struct.pack('>HHHHHH', 
> transaction_id, # ID
> flags, # Flags
> 1, # QDCOUNT (问题数)
> 0, # ANCOUNT (回答数)
> 0, # NSCOUNT (授权记录数)
> 0) # ARCOUNT (附加记录数)
>         
> # Question Section
> question = self._encode_domain(domain)
> question += struct.pack('>HH', qtype, 1) # QTYPE, QCLASS (1=IN)
>         
> return header + question
>     
> def _encode_domain(self, domain: str) -> bytes:
> """将域名编码为DNS格式"""
> encoded = b''
> for label in domain.split('.'):
> length = len(label)
> encoded += bytes([length]) + label.encode('ascii')
> encoded += b'\x00' # 以0结尾
> return encoded
>     
> def parse_dns_response(self, response: bytes) -> Dict:
> """
> 解析DNS响应包
> :param response: DNS响应包
> :return: 解析后的字典
> """
> # 解析Header
> header = struct.unpack('>HHHHHH', response[:12])
> transaction_id, flags, qdcount, ancount, nscount, arcount = header
>         
> result = {
> 'transaction_id': transaction_id,
> 'flags': flags,
> 'questions': qdcount,
> 'answers': ancount,
> 'authority': nscount,
> 'additional': arcount,
> 'answer_records': [],
> 'authority_records': [],
> 'additional_records': []
> }
>         
> # 跳过Question Section
> offset = 12
> for _ in range(qdcount):
> offset, _ = self._skip_name(response, offset)
> offset += 4 # QTYPE + QCLASS
>         
> # 解析Answer Section
> for _ in range(ancount):
> offset, record = self._parse_record(response, offset)
> result['answer_records'].append(record)
>         
> # 解析Authority Section (NS记录通常在这里)
> for _ in range(nscount):
> offset, record = self._parse_record(response, offset)
> result['authority_records'].append(record)
>         
> # 解析Additional Section (可能包含NS的A记录)
> for _ in range(arcount):
> offset, record = self._parse_record(response, offset)
> result['additional_records'].append(record)
>         
> return result
>     
> def _skip_name(self, data: bytes, offset: int) -> Tuple[int, str]:
> """跳过并解析域名，返回新的offset和域名"""
> labels = []
> jumped = False
> jump_offset = offset
>         
> while True:
> if offset >= len(data):
> break
>                 
> length = data[offset]
>             
> if length == 0:
> offset += 1
> break
> elif (length & 0xC0) == 0xC0: # 指针压缩
> if not jumped:
> jump_offset = offset + 2
> jumped = True
> pointer = struct.unpack('>H', data[offset:offset+2])[0]
> offset = pointer & 0x3FFF
> continue
> else:
> offset += 1
> labels.append(data[offset:offset+length].decode('ascii', errors='ignore'))
> offset += length
>         
> if jumped:
> return jump_offset, '.'.join(labels)
> return offset, '.'.join(labels)
>     
> def _parse_record(self, data: bytes, offset: int) -> Tuple[int, Dict]:
> """解析单条DNS记录"""
> offset, name = self._skip_name(data, offset)
>         
> if offset + 10 > len(data):
> return offset, {}
>         
> rtype, rclass, ttl, rdlength = struct.unpack('>HHIH', data[offset:offset+10])
> offset += 10
>         
> record = {
> 'name': name,
> 'type': rtype,
> 'class': rclass,
> 'ttl': ttl,
> 'data': None
> }
>         
> if offset + rdlength > len(data):
> return offset, record
>         
> # 解析RDATA
> if rtype == 1: # A记录
> if rdlength == 4:
> record['data'] = '.'.join(str(b) for b in data[offset:offset+4])
> elif rtype == 2: # NS记录
> _, ns_name = self._skip_name(data, offset)
> record['data'] = ns_name
> elif rtype == 5: # CNAME记录
> _, cname = self._skip_name(data, offset)
> record['data'] = cname
> elif rtype == 6: # SOA记录
> record['data'] = 'SOA'
> else:
> record['data'] = data[offset:offset+rdlength].hex()
>         
> offset += rdlength
> return offset, record
>     
> def query_dns(self, server: str, domain: str, qtype: int = 2, port: int = 53) -> Optional[Dict]:
> """
> 向指定DNS服务器发送查询
> :param server: DNS服务器IP
> :param domain: 要查询的域名
> :param qtype: 查询类型
> :param port: 端口号
> :return: 解析后的响应
> """
> try:
> query = self.build_dns_query(domain, qtype)
> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> sock.settimeout(5)
> sock.sendto(query, (server, port))
> response, _ = sock.recvfrom(4096)
> sock.close()
> return self.parse_dns_response(response)
> except Exception as e:
> return None
>     
> def recursive_query(self, domain: str):
> """
> 递归查询域名，从根服务器开始
> :param domain: 要查询的域名
> """
> print(f"\n查询 {self.ROOT_SERVERS[0]}")
>         
> response = self.query_dns(self.ROOT_SERVERS[0], domain, qtype=2)
>         
> if not response:
> return
>         
> self._print_response(response)
>         
> # 从Authority Section获取下一级NS服务器
> ns_servers = self._extract_ns_servers(response)
>         
> if not ns_servers:
> return
>         
> # 第二步及后续：向TLD服务器查询
> current_server = ns_servers[0]
>         
> while True:
> print(f"\n查询 {current_server['ns']} ({current_server['ip']})")
>             
> response = self.query_dns(current_server['ip'], domain, qtype=2)
>             
> if not response:
> break
>             
> self._print_response(response)
>             
> # 检查是否有Answer Section (表示找到了最终答案)
> if response['answers'] > 0:
> break
>             
> # 否则继续从Authority Section获取下一级服务器
> ns_servers = self._extract_ns_servers(response)
>             
> if not ns_servers:
> break
>             
> # 检查返回的zone是什么
> if response['authority_records']:
> zone = response['authority_records'][0].get('name', '')
> print(f"Zone: {zone}")
>             
> current_server = ns_servers[0]
>     
> def _print_response(self, response: Dict):
> """打印DNS响应的详细信息"""
> for record in response['authority_records']:
> self._print_record(record)
> for record in response['additional_records'][:5]:
> self._print_record(record)
>     
> def _print_record(self, record: Dict):
> """打印单条记录"""
> type_map = {1: 'A', 2: 'NS', 5: 'CNAME', 6: 'SOA'}
> type_str = type_map.get(record.get('type'), f"TYPE{record.get('type')}")
> print(f"{record.get('name'):25s} {type_str:5s} {record.get('data')}")
>     
> def _extract_ns_servers(self, response: Dict) -> List[Dict]:
> """从响应中提取NS服务器及其IP地址"""
> ns_servers = []
>         
> # 从Authority Section获取NS记录
> ns_names = []
> for record in response['authority_records']:
> if record.get('type') == 2: # NS记录
> ns_names.append(record.get('data'))
>         
> # 从Additional Section获取对应的A记录
> for ns_name in ns_names:
> for record in response['additional_records']:
> if record.get('type') == 1 and record.get('name') == ns_name:
> ns_servers.append({
> 'ns': ns_name,
> 'ip': record.get('data')
> })
> break
>         
> return ns_servers
> 
> def main():
> """主函数"""
> import sys
>     
> dns = DNSQuery()
>     
> # 如果有命令行参数，使用参数作为域名
> # python3 main.py markdown.com.cn
> if len(sys.argv) > 1:
> domain = sys.argv[1]
> else:
> domain = "sysu.edu.cn"
>     
> dns.recursive_query(domain)
> 
> if __name__ == " __main__":
> main()
> 
> ```

---

<div class="post-metadata">

作者： ![BBS](https://idcflare.com/user_avatar/idcflare.com/bbs/32/8893_2.png) [@BBS](https://idcflare.com/u/BBS)\
发布日期： [2025 年11 月 2 日 16:46 UTC](https://idcflare.com/t/topic/37206/2 "2025-11-02T16:46:46Z")

</div>

因为大量黑洞查询全球根域名服务器压力奇大，clcloudflare特别推一项计划来缓解这个问题呢w

---

<div class="post-metadata">

作者： ![xkm](https://idcflare.com/letter_avatar/xkm/32/6_22734026db12803ebb3e059622ac3534.png) [@xkm](https://idcflare.com/u/xkm)\
发布日期： [2025 年11 月 2 日 18:13 UTC](https://idcflare.com/t/topic/37206/3 "2025-11-02T18:13:55Z")

</div>

好文无人，顶一下喵

---

<div class="post-metadata">

作者： ![nero](https://idcflare.com/user_avatar/idcflare.com/nero/32/714_2.png) [@nero](https://idcflare.com/u/nero)\
发布日期： [2025 年11 月 2 日 18:17 UTC](https://idcflare.com/t/topic/37206/4 "2025-11-02T18:17:46Z")

</div>

谢谢分享 🫰

---

<div class="post-metadata">

作者： ![orz\_10086](https://idcflare.com/user_avatar/idcflare.com/orz_10086/32/52403_2.png) [@orz\_10086](https://idcflare.com/u/orz_10086)\
发布日期： [2025 年11 月 2 日 18:26 UTC](https://idcflare.com/t/topic/37206/5 "2025-11-02T18:26:27Z")

</div>

支持，我感觉L站或者if站对我来说，最有用的就是各种教程，虽然学的零零碎碎🤣。

---

<div class="post-metadata">

作者： ![pikaqiu](https://idcflare.com/user_avatar/idcflare.com/pikaqiu/32/10439_2.png) [@pikaqiu](https://idcflare.com/u/pikaqiu)\
发布日期： [2025 年11 月 2 日 19:50 UTC](https://idcflare.com/t/topic/37206/6 "2025-11-02T19:50:57Z")

</div>

好文 学习一下

---

<div class="post-metadata">

作者： ![ATM](https://idcflare.com/letter_avatar/atm/32/6_22734026db12803ebb3e059622ac3534.png) [@ATM](https://idcflare.com/u/ATM)\
发布日期： [2025 年11 月 2 日 20:30 UTC](https://idcflare.com/t/topic/37206/7 "2025-11-02T20:30:29Z")

</div>

现在不是有http dns了，直接去问权威域名要IP，传统的方式可以留着兜底用

---

<div class="post-metadata">

作者： ![yqyan](https://idcflare.com/user_avatar/idcflare.com/yqyan/32/3375_2.png) [@yqyan](https://idcflare.com/u/yqyan)\
发布日期： [2025 年11 月 2 日 22:39 UTC](https://idcflare.com/t/topic/37206/8 "2025-11-02T22:39:02Z")

</div>

感谢科普 🙏

---

<div class="post-metadata">

作者： ![MatsuzakaSato](https://idcflare.com/user_avatar/idcflare.com/matsuzakasato/32/19828_2.png) [@MatsuzakaSato](https://idcflare.com/u/MatsuzakaSato)\
发布日期： [2025 年11 月 2 日 22:50 UTC](https://idcflare.com/t/topic/37206/9 "2025-11-02T22:50:41Z")

</div>

DoH，DoT只是终端用户的DNS查询方式，描述终端用户如何向域名系统（DNS）发起查询，属于DNS **协议** 。  
而本文主要描述的是DNS，也就是域名 **系统** 本身。DoH、DoT的出现并不会改变域名系统基于全球根服务器开始，树状结构、分层授权、迭代查询的底层逻辑。

---

<div class="post-metadata">

作者： ![SONY](https://idcflare.com/user_avatar/idcflare.com/sony/32/2299_2.png) [@SONY](https://idcflare.com/u/SONY)\
发布日期： [2025 年11 月 2 日 23:37 UTC](https://idcflare.com/t/topic/37206/10 "2025-11-02T23:37:04Z")

</div>

大佬 就是大佬 感谢科普

---

<div class="post-metadata">

作者： ![realms](https://idcflare.com/user_avatar/idcflare.com/realms/32/1908_2.png) [@realms](https://idcflare.com/u/realms)\
发布日期： [2025 年11 月 2 日 23:48 UTC](https://idcflare.com/t/topic/37206/11 "2025-11-02T23:48:27Z")

</div>

支持砂糖

---

<div class="post-metadata">

作者： ![zdq](https://idcflare.com/user_avatar/idcflare.com/zdq/32/8109_2.png) [@zdq](https://idcflare.com/u/zdq)\
发布日期： [2025 年11 月 3 日 00:14 UTC](https://idcflare.com/t/topic/37206/12 "2025-11-03T00:14:36Z")

</div>

知识+1

---

<div class="post-metadata">

作者： ![MacroHard](https://idcflare.com/user_avatar/idcflare.com/macrohard/32/7514_2.png) [@MacroHard](https://idcflare.com/u/MacroHard)\
发布日期： [2025 年11 月 3 日 00:16 UTC](https://idcflare.com/t/topic/37206/13 "2025-11-03T00:16:13Z")

</div>

感谢分享，学习ing

---

<div class="post-metadata">

作者： ![Luis](https://idcflare.com/user_avatar/idcflare.com/luis/32/247_2.png) [@Luis](https://idcflare.com/u/Luis)\
发布日期： [2025 年11 月 3 日 00:32 UTC](https://idcflare.com/t/topic/37206/14 "2025-11-03T00:32:07Z")

</div>

砂糖太强了！ 马上学习dns

---

<div class="post-metadata">

作者： ![ketto](https://idcflare.com/user_avatar/idcflare.com/ketto/32/11517_2.png) [@ketto](https://idcflare.com/u/ketto)\
发布日期： [2025 年11 月 3 日 00:41 UTC](https://idcflare.com/t/topic/37206/15 "2025-11-03T00:41:23Z")

</div>

不错，学习了，感谢佬友的分享。

---

<div class="post-metadata">

作者： ![ORG](https://idcflare.com/user_avatar/idcflare.com/org/32/10054_2.png) [@ORG](https://idcflare.com/u/ORG)\
发布日期： [2025 年11 月 3 日 00:44 UTC](https://idcflare.com/t/topic/37206/16 "2025-11-03T00:44:23Z")

</div>

受教了，感谢大佬的精彩分享。

---

<div class="post-metadata">

作者： ![EmptyKYP](https://idcflare.com/user_avatar/idcflare.com/emptykyp/32/14148_2.png) [@EmptyKYP](https://idcflare.com/u/EmptyKYP)\
发布日期： [2025 年11 月 3 日 00:56 UTC](https://idcflare.com/t/topic/37206/17 "2025-11-03T00:56:37Z")

</div>

感谢大佬的精彩分享

---

<div class="post-metadata">

作者： ![y27450202](https://idcflare.com/user_avatar/idcflare.com/y27450202/32/621_2.png) [@y27450202](https://idcflare.com/u/y27450202)\
发布日期： [2025 年11 月 3 日 01:09 UTC](https://idcflare.com/t/topic/37206/18 "2025-11-03T01:09:24Z")

</div>

感谢佬友抽出时间来科普知识。mark下，晚点来看

---

<div class="post-metadata">

作者： ![williamwei](https://idcflare.com/user_avatar/idcflare.com/williamwei/32/4923_2.png) [@williamwei](https://idcflare.com/u/williamwei)\
发布日期： [2025 年11 月 3 日 01:13 UTC](https://idcflare.com/t/topic/37206/19 "2025-11-03T01:13:48Z")

</div>

给佬友点个赞了！

---

<div class="post-metadata">

作者： ![ddd](https://idcflare.com/user_avatar/idcflare.com/ddd/32/19861_2.png) [@ddd](https://idcflare.com/u/ddd)\
发布日期： [2025 年11 月 3 日 01:16 UTC](https://idcflare.com/t/topic/37206/20 "2025-11-03T01:16:59Z")

</div>

谢谢，学到了

[下一页](https://idcflare.com/t/topic/37206.md?page=2)
