PLOD

[면접] 기술 면접 준비(CS) 본문

대외 활동 및 IT 지식

[면접] 기술 면접 준비(CS)

훌룽이 2024. 7. 23. 20:12

Q : Call by reference란 무엇이고 보통 어떻게 쓰이나요?

더보기
Call by reference는 함수 호출 시 인수로 전달된 변수의 참조(메모리 주소)를 함수로 넘기는 방식입니다.

함수가 인수로 받은 변수를 직접 참조하기 때문에, 함수 내부에서 그 값이 변경되면 원래 변수의 값도 바뀌게 됩니다.

 

특징:

 

  • 메모리 주소 전달: 변수를 복사하는 것이 아니라 그 변수의 메모리 주소를 전달합니다. 따라서 함수에서 변경된 값은 원래 변수에 직접 영향을 미칩니다.
  • 효율성: 큰 데이터를 복사하지 않고 참조만 전달하므로 메모리와 시간을 절약할 수 있습니다.
  • 직접 변경 가능성: 원본 데이터가 함수 내에서 변경될 수 있기 때문에, 데이터 변형이 필요한 경우에 유용합니다.

사용 :

 

1) 함수 내부에서 여러 개의 값을 반환해야 할 때
2) 함수 호출 시 매우 큰 데이터 구조를 전달해야 할 때
3) 전역 변수를 변경하거나 수정해야 할 때가 있습니다. 

Q :  Override 와 Overload 를 설명해주실 수 있을까요

더보기

Override와 Overload는 객체지향 프로그래밍(OOP)에서 자주 사용되는 개념

override(오버라이드)

  • 객체지향의 4가지 특성 중 상속과 추상화에 관련된 기능입니다.
    부모 클래스에서 메서드 명, 반환타입, 매개변수만 설정하고 자식 클래스에서 메서드 동작을 재정의 하는 것입니다.

overload(오버로드)

  • 객체지향의 4가지 특성 중 다형성에 관련된 기능입니다.
  • 여러 개의 메서드의 이름만 같게 하고 반환 타입과 매개변수를 다르게 하여 메서드 동작을 재정의 하는 것입니다.
특징 override overload
적용 대상 상속 관계의 부모-자식 클래스 같은 클래스 내
메서드 시그니처 이름, 매개변수, 반환 타입 동일 이름은 같지만, 매개변수의 타입, 개수, 순서 다름
목적 부모 클래스의 메서드를 재정의 다양한 입력 타입에 대응하는 메서드 구현
동적 바인딩 런타임에 결정 컴파일 시 결정

 

Q : JPA는 언제 필요하고 언제 필요하지 않은지 설명해주실 수 있을까요?

더보기

JPA(Java Persistance API)

  • 데이터베이스와 자바 객체 간의 매핑을 자동으로 처리해주는 ORM(Object-Relational Mapping) 프레임워크
  • JPA가 필요한 경우
    1. 데이터 베이스와 상호작용이 복잡하고 객체 간의 관계가 복잡한 경우에 ORM을 통해 간단하게 처리할 수 있을 때 편리하게 사용할 수 있습니다. 
    2. 개발자가 반복적으로 작성해야 하는 SQL 코드 양을 줄여야 할 때 생산성을 높일 수 있다
    3. 복잡한 트랜잭션 관리가 필요한 경우
  •  JPA가 필요하지 않은 경우
    1. 최대 성능이 필요한 경우나 대량의 데이터를 처리하는 배치 작업이나 일괄적인 데이터 삽입/업데이트는 JPA가 적합하지 않을 수 있습니다.
    2. 간단한 API의 경우와 같은 일부 상황에서는 오버헤드를 발생시킬수 있으므로, 쿼리 사용이나 다른 데이터 엑세스 방식을 사용하는 것이 좋습니다.

4 . JPA의 더티 체킹이란 무엇인가요?

더보기

영속성 컨텍스트에서 관리되는 엔티티의 상태 변경을 자동으로 감지하고 데이터베이스에 변경사항을 동기화하는 매커니즘이다. 

→ 엔티티의 변경사항을 자동으로 감지하여 별도의 명시적인 명령 없이도 변경된 데이터를 데이터베이스에 자동으로 반영하는 기능

// 1. 엔티티 조회
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();

Member member = em.find(Member.class, 1L); // ID가 1인 회원 조회

// 2. 엔티티 수정 (데이터베이스에 아직 반영되지 않음)
member.setName("New Name");

// 3. 트랜잭션 커밋 (더티 체킹에 의해 자동으로 UPDATE 쿼리가 실행됨)
em.getTransaction().commit();
em.close();

더티 체킹의 장점:

  1. 개발 생산성 향상:
    • 개발자가 객체의 변경 사항을 일일이 추적하고 저장할 필요가 없으므로, 코드 작성이 간결해지고 생산성이 높아집니다.
  2. 일관된 트랜잭션 관리:
    • JPA가 트랜잭션이 끝날 때 자동으로 변경된 부분을 처리하므로, 개발자는 비즈니스 로직에만 집중할 수 있습니다. 여러 엔티티의 변경이 있을 때도 일관된 방식으로 처리됩니다.
  3. 성능 최적화:
    • 변경된 엔티티에 대해서만 쿼리를 생성하므로 불필요한 데이터베이스 액세스를 줄여 성능이 최적화될 수 있습니다.

5. JVM 이란 무엇이고 왜 필요한지 설명해주실 수 있을까요?

더보기

Java Virtual Machine

  • CPU가 Java를 인식하여 Java 프로그램을 실행할 수 있도록 하는 가상 컴퓨터이다.
  • 운영체제독립적이라는 장점으로 인해 OS에 종속받지 않고 여러 컴퓨터에서 동일한 자바코드를 실행할 수 있다.

6. Java가 컴파일 되는 과정은 어떻게 되는지 설명해주실 수 있을까요?

더보기

(개발자에의해) Java 소스가 생성되면 자바 컴파일러가 자바 소스를 컴파일 한다. 컴파일 후 생성된 자바 바이트 코드를 JVM에게 전달 후 최종적으로 플랫폼에 맞게 번역하여 실행

Java 컴파일 및 실행 과정 요약:

  1. 소스 코드 작성: 개발자가 자바 소스 파일을 작성한다.
  2. 컴파일: javac 컴파일러가 자바 소스 파일(.java)을 바이트코드(.class)로 변환한다.
  3. 클래스 로딩: JVM이 클래스 로더를 통해 바이트코드(.class)를 메모리로 로드한다.
  4. 실행: JVM의 실행 엔진이 바이트코드를 해석하거나 JIT 컴파일러가 기계어로 변환해 실행한다.
  5. 메모리 관리 및 가비지 컬렉션: JVM이 메모리를 관리하고, 불필요한 객체를 가비지 컬렉터로 제거한다.
  6. 종료: 프로그램 실행이 완료되면 JVM이 종료된다.

7. JVM의 스택과 힙 메모리 영역에 대해 아는 만큼 설명해주실 수 있을까요?

더보기

1. 스택(Stack) 메모리

  • 특징: 스택 메모리는 LIFO(Last In, First Out) 방식으로 관리되는 메모리 영역입니다. 메서드 호출 시 메서드 내에서 사용되는 지역 변수, 매개변수, 그리고 해당 메서드가 호출될 때의 실행 상태(프레임)를 저장합니다.
  • 저장되는 데이터:
    • 지역 변수: 메서드 내부에서 선언된 변수
    • 메서드 호출 시 전달되는 매개변수
    • 메서드 호출에 대한 정보(스택 프레임): 메서드의 실행 상태, 리턴 주소 등이 저장됩니다.
  • 생명주기: 스택 메모리에 저장된 데이터는 메서드가 종료되면 자동으로 제거됩니다. 즉, 각 메서드의 호출과 종료에 따라 스택 프레임이 쌓이고 제거됩니다.
  • 메모리 크기: 상대적으로 작은 크기이며, 스택 오버플로(StackOverflowError)는 재귀 호출이 과도하게 발생하거나 너무 많은 메서드 호출이 일어나면 발생할 수 있습니다.

2. 힙(Heap) 메모리

  • 특징: 힙 메모리는 동적으로 생성된 객체와 배열이 저장되는 영역입니다. 스택과 달리 크기가 상대적으로 크고, 메모리가 할당되거나 해제되는 방식은 JVM의 가비지 컬렉터(Garbage Collector)가 관리합니다.
  • 저장되는 데이터:
    • 인스턴스 객체: new 키워드를 통해 생성된 객체
    • 배열: 모든 배열은 힙 메모리에 저장됩니다.
  • 생명주기: 힙에 저장된 데이터는 프로그램 전체에서 접근 가능하며, 참조가 사라지면 가비지 컬렉터에 의해 메모리가 해제됩니다. 객체는 더 이상 참조되지 않으면 가비지 컬렉션 대상이 됩니다.
  • 메모리 크기: 힙 메모리의 크기는 프로그램이 사용하는 데이터의 양에 따라 유동적이며, 메모리 부족 시 OutOfMemoryError가 발생할 수 있습니다.

스택과 힙의 차이

  • 스택: 메서드 실행과 관련된 지역 변수 저장, 빠른 메모리 접근 속도, 자동 메모리 관리(메서드 종료 시 메모리 해제).
  • : 객체와 배열을 저장하며, 메모리 관리가 가비지 컬렉터에 의해 이루어짐, 상대적으로 느리지만 더 큰 메모리 사용 가능.

8. 클래스와 인스턴스의 차이에 대해 설명해주실 수 있을까요?

더보기

1. 클래스(Class)

  • 정의: 클래스는 객체를 정의하기 위한 청사진 또는 설계도입니다. 클래스는 속성(필드, 멤버 변수)과 동작(메서드)을 포함하여 객체의 구조와 행동을 정의합니다.
  • 역할: 프로그램에서 여러 객체를 만들 때 공통된 특성과 동작을 묘사하는 틀을 제공하여 코드의 재사용성을 높입니다.

2. 인스턴스(Instance)

  • 정의: 인스턴스는 클래스를 기반으로 실제로 생성된 객체입니다. 클래스가 설계도라면, 인스턴스는 그 설계도를 바탕으로 만들어진 구체적인 제품입니다. 인스턴스는 메모리에 생성된 실체로, 클래스에 정의된 속성(필드)과 메서드를 가지며 각 인스턴스는 고유의 상태를 가질 수 있습니다.
  • 역할: 클래스에 정의된 구조와 동작을 실제로 구현하며, 프로그램에서 여러 개의 인스턴스를 만들어 각기 다른 상태를 가지는 객체로 동작하게 할 수 있습니다.

9. Garbage Collector의 역할, 원리, 알고리즘에 대해 아는 만큼 설명해주실 수 있을까요?

더보기

Garbage Collector : 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체를 모아 주기적으로 제거하는 프로세스

Garbage Collector의 역할

  • 역할: GC의 주된 역할은 프로그램 실행 중 더 이상 참조되지 않는 객체를 메모리에서 제거해 힙 메모리를 효율적으로 관리하는 것입니다. 이렇게 함으로써 메모리 부족 현상을 예방하고, 프로그램 성능을 최적화합니다.
  • 목표:
    • 힙 메모리의 효율적 사용: 사용되지 않는 객체를 제거해 새로운 객체를 위한 공간을 확보.
    • 메모리 누수 방지: 프로그램에서 참조되지 않는 객체들이 메모리에 남아 있지 않도록 관리.

10 . Java Map의 내부 구현은 어떻게 이루어져 있을지 추측해보실 수 있을까요?

더보기

Java의 Map 인터페이스는 키와 값의 쌍을 저장하는 자료 구조로, 이를 구현하는 다양한 클래스들이 있습니다. 가장 대표적인 구현체는 HashMap, TreeMap, LinkedHashMap 등이며, 각각 내부 구현 방식이 다릅니다. 이를 바탕으로, Map의 내부 구현 방식을 추측해볼 수 있습니다.

1. HashMap의 내부 구현

HashMap은 해시 테이블을 기반으로 구현되며, 키-값 쌍을 빠르게 검색, 삽입, 삭제할 수 있는 자료 구조입니다.

내부 구조

  • 배열 + 연결 리스트 (혹은 트리): HashMap은 배열을 사용해 데이터를 저장하고, 동일한 해시 값을 가지는 충돌된 키들은 연결 리스트나 트리(자바 8 이후)로 저장됩니다.
  • 버킷: 배열의 각 요소는 버킷이라고 불리며, 하나의 버킷은 동일한 해시 값을 가진 엔트리들의 리스트입니다.
  • Entry 객체: 각 버킷에는 Map.Entry<K, V> 객체가 저장됩니다. 이 객체는 키-값 쌍을 표현하고, 다음 엔트리에 대한 참조(연결 리스트일 경우)를 가집니다.

해시 함수와 충돌 처리

  • 해시 함수: 주어진 키는 해시 함수를 통해 해시 값으로 변환됩니다. 이 해시 값은 배열의 인덱스에 매핑되어 해당 버킷을 찾는 데 사용됩니다.
  • 충돌 해결: 서로 다른 키가 같은 해시 값을 가질 수 있기 때문에, 충돌이 발생할 수 있습니다. 충돌이 발생하면 해당 버킷 내에서 연결 리스트에 추가되며, 자바 8 이후로 연결 리스트의 길이가 일정 수준 이상이 되면 트리로 변환되어 검색 성능을 향상시킵니다.

성능

  • 시간 복잡도: HashMap의 평균적인 삽입, 삭제, 검색 시간 복잡도는 O(1)입니다. 그러나 최악의 경우(충돌이 많이 발생할 경우)에는 O(n)에 가까워질 수 있습니다. 자바 8 이후에는 충돌 시 연결 리스트가 트리로 변환되어 최악의 경우 시간 복잡도가 O(log n)으로 개선되었습니다.

2. TreeMap의 내부 구현

TreeMap은 이진 검색 트리(레드-블랙 트리)를 기반으로 한 Map의 구현체입니다. 키의 정렬 순서를 유지하며 데이터를 저장하고 관리합니다.

내부 구조

  • 레드-블랙 트리: TreeMap은 레드-블랙 트리로 구현되어 있으며, 삽입, 삭제, 검색 작업이 효율적으로 수행될 수 있도록 트리가 항상 균형을 유지합니다.
  • 정렬된 키: 트리의 각 노드는 키와 값의 쌍을 저장하며, 키는 자연 순서(Comparable 인터페이스 구현)나 사용자 정의 Comparator에 따라 정렬됩니다.

성능

  • 시간 복잡도: TreeMap의 삽입, 삭제, 검색은 모두 O(log n)의 시간 복잡도를 가집니다. 이는 트리의 높이가 로그에 비례하기 때문입니다.

3. LinkedHashMap의 내부 구현

LinkedHashMap은 HashMap의 특성을 유지하면서, 삽입 순서를 기억하는 기능을 추가한 구현체입니다.

내부 구조

  • HashMap + 이중 연결 리스트: LinkedHashMap은 HashMap과 유사하게 해시 테이블을 사용하지만, 각 엔트리가 이중 연결 리스트로 연결되어 있습니다. 이로 인해 삽입된 순서나 최근 접근 순서를 기억할 수 있습니다.
  • 순서 유지: 기본적으로는 삽입 순서를 유지하지만, LRU(Least Recently Used) 방식으로 순서를 변경할 수도 있습니다.

