/web12-algo-with-me

🏆누구나 만들고 참여할 수 있는 알고리즘 대회 서비스

Primary LanguageTypeScript

Hits



🏆web12-algo-with-me

Algo With Me는 모두가 참여하고 만들 수 있는 알고리즘 대회 서비스입니다.

주요 기능은 다음과 같습니다.

  • 사용자가 제출한 코드를 채점할 수 있습니다
  • 실시간으로 대회에 참여한 경쟁자들의 순위를 확인할 수 있습니다

알고윗미 체험하기

프로젝트 문서 바로가기



📄목차



🎬데모 영상

_.mp4

유튜브 바로가기



🚀Algo With Me 기능 설명

코드 채점하기

right-wrong

대회 페이지는

  • 문제 화면
  • 코드를 작성할 수 있는 에디터
  • 제출 결과 화면

으로 구성됩니다.
나만의 테스트 케이스를 추가하고 "테스트 실행"버튼을 눌러 실행할 수 있습니다.
"제출하기" 버튼을 누르면 히든 테스트 케이스들의 정답 여부와 시간, 메모리 사용량을 받아볼 수 있습니다.

대시 보드 확인

dashboard

대회 참여자 순위 100위까지와, 나의 순위를 대회 진행 중 실시간으로 확인할 수 있습니다.
대회 참여자가 아니라도 대시보드를 확인할 수 있습니다.

그 외

메인 페이지

메인 페이지

algo-with-me 메인페이지입니다. 현재까지의 모든 대회를 확인할 수 있습니다.

대회 생성

대회 생성

대회 생성 페이지 입니다. 최대 참여인원 설정이 가능하고 대회 시간을 지정할 수 있습니다. 등록된 문제를 선택해 대회에 포함시킬 수 있습니다.

대회 상세 페이지

대회 상세 페이지

대회 상세 페이지에서는 대회의 시작, 종료 시간, 참가자 등의 정보를 얻을 수 있습니다. 대회 시작 시간이 되면 대회 입장 버튼과 대시보드 보기 버튼이 활성화됩니다.

테스트 케이스 추가

테스트 케이스 추가

제출하기 전 테스트 케이스를 추가하고 내 코드를 실행해볼 수 있습니다.



🥚문제 해결 과정: 배경

저희 팀에게 주어진 자원은 2코어, 8GB RAM 네이버 클라우드 인스턴스 하나였습니다.
하지만 부스트캠프 전원(200명)이 참여할 수 있는 서비스를 만들고 싶었습니다.

그래서 가진 자원을 어떻게 해야 최대한으로 활용할 수 있을까 라는 도전과제를 목표로 설정하게 되었습니다.


🐣문제 해결 과정: 시도한 것들

BE) 아키텍처 설계 최적화

어떻게 많은 채점 요청이 들어오더라도 누락 없이 모두 채점할 수 있을까?
어떤 기술을 사용해야 우리 문제를 해결하는 데에 유리할까?

👉 BE 아키텍처 설계 및 DB ERD 설계
👉 기술 스택 선정

BE) 채점 로직

병렬적으로 채점하려면 어떻게 구조를 짜야 할까?
보안 위협 없이 안전하게 채점할 수 있을까?

👉 채점서버, 도커서버 실행흐름
👉 BE 채점서버 아키텍처 관련 회의

BE) 대시보드

폴링, 웹 소켓, SSE 무엇을 사용해야 할까?
DB, 메모리 자원을 어떻게 효율적으로 활용할 수 있을까?
어떻게 해야 서버 부담을 줄이면서도 실시간으로 데이터를 전달할 수 있을까?

👉 대시보드 데이터 redis 저장 방식, 클라이언트에게 보낼 양식, db 저장 방식
👉 대시보드 소켓 재사용 관련 회의

FE) 클라이언트에서 JS 코드를 테스트할 수 있을까?

어떻게 해야 서버로 가는 요청을 줄여서 리소스를 아낄 수 있을까?
채점은 몰라도 테스트 정도는 클라이언트에서 돌려도 되지 않을까?
Eval을 사용하면 될 것 같긴 한데, Eval을 써도 될까?

