Java全栈面试题及答案汇总(3)

文章目录

jdk1.8有那些特性

  • Lambda表达式:简化匿名内部类的编写,支持函数式编程。
  • Stream API :提供声明式处理集合数据的能力,支持过滤、映射、归约等操作。比如filtersummaxcollect
  • 新的日期时间API (java.time包):如LocalDateLocalTimeLocalDateTime解决旧Date类的线程安全问题。
  • 默认方法 :允许在接口中定义具体实现方法,便于接口扩展。接口的方法使用default关键字修饰
  • 函数式接口 :Lambda 表达式的使用前提,是一种特殊的接口。可使用@FunctionalInterface修饰
  • Optional类 :用于避免空指针异常,封装可能为null的值。Optional.ofNullable(T t),orElse(T t)
  • HashMap 底层优化(红黑树)

静态方法引用:ClassName::staticMethod

实例方法引用(特定对象):instance::method

任意对象的实例方法引用:ClassName::instanceMethod

构造方法引用:ClassName::new

JDK1.8中stream用法

Stream是JDK 1.8中用于处理集合数据的API,支持函数式编程风格。常用用法包括:

  • 创建Stream:通过集合的 stream() 方法或 Stream.of() 创建。
  • 中间操作:如 filter() (过滤)、 map() (映射)、 sorted() (排序),这些操作返回新Stream,可链式调用。
  • 终端操作:如 collect() (收集为集合)、 forEach() (迭代)、 reduce() (归约),触发实际计算。
  • 示例: list.stream().filter(x -> x > 0).map(x -> x *
    2).collect(Collectors.toList()) 过滤正数并加倍后收集到列表。
    Stream具有惰性求值特性,提高处理效率。

HashMap 底层原理||工作原理

HashMap基于哈希表实现,工作原理如下:

HashMap底层结构(JDK 8)

  • 数组 + 链表 + 红黑树
    • 数组:默认容量16(2^4),存储Node节点(包含hash、key、value、next)。
    • 链表:哈希冲突时链接相同索引的节点,长度>8转为红黑树。
    • 红黑树:优化长链表查询性能,时间复杂度从O(n)降至O(log n)。

基于哈希表存储数据的。

哈希表

JDK8之前,哈希表 = 数组+链表

JDK8开始,哈希表 = 数组+链表+红黑树

哈希表是一种增删改查数据,性能都较好的数据结构

java 复制代码
Set<String> set = new HashSet<>();
  1. 创建一个默认长度16的数组,默认加载因子为0.75,数组名table
  2. 使用元素的哈希值对数组的长度做运算计算出应存入的位置,可以想象这个运算是取余。
  3. 判断当前位置是否为null,如果是null直接存入
  4. 如果不为null,表示有元素,则调用equals方法比较相等,则不存入链表;不相等,则存入链表。
    • JDK 8之前,新元素存入数组,占老元素位置,老元素挂下面
    • JDK 8开始之后,新元素直接使用链表挂在老元素下面。
  5. 但是如果我们链表过长不就相当于LinkedList了吗。所以当这16个元素被占用了16(当前长度) * 上面第一步的加载因子(0.75) = 12个元素后,会自动扩容。数组扩容为原2倍。
  6. 但是会有一种可能,我的链表可以一直无限长。但是我的HashSet长度的元素一直没有达到扩容标准。于是加了一个另一个准则:JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树

哈希计算

  1. 哈希值hash = key.hashCode() ^ (key.hashCode() >>> 16)(高位参与运算,减少冲突)。
  2. 数组索引index = hash & (capacity - 1)(等价于取模运算)。

扩容机制

  1. 触发条件:元素数量 > 容量 × 负载因子(默认0.75)。
  2. 扩容过程
    • 新容量 = 旧容量 × 2(翻倍)。
    • 重新计算每个元素的索引,复制到新数组。
    • JDK 8优化:元素要么留在原索引,要么移至原索引 + 旧容量。

list,set,map,Queue的区别

java 复制代码
Java 集合框架
├── Collection(单元素集合根接口)接口
│   ├── List(有序、可重复)接口
│   ├── Set(无序/有序、不可重复)接口
│   └── Queue(有序、按特定规则存取,可重复)接口
└── Map(键值对集合根接口,独立体系)接口
    ├── HashMap(哈希无序、key不可重复)实现类
    ├── LinkedHashMap(保留插入顺序、key不可重复)实现类
    └── TreeMap(key排序有序、key不可重复)实现类

这些是Java集合框架的核心接口,区别如下:

  • List:有序集合,元素可重复,支持索引访问。实现类有ArrayList、LinkedList。
  • Set:无序集合(某些实现如TreeSet有序),元素不可重复。实现类有HashSet、TreeSet。
  • Map:键值对集合,键不可重复,值可重复。实现类有HashMap、TreeMap。
  • Queue:队列,通常遵循先进先出(FIFO)或优先级顺序。实现类有LinkedList、PriorityQueue。

主要区别在于元素顺序、重复性和存储结构。

