2026年2月

想象一下,你正在开发一个大型Web应用。营销团队想要用Astro构建他们的页面以获得最佳的SEO效果,而产品团队却坚持要用React来构建功能丰富的后台管理系统。更糟糕的是,每次发布新版本时,十几个团队的代码都需要一起打包、一起测试、一起上线——只要其中一个团队引入了一个bug,整个发布就要回滚。这种"一荣俱荣、一损俱损"的耦合方式,是不是让你感到无比头疼?

或者,你的公司刚刚收购了一个创业公司,他们的产品是用Vue写的,而你们的主站是用React写的。你想把他们的功能整合进来,但又不希望把两个完全不同的代码库强行混在一起。

这些都是现代Web开发中真实存在的难题。传统的微前端架构通常是"水平"的——同一个页面上的不同组件来自不同的服务。但如果有一种方式,能让每个团队完全独立地开发、部署和维护自己的功能模块,而用户却感觉在使用一个无缝的、统一的应用呢?

这就是垂直微前端(Vertical Microfrontends)要解决的问题。现在,Cloudflare推出了一款全新的Worker模板,让这种架构变得前所未有的简单。

什么是垂直微前端?

垂直微前端是一种架构模式,单个独立团队拥有应用程序功能的完整切片,从用户界面一直到底层的CI/CD流水线。这些切片通过域名上的路径来定义,你可以将各个独立的Worker与特定路径关联起来:

/      = 营销网站
/docs  = 文档
/blog  = 博客
/dash  = 仪表盘

我们还可以进一步细化,在更细粒度的子路径上关联不同的Worker。比如在仪表盘中,你可能通过各种功能或产品来划分URL路径的深度(例如 /dash/product-a),在两个产品之间导航可能意味着两个完全不同的代码库。

现在有了垂直微前端,我们还可以这样设计:

/dash/product-a  = WorkerA
/dash/product-b  = WorkerB

上面的每个路径都是独立的前端项目,它们之间没有任何共享代码。product-aproduct-b 路由映射到分别部署的前端应用,它们有自己的框架、库、CI/CD流水线,由各自的团队定义和拥有。

你可以端到端地拥有自己的代码。但现在我们需要找到一种方法将这些独立的项目缝合在一起,更重要的是,让它们感觉像是一个统一的体验。

Cloudflare自己也在经历这个痛点,因为仪表盘有许多独立的团队负责各自的产品。团队必须面对一个事实:在他们控制范围之外所做的更改会影响用户对其产品的体验。

在内部,我们现在对自己的仪表盘也采用了类似的策略。当用户从核心仪表盘导航到我们的ZeroTrust产品时,实际上它们是两个完全独立的项目,用户只是通过路径 /:accountId/one 被路由到那个项目。

视觉上的统一体验

将这些独立项目缝合在一起,让它们感觉像一个统一的体验,并没有你想象的那么困难:只需要几行CSS魔法。我们绝对不希望发生的事情是将我们的实现细节和内部决策泄露给用户。如果我们无法让这个用户体验感觉像一个统一的前端,那我们就对用户犯下了严重的错误。

要实现这种巧妙的手法,让我们先了解一下视图过渡和文档预加载是如何发挥作用的。

视图过渡

当我们想要在两个不同页面之间无缝导航,同时让最终用户感觉流畅时,视图过渡非常有用。在页面上定义特定的DOM元素,让它们一直保留到下一页可见,并定义任何变化的处理方式,这成为了多页应用的强大缝合工具。

然而,在某些情况下,让各个垂直微前端感觉不同也是完全可以接受的。比如我们的营销网站、文档和仪表盘,它们各自都有独特的定义。用户不会期望这三者在导航时都感觉统一。但是……如果你决定在单个体验中引入垂直切片(例如 /dash/product-a/dash/product-b),那么用户绝对不应该知道它们底层是两个不同的仓库/Worker/项目。

好了,说得够多了——让我们开始动手吧。我说过让两个独立的项目对用户来说感觉像是一个是低成本的,如果你还没有听说过CSS视图过渡,那么接下来我要让你大开眼界了。

如果我告诉你,你可以在单页应用(SPA)或多页应用(MPA)的不同视图之间创建动画过渡,让它们感觉像是一个整体?在添加任何视图过渡之前,如果我们导航属于两个不同Worker的页面,中间加载状态会是浏览器中的白色空白屏幕,持续几百毫秒,直到下一页开始渲染。页面不会感觉统一,当然也不会像单页应用。

如果希望元素保留,而不是看到白色空白页,我们可以通过定义CSS视图过渡来实现。通过下面的代码,我们告诉当前文档页面,当视图过渡事件即将发生时,将nav DOM元素保留在屏幕上,如果现有页面和目标页面之间存在任何外观差异,我们将使用ease-in-out过渡来动画展示。

突然之间,两个不同的Worker感觉就像一个了。

@supports (view-transition-name: none) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.3s;
    animation-timing-function: ease-in-out;
  }
  nav { view-transition-name: navigation; }
}

预加载

在两个页面之间过渡让它"看起来"无缝——我们还希望它"感觉"像客户端SPA一样即时。虽然目前Firefox和Safari不支持Speculation Rules,但Chrome/Edge/Opera确实支持这个较新的API。Speculation Rules API旨在提高未来导航的性能,特别是对于文档URL,让多页应用感觉更像单页应用。

分解成代码,我们需要定义一个特定格式的脚本规则,告诉支持的浏览器如何预取与我们Web应用程序连接的其他垂直切片——可能通过某些共享导航链接。

<script type="speculationrules">
  {
    "prefetch": [
      {
        "urls": ["https://product-a.com", "https://product-b.com"],
        "requires": ["anonymous-client-ip-when-cross-origin"],
        "referrer_policy": "no-referrer"
      }
    ]
  }
</script>

有了这些,我们的应用程序会预取其他微前端并将它们保留在内存缓存中,所以如果我们导航到那些页面,会感觉几乎是即时的。

对于明显可区分的垂直切片(营销、文档、仪表盘),你可能不需要这样做,因为用户在它们之间导航时会预期有轻微的加载。然而,当垂直切片定义在特定可见体验内时(例如在仪表盘页面中),强烈建议使用。

通过视图过渡和推测规则,我们能够将完全不同的代码仓库联系在一起,感觉就像它们来自单页应用一样。如果你问我,这太神奇了。

零配置请求路由

现在我们需要一种机制来托管多个应用程序,以及一种在请求流入时将它们缝合在一起的方法。定义一个Cloudflare Worker作为"路由器",允许在边缘的单个逻辑点处理网络请求,然后将它们转发给负责该URL路径的垂直微前端。而且我们可以将单个域名映射到该路由器Worker,其余的就"正常工作"了。

服务绑定

如果你还没有探索过Cloudflare Worker服务绑定,那么值得花点时间了解一下。

服务绑定允许一个Worker调用另一个Worker,而无需经过公开可访问的URL。服务绑定允许Worker A调用Worker B上的方法,或将请求从Worker A转发到Worker。进一步分解,路由器Worker可以调用已定义的每个垂直微前端Worker(例如营销、文档、仪表盘),假设它们都是Cloudflare Workers。

这为什么重要?这正是将这些垂直切片"缝合"在一起的机制。我们将在下一节深入探讨请求路由如何处理流量分割。但要定义这些微前端中的每一个,我们需要更新路由器Worker的wrangler定义,这样它就知道允许调用哪些前端。

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "router",
  "main": "./src/router.js",
  "services": [
    {
      "binding": "HOME",
      "service": "worker_marketing"
    },
    {
      "binding": "DOCS",
      "service": "worker_docs"
    },
    {
      "binding": "DASH",
      "service": "worker_dash"
    }
  ]
}

上面的示例定义在我们的路由器Worker中,然后告诉我们被允许向三个独立的额外Worker(营销、文档和仪表盘)发出请求。授予权限就这么简单,但让我们深入研究一些更复杂的逻辑,包括请求路由和HTML重写网络响应。

请求路由

了解了在需要时可以调用的各种其他Worker之后,现在我们需要一些逻辑来确定何时将网络请求定向到哪里。由于路由器Worker被分配到我们的自定义域名,所有传入的请求首先在网络边缘到达它。然后它确定哪个Worker应该处理请求,并管理结果响应。

第一步是将URL路径映射到关联的Worker。当收到某个请求URL时,我们需要知道它需要被转发到哪里。我们通过定义规则来实现这一点。虽然我们支持通配符路由、动态路径和参数约束,但我们将专注于基础——字面路径前缀——因为它更清楚地说明了要点。

在这个例子中,我们有三个微前端:

/      = 营销
/docs  = 文档
/dash  = 仪表盘

上面的每个路径都需要映射到一个实际的Worker(参见上面章节中的wrangler服务定义)。对于我们的路由器Worker,我们定义一个额外的变量,包含以下数据,这样我们就知道哪些路径应该映射到哪些服务绑定。现在我们知道当请求进来时应该将用户路由到哪里!定义一个名为ROUTES的wrangler变量,内容如下:

{
  "routes": [
    {"binding": "HOME", "path": "/"},
    {"binding": "DOCS", "path": "/docs"},
    {"binding": "DASH", "path": "/dash"}
  ]
}

让我们设想一个用户访问我们网站的路径 /docs/installation。在底层,发生的情况是请求首先到达我们的路由器Worker,它负责了解什么URL路径映射到哪个独立的Worker。它理解 /docs 路径前缀映射到我们的 DOCS 服务绑定,参照我们的wrangler文件指向我们的 worker_docs 项目。我们的路由器Worker知道 /docs 被定义为垂直微前端路由,从路径中移除 /docs 前缀,将请求转发给我们的 worker_docs Worker来处理请求,然后最终返回我们得到的任何响应。

为什么要删除 /docs 路径呢?这是一个实现细节的选择,目的是当Worker通过路由器Worker访问时,它可以清理URL来处理请求,就像它是从路由器Worker外部调用的一样。像任何Cloudflare Worker一样,我们的 worker_docs 服务可能有自己的独立URL可以访问。我们决定希望该服务URL继续独立工作。当它附加到我们的新路由器Worker时,它会自动处理移除前缀,这样服务就可以从自己定义的URL或通过我们的路由器Worker访问……任何地方都可以,无所谓。

