找工作好难呀之Java面试题总结(不断总结中)
Posted 可乐好哇!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找工作好难呀之Java面试题总结(不断总结中)相关的知识,希望对你有一定的参考价值。
什么是面向对象?
-
面向过程注重事情的每一个步骤
-
面向对象注重事情有哪些参与者以及各自需要干什么
-
封装:明确标识允许外部使用的所有成员函数和数据项
-
继承:继承基类的方法,并且自己做出扩展或改变
-
多态:继承、方法重写、父类引用子类对象(便于开发扩展新的功能)
父类类型 变量名 = new 子类对象(); 变量名.方法名(); // 调用的是子类的方法,但是没办法调用子类独有的功能
重载和重写的区别?
- 重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时
- 重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类不能重写该方法
接口和抽象类的区别?
- 抽象类:可以存在普通成员函数,可以是各种类型的,只能继承一个
- 接口:只能存在public abstract 方法,成员变量只能是public static final 类型的,接口可以实现多个
JDK、JRE、JVM三者区别和联系?
-
JDK:Java开发工具
-
JRE:Java运行时环境
-
JVM:Java虚拟机
-
JDK(JRE(JVM))
== 和 equals(笔试)
- == :对比栈中的值,基本数据类型是变量的值,引用类型是堆中内存对象的地址
- equals:可以重写
final的作用?
- 修饰类时,类不可以被继承
- 修饰方法时,方法不可被子类覆盖,但是可以重载
- 修饰变量时,变量一旦被赋值就不可以更改它的值
String、StringBuffer、StringBuilder区别及使用场景?
- String:是final修饰的,不可变,每次操作都会产生新的String对象
- StringBuffer:在原对象上操作,是线程安全的,它的方法都是synchronize修饰
- StringBuilder:在原对象上操作,是线程不安全的
- 性能:StringBuilder > StringBuffer > String
- 场景:优先使用 StringBuilder,多线程使用共享变量时使用StringBuffer(解决并发问题)
List 和 Set 的区别?
- List:有序,按对象进入的顺序保存对象,可重复,允许多个Null元素对象,可以用iterator取出所有的元素,再逐一遍历,还可以使用get(int index)获取指定的下标元素
- Set:无序,不可重复,最多允许一个Null元素对象,取元素时只能用iterator接口取得所有元素,再逐一遍历各个元素
hashCode 与 equals?
- equals:默认是object中的方法相等与“==”,也可以重写它的方法
- hashCode:两个对象相等,则hashCode一定相同;两个对象相等,对两个对象分别调用equals方法都返回true;两个对象有相同的hashCode值,他们也不一定是相等的;equals方法被覆盖过,则hashCode方法也必须被覆盖;hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等
ArrayList 和 LinkedList的区别?
- ArrayList:基于动态数组,连续内存存储的,适合下标访问,有自己的扩容机制,如果数组空间足够,尾插法效率可能比LinkedList的更高效
- LinkedList:基于链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询
HashMap 和 HashTable 的区别?其底层实现是什么?
-
区别:
- HashMap 方法没有synchronize修饰,线程不安全;HashTable是线程安全的
- HashMap允许key和value为null,而HashTable不允许
-
底层实现:(数组 + 链表实现)
-
jdk8开始链表高度到8,数组长度超过64,链表转变为红黑树,元素以内部Node节点存在
- 计算key的hash值,二次hash然后对数组长度取模,对应到数组下标
- 如果没有产生hash冲突,则直接创建Node存入数组
- 如果产生hash冲突,先进行equals比较,相同则取代该元素,不同则判断链表高度插入链表,链表高度达到8,并且数组长度到64则转变为红黑树,长度低于6则将红黑树转回链表
- key为null,存在下标0的位置
-
数组扩容
-
Java中的类加载器
- BootStrapClass
- ExtClassLoader
- AppClassLoader
什么是双亲委派模型?好处?
- 向上委派:实际上就是查找缓存,是否加载了该类,有就直接返回,没有继续向上
- 向下查找:查找加载路径,有就加载返回,没有就继续向下查找
- 主要为了安全性,避免用户自己编写的类动态替换Java的核心类
- 避免类的重复加载,因为JVM中区分不同类,不仅仅是根据类名,相同的class文件被不同的ClassLoader加载就是不同的两个类
线程的生命周期
-
线程通常有五种状态:创建,就绪,运行,阻塞和死亡状态
- 新建状态(New):新创建了一个线程
- 就绪状态(Runnable):线程对象创建后,其他线程调用该对象的start方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权
- 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码
- 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态
- 死亡状态(Dead):线程执行完了或者因为异常退出了run方法,该线程结束生命周期
-
阻塞的情况分为三种:
- 等待阻塞:运行线程执行wait方法,该线程会释放占用的所有资源,JVM会吧线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify或notifyAll方法才能被唤醒,wait是object类的方法
- 同步阻塞:运行的线程在获取对象的同步锁时,若同步锁被别的线程占用,则JVM会把该线程放入“锁池”中
- 其它阻塞:运行的线程执行sleep或join方法,或者发出I/O请求时,JVM会把该线程置为阻塞状态。当sleep状态超时,join等待线程终止或者超时,或者I/O处理完毕时,线程重新转入就绪状态。sleep是Thread类的方法
并发的三大特性
- 原子性:不被中断操作,要不全部执行完成,要不都不执行
- 可见性:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
- 有序性:虚拟机在进行代码编译时,对那些改变顺讯之后不会对最终结果造成影响的代码,虚拟机不一定惠安张我们写的代码顺序来执行,有可能将他们重排序
为什么用线程池?解释下线程池参数
- 降低资源消耗;提高线程利用率,降低创建和销毁线程的消耗
- 提高响应速度;任务来了,直接有线程可用可执行,而不是先创建线程,再执行
- 提高线程的可管理性;线程是稀缺资源,使用线程池可以统一分配调优监控
线程池处理流程
- 线程池执行任务
- 判断线程是否已满,未满就创建核心线程,满了就继续下面流程
- 判断任务队列是否已满,未满就将任务放入队列中,满了就继续下面流程
- 判断线程数是否达到,未达到就创建临时线程执行,达到就执行下面流程
- 根据拒绝策略处理任务
线程池中阻塞队列的作用?为什么是先添加队列而不是先创建最大线程?
- 阻塞队列通过阻塞可以保留住当前想要继续入队的任务;它可以保证任务队列中没有任务是阻塞获取任务的线程,使得线程进入wait状态,释放CPU资源;它自带阻塞和唤醒功能,不需要额外处理,无任务执行时,线程池利用阻塞队列的take方法挂起,从而维持核心线程的存活、不至于一直占用CPU资源
- 在创建新线程的时候,是要获取全局锁的,这个时候其他的就得阻塞,影响了整体效率
线程池中线程复用原理
- 线程池将线程和任务进行解耦,线程是线程,任务是任务,摆脱之前通过Thread创建线程时的一个线程必须对应一个任务的限制
- 在线程池中,同一个线程可以从阻塞队列中不断获取新任务来执行,其核心在于线程池对Thread进行了封装,并不是每次执行任务都会调用Thread.start()来创建新线程,而是让每个线程去执行一个“循环任务”,在这个“循环任务中”不停检查是否有任务需要被执行,如果有则直接执行,也就是调用任务中的run方法,将run方法当成一个普通的方法执行,通过这种方式只使用固定的线程就将所有的任务run方法串联起来
索引的基本原理
- 索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般说执行查询时遍历整张表
- 索引的原理:就是把无序的数据变成有序的查询
- 把创建了索引的列的内容进行排序
- 对排序结果生成倒排表
- 在倒排表内容上拼上数据地址链
- 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据
索引设计原则
- 查询更快、占用空间更小
mysql锁的类型有哪些?
- 基于锁的属性:共享锁,排他锁
- 基于锁的粒度分类:行级锁(INNODB)、表级锁(INNODB、MYISAM)、页级锁(BDB引擎)、记录锁、间隙锁、临键锁
- 基于锁的状态:意向共享锁、意向排他锁
事务的基本特性和隔离级别
- 事务的基本特性ACID分别是:(用户微信转账场景)
- 原子性:一个事务中的操作要么全部成功,要么全部失败
- 一致性:数据库总是从一个一致性的状态转换到另一个一致性的状态
- 隔离性:一个事务的修改在最终提交前,对其他事务是不可见的
- 持久性:一旦事务提交,所做的修改就会永久保存到数据库中
- 隔离性有4个隔离级别:
- ru读未提交,可能会读到其他事务未提交的数据,也叫脏读
- rc读已提交,两次读取结果不一致,叫做不可重复读
- rr可重复读,MySQL默认级别,每次读取的结果都一样,但是可能产生幻读
- 串行,一般不会使用,它会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题
如何实现IOC容器
- 配置文件配置包扫描路径
- 递归包扫描获取的.class文件
- 反射、确定需要交给IOC管理的类
- 对需要注入的类进行依赖注入
以上是关于找工作好难呀之Java面试题总结(不断总结中)的主要内容,如果未能解决你的问题,请参考以下文章