ollama v0.32.14正式发布:WebP 自动转码、Qwen 系统消息兼容升级与 llama.cpp、MLX 更新全解析

2026 年 8 月 17 日,ollama 发布 v0.32.14。此次版本更新共包含 5 次提交,涉及 10 个文件,整体变更为 341 行新增、530 行删除。

从更新内容看,v0.32.14 的重点集中在三个方面:

  1. 为 llama-server 增加 WebP 图片转码支持。
  2. 调整 Qwen 渲染器对非首位 system 消息的处理逻辑。
  3. 更新 llama.cpp 与 MLX 依赖版本。

与此同时,该版本还完成了 DeepSeek Harness 集成文档登记,并同步补充了图片、工具调用和 Qwen 渲染相关测试。


一、版本发布信息与整体变更概览

v0.32.14 的发布日期为 2026 年 8 月 17 日。

本次版本的更新说明包含两项核心变化:

  • llm:为 llama-server 转码 WebP 图片。
  • renderers/qwen:容忍不处于开头位置的 system 消息。

从提交记录可以看到,本次版本包含以下类别的变更:

  1. llama-server 的 WebP 图片处理。
  2. Qwen 3.5 与 Qwen 3.8 渲染逻辑调整。
  3. DeepSeek Harness 文档登记。
  4. llama.cpp 版本更新。
  5. MLX 版本更新。
  6. 多模态图片测试调整。
  7. Anthropic 工具路由测试调整。

本次修改涉及的文件包括:

  • LLAMA_CPP_VERSION
  • MLX_VERSION
  • docs/docs.json
  • docs/integrations/deepseek-harness.mdx
  • integration/llm_image_test.go
  • integration/tools_routes_test.go
  • llm/llama_server.go
  • llm/llama_server_test.go
  • model/renderers/qwen35.go
  • model/renderers/qwen38_test.go

其中,integration/llm_image_test.go 的变更量最大,显示为 280 行新增、496 行删除。该大文件差异在展示内容中未默认渲染,因此无法从已给出的内容中进一步确认其具体测试逻辑。


二、llama-server 新增 WebP 图片转码能力

v0.32.14 最核心的一项改动,是 llama-server 对 WebP 图片的处理方式发生变化。

此前,在处理多模态请求时,图片数据会直接进行 Base64 编码并传递。此次更新后,llama-server 会在发送媒体数据前检查图片格式;如果检测到输入为 WebP,则会先解码为图像,再编码为 PNG,最后将 PNG 数据传递给后续请求。

这一逻辑同时覆盖了两条路径:

  1. Completion 请求中的媒体处理。
  2. Chat 消息中的媒体内容处理。

三、Completion 请求中的 WebP 转码流程

llm/llama_server.go 的 Completion 处理逻辑中,原来的实现会直接将 media.Data 进行 Base64 编码:

go 复制代码
mediaData = append(mediaData, base64.StdEncoding.EncodeToString(media.Data))

更新后,这里不再直接对原始媒体数据编码,而是先调用新的处理函数:

go 复制代码
data, err := llamaServerMediaBytes(media.Data)
if err != nil {
    return err
}
mediaData = append(mediaData, base64.StdEncoding.EncodeToString(data))

这段变化体现出新的处理顺序:

  1. 读取原始媒体数据。
  2. 调用 llamaServerMediaBytes
  3. 如果媒体不是 WebP,则返回原始字节。
  4. 如果媒体是 WebP,则转换为 PNG 字节。
  5. 对最终字节进行 Base64 编码。
  6. 将编码结果放入 mediaData

也就是说,Completion 请求中的图片数据在进入 llama-server 多模态请求结构前,会先经过统一的媒体字节处理。

原来的逻辑是:

text 复制代码
原始媒体数据
→ Base64 编码
→ 发送

新的逻辑是:

text 复制代码
原始媒体数据
→ 判断是否为 WebP
→ 如果是 WebP,解码并转为 PNG
→ Base64 编码
→ 发送

对于 PNG、JPEG 或其他非 WebP 数据,处理函数不会进行转码,而是直接原样返回。因此,这项改动的目标非常明确:只针对 WebP 输入进行转换。


四、Chat 消息中的媒体处理同步调整

除了 Completion 路径外,llama-server 的聊天消息转换逻辑也同步做了调整。

llamaServerChatMessage 函数中,原本处理媒体内容的方式是直接追加媒体部分:

go 复制代码
parts = append(parts, llamaServerChatMediaPart(media))