성능

  • 시간 복잡도: LinkedHashMap도 HashMap과 유사한 성능을 가지며, 삽입, 삭제, 검색의 평균적인 시간 복잡도는 **O(1)**입니다.

4. ConcurrentHashMap의 내부 구현

ConcurrentHashMap은 다중 스레드 환경에서 안전하게 Map을 사용할 수 있도록 설계된 구현체입니다.

내부 구조

  • 세그먼트 락(Segment Lock): ConcurrentHashMap은 해시 테이블을 여러 **세그먼트(Segment)**로 나누어, 각 세그먼트에 대해 별도로 락을 걸 수 있게 하여 동시성을 높입니다. 즉, 여러 스레드가 다른 세그먼트에 대해 동시에 접근할 수 있습니다.
  • 락 분할(Lock Striping): 전체 맵에 락을 걸지 않고, 특정 세그먼트에만 락을 걸어 성능 저하를 방지합니다.

성능

  • 시간 복잡도: 락 분할 덕분에 성능이 향상되며, 다중 스레드 환경에서 락 경합을 줄이면서도 안전하게 동작합니다. 평균적인 시간 복잡도는 **O(1)**이지만, 여러 스레드가 동시에 접근할 경우 성능에 영향을 받을 수 있습니다.

5. 요약

  • HashMap: 해시 테이블을 기반으로, 평균 **O(1)**의 성능을 제공하며 충돌 시 연결 리스트 또는 트리로 처리.
  • TreeMap: 레드-블랙 트리를 기반으로, 키가 정렬된 상태로 저장되며 **O(log n)**의 성능.
  • LinkedHashMap: 해시 테이블에 삽입 순서를 유지하기 위해 이중 연결 리스트를 추가한 구현체로, 성능은 HashMap과 유사.
  • ConcurrentHashMap: 다중 스레드 환경에서 안전한 동시성을 제공하며, 세그먼트 락을 사용해 성능을 최적화.

이러한 내부 구현 방식을 통해 Map의 다양한 구현체들은 서로 다른 성능과 특성을 제공합니다.

+ 추가 정보)

Java 8 버전 이후로 Hash key 이외에 Tree key도 지원

https://devlogofchris.tistory.com/41

 

[JAVA]Map이란? (HashMap, Hashtable, TreeMap)

Map 컬렉션 클래스 Map 인터페이스는 Collection 인터페이스와는 다른 저장 방식을 가집니다. Map 인터페이스를 구현한 Map 컬렉션 클래스들은 키와 값을 하나의 쌍으로 저장하는 방식(key-value 방식)을

devlogofchris.tistory.com

Loadfactor

https://mungto.tistory.com/309

 

LoadFactor란 무엇인가?

Java의 Map에 대해서 공부를 하다보니 Load Factor라는 이야기가 나왔다. LoadFactor란 무엇인가? 부하율 혹은 적재율을 나타낸다. Java의 경우 Map의 LoadFactor는 0.75로 총 버킷의 75% 달하는 데이터가 적재된

mungto.tistory.com

Java의 경우 Map의 LoadFactor는 0.75로 총 버킷의 75% 달하는 데이터가 적재된다면 배열을 확장한다.

11 . DI와 IoC에 대해 아는 만큼 설명해주실 수 있을까요?

더보기

IoC(Inversion of Control) - 제어의 역전

 

객체의 생성과 의존성 관리를 개발자가 제어하지 않고, 외부의 컨테이너나 프레임워크에 맡기는 설계 원칙입니다.

 

전통적인 제어 방식: 객체가 스스로 필요한 의존성을 생성하고 관리하며, 모든 흐름을 개발자가 직접 제어합니다

→ IoC 방식: 제어의 흐름이 역전되어 프레임워크(예: Spring)가 객체를 생성하고 주입해줍니다. 개발자는 더 이상 직접 객체를 생성하지 않으며, 객체의 생성과 라이프사이클은 컨테이너가 관리합니다.

IoC의 장점

  • 의존성 분리: 각 객체가 서로의 의존성에 대한 결합도를 줄일 수 있습니다.
  • 테스트 용이성: 의존성을 외부에서 주입받기 때문에, 유닛 테스트 시에 모킹(mocking) 등을 쉽게 사용할 수 있습니다.
  • 유연성 증가: 객체 간의 관계가 느슨하게 결합되므로, 유지보수와 확장이 쉬워집니다.

 

DI(Dependency Injection) - 의존성 주입

IoC를 구현하는 방법 중 하나로, 객체의 의존성을 외부에서 주입받는 방식입니다.

 

IoC와 DI의 장점

 IoC와 DI는 코드의 유연성과 테스트 용이성을 높이고, 객체 간의 결합도를 낮춰 유지보수성을 향상시킵니다.

DI의 주요 방식

생성자 주입(Constructor Injection):

class Service {
    private Repository repository;

    // 생성자를 통한 주입
    public Service(Repository repository) {
        this.repository = repository;
    }

    public void doSomething() {
        repository.save();
    }
}
  • 객체를 생성할 때 생성자를 통해 의존성을 주입하는 방식입니다. 이 방식은 주입받는 객체가 필수적으로 필요할 때 유용합니다.
  • 이 방식은 **불변성(immutability)**을 보장할 수 있어 객체가 항상 필요한 의존성을 가지고 초기화될 수 있습니다.

세터 주입(Setter Injection):

class Service {
    private Repository repository;

    // 세터 메서드를 통한 주입
    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    public void doSomething() {
        repository.save();
    }
}
  • 생성자가 아닌 세터 메서드를 통해 의존성을 주입하는 방식입니다. 이 방식은 선택적인 의존성 주입에 적합하며, 객체 생성 후 의존성을 변경할 수 있습니다.
  • 이 방식은 객체 생성 이후에 의존성을 설정할 수 있으나, 주입이 제대로 이루어지지 않았을 때 발생할 수 있는 문제(NullPointerException) 등을 방지하기 위해 주의해야 합니다.

필드 주입(Field Injection):

class Service {
    @Autowired
    private Repository repository;

    public void doSomething() {
        repository.save();
    }
}
  • 객체의 필드에 직접적으로 의존성을 주입하는 방식입니다. 주로 프레임워크(예: Spring)에서 @Autowired와 같은 어노테이션을 통해 구현됩니다.
  • 필드 주입은 가장 간단한 방식이지만, 의존성 주입을 보장하기 어렵고, 테스트에서 의존성 관리가 어려울 수 있어 권장되지 않는 방식으로 간주되기도 합니다

https://dev-coco.tistory.com/70

IoC와 DI의 예: Spring 프레임워크

Spring 프레임워크는 IoC와 DI의 대표적인 예입니다. Spring 컨테이너는 객체(빈)를 관리하며, 필요한 의존성을 주입하는 역할을 담당합니다.

  • IoC 컨테이너: ApplicationContext와 같은 Spring의 IoC 컨테이너는 객체를 관리하고, 의존성을 주입하여 객체 간의 관계를 관리합니다.
  • DI: Spring은 @Autowired, XML 설정, Java Config 등 다양한 방식으로 의존성을 주입할 수 있습니다. 이를 통해 객체 간의 강한 결합을 줄이고, 코드의 유연성을 높입니다.

 

12. MVC 모델이란 무엇인지 설명해주실 수 있을까요?

더보기

mvc

소프트웨어 설계 패턴 중 하나로, 애플리케이션을 모델(Model), 뷰(View), **컨트롤러(Controller)**의 세 가지 구성 요소로 나누어 설계하는 패턴입니다. 이 구조는 애플리케이션의 로직과 사용자 인터페이스(UI)를 분리하여 코드의 유지보수성, 확장성, 재사용성을 높이는 데 중점을 둡니다.

1. MVC의 구성 요소

MVC 패턴은 각각의 역할을 분명하게 분리하여 애플리케이션의 동작을 정의합니다. 각 요소의 역할은 다음과 같습니다.

1. Model (모델)

  • 역할: 애플리케이션의 데이터와 비즈니스 로직을 관리합니다. 데이터베이스와의 상호작용, 비즈니스 규칙, 상태 등을 처리합니다.
  • 책임: 데이터를 저장하고 조작하는 기능을 제공하며, 애플리케이션의 핵심 로직을 담고 있습니다.
  • 특징: 모델은 독립적으로 존재하며, 다른 부분(View, Controller)에 대해 알지 못합니다. 데이터와 상태 변경 시 이를 알림으로 전달합니다.

2. View (뷰)

  • 역할: 사용자에게 데이터를 시각적으로 표현하는 역할을 담당합니다. 모델에서 데이터를 가져와 화면에 표시하는 부분입니다.
  • 책임: 모델의 데이터를 사용자에게 보여주고, 입력된 데이터를 받아 처리할 준비를 합니다. UI에 대한 부분만 담당하며, 비즈니스 로직은 포함되지 않습니다.
  • 특징: 뷰는 컨트롤러나 모델을 통해 데이터를 전달받고 이를 시각적으로 표현하지만, 모델의 상태를 직접 변경하지 않습니다.

3. Controller (컨트롤러)

  • 역할: 사용자 입력을 처리하고, 입력에 따라 모델과 뷰를 업데이트하는 역할을 담당합니다. 모델과 뷰 간의 중개자 역할을 하여, 사용자의 요청을 모델에게 전달하고, 모델의 상태 변화에 따라 적절한 뷰를 선택하여 사용자에게 응답합니다.
  • 책임: 사용자로부터 입력을 받아서 이를 처리하는 로직을 담고 있으며, 모델을 수정하거나 뷰를 업데이트하는 일을 담당합니다. 컨트롤러는 사용자 요청을 해석하고 그에 따라 데이터를 갱신하거나 필요한 작업을 수행합니다.

13. Annotation이란 무엇이고 구체적으로 어떤 것이 있는지 예시를 들어 설명해주실 수 있을까요?

더보기

에너테이션

 

자바에서 메타데이터를 제공하는 특별한 형식의 코드이다. 프로그램의 동작에 직접 영향을 주지 않지만 , 컴파일러에게 특정 정보를 전달하거나 런타임 시 특정 동작을 하도록 지시할 수 있다.

자주 사용하는 자바 표준 어노테이션

@Override : 부모클래스의; 메서드를 오버라이드 재정의 한다는 것을 명시

@Deprecated : 더 이상 사용되지 않는 코드에 붙여, 해당 요소가 앞으로는 제거될 수 있다는 경고를 표시합니다

@Autowired : 스프링에서 의존성 주입(DI)를 할 때 사용하는 애너테이션으로 스프링이 자동으로 해당 필드나 메서드에 필요한 객체를 주입한다. 

@Transactional : 메서드나 클래스에 트랜잭션을 적용할 때 사용한다. 

@Mapping : GET, POST 명령에 따른 restapi application을 만들 때 사용

14. Spring Security의 구조와 JWT 발급 과정에 대해 설명해주실 수 있을까요?

더보기

spring security

 

애플리케이션의 **인증(Authentication)**과 **인가(Authorization)**를 관리하는 강력한 보안 프레임워크입니다. 이를 통해 사용자의 접근 권한을 제어하고, 보안 설정을 유연하게 관리할 수 있습니다. 최근에는 **JWT (JSON Web Token)**를 활용한 인증 방식이 널리 사용되며, 특히 RESTful API와 같은 무상태(stateless) 애플리케이션에서 자주 사용됩니다

 

인증 : 사용자가 누구인지 확인하는 과정

인가 : 인증된 사용자가 어떤 리소스에 접근할 수 있는 지를 결정

 

  • SecurityContext: 현재 사용자의 인증 정보를 담고 있는 컨텍스트로, 요청이 들어올 때마다 유지됩니다.
  • AuthenticationManager: 인증 로직을 처리하는 핵심 인터페이스입니다. 다양한 인증 방법 (JWT, OAuth 등)을 지원할 수 있습니다.
  • FilterChain: 들어오는 요청을 필터링하여 인증과 인가를 처리하는 필터 체인입니다.
  • UserDetailsService: 사용자의 정보를 로드하는 서비스로, 데이터베이스에서 사용자 정보를 가져와 인증 과정에서 활용합니다.

JWT 발급과정은 다음과 같다. 우선 JWT는 HS256 기반의 헤더 , 페이로드, 서명 세 부분으로 이루어집니다. 

  • 사용자 인증 요청: 클라이언트(사용자)는 로그인 정보를 입력하여 서버에 인증을 요청합니다. 보통 username과 password를 HTTP POST 요청으로 서버에 전달합니다.
  • 인증 처리: 서버는 Spring Security의 AuthenticationManager를 사용하여 전달받은 사용자 정보를 인증합니다. 이 과정에서 UserDetailsService는 데이터베이스에 저장된 사용자 정보를 로드하여 인증을 진행합니다.
  • JWT 생성: 인증이 성공하면 서버는 사용자 정보를 바탕으로 JWT를 생성합니다. JWT에는 사용자 ID, 권한, 만료 시간 등의 정보가 포함됩니다. 이 JWT는 사용자에게 발급되며, 사용자는 이 토큰을 클라이언트에 저장(예: 브라우저의 로컬 스토리지 또는 쿠키)합니다

15. N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상 말씀해주시면 좋습니다.

더보기

N+1 문제는 데이터베이스에서 객체를 조회할 때 발생하는 성능 문제로, 주로 ORM(Object Relational Mapping) 프레임워크를 사용할 때 나타납니다. 이 문제는 하나의 쿼리로 N개의 객체를 조회할 때, 각 객체에 대한 추가적인 쿼리가 N번 더 실행되어 총 N+1개의 쿼리가 발생하는 상황을 말합니다.

N+1 문제 발생 이유

N+1 문제는 일반적으로 지연 로딩(Lazy Loading) 때문에 발생합니다. 지연 로딩은 객체를 조회할 때, 그 객체와 연관된 데이터는 필요할 때까지 데이터베이스에서 가져오지 않고 미루는 방식입니다. 예를 들어, 부모 엔티티를 조회한 후, 그와 연관된 자식 엔티티를 지연 로딩하게 되면, 부모 객체를 먼저 조회하는 쿼리 1개와 자식 객체를 각각 개별로 조회하는 N개의 추가 쿼리가 발생하게 됩니다.

N+1 문제 해결 방법

1. 즉시 로딩(Eager Loading)

@ManyToOne, @OneToMany 등의 관계 설정에서 즉시 로딩을 사용하여 연관된 엔티티를 함께 조회하도록 설정합니다. 즉시 로딩을 사용하면 부모 엔티티를 조회할 때 자식 엔티티도 한 번의 조인 쿼리로 가져옵니다.

2. JPQL(JPA Query Language)에서 JOIN FETCH 사용

JPQL에서 JOIN FETCH를 사용하면 연관된 엔티티를 함께 조회할 수 있습니다. 이 방법은 지연 로딩을 사용하면서도 연관된 데이터를 한 번에 가져오는 쿼리를 작성할 수 있어 유용합니다. 이 방식은 N+1 문제를 방지하면서도 필요한 시점에만 데이터를 가져올 수 있습니다. JOIN FETCH를 사용하면 User와 관련된 Post를 한 번의 쿼리로 모두 가져옵니다.

3. Entity Graph 사용

