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

突击复习清单(高频核心考点)

  1. 🔒 锁的作用与使用(synchronized vs ReentrantLock)
    面试官为什么问:考察你对并发编程基础的掌握程度。

速记答案:

作用:保证线程安全,解决多线程环境下对共享资源访问的数据不一致问题。

synchronized:JVM关键字,是悲观锁。用法:

修饰实例方法:锁是当前实例对象 (this)

修饰静态方法:锁是当前类的Class对象

修饰代码块:锁是synchronized括号里配置的对象

ReentrantLock:JDK类,也是悲观锁。比synchronized更灵活:

必须手动加锁(lock())和解锁(unlock()),通常放在finally块中保证必然解锁。

可以尝试非阻塞获取锁 (tryLock())

可以设置公平锁(先等待的线程先获得锁)

可以绑定多个条件变量 (Condition),实现分组唤醒线程

对比总结:

特性 synchronized ReentrantLock
实现 JVM层面,关键字 JDK层面,API
锁释放 自动释放 必须手动unlock()
灵活性 不灵活 灵活(可尝试、可公平、可中断)
性能 1.6后优化得很好,两者差不多 两者差不多
面试时这么说:”锁的核心作用是保证线程安全。synchronized最简单,JVM自动管理。但如果需要尝试获取锁、公平锁或者更复杂的线程协作,就用ReentrantLock。“

  1. ☁️ Spring Cloud 服务注册与发现
    面试官为什么问:考察你对微服务核心原理的理解。

速记答案:

服务注册:服务提供者(如user-service)启动时,把自己的网络地址(IP、端口)注册到注册中心(如Eureka、Nacos)。

服务发现:服务消费者(如order-service)要调用user-service时,不去写死地址,而是去注册中心查找user-service的可用地址列表,然后再调用。

核心组件:

Eureka Server:注册中心,一个独立的服务。

Eureka Client:集成到每个微服务中,负责注册和发现。

好处:服务动态上下线,消费者无需硬编码地址,实现了服务解耦。

面试时这么说:”就像酒店的前台。服务提供者就是客房,入住时在前台登记(注册)。服务消费者就是客人,需要找客房时先去前台问房间号(发现),然后再过去。注册中心(Eureka/Nacos)就是那个前台。“

  1. 🍃 Spring Boot 中如何使用锁?
    面试官为什么问:考察你是否能在实际项目中应用并发知识。

速记答案:

在Spring Boot中,锁的使用和普通Java应用一样,但更要注意单例Bean的线程安全问题。

方法1:synchronized

java
@Service
public class UserService {
public synchronized void businessMethod() {
// 业务代码,同一时间只有一个线程能进入
}
}
方法2:ReentrantLock (更推荐,更灵活)

java
@Service
public class UserService {
// 定义锁对象
private final ReentrantLock lock = new ReentrantLock();

public void businessMethod() {lock.lock(); // 加锁try {// 业务代码} finally {lock.unlock(); // 解锁必须放在finally块中}
}

}
面试时这么说:”Spring Boot里用锁和普通Java一样。但因为它的Bean默认是单例的,所以高并发下成员变量会有线程安全问题,必须加锁。我一般用ReentrantLock,因为控制起来更灵活。“

  1. 🏗️ 微服务设计思路
    面试官为什么问:考察你的系统架构能力和全局观。

速记答案(按模块说):

服务拆分:按业务领域拆分(如用户、订单、商品服务),做到单一职责,避免臃肿。

服务治理:

注册与发现:用Nacos或Eureka。

配置管理:用Nacos Config,统一管理配置,动态刷新。

服务调用:用OpenFeign,声明式HTTP客户端,像调用本地方法一样调用远程服务。

负载均衡:用Ribbon或LoadBalancer,实现服务调用的负载均衡。

容错保护:用Sentinel或Hystrix,实现熔断、降级、限流,防止服务雪崩。

网关:用Spring Cloud Gateway,统一入口,负责路由、鉴权、日志、监控等。

