0
点赞
收藏
分享

微信扫一扫

面试题记录

RJ_Hwang 9小时前 阅读 1

一、SQL 执行慢排查与优化方案

1. SQL 执行慢排查步骤

  • 查看执行计划:通过 EXPLAIN 分析 SQL 执行计划,重点关注 type(访问类型,如 ALL 表示全表扫描,性能差)、key(是否使用索引)、rows(预估扫描行数)。
  • 检查索引使用情况:确认是否走索引,是否存在索引失效(见下文 “索引失效原因”)。
  • 分析锁等待:通过 SHOW PROCESSLIST 查看是否有锁阻塞(如行锁、表锁),INFORMATION_SCHEMA.INNODB_LOCKS 查看锁详情。
  • 统计信息更新:表数据变化大时,统计信息过时可能导致执行计划不准,执行 ANALYZE TABLE 更新统计信息。
  • 日志定位:开启慢查询日志(slow_query_log=1),设置 long_query_time 阈值(如 2 秒),记录慢 SQL 进行分析。

2. SQL 优化方案

  • 优化索引:为过滤条件、排序字段、关联字段建立合适索引(见下文 “索引设计原则”)。
  • 改写 SQL
  • 避免 SELECT *,只查询必要字段。
  • 拆分复杂 JOIN,避免多表关联时扫描大表。
  • 用 UNION ALL 替代 OR(索引友好),用 EXISTS 替代 IN(大数据量时)。
  • 分页优化:避免 LIMIT 100000, 10(扫描大量无用数据),可通过主键定位:WHERE id > 100000 LIMIT 10
  • 减少锁冲突:避免长事务,批量操作拆分小批次执行。

二、索引设计原则

  1. 按需创建:只为频繁作为 WHEREORDER BYGROUP BYJOIN ON 的字段建索引。
  2. 联合索引顺序:遵循 “最左前缀原则”,将区分度高的字段放前面(如 WHERE a=? AND b=?,联合索引 (a,b) 优于 (b,a))。
  3. 控制索引数量:每张表索引不超过 5-6 个(索引会降低插入 / 更新性能,占用存储空间)。
  4. 避免冗余索引:如已存在 (a,b),无需再建 (a)(联合索引前缀可单独使用)。
  5. 不适合建索引的场景
  • 字段值重复率高(如 gender,区分度低)。
  • 表数据量小(全表扫描比索引快)。
  • 频繁更新的字段(索引维护成本高)。

三、分表分库方案

1. 分表(单库内拆分)

  • 水平分表(按行拆分):
  • 范围分表:按时间(如 order_2023order_2024)、ID 范围(如 user_0 到 user_9 按 ID 模 10)。
  • 哈希分表:ID 哈希后取模(如 user_{id%10}),适合均匀分布场景。
  • 垂直分表(按列拆分):将大表按字段关联性拆分(如 user 拆分为 user_base(基本信息)和 user_extra(扩展信息))。

2. 分库(多库拆分)

  • 水平分库:同水平分表逻辑,将数据分散到不同库(如按用户 ID 哈希分库,再在库内分表)。
  • 垂直分库:按业务模块拆分(如订单库、用户库、商品库),降低单库压力。

3. 中间件选择

  • 分库分表中间件:ShardingSphere-JDBC(轻量级,客户端模式)、MyCat(代理模式)。
  • 路由策略:通过中间件配置分片规则(如哈希、范围),透明化分库分表逻辑。

四、哈希表扩容

哈希表扩容的核心是解决哈希冲突(如拉链法中链表过长导致查询变慢),步骤如下:

  1. 创建新表:新表容量通常为原表的 2 倍(保证负载因子 loadFactor = 元素数/容量 在合理范围,如 0.7)。
  2. 重新哈希:遍历原表所有元素,按新表容量重新计算哈希值,放入新表对应位置。
  3. 替换引用:扩容完成后,用新表替换原表引用,释放原表内存。
  4. 并发处理
  • 非并发场景:直接扩容,期间暂停读写。
  • 并发场景(如 Java ConcurrentHashMap):采用分段锁,逐段扩容,不阻塞读写。

五、导致索引失效的原因

  1. 函数 / 表达式操作索引字段:如 WHERE SUBSTR(name, 1, 1) = 'a'(无法走 name 索引)。
  2. 隐式类型转换:如 WHERE phone = 13800138000phone 是字符串,转换为数字导致索引失效)。
  3. 否定条件NOT IN!=<>, 可能导致全表扫描(视情况而定)。
  4. LIKE 以通配符开头:如 WHERE name LIKE '%张'(无法走索引),LIKE '张%' 可走索引。
  5. 联合索引不满足最左前缀:如联合索引 (a,b,c),查询 WHERE b=? AND c=? 会失效。
  6. OR 连接非索引字段:如 WHERE a=? OR b=?,若 b 无索引,可能导致全表扫描。

