面试题-基础
主页
标签
文章
### Java 有哪些特点 - 并发性的: 你可以在其中执行许多语句,而不必一次执行它 - 面向对象的:基于类和面向对象的编程语言。 - 独立性的: 支持一次编写,到处运行的独立编程语言,即编译后的代码可以在支持 Java 的所有平台上运行。 ### == 和 equals 区别是什么 对于**基本数据类型来说**, == 判断的是两边的值是否相等 对于**引用类型**来说, == 判断的是两边的引用是否相等,也就是判断两个对象是否指向了同一块内存区域 ### String 中的 equals 是如何重写的 首先会判断要比较的两个字符串它们的引用是否相等。如果引用相等的话,直接返回 true 然后再判断被比较的对象是否是 String 的实例,如果不是的话直接返回 false,如果是的话,再比较两个字符串的长度是否相等,如果长度不想等的话也就没有比较的必要了;长度如果相同,会比较字符串中的每个 字符 是否相等,一旦有一个字符不相等,就会直接返回 false。 ### String s1 = new String("abc") 在内存中创建了几个对象 一个或者两个,String s1 是声明了一个 String 类型的 s1 变量,它不是对象。使用 new 关键字会在堆中创建一个对象,另外一个对象是 abc ,它会在常量池中创建,所以一共创建了两个对象;如果 abc 在常量池中已经存在的话,那么就会创建一个对象。 ### String 为什么是不可变的、jdk 源码中的 String 如何定义的、为什么这么设计。 String 被设计为 final 的,表示 String 对象一经创建后,它的值就不能再被修改,任何对 String 值进行修改的方法就是重新创建一个字符串。String 对象创建后会存在于运行时常量池中,运行时常量池是属于方法区的一部分,JDK1.7 后把它移到了堆中。 ### static 关键字是干什么用的?谈谈你的理解 - 修饰变量,static 修饰的变量称为静态变量,static 修饰的变量能够直接通过 类名.变量名 来进行访问,不用通过实例化类再进行使用。 - 修饰方法,static 修饰的方法被称为静态方法,静态方法能够直接通过 类名.方法名 来使用,在静态方法内部不能使用非静态属性和方法 - static 可以修饰代码块,主要分为两种,一种直接定义在类中,使用 static{},这种被称为静态代码块,一种是在类中定义静态内部类,使用 static class xxx 来进行定义 ### final 关键字是干什么用的?谈谈你的理解 - 修饰类,final 修饰的类不能被继承 - 修饰变量,final 修饰的变量不能被改写 - 修饰方法,final 修饰的方法不能被重写 ### 抽象类和接口的区别是什么 - 在接口中,只允许进行方法的定义,不允许有方法的实现,抽象类中可以进行方法的定义和实现 - 抽象类使用 abstract class 来表示;接口使用 interface 来表示 - 接口中定义的变量只能是公共的静态常量,抽象类中的变量是普通变量。 - 抽象类只能被继承,继承就只能继承一个,接口能实现多个 ### 重写和重载的区别 - 重写是子类对父类的方法重写,方法名、参数、返回都需要完全一致,是完全替代父类的方法 - 重载是在同一个类中,对同一个功能的不同实现,在一个类中方法名相同,返回值相同,但是传参不相同 ### HashMap 和 HashTable 的区别 - 相同点 - HashMap 和 HashTable 都是基于哈希表实现的,其内部每个元素都是 key-value 键值对 - HashMap 和 HashTable 都实现了 Map、Cloneable、Serializable 接口 - 不同点 - 父类不同:HashMap 继承了 AbstractMap 类,而 HashTable 继承了 Dictionary 类 - 空值不同:HashMap 允许空的 key 和 value 值,HashTable 不允许空的 key 和 value 值。 - 线程安全性:HashMap 不是线程安全的,而 HashTable 本身就是线程安全的容器。 - 性能方面:虽然 HashMap 和 HashTable 都是基于单链表的,但是HashTable 的 put 和 get 操作都是加了 synchronized 锁的,所以效率很差。 ### HashMap 和 HashSet 的区别 HashSet 继承于 AbstractSet 接口,实现了 Set、Cloneable,、java.io.Serializable 接口。HashSet 不允许集合中出现重复的值。HashSet 底层其实就是 HashMap,所有对 HashSet 的操作其实就是对 HashMap 的操作。所以 HashSet 也不保证集合的顺序,也不是线程安全的容器。 ### HashMap 线程安全的实现有哪些 HashMap 不是一个线程安全的容器,所以并发场景下推荐使用 ConcurrentHashMap ,或者使用线程安全的 HashMap,使用 Collections 包下的线程安全的容器,比如说 ```java Collections.synchronizedMap(new HashMap()); ``` 还可以使用 HashTable ,它也是线程安全的容器,基于 key-value 存储,经常用 HashMap 和 HashTable 做比较就是因为 HashTable 的数据结构和 HashMap 相同。 上面效率最高的就是 ConcurrentHashMap。 ### ConcurrentHashMap 底层实现 ConcurrentHashMap 是线程安全的 Map,它也是高并发场景下的首选数据结构,ConcurrentHashMap 底层是使用分段锁来实现的。 ### Arrays.asList 获得的 List 应该注意什么 1. Arrays.asList 转换完成后的 List 不能再进行任何 List 元素的增加或者减少的操作,否则会抛出异常UnsupportedOperationException,它继承了AbstractList类,AbstractList 中的add、remove、set操作都是直接抛异常,但是因为ArrayList重写了set方法,所以支持set 2. Arrays.asList 不支持基础类型的转换 ### Collection 和 Collections 的区别 Collection 是集合类的父类,比如比如说 AbstractList、AbstractSet Collections 是集合类的工具类,Collections 提供了一些工具类的基本使用,如sort、reverse、fill等 ### ArrayList、LinkedList 和 Vector 的区别 ArrayList、LinkedList、Vector 都是位于 java.util 包下的工具类,它们都实现了 List 接口 - ArrayList 的底层是动态数组,它是基于数组的特性而演变出来的,所以 ArrayList 遍历访问非常快,但是增删比较慢,因为会涉及到数组的拷贝。ArrayList 是一个非线程安全的容器,在并发场景下会造成问题,如果想使用线程安全的容器的话,推荐使用 Collections.synchronizedList - LinkedList 的底层是双向链表,所以 LinkedList 的增加和删除非常快,只需把元素删除,把各自的指针指向新的元素即可。但是 LinkedList 遍历比较慢,因为只有每次访问一个元素才能知道下一个元素的值。LinkedList 也是一个非线程安全的容器,推荐使用 Collections.synchronizedList - Vector 向量是最早出现的集合容器,Vector 是一个线程安全的容器,它的每个方法都粗暴的加上了 synchronized 锁,所以它的增删、遍历效率都很低 ### Exception 和 Error 有什么区别 Exception 泛指的是 异常,Exception 主要分为两种异常,一种是编译期出现的异常,称为 checkedException ,一种是程序运行期间出现的异常,称为 uncheckedException,常见的 checkedException 有 IOException,uncheckedException 统称为 RuntimeException,常见的 RuntimeException 主要有NullPointerException、 IllegalArgumentException、ArrayIndexOutofBoundException等,Exception 可以被捕获。 Error 是指程序运行过程中出现的错误,通常情况下会造成程序的崩溃,Error 通常是不可恢复的,Error 不能被捕获。 ### String、StringBuilder 和 StringBuffer 有什么区别 String 特指的是 Java 中的字符串,String 类位于 java.lang 包下,String 类是由 final 修饰的,String 字符串一旦创建就不能被修改,任何对 String 进行修改的操作都相当于重新创建了一个字符串。String 字符串的底层使用 StringBuilder 来实现的 StringBuilder 位于 java.util 包下,StringBuilder 是一非线程安全的容器,StringBuilder 的 append 方法常用于字符串拼接,它的拼接效率要比 String 中 + 号的拼接效率高。StringBuilder 一般不用于并发环境 StringBuffer 位于 java.util 包下,StringBuffer 是一个线程安全的容器,多线程场景下一般使用 StringBuffer 用作字符串的拼接 StringBuilder 和 StringBuffer 都是继承于 AbstractStringBuilder 类,AbstractStringBuilder 类实现了 StringBuffer 和 StringBuilder 的常规操作。 ### int 和 Integer 的区别 - int 是 Java 中的基本数据类型,int 代表的是 整型,一个 int 占 4 字节,也就是 32 位,int 的初始值是默认值是 0 ,int 在 Java 内存模型中被分配在栈中,int 没有方法。 - Integer 是 Java 中的基本数据类型的包装类,Integer 是一个对象,Integer 可以进行方法调用,Integer 的默认值是 null,Integer 在 Java 内存模型中被分配在堆中。int 和 Integer 在计算时可以进行相互转换,int -> Integer 的过程称为 装箱,Integer -> int 的过程称为 拆箱,Integer 还有 IntegerCache ,会自动缓存 -128 - 127 中的值 ### Java 提供了哪些 I/O 方式 ![](/api/file/getImage?fileId=65e827f64521a0000d000799) ### 谈谈你知道的设计模式 ![](/api/file/getImage?fileId=65e827f64521a0000d000798) ### Comparator 和 Comparable 有什么不同 - 对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了 Comparable 接口,实现了 compareTo 方法,我们可以直接使用。 - 而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。 ### Object 类中一般都有哪些方法 hashCode():用于计算对象的哈希码 equals():用于对象之间比较值是否相等 toString(): 用于把对象转换成为字符串 clone(): 用于对象之间的拷贝 wait(): 用于实现对象之间的等待 notify(): 用于通知对象释放资源 notifyAll(): 用于通知所有对象释放资源 finalize(): 用于告知垃圾回收器进行垃圾回收 getClass(): 用于获得对象类 ### 反射的基本原理,反射创建类实例的三种方式是什么 反射机制就是使 Java 程序在运行时具有自省(introspect) 的能力,通过反射我们可以直接操作类和对象,比如获取某个类的定义,获取类的属性和方法,构造方法等。 **创建类实例的三种方式是** - 对象实例.getClass(); - 通过 Class.forName() 创建 - 对象实例.newInstance() 方法创建 ### final、finally 和 finalize() 的区别 final 可以用来修饰类、变量和方法 finally 是一个关键字,它经常和 try 块一起使用,用于异常处理。使用 try...finally 的代码块种,finally 部分的代码一定会被执行,所以我们经常在 finally 方法中用于资源的关闭操作 finalize 是 Object 对象中的一个方法,用于对象的回收方法 ### 内部类有哪些分类,分别解释一下 - 静态内部类:就是定义在类内部的静态类,静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量; - 成员内部类:就是定义在类内部,成员位置上的非静态类,就是成员内部类。成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。 - 局部内部类:就是定义在方法中的内部类。定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。 - 匿名内部类:就是没有名字的内部类,除了没有名字,匿名内部类还有以下特点: - 匿名内部类必须继承一个抽象类或者实现一个接口 - 匿名内部类不能定义任何静态成员和静态方法。 - 当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。 - 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。 ### 说出几种常用的异常 NullPointerException: 空指针异常 NoSuchMethodException:找不到方法 IllegalArgumentException:不合法的参数异常 IndexOutOfBoundException: 数组下标越界异常 IOException:由于文件未找到、未打开或者 I/O 操作不能进行而引起异常 ClassNotFoundException :找不到文件所抛出的异常 NumberFormatException: 字符的 UTF 代码数据格式有错引起异常; InterruptedException: 线程中断抛出的异常 **参考地址:**https://xie.infoq.cn/article/3d161e7b8229892184160ba07
上一篇:
面试题-Spring
下一篇:
面试题-线程
Title
-
Artist
0:00