스터디

[스터디] 자바 신입 개발자 면접준비

거북이07 2024. 5. 5. 16:36

다음주 화요일 개발자 면접을 보러가기때문에 면접 대비해서 준비를 하기로했다..

혼자 그냥 블로그 보면서 하는건 힘들기때문에 유튜브의 힘을 빌려 아래 유튜브에서 질문들을 참고해서 정리하고 이해해보려고한다.

 


✏️ 참고 유튜브

https://www.youtube.com/watch?v=a-f0HxYRNiM

 

 

1. 자바 컴파일 과정

우선 자바는 OS에 독립적인 특성을 가지고 있다. 이 말은 mac에서든 window에서든 운영체제가 다른 컴퓨터에서 실행시켜도 같은 결과값이 나온다는 말이다. OS에 독립적인 이유는 JVM(Java Virtual Machine) 때문이다.

 

💡여기서 JVM이란?

JVM은 자바 소스 코드를 컴파일하여 생성된 바이트코드를 실행하는 역할을 한다. 이 바이트코드는 JVM이 이해할 수 있는 언어이다, 즉 JVM이란 OS에 종속받지 않고 CPU가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터이다.

 

컴파일 과정

  1. 개발자가 소스코드(.java)를 작성한다.
  2. build를 한다.
  3. 자바 컴파일러가 자바 소스코드 파일을 읽어 바이트코드(.class)코드로 컴파일한다.
  4. 클래스 로더를 통해 JVM내로 로드한다 (클래스로더는 동적로딩을 통해 필요한 클래스들을 로딩 및 링크한다)
  5. 실행엔진을 통해 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행한다.

 

여기서 실행엔진은 두가지 방식이 있다.

 

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

 

2. JIT컴파일러: 인터프리터의 단점을 보완하기 위해 도입된 방식, 바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실행하는 방법

https://velog.io/@minseojo/Java-%EC%9E%90%EB%B0%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EA%B3%BC%EC%A0%95-JVM-%EB%82%B4%EB%B6%80-%EA%B5%AC%EC%A1%B0

 

2. String, StringBuilder, StringBuffer의 차이

자바에서 대표적으로 문자열을 다루는 자료형 클래스로 String, StringBuilder, StringBuffer 라는 3가지 자료형을 지원

위 3가지 클래스 자료형은 모두 문자열을 다루는데 있어 공통적으로 사용되지만 사용 목적에 따라 쓰임새가 많이 달라진다.

StringBuilder, StringBuffer 클래스

stringBuilder, StringBuffer 클래스는 문자열을 연산(추가하거나 변경)할 때 주로 사용하는 자료형이다.(가변)

여기서 String 자료형도 +연산이나 concat() 메소드로 문자열을 이어붙일 수 있지만 해당 방식대로 문자열을 결합하면 내용이 합쳐진 새로운 String 인스턴스를 생성하게 되어 메모리가 낭비되고 속도 또한 매우 느려지는 단점이 있다.

 

StringBuffer 클래스는 내부적으로 버퍼(buffer) 라고 하는 독립적인 공간이 있어 메모리 낭비도 없고 문자열 연산 속도도 매우 빠르다. 동기 방식으로 저장되기 떄문에 멀티쓰레드로 접근하거나 문자열이 변경될 경우에 사용

 

StringBuilder 클래스는 비동기 방식이기 때문에 Single Thread 환경하에서 변화되는 문자열을 사용한다. 비동기식이기 때문에 처리속도는 제일 빠르다.

 

String 클래스

String클래스는 객체(불변) 불변이기 때문에 변하지 않는 문자열은 String을 사용한다.

 

2-1. Thread safe

Thread safe란 말 그대로 스레드 안전이란 뜻으로 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻한다.

 

하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 옳바르게 나오는 것을 말한다.

 

2-2. Java String이 불변객체인 이유

String은 성능, 동기화, 캐싱, 보안의 이유로 불편 객체로 만들어졌다.

 

아래 블로그에 자세하게 정리되어있다..ㅎㅎ

https://devlog-wjdrbs96.tistory.com/247

 

[Java] String이 불변 객체인 이유는 무엇일까?

String이 불변 객체인 이유 String 객체가 불변 객체라는 것은 다들 알고 있을 것입니다. 불변 개체는 완전히 생성된 후에도 내부 상태가 일정하게 유지되는 개체입니다. 즉, 객체가 변수에 할당되

devlog-wjdrbs96.tistory.com

 

3. Java 접근제어자의 종류와 특징

자바에서 접근제어자(access modifier)는 클래스와 클래스의 멤버(필드, 메소드, 생성자)를 사용할 때, 접근할 수 있는 범위를 지정해주는 역할을 한다. 보통 접근제어자 또는 접근지정자라고 부르며 클래스 멤버 앞에 붙어있는 public, private, protected 등의 키워드가 접근 제어자이다.

 

접근제어자는 Java의 캡슐화 특징때문에 사용된다. 여기서 캡슐화란 객체 내부의 속성이나 행위를 외부에서 직접 접근할 수 없게 하는것이다.

