SlideShare a Scribd company logo
코드리뷰 짝 매칭 프로그램 구현기 
2014-12-09 김 용 훈
오늘 얘기 할 주제는? 
• Node.js에 대해선 다루지 않습니다. 
• 이걸 왜 만들었을까요? 
• 구현시 어려웠던 점. 느꼈던 점.
이걸 왜 만들었을까요? 
• 현재 팀장포함 총 팀원수 7명 
• 2개 프로젝트에서 코드리뷰 사항을 위키로 정리하여 공유 
=> 잘 안됨 
• 코드리뷰 활성화를 위해 이 프로그램을 먼저 만들고 공유 
=> 유지보수부터 내 짝과 코드리뷰를 한번 해보자!
이걸 왜 만들었을까요? 
• 코드리뷰 짝의 역할 정의 
- 짝의 요청이 있으면 같이 설계참여. 커밋 전 코드리뷰(필수) 
- 정기배포시 시간적여유가 있으면 같이 테스트(옵션) 
• 코드리뷰 짝 매칭시 규칙 
- 팀장제외 총 6명이 일대일로 매칭되어 총 3개의 짝 만듦 
- 짝은 1주단위로 매주 금요일마다 바뀜 
- 짝은 본인을 제외한 나머지 5명 중 랜덤으로 결정 
단, 지난주에 짝이 된 사람과는 다시 짝이 되지 않음
구현시 어려웠던 점. 느꼈던 점. 
• 처음에 했던 생각! 
“코드리뷰 짝 매칭 결과만 웹페이지 하나로 
보여주면 될 것 같은데… 
Java + Spring을 써야할까…” 
=> 그래서 간단하게 자바스크립트만으로 
서버어플리케이션을 만들 수 있는 Node.js 선택
구현시 어려웠던 점. 느꼈던 점. 
Node.js 기본개념 + 트위터백업예제/Express 필요한 부분 학습
구현시 어려웠던 점. 느꼈던 점. 
[사용자 시나리오] 
1. HTTP로 해당 URL 요청 
2. Node.js 서버 Express가 
처리 할 Controller 찾음 
3. 비지니스로직 처리 후 
결과를 EJS에게 보냄 
4. 사용자는 EJS가 랜더링한 
결과를 브라우져에서 봄 
5. node-schedule이 
백단에서 주기적으로 
코드리뷰 결과데이터 넣음
구현시 어려웠던 점. 느꼈던 점. 
http://bluepoet1004.cafe24.com:4000/users
구현시 어려웠던 점. 느꼈던 점. 
• 어려웠던 점! 비동기 I/O 
=> Node.js는 이벤트루프기반의 비동기 I/O로 실행됨 
이미지 출처 : http://www.techthali.org/node-js-asynchronous-non-blocking-events-callbacks/
구현시 어려웠던 점. 느꼈던 점. 
• 어려웠던 점! 비동기 I/O 
client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date, 
INTERVAL 7 DAY) > NOW() AND create_date < NOW();select * from member order by 
id', function(err, rows, fields) { 
ㅗㅗㅗ소 
if(err) { 
throw err; 
} 
res.render('userList', { 
users: rows[1], 
prevUsers: rows[0], 
title: 'Listing Developmemt Team CodeReview Matching Result' 
}); 
}); 
비동기 I/O를 사용해 콜백함수를 전달하고, DB에서 조회가 끝났다는 
이벤트가 발생하면 콜백함수를 처리한다는 걸 이해못함!
구현시 어려웠던 점. 느꼈던 점. 
• 어려웠던 점! 비동기 I/O 
client.query('SELECT * FROM member', function(err, results, fields) { 
client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date, INTERVAL 7 
DAY) > NOW() AND create_date < NOW();select * from member order by id', function(err, rows, fields) { 
ㅗㅗㅗ소 
if(err) { 
throw err; 
} 
console.log('results ' + results[0].name); 
res.render('userList', { 
users: rows[1], 
prevUsers: rows[0], 
title: 'Listing Developmemt Team CodeReview Matching Result' 
}); 
}); 
}); 
코드리뷰 매칭결과를 가져오는 콜백함수(클로저) 안에서 멤버를 조회 
하는 콜백함수의 파라미터인 results(외부변수)를 참조할 수 있음!
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “알고리즘”은 중요하다! 
“결국, Node.js와 그 안에서 쓰이는 기본/확장모듈은 
내가 만들고자 하는 서비스를 빠르게 구현해주는 
장식자(Decorator)의 역할인 것 같다….”
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “알고리즘”은 중요하다! 
나의 코드리뷰짝 번호를 찾아주는 
getRandomNumber(selectedNumber); 
함수가 이 프로그램의 핵심! 
손으로 구현하기 전엔 간단할 것 같았다.. 
하지만.. 막상 구현을 시작하니... 
생각처럼 쉽지 않았고, 시간이 오래 걸림. 
역시 “백문이 불여일타!” 
getRandomNumber: function(selectedNumber) { 
ㅗㅗㅗ소 
var me = this; 
var randomNumbers = [1,2,3,4,5,6]; 
randomNumbers.splice(randomNumbers.indexOf(selectedNumber), 1); 
var prevPairNumber = me.prevPair.get(selectedNumber); 
if(prevPairNumber !== undefined) { 
randomNumbers.splice(randomNumbers.indexOf(prevPairNumber), 1); 
} 
for(var i=0; i<me.leftNumbers.length; i++) { 
if(randomNumbers.indexOf(me.leftNumbers[i]) == -1) { 
continue; 
} 
randomNumbers.splice(randomNumbers.indexOf(me.leftNumbers[i]), 1); 
} 
if(randomNumbers.length == 3) { 
var deleteNumber = randomNumbers.slice(0); 
for(var i=0; i<randomNumbers.length; i++) { 
if(me.prevPair.get(randomNumbers[i]) !== undefined) { 
var key = randomNumbers[i]; 
var value = me.prevPair.get(randomNumbers[i]); 
deleteNumber.splice(deleteNumber.indexOf(key), 1); 
deleteNumber.splice(deleteNumber.indexOf(value), 1); 
break; 
} 
} 
randomNumbers.splice(randomNumbers.indexOf(deleteNumber[0]), 1); 
} 
var randomNumbersCnt = randomNumbers.length; 
var randomNumberIndex = Math.floor(Math.random() * (randomNumbersCnt - 
1 + 1)) + 1; 
return randomNumbers[randomNumberIndex-1]; 
},
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “테스트코드”는 꼭 작성하자! 
“만들기에 바빠, 테스트코드 만드는 건 처음에 
생각하지도 못함. 
하지만… 
다 만들고 웹페이지 결과도 봤지만 왠지모를 이 찜찜함…”
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “테스트코드”는 꼭 작성하자! 
test/codeReviewPairLogicTest.js 
ㅗㅗㅗ소 
var assert = require('assert'); 
var pair = require('../pair'); 
var Map = require('./map'); 
before(function() { 
pair.init(); 
pair.prevPair = new Map(); 
pair.result = new Map(); 
pair.prevPair.put(1, 5); 
pair.prevPair.put(2, 6); 
pair.prevPair.put(3, 4); 
}); 
describe('[CodeReviewMatchingPair]PairLogicConfirm Test Suite', function() { 
describe('CodeReviewPair Result Confirm', function() { 
it('result count is 3, the key and value of the map is not the same', function() { 
pair.fakeExtractPrevMembers(); 
assert.equal(pair.result.size(), 3); 
var keys = pair.result.keys(); 
for(var i=0; i< keys.length; i++) { 
assert.notEqual(keys[i] != pair.result.get(keys[i]), false); 
} 
}); 
}); 
});
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “테스트코드”는 꼭 작성하자! 
“done()함수” 전달로 “비동기테스트” 가능! test/dbDataConfirmTest.js 
ㅗㅗㅗ소 
var assert = require('assert'); 
var db = require('./db'); 
var repo = require('../repository'); 
before(function() { 
repo.getMembers(); 
}); 
describe('[CodeReviewMatchingPair]DbDataConfirmTest Test Suite', function() { 
describe('Total Member Count : Direct Query', function() { 
it('All Member is six', function(done) { 
db.query('SELECT * FROM member', function(err, rows, fields) { 
if(err) { 
throw err; 
} 
assert.equal(rows.length, 6); 
done(); 
}); 
}); 
}); 
describe('CodeReview Member Data Confirm', function() { 
it('CodeReview Member Data Confirm', function(done) { 
db.query('SELECT first_id, after_id FROM member_match_list where DATE_ADD(create_date, INTERVAL 7 DAY) > NOW() AND create_date < NOW()', function(err, rows, fields) { 
if(err) { 
throw err; 
} 
assert.equal(rows.length, 3); 
for(var i=0; i< rows.length; i++) { 
assert.notEqual(rows[i].first_id != rows[i].after_i, false); 
} 
done(); 
}); 
}); 
}); 
describe('Total Member Count : Other Module Called', function() { 
it('All Member is six', function() { 
assert.equal(repo.result.length, 6); 
}); 
}); 
});
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “테스트코드”는 꼭 작성하자! 
- Node.js Test Framework인 “Mocha”와 
Node.js 내장 “assert 모듈”로 유닛테스트 작성
구현시 어려웠던 점. 느꼈던 점. 
• 느꼈던 점! “테스트코드”는 꼭 작성하자! 
- BDD(behavior-driven development)로 작성된 
유닛테스트코드를 통해 “내가 만든 코드에 대한 
검증 및 추후 리팩토링에 대한 자신감” 얻음!
• 소스코드/프로젝트설명 보기 
https://github.com/bluepoet/CodeReviewMatchingPair
끝

