Java开发者必备:Elasticsearch核心原理与面试指南
1. 为什么Elasticsearch面试题对Java开发者如此重要Elasticsearch作为当前最流行的分布式搜索和分析引擎已经成为Java开发者必须掌握的核心技能之一。根据2023年Stack Overflow开发者调查Elasticsearch在数据库类别中排名前五超过45%的专业开发者表示在工作中使用过Elasticsearch。对于Java开发者而言掌握Elasticsearch不仅能够提升数据处理能力还能显著增强在求职市场中的竞争力。我在过去三年面试Java中级和高级开发岗位时发现几乎90%的技术面试都会涉及Elasticsearch相关问题。这些问题从基础的原理概念到实际应用场景再到性能优化和问题排查覆盖了开发者对Elasticsearch理解的各个层面。特别值得注意的是随着微服务架构的普及Elasticsearch作为日志收集和分析的核心组件其重要性还在不断提升。2. Elasticsearch核心概念快速入门2.1 基础架构与核心组件Elasticsearch的核心架构设计遵循分布式原则理解这一点对Java开发者至关重要。一个Elasticsearch集群由多个节点(Node)组成每个节点可以承担不同的角色主节点(Master Node)负责集群范围内的轻量级操作如创建/删除索引、跟踪节点状态等数据节点(Data Node)存储数据并执行数据相关操作如CRUD、搜索和聚合协调节点(Coordinating Node)接收客户端请求并将它们路由到适当的节点在Java应用中我们通常通过TransportClient或RestHighLevelClient与Elasticsearch交互。自7.0版本后官方推荐使用基于HTTP的RestClient这更符合现代微服务架构的设计理念。2.2 倒排索引原理倒排索引(Inverted Index)是Elasticsearch高效搜索的核心。与传统的正向索引不同倒排索引建立了从词项到文档的映射关系。例如文档1Java is great 文档2Elasticsearch is powerful 倒排索引 java → [文档1] is → [文档1, 文档2] great → [文档1] elasticsearch → [文档2] powerful → [文档2]这种结构使得Elasticsearch能够快速定位包含特定词项的文档。在Java实现层面Elasticsearch使用Lucene库构建倒排索引通过FST(Finite State Transducer)等数据结构优化存储和查询效率。2.3 分片与副本机制分片(Shard)是Elasticsearch实现水平扩展的基础。创建索引时可以指定主分片(Primary Shard)的数量这个值一旦设置就不能修改除非重建索引。每个分片都是一个完整的Lucene索引可以独立处理查询请求。副本(Replica)则是主分片的拷贝提供数据冗余和高可用性。一个典型的配置可能是PUT /my_index { settings: { number_of_shards: 3, number_of_replicas: 1 } }这意味着数据会被分散到3个主分片上每个主分片有1个副本总共需要6个分片3主3副。在Java客户端中我们可以通过以下代码创建这样的索引CreateIndexRequest request new CreateIndexRequest(my_index); request.settings(Settings.builder() .put(index.number_of_shards, 3) .put(index.number_of_replicas, 1) ); client.indices().create(request, RequestOptions.DEFAULT);3. Java开发者必须掌握的Elasticsearch面试题3.1 基础原理类问题问题1Elasticsearch中的文档(Document)、类型(Type)、索引(Index)和集群(Cluster)之间是什么关系这是面试中最常见的基础问题。在7.x及以后版本中类型(Type)的概念已经被废弃现在一个索引只能包含一种类型_doc。完整的层级关系是集群(Cluster) → 节点(Node) → 索引(Index) → 分片(Shard) → 文档(Document)在Java代码中我们操作文档的基本单元是IndexRequestIndexRequest request new IndexRequest(my_index); request.id(1); // 文档ID String jsonString { \user\:\kimchy\, \postDate\:\2013-01-30\, \message\:\trying out Elasticsearch\ }; request.source(jsonString, XContentType.JSON); IndexResponse response client.index(request, RequestOptions.DEFAULT);问题2Elasticsearch的写操作流程是怎样的写操作(索引/更新/删除)的流程是面试官考察分布式系统理解深度的绝佳问题。完整的流程包括客户端向协调节点发送写请求协调节点通过文档ID的哈希值确定目标主分片请求被转发到主分片所在的数据节点主分片执行本地写操作主分片并行将操作转发到所有副本分片所有副本分片确认成功后主分片向协调节点返回成功协调节点向客户端返回成功在Java客户端中我们可以通过设置一致性级别(consistency)来控制写行为IndexRequest request new IndexRequest(my_index); request.consistency(WriteRequest.ConsistencyLevel.ONE); // 只需要一个分片可用3.2 Java API操作类问题问题3如何使用Java客户端实现批量操作(Bulk)批量操作能显著提升性能是实际项目中的必备技能。Elasticsearch的Java客户端提供了BulkProcessor来简化批量操作BulkProcessor.Listener listener new BulkProcessor.Listener() { Override public void beforeBulk(long executionId, BulkRequest request) { // 批量操作执行前 } Override public void afterBulk(long executionId, BulkRequest request, BulkResponse response) { // 批量操作成功后 } Override public void afterBulk(long executionId, BulkRequest request, Throwable failure) { // 批量操作失败后 } }; BulkProcessor bulkProcessor BulkProcessor.builder( (request, bulkListener) - client.bulkAsync(request, RequestOptions.DEFAULT, bulkListener), listener) .setBulkActions(1000) // 每1000个请求执行一次批量操作 .setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)) // 或每5MB .setFlushInterval(TimeValue.timeValueSeconds(5)) // 或每5秒 .build(); // 添加请求到批量处理器 IndexRequest one new IndexRequest(my_index).id(1) .source(XContentType.JSON, field, value); DeleteRequest two new DeleteRequest(my_index, 2); UpdateRequest three new UpdateRequest(my_index, 3) .doc(XContentType.JSON, field, value); bulkProcessor.add(one); bulkProcessor.add(two); bulkProcessor.add(three); // 最后记得关闭处理器 bulkProcessor.close();问题4如何实现高效的复合查询复合查询是实际业务中最常见的需求。Elasticsearch提供了Bool查询来组合多个查询条件SearchRequest searchRequest new SearchRequest(my_index); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); BoolQueryBuilder boolQuery QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery(content, elasticsearch)) // 必须包含 .filter(QueryBuilders.termQuery(status, published)) // 过滤条件不计算分数 .should(QueryBuilders.termQuery(priority, high)) // 应该包含影响分数 .mustNot(QueryBuilders.rangeQuery(age).lt(18)); // 必须不包含 sourceBuilder.query(boolQuery); sourceBuilder.from(0); // 分页起始 sourceBuilder.size(10); // 每页大小 searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT);3.3 性能优化类问题问题5如何诊断和解决慢查询问题慢查询是生产环境中的常见问题。Elasticsearch提供了多种工具来诊断慢查询开启慢查询日志PUT /my_index/_settings { index.search.slowlog.threshold.query.warn: 10s, index.search.slowlog.threshold.query.info: 5s, index.search.slowlog.threshold.fetch.warn: 1s, index.search.slowlog.threshold.fetch.info: 500ms }使用Profile API分析查询执行细节SearchRequest searchRequest new SearchRequest(my_index); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.profile(true); sourceBuilder.query(QueryBuilders.matchQuery(content, elasticsearch)); searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT); MapString, ProfileShardResult profileResults response.getProfileResults();常见优化手段包括使用filter代替query进行不计算分数的过滤避免使用通配符查询合理使用分页避免深度分页为常用过滤字段添加doc_values问题6如何设计索引映射(Mapping)以获得最佳性能合理的映射设计对性能影响巨大。以下是一些关键建议明确字段类型避免动态映射CreateIndexRequest request new CreateIndexRequest(my_index); request.mapping( {\n \properties\: {\n \title\: {\n \type\: \text\,\n \analyzer\: \ik_max_word\,\n \search_analyzer\: \ik_smart\\n },\n \publish_date\: {\n \type\: \date\\n },\n \rating\: {\n \type\: \double\\n }\n }\n }, XContentType.JSON );对于不参与搜索的字段设置index为falsemetadata: { type: keyword, index: false }对于数值范围查询较多的字段考虑使用keyword而不是numeric类型age: { type: keyword }4. 从入门到精通的实战路线4.1 开发环境搭建对于Java开发者我推荐以下开发环境配置Elasticsearch安装下载官方压缩包https://www.elastic.co/downloads/elasticsearch解压后运行bin/elasticsearchWindows运行elasticsearch.bat验证http://localhost:9200Java项目依赖dependency groupIdorg.elasticsearch.client/groupId artifactIdelasticsearch-rest-high-level-client/artifactId version7.17.0/version /dependency初始化客户端RestHighLevelClient client new RestHighLevelClient( RestClient.builder( new HttpHost(localhost, 9200, http) ) );4.2 典型业务场景实现场景1商品搜索系统// 创建商品索引 CreateIndexRequest request new CreateIndexRequest(products); request.mapping( {\n \properties\: {\n \name\: {\n \type\: \text\,\n \analyzer\: \ik_max_word\\n },\n \price\: {\n \type\: \double\\n },\n \category\: {\n \type\: \keyword\\n },\n \attributes\: {\n \type\: \nested\\n }\n }\n }, XContentType.JSON ); client.indices().create(request, RequestOptions.DEFAULT); // 商品搜索 SearchRequest searchRequest new SearchRequest(products); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); BoolQueryBuilder boolQuery QueryBuilders.boolQuery() .must(QueryBuilders.matchQuery(name, 手机)) .filter(QueryBuilders.rangeQuery(price).gte(1000).lte(5000)); sourceBuilder.query(boolQuery); sourceBuilder.aggregation(AggregationBuilders.terms(categories).field(category)); searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT);场景2日志分析系统// 日志索引模板 PutIndexTemplateRequest request new PutIndexTemplateRequest(logs_template); request.patterns(Arrays.asList(logs-*)); request.mapping( {\n \properties\: {\n \timestamp\: {\n \type\: \date\\n },\n \level\: {\n \type\: \keyword\\n },\n \message\: {\n \type\: \text\\n },\n \service\: {\n \type\: \keyword\\n }\n }\n }, XContentType.JSON ); request.settings(Settings.builder() .put(index.number_of_shards, 3) .put(index.number_of_replicas, 1) ); client.indices().putTemplate(request, RequestOptions.DEFAULT); // 日志分析查询 SearchRequest searchRequest new SearchRequest(logs-*); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.boolQuery() .must(QueryBuilders.rangeQuery(timestamp) .gte(now-1d/d) .lte(now/d)) .filter(QueryBuilders.termsQuery(level, ERROR, WARN)) ); sourceBuilder.aggregation(AggregationBuilders.terms(services).field(service) .subAggregation(AggregationBuilders.terms(levels).field(level)) ); searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT);4.3 高级特性掌握特性1索引生命周期管理(ILM)// 创建生命周期策略 PutLifecyclePolicyRequest request new PutLifecyclePolicyRequest( new LifecyclePolicy(logs_policy, 30d, // 热阶段 new Phase(warm, TimeValue.timeValueDays(60), null), // 暖阶段 new Phase(cold, TimeValue.timeValueDays(90), null), // 冷阶段 new Phase(delete, TimeValue.timeValueDays(365), null) // 删除阶段 ) ); client.indexLifecycle().putLifecyclePolicy(request, RequestOptions.DEFAULT); // 应用策略到索引模板 PutIndexTemplateRequest templateRequest new PutIndexTemplateRequest(logs_template); templateRequest.settings(Settings.builder() .put(index.lifecycle.name, logs_policy) .put(index.lifecycle.rollover_alias, logs) ); client.indices().putTemplate(templateRequest, RequestOptions.DEFAULT);特性2跨集群搜索(CCR)// 配置跨集群连接 Settings settings Settings.builder() .put(cluster.remote.cluster_two.seeds, other_cluster_host:9300) .build(); // 跨集群查询 SearchRequest searchRequest new SearchRequest(cluster_two:remote_index); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.matchAllQuery()); searchRequest.source(sourceBuilder); SearchResponse response client.search(searchRequest, RequestOptions.DEFAULT);5. 常见问题排查与性能优化5.1 集群健康问题问题现象集群状态为RED或YELLOW排查步骤检查集群健康状态ClusterHealthRequest request new ClusterHealthRequest(); request.timeout(TimeValue.timeValueSeconds(30)); ClusterHealthResponse response client.cluster().health(request, RequestOptions.DEFAULT); String status response.getStatus().name(); // GREEN, YELLOW, RED查看未分配的分片原因ClusterAllocationExplainRequest explainRequest new ClusterAllocationExplainRequest(); explainRequest.index(my_index); explainRequest.shard(0); explainRequest.primary(true); ClusterAllocationExplanation explanation client.cluster() .allocationExplain(explainRequest, RequestOptions.DEFAULT); String explanationText explanation.getExplanation();常见解决方案磁盘空间不足清理旧索引或扩容磁盘分片分配设置错误调整cluster.routing.allocation设置节点故障修复或替换故障节点5.2 查询性能优化优化案例商品搜索接口响应慢优化步骤使用Profile API分析查询瓶颈检查是否使用了昂贵的查询如通配符、模糊查询确认分片数量是否合理建议每个分片大小在10-50GB添加适当的缓存SearchRequest searchRequest new SearchRequest(products); SearchSourceBuilder sourceBuilder new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.matchQuery(name, 手机)); sourceBuilder.requestCache(true); // 启用查询缓存 searchRequest.source(sourceBuilder);考虑使用异步查询SearchRequest searchRequest new SearchRequest(products); // 构建查询... client.searchAsync(searchRequest, RequestOptions.DEFAULT, new ActionListenerSearchResponse() { Override public void onResponse(SearchResponse searchResponse) { // 处理结果 } Override public void onFailure(Exception e) { // 处理错误 } });5.3 JVM调优建议Elasticsearch是Java应用合理的JVM配置对稳定性至关重要堆内存设置不超过物理内存的50%不超过32GB避免指针压缩失效Xms和Xmx设置为相同值GC调优JDK 8使用CMS或G1-XX:UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction75 -XX:UseCMSInitiatingOccupancyOnlyJDK 11默认G1即可监控JVM状态NodesStatsRequest nodesStatsRequest new NodesStatsRequest(); nodesStatsRequest.addMetric(NodesStatsRequest.Metric.JVM.metricName()); NodesStatsResponse response client.nodes().stats(nodesStatsRequest, RequestOptions.DEFAULT); for (NodeStats nodeStats : response.getNodes()) { JvmStats jvmStats nodeStats.getJvm(); long heapUsed jvmStats.getMem().getHeapUsed().getBytes(); long heapMax jvmStats.getMem().getHeapMax().getBytes(); }6. 学习资源与进阶路线6.1 推荐学习路径入门阶段1-2周官方文档https://www.elastic.co/guide/index.html掌握基本CRUD操作理解倒排索引原理中级阶段2-4周深入查询DSL学习聚合分析掌握Java High Level Client高级阶段4-8周集群管理与调优索引生命周期管理跨集群搜索6.2 实战项目建议电商搜索系统实现商品全文搜索添加分类聚合和筛选实现搜索建议(Completion Suggester)日志分析平台搭建ELK栈设计日志索引模板实现异常日志告警应用性能监控(APM)集成Elastic APM追踪慢事务分析性能瓶颈6.3 认证与职业发展Elastic官方提供以下认证Elastic Certified EngineerElastic Certified AnalystElastic Certified Observability Engineer准备认证的建议完成官方培训课程在测试环境反复练习参加模拟考试对于Java开发者我建议先专注于Elastic Certified Engineer认证这能验证你对Elasticsearch核心功能的掌握程度也是许多企业对Elasticsearch开发岗位的基本要求。

