当前位置:   article > 正文

JAVA基础知识点笔记

java基础知识点笔记

一. java基础篇

1.final 关键字的作用?
  • 被 final 修饰的类不可以被继承
  • 被 final 修饰的方法不可以被重写
  • 被 final 修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内容可变.
  • 被 final 修饰的方法,JVM 会尝试将其内联,以提高运行效率,被 final 修饰的变量,在编译阶段会存入常量池中.
2.abstract class 和 interface 有什么区别?
  • 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建 abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
  • 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义 static final 成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换, instanceof 运算符可以用来决定某对象的类是否实现了接口
3. Java 集合类:list、set、queue、map、stack 的特点与用法?
  • Map
    • Map 是键值对,键 Key 是唯一不能重复的,一个键对应一个值,值可以重复。

    • TreeMap 可以保证顺序,HashMap 不保证顺序,即为无序的,

    • Map 中可以将 Key 和 Value 单独抽取出来,其中 KeySet()方法可以将所有的 keys 抽取成一个 Set,而 Values()方法可以将 map 中所有的 values 抽取成一个集合。

  • Set
    • 不包含重复元素的集合,set 中最多包含一个 null 元素,只能用 Iterator 实现单项遍历, Set 中没有同步方法。
  • List
    • 有序的可重复集合,可以在任意位置增加删除元素,用 Iterator 实现单向遍历,也可用ListIterator 实现双向遍历。
  • Queue
    • Queue 遵从先进先出原则,使用时尽量避免 add()和 remove()方法,而是使用 offer()来添加元素,使用 poll()来移除元素,它的优点是可以通过返回值来判断是否成功,LinkedList实现了 Queue 接口,Queue 通常不允许插入 null 元素。
  • Stack
    • Stack 遵从后进先出原则,Stack 继承自 Vector,它通过五个操作对类 Vector 进行扩展允许将向量视为堆栈,它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 peek()方法、测试堆栈是否为空的 empty 方法等。
  • 用法
    • 如果涉及堆栈,队列等操作,建议使用 List。
    • 对于快速插入和删除元素的,建议使用 LinkedList。如果需要快速随机访问元素的,建议使用ArrayList。
4.说出 ArrayList,Vector, LinkedList 的存储性能和特性?
  • ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差,而 LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
5.内存泄漏和内存溢出?
  • 内存泄漏(memoryleak),是指应用程序在申请内存后,无法释放已经申请的内存空间,一次内存泄漏危害可以忽略,但如果任其发展最终会导致内存溢出(outofmemory)。如读取文件后流要进行及时的关闭以及对数据库连接的释放。

  • 内存溢出(outofmemory)是指应用程序在申请内存时,没有足够的内存空间供其使用。如我们在项目中对于大批量数据的导入,采用分批量提交的方式。

7. int 和 Integer 的区别?
  • Integer 是 int 的包装类型,在拆箱和装箱中,二者自动转换.int 是基本类型,直接存数值;而 integer 是对象;用一个引用指向这个对象.由于 Integer 是一个对象,在 JVM 中对象需要一定的数据结构进行描述,相比 int 而言,其占用的内存更大一些.
8. String、StringBuilder、StringBuffer 区别?
String字符串常量不可变使用字符串拼接时是不同的 2 个空间
StringBuffer字符串变量可变线程安全字符串拼接直接在字符串后追加
StringBuilder 字符串变量可变非线程安全字符串拼接直接在字符串后追加
  • StringBuilder 执行效率高于 StringBuffer 高于 String.
  • String 是一个常量,是不可变的,所以对于每一次+=赋值都会创建一个新的对象,StringBuffer 和 StringBuilder 都是可变的,当进行字符串拼接时采用 append 方法,在原来的基础上进行追加,所以性能比 String 要高,又因为 StringBuffer是线程安全的而 StringBuilder 是线程非安全的,所以 StringBuilder 的效率高于 StringBuffer.
  • 对于大数据量的字符串的拼接,采用 StringBuffer,StringBuilder.
9. Hashtable 和 Hashmap 的区别?
  • HashTable 线程安全,HashMap 非线程安全2、Hashtable 不允许 null 值(key 和 value 都不可以),HashMap 允许 null 值(key 和 value 都可以)。
    两者的遍历方式大同小异,Hashtable 仅仅比 HashMap 多一个 elements 方法。