JPA에서 제공하는 Entity Graph를 사용하면 N+1 문제를 해결할 수 있습니다. 특정 필드를 즉시 로딩하는 방식으로 동작하며, 메서드 호출 시 그래프를 정의하여 연관된 엔티티를 한 번에 가져오게 할 수 있습니다. 위 코드에서는 EntityGraph를 사용해 User를 조회할 때 Post 필드를 함께 가져오도록 지정했습니다. 이 방법은 필요한 쿼리만 최적화하여 실행할 수 있어 성능에 긍정적인 영향을 미칩니다.

16. 즉시로딩과 지연로딩은 각각 언제 사용하면 좋은지 설명해주실수 있을까요?

더보기

즉시 로딩(Eager Loading)과 지연 로딩(Lazy Loading)은 데이터베이스에서 연관된 데이터를 조회할 때 사용되는 전략입니다. 각각의 사용 시점은 성능과 데이터 사용 시나리오에 따라 다릅니다.

1. 즉시 로딩 (Eager Loading)

즉시 로딩은 연관된 데이터를 즉시 한 번에 로드하는 방식입니다. 즉, 엔티티를 조회할 때 그와 연관된 모든 데이터도 함께 조회됩니다.

언제 사용하면 좋은가?

  • 연관된 데이터를 자주 사용하는 경우: 특정 엔티티를 사용할 때, 그와 연관된 데이터를 거의 항상 함께 사용하는 경우. 예를 들어, Order 엔티티를 조회할 때 관련된 OrderItem을 자주 사용하는 경우, 즉시 로딩을 통해 한 번에 데이터를 가져오면 성능이 향상될 수 있습니다.
  • 데이터베이스 쿼리 수를 줄이고 싶은 경우: 한 번의 쿼리로 모든 데이터를 가져오므로 N+1 문제를 방지할 수 있습니다. 대량의 쿼리 실행을 방지하고 싶을 때 유용합니다.
  • 성능이 충분히 여유 있을 때: 모든 연관 데이터를 미리 로딩하므로 데이터베이스 부하가 증가할 수 있으나, 성능이 충분하다면 큰 문제가 되지 않습니다.

주의할 점:

  • 불필요한 데이터 로딩: 사용하지 않을 데이터도 로드되기 때문에 메모리와 성능에 불필요한 부하를 줄 수 있습니다.

2. 지연 로딩 (Lazy Loading)

지연 로딩은 연관된 데이터를 필요할 때 로드하는 방식입니다. 즉, 처음에는 연관된 데이터를 가져오지 않고, 실제로 그 데이터를 사용할 때 쿼리가 실행됩니다.

언제 사용하면 좋은가?

  • 연관된 데이터를 자주 사용하지 않는 경우: 엔티티의 연관 데이터를 특정 상황에서만 사용할 때. 예를 들어, User 엔티티에서 UserProfile 정보를 자주 사용하지 않는 경우, 필요할 때만 로딩하는 것이 효율적입니다.
  • 메모리 효율을 중시할 때: 필요한 데이터만 가져오기 때문에 메모리 사용량이 줄어들고, 불필요한 데이터 로딩으로 인한 성능 저하를 막을 수 있습니다.
  • 대규모 데이터를 다룰 때: 모든 데이터를 한 번에 가져오지 않고, 필요한 데이터만 점진적으로 로드할 수 있으므로 성능을 개선할 수 있습니다.

주의할 점:

  • N+1 문제 발생 가능: 연관 데이터를 반복적으로 사용하면 매번 쿼리가 실행되어 성능이 저하될 수 있습니다.
  • 프록시 객체에 의존: 지연 로딩은 프록시 객체를 사용하여 데이터베이스에 추가 쿼리를 실행하는데, 이로 인해 예기치 않은 동작이나 LazyInitializationException이 발생할 수 있습니다. 이를 방지하기 위해 트랜잭션 범위 내에서 지연 로딩을 처리해야 합니다.

17. Spring bean container 생성부터 스프링 종료까지의 사이클에 대해 알려주실 수 있을까요? @PostConstruct,@PreDestory 어노테이션의 역할도 함께 알려주시면 좋을 거 같습니다.

더보기

Spring Bean LifeCycle 요약

  1. Bean Container 생성: ApplicationContext 또는 BeanFactory 생성.
  2. Bean 정의 로드: 설정 파일을 통해 Bean 메타데이터를 로드.
  3. Bean 생성: 정의된 Bean 인스턴스가 생성됨.
  4. 의존성 주입: 생성된 Bean에 의존성 주입.
  5. 초기화: @PostConstruct 어노테이션을 통해 초기화 메서드 호출.
  6. Bean 사용: 애플리케이션에서 Bean 사용.
  7. 종료 및 소멸: @PreDestroy 어노테이션을 통해 소멸 전 정리 작업 수행.
  8. Spring 종료: 애플리케이션 종료.

@PostConstruct와 @PreDestroy의 역할

  • @PostConstruct: Bean이 완전히 생성되고, 의존성 주입이 완료된 후 호출. 초기화 작업에 사용.
  • @PreDestroy: Bean이 소멸되기 전에 호출. 리소스 정리나 외부 자원 해제 작업에 사용.

이를 통해 Spring Bean의 생명주기 동안 필요한 초기화 및 정리 작업을 자동으로 처리할 수 있다.

18. AOP, Intercepter, Filter의 차이점 , Request가 들어올 때 거치는 순서 , 각 역할 들의 장점을 설명해주실수 있나요?

더보기

AOP, Interceptor, Filter의 차이점

AOP (Aspect-Oriented Programming)

  • 개념: 비즈니스 로직에 횡단 관심사(로깅, 트랜잭션, 보안 등)를 분리하여 관리하는 프로그래밍 패턴입니다. 메소드 호출 전후나 예외 발생 시 등 특정 시점에서 공통 로직을 처리할 수 있게 해줍니다.
  • 적용 대상: Spring Bean에만 적용됩니다.
  • 작동 방식: 메서드 실행 전후에 공통 기능을 적용하는 방식으로 Advice와 JoinPoint를 사용하여 동작합니다.
  • 용도: 트랜잭션 관리, 로깅, 예외 처리 등 비즈니스 로직과 관련된 기능을 주로 처리합니다.

장점:

  • 코드 중복 제거: 횡단 관심사를 분리함으로써 코드의 중복을 줄일 수 있습니다.
  • 코드 유지보수성 향상: 핵심 로직과 공통 기능을 분리하여 관리할 수 있어 코드의 가독성과 유지보수성이 좋아집니다.

Interceptor

  • 개념: Spring MVC에서 HandlerInterceptor를 구현하여 사용되며, 컨트롤러로 들어가는 요청을 가로채서 전처리, 후처리를 수행할 수 있습니다.
  • 적용 대상: HTTP 요청/응답 흐름에서 Controller에 도달하기 전후에 개입합니다.
  • 작동 방식: preHandle(), postHandle(), afterCompletion() 메서드를 사용하여 요청 전, 응답 후, 뷰 렌더링 후에 각각 동작합니다.
  • 용도: 인증 및 권한 체크, 로깅, 공통 처리 작업 등을 할 수 있습니다.

장점:

  • 비즈니스 로직에 영향을 주지 않고 공통 작업을 처리할 수 있습니다.
  • 요청 처리 전후를 각각 처리할 수 있어, 다양한 처리 시점을 활용할 수 있습니다.

Filter

  • 개념: Java EE 표준 서블릿 필터로, 클라이언트에서 서버로 들어오는 HTTP 요청과 서버에서 클라이언트로 나가는 응답을 가로채서 처리할 수 있는 기능입니다. Spring에서도 필터는 서블릿 스펙을 기반으로 동작합니다.
  • 적용 대상: 요청(Request)와 응답(Response)의 전반적인 흐름을 제어하며, 모든 서블릿 요청에 대해서 동작할 수 있습니다.
  • 작동 방식: doFilter() 메서드를 사용하여 요청이 들어오기 전에 필터링 작업을 하거나 요청을 전달하기 전에 응답을 수정할 수 있습니다.
  • 용도: 인코딩 설정, 보안 관련 처리(CORS 설정, 인증), 요청 검증 등을 할 수 있습니다.

장점:

  • HTTP 요청과 응답 전체를 대상으로 동작하여 범용적으로 사용할 수 있습니다.
  • 클라이언트와 서버 사이의 전반적인 흐름을 제어할 수 있어, 보안이나 로깅과 같은 전반적인 처리에 적합합니다.

Request가 들어올 때 거치는 순서

  1. Filter (서블릿 필터)
    • 요청이 들어오면 가장 먼저 Filter가 동작합니다. HTTP 요청/응답에 대한 전반적인 처리를 여기서 할 수 있습니다. 예를 들어, 보안 검사를 하거나, 인코딩을 설정하는 등의 작업을 수행합니다.
    • 요청 처리 전후 모두 개입할 수 있습니다.
  2. Interceptor (스프링 인터셉터)
    • Filter를 거친 후, DispatcherServlet이 요청을 처리할 때 Interceptor가 동작합니다.
    • preHandle()이 먼저 호출되어 Controller로 요청이 전달되기 전에 실행됩니다. 요청을 중단하거나, 추가 정보를 로그에 기록하는 작업이 가능합니다.
    • Controller에서 응답을 생성한 후에는 postHandle()이 실행되며, 응답이 완성되기 전에 추가적인 작업을 할 수 있습니다.
    • 뷰가 렌더링된 후에는 afterCompletion()이 호출되어 최종 정리 작업을 수행할 수 있습니다.
  3. AOP (Spring AOP)
    • Interceptor에서 Controller로 요청이 넘어간 후, 메서드 실행 단계에서 AOP가 동작합니다.
    • 메서드의 실행 전후(Before, After, AfterReturning, Around)에서 횡단 관심사(Cross-cutting Concerns)를 처리합니다.
    • 이 시점에서는 트랜잭션 처리, 메서드 호출 로깅, 예외 처리 등의 작업을 할 수 있습니다.

각 역할의 장점 요약

  • AOP:
    • 메서드 실행 전후의 횡단 관심사를 처리하여 중복된 코드를 제거하고 로직을 명확하게 분리합니다.
    • 주로 로깅, 트랜잭션 처리, 예외 처리 등에 사용됩니다.
  • Interceptor:
    • Controller의 실행 전후에 전처리와 후처리를 수행할 수 있어, 인증, 권한 체크, 로깅에 유용합니다.
    • 요청 흐름에 따라 처리할 작업을 구체적으로 나누어 구현할 수 있습니다.
  • Filter:
    • 요청과 응답 전체를 다룰 수 있어, 보안 설정, CORS, 인코딩 설정 등 전반적인 HTTP 요청을 관리합니다.
    • 서블릿 스펙에 맞게 작동하므로 Spring 외에도 다른 서블릿 기반 애플리케이션에서도 사용할 수 있습니다.

정리

  • Filter는 가장 먼저 동작하며 요청과 응답 전체를 다루는 전반적인 작업에 적합합니다.
  • Interceptor는 컨트롤러로 가기 전후에 개입하여, 주로 인증/권한 체크나 공통적인 로직을 처리합니다.
  • AOP는 메서드 실행 시점에 특정 로직을 주입할 수 있는 강력한 도구로, 주로 횡단 관심사에 사용됩니다.

19. NoSQL과 RDBMS의 특징과 차이점에 대해서 장, 단점을 들어 설명해주세요.

더보기

1. RDBMS (관계형 데이터베이스 관리 시스템)

RDBMS는 데이터가 테이블이라는 구조로 조직화되며, 각 테이블은 행과 열로 구성됩니다. RDBMS는 데이터 간의 관계를 **SQL(Structured Query Language)**로 처리하고, 관계형 모델을 기반으로 데이터를 관리합니다.

장점

  • 데이터 일관성: RDBMS는 ACID(Atomicity, Consistency, Isolation, Durability)를 준수하여 트랜잭션이 안전하게 처리되며, 데이터 일관성이 보장됩니다.
  • 복잡한 쿼리 처리: SQL을 사용해 JOIN과 같은 복잡한 쿼리를 효율적으로 처리할 수 있습니다. 여러 테이블 간의 복잡한 관계를 처리하는 데 적합합니다.
  • 표준화된 언어(SQL): SQL은 오랜 기간 표준으로 사용되었으며, 잘 정립된 툴과 라이브러리들이 존재합니다.
  • 정형화된 데이터: 데이터 스키마가 엄격하게 정의되어 있어, 데이터를 정형화하고 구조적으로 관리할 수 있습니다.

단점

  • 확장성 문제: RDBMS는 수직적 확장(성능 향상을 위해 더 강력한 서버를 사용하는 방식)이 일반적이며, 대규모 트래픽을 처리하는 데 한계가 있을 수 있습니다.
  • 유연성 부족: 스키마가 고정되어 있어 데이터 구조를 변경하려면 많은 작업이 필요합니다. 비정형 데이터를 다루기 어렵습니다.
  • 복잡한 관계 처리 비용: JOIN 같은 복잡한 관계형 연산이 많아질수록 성능이 저하될 수 있습니다.

2. NoSQL (비관계형 데이터베이스)

NoSQL은 비관계형 데이터베이스로, 데이터를 테이블 대신 문서, 키-값, 그래프, 컬럼 등의 형식으로 저장합니다. 비정형 데이터를 유연하게 처리하는 데 적합하며, 데이터 스키마가 유연합니다.

장점

  • 확장성: NoSQL은 수평적 확장(서버를 추가하여 클러스터를 확장하는 방식)이 가능하여, 대규모 데이터와 높은 트래픽을 처리하는 데 적합합니다.
  • 유연한 스키마: 고정된 스키마가 없어서 비정형 데이터나 동적으로 변화하는 데이터를 저장할 수 있으며, 데이터 구조를 쉽게 변경할 수 있습니다.
  • 성능: RDBMS에 비해 쿼리 성능이 빠를 수 있습니다. 특히 대량의 읽기 또는 쓰기 작업에서 성능이 뛰어납니다.
  • 다양한 데이터 모델: 문서 지향형, 키-값, 그래프 등 다양한 데이터 모델을 지원하여 사용 사례에 따라 적합한 방식을 선택할 수 있습니다.

단점

  • 데이터 일관성 부족: NoSQL은 CAP 이론에서 가용성(Availability)과 파티션 허용성(Partition Tolerance)을 중시하며, 일관성(Consistency)이 희생될 수 있습니다. 강한 트랜잭션 처리가 필요한 경우에는 적합하지 않을 수 있습니다.
  • 복잡한 쿼리 처리 부족: NoSQL은 복잡한 JOIN 연산을 지원하지 않거나, 이를 효율적으로 처리하지 못하는 경우가 많습니다. 복잡한 관계형 데이터 처리에는 부적합할 수 있습니다.
  • 표준화 부족: RDBMS와 달리 NoSQL은 표준화된 쿼리 언어가 없으며, 각 DB마다 사용하는 쿼리 방식이 다릅니다. 따라서 데이터베이스 간에 이식성이 떨어질 수 있습니다.
  • 데이터 중복: NoSQL에서는 데이터를 중복해서 저장하는 경우가 많아 데이터의 무결성을 관리하기 어려울 수 있습니다.

3. NoSQL과 RDBMS의 비교 요약

