Coding Planet

개발자 기술면접 빈출 문제 - udpate 중 본문

etc

개발자 기술면접 빈출 문제 - udpate 중

jhj.sharon 2023. 9. 13. 00:47
반응형

Java

자바의 특징

  • 객체지향 프로그래밍 언어이다.
  • 기본 자료형을 제외한 모든 요소들이 객체로 표현되고, 객체 지향 개념의 특징인 캡슐화, 상속, 다형성이 잘 적용된 언어이다.
  • 자바의 장점 : JVM 위에서 동작하기 때문에 운영체제에 독립적이며 가비지 컬렉터를 통해 메모리가 자동으로 관리된다.
  • 자바의 단점 : JVM 위에서 동작하기 때문에 실행 속도가 상대적으로 느리다. 다중 상속이나 타입에 엄격하며, 제약이 많다.

 

객체지향 프로그래밍(Object-Oriented Programming)

소프트웨어 개발에서 사용하는 프로그래밍의 패러다임 중 하나로 현실 세계의 객체와 그 객체들 간의 상호 작용을 모델링하는 방식으로 소프트웨어를 설계하고 개발하는 접근 방법이다. 이 때 현실 세계를 개념을 클래스(Class)로 표현하고 클래스의 인스턴스를 객체라고 한다. 클래스는 객체를 생성하기 위한 일종의 설계도로, 객체는 클래스의 실체이다.

객체지향 프로그래밍에서는 기능이 아닌 객체가 중심이며 누가 어떤일을 할 것인가가 핵심이다. 객체지향언어는 다음과 같은 특징을 가진다.

 

1. 캡슐화(Encapsulation)

  • 캡슐화는 객체의 상태(State)와 행위(Behavior)를 하나로 묶고, 상태에 대한 접근을 제한하는 개념이다. 
  • 클래스는 멤버 변수(상태)와 메서드(행위)로 구성되며 멤버변수는 보통 private, protected로 선언하여 외부에서 직접 접근할 수 없도록 한다.

2. 상속(Inheritance)

  • 상속은 상위 클래스를 확정하여 새로운 클래스인 하위 클래스를 생성하는 개념이다.
  • 상속을 통해 코드 재소용성이 향상되며, 상위 클래스의 특성과 메서드를 하위 클래스가 상속받아 사용할 수 있다.

3. 다형성(Polymorphism)

  • 다형성은 같은 이름의 메서드를 다양한 방식으로 구현하거나 다양한 클래스의 객체를 동일한 방식으로 다룰 수 있는 능력을 의미한다. 
  • 다형성은 메서드 오버로딩과 메서드 오버라이딩으로 구현되며, 인터페이스와 추상 클래스를 활용하여 강화할 수 있다.

4. 추상화(Abstraction)

  • 추상화는 복잡한 시스템을 단순화하고 필수적인 기능에만 집중할 수 있도록 도와준다.
  • 클래스와 메서드를 사용하여 필수적인 부분을 추출하고, 불필요한 세부사항을 숨기는 개념이다.

 

자바의 컴파일 과정과 JVM

  • 자바는 OS에 독립적은 특징을 가지고 있다. 그게 가능한 이유는 JVM(Java Vitual Machine)이라 불리는 자바 가상 머신 덕분이다. JVM은 자바 프로그램을 실행하기 윈한 가상 환경을 제공하는 소프트웨어이다. 이는 기본적으로 자바 바이트 코드로 컴파일된 자바 애플리케이션을 실행하는 역할을 한다.

이미지 출처 확인

1. 개발자가 자바 소스코드(.java)를 작성한다.

2. 자파 컴파일러(Java Complier)가 자바 소스파일을 컴파일한다. 이 때 나오는 파일은 자바 바이트 코드(.class) 파일로 아직 컴퓨터가 읽을 수 없는 형식이다. 이 바이트 코드는 운영 체제나 하드웨어에 종속되지 않으며 JVM에 의해서 실행된다. 이렇게 함으로써 자바 애플리케이션은 OS에 종속되지 않는다(Write Once, Run Anywhere). JVM이 os에 맞게 바이트 코드를 해석하고 실행하게 된다.

