로드맵 파헤치기
— Java, Server, CS — 15 min read
서론
roadmap 을 보면서, 내가 아는 것도 어렴풋이 알고 있고 모르는 건 아주 화끈하게 모른다는 점을 알게 되었다. 머릿속에 정리가 안되는 찜찜한 상태로 있기 보다는, 일단 위키를 만들어서 써내려가기로 했다. 최대한 2-3줄 안에 정리하는게 목적인데 잘 될지는 ! 😮 상세한 설명을 한 나의 블로그 글이 있으면 첨부한다.
CS 기본 지식 관련 질문 (네트워크 / 자료구조 / OS / 알고리즘)
OSI 7계층에 대해 아는 대로 말해주세요.
- physical (1) e.g) Fiber / wireless (실제로 회선으로 넘기는 단계)
- data link (2) e.g) ethernet
- network layer (3) e.g) IP , ARP
- transport layer (4) e.g.) TCP (Transmission Control Protocol), UDP
- session layer (5) e.g) socket / APIs
- presentation layer (6) e.g.) SSL, SSH
- application layer (7) e.g) HTTP, FTP, SSH, DNS
데드락 , 데드락 해결
교착상태, 자원을 가진 프로세스가 서로의 자원을 위해 대기하는 상황
- mutual exclusive (상호배제) : 한번에 한프로세스만 자원을 사용
- 점유 대기 : 최소 하나의 자원을 보유하고 다른 프로세스의 자원을 위해 대기함- 순환 대기: 대기 프로세스의 집합이 순환 상태로 자원을 대기하고 있다.
- 비선점: 자원을 강제로 뺏을 수 없다.
이 중 하나만 풀어줘도 데드락이 풀림
prevention
여러개가 동시에 (mx 없앰)
한번에 여러개를 요구
순환이 없도록 한 방향으로
선점 우선순위를 넣음
비효율적이거나 동기화 문제 발생할 수 있음
avoidance 모든 자원을 데드락을 발생시키지않을 수 있게 분배가 가능한 상황 - safe state / 그 순서를 safe sequence라고 부름 은행원알고리즘(by 다익스트라)
- 총 자원을 알고 있어야하는 문제가 있음
detection 현재 자원의 할당 상태로 detect
회복방법
- 단순히 프로세스를 1개 이상 종료
- 자원 선점하기
64bit CPU / 32bit CPU
register의 크기가 일단 다르게 됨 연산량이 달라질 뿐 아니라 32bit CPU 에는 4GB 메모리만 가능
32bit = 4294967296 개의 주소값 사용 가능 주소값은 하나에 1byte이고, 이 주소값이라는 것은 메모리의 위치를 의미하므로 4294967296 이상의 메모리의 주소를 알수없음
2^32 1byte = 2^30 2^2 byte = 4 GB 이므로 4GB 메모리. 실제로는 다 인식하기도 어려움. RAM / VGA 메모리등 색인 윈도우는 3.3GB로 정해놨다고함
TCP 와 UDP 의 차이점은 무엇일까요?
OSI 레이어에서 전송 계층 (transport) 데이터의 패킷을 추적 관리
- TCP (Transmission Control Protocol): 안정성, 순서보장(3-handshake(연결 설정), 4-handshake(연결해제) 많은 어플리케이션이 tcp 기반, 흐름 제어 및 혼잡 제어, 1:1 연결, 응답과 재전송 요청등 때문에 성능이 낮고 스트리밍에 불리, 소켓 기반으로 데이터 전송
- UDP (User Datagram Protocol): 속도가 빠름, 순서보장이 안됨, 주로 VoIP, 하나의 경로가 없이 나눠진 패킷들이 각각 다른 경로로 가게 될 수 있음. (독립적), 정보를 주고 받을 때 신호절차를 거치지않기 때문에 신뢰성은 낮지만 TCP 보다 속도가 빠르다. 서버 - 클라이언트 간 N:M 연결이 가능
API 에 대해 설명해주세요
제품, 서비스가 서로 내부 구현을 알지 못해도 커뮤니케이션을 할 수 있도록 한 명세를 의미.
API를 사용하면 구현 방식을 알지 못해도 제품 또는 서비스가 서로 커뮤니케이션할 수 있으며 애플리케이션 개발을 간소화하여 시간과 비용을 절약할 수 있습니다. 새로운 툴과 제품을 설계하거나 기존 툴과 제품을 관리하는 경우 API는 유연성을 제공하고 설계, 관리, 사용 방법을 간소화하며 혁신의 기회를 제공합니다.
인터넷이 무엇인가요?
레퍼런스 없이 생각해봤을 때.. internet 이라는 이름부터 파고 들어보자. internet, net 은 여기서 network 이다. 네트워크는 노드와 엣지로 이루어져 정보를 교환하는 '망'을 의미한다.(net) inter-net 은 이 네트워크끼리 소통하는 더 커다란 의미의 네트워크를 의미한다고 볼 수 있다.
소비자 입장에서 생각해보면 인터넷은 타인의 노드(device)에 브라우저를 통해서 자유롭게 접근하는 망을 의미한다. 이 노드 간 연결은 어떻게 되냐고? 레이어를 쭉 타고 내려가야겠지만 일반적인 인터넷 연결은 TCP-IP를 지나... 노드간에 전송인 transport layer? - data layer - physical layer 까지 거쳐서 정보를 전송한다.
정렬의 종류 및 특징을 설명해 주세요.
안정정렬 / 불안정 정렬
- 정렬되지 않은 상태에서 중복된 값(같은 키 값)의 정렬 이후에도 입력 순서와 동일하게 정렬 - 안정 e.g.) 포커카드를 숫자를 기준으로 정렬했을 때, 5로 겹치는 값은 무늬 순서가 일정하다
bubble sort
- 안정 정렬
- O(n^2)
insertion
- 안정
- O(n^2)
- 기존 자료의 정렬 정도에 따라 최선이 O(n)
- 앞의 정렬된 배열 부분과 비교하여, 자신의 ㅊ위치를 찾아서 삽입함으로써 정렬을 완성.
- 두번째부터 시작
selection sort
- 최솟값 / 최댓값의 자리는 정해져있고, 전체를 탐색하면서 그 자리에 맞는 걸 찾음
- 불안정 but 제자리 정렬 (추가메모리 필요없음)
- O(n^2)
quick sort
- 불안정
- pivot을 잘못정하면 최악 O(n^2), 평균적으로 O(nlogn)
- merge sort
- 안정
- 파일시스템에서 사용
- 추가 메모리 공간 필요
- heap sort
- 불안정
- O(nlogn)
- 추가 메모리 필요
- heap 구조를 만족하도록 하면서, 삽입시 heapify 를 통해 정렬을 맞춰줌
- heap 속성을 맞추지않은 상태에서는 루트부터 시작해서 맞춤
- insert 는 비어있는 가장 아래의 leaf 노드의 가장 왼쪽부터 채워서, 아래부터 맞춰줌
WAS의 동작방식에 대해서 설명해주세요.
Web Application server 는 로직을 요구하는 동적인 컨텐츠를 http 통신을 통해 제공하는 기능을 담당. servlet 구동환경을 제공하는 서버이기도 함. e.g) tomcat
- 클라이언트의 요청에 맞는 servlet을 메모리에 올린다.
- web.xml 을 참조해 해당 서블릿에 대한 쓰레드를 생성한다.
- httpservlet request / response 객체를 생성하고, 그에 맞는 doGet / doPOST 메소드를 호출해 생성된 동적 페이지를 response 객체에 담아 was 에 전달한다.
- was 는 http response 형태로 바꾸어 웹서버에 전달하고, 생성된 스레드 / servlet request / response를 제거한다.
+) 스프링과 결합할 때..
- spring mvc에서는 dispatcher servlet이라는 모든 요청 담당 서블릿으로 컨트롤러에 위임함.
- servlet : 웹페이지 / 결과값을 동적으로 생성하는 역할을 하는 자바 프로그램
내장 tomcat 내부의 servlet container (~ dispatcher servlet ) 에서 spring container 로 통신! 이때 handler mapping / adaptor를 통해서 대상 컨트롤러를 확인하고 요청을 보냄
=
- Client -> Web server 으로 request 보냄
- 동적 Web server -> Servlet container로 전달
- Servlet container 쓰레드 생성
- DispatcherServlet init (서블릿 생성 안되어 있을경우)
- 생성된 쓰레드에서 DispatcherServlet service() 메서드 호출
- HandlerMapping을 통해 매핑 컨트롤러 조회
- HandlerAdapter를 통해 매핑 컨트롤러에 request 전달
- 개발자가 구현한 Controller -> Service -> Repository … 동작
세션과 쿠키를 사용하는 이유는 무엇일까요?
쿠키와 세션 ! http 프로토콜
- connectionless
- 클라이언트에게 요청을 반환하면 그 연결을 끊어버리는 특징
- keep-alive 로 conneciton을 재활용할 수 있음 (http 1.1 에서는 이것이 기본)
- stateless
- 통신이 끝나면 상태를 유지하지 않음
이렇게 안쓰고 싶을 때 쿠키 / 세션
쿠키 : 클라이언트 사이드에서 저장되는 key-value의 데이터 타입. 유효시간을 명시할 수 있으며, 그렇게 되면 브라우저 종료해도 인증이 유지됨. 클라이언트에 300개 까지 쿠키 저장 가능 response header에 set-cookie를 사용하면 클라이언트 쪽에 쿠키를 만들어줄 수 있음 따로 요청하지않아도 request 시 날아간다.
세션 : 서버 측에서 관리하는 데이터. id를 부여하며, 웹 브라우저가 서버에 접속해서 브라우저를 종료할때까지 인증상태를 유지함. 접속시간에 제한을 두어서 응답이 없으면 정보가 유지되지않게 설정. 쿠키보다 보안은 좋지만, 서버 메모리를 차지하고(동접이 많으면 서버에 과부하)
아래는 스토리지 관점에서.. 쿠키, 로컬 스토리지, 세션 스토리지 5초만에 알기
해시테이블에 대해 설명해주세요.
key-value 구조로 데이터를 빠르게 검색이 가능한 자료구조중 하나. 내부적으로 bucket (배열) 을 사용하여 데이터를 저장하고, 각각 키에 해시함수를 적용해서 저장될 버킷을 정하게 된다.
쓰레드와 프로세스의 차이는 무엇일까요?
프로세스
- 실행되고 있는 컴퓨터 프로그램 자체
- 운영체제로 부터 시스템 작업을 할당받는 자원의 단위
- code / data/ stack / heap 의 구조를 가진 메모리를 할당 받음
쓰레드
프로세스에서 실행되고 있는 흐름 단위
프로세스 내에서 공유 / 비공유 파트가 있고, 병렬 실행
- stack만 비공유
- code / data / heap 은 공유
하드웨어 스레드는 os가 스케쥴 해줄 수 있는 최소 단위의 일
여기서의 스레드는 소프트웨어 스레드를 의미한다. 이 스레드는 소프트웨어 상에서 병렬적으로 task 를 나누고, 일을 할당할 때 쓰인다. 이 스레드가 고대로 하드웨어 스레드에 올라가서 사용된다. 즉, 소프트웨어 스레드가 100개가 있다고 하더라도 동시에 실행될 수 있는 스레드는 하드웨어 스레드 갯수와 같다.
MVC 패턴에 대해서 설명해주세요.
Model - View - Controller DB에 저장되며 - 도메인을 코드화한 Model, 사용자에게 보이는 부분인 View, 이 두개의 매개가 되어주는 Controller
Spring / Java / OOP
Spring이 무엇인가요?
스프링은 복잡한 엔터프라이즈 애플리케이션을 효과적으로 개발하기 위한 기술이다.
JavaBean
아래 두가지 관례에 따라 만들어진 오브젝트
- 디폴트 생성자: 자바빈은 파라미터가 없는 디폴트 생성자를 갖고 있어야 한다. 툴이나 프레임워크에서 리플렉션을 이용해 오브젝트를 생성하기 때문에 필요하다.
- 프로퍼티: 자바빈이 노출하는 이름을 가진 속성. getter, setter
Spring의 Bean, BeanFactory
- 빈 : 스프링 컨테이너가 생성, 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트
- 빈팩토리: 빈 생성, 관계설정 같이 제어를 담당하는 IoC 오브젝트
- application context : 빈 팩토리를 확장한 IoC 컨테이너, 빈 팩토리의 기능 + 스프링이 제공하는 각종 부가 서비스를 추가로 제공 빈 팩토리라고 부를 때는 주로 빈 생성과 제어의 관점, 애플리케이션 컨텍스트라고 할 떄는 스프링이 제공하는 애플리케이션 지원 기능을 포함하는 것 ApplicationContext는 BeanFactory를 상속
상속이 반드시 좋은 방법이 아닌 이유
상속을 통한 상하위 클래스의 관계는 생각보다 밀접해있어 다른 관심사 간 긴밀한 결합을 허용한다. 상속을 통해 만들어진 구현체가 중복을 발생시킬 수 있다.
IoC (Inversion of Control)
제어의 역전이란 이런 제어 흐름의 개념을 거꾸로 뒤집는 것이다. 즉 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않는다! 당연히 생성하지도 않는다. 모든 제어 권한을 다른 대상에게 위임하기 때문이다. 예를 들어, 서블릿을 개발해서 서버에 배포할 수 있지만 서블릿의 실행을 직접 제어할 수 있는 방법은 없다. 프레임워크도 제어의 역전 기술이 적용된 대표적인 기술이다. 흔히 라이브러리와 혼동하고는 하는데, 큰 잘못이다. 우리는 라이브러리를 능동적으로 사용한다. 반면 프레임 워크는 거꾸로 애플리케이션 코드가 프레임워크에 의해 사용된다. 즉 우리는 스프링 없이도 작은 IoC 프레임워크를 사용한 셈이다. 제어의 역전에는 프레임워크 혹은 컨테이너와 같이 애플리케이션 컴포넌트의 생성과 관게설정, 생명주기 관리 등을 관장하는 존재가 필요하다. 단순한 적용이면 우리의 예제로 충분하지만, 애플리케이션 전반에 IoC를 사용하고 싶다면 스프링과 같은 IoC 프레임워크의 도움을 받는 편이 유리하다. 🦦
JVM, JRE, JDK 를 설명해주세요.
java virtual machine (환경)
자바 가상 머신. 소스코드로 만들어지는 자바 바이너리 파일 (.class) 를 실행할 수 있음.
자체적으로는.. 환경(플랫폼) 의존적이지만, JVM 이 있어 컴파일된 파일은 어떤 JVM 에서도 동작시킬 수 있다.
java run env
- JVM 이 자바프로그램을 동작시킬때 필요한 라이브러리와 기타 파일을 가지고 있음.
- JVM 의 실행환경.
java development kit
자바 클래스 라이브러리(Java class libraries)와 자바 클래스 로더(Java class loader), 자바 가상 머신(Java Virtual Machine)이 포함된다.
JDK 안에 JRE. JRE + 개발을 위해 필요한 도구 (javac, java )
final 키워드에 대해 설명해주세요.
변수의 상수화 (modification 불가능)
- get 만 가능
- 메소드에 사용된 경우, 오버라이딩 불가능 🤨
- 클래스에 사용된 경우, 상속이 불가능
Checked Exception / Unchecked exception
우리가 예외적인 조건 이라고 말할 때는 이 세가지 경우 중 하나를 의미합니다.
Checked Exceptions
개발자도 예상하고 대처할 수 있는 exception
컴파일러가 명시적으로 고쳐달라고 함
트랜잭션을 롤백하지 않음
Unchecked Exceptions / Runtime Exceptions (같다고 생각하시면 됩니다.)
runtime exception의 상속체
트랜잭션을 롤백함
Errors
대처법
- throws / throw
- try - catch
- try - catch - finally
- try with resources
영속성 컨텍스트 - JPA (/hibernate)
엔티티를 저장하는 환경. 하나하나를 식별자로 구별한다. entitymanager 하나 당 하나의 context가 만들어짐!
JPA는 트랜잭션을 커밋하는 순간, 영속성 컨텍스트에서 새롭게 저장된 엔티티를 데이터베이스 반영함. 커밋 전에는, 영속성 컨텍스트에 있고. (1차 캐시, map 형태로 엔티티를 저장)
- 1차 캐시에서 인스턴스를 반환하기 때문에 같은 객체임을 보장한다.
- 쓰기 지연 지원 (커밋 전까지는 DB에 저장하지 않고, 내부에 쿼리를 생성해둠)
- flush 시점에 스냅샷과 엔티티를 비교해서 변경된 entity를 찾는다.
- 지연로딩(프록시 객체를 로딩해두고, 실제 사용할때만 영속성 컨텍스트를 통해 데이터를 불러오는 방법)
n+1 문제
1: N 상황에서, 하위 엔티티들을 첫 쿼리 실행시에 한번에 가져오지 않고, lazy loading으로 가져올 때 쿼리가 실행될 때 쿼리가 과도하게 늘어나는 현상
예를 들어, 게시글 1: 리뷰 N 개로 엔티티 관계가 맺어져있다 (ManyToOne(FetchType Lazy))고 하면 게시글 목록 A개를 가져오는 로직 실행시 게시글 가져오는 쿼리 (1) + 각 게시글마다 리뷰를 가져오는 쿼리 (A개) 식으로 쿼리가 늘어나게됨
해결 방법)
- FetchType을 eager로 (가져올 때 가져오도록)
- fetch join 를 사용
open session in view
true일 경우, 영속성 컨텍스트가 트랜잭션 범위를 넘어선 레이어까지 살아있다.
api 라면 클라이언트에게 응답될 때까지
view 반환이면 view 렌더링까지 영속성 컨텍스트가 살아있음
영속성 컨텍스트가 살아있으면 수정이 가능, 기본값은 true
db connection을 계속 갖고 있음. 성능이 중요하다면 false로 ..
@Transactional 동작과정
Spring에서, 바이트 코드 위빙 같은 고급기술을 활용할 수는 없고 + 그렇다고 내가 작성한 자바코드에 재작성할수도 없음. 대신 IoC Container를 사용해서 트랜잭션 프록시를 인스턴스화해서, 마치 코드를 넣는 것처럼 동작하게 함. 트랜잭션 처리를 트랜잭션 매니저에게 위임해서 처리하게 함.
@Transactional
을 찾으면, 빈의 다이나믹 프록시를 만들어서! 해당 빈이 트랜잭션 매니저에 접근하고, JDBC 방식으로 트랜잭션 매니저가 코드를 실행해줌.
propagation level
- required : 트랜잭션을 필요로 하긴 함 (재사용이나 새로 만드는 방식은 일단 상관하지않겠음)
- supports : JDBC 가 아무것도 하지않음. 트랜잭션이 있어도 상관없음 1
- mandatory: 트랜잭션이 꼭 필요해 but 내가 안만듬
- required_new: 새로 트랜잭션 만들어서 함
아ㅠㅠ 토비에 있었는데! 추가로 이해 필요
hibernate와 결합하면..
hibernate는 sessionFactory 로 트랜잭션을 관리함.
스프링의 @Transcational
은 모름
DataSourcePlatformTransactionManager -> Hibernate/JPA Transaction Manager로 이미 통합해둠!
자바 컬렉션 종류와 특징에 대해 설명해주세요.
ArrayList
- 순서가 있고, 중복 허용, 인덱스를 통한 랜덤 액세스
Set
- 순서가 없고, 중복을 허용하지않음. 랜덤 액세스 불가능
Map (HashMap)
- key-value 구조의 저장방식, key를 통한 액세스 가능
- Hashmap은 hashtable을 통한 저장방식을 지원
자바 코드의 실행 과정을 설명해주세요.
컴파일 (.class) -> 메모리 로딩 -> jvm 메모리에 올려짐 (heap / stack / native / class) 함수가 실행될때마다 stack 에 저장되며 할당할 때마다 heap 을 사용하여 실행됨.
자바의 메모리 영역에 대해 설명해주세요.
JVM 메모리 - heap, java stack, class, native method
method (static)
- jvm 이 읽어들인 클래스, 인터페이스의 런타임 상수 풀, 필드, 클래스 변수
stack
- 스레드마다 하나씩.
- 메소드 호출할때마다.
- 원시타입 변수는 여기에 값을 가짐
native method
- JNI 등을 통해 호출되는 자바외 언어 네이티브 코드를 위한 스택
여기에서 gc를 하고 인식하는 메모리 영역은 힙
모든 자바 클래스의 인스턴스와 배열이 할당되기도 함.
heap 에서 young / old / perm (permanent 로 나뉘게됨)
- young (young space)
- old와 permanent가 있는 old space
young space가 가득차면 young collection을 실행하여 gc를 한다. 어느정도 오래 머문 객체는 old space로 이동한다.
객체지향 프로그래밍에 대해 설명해주세요.
- 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법
spring interceptor / filter
servlet request -> filter -> dispatcher servlet -> interceptor -> aop -> controller 순
filter
- 응답 자체를 거르고 정제함. dispatcher servlet 전에 실행
- 자원 처리 끝나고 정제처리 가능
- 인코딩, 체크
interceptor
- 스프링 내부에 있음
- 스프링의 모든 빈 객체에 접근가능
- 여러 개 사용 가능
- preHandler
- postHandler
스트링과 스트링버퍼의 차이에 대해 설명해주세요.
- new 로 생성하는 방법
- heap 영역에 저장
- 리터럴 생성
- string constatnt pool 에 저장, 동일 문자열은 동일 주소값 반환
- 자바 7까지 perm -> heap 으로 바뀌었다구함(perm은 고정이라 OOM 될까봐)
String: 불변성
- 수정하는 시점에 새로운 인스턴스, but 변하지않는 문자열은 괜찮은 성능
String buffer / builder : 가변성
- 동일 객체내에서 문자열 변경 가능
new StringBuffer("hello");
sb.append("Hello")
- buffer : 동기화 키워드를 지원해서 멀티쓰레드에 안전
- builder: 동기화 지원하지않음, but 단일쓰레드성능이 뛰어남
자바의 데이터 타입인 Primitive Type(기본형) 에 대해 말해보세요.
int / float / double / long /short ?
object를 상속한 객체타입이 아니기때문에 null을 받을 수 없지만, wrapper class를 unbox 하는 과정이 없기때문에 연산속도가 빠르다!
접근제어자의 종류와 특성에 대해 설명해보세요.
- public / protected / private
- 모든 class / 같은 패키지 / 같은 클래스
Interface와 Abstract에 대해 말해주세요.
- abstract 부터 설명
- 구체적인 구현이 없는 명세에 해당하는 메소드 (혹은 클래스) 에 부여하는 accessor..?
- abstract class는 abstract method가 하나라도 있는 클래스를 말하고, 구체적인 메소드가 있어도됨
- interface는 모든 메소드가 추상메소드의 형태를 띄는 클래스를 의미.
쓰레드를 구현하기 위한 인터페이스, 클래스는 무엇이 있나요?
- Thread 클래스
- run 메소드만 오버라이딩
- Runnable 인터페이스
- 인터페이스니까 다중 상속 구현 가능
static 키워드에 대해 설명해주세요.
- 인스턴스가 공유하는 것이 아닌 class 레벨에서의 값들을 지정할 때 사용하는 키워드
- 필드일수도, 메소드일수도 있음
오버로딩과 오버라이딩에 대해 설명해주세요.
- 오버로딩 : 같은 함수명, 다른 메소드 시그니처가 가능한 것
- 오버라이딩 : 상속에서 부모 클래스의 함수를 재정의해서 사용하는 것
디자인 패턴
Singleton
어떤 클래스를 애플리케이션 내에서 제한된 인스턴스 개수(1개)만 존재하도록 강제 private 생성자를 갖고 있기 때문에 상속할 수 없다 객체지향의 장점인 상속과 이를 이용한 다형성을 적용할 수 없다. 기술적인 서비스만 제공하는 경우라면 상관없지만 애플리케이션 로직을 담고 있는 일반 오브젝트의 경우 싱글톤이 되면 객체지향의 장점을 적용하기 어렵다. 싱글톤은 테스트하기 힘들다(큰 단점) 싱글톤으로 되어 있어 테스트할때 mock 오브젝트로 대체하기 힘들기 때문에 직접 다 만들어서 사용할 수 밖에 없는데 이런 경우 테스트 오브젝트로 대체하기 어렵다. 서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다. 클래스 로더를 어떻게 구성하고 있느냐에 따라 싱글톤 클래스임에도 하나 이상의 오브젝트가 생길 수 있음. 여러 JVM에 분산되어 설치되는 경우에도 각각 독립적으로 오브젝트가 생기기 때문에 싱글톤으로서의 가치가 떨어짐 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다 싱글톤은 사용하는 클라이언트가 정해져있지 않고 스태틱 메서드로 언제든지 접근할 수 있기 때문에 자연스럽게 전역 상태로 사용되기 쉽다. 아무 객체나 자유롭게 접근하고 수정하고 공유할 수 있는 것은 객체지향 프로그래밍에서는 권장되지 않는 모델이다.
DB / Data Processing
데이터베이스 정규화 과정에 대해 설명해주세요.
정규화는 하나의 릴레이션에 하나의 의미만 존재하도록 릴레이션을 분해하는 과정이다.
제 1정규화 중복되는 항목이 없어야한다 (도메인이 원자값으로 되어있어야한다.)
제 2정규화 부분 함수적 종속 관계를 제거해야 함 위 테이블에서 candidate key는 종업원 + 기술이다. 그런데 근무지는 종업원이 근무하는 곳이므로 항상 종업원에 종속적인 관계를 갖는다. 키의 일부에만 종속적인 관계를 가지는 것을 부분 함수적 종속 관계라고 하며,
제3정규형(3NF) 이행 함수적 종속 제거 ( x→ y→ z), transitive하지 않게 하기! 대회 + 연도를 키로 우승자가 결정된다. 또 우승자에 따라서 우승자 생년월일이 결정된다. 즉 x → y , y → z 인 관계를 이행 함수적 종속 이라고 한다.
BC(Boyce-codd) 정규형 (BCNF) 결정자이면서 후보키가 아닌 것을 제거하는 정규형
Caching - CDN / Redis
Redis: 메모리 기반의 key-value 스토리지. 빠르고, 다양한 데이터 구조체를 지원함
- 큐, Cache, dictionary, 세션 용도로 다양하게 사용함
- 데이터 유실을 그래도 막기 위해서 두가지 방식 사용
- 스냅샷
- AOF (Append on File): 명령어 로깅
- 싱글 스레드
CDN: 서버와 사용자 사이의 물리적 거리를 줄여서 웹 페이지 로드 지연을 최소화하는 네트워크 (Contents Delivery Network)
데이터베이스 인덱스와 동작 방식
추가적인 쓰기와 저장공간을 활용하여 데이터베이스 테이블의 검색속도를 향상시키기 위한 자료구조.
- 약 10%에 해당하는 저장공간
- 인덱스 관리 작업이 필요함
대표적인 자료구조는 hashtable / b+tree
해시는 등호 연산만 특화되어있어서 부등호 연산이 자주 사용되는 db 검색의 경우 해시테이블이 적합하지않음.
b+tree는 자식 노드가 2개 이상인 b-tree를 개선시킨 자료구조
- 리프노드만 인덱스 + 데이터이고, 나머지는 모두 인덱스만 갖는다.
- 리프 노드들이 linked list로 연결되어있다.
NoSQL
RDBMS에서의 문제 (대용량 서비스, 비용적 문제, 데이터 분산)...을 해결하기 위해 등장한 schema-free 한 구조의 데이터베이스.
e.g.) MongoDB
- document based
- 자체적으로 분산처리, 샤딩, 데이터 리밸런싱, 복제, 복구등을 지원
- 레코드, 칼럼, 인덱스..
- 어떤 데이터도 저장할 수 있음, read /write가 뛰어남, scale out 구조 / coversion -mapping 가능
- join이 없어서, 필요없도록 데이터 구조화 필요
- memory mapped file로 파일 엔진 DB.
- SQL 을 완전히 이전할 수 없음.
Data Replication
복제(Replication)은 같은 데이터의 복제본을 네트워크로 연결된 여러 머신에 나눠서 보관하는 일을 말함.
데이터가 계속 변하기때문에 복제가 어려움.
- single leader
- multi leader
- leader less
다뤄야할 문제 :
- sync / async 할 것인지
- 현실적으로 모든 팔로워가 sync한 상황은 어려움
- 보통 완전 비동기식으로 구성함. 지속성은 보장하지않지만, 모든 팔로워가 잘못되더라도 리더가 쓰기 가능
- replica가 실패했을때?
- 팔로워 실패는 backlog를 보관하기때문에 복구가 비교적 쉬움
- 리더 실패는 까다로움. 기존 팔로워중 하나를 리더로 변경하고, 클라이언트를 재설정해서 새로운 리더로 쓰기를 전송해야함...
[데이터중심어플리케이션설계] 5장. replication
데이터베이스 트랜잭션이란 무엇인가요?
트랜잭션 (ACID) DBMS에서 처리되는 작업의 논리적 단위
Atomicity: all or nothing 실행되거나, 하나라도 오류가 있으면 rollback 된다.
Consistency: 트랜잭션이 성공적으로 완료되면, 일관성있는 데이터베이스 시스템이 된다.
isolation: 둘 이상의 트랜잭션이 동시에 실행되는 경우, 어느 하나가 다른 것에 영향을 미치거나 연산이 끼어들 수 없다.
durability: 트랜잭션의 결과는 시스템이 고장나더라도 영구적으로 반영되어야한다.
보안 / 인증
OAuth / Basic Auth / Token Auth / JWT
oauth 흐름
oauth2는 다양한 플랫폼 환경에서 권한 부여를 위한 산업 표준프로토콜이다. 인증과 권한을 위함
Resource owner(사용자)
Auth server
Resource server (보통 이용하려는 서비스의 서버 )
client (이용하려는 서비스의 클라이언트)
Access token
- 특정 앱에 권한이 있다는 것을 인증하는 토큰.
- scope와 기간등의 정보가 들어있음
refresh token
- access token 이 만료되었을 때, 반복인증 없이 새로 access token을 발급 받을 수 있는 토큰
auth code grant
- 인증서버가 클라이언트와 리소스서버 간 중재 역할
- access token을 클라이언트로 바로 넘기지 않음
implicit grant
- 권한 코드 없이 바로 발급 (read only 사이트)
password credentials grant
- 클라이언트에 아이디/ 패스워드를 저장해놓고 직접 token을 받아옴
- 공식 어플리케이션이나 믿을 수 있는 클라이언트만
- client credentials grant
- 클라이언트가 confiential client이면 id와 secret을 가지고 인증
jwt 개선
- header
- payload (실제 데이터)
- signature
- 실제로 서버가 발행한 토큰인지 검증
- header를 base64url로 암호화 . + payload을 base64url로 암호화 + secret
client에서 현재 가지고 있는 토큰이 만료되었는지 확인할 때는 secret이 필요하지 않습니다.
exp 값은 그냥 decode하는 것만으로도 알 수 있기 때문입니다 토큰으로 토큰을 만들자 - pyjwt 사용기
인증 토큰과 세션을 통한 인증방식
세션 인증:
- 위에서 말했던 것 처럼 유저의 수가 늘어났을 때 성능에 무리
- 서버 확장이 어려움 (분산시스템)
토큰 인증:
- stateless 함
- scalable
- CORS 이슈 (쿠키에서는 발생할수도 있음) 해소
- 토큰만 유효하면 정상 요청 처리
HTTPS / CORS / SSL /TLS / OWSAP Security RISKS
SSL 이라는 암호 규약이 이전에 있었고, 이가 표준으로 만들어진 공식 이름이 TLS(Transport Layer Security 전송 계층 보안) CA(Certificate Authority) 라는 제 3자가 서버와 클라이언트 간 통신을 보증 해줄 때 사용됩니다.
SSL 의 암호화 방식
- 하나가 대칭키 방식 (하나의 키로 암호화, 복호화 가능)
- 키 유출 시 무조건 복호화 가능하다는 단점. 키 전달 자체가 조심스러움
- 다른 하나는 공개키 방식 (비대칭 키 방식)
- 대칭키의 단점을 보완.
- A, B 의 키 페어. A 와 B는 수학적으로 밀접한 연관을 가짐
- 공개키로 암호화, 비공개키로 복호화!
- 거꾸로 하면 전자서명 가능 (비공개키로 암호화, 공개키로 복호화) (보낸 사람의 신원을 보장 가능)
전자서명을 이용해서, 공인기업(CA)의 신원을 확인할 수 있음
- 서버가 인증서를 제공
- 브라우저는 공인 CA인지 확인하고, 그쪽에서 제공해준 공개키로 인증서를 복호화
- 복호화되면 이 인증서가 CA에서 제공한게 확인됨
- 이 인증서를 갖고 있는 서버 너도 안전하구나
MD5 (왜 사용하면 안되는지) SHA family
md5
- 암호화 해시 함수
- 임의 길의 메시지를 입력받아 128bit의 고정 출력값을 낸다.
- 취약점이 많음
- 실제로 복호화가 가능한것은 아니지만 매핑 테이블이 큼
- hash collision이 실제로 나고 있음
- junekim 의 hash 가 aaa, ottol의 hash가 aaa 인 식
- 실제로는 junekim이 작성한게 ottol 의 서명이어도 상관없음
sha
- secure hashing algorithm
- sha-0 (최초), sha-1, sha-224, sha-256, sha-384, sha-512
- 뒤의 4종류를 sha-2라고도 함
- sha-1는 매우 많이 사용됨 (TLS / SSL 도)
- 충돌이 발견되기는 했음.
- 해시 크기가 160 비트
- sha-2 패밀리의 번호는 해시 크기를 뜻함
ElasticSearch
텍스트, 숫자, 정형 / 비정형 데이터 등 많은 유형을 위한 무료 검색 및 분석 엔진. Apache Lucene 기반. NoSQL 처럼 활용할 수 있음 분산 검색 엔진 키에 따라 여러 샤드가 구성되는 방식
Kafka (메시지 브로커로서)
볼륨이 큰 publish-subscribe 메시지와 스트림을 내구성있게, 빠르게, 확장가능하게 다룰 수 있도록 디자인되었다. 카프카는 로그처럼 내구성있는 메시지 저장을 지원하며, 서버 클러스터 내에서 돌고, topic 별로 레코드를 저장한다.
consumer가 직접 버퍼를 읽는 형식을 사용한다. 카프카 브로커는 어떤 컨슈머가 뭘 읽었는지 기록하려고 하지 않고, 일정시간 동안 모든 메시지를 들고 있는다.
시스템이나 어플리케이션 간에 안정성 있게 데이터를 가져오는 실시간 스트리밍 데이터 파이프라인 구축할 때 데이터 스트림에 따라 변하거나 대응하는 리얼타임 스트리밍 어플리케이션을 만들 때
개발 방법론
TDD를 해보셨습니까?
red - green -yellow 의 테스트 작성 - 실제 코드 작성 - 리팩토링 수행의 플로우 가지는 개발 방법론.
실제 코드에 대해서 기대되는 바를 명확하게 정의함으로써 불필요한 설계를 피할 수 있음.
Testing - Integration Test / UnitTest / Functional Test
- 통합테스트
- unittest
- functional test (블랙박스 테스팅)
Monolithic / Microservices / SOA / Serverless
monolithic
- 하나의 커다란 서비스
- 개발 환경이 같아서 복잡하지 않다.
- 쉽게 HA 를 보장
- end to end 테스트 용이
- 덩치가 너무 커져서 어플리케이션 구동시간이 늘어남
- 전체 다시 빌드 후 배포
msa
- 마이크로 서비스 설계
- 작은 단위로 서비스를 구성해서 민첩하고 유연한 설계
- 재가용성이 늘어나면 서비스간 결합도도 늘어나기때문에 아주 작은 서비스 단위를 독립적으로 나누어 구성.
- restful API 로 통신
- 관리가 어렵다. 통신오류가 잦을 수 있다. 테스트 불편.
soa
- 서비스 지향 설계 방식
- 서비스 단위로 개발
- 최대한 재가용하려고 함
- SOAP / WSDL 등 서비스 간 통합적이고 공통된 방식
서버리스
- 개발자가 서버를 관리할 필요없이 애플리케이션을 빌드하고 실행할 수 있도록 하는 클라우드 네이티브 모델
- 클라우드 제공업체가 서버 인프라에 대한 프로비저닝, 유지 관리, 스케일링 등의 일상적인 작업을 처리하며, 개발자는 배포를 위해 코드를 컨테이너에 패키징하기만 하면 됩니다.
- IaaS 모델 (인프라를 구매) vs 서버리스에서는 애플리케이션이 필요할 때만 리소스 할당
mitigation strategy ( 경감 전략)
- Graceful Degradation
- Throttling
- 성능에 제한을 두어서 너무 많은 요청으로 API 요청 bucket이 가득차는 경우를 제한
- 429 too many requests / tomcat 의 max thread 수 (default 200) 으로 throttling
- Backpressure
- 시스템이 처리 가능한만큼의 속도 이상으로 데이터를 받고 있을대, 다이나믹 풀을 이용해서 수용할 수 있는 만큼의 데이터를 요청하는 방식
- LoadShifting
- Circuit breaker
- msa에서 하나의 컴포넌트가 느려지거나 장애가 발생했을때 장애가 발생하는 특성이 있음
- 이 문제를 해결하는 디자인 패턴
- circut breaker는 특정 컴포넌트로의 호출을 모두 보게됨 (정상상황에서 bypass)
- 장애 상황에서는 호출을 강제적으로 끊어서 장애 전파 방지 e.g) netflix hystrix
DevOps
Load Balancer
말 그대로 부하를 분산해주는 장비. 서비스를 하는 경우 부하를 요청 정도로 치환해도 무리 없음. 위의 OSI 단계에 따라서, 4단계 (transport 즉 - ip +port) 에서 작동하면 L4, 7단계 (application - 즉 http 서비스를 한다면 http)에서는 L7라고 부른다.
L4는 ip + port 기반의 단순한 분산만 가능하다면, L7 은 http 와 같은 프로토콜을 이해해서 분산할 수 있다.
Docker / kubernetes / 가상화
docker : 컨테이너 기반의 오픈 소스 가상화 플랫폼
os 가상화가 아닌 격리된 공간에서 프로세스가 동작하는 기술
os 가상화는 무겁고 느림. 간단한 편
host os 위에 docker engine, 그 위에 프로세스가 격리됨
컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 것
kubernetes : 오케스트레이션 툴
- 컨테이너를 쉽고 빠르게 배포/확장하고 관리를 자동화해주는 오픈소스 플랫폼
Nginx
세계에서 가장 많이 쓰고 있는 웹서버 중 하나. 가볍고 여러 요청을 한번에 처리할 수 있다는 장점.
잠깐! 리버스 프록시는 뭐지?
프록시는, 클라이언트와 서버 통신 중간에서 대신 통신을 해주는 서버를 의미한다.
포워드 프록시는, 내부망에 함께 있는 클라이언트가 인터넷을 통해 어딘가에 있는 서버로 요청을 보내려고하면 이 요청을 받아 연결해준다. 클라이언트 앞단에서의 처리!
리버스 프록시는, 내부망의 서버 앞단에서 요청을 처리한다. 이렇게 구성하는 이유는 보안때문이다. WAS(웹어플리케이션서버)는 대부분 DB 서버와 연결 되어있으므로, WAS 가 최전방에 있으면 보안에 취약해진다. 그때문에 리버스 프록시를 두고 사용한다면 WS 가 WAS 와 통신해서 결과를 클라이언트에 제공하는 방식으로 서비스를 하게 된다.
- nginx 로드밸런싱? 나는 nginx 설정이 정말 싫다구요
무중단 배포방식
Blue - green 배포
애플리케이션 또는 마이크로서비스의 이전 버전에 있던 사용자 트래픽을 이전 버전과 거의 동일한 새 버전으로 점진적으로 이전하는 애플리케이션 릴리스 모델입니다. 이때 두 버전 모두 프로덕션 환경에서 실행 상태를 유지합니다.
이전 버전을 blue 환경으로, 새 버전은 green 환경으로 부를 수 있습니다. 프로덕션 트래픽이 blue에서 green으로 완전히 이전되면, blue는 롤백에 대비하여 대기 상태로 두거나 프로덕션에서 가져온 후 업데이트하여 다음 업데이트의 템플릿으로 삼을 수 있습니다.
- 환경에 따라서는 업타임 요구 사항이 다르거나 blue-green과 같은 CI/CD 프로세스를 제대로 수행할 리소스가 없을 수도 있습니다
rolling update
배포된 서버를 구버전에서 새버전으로 하나씩 교체
canary deployment
출처
자바면접질문: https://mellowp-dev.tistory.com/4
https://jeong-pro.tistory.com/95
https://www.itworld.co.kr/news/110768
https://www.redhat.com/ko/topics/api/what-are-application-programming-interfaces
https://smjeon.dev/etc/interview-question/
https://ratsgo.github.io/data%20structure&algorithm/2017/09/27/heapsort/
https://taes-k.github.io/2020/02/16/servlet-container-spring-container/
https://gracelove91.tistory.com/100
https://www.redhat.com/ko/topics/devops/what-is-blue-green-deployment