자바 프로그래밍 인터뷰 질문 상위 50개

소개

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

}

출력에서 정수 값이 교환되었음을 보여줍니다:

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 (N의 제곱근)까지의 소수 M이 있다면, N은 소수가 아닙니다.

5. 피보나치 수열을 재귀를 사용하여 출력하는 Java 프로그램을 작성하세요.

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

}
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() // 빠른 처리를 위한 병렬 스트림
			.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();
}

자바에서 문자열에서 공백 및 다른 문자 제거에 대해 더 알아보세요.

9. 자바에서 문자열에서 앞뒤 공백을 제거하는 방법은 무엇입니까?

String 클래스에는 선행 및 후행 공백을 제거하는 두 가지 메서드가 있습니다: trim()strip(). strip() 메서드는 자바 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. 자바에서 배열을 정렬하는 방법은 무엇인가요?

Arrays 유틸리티 클래스에는 기본 타입(primitive) 및 객체 배열을 정렬하기 위한 다양한 오버로딩된 sort() 메소드가 있습니다. 기본 타입 배열을 자연 순서로 정렬하려면 다음과 같이 Arrays.sort() 메소드를 사용할 수 있습니다:

int[] array = {1, 2, 3, -1, -2, 4};

Arrays.sort(array);

System.out.println(Arrays.toString(array));

그러나 객체 배열을 정렬하려면 객체는 Comparable 인터페이스를 구현해야 합니다. 정렬 기준을 지정하려면 정렬 로직을 위해 Comparator를 전달할 수 있습니다. 자세한 내용은 자바에서 Comparable 및 Comparator 알아보기.

11. 자바에서 프로그래밍적으로 데드락(deadlock) 시나리오를 만드는 방법은 무엇인가요?

데드락은 다중 스레드 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에서 정수의 팩토리얼을 어떻게 찾을 수 있나요?

정수의 팩토리얼은 주어진 숫자까지의 모든 숫자를 곱하여 계산됩니다:

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 (uniqueElements1.size() != uniqueElements2.size()) return false;
		
		for (Object obj : uniqueElements1) {
			// 양쪽에 모두 존재하지 않는 요소?
			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);

	// 파일을 한 줄씩 읽기
	while (scanner.hasNextLine()) {
		String line = scanner.nextLine();
		if (line.contains(str)) {
			scanner.close();
			return true;
		}
	}
	scanner.close();

	return false;
}

예제 코드는 파일에서 검색하는 문자열에 새 줄 문자가 포함되지 않았다고 가정합니다.

22. Java에서 특정 형식으로 날짜를 어떻게 출력합니까?

String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

String date = simpleDateFormat.format(new Date());
System.out.println(date); // 2020-06-23

Java SimpleDateFormat 클래스를 사용하여 날짜 문자열을 포맷하는 방법을 보여주는 다음 예제 코드입니다.

자바에서 두 개의 리스트를 병합하는 방법은 무엇인가요?

다음은 자바에서 여러 리스트를 병합하는 addAll() 메서드를 사용하는 예제 코드입니다:

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]

해시맵을 값에 따라 정렬하는 자바 프로그램을 작성하세요.

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에서 문자열에서 문자를 제거하는 방법에 대해 더 알아보세요removing characters from a string in Java.

26. 자바에서 문자열 내에서 고유한 문자와 그 개수를 어떻게 얻나요?

문자열에서 문자 배열을 만들 수 있습니다. 그런 다음에 반복하여 각 문자를 키로하고 그 개수를 값으로 하는 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. 자바에서 String 객체가 변경 불가능하다는 것을 프로그램적으로 증명할 수 있나요?

다음 예제 코드는 String 객체가 변경 불가능하다는 것을 증명하는 방법을 보여주며, 코드의 주석은 각 단계를 설명합니다:

String s1 = "Java"; // "Java" 문자열이 풀에 생성되고 s1에 참조가 할당됩니다

String s2 = s1; //s2도 풀에 있는 "Java"에 동일한 참조를 갖습니다

System.out.println(s1 == s2); // s1과 s2가 동일한 참조를 갖고 있는 증거

s1 = "Python"; 
// 위의 경우 s1 값이 변경되었으므로 String이 불변인 이유는?

// 위의 경우에 새로운 문자열 "Python"이 풀에 생성되었습니다
// s1이 이제 풀에 있는 새 문자열을 참조하고 있습니다
// 그러나, 원래 문자열 "Java"는 여전히 변경되지 않았으며 풀에 그대로 남아 있습니다
// s2는 여전히 풀에 있는 원래 문자열 "Java"를 참조하고 있습니다

// s1과 s2가 다른 참조를 갖고 있는 증거
System.out.println(s1 == s2); 

