제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

H-Index를 찾기 위해서 정렬이 꼭 필요합니다. 또 i를 0부터 순회하면 len - i는 최대 값이 되므로 다음 코드와 같이 로직을 계산합니다.

소스코드

import java.util.*;

class Solution {
    public int solution(int[] citations) {
        Arrays.sort(citations);

        int len = citations.length;
        for (int i = 0; i < len; i++) {
            if (citations[i] >= len - i) {
                return len - i;
            }
        }
        return 0;
    }
}

코드 설명

  • Arrays.sort(citations);
    주어진 citations 배열을 오름차순으로 정렬합니다. 이는 논문의 인용 횟수를 작은 순서부터 큰 순서로 정렬하여 H-Index를 계산하기 쉽게 만듭니다.
  • for (int i = 0; i < len; i++) { if (citations[i] >= len - i) { return len - i; } }
    citations 배열을 순회하며 H-Index 조건을 검사합니다.
    • citations[i]는 논문의 인용 횟수를 나타냅니다.
    • len - i는 현재 인덱스 기준으로 남은 논문 개수를 나타냅니다.
    • if (citations[i] >= len - i): 논문 i번째의 인용 횟수가 남은 논문 개수 이상일 경우, H-Index 조건을 만족합니다. 즉, 인용 횟수가 적어도 len - i 이상인 논문이 len - i편 존재한다는 의미입니다.
  • 루프를 다 돌아도 H-Index 조건을 만족하는 값이 없다면 0을 반환합니다. 이는 모든 논문의 인용 횟수가 H-Index 조건을 만족하지 않을 때입니다.
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

각 자릿수를 토대로 비교하면서 가장 큰 수를 구할 수도 있겠습니다만, 시간 초과가 날 것입니다.
이를 위해 문자열 정렬로 생각하여 문제를 풀었습니다. 예를 들어, a = "3"와 b = "30"일 때 (b + a)는 "303"이고 (a + b)는 "330"입니다. 따라서 "330"이 더 앞에 오도록 구현하였습니다.

소스코드

import java.util.*;

class Solution {
    public String solution(int[] numbers) {
        StringBuilder sb = new StringBuilder();

        String[] strNumbers = Arrays.stream(numbers)
                .mapToObj(String::valueOf)
                .toArray(String[]::new);

        Arrays.sort(strNumbers, (a, b) -> (b + a).compareTo(a + b));

        for (String num : strNumbers) {
            sb.append(num);
        }

        if (sb.toString().charAt(0) == '0') {
            return "0";
        }
        
        return sb.toString();
    }
}

코드 설명

  • StringBuilder sb = new StringBuilder();
    문자열을 효율적으로 생성하기 위해 StringBuilder 객체 sb를 생성합니다. 최종 결과 문자열을 생성하는 데 사용됩니다.
  • String[] strNumbers = Arrays.stream(numbers).mapToObj(String::valueOf).toArray(String[]::new);
    numbers 배열의 각 요소를 문자열로 변환하여 새로운 String 배열 strNumbers에 저장합니다.
    • Arrays.stream(numbers): numbers 배열을 스트림으로 변환합니다.
    • .mapToObj(String::valueOf): 각 정수 요소를 String 객체로 변환합니다.
    • .toArray(String[]::new): 스트림의 결과를 String 배열로 반환합니다.
  • Arrays.sort(strNumbers, (a, b) -> (b + a).compareTo(a + b));
    strNumbers 배열을 사용자 정의 비교자로 정렬합니다.
    • 정렬 기준을 문자열 (a + b) 와 (b + a)의 비교로 결정합니다.
    • (b + a).compareTo(a + b): 두 연결 결과를 비교하여 내림차순으로 정렬합니다.
  • if (sb.toString().charAt(0) == '0') { return "0"; }
    생성된 문자열이 0으로 시작하는 경우, 이는 numbers 배열의 모든 요소가 0일 때입니다. 따라서 "0"을 반환합니다.
  • return sb.toString();
    StringBuilder에 추가된 모든 요소를 문자열로 변환하여 반환합니다.
 
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

배열의 서브 어레이를 구하는 것이 포인트였다고 생각합니다. 이를 위해 자바의 copyOfRange() 함수를 이용합니다.

소스코드

import java.util.*;