👉 eval을 사용해선 안 되는 이유와 대안들

FE) Eval은 안전할까? 어떻게 해야 안전해질까

Eval을 사용하면 무한 루프를 만났을 때 메인 스레드가 멈추는 문제가 생긴다.
웹 워커를 이용해서 스레드를 분리해 보자

👉 웹 워커란 무엇인가? & 알고윗미에서의 활용 방안

Eval은 언제 위험할까?
Eval은 사이드 이펙트가 발생할 때 위험해
사이드 이펙트가 일어날 수 없는 순수한 JS 엔진을 올려서 사용해 보자

👉 웹 어셈블리란 무엇인가? & 알고윗미에서의 활용 방안

FE) QuickJS는 엄밀한가?

QuickJS라는 JS 엔진을 사용하면 될 것 같아.
하지만 이게 정말 모든 브라우저에서 공평하게 동작할까?

👉 [검증] QuickJS는 모든 브라우저에서 동일한 성능을 보장할 수 있는가?
👉 [검증] QuickJS는 모든 브라우저에서 동일한 Max Call Stack을 보장할 수 있는가?

FE) 공정한 환경을 구성하기 위해선 서버와 클라이언트의 시간을 동기화해야 한다

참여자들은 시험이 정확하게 같은 시간에 시작하고 같은 시간에 끝나기를 기대한다.
이를 위해서 서버와 클라이언트의 시간을 동기화해야 하는데, 어떻게 할 수 있을까?
서버 자원이 무한하다면 1초마다 Http 요청을 보내면 되지만, 서버 자원은 한정되어 있다.
클라이언트의 Date 객체만으로는 서버와 시간 동기화할 수 없을까?

👉 Date 내장 객체는 믿을만한가?

브라우저의 Date 내장 객체로는 엄밀한 시간 동기화가 불가능해
5초 간격으로 시간을 갱신해주는 정도로 요청을 최소화해볼 수 있을까?
setInterval은 얼마나 믿을 수 있을까?

👉 setInterval은 메인스레드가 바빠도 정확하게 동작할까?


🐓문제 해결 과정: 트러블 슈팅

BE) 대시보드 데이터 관리를 위한 Redis 설치 과정에서 겪은 트러블슈팅

대시보드 데이터 관리를 위해 Redis를 설치하려고 했다.
NestJS에서 제공하는 cache-module을 사용했는데, Redis에 특화된 자료구조를(e.g. SortedSet) 제어하는 명령어를 사용할 수 없었다.
redis-client를 설치하여 문제를 해결했다.

👉 대시보드 데이터 관리를 위한 Redis 설치 과정에서 겪은 트러블슈팅

BE) 트랜잭션과 락 관련 트러블슈팅

일부 채점 결과가 누락되는 문제가 발생했다.
채점이 병렬적으로 진행되어 API 서버에 요청이 거의 동시에 들어왔고, 경쟁 조건이 발생했기 때문이었다.
트랜잭션을 걸었지만, 문제는 해결되지 않았고, 락을 건 이후에야 제대로 동작했다.

👉 도커 서버 개수 5개로 늘린 이후 일부 채점 결과가 누락되는 문제

BE) 도커 권한 관련 트러블슈팅

기존에는 root 사용자로 모든 서버를 운영하고 있었다.
보안상의 이유로 코드 실행 서버의 유저 권한을 root에서 일반사용자로 바꾸었는데, 권한이 줄어들어 파일 읽기 쓰기가 되지 않는 문제가 발생했다.
도커 유저 설정을 통해 API 서버와 채점 서버의 권한을 일반 사용자로 바꾸어 문제를 해결했다.

👉 채점서버 도커 권한으로 인한 읽기/쓰기 불가 문제

FE) useEffect, 생명주기를 알고 쓰자

socket으로 데이터를 받아 대시보드를 모달로 보여줘야지
모달을 닫고 다시 열면 데이터가 정상적으로 수신되지 않아
페이지에서는 정상 작동하는데, 모달에서는 왜 작동하지 않을까?

