华为OD面试真题题库
专栏:华为OD面试真题题库
目录: 最新华为OD面试手撕代码真题目录以及八股文真题目录
1. arrayList是怎么实现动态数组的
ArrayList
在Java中是一种常用的动态数组实现。它内部使用一个数组来存储元素。当我们向ArrayList
添加元素时,如果内部数组已满,ArrayList
会创建一个新的数组,通常是原数组大小的1.5倍,然后将原数组的所有元素复制到新数组中,这个过程称为数组扩容。
以下是这个过程的简化版代码:
public void add(E e) {
ensureCapacity(size + 1); // 增加前,先确保容量足够
elementData[size++] = e;
}
public void ensureCapacity(int minCapacity) {
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
int newCapacity = oldCapacity * 3/2 + 1; // 新容量为旧容量的1.5倍
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity); // 复制到新数组
}
}
这种动态调整容量的方式使ArrayList
可以在运行时动态地添加或删除元素,而无需事先知道需要存储多少元素,因此被称为动态数组。
然而,这种动态调整容量的方式也带来了一些性能开销。每次数组扩容时,都需要创建新数组并复制元素,这是一个时间复杂度为O(n)的操作。因此,如果可以预估到需要存储的元素数量,最好在创建ArrayList
时指定初始容量,以减少扩容操作的次数,提高性能。
2. jdk13、jdk17新特性?
一 JDK8 新特性
1.1 Lambda 表达式
Lambda表达式是Java 8引入的一个重要特性,它允许以更简洁的方式编写匿名函数,Lambda表达式可以看作是一种轻量级的函数式编程的语法表示 Lambda表达式的基本语法如下:
(parameter1, parameter2, ..., parameterN) -> {
// 方法体
}
Lambda表达式包含以下几个部分:
- 参数列表:包含在圆括号内,可以是零个或多个参数。
- 箭头操作符:由箭头符号 “->” 表示,用于分隔参数列表和方法体。
- 方法体:包含在花括号内,实现具体的操作逻辑。
Lambda表达式的主要用途是简化代码,尤其是在使用函数式接口时非常方便。函数式接口是只包含一个抽象方法的接口,Lambda表达式可以与函数式接口@FunctionalInterface一起使用,从而实现函数式编程的效果。
package lambda;
/**
* @description: 使用 lambda 表达式创建线程
* @author: shu
* @createDate: 2023/6/30 9:49
* @version: 1.0
*/
public class Thread01 {
public static void main(String[] args) {
// 1.1 使用匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World! 1.1");
}
}).start();
// 1.2 使用 lambda 表达式
new Thread(() -> System.out.println("Hello World! 1.2 ")).start();
// 1.3 使用 lambda 表达式和类型推导
new Thread(() -> {
System.out.println("Hello World! 1.3");
}).start();
}
}
Lambda表达式可以更简洁地表示匿名函数,避免了传统的匿名内部类的冗余代码,提高了代码的可读性和可维护性。它是Java 8引入的一个强大特性,广泛应用于函数式编程和Java 8以后的各种API中。
1.2 新的日期API
JDK 8引入了一个新的日期和时间API,名为java.time
,它提供了更加灵活和易于使用的日期和时间处理功能。该API在设计上遵循了不可变性和线程安全性的原则,并且提供了许多方便的方法来处理日期、时间、时间间隔和时区等。 下面是java.time
包中一些主要的类和接口:
LocalDate
:表示日期,例如:年、月、日。LocalTime
:表示时间,例如:时、分、秒。LocalDateTime
:表示日期和时间,结合了LocalDate
和LocalTime
。ZonedDateTime
:表示带时区的日期和时间。Instant
:表示时间戳,精确到纳秒级别。Duration
:表示时间间隔,例如:小时、分钟、秒。Period
:表示日期间隔,例如:年、月、日。DateTimeFormatter
:用于日期和时间的格式化和解析。ZoneId
:表示时区。ZoneOffset
:表示时区偏移量。
这些类提供了一系列方法来执行日期和时间的计算、格式化、解析和比较等操作。而且,java.time
包还提供了对日历系统的支持,包括对ISO-8601日历系统的全面支持。 以下是一个简单的示例,展示了如何使用新的日期API创建和操作日期和时间:
package lambda;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @description: 新的日期和时间 API 示例
* @author: shu
* @createDate: 2023/6/30 10:15
* @version: 1.0
*/
public class DateDemo01 {
public static void main(String[] args) {
// 创建日期
LocalDate date = LocalDate.now();
System.out.println("Today's date: " + date);
// 创建时间
LocalTime time = LocalTime.now();
System.out.println("Current time: " + time);
// 创建日期和时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println("Current date and time: " + dateTime);
// 格式化日期和时间
String formattedDateTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("Formatted date and time: " + formattedDateTime);
// 执行日期的计算操作
LocalDate tomorrow = date.plusDays(1);
System.out.println("Tomorrow's date: " + tomorrow);
// 执行时间的比较操作
boolean isBefore = time.isBefore(LocalTime.NOON);
System.out.println("Is current time before noon? " + isBefore);
}
}
1.3 使用Optional
JDK 8引入了一个新的类,名为Optional
,用于解决在处理可能为null的值时出现的NullPointerException(空指针异常)问题。Optional
类的设计目标是鼓励更好的编程实践,明确表示一个值可能为空,并鼓励开发人员在使用这些可能为空的值时进行显式的处理。 Optional
类是一个容器对象,可以包含一个非空的值或者没有值。它提供了一系列方法来处理包含值和没有值的情况,例如:获取值、判断是否有值、获取默认值、执行操作等。 下面是Optional
类的一些常用方法:
of()
:创建一个包含非空值的Optional对象。empty()