转载

个人模拟面试之基础知识

转自点点

说说抽象和接口的异同

补充定义:
抽象类,即一个包含抽象方法的类,类中的抽象方法以abstract来修饰。
abstract只能修饰类和方法,不能修饰变量。

接口,一个方法的集合,接口中所有的方法都没有方法体,且方法都是以public abstract默认修饰,其中abstract可以省略。public abstract也可以省略
接口是程序的功能扩展,用来多实现。

相同点:

抽象类和接口都不能被实例化,只有接口的实现类或抽象类的子类实现了抽象类或接口中的所有抽象方法之后才能被实例化。

不同点

1。从继承关系上来说,
抽象类类与类之间属于单继承,接口与接口属于多继承,类可以实现接口;
2。从方法上来说,
抽象类中可以包含抽象方法(没有方法体),也可以不包含(声明该类不能被实例化而已),可以存在有其他实现的普通方法。抽象方法不能用private static synchronized native修饰。子类继承抽象类,要么实现抽象类中所有抽象方法,要么自己也是抽象类,实现部分抽象方法;
接口中的方法都是以public abstract默认修饰的,因此都不能有方法体,不能有普通方法。实现类必须实现接口中的所有方法,否则为抽象类。其中,public abstract可以省略abstract,也可以public abstract都省略。
3。从成员变量来说。
抽象类中可以有普通变量,可以有静态变量等各种类型;
接口中的变量只能被public static final修饰,并且必须要赋初值。

异常及异常处理方法(try throws)

Java提供了两种错误的异常,分别是Error和Exception,且它们拥有共同的父类Throwable,这使得异常体系中所有类以及对象都具备可抛性。

Error表示程序在运行期间出现了严重的错误,且该错误是不可恢复的,这将导致程序的终止。由于编译器不会检查Error是否被处理,因此一般对Error不作捕获。
Exception表示可恢复的异常,是编译器可以捕获到的。包含两种,检测时异常和运行时异常。

异常分类

检测时异常:所有继承自Exception且不是运行时异常的都是检测时异常。如最常见的IO异常和SQL异常等。发生在编译阶段,Java编译器会强制程序去捕获异常。
运行时异常:编译器不对其进行捕获处理。如果不对其进行处理,将由JVM来进行处理。如NullPointException,ClassCastException,ArrayIndexOutOfBoundsException,BufferOverflowException,ArithmeticException等。函数内抛异常,函数上不用声明,编译照样通过。

处理异常

对于异常的处理,通常有两种,一种是在函数上声明异常,用throws抛出异常;一种是在函数内抛异常,用try catch finally的组合等。

//函数上用throws声明异常
public static void getException() throws ArithmeticException{
        System.out.println(10/0);
    }
    //函数内try catch处理异常
    public static void testException(){
        try {//函数运算内容
            System.out.println(10/0);
        } catch (Exception e) {//发生异常时的处理
            throw new RuntimeException("除数为0,出现异常");
        }finally{
            .....//一定会执行的内容,如资源的关闭等
        }
    }

对于try catch finally组合,有以下几种:
try catch(try catch catch…)
try finally;
try catch finally(try catch catch…finally)
其中,多个catch时,最上层的是子类,父类都位于最下层,如有Exception,则将位于最后一个catch

try catch finally中的return

try中有return,finally中没有,且不出现异常

public class Test1{
    public static void main(String[] args) {
        System.out.println(testException());
    }
        public static int testException(){
        int a=1;
        int b=10;
        try {
            System.out.println("try");
            return a+b;
        }catch (ArithmeticException e) {
            System.out.println("catch");
            return a+b+10;
        }catch (Exception e) {
            // TODO: handle exception
        }finally{
            a=a+10;
            System.out.println("finally");
        }
        return 0;
    }
}

//执行结果:
//try
//finally
//11

如上代码所示,try中返回的是a+b,但finally是一定要执行的,如果return是在finally之后执行,那么a=a+10后a变为11,这时返回应该是21,而结果却是11。这说明,当try中有return且不抛异常,而finally中没有return时,在try遇到return时先保存返回值,再去执行finally,执行完再返回到try中返回先前保存的值。
如果try中此时抛异常,如令a=0,且try中 return b/a;结果如下:

try
catch
finally
20

当try中出现异常,catch中return的返回值也是暂存了,执行完finally之后再返回。
如果finally中也有返回值呢?!

public static int testException(){
        int a=0;
        int b=10;
        try {
            System.out.println("try");
            return b/a;
        }catch (ArithmeticException e) {
            System.out.println("catch");
            return ++a+1;
        }finally{
            System.out.println("finally");
            return a+30;
        }
    }
    /////执行结果
        try
        catch
        finally
        31

在try中抛异常,进入catch,此时return返回值应该是为1,a值为1,但由于finally存在,还得执行finally,结果finally中也有return,返回结果为31。这里,就将catch中的返回值进行了覆盖。即finally中有返回值时,最终返回的是finally中的返回值。

异常子父类覆盖情况。
子类抛异常必须是父类的子类或子集。父类不抛异常,子类只能try catch.
在try catch中如果抛检测时异常,都得以try catch再包裹起来。如果是运行时异常,直接抛出即可。且try中的任何异常都会进入catch进行处理。
如果方法是没有返回值的,finally中也可以直接抛异常,否则由于抛异常之后return不执行,导致检测时不能通过。如果try中只抛异常,也会出现这种结果。
这里写图片描述

Object类有哪些方法?

这里写图片描述
除此之外,还有被隐藏的finalize和clone,总共11个方法。

判断对象是否相等 equals、hashCode、==

==:如果是基本数据类型,则直接比较两值是否相等;如果是引用数据类型,则比较的是两个值的引用地址。
equals:Object类中的equals是直接使用“==”来比较两个对象的。所以如果对equals方法没有复写的话,比较的是两对象的引用地址。像String Date等类,都复写了equals方法,最终比较的是二者的内容。
hashCode:Object类方法,也是用来判断两个对象是否相等的,它是返回对象在内存中地址转换成的一个int值。如果没有重写hashCode,任何对象的hashCode都是不相等的。如果两对象引用是相同的,则hashCode也是一样的。String等类同样对其进行了复写。

equals和hashCode区别(**可以从hashmap底层实现来看)

如果equals返回值为true,那么hashCode一定相等;如果equals返回为false,那么hashCode可能相等也可能不等。
hashCode不相等,那么equals肯定为false;如果hashCode相等,equals可能为true也可能为false。
这个我们可以从散列角度考虑,不同的对象计算哈希码时可能会发生冲突。某种程度上,hashCode比equals效率高
例如hashmap底层实现,查找Key时,先对其进行hash算法得到哈希值,如果hash值相同,再去比较key是否相等,key相等才能说找到了正确的结果。如果hash值不相等,那么肯定在找不到相等的key。

包装类的一些小知识

int 跟包装类做==比较时,只比较数值大小,数值大小相等即为true;
Integer m=数值的效果等同于Integer m=Integer.valueOf(数值),
valueOf会将常用的值(-128 to 127)cache起来。当i值在这个范围时,会比用构造方法Integer(int)效率和空间上更好。Long也是。数值在-128-127之间时,装箱后的Integer对象会重用,(直接在缓存中找);超过此范围,装箱后的Integer对象不会重用;
new Integer(数值),总会new一个对象,而且不是new缓存中的对象,==比较时,数值大小相等也会false

public static void main(String[] args) {
        //涉及到数值重用,数据在-128-127的情况
        int x1=59;
        Integer x2=59;
        Integer x3=Integer.valueOf(59);
        Integer x4=new Integer(59);
        //int和包装类作==比较,只比较数值大小
        //(就算是new也是比较大小)
        System.out.println("1-2"+(x1==x2));//true
        System.out.println("1-3"+(x1==x3));//true
        System.out.println("1-4"+(x1==x4));//true
        //Integer m=数值的效果等同于Integer m=Integer.valueOf(数值)
        //(-128-127内都会重用缓存中的值)
        System.out.println("2-3"+(x2==x3));//true
        //new对象,new的是缓存中的对象,数值相等也为false
        System.out.println("2-4"+(x2==x4));//false
        System.out.println("3-4"+(x3==x4));//false
        System.out.println("==============");

        //数值不在-128-127的情况
        int y1=200;
        Integer y2=200;
        Integer y3=Integer.valueOf(200);
        Integer y4=new Integer(200);
        //int比较值,仍成立
        System.out.println("1-2"+(y1==y2));//true
        System.out.println("1-3"+(y1==y3));//true
        System.out.println("1-4"+(y1==y4));//true
        //不会重用,Integer.valueOf(数值)相当于new Integer,因此不会和Integer m=数值 相等。
        System.out.println("2-3"+(y2==y3));//false
        //new对象,都不会相等
        System.out.println("2-4"+(y2==y4));//false
        System.out.println("3-4"+(y3==y4));//false
    }

getClass、toString方法

这两个方法都是属于辅助方法。
getClass返回的是一个Class对象,后面可以跟class类的方法,用的是谁的构造函数,那么getClass返回的就是谁的类型。getClass经常用于Java反射机制。
toString方法返回的是一个string对象,用来标识自己。

clone finalize方法

clone:使用clone可以用来复制一个对象,会在单独的博文中分析该方法。
finalize:JVMGC机制时对对象回收的一个方法,判断对象是否真的无法存活,如果在该方法过程中对象还能和引用链发生关系,则对象不会被回收。该方法一个对象只能调用一次。

wait wait(long) wait(long,int) notify notifyAll

这五种方法都与多线程的唤醒阻塞有关系。其中wait表示让正在进行的线程暂停执行,释放对象锁,进入等待阻塞状态,直到被其他的线程唤醒或者是等待阻塞超时才重新进入就绪状态等待获取锁,。与之匹配的就是唤醒,即notify随机唤醒阻塞的线程,notifyAll唤醒的是所有阻塞的线程。
sleep是不释放资源,等待一定时间继续执行。

说说wait和sleep的区别

1。原理不同。
sleep是Thread的静态类,是线程用来控制自身流程的。它会使得线程暂停执行一段时间,将执行机会交给其他线程,等到时间一到就自动“唤醒”继续执行;
wait是Object方法,用于线程间的通信。它使得正在执行的线程放弃执行机会,进入阻塞状态,让其他线程去争夺执行权。直到超时或者被唤醒才重新进入就绪状态去争夺执行权。
2。对锁的处理机制不同。
sleep不释放锁,而wait会释放锁。
3。使用区域不同。
sleep可以放在任何地方使用,而wait由于其特殊性,只能放在同步控制方法或同步块中执行。
4。对于异常。
sleep必须捕获异常,如InterruptedException。wait等不用捕获异常,但要进行try catch处理,否则会在运行时抛出IllegalMonitorStateException。
线程状态:创建,就绪,运行,阻塞,停止。

既然谈到线程,说说线程创建方式

线程创建的方式有两种,一种是继承Thread类,一种是实现runnable接口。由于接口的多继承和扩展性,一般来说,使用实现runnable接口形式更好。

什么是进程?什么是线程?什么是多进程?什么是多线程?为什么要有多进程和多线程?

进程:操作系统进行资源分配的单位;正在运行的程序。
线程:进程中独立操作的执行单元。
多进程:多进程是指同时运行多种程序。或者一个程序多个进程。
多线程:多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率。线程是在同一时间需要完成多项任务的时候被实现的。

谈谈什么是死锁,如何避免死锁

死锁,多线程竞争共享资源导致的无限期等待。
四个必要条件:互斥条件,不可抢占条件,占有且申请条件,循环等待条件。
如何避免死锁:安全序列,银行家算法。

线程池介绍,几个线程池的区别

线程池7个参数的解释,
Executors.newCachedThreadPool(); //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE
Executors.newSingleThreadExecutor(); //创建容量为1的缓冲池
Executors.newFixedThreadPool(int); //创建固定容量大小的缓冲池

Java如何保证原子性的

锁(lock和unlock来实现原子性的)和循环CAS(共享变量)。
对于线程安全的实现,有三种,同步互斥,非阻塞同步,无同步。其中涉及到锁的为同步互斥,涉及到synchronized锁,如果加锁解锁太过频繁,用户态到核心态的一个切换会消耗各种资源。因此对锁进行一系列的优化,如自旋锁,自适应自旋锁,锁消除,锁加粗,轻量级锁,偏向锁和重量级锁。

说说反射机制

反射机制,在程序运行时动态的去获取一个已知类名的所有内部信息,包括对象,方法,字段等。
反射机制可以去操纵对象的。

对设计模式有了解么

单例设计模式,必须掌握的。
单例设计模式怎么实现的
私有构造函数,私有自定义实例对象,公有访问方法。
为什么要声明静态单例对象
首先,单例模式决定了你不能在其他地方创建对象,而是通过类中提供的公有访问方法去访问类中的那个自定义对象。
而程序调用类中的方法只有两种,一种是创建类的一个对象,用对象去调用方法;构造函数私有化以后这种方法就不合适了。
第二种是通过类名.方法名来进行调用。这样访问方法必须是静态的,而静态方法不能访问非静态成员变量,因此类中自定义的实例变量必须是静态的。

static关键字

作用,修饰成员(成员变量和成员函数)
特点;(随着类的加载而加载,优先于对象存在,被所有对象共享,可以直接被类名调用)
和实例变量的区别(存放位置,生命周期)(实例变量就是成员变量,非static修饰的)(方法区,堆内存)
利弊:好处是对共享数据进行单独存储,节省空间,没必要每个对象都存一份,可以直接被类名调用;
坏处就是其生命周期过长,对于一些使用较少的,浪费了空间。
访问特点:静态的只能访问静态的,非静态的既可以访问非静态,也可以访问静态的。

知道final关键字么?

修饰类。变量。函数。 变量为成员变量,静态变量,局部变量
类不可被继承,方法不可被重写,变量不可改变

final finally finalize的作用

关键字,异常处理,垃圾回收时调用来判断对象是否需要被回收

文章最后发布于: 2017-09-07 23:41:47
展开阅读全文
0 个人打赏
私信求帮助

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie

分享到微信朋友圈

×

扫一扫,手机浏览