<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on 架构视界</title>
    <link>https://blog-architectview.pages.dev/posts/</link>
    <description>Recent content in Posts on 架构视界</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <copyright>© 2026 架构视界 Architect View</copyright>
    <lastBuildDate>Thu, 21 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog-architectview.pages.dev/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>DDD 实战：聚合根设计的五条血泪教训</title>
      <link>https://blog-architectview.pages.dev/posts/ddd-aggregate-root-lessons/</link>
      <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/ddd-aggregate-root-lessons/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;2023 年，我主导了一个电商中台的 DDD 重构项目。从最初的「大泥球」单体架构到最终的领域驱动设计落地，我们踩了无数的坑。这篇文章不谈理论，只讲实战中用血泪换来的五条聚合根设计教训。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;背景那个让我们失眠的订单系统&#34;&gt;背景：那个让我们失眠的订单系统&lt;/h2&gt;&#xA;&lt;p&gt;老系统是一个典型的「上帝类」架构——&lt;code&gt;OrderService&lt;/code&gt; 有 8000 多行代码，一个 &lt;code&gt;createOrder&lt;/code&gt; 方法就包含了库存扣减、优惠券核销、积分计算、物流单创建等 12 个领域的逻辑。任何一个小改动都可能引发蝴蝶效应。&lt;/p&gt;&#xA;&lt;p&gt;我们决定用 DDD 重构。但理论上的 DDD 和工程实践之间的鸿沟，远比教科书中描述的要深。&lt;/p&gt;&#xA;&lt;h2 id=&#34;教训一聚合根不是实体是一致性边界&#34;&gt;教训一：聚合根不是实体，是一致性边界&lt;/h2&gt;&#xA;&lt;p&gt;最初的设计中，我们把 &lt;code&gt;Order&lt;/code&gt;（订单）设计成了一个巨大的聚合根，里面包含了订单项、收货地址、支付信息、物流跟踪、发票信息等所有关联实体。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 错误示范：上帝聚合根&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Order&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; OrderId id;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;OrderItem&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; items;          &lt;span style=&#34;color:#75715e&#34;&gt;// 订单项&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; ShippingAddress address;        &lt;span style=&#34;color:#75715e&#34;&gt;// 收货地址&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; PaymentInfo payment;            &lt;span style=&#34;color:#75715e&#34;&gt;// 支付信息&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;LogisticsRecord&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; logistics;&lt;span style=&#34;color:#75715e&#34;&gt;// 物流跟踪&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; InvoiceInfo invoice;            &lt;span style=&#34;color:#75715e&#34;&gt;// 发票信息&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; CouponUsage couponUsage;        &lt;span style=&#34;color:#75715e&#34;&gt;// 优惠券使用记录&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;OrderRemark&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; remarks;      &lt;span style=&#34;color:#75715e&#34;&gt;// 订单备注&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 一个方法改了 7 个实体的状态...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;confirmOrder&lt;/span&gt;() {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 验证库存、验证地址、创建支付单、生成物流单...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;问题很快暴露了&lt;/strong&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>JVM 调优手记：GC 停顿时间从 500ms 压到 20ms</title>
      <link>https://blog-architectview.pages.dev/posts/jvm-gc-tuning-500ms-to-20ms/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/jvm-gc-tuning-500ms-to-20ms/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;线上告警：P99 延迟从 80ms 飙升至 2000ms，每隔几分钟就有一次「毛刺」。排查了三天，最终发现罪魁祸首是 GC。这是一篇完整的 JVM 调优实战记录，从问题定位到参数调优，全程复盘。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;事故现场&#34;&gt;事故现场&lt;/h2&gt;&#xA;&lt;p&gt;我们的实时推荐服务部署在 8 台 16C32G 的机器上，JDK 17，堆内存配置为 &lt;code&gt;-Xmx12g -Xms12g&lt;/code&gt;，使用 G1 垃圾回收器。日均请求量 2 亿次，单机 QPS 约 3000。&lt;/p&gt;&#xA;&lt;p&gt;某天凌晨，监控系统突然告警：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;告警指标：&#xA;- P99 延迟：80ms → 2000ms（持续波动）&#xA;- GC 暂停时间：平均 500ms，峰值 3200ms&#xA;- Full GC 频率：每 3-5 分钟一次&#xA;- CPU 使用率：从 40% 飙升至 85%&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;用户侧的表现是：推荐列表偶尔加载极慢，页面出现空白等待。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第一步收集-gc-日志&#34;&gt;第一步：收集 GC 日志&lt;/h2&gt;&#xA;&lt;p&gt;开启详细 GC 日志是所有调优工作的起点：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# JDK 17 的 GC 日志参数&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/data/logs/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;50m&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 如果是 JDK 8（虽然很老了）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/data/logs/gc.log&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;用 &lt;a href=&#34;https://gceasy.io&#34;&gt;GCEasy&lt;/a&gt; 或 &lt;code&gt;gchisto&lt;/code&gt; 分析日志后，问题一目了然：&lt;/p&gt;</description>
    </item>
    <item>
      <title>分布式系统演进：从 CAP 到 PACELC 的架构思考</title>
      <link>https://blog-architectview.pages.dev/posts/distributed-systems-cap-to-pacelc/</link>
      <pubDate>Tue, 19 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/distributed-systems-cap-to-pacelc/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;CAP 定理是分布式系统的「牛顿第一定律」——它定义了这个领域的基本约束。但在真实的工程实践中，CAP 定理过于粗粒度，以至于它无法指导我们在实际系统中做出正确的设计决策。我们需要一个更精细的模型。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;cap-定理的再理解&#34;&gt;CAP 定理的再理解&lt;/h2&gt;&#xA;&lt;p&gt;2000 年，Eric Brewer 提出 CAP 猜想；2002 年，Gilbert 和 Lynch 给出了形式化证明。CAP 定理告诉我们：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;在一个分布式系统中，以下三个特性最多只能同时满足两个：&#xA;&#xA;C (Consistency)  - 一致性：所有节点在同一时刻看到相同的数据&#xA;A (Availability) - 可用性：每个请求都能在合理时间内收到非错误响应&#xA;P (Partition Tolerance) - 分区容错：网络分区发生时系统仍能运行&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;大多数架构师对 CAP 的理解停留在「三选二」的层面。但这个理解有几个问题：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;问题 1：P 不是一个可选项&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在真实的分布式系统中，网络分区是必然会发生的事情——交换机故障、光缆被挖断、数据中心之间的网络抖动。所以 P 不是你可以「选择放弃」的特性，它是一个既定事实。&lt;/p&gt;&#xA;&lt;p&gt;真正的选择是在 &lt;strong&gt;C 和 A 之间&lt;/strong&gt;，而且这个选择只在分区发生时才有意义。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;没有分区时：C 和 A 可以同时满足&#xA;发生分区时：必须在 C 和 A 之间选择&#xA;&#xA;CP 系统：分区时拒绝服务，保证一致性&#xA;  例：ZooKeeper、etcd、HBase&#xA;&#xA;AP 系统：分区时继续服务，可能返回过期数据&#xA;  例：Cassandra、DynamoDB、CouchDB&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题 2：CAP 是全局的，但需求是局部的&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;同一个系统中，不同的业务操作可能有不同的一致性需求：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;电商系统的一致性需求：&#xA;&#xA;操作 A：扣减库存&#xA;  → 需要强一致性（不能超卖）→ CP&#xA;&#xA;操作 B：展示商品评价&#xA;  → 可以接受最终一致性（延迟几秒看到新评价无所谓）→ AP&#xA;&#xA;操作 C：用户修改收货地址&#xA;  → 需要强一致性（改错了会寄错地方）→ CP&#xA;&#xA;操作 D：商品浏览量计数&#xA;  → 可以接受最终一致性（少计几次没关系）→ AP&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一个成熟的分布式系统不会在全局层面选择 CP 或 AP，而是在每个操作级别做精细的选择。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Redis 高并发缓存架构：击穿、穿透、雪崩全解</title>
      <link>https://blog-architectview.pages.dev/posts/redis-cache-breakdown-penetration-avalanche/</link>
      <pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/redis-cache-breakdown-penetration-avalanche/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;缓存是提升系统吞吐量最简单的手段，但它引入的问题也比你想象的更多。击穿、穿透、雪崩——这三个听起来像地质灾害的名词，是每一个高并发系统设计者必须跨越的三道坎。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;缓存的基本模型&#34;&gt;缓存的基本模型&lt;/h2&gt;&#xA;&lt;p&gt;在深入三个核心问题之前，先建立一个标准的缓存读写模型：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;标准缓存读取流程：&#xA;&#xA;客户端 → 缓存层（Redis）→ [命中] → 直接返回&#xA;                         → [未命中] → 数据库层 → 写入缓存 → 返回&#xA;&#xA;标准缓存写入流程：&#xA;&#xA;方案 A（Cache Aside）：先更新数据库，再删除缓存&#xA;方案 B（Read/Write Through）：通过缓存层代理读写&#xA;方案 C（Write Behind）：只写缓存，异步刷入数据库&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在绝大多数互联网场景中，&lt;strong&gt;Cache Aside&lt;/strong&gt;（旁路缓存）是最常用的模式——代码直接操作 Redis 和数据库，简单透明。但正是这种简单性，隐藏着三大问题。&lt;/p&gt;&#xA;&lt;h2 id=&#34;问题一缓存穿透cache-penetration&#34;&gt;问题一：缓存穿透（Cache Penetration）&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;定义&lt;/strong&gt;：查询一个根本不存在的数据，缓存中没有，数据库中也没有。每次请求都会穿透缓存直接打到数据库。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;正常请求：&#xA;  查询 user_id=123 → 缓存命中 → 返回（快）&#xA;&#xA;穿透请求：&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  查询 user_id=-1 → 缓存未命中 → 查数据库 → 数据库也没有 → 返回空&#xA;  &#xA;  如果每秒 10000 次这样的请求，数据库直接被压垮&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;穿透通常由恶意攻击或业务 Bug 引起——攻击者构造大量不存在的 ID，绕过缓存直接攻击数据库。&lt;/p&gt;</description>
    </item>
    <item>
      <title>微服务治理演进：从 Netflix OSS 到 Service Mesh</title>
      <link>https://blog-architectview.pages.dev/posts/microservices-netflix-to-service-mesh/</link>
      <pubDate>Sun, 17 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/microservices-netflix-to-service-mesh/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;微服务架构的流行带来了一个悖论：系统被拆分成更小的单元以降低复杂度，但服务之间的通信却创造了一个更复杂的分布式系统。如何治理这个「服务间的混沌」，是过去十年基础架构领域最重要的课题之一。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;第一阶段蛮荒时代2014-之前&#34;&gt;第一阶段：蛮荒时代（2014 之前）&lt;/h2&gt;&#xA;&lt;p&gt;在微服务概念刚刚兴起的时候，服务治理几乎等于「手写一切」：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;服务 A 调用服务 B：&#xA;&#xA;1. 自己实现服务发现（查 ZooKeeper / Nginx upstream）&#xA;2. 自己实现负载均衡（轮询 / 随机）&#xA;3. 自己实现重试（try-catch + 循环）&#xA;4. 自己实现超时（设置 HTTP timeout）&#xA;5. 自己实现熔断（状态机 + 计数器）&#xA;&#xA;每一个服务的开发者都要重复实现这些逻辑，而且不同团队的实现质量参差不齐&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个阶段的核心问题是：&lt;strong&gt;治理逻辑和业务逻辑耦合在应用代码中&lt;/strong&gt;。每一次修改治理策略（比如调整超时时间），都需要修改业务代码、重新编译、重新部署。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第二阶段sdk-时代2014-2017&#34;&gt;第二阶段：SDK 时代（2014-2017）&lt;/h2&gt;&#xA;&lt;p&gt;Netflix 开源了一整套微服务治理工具（Netflix OSS），标志着微服务治理进入 SDK 时代：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Netflix OSS 全家桶：&#xA;&#xA;Eureka    → 服务注册与发现&#xA;Ribbon    → 客户端负载均衡&#xA;Hystrix   → 熔断器&#xA;Feign     → 声明式 HTTP 客户端&#xA;Zuul      → API 网关&#xA;Archaius  → 动态配置&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Spring Cloud 在此基础上做了封装，让 Java 开发者可以用注解的方式快速接入：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@FeignClient&lt;/span&gt;(name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user-service&amp;#34;&lt;/span&gt;, fallback &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; UserServiceFallback.&lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;UserServiceClient&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@GetMapping&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/users/{id}&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    User &lt;span style=&#34;color:#a6e22e&#34;&gt;getUser&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;@PathVariable&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;) Long id);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@Component&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;UserServiceFallback&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;implements&lt;/span&gt; UserServiceClient {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; User &lt;span style=&#34;color:#a6e22e&#34;&gt;getUser&lt;/span&gt;(Long id) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; User.&lt;span style=&#34;color:#a6e22e&#34;&gt;defaultUser&lt;/span&gt;();  &lt;span style=&#34;color:#75715e&#34;&gt;// 熔断降级&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;sdk-模式的问题&#34;&gt;SDK 模式的问题&lt;/h3&gt;&#xA;&lt;p&gt;Netflix OSS 解决了「重复造轮子」的问题，但它引入了新的痛点：&lt;/p&gt;</description>
    </item>
    <item>
      <title>架构师的系统论：用复杂性科学重构团队认知</title>
      <link>https://blog-architectview.pages.dev/posts/system-thinking-for-architects/</link>
      <pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/system-thinking-for-architects/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;做了五年架构师之后，我逐渐意识到一个事实：技术上的挑战往往不是最难的部分。真正困难的是如何让一个团队对「什么是好的架构」达成共识。这篇文章尝试从系统论和复杂性科学的角度，重新审视架构师的工作方式。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;架构师不是高级程序员&#34;&gt;架构师不是高级程序员&lt;/h2&gt;&#xA;&lt;p&gt;很多公司在晋升到「架构师」这个职级时，默认的评判标准还是技术深度：你对某个领域的源码理解有多深？你能不能设计出高并发的系统？你熟不熟悉各种中间件？&lt;/p&gt;&#xA;&lt;p&gt;这些能力当然重要，但它们描述的是「高级工程师」，不是「架构师」。&lt;/p&gt;&#xA;&lt;p&gt;一个高级工程师解决的问题是：&lt;strong&gt;怎么把这个功能做好？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;一个架构师解决的问题是：&lt;strong&gt;这个系统应该长什么样？为什么？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;两者的区别在于：工程师在约束内寻找最优解，架构师定义约束本身。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;工程师思维：&#xA;  &amp;#34;我们需要一个消息队列来解耦。Kafka 和 RocketMQ 哪个更好？&amp;#34;&#xA;  → 在已知选项中选择最优解&#xA;&#xA;架构师思维：&#xA;  &amp;#34;我们真的需要消息队列吗？如果用事件溯源，是否可以从根本上消除对 MQ 的依赖？&amp;#34;&#xA;  → 重新定义问题和约束&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;系统是一个复杂自适应系统cas&#34;&gt;系统是一个复杂自适应系统（CAS）&lt;/h2&gt;&#xA;&lt;p&gt;复杂自适应系统（Complex Adaptive System, CAS）是圣塔菲研究所的核心研究对象。一个软件系统——包括它的代码、基础设施、开发团队、用户——本质上就是一个 CAS。&lt;/p&gt;&#xA;&lt;p&gt;CAS 的四个核心特征：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1. 由大量自主主体组成&#xA;   主体：微服务、开发者、团队、用户&#xA;   每个主体有自己的目标和行为规则&#xA;&#xA;2. 主体之间相互作用&#xA;   服务之间的 API 调用&#xA;   团队之间的沟通协调&#xA;   用户与系统的交互&#xA;&#xA;3. 涌现（Emergence）&#xA;   宏观行为无法从微观行为简单推导&#xA;   例：每个服务都是高可用的，但整个系统却可能因为级联故障而宕机&#xA;&#xA;4. 自适应（Adaptation）&#xA;   系统会根据环境变化调整自身行为&#xA;   例：自动扩缩容、熔断降级、团队根据事故复盘调整流程&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;理解了 CAS 的特性，就会明白为什么架构设计不能是「自上而下的完全规划」：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;涌现不可预测&lt;/strong&gt;：你无法预知所有微服务组合在一起后会产生什么样的宏观行为。这就是为什么混沌工程（Chaos Engineering）如此重要——你需要在生产环境中主动注入故障，观察系统的涌现行为。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;过度控制会扼杀适应性&lt;/strong&gt;：如果你把每一个服务的实现细节都规定死了，团队就失去了根据实际情况做调整的能力。好的架构应该定义边界和接口，而不是规定实现。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;康威定律的工程解读&#34;&gt;康威定律的工程解读&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;康威定律：&#xA;&amp;#34;设计系统的组织，其产生的设计等同于组织之内、组织之间的沟通结构。&amp;#34;&#xA;&#xA;—— Melvin Conway, 1967&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这不是一句口号，而是一个被反复验证的工程事实。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;反例 1：单体团队做微服务&#xA;&#xA;组织架构：一个 50 人的大团队，所有人向同一个 leader 汇报&#xA;技术架构：虽然拆分了 20 个微服务，但因为沟通无障碍，服务之间的耦合越来越多&#xA;结果：分布式单体（Distributed Monolith）——有微服务的所有缺点，没有微服务的任何优点&#xA;&#xA;反例 2：跨团队共享数据库&#xA;&#xA;组织架构：三个独立的业务团队&#xA;技术架构：三个团队共用同一个数据库&#xA;结果：任何一个团队的 Schema 变更都会影响其他团队，沟通成本随团队数量指数增长&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;正确的做法是让组织架构和技术架构对齐：&lt;/p&gt;</description>
    </item>
    <item>
      <title>技术债务的拓扑学：如何量化和治理系统熵增</title>
      <link>https://blog-architectview.pages.dev/posts/tech-debt-topology-and-governance/</link>
      <pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/tech-debt-topology-and-governance/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;Ward Cunningham 在 1992 年提出「技术债务」这个概念时，他可能没想到三十年后这个词会成为每一个技术团队的噩梦。技术债务不像金融债务那样可以精确计算，它更像是一种熵——在看不见的地方悄悄增长，直到系统变得不可维护。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;技术债务不是一种债&#34;&gt;技术债务不是一种债&lt;/h2&gt;&#xA;&lt;p&gt;很多人把技术债务理解为「欠下的代码质量」，觉得只要花时间重构就能还清。这个理解有一个根本性的错误：&lt;strong&gt;技术债务不是贷款，而是复利。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;金融债务：&#xA;  借 100 万，年利率 5%，每年还 5 万利息&#xA;  债务总额是确定的，还款计划是可预测的&#xA;&#xA;技术债务：&#xA;  写了一段快速但丑陋的代码来赶 deadline&#xA;  第一个月：需要在这段代码旁边加个功能 → 多花了 2 小时&#xA;  第三个月：新人入职看不懂这段代码 → 多花了 2 天&#xA;  第六个月：这段代码的 Bug 引发了线上事故 → 多花了 1 周&#xA;  第十二个月：这段代码和其他模块的耦合太深，无法重构 → 被迫放弃&#xA;&#xA;技术债务的利息不是线性的，而是指数增长的&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这就是为什么技术债务不能「等有空了再还」——因为等你有空的时候，利息可能已经超过了本金。&lt;/p&gt;&#xA;&lt;h2 id=&#34;技术债务的四种类型&#34;&gt;技术债务的四种类型&lt;/h2&gt;&#xA;&lt;p&gt;Martin Fowler 在《Refactoring》中把技术债务分为四个象限：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;                    鲁莽的                审慎的&#xA;              ┌──────────────────┬──────────────────┐&#xA;    故意的     │ &amp;#34;我们不需要测试&amp;#34;  │ &amp;#34;我们知道这里耦合   │&#xA;              │ &amp;#34;先 copy paste  │  太紧，但现在重构   │&#xA;              │  以后再重构&amp;#34;     │  会延误发布，下个月  │&#xA;              │                 │  专门处理&amp;#34;         │&#xA;              ├──────────────────┼──────────────────┤&#xA;    无意的     │ &amp;#34;什么是分层？&amp;#34;    │ &amp;#34;我们现在才理解    │&#xA;              │ &amp;#34;把 SQL 写在     │  应该怎么做&amp;#34;       │&#xA;              │  Controller 里&amp;#34;  │（随着认知深入发现   │&#xA;              │                 │  之前的设计有问题）  │&#xA;              └──────────────────┴──────────────────┘&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;鲁莽且故意的债务&lt;/strong&gt;最危险——团队明知故犯，而且不考虑后果。&lt;/p&gt;</description>
    </item>
    <item>
      <title>RAR/ZIP 压缩包密码忘了怎么办？2026 年完整恢复指南</title>
      <link>https://blog-architectview.pages.dev/posts/rar-zip-password-recovery-guide/</link>
      <pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/rar-zip-password-recovery-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;作为技术人员，你一定经历过这样的噩梦：几个月前加密的压缩包，密码死活想不起来了。里面可能是重要的项目资料、珍贵的照片备份、或者是离职前交接给你的技术文档。别慌，这篇文章系统梳理了当前主流的压缩包密码恢复方案。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;压缩包加密的基本原理&#34;&gt;压缩包加密的基本原理&lt;/h2&gt;&#xA;&lt;p&gt;在讨论恢复方案之前，先理解压缩包是怎么加密的。这决定了哪些恢复方案可行，哪些不可行。&lt;/p&gt;&#xA;&lt;h3 id=&#34;zip-加密&#34;&gt;ZIP 加密&lt;/h3&gt;&#xA;&lt;p&gt;ZIP 格式支持两种加密方式：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;传统 ZIP 加密（ZipCrypto）：&#xA;  - 基于流密码的简单加密&#xA;  - 安全性较低，存在已知的明文攻击漏洞&#xA;  - 如果压缩包内有你知道内容的文件，可以通过已知明文攻击快速破解&#xA;  - 恢复难度：★★☆☆☆&#xA;&#xA;AES-256 加密（WinZip AES）：&#xA;  - 基于 AES-256-CBC 的现代加密&#xA;  - 目前没有已知的密码学漏洞&#xA;  - 只能通过暴力枚举或字典攻击恢复&#xA;  - 恢复难度：★★★★☆&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;rar-加密&#34;&gt;RAR 加密&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;RAR3 加密：&#xA;  - AES-128-CBC&#xA;  - 密钥派生使用 PBKDF2，但迭代次数较低&#xA;  - 恢复速度：中等&#xA;&#xA;RAR5 加密：&#xA;  - AES-256-CBC&#xA;  - 密钥派生使用 PBKDF2-HMAC-SHA256，迭代次数可配置&#xA;  - 抗暴力破解能力显著增强&#xA;  - 恢复速度：较慢&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;关键认知：&lt;strong&gt;现代加密算法（AES-256）本身是无法被「破解」的。&lt;/strong&gt; 所有恢复方案本质上都是在尝试猜测密码——通过字典攻击、暴力枚举、规则变异等方式，逐一尝试可能的密码组合。&lt;/p&gt;&#xA;&lt;h2 id=&#34;方案一回忆与推理零成本优先尝试&#34;&gt;方案一：回忆与推理（零成本，优先尝试）&lt;/h2&gt;&#xA;&lt;p&gt;在动用任何工具之前，先花 10 分钟做密码推理。很多人忽略了这一步，直接上工具，浪费了大量时间。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;密码回忆清单：&#xA;&#xA;1. 检查你的密码管理器&#xA;   - 1Password / Bitwarden / KeePass 中是否保存过？&#xA;   - 浏览器密码管理器中是否有记录？&#xA;&#xA;2. 常见密码模式&#xA;   - 你的常用密码 + 数字后缀（如 MyPass2024）&#xA;   - 项目名称 + 特殊字符（如 Project@Arch）&#xA;   - 日期组合（如 20240101、199506）&#xA;   - 手机号、身份证号的部分数字&#xA;&#xA;3. 查看历史记录&#xA;   - 邮件中是否有发送过这个压缩包？附件里可能有密码&#xA;   - 聊天记录（微信/钉钉/Slack）中是否提到过密码？&#xA;   - 笔记软件（Notion/Obsidian/备忘录）中是否有记录？&#xA;&#xA;4. 询问相关人&#xA;   - 谁给你的这个压缩包？&#xA;   - 当时是在什么场景下加密的？&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;方案二本地恢复工具&#34;&gt;方案二：本地恢复工具&lt;/h2&gt;&#xA;&lt;p&gt;如果回忆无果，可以使用本地工具进行密码恢复。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Word/Excel 文档加密密码恢复：从原理到实战</title>
      <link>https://blog-architectview.pages.dev/posts/word-excel-password-recovery-guide/</link>
      <pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/word-excel-password-recovery-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;前两天帮一位做财务的朋友恢复了一个加密的 Excel 文件密码——那里面存着三年的税务数据，密码忘了但文件又不能丢。Office 文档的加密机制和压缩包完全不同，恢复策略也有很大差异。这篇文章把 Office 文档密码恢复的技术原理和实战方案完整梳理一遍。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;office-文档的加密演进&#34;&gt;Office 文档的加密演进&lt;/h2&gt;&#xA;&lt;p&gt;Office 文档的加密方案随着版本迭代发生了很大变化。了解加密版本是选择恢复方案的前提。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Office 97-2003（.doc / .xls / .ppt）：&#xA;  加密方式：RC4（40-bit 密钥）&#xA;  安全性：极弱&#xA;  恢复难度：★☆☆☆☆&#xA;  说明：40-bit 密钥空间只有 2^40 ≈ 1 万亿种组合，现代 GPU 几小时即可穷举&#xA;&#xA;Office 2007（.docx / .xlsx / .pptx）：&#xA;  加密方式：AES-128 + SHA-1&#xA;  密钥派生：PBKDF2，迭代 50,000 次&#xA;  安全性：中等&#xA;  恢复难度：★★★☆☆&#xA;  说明：迭代次数显著增加了暴力破解的难度&#xA;&#xA;Office 2010：&#xA;  加密方式：AES-128 + SHA-1&#xA;  密钥派生：PBKDF2，迭代 100,000 次&#xA;  安全性：中等偏上&#xA;  恢复难度：★★★☆☆&#xA;&#xA;Office 2013-2021 / Microsoft 365：&#xA;  加密方式：AES-256 + SHA-512&#xA;  密钥派生：PBKDF2，迭代 100,000 次（可配置到 1,000,000）&#xA;  安全性：强&#xA;  恢复难度：★★★★☆&#xA;  说明：AES-256 + 高迭代次数，对暴力破解有很强的抵抗力&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;查看你的文档使用的加密版本&#34;&gt;查看你的文档使用的加密版本&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 使用 msoffcrypto-tool 查看加密信息&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; msoffcrypto&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;with&lt;/span&gt; open(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;encrypted.xlsx&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; f:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    file &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; msoffcrypto&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;OfficeFile(f)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;加密类型: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;file&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;file_type&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;密钥大小: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;file&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;keyTypes&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# 或者使用命令行：&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# msoffcrypto-tool -t encrypted.xlsx&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;office-的两种加密别搞混了&#34;&gt;Office 的两种「加密」：别搞混了&lt;/h2&gt;&#xA;&lt;p&gt;很多用户混淆了 Office 的两种保护机制：&lt;/p&gt;</description>
    </item>
    <item>
      <title>PDF 文件密码忘记了？加密 PDF 恢复方案全面对比</title>
      <link>https://blog-architectview.pages.dev/posts/pdf-password-recovery-comparison/</link>
      <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/pdf-password-recovery-comparison/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;PDF 加密比其他文件格式更「诡异」——它有用户密码和所有者密码两套机制，安全性差异巨大。上周遇到一个案例：一份加密的 PDF 合同，打不开也打印不了，折腾了一下午终于搞定了。这篇文章把 PDF 密码恢复的技术细节彻底讲清楚。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;pdf-加密的两种密码&#34;&gt;PDF 加密的两种密码&lt;/h2&gt;&#xA;&lt;p&gt;PDF 的加密机制和其他文件格式最大的不同在于：它有&lt;strong&gt;两种独立的密码&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;用户密码（User Password / Open Password）：&#xA;  作用：打开文件时必须输入&#xA;  效果：文件内容被加密，没有密码无法查看&#xA;  恢复难度：取决于加密算法版本&#xA;  这是真正意义上的「加密」&#xA;&#xA;所有者密码（Owner Password / Permissions Password）：&#xA;  作用：限制打印、复制、编辑等操作&#xA;  效果：文件可以打开查看，但不能执行受限操作&#xA;  恢复难度：★☆☆☆☆（几乎可以秒解）&#xA;  这不是真正的加密，只是一个「限制标记」&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;如何判断你的-pdf-是哪种密码&#34;&gt;如何判断你的 PDF 是哪种密码？&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;场景 1：打开 PDF 时弹出密码输入框&#xA;  → 用户密码（需要正经恢复）&#xA;&#xA;场景 2：可以打开查看，但打印按钮灰色/复制文字失败&#xA;  → 所有者密码（可以轻松移除）&#xA;&#xA;场景 3：既需要密码打开，又有操作限制&#xA;  → 两种密码都设置了（先恢复用户密码，再移除所有者密码）&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;所有者密码秒解方案&#34;&gt;所有者密码：秒解方案&lt;/h2&gt;&#xA;&lt;p&gt;所有者密码不加密文件内容，只是在 PDF 元数据中设置了一个权限标记。有密码可以修改权限，没密码也可以直接移除。&lt;/p&gt;&#xA;&lt;h3 id=&#34;方法-1ghostscript命令行免费&#34;&gt;方法 1：Ghostscript（命令行，免费）&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 安装 Ghostscript&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# macOS: brew install ghostscript&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Ubuntu: sudo apt install ghostscript&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 移除所有者密码（重新生成 PDF）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;gs -q -dNOPAUSE -dBATCH &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;   -sDEVICE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;pdfwrite &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;   -dCompatibilityLevel&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1.4 &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;   -sOutputFile&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;unlocked.pdf &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;   encrypted.pdf&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 原理：Ghostscript 读取 PDF 内容后重新生成一个新的 PDF&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 新 PDF 不包含任何权限限制&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;方法-2qpdf命令行免费&#34;&gt;方法 2：qpdf（命令行，免费）&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 安装 qpdf&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# macOS: brew install qpdf&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Ubuntu: sudo apt install qpdf&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 移除所有加密&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;qpdf --decrypt encrypted.pdf unlocked.pdf&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 如果同时有用户密码，需要提供密码&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;qpdf --password&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;yourpassword --decrypt encrypted.pdf unlocked.pdf&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;方法-3在线工具&#34;&gt;方法 3：在线工具&lt;/h3&gt;&#xA;&lt;p&gt;各种在线 PDF 工具（如 ilovepdf.com、smallpdf.com）都可以一键移除所有者密码限制。原理和 Ghostscript 一样——读取内容后重新生成。&lt;/p&gt;</description>
    </item>
    <item>
      <title>BitLocker 加密磁盘密码恢复：方案、工具与注意事项</title>
      <link>https://blog-architectview.pages.dev/posts/bitlocker-password-recovery-guide/</link>
      <pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/bitlocker-password-recovery-guide/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;BitLocker 是 Windows 自带的全盘加密功能，很多企业在部署笔记本时会默认开启。它的安全性远高于文件级加密——一旦密码丢失，整个磁盘的数据都不可访问。这篇文章详细梳理了 BitLocker 密码丢失后的所有恢复路径。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;bitlocker-的工作原理&#34;&gt;BitLocker 的工作原理&lt;/h2&gt;&#xA;&lt;p&gt;在讨论恢复方案之前，有必要先理解 BitLocker 的加密架构。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BitLocker 加密层次：&#xA;&#xA;┌─────────────────────────────────────┐&#xA;│ 全卷加密密钥（FVK / Full Volume Key）│ ← 真正加密磁盘数据的密钥&#xA;├─────────────────────────────────────┤&#xA;│ 保护密钥（保护 FVK 的多种机制）       │&#xA;│  ├─ TPM 芯片（硬件级密钥存储）       │&#xA;│  ├─ USB 启动密钥                    │&#xA;│  ├─ 恢复密钥（48 位数字）            │&#xA;│  └─ 用户密码 / PIN                  │&#xA;├─────────────────────────────────────┤&#xA;│ AES-128 或 AES-256 全盘加密          │ ← 加密整个系统分区&#xA;└─────────────────────────────────────┘&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;关键理解：&lt;strong&gt;BitLocker 的真正密钥是 FVK（Full Volume Key）&lt;/strong&gt;。用户密码、TPM、PIN 码等都是「保护密钥的方式」，它们的作用是保护 FVK 不被未授权访问。&lt;/p&gt;&#xA;&lt;p&gt;这意味着 BitLocker 的恢复有两种思路：&lt;/p&gt;</description>
    </item>
    <item>
      <title>WiFi 密码忘了怎么办？WPA2/WPA3 握手包恢复实战教程</title>
      <link>https://blog-architectview.pages.dev/posts/wifi-wpa2-wpa3-password-recovery/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/wifi-wpa2-wpa3-password-recovery/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;家里换了路由器之后忘了 WiFi 密码，或者公司前任网管离职了没交接 WiFi 密码——这些场景比想象中更常见。这篇文章从技术角度讲解 WiFi 密码的加密原理和恢复方案，同时也会谈谈 WPA3 带来的安全改进。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;wifi-加密协议演进&#34;&gt;WiFi 加密协议演进&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;WiFi 安全协议时间线：&#xA;&#xA;WEP (1997)      → 已被完全破解，几分钟即可恢复密钥&#xA;WPA (2003)      → TKIP 加密，存在已知漏洞&#xA;WPA2 (2004)     → AES-CCMP，目前主流，安全性较高&#xA;WPA3 (2018)     → SAE 握手，抗离线字典攻击&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;wpa2-的认证机制四次握手&#34;&gt;WPA2 的认证机制：四次握手&lt;/h3&gt;&#xA;&lt;p&gt;WPA2 使用「四次握手」（4-Way Handshake）来验证客户端和路由器是否知道相同的密码：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;WPA2 四次握手流程：&#xA;&#xA;    路由器 (AP)                          客户端 (Client)&#xA;       │                                      │&#xA;       │  ── 1. ANonce (随机数) ──────────→   │&#xA;       │                                      │&#xA;       │  ←── 2. SNonce + MIC ─────────────   │&#xA;       │     (客户端的随机数 + 消息完整性校验)   │&#xA;       │                                      │&#xA;       │  ── 3. GTK + MIC ────────────────→   │&#xA;       │     (组密钥 + 确认)                    │&#xA;       │                                      │&#xA;       │  ←── 4. 确认 ─────────────────────   │&#xA;       │                                      │&#xA;&#xA;关键点：&#xA;  - 密码本身不在网络上传输&#xA;  - 握手过程使用密码派生的 PMK (Pairwise Master Key) 来生成加密密钥&#xA;  - PMK = PBKDF2(密码, SSID, 4096, 256)&#xA;  - 攻击者可以捕获握手包，然后离线尝试猜测密码&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;为什么-wpa2-可以被离线恢复&#34;&gt;为什么 WPA2 可以被离线恢复？&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;WPA2 的安全模型：&#xA;&#xA;PMK = PBKDF2(HMAC-SHA1, 密码, SSID, 4096, 256位)&#xA;       ↑                    ↑      ↑&#xA;       密码学哈希函数        WiFi名  迭代次数&#xA;&#xA;PMK 是固定的（同一个密码 + 同一个 SSID = 同一个 PMK）&#xA;四次握手中的 Nonce 是随机的&#xA;&#xA;攻击者的思路：&#xA;  1. 捕获一次完整的四次握手包&#xA;  2. 离线计算：对每个候选密码，计算 PMK，然后验证是否能生成正确的 MIC&#xA;  3. 如果 MIC 匹配 → 密码正确&#xA;&#xA;这就是为什么只需要捕获一次握手包，就可以无限次地离线尝试密码&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;第一步捕获握手包&#34;&gt;第一步：捕获握手包&lt;/h2&gt;&#xA;&lt;p&gt;要恢复 WiFi 密码，首先需要捕获一次完整的四次握手。&lt;/p&gt;</description>
    </item>
    <item>
      <title>云算力 vs 本地破解：2026 年加密文件恢复方案选型指南</title>
      <link>https://blog-architectview.pages.dev/posts/cloud-vs-local-password-recovery/</link>
      <pubDate>Sat, 09 May 2026 00:00:00 +0000</pubDate>
      <guid>https://blog-architectview.pages.dev/posts/cloud-vs-local-password-recovery/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;作为一名架构师，我习惯用系统思维来分析问题——即使这个「问题」是忘了自己加密文件的密码。加密文件密码恢复本质上是一个算力密集型任务，而算力的获取方式无非两种：本地和云端。这篇文章从架构角度对比两种方案的优劣，帮你做出理性的选择。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;密码恢复的算力需求模型&#34;&gt;密码恢复的算力需求模型&lt;/h2&gt;&#xA;&lt;p&gt;先建立一个定量的认知框架。不同的加密格式，每次密码尝试的计算成本差异巨大：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;各格式单次密码尝试的计算成本（从低到高）：&#xA;&#xA;WPA2 握手包:     PBKDF2-SHA1, 4096 迭代     → 约 1,600 FLOPs/次&#xA;ZIP (ZipCrypto): RC4-40                       → 约 500 FLOPs/次&#xA;RAR3:            AES-128 + SHA1               → 约 5,000 FLOPs/次&#xA;Office 2007:     AES-128 + SHA1, 50K 迭代     → 约 20,000 FLOPs/次&#xA;RAR5:            AES-256 + SHA256, 可配置迭代  → 约 50,000 FLOPs/次&#xA;Office 2013+:    AES-256 + SHA512, 100K 迭代  → 约 100,000 FLOPs/次&#xA;BitLocker:       AES-256 + SHA256, 高迭代     → 约 100,000 FLOPs/次&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这意味着同一个 GPU，恢复 WPA2 密码的速度是恢复 Office 2013+ 密码的 &lt;strong&gt;60 倍以上&lt;/strong&gt;。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