범위 public protected default ptivate
외부 패키지에서 사용 O X X X
상속 관계에서 사용 O O X X
외부 클래스에서 사용 O O O X
같은 클래스에서 사용 O O O O

 

클래스 선언 시 public을 생략한다면 default 접근 제한을 가진다.(같은 패키지에서는 아무런 제한 없이 사용, 다른 패키지에서는 사용불가)

 

4. OOP의 4가지 개념 

OOP란 객체 지향 프로그래밍(Object-Oriented Programming)의 약자로 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다.

 

즉 프로그래밍을 여러 개의 객체 단위로 보고 작업한다 라고 생각하면 된다.

 

객체란(Object)

객체(Object)란 우리 일상생활에서 인식할 수 있는 모든 사물이 될 수 있다. 이러한 객체는 속성(Filed)와 행위(Method)로 구성되어있다. 그리고 위 객체를 만드는 설계도 또는 틀이 바로 클래스(Class)이다.

 

* Java에서 사람이라는 클래스를 만든다고 가정했을 때 아래와 같이 만들 수 있다.

public class Person {
    // 필드(항목)
    private int age;
    private String gender;
    
    // 메소드(행동)
    private void sleep() {
        System.out.println("잠을 잡니다.");
    }
}
Person ram = new Person();

 

만들어진 클래스는 위와 같은 방법으로 객체를 생성할 수 있다.

 

OOP의 4가지 개념(캡슐화, 상속, 다형성, 추상화)

1️⃣ 캡슐화(Encapsulation)

캡슐화는 객체의 데이터와 그 데이터를 처리하는 함수를 하나로 묶는 것을 의미한다. 이를 통해 객체의 내부 데이터는 외부에서 직접 접근할 수 없게 되며, 오직 객체가 제공하는 함수를 통해서만 접근이 가능하게된다.

 

2️⃣ 상속(Inheritance)

상속은 기존의 클래스에서 일부 기능을 그대로 물려받아 새로운 클래스를 생성하는 것을 의미한다. 이를 통해 코드의 재사용성이 높아지며, 중복된 코드의 작성을 줄일 수 있다. 예를 들어 "동물" 클래스에서 "포유류"나 "조류" 클래스를 파생시킬 수 있으며, 이렇게 파생된 클래스는 "자식 클래스"라고도 한다.

 

3️⃣ 다형성(Polymorphism)

다형성은 하나의 인터페이스나 클래스가 여러 가지 형태로 동작하는 것을 의미한다. 예를들어 "동물" 클래스에 "울다" 라는 메서드가 있을 때 "개" 클래스와 "고양이" 클래스에서 이 메서드를 각각 다르게 구현할 수 있다. 이를 통해 유연한 코드 작성이 가능하며, 코드의 가독성이 높아진다.

 

4️⃣ 추상화(Abstraction)

추상화는 복잡한 시스템을 단순화시켜 표현하는 것을 의미한다. 필요한 특성만을 강조하여 복잡한 현실 세계의 객체를 프로그램에서 사용하기 쉬운 형태로 변환하는 것이다. 예를 들어 "자동차" 객체를 프로그램에서 표현할 때 엔진, 바퀴, 핸들 등의 주요 특성만을 강조하고 나머지 세부 사항은 생략할 수 있다.

 

OOP의 장점

  • 코드의 재사용성이 높아진다.
  • 유지보수가 용이하다.
  • 코드의 구조가 직관적이며, 셜계 단계에서의 생각을 코드로 쉽게전환할 수 있다.

 

4-1. 캡슐화와 은닉화의 차이

은닉화는 중요사항(변수, 메서드 등)을 밖으로 드러나지 않도록 꼭꼭 감추는 것이고 캡술화는 중요사항을 감춘 상태에서 외부에 그것을 사용할 수 있는 방법을 설정하고 외부와 직접적으로 의사소통하는 것을 말한다.

 

캡슐화를 하면 불필요한 정보를 감출 수 있기 때문에 정보 은닉을 할 수 있다는 특징을 가지지만 캡슐화와 은닉화는 동일 개념이 아니다.

 

5. OOP의 5대 원칙(SOLID)

SRP(Single Respomsibility Principle): 단일 책임 원칙

쉽게 말하면 하나의 클래스에 역할과 책임을 너무 많이 주지 말라는 것, 클래스에 모든 기능을 다 때려넣지 말고 목적과 취지에 맞게 속성과 Method를 구성함으로 관련된 책임만 주어야한다.

OPC(Open Closed Priciple): 개방 폐쇄 원칙

자신의 확장에는 열려있어야 하며, 주변의 변화에 대해서는 닫혀있어야 한다.

 

LSP(Listov Substitution Priciple): 리스코프 치환 원칙

하위 클래스의 인스턴스는 상위 클래스의 인스턴스 역할을 하는데 문제가 없어야한다. 인터페이스와 클래스 관계, 상위 클래스와 하위 클래스 관계를 얼마나 논리적으로 설계했는지냐이다. 하위 클래스가 상클래스의 역할을 대신할 때 논리적으로 맞아야한다.

 