10. 说几个常见的编译时异常?
  • SQLException 提供有关数据库访问错误或其他错误的信息的异常。
    IOexception 表示发生了某种 I / O 异常的信号。此类是由失败或中断的 I / O 操作产生的
    一般异常类 FileNotFoundException 当试图打开指定路径名表示的文件失败时,抛出此异常。
    ClassNotFoundException 找不到具有指定名称的类的定义。
    EOFException 当输入过程中意外到达文件或流的末尾时,抛出此异常。
11. 方法重载的规则?
  • 方法名一致,参数列表中参数的顺序,类型,个数不同。重载与方法的返回值无关,存在于父类和子类,同类中。可以抛出不同的异常,可以有不同修饰符。
12. 方法重写的规则?
  • 参数列表、方法名、返回值类型必须完全一致,构造方法不能被重写;
  • 声明为 final 的方法不能被重写;
  • 声明为 static 的方法不存在重写(重写和多态联合才有意义);
  • 访问权限不能比父类更低;
  • 重写之后的方法不能抛出更宽泛的异常
  • 子类无法重写父类的私有方法
13. throw 和 throws 的区别?
  • throw:
    throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。throw 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常。
  • throws:
    throws 语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的
  • 异常的类型。throws 表示出现异常的一种可能性,并不一定会发生这种异常。
14. 抽象类和接口的区别?
  • 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
  • 类可以实现很多个接口,但是只能继承一个抽象类
  • 类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
  • 抽象类可以在不提供接口方法实现的情况下实现接口。
  • Java 接口中声明的变量默认都是 final 的。抽象类可以包含非 final 的变量。
  • Java 接口中的成员函数默认是 public 的。抽象类的成员函数可以是 private,protecte或者是 public 。
  • 接口是绝对抽象的,不可以被实例化(java 8 已支持在接口中实现默认的方法)。抽象类也不可以被实例化,但是,如果它包含 main 方法的话是可以被调用的。
15. Java 的基础类型和字节大小? bit。
byteshortintlongfloatdoublecharboolean
8位16 位32位64 位32位64位16位使用八分之一个字节
16. 四个访问修饰符合访问级别?

public、protected , 没有访问修饰符、private

17. String 和 StringBuffer 的区别?
  • String 和 StringBuffer 主要区别是性能:String 是不可变对象,每次对 String 类型进行操作都等同于产生了一个新的 String 对象,然后指向新的 String 对象.所以尽量不要对 String 进行大量的拼接操作,否则会产生很多临时对象,导致 GC 开始工作,影响系统性能.
    StringBuffer 是对象本身操作,而不是产生新的对象,因此在有大量拼接的情况下,我们建议使用 StringBuffer(线程安全).
18. HashSet 的底层实现是什么?
  • HashSet 的实现是依赖于 HashMap 的,HashSet 的值都是存储在 HashMap 中的。在 HashSet 的构造法中会初始化一个 HashMap 对象,HashSet 不允许值重复。
    因此,HashSet 的值是作为 HashMap 的 key 存储在 HashMap 中的,当存储的值已经存在时返回 false。
19. 抽象类的意义?
  • 抽象类的意义可以用三句话来概括: 1、为其他子类提供一个公共的类型2、封装子类中重复定义的内容
  • 定义抽象方法,子类虽然有不同的实现,但是定义时一致的
20. 你为什么重写 equals 时必须重写 hashCode 方法?
  • hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。如果两个对象相等,则 hashcode 一定也是相同的如果两个对象相等,对两个对象分别调用 equals 方法都返回 true 如果两个对象有相同的 hashcode 值,它们也不一定是相等的因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据).
21. HashSet 和 TreeSet 有什么区别?
  • HashSet 是由一个 hash 表来实现的,因此,它的元素是无序的。add(),remove(),contains()
    方法的时间复杂度是 O(1)。TreeSet 是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是 O(logn)。
23. 数组在内存中如何分配?
  • 当一个对象使用 new 关键字创建的时候,会在堆上分配内存空间,然后才返回到对象的引用。这对数组来说也是一样的,因为数组也是一个对象,简单的值类型的数组,每个数组成员是一个引用(指针)引用到栈上的空间。
24. Java 中怎么创建一个不可变对象?
  • 对象的状态在构造函数之后都不能被修改,任何修改应该通过创建一个新对象来实现.

  • 所有的对象属性应该都设置为 final

  • 对象创建要正确,例如:对象的应用不能在构造函数中被泄露出去

  • 对象要设置为 final,确保不要继承的 Class 修改了 immutability 特性

25. Java 中 ++ 操作符是线程安全的吗?
  • 不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交差。
27. Java 中==和 equals()的区别?
  • ==既可以比较基本数据类型,也可以比较引用数据类型
  • ==在比较基本数据类型时, 比较的是值, 在比较引用数据类型时, 比较对象的地址
  • equals只能比较引用数据类型, 比较对象中的内容是否相同, 在没有重写的情况下也是比较对象的地址