More Related Content

What's hot

Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹
Kros Huang
 
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
Hansol Kang
 
RSpec & TDD Tutorial
RSpec & TDD TutorialRSpec & TDD Tutorial
RSpec & TDD Tutorial
Wen-Tien Chang
 
Handling concept drift in data stream mining
Handling concept drift in data stream miningHandling concept drift in data stream mining
Handling concept drift in data stream mining
Manuel Martín
 
Event driven autoscaling with KEDA
Event driven autoscaling with KEDAEvent driven autoscaling with KEDA
Event driven autoscaling with KEDA
Nilesh Gule
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
Ravindu Fernando
 
Design by contract(계약에의한설계)
Design by contract(계약에의한설계)Design by contract(계약에의한설계)
Design by contract(계약에의한설계)
Jeong-gyu Kim
 
Docker 101 - High level introduction to docker
Docker 101 - High level introduction to dockerDocker 101 - High level introduction to docker
Docker 101 - High level introduction to docker
Dr Ganesh Iyer
 
Pixel Recurrent Neural Networks
Pixel Recurrent Neural NetworksPixel Recurrent Neural Networks
Pixel Recurrent Neural Networks
neouyghur
 
DevTest Portfolio Overview
DevTest Portfolio OverviewDevTest Portfolio Overview
DevTest Portfolio Overview
CA Technologies
 
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
iFunFactory Inc.
 
