基于Redis向量数据库的arXiv论文语义搜索引擎实战

news2026/5/16 7:56:31
1. 项目概述构建一个基于语义的学术论文搜索引擎如果你经常在arXiv上找论文肯定有过这样的体验面对海量的预印本用关键词搜索出来的结果要么不相关要么漏掉了真正重要的文献。传统的基于关键词匹配的搜索很难理解“用图神经网络做蛋白质结构预测”和“基于GNN的蛋白质折叠研究”其实是高度相关的。这正是向量搜索技术大显身手的地方。这个项目redis-arXiv-search就是一个将前沿的向量数据库技术与经典的学术搜索场景结合的绝佳示例。它构建了一个完整的、生产就绪的arXiv论文语义搜索API和应用。核心思路很简单将每篇论文的标题和摘要文本通过AI模型转化为一个高维的“向量”可以理解为一串能代表其语义的数字指纹然后存入Redis这个高性能的向量数据库中。当用户用自然语言提问时同样将问题转化为向量并在数据库里快速找出“指纹”最相似的论文。这样一来搜索就从机械的字面匹配升级为了理解语义的智能检索。整个技术栈非常清晰和现代后端用FastAPI提供高性能的APIRedis Stack作为向量数据库引擎RedisVL作为操作Redis的Python客户端前端用React构建交互界面通过Docker Compose一键部署。它原生支持HuggingFace、OpenAI和Cohere三家主流平台的嵌入模型让你可以根据需求、预算和延迟要求灵活选择。无论是想学习如何将大语言模型LLM的嵌入能力与专业向量数据库结合还是希望为自己的知识库或文档系统搭建一个类似的智能搜索原型这个项目都提供了从数据准备、向量化、存储到查询、前端展示的完整闭环代码结构清晰堪称一个教科书级的实战案例。2. 核心架构与组件选型解析2.1 为什么选择Redis Stack作为向量数据库在向量数据库的选型上项目选择了Redis Stack这是一个经过深思熟虑的决定。首先性能是压倒性的优势。Redis本身就是一个基于内存的键值存储其读写速度极快。对于向量搜索这种需要高并发、低延迟的场景内存数据库的优势非常明显。当用户发起一个搜索请求时系统需要实时计算查询向量的K近邻K-NN这个过程涉及大量的向量距离计算如余弦相似度Redis Vector Search模块对此进行了高度优化。其次Redis提供了超越纯向量搜索的能力。Redis Stack集成了RedisJSON、RedisSearch和RedisTimeSeries等模块。这意味着你不仅可以存储和检索向量还可以将论文的元数据如作者、分类、发布日期以JSON格式原生存储在同一个数据库中并利用RedisSearch对这些字段进行复杂的过滤和全文检索。例如你可以轻松实现“找出最近一年内在cs.CL计算语言学分类下与‘注意力机制优化’语义相似的论文”。这种混合查询Hybrid Search能力——结合向量相似度和结构化过滤——是构建复杂搜索应用的关键而Redis在一个引擎内就提供了完整的支持。再者成熟度和运维友好性。Redis拥有超过十年的历史是最流行的数据库之一其稳定性、工具链和社区支持都非常完善。RedisVL这个官方Python库的引入进一步降低了开发门槛它提供了高级的、Pythonic的API来操作向量索引和进行搜索避免了直接使用原始Redis命令的繁琐。注意虽然像Pinecone、Weaviate这样的专职向量数据库在易用性和托管服务上可能有优势但Redis Stack在需要极高性能、已有Redis技术栈、或希望将向量能力与现有缓存/数据结构服务深度集成的场景下是更优的选择。这个项目也展示了如何将Redis“升级”为一个功能强大的向量搜索引擎。2.2 前端与后端技术栈的协同设计项目的整体架构采用了前后端分离的SPA单页面应用模式这是一种现代Web应用的标配能带来更好的用户体验和开发效率。后端Backend以FastAPI为核心。FastAPI是一个现代、快速高性能的Python Web框架特别适合构建API。它自动生成交互式API文档Swagger UI内置了基于Pydantic的数据验证极大地提升了开发效率。在这里FastAPI主要提供两个核心服务一是处理前端的搜索请求与RedisVL交互执行向量搜索二是在开发模式下还能直接托管编译后的React前端静态文件通过spa.py简化了部署流程。Pydantic则用于严格定义API请求和响应的数据模型Schema确保数据类型的正确性这在处理复杂的论文对象时非常有用。前端Frontend使用React with TypeScript构建。TypeScript为JavaScript带来了静态类型检查能在开发阶段就捕获许多潜在的错误对于维护像论文搜索这样数据结构相对复杂的应用非常有益。UI层面混合使用了Material-UI和React-Bootstrap这可能是为了利用两者各自的优势组件快速搭建出美观且功能齐全的界面如搜索框、结果列表、分页器等。通信与部署前后端通过清晰的RESTful API进行通信。在开发时可以分别运行前端开发服务器npm run start端口3000和后端服务器并通过代理解决跨域问题。在生产部署时则通过Docker Compose将前后端、Redis数据库打包在一起实现一键启动。这种设计保证了开发时的灵活性与生产环境的一致性。2.3 多模型嵌入策略的设计考量项目支持HuggingFace、OpenAI和Cohere三家嵌入模型这并非简单的功能堆砌而是针对不同应用场景的务实设计。HuggingFace (sentence-transformers/all-mpnet-base-v2): 这是项目的默认且必选模型。它的最大优势是本地化和零成本。模型可以直接从HuggingFace Hub下载并在本地运行无需网络请求因此速度最快且没有API调用费用。all-mpnet-base-v2是一个在多种语义相似度任务上表现优异的通用模型对于学术文本的语义捕捉能力很强。它是保证项目基础功能随时可用的关键。OpenAI (text-embedding-ada-002): 这是OpenAI提供的嵌入模型。它的优势在于可能因训练数据不同对某些领域或表述方式有更好的理解并且作为云服务无需关心本地计算资源。缺点是会产生API费用且查询延迟受网络影响。适合那些愿意为潜在的性能提升付费或者已经深度集成OpenAI生态的系统。Cohere (embed-multilingual-v3.0): Cohere的模型特别是这个多语言版本在处理多语言查询时具有独特优势。如果你的用户可能会用中文、日文等其他语言搜索英文论文这个模型就能派上用场。它同样是一种云API服务。这种多模型支持架构带来了灵活性。你可以在.env配置文件中轻松切换模型甚至可以根据查询的上下文如检测到用户输入为非英语动态选择嵌入提供者。代码中通过抽象出统一的嵌入接口Embedder类使得增加新的提供商如百度文心、阿里通义变得相对容易只需实现对应的接口即可。3. 数据管道与Redis向量索引构建详解3.1 arXiv数据集的处理与准备项目使用的数据来自Kaggle上的一个arXiv论文元数据数据集。这个数据集通常包含每篇论文的ID、标题、作者、摘要、分类和提交日期等信息。原始数据可能是巨大的JSON或CSV文件直接处理效率低下。在/backend/arxivsearch/db/load.py脚本中完成了数据管道的核心工作。其处理流程大致如下数据读取与采样由于arXiv数据集可能包含数百万篇论文首次加载或演示时通常不需要全部数据。脚本会读取数据文件并可能进行随机采样或按时间过滤例如只加载最近几年的论文以控制数据规模和初始化时间。文本清洗与拼接对于每篇论文将标题和摘要这两个最具信息量的文本字段拼接起来形成待编码的文本块。在此之前需要进行基本的清洗如去除过多的换行符、HTML标签如果存在等。分批向量化这是最耗时的步骤。脚本会初始化所选的嵌入模型如HuggingFace模型然后将清洗后的文本分批例如每批100条送入模型生成对应的向量。这里的关键是批处理它能极大提升GPU或CPU的利用效率比单条处理快得多。构建Redis数据结构对于每篇论文我们需要在Redis中创建一条记录。这条记录至少包含两个部分向量字段存储生成的768维或1536维取决于模型浮点数向量。元数据字段以JSON格式存储论文的原始信息如id、title、authors、abstract、categories、update_date等。这些字段将用于后续的过滤和结果显示。一个高效的技巧是使用Redis的pipeline。脚本不会每插入一篇论文就与Redis服务器通信一次而是将一批插入命令缓存在本地然后一次性发送这能减少网络往返开销提升写入速度数倍。3.2 Redis向量索引的创建与配置仅仅把向量存进去还不够要实现快速检索必须在存储前创建合适的向量索引。这是在redis_helpers.py或类似文件中完成的。使用RedisVL库创建索引的配置类似于下面这个JSON结构以HuggingFace的768维模型为例index_schema { index: { name: arxiv_vector_idx, prefix: [doc:], # 键的前缀方便管理 storage_type: hash, # 存储类型 }, fields: [ { name: embedding, # 向量字段名 type: vector, attrs: { dims: 768, # 向量维度 distance_metric: COSINE, # 距离度量余弦相似度 algorithm: FLAT, # 算法这里用精确搜索的FLAT datatype: FLOAT32 } }, { name: title, type: text # 文本字段支持全文检索 }, { name: categories, type: tag # 标签字段用于精确过滤如 categories:{cs.CL} }, { name: update_date, type: numeric # 数字字段可用于范围过滤 }, # ... 其他元数据字段定义 ] }关键参数解析distance_metric: 设置为COSINE余弦相似度。这是文本语义相似度最常用的度量方式它衡量的是向量在方向上的差异而非绝对距离更适合嵌入向量的特性。algorithm: 这里示例用了FLAT即“扁平”索引也称为暴力搜索Brute-Force。它会计算查询向量与索引中所有向量的距离。它的优点是精度100%能返回最准确的结果缺点是当数据量极大时如数千万查询延迟会线性增长。对于演示或百万级以下的数据集FLAT是完全可行的。Redis也支持HNSW分层可导航小世界这种近似最近邻搜索算法它在海量数据下能实现亚秒级检索但会牺牲极少量精度。在真实生产环境中根据数据量在精度和速度间权衡选择算法至关重要。其他字段定义将元数据定义为text、tag、numeric类型是为了后续能利用RedisSearch的强大过滤能力。例如在搜索时可以轻松附加查询条件categories:{cs.AI} update_date:[20230101 20241231]意为“在人工智能分类下且更新时间在2023年至2024年之间的论文”。创建索引后再写入数据Redis会自动为这些字段建立内部的数据结构以支持快速检索和过滤。4. 搜索API的实现与高级查询技巧4.1 核心搜索接口的拆解后端的主要逻辑集中在/backend/arxivsearch/api/routes/papers.py中。核心的搜索接口例如/api/search通常接收以下参数query: 用户输入的自然语言查询字符串。top_k: 返回最相似结果的数量默认为10。category_filter(可选): 用于按论文分类过滤如cs.CL。year_range(可选): 用于按年份范围过滤。接口内部的处理流程如下查询向量化使用配置好的嵌入模型将query字符串转化为一个向量。构建RedisVL查询对象这是最关键的一步。你需要构建一个混合查询Hybrid Query。from redisvl.query import VectorQuery # 1. 基础向量查询 vector_query VectorQuery( vectorquery_vector, # 上一步生成的查询向量 vector_field_nameembedding, # 向量字段名 num_resultstop_k, return_fields[id, title, authors, abstract, categories, update_date, score] # 指定返回的字段 ) # 2. 添加过滤条件如果存在 filter_expression [] if category_filter: filter_expression.append(fcategories:{{{category_filter}}}) if year_range: start_year, end_year year_range filter_expression.append(fupdate_date:[{start_year}0101 {end_year}1231]) if filter_expression: # 将过滤条件以字符串形式附加到查询中 vector_query.set_filter( .join(filter_expression))执行搜索使用RedisVL客户端在指定的索引上执行这个查询。results client.search(vector_query)结果处理与返回Redis返回的结果包含论文的元数据和相似度分数score。分数通常在0到1之间对于余弦相似度越接近1表示越相似。后端需要将这些结果序列化通常通过Pydantic模型并返回给前端。4.2 混合搜索与结果排序策略单纯的向量相似度搜索有时会返回相关性高但过于“陈旧”的论文或者用户明确想找某个子领域的研究。这时混合搜索就显示出威力。如上所示通过在向量查询上附加filter可以精确控制搜索范围。更高级的策略是加权混合搜索Weighted Hybrid Search虽然RedisVL当前版本可能不直接支持复杂的权重融合但我们可以通过业务逻辑实现一种简化版先进行严格的向量相似度搜索然后在结果池中根据元数据进行二次排序或过滤。例如可以给近期发表的论文一个时间权重加分将最终得分调整为相似度分数 * 0.7 时间新鲜度权重 * 0.3然后再重新排序。这需要在后端代码中实现自定义的排序逻辑。另一个实用技巧是查询扩展Query Expansion。对于过于简短的查询如“transformer”直接搜索可能结果太泛。可以在后端对查询进行轻微扩展例如利用同义词库或LLM生成几个相关的查询词分别进行向量搜索然后合并去重。这能有效提升召回率。实操心得在调试搜索效果时不要只看前几条结果。准备一个包含不同领域、不同表述方式的查询测试集并人工评估前10条结果的总体相关性。调整top_k参数比如从10调到20或50有时能发现真正相关的论文可能排在第15位这提示你可能需要优化嵌入模型或引入混合搜索策略。5. 前端交互与结果展示优化5.1 构建响应式搜索界面前端/frontend/src/views/下的组件负责构建用户界面。核心组件通常包括SearchBar.tsx: 一个包含输入框、分类下拉选择器、年份范围选择器以及搜索按钮的表单组件。它负责收集用户的搜索意图。SearchResults.tsx: 用于展示搜索结果的列表组件。它会接收从后端API返回的论文数组并以卡片或列表的形式渲染每篇论文的标题、作者、摘要片段、分类和相似度分数。Pagination.tsx: 如果结果很多分页组件是必要的。虽然向量搜索通常只返回最相关的几十条但良好的用户体验仍需考虑分页。前端通过/frontend/src/api.ts中定义的函数与后端通信。这里会使用fetch或axios库发起HTTP请求。一个健壮的实现需要包含加载状态、错误处理如网络错误、API返回错误和请求取消防止用户快速连续点击搜索的逻辑。交互优化点防抖Debounce在搜索输入框实现防抖。当用户连续输入时不要每次按键都发起搜索而是等待用户停止输入一段时间如300毫秒后再发送请求。这能显著减少不必要的API调用。加载状态反馈发起搜索请求时显示一个旋转的加载图标或骨架屏让用户知道系统正在工作。空结果与错误提示友好地提示“未找到相关论文”或“搜索服务暂时不可用请稍后再试”。5.2 结果列表的信息设计与交互如何展示一篇论文的搜索结果卡片直接影响用户的决策效率。一个好的设计应包含高亮标题标题是论文的核心标识应使用加粗或较大的字体。作者与出处显示主要作者和arXiv ID如arXiv:2307.09288。arXiv ID可以做成链接直接跳转到arXiv官网页面提供无缝体验。智能摘要片段不要显示完整的摘要太长而是显示与用户查询最相关的片段。这需要后端支持在返回结果时不仅返回全文还返回一个“高亮”字段其中摘要里与查询语义最匹配的句子被标记出来。前端可以着重显示这些片段。如果后端没提供前端可以简单截取摘要的前200个字符。分类标签将categories字段如cs.CL, cs.AI渲染成一系列小标签Chip。这不仅美观用户还可以点击某个标签如cs.AI作为新的过滤条件发起一次新的搜索这是一个非常流畅的探索路径。相似度分数可以以进度条、百分比或星级的形式直观展示分数让用户对结果的相关性有个量化感知。操作按钮提供“查看详情”可能弹出模态框显示更多信息、“在arXiv打开”等按钮。前端状态管理对于这样一个相对简单的应用可能不需要引入Redux或Context API进行复杂的状态管理。使用React的useState和useEffect钩子结合组件内部状态或通过Props传递通常就足够了。搜索参数、结果列表、加载状态等可以作为顶级App组件的状态。6. 部署实践与性能调优指南6.1 使用Docker Compose进行一体化部署项目提供的docker-compose.yml文件是部署的关键。它定义了三个服务redis: 基于redis/redis-stack镜像它包含了Redis服务器以及RedisInsight一个可视化管理工具运行在8001端口。数据通过挂载的卷./data:/data进行持久化防止容器重启后数据丢失。backend: 基于包含Python依赖的Dockerfile构建。它依赖redis服务在启动时会运行数据加载脚本如果数据尚未加载然后启动FastAPI服务器。frontend: 通常是通过一个多阶段构建的Dockerfile先在一个Node环境中用npm run build编译React生产版本然后将生成的静态文件位于build目录复制到一个轻量的Nginx或http-server容器中提供服务。运行make deploy或docker-compose up -d后这三个服务会按依赖顺序启动。前端通常映射到主机的80或3000端口后端API映射到另一个端口如8000。这种部署方式将整个应用封装起来与环境隔离保证了从开发到生产环境的一致性。6.2 性能调优与监控要点当数据量增长或并发请求增加时需要考虑性能优化Redis性能内存向量数据库是内存消耗大户。确保宿主机有足够的内存。一个100万条768维向量的索引大约需要1000000 * 768 * 4 bytes ≈ 2.93 GB的内存假设FLOAT32。还要为元数据和Redis本身预留空间。持久化策略根据对数据安全性的要求配置RDB快照和AOF日志。向量数据重新加载非常耗时良好的持久化配置至关重要。连接池在后端应用中使用Redis连接池避免为每个请求创建新连接的开销。API性能嵌入模型延迟这是整个搜索链路中最慢的环节。对于HuggingFace本地模型确保它运行在GPU上如果可用能极大提升速度。对于OpenAI/Cohere API考虑实施请求批处理、缓存Cache和重试机制。可以为常见的查询结果特别是热门查询在Redis或内存中建立短期缓存。异步处理FastAPI天然支持异步。确保向量化、数据库查询等I/O密集型操作使用async/await以提高并发处理能力。分页与限制API应强制对top_k参数设置一个合理的上限如100防止恶意或错误查询拖垮系统。监控与日志为FastAPI接入像Prometheus这样的监控工具收集请求延迟、错误率等指标。在Redis中监控内存使用情况、命令延迟、连接数等。记录详细的应用程序日志包括查询内容、返回结果数量、处理时间等便于问题排查和效果分析。6.3 常见问题与排查实录在实际搭建和运行过程中你可能会遇到以下问题问题1运行make deploy或docker-compose up时后端服务启动失败报错连接不上Redis。排查检查docker-compose.yml中后端服务对Redis的依赖设置depends_on。depends_on只控制启动顺序不保证服务已就绪。Redis启动可能需要几秒钟。需要在后端启动脚本如start.sh中加入健康检查重试逻辑例如循环检测Redis端口6379是否可连接成功后再运行数据加载和启动FastAPI。解决在后端的Dockerfile入口脚本或main.py开头添加一个等待Redis可用的函数。问题2搜索返回的结果相关性很差感觉像是随机返回的。排查首先确认数据是否成功加载。通过RedisInsight访问localhost:8001连接Redis查看arxiv_vector_idx索引下的文档数量是否与预期相符。然后检查嵌入模型是否匹配。如果你在.env中配置了OpenAI模型但加载数据时使用的是HuggingFace模型那么查询向量和存储向量的“语义空间”就不一致导致搜索失效。解决确保数据加载load.py和查询时papers.py使用的是同一个嵌入模型。清理Redis数据用统一的模型重新加载。问题3前端访问localhost:3000页面空白或报JavaScript错误。排查打开浏览器开发者工具查看Console和Network标签页。可能是API请求失败Network中看到对后端API如localhost:8000/api/search的请求返回404或500错误。检查后端服务是否正常运行以及前端api.ts中配置的API基础URL是否正确。CORS错误如果前端和后端运行在不同端口且后端未正确配置CORS浏览器会阻止请求。FastAPI需要使用CORSMiddleware。React编译错误检查frontend目录下是否成功运行了npm install以及npm run build是否有错误。解决根据错误信息逐一排查。确保后端CORS配置允许前端源并检查所有服务的日志输出。问题4数据加载速度非常慢。排查向量化是瓶颈。如果是本地HuggingFace模型检查是否使用了CPU而非GPU。对于大型数据集即使使用GPU全量加载也可能需要数小时。解决使用GPU确保Docker容器可以访问宿主机的GPU需要安装NVIDIA Container Toolkit。增大批处理大小在load.py中增加batch_size参数值但注意不要超出GPU内存。增量加载修改脚本支持从断点续传。记录已处理的论文ID下次运行时跳过。考虑云服务对于超大数据集可以考虑使用OpenAI或Cohere的批量嵌入API它们通常有更高的吞吐量限制。这个项目作为一个功能完备的样板为你探索语义搜索和向量数据库的应用打开了大门。从我个人的实践经验来看最大的收获往往来自于对细节的调整尝试不同的嵌入模型、调整向量索引的算法参数比如从FLAT切换到HNSW并调整其ef_construction和M参数、设计更复杂的混合查询逻辑甚至将用户点击反馈哪些结果被点击了作为信号来优化排序。把这些环节都摸透你就能真正掌握构建下一代智能搜索应用的核心能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2600011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…