1、compareable和compactor区别
Comparable:是类内部实现的接口(位于java.lang 包),通过实现compareTo()方法定义对象的“自然排序规则
Compactor:是外部比较器(位于java.util 包),通过独立类实现compare()方法,允许在不修改原类代码的情况下定义多种排序规则
排序逻辑:Comparable由类自身定义唯一排序规则,Compactor可以自定义多种排序规则
2、SpringIOC,什么是控制反转,什么是依赖注入?
IOC其实就是控制反转,依赖注入(DI)是SpringIOC的一种实现方式
IOC(Inversion of Control):IOC指将对象的创建和管理权交给Spring容器(如ApplicationContext)统一控制。传统开发中,对象通过new主动创建依赖,而IoC模式下,容器负责对象的生命周期和依赖关系
DI(Dependency Injection):是IoC的具体实现方式,指容器在运行时动态将依赖对象注入到目标组件中
依赖注入的两种实现方式:
- XML配置:通过
<bean>标签定义对象及依赖关系。 - 注解:如
@Autowired(按类型注入)、@Resource(按名称注入)、@Component等,简化配置
依赖注入的三种方式
构造方法注入
Setter方法注入
属性注入:@Autowired,@Resources
spring容器的核心作用
创建和管理bean、依赖注入、管理bean生命周期
SpringAOP是什么?特点是什么
Spring AOP(面向切面编程)是 Spring 框架的核心模块之一,通过动态代理技术将横切关注点(如日志记录、性能监控、事务管理、安全控制等)与业务代码解耦。
核心是:
切面(Aspect)
封装横切逻辑的模块化单元,通过@Aspect注解定义。例如日志切面类中可包含记录方法执行时间的代码
连接点(JoinPoint)
程序执行过程中的可插入点,如方法调用、异常抛出等。Spring AOP仅支持方法级别的连接点
通知(Advice)
通知类型:
- 前置通知(@Before):在方法执行前触发(如权限校验)。
- 后置通知(@After):在方法执行后触发(如日志记录)。
- 环绕通知(@Around):包裹目标方法,可控制执行流程(如事务管理)。
- 异常通知(@AfterThrowing):在方法抛出异常时触发(如错误处理)。
- 返回通知(@AfterReturning):在方法正常返回后触发
优点:与业务代码解耦,提高代码复用性,代码灵活性提高
代理
静态代理
动态代理
JDK动态代理:需要实现至少一个接口,这个接口可以是任意接口,spring会扫描是否使用了接口,如果有接口就用JDK动态代理,运行时动态生成接口实现类,用代理去掉用实现类的方法
CGLIB动态代理:是一个外部的类库,支持去代理未实现接口的普通类
JDK动态代理与CGLIB在Spring中互补使用,前者适用于接口代理,后者覆盖无接口场景
3、BIO/NIO/AIO区别
同步:同步就是发起一个调用后,被调用者未处理完请求之前,调用者不返回
异步:异步就是发起一个调用后,但是被调用者并没有返回结果,此时调用者可以处理其他请求。
阻塞:阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续。
非阻塞:非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。
-
BIO是同步阻塞I/O模型,它使用一个线程来处理一个请求,如果这个请求没有被处理完,这个线程就会一直等待,直到请求处理完成。
-
NIO是同步非阻塞I/O模型,它使用单个线程来处理多个请求,这些请求可以同时被这个线程处理,它通过轮询的方式来处理I/O请求,如果有I/O请求就处理,没有就继续轮询。这种模型适用于连接数较多但是连接时间短的情况
-
AIO是异步非阻塞I/O模型,这种模型不需要为每个请求创建一个线程,由操作系统内部的线程来处理I/O请求,同时它也具有非阻塞的特性,I/
O请求不会一直等待,而是异步执行。这种模型适用于连接数很多的情况
举个生活中简单的例子,你妈妈让你烧水,小时候你比较笨啊,在那里傻等着水开(同步阻塞)。等你稍微再长大一点,你知道每次烧水的空隙可以去干点其他事,然后只需要时不时来看看水开了没有(同步非阻塞)。后来,你们家用上了水开了会发出声音的壶,这样你就只需要听到响声后就知道水开了,在这期间你可以随便干自己的事情,壶响了你需要去倒水了(异步非阻塞)。
4、final 在 Java 中有什么作用?
-
final 修饰的类叫最终类,该类不能被继承。
-
final 修饰的方法不能被重写。
-
final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
5、Java中的容器都有哪些?

6、http和https区别
传输形式:http是明文传输的,https加密传输,采用对称加密和非对称加密结合的方式
传输协议:http基于TCP协议,而https基于SSL/TLS 协议
端口不同:http端口为80,https端口为443
证书:https需要证书认证,而http不需要证书
7、Array 和 ArrayList 有何区别
-
Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。
-
Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。
-
Array 内置方法没有 ArrayList 多,比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。
8、哪里用到了对称加密和非对称加密?
对称加密:JWT生成token
非对称:https,阿里云效代码仓库
9、spring框架哪里用到了反射?
1、bean的实例化:Spring通过反射动态创建对象实例,无需硬编码new操作
2、依赖注入:通过反射调用setter方法或直接修改字段(如Field.set() ),将依赖对象注入目标Bean
3、Spring AOP利用反射生成代理对象
4、Spring MVC处理请求:Spring MVC通过反射解析@RequestMapping标记的方法,动态匹配请求参数并执行目标方法
5、数据库访问:Spring JDBC通过反射将ResultSet数据映射到实体类字段
10、SPU和SKU
SPU(Standard Product Unit)标准产品单元:指的是标准化的产品单位,通常是一个品牌下具有相同特征、属性的一类产品,例如,iPhone 13可以被认为是一个SPU,它包含了所有配置和版本的iPhone 13
SKU(Stock Keeping Unit)库存保有单位:是指库存管理中的最小可用单元,用于区分具体商品的种类。例如,不同颜色、不同内存大小的iPhone 13将被视作不同的SKU。
11、Spring Cache是什么的?
SpringCache是Spring提供的一个缓存框架
Spring Cache利用了AOP,实现了基于注解的缓存功能,保证了幂等性,简化代码,提高接口响应速度
Spring Cache不支持TTL的设置,但是可以加上一个#后面可以设置过期时间
12、flowable干嘛的?
简化审核流程的代码,将我们审核流程的代码与业务代码解耦,比如将我们采购单的审核流程通过flowable完成,这样哪怕审核条件变化也可以不用修改代码;
13、xxl-job在哪用到了
1、xxl-job定期扫描死信队列中堆积的消息,每天将死信队列中的消息钉钉推送
2、订单完成:超过20天的订单,xxl-job去扫描订单表里20天前状态为运输中的订单,去调用快递100接口查看这些订单的状态,如果快递的状态为签收则修改订单的状态为完成,如果订单状态还是运输中,就将这些订单推送到客服中心,走人工
3、商品中心第一次全量同步使用ES做个定时任务
4、秒杀系统,在活动开始前5分钟将商品预热到Redis中,原理是我们活动都有一个活动表和活动明细表,XXL-JOB每5分钟扫描一次活动表,用活动表的活动开始日期减去当前日期剩余的时间如果小于五分钟就将活动对应的商品预热到Redis中
5、ELK定期清除10天前的日志
14、聚合支付Jeepay
我们使用的聚合支付jeepay,只需要在Jeepay管理后台填入支付宝/微信等渠道的接口参数(如APPID、密钥),系统自动生成支付路由规则,通过Jeepay提供的Java SDK或HTTP接口,用一行代码发起支付请求,屏蔽不同支付平台的差异,支付结果通过MQ(如RabbitMQ)异步通知业务系统,需验签并更新订单状态,确保高可用。
15、如何设计一个秒杀系统
前端:
1、前端页面静态化+CDN,意思是对于秒杀活动设计来说,我们可以将所有可以静态化的内容全部静态化,然后将其配置在 CDN 服务器上。这样既提高了用户打开页面的时间,又减少了后端服务器的压力。
2、请求频率限制进行优化
后端:
-
增加缓存层 + 预热数据:我们在秒杀活动开始之前,可以手动将热点数据加载到缓存中,从而避免秒杀时去请求数据库
-
MQ 异步处理:
-
限流、熔断、降级
-
业务端优化
16、为什么要序列化和反序列化?
为了能将数据持久化存储,网络传输,跨语言支持,提高效率
其核心作用在于实现数据结构的跨场景兼容性
例如:
网络传输:网络通信只能传输二进制字节流,而程序中的对象无法直接传输。序列化将对象转换为字节流(如JSON、二进制等),接收方再通过反序列化还原为对象,实现跨网络的对象传递
持久化存储:对象无法直接存储到文件或数据库,需序列化为特定格式(如二进制、XML)
序列化和反序列化是连接内存对象与外部介质(网络、存储)的桥梁,解决了数据跨场景交互、持久化和跨语言协作的难题。合理使用可提升系统扩展性,但需注意版本控制、安全性和性能优化。
17、JWT好处
无状态
有效避免CSRF攻击
适合移动后端
单点登录友好
18、线程池核心参数怎么设置
CPU密集型:核心线程数=CPU核数,最大线程数=核心线程数
IO密集型任务:核心线程数=CPU核数x2,最大线程数=根据阻塞系数计算