Python 테스트 시작하기
Python 테스트 시작하기Python 테스트 시작하기
Python 테스트 시작하기
Hosung Lee
 
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
Deep Learning JP
 
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
Ajeet Singh Raina
 
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...Вячеслав Ипполитов
 
DevOps Architecture Design
DevOps Architecture DesignDevOps Architecture Design
DevOps Architecture Design
Agile Testing Alliance
 
Introduction to kubernetes
Introduction to kubernetesIntroduction to kubernetes
Introduction to kubernetes
Michal Cwienczek
 
FIWARE NGSI: Managing Context Information at Large Scale
FIWARE NGSI: Managing Context Information at Large ScaleFIWARE NGSI: Managing Context Information at Large Scale
FIWARE NGSI: Managing Context Information at Large Scale
FIWARE
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
Skills Matter
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal Architecture
CodelyTV
 

What's hot (20)

Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹Kotlin Receiver Types 介紹
Kotlin Receiver Types 介紹
 
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
Photo-realistic Single Image Super-resolution using a Generative Adversarial ...
 
RSpec & TDD Tutorial
RSpec & TDD TutorialRSpec & TDD Tutorial
RSpec & TDD Tutorial
 
Handling concept drift in data stream mining
Handling concept drift in data stream miningHandling concept drift in data stream mining
Handling concept drift in data stream mining
 