更新后,llamaServerChatMediaPart 的返回类型由单一的映射对象变成了"映射对象加错误":

go 复制代码
part, err := llamaServerChatMediaPart(media)
if err != nil {
    return nil, err
}
parts = append(parts, part)

这一调整意味着媒体转换过程现在可能失败,并且失败会被向上传递。

新的处理流程如下:

  1. 遍历消息中的每一个媒体对象。
  2. 调用 llamaServerChatMediaPart 生成内容部分。
  3. 如果转换失败,直接返回错误。
  4. 如果转换成功,将内容部分追加到 parts
  5. 最终将 parts 写入消息的 content 字段。

这与 WebP 的解码和 PNG 编码有关。因为图片转码本身可能出现错误,例如 WebP 解码失败或 PNG 编码失败,因此函数签名需要返回错误信息。


五、音频与图片的处理分支保持清晰

更新后的 llamaServerChatMediaPart 函数仍然优先检测音频格式:

go 复制代码
if format, ok := AudioFormat(media.Data); ok {
    return map[string]any{
        "type": "input_audio",
        "input_audio": map[string]any{
            "data":   base64.StdEncoding.EncodeToString(media.Data),
            "format": format,
        },
    }, nil
}

从这段逻辑可以确认,音频处理方式没有被 WebP 转码逻辑影响。

如果媒体数据可以识别为音频,函数会返回:

  • typeinput_audio
  • input_audio.data 为原始音频数据的 Base64 编码
  • input_audio.format 为检测到的音频格式

在音频分支中,仍然使用原始 media.Data 进行编码。

图片处理则进入另一个分支:

go 复制代码
data, err := llamaServerMediaBytes(media.Data)
if err != nil {
    return nil, err
}

这里会调用统一的 llamaServerMediaBytes 函数,得到最终要发送的图片数据。

因此,v0.32.14 中的处理结构可以概括为:

text 复制代码
媒体数据
→ 是否为音频
  → 是:按 input_audio 格式发送原始音频数据
  → 否:进入图片处理
       → WebP 转为 PNG
       → 非 WebP 保持原始数据
       → 按 image_url 格式发送

六、图片 MIME 类型检测改为基于最终数据

在 WebP 转码后,图片的 MIME 类型也需要根据转换后的数据重新识别。

原逻辑是直接检测原始数据:

go 复制代码
mime := http.DetectContentType(media.Data)

更新后变为:

go 复制代码
mime := http.DetectContentType(data)

这里的 data 是经过 llamaServerMediaBytes 处理后的结果。

这一区别非常重要。

对于 PNG 图片,data 与原始 media.Data 相同,因此 MIME 类型仍然是 PNG。

对于 WebP 图片,原始数据的 MIME 类型是 image/webp,但经过转码后,data 已经变成 PNG 字节,因此重新检测后得到的 MIME 类型将是 image/png

随后,代码仍保留了原有的兜底处理:

go 复制代码
if !strings.HasPrefix(mime, "image/") {
    mime = "image/jpeg"
}

最终生成的图片内容结构为:

go 复制代码
return map[string]any{
    "type": "image_url",
    "image_url": map[string]any{
        "url": "data:" + mime + ";base64," + base64.StdEncoding.EncodeToString(data),
    },
}, nil

也就是说,image_url.url 中的 MIME 类型和 Base64 数据,现在都以转换后的最终数据为准。

对于 WebP 图片,最终形式将不再是:

text 复制代码
data:image/webp;base64,...

而是 PNG 形式:

text 复制代码
data:image/png;base64,...

七、新增 llamaServerMediaBytes 统一媒体字节处理函数

v0.32.14 新增了 llamaServerMediaBytes 函数,作为 WebP 转码的核心实现。

函数逻辑如下:

go 复制代码
func llamaServerMediaBytes(data []byte) ([]byte, error) {
    if http.DetectContentType(data) != "image/webp" {
        return data, nil
    }

    img, err := webp.Decode(bytes.NewReader(data))
    if err != nil {
        return nil, fmt.Errorf("decode WebP image: %w", err)
    }

    var buf bytes.Buffer
    if err := png.Encode(&buf, img); err != nil {
        return nil, fmt.Errorf("encode WebP image as PNG: %w", err)
    }
    return buf.Bytes(), nil
}

该函数的完整处理逻辑可以分为四步。

第一步,检测媒体类型:

go 复制代码
http.DetectContentType(data)

如果检测结果不是 image/webp,函数直接返回原始数据:

go 复制代码
return data, nil

因此,非 WebP 输入不经过解码和重新编码。

第二步,解码 WebP:

go 复制代码
img, err := webp.Decode(bytes.NewReader(data))

这里使用 WebP 解码器读取原始字节。如果解码失败,返回带有 decode WebP image 描述的错误。

第三步,将图像编码为 PNG:

go 复制代码
var buf bytes.Buffer
if err := png.Encode(&buf, img); err != nil {
    return nil, fmt.Errorf("encode WebP image as PNG: %w", err)
}

代码将解码得到的图像对象写入内存缓冲区,并以 PNG 格式编码。

第四步,返回 PNG 字节:

go 复制代码
return buf.Bytes(), nil

通过这一函数,WebP 转 PNG 的行为被集中封装,Completion 和 Chat 两类请求都复用同一套逻辑。


八、新增 WebP 相关依赖

为了实现 WebP 图片解码,llm/llama_server.go 新增了以下导入:

go 复制代码
"image/png"

以及:

go 复制代码
"golang.org/x/image/webp"

其中:

  • image/png 用于将解码后的图片编码为 PNG。
  • golang.org/x/image/webp 用于解码 WebP 图片。

原有的 bytesbase64http 等能力共同参与了转码后的数据组织过程。

新的依赖组合对应完整链路:

text 复制代码
WebP 原始字节
→ bytes.NewReader
→ webp.Decode
→ 图像对象
→ png.Encode
→ PNG 字节缓冲区
→ Base64 编码
→ data URL

九、llama-server 媒体测试同步扩展

llm/llama_server_test.go 中,媒体转换测试进行了扩展。

测试首先准备了四类媒体数据:

go 复制代码
png := []byte("\x89PNG\r\n\x1a\n")
webp, err := base64.StdEncoding.DecodeString("UklGRhwAAABXRUJQVlA4TA8AAAAvAAAAAAcQ/Y/+ByKi/wEA")
wav := []byte("RIFF\x00\x00\x00\x00WAVE")
mp3 := []byte("ID3\x04\x00\x00")

也就是说,测试覆盖:

  1. PNG 图片。
  2. WebP 图片。
  3. WAV 音频。
  4. MP3 音频。

消息媒体数组从原来的三项变成四项:

go 复制代码
Media: []MediaData{
    NewMediaData(0, png),
    NewMediaData(1, webp),
    NewMediaData(2, wav),
    NewMediaData(3, mp3),
},

加上文本内容后,预期消息内容部分总数由四个调整为五个:

go 复制代码
if !ok || len(parts) != 5 {
    t.Fatalf("expected five content parts, got %#v", msg["content"])
}

这里的五个部分对应:

  1. 文本内容。
  2. PNG 图片。
  3. WebP 转换后的 PNG 图片。
  4. WAV 音频。
  5. MP3 音频。

十、PNG 图片保持原样的测试验证

测试明确验证了 PNG 图片不会被不必要地修改。

对应断言为:

go 复制代码
if parts[1]["type"] != "image_url" {
    t.Fatalf("expected image_url for PNG, got %#v", parts[1])
}

随后,测试检查生成的 URL 是否完全等于原始 PNG 数据的 Base64 结果:

go 复制代码
if imageURL := parts[1]["image_url"].(map[string]any)["url"]; imageURL != "data:image/png;base64,"+base64.StdEncoding.EncodeToString(png) {
    t.Fatalf("expected PNG to pass through unchanged, got %#v", imageURL)
}

该测试确认两件事:

  1. PNG 会被识别为 image_url
  2. PNG 数据保持不变,直接使用原始 PNG 字节进行 Base64 编码。

因此,WebP 转码逻辑并不是对所有图片统一重新编码,而是仅对检测到的 WebP 图片进行转换。


十一、WebP 图片转 PNG 的测试验证

测试新增了对 WebP 图片的检查:

go 复制代码
if imageURL := parts[2]["image_url"].(map[string]any)["url"].(string); !strings.HasPrefix(imageURL, "data:image/png;base64,") {
    t.Fatalf("expected WebP to be converted to PNG, got %q", imageURL)
}

这里验证的是 WebP 图片最终输出的 data URL 前缀。

预期前缀为:

text 复制代码
data:image/png;base64,

而不是 WebP 原始格式。

这直接对应 v0.32.14 的核心变化:当 llama-server 接收到 WebP 图片时,最终传递给下游的数据会是 PNG。