class Solution {
    public int[] solution(int[] array, int[][] commands) {
        List<Integer> answerList = new ArrayList<>();
        
        for (int[] command: commands) {
            int i = command[0] - 1;
            int j = command[1];
            int k = command[2] - 1;
            int[] subArray = Arrays.copyOfRange(array, i, j);
            Arrays.sort(subArray);
            answerList.add(subArray[k]);
        }
        
        return answerList.stream().mapToInt(Integer::intValue).toArray();
    }
}

코드 설명

  • List<Integer> answerList = new ArrayList<>();
    정수형 요소를 저장할 수 있는 ArrayList 객체 answerList를 생성합니다.
    이 리스트는 각 명령(commands)에 따라 추출된 결과값들을 저장하는 역할을 합니다.
  • int[] subArray = Arrays.copyOfRange(array, i, j); Arrays.sort(subArray);
    array의 i부터 j (종료 인덱스는 포함되지 않음)까지의 부분 배열을 subArray에 복사하고, 이를 오름차순으로 정렬합니다.
    • copyOfRange(array, i, j)는 array 배열을 i부터 j-1까지 배열을 생성합니다.
  • answerList.add(subArray[k]);
    정렬된 subArray에서 k번째 요소를 가져와 answerList에 추가합니다.
  • return answerList.stream().mapToInt(Integer::intValue).toArray();
    결과 값을 int[] 배열로 변환 후 반환합니다.
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

최댓값과 최솟값을 효율적으로 관리 및 구하기 위해 최소 힙과 최대 힙을 두개 선언하고 연산에 맞게 관리합니다.

소스코드

import java.util.*;

class Solution {
    public int[] solution(String[] operations) {
        PriorityQueue<Integer> max = new PriorityQueue<>(Collections.reverseOrder());
        PriorityQueue<Integer> min = new PriorityQueue<>();
        
        for (String operation : operations) {
            String[] split = operation.split(" ");
            String command = split[0];
            int number = Integer.parseInt(split[1]);

            switch (command) {
                case "I":
                    min.add(number);
                    max.add(number);
                    break;
                case "D":
                    if (number == 1 && !max.isEmpty()) {
                        int maxNum = max.poll();
                        min.remove(maxNum);
                    } else if (number == -1 && !min.isEmpty()) {
                        int minNum = min.poll();
                        max.remove(minNum);
                    }
                    break;
            }
        }
        
        int[] answer = {0, 0};
        if (!min.isEmpty() && !max.isEmpty()) {
            answer[0] = max.poll();
            answer[1] = min.poll();
        }
        
        return answer;
    }
}

코드 설명

  • PriorityQueue<Integer> max = new PriorityQueue<>(Collections.reverseOrder());
    PriorityQueue<Integer> min = new PriorityQueue<>();
    최대 힙 max와 최소 힙 min을 초기화합니다. 이는 최소 값 및 최대 값을 빠르게 가져오거나 삭제하기 위해 사용됩니다.
  • for (String operation : operations)
    operations 배열의 각 명령어를 순차적으로 탐색합니다. 각 명령어는 삽입 또는 삭제 작업을 나타냅니다.
    • String[] split = operation.split(" ");
      명령어를 공백으로 나누어 split 배열에 저장합니다. 첫 번째 요소는 명령어(I 또는 D), 두 번째 요소는 숫자를 나타냅니다.
    • String command = split[0];
      명령어(I 또는 D)를 command에 저장합니다.
    • int number = Integer.parseInt(split[1]);
      명령어의 숫자 값을 정수로 변환하여 number에 저장합니다.
    • switch (command)
      명령어(command)에 따라 조건문을 통해 동작을 결정합니다.
      • case "I":
        number를 min과 max 두 큐 모두에 추가합니다.
      • case "D":
        • if (number == 1 && !max.isEmpty())
          number가 1이면 최대값 삭제 명령어입니다. max에서 최대값을 poll()로 제거하고, min에서도 동일한 값을 remove()로 삭제합니다.
        • else if (number == -1 && !min.isEmpty())
          number가 -1이면 최소값 삭제 명령어입니다. min에서 최소값을 poll()로 제거하고, max에서도 동일한 값을 remove()로 삭제합니다.
    • int[] answer = {0, 0};
      • 결과를 담을 배열 answer를 선언하고 초기화합니다.
    • if (!min.isEmpty() && !max.isEmpty())
      • min과 max가 모두 비어 있지 않으면, answer[0]에 max의 최대값, answer[1]에 min의 최소값을 할당합니다.
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

