1. 불변성의 장점

  • 생성 시점 이후 해당 객체의 상태를 변경할 수 없으므로, 실행 중인 쓰레드 간 서로의 간섭에 의해 생길 수 있는 동기화(synchronization) 문제에 대한 걱정을 안 해도 되게끔 해준다. (Thread safe 하다.)
  • side-effect에 대한 걱정이 없기 때문에 설계, 구현, 및 사용하는데 편리하다는 장점이 있다.
  • 프로그램 실행 간 exception이 발생하더라도 사용했던 객체들의 상태값은 변함이 없고, 이런 장점 때문에 캐시 해두고 사용한다면 효율을 극대화할 수 있다.

2. 세션 쿠키와 영구 쿠키

 

3. 쿠키는 서버에 요청을 보낼 때 자동으로 요청 헤더에 따라가는데 그 이유는? (쿠키의 사용 이유)

  • HTTP는 본질적으로 상태가 없는(stateless) 프로토콜로 다른 페이지를 요청했을 때 서버는 이전 요청의 상태를 기억하지 못한다. (각 요청은 독립적이기 때문에)
  • 그래서 쿠키를 요청 헤더에 포함시켜서 브라우저와 서버의 연속적인 상호작용에서 상태를 유지하기 위해 쓰인다. 
  • 상태 유지, 세션 관리, 사용자 식별, 환경 설정 저장, 사용자의 행동 추적과 분석을 가능하게 하기 위해 쿠키를 사용한다. 

4. 서버에서 생성되는 세션ID는 어떤 원리로 클라이언트의 쿠키에 저장이 되는지?

  • 클라이언트가 서버에 요청을 보내면, 서버는 해당 요청을 처리한 후 응답을 준비한다. 이 응답에는 세션 ID를 클라이언트에게 전달하기 위한 HTTP 헤더가 포함된다.
  • 서버는 HTTP 응답 헤더에 Set-Cookie 헤더를 추가하여 세션 ID를 쿠키로 설정한다. 이 헤더는 클라이언트에게 쿠키를 설정하라는 지시를 포함한다.
  • Set-Cookie 헤더는 여러 속성을 포함하고 있다:
      • sessionID=abc123xyz: 쿠키의 이름과 값이다. 여기서 세션 ID는 abc123xyz이다.
      • Path=/: 쿠키가 유효한 URL 경로를 지정한다. 루트 경로 /로 설정되어 있어 해당 도메인의 모든 경로에 대해 쿠키가 전송된다.
      • HttpOnly: 이 속성이 설정되면, 쿠키는 클라이언트 측 스크립트(JavaScript 등)에서 접근할 수 없습니다. 이는 XSS 공격으로부터 쿠키를 보호한다.
      • Secure: 이 속성이 설정되면, 쿠키는 HTTPS 연결을 통해서만 전송된다. 이는 쿠키의 전송 중 도청을 방지한다.
      • SameSite=Strict: 이 속성은 쿠키가 동일한 사이트의 요청에서만 전송되도록 한다. 이는 CSRF 공격을 방지하는 데 도움이 된다.
  • 클라이언트의 브라우저는 서버로부터 HTTP 응답을 받으면, Set-Cookie 헤더를 읽고 쿠키를 저장한다. 브라우저는 지정된 속성에 따라 쿠키를 로컬 저장소에 저장한다.
  • 이후 클라이언트가 동일한 서버에 요청을 보낼 때, 브라우저는 저장된 쿠키를 자동으로 요청 헤더에 포함시켜 전송한다. 이를 통해 서버는 클라이언트를 식별하고 세션 정보를 유지할 수 있다.

5. 데이터베이스 호출을 끝내면 ResultSet , Statement , Connection 순서대로 close를 호출해줘야하는데 이렇게 닫아주지 않으면 어떤 일이 발생할까요?

  • 메모리 누수 : 해당 객체들이 사용하던 메모리가 회수되지 않고 계속 점유된 상태로 남아있게 된다. 이로 인해 메모리 누수가 발생할 수 있으며, 결국 애플리케이션이 사용할 수 있는 메모리가 부족해질 수 있다.
  • 데이터베이스 연결 누수 
    • 데이터베이스 커넥션 풀을 사용하는 경우, 사용한 커넥션을 반환하지 않으면 연결이 점점 고갈된다. 연결이 고갈되면 새로운 연결을 생성할 수 없게 되어 애플리케이션이 데이터베이스와 상호작용할 수 없게 된다.
    • 데이터베이스 서버는 동시에 처리할 수 있는 연결 수에 제한이 있다. 닫히지 않은 연결이 많아지면 이 제한을 초과하게 되어 다른 애플리케이션이나 사용자들이 데이터베이스에 접근할 수 없게 된다.
  • 데이터베이스 락 문제 : ResultSet이나 Statement를 닫지 않으면, 데이터베이스의 특정 자원에 대한 락이 해제되지 않을 수 있다. 이는 다른 트랜잭션이 해당 자원에 접근하지 못하게 하고, 교착 상태(deadlock)나 성능 저하를 초래할 수 있다.

6. 커넥션 과정은 비용이 많이 드는데, 왜 그런가요?

  • 네트워크 연결 설정: 클라이언트와 데이터베이스 서버 간의 네트워크 연결을 설정하는 것은 시간이 많이 소요됩니다. 특히, 데이터베이스 서버가 원격에 있는 경우 네트워크 지연(latency)도 고려해야 합니다.
  • 메모리 할당: 새로운 커넥션을 설정하면 서버는 해당 커넥션을 처리하기 위한 메모리를 할당해야 합니다. 이에는 버퍼, 캐시, 기타 연결 관련 데이터 구조가 포함됩니다.
  • 스레드 생성: 많은 데이터베이스 시스템은 각 연결을 처리하기 위해 새로운 스레드를 생성하거나 기존 스레드 풀에서 스레드를 할당합니다. 스레드 생성과 관리에는 오버헤드가 발생합니다.
  • 쿼리를 요청하는 과정은 TCP 기반으로 동작하기 때문에 커넥션을 열고 닫는 과정이 오래 걸린다.

7. 톰캣에는 스레드 풀이 있습니다. 이 스레드 풀은 왜 존재하는걸까요?

  • 서버에 들어오는 요청마다 각각의 스레드를 만들어 처리하고 처리가 끝나면 스레드를 버리는 식으로 동작한다면 스레드를 생성하는 시간 때문에 요청 처리가 오래 걸린다.(커널이 개입해서 커널 레벨에서 스레드가 생성되기 때문에)
  • 스레드가 계속 생성되면 컨텍스트 스위칭이 자주 발생하고 cpu 오버헤드 증가 
  • 스레드 수가 증가하면서 메모리 부족 
  • 스레드 풀을 사용하면 처리가 끝난 뒤 스레드를 버리지 않고 스레드 풀에 보관했다가 다른 요청이 들어오면 재사용
  • 여러 작업을 동시에 처리해야 할 때 사용 

8. 커넥션 풀과 스레드 풀의 개수는 어떤 상황에서 어떻게 맞추면 좋을지?

  • 커넥션 풀의 개수 고려 사항
    • 동시 사용자 수 : 동시에 접속하는 사용자가 많으면 더 많이 생성한다.
    • 쿼리 실행 시간 : 각 쿼리의 실행 시간이 길다면 더 많은 커넥션이 필요할 수 있다.
    • 데이터베이스 성능 : 데이터베이스 서버가 처리할 수 있는 최대 연결 수를 고려해야 한다.
    • 애플리케이션 논리 : 애플리케이션이 얼마나 자주 데이터베이스에 접근하는지와 트랜잭션 길이에 따라 달라질 수 있다.
    • 일반적으로 커넥션 풀의 크기는 10~30
  • 스레드 풀의 개수 고려 사항
    • CPU 코어의 수 : 스레드 수는 CPU 코어 수와 밀접하게 관련된다. 너무 많은 스레드는 오히려 컨텍스트 스위칭 오버헤드를 증가시켜 성능 저하를 초래할 수 있다.
    • 작업 특성 : /O 바운드 작업(네트워크, 파일 입출력 등)이 많은 경우 더 많은 스레드를 사용할 수 있지만, CPU 바운드 작업이 많은 경우 CPU 코어 수에 맞추는 것이 좋다.
    • 응답 시간 요구사항 : 응답 시간이 중요한 애플리케이션이라면 스레드 수를 늘려 병렬 처리를 최대화할 수 있다.
    • 일반적으로 CPU 코어 수 * 2
  • 모든 요청이 db에 접근하는 것 아니기 때문에 스레드 풀의 개수는 커넥션 풀의 개수보다 많아야 한다.

 

9. JWT. 인증, 인가 관련된 내용 자유롭게 학습하기

'공부 > f-lab' 카테고리의 다른 글

f-lab 11주차  (0) 2024.05.28
f-lab 10주차  (0) 2024.05.23
f-lab 8주차  (0) 2024.05.07
f-lab 7주차  (0) 2024.04.30
f-lab 6주차  (0) 2024.04.24