ISP(Interface Segregation Principle): 인터페이스 분리 원칙

클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안 된다.
즉 상황에 맞는 메소드만 제공하라는 것. 자신이 구현하지 않은 인터페이스는 사용하지 않아야한다.

 

DIP(Dependency Inversion Principle): 의존관계 역전 원칙

추상화된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야한다.

 

위 이미지처럼 스노우타이어에 의존하지 않고 해당 관계를 타이어 인터페이스에 역전 시키는것. 이것이 의존성 주입이다.

 

6. JVM 구조

JVM의 구조는 크게 보면, Garbage Colletor, Execution Engine, Class Loader, Runtime Data Area 4가지로 나눌 수 있다.

 

1. Class Loader

JVM 내로 클래스 파일을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈, 런타입 시에 동적으로 클래스를 로드한다.

 

2. Execution Engine

클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 명령어 단위로 읽어서 실행한다.

 

3. Garbage Collector

Garbage Collector는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 한다.

 

4. Runtime Data Area

JNV의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.

 

7. 클래스, 객체, 인스턴스의 차이

1️⃣ 클래스(Class)란?

  • Java에서 객체를 생성하기 위한 일종의 설계도
  • 객체가 가지는 속성(필드)와 동작(메서드)로 이루어져 있다.
    • 이들은 생략될 수 있고, 하나 이상 작성될 수 있다.
  • Java를 실행 시 클래스는 JVM 메모리의 클래스 영역(Class Area)에 로드 된다.

2️⃣ 객체(Object)란?

  • 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고, 다른것과 식별 가능한 것을 말한다.

3️⃣ 인스턴스(Instance)란?

  • 클래스가 붕어빵 틀이라면, 그 틀을 통해 생성된 객체(붕어빵) 하나하나를 해당 클래스의 인스턴스라 한다.
  • 클래스를 사용하여 힙 영역(Heap Area)에 새로운 인스턴스(객체)를 생성할 수 있다. 즉 인스턴스란 현실의 객체를 소프트웨어 내에서 구현한 실체라고 볼 수 있다.

 

요약

  • 객체(Object)란 자신 고유의 속성을 가지는 물리적, 추상적인 모든 대상을 일컫는다.
  • 클래스(Class)란 객체들을 소프트웨어 내에서 구현하기 위해 만든 설계도이다.
    • 이를 통해 생성된 객체 하나하나를 인스턴스(Instance)라고 부른다.
    • 대체로 객체와 인스턴스는 혼용해서 표현한다.

 

8. interface와 abstract class의 차이

Class는 일반 클래스와 추상 클래스로 나뉘는데 추상 클래스는 클래스 내 "추상 메소드"가 하나 이상 포함되거나 abstract로 정의된 경우를 말한다. 반면 인터페이스는 모든 메소드가 추상 메소드인 경우이다.

 

두 개념은 생김새와 사용하는 방법은 다르지만 하는 일은 비슷하다.

추상 클래스와 인터페이스는 상속받는 클래스 혹은 구현하는 인터페이스 안에 있는 추상 메소드를 구현하도록 강제한다.

 

하는 일은 비슷하지만 인터페이스와 추상 클래스는 존재 목적이 다르다. 추상 클래스는 그 추상 클래스를 상속받아서 기능을 이용하고 확장시키는 데 있고, 인터페이스는 함수의 껍데기만 있는데, 그 이유는 그 함수의 구현을 강제하기 위해서이다. 구현을 강제함으로써 구현 객체의 같은 동작을 보장할 수 있다.

 

9. CheckedException과 UnCheckedException의 차이

 

Checked Exception 의 특징

  • RuntimeException을 상속하지 않는 클래스
  • 컴파일 시점에 컴파일러에서 확인하는 예외
  • 반드시 에러를 처리해야야 하는 특징(try/catch to throw)을 가지고있다.

Unchecked Exception 의 특징

  • RuntimeException을 상속하는 클래스
  • 런타임 단계에서 확인 가능
  • 에러 처리를 강제하지 않는다.

간단하게 정리하면 Checked Exception은 RuntimeException을 상속하지 않은 클래스이며, 예외처리를 반드시 해줘야 하고, Unchecked Exception은 코드에 개발자가 예상치 못한 에러가 발생할 수 있기 때문에 예외처리를 강제하지 않는다.

 

10. 오버로딩과 오버라이딩의 차이

오버로딩(Overloading)

  • 메서드의 이름은 같고 매개변수의 갯수나 타입이 다른 함수를 정의하는 것을 의미
  • 리턴값만을 다르게 갖는 오버로딩은 작성 할 수 없다.

오버라이딩(Overriding)

  • 상위 클래스의 메서드를 하위 클래스가 재정의 하는 것이다.
  • 메서드의 이름은 물론 파라미터의 개수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용된다.

 

즉 오버로딩은 기존에 없던 새로는 매서드를 정의하는 것이고, 오버라이딩은 상속 받은 메서드의 내용만 변경 하는 것이다.