总结一下最近的面试的常见面试题,有些有答案有些没有。
最近两星期面了六家小公司,两家大公司(一家外包性质),还有一家南京外包。总结一下最近遇到的常见面试题,感觉有用就看看,祝各位大佬都能找到自己满意的工作。如果简历和面试想交流的欢迎私信,如果说你其他条件都很好,简历初筛都不通过,那么一定是你简历写的有问题了。
1.HashMap实现原理
2.创建线程的方式,线程的状态
3.线程池的七个参数和应用场景
4.JUC并发工具包用过哪些
5.CAS和AQS
CAS(Compare and Swap)和AQS(AbstractQueuedSynchronizer)都是Java中用于实现并发编程的重要机制。
CAS是一种乐观锁的实现方式,它基于CPU的原子操作指令实现。CAS操作包括三个步骤:读取当前内存值、比较当前内存值与期望值、如果相同则进行更新操作。CAS适用于多线程环境下的并发操作,可以保证变量的原子性操作。在Java中,java.util.concurrent.atomic
包中的原子类(如AtomicInteger、AtomicReference等)就是基于CAS实现的。
AQS是实现锁和同步器的基础类,通过AQS可以实现自定义的同步器。AQS提供了一套基于FIFO队列的排队机制,通过重写AQS的方法可以实现锁和同步器的功能。AQS内部维护了一个双向链表,用于存储等待获取锁的线程,并通过CAS操作来实现线程的挂起和唤醒。java.util.concurrent.locks
包中的ReentrantLock、Semaphore等锁类就是基于AQS实现的。
在Java并发编程中,CAS和AQS共同构成了一套高效且灵活的并发编程工具集。CAS提供了一种原子性操作的基础,AQS则提供了一种通用的同步器框架,开发者可以基于AQS来实现各种自定义的同步器。通过合理地使用CAS和AQS,可以在多线程环境下实现高性能、线程安全的并发编程方案。
6.数据库MySQL的sql语句掌握程度
7.数据库索引,需求:按照a,b,c三个字段查询,如何去建索引
如果需要按照字段a、b、c三个字段进行查询,可以考虑建立一个联合索引(Composite Index),联合索引是建立在多个字段上的索引,可以提高查询效率。
在建立联合索引时,需要考虑以下几点:
-
选择合适的字段顺序:根据查询场景和具体的需求,选择合适的字段顺序建立联合索引。一般来说,将经常用于过滤的字段放在联合索引的前面可以提高查询效率。
-
避免冗余字段:避免在联合索引中出现冗余或不必要的字段,以减小索引的大小和提高性能。
-
考虑字段的数据类型和长度:在建立联合索引时,需要考虑字段的数据类型和长度,尽量保持字段长度较短,避免影响索引的效率。
对于按照字段a、b、c三个字段查询的需求,可以按照以下步骤建立联合索引:
CREATE INDEX idx_abc ON table_name (a, b, c);
这样就可以在字段a、b、c上建立一个联合索引,提高按照这三个字段进行查询的效率。
需要注意的是,在设计索引时需要根据具体的业务场景和查询需求进行优化,不同的查询需求可能需要不同的索引设计。建立合适的索引可以提高查询效率,同时也需要避免创建过多或不必要的索引,以减少索引维护的开销。
8.数据库索引的种类,为什么建索引
9.sql优化有了解吗?应用场景
Redis
1.缓存击穿、缓存穿透、缓存雪崩,有遇到过吗?怎么解决的?
2.你是怎么保证MySQL和redis的数据一致的。
3.大面积key失效是什么场景,你准备怎么解决
10.Spring框架IOC容器启动过程
Spring框架的IOC容器启动过程主要包括以下几个阶段:
-
加载配置文件:Spring容器会读取并解析应用程序中的配置文件,一般是XML格式的Spring配置文件(如applicationContext.xml)或基于注解的配置类。
-
创建容器:Spring根据配置文件中定义的Bean信息,实例化并管理各个Bean对象。在容器启动过程中,Spring会创建一个BeanFactory或ApplicationContext容器对象。
-
注册Bean定义:Spring容器会根据配置文件中的Bean定义信息,将Bean对象注册到容器中,并配置Bean之间的依赖关系。
-
实例化Bean:容器启动后,会根据Bean定义信息实例化各个Bean对象,并根据需要填充Bean的属性。
-
注册BeanPostProcessor:Spring容器会注册BeanPostProcessor接口的实现类,这些类可以在Bean实例化之后、初始化之前和初始化之后对Bean进行处理。
-
初始化Bean:容器会调用Bean的初始化方法(如@PostConstruct注解标注的方法或实现InitializingBean接口的方法)对Bean进行初始化。
-
完成容器启动:容器启动完成后,可以通过ApplicationContext接口提供的各种方法来获取和操作Bean对象。
总的来说,Spring的IOC容器启动过程就是将Bean注册到容器中、实例化Bean、初始化Bean、以及处理Bean之间的依赖关系等一系列操作。通过IOC容器,Spring实现了对象的创建、管理和协调,实现了松散耦合和可维护性,使得业务逻辑和对象的创建、销毁、依赖等不再紧密耦合在一起。
11.Spring框架bean的生命周期
Spring 中 Bean 的生命周期大致分为四个阶段:实例化(Instantiation)、属性赋值(Populate)、初始化(Initialization)、销毁(Destruction)。
12.Spring框架AOP,AOP用过吗
13.Spring事务中,什么情况下导致事务失效
14.Spring框架提供几种事务的传播行为
Spring框架提供以下几种事务的传播行为:
-
REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。
-
SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式执行。
-
MANDATORY:必须存在一个事务,如果当前没有事务,则抛出异常。
-
REQUIRES_NEW:创建一个新事务,如果当前存在事务,则将当前事务挂起。
-
NOT_SUPPORTED:以非事务的方式执行操作,如果当前存在事务,则将当前事务挂起。
-
NEVER:以非事务的方式执行操作,如果当前存在事务,则抛出异常。
-
NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新事务。嵌套事务的提交和回滚会影响到外部事务的提交和回滚。
每种传播行为都可以根据具体情况选择适合的使用方式,以确保事务管理的准确性和一致性。
15.springboot相比于SSM的优势在哪劣势在哪
Spring Boot和传统的SSM(Spring + Spring MVC + MyBatis)框架相比,各有优劣势:
Spring Boot的优势:
-
简化配置:Spring Boot提供了自动配置功能,通过约定大于配置的方式,可以快速搭建和配置项目,减少了繁琐的配置工作。
-
内嵌式容器:Spring Boot内置了多种常用的Web容器(如Tomcat、Jetty),可以方便地进行打包和部署,不再需要依赖外部的容器。
-
微服务开发:Spring Boot支持快速开发和部署微服务架构,包括服务注册发现、配置中心、断路器等功能。
-
自动化管理:Spring Boot集成了Actuator监控组件,可以方便地进行应用的健康监测和管理。
Spring Boot的劣势:
-
学习曲线较陡:对于初学者来说,由于Spring Boot集成了大量的常用组件和框架,可能需要一定的学习成本。
-
不适合复杂场景:对于复杂的企业级应用或有特定需求的项目来说,Spring Boot可能提供的默认配置和功能不足以满足要求,需要定制化开发。
-
集成组件版本更新快:Spring Boot集成了大量的组件和框架,其中一些组件在更新时可能会导致兼容性问题,需要及时更新升级。
SSM框架的优势:
-
灵活性强:SSM框架相对灵活,可以根据项目的需求选择合适的技术栈和组件,满足不同情况下的定制开发需求。
-
经典稳定:SSM框架是JavaWeb开发的经典组合,已经得到广泛应用和验证,稳定性较高。
-
社区资源丰富:由于长期得到开发者的支持和使用,在社区资源和解决方案方面比较成熟。
SSM框架的劣势:
-
配置繁琐:传统的SSM框架需要手动配置大量XML文件,配置过程繁琐,并且容易出现错误。
-
缺乏自动化功能:SSM框架缺乏自动化配置和管理功能,开发者需要手动管理依赖、部署等操作。
-
比较落后:相比于Spring Boot,SSM框架的技术栈相对较为传统,可能不够适应当前快速发展的技术潮流。
16.能手写springboot的starter吗?
编写一个Spring Boot的Starter主要包括以下几个步骤:
-
创建一个Maven项目: 在Maven项目中创建以下几个模块:
-
starter模块:用于编写Starter的核心逻辑和配置。
-
sample模块:用于测试Starter。
-
在starter模块中编写自定义的自动配置类(AutoConfiguration): 编写一个自动配置类,该类会在Spring Boot应用启动时自动配置相关的Bean和组件。
@Configuration @EnableConfigurationProperties(HelloProperties.class) public class HelloAutoConfiguration { @Autowired private HelloProperties helloProperties; @Bean public HelloService helloService() { return new HelloService(helloProperties.getMessage()); } }
-
创建一个配置类来定义Starter的属性: 编写一个配置类,用于定义Starter需要的属性,如下所示:
@ConfigurationProperties("hello") public class HelloProperties { private String message = "Hello, World!"; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
-
在resources目录下创建META-INF/spring.factories文件,注册自动配置类的全限定名: 在spring.factories文件中添加如下配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.demo.configuration.HelloAutoConfiguration
-
在sample模块中使用自定义的Starter: 在sample模块的application.properties文件中配置Starter的属性:
hello.message=Hello, Spring Boot Starter!
在一个Spring Boot的应用中,直接注入HelloService即可使用自定义的Starter:
@RestController @EnableAutoConfiguration public class HelloController { @Autowired private HelloService helloService; @RequestMapping("/") public String home() { return helloService.sayHello(); } public static void main(String[] args) { SpringApplication.run(HelloController.class, args); } }
这样就完成了一个简单的Spring Boot Starter的编写和使用。当我们在Spring Boot应用中引入自定义的Starter依赖后,Starter中定义的自动配置类会生效,相应的Bean会被自动注入到Spring容器中,从而实现了自定义功能的快速集成和使用。
17.你的项目中使用分布式锁,你的实现方案是什么,出现并发修改的时候你是怎么做的?
18.分布式事务和传统的事务相同点和不同点
分布式事务和传统的事务在某些方面有相同点,同时也存在一些显著的不同点。以下是它们的相同点和不同点:
相同点:
-
ACID特性:分布式事务和传统事务都遵循ACID(原子性、一致性、隔离性、持久性)特性,保证事务的正确性和完整性。
-
保证数据一致性:无论是分布式事务还是传统事务,都致力于确保事务操作在执行完毕后数据的一致性。
-
提供事务管理:分布式事务和传统事务都提供了事务管理机制,可以控制事务的提交、回滚和隔离级别。
不同点:
-
分布式环境:分布式事务通常在多个独立的节点或系统之间进行操作,而传统事务通常在单个数据库或系统中进行操作。
-
事务管理协议:传统事务通常使用本地事务管理机制(如JDBC事务、Spring事务管理),而分布式事务需要使用分布式事务管理协议(如XA协议、TCC协议)来实现跨多个系统的事务一致性。
-
性能开销:由于涉及多个系统的通信和协调,分布式事务通常比传统事务具有更高的性能开销和复杂度。
-
故障处理:在分布式环境下,出现故障或网络问题可能会导致事务的不确定状态,需要额外的机制来保证事务的正确性。
-
可伸缩性:传统事务在面对大规模的并发请求时可能会成为性能瓶颈,而分布式事务可以通过拆分事务、分布式锁等措施来提高可伸缩性。
总的来说,分布式事务和传统事务都是为了保证数据的一致性和事务的可靠性,但在应对分布式环境以及处理跨系统事务时存在一些不同。在选择事务模型时,需要根据具体业务场景和需求来决定使用传统事务还是分布式事务。