1. 웹을 지탱하는 기술 : URI, HTML, HTTP
URI를 사용하면, 쇼핑 사이트의 상품이든 학술논문이든 동영상 사이트에 올라온 영상이든, 전 세계 온갖 정보를 가리킬 수 있습니다.
HTML은 그 정보를 표현하는 문서형식입니다.
그리고 HTTP라는 프로토콜을 사용하여 그 정보들을 가져오거나 내보냅니다.
HTTP,URI,HTML은 심플한 기술입니다.
예를 들어, HTTP 1.1이 정의하고 있는 메서드는 고작 8개뿐입니다.
그리고 URI는 종이 광고에 삽입할 수 있을 정도로 짧은 문자열입니다.
HTML은 XML을 바탕으로 한 범용 문서포맷입니다.
이런 심플함에 의해서 웹은 여러가지 응용이 가능하게 되어 있습니다.
1-1. URI : URI를 사용하면 웹상에 존재하는 모든 리소스를 한결같은 방식으로 보여줄 수 있습니다.
인터넷 상에서 반드시 유일한 호스트명의 구조와 호스트 내에서 유일한 계층적인 경로를 결합함으로써, 어떤 리소스의 URI가 전 세계의 다른 리소스와 절대로 중복되지 않도록 되어 있습니다.
* URN : 리소스의 이름을 나타내는 것 :리소스에 도메인명과는 독립된 이름을 붙일 수 있습니다. 예를 들어, 서적은 ISBN이라는 세계적으로 통일된 ID를 가지고 있습니다. URL과 같이 서버명과 프로토콜명이 들어있지 않기 때문에 URI로서 리소스를 가져 올 수 없다.
* URL : 리소스의 위치를 나타내는 것
* 리소스 : 웹상에 존재하는 이름을 가진 모든 정보.
리소스의 이름은 어떤 리소스를 다른 리소스와 구별하기 위한 것이고 즉 URI를 말합니다. 리소스들은 URI로 식별할 수 있습니다.전 세계의 무수한 리소스는 각각 URI로 의미 있는 이름을 가진다. URI를 이용함으로써, 프로그램은 리소스가 표현하는 정보에 접근할 수 있다.서버와 클라이언트 간에 실제로 리소스를 주고받을 때는 어떤 구체적인 데이터를 서로 송신합니다.
* 어드레스 가능성 : URI가 지니고 있는 리소스를 간단히 가리킬 수 있는 성질을 가리킴. 리소스를 어드레스 가능한 상태, 즉 제대로 이름이 붙어 있고 적절한 수단으로 접근할 수 있는 상태로 만들면, 프로그램을 만들기가 아주 쉬워집니다.
Cool URI : 변하지 않는 URI야말로 최고의 URI이다.
구현 의존성을 배제하고 심플하게 만들면 사용성이 향상된다. 기억하기도 간단하고, 개발자가 아닌 보통사람들도 사용하기 쉽다.
- 프로그래밍 언어에 의존적인 확장자와 경로를 포함하지 않는다.(.pl,rb,.do,.jsd 등)
- 메서드명과 세션ID를 포함하지 않는다.(jsessionid=123456)
- URI는 리소스를 표현하는 명사로 한다 (/show/123)
- 구현에 의존적인 경로명을 사용하지 않는다.(cgi-bin, servlet 등)
- URI를 변경하고 싶으면 가능한 한 Redirect하도록 합시다.
1-2. HTTP : 웹의 기반이 되는 프로토콜
HTTP : 이름대로라면 하이퍼텍스트 전송용 프로토콜이지만, 실제로는 HTML과 XML같은 하이퍼텍스트뿐만 아니라, 이미지, 음성, 동영상, JavaScript 프로그램,PDF와 같은 각종 오피스 도큐먼트 파일 등 컴퓨터에서 다룰 수 있는 데이터라면 무엇이든 전송할 수 있습니다.
웹은 HTTP라는 프로토콜을 이용해 클라이언트와 서버가 서로 통신하는 클라이언트/서버의 아키텍처 스타일을 채용하고 있습니다. 즉, 클라이언트가 서버에 요청Request을 보내면 서버는 클라이언트에 대해 응답을 돌려줍니다.
* TCP/IP : 인터넷의 토대를 구성하는 중요한 네트워크 프로토콜입니다. HTTP는 TCP/IP를 기반으로 하고 있습니다.인터넷의 네트워크 프로토콜은 계층 구조를 가지고 있습니다.각 계층별로 추상화하여 구현하면, 물리적으로 케이블이 동선인지 광케이블인지 하는 하위 계층의 구체적인 사항에 좌우되지 않고, 상위 계층을 구현할 수 있습니다.
- 네트워크 인터페이스 계층(이더넷) : 가장 아래의 계층으로 물리적인 케이블이나 네트워크 어댑터에 해당하는 부분입니다.
- 인터넷계층(IP) : 네트워크에서 데이터를 실제로 주고받는 것입니다. IP가 여기 해당합니다. IPㅇ서는 데이터의 기본적인 통신단위를 패킷이라고 부릅니다. 지정한 IP어드레스와 패킷 단위로 데이터를 주고받으면서 통신합니다.
- 트랜스포트(전송) 계층(UDP, TCP) : TCP가 여기 해당합니다. TCP는 목적지의 상대에 대해서 커넥션을 연결합니다. 이 커넥션을 사용해 데이터의 누락을 체크하고, 데이터의 도달을 보증합니다.
- 애플리케이션(응용) 계층(HTTP,NTP,SSH,SMTP,DNS) : TCP로 프로그램을 만들 때는 소켓이라고 불리는 라이브러리를 사용하는 것이 일반적입니다. 소켓은 네트워크에서의 데이터 교환을 추상화한 API로 접속,송신,수신,절단 등의 기본적인 기능을 갖추고 있습니다. HTTP서버와 브라우저는 소켓을 이용하여 구현합니다.
HTTP의 구체적인 구조
웹은 아키텍처 스타일로 클라이언트/서버를 채용하고 있습니다. 즉 웹브라우저가 정보를 제공하는 웹서버에 접속하여 각종 요청을 보내고 응답을 받는 구조입니다.
HTTP가 동기형 프로토콜이기 때문에 서버에서의 처리에 시간이 많이 걸리는 경우라도 요청을 보낸 클라이언트는 응답이 돌아올 때까지 대기합니다. 클라이언트는 우선 DNS를 사용해 호스트 이름을 해석하고, 그 결과로 얻어진 IP어드레스의 TCP 80번 포트에 접속한후 요청을 전송합니다. 서버는 이 요청을 읽어 들여 해석하고 응답을 보냅니다.
- 클라이언트에서 일어나는 일들 : 1.요청 메시지 구축 2.요청 메시지 송신 3.(응답이 돌아올 때까지 대기) 4.응답 메시지 수신 5.응답메시지 해석 6.클라이언트의 목적을 달성하기 위해 필요한 처리
- 서버에서 일어나는 일들 : 1.(요청을 대기) 2.요청 메시지 수신 3.요청 메시지 해석 4.적절한 애플리케이션 프로그램으로 처리를 위임 5. 애플리케이션 프로그램으로부터 결과를 취득 6.응답 메시지 구축 7.응답 메시지 송신
HTTP메시지의 구성요소 (스타트 라인, 헤더, 빈 줄 , 바디)
요청메시지 (1.요청라인-메서드,요청URI,프로토콜버전으로 구성 2.헤더-메시지의 메타 데이터, 각 헤더는 이름:값의 구성 3.바디-메시지를 나타내는 본질적인 정보,리소스를 새로 작성하거나 갱신할 때는 요청의 바디부분에 리소스의 표현자체)
응답메시지 (1.스테이터스 라인-프로토콜버전,스테이터스 코드,텍스트구문으로 구성 2.헤더- HTML의 MIME미디어 타입과 그 문자 인코딩 방식을 지정 3.바디)
*메타 데이터 : 데이터를 기술하는 데이터, 데이터에 대한 데이터를 말합니다. 메타라는 것은 이렇게 어떤 대상에 대해 고차원 것을 나타내는 접두어입니다.
HTTP의 스테이트리스성
스테이트풀의 결점 : 서버가 클라이언트의 애플리케이션 상태를 기억하는 것은 클라이언트의 수가 증가함에 따라 어려워지게 됩니다.
스테이트리스의 이점 : 스테이트리스는 클라이언트가 요청 메시지에 필요한 정보를 모두 포함시킵니다. 스테이트리스한 서버는 애플리케이션 상태를 기억할 필요가 없기 때문에 서버 시스템이 단순해집니다. 이 특성을 이용하면 확장시키는 것이 간단해집니다.
스테이트리스의 결점 : 1. 퍼포먼스 저하(클라이언트의 송신할 데이터 양이 많아지고 인증 등 서버에 부하가 걸리는 처리를 반복한다) 2. 통신에러에 대한 대처(네트워크 트러블이 발생했을 때 그 요청이 처리되었는지 알 수 없습니다)
* 스트레이트리스 : 서버가 클라이언트의 애플리케이션 상태를 보존하지 않는다는 제약
* 애플리케이션 상태 : 다른 이름으로 '세션상태'라고도 합니다. 시스템에 로그인하고부터 로그아웃할 때까지 일련의 조작을 모아'세션'이라고 부르는데, 이 일련의 조작 중의 상태는 애플리케이션 상태를 말하는 것이므로, 애플리케이션 상태와 세션 상태는 거의 동일한 의미가 됩니다.
HTTP메서드 - 8개 밖에 없는 메서드(GET,POST,PUT,DELETE,HEAD,OPTIONS,TRACE,CONNECT)
HTTP의 메서드를 한정하여 고정시켰기 때문에 결국 프로토콜이 심플하게 유지되었고, REST의 통일 인터페이스 제약으로 웹은 성공했습니다. GET의 숨겨진 안전성, PUT과 DELETE의 멱등성, 그리고 여차할 때는 뭐든지 할 수 있는 POST 각각의 메서드에 맞는 성질과 확장성을 갖춘 뛰어난 프로토콜입니다.
*GET : 리소드의 취득, 지정한 URI의 정보를 가져옵니다.
*POST : 리소스의 작성, 추가 1.서버 리소스의 작성(블로그 기사의 투고 등 조작에 사용) 2.리소스에 데이터 추가(로그등을 추가할 때) 3.다른 메서드로는 대응할 수 없는 처리(검색결과가 긴 경우 키워드를 요청 메시지의 바디에 넣는 경우)
* PUT : 리소스의 갱신,작성 1.리소스의 갱신(리소스의 텍스트를 바꿀때) 2.리소스의 작성(존재하지 않는 URI에 대한 요청)
- POST와 PUT의 사용 구분 : POST로 리소스를 작성할 경우, 클라이언트는 리소스의 URI를 지정할 수 없습니다. URI의 결정권은 서버 측에 있습니다. 반대로 PUT으로 작성하면 리소스의 URI는 클라이언트가 결정합니다. 예를 들어 Twitter와 같이 포스팅한 트윗의 URI를 서버 측이 자동적으로 결정하는 웹 서비스와 같은 경우는 POST를 이용하고, Wiki처럼 클라이언트가 결정한 타이틀이 그대로 URI가 되는 웹 서비스는 PUT을 사용하는 것이 적합합니다.
*DELETE : 리소스의 삭제
*HEAD : 리소스의 헤더(메타 데이터) 취득
*OPTIONS : 리소스가 서포트하는 메서드의 취득
- POST를 PUT/DELETE대신 사용하는 방법 1._method파라미터 2.X-HTTP-Method-Override
- 멱등성(어떤 조작을 몇번을 반복해도 결과가 동일한 것)과 안정성(조작 대상의 리소스의 상태를 변화시키지 않는 것
GET,HEAD(멱등이고 안전하다, PUT,DELETE(멱등이지만 안전하지도 않다) POST(멱등이지도 안전하지도 않다)
*CRUD : Create작성(POST/PUT), Read읽기(GET), Update갱신(PUT), Delete삭제(DELETE)라는 데이터 조작의 기본이 되는 4가지 처리
스테이터스 코드 - 요청의 결과로 얻어지는 응답메시지에서 그 의미를 전달한다.
클라이언트는 숫자를 보고 서버가 어떤 응답을 보낸 것인지 이해할 수 있으며, 클라이언트 측에서 어떻게 처리해야 할지 대략 알수 있게 됩니다. (1xx : 처리중 2xx : 성공 3xx : 리다이렉트 4xx : 클라이언트 에러 5xx : 서버 에러)
자주 사용되는 스테이터스 코드 9개(200 OK- 요청성공 201 Created-리소스 작성 성공 301 Moved Permanently-리소스의 항구적인 이동 303 See Other-다른 URI의 참조 400 Bad Request-요청 오류 401 Unauthorized-접근권한 없음, 인증실패 404 Not Found-리소스 없음 500 Internal Server Error-서버 내부 에러 503 Service Unavailable-서비스 정지
HTTP헤더 - 메시지의 바디에 대한 부가적인 정보, 즉 메타 데이터를 표현합니다. 클라이언트와 서버는 헤더를 보고 메시지에 대한 동작을 결정합니다. 미디어 타입과 언어 태그 등 프레임워크가 아닌 구현하는 사람이 구체적으로 설정해야만 하는 헤더도 많이 있습니다.
- 날짜 시간을 가지는 헤더, MIME 미디어 타입
1-3. HTML
<id>tag:example.com,2010-08-24:entry:1234</id><title>테스트 일기</title><updated>2010-08-24T13:11:54Z</updated><link href="http://example.com/1234" /><content>테스트입니다.</content>
"name":{
"first":"John","last":"Doe"
},"blog":"http://blog.example.com","age":34,"interests": ["Web","XML","REST"]
2. REST는 웹의 아키텍처 스타일
REST는 네트워크 시스템의 아키텍처 스타일입니다. 네트워크 시스템의 아키텍처 스타일로서 가장 유명한 것은 클라이언트/서버입니다. 그리고 웹은 클라이언트/서버이기도 합니다. 순수한 클라이언트/서버 아키텍처 스타일에 몇 가지 제약을 더해가면, REST라는 아키텍처 스타일이 됩니다.
일반적으로 소프트웨어 아키텍처는 복수의 컴포넌트를 조합해 구현하는데, 각각의 컴포넌트가 따로따로 움직여서는 동작하지 않습니다. 그래서 각 컴포넌트에 제약을 부과해 갑니다. 그 결과 전체적으로 각 컴포넌트가 협력하면서 동작하게 되는 것이지요.
* 아키텍처 스타일 : '(매크로)아키텍처 패턴'이라고도 하며, 복수의 아키텍처의 공통된 성질, 양식, 규정 혹은 독특한 방식을 가리키는 말입니다.
아키텍처 스타일에는 MVC와 파이프 앤 필터, 이벤트 시스템 등이 있습니다.
실제 시스템은 구체적인 아키텍처를 가지고 있습니다. 그 아키텍처를 설계할 때, 그냥 마구잡이로 만들어 가는 것이 아니라 아키텍처 설계 지침, 규정, 방식 즉, 아키텍처 스타일을 적용합니다. 시스템의 아키텍처를 결정할 때 나침반이 되는 것이 아키텍처 스타일입니다.
* 아키텍처 : 구현에서 추상도를 한 단계 올린 것
* 아키텍처 스타일 : 아키텍처에서 추상도를 한 단계 더 올린 것
* 제약 : 조건을 붙여 내용을 제한함. 또는 그 조건.
2-1. REST의 등장 배경
폭발적으로 보급된 웹으로 인해 각 회사의 서버, 클라이언트 사이에서 이용되어야 하고 상호 운용성이 요구되었기 때문에
웹을 구성하는 기술, 특히 HTTP와 URI와 HTML에 대한 표준화가 요구되었습니다.
웹 이전의 인터넷 표준은 IETF의 RFC로 정해져 왔지만 웹이 너무나 급속하게 보급되어 버렸기 떄문에 스펙 책정이 따라가지 못하고,
각 기업의 구현은 제각각이라 상호운용성이 결여되는 상태가 발생되어 버렸습니다.
필딩은 HTTP의 스펙을 책정하는 시기에 자신의 연구과제로 웹이 왜 이렇게 성공했는지, 왜 이 정도의 대규모 시스템이 성립된 것인지에 대해 소프트웨어 아키텍처의 관점에서 분석하고, 하나의 아키텍처 스타일로 정리했습니다.
그는 이 아키텍처 스타일을 REST(Representational State Transfer)라 이름붙였습니다.
**리소스 상태의 표현???????
* SOAP : HTTP를 애플리케이션 프로토콜이 아닌 트랜스포트 프로토콜로 다루고, HTTP 상에서 독자적으로 메시지를 전송합니다.
SOAP는 메시지 전송 방법만을 규정한 스펙이기 때문에 실제로 시스템을 구축할 때는 SOAP 상에 서비스 별로 프로토콜을 정의하지 않으면 안 됩니다.
각 벤더마다 제각기 정의하게 되면 이전 분산 시스템의 전철을 밟는 셈이었기 때문에 주변 스펙들이 제안되었습니다. 하지만 여러 비슷한 스펙들이 여러 개가 난립했기 때문에, 결국 이전과 마찬가지의 표준화 경쟁을 불러일으켰습니다.
SOAP와 WS-*의 패인
첫째는 기술적인 이유. RPC/분산 오브젝트가 가지고 있던 기술적인 문제점을 그대로 가지고 있는데다 스펙들마저 복잡해져 버렸습니다.
예를 들어, 벤더 간 인터페이스 호환성의 결여, 복잡한 프로토콜 스택, 네트워크를 통한 인터페이스 호출에 의한 오버헤드 등입니다.
둘째는 정치적인 이유. 표준화 작업은 각 벤더가 드래프트를 가지고 오면, 그 차이를 조정하는 식으로 이루어졌습니다. 하지만 많은 벤더들이 SOAP 자체도 표준으로 확정되기도 전에 구현을 추진했기 때문에 동일한 SOAP와 WS-*라도 해석에 차이가 생겼고 호환성이 결여되었습니다.
2-2. REST는 복수의 아키텍처 스타일을 조합하여 구축한 복합 아키텍처 스타일
클라이언트/서버- 유저 인터페이스와 처리를 분리한다.
클라이언트/서버의 이점은 단일 컴퓨터 상에서 모든 것을 처리하는 것이 아니라, 클라이언트와 서버로 분리해서 처리할 수 있다는 점입니다.
유저 인터페이스는 클라이언트에서 담당하기 때문에 서버는 데이터 스토리지로서의 기능만을 제공하면 됩니다.
스테이트리스 서버- 서버 측에서 애플리케이션의 상태를 가지지 않는다, 클라이언트는 요청마다 모든 정보를 송신한다.
*스테이트리스 : 클라이언트의 애플리케이션 상태를 서버에서 관리하지 않는다
서버가 애플리케이션의 상태를 가지지 않게 되면, 그만큼 서버 측의 구현을 간략화 할 수 있다는 장점이 있습니다. 간략하게 구현된 서버는 클라이언트로부터의 요청에 응답한 뒤 바로 서버의 자원을 해제할 수 있습니다.
- 스테이트리스가 아닌 스테이트풀한 서비스 :: Cookie를 사용한 사용자 세션 관리
* 캐시- 클라이언트와 서버의 통신횟수와 양을 감소시킨다, 캐시에 필요한 정보를 클라이언트에게 전달, 같은 요청의 결과를 재이용 : 리소스의 신선도에 기초해, 한번 가져온 리소스를 클라이언트 쪽에서 돌려쓰는 방식
캐시의 장점은 서버와 클라이언트 사이의 통신량을 줄여 네트워크 대역의 이용과 처리시간을 축소하고, 더욱 효율적으로 처리할 수 있다는 것입니다. 단, 오래된 캐시를
이용해 정보의 신뢰성이 떨어질 가능성도 있습니다.
* 유니폼 인터페이스- 인터페이스를 고정한다, 모든 서버가 같은 인터페이스를 채용한다. URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일
예를 들어, HTTP 1.1에서는 GET과 POST 등 8개의 메서드만 정의되어 있고 확장할 수 없는 제약이 있다. 아주 엄격한 제약으로 느껴지지만, 인터페이스의 유연성에 제약을 가함으로써 전체적인 아키텍처가 간결해집니다. 또한 인터페이스를 통일함으로써 클라이언트와 서버 구현의 중립성이 향상됩니다.
* 계층화 시스템- 시스템을 계층별로 분리한다, 인터페이스가 다른 레거시 시스템에 접속할 수 있게 한다, 시스템을 복수의 계층으로 분할한다 : 시스템 전체를 계층화하기 쉽다. 예를 들면, 웹 서비스에서는 서버와 클라이언트간의 로드 밸런서를 설치해 부하를 분산시키거나, 프록시를 설치해 액세스를 제어합니다. 클라이언트 측에서 보면, 서버나 프록시 모두 동일한 인터페이스로 접속할 수 있기 떄문에 접속할 곳이 서버에서 프록시로 바뀐 것을 신경 쓸 필요가 없습니다. 이것은 서버와 프록시 등 각 컴포넌트 간의 인터페이스를 HTTP로 통일하고 있기에 실현될 수 있었습니다.
시스템을 몇 개의 계층으로 분리하는 아키텍처 스타일을 계층화 시스템이라고 합니다.
* 코드 온 디맨드- 프로그램을 클라이언트에 다운로드하여 실행한다, 인터페이스가 다른 레거시 시스템에 접속할 수 있게 한다 , 서버가 제공하는 코드를 클라이언트에서 실행 : 프로그램 코드를 서버에서 다운받아 클라이언트에서 실행하는 아키텍처 스타일입니다. 예를 들어, JavaScript나 Flash,Java 애플릿 등이 여기에 해당합니다. 장점은 클라이언트를 차후에 확장할 수 있다는 것입니다. 클라이언트 프로그램에 미리 준비해 둔 기능뿐만 아니라, 새로운 기능을 계속 추가할 수 있습니다.
*P2P : 대표적인 REST 이외의 아키텍처 스타일 ; 서버를 거치지 않고, 피어(분산 네트워크상의 각 노드(컴퓨터))사이에서의 통신
* 하이퍼미디어 : 텍스트와 이미지, 음성, 영상 등 다양한 미디어를 하이퍼링크로 연결해 구성한 시스템. 웹은 하이퍼미디어의 한 예
* 하이퍼링크 : 하이퍼미디어에 있어서 정보끼리 연결하는 구조
* 중앙 집중형 시스템 : 한 대의 중앙 컴퓨터가 모든 것을 처리하는 형식
* 분산 시스템 : 복수의 컴퓨터를 조합해 처리를 분산시키는 형식.
3-1. 다양한 하이퍼미디어 포맷
* microformats : HTML의 구조는 그대로 유지한 채, HTML에 다양한 의미를 가지게 할 수 있는 기술
* RSS : 웹페이지의 새로운 정보를 서버에서 발송하고, 전용 프로그램으로 그것을 체크하기 위한 용도
* Atom : RSS가 복수의 버전이 난립해 혼란스러웠던 탓에 최종적으로는 IETF에서 Atom이 표준화되었습니다.
* JSON : RSS와 Atom이 XML을 베이스로 한 구조화 문서용 마크업 언어이기 때문에 단순한 데이터 포맷이 필요해서 제안된 데이터 포맷
3-2. REST와 하이퍼미디어& 분산시스템
REST와 하이퍼미디어 : 하이퍼미디어를 이용한 애플리케이션에는 리소스의 URI만 알면 어떤 애플리케이션이 제공하고 있는 리소스를 다른 애플리케이션에서도 간단히 재사용할 수 있다는 장점이 있다. 리소스를 링크로 연결하여 하나의 애플리케이션을 구성한다는 개념은 REST의 근간을 이루는 사상입니다. 이 개념은 '접속성'라고도 불립니다.
REST와 분산 시스템 : 분산 오브젝트에서는 함수나 메서드단위로 서버 쪽의 처리를 호출합니다. 네트워크를 통한 함수 호출을 하면 오버헤드가 심하기 때문에 시스템 전체 성능의 저하를 가져옵니다. 그에 비해 REST에 기초한 웹 서비스는 링크를 이용하여 애플리케이션을 실현합니다. 분산시스템에서는 기능을 추가해 버전 업 할 때마다 메서드가 늘어나거나 메서드의 인수와 반환값이 바뀌고, REST는 인터페이스가 고정되어 있기 때문에 호환성 문제는 발생하지 않는다. 리소스에 적용할 수 있는 HTTP메서드는 항상 고정되어 있어 HTTP를 구현한 클라이언트라면 동일하게 접속할 수 있습니다.
|
Chapter 06_ HTTP의 기본
Chapter 10_ HTML
Chapter 15_ 읽기 전용 웹 서비스의 설계
'Book' 카테고리의 다른 글
2014/03/02 북쇼핑리스트 - 알라딘 중고서점 (0) | 2014.03.02 |
---|---|
실용주의 프로그래머를 위한 단위테스트 (0) | 2011.08.02 |
프로그래머의 길, 멘토에게 묻다 (2) | 2011.01.16 |
행복한 프로그래밍 _ 임백준 (0) | 2010.06.17 |
2010 년도 읽은 책 (1) | 2010.06.03 |
WRITTEN BY