相关新闻

Azure Stack Hub 云恢复:从灾难性数据丢失到 Scale Unit 重建的多阶段实战

Azure Stack Hub 云恢复:从灾难性数据丢失到 Scale Unit 重建的多阶段实战

未经同意,请勿转载!本文以 Azure Stack Hub 云恢复(Cloud Recovery) 为主线 —— 从"什么样的灾难需要云恢复"出发,厘清"灾难性数据丢失 vs 硬件不可恢复"两种场景的差异,再到多阶段恢…

2026/8/3 5:40:44 阅读更多 →
山海万灵 HarmonyOS 文化知识实战(02):响应式侧栏与多设备内容宽度

山海万灵 HarmonyOS 文化知识实战(02):响应式侧栏与多设备内容宽度

把“放大页面”改成“重算可用空间” 文化知识应用的首页同时容纳探索路线、统计卡片、地图和底部导航。手机上最重要的是让单手浏览的内容不拥挤;屏幕变宽后,如果仍把全部区域按比例拉伸,卡片之间会出现大块空白,正文也会变成难…

2026/8/3 5:40:44 阅读更多 →
使用Cheat Engine修改《植物大战僵尸》游戏数据的完整指南

使用Cheat Engine修改《植物大战僵尸》游戏数据的完整指南

