Java基础面试题

基础&进阶

1.什么是Java

       Java是一门面向对象的高级编程语言,不仅吸收了C++语言的各种优点,比如继承了C++语言面向对象的 技术核心。还摒弃了C++里难以理解的多继承、指针等概念,同时也增加了垃圾回收机制,释放掉不 被使用的内存空间,解决了管理内存空间的烦恼。

       因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地 实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

2.Java的特点有哪些

        Java 语言是一种分布式的面向对象语言,具有面向对象、平台无关性、简单性、解释执行、多线程、安 全性等很多特点,下面针对这些特点进行逐一介绍。

1. 面向对象 

        Java 是一种面向对象的语言,它对对象中的类、对象、继承、封装、多态、接口、包等均有很好的支 持。为了简单起见,Java 只支持类之间的单继承,但是可以使用接口来实现多继承。使用 Java 语言开发 程序,需要采用面向对象的思想设计程序和编写代码。

2. 平台无关性

        平台无关性的具体表现在于,Java 是“一次编写,到处运行(Write Once,Run any Where)”的语言, 因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 的虚拟机机制。在引入 虚拟机之后,Java 语言在不同的平台上运行不需要重新编译。 Java 语言使用 Java 虚拟机机制屏蔽了具体平台的相关信息,使得 Java 语言编译的程序只需生成虚拟机 上的目标代码,就可以在多种平台上不加修改地运行。

3. 简单性

        Java 语言的语法与 C 语言和 C++ 语言很相近,使得很多程序员学起来很容易。对 Java 来说,它舍弃了 很多 C++ 中难以理解的特性,如操作符的重载和多继承等,而且 Java 语言不使用指针,加入了垃圾回 收机制,解决了程序员需要管理内存的问题,使编程变得更加简单。

4. 解释执行

        Java 程序在 Java 平台运行时会被编译成字节码文件,然后可以在有 Java 环境的操作系统上运行。在运 行文件时,Java 的解释器对这些字节码进行解释执行,执行过程中需要加入的类在连接阶段被载入到运 行环境中。

5. 多线程

        Java 语言是多线程的,这也是 Java 语言的一大特性,它必须由 Thread 类和它的子类来创建。Java 支持 多个线程同时执行,并提供多线程之间的同步机制。任何一个线程都有自己的 run() 方法,要执行的方 法就写在 run() 方法体内。

6. 分布式

        Java 语言支持 Internet 应用的开发,在 Java 的基本应用编程接口中就有一个网络应用编程接口,它提 供了网络应用编程的类库,包括 URL、URLConnection、Socket 等。Java 的 RIM 机制也是开发分布式 应用的重要手段。

7. 健壮性

        Java 的强类型机制、异常处理、垃圾回收机制等都是 Java 健壮性的重要保证。对指针的丢弃是 Java 的 一大进步。另外,Java 的异常机制也是健壮性的一大体现。

8. 高性能

        Java 的高性能主要是相对其他高级脚本语言来说的,随着 JIT(Just in Time)的发展,Java 的运行速度 也越来越高。

9. 安全性

        Java 通常被用在网络环境中,为此,Java 提供了一个安全机制以防止恶意代码的攻击。除了 Java 语言 具有许多的安全特性以外,Java 还对通过网络下载的类增加一个安全防范机制,分配不同的名字空间以 防替代本地的同名类,并包含安全管理机制。

        Java 语言的众多特性使其在众多的编程语言中占有较大的市场份额,Java 语言对对象的支持和强大的 API 使得编程工作变得更加容易和快捷,大大降低了程序的开发成本。Java 的“一次编写,到处执行”正是 它吸引众多商家和编程人员的一大优势。

3.JDK,JRE和JVM的区别

1. JDK

        JDK(Java SE Development Kit),Java标准的开发包,提供了编译、运行Java程序所需要的各种工具 和资源,包括了Java编译器、Java运行时环境、以及常用的Java类库等。