특성 RDBMS NoSQL
데이터 구조 정형 데이터, 고정된 스키마 비정형 데이터, 유연한 스키마
확장성 수직적 확장 (성능 향상을 위해 더 강력한 서버 사용) 수평적 확장 (서버를 추가하여 성능 향상)
트랜잭션 ACID 트랜잭션 지원 보통 BASE(일관성보다 가용성 중시)
쿼리 언어 SQL 다양한 쿼리 언어 및 API 사용
성능 적은 데이터 및 복잡한 관계형 쿼리에서 유리 대량의 데이터 및 읽기/쓰기 성능에 유리
유연성 스키마 변경이 어려움 스키마가 유연하고 비정형 데이터에 적합
사용 사례 금융, ERP, 고객 관계 관리 시스템 등 소셜 네트워크, 빅데이터, IoT 등 비정형 데이터 처리

4. 결론

  • RDBMS는 데이터의 정확성과 일관성이 중요한 트랜잭션 기반 시스템에 적합하며, 복잡한 관계형 데이터를 처리하는 데 강점이 있습니다.
  • NoSQL은 대규모 트래픽과 데이터를 유연하게 처리할 수 있으며, 확장성이 뛰어나므로 빅데이터, 실시간 웹 애플리케이션 등에서 유용합니다.

20. RDBMS의 정규화에 대해 설명해주세요.

더보기

정규화(Normalization)는 관계형 데이터베이스(RDBMS)에서 데이터를 구조화하고 중복을 최소화하기 위해 사용하는 방법입니다. 데이터베이스에서 데이터를 보다 효율적으로 저장하고 유지 관리하기 위해 테이블을 설계하는 과정으로, 데이터의 무결성을 유지하고 이상현상(anomalies)을 방지하는 데 중점을 둡니다.

정규화는 여러 **정규형(Normal Form)**으로 나누어지며, 각 정규형은 특정 규칙을 따름으로써 데이터베이스 설계의 품질을 높이는 역할을 합니다.

1. 정규화의 목적

  • 중복 데이터 최소화: 데이터 중복을 최소화하여 저장 공간을 절약하고, 중복으로 인한 데이터 불일치를 방지합니다.
  • 데이터 무결성 보장: 데이터를 삽입, 삭제, 수정할 때 발생할 수 있는 갱신 이상(Update Anomaly), 삭제 이상(Delete Anomaly), 삽입 이상(Insert Anomaly)을 방지합니다.
  • 유지보수 용이: 데이터베이스 구조가 단순해지므로 유지보수가 쉬워지고 데이터의 수정과 확장이 용이합니다.

2. 정규화 과정 및 정규형

정규화는 각 단계마다 더 엄격한 규칙을 적용하여 데이터를 정리합니다. 주로 사용되는 정규형은 1NF(제1정규형), 2NF(제2정규형), 3NF(제3정규형), 그리고 **BCNF(Boyce-Codd 정규형)**입니다.

(1) 제1정규형 (1NF): 중복된 데이터 허용 X, 원자값(Atomic Value) 유지

  • 규칙: 모든 필드가 **원자값(Atomic Value)**을 가져야 하며, 중복되는 행이 없어야 합니다. 즉, 각 필드에 더 이상 분리할 수 없는 단일 값이 들어가야 합니다.
  • 예시: 한 셀에 여러 개의 값이 들어가는 경우 1NF를 위반합니다. 예를 들어, 하나의 필드에 여러 개의 전화번호를 저장하는 대신, 각 전화번호를 별도의 행이나 테이블로 분리해야 합니다.IDNamePhoneNumber
    1 Alice 010-1111-1111, 010-2222-2222
    1NF 준수 예시IDNamePhoneNumber
    1 Alice 010-1111-1111
    1 Alice 010-2222-2222
  • 위반 예시

(2) 제2정규형 (2NF): 부분적 종속성 제거

  • 규칙: 1NF를 만족하면서, 기본키의 부분적 종속성(Partial Dependency)을 제거해야 합니다. 즉, 기본키의 일부에만 의존하는 필드가 없어야 합니다.
  • 부분적 종속성: 하나의 테이블에서 기본키가 여러 필드로 구성된 경우, 그 기본키의 일부에만 의존하는 비키(Non-Key) 필드는 제거되어야 합니다.
  • 해결 방법: 부분적으로 종속된 필드를 분리하여 다른 테이블로 나누어야 합니다.StudentIDCourseIDStudentNameCourseName
    1 101 Alice Math
    2 102 Bob English
    여기서 StudentName은 StudentID에만 종속되고, CourseName은 CourseID에 종속됩니다. 따라서 부분적 종속성이 존재하므로 2NF를 위반합니다.StudentIDStudentName
    1 Alice
    2 Bob
    CourseIDCourseName
    101 Math
    102 English
  • 2NF 준수 예시
  • 위반 예시

(3) 제3정규형 (3NF): 이행적 종속성 제거

  • 규칙: 2NF를 만족하면서, 이행적 종속성(Transitive Dependency)을 제거해야 합니다. 즉, 기본키가 아닌 필드가 다른 비키(Non-Key) 필드에 의존하면 안 됩니다.
  • 이행적 종속성: 비키 필드가 다른 비키 필드에 종속된 경우를 말합니다.
  • 해결 방법: 이행적으로 종속된 필드를 분리하여 별도의 테이블로 옮겨야 합니다.StudentIDStudentNameDepartmentIDDepartmentName
    1 Alice 10 Computer Science
    2 Bob 20 Mathematics
    여기서 DepartmentName은 DepartmentID에 종속되며, 이는 StudentID와 직접적인 관계가 없으므로 이행적 종속성이 존재합니다.StudentIDStudentNameDepartmentID
    1 Alice 10
    2 Bob 20
    DepartmentIDDepartmentName
    10 Computer Science
    20 Mathematics
  • 3NF 준수 예시
  • 위반 예시

(4) BCNF (Boyce-Codd 정규형): 후보키에 대한 더 강력한 제약

  • 규칙: 3NF를 만족하면서, 모든 결정자가 후보키(Superkey)여야 합니다. 즉, 모든 함수적 종속에서 좌변(결정자)이 반드시 후보키여야 합니다.
  • 해결 방법: 3NF를 만족하면서 후보키가 아닌 결정자가 있는 경우 테이블을 더 분리해야 합니다.

3. 정규화의 장점

  • 데이터 중복 제거: 중복된 데이터가 제거되므로, 저장 공간이 절약되고 데이터 불일치의 위험이 줄어듭니다.
  • 데이터 무결성 보장: 데이터의 일관성과 무결성을 보장하여, 잘못된 데이터가 저장되는 것을 방지합니다.
  • 데이터 수정 용이성: 데이터를 삽입, 수정, 삭제하는 과정에서 이상현상이 발생하지 않아 유지보수가 용이해집니다.

4. 정규화의 단점

  • 복잡성 증가: 테이블이 분리되면서 복잡한 JOIN 쿼리가 필요하게 되어, 성능이 저하될 수 있습니다.
  • 읽기 성능 저하: 데이터를 읽어올 때 여러 테이블을 JOIN해야 하는 경우, 읽기 성능이 저하될 수 있습니다.
  • 과도한 정규화 문제: 과도하게 정규화된 경우, 지나치게 많은 테이블로 쪼개어져 관리가 어려워질 수 있습니다.

5. 결론

정규화는 관계형 데이터베이스에서 데이터 중복을 최소화하고 일관성을 유지하는 데 매우 중요한 설계 기법입니다. 하지만 지나치게 정규화하면 쿼리 성능이 저하될 수 있으므로, 정규화와 비정규화를 적절히 혼합하여 성능과 무결성 사이에서 균형을 맞추는 것이 중요합니다.

21. Primary Key, Foreign Key에 대해 설명해주세요.

더보기

**Primary Key(기본 키)**와 **Foreign Key(외래 키)**는 데이터베이스에서 테이블 간의 관계를 정의하고 데이터 무결성을 유지하는 데 중요한 역할을 하는 키입니다.

1. Primary Key (기본 키)

Primary Key는 테이블에서 각 행을 고유하게 식별하는 유일한 속성입니다. 기본 키는 한 테이블에서 중복되지 않으며, NULL 값을 가질 수 없습니다. 즉, 테이블 내에서 각 행을 고유하게 구분할 수 있는 값입니다.

특징

  • 유일성: 테이블 내의 모든 행이 고유한 값을 가져야 합니다. 중복된 값이 존재할 수 없습니다.
  • NOT NULL: 기본 키는 NULL 값을 가질 수 없습니다. 즉, 반드시 값이 있어야 합니다.
  • 단일 컬럼 또는 다중 컬럼 가능: 기본 키는 하나의 열(단일 속성)으로도 설정할 수 있고, 여러 열(다중 속성)으로도 설정할 수 있습니다. 다중 컬럼으로 설정할 경우 이를 **복합 키(Composite Key)**라고 합니다.

예시

StudentIDNameAge

1 Alice 20
2 Bob 22
3 Carol 21

위 테이블에서 StudentID가 Primary Key로 설정된다면, 각 학생을 고유하게 식별할 수 있으며 StudentID 값이 중복되거나 NULL이 될 수 없습니다.

기능

  • 테이블에서 행을 고유하게 식별하는 데 사용됩니다.
  • 검색, 업데이트, 삭제 등의 작업을 효율적으로 수행할 수 있게 도와줍니다.

2. Foreign Key (외래 키)

Foreign Key는 한 테이블의 열이 다른 테이블의 Primary Key를 참조하는 키입니다. 외래 키는 테이블 간의 관계를 나타내며, 두 테이블 간에 참조 무결성을 유지하는 역할을 합니다. 외래 키는 다른 테이블의 기본 키 값을 참조하는 경우가 많습니다.

특징

  • 참조 관계: 외래 키는 한 테이블의 열이 다른 테이블의 기본 키를 참조하여 테이블 간의 관계를 형성합니다.
  • 참조 무결성: 외래 키로 설정된 열의 값은 반드시 참조하는 테이블의 기본 키 값 중 하나여야 합니다. 즉, 외래 키 값은 NULL이거나 참조하는 테이블에 존재하는 값이어야 합니다.
  • 다중 외래 키: 한 테이블에는 여러 개의 외래 키가 있을 수 있으며, 이를 통해 여러 테이블과 관계를 맺을 수 있습니다.

예시

OrderIDStudentIDProductQuantity

1001 1 Notebook 2
1002 2 Pencil 5
1003 1 Backpack 1

위 테이블에서 StudentID는 Foreign Key로 설정되어 있으며, 이는 학생 테이블의 StudentID(Primary Key)를 참조합니다. 즉, Order 테이블에서 StudentID는 반드시 Student 테이블에 존재하는 값이어야 하며, 해당 값은 다른 테이블의 기본 키로 설정된 값입니다.

기능

  • 테이블 간의 관계를 정의하여 참조 무결성을 유지합니다.
  • 데이터베이스에서 일대다, 다대다 등의 관계를 모델링하는 데 사용됩니다.

3. Primary Key와 Foreign Key의 차이점

항목Primary Key (기본 키)Foreign Key (외래 키)

역할 테이블의 각 행을 고유하게 식별함 다른 테이블의 기본 키를 참조하여 테이블 간의 관계를 정의
값의 고유성 반드시 고유해야 하며 중복될 수 없음 고유하지 않아도 됨, 참조하는 테이블의 값 중 하나여야 함
NULL 허용 여부 NULL 값을 허용하지 않음 NULL 값을 허용할 수 있음 (외래 키 참조가 없는 경우)
테이블 내 위치 한 테이블에 하나만 존재 가능 한 테이블에 여러 개 존재할 수 있음
주요 목적 데이터를 고유하게 식별하는 데 사용 테이블 간의 관계를 정의하고 참조 무결성을 유지

4. Primary Key와 Foreign Key의 관계

Primary Key와 Foreign Key는 관계형 데이터베이스에서 중요한 역할을 합니다. Primary Key는 각 테이블의 행을 고유하게 식별하는 데 사용되고, Foreign Key는 테이블 간의 관계를 정의하여 참조 무결성을 유지합니다.

예를 들어, 학생 테이블의 StudentID가 Primary Key이고, 주문 테이블에서 StudentID가 Foreign Key로 사용되면, 주문 테이블에서 특정 학생이 주문한 내역을 참조할 수 있습니다. 이런 방식으로 두 테이블 간의 관계가 형성되며, 이는 데이터의 무결성과 관계형 구조를 유지하는 데 핵심적인 역할을 합니다.

22. HTTP 메서드에 대해 설명해주세요

더보기

HTTP 메서드 : 클라이언트가 서버에 요청을 보낼 때 사용하는 다양한 작업을 정의하는 방법

1. GET

  • 목적: 서버에서 리소스를 조회할 때 사용됩니다.
  • 특징:
    • 데이터를 가져오기 위한 요청으로, 서버의 상태나 데이터를 변경하지 않습니다.
    • URL에 쿼리 파라미터를 붙여 요청할 수 있습니다.
    • 캐싱이 가능하며, 브라우저에서 뒤로 가기나 새로고침을 할 때 다시 요청할 수 있습니다.
  • 예시:
    http
    코드 복사
    GET /users?id=1 HTTP/1.1 Host: www.example.com

2. POST

  • 목적: 서버에 데이터를 전송하여 리소스를 생성하거나 업데이트할 때 사용됩니다.
  • 특징:
    • 서버의 상태나 리소스에 변화를 일으킵니다.
    • 데이터는 요청 본문에 담겨 서버로 전달됩니다.
    • GET과 달리, 대량의 데이터를 전송할 수 있으며 보안 측면에서도 더 안전합니다.
  • 예시:
    http
    코드 복사
    POST /users HTTP/1.1 Host: www.example.com Content-Type: application/json { "name": "John Doe", "email": "john@example.com" }

3. PUT

  • 목적: 서버에 리소스를 생성하거나 해당 리소스가 이미 있으면 업데이트할 때 사용됩니다.
  • 특징:
    • 요청에서 지정한 리소스를 해당 리소스의 상태에 맞춰 새롭게 저장합니다.
    • 주로 특정 리소스의 전체 데이터를 교체하는 데 사용됩니다.
  • 예시:
    http
    코드 복사
    PUT /users/1 HTTP/1.1 Host: www.example.com Content-Type: application/json { "name": "Jane Doe", "email": "jane@example.com" }

4. PATCH

  • 목적: 리소스의 부분적인 업데이트를 수행할 때 사용됩니다.
  • 특징:
    • PUT과 달리 전체 리소스를 수정하지 않고 일부 필드만 수정할 수 있습니다.
  • 예시:
    http
    코드 복사
    PATCH /users/1 HTTP/1.1 Host: www.example.com Content-Type: application/json { "email": "newemail@example.com" }

5. DELETE

  • 목적: 서버에서 리소스를 삭제할 때 사용됩니다.
  • 특징:
    • 요청된 리소스를 서버에서 삭제하는 작업을 수행합니다.
    • GET처럼 안전하지 않으며 서버 상태를 변경합니다.
  • 예시:
    http
    코드 복사
    DELETE /users/1 HTTP/1.1 Host: www.example.com

6. HEAD

  • 목적: GET과 유사하지만, 응답 본문을 제외하고 상태와 헤더만 요청할 때 사용됩니다.
  • 특징:
    • 리소스의 상태나 메타데이터를 확인하는 데 사용됩니다.
    • 응답 본문은 없지만, 상태 코드와 헤더는 GET 요청과 동일합니다.
  • 예시:
    http
    코드 복사
    HEAD /users/1 HTTP/1.1 Host: www.example.com

