資料來源:Dev.to 各位開發人員大家好,我整理了一份每個程式設計師都應該知道的基本 Java 面試問題清單。
1. 如何在Java中不使用reverse()方法來反轉字串?
答: Java中沒有標準的reverse()方法,儘管reverse()方法存在於多個庫中,例如StringBuffer或StringBuilder。因此,面試中常會遇到陣列反轉的問題。下面是一個可用於反轉數組的簡單演算法。public class StringReverse {
public static void main(String[] args) {
String str = "Flexiple";
System.out.println(reverse(str));
}
public static String reverse(String in) {
if (in == null)
throw new IllegalArgumentException("Null is not valid");
StringBuilder out = new StringBuilder();
char[] chars = in.toCharArray();
for (int i = chars.length - 1; i >= 0; i--)
out.append(chars[i]);
return out.toString();
}
}
2.編寫程式碼片段,使用遞迴實作斐波那契數列
答:下面的程式碼片段使用遞歸實作了斐波那契數列。這個問題在Java面試中也很常見。public class FibonacciNumbers {
public static int fibonacci(int n) {
if (n <= 1)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void main(String args[]) {
int n = 10;
System.out.println(fibonacci(n));
}
}
3. Java中如何刪除字串中的空格?
答案:strip()方法是一個字串方法,用於刪除所有前導和尾隨空格。Strip()在內部使用Character.isWhitespace()方法來檢查空格。它使用 Unicode 字元檢測空格,並且是刪除空格的建議方法。也可以使用替代方法stripLeading()和stripTrailing()。如果您只想分別刪除前導空格或尾隨空格,它們將有所幫助。下面的程式碼是使用strip()方法的範例。String s = " flexiple ";
s = s.strip();
System.out.println(s);
4. 什麼原因導致死鎖場景?編寫程式碼造成死鎖
答:當兩個執行緒需要相同的鎖來執行時,就會出現死鎖情況。當兩個執行緒都已取得一個鎖並正在等待取得另一個鎖時,就會發生這些情況。但是,由於兩個執行緒都在等待對方執行,因此它們會互相阻塞,導致死鎖。多執行緒程式會遇到死鎖,因為使用了synchronized關鍵字來讓方法執行緒安全。這意味著只有一個執行緒可以阻塞並使用同步方法。其他線程必須等待當前線程完成。下面的程式碼創建了兩個死鎖的線程。class Util
{
static void sleep(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class Shared
{
synchronized void test1(Shared s2)
{
System.out.println("test1-begin");
Util.sleep(1000);
s2.test2();
System.out.println("test1-end");
}
synchronized void test2()
{
System.out.println("test2-begin");
Util.sleep(1000);
System.out.println("test2-end");
}
}
class Thread1 extends Thread
{
private Shared s1;
private Shared s2;
public Thread1(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run()
{
s1.test1(s2);
}
}
class Thread2 extends Thread
{
private Shared s1;
private Shared s2;
public Thread2(Shared s1, Shared s2)
{
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run()
{
s2.test2(s1);
}
}
public class Deadlock
{
public static void main(String[] args)
{
Shared s1 = new Shared();
Shared s2 = new Shared();
Thread1 t1 = new Thread1(s1, s2);
t1.start();
Thread2 t2 = new Thread2(s1, s2);
t2.start();
Util.sleep(2000);
}
}
5.編寫Java程式碼以特定格式列印日期
答案:SimpleDateFormat類別有助於將日期從一種格式轉換為另一種格式。此方法還允許使用者使用日期字串格式並將其變更為所需的格式。下面的程式碼將日期轉換為標準格式:DD/MM/YYYYimport java.text.SimpleDateFormat;
import java.util.Date;
public class CurrentDateTimeExample2 {
public static void main(String[] args) {
SimpleDateFormat formatter = new SimpleDateFormat("DD/MM/YYYY HH:mm:ss");
Date date = new Date();
System.out.println(formatter.format(date));
}
}
將日期轉換為 MM/DD/YYYY 的程式碼片段:
import java.text.SimpleDateFormat;
import java.util.Date;
public class CurrentDateTimeExample2 {
public static void main(String[] args) {
SimpleDateFormat formatter = new SimpleDateFormat("MM/DD/YYYY HH:mm:ss");
Date date = new Date();
System.out.println(formatter.format(date));
}
}
6. 如何依照 HashMap 的值對 HashMap 進行排序?
答: HashMap用於實作map介面。它們允許使用者儲存鍵值對,但鍵必須是唯一的。 HashMap不是有序集合,對它們進行排序沒有意義,但由於對 hashmap 進行排序可能相當棘手,因此它們是 Java 面試中的常見問題。下面的程式碼顯示了HashMap的實作。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 SortHashMap {
public static void main(String[] args) {
Map scores = new HashMap<>();
scores.put("John", 6);
scores.put("Carol", 8);
scores.put("Martin", 9);
scores.put("Mona", 7);
scores.put("Eric", 5);
System.out.println(scores);
scores = sortByValue(scores);
System.out.println(scores);
}
private static Map sortByValue(Map scores) {
Map sorted = new LinkedHashMap<>();
Set> entrySet = scores.entrySet();
System.out.println(entrySet);
List> entryList = new ArrayList<>(entrySet);
System.out.println(entryList);
entryList.sort((x, y) -> x.getValue().compareTo(y.getValue()));
System.out.println(entryList);
for (Entry e : entryList)
sorted.put(e.getKey(), e.getValue());
return sorted;
}
}
7. forEach() 方法的作用是什麼?舉例說明
Ans: forEach()是Java中用來迭代物件的方法。但與其他循環不同的是,這裡的循環計數器沒有聲明或初始化,而是將變數作為可迭代物件傳遞。因此,forEach()通常與陣列或集合類別一起使用。句法:for (type var : array)
{
statements using var;
}
使用forEach()的範例:
class ExampleForEach
{
public static void main(String[] arg)
{
{
int[] scores = { 10, 13, 9, 11, 11};
int highest_score = maximum(scores);
System.out.println(highest_scores);
}
}
public static int maximum(int[] numbers)
{
int max = numbers[0];
// for each loop
for (int n : numbers)
{
if (n > max)
{
max = n;
}
}
return max;
}
}
8. 什麼是函數式介面以及它們是如何被建立的?
答:僅包含一個抽象方法的介面稱為函數式介面。因此,函數式介面只能有一個函數,但可以包含多個預設方法。在 Java 8 中,lambda 表達式可用於實例化函數式接口,使事情變得更加容易。函數式介面的範例:ActionListener、Comparable。這是用於定義功能介面的程式碼。@FunctionalInterface
interface Foo {
void test();
}
9.舉例描述重載
答:重載是解析具有相同名稱但根據其簽章、資料型別或參數數量而不同的多個方法的過程。重載允許使用者重複使用單一方法,而不是建立和記住多個方法。簡而言之,重載與編譯時多態性有關。方法重載範例程式碼:public class Sum {
public int sum(int x, int y)
{
return (x + y);
}
public int sum(int x, int y, int z)
{
return (x + y + z);
}
public double sum(double x, double y)
{
return (x + y);
}
public static void main(String args[])
{
Sum s = new Sum();
System.out.println(s.sum(10, 20));
System.out.println(s.sum(10, 20, 30));
System.out.println(s.sum(10.5, 20.5));
}
}
10.透過範例描述覆蓋
Ans:重寫是Java中的功能,它允許子類別或子類別為父類別中的現有方法提供單獨的實作。當子類別中的方法與父類別中的方法具有相同的名稱、參數和傳回類型時,方法將覆寫父類別中的方法。並且被呼叫方法的版本決定了要執行哪個方法。重寫是一種在運行時實現多態性的方法。方法覆蓋程式碼範例:class Parent {
void show()
{
System.out.println("Parent's show()");
}
}
class Child extends Parent {
@Override
void show()
{
System.out.println("Child's show()");
}
}
class Main {
public static void main(String[] args)
{
Parent obj1 = new Parent();
obj1.show();
Parent obj2 = new Child();
obj2.show();
}
}
11.什麼是二分查找?這是如何實施的?
答案:二分查找演算法用於在排序數組或集合類型中尋找值。這種搜尋方法比線性搜尋方法快得多。二分找出將陣列分成更小的集合,然後套用規則來檢查輸入鍵。 實現二分(binary)搜尋的階段:- 依升序對數組進行排序。
- 找到數組的平均值並與鍵進行比較。
- 如果鍵等於平均值,則傳回 true。
- 如果為 false,則檢查鍵是否大於或小於平均值。
- 接下來,根據結果,分別檢查上半部或下半部的密鑰。
- 迭代每個值並將其與鍵進行比較。
import java.util.Scanner;
public class BinarySearch {
public static void main(String[] args) {
Scanner commandReader = new Scanner(System.in);
System.out.println("Enter total number of elements : ");
int length = commandReader.nextInt();
int[] input = new int[length];
System.out.printf("Enter %d integers %n", length);
for (int i = 0; i < length; i++) {
input[i] = commandReader.nextInt();
}
System.out.println("Please enter number to be searched in array
(sorted order)");
int key = commandReader.nextInt();
int index = performBinarySearch(input, key);
if (index == -1) {
System.out.printf("Sorry, %d is not found in array %n", key);
} else {
System.out.printf("%d is found in array at index %d %n", key,
index);
}
commandReader.close();
}
public static int performBinarySearch(int[] input, int number) {
int low = 0;
int high = input.length - 1;
while (high >= low) {
int middle = (low + high) / 2;
if (input[middle] == number) {
return middle;
} else if (input[middle] < number) {
low = middle + 1;
} else if (input[middle] > number) {
high = middle - 1;
}
}
return -1;
}
}
12. Java中防止死鎖的最佳方法是什麼?
答:- 嵌套鎖:死鎖的主要原因是將鎖傳遞給多個執行緒。如果已存在具有阻塞的線程,則避免阻塞多個線程有助於防止死鎖。
- 使用Thread.join():當一個執行緒等待另一個執行緒的資源時,也可能會發生死鎖。但是,在這種情況下,可以使用Thread.join()來實現最大執行時間。
- 僅在必要時使用鎖定:練習僅在必要時對元素使用鎖定。不必要的鎖是死鎖的主要原因。
13.編寫Java實作LRU快取的程式碼
答: LRU 代表最少使用的快取。LRU快取方案用於刪除最後使用的快取。當現有快取已滿並且被引用的新頁面不在現有快取中時,會發生此過程。下面的程式碼展示了實作:import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Iterator;
public class LRUCache {
private Deque doublyQueue;
private HashSet hashSet;
private final int CACHE_SIZE;
LRUCache(int capacity) {
doublyQueue = new LinkedList<>();
hashSet = new HashSet<>();
CACHE_SIZE = capacity;
}
public void refer(int page) {
if (!hashSet.contains(page)) {
if (doublyQueue.size() == CACHE_SIZE) {
int last = doublyQueue.removeLast();
hashSet.remove(last);
}
}
else {/* The found page may not be always the last element, even if it's an
intermediate element that needs to be removed and added to the start
of the Queue */
doublyQueue.remove(page);
}
doublyQueue.push(page);
hashSet.add(page);
}
public void display() {
Iterator itr = doublyQueue.iterator();
while (itr.hasNext()) {
System.out.print(itr.next() + " ");
}
}
public static void main(String[] args) {
LRUCache cache = new LRUCache(4);
cache.refer(1);
cache.refer(2);
cache.refer(3);
cache.refer(1);
cache.refer(4);
cache.refer(5);
cache.refer(2);
cache.refer(2);
cache.refer(1);
cache.display();
}
}
14. 陣列如何根據 K 的位置旋轉,例如 k = 2?
答:程式碼片段根據指定的位置旋轉(返回)陣列。雖然看起來很簡單,但它考驗的是你對循環和陣列的理解,因此是 Java 面試中的常見問題。public static int[] rotateBruteForce(int[] nums, int k) {
for (int i = 0; i < k; i++) {
for (int j = nums.length - 1; j > 0; j--) {
// move each number by 1 place
int temp = nums[j];
nums[j] = nums[j - 1];
nums[j - 1] = temp;
}
System.out.println("Array rotation after "+(i+1)+" step");
printArray(nums);
System.out.println();
}
return nums;
}
15.Java中的佇列是什麼?使用數組來實現它們。
答:隊列是線性結構,以先到先服務的方式展示操作順序。Java 確實為佇列、堆疊等抽象資料型別提供了更簡單的實作。然而,使用陣列實現它們是一個考驗你對這個概念的理解的問題。請記住,佇列的數組實作不是動態的。package org.arpit.java2blog;
public class QueueUsingArrayMain {
private int capacity;
int queueArr[];
int front;
int rear;
int currentSize = 0;
public QueueUsingArrayMain(int sizeOfQueue) {
this.capacity = sizeOfQueue;
front = 0;
rear = -1;
queueArr = new int[this.capacity];
}
16.什麼是堆排序?編寫程式碼來實現它
答: HeapSort是一種基於二元堆資料結構的排序方法。二元堆是一棵二元樹,其中元素的儲存方式是父節點中的值大於(最大堆)或小於(最小堆)子節點中的值。實作HeapSort的程式碼如下所示:public class HeapSort {
public void sort(int arr[])
{
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i + 1; // left = 2*i + 1
int r = 2 * i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i) {
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver code
public static void main(String args[])
{
int arr[] = { 12, 11, 13, 5, 6, 7 };
int n = arr.length;
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("Sorted array is");
printArray(arr);
}
}
17. 什麼是記憶化?
答:記憶化是一種有助於解決動態規劃所引起的問題的方法。此過程可確保不會對相同輸入多次執行給定方法。返回值儲存在雜湊表或雜湊映射中,並根據需要重複使用。下面的程式碼是斐波那契數列記憶的範例。import java.io.*;
class GFG
{
// Fibonacci Series
// using Recursion
static int fib(int n)
{
// Base case
if (n <= 1)
return n;
// recursive calls
return fib(n - 1) +
fib(n - 2);
}
// Driver Code
public static void main (String[] args)
{
int n = 6;
System.out.println(fib(n));
}
}
18.編寫一段程式碼實現冒泡排序
答:下面的程式碼是冒泡排序的解決方案,這也是Java面試中的常見問題。public class BubbleSortExample {
static void bubbleSort(int[] arr) {
int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){
if(arr[j-1] > arr[j]){
//swap elements
temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
}
}
}
}
public static void main(String[] args) {
int arr[] ={3,60,35,2,45,320,5};
System.out.println("Array Before Bubble Sort");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
bubbleSort(arr);//sorting array elements using bubble sort
System.out.println("Array After Bubble Sort");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
19. Java中的trie資料結構是什麼?
Ans: Trie 是一種使用儲存鍵將資料儲存在有序樹結構中的資料結構。節點在樹中的位置決定了與該節點關聯的鍵,並且該節點的後代共享一個公共前綴。由於這種結構,嘗試提供了更好的性能並且更快地檢索資料。然而,使用木材的唯一缺點是它需要更多的儲存空間。20.編寫一段程式碼將HashMap轉換為ArrayList
答:下面的程式碼用於將HashMap轉換為ArrayList。import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
public class Java8MapToListExamples
{
public static void main(String[] args)
{
//Creating a HashMap object
HashMap studentPerformanceMap = new HashMap();
//Adding elements to HashMap
studentPerformanceMap.put("John Kevin", "Average");
studentPerformanceMap.put("Rakesh Sharma", "Good");
studentPerformanceMap.put("Prachi D", "Very Good");
studentPerformanceMap.put("Ivan Jose", "Very Bad");
studentPerformanceMap.put("Smith Jacob", "Very Good");
studentPerformanceMap.put("Anjali N", "Bad");
//Getting Set of keys
Set keySet = studentPerformanceMap.keySet();
//Creating an ArrayList of keys
ArrayList listOfKeys = new ArrayList(keySet);
System.out.println("ArrayList Of Keys :");
for (String key : listOfKeys)
{
System.out.println(key);
}
System.out.println("--------------------------");
//Getting Collection of values
Collection values = studentPerformanceMap.values();
//Creating an ArrayList of values
ArrayList listOfValues = new ArrayList(values);
System.out.println("ArrayList Of Values :");
for (String value : listOfValues)
{
System.out.println(value);
}
System.out.println("--------------------------");
//Getting the Set of entries
Set> entrySet = studentPerformanceMap.entrySet();
//Creating an ArrayList Of Entry objects
ArrayList> listOfEntry = new ArrayList>(entrySet);
System.out.println("ArrayList of Key-Values :");
for (Entry entry : listOfEntry)
{
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
}
GO TO FULL VERSION