2. JRE

        JRE(Java Runtime Environment),Java运行时环境,用于解释执行Java的字节码文件。普通用户只 需要安装JRE来运行Java程序即可,而作为一名程序员必须安装JDK,来编译、调试程序。

3. JVM

        JVM(Java Virtual Mechinal),Java虚拟机是JRE的一部分。它是整个Java实现跨平台的核心,负责 解释执行字节码文件,是可运行Java字节码文件的虚拟计算机。所有平台上的JVM向编译器提供相同的 接口,而编译器只需要面向虚拟机,生成虚拟机能识别的代码,然后由虚拟机来解释执行。

总结

        1. JDK 用于开发,JRE 用于运行java程序 ;如果只是运行Java程序,可以只安装JRE,无序安装JDK。 

        2. JDk包含JRE,JDK 和 JRE 中都包含 JVM。

        3. JVM 是 Java 编程语言的核心并且具有平台独立性。

4. Java有哪些数据类型

        Java的数据类型分为基本数据类型和引用类型

        1.基本数据类型

        Java中有 8 种基本数据类型,分别为:

                6 种数字类型 (四个整数形,两个浮点型):byte、short、int、long、float、double

                1 种字符类型:char

                1 种布尔型:boolean。

        2.引用数据类型

                引用数据有三种类型:类、接口和数组

                简单来说,只要不是基本数据类型.都是引用数据类型。

5.==和equals区别

        1. ==操作符
                
==操作符专门用来比较变量的值是否相同。

                基本数据类型:比较的是他们的是否相同。
                引用数据类型:比较的是他们的内存地址是否同一地址。
                引用类型对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。

        2. equals方法
               
 equals方法常用来比较对象的内容是否相同。

6.int和integer的区别(有了基本数据类型为什么还要有封装类)

        两者的区别主要体现在以下几个方面:
        1、数据类型不同:
int 是基础数据类型,而 Integer 是包装数据类型;
        2、默认值不同:int 的默认值是 0,而 Integer 的默认值是 null;
        3、内存中存储的方式不同:int 在内存中直接存储的是数据值,而 Integer 实际存储的是对象引用,当 new 一个 Integer 时实际上是生成一个指针指向此对象;
        4、实例化方式不同:Integer 必须实例化才可以使用,而 int 不需要;
        5、变量的比较方式不同:int 可以使用 == 来对比两个变量是否相等,而 Integer 一定要使用 equals 来比较两个变量是否相等。

二者的区别:

        1. 声明方式不同:基本类型不使用new关键字,而包装类型需要使用new关键字来在堆中分配存储空 间;

        2. 存储方式及位置不同:基本类型是直接将变量值存储在栈中,而包装类型是将对象放在堆中,然后 通过引用来使用;

        3. 初始值不同:基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null;         4. 使用方式不同:基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用 到。

7.a=a+b与a+=b有什么区别吗?

        += 操作符会进行隐式自动类型转换,而 a=a+b则不会自动进行类型转换