Event driven autoscaling with KEDA
Event driven autoscaling with KEDAEvent driven autoscaling with KEDA
Event driven autoscaling with KEDA
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
Design by contract(계약에의한설계)
Design by contract(계약에의한설계)Design by contract(계약에의한설계)
Design by contract(계약에의한설계)
 
Docker 101 - High level introduction to docker
Docker 101 - High level introduction to dockerDocker 101 - High level introduction to docker
Docker 101 - High level introduction to docker
 
Pixel Recurrent Neural Networks
Pixel Recurrent Neural NetworksPixel Recurrent Neural Networks
Pixel Recurrent Neural Networks
 
DevTest Portfolio Overview
DevTest Portfolio OverviewDevTest Portfolio Overview
DevTest Portfolio Overview
 
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
[MGDC] 리눅스 게임 서버 성능 분석하기 - 아이펀팩토리 김진욱 CTO
 
Python 테스트 시작하기
Python 테스트 시작하기Python 테스트 시작하기
Python 테스트 시작하기
 
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
[DLHacks 実装]Perceptual Adversarial Networks for Image-to-Image Transformation
 
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
Collabnix Online Webinar - Demystifying Docker & Kubernetes Networking by Bal...
 
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...
каталог сортов зернофуражных культур (ячмень, овес) селекции тоо «казнии земл...
 
DevOps Architecture Design
DevOps Architecture DesignDevOps Architecture Design
DevOps Architecture Design
 
Introduction to kubernetes
Introduction to kubernetesIntroduction to kubernetes
Introduction to kubernetes
 
FIWARE NGSI: Managing Context Information at Large Scale
FIWARE NGSI: Managing Context Information at Large ScaleFIWARE NGSI: Managing Context Information at Large Scale
FIWARE NGSI: Managing Context Information at Large Scale
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Towards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal ArchitectureTowards Functional Programming through Hexagonal Architecture
Towards Functional Programming through Hexagonal Architecture
 

Viewers also liked

알고리듬? 알고리즘?
알고리듬? 알고리즘?알고리듬? 알고리즘?
알고리듬? 알고리즘?
Choulhyouc Lee
 
1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)fmbvbfhs
 
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
NAVER D2
 
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
datasciencekorea
 
Collaborative filtering
Collaborative filteringCollaborative filtering
Collaborative filtering
SungMin OH
 
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
datasciencekorea
 
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
datasciencekorea
 
집단지성 프로그래밍 02-추천시스템 만들기
집단지성 프로그래밍 02-추천시스템 만들기집단지성 프로그래밍 02-추천시스템 만들기
집단지성 프로그래밍 02-추천시스템 만들기
Kwang Woo NAM
 
자바채팅 다중
자바채팅 다중자바채팅 다중
자바채팅 다중
라한사 아
 
스마트 시티의 빅데이터 분석론 - 최준영
스마트 시티의 빅데이터 분석론 - 최준영스마트 시티의 빅데이터 분석론 - 최준영
스마트 시티의 빅데이터 분석론 - 최준영
datasciencekorea
 
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
Minkyu Cho
 
대단한 기술없이 반응형웹 UI 만들기
대단한 기술없이 반응형웹 UI 만들기대단한 기술없이 반응형웹 UI 만들기
대단한 기술없이 반응형웹 UI 만들기
지수 윤
 
20141223 머하웃(mahout) 협업필터링_추천시스템구현
20141223 머하웃(mahout) 협업필터링_추천시스템구현20141223 머하웃(mahout) 협업필터링_추천시스템구현
20141223 머하웃(mahout) 협업필터링_추천시스템구현
Tae Young Lee
 