HTMLRewriter

用URL路径分割我们的各种前端服务(例如 /docs/dash)让我们很容易转发请求,但当我们的响应包含不知道它被通过路径组件反向代理的HTML时……嗯,这就会出问题。

假设我们的文档网站在响应中有一个图片标签 <img src="./logo.png" />。如果我们的用户正在访问页面 https://website.com/docs/,那么加载 logo.png 文件可能会失败,因为我们的 /docs 路径只是由我们的路由器Worker人为定义的。

只有当我们的服务通过路由器Worker访问时,我们才需要对一些绝对路径进行HTML重写,这样我们返回的浏览器响应才能引用有效的资源。实际上发生的是,当请求通过我们的路由器Worker时,我们将请求传递给正确的服务绑定,并从中接收响应。在将其传回客户端之前,我们有机会重写DOM——所以在看到绝对路径的地方,我们继续用代理路径预先填充它。以前我们的HTML返回的图片标签是 <img src="./logo.png" />,现在我们修改为在返回客户端浏览器之前 <img src="./docs/logo.png" />

让我们回到CSS视图过渡和文档预加载的魔法。我们当然可以把那段代码手动放到我们的项目中并让它工作,但这个路由器Worker也会使用HTMLRewriter自动为我们处理这些逻辑。

在你的路由器Worker ROUTES 变量中,如果你在根级别设置 smoothTransitionstrue,那么CSS过渡视图代码会自动添加。此外,如果你在路由中设置 preload 键为 true,那么该路由的推测规则脚本代码也会自动添加。

下面是两者结合使用的示例:

{
  "smoothTransitions": true,
  "routes": [
    {"binding": "APP1", "path": "/app1", "preload": true},
    {"binding": "APP2", "path": "/app2", "preload": true}
  ]
}

开始使用

你今天就可以开始使用垂直微前端模板构建了。

访问Cloudflare仪表盘的链接,或者进入"Workers & Pages"并点击"创建应用程序"按钮开始。从那里,点击"选择模板"然后"创建微前端",你就可以开始配置你的设置了。

更多使用指南,可以点击查看文档 ,如果您对各种云原生架构的内容感兴趣,也可以关注我的博客:程序猿DD,第一时间获得干货更新。

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。

在线运行 TVM 学习教程

链接是:https://hyper.ai/notebooks/48919?utm_source=Distribute&utm_me...

本文档面向希望了解 TVM 框架如何与特定设备 API 进行交互的开发者,或希望为新的 API 或新硬件添加支持的开发者。

对于任何新的运行时环境,需要实现三个主要部分:

  • DeviceAPI <tvm-target-specific-device-api>{.interpreted-text role="ref"} 类提供对特定设备的句柄,以及用于与其交互的 API。它定义了一套通用接口,用于查询设备参数(例如:可用内存、线程数量等),以及执行简单操作(例如:从主机复制内存,或在设备缓冲区之间复制数据)。
  • Target <tvm-target-specific-target>{.interpreted-text role="ref"} 类包含将要运行函数的设备描述。它同时暴露给目标代码生成器和优化 Pass。
  • 目标代码生成器 <tvm-target-specific-codegen>{.interpreted-text role="ref"} 从 IRModule 构建一个由一个或多个 PackedFunc <tvm-runtime-system-packed-func>{.interpreted-text role="ref"} 组成的 Module <tvm-runtime-system-module>{.interpreted-text role="ref"}。

DeviceAPI

DeviceAPI(设备 API)表示对特定硬件设备 API 的访问句柄。(例如,CUDADeviceAPI 处理所有通过 CUDA 框架的交互。)大多数 DeviceAPI 方法都接受一个 device_id 参数,用于指定访问哪个设备。

在 Python 中,通常使用 tvm.runtime.device{.interpreted-text role="py:func"} 函数访问特定设备,该函数返回指定 API 所访问设备的句柄。(例如,tvm.runtime.device('cuda', 0) 表示访问通过 CUDA API 访问的物理设备 0。)

  • 属性查询 — GetAttr 用于查询不同的设备特定参数,例如设备名称、线程数量等。可查询的参数定义在 enum DeviceAttrKind,文件位置: device_api.h。 并非所有参数都适用于所有设备。如果某个参数无法查询(例如 Vulkan 上的 kMaxClockRate),或不适用(例如 CPU 上的 kWarpSize),应返回 nullptr
  • 设置活动设备 — SetDevice 应将某个设备设置为当前活动设备。如果目标代码生成器生成的 PackedFunc 需要在设备上执行,该执行应发生在当前活动设备上。
  • 内存管理 — 用于在设备上分配和释放内存的工具函数。
    • 分配数据空间 — AllocDataSpace 和 FreeDataSpace 用于在设备上分配和释放数据存储空间。这些空间可作为算子输入和输出,并构成算子图的主要数据流。必须支持主机与数据空间之间的数据传输。返回值为不透明指针 void*。某些实现返回真实地址,但这不是必须的,该指针也可能是仅可由设备后端解释的句柄。该 void* 将作为参数传递给其他后端函数(例如 CopyDataFromTo)。
    • 分配工作空间 — AllocWorkspace 和 FreeWorkspace 用于分配和释放工作区。这些区域用于算子内部中间值存储,不要求可与主机传输。如果子类未实现,则默认调用对应的数据空间分配函数。
    • 数据复制 — CopyDataFromTo 应在不同位置之间复制数据。复制类型由 dev_from 和 dev_to 决定。实现应该支持将内存从CPU复制到设备,从设备复制到CPU,以及在单个设备上从一个缓冲区复制到另一个缓冲区。如果源或目标位于 CPU,则指针为可直接用于 memcpy 的主机地址;如果位于设备,则指针必定由 AllocDataSpace 或 AllocWorkspace 生成。
      这些复制会排队在某个 TVMStreamHandle 流中执行。但是实现不应假设 CPU 缓冲区在函数返回后仍然有效或可访问。
  • 执行流管理 — 管理 TVMStreamHandle(执行命令的并行流)。
    • 创建流 — CreateStream / FreeStream 负责分配和释放执行流。如果设备只有单一指令队列,则 CreateStream 应返回 nullptr
    • 设置活动流 — SetStream 用于将某个流设置为当前活跃流。目标代码生成器生成的函数执行时应提交到该流。
    • 同步到 CPU — StreamSync 应同步流,使之在执行完成前阻塞返回。
    • 流间同步 — SyncStreamFromTo 应在两个流之间插入同步屏障,使目标流在源流执行完当前排队命令前无法继续执行。

为了使 TVM 能够使用新的 DeviceAPI,需要执行以下注册步骤:

  1. 创建一个实例化 DeviceAPI 并返回其指针的函数:
FooDeviceAPI* FooDeviceAPI::Global() {
  static FooDeviceAPI inst;
  return &inst;
}
  1. 在 TVM 注册表中注册:
TVM_FFI_STATIC_INIT_BLOCK() {
  namespace refl = tvm::ffi::reflection;
  refl::GlobalDef().def("device_api.foo", FooDeviceAPI::Global);
}
  1. 在 base.h 的 TVMDeviceExtType 枚举中为新的 DeviceAPI 添加条目。值需大于 DLDeviceType::kDLExtDev,且小于 DeviceAPIManager::kMaxDeviceAPI
  2. 在 device_api.h 的 DeviceName 中添加对应枚举 → 字符串映射,该字符串需与 GlobalDef().def 中一致。
  3. 在 tvm.runtime.Device的 _DEVICE_TYPE_TO_NAME 与 _DEVICE_NAME_TO_TYPE 字典中添加对应映射。

Target 定义

Target 对象是有关物理设备、其硬件/驱动限制和能力的属性查询表。Target 可在优化阶段和代码生成阶段使用。虽然所有运行时共享相同的 Target 类,但不同运行时可能需要额外的 target 特定属性。

在 target_kind.cc 中使用 TVM_REGISTER_TARGET_KIND 注册新的 target,需传入 target 名称,以及对应运行设备的 TVMDeviceExtType 或 DLDeviceType。通常情况下,target 名称和设备名称一致(如 "cuda" 运行于 kDLCUDA),但也有例外(例如 "llvm" 与 "c" 目标都运行于 kDLCPU)。

所有 target 选项通过 add_attr_option 添加,可带默认值。可以使用 set_target_parser 添加解析器,用于处理依赖其他参数或硬件属性的动态参数。

该参数解析器定义了如何从字符串格式构造 target。这由 Target::Target(const String&) 构造函数执行,该构造函数接受 JSON 格式字符串,通常通过 Python:

tvm.target.Target('{"kind": "cuda", "max_num_threads": 1024}')

在代码生成器中,可通过以下方式访问 target 属性:

  • C++:target->GetAttr<T>(param_name)
  • Python:target.attrs

Target 代码生成器

代码生成器将优化后的 IRModule 转换为可执行表示。每个代码生成器必须注册到 TVM 框架中,其名称为:

"target.build.foo"

其中 foo 与先前 TVM_REGISTER_TARGET_KIND 中的名称一致。

示例:

tvm::runtime::Module GeneratorFooCode(IRModule mod, Target target);
TVM_FFI_STATIC_INIT_BLOCK() {
  namespace refl = tvm::ffi::reflection;
  refl::GlobalDef().def("target.build.foo", GeneratorFooCode);
}

代码生成器有两个参数。第一个是要编译的IRModule,第二个是描述代码应该运行在哪个设备上的目标 Target。由于编译环境不一定与执行环境相同,因此代码生成器不应直接向设备查询属性,而应始终使用 Target 中的属性。

输入 IRModule 中的每个函数都应在输出的 runtime::Module 中可通过名称访问。

📖 前言

最近要学 Java,第一步就是装 JDK。

打开 Oracle 官网一看,下载 JDK 11 需要注册账号,注册页面还要填公司信息。好不容易填完,下载速度几 KB/s,一个 100 多 MB 的文件要下大半天。

后来发现国内有镜像站点,下载速度快多了。今天把完整步骤写下来,帮有需要的同学快速搞定。

这套方法在几台电脑上都试过,十分钟内完成安装。

🔧 前置准备

