当时在网上汇总了不知多少面试和基础题,弄了个精华总结。java
一、一个".java"源文件中是否能够包括多个类(不是内部类)?有什么限制?程序员
能够有多个类,但只能有一个public的类,而且public的类名必须与文件名相一致。面试
二、short s1= 1; s1= s1+1; 有没有错?编程
s1+1运算时会自动提高类型,结果是int,赋值给s1时,将报告须要强转类型的错误。数组
三、short s1= 1; s1 += 1;有没有错?缓存
+=是java规定的运算符,编译器会对它进行特殊处理,所以能够正确编译。markdown
四、使用final关键字修饰一个变量时,引用的内容必定不能变?多线程
使用final修饰变量时,是引用变量(也就是地址)不能变,引用变量所指向的对象中的内容仍是能够改变的并发
五、是否能够从static方法内对非static方法调用?为何?jvm
不能够。由于非static方法是与对象关联的,必须建立一个对象,才能够在该对象上进行方法调用(对象.方法)。而static方法调用时不须要建立对象,能够直接调用。若是从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪一个对象上的呢?这个逻辑没法成立。
六、Overload和Override的区别?
重载Overload表示同一个类中能够有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不一样)。
重写Override表示子类中的方法能够与父类中的方法的名称和参数彻底相同,子类对象调用这个方法时,将调用子类中的定义方法,这就把父类中的方法覆盖了,这也是面向对象编程的多态性的一种表现。
七、Overloaded的方法是否能够改变返回值的类型?
若是几个重载Overloaded的方法的参数列表不同,它们的返回者类型固然也能够不同。
若是两个方法的参数列表彻底同样,无论返回值是否相同,都不容许。由于没法肯定编程者倒底是想调用哪一个方法了,由于他们被调用时看起来彻底相同。
八、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?抽象类中是否能够有静态的main方法?
接口能够继承接口。抽象类能够实现(implements)接口,抽象类能够继承具体类。抽象类中能够有静态的main方法。
记住抽象类与普通类的惟一区别就是不能建立实例对象和容许有abstract方法。
九、Java中实现多态的机制是什么?
靠的是父类(或接口定义)的引用变量能够指向子类(或具体实现类)的实例对象。
而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,而不是引用变量的类型中定义的方法。
十、abstractclass和interface有什么区别?
抽象类能够有构造方法,接口中不能有构造方法。
抽象类中能够有普通成员变量,接口中没有普通成员变量
抽象类中能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的,不能有非抽象的普通方法。
抽象类中的抽象方法类型能够是public,protected,接口中的抽象方法只能是public类型的,而且默认为public abstract。
7. 一个类能够实现多个接口,但只能继承一个抽象类。
十一、String s = "Hello";s = s + "world!";执行后,原始的String对象中的内容变了没有?
没有。由于String被设计成不可变类,因此它的全部对象都是不可变对象。只是s再也不指向旧的对象了。
十二、下面这条语句一共建立了多少个对象:String s="a"+"b"+"c"+"d";
javac编译能够对字符串常量直接相加的表达式进行优化直接得出答案,没必要要等到运行期再去进行加法运算处理
这行代码被编译器在编译时优化后,至关于直接定义了一个”abcd”的字符串,因此,上面的代码应该只建立了一个String对象。
1三、final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示老是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法.
1四、error和exception有什么区别?
error 表示恢复不是不可能但很困难的状况下的一种严重问题。好比说内存溢出。不可能期望程序能处理这样的状况。 exception表示程序还可以克服和恢复的问题
1五、Java 中堆和栈区别?
栈经常使用于保存方法帧和局部变量,而对象老是在堆上分配。
栈一般都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的全部线程共享。
栈:在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的做用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间能够当即被另做它用。
堆:堆内存用来存放由 new 建立的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。
1六、能将 int 强制转换为 byte 类型的变量吗?(引伸到全部大类型转小类型)
实际中,咱们能够作强制转换,不会报错。
可是存在大类型转小类型的通病: int 是 32 位的,而 byte 是 8 位的,若是强制转化,int 类型的高 24 位将会被丢弃,因此尽可能不要这样作。
1七、hashCode有什么用?与 a.equals(b) 有什么关系?
hashCode方法对应对象的 hash 值。它经常使用于基于 hash 的集合类,如 Hashtable、HashMap、LinkedHashMap等等。根 据 Java 规范,两个使用 equal() 方法来判断相等的对象,必须具备相同的 hash code。
1八、垃圾回收的优势和原理。
垃圾回收能够有效的防止内存泄露,有效的使用可使用的内存。垃圾回收器一般是做为一个单独的低级别的线程运行,不可预知的状况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或全部对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
原理:能够给对象添加一个被引用的计数器,就能够判断是否已是无引用对象。可是难以解决循环引用问题。
若是不下当心直接把 Obj1-reference 和 Obj2-reference 置 null。则在 Java 堆当中的两块内存依然保持着互相引用没法回收。
可达性分析法:经过一系列的 ‘GC Roots’ 的对象做为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用。
19,java中会存在内存泄漏吗
内存泄漏:指一个再也不被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它能够保证当对象再也不被引用的时候,对象将自动被垃圾回收器从内存中清除掉。
因为Java使用有向图的方式进行垃圾回收管理,能够消除引用循环的问题,例若有两个对象,相互引用,只要它们和根进程不可达,那么GC也是能够回收它们的。
java中的内存泄露的状况:长生命周期的对象持有短生命周期对象的引用就极可能发生内存泄露.
尽管短生命周期对象已经再也不须要,可是由于长生命周期对象持有它的引用而致使不能被回收,这就是java中内存泄露的发生场景。通俗地说,就是程序员可能建立了一个对象,之后一直再也不使用这个对象,这个对象却一直被引用,即这个对象无用可是却没法被垃圾回收器回收的,这就是java中可能出现内存泄露的状况,例如,缓存系统,咱们加载了一个对象放在缓存中(例如放在一个全局map对象中),而后一直再也不使用它,这个对象一直被缓存引用,但却再也不被使用。
2一、线程和进程有什么区别?
进程是操做系统资源分配的基本单位,而线程是任务调度和执行的基本单位
线程是进程的子集,一个进程能够有不少线程,每条线程并行执行不一样的任务。
不一样的进程使用不一样的内存空间,而全部的线程共享一片相同的内存空间。
2二、如何在Java中实现线程?
继承Thread类
class Handler extends Thread{
public void run(){
//方法重写
}
public static void main(String[] args){
Thread thread = new Handler();//建立线程对象
thread.start();//启动线程
}
}
实现Runnable接口
class Handler implements Runnable{
public void run(){
//方法实现
}
public static void main(String[] args){
Handler handler = new Handler();
Thread thread = new Thread(handler);//建立线程对象
thread.start();//启动线程
}
}2三、Java 关键字volatile 与 synchronized 做用与区别?
复制代码
1,volatile
它所修饰的变量不保留拷贝,直接访问主内存中的。
在Java内存模型中,有main memory,每一个线程也有本身的memory (例如寄存器)。
为了性能,一个线程会在本身的memory中保持要访问的变量的副本。这样就会出现同一个变 量在某个瞬间,在一个线程的memory中的值可能与另一个线程memory中的值,或者main memory中的值不一致的状况。
一个变量声明为volatile,就意味着这个变量是随时会被其余线程修改的,所以不能将它cache在线程memory中。
2,synchronized
当它用来修饰一个方法或者一个代码块的时候,可以保证在同一时刻最多只有一个线程执行该段代码。
1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程获得执行。
2、当一个线程访问object的一个synchronized(this)同步代码块时,另外一个线程仍然能够访问该object中的非synchronized(this)同步代码块。
3、尤为关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其余线程对object中全部synchronized(this)同步代码块的访问将被阻塞。
2四、线程生命周期?
新建一个线程时,它的状态是New。当咱们调用线程的start()方法时,状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间而且将它们的状态改变为Running。其余的线程状态还有Waiting,Blocked 和Dead。
2五、死锁?
指多个进程在运行过程当中因争夺资源而形成的一种僵局,当处于这种状态时,若无外力做用,它们都将没法再向前推动。
缘由可归结为两点:竞争资源、 进程间推动顺序非法
产生死锁的必要条件:
互斥条件:在一段时间内某资源仅为一进程所占用。
请求和保持条件:对已得到的资源保持不放。
不剥夺条件:已得到的资源只能由本身释放。
环路等待条件:存在一个进程--资源的环形链。
2六、什么是线程池? 为何要使用它?
建立线程要花费昂贵的资源和时间,若是任务来了才建立线程那么响应时间会变长,并且一个进程能建立的线程数有限。
线程池实现了线程重复利用,节约了时间和资源。
// Java线程池的完整构造函数
public ThreadPoolExecutor(
int corePoolSize, // 线程池长期维持的线程数,即便线程处于Idle状态,也不会回收。
int maximumPoolSize, // 线程数的上限
long keepAliveTime, TimeUnit unit, // 超过corePoolSize的线程的idle时长,
// 超过这个时间,多余的线程会被回收。
BlockingQueue<Runnable> workQueue, // 任务的排队队列
ThreadFactory threadFactory, // 新线程的产生方式
RejectedExecutionHandler handler) // 拒绝策略
复制代码
2七、反射?
JAVA反射机制是在运行状态中,对于任意一个实体类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2八、JDK 、 JRE 、JVM有什么区别和联系?
JVM : Java 虚拟机。可以将 class 文件中的字节码指令进行识别并调用操做系统向上的 API 完成动做。因此说,jvm 是 Java 可以跨平台的核心。
JRE :Java 运行时环境。包含两个部分,jvm和 Java 的一些基本类库。
JDK :Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。
这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。
2九、深拷贝浅拷贝
数据类型分为两种基础类型和引用类型:
基础类型:像Number、String、Boolean等这种为基本类型
引用类型:Object和Array
浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,修改其中任意的值,另外一个值会随之变化
深拷贝是将对象及值复制过来,两个对象修改其中任意的值另外一个值不会改变。
30、JVM内存分为哪几部分?各个部分的做用是什么?
JVM内存区域分为五个部分,分别是堆,方法区,虚拟机栈,本地方法栈,程序计数器。
1)堆。
堆是Java对象的存储区域,任何用new字段分配的Java对象实例和数组。
2)方法区。
它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,方法区,从JDK1.8永久代被移除。
3)虚拟机栈。
虚拟机栈中执行每一个方法的时候,都会建立一个栈帧用于存储局部变量表,操做数栈,动态连接,方法出口等信息。
4)本地方法栈。
与虚拟机栈发挥的做用类似,相比于虚拟机栈为Java方法服务,本地方法栈为虚拟机使用的Native方法服务,执行每一个本地方法的时候,都会建立一个栈帧用于存储局部变量表,操做数栈,动态连接,方法出口等信息。
5)程序计数器。
指示Java虚拟机下一条须要执行的字节码指令。
总:其中方法区和堆被JVM中多个线程共享,好比类的静态常量就被存放在方法区,供类对象之间共享,虚拟机栈,本地方法栈,pc寄存器是每一个线程独立拥有的,不会与其余线程共享。
3一、为何会出现4.0-3.6=0.40000001这种现象?
2进制的小数没法精确的表达10进制小数,在计算10进制小数的过程当中要先转换为2进制进行计算,这个过程当中出现偏差。
3二、“==”比较的是什么?
“==”两边是对象,比较地址。
“==”两边是基本类型,比较数值。