你好 我是懂java的测试
前言
前几天有个小伙伴发了在群里发了Java的面试题,仔细看了下都是很基础的面试题,如果你简历上写了熟悉或了解java可能会问到,切记不要死记硬背,得在理解的基础上背诵。本篇文章就详细梳理一下这个java面试题
Redis为什么这么快?
具体原因可阅读另两篇文章
测试工程师都能看懂的Redis 上 、测试工程师都能看懂的Redis 下
多线程有什么好处?
多线程最大的好处就是:
-
更好地利用CPU
-
简单的程序设计
-
程序更多的响应
-
多任务下CPU资源分配公平性
线程池作用,几个参数?
去年面试货拉拉的时候,面试官问过我这个问题。线程频繁创建其实很消耗资源,有了线程池,线程用完可以放入线程池中,降低了资源消耗。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
1、corePoolSize线程池中的常驻核心线程数
2、maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值大于等于1
3、keepAliveTime:多余的空闲线程存活时间,当空间时间达到keepAliveTime值时,多余的线程会被销毁
直到剩下corePoolSize个线程为止。
默认情况下:只有当线程池中的线程数大于corePoolSize时keepAliveTime才会起作用,知道线程中的线程
数不大于corepoolSIze。
4、Unit:keepAliveTime的单位
5、WorkQueue:任务队列,被提交但尚未被执行的任务
6、ThreadFactory:表示生成线程池中工作线程的线程工厂,用户创建新线程,一搬用默认即可
7、Handler:拒绝策略,表示当线程队列满了并且工作线程大于等于线程池的最大线程数
(maximumPoolSize)时如何来拒绝请求执行的runnable的策略
当线程池中corePoolSize使用完毕之后,多出来的任务就会进入缓存队列;当缓存队列也存放满了之后,还有大量的任务,这时将会创建线程池中支持的最大量的线程,然后执行缓存队列里面的任务,而外面的任务进入缓存队列中;当线程池中的线程达到最大时,缓存队列也存满之后,这时该线程池将会执行拒绝策略。
jmeter 测试性能主要关注啥?
接口响应时间、错误率和Tps
java三大特性?
见 Java基础之面对对象文章,里面有继承、多态的介绍
索引是什么,底层是什么?
见 Mysql相关面试题 上 文章关于索引介绍
arraylist和linkedlist区别?
arraylist底层是 动态数据,查询快和插入数组最后面较快。
注意:数据插入非尾部,涉及到下标index移位
linkedlist底层是链表,插入和查询头部元素较快。
注意:linkedlist如果查询头部元素还是比较快的。
数组查询效率高?
数组是一组连续的内存,查询的时候可以用index直接取到,时间复杂度为O(1),
HashMap底层原理是什么?
Java最经典的集合,没有之一,这个集合几乎涵盖了java所有的基础知识,如果聊起来两个小时都不够。我每次去面试java测开,hashmap被问到的概率高达90%。
底层是数组+链表,jdk 1.8以后变成数组+链表+红黑树。为什么变成了红黑树了呢?使用红黑树提高了查询效率,因为链表数据结构的查询时间复杂度是O(n),随着元素越来越多,查询效率只会越来越低,红黑树时间复杂度是 O(logn) 查询效率更高。
除了底层原理外,还有其他扩容机制、锁原理、并发访问等等知识,后面打算出一期文章,专门聊聊HashMap。
Spring的依赖注入是啥?
来自群里小伙伴的回答
锁的机制了解不,什么原因导致死锁?
什么是锁呢?锁机制是实现线程同步的基础
Java中的锁无非就是JVM提供的synchronized关键字和JDK中的Lock接口实现。
在使用多线程以及多进程时,两个或两个以上的运算单元(进程、线程或协程),各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,就称为死锁。
String、Stringbuffer、StringBuilder区别?
老八股文了都,值得2016年刚毕业去面试的时候,面试官就问过它们三个的区别,没想到现在还有人会问,
总结:
1.String字符串是不可变的。
2.在修改字符串操作比较多的时候用StringBuilder或StringBuffer.
3.在要求线程安全的情况下用StringBuffer
4.在不要求线程安全的情况下用StringBuilder
怎么保证线程并发事件发生?
这个问题就比较诡异了,题目问道怎么保证线程并发事件发生,个人理解并发事件的发生可能会导致线程安全问题,所以这道题目其实是想问,怎么保证线程安全。
加锁,如果是单机系统,可以用JVM提供的synchronized关键字和JDK中的Lock接口实现,还可以用JUC包下并发组件,譬如,atomic原子类concurrenthashmap 等。
如果是分布式系统,且有共享的资源,那就使用分布式锁吧,后面详聊。
什么是反射?
JAVA机制反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
bean的生命周期?
这个没办法,死记硬背吧,就是一些spring的关键类,
对于Bean的生命周期,主要步骤为:
1、实例化Bean:通过反射调用构造方法实例化对象。
2、依赖注入:装配Bean的属性
3、实现了Aware接口的Bean,执行接口方法:如顺序执行BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
4、Bean对象初始化前,循环调用实现了BeanPostProcessor接口的预初始化方法(postProcessBeforeInitialization)
5、Bean对象初始化:顺序执行@PostConstruct注解方法、InitializingBean接口方法、init-method方法
6、Bean对象初始化后,循环调用实现了BeanPostProcessor接口的后初始化方法(postProcessAfterInitialization)
7、容器关闭时,执行Bean对象的销毁方法,顺序是:@PreDestroy注解方法、DisposableBean接口方法、destroy-method。
新开了java测试开发交流群,喜欢的可加入,若失效,可加我微信lvceshikaifa,拉你进群。