웹사이트 검색

상위 50개의 Java 프로그래밍 인터뷰 질문


소개

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에서 세 번째 변수를 사용하지 않고 어떻게 두 숫자를 교환합니까?

세 번째 변수를 사용하지 않고 숫자를 교환하는 것은 코드에서 더 잘 시각화되는 3단계 프로세스입니다.

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);
    }

}

출력은 정수 값이 교체되었음을 보여줍니다.

Output
a 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 사이에 소수 M이 있는 경우( N의 제곱근)을 균등하게 나눈다면 N은 소수가 아닙니다.

5. 재귀를 사용하여 피보나치 수열을 인쇄하는 Java 프로그램을 작성하십시오.

피보나치 수열은 각 숫자가 이전 두 숫자의 합인 수열입니다. 이 예에서 시퀀스는 01로 시작합니다. 다음 예제 코드는 for 루프를 사용하여 피보나치 시퀀스를 인쇄하는 방법을 보여줍니다.

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);
	}

}
Output
0, 1, 1, 2, 3, 5, 8, 13, 21, 34,

또한 재귀를 사용하여 피보나치 수열을 인쇄할 수 있습니다. 피보나치 수는 수열에서 이전 두 수를 더하여 생성되기 때문입니다.

F(N) = F(N-1) + F(N-2)

다음 예제 클래스는 재귀를 사용하여 숫자 10개 길이의 피보나치 수열을 계산하는 방법을 보여줍니다.

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) + " ");
    	}
  	}

}
Output
A 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() // parallel stream for faster processing
			.anyMatch(x -> x % 2 != 0); // return as soon as any elements match the condition
}

정수가 홀수인지 결정하는 수학에 대해 자세히 알아보려면 Wikipedia의 Modulo 연산을 참조하세요.

7. Java에서 문자열이 회문인지 어떻게 확인합니까?

회문 문자열은 앞뒤로 같은 문자열입니다. 회문을 확인하려면 입력 문자열을 뒤집고 결과가 입력과 같은지 확인할 수 있습니다. 다음 예제 코드는 String charAt(int index) 메서드를 사용하여 회문 문자열을 확인하는 방법을 보여줍니다.

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( ) 문자가 공백인지 확인하는 메서드입니다. 이 메서드는 유니코드 코드 포인트를 사용하는 반면, trim() 메서드는 코드 포인트 값이 U+0020보다 작거나 같은 문자를 공백 문자로 식별합니다.

strip() 메서드는 유니코드 표준을 사용하기 때문에 공백을 제거하는 데 권장되는 방법입니다. 다음 예제 코드는 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 프로그램을 작성하십시오.

병합 정렬은 가장 효율적인 정렬 알고리즘 중 하나입니다. \분할 정복\의 원칙에 따라 작동합니다. 각 하위 목록이 단일 요소로 구성될 때까지 목록을 여러 하위 목록으로 나눈 다음 해당 하위 목록을 다음과 같은 방식으로 병합한다는 아이디어를 기반으로 합니다. 다음 예제 코드는 병합 정렬을 사용하는 한 가지 방법을 보여줍니다.

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 size is different, means there will be a mismatch
		if (uniqueElements1.size() != uniqueElements2.size()) return false;
		
		for (Object obj : uniqueElements1) {
			// element not present in both?
			if (!uniqueElements2.contains(obj)) return false;
		}
		
		return true;
	}

}
Output
true 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);

	// read the file line by line
	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. HashMap을 값별로 정렬하는 Java 프로그램을 작성하십시오.

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<>();

		// get the entry set
		Set<Entry<String, Integer>> entrySet = scores.entrySet();
		System.out.println(entrySet);

		// create a list since the set is unordered
		List<Entry<String, Integer>> entryList = new ArrayList<>(entrySet);
		System.out.println(entryList);

		// sort the list by value
		entryList.sort((x, y) -> x.getValue().compareTo(y.getValue()));
		System.out.println(entryList);

		// populate the new hash map
		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" String created in pool and reference assigned to s1

String s2 = s1; //s2 also has the same reference to "Java" in the pool

System.out.println(s1 == s2); // proof that s1 and s2 have the same reference

s1 = "Python"; 
//s1 value got changed above, so how String is immutable?

//in the above case a new String "Python" got created in the pool
//s1 is now referring to the new String in the pool 
//BUT, the original String "Java" is still unchanged and remains in the pool
//s2 is still referring to the original String "Java" in the pool

// proof that s1 and s2 have different reference
System.out.println(s1 == s2); 