28. final、finalize 和 finally 的不同之处?
  • final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally 是异常处理语句结构的一部分,表示总是执行。 finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,
    可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
29. Java 的多态表现在哪里?
  • 多态要有动态绑定,否则就不是多态,方法重载也不是多态(因为方法重载是编译期决定好的,没有后期也就是运行期的动态绑定)
  • 当满足这三个条件:1、子父类关系 2、有重写 3、要有父类引用指向子类对象
30. 静态类型有什么特点?
  • 静态的属性:随着类的加载而加载,该属性不在属于某个对象,属于整个类
  • 静态的方法:直接用类名调用,静态方法里不能访问非静态成员变量
  • 静态只能访问静态
31.Java 创建对象的几种方式?
  • new 创建新对象
  • 通过反射机制
  • 采用 clone 机制
  • 通过序列化机制 ObjectInputStream
32.Object 中有哪些公共方法?
  • Object 是所有类的父类,任何类都默认继承 Object clone 保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。
  • equals 在 Object 中与==是一样的,子类一般需要重写该方法。
  • hashCode 该方法用于哈希查找,重写了 equals 方法一般都要重写 hashCode 方法。这个方法在一些具有哈希功能的Collection 中用到。
  • getClass 方法,获得运行时类型
  • wait 使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。
  • wait()方法一直等待,直到获得锁或者被中断。
  • wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
33.&和&&的区别?
  • &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。
34.在.java 源文件中可以有多个类吗(内部类除外)?
  • 一个.java 源文件中可以包括多个类(不是内部类),但是单个文件中只能有一个 public 类,并且该 public 类必须与文件名相同
35.如何正确的退出多层嵌套循环?
  • break;

  • 使用别名

36.内部类有什么作用?
  • 内部类可以很好的实现隐藏,一般的非内部类,是不允许有 private 与 protected
    权限的,但内部类可以

  • 内部类拥有外围类的所有元素的访问权限

  • 可是实现多重继承

  • 可以避免修改接口而实现同一个类中两种同名方法的调用

38.String 是基本数据类型吗?
  • 基本数据类型包括 byte、int、char、long、float、double、boolean 和 short。 java.lang.String 类是 final 类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用 StringBuffer 类
39. static 的用法?
  • Static 可以修饰内部类、方法、变量、代码块;Static 修饰的类是静态内部类;Static 修饰的方法是静态方法,表示该方法属于当前类的,而不属于某个对象的,静态方法也不能被重写,可以直接使用类名来调用。在 static 方法中不能使用 this 或者 super 关键字。
  • Static 修饰变量是静态变量或者叫类变量,静态变量被所有实例所共享,不会依赖于对象。静态变量在内存中只有一份拷贝,在 JVM 加载类的时候,只为静态分配一次内存。
    Static 修饰的代码块叫静态代码块,通常用来做程序优化的。静态代码块中的代码在整个类加载的时候只会执行一次。静态代码块可以有多个,如果有多个,按照先后顺序依次执行。
40. 什么是值传递和引用传递?
  • 基本数据类型传递值, 引用数据类型传递地址
  • 基本数据类型之间的传递就是值传递,引用数据类型之间的传递就是引用传递
41. 重载和重写的区别?
  • 方法的重写 Overriding 和重载 Overloading 是 Java 多态性的不同表现。重写 Overriding
    是父类与子类之间多态性的一种表现,重载 Overloading 是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。
42. 成员变量和局部变量的区别有哪些?
  • 从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;成员变量和局部变量都能被 final 所修饰;
  • 从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存
  • 从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
  • 成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被 final 修饰但没有被 static 修饰的成员变量必须显示地赋值);而局部变量则不会自动赋值。
43. 静态方法和实例方法有何不同?
  • 静态方法和实例方法的区别主要体现在两个方面:
    在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
  • 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制
44.什么是多态?
  • 允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
45.多态的优点?
  • 可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆 Circle 类工作,对其他任何圆形几何体,如圆环,也同样工作。
    可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
46. 多态存在的三个必要条件?
  • 要有继承。
  • 要有方法的重写。
  • 父类引用指向子类对象(对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接)
47. TreeMap、HashMap、LindedHashMap 的区别?
  • LinkedHashMap 可以保证 HashMap 集合有序。存入的顺序和取出的顺序一致。TreeMap 实现
    SortMap 接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时,得到的记录是排过序的。HashMap 不保证顺序,即为无序的,具有很快的访问速度。HashMap 最多只允许一条记录的键为 Null;允许多条记录的值为 Null;HashMap 不支持线程的同步。
