1.public static void main() 方法中,static 和 public能够换位置,能够final修饰,也能够synchronize修饰。java
final修饰变量时,若是没有static修饰,那么能够在声明时赋值,也能够在构造函数中赋值。。mysql
2.类中的静态代码块比main方法先执行,不管静态代码块在main以前仍是以后。准确来讲,这是由于,静态代码块在类加载时就会执行,而且只执行一次。而main方法是类加载入口,遇到main就会加载类(new也会),这时候会先加载静态代码块(不管在main前仍是后面),而后再去执行main方法中的内容。而非静态代码块就要每次new对象时都会执行。静态代码块只加载一次,若是main时已经执行了,那么new时就不会再执行了。sql
3.初始化的顺序:父类优先于子类,先把父类初始化完了再初始化子类;可是注意静态代码块特殊,由于静态代码块是在类加载阶段,优先于其余部分,因此会先加载父类和子类静态代码块,再加载父类和子类的其余部分。 数据库
(1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
(2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )
(3)
父类非静态代码块( 包括非静态初始化块,非静态属性 )
(4) 父类构造函数
(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
(6) 子类构造函数
4.做用域

5.final关键字
final修饰类:该类不能够被继承,里面属性默认都是final。如String数组
final修饰方法:方法不能够被覆盖。安全
final修饰变量:变量不能够被修改。多线程
final修饰引用类型如数组,则引用(地址)不能够被修改,可是引用的内容能够被修改,数组中的值能够改变。eclipse
6.String类
String类是被final,表示不能够被继承,也不暴露。该类中使用final char[]数组来存字符串。该数组也是final修饰,private修饰的,,因此引用(地址不可变),可是数组中内容能够变,设计人员每次操做数组时,不会去原数组进行操做,而是新建一个数组等于原数组,进行操做,并返回新数组。jvm
由于底层是数组,因此对于一个字符串s="s",数组长度是固定的,s+"a",此时会用新数组操做,返回一个新字符串,并非在原来的数组中操做,因此这里有两个对象,"s"是不变的因此String是不可变的函数
7.三大特性
2)继承:继承是从已有的类中派生出新的类,新的类能吸取已有类的数据属性和行为,并能扩展新的能力。继承避免了对通常类和特殊类之间共同特征进行的重复描述。
3)封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。
4)多态性:多态性是指同一操做做用在不一样对象时,会产生不一样语义,产生不一样结果。多态经过重载(编译时多态)和覆盖(运行时多态)实现。父类引用只能调用父类中存在的方法和属性,不能调用子类的扩展部分;由于父类引用指向的是堆中子类对象继承的父类;
重载经过不一样参数来实现,不能经过返回参数、方法权限以及抛出异常的不一样来实现。
8.float f = 3.4编译不会经过,应该f=3.4f.
9.&是按位与运算,&&是逻辑与
10、heap 和stack 有什么区别?
答:栈是一种线形集合,后进先出;栈中存放的是局部变量表,变量生命周期一旦结束就会被释放。而堆能够看似一棵树,用来存放新建的对象,由垃圾收集器进行回收。
11.抽象类和接口
首先,都不能够被实例化。
下面比较一下二者的语法区别:
1.抽象类能够有构造方法,接口中不能有构造方法。
2.抽象类中能够有普通成员变量,也能够有静态成员变量,可是接口中没有普通成员变量 ,都是 public static final静态成员变量。
3.抽象类中能够包含非抽象的普通方法,接口中的全部方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型能够是public,protected和(默认类型,虽然
eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,而且默认即为public abstract类型。
5. 抽象类中能够包含静态方法(非抽象方法能够是静态),接口中不能包含静态方法
7. 一个类能够实现多个接口,但只能继承一个抽象类。
java 中会存在内存泄漏吗,请简单描述。【基础】
答:会;存在无用但可达的对象,这些对象不能被GC 回收,致使耗费内存资源。
没法分配内存(内存不够),就是内存溢出
error 和exception 有什么区别? 【基础】都继承Throwable
答:error 表示系统级的错误和程序没必要处理的异常,是恢复不是不可能但很困难的状况下的一种严重问题;好比内存溢出,不可能期望程序能处理这样的状况;exception 表示须要捕捉或者须要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示若是程序运行正常,从不会发生的状况。
运行时异常默认状况下会自动进行处理,不须要捕捉,能够选择抛出,不用声明;
受检查异常表示程序能够处理的异常,须要捕捉,或者抛出并声明。
常见的运行时异常:
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操做数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
try-finally
在try-finally中,当try中返回一个变量,如return a.可是finally中对a作了修改(finally中没有return a),此时try中仍是返回没有修改的a,由于return以前会将return的内容保存在临时栈中,再去执行finally内容,执行完finally内容再return。不过当finally中有return语句,就会覆盖原来的return
一、无论有木有出现异常,finally块中代码都会执行;
二、当try和catch中有return时,finally仍然会执行;
三、finally是在return后面的表达式运算后执行的(此时并无返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是以前保存的值),因此函数返回值是在finally执行前肯定的,可是finally也是在return以前执行;
四、finally中最好不要包含return,不然程序会提早退出,返回值不是try或catch中保存的返回值。finally中有return,会覆盖前面的return
五、catch中有System.exit(0)。表示将整个虚拟机里的内容都释放,JVM中止工做,此时程序正常退出,也就不会再执行finally了
ThreadLocal
ThreadLocal为变量在每一个线程中都建立了一个副本,那么每一个线程能够访问本身内部的副本变量。
ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免经过参数来传递
线程的角度看,每一个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的而且 ThreadLocal 实例是可访问的;在线程消失以后,其线程局部实例的全部副本都会被垃圾回收
在Thread类中有一个Map,用于存储每个线程的变量的副本。
对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式
Arrays.sort和Collections.sort使用的排序
Arrays.sort总结: lenthth<47 插入排序
47<length<286 双轴快速排序 (两个枢纽,将数组分红三部分,对着三部分递归)。
length>286 且连续性(升序或者降序)很差 双轴快速排序
length>286 且连续性好 归并排序
Collections.sort调用了Arrays.sort。
非抽象类实现接口
两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
synchronized与Lock的区别
二者区别:
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java接口;
2.synchronized,会自动释放线程占有的锁,在发生异常时,所以不会致使死锁现象发生;而Lock在发生异常时,若是没有主动经过unLock()去释放锁,则极可能形成死锁现象,所以使用Lock时须要在finally块中释放锁;
3.经过Lock能够知道有没有成功获取锁,而synchronized却没法办到
4.用synchronized关键字的两个线程1和线程2,若是当前线程1得到锁,线程2线程等待。若是线程1阻塞,线程2则会一直等待下去,而Lock锁就不必定会等待下去,若是尝试获取不到锁,线程能够不用一直等待就结束了;
6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少许的同步问题。
克隆函数
从一个对象克隆一个对象,则对克隆对象的修改不会影响到原对象。
使用clone()的步骤:
1.实现Cloneable接口;这是一个标识接口,没有任何方法
2.重写Object中的clone()方法;
3.调用super.clone完成浅拷贝。本身操做,完成深拷贝
浅拷贝:只考虑基本成员变量,不会复制对象中引用的其余对象(包括数组),
深拷贝:把引用的其余对象也从新拷贝一份。

反射
主要做用就是在运行时动态的建立类对象。
建立class类:class.forName() 类名.class 实例.getClass()
建立对象的方式
new 反射 clone 反序列化
子类中获取父类的类名
获取本类类名:this.getClass().getName();
注意,super.getClass().getName()不能获得父类的类名,而是获得本类的类名。getClass()是Object的方法,表示返回Object运行时类,也就是返回子类。
获取父类:this.getClass().getSuperClass().getName();
右移
>>有符号右移,对于正数,高位补0,负数高位补1.。>>>无符号右移,对于负数,高位补0;
==和equals
==比较基本数据类型是比较值,比较对象时比较对象的地址(引用);
equals是Object方法,默认使用==进行比较,也就是和==效果同样。可是通常类都会覆盖equals方法,比较具体对象的内容。
泛型
在没有泛型以前,一旦吧一个对象“丢进”java集合中,集合就会忘记对象的类型,把全部的对象都当成是Object类型处理。当程序从集合中取出对象以后,就要进行强制类型转换,这种强制类型转换不只代码臃肿还容易引发ClassCastException异常。
在JDK1.5以后,Java引用了“参数化类型(parameterized type)”的概念,容许咱们在建立集合时指定集合元素的类型。如List<String>,这代表该List只能保存字符串类型的对象。Java的参数化类型被称为泛型(Generic)
所谓泛型:就是容许定义类、接口时指定类型形参,这个类型形参将在声明变量,建立对象时肯定(即传入实际的类型参数,也可称为类型实参)。
避免死锁的几种方式: