当前位置:   article > 正文

java面试题——2-5年java后端开发常见面试题(六)

java面试题——2-5年java后端开发常见面试题(六)

1、序列化和反序列化什么时候用到?

使用redis为对象做持久化,就是把内存里的对象保存到磁盘(暂且叫做磁盘吧,可以等同于sp、db、文件、网络等)上,等以后需要这个对象的时候再从磁盘上还原到内存,因此需要序列化和反序列化。


2、设计模式之策略模式有了解吗?

什么是策略模式:

策略模式是对算法的包装,是把使用算法的责任和算法本身分隔开来,委派给不同的对象管理,最终可以实现解决多重if判断问题:

为什么叫策略模式:

每个if判断都可以理解为就是一个策略。

  1. public String toPay(String payCode){
  2. if(payCode.equals("ali_pay")){
  3. return "调用支付宝接口支付";
  4. }
  5. if(payCode.equals("weixin_pay")){
  6. return "调用微信支付接口支付";
  7. }
  8. if(payCode.equals("yinlian_pay")){
  9. return "调用银联支付接口支付";
  10. }
  11. return "未找到该支付接口";
  12. }

我们来看上面一段代码,我们传不同的payCode,得到对应的支付平台,调用接口行为是相同的,调用接口代码是不同的。


3、锁的优化有了解吗?

一、锁的优化的思路和方法

1、减少锁持有时间

2、减小锁粒度
(1)将大对象拆分成小对象,大大增加并行度,降低锁竞争
(2)偏向锁,轻量级锁成功率提高
(3)ConcurrentHashMap

  1. 若干个Segment:Segment<K,V>[]segments
  2. Segment中维护HashEntry<K,V>
  3. pu操作时,先定位到Segment,锁定一个Segment,执行put
  4. 在减小锁粒度后,ConcurrentHashMap允许若干个线程同步进入

(4)HashMap的同步实现

  1. Collections.synchronizedMap(Map<K,V> m)
  2. 返回SynchronizedMap对象

3、锁分离
(1)根据功能进行锁分离
(2)ReadWriteLock
(3)读多写少的情况,可以提高性能
(4)只要操作互不影响,锁就可以分离
(5)LinkedBlockingQueue:队列、链表

4、锁粗化
通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能今早的获得资源执行任务。但如果对同一个锁不停的进行请求、同步和释放,其本身也会消除系统宝贵的资源,反而不利于性能的优化

5、锁消除
在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作

二、虚拟机内的锁优化

1、对象头Mark
(1)Mark Word,对象头的标记,32位
(2)描述对象的hash、锁信息,垃圾回收标记,年龄
(3)指向锁记录的指针、指向monitor的指令、GC标记、偏向锁线程ID

2、偏向锁
(1)大部分情况是没有竞争的,所以可以通过偏向来提高性能
(2)所谓偏向,即锁会偏向于当前已经占有锁的线程
(3)将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark
(4)只要没有竞争,获得偏向锁的线程,在将来进入同步块,不需要做同步
(5)当其他线程请求相同的锁时,偏向模式结束
(6)在竞争激烈的场合,偏向锁会增加系统负担


4、spring的IOC和AOP在写代码的时候哪里有用到?

ioc:

  1. @Controller //控制器,推荐给Controller层添加此注解
  2. @Service //业务逻辑,推荐给业务逻辑层添加此注解
  3. @Repository //仓库管理,推荐给数据访问层添加此注解
  4. @Component //给不属于以上基层的类添加此注解

aop:

  1. //标记这个类是一个切面
  2. @Aspect
  3. public class AnnotationPointCut {
  4. @Before("execution(* com.wzq.service.UserServiceImpl.*(..))")
  5. public void before() {
  6. System.out.println("==========方法执行前==========");
  7. }
  8. @After("execution(* com.wzq.service.UserServiceImpl.*(..))")
  9. public void after() {
  10. System.out.println("==========方法执行前==========");
  11. }
  12. //在环绕增强中,可以给定一个参数,代表想要获取处理切入的点
  13. @Around("execution(* com.wzq.service.UserServiceImpl.*(..))")
  14. public void around(ProceedingJoinPoint jp) throws Throwable {
  15. System.out.println("Around ==========方法执行前==========");
  16. //执行
  17. Object proceed = jp.proceed();
  18. //获取签名
  19. Signature signature = jp.getSignature();
  20. System.out.println(signature);
  21. System.out.println("Around ==========方法执行后==========");
  22. }
  23. }