8. final 在 Java 中有什么作用?

        final作为Java中的关键字可以用于三个地方。用于修饰类、实例变量和类方法。

        特征:凡是引用final关键字的地方皆不可修改!

        (1)修饰类:表示该类不能被继承;

        (2)修饰方法:表示方法不能被重写;

        (3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

9.浅析final finally finalize的区别

        1.性质不同

                (1)final为关键字;

                (2)finalize()为方法;

                (3)finally为为区块标志,用于try语句中;

        2. 作用

        (1)final为用于标识常量的关键字,final标识的关键字存储在常量池中(在这里final常量的具体用法将在下面进行介绍);

        (2)finalize()方法在Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象 进行垃圾回收,类似于C++中的析构函数;用户自定义时,用于释放对象占用的资源(比如进行 I/0操作);

        (3)finally{}用于标识代码块,与try{ }进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行 .

10.什么是java序列化,如何实现java序列化?或者请解释 Serializable接口的作用。

        我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如, 要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java 对象变成某个格式的字节流再传输。

        但是,JRE本身就提供了这种支持,我们可以调用 OutputStreamwriteObject 方法来做,如果要让 java帮我们做,要被传输的对象必须实现 serializable 接口,这样,javac编译时就会进行特殊处理, 编译的类才可以被 writeObject 方法操作,这就是所谓的序列化

        需要被序列化的类必须实现 Serializable 接口,该接口是一个mini接口,其中没有需要实现方法,implements Serializable只是 为了标注该对象是可被序列化的。 例如,在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬 盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输,被传输的对象就 必须实现Serializable接口。

11.什么是内部类,内部类的特点

        内部类的定义 将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

        内部类的作用:

        1、成员内部类 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态 成员)。 当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问 的是成员内部类的成员。

        2、局部内部类 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局 部内部类的访问仅限于方法内或者该作用域内。

        3、匿名内部类 匿名内部类就是没有名字的内部类

         4、静态内部类 指被声明为static的内部类,他可以不依赖内部类而实例,而通常的内部类需要实例化外 部类,从而实例化。静态内部类不可以有与外部类有相同的类名。不能访问外部类的普通成员变量,但是可以访问静态成员变量和静态方法(包括私有类型) 一个 静态内部类去掉static 就是成员内部类,他 可以自由的引用外部类的属性和方法,无论是静态还是非静态。但是不可以有静态属性和方法

12.Excption与Error的区别。或异常你了解吗?

        Throwable 类是Java程序执行过程中发生的异常事件对应的类的根父类

        Java可抛出(Throwable)的结构分为三种类型:被检查的异常(CheckedException),运行时异常 (RuntimeException),错误(Error)

        1、运行时异常

        定义:RuntimeException及其子类都被称为运行时异常。

        特点:Java编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明 抛出它",也"没有用try-catch语句捕获它",还是会编译通过。例如,除数为零时产生的 ArithmeticException异常,数组越界时产生的IndexOutOfBoundsException异常,fail-fast机制产生的 ConcurrentModificationException异常(java.util包下面的所有的集合类都是快速失败的,“快速失败” 也就是fail-fast,它是Java集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有 可能会产生fail-fast机制。记住是有可能,而不是一定。例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而 不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异 常,从而产生fail-fast机制,这个错叫并发修改异常。Fail-safe,java.util.concurrent包下面的所有的类 都是安全失败的,在遍历过程中,如果已经遍历的数组上的内容变化了,迭代器不会抛出 ConcurrentModificationException异常。如果未遍历的数组上的内容发生了变化,则有可能反映到迭 代过程中。这就是ConcurrentHashMap迭代器弱一致的表现。ConcurrentHashMap的弱一致性主要是 为了提升效率,是一致性与效率之间的一种权衡。要成为强一致性,就得到处使用锁,甚至是全局锁, 这就与Hashtable和同步的HashMap一样了。)等,都属于运行时异常。

        常见的五种运行时异常:

        ClassCastException (类转换异常)

        IndexOutOfBoundsException (数组越界)

        NullPointerException (空指针异常)

        ArrayStoreException (数据存储异常,操作数组是类型不一致)

        BufferOverflowException

        2、被检查异常 (编译时异常)

        定义:Exception类本身,以及Exception的子类中除了"运行时异常"之外的其它子类都属于被检查异常。 特点 : Java编译器会检查它。 此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获 处理,否则不能通过编译。例如,CloneNotSupportedException就属于被检查异常。 当通过clone()接口去克隆一个对象,而该对象对应的类没有实现Cloneable接口,就会抛出 CloneNotSupportedException异常。被检查异常通常都是可以恢复的。 如: IOException FileNotFoundException SQLException 被检查的异常适用于那些不是因程序引起的错误情况,比如:读取文件时文件不存在引发的 FileNotFoundException 。然而,不被检查的异常通常都是由于糟糕的编程引起的,比如:在对象引 用时没有确保对象非空而引起的 NullPointerException 。

        3、错误

        定义 : Error类及其子类。

        特点 : 和运行时异常一样,编译器也不会对错误进行检查。 当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生错误。程序本身无法修复这 些错误的。例如,VirtualMachineError就属于错误。出现这种错误会导致程序终止运行。 OutOfMemoryError、ThreadDeath。 Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等