👉 [트러블 슈팅] useEffect, 생명주기를 알고 쓰자

FE) 싱글톤 패턴을 이용한 웹소켓 다중 연결 상태 해결

통신 오버헤드를 줄이기 위해 웹 소켓을 사용하기로 결정했다.
개발자 도구로 웹 소켓 연결을 확인하니 10개의 웹 소켓이 연결되는 것을 확인했다.
무엇이 문제고, 어떻게 해결해 나가야할까?

👉 [트러블 슈팅] 싱글톤 패턴을 이용한 웹소켓 다중 연결 상태 해결

FE) 배포하고 새로고침하면 404페이지가 떠요

Netlify에 웹페이지는 배포를 마쳤다.
하지만 메인 페이지를 제외한 다른 페이지에서 새로고침을 하면 404 페이지가 나오는 문제를 겪게 된다.
개발 환경과 배포 환경은 무엇이 달라 이런 문제가 생겼을까? 어떻게 해결할 수 있을까?

👉 [트러블 슈팅] 배포하고 새로고침하면 404페이지가 떠요


🍗문제 해결 과정: 결과

BE) 부하 테스트 결과

JMeter로 부하테스트를 수행하여 부스트캠프 전 인원이 우리 서비스를 이용할 수 있을지 알아보았다.
200명이 동시에 WebSocket을 통해 대시보드 데이터를 원활하게 받을 수 있음을 확인하였다.
그리고, 100명이 0~10초 균등확률분포로 코드 제출 요청을 보냈을 때, 채점을 원활하게 할 수 있음을 확인했다.

👉 부하 테스트 수행 및 결과 정리



👨‍👨‍👧‍👧미니 개발 세미나

미니 개발 세미나 5회

미니 개발 세미나란?

미니 개발 세미나는 Web12 코드 사피엔스팀 내부에서 공유 문화를 만들기 위해 시작된 소규모 세미나입니다. 5 ~ 10분 동안 자유주제 혹은 프로젝트를 진행하면서 공유하고 싶은 내용을 발표하는 방식으로 진행됩니다. 발표자는 팀원들로 구성되지만, 다른 캠퍼들도 자유롭게 듣고 질문할 수 있도록 외부적으로 공개하였습니다. 2023/11/08 첫 세미나를 시작으로 5회 진행되었으며, 부스트캠프가 끝나고도 이어갈 예정입니다.

👉 전체 보기

Best Pick

썸네일 한 줄 소개 링크
그대들 어떻게 개발할 것인가? 제가 개발자의 길을 걷게 되면서 스스로 가지고 있던 개발자의 정의가 어떻게 바뀌었는지 회고하고 질문을 던집니다 그대들 어떻게 개발할 것인가?
WebSocket을 선택한 이유 양방향 통신들의 기법에 대해서 간략히 알아보고, 왜 우리가 webSocket을 선택했는지 공유합니다. WebSocket을 선택한 이유
클린 코드, 주석 클린 코드를 왜 지향해야 하는지, 클린 코드와 주석의 상관관계는 무엇인지에 대해 설명합니다. 클린 코드, 주석
Why MSA? MicroService Architecture가 무엇인지, 어떤 장점이 있는지, 언제 사용해야 하는지 살펴봅니다. Why MSA?
대시보드 어떻게 구현하지 대시보드 실시간 갱신을 위해 WebSocket과 Redis를 도입하여 사용하게 된 과정을 소개합니다. 대시보드 어떻게 구현하지



👷아키텍처

캡처 아키텍처



🛠기술스택

Language

TypeScript JavaScript

BE Skill

NestJS Socket.io Postgres Redis Docker Express.js NodeJS Nginx TypeORM

FE Skill

React Socket.io PandaCSS

Etc

Netlify Notion Slack Figma GitHub Actions



🗺디자인 및 기획



🎸기타 등등



🙉팀원 소개

FE FE FE BE BE

J079 양기조
(dev2820)

J111 이우찬
(dmdmdkdkr)

J140 정유석
(mahwin)

J026 김용후
(rladydgn)

J109 이예찬
(yechan2468)