[4차]왓챠 알고리즘 분석(151106)
[4차]왓챠 알고리즘 분석(151106)[4차]왓챠 알고리즘 분석(151106)
[4차]왓챠 알고리즘 분석(151106)
고려대학교 정보기술경영학회 : ITS
 
[4차]넷플릭스 알고리즘 분석(151106)
[4차]넷플릭스 알고리즘 분석(151106)[4차]넷플릭스 알고리즘 분석(151106)
[4차]넷플릭스 알고리즘 분석(151106)
고려대학교 정보기술경영학회 : ITS
 
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
승화 양
 
제1화 추천 시스템 이란.ppt
제1화 추천 시스템 이란.ppt제1화 추천 시스템 이란.ppt
제1화 추천 시스템 이란.ppt
choi kyumin
 

Viewers also liked (17)

알고리듬? 알고리즘?
알고리듬? 알고리즘?알고리듬? 알고리즘?
알고리듬? 알고리즘?
 
1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)1.자료구조와 알고리즘(강의자료)
1.자료구조와 알고리즘(강의자료)
 
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
 
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
온라인 데이터 분석을 통한 선거예측- 김찬우, 조인호
 
Collaborative filtering
Collaborative filteringCollaborative filtering
Collaborative filtering
 
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
국가의 신성장 동력으로서 공간정보의 가치와 활용 2016-0603
 
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
빅데이터 기술을 활용한 뉴스 큐레이션 서비스 - 온병원
 
집단지성 프로그래밍 02-추천시스템 만들기
집단지성 프로그래밍 02-추천시스템 만들기집단지성 프로그래밍 02-추천시스템 만들기
집단지성 프로그래밍 02-추천시스템 만들기
 
자바채팅 다중
자바채팅 다중자바채팅 다중
자바채팅 다중
 
스마트 시티의 빅데이터 분석론 - 최준영
스마트 시티의 빅데이터 분석론 - 최준영스마트 시티의 빅데이터 분석론 - 최준영
스마트 시티의 빅데이터 분석론 - 최준영
 
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
Apache Mahout 맛보기 - 30분만에 추천시스템 만들기 for 네이버 TV 서비스
 
대단한 기술없이 반응형웹 UI 만들기
대단한 기술없이 반응형웹 UI 만들기대단한 기술없이 반응형웹 UI 만들기
대단한 기술없이 반응형웹 UI 만들기
 
20141223 머하웃(mahout) 협업필터링_추천시스템구현
20141223 머하웃(mahout) 협업필터링_추천시스템구현20141223 머하웃(mahout) 협업필터링_추천시스템구현
20141223 머하웃(mahout) 협업필터링_추천시스템구현
 
[4차]왓챠 알고리즘 분석(151106)
[4차]왓챠 알고리즘 분석(151106)[4차]왓챠 알고리즘 분석(151106)
[4차]왓챠 알고리즘 분석(151106)
 
[4차]넷플릭스 알고리즘 분석(151106)
[4차]넷플릭스 알고리즘 분석(151106)[4차]넷플릭스 알고리즘 분석(151106)
[4차]넷플릭스 알고리즘 분석(151106)
 
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
실전 스타트업 데이터분석: 소셜데이팅 이음은 이렇게 한다
 
제1화 추천 시스템 이란.ppt
제1화 추천 시스템 이란.ppt제1화 추천 시스템 이란.ppt
제1화 추천 시스템 이란.ppt
 

Similar to 코드리뷰 짝 매칭 프로그램 구현기

Naver Campus Hackday Winter 2017 참가 후기
Naver Campus Hackday Winter 2017 참가 후기Naver Campus Hackday Winter 2017 참가 후기
Naver Campus Hackday Winter 2017 참가 후기
Youngbin Han
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
Ryan Park
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
Ryan Park
 
[131]chromium binging 기술을 node.js에 적용해보자
[131]chromium binging 기술을 node.js에 적용해보자[131]chromium binging 기술을 node.js에 적용해보자
[131]chromium binging 기술을 node.js에 적용해보자
NAVER D2
 
[Osxdev]4.swift
[Osxdev]4.swift[Osxdev]4.swift
[Osxdev]4.swift
NAVER D2
 
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012Esun Kim
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
기동 이
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
beom kyun choi
 
Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822병헌 정
 