3. 컴파일된 바이트 코드를 JVM의 클래스 로더(Class Loader)에게 전달한다.

4. 클래스 로더는 동적로딩(Dynamic Loading)을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(Runtime Data area) 즉, JVM의 메모리에 올린다.

5. 실행엔진(Execution Engine)은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행합니다. 이때, 실행 엔진은 두가지 방식으로 변경한다.

   - 인터프리터 : 바이트 코드 명령어를 하나씩 읽어서 해석하고 실행한다. 하나하나의 실행은 빠르나, 전체적인 실행 속도       가 느리다는 단점이 있다.

    - JIT 컴파일러(Just-In-Time Compiler) : 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴        파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실         행하는 방식이다. 하나씩 인터프리팅하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 바이너리 코드를 실행하       는 것이기 때문에 전체적인 실행속도는 인터프리팅 방식보다 빠르다.

 

 

Call by value와 Call by reference

1. Call by value : 값에 의한 호출

  • 자바에서 사용되는 방식으로 메소드에 인자로 전달되는 것은 변수의 값이며 변수 자체가 전달되는 것이 아니다. 메소드 내에 전달받은 값을 변경하더라도 호출한 측의 변수값은 변경되지 않는다. 따라서, 함수 안에서 인자 값이 변경되더라도 외부 변수 값은 변경되지 않는다.
  • 기본 데이터 타입을 사용할 때 Call by value 방식이 적용된다.
  • 객체(참조 타입)을 전달할 때에도 그 객체의 참조가 전달되므로 객체 내부의 상태를 변경하는 것은 가능하지만, 참조 자체를 다른 객체로 변경하는 것은 불가능한다.
public void modifyValue(int x) {
    x = x * 2;
}

public static void main(String[] args) {
    int num = 5;
    modifyValue(num);
    System.out.println(num); // 출력 결과는 5
}

 

2. Call by reference : 참조에 의한 호출

  • 일부 언어에서 지원하는 방식으로 변수의 참조가 메서드에 전달된다.
  • 메서드 내에서 전달받은 참조를 통해 변수의 값을 변경하면 호출한 측의 변수 값도 변경된다.
  • 자바는 Call by Reference를 직접 지원하지 않는다. (C++, Python 등은 Call by reference 형식을 직접 지원한다.)
// 자바에서는 이런 방식이 직접 지원되지 않는다
public void modifyReferenceValue(int[] arr) {
    arr[0] = arr[0] * 2;
}

public static void main(String[] args) {
    int[] arr = {5};
    modifyReferenceValue(arr);
    System.out.println(arr[0]); // 호출한 측의 배열 값도 변경될 것이라고 예상되지만, 자바에서는 변경되지 않음
}

 

 

String, StringBuffer, StringBuilder

분류  String  StringBuffer  StringBuilder
변경 Immutable Mutable Mutable
동기화 Thread-safe Synchronized 가능 (Thread-safe) Synchronized 불가능.

 

1. String 특징

  • Immutable : 불변 클래스로 한번 생성된 문자열을 변경할 수 없다. 따라서 문자열 연산시 기존 문자열이 변경되는 것이 아니라 새로운 문자열이 생성된다. 그러므로 연산이 빈번할 경우 Overhead가 발생하여 성능이 저하 될 수 있다.
  • 가비지 컬렉터로 제거되어야 한다.
  • 문자열 리터럴로 생성된 문자열은 문자열 풀에 저장되어 재사용 될 수 있다. 
  • 객체가 불변하므로, 멀티 스레드에서 동기화를 신경 쓸 필요가 없다. 스레드 안전(thread-safe)하다
  • 문자열 연산이 적고, 조회가 많은 멀티 쓰레드 환경에 적합
String str = "Hello";
str = str + " World"; // 새로운 문자열 생성

 