1️⃣ Docker 설치

https://www.docker.com/products/docker-desktop/  도커 홈페이지에 접속해서 OS에 맞는 도커를 내려 받아 설치한다.

설치가 완료되면 다음의 명령어로 버전 확인

 

2️⃣ MySQL Docker 이미지 다운로드

다음 명령어로 MySQL Docker 이미지를 다운로드한다. 태그에 버전을 지정하지 않으면 최신 버전을 다운로드한다.

 

다운로드한 이미지 확인

 

3️⃣ MySQL Docker 컨테이너 생성 및 실행

 

4️⃣ Docker 컨테이너 리스트 출력

 

5️⃣ MySQL Docker 컨테이너 중지/시작/재시작

6️⃣ MySQL Docker 컨테이너 접속

 

1. git에서 pull request merge의 3가지 전략

https://ssocoit.tistory.com/273#2._%EC%84%B8_%EA%B0%80%EC%A7%80_%EB%A8%B8%EC%A7%80_%EC%A0%84%EB%9E%B5 참고

https://im-developer.tistory.com/182 참고 

  • Create a merge commit 
    • 기본 머지
    • 하나의 브랜치와 다른 브랜치의 변경 이력 전체를 합친다.
    • 각각의 브랜치에 남은 커밋을 히스토리에 그대로 남긴다.
    • 어떤 브랜치에서 어떻게 만들어져서 머지가 되었는지 상세하게 파악할 수 있다. 
    • 히스토리가 자세하게 남아서 보기 어려울 수 있다는 단점이 있다.
  • Squash and merge
    • 개발용 브랜치에 있던 내용들을 하나로 합쳐서 중앙 브랜치에 하나의 커밋으로 저장하는 전략
    • 기존 변경사항들이 어떻게 변했는가보다 머지가 되었다에 좀 더 집중한 전략
    • 남아있는 정보량이 비교적 적기 때문에, 개발용 브랜치에서 언제 어떤 코드를 바꿨는지에 대한 정보를 잃을 수 있다는 단점이 있다.
  • Rebase and merge
    • 이미 존재하는 Rebase라는 기능을 이용해서 브랜치를 머지하는 것이다.
    • 모든 커밋들이 합쳐지지 않고 각각 main 브랜치에 추가된다.
    • 히스토리의 base를 직접 옮겨서 처리하는 방식이기 때문에 개발용 브랜치에서 변경한 내용을 중앙 브랜치에서 변경한 것처럼 바꿔버릴 수 있다.
    • 어느 시점에 머지가 되었는지 나중에 판단하기 어렵다.

2. 테스크 코드 (필요성, 장단점)

  • 테스트 코드란 작성한 코드가 의도대로 잘 동작하고 예상치 못한 문제가 없는지 확인할 목적으로 작성하는 코드
  • 필요성 : 개발 과정 중 예상치 못한 문제를 미리 발견할 수 있고, 코드 수정이 필요한 상황에서 유연하고 안정적인 대응을 할 수 있다. 이는 서비스의 품질 및 안정성과 직결되어 있다.
  • 장점
    • 코드 및 서비스의 품질을 향상시킨다.
    • 개발자가 더 빠르게 기능의 동작 방식을 이해하는 데 도움이 되는 문서로 작용할 수 있다.
    • 리팩토링 작업을 진행할 경우 이전에 작성한 테스트 코드를 통해 서비스에서 동작하는 기능에 대한 안정적인 확장 및 품질 향상이 가능하다.
  • 단점
    • 테스트 코드 작성은 단순한 작업이 아니므로 개발 시간이 늘어날 수 있다.
    • 서비스의 기능이 변경되거나 확장될 때마다 테스트 코드로 함께 수정해야 하기 때문에 추가적인 유지보수 비용이 발생할 수 있다.
    • 오버 엔지니어링 발생 : 개발 과정에서 소프트웨어의 요구사항보다 더 복잡하고 정교하게 코드를 작성하는 것
    • 테스트 코드 작성 방법을 익히는 데 시간이 소요된다.

3. 동기 vs 비동기 vs 블로킹 vs 논블로킹

https://www.youtube.com/watch?v=oEIoqGd-Sns 참고 

  • 동기
    • 작업을 동시에 수행하거나, 동시에 끝나거나, 끝나는 동시에 시작함을 의미
  • 비동기
    • 시작, 종료가 일치하지 않으며 끝나는 동시에 시작을 하지 않음을 의미 
  • 블로킹
    • 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 다른 작업이 끝날 때까지 기다렸다가 자신의 작업을 시작하는 것
  • 논블로킹
    • 다른 주체의 작업에 관련없이 자신의 작업을 하는 것 
  • 블로킹 vs 논블로킹은 다른 주체가 작업할 때 자신의 제어권이 있는지(논블로킹) 없는지(블로킹)로 볼 수 있다.
  • 동기와 비동기는 결과를 돌려주었을 때 순서와 결과에 관심이 있는지(동기) 아닌지(비동기)로 판단할 수 있다. 
  • 4가지 조합
    • 동기+블로킹 : 작업을 넘겨주고 그 작업이 끝날 때까지 대기했다가 작업이 완료되고 제어권과 결과가 넘어오면 바로 처리를 한다. 예) 자바에서 입력 요청을 할 때 사용한다. (입력을 받을 때까지 다른 작업을 하지 않고 기다렸다가 입력을 받으면 처리)
    • 동기 + 논블로킹 : 자신의 제어권을 가지고 일을 하다가 중간중간에 다른 작업에 결과가 나왔는지 물어보다가 결과가 나오면 가지고 와서 업무를 처리한다. 예) 해당 데이터를 가져올 때까지 유저에게 정보의 로드율이 얼만큼인지 보여줄 때 사용한다.
    • 비동기 + 블로킹 : 다른 작업을 할 동안 결과에는 관심이 없지만 기다렸다가 결과를 가지고 나중에 처리한다. 
    • 비동기 + 논블로킹 : 다른 작업이 진행될 동안 자신의 작업을 이어서 하다가 다른 작업이 끝나서 결과가 넘어오면 그 결과를 나중에 처리한다.

4. TCP의 3-way handshake란?

  • TCP 프로토콜을 이용해서 통신하는 프로그램은 데이터를 주고받기 전에 먼저 연결을 진행하는 과정을 말한다.
  • SYN : 연결 설정. 시퀀스 번호를 랜덤으로 설정하여 세션을 연결하는 데 사용
  • ACK : 응답 확인. 패킷을 받았다는 것을 의미
  • LISTEN : 포트가 열린 상태로 연결 요청 대기 중
  • SYN_RECV : SYNC 요청을 받고 상대방의 응답을 기다리는 중
  • 동작방식
    • Client → SYN → Server : 클라이언트가 서버에게 접속을 요청하는 SYN 플래그를 보낸다.
    • Server → SYN + ACK Client : 서버는 Listen 상태에서 SYN이 들어온 것을 확인하고 SYN_RECV 상태로 바뀌어 SYN+ACK 플래그를 클라이언트에게 전송한다. 그 후 서버는 다시 ACK 플래그를 받기 위해 대기상태로 변경된다.
    • Client → ACK → Server : SYN+ACK 상태를 확인한 클라이언트는 서버에게 ACK를 보내고 연결 성립이 된다.

5. 함수형 프로그래밍의 특징 및 장점(명령형 프로그래밍과 비교)

  • 프로그램이 상태의 변화 없이 데이터 처리를 수학적 함수 계산으로 취급하고자 하는 패러다임
  • 순수 함수
    • 동일한 입력에는 항상 같은 값을 반환한다.
    • 함수의 출력은 오로지 그 함수에 입력된 값에만 의존한다.
    • 함수의 실행은 프로그램의 실행에 영향을 미치지 않아야 한다.
  • 불변성
    • input의 불변성을 유지해야 순수함수의 순수성 유지가 의미가 있다.
  • 참조의 투명성
    • 함수 외부에 의존하는 코드가 없고, 함수 사용자 입장에서는 유효한 매개변수만 전달하면 된다.
    • 동일한 매개변수에 대해서는 항상 동일한 결과가 나온다,
    • 예외를 던지지 않는다.
    • 데이터베이스, 파일 시스템, 네트워크 등의 외부 기기로 인해 동작이 멈추지 않는다.
  • 장점
    • 여러 가지 연산 처리 작업이 동시에 일어나는 프로그램을 만들기 쉽다.
    • 머러티 코어 혹은 여러 연산 프로세스를 사용하는 시스템에서 효율적인 프로그램을 만들기 쉽다.
    • 상태변화에 따른 부작용에서 자유로워지기 때문에 순수하게 기능 구현에 초점을 맞추어 설게할 수 있다.
