오늘의 목표

더보기

✔️ 프로그래머스 코테 문제 풀기

✔️ 팀프로젝트 회의

 


⏱️ 오늘의 일정

프로그래머스 코테 문제 풀기

팀 프로젝트 회의


📜 프로그래머스 코테 문제 풀기

 

Jaden 문자열 만들기

 

https://github.com/YamSaeng/AlgorithmCodingTest/tree/main/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/2/12951.%E2%80%85JadenCase%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0

 

AlgorithmCodingTest/프로그래머스/2/12951. JadenCase 문자열 만들기 at main · YamSaeng/AlgorithmCodingTest

This is an auto push repository for Baekjoon Online Judge created with [BaekjoonHub](https://github.com/BaekjoonHub/BaekjoonHub). - YamSaeng/AlgorithmCodingTest

github.com

 

function solution(s) {
    var answer = '';

    let isFirst = false;
    for (let i = 0; i < s.length; i++) {
        if (s[i] === ' ') {
            answer += ' ';
            isFirst = false;
        }
        else if (isFirst === false) {
            answer += s[i].toUpperCase();
            isFirst = true;
        }
        else {
            answer += s[i].toLowerCase();
        }
    }

    return answer;
}

 

문제에서 설명해준 대로 코드를 구성하니 쉽게 풀 수 있었다.

 

📜 팀프로젝트 회의

 

앞서 언급한대로 새로운 팀프로젝트가 시작됐다.

이번 팀 프로젝트는 타워 디펜스 게임을 만드는 프로젝트다.

 

기본적으로 캠프에서 타워 디펜스를 제공해주고, 팀에서는 그에 해당하는 서버를 만드는 것을 목표로 삼는다.

 

와이어 프레임 ( 화면 구성 )

 

회원가입과 로그인은 express를 이용해 처리해주고,

메인인 게임에 들어가면 서버와는 웹소켓을 활용해 통신해 주도록 구성했다.

 

이번 팀 프로젝트는 총 6명이서 진행하는데,

맡아야할 파트를 나누는게 참 어려웠다. 긴 회의를 거친 끝에 다음과 같이 분배했다.

 

 

 

나는 회원가입과 로그인 파트를 맡았다.

 

 

 

 

회원가입한 유저들을 관리하는 users 테이블과

게임 시작할때 게임 초기화에 필요한 데이터가 들어있는 initGame 테이블,

몬스터에 대한 데이터가 들어있는 monster 테이블

타워에 대한 정보가 들어있는 tower 테이블

타워를 업그레이드 할때 능력치의 비율이 들어있는 upgrade 테이블로 DB를 구성했다.

 

사실상 insert 하고 delete 하는 테이블은 users 테이블 하나고 나머지는 모두 데이터 자체가 들어있는 테이블이다.

 

 

내일까지 회원가입과 로그인을 완성해 다른 팀원분들이 테스트 할 수 있도록 준비해야겠다!!

 

오늘의 목표

더보기

✔️ CS 정리

✔️ 개인과제 완성


⏱️ 오늘의 일정

CS 정리

개인과제 완성


📜 CS 정리

IP 주소의 체계, 사설망과 공인망에 대해 정리했다.

2024.10.07 - [CS] - [CS] IP 주소의 체계, 사설망, 공인망

 

[CS] IP 주소의 체계, 사설망, 공인망

IP 주소네트워크에서 통신을 위한 일련의 규칙이자 약속( 통신규약 )들이 존재하며, 이를 프로토콜이라고 부른다.그 중 인터넷 통신을 위한 프로토콜도 존재하는데 대표적인 것이 바로 IP다.IP는

program-yam.tistory.com

 

 

📜 개인 과제 완성

 

10월 7일 정오까지 개인 과제 제출시간이라서 시간에 맞게 제출했다.

 

https://github.com/YamSaeng/DinoRunner

 

GitHub - YamSaeng/DinoRunner

Contribute to YamSaeng/DinoRunner development by creating an account on GitHub.

github.com

 

기존에 설명했던 https://dinorunner.com/ko/

 

크롬 다이노 게임 온라인

T-Rex Dinosaur (Dinosaur Google) - 인터넷이 없을 때 Chrome 브라우저에 숨겨진 게임의 복제본. 시작하려면 스페이스바를 누르십시오. 스페이스바 또는 위쪽 화살표와 아래쪽 화살표(↓)를 사용하여 공룡

dinorunner.com

 

위 게임에서 추가한 부분은 다음과 같다.

Update() {
        this.userScoreUpdateTime -= 15;

        // 1초마다 서버에서 Score 계산
        if (this.userScoreUpdateTime < 0) {
            this.userScoreUpdateTime = USER_SCORE_UPDATE_TIME;

            if (this.users.length > 0) {
                // 접속중인 유저들을 순환하면서 스테이지에 맞게 점수 증가
                this.users.forEach(user => user.Update());

                // HighScore를 갱신
                for (let i = 0; i < this.users.length; i++) {
                    if (this.users[i].score > this.HighScore.score) {
                        this.HighScore.score = this.users[i].score;
                        this.HighScore.userId = this.users[i].userUUID;
                        
                        this.users[i].socket.emit("response", {
                            packetType: S2C_PACKET_TYPE_NEW_HIGH_SCORE,
                            data: { userId: this.HighScore.userId, score: this.HighScore.score }
                        });
                    }                  
                }                
            }
        }       
    }

서버에서 매 시간 1초마다 접속중인 유저들을 순환하면서 점수를 스테이지에 맞게 증가시켜준다.

이처럼 매 시간마다 서버에서 반복하면서 로직을 처리하는 방식에 대한 것을 튜터님에게 따로 물어봤다.

 

지금처럼 접속하는 유저가 적을 경우에는 서버에 부담이 가지 않아 위처럼 구성해도 되지만, 

서버에 접속하는 유저가 많아지면 서버에 부담이 가서 위와 같은 방법은 추천하지 않는다고 피드백을 받았다.

 

대신 점수를 검증하는 부분을 클라가 점수를 쌓기 시작한 시간과 어떤 특정한 점수에 도달했을 때 시간을

서버에 전송해서 서버는 두 시간 차를 토대로 점수를 계산해 인증해주는 방식이 서버에 부담이 가지 않는 방식이라는 말도 추가로 피드백을 받았다.

 

 

나는 기본적으로 서버에서 모든 로직을 담당하고 그냥 클라는 서버에서 처리한 결과를 보여주는 방식으로만 생각하긴 했는데, 물론 내 생각처럼 구성하는 서버도 존재한다고는 했다.

 

아마도.. 위와 같은 부분을 잘 구분( 서버에서 처리할건지, 클라에서 처리할 건지) 하고 설정하는 것이 기술이라고 생각 할 수 있긴 할 것 같다.

 

Update() {
        this.rankingScoreUpdateTime -= 15;
        if (this.rankingScoreUpdateTime < 0) {
            // 업데이트한 랭킹 점수를 접속 중인 유저들에게 전달                        
            this.rankingScoreUpdateTime = RANK_SCORE_UPDATE_TIME;
            let scoreArray = this.users.map((user) => {
                const score = [];
                score.push({
                    userUUID: user.userUUID,
                    score: user.score,
                    currentStage: user.currentStage
                });
                return score;
            });

            this.BroadCast({ packetType: S2C_PACKET_TYPE_RANK_SCORE_UPDATE, data: scoreArray });;
        }
    }

 

유저들의 점수를 계산하고 나서는 BroadCast를 활용해 유저들의 점수를 접속중인 모든 유저들에게 전달한다.

 

 

keydown = (event) => {
        if (event.code === "Space") {
            this.jumpPressed = true;
        }

        if (event.code === "ArrowLeft") {
            this.speed = -PLAYER_SPEED;
        }

        if (event.code === "ArrowRight") {
            this.speed = PLAYER_SPEED;
        }
    };

 

좌우 키를 입력하면 speed에 값을 줘서 공룡 캐릭터를 움직일 수 있도록 변경했다.

 

keydown = (event) => {       
        // A키를 누르면 불꽃 발사
        if (event.code === "KeyA") {
            if (this.fireAttackTimer <= 0 && this.fireCount > 0) {
                let game = Game.GetInstance();
                if (game != null) {
                    this.fireCount--;
                    game.jobQue.push(new Job(JOB_TYPE_CREATE_OBJECT_FIRE,
                        OBJECT_TYPE_FIRE, this.x, this.y));

                    this.fireAttackTimer = FIRE_ATTACK_TIMER;
                }
            }
        }

        // R키를 누르면 불꽃 발사
        if (event.code === "KeyR") {
            this.fireCount = FIRE_COUNT;
        }
    };

 

'A'키를 입력하면 불꽃을 발사할 수 있도록 하고, R키를 누르면 불꽃을 재장전한다.

 

// 불꽃 관리
class FireController {
    constructor(ctx, scaleRatio, itemController) {
        this.fireId = 1; // 관리중인 fire 구분하기 위한 id 값
        this.fires = [];
        this.ctx = ctx;
        this.canvas = ctx.canvas;
        this.scaleRatio = scaleRatio;
        this.itemController = itemController;
    }

    // 불꽃 생성
    CreateFire(spawnXPosition, spawnYPosition) {
        const newFire = new Fire(this.fireId, this.ctx, this.scaleRatio);
        newFire.SetPosition(spawnXPosition, spawnYPosition);

        this.fires.push(newFire);
        this.fireId++;
    }

    // 불꽃 업데이트
    Update(gameSpeed, deltaTime) {       
        // 충돌한 불꽃이 있으면 제거
        this.fires.forEach((fire)=>{
            if(fire.isCollide == true)
            {
                this.fires = this.fires.filter(collideFire => collideFire.id !== fire.id);
            }
        })

        this.fires.forEach((fire) => {
            fire.update(gameSpeed, deltaTime);
        });
        
        this.fires = this.fires.filter(fire => fire.x < 800);
    }

    // 매개변수로 받은 sprites 배열과 충돌하는지 확인
    CollideWithMultiple(sprites) {
        let isCollider = false;

        for (let i = 0; i < this.fires.length; i++) {
            for (let j = 0; j < sprites.length; j++) {
                // 충돌 여부 확인 하고 기록
                if (this.fires[i].collideWith(sprites[j])) {
                    sprites[j].isCollide = true;
                    this.fires[i].isCollide = true;

                    // 부딪힌 대상 위치에 아이템 생성
                    this.itemController.createItem(sprites[j].x);

                    break;
                }
            }
        }

        return isCollider;
    }

    Draw() {
        this.fires.forEach((fire) => fire.draw());
    }
}

 

불꽃은 위 클래스에 관리하고, 기본적으로는 오른쪽으로만 움직인다.

불꽃은 isCollide라는 변수를 가지고 있고, 해당 변수를 통해 충돌여부를 확인할 수 있다.

 

불꽃과 선인장이 부딪히면, 해당 자리에 아이템을 생성하고 불꽃과 선인장은 사라진다.

 

UpdateObject()
{
        if (this.cactiController.collideWithSingle(this.player)) {     
            Session.GetInstance().SendEvent(C2S_PACKET_TYPE_COLLIDE_CACTUS);                   
        }       

        if(this.itemController.collideWith(this.player)){
            Session.GetInstance().SendEvent(C2S_PACKET_TYPE_GET_ITEM);            
        }
}

 

플레이어가 선인장에 부딪히면 현재 스테이지에 비례하게 점수가 차감된다.

아이템과 부딪히면 점수가 증가한다.

 

🌙 하루를 마치며

1주일간 진행한 개인과제 주차가 끝났다.

10월 8일 오전 10시에 팀 프로젝트 발제가 있을 예정이다.

타워 디펜스( 유니티로 제공 )에 관한 서버를 만들 것이라는 공지를 전달 받았다.

 

이번에도 잘 참여해서 팀프로젝트를 완성할 수 있도록 노력해야겠다.

IP 주소

네트워크에서 통신을 위한 일련의 규칙이자 약속( 통신규약 )들이 존재하며, 이를 프로토콜이라고 부른다.

그 중 인터넷 통신을 위한 프로토콜도 존재하는데 대표적인 것이 바로 IP다.

IP는 Internet Protocol의 약자로 인터넷 통신을 위한 일련의 통신 규칙들을 지칭한다.

IP기반 네트워크 환경에서 단말장치들이 서로를 인식하고 통신을 하기 위해 지정되는 주소체계를 IP 주소라고 부른다.

 

기본적으로 네트워크에 연결되는 단말장치에 탑재된 하나의 랜카드는 하나의 IP주소를 가진다.

유일한 값을 가지는 MAC 주소와는 달리 IP 주소는 보통 랜카드에 연결되는 네트워크에 따라 주소 값이 동적으로 변경된다. 

 

IPv4와 IPv6 주소 체계

IPv4 주소의 길이는 총 32bit로 총 2^32 = 4,294,967,296 개의 IP 주소를 표현할 수 있다.

네트워크 규모가 커질수록 단말장치의 수는 점점 늘어나고, 이에 따라 IP 주소의 고갈을 염려해야한다.

그래서 등장한 것이 바로 IPv6다.

 

현재 사용하는 IP 주소는 32 bit 길이의 IPv4인 반면에 IPv6는 12 bit 길이로 IP 주소의 고갈 문제를 해결할 수 있다.

하지만 당장 IPv6로 적용하기는 대부분의 통신 장비들이 IPv4 주소 기반으로 제작되어 운용중이라 IPv6기반의 장비로 교체하거나 적용하기는 어렵다.

 

앞서 언급한 것처럼 IPv6로 주소체계를 바꾸기에는 어려우므로 IP 주소를 보다 효율적으로 사용할 필요가 있다.

그 방법 중 하나가 네트워크를 사설망과 공인망으로 구분하고, 할당되는 IP 주소를 달리해 사용하는 것이다.

 

사설망과 공인망

공인망( = 공중망, 외부망 )은 사용자가 세계 어디에 있더라도 접속할 수 있는 네트워크 즉, 인터넷이다. 

공인망에서 쓰이는 IP 주소를 공인 IP라고 부르고, 인터넷상에서 유일한 IP 주소 값을 가진다.

 

사설망( = 내무방 )은 인터넷과 달리 특정 조직이나 기관 내에 독립적으로 사용하는 네트워크를 말한다. 인트라넷이 여기에 해당한다. 사설망에서 적용되는 IP 주소를 사설 IP라고 부른다. 사설 IP는 인터넷과 같은 외부망에서는 사용할 수 없고, 내부 네트워크에서만 사용할 수 있다. 외부 접속 목적이 아니라 사설망 내부 통신에서만 활용되기 때문에 다른 사설망에서 중복해서 사용해도 된다.

 

사설망과 공인망 사이의 통신 ( NAT )

사설망이라고 해서 인터넷을 이용할 수 없는 것은 아니다. 사설망과 공인망 사이에 망을 중계하는 역할을 하는 네트워크 장비를 하나 두고, 이 네트워크 장비에서 사설망의 IP 주소를 공인 IP 주소로 변경해 데이터를 중계하면 사설망에서도 인터넷을 이용할 수 있다.

 

네트워크 장비는 사설 IP와 공인 IP를 모두 가지고 있으며, 자신을 지나는 데이터의 사설 IP 주소를 자신의 공인 IP 주소로 바꾸어 중계한다. 이러한 기능을 네트워크 주소 변환( NAT, Network Address Translation )이라고 한다.

이 같은 NAT 기능을 수행하는 네트워크 장비를 보통은 '게이트웨이'라고 부른다.

 

'CS' 카테고리의 다른 글

[CS] 디자인 패턴  (0) 2024.11.11
[CS] 랜카드, MAC 주소  (0) 2024.10.02
[CS] 웹서버와 게임서버  (0) 2024.08.25
[CS] 문자 집합과 인코딩  (0) 2024.08.19

오늘의 목표

더보기

✔️ 프로그래머스 코테 문제 풀기

✔️ 개인 과제


⏱️ 오늘의 일정

프로그래머스 코테 문제 풀기

개인 과제


📜 프로그래머스 코테 문제 풀기

 

이진 변환 반복하기

https://github.com/YamSaeng/AlgorithmCodingTest/tree/main/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/2/70129.%E2%80%85%EC%9D%B4%EC%A7%84%E2%80%85%EB%B3%80%ED%99%98%E2%80%85%EB%B0%98%EB%B3%B5%ED%95%98%EA%B8%B0

 

AlgorithmCodingTest/프로그래머스/2/70129. 이진 변환 반복하기 at main · YamSaeng/AlgorithmCodingTest

This is an auto push repository for Baekjoon Online Judge created with [BaekjoonHub](https://github.com/BaekjoonHub/BaekjoonHub). - YamSaeng/AlgorithmCodingTest

github.com

 

function solution(s) {
    var answer = [0, 0];

    while (s.length > 1) {
        answer[0]++;

        for (let i = 0; i < s.length; i++) {
            if (s[i] == '0') {
                answer[1]++;
            }
        }

        s = s.split("0").join("");

        let tempSArray = [];
        let tempsLength = s.length;

        let quotient = 0;
        let remain = 0;
        while (true) {
            quotient = Math.floor(tempsLength / 2);
            remain = tempsLength - quotient * 2;

            tempsLength = quotient;

            tempSArray.push(remain);

            if (quotient == 0) {
                break;
            }
        }

        s = tempSArray.reverse().join("");        
    }

    return answer;
}

 

문제 설명대로 구현하니 다행히도 쉽게 해결할 수 있었다.

 

📜 개인과제

 

개인과제를 진행했다.

 

https://dinorunner.com/ko/

 

크롬 다이노 게임 온라인

T-Rex Dinosaur (Dinosaur Google) - 인터넷이 없을 때 Chrome 브라우저에 숨겨진 게임의 복제본. 시작하려면 스페이스바를 누르십시오. 스페이스바 또는 위쪽 화살표와 아래쪽 화살표(↓)를 사용하여 공룡

dinorunner.com

 

 

앞서 언급한대로 크롬 다이노 게임에서 다른 움직임을 줬다.

우선은 좌, 우 화살표로 공룡을 직접 움직일 수 있도록 수정했다.

if (event.code === "ArrowLeft") {
    this.speed = -PLAYER_SPEED;
}

if (event.code === "ArrowRight") {
    this.speed = PLAYER_SPEED;
}

 

keydown 이벤트에서 왼쪽 화살표를 입력하면, -speed 값을 주고,

keydown 이벤트에서 오른쪽 화살표를 입력하면, speed 값을 줘서 공룡 캐릭터를 움직인다.

 

 

if (event.code === "KeyA") {
   if (this.fireAttackTimer <= 0 && this.fireCount > 0) {
        let game = Game.GetInstance();
        if (game != null) {
           this.fireCount--;
           game.jobQue.push(new Job(JOB_TYPE_CREATE_OBJECT_FIRE,
              OBJECT_TYPE_FIRE, this.x, this.y));

           this.fireAttackTimer = FIRE_ATTACK_TIMER;
        }
    }
}

 

A 키를 누르면 공룡 입에서 불꽃을 발사하도록 코드를 수정했다.

불꽃은 일정 개수를 가지고, R키를 눌러 재장전할 수 있다.

 

불꽃은 다가오는 선인장을 제거할 수 있다.

지금은 재장전할때, 바로바로 되는데 재장전시간을 둬서 선인장을 바로 없앨 수는 없도록 하긴 해야겠다.

 

https://github.com/YamSaeng/DinoRunner

 

GitHub - YamSaeng/DinoRunner

Contribute to YamSaeng/DinoRunner development by creating an account on GitHub.

github.com

 

랜카드( NIC, Network Interface Card, Network Interface Controller )

단말장치들이 인터넷과 같은 네트워크에 연결되기 위해서 필요한 장치.

여기서에서 랜( LAN, Local Area Network )이란 소규모의 네트워크를 의미하고,

랜카드는 이런 소규모의 네트워크를 연결해주는 장치라고 생각하면 된다.

 

보통은 메인보드에 내장되어 있기 때문에 별도의 슬롯에 NIC을 추가해 확장할 필요는 없다.

다만 네트워크 속도를 개선하기 위해 별도의 NIC을 탑재하는 경우가 있다.

 

네트워크의 전송 속도를 올린다는 의미는 단순히 데이터를 빨리 전송한다기보다

네트워크의 대역폭을 늘려 한번에 전송할 수 있는 데이터의 양을 늘리는 것이 정확한 표현이다.

 

MAC( Media Access Control )주소

네트워크에서 출발지와 목적지를 나타내는 주소는 총 2가지다. ( MAC 주소와 IP 주소 )

네트워크에서는 IP주소를 참조해 데이터를 목적지 단말장치로 전달한다.

 

전달할 때, IP 주소가 데이터를 보내고자 하는 컴퓨터의 주소가 맞는지를 확인해야 하는데,

이때 활용하는 것이 바로 MAC 주소다.

 

IP 주소는 단말의 위치에 따라 연결되는 네트워크가 달라질 수 있기 때문에 고정적이지 않지만,

MAC 주소는 랜카드의 고유 주소이기 때문에 메인보드 혹은 메인보드에 장착한 NIC을 교체하지 않는 이상

바뀌지 않는다. 따라서 MAC 주소가 네트워크의 출발지 또는 목적지인 단말장치를 구분하기 위한 주소가 된다.

 

MAC 주소 체계

숫자와 알파벳을 포함한 12개의 문자( 16진수 )로 구성되고 - 또는 : 으로 구분한다.

 

2C-60-0C-75-FF-09

00:0C:29:F0:F5:AF

 

거주지 주소를 시, 구, 동 단위로 세분화해 표기하듯,

16진수로 표현되는 MAC 주소도 체계적인 규칙을 가지고 있다.

 

위에 예시로 든 MAC주소를 분석해보자면 다음과 같다.

2C-60-0C 앞 3개는 제조사 식별코드( OUI )를 나타내고

75-FF-09 뒤 3개는 장비 코드( =시리얼번호 )를 나타낸다.

 

제조사 식별코드( OUI, Organizationally Unique Identifier )는 랜카드 제조사가 가지는 고유 번호를 말하고,

장비코드( =시리얼번호 )는 제조사가 각자의 방법으로 할당하는 번호다.

 

MAC 주소는 이론적으로 2^48개의 주소를 지정할 수 있다.

이 중에서 이미 고정되어 자유롭게 할당할 수 없는 MAC 주소가 하나 있는데, 바로 브로드캐스트 주소다.

 

네트워크에서 데이터를 주고 받을 때 반드시 데이터를 보내는 도착지의 MAC 주소가 필요하다.

하지만 MAC 주소를 굳이 알 필요가 없는 통신 방식이 있는데, 바로 브로드캐스드다.

브로드캐스트는 동일한 네트워크 내에 있는 모든 단말장치에 똑같은 데이터를 보내는 통신 방식이기 때문에

목적지를 지정할 필요가 없다. 그럼에도 데이터를 보내기 위해서는 도착지 MAC 주소가 필요는 하니까 

MAC 주소 체계로 표현할 수 있는 맨 마지막 값인 FF:FF:FF:FF:FF:FF을 브로드캐스트 주소로 지정한다.

'CS' 카테고리의 다른 글

[CS] 디자인 패턴  (0) 2024.11.11
[CS] IP 주소의 체계, 사설망, 공인망  (0) 2024.10.07
[CS] 웹서버와 게임서버  (0) 2024.08.25
[CS] 문자 집합과 인코딩  (0) 2024.08.19

오늘의 목표

더보기

✔️ 모의 면접

✔️ 개인 과제 


⏱️ 오늘의 일정

모의 면접개인 과제챌린지반 수업


📜 모의 면접

 

어제 언급한대로 오늘 모의 면접을 봤다.

총 3가지의 질문을 받았다.

 

1. IP의 개념과 주소체계, 서브넷에 관한 설명

2. 브라우저에 도메인을 입력하면 발생하는 일련의 과정 설명

3. 라우터, 라우팅과 라우팅 프로토콜 RIP, BGP의 대한 설명

 

면접 시간 전까지 암기를 하고 면접에 들어갔는데, 

그게 독이 된것 같다. 머리 속에 입력한 내용을 장황하게 설명하느라 튜터님이 강조한 '대화'를 하지 못했다.

피드백도 알고 있는 지식을 얘기한다기보다는 암기를 해서 설명하는 점이 강하고,

암기를 해서 설명하다보니 모든 지식을 끌어모아서 장황하게 설명하는 점이 좋지 않았다라고 피드백을 받았다.

 

면접은 '대화'라는 점을 강조 받았듯이 어떤 개념을 간단하게 설명을하고,

추가로 질문을 받으며 말 그대로 대화를 해 나가는 것이 중요하다라는 것을 깨달았다.

 

이번 모의 면접이 마지막은 아니고, 2번 정도 더 모의 면접 시간을 가질 것이라고 공지를 받았다.

다음 모의 면접에서는 위에서 받은 피드백 내용을 기억해두고 명심해서 임해야겠다.

 

 

📜 개인 과제

 

어제 제공 받은 스켈레톤 코드의 구조를 참고해서 다시 구성을 해야겠다.

 

https://github.com/YamSaeng/DinoRunner

 

GitHub - YamSaeng/DinoRunner

Contribute to YamSaeng/DinoRunner development by creating an account on GitHub.

github.com

 

📜 스탠다드반, 챌린지반 수업

 

스탠다드반에서 DNS 서버에 대해 배우고,

챌린지반에서는 데이터베이스 모델링에 관한 수업을 들었다.

오늘의 목표

더보기

✔️ 프로그래머스 코테 문제 풀이

✔️ 면접 특강

✔️ Node.js 게임서버 개발 강의 듣기


⏱️ 오늘의 일정

프로그래머스 코테 문제 풀이

면접 특강

Node.js 게임서버 개발 강의 듣기


📜 프로그래머스 코테 문제 풀이

 

피보나치 수

https://github.com/YamSaeng/AlgorithmCodingTest/tree/main/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/2/12945.%E2%80%85%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98%E2%80%85%EC%88%98

 

AlgorithmCodingTest/프로그래머스/2/12945. 피보나치 수 at main · YamSaeng/AlgorithmCodingTest

This is an auto push repository for Baekjoon Online Judge created with [BaekjoonHub](https://github.com/BaekjoonHub/BaekjoonHub). - YamSaeng/AlgorithmCodingTest

github.com

 

처음에 딱 보자마자 생각난 것이 재귀 함수라서, 바로 구현해봤다.

function Fibonacci(n) {
    if (n == 0) {
        return 0;
    }
    else if (n == 1) {
        return 1;
    }
    else {
        return (Fibonacci(n - 2) + Fibonacci(n - 1)) % 1234567;
    }
}

 

설렜던 기분과는 다르게.. 시간초과가 나는 바람에 다른 방법을 고민해봤다.

function solution(n) {      
    let answer = new Array(100001);
    
    answer[0] = 0;
    answer[1] = 1;

    for (let i = 2; i <= n; i++) {
        answer[i] = (answer[i - 2] + answer[i - 1]) % 1234567;
    }

    return answer[n];
}

 

미리 배열을 선언하고

[0] = 0

[1] = 1 

 

0과 1을 저장해두고 피보나치 공식에 맞게 배열을 채워나간후에, n번째 배열 값을 반환해준다.

 

 

📜 면접 특강

 

면접.. 면접에 대한 특강 시간을 가졌다. 

내일 16시에 모의 면접 시간이 30분간 잡혀있는데, 매우 많이 긴장된다.

면접에 나올 문제를 캠프에서 알려준게 있어서, 그 내용만큼은 암기하고 모의 면접 시간을 가져야겠다..

 

 

📜 Node.js 게임서버 개발 강의 듣기

 

Node.js 게임서버 개발 강의를 모두 수강했다.

이번 개인과제와 관련된 강의로

서버를 만들고, 클라를 만드는 강의다.

 

서버는 웹소켓을 이용해 만들고,클라는 

 

https://dinorunner.com/ko/

 

크롬 다이노 게임 온라인

T-Rex Dinosaur (Dinosaur Google) - 인터넷이 없을 때 Chrome 브라우저에 숨겨진 게임의 복제본. 시작하려면 스페이스바를 누르십시오. 스페이스바 또는 위쪽 화살표와 아래쪽 화살표(↓)를 사용하여 공룡

dinorunner.com

 

일명 크롬 다이노 게임이라고 불리는 게임코드를 제공받았다.

 

강의에서는 기본적인 틀을 제공해주고, 개인과제 조건에 맞게 서버와 클라를 다듬어 제출해야한다.

지금 드는 생각은 단조롭게 장애물을 점프해서 피하기보다는 좀 더 역동적인 움직임을 갖춰서 구현할 생각이다.

 

좀 더 자세한 내용은 내일 서버를 구현해보면서 생각해봐야겠다.

 

HTTP에 대해 알아야할 것

1. Request <-> Resonpse 구조 + 비연결성

  • 하나의 Request가 있으면 그에 대응하는 Response가 있다. 다시 말해,Request가 없으면 Response를 보내지 않는다.
  • 연결을 유지하지 않기 때문에 리소스를 줄일 수 있어서 많은 트래픽을 빠르게 처리가 가능하다.

 

2. Stateless ( 무상태 )

  • 연결을 한번 하고 끊기 때문에, 이전에 일어났던 일( 상태 )를 저장하고 있지 않는다.
  • 매번 새로운 요청을 처리한다. ( 세션, 쿠키, DB로 해당 요청에 대한 정보를 임의로 저장해 처리하긴 한다. )

3. HTTP 프로토콜의 메세지 구조

  • HTTP 프로토콜의 메세지 구조는 위 그림과 같다.
  • 이 중에서 중요하게 살펴볼 부분은 헤더( header ) 부분인데, 메세지에 필요한 모든 부가 정보가 들어있고, 그림처럼 넣고 싶은 내용을 임의로 추가 할 수도 있다.

 

General Header

  • Date : 현재 시간
  • Pragma : 캐시제어( no-cache ), HTTP/1.0에서 쓰던 것으로 HTTP/1.1에서는 Cache-Control이 쓰인다.
  • Cache-Control : 캐시 제어 + no-cache( 모든 캐시를 쓰기 전에 서버에 해당 캐시를 사용해도 되는지 확인 ) + public( 공유 캐시에 저장해도 됨 ) + max-age( 캐시의 유효시간을 명시 ) + private( '브라우저' 같은 특정 사용자 환경에만 저장 ) + must-revalidate( 만료된 캐시만 서버에 확인 ) + no-store( 캐시를 저장하지 않음 )
  • Transfer-Encoding : body 내용 자체 압축 방식 지정. 본문에 데이터 길이가 나와서 야금야금 브라우저가 해석해 화면에 뿌려줄 때 이 기능을 사용한다. ( 'chunked'면 본문의 내용이 동적으로 생성되어 길이를 모르기 때문에 나눠서 보낸다는 의미 )
  • Upgrade : 프로토콜 변경시 사용 
  • Via : 중계( 프록시 )서버의 이름, 버전, 호스트명
  • Content-Encoding : 본문의 리소스 압축 방식( transfer-encoding은 body 자체이므로 다르다 )
  • Content-type : 본문의 미디어 타입(MIME) 예) application/json, text/html
  • Content-Length : 본문의 길이
  • Content-Language : 본문을 이해하는데 가장 적절한 언어. 예) ko
  • Expires : 자원의 만료 일자
  • Allow : 사용이 가능한 HTTP 메소드 방식 예) GET, HEAD, POST ...
  • Last-Modified : 최근에 수정된 날짜
  • ETag : 캐시 업데이트 정보를 위한 임의의 식별 숫자
  • Connection : 클라이언트와 서버의 연결 방식 설정 HTTP/1.1은 kepp-alive로 연결을 유지하는게 디폴트

 