함수형 프로그래밍
함수형 프로그래밍함수형 프로그래밍
함수형 프로그래밍
QooJuice
 
Light Tutorial Django
Light Tutorial DjangoLight Tutorial Django
Light Tutorial Django
Kwangyoun Jung
 
Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리
Younghan Kim
 
KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기
Ryan Park
 
개발자의 컴퓨터
개발자의 컴퓨터개발자의 컴퓨터
개발자의 컴퓨터
jaehyok Song
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
mniktw
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
Han Jung Hyun
 
유니티3D 그리고 웹통신
유니티3D 그리고 웹통신유니티3D 그리고 웹통신
유니티3D 그리고 웹통신
현욱 김
 
Spring Boot 2
Spring Boot 2Spring Boot 2
Spring Boot 2
경륜 이
 
Nodejs 발표자료
Nodejs 발표자료Nodejs 발표자료
Nodejs 발표자료
shanka2
 

Similar to 코드리뷰 짝 매칭 프로그램 구현기 (20)

Naver Campus Hackday Winter 2017 참가 후기
Naver Campus Hackday Winter 2017 참가 후기Naver Campus Hackday Winter 2017 참가 후기
Naver Campus Hackday Winter 2017 참가 후기
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
온라인 게임에서 사례로 살펴보는 디버깅 in NDC2010
 
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
온라인 게임에서 사례로 살펴보는 디버깅 in NDC10
 
[131]chromium binging 기술을 node.js에 적용해보자
[131]chromium binging 기술을 node.js에 적용해보자[131]chromium binging 기술을 node.js에 적용해보자
[131]chromium binging 기술을 node.js에 적용해보자
 
[Osxdev]4.swift
[Osxdev]4.swift[Osxdev]4.swift
[Osxdev]4.swift
 
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
자동화된 소스 분석, 처리, 검증을 통한 소스의 불필요한 #if - #endif 제거하기 NDC2012
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822Node js[stg]onimusha 20140822
Node js[stg]onimusha 20140822
 
함수형 프로그래밍
함수형 프로그래밍함수형 프로그래밍
함수형 프로그래밍
 
Light Tutorial Django
Light Tutorial DjangoLight Tutorial Django
Light Tutorial Django
 
Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리Ksug2015 jpa4 객체지향쿼리
Ksug2015 jpa4 객체지향쿼리
 
KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기KGC2010 - 낡은 코드에 단위테스트 넣기
KGC2010 - 낡은 코드에 단위테스트 넣기
 
개발자의 컴퓨터
개발자의 컴퓨터개발자의 컴퓨터
개발자의 컴퓨터
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
 
유니티3D 그리고 웹통신
유니티3D 그리고 웹통신유니티3D 그리고 웹통신
유니티3D 그리고 웹통신
 
Spring Boot 2
Spring Boot 2Spring Boot 2
Spring Boot 2
 
Nodejs 발표자료
Nodejs 발표자료Nodejs 발표자료
Nodejs 발표자료
 