7. OPTIONS

  • 목적: 서버가 지원하는 HTTP 메서드를 확인할 때 사용됩니다.
  • 특징:
    • 특정 리소스에 대해 서버가 어떤 메서드를 지원하는지 확인하는 데 유용합니다.
    • 서버는 Allow 헤더에 지원하는 메서드 목록을 응답으로 보냅니다.
  • 예시:
    http
    코드 복사
    OPTIONS /users/1 HTTP/1.1 Host: www.example.com

8. CONNECT

  • 목적: 터널을 설정하여 주로 프록시 서버와의 통신에서 SSL(HTTPS) 연결을 설정할 때 사용됩니다.
  • 특징:
    • 클라이언트가 프록시 서버를 통해 터널링하여 서버와 안전한 통신을 할 수 있도록 합니다.
  • 예시:
    http
    코드 복사
    CONNECT www.example.com:443 HTTP/1.1 Host: www.example.com

9. TRACE

  • 목적: 서버로 가는 경로를 추적할 때 사용됩니다.
  • 특징:
    • 서버로 향하는 요청이 중간에서 어떻게 변경되는지 디버깅할 때 유용합니다.
    • 서버는 요청을 그대로 응답으로 반환합니다.
  • 예시:
    http
    코드 복사
    TRACE / HTTP/1.1 Host: www.example.com

요약

  • GET: 리소스 조회.
  • POST: 리소스 생성.
  • PUT: 리소스 전체 업데이트.
  • PATCH: 리소스 부분 업데이트.
  • DELETE: 리소스 삭제.
  • HEAD: 리소스의 메타데이터 확인.
  • OPTIONS: 서버에서 지원하는 메서드 확인.
  • CONNECT: SSL 터널링 설정.
  • TRACE: 경로 추적.

23. CORS(Cross Origin Resource Sharing)에 대해 설명해주세요

더보기

CORS(Cross-Origin Resource Sharing)는 웹 브라우저에서 보안상의 이유로 **다른 출처(origin)**에서 리소스를 요청할 때 적용되는 보안 정책입니다. 기본적으로 웹 브라우저는 동일 출처 정책(Same-Origin Policy)을 적용하여, 다른 도메인, 포트 또는 프로토콜에서 리소스를 요청하는 것을 제한합니다. CORS는 이러한 제약을 완화해 주는 HTTP 헤더 기반의 보안 메커니즘입니다.

1. 동일 출처 정책(Same-Origin Policy)

  • 동일 출처 정책이란, 웹 페이지가 자신과 동일한 출처에서만 리소스를 요청하거나 자바스크립트를 실행할 수 있게 하는 보안 규칙입니다.
  • **출처(Origin)**은 프로토콜(http, https), 도메인(www.example.com), 포트(80, 443)를 조합하여 결정됩니다.
  • 예를 들어, http://example.com http://api.example.com은 서로 다른 출처입니다.
  • 이 정책이 없으면 악성 웹사이트가 사용자의 브라우저를 통해 다른 사이트의 민감한 정보를 요청할 수 있게 되어 보안에 큰 위협이 됩니다.

2. CORS의 필요성

  • 동일 출처 정책은 보안을 강화하지만, 현실에서는 다양한 출처 간의 리소스 요청이 빈번하게 발생합니다. 예를 들어:
    • 자바스크립트 코드가 https://api.example.com에서 데이터를 가져와야 할 때.
    • 제3자 API를 통해 외부 리소스에 접근해야 할 때.
  • 이런 상황에서 CORS는 서버 측에서 특정 출처에 대해 리소스 접근을 허용하도록 하여 제약을 완화해 줍니다.

3. CORS 동작 방식

CORS는 HTTP 요청과 응답에 포함되는 헤더를 통해 작동합니다. 기본적인 요청 흐름은 다음과 같습니다:

  1. 브라우저가 CORS 요청을 보냄:
    • 클라이언트(브라우저)가 특정 리소스를 요청할 때, 요청 헤더에 Origin을 포함하여 자신의 출처를 명시합니다.
  2. 서버가 CORS를 허용하는지 응답:
    • 서버는 응답할 때 Access-Control-Allow-Origin 헤더를 포함하여 어떤 출처에서 요청을 허용할지 명시합니다.
    • 브라우저는 서버 응답을 보고 요청한 리소스에 접근할 수 있는지 결정합니다.

4. CORS 요청 유형

CORS 요청은 크게 두 가지로 나눌 수 있습니다: **단순 요청(Simple Request)**과 프리플라이트 요청(Preflight Request).

4.1. 단순 요청(Simple Request)

  • CORS 정책에 따라, 브라우저는 특정 조건을 만족하는 요청을 단순 요청으로 처리합니다.
  • 조건:
    • GET, POST, HEAD 메서드만 사용.
    • 요청 헤더에 Accept, Content-Type, Origin과 같은 기본적인 헤더만 포함.
    • Content-Type은 text/plain, multipart/form-data, application/x-www-form-urlencoded 중 하나여야 함.
  • 동작:
    • 브라우저가 리소스를 요청하고, 서버가 Access-Control-Allow-Origin 헤더를 응답에 포함하면 요청이 성공합니다.
    • 예시 응답:
      http
      코드 복사
      HTTP/1.1 200 OK Access-Control-Allow-Origin: https://example.com

4.2. 프리플라이트 요청(Preflight Request)

  • 프리플라이트 요청은 안전하지 않은 HTTP 메서드(PUT, DELETE, PATCH) 또는 특정한 헤더가 포함된 요청을 보내기 전에, 브라우저가 먼저 서버에 이 요청을 해도 되는지 미리 확인하는 절차입니다.
  • 브라우저는 OPTIONS 메서드를 사용해 서버에 "이런 조건의 요청을 보내도 될까요?"라고 물어봅니다.
  • 서버는 응답으로 허용된 메서드, 헤더, 출처 정보를 포함하여 허용 여부를 응답합니다.
  • 프리플라이트 요청 예시:
    1. 클라이언트가 프리플라이트 요청을 보냅니다:
    http
    코드 복사
    OPTIONS /api/data HTTP/1.1 Origin: https://example.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Content-Type
    1. 서버가 응답합니다:
    http
    코드 복사
    HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type

5. CORS 관련 주요 HTTP 헤더

  • Origin: 클라이언트가 요청을 보낼 때 자신의 출처를 명시하는 헤더입니다.
  • Access-Control-Allow-Origin: 서버가 응답할 때 특정 출처의 요청을 허용하는 헤더입니다. 와일드카드(*)로 모든 출처를 허용할 수도 있습니다.
  • Access-Control-Allow-Methods: 서버가 허용하는 HTTP 메서드를 명시합니다. (GET, POST, PUT 등)
  • Access-Control-Allow-Headers: 클라이언트가 보낼 수 있는 허용된 헤더 목록을 명시합니다.
  • Access-Control-Allow-Credentials: 자격 증명(쿠키, 인증 정보)을 포함한 요청을 허용할지 여부를 결정합니다.
  • Access-Control-Max-Age: 프리플라이트 요청에 대한 응답을 브라우저가 캐시할 시간을 설정합니다.

6. CORS의 예시

클라이언트 요청

http
코드 복사
GET /api/data HTTP/1.1 Host: api.example.com Origin: https://example.com

서버 응답

http
코드 복사
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://example.com Content-Type: application/json { "data": "example data" }

7. CORS 오류 발생 시 상황

  • 서버가 Access-Control-Allow-Origin 헤더를 포함하지 않거나 클라이언트의 출처를 허용하지 않으면, 브라우저는 요청을 차단하고 CORS 오류를 발생시킵니다. 이러한 오류는 개발자 도구의 콘솔에서 확인할 수 있습니다.

8. CORS의 적용 대상

  • 웹 브라우저: CORS는 브라우저 차원의 보안 메커니즘이므로, 브라우저가 아닌 서버 간의 통신(API 서버끼리의 통신 등)에는 적용되지 않습니다.
  • 서버 측 설정: 서버는 해당 헤더를 설정하여 특정 출처의 요청을 허용하거나 거부할 수 있습니다. 이를 통해 클라이언트에서 허용된 리소스만 접근할 수 있도록 제어할 수 있습니다.

요약

CORS는 브라우저가 보안 상 다른 출처의 리소스에 접근하는 것을 제한하는 동일 출처 정책을 완화하여, 특정 조건하에 다른 출처에서의 요청을 허용하는 메커니즘입니다. 서버에서 CORS 관련 헤더를 설정하여 제어할 수 있으며, 이를 통해 안전한 방식으로 외부 리소스와 상호작용이 가능해집니다.

 

24. 브라우저의 작동 방식에 대해서 설명해주세요.

더보기

브라우저는 사용자가 웹 페이지를 요청하고 이를 화면에 표시하는 복잡한 과정을 수행하는 소프트웨어입니다. 이 과정은 여러 단계로 나뉘며, 주요 요소에는 사용자의 요청 처리, HTML, CSS, JavaScript 파일의 해석과 렌더링, 화면에 웹 페이지를 표시하는 것 등이 포함됩니다. 브라우저의 작동 방식은 다음과 같습니다.

1. URL 입력 및 요청

  • 사용자가 브라우저의 주소창에 URL을 입력하거나 링크를 클릭하면, 브라우저는 그 URL을 해석하여 HTTP 또는 HTTPS 요청을 서버로 보냅니다.
  • 이 요청에는 웹 페이지를 요청하는 정보뿐만 아니라, 브라우저와 관련된 여러 메타데이터(쿠키, 사용자 에이전트 정보 등)가 포함됩니다.
  • DNS를 통해 도메인 이름을 서버 IP 주소로 변환하고, 해당 IP 주소로 접속하여 요청을 보냅니다.

2. 서버 응답

  • 서버는 요청된 URL에 해당하는 HTML 파일을 브라우저에 응답으로 보냅니다.
  • 웹 페이지가 복잡할 경우, HTML 파일 내에는 CSS, JavaScript 파일, 이미지 파일 등의 추가적인 리소스 파일에 대한 링크도 포함됩니다.
  • 서버는 상태 코드(예: 200 OK, 404 Not Found 등)를 함께 보내 브라우저에 응답 상태를 알립니다.

3. HTML 파싱 및 DOM 트리 생성

  • 브라우저는 서버로부터 받은 HTML 파일을 **파싱(Parsing)**하여 DOM(Document Object Model) 트리를 생성합니다.
    • HTML 파일은 문서의 구조를 나타내는 마크업 언어이며, 브라우저는 이 구조를 해석하여 각 요소(태그)를 DOM 노드로 변환합니다.
    • DOM은 HTML 문서의 계층적 구조를 나타내는 객체 모델로, 페이지의 각 요소가 트리 구조로 표현됩니다.

4. CSS 파싱 및 CSSOM 트리 생성

  • 브라우저는 HTML 문서 내의 CSS 파일이나 <style> 태그를 찾아 CSS를 파싱합니다.
  • CSS 파일을 파싱하면 CSSOM(CSS Object Model) 트리를 생성합니다.
    • CSSOM은 각 HTML 요소에 적용될 스타일 정보를 담고 있으며, DOM 트리와 함께 웹 페이지의 최종 레이아웃을 결정하는데 사용됩니다.

5. JavaScript 실행 및 DOM 조작

  • HTML 문서에 포함된 JavaScript는 브라우저의 JavaScript 엔진에 의해 해석되고 실행됩니다.
  • 브라우저는 JavaScript 코드가 DOM과 CSSOM을 조작하거나 변경할 수 있도록 합니다.
    • 예를 들어, 사용자가 버튼을 클릭하면 JavaScript가 DOM 트리에서 해당 요소를 변경하거나 스타일을 적용할 수 있습니다.
  • 브라우저는 JavaScript 파일을 네트워크 요청으로 가져오거나 <script> 태그로 인라인 JavaScript 코드를 실행합니다.

주의: JavaScript는 웹 페이지가 인터랙티브하게 동작하는데 필수적입니다. 일반적으로 **비동기 처리(Asynchronous JavaScript)**를 통해 HTML과 CSS 파싱이 중단되지 않도록 합니다. defer, async 속성을 사용해 스크립트가 페이지 로딩을 방해하지 않도록 최적화할 수 있습니다.

6. 렌더 트리 생성

  • 브라우저는 DOM과 CSSOM을 결합하여 **렌더 트리(Render Tree)**를 생성합니다.
    • 렌더 트리는 화면에 표시되어야 할 요소들만 포함하고, 이 요소들의 크기와 위치 정보를 담고 있습니다.
    • 예를 들어, display: none 속성이 적용된 요소는 렌더 트리에 포함되지 않습니다.

7. 레이아웃 단계

  • 렌더 트리가 생성된 후, 브라우저는 각 요소가 화면에서 어디에 위치해야 하고, 얼마나 큰지 계산하는 레이아웃(Layout) 과정을 수행합니다.
  • 이 과정에서 브라우저는 화면 크기와 같은 정보들을 바탕으로 요소들의 너비, 높이, 위치를 계산합니다.

8. 페인팅(Painting)

  • 레이아웃이 완료되면, 브라우저는 각 요소를 화면에 그리는 페인팅(Painting) 작업을 진행합니다.
  • 각 렌더 트리 노드를 픽셀 단위로 변환하여 화면에 그리기 위해 GPU를 사용하여 레이어(Layer) 단위로 나누어 처리할 수 있습니다.

9. 컴포지팅(Compositing)

  • 페인팅된 결과물은 여러 레이어로 나뉘어질 수 있으며, 브라우저는 이 레이어들을 조합하여 최종적으로 화면에 표시합니다.
  • 이 과정은 **컴포지팅(Compositing)**이라고 불리며, 브라우저가 각 레이어를 올바른 순서로 배치하여 웹 페이지를 화면에 완성합니다.

10. 재렌더링(Reflow)과 리페인트(Repaint)

  • 페이지가 로드된 이후에도 사용자의 입력이나 JavaScript로 인해 DOM이 변경될 수 있습니다.
  • DOM이나 스타일이 변경되면 브라우저는 Reflow(레이아웃 다시 계산) 또는 **Repaint(화면 다시 그리기)**를 수행해야 합니다.
  • 이 작업이 빈번하게 발생하면 성능에 영향을 미칠 수 있으므로, 최적화가 중요합니다.

11. 캐시 활용

  • 브라우저는 네트워크 성능을 최적화하기 위해 리소스(HTML, CSS, JS, 이미지 등)를 **캐시(Cache)**에 저장합니다.
  • 캐시된 리소스를 활용하면 동일한 웹 페이지를 다시 로드할 때 서버로부터 다시 리소스를 요청하지 않고 빠르게 로드할 수 있습니다.

12. 보안 검사

  • CORS(Cross-Origin Resource Sharing) 정책, SSL 인증서 확인, Content Security Policy(CSP) 등 여러 보안 메커니즘을 통해 브라우저는 사용자 정보를 보호하고 웹 페이지를 안전하게 로드할 수 있도록 합니다.

브라우저의 주요 구성 요소

  1. 사용자 인터페이스: 주소 표시줄, 북마크, 뒤로/앞으로 가기 버튼과 같은 사용자가 상호작용하는 UI 요소.
  2. 렌더링 엔진: HTML과 CSS를 파싱하여 DOM, CSSOM, 렌더 트리를 생성하고, 웹 페이지를 화면에 그리는 역할을 합니다. (예: 크롬의 Blink 엔진, 파이어폭스의 Gecko 엔진)
  3. JavaScript 엔진: JavaScript 코드를 해석하고 실행합니다. (예: 크롬의 V8 엔진)
  4. 네트워킹: HTTP/HTTPS 요청