System.out.println(s2); 
// prints "Java" supporting the fact that original String value is unchanged, hence String is immutable

28. Java에서 상속을 보여주는 코드를 작성할 수 있습니까?

다음 예제 코드는 extends 키워드를 사용하여 Animal 클래스의 하위 클래스를 만드는 방법을 보여줍니다. 새 클래스 CatAnimal 클래스에서 변수를 상속하고 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 { // won't compile
	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할 수도 있습니다. 모든 catch 블록에 동일한 코드가 있을 때 유용합니다.

public static void foo(int x) throws IllegalArgumentException, NullPointerException {
	// some code
}

public static void main(String[] args) {
	try {
		foo(10);
	} catch (IllegalArgumentException | NullPointerException e) {
		System.out.println(e.getMessage());
	}
}

31. NullPointerException을 표시하는 Java 프로그램을 작성하십시오.

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
	}
}

다음 예제 코드와 같이 초기 유효성 검사를 위해 null 검사를 수행해야 합니다.

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() 메서드 코드를 자동으로 생성합니다. 레코드는 최종이며 암시적으로 java.lang.Record 클래스를 확장합니다. 다음 예제 코드는 레코드를 생성하는 한 가지 방법을 보여줍니다.

import java.util.Map;
 
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
}

Wikipedia에서 Plain old Java object에 대해 자세히 알아보십시오.

33. Java에서 텍스트 블록을 어떻게 생성합니까?

Java 15에는 텍스트 블록 기능이 추가되었습니다. 텍스트 블록을 사용하여 여러 줄 문자열을 만들 수 있습니다. 여러 줄 문자열은 다음 예와 같이 삼중 이중 따옴표 쌍 안에 작성해야 합니다.

String textBlock = """
		Hi
		Hello
		Yes""";

Hi\nHello\nYes와 같은 문자열을 만드는 것과 같습니다.

34. Java에서 switch 표현식과 다중 레이블 case 문의 예를 보여줍니다.

스위치 표현식은 Java 14에서 표준 기능으로 추가되었습니다. 다음 예는 스위치 표현식과 다중 레이블 case 문을 보여줍니다.

int choice = 2;

int x = switch (choice) {
    case 1, 2, 3:
	    yield choice;
    default:
	    yield -1;
};

System.out.println("x = " + x); // x = 2

스위치 표현식에서 람다 표현식을 사용할 수도 있습니다.

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");
	}

}

터미널에서 다음 명령을 사용하여 컴파일할 수 있습니다.

  1. javac Test.java

클래스를 실행하려면 터미널에서 다음 명령을 사용하십시오.

  1. java Test

최신 릴리스의 경우 java 명령은 클래스 파일이 없는 경우에도 프로그램을 컴파일합니다. 클래스가 com.example과 같은 패키지에 있으면 com/example 폴더 안에 있어야 합니다. 컴파일 및 실행 명령은 다음과 같습니다.

  1. java com/example/Test.java

클래스에서 컴파일 및 실행을 위해 일부 추가 JAR이 필요한 경우 java -cp 옵션을 사용할 수 있습니다. 예를 들어:

  1. 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, WAITINGDEAD 가 있는 열거형입니다. . 모든 enum은 java.lang.Enum 클래스를 암시적으로 확장하고 SerializableComparable 인터페이스를 구현합니다. 열거형도 메서드를 가질 수 있습니다. Java의 열거형에 대해 자세히 알아보세요.

37. Java에서 forEach() 메서드를 어떻게 사용합니까?

forEach() 메서드는 iterable의 모든 요소에 대해 작업을 수행하는 바로 가기를 제공합니다. 다음 예제 코드는 목록 요소를 반복하고 인쇄하는 방법을 보여줍니다.

List<String> list = new ArrayList<>();

Iterator<String> it = list.iterator();

while (it.hasNext()) {
	System.out.println(it.next());
}

다음 예제 코드와 같이 람다 식과 함께 forEach() 메서드를 사용하여 코드 크기를 줄일 수 있습니다.

List<String> list = new ArrayList<>();

list.forEach(System.out::print);

38. 기본 및 정적 메서드로 인터페이스를 어떻게 작성합니까?

Java 8은 인터페이스에 기본 및 정적 메서드를 도입했습니다. 이것은 인터페이스와 추상 클래스 사이의 격차를 해소했습니다. 다음 예제 코드는 defaultstatic 메서드로 인터페이스를 작성하는 한 가지 방법을 보여줍니다.

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;
	}

}

Java 8 인터페이스 변경 사항에서 인터페이스의 defaultstatic 메서드에 대해 자세히 알아보세요.

