文章目录
- 一、专业技能
- 1.1 具备扎实的Java基础,熟练掌握面向对象编码规范、集合、反射以及Java8特性等。
- 1.2 熟悉常用的数据结构(链表、栈、队列、二叉树等),熟练使用排序、动态规划、DPS等算法。
- 1.3 理解设计模式如工厂、代理、策略、模板、建造者等,并善用设计原则构建可复用的代码。
- 1.4 熟悉JVM的内存结构,垃圾回收机制,类加载机制及JMM。
- 1.5 熟悉Java并发编程,了解锁机制、线程池、CAS以及JUC中常用类如ConcurrentHashMap、CountDownLatch、Semaphore、CyclicBarrier等。
- 1.6 熟悉MySQL事务、存储过程、锁、索引、执行计划等,掌握复杂SQL编写、数据库优化方案以及SQL优化,在工作中有相关SQL优化经验。
- 1.7 熟练掌握MyBatis、Spring、SpringMVC进行整合开发项目经验,对IOC、AOP原理有一定的理解。
- 1.8 熟练使用SpringBoot框架用于快速构建项目,SpringCloud微服务治理架构以及Nacos、Kafka、RabbitMQ、Gateway、Feign、Sentinel等技术。
- 1.9 熟悉Redis数据结构、持久化、内存回收策略、常见缓存高并发场景以及生产环境常见问题解决方案(缓存雪崩、穿透、缓存db数据一致性等处理)。
- 1.10 理解消息中间件落地方案和使用场景,熟悉消息队列有序性、可靠性、幂等性、事务消息、消息积压的解决方案。
- 1.11 理解CAP和BASE理论,理解分布式场景下常见问题和解决,如分布式锁、分布式事务、分布式session、分布式调度任务等。
- 1.12 掌握Linux常用命令,了解Nginx服务的反向代理、负载均衡、动静分离。
- 二、工作经历
- 2.1 利用delayqueue+scheduled+mq实现了延迟消息工具完成了常见的延迟消息场景,并且避免了引入mq延时队列插件导致有多个mq时插件不通用的问题。
- 2.2 热门数据利用caffeine和redis实现了两级缓存,解决了用redis时压力过大查询缓慢的问题,保证了接口的高性能和高可用。
- 2.3 基于本地消息记录表实现了事务消息的投递过程,引入衰减重试+错误预警保证了消息投递的可靠性。
- 2.4 基于事务消息+消费幂等+失败补偿方案,利用mq最终一致性解决了分布式事务的问题。
- 2.5 使用CompletableFuture优化查询模块,对业务功能模块中的多个异步调用进行重新编排,优化结果显示响应时间从2s降到0.2s。
- 2.6 对原有的复杂代码进行重构,采取工厂+策略模式实现了项目的各个业务产品对应的信息创建、编辑的解耦处理,解决了原先老旧代码不易维护的问题。
- 2.7 基于自定义注解+jackson序列化器优雅实现不同业务数据的脱敏处理。
- 2.8 第三方sdk接入,如短信接口对接、微信小程序js-sdk对接、内部项目接口对接、银行业务接口对接等。
- 2.9 基于Spring Cloud、Spring Boot、Spring Security、jwt、Redis技术栈,实现了一个高效、安全的微服务统一认证授权解决方案,基于拦截器实现了登录用户的权限管理。
- 2.10 基于EasyExcel实现了常见业务数据的Excel报表导入导出功能,基于poi-tl实现了动态word文档的导出,并通过自定义线程池+completable进行了多线程改造,解决了大批量导入客户公司人员信息时的效率过低的问题。
- 2.11 采用定时任务定时推送数据、发送邮件到用户,并进行错误校验,对失败的任务进行衰减式重试。
- 2.12 对慢接口进行检查分析,对跨库的多个复杂SQL查询进行调优,解决了前端报表响应过慢的问题。
- 2.13 基于Canal+Kafka实现了从MySQL到ElasticSearch的数据增量同步。
一、专业技能
1.1 具备扎实的Java基础,熟练掌握面向对象编码规范、集合、反射以及Java8特性等。
1.1.1 Java基础
- 重载与重写区别
- 接口和抽象类
- 自动装拆箱
- 流
1.1.2 集合
- 集合体系
- ArrayList,HashMap
1.1.3 Java8新特性
- stream流
1.2 熟悉常用的数据结构(链表、栈、队列、二叉树等),熟练使用排序、动态规划、DPS等算法。
1.2.1 数据结构
- 二叉树
- 栈
- 队列
- 链表
1.2.2算法
- 排序
1.3 理解设计模式如工厂、代理、策略、模板、建造者等,并善用设计原则构建可复用的代码。
1.3.1 代理模式
参考:一文搞懂代理模式
静态代理:中介租房案例
动态代理:
- jdk动态代理
- cglib动态代理
1.3.2 工厂模式
参考Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)
简单工厂模式
工厂方法模式
抽象工厂模式
1.3.3 策略模式
1.3.4 模板方法模式
参考模板方法模式
举例
1.3.5 项目中用到过什么设计模式?
1.4 熟悉JVM的内存结构,垃圾回收机制,类加载机制及JMM。
1.4.1 jvm内存分区,每个区的作用
参考1:JVM的内存区域划分
参考2:jvm-内存管理
1.4.2 垃圾回收的方法
1.4.3 类加载过程,类加载器
1.5 熟悉Java并发编程,了解锁机制、线程池、CAS以及JUC中常用类如ConcurrentHashMap、CountDownLatch、Semaphore、CyclicBarrier等。
1.5.1 线程池有哪些
参考1:java线程池(简单易懂)
参考2:java线程池
1.5.2 Synchronized和Reentranlock
参考1:synchronized和ReentrantLock的区别小结
1.5.3 锁机制,锁升级
参考1:锁机制(JUC)
参考2:JUC并发编程01——谈谈锁机制:轻量级锁、重量级锁、偏向锁、锁消除与锁优化
1.5.4 CAS操作
参考1:【JUC】CAS(轻量级加锁)
1.5.5 AQS抽象队列同步器
参考1:谈谈Java多线程离不开的AQS
1.5.6 ConcurrentHashMap
1.5.7 CountDownLatch、Semaphore、CyclicBarrier
1.6 熟悉MySQL事务、存储过程、锁、索引、执行计划等,掌握复杂SQL编写、数据库优化方案以及SQL优化,在工作中有相关SQL优化经验。
1.6.1 事务
- 四大特性
- 事务的隔离级别
参考:MySQL事务(transaction) (有这篇就足够了…)
1.6.2 索引
- 索引有哪些,分类
- 聚簇索引和非聚簇索引
- innodb和myisam引擎
- 索引失效的情况
参考1:一文搞懂MySQL索引所有知识点
参考2:MySQL高级篇——索引失效的11种情况
1.6.3 锁 悲观锁和乐观锁
1.6.4 优化
- MySQL语句可以怎么优化
- 案例
1.6.5 执行计划
- explain关键词 type
1.6.6 MVCC
参考1:【MySQL笔记】正确的理解MySQL的MVCC及实现原理
1.7 熟练掌握MyBatis、Spring、SpringMVC进行整合开发项目经验,对IOC、AOP原理有一定的理解。
1.7.1 IOC和AOP
1.7.2 循环依赖问题
1.8 熟练使用SpringBoot框架用于快速构建项目,SpringCloud微服务治理架构以及Nacos、Kafka、RabbitMQ、Gateway、Feign、Sentinel等技术。
1.8.1 微服务的概念
1.8.2 各个组件的作用,Nacos、Kafka、RabbitMQ、Gateway、Feign、Sentinel
参考1:微服务 常用组件(常用大全)
参考2:【微服务】------架构设计及常用组件
1.9 熟悉Redis数据结构、持久化、内存回收策略、常见缓存高并发场景以及生产环境常见问题解决方案(缓存雪崩、穿透、缓存db数据一致性等处理)。
1.9.1 Redis数据结构有哪几种
1.9.2 Redis的持久化方式
1.9.3 内存回收策略
1.9.4 常见使用Redis的场景
1.9.5 Redis和MySQL的数据一致性怎么保证
1.9.6 缓存击穿、缓存穿透、缓存雪崩的原因和解决方案
1.9.7 布隆过滤器
1.10 理解消息中间件落地方案和使用场景,熟悉消息队列有序性、可靠性、幂等性、事务消息、消息积压的解决方案。
1.10.1 mq的作用。削峰填谷、解耦
1.10.2 如何保证消息的有序性
1.10.3 如何保证消息不会丢失
1.10.4 消息有可能会被重复处理吗?幂等性如何保证?
1.10.5 事务消息如何设计
1.10.6 mq的应用场景
1.11 理解CAP和BASE理论,理解分布式场景下常见问题和解决,如分布式锁、分布式事务、分布式session、分布式调度任务等。
1.11.1 分布式锁
- Redisson基于Redis实现的分布式锁的原理
- 分布式锁使用场景
- 分布式锁的缺陷
1.11.2 分布式事务
- CAP和BASE理论
- 分布式事务解决方案: 2PC、TCC、MQ最终一致性
- Seata分布式事务框架实现原理
1.11.3 分布式一致性 Session的实现方案
1.11.4 分布式任务调度:xxl-job
1.12 掌握Linux常用命令,了解Nginx服务的反向代理、负载均衡、动静分离。
1.12.1 linux常用命令
1.12.2 nginx反向代理、负载均衡、动静分离
二、工作经历
2.1 利用delayqueue+scheduled+mq实现了延迟消息工具完成了常见的延迟消息场景,并且避免了引入mq延时队列插件导致有多个mq时插件不通用的问题。
2.1.1 技术选择
为什么不使用MQ自带的延迟消息工具?你的做法有什么优点?
2.1.2 具体实现细节
你是如何具体实现延迟消息工具的?可以描述一下基本的工作流程吗?
2.1.3 你是如何处理消息发送失败的情况的?
2.1.4 事务消息是怎么处理的?
2.1.5 延迟消息的使用场景有哪些
2.2 热门数据利用caffeine和redis实现了两级缓存,解决了用redis时压力过大查询缓慢的问题,保证了接口的高性能和高可用。
2.1.1 缓存设计问题:
你是如何决定使用两级缓存架构的?
在什么场景下,两级缓存比单一缓存更有效?
2.1.2 技术选择问题:
为什么选择 Caffeine 作为一级缓存,它相比其他本地缓存(如 Guava、EhCache)有哪些优势?
Redis 作为二级缓存,它的哪些特性让你觉得适合这个场景?
2.1.3 性能优化问题:
你是如何评估 Redis 压力过大的?有使用哪些监控工具吗?
在引入两级缓存后,性能提升了多少?你是如何衡量的?
2.1.4 高可用性问题:
你是如何确保缓存系统的高可用性的?
如果缓存服务宕机,你的系统有哪些降级策略?
2.1.5 缓存一致性问题:
在使用两级缓存时,你是如何处理缓存一致性问题的?
是否遇到过缓存穿透、缓存击穿或缓存雪崩问题?如果有,你是如何解决的?
2.1.6 数据同步问题:
当数据更新时,你是如何确保多个节点中的Caffeine缓存中的数据同步的?
是否有使用发布/订阅模式或其他机制来更新缓存?
2.1.7 缓存配置问题:
你是如何配置 Caffeine 和 Redis 缓存的?比如缓存的大小、过期策略等。
在分布式环境中,Redis 缓存是如何进行集群部署的?
2.1.8 代码实现问题:
你能简单描述一下你在代码中是如何实现两级缓存的吗?
你使用了 Spring Cache 还是直接使用 Caffeine 和 Redis 客户端?
2.1.9 业务理解问题:
这个缓存方案主要解决了哪个业务场景的问题?
哪些数据放在Redis,哪些数据放在Caffeine,还是说本地缓存和Caffeine缓存中的数据是一样的?
2.1.10 扩展性问题:
如果业务增长,缓存需求增加,你打算如何扩展当前的缓存架构?
考虑到未来可能的需求变化,缓存策略会如何调整?
2.3 基于本地消息记录表实现了事务消息的投递过程,引入衰减重试+错误预警保证了消息投递的可靠性。
2.3.1 设计和实现
为什么选择本地消息表来实现事务消息?还有别的方式吗
事务消息,你的方案具体怎么实现的?
在你的方案中,如何保证可靠性呢?怎么保证你把消息记录到本地消息表后,这条消息一定就会被投递到mq,而中途不会产生例如网络不好导致的异常呢?或者讲讲你的衰减重试+错误预警是怎么保证可靠性的?
2.4 基于事务消息+消费幂等+失败补偿方案,利用mq最终一致性解决了分布式事务的问题。
2.4.1 设计和实现
解决分布式事务问题还有别的方案吗?你为什么选择用mq最终一致性来解决?
详细介绍一下你的事务消息+消费幂等+失败补偿方案?
你能详细解释一下你是如何实现事务消息的?具体的设计思路是什么?
什么是消费幂等性?为什么在分布式事务处理中需要实现消费幂等性?
如何确保消息一定会被消费者消费的?(关键在关闭自动ack+消费幂等+失败重试)
幂等消费是怎么实现的?
2.5 使用CompletableFuture优化查询模块,对业务功能模块中的多个异步调用进行重新编排,优化结果显示响应时间从2s降到0.2s。
2.5.1 具体场景:
你能描述一下你是如何识别出原始查询模块存在的性能瓶颈的吗?
这个查询模块是在什么样的业务场景下运行的?它涉及哪些数据源或服务?
2.5.2 技术细节:
你能否解释一下你是如何使用CompletableFuture来优化这个模块的?
在优化过程中,你遇到了哪些挑战?你是如何解决这些挑战的?
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
try {
allFutures.join(); // 等待所有Future完成
} catch (CompletionException e) {
// 如果任何一个Future抛出异常,则在这里被捕获
System.err.println("One of the futures failed with an exception: " + e.getCause());
// 处理异常情况
}
------
CompletableFuture<Data1> future1 = CompletableFuture.supplyAsync(() -> service1.getData());
CompletableFuture<Data2> future2 = CompletableFuture.supplyAsync(() -> service2.getData());
CompletableFuture<Data3> combinedFuture = future1.thenCompose(data1 -> {
return future2.thenApply(data2 -> {
// 结合两个结果
Data3 combinedData = combineData(data1, data2);
return combinedData;
}).exceptionally(throwable -> {
// 如果future2抛出异常,则返回null或其他默认值
System.err.println("Failed to get data2: " + throwable.getMessage());
return null;
});
}).exceptionally(throwable -> {
// 如果future1抛出异常,或者前面的处理中有任何异常,则返回null或其他默认值
System.err.println("Failed to get data1 or combine data: " + throwable.getMessage());
return null;
});
combinedFuture.thenAccept(data3 -> {
if (data3 != null) {
// 正常处理数据
processCombinedData(data3);
} else {
// 异常处理逻辑
handleFailure();
}
});
------
CompletableFuture<Data3> finalFuture = future1.thenCompose(data1 -> future2.thenApply(data2 -> combineData(data1, data2)))
.handle((data3, throwable) -> {
if (throwable == null) {
return data3; // 没有异常,直接返回结果
} else {
System.err.println("Failed to combine data: " + throwable.getMessage());
return null; // 或者返回一个默认值或错误对象
}
});
finalFuture.thenAccept(data3 -> {
if (data3 != null) {
processCombinedData(data3);
} else {
handleFailure();
}
});
2.5.3 性能改进:
你能详细说明一下从2秒减少到0.2秒的具体实现方法是什么?
2.5.4 并发编程经验:
在使用CompletableFuture时,你有没有遇到过线程安全或者死锁等问题?如果有,你是怎么处理的?
除了CompletableFuture,还有其他的并发工具或框架用在项目中实现异步需求吗?
2.5.5 设计模式与架构:
为了实现异步调用,你是否应用了某些设计模式?
你是否有对现有的系统架构进行任何改变以适应新的异步调用需求?
2.5.6 测试与验证:
你是如何确保异步调用的正确性的?你采用了什么样的测试方法?
优化后的系统在负载测试中的表现如何?
2.6 对原有的复杂代码进行重构,采取工厂+策略模式实现了项目的各个业务产品对应的信息创建、编辑的解耦处理,解决了原先老旧代码不易维护的问题。
2.6.1 重构的具体细节
具体场景:
你能具体描述一下原有代码存在的问题吗?为什么说它是复杂的、不易维护的?
怎么重构的,重构前后,代码的结构发生了怎样的变化?
public ResultVO queryTicket(QueryTicketParam param) {
IProvideStrategy provideStrategy = strategyFactory.getProvideStrategy(param.getcId(),param.getType());
return provideStrategy.queryTicketList(param);
}
2.6.2 工厂模式和策略模式的运用
模式选择:
为什么选择了工厂模式和策略模式?还有没有考虑过其他的设计模式?
在你的项目中,工厂模式和策略模式分别解决了什么具体问题?
模式实现:
你能详细解释一下你是如何实现工厂模式的吗?具体是怎么创建对象的?
在使用策略模式时,你是如何定义不同的策略以及它们的执行逻辑的?
2.7 基于自定义注解+jackson序列化器优雅实现不同业务数据的脱敏处理。
2.7.1 你的数据脱敏方案有什么优点?
2.7.2 能详细说明一下这个方案是怎么实现的吗?
2.7.3 你的脱敏策略是怎么设计的?
2.7.4 ContextualSerializer在实现中起到了什么作用?
2.8 第三方sdk接入,如短信接口对接、微信小程序js-sdk对接、内部项目接口对接、银行业务接口对接等。
2.8.1 第三方SDK接入的具体细节
具体场景:
你能描述一下你在项目中接入的第三方SDK有哪些具体的功能需求吗?
在接入这些SDK的过程中,遇到了哪些主要的技术挑战?
技术细节:
你是如何选择和评估这些第三方SDK的?考虑了哪些因素?
在接入过程中,你是如何确保安全性(如数据传输加密、敏感信息保护等)的?
2.8.2 接口对接的具体实现
对接流程:
以短信接口对接为例,你能详细描述一下对接的整个流程吗?
在对接微信小程序js-sdk时,你是如何处理权限校验和数据安全的?
接口设计:
在对接内部项目接口时,你是如何设计接口规范的?如何确保接口的一致性和可扩展性?
对接银行业务接口时,你采用了哪些标准协议或框架?
2.8.1 安全性和可靠性
安全措施:
在对接第三方服务时,你是如何保障数据传输的安全性的?采用了哪些加密技术?
对于敏感数据(如银行账户信息),你是如何处理的?
可靠性保障:
在对接过程中,你是如何处理网络不稳定或第三方服务中断的情况的?
你是否设计了相应的容错机制或备份方案?
2.8.1 测试与验证
测试策略:
在对接完成后,你是如何进行测试的?采用了哪些测试方法?
你是否进行了压力测试或性能测试?结果如何?
问题排查:
在测试过程中,发现了哪些问题?你是如何解决的?
2.8.1 团队协作与沟通
团队合作:
在对接过程中,你是如何与团队成员协作的?如何协调各方的需求?
你是否与其他部门(如产品、运营等)有过沟通?如何确保各方需求得到满足?