2. StringBuffer, StringBuilder 특징

  • 공통점 
    • mutable : new 연산으로 클래스를 한번만 만든다. 따라서 문자열 연산시 새로 객체를 만들지 않고, 크기를 변경시킨다.
    • 따라서 문자열 연산 시 내부 버퍼를 사용하므로 연산이 빠르며 메모리 사용량이 적다. 주로 문자열 연산이 빈번하게 발생하는 상황에서 사용된다. 
  • 차이점
    • StringBuffer는 Thread-Safe함 / StringBuilder는 Thread-safe하지 않음 (불가능)
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // 기존 문자열 변경 Hello World

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 기존 문자열 변경 Hello World

 

 

가비지 컬렉션(Garbage Collection)

  • 자바 이전의 프로그래밍 언어에서는 프로그래머가 직접 프로그램의 메모리를 관리했다. 하지만 Java에서는 JVM의 가비지 컬렉션가 이 역할을 대신한다.
  • 가비지 컬렉션은 더 이상 사용하지 않는 메모리 자원, 즉 "가비지(garbage)"를 자동으로 탐지하고 회수하는 프로세스를 의미한다.
  • 실행순서 : 참조되지 않은 객체들을 탐색 후 삭제    삭제된 객체의 메모리 반환 → 힙 메모리 재사용

 

Casting(업캐스팅 & 다운캐스팅)

캐스팅이란 데이터 형식을 다른 데이터 형식으로 변환하는 과정을 의미한다. 이러한 형 변환은 데이터 형식간 호환성이 없을 때, 또는 특정 연산을 수행하기 위해 필요한 경우에 사용된다.

 

1. 캐스팅의 종류 

  • 암시적 형변환(또는 자동 형변환) : 컴파일러에서 자동으로 수행하는 형변환. 보통 더 작은 범위의 데이터 형식에서 더 큰 범위의 데이터 형식으로 형변환하는 경우에 발생한다.
int num = 5;
double result = num; // 암시적 형변환
  • 명시적 형변환(또는 강제형변환) : 개발자가 직접 데이터 형식을 지정하여 형변환을 수행하는 경우를 의미한다. 보통 더 큰 범위에서 더 작은 범위의 데이터 형식으로 형변환을 하거나, 서로 다른 데이터 형식 간에 형 변환을 수행할 때 사용된다. 명시적 형변환에는 캐스팅 연산자가 필요하다.
double num = 5.7;
int result = (int) num; // 명시적 형변환

 

2. 업캐스팅(Upcasting)

  • 업캐스팅은 하위 클래스의 객체를 상위 클래스 타입으로 형변환하는 것을 의미한다.
  • 상위 클래스는 하위 클래스의 모든 기능을 가지고 있으므로 하위 클래스 객체를 상위 클래스로 형변환하여 일반화된 코드를 작성할 수 있다.
  • 업캐스팅은 자동으로 이루어지기 때문에 명시적 형변환 연산자가 필요하지 않다.
  • 업캐스팅은 일반적으로 다형성을 활용하여 객체를 추상화하고 일반적인 인터페이스나 기능을 제공하기 위해 사용한다. 
class Animal { }
class Dog extends Animal { }

Animal animal = new Dog(); // 업캐스팅

 

3. 다운캐스팅(Downcasting)

  • 상위 클래스로 형변환된 객체를 다시 하위 클래스 타입으로 형변환하는 것을 의미한다.
  • 다운캐스팅은 업캐스팅과 달리 명시적 형변환 연산자를 사용해야한다. 다운캐스팅은 원래 하위 클래스 객체로 복원하는 것이 목적이며 이를 위해서는 반드시 이전에 업캐스팅이 수행된 객체여야한다. 그렇지 않으면 'ClassCastException'이 발생한다.
Animal animal = new Dog(); // 업캐스팅
Dog dog = (Dog) animal;    // 다운캐스팅

 

4. 캐스팅이 필요한 이유는?

  • 다형성 : 오버라이딩된 함수를 분리하여 활용할 수 있다.
  • 상속 : 캐스팅을 통해 범용적인 프로그래밍이 가능하다.

 

 

 