48.Java(OOP)面向对象的特征有哪些方面?
  • 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

  • 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段

  • 封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。

  • 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当 A 系统访问 B 系统提供的服务时,B 系统有多种提供服务的方式,但一切对 A 系统来说都是透明的。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1. 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2. 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)

49.列出一些常见的运行时异常?
  • ArithmeticException(算术异常)
  • ClassCastException (类转换异常)
  • IllegalArgumentException (非法参数异常)
  • IndexOutOfBoundsException (下标越界异常)
  • NullPointerException (空指针异常)
  • SecurityException (安全异常)
50.什么是反射?
  • 反射就是动态加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能成为 Java 反射机制。
51.反射的作用?
  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法
52.获取 class 的三种方式?
  • 对象调用 getClass() 方法来获取;类名.class 的方式得到;通过 Class 对象的 forName()
    静态方法来获取
53.break 和 continue 的区别?
  • break 和 continue 都是用来控制循环的语句。break 用于完全结束一个循环,跳出循环体执行循环后面的语句。continue 用于跳过本次循环,继续下次循环。
54.运行时异常与一般异常有何异同?
  • 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
55.List、Map、Set 三个接口存取元素时,各有什么特点?
  • List 以特定索引来存取元素,可以有重复元素。Set 不能存放重复元素(用对象的 equals() 方法来区分元素是否重复)。Map 保存键值对(key-value pair)映射,映射关系可以是一对一或多对一
56.Collection 和 Collections 的区别?
  • Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.
    Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
57.Error 和 Exception 有什么区别?
  • error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
58.EJB 的生命周期,以及如何管理事务?
  • SessionBean:Stateless Session Bean 的生命周期是由容器决定的,当客户机发出请求要建立一个 Bean 的实例时,EJB 容器不一定要创建一个新的 Bean 的实例供客户机调用,而是随便找一个现有的实例提供给客户机。当客户机第一次调用一个 Stateful Session Bean 时,容器必须立即在服务器中创建一个新的 Bean 实例,并关联到客户机上,以后此客户机调用 Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的 Bean 实例。EntityBean:Entity Beans 能存活相对较长的时间,并且状态是持续的。只要数据库中的数据存在,Entity beans 就一直存活。而不是按照应用程序或者服务进程来说的。即使 EJB
    容器崩溃了,Entity beans 也是存活的。Entity Beans 生命周期能够被容器或者 Beans 自
    己管理。EJB 通过以下技术管理实务:对象管理组织(OMG)的对象实务服务(OTS),Sun Microsystems 的 Transaction Service(JTS)、Java Transaction API(JTA),开发组(X/Open)
    的 XA 接口。
59.Comparable 和 Comparator 接口的区别?
  • Comparable 接口只包含一个 compareTo()方法。这个方法可以个给两个对象排序。具体来说,它返回负数,0,正数来表明输入对象小于,等于,大于已经存在的对象。Comparator 接口包含 compare()和 equals()两个方法。
60.switch 能否作用在 byte、long、string 上?
  • switch 可作用在 char、byte、short、int switch 可作用于 char、byte、short、int 的包装类上
    switch 不可作用于 long、double、float、boolean,包括他们的包装类 switch 中可以是字符串类型,String(Java1.7 以后才可以作用在 String 上) switch 可以是枚举类型(JDK1.5 之后)
61.jdk 中哪些类是不能继承的?
  • 不能继承的是类是那些用 final 关键字修饰的类。一般比较基本的类型或防止扩展类无意间破坏原来方法的实现的类型都应该是 final 的,在 jdk 中 System,String,StringBuffer 等都是基本类型。
62.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?
  • Set 里的元素是不能重复的,元素重复与否是使用 equals()方法进行判断的。equals()和==方法决定引用值是否指向同一对象 equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
63.JDK 和 JRE 的区别是什么?
  • Java 运行时环境(JRE)是将要执行 Java 程序的 Java 虚拟机。它同时也包含了执行 applet 需要的浏览器插件。Java 开发工具包(JDK)是完整的 Java 软件开发包,包含了 JRE,编译器和其他的工具(比如:JavaDoc,Java 调试器),可以让开发者开发、编译、执行 Java 应用程序。
64.是否可以在 static 环境中访问非 static 变量?
  • static 变量在 Java 中是属于类的,它在所有的实例中的值是一样的。当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化。如果你的代码尝试不用实例来访问非 static 的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
65.Java 支持多继承么?
  • 不支持,Java 不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。