13.两个对象的 hashCode() 相同, 那么 equals() 也一定为 true 吗?

不对,两个对象的 hashCode() 相同,equals() 不一定 true。

如果两个对象是相等的,它们的 equals() 方法应该要返回 true,它们的 hashCode() 需要返回相同的结果

14.面向对象的特征

        面向对象的编程语言有封装、继承 、多态三大特性。

        1. 封装: 把描述一个对象的属性和行为的代码封装在一个模块中,也就是一个类中,属性用变量定 义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。

        2. 抽象: 把现实生活中的对象抽象为类。分为过程抽象和数据抽象 数据抽象 -->鸟有翅膀,羽毛等(类的属性) 过程抽象 -->鸟会飞,会叫(类的方法)

                1. 继承:子类继承父类的特征和行为。子类可以有父类的方法,属性(非private)。子类也可以对父 类进行扩展,也可以重写父类的方法。缺点就是提高代码之间的耦合性。

                2. 多态: 多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定(比如:向上转型,只有运行才能确定其对象属性)。方法覆盖和重载体现了多态性。

15.你对多态有什么理解

        1. 多态是继封装、继承之后,面向对象的第三大特性。

        2. 多态现实意义理解:

        现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。

         Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一 个Student的对象便既是Student,又是Person。

1. 多态体现为父类引用变量可以指向子类对象。

2. 前提条件:必须有子父类关系。

16.重载和重写的区别

重写(Override)

        从字面上看,重写就是 重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列 表,返回类型(除过子类中方法的返回值是父类中方法返回值的子类时)都相同的情况下, 对方法体进行 修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。

总结:

         1.发生在父类与子类之间

        2.方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同

        3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)         4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

重载(Overload)

        在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同) 则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来 判断重载。

总结:

        1.重载Overload是一个类中多态性的一种表现

        2.重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)

        3.重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准

17.Java创建对象有几种方式?

java中提供了以下四种创建对象的方式:

        new创建新对象

        通过反射机制

        采用clone机制

        通过序列化机制

18.HashMap和HashTable、ConcurrentHashMap区别?

相同点:

        1. HashMap和Hashtable都实现了Map接口

        2. 都可以存储key-value数据

不同点:

        1. HashMap可以把null作为key或value,HashTable不可以

        2. HashMap线程不安全,效率高。HashTable线程安全,效率低。

         3. HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast 的。

19.BIO、NIO、AIO 有什么区别?

         BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并 发处理能力低。

        NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通 讯,实现了多路复用。

        AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于 事件和回调机制。

20.Files的常用方法都有哪些?

        Files. exists():检测文件路径是否存在。

        Files. createFile():创建文件。

        Files. createDirectory():创建文件夹。

        Files. delete():删除一个文件或目录。

        Files. copy():复制文件。

        Files. move():移动文件。

        Files. size():查看文件个数。

        Files. read():读取文件。

        Files. write():写入文件。

21.Java反射的作用于原理

        1、定义: 反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意个对象,都能 够调用它的任意一个方法。在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。

        这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

        2、哪里会用到反射机制?

         jdbc就是典型的反射 这就是反射。如hibernate,struts等框架使用反射实现的。

        Class.forName('com.mysql.jdbc.Driver.class');//加载MySQL的驱动类

22.反射的实现方式

        第一步:获取Class对象,有4种方法:

        1)Class.forName(“类的路径”);

        2)类名.class

        3)对象 名.getClass()

        4)基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象