System.out.println(s2); 
// 원래 문자열 값이 변경되지 않았음을 증명하는 "Java"를 출력하며, 따라서 String은 불변입니다

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

다음 예제 코드는 extends 키워드를 사용하여 Animal 클래스의 서브클래스를 만드는 방법을 보여줍니다. 새로운 클래스 CatAnimal 클래스에서 변수를 상속받고 Cat 클래스에만 속하는 더 많은 코드를 추가합니다.

class Animal {
	String color;
}

class Cat extends Animal {
	void meow() {
		System.out.println("Meow");
	}
}

29. 자바에서 다중 상속으로 다이아몬드 문제를 어떻게 보여주나요?

다이아몬드 문제는 클래스가 여러 클래스에서 상속받을 때 발생하며, 어떤 클래스에서 어떤 메서드를 실행해야 하는지 명확하지 않은 경우에 모호성이 발생합니다. 자바는 이러한 다이아몬드 문제를 피하기 위해 여러 클래스를 확장하는 것을 허용하지 않습니다. 다음 예제에서 설명한 다이아몬드 문제를 피하기 위해 다음과 같이 작성한 코드는 컴파일되지 않습니다:

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. 자바에서 try catch 예제를 어떻게 설명하나요?

다음 예제 코드는 try-catch의 예제를 보여줍니다:

try {
	FileInputStream fis = new FileInputStream("test.txt");
} catch(FileNotFoundException e) {
	e.printStackTrace();
}

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

일차적으로 유효성 검사를 위해 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() 메서드 코드를 생성합니다. 레코드는 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에서 스위치 표현식과 다중 레이블 케이스 문을 보여주세요.

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

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에서 열거형(enum)을 만드는 방법은 무엇입니까?

다음 예제 코드는 기본 열거형을 만드는 방법을 보여줍니다:

public enum ThreadStates {
	START,
	RUNNING,
	WAITING,
	DEAD;
}

ThreadStates는 상수 필드 START, RUNNING, WAITING, 그리고 DEAD를 가진 열거형입니다. 모든 열거형은 암묵적으로 java.lang.Enum 클래스를 확장하고 SerializableComparable 인터페이스를 구현합니다. 열거형은 메서드를 가질 수도 있습니다. Java에서의 열거형에 대해 더 알아보기.

37. Java에서 forEach() 메서드를 어떻게 사용하나요?

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

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. defaultstatic 메서드를 가진 인터페이스를 어떻게 작성하나요?

자바 8에서는 인터페이스에 기본 및 정적 메서드를 도입했습니다. 이것은 인터페이스와 추상 클래스 간의 격차를 좁히는 역할을 했습니다. 다음 예제 코드는 defaultstatic 메서드가 있는 인터페이스를 작성하는 한 가지 방법을 보여줍니다:

public interface Interface1 {
	
	// 일반 추상 메서드
	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. 자바에서 람다 표현식을 사용한 예제를 보여주세요.

Runnable은 함수형 인터페이스의 훌륭한 예입니다. 람다 표현식을 사용하여 다음 예제 코드에 나와 있는 것처럼 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);
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입니다. 자바의 자동박싱 기능은 기본 유형이 short인 표현식 iShort 객체로 변환합니다. 마찬가지로, 기본 유형이 int인 표현식 i - 1Integer 객체로 자동박싱됩니다. HashSetInteger 객체가 없으므로 아무 것도 제거되지 않고 크기는 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을 throw합니다. 왜냐하면 OR 논리 연산자는 결과를 반환하기 전에 두 리터럴을 모두 평가합니다. strnull이므로 .equals() 메서드가 예외를 throw합니다. 항상 왼쪽에서 오른쪽으로 리터럴 값을 평가하는 단락 평가 논리 연산자인 ||&&를 사용하는 것이 좋습니다. 이 경우, 첫 번째 리터럴이 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에 의해 처리됩니다.

다음 코드 스니펫에서 5가지 오류를 찾으세요.

package com.digitalocean.programming-interviews;

public class String Programs {

	static void main(String[10] args) {
		String s = "abc"
		System.out.println(s);
	}
}
Answers
  1. 패키지 이름에 하이픈이 들어갈 수 없습니다.
  2. 클래스 이름에는 공백이 들어갈 수 없습니다.
  3. 주 메서드가 public이 아니므로 실행되지 않습니다.
  4. 주 메서드의 매개변수는 크기를 지정해서는 안 됩니다.
  5. 문자열 정의에서 세미콜론이 빠져 있습니다.

결론

이 Java 프로그래밍 인터뷰 질문 50개 컬렉션에는 초보자부터 전문가 수준까지의 질문이 포함되어 있어 인터뷰 준비에 도움이 됩니다.

추천 독서:

Source:
https://www.digitalocean.com/community/tutorials/java-programming-interview-questions