66.什么是迭代器(Iterator)?
  • Iterator 接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。
    克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
67.Iterator 和 ListIterator 的区别是什么?
  • 下面列出了他们的区别:
    Iterator 可用来遍历 Set 和 List 集合,但是 ListIterator 只能用来遍历 List。 Iterator 对集合只能是前向遍历,ListIterator 既可以前向也可以后向。
    ListIterator 实现了 Iterator 接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
69.List, Set, Map 是否继承自 Collection 接口?
  • 只有 List 和 Set 接口继承于 Collection 接口,Map 是与 Collection 并列的接口概念
70.字符串常量池到底存在于内存空间的哪里?
  • jdk 6.0 字符串常量池在方法区,方法区的具体体现可以看做是堆中的永久区。 jdk 7.0 java 虚拟机规范中不再声明方法区,字符串常量池存放在堆空间中 jdk 8.0 java 虚拟机规范中又声明了元空间,字符串常量池存放在元空间中
72.用哪两种方式来实现集合的排序?
  • 你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有顺序的的集合,如 list,然后通过 Collections.sort() 来排序。
73.说出 JDK 1.7 中的三个新特性?
  • 虽然 JDK 1.7 不像 JDK 5 和 8 一样的大版本,但是,还是有很多新的特性,如 try-with-resource 语句,这样你在使用流或者资源的时候,就不需要手动关闭,Java 会自动关闭。Fork-Join 池某种程度上实现 Java 版的 Map-reduce。允许 Switch 中有 String 变量和文本。菱形操作符(<>)用于类型推断,不再需要在变量声明的右边申明泛型,因此可以写出可读写更强、更简洁的代码。另一个值得一提的特性是改善异常处理,如允许在同一个 catch 块中捕获多个异常。
74.说出 5 个 JDK 1.8 引入的新特性?
  • Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: Lambda 表达式,允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用 扩展方法,现在,接口中可以有静态、默认方法。 重复注解,现在你可以将相同的注解在同一类型上使用多次。
75.ArrayList 源码分析?(背诵)
  • ArrayList 是一种变长的集合类,基于定长数组实现,使用默认构造方法初始化出来的容量是 10 ( 1.7 之后都是延迟初始化,即第一次调用 add 方法添加元素的时候才将 elementData 容量初始化为 10)。
  • ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个更大的数组。ArrayList 扩容的长度是原长度的 1.5 倍
  • 由于 ArrayList 底层基于数组实现,所以其可以保证在 O(1) 复杂度下完成随机查找操作。
  • ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的异常或错误。
  • 顺序添加很方便
  • 删除和插入需要复制数组,性能差(可以使用 LinkindList)
  • Integer.MAX_VALUE - 8 :主要是考虑到不同的 JVM,有的 JVM 会在加入一些数据头,当扩容后的容量大于 MAX_ARRAY_SIZE,我们会去比较最小需要容量和 MAX_ARRAY_SIZE 做比较,如果比它大, 只能取 Integer.MAX_VALUE,否则是 Integer.MAX_VALUE -8。 这个是从 jdk1.7 开
    始才有的 new Object[]
76.HashMap 源码分析?(背诵)
  • jdk1.8 之前 list + 链表
  • jdk1.8 之后 list + 链表(当链表长度到 8 时,转化为红黑树)
  • HashMap 的扩容因子
    默认 0.75,也就是会浪费 1/4 的空间,达到扩容因子时,会将 list 扩容一倍,0.75 是时间与空间一个平衡值;
77. ConcurrentHashMap 源码分析?(背诵)
  • ConcurrentHashMap 所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。有些方法需要跨段,比如 size()和 containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。这里“按顺序”是很重要的,否则极有可能出现死锁,在 ConcurrentHashMap 内部,段数组是 final 的,并且其成员变量实际上也是 final 的,但是,仅仅是将数组声明为 final 的并不保证数组成员也是 final 的,这需要实现上的保证。这可以确保不会出现死锁,因为获得锁的顺序是固定的。
  • ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成。Segment 是一种可重入锁 ReentrantLock,在 ConcurrentHashMap 里扮演锁的角色,HashEntry 则用于存储键值对数据。一个 ConcurrentHashMap 里包含一个 Segment 数组,Segment 的结构和 HashMap
    类似,是一种数组和链表结构, 一个 Segment 里包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素,每个 Segment 守护者一个 HashEntry 数组里的元素,当对 HashEntry 数组的数据进行修改时,必须首先获得它对应的 Segment 锁。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/201965
推荐阅读
相关标签
  

闽ICP备14008679号