介紹
如果您正在應聘Java編程職位,那麼您的編碼能力可能會受到考驗。無論您是Java的初學者還是專業程序員,本文提供了一些常見的Java面試問題和答案,以幫助您做好準備。
1. 如何在Java中反轉字符串?
在String
類中沒有reverse()
實用方法。但是,您可以從字符串創建一個字符數組,然後從末尾到開始遍歷它。您可以將字符附加到字符串生成器中,最後返回反轉的字符串。
以下示例代碼展示了反轉字符串的一種方法:
public class StringPrograms {
public static void main(String[] args) {
String str = "123";
System.out.println(reverse(str));
}
public static String reverse(String in) {
if (in == null)
throw new IllegalArgumentException("Null is not valid input");
StringBuilder out = new StringBuilder();
char[] chars = in.toCharArray();
for (int i = chars.length - 1; i >= 0; i--)
out.append(chars[i]);
return out.toString();
}
}
在方法中添加null
檢查並使用StringBuilder
附加字符可以獲得額外的分數。請注意,Java中的索引從0開始,因此您需要在for
循環中從chars.length - 1
開始。
2. 如何在Java中不使用第三个变量交换两个数字?
不使用第三个变量交换数字是一个三步过程,最好通过代码进行可视化:
b = b + a; // now b is sum of both the numbers
a = b - a; // b - a = (b + a) - a = b (a is swapped)
b = b - a; // (b + a) - b = a (b is swapped)
以下示例代码展示了一种实现数字交换方法的方式:
public class SwapNumbers {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a is " + a + " and b is " + b);
a = a + b;
b = a - b;
a = a - b;
System.out.println("After swapping, a is " + a + " and b is " + b);
}
}
输出显示整数值已交换:
Outputa is 10 and b is 20
After swapping, a is 20 and b is 10
3. 编写一个Java程序,检查字符串中是否存在元音。
以下示例代码演示了如何使用正则表达式检查字符串是否包含元音:
public class StringContainsVowels {
public static void main(String[] args) {
System.out.println(stringContainsVowels("Hello")); // true
System.out.println(stringContainsVowels("TV")); // false
}
public static boolean stringContainsVowels(String input) {
return input.toLowerCase().matches(".*[aeiou].*");
}
}
4. 编写一个Java程序,检查给定的数字是否为质数。
您可以撰寫一個程式來將給定的數字 n
除以從 2 到 n
/2 的數字,並檢查餘數。如果餘數為 0,則它不是質數。以下示例代碼展示了檢查給定數字是否為質數的一種方法:
public class PrimeNumberCheck {
public static void main(String[] args) {
System.out.println(isPrime(19)); // true
System.out.println(isPrime(49)); // false
}
public static boolean isPrime(int n) {
if (n == 0 || n == 1) {
return false;
}
if (n == 2) {
return true;
}
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
雖然此程式有效,但不夠節省記憶體和時間。考慮到對於給定的數字 N
,如果在 2
到 √N
(N 的平方根)之間有一個質數 M
可以整除它,那麼 N
就不是質數。
5. 寫一個 Java 程式來使用遞迴打印 Fibonacci 數列。
A Fibonacci sequence is one in which each number is the sum of the two previous numbers. In this example, the sequence begins with 0
and 1
. The following example code shows how to use a for
loop to print a Fibonacci sequence:
public class PrintFibonacci {
public static void printFibonacciSequence(int count) {
int a = 0;
int b = 1;
int c = 1;
for (int i = 1; i <= count; i++) {
System.out.print(a + ", ");
a = b;
b = c;
c = a + b;
}
}
public static void main(String[] args) {
printFibonacciSequence(10);
}
}
Output0, 1, 1, 2, 3, 5, 8, 13, 21, 34,
您也可以使用遞迴來打印 Fibonacci 數列,因為 Fibonacci 數是通過將序列中前兩個數相加而生成的:
F(N) = F(N-1) + F(N-2)
以下示例類展示了如何使用遞迴來計算一個長度為 10 的 Fibonacci 數列:
public class PrintFibonacciRecursive {
public static int fibonacci(int count) {
if (count <= 1)
return count;
return fibonacci(count - 1) + fibonacci(count - 2);
}
public static void main(String args[]) {
int seqLength = 10;
System.out.print("A Fibonacci sequence of " + seqLength + " numbers: ");
for (int i = 0; i < seqLength; i++) {
System.out.print(fibonacci(i) + " ");
}
}
}
OutputA Fibonacci sequence of 10 numbers: 0 1 1 2 3 5 8 13 21 34
6. 如何在Java中檢查整數列表是否僅包含奇數?
您可以使用for
循環,並檢查每個元素是否為奇數:
public static boolean onlyOddNumbers(List<Integer> list) {
for (int i : list) {
if (i % 2 == 0)
return false;
}
return true;
}
如果列表很大,您可以使用平行流進行更快的處理,如以下示例代碼所示:
public static boolean onlyOddNumbers(List<Integer> list) {
return list
.parallelStream() // 用於更快的處理的平行流
.anyMatch(x -> x % 2 != 0); // 一旦任何元素符合條件就返回
}
要了解更多關於確定整數是否為奇數的數學知識,請參考維基百科上的取模運算。
7. 如何在Java中檢查字符串是否為回文?
A palindrome string is the same string backwards or forwards. To check for a palindrome, you can reverse the input string and check if the result is equal to the input. The following example code shows how to use the String charAt(int index)
method to check for palindrome strings:
boolean checkPalindromeString(String input) {
boolean result = true;
int length = input.length();
for (int i = 0; i < length/2; i++) {
if (input.charAt(i) != input.charAt(length - i - 1)) {
result = false;
break;
}
}
return result;
}
8. 如何從Java中的字符串中刪除空格?
以下是示例代碼,展示了使用 Character.isWhitespace()
方法從字符串中刪除空格的一種方法:
String removeWhiteSpaces(String input) {
StringBuilder output = new StringBuilder();
char[] charArray = input.toCharArray();
for (char c : charArray) {
if (!Character.isWhitespace(c))
output.append(c);
}
return output.toString();
}
在Java中了解更多關於從字符串中刪除空格和其他 字符 的信息。
9. 如何在Java中刪除字符串中的領導和尾隨空格?
String
類包含兩個方法來刪除領導和尾隨的空格:trim()
和 strip()
。 strip()
方法是在Java 11中添加到 String
類中的。 strip()
方法使用 Character.isWhitespace()
方法來檢查字符是否是空格。 這個方法使用Unicode代碼點,而 trim()
方法將任何具有代碼點值小於或等於 U+0020
的字符標識為空格字符。
strip()
方法是刪除空格的推薦方法,因為它使用了Unicode標準。 以下是使用 strip()
方法刪除空格的示例代碼:
String s = " abc def\t";
s = s.strip();
System.out.println(s);
因為 String
是不可變的,所以你必須將 strip()
的輸出賦值給字符串。
10. 如何在Java中對數組進行排序?
Arrays
實用工具類有許多重載的 sort()
方法,用於對基本數組和對象數組進行排序。如果要對基本數組按自然順序進行排序,則可以使用 Arrays.sort()
方法,如下例所示:
int[] array = {1, 2, 3, -1, -2, 4};
Arrays.sort(array);
System.out.println(Arrays.toString(array));
但是,如果要對對象數組進行排序,則該對象必須實現 Comparable
接口。如果要指定排序標準,則可以傳遞 Comparator
進行排序邏輯。了解更多有關 Java中的Comparable和Comparator。
11. 如何在Java中以編程方式創建死鎖場景?
死鎖是在多線程Java環境中兩個或多個線程永久阻塞的情況。死鎖情況發生在至少兩個線程之間。以下示例代碼創建了一個死鎖場景:
public class ThreadDeadlock {
public static void main(String[] args) throws InterruptedException {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
t1.start();
Thread.sleep(5000);
t2.start();
Thread.sleep(5000);
t3.start();
}
}
class SyncThread implements Runnable {
private Object obj1;
private Object obj2;
public SyncThread(Object o1, Object o2) {
this.obj1 = o1;
this.obj2 = o2;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1);
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1);
work();
System.out.println(name + " acquiring lock on " + obj2);
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2);
work();
}
System.out.println(name + " released lock on " + obj2);
}
System.out.println(name + " released lock on " + obj1);
System.out.println(name + " finished execution.");
}
private void work() {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
所有三個線程將能夠在第一個對象上獲得鎖定。然而,它們正在使用共享資源,並且以這樣的方式啟動,以致它們將無限期地等待獲得第二個對象上的鎖定。您可以使用Java線程轉儲來檢測死鎖。了解更多有關Java中的死鎖。
12. 如何在Java中找到整數的階乘?
整數的階乘是通過將所有數字從1乘到給定數字計算得出的:
F(n) = F(1)*F(2)...F(n-1)*F(n)
以下示例代碼顯示了如何使用遞歸來找到整數的階乘:
public static long factorial(long n) {
if (n == 1)
return 1;
else
return (n * factorial(n - 1));
}
13. 如何在Java中反轉鏈表?
LinkedList descendingIterator()
返回一個迭代器,該迭代器以相反的順序迭代元素。以下示例代碼顯示了如何使用此迭代器創建一個新的鏈表,其中元素按相反的順序列出:
LinkedList<Integer> ll = new LinkedList<>();
ll.add(1);
ll.add(2);
ll.add(3);
System.out.println(ll);
LinkedList<Integer> ll1 = new LinkedList<>();
ll.descendingIterator().forEachRemaining(ll1::add);
System.out.println(ll1);
了解有关从数据结构和算法的角度学习反转链表的更多信息。
14. 如何在Java中实现二分搜索?
为了实现二分搜索,数组元素必须是排序的。二分搜索算法基于以下条件:
- 如果键小于中间元素,则现在只需在数组的前半部分中搜索。
- 如果键大于中间元素,则只需在数组的后半部分中搜索。
- 如果键等于数组中间的元素,则搜索结束。
- 最后,如果在整个数组中未找到键,则应返回
-1
。这表示元素不存在。
以下示例代码实现了二分搜索:
public static int binarySearch(int arr[], int low, int high, int key) {
int mid = (low + high) / 2;
while (low <= high) {
if (arr[mid] < key) {
low = mid + 1;
} else if (arr[mid] == key) {
return mid;
} else {
high = mid - 1;
}
mid = (low + high) / 2;
}
if (low > high) {
return -1;
}
return -1;
}
15. 编写一个Java程序,演示归并排序。
Merge sort 是最有效率的排序算法之一。它運作的原理是「分而治之」。它基於將列表分解為多個子列表的想法,直到每個子列表只包含一個元素,然後以一種方式合併這些子列表,以得到一個排序好的列表。以下是一個示例代碼,展示了使用合併排序的一種方式:
public class MergeSort {
public static void main(String[] args) {
int[] arr = { 70, 50, 30, 10, 20, 40, 60 };
int[] merged = mergeSort(arr, 0, arr.length - 1);
for (int val : merged) {
System.out.print(val + " ");
}
}
public static int[] mergeTwoSortedArrays(int[] one, int[] two) {
int[] sorted = new int[one.length + two.length];
int i = 0;
int j = 0;
int k = 0;
while (i < one.length && j < two.length) {
if (one[i] < two[j]) {
sorted[k] = one[i];
k++;
i++;
} else {
sorted[k] = two[j];
k++;
j++;
}
}
if (i == one.length) {
while (j < two.length) {
sorted[k] = two[j];
k++;
j++;
}
}
if (j == two.length) {
while (i < one.length) {
sorted[k] = one[i];
k++;
i++;
}
}
return sorted;
}
public static int[] mergeSort(int[] arr, int lo, int hi) {
if (lo == hi) {
int[] br = new int[1];
br[0] = arr[lo];
return br;
}
int mid = (lo + hi) / 2;
int[] fh = mergeSort(arr, lo, mid);
int[] sh = mergeSort(arr, mid + 1, hi);
int[] merged = mergeTwoSortedArrays(fh, sh);
return merged;
}
}
16. 你能在 Java 中創建一個字符金字塔嗎?
模式程序是一個非常熱門的面試話題。這類問題用於了解面試者的邏輯思維能力。參考Java 中的金字塔模式程序以查看創建金字塔模式的不同方法的示例。
17. 編寫一個 Java 程序,檢查兩個數組是否包含相同的元素。
檢查兩個陣列是否包含相同元素,需要先從這兩個陣列創建一個元素集合,然後比較這些集合中的元素,以找出是否存在一個元素不在兩個集合中都存在。以下示例代碼顯示如何檢查兩個陣列是否只包含共同元素:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class ArraySameElements {
public static void main(String[] args) {
Integer[] a1 = {1,2,3,2,1};
Integer[] a2 = {1,2,3};
Integer[] a3 = {1,2,3,4};
System.out.println(sameElements(a1, a2));
System.out.println(sameElements(a1, a3));
}
static boolean sameElements(Object[] array1, Object[] array2) {
Set<Object> uniqueElements1 = new HashSet<>(Arrays.asList(array1));
Set<Object> uniqueElements2 = new HashSet<>(Arrays.asList(array2));
// 如果大小不同,意味著會有不匹配
if (uniqueElements1.size() != uniqueElements2.size()) return false;
for (Object obj : uniqueElements1) {
// 在兩者中均不包含的元素?
if (!uniqueElements2.contains(obj)) return false;
}
return true;
}
}
Outputtrue
false
18. 如何在Java中獲取整數陣列中所有元素的總和?
您可以使用 for
循環來遍歷陣列元素並將它們相加以獲得最終總和:
int[] array = { 1, 2, 3, 4, 5 };
int sum = 0;
for (int i : array)
sum += i;
System.out.println(sum);
19. 如何在Java中找到陣列中第二大的數字?
有很多方法可以解決這個問題。您可以將陣列按自然升序排序並取第二倒數值。然而,排序是一個昂貴的操作。您也可以使用兩個變量在單次迭代中找到第二大的值,如下示例所示:
private static int findSecondHighest(int[] array) {
int highest = Integer.MIN_VALUE;
int secondHighest = Integer.MIN_VALUE;
for (int i : array) {
if (i > highest) {
secondHighest = highest;
highest = i;
} else if (i > secondHighest) {
secondHighest = i;
}
}
return secondHighest;
}
20. 如何在Java中对数组进行洗牌?
以下示例代码展示了如何使用Random
类生成随机索引并对元素进行洗牌:
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
int randomIndexToSwap = rand.nextInt(array.length);
int temp = array[randomIndexToSwap];
array[randomIndexToSwap] = array[i];
array[i] = temp;
}
System.out.println(Arrays.toString(array));
您可以在另一个for
循环内运行洗牌代码以进行多轮洗牌。
21. 如何在Java中在文本文件中查找字符串?
以下示例代码展示了如何使用Scanner
类逐行读取文件内容,然后使用String contains()
方法检查字符串是否存在于文件中:
boolean findStringInFile(String filePath, String str) throws FileNotFoundException {
File file = new File(filePath);
Scanner scanner = new Scanner(file);
// 逐行读取文件
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains(str)) {
scanner.close();
return true;
}
}
scanner.close();
return false;
}
请注意,示例代码假定在文件中搜索的字符串不包含换行符。
22. 如何在Java中以特定格式打印日期?
以下示例代碼顯示如何使用SimpleDateFormat
類來格式化日期字符串:
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String date = simpleDateFormat.format(new Date());
System.out.println(date); // 06-23-2020
了解更多關於Java SimpleDateFormat的信息。
23. 如何在Java中合併兩個列表?
以下示例代碼顯示如何使用addAll()
方法在Java中合併多個列表:
List<String> list1 = new ArrayList<>();
list1.add("1");
List<String> list2 = new ArrayList<>();
list2.add("2");
List<String> mergedList = new ArrayList<>(list1);
mergedList.addAll(list2);
System.out.println(mergedList); // [1, 2]
24. 編寫一個Java程序,按值對HashMap進行排序。
HashMap
不是有序集合。以下示例代碼顯示如何根據值對項目進行排序並將它們存儲到LinkedHashMap
中,該集合保持插入的順序:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class SortHashMapByValue {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("David", 95);
scores.put("Jane", 80);
scores.put("Mary", 97);
scores.put("Lisa", 78);
scores.put("Dino", 65);
System.out.println(scores);
scores = sortByValue(scores);
System.out.println(scores);
}
private static Map<String, Integer> sortByValue(Map<String, Integer> scores) {
Map<String, Integer> sortedByValue = new LinkedHashMap<>();
// 獲取條目集
Set<Entry<String, Integer>> entrySet = scores.entrySet();
System.out.println(entrySet);
// 創建列表,因為集合是無序的
List<Entry<String, Integer>> entryList = new ArrayList<>(entrySet);
System.out.println(entryList);
// 按值對列表進行排序
entryList.sort((x, y) -> x.getValue().compareTo(y.getValue()));
System.out.println(entryList);
// 填充新哈希映射
for (Entry<String, Integer> e : entryList)
sortedByValue.put(e.getKey(), e.getValue());
return sortedByValue;
}
}
25. 如何在Java中從輸入字符串中刪除所有給定字符的出現?
String
類沒有刪除字符的方法。以下示例代碼顯示如何使用 replace()
方法創建一個不包含給定字符的新字符串:
String str1 = "abcdABCDabcdABCD";
str1 = str1.replace("a", "");
System.out.println(str1); // bcdABCDbcdABCD
在Java中,字符串是不可變的。所有字符串操作方法都返回一個新字符串,這就是為什麼你需要將其分配給另一個變量。了解更多關於在Java中從字符串中刪除字符的信息。
26. 如何在Java中获取字符串中不同字符及其计数?
您可以从字符串创建字符数组,然后遍历它并使用字符作为键,它们的计数作为值创建一个HashMap
。以下示例代码展示了如何提取和计算字符串的字符:
String str1 = "abcdABCDabcd";
char[] chars = str1.toCharArray();
Map<Character, Integer> charsCount = new HashMap<>();
for (char c : chars) {
if (charsCount.containsKey(c)) {
charsCount.put(c, charsCount.get(c) + 1);
} else
charsCount.put(c, 1);
}
System.out.println(charsCount); // {a=2, A=1, b=2, B=1, c=2, C=1, d=2, D=1}
27. 你能证明Java中的String对象是不可变的吗?
以下示例代码演示了如何证明String
对象是不可变的,代码中的注释解释了每个步骤:
String s1 = "Java"; // 創建在池中的 "Java" 字串並將參考指派給 s1
String s2 = s1; // s2 也具有相同的參考指向池中的 "Java"
System.out.println(s1 == s2); // 證明 s1 和 s2 具有相同的參考
s1 = "Python";
// 上面更改了 s1 的值,那麼字符串是如何不可變的呢?
// 在上面的情況下,在池中創建了一個新的字符串 "Python"
// 現在 s1 正引用池中的新字符串
// 但是,原始字符串 "Java" 仍然未更改且保留在池中
// s2 仍然引用池中的原始字符串 "Java"
// 證明 s1 和 s2 具有不同的引用
System.out.println(s1 == s2);
System.out.println(s2);
// 打印 "Java",支持原始字符串值未更改的事實,因此字符串是不可變的
28. 你能寫一些展示 Java 中繼承的代碼嗎?
以下示例代碼顯示了如何使用extends
關鍵字創建Animal
類的子類。新類Cat
繼承自Animal
類的變量,並添加了屬於Cat
類的代碼。
class Animal {
String color;
}
class Cat extends Animal {
void meow() {
System.out.println("Meow");
}
}
29. 如何在Java中展示具有多重繼承的菱形問題?
當一個類從多個類繼承並且不明確地指定了從哪個類執行方法時,就會出現菱形問題。為了避免菱形問題,Java不允許擴展多個類,下面的示例說明了這個問題:
interface I {
void foo();
}
class A implements I {
public void foo() {}
}
class B implements I {
public void foo() {}
}
class C extends A, B { // 不會編譯
public void bar() {
super.foo();
}
}
30. 如何在Java中舉例try catch?
以下示例代碼展示了try-catch的示例:
try {
FileInputStream fis = new FileInputStream("test.txt");
} catch(FileNotFoundException e) {
e.printStackTrace();
}
從Java 7開始,您還可以在單個catch塊中捕獲多個異常,如下例所示。當所有catch塊中的代碼相同時,這很有用。
public static void foo(int x) throws IllegalArgumentException, NullPointerException {
// 一些代碼
}
public static void main(String[] args) {
try {
foo(10);
} catch (IllegalArgumentException | NullPointerException e) {
System.out.println(e.getMessage());
}
}
31. 撰寫一個 Java 程式來展示 NullPointerException
。
如果您在 null
上調用函數,它將拋出 NullPointerException
,如下面的範例代碼所示:
public static void main(String[] args) {
printString(null, 3);
}
static void printString(String s, int count) {
for (int i = 0; i < count; i++) {
System.out.println(s.toUpperCase()); // Exception in thread "main" java.lang.NullPointerException
}
}
您應該在程式中進行空值檢查以進行早期驗證,如下面的範例代碼所示:
static void printString(String s, int count) {
if (s == null) return;
for (int i = 0; i < count; i++) {
System.out.println(s.toUpperCase());
}
}
根據專案需求,您也可以拋出 IllegalArgumentException
。
32. 如何在 Java 中創建一個記錄?
記錄是 Java 16 中新增的標準功能。記錄使您能夠使用最少的代碼創建一個 POJO 類。記錄自動為類生成 hashCode()
、equals()
、getter 方法和 toString()
方法代碼。記錄是 final 的,並隱式擴展了 java.lang.Record
類。下面的範例代碼展示了創建記錄的一種方式:
import java.util.Map;
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
}
了解有关在Java中的记录。有关POJO的详细信息,请参阅维基百科上的“Plain old Java object”
33. 如何在Java中创建文本块?
Java 15添加了文本块功能。您可以使用文本块创建多行字符串。多行字符串必须写在一对三重双引号之间,如下例所示:
String textBlock = """
Hi
Hello
Yes""";
这与创建字符串相同,例如Hi\\nHello\\nYes
。
34. 在Java中显示switch表达式和多标签case语句的示例。
在Java 14中,添加了switch表达式作为标准功能。以下示例显示了switch表达式以及多标签case语句:
int choice = 2;
int x = switch (choice) {
case 1, 2, 3:
yield choice;
default:
yield -1;
};
System.out.println("x = " + x); // x = 2
您还可以在switch表达式中使用lambda表达式。
String day = "TH";
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if (day.isEmpty())
yield "Please insert a valid day.";
else
yield "Looks like a Sunday.";
}
};
System.out.println(result); // TTH
35. 如何從命令行編譯和運行 Java 類?
此示例涉及以下 Java 文件:
public class Test {
public static void main(String args[]) {
System.out.println("Hi");
}
}
您可以在終端中使用以下命令編譯它:
- javac Test.java
要運行該類,請在終端中使用以下命令:
- java Test
對於最近的版本,如果類文件不存在,java
命令也會編譯程序。 如果類位於包中,例如 com.example
,則應該位於文件夾 com/example
內。 編譯和運行的命令是:
- java com/example/Test.java
如果您的類需要一些額外的 JAR 文件來編譯和運行,您可以使用 java -cp
選項。 例如:
- java -cp .:~/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar com/example/Test.java
36. 如何在 Java 中創建枚舉?
以下示例代碼顯示了如何創建基本枚舉:
public enum ThreadStates {
START,
RUNNING,
WAITING,
DEAD;
}
ThreadStates
是具有固定常量字段 START
, RUNNING
, WAITING
, 和 DEAD
的枚举。所有枚举隐式扩展了 java.lang.Enum
类,并实现了 Serializable
和 Comparable
接口。枚举也可以有方法。了解更多关于 Java 中的枚举。
37. 如何在 Java 中使用 forEach()
方法?
forEach()
方法提供了一种快捷方式,可对可迭代对象的所有元素执行操作。以下示例代码显示如何遍历列表元素并打印它们:
List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
您可以使用 lambda 表达式将 forEach()
方法与 lambda 表达式一起使用,以减少代码量,如下例所示:
List<String> list = new ArrayList<>();
list.forEach(System.out::print);
38. 如何编写具有 default
和 static
方法的接口?
Java 8 在介面中引入了預設(default)和靜態(static)方法。這彌合了介面與抽象類之間的差距。以下示例代碼展示了使用 default
和 static
方法撰寫介面的一種方式:
public interface Interface1 {
// regular abstract method
void method1(String str);
default void log(String str) {
System.out.println("I1 logging::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
了解更多關於介面中 default
和 static
方法的資訊,請參閱 Java 8 interface changes。
39. 如何創建功能介面?
僅具有一個抽象方法的介面稱為功能介面。功能介面的主要好處在於您可以使用 Lambda 表達式來實例化它們,而無需使用冗長的匿名類實現。 @FunctionalInterface
注釋指示了功能介面,如以下示例代碼所示:
@FunctionalInterface
interface Foo {
void test();
}
40. 在 Java 中使用 Lambda 表達式的示例。
`Runnable` 是一個功能介面的優秀範例。您可以使用 Lambda 表達式來創建一個可運行對象,如下面的範例代碼所示:
Runnable r1 = () -> System.out.println("My Runnable");
41. 展示 Java 中的重載和覆寫的示例。
當一個類有兩個或更多同名方法時,它們被稱為重載方法。下面的範例代碼展示了一個名為 print
的重載方法:
class Foo {
void print(String s) {
System.out.println(s);
}
void print(String s, int count) {
while (count > 0) {
System.out.println(s);
count--;
}
}
}
當一個父類方法在子類中也被實現時,這被稱為覆寫。下面的範例代碼展示了如何註釋在兩個類中都實現的 printname()
方法:
class Base {
void printName() {
System.out.println("Base Class");
}
}
class Child extends Base {
@Override
void printName() {
System.out.println("Child Class");
}
}
了解更多關於 Java 中的覆寫和重載。
42.-49. 猜測輸出
通過猜測以下代碼片段的輸出來測試自己。
String s1 = "abc";
String s2 = "abc";
System.out.println("s1 == s2 is:" + s1 == s2);
Output
false
給定語句的輸出是false
,因為+
運算符的優先級高於==
運算符。因此,給定的表達式被評估為“s1 == s2 is:abc” == “abc”
,這是false
。
String s3 = "JournalDev";
int start = 1;
char end = 5;
System.out.println(s3.substring(start, end));
Output
ourn
以下是給定敘述的輸出:ourn
。第一個字符自動轉換為int
。然後,由於第一個字符索引為0,它將從o
開始並打印到n
。請注意,String substring
方法創建一個從索引start
開始並延伸到索引end - 1
的子字符串。
HashSet shortSet = new HashSet();
for (short i = 0; i < 100; i++) {
shortSet.add(i);
shortSet.remove(i - 1);
}
System.out.println(shortSet.size());
Output
100
shortSet
的大小為100
。Java中的自動裝箱功能意味著具有基本類型short
的表達式i
轉換為Short
對象。同樣,表達式i - 1
具有基本類型int
並被自動裝箱為Integer
對象。由於HashSet
中沒有Integer
對象,因此不會刪除任何內容,大小為100
。
try {
if (flag) {
while (true) {
}
} else {
System.exit(1);
}
} finally {
System.out.println("In Finally");
}
Output
沒有輸出。如果標誌為true
,則此代碼導致無窮循環;如果標誌為false
,則程序退出。finally
區塊永遠不會被執行。
String str = null;
String str1="abc";
System.out.println(str1.equals("abc") | str.equals(null));
Output
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "<local1>" is null
給定的打印語句將拋出java.lang.NullPointerException
,因為OR
邏輯運算符在返回結果之前評估兩個文字。由於str
為null
,.equals()
方法將拋出異常。建議始終使用短路邏輯運算符,例如||
和&&
,這將從左到右評估文字值。在這種情況下,由於第一個文字將返回true
,它將跳過第二個文字的評估。
String x = "abc";
String y = "abc";
x.concat(y);
System.out.print(x);
Output
abc
x.concat(y)
創建一個新的字串,但並未指派給 x
,因此 x
的值未改變。
public class MathTest {
public void main(String[] args) {
int x = 10 * 10 - 10;
System.out.println(x);
}
}
Output
Error: Main method is not static in class MathTest, please define the main method as:
public static void main(String[] args)
儘管這個問題看起來是關於數學運算符的執行順序,但實際上是關於注意到 main 方法 未被宣告為 static
。
public class Test {
public static void main(String[] args) {
try {
throw new IOException("Hello");
} catch(IOException | Exception e) {
System.out.println(e.getMessage());
}
}
}
Output
Test.java:5: error: cannot find symbol
throw new IOException("Hello");
^
symbol: class IOException
location: class Test
Test.java:6: error: cannot find symbol
}catch(IOException | Exception e) {
^
symbol: class IOException
location: class Test
2 errors
這段程式碼導致編譯時錯誤。例外 IOException
已被另一個 Exception
捕獲。
50. 在以下程式碼片段中找出 5 個錯誤。
package com.digitalocean.programming-interviews;
public class String Programs {
static void main(String[10] args) {
String s = "abc"
System.out.println(s);
}
}
Answers
- 套件名稱不能有連字符。
- 類別名稱不能有空格。
- main 方法不是
public
,所以不會執行。 - main 方法的引數不應該指定大小。
- 字串定義中缺少分號。
結論
這 50 個 Java 程式設計面試問題的集合包含從初學者到專家級別的問題,幫助您為面試做好準備。
推薦閱讀:
Source:
https://www.digitalocean.com/community/tutorials/java-programming-interview-questions