面试题一Java基础

面试题一Java基础

  1. String s = new String(“xyz”);创建了1几个对象

    两个,一个字符串对象,一个字符对象引用对象

  2. Overload和Override的区别?Overloaded的方法是否可以改变返回值的类型?

    方法的重写Overrideing和重载Overloading是Java多态性的不同表现。重写Overrideing是父类与子类之间多态性的一种表现,重载Overloing是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写Overrideing。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载Overloading。

    Overloaded的方法是可以改变返回值的类型。

  3. 最常见的Runtime Exception

    NullPointerException 空指针引用异常

    ClassCastException 类型转换异常

    IndexOutOfBoundsException 下标越界异常

    NumberFormatException 数字格式异常

    EOFException 文件已结束异常

    FiileNotFoundException 文件未找到异常

    NoSuchMethodException 方法未找到异常

  4. error和exception有什么区别?

    error表示恢复不是不可能但很困难的情况下的1一种严重问题,比如内存溢出,不可能指望程序能处理这样的情况;

    exception表示一种设计或实现问题,也就是说,它表示如果程序运行正常,从不会发生的情况

  5. String、StringBuffer和StringBuilder的区别?

    String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。

    StringBuffer 和 StringBuilder 的值是长度可变的,并且不产生新的未使用对象。StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

    String可以赋空值,后者不可以。

  6. 线程和进程的区别?

    进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。

  7. 简单介绍一下集合?

    集合主要分为两大类:Collection和Map

    Collection:
    
    ​	├List:有序可重复
    ​			├ArrayList
    ​					底层数据结构:数组      查询快,增删慢
    ​					线程不安全,效率高
    ​			├LinkedList
    ​					底层数据结构:链表      查询慢,增删快
    ​					线程不安全,效率高
    ​			├Vector
    ​					底层数据结构:数组      查询快,增删慢
    ​					线程安全,效率低
    ​	├Set:无序不可重复
    ​			├HashSet
    ​					底层数据结构:哈希表
    ​					如何保证元素的唯一性呢?
    ​					依赖两个方法:hashCode()和equals(),自动生成即可
    ​			├LinkedHashSet
    ​					底层数据结构:链表和哈希表
    ​					由链表保证元素有序
    ​					由哈希表保证元素唯一
    ​			├TreeSet
    ​					底层数据结构:红黑树
    
    Map:
    
    ​	|-HashMap:
    ​			底层数据结构:键是哈希表结构,保证键的唯一性。可以存入null键,null值
    ​			线程不安全,效率高。 允许key或者value为null
    ​	|-Hashtable:
    ​	      		底层数据结构:哈希表,不可以存入null键,null值
    ​			线程是安全,效率低。
    ​	|-TreeMap:
    ​			底层数据结构:二叉树,保证键的排序和唯一性。需要使用Comparable或者Comparator
     			进行比较排序
    ​			线程不安全,效率高。
    
  8. Hashmap线程不安全,怎么实现一个线程安全的HashMap?

    我们知道HashMap底层的数据结构是数组+链表/红黑树,默认初始容量是16,当数组中的元素大于hashMap的初始容量乘以加载因子时(加载因子默认是0.75),HashMap就会进行扩容,容量变为原来的2倍,然后将原来的数据重新映射到新的桶里面,然后将原来的桶逐个置为null,使得引用失效。也就是在hashMap进行扩容的时候容易发生HashMap线程不安全。HashMap线程不安全主要会产生以下两种情况:1、在多线程的环境下,进行put()的时候会导致多线程的数据不一致。2、在多线程的环境下,对HashMap进行get操作可能因为扩容而引起死循环。

    实现一个线程安全的HashMap

    1、使用ConcurrentHashMap

    2、使用Collections.synchonizedMap(Map<K,v> m)方法将HashMap变成一个线程安全的map。

  9. 线程的生命周期?

    A:新生 new,每个线程都有自己的运行空间
    B:就绪 start(),就绪不代表运行,代表线程具有可运行的能力,在就绪队列中排队等待cpu调度
    C:运行 cpu把时间片分配给某个线程,这个线程就就行运行状态
    D:阻塞 sleep()…
    E:死亡 执行完毕

  10. start()方法和run()方法的区别?

    只有调用start()方法,才会表现出多线程的特征,不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。

  11. java中的notify和notifyAll有什么区别?

    这又是一个刁钻的问题,因为多线程可以等待单监控锁,Java API 的设计人员提供了一些方法当等待条件改变的时候通知它们,但是这些方法没有完全实现。notify()方法不能唤醒某个具体的线程,所以只有一个线程在等 待的时候它才有用武之地。而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。

  12. 什么是线程池?为什么要使用它?

    创建线程花费昂贵的资源和时间,如果任务来了才创建那么响应时间会变长,而且一个进程能够创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。

  13. 如何避免死锁?
    死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

    • 互斥条件:一个资源每次只能被一个进程使用。
    • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    • 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
    • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章