1、面向对象的特征有哪些方面
抽象: 抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。
例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。
抽象包括行为抽象和状态抽象两个方面。
例如,定义一个Person类,如下:
class Person{ String name; int age; }
人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽象,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。
1)继承: 就是子类继承父类的特征和和行为,使得子类对象(实例)具有父类的实例域和方法,使得子类具有父类相同的行为,还可以以此基础添加新方法和域来满足需求。
2)封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
3)多态: 是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。
多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。
2、String是最基本的数据类型吗?
String 不属于基础类型,基础类型有 8 种:byte、boolean、char、short、int、float、long、double,而 String 属于对象。
3、int 和 Integer 有什么区别?
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。int 是 java 的原始数据类型,Integer是java 为 int 提供的封装类。
1)int默认值是0,Integer默认值是null;
2)int类型直接存储数值,Integer需要实例化对象,指向对象的地址。
4、java 中操作字符串都有哪些类?它们之间有什么区别?
操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
5、String str="i"与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。
6、如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(“abcdefg”);
System.out.println(stringBuffer.reverse()); // gfedcba
7、String 类的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
8、是否可以继承 String 类?
String 类是 final 类故不可以继承,被final修饰的类都不能被继承。
9、== 和 equals 的区别是什么?
- .== 解读
对于基本类型和引用类型 == 的作用效果是不同的, - 基本类型:比较的是值是否相同;
- 引用类型:比较的是引用是否相同;
因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而 new String()方法则重写开辟了内存空间,所以 == 结果为 false,而 equals 比较的一直是值,所以结果都为 true。 - equals 解读
equals 本质上也是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。
我们先看一下 Object 类的equals()方法
底层用的是 == 作判定,我们再看String的 equals 方法
String 重写了 Object 的 equals 方法,把引用比较改成了值比较。
总结 : == 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而 equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。
10、final, finally, finalize 的区别?
final 用于声明属性、方法和类,分别表示属性不可变、不能被重写和类不能被继承。final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
finally 是异常处理语句结构的一部分,无论有没有异常发生,总要执行 finally 语句,它为程序提供了一个统一的出口,使程序能正常退出。
finalize 是 Object 类的一个方法,在垃圾收集器执行的时候,会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。
11、普通类和抽象类有哪些区别?
- 普通类不能包含抽象方法,抽象类可以包含抽象方法。
- 抽象类不能直接实例化,普通类可以直接实例化。
12、abstract(抽象类) 和 interface(接口) 有什么区别?
- 实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
- 构造函数:抽象类可以有构造函数;接口不能有。
- main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
- 实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
- 访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。
13、抽象类必须要有抽象方法吗?
不需要,抽象类不一定非要有抽象方法。
14、Collection 和 Collections 有什么区别?
java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。
Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。
15、List、Map、Set 三个接口,各有什么特点及区别?
List:集合中可以存放重复对象,按对象进入的顺序保存对象顺序,允许有重复的对象。
Set:集合中的对象不按特定的方式排序,并且没有重复对象。
Map: Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。Map集合中的键对象不允许重复。
16、如何实现数组和 List 之间的转换?
- List转换成为数组:调用 ArrayList 的toArray方法。
- 数组转换成为List:调用 Arrays 的 asList 方法。
17、ArrayList有哪些特点?
- ArrayList 是一种变长的集合类,基于定长数组实现,使用默认构造方法初始化出来的容量是0,之后都是延迟初始化,即第一次调用add方法添加元素的时候才将容量初始化为10。
- ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个更大的数组。ArrayList扩容的长度是原长度的1.5倍由于 ArrayList 底层基于数组实现,所以其可以保证在 O(1) 复杂度下完成随机查找操作。
- ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的异常或错误。
- 顺序添加很方便。
- 删除和插入需要复制数组,性能差(可以使用LinkindList)。
18、LinkedList 有什么特点?
- LinkedList是通过双向链表去实现的。
- 从LinkedList的实现方式中可以看出,它不存在容量不足的问题,因为是链表。
- LinkedList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写出“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
- LinkdedList的克隆函数,即是将全部元素克隆到一个新的LinkedList中。
- 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。
- LinkedList可以作为FIFO(先进先出)的队列。
- LinkedList可以作为LIFO(后进先出)的栈。
- 遍历LinkedList时,使用removeFirst()或removeLast()效率最高。但是用它们遍历会删除原始数据;若只是单纯的取数据,而不删除,建议用迭代器方式或者for-each方式。无论如何,千万不要用随机访问去遍历LinkedList!因为这样的效率非常非常低。
19、ArrayList 和 LinkedList 的区别是什么?
最明显的区别是 ArrrayList 底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。
对于随机访问的 get 和 set 方法,ArrayList 要优于 LinkedList,因为LinkedList要移动指针。
当对数据进行增加和删除的操作时,LinkedList 比 ArrayList 的效率更高,因为 ArrayList 是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
20、ArrayList 和 Vector 的区别是什么?
- Vector 是同步的,而 ArrayList 不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
- ArrayList 比 Vector 快,它因为有同步,不会过载。
- ArrayList 更加通用,因为我们可以使用 Collections 工具类轻易地获取同步列表和只读列表。
21、HashMap 和 Hashtable 有什么区别?
- 继承的父类不同。HashMap 继承自AbstractMap类,Hashtable 继承自 Dictionary 类,但二者都实现了 Map 接口。
- HashMap线程不安全,HashTable 线程安全。
- 包含的 contains 方法不同。hashMap 去掉了 HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
- hashMap 允许空键值,而 hashTable 不允许。
22、HashMap 和 treeMap 有什么区别?
- HashMap 是无序的,TreeMap 是有序的。
- HashMap 继承 AbstractMap 类,TreeMap 继承 SortedMap 类。
23、在 Queue 中 poll()和 remove()有什么区别?
- 相同点:都是返回第一个元素,并在队列中删除返回的对象。
- 不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出 NoSuchElementException 异常。
24、迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
25、迭代器 Iterator 是什么?
Java中的Iterator功能比较简单,并且只能单向移动:
(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
(2) 使用next()获得序列中的下一个元素。
(3) 使用hasNext()检查序列中是否还有元素。
(4) 使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
26、Iterator 和 ListIterator 有什么区别?
(1) Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
(2) Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
(3) ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
27、throw 和 throws 的区别?
throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。而throw则是指抛出的一个具体的异常类型。
28、 try-catch-finally 中哪个部分可以省略?
catch 块的部分可以省略
29、 try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
会执行,在 return 前执行。如果 cath 和 finally 块里都有 return
返回值,那么 finally 里的值会被返回。
30、常见的异常类有哪些?
- NullPointerException:当应用程序试图访问空对象时,则抛出该异常。
- SQLException:提供关于数据库访问错误或其他错误信息的异常。
- IndexOutOfBoundsException:指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
- NumberFormatException:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
- FileNotFoundException:当试图打开指定路径名表示的文件失败时,抛出此异常。
- IOException:当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类。
- ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出该异常。
- ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常。
- IllegalArgumentException:抛出的异常表明向方法传递了一个不合法或不正确的参数。
- ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
- NegativeArraySizeException:如果应用程序试图创建大小为负的数组,则抛出该异常。
- NoSuchMethodException:无法找到某一特定方法时,抛出该异常。
- SecurityException:由安全管理器抛出的异常,指示存在安全侵犯。
- UnsupportedOperationException:当不支持请求的操作时,抛出该异常。
- RuntimeExceptionRuntimeException:是那些可能在Java虚拟机正常运行期间抛出的异常的超类。
31、 java 中 IO 流分为几种?
按功能来分:输入流(input)、输出流(output)。
按类型来分:字节流和字符流。
字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。
32、BIO、NIO、AIO 有什么区别?
- BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
- AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
33、Files的常用方法都有哪些?
- Files.exists():检测文件路径是否存在。
- Files.createFile():创建文件。
- Files.createDirectory():创建文件夹。
- Files.delete():删除一个文件或目录。
- Files.copy():复制文件。
- Files.move():移动文件。
- Files.size():查看文件大小。
- Files.read():读取文件。
- Files.write():写入文件。
34、Override和Overload的含义去区别?
重载 (Overload) 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数、类型或顺序不同)。
覆盖 (Override) 表示子类中的方法可以与父类中的某个方法的名称 和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那 个完全相同的方法给覆盖了。