[TIL #35] 데드락에 죽다 살다
·
Camp/T.I.L.
현재 진행 중인 프로젝트는 레이드 컨텐츠 입장을 위해 큐를 사용한다.최초로 개발하며 개념 검증 시엔 원시적인 큐만 사용했고, 이는 동시성 문제어 이어질 수 있었다.따라서 Bull을 도입하게 됐다.  하지만 Bull만 도입한다고 되는 것은 아니었다.Bull 자체의 ``Job``에 대해선 원자적 처리를 보장하지만 그 이외의 부분에 대해선 원자적 처리가 보장되지 않는 상황이다.각각의 필요한 모든 부분에 대해 명시적으로 락을 걸어 완전한 원자적 처리를 보장해야 했다.이러한 처리를 위해 async-lock을 도입했다. // pendingGroups 접근을 안전하게 하기 위한 헬퍼 메서드async withPendingGroupsLock(fn) { return this.pendingGroupsLock.acquire..
[TIL #34] Docker 및 Docker Compose 올려보기
·
Camp/T.I.L.
도커를 올려보기로 했다.이미 라즈베리 파이 서버에 인프라가 다 준비돼 있지만,내가 만져보면서 이해해보고 싶었던 것이기도 했고, 아마존 ECS에 올려보기 위함이기도 하다. 일단 현재 서버는 다음과 같은 상태다.Node.js 서버MySQLRedisGrafana그럼 각각의 것들을 다 컨테이너로 만들어 ``Compose``로 묶어서 빌드 후 배포할 수 있어야 하겠다. 먼저 노드 서버를 위한 ``Dockerfile``을 다음과 같이 만들었다.# Node.js 베이스 이미지 사용FROM node:20-alpine# 작업 디렉토리 설정WORKDIR "작업 디렉토리"# 패키지 파일 복사 및 의존성 설치COPY package*.json ./RUN npm install# 소스 코드 복사COPY . .# 포트 노출EXPOS..
[TIL #33] 마법의 엘리베이터
·
Camp/T.I.L.
https://school.programmers.co.kr/learn/courses/30/lessons/148653 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.programmers.co.kr 모듈러 뺑뺑이 돌리는 문제.접근법은 명확한데, 특정 테스트 케이스를 통과하지 못해서 평소보다 많은 시간을 투자했다. 먼저 첫 접근부터.// 음수층은 없음// 하지만 음수층이 있는 것 처럼 생각 가능// 모듈러 지옥function solution(storey) { let total = 0; let carry = 0; while (storey > 0) { let digit ..
[TIL #32] 자바스크립트와 싱글톤
·
Camp/T.I.L.
싱글톤싱글톤에 대해 아시는가.전역에서 단 한 번만 초기화되어 항상 같은 인스턴스를 공유하는 것을 두고 흔히 싱글톤이라 한다. 그럼 두 번 초기화되는 일은 없어야 할 것이다.하지만 그게 발생할 수도 있다.노드의 모듈 임포트 구조는 왜 이래야만 했는가... 하는 의문도 있다.  싱글톤이지만 싱글톤이 아니다import DungeonState from './dungeonState.js';import EnemyAttackState from './enemyAttackState.js';import MonsterDeadState from './monsterDeadState.js';이러한 임포트가 있다고 하자.임포트 하는 ``.js`` 파일의 이름은 실제로 카멜 케이스를 따르고 있다. 그런데 이래도 임포트는 된다.imp..
[TIL #31] 상태 업데이트의 벽
·
Camp/T.I.L.
서버가 존재하는 온라인 멀티플레이어 게임은 모두 상태 업데이트에 큰 노력을 쏟을 것이다.플레이어 A와 B가 같은 곳에 있다면, 둘은 서로 같은 상태로 동기화되어야 한다.A는 움직였지만 B의 화면에서 A가 움직이지 않았다면 대형 사고다. 지금의 과제에서 가장 어려운 부분 또한 그런 내용이다.명확한 상태 동기화를 위해 고민해야 할 부분이 많다.어떤 주기로 동기화할 것인지, 어떻게 동기화할 것인지와 같은 내용이 되겠다.  1. Interval Manager 활용서버 내에서 벌어지는 주기적인 활동을 ``Interval Manager``를 통해 관리할 수 있다.하지만 강의에서 이를 최대한 활용하지 않는다는 느낌이 들었다.이걸 어떻게든 활용해 보려고 했다. const updateLocationHandler = ({..
[TIL #30] 모의 면접을 준비하며
·
Camp/T.I.L.
모의 면접에서 메인 토픽뿐만 아니라, 그 연계질문까지 공개하는 건 이례적이라는 생각이 든다.애초에 미리 고지한다고 그 꼬리로 가는 것이 가능한 건지 의문스럽기도 하다.대답에 따라 꼬리 무는 것도 달라지지 않나.그 의도는 모르겠으나, 일단 준비된 질문들에 대해 생각해 보자.  전송 계층 프로토콜에 대한 설명- 꼬리1 : IP의 한계- 꼬리2 : 오류 제어, 흐름 제어대칭키, 비대칭키 암호화에 대한 설명- 꼬리1 : 혼합 암호 사용- 꼬리2 : HTTPS로드 밸런싱에 대한 설명- 꼬리1 : 로드밸런싱 알고리즘- 꼬리2 : 헬스 체크  전송 계층 프로토콜전송 계층은 4번째 계층으로 종단 간 통신을 담당한다.신뢰성 있는 통신을 위한 여러 기능(흐름 / 혼잡제어 및 오류 검출 및 수정)을 수행한다. 프로토콜엔 T..
[TIL #29] 점 찍기
·
Camp/T.I.L.
https://school.programmers.co.kr/learn/courses/30/lessons/140107 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.programmers.co.kr 변의 길이가 ``d``인 정사각형에 ``k``의 간격으로 점을 찍는 문제. 최초 접근은 피타고라스 정리를 매 사이클마다 계산하지 않고 $\sqrt{2} ≒ 1.414...$를 활용하려고 했다.이러면 숫자가 커질수록 발생하는 오차를 말끔히 해결할 수 없다는 걸 깨닫고 선회. 다음 방법은 이것.function solution(k, d) { let count = 0; const dSquared..
[TIL #28] Investments in 2016
·
Camp/T.I.L.
https://leetcode.com/problems/investments-in-2016/description/ 질문이 바로 이해가 가지 않아, 질문 이해에 약간의 시간이 더 투자된 문제. 같은 ``tiv_2015``의 값을 공유하는 레코드가 2개 이상 존재하는 레코드위도와 경도가 같지 않은(같은 위치가 아니고 고유한) 레코드이 레코드들을 찾아서 각각의 ``tiv_2016``값을 더해서 소수점 2자리까지 반올림진짜 이런 요구 사항이 실제로 존재할진 모르겠지만... 문제도 잘 다가오지 않고, 힌트도 이런 상황이다.당연한 걸 힌트랍시고 준 걸 보면, 너무 간단한 문제라고 생각했나 보다. 처음엔 문제를 제대로 이해하지 못해 "윈도우 함수로 밀면서 같고 다른 걸 체크해야 하나?" 같은,이상한 의문에 빠져있었다...
[TIL #27] 호텔 대실
·
Camp/T.I.L.
https://school.programmers.co.kr/learn/courses/30/lessons/155651 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.programmers.co.kr 왠지 이전에 했던 주차장 관리가 생각나던 문제.이 문제의 난도가 더 낮았던 것 같다. 시간들을 다 분으로 변환하고시작 시간 기준으로 정렬시간을 비교하며 최대 방 개수 관리이거면 끝나는 문제.  // 분단위 관리, 종료시간에 청소시간 추가let events = [];for (const [start, end] of book_time) { // 숫자만 남김 const [startHour, st..
[TIL #26] 함수 오버로딩의 함정
·
Camp/T.I.L.
정처기 실기 문제엔 다음과 같은 유형의 프로그래밍 문제가 나온다. // 다음 프로그램의 실행 순서가 어떻게 되는지 맞춰라!// 5 -> ...class Parent { int x, y; Parent(int x, int y) { // 1 this.x = x; this.y = y; } int getT() { // 2 return x * y; }}class Child extends Parent { int x; Child(int x) { // 3 super(x + 1, x); this.x = x; } int getT(int n) { // 4 return super.getT() + n; ..