23.实现Java反射的类:

        1)Class:表示正在运行的Java应用程序中的类和接口 注意: 所有获取对象的信息都需要Class类来实 现。

        2)Field:提供有关类和接口的属性信息,以及对它的动态访问权限。

        3)Constructor:提供关于 类的单个构造方法的信息以及它的访问权限

        4)Method:提供类或接口中某个方法的信息

24.反射机制的优缺点:

        优点:

        1、能够运行时动态获取类的实例,提高灵活性;

        2、与动态编译结合

        缺点:

        1、使用反射性能较低,需要解析字节码,将内存中的对象进行解析。

         解决方案:

                1、通过setAccessible(true)关闭JDK的安全检查来提升反射速度;

                 2、多次创建一个类的实例时,有缓存会快很多

                3、ReflectASM工具类,通过字节码生成的方式加快反射速度         

        2、相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)

25.Java 中 IO 流分为几种?

        按照流的流向分,可以分为输入流和输出流;

        按照操作单元划分,可以划分为字节流和字符流;

        按照流的角色划分为节点流和处理流。

        Java Io 流共涉及 40 多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的 联系, Java I0 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。         InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。         OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

字符串&集合

1.Java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有: String 、 StringBuffer 、 StringBuilder 。

String 和 StringBuffer、StringBuilder 的区别在于:

String 声明的是不可变的对象,每次操作都会生成 新的 String 对象,然后将指针指向新的 String 对象。 而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况 下最好不要使用 String。

StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的而 StringBuilder 是 非线程安全的,但 StringBuilder 的性能却高于 StringBuffer, 所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer

2.String 类的常用方法都有那些?

        indexOf():返回指定字符的索引。

        charAt():返回指定索引处的字符。

        replace():字符串替换。

        trim():去除字符串两端空白。

        split():分割字符串,返回一个分割后的字符串数组。

        getBytes():返回字符串的 byte 类型数组。

        length():返回字符串长度。

        toLowerCase():将字符串转成小写字母。

        toUpperCase():将字符串转成大写字符。

        substring():截取字符串。 equals():字符串比较。

3.List、Map、Set三个接口,存取元素时,各有什么特点?

