最近辞职准备面试,顺便整理一下面试题分享给你们,若有错误欢迎指出java
01. 你对面向对象思想的理解?程序员
面向对象编程简称OOP,是开发程序的一种方法、思想。
面向过程编程中经常会致使全部的代码都在一块儿,难以阅读和维护,牵一动百。而OOP,使用许多代码模块,每一个模块都只提供特定的功能,彼此独立,能够增长代码重用概率,更加有利于软件的开发、维护和升级。
另外OOP的三大核心特性:继承、封装、多态 的特性,使得程序员可以设计出高内聚、低耦合的系统结构,使得系统更灵活、易扩展,成本较低面试
02. 不少程序员都知道多态,但大都知其然不知其因此然,说说你对多态的理解
一个引用变量倒底会指向哪一个类的实例对象,该引用变量发出的方法调用究竟是哪一个类中实现的方法,在编程时并不肯定,而是在程序运行期间才肯定。
由于在程序运行时才肯定具体的类,即不修改程序代码就能够改变程序运行时所绑定的具体代码,让程序能够选择多个运行状态,这就是多态性
多态的优势:解耦、灵活、可扩展性强算法
多态存在的三个必要条件:继承、重写、父类引用指向子类对象sql
03. Collection集合有什么子类
List
1.能够容许重复的对象。
2.能够插入多个null元素。
3.有序,保持元素的插入顺序
4.经常使用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于常常须要从 List 中添加或删除元素的场合更为合适。数据库
Set
1.不容许重复对象
2.无序
3.只容许一个 null 元素
4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口。编程
Map
1.Map不是collection的子接口或者实现类。Map是一个接口。
2.Map 可能会持有相同的值对象但键对象必须是惟一的。
3.TreeMap 也经过 Comparator 或者 Comparable 维护了一个排序顺序。
4.Map 里你能够拥有随意个 null 值但最多只能有一个 null 键。
Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最经常使用)vim
04. list,set,map的使用场景
1.若是你常常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。若是你已经知道索引了的话,那么 List 的实现类好比 ArrayList 能够提供更快速的访问,若是常常添加删除元素的,那么确定要选择LinkedList。
2.若是你想容器中的元素可以按照它们插入的次序进行有序存储,那么仍是 List,由于 List 是一个有序容器,它按照插入顺序进行存储。
3.若是你想保证插入元素的惟一性,也就是你不想有重复值的出现,那么能够选择一个 Set 的实现类,好比 HashSet、LinkedHashSet 或者 TreeSet。
4.若是你以键和值的形式进行数据存储那么 Map 是你正确的选择。你能够根据你的后续须要从 Hashtable、HashMap、TreeMap 中进行选择。数组
05. ArrayList和HashMap的比较
使用场景:若是须要快速随机访问元素,应该使用ArrayList。须要键值对形式的数据时,应该使用HashMap浏览器
相同点:
1)都是线程不安全,不一样步 2)均可以储存null值 3)获取元素个数方法同样,都用size()方法获取
区别:
1)实现的接口 ArrayList实现了List接口(Collection(接口)->List(接口)->ArrayList(类)),底层使用的是数组;而HashMap现了Map接口(Map(接口)->HashMap(类)),底层使用的是Hash算法存储数据。 2)存储元素 ArrayList以数组的方式存储数据,里面的元素是有顺序,能够重复的;而HashMap将数据以键值对的方式存储,键的哈希码(hashCode)不能够相同,相同后面的值会将前面的值覆盖,值能够重复,里面的元素无序。 3)添加元素的方法 ArrayList用add(Object object)方法添加元素,而HashMap用put(Object key, Object value)添加元素。 4)默认的大小和扩容 在 Java 7 中,ArrayList的默认大小是 10 个元素,HashMap 的默认大小是16个元素(必须是2的幂)。
06. 多线程建立方式有哪几种(具体建立过程是什么)
1.继承thread 类,重写run方法,而后new Thread().start启动线程,也能够直接匿名内部类的方式建立
new Thread(
public void run(){ };
).start;
在里边写run方法的实现
2.实现runnable接口,重写run方法
3.实现callable接口(通常不多用)
07. 多线程的常见应用场景:
一、后台定时任务,例如:定时向大量(100w以上)的用户发送邮件;
二、异步处理,例如:发微博、记录日志等;
三、分布式计算消息队列
08. 线程有哪几种状态
1.建立状态 刚被new Thread()
2.就绪状态 准备好了run方法,等待cpu
3.运行状态 running
4.阻塞状态(包括sleep、wait(notify)、suspend(resume)、以及没抢到锁)
5.死亡状态
09. 线程池初始化时有哪些参数能够设置
通常tomcat线程池不用本身配,本身写线程池的话是须要本身配置参数的
那 线程初始化时设置参数的格式是:
private static final int corePoolSize = xxx;
建立线程池对象时,将配置的各类参数用逗号链接传参进去。
ThreadPoolExecutor mExecute = new ThreadPoolExecutor(
corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, rejectHandler
);
各个参数表明的意义:
corePoolSize:线程池的核心线程数。在没有设置 allowCoreThreadTimeOut 为 true 的状况下,核心线程会在线程池中一直存活,即便处于闲置状态。 maximumPoolSize:线程池所能容纳的最大线程数。大于这个数调用任务拒绝handler keepAliveTime:非核心线程闲置时的超时时长。超过该时长,非核心线程就会被回收。 unit:keepAliveTime 时长对应的单位。 workQueue:线程池中的任务队列,当有提交的任务暂时没有足够的线程去执行的时候,就会进入workQueue等待 rejectHandler:拒绝策略,当线程池中线程数大于maximumPoolSize,且任务队列也排满了,如何拒绝任务。 JDK给咱们内置了四种拒绝策略:直接抛出异常、丢弃最老的一个任务而后从新提交当前任务、放弃没法执行的任务,而后当作无事发生、还有一种没看懂就不写出来了
10. 线程池的种类(4种)区别和使用场景
首先,不一样线程池之间的区别就是他们新建时传入的参数值不同(新建方法是同样的)
1.newFixedThreadPool,线程数量固定的线程池,线程池的corePoolSize和maximumPoolSize大小同样,而且keepAliveTime为0,传入的队列LinkedBlockingQueue为无界队列
2.newSingleThreadExecutor,单线程池,corePoolSize和maximumPoolSize都是1,keepAliveTime是0
3.newCachedThreadPool,可缓存线程池,说到缓存通常离不开过时时间,该线程池也是,corePoolSize设置为0,maximumPoolSize设置为int最大值,不一样的是,线程池传入的队列是SynchronousQueue,一个同步队列,该队列没有任何容量,每次插入新数据,必须等待消费完成。当有新任务到达时,线程池没有线程则建立线程处理,处理完成后该线程缓存60秒,过时后回收,线程过时前有新任务到达时,则使用缓存的线程来处理。
4.newScheduledThreadPool,这个线程池使用了ScheduledThreadPoolExecutor,该线程池继承自ThreadPoolExecutor, 执行任务的时候能够指定延迟多少时间执行,或者周期性执行。
11. ==和equals有什么区别?
对基本数据类型 ==比较的是值,引用类型 ==比较的是地址 equals比较的大可能是地址,可是String和Integer对其进行了重写,因此比较的是值
12. Thread类中的start()和run()方法有什么区别
start启动线程,run方法只是thread的一个普通方法,就算调用了也仍是在主线程里执行
同步有几种实现方法?
同步的实现方面有两种,使用synchronized同步锁、volatile关键字、lock锁对象的lock()和unlock()方法
volatile关键字
Java 语言中的 volatile 变量能够被看做是一种 “程度较轻的 synchronized”
锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。
互斥指一个线程拿到了锁,其余线程就必须等待完成。
可见性要表示一个线程改完了一个公共数据(其实是先改本身的缓存数据,而后同步到公共数据上,而后另外的线程看到公共数据变了,将变换的值同步到本身的缓存,这个过程有好几部,因此会有线程安全问题),必需要保证其余线程知道数据改变了
使用 volatile 变量的主要缘由用法简单,在公共数据上加一个volatile关键字就行,其次是性能优于sychronize同步锁
线程产生死锁的缘由和解决办法:
什么是死锁:打个比方,假设有P1和P2两个进程,都须要A和B两个资源,如今P1持有A等待B资源,而P2持有B等待A资源,两个都等待另外一个资源而不愿释放资源,就这样无限等待中,这就造成死锁
定义:若是一组进程中每个进程都在等待仅由该组进程中的其余进程才能引起的事件,那么该组进程是死锁的。
产生死锁缘由:一种缘由是系统提供的资源太少了,远不能知足并发进程对资源的需求。这种竞争资源引发的死锁是咱们要讨论的核心;
另外一种缘由是因为进程推动顺序不合适引起的死锁。资源少也未必必定产生死锁。就如同两我的过独木桥,若是两我的都要先过,在独木桥上僵持不愿后退,必然会应竞争资源产生死锁;可是,若是两我的上桥前先看一看有无对方的人在桥上,当无对方的人在桥上时本身才上桥,那麽问题就解决了。因此,若是程序设计得不合理,形成进程推动的顺序不当,也会出现死锁。
解决死锁问题的三种方法:预防死锁、检测死锁及避免死锁。
解决办法:预防死锁的发生每每须要很大的系统开销,并且不能充分利用资源,为此,一种简便的方法是系统为进程分配资源时,不采起任何限制性措施,可是提供了检测和解脱死锁的手段
核心思想:打破线程间的相互等待状态,好比
1.找到相互等待的线程的spid,kill掉
2.使用sql server 内部的锁监视器线程执行死锁检查,当检测到死锁时,回滚事务以及该事务持有的锁,使得其余线程得以正常运行
多线程有几种实现方法?
多线程有三种实现方法,分别是继承Thread类、实现Runnable接口、实现Callable接口
Callable和Runnable的区别是什么
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法能够抛出异常,run方法不能够
(4)运行Callable任务能够拿到一个Future对象,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,若是线程没有执行完,Future.get()方法可能会阻塞当前线程的执行;若是线程出现异常,Future.get()会throws InterruptedException或者ExecutionException;若是线程已经取消,会跑出CancellationException。取消由cancel 方法来执行。isDone肯定任务是正常完成仍是被取消了。一旦计算完成,就不能再取消计算。若是为了可取消性而使用 Future 但又不提供可用的结果,则能够声明Future<?> 形式类型、并返回 null 做为底层任务的结果。
IO流,了解常见的几个流对象以及基本的流操做便可
数组集合
什么是链接池,为何使用链接池
什么是接口隔离?
接口跟抽象类的区别?
hashcode和equal的区别
hashmap和hashtable的区别是什么?
hashmap实现原理,扩容因子过大太小的缺点,扩容过程
ArrayList和linkenList的区别?
java地址和值传递的例子
值传递:只传递值,各是各的
引用传递:传递地址,共同操做这个值
Linux经常使用命令列举10个
ls/ll 显示文件夹下全部文件/详细显示
pwd 查看当前目录的绝对路径
cd 切换目录
ps 查看进程
kill 杀死进程
mv 移动文件
mkdir 建立文件夹
rmdir 删除文件夹
touch 建立文件
tar zxvf 解压
date 显示日期
cal 显示日历
vi 用vim编辑文件
clear 清屏
synchronized实现原理
synchronizated和lock差异?
java Nio
是否能够继承String类?
String类是final类故不能够继承。
几种线程暂停
a. wait():使一个线程处于等待状态,而且释放持有的锁
b. sleep():使一个正在运行的线程处于睡眠状态,时间过了自动会醒,因此不释放锁
c. notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确
切的唤醒某一个等待状态的线程,而是由JVM肯定唤醒哪一个线程,并且不是按优先级。
d. allnotity():唤醒全部处入等待状态的线程,注意并非给全部唤醒线程一个对象的锁,而是让它们竞争。
启动一个线程是用run()仍是start()?
启动一个线程是调用start()方法,使线程就绪状态,之后能够被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
SOCKET套接字中有几中链接方式,各有什么区别?
Sockets有两种主要的操做方式:面向链接(TCP/IP)的和无链接(UDP)的。无链接的操做使用数据报协议,无链接的操做是快速的和高效的,可是数据安全性不佳. 面向链接的操做使用TCP协议.面向链接的操做比无链接的操做效率更低,可是数据的安全性更高
sleep()和wait()区别
sleep() 方法:线程主动放弃CPU,使得线程在指定的时间内进入阻塞状态,不能获得CPU 时间,指定的时间一过,线程从新进入可执行状态。典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不知足后,让线程阻塞一段时间后从新测试,直到条件知足为止。
wait( ) :与notify()配套使用,wait()使得线程进入阻塞状态,它有两种形式,一种容许指定以毫秒为单位的一段时间做为参数,另外一种没有参数,当指定时间参数时对应的 notify() 被调用或者超出指定时间时线程从新进入可执行状态,后者则必须对应的 notify() 被调用
hashCode方法的做用?
hashcode这个方法是用来鉴定2个对象是否相等的。hashcode方法通常用户不会去调用,好比在hashmap中,因为key是不能够重复的,他在判断key是否是重复的时候就判断了hashcode这个方法,并且也用到了equals方法。这里不能够重复是说equals和hashcode只要有一个不等就能够了!因此简单来说,hashcode至关因而一个对象的编码。咱们通常在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。
简述synchronized和java.util.concurrent.locks.Lock的异同 ?
主要相同点:Lock能完成synchronized所实现的全部功能
主要不一样点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock必定要求程序员手工释放,而且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法能够非阻塞方式去拿锁。
Java字节码的执行有两种方式:
1)即时编译方式:解释器先将字节编译成机器码,而后再执行该机器码。 2)解释执行方式:解释器经过每次解释并执行一小段代码来完成java字节 码程序的全部操做。
Java四种引用包括强引用,软引用,弱引用,虚引用
2.获取Class的方式有哪些
方式一:对象.getClass()
Student student = new Student();
student.getClass();
方式二:类名.Class
Student.Class
方式三:Class.forname("完整的类路径.包名.类名")
3.int和Integer的区别
基础答案:Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。
进阶答案:Ingeter将-128-127进行缓存,所以
4.ArrayList和LinkedList的区别
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList以为优于LinkedList,由于LinkedList要移动指针。
3.对于新增和删除操做add和remove,LinedList比较占优点,由于ArrayList要移动数据。
5.==和equals的区别
1)对于==,比较的是值是否相等
若是做用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
若是做用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能做用于基本数据类型的变量
若是没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
6.override和overload的比较
重载Overload:在同一个类中,容许存在一个以上的同名函数,只要他们的参数个数或者参数类型不一样便可。
重载的特色:与返回值类型无关,只看参数列表。
重写Override表示子类中的方法能够与父类中的某个方法的名称和参数彻底相同,经过子类建立的实例对象调用这个方法时,将调用子类中定义的方法,这至关于把父类中定义的那个彻底相同的方法给覆盖掉了,这也是面向对象编程的多态的一种表现。子类覆盖父类方法时只能抛出父类的异常或者异常的子类或者父类异常的子集,由于子类能够解决父类的一些问题,但不能比父类有更多的问题。还有,子类方法的访问权限只能比父类的更大,不能更小。若是父类的方法是private类型,则子类中根本不存在覆盖,即子类中和父类的private的同名的方法没有覆盖的关系,由于private的访问权限只限于同一类中,而子类就不会访问到private的方法,因此是子类中增长的一个全新的方法
7.简述servlet生命周期
(1)加载和实例化
当Servlet容器启动或客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet实例,若存在,则直接读取该实例响应请求;若是不存在,就建立一个Servlet实例。
(2) 初始化
实例化后,Servlet容器将调用Servlet的init()方法进行初始化(一些准备工做或资源预加载工做)。
(3)服务
初始化后,Servlet处于能响应请求的就绪状态。当接收到客户端请求时,调用service()的方法处理客户端请求,HttpServlet的service()方法会根据不一样的请求 转调不一样的doXxx()方法。
(4)销毁
当Servlet容器关闭时,Servlet实例也随时销毁。其间,Servlet容器会调用Servlet 的destroy()方法去判断该Servlet是否应当被释放(或回收资源)。
9.farward和redirect区别
转发(Forward),是一次请求,只有一个request,所以request域内的数据能够共享。
重定向(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另一个URL发出请求,从而达到转发的目的。
10.final finally finalize区别
Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。
11.乐观锁与悲观锁
悲观锁
老是假设最坏的状况,每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁 。传统的关系型数据库里边就用到了不少这种锁机制,好比行锁,表锁等,读锁,写锁等,都是在作操做以前先上锁。Java中synchronized 等独占锁就是悲观锁思想的实现。
乐观锁
老是假设最好的状况,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样能够提升吞吐量,像数据库提供的相似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。
两种锁的使用场景
冲突真的不多发生的时候,用乐观锁就比较合适。
常常产生冲突,用悲观锁就比较合适。
12.String、StringBuffer和StringBuilder的区别
在线程安全:StringBuilder是线程不安全的,而StringBuffer是线程安全的
运行速度:StringBuilder > StringBuffer > String
13.char能够存储汉字吗为何
char是按照字符存储的,无论英文仍是中文 占用占用2个字节,用来储存Unicode字符 unicode编码字符集中包含了汉字,因此,char型变量中固然能够存储汉字啦。
15.简述HashMap的实现原理
重写HashMap须要重写hashCode()和equals()方法
16.HashMap和HashTable的区别
线程不安全和线程不安全
键值可为null键值不可为null
前者快后者慢
咱们可否让HashMap同步?
HashMap能够经过下面的语句进行同步:
Map m = Collections.synchronizeMap(hashMap);
18.a=a+b与a+=b的区别
举例:a为int,b为float 则a = a + b 须要强制类型转换,也就是咱们常写的 a = (int) (a+b);
而咱们的a += b 被咱们的编译器在编译期作了一些小手脚。也就是编译器帮咱们进行了强制类型转化。
& 和 &&的区别
&和&&均可以用做逻辑与的运算符
&&还具备短路的功能
&还能够用做位运算符
深拷贝和浅拷贝的区别
打个不太恰当的比喻:一个是复制一份新的 一个是弄了一个快捷方式
Java的八大基本数据类型是什么
byte short int long float double boolean char
进程、线程和协程的区别
1) 一个线程能够多个协程,一个进程也能够单独拥有多个协程
2) 线程进程都是同步机制,而协程则是异步
3) 协程能保留上一次调用时的状态,每次过程重入时,就至关于进入上一次调用的状态
建立两种线程的方式 他们有什么区别
1.继承Thread类
2.实现Runnable接口
守护线程:守护线程则是用来服务用户线程的,若是没有其余用户线程在运行,那么就没有可服务对象,守护线程就会退出。
Array(数组)和ArrayList(列表)有什么区别
1)精辟阐述:
能够将 ArrayList想象成一种“会自动扩增容量的Array”。
2)Array([]):数组,最高效;可是其容量固定且没法动态改变;
ArrayList: 动态数组,容量可动态增加;但牺牲效率;
Runnable和Callable的区别
编写多线程程序通常有三种方法,Thread,Runnable,Callable.
Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法能够抛出异常,run方法不能够
(4)Runnable是自从java1.1就有了,而Callable是1.5以后才加上去的
wait(),notify()和suspend(),resume()之间的区别
wait(),notify()有两种形式一种是传入一个时间参数,自动恢复,一种是不传参,不会自动恢复,必须使用notify()方法
suspend(),resume():suspend()方法很容易引发死锁问题,已经不推荐使用了。
default,public,private,protected区别
tomcat调优
声明式事务
接口隔离
代码块、静态代码块执行顺序
Java子父类间静态代码块、非静态代码块、构造方法的执行顺序
子类A继承父类B,A a=new A();
正确的执行顺序是:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
也就是说非静态初始化块的执行顺序要在构造函数以前。
如何捕获子线程异常线程设计的理念:“线程的问题应该线程本身自己来解决,而不要委托到外部。”