내일배움캠프 Node.js 본캠프 38일차

김선우·2024년 10월 1일
post-thumbnail

알고리즘 문제 풀어보기

체육복

문제 설명

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

제한사항

전체 학생의 수는 2명 이상 30명 이하입니다.
체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

풀이 코드

function solution(n, lost, reserve) {
    var realLost = lost.filter(v => !reserve.includes(v)).sort((a, b) => a - b);

    var realReserve = reserve.filter(r => !lost.includes(r)).sort((a, b) => a - b);

    var answer = n - realLost.length;

    for(i = 0; i < realLost.length; i++){

        for(j = 0; j < realReserve.length; j++){
            if(realReserve[j] === realLost[i] - 1 || realReserve[j] === realLost[i] + 1){
                answer += 1;
                realReserve[j] = -1;
                break;
            }
        }
    }

    return answer;
}

풀이 과정

여벌없이 체육복을 분실한 학생의 번호를 담은 realLost와 분실없이 여벌 체육복을 가진 학생의 번호를 담은 realReserve배열을 만듦.(lost나 reserve값이 정렬이 되지 않은 경우를 생각해서 오름차순 정렬을 해줌.) => answer = 체육수업에 참여할 수 있는 학생의 수이므로 전체 학생의 수 - 여벌없이 체육복을 분실한 학생수(n-realLost.length)
realLost의 수만큼 반복하는 반복문을 통해 realLost의 i번째 값보다 1크거나 1작은 값이 realReserve에 존재하면 answer값을 1추가하고 realReserve에서 그 값을 제거해줌.

게임 기획

  • 만약 기획을 하게 된다면 꼭 다른 레퍼런스를 가지고와서 저런걸 어떻게 만들었더라라는 것을 확실하게 정립, 글로 한번 정리를 해본 다음에 만드는게 좋음.
    • ex) 점핑 액션 게임을 만든다고 하면 별의커비라거나 슈퍼마리오라거나 그런 게임을 레퍼런스로 가지고 와서 어떤식으로 만들었는지 정리 후 기획.

예시

1. 게임 장르 정하기

사이드뷰, 점핑 액션 게임

2. 게임 컨텐츠

  • 1) 스테이지 진행
    • 시간에 따른 점수 획득
    • 스테이지에 따라서 더 높은 점수 획득
  • 2) 아이템 획득
    • 아이템 종류에 따라 다른 점수 획득
    • 스테이지에 따라 생성되는 아이템 구분
      • 1스테이지에서는 1번 아이템만, 2스테이지부터는 2번 아이템까지

3. 데이터 테이블 만들기

#으로 시작하는 것은 기획 관리용 이름

  • 1) 스테이지
    • json
      {
        "name": "stage", // 테이블 이름
        "version": "1.0.0", // 테이블 버전
        "data": [
          { "id":  1000, "score": 0 },
          { "id":  1001, "score": 100 },
          { "id":  1002, "score": 200 },
          { "id":  1003, "score": 300 },
          { "id":  1004, "score": 400 },
          { "id":  1005, "score": 500 },
          { "id":  1006, "score": 600 }
        ]
      }
  • 2) 아이템

    • json
      {
        "name": "item",
        "version": "1.0.0",
        "data": [
          { "id":  1, "score": 10 },
          { "id":  2, "score": 20 },
          { "id":  3, "score": 30 },
          { "id":  4, "score": 40 },
          { "id":  5, "score": 50 },
          { "id":  6, "score": 60 }
        ]
      }
  • 3) 아이템해금

    • json
      {
        "name": "item_unlock",
        "version": "1.0.0",
        "data": [
          { "id":  101, "stage_id": 1001, "item_id": 1 },
          { "id":  201, "stage_id": 1002, "item_id": 2 }
        ]
      }

4. 패킷 구조 설계

  • 1) 공통 부분

  • 2) 요청

    • 최초 접속
      {
      	handlerId: 0,
      	userId: 0,
      	clientVersion: "1.0.0",
      	payload: {},
      }
    • 스테이지 이동
      {
      	// 공통 부분
      	handlerId: 0,
      	userId: 0,
      	clientVersion: "1.0.0",
      	payload: {
      		// 스테이지 정보
      		currentStage: 0,
      		targetStage: 0,
      	}
      }
    • 아이템 획득
      {
      	// 공통 부분
      	handlerId: 0,
      	userId: 0,
      	clientVersion: "1.0.0",
      	payload: {
      		// 아이템 정보
      		itemId: 0,
      	}
      }
    • 그외
      • 게임시작, 종료등
  • 3) 응답