가장 최소의 처리량 평균 시간을 구하는 문제였습니다. 요청시간이 빠른 순대로 정렬을 하면 짧은 작업시간을 가지는 일들에 대해서는 너무 오래 기다리게 되고, 짧은 작업시간 순대로 정렬을 하면 요청이 먼저 온 작업을 처리를 하지 못하게 됩니다. 

따라서 현재 시간에 따라 처리 가능한 작업을 구하고 그 중에서 요청시간이 짧은 것을 먼저 처리합니다.

소스코드

import java.util.*;

class Solution {
    
    static class Job implements Comparable<Job> {
        int requestTime, workingTime;
        
        public Job(int requestTime, int workingTime) {
            this.requestTime = requestTime;
            this.workingTime = workingTime;
        }
        
        @Override
        public int compareTo(Job j) {
            if (this.requestTime == j.requestTime) {
                return this.workingTime - j.workingTime;
            }
            return this.requestTime - j.requestTime;
        }
    }
    
    public int solution(int[][] jobs) {
        PriorityQueue<Job> disk = new PriorityQueue<>();
        int len = jobs.length;
        
        for(int[] job: jobs) {
            disk.add(new Job(job[0], job[1]));
        }
        
        int time = 0; // 현재 시간
        int ans = 0; // 처리량 평균 구하기
        List<Job> execList = new ArrayList<>();
        
        while (!disk.isEmpty() || !execList.isEmpty()) {
            // 현재 시간에 요청된 작업을 모두 execList에 추가
            while (!disk.isEmpty() && time >= disk.peek().requestTime) {
                execList.add(disk.poll());
            }

            // 작업을 소요 시간 기준으로 정렬
            if (!execList.isEmpty()) {
                Collections.sort(execList, Comparator.comparingInt(job -> job.workingTime));
                Job exec = execList.remove(0);
                if (time < exec.requestTime) {
                    time = exec.requestTime;
                }
                time += exec.workingTime;
                ans += time - exec.requestTime;
            } else if (!disk.isEmpty()) {
                time = disk.peek().requestTime;
            }
        }
        
        return ans / len;
    }
}

코드 설명

Job 클래스

  • Job 클래스는 Comparable 인터페이스를 구현하며, 작업의 요청 시간(requestTime)과 소요 시간(workingTime)을 필드로 가지고 compareTo 메서드는 Job 객체를 요청 시간 순서로 정렬합니다. 요청 시간이 동일할 경우, 소요 시간 기준으로 정렬하도록 조건을 설정할 수 있습니다.

 

  • PriorityQueue<Job> disk = new PriorityQueue<>();
    작업 요청 시간 기준으로 정렬되는 우선순위 큐를 초기화합니다. Job 객체를 담아 요청 시간이 빠른 순서대로 작업을 처리할 수 있습니다.
  • while문 내부 변수 사용부분
    • time은 현재 시각을 나타내며, ans는 작업 완료까지 걸린 총 시간을 누적합니다.
    • execList는 현재 처리 가능한 작업 목록입니다.
  • while (!disk.isEmpty() || !execList.isEmpty()) { ... }
    • disk 큐의 작업 중 현재 time에 요청된 작업을 execList로 이동합니다.
    • execList에 작업이 있으면 소요 시간 기준으로 정렬하고, 가장 짧은 작업을 선택하여 실행합니다.
    • time이 해당 작업의 요청 시간보다 작으면, time을 그 요청 시간으로 맞춥니다.
    • time을 해당 작업의 소요 시간만큼 증가시키고, 요청부터 종료까지 걸린 시간(time - requestTime)을 ans에 더합니다.
    • 만약 execList가 비어 있고 disk에 작업이 남아 있다면, time을 다음 작업의 요청 시간으로 설정하여 작업을 진행할 수 있게 합니다.

 

제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
Programmers 알고리즘 고득점 Kit입니다.

포인트

최솟값을 찾기 위해 정렬을 사용해도 되지만 가장 효율적인 자료 구조 Heap을 이용하여 스코빌 지수의 최솟값을 찾도록 코드를 구현하였습니다.

소스코드

import java.util.*;

class Solution {
    public int solution(int[] scoville, int K) {
        PriorityQueue<Integer> scovilles = new PriorityQueue<>();
        
        for (int level: scoville) {
            scovilles.add(level);
        }
        
        int mix = -1;
        int ans = 0;
        while (scovilles.peek() < K) {
            if (scovilles.size() < 2) {
                return -1;
            }
            int first = scovilles.poll();
            int second = scovilles.poll();
            mix = first + second * 2;
            scovilles.add(mix);
            ans++;
        }
        
        return ans;
    }
}

