当前位置: 首页 > ds >正文

Java 语言特性(面试系列2)

一、SQL 基础

1. 复杂查询
(1)连接查询(JOIN)
  • 内连接(INNER JOIN):返回两表匹配的记录。
    SELECT e.name, d.dept_name
    FROM employees e
    INNER JOIN departments d ON e.dept_id = d.dept_id;

    左连接(LEFT JOIN):返回左表所有记录,右表无匹配时补 NULL。

    SELECT e.name, p.project_name
    FROM employees e
    LEFT JOIN projects p ON e.emp_id = p.lead_emp_id;

    多表连接

    SELECT e.name, d.dept_name, p.project_name
    FROM employees e
    JOIN departments d ON e.dept_id = d.dept_id
    JOIN projects p ON e.emp_id = p.lead_emp_id;
    2)子查询
  • 标量子查询:返回单个值,用于条件判断
    SELECT name FROM employees
    WHERE salary > (SELECT AVG(salary) FROM employees);

    行子查询:返回一行多列。

    SELECT * FROM employees
    WHERE (dept_id, salary) = (SELECT dept_id, MAX(salary) FROM employees);

    存在性查询(EXISTS)

    SELECT dept_name FROM departments d
    WHERE EXISTS (SELECT 1 FROM employees e WHERE e.dept_id = d.dept_id);
    (3)分组查询(GROUP BY)
  • 基本分组
    SELECT dept_id, COUNT(*) as emp_count
    FROM employees
    GROUP BY dept_id;

    HAVING 过滤:对分组结果过滤(WHERE 用于分组前,HAVING 用于分组后)。

    SELECT dept_id, AVG(salary) as avg_salary
    FROM employees
    GROUP BY dept_id
    HAVING AVG(salary) > 10000;

2. 索引优化
  • 索引类型
    • B-Tree 索引:最常用,适用于等值查询和范围查询(如WHERE age > 20)。
    • 哈希索引:仅支持等值查询(如WHERE id = 1),不支持范围查询。
    • 全文索引:用于文本搜索(如MATCH AGAINST)。
  • 优化原则
    • 最左前缀匹配:复合索引(如(a, b, c))支持WHERE a=1WHERE a=1 AND b=2,但不支持WHERE b=2
    • 避免索引失效:避免在索引列上使用函数(如WHERE YEAR(create_time) = 2023)。
    • 覆盖索引:查询的字段直接在索引中,无需回表(如SELECT id, name FROM users WHERE id = 1)。
  • 索引失效场景
    -- 错误:索引列参与计算
    SELECT * FROM orders WHERE price * 0.9 < 100;-- 正确:移项到右侧
    SELECT * FROM orders WHERE price < 100 / 0.9;

二、数据库设计