{
  "status": "success",
}

개발환경 설정

  • nodemon 라이브러리
    • 코드가 변경이 일어났을 때 서버에 그걸 적용하고 싶으면 서버를 껏다키는 재시동 과정을 수동으로 해야하는데 코드 감시를 실시간으로 하면서 필요한게 있거나 변경이 일어났을 때 자동으로 서버를 재시작해주는 편한 개발을 도와주는 유틸리티 툴.

서버 로직 개발

1. 데이터 테이블 로드

fs(파일시스템)를 사용해 서버에서 필요한 데이터 테이블을 메모리에 로드할 수 있다.

fs

  • node.js의 fs 모듈은 파일 시스템에 접근하고, 파일을 읽고 쓰는 기능을 제공함.
  • 동기적 및 비동기적 방식 모두로 파일I/O 작업을 수행할 수 있음.
  • 파일 생성, 읽기, 쓰기, 삭제, 수정 등의 작업을 할 수 있음.
  • 다양한 형태의 파일 기반 작업을 가능하게 함.

데이터 테이블의 관리 방법

  • DB, CDN, file 등으로 테이블을 관리.

file로 관리

  • 서버의 파일에 데이터 테이블을 저장, 클라이언트가 가지고있는 파일을 서버의 파일과 검증 작업을 통해 데이터 테이블 관리
    => 서버에서 유저에 대한 메시지를 처리

DB로 관리

  • 파일이 가지고 있던 데이터 테이블을 DB에 데이터화 시켜서 저장.(파일은 기획팀에서 관리)
    => 기획팀에서 파일에 대한 데이터 테이블을 DB에 보냄, 유저가 서버에 요청 시 서버가 DB에 접근해 파일을 읽어오게 되고 유저에 대한 메시지를 처리.

CDN으로 관리

  • 파일을 CDN에 업로드, 요청에 따라 CDN에서 파일을 읽어옴

  • 클라이언트에서 필요한 데이터와 서버에서 필요한 데이터가 다르기 때문에 여러가지 방법을 이용해서 데이터 테이블을 관리함.(한가지만 사용하는게 아님.)

2. 유저 접속 관리

유저 모델을 통해 접속한 유저들의 정보를 메모리에 저장할 수 있다.

유저가 서버에 웹소켓이란 프로토콜을 통해 접속을 하게 되면 socketId라는게 발급됨.

uuid - 서버에서 우리가 임의로 발급해 줄 ID
socketId - 현재 유저가 서버에 접속해있다는 상태를 저장하기 위해 같은 소켓으로 계속 데이터 교환을 할 것 인데 해당 값을 저장하기위해 존재.

3. 커넥션 핸들러

서버에서 유저를 위한 데이터를 생성해 저장할 수 있다.

4. 이벤트 핸들러

기획한 컨텐츠를 처리하기 위한 이벤트 핸들러를 만들 수 있다.

핸들러 맵핑

각 핸들러에 고유 ID를 부여해 호출하는 기법

5. 변경된 패킷구조 정리

  • 공통 패킷

모의 면접

이번 모의 면접의 경우에는 면접 질문 리스트가 미리 나와있어서 준비하기가 편했다.

부족했던 부분

  • 첫번째 질문이었던 'IP의 개념과 IP 주소 체계, 서브넷 마스크에 대해 설명해주세요. '에서 꼬리 질문으로 IPv6의 진수와 서브넷 마스크를 쓰는 이유에 대해 질문해주셨는데 IPv6의 진수를 대답하지 못했다.
  • 두번째 질문이엇던 '브라우저에 네이버 주소를 입력했을 때 네트워크 상에서 발생하는 과정을 설명해주세요.'부분에 대한 꼬리 질문으로 DNS에 관한 질문을 해주셨는데 이에 잘 답변하지 못했다.(DNS 동작 관련)
  • 세번째 질문이었던 '라우터와 라우팅(동적 라우팅, 정적 라우팅)에 대해 설명해주세요.'의 꼬리 질문으로 동적라우팅이 사용하는 프로토콜에 대한 질문을 주셨는데 답변하지 못했다.

보완할 것

1) 면접관님이 주신 링크를 통해 이번 모의면접의 주제를 다시 공부한다.
2) 꼬리 질문에 대한 부분을 제대로 대답하지 못한 부분이 많으므로 면접 준비시 이런 질문이 나오면 연관 질문으로 어떤 질문을 더 주실까 하는 부분에 대해 더 생각해보고 준비한다.

0개의 댓글