JAVA后端开发面经3

​面经来源于github上的

Java-Interview

在学习时,用自己的语言解释​

 21.面向对象的特征有哪些方面

面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征。

  • 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。

例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性,人以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配在人这个对象上,这就是面向对象的封装性。

  • 继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,提高了软件的可重用性和可扩展性。
  • 抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。
  • 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

22.java中实现多态的机制是什么?

靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

23.abstract class和interface有什么区别?

这道题原文讲的很好

含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。

  • 通俗解释:可以定义一个具体方法在abstract class中,其实可以理解为抽象方法是各个方法的总和,你定义的方法抽象也可以,不抽象也可以。

abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。

  • 这个的意思就是,虽然你可以定义抽象或者不抽象的方法,但是你定义的抽象方法一定要放在具体子类去实现,否则你定义子类也会是抽象的。这里的 ‘不能有抽象构造方法或抽象静态方法’ 其实讲的是子类

接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

下面比较一下两者的语法区别:

  • 1)抽象类可以有构造方法,接口中不能有构造方法。
  • 2)抽象类中可以有普通成员变量,接口中没有普通成员变量
  • 3)抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
  • 4) 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然
  • eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
  • 5)抽象类中可以包含静态方法,接口中不能包含静态方法
  • 6)抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
  • 7)一个类可以实现多个接口,但只能继承一个抽象类。

下面接着再说说两者在应用上的区别:

接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用。

例如,模板方法设计模式是抽象类的一个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:

public abstract class BaseServlet extends HttpServlet {

    public final void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        // 记录访问日志, 进行权限判断
        if (具有权限) {
            try {
                doService(request, response);
            } catch (Exception e) {
                // todo:记录异常信息
            }
        }
    }

    protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的
    }
}
public class MyServlet1 extends BaseServlet {
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws IOExcetion, ServletException {
        // 本Servlet只处理的具体业务逻辑代码
    }
}

这道题目把前面看明白,大概大概逻辑都可以捋清楚了。

24.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

这道题目有点难度

abstract的method 不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!

native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。

如果我们要用java调用别人写的c语言函数,我们是无法直接调用的,我们需要按照java的要求写一个c语言的函数,又我们的这个c语言函数去调用别人的c语言函数。由于我们的c语言函数是按java的要求来写的,我们这个c语言函数就可以与java对接上,java那边的对接方式就是定义出与我们这个c函数相对应的方法,java中对应的方法不需要写具体的代码,但需要在前面声明native。

关于synchronized与abstract合用的问题,我觉得也不行,因为在我几年的学习和开发中,从来没见到过这种情况,并且我觉得synchronized应该是作用在一个具体的方法上才有意义。而且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上无法确定this是什么。

25.什么是内部类?Static Nested Class 和 Inner Class的不同。

内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已)

Static Nested Class(嵌套类)是静态(static)内部类。(一般是C++的说法)

Inner Class(内部类)定义在类中的类。 (一般是JAVA的说法)

1.是否能拥有静态成员

静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。

2.访问外部类的成员

静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。

3.静态内部类和非静态内部类在创建时有区别
4.一个有static修饰,一个没有static修饰

5.static修饰表示静态的,在类加载时JVM会把它放到方法区,被本类以及本类中所有实例所公用。
 

26.内部类可以引用它的包含类的成员吗?有没有什么限制?

完全可以

如果把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:

class Outer {
    static int x;

    static class Inner {
        void test() {
            syso(x);
        }
    }
}

27.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

可以继承其他类或实现其他接口。

28.super.getClass()方法调用

下面程序的输出结果是多少?

import java.util.Date;

public class Test extends Date {
	public static void main(String[] args) {
		new Test().test();
	}
	
	public void test() {
		System.out.println(super.getClass().getName());
	}
}

很奇怪,结果是Test。

在test方法中,直接调用getClass().getName()方法,返回的是Test类名。由于getClass()在Object类中定义成了final,子类不能覆盖该方法,所以,在test方法中调用getClass().getName()方法,其实就是在调用从父类继承的getClass()方法,等效于调用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也应该是Test。

如果想得到父类的名称,应该用如下代码:

getClass().getSuperClass().getName();

29.String是最基本的数据类型吗?

基本数据类型包括byte、int、char、long、float、double、boolean和short。

java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类

这个记住就好。

30.String s = "Hello";s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有? 

没有变,只是在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?

答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

你可能感兴趣的:(java面经基础,java,开发语言,学习,经验分享)