1、String.valueof()、(String)、toString()的区别
答案:
(String)进行转换的时候,如果类型不匹配会抛出类型转换异常。因此在转化的时候如果不确定该类型是否为String类型,需要先用instanceof进行类型判断。
toString()是java.lang.Object类里已有的public方法。在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常。toString()不会关注类型的转换,toString()方法返回的是该对象的字符串。
String.valueOf()是String的静态方法,可直接通过String调用。String.valueOf()方法会将非空的对象直接调用其toString方法。但是为空的情况下会返回"null"而不是null。
2、重载(Overload)和重写(Override)
答案:
重载:重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同。
a.通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,也就是多态性。
b.返回值类型可以相同也可以不同。不能以返回值类型作为重载函数的区分标准。
重写:重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数列表和相同的返回类型。
子类可以继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动的继承父类的方法,而是想做一定的修改。重写又称覆盖。
a.子类中不能重写父类中的final方法但是必须重写父类中的abstract方法。
区别:
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。
3、面向对象特征之一---多态性
答案:
存在多态的前提条件:
a.有继承的关系
b.子类重写父类的方法
c.父类的引用指向子类的对象
多态性是面向对象编程的一种特性,和方法无关。分为静态多态性和动态多态性。
同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的重载--有不同的参数列表==>静态多态性。
当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,就要重写父类方法,即在子类中重写该方法--相同参数列表,不同实现==>动态多态性。
4、String、StringBuffer与StringBuilder之间的区别
答案:
运行速度:StringBuilder>StringBuffer>String
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
线程安全:在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。
String适用于少量的字符串操作的情况。
StringBuffer适用于多线程下在字符缓冲区进行大量操作的情况。
StringBuilder适用于单线程下在字符缓冲区进行大量操作的情况。
5、list、set、map的区别
答案:
list、set都是继承自Collection接口,map不是。
list存放元素有序,可重复。set存放元素无序,不可重复
list查找元素效率高,插入和删除元素效率低。set查找元素效率低,插入和删除元素效率高。
6、过滤器(Filter)与拦截器(Interceptor)的区别
使用范围不同:
Filter只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。
规范不同:
Filter是在Servlet规范中定义的,是Servlet容器支持的。而拦截器是在Spring容器中内的,是Spring框架支持的。
使用的资源不同:
同其他的代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源,对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可。而Filter不能。
深度不同:
Filter只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。所以Spring构架的程序中,需要优先使用拦截器。
1、拦截器是基于Javad的反射机制,而过滤器是基于函数回调。
2、拦截器不依赖与Servlet容器,过滤器依赖与Servlet容器。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
5、拦截器可以获取获取IOC容器中的各个bean,而过滤器就不行。
6、拦截器需要在Spring配置文件中配置,过滤器只需要在web.xml中配置。
7、简述单例模式
Java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
单例模式的特点
a.单例类只能有一个实例。
b.单例类必须自己创建自己的唯一实例。
c.单例类必须给所有其他对象提供这一实例。
单例模式的好处
a.控制资源的使用,通过线程同步来控制资源的并发访问。
b.控制实例产生的数量,达到节约资源的目的。
8、HashMap和HashTable的区别
不同点:
a.HashMap是非线程安全的,而HashTable是线程安全的。(HashTable的实现方法里都添加了synchronized关键字来确保线程同步,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法)。因为HashTable是线程安全的,所以效率比HashMap低。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
b.HashMap的键和值都可以为空。HashTable的键和值都不可以为空。
c.HashMap的初始容量为16,HashTable初始容量为11,两者填充因子默认都是0.75.
d.HashMap扩容时当前容量翻倍即:capacity*2,HashTable扩容时是容量翻倍+1即:capactiy*2-1。
e.两者计算hash的方法不同。
相同点:
HashMap和HashTable都实现Map接口。
HashMap和HashTable的底层实现都是数组+链表结构实现。
判断是否含有某个键:
HashMap中的get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值是null。因此,在HashMap中不能用get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。HashTable的键值都不能为null,所以可以用get()方法来判断是否包含某个键。
9、&和&&、|和||的区别
单&时,左边无论真假,右边都进行运算。
双&&时,如果左边为真,右边参与运算。如果左边为假,右边不参与运算。
单|时,左边无论真假,右边都进行运算。
双||时,左边为真,右边不参与运算。
10、位运算符(^,|,&)
按位与、按位或、异或的计算方式都是转换为二进制再计算,不同的是运算规则。
&(按位与)
按位与 运算规则为:两个为真才为真。
例:1&1=1,1&0=0,0&1=0,0&0=0
3 & 5
3的二进制位是0000 0011 , 5的二进制位是0000 0101
011 & 101为001 最终值为0000 0001 故3 & 5等于1
|(按位或)
按位或 运算规则为:一个为真即为真。
例:1|0=1,1|1=1,0|0=0,0|1=1
6 | 2
6的二进制位0000 0110 , 2的二进制位0000 0010
110 | 010为110 最终值为0000 0110 故6 | 2等于6
^(异或)
异或的运算规则为:
例:1^0 = 1 , 1^1 = 0 , 0^1 = 1 , 0^0 = 0
5的二进制位是0000 0101 , 9的二进制位是0000 1001,也就是0101 ^ 1001,结果为1100 , 00001100的十进制位是12
11、Java类的初始化顺序(静态代码块 、构造函数等的执行顺序)
没有继承的情况下:
执行顺序:
1.静态成员变量
2.静态代码块
3.普通成员变量
4.普通代码块
5.构造函数
总结:
1.静态>普通
2.变量>代码块>构造函数
3.构造函数是最后执行的
子类继承父类的情况下:
1.父类的静态成员变量
2.父类的静态代码块
3.子类的静态成员变量
4.子类的静态代码块
5.父类的成员变量
6.父类的代码块
7.父类的构造函数
8.子类的成员变量
9.子类的代码块
10.子类的构造函数
总结:
1.先父类再子类
2.如果子类有静态成员变量和静态代码块,则执行完父类的静态成员变量和静态代码块后,接着执行子类的静态成员变量和静态代码块,否则直接按照父类的变量>代码块>构造函数,再执行子类的变量>代码块>构造函数
3.需要注意的是子类的静态变量和静态代码块是优先于父类的普通成员变量和代码块以及构造函数的。
12、Java中sleep和wait的区别
1、来自不同的类
sleep来自Thread类。wait来自Object类。
sleep是Thread类中的静态方法,谁调用的谁休眠,即使在a线程里调用了b的sleep方法,实际还是a休眠。
2、有没有释放锁(释放资源)
sleep方法没有释放锁,wait方法释放了锁,使其它线程可以使用同步控制快或者方法。
sleep不出让系统资源;wait是进入线程等待持等待,出让系统资源。其它线程可以占用cpu。
sleep可以加时间限制指定它自动唤醒过来。如果时间不到只能用interrupt()强行打断。wait一般不会加时间限制,因为wait线程的运行资源不够,再出来也没用,要等待其它线程调用notify/notifyAll唤醒等待池中所有线程,才会进入就绪队列等待OS分配的系统资源。
就是说sleep有时间限制的就像闹钟一样到时候就叫了,而wait是无限期的,除非用户主动notify
Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
3.使用范围不同
sleep可以在任何地方使用。wait只能在同步控制方法或者同步控制块中使用。
4.是否需要捕获异常
sleep必须捕获异常。wait不需要捕获异常。
13、Java线程的生命周期
14、Java多线程中start()和run()的区别
Java的线程是通过java.lang.Thread类来实现的。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的run()方法来完成其操作的,通过run()方法执行线程体。通过start()方法来启动一个线程。
多线程原理:
调用start()后,线程会被放到等待队列,等待cpu调度,并不一定马上开始执行,只是将这个线程置于可执行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。先调用start后调用run,这么麻烦,为了不直接调用run?就是为了实现多线程的优点,没这个start不行。
多线程就是分时利用CPU,宏观上让所有线程一起执行 ,也叫并发。