코드 설명

  • PriorityQueue<Integer> scovilles = new PriorityQueue<>();
    스코빌 지수를 저장하는 Heap을 생성합니다. 해당 힙은 최소 힙으로 구현합니다.
  • 섞은 음식의 스코빌 지수
    • while 루프는 큐의 최솟값(scovilles.peek())이 K 미만인 동안 반복됩니다.
    • 이때 큐의 크기가 2 미만이 되면, 더 이상 결합할 수 없으므로 -1을 반환하여 목표를 달성할 수 없음을 나타냅니다.
    • 최솟값 두 개를 꺼내어(poll() 메서드 사용) 결합하여 새로운 스코빌 지수(first + second * 2)를 계산합니다.
    • 새로 만든 스코빌 지수를 큐에 다시 추가하고, 결합 횟수 ans를 증가시킵니다.
  • 섞은 횟수를 반환합니다.
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
접은 글을 통해 먼저 답변을 해보시고 제가 정리한 답을 확인해보시기 바라겠습니다!!

면접 리스트

NAT 네트워크를 사용했을때의 사이드 이펙트는 없는가?

더보기

NAT 네트워크를 사용하면 사이드 이펙트가 있습니다.

 

기존 라우터는 4계층의 하드웨어로써 전송계층의 port 번호는 보지 못합니다. 하지만 NAT 도입시, 세그먼트에 해당하는 머신에 데이터를 주고 받기위해 포트번호를 라우터가 열람할 수 있게 되어 스푸핑이 일어나 중간자 공격이 일어날 수 있습니다.

 

또 NAT은 IP 주소와 포트번호를 수정하여 Transport layer의 특징인 end to end 원칙을 위배하고 문제 해결 프로세스를 복잡하게 만들 수 있습니다.

 

또한 NAT은 오버헤드를 도입하여 트래픽이 많은 네트워크에서 네트워크 성능에 영향을 미칠 수 있습니다. 주소 변환과정에서 네트워크 병목현상이 일어날 수 있습니다. NAT은 공용 IP를 보존하고 IP 주소의 확장성을 제공하지만 보안에 취약합니다.

라우팅 알고리즘은 모든 라우터에서 실행되어야 하는가?

더보기

라우팅 알고리즘네트워크 전체에서 효율적이고 안정적인 패킷 라우팅을 보장하기 위해 모든 라우터에서 실행되어야 합니다.

 

특정 라우터에서만 실행될 경우 라우팅 결정이 최적화 되지 않고 패킷 전달이 비효율적일 수 있습니다. 왜냐하면 각 라우터는 네트워크의 상황에 따라 경로가 실시간으로 변경되어 라우팅 정보를 교환하고 라우팅 테이블을 업데이트하며 네트워크 조건에 따라 새 경로를 계산할 수 있기 때문입니다. 또 모든 라우터에서 라우팅을 실행하면, 로드 밸런싱 기술을 활용할 수 있습니다. 리소스 활용률을 최적화하고 정체를 방지하기 위한 트래픽을 여러 경로로 분산시킵니다. 이를 사용하기 위해 네트워크 트래픽을 각 라우터마다 계산해야하므로 라우팅 알고리즘이 모든 라우터에서 적용되어야 합니다.

 

이러한 이유로 라우팅 알고리즘은 모든 라우터에서 실행되어야 합니다.

라우터에서의 라우팅과 포워딩의 차이를 설명해주세요.

더보기

라우팅과 포워딩은 네트워크 레이어의 역할로 패킷을 전달하는 데에 목적이 있습니다. 각각을 살펴보면

 

라우팅은 데이터 패킷이 네트워크를 통해 대상에 도달할 수 있는 최적의 경로를 결정하는 프로세스입니다. 대상 IP 주소를 기반으로 패킷을 전달해야하는 다음 홉 또는 라우터에 대한 결정을 수행합니다. OSPF나 BGP와 같은 라우팅 알고리즘은 사용가능한 경로 및 관련 메트릭에 대한 정보를 포함하는 라우팅 테이블을 관리하고 업데이트하면서 사용됩니다.

 

포워딩수신 인터페이스에서 송신 인터페이스로 전송하는 프로세스입니다. 라우팅 결정이 이루어지면 대상 IP 주소를 검사하고 각 인터페이스의 IP 주소를 검사하여 가장 길게 맞춰진 인터페이스로 패킷을 전달하여 다음 홉으로 전송합니다.

