java面试题-javaSE

JavaSE基础

1、面向对象有哪些特性以及你对这些特性的理解

  1. 继承:继承是从已有类到得继承信息创建新类的过程。(提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类))。
  2. 封装:把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
  3. 多态:指允许不同子类型的对象对同一消息做出不同的响应。
  4. 抽象:将一类对象的共同特征总结出来构造类的过程。

默认情况面向对象有3大特性(封装、继承、多态),问4大特性就把抽象加上去。

2、访问权限修饰符的区别

java面试题-javaSE_第1张图片

3、为什么用clone

  • 比如有一个对象A,此时又需要一个和A完全相同的对象B,并且此后对B任何改动都不影响到A中的值(A和B是两个独立对象),但B的初始值是A对象确定的,此时用clone()实现最简单也最高效。

4、&&&的区别

  • &运算符有两种用法:(1)按位与;(2)逻辑与。
  • &&运算符是短路与运算。
  • &&之所以成为短路与运算是因为,如果&&左边的变道时的值是false,右边的表达式会被直接短路掉,不会进行运算。但是&遇到左边的变道时的值是false,还会继续运算右边的表达式。(逻辑或(|)与短路或(||)的区别也是如此)

5、在Java中,如何调出当前的多重嵌套循环

  • 在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。

6、两个对象值相同(x.equals(y) == true),但却可能有不同的hashCode,这句话对不对?

  • 不对,如果两个对象x和y满足(x.equals(y) == true),它们的hashCode一定相同。

如果两个对象的hashCode相同,它们的equals不一定相同

7、是否可以继承String

  • 不可以,String类是final修饰的类,不可被继承。

8、重载(overload)和重写(override)的区别?重载的方法能否根据返回类型进行区分?

  • 重载–>实现编译时的多态性–>发生在一个类中同名的方法如果有不同的参数列表(参数类型、个数不同)则视为重载。
  • 重写–>实现运行时的多态性–>发生在子类与父类之间,重写要求被重写的方法子父类中有相同的返回类型,比父类被重写的方法更好访问(权限更低)不能比父类被重写的方法声明更多的异常
  • 重载的方法不能根据返回类型进行区分,重载对返回类型没有要求。

9、char类型变量能不能存储一个中文汉字,为什么?

  • 可以。因为Java中使用的编码是Unicode,一个char类型占2个字节(16比特),一个中文占2个字节,所以放一个中文没问题。

10、抽象类和接口有什么异同?

  • 不同:
    • 抽象类:
      • 1.可以定义构造器
      • 2.可以有抽象方法和具体方法
      • 3.成员可以是private、默认、protected、public
      • 4.可以定义成员变量
      • 5.可以包含静态方法
      • 6.一个类只能继承一个抽象类
    • 接口:
      • 1.不能定义构造器
      • 2.方法全部是抽象方法
      • 3.成员全部是public
      • 4.定义的成员变量实际上都是常亮(static final修饰)
      • 5.不能有静态方法
      • 6.一个类可以实现多个接口
  • 相同
    • 1.不能够实例化
    • 2.可以将抽象类和接口类型作为引用类型
    • 3.一个类如果继承了某个抽象类或实现了某个接口,都需要对其中的抽象方法全部实现,否则该类仍然需要被声明为抽象类

11、抽象的方法是否可同时是静态的?是否可同时是本地方法?是否可同时被synchronized?

  • 都不能;
  • 抽象方法需要被子类重新,而静态方法是无法被重写的,所以矛盾;
  • 本地方法是有本地代码实现的,而抽象方法是没有实现的,所以矛盾;
  • synchronized和方法的实现细节有关,抽象方法不涉及实现细节,所以矛盾。

12、阐述静态变量和实例变量的区别

  • 静态变量:是被static修饰符修饰的变量,也成为类变量,它属于类,不属于类的任何一个对象,内存中仅有一个拷贝。
  • 实例变量:必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

13、==和equals()的区别

  • ==和equals()最大的区别是前者是运算符,后者是方法。
  • ==:比较对象如果是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等;
  • equals():用来比较两个对象的内容是否相等。不能用于基本数据类型的变量。如果没有对equals()方法进行重写,则比较的是引用类型的变量所指向的对象的地址。