链路追踪:用SkyWalking或Zipkin,解决微服务调用链路过长,难以排查问题的问题。

面试时这么说:”我的设计思路是:先按业务模块垂直拆分服务。然后通过注册中心解决服务发现问题;用OpenFeign做声明式调用;用Sentinel做熔断降级保护下游服务;最后用API网关作为统一的流量入口。“

  1. 📊 SQL索引避免失效
    面试官为什么问:考察你的SQL优化实战能力,这是性能调优的基础。

速记答案(记住失效场景就等于知道如何避免):
失效场景:

最左前缀原则:联合索引(a, b, c),查询条件没用到a,索引失效。

在索引列上计算或函数操作:WHERE YEAR(create_time) = 2023,WHERE amount * 2 > 100。

类型转换:字符串字段varchar,用数字去查:WHERE code = 123(应改为WHERE code = ‘123’)。

Like以%开头:WHERE name LIKE ‘%张’。

使用OR:如果OR前后的条件列不是都有索引,则索引可能失效。

面试时这么说:”要避免索引失效,最重要的是遵守最左前缀原则。另外,要避免对索引列做计算、函数操作、类型转换,以及避免使用前导百分号的LIKE查询和随意的OR连接。“

  1. 🧠 JVM内存模型(运行时数据区)
    面试官为什么问:考察你对Java程序运行底层的理解,这是调优的基础。

速记答案(记住图就行):
线程私有的:

程序计数器:记录当前线程执行到的字节码行号。

虚拟机栈:存储方法调用的栈帧,包含局部变量表、操作数栈等。StackOverflowError出自这里。

本地方法栈:为Native方法服务。

线程共享的:

堆:存放对象实例和数组,是垃圾回收的主要区域。OutOfMemoryError常在这里发生。分为新生代和老年代。

方法区:存储类信息、常量、静态变量。JDK8后叫元空间(Metaspace),使用本地内存。

面试时这么说:”JVM内存分线程共享和私有两大块。每个线程有自己的栈和程序计数器,用来执行方法。所有线程共享一个堆和方法区,堆里放对象,是GC的主战场;方法区放类的元信息。“

  1. 🐞 代码出错如何排查定位?
    面试官为什么问:考察你的实际运维和问题解决能力,这是经验的体现。

速记答案:

看日志:第一反应是查看应用日志和系统日志,95%的问题都能从这里找到线索。

CPU飙升:

top -> top -Hp [pid] 找到耗CPU的线程ID。

将线程ID转16进制:printf “%x\n” [tid]。

jstack [pid] | grep -A 20 [十六进制tid] 查看该线程的堆栈信息,定位问题代码。

内存溢出(OOM):

在启动参数中添加-XX:+HeapDumpOnOutOfMemoryError,让JVM在OOM时自动导出堆转储文件。

使用MAT或JVisualVM工具分析这个dump文件,找到是哪个对象占用了大量内存,以及是谁在引用它(GC Roots链)。

死锁:

用jstack [pid]命令,查看输出最后,如果有死锁,JVM会明确告诉你。

面试时这么说:”我首先会查看日志。如果是CPU问题,我用top和jstack命令定位到具体线程和代码行。如果是内存OOM,我会让JVM自动导出heap dump,然后用MAT工具分析,找到泄漏对象。如果是死锁,jstack命令能直接检测出来。“

  1. 🔄 MQ如何避免重复消费?
    面试官为什么问:考察你对消息队列可靠性的理解。

速记答案:

原因:网络抖动、消费者重启等导致MQ没有收到确认,从而重发消息。

核心:解决之道不是防止重复,而是保证业务的幂等性(多次执行结果一致)。

方案:

数据库唯一键:利用DB主键或唯一约束,插入成功才消费,重复插入会报错。

Redis原子操作:用SETNX [消息ID]命令,设置成功才消费。

乐观锁:给数据加版本号version,更新时带版本条件:update … set … where id=xxx and version=xxx。

