'전산'에 해당되는 글 136건
- 2011/03/16 로우레벨 (2)
- 2010/11/05 디스크... (2)
- 2010/06/26 TIOBE Index 2010
- 2010/05/04 Mercurial 에서의 branching (6)
- 2010/04/16 AlienBrain -> Mercurial 이주기
- 2010/03/25 너티독, 그리고 여행의 기록 (2)
- 2010/02/09 LUA 를 이용한 RPC
- 2009/09/11 lock-free 와 최적화 (9)
- 2009/09/09 volatile 과 memory barrier (2)
- 2009/09/07 TDD (4)
* 해서, 서버 설계에 특별한 문제가 없다면 (특별한 문제가 없도록 만들 수 있으려면 한 10년정도 죽어라 삽질해 봐야 하지만..) , 이상적인 상황일 경우 결국 동접의 병목은 DB 가 결정하게 된다.
* 그런데 안타깝게도 DB 분야에서 혁신적인 성능 향상을 기대하긴 힘들다.
* 메모리 증설이나 중간에 이것저것 트릭을 써서 DB 부하를 경감할 수 있지만, 서버 시동 후 대량으로 몰리는 순간 로그인 요청은 결국 디스크 긁어야 한다.
* 아무리 비싸고 빠른 스토리지라 해도 일반적인 사용 환경에서 하드 디스크 수배 이상의 성능을 내기는 힘들다. 돈이 모든걸 해결해 주지는 않는다...
TIOBE Index 2010

Mercurial 에서의 branching

AlienBrain -> Mercurial 이주기