ArrayList与LinkedList,Vector的区别

  • ArrayList:基于动态数组,支持随机访问(通过索引),时间复杂度O(1);但插入和删除元素需移动后续元素,平均O(n)。非线程安全。
  • LinkedList:基于双向链表,插入和删除元素效率高(只需修改指针),平均O(1);但随机访问需遍历链表,平均O(n)。非线程安全。
  • Vector:类似ArrayList,但线程安全(方法使用synchronized修饰),性能较低。在现代Java中,通常用CopyOnWriteArrayList替代。

Hashtable与HashMap,HashSet的区别

类名 所属接口 存储形式 线程安全 null 值支持 底层结构 核心用途
HashMap Map <Key, Value> 1 个 null Key + 多个 null Value 数组 + 链表 + 红黑树(JDK1.8+) 普通键值对存储(高性能)
Hashtable Map <Key, Value> 不允许 null Key /null Value 数组 + 链表(无红黑树优化) 老旧系统兼容(现已过时)
HashSet Set 单个元素 E 1 个 null 元素(依赖 HashMap) 封装 HashMap(Key 存元素) 元素去重(无需关联额外数据)

JAVA中那些集合是线程安全的

  • 传统集合:Vector、Hashtable、Stack(通过synchronized实现)
  • Collections 工具类包装:
    • Collections.synchronizedList(new ArrayList())
    • Collections.synchronizedSet(new HashSet())
    • Collections.synchronizedMap(new HashMap())
  • JUC包 (并发编程核心工具包)中的并发集合:
    • ConcurrentHashMap :分段锁实现的线程安全Map
    • CopyOnWriteArrayList :写时复制的List
    • CopyOnWriteArraySet :写时复制的Set
    • ConcurrentLinkedQueue :无锁队列
    • BlockingQueue implementations:如ArrayBlockingQueue、LinkedBlockingQueue
java 复制代码
// 将 ArrayList 包装为线程安全的 List
List<String> safeList = Collections.synchronizedList(new ArrayList<>());
// 将 HashMap 包装为线程安全的 Map
Map<String, Integer> safeMap = Collections.synchronizedMap(new HashMap<>());

面向对象三大特征及解释

  1. 封装:隐藏类的内部实现细节,对外提供一个可访问的接口。
  2. 继承 :子类继承父类属性和方法,实现代码复用(如extends关键字)
  3. 多态:同一种事物,由于条件不同,产生的结果也不同。即同一个引用类型,使用不同的实例而执行不同的操作。

方法覆盖与方法重载的区别

方法重写

  1. 在父类与子类之间
  2. 方法名相同
  3. 参数列表相同
  4. 返回值类型相同或是其子类
  5. 访问权限不能严于父类

方法重载

  1. 在同一个类中
  2. 方法名相同
  3. 参数个数或类型不同
  4. 与返回值和访问修饰符无关
比较项 位置 方法名 参数表 返回值 访问修饰符
方法重写 子类 相同 相同 相同或是其子类 不能比父类更严格
方法重载 同类 相同 不相同 无关 无关

10. JAVA接口与抽象类的区别

两者能包含的成员类型有明确区别,具体对比如下:

成员类型 抽象类(Abstract Class) 接口(Interface)
成员变量 可以有普通实例变量、静态变量 仅能有 public static final 常量(默认修饰符,可省略)
构造方法 有构造方法(用于子类初始化父类成员) 无构造方法(接口不能被实例化,也无需初始化成员)
普通方法 可以有普通成员方法(有完整实现) Java 8 前:无;Java 8 后:可包含 default 默认方法(有实现)
抽象方法 可以有抽象方法(abstract 修饰,无实现) Java 8 前:仅能有抽象方法(默认 public abstract,可省略);Java 8 后:仍支持抽象方法
静态方法 可以有静态方法(有实现) Java 8 后:可包含静态方法(有实现,仅接口自身可调用)
私有方法 可以有私有方法(Java 7+,用于内部复用) Java 9 后:可包含私有方法(用于默认方法间的代码复用)
继承性 一个类可以实现多个接口 一个类只能继承一个抽象类
关键字 使用 implements实现 使用 extends继承
相关推荐
鱼跃鹰飞17 小时前
设计模式系列:工厂模式
java·设计模式·系统架构
时见先生17 小时前
Python库和conda搭建虚拟环境
开发语言·人工智能·python·自然语言处理·conda
a努力。17 小时前
国家电网Java面试被问:混沌工程在分布式系统中的应用
java·开发语言·数据库·git·mysql·面试·职场和发展
Yvonne爱编码17 小时前
Java 四大内部类全解析:从设计本质到实战应用
java·开发语言·python
wqwqweee17 小时前
Flutter for OpenHarmony 看书管理记录App实战:搜索功能实现
开发语言·javascript·python·flutter·harmonyos
J2虾虾17 小时前
SpringBoot和mybatis Plus不兼容报错的问题
java·spring boot·mybatis
yongui4783418 小时前
基于MATLAB的NALM锁模光纤激光器仿真实现
开发语言·matlab
毕设源码-郭学长18 小时前
【开题答辩全过程】以 基于springboot 的豪华婚车租赁系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
-To be number.wan19 小时前
Python数据分析:numpy数值计算基础
开发语言·python·数据分析
Cx330❀20 小时前
【优选算法必刷100题】第038题(位运算):消失的两个数字
开发语言·c++·算法·leetcode·面试