阻塞系数0~1,阻塞系数越大,CPU越闲,一般阻塞系数为0.8
19、你对工作的期望是什么?
1、我希望通过我的努力,为团队和公司解决实际问题,推动项目的成功落地。同时,我也非常期待能够在团队中与优秀的同事合作,共同成长。
2、我对工作的期望是能够在公司中深入参与到具体技术领域,如分布式系统、大数据处理等相关的项目中。我希望通过实践不断提升自己的技术水平,并将所学应用于实际场景,为公司创造更多价值。
此外,我也期待能够在一个鼓励创新和持续学习的环境中工作,与团队一起攻克技术难题。
20、你自己感觉你是一个怎样的人?
1.好学 2.责任心强 3,协作强 4.吃苦耐劳 5.自我总结自我复盘 6.积极上进
21、你如何去胜任这份工作?
1.多年经验 2.高效的编码能力 3.全栈 4.沟通能力强 5.及时汇报进度
6.自我学习,解决问题 7.同学在这个领域,经常沟通学习
22、你们人脸识别传的核心参数有哪些?
性别,年龄,业主的某一帧的照片
23、享元模式
是一种结构型设计模式,其核心思想是通过共享技术减少大量相似对象的资源消耗,优化内存使用和系统性能。
优点:减少内存占用:通过共享对象避免重复创建;提升性能:降低对象频繁创建/销毁的开销
缺点:增加系统复杂性以及线程安全问题
场景:字符串常量池、数据库连接池、游戏开发(角色与道具复用
)
24、单体数据库挂了怎么保证数据的可靠性?
日志持久化、数据备份与恢复、主从复制、最好采用集群
25、MySQL的二阶段提交
第一阶段先把数据提交的内存和redolog中,二阶段后台起一个线程去将redolog日志里记录的数据刷新到磁盘里
26、list、set、map区别
| 特性 | List | Set | Map |
|---|---|---|---|
| 重复元素 | 允许 | 不允许 | 键唯一,值可重复 |
| Null 值 | 允许多个 null | 最多一个 null(如 HashSet允许,TreeSet不允许) | 键最多一个 null,值允许多个 null |
| 顺序性 | 按插入顺序存储 | 默认无序(TreeSet 有序,LinkedHashSet 按插入顺序) | 默认无序(TreeMap 按键排序,LinkedHashMap 按插入顺序) |
27、实现深拷贝的两种核心方式
1、实现 Cloneable 接口 + 重写 clone() 方法
①目标类实现 Cloneable 接口(标记接口,无方法需实现
②重写 Object 类的 clone() 方法,所有需要深拷贝的引用类型属性所在的类,都必须实现 Cloneable 接口并重写 clone() 方法,否则仅实现浅拷贝
2、序列化(Serializable 接口)
目标类实现 Serializable 接口
通过对象序列化与反序列化生成新对象,自动实现深拷贝
28、死锁产生的条件
互斥条件(锁的互斥):一个资源一次只能被线程持有
保持条件:一个线程获取资源时,会一直持有这些资源,直到获取所有满足的资源才释放
不剥夺条件:已分配的资源不能被其他线程抢走
环路等待:多个线程形成一种循环等待的关系,互相持有对方所需资源,导致死锁
死锁产生这四个条件必须全部满足,少一个都产生不了死锁
如何避免死锁?
1. 尽量避免使用多个锁,尽量使用一个锁。
2.减少锁的粒度, 确保同步代码块的执行时间尽可能短,这样可以减少线程等待时间,从而避免死锁的产生。
3. 使用尝试锁,通过 ReentrantLock.tryLock() 方法可以尝试获取锁,如果在规定时间内获取不到锁,则放弃锁。
4. 避免嵌套锁,如果需要使用多个锁,请确保它们的获取顺序是一致的,这样可以避免死锁。
29、static 属性为什么不会被序列化
因为序列化是针对对象而言的, 而 static 属性优先于对象存在, 随着类的加载而加载, 所以不会被序列化.
static修饰的类的,而我们序列化是针对对象的
30、强软弱虚引用
强引用:普通的变量引用
软引用:
-
当所剩内存空间不够我们新的对象存储的时候,直接干掉软引用。
-
当所剩内存空间够我们新对象的存储的时候,不会删除我们的软引用对象。
弱引用:将对象用WeakReference弱引用类型的对象包裹,弱引用跟没引用差不多,GC会直接回收掉,只要GC执行了,他就会被回收掉.
虚引用:虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系,几乎不用
31、你们接到一个新项目怎么做的?
开需求发布会
技术栈选型
分组开发
核心的接口讨论一下,定义一下入参出参
建代码仓库,接下来每个人去实现自己功能
项目快完成的时候联调测试一下
测试完没问题就上线
上线后跟踪
32、你最近遇到的技术难点?
1、库存的派生列(过期时间)
2、springcloud使用openfeign的时候,当我们使用GetMappering传递的参数是一个对象的时候,需要加一个注解,@springquerymap,否则他会默认将请求当做post请求
3、openfeign的解码器
4、乱脚本进行扣库存
33、为什么不用布隆过滤器
1、不适合新增和下架商品,会影响到其他商品
2、因为误判率是自己固定设置的,一旦商品增加了,hash函数个数就会增加,效率就会变低
3、当我们商品一旦新增或者下架,我们需要重新同步商品
34、购物车使用的什么结构?
hash结构,大key是用户id,小key是商品id,value是时间
35、count(1)、count(*)、count(列名)
count(1)和count(*)在MySQL8的时候性能相差不多,有时候甚至count(*)更快一些,而且count(1)和count(*)一定会走索引,只不过MySQL8以后对count(*)做了些优化,他可以自动的寻找最合适的短索引
count(列名):如果有空值会排除,有索引就走索引
36、支付中遇到过什么问题?
1、支付宝回调返回的是一个html代码,需要我们去执行一下才会跳到回调的页面,不执行跳不过去
2、我们在开发环境下,回调地址需要做内网穿透
37、退款的时候怎么做的?
调支付宝退款接口,传递订单id和退款金额
38、springmvc中只注入一个httpservlet对象怎么做到的?
39、断言提供了哪些方法?
40、stream流按什么分类


41、为什么要序列化?
跨进程之间调用的时候,只能通过序列化将对象转化为可以存储或传输的形式,另一方接受后再将它转为对象
42、重写equals为什么要重写hashcode?
因为equals方法比较两个对象要求两个对象的hashcode相同,如果重写equals而不重写hashcode,hashmap底层的数据结构都乱了
43、插入后获取对应的主键
selectKey
usegeneratekeys
44、为什么禁止使用存储过程
可维护性差,对数据库压力大(用存储过程就把计算压力交给数据库了),性能低
45、受检异常有哪些
FileNotFoundException:当试图打开一个不存在的文件时会抛出该异常
SQLException:在使用 JDBC(Java Database Connectivity)进行数据库操作时,如果出现与数据库相关的错误
ClassNotFoundException:当应用程序试图通过类的全限定名来加载类,但在类路径中找不到该类的定义时
InterruptedException: 当一个线程在等待、休眠或其他暂停状态时,被其他线程中断,就会抛出 InterruptedException 异常
SQL异常,IO异常,
运行时异常有哪些
-
空指针异常(NullPointerException):尝试访问一个未初始化或已置为null的对象的方法或属性时发生。
-
数组越界异常(ArrayIndexOutOfBoundsException):当试图访问数组中不存在的索引位置时发生。
-
类型转换异常(ClassCastException):尝试将一个对象强制转换为不兼容的数据类型时发生。
-
算术异常(ArithmeticException):如除以零等非法的数学操作时发生。
-
文件未找到异常(FileNotFoundException):尝试打开指定路径下的文件进行读取或写入,但该路径下没有此文件时发生。
-
输入输出异常(IOException):处理输入输出操作时遇到的问题,比如网络连接失败、硬盘故障等导致数据不能正常读写。
46、string里有哪些方法?
获取字符串长度length():返回字符串的长度,即字符串中字符的个数。字符串比较equals(Object anObject):比较两个字符串的内容是否相等,区分大小写忽略大小写比较equalsIgnoreCase(String anotherString):比较两个字符串的内容是否相等,不区分大小写compareTo(String anotherString):按字典顺序比较两个字符串,返回一个整数。indexOf(int ch):返回指定字符在字符串中第一次出现的索引位置,如果未找到则返回 -1lastIndexOf(int ch):返回指定字符在字符串中最后一次出现的索引位置,如果未找到则返回 -1contains(CharSequence s):判断字符串是否包含指定的字符序列- 字符串截取
substring(int beginIndex):返回从指定索引位置开始到字符串末尾的子字符串 replace(char oldChar, char newChar):将字符串中所有的旧字符替换为新字符toUpperCase():将字符串中的所有字符转换为大写。toLowerCase():将字符串中的所有字符转换为小写。split(String regex):根据指定的正则表达式将字符串分割成字符串数组。trim():去除字符串首尾的空白字符concat(String str):将指定的字符串连接到当前字符串的末尾toCharArray():将字符串转换为字符数组。
47、threadlocal怎么造成内存泄露的?
threadlocalmap中的key是弱引用,值是强引用,如果只删除了key而不删除值,值会一直存在内存中
为了避免 ThreadLocal 造成的内存泄漏,在使用完 ThreadLocal 后,应该及时调用其 remove 方法
48、开启线程池的步骤?
通过ThreadPoolExecutor类直接创建线程池,设置一些核心参数
使用Executors工具类创建线程池(newFixedThreadPool、newCachedThreadPool()、newSingleThreadExecutor()、newScheduledThreadPool),不建议用
使用hutool工具类ThreadPoolBuilder.create()
49、项目中事务怎么设置的,配了哪些参数,这些参数是多少?
参数:
- propagation:传播行为,默认为
Propagation.REQUIRED。其他选项包括SUPPORTS,MANDATORY,REQUIRES_NEW等。 - isolation:隔离级别,默认为
Isolation.DEFAULT。可以是READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE。 - timeout:事务超时时间,默认值依赖于底层事务系统。(30s)
- readOnly:是否为只读事务,默认为
false。 - rollbackFor:指定哪些异常发生时应回滚事务,默认情况下仅运行时异常会触发回滚。(指定了BizException,RuntimeException,Error)
- noRollbackFor:指定哪些异常发生时不应回滚事务。
50、事务报异常了怎么办?
记录日志
new BizException (错误码和对应的描述)
51、char和varchar区别,哪个性能好
char:char 是固定长度的数据类型,如果存储的字符串长度小于定义的长度,剩余的空间会用空格填充
varchar:varchar 是可变长度的数据类型。它会根据实际存储的字符串长度来动态分配存储空间
- 如果你的字符串长度几乎不变或变化很小(如固定格式的编码、状态码等),使用
char可能更合适。 - 如果字符串长度变化较大,使用
varchar可以节省存储空间,并且在大多数情况下不会显著影响性能。
52、微服务是什么,为什么要用微服务,微服务的好处
微服务是什么:是一种架构概念,旨在通过将功能分解到各个细小的服务中以实现对模块的解耦,实现一个功能的单一职责
为什么用微服务?随着应用规模的增长,传统的单体架构可能会变得庞大而复杂,难以管理和扩展
微服务好处:
易于测试
服务解耦
开发简单,集中式管理
易于部署与升级
较低的维护成本
53、nacos服务收不到心跳,多久标记为不健康的?
每5秒发一次心跳,如果15也就是连续三次服务没有做出响应,将服务标记为不健康状态,openfeign有重试机制,15s不成功,30s收不到就将服务下线
54、你的劣势是什么?
番茄工作法、跟您这样的技术大佬相比我还有很多药学习的
55、给你一个完整的需求,你会怎么做?
深入了解文档需求
将想法和功能写入文档,和领导沟通一下自己的想法
任务细分
功能的划分,确定开发周期
及时向上级汇报
56、如果在订单关闭,我卡那个9分59秒支付,你怎么处理?
我们的队列虽然显示的是十分钟,其实少个5s
下单的时候会带有那个下单时间,我们订单表中记录的有下单时间,如果传到支付宝那边就过期了,支付宝那边自动就不让支付了
57、用过大数据类型的数据库吗?
tidb,postogredb
58、猜你喜欢怎么做?
埋点
找到访问商品,拿到对应的访问次数,拿到对应商品的标签
通过标签查询ES,假如是猜你喜欢是6个,抓取6个商品放在猜你喜欢那里
59、关闭订单就是订单完成
60、OpenFeign的原理与协议
OpenFeign是一种基于动态代理的声明式HTTP客户端,其核心原理围绕接口代理生成和HTTP请求模板化实现
动态代理机制:当使用@FeignClient注解定义接口时,OpenFeign在Spring容器启动阶段会通过FeignClientFactoryBean工厂类,生成该接口的动态代理对象
请求转发:通过代理会将我们的请求转发到nacos对应的服务实例上边,将我们的服务名替换成对应的url,从而调取服务的方法
61、某个接口很慢怎么办
Redis走缓存
JVM层加缓存
SQL优化
发多个版本,Nginx负载
nginx做Jzip压缩
能异步就异步,mq
多线程
62、在线用户统计怎么做
linster里的httpsessionLinstenr,监听session对象的创建和消亡,使用JUC包里的原子类,用户上线了就加一,用户下线就减一
63、为什么要做统一封装?
方便我们前端开发,我们前端使用axios作相应拦截器,方便前端看到底哪里报错了,是0就是成功,不是0我们直接就抛出一个bizexception,做openfeign解码器是因为我们做了统一返回的包装,我们判断一下返回的code是否为0,是0我们就将对应的data通过反序列化成对应的对象
64、拼车是给谁做的?
给我们老板的一个朋友做的
65、门禁系统给谁做的?哪个小区?
给我们当地的一个郑州信良物业管理有限公司做的,覆盖中原区的一些小区,金科城,瓦屋里,万科城,紫薇小区等
66、k8s核心组件?
deployment(部署)-->k8s的yml就是给部署用的
pod(应用)
service(服务),每个应用都可以发服务,我们当时gateway发到k8s的service里是为了以后哪怕gateway发多份,k8s他自己就可以伸缩
67、MySQL行转列实现方式
1:CASE WHEN + 聚合函数
SELECT userid,
MAX(CASE subject WHEN '语文' THEN score ELSE 0 END) AS '语文',
MAX(CASE subject WHEN '数学' THEN score ELSE 0 END) AS '数学',
MAX(CASE subject WHEN '英语' THEN score ELSE 0 END) AS '英语'
FROM scores
GROUP BY userid;
#通过CASE WHEN将每个科目拆分为独立的列,聚合函数(MAX/SUM)确保每个用户仅保留一条记录
2:IF() + 聚合函数
SELECT userid,
SUM(IF(subject='语文', score, 0)) AS '语文',
SUM(IF(subject='数学', score, 0)) AS '数学'
FROM scores
GROUP BY userid;
68、Linux管道命令
“|”在前面的执行结果的基础上在做一层过滤
69、k8s用了几台机器?5台
70、Redis的槽位
定义:Redis 集群将数据划分为 16384 个固定槽位(编号 0~16383)也就是2的14次方,每个槽位对应一个哈希值范围,通过 CRC16 算法对键(Key)计算哈希值后取模(CRC16(key) % 16384)确定所属槽位
Redis集群的每个节点负责管理一部分槽位,经过对key(Redis的键)的计算出槽位,会把请求发送到管理槽位的对应节点上
71、innodb的理解,底层实现是什么(B+树)
InnoDB 是MySQL默认的存储引擎,支持事务,支持外键,默认行级锁,使用聚簇索引
MyISAM 不支持事务,不支持外键,默认表级锁,使用非聚簇索引
innodb的索引数据结构是B+树,B+树只有叶子节点存储数据,并且B+树的叶子节点通过指针连接,形成有序链表,这样范围查询更高效
72、http基于tcp协议,默认是短连接,可以减轻服务器压力
73、httpclient和urlconnection区别
HttpClient 和 URLConnection 都是用于在Java中进行HTTP通信的工具
| 特性 | URLConnection | HttpClient |
|---|---|---|
| HTTP 版本支持 | 仅支持 HTTP/1.1 | 支持 HTTP/2(需服务端兼容)3 |
| 连接池管理 | 默认无连接池,需手动配置系统属性 | 内置智能连接池,支持复用和超时控制3 |
| 异步请求 | 仅同步阻塞模式 | 支持异步非阻塞(如 JDK 11+ 的 CompletableFuture)2 |
| 重试与容错 | 无自动重试机制 | 支持可配置的重试策略和故障恢复3 |
| Cookie 管理 | 需手动处理 Cookie | 内置 Cookie 存储和自动管理3 |
HttpClient默认短连接可以变为长连接,在请求头上加keepAlive就可以变为长连接)适合复杂的HTTP请求,比如需要高并发处理、连接池管理、更好的错误处理机制等,HttpClient通常是更好的选择。
URLConnection :执行简单的单次HTTP请求。受限于 JDK 版本(低于 JDK 11)的项目
74、UDP在哪用到了?
DNS(Domain Name System)解析是将域名转换为对应 IP 地址的关键过程
DNS域名解析用到了UDP
网络直播用到了UDP
域名和ip是多对多的关系
DNS域名解析过程:首先,假设我们申请一个域名的时候会对应有一个公网ip(可以有多个),我们比如访问www.baidu.com的时候,它会先去DNS 服务器上边找对应的ip,从而去访问我们真实的ip和端口,下一次再访问相同域名的时候会先去本地浏览器的缓存中去查看有没有对应的ip,有就直接访问
75、电商项目线上遇到的bug有哪些?
元空间干到了121M
连续签到三天送积分,当时没送到,是因为当时的算法有问题,后来改为对三取模
刚上线的时候,验证码防刷做的不够完全,没有针对ip防刷
skywalking没有注册上,因为我们JVM属性参数配置的时候,不能加http,不然他会把http当做一个字符串,需要将http去掉
猜你喜欢当时写的有问题,后来才改成limit
上线的时候支付的回调地址没有配正确
取消订单的时候,第一次只支持一种场景,后来改为了
http属于
IP属于网络层
76、hashmap和treemap的时间复杂度?
hashmap:O(1)
treemap:O(logn)
77、QPS(访问量)/TPS(订单量)
QPS每秒有个四五百(搞活动的时候)
TPS每秒有一二十单(搞活动的时候)
78、一个视频流 50G,上传会出现什么问题,除了 oom 还有什么,怎么解决
会出现OOM
可能会出现网络传输过程的丢包问题:解决办法是使用TCP协议,TCP是个面向连接的安全可靠的传输层协议
传输速率会变慢,可能将我们的带宽占满:解决办法是多线程分块上传(如 AWS S3 分片上传)
服务器可能存储空间不足(解决办法是去使用阿里云OSS)
79、中台是什么?
中台是一种将系统的通用化能力进行打包整合,通过接口的形式赋能到外部系统,从而达到快速支持业务发展的架构模式。
其核心理念是 "大中台,小前台",即通过集中化管理共性能力,支持前端业务快速创新
好处是:整合资源、快速响应、降低成本、统一管理
- 前台:面向用户的业务终端(如淘宝App、线下门店系统)。
- 中台:包含业务中台(如交易、会员中心)、数据中台(数据分析能力)、技术中台(中间件)。
- 后台:传统IT系统(如财务、供应链系统)
80、栈里面有什么?
栈中存储八大基本类型的变量值和引用类型的引用地址。引用地址指向堆中的对象
public void exampleMethod() {
int a = 10; // 基本类型,直接存入栈
String str = "hello"; // 字符串常量,引用地址存栈,实际值在常量池
// str 在栈中存的就是引用地址
Object obj = new Object(); // 引用地址存栈,对象实例存堆
}
81、k8s的endpoint有什么?
应用的每个接口都属于endpoint
82、你在微服务中收获最大的是什么
熟悉了每个中间件独有的应用场景,真正体会到了那些中间件的优势
知道了服务之间职责怎么划分的
体验到了k8s的优势
对一个流量一步一步如何走到后端服务的
学会了在测试阶段怎么联调一个项目
84、库存如何不保证超卖(lua脚本)
1、定义入参:商品id和需求量,以及订单id
2、判断Redis库存够不够,或者商品是否存在于Redis
3、判断库存量满不满足所有的商品需求,创建一个临时变量,判断这个临时变量里有没有值,有值证明这个库存量不够
4、临时变量没有值的时候直接去扣库存
5、扣完库存就返回
85、SkyWalking谁路追踪怎么传下去的
1、SkyWalking会生成TraceID(全链路跟踪id)和SpanID(服务的唯一id),将他们嵌入到请求头中
2、接收方获取请求头的TraceID和SpanID,生成新 Span 并关联父 SpanID,形成完整链路
86、nacos的CP和AP的切换?
nacos默认是AP。可以在配置文件切换CP
CP是将数据持久化到本地,当集群中某台机器宕机时,会进行选举产生新的Master节点,但选举过程中服务对外是不可用的。
在AP模式下,Nacos集群节点之间的数据同步是异步的,服务列表信息不会持久化到本地,只会存储在内存中
87、k8s控制器有几种?
1.Deployment控制器:(普通的发实例,Pod副本有几个就发几份)用于管理无状态应用,支持滚动更新、回滚和扩缩容操作,确保Pod副本数量与期望状态一致
2.DaemonSet控制器
确保所有或指定节点上运行一个Pod副本(每个节点都发一份),常用于日志收集、监控等守护进程任务
3.CronJob控制器:用于执行周期性任务,可以结合cron表达式。
XXL-JOB跟CronJob区别,XXL-JOB适合那种频繁使用的任务,有可视化的管理页面,便于管理,而CronJob控制器他的好处是使用完会自动下线
88、哪些区域会发生Full GC
老年代和元空间
年轻代不会发生
89、seata分布式事务
1.长事务分成多个短事务
2.每个业务库有自己的undo_log 表: 业务sql记录的是操作之前和之后的镜像数据。 如果需要回滚使用undo_log数据恢复,正常成功后 异步删除undo_log无用数据。
优势:
锁资源时间短,效率高. 支持多个数据库的事务。
涉及的表:
global_table 存储全局 xid
branch_table 存储分支的信息(短事务的信息,例如短事务id)
lock_table 此时此刻锁的表(行锁,锁的那一行数据)
业务库 undo_log
90、没有用到分布式事务怎么保证数据一致性的?
我们保证的是AP,也就是最终一致性
我们有两个数据库,一个业务库,一个仓储的数据库
下单完成我们会将业务库的订单推送到仓储那边
每天晚上我们XXL-JOB发布一个定时任务会对两边数据库的数据进行对比,也就是今天下的单和仓储那边接受的订单进行对比,如果出错了就走人工
91、aliyunIOT平台和MQTT协议
aliyunIOT:阿里云物联网平台(Alibaba Cloud IoT Platform)是阿里云提供的物联网设备接入与管理服务,支持海量设备连接、数据采集、设备管理、消息通信等功能,适用于智能家居、工业物联网、城市感知等场景
MQTT(Message Queuing Telemetry Transport):是一种基于发布/订阅模型的轻量级通信协议,专为低带宽、高延迟的物联网环境设计
92、说一说 RestTemplate.是异步非阻塞的吗(RestTemplate和WebClient区别)?
两者均为 Spring 框架提供的 HTTP 客户端工具,用于在 Java 应用中调用 RESTful 接口
| 特性 | RestTemplate | WebClient |
|---|---|---|
| 线程模型 | 同步阻塞,每个请求占用一个线程,高并发下易导致线程耗尽 | 异步非阻塞,通过事件循环复用少量线程,支持高并发 |
| 性能表现 | 低并发下简单易用,高并发时吞吐量受限 | 高并发下吞吐量更高(实测可达 RestTemplate 的 2-3 倍) |
| 编程模型 | 命令式编程,通过 getForObject() 等方法直接获取响应 | 响应式编程,返回 Mono 或 Flux 对象,支持链式调用 |
| 错误处理 | 需手动捕获异常(如 try-catch) | 通过 onErrorResume()、onErrorReturn() 等操作符处理错误 |
| HTTP 协议支持 | 仅支持 HTTP/1.1 | 支持 HTTP/1.1 和 HTTP/2 |
| 依赖与兼容性 | 集成于 Spring Web(无需额外依赖) | 需引入 spring-webflux 模块 |
RestTemplate 是一个同步阻塞的HTTP客户端,它提供了一组方便的方法来发送HTTP请求并处理响应。
WebClient 是一个非阻塞的、基于Reactive编程模型的HTTP客户端。
93、数据清洗和数据收集
数据收集面向原始数据,数据清洗面向已获取的数据
- 数据收集
- 数据清洗
94、多线程可能有哪些问题
死锁
线程饥饿
线程不安全:多个线程同时修改共享资源(如变量、对象属性)时,可能导致数据不一致或程序崩溃
上下文切换开销:线程频繁切换导致 CPU 资源浪费,尤其在大量线程并发时性能下降明显
没有及时释放资源可能造成内存泄漏
95、隔离级引中、产生幻读和不可重复度的区别?
不可重复度:针对update
幻读:针对insert
隔离级别:通过锁实现
96、TCC一定要去问一下
其实就是在下单那里加了一个version变量,执行完一个操作version就加一,然后在switch case 中定义每个version情况对应的回滚逻辑(其实就是先把数据给写入数据库了,如果走到哪一步出错了,就手动通过代码将数据变为原来状态)
97、hashmap的put流程

