목록전체 글 (389)
만족
분석 조건 30일간 진행된 공식전 게임 중 랭킹 1000위 안의 유저들의 게임 기록을 기준으로 약 20000회의 경기 결과를 대상으로 분석합니다 분석 방법 사이퍼즈 OPEN API를 이용해 수집된 데이터를 js로 분석합니다. 카운터 픽 분석 방법 (파란색은 승리팀, 붉은색은 패배팀입니다) 해당 경기에서 각각의 캐릭터마다 한 번씩 비교하여 총 25번의 비교를 하여 다음과 같은 데이터를 만들어냅니다 (클레어vs까미유=> 승리1vs승리0, 클레어vs디아나=> 승리1vs승리0 ...... 스텔라vs호타루=> 승리1vs승리0) 이와 같은 작업을 20000여개의 경기에 대해 누적식으로 모두 진행한 다음, 해당 데이터를 가공하여 DB에 넣습니다. 이 데이터는 한번 더 백엔드에서 처리하여 프론트에 전달되는데, 최종적으..
매우 큰 javascript array를 파일로 저장하던 중 out-of-heap 오류가 뜨면서 프로그램이 정지되어서 힙 메모리에 충분한 값을 주고 실행했더니 이번엔 RangeError: Invalid string length 오류가 뜬다. 원인은, js엔진에서 객체 사이즈에 제한을 두고 있다고 한다. array를 JSON.stringify()하는 과정에서 생겨난 string 크기가 해당 사이즈를 넘어버린 것이다. 해결법은 해당 객체를 작은 사이즈로 나누거나 스트림을 이용해 잘게 쪼개어 파싱하면 된다. 참고: https://ohgyun.com/782 Node: String 크기 제한에 의한 RangeError 발생일: 2018.10.22 키워드: JSON.stringify, RangeError, Inva..
Nodejs로 크롤러를 만들던 중, 수집한 정보를 file로 저장하던 중에 해당 오류가 발생했다. 원인은 Nodejs의 기본 힙 메모리는 512MB라서 프로그램이 돌다가도 해당 사이즈를 넘어버리면 해당 오류가 출력되면서 프로그램이 강제 종료된다. 해결법은 간단히 실행 시 옵션에 --max-old-space-size=[SIZE] 를 주면 된다. 가령 내 프로그램을 돌리는데 1GB가 필요하다면 커맨드라인에 다음과 같이 입력하면 된다 node --max-old-space-size=1024 index.js
https://ko.reactjs.org/docs/react-api.html#reactmemo React 최상위 API – React A JavaScript library for building user interfaces ko.reactjs.org 요즘 클래스형 컴포넌트를 갖다 버리고, 거의 함수 컴포넌트만 사용중이다. 클래스형 컴포넌트에서는 shouldComponentUpdate 메서드를 사용하여 해당 컴포넌트를 업데이트할지 말지 결정할 수 있었으나, 함수 컴포넌트에서는 할 줄 몰라서 그냥 내버려뒀다. (사실 페이지 내에 요소가 그렇게 많지가 않아서 크게 신경쓰지 않아도 문제는 없었다) 그러나, 엘리먼트가 매우 많은 페이지를 만들면서 해당 문제를 해결하는 방법에 대해 알아보았다. 탭바 컴포넌트 구조를..
참고: https://expressjs.com/en/4x/api.html#res Express 4.x - API Reference Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex expressjs.com 자주 쓸 것 같은 프로퍼티에 대해 정리한다 Res.headersSent response heade..
참고: https://expressjs.com/en/4x/api.html#req Express 4.x - API Reference Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex expressjs.com 자주 쓸 것 같은 프로퍼티를 정리한다 req.ip request client ip req.meth..
예제로 알아보기 npx express-generator 커맨드로 프로젝트를 생성했다면, App.js에서 해당 코드블럭을 찾을 수 있다 app.use는 핸들러 등록에 사용되며, 등록한 핸들러의 순서대로 request가 처리된다. 다음 핸들러로의 진행은 현재 핸들러에서 next()를 호출함으로써 진행된다. 먼저 404(Not Found)를 핸들링하는 부분을 보면, request한 경로가 '/'이거나 ''/users'를 포함하면 해당 핸들러로 진입하지만 그 외의 경로일 경우 일치하는 패턴이 없기 때문에 마지막 순서인 404 handler로 진입한다 next()의 경우 인자로 null이 아닌 값이 전달되었을 경우 다음 핸들러로 진입하지 않고, 에러 핸들러로 점프한다. 해당 핸들러는 next를 호출하지 않으므로,..
단순히 yarn start해서 서버를 시작했을 경우에는 변경된 코드를 반영하려면 종료 후 재시작이 필요했다. 이는 매우 번거로운데, Nodemon을 사용하면 코드 수정 시 서버 재시작을 자동으로 처리해준다. https://github.com/remy/nodemon remy/nodemon Monitor for any changes in your node.js application and automatically restart the server - perfect for development - remy/nodemon github.com yarn add nodemon --global 로 해당 모듈을 설치한다 (npm 사용자라면 npm install -g nodemon을 입력하여 설치한다) 설치가 완료되었다면..
참고: https://expressjs.com/ko/starter/installing.html Express 설치 설치 Node.js가 이미 설치되었다고 가정한 상태에서, 애플리케이션을 보관할 디렉토리를 작성하고 그 디렉토리를 작업 디렉토리로 설정하십시오. $ mkdir myapp $ cd myapp npm init 명령을 이용하여 애플� expressjs.com 우선 프로젝트명으로 원하는 경로에 폴더를 생성한다. 해당 폴더를 기준으로 윈도우 사용자는 PowerShell로, 그 외의 OS사용자는 터미널을 이용해 해당 폴더로 이동한다. (예를 들어, 해당 폴더가 C:\\projects\express-project라면 cd C:\\projects\express-project를 입력한다) 그 후, npx ex..
js는 다른 언어들과는 다르게 동작하는 연산들이 많이 있다. 오죽하면 이런 밈이 유행할 정도인데... 이번 포스트에서 다룰 것은 AND연산자와 OR연산자다. 불 연산 컴퓨터나 이공계를 전공했다면 '불 대수'에 대해 들어본 적이 있을 것이다. 불 대수에서, A AND B (A와 B는 참이거나 거짓)의 결과값은 항상 참이거나 거짓이다. 마찬가지로, C나 JAVA같은 강타입 언어에서 불 연산을 진행하면 값 역시 반드시 boolean 값으로 나오게 된다. 그런데 js에서의 논리 연산의 결과값은 boolean 값을 가질 수도 있지만, 다른 값을 가질 수도 있다. const test= "first" && "second"; console.log(typeof test === 'boolean'); //false 분명 &..
React를 활용해 제작한 두 번째 프론트엔드 프로젝트입니다. 안드로이드 앱 주요 기능을 중점으로 구현하였으며, 네이티브 앱의 단점 때문에 현재까지는 안드로이드에서만 사용이 가능했습니다. 또한 안드로이드 유저라도, 앱이 설치되어 있지 않으면 사용이 어려웠었죠. 웹사이트가 제공된다면, 웹 브라우저를 활용할 수 있는 모든 환경에서 설치 없이 빠르고 간편한 사용이 가능해집니다. 사실 모바일보다는, 사이퍼즈는 PC게임이므로 PC 환경을 지원하는 것이 중요하다고 생각합니다. 웹 버전은 작년 여름부터 제작하고 있었으나, 예비창업패키지 협약과 개인 사정 등으로 진행이 매우 더디다가 협약이 완전히 끝난 다음, 처음부터 다시 시작하여 금일 출시 완료했습니다. 모든 플랫폼에서 사용이 가능하되 레이아웃을 세심히 조정하여 불..
리덕스는 대표적인 상태 관리 라이브러리다. 리액트에서는 여러 컴포넌트가 동시에 사용하는 state를 props를 이용해 하위 컴포넌트로 계속해서 전달하는 대신 하나의 스토어에서 관리하게 되어 생산성을 높이는데 주로 사용된다. 잠깐 설명을 하고 가자면, 리액트는 FLUX아키텍쳐를 채택하여 컴포넌트 간 데이터 흐름은 항상 상위 컴포넌트에서 하위 컴포넌트로 흐르게끔 강제한다. 그러나 때때로 A Component에서 B Component로 데이터를 넘겨줘야만 할 때가 있는데, 이 규칙을 따르려면 불필요한 래핑을 진행하거나 사용할 데이터를 Parent Component로 옮긴 후, props로 보내주는 방식을 채택해야 한다. 컴포넌트간 관계가 소규모라면 어렵지 않지만, 매우 복잡하게 얽혀있는 관계라면 꽤 번거롭고..
hook을 사용하다가 발생하는 에러다. 무슨 에러인지 잘 모르겠지만, 콘솔에 찍힌 에러를 따라가보면 다음과 같은 메시지를 확인할 수 있다. 즉 useEffect의 마지막 인자(deps)부분이 array가 아니라서 발생하는 에러다. 이런 식으로 deps에 array가 아닌 string이 주어진 상태이므로 이렇게 배열로 바꿔주면 해결된다.
앱에서 제공되는 해당 데이터는 랭크 1000위 내의 유저들을 대상으로 얻어진 데이터를 분석하여 표시해줍니다. 해당 플레이어의 전적을 얻기 위해서 한번 조회하고, 그 전적에서 나온 매칭 아이디로 다시한번 매칭 정보를 조회하여 얻어지는 데이터로 포지션 통계가 작성됩니다. (물론 현재는 플레이어의 전적 조회 시, 포지션 정보가 표시되긴 합니다) 그런데 문제는 이렇게 하면 request 횟수는 약 3~4만번인 데다가 다뤄야 하는 데이터의 갯수도 매우 많습니다. 크롤러를 서버 측에서 돌아가게 설정해 두어서 서버에 가해지는 부하가 너무 크다는 뼈아픈 단점이 있습니다. (현재 서버 사양 1Core, 1GB RAM) 해당 크롤러를 작동시키면 10~30분 정도가 걸리며 메모리는 90%, CPU는 거의 100%를 찍게 됩..
https://smallbusiness.seoul.go.kr/html/home.php 서울시자영업자생존자금 서울시자영업자생존자금 신청 페이지 smallbusiness.seoul.go.kr 자격조건 잘 보고 신청하세요. 잘먹겠습니다
현재까지 배포 과정은 다음과 같았다. 1. yarn build 입력 후 빌드 대기2. FTP클라이언트를 켠 후, build폴더 내용을 원격 서버에 복사 터미널에 yarn build후, 다른 창으로 이동하여 작업을 이어나가야 한다는 점이 매끄럽지 못하다고 느꼈기 때문에 다른 방법을 알아보기로 했다. 가능하면 터미널에서 build했으니, 터미널에서 배포까지 끝내고 싶어 검색하던 도중 scp 명령어에 대해 알게 되었다. scp란 무엇인가scp란 secure copy의 약자로써, 원격으로 파일의 카피를 할 수 있게 해주는 명령어이다. 어떻게 사용하는가MAC이나 Linux계열의 OS사용자면 그냥 터미널을 열면 되고Windows사용자는 PowerShell을 사용해야 한다. 사용 포맷은 다음과 같다. scp [OPT..
A액티비티에서 어떤 데이터를 B액티비티에 전달하고자 할 때, A액티비티에서 Intent.putExtra()를 이용해 인텐트에 데이터를 넣고, startActivity()를 이용해 B액티비티에 데이터를 전달함과 동시에 B액티비티를 실행한다. 그러나, intent.putExtra()에 들어갈 수 있는 데이터의 크기는 무한정하지 않다. 공식 문서를 살펴보면, 이러한 방식으로 매우 큰 데이터가 입력될 경우 TransactionTooLargeException이 발생함을 명시하고 있다. (한 프로세스가 공유하는 트랜젝션 버퍼에 1MB 넘게 입력할 때 이런 문제가 발생한다고 한다. 보통 Bitmap이나 길이가 긴 배열을 입력하려 할 때 발생한다) If the arguments or the return value ar..
ListView가 낮은 성능을 보이는 데는 나의 경험에 기반한 몇 가지 이유가 있다. 1. getView 구현부에서 항상 view inflatation을 하는 경우 2. getView 구현부에서 ViewHolder패턴을 사용하지 않아 항상 업데이트하는 경우 3. ListView 높이 재설정 시 아이템 갯수만큼 measure하는 경우 4. 필요하지 않은 데이터까지 한번에 렌더링하는 경우 ListView 작업은 UIThread에서 이루어지기 때문에, 여기에서 많은 시간을 사용한다면 로그캣에 Layout Skipping메시지가 뜨면서 일정 시간동안 화면이 멈추게 된다. 위의 원인만 제거해주더라도 체감할 수 있을 정도의 성능 향상이 있을 것이다. 1. getView 구현부에서 항상 view inflatation..
플레이어의 플레이 정보를 얻어오는 API(/cy/players/{MATCH_ID}/matches)에서 간혹 400 에러가 발생하는 오류가 꽤 오랬동안 있었습니다. 테스트 환경에서는 재현이 불가능해 꽤 오랫동안 방치되었던 원인인데, 해결을 위해 로그를 수집하니, 20일만에 1000개의 오류 로그가 찍혔습니다. 몇몇분들께만 발생하는 줄 알았으나, 꽤 많은 분들께서 해당 오류로 이용에 불편을 겪고 있었네요... 그런데 원인은 의외로 간단했습니다. createDate는 로그가 찍힌 시간(서버 시간 기준)이고, description에는 요청 url 정보가 기록되어 있습니다. createDate를 보면 거의 00초 부근(분 단위가 바뀌기 직전 혹은 직후)이고 description의 endDate쿼리에는 전부 분 단..
안드로이드 개발자라면 누구나 한 번쯤은 ScrollView아래의 ListView를 사용했을 때 ListView의 높이가 쪼그라드는 문제를 경험해본적이 있을 것이다. 구글에 android listview height is weired처럼 검색하면 가장 많이 나오는 솔루션은 요런 함수를 쓰라는 내용이다. 웬만하면 리사이클러뷰를 사용하는 방법으로 회피해가려 하지만 "스크롤뷰+리스트뷰"조합으로 된 모든 코드를 뒤집어버릴 순 없으니 해당 부분에만 위의 함수를 적용시켜주고 있었다. 그런데 예상했던 것과는 달리 위의 함수는 연산시간을 꽤 잡아먹는 녀석이다. (특히 listItem.measure 부분) 200개의 요소가 있는 리스트뷰의 높이를 계산하려고 하니 소요시간이 1초가 넘어가버려서 앱 애니메이션이 뚝뚝 끊기는 ..