今天看了一下关于java的一些挺经典、全面的面试题 所以今晚总结了一下 和 大家多交流交流.
1.java中九种基本数据类型的大小及他们的封装类.
其中包括六种数字类型(四个整数型,两个浮点型),一种布尔型,一个是void
整型:short,int,long,byte
16 32 64 8
浮点型:float,double
32 64
字符型:char
16(unicode)
布尔型:boolean
1
void
解释:java中有两种数据类型,一种是基本数据类型 一种是引用型数据类型 在Java的圣经Thinking in java中把void也列为基本数据类型,里面认为两种个数据类型的区别在于,基本数据类型是在堆栈中分配空间存“值”,而引用数据类型是在堆中分配空间存“值”,但是void他不能通过new来实例化出来,只能在堆栈中分配空间存储,所以认为void是一种基本数据类型.
建议:在面试中 大家可以先说有8中基本数据类型,然后再说有些书 如thinking in java也把void归为基本数据类型中的一种 故为九种.
疑问:这么说的话,那任何不能实例化 但在堆栈中存储的都算基本数据类型吗?
2.Switch能否用string做参数?
可以 凡是可以自动转换为整型数据类型的数据类型都可以作为switch的参数.如:byte short int string 但是 float long double boolean不能自动转换为int的就不能作为其参数.
比如:
public class Main {
public static void main(String[] args) {
String s="abc";
switch(s){
case("abc"):
System.out.println("i love xingxing");
break;
case("123"):
System.out.println("i love jiming");
break;
default:
break;
}
}
}
3.== 与 equals的区别:
首先==是基本数值的比较(原生类型和对象),如比较int , boolean等的值比较,但是也可以用来比较两个对象,但是是比较的两个对象在堆栈中的引用,而不是比较的两个对象在堆中的具体值;再者,如果大家去查看equals的源码就不难发现
public boolean equals(Object obj) {
return (this == obj);
}
其实equals的内部实现也是用==来进行两个对象比较的,所以java其实是希望开发人员结合自己的业务逻辑来重写equals和equals的契约小伙伴Hashcode(),从而完成对业务逻辑的具体比较,比如是判断两个员工是不是同一个人则判断他们的name是不是相等。
public boolean equals(Object object){
if(object instanceof Person){
Person p = (Person) object;
if(p.getName() == null || name == null){
return false;
}
else{
return name.equals(p.getName ());
}
}
return false;
}
而为什么在比较String字符串时,equals就是比较的两个字符串的值呢,那是因为字符串自己早就把equals给重写了, 如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
说简单点,java不支持操作符重载,所以对于==规定了是什么比较规则就怎么比,而equals返回的true或false都是可以自己来定义的,如两个值相等,也可以根据自己的意愿让它返回false.
小口诀:==值,址比较 equals自定义比较,string已定义了比较。
4.Object有哪些公用方法: clone() 、 finlize() 、 toString() 、getClass()、 equals() 、hashcode() 、wait() 、 notify()喚醒等待的綫程 、notifyAll()喚醒等待的全部綫程.
这里需要解释一下常用的toString方法,为什么呢?因为我不太会=D
toString() 方法:
toString()方法在Object类中定义,其返回值是String类型,描述当前对象的有关信息
在进行String与其它类型数据的连接操作时,自动调用toString()方法
可以根据需要在用户自定义类型中重写toString()方法
基本类型数据转换为String类型时,调用了对应封装类的toString()方法
public class Person {
private String name;
private int age;
private char sex;
public Person()
{
}
public Person(String name,int age, char sex)
{
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public boolean equals(Object obj)
{
if(obj==null)
{
return false;
}
if(obj==this)//传递进来的参数是否等于本对象
{
return true;
}
if(obj instanceof Person)
{
Person p = (Person)obj;//强制类型转换成Person
return p.getName().equals(this.name);//String内重写的equals方法,写这句的目的是重写equeals方法,如果姓名相等,则p1跟p2相等。
}
return super.equals(obj);
}
//重写hashCode方法
public int hashCode()
{
return this.name.hashCode()*328;
}
//重写toString 方法
public String toString()
{
return "姓名为:"+this.name+"年龄为:"+this.age+"性别为:"+this.sex;
}
}
public class TestPerson {
public static void main(String args[])
{
Person p1 = new Person("王惠", 24, '女');
Person p2 = new Person("吴嫚真",23,'女');
if(p1.equals(p2))
{
System.out.println("她们相等..");
}
else
{
System.out.println("她们不相等");
}
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1);
System.out.println(p2);
}
}
输出结果:
她们不相等
308893672
-1548821240
姓名为:王惠年龄为:24性别为:女
姓名为:吴嫚真年龄为:23性别为:女
注:如果 Person p2 = new Person("王惠",23,'女');
则输出:
她们相等..
308893672
308893672
姓名为:王惠年龄为:24性别为:女
姓名为:王惠年龄为:23性别为:女
如果没有重写toString 方法,那么最后输出结果(因为toString返回的是 hashCode码):
她们不相等
308893672
-1548821240
com.cstp.java1223.Person@126957e8
com.cstp.java1223.Person@a3aedd08
5.内存泄漏问题:
内存泄漏的原理:我们可将对象视为图的有向边的一个顶点,有向边是从引用指向对象.大多数程序从main函数开始执行所以该图就是以main函数的开始进程作为一颗根树.在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC 回收。
内存泄漏要满足两个条件:对象可达 但对象已经不再使用或不常使用,占据内存又不能被回收.
给一个内存泄漏的典型案例:
Vector v = new Vector(10);
for (int i = 1; i < 100; i++) {
Object o = new Object();
v.add(o);
o = null;
}
若有错误,请路过的大神多指教哈=)
未完待续。。。
1.java中九种基本数据类型的大小及他们的封装类.
其中包括六种数字类型(四个整数型,两个浮点型),一种布尔型,一个是void
整型:short,int,long,byte
16 32 64 8
浮点型:float,double
32 64
字符型:char
16(unicode)
布尔型:boolean
1
void
解释:java中有两种数据类型,一种是基本数据类型 一种是引用型数据类型 在Java的圣经Thinking in java中把void也列为基本数据类型,里面认为两种个数据类型的区别在于,基本数据类型是在堆栈中分配空间存“值”,而引用数据类型是在堆中分配空间存“值”,但是void他不能通过new来实例化出来,只能在堆栈中分配空间存储,所以认为void是一种基本数据类型.
建议:在面试中 大家可以先说有8中基本数据类型,然后再说有些书 如thinking in java也把void归为基本数据类型中的一种 故为九种.
疑问:这么说的话,那任何不能实例化 但在堆栈中存储的都算基本数据类型吗?
2.Switch能否用string做参数?
可以 凡是可以自动转换为整型数据类型的数据类型都可以作为switch的参数.如:byte short int string 但是 float long double boolean不能自动转换为int的就不能作为其参数.
比如:
public class Main {
public static void main(String[] args) {
String s="abc";
switch(s){
case("abc"):
System.out.println("i love xingxing");
break;
case("123"):
System.out.println("i love jiming");
break;
default:
break;
}
}
}
3.== 与 equals的区别:
首先==是基本数值的比较(原生类型和对象),如比较int , boolean等的值比较,但是也可以用来比较两个对象,但是是比较的两个对象在堆栈中的引用,而不是比较的两个对象在堆中的具体值;再者,如果大家去查看equals的源码就不难发现
public boolean equals(Object obj) {
return (this == obj);
}
其实equals的内部实现也是用==来进行两个对象比较的,所以java其实是希望开发人员结合自己的业务逻辑来重写equals和equals的契约小伙伴Hashcode(),从而完成对业务逻辑的具体比较,比如是判断两个员工是不是同一个人则判断他们的name是不是相等。
public boolean equals(Object object){
if(object instanceof Person){
Person p = (Person) object;
if(p.getName() == null || name == null){
return false;
}
else{
return name.equals(p.getName ());
}
}
return false;
}
而为什么在比较String字符串时,equals就是比较的两个字符串的值呢,那是因为字符串自己早就把equals给重写了, 如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
说简单点,java不支持操作符重载,所以对于==规定了是什么比较规则就怎么比,而equals返回的true或false都是可以自己来定义的,如两个值相等,也可以根据自己的意愿让它返回false.
小口诀:==值,址比较 equals自定义比较,string已定义了比较。
4.Object有哪些公用方法: clone() 、 finlize() 、 toString() 、getClass()、 equals() 、hashcode() 、wait() 、 notify()喚醒等待的綫程 、notifyAll()喚醒等待的全部綫程.
这里需要解释一下常用的toString方法,为什么呢?因为我不太会=D
toString() 方法:
toString()方法在Object类中定义,其返回值是String类型,描述当前对象的有关信息
在进行String与其它类型数据的连接操作时,自动调用toString()方法
可以根据需要在用户自定义类型中重写toString()方法
基本类型数据转换为String类型时,调用了对应封装类的toString()方法
public class Person {
private String name;
private int age;
private char sex;
public Person()
{
}
public Person(String name,int age, char sex)
{
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public boolean equals(Object obj)
{
if(obj==null)
{
return false;
}
if(obj==this)//传递进来的参数是否等于本对象
{
return true;
}
if(obj instanceof Person)
{
Person p = (Person)obj;//强制类型转换成Person
return p.getName().equals(this.name);//String内重写的equals方法,写这句的目的是重写equeals方法,如果姓名相等,则p1跟p2相等。
}
return super.equals(obj);
}
//重写hashCode方法
public int hashCode()
{
return this.name.hashCode()*328;
}
//重写toString 方法
public String toString()
{
return "姓名为:"+this.name+"年龄为:"+this.age+"性别为:"+this.sex;
}
}
public class TestPerson {
public static void main(String args[])
{
Person p1 = new Person("王惠", 24, '女');
Person p2 = new Person("吴嫚真",23,'女');
if(p1.equals(p2))
{
System.out.println("她们相等..");
}
else
{
System.out.println("她们不相等");
}
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1);
System.out.println(p2);
}
}
输出结果:
她们不相等
308893672
-1548821240
姓名为:王惠年龄为:24性别为:女
姓名为:吴嫚真年龄为:23性别为:女
注:如果 Person p2 = new Person("王惠",23,'女');
则输出:
她们相等..
308893672
308893672
姓名为:王惠年龄为:24性别为:女
姓名为:王惠年龄为:23性别为:女
如果没有重写toString 方法,那么最后输出结果(因为toString返回的是 hashCode码):
她们不相等
308893672
-1548821240
com.cstp.java1223.Person@126957e8
com.cstp.java1223.Person@a3aedd08
5.内存泄漏问题:
内存泄漏的原理:我们可将对象视为图的有向边的一个顶点,有向边是从引用指向对象.大多数程序从main函数开始执行所以该图就是以main函数的开始进程作为一颗根树.在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC 回收。
内存泄漏要满足两个条件:对象可达 但对象已经不再使用或不常使用,占据内存又不能被回收.
给一个内存泄漏的典型案例:
Vector v = new Vector(10);
for (int i = 1; i < 100; i++) {
Object o = new Object();
v.add(o);
o = null;
}
若有错误,请路过的大神多指教哈=)
未完待续。。。