14、break和continue的区别

  • break和continue都是用来控制循环的语句;
  • break用于完全结束一个循环,跳出循环体执行循环后面的语句;
  • continue用于跳过本次循环,执行下次循环。

15、Java中实现多态的机制是什么?

  • 靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法。
  • A是B的父类,A a = new B(); 那么a调用的是A中的方法,因为a在内存中指向的对象是A。可以理解为 B b = new B(); A a = b; 向上转型。

16、Java中异常分类哪些种类

java面试题-javaSE_第2张图片

  • 1)按照异常需要处理的时机分为编译时异常(强制性异常)也叫CheckedException和运行时异常(非强制性异常)也叫RunntimeException。只有Java语言提供了编译时异常,Java认为编译时异常都是可以被处理的异常,所以Java程序必须显式处理编译时异常。如果程序没有处理Checked异常,改程序在编译时就会发生错误无法继续编译。这体现了Java的设计哲学:没有完善错误处理的代码根本没有机会被执行。对Checked异常处理方法有两种:
    • 1.当前方法知道如何处理该异常,则用try...catch块来处理该异常。
    • 2.当前方法不知道如何处理,则在定义该方法时声明抛出该异常。
  • 2)运行时异常只有代码在运行时才发现的异常,编译时不需要try…catch。Runtime异常如除数是0和数组下标越界等,其产生频繁,处理麻烦,若显示声明或者捕获将对程序的可读性和运行效率影响很大。所以由系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们。

17、try…catch…finally运行机制

public int getNum(){
	try{
		int a = 1/0;
		return 1;
	} catch(Exception e) {
		return 2;
	} finally {
		return 3;
	}
}
  • 上面的运行结果是3。因为int a = 1/0;语句存在异常,会被catch(Exception e)捕捉,返回2,最后还会执行finally 中的语句,最终返回3。

18、error和exception的区别

  • 它们的父类都是Throwable类;
  • Error类一般指与虚拟机有关的问题,如系统崩溃、虚拟机错误、内存空间不足等,这类错误会导致的程序中断,仅靠程序本身是无法恢复和预防的,建议让程序终止
  • Exception类表示程序可以处理的异常,可以捕获且可能恢复。这类异常,应该尽可能处理。

19、Java异常处理机制

  • Java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try…catch处理或用throws声明继续抛给上层调用者处理,所以普通异常也成为编译时异常(CheckedException);而系统异常(RunntimeException)可以处理也可以不处理。

20、写出5个常见的RunntimeException

  • java.lang.NullPointerException 空指针异常
    • 调用了未经初始化的对象或者不存在的对象
  • java.lang.ClassNotFoundException 找不到类异常
    • 类的名称或路径加载错误
  • java.lang.IllegalArgumentException 方法传递参数错误
  • java.lang.ClassCastException 数据类型转换异常
  • SQLException SQL异常

21、throw和throws的区别

  • throw
    • 1.用在方法体内,表示抛出异常,有方法体内的语句处理;
    • 2.throw是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行throw一定是抛出了某种异常。
  • throws
    • 1.用在方法声明后面,表示如果抛出异常,就由方法的调用者来进行异常的处理;
    • 2.throws主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型;
    • 3.throws表示出现异常的一种可能性,并不一定会发生这种异常。

22、final、finally、finalize的区别

  • final:用于声明属性、方法和类,分别表示属性不可变,方法不可覆盖,类不可继承;
  • finally:异常处理语句结构的一部分, 表示总是执行;
  • finalize:Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法。可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

23、switch能否作用在byte、long和String上?

  • Java5以前switch(expr)中,expr只能是byteshortcharint
  • Java5开始,Java引入了枚举类型,expr也可以是enum类型。
  • Java7开始,expr还可以是String类型。

24、数组有没有length()方法?String有没有length()方法?

  • 数组没有length()方法,而是有length属性。
  • String有length()方法。

25、String、StringBuffer、StringBuilder的区别

  • String是只读字符串,引用的字符串内容不能被改变,底层是char[]Java8byte[]
  • StringBuilder/StringBuffer表示字符串对象可以通过各种方法来达到简单的增删改,底层是char[]默认16字符空间,会自动维护数组的扩容;
  • StringBuilderJava5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的;StringBuffer是线程安全的,方法都被synchronized修饰。所以StringBuilder的效率理论上比StringBuffer高。

