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/10/17 16:58:57 阅读更多 →
山海万灵 HarmonyOS 文化知识实战(02):响应式侧栏与多设备内容宽度

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

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

2026/10/15 7:07:53 阅读更多 →
使用Cheat Engine修改《植物大战僵尸》游戏数据的完整指南

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

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

2026/10/17 9:37:17 阅读更多 →

最新新闻

esp-adf环境搭建-基于vscode插件扩展:把settings.json改到TaoToken统一Key通道

esp-adf环境搭建-基于vscode插件扩展:把settings.json改到TaoToken统一Key通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 16:59:03 阅读更多 →
CLI-Anything:命令行原生智能体范式

CLI-Anything:命令行原生智能体范式

1. 项目概述:CLI-Anything 不是又一个命令行工具,而是一套“命令行原生”的智能体交互范式你有没有过这种体验:在终端里敲下git status,心里却想着“要是它能自动告诉我哪些文件该加进暂存区、哪些可能漏了.gitignore规则就好了”…

2026/10/17 16:59:03 阅读更多 →
AI论文工具实测:从选题到答辩的效率与避坑指南

AI论文工具实测:从选题到答辩的效率与避坑指南

每年到了毕业季,总有人在群里问同一个问题:“有没有好用的AI论文工具?求推荐。”问的人多,踩坑的人更多——有人花了几个月时间试了十来个平台,最后发现生成内容既不能用、引用还是编的;也有人被号称“一键…

2026/10/17 16:59:03 阅读更多 →
Superpowers智能编程工具链:本地化AI开发工作流实战指南

Superpowers智能编程工具链:本地化AI开发工作流实战指南

1. 这不是魔法,是开发者正在用的“超能力”工具链最近在几个技术社区和内部开发群聊里,“superpowers”这个词出现频率高得有点反常——它既不是某个新发布的开源框架,也不是某家大厂的神秘项目代号,而是一整套正在被真实工程团队…

2026/10/17 16:59:03 阅读更多 →
AI电销机器人源码部署全指南:从架构拆解到上线调优

AI电销机器人源码部署全指南:从架构拆解到上线调优

简介:这是一份面向智能电销机器人部署的源码项目包,适合具备基础Linux操作经验、希望快速上手安装自动外呼系统的开发者或运维人员,对想了解服务器部署全流程的新手也颇为友好。压缩包共3个文件,以HTML页面承载部署教程&#xff0…

2026/10/17 16:59:03 阅读更多 →
AI辅助专著写作全流程:从选题到定稿的实操指南

AI辅助专著写作全流程:从选题到定稿的实操指南

写一本专著,对绝大多数人来说,第一反应都是“这事太大了”。从选题、搭框架、找文献、写初稿,到来回改格式、统一术语、核对引用,随便哪一环拎出来都够磨掉几个月。更要命的是,很多内容领域里的资深从业者,…

2026/10/17 16:58:03 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →