java面试基础篇(四)

1、Q:java三个特性都有什么,分别来谈一谈。

  A:继承:继承后子类自动拥有了父类的属性和方法,但特别注意的是,父类的私有属性和构造方法并不能被继承。好处可以代码复用,减少代码量

       封装:封装也称为信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他部分只有通过包裹在数据外面的被授权的操作来与这个抽象数据类型交流与交互。也就是说,用户无需知道对象内部方法的实现细节,但可以根据对象提供的外部接口(对象名和参数)访问该对象。优点是将能实现某一特定功能的代码封装成一个独立的实体后,各程序员可以在需要的时候调用,从而实现了专业的分工,同时也尽可能的隐藏信息,实现细节。

     多态:多态的三个要素:1.多态是方法的多态,不是属性的多态(多态与属性无关)2.多态存在要有3个必要条件:继承、方法重写、父类引用指向子类对象。3.父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。

    抽象:在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。抽象类的限制:1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

2、Q:简单说一下java的堆和栈

   A:JAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆。

    基本数据类型、局部变量都是存放在栈内存中的,用完就消失。new创建的实例化对象及数组,是存放在堆内存中的,用完之后靠垃圾回收机制不定期自动消除。

    栈:

函数中定义的基本类型变量,对象的引用变量都在函数的栈内存中分配。
栈内存特点,数据一执行完毕,变量会立即释放,节约内存空间。
栈内存中的数据,没有默认初始化值,需要手动设置。  

    堆:

堆内存用来存放new创建的对象和数组。
堆内存中所有的实体都有内存地址值。
堆内存中的实体是用来封装数据的,这些数据都有默认初始化值。
堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除,这也是JAVA优于C++的表现之一(C++中需要程序员手动清除)。

    可以参考:https://blog.csdn.net/jasonwang18/article/details/70578647

    总结起来可以是:堆和栈的区别可以用如下的比喻来看出:使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

3、Q:阐述final、finally、finalize的区别?

   A:在java中,final可以用来修饰类,方法和变量(成员变量或局部变量)。当用final修饰类的时,表明该类不能被其他类所继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:

final类中所有的成员方法都会隐式的定义为final方法。

    finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。当遇到exit时,会直接退出程序,不会执行下边的finally中的语句。否则finally一定会执行,即使没有catch时,会在try的return前来执行finally代码程序。

    finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。 

特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。 
  使用finalize还需要注意一个事,调用super.finalize();

  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。

 4、Q:用Java写一个冒泡排序。(前面在python 里说过什么是冒泡排序,第一个就是冒泡排序:https://www.cnblogs.com/cxiaocai/p/11040749.html)

   A:

package com;

public class Blog {
//    冒泡排序算法的原理如下:
//    比较相邻的元素。如果第一个比第二个大,就交换他们两个。
//    对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
//    针对所有的元素重复以上的步骤,除了最后一个。
//    持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    public static void main(String[] args) {
        int[] arr = { -97, -8, 9, -5, 87, 1, -87, 98 };
        for (int i = 0; i < arr.length; i++) {
            int k = 0;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    k = arr[i];
                    arr[i] = arr[j];
                    arr[j] = k;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

5、Q:如何决定选用HashMap还是TreeMap?

   A:TreeMap的key按自然增加顺序排序,HashMap没有顺序,HashMap速度快.他们都是非线程安全的,需要线程安全,建议使用HashTable

猜你喜欢

转载自www.cnblogs.com/cxiaocai/p/11099714.html
今日推荐