Java 面试题基础(六)
- 前言
- 1、深拷贝和浅拷贝?
- 2、poll() 方法和 remove() 方法的区别?
- 3、DelayQueue实现延时任务原理?
- 4、ArrayList 与 LinkedList 的区别?
- 5、用哪两种方式来实现集合的排序?
- 6、LinkedList 是单向链表还是双向链表?
- 7、Java 中的 TreeMap 和hashMap?
- 8、ArrayList 和 HashMap 的默认大小是多数?
- 9、有没有可能两个不相等的对象有有相同的 hashcode?
- 10、List安全删除元素详解?
- 11、ByteBuffer 与 StringBuffer 有什么区别?
- 12、Java 中,编写多线程程序的时候你会遵循哪些最佳实践?
- 13、DateTimeFormatter的使用?
- 14、抽象类与接口之间有什么不同?
- 15、Java 中,throw 和 throws 有什么区别?
- 16、Java 中,Serializable 与 Externalizable 的区别?
- 17、Java常用数据结构有哪些?
- 18、GC 是什么?为什么要有 GC?
- 19、全局变量和局部变量的区别?
- 20、获得一个Servlet的生命周期?
- 总结
前言
最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。
如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!
1、深拷贝和浅拷贝?
- 1、浅拷贝是指:只会拷⻉基本数据类型的值,以及实例对象的引⽤地址,并不会复制⼀份引⽤地址所指向的对象,也就是说浅拷⻉出来的对象,内部的引用对象指向的是同⼀个对象。
- 2、深拷贝是指:既会拷⻉基本数据类型的值,也会复制引⽤地址所指向的实例对象, 也就是说深拷⻉出来的对象,内部的引用对象指向的不是同⼀个对象。
2、poll() 方法和 remove() 方法的区别?
poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回null,
但是 remove() 失败的时候会抛出异常。
Queue queue = new LinkedList();
queue.offer(“1”);
System.out.println(queue.remove(“1”)); //返回true
System.out.println(queue.poll()); //返回null。
3、DelayQueue实现延时任务原理?
DelayQueue是一个无界的BlockingQueue的实现类,延迟队列中的元素只有在到期的时候,才能从队列中取走。
它的实现原理是基于priorityQueue,它是一个优先级队列,可以根据元素的优先级进行排序;在delayQueue中,元素的优先级是根据元素的延迟时间来确定的,延迟时间越短的元素优先级越高。
4、ArrayList 与 LinkedList 的区别?
- 1、数据结构不同:
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)双向链表的数据结构。 - 2、效率不同:
当随机访问List(get和set)时,ArrayList的效率更高,时间复杂度是O(1);
而LinkedList是线性存储方式,时间复杂度是O(log n);但是插入与删除元素时,LinkedList的效率更高。 - 3、内存使用方式不同:
ArrayList它的内存空间是预先分配好的,默认可以存放10个元素;而LinkedList它没有初始化大小,它就是一个双向链表,没有扩容,插入或删除元素时只需要改变前后节点的指针,不会浪费额外的内存空间。
5、用哪两种方式来实现集合的排序?
java集合的工具类Collections中提供了两种排序的方法,分别是:
List list = new ArrayList();
- 1.Collections.sort(list):userDTO必须实现Comparable接口,重写compareTo方法
- 2.Collections.sort(list:new Comparator())。
6、LinkedList 是单向链表还是双向链表?
是双向链表,它的每个Node节点都有3个属性:本节点存放的数据,以及指向前后节点的两个指针。
7、Java 中的 TreeMap 和hashMap?
- HashMap是通过hashcode()对其内容进行快速查找的;HashMap中的元素是没有顺序的;
- TreeMap中所有的元素都是有某一固定顺序的,如果需要得到一个有序的结果,就应该使用TreeMap;
HashMap和TreeMap都不是线程安全的。
8、ArrayList 和 HashMap 的默认大小是多数?
- ArrayList 的默认大小是10 个元素,每次扩容为原长度的1.5倍;
- HashMap 的默认大小是 16 个元素(必须是 2 的幂),每次扩容为原来的2倍。
9、有没有可能两个不相等的对象有有相同的 hashcode?
有可能,两个不相等的对象可能会有相同的 hashcode 值,这就是为什么在 hashmap 中会有冲突。如果两个对象相等,必须有相同的 hashcode 值,反之不一定相等。
10、List安全删除元素详解?
- 1、使用迭代器Iterator遍历list,调用Iterator的remove方法可以安全地移除元素;
Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {String element = iterator.next();if (element.equals("B")) {iterator.remove(); // 安全移除元素}}
- 2、Java8之后list新增了一个api removeIf,这个也可以做安全删除;
list.removeIf(s -> s.equals("B"));
- 3、使用removeAll方法;
List<String> elementsToRemove = new ArrayList<>();for (String element : list) {if (element.equals("B")) {elementsToRemove.add(element);}}
list.removeAll(elementsToRemove);
11、ByteBuffer 与 StringBuffer 有什么区别?
- 1、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的
- 2、只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。
- 3、在单线程程序下,StringBuilder效率更快,因为它不需要加锁,而StringBuffer则每次都需要判断锁,效率相对更低。
12、Java 中,编写多线程程序的时候你会遵循哪些最佳实践?
这是我在写 Java 并发程序的时候遵循的一些最佳实践:
- 1、给线程命名,这样可以帮助调试。
- 2、最小化同步的范围,而不是将整个方法同步,只对关键部分做同步。
- 3、如果可以,更偏向于使用volatile 而不是 synchronized。
- 4、使用更高层次的并发工具,而不是使用wait() 和notify() 来实现线程间通信,如BlockingQueue;
- 5、优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。
13、DateTimeFormatter的使用?
SimpleDateFormat 是线程不安全的,DateTimeFormatter是线程安全的。
常用方法:
- 1、ofPattern(“yyyy-MM-dd”):静态方法,返回一个DateTimeFormatter对象;
- 2、format(LocalDateTime.now()) :格式化一个日期、时间,返回字符串;
- 3、parse(“2021-07-21 07:17:34”) :将指定格式的字符序列解析为一个日期、时间。
14、抽象类与接口之间有什么不同?
Java 中,抽象类和接口有很多不同之处,但是最重要的一个是 Java 中限制一个类只能继承一个类,但是可以实现多个接口。
15、Java 中,throw 和 throws 有什么区别?
- throw 用于抛出 java.lang.Throwable 类的一个实例化对象,意思是说你可以通过关键字 throw 抛出一个 Error 或者 一个 Exception,如:
throw new IllegalArgumentException(“size must be multiple of 2″) - throws 的作用是方法被抛出相应的异常以便调用者能处理。Java 中,任何未处理的受检查异常强制在throws 子句中声明。
16、Java 中,Serializable 与 Externalizable 的区别?
- Serializable 接口是一个序列化Java 类的接口,以便于它们可以在网络上传输或者可以将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式,成本高、脆弱而且不安全。
- Externalizable 允许你控制整个序列化过程,指定特定的二进制格式,增加安全机制。
17、Java常用数据结构有哪些?
Java数据结构有:1、数组;2、哈希表;3、链表;4、队列; 5、堆; 6、栈,按照“后进先出”、“先进后出”的原则来存储数据; 7、图;8、树
18、GC 是什么?为什么要有 GC?
GC 是垃圾回收的意思,因为内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致系统的不稳定甚至崩溃。因此,Java提供了GC功能。
GC有效的防止了内存泄漏。
一般是把Java堆分为年轻代和老年代。
- 年轻代:年轻代用来存放最近创建的对象,生命周期很短
- 老年代:老年代中存放的都是存活了很久的对象
垃圾回收算法分为三种: - 标记-清除算法:标记无用对象,然后对其进行清除回收。
- 复制算法:将内存区域划分为大小相等的两部分,每次只使用一部分,当该部分用完后将其存活的对象复至另一部分,并把该部分内存全部清除。
- 标记-整理算法:标记无用对象,让所有存活的对象都向内存一端移动,然后清除掉存活对象边界外的内存区域。
19、全局变量和局部变量的区别?
- 1,作用域不同:全局变量的作用域为整个程序,而局部变量的作用域为当前函数或循环等;
- 2,内存存储方式不同:全局变量存储在方法区中,局部变量存储在虚拟机栈中;
- 3,生命期不同:全局变量的生命期和主程序一样,随程序的销毁而销毁,局部变量在函数内部或循环内部,随函数的退出或循环退出就不存在了;
- 4,使用方式不同:全局变量在声明后程序的各个部分都可以用到,但是局部变量只能在局部使用,函数内部会优先使用局部变量再使用全局变量。
20、获得一个Servlet的生命周期?
在我的理解Servlet的生命周期可以分为实例化、初始化、处理请求、销毁四个阶段。
Tomcat容器调用servlet的构造方法去执行实例化操作;
- 1.容器调用servlet的init方法去执行初始化操作;
- 2.初始化完成后调用service()方法,service方法根据请求方式调用doGet或者doPost方法,处理完后响应结果给客户端;
当服务器关闭时,Servlet调用destroy()方法进行销毁。
总结
都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!