함수형 프로그래밍 명령형 프로그래밍
상태 변경을 지양하고 불변성 유지 상태 변경 중심
외부 상태에 의존하지 않아 부작용 최소화 함수가 외부 상태에 의존해 부작용을 일으킬 가능성 높음
데이터의 불변성 강조 변수와 객체의 값을 자유롭게 변경 가능
상태 변이가 없고 부작용이 없으므로 병렬성와 동시성 쉽게 처리 상태 변이와 부작용이 많아 병렬성과 동시성 관리 어려움

6. 웹이란?

  • 전 세계 인터넷에 연결된 수많은 기기들이 서로의 정보를 공유하는 공간
  • 하이퍼텍스트로 표현되는 여러 문서들을 컴퓨터를 통해 모니터에 출력
  • 하이퍼텍스트는 HTML로 작성되며 HTTP 프로토콜을 통해 주고받게 된다.

'공부 > f-lab' 카테고리의 다른 글

f-lab 10주차  (0) 2024.05.23
f-lab 9주차  (0) 2024.05.19
f-lab 7주차  (0) 2024.04.30
f-lab 6주차  (0) 2024.04.24
f-lab 5주차  (0) 2024.04.16

1. 동기 / 비동기 / 블로킹 IO / 논블로킹 IO

  • https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%EB%8F%99%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC 참고
  • 동기 / 비동기 : 요청한 작업에 대해 완료 여부를 신경 써서 작업을 순차적으로 수행할지 아닌지에 대한 관점
  • 블로킹 / 논블로킹 : 현재 작업이 블록되느냐 아니냐에 따라 다른 작업을 수행할 수 있는지에 대한 관점
  • 동기( Synchronous ) : 요청한 작업에 대해 완료 여부를 따져 순차적으로 처리한다.
  • 비동기( Asynchronous ) : 요청한 작업에 대해 완료 여부를 따지지 않기 때문에 자신의 다음 작업을 그대로 수행한다.
    • 장점 : 느린 작업이 발생했을 때 기다리지 않고 다른 작업을 처리할 수 있기 때문에 시스템 성능 향상에 도움을 준다.
  • 동기 작업은 요청한 작업에 대해 순서가 지켜지고, 비동기는 지켜지지 않을 수 있다.
  • 콜백함수 : 비동기나 논블로킹에서 작업의 완료 여부나 결과에 대한 후처리를 위해 이용되는 방식
  • 블로킹과 논블로킹은 호출된 함수가 호출한 함수에게 제어권을 바로 주느냐(블로킹) 안주느냐(논블로킹)로 구분된다.
  • 제어권 : 함수의 코드나 프로세스의 실행 흐름을 제어할 수 있는 권리

2. TCP와 UDP의 차이

  • https://inpa.tistory.com/entry/NW-%F0%9F%8C%90-%EC%95%84%EC%A7%81%EB%8F%84-%EB%AA%A8%ED%98%B8%ED%95%9C-TCP-UDP-%EA%B0%9C%EB%85%90-%E2%9D%93-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EC%9E%90 참고
  • 프로토콜 : 클라이언트와 서버가 정보를 교환할 수 있도록 하는 메시지 형식에 대한 규칙
  • TCP - 전송 제어 프로토콜
    • IP 규칙으로만 통신하기에 부족하거나 불안정하던 여러 단점(패킷 순서 보장 없음, 패킷 유실)들을 커버해, 패킷 전송을 제어하여 신뢰성을 보증한다.
    • 패킷 데이터의 전달을 보증하고 보낸 순서대로 받게 해준다.
    • 데이터를 확실하게 보내기 위해서 3 way handshake이라는 방법을 사용한다. 
    • 3 way handshake 
      • 본격적으로 상대 클라이언트와 연결되기 전에 가상 연결을 해서 패킷으로 보내서 확인하는 동작
      • SYN : 연결을 생성할 때 클라이언트가 서버에 시퀀스 번호를 보내는 패킷
      • SYN-ACK : 시퀀스 번호를 받은 서버가 ACK 값을 생성하여 클라이언트에세 응답하는 패킷
      • ACK : ACK 값을 사용하여 응답하는 패킷
      • ACK 값을 받지 못한 데이터는 재전
    • TCP 데이터 안에 전송 제어, 순서, 정보들이 있기 때문에 패킷을 순서대로 제어할 수 있다.
  • UDP - 사용자 데이터그램 프로토콜
    • 비 연결지향적 프로토콜
    • 데이터 전달과 순서를 보증하지 않는다.
    • TCP와 비교해서 기능이 거의 없어 단순하지만 빠르게 패킷을 보내는 목적 

3. 람다란? 람다의 장점 

  • https://inpa.tistory.com/entry/%E2%98%95-Lambda-Expression 참고
  • 람다 표현식 = 익명 함수 : 함수형 프로그래밍을 구성하기 위한 함수식, 메서드를 간결한 함수 식으로 표현한 것
  • 메서드 타입/이름, 매개변수 타입, 중괄호, return 문을 생략하고 화살표 기호를 넣음

  • 인터페이스(= 함수형 인터페이스)로 선언한 익명 구현 객체만이 람다식으로 표현이 가능하다.
  • 함수형 인터페이스 : 딱 하나의 추상메서드가 선언된 인터페이스. 인터페이스 선언 시 @FuntionalInterface 어노테이션을 붙여주면 두 개 이상의 메서드가 선언되지 않도록 한다. 
  • 장점
    • 코드의 길이를 줄일 수 있다. 
    • 람다 함수는 일급 객체로 취급되기 때문에 메서드를 변수에 할당하거나 매개변수로 넣거나 리턴값으로 사용할 수 있다.
    • 함수형 프로그랭 지원
    • 함수형 프로그래밍의 특성으로 상태 변경이 없고 스레드에 안전하기 때문에 다중 스레드 환경에서 안전하게 사용할 수 있다.
  • 단점 
    • 문서화를 할 수 없다.
    • 익명 구현 객체 기반이기 때문에 디버깅이 까다롭다.

4. 스트림이란? 스트림의 장점 (함수형 프로그래밍과 엮어서)

  • 스트림 : 데이터의 흐름. 배열 또는 컬렉션 인스턴스에 함수 여러 개를 조합해서 원하는 결과를 필터링하여 가공된 결과를 얻을 수 있다.
  • 원본 데이터를 변경하지 않는다 : 원본의 데이터를 조회하여 원본의 데이터가 아닌 별도의 요소들로 스트림을 생성한다.
  • 일회용이다 : 한번 사용이 끝나면 재사용이 불가능하다. 다시 필요한 경우는 재생성해서 사용해야 한다.
  • 내부 반복자 : 반복 문법을 메서드 내부에 숨기고 있기 때문에 간결한 코드의 작성이 가능하다.
  • 장점
    • 배열과 컬렉션을 함수형으로 처리할 수 있다.
    • 스레드를 이용해 하나의 작업을 둘 이상의 작업으로 나눠서 동시에 진행하는 병렬 처리가 가능하다.

5. Optional 클래스가 무엇이고, 왜 탄생했는지?

  • null을 처리하기 위한 새로운 방법으로 등장
  • 값이 있을 수도 있고 없을 수도 있는 객체를 감싸는 래퍼 클래스
  • 명시적으로 해당 값이 null일 수 있음을 표현하고 NullPointerException을 방지할 수 있는 API를 제공한다.
  • 코드의 가독성을 높이고, null 체크를 강제함으로써 더 안전한 코드를 작성할 수 있게 해준다.

6. ThreadLocal이란?

  • 각각의 스레드 별로 필요한 정보를 저장할 수 있다.
  • 스프링의 데이터베이스 접근 기술은 스레드 로컬을 기반으로 동작하고 있다.
  • 서비스 계층에서 트랜잭션을 시작하도록 커넥션을 커넥션 풀로부터 꺼내오고, Dao 계층에서 해당 커넥션활용해 커밋하거나 롤백하는 동작은 스레드 로컬 덕분에 가능한 것이다.

 

※ 다음주 예습 ※

최범균의 JSP 1~4장

'공부 > f-lab' 카테고리의 다른 글

f-lab 9주차  (0) 2024.05.19
f-lab 8주차  (0) 2024.05.07
f-lab 6주차  (0) 2024.04.24
f-lab 5주차  (0) 2024.04.16
f-lab 4주차  (0) 2024.04.09

1. Checked Exception은 왜 생겨났고, 현재는 왜 안쓰는가?

  • 쇼규모 프로그램에서는 개발자의 생산성과 코드품질을 향상시킬 수 있으나, 일반적인 대규모 소프트웨어에서는 그렇지 않다.
  • 낮은 수준에서 발생하는 특정유형의 CheckedException 의 경우 (File I/O, Network, Database …) 일반적인 응용프로그램에서는 알 필요 없거나 알고싶지 않아한다. 만약 Exception을 캐치한다고 하더라도 적절하게 대응하기 힘든경우가 대부분이라 RuntimeException으로 rethrow처리하는 경우가 많다.
  • 코드의 확장성에 이슈가 생길수 있다. 단일 CheckedException 사용은 훌륭하게 동작하는것으로 보이나 4~5개의 서로다른 CheckedExcpetion을 사용하는 하위 API를 호출하는 경우 Exception 체인이 기하급수적으로 증가할 수 있다.
  • 반드시 예외 처리를 하는 코드를 작성해야 한다. 예외를 던지는 것은 모든 하위 메서드, 호출 트리에 누적되기 때문에 수많은 메서드를 조정해야 할 수도 있다.