을 통해 서버와 데이터를 주고받는 모듈입니다. 브라우저는 서버와의 통신을 관리하고, 페이지를 렌더링하기 위해 필요한 리소스를 로드합니다.

  1. UI 백엔드: 버튼, 입력 필드 등 기본적인 UI 요소를 화면에 그리는 역할을 합니다. 플랫폼에 따라 시스템 인터페이스를 사용합니다.
  2. 데이터 저장소: 쿠키, 로컬 스토리지, 세션 스토리지, 인덱스드 DB 등의 방식으로 데이터를 클라이언트 측에 저장하는 모듈입니다.

브라우저 작동 방식 요약

  1. URL 입력 → 요청
  2. 서버 응답 → HTML, CSS, JS 로드
  3. HTML, CSS 파싱 → DOM, CSSOM 트리 생성
  4. JavaScript 실행
  5. 렌더 트리 생성 → 레이아웃, 페인팅 → 화면에 표시
  6. 캐싱 및 보안 검사

브라우저는 이 과정을 거쳐 웹 페이지를 사용자에게 빠르고 안전하게 보여줍니다.

https://velog.io/@wlwl99/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EA%B5%AC%EC%A1%B0

25. 쿠키  /  세션의 차이점 설명

더보기

쿠키

  1. 웹 브라우저에 저장되는 데이터 조각
  2. 쿠키는 유효시간을 설정 할 수 있음 (유효시간 없으면 브라우저를 닫을 때 삭제)
  3. CSRF와 같은 session hijacking 공격에 쿠키가 탈취 될 수 있으므로 보안에 취약함

세션 

  1. 서버에 저장되는 사용자 정보
  2. 세션 ID를 쿠키 또는 URL을 통해 전달 받아 세션을 참고
  3. 서버가 종료되거나 일정시간이 지나면 만료
  4. CSRF와 같은 session hijacking 공격에 쿠키가 탈취 될 수 있으므로 보안에 취약함

쿠키와 세션의 차이점

구분 쿠키 세션
저장 위치 클라이언트(브라우저) 서버
만료 시간 유효 기간 설정 가능 브라우저 종료 또는 시간 만료 시
보안성 상대적으로 낮음 (클라이언트에 저장) 상대적으로 높음 (서버에 저장)
데이터 용량 최대 4KB 정도 서버 메모리에 의존
사용 용도 로그인 유지, 사용자 설정 저장 로그인 상태 유지, 사용자 정보 관리
서버 부담 낮음 (클라이언트가 데이터 저장) 높음 (서버가 세션 관리)

26. TCP/ UDP에 대해서 설명해주세요.

더보기

TCP 

  1. 연결 지향형 프롵초콜
  2. 신뢰성 보장
  3. 흐름제어 및 혼잡 제어
  4. 웹 브라우징, 이메일, 파일전송

UDP 

  1. 비연결성 프로토콜
  2. 신뢰성 보장 X
  3. 오버헤드가 적음
  4. 스트리밍, 온라인 서비스 등 실시간 서비스

TCP와 UDP의 차이점 요약

구분 TCP UDP
연결 방식 연결 지향형 (3-way 핸드셰이크) 비연결형 (연결 설정 없음)
신뢰성 신뢰성 보장 (재전송, 순서 보장) 신뢰성 보장 없음
속도 상대적으로 느림 빠름
오버헤드 크고 복잡 작고 간단
용도 신뢰성이 중요한 서비스 실시간성이 중요한 서비스

27. http, https 차이점에 대해 설명해주세요

더보기

1. HTTP (HyperText Transfer Protocol)

  • 개념: HTTP는 웹 브라우저와 웹 서버 간에 데이터를 주고받기 위한 기본 통신 프로토콜입니다. 주로 웹 페이지나 이미지, 동영상 등의 리소스를 전송하는 데 사용됩니다.
  • 보안성: HTTP는 데이터를 평문(암호화되지 않은 상태)으로 전송하기 때문에, 중간에 제3자가 통신을 가로채면 내용을 쉽게 읽거나 조작할 수 있습니다. 이는 특히 로그인 정보나 금융 정보를 주고받을 때 심각한 보안 문제가 될 수 있습니다.
  • 포트 번호: 기본적으로 80번 포트를 사용합니다.

2. HTTPS (HyperText Transfer Protocol Secure)

  • 개념: HTTPS는 HTTP에 SSL(Secure Sockets Layer) 또는 TLS(Transport Layer Security) 프로토콜을 추가하여 보안을 강화한 프로토콜입니다. 웹 브라우저와 서버 간의 데이터 전송을 암호화하여 기밀성을 보장합니다.
  • 보안성: HTTPS는 데이터를 암호화하여 전송하므로, 제3자가 통신을 가로채더라도 내용을 해독할 수 없습니다. 이로 인해 HTTPS는 금융 거래, 로그인 등 보안이 중요한 웹사이트에서 주로 사용됩니다.
    • SSL/TLS: HTTPS는 SSL 또는 그 후속 기술인 TLS를 사용하여 데이터를 암호화합니다. 이를 통해 클라이언트와 서버 간의 데이터를 보호하고, 인증서를 통해 서버가 신뢰할 수 있는 기관인지 확인합니다.
  • 포트 번호: 기본적으로 443번 포트를 사용합니다.

3. HTTP와 HTTPS의 차이점

구분 HTTP HTTPS
보안성 평문으로 데이터 전송 (암호화 없음) SSL/TLS로 데이터 암호화
포트 번호 80번 포트 사용 443번 포트 사용
인증서 인증서 사용 안 함 SSL/TLS 인증서 필요
속도 상대적으로 빠름 암호화/복호화로 인해 약간 느림
주요 사용처 보안이 필요하지 않은 웹사이트 로그인, 금융, 전자상거래 등 보안 중요 웹사이트

4. HTTPS의 주요 장점

  • 데이터 암호화: HTTPS는 데이터가 서버와 클라이언트 간에 주고받을 때 암호화되므로, 제3자가 데이터를 도청하거나 중간에서 탈취하더라도 내용을 확인할 수 없습니다.
  • 데이터 무결성: 데이터가 전송되는 도중에 제3자가 수정하거나 변조할 수 없도록 보장합니다.
  • 인증: 서버가 SSL/TLS 인증서를 통해 신뢰할 수 있는 서버임을 보장받습니다. 이는 사용자가 의심스러운 사이트에 접속하는 것을 방지하는 역할을 합니다.

 

28. 객체 지향 프로그래밍이란 무엇이고 어떻게 활용할 수 있나요?

더보기

**객체 지향 프로그래밍(Object-Oriented Programming, OOP)**은 **객체(Object)**를 중심으로 프로그램을 설계하고 개발하는 프로그래밍 패러다임입니다. 객체 지향 프로그래밍은 현실 세계의 사물을 모델링하여 객체로 표현하고, 이 객체들이 상호작용하며 동작하는 방식으로 소프트웨어를 구성합니다.

 

1. 캡슐화

2. 상속 

3. 다형성

4. 추상화

 

객체 지향 설계 원칙(SOLID)

객체 지향 프로그래밍에서 좋은 설계를 위해 자주 언급되는 원칙으로 SOLID 원칙이 있습니다. 이 원칙은 객체 지향 설계를 개선하고, 유지보수성을 높이는 데 도움이 됩니다.

  1. 단일 책임 원칙(Single Responsibility Principle, SRP): 클래스는 하나의 책임만 가져야 합니다.
  2. 개방-폐쇄 원칙(Open/Closed Principle, OCP): 클래스는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 합니다.
  3. 리스코프 치환 원칙(Liskov Substitution Principle, LSP): 하위 클래스는 상위 클래스를 대체할 수 있어야 합니다.
  4. 인터페이스 분리 원칙(Interface Segregation Principle, ISP): 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫습니다.
  5. 의존 역전 원칙(Dependency Inversion Principle, DIP): 고수준 모듈은 저수준 모듈에 의존해서는 안 됩니다.

29. 대용량 트래픽 발생 시 어떻게 대응해야 하나요?

더보기

대용량 트래픽이 발생하면 서버의 성능에 영향을 미치고, 응답 시간이 느려지거나 서버 다운 등의 문제가 발생할 수 있습니다. 이를 방지하고 시스템이 안정적으로 동작하도록 하기 위해 다양한 아키텍처기술적 전략을 적용할 수 있습니다. 여기서는 대용량 트래픽 대응 전략을 설명하겠습니다.

1. 로드 밸런싱 (Load Balancing)

로드 밸런싱은 다수의 서버에 트래픽을 균등하게 분배하는 기술입니다. 이를 통해 단일 서버에 집중되는 트래픽을 분산시켜, 성능을 높이고 장애를 방지할 수 있습니다.

  • 수평적 확장(Scale-Out): 서버를 여러 대로 확장하여 트래픽을 분산합니다. 이를 위해 로드 밸런서를 사용하여 여러 서버로 트래픽을 고르게 분배합니다.
  • 로드 밸런서 종류:
    • L4 로드 밸런서: IP와 포트 기반으로 트래픽을 분산합니다.
    • L7 로드 밸런서: HTTP 요청 내용을 기반으로 트래픽을 분산합니다. (URL, 쿠키 등)
    예시:
    • AWS의 Elastic Load Balancer (ELB)
    • NGINX 또는 HAProxy 같은 오픈 소스 로드 밸런서

2. 캐싱(Caching)

캐싱은 자주 요청되는 데이터를 미리 저장해두고, 다음 요청 시 저장된 데이터를 빠르게 제공하는 방식입니다. 캐싱을 통해 데이터베이스나 서버의 부하를 크게 줄일 수 있습니다.

  • 클라이언트 사이드 캐싱: 브라우저 또는 앱에서 자주 사용하는 데이터를 캐싱하여 서버로의 요청을 최소화합니다.
  • CDN(Content Delivery Network): 전 세계에 분산된 서버 네트워크를 통해 정적 콘텐츠(이미지, JS, CSS 파일 등)를 캐싱하여 제공하고, 사용자에게 가까운 서버에서 빠르게 데이터를 전달합니다.
    • 예시: Cloudflare, AWS CloudFront, Akamai
  • 애플리케이션 캐싱: 서버 측에서 자주 사용되는 데이터를 메모리에 저장하여 빠르게 응답하는 방법입니다.
    • RedisMemcached 같은 인메모리 데이터베이스를 사용하여 데이터베이스 조회를 줄이고 성능을 향상시킬 수 있습니다.

3. 데이터베이스 튜닝

대용량 트래픽이 발생할 때, 데이터베이스는 성능 저하의 주요 병목이 될 수 있습니다. 이를 해결하기 위해 데이터베이스 최적화가 필요합니다.

  • 쿼리 최적화: 데이터베이스 쿼리를 분석하고, 필요한 인덱스를 추가하여 성능을 높입니다.
  • 데이터베이스 샤딩(Sharding): 데이터를 여러 개의 데이터베이스로 분할하여 저장하고, 트래픽을 분산시킵니다. 각 샤드에는 데이터의 일부분만 저장되므로, 특정 샤드에만 쿼리가 집중되지 않게 할 수 있습니다.
  • 데이터베이스 수평 확장(Scale-Out): 데이터베이스를 복제하여 읽기 요청(Read)을 여러 데이터베이스에서 처리할 수 있게 합니다. 예를 들어, 마스터-슬레이브 복제 구조에서 쓰기 요청은 마스터 데이터베이스가, 읽기 요청은 슬레이브 데이터베이스가 처리합니다.

4. 비동기 처리 및 메시지 큐

실시간 처리가 필요하지 않은 작업은 비동기 처리로 전환하여 서버 부담을 줄일 수 있습니다. 특히, 대량의 작업이 동시에 들어오는 상황에서 효과적입니다.

  • **메시지 큐(Message Queue)**를 사용하여 작업을 비동기적으로 처리하고, 트래픽의 피크 시간 동안 과부하를 방지합니다.
    • RabbitMQ, Apache Kafka, AWS SQS와 같은 메시지 큐 시스템을 사용하여 비동기 처리를 구현할 수 있습니다.
    예시:
    • 이메일 발송, 로그 저장, 이미지 처리 등의 작업을 비동기 큐에 넣고, 별도의 워커(Worker) 서버가 이를 처리하도록 합니다.

5. 오토 스케일링 (Auto Scaling)

오토 스케일링은 트래픽 변화에 따라 자동으로 서버의 인스턴스를 추가하거나 제거하는 방법입니다. 예를 들어, 트래픽이 급격히 증가할 때는 서버 인스턴스를 자동으로 늘리고, 트래픽이 줄어들면 불필요한 인스턴스를 제거하여 비용을 절감할 수 있습니다.

  • AWS의 EC2 Auto Scaling이나 Google Cloud의 Compute Engine과 같은 서비스를 활용하여 동적으로 서버 인프라를 확장할 수 있습니다.

6. 무상태 아키텍처(Stateless Architecture)

서버는 가능한 한 무상태(stateless)로 설계되어야 합니다. 즉, 서버가 클라이언트의 상태를 유지하지 않고, 각 요청은 독립적으로 처리될 수 있어야 합니다. 이를 통해 서버 간에 요청을 자유롭게 분산할 수 있습니다.

  • 세션 관리는 데이터베이스나 Redis 같은 외부 스토리지에서 처리하고, 각 서버는 상태 정보를 유지하지 않도록 설계합니다.
  • **JWT (JSON Web Token)**와 같은 토큰 기반 인증 방식을 사용하면, 사용자의 세션 상태를 유지하지 않고도 인증 정보를 클라이언트가 저장하고 서버로 전달할 수 있습니다.

7. 트래픽 제어 및 제한 (Rate Limiting)

과도한 트래픽이나 악성 트래픽이 서버에 영향을 주지 않도록 트래픽을 제한할 수 있는 Rate Limiting을 적용할 수 있습니다. Rate Limiting은 사용자가 일정 시간 내에 보낼 수 있는 요청의 수를 제한하는 방법입니다.

  • NGINXAPI Gateway 같은 시스템에서 특정 IP나 클라이언트별로 요청을 제한할 수 있습니다.
  • AWS의 API Gateway는 기본적으로 Rate Limiting을 지원하며, 일정 수의 요청을 초과하면 더 이상 요청을 처리하지 않도록 설정할 수 있습니다.

8. 모니터링 및 알림 시스템

대용량 트래픽을 처리하면서 서버의 상태를 실시간으로 모니터링하는 것이 중요합니다. 문제가 발생하기 전에 서버의 부하, CPU 사용량, 메모리 사용량, 네트워크 트래픽 등을 모니터링하고, 이상 징후가 발견되면 즉시 대응할 수 있도록 합니다.

  • Prometheus, Grafana, Datadog, New Relic과 같은 모니터링 도구를 사용하여 시스템 상태를 모니터링하고, 알림 시스템을 설정하여 실시간으로 대응할 수 있도록 합니다.

9. 데이터베이스 및 애플리케이션 분산

  • 데이터베이스 분산: 데이터베이스를 수평적으로 확장하는 방법으로, 분산 데이터베이스 시스템을 구축하여 대량의 트래픽을 처리할 수 있습니다.
  • 마이크로서비스 아키텍처(Microservices Architecture): 애플리케이션을 작은 서비스 단위로 나누어 각 서비스가 독립적으로 동작할 수 있게 하여 확장성을 높입니다. 이 구조에서는 각 서비스가 독립적으로 배포되고 확장되므로, 트래픽 증가에 더 유연하게 대응할 수 있습니다.