系统要求:

  • Windows 7/8/10/11(64位)
  • 至少 500MB 空闲硬盘空间

下载 JDK 11:

网盘下载(下载快):https://pan.quark.cn/s/7186f4aa4c10

📝 详细步骤

步骤一:下载 JDK 11

下载地址:

网盘下载(推荐):

网盘下载(下载快):https://pan.quark.cn/s/7186f4aa4c10

官网下载(备选):

或者去 Adoptium 官网

小提示:

  • .msi 安装版安装简单,推荐新手用
  • .zip 免安装版适合多版本共存
  • 下载完成后是类似 OpenJDK11U-jdk_x64_windows_hotspot_11.0.xx_xxx.msi 的文件

步骤二:安装 JDK

双击 .msi 文件:

  1. 点"下一步"
  2. 选安装路径

    • 默认是 C:\Program Files\Eclipse Adoptium\jdk-11.x.xx.x-hotspot\
    • 我一般改成 D:\Java\jdk-11\(好管理,不占 C 盘)

路径别带中文或特殊字符,不然可能出问题。

  1. 点"安装",等几分钟
  2. 安装完点"完成"

安装向导
图3:JDK 安装过程

到这步,JDK 已经装好了。


步骤三:配置环境变量

这步是关键,让系统能识别 Java 命令。

1. 打开环境变量

方法一(快):

  • Win + R,输入 sysdm.cpl,回车
  • 点"高级" → "环境变量"

方法二:

  • 右键"此电脑" → "属性"
  • 点"高级系统设置" → "环境变量"

2. 配置 JAVA_HOME

在"系统变量"那块(注意是系统变量,不是用户变量):

  1. 点"新建"
  2. 变量名:JAVA_HOME
  3. 变量值:你的 JDK 安装目录

    D:\Java\jdk-11\
  4. 点"确定"

配置 JAVA_HOME
图4:新建 JAVA_HOME 环境变量

3. 配置 Path

  1. 在"系统变量"里找到 Path
  2. 选中,点"编辑"
  3. 点"新建",加两行:

    %JAVA_HOME%\bin
    %JAVA_HOME%\jre\bin
  4. 把这两行拖到最上面(优先级最高)
  5. 点"确定"保存

配置 Path
图5:编辑 Path 环境变量

注意:

  • Win10/11 用"新建"按钮添加就行
  • 老版本 Win 要手动在变量值末尾加,用分号隔开
  • 电脑上装过其他 JDK?把新版本移到最上面

步骤四:验证安装

打开 CMD 测试一下:

打开 CMD:

  • Win + R,输入 cmd,回车

输入:

java -version

成功了会显示类似:

java version "11.0.xx" 202x-xx-xx LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.xx+xx-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.xx+xx-LTS, mixed mode)

验证成功
图6:成功安装后的版本信息

再测一下编译器:

javac -version

输出:

javac 11.0.xx

看到这个,JDK 11 就装好了。


步骤五:写个 Hello World(可选)

跑个程序测试环境:

  1. 新建文本文件,改名 HelloWorld.java
  2. 用记事本打开,写入:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, JDK 11!");
    }
}
  1. 保存
  2. CMD 进入文件所在目录
  3. 编译:

    javac HelloWorld.java
  4. 运行:

    java HelloWorld

输出 Hello, JDK 11! 就说明环境完全正常。

❓ 常见问题

几个新手常遇到的问题:

Q1: java -version 提示"不是内部或外部命令"?

A: 环境变量没配好。

解决方法:

  1. 检查 JAVA_HOME 路径对不对
  2. Path 里的 %JAVA_HOME%\bin 有没有
  3. 关掉所有 CMD 窗口,重新打开
  4. 还不行就重启电脑

Q2: 装了多个 JDK 版本,怎么切换?

A: 调整 Path 里变量的顺序。

方法:

  1. 编辑 Path 环境变量
  2. 把要用的版本移到最上面
  3. 重开 CMD 验证

小技巧:可以给不同版本配不同的 JAVA_HOME,比如 JAVA_HOME8JAVA_HOME11,切换时改 Path 引用的变量就行。


Q3: Win11 配置了还是提示找不到 java?

A: Win11 有时要在用户变量里单独配一遍。

方法:

  1. 在"用户变量"也加个 JAVA_HOME
  2. 在"用户变量"的 Path 也加 %JAVA_HOME%\bin
  3. 重启终端或电脑

Q4: 下载还是慢?

A: 换个镜像试试。

推荐顺序:

  1. 清华镜像https://mirrors.tuna.tsinghua.edu.cn/Adoptium/
  2. 华为云https://repo.huaweicloud.com/java/jdk/
  3. Adoptium 官网https://adoptium.net/(国内有 CDN)

Q5: .zip 免安装版怎么用?

A: 解压后配置环境变量就行。

步骤:

  1. 把 .zip 解压到 D:\Java\jdk-11\
  2. 后面环境变量配置跟安装版一样
  3. 好处是多版本共存方便,卸载直接删文件夹

📌 总结

今天装 JDK 11 的步骤:

  1. 从国内镜像快速下载
  2. 运行安装程序
  3. 配置 JAVA_HOMEPath
  4. 验证安装

这套方法的好处:

  • 下载速度快
  • 步骤简单,新手友好

到这步,Java 开发环境就搭好了。

接下来可以:

  • 装个 IDE(IntelliJ IDEA 或 Eclipse)
  • 学 Java 基础语法
  • 写第一个 Java 项目

遇到问题?

  • 检查环境变量配置
  • 确认 JDK 安装路径
  • 评论区交流

🔗 参考来源


过去,代理工具的主要作用是帮助用户突破地域限制或隐藏真实 IP。那是一个相对粗放的阶段,网络系统更多依赖静态规则进行判断,只要更换出口地址,很多限制就可以被绕过。然而到了 2026 年,这种逻辑已经彻底失效。
如今的网络环境更像是一个动态评估系统。访问行为不再只看你来自哪里,而是综合分析你是谁、你是否像一个真实用户、你的连接是否符合正常网络模式。IP 只是其中的一个入口参数,而不是决定性的唯一因素。
在这样的背景下,代理是否“高匿名”,已经不再是技术细节,而是直接影响访问成败的核心条件。

什么是真正意义上的高匿名

很多代理服务在宣传时都会强调“匿名性”,但在实际网络识别体系中,并非所有隐藏 IP 的方式都被视为同等可信。高匿名并不仅仅意味着目标网站无法看到你的真实地址,更重要的是在整个连接链路中,不暴露任何异常代理特征。
真正的高匿名代理,会在协议层、请求头以及连接行为上都尽量贴近普通用户的访问模式。这意味着服务器端无法轻易判断请求是否经过中转,也难以通过流量特征推断出代理的存在。
如果代理只是简单替换出口 IP,却在其他层面留下明显痕迹,那么它在现代风控系统中几乎没有生存空间。

数据中心代理与住宅代理的本质差异

在当前环境下,IP 的来源比 IP 本身更重要。数据中心代理虽然速度快、成本低,但它们的地址段高度集中,长期被大量用户重复使用。这种特征在网络识别系统中非常明显,很容易被标记为“非自然流量”。
相比之下,住宅代理的 IP 来自真实家庭网络,分布更分散,使用行为也更接近普通用户。即使在高频访问或长期连接的场景下,住宅 IP 仍然更容易被视为正常网络活动的一部分。
当“像不像真实用户”成为判断标准时,住宅代理自然比数据中心代理更具优势,而高匿名住宅代理则是在这一基础上的进一步优化。

高匿名住宅代理为何能提升长期稳定性

许多用户在使用普通代理时,都会遇到同一个问题:刚开始可用,但很快失效。这并不是偶然,而是因为网络系统会持续评估连接行为。一旦某个出口被反复识别为异常来源,其可用性就会迅速下降。
高匿名住宅代理的价值,正体现在“不容易被识别”为代理这一点上。由于其 IP 真实性高、使用痕迹分散,单个出口不会因为短期行为而被迅速封禁。
从长期使用角度看,这种稳定性远比短期速度或价格更重要。它减少了频繁更换 IP 的成本,也降低了业务或访问中断的风险。

代理服务质量对匿名性的影响

并非所有住宅代理都天然具备高匿名属性。如果 IP 来源管理混乱、轮换策略不合理,或者同一出口被过度使用,即使是住宅 IP,也可能迅速失去可信度。
高质量的代理服务,通常会在 IP 分配、使用频率和连接行为上进行精细控制。这种控制并不会对用户造成明显感知,但会显著影响外部系统对流量的判断结果。
在实际应用中,一些用户会选择像 IPPeak 这样的住宅代理服务,拥有8000万+住宅IP,正是因为其更接近“长期可用网络环境”的定位,而不是短期突破限制的工具。

总结

高匿名住宅代理的重要性,并不来自某一个单一优势,而是源于现代网络环境的整体变化。当网络开始“理解”你的行为,简单的 IP 替换已经无法满足长期需求。
真正稳定、安全、可持续的访问方式,建立在可信网络身份之上。高匿名住宅代理,正是这一身份的基础组成部分。
在 2026 年之后,这种代理形态只会变得更加普遍,而不会被替代。

点赞 + 关注 + 收藏 = 学会了

整理了一个n8n小专栏,有兴趣的工友可以关注一下 👉 《n8n修炼手册》

在日常办公中,重复发送通知邮件、定时推送报表、表单提交后自动回复等场景十分常见,手动操作不仅耗时,还容易出现遗漏或错误。n8n作为一款开源的可视化工作流自动化工具,无需复杂编程,只需通过拖拽节点、配置参数,就能轻松实现邮件自动发送,非常适合没编程经验的工友上手。

n8n的核心优势是“可视化拖拽”和“多节点集成”,它能连接不同工具和服务,让数据按设定好的规则流转,从而完成自动化任务。对于自动发邮件来说,整个工作流的逻辑非常简单,只需满足两个核心组件:

  1. 触发节点:相当于工作流的“开关”,用来启动整个邮件发送流程,比如手动点击触发、定时触发、表单提交后触发等,初学者可先从最简单的手动触发入手;
  2. 动作节点:相当于工作流的“执行器”,负责完成具体的发邮件操作,n8n内置了专门的Email节点,支持通过SMTP协议连接各类邮箱,适配QQ、网易、企业邮箱等主流平台。