2. Java 8 기준으로 GC는 어떻게 실행이 되는가? (heap young/old generation 동작 관점)

  • parellel GC
  • 멀티 스레드로 GC를 수행하기 때문에 stop-the-world 시간을 줄일 수 있다.
  • minor GC(young)에서 멀티 스레드를 사용한다.(후에는 major GC(old)에서도 멀티 스레드 사용)
  • https://www.youtube.com/watch?v=FMUpVA0Vvjw 참고

3. Java BigDecimal은 부동 소수점의 오류를 어떻게 해결하는가?

  • BigDecimal은 십진법을 사용하여 숫자를 저장한다.
  • 실수 타입인 double이나 float를 사용하지 않고 정수를 사용하여 소수를 다룬다. 
    • intVal : 정수부 값
    • precision : 정수부+소수부 길이
    • scale : 소수부 길이
    • stringCache : 숫자를 String으로 변환한 값
    • intCompact : 소수점을 제외한 전체 수(10.25 → 1025)

4. System.out.println 클래스를 절대 쓰지 말라고 하는데 이유가 무엇인가?

  • 이 클래스는 블로킹 I/O인데 동기화가 동작된다는 이유때문에 멀티스레드에서 락이 발생한다.
  • 출력이 완료될 때까지 실행이 멈추고 대기해야 하기 때문에 성능을 저하시킨다. 
  • 동기화 블록 안에서 블로킹 I/O 까지 일어난다면 대기가 계속 길어질 수 있다.

5. 메인 vs 엔티티

  • 도메인 : 특정한 문제 영역이나 분야
    • 사용자가 이용하는 앱의 기능, 회사의 비즈니스 로직을 정의하고 있는 영역
    • 유스케이스에서 한 액터가 수행하는 기능
    • 음식을 만드는 '행위'
  • 엔티티 : 도메인에서 식별 가능한 개별적인 객체나 개념 
    • 고유의 식별자를 갖는 객체로 자신의 라이프 사이클을 가진다.
    • 주문, 회원, 상품과 같이 도메인의 고유한 개념을 표현한다.
    • 도메인 모델의 데이터를 포함하며 해당 데이터와 관련된 기능을 함께 제공한다.
    • 음식 제작의 '데이터' 

※ 다음 주 예습 ※

1. HashMap

2. 스레드

https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%E2%9A%94%EF%B8%8F-%EC%93%B0%EB%A0%88%EB%93%9C-%EC%B0%A8%EC%9D%B4

 

👩‍💻 ‍완전히 정복하는 프로세스 vs 스레드 개념

한눈에 이해하는 프로세스 & 스레드 개념 전공 지식 없이 컴퓨터의 프로그램을 이용하는데는 문제 없어 왔지만 소프트웨어를 개발하는 사람으로서 컴퓨터 실행 내부 요소를 따져보게 될때, 아

inpa.tistory.com

3. I/O

4. Serializable, NIO

'공부 > f-lab' 카테고리의 다른 글

f-lab 8주차  (0) 2024.05.07
f-lab 7주차  (0) 2024.04.30
f-lab 5주차  (0) 2024.04.16
f-lab 4주차  (0) 2024.04.09
f-lab 3주차  (0) 2024.04.02

1. 다형성을 사용하면 좋은 점은?

  • 다형성 : 한 타입의 참조 변수를 통해 여러 타입의 객체를 참조할 수 있도록 하는 것. 즉, 상위 클래스 타입의 참조 변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용하여 상위 클래스가 동일한 메시지로 하위 클래스들이 서로 다른 동작을 할 수 있도록 한다.
  • 클래스가 상속 관계에 있을 때 나타나는 다채로운 성질
  • 장점
    • 코드를 유지보수하기 쉽다. 
    • 여러 클래스를 하나의 타입으로 묶어서 사용할 수 있기 때문에 코드를 압축할 수 있다.
  • https://inpa.tistory.com/entry/OOP-JAVA%EC%9D%98-%EB%8B%A4%ED%98%95%EC%84%B1Polymorphism-%EC%99%84%EB%B2%BD-%EC%9D%B4%ED%95%B4 참고

2. 언제 interface 사용하고, 언제 abstract class 사용 하는가? (문법적인 차이도)

  • 인터페이스
    • 모든 메서드가 추상 메서드로 구성되어 있고 구현 클래스에서 이를 구현해야 한다.
    • 다중 상속을 지원한다.
    • 주로 다중 상속을 필요로 하는 상황에서 사용한다. 여러 인터페이스를 구현함으로써 한 클래스가 다양한 역할을 수행할 수 있게 하는 상황
    • 다중 상속이 필요하거나 구현 객체 간의 계약을 정의할 필요가 있는 경우
  • 추상 클래스
    • 추상 메서드와 일반 메서드를 모두 포함하고 일부 기능을 구현한다. 
    • 다중 상속을 지원하지 않는다.
    • 공통적인 기능을 가진 클래스들 사이에서 코드의 재사용성을 높이기 위해 사용한다. 
    • 상속을 통해 코드의 재사용성을 높이고 공통적인 기능을 효율적으로 관리할 수 있게 한다.

3. checked exception vs unchecked exception

  • checked exception
    • 컴파일 단계에서 확인
    • 반드시 예외처리를 해야 함
    • 예외발생 시 트랜잭션 처리에서 롤백하지 않음(복구 가능한 메커니즘을 가져서)
    • RuntimeException의 하위 클래스가 아니면서 Exception 클래스의 하위 클래스들
  • unchecked exception
    • 실행단계에서 확인
    • 명시적인 예외 처리를 강제하지 않음
    • 외발생 시 트랜잭션 처리에서 롤백함
    • RuntimeException의 하위 클래스들

4. StringBuffer는 내부적으로 동기화 처리가 어떻게 되어 있나요?

  • StringBuilder와 StringBuffer의 append 메소드에는 차이가 있다.
  • StringBuilder
@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
    super.append(str);
    return this;
}
  • StringBuffer
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}
  • Synchronized 메서드를 호출하였을 때, 자신이 포함된 객체에 lock 걸게 된다. 

5. enum 어떤 메모리에 저장이 될까요? (method 영역, Heap 영역 분리하여)

  • enum 클래스의 정보가 메서드 영역에 저장된다.
  • enum 객체 인스턴스가 힙 영역에 저장된다.
  • enum 클래스는 상수 하나당 인스턴스 하나를 생성해서 public static final로 공개한다. 열거 타입의 인스턴스는 클라이언트가 직접 생성할 수 없고, 인스턴스는 런타임에 한 번만 생성된다. 이런 특징으로 싱글톤 패턴을 구현할 때 사용되기도 한다.

6. inner class vs nested class (+ GC의 대상이 되는건 누구?)

  • inner class
    • static 키워드를 사용하지 않고 다른 클래스 내부에 정의된 클래스
    • 내부 클래스는 외부 클래스 멤버에 접근할 수 있다.
    • 내부 클래스 객체를 생성하려면 외부 클래스의 객체부터 생성해야 한다.
    • 내부 클래스에서 외부 클래스 멤버에 접근할 때는 외부클래스.this 로 사용한다. 내부 클래스 멤버에 접근하려면 this만 사용한다.
  • nested class
    • static 키워드를 사용하고 다른 클래스 내부에 정의된 클래스
    • 기술적으로는 내부 클래스가 아니다.
    • 내부 클래스에서 외부 클래스의 멤버에 접근할 수 없다.
    • 내부 클래스를 인스턴스화하기 위해 외부 클래스를 인스턴스화할 필요는 없다.
  •   inner class는 외부 클래스에 종속되어 있기 때문에 외부 클래스의 인스턴스가 더 이상 쓰이지 않고 GC의 대상이 되었을 때 inner class도 GC의 대상이 된다. 즉, 외부 클래스의 인스턴스가 메모리에 계속 남아있다면 inner class도 그렇다. nested class는 외부 클래스와 독립적으로 이루어져 있고 static이 붙은 클래스이기 때문에 GC의 대상이 될 수 없다.