1. 为什么选择Cheat Engine修改《植物大战僵尸》作为一款经典的塔防游戏,《植物大战僵尸》凭借其独特的玩法和幽默的风格风靡全球。但对于部分玩家来说,反复挑战同一关卡可能会感到枯燥,这时候使用Cheat Engine(简称CE&#xff09…

2026/8/3 5:40:44 阅读更多 →

最新新闻

Open-Golf游戏性能优化实战:从算法到渲染的全面调优指南

Open-Golf游戏性能优化实战:从算法到渲染的全面调优指南

1. 项目概述:为什么Open-Golf的性能优化值得深挖?最近在社区里看到不少朋友在讨论一个叫Open-Golf的开源迷你高尔夫游戏项目,也看到很多人在搜索“C语言文件读写操作代码”、“JVM性能优化”这些看似不相关的词。这让我想起自己几年前参与一个…

2026/8/3 6:33:08 阅读更多 →
位运算实现字符唯一性检测的高效算法

位运算实现字符唯一性检测的高效算法

1. 位运算在字符唯一性判断中的应用原理位运算(Bitwise Operation)是直接对整数在内存中的二进制位进行操作的一类运算方法。在字符唯一性判断场景中,位运算能够以O(1)的时间复杂度完成单个字符的状态记录,相比传统哈希表等数据结…

2026/8/3 6:33:08 阅读更多 →
黑苹果免驱网卡魔改:BCM94360Z4刷写苹果蓝牙固件实战指南

黑苹果免驱网卡魔改:BCM94360Z4刷写苹果蓝牙固件实战指南

1. 项目概述:从一张“废卡”到完美免驱的蜕变如果你也像我一样,是个热衷于折腾黑苹果的玩家,那么对“免驱网卡”这四个字一定有着近乎执念的追求。原装拆机卡价格高昂且真假难辨,市面上那些号称“免驱”的第三方卡,要么…

2026/8/3 6:33:08 阅读更多 →
Excel COUNTIF函数:从原理到实战,高效查找与处理重复数据

Excel COUNTIF函数:从原理到实战,高效查找与处理重复数据

1. 项目概述:为什么COUNTIF是处理重复数据的“瑞士军刀”在日常的数据处理工作中,尤其是在处理客户名单、库存清单、员工信息表这类表格时,最让人头疼的问题之一就是数据重复。你可能遇到过这样的情况:从不同部门汇总来的销售记录…

2026/8/3 6:33:08 阅读更多 →
8K 180° 3D VR视频播放全攻略:从格式解析到DeoVR实战优化

8K 180° 3D VR视频播放全攻略:从格式解析到DeoVR实战优化

这次我们来看一个专门为VR设备优化的沉浸式视频项目。这个项目不是传统意义上的软件工具或AI模型,而是一系列精心制作的8K分辨率、180度分屏的3D VR视频内容,主要适配DeoVR等主流VR视频播放器。如果你拥有VR眼镜,并且厌倦了低分辨率或2D平面的…

2026/8/3 6:33:08 阅读更多 →
YOLOv5模型CPU部署实战:基于OpenVINO 2022的C++推理优化指南

YOLOv5模型CPU部署实战:基于OpenVINO 2022的C++推理优化指南

1. 项目概述与核心价值最近在做一个工业质检的项目,客户现场的环境比较特殊,服务器是Intel的Xeon CPU,没有独立GPU,但要求推理速度必须满足产线节拍。我们模型用的是YOLOv5s,在PyTorch下训练好的。一开始尝试用ONNX Ru…

2026/8/3 6:32:08 阅读更多 →

日新闻

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

PC服务器具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构一、前言:具身智能需要“混合算力闭环系统”传统人工智能依赖云端静态数据集训练,不具备物理交互能力,无法适应真实世界的不确定性。具身智能(Embodied…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

前言构建机器人、具身智能这类分布式实时系统,通信底座直接决定整套系统的实时性、容错性、组网能力。分布式领域长期存在 4 类经典通信架构:点对点模式、Broker 中间代理模式、广播模式、以数据为中心(DDS)模式。很多开发者疑惑&…

2026/8/3 0:00:47 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/3 4:58:13 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/3 4:36:35 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/2 6:34:16 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/3 5:19:38 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/2 0:23:22 阅读更多 →