测试并没有要求转码后的 PNG Base64 与某一段固定内容完全一致,而是检查输出 MIME 前缀是否为 PNG。这样可以验证转码结果类型,同时避免将测试绑定到具体编码字节。


十二、音频位置调整后的测试验证

由于新增了 WebP 图片,WAV 和 MP3 音频在内容部分中的索引位置也发生变化。

原来的音频检查逻辑使用:

go 复制代码
part := parts[i+2]

更新后改为:

go 复制代码
part := parts[i+3]

这是因为内容数组中增加了一个 WebP 图片对应的内容部分。

测试仍然遍历两种音频格式:

go 复制代码
for i, want := range []string{"wav", "mp3"} {

并继续验证其类型是否为:

go 复制代码
input_audio

这说明,新增 WebP 图片转码能力后,WAV 和 MP3 的识别与转换路径仍需保持正常。


十三、Qwen 渲染器不再拒绝非首位 system 消息

本次版本的另一项核心改动位于 model/renderers/qwen35.go

此前,Qwen 3.5 渲染器的 validateMessages 函数会检查 system 消息是否处于消息列表第一位。

原来的逻辑如下:

go 复制代码
for i, message := range messages {
    switch message.Role {
    case "system":
        if i != 0 {
            return fmt.Errorf("system message must be at the beginning")
        }
    case "user", "assistant", "tool":
    }
}

这一逻辑意味着:

  • system 消息可以存在。
  • 但 system 消息必须位于第一条消息。
  • 如果 system 消息出现在 user、assistant 或 tool 消息之后,则直接返回错误。
  • 错误内容为 system message must be at the beginning

v0.32.14 删除了这段校验。

删除后,validateMessages 不再因 system 消息没有位于开头而返回错误。

保留的验证逻辑仍然会检查是否存在用户查询。若没有找到用户查询,仍然会返回:

text 复制代码
no user query found in messages

因此,本次调整不是移除所有消息验证,而是专门移除了"system 必须在开头"的限制。


十四、Qwen 3.5 对非首位 system 消息的渲染方式

Render 逻辑中,v0.32.14 对 user 和非首位 system 消息采用同一类渲染处理。

更新后的条件为:

go 复制代码
if message.Role == "user" || (message.Role == "system" && i != 0) {

对于符合该条件的消息,会写入以下结构:

go 复制代码
sb.WriteString(imStartTag + message.Role + "\n" + content + imEndTag + "\n")

也就是说,当 system 消息不处于首位时,会按照消息自身角色写入内容:

text 复制代码
开始标签
system
消息内容
结束标签

从代码可以看到,非首位的 system 消息不再触发验证失败,而是会被写入渲染结果。

这正对应更新说明中的"容忍不处于开头位置的 system 消息"。


十五、Qwen 3.8 对非首位 system 消息增加警告日志

对于 Qwen 3.8 变体,v0.32.14 在渲染非首位 system 消息时增加了日志警告。

相关逻辑为:

go 复制代码
if r.variant == qwen35Renderer38 && message.Role == "system" {
    slog.Warn("non-leading system message", "renderer", "qwen3.8")
}

该逻辑位于非首位 system 消息进入渲染分支之后。

因此,当同时满足以下条件时,会产生警告日志:

  1. 当前渲染器变体是 Qwen 3.8。
  2. 当前消息角色是 system。
  3. 当前 system 消息不是消息列表中的第一条。

日志内容为:

text 复制代码
non-leading system message

日志中还会携带渲染器字段:

text 复制代码
renderer = qwen3.8

需要注意的是,代码在输出警告后仍会继续渲染消息,并不会因此返回错误。

也就是说,Qwen 3.8 对非首位 system 消息的处理方式是:

text 复制代码
检测到非首位 system 消息
→ 输出警告日志
→ 正常写入渲染结果

而不是:

text 复制代码
检测到非首位 system 消息
→ 返回错误
→ 中断渲染

十六、Qwen 3.8 测试移除"晚到的 system 消息"错误用例

model/renderers/qwen38_test.go 中,针对无效对话记录的测试删除了一项用例。

被删除的测试用例名称为:

text 复制代码
late system

该用例原本构造了以下消息顺序:

go 复制代码
messages: []api.Message{
    {Role: "user", Content: "Hello"},
    {Role: "system", Content: "Late"},
},

原本预期得到的错误为:

text 复制代码
system message must be at the beginning

在 v0.32.14 中,这个测试用例被移除,原因与渲染器校验逻辑删除完全一致:非首位 system 消息不再属于需要拒绝的无效输入。

同一测试中,仍保留了"没有用户查询"的错误验证。例如仅包含 system 消息时,仍然预期报错:

text 复制代码
no user query found in messages

由此可以看出,版本调整后的规则是:

  • 缺少 user 查询,仍然是无效情况。
  • system 消息位于非首位,不再是无效情况。
  • Qwen 3.8 在非首位 system 消息场景下会记录警告。
  • 消息仍会继续进入渲染流程。

十七、Anthropic 工具路由测试增加非首位 system 消息

integration/tools_routes_test.go 中,工具路由测试的消息序列增加了一条 system 消息:

go 复制代码
map[string]any{
    "role": "system",
    "content": []any{
        map[string]any{
            "type": "text",
            "text": "Runtime token budget update.",
        },
    },
},

这条 system 消息的位置位于 user 消息之后、assistant 工具调用消息之前。

整体顺序表现为:

text 复制代码
user 消息
→ system 消息
→ assistant 工具调用消息

新增的 system 消息文本为:

text 复制代码
Runtime token budget update.

该测试调整与 Qwen 渲染器对非首位 system 消息的兼容变化相呼应,覆盖了 system 消息并非总是位于会话开头的情况。

从给出的代码片段可以确认,这条 system 消息使用的是文本内容块结构:

go 复制代码
"content": []any{
    map[string]any{
        "type": "text",
        "text": "Runtime token budget update.",
    },
},

十八、llama.cpp 版本更新

v0.32.14 更新了 LLAMA_CPP_VERSION 文件中的版本标识。

旧版本为:

text 复制代码
b10380

新版本为:

text 复制代码
b10434

该文件只有一行变化,即 llama.cpp 版本从 b10380 更新至 b10434

本次发布说明中将其归类为 llama.cpp 更新。


十九、MLX 版本更新

v0.32.14 同时更新了 MLX_VERSION 文件。

旧版本提交标识为:

text 复制代码
3abd0fd6b3eb9d9d3a34cb65e8a2189c57260399

新版本提交标识为:

text 复制代码
adf21deabd32c4fe3726ab2d373ff2165c3f27d6

该文件同样只有一行变化,表示 MLX 依赖版本切换至新的提交标识。

本次更新中,llama.cpp 和 MLX 的版本文件均进行了同步调整。


二十、DeepSeek Harness 集成文档登记

v0.32.14 对文档目录配置进行了更新,在 docs/docs.json 的 integrations 页面列表中加入:

text 复制代码
/integrations/deepseek-harness

该页面被加入到以下集成文档附近:

text 复制代码
/integrations/claude-code
/integrations/opencode
/integrations/deepseek-harness
/integrations/cline-cli
/integrations/codex-app
/integrations/codex

这意味着 DeepSeek Harness 集成页面被正式登记到文档导航结构中。


二十一、DeepSeek Harness 文档中的模型示例调整

docs/integrations/deepseek-harness.mdx 中,文档展示了通过以下命令启动:

shell 复制代码
ollama launch dsh

文档说明:如果需要,ollama 会安装 @deepseek-ai/dsh

在选择模型的示例中,模型列表发生了调整。

更新后的示例为:

shell 复制代码
ollama launch dsh --model qwen3.5
ollama launch dsh --model qwen3.5:cloud
ollama launch dsh --model qwen3.8
ollama launch dsh --model deepseek-v4-flash:cloud

其中,展示内容中体现出的替换关系是:

text 复制代码
qwen3.5
qwen3.5:cloud
qwen3.8
deepseek-v4-flash:cloud

文档在模型示例之后还保留了"无需启动即可配置"的说明入口:

text 复制代码
To configure without starting:

但给出的差异内容未继续展示后续命令或配置内容。


二十二、多模态图片集成测试的大规模调整

integration/llm_image_test.go 在本次版本中出现了较大规模变更。

统计显示,该文件共有:

text 复制代码
280 行新增
496 行删除

由于差异内容较大,展示中标注为默认不渲染,因此无法从当前提供的内容确认具体删除或新增了哪些测试代码。

可以确认的是,该文件属于 LLM 图片集成测试,并且此次 v0.32.14 的核心更新之一正是 llama-server 对 WebP 图片的转码处理。因此,该测试文件的调整与本版本多模态图片相关变更处于同一次更新范围内。

除此之外,展示内容没有给出该文件的具体代码,不能据此确认更多实现细节。


二十三、v0.32.14 主要变化汇总

根据已展示的变更内容,ollama v0.32.14 的重点可以归纳为以下几项。

  1. llama-server 增加 WebP 图片转 PNG 处理。

当媒体数据被识别为 image/webp 时,系统会先进行 WebP 解码,再编码成 PNG。最终发送的图片数据使用 PNG MIME 类型和 PNG Base64 内容。

  1. Completion 与 Chat 两条媒体处理路径均使用转码逻辑。

Completion 请求在组装媒体 Base64 数据前调用统一处理函数。Chat 消息在构建 image_url 内容时也调用同一函数。

  1. PNG 图片保持原样。

测试明确验证 PNG 图片会保持原始数据,不会被重新编码。

  1. 音频处理不受影响。

WAV、MP3 等音频仍通过 input_audio 内容结构发送,使用原始媒体数据进行 Base64 编码。

  1. WebP 转码错误可以向上传递。

由于 WebP 解码或 PNG 编码可能失败,聊天媒体转换函数改为返回内容对象和错误信息。

  1. Qwen 不再拒绝非首位 system 消息。

原有"system 消息必须处于开头"的校验已删除。

  1. Qwen 3.8 会对非首位 system 消息发出警告。

该场景不会阻止渲染,但会输出 non-leading system message 警告,并标记渲染器为 qwen3.8

  1. 工具路由测试加入了 user 消息之后出现 system 消息的场景。

新增的 system 文本是 Runtime token budget update.

  1. llama.cpp 版本从 b10380 更新到 b10434

  2. MLX 版本从 3abd0fd6b3eb9d9d3a34cb65e8a2189c57260399 更新到 adf21deabd32c4fe3726ab2d373ff2165c3f27d6

  3. DeepSeek Harness 集成页面登记到文档导航。

  4. DeepSeek Harness 文档更新了模型启动示例,包括 qwen3.5、qwen3.5:cloud、qwen3.8 与 deepseek-v4-flash:cloud。


二十四、结语

代码地址:github.com/ollama/ollama

ollama v0.32.14 的更新内容虽然集中,但覆盖了多模态输入、消息渲染、依赖版本和集成文档多个部分。

在多模态方面,llama-server 新增 WebP 转 PNG 能力,并通过统一函数覆盖 Completion 与 Chat 两类媒体处理流程。PNG 保持原样,音频仍走原有输入音频逻辑,WebP 则会在传递前完成解码和重新编码。

在 Qwen 渲染方面,非首位 system 消息不再被直接判定为错误。Qwen 3.8 会保留日志警告,但消息可以继续被渲染。对应的测试也删除了此前"晚到 system 消息必须报错"的预期。

此外,版本还更新了 llama.cpp、MLX 的版本标识,登记了 DeepSeek Harness 文档入口,并更新了相关模型启动示例。

相关推荐
Dicky-_-zhang3 小时前
大模型部署架构:从推理引擎到弹性扩缩容的工程实践
java·jvm
vHelios3 小时前
【电商项目】商品搜索开发复盘(1):根据需求拆解搜索接口的设计逻辑
java·微服务·es
Dovis(誓平步青云)4 小时前
DevEco Studio 6.1.1 Windows 安装实录:从下载校验到首次启动
android·开发语言·数据库·人工智能·windows·harmonyos
极创信息4 小时前
国产化信创适配认证高频术语:信创适配、软件自主可控、国产化率、代码溯源率、代码自主率、代码开源率是什么?
java·python·struts·eclipse·开源·php·hibernate
Data_Journal4 小时前
什么是 CAPTCHA,它是如何工作的?
java·大数据·服务器·前端·数据库
Zender Han4 小时前
Flutter 自适应(Adaptive)与响应式(Responsive)设计实践:官方推荐方案详解
android·flutter·ios
mqiqe4 小时前
响应式流中的错误处理:Project Reactor 异常治理全体系
java·架构
我命由我123454 小时前
Android 开发问题:TopAppBar 和 topAppBarColors API is experimental...
android·java·java-ee·kotlin·android studio·android jetpack·android-studio
AC赳赳老秦4 小时前
语义采集进阶实战:利用 OpenClaw AI 语义识别自动提取网页核心信息,无需手动编写选择器
java·运维·服务器·python·信息可视化·deepseek·openclaw
AI人工智能+电脑小能手4 小时前
大白话说Java设计模式-23-桥接模式(源码剖析篇)
java·设计模式·jdbc·桥接模式·源码分析·awt·java logging