1.Integer和int的区别
1)int是java提供的8中原始数据类型之一,java为每个呀un是数据类型提供了封装类,Integer是java为int提供的封装类(封装类=数据+操作)。
2)int的默认值为0,而Integer的默认值为null,即Integer可以区分出为赋值和值为0的区别,int无法表达出为赋值的情况。例如:想要表达出没有参加考试和考试成绩为0的区别,只能使用Integer。在JSP中Integer的默认值为null,所以用EL表达式在文本框中显示时,值为空表字符串,而int默认值为0,所以用EL表达式在文本框中显示时,结果为0,所以,int不适合作为WEB层的表单数据的类型。
3)Integer提供了一系列与int相关的操作方法。
2.Math.round、Math.float、Math.ceil
Math类提供了三个与取整有关的方法:ceil、floor、round。
ceil:向上取整。如:Math.ceil(11.5),结果为:12;Math.ceil(-11.5),结果为:-11。
floor:向下取整。如:Math.floor(11.5),结果为:11;Math.floor(-11.5),结果为:-12。
round:“四舍五入”,算法为Math.floor(x+0.5)。Math.round(11.5),结果为:12;Math.round(-11.5),结果为:-11。
3.“==”和equals方法的区别
1)“==”操作符是用来比较连个变量的值是否相等,也就是用来比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
2)equals方法是用来比较两个独立对象的内容是否相等。
3)如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
public boolean equals(Object obj) {
return (this == obj);3
}
从代码中可以得出以下结论:如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一个对象,这时候使用equals方法和使用==操作符会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相等,那么你必须覆盖equals方法,由你编写的代码来决定在什么情况即可认为两个对象的内容是相同的。
4.switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。
5.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。
例如,对于如下语句:final StringBuffer a=new StringBuffer("immutable");执行如下语句将报告编译期错误:a=new StringBuffer("");但是,执行如下语句则可以通过编译:a.append("broken!");有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:public void method(final StringBuffer param){}实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:param.append("a");
public class Test {
public static void main(String[] args) {
final StringBuffer a=new StringBuffer("Hello");
//a=new StringBuffer("hello");//编译错误
a.append(",world");
System.out.println(a.toString());//Hello,world
}
}
6.&与&&的区别
1)&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
2)&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str!=null&&!str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33&++y>0)y会增长,If(x==33&&++y>0)不会增长
3)&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31&0x0f的结果为0x01。
7.在JAVA中如何跳出当前的多重嵌套循环?
1)在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break语句,即可跳出外层循环。例如:
label:
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
System.out.println("i="+i+",j="+j);
if(j==5)
break label;
}
}
2)我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。
public class Test {
public static void main(String[] args) {
int arr[][]={{1,2,3},{4,5,6,7},{9}};
boolean found=false;
for(int i=0;i<arr.length&&!found;i++){
for(int j=0;j<arr[i].length;j++){
System.out.println("i="+i+",j="+j);
if(arr[i][j]==5){
found=true;
break;
}
}
}
}
}
8.abstract class和interface的区别
接口中所有的方法必须都是抽象的,接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
语法上的区别:
1、抽象类可以有构造方法,接口中不能有构造方法。
2、抽象类中可以有普通成员变量,接口中没有普通成员变量。
3、抽象类中可以包含非抽象的普通方法,接口中的所有方法都必须是抽象的,不能有非抽象的普通方法。
4、抽象类中的抽象方法的访问类型可以使public、protected,但接口中的所有抽象方法只能是public类型的,并且默认即为public abstract类型。
5、抽象类中可以包含静态方法,接口中不能包含静态方法。
6、抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以使任意的,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7、一个类可以实现多个接口,但只能继承一个抽象类。
9.面向对象的特征
面向对象编程语言有封装、继承、抽象、多态4个主要的特征。
1)封装:封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖而带来的变动影响。在面向对象的编程语言中,对象是封装的基本单位。面向对象的封装就是把描述一个对象的属性和行为的代码封装到一个“模块”中,即一个类中。只要把变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义为私有的,只有这个类的方法可以访问,这就基本上实现了对象的封装。
2)抽象:抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的哪些部分,将注意力集中在与当前目标有关的方面。
3)继承:继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的重用性和可扩展性。
4)多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行时才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在程序运行期间才能决定。因为在程序运行时才能确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,、重载Overloading是一个类中多态性的一种表现。
10.finally,final,finalize
finally: 释放资源(内存之外的,打开的文件、连接、屏幕上的图形,,)
①总会执行②非后台线程结束,后台线程被强关,不会执行finally
③当try和catch中有return时,finally在return之后执行,但是返回值不会改变(finally中不会改变已保存的返回结果)
④finally中最好不要包含return,否则程序会从finally中退出,返回值不是try或catch中保存的返回值。
final:基本数据类型:不可更改 类:不可继承 对象:引用不可变,对象内容可变
finalze:回收前调用,不适合用来清理或释放资源。对象免死最后机会!保证会被调用,但不保证会执行完(在低优先级线程中执行)
11. Hashtable、HashMap
Hashtable 与 HashMap类似,但是主要有7点不同。
1.HashTable的方法是同步的,HashMap未经同步,如Vector和ArrayList一样。
2.HashTable不允许null,key和value都不可以,HashMap允许null值,key和value都可以。HashMap允许 key值只能由一个null
3.HashTable有一个contains(Object value)功能和containsValue(Object value)功能一样。
4.遍历的时候,HashTable使用Enumeration,HashMap使用Iterator。
5.HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
6.哈希值的使用不同,HashTable直接使用对象的hashCode。
Hashtable继承自Dictionary类,实现了Map接口。而HashMap是继承自AbstractMap,实现了Map接口。
HashMap: 一个数组,hash(h)决定位置,
冲突使用链表法:单向--Entry对象(保存final key,value,next指针,hash值),遍历比较hash值
Collections.synchronizedMap(hashmap)来构造一个线程安全的map,与Hashtable几乎一样
扩容:先插入再判断是否扩容
Hashtable: 直接使用对象hash值,对跟线程安全相关的方法和步骤加Syncrolized
LinkedHashMap: 继承HashMap, 重写Entry类,before,after两个指针,保存插入顺序或者访问顺序(可指定)
HashSet:持有一个HashMap
ConcurrentHashMap: 两个数组Segment[] 和HashEntry[]
Segment:extends ReentrantLock, 一种可重入锁,持有一个数组HashEntry[],可以通过concurrencylevel指定Segment数组长度
HashEntry:hash,key,value,next
读不需要锁,读到空时加锁重读
扩容:支队某个Segment的HashEntry[]扩容,先判断是否扩容再插入
size():先尝试两次锁,判断modCount是否变化再决定是否加锁
CopyOnWriteArrayList: 适合多读少写,只保证最终一致性,不保证实时一致性
加锁-->拷贝数据-->改、写-->赋值回去-->解锁
用的ReentrantLock,读无需锁,可能读到旧数据
TreeMap:红黑树,可自定义顺序
TessSet:TreeMap
12.GET,POST区别?
答: 基础知识:Http的请求格式如下。
<request line> 主要包含三个信息:1、请求的类型(GET或POST),2、要访问的资源(如\res\img\a.jif),3、Http版本(http/1.1)
<header> 用来说明服务器要使用的附加信息
<blank line> 这是Http的规定,必须空一行
[<request-body>] 请求的内容数据
区别:
1、Get是从服务器端获取数据,Post则是向服务器端发送数据。
2、在客户端,Get方式通过URL提交数据,在URL地址栏可以看到请求消息,该消息被编码过;Post数据则是放在Html header内提交。
3、对于Get方式,服务器端用Request.QueryString获取变量的值;对用Post方式,服务器端用Request.Form获取提交的数据值。
4、Get方式提交的数据最多1024字节,而Post则没有限制。
5、Get方式提交的参数及参数值会在地址栏显示,不安全,而Post不会,比较安全。
13.session和cookie的区别
session放在服务器,cookie放在客户端
session不区分路径,在同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到。而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。也就是说,同一个用户的cookie,他换了浏览器,就访问不到之前的那个不同牌子的浏览器的cookie了。session中保存的是对象,cookie中保存的是字符串。
由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择【经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段】。
14.数组和链表,遍历效率哪个高,为什么(cpu缓存与内存)
数组的效率高,因为数组是连续存储的,即内存地址是连续的,所以在读取数组时,会将连续的内存地址的数据放入缓存中,所以读取数组时相当于是从缓存读取。而链表遍历都是从内存读取,缓存的读取速度要比内存块 100 倍左右。
15.string类能否继承?如果写一个类不能被继承 final外还有什么方法
不能,因为是final的。还可以把构造函数私有化,单例模式
16.Java中为什么要序列化?什么时候序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。 序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
对象序列化到底有什么好处?
数据操作规范类似于还是等于XML文件?- -保证数据一致性和安全性
为什么要对对象进行序列化?为什么不直接用数据库来存储数据?- -采用数据流来存储 ,以数据流传输会提高网络传输速度,在数据流进行操作可以直接操作数据流,少了对数据表进行操作的过程,减少数据出错的几率.
在具体的编程应用中那些地方会用的上?--分布式计算,网络数据存取
对象持久化,transient:修饰变量,不序列化
17.单例模式线程安全
1. 静态变量new 对象,类加载时即生成,
2. 加锁:双重检测加锁 不能达到真正的线程安全,1.5之前主要是JIT编译器执行顺序问题.1.6之后可能是指令重排(volatile可解决?)
3. 使用私有的静态类来实现:
public class Singleton {
private static class SingletonHolder{//私有静态类
public final static Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
4. 枚举单例