简单来说,我们要做的就是“搭建触发节点→连接邮件动作节点→配置邮箱参数→测试运行”,全程无需写一行代码。

创建邮箱凭证

想发邮件,首先就得登录邮箱。

在 n8n 登录邮箱跟我们在邮箱提供商的网页登录有点不同,我们需要到邮箱提供方那里开启 SMTP 授权。

我用 QQ 邮箱举例说明。

其他邮箱的开启方式大同小异,在流行 Python 自动化办公的年代,自动发邮件是很常见的示例。使用其他邮箱的工友直接百度搜【邮箱名 + 开启SMTP授权】基本能找到相关的教程。

首先在 QQ 邮箱网页登录你的账号。

然后找到“设置 -> 账号”。

然后 Ctrl + F ,搜索 SMTP 就能找到它。

默认情况 SMTP 是关闭的,如下图所示。需要你手动打开它(点击“开启服务”按钮)。

开启时,通常要收条短信验证码。输入完验证码之后就会给你一个授权码,这个授权码是用在 n8n 这边的,一定要保管好这个授权码,不要泄露出去。

在浏览器打开 n8n,创建一个凭证。

搜索 SMTP,选中它。

在表单里填入你的邮箱地址,Password 填入你刚刚申请的授权码。

Host、Port 和 SSL 要根据你所使用的邮箱去填,详情要看你使用的邮箱的官方文档。

比如我使用的 QQ 邮箱是这么要求的,发邮件的话,Host 填 smtp.qq.com,使用 SSL,端口是 465587

创建完成后就能看到一条记录。

发送第一封邮件

接下来的邮件发送我会用一个非常简单的工作流来讲解。

触发器我用了“手动触发”,也就是点一下鼠标就发邮件。虽然这看上去不像“自动化”,但你掌握了“发邮件节点”的用法,在以后的工作中只要把上游节点改成别的节点也是走得通的。

发送邮件用的是 Send email 节点。

本例的工作流是这样的。

重点是配置 Send email 节点。

  • Credential to connect with:邮件的凭证,用前面创建的那个凭证就行。
  • Operation:你要用这个节点做什么。Send 是发邮件的意思。
  • From Email:发送方的邮箱地址,填你的邮箱。
  • To Email:收件方的邮箱地址,填目标邮箱地址。
  • Subject:邮件标题
  • Email Format:邮件格式,如果你对格式没要求,选择 Text 也行。如果你需要搞一些样式,那就选 HTML
  • HTML:邮件内容。上一项选了 HTML,这项的标题就是 HTML;选 Text 这项的标题就是 Text
  • Options:其他选项。这里可以添加附件、添加抄送人等。

邮件标题和邮件内容可以写死,也可以使用上游节点传入的数据,动态调整邮件内容。

本例先写死,你根据自己的需求来做就行。

我用 QQ 邮箱向 Outlook 邮箱发一封邮件。

标题是“雷猴,自己人”。

格式是“Text”,也就是最简单的发送一些字符串过去。

内容是“用n8n发送的第一封邮件”。

完成上面的配置后,回到工作流画布面板,点一下“Execute workflow”按钮就能运行工作流了。

可以看到它已经执行了发邮件的操作。

打开 Outlook 邮箱就能看到这封邮件。

我使用的 n8n 是社区版(免费版),所以邮件下方会添加一条 n8n 的尾巴。

同时给多个人发送邮件

如果你想将一封邮件同时发送给多个人,只需要在 To Email 这里继续输入其他邮件地址就行。

每个邮箱之间要用“英文逗号”分割!!!

抄送

抄送也是很常用的功能,这个功能藏在 Send email 节点的 Options 配置项里。

CC(抄送)和BCC(密送)是邮件常用功能:CC用于告知相关人员邮件内容,所有收件人可见彼此信息,适合同步工作进度;BCC收件人信息对其他人隐藏,可保护隐私,适合批量发送通知。

我以 CC Email 举例说明。

CC Email 输入框里输入邮箱地址就行。如果要抄送给多个邮箱,那就用英文逗号把每个邮箱分割开来。

来到被抄送的邮箱,能清楚看到“我”是被抄送的对象。

发送附件

添加附件也是很常用的功能。

发送附件之前,首先得获取到附件。在日常工作中可能会从上游同事的接口获取附件,也可能是从本地上传一个附件。

我用本地附件来举例说明。

在此之前你需要掌握 《『n8n』读写本地文件》 这里的知识。也许你还会遇到无法读取本地文件的问题,可以看看这个解决方案👉 《『n8n』一招解决“无法读写本地文件”》

在 n8n 获取本地文件可以使用 Read/Write Files from Disk 节点。

我要获取本地的 posts.xlsx 文件, Read/Write Files from Disk 节点的配置如下图所示。

然后调整一下 Send email 节点的配置,需要在 Options 里添加一项 Attachments

上一个节点传入的是 data 字段,所以在 Attachments 直接填入 ”data“ 即可。

运行工作流,然后打开接收方的邮箱,就能看到这份附件了。


以上就是本文的全部内容啦,想了解更多n8n玩法欢迎关注《n8n修炼手册》👏

如果你有 NAS,我非常建议你在 NAS 上部署一套 n8n,搞搞副业也好,帮你完成工作任务也好 《『NAS』不止娱乐,NAS也是生产力,在绿联部署AI工作流工具-n8n》

点赞 + 关注 + 收藏 = 学会了

AI 小白一枚,周日下午体验了下 腾讯云 openclaw ( 99 元),买了腾讯云后发现阿里云( 78 元)更便宜。

配置了飞书和电报,开通了 7 天的 kimi,配置上 token,下午加晚上,简单体验消耗 20% token 。这 token 真的用不起呀。

关于 skills ,有点疑问,看用的相关 app 都是苹果系统下的,这里再 macmin 上部署是不是更合适一些?

如果自己买个 macmin ,单独部署体验 openclaw ,如何随时随地调用?暴露在公网会不会存在风险?

大家都是怎么用的 openclaw? 有没有哪些比较高效的使用方式?

比如我现在通过飞书让 openclaw 整理资料,然后通过文件形式发送到我的电报上查看。

在人工智能从“对话式交互”迈向“任务型执行”的过程中,一个明确的行业共识正在形成:真正具备生产力价值的,不是会聊天的模型,而是能完成任务的智能体系统。

所谓智能体,本质是一类具备目标理解、任务规划、工具调用与状态记忆能力的软件执行单元。它不依赖单次提示词完成工作,而是围绕一个目标,持续感知环境、调整路径并输出结果。围绕这一形态,越来越多企业开始尝试将原本由人完成的复杂流程,重构为智能体可执行的工作流——智能体来了,已经成为实践中的客观现象。

一、从“指令执行”到“目标达成”的根本转变

传统自动化依赖预设规则,传统聊天模型依赖一次性指令,而智能体的核心差异在于: 它接收的是目标,而不是步骤。

这意味着开发重点不再是“怎么写 Prompt”,而是:

  • 目标是否可被拆解
  • 每一步是否可被验证
  • 失败是否能被回滚与重试

本质上,这是一次业务逻辑的重新工程化

二、任务拆解的底层方法:把人的直觉变成流程

人类处理复杂事务时,依赖大量隐性经验与上下文判断,而智能体只能执行被显性描述的流程。因此,从人到智能体的迁移,必须经历三层转化。

1. 选择适合交给智能体的任务类型

高适配任务通常具备以下共性:

  • 输入与输出边界清晰
  • 中间过程允许试错与迭代
  • 结果可被规则或样本评估

典型如:信息整理、内容生成、客服处理、数据分析、流程编排等。

2. 将连续动作拆成“原子任务”

对人来说是一个动作,对智能体来说必须是多步链路。

例如“处理一次客户投诉”,可被拆解为:

  • 信息识别:提取情绪、问题类型、涉及模块
  • 策略判断:是否命中历史案例、是否升级人工
  • 执行操作:生成回复、记录工单、更新状态
  • 事后总结:是否形成新知识、是否需要补充规则

每一步都必须是可独立验证的。

3. 明确哪些环节不交给智能体

成熟的系统一定包含边界:

  • 高风险决策 → 人工确认
  • 异常路径 → 强制中断
  • 模型不确定性过高 → 回退规则

这不是能力不足,而是工程理性。

三、支撑智能体运行的三大系统组件

任务拆解完成后,还需要基础能力支撑,才能真正跑起来。

1. 记忆系统

  • 短期记忆:维持当前任务上下文与状态
  • 长期记忆:沉淀历史经验、用户偏好、领域知识

长期记忆的引入,决定了智能体是否“越用越聪明”。

2. 规划与自检能力

一个可落地的智能体,必须具备:

  • 子目标拆分能力
  • 执行过程中的自我校验
  • 失败后的路径调整能力

没有反思能力的智能体,只是更复杂的脚本。

3. 工具调用能力

真正的“执行”,来自工具:

  • API 调用
  • 内部系统操作
  • 数据读写与状态变更

工具是否标准化,直接决定智能体是否具备扩展性。

四、实践中最常见的三个误区

误区表现修正方向
过度依赖单模型一个 Prompt 解决所有问题多智能体分工
执行不可观测出错但无法定位全流程日志与状态记录
边界不清智能体“擅自决策”Human-in-the-loop 机制

智能体系统不是越聪明越好,而是越可控越好。

五、可复用的智能体构建路径

一条被反复验证有效的路径是:

  1. 明确目标与失败边界
  2. 拆解为可验证的原子任务
  3. 为每一步配置工具与规则
  4. 引入反馈与评分机制
  5. 将成功路径沉淀为长期记忆

这是一项持续工程,而非一次性交付。

结语

从 0 到 1 构建智能体,不是在追逐更大的模型参数,而是在做一件更“笨”却更重要的事: 把人的经验,翻译成机器能反复执行的结构化流程。

当任务被拆清、边界被定义、反馈形成闭环,智能体才能真正从工具,进化为协作单元。

已经 2026 年了,好久没写 blog,今天简单写几句。这两年生活发生了一些变化。

