文章目录
- 远程调用代码规范
- [MySQL 视图有什么用?什么时候用?](#MySQL 视图有什么用?什么时候用?)
- ELK日志解决方案
- ThreadLocal内存泄漏
- MAT怎么用
- ThreadLocal怎么用?哪些场景好用
- [WebSocket vs SSE](#WebSocket vs SSE)
- Redis怎么抗住某个表的高并发
- [RocketMQ加快服务的处理速度 & 延迟消息](#RocketMQ加快服务的处理速度 & 延迟消息)
- 介绍一下RPC
- Docker组件数据如何流转?
- TCP比HTTP性能好吗?为什么SpringCloud用HTTP
- 自定义热度算法举例
- 轮询时间间隔多少合适
- zset如何实现热榜排名
- Redis真实项目的分布式锁实现
- Redis怎么实现签到功能
- ES优点和缺点
远程调用代码规范

MySQL 视图有什么用?什么时候用?
MySQL 视图(View)是一种虚拟表,其内容由查询定义。与普通表不同的是,视图并不实际存储数据,而是基于SQL语句的结果集动态生成的。以下是MySQL视图的一些主要用途及适用场景:
主要用途
-
简化复杂查询:如果经常需要执行复杂的查询(如多表连接、聚合等),可以将这些查询封装到一个视图中。这样,以后只需简单地查询这个视图,而不需要重复编写复杂的SQL语句。
-
数据安全:通过视图可以限制用户访问的数据,只暴露部分列或特定行的数据给用户,从而增强安全性。例如,对于敏感信息,可以通过视图隐藏某些字段。
-
逻辑数据独立性:视图可以在不改变应用程序的情况下,为用户提供一种适应数据库结构变化的方式。比如,当底层表结构发生变化时,只需要调整视图定义即可,不影响现有应用代码。
-
汇总数据展示:视图可用于展示汇总数据,如统计总数、平均值等,便于数据分析和报表生成。
-
重用查询逻辑:一旦定义了视图,就可以在不同的地方重复使用该视图中的查询逻辑,减少代码重复,提高开发效率。
适用场景
- 复杂查询频繁出现的场合:当你发现某些复杂查询被多次使用时,创建视图为这些查询提供一个简单的接口。
- 需要对不同用户提供不同级别的数据访问权限时:利用视图可以限制用户只能看到特定的数据,保护敏感信息。
- 数据库重构期间保持兼容性:在进行数据库结构调整时,可以使用视图来模拟旧的表结构,以保持现有应用程序的正常运行。
- 简化跨多个表的数据检索:如果需要从多个表中提取数据,可以使用视图来简化操作,无需每次都指定所有连接条件。
尽管视图有很多优点,但它们也可能带来性能上的挑战,特别是在处理非常大的数据集或者复杂的查询时。因此,在设计和使用视图时应考虑到这一点,并进行适当的优化。此外,需要注意的是,并非所有的视图都支持数据修改操作(如INSERT, UPDATE, DELETE)。
ELK日志解决方案

ThreadLocal内存泄漏
MAT怎么用
MAT(Memory Analyzer Tool) 是 Java 内存分析工具,常用于排查内存泄漏和优化内存使用。
常用功能:
- Leak Suspects 报告:自动检测潜在的内存泄漏点。
- Dominator Tree:查看对象的保留大小(Retained Heap),找出内存占用高的对象。
- Histogram:统计类的实例数量和占用内存。
- OQL(对象查询语言):类似 SQL 查询堆内存中的对象。
使用步骤:
- 生成堆转储文件 :通过 JVM 参数
-XX:+HeapDumpOnOutOfMemoryError
或jmap
工具生成.hprof
文件。 - 导入 MAT :打开 MAT,选择
File → Open Heap Dump
加载文件。 - 分析报告:查看 Leak Suspects 报告,检查 Dominator Tree 和 Histogram。
- 定位问题:通过引用链(Path to GC Roots)分析对象为何未被回收。
ThreadLocal怎么用?哪些场景好用
ThreadLocal 为每个线程提供独立的变量副本,避免线程安全问题。
使用方式:
java
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("value"); // 设置当前线程的值
String value = threadLocal.get(); // 获取当前线程的值
threadLocal.remove(); // 避免内存泄漏
适用场景:
- 线程上下文传递:如用户登录信息、事务上下文(如数据库连接)。
- 避免共享变量竞争:如日志记录器、线程池中的任务参数。
- 工具类封装 :如
SimpleDateFormat
(线程不安全,需用 ThreadLocal 包裹)。
注意事项:
- 内存泄漏风险 :如果线程是线程池中的长期线程(如 Tomcat 线程池),需及时调用
remove()
。 - 继承性问题 :默认不支持父子线程共享,可通过
InheritableThreadLocal
解决。
WebSocket vs SSE
- WebSocket:双向通信,客户端和服务器可随时发送消息。适合实时性要求高的场景(如聊天室、在线游戏)。
- SSE(Server-Sent Events):单向通信(服务器到客户端),适合服务器主动推送数据(如新闻推送、股票行情)。
对比:
特性 | WebSocket | SSE |
---|---|---|
通信方向 | 双向 | 单向(服务器→客户端) |
连接方式 | 长连接 | HTTP 长连接(基于 HTTP/1.1) |
数据格式 | 二进制/文本 | 文本(只能用 text/event-stream ) |
适用场景 | 实时交互(如 IM) | 服务器推送(如通知) |
Redis怎么抗住某个表的高并发
策略:
- 缓存热点数据:将高频查询的数据(如商品详情、用户信息)缓存在 Redis 中,减少数据库压力。
- 使用布隆过滤器:防止缓存穿透(查询不存在的数据直接返回)。
- 数据分片:对表进行分库分表,同时将数据映射到 Redis 的不同 Key(如按用户 ID 分片)。
- 异步写回:对写操作(如更新库存)使用 Redis 队列异步落库,避免直接写数据库。
- 限流降级 :通过 Redis 记录请求次数,限制突发流量(如使用
Redis + Lua
实现分布式限流)。
RocketMQ加快服务的处理速度 & 延迟消息
提高处理速度:
- 批量发送:合并多个消息为一个批量消息,减少网络开销。
- 顺序消息:确保消息按顺序消费(如订单状态更新)。
- 负载均衡:生产者和消费者均采用负载均衡策略(如轮询)。
实现延迟消息:
- 配置延迟级别 :在
broker.conf
中设置messageDelayLevel=1s 5s 10s 30s 1m ...
。 - 发送延迟消息:
java
Message msg = new Message("TopicTest", "TagA", "Hello world".getBytes());
msg.setDelayTimeLevel(3); // 对应配置的第3级延迟(如10秒)
producer.send(msg);
介绍一下RPC
RPC(Remote Procedure Call) 是远程过程调用,允许程序调用另一个地址空间(通常是远程服务器)上的函数,如同本地调用。
核心组件:
- 客户端桩(Client Stub):将调用参数序列化并发送到服务端。
- 服务端桩(Server Stub):反序列化参数并调用本地方法。
- 通信协议:如 HTTP、TCP、gRPC(基于 HTTP/2)。
- 注册中心:如 ZooKeeper、Nacos,用于服务发现。
优势:
- 透明性:开发者无需关注网络细节。
- 高性能:相比 HTTP,RPC 通常使用二进制协议(如 Protobuf)更高效。
- 可扩展性:支持负载均衡、熔断、重试等机制。
Docker组件数据如何流转?
Docker 数据流转:
- 容器间通信 :
- 网络模式 :使用
--network
指定容器网络(如bridge
、host
)。 - 自定义网络 :通过
docker network create
创建自定义网络,容器加入后可通过名称互相访问。
- 网络模式 :使用
- 数据持久化 :
- 数据卷(Volumes) :使用
docker volume create
创建持久化存储,容器挂载后数据不丢失。 - 绑定挂载(Bind Mounts) :将主机目录挂载到容器中(如
-v /host/path:/container/path
)。
- 数据卷(Volumes) :使用
- 日志和监控 :
- 日志驱动 :通过
docker logs
或日志收集工具(如 Fluentd)获取容器日志。 - 监控工具:使用 Prometheus + Grafana 监控容器资源使用。
- 日志驱动 :通过
TCP比HTTP性能好吗?为什么SpringCloud用HTTP
- TCP 性能:TCP 是传输层协议,直接建立连接传输数据,性能更高(无 HTTP 头部开销)。
- HTTP 性能:HTTP 是应用层协议,基于 TCP,但需额外处理请求/响应格式、状态码等。
Spring Cloud 为何用 HTTP:
- 标准化:HTTP 是 Web 标准协议,兼容性好,易于调试和集成。
- 生态支持:Spring Cloud 提供丰富的 HTTP 客户端(如 Feign、RestTemplate)和网关(如 Spring Cloud Gateway)。
- 灵活性:HTTP 支持 RESTful API,适合微服务间的松耦合通信。
- 安全性:HTTPS 提供加密传输,支持 OAuth2、JWT 等认证机制。
自定义热度算法举例
热度算法公式:
java
double hotScore = views * 0.1 + likes * 0.3 + shares * 0.2 + (System.currentTimeMillis() - createdTime) / 3600000 * 0.4;
- 权重分配:根据业务需求调整各字段权重(如点击量、点赞数、时间衰减)。
- 时间衰减:随时间推移降低热度(如每小时衰减 1%)。
- 归一化处理:将分数标准化到 [0,1] 范围,便于排序。
轮询时间间隔多少合适
轮询时间间隔建议:
- 低频场景:30 秒~1 分钟(如定时拉取配置)。
- 中频场景:5~10 秒(如实时性要求一般的数据同步)。
- 高频场景:1~2 秒(如实时监控,但需权衡服务器压力)。
优化策略:
- 指数退避:失败后延迟翻倍,减少重试压力。
- 长轮询:服务端在无数据时保持连接,直到有数据或超时(如 SSE 的变体)。
zset如何实现热榜排名
Redis zset(有序集合)实现热榜:
-
数据结构:每个用户或商品的热度值作为分数(score),ID 作为成员(member)。
-
更新排名 :每次用户行为(如点赞)更新分数:
javaZSetOperations<String, String> zSet = redisTemplate.opsForZSet(); zSet.add("hot_rank", "item1", 100); zSet.increaseScore("hot_rank", "item1", 10); // 点赞+10分
-
获取排行榜 :
javaSet<ZSetOperations.TypedTuple<String>> top10 = zSet.rangeWithScores("hot_rank", 0, 9);
Redis真实项目的分布式锁实现
分布式锁实现:
-
SETNX 命令(已弃用):
bashSET lock_key unique_value NX PX 30000
NX
:仅当 key 不存在时设置。PX
:设置过期时间(毫秒)。
-
Redisson 客户端(推荐):
javaRLock lock = redisson.getLock("lock_key"); lock.lock(); try { // 业务逻辑 } finally { lock.unlock(); }
-
RedLock 算法(多节点锁):
- 在多个 Redis 节点上尝试加锁,超过半数成功则视为加锁成功。
- 需要严格处理时钟漂移问题。
Redis怎么实现签到功能
方案一:使用 BITMAP
java
// 用户 ID=1,签到日期=2025-06-05(假设日期转换为偏移量)
redisTemplate.opsForValue().setBit("sign:1", 5, true); // 第5天签到
// 查询某月签到情况
Long signDays = redisTemplate.opsForValue().bitCount("sign:1");
方案二:使用字符串
java
// 每位代表一天(0=未签到,1=已签到),32 位表示一个月
String sign = redisTemplate.opsForValue().get("sign:1");
if (sign == null) sign = "00000000000000000000000000000000";
char[] bits = sign.toCharArray();
bits[5] = '1'; // 第5天签到
redisTemplate.opsForValue().set("sign:1", new String(bits));
ES优点和缺点
优点:
- 全文搜索:支持复杂查询(如分词、模糊搜索、短语匹配)。
- 实时性:近实时数据索引和搜索(默认 1 秒刷新间隔)。
- 分布式:支持水平扩展,自动分片和副本。
- 聚合分析:强大的聚合功能(如统计、直方图)。
缺点:
- 写入性能:写入成本较高(需生成倒排索引)。
- 资源消耗:内存和磁盘占用大,需合理规划分片。
- 复杂查询限制:不擅长深度分页(如超过万级结果)。
- 一致性:默认最终一致性,需手动控制刷新策略。