3주 차에서 다룰 내용은 다음과 같다.
1. Network
- OSI 7 계층
- TCP 3 way handshake&4 way handshake
- TCP/IP 흐름 제어&혼잡 제어
- UDP
2. Java
- Error&Exception
- Stream API
- Record
Network
OSI 7 계층
OSI 7 계층이란?
OSI계층은 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것을 말한다.
7 계층은 왜 나눌까?
통신이 일어나는 과정을 단계별로 알 수 있고, 특정한 곳에 이상이 생기면 그 단계만 수정할 수 있기 때문이다.
1. 물리 계층(Physical): 단지 데이터 전기적인 신호로 변환해서 주고받는 기능을 진행하는 공간
즉, 데이터를 전송하는 역할만 진행한다.
2. 데이터 링크 계층(Data Link): 물리 계층으로 송수신되는 정보를 관리하여 안전하게 전달되도록 도와주는 역할
Mac 주소를 통해 통신한다. 프레임에 Mac 주소를 부여하고 에러 검출, 재전송, 흐름 제어를 진행한다.
3. 네트워크 계층(Network): 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능을 담당한다.
라우터를 통해 이동할 경로를 선택하여 IP 주소를 지정하고, 해당 경로에 따라 패킷을 전달해준다.
라우팅, 흐름 제어, 오류 제어, 세그먼테이션 등을 수행한다.
4. 전송 계층(Transport): TCP와 UDP 프로토콜을 통해 통신을 활성화한다. 포트를 열어두고, 프로그램들이 전송을 할 수 있도록 제공해준다.
5. 세션 계층(Session): 데이터가 통신하기 위한 논리적 연결을 담당한다. TCP/IP 세션을 만들고 없애는 책임을 지니고 있다.
6. 표현 계층(Presentation): 데이터 표현에 대한 독립성을 제공하고 암호화하는 역할을 담당한다.
파일 인코딩, 명령어를 포장, 압축, 암호화한다.
7. 응용 계층(Application): 최종 목적지로, 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행한다.
사용자 인터페이스, 전자우편, 데이터베이스 관리 등의 서비스를 제공한다.
TCP 3 way handshake & 4 way handshake
TCP는 정확한 전송을 보장해야 한다. 따라서 통신하기에 앞서, 논리적인 접속을 성립하기 위해 3 way handshake과정을 진행한다.
3 way handshake - 연결 성립
1. 클라이언트가 서버에게 SYN 패킷을 보낸다.
2. 서버가 SYN을 받고, 클라이언트로 받았다는 신호인 ACK와 SYN패킷을 보낸다.
3. 클라이언트는 서버의 응답은 ACK와 SYN패킷을 받고, ACK를 서버로 보낸다.
위와 같이 3번의 통신이 완료되면 연결이 성립된다.
4 way handshake - 연결 해제
1. 클라이언트는 서버에게 연결을 종료한다는 FIN 플래그를 보낸다.
2. 서버는 FIN을 받고, 확인했다는 ACK를 클라이언트에게 보낸다.
3. 데이터를 모두 보냈다면, 연결이 종료되었다는 FIN 플래그를 클라이언트에게 보낸다.
4. 클라이언트는 FIN을 받고, 확인했다는 ACK를 서버에게 보낸다.
위와 같이 4번의 통신이 완료되면 연결이 해제된다.
TCP/IP (흐름 제어/혼잡 제어)
TCP 통신이란?
- 네트워크 통신에서 신뢰적인 연결방식
- TCP는 기본적으로 unreliable network에서, reliable network를 보장할 수 있도록 하는 프로토콜
- TCP는 network congestion avoidance algorithm을 사용
신뢰성(reliable network)을 보장한다는 것은 4가지 문제점이 존재한다.
- 손실 : packet이 손실될 수 있는 문제
- 순서 바뀜 : packet의 순서가 바뀌는 문제
- Congestion : 네트워크가 혼잡한 문제
- Overload : receiver가 overload 되는 문제
흐름 제어란?
- 송신 측과 수신 측의 데이터 처리 속도 차이를 해결하기 위한 기법
- Flow Control은 receiver가 packet을 지나치게 많이 받지 않도록 조절하는 것
- 기본 개념은 receiver가 sender에게 현재 자신의 상태를 feedback 한다는 점
해결방법
Stop and Wait : 매번 전송한 패킷에 대해 확인 응답을 받아야만 그다음 패킷을 전송하는 방법
Sliding Window (Go Back N ARQ)
- 수신 측에서 설정한 윈도 크기만큼 송신 측에서 확인 응답 없이 세그먼트를 전송할 수 있게 하여 데이터 흐름을 동적으로 조절하는 제어기법
- 목적 : 전송은 되었지만, acked를 받지 못한 byte의 숫자를 파악하기 위해 사용하는 protocol
- 동작 방식 : 먼저 윈도에 포함되는 모든 패킷을 전송하고, 그 패킷들의 전달이 확인되는 대로 이 윈도를 옆으로 옮김으로써 그다음 패킷들을 전송
혼잡 제어란?
송신 측의 데이터 전달과 네트워크의 데이터 처리 속도 차이를 해결하기 위한 기법
해결방법
AIMD(Additive Increase/Multiplicative Decrease)
- 처음에 패킷을 하나씩 보내고 이것이 문제없이 도착하면 window 크기(단위 시간 내에 보내는 패킷의 수)를 1씩 증가시켜가며 전송하는 방법
- 패킷 전송에 실패하거나 일정 시간을 넘으면 패킷의 보내는 속도를 절반으로 줄인다.
- 공평한 방식으로, 여러 호스트가 한 네트워크를 공유하고 있으면 나중에 진입하는 쪽이 처음에는 불리하지만, 시간이 흐르면 평형상태로 수렴하게 되는 특징이 있다.
- 문제점은 초기에 네트워크의 높은 대역폭을 사용하지 못하여 오랜 시간이 걸리게 되고, 네트워크가 혼잡해지는 상황을 미리 감지하지 못한다. 즉, 네트워크가 혼잡해지고 나서야 대역폭을 줄이는 방식이다.
Slow Start
- AIMD 방식이 네트워크의 수용량 주변에서는 효율적으로 작동하지만, 처음에 전송 속도를 올리는데 시간이 오래 걸리는 단점이 존재했다.
- Slow Start 방식은 AIMD와 마찬가지로 패킷을 하나씩 보내면서 시작하고, 패킷이 문제없이 도착하면 각각의 ACK 패킷마다 window size를 1씩 늘려준다. 즉, 한 주기가 지나면 window size가 2배로 된다.
- 전송속도는 AIMD에 반해 지수 함수 꼴로 증가한다. 대신에 혼잡 현상이 발생하면 window size를 1로 떨어뜨리게 된다.
- 처음에는 네트워크의 수용량을 예상할 수 있는 정보가 없지만, 한번 혼잡 현상이 발생하고 나면 네트워크의 수용량을 어느 정도 예상할 수 있다.
- 그러므로 혼잡 현상이 발생하였던 window size의 절반까지는 이전처럼 지수 함수 꼴로 창 크기를 증가시키고 그 이후부터는 완만하게 1씩 증가시킨다.
Fast Retransmit
- 빠른 재전송은 TCP의 혼잡 조절에 추가된 정책이다.
- 패킷을 받는 쪽에서 먼저 도착해야 할 패킷이 도착하지 않고 다음 패킷이 도착한 경우에도 ACK 패킷을 보내게 된다.
- 단, 순서대로 잘 도착한 마지막 패킷의 다음 패킷의 순번을 ACK 패킷에 실어서 보내게 되므로, 중간에 하나가 손실되게 되면 송신 측에서는 순번이 중복된 ACK 패킷을 받게 된다. 이것을 감지하는 순간 문제가 되는 순번의 패킷을 재전송해줄 수 있다.
- 중복된 순번의 패킷을 3개 받으면 재전송을 하게 된다. 약간 혼잡한 상황이 일어난 것이므로 혼잡을 감지하고 window size를 줄이게 된다.
Fast Recovery
혼잡한 상태가 되면 window size를 1로 줄이지 않고 반으로 줄이고 선형 증가시키는 방법이다. 이 정책까지 적용하면 혼잡 상황을 한번 겪고 나서부터는 순수한 AIMD 방식으로 동작하게 된다
UDP
UDP 통신이란?
- User Datagram Protocol의 약자로 데이터를 데이터그램 단위로 처리하는 프로토콜이다.
- 비연결형, 신뢰성 없는 전송 프로토콜이다.
- 데이터그램 단위로 쪼개면서 전송을 해야 하기 때문에 전송 계층이다.
- Transport layer에서 사용하는 프로토콜.
UDP는 왜 사용할까?
- UDP의 결정적인 장점은 데이터의 신속성이다. 데이터의 처리가 TCP보다 빠르다.
- 주로 실시간 방송과 온라인 게임에서 사용된다. 네트워크 환경이 안 좋을 때, 끊기는 현상을 생각하면 된다.
Java
Error & Exception
Error는 컴파일 시 문법적인 오류와 런타임 시 널 포인트 참조와 같은 오류로 프로세스에 심각한 문제를 야기시켜 프로세스를 종료시킬 수 있다.
Exception 은 컴퓨터 시스템의 동작 도중 예기치 않았던 이상 상태가 발생하여 수행 중인 프로그램이 영향을 받는 것으로 예를 들면, 연산 도중 넘침에 의해 발생한 끼어들기 등이 이에 해당한다.
에러는 메모리 부족이나 스택오버플로우와 같이 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습할 수 있는 비교적 덜 심각한 오류이다. 이 예외는 프로그래머가 적절히 코드를 작성해주면 비정상적인 종류를 막을 수 있다.
예외가 주로 발생하는 원인
- 사용자의 잘못된 데이터 입력
- 잘못된 연산
- 개발자가 로직을 잘못 작성
- 하드웨어, 네트워크 오작동
- 시스템 과부하
대표적인 Exception Class
- NullPointerException : Null 레퍼런스를 참조할 때 발생, 뭔가 동작시킬 때 발생한다.
- IndexOutOfBoundsException : 배열과 유사한 자료구조(문자열, 배열, 자료구조)에서 범위를 벗어난 인덱스 번호 사용으로 발생한다.
- FormatException : 문자열, 숫자, 날짜 변환 시 잘못된 데이터(ex. "123A" -> 123으로 변환 시)로 발생하며, 보통 사용자의 입력, 외부 데이터 로딩, 결과 데이터의 변환 처리에서 자주 발생한다.
- ArthmeticException : 정수를 0으로 나눌 때 발생한다.
- ClassCastException : 변환할 수 없는 타입으로 객체를 변환할 때 발생한다.
- IllegalArgumentException : 잘못된 인자 전달 시 발생한다.
- IOException : 입출력 동작 실패 또는 인터럽트 시 발생한다.
- IllegalStateException : 객체의 상태가 매소드 호출에는 부적절한 경우에 발생한다.
- ConcurrentModificationException : 금지된 곳에서 객체를 동시에 수정하는 것이 감지될 경우 발생한다.
- UnsupportedOperationException : 객체가 메서드를 지원하지 않는 경우 발생한다.
주요 메서드
printStackTrace() : 발생한 Exception의 출처를 메모리상에서 추적하면서 결과를 알려준다. 발생한 위치를 정확히 출력해줘서 제일 많이 쓰며 void를 반환한다.
getMessage() : 한 줄로 요약된 메시지를 String으로 반환해준다.
getStackTrace() : jdk1.4부터 지원, printStackTrace()를 보완, StackTraceElement []이라는 문자열 배열로 변경해서 출력하고 저장한다.
로직 중에 예외가 발생할지도 모르는 부분에 try - catch 구문으로 보험을 들 수도 있다.
만약 ①번 try 블록에서 예외가 발생하지 않고, 바깥쪽 try 블록에서도 예외가 발생하지 않으면, ⑥번 finally 블록이 바로 실행된다.
하지만 ①번 try 블록에서 예외가 발생하면, ②번과 ③번 catch 블록에서 해당 예외를 처리할 수 있는지 검사하게 된다.
만약 적절한 catch 블록을 찾지 못하면, 바깥쪽 try 블록의 ④번과 ⑤번 catch 블록도 차례대로 검사하게 된다.
이때 해당 예외를 처리할 수 있는 catch 블록을 찾게 되면, 해당 catch 블록을 실행한 후 ⑥번 finally 블록을 실행된다.
하지만 모든 catch 블록이 해당 예외를 처리할 수 없으면, 예외는 처리되지 못한 채 해당 프로그램은 강제 종료된다.
Stream API
자바에서는 많은 양의 데이터를 저장하기 위해서 배열이나 컬렉션을 사용한다.
이렇게 저장된 데이터에 접근하기 위해서는 반복문이나 반복자(iterator)를 사용하여 매번 새로운 코드를 작성해야 한다.
하지만 이렇게 작성된 코드는 길이가 너무 길고 가독성도 떨어지며, 코드의 재사용이 거의 불가능하다.
즉, 데이터베이스의 쿼리와 같이 정형화된 처리 패턴을 가지지 못했기에 데이터마다 다른 방법으로 접근해야만 했다.
이러한 문제점을 극복하기 위해서 Java SE 8부터 스트림(stream) API를 도입했다.
특징
1. 스트림은 외부 반복을 통해 작업하는 컬렉션과는 달리 내부 반복(internal iteration)을 통해 작업을 수행한다.
2. 스트림은 재사용이 가능한 컬렉션과는 달리 단 한 번만 사용할 수 있다.
3. 스트림은 원본 데이터를 변경하지 않는다.
4. 스트림의 연산은 필터-맵(filter-map) 기반의 API를 사용하여 지연(lazy) 연산을 통해 성능을 최적화한다.
5. 스트림은 parallelStream() 메서드를 통한 손쉬운 병렬 처리를 지원한다.
스트림은 3가지 단계를 걸쳐서 동작한다.
1. 스트림의 생성
2. 스트림의 중간 연산 (스트림의 변환) - 여러 번 사용 가능
3. 스트림의 최종 연산 (스트림의 사용) - 1번만 사용 가능
Stream 중간 연산
- filter(Predicate) : Predicate를 인자로 받아 true인 요소를 포함한 스트림 반환
- distinct() : 중복 필터링
- limit(n) : 주어진 사이즈 이하 크기를 갖는 스트림 반환
- skip(n) : 처음 요소 n개 제외한 스트림 반환
- map(Function) : 매핑 함수의 result로 구성된 스트림 반환
- flatMap() : 스트림의 콘텐츠로 매핑함. map과 달리 평 면화된 스트림 반환
Stream 최종 연산
- (boolean) allMatch(Predicate) : 모든 스트림 요소가 Predicate와 일치하는지 검사
- (boolean) anyMatch(Predicate) : 하나라도 일치하는 요소가 있는지 검사
- (boolean) noneMatch(Predicate) : 매치되는 요소가 없는지 검사
- (Optional) findAny() : 현재 스트림에서 임의의 요소 반환
- (Optional) findFirst() : 스트림의 첫 번째 요소
- reduce() : 모든 스트림 요소를 처리해 값을 도출. 두 개의 인자를 가짐
- collect() : 스트림을 reduce 하여 list, map, 정수 형식 컬렉션을 만듦
- (void) forEach() : 스트림 각 요소를 소비하며 람다 적용
- (Long) count : 스트림 요소 개수 반환
Record
레코드란?
데이터 전달자를 생성하기 위한 record는 java 14부터 프리뷰 상태로 포함되어 있다. record는 class, enum, interface와 같은 타입 선언이다. record는 enum과 같이 제약을 가진 클래스의 일종으로 자바 클래스가 가진 자유를 포기하고 간결함을 얻기 위한 용도이다.
record는 다음과 같이 이해할 수 있다.
- 불변(immutable) 데이터 집합
- 명목상 튜플(nominal tuples)
record의 제약
- 다른 클래스를 상속할 수 없습니다.
- 다른 필드를 선언하려면 오로지 static으로만 선언할 수 있습니다.
객체를 생성할 때, 대부분은 아래와 같이 만든다.
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
클래스 Person을 만들고, 필드 name, age를 생성한다.
이후 생성자와 getter를 구현한다.
Record 타입으로 클래스를 만들면 매우 단순해진다.
public record Person(String name,int age){}
자동으로 필드를 private final로 선언하여 만들어주고, 생성자와 getter까지 암묵적으로 생성된다.
또한 equals, hashCode, toString 도 자동으로 생성된다고 하니 매우 편리하다.
대신 getter 메서드의 경우 구현 시 getXXX()로 명칭을 짓지만, 자동으로 만들어주는 메서드는 name(), age()와 같이 필드명으로 생성된다.
'CS' 카테고리의 다른 글
HTTP 상태 코드 (2) | 2023.01.04 |
---|---|
5주차 CS 스터디 Operating System&Spring (1) | 2022.11.08 |
4주차CS스터디Network&Spring (0) | 2022.10.27 |
2주차CS스터디Computer Architecture&Java (2) | 2022.09.28 |
1주차 CS스터디 Computer Architecture & Java (8) | 2022.09.21 |