2024 年底,家里添了一辆车。当初在电车和油车之间纠结了一阵,最终听了媳妇儿的建议,选了新款帕萨特 Pro。如今安全行驶满一年,体验很好,挺满意。有车之后,生活的半径实实在在地变大了。周末不再只限于商场和公园,今年夏天还抽出一周时间,自驾去广西转了一圈。一路青山绿水,走走停停,那种手握方向盘、说走就走的自由感,确实是之前没有过的体验。

再说说房子的事。现在租的房子旁边一直在建保障房,每天从早到晚叮叮当当,实在有点吵。加上这几年房价降了不少,首付比例也调低了,手头的积蓄刚好差不多够付首付,于是年初开始陆续看房。其中有一套和房东聊了聊,感觉对方价格咬得比较紧,也就没再继续。看房的事就这样暂时搁置了。

直到年底,平台上又冒出几套不错的房源,看房计划重新启动。偶然看到一套装修和格局都很合心意的房子,除了价格稍高一点,其他几乎完美。最后终于定下来了。在这个小区租住了七八年,如今总算有了属于自己的小家。

工作方面比较稳定,没什么特别亮眼的成绩,算是中规中矩。前年获得了一次晋升,心态也随之有些变化,希望今年能再往上走一步。公司没有加班文化,身心都比较放松,工作和生活平衡得还不错。

体重一直维持在 170 斤左右,最近几个月健身基本停了,这方面还得重新捡起来,不然身材走形太厉害。

新的一年,给自己定几个小目标吧:

  • 每周跑步 6 公里,月跑量达到 25 公里
  • 攒钱还债,争取提前还清车贷
  • 从新疆、青海湖、内蒙古或云南中选一个地方旅行
  • 尝试经营小红书副业(方向再琢磨)
  • 新增 3 道自己的拿手菜

大家好,我是良许

三极管作为电子电路中最基础也是最重要的器件之一,在嵌入式系统设计中扮演着举足轻重的角色。

无论是信号放大、开关控制,还是电平转换,三极管都是我们绕不开的话题。

而要真正理解三极管的工作原理,掌握其伏安特性曲线是必不可少的。

今天我们就来深入探讨一下三极管的伏安特性曲线,帮助大家更好地理解和应用这个经典器件。

1. 三极管基础知识回顾

在深入伏安特性曲线之前,我们先简单回顾一下三极管的基本结构和工作原理。

三极管有三个电极:发射极(E)、基极(B)和集电极(C)。

根据半导体材料的不同排列,三极管分为 NPN 型和 PNP 型两种类型。

在嵌入式开发中,我们最常用的是 NPN 型三极管,比如经典的 2N2222、S8050 等型号。

三极管的核心作用是电流放大。

当基极注入一个很小的电流 IB 时,集电极就会产生一个较大的电流 IC,两者之间存在一个放大倍数关系,我们称之为电流放大系数 β(或者 hFE)。

这个关系可以用公式表示为:IC = β⋅IB。

在实际应用中,β 值通常在 50 到 300 之间,具体数值取决于三极管的型号和工作条件。

2. 伏安特性曲线的分类

三极管的伏安特性曲线主要分为两大类:输入特性曲线和输出特性曲线。

这两类曲线从不同角度描述了三极管的电气特性,对于电路设计和分析都具有重要意义。

2.1 输入特性曲线

输入特性曲线描述的是基极-发射极之间的电压 VBE 与基极电流 IB 之间的关系。

这条曲线在集电极-发射极电压 VCE 保持恒定的条件下测得。

对于硅材料的 NPN 型三极管,当 VBE 小于 0.5V 时,基极电流几乎为零,三极管处于截止状态。

当 VBE 达到约 0.7V 时,三极管开始导通,基极电流开始明显增加。

这个 0.7V 就是我们常说的三极管导通电压。

输入特性曲线的形状与二极管的伏安特性曲线非常相似,这是因为三极管的基极-发射极之间本质上就是一个 PN 结。

在实际电路设计中,我们通常会在基极串联一个限流电阻,以控制基极电流的大小,防止基极电流过大而损坏三极管。

2.2 输出特性曲线

输出特性曲线是三极管最重要的特性曲线,它描述了集电极电流 IC 与集电极-发射极电压 VCE 之间的关系。

这组曲线是在不同的基极电流 IB 条件下测得的,因此输出特性曲线实际上是一族曲线。

输出特性曲线可以分为三个区域:截止区、放大区和饱和区。

这三个区域对应着三极管的三种不同工作状态,在不同的应用场景中,我们会让三极管工作在不同的区域。

3. 输出特性曲线的三个工作区域

3.1 截止区

当基极电流 IB=0 或者 VBE 小于导通电压时,三极管工作在截止区。

此时,集电极电流 IC 几乎为零(实际上存在一个很小的漏电流,通常在微安级别,可以忽略不计)。

在这个区域,三极管相当于一个断开的开关,集电极和发射极之间呈现高阻态。

在嵌入式系统中,当我们需要用三极管作为开关来控制负载时,关断状态就是让三极管工作在截止区。

比如用 STM32 的 GPIO 控制一个 LED 灯,当 GPIO 输出低电平时,三极管基极没有电流,三极管截止,LED 熄灭。

3.2 放大区

放大区是三极管最重要的工作区域,也称为线性区或有源区。

在这个区域,集电极电流 IC 与基极电流 IB 保持线性关系,即 IC=β⋅IB。

同时,VCE 要大于一个临界值(通常为 0.3V 到 0.7V 之间),这样才能保证三极管工作在放大区而不是饱和区。

在放大区,输出特性曲线几乎是水平的,这意味着在基极电流 IB 恒定的情况下,集电极电流 IC 基本不随 VCE 的变化而变化。

这个特性使得三极管可以作为一个理想的电流源使用。

在模拟电路设计中,比如音频放大器、信号调理电路等,我们都需要让三极管工作在放大区。

3.3 饱和区

当基极电流 IB 足够大,使得集电极电流 IC 达到最大值时,三极管进入饱和区。

在饱和区,IC 不再随 IB 线性增加,此时 VCE 很小,通常只有 0.2V 到 0.3V 左右。

在这个状态下,三极管相当于一个闭合的开关,集电极和发射极之间呈现低阻态。

在数字电路和开关电路中,我们通常让三极管工作在饱和区。

比如在 STM32 项目中,用三极管驱动继电器或者大功率 LED 时,我们会给基极足够大的电流,让三极管深度饱和,这样可以降低导通损耗,提高效率。

4. 伏安特性曲线在实际电路中的应用

理解了三极管的伏安特性曲线后,我们来看看如何在实际电路设计中应用这些知识。

4.1 开关电路设计

在嵌入式系统中,最常见的应用就是用三极管作为开关。

假设我们要用 STM32 的 GPIO(输出电压 3.3V)来控制一个 12V 的继电器,继电器线圈电流为 50mA。

可以这样设计电路:首先选择一个合适的 NPN 三极管,比如 S8050,其 β 值约为 100。

为了让三极管工作在饱和区,我们需要提供足够的基极电流。

理论上,基极电流只需要 IB = IC / β= 50mA / 100 = 0.5mA 即可。

但在实际设计中,为了确保三极管深度饱和,我们通常会让基极电流达到理论值的 2 到 3 倍,即 1mA 到 1.5mA。

基极串联电阻的计算公式为:RB = (V\_GPIO - VBE) / IB = (3.3V - 0.7V) / 1mA = 2.6kΩ。

我们可以选择标准阻值 2.7kΩ 的电阻。

下面是一个简单的 HAL 库代码示例,演示如何控制这个三极管开关:

// GPIO初始化配置
void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    // 使能GPIOA时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    // 配置PA5为推挽输出
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    // 初始状态设为低电平,三极管截止
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}
​
// 控制继电器开关
void Relay_Control(uint8_t state)
{
    if(state == 1)
    {
        // 输出高电平,三极管导通(饱和区),继电器吸合
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    }
    else
    {
        // 输出低电平,三极管截止,继电器释放
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    }
}

4.2 放大电路设计

在模拟信号处理中,我们经常需要设计放大电路。

假设我们要设计一个共发射极放大电路,用于放大传感器输出的微弱信号。

在这种应用中,三极管必须工作在放大区。

设计放大电路时,我们需要通过合理选择偏置电阻,让三极管的静态工作点(Q 点)落在放大区的中间位置。

这样可以保证输入信号在正负两个方向都有足够的摆幅空间,避免信号失真。

静态工作点的选择通常遵循以下原则:VCE 约为电源电压的一半,IC 根据负载电阻和所需的放大倍数来确定。

通过在输出特性曲线上画出负载线,我们可以直观地看到静态工作点的位置以及信号的动态范围。

4.3 电平转换电路

在嵌入式系统中,经常会遇到不同电压域之间的接口问题。

比如 3.3V 的 MCU 需要与 5V 的外设通信,或者需要驱动 12V 的负载。

这时候,三极管可以作为一个简单有效的电平转换器。

以 3.3V 转 5V 为例,我们可以用一个 NPN 三极管搭建一个反相器电路。

当输入为高电平(3.3V)时,三极管导通,输出为低电平(接近 0V);当输入为低电平(0V)时,三极管截止,输出被上拉电阻拉到高电平(5V)。

虽然这个电路会产生信号反相,但在很多应用场景中,这并不是问题,或者可以通过软件或者再加一级反相器来解决。

5. 伏安特性曲线的测量与分析

在实际工作中,有时候我们需要测量三极管的伏安特性曲线,以验证器件性能或者进行故障诊断。

测量输出特性曲线的基本方法是:固定基极电流 IB,然后改变集电极-发射极电压 VCE,同时测量集电极电流 IC。

重复这个过程,在不同的 IB 值下进行测量,就可以得到一族输出特性曲线。

现代的晶体管图示仪可以自动完成这个测量过程,并在示波器上直接显示特性曲线。

但如果没有专业设备,我们也可以用万用表、可调电源和电阻搭建一个简单的测量电路。

虽然这种方法比较繁琐,需要手动记录大量数据点,但对于理解三极管的工作原理非常有帮助。

在分析特性曲线时,我们需要关注几个关键参数:饱和压降 VCE(sat)、放大系数 β、以及击穿电压 BVCEO。

这些参数直接影响电路的性能和可靠性。

比如,如果实测的 β 值远小于数据手册的典型值,可能说明三极管已经老化或者损坏。

6. 温度对伏安特性曲线的影响

三极管的伏安特性曲线并不是一成不变的,它会受到温度的显著影响。

随着温度升高,导通电压 VBE 会降低,大约每升高 1℃ 降低 2mV。

同时,电流放大系数 β 也会随温度升高而增大。

这些变化会导致静态工作点发生漂移,在精密模拟电路中可能引起性能下降。

在嵌入式系统设计中,特别是工业级和车规级应用,我们必须考虑温度变化的影响。

对于开关电路,温度影响相对较小,因为我们只关心三极管是导通还是截止。

但对于放大电路,就需要采取温度补偿措施,比如使用负反馈、温度补偿电路或者选用温度特性更好的器件。

在汽车电子项目中,我曾经遇到过一个案例:一个传感器信号调理电路在常温下工作正常,但在高温环境下输出信号出现明显漂移。

经过分析发现,是三极管放大电路的静态工作点随温度升高而偏移,导致放大倍数发生变化。

最后通过增加温度补偿电路和调整偏置参数,解决了这个问题。

7. 实际应用中的注意事项

在使用三极管时,除了要理解伏安特性曲线,还需要注意一些实际问题。

首先是功耗问题。

三极管在导通状态下会产生功耗,功耗大小为 P = VCE×IC。

在大电流应用中,必须考虑散热问题,必要时需要加装散热片。

其次是开关速度问题。

三极管从截止到饱和,或者从饱和到截止,都需要一定的时间。

这个时间主要由三极管的结电容和电荷存储效应决定。

在高频开关应用中,如果三极管的开关速度不够快,会导致效率降低和发热增加。

这时候可以考虑使用开关速度更快的 MOSFET。

最后是保护问题。

在驱动感性负载(如继电器、电机)时,必须在集电极并联一个续流二极管,防止负载断电时产生的反向电动势击穿三极管。

这是一个很容易被忽视但又非常重要的细节。

8. 总结

三极管的伏安特性曲线是理解和应用三极管的基础。

通过输入特性曲线,我们可以了解基极-发射极之间的电压电流关系;通过输出特性曲线,我们可以清楚地看到三极管的三个工作区域,并根据应用需求选择合适的工作状态。

在嵌入式开发中,无论是设计开关电路、放大电路还是电平转换电路,都离不开对伏安特性曲线的理解。

掌握了这些知识,我们就能更加自信地进行电路设计,也能更快地定位和解决电路问题。

虽然现在 MOSFET 等新型器件越来越普及,但三极管凭借其简单、可靠、成本低的优势,依然在嵌入式系统中占有重要地位。

希望这篇文章能帮助大家更好地理解和应用三极管。

更多编程学习资源

小时候家里穷,也的确没的穿的,都是穿亲戚剩下的旧衣服,也没觉得有什么不好。可能是学习好,老师和同学也没和我说过旧衣服的事,或者自己心思压根没注意到。 工作以后,衣服就基本优衣库,鞋子就安踏李宁,T 恤穿到领子破了就再买新的。 =======我不穿的衣服之前拿回老家被我妈骂了,说我要是不穿的衣服,整个村子也不会再有人穿了... ........=====可是我真的不咋在意穿着,衣能蔽体御寒的程度就可以了。 ======前两天又有一个人意味深长地说我,年轻人该对自己好一点,买点好衣服穿,穿得帅气多好。 可是我看着还干净整洁啊,也修边幅啊。 倒不是经济原因,想问下你们也有人不在意穿着的么?

从 ChatGPT 3.5 诞生以来,我们公司就通过防火墙的形式把各种 AI 屏蔽了,去年年初的 Deepseek ,到今年年初的 Qwen ,不过也是草台班子,并没有一次性把国内的所有 AI 都屏蔽了,一些暂时没有大火的工具现在还能用,总之就是现在国内哪个 AI 火了就屏蔽哪个。
尊重公司为了数据安全不让访问 AI ,但是无法理解公司不去采购企业账户拥抱 AI 工具提效,而是像大清闭关锁国一样一股脑全不让访问....
后面在我自己的争取下,找到了公司的一个访问申请流程,可以通过虚拟机的形式开启权限,但是流程巨多巨麻烦,而且每次访问都需要修改密码,常规文件和剪贴板和虚拟机也无法共享,同样也没有企业账户。就算我自己登录了我自己的个人 AI 账户,无法共享文件和剪贴板和我自己在手机上问 AI 没有任何区别,和提效背道而驰.....而且我根本就不想用自己的账户,虚拟机的 IP 在海外的公司总部,我担心因为 IP 地址差异太大把我号给风控了,得不偿失。
很难想象我们还是一家「巨型」「跨国」「科技」公司,我们还有自己的生成式 AI ,但是难用得一批。哎,我日常已经离不开 AI 了,上班不能使用真的很难受。

之前大学还没感受,老听同学说欧美的才是正经音乐,现在感觉国内的音乐风格越来越偏苦情歌,各种无痛呻吟。再听韩国的 k-pop ,感觉国内音乐连韩国都赶不上了。不知道大家有类似感受没。从娱乐到科技。咱们国内综合实力是不是一直都处于中等的位置、

但凡提到国漫,《凡人修仙传》基本就是绕不过去的话题,但作为一个动漫爱好者真的不太喜欢,最主要的点就是韩立永远一张没有表情的面瘫脸,我的感受是很违和,很出戏。可能有的老哥解释韩立是一个清心寡欲的人,面部表情本来就不多。但我觉得清心寡欲和面瘫是不一样的。这也是我尝试几次都坚持不下去的原因。

相反同为 3D 漫的《灵笼》我觉得就没有这个问题,里面的每一个角色都很鲜活。

2 友们 2025 年有发现什么宝藏音乐吗?值得单曲循环的宝藏音乐~

当大模型在数学竞赛、代码编写等领域持续突破,甚至超越顶尖人类专家时,大家难免会好奇:这些在基准测试中拿高分的模型,能否真正落地到复杂多变、充满噪声的真实世界任务中?

近期,美团 LongCat 团队交出了一份重磅答卷——开源 LongCat-Flash-Thinking-2601。作为一款拥有 5600 亿参数的 MoE(混合专家) 模型,它不仅在 BrowseComp、VitaBench 等智能体基准测试中登顶开源 SOTA,更通过“环境扩展、多环境RL训练、抗噪训练”等核心创新,解决了智能体“落地难”的问题。同时,该模型创新性地打造了 “重思考模式” ,通过并行推理与深度总结,实现推理宽度与深度的协同扩展,显著提升复杂交互与多步规划任务中的表现。

今天,我们深入解析 LongCat 如何通过多维度的创新打造强泛化的智能体模型。

01 为何智能体在真实世界中总是“水土不服”?

当前,智能体系统依然严重依赖垂直场景的定制化设计——需要工程师精心打磨特定的Prompt、工具链,甚至环境接口。这种模式带来了高昂的适配成本:模型在一个场景下表现优异,一旦换个领域、换套工具,或者环境稍微嘈杂一点(比如工具调用超时、工具报错),它们就会“水土不服”,甚至失效。

根本原因在于:缺乏一个能够在多样化、复杂化、带噪声环境中“身经百战”并稳定泛化的基础模型。 现有的训练往往在高度理想化、规则明确的环境中进行,缺乏对真实世界复杂交互与不确定性的充分覆盖。

为此,美团LongCat团队提出了一套以 “两个扩展+噪声训练” 为核心的通用智能体训练范式:

  • 环境扩展:构建覆盖20+领域的规模化训练场
  • 强化学习扩展:在万级异构环境中实现高效稳定训练
  • 噪声鲁棒训练:系统化注入真实世界扰动,提升模型韧性

通过这套组合拳,模型能够获得高级别的任务执行与跨领域泛化能力,实现模型即智能体,显著降低后续垂直场景的适配负担,让模型能够在真实复杂世界中自如地应对新任务和新挑战。

02 环境扩展:构建高质量“练兵场”

环境扩展是模型获取通用智能体能力的核心基础。要让模型真正掌握实际任务执行能力,就必须脱离纯文本训练的局限,让模型在模拟真实场景的交互环境中落地实操。

面对真实世界场景复刻成本高、迭代效率低的痛点,LongCat 团队构建了端到端自动化环境生成系统,为模型打造了覆盖 20 余个领域、包含上万种情境的规模化训练环境。该系统具备高效智能化生成能力:输入简洁的 “领域定义” 即可完成全链路环境构建,自动合成包含 60 余个工具、具备复杂依赖关系的可执行环境图谱,并同步生成配套的数据库架构、工具调用接口及验证逻辑。环境类型覆盖文件管理、数据分析、电商零售、电信服务等多元场景,提供与真实世界一致的工具交互体验,支撑模型调用工具、处理数据、接收反馈的全流程训练。

图 1 - 可执行领域图谱的自动化构建流程

自动化合成的环境越复杂,其背后关联的需要自动合成的数据库越多,越难保持这些自动合成的“数据库一致性” —— 单个环境关联数十个数据库,工具间参数依赖错综复杂,易出现逻辑冲突导致任务 “看似可解实则无解”,向模型传递错误训练信号。为此,LongCat 团队创新了 “可解路径优先” 的环境构建策略:

  • 种子采样:随机采样一条长工具调用链作为锚点,并依此自动构建一个采纳该工具调用链作为解法之一的复杂任务,同时对于采样过的工具,降低其采样概率;
  • 受控扩展:以该“黄金工具链”为根,通过BFS式扩展,生成一个极大环境子图(保证其前序依赖结点均在已有的工具集内,从而进行可控扩展),严格保证数据库的逻辑一致性;
  • 动态环境构建:系统会根据当前环境的复杂度、剩余工具图中找到新有效路径的难度、以及未使用的工具数量,动态决定是否加入新的“黄金工具链”。这样既能扩展环境规模,又能保证任务可解、训练有效;
  • 最小规模保证:如果当前环境的工具数量太少(不足20个),系统会直接从全局工具库中随机选一条中等规模的可用工具链加入,并始终保持数据库状态一致,避免环境失效。

这套机制既能扩展环境规模,又能保证任务可解、训练信号有效,彻底摆脱“纸上谈兵”的局限。