26、什么情况下用"+"运算符进行字符串连接比调用StringBuilder/StringBuffer对象的append方法连接字符串性能更好?

  • 我们平时用字符串直接相加作连接,也可以,但在循环内部最好还是用 StringBuilder/StringBuffer作字符串的连接,其实在循环次数较小的情况下我们也可以用 String 直接来相加连接,但有时我们根本不能确定循环次数的大小,所以最好还是老老实实的用 StringBuilder/StringBuffer。

27、说出下面程序的输入

java面试题-javaSE_第3张图片

String对象的intern()方法会得到字符串对象在常量池中对应的版本的引用。

28、Java中的日期和时间

  • 内容较多,自主浏览复习
    Java基础编程-JDK8之前日期时间API
    Java基础编程-JDK8新增日期时间API

29、Java的基本数据类型都要哪些,各占几个字节

java面试题-javaSE_第4张图片

30、判断下列的代码是否有错

short s1 = 1;
s1 = s1 + 1;

判断:错误。由于1int类型,因此s1+1运算结果也是int型,需要强制类型转换才能赋给short型。
------------------------------
short s1 = 1;
s1 += 1;

判断:正确。s1 += 1 是编译器优化的结果,含有隐式的强制类型转换,可以理解为s1 = (short)(s1+1)

31、包装类和自动装箱/拆箱

java面试题-javaSE_第5张图片

  • Integer ,Byte,Float,Double,Short,Long都属于Number类的子类,Number类本身提供了一系列的返回以上六种基本数据类型的操作。
  • Character属于Object子类。Boolean属于Object子类。
    java面试题-javaSE_第6张图片
    public static void main(String[] args) {
        Integer a = new Integer(3);
        Integer b = 3;   // 将3自动装箱成Integer
        int c = 3;
        System.out.println(a==b); // false 引用的不是同一个对象
        System.out.println(a.equals(b)); // true 内容相等
        System.out.println(a==c);  // true  a自动拆箱成int类型再和c比较
    }
    public static void main(String[] args) {
        Integer f1 = 100,f2 = 100,f3=150,f4=150;
        System.out.println(f1==f2); // true
        System.out.println(f3==f4); // fa;se
    }
如果整形字面量的值在-128127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。

32、String类常用方法

java面试题-javaSE_第7张图片

33、数据类型之间的转换

  • 1、字符串转基本数据类型
    • 调用基本数据类型对应的包装类中的方法 parseXXX(String)valueOf(String)
  • 2、基本数据类型转字符串
    • 1、将基本数据类型与空字符串("")连接(+)
    • 2、调用String类的valueOf()方法返回相应字符串

34、Java中有几种类型的流

  • 按照流的方向:输入流(inputStream)和输出流(outputStream)
  • 按照实现功能:节点流(从一个特点的节点读写数据)和处理(对一个已存在的流的连接和封装)
  • 按照处理数据的单位:字节流(继承于InputStreamOutputStream)和字符流(继承于InputStreamReaderOutputStreamWriter)

35、什么是Java序列化,如何实现Java序列化

  • 序列化就是一种用来处理流的机制,所谓对象流也就是将对象的内容进行流化,序列化是为了解决在对对象流进行读写操作时所引发的问题。
  • 序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,只是为了标注该对象可被序列化,然后使用一个输出流(如:FileOutputStream)来构造一个对象流(ObjectOutputStream)对象,接着使用对象流对象的writeObject(Object obj)方法就可以将参数为obj的对象写出,要恢复的话则用输入流(ObjectInputStream)。

36、HashMap排序题(上机题)

java面试题-javaSE_第8张图片

public class HashMapTest {
    public static void main(String[] args) {
        HashMap<Integer, User> users = new HashMap<>();
        users.put(1, new User("张三", 22));
        users.put(2, new User("李四", 12));
        users.put(3, new User("王五", 66));
        System.out.println("排序前:" + users);
        HashMap<Integer, User> sortHashMap = sortHashMap(users);
        System.out.println("排序后:"+sortHashMap);
        ArrayList<Object> objects = new ArrayList<>();
        // 排序前:{1=User{name='张三', age=22}, 2=User{name='李四', age=12}, 3=User{name='王五', age=66}}
        // 排序后:{3=User{name='王五', age=66}, 1=User{name='张三', age=22}, 2=User{name='李四', age=12}}
    }

