设计分层架构Dubbo 最显著的特点就是其分层架构。官方文档中将其划分为 10 层,但为了便于理解,我们可以将其归纳为三大块:业务层、RPC 核心层、Remoting 通信层。
业务层 (Business Layer):
Service 层: 开发者定义的业务接口和实现。
Config 层: 对外配置层,用于配置服务的暴露和引用,如 ServiceConfig 和 ReferenceConfig。这是开发者直接接触的部分。
RPC 核心层 (RPC Core Layer): 这是 Dubbo 功能的核心所在。
Proxy 层: 服务代理层。为消费者端生成接口的代理对象,使其能像调用本地方法一样调用远程服务。
Registry 层: 注册中心层。负责服务的注册与发现,封装了与 Zookeeper、Nacos 等注册中心的交互。
Cluster 层: 集群容错层。当从注册中心获取到多个服务提供者时,由该层决定如何选择(负载均衡)以及在调用失败时如何应对(容错机制)。
Monitor 层: 监控层。负责统计服务的调用次数、耗时等信息。
Protocol 层: 远程调用层。这是 RPC ...
分布式1.介绍一下CAP理论CAP 原则又称 CAP 定理, 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性), 三者不可得兼
一致性(C) : 在分布式系统中的所有数据备份, 在同一时刻是否同样的值(等同于所有节点访问同一份最新的数据副本)
可用性(A): 在集群中一部分节点故障后, 集群整体是否还能响应客户端的读写请求(对数据更新具备高可用性)
分区容忍性(P): 以实际效果而言, 分区相当于对通信的时限要求. 系统如果不能在时限内达成数据一致性, 就意味着发生了分区的情况, 必须就当前操作在 C 和 A 之间做出选择
2.如何使用redis分布式锁分布式锁是用于分布式环境下并发控制的一种机制,用于控制某个资源在同一时刻只能被一个应用所使用。
Redis 本身可以被多个客户端共享访问,正好就是一个共享存储系统,可以用来保存分布式锁,而且 Redis 的读写性能高,可以应对高并发的锁操作场景。Redis 的 SET 命令有个 NX 参数可以实现「key不存在才插入」,所以可以用 ...
点评多级缓存1.设计决策: 当初为什么决定要引入 Caffeine 做本地缓存,只用 Redis 不行吗?你是如何界定哪些数据应该放在本地缓存,哪些放在分布式缓存的?这个决策的依据是什么?
你设计了Caffeine + Redis的二级缓存。请阐述这个架构的完整请求链路和数据回源链路。为什么需要Caffeine?在你的业务场景里,它相比只有Redis,解决了什么核心痛点?带来了什么新的复杂性?
你的Caffeine和Redis中缓存的数据是同构的吗?还是有所侧重?比如Caffeine只缓存热点中的热点?数据筛选和淘汰策略是如何设计的?
缓存预热:服务刚启动时,Caffeine是冷的,可能会导致瞬间大量请求打到Redis甚至DB。你们是如何处理这个冷启动问题的?
一致性挑战: 你提到了通过监听 binlog 来做数据同步,这是一个很好的方案。但从数据库变更发生,到 binlog 被监听到,再到消息传递,最后更新 Redis 和 Caffeine,这中间是存在延迟的。你是如何处理这个延迟窗口内可能发生的“脏读”问题的?比如,一个用户刚更新完地址(DB已更新),立马刷新页面,请求打到了一个 ...
技术栈
未读IOCBeanDefinitionBeanDefinition 是 Spring IoC 容器的基石,它是 Bean 的一切元数据(类名、作用域、构造函数参数、属性等)的载体,是面向接口编程思想的体现。容器操作的是 BeanDefinition,而非直接操作 Class。
我们最常用的就是DefaultListableBeanFactory 中 beanDefinitionMap 这个 ConcurrentHashMap,所有加载的 BeanDefinition 都存储于此。
然后我们的IOC容器ApplicationContext 根据其实现(XML, Annotation)选择不同的策略(Reader, Scanner)来加载 BeanDefinition。模板方法模式在 AbstractBeanDefinitionReader 等类中被广泛使用。
XML 路径: 从 AbstractXmlApplicationContext 的构造函数出发 -> loadBeanDefinitions(new XmlBeanDefinitionReader(this)) -> Xml ...
美团一面题目1请说明进程和线程的区别与联系。操作系统中的虚拟内存是如何实现的?谈谈乐观锁和悲观锁,以及它们在Java中的具体实现(如CAS、Synchronized)。AQS(AbstractQueuedSynchronizer)的原理是什么?请举例说明(如ReentrantLock)。当向一个线程池提交任务时,它的执行流程是怎样的?(考虑核心线程、队列、最大线程、拒绝策略)
介绍一下Redis的持久化机制有哪几种,它们各自有什么优缺点?如何保证缓存与数据库双写一致性?谈谈MySQL的事务隔离级别,以及MVCC是如何在可重复读(RR)级别下工作的。什么是覆盖索引和回表?在使用联合索引时,需要注意哪些最左前缀匹配原则?
请描述一下JVM的类加载过程,以及双亲委派模型。G1垃圾收集器相比于CMS有哪些优势?什么情况下会发生OOM(堆内存溢出),请举例说明几种场景。Java中的强引用、软引用、弱引用、虚引用之间有什么区别?
题目21:自我介绍
2:HashMap1.8底层数据结构和put流程
3:jvm底层和OOM发生区域
4:roc调用流程
5:慢SQL调查流程
6:mysql隔离级别和如 ...
线程1.从 JVM 的角度来说一下线程和进程之间的关系一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)\资源,但是每个线程有自己的*程序计数器、虚拟机栈 和 本地方法栈*。
线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。
那么?为什么程序计数器、虚拟机栈和本地方法栈是线程私有的呢?为什么堆和方法区是线程共享的呢?
程序计数器:
主要作用:字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。
so,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
虚拟机栈和本地方法栈
虚拟 ...
索引1.索引的分类从数据结构上分类,B+树索引,hash索引,倒排索引,R树索引
从InoDB的B+树的索引分类,分为聚簇索引和非聚簇索引
从索引的性质进行分类,普通索引,主键索引,唯一索引,联合索引,全文索引,空间索引
锁&隔离级别1.表级锁与行级锁的区别?MySQL 常见的两种锁是表级锁和行级锁。
表级锁锁定整个表,所有对该表的读写操作都会被阻塞,适用于低并发场景;而行级锁锁定特定行,允许其他行的操作并发进行,适用于高并发场景。
表级锁粒度大,加锁快、开销小,但并发性能差,典型代表是 MyISAM。 行级锁粒度小,允许多个事务并发操作不同的行,并发性高,但锁的开销大,容易出现死锁,典型代表是 InnoDB。 因此实际使用时,MyISAM 适合读多写少的分析场景,而 InnoDB 的行级锁更适合高并发的 OLTP 系统。
2.MySQL 默认隔离级别?为何选择它?MySQL 的默认隔离级别是可重复读(REPEATABLE READ)。选择这一隔离级别是因为它能够提供较高的数据一致性,防止不可重复读,并通过 MVCC(多版本并发控制)技术支持高效的并发性能。同时,通过间隙锁( ...
Spring框架1.SpringBoot的配置加载优先级首先我们先确定一下配置加载优先级是按照我以下的顺序,由高到低的。分别是:
先是命令行参数(--server.port=9000 或 java -jar app.jar --spring.config.location=...)
然后是我们的系统的环境变量和JVM系统属性,比如设置端口为8080,比如我们在这里设置API的KEY
然后RandomValuePropertySource(random.* 占位符,用于生成随机数/字符串,可在配置中引用)
接着是外部配置文件(properties / yml)
JAR 包外部的 ./config/
JAR 包外部的 ./
JAR 包内部的 classpath:/config/
JAR 包内部的 classpath:/
接着是我们@PropertySource注解指定的配置
最后是我们Springboot默认的配置
然后在配置文件中,properties的配置大于yml,因为springboot是按加载顺序来的,后加载的properties把yml的值给覆盖了
...
javase源码详解1.==和equal()和hashcode==和equals函数对于基本类型来说, = = 比较是值,equals不能比较基本类型
对于包装类型来说,== 比较的是对象的引用,就是对象的内存地址。而equals()通常被重写以比较对象的值。
需要注意的是,像Interger这种包装类具有缓存机制,如果在缓存的范围,==的结果可能就是true,因为他们都是指向常量池的同一个对象
对于引用类型来说,==比较的是其对象的内存地址,equals要分为两个情况,看这个类型到底重写了equals函数了没,重写了就按重写的比较,比如String类型,他的equals就是比较的对象的值。然后没有重写的话,equals内部还是使用 ==来比较。没有什么区别。还是比较的对象的内存地址
hashcode函数的作用是获取哈希码,然后确定该对象再hash表中的位置,比如hashmap,hashset,布隆过滤器等都用到了hashcode
hasecode分为好几种哈希函数,有取模的,有进行位运算的。我们在布隆过滤器中使用最好是使用两种hash函数来确定位的位置。
hashCode() 定义在 ...
技术栈应用Nacos—-服务注册
OpenFeign—-RPC
Seata —-分布式事务
真正内容设计亮点
基于 Sa-Token 构建统一 OAuth2 认证中心,实现账号密码、短信验证码、第三方平台(微信/支付宝/GitHub 等)等多种登录方式;通过自定义 Token 生成与权限控制,实现细粒度角色/权限管理;集成 Redis 实现分布式会话共享,支持多微服务统一认证与单点登录(SSO);结合注解与全局拦截器完成接口级鉴权,有效提升系统安全性与扩展性。
基于 Seata 分布式事务框架 实现跨微服务数据一致性保障,支持 AT/Saga/TCC 多事务模式;通过 Feign 拦截器实现全局事务上下文透传,结合异常分类回滚策略提升稳定性;引入事务监控与告警系统,支持事务状态实时追踪与自动补偿,显著降低人工介入成本。
设计并实现 基于 Spring Cloud Gateway 的全局认证过滤器,支持 JWT 多端统一认证、白名单动态管理、用户上下文透传;集成 Redis 实现 Token 黑名单与防重放攻击机制,提升系统安全性;引入链路追踪 ID 与异常告警体系,支持全链路请求跟踪 ...