5、一个事务外面还有一个事务,按照Spring事务的默认传播级别,这个运行过程说一下?

* 保证同一个事务中
PORPAGATION_REQUIRED:支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常
* 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行


6、单例模式中的双重校验锁实际在哪里用到的?

又要懒加载、又要高性能,又要线程安全的时候用


7、索引的最左前缀原则,他举例子,问你运行后能不能用到索引?

最左前缀原则:顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上。

当创建(a,b,c)复合索引时,想要索引生效的话,只能使用 a和a,b和a,b,c三种组合


8、你们接口在哪些场景加redis,怎么加redis的?

由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页接口数据缓存到redis缓存中,减少数据库压力和提高访问速度。


9、泛型T和?有什么区别?分别应用于什么场景?

泛型的使用有效的降低了代码的冗余,减少了重复无用的代码,使代码的可读性更高,更简洁,同时也缩短了搬 砖工人的重复劳动时间。

T:表示确定的类型,最常用的泛型表示方法。
? :表示不确定的类型,类似于通配符。

类型参数T主要用于,声明泛型类或泛型方法。
无界通配符?主要用于,使用泛型类或泛型方法


10、@springbootapplication 底层有哪三个注解?

@SpringBootConfiguration:

该注解由Spring原生注解@Configuraction封装而成。

@ComponentScan:

该注解主要用来开启组件扫描,可以扫描该注解标注的类、以及该注解标注的类的目录路径下的类,并将其实例注册添加到Spring容器中。此处需注意,由于Spring仅仅整合了自己的注解,并没有接收Mybatis的注解,因此SpringBoot整合Mybatis时,需要额外添加注解:@MapperScan(“/指向mybatis的包路径”)

@EnableAutoConfiguration:

该注解主要用来提供自动装配,是这三个注解中最重要的一个注解。她是Spring Boot新添加的注解,提供了强大的自动依赖功能,是SpringBoot这么方便的大功臣。

自动装配原理:
@EnableAutoConfiguration注解的关键在于引入了AutoConfigurationImportSelector,其核心逻辑为selectImports方法,逻辑大致如下:
从配置文件META-INF/spring.factories加载所有可能用到的自动配置类;去重,并将exclude和excludeName属性携带的类排除;过滤,将满足条件(@Conditional)的自动配置类返回。


11、mybatis的工作原理?

通过SqlSessionFactoryBuilder从mybatis-config.xml配置⽂件中构建出SqlSessionFactory会话工厂,然后SqlSessionFactory的实例直接开启⼀个SqlSession会话对象,再通过SqlSession实例获得Mapper对象并运⾏Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。


12、如何快速排查微服务的各种问题?

Zipkin 是一款开源的分布式实时数据追踪系统,由基于 Google Dapper 的论文设计而来,由 Twitter 公司提供开源实现,主要功能是聚集来自各个异构系统的实时监控数据,和微服务架构下的接口直接的调用链路和系统延时问题。

链路追踪即通过跟踪一个请求从发布到被响应的整个过程,了解到每个请求的详细经过,比如有哪些服务参与,参与顺序是什么,各服务调用了多少次数据库等。如此一来 ,当出现异常问题,开发就能快速定位问题根源,快速解决问题。

链路追踪优点:

  • 服务关系:可以很清晰地展现服务间的依赖或者调用关系;
  • 故障定位:在系统出现故障时候可以快速高效定位问题;
  • 系统监测:在系统服务性能变差时可以及时发现,提前采取预防措施;
  • 系统瓶颈分析与优化:基于全链路分析,很容易找出系统性能瓶颈点并作出优化改进,验证优化措施是否奏效

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号