三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

解题思路

  • 先排序
  • 双层循环
    • 外层遍历作为第一个数的选择
    • 内层通过左右指针往内靠,找到另外两个数
  • 不管是内外层,重复的出现的数都跳过不计算

算法:无重复字符的最长连续子串

通过滑动窗口实现,但需要注意是窗口内不能出现重复字符

实现思路

  • 通过双指数构建一个滑动窗口,以及map集合判断重复性
  • 将string转化为[]rune, 兼容字符串可能包含汉字的问题
  • 窗口更新条件
    • 无重复字符时,right一直向右移动
    • 出现重复字符时,需要判断重复字符的旧key是否存在于窗口内
      • 存在窗口内,才被判断为当前窗口内的重复
    • 一旦窗口变大,直接更新窗口最大值或者最大窗口的起始结束位置

代码实现

js
func lengthOfLongestSubstring(s string) int { runes := []rune(s) // 支持 Unicode(中文等) lastIndex := make(map[rune]int) left := 0 maxLen := 0 for right, ch := range runes { if prev, exists := lastIndex[ch]; exists && prev >= left { left = prev + 1 } lastIndex[ch] = right if currLen := right - left + 1; currLen > maxLen { maxLen = currLen } } return maxLen }

rag篇

如何评估一个rag系统的好坏

  • 首先是检索相关性(找到的内容是否包含答案)
  • 其次是生成质量,这又可以细分为
    • 语义准确性(回答的意思是否正确)
    • 词汇匹配度(专业术语是否使用得当)

如果优化rag

  • 在性能层面,可以通过以下方式来提升效率和能力边界。
    • 索引分层(对高频数据启用缓存)
    • 多模态扩展(支持图像/表格检索)
  • 在架构层面,简单的线性流程正在被更复杂的设计模式所取代
    • 通过分支模式并行处理多路检索
    • 或通过循环模式进行自我修正

embedding 模型的作用是什么

将文本映射到一个能够表达语义信息的向量空间中,使语义相似的文本在向量空间中的距离更近。

  • 示例解释
    • 苹果手机多少钱和iphone的价格是多少
    • 虽然文字字面不同,但是语义是相同的
    • 转为向量后,向量距离会很近

prompt、rag、skill和微调的区别

  • promt 的目标是如何用好llm现有的能力
  • rag 是通过外部知识库,来解决llm 无法获取实时信息的问题
  • 微调 是调整底层具备的能力、风格,是模型群众的重塑
  • skill 的话是行为能力的一种延伸

如何选择

  • 当你在工程落地中面临选择时,可以依次问自己以下几个问题:
  • 模型现有的知识和能力够用吗?
    • 够用 ➡️ 提示工程。
  • 不够用,是因为缺乏特定/实时的垂直知识吗?
    • 是,需要看文档 ➡️ RAG。
  • 不够用,是因为需要做数学计算、数据库查询等具体动作吗?
    • 是,需要连外部系统 ➡️ Skill / Tool Calling。
  • 模型什么都知道,但怎么和它说它都不听话、格式总是对不齐、或者想要极致的特定文风?
    • 是,必须改造行为 ➡️ 微调。

Go 语言仓储模式(Repository Pattern)落地指南

一、 核心架构图

仓储模式的核心思想是解耦业务底层存储。业务层通过接口与数据层交互,实现“铁打的业务,流水的技术”。

二、 标准目录结构

在 Go 项目中,通常结合 internal 目录限制外部非法引入,结构如下:

text
my-project/ ├── domain/ # 【领域层】最核心,完全纯粹,无外部技术/数据库依赖 │ ├── user.go # 用户实体、业务方法、以及 UserRepository 接口 │ └── errors.go # 领域层的通用业务错误(如 ErrUserNotFound) │ ├── internal/ # 【实现层】私有封装,防依赖污染,允许大胆重构 │ ├── repository/ # 仓储实现层 │ │ └── mysql_user.go # 实现 domain.UserRepository 接口,内含 GORM/SQL 逻辑 │ │ │ ├── service/ # 业务逻辑/应用层 │ │ └── user_service.go # 组合各种 domain 接口完成具体的业务流水线 │ │ │ └── delivery/http/ # 传输层/接口层(如 Gin 路由、HTTP Handler) │ └── handler.go │ └── main.go # 【入口】组装全局依赖(依赖注入),启动服务

核心原则

Agent 不可能完全避免报错,关键在于:

让错误可恢复(Recoverable)、可观测(Observable)、可控制(Controllable)。

标准处理流程:

text
报错发生 ↓ 识别错误类型 ↓ 判断是否可重试 ↓ 自动修复或降级 ↓ 记录日志 ↓ 必要时转人工

GPM模型

  • G:go中的协程
  • M: 系统线程,真正执行go代码的地方
  • P:调度上下文,保存本地G队列以及调度运行所需的资源,M必须绑定一个P 才能执行go代码 在Go中,线程是运行goroutine的实体,调度器的功能是把可运行的goroutine分配到工作线程上 image.png
  1. 全局队列(Global Queue):存放等待运行的G。
  2. P的本地队列:同全局队列类似,存放的也是等待运行的G,存的数量有限,不超过256个。新建G'时,G'优先加入到P的本地队列,如果队列满了,则会把本地队列中一半的G移动到全局队列。
  3. P列表:所有的P都在程序启动时创建,并保存在数组中,最多有GOMAXPROCS(可配置)个。
  4. M:线程想运行任务就得获取P,从P的本地队列获取G,P队列为空时,M也会尝试从全局队列拿一批G放到P的本地队列,或从其他P的本地队列偷一半放到自己P的本地队列。M运行G,G执行之后,M会从P获取下一个G,不断重复下去。 image.png

面试总结

面试介绍总结:百度poi商业化数据清洗平台(架构级别描述)

项目描述 or 项目定位

主要负责地图 商业化POI 数据清洗,平台整体是一个多阶段的数据处理流水线。数据以文件形式在各个处理环节之间流转,每一步都会读取上一步的结果文件进行处理,并生成新的结果文件。整个流程包括数据请求、结构解析、diff判断、策略判重、人工审核以及数据上线等

做了哪些数据库相关的优化

  • 性能优化

    • 解决数据量激增需要面临的分库分表问题
      • 从mysql迁移到百度的gaiaDB,增加读写分离
        • 增加只读节点
          • 把大量查询请求从 RW(Read Write)节点分流出去,
          • 让 RW 专注于写事务和少量必须读取最新数据的查询,
          • 从而提升整个集群的吞吐能力
  • gaiaDB优势:

    • 通过数据库代理统一管理连接池、读写分离、故障切换、读写分离
    • 无需分库分表
    • 采用存储和计算分离架构,单实例最大数据量超 500TB,存储自动扩容
    • 支持列存索引,实现复杂查询性能相比MySQL提升100倍以上
    • 支持按需扩展、按需付费,综合成本降低50%
  • 索引优化

    • explain 判断是否使用索引、索引类型、扫描多少行、连接方式、是否需要排序、是否使用临时表等。
      • type 的常见值
      type含义好坏
      const主键唯一查询⭐⭐⭐⭐⭐
      eq_ref主键关联⭐⭐⭐⭐⭐
      ref普通索引⭐⭐⭐⭐
      range范围查询⭐⭐⭐
      index全索引扫描⭐⭐
      ALL全表扫描
      • key 使用了那个索引
      • extra
        • use index
        • use where
        • use tempory
        • use filesort
  • sql优化

    • 接口响应优化从23s到 300ms的实现
    • sql LIMIT offset, size查询导致的频繁扫表问题