39. 기능적 인터페이스는 어떻게 만드나요?

정확히 하나의 추상 메서드가 있는 인터페이스를 기능적 인터페이스라고 합니다. 기능적 인터페이스의 주요 이점은 람다 식을 사용하여 인스턴스화하고 부피가 큰 익명 클래스 구현을 피할 수 있다는 것입니다. @FunctionalInterface 주석은 다음 예제 코드와 같이 기능적 인터페이스를 나타냅니다.

@FunctionalInterface
interface Foo {
	void test();
}

40. Java에서 람다 식을 사용하는 예를 보여줍니다.

Runnable은 기능적 인터페이스의 훌륭한 예입니다. 다음 예제 코드와 같이 람다 식을 사용하여 실행 가능 항목을 만들 수 있습니다.

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);
false

+ 연산자가 == 연산자보다 우선 순위가 높기 때문에 주어진 문의 출력은 false입니다. 따라서 주어진 식은 \s1 == s2 is:abc” == \abc”로 평가되며, 이는 false입니다.

String s3 = "JournalDev";
int start = 1;
char end = 5;

System.out.println(s3.substring(start, end));
ourn

주어진 문의 출력은 ourn입니다. 첫 번째 문자는 자동으로 int로 유형 변환됩니다. 그러면 첫 번째 문자 인덱스가 0이므로 o부터 시작하여 n까지 인쇄됩니다. 문자열 하위 문자열 메서드는 인덱스 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());
100

shortSet의 크기는 100입니다. Java의 오토박싱 기능은 프리미티브 유형 short를 갖는 표현식 iShort 객체로 변환됨을 의미합니다. 유사하게 i - 1 표현식은 기본 유형 int를 가지며 Integer 객체에 오토박싱됩니다. HashSetInteger 객체가 없기 때문에 아무 것도 제거되지 않으며 크기는 100입니다.

try {
	if (flag) {
  		while (true) {
   		}
   	} else {
   		System.exit(1);
   	}
} finally {
   	System.out.println("In Finally");
}

출력이 없습니다. 이 코드는 플래그가 true인 경우 무한 루프를 발생시키고 플래그가 false인 경우 프로그램이 존재합니다. finally 블록에는 절대 도달하지 않습니다.

String str = null;
String str1="abc";

System.out.println(str1.equals("abc") | str.equals(null));
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because "<local1>" is null

주어진 인쇄 문은 OR 논리 연산자가 결과를 반환하기 전에 두 리터럴을 모두 평가하기 때문에 java.lang.NullPointerException을 발생시킵니다. strnull이므로 .equals() 메서드는 예외를 발생시킵니다. 리터럴 값을 왼쪽에서 오른쪽으로 평가하는 ||&&와 같은 단락 논리 연산자를 사용하는 것이 항상 권장됩니다. 이 경우 첫 번째 리터럴이 true를 반환하므로 두 번째 리터럴 평가를 건너뜁니다.

String x = "abc";
String y = "abc";

x.concat(y);

System.out.print(x);
abc

x.concat(y)는 새 문자열을 생성하지만 x에 할당되지 않으므로 x의 값은 변경되지 않습니다.

public class MathTest {

 	public void main(String[] args) {  		
   		int x = 10 * 10 - 10;
   		
   		System.out.println(x);
   	}
   
}
Error: Main method is not static in class MathTest, please define the main method as:
   public static void main(String[] args)

이 질문이 수학 연산자의 실행 순서에 관한 것처럼 보일 수 있지만 실제로는 기본 메서드가 정적으로 선언되지 않았다는 사실에 대한 질문입니다.

public class Test {
   
  	public static void main(String[] args) {
   		try {
   			throw new IOException("Hello");
   		} catch(IOException | Exception e) {
   			System.out.println(e.getMessage());
   		}
   	}
}
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);
	}
}

  1. 패키지 이름에는 하이픈을 사용할 수 없습니다.
  2. 클래스 이름은 공백을 포함할 수 없습니다.
  3. 메인 메서드는 public이 아니므로 실행되지 않습니다.
  4. 메인 메서드 인수는 크기를 지정하면 안 됩니다.
  5. 문자열 정의에 세미콜론이 없습니다.

결론

이 50개의 Java 프로그래밍 인터뷰 질문 모음에는 인터뷰를 준비하는 데 도움이 되는 초보자부터 전문가 수준까지의 질문이 포함되어 있습니다.

권장 읽기:

  • 자바 까다로운 인터뷰 질문
  • 자바 문자열 인터뷰 질문