java常问知识点(一)

以下内容大部分来自网络,自己做了小部分修改
- final,finally,finalize的区别
final是java的关键字,被其修饰的类不能被继承,故一个类不能同时被abstract和final修饰;被修饰的final修饰的方法只能被使用,而不能被覆写、重载;被fanla修饰的变量只能被引用,而不能修改,故要有初始值。
finally通常与catch一起使用,保证无论程序抛出exception与否都要执行finally代码块,即使在catch中return退出了函数。
finalize是一个方法名,这个方法由垃圾收集器确定对象未被使用时调用,将对象销毁。

  • anonymousinnerclass(匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
    new <类或接口> <类的主体>
    可以继承和实现接口,但都尽限一个,为什么?先请看代码
interface IA{
    public  void print();
}

abstract class B{
    public abstract void print();
}

class D{
    public static void test() {
        new IA() {
             public void f(){System.out.println("BBB");}
            @Override
            public void print() {
                // TODO Auto-generated method stub

            }
        };
        new B() {
            @Override
            public void print() {
                // TODO Auto-generated method stub

            }
        };
    }
}

匿名内部类的继承或实现接口时,声明时,类名要和抽象类或接口名一致。

  • static nested class和inner class的不同
    static nested class 指静态嵌套类,或称嵌套类,是C++中常用的说法,inner class指内部类,是JAVA中的说法.
    内部类是一个类内部的类的统称,具体分为四种:成员类,静态成员类,局部类,匿名类.
    其中匿名类是局部类的特殊情况.
//匿名类上个问题有,不说了
class D{
    public static void test() {
        class A{
            void print() {
                System.out.println();
            }
        };
    }
}

对于成员类和静态成员类都存在于类的顶层代码中,相当于类的静态方法和非静态方法的关系。区别在于 成员类依赖于类实例而静态成员类不依赖.所以前者只能访问实例方法和成员而后者只能访问静态方法和成员。

class A{
    public class C{};
    static class D{};
}

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("匿名内部类");
        A.D d = new A.D();

        A a = new A();
        A.C c = a.new C();
    }

}
  • &和&&的区别。
    位运算符和逻辑运算符
  • hashmap和hashtable的区别
  • collection和collections的区别
  • 什么时候用assert
    使用assert需要开启-ea开关,执行程序
    1、assert关键字需要在运行时候显式开启才能生效,否则你的断言就没有任何意义。而现在主流的Java IDE工具默认都没有开启-ea断言检查功能。这就意味着你如果使用IDE工具编码,调试运行时候会有一定的麻烦。并且,对于Java Web应用,程序代码都是部署在容器里面,你没法直接去控制程序的运行,如果一定要开启-ea的开关,则需要更改Web容器的运行配置参数。这对程序的移植和部署都带来很大的不便。
    2、用assert代替if是陷阱之二。assert的判断和if语句差不多,但两者的作用有着本质的区别:assert关键字本意上是为测试调试程序时使用的,但如果不小心用assert来控制了程序的业务流程,那在测试调试结束后去掉assert关键字就意味着修改了程序的正常的逻辑。
    3、assert断言失败将面临程序的退出。这在一个生产环境下的应用是绝不能容忍的。一般都是通过异常处理来解决程序中潜在的错误。但是使用断言就很危险,一旦失败系统就挂了。
    所以测试的时候时候断言就可。

  • gc是什么?为什么要有gc?
    GC 即 garbage collection(垃圾收集),是JAVA用于回收内存的一种方式,主要的实现方法有引用计数,标记回收,复制清除等,GC可以避免内存泄露和堆栈溢出,有效提高内存的利用效率,同时将程序员从繁琐的内存管理中释放出来.
    System类里有个gc()函数,供程序员调用回收内存。那为什么有了垃圾回收机制了,还要使用gc()呢,请看下面代码

a.v = b;
b.v = c;
/*
 *Watch out !
 *b仍然有指向!!
 */
a.v = d;
  • string s=new string(“xyz”);创建了几个stringobject?
    2个,文字池中1个,堆中1个.先在文字池中创建1个”xyz”对象,再在堆中拷贝一个”xyz”对象,并将其赋给引用s.
  • Math.round(11.5)和Math.round(-11.5)
    结果为12和-11.因为四舍五入。
  • short s1=1;s1=s1+1;有什么错?short s1=1;s1+=1;有什么错?
    s1=s1+1会出错,s1+1是int型,不能将int赋值给s1.需要显示转换,s1=(int)(s1+1).而s1+=1不会出错,至于原因,有人说和编译器的机制有关,需要看编译原理。
  • sleep()和wait()有什么区别?
    1,sleep()是java.lang.Thread中的静态方法,wait()是java.lang.Object中的方法
    2,sleep()用作当前线程阻塞自己,并在制定时间后恢复,wait()用于当前线程决定其他线程阻塞,是线程通信的表现.
    3,sleep()不释放资源,wait()释放资源.
    4,sleep()必须捕获异常,而wait()不需要.
  • java有没有goto?
    有,但不用常用,可读性不高
  • 数组有没有length()这个方法?string有没有length()这个方法?
    数组没有,lenght有
  • overload和override的区别。overloaded的方法是否可以改变返回值的类型?
    Overload是重载的意思,Override是覆盖的意思,也就是重写。
    重载Overload,类内定义。表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。重载不能根据放回值来区分。
    重写Override,因子类和父类的关系定义。表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。
    那overloaded的方法是否可以改变返回值的类型?
    不可以。因为若这样改了,它就不能实现多态。
    错误提示