7. 어노테이션을  왜 쓸까요? (+ 리플렉션 적용 과정)

  • 용도
    • 소스 코드에 메타데이터 추가
    • 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공
    • 소프트웨어 개발툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
    • 실행 시 특정 기능을 실행하도록 정보 제공
  • 리플렉션 : 힙 영역에 로드된 Class 타입의 객체를 통해, 원하는 클래스의 인스턴스를 생성할 수 있도록 지원하고, 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API이다. 컴파일타임이 아닌 런타임에 동적으로 특정 클래스의 정보를 추출할 수 있는 프로그래밍 기법이다.
  • 어노테이션은 소스 코드에 메타데이터를 추가하는 방법이며, 리플렉션은 실행 시간에 클래스의 정보를 검사하고 조작하는 데 사용됩니다. 어노테이션을 사용하여 클래스에 메타데이터를 추가하고, 리플렉션을 사용하여 그 정보를 동적으로 검사하고 처리한다.
  • 리플렉션 적용 과정
    • 클래스 객체 얻기 
    • 얻고자 하는 클래스의 정보를 얻기 위해 클래스 객체의 메서드를 사용한다. 이러한 메서드는 클래스의 필드, 메서드, 생성자, 어노테이션 등에 접근할 수 있는 다양한 방법을 제공합니다.
    • 얻은 클래스, 필드, 메서드 등에 어노테이션을 조사하여 필요한 작업을 수행할 수 있다.
Class<?> clazz = MyClass.class;
MyClass obj = new MyClass();
Class<?> clazz = obj.getClass();

 

 

8. GC에서 사용하는 알고리즘은 무엇이 있고, Java는 어떤 알고리즘을 사용하나요?

9. 부동 소수점의 오류란?

  • 부동 소수점 숫자를 정확하게 표현하지 못하는 문제, 부동 소수점 숫자를 이진수로 표현할 때 발생한다.
  • 예를 들어, 10진수 0.1을 이진 소수점으로 정확하게 표현할 수 없다. 따라서 이진 소수점으로 근사하여 표현하게 되는데, 이 과정에서 정확한 값과 약간의 차이가 발생할 수 있다. 이러한 근사로 인해 부동 소수점 오류가 발생할 수 있다.
  • 계산 결과의 정확성에 영향을 미칠 수 있다. 특히 금융 애플리케이션과 같이 정밀한 계산이 필요한 경우에는 이러한 오류를 최소화해야 한다.
  • 이를 위해 BigDecimal과 같은 정확한 십진수 연산을 지원하는 데이터 타입을 사용한다.

※ 다음 주 예습 주제

1. 제네릭 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%EA%B0%9C%EB%85%90-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0

2. ArrayList

https://inpa.tistory.com/entry/JAVA-%E2%98%95-ArrayList-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9%EB%B2%95

3. Stack 클래스

https://inpa.tistory.com/entry/JCF-%F0%9F%A7%B1-Stack-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC

4. Set, HashSet, Queue, LinkedList

5. Map, HashMap

 

※ 프로젝트

- 유저 시나리오 작성하기

- API 문서 작성하기

- 최소한의 기능이 무엇인지 고민해보기

'공부 > f-lab' 카테고리의 다른 글

f-lab 7주차  (0) 2024.04.30
f-lab 6주차  (0) 2024.04.24
f-lab 4주차  (0) 2024.04.09
f-lab 3주차  (0) 2024.04.02
f-lab 2주차  (0) 2024.03.26

1. 객체 지향 언어가 상태를 가져서 좋은 점은?(절차 지향과 비교)

  • 객체 지향은 클래스라는 개념으로 데이터와 함수를 묶어서 사용한다.  그 클래스의 데이터들을 객체의 상태라고 할 수 있다. 이것을 캡슐화라고 할 수 있고 캡슐화를 하면 정보를 은닉해두기 때문데 외부에서 그 객체의 메서드를 호출하지 않는 이상 객체의 상태를 변경할 수 없다. 
  • 절차지향에서는 클래스라는 개념을 사용하지 않고 데이터와 함수를 묶지 않고 분리해서 사용하기 때문에 데이터가 예기치 않게 변경될 수 있다.
  • 절차 지향에서는 주로 전역 변수를 사용하고 어느 곳에서나 쉽게 접근할 수 있고 객체 지향에서는 상태를 행동을 통해서만 변경할 수 있다.

2. SSD에서는 전기 신호로 어떻게 데이터를 읽어 오는가?

  • SSD는 플래시 메모리를 사용해서 전기 신호로 데이터를 읽고 저장한다.
  • 플래시 메모리는 비휘발성 메모리의 한 유형으로, 데이터를 저장하는 데 사용되는 전자 소자이다. 플래시 메모리는 전기 신호를 이용하여 데이터를 읽고 쓰며, 전원이 꺼져도 저장된 데이터를 유지할 수 있다.

3. HDD와 SSD의 데이터 액세스 포인트 개수 차이는?

  • HDD는 보통 한 번에 하나의 데이터 액세스 포인트에 액세스 할 수 있다.
  • SSD는 병렬로 한 번에 여러 개의 데이터에 액세스 할 수 있으며 물리적은 접근이 아니기 때문에 가능하다.

4. JVM 링크에서 심볼릭 레퍼런스란?

  • 클래스로더의 링크 과정에서 마지막 단계인 해결단계와 관련된 용어이다.
  • 메서드 영역 내의 런타임 상수 풀에 있는 심볼릭 레퍼런스를 직접 참조로 대체한다. 
  • 심볼릭 레퍼런스란 우리가 코드를 작성하면서 사용한 클래스, 필드, 메서드의 이름을 지칭한다. 해결 단계에서 클래스, 필드, 메서드 , 상수 풀의 심볼릭 레퍼런스를 실제 메모리 주소로 변환한다.
  • 심볼릭 레퍼런스 : 특정 객체를 참조할 때 객체의 이름으로 참조하는 것, 상수 풀에 저장됨
  • 직접 참조 : 객체를 메모리의 실제 주소 값으로 참조하는 것

5. 상속을 타입 공유로 사용하였을 때의 장점

  • 업캐스팅을 이용해서 자식 객체를 부모 클래스의 타입으로 변환할 수 있다.(=업캐스팅, 반대는 불가능)
  • 다양한 자식 객체들을 부모의 타입으로 묶어서 관리할 수 있다.

  • 각각의 자식 객체들은 같은 부모 타입이지만 각각의 객체를 참조하기 때문에 같은 이름의 메서드를 실행해도 각각의 자식 클래스에서 재정의된 메서드로 실행된다.
  • 다형성을 구현하고 코드의 유연성을 높인다.

6. 상속의 단점은?

  • 결합도가 높아짐 :  부모 클래스의 변경이 자식 클래스에 영향을 미칠 수 있기 때문에 유지보수를 어렵게 만든다.
  • 불필요한 기능 상속 : '동물'이라는 부모 클래스에 '날다'라는 메서드가 있다면 '호랑이'라는 자식 클래스에는 불필요한 메서드가 상속된다.
  • 부모 클래스의 결함이 그대로 넘어옴
  • 부모 클래스와 자식 클래스의 동시 수정 문제  : OCP 법칙 위반(확장에는 열려 있고 수정에는 닫혀있다)
  • 메서드 오버라이딩의 오동작
  • 불필요한 인터페이스 상속 문제
  • 클래스 폭발 : 상속을 남용하게 되면 새롭게 만든 클래스에 하나의 기존 기능을 연결하기 위해 상속을 하게 되고, 이러한 과정이 반복되면 필요 이상으로 수많은 클래스를 추가해야 한다.
  • 단일 상속의 한계 : 상속이 필요한 클래스가 이미 다른 클래스를 상속하고 있다면 또 클래스를 나누어서 상속을 해야 하는데 이렇게 하면 결국 클래스 폭발 문제로 이어진다.
  • https://brightstarit.tistory.com/43 참고

7. instanceof는 왜 성능이 안좋은가?

  • instanceof를 사용하면 알맞은 타입을 찾을 때까지 컴파일 시에 모든 타입을 돌며 검사해야한다.
  • 대신에 is타입명() 과 같은 메서드의 다형성을 적용해야 성능이 더 좋다.

8. 언제 interface 사용하고, 언제 abstract class 사용 하는가?

  • 인터페이스 : 상속 관계를 타고 올라갔을 때 다른 부모 클래스를 상속하는데 같은 기능이 필요할 경우
  • 추상 클래스 : 상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하는데 같은 기능도 필요할 경우
  • 상속을 받아 기능을 확장하고자 할 때는 추상클래스를 사용하고 동일한 기능을 구현하는 클래스 간의 메서드나 변수의 이름을 통일하고자 할 때는 인터페이스를 사용한다.

9. final 키워드에 대해 설명

  • final 키워드는 한 번 초기화되면 변경할 수 없음을 나타낸다.
  • final 변수 
    • 한 번 할당되면 값을 변경할 수 없다. 즉, 변수가 초기화된 후 다른 값으로 재할당할 수 없다.
    • 선언 시 초기화를 해야 한다. 초기화를 하지 않고 선언만 하면 컴파일 오류가 발생한다.
    • 보통 상수를 표현할 때 사용된다.
  • final 메서드
    • 하위 클래스에서 오버라이딩할 수 없다. 즉, final 메서드는 하위 클래스에서 변경할 수 없다.
    • 보안, 성능 최적화, 메서드의 의도된 동작 보호 등을 위해 사용됩니다.
  • final 클래스 
    • 상속할 수 없는 클래스이다. 즉, final 클래스는 하위 클래스를 가질 수 없다.
    • 보안, 불변 클래스(immutable class) 설계, 효율성 등을 위해 사용된다.
  • final 키워드를 사용하면 코드의 안정성을 높일 수 있다. final 변수는 값이 변경되지 않음을 보장하고, final 메서드와 final 클래스는 의도된 대로 동작하도록 보호할 수 있다. 따라서 코드의 의도를 명확히 전달하고 오류를 방지하기 위해 final 키워드를 적절히 활용하는 것이 좋다.

10. exception vs error

  • exception(프로그램 안) 
    • 프로그램의 실행 도중 발생할 수 있는 예외적인 상황을 나타낸다. 이러한 예외적인 상황은 일반적으로 프로그램의 사용자 또는 외부 환경의 영향을 받아 발생한다.
    • 주로 프로그램 코드 내에서 예상할 수 있는 오류나 예외적인 상황을 처리하기 위해 사용된다. 예를 들어, 파일을 찾을 수 없는 경우나 배열 범위를 벗어나는 경우 등이 있다.
    • checked exception은 반드시 처리되어야 하는 예외이며, 컴파일 시에 확인된다. unchecked(runtime) exception은 명시적으로 처리하지 않아도 되는 예외로, 실행 시에 확인된다.
    • 스레드에만 영향을 준다.
    • checked  exception
    • unchecked(runtime) exception : 예외를 미리 감지하디 못했을 때 발생. 컴파일시에 체크를 하지 않는다.
  • error(프로그램 밖)
    • 일반적으로 프로그램이 복구할 수 없는 심각한 상황을 나타낸다. 이러한 상황은 주로 시스템 레벨에서 발생하며, 프로그램 자체의 문제보다는 주로 시스템 리소스 부족, 가상 머신의 오동작, 하드웨어 장애 등과 관련이 있다.
    • 프로그램이 직접 처리할 수 없으며, 대부분의 경우 프로그램이 종료되거나 예외처리 기능을 사용하여 처리할 수 없다. Error는 주로 시스템 관리자나 개발자에게 알려주는 역할을 한다.
    • 예를 들어, OutOfMemoryError는 메모리 부족으로 인해 발생하는 오류이며, StackOverflowError는 스택 오버플로우로 인해 발생하는 오류이다.
    • 프로세스에 영향을 준다.
  • exception은 프로그램의 예외적인 상황을 처리하는 데 사용되며, 프로그램이 복구할 수 있는 상황을 나타내는 반면, error는 프로그램이 처리할 수 없는 심각한 상황을 나타내며, 주로 시스템 레벨의 문제와 관련이 있다.

11. String vs StringBuilder vs StringBuffer

  • String 
    • 불변(immutable)한 클래스이다. 즉, 한 번 생성된 문자열은 변경할 수 없다.
    • 문자열이 변경되면 새로운 문자열 객체가 생성되며, 기존 문자열은 가비지 컬렉션의 대상이 된다.
  • StringBuilder 
    • 가변적인(mutable)인 문자열을 다루는 데 사용된다. 즉, 문자열을 변경할 수 있다.
    • 내부적으로 가변적인 크기의 문자열을 저장하기 위한 버퍼를 사용하며, 이 버퍼는 동기화(synchronization)를 지원하지 않기 때문에 단일 스레드 환경에서 안전하게 사용할 수 있다.
  • StringBuffer
    • 가변적인 문자열을 다루는 데 사용된다. 그러나 StringBuilder와 달리 StringBuffer는 스레드 안전(thread-safe)한 클래스이다.
    • 멀티 스레드 환경에서 안전하게 사용할 수 있습니다. 여러 스레드가 동시에 StringBuffer 객체를 수정해도 상호간섭없이 안전하게 작동한다.
  • 멀티 스레드 환경에서는 StringBuffer를 사용해야 하지만 대부분의 경우 단일 스레드 환경에서 문자열 조작이 이루어지기 때문에 StringBuilder를 주로 사용한다.  StringBuffer는 동기화를 적용하기 때문에 오버헤드가 발생할 수 있다.

12. C1 컴파일러와 C2 컴파일러의 차이

  • C1 컴파일러 : 빠른 컴파일 시간과 작은 코드 풋프린트를 갖는 환경에서 사용된다. 1~3레벨, 낮은 수준의 최적화
  • C2 컴파일러 : 더 높은 수준의 최적화를 수행하여 더 높은 성능을 제공하는 대규모 서버 및 데스크톱 애플리케이션과 같은 환경에서 사용된다. 4레벨

13. 스프링 부트 + JSP 프로젝트에서 .jar로 빌드하는 방법은 없는가?

  • 스프링 부트 + JSP 프로젝트를 jar로 빌드하면 WEB-INF를 생성하지 못하기 때문에 jsp 파일을 가져올 수 없다.
  • 추가적으로 필요한 resource들을 담아주는 역할도 하는 META-INF를 사용하면 해결가능하다. resource에 jsp를 넣어주는 방법이다. 다음과 같이 WEB-INF를 복사해주고 원래 WEB-INF를 지워준다. 그리고 sub application을 dependency로 활용할 수 있도록 변경을 해줘야 한다.(https://oingdaddy.tistory.com/426 참고)

 

 

 

## 프로젝트

다음 3가지 주제 중 원하는 것 하나 정해서 "카카오 오븐으로 프로토 타이핑", "유저 시나리오 (글 + 그림으로 표현하면 좋음" 작성하기 (유저 시나리오까지 시간 어려우면 프로토 타이핑까지라도)
  • 필라테스, 헬스장 수업 예약
  • 서브웨이, 버거킹 등 음식점 미리 주문하기
  • 여행을 주제로 한 SNS인데, 같은 여행지에 있는 사람 찾기

'공부 > f-lab' 카테고리의 다른 글

f-lab 6주차  (0) 2024.04.24
f-lab 5주차  (0) 2024.04.16
f-lab 3주차  (0) 2024.04.02
f-lab 2주차  (0) 2024.03.26
f-lab 1주차  (0) 2024.03.19

1. 객체 지향 언어가 상태를 가져서 좋은 점은? (절차 지향과 비교)

  • 상태를 알면 행동의 결과를 쉽게 예측할 수 있다. 
  • 상태를 노출시키지 않고 행동으로 캡슐화하기 때문에 객체의 자율성을 높인다.
  • 상태를 이용하면 과거의 모든 이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 수 있음
  • 절차 지향에서는 데이터와 함수가 분리되어 있기 때문에 각각의 함수가 어떤 상태에 영향을 미치는지 추론하기 어렵다.

 

2. JVM에서 Warming Up이란?

  • 프로그램 실행 초기에는 캐시(코드 캐시)에 저장되는 기계어들이 없기 때문에 지연이 발생할 수 있다. 이것을 해결하기 위해 warm up이 필요하다.
  • warm up은 의도적으로 미리 자주 사용되는 로직을 실행시켜 기계어가 캐시에 저장되고 최적화될 수 있도록 하는 것이다. 
  • warm up의 방법에는 여러가지가 있는데, 스프링에서는 주로 ApplicationRunner를 이용해 스프링 애플리케이션이 기동될 때 특정 코드(자주 실행되는)를 실행할 수 있도록 한다. 
  • https://hudi.blog/jvm-warm-up/ 참고
  • https://www.youtube.com/watch?v=CQi3SS2YspY 참고

 

3. 스프링 부트에서 war를 사용할 때 그 이유는?

  • JSP를 사용하여 화면을 구성할 때 - 현재 회사에서 스프링부트에 war 파일을 쓰는 이유
  • 외장 WAS를 사용할 때

 

4. 데드락 해결 방법(예방, 회피 등)

  • 데드락 발생 조건 
    • 상호 배제 : 프로세스끼리 자원을 공유하지 않을 경우. 동시에 프로세스 하나만 해당 자원을 사용할 수 있다.
    • 점유 대기 : 자원을 최소한 하나 보유하고, 다른 프로세스에 할당된 자원을 점유하기 위해 대기하는 프로세스가 존재한다.
    • 비선점 : 이미 할당된 자원을 강제로 뺏을 수 없다. 자원을 반환할 때까지 기다려야 한다.
    • 순환 대기 : 프로세스들이 순환하는 형태로 서로의 자원을 기다린다.
  • 예방 : 데드락 발생 조건 4가지 중 1개가 충족되지 않도록 시스템 디자인
    • 상호 배제 :  프로세스끼리 자원을 공유하도록 설정. 하지만 이 방법은 거의 불가능하다. 프린터, CPU는 모두 동시에 사용할 수 없다.
    • 점유 대기 : 프로세스 실행에 필요한 모든 자원을 한꺼번에 요구하고 허용할 때까지 작업을 보류한다.
    • 비선점 : 추가적으로 자원을 기다려야 하면 다른 프로세스가 자원을 가져갈 수 있도록 한다. 
    • 순환 대기 : 모든 자원에 순서 체계를 부여해서 오름차순으로 자원을 요청. 자원을 한 쪽 방향으로만 요구하도록 한다.
  • 회피 : 실행 환경에서 현재 사용 가능한 자원, 이미 사용중인 자원 등의 정보를 활용해 데드락이 발생할 것 같은 상황을 미리 예측해서 자원을 할당하지 않거나 이미 할당된 자원을 해제함으로써 데드락을 회피한다. Banker Algorithm(은행원 알고리즘)을 사용하는데 자원 요청을 허락했을 때 데드락 발생 가능성이 있으면 자원을 할당해도 안전할 때까지 계속 요청을 거절하는 알고리즘이다.
  • 탐지와 복구 : 데드락을 허용하고 데드락이 발생하면 복구하는 과정. 복구 작업은 데드락을 일으킴 프로세스 중 하나 혹은 여러 개를 중단시키거나, 일시적으로 자원을 선점하는 것을 허용한다.

 

5. 하드디스크 vs SSD (동작 원리 중심으로)

  • 하드디스크 : 기계적인 부품을 사용하여 데이터를 저장한다. 데이터를 읽고 쓰는 데 시간이 더 오래 걸린다.
  • SSD : 반도체 메모리와 전기적인 신호를 이용해 데이터를 저장한다. 시간이 더 짧게 걸린다.

 

6. JVM에서 클래스를 로드하는 타이밍은? / 클래스로더 기초 학습

  • 클래스 로딩 시점 : 클래스의 인스턴스 생성, 클래스의 정적 변수 사용(final 키워드 X), 클래스의 정적 메서드 호출
  • 클래스로더는 런타임 중에 JVM의 메서드 영역에 동적으로 클래스를 로드하는 역할을 한다.
  • 클래스 로드의 단계
    • 로드 : 자바 바이트 코드를 메서드 영역에 저장한다. 로드된 클래스와 부모 클래스의 정보, 클래스와 Interface, Enum의 관련 여부, 변수나 메서드의 정보를 저장한다.
    • 링크 
      • 검증 : 읽어 들인 클래스가 자바 언어 명세 및 JVM 명세에 명시된 대로 잘 구성되어 있는지 검사한다.
      • 준비 : 클래스가 필요로 하는 메모리를 할당하고, 클래스에서 정의된 필드, 메소드, 인터페이스를 나타내는 데이터 구조를 준비한다.
      • 분석 : 심볼릭 메모리 레퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체한다.
    • 초기화 : 클래스 변수들을 적절한 값으로 초기화 한다. 즉, static 필드들이 설정된 값으로 초기화한다.
  • 클래스 로더의 종류
    • 부트스트랩 클래스 로더 : JVM 시작 시 가장 최초로 실행되는 클래스 로더이다. 부트스트랩 클래스 로더는 자바 클래스를 로드하는 것이 아닌, 자바 클래스를 로드할 수 있는 자바 자체의 클래스 로더와 최소한의 자바 클래스(java.lang.Object, Class, ClassLoader)만을 로드한다.
    • 확장 클래스 로더 : 확장 클래스 로더는 부트스트랩 클래스 로더를 부모로 갖는 클래스 로더로서, 확장 자바 클래스들을 로드한다. java.ext.dirs 환경 변수에 설정된 디렉토리의 클래스 파일을 로드하고, 이 값이 설정되어 있지 않은 경우 ${JAVA_HOME}/jre/lib/ext 에 있는 클래스 파일을 로드한다.
    • 시스템 클래스 로더 : 자바 프로그램 실행 시 지정한 Classpath에 있는 클래스 파일 혹은 jar에 속한 클래스들을 로드한다. 쉽게 말하자면, 우리가 만든 .class 확장자 파일을 로드한다.
  • 클래스 로더의 동작 방식
    • 클래스가 호출되면 메서드 영역에 해당 클래스가 로드되어 있는지 확인한다. 있다면 해당 클래스를 사용한다.
    • 정보가 없으면 시스템 클래스 로더에게 클래스 로드를 요청한다.
    • 시스템 클래스 로더는 확장 클래스 로더에 요청을 위임한다.
    • 확장 클래스 로더는 부트스트랩 로더에 요청을 위임한다.
    • 부트스트랩 클래스 로더는 classpath에 해당 클래스가 있는지 확인하고 없다면 확장 클래스 로더에 요청을 넘긴다. 
    • 확장 클래스 로더는 classpath에 해당 클래스가 있는지 확인하고 없다면 시스템 클래스 로더에 요청을 넘긴다. 
    • 시스템 클래스 로더는 classpath에 해당 클래스가 있는지 확인하고 없다면 ClassNotFoundException을 발생시킨다.

 

7. Pass by value vs Pass by Reference

  • 자바는 모든 데이터를 Pass By Value로 전달한다.
  • 객체가 전달되는 경우 복사 후 전달되는 값은 실제 메모리를 가리키는 참조값인 포인터라는 것이다.

 

8. 상속은 주로 언제 쓸까요?

  • 코드 재사용
  • 일반적인 클래스가 이미 구현이 되어 있는 상태에서 그보다 좀 더 구체적인 클래스를 구현하기 위해 사용

 

9. 상속의 단점은?

  • 상속을 제대로 활용하기 위해서는 부모 클래스의 내부 구현에 대해 상세하게 알아야 하기 때문에 자식 클래스와 부모 클래스 사이의 결합도가 높아질 수밖에 없다.
  • 상속 관계는 컴파일 시점에 결정되고 고정되기 때문에 코드를 실행하는 도중에 변경할 수 없다.
  • 따라서 여러 기능을 조합해야 하는 설계에 상속을 이용하게 된다면 모든 조합별로 클래스를 하나하나 추가해야 하는데 이 때 클래스 폭발 문제가 일어난다.
  • 부모 클래스에 메서드를 추가했을 때, 자식 클래스에는 적합하지 않는 메서드가 상속될 수 있다.
  • 부모 클래스에 결함이 있으면 자식 클래스에도 그대로 상속된다.
  • 부모 클래스를 변경하면 자식 클래스도 함께 변경해야 한다.

 

10. 상속과 조합(합성)의 차이

  • 상속은 하나의 클래스를 확장해서 사용하는 것 , 조합은 필드로 클래스의 인스턴스를 참조하게 만드는 설계
  • 상속은 객체 간의 관계가 수직 관계이고 조합은 수평 관계가 된다.
  • 조합은 구현에 대한 의존성을 결합에 대한 의존성으로 변경하여 결합도를 낮춘다.
  • 코드 작성 시점에 결정한 상속 관계는 변경이 불가능하지만 합성 관계는 실행 시점에 동적으로 변경할 수 있다.

 

11. instanceOf 키워드를 사용할 때 문제점은?

    하나의 타입이 여러 인스턴스를 가질 수 있을 때 instanceOf를 사용한다. (상속 관계일 때)

    object instanceOf type : object가 type 을 상속받는 클래스라면 true를 리턴하고 아니라면 false 리턴 

 

  • 추상화 계층을 깨뜨린다(캡슐화가 깨진다) : 추상 클래스를 이용하여 상속을 하면 하나의 추상화 계층이 형성된다. 추상화 계층이 형성되면, 해당 추상화 계층을 사용하는 외부에서는 아래의 하위 문제를 알 필요가 없어진다. instanceof는 추상화 및 캡슐화를 지키지 못한다는 의미를 담고 있다. 상위 계층인 클래스가 하위 계층인 클래스를 직접적으로 알 필요도 없고 알아서는 안된다.
  • OCP(Open Closed Principle, 객체가 확장에는 열려있고 변화에는 닫혀 있어야 한다) 위반 : 새로운 객체가 추가될 때마다 instanceof로 체크하는 로직이 추가되어야 하는데 이렇게 되면 기존의 코드를 계속 변경해야하기 때문에 OCP를 위반하게 된다.
  • SRP(Single Responsibility Principle, 객체는 한 가지의 책임만 가져야 한다) 위반 : instanceof를 사용하지 않으면 상위 계층 클래스를 사용하여 하위 계층 클래스의 로직은 알 필요가 없지만 instanceof를 사용하면 히위 클래스가 책임을 가지게 된다.

 

  • 해결 방법 : 다형성을 사용해서 해결한다.
    • 상위 클래스에 추상 메서드 선언
    • 하위 클래스에 추상 메서드 오버라이딩하여 구현
    • 외부에서 상위 클래스의 추상 메서드를 사용하여 메세지 전달

 

12. 얕은 복사 vs 깊은 복사

  • 얕은 복사 주소값을 복사하는 것이고, 깊은 복사 실제 값을 새로운 메모리 공간에 복사하여 저장하는 것이다.
  • 얕은 복사의 경우는 주소값을 복사하기 때문에 참조하고 있는 값이 같다. 복사한 객체가 변경되면 기존의 객체도 변경된다.
CopyObject original = new CopyObject("JuHyun", 20);
CopyObject copy = original; //얕은 복사
  • 깊은 복사
    • cloneable 인터페이스 구현 
public class CopyObject implements Cloneable //인터페이스 구현


CopyObject original = new CopyObject("JuHyun", 20);
CopyObject copy = original.clone(); //깊은 복사
  • 복사 생성자, 복사 팩토리
/* 복사 생성자 */
public CopyObject(CopyObject original) {
    this.name = original.name;
    this.age = original.age;
}

/* 복사 팩터리 */
public static CopyObject copy(CopyObject original) {
    CopyObject copy = new CopyObject();
    copy.name = original.name;
    copy.age = original.age;
    return copy;
}


CopyObject original = new CopyObject("JuHyun", 20);
CopyObject copyConstructor = new CopyObject(original); //복사 생성자를 통한 깊은 복사
CopyObject copyFactory = CopyObject.copy(original); //복사 팩토리를 통한 깊은 복사

 

 

13. 인터페이스란?

  • 추상화된 형태의 계약으로, 해당 인터페이스를 구현하는 클래스가 가져야 할 메서드의 시그니처를 정의한다. 이러한 메서드는 구현되지 않고 단지 선언만 되어 있으며, 실제로는 해당 인터페이스를 구현하는 클래스에서 메서드를 구현해야 한다. 이를 통해 다형성을 구현하고 객체 간의 느슨한 결합을 가능하게 한다. 인터페이스는 코드 재사용을 높이고, 코드 유지보수를 용이하게 한다.
  • 다형성이라는 객체 지향의 특징을 구현하는 핵심
  • 객체의 내부 구현이 어떻든 깊이 알 필요없이 필요한 메서드만 호출하고 원하는 결과 값을 제대로 받게 해주는 간편한 상호작용 기능
  • 인터페이스의 역할
    • 프레임워크의 내부구성 학습 없이 지원해주는 메서드를 이용하여 간편하게 프로그램을 개발할 수 있게 해준다.
    • 일종의 '스펙'을 지정하게 하여 소프트웨어 확장을 유리하게 한다.
  • 추상화를 통해 관련 있는 메서드들의 집합을 정의한다.
  • 메서드의 명세만을 가지고 있고(시그니처만 선언하고) 메서드에 대한 구현부분은 없다.
  • 다중 상속이 가능하다. 한 클래스에서 여러 인터페이스를 구현할 수 있다.
  • 자바 API에서도 Comparable, Runnable, Serializable 등의 인터페이스를 구현하고 있다.
  • 위의 세가지 인터페이스는 마커 인터페이스. 아무 메서드도 선언하지 않은 인터페이스. 객체의 타입과 관련된 정보만을 제공한다. 
  • 인터페이스에서는 구현체 간의 일관된 동작을 보장하고 상태의 변경을 허용하지 않아야 해서 필드를 상수로만 선언할 수 있다.
  • 자바8 이후부터는 디폴트 메서드와 스태틱 메서드를 통해 구현 메서드를 정의할 수 있다.
  • 인터페이스 사용의 장점
    • 인터페이스 다형성 : 클래스가 여러 개의 인터페이스를 구현하게 되면 변수로 타입으로도 다양하게 쓸 수 있다는 말이다. 인터페이스 타입으로 변수를 선언하면 사용하는 입장에서는 뒤에 오는 모든 인터페이스만 구현한 객체이면 되기 때문에 시스템이 더 유연해진다. 적당한 인터페이스가 있다면 반환값, 변수, 필드, 매개변수를 인터페이스로 사용하면 좋다.
    • 형제 관계를 맺어줌 : 아무 관계도 없는 클래스들에게 공통적인 인터페이스를 구현함으로 관계를 맺어줄 수 있다.
    • 타입 접근 제한 
    • 메서드 접근 제한
  • https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4Interface%EC%9D%98-%EC%A0%95%EC%84%9D-%ED%83%84%ED%83%84%ED%95%98%EA%B2%8C-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC 참고

 

14. 인터페이스 vs 추상클래스   

    자바에서 인터페이스와 추상클래스는 객체 지향 프로그래밍의 다형성을 구현하는 요소이다. 공통적으로 인스턴스를 생 
    성할 수 없으며, 하나 이상의 추상 메서드를 포함한다.

 

    인터페이스는 모든 메서드가 기본적으로 추상 메서드이고 추상 클래스는 추상 메서드와 일반 메서드 모두를 포함한다.
    인터페이스는 구현할 기능의 '계약'을 정의하고, 추상 클래스는 '계승'을 통해 기능을 확장하거나 일부 구현을 제공한다.

 

  • 인터페이스 : 클래스와 별도로 구현 객체가 같은 기능을 한다는 것을 보장하기 위해 사용한다. / 추상클래스 : 클래스 간의 연관 관계를 구축하는 데 초점을 맞춘다.
  • 인터페이스의 장점
    • 다중 상속의 문제를 해결하고 클래스 간의 느슨한 결합을 가능하게 한다. 
    • 구현 클래스가 인터페이스의 메서드를 반드시 구현해야 하므로 일관된 API를 제공할 수 있다.
    • 한 클래스가 여러 인터페이스를 구현할 수 있으므로 다양한 기능을 조합하여 사용할 수 있다.
    • 메서드의 시그니처만을 정의하기 때문에 구현 클래스는 인터페이스가 요구하는 메서드를 자유롭게 구현할 수 있다. 
    • 시스템의 확장성과 유지보수성을 향상시키는 데 기여한다.
  • 추상클래스의 장점
    • 공통적인 일부 기능을 구현하고 나머지는 상속받는 클래스에서 구현하도록 강제하는 데 사용된다.
    • 코드의 재사용성을 높이고 일관된 구현을 보장한다.
    • 상속받는 클래스에 대한 공통의 템플릿을 제공하므로, 설계 단계에서는 클래스 계층구조를 명확히 할 수 있다.
    • 인스턴스 변수를 가질 수 있으므로 상속받는 클래스들이 이 변수들을 공유하거나 활용할 수 있어서 데이터 관리에 유용하다.
    • 상속을 통한 기능의 확장에 초점을 맞추므로 특정 기능을 계승하고자 할 때 유리하다. 이는 클래스 간의 결합을 형성하지만 효율적인 코드 재사용을 가능하게 한다.

 

15. 언제 인터페이스를 사용하고 언제 추상클래스를 사용하는지?

  • 인터페이스 : 인터페이스에 정의된 메서드를 각 클래스의 목적에 맞게 기능을 구현 / 추상클래스 : 자신의 기능들을 하위 클래스로 확장
  • 추상클래스는 미리 논리적인 클래스 상속 구조를 만들어놓고 사용이 결정되는 느낌, 인터페이스는 그때 그때 필요에 따라 구현해서 자유롭게 붙였다 뗐다 하는 느낌
  • 추상클래스를 사용하는 경우
    • 상속 받을 클래스들이 공통으로 가지는 필드와 메서드들이 많아 중복 맴버를 통합할 경우
    • 멤버에 public 이외의 접근자들의 선언이 필요할 경우
    • non-static, non-final 필드 선언이 필요한 경우(각 인스턴스에서 상태 변경을 위한 메서드가 필요한 경우)
    • 요구사항과 함께 구현 세부 정보의 일부 기능만 지정했을 경우
    • 하위 클래스가 오버라이드하여 재정의하는 기능들을 공유하기 위한 상속 개념을 사용할 경우
    • 추상 클래스는 이를 상속할 각 객체들의 공통점을 찾아 추상화시켜 놓은 것으로, 상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하며 부모 클래스가 가진 기능들을 구현해야 할 경우
  • 인터페이스를 사용하는 경우
    • 어플리케이션의 기능을 정의해야 하지만 그 구현 방식이나 대상에 대해 추상화 할 때
    • 서로 관련성이 없는 클래스들을 묶어주고 싶을 때 (형제 관계)
    • 다중 상속(구현)을 통한 추상화 설계를 해야할 때
    • 특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지는 신경쓰지 않는 경우
    • 클래스와 별도로 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용

 

16. 프로젝트 주제 후보

  • 필라테스/헬스장 수업 예약 시스템
  • 음식점 주문 시스템(서브웨이, 버거킹 등)
  • 여행 SNS (여행 동행자 찾기, 여행지 공유 등의 기능)

'공부 > f-lab' 카테고리의 다른 글

f-lab 6주차  (0) 2024.04.24
f-lab 5주차  (0) 2024.04.16
f-lab 4주차  (0) 2024.04.09
f-lab 2주차  (0) 2024.03.26
f-lab 1주차  (0) 2024.03.19

+ Recent posts