文章目录
- 前言
- 面试题系列文章传送门
- Spring突击面试题内容
- 1. 面向对象的特征有哪些方面?
- 2. Java中实现多态的机制是什么?
- 3. JDK 和 JRE 的区别是什么?
- 4. == 和 equals()方法的区别?
- 5. 如何编译和运行Java文件?
- 6. Java 有哪几种基本数据类型?
- 7. 访问修饰符 public,private,protected以及不写(defualt)时的区别?
- 8. 静态(static)变量和普通变量有什么区别?
- 9. this和super有什么区别?
- 10. short s1= 1; s1 = s1+1有什么错? short s1 = 1; s1 += 1;有什么错?
- 11. float 型 float f=3.4 是否正确?
- 12. 说说&和&&的区别?
- 13. 数组有没有 length()这个方法? String 有没有 length()这个方法?
- 14. 什么是值传递和引用传递?
- 15. 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
- 16. final、finally、finalize有什么区别?
- 17. Java 中的注释有哪些写法?
- 18. 是否可以从一个static方法内部发出对非static方法的调用?
- 19. 2 * 8最有效率的计算方法是什么?
- 20. void和Void有什么区别?
- 21. 一个".java"源文件中是否可以包括多个不是内部类的类?有什么限制?
- 22. static 关键字有什么用?
- 23. Integer与int的区别?
- 24. final 关键字有什么用法?
- 25.(方法重载)Overload和(方法重写)Override的区别?Overloaded的方法是否可以改变返回值的类型?
- 26. abstract的方法是否可同时是static、native和synchronized?
- 27. (11.5)等於多少?(-11.5)等於多少?
- 28. abstract class(抽象类)和interface(接口)语法上有什么区别?
- 29. 为什么byte取值范围为-128~127?
- 30. char 型变量中可以存贮一个中文汉字吗?
- 31. 重载和重写有什么区别?
- 32. Java有没有goto?
- 33. String和StringBuffer的区别?
- 34. switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
- 35. 下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d"?
- 36. 内部类可以引用它的包含类的成员吗?有没有什么限制?
- 37. String s = new String("xyz");创建了几个String对象?是否可以继承String类?
- 38. try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
- 39. 能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
- 40. 运行时异常(runtime exception)与一般异常(checked exception)有何异同?
- 41. List和Map的区别?
- 42. List、Map、Set三个接口存取元素时,各有什么特点?
- 43. 为何没有像 ()这样的方法,向集合中添加元素?
- 44. Iterator 和 ListIterator 之间有什么区别?
- 45. error和exception有什么区别?
- 46. 简单说说Java中的异常处理机制的简单原理和应用?
- 47. Java 中堆(heap)和栈(stack)有什么区别?
- 48. ArrayList和Vector的异同点?
- 49. HashMap和HashTable的区别?
- 50. 说出ArrayList,Vector,LinkedList的存储性能和特性?
- 51. Collection和Collections的区别?
- 52. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
- 53. 迭代器(Iterator)是什么?
- 54. hashCode()方法与equals()方法的区别?
- 55. 字节流与字符流的区别?
- 56. 什么是java序列化,如何实现java序列化?(请解释Serializable序列化接口的作用?)
- 57. 流按实现功能怎么分?
- 58. Java中,throw和throws有什么区别?
- 59. 节点流(OutputStream)里面的write()方法是什么意思,write(byte b[], int off, int len)这个方法里面的三个参数分别是什么意思?
- 60. 流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是>怎么关闭的?
- 61. 字节输入流(InputStream)里的read()方法返回的是什么,read(byte[] data)是什么意思,返回的是什么值?
- 62. 说说常见的集合有哪些?
- 63. 为什么Map接口不继承Collection接口?
- 64. Collections类是什么?
- 65. Comparable 和 Comparator 接口有何区别?
- 66. io流怎样读取文件的?
- 67. 什么是cookie?Session和cookie有什么区别?
- 68. 什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?
- 69. 为何 Collection 不从克隆(Cloneable)和序列化(Serializable)接口继承?
- 70. Map 接口提供了哪些不同的集合视图?
- 71. 如何决定选用 HashMap 还是 TreeMap?
- 72. ArrayList 和 LinkedList 有何区别?
- 73. Java中的HashMap的工作原理是什么?
- 74. Java 集合类框架的最佳实践有哪些?
- 75. Java自动装箱与拆箱?
- 76. 面向对象和面向过程的区别?
- 77. Java创建对象有几种方式?
- 78. 对象克隆深拷贝和浅拷贝的区别是什么?
- 79. Java 中 IO 流分为几种?
- 80. 说说List,Set,Map三者的区别?
- 81. Java中实现多线程有几种方法?
- 82. 多线程有什么用?
- 83. Thread类中的start()方法和run()方法的区别?
- 84. Runnable接口和Callable接口的区别?
- 85. 在 Java 程序中怎么保证多线程的运行安全?
- 86. volatile关键字的作用是什么?
- 87. Java如何在两个线程之间共享数据?
- 88. 生产者-消费模型是什么?
- 89. 生产者-消费者模型的作用是什么?
- 90. ThreadLocal有什么用?
- 91. 为什么wait()方法和notify()/notifyAll()方法要在同步方法或者同步块中被调用?
- 92. wait()方法和notify()/notifyAll()方法在释放对象监视器时有什么区别?
- 93. 为什么要使用线程池?
- 94. 什么是线程池?
- 95. 线程池有什么优点?
- 96. 线程池创建有哪几种常见方式?
- 97. Java中sleep()方法和wait()方法有什么区别?
- 98. Java中如何停止一个正在运行的线程?
- 99. notify()和notifyAll()有什么区别?
- 100. 为什么wait(), notify()和notifyAll()这些方法不在thread类里面?
- 101. Java中interrupted()方法和isInterrupted()方法的区别?
- 102. Thread类中的yield()方法有什么作用?
- 103. 如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
- 104.有三个线程T1,T2,T3,如何保证顺序执行?
- 105. 谈谈你对线程安全的理解?
- 106. Java中synchronized和ReentrantLock有什么区别?
- 107. Java线程池中submit()方法和execute()方法有什么区别?
- 108. Java类加载过程?
- 109. 描述一下JVM加载Class文件的原理机制?
- 110. 进程和线程的区别是什么?
- 111. GC是什么? 为什么要有GC?
- 112. 简述Java垃圾回收机制?
- 113. ()和()会做什么事情?
- 114. 垃圾回收的优点和原理?并考虑2种回收机制?
- 115. 垃圾回收器的基本原理(对象引用遍历)是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
- 116. Java 中会存在内存泄漏吗,请简单描述?
- 117. 如何判断一个对象是否存活?(或者 GC 对象的判定方法?)
- 118. finalize() 方法什么时候被调用?析构函数 (finalization) 的 目的是什么?
- 119. SynchronizedMap和ConcurrentHashMap有什么区别?
- 120. 什么是分布式垃圾回收(DGC)?它是如何工作的?
- 121. 串行(serial)收集器和吞吐量(throughput)收集器的区别 是什么?
- 122. 在Java 中,对象什么时候可以被垃圾回收?
- 123. 说一下JVM有哪些垃圾回收算法?
- 124. 什么是类加载器,类加载器有哪些?
- 125. 类加载器双亲委派模型机制?
- 126. PrintStream、BufferedWriter、PrintWriter的比较?
- 127. 字节流和字符流哪个好?怎么选择?
- 128. 简述java内存分配与回收策率以及Minor GC和Major GC?
- 129. 什么是缓冲区?有什么作用?
- 130. BufferedReader属于哪种流,它主要是用来做什么的,它里面有那些经典的方法?
前言
作为应届生,处于找工作中ing。今年2月份刚刚整理出来的面试题,时间比较赶就没有按照模块分类排序了。总而言之,顺序比较乱,希望大家耐着性子 看。如果实在介意,评论告知,我会视情况作修改的。另外如果大家觉得我找的答案不够清晰,欢迎私信或者评论只出,我看到都会去修改的!
面试题系列文章传送门
2021年后端开发面试题整理合集
Spring突击面试题内容
1. 面向对象的特征有哪些方面?
面向对象的特征有抽象、继承、封装和多态性。
- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
- 继承:继承是从现有类中得到继承信息来创建新类的过程,提供继承信息的类被称为父类,得到继承信息的类被称为子类。
- 封装:封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。
- 多态性:多态性允许不同子类型的对象对同一消息作出不同的响应,可分为编译时的多态性和运行时的多态性。
2. Java中实现多态的机制是什么?
- 多态是指依靠父类或接口的引用指向子类,从而实现了一个对象有多种形态的特性。
- 父类的引用是在程序运行时动态的指向具体的实例,调用该引用的方法时,不是根据引用变量的类型中定义的方法来运行,而是根据具体的实例方法来运行。
- Java中实现多态的机制有继承、抽象类、接口、方法的重载、方法的重写等。编译时的多态性使用方法的重载,运行时的多态性使用方法的重写。
3. JDK 和 JRE 的区别是什么?
JRE是Java 运行时的环境和将要执行 Java 程序的虚拟机,同时包含了执行程序需要的浏览器插件。
JDK是完整的 Java 软件开发工具包,包含了 JRE,可以让开发者开发、编译、执行 Java 应用程序。
4. == 和 equals()方法的区别?
== : 它的作用是判断两个对象的地址是否相等,判断两个对象是否相等。基本数据类型通过== 比较的是值,引用数据类型通过 == 比较的是内存地址。
equals()方法 : 它的作用是判断两个对象是否相等,一般有两种使用情况:
类没有覆盖 equals() 方法,通过 equals() 方法比较该类的两个对象时,等价于通过“==”比较。
类覆盖 equals() 方法,通过 equals() 方法比较两个对象的内容是否相等时。若它们的内容相等,则返回 true ,反之返回 false。
5. 如何编译和运行Java文件?
使用javac命令来编译.java文件(比如),运行之后会生产对应的文件
使用Java命令来运行java文件
6. Java 有哪几种基本数据类型?
整型有byte、short、int、long,浮点型有float、double,字符型有char、布尔型:boolean
7. 访问修饰符 public,private,protected以及不写(defualt)时的区别?
Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问,支持 4 种不同的访问权限。
- private : 在同一类内可见,使用对象:变量、方法,不能修饰外部类
- default : 在同一包内可见,不使用任何修饰符,使用对象:类、接口、变量、方法。
- protected : 对同一包内的类和所有子类可见,使用对象:变量、方法,不能修饰外部类。
- public : 对所有类可见,使用对象:类、接口、变量、方法
8. 静态(static)变量和普通变量有什么区别?
- 所属目标不同:静态变量属于类的变量,普通变量属于对象的变量
- 存储区域不同:静态变量存储在方法区的静态区,普通变量存储在堆区
- 生命周期不同:静态变量是随着类的加载而加载,随着类的消失而消失。普通变量随着对象的加载而加载,随着对象的消失而消失
- 调用方式不同:静态变量只能通过类名调用,普通变量只能通过对象调用
9. this和super有什么区别?
this:代表当前对象本身,super:代表当前对象的父类。
10. short s1= 1; s1 = s1+1有什么错? short s1 = 1; s1 += 1;有什么错?
对于s1=s1+1,因为1是int类型,所以当s1+1进行运算时,会把结果自动作升级转换变为int类型。而s1是short类型,会报类型转换错误。另外,由于s1+=1含有强制类型转换,所以不会错。
11. float 型 float f=3.4 是否正确?
精度不准确,应该用强制类型转换。如 float f=(float)3.4
12. 说说&和&&的区别?
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与
13. 数组有没有 length()这个方法? String 有没有 length()这个方法?
数组没有 length()方法,有 length 的属性。String 有 length()这个方法
14. 什么是值传递和引用传递?
值传递是对基本数据类型的变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。一般认为,java 内的传递都是值传递.
引用传递是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身, 所以对引用对象进行操作会同时改变原对象,
15. 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容是可以改变的。总得来说,对于一个final变量,如果是基本数据类型的变量,则其数值在初始化之后便不能更改;如果是引用类型的变量,则在初始化之后便不能再指向另一个对象。
16. final、finally、finalize有什么区别?
- final可以修饰类、变量、方法,修饰类时表示该类不能被继承、修饰方法时表示该方法不能被重写、修饰变量时表示该变量是一个常量不能被重新赋值。
- finally一般作用在try-catch代码块中,在处理异常的时候,通常将一定要执行的代码放在finally代码块中。表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
- finalize是Object类的一个方法,它是用来实现垃圾回收的。在垃圾回收器执行时会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收。
17. Java 中的注释有哪些写法?
单行注释//
多行注释/* 注释… /
用于注释文档的多行注释/* 注释… */
18. 是否可以从一个static方法内部发出对非static方法的调用?
在static方法内部不可以直接调用非static方法,因为static方法被调用时无需创建对象,而非static方法需要创建对象后才能被调用。要想在static方法内部调用非static方法,可以在static方法内部先创建一个对象,然后通过对象来调用非static方法。
19. 2 * 8最有效率的计算方法是什么?
由于位运算符是cpu直接支持的,效率最高,所以2 * 8最有效的计算方法是 2 << 3(读作右移3位或者2两个小于号如何3)
20. void和Void有什么区别?
void用于无返回值的方法定义
Void是void的包装方法,和其他基础类型的包装方法不同的是Void不能被实例化,Void还可以用于一直返回null的方法或泛型。
21. 一个".java"源文件中是否可以包括多个不是内部类的类?有什么限制?
可以包含多个不是内部类的类,但是有且只有一个类名与文件名相同。
22. static 关键字有什么用?
static关键字可以用来修饰内部类、类的成员方法、类的成员变量、以及static静态代码块。
23. Integer与int的区别?
- Integer是int的包装类,int则是java基本数据类型中的一种,Integer变量必须实例化后才能使用,而int变量不需要。
- Integer是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象,而int是直接存储数据值。
- Integer的默认值是null,int的默认值是0
24. final 关键字有什么用法?
final关键字可以修饰类、变量、方法,修饰类时表示该类不能被继承、修饰方法是表示该方法不能被重写、修饰变量时表示该变量是一个常量不能被重新赋值。
25.(方法重载)Overload和(方法重写)Override的区别?Overloaded的方法是否可以改变返回值的类型?
重写与重载是java多态性的不同表现,重写是指子类拥有和父类相同的名称和参数,重载是在一个类中定义了多个同名的方法但是返回的参数不同。Overloaded的方法不可以改变返回值类型的
26. abstract的方法是否可同时是static、native和synchronized?
都不可以。
- abstract是指抽象方法,只有方法声明没有方法实现,不能被直接调用。
- static是类方法, 它可以不生成类的实例直接被类调用,而abstract方法不能被调用,所以static与abstract不能同时使用。
- native用来声明本地方法,一般用于java与外环境的交互。它与抽象方法类似,只有方法声明没有方法实现,native与abstract本身就是相冲突的,所以不能同时使用。
- synchronized是同步方法,然而同步是需要有具体操作才能实现的,但abstract只有方法声明,无法实现同步,所以static和synchronized不能同时使用
27. (11.5)等於多少?(-11.5)等於多少?
方法表示“四舍五入”,即将原来的数字加上0.5后再向下取整,所以(11.5)的结果为12,(-11.5)的结果为-11。
28. abstract class(抽象类)和interface(接口)语法上有什么区别?
- 抽象类可以包含构造方法,接口中不能包含构造方法;
- 抽象类可以包含普通成员变量,接口中不能包含普通成员变量;抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的。
- 抽象类中的抽象方法的访问类型可以是public,protected,但接口中的抽象方法只能都是public类型的,并且默认为public abstract类型。
- 抽象类中可以包含静态方法,接口中不能包含静态方法。
- 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型是任意的,但接口中的静态成员变量只能是public static final类型
29. 为什么byte取值范围为-128~127?
Java中byte类型为1个字节,1个字节占8位刚好256个数,而-128到127也是256个数。
30. char 型变量中可以存贮一个中文汉字吗?
java 中以 unicode 编码,一个 char 型变量占 16 个字节,所以放一个中文是没问题的
31. 重载和重写有什么区别?
重载和重写都是实现多态的方式,区别在于重载实现的是编译时的多态性,而重写实现的是运行时的多态性。
32. Java有没有goto?
goto是java语言中的保留字,目前还没有在java中使用。
33. String和StringBuffer的区别?
- String类的内容一旦声明后是不可改变的,改变的只是内存的指向,而StringBuffer类的对象内容是可以改变的。
- String对象不可修改指的是对象本身不可修改,而不是引用不可修改。
- 对于StringBuffer,不能像String那样直接通过赋值的方式完成对象实例化,必须通过构造方法的方式完成。StringBuffer类在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。在实际使用时,如果经常需要对一个字符串进行修改,例如插入,删除等操作,使用StringBuffer更加适合。
34. switch语句能否作用在byte上,能否作用在long上,能否作用在String上?
switch可作用于byte、int、String和枚举类型,不可作用于long类型。
35. 下面这条语句一共创建了多少个对象:String s=“a”+“b”+“c”+“d”?
只创建一个对象,编译时对字符串常量直接相加的表达式进行优化, 不必要等到运行期去进行加法运算处理。 而是在编译时去掉其中的加号, 直接将其编译成一个常量相连的结果,比如String s = “abcd”。
36. 内部类可以引用它的包含类的成员吗?有没有什么限制?
完全可以,如果不是静态内部类,就没有限制。如果把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,只能访问外部类中的静态成员变量。内部类有4种。
- 静态内部类是用static关键字修饰的,在访问限制上只能访问外部类中的static关键字所修饰的成员变量或者是方法。
- 成员内部类是最普遍的内部类,可以无条件访问外部类的所有成员属性和成员方法(包括私有成员和静态成员)
- 局部内部类是定义在外部类的方法中的,可以访问外部类的所有成员。但是不能随便访问局部变量,除非这个局部变量被final关键字修饰
- 匿名内部类其实就是局部内部类的简写格式,只能使用一次。
37. String s = new String(“xyz”);创建了几个String对象?是否可以继承String类?
产生两个对象。一个是存储于常量池中的字符串常量xyz,另一个是由new产生的,存储于堆中。String类是不可变类,是不可以继承的。
38. try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
在try后面的finally里的code会被执行,执行时机是在return的前面。
39. 能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
可以转换。如果int类型的值大于byte类型的范围,int类型的高位将被丢弃。
40. 运行时异常(runtime exception)与一般异常(checked exception)有何异同?
checked exception即一般异常,比如 IO 异常和 SQL 异常。 对于这种异常, JAVA 编译器强制要求进行 try-catch 。
Runtime exception即运行时异常,可以选择不处理,当出现这样的异常时,总是由虚拟机接管。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码,如果没有处理块,则到最上层。此时如果是多线程,就由()方法抛出,如果是单线程,那就由main()方法抛出。如果是线程抛出的异常,这个线程就退出了,如果是主程序抛出的异常,那么这整个程序也退出了。
41. List和Map的区别?
List:是存储单列数据的集合,存储的数据是有序的并且是可以重复的。
Map:是存储双列数据的集合,通过键值对存储数据,存储的数据是无序的。Key值不能重复,value值可以重复,key和value是一一对应的。
42. List、Map、Set三个接口存取元素时,各有什么特点?
- List存取元素时有放入顺序,元素可以重复
- Map存取元素时按键值对存储,无放入顺序
- Set存取元素时元素无放入顺序,元素不可以重复
43. 为何没有像 ()这样的方法,向集合中添加元素?
Iterator不能确保迭代的顺序,所以需要add操作。ListIterator没有提供一个add操作,因为它能确保迭代的顺序。
44. Iterator 和 ListIterator 之间有什么区别?
- Iterator 可以遍历 Set 和 List 集合,ListIterator 只能遍历List集合。
- Iterator 只可以向前遍历,ListIterator 可以双向遍历。
- ListIterator 从 Iterator 接口继承,多了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。
45. error和exception有什么区别?
Exception和Error都是继承于Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出或者捕获,它是异常处理机制的基本组成类型。
Exception是Java程序运行中可预料的异常,可以获取到这种异常和进行业务外的处理。
Error是Java程序运行中不可预料的异常,这种异常发生以后,会直接导致JVM出现不可处理或者不可恢复的情况,所以这种异常不可能抓取到。
46. 简单说说Java中的异常处理机制的简单原理和应用?
- 异常是指Java程序运行时所发生的非正常情况或者错误,java对异常进行了分类,不同类型的异常使用了不同的java类,所有异常的根类都为。Throwable派生了2个子类:Error和Exception。
- Error表示程序本身无法克服和恢复的一种严重错误。Exception表示程序本身能克服和恢复的异常,Exception分为系统异常和普通异常。
- 系统异常是软件本身缺陷导致的问题,也就是软件开发问题考虑不周所导致的问题,如数组越界问题、空指针异常、类转换异常等等,用户无法克服和恢复这种问题,但这种情况下可以选择让软件继续运行或停止运行。
- 普通异常是运行环境的变化或异常导致的问题,是用户能够克服的问题,如网路掉线、硬盘空间不足等等。
47. Java 中堆(heap)和栈(stack)有什么区别?
- 栈内存用来存储局部变量和方法调用,堆内存用来存储Java中的对象,无论是成员变量、局部变量还是类变量,它们指向的对象都存储在堆内存中,栈内存要远远小于堆内存。
- 栈内存属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,栈内存可以理解成线程的私有内存。
- 堆内存中的对象对所有线程可见,可以被所有线程访问。
48. ArrayList和Vector的异同点?
相同点:
ArrayList和Vector都是基于索引的,内部都是通过数组实现,都实现了List接口和允许null值。
ArrayList和Vector都维护插入的顺序,可以根据插入顺序获取元素和根据索引值对元素随机访问。
不同点:
Vector是同步的和线程安全的,而ArrayList却不是。
ArrayList比Vector性能更快,因为Vector的线程同步在一定程度上影响了性能。
49. HashMap和HashTable的区别?
- HashMap允许key和value为空,HashTable不允许。
- HashTable的默认容量为11,HashMap的默认容量为16。
- HashTable扩容时,将容量变为原来的2倍加1,HashMap扩容时,将容量变为原来的2倍。
- HashTable是同步和线程安全的,适合多线程环境。HashMap是非线程安全的,适合单线程环境。
- HashMap和HashTable都是基于哈希表实现,每一个元素都是一个key-value键值对,内部通过单链表解决冲突问题,都实现了Serializable序列化接口。
50. 说出ArrayList,Vector,LinkedList的存储性能和特性?
- ArrayList和Vector都是使用数组方式存储数据,此数组的元素个数大于实际存储的数据个数以便增加和插入元素。它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据效率较低。
- Vector由于使用了synchronized同步方法,性能上比ArrayList差。
- LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项,所以插入速度较快。
- LinkedList不是线程安全的,提供了一些方法,使得LinkedList可以被当作堆、栈和队列来使用。
51. Collection和Collections的区别?
- Collection是集合类的上级接口,继承于它的接口主要有List和Set。
- Collections是针对集合类的一个帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作。
- Collections的主要方法有:混排(Shuffling)、反转(Reverse)、替换(fill)、拷贝(copy)、排序(Sort)等。
52. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
Set是Collection容器的一个子接口,它不允许出现重复元素,元素重复与否是使用 equals()方法进行判断的。
(==和equals()方法的区别见上述)
53. 迭代器(Iterator)是什么?
迭代器接口提供了很多对集合元素进行迭代的方法,每一个集合类都包含了可以返回迭代器实例的迭代方法。
迭代器可以在迭代的过程中删除底层集合的元素,通过迭代器的remove()方法删除。
54. hashCode()方法与equals()方法的区别?
hashCode()方法和equals()方法都是用于比较两个对象是否相等的,hashCode()方法只需要对两个对象的hash值进行比较,效率比较高。但hashCode()方法不可靠,两个不同的对象的hash值很有可能相同。因此需要使用equals()方法进行进一步的相等判断,equals()方法相等则hashCode()方法一定相等,而hashCode()方法相等但equals()方法不一定相等。
55. 字节流与字符流的区别?
字节流在操作时不会用到缓冲区,是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。字符流最大的好处是可以进行中文的有效处理,如果在日常开发中有中文处理则用字符流,如果没有建议使用字节流。
(不用背,辅助理解用的缓冲区可以简单地理解为一段内存区域)
56. 什么是java序列化,如何实现java序列化?(请解释Serializable序列化接口的作用?)
序列化是一种用来处理对象流的机制,将对象的内容进行流化,可以对流化后的对象进行读写操作和传输于网络之间,序列化是为了解决对象流读写操作时所引发的问题。序列化的实现是将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,只是为了标注对象可被序列化。然后使用一个输出流(FileOutputStream)来构造一个对象流(ObjectOutputStream)对象,通过对象流对象的write()方法就可以将参数的对象写出
57. 流按实现功能怎么分?
- 流按照实现功能分为节点流(OutputStream)和处理流 (OutputStreamWriter)
- 节点流直接与数据源相连,用于输入或输出。
- 处理流是在节点流的基础上进行加工和一些功能的扩展
58. Java中,throw和throws有什么区别?
- throw和throws都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的异常处理是由函数的上层调用处理。
- throw用来抛出一个具体的异常类型,throws是声明方法,可能会抛出某个异常
- throws出现在方法函数头,throw出现在方法函数体。
- throws表示出现异常的一种可能性,并不一定会发生。throw则是一定抛出了某种异常。
59. 节点流(OutputStream)里面的write()方法是什么意思,write(byte b[], int off, int len)这个方法里面的三个参数分别是什么意思?
write()方法将指定字节传入数据源、byte数组表示数据、int off表示数据偏移的开始、int len表示写入的字节数
60. 流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是>怎么关闭的?
流一旦打开就必须关闭,使用close方法放入finally语句块中执行关闭,调用的是处理流就关闭处理流,如果多个流互相调用只关闭最外层的流。
61. 字节输入流(InputStream)里的read()方法返回的是什么,read(byte[] data)是什么意思,返回的是什么值?
InputStream的read()方法将读取的字节储存在byte数组,返回的是传入数组的参数个数。
62. 说说常见的集合有哪些?
- Collection接口的子接口包括:Set 接口和List 接口;
- Map接口的实现类主要有HashMap、TreeMap、HashTable、ConcurrentHashMap
- Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet
- List接口的实现类主要有:ArrayList、LinkedList、Stack、Vector
63. 为什么Map接口不继承Collection接口?
因为Map提供的是键值对映射,而collection提供的是一组数组,所以Map接口不继承Collection接口。
64. Collections类是什么?
Collections是针对集合类的一个帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作。
Collections的主要方法有:混排(Shuffling)、反转(Reverse)、替换(fill)、拷贝(copy)、排序(Sort)等。
65. Comparable 和 Comparator 接口有何区别?
Comparable接口被用来提供对象的自然排序,可以使用它来提供基于单个逻辑的排序。
Comparator接口被用来提供不同的排序算法,可以选择需要使用的Comparator接口对给定的对象集合进行排序。
66. io流怎样读取文件的?
io流使用File对象获取文件路径,通过字符流Reader加入文件,使用字符缓冲流BufferedReader处理Reader,最后定义一个字符串循环遍历输出文件。
67. 什么是cookie?Session和cookie有什么区别?
- Cookie是HTTP协议的规范之一,它是一个键值对,是服务器保存在客户端的数据。它的流程是由服务器通过响应头把Cookie传输给客户端,客户端将Cookie保存起来。当客户端再次请求同一服务器时,在请求头中添加该服务器保存在客户端的Cookie,发送给服务器。
- Session技术将用户的数据写到用户独占的session中,保存在服务器。
- Cookie只能存储文本,大小限制在4KB内。Session可以保存任何类型的数据,不过会占用服务器内存,所以使用的时候要充分考虑。
68. 什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?
节点流直接与数据源相连,用于输入或者输出
处理流在节点流的基础上对之进行加工和一些功能的扩展
处理流的构造器必须传入节点流的子类
69. 为何 Collection 不从克隆(Cloneable)和序列化(Serializable)接口继承?
Collection表示一个集合包含了一组对象,如何存储和维护这些对象是由具体实现来决定的。因为集合的具体形式多种多样,例如List集合允许元素重复,Set集合则不允许。Collection是一个抽象表现,重要的是实现。当与具体实现打交道的时候,克隆或序列化才能发挥作用,Collection具体的实现类是否可以克隆或序列化应该由其自身决定。
70. Map 接口提供了哪些不同的集合视图?
- Map 接口提供三个集合视图,都不支持add和addAll操作。
- Set类型的keySet()方法:该方法返回的map中包含所有 key 的一个 Set 视图,
- Collection类型的values()方法:该方法返回的map中包含所有value的一个Collection视图。
- entrySet()方法:该方法返回的 map 中包含所有映射的一个集合视图。
71. 如何决定选用 HashMap 还是 TreeMap?
HashMap适合在Map中进行插入、删除和定位元素这类操作,TreeMap适合用在对一个有序的key集合进行遍历。
72. ArrayList 和 LinkedList 有何区别?
ArrayList支持随机访问而LinkedList不支持。
ArrayList是通过数组来实现,插入和删除会受到元素位置的影响而会产生移位。LinkeList采用双向链表来存储数据,插入和删除不会受到元素位置的影响。
ArrayLIst会预留一定的空间,数组实际空间小于存储的空间。linkedlist则不会预留空间,有元素添加才会去申请这个元素所对应的内存空间。
ArrayList执行频繁的查找效率比LinkedList高,LinkedList执行频繁的插入和删除效率比Arraylist高
73. Java中的HashMap的工作原理是什么?
HashMap是基于hashing的原理,使用put()方法存储对象,使用get()方法获取对象。给put()方法传递键和值时,先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。HashMap是在bucket中储存键对象和值对象,作为。
74. Java 集合类框架的最佳实践有哪些?
假如元素的大小是固定的,而且能事先知道,应该使用Array而不是ArrayList。
有些集合类允许指定初始容量,如果能估计出存储的元素数目,可以设置初始容量来避免重新计算hash值或者是扩容。
在底层的集合实际上是空的情况下,返回为长度是0的集合或数组而不是null,避免空指针异常。
75. Java自动装箱与拆箱?
自动装箱就是自动将基本数据类型转换为包装器类型,比如调用Integer的valueOf() 方法将int类型转换为Integer类型
自动拆箱就是自动将包装器类型转换为基本数据类型,比如调用Integer的intValue()方法将Integer类型转换为int类型
76. 面向对象和面向过程的区别?
面向过程:是分析解决问题的步骤,用函数把这些步骤一步一步地实现,然后在使用的时候一一调用,性能较高。
面向对象:是把构成问题的事物分解成各个对象,而建立对象的目的也不是为了完成一个个步骤,而是为了描述某个事物在解决整个问题的过程中所发生的行为。面向对象有封装、继承、多态的特性,所以容易维护、复用和扩展。面向对象可以设计出低耦合的系统,但是性能上要比面向过程低。
77. Java创建对象有几种方式?
- 通过new创建新对象
- 通过反射机制
- 采用clone机制
- 通过序列化机制
78. 对象克隆深拷贝和浅拷贝的区别是什么?
浅拷贝:在拷贝对象时仅仅拷贝对象本身和基本数据类型的变量,而不拷贝引用类型的变量
深拷贝:在拷贝对象时不仅拷贝对象本身,还有全部变量(包括引用类型的变量)
79. Java 中 IO 流分为几种?
- 按照IO流的流向分,可以分为输入流和输出流;
- 按照IO流的操作单元划分,可以分为字节流和字符流;
- 按照IO流的实现功能划分,可以分为节点流和处理流。
80. 说说List,Set,Map三者的区别?
- List集合存储的元素是有序的,是可以重复的
- Set是一个不允许元素重复的集合。
- Map集合使用键值对存储,key值不能重复,value值可以重复,key和value是一一对应的。
81. Java中实现多线程有几种方法?
- 继承Thread类;
- 实现Runnable接口;
- 实现Callable接口;
82. 多线程有什么用?
- 发挥多核 CPU 的优势
- 防止线程阻塞
- 便于建模
83. Thread类中的start()方法和run()方法的区别?
通过start()方法来启动一个线程,此时线程处于就绪状态,可以被JVM来调度执行。在调度过程中,JVM通过调用run()方法来完成业务逻辑,run()方法结束的同时线程会终止,所以通过start()方法可以达到多线程的目的。
如果直接调用run()方法,会被当做一个普通的方法调用,程序中仍然只有主线程这一个线程。代码还是同步执行的,必须等待一个线程的 run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其 run()方法里面的代码,无法达到多线程的目的。
84. Runnable接口和Callable接口的区别?
相同点:runnable接口和callable接口都可以编写多线程程序,都采用()方法启动线程。
不同点:
Runnable接口的run()方法无返回值,只能抛出运行时异常,且无法捕获处理。
Callable接口的call()方法有返回值,允许抛出异常,可以获取异常信息。
85. 在 Java 程序中怎么保证多线程的运行安全?
- 使用安全类,比如AtomicInteger类。
- 使用自动锁,比如synchronized。
- 使用手动锁,Lock。
86. volatile关键字的作用是什么?
在Java多线程的开发中有三种特性:原子性、可见性和有序性,volatile关键字主要作用是保证内存可见性和防止指令重排序。使用volatile关键字修饰的变量,保证了在多线程之间的可见性,即每次读取的volatile变量一定是最新的数据。volatile关键字还可以和CAS结合来保证原子性,比如AtomicInteger类。
87. Java如何在两个线程之间共享数据?
将要共享的数据抽象成一个类,并将对共享数据的操作作为这个类的方法,然后在方法上加synchronized关键字
将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法封装在外部类。以便实现对数据的各个操作的同步和互斥,而作为内部类的各个 Runnable 对象调用外部类的这些方法。
88. 生产者-消费模型是什么?
以商品为例,当队列空间排满时,生产者需要等待队列有空余空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源的占用权。如果生产者不释放临界资源,消费者就无法消费队列中的商品,队列就不会有空余空间,那么生产者就会一直无限等待下去。因此当队列空间排满时,会让生产者交出对临界资源的占用权并进入挂起状态,然后等待消费者消费了商品后,通知生产者队列有空余空间。当队列有空余空间时,消费者也必须等待生产者的通知才能消费商品,这种互相通信的过程就是生产者-消费者模型。
(不用背:临界资源即队列)
89. 生产者-消费者模型的作用是什么?
通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者-消费者模型最重要的作用
解耦,解耦意味着生产者和消费者之间的联系变少,然而联系越少越可以独自发展而不需要受到相互的制约,这是生产者-消费者模型附带的作用
90. ThreadLocal有什么用?
ThreadLocal是一种以空间换时间的做法,在每个Thread里面维护了一个来对数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。
91. 为什么wait()方法和notify()/notifyAll()方法要在同步方法或者同步块中被调用?
因为一个线程调用对象的wait()方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这个锁并进入等待状态,直到其他线程调用这个对象上的notify()方法。当一个线程需要调用对象的notify()方法时,它会释放这个对象的锁,则其他在等待的线程就可以得到这个对象锁。由于wait()方法和notify()/notifyAll()方法都需要线程持有对象的锁,只能通过同步来实现,所以它们只能在同步方法或者同步块中被调用。
92. wait()方法和notify()/notifyAll()方法在释放对象监视器时有什么区别?
wait()方法立即释放对象监视器
notify()/notifyAll()方法则会等待线程剩余代码执行完毕,才会释放对象监视器。
93. 为什么要使用线程池?
使用线程池可以避免频繁地创建和销毁线程。
使用线程池可以根据项目灵活地控制并发的数目。
94. 什么是线程池?
线程池就是事先创建多个可执行的线程放入一个容器中,需要的时候从容器中获取而不用自行创建。线程使用完毕时不需要销毁线程而是放回容器中,从而减少创建和销毁线程对象的开销。
95. 线程池有什么优点?
- 降低资源消耗,复用存在的线程,减少创建和销毁线程的开销。
- 有效的控制最大并发线程数,提高响应速度和系统资源的使用率。
- 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性。使用线程池可以进行资源统一的分配,调优和监控,提高线程的可管理性。
- 提供定时执行、定期执行、单线程、并发数控制等功能。
96. 线程池创建有哪几种常见方式?
- newSingleThreadExecutor方式:此方式创建一个单线程的线程池,这个线程池只有一个线程在工作,相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,会有一个新的线程来替代,此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
- newFixedThreadPool方式:此方式创建一个固定大小的线程池,每提交一个任务就创建一个线程,直到线程数达到线程池的最大值。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
- newCachedThreadPool方式:此方式创建一个可缓存的线程池,如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲的线程。当任务所需要的线程数增加时,可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统能够创建的最大线程数。
- newScheduledThreadPool方式:此方式创建一个大小无限的线程池,此线程池支持线程定时执行或者定期执行。
97. Java中sleep()方法和wait()方法有什么区别?
sleep()方法和wait()方法都可以暂停线程的执行,区别在于:
- 类的不同:sleep() 方法是Thread线程类的静态方法,wait()方法是Object类的方法。
- 是否释放锁:sleep()方法不释放锁;wait()方法释放锁。
- 用途不同:wait()方法通常用于线程之间的通信,sleep()方法通常用于暂停执行。
- 用法不同:wait() 方法被调用后,超时之前线程不会自动苏醒,除非别的线程调用同一个对象上的 notify()方法或者notifyAll() 方法。sleep()方法执行完成后,线程会自动苏醒。
98. Java中如何停止一个正在运行的线程?
- 等待run()方法完成后,线程会终止。
- 使用stop()方法强行终止线程,但是不推荐,因为stop()方法是过期的方法。
- 使用interrupt()方法中断线程。
99. notify()和notifyAll()有什么区别?
先说两个概念:锁池和等待池
锁池:假设线程A已经拥有了某个对象的锁,而其它线程在调用这个对象的某个synchronized方法之前,必须先获得该对象的锁的拥有权,但是该对象的锁正被线程A拥有,所以这些线程就进入到该对象的锁池中竞争。
等待池:假设线程A调用了某个对象的wait()方法,线程A释放该对象的锁后,就进入到了该对象的等待池中
notify()方法和notifyAll()方法的区别:
如果线程调用了对象的 wait()方法,线程便会处于该对象的等待池中,在等待池中的线程是不会去竞争该对象的锁。
如果线程调用了对象的 notify()方法或者notifyAll()方法,被唤醒的的线程会进入该对象的锁池中,锁池中的线程会去竞争该对象的锁。也就是说,调用了notify()方法后,只要有一个线程就会由等待池进入锁池中,而notifyAll()方法是将该对象等待池内的所有线程移动到锁池中,等待锁竞争
100. 为什么wait(), notify()和notifyAll()这些方法不在thread类里面?
简单的说,由于wait(),notify()和notifyAll()方法都是锁级别的操作,所以把他们定义在Object类中,因为锁属于对象 。
101. Java中interrupted()方法和isInterrupted()方法的区别?
- interrupted() 和isInterrupted()的主要区别是前者会将中断状态而后者不会。
- 当中断线程调用静态方法()来检查中断状态时,中断状态会被清零。
- 而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态的标识。
102. Thread类中的yield()方法有什么作用?
yield()方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法,只能保证当前线程放弃CPU占用而不能保证让其它线程一定能占用CPU,所以执行yield()的线程有可能在进入到暂停状态后马上又被执行。
103. 如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
不会立即释放对象占用的内存,因为在下一个垃圾回收周期中,这个对象是可被回收的。也就是说并不会被垃圾收集器立刻回收,而是在下一次垃圾回收时才会释放对象占用的内存 。
104.有三个线程T1,T2,T3,如何保证顺序执行?
要保证T1、T2、T3三个线程顺序执行,可以利用Thread线程类的join()方法。
105. 谈谈你对线程安全的理解?
当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象是线程安全的。
106. Java中synchronized和ReentrantLock有什么区别?
相同点:
synchronized和ReentrantLock都是加锁方式同步,而且都是阻塞式的同步。
区别:
- synchronized竞争锁时会一直等待;ReentrantLock可以尝试获取锁,并得到获取结果。
- synchronized无法设置获取锁的超时时间;ReentrantLock可以设置获取锁的超时时间
- synchronized无法实现公平锁;ReentrantLock可以满足公平锁,公平锁即先等待先获取到锁
- synchronized控制等待和唤醒需要结合加锁对象的wait()、notify()和notifyAll()方法;ReentrantLock控制等待和唤醒需要结合Condition的await()、signal()和signalAll()方法
- synchronized是JVM层面实现的;ReentrantLock是JDK代码层面实现的
- synchronized在加锁代码块执行完或者出现异常时,会自动释放锁;ReentrantLock不会自动释放锁,需要在finally代码块释放
107. Java线程池中submit()方法和execute()方法有什么区别?
- submit()方法和execute()方法都可以向线程池提交任务。
- execute()方法的返回类型是void,它定义在Executor接口中,。
- submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,扩展了Executor接口 。
108. Java类加载过程?
- 加载:把.java文件编译成.class文件,生成Class对象
- 验证:验证字节码的准确性
- 准备:给类的静态变量分配内存,并赋予默认值
- 解析:符号引用和动态链接都变为直接引用
- 初始化:给类的静态变量初始化为指定的值,执行静态代码块
109. 描述一下JVM加载Class文件的原理机制?
Java中的所有类都需要由类加载器装载到JVM中才能运行,类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。
类装载方式有两种 :
- 隐式装载:程序在运行过程中通过new 等方式生成对象时,隐式调用类加载器装载对应的类到JVM中。
- 显式装载:通过()等方法,显式加载需要的类。Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类完全加载到JVM中。至于其他类,则在需要的时候才加载,为了节省内存开销。
110. 进程和线程的区别是什么?
进程是正在运行的应用程序,而线程是进程内部的一个执行序列,一个进程可以有多个线程。
111. GC是什么? 为什么要有GC?
GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃。Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java没有提供释放已分配内存的显示操作方法,不用担心内存管理,因为垃圾收集器会自动进行管理。
112. 简述Java垃圾回收机制?
当程序创建对象,数组等引用类型对象时,系统会在堆内存中分配一块内存区,对象就保存在内存区中。当内存不再被任何引用变量引用时,这块内存就变成了垃圾,等待垃圾回收机制去进行回收。
113. ()和()会做什么事情?
()方法和()方法用来提示JVM要进行垃圾回收,由JVM来决定立即开始还是延迟进行垃圾回收。
114. 垃圾回收的优点和原理?并考虑2种回收机制?
垃圾回收可以有效的防止内存泄露,有效的使用内存,它使得Java程序员在编写程序的时候不再需要考虑内存管理。垃圾回收器通常是作为一个单独的低级别的后台线程运行,在不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。程序员不能实时的调用垃圾回收器对某个或所有对象进行垃圾回收,回收机制有引用计数和对象引用遍历两种。
115. 垃圾回收器的基本原理(对象引用遍历)是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?
当对象创建时,GC就开始监控这个对象的地址、大小以及使用情况,通常采用有向图的方式记录和管理堆内存中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,就有责任回收这些对象的内存空间。垃圾回收器不可马上回收内存,程序员可以手动执行()方法来通知GC运行,但并不保证GC一定会执行。
116. Java 中会存在内存泄漏吗,请简单描述?
内存泄漏是指不再被使用的对象或者变量一直被占据在内存中。理论上来说,Java是有GC垃圾回收机制的,也就是说,不再被使用的对象,会被GC自动回收掉,自动从内存中清除。但是,即使这样,Java也还是存在着内存泄漏的情况,java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景。
117. 如何判断一个对象是否存活?(或者 GC 对象的判定方法?)
判断一个对象是否存活有两种方法:
- 引用计数法:所谓引用计数法就是给每一个对象设置一个引用计数器,每当有一个地方引用这个对象时,就将计数器加一,引用失效时,计数器就减一。当一个对象的引用计数器为零时,说明此对象没有被引用,也就是“死对象”,将会被垃圾回收.引用计数法有一个缺陷就是无法解决循环引用问题,也就是说当对象A引用对象B,对象B又引用者对象A,那么此时A,B对象的引用计数器都不为零,也就造成无法完成垃圾回收,所以主流的虚拟机都没有采用这种算法。
- 可达性算法(引用链法):该算法的思想是从一个被称为 GC Roots的对象开始向下搜索,如果一个对象到 GC Roots没有任何引用链相连时,则说明此对象不可用。
118. finalize() 方法什么时候被调用?析构函数 (finalization) 的 目的是什么?
垃圾回收器决定回收某对象时,就会调用该对象的finalize()方法,在Java中如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的,它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI调用non-Java程序,finalize()的工作就是回收这部分的内存。
119. SynchronizedMap和ConcurrentHashMap有什么区别?
- SynchronizedMap一次锁住整张表来保证线程安全,所以每次只能有一个线程来访问使用分段锁来保证在多线程下的性能。
- ConcurrentHashMap中则是一次锁住一个桶。ConcurrentHashMap 默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。
- 另外ConcurrrentHashMap使用一种不同的迭代方式。在这种迭代方式中,当iterator被创建后集合再发生改变就不再是抛出异常了,取而代之的是在改变new新的数据从而不影响原有的数据,iterator完成后再将头指针替换为新的数据,这样iterator线程可以使用原来老的数据,而写线程也可以并发的完成改变
120. 什么是分布式垃圾回收(DGC)?它是如何工作的?
DGC 叫做分布式垃圾回收。远程方法调用(RMI)使用DGC来做自动垃圾回收。因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。DGC使用引用计数算法来给远程对象提供自动内存管理。
121. 串行(serial)收集器和吞吐量(throughput)收集器的区别 是什么?
吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等规模和大规模数据的应用程序。而串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了。
122. 在Java 中,对象什么时候可以被垃圾回收?
当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了。
123. 说一下JVM有哪些垃圾回收算法?
- 标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
- 复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
- 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。
124. 什么是类加载器,类加载器有哪些?
实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。
主要有一下四种类加载器:
- 启动类加载器:用来加载 java 核心类库,无法被 java 程序直接引用。
- 扩展类加载器:它用来加载Java的扩展库。Java虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载Java类。
- 系统类加载器:它根据Java应用的类路径(CLASSPATH)来加载Java类。一般来说,Java应用的类都是由它来完成加载的。可以通过()来获取它。
- 用户自定义类加载器:通过继承类的方式实现。
125. 类加载器双亲委派模型机制?
当一个类收到了类加载请求时,不会自己先去加载这个类,而是将其委派给父类,由父类去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载。
126. PrintStream、BufferedWriter、PrintWriter的比较?
- PrintStream类支持将输出流包装成PrintStream后进行输出文本内容,PrintStream永远不会抛出IOException,支持自动刷新和通过checkError方法检查异常是否发生
- BufferedWriter类将支持文本写入字符输出流,缓冲各个字符从而提供单个字符、数组和字符串的高效写入。BufferedWriter通过write()方法可以将获取到的字符输出,然后通过newLine()进行换行操作。BufferedWriter中的字符流必须通过调用flush方法才能将其刷出去,并且BufferedWriter只能对字符流进行操作。如果要对字节流操作,则使用BufferedInputStream
- PrintWriter类的println方法自动添加换行,不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生,PrintWriter的构造方法可指定参数,实现自动刷新缓存
127. 字节流和字符流哪个好?怎么选择?
大多数情况下使用字节流会更好,因为大多数时候IO操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的(图片等都是按字节存储的)如果对于操作需要通过 IO 在内存中频繁处理字符串的情况使用字符流会好些,因为字符流具备缓冲区,提高了性能
128. 简述java内存分配与回收策率以及Minor GC和Major GC?
内存分配:
- 栈区:栈可分为Java虚拟机和本地方法栈
- 堆区:堆被所有线程共享,在虚拟机启动时创建,是唯一的目的是存放对象实例,是gc的主要区域,通常可分为两个区块年轻代和年老代。更新一点年轻代可分为Eden区,主要放新创建对象,From survivor 和 To survivor 保存 gc 后幸存下的对象,默认情况下各自占比 8:1:1。
- 方法区:被所有线程共享,用于存放已被虚拟机加载的信息、常量、静态变量等,是Java虚拟机描述为堆的一个逻辑部分。习惯被称为永久代。
- 程序计数器:是当前线程所执行的行号指示器,跳转指令等都依赖这个完成,线程私有。
回收策略以及Minor GC 和 Major GC(Full GC):- 对象优先在堆的 Eden 区分配。
- 大对象直接进入老年代.
- 长期存活的对象将直接进入老年代。当Eden区没有足够的空间进行分配时,虚拟机会执行一次通常发生在新生代的Eden区,在这个区的对象生存期短,往往发生 Gc 的频率较高,回收速度比较快;Full Gc/Major GC发生在老年代,一般情况下,触发老年代 GC 的时候不会触发 Minor GC,但是通过配置,可以在 Full GC 之前进行一次 Minor GC 这样可以加快老年代的回收速度。
129. 什么是缓冲区?有什么作用?
缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性。对于Java字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用flush()方法操作。
130. BufferedReader属于哪种流,它主要是用来做什么的,它里面有那些经典的方法?
属于处理流中的缓冲流,可以将读取的内容存在内存里面,有readLine()方法,它,用来读取一行
有问题欢迎私信/评论指出,谢谢您的观看,希望对您有帮助哦!
/