JAVA基础
概念
1、Java有哪些数据类型?
定义:Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类 型,在内存中分配了不同大小的内存空间。
基本数据类型: 数值型:整数类型(byte,short,int,long) 、浮点类型(float,double)
字符型(char)
布尔型(boolean)
引用数据类型: 类(class)
接口(interface)
数组([])
2、java三大特性
封装: 使用private关键字,让对象私有,防止无关的程序去使用。
继承: 继承某个类,使子类可以使用父类的属性和方法。
多态: 同一个行为,不同的子类具有不同的表现形式。
3、重载和重写的区别
1.重写(Override)
从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。
4、String、StringBuffer、StringBuilder的区别
5、Java的反射原理与作用
在运行过程中,对于任何一个类都能获取它的属性和方法,任何一个对象都能调用其方法,动态获取信息和动态调用,就是反射。
Java获取反射的三种方法:
1.通过new对象实现反射机制
2.通过路径实现反射机制
3.通过类名实现反射机制
6、浅拷贝和深拷贝的区别
7、BIO,NIO,AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过
Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO
,异步 IO 的操作基于事件和回调机制。
8、什么是线程死锁 ?
死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资 源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推 进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 程(线程)称为死锁进程(线程)。
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线 程被无限期地阻塞,因此程序不可能正常终止。
线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方 的资源,所以这两个线程就会互相等待而进入死锁状态。
9、形成死锁的四个必要条件是什么
互斥条件:线程(进程)对于所分配到的资源具有排它性,即一个资源只 能被一个线程(进程)占用,直到被该线程(进程)释放
请求与保持条件:一个线程(进程)因请求被占用资源而发生阻塞时,对 已获得的资源保持不放。
不剥夺条件:线程(进程)已获得的资源在末使用完之前不能被其他线程 强行剥夺,只有自己使用完毕后才释放资源。
循环等待条件:当发生死锁时,所等待的线程(进程)必定会形成一个环 路(类似于死循环),造成永久阻塞
JVM
Spring
1、Spring 是如何管理事务的?
spring的事务声明有两种方式,编程式和声明式。spring主要是通过“声明式事务”的方式对事务进行管理,即在配置文件中进行声明,通过AOP将事务切面切入程序,最大的好处是大大减少了代码量。
2、Spring中Bean的作用域有哪些?
singleton(单例模式):默认,每个容器一个实例
prototy(原型模式):每次请求为一个Bean创建一个实例,适用都是有状态的Bean
request(请求作用域):为每个Http请求创建一个实例,在请求完成之后,Bean会失效,由GC回收
session(会话作用域):为每一个HTTP会话创建一个实例,不同会话使用不同实例
3、解释一下Bean的生命周期?
spring的bean生命周期经历四个阶段:实例化、属性注入、初始化和销毁。首先Spring根据配置信息实例化Bean对象;然后通过依赖注入将Bean的依赖关系注入;接下来,执行Bean的初始化方法;最后,在容器关闭的时候执行Bean的销毁方法
4、Spring中的AOP是如何工作的?
Spring的AOP通过动态代理技术实现的,即根据目标对象动态创建代理对象来实现横切关注点的功能。Spring使用切面Aspect和连接点(Join point)来定义横切关注点,通知(Advice)和切点(Pointcut)来控制横切代码的执行
5、Spring的通知有哪些
前置通知(@Before):在目标方法被调用之前调用此功能
后置通知(@After):在目标方法完成之后执行
环绕通知(@Round):在目标方法调用之前和调用之后执行
返回通知(@AfterRreturing):在目标方法成功执行之后调用此功能
异常通知(@AferThrowing):在目标方法抛出异常之后调用此通知
6、spring中bean的注入方式
构造器注入
Setter注入
接口注入(灵活性和易用性差,Spring4已经废弃)
7、spring中单例Bean是线程安全的吗?
不是,因为所有的线程共享一个单例Bean,存在资源的竞争,所以是线程不安全的,实际上大部分的Bean是无状态的,所以说在某种程度上来说Bea其实是安全的,如果是有状态,那就需要修改Bean的作用域,由单例(Singleton)改为原型(prototype)
8、Spring的事务隔离
五大隔离级别
ISOLATION_DEFAULT: 默认隔离,使用数据库的隔离级别
ISOLATION_READ_UNCOMMITTED:读未提交
ISOLATION_READ_COMMITTED:读已提交
ISOLATION_REPEATABLE_READ:可重复读
ISOLATION_SERIALIZABLE:序列化
9、spring 事务实现方式有哪些?
编程式:beginTransction(),commit(),rollback() 等事务管理相关的方法,灵活度高,但是维护性差。
声明式:利用注解或者XML配置,将业务和事务分离出来
10、spring事务的实现方式和实现原理
spring事务就是对数据库事务的支持,没有数据库的事务支持,spring是无法提供事务
功能的。
11、spring的常用注解
@Component(注解)
@Controller(表现层)
@Service(逻辑层)
@Repository(持久层)
@Scope:设置spring的作用域
@Bean:用于将方法对象返回容器
@import 在一个配置类帐导入其他配置类的内容
@AutoWired 按照类型匹配注入
@Resource :按照名称匹配依赖注入
@ComponentScan:用于对组件(@Componet)进行扫描
@Value 将外部的值动态注入到Bean中
12、 spring用到了那些设计模式
工厂模式:BeanFactory 就用到简单工厂模式
单例模式:Bean默认为单例模式
代理模式:AOP用到JDK的动态代理
模板模式:减少代码冗余,JDBC模板等
观察者模式:定义对象间的一对多的关系,当一个对象状态发生改变时,所依赖于它的对象都得到通知并自动更新,spring监听器的实现就用到观察者模式
适配器模式:
Spring boot
1、springBoot的核心配置文件有哪些,作用是什么
application和bootsrap 配置文件
application:用于项目的自动化配置
bootstrap: 一些不能被覆盖的属性和加密或解密的场景,比application要先加载
2、什么时热部署,spring boot 怎么实现热部署
热部署: 修改代码不需要重启,就可以实现编译并部署到服务器上
(1)在开发时修改代码不重启服务,节省时间
(2)部署在服务器上的程序,可以在不停止的情况下进行升级
如何实现:
1、使用devtools.在配置文件中把devtools,restart.enabled设置为true,每次都需要重新build一下
2、idea实现热部署
3、Spring Boot的核心注解时哪个?它主要由那几个注解组成的或介绍一下@SpringBootApplication 注解
@SpringBootApplication :包含三个注解
@SpringBootConfiguration :实现@Configuration注解,实现配置文件的功能
@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,
@ComponentScan: Spring 组件的扫描
4、Spring Boot 启动流程
1、创建SpringApplication 对象
在spring boot 应用程序中,通常会创建一个 SpringApplicatin 对象,这时通过在main方法中调用SpringApplcation.run(Applicatin.class,args) 实现的,例如:
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
2、初始化SpringApplication
SpringApplcaiton 对象在创建时,会进行一些初始化操作,包括但不限于:
设置应用类型:判断应用时web应用还是普通应用
设置监听器:添加事件监听器,用于监听Spring boot 启动过程中的事件
设置主来源: 确定应用程序的主类(通常是包含Main方法的类)
3、运行SpringApplication
调用SpringApplication.run()方法后,SpringBoot开始启动流程:
推断环境属性:从命令行参数、环境变量、配置文件等处读取并解析配置属性
加载配置:加载application.properties 或application.yml 中的配置
创建ApplictionConttent:根据推断和应用配置,创建ApplicationContext 实例
注册Bean:扫描并注册所有标注@Component、@Service 、@Repository @Controller 等注解的Bean
初始化Bean:对注册的Bean进行初始化
启动嵌入式服务器(如果是Web):如果是Web应用,SpringBoot 将启动内嵌的Tomcat、Jetty 或Undertow 服务器
触发事件: 在启动过程红,会触发一系列事件,如ContextRefreshedEnvent 等
完成启动: 最后,输出启动完成的日志信息,包括启动时间等信息
4、应用运行
一旦ApplcationContentex 被创建并初始化完成,应用就进入了运行状态,可以处理Http请,或者执行其他的业务逻辑
5、优雅停机
当需要停止Spring boot应用时,可以调用SpringApplciatin.exit()方法,这将触发关闭钩子,运行应用优雅关闭,执行清理操作,关闭数据库等
SpringMVC
Spring cloud
1、使用Spring Cloud 有什么优势
使用Spring Boot 开发分布式微服务时,我们面临以下几个问题:
1、与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题。
2、性能-问题 由于各种运营开销导致的性能问题。
3、冗余-分布式系统中的冗余问题。
4、负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央 处理单元,或磁盘驱动器的分布。
2、什么是 Hystrix?它如何实现容错?
Hystrix 是一个用于处理分布式系统延迟和容错的开源库,它提供了线程隔离、断路器等功能,可以帮助开发者在微服务架构中实现容错。Hystrix 主要是用 Java 语言编写的,但也可以在其他 JVM 语言中使用。
Hystrix 实现容错方式:
(一)监控服务调用
-
指标收集:Hystrix 会收集服务调用的各种指标,如请求数量、成功数量、失败数量、超时数量等。这些指标可以帮助开发者了解服务的运行情况,及时发现问题。
-
实时监控:通过实时监控这些指标,Hystrix 可以在服务出现问题时及时采取措施,如打开断路器、进行降级处理等。
(二)快速失败
-
原理:当一个服务出现故障时,Hystrix 会立即返回失败,而不是等待超时。这样可以避免客户端长时间等待,提高系统的响应速度。
-
好处:快速失败可以减少故障对系统的影响,同时也可以让客户端更快地尝试其他的服务或者采取其他的措施
(三) 降级处理
-
自动降级:当一个服务不可用时,Hystrix 会自动执行降级处理,返回一个预设的默认值或者执行一个备用的逻辑。
-
人工降级:开发者也可以根据实际情况手动触发降级处理,例如在系统维护期间或者出现重大故障时。
(四)恢复服务调用
断路器状态转换:当服务的错误率下降到一定阈值以下时,Hystrix 会自动尝试恢复服务的调用。断路器会从打开状态转换为半打开状态,此时会允许部分请求通过,如果这些请求成功,断路器会关闭,恢复正常的服务调用。
健康检查:Hystrix 还可以通过健康检查机制来判断服务是否已经恢复正常。例如,可以定期发送一些测试请求来检查服务的可用性。
3、作为务注册中心,Nacos比Eureka好在哪里?
-
功能全面性:Nacos不仅提供了服务发现和注册功能,还集成了配置管理和消息总线等特性,而Eureka主要聚焦于服务发现与注册,功能相对单一。这意味着Nacos能更好地满足复杂分布式系统的需求,减少对外部工具的依赖。
-
可靠性增强:Nacos支持配置多个注册中心实例,形成集群部署,这显著提高了系统的可用性和可靠性。相比之下,Eureka依赖单一的服务注册中心,一旦该中心发生故障,可能会导致整个服务发现体系的不稳定。
-
健康检查机制:Nacos采用了更为先进的健康检查机制,能够更准确地判断服务的健康状态。而Eureka依赖心跳检测,可能在服务实际已不可用但心跳仍正常的情况下,无法及时移除故障服务。
-
多数据中心支持:Nacos原生支持多数据中心的服务注册与发现,便于进行跨地域的部署和管理。Eureka虽然也能实现多数据中心,但需要借助额外的解决方案,增加了实施难度和维护成本。
-
配置管理服务:Nacos的动态配置服务允许开发者在运行时更改应用配置,并实时推送到相关应用,无需重启服务。Eureka并不提供这样的配置管理功能。
4、什么是CAP原则?
CAP 原则是 Consistency(一致性)、Availablity(可用性)和 Partition-tolerance(分区容错性)的缩写,它是分布式系统中的平衡理论
5、Spring Cloud 各个组件及作用?
1. 服务注册与发现
-
Eureka
Netflix 开源的服务注册与发现组件,微服务启动时向 Eureka 注册自身信息,其他服务通过 Eureka 查询可用服务实例。
注意:Eureka 2.x 已停止维护,推荐替代方案如 Consul、Nacos(Spring Cloud Alibaba)。 -
Consul
支持服务发现、健康检查、键值存储和多数据中心功能,与 Spring Cloud 集成良好。 -
Nacos
Spring Cloud Alibaba 组件,兼具服务注册与发现、动态配置管理功能,支持 AP/CP 模式切换。
2. 配置中心
-
Spring Cloud Config
集中化管理分布式系统的配置,支持 Git、SVN 等存储,需配合 Spring Cloud Bus(基于 RabbitMQ/Kafka)实现配置动态刷新。 -
Nacos Config
提供配置管理和服务发现一体化方案,支持配置实时推送和版本管理。
3. 服务调用与负载均衡
-
Ribbon
客户端负载均衡器,从注册中心获取服务列表,按策略(轮询、随机等)选择实例调用。 -
OpenFeign
声明式 HTTP 客户端,整合 Ribbon 和 Hystrix,通过接口注解简化服务调用。
4. 断路器与容错
-
Hystrix
Netflix 的断路器实现,通过熔断、降级和隔离机制防止服务雪崩。
注意:已进入维护模式,推荐替代方案 Resilience4j 或 Spring Cloud Circuit Breaker。 -
Sentinel
Spring Cloud Alibaba 组件,支持流量控制、熔断降级和系统自适应保护。
5. API 网关
-
Spring Cloud Gateway
基于 WebFlux 的异步非阻塞网关,支持路由、过滤(鉴权、限流)、重试等,性能优于 Zuul。 -
Zuul
Netflix 的 API 网关,基于 Servlet 2.5(阻塞模型),适合旧项目。
6. 消息驱动
-
Spring Cloud Stream
抽象消息中间件(如 Kafka、RabbitMQ),通过绑定器(Binder)简化消息发布/订阅,支持函数式编程。 -
Spring Cloud Bus
利用消息中间件广播状态变更(如配置更新),连接分布式节点。
7. 分布式链路追踪
-
Sleuth
为请求添加唯一跟踪 ID(Trace ID 和 Span ID),集成日志系统(如 Logback)以追踪调用链。 -
Zipkin
可视化分布式追踪数据,分析延迟问题和服务依赖关系。
8. 安全
-
Spring Cloud Security
基于 OAuth2 和 JWT 实现认证与授权,保护微服务间通信,支持单点登录(SSO)和资源服务器配置。
9. 监控与管理
-
Spring Boot Admin
监控微服务实例的健康状态、日志、线程等信息,提供可视化界面。 -
Hystrix Dashboard/Turbine
监控 Hystrix 断路器状态,Turbine 聚合多实例数据。
10. 其他工具
-
Spring Cloud Contract
契约测试工具,确保服务提供者与消费者的接口一致性。 -
Spring Cloud Task
管理短期任务(如批处理作业),支持任务生命周期监控。 -
Spring Cloud Vault
管理敏感信息(如数据库密码),与 HashiCorp Vault 集成。
Spring Cloud Alibaba 生态
-
Nacos
服务注册与发现、配置中心二合一。 -
Sentinel
流量控制、熔断降级。 -
Seata
分布式事务解决方案,支持 AT、TCC 模式。 -
RocketMQ
高性能消息中间件,与 Spring Cloud Stream 集成。
6、Spring Cloud 雪崩问题
在微服务架构中,服务间的调用关系错综复杂,一个微服务往往依赖于多个其它微服务。当某个微服务出现故障时,可能会引发级联失败,导致整个系统崩溃,这就是所谓的雪崩问题。
雪崩问题的根本原因是服务间的耦合度过高。当某个微服务出现故障时,会导致依赖它的其它微服务也出现故障,进而引发级联故障。此外,服务间的调用关系也可能存在环路,导致故障的快速传播。
1、超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待。
2、舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
3、熔断降级: 由断路器统计业务执行的异常比例,如果超出阈值则熔断该业务,拦截访问该业务的一切请求
4、流量控制:限制业务访问的QPS,避免服务因流量的突增而故障
7、服务保护技术对比
在SpringCloud 当中支持多种服务保护技术,早期比较流行的是Hystrix框架,但是目前国内最广泛的还是阿里巴巴的Sentinel框架,方案对比
Sentinel | Hystrix | |
隔离策略 | 信号量隔离 | 线程池隔离、信号量隔离 |
熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比例 |
实时指标实现 | 滑动窗口 | 滑动窗口 |
规则配置 | 支持多种数据源 | 支持多种数据源 |
扩展性 | 多个扩展点 | 插件形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于QPS,支持调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动、均匀排队模式 | 不支持 |
系统自适应保护 | 支持 | 不支持 |
控制台 | 开箱即用、可配置规则、查看秒级监控、机器发现等 | 不完善 |
常见框架适配 | Servlet、SpringCloud Dubbo、gRpc 等 | Servlet、SpringCloud Netflix |
8、Sentinel 的熔断配置项
1、FeignClient 编写失败后的降级逻辑
· 方式1:FallbackClass,无法对远程调用的异常做处理
方式2:FallbackFactory,可以对远程调用的异常做处理,
熔断规则:
1、流控规则
流控模式:直接:api达到限流条件,直接限流
关联:当关联的资源达到阈值时,就限流自己
链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就限流)
流控效果:
1、直接失败:直接失败抛异常
2、Warm UP: 根据 codeFactor 的值,从阈值 经过预热时长,才能达到设置的QPS阈值
3、排队等待:均匀排队,让请求匀速通过,阈值类型必须设置为QPS
9、Spring Cloud 负载均衡策略
1、轮询(RoundRobin)
按照顺序依次将请求分发到各服务实例
2、随机(Random)
随机选择一个服务实例处理请求
3、权重(Weigheted)
根据服务实例的权重分发请求
4、基于响应时间(Best Available)
优先将请求发到响应时间最短的实例
10、Nacos 如何进行服务的注册和发现的
1、服务注册:当服务实例启动时,会向Nacos 发生一个注册请求,这个请求包括服务的相关信息、如服务名、IP地址、端口号等
2、服务同步:Nacos 服务器接收到注册信息后,会将这些信息存储在服务列表中,并同步到其他额Nacos节点,保证服务信息的一致性
3、服务发现:当客户端需要调用服务时,它会向Nacos服务器请求该服务的信息,Nacos会返回服务列表,客户端可以根据这些信息找到响应的服务实例进行调用
4、心跳检测:服务实例会定期向Nacos 发送心跳包,以证明自己还活着,如果Nacos在配置的时间内未检测达到某服务实例的心跳,会认为该实例不可用,从服务列表中移除。
5、服务更新:当服务实例的钻沟通发生变化,或者有新的实例注册时,Nacos会实时更新服务信息,并通知给其他服务消费者。
11、Spring Cloud Alibaba Seata 是如何处理分布式事务的?
1、事务协调
2、AT模式:自动变更追踪,适用于大多数单数据库的分布式常见,它通过记录数据变更的状态来实现事务的回滚和提交
3、TCC模式:Tty-Confirm-Cancel 模式,适用于复杂业务逻辑,每个操作分为尝试、确认、取消三个阶段
4、Saga模式:适用于长事务处理,将长事务拆分成多个事务,每个事务都可以独立提交或回滚
5、分支注册和报告:服务在参与分布式事务时,需要向Seata注册事务分支,完成后报告事务的状态
mybatis
1、#{}和${}的区别是什么?
Mybatis在处理时,就是把 {}时,就是把时,就是把{}直接替换成变量的值。而Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为号,调用PreparedStatement的set方法来赋值;
使用#{}可以有效的防止SQL注入,提高系统安全性。
2、Mybatis的一级、二级缓存?
(1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存
(2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;
(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。
3、Hibernate 与 MyBatis 比较
MyBatis与Hibernate在性能、开发灵活性、学习维护上有差异。MyBatis允许直接写SQL,缓存机制灵活;Hibernate自动生成SQL,缓存复杂。MyBatis学习易,维护清晰;Hibernate学习难,维护复杂。
MyBatis
MyBatis 是一个半自动ORM(对象关系映射)框架。它提供了对SQL的直接操作能力,允许开发者手动编写SQL语句来完成数据的增删改查。
特点:
-
SQL 完全可控:开发者可以完全控制SQL语句,可以编写动态SQL来满足复杂查询的需求。
-
灵活性高:可以很容易地与任何数据库交互,因为它不依赖于特定数据库的高级特性。
-
轻量级:相对于Hibernate来说,MyBatis的实现更为轻量,因为它不包含完整的对象生命周期管理。
-
配置或注解:可以通过XML配置文件或注解来配置映射规则。
使用场景:
-
当项目对SQL有高度定制化需求,需要精确控制SQL语句时。
-
当项目需要与多种数据库交互,且不希望框架绑定特定的数据库特性时。
Hibernate
Hibernate 是一个全自动的ORM框架,它使用元数据(通常是XML文件或注解)来描述对象模型与数据库表之间的映射关系,并通过HQL(Hibernate Query Language)或JPQL(Java Persistence Query Language)来执行查询。
特点:
-
全自动ORM:Hibernate自动处理数据库表到Java对象的映射,包括对象的持久化和查询。
-
高级特性支持:如懒加载、缓存、事务管理等,这些特性通常在Hibernate中内置支持。
-
面向对象:Hibernate的设计更接近于面向对象编程,它通过对象的方式来管理数据库操作。
-
复杂性:相对于MyBatis,Hibernate的实现更为复杂,因为它提供了更高级的对象生命周期管理功能。
使用场景:
-
当项目需要快速开发,并且希望减少SQL编写的复杂度时。
-
当项目需要利用Hibernate提供的复杂特性(如缓存、事务管理等)时。
-
当项目团队更熟悉面向对象编程,希望减少对SQL的依赖时。
总结
-
选择MyBatis:如果你需要完全控制SQL,希望保持轻量级框架,或者需要与多种数据库交互,那么MyBatis可能是更好的选择。
-
选择Hibernate:如果你希望减少编写SQL的工作量,需要利用ORM框架的高级特性(如缓存、事务管理等),并且团队更倾向于面向对象编程,那么Hibernate可能更适合你的项目。
数据库
1、理解EXPLAIN 与执行计划分析
EXPLAIN ANALYZE 的输出 (Seq Scan ,Index Scan ,Index Only Scan 、Nested Loop、Hash Join、Merge Join 等)
关键指标:const(预估成本)、Row (返回行数)、actual time(实际耗时)、BUffers (缓存命中率)
PostgreSQL
中间件
1、缓存穿透、缓存击穿、缓存雪崩的理解和解决方案
缓存穿透、缓存击穿、缓存雪崩的理解和解决方案[通俗易懂]-腾讯云开发者社区-腾讯云
缓存穿透
缓存穿透是指查询一个根本不存在的数据,缓存层和持久层都不会命中,在日常工作中出于容错考虑,如果从持久层查不到数据则不写入缓存层,缓存穿透将导致不存在的数据每次请求都要到持久层去查询,失去了缓存保护后端持久的意义。
缓存穿透问题可能会使后端存储负载加大,由于后端持久层不具备高并发,甚至可能造成后端存储宕机,通常可以在程序中统计总调用数、缓存层命中数,如果同一个Key的缓存命中率很低,可能是出现了缓存穿透的问题
解决方案
1、缓存空对象
缓存空对象:是指在持久层没有命中的情况下,对key进行set 空对象
2 布隆过滤器拦截,在访问缓存层和存储层之前,将存在的key 用布隆过滤器保存起来,做第一层拦截,当收到一个对key 请求时先用布隆过滤器验证key是否存在,如果存在,再进入缓存层,存储层,
缓存击穿
当前key是一个热点key(例如一个秒杀活动),并发量非常大。 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的SQL、多次IO、多个依赖等。 在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。
解决方案:
分布式互斥锁
只允许一个线程重建缓存,其他线程等待重建缓存的线程走完,重新从缓存获取数据即可
永不过期
从缓存层来看,确实没有设置过期时间,所以不会出现热点Key过期之后产生的额外难题,也就是物理的不过期
从功能层来看,为每个Value 设置一个逻辑过期时间,当发现逻辑过期时间后,使用单独的线程去更新缓存
缓存雪崩
如果缓存集中在一段时间内失效,发生大量大缓存穿透,所有的查询都落在数据库上,造成缓存雪崩
解决方案:
1、缓存层高可用
2、做二级缓存,或者双缓存策略
采用多级缓存,本地进程作为一级缓存,redis 作为二级缓存,不同级别的缓存设置超时时间不同,即使某级缓存过期了,也有其他的缓存级别兜底
3、数据预热
可以通过缓存Reload 机制,预先去更新缓存,再即将发生大并发的前手动触发加载缓存不同的Key,设置不同的过期时间,让缓存失效时间点尽量均匀分布
容器
项目
代码审查主要审查哪些方面:
1、代码质量:评审代码的可读性、可维护性和可扩展性,检查代码是否遵循编程规范和最佳实践,例如命名规范、注释、函数长度等。
2、功能实现:验证代码是否正确地实现了预期的功能和需求,检查代码逻辑是否正确。边界情况是否处理完整等
3、性能优化:检查代码是否存在潜在的性能问题,并提出改进建议。例如,避免不必要的循环,减少重复代码、使用更高效的算法等。
4、安全性:评估代码的安全性;检查是否存在潜在的安全漏洞和风险,例如防止SQL注入、XSS攻击、验证用户输入等
5、单元测试和集成测试:检查代码是否有相应的单元测试和集成测试,并评估测试覆盖率和质量,确保代码变更不会破坏已有的功能和逻辑
6、代码结构和模块化:平时代码的组织结构和模块化程度,确保代码按照功能进行良好的分割,并遵循单一职责原则
7、错误处理和异常信息:检查代码是否正确处理错误和异常情况,包括错误信息的处理、日志记录等。
8、注释和文档:评估代码的文档和注释的质量和完整性,确保代码有清晰的文档说明和注释,方便后续维护和理解
9、代码风格一致性;确保代码遵循团队的编码规范,如命名规则、代码缩进、括号位置等,使用一致的格式化工具来规范代码格式
10、可读性和可维护性:确保代码清晰易懂、便于他人阅读和维护,优化复杂的表达式或函数、避免过于复杂或冗长的代码
11、代码重复性:检查是否存在重复代码。使用DRY原则,避免同样的逻辑出现在不同的地方
12、依赖管理:检查项目中新增的依赖库,确保他们是必要的,且不会引入不必要的复杂性或安全风险。
2、如何实现项目的高并发
1、分布式系统设计
采用分布式系统设计,将任务分配到多个节点上并行处理,显著提高系统的并发处理能力和可扩展性。分布式系统还具备高可用性、数据一致性、安全性等优势,能够确保平台在面临各种挑战时依然能够稳定运行
2、水平扩展
通过增加更多的服务器来处理请求,每个服务器处理一部分数据和请求,从而分散负载。这种策略适用于读多写少的场景,可以通过增加更多的读取节点来提高读取速度和并发处理能力
3、服务治理
采用注册发现、限流、熔断、降级等方案,使每个服务可以自己处理问题,减少人工干预,提高系统的稳定性和可用性
4、缓存机制
使用缓存来减少对数据库的直接访问,特别是对于读多写少的场景,可以通过缓存常用数据来提高读取速度和并发处理能力。对于写多读少的场景,可以采用异步写入和合并写请求的策略来优化数据库操作
5、数据库优化
对于数据库操作进行优化,比如优化SQL语句、使用索引、合理设计表结构等,以提高查询效率和减少响应时间。对于写操作,可以采用异步写入和合并写请求的策略来减少数据库压力
6、负载均衡
通过负载均衡技术,将请求均匀地分配到不同的服务器上,避免某台服务器过载,从而提高系统的整体处理能力和稳定性
7、使用CDN
内容分发网络(CDN)可以减少用户访问源服务器的距离,加快内容传输速度,从而提高并发访问的响应速度和用户体验
3、在总体架构设计包含哪些信息详解
在总体设计阶段,需要涵盖系统的核心蓝图和关键决策,以确保系统的高效、可靠性、和可扩展。以下是总设包含的主要信息,按逻辑分层组织
一、目标与范围
业务目标:系统解决的业务问题、核心价值(如提升交易效率30%)
范围定义:功能边界(如支持电商交易,不包含物流跟踪)、用户群体(C端消费者+B端商家)
关键需求:优先排序的核心功能(如支付、订单管理)
二、架构视图(多维度拆解)(4+1模型)
逻辑架构
模块划分:微服务划分(用户服务、库存服务)或者分层结构(表现层、业务层)
组件交互:服务间调用方式(REST API、事件驱动)
物理架构
部署拓扑:服务器位置(公有云等)、网络架构
硬件配置:数据库集群规模(主从节点数)、缓存节点容量(Redis 集群大小)
数据架构
数据流:订单数据从APP->API网关-》订单服务-》DB路径
存储设计:关系型数据库(MySQL 分表策略)、大数据存储(HDFS冷热分层)
场景架构
架构使用场景:用例图
开发架构
开发视图:开发视图关注的是架构如何指导开发流程,在这个视图中,软件系统会被分解成小的子程序或软件包,并为每个子程序或软件包定义接口。系统设计人员会根据这些分解的子程序和软件包分配工作内容
安全架构:
防护体系:身份认证(OAuth2.0)、数据加密(TLS/字段加密)
三、技术选型和核心组件
技术栈:编程语言(Java/Python)、框架(Spring Cloud / Django)
关键中间件:消息队列(Kafka VS RabbitMQ选型原因)、API网关(Kong VS Envoy 对比)
基础设施:云服务商(AWS)\容器化方案
4、非功能设计需求属性
性能指标:响应时间()、吞吐量、QPS
可用性设计:多活架构(异地多活实现方案)、故障转移(数据库主从切换策略)
扩展性:水平扩展设计(无服务状态+自动伸缩组)
安全合规:GDPR数据合规措施、审计日志保留策略
5、部署与运维架构
部署模型:混合云架构(敏感数据本地化+计算层云端扩展)
灾备方案:PRO/RTO 目标(数据丢失时间、恢复时间)
监控架构:指标采集(Prometheus +Grafana)、日志分析
6、集成与接口
内部集成:服务发现机制(Consul /Zookeeper)、内部通信协议(gRPC优化点)
外部集成:第三方API 鉴权方式(JWT令牌交换)、数据交换方案
7、演进路线图
阶段规划:MVP 版本(3月上线核心方案)、V2.0(6个月后引入AI 推荐)
技术债管理:临时方案标记
8、约束与假设
已知限制:团队技术栈限制(暂无Go语言经验、预算限制)
关键假设:假设第三方支付接口延迟<100ms,否则需设计补偿交易机制
9、风险评估与应对
技术风险:如选型的放方案不成熟-》制定回滚Mysql 方案
资源风险:核心开发人员流失->建立文档文化+交叉培训
10、交付物清单
架构图
设计文档:
原型代码
关键设计原则:
简单性:避免过度设计
演进能力:预留扩展点
故障隔离: 服务熔断策略
4、在项目中遇到什么样的问题,如何解决的
-
真实性:从简历中提取真实技术点(如PostgreSQL、RocketMQ、Sentinel),避免虚构工具链。
-
结构化表达:按“问题→分析→解决→结果”逻辑展开,突出技术决策背后的思考。
-
数据支撑:用量化指标(响应时间、吞吐量、故障率)体现结果可信度。
-
扩展性:为追问留出“钩子”,如提到“未来1000 TPS”引导面试官深入探讨架构演进。