98、Controller和RestController 区别
- @Controller
- @RestController
- 核心用途:专为 RESTful API 设计,适用于前后端分离场景,直接返回 JSON/XML 数据而非视图页面。
- 本质:是
@Controller和@ResponseBody的组合注解,所有方法默认添加@ResponseBody,无需手动声明
99、有哪些IO模型
| 模型 | 数据等待阶段 | 数据拷贝阶段 | 典型应用 |
|---|---|---|---|
| 阻塞 I/O | 阻塞 | 阻塞 | 简单客户端程序 |
| 非阻塞 I/O | 非阻塞(轮询) | 阻塞 | 低并发实时监控 |
| I/O 多路复用 | 阻塞(统一监听) | 阻塞 | Nginx、Redis 等高并发服务 |
| 信号驱动 I/O | 非阻塞(信号) | 阻塞 | UDP 网络通信 |
| 异步 I/O | 非阻塞 | 非阻塞 | 高性能分布式存储系统 |
100、简述下java web 框架发展
纯 Servlet 开发:通过 Servlet 类逐行输出 HTML 代码
Spring MVC:以注解驱动(如 @Controller)替代 XML 配置,整合依赖注入(IoC)和面向切面(AOP)
Spring Boot:通过“约定优于配置”理念,内嵌 Tomcat、自动装配等特性,快速构建独立运行的微服务
101、分布式解决了什么问题?
高可用、可以将业务拆分实现服务的单一职责、数据分片存储
102、分布式和微服务区别
分布式系统:解决 性能瓶颈与高并发问题,属于 部署方式,粒度较大,子系统可能包含多个模块
微服务架构:解决 系统复杂度问题,属于 架构设计,粒度更小,每个服务仅负责单一业务功能
103、resultful设计风格与传统模式区别
RESTful :包含通HTTP 方法(GET、POST、PUT、DELETE),接口功能清晰,数据格式灵活,支持 JSON、XML 等格式。url简洁
传统模式:接口冗余,数据格式固定(如仅支持表单或特定 XML 结构),url长
104、SSO就是单点登录
105、XXLJOB
秒杀商品提前预热
每天早上推送慢日志
订单完成
XXLJOB每天扫描队列中的堆积消息
106、线程池的优势
线程复用机制、响应速度优化、方便管理、扩展性强;(先讲一下线程池的工作原理,在讲工作原理的时候可以说一下线程池的核心参数,这里可以扩展一下为什么不建议使用JDK自带线程池)
107、锁表的情况?
当一个表数据量比较大,加入一个新字段就会导致锁表
我们的方式是开一个新表,根据那个lastupdatetime作为分界去同步
108、前后端如何沟通的
业务上:接口文档,apifox,swagger
程序上:axios,我们在前端定义了请求和响应拦截器,
请求拦截器:当请求成功时我们从localStorage 获取token,如果存在就放入请求头里,用于身份认证;请求失败时,我们将错误信息打印出来
109、秒杀是不走购物车的,下单直接到提单页
110、vue的优势
轻量级与渐进式架构
响应式数据绑定与组件化开发
高效开发工具与生态系统
低门槛与易用性
跨平台
Vue.js 凭借 轻量级架构、数据驱动视图、组件化开发 等特性,成为中小型项目及复杂单页应用的首选框架。其 低学习门槛 和 活跃生态 进一步降低了开发成本,适合快速迭代和团队协作
111、Pinia和 LocalStorage 的区别
存储位置:Pinia存储到内存中,LocalStorage存储到磁盘中
生命周期:Pinia与 Vue 应用实例绑定,LocalStorage独立于应用状态
支持的数据类型:Pinia支持任意 JavaScript 对象(如数组、嵌套对象),无需手动序列化
LocalStorage仅支持字符串,存储复杂数据需手动使用 JSON.stringify() 序列化,读取时需反序列化
112、JDK常用队列
ArrayBlockingQueue:基于数组实现的有界阻塞队列,遵循FIFO(先进先出)原则,
LinkedBlockingQueue:基于链表实现的有界或无界阻塞队列,默认长度为Integer.MAX_VALUE
DelayQueue:无界阻塞队列,元素只有在延迟期满时才能被取出,常用于定时任务调度。
SynchronousQueue:不存储元素的阻塞队列,每个插入操作必须等待一个移除操作 ,
113、BeanFactory和FactoryBean 的区别?
共同点:都是接口,都适用于创建bean对象
不同点:
1:普通的类,spring 通过 BeanFactory直接创建 bean 对象
2:对于那些也是要求的比如 mybatis 的 mapper 接口和 feignclient 接口,需要生
成动态代理对象,这些需要第三方自己去实现的,通过 FactoryBean 去实现
114、DTO、VO、PO、Entity 有什么用?
115、购物车中价格发生变动怎么处理?
通知用户:用户进购物车页面的时候,去查一下购物车商品对应的价格,如果价格有变动就将那个商品置灰,并且告知用户价格有变动,用户不能去支付这个商品,但是用户可以将商品从购物车删除,我们
116、mybatis存储json
自定义JsonTypeHandler继承Mybatis的BaseTypeHandler处理器
package com.jiusi.config;
import cn.hutool.json.JSONUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class jsonTypeHandler01<T> extends BaseTypeHandler {
/**
*
* @param ps 预编译的sql对象
* @param i 插入字段的索引从1开始
* @param parameter 要插入的数据
* @param jdbcType 用来精确指定数据库中的数据类型
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
//将数据转换为json字符串
ps.setString(i, JSONUtil.toJsonStr(parameter));
}
/**
*
* @param rs 获取的结果集
* @param columnName 指定的列名
* @return
* @throws SQLException
*/
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
//将json字符串转换为任意类型
if(rs.getString(columnName).charAt(0)=='{'){
return (T) JSONUtil.parseObj(rs.getString(columnName));
}
return (T)JSONUtil.parseArray(rs.getString(columnName));
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return null;
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return null;
}
}
在xml中使用:添加数据时在需要改序列化的字段后添加TypeHandler属性,指定序列化器的包名
<insert id="insert">
insert into msg (name, age, height, address, friend)
values (#{name}, #{age}, #{height},
#{address,typeHandler=com.jiusi.config.jsonTypeHandler01},
#{friend,typeHandler=com.jiusi.config.jsonTypeHandler01})
</insert>
获取数据时在ResultMap里将需要序列化的字段上添加typeHandler属性
<resultMap type="com.jiusi.model.Msg" id="Jackon">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
<result property="address" column="address" typeHandler="com.jiusi.config.JsonTypeHandler01"></result>
<result property="friend" column="friend" typeHandler="com.jiusi.config.JsonTypeHandler01"></result>
</resultMap>
117、微信登录怎么实现的
首先到微信开发者平台注册一下,拿到AppId和小程序秘钥,登录的前端会跳转到微信的授权页面,授权后拿到一个临时的授权码,后端需要用这个授权码去微信服务器换取access_token和openid,再通过access_token获取用户的基本信息,比如昵称、头像等
118、docker的网络模式

119、spring对spi的增强
原生的Java是通过接口实现,而spring的spi可以通过注解和类实现
120、如何动态的设置线程池的核心参数
//动态调整核心线程数
tcorePoolsize(newCorePoolsize);
executor
动态调整最大线程数
executor.setMaximumPoolsize(newMaximumPoolsize);
动态调整队列容量(自定义队列)
resizableQueue.setCapacity(newCapacity);
121、索引存在哪?
索引存在磁盘里,但是对于高频访问的索引,MySQL会将他们放入内存中
122、都什么索引用 b+树
除了全文索引以外的索引
123、你的分页支持分库分表吗
看场景,如果数据在同一张表,那个可以
但是加入根据用户下单时间来分,这个用户的订单可能不在同一张表,不支持分页
124、全文索引 怎么用
125、java.util包里有哪些常用的
126、除了#防止SQL注入,还有什么办法?
手动使用preparestatement
使用存储过程(作用和preparestatement一样,但是不推荐)
自己转义(手动替换特殊字符)
127、什么是socket?
socket是应用层和传输层的通信接口也是一种协议,所有应用层的协议都是基于socket实现的,socket(文件)里包含目标进程的ip和端口
128、MQTT协议和SMPP 协议
MQTT它是一个为IOT服务的轻量级的协议,主要用于物联网(IoT)设备通信,我简历上边的门禁系统就是基于这个实现的
SMPP:运营商与短信平台之间的底层协议,支持批量短信发送和高吞吐量
129、Sentinel限流如何灵活配置(一种是基于服务,另一种是基于分组)
130、nacos心跳机制
状态检测:Nacos 服务器会定时检查服务实例的状态。如果超过 15 秒未收到心跳信号,Nacos 会将该实例标记为不健康;如果超过 30 秒未收到心跳信号,Nacos 会将该实例从服务列表中剔除,
131、仓储系统如何保证出入库的原子性?(加事务)
132、一对一,一对多的两种实现方法
132、mongondb优势?
文档型存储:数据以类似 JSON 的文档(BSON 格式)存储
BSON 格式文档:数据以类似 JSON 的文档形式存储,无需预定义表结构
灵活模式:同一集合(Collection)中的文档可以有不同的字段,适合插入新字段
横向扩展能力(分片集群),高可用性,支持数据分片存储
132、判断一个表的锁定状态

133、https证书认证用到了对称加密和非对称加密
134、商城中设计不合理的地方
商品标签目前是写死的,没有建一个表
采购单审核,那个超过多少钱采交给经理审批,后来我老大跟我提了,尽量使用flowable实现标准化的流程审批
目前不支持,未注册的手机号登录,我觉得后续可以改为没有注册的手机号可以直接登录,往数据库插入一条数据就行
购物车商品价格那里,我们原本是用户进入购物车页面点击提交按钮,如果商品价格有变动,会告知用户下单不成,某个商品价格变动了,这样对用户的体验不太好,因为只有用户点击了按钮才能知道价格变动了。后来我们想的是用户进入购物车页面的时候,我们就把价格变动的商品告知给用户,本来购物车的商品就在Redis,我们只需要从新抓取一下购物车商品的价格循环遍历对比一下就行。
135、单元测试和集成测试有没有,有没有可能不写呢,有没有什么可以管理
管理:我们用阿里云上的项目管理
136、AQS是啥
①AQS:抽象队列同步器,Java并发的同步管理器
②核心:state 用voliate int 修饰的,用于表示锁的状态
③双向链表: 存储那个等待获取锁的线程的信息和状态
④独占锁/共享锁:
⑥哪里使用到了?countdownlatch、reentrantlock、cyclicbarrier、stamplock
⑦功能:状态管理*(可控制独占锁和共享锁),线程排队与唤醒
137、静态代理和动态代理区别?
静态代理:需手动为每个目标类编写独立的代理类,代理类在编译前就已确定;仅能代理特定的类或接口,需提前明确代理内容。效率高一些
动态代理:在运行时通过反射动态生成代理类,无需预先编写代码;可为多个类或接口生成通用代理,适合代理大量类或频繁变动的场景。因为使用了反射效率不如静态代理
138、freemarker是什么
139、多线程环境下如何根据线程id 实现线程顺序执行
join方法
synchronized
使用两个countdownlatch
140、创建什么对象会导致内存泄漏
静态的大对象
单例bean对象过大
IO流不关闭
threadlocal的使用不当
141、ConCurrentHashMap为什么是线程安全的
①分段锁:通过分段锁缩小锁范围
②分段扩容:提高扩容效率
③CAS算法:通过 比较内存值与预期值 决定是否更新数据,实现多线程环境下的原子操作
1. 读取内存当前值 V; 2. 比较 V 与预期值 A; 3. 若相等,写入新值 B 并返回成功; 4. 若不相等,放弃操作或重试。
④volatile 修饰关键变量,确保多线程内存可见性
142、delete 、drop和TRUNCATE 的区别
| 对比项 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 操作类型 | DML(数据操作语言) | DDL(数据定义语言) | DDL |
| 是否可回滚 | ✔️(事务日志记录)1 | ❌(无日志记录)2 | ❌ |
| 自增列处理 | 不重置(继续当前值递增)3 | 重置(恢复初始值)12 | 删除表结构(自增列消失) |
| 执行速度 | 慢(逐行删除)1 | 快(页释放/重建表)4 | 最快(直接删表)4 |
143、生成当前时间点的 RDP 文件用什么命令
save (会阻塞进程)和 bgsave(开启一个全新的进程去生成RDB文件,) 的区别
SAVE
- 功能:立即生成 RDB 快照文件(默认保存为
dump.rdb)。 - 特点:同步阻塞主进程,期间 Redis 无法处理任何客户端请求,会阻塞进程
BGSAVE
- 功能:在后台异步生成 RDB 文件。
- 特点:通过 fork 子进程 执行持久化,主进程仅短暂阻塞(fork 阶段)
144、分布式事务有哪些常见的解决方案
基于XA协议的二阶段提交或三阶段提交
TCC(补偿性事务)
145、list和set的contains方法有啥区别?
list(时间复杂度为O(n)):遍历所有元素,逐个调用 equals() 进行匹配 ,允许元素重复
set(时间复杂度为O(1)):
1. 先计算 hashCode() 定位桶;
2. 若哈希冲突,再调用 equals() 匹配,不允许重复元素
简单说list会遍历整个集合,而set当查找到一个就返回,通过计算hashcode定位。
146、hashmap的尾插法解决了头插法的什么问题?
解决了下次扩容的时候会出现死循环的问题
147、Java常见的error和exception有哪些?
error:表示 JVM 或底层资源严重故障,通常无法通过代码修复,需系统级处理
OutOfMemoryError
- JVM 堆内存耗尽时抛出,常见于内存泄漏或超大对象分配场景
StackOverflowError
- 方法递归调用过深导致栈溢出,如无限递归调用
NoClassDefFoundError
- 类文件存在但加载失败(如依赖缺失或类版本冲突)
运行时异常(RuntimeException)编译器不强制处理,通常由代码逻辑错误导致
| 异常类型 | 触发场景 | 来源 |
|---|---|---|
NullPointerException | 访问 null 对象的方法或属性 | 156 |
ArrayIndexOutOfBoundsException | 数组索引越界(如访问负索引或超长索引) | 156 |
ClassCastException | 类型强制转换失败(如父类转子类不兼容) | 56 |
ArithmeticException | 数学运算错误(如整数除以零) | 16 |
IllegalArgumentException | 方法参数不合法(如传 null 到非空参数) | 57 |
受检异常(Checked Exception)编译器强制要求处理(try-catch 或 throws),常见于外部资源操作
| 异常类型 | 触发场景 | 来源 |
|---|---|---|
IOException | 文件读写失败或网络通信中断 | 156 |
SQLException | 数据库操作错误(如 SQL 语法错误或连接超时) | 57 |
FileNotFoundException | 尝试访问不存在的文件路径 | 56 |
ClassNotFoundException | 动态加载类失败(如类名错误或类未在类路径中) | 56 |
148、请求和响应三部分
请求:
请求行(Request Line):请求行包含了请求的方法(Method),如GET、POST、PUT、DELETE等,请求的URL或者资源路径,HTTP协议版本号,表示使用的HTTP协议版本
请求头部(Headers):请求头部包含了一系列键值对,提供了关于请求的元数据,编码方式(Content-Encoding)、认证信息(Authorization)
请求体(Body):请求体是可选的,主要用于在请求中发送数据给服务器,里面存传递的数据
响应:
状态行(Status Line):状态行包含了HTTP协议版本号、一个三位数的状态码以及一条简短的消息描述。
响应头部(Headers):响应头部包含了一系列键值对,提供了关于响应的元数据信息。
响应体(Body):响应体包含了返回给客户端的实际数据,比如HTML文档、图片、JSON数据等
149、PO、VO、DAO、BO、DTO、POJO、Entity
PO:可以看成是与数据库中的表相映射的java对象
VO:通常用于业务层之间的数据传递,面向前端展示的视图对象,字段可能聚合多个 PO
DAO:AO是Data Access Object数据访问接口,数据访问:顾名思义就是与数据库打交道。
BO:封装业务逻辑的对象,可能组合多个 PO 并包含业务方法。这些实体类驻留在服务器上
DTO:主要用于远程调用等,跨层数据传输对象
POJO:简单 Java 对象,无框架依赖,仅含属性和 getter/setter
Entity:与 PO 类似,通常指代数据库表映射的实体、
150、了解过同步锁吗
就是问synchronized和lock区别
所属不同:synchronized是一个关键字,属于JVM层的锁,作用的普通方法上是锁的是当前实例,在静态方法上时锁的当前类对象;lock是一个接口,他的实现类有reentrantlock、reentrantreadwritelock
作用范围:synchronized作用于同步代码块,lock可以指定上锁和释放锁的位置
公平性:synchronized是非公平锁,而lock可以指定公平或非公平,而且lock具有尝试锁机制以及超时机制
上锁和释放锁:synchronized会自动上锁和释放锁,而lock需要我们手动上锁和释放锁,一般是在finally中调用unlock()方法来释放锁,避免死锁
粒度:synchronized锁的粒度较大,而lock锁的粒度更细
151、验证码防刷怎么实现的?
我们验证码防刷主要是为了解决一个或多个手机号频繁刷我们的接口造成的资源损耗
第一重是前端我们发送验证码的按钮做的防刷,60s只能点击一次
第二个就是后端我们单位时间内同一个手机号频繁发送请求,用Redis的string类型,key是用户手机号,value是记录的次数,我们设置了ttl过期时间,当单位时间内访问次数达到我们设置的阈值就不让他访问了
第三个就是针对用户多个手机号同一ip做的,我们先从nginx里获取用户的ip和url,也是使用Redis的string类型,key是ip和url。value是记录的访问次数,我们时间设置的是当前时间到这一天结束,通过Redis的increment命令,每有一次请求来我们就加1,当达到一天内的最大访问次数我们就不让他访问了
后来我们为了提高代码的复用性,我们就把他写成了一个starter,通过AOP和拦截器实现
首先自定义一个注解,里面包含一些单位时间内访问次数和一天内的最大访问次数以及用户是否登录的状态,它是基于AOP和拦截器实现的,我们写了一个拦截器,首先判断方法上有没有加我们那个注解,加了的话看注解里面传递的参数,先获取用户的ip和访问的url,通过Redis的increment命令结合lua脚本实现,key是业务标识加上用户的ip和url,每访问一次我们加1,如果达到我们设置的限定次数我们就不让访问了
152、AQS(AbstractQueuedSynchronizer)
AQS是一个抽象队列同步器,它是实现同步器的基础组件,ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch、Cyclicbarrier都用到了AQS
核心是
一个状态变量state:表示线程的状态,通过CAS完成对state值的修改,当state为0时代表线程可以竞争锁,不为0时代表当前对象锁已经被占有。为1代表当前线程已经获取到锁了,大于1是代表可以重复获取锁的次数;可以实现可重入锁
CLH队列:CLH是AQS内部维护的FIFO(先进先出)双端双向队列(方便尾部节点插入),基于链表数据结构。当一个线程竞争资源失败,就会将等待资源的线程封装成一个Node节点,通过CAS原子操作插入队列尾部,等待其他线程执行完去唤醒(保证了公平性,非阻塞队列,高性能,采用自旋思想);可以实现共享锁和独占锁
能够实现独占锁、共享锁、尝试锁、公平锁
功能:acquire(以独占模式获取)、tryAcquire(尝试以独占模式获取资源)、release(以独占模式释放资源)、tryRelease(以独占模式释放资源)、acquireShared(以共享模式获取,忽略中断)、tryAcquireShared(尝试以共享模式获取资源)、releaseShared(以共享模式释放资源)、tryReleaseShared(试以共享模式释放资源)
153、如何设计一个秒杀系统
前端:前端页面静态化加CDN、请求频率限制
后端:
-
增加缓存层 + 预热数据
-
MQ 异步处理
-
限流、熔断、兜底
-
业务端优化
-
增加集群
154、接口慢怎么办
skywalking查看慢接口
SQL优化、分库分表
前端:前端页面静态化+CDN、JZIP在nginx里压缩对象(gzip 压缩对象指的是 Nginx 服务器会对满足特定条件的响应内容进行 gzip 压缩处理后再发送给客户端)
后端:加Redis、mq异步、加集群、JVM调优、发多份实例、
155、skywalking里有什么?
应用实例的拓扑图
慢接口、接口耗时、慢SQL
JVM相关的参数
156、如果我们并发量太大,我们Redis的日志怎么采集?
使用xxljob,每天定时将日志推送到mq中,然后后续我们大数据部门起消费者去消费消息
157、下单流程
1下单防重,第一重前端遮罩层,第二层Redis的setnx命令,设置ttl为5s,第三重redission的看门狗。
2校验:验证商品是否在购物车,积分是否足够,商品价格是否变动,验证总金额
3生成订单号,结合当前时间精确到秒的时间戳,以及用Redis的increment命令生成四位的,不够用0补全
4冻结库存
5落库
6往mq推送消息
7删除购物车
8往前端发送一个对象,里面是订单号和应付金额,然后去调支付宝的支付接口,进行支付
注意:校验、冻结库存、落库、推送消息、删除购物车都会加入TCC事务,在catch中有相应的version(初始为0)对相应的操作进行补偿性事务
158、多个任务执行的时候实现串行化执行?怎么做?
join方法
用同步工具类:countdownlatch
使用单个线程的线程池,newfixedthreadlpool
159、springsecurity权限管理的过滤器链我们剔除了哪些过滤器?
1、防止csrf攻击的,因为我们jwt本身就防止csrf攻击
2、提交form表单的,我们用不上
3、禁用了httpsession
160、select * from 表名 where 列=值 for update 这个语句会锁表吗?
如果那一列加索引了,会锁那一行或者间隙锁(锁那一片),不加索引就是锁整张表
161、为什么要分年轻代老年代?
因为我们大部分对象是朝生夕亡的,我们将那些不频繁使用的对象放入新生代,而频繁使用的对象我们可以放入老年代,避免老年代频繁触发majorJC(也叫fullJC)
162、阻塞队列
我们一般用的ArrayBlockingQueue(有界阻塞队列),LinkedBlockingQueue(无界阻塞队列)
一般用于生产者和消费者模型
对于生产者如果投递消息的时候,如果队列满了就会让线程阻塞
对于消费者,如果队列中没有消息的话就会阻塞线程
163、JMM(Java内存模型)和JVM
java memory model
它是一种java在并发环境下的一种规范,解决了并发环境下的原子性(synchronized那些锁保证)、有序性(volatile关键字保证)、可见性(volatile关键字保证),确保线程之间正常通信,它的规范主要依赖于happens-before(保证我们程序按顺序执行)和内存屏障(禁止指令重排)这两个规则;在volatile读写时插入屏障,防止重排序
164、SET是无序唯一的吗?分情况
HashSet:无序唯一
LinkedHashSet:有序唯一
TreeSet:有序且能排序,唯一
165、openfeign是对谁的封装?
OpenFeign主要封装了Feign,而Feign本身封装了底层的HTTP客户端,如HttpURLConnection,并允许替换为其他库
166、mybatis底层用的设计模式?
-
Builder 模式:用于构建复杂的对象。例如,SqlSessionFactoryBuilder 用来根据配置信息创建 SqlSessionFactory 对象。
-
Factory 模式:SqlSessionFactory 是一个工厂类,负责创建 SqlSession 实例。这种模式隐藏了创建 SqlSession 的复杂性,并且提供了一种获取 SqlSession 的统一接口。
-
Prototype 模式:SqlSession 本身可以视为原型模式的应用,通过现有的 SqlSession 实例克隆出新的实例,以便执行数据库操作。
-
Singleton 模式:通常情况下,SqlSessionFactory 在应用中是单例的,因为创建它的成本比较高,而且整个应用只需要一个实例就足够了。
-
Proxy 模式:MyBatis 使用动态代理来为接口生成实现类,使得我们可以直接使用定义好的 Mapper 接口而无需手动编写其实现。对于接口的方法调用实际上是通过代理对象完成的,代理对象负责将方法调用转换为对应的 SQL 执行。
-
Template Method 模式:在 MyBatis 中,某些核心算法(如处理 SQL 语句的执行)被封装在基类中,具体的步骤由子类来实现。这种方式允许你在不修改原有逻辑的情况下扩展行为。
-
Adapter 模式:TypeHandler 可以看作一种适配器模式的应用,它能够将 Java 类型与数据库类型之间进行转换,使不同的数据类型能够在 MyBatis 中无缝地工作。
-
Observer 模式(发布-订阅模式):虽然这不是 MyBatis 核心功能的一部分,但在某些插件或扩展机制中可能会用到观察者模式,比如监听某些事件的发生并做出相应的处理。
167、spring框架用的代理模式?
-
单例模式(Singleton Pattern):Spring的Bean默认是单例的。IoC容器管理的每个Bean在默认情况下在整个应用程序中只有一个实例。
-
原型模式(Prototype Pattern):当scope设置为"prototype"时,每次获取Bean都会返回一个新的实例。
-
工厂模式(Factory Pattern):通过BeanFactory和ApplicationContext接口,Spring提供了创建对象的抽象层,隐藏了对象创建的细节,允许动态地决定何时以及如何创建Bean。
-
代理模式(Proxy Pattern):Spring AOP模块大量使用了代理模式来提供声明式事务管理、日志记录等功能,可以通过JDK动态代理或CGLIB代理实现。
-
观察者模式(Observer Pattern):在Spring事件机制中得到体现,如ApplicationContext发布事件给注册的监听器,这有助于解耦组件之间的直接依赖关系。
-
适配器模式(Adapter Pattern):用于各种回调接口的适配,比如HandlerAdapter支持不同的处理器映射,使它们能够协同工作。
-
策略模式(Strategy Pattern):在Spring MVC中,视图解析策略可以通过配置不同的ViewResolver实现类来选择不同的解析逻辑。
-
构建者模式(Builder Pattern):在构建复杂的对象时使用,例如Fluent API风格的Bean构造方式,或者在创建复杂的HttpRequest时。
168、skywalking的底层原理?链路跟踪怎么实现的,探针起了什么作用?
skywalking的探针是嵌入到目标应用程序,自动拦截应用程序的调用(比如http请求、RPC调用等),skywalking会拦截我们的请求,为每个服务节点生成spanId,探针会将spanId进行关联,在请求头上加上traceId和spanId,传递给下一个服务,从此循环往复,实现链路跟踪
169、仓储系统的角色
商品管理员、采购员、采购部经理、财务、
170、用过seta吗?
我们之前在电商项目的时候开始时尝试用seata,但是后来在压测的时候就扛不住高并发没后来改成了TCC
171、VUE生命周期
创建(created、oncreate)、挂载(mounted、onmounted)、更新(update)、销毁(destory)
172、静态内部类和内部类区别
173、mybatis分页方式
pagehelper,limit
174、Java锁和分布式锁区别
Java:适用于单击环境,JVM本地锁,synchronized、reentrant
分布式锁:适用于分布式,解决多节点并发问题,比如Redis的setnx,redission,dubbo实现
175、多线程下如何获取异步回调地址
callable接口+futuretask
submit(这个方法提交callable和runnable类型的任务,有返回值)方法提交线程的时候+future类
execute(只能提交runnable类型任务)提交任务无返回值
176、不用阿里的CICD如何部署?
原本的阿里云就支持将我们的发布流程添加到CICD上,我们也可以自己构建一个jentins
177、前后端如何交互
后端使用restfulApi,支持四种请求方式,通过restcontroller会将我们的Java对象序列化为json对象
前端使用axios,我们可以自定义请求和响应拦截器
178、秒杀系统什么时候锁单和冻结库存
其实锁单和冻结库存可以同时进行,我们在点击去支付按钮的·时候就锁单了,我们秒杀系统的流程其实和正常下单差不多,但是没有正常下单那么复杂,因为不需要积分校验,扣几分操作了,我们只需要用try catch包裹一下扣库存即可,然后用事务操作落库,不需要清空购物车操作
92万+

被折叠的 条评论
为什么被折叠?