六、Spring Cloud 常用组件及作用

  1. Eureka/Consul/Nacos:服务注册与发现,维护服务地址列表,支持健康检查。
  2. Ribbon:客户端负载均衡,在服务调用时分配请求到不同实例(如轮询、随机)。
  3. Feign:声明式 HTTP 客户端,简化服务间调用(基于 Ribbon,自动集成负载均衡)。
  4. Hystrix:服务熔断与降级,防止依赖服务故障导致级联失败(超时、错误率超阈值时触发)。
  5. Gateway:API 网关,统一入口,处理路由、过滤(如鉴权、日志)、限流。
  6. Config:分布式配置中心,集中管理多环境配置,支持动态刷新。
  7. Sleuth + Zipkin:分布式追踪,记录请求链路,排查跨服务问题。

七、MySQL 与 Oracle 使用区别

维度

MySQL

Oracle

事务隔离级别

默认 REPEATABLE READ

默认 READ COMMITTED

分页语法

LIMIT offset, row_count

ROWNUM 或 FETCH FIRST ... ROWS ONLY(12c+)

自增主键

支持 AUTO_INCREMENT

需通过序列(SEQUENCE)+ 触发器实现

索引类型

主要支持 B + 树,部分引擎支持哈希索引

支持 B + 树、 bitmap、函数索引等

存储引擎

多引擎(InnoDB、MyISAM 等),InnoDB 为主

单一引擎(类似 InnoDB,支持事务)

函数差异

字符串函数:CONCAT()SUBSTRING()

字符串函数:`

(拼接)、SUBSTR()`

锁机制

InnoDB 支持行锁、表锁

支持行锁、表锁、间隙锁,锁机制更复杂

适用场景

互联网、中小规模应用,开源免费

大型企业级应用,收费,稳定性强

八、开发常用注解(Spring + MyBatis)

Spring 注解

  1. 组件注册
  • @Controller/@Service/@Repository/@Component:标识 Spring 组件,纳入 IOC 容器。
  • @RestController:组合 @Controller + @ResponseBody,返回 JSON。
  1. 依赖注入
  • @Autowired:自动注入依赖(按类型,配合 @Qualifier 按名称)。
  • @Resource:JDK 注解,按名称注入。
  1. 事务管理@Transactional:声明事务(见事务回滚相关内容)。
  2. 请求映射@RequestMapping/@GetMapping/@PostMapping:映射 HTTP 请求。
  3. 参数绑定@RequestParam(绑定请求参数)、@PathVariable(绑定 URL 路径变量)、@RequestBody(绑定请求体 JSON)。

MyBatis 注解

  1. SQL 映射@Select/@Insert/@Update/@Delete:直接在接口方法上写 SQL。
  2. 结果映射@ResultMap(引用 XML 中的 resultMap)、@One/@Many(处理一对一 / 一对多关联)。
  3. 参数传递@Param:指定方法参数在 SQL 中的别名(如 @Param("id") Long userId)。

九、Redis 持久化机制

  1. RDB(Redis Database)
  • 原理:在指定时间间隔内,将内存中的数据集快照写入磁盘(二进制文件,如 dump.rdb)。
  • 触发方式:手动执行 SAVE(阻塞)/BGSAVE(后台异步),或配置 save <seconds> <changes> 自动触发。
  • 优点:文件小,恢复快;缺点:可能丢失最后一次快照后的所有数据。
  1. AOF(Append Only File)
  • 原理:记录所有写操作命令到日志文件(文本格式),重启时重新执行命令恢复数据。
  • 配置:appendonly yes 开启,appendfsync 控制刷盘策略(always 实时刷盘,everysec 每秒刷盘,no 由 OS 控制)。
  • 优点:数据安全性高(最多丢失 1 秒数据);缺点:文件大,恢复慢。
  1. 混合持久化(4.0+)aof-use-rdb-preamble yes,AOF 文件开头包含 RDB 快照,兼顾 RDB 的快速恢复和 AOF 的安全性。

十、接口请求很慢排查步骤

  1. 前端排查
  • 检查网络耗时(浏览器 F12 的 Network 面板,看 TTFB(首字节时间)和 Content Download 耗时)。
  • 确认是否前端渲染慢(如大量 DOM 操作)。
  1. 后端排查
  • 接口耗时统计:在接口入口 / 出口打印时间戳,计算总耗时。
  • 分阶段定位
  • 数据库操作:通过日志记录 SQL 执行时间,排查慢查询(见 SQL 慢排查)。
  • 外部服务调用:检查调用第三方接口的响应时间(如 HTTP、RPC)。
  • 代码逻辑:是否有复杂计算、死循环、线程阻塞(用 jstack 分析线程栈)。
  • 资源监控
  • 服务器:CPU、内存、磁盘 IO、网络(topfreeiostat 命令)。
  • JVM:GC 频率、堆内存使用(jstatjmap),是否有频繁 Full GC 导致卡顿。
  • 分布式追踪:若用 Spring Cloud,通过 Sleuth+Zipkin 查看跨服务调用链路,定位哪个服务耗时最长。
  1. 中间件排查
  • 缓存(Redis):检查是否缓存失效导致大量穿透到 DB,或 Redis 响应慢(INFO 命令看 latency)。
  • 消息队列:检查是否队列积压,消费者处理慢导致接口等待。
  1. 优化方向
  • 加缓存(Redis)减轻 DB 压力。
  • 异步化处理非核心逻辑(如消息通知)。
  • 优化 SQL 和索引,减少 DB 耗时。
  • 扩容服务器或数据库(垂直 / 水平扩容)。
举报

相关推荐

0 条评论