class A{
    public void print() {
        System.out.println("A");
    };
}
class B extends A{
//错误提示: The return type is incompatible with A.print()
    public int print() {
        return 1;
    };
}
class C extends A{
//错误提示: The return type is incompatible with A.print()
    public String print() {
        return "hello";
    };
}
/*
*若一个方法传入的是<?extends A>请如何调用print方法
*/
  • set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用hashcode()还是equals()?它们有何区别?
    这个属于集合类的查找机制问题,在集合类中,确定两个元素是 否相同,是用equals方法进行比较,hashcode的存在在于可以给元素快速分配一个index来存储.可以将collection看做很多个大箱 子,index是箱子的编号,先将要扔进去的物品进行hash确定index,扔进响应箱子,然后再和箱子里的其它物品equals()来比较是否相同.
    此外,相等的物品一定具有相同的hashcode,不等的物品不一定.具有相同hashcode的元素不一定相等.不同的hashcode的元素肯定不 等.以上规则可以想象一下相等物品一定要分在同一个箱子中的情况.
class Person{
    int age;
    String name;
    @Override

    public int hashCode() {
        return 1;
    }
    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + "]";
    }

}


public class Main {

    public static void main(String[] args) {
        Set<Person> set = new HashSet<Person>();
        set.add(new Person(10,"张三"));
        set.add(new Person(10,"张三"));
        set.add(new Person(10,"张三"));
        Iterator<Person> it = set.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }

    }

}
  • 给我一个你最常见到的runtimeexception
    可以查java的api文档的java.lang包
    NullPointerException - 空指针引用异常
    ClassCastException - 类型强制转换异常。
    IllegalArgumentException - 传递非法参数异常。
    ArithmeticException - 算术运算异常
    ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
    IndexOutOfBoundsException - 下标越界异常
    NegativeArraySizeException - 创建一个大小为负数的数组错误异常
    NumberFormatException - 数字格式异常
    SecurityException - 安全异常
    UnsupportedOperationException - 不支持的操作异常

  • list,set,map是否继承自collection接口?
    list和set是,colletion不是,这查api文档或源代码都知道

  • abstractclass和interface有什么区别
    抽象类可以有抽象方法和普通方法,也可以有自己的数据成员.接口只允许有常量,抽象方法和静态类成员.
    接口可以被多实现,抽象类不多继承.接口被实现时,所有方法必须被重写.抽象类被继承时如果有抽象方法没被重写,则子类也为抽象类.
    不过JDK1.8有了新的改变,interface可以有default和static完整方法
interface A{
    public static void print() {
        System.out.println("我是A的静态方法");
    }
    public default void defaultPrint() {
        System.out.println("我是A的default方法");
    }
}
  • abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
    abstact方法需要子类重写,重写的概念是就实例方法而 言, 所以不能是static.因为同一原因,要重写就不能native。
    synchronized是同步,没实现也同步不起来。
abstract class D{
//Eclipse竟然显示的错误是The abstract method print in type D
//can only set a visibility modifier, one of public or //protected
    abstract synchronized void print();
}

abstract方法的修饰符只有protected和public.因为你私有了,怎么override。

  • 启动一个线程是用run()还是start()?
  • 构造器constructor是否可被override?
    构造器(override)不能被继承,因此不能重写overriding
  • 是否可以继承string类
    String类为final,不可被继承.
  • 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
    对象的synchronized方法不能进入了,但它的其他非synchronized方法还是可以访问的。
    class C {
    public synchronized void print(String msg) {
    System.out.print(“print方法”+msg+”\n”);
    try {
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    public synchronized void println(String msg) {
    System.out.println(“println方法”+msg+”\n”);
    }
    }
    public class Main {
    public static void main(String[] args) {
    C c = new C();

        new Thread(()-> {
            c.print(Thread.currentThread()+"我占用啦,哈哈哈!!");
        }).start();;
        new Thread(()-> {
            c.println(Thread.currentThread()+"我占用啦,哈哈哈!!");
        }).start();;
    

    }
    }

  • synchronized和lock的区别
  • try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
class C {
    public  String ret() {
        try {
            return "我是try";
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            return "我是finally";
        }
    }
}
public class Main {
    public static void main(String[] args) {
        C c = new C();
        System.out.println(c.ret());
    }
}

输出:

"我是finally"

我发现额外的错误

class C {
编译错误提示:Unreachable codeThis method must return a result of type String
    public  String ret() {
        try {
            return "我是try";
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            //return "我是finally";
        }
    }
}
class C {
    public  String ret() {
        try {
            return "我是try";
        }catch(Exception e) {
            e.printStackTrace();
        }finally {
            return "我是finally";
        }
        //编译错误提示:Unreachable code
        return "我是end";
    }
}

我终于知道finally必须执行的原因了,它的地位比任何return还高。

  • 用最有效率的方法算出2乘以8等於几
    用位移
int x=2;
x=x<<2; //乘两次2
x=x>>4; //除四次2      
  • 两个对象值相同(x.equals(y)true),但却可有不同的hashcode,这句话对不对?

  • 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    引用传递,毫无疑问,对象传递只能是引用.你可以换改变引用的内容,但并不能改变引用本身.

  • swtich是否能作用在byte上,是否能作用在long上,是否能作用在string上?
    错误提示: Cannot switch on a value of type long. Only convertible int values, strings or enum variables are permitted

switch可作用于char 、byte 、short、 int
switch可作用于char、 byte 、short 、int对应的包装类
switch不可作用于long、 double、 float、 boolean,包括他们的包装类
swith还可以作用于String、enum变量

//      错误提示: Cannot switch on a value of type long. Only convertible int values, 
//      strings or enum variables are permitted
long d=3;
switch(d){}
  • 编程题:写一个singleton出来

参考

JAVA面试常被问到的题目
Java陷阱之assert关键字
浅谈System.gc()的工作原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值