loopback address는 무엇인가? 또 어떻게 쓰일 수 있는가

더보기

loopback address로컬 장치에서 네트워크 연결을 테스트하는 특수한 IP 주소입니다. 일반적으로 IPv4의 경우 127.0.0.1을 가지고 있으며 네트워크 응용 프로그램이 루프백 주소로 데이터를 보낼 때 기본적으로 자신에게 데이터를 보내는 것입니다. 루프백 주소로 전송되는 네트워크 트래픽을 처리하는 운영체제 내의 소프트웨어 구성 요소인 루프백 드라이버에 연결됩니다.

 

loopback address는 다양한 용도로 사용됩니다.

 

루프백 드라이버를 사용하면 루프백 주소로 주소 지정된 네트워크 패킷을 장치 내에서 내부적으로 라우팅할 수 있으므로 실제 물리적 네트워크를 통해 데이터를 전송하지 않고도 네트워크 통신을 시뮬레이션할 수 있습니다. 즉, 루프백 주소로 전송되는 네트워크 트래픽은 IP, TCP 및 UDP와 같은 프로토콜을 포함하여 장치 자체의 네트워크 스택에서 처리됩니다.

 

개발자는 네트워크 연결 없이 응용 프로그램을 루프백 주소를 이용함으로써 테스트 할 수 있습니다. 트래픽을 로컬 호스트로 유도하여 통신과 서비스가 올바르게 작동하는 지 확인할 수 있습니다. 여기서 네트워크 관련 문제를 확인하며 해결할 수 있고, 외부 네트워크 연결없이 로컬 테스트 및 검증을 수행할 수 있습니다.

default gateway는 무슨 역할을 하는가?

더보기

default gateway router는 다른 네트워크에서 또는 다른 네트워크로 향하는 네트워크 트래픽의 출입구 역할을 하는 라우터입니다. 주요한 역할로 데이터 패킷의 라우팅을 용이하게 하는 것이 있습니다.

 

기본 게이트웨이는 서로 다른 네트워크 간의 네트워크 트래픽에 대한 시작 및 종료 지점 역할을 합니다. 로컬 네트워크와 외부 네트워크 간에 데이터를 라우팅하고, 연결을 제공하며, 장치가 다른 네트워크의 장치와 통신할 수 있도록 하며, 로컬 네트워크 외부의 대상으로 데이터를 전송하는 기본 경로 역할을 하며, NAT(네트워크 주소 변환)을 수행합니다, 네트워크를 보호하기 위한 방화벽 기능과 같은 보안 기능을 제공합니다.

만약 라우팅 테이블에 다음 목적지에 대한 맵핑정보가 없다면 라우터는 어떻게 동작하는가?

더보기

라우팅 테이블에 다음 대상에 대한 매핑 정보가 없으면 라우터는 패킷을 전달하기 위한 적절한 넥스트 홉을 결정할 수 없으며 구성된 경우 패킷을 폐기하거나 기본 게이트웨이로 전송합니다.

 

패킷을 삭제하고 대상에 연결할 수 없음을 나타내는 ICMP(Internet Control Message Protocol) 메시지를 소스로 보낼 수 있습니다. 또는 기본 게이트웨이가 구성된 경우 라우터는 라우팅 테이블의 특정 경로와 일치하지 않는 패킷의 기본 종료 지점 역할을 하는 기본 게이트웨이로 패킷을 전달할 수 있습니다.

'기술면접 > 네트워크' 카테고리의 다른 글

[기술면접] 네트워크 5  (3) 2024.11.14
[기술면접] 네트워크 3  (1) 2024.11.10
[기술면접] 네트워크 2  (0) 2024.11.08
[기술면접] 네트워크 1  (2) 2024.11.06
제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁
접은 글을 통해 먼저 답변을 해보시고 제가 정리한 답을 확인해보시기 바라겠습니다!!

면접 리스트

여러개의 프로세스가 존재할 때 트랜스포트 레이어의 동작을 설명해보세요

더보기

응용 계층과 전송 계층 사이의 인터페이스 socket을 이용하여 세그먼트를 프로세스에게 전달합니다. 각 socket에는 매핑되어 있는 port 넘버가 있고, port 넘버는 호스트에서 실행중인 프로세스를 구분합니다. 이 포트 넘버를 소켓에 바인딩하고 데이터를 보낼 때에는 트랜스포트 레이어에서 제공하는 포트 멀티플렉싱을 합니다.

 

