출처: Dev.to 안녕하세요, 개발자 여러분, 모든 코더가 알아야 할 기본 Java 면접 질문 목록을 정리했습니다.
1. reverse() 메소드를 사용하지 않고 Java에서 문자열을 뒤집는 방법은 무엇입니까?
답변: 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() 메서드를 사용하여 공백을 확인합니다. 유니코드 문자를 사용하여 공백을 감지하며 공백을 제거하는 데 권장되는 방법입니다. 대체 방법 인 StripLeading() 및 StripTrailing() 도 사용할 수 있습니다 . 선행 또는 후행 공백만 각각 제거하려는 경우 도움이 됩니다. 아래 코드는 Strip() 메소드 를 사용한 예이다 .String s = " flexiple ";
s = s.strip();
System.out.println(s);
4. 교착상태 시나리오의 원인은 무엇입니까? 교착 상태를 만드는 코드 작성
대답: 교착 상태 시나리오는 두 스레드가 실행하기 위해 동일한 잠금을 요구할 때 발생합니다. 이러한 시나리오는 두 스레드가 하나의 잠금을 획득하고 다른 잠금을 획득하기를 기다리고 있을 때 발생합니다. 그러나 두 스레드 모두 다른 스레드가 실행되기를 기다리고 있으므로 서로를 차단하여 교착 상태가 발생합니다. 다중 스레드 프로그램은 메서드를 스레드로부터 안전하게 만드는 데 동기화 키워드가 사용되기 때문에 교착 상태가 발생합니다. 이는 하나의 스레드만 동기화된 메서드를 차단하고 사용할 수 있음을 의미합니다. 다른 스레드는 현재 스레드가 완료될 때까지 기다려야 합니다. 아래 코드는 교착 상태에 있는 두 개의 스레드를 생성합니다.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/YYYY로 변환합니다.import 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은 순서가 지정된 컬렉션이 아니며 정렬하는 것은 의미가 없습니다. 그러나 해시맵 정렬은 상당히 까다로울 수 있으므로 Java 인터뷰에서 일반적인 질문입니다. 아래 코드는 HashMaps 의 구현을 보여줍니다 .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() 메소드는 무엇을 합니까? 예를 들어서 설명해보세요
답변: 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에서는 람다 표현식을 사용하여 기능적 인터페이스를 인스턴스화할 수 있으므로 작업이 훨씬 쉬워집니다. 기능적 인터페이스의 예: 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. 예를 들어 재정의 설명
답변: 재정의는 하위 클래스나 하위 클래스가 상위 클래스의 기존 메소드에 대해 별도의 구현을 제공할 수 있도록 하는 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. 이진 검색이란 무엇입니까? 이것은 어떻게 구현됩니까?
답변: 이진 검색 알고리즘은 정렬된 배열 또는 컬렉션 유형에서 값을 찾는 데 사용됩니다. 이 검색 방법은 선형 검색 방법보다 훨씬 빠릅니다. 이진 검색은 배열을 더 작은 세트로 나눈 다음 규칙을 적용하여 입력 키를 확인합니다. 이진(이진) 검색 구현 단계:- 배열을 오름차순으로 정렬합니다.
- 배열의 평균값을 찾아 키와 비교합니다.
- 키가 평균과 같으면 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는 Least Used Cache를 나타냅니다. 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 데이터 구조는 무엇입니까?
답변: 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