진리의 TortoiseHg
너티독, 그리고 여행의 기록
LUA 를 이용한 RPC
-- 함수 호출 핸들러
function CALL_HANDLER( tbl, ... )
print( "function : " .. tbl.FUNC_NAME )
a = {...}
print( "args : " )
for i = 1, #a do
print( a[i] )
end
end
-- tbl 에 호출러를 바인딩
function Bind( tbl )
mt = {}
mt.__index = function( tbl, key )
-- 리턴할 함수 호출을 위한 임시객체
local tmp = {}
tmp.FUNC_NAME = key
-- 핸들러 바인딩
local inst = {}
inst.__call = CALL_HANDLER
setmetatable( tmp, inst )
return tmp
end
setmetatable( tbl, mt )
end
obj = {}
Bind( obj )
obj.aa( "a", 3, 5 )
$ lua-5.1 call.lua function : aa args : a 3 5
lock-free 와 최적화
volatile 과 memory barrier
나는 TDD 의 장점이 두 가지가 있다고 생각한다.
우선 첫 번째는… 살다 보면 예전에 만들어둔 코드가 이후의 수정 때문에 문제가 생기는 경우가 가끔 있다. 그런데 TDD 로 개발해 왔다면 이전에 작성해 둔 테스트를 활용 할 수 있기 때문에 이런 문제 발견이 쉬워진다. 대신, 코드 인터페이스 변경 시에는 기존의 테스트들도 고쳐주는 수고를 감수해야 할 것이다.
두 번째로, TDD 는 결합도(coupling) 낮은 디자인을 유도한다. 코드를 테스트 가능하게 만들려면 인터페이스가 명확해야 하고 어떻게든 다른 모듈과의 관계를 제거하거나 줄여야만 한다. 일반적으로 결합도가 낮은 코드는 좋은 디자인일 확률이 높기 때문에 모든 코드를 테스트 가능하게 유지하다 보면 전체적인 코드 수준도 좋아진다.
위와 같은 이유로, 기존의 프로젝트에 TDD 를 적용하는 것은 불가능하다고 본다. TDD 는 좋은 디자인을 ‘유도’ 할 뿐이지 이미 존재하는 나쁜 디자인을 좋은 디자인으로 ‘변화’ 시키지는 않기 때문이다. 켄트 벡은 기존 프로젝트에 TDD 를 어떻게 적용하냐는 질문에 책에서 ‘그것은 책 한권으로 설명해야 하는 분량이다’ 라는 답을 한것 같은데 내 생각에 기존 코드를 테스트 가능하게 만드는 방법은 없다. 그냥 새로 짜는게 빠르고 효율적일거다.
그렇다면 Testors는 모든 것을 TDD 로 개발하느냐..? 그렇지 않다. 나는 에반젤리스트도, 방법론자도 아니다. 뭔가가 새로 나오면 그것이 필드에서 실제로 동작하는걸 확인하지 않는 이상은 도입을 꺼린다. 좋은 방법론 1~2년쯤 늦게 도입한다 해서 프로젝트가 망하지는 않는다. 구지 리스크를 감수할 필요 없이 나 빼고 남들이 다 써서 긍정적인 효과가 명백히 드러날때에 써도 늦지 않다.
만약 내가 엔진이나 라이브러리나 웹, 혹은 비즈니스 로직을 주로 다루는 프로그래머였다면 대부분을 TDD 로 작성했을지 모르겠다. 하지만 나는 온라인 게임 프로그래머이고(였고) 게임에서 발생하는 상황에 대한 테스트 케이스를 작성하는 것은 쉽지 않다. 이건 숫자들의 합을 더하는 수준의 문제가 아니다. 결합도를 없애는 것만이 능사가 아니며 효율을 위해 어느정도의 관계는 분명히 유지시켜야 한다.
사실 TDD 라는 용어를 접하기 전부터 길찾기라던가 기타 게임 개발에 필요한 기하 문제들을 풀때는 항상 테스트를 작성했었다. input & output 이 명확한 이런 문제들을 테스트를 작성하지 않고 작업하는 사람이 정말 근성가이라고 본다.
3년쯤 전인가 회사의 UI 엔진을 스크립팅 가능하게 리뉴얼 하는 작업을 한 적이 있었다. 기존의 엔진은 폼 디자이너 툴만이 제공되었는데 이걸 기존 C++ 코드 & 리소스들과의 하위호환성을 유지하면서 루아 스크립팅 & 시뮬레이션이 가능하도록 만드게 목표였다. 작업은 순조로워서 엔진과 툴 모두 쓸만한 수준으로 부작용 없이 리뉴얼 할 수 있었다. 이후 UI 들은 자체 테스트를 내장한 채로 개발이 되었었다. 그런데 어떤 경우들은 테스트 작성 비용이 재현 및 디버깅 비용을 넘어서기도 했다.
게임 프로그래밍이란게 그렇다. input 과 output 을 명확하게 정의하기 힘들다. 시간의 흐름도 중요하고 타이밍도 중요하다. 몇몇 특정한 상태에 대한 테스트를 작성하고 유지하는것에 대한 비용은 정말이지 엄청나게 커질 수 있다. 내가 취한 방법은 대부분의 UI 들에서 테스트 작성을 포기하고, 런타임에 재현 및 디버깅이 쉽도록 한 것이었다. 키 하나로 스크립트가 모두 reload 되고, UI 가 문제 발생 이전으로 리셋되는 식이었다.
요약하자면, TDD 는 사실 패턴과 마찬가지로 이전부터 쓰는 사람은 모두 써왔던 방법이고, 그게 모든 분야에 사용되고 있지 않은 이유는 당연하게도 TDD 모든것에 대한 해답이 될 수 없기 때문이라고 생각한다. (난 사실 TDD 가 적용될 수 있는 분야가 매우 한정적이라고 생각한다) 문제는 이런글 (http://testors.net/tt/625)들이 귀 얇은 친구들을 혹세무민하여 주화입마에 빠지게 하는것에 있다. (이 대목에서 모 군이 찔려할것 같다...)
만약 TDD 가 정말로 결함을 줄여주고 개발 기간을 단축시켜 준다면 (참고: 난 이런 개발 효율이 측정 가능하지 않다고 생각한다), TDD 를 도입하지 않은것을 불안해 할 필요가 없다. 그게 사실이라면 어느샌가 당신 주변의 대부분의 개발자들이 TDD 를 사용해 프로젝트를 진행하고 있게 될거다. 그때 관심 가져도 늦지 않을것 같다.







Textcube 1.8.5 : Accelerando