자바의 원시 자료형

  • 원시 타입 : 정수형(byte, short, int, long), 실수형(float, double), 문자열(char), 논리형(boolean)
  • 정수형 1, 2, 4, 8, 실수형 4, 8, 문자형 2, 논리형 1 바이트를 차지한다.
  • 비원시 타입 : String, Array..

 

 

오버라이딩(Overriding)과 오버로딩(Overloading)

  • 오버라이딩 : 상위 클래스에 있는 메서드를 하위 클래스에서 재정의하여 사용하는 것
  • 오버로딩 : 매개변수의 타입이나 개수를 다르게하여 같은 이름의 메서드를 여러 개 정의하는 것

 

 

try-with-resources

  • try-catch-finally의 문제점을 보완하는 개념이다. try(...) 안에 자원 객체를 전다랗면, try블록이 끝나고 자동으로 자원 해제 해주는 기능을 의미한다.
  • 따로 finally 구분이나 모든 catch 구문에 종료 처리를 하지 않아도 되는 장점이 있다.

 

불변 객체(Immutable Object)

불변 객체란 객체의 상태(멤버 변수)가 객체의 생명 주기 동안 변경되지 않는 객체를 의미한다. 즉, 한 번 생성된 불변 객체는 그 이후에 변경할 수 없다. 불변 객체를 설계하려면 상태를 변경하는 메서드를 제공하지 않고, 멤버 변수를 'final'로 선언하고 생성자를 통해 초기화하는 방법을 사용한다. 대표적인 불변 객체는 String 클래스가 있다. 불변 객체의 이점은 다음과 같다.

  1. 불변성 : 불변 객체의 상태는 생성시점에 고정되어 있으므로 객체의 상태에 대학 예측 가능성을 높힌다.
  2. 스레드 안전성 : 여러 스레드가 동시에 불변 객체를 읽어도 안전하므로 동시성 이슈를 방지할 수 있다.
  3. 캐싱 : 불변 객체를 한 번 생상되면 그 값을 재사용할 수 있으므로 메모리와 성능 관리에 효율적이다.
  4. 실패 원자적 메소드를 만들 수 있다 : 어떠한 예외가 발생되더라도 메서드 호출 전의 상태를 유지할 수 있어 예외 발생 전과 똑같은 상태로 다음 로직 처리 가능
  5. 가비지 컬렉션 성능을 높힐 수 잇다. 

 

 

추상 클래스와 인터페이스의 차이점

1. 추상 클래스

  • 클래스 내 추상 메서드가 하나 이상 포함되거나 abstract로 정의된 클래스
  • 추상메서드는 메서드의 선언만 있고 구현이 없는 메서드이다. 

2. 인터페이스

  • 인터페이스는 모든 메서드가 추상 메서드로만 이루어져 있는 것

3. 공통점

  • new 인스턴스로 연산자를 생성할 수 없다.
  • 사용하기 위해서는 하위 클래스에서 확장/구현해야한다.

4. 차이점

  • 추상 클래스의 목표는 그 추상 클래스를 상속받아서 기능을 이용하고 확장하는데 있다. 반면에 인터페이스는 함수의 껍데기만 있는데 그 이유는 그 함수의 구현을 강제하기 위해서이다. 구현을 강제함으로써 구현 객체의 같은 동작을 보장할 수 있다.
  • 추상클래스도  다중상속이 불가능하지만 인터페이스는 여러 개의 인터페이스를 동시에 구현하는 다중상속이 가능하다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Data Structure

Array

 


 프로세스 및 운영체제

운영체제

  • 시스템의 자원과 동작을 관리하는 소프트웨어 이다. 

 

 

 

 

 

 

 

[위 포스트는 하기 출처들의 정보를 취합했습니다.]

-https://github.com/gyoogle/tech-interview-for-developer/blob/master/Language/%5Bjava%5D%20%EC%9E%90%EB%B0%94%20%EC%BB%B4%ED%8C%8C%EC%9D%BC%20%EA%B3%BC%EC%A0%95.md

 

 

 

 

 

반응형
Comments