코드리뷰 짝 매칭 프로그램 구현기

  • 1. 코드리뷰 짝 매칭 프로그램 구현기 2014-12-09 김 용 훈
  • 2. 오늘 얘기 할 주제는? • Node.js에 대해선 다루지 않습니다. • 이걸 왜 만들었을까요? • 구현시 어려웠던 점. 느꼈던 점.
  • 3. 이걸 왜 만들었을까요? • 현재 팀장포함 총 팀원수 7명 • 2개 프로젝트에서 코드리뷰 사항을 위키로 정리하여 공유 => 잘 안됨 • 코드리뷰 활성화를 위해 이 프로그램을 먼저 만들고 공유 => 유지보수부터 내 짝과 코드리뷰를 한번 해보자!
  • 4. 이걸 왜 만들었을까요? • 코드리뷰 짝의 역할 정의 - 짝의 요청이 있으면 같이 설계참여. 커밋 전 코드리뷰(필수) - 정기배포시 시간적여유가 있으면 같이 테스트(옵션) • 코드리뷰 짝 매칭시 규칙 - 팀장제외 총 6명이 일대일로 매칭되어 총 3개의 짝 만듦 - 짝은 1주단위로 매주 금요일마다 바뀜 - 짝은 본인을 제외한 나머지 5명 중 랜덤으로 결정 단, 지난주에 짝이 된 사람과는 다시 짝이 되지 않음
  • 5. 구현시 어려웠던 점. 느꼈던 점. • 처음에 했던 생각! “코드리뷰 짝 매칭 결과만 웹페이지 하나로 보여주면 될 것 같은데… Java + Spring을 써야할까…” => 그래서 간단하게 자바스크립트만으로 서버어플리케이션을 만들 수 있는 Node.js 선택
  • 6. 구현시 어려웠던 점. 느꼈던 점. Node.js 기본개념 + 트위터백업예제/Express 필요한 부분 학습
  • 7. 구현시 어려웠던 점. 느꼈던 점. [사용자 시나리오] 1. HTTP로 해당 URL 요청 2. Node.js 서버 Express가 처리 할 Controller 찾음 3. 비지니스로직 처리 후 결과를 EJS에게 보냄 4. 사용자는 EJS가 랜더링한 결과를 브라우져에서 봄 5. node-schedule이 백단에서 주기적으로 코드리뷰 결과데이터 넣음
  • 8. 구현시 어려웠던 점. 느꼈던 점. http://bluepoet1004.cafe24.com:4000/users
  • 9. 구현시 어려웠던 점. 느꼈던 점. • 어려웠던 점! 비동기 I/O => Node.js는 이벤트루프기반의 비동기 I/O로 실행됨 이미지 출처 : http://www.techthali.org/node-js-asynchronous-non-blocking-events-callbacks/
  • 10. 구현시 어려웠던 점. 느꼈던 점. • 어려웠던 점! 비동기 I/O client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date, INTERVAL 7 DAY) > NOW() AND create_date < NOW();select * from member order by id', function(err, rows, fields) { ㅗㅗㅗ소 if(err) { throw err; } res.render('userList', { users: rows[1], prevUsers: rows[0], title: 'Listing Developmemt Team CodeReview Matching Result' }); }); 비동기 I/O를 사용해 콜백함수를 전달하고, DB에서 조회가 끝났다는 이벤트가 발생하면 콜백함수를 처리한다는 걸 이해못함!
  • 11. 구현시 어려웠던 점. 느꼈던 점. • 어려웠던 점! 비동기 I/O client.query('SELECT * FROM member', function(err, results, fields) { client.query('SELECT first_id, after_id FROM ' + TABLE + ' where DATE_ADD(create_date, INTERVAL 7 DAY) > NOW() AND create_date < NOW();select * from member order by id', function(err, rows, fields) { ㅗㅗㅗ소 if(err) { throw err; } console.log('results ' + results[0].name); res.render('userList', { users: rows[1], prevUsers: rows[0], title: 'Listing Developmemt Team CodeReview Matching Result' }); }); }); 코드리뷰 매칭결과를 가져오는 콜백함수(클로저) 안에서 멤버를 조회 하는 콜백함수의 파라미터인 results(외부변수)를 참조할 수 있음!
  • 12. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “알고리즘”은 중요하다! “결국, Node.js와 그 안에서 쓰이는 기본/확장모듈은 내가 만들고자 하는 서비스를 빠르게 구현해주는 장식자(Decorator)의 역할인 것 같다….”
  • 13. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “알고리즘”은 중요하다! 나의 코드리뷰짝 번호를 찾아주는 getRandomNumber(selectedNumber); 함수가 이 프로그램의 핵심! 손으로 구현하기 전엔 간단할 것 같았다.. 하지만.. 막상 구현을 시작하니... 생각처럼 쉽지 않았고, 시간이 오래 걸림. 역시 “백문이 불여일타!” getRandomNumber: function(selectedNumber) { ㅗㅗㅗ소 var me = this; var randomNumbers = [1,2,3,4,5,6]; randomNumbers.splice(randomNumbers.indexOf(selectedNumber), 1); var prevPairNumber = me.prevPair.get(selectedNumber); if(prevPairNumber !== undefined) { randomNumbers.splice(randomNumbers.indexOf(prevPairNumber), 1); } for(var i=0; i<me.leftNumbers.length; i++) { if(randomNumbers.indexOf(me.leftNumbers[i]) == -1) { continue; } randomNumbers.splice(randomNumbers.indexOf(me.leftNumbers[i]), 1); } if(randomNumbers.length == 3) { var deleteNumber = randomNumbers.slice(0); for(var i=0; i<randomNumbers.length; i++) { if(me.prevPair.get(randomNumbers[i]) !== undefined) { var key = randomNumbers[i]; var value = me.prevPair.get(randomNumbers[i]); deleteNumber.splice(deleteNumber.indexOf(key), 1); deleteNumber.splice(deleteNumber.indexOf(value), 1); break; } } randomNumbers.splice(randomNumbers.indexOf(deleteNumber[0]), 1); } var randomNumbersCnt = randomNumbers.length; var randomNumberIndex = Math.floor(Math.random() * (randomNumbersCnt - 1 + 1)) + 1; return randomNumbers[randomNumberIndex-1]; },
  • 14. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! “만들기에 바빠, 테스트코드 만드는 건 처음에 생각하지도 못함. 하지만… 다 만들고 웹페이지 결과도 봤지만 왠지모를 이 찜찜함…”
  • 15. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! test/codeReviewPairLogicTest.js ㅗㅗㅗ소 var assert = require('assert'); var pair = require('../pair'); var Map = require('./map'); before(function() { pair.init(); pair.prevPair = new Map(); pair.result = new Map(); pair.prevPair.put(1, 5); pair.prevPair.put(2, 6); pair.prevPair.put(3, 4); }); describe('[CodeReviewMatchingPair]PairLogicConfirm Test Suite', function() { describe('CodeReviewPair Result Confirm', function() { it('result count is 3, the key and value of the map is not the same', function() { pair.fakeExtractPrevMembers(); assert.equal(pair.result.size(), 3); var keys = pair.result.keys(); for(var i=0; i< keys.length; i++) { assert.notEqual(keys[i] != pair.result.get(keys[i]), false); } }); }); });
  • 16. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! “done()함수” 전달로 “비동기테스트” 가능! test/dbDataConfirmTest.js ㅗㅗㅗ소 var assert = require('assert'); var db = require('./db'); var repo = require('../repository'); before(function() { repo.getMembers(); }); describe('[CodeReviewMatchingPair]DbDataConfirmTest Test Suite', function() { describe('Total Member Count : Direct Query', function() { it('All Member is six', function(done) { db.query('SELECT * FROM member', function(err, rows, fields) { if(err) { throw err; } assert.equal(rows.length, 6); done(); }); }); }); describe('CodeReview Member Data Confirm', function() { it('CodeReview Member Data Confirm', function(done) { db.query('SELECT first_id, after_id FROM member_match_list where DATE_ADD(create_date, INTERVAL 7 DAY) > NOW() AND create_date < NOW()', function(err, rows, fields) { if(err) { throw err; } assert.equal(rows.length, 3); for(var i=0; i< rows.length; i++) { assert.notEqual(rows[i].first_id != rows[i].after_i, false); } done(); }); }); }); describe('Total Member Count : Other Module Called', function() { it('All Member is six', function() { assert.equal(repo.result.length, 6); }); }); });
  • 17. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! - Node.js Test Framework인 “Mocha”와 Node.js 내장 “assert 모듈”로 유닛테스트 작성
  • 18. 구현시 어려웠던 점. 느꼈던 점. • 느꼈던 점! “테스트코드”는 꼭 작성하자! - BDD(behavior-driven development)로 작성된 유닛테스트코드를 통해 “내가 만든 코드에 대한 검증 및 추후 리팩토링에 대한 자신감” 얻음!
  • 19. • 소스코드/프로젝트설명 보기 https://github.com/bluepoet/CodeReviewMatchingPair
  • 20.