首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个共同的父接口,叫 Collection。

        1、Set里面不允许有重复的元素

        即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,现在我要向Set 集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法 有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true, 当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取 元素时,不能细说要取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

        2、List表示有先后顺序的集合

        String s1 = "a"; String s2 = s1 + "b"; String s3 = "a" + "b"; System.out.println(s2 == "ab"); System.out.println(s3 == "ab"); String s ="a" + "b" +"c" + "d"; System.out.println(s== "abcd"); 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obje)方法时,每次加入的对 象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用 add(intindex,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List 中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集 合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个 索引指向了这个对象。List除了可以用Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以 调用get(index i)来明确说明取第几个。

        3、Map与List和Set不同

        它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对 key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应 的value,即get(Object key)返回值为key所对应的value。另外,也可以获得所有的key的结合,还可以 获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

总结

        List以特定次序来持有元素,可有重复元素。Set无法拥有重复元素,内部排序。Map保存key-value值, value可多值。

4.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?它们有何区别?

        在使用 Set 来存储元素时,Set 会调用元素的 equals() 方法来判断元素是否重复。如果两个元素的 equals() 方法返回 true,则 Set 认为这两个元素相同,后续添加的重复元素将不会被加入 Set 中。

5.ArrayList和LinkedList区别?ArrayList与Vector的区别?

ArrayList和LinkedList区别

        1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。

        2. 对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。

        3. 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

ArrayList与Vector的区别 

        两个类都实现了List接口(List接口继承了 Collection 接口),他们都是有序集合,即存储在这两个集 合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素, 并且其中的数据是允许重复的,这是与 HashSet 之类的集合的最大不同处, HashSet 之类的集合不可以 按索引号去检索其中的元素,也不允许有重复的元素。

主要包括两个方面:

         同步性: Vector 是线程安全的,也就是说是它的方法之间是线程同步的,而 ArrayList 是线程序不安全的,它 的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用 ArrayList ,因为它不考 虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用 Vector ,因为不需要我们自 己再去考虑和编写线程安全的代码。

        数据增长: ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需 要增加 ArrayList 与 Vector 的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增 加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。 Vector 默认增长为原来两倍,而 ArrayList 的增长策略在文档中没有明确规定(从源代码看到的是增 长为原来的1.5倍)。 ArrayList 与 Vector 都可以设置初始的空间大小, Vector 还可以设置增长的空 间大小,而 ArrayList 没有提供设置增长空间的方法。 总结:即Vector增长原来的一倍, ArrayList 增加原来的0.5倍。

6.ArrayList,Vector,LinkedList的存储性能和特性

ArrayListVector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入 元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据 快而插入数据慢, Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差。

LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,索引就变慢了,但是插入数据时只 需要记录本项的前后项即可,所以插入速度较快。 LinkedList 也是线程不安全的, LinkedList 提供了一些方法,使得 LinkedList 可以被当作堆栈和 队列来使用。

7.HashMap和Hashtable的区别

HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了Map接口, 主要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下, 效率要高于 Hashtable 。 HashMap 允许将null作为一个entry的key或者value,而 Hashtable 不允许。 HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey 。因为 contains方法容易让人引起误解。 Hashtable 继承自 Dictionary 类,而 HashMap 是Java1.2引进的Map interface的一个实现。 最大的不同是, Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供同步。 就 HashMap 与 HashTable 主要从三方面来说。 历史原因: Hashtable 是基于陈旧的 Dictionary 类的, HashMap 是Java 1.2引进的Map接口的一 个实现同步性: Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的值:只有 HashMap 可以让你将空值作为一个表的条目的key或value

8.Java中的同步集合与并发集合有什么区别?

同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合,不过并发集合的可扩展性更高。 在Java1.5之前程序员们只有同步集合来用且在多线程并发的时候会导致争用,阻碍了系统的扩展性。 Java5介绍了并发集合 ConcurrentHashMap不仅提供线程安全还用锁分离和内部分区等现代技术提高 了可扩展性。 不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有 他们如何实现的线程安全上。 同步 HashMap , Hashtable , HashSet , Vector , ArrayList 相比他们并发的实现 ( ConcurrentHashMap , CopyOnWriteArrayList , CopyOnWriteHashSet )会慢得多。造成如此慢的 主要原因是锁, 同步集合会把整个Map或List锁起来,而并发集合不会。并发集合实现线程安全是通过 使用先进的和成熟的技术像锁剥离。 比如 ConcurrentHashMap 会把整个Map 划分成几个片段,只对相关的几个片段上锁,同时允许多线程 访问其他未上锁的片段。 同样的, CopyOnWriteArrayList 允许多个线程以非同步的方式读,当有线程写的时候它会将整个List 复制一个副本给它。 如果在读多写少这种对并发集合有利的条件下使用并发集合,这会比使用同步集合更具有可伸缩性。

9.poll()方法和remove()方法区别?

        poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。

10.ArrayList和Array有什么区别?

        Array可以容纳基本类型和对象,而ArrayList只能容纳对象。 ArrayList 是Java集合框架类的一员,可以称它为一个动态数组. array 是静态的,所以一个数据一旦创建就 无法更改他的大小

11.Comparator和Comparable的区别?

相同点

        都是用于比较两个对象“顺序”的接口

        都可以使用Collections.sort()方法来对对象集合进行排序

不同点

        Comparable位于java.lang包下,而Comparator则位于java.util包下

        Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序

12.HashMap的实现原理

HashMap是基于哈希表实现的map,哈希表(也叫关联数组)一种通用的数据结构,是Java开发者常用 的类,常用来存储和获取数据,功能强大使用起来也很方便,是居家旅行...不对,是Java开发需要掌握 的基本技能,也是面试必考的知识点,所以,了解HashMap是很有必要的。

原理

简单讲解下HashMap的原理:HashMap基于Hash算法,我们通过put(key,value)存储,get(key)来获 取。当传入key时,HashMap会根据key.hashCode()计算出hash值,根据hash值将value保存在bucket 里。当计算出的hash值相同时怎么办呢,我们称之为Hash冲突,HashMap的做法是用链表和红黑树存 储相同hash值的value。当Hash冲突的个数比较少时,使用链表,否则使用红黑树。

内部存储结构

HashMap类实现了Map< K, V>接口,主要包含以下几个方法:

V put(K key, V value)

V get(Object key)

V remove(Object key)

Boolean containsKey(Object key)

HashMap使用了一个内部类Node< K, V>来存储数据

put操作

        1. 对key的hashCode()做hash,然后再计算index;

        2. 如果没碰撞直接放到bucket里;

        3. 如果碰撞了,以链表的形式存在buckets后;

        4. 如果碰撞导致链表过长(大于等于TREEIFY_THRESHOLD),就把链表转换成红黑树;

        5. 如果节点已经存在就替换old value(保证key的唯一性)

        6. 如果bucket满了(超过load factor*current capacity),就要resize。

get操作 

         1. bucket里的第一个节点,直接命中;

        2. 如果有冲突,则通过key.equals(k)去查找对应的entry

        3. 若为树,则在树中通过key.equals(k)查找,O(logn);

        4. 若为链表,则在链表中通过key.equals(k)查找,O(n)。

13.HashMap自动扩容

        如果在初始化HashMap中没有指定初始容量,那么默认容量为16,但是如果后来HashMap中存放的数 量超过了16,那么便会有大量的hash冲突;在HashMap中有自动扩容机制,如果当前存放的数量大于 某个界限,HashMap便会调用resize()方法,扩大HashMap的容量。

        当hashmap中的元素个数超过数组大小loadFactor时,就会进行数组扩容,loadFactor的默认值为 0.75,也就是说,默认情况下,数组大小为16,那么当hashmap中元素个数超过160.75=12的时候,就 把数组的大小扩展为2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常 消耗性能的操作,所以如果我们已经预知hashmap中元素的个数,那么预设元素的个数能够有效的提高 hashmap的性能。

        HashMap的capacity必须满足是2的N次方,如果在构造函数内指定的容量n不满足,HashMap会通过下面 的算法将其转换为大于n的最小的2的N次方数。

14.HashMap和HashTable有何不同?

(1)HashMap允许key和value为null,而HashTable不允许。

(2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程 环境。

(3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从 HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。

(4)HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的 Enumeration进行遍历,它不支持fail-fast。 (5)HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用 CocurrentHashMap。

  • 45
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Java基础面试题可以包括很多方面的知识,以下是一些常见的问题和答案: 1. 什么是JNI? JNI是Java Native Interface的缩写,它提供了一组API,用于实现Java和其他语言(主要是C和C++)之间的通信。JNI允许Java代码与本地已编译的代码进行交互,尽管这可能会降低平台的可移植性。\[2\] 2. JNI的步骤是什么? JNI的步骤包括以下几个部分: - 在Java类中编写带有native声明的方法。 - 使用javac命令编译Java类。 - 使用javah命令生成头文件。 - 使用C/C++实现本地方法。 - 生成动态连接库。 - 执行Java代码。\[1\] 3. 请解释一下super.getClass()方法的作用。 super.getClass()方法是用于获取当前对象的父类的Class对象。在给定的示例中,Test类继承自Date类,当调用super.getClass().getName()时,会返回Test类的名称。因此,输出的结果是"Test"。\[3\] 希望以上回答能够帮助你理解Java基础面试题。如果你有其他问题,请随时提问。 #### 引用[.reference_title] - *1* *2* [Java基础常见面试题及详细答案(总结40个)](https://blog.csdn.net/ayouki123456/article/details/124983188)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Java基础面试题50题](https://blog.csdn.net/weixin_38337769/article/details/100560220)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值