Request / Response Header

 ● request header form은 웹브라우저가 웹서버에 요청하는 것을 텍스트로 변환한 메세지들이다.

   ● Request Line : 어떤 웹서버로 접속( Host 부분 )해서, 어떠한 방식( HTTP / 1.1 )으로, 어떠한 메소드( GET )를 통해 무엇을( /doc/test/.html ) 요청했는지에 대한 메시지가 담겨있다. ( GET /test.html http 1.1 )

  ● Host : 요청하려는 서버 호스트 이름과 포트번호

  ● User-agent : 클라이언트 프로그램 정보 예) Mozilla / 4.0, Windows NT5.1 ( 이 정보를 통해 서버는 클라이언트 프로그램( 브라우저 )에 맞는 최적의 데이터를 보내줄 수 있다. )

  ● Referer : 바로 직전에 머물렀던 웹 링크 주소( 해당 요청을 할 수 있게된 페이지 )

  ● Accept : 클라이언트가 처리 가능한 미디어 타입 종류 나열 예) */* - 모든 타입 처리가능, application/json - json데이터 처리 가능

  ● Accept-charset : 클라이언트가 지원가능한 문자열 인코딩 방식

  ● Accept-language : 클라이언트가 지원가능한 언어 나열

  ● Accept-encoding : 클라이언트가 해석가능한 압축 방식 지정 예) gzip, deflate

  ● Content-location : 해당 개체의 실제 위치

  ● Content-disposition : 응답 메세지를 브라우저가 어떻게 처리할지 알려준다. 예) inline, attachment; filename='jeong-pro.xlsx'

  ● Content-Security-Policy : 다른 외부 파일을 불러오는 경우 차단할 리소스와 불러올 리소스 명시

      예) default-src 'self' -> 자기 도메인에서만 가져온다.

            default-src 'none' -> 외부파일은 가져올 수 없다.

            default-src https -> https로만 파일을 가져온다.

  ● If-Modified-Since : 여기에 쓰여진 시간 이후로 변경된 리소스를 취득. 페이지가 수정되었으면 최신 페이지로 교체하기 위해 사용된다.

  ● Authorization : 인증 토큰을 서버로 보낼 때 쓰이는 헤더

  ● Origin : 서버로 Post 요청을 보낼 때 요청이 어느 주소에서 시작되었는지 나타내는 값 ( 이 값으로 요청을 보낸 주소와 받는 주소가 다르면 CORS 에러가 난다. )

  ● Cookie : 쿠키 값 key-value로 표현된다. 예) attr1=value1; attr2=value2

 

● response header form은 웹브라우저가 요청한 메세지에 대해서 status 즉, 성공했는지 여부( 202, 400 등), 메세지, 그리고 요청한 응답 값들이 body에 담겨 있다.

  ● Location : 301, 302 상태코드일 때만 볼 수 있는 헤더로 서버의 응답이 다른 곳에 있다고 알려주면서 해당 위치( URL )를 지정한다.

  ● Server : 웹서버의 종류 예) nginx

  ● Age : max-age 시간내에서 얼마나 흘렀는지 초 단위로 알려주는 값

  ● Referrer-policy : 서버 referrer 정책을 알려주는 값 예) origin, no-referrer, unsafe-url

  ● WWW-Authenticate : 사용자 인증이 필요한 자원을 요구할 시, 서버가 제공하는 인증 방식

  ● Proxy-Authenticate : 요청한 서버가 프록시 서버인 경우 유저 인증을 위한 값

  ● 응답 상태 코드 ( 200, 202, 404 등 )

 

HTPP는 Application Layer 에서 동작하는 프로토콜이고, transport laye( 전송계층 )의 위에서 동작한다.

전송계층의 대표적인 프로토콜은 TCP / UDP가 있다.

HTTP는 TCP와 UDP 둘 중 하나의 연결을 통해서 동작한다. ( 결론적으로 TCP / UDP 프로토콜이 없으면 동작 불가 )

 

예외)

HTTP / 2 : 멀티플렉싱 기술의 등장으로 한번의 연결을 재사용하는 것이 가능하다.

HTTP / 3 : QUIC( UDP )위에서 동작한다.

 

TCP

HTTP는 비연결성이지만 TCP는 연결지향성이다.

  • TCP는 데이터교환을 할 때 무조건 연결을 가진다.
  • HTTP의 Req <-> Res가 발생할 때 밑에서 TCP 연결이 이루어진다.
  • TCP는 3-handshake라고 하는 연결 과정을 가진다.

 

TCP 통신방법

 양방향 통신( Full-Duplex ) 순서

  1. 서버는 접속 요청을 받기 위한 소켓을 연다. ( Listen )
  2. 클라이언트는 소켓을 만들고, 서버에 접속을 요청한다. ( Connect )
  3. 서버는 접속 요청을 받아서 클라이언트와 통신할 소켓을 따로 만든다. ( Accept )
  4. 소켓을 통해 서로 데이터를 주고 받는다. ( Send & Receive 반복 )
  5. 통신을 마치면 소켓을 닫는다. ( Close ( 상대방은 Receive로 인지할 수 있다. ) )

 

웹소켓( Websocket )

 

HTTP 프로토콜 위에서 동작하는 실시간 양방향 통신( Full-Duplex )

특징

 1. 실시간 통신

  • 웹소켓은 연결이 활성화된 상태에서 빠르고 지속적인 메세지 교환을 허용한다. 이로 인해 에플리케이션은 사용자에게 지연 없는 인터랙션을 제공할 수 있다.

 2. 양방향 통신( Full-Duplex )

  • 클라이언트와 서버가 동시에 서로에게 베세지를 보낼 수 있다. 이는 한 쪽이 다른 쪽의 메세지를 기다리지 않고도 독립적으로 메세지를 송수신 할 수 있음을 의미한다.

 3. 지속적 연결

  • 웹소켓 연결이 수립되면, 그 연결은 클라이언트나 서버가 명시적으로 종료할 때까지 유지된다. 이는 오버헤드를 줄이고 빠른 데이터 전송을 가능하게 한다.

 4. 낮은 오버헤드

  • 웹소켓은 데이터 패킷의 헤더가 매우 작기 때문에 오버헤드가 낮다. 이는 효율적인 네트워크 자원 사용을 가능하게 한다.

 5. HTTP와의 호환성

  • 웹소켓은 HTTP 포트( 80과 443 )을 통해 작동하기 때문에 기존 웹 인프라와 잘 통합된다. 웹소켓 연결은 HTTP 연결을 통해 초기화되며, 이후 전이중 통신 채널로 전환된다.

 

각 프토토콜의 헤더 비교

HTTP 헤더

GET /data HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/90.0.4430.212
Accept: application/json
Cookie: sessionToken=abcdef; userID=12345
  • 보통의 HTTP Request Header의 일부분 ( 여기에 더해 General Header까지 추가하면 대략 수백 바이트의 양을 가진다. )

 

웹소켓 헤더

  0x81 0x05
  • 연결 이후 데이터 교환할때의 websocket의 헤더
  • 극도로 간소화되어 있지만, FIN 비트, Opcode, Mask 비트, Payload 길이 정보가 포함되어 있다.

 

TCP 패킷 헤더 

  Source Port:       54321
  Destination Port:  80
  Sequence Number:   123456789
  Acknowledgment Number: 987654321
  Data Offset:       5 (Header Length: 20 bytes)
  Reserved:          0
  Flags:             [ACK, PSH]
  Window Size:       65535
  Checksum:          0x1a2b
  Urgent Pointer:    0
  Options:           [No options]
  Payload Data:      "Hello, TCP!"

 

TCP 패킷의 구조

TCP 패킷, 종종 세그먼트라고 불리는 것은 다음과 같은 주요 부분으로 구성된다.

  1. 소스 포트번호( 16비트 ) : 발신자의 포트 번호
  2. 목적지 포트번호( 16비트 ) : 수신자의 포트 번호
  3. 시퀀스 번호( 32비트 ) : 데이터 스트림 내에서 이 세그먼트의 위치를 식별하기 위한 번호
  4. 응답 번호( 32비트 ) : 다음에 기대하는 데이터의 시퀀스 번호
  5. 헤더 길이( 4비트 ) : 헤더의 크기를 나타냄
  6. 예약된( 3비트 ) : 향후 사용을 위해 예약된 공간
  7. 플래그( 9비트 ) : 연결 설정, 관리, 종료를 제어하는 다양한 플래그
  8. 윈도우 크기( 16비트 ) : 수신자가 받을 준비가 되어 있는 버퍼의 크기
  9. 체크섬( 16비트 ) : 오류 검사를 위한 값
  10. 긴급 데이터 포인터( 16비트 ) : 긴급 데이터의 끝을 가리키는 포인터
  11. 옵션( 가변 길이 ) : 필요에 따라 추가적인 옵션을 포함할 수 있음
  12. 데이터( 가변 길이 ) : 실제 전송할 데이터

 

웹소켓의 연결방법은 TCP의 연결방법 ( 3-way-handshake)를 닮아있다.

웹소켓은 기본적으로 TCP 연결 위에서 작동하기 때문에, 웹소켓 연결을 시작하기 전에 TCP의 표준 연결 방법인 3-way handshake가 수행된다. 하지만 웹소켓은 이후에 추가적인 핸드셰이크 과정을 진행해 웹소켓 특유의 연결을 완성한다.

 

 

테스팅 프레임워크 Jest에 대해 알아보기

Node.js를 통해 사용하고 있는 언어인 JavaScript에서 사용이 가능한 테스팅 프레임워크의 종류는 매우 다양하다.

이 중 Jest를 사용해보자.

 

Jest는 다른 테스팅 프레임워크와 비교하면 여러가지 장점이 있지만, 그 중 가장 제일이라고 생각되는 것은 테스트 코드의 표현이 다른 프레임워크보다 훨씬 간결하다.

 

jest 모듈 설치

# yarn 프로젝트를 초기화합니다.
yarn init -y

# DevDependencies로 jest를 설치합니다.
yarn add -D jest

 

 

테스트 코드

작성한 코드에 문제가 없는지 테스트하기 위해 작성한 코드다.

흔히 테스트 기본 원칙이라고 불리는 "일곱 테스트 원칙"에서는 첫번째 규칙이 아래와 같다.

 

Testing shows the presence of defects, not their absence

테스팅은 결함이 없는것이 아니라, 결함의 존재를 보여주는것이다.

 

이 원칙을 알아두고 테스트 코드를 작성하는 것이 가장 중요하다. 

왜냐하면 테스트 코드의 목적은 내 코드의 증명이 아니라, "내 코드가 멀쩡하다면 이렇게 결과가 나와야한다"라는 기대치를 설정하고 검증하기 위한 것이기 때문.

하나의 기능을 여러번 수정하다 보면 예상치 못한 결과가 나오기 마련인데, 테스트 코드를 이용해 코드를 믿고 사용할 수 있도록 해보자.

 

테스트 코드의 종류에 대해 알아보기

테스트 코드란, 어떠한 언어에 얽매이지 않고 개념적으로 표현하기도 한다.

많은 개발자들이 오랜 기간동안 테스트 코드를 작성하며 아래와 같은 테스트 코드의 종류를 정립했으며, 이 중 가장 작은 기능을 테스트하는 "단위 테스트" 코드를 실제로 작성해볼 예정

  • 단위 테스트( Unit Test ) : 가장 작은 규모의 기능을 테스트한다.
  • 통합 테스트( Integration Test ) : 다양한 기능을 합쳤을때 생기는 문제를 방지하기 위한 테스트다.
  • E2E 테스트( End-to-end Test ) : 끝에서 끝( 종단 간 )을 의미하는 End to end 테스트다. 쉽게 말하면 백엔드부터 시작해서 최종적으로 웹 페이지가 원하는대로 동작하며 원하는 데이터를 잘 보여주는지 확인한다.

 

+ Recent posts