-
Java的基本数据类型
四类八种
整数类型:byte,short,int,long
浮点类型:float,double
字符类型:char
布尔类型:boolean
-
char类型的范围
0 ~ 65535,可以表示16位无符号整数
-
equals和==的区别
-
&,&&的区别
-
String,StringBuffer,StringBuilder的区别,运行效率排序
-
集合的介绍
在 Java 中,集合是用于存储和操作对象的工具,主要分为两大类:Collection 和 Map。
Collection 接口包括三种子接口:List、Set 和 Queue。
- List 是有序的、可重复的集合,常用的有
ArrayList
和LinkedList
和Vector
,其中ArrayList
基于动态数组实现,查询快增删满。LinkedList
基于链表实现,增删快查询慢。Vector线程安全的动态数组,性能较低。 - Set 是无序的、不可重复的集合,例如
HashSet
和TreeSet
,其中HashSet
基于哈希表实现,TreeSet
基于红黑树实现并支持排序。LinkedHashSet基于链表和哈希表,按插入顺序存储。 - Queue 是遵循先进先出(FIFO)规则的队列,例如
PriorityQueue
和LinkedList
。
Map 接口则用于存储键值对(key-value),如
HashMap
和TreeMap
。HashMap
是无序的基于哈希表实现,TreeMap
按键的自然顺序排序基于红黑树实现。Hashtable线程安全的哈希表,性能较低。LinkedHashMap按插入顺序存储键值对。集合框架还提供了工具类
Collections
和Arrays
,用于操作集合和数组,比如排序、搜索等。 - List 是有序的、可重复的集合,常用的有
-
多线程的创建方式
四种
1. 继承
Thread
类实现方式:
- 创建一个类继承
Thread
类。 - 重写
Thread
类的run()
方法,将线程执行的逻辑写在run()
方法中。 - 创建该类的实例并调用
start()
方法启动线程。
特点:
- 简单直观,但不能继承其他类(Java 中不支持多继承)。
- 适合不需要共享资源的场景。
2. 实现
Runnable
接口实现方式:
- 创建一个类实现
Runnable
接口。 - 实现
Runnable
接口的run()
方法,将线程逻辑写在其中。 - 使用
Thread
类创建线程对象,并将Runnable
实现类的实例作为参数传入。
特点:
- 更灵活,可以实现多个接口(不受单继承限制)。
- 适合需要共享资源的多线程场景。
实现
Callable
接口实现方式:
- 创建一个类实现
Callable
接口(位于java.util.concurrent
包)。 - 实现
Callable
的call()
方法,将线程逻辑写在其中。 - 使用
FutureTask
类包裹Callable
对象,再用Thread
启动。
特点:
- 可以返回执行结果或抛出异常。
- 更适合需要有返回值的线程任务。
4. 使用线程池(推荐方式)
实现方式:
- 使用
ExecutorService
接口创建线程池(如Executors.newFixedThreadPool
)。 - 提交任务(
Runnable
或Callable
对象)到线程池。
特点:
- 提高线程管理效率,避免频繁创建和销毁线程。
- 更适合高并发场景。
- 创建一个类继承
-
MySQL中的DQL,DCL,DML,DDL
-
drop和truncate语句的区别
-
内连接和左连接的区别
-
SpringMVC的执行流程
流程总结
- DispatcherServlet 接收请求,调用 HandlerMapping 查找处理器。
- HandlerAdapter 适配处理器并执行控制器方法。
- 控制器方法返回数据(如
ModelAndView
)。 - DispatcherServlet 调用 ViewResolver 解析视图,生成响应。
- 响应结果返回给客户端。
-
过滤器,拦截器,监听器的区别
-
说一下登录的流程
- 用户输入用户名和密码,提交到后端。
- 后端接收请求,验证用户输入。
- 使用数据库检查用户名和密码。
- 比对加密后的密码。
- 如果验证成功:
- 返回会话或令牌。
- 响应中包含登录成功的相关信息。
- 如果验证失败:
- 返回错误信息。
- 前端根据响应:
- 成功:存储状态(如令牌)并跳转页面。
- 失败:提示用户重新输入。
-
Linux的常见的几个命令
-
说一下树的前中后序遍历,图的深度和广度优先搜索
-
说一下快速排序
快速排序是一种基于**分治法(Divide and Conquer)**的高效排序算法。它的核心思想是通过一次排序将数组分为两部分,其中一部分的所有元素都比另一部分的所有元素小,然后递归地对两部分分别进行快速排序。
快速排序的基本步骤
- 选择基准值(Pivot):
- 从数组中选择一个元素作为基准值。
- 通常可以选择第一个元素、最后一个元素或随机选择一个元素。
- 分区操作(Partition):
- 通过一轮排序将数组划分为两个子数组:
- 左侧子数组:所有元素小于等于基准值。
- 右侧子数组:所有元素大于基准值。
- 基准值的位置最终确定。
- 通过一轮排序将数组划分为两个子数组:
- 递归排序:
- 对左子数组和右子数组递归调用快速排序,直到子数组长度为 0 或 1(此时已经有序)。
- 组合结果:
- 左子数组 + 基准值 + 右子数组形成排序后的数组。
优点:
- 平均时间复杂度较低,为
O(n log n)
。 - 原地排序,不需要额外的存储空间。
- 在实际工程中表现优良,常被视为快速排序的实际应用。
缺点:
- 最坏情况下,时间复杂度为
O(n^2)
。 - 递归调用可能导致栈溢出(对于极端数据,可使用尾递归优化)。
- 选择基准值(Pivot):
-
说一下RabbitMQ的组成,以及应用场景
RabbitMQ 是一个开源的消息代理中间件,用于实现 消息的发送、接收、路由和存储,在分布式系统中具有广泛的应用。
组成:
producer
exchange
queue
binding
consumer
connection和channel
virtual host
应用场景:
异步处理
发布-订阅模式
分布式通信
。。。
-
查询数据库第5行到第10行的数据
SELECT *
FROM table_name
LIMIT 5 OFFSET 4;
2.Java比较常用的数据结构,在Java里面中的应用场景。
如果需要 随机访问,选择 ArrayList
。
如果需要 频繁插入和删除,选择 LinkedList
。
如果需要 无序但唯一,选择 HashSet
。
如果需要 有序且唯一,选择 TreeSet
。
如果需要 键值对存储,选择 HashMap
。
-
hashmap 的时间复杂度和空间复杂度 ,详细说说。get(key)
时间复杂度:
增 put O(1) O(n)
删 get O(1) O(n)
改 remove O(1) O(n)
查 O(n)
-
hashmap 数组不够用扩容,hashmap数组扩容可以改进的地方。改进带来的好处。
HashMap 的底层数据结构是一个数组,当存储的键值对数量超过容量(由负载因子
loadFactor
决定)时,会触发扩容。扩容虽然能解决数组不够用的问题,但存在性能开销。以下分析扩容机制、可改进的地方及改进带来的好处。HashMap 扩容存在的问题
- 性能开销大:
- 扩容时需要将所有键值对重新哈希,导致时间复杂度为
O(n)
,影响性能。
- 扩容时需要将所有键值对重新哈希,导致时间复杂度为
- 扩容次数多:
- 如果在短时间内大量插入数据,会频繁触发扩容,增加系统开销。
- 内存浪费:
- 默认负载因子为
0.75
,扩容后数组往往会有部分桶为空,内存利用率降低。
- 默认负载因子为
- 线程安全问题:
- 在多线程环境下使用
HashMap
时,扩容可能引发数据丢失或死循环。
- 在多线程环境下使用
提前估算容量
延迟Rehash
动态负载因子调整:快速增长,内存敏感
增量式扩容
改进哈希函数
使用链表与红黑树混合优化
改进带来的好处
- 性能优化:
- 减少扩容和重新哈希的开销,提高插入效率。
- 避免扩容时的性能“卡顿”现象。
- 内存利用率提升:
- 动态调整负载因子或容量,避免过多的空桶,节省内存。
- 适应高并发场景:
- 平滑扩容操作可以避免多线程环境中的数据竞争。
- 提高用户体验:
- 系统的响应时间更平稳,避免因扩容导致的性能抖动。
- 性能开销大:
-
红黑树大致介绍一下,平衡二叉树与红黑树的区别。
红黑树是一种自平衡二叉查找树(Binary Search Tree, BST),通过颜色属性和调整规则保证在最坏情况下基本操作的时间复杂度为
O(log n)
。红黑树广泛应用于许多计算机系统中,如TreeMap
和TreeSet
。红黑树的性质
- 节点是红色或黑色。
- 根节点始终是黑色。
- 每个叶子节点(空节点)都是黑色的 NIL 节点。
- 红色节点不能连续
- 一个红色节点的子节点必须是黑色。
- 从任一节点到其每个叶子节点的路径都包含相同数量的黑色节点(即黑色高度一致)。
-
mysql的索引索引(b+树),详细说说B+树、红黑树、平衡二叉树。
-
spring的理解(ioc和aop),bean的生命周期,几种不同类型的生命周期详细说说区别,
控制反转(Inversion of Control) 是一种设计思想,通过将对象的创建和依赖管理交由 Spring 容器完成,开发者只需关注业务逻辑。
面向切面编程(Aspect-Oriented Programming) 通过定义切面,将与业务逻辑无关的公共功能(如日志、事务、权限校验)与主业务逻辑解耦。
-
自己尝试写一个ioc容器,分别有四种场景:每次请求来的时候创建,单例模式static创建、线程创建内,进程创建内,怎么用Java来实现这四种场景
每次请求创建(Prototype)、单例模式(Singleton)、线程级别(ThreadLocal)、进程级别(全局单例)。
-
你怎么给小朋友解释ioc的概念
假设小朋友每天都需要喝牛奶:
- 不用 IOC:每天小朋友都要跑到超市买牛奶(主动获取依赖)。
- 用 IOC:家长每天把牛奶送到小朋友手里(依赖注入,控制权反转)。
-
你有看过spring的源代码么,spring的设计模式
Spring Boot 带来的好处
-
快速开发
:
- 自动配置和内嵌服务器简化开发流程。
-
减少配置
:
- 减少冗长的 XML 或 Java 配置。
-
一致性依赖
:
- 通过
Spring Boot Starter
管理依赖版本,减少冲突。
- 通过
-
开箱即用
:
- 提供内置功能(如 Actuator、DevTools)提高开发效率。
-
-
springboot和spring的区别,平常使用springboot给你最大的好处是什么,自己写过自定义注解么,自定义注解大概的流程详细说说
自定义注解的步骤
- 创建注解类:
- 使用
@interface
定义注解。 - 指定元注解(如
@Retention
和@Target
)。
- 使用
- 编写注解逻辑:
- 利用反射读取注解的属性和行为。
- 在运行时、编译时或加载时实现自定义逻辑。
- 注册注解处理逻辑:
- 如果是运行时注解,在框架或工具类中解析并执行注解行为。
- 如果是编译时注解,使用
Annotation Processor
。
- 创建注解类:
2.说说你对面向对象和面向过程的理解
以过程为中心,问题分解为若干步骤,逐步解决。
以对象为中心,使用对象封装数据和行为,通过对象交互完成任务。
3.面向对象的特征(继承封装多态)
将对象的属性和行为隐藏起来,通过访问方法(getter/setter)暴露必要接口。
子类继承父类的属性和方法,形成父子关系。
对象可以以不同形式表现(编译时多态、运行时多态)。方法重载(编译时多态)。方法重写 + 父类引用指向子类对象(运行时多态)。
4.接口和抽象类的区别(接口制定规范、抽象类复用代码)
5.Java的基本数据类型(8种)
int的取值范围(问我怎么推倒出来的取值范围)
6.int 的包装类 (integer区别和用法,拆箱和装箱)
Integer 的特点
- 包装类,提供
int
的对象封装。 - 包含静态常量
MAX_VALUE
和MIN_VALUE
,表示取值范围。 - 支持自动装箱与拆箱。
拆箱与装箱
- 装箱:
int
转为Integer
。 - 拆箱:
Integer
转为int
。
7.jvm对integer进行一个范围保存,能调整么(-128~127,不知道怎么调整这个范围)
范围:-128
到 127
。
- 在此范围内的 Integer 对象会被缓存,重复使用。
- JVM 内部维护一个
IntegerCache
。
调整方法:通过 JVM 参数 -XX:AutoBoxCacheMax=<value>
修改最大值。
8.Java线程池的一个工作原理(Java线程池的7大核心参数和4种拒绝策略),调整线程池的大小(创建线程池的时候使用构造函数指定线程池的大小和线程数量,具体让我说核心线程数和最大线程数,核心线程数+救急线程=最大线程数),
7.1 核心组件
-
线程池的工作流程
:
- 提交任务。
- 若线程数未达到核心线程数(
corePoolSize
),则创建新线程。 - 若达到核心线程数,任务放入阻塞队列。
- 若阻塞队列已满且线程数小于最大线程数(
maximumPoolSize
),则创建救急线程。 - 若线程数达到最大线程数,任务被拒绝(触发拒绝策略)。
7.2 线程池的 7 大核心参数
- corePoolSize:核心线程数。
- maximumPoolSize:最大线程数。
- keepAliveTime:救急线程空闲时间,超过时间会被销毁。
- unit:
keepAliveTime
的时间单位。 - workQueue:任务队列(阻塞队列)。
- threadFactory:线程工厂,创建线程时定义线程属性。
- handler:拒绝策略(当任务无法处理时的应对方法)。
7.3 线程池的 4 种拒绝策略
-
AbortPolicy
(默认):
- 抛出
RejectedExecutionException
异常。
- 抛出
-
CallerRunsPolicy
:
- 由提交任务的线程直接执行任务。
-
DiscardPolicy
:
- 丢弃无法处理的任务。
-
DiscardOldestPolicy
:
- 丢弃队列中最旧的任务,执行新任务。
9.说说对apo的理解(面向切面编程,无侵入增强方法),说一说aop种的概念(切面、切点、通知。。。),具体说说怎么对类中的方法进行增强(通知和找到方法所在类的路径进行方法增强),说一下aop执行顺序(我大致说了一下spring中有过滤器链)
9.1 AOP 概念
- 面向切面编程(Aspect-Oriented Programming) 是一种编程范式,用于动态增强目标对象的功能,达到无侵入的代码扩展。
- 核心思想:将横切关注点(如日志、事务、权限校验)从业务逻辑中剥离,通过切面模块动态织入目标方法。
9.2 AOP 的核心概念
-
切面(Aspect)
:
- 模块化的关注点定义,如日志记录、事务管理。
-
切点(Pointcut)
:
- 定义在哪些位置织入增强逻辑。
- 通过表达式(如
execution
)定义匹配规则。
-
通知(Advice)
:
-
切面的增强逻辑。
-
类型
:
- 前置通知(
@Before
):方法执行前增强。 - 后置通知(
@After
):方法执行后增强。 - 返回通知(
@AfterReturning
):方法正常返回后增强。 - 异常通知(
@AfterThrowing
):方法抛出异常时增强。 - 环绕通知(
@Around
):方法前后均可增强。
- 前置通知(
-
-
目标(Target)
:
- 被增强的对象或方法。
-
织入(Weaving)
:
- 将切面逻辑应用到目标对象的过程。
9.3 实现方法增强
-
配置切点
:
- 使用
@Pointcut
定义方法匹配规则。
- 使用
-
实现通知
:
- 编写增强逻辑,并通过
@Before
、@Around
等注解应用到切点。
- 编写增强逻辑,并通过
9.4 AOP 的执行顺序
-
Spring 中的 AOP 执行顺序
:
- 前置通知 → 目标方法 → 返回/异常通知 → 后置通知。
- 依赖 责任链模式 管理通知的执行顺序。
10.说说对jdk动态代理的理解(Java种有2种动态代理,jdk和cglib,说了一下使用场景,反射,aop,事务,jdbc连接数据库 class.forname)
10.1 动态代理的定义
-
动态代理 是在运行时动态生成代理类,拦截目标对象的方法调用并添加增强逻辑。
-
Java 提供两种动态代理:
-
JDK 动态代理
:
- 基于
java.lang.reflect.Proxy
,仅支持接口代理。
- 基于
-
CGLIB 动态代理
:
- 使用子类继承目标类,支持类和接口代理。
-
10.2 使用场景
-
JDK 动态代理
:
- 适合接口的代理,如日志记录、事务管理。
-
CGLIB 动态代理
:
- 适合类代理,如增强方法执行逻辑。
11.mysql 动态sql 标签简单说说,#和 符号的区别,什么使用 符号的区别,什么使用 符号的区别,什么使用符号(不会)
#
(预编译,占位符):- SQL 中的参数使用占位符
?
。 - 防止 SQL 注入。
- 用于大多数场景。
- SQL 中的参数使用占位符
$
(字符串拼接):- 直接拼接 SQL,危险,易受 SQL 注入攻击。
- 用于动态传递字段名或表名。
12.mysql列格式都有哪些(数值,时间datetime,文本varchar char text blog BigDecimal),
13.说一下金额为什么要用BigDecimal 而不是 float和double (标度和数值,float和double近似值)
精度丢失
14.分析一条sql的执行计划(explain 关注 key type extra 这三个属性,并简单解释了这3个属性)
15.说一下你对微服务和boot的理解(多个单体组成微服务,微服务将功能更加细化,每一个功能做成一个服务,职责更加细化)
16.说说你对分布式的cap的理解(听不懂,不会)
Consistency(一致性):
- 所有节点的数据一致。
Availability(可用性):
- 服务始终可用。
Partition Tolerance(分区容错性):
- 系统可容忍网络分区。
分布式系统不能同时满足 CAP,只能取其二。
常见组合:
- CP:如 Zookeeper。
- AP:如 Cassandra。
17.说说springcloud的常用组件(nacos,sentinel,gateway,openfeign)
Spring Cloud 常用组件
- Nacos:服务注册与发现。
- Sentinel:限流、熔断。
- Gateway:API 网关,路由和过滤。
- OpenFeign:服务间的声明式 HTTP 调用
18.分布式和集群的区别(集群 反向代理,分布式 gaetway网关)
19.说说你项目中遇到的问题,并怎么解决的。
20.mvvm模型是否了解(简单说了下,双向绑定 )
get post 区别?
redis数据结构有哪些?(string list hash set zset hyperLogLog Bitmap)
Java实现线程安全的机制(synchronized ReentrantLock ReadWriteLock CAS)
synchronized 使用方法?(方法上 代码块)
synchronized 能用在属性上吗?(不能)
linux命令说说?(top ps -ef df free iostat ifstat vmstat)
如何部署的项目?
遇到问题怎么解决的?
说说常见的异常?
ConcurrentModificationException 如何出现?
用过哪些线程安全的集合(CopyOnWriteArrayList ConcurrentHashMap … )
空指针异常如何出现,怎么预防?(“abc”.equals(str) StringUtil.isBlank() )
用过哪些工具包?(HTMLUtil)
如何读取xml文件(忘了)
yml 和 properties的区别?
配置文件放在jar包外怎么弄?几种方法
SpringCloud的组件你知道哪些?
服务之间调用的方法你知道哪些?(Restful feign rpc MQ)
网络几层结构
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
redis
Redis(Remote Dictionary Server)是一种基于内存的高性能键值存储数据库,支持多种数据结构,并提供丰富的功能扩展,广泛应用于缓存、消息队列、实时分析等场景。