图 2 - 保持可验证性的环境扩展流程

03 强化学习扩展:万级异构环境下的高效稳定训练

当我们有了海量训练环境,怎么让模型高效学习?为支持大规模多环境训练,LongCat团队升级了异步训练系统DORA。在训练启动前,团队将预训练/微调模型的目标,从追求基准高分,重新定义成为后续RL提供“冷启动策略”:

  • 有真实数据的领域(如数学、编码):通过严格的质量控制与可执行性验证筛选高质量轨迹。
  • 缺乏真实数据的领域(如搜索、工具使用):采用双路合成,包括文本驱动合成及环境锚定合成。

这样既保证了数据质量,也为后续强化学习提供了多样化的探索基础。

DORA 系统的核心突破在于全异步流式训练架构,颠覆传统同步训练模式

  • 多版本模型并行探索:不同版本模型生成的训练经验 “随产随收”,直接存入样本队列,训练器无需等待所有任务完成即可启动训练,彻底消除任务间等待时间;训练设备空闲时,系统可弹性扩容生成实例,进一步提升吞吐量;
  • 分布式调度架构:拆解集中式调度设计,采用 “轻量级 Rollout Manager + 多 Rollout Controller” 的分布式模式,前者负责全局元数据管理,后者各自管理一个虚拟 rollout 组的生命周期,通过数据并行处理环境交互,解决单机器调度瓶颈;
  • 灵活环境部署:扩展 PyTorch RPC 框架,支持基于 CPU 空闲状态的远程函数调用与对象实例化,可将海量环境灵活部署到任意空闲机器,实现资源高效利用。

为适配 5600 亿参数 MoE 模型训练需求,DORA 引入两项关键优化

  • Prefill-Decode(PD)解耦,将预填充与解码任务部署在不同设备组,避免长上下文请求的预填充任务干扰解码流程,保障多轮交互中的生成效率;
  • KV-cache 交换机制,通过 chunk 级 KV-cache 聚合传输、异步传输与计算重叠降低数据传输开销,配合 CPU 驻留的 KV-cache 动态交换机制,彻底解决设备显存不足导致的重复计算问题。

资源分配上,DORA 实现 “双层平衡”:

  • 整体平衡:根据环境难度分配训练任务量,对复杂、低吞吐量领域提高 rollout 配额,避免简单环境训练过度;
  • 批内平衡:单批次保证任务域多样性,防止模型仅适应少数环境出现过拟合。

最终,该系统实现 2-4 倍于传统同步训练的效率,支持千步以上稳定训练,支撑模型在万级异构环境中持续学习、稳步提升。

图 3 - 在大规模多环境智能体强化学习中的训练奖励曲线

图 4 - 在RL训练期间使用纯合成通用智能体数据的基准测试性能

04 噪声环境下的稳健训练:系统化注入真实世界扰动

真实世界环境存在固有不完美性 —— 工具可能因网络问题随机失效、返回残缺结果,用户指令可能存在歧义、表述前后不一致,数据传输过程中还可能出现误差,这些噪声会导致仅在理想化完美环境中训练的模型,部署到真实场景后 “水土不服”,性能大幅下降。为此,LongCat 团队将真实世界的 “不完美” 纳入训练核心,设计系统化鲁棒性训练方案,提升模型在不确定环境中的稳定决策能力。

团队首先对真实世界噪声进行系统拆解与建模,明确两类核心噪声来源:

  • 工具噪声:包括工具执行失败(如调用超时、权限不足)、返回结果不完整(如数据字段缺失)、响应格式不一致(如有时返回 JSON 有时返回文本)等场景;
  • 指令噪声:涵盖用户表述歧义(如未明确任务目标)、指令信息冗余(如包含无关干扰内容)、需求动态变更(如中途调整任务参数)等情况。

这些噪声均基于真实场景观测总结,最大程度还原真实世界的不确定性。为使模型循序渐进适应噪声,团队采用 “课程学习” 注入策略:训练初期注入轻微扰动(如工具返回结果少部分缺失、指令存在轻微歧义),模型在当前噪声水平下表现出足够稳定性后,再逐步提升噪声复杂度与干扰强度(如工具频繁失效、指令严重模糊),形成稳健决策模式。

训练执行层面,团队将噪声注入与多环境训练深度融合:在20余个领域的上万种环境中,针对性加入不同类型、不同强度的噪声,使模型在学习各领域任务能力的同时,同步适应噪声环境。通过这种渐进式训练,模型最终能够在各种真实世界扰动下仍保持稳健的决策能力。

05 构建 “重思考机制”:让模型“做事”三思而后行

在特别复杂的任务上,模型有时会一根筋——沿着一条思路走到黑,即使那条路可能不对。这很像人类在遇到难题时,需要多想想不同的可能性。“重思考”模式的核心是 “宽度 + 深度” 双扩展:先让模型同时生成多条推理路径,探索不同的解决方案,再用专门的总结模型,对这些路径进行分析、筛选,提炼出最优思路。而且还会通过强化学习,让模型学会整合中间结果,不断完善推理过程。

在实际测试中,不管是长链推理、工具集成推理,还是完全的智能体工具使用场景,“重思考”模式都特别有效。随着测试时计算预算的增加,它的性能优势会越来越明显,比只扩展推理深度或宽度的策略表现好得多。

图 5 - 重思考模式框架

06 能力验证:不仅会做,而且做得稳、能泛化

在以下基准测试中,LongCat-Flash-Thinking-2601 的表现相当亮眼:在 BrowseComp 、τ²-Bench 、VitaBench 均达到开源模型中的顶尖水平,甚至在部分任务上逼近了闭源顶级模型。

表1 - 多基准测试性能(%)对比

同时,模型展现出强泛化能力,在未见过的随机工具组合与任务中表现出色,掌握 “解决问题的元能力”;在注入真实噪声的测试集上,表现大幅超越其他模型,验证了主动噪声训练的有效性。通过算法与工程的深度协同,自动化环境构建降低适配成本,DORA 系统让训练效率提升 2-4 倍,Heavy Thinking 模式放大复杂任务处理能力,形成高效可扩展的训练体系。

07 One More Thing:Zigzag 注意力机制

传统全注意力机制的二次计算复杂度限制了其对百万级token上下文的支持,而现有稀疏注意力方案往往需要完全重训,成本高昂。

LongCat团队提出的Zigzag注意力机制(Zigzag Attention)创新性地结合了两种稀疏注意力模式:MLA(多头潜在注意力)SSA(流式稀疏注意力)。该机制采用分层设计,在不同层中交替使用这两种稀疏注意力变体,避免了传统稀疏注意力中常见的计算不平衡问题,实现了更高的硬件利用率。

核心设计:对每个查询token,注意力被限制在以下两部分:

  • 局部窗口:最近的W个token,捕捉短期依赖
  • 全局锚点:序列开头的B个token,保留长期记忆

这一设计显著降低了计算和内存复杂度,同时保持了模型对短长期上下文的感知能力。

实施方式:Zigzag注意力在中期训练阶段引入,通过结构化稀疏化流程将原始全注意力模型高效转换为稀疏变体,转换开销极低。经过优化后的模型支持最长100万token的上下文长度,为超长序列处理提供了可行解决方案。

团队同步开源适配该机制的模型 LongCat-Flash-Thinking-ZigZag ,完整继承LongCat-Flash-Thinking-2601的核心能力,同时具备超长上下文处理优势,为开发者提供即拿即用的长序列解决方案。

图 6 - LongCat-Flash-Thinking与采用Zigzag注意力的LongCat-Flash-Thinking-ZigZag的推理效率对比

08 总结

LongCat-Flash-Thinking-2601 通过环境扩展与噪声训练,显著降低了智能体对垂直场景的依赖,为开源模型在真实世界任务中的泛化能力设立了新的参考标准。我们相信,真正通用的智能体,不应是温室里的盆景,而应是能在真实世界风雨中扎根的大树。

LongCat-Flash-Thinking-2601 的发布,是我们向这个目标迈出的坚实一步。开源是我们播下的一颗种子,我们期待与整个社区一起,在这片名为“智能体”的星辰大海中,共同驶向辽阔的未来。

开源平台

在线体验与调用

欢迎开发者下载、部署并体验 LongCat-Flash-Thinking-2601,同时也欢迎您在LongCat API 开放平台申请免费调用额度。如果您在智能体开发、大模型推理优化等领域有合作想法或反馈,我们期待与您交流。

| 关注「美团技术团队」微信公众号,阅读更多技术干货!

| 本文系美团技术团队出品,著作权归属美团。欢迎出于分享和交流等非商业目的转载或使用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者使用。任何商用行为,请发送邮件至 tech@meituan.com 申请授权。

opencode 加 kimi k2.5 。

结论,蠢得要死,逻辑推理还是稀烂。完全不理解需求,幻觉依然多,花了 4 个小时,最后我手动给他找 bug 把一个简单程序跑通了。 试了下 gemini3flash ,20 分钟自己搞定

完全是垃圾。

但是有几点好的,1 在 opencode 的依序执行时,哪怕执行出错也能中断继续,虽然慢,但是能执行完。gemini 偶尔傻掉会无限循环输出。2 比较听话,gemini 和 qwen 是很不听话的,gemini 你给他写个 rules 或者 agents.md ,里面哪怕就一句,永远用中文回复。他都不听话。claude 是最守规矩的

估摸着实际编码能力只能和 claude 3.5 haiku 比下,应该还落后御三家一年以上。 比 GLM4.7 要好,GLM4.7 最恶心的是非常经常的,没做的需求他说他做了。。。最后和他对质,他还会说,我就是忽悠你的。我没做。要气吐血。

K2.5 会坦诚接受错误,可是他真的跑多少次,简单的错误都改不好。

所以用御三家做设计,k2.5 做执行可能还马马虎虎吧。

在业务规则配置中,我们经常需要先对原始数据进行加工,生成一个复杂的“复合变量”。之后,在具体的决策流程中,我们可能需要调用这个复合变量,这时就会出现调用时以复合变量的某些值作为入参给到决策进行动态传参。
以下解读用到的是国内一款可视化决策配置——JVS规则引擎
JVS规则引擎是可以直接使用的企业级规则引擎,自动化与智能化并行。Java语言开发,前端VUE+ElementUI,提供私有化部署,支持提供全量源码、二次开发、定制、可集成。

