서브넷 마스크의 길이를 자유롭게 바꿀 수 있다면 서브넷 별로 접속할 컴퓨터의 수를 유연하게 결정할 수 있다.
CIDR : 잘 이해가 안된다 .. 다시 공부 해봐야겠다.
MAC 주소
이더넷 등의 네트워크 하드웨어에 하나씩 할당되어 있는 주소로 원칙적으로는 다른 것과 중복되지 않는 유일한 값이다.
위에서 이야기한 개체별로 사용하는 주소가 유일하다는 점이 반드시 보장되는것은 아니다.
이더넷등의 네트워크 하드웨어는 통신 대상을 특정하기 위해 MAC주소를 사용함.
현재 주류인 이더넷은 LAN 케이블에서 허브/스위치에 각 컴퓨터를 연결하여 사용함.
AA-BB-CC-DD-EE-FF
AA-BB-CC : 제조사를 나타내는 벤더 ID
DD : 제품 기종을 나타내는 ID
EE-FF : 시리얼 번호를 나타냄.
ARP가 필요한 이유
수신 대상이 다른 네트워크에 있는 경우 그 IP 패킷을 다음 라우터로 넘겨야 하는데 이때 라우터의 IP주소에서 MAC주소를 얻을 필요가 있다.
위의 동작에 ARP 프로토콜이 사용된다.
ARP로 IP주소에서 MAC주소를 얻은 후에 컴퓨터는 그 MAC 주소를 전송처로 지정된 이더넷 프레임을 사용해서 IP패킷을 대상 컴퓨터로 전송한다.
ARP에는 브로드 캐스트가 사용된다.
알고자 하는 IP주소를 포함한 ARP 요청을 브로드캐스트
해당 IP를 사용중인 컴퓨터는 MAC 주소를를 요청자에게 직접 전송한다.
도메인명
인간이 다를 수 있는 범위에 맞춰 네트워크 상의 컴퓨터 명칭으로 도메인명을 쓴다.
인터넷 도메인 명은 전세계에서 유일하도록 관리되며 총본산인데가 ICANN이다. 최상위 도메인을 관리한다.(TLD)
도메인 구조는 www -> 3단계도메인 example ->2단계도메인(SLD), com -> 최상위 도메인(TLD)로 관리된다. www.example.com
라우팅과 기본 게이트웨이
라우터로 패킷을 전송하는 것을 라우팅이라고 한다.
라우터는 전송 규칙에 따라 수행하며 라우팅 테이블을 이용한다.
라우팅 테이블에는 ‘수신처의 네트워크’와 그’네트워크에 대한 발송 방법’이 등록되어있다.
라우터는 패킷을 받으면 그 수신처로 표시되 있는 IP 주소에 서브넷 마스크를 적용해서 네트워크 주소를 추출한다.
게이트웨이란 자신이 소속된 네트워크 이외에 보내려는 패킷에 대해 어딜로 보낼지 모를때의 전송처이다. 보낼 곳을 모르는 때에 우선 전송해두는곳이라고 생각하면 된다.
일반적으로 기본 게이트웨이로 네트워크의 입출입 역할을 하는 라우터를 설정한다.
정적 라우팅과 동적 라우팅
새로운 네트워크가 추가되는 경우 등 네트워크의 접속 상태가 변하는 때에 그 변경에 따라 관련된 각 라우터의 라우팅 테이블을 수정할 필요가 생긴다
정적 라우팅
위의 상황에서 네트워크 접속이 변경될 때마다 관련된 라우터 등의 라우팅 테이블을 수동으로 수정하는 방법이다.
네트워크 규모가 작거나 구성변경이 없는경우 간단히 쓰이는 방법이다.
동적 라우팅
네트워크의 접속 라우터에 관한 정보를 라우터끼리 정기적 또는 필요에 따라 서로 교환하여 그 정보를 기반으로 라우팅 테이블을 자동 관리한다.
신규 네트워크가 연결되면 그 네트워크의 접점이 되는 라우터가 인접해 있는 각 라우터로 새로운 네트워크의 정보를 전달하고 수신한 라우터는 필요에 따라 그 신규 라우터의 정보를 인접 라우터로 전달한다. 이렇게 확산 시키고 각 라우터가 필요한 규칙은 라우팅 테이블에 설정한다.
라우팅 프로토콜
라우팅 테이블을 동적으로 갱신하는 동적 라우팅에서 사용하는 프로토콜을 라우팅하는 프로토콜이다.
라우팅 프로토콜로 최적 경로를 구하고 여기서 말하는 최적 경로는 네트워크 내를 따라가는 데 있어 최소 경로를 의미한다.
단순히 통신하는 라우터의 수가 적은 경우 최적경로를 구하는 프로토콜 : RIP/RIP2
도중에 통신하는 네트워크의 속도 등도 고려해서 선택하는 프로토콜 : OSPF
라우터는 크게 IGP와 EGP로 나뉜다.
IGP(interior Gateway Protocol)
EGP(Exterior Gateway Protocol)
AS(Autonomous System)은 한개의 ISP 또는 대기업의 대규모 네트워크를 칭한다.
IGP는 AS 내의 라우팅에 이용하고 EGP는 주로 AS간의 라우팅에 이용한다.
DHCP(Dynamic Host Coniguration Protocol)
네트워크에 접속되어 있는 컴퓨터에 대해 필요한 네트워크 설정 정보를 자동으로 배포하기 위한 구조다.
컴퓨터의 IP주소, 서브넷마스크, 기본 게이트웨이, DNS서버의 IP 주소 등을 설정할 수 있고 컴퓨터가 네트워크에 접속하는데 필요한 정보는 대부분 다 포함한다.
DHCP는 아직 컴퓨터에 IP주소 등의 네트워크 설정이 되어 있지 않은 시점에 사용하므로 IP 주소를 지정해서 하는 일반적인 통신을 이용하지 않는다.
DHCP discover(브로드 캐스트) -> DHCP offer(1:1통신) -> DHCP request(offer에 받은 후보를 사용한 다는 사실을 알림) -> DHCP Ack
NAT와 NAPT
NAT(Network Address Translation)
몇개의 전역 IP주소를 라우터에 할당해 두고 LAN 내의 컴퓨터가 인터넷에 접속할때 이 중 하나를 이용하여 통신하는 방법.
라우터가 갖고 있는 전역 IP주소의 수로 제한된다.
NAPT(Network Address Port Translation)
IP 주소의 변환과 동시에 포트번호도 변환하고 한개의 전역 IP주소를 여러대의 컴퓨터에서 공용으로 사용할 수 있게하는 기술
인터넷에 송출할 때 자신의 IP 주소와 port 번호의 조합을 라우터의 전역 IP주소와 라우터가 관리하는 포트번호의 조합으로 변환.
2. 코틀린 질문 정리
p.205 jvm 스레드와 하드웨어 스레드의 차이.
jvm 스레드는 대부분 하드웨어 스레드에 의해 백업 된다?
p.211 스레드 풀이란? executor의 작동 방식에 대해서 공부한다.
p.213 코루틴과 스레드의 차이
동기 구현 -> 콜백 -> 자바퓨처 -> 코버넌트를 통한 프로미스 -> 코루틴 순서로 비교를 하고 있다. 각각의 동작 원리를 공부.
async 코루틴 빌더와 runblocking의 차이
p.237 코루틴은 항상 컨텍스트에서 실행 된다는데 여기서 말하는 컨텍스트란 ? 그리고 어떻게 얻을 수 있나 ?
두 코루틴이 통신할 수 있는 방법으로 Deferred<T>로 완료된 이벤트를 날리는것(complete)과 받는것(await)과 채널이 있다.
기능적으로 변경 불가능한 스타일 사용이 불가능 할 때가 있는데 코루틴은 대안을 제시한다.
병렬화 방법
컨텍스트 전환 : withContext함수는 특정 코루틴 컨텍스트 블록을 실행한다.
스레드 안전 구조체 : 코루틴에선 유용한 일부 아토믹 스레드 안전 구조체에 접근 가능하며 AtomicIntger() 함수를 사용함. 다른 타입도 가능하다.
뮤텍스 : 여러 코루틴이 리소스를 공유하지만 동시에는 접근하지 못하게 한다. 컨트롤 구조체화 비슷하게 작동하지만 스레드를 차단하는 대신 코루틴만 블록한다.
액터 : 메시지를 통해 외부 월드 및 다른 액터와 상호작용 하는 일종의 오브젝트이다. actor<T>{} 형태로 사용한다.
3. 코틀린 코드스피츠 continuation & cps 정 리
continuation : callback과 부합한다.
cps(continuation passing style) : continuation(콜백)을 pass 하는 식으로 프로그래밍 하는것
블로킹 : 명령이 지나가다가 어떤 명령이 cpu time을 오랫동안 끌고 있는것을 의미
cpu타임을 얼만큼 점유하냐의 문제
사실 모든 노이만 머신은 블로킹이다. blocking nonblocking은 상대적이다.
동기 & 비동기
sync : 노이만 머신이 메모리에 적재되 있는 명령을 순서대로 빼서 실행 하는것
서브루틴이 즉시 값을 반환(return)
async는 명령이 적재된 순서대로 실행되지 않는것. 프로그램의 임의대로 메모리에 적재되있는 명령을 끌어 쓰는것.(콜백)
서브루틴이 다른 수단으로 값을 반환(return Promise는 값이 아니기 때문에 즉시 사용할 수 없음.)
콜백 함수 a를 위에 먼저 선언하고 b라는 함수한태 a를 넘겨준다면 로직 상으로는 a -> b이지만 b -> a순으로 실행됨.
blocking nonblocking & sync async
싱크이면서 블로킹은 절대 안된다(우리가 짜는것)
싱크이면서 논블로킹 : 메모리의 순서대로 명령을 읽다가 블로킹이 가능한가? 현재 실행중인 스레드에선 불가능. 메모리에서 명령을 읽어 내려오다가 싱크 명령어가 어떤 명령어를 실행하면 현재 스레드는 블로킹이다.
스레드 안에서의 싱크로직인 누군가가 백그라운드 스레드에서 다른 로직을 돌린다면(얘가 애초에 async 아닌가?) 현재 스레드는 블로킹이고 밖에 있는건 블로킹이 아님. 자바 퓨처가 이런 방식. 싱크로 백그라운드를 실행하는 것은 블로킹이 되지만 이외의 것은 논블로킹이다. java future 같은 경우 while 문으로 future.isCompleted를 확인하고 백그라운드에서 완료되면 isCompleted를 변경해주고 while문을 탈출 할것임.
어싱크 블로킹 : 내가 콜백(async)으로 함수를 불렀지만 그 콜백을 부르는 함수가 안에서 포문이 1억까지 돈다. 어싱크로 콜백으로 응답이 오긴 하지만 포문을 도는 함수는 블로킹된다. 제어권이 포문한태 가서 돌아오지 않고, 콜백할 때 돌아옴.(얘는 진짜 하면 안된다. 찾기가 어렵다.)
어싱크 논블로킹 : 가장 바람직 한것
우리의 목표 싱크 블로킹으로 처럼 표현(우리가 머리가 나빠서 이렇게 쉽게 하는것) 했는데 백그라운드에서 어싱크 논블로킹으로 작동하게 하는것
우리가 특수한 섹션을 선언해서 짜면 프로그램이 알아서 쪼개서 쪼갠 단위별로 점프시켜주는 타이밍을 비동기로 잡아서 처리해주기 때문임.
우리는 싱크 블로킹으로 짰으니 같은 지역변수를 사용한다. 근데 프로그램이 알아서 나눠졌는데 이 지역변수를 어떻게 구분하나 지역객체가 아니라는것. 어떤 객체에 담아 나눠주고 있다는 뜻임 이것을 continuation이라고 함
factorial
재귀 : 진입점에 특이점을 갖는데 처음 부른 후의 재귀는 전부다 현재값과 합산값을 갖는데 진입점만 인자가 한개이다. 진입점은 일반적으로 특이점을 가짐
재귀함수가 성립하는 이유 : 함수의 리턴 값에 연산을 사용하지 않고 함수의 인자값에 연산의 인자를 캐쉬처럼 보내기 때문이다. 재귀에는 acc가 필요 없기 때문에 진입점에는 특이점이 있음.
tailrec : 함수 내용이 trailrecursive인지 확인하고 맞는지 아닌지 컴파일 타임에 경고. 그리고 컴파일 타임에 tailrec 함수가 되는 경우 반환형을 생략할 수 없음. 밑의 코드를 보면 n==0일 때는 int로 확정지을 수 있지만 _fact(n - 1, n * a)는 추론 해야되고, 추론에 추론을 해야 되기 때문에 확정지을 수 없다.
funfact(n:Int)=_fact(n,1)tailrecfun_fact(n:Int, a:Int):Int =if(n==0) a else_fact(n -1, n * a)
위의 것을 cps(continuos passing style)(콜백을 통해 값을 얻음 반대로 함수엔 콜백에 값을 보고 할것임)로 바꿔보면 밑의 코드를 보면 _fact에게 앞에 받아왔던 콜백 함수를 패싱을 하게됨. 파라미터 block은 continuos 함수 또는 객체.
block 콜백을 받아 _factCPS에 패싱하고 또 재귀로 패싱함 그래서 마지막엔 return a가 아니라 block으로 보고함 함수의 리턴이 아니라 continuation에게 보고한다.이것이 cps의 기본
funfactCPS(n:Int, block:(Int)->Unit)=_factCPS(n,1, block)tailrecfun_factCPS(n:Int, a:Int, block:(Int)->Unit){if(n==0)block(a)else_factCPS(n -1,n*a, block)}factCPS(3,::println)// 함수 참조 포인터라고 하며 내부에서 람다 만든것 처럼 람다 객체가 생김. 자바 jvm에서 8이후 이것을 쓰는게 메모리 적으로 효과 적이지만 코틀린은 똑같다.
cps에선 예외를 레포트로 받으면 그만. 그래서 내 범위내에서 정의가 된다.
밑의 코드와 위의 코드랑 차이로 throw Throwable()이 있는데 이걸로 tailrec이 안된다.
tailrec의 조건은 언어 마다 다름. 코틀린에서는 throw 인정 안함.
밑의 코드는 언어 구조를 이용한 예외처리 별로 좋지 못함 예외라서 예외라는건 특정 예외 감시 블록이 모든 머신의 프로그램 명령을 감시하다 잘못된 cpu의 출력을 감지하는 로직을 다 거친다. try 부분의 모든 코드는 계속해서 감시를 하고 그래서 무조건 과부하 걸린다. 또 if문처럼 조건 분기를 함.(try catch) 또 예외 안에서 또 예외가 생기면 중첩 끝없는 예외처리의 가능성이 있음.그래서 코틀린에서는 반드시 catch해야만 하는 예외 자체를 없애버림.
자바에서는 catch해야 만 하는 예외가 있고 아닌게 있음(런타입 exception, error 계열 얘내 둘은 안해도됨) 예외 계열중 런타임 아닌 애들만 하면 된다.
코틀린에서는 jvm이라고 해도 캐치할 필요 없음.
밑의 코드는 일반적인 함수 스타일에서 값을 리턴하는 경우 throw밖에 대안이 없고, 밖에선 함수 호출 로직 이외에 예외 처리하는 별도의 제어문 블록이 나와야 처리할 수 있음.
funfactThrow(n:Int)=_factThrow(n,1)
fun_ factThrow(n:Int, a:Int):Int =when{
n <0->throwThrowable("invalid value: $n")
n ==0-> a
else->_fact(n -1, n * a)}try{println(factThrow(-3))}catch(e:Throwable){println(e)}
cps스타일에서는 예외처리 또한 report중 하나일 뿐
그래서 정상 레포트와 예외 레포트 두개만 받으면 된다.
그리고 passing은 둘 다한태
funfactCPSEx(n:Int, block:(Int)->Unit, ex:(String)->Unit ={})=_factCPSEx(n,1,block,ex)tailrecfun_factCPSEx(n:Int, a:Int, block:(Int)-> Unit, ex:(String)->Unit){when{
n <0->ex("invalid value: $a")
n ==0->block(a)else->_factCPSEx(n -1, n * a, block, ex)}}factCPSEx(-3,::println,::println)
CPS의 장점
우리가 레포트 하는 시점을 고를 수 있다.
예외를 포함한 기존의 제어문이 관여했던 부분을 CPS에서 메소드로 해결할 수 있다.
continuos : 현재 호출된 함수의 상태를 기억하는 객체
2.Feelings
코틀린은 정말 어려운 언어이지만 재미있다.
점심 먹고 하는 독서스터디가 너무 시간을 많이 잡아먹는다. 따로 읽어와서 공유하는 방법으로 변경했다.
코딩 도장에서 짝프로그래밍으로 셋이서 같이 푸는데 의사소통과 팀원들이 잘 팀웍을 맞추지 않으면 산으로 간다는 것을 느꼈다. 셋이서 어떻게 풀지 다 구해놓고 거의 한 시간 동안 딴짓하다가 5분만에 풀었다.