1. 范式(Normalization)
  • 第一范式(1NF):字段不可再分。
    • 反例:address字段存储"北京市海淀区"(应拆分为citydistrict)。
  • 第二范式(2NF):消除部分依赖(主键为复合键时)。
    • (订单ID, 商品ID, 商品名称, 数量)中,商品名称只依赖于商品ID,应拆分表。
  • 第三范式(3NF):消除传递依赖。
    • (员工ID, 部门ID, 部门地址)中,部门地址通过部门ID传递依赖,应拆分表。

    2. 反范式(Denormalization)
    • 定义:为提高查询性能,有意违反范式,引入冗余数据。
    • 场景
      • 频繁关联的字段(如订单表冗余用户姓名,避免每次 JOIN 用户表)。
      • 统计数据(如文章表保存comment_count字段,避免每次 COUNT 评论表)。
    • 优缺点
      • 优点:减少 JOIN,提升查询速度。
      • 缺点:数据冗余,更新时需维护一致性(如用触发器或事务)
    3. 事务隔离级别
    • 四大特性(ACID):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

    • 隔离级别
      隔离级别脏读不可重复读幻读实现方式
      读未提交(Read Uncommitted)无锁
      读已提交(Read Committed)行级共享锁,读取时加锁立即释放
      可重复读(REPEATABLE READ)行级共享锁,事务结束后释放(MySQL 默认)
      串行化(SERIALIZABLE)表级共享锁,事务结束后释放
    • MySQL 默认隔离级别REPEATABLE READ,通过 MVCC(多版本并发控制)解决不可重复读。

    三、主流数据库

    1. MySQL
    • 存储引擎对比
      特性InnoDBMyISAM
      事务支持
      外键支持
      锁粒度行锁表锁
      索引与数据存储聚簇索引(索引和数据一起存储)非聚簇索引(索引和数据分开)
      适用场景事务性场景(如订单、支付)只读或插入为主(如日志)
    • 索引优化工具
      • EXPLAIN语句:分析查询执行计划,查看是否使用索引。
        EXPLAIN SELECT * FROM users WHERE age > 18;
      • SHOW PROFILE:查看查询各阶段耗时。

    2. Redis
    • 数据结构与应用场景
      • String:缓存(如SET user:1 '{"name":"Alice"}')。
      • Hash:存储对象(如用户信息HSET user:1 name "Alice")。
      • List:消息队列(如LPUSH queue task1)。
      • Set:去重(如点赞用户集合)。
      • Sorted Set:排行榜(如ZADD scoreboard 100 "user1")。
    • 缓存策略
      • 缓存穿透:查询不存在的数据,导致请求直达 DB。
        • 解决方案:缓存空值、布隆过滤器。
      • 缓存雪崩:大量缓存同时过期,导致 DB 压力骤增。
        • 解决方案:随机过期时间、多级缓存。
      • 缓存击穿:热点 key 过期瞬间,大量请求直达 DB。
        • 解决方案:永不过期、加互斥锁。

    3. MongoDB
    • 适用场景
      • 灵活 schema:文档结构不固定(如用户行为日志)。
      • 高并发写入:支持分片集群,写性能优异。
      • 地理空间查询:内置对地理位置的索引和查询支持。
      • 与关系型数据库对比
        特性MongoDBMySQL
        数据模型文档(JSON 格式)表结构
        查询语言类 JSON 的 BSONSQL
        事务支持4.0 + 支持多文档事务全事务支持
        水平扩展原生支持分片集群需要中间件(如 ShardingSphere)
        适用场景灵活、高并发写入场景强事务一致性场景

    四、综合应用示例

    场景:设计一个电商订单系统,包含用户、商品、订单表。

     

    数据库设计

     
    1. 用户表(users)
      CREATE TABLE users (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      );

      2.商品表(products)

      CREATE TABLE products (id BIGINT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,price DECIMAL(10, 2) NOT NULL,stock INT DEFAULT 0,category_id BIGINT,INDEX idx_category (category_id)
      );

      3.订单表(orders)

      CREATE TABLE orders (id BIGINT PRIMARY KEY AUTO_INCREMENT,user_id BIGINT NOT NULL,total_amount DECIMAL(10, 2) NOT NULL,status TINYINT DEFAULT 0 COMMENT '0-待支付,1-已支付',create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,FOREIGN KEY (user_id) REFERENCES users(id),INDEX idx_user_status (user_id, status)
      );

      索引优化

    2. orders.user_id添加索引,加速用户订单查询。
    3. 复合索引(user_id, status)支持按用户和状态过滤(如查询用户待支付订单)。

    事务示例(扣库存): 

    BEGIN TRANSACTION;-- 检查库存
    SELECT stock FROM products WHERE id = 1 FOR UPDATE; -- 行锁-- 扣减库存(假设库存足够)
    UPDATE products SET stock = stock - 1 WHERE id = 1;-- 创建订单
    INSERT INTO orders (user_id, total_amount, status) VALUES (1001, 99.99, 0);COMMIT;

    五、总结

    数据库是面试的核心考点,需掌握:

     
    1. SQL:熟练编写复杂查询,理解索引原理与优化。
    2. 设计:权衡范式与反范式,根据业务选择事务隔离级别。
    3. 主流数据库:掌握 MySQL 存储引擎差异、Redis 缓存策略、MongoDB 适用场景。
    http://www.xdnf.cn/news/13526.html

    相关文章:

  • 自动K码对齐
  • Kotlin基础语法一
  • float负数浮点值强转uint16_t
  • NIFI的处理器:ConsumeMQTT 2.4.0
  • 【Zephyr 系列 17】多协议网关实战:BLE + LoRa + UART + MQTT 综合调度系统设计与实现
  • CoW模式、线程的本地存储和生产者-消费者模式
  • 线程分离属性
  • 【Python】 -- 趣味代码 - 扫雷游戏
  • 使用obsutil工具在OBS上完成基本的数据存取【玩转华为云】
  • LLM 推理:LLM 路由和分层技术的表征和分析
  • 进行性核上性麻痹护理指南:全维度守护健康
  • LIGHT (数据库操作)
  • 【Css】css修改滚动条的样式
  • MySQL InnoDB更新流程
  • Python格式化:让数据输出更优雅
  • 场景题目记录
  • Java - Mysql数据类型对应
  • JxBrowser 8.8.0 版本发布啦!
  • 小天互连IM系统:即时通讯在远程工作中的应用
  • 系统思考:恶性循环
  • 走线太长导致的下冲(Undershoot)现象及解决
  • matplotlib画图报错
  • 使用 pytdx,`TdxHq_API` 接口下载数据的 AI 编程指引提示词
  • 微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
  • 第二十章 BKP
  • 华为认证入门怎么选?
  • Java-面向对象-类与对象(基础)
  • leetcode题解450:删除BST中的结点!调整二叉树的结构最难!
  • ​​绿色PCB通关密码:猎板无铅焊料+水性油墨的RoHS合规实践​​
  • SpringBoot基于RabbitMQ实现异步请求处理