본문 바로가기

기록지/산업기능요원

[산업기능요원] 크나큰 실수 기념 광기의 회고록 #3 👏🏻

반응형

1. 서론

  내가 만든 개임의 수가 한 손을 넘어간다. 짜잘한 실수가 많았지만 이번에는 꽤나 큰 실수를 했다. 얼마나 큰 실수인지를 굳이 말하자면... 매출에 부정적인 영향을 미칠법한 실수를 하였다.

 

 신나게 놀다가 방금 알고리즘 한 문제를 풀고 회고록 계획이 생각나 이제서야 기억을 되살려 적기 시작한다. 문법적인 오류가 아닌 그냥 내가 깊이 있게 생각하지 못한 실수였다. 오죽했으면 코드리뷰때도 안 잡혔을까... ㅠㅠ

 

 신입이 실수하는건 그 사람만의 잘못이 아니라는 말을 들었지만 일단 내 잘못도 있다는 뜻으로 새겨들었다. 사실 이렇게 신입의 입장에서 큰 책임이 주어지는 업무를 한다는 것 자체가 정말 좋은 기회라고 생각된다. 다음부터는 이런일이 다시 일어나지 않기 위해 더 꼼꼼히 일해야겠다는 사실을 다짐하며 회고록을 작성한다.

2. 본론

 내가 이번에 한 실수는 총 두가지가 있다. 회사의 코드를 보여줄순 없기에 추상적으로 정리하겠다.

 

- 무한 보상 지급

 

 내가 제작하고 있는 게임에서는 "특정 조건"을 만족하는 유저에게 "보상"을 무조건 한번만 지급한다. (매우 매우 추상적인 표현입니다.) 이 부분에서 내가 작성한 코드는 다음과 같은 구조를 가지고 있다.

 

//보상을 주어야 하는 유저인지를 판단한다.
let isUserInCondition = this.getUserConditionResult();

for(let i = 0; i < this.MAX_SIMULATION_COUNT; i++){
    
    // ...프로세스 진행...

    //보상을 주어야하는 유저라면
    if(isUserInCondition){
        //보상을 수령 여부에 대한 상태값을 변경한다.
        this.userInfo.isRewardGiven = true;
    }

    // ...남은 프로세스 진행...
}

//만약 보상을 받은 유저라면
if(this.userInfo.isRewardGiven){
    //영구적으로 보상을 받지 못하도록 상태값을 변경한다.
    this.changeUserCondition();
}

 

 자 어떻게 보면 아주 간단한 코드인데 무슨 말같지도 않은 실수를 했는지를 기록하기 위해 나의 실수 코드를 가지고와보겠다.

 

//보상을 주어야 하는 유저인지를 판단한다.
let isUserInCondition = this.getUserConditionResult();

for(let i = 0; i < this.MAX_SIMULATION_COUNT; i++){
    
    // ...프로세스 진행...

    //보상을 주어야하는 유저라면
    if(isUserInCondition){
        //보상을 수령 여부에 대한 상태값을 변경한다.
        this.userInfo.isRewardGiven = true;
    }

    // ...남은 프로세스 진행...
}

//만약 보상을 받은 유저라면
if(this.userInfo.isRewardGived){
    //영구적으로 보상을 받지 못하도록 상태값을 변경한다.
    this.changeUserCondition();
}

 

 ㄹㅇㅋㅋ... 잘 안 보이는 분들을 위해 알려드리자면 오타 때문에 발생한 버그이다. 보상 수령 여부는 userInfo객체의 isRewardGiven이라는 변수에 저장해놓고 수령 여부에 대한 상태를 변경할 때는 isRewardGived라는 변수를 참조했다... ㅋㅋㅋ....

 

 아 JS는 정말 너무 편해서 문제라는 말을 뼈로 느꼈다. 애초에 isRewardGived라는 변수는 애초에 userInfo 객체 안에 만들어주지도 않았는데 코드는 잘 돌아가니 이런 숨겨진(?) 버그는 찾지 못했던 것이다. 코드 리뷰때도 전체적인 구조를 보지 변수명까지 보진 않으니...

 

 그래서 해당 버그를 예방할 수 있는 방법은 따로 정리하였다. 링크는 아래에 첨부해두었다.


https://apape1225.tistory.com/170

 

[Javascript] 객체에 정의되지 않은 요소의 참조를 예방하는 방법

1. 서론 회사에 큰 손해를 끼치며 배운 JS문법을 정리하고 같은 실수를 반복하지 않기 위해 과정을 정리하고자 한다. 사견이지만 JS는 자유도가 너무 높은 객체인 것 같다. 코테는 C++, 서버는 JAVA

apape1225.tistory.com


- 계산 중복

 

 이건 진짜 위의 버그보다 더 답이 없는 실수이다. 나는 아래의 조건을 구현해야했다.


유저가 하루에 사용한 금액에 비례하는 보상 계산

유저가 한달 동안 사용한 금액에 비례하는 보상 계산


 자 이제 내가 이걸 어떻게 구현했는지를 보자. 보고 놀리고 욕하셔도 된다. 이건 진짜 욕 먹어야하는 실수이다.

 

// 보상 집계 코드
let usedAmount = this.getUsedAmount();

this.userInfo.totalDayAmount += usedAmount;
this.userInfo.totalDayCount++;
this.userInfo.totalMonthAmount += this.userInfo.totalDayAmount;
this.userInfo.totalMonthCount++;

 

// 보상 지급 코드
let dayRewardAmount = this.userInfo.totalDayAmount / this.userInfo.totalDayCount;
let monthRewardAmount = this.userInfo.totalMonthAmount / this.userInfo.totalMonthCount;

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

this.userInfo.totalMonthAmount += this.userInfo.totalDayAmount;

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

 진짜 답도 안나오는 버그다... 대체 뭔 생각으로... 정신나간 코드 덕에 나는 유저에게 보상을 복리로 주려하는 착한 서버 개발자라는 별명이 생길 것 같다.

 

 형식상 핫 픽스된 코드를 작성하자면 다음과 같다.

 

// 보상 집계 코드
let usedAmount = this.getUsedAmount();

this.userInfo.totalDayAmount += usedAmount;
this.userInfo.totalDayCount++;
this.userInfo.totalMonthAmount += usedAmount;
this.userInfo.totalMonthCount++;

 

3. 결어

 시간이 지나고 팀원분들이 정말 훌륭하신 분들이기에 지금 이렇게 웃으면서 회고록을 작성하지만 버그가 발생했을 당시에는 정말 온갖생각이 다들었다. 팀장님께서는 "다음에 안 일어나면 되죠. 너무 마음에 담아두지 마세요. 기록하고 집중합시다. 쉬운일은 아니니까요." 라고 말씀해주셨다. 그래서 개인 노션과 블로그에 기록하는 중이다.

 

 추후 위의 버그의 재발 방지를 작성해서 올릴 계획이다. 이런 것이 경험이라지만 꽤나 아픈 경험이 된 것 같다. 그래도 가장 중요한 것은 미래이니 조금 더 집중하는 회사생활을 해야겠다.

 

 사진은 버그터져서 야근한 다음날 놀러가서 찍은 바다!

 

반응형