데이터를 받을 때에는 전송계층은 세그먼트 헤더의 대상 포트넘버를 검사하여 디멀티플렉싱을 통해 포트넘버와 연관된 소켓을 찾아 데이터를 넘겨줍니다.

소켓 생성과 삭제에서 발생하는 오버헤드를 줄이는 방법은 무엇이 있을까요?

더보기

많은 소켓의 생성과 삭제에서 발생할 수 있는 오버헤드를 줄일 방법은 소켓을 풀에 유지하여 관리하는 방법입니다.

 

연결이 필요한 경우 풀에서 사용 가능한 소켓을 할당하고 연결이 닫히면 다시 풀에 반환하여 관리하면 소켓이 재사용되므로 생성 및 삭제의 오버헤드를 줄일 수 있습니다.

 

또 다른 방법으로 TCP는 소켓 재사용을 허용하므로 새 소켓을 만들 필요없이 새로운 주소와 포트로 바인딩하여 소켓을 재사용하는 방법이 있습니다. 만약 응용 프로그램에서 허용하는 경우라면 영구 연결을 사용하여 소켓의 생성 및 삭제의 오버헤드를 줄일 수 있습니다.

N+1번의 세그먼트에 대한 ACK가 도착하고 N에 대한 ACK는 도착하지 않았을 때 TCP는 어떻게 동작하는가?

더보기

Selective ack 일 때 N+1번 세그먼트에 대한 ACK가 도착했다는 것은 N에 대해서도 패킷이 도달했다는 것을 알 수 있습니다.

 

TCP는 accumulative ack로 ack를 매 패킷마다 보내지 않을 수 있고, 순서대로 마지막에 받은 패킷에 대한 ack를 보낼 수 있습니다.

 

따라서 N+1번 세그먼트에 대한 ACK가 도착했다는 것은 N번 세그먼트에 대해서도 도달했다는 것을 알 수 있고, window사이즈만큼 sliding window를 이동시켜 다음 패킷을 보낼 준비를 합니다.

네트워크 레이어의 목적은 무엇일까요?

더보기

네트워크 레이어의 목적으로는 크게 라우팅포워딩이 있습니다.

 

라우팅출발지에서부터 목적지로까지 최적의 경로를 결정합니다. 라우팅 프로토콜과 알고리즘을 사용하여 정체 및 비용과 같은 요소를 기반으로 최적의 경로를 결정합니다.

 

포워딩은 라우팅을 통해 최적의 경로가 밝혀지면 결정된 경로를 따라 해킷 헤더의 목적지 주소를 검사하여 long prefix 알고리즘을 바탕으로 다음 노드로 데이터 패킷을 전달하는 역할을 합니다.

왜 트랜스포트 레이어에 checksum이 있는데 네트워크 레이어에도 체크섬이 있는가?

더보기

전송 계층과 네트워크 계층 모두 체크섬을 사용하여 전송된 데이터의 무결성을 보장합니다. 그러나 체크섬은 다른 용도로 사용됩니다.

 

TCP 또는 UDP 체크섬과 같은 전송 계층 체크섬은 데이터가 소스 호스트와 대상 호스트 간에 오류 없이 전송되었는지 확인하는 데 사용됩니다. 체크섬은 전송 계층 헤더 및 데이터 필드의 내용을 기반으로 계산됩니다. ⇒ 데이터 포함

 

반면 IPv4 또는 IPv6 체크섬과 같은 네트워크 계층 체크섬은 데이터가 src 네트워크와 dest 네트워크 간에 오류 없이 전송되었는지 확인하는 데 사용됩니다. 체크섬은 네트워크 계층 헤더 및 데이터 필드의 내용을 기반으로 계산됩니다. ⇒ 헤더 체크

 

즉, 전송 계층 체크섬은 단일 네트워크 연결 내에서 종단 간 오류 탐지 기능을 제공하는 반면 네트워크 계층 체크섬은 여러 네트워크 연결에 걸쳐 오류 탐지 기능을 제공합니다. 이러한 이중화는 컴퓨터 네트워크에서 데이터 전송의 안정성과 무결성을 보장하는 데 도움이 됩니다.

'기술면접 > 네트워크' 카테고리의 다른 글

[기술면접] 네트워크 5  (3) 2024.11.14
[기술면접] 네트워크 4  (5) 2024.11.10
[기술면접] 네트워크 2  (0) 2024.11.08
[기술면접] 네트워크 1  (2) 2024.11.06

+ Recent posts