10. 실패 복구 전략(Failover and Redundancy)

대용량 트래픽에 대비하여, 특정 서버나 인스턴스가 장애를 일으킬 경우를 대비한 고가용성(HA) 전략을 마련해야 합니다. 서버 장애 시 자동으로 다른 서버로 트래픽을 넘기는 Failover와 서버를 중복 배치하여 안정성을 높이는 Redundancy를 통해 시스템의 복구력을 강화할 수 있습니다.


대용량 트래픽 대응 요약

  1. 로드 밸런싱으로 트래픽 분산
  2. 캐싱을 통해 서버 및 데이터베이스 부하 감소
  3. 데이터베이스 최적화로 쿼리 성능 개선 및 샤딩/복제 적용
  4. 비동기 처리메시지 큐를 통해 서버 부하 완화
  5. 오토 스케일링으로 서버 자원을 동적으로 확장
  6. 무상태 아키텍처를 통해 서버 간 유연한 트래픽 분산
  7. Rate Limiting으로 악성 트래픽 차단
  8. 모니터링알림 시스템으로 실시간 대응
  9. 마이크로서비스 및 데이터베이스 분산을 통해 확장성 극대화
  10. FailoverRedundancy로 안정성 확보

이러한 대응 방안들을 적절하게 결합하고 적용하여 대용량 트래픽을 효과적으로 관리할 수 있습니다.

30.ORM을 사용하면서 쿼리가 복잡해지는 경우에는 어떻게 해결하는게 좋을까요?

더보기

ORM(Object-Relational Mapping)은 데이터베이스와 객체 지향 프로그래밍 간의 매핑을 제공하여 데이터베이스 작업을 쉽게 할 수 있도록 도와줍니다. 하지만 ORM을 사용하면서 쿼리가 복잡해지면 성능 저하, 가독성 저하, 디버깅 어려움 등의 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위한 몇 가지 방법을 소개하겠습니다.

1. 쿼리 최적화

  • Eager Loading vs. Lazy Loading: ORM에서 데이터를 가져오는 방법으로 Eager Loading(사전 로딩)과 Lazy Loading(지연 로딩)이 있습니다. 쿼리가 복잡해지는 이유 중 하나는 관련 데이터를 불필요하게 여러 번 조회하는 것입니다. 필요한 데이터를 한 번에 가져오도록 Eager Loading을 사용하는 것이 좋습니다.

2. Native Query 사용

ORM에서 제공하는 쿼리 생성 기능이 복잡한 쿼리를 처리하기에 부족할 경우, 직접 SQL 쿼리를 작성하는 Native Query를 사용하는 방법이 있습니다. 이를 통해 복잡한 조인이나 조건 등을 효율적으로 처리할 수 있습니다.

 

3. DTO(Data Transfer Object) 사용

ORM은 엔티티(Entity) 객체를 매핑하는데 중점을 두기 때문에, 복잡한 데이터 구조를 반환할 때는 DTO를 사용하여 쿼리 결과를 보다 명확하게 전달할 수 있습니다. DTO는 필요한 필드만 포함하므로, 데이터 전송 시 효율적입니다.

 

4. 쿼리 분리

복잡한 쿼리를 여러 개의 단순한 쿼리로 분리하여 처리하는 방법입니다. 여러 단계를 거쳐 필요한 데이터를 점진적으로 수집하는 방식으로 성능을 개선할 수 있습니다. 이는 각 단계에서 데이터를 필터링하고 가공하는 데 유리합니다.

5. 성능 분석 및 모니터링

ORM에서 실행되는 쿼리를 모니터링하고 성능을 분석하여 병목 현상을 찾아내는 것이 중요합니다. SQL 실행 계획을 확인하거나, 쿼리 로그를 통해 어떤 쿼리가 성능을 저하시키는지 파악하고 최적화합니다.

  • Hibernate Statistics: Hibernate에서는 쿼리 성능을 모니터링할 수 있는 기능을 제공합니다.

6. 캐싱 활용

ORM의 캐시 기능을 활용하여 데이터베이스 쿼리 횟수를 줄일 수 있습니다. Hibernate와 같은 ORM에서는 1차 캐시(세션 내 캐시)와 2차 캐시(다수의 세션 간 공유 캐시)를 지원합니다.

 

7. 쿼리 최적화 도구 사용

복잡한 쿼리를 작성하거나 최적화하는 데 도움을 주는 도구를 활용합니다. 예를 들어, Hibernate Query Language (HQL), JPQL과 같은 ORM 전용 쿼리 언어를 사용하여 쿼리를 단순화할 수 있습니다.

8. 사용자 정의 쿼리 메서드

복잡한 쿼리가 자주 사용된다면, 이를 사용자 정의 메서드로 만들어 재사용할 수 있습니다. 이를 통해 코드의 중복을 줄이고, 유지보수성을 높일 수 있습니다.

9. 최신 ORM 프레임워크 활용

최신 ORM 프레임워크는 더욱 발전된 기능을 제공하므로, 기존 ORM의 한계를 느끼면 다른 프레임워크로의 전환을 고려할 수 있습니다. 예를 들어, JOOQ와 같은 프레임워크는 SQL 쿼리를 더욱 유연하고 직관적으로 작성할 수 있게 도와줍니다.

31. GET, POST의 개념과 함께 데이터 흐름에 대해서 설명해주세요.

더보기

GET과 POST는 HTTP 프로토콜에서 클라이언트와 서버 간의 데이터 전송을 위한 두 가지 주요 메서드입니다. 각각의 메서드는 데이터 흐름과 사용 목적이 다르며, 일반적으로 웹 애플리케이션에서 자주 사용됩니다. 아래에서 두 메서드의 개념과 데이터 흐름을 설명하겠습니다.

1. GET 메서드

개념

  • GET 메서드는 서버에서 리소스를 요청할 때 사용됩니다. 클라이언트는 요청 URL에 필요한 데이터를 포함시켜 서버로 요청을 보내며, 서버는 요청된 리소스를 반환합니다.
  • GET 요청은 읽기 전용으로 설계되었으며, 서버의 상태를 변경하지 않아야 합니다.

데이터 흐름

  1. 요청 생성: 클라이언트(예: 웹 브라우저)는 URL을 입력하거나 링크를 클릭하여 GET 요청을 생성합니다. 요청 URL에는 쿼리 문자열(query string)을 포함하여 추가 데이터를 전달할 수 있습니다. 쿼리 문자열은 URL 끝에 ?로 시작하며, key=value 형태로 여러 개의 값을 &로 연결합니다.
  2. 예시:
  3. 요청 전송: 클라이언트는 서버로 GET 요청을 전송합니다.
  4. 서버 처리: 서버는 요청된 리소스를 검색하고, 필요한 데이터베이스 쿼리를 실행하여 결과를 생성합니다.
  5. 응답 반환: 서버는 클라이언트에게 요청된 데이터를 포함한 응답을 반환합니다.
  6. 데이터 표시: 클라이언트는 받은 응답을 사용자에게 표시합니다.

특징

  • 요청한 데이터는 URL에 포함되어 있으므로, 북마크하거나 공유하기 용이합니다.
  • 요청 크기 제한이 있으며, 일반적으로 URL 길이에 제한이 있습니다 (브라우저나 서버에 따라 다름).
  • 보안상의 이유로, 중요한 데이터를 GET 요청에 포함시키지 않는 것이 좋습니다.

2. POST 메서드

개념

  • POST 메서드는 서버에 데이터를 전송할 때 사용됩니다. 클라이언트는 요청 본문(body)에 데이터를 포함시켜 서버로 요청을 보냅니다. 주로 데이터 생성, 업데이트, 또는 서버의 상태를 변경할 때 사용됩니다.

데이터 흐름

  1. 요청 생성: 클라이언트는 웹 폼을 작성하거나 API를 호출하여 POST 요청을 생성합니다. 데이터는 요청 본문에 포함되며, 일반적으로 application/x-www-form-urlencoded 또는 application/json 형식으로 전송됩니다.
  2. 예시:
  3. 요청 전송: 클라이언트는 서버로 POST 요청을 전송합니다.
  4. 서버 처리: 서버는 요청 본문에서 데이터를 추출하고, 필요한 데이터베이스 작업을 수행합니다.
  5. 응답 반환: 서버는 작업 결과를 클라이언트에게 응답으로 반환합니다.
  6. 데이터 표시: 클라이언트는 받은 응답을 사용자에게 표시합니다.

특징

  • 요청 데이터는 본문에 포함되어 있어 URL에 노출되지 않습니다. 따라서 더 많은 데이터(파일 업로드 등)를 전송할 수 있습니다.
  • 데이터 길이에 제한이 없으며, 다양한 형식으로 전송할 수 있습니다.
  • POST 요청은 서버의 상태를 변경할 수 있으므로, 안전하지 않은 요청으로 간주됩니다.

GET vs POST 요약

속성 GET POST
데이터 전송 위치 URL의 쿼리 문자열 요청 본문
사용 목적 데이터 조회, 리소스 요청 데이터 생성, 업데이트, 삭제
보안 데이터가 URL에 노출되어 보안 취약 데이터가 요청 본문에 포함되어 보안 강화
캐시 캐시 가능 일반적으로 캐시되지 않음
요청 크기 제한 있음 (브라우저에 따라 다름) 제한 없음
멱등성 멱등적 (같은 요청 시 같은 결과) 비멱등적 (같은 요청 시 결과가 다를 수 있음)

32. OSI 7계층에 대해 아는대로 설명해주세요.

더보기

OSI(Open Systems Interconnection) 7계층 모델은 네트워크 통신의 표준화된 구조를 정의하여 다양한 시스템 간의 상호 운용성을 가능하게 하는 개념적 모델입니다. 이 모델은 네트워크 통신을 7개의 계층으로 나누어 각 계층의 역할과 기능을 정의합니다. 각 계층은 특정한 기능을 수행하며, 상위 계층은 하위 계층의 서비스를 이용합니다. 아래는 OSI 7계층의 각 계층에 대한 설명입니다.

1. 물리 계층 (Physical Layer)

  • 기능: 데이터 전송을 위한 물리적 매체와 전기적 신호를 정의합니다. 비트의 전송 속도, 전압, 케이블의 특성 등을 다루며, 실제 전송 매체에 관한 사항을 포함합니다.
  • 예시: 이더넷 케이블, 광섬유, USB 포트 등.

2. 데이터 링크 계층 (Data Link Layer)

  • 기능: 물리 계층 위에서 데이터의 오류 검출 및 수정을 수행합니다. 데이터 패킷을 프레임으로 캡슐화하여 전송하며, MAC 주소를 사용하여 장치 간 통신을 관리합니다.
  • 예시: 이더넷(IEEE 802.3), Wi-Fi(IEEE 802.11), PPP(Point-to-Point Protocol).

3. 네트워크 계층 (Network Layer)

  • 기능: 데이터 패킷의 라우팅과 전달을 담당하며, IP 주소를 사용하여 데이터 전송 경로를 결정합니다. 서로 다른 네트워크 간의 통신을 지원합니다.
  • 예시: IP(Internet Protocol), ICMP(Internet Control Message Protocol).

4. 전송 계층 (Transport Layer)

  • 기능: 데이터의 신뢰성 있는 전송을 보장하고, 데이터의 세그먼트화 및 재조합을 관리합니다. 흐름 제어와 오류 검출 기능도 포함되어 있습니다.
  • 예시: TCP(Transmission Control Protocol), UDP(User Datagram Protocol).

5. 세션 계층 (Session Layer)

  • 기능: 통신 세션의 설정, 유지, 종료를 관리합니다. 데이터 전송 중에 세션이 유지되도록 하며, 두 장치 간의 대화를 관리합니다.
  • 예시: API(Application Programming Interface) 호출, RPC(Remote Procedure Call).

6. 표현 계층 (Presentation Layer)

  • 기능: 데이터의 형식 변환, 암호화 및 압축을 담당하여, 데이터가 서로 다른 시스템에서 호환될 수 있도록 합니다. 사용자에게 데이터를 전달하기 전에 최종 형식으로 변환합니다.
  • 예시: JPEG, GIF, SSL(Secure Sockets Layer).

7. 애플리케이션 계층 (Application Layer)

  • 기능: 사용자와 가장 가까운 계층으로, 네트워크 서비스와 애플리케이션 간의 상호 작용을 지원합니다. 이메일, 파일 전송 등 다양한 네트워크 서비스를 제공합니다.
  • 예시: HTTP, FTP, SMTP, DNS.

33. 세션 기반 인증과 토큰 기반 인증의 차이에 대해 설명해주세요.

더보기

1. 세션 기반 인증 (Session-based Authentication)

개념

  • 사용자가 로그인하면 서버는 사용자 정보를 포함하는 세션을 생성합니다.
  • 세션 ID가 클라이언트에 전달되며, 클라이언트는 이후 요청 시 이 세션 ID를 함께 보내어 서버가 사용자를 식별할 수 있도록 합니다.

동작 방식

  1. 사용자 로그인: 사용자가 로그인 정보를 입력하고 제출합니다.
  2. 세션 생성: 서버는 사용자 정보를 기반으로 세션을 생성하고, 세션 ID를 클라이언트에 반환합니다. 이 세션 ID는 쿠키에 저장됩니다.
  3. 후속 요청: 클라이언트는 이후의 요청에서 쿠키에 저장된 세션 ID를 서버로 전송합니다.
  4. 세션 검증: 서버는 세션 ID를 기반으로 세션을 조회하고, 해당 세션에 저장된 사용자 정보를 통해 인증을 수행합니다.

특징

  • 서버 상태 유지: 서버가 세션 상태를 관리하므로 서버 메모리에 세션 정보를 저장합니다.
  • 세션 만료: 세션은 특정 시간(예: 사용자 비활성 시) 후에 만료될 수 있습니다.
  • 상태 저장: 세션 기반 인증은 상태를 저장하는 방식으로, 서버와 클라이언트 간의 상태 정보가 필요합니다.

2. 토큰 기반 인증 (Token-based Authentication)

개념

  • 사용자가 로그인하면 서버가 암호화된 토큰을 생성하여 클라이언트에 반환합니다. 이후 클라이언트는 이 토큰을 사용하여 인증된 요청을 서버에 보냅니다.

동작 방식

  1. 사용자 로그인: 사용자가 로그인 정보를 입력하고 제출합니다.
  2. 토큰 생성: 서버는 사용자를 인증한 후, JSON Web Token(JWT)과 같은 토큰을 생성하여 클라이언트에 반환합니다.
  3. 후속 요청: 클라이언트는 요청 시 HTTP 헤더에 토큰을 포함시켜 서버로 전송합니다.
  4. 토큰 검증: 서버는 수신한 토큰을 검증하고, 유효한 경우 사용자 정보를 기반으로 요청을 처리합니다.

특징

  • 무상태(stateless): 서버는 사용자의 상태를 저장하지 않으며, 클라이언트가 모든 필요한 정보를 포함한 토큰을 보냅니다.
  • 확장성: 서버 간의 확장이 용이하며, 여러 서버에서 동일한 토큰을 사용할 수 있습니다.
  • 보안: 토큰은 암호화되어 있어 서버가 수신한 후 유효성을 확인할 수 있습니다. 또한, 토큰은 만료 시간을 포함하여 안전하게 관리됩니다.