    public static HashMap<Integer, User> sortHashMap(HashMap<Integer, User> map) {
        // 首先拿到map的键值对集合
        Set<Map.Entry<Integer, User>> entrySet = map.entrySet();
        // 将Set转为List,为了使用工具类的排序方法
        List<Map.Entry<Integer, User>> list = new ArrayList<>(entrySet);
        // 使用Collections集合工具类对list进行排序,排序规则使用匿名内部类实现
        Collections.sort(list, new Comparator<Map.Entry<Integer, User>>() {
            @Override
            public int compare(Map.Entry<Integer, User> o1, Map.Entry<Integer, User> o2) {
                // 根据User的age倒序进行排序(默认从小到大,倒序是从大到小)
                return -(o1.getValue().getAge() - o2.getValue().getAge());
            }
        });
        // 创建一个新的有序的HashMap子类的集合
        LinkedHashMap<Integer, User> linkedHashMap = new LinkedHashMap<>();
        // 将list中的数据存储在linkedHashMap中
        for (Map.Entry<Integer, User> entry : list) {
            linkedHashMap.put(entry.getKey(), entry.getValue());
        }
        return linkedHashMap;
    }
}

37、集合框架体系图

java面试题-javaSE_第9张图片

38、请问ArrayListHashSetHashMap是线程安全的吗?如何把它们变成线程安全的?

  • 它们都不是线程安全的。
  • 在集合中,VectorHashTable是线程安全的,它们的核心方法声明上都加上了synchronized
  • Collections工具类提供了相关API,可以让它们变成线程安全你的集合
    java面试题-javaSE_第10张图片

39、集合框架复习

Java基础编程-Java集合

40、多线程基础知识

Java基础编程-多线程

41、在Java中wait和sleep方法的不同

  • sleep() 和 wait()的异同?
    • 相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
    • 不同点:
      • 1)两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()
      • 2)调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
      • 3)关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。

42、叙述一下您对线程池的理解

可以展开说线程池如何用、好处、启动策略

  • 第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会小高系统资源,还会降低系统的稳定性,食堂线程池可以进行统一的分配,调优和监控。

JavaSE高级

1、对Java中反射的理解

  • Java中的反射首先是能够获取到Java中要反射类的字节码,获取字节码的方法有三种
    • 1.Class.forName(className)
    • 2.类名.class
    • 3.this.getClass()
  • 然后将字节码中的方法,变量,构造函数等映射成响应的Method、Filed、Constructor等类,这些类提供了丰富的方法。

2、动静态代理的区别,什么场景使用

  • 静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。
  • 静态代理程序编译时知道代理对象是谁,而动态代理是程序运行时才知道。
  • 动态代理是实现JDK里的InvocationHandler接口的invoke()方法,代理的是接口,所以业务类必须要实现这个接口,通过Proxy里的newProxyInstance()得到代理对象。
  • 还有一种动态代理CGLIB,代理的是类,不需要业务类实现接口,通过派生的子类来实现代理。
  • AOP编程就是基于动态代理实现的。

参考文章:Java动静态代理

3、写出你所知道的设计模式

  • 创建型:工厂方法模式、抽象工程模式、单例模式、建造者模式、原型模式
  • 结构型:适配器模式、代理模式、享元模式
  • 行为型:策略模式、观察者模式

参考文章:设计模式

4、JVM内存分配

java面试题-javaSE_第11张图片

参考文章:深入理解JVM-内存模型(jmm)和GC

5、类在什么时候被初始化

  • 1.创建类的实例,也就是new一个对象
  • 2.访问某个类或接口的静态变量
  • 3.调用类的静态方法
  • 4.反射(Class.forName("com.hjl.hello"))
  • 5.初始化一个类的子类
  • 6.JVM启动时标明的启动类

6、lamba的使用

复习文章:Java基础编程-Lambda

你可能感兴趣的:(Java面试题)