面试时这么说:”重复消费无法完全避免,所以关键是做幂等设计。我最常用的方案是利用数据库唯一键,收到消息后先尝试insert一条记录,如果重复则直接放弃,这样就保证了只会被处理一次。“

  1. 🔐 分布式锁怎么搞?
    面试官为什么问:考察你解决分布式环境下资源争抢的能力。

速记答案:

基于Redis:

SET lock_key unique_value NX PX 30000:NX表示仅当不存在时设置,PX设置超时时间(防死锁),unique_value(如UUID)用于安全释放锁。

优点:性能高。

缺点:主从切换时可能丢锁(AP模型)。

基于ZooKeeper:

创建临时有序节点,最小的节点获锁。监听前一个节点,它释放了你就获得锁。

优点:强一致性,可靠(CP模型)。临时节点在客户端断开后自动删除,避免死锁。

缺点:性能比Redis差。

选型:要性能选Redis,要绝对可靠选ZooKeeper。常用框架:Redisson(Redis)、Curator(ZK)。

面试时这么说:”分布式锁主要有两种实现。Redis方案性能好,但理论上有极低概率失效。ZooKeeper方案可靠性高,但性能稍差。根据业务的容忍度来选择,比如秒杀用Redis,金融交易用ZooKeeper。在实际项目中,我们直接用Redisson这个框架,它封装得很好用。“

💡 面试技巧 & 最后鼓励
别怕“忘了”:面试时如果突然忘了,可以说:“这块细节我有点记不清了,我的理解是…”然后尝试把你知道的核心概念讲出来,这比完全沉默要好得多。

引导到你熟悉的项目:尽量把问题引到你做过的项目上。“这个知识点在我之前做XX项目的时候用到过,当时我们是…”这样更有说服力。

展现思考过程:对于设计题,面试官更看重你的思路。即使最终方案不完美,把你思考的步骤和权衡的因素说出来,也是大大的加分项。

朋友,别因为一次面试否定自己。你已经有5年经验,这些知识肯定都接触过,只是暂时被埋没了。把这些核心要点和关键词记住,下次面试时就能迅速提取出来。

你不是不会,只是需要一点提示来唤醒记忆! 祝你下次面试一举成功!

http://www.dtcms.com/a/344650.html

相关文章:

  • 【C++高阶六】哈希与哈希表
  • 线程池拒绝策略踩坑
  • uniappx与uniapp的区别
  • 【UniApp打包鸿蒙APP全流程】如何配置并添加UniApp API所需的鸿蒙系统权限
  • MySQL B+树索引使用
  • QT之QSS的使用方法和常用控件的样式设置
  • Qt 的事件类QEvent及其他子类事件的开发详解:从基础到实践的全方位指南
  • 高并发用户数峰值对系统架构设计有哪些影响?
  • Qt-窗口类部件
  • 极验demo(float)(一)
  • 数据结构:队列 二叉树
  • vivo“空间计算-机器人”生态落下关键一子
  • 码蹄杯进阶
  • 笔试——Day46
  • 基于SpringBoot+Vue框架的高校论坛系统 博客论坛系统 论坛小程序
  • 企业版Idea 无快捷键的启动方式
  • 和AI Agent一起读论文——A SURVEY OF S ELF EVOLVING A GENTS(五)
  • 如何监控和管理微服务之间的调用关系
  • 微信开发者工具:更改 AppID 失败
  • Unreal Engine Class System
  • 滑动窗口+子串+普通数组算法
  • Spring AI调用本地大模型实战
  • 【LINUX】CentOS7在VMware15中,从命令行界面切换到图形界面的异常汇总
  • Day10 Go语言深入学习(2)
  • 零成本 Redis 实战:用Amazon免费套餐练手 + 缓存优化
  • skywalking-agent与logback-spring.xml中的traceId自动关联的原理
  • 使用C#的 PdfDocument 实现 PDF 页眉页脚的编辑
  • 我用Photoshop Firefly+Blender,拯救被环境毁掉的人像大片
  • Blender模型动画导入到UE5
  • uniappx新增的几个api