세션 기반 인증 vs. 토큰 기반 인증의 차이

특성세션 기반 인증토큰 기반 인증
상태 유지 서버가 세션 상태를 유지 서버가 상태를 유지하지 않음
세션 저장 위치 서버 메모리에 세션 정보 저장 클라이언트가 토큰을 저장 (예: 로컬 스토리지)
요청 시 인증 정보 쿠키를 통해 세션 ID 전송 HTTP 헤더에 토큰 포함
확장성 여러 서버 간의 세션 공유가 어려움 여러 서버에서 동일한 토큰 사용 가능
보안 CSRF(Cross-Site Request Forgery) 공격에 취약 CORS(Cross-Origin Resource Sharing)와 조합해 보안 강화 가능
만료 처리 세션 만료 후 재로그인이 필요 토큰에 만료 시간을 설정 가능

34. JWT, Refresh, Access Token에 대해서 설명해주세요.

더보기

1. JWT (JSON Web Token)

개념

  • JWT는 JSON 포맷으로 정보를 안전하게 전송하기 위해 사용되는 토큰입니다. 주로 인증 및 정보 교환에 사용되며, 클라이언트와 서버 간의 정보를 안전하게 전달하는 방법으로 활용됩니다.
  • JWT는 세 부분으로 구성되어 있습니다:
    • Header: 토큰의 타입(일반적으로 "JWT")과 사용할 서명 알고리즘(예: HMAC SHA256)을 포함합니다.
    • Payload: 사용자 관련 정보(클레임)를 포함합니다. 클레임은 등록된 클레임(예: sub, iat 등), 공개 클레임, 비공개 클레임이 있을 수 있습니다.
    • Signature: 헤더와 페이로드를 비밀 키로 서명하여 생성합니다. 이 서명을 통해 데이터의 무결성을 검증할 수 있습니다.

특징

  • 자체 포함: JWT는 필요한 사용자 정보를 자체적으로 포함하고 있어, 서버가 세션 상태를 저장할 필요가 없습니다.
  • 무상태: 서버는 상태를 유지하지 않으므로 확장성이 좋습니다.
  • 안전성: 서명으로 무결성을 검증할 수 있으며, 필요한 경우 암호화를 통해 보안을 강화할 수 있습니다.

2. Access Token

개념

  • Access Token은 사용자가 인증된 후에 클라이언트에게 제공되는 토큰으로, 서버에 요청을 할 때 사용됩니다. 이 토큰을 통해 사용자의 권한을 검증하고, 리소스에 접근할 수 있도록 합니다.
  • 보통 JWT 형식으로 발급되며, 서버는 이 토큰을 통해 사용자가 어떤 리소스에 접근할 수 있는지를 판단합니다.

특징

  • 만료 시간: Access Token은 일반적으로 짧은 유효 기간(예: 몇 분 또는 몇 시간)을 가지며, 보안을 위해 자주 갱신해야 합니다.
  • 리소스 접근: API 호출 시 Authorization 헤더에 포함되어 서버로 전송됩니다.

3. Refresh Token

개념

  • Refresh Token은 Access Token의 유효 기간이 만료된 후, 새로운 Access Token을 발급받기 위해 사용되는 토큰입니다. 클라이언트가 Refresh Token을 서버로 전송하면, 서버는 새로운 Access Token을 발급합니다.
  • Refresh Token은 일반적으로 더 긴 유효 기간을 가지며, 자주 사용되지 않습니다.

특징

  • 보안: Refresh Token은 Access Token보다 더 안전하게 관리되어야 하며, 서버의 저장소에 안전하게 저장됩니다.
  • 세션 유지: 사용자가 로그인을 반복하지 않고도 지속적으로 세션을 유지할 수 있도록 도와줍니다.

35. HTTP 상태코드에 대해서 설명해주세요.

더보기

1. 1xx (정보 상태 코드)

  • 100 Continue: 클라이언트가 요청을 계속해도 좋다는 의미입니다. 초기 요청을 받았고, 계속 진행할 수 있습니다.
  • 101 Switching Protocols: 서버가 클라이언트의 프로토콜 변경 요청을 수락하고, 프로토콜을 변경하고 있다는 의미입니다.

2. 2xx (성공 상태 코드)

  • 200 OK: 요청이 성공적으로 처리되었음을 나타냅니다. 일반적으로 요청한 데이터가 포함됩니다.
  • 201 Created: 요청이 성공적으로 처리되어 새로운 리소스가 생성되었음을 나타냅니다. POST 요청 후에 주로 사용됩니다.
  • 204 No Content: 요청은 성공적으로 처리되었지만, 반환할 콘텐츠가 없음을 나타냅니다.

3. 3xx (리다이렉션 상태 코드)

  • 301 Moved Permanently: 요청한 리소스가 영구적으로 다른 URI로 이동했음을 나타냅니다. 클라이언트는 새로운 URI로 요청을 시도해야 합니다.
  • 302 Found: 요청한 리소스가 임시로 다른 URI로 이동했음을 나타냅니다. 클라이언트는 원래 URI를 계속 사용해야 합니다.
  • 304 Not Modified: 클라이언트의 캐시된 버전이 최신임을 나타내며, 서버에서 새로운 콘텐츠가 없음을 의미합니다.

4. 4xx (클라이언트 오류 상태 코드)

  • 400 Bad Request: 서버가 요청을 이해할 수 없음을 나타냅니다. 요청 형식이 잘못되었거나 파라미터가 유효하지 않습니다.
  • 401 Unauthorized: 인증이 필요함을 나타내며, 클라이언트가 유효한 인증 정보를 제공하지 않았습니다.
  • 403 Forbidden: 클라이언트가 요청한 리소스에 대한 접근이 금지되어 있음을 나타냅니다.
  • 404 Not Found: 요청한 리소스를 서버에서 찾을 수 없음을 나타냅니다. URL이 잘못되었거나 리소스가 삭제된 경우에 발생합니다.

5. 5xx (서버 오류 상태 코드)

  • 500 Internal Server Error: 서버에서 예기치 않은 오류가 발생했음을 나타냅니다. 서버의 문제로 요청을 처리할 수 없습니다.
  • 502 Bad Gateway: 서버가 게이트웨이나 프록시로서 다른 서버에서 유효한 응답을 받지 못했음을 나타냅니다.
  • 503 Service Unavailable: 서버가 현재 요청을 처리할 수 없는 상태(예: 과부하 또는 유지 보수 중)임을 나타냅니다.

36. 컴퓨터 네트워크와 서버에 대해 설명해주세요.

더보기

컴퓨터 네트워크

여러 컴퓨터와 장치들을 연결해서 데이터와 자원을 공유 할 수 있도록 하는 시스템

1. 네트워크의 종류

  • LAN(Local Area Network): 특정 건물이나 구역 내의 컴퓨터들을 연결한 네트워크입니다. 집이나 회사 내에서 주로 사용됩니다.
  • WAN(Wide Area Network): 넓은 지역을 연결하는 네트워크로, LAN보다 더 넓은 지역에 걸쳐 있습니다. 예를 들어, 인터넷이 대표적인 WAN입니다.
  • MAN(Metropolitan Area Network): 도시 규모의 네트워크로, 여러 LAN을 연결하여 광범위한 지역 내의 네트워크를 구성합니다.

2. 네트워크 구성 요소

  • 라우터(Router): 서로 다른 네트워크를 연결해주는 장치입니다. 데이터를 목적지까지 전달하기 위해 경로를 설정합니다.
  • 스위치(Switch): 동일 네트워크 내에서 데이터를 전송하는 장치로, 각 장치 간의 데이터 흐름을 관리합니다.
  • 허브(Hub): 네트워크 내 모든 장치에게 데이터를 전달하는 장치지만, 스마트한 데이터 관리 기능이 없습니다.
  • 방화벽(Firewall): 네트워크를 보호하기 위해 외부의 접근을 통제하고, 네트워크 보안을 유지합니다.

3. 프로토콜

네트워크에서는 **프로토콜(Protocol)**이라는 통신 규약을 통해 데이터를 전송합니다. 가장 흔히 사용되는 프로토콜로는 TCP/IP가 있습니다.

  • TCP(Transmission Control Protocol): 데이터 전송이 신뢰성 있게 이루어지도록 연결을 설정하고, 데이터의 순서를 맞추고, 손실된 데이터는 재전송합니다.
  • IP(Internet Protocol): 각 컴퓨터에게 주소(IP 주소)를 부여하여 데이터를 전송할 위치를 지정하는 역할을 합니다.

서버(Server)

서버는 네트워크에서 클라이언트(사용자)의 요청을 처리하고 자원을 제공하는 컴퓨터나 시스템을 의미

1. 서버의 역할

  • 데이터 제공: 웹 서버는 웹사이트의 파일을 제공하고, 데이터베이스 서버는 데이터베이스 요청을 처리합니다.
  • 응용 프로그램 실행: 서버는 클라이언트가 실행하려는 애플리케이션을 관리합니다. 예를 들어, 게임 서버는 다수의 사용자에게 실시간 게임 데이터를 전송합니다.
  • 파일 저장 및 공유: 파일 서버는 여러 사용자가 동시에 파일에 접근하고 공유할 수 있도록 합니다.

2. 서버의 종류

  • 웹 서버: 웹 브라우저의 요청을 받아들이고 웹 페이지를 제공하는 서버입니다. 예: Apache, Nginx
  • 데이터베이스 서버: 데이터베이스 관리 시스템(DBMS)을 통해 데이터베이스의 요청을 처리합니다. 예: MySQL, PostgreSQL
  • 파일 서버: 파일을 저장하고, 사용자나 장치들이 네트워크를 통해 파일에 접근할 수 있도록 관리합니다.
  • 메일 서버: 이메일 송수신을 관리하는 서버로, 클라이언트에게 메일 서비스를 제공합니다. 예: Gmail, Microsoft Exchange

3. 서버 운영 시스템

서버는 운영 체제를 기반으로 운영되며, 주로 Linux 또는 Windows Server와 같은 서버 운영체제를 사용합니다.

  • Linux: 서버 운영에 많이 사용되는 오픈 소스 운영 체제로, 높은 안정성과 성능을 제공합니다.
  • Windows Server: Microsoft의 서버 운영체제로, Active Directory 및 다양한 네트워크 서비스 제공에 유용합니다.

4. 클라우드 서버

최근에는 물리적인 서버 대신 클라우드 서버를 통해 서비스를 제공하는 방식이 증가하고 있습니다. AWS, Google Cloud, Microsoft Azure 같은 클라우드 플랫폼을 통해 필요에 따라 서버 자원을 유연하게 사용하고 확장할 수 있습니다.

 

 

37. 객체지향의 4가지 특성에 대해 설명해주세요

더보기
객체지향프로그래밍은 캡슐화, 상속, 다형성, 추상화로 이루어져 있습니다. 이 네 가지 특성을 통해 객체지향 프로그래밍에서는 코드의 재사용성, 유지보수성, 확장성을 높일 수 있습니다.

  1. 추상화 (Abstraction)
    추상화는 복잡한 시스템에서 중요한 정보만을 표현하고, 불필요한 세부 사항을 숨기는 것을 의미합니다. 예를 들어, '자동차' 객체를 만들 때, 자동차의 색상이나 속도 등 중요한 정보만 포함하고, 엔진의 내부 작동 방식과 같은 복잡한 구현 세부 사항은 추상화하여 외부에 드러내지 않습니다.
  2. 캡슐화 (Encapsulation)
    캡슐화는 객체의 데이터와 메서드를 하나로 묶고, 외부에서 접근할 수 없도록 보호하는 것입니다. 이를 통해 객체의 상태가 외부에 의해 무분별하게 변경되는 것을 방지할 수 있습니다. 객체는 공개된 인터페이스를 통해서만 데이터를 변경하거나 접근할 수 있습니다. 예를 들어, 은행 계좌 객체에서 잔액을 직접 변경하지 못하게 하고 입금 및 출금 메서드를 통해서만 잔액을 조작할 수 있도록 하는 것이 캡슐화입니다.
  3. 상속 (Inheritance)
    상속은 기존 클래스의 속성과 메서드를 물려받아 새로운 클래스를 생성하는 방법입니다. 이를 통해 코드의 재사용성을 높이고, 클래스 간의 계층 구조를 만들어서 관계를 표현할 수 있습니다. 예를 들어, '동물'이라는 부모 클래스를 만들고, '개', '고양이' 같은 클래스는 이를 상속받아 공통된 특성은 유지하고, 각자 고유의 행동을 추가할 수 있습니다.
  4. 다형성 (Polymorphism)
    다형성은 같은 이름의 메서드가 서로 다른 기능을 할 수 있도록 하는 것입니다. 이는 주로 메서드 오버로딩과 오버라이딩을 통해 구현됩니다. 다형성 덕분에 같은 이름의 메서드를 사용해도, 객체의 타입에 따라 다른 동작을 수행하게 할 수 있습니다. 예를 들어, '동물' 클래스의 '소리 내기' 메서드를 각 동물 클래스에서 오버라이딩하여, '개'는 '멍멍', '고양이'는 '야옹' 소리를 내도록 구현할 수 있습니다.

38. Saas, Iaas, Paas 에 대해 설명해줘

더보기

IaaS, PaaS, SaaS는 클라우드 컴퓨팅의 세 가지 주요 서비스 모델로, 각각 다른 수준의 인프라 및 관리 요소를 제공합니다. 이들은 기업이 서버, 네트워크, 데이터베이스 등 IT 인프라를 구축, 관리하는 방식에 큰 변화를 가져왔습니다.

1. IaaS (Infrastructure as a Service)

  • 설명: IaaS는 컴퓨팅 리소스의 기본 인프라(서버, 스토리지, 네트워크)를 가상화하여 제공하는 서비스입니다. 기업은 물리적 장비를 구매할 필요 없이, 클라우드에서 필요한 컴퓨팅 리소스를 사용량에 따라 빌릴 수 있습니다.
  • 사용 예시: 가상 서버 설정 및 관리가 필요한 경우, 고성능 컴퓨팅 환경이 필요한 경우.
  • 대표 서비스: Amazon Web Services (AWS) EC2, Google Cloud Platform (GCP) Compute Engine, Microsoft Azure.

2. PaaS (Platform as a Service)

  • 설명: PaaS는 소프트웨어 개발 및 배포를 위한 플랫폼을 제공합니다. 개발자는 인프라 설정을 신경 쓰지 않고 애플리케이션 개발에 집중할 수 있으며, 플랫폼에는 데이터베이스, 개발 도구, 미들웨어 등이 포함됩니다.
  • 사용 예시: 애플리케이션 개발에 필요한 환경을 신속히 구축하고 싶을 때.
  • 대표 서비스: Google App Engine, Microsoft Azure App Service, Heroku.

3. SaaS (Software as a Service)

  • 설명: SaaS는 사용자가 애플리케이션을 직접 설치할 필요 없이 클라우드를 통해 소프트웨어를 제공받아 사용하는 서비스입니다. 클라우드에 호스팅된 애플리케이션을 인터넷을 통해 사용하기만 하면 됩니다.
  • 사용 예시: 이메일 서비스, CRM, 협업 소프트웨어 등이 필요할 때.
  • 대표 서비스: Google Workspace (Gmail, Docs), Salesforce, Microsoft 365.

 

Comments