金三银四----Java面试复盘(二)

Java基础篇:

  1. List接口下有哪些类?它们的区别?

1.ArrayList:底层是动态数组;查询快,插入和删除慢;线程不安全的。
2.LinkedList:底层是双向链表;插入和删除快,查询慢;线程不安全的。
3.Vector:底层和ArrayList一样;查询快,插入和删除慢;线程安全的。
拓展:为什么Vector是线程安全的,因为它的方法都加了synchronized关键字修饰。

  1. 线程的创建方式?

Thread
Runable
Callable
线程池

  1. 阻塞队列是什么意思?

阻塞队列(BlockingQueue) 是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

  1. jdk1.7中有哪些阻塞队列?

ArrayBlockingQueue : 一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue : 一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue : 一个支持优先级排序的无界阻塞队列。
DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue: 一个不存储元素的阻塞队列。
LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。

  1. 启动线程为什么要先Start(),在Run()?

1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。 然后通过此Thread类调用方法run()来完成其运行操作的, 这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码; 程序中只有主线程——这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。

框架篇:

  1. mybatis中dao(Mapper)接口的原理?

Dao接口的工作原理是JDK动态代理,MyBatis运行时会使用JDK动态代理,为Dao接口生成代理proxy对象,代理proxy对象会拦截接口方法,转而执行MappedStatement所代表的sql,然就将执行结果返回。
Mapper 接口开发需要遵循以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的全限定名相同
  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
  1. Spring中依赖注入(DI)和控制反转(IoC)?

IoC和DI其实是同一概念的不同角度描述。IoC强调的是将对象实例的创建控制权由spring容器来统一管理,需要的时候从容器中取出,而不是由调用者自身去创建,从而达到降低代码耦合性与硬代码的目的。依赖注入强调的是当调用者需要使用对象实例时,spring容器为调用者提供对象实例这个过程。本质上应该是属于同一技术实现方式,但是在不同的情况,叫法不同。就好比张三在村里住的时候,邻居叫他狗蛋,但是出到外面打工,别人叫他张三一样。

  1. Spring中如何解决循环依赖?

有A,B两个类,A类中有B类属性,B类中有A类属性。加载过程,首先创建A类,先从ApplicationContext.getBean()获取A类,这时A类不存在,所以创建一个A类,接下来就是创建A中B类的属性,同样是使用ApplicationContext.getBean()来获取B类,这时B类也不存在,所以要创建一个B类,接下来就是创建B类中A类的属性了,还是调用ApplicationContext.getBean()方法,不过这次会从缓存中得到一个A类的半成品,给A属性,创建好了之后,B类也创建好了,给B属性,这时A类也创建完成。其中B类得到的A类的半成品,和A类是同一个引用地址。所以是一个对象。(ApplicationContext.getBean()方法是通过doGetBean来获取对象,而doGetBean是通过GetSingleton来获取对象)

  1. 用过哪些mybatis的插件?有没有写过?

mybatis-generator:根据数据库自动生成pojo、dao和xml文件。
mybatis-plugin:这是一个能够追踪dao 接口和mapper文件里xml的一个插件
mybatis-pagehelper:它是一个开源的分页插件点击打开链接,它的原理,是通过spring的AOP来实现的,这个插件能在执行sql的时候,把相关的数据再执行一次。

中间件篇:

  1. redis主从复制的应用

读写分离:主从复制可以用来支持读写分离
数据安全:slave 服务器设定为只读
避免 master 持久化造成的开销

  1. redis的缓存穿透和雪崩原理?

缓存雪崩:指在我们设置缓存时,key采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩

解决方案:
1.使用 Redis 高可用架构:使用 Redis 集群来保证 Redis 服务不会挂掉
2. 缓存时间不一致,给缓存的失效时间,加上一个随机值,避免集体失效
3. 限流降级策略:有一定的备案,比如个性推荐服务不可用了,换成热点数据推荐服务

缓存穿透:指查询大量为null的数据,导致数据库压力增大
解决方案:
1.在接口做校验
2.存null值(缓存击穿加锁)
3.布隆过滤器拦截: 将所有可能的查询key 先映射到布隆过滤器中,查
时先判断key是否存在布隆过滤器中,存在才继续向下执行,如果不存在,则直接返回。布隆过滤器将值进行多次哈希bit存储,布隆过滤器说某个元素在,可能会被误判。布隆过滤器说某个元素不在,那么一定不在。

  1. zookeeper的选举机制?

目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:

  1. 服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking。
  2. 服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
  3. 服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为leader,服务器1,2成为follower。
  4. 服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为follower。
  5. 服务器5启动,后面的逻辑同服务器4成为follower。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forrest Gump plus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值