场景示例

现有一张成绩表,分别为不同姓名不同学科得到的不同成绩分数。要求在决策里进行加工:90分以上评级为优,90分以下评级为良。最终决策端只需输入学科和姓名即出现对应评级情况。原本数据表如下所示:
图片

配置步骤解析

1、先导入Excel表格,作为Excel数据源。
图片
2、配置查询条件,可根据实际场景配置。此处需要姓名和学科,即配置姓名和学科的查询条件并提供默认值。
图片
3、面对一堆数据的处理,所以得用复合变量进行加工。先新建一个复合变量并选择该数据源作为输入。
图片
4、对数据进行字段设置,把日期和分数改为对应时间、数字类型。
图片
5、用数据拓展节点对现有数据进行加工判断,新增一个成绩水平字段并配置判断条件。
图片

图片
6、输出节点连接保存拿到最终结果。
图片
7、新建一个决策流,且无需添加任何入参。
图片
8、进入决策,拖拽赋值节点到画布并新增一个基础变量。
图片
9、配置基础变量的值,选择复合变量里的【成绩水平】作为该res的值。当你选择完毕后,此时系统便会自己去查找该复合变量的查询条件,并会自动在执行时带出所需要填写的入参值。
图片
10、拖拽结束节点并配置输出结果为res。
图片
11、点击执行,此时就可看到复合变量所需要的条件已经显示出来。
图片
12、分别输入不同学科和姓名,拿到的最终res也不同。
图片

图片
在线demo:http://rules.bctools.cn
gitee:https://gitee.com/software-minister/jvs-rules

自 2014 年提出以来,低代码已逐步进入 ICT 技术成熟期,并开始深度嵌入企业核心系统建设体系。对 CIO、总架构师及技术管理者而言,关键问题已不再是“是否引入低代码”,而是如何将其纳入既有架构体系与工程治理框架,并确保其对系统长期演进产生正向影响。

为此,我们通过阅读大量文献,结合实践案例,编写了这本手册,希望能为您带来更全面、更客观的低代码技术介绍,尝试解答直接决定低代码项目的可持续性的重点问题:

  • 低代码解决的是哪些长期存在的工程问题?
  • 其能力边界与适用前提在哪里?
  • 如何与既有开发体系、架构体系协同?
  • AI 参与开发后,低代码的工程角色如何变化?
  • 技术管理者应如何构建配套治理机制?

手册按“背景 → 概念 → 原理 → 场景 → 管理 → 前瞻”的顺序展开,形成完整认知闭环,建议您按顺序阅读,以建立系统视角;亦可根据实际职责,重点研读相关部分。

一句话总结:

本手册面向承担架构设计、平台规划与技术治理责任的管理者,

旨在提供一套可长期参考的低代码认知框架。

第一部分 低代码诞生的背景

企业软件的复杂度并非源于单一技术选择,而是伴随需求扩张、规模增长和生命周期延长逐步累积的必然结果。从关系型数据库将业务抽象为数据,到高级语言“为数据库套壳”形成应用软件,企业软件正式进入“高级语言+数据库”的长期技术范式。随之而来的是数据模型持续膨胀、业务规则不断叠加、交互逻辑日益复杂、生命周期显著拉长。企业软件不再是一次性交付的工具,而是需要多年演进、持续维护的复杂系统。

传统开发模式在小规模下高效,在规模化后却暴露出结构性瓶颈。组件与框架解决的是“写不写得快”的问题,而不是“能不能长期管控”的问题。当系统进入小团队、不稳定需求、长生命周期的企业软件现实场景时,千人千面的代码实现、高度依赖个人能力的维护方式、难以规模化的工程治理,使系统的复杂度被长期分散在大量命令式代码和个人决策中,缺乏可被平台统一理解、治理和演进的表达形式。这种结构性矛盾会随系统演进持续放大,最终成为企业数字化进程中的隐性成本中心。

低代码正是在这一背景下应运而生的范式跃迁,通过提升业务表达的抽象层级、将工程复杂度内聚到平台层、提供结构化和可视化的统一表达形式,使企业软件的开发从依赖个人能力转向依赖平台能力沉淀,从分散复杂度转向集中可治理的复杂度。

这部分内容将帮助您理解:

  • 企业软件复杂度如何从数据库时代开始逐步累积,最终演变为长期演进的系统性挑战
  • 传统开发模式的结构性瓶颈为何在企业软件规模化后不可避免地暴露
  • 低代码作为范式跃迁,如何回应企业软件在长期演进中面临的根本性问题

开始阅读:第一部分:低代码诞生的背景

第二部分 低代码的概念与发展现状

在实践中,低代码并不存在一个严格统一的定义。不同厂商、不同产品对低代码的理解差异,反映的并非概念混乱,而是低代码本身处于持续演进之中。从现实情况看,低代码首先是一种围绕“降低软件开发综合成本、提升交付可持续性”的价值主张,其次才是一系列具体技术实现方式的集合。它的准确定位是开发工具层级,而非业务系统本身,本质上是将中间件能力、工程规范与开发工具深度融合的平台型产品。

低代码的核心价值并不体现在写代码更少或交付更快等单点指标上,而在于重构企业软件的经济模型。传统模式系统性低估了软件的隐性成本——真正昂贵的不是当初买系统的那一刻,而是之后养系统的全过程。低代码通过成本导向(控制变化的长期成本)和成果导向(持续产生业务成果)的结合,改变了企业面对变化时的决策方式。当一次业务规则调整不再等价于一次完整项目,企业才会更主动地将业务意图转化为系统能力。这正是低代码作为商业概念得以成立的根本原因。

理解低代码的多样性,有助于避免将其简单理解为拖拽式工具或代码生成工具,从而形成更加理性的技术预期。

这部分内容将帮助您理解:

  • 为什么低代码更像一种软件经济模型的重构,而非单一技术突破
  • 低代码如何通过成本导向与成果导向,改变企业软件的生产方式
  • 不同低代码形态(面向业务开发者 vs 面向专业开发者)之间的本质差异及其适用边界

开始阅读:第二部分 低代码的概念、价值与发展现状

第三部分 低代码的技术原理与工程基础

企业软件开发的核心矛盾,早已从如何实现功能转向如何长期控制系统演进。当系统规模扩大、生命周期拉长、团队人员流动成为常态时,理解成本、协作成本、变更风险和知识传承断层,逐步超越编码本身,成为制约交付和演进的真正瓶颈。这些问题的根源在于长期积累的业务规则和设计决策,被分散在大量命令式代码和个人经验中,缺乏可被平台统一理解、治理和演进的表达形式。

低代码平台的主流技术路线——元数据驱动,正是对这一问题的正面回应。通过元数据、设计器、运行时三者构成的完整闭环,平台将业务模型、约束规则和系统结构从代码中剥离,以结构化、可验证、可执行的形式加以表达。元数据成为软件行为的唯一决定者,设计器确保元数据生产的质量和一致性,运行时保证执行的可预测性和可观测性。这种架构使系统的长期演进从依赖个人能力,转向依赖可管理的工程资产。

理解低代码的技术原理,有助于认识到它不是黑盒,也不是简单的拼装工具,而是一套面向工程治理的系统性解决方案。

这部分内容将帮助您理解:

  • 企业软件开发的核心矛盾如何从实现问题转向工程治理问题
  • 元数据驱动为何成为低代码的主流技术路线,以及它如何通过结构化表达解决工程治理难题
  • 元数据、设计器、运行时如何协同工作,构成可控、可预测、可演进的完整技术体系

开始阅读:第三部分:低代码的技术原理与工程基础

第四部分 低代码的典型应用场景与价值呈现

低代码的价值,并不体现在“写了多少代码”,而体现在其是否有助于提升组织整体的数字化成熟度。

在不同阶段,低代码的作用并不相同:在早期,它可以降低应用交付门槛;在规模化阶段,它有助于形成统一的系统结构和开发规范;在更高成熟度阶段,它需要与既有架构、数据治理体系和专业开发流程协同工作。

这部分内容将帮助您理解:

  • 低代码在不同成熟度阶段的合理定位
  • 为什么低代码并非越“核心”越合适
  • 如何判断低代码是否正在产生长期价值

开始阅读:第四部分:低代码的典型应用场景与价值呈现

第五部分 低代码应用的管理挑战

低代码的引入往往伴随着组织协作方式和治理结构的变化。如果缺乏相应的管理机制,这种变化可能放大问题而非解决问题。

在实践中,低代码项目的失败往往并非源于技术能力不足,而是源于目标设定偏差、角色分工不清晰以及缺乏统一治理。本章将围绕这些现实问题展开分析。

这部分内容将帮助您理解:

  • 低代码项目为何容易偏离初衷
  • 管理与治理在低代码中的关键作用
  • 如何避免低代码成为零散工具的集合

开始阅读:第五部分:低代码应用的管理挑战

第六部分 AI辅助开发技术与低代码的结合路径

生成式人工智能的出现,并未改变软件工程的基本规律,但为低代码提供了新的工具形态和能力扩展方向。在可预见的阶段内,AI难以一次性完成高复杂度企业系统的完整开发,而低代码恰好提供了一种“可调试、可修正、可解释”的中间形态。

在这一模式下,AI的核心作用并非直接交付最终系统,而是生成和补全元数据,例如页面结构、业务模型、规则草稿和流程骨架。开发人员再通过低代码平台提供的可视化设计界面,对这些结果进行调试、测试和修改。

这部分内容将帮助您理解:

  • 为什么AI需要低代码作为工程载体
  • 如何在AI不完美的前提下实现可控落地
  • 低代码在AI应用治理中的独特价值

开始阅读:第六部分:AI辅助开发技术与低代码的结合路径

总结

低代码并非对专业开发人员的替代,而是一种在既定工程约束下,通过改变开发活动组织方式来提升整体效率和可持续性的实践路径。在 AI 加速到来的背景下,低代码为企业提供了一种更加可控、可解释的技术中间层。

手册将围绕这些问题,不断补充和完善相关内容,欢迎持续关注。