<뽀모도로>

 

1. 어떤 일을 할지 정한다.

2. 뽀모 도로(타이머)를 25분에 맞춘다.

3. 타이머가 끝날 때까지 그 일을 한다.

4. 짧게 쉰다(보통 5분)

5. 매 4회의 ‘뽀모도로마다 길게 쉰다(15~30분).

 

<레거시 시스템>

 

실행 관례의 도입 자체를 관리자나 팀 구성원에게 설득하지 말고 현재 일하는 방식과 비교해 가져올 이익에 집중해야 한다.

빠른 피드백 루프, 요구사항과 비용에 대한 더 나은 이해, 지식 공유, 줄어드는 버그, 전체적으로 자동화되고 릴리즈가 빨라지는 일들이 기술적 실행 관례를 도입함으로써 얻을 수 있는 가치들이다.

 

테스크 코드를 머저 개발하기!! 

 

 

<채용>

 

소프트웨어 장인이 직장을 찾을 때는 특정한 프로젝트나 펜시한 기술, 괜찮은 급여만을 쫓지는 않는다. 소프트웨어 장인은 생산적인 파트너십과 아침에 일어날 때마다 일하러 가는 것이 행복한 직장을 찾는다.

 

<사기>

개발자들의 낮은 사기는 소프트웨어 프로젝트 실패의 주된 이유 중 하나이다.

 

소프트웨어 장인을 팀에 들이는 것은 기술적인 문제 해결에 도움이 될 뿐만 아니라 열정을 불어 넣고

혁신을 일으키는 데 지지자이자 동맹이 되어 준다는 것이다.

 

배움의 문화 만들기

 

--- 아무도 참여하려 하지 않는다면,

모범을 보여라 (TDD)

관심을 보이는 사람들에게 집중하라

강제하지 마라

모두를 변화시켜 들지 말라

모임에 대한 약속을 제때하라

허락을 구하지 마라

투덜대지 마라

리듬을 만들라

 

 

 

 

 

 

 

Posted by '김용환'
,


이 블로그는 내가 쓴 쓴글에 대한 후속이다. 

http://knight76.tistory.com/entry/Google%EC%9D%98-TCP-Fast-Open-paper 
 

 

http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/ko//pubs/archive/37517.pdf

 

예전에 RTOS의 통신 프로토콜, 방송용 전송 프로토콜(mpeg2, dab 프로토콜,)을 일부 구현하면서 transport layer에 대해서 관심이 많다. 이번에 구글에서 나온 TCP Fast Open을 보고, “TCP / IP Illustrated, Volume 1”을 다시 보았다. 그리고, “Blind TCP/IP hijacking is stall alive(TCP 하이재킹)” 블로그도 읽었다.

 

최근 웹 페이지 분석 자료.

(참조 : http://code.google.com/intl/ko-KR/speed/articles/web-metrics.html)

 

이 paper는 TCP 연결 기본과 관찰력으로 나왔다고 볼 수 있다.  파일을 읽고 쓰는 것보다 파일을 열고 닫는 것이 리소스가 많이 드는 것처럼 네트웍 소켓을 열고 닫는 부분에 대해서 고민하는 것과 비슷하다.  이 paper는 TCP 연결의 여는 부분에 대해서 고민했다.

크롬 브라우져와 구글 서버간의 통신 상태를 2011년에 28일 동안 분석해보았다. 33%정도가 Http persistent 연결이었다. 최신 브라우져는 서버당 연결 개수를 높여 빠르게 로딩하려고 하고 있다.
(TCP 3-way handshake 방식은 connection마다 이루어지기 때문에 서버와 클라이언트에 부하를 이룬다. 그러나 DDOS 나 트래픽이 너무 몰릴 때에는 안좋을 수 있어서 Keep Alive를 하지 않는 경우가 많다. Apache Http 서버의 기본 설정이 keep alive가 아닌 것으로 바뀐 것은 의미가 있다. 그렇지만 역시 keep alive 상태로 해서 http permanent connection인 경우에는 확실히 부하를 적게 할 뿐 아니라 브라우져의 병렬 처리 소켓 개수로 인해서 속도를 높일 수 있어서 점차 사용이 확대되고 있다. )

새로운 TCP 연결에 대한 요청은 Cold Request, 이미 연결된 TCP 연결에 대한 요청을 Warn request라고 정의했다. 새로운 TCP를 연결(Cold request) 하는데 Cost가 많이 들었다. Cold request는 8~28%의 Cost가 더 든다.

 

Cold request가 50% 정도 느리다.

 

TCP 3 way handshaking은 delay와 중복 syn 패킷을 처리하기 위해서 만들어졌다. Tcp Fast Open은  이 철학을 잘 이해하고 이 부분에 좀 더 보강을 했다. TCP 패킷은 security “Cookies” 값을 추가했다. 기존에 hijacking당할 수 있는 TCP에 보안적인 부분을 염두해서 보강했다. 클라이언트는 cookie 요청을 하지만, 실제로 cookie generation은 서버에서 하게 한다. 클라이언트는 cookie를 캐쉬해두고 사용한다. 서버는 이 쿠키를 validate한다.

TFO의 중요한 포인트는 client와 server간의 3 way handshaking 을 하면서 데이터가 전달되게 하는 것이다.  이렇게 함으로서 보다 많은 패킷을 전달할 수 있다.

 

 

그리고, TCP의 congestion control은 따로 수정할 필요가 없으며 sendto, sendmsg 와 같은 시스템콜을 수정하여 편하게 쓸 수 있게 했다.

 

좋아진 결과는 4~10% 정도였다. RTT가 늦어야 효과가 높았다. 떄로는 41%까지 좋아졌다.

현재는 IETF에 제안서(http://tools.ietf.org/html/draft-cheng-tcpm-fastopen-00)를 넣은 상태이다.

 
2012년 1월 까지 리눅스 커널에 패치되지는 않은 상태이다.
 

마치며..

response time이 긴 웹 서버의 경우의 서버, 국내용 서버라면 쓰기 어려운 부분이 있지만 세계를 배경으로 하는 웹 서버에 대해서는 쓸만한 대안이 될 수 있겠다는 생각이 들었다. 현재 필리핀이나 중국에서 한국 웹 서버를 접근하는데 시간이 오래 소요된다고 한다. TFO가 리눅스 커널에 적용된다고 여러 어플에 적용된다면 좋을 수도 있겠다는 생각이 든다.

Posted by '김용환'
,

 

http://www.usenix.org/events/hotos03/tech/full_papers/vonbehren/vonbehren.pdf

이 paper를 읽으니, 재미가 있었다. 기억에 남는 것은 thread 방식의 문제를 compiler가 고치면 된다고 했다. dynamic stack growth, live state management, synchronization 등의 문제에 대해서 compiler의 도움을 얻는다면 성능이 잘 나올 수 것 같다고 작성했다.

------

내가 다니고 있는 회사의 웹 서버에서 사용하는 수많은 서버들의  web 서버들은 여전히 apache http가 가장 편하고 안정적이기 때문에 이를 사용하고 있다. 또한 nginx를 일부 사용하고 있다. was인 tomcat과 연동해서 사용할 때는 대부분 apache http 서버를 사용하고 있고, 주로 static 서버로 사용할 때는 nginx 를 사용하고 있다. 물론 nginx는 tomcat과 연동해서 쓰고 있다.

event-driven이든, fork/thread 방식이든 상관없이 이미 안전하고 운영하기 편리한 것으로 검증 받는 것으로 가는 것은 사람의 기본 심리인 것 같다.

2003년도에 thread나 event 방식의 개발 중에 어느 것이 더 좋은 것인지 학자들끼리 토론하는 것이 있었던 것 같다. 나는 그 때 머했나? 음. 당시에 다니던 전직 회사에서는 thread에 대한 부담감이 많이 있었다. 미들웨어 개발 당시에 thread의 남발로 인한 부작용이 심각했다. 너무 많은 thread들이 돌아다니면서 conditional 코드들이 생기고 코드는 점점 복잡해져 갔고, 무거워져 갔다. 성능이 느려지기 시작했다. 또한 코드 또한 복잡해졌다. 당시에 쓰레드를 남발하고 synchronized 블럭을 잘 써서 개발자라면 능력 있는 개발자로 여기는 행태도 있었다.

운영체제에서 쓰는 one thread에서 동작하는 polling 방식의 event 방식으로 구현하는 것은 어떨까 고민하고 구현하던 중이던 시점인 것 같다. event driven 구현 방식도 api를 제공이나 내부 구현의 복잡성, 속도에 대해서 한계가 존재했다.

구현 후 느낀 점은.. 어떻게 구현해도 만족시키지 못했던 것 같다. 각각 장/단점이 있었던 것 같다. 그 틀에서 어떻게 좀더 성능을 높인다는 것은 뼈를 깎는 고통인 것으로 기억한다. 나의 무식과 무지가 많이 드러나서 힘들었다.  웹 환경에서는 장비를 늘리고, scalabity를 지원하는 오픈소스를 사용하는 지금의 모습과는 많이 다른 것 같다.

Posted by '김용환'
,



JSR292를 보다가 invokedynmaic jvm instruction에 대한 자세한 글을 보게 되었다. 굿..

The Java Virtual Machine (JVM) has been widely adopted in part
because of its classfile format, which is portable, compact, modular,
verifiable, and reasonably easy to work with. However, it was
designed for just one language—Java—and so when it is used to
express programs in other source languages, there are often “pain
points” which retard both development and execution. The most
salient pain points show up at a familiar place, the method call
site.
To generalize method calls on the JVM, the JSR 292 Expert
Group has designed a new invokedynamic instruction that provides
user-defined call site semantics. In the chosen design,
invokedynamic serves as a hinge-point between two coexisting
kinds of intermediate language: bytecode containing dynamic call
sites, and combinator graphs specifying call targets. A dynamic
compiler can traverse both representations simultaneously, producing
optimized machine code which is the seamless union of
both kinds of input. As a final twist, the user-defined linkage of a
call site may change, allowing the code to adapt as the application
evolves over time. The result is a system balancing the conciseness
of bytecode with the dynamic flexibility of function pointers.
Posted by '김용환'
,

http://www.infoq.com/articles/twitter-java-use;jsessionid=BCBAEA4F386A677C22155A1AC63BAEE1

Twitter Shifting More Code to JVM, Citing Performance and Encapsulation As Primary Drivers

위의 infoQ 글을 약간 요약해서 정리합니다. 일목정연한 느낌의 글은 아니니. 그냥 편하게 보시면 좋을 것 같습니다.

<주 내용>
트위터는 Ruby on Rails와 Mysql로 시작하였습니다. 비용과 성능, 확장성, 아직 성숙하지 못한 library의 한계로 JVM 기반으로 코드를 바꾸고 있습니다.
InfoQ에서는 트위터 엔지니어인 Evan Weaver에게 이런 변화에 대한 배경을 더 알아보기 위해서인터뷰를 하였습니다. 

<트위터 아키텍처 Overview>
트위터는 2010년 봄에 검색 스토리지를 Mysql에서 Lucene의 리얼 타임 버전으로 변경했습니다. 그리고, 최근에는 검색 쪽 Front end를 Ruby on Rails 에서 Blender라고 하는 자바 서버로 바뀌었습니다. 이를 통해서 3배 정도로 성능을 좋게 할 수 있었습니다.
http://engineering.twitter.com/2011/04/twitter-search-is-now-3x-faster_1656.html

저희가 Cassandra를 사용하는데, Cassandra는 훨씬 flexible한 데이터인 신상품, 시간정보 데이터, 아주 빠른 속도로 저장해야 하는것들, Hadoop을 이용하여 나오는 결과물에 대해서 처리하는데 아주 유용한 것 같습니다.
한편, Front-End와 Back-End간의 통신은 Facebook에서 사용하는 Thrift를 사용합니다.
 
트위터 내부에서는 Finagle(http://twitter.github.com/finagle/)이라는 Java, Scala로 된 Async RPC 클라/서버를 투자해서 만들기도 했습니다. 

<언어>
트위터 서비스를 처음 할 때, Javascript, Ruby, Scala, Java언어를 사용해서 개발했습니다. Ruby 기반 개발자는 Scala를 선호했으며, C/C++ 기반 개발자들은 Java를 선호했습니다. C를 다 지원하는 언어라서 C언어로 만든 것들을 적용하기도 했습니다.

검색팀에서는 Java 기반의 Lucene을 많이 작업했기 때문에 Scala 언어보다는 Java가 훨씬 편했습니다. 트위터의 서비스가 점점 복잡해지면서 Backend로는  JVM과 Front-end에 back-end 코드가 들어가기 시작했습니다. 
또한 Javascript가 무거워지면서 Ruby 컴포넌트는 점차 사라지기 시작했습니다. 이로 인해서 성능과 encapsulation이 매우 중요한 요소가 되었습니다. 

Ruby runtime은 JVM보다 느렸습니다. 성능 최적화 작업을 하기 위해서 GC 쪽을 힘들게 작업 했어야 했습니다. 그리고, Ruby 의 LAMP 모델과 수직 encapsultation 모델은 트위터와 같은 대용량서비스에는 맞지 않았습다. 새로운 서비스를 만들 때는 좀 더 성능과 encapsulation과 서비스 중심 프로젝트를 빨리 하기 위해서는 Rails 대신 Java 로 가야 했습니다. Front-end쪽의 렌더링은 Rails의 템플릿 모델 대신 브라우져 기반의 javascript로 사용했습니다. 
결국 성능과 개발 생산성을 위해서는 Backend/Frontend에서 Ruby/Rails를 빼고 java 기반으로 가게 되었습니다.

<검색쪽 이야기>
검색쪽을 Ruby에서 java로 바꾸니 2가지가 좋아졌습니다. 첫번째는 Lucene에서 만든 real time reverse index가 Mysql을 대체할 수 있었습니다. 저희는 이 Lucene을 Earlybird라 불렀는데, Earlybird는 메모리 효율을 2배로 높일 수 있었고, 검색 필터링에 대한 연관 확장성을 높였습니다. 마지막으로는 검색 서비스에 대한 요구들을 빨리 처리할 수 있었습니다. 실제 성능결과는 mysql 은 20TPS/200QPS에서 Earlybird는 1000TPS/12000QPS로 높였습니다. 
Blender 는 Thrift 이고, Netty 기반의 HTTP 서비스입니다. Netty는 Fully Async를 지원하며.. 하여튼 완전 좋습니다. Blender를 적용하면서 800ms였던 latency를 250m로 줄였으며 cpu도 반으로 줄어들었습니다.

JVM 기반 언어의 장점이 성능과 확장성이라면, 트위터는 적어도 backend 서비스에서만큼은 static typing 이라는 장점이 있겠다고 말씀드릴 수 있습니다. (static typing은 프로그래밍 언어개념이며, 컴파일시 문제점을 발견 가능하고, 실행이 빠르며 가독성이 좋아지는 특징이 있습니다. Ruby 언어가 Dynamic한 언어의 특성을 가지다 보니 개런티에 대한 모호함이 있을 수 있었던 단점을 java에서 최대한 명확하게 해주는 편의성을 주요하게 봤던 것으로 생각됩니다. 그래서 Scala 언어가 static 하기 때문에 이런 부분에 대해서 얘기가 나왔습니다.)

한편, 여전히 Ruby가 어떤 서비스에서는 최고의 선택이 됩니다. 트위터는 여전히 GC로직을 수정한 Ruby MRI(CRuby) 1.8 을 사용하고 있으며, Ruby 1.9 에 기어하려고 하고 있습니다. 
JVM 언어인 JRuby로 옮길라고 하는데, 성능이슈가 있습니다. CRuby의 memcached의 경우는 엄청 빠른데, JRuby 클라언트로는 성능이 안나옵니다. JRuby 자체를 2배로 빠르게 한다 하더라도 느린 memcached client가 성능의 이점을 다 날릴 수 있을 것입니다. JRuby 잘못은 안라고 생각은 듭니다. 아직 immature한 환경이라고 생각이 듭니다. CRuby 도 마찬가지이지요. 여전히 우리는 얻을 수 있 이익이 많기 때문에 계속 JRuby에 투자를 할 것입니다. 
 
한편, 이익이 있다면, JRuby Twitter는 Thrift 기반으로 재작성하여 평가할 수 있을 것입니다. 

(블로그 주인이 추가합니다.)
LAPM는  (Linux-Apache-mysql-PHP/Perl/Python)의 약자이고,
APM은 (Apache-mysql-PHP/Perl/Python)의 약자입니다. 

 Java7에서 invokeDynamic이 추가되었습니다. JRuby 성능은 추후 달라질 것으로 예상됩니다.
Posted by '김용환'
,

Virtual Machine Showdown: Stack Versus Registers
http://www.usenix.org/events/vee05/full_papers/p153-yunhe.pdf

오래만에 잼나게 본 논문이다.
stack based vm이냐, register based vm이 어떤가 해서 봤는데.. 역쉬

sun(oracle) jvm의 경우는 어떤 환경에서도 돌릴 수 있도록 디자인 되어 있기 때문에, stack based로 가게 된다. 대신 성능이 조금 떨어질 수 있겠다.
그러나 android jvm의 경우는 특정 환경에 돌려야 하기 때문에 빠른 성능이 중요하다. 따라서, 구글은 register based jvm으로 선택했다.

예전에 임베디드 분야에 일 할때, pjava, cldc, cvm 기반 위에서 동작했던 부분을 생각했을 때, 이 부분을 고려했었으면 더 좋은 성과가 나지 않았을 까 생각도 든다.
구글은 참 머리가 좋았다. 바로 과거의 실패를 생각하고 정말 중요한 부분이 무엇인지 파악하고 그 부분에 대해서 고민을 했다라는 생각이 들었다.


머 하여튼..
논문으로 돌아가서. stack based bytecode들을 register based bytecode로 바꿨더니 45%의 instuction 이 줄어들고, size도 25%나 줄어들었다고 한다. 사실 생각해보면, operand가 들어가고, 약간 고급스러워진 bytecode덕택이라고 생각한다. 펜티움 4에서 실행속도도 32.3%도로 줄어들었다고 한다.
수치는 약간 테스트환경이라 다를 수 있지만, 이처럼 굳이 특정 target 플랫폼에서 동작한다고 가정한다면, register 기반이 훨씬 좋을 것 같다.


The result is that we eliminate an average
of more than 47% of executed VM instructions, with the
register machine bytecode size only 25% larger than that of
the corresponding stack bytecode. Secondly we present an
implementation of a register machine in a fully standardcompliant
implementation of the Java VM. We find that,
on the Pentium 4, the register architecture requires an average
of 32.3% less time to execute standard benchmarks if
dispatch is performed using a C switch statement. Even if
more efficient threaded dispatch is available (which requires
labels as first class values), the reduction in running time is
still approximately 26.5% for the register architecture.
Posted by '김용환'
,

프로그램은 왜 실패하는가?의 저자 Zeller교수의 논문

"Isolating CauseEffect Chains from Computer Programs" 이다.

 

http://www.st.cs.uni-sb.de/papers/fse2002/p201-zeller.pdf

 

책 한권의 내용이 이 논문에 잘 담겨져 있다.

 

디버깅의 방법, 그리고 어떻게 하면 디버깅이 가능한지 잘 정리되어 있다.

 

Idea -> 형상화

 

 

 

Posted by '김용환'
,
www.cs.umass.edu/~emery/pubs/04-15.pdf
 
(이 논문을 완벽히 이해하지도 못했지만, 어느 정도 이해한 바도 있고, 앞으로 계속 공부할 수 부분이 있기에 계속 시도할 것이다. 어려운 논문이다..)

가비지 콜렉션은 성능 문제가 가장 중요하다. c나 C++처럼 명시적인 힙 메모리 해제를 지원하지 않기 때문에, 어느 정도 시간이 되면, 자동으로 쓰이지 않은 힙 메모리에 대해서 compaction과 deallocation을 실시한다.
가비지 콜렉션은 mark -sweep이라는 방식, marking (sweep) * compaction, memory constrained copying(mc2) 이렇게 세개로 나누어진다.

또한 가비지 콜렉션 알고리즘에 따라 Mark-Sweep, Mark-Compaction, Copying, Generational collection 이렇게 4개로 카테고리로 나눌 수 있다. (nursey = young gen)

Mark-Copy 방법은 임베디드에서는 퍼포먼스가 나오지 않는다. copying 단계에서 메모리를 직접 map, unmap하는 부분에서 virtual memory를 써야 하는 부분, 콜렉터가 항상 old gen에서 복사를 함으로서, 효울성이 떨어진다는 점, 가비지 콜렉터시 pause 타임이 길다라는 단덤이 있다.

이런 단점을 최대한 줄인 MC2는 dynamic memory 정책과 table형태의 map, unmap 형태의 구조, indirect  addressing memory table을 가짐으로서, 최대한 장점을 가지려고 하고 있다. 이런 작업을 marking때 함으로서, 실제 map, unmap할 때의 시간적 소요를 최대한 줄일 수 있고, indirect이므로, 효율적으로 copy하는 복잡성을 제거할 수 있다.

Increment makring이라는 방법을 통해서, full 콜렉션시 pause 시간을 최대한 줄일 수 있다. 이는 마킹하는 작업시, young gen에서 interleaving하는 방법을 통해서, 마킹시시 큐를 가지고 작업하고, 번호를 부여하는 remembered set이라는 데이터 자료형을 가지고 작업하게 된다. 순차적으로 번호를 부여하고, 콜렉션 할 때마다 오랫동안 살아남았는지 여부를 판단할 수 있는 근거가 됨으로서, 추후 old gen으로 promotion할 때 사용할 수 있도록 되어 있다. 이 때 사용되는 메모리의 단위는 window라고 하는 메모리 단위이다..

copy과정에서는 Increment copying이라는 방법을 사용한다. 이 부분에서 좀 복잡한 개념이 나오는데, write barrier라는 것이다. 이 부분은 명확하게 들어오지 않아서, 다른 논문을 읽고, 다시 정리하면서 공부하는 게 좋을 거 같아서 일단 패쓰한다.

실제 이를 RVM, linux로 구현을 해서, GC 알고리즘을 가지고, 얼마나 performance가 좋은 지를 확인하는 결과를 보여주고 있다. 전체적으로 MC2가 효율이 좋은 결과를 보이고 있다.
PC나 서버에서는 full 콜렉션시 긴 pause타임이 별 의미가 없다. 하지만, 임베디드 시스템에서는 얼마나 효율적으로 메모르를 잘 사용하고, pause 타임이 최소화해야 하는 알고리즘이 사용될 수 있어야 한다. 바로 MC2는 이에 대해 잘 언급이 되어 있다. 짧은 pause 타임과 좋은 성능을 제공하고, 실시간적인 요구사항이 필요한 임베디드 단말기에서 동작할 수 있는 형태의 알고리즘이 결과를 내세웠다.

실제로 MC2가 가장 좋은 알고리즘이라고 하지만, 구현 복잡성이 있어서, 대부분 generation gc 알고리즘을 사용한다고 한다.

GC 알고리즘 논문을 처음으로 본 게 가장 어려운 논문이라 나에게 조금 벅찬 듯 하지만, 계속 공부하기엔 좋은 레퍼런스를 제공한 것 같다. 찾아 볼 수 있는 레퍼런스를 통해서 계속 GC공부를 할 수 있도록 노력해야 겠다!!

Posted by '김용환'
,
CACM 2004.11에서

전자상거래 계획중 가장 중요한 부분은 고객을 최고의 우선순위(80%)로 둔다는 점이다.
디스플레이와 검색, 편한 UI가 고객에게 편리함을 제공할 터인데, visualization을 이용하면 놀라운 성과를 발휘할 수 있다. 2D또는 3D를 이용하여 ui를 살짝 바꿔주기만 해도 편리한 UI를 제공하여 고객에게 능동적인 검색이 가능할 수 있는 장점이 있다.

visiT, Firafa, Flamenco, Kartoo라는 싸이트에서 이미 이렇게 사용되고 있다.

실제 구글 맵의 경우는 BM을 잘 설정해 놓은 것 같다. 웹 기반의 검색을 지도에 잘 이용함으로서, 지금 여태까지 나온 서비스와는  차별화된 컨텐츠와 요깃거리를 제공함으로서 고객을 잡아놓는 형태를 추구하고 있다.

Visualization은 고객에게 가장 중요한 부분이다..
Posted by '김용환'
,
CACM 2005.2에서

OO 언어를 배울 때, 잘 못 배우고 있는 것이 있다.


즉, 자바 언어를 들어 보자.
대부분의 자바 언어 입문에서는 다음과 같은 코드로 되어 있다.


class HelloWorld {
   public static void main(String[] args) {
       System.out.println("Hello, World");
   }
}


위의 코드는 아래와 같은 코드가 바뀌는 것이 참 좋다.

class HelloWorld {
   public static void printHello() {
        System.outprintln("Hello World");
   }
}

class UseHelloWorld {
   public static void main(String[] args) {
      HelloWorld hw = new HelloWorld();
      hw.printHello();
   }
}

Objet-orient라는 개념이 어떤 뜻인지 잘 알려줘야할 입문서의 맨 앞에서는 그냥 출력에 대한 것만을 설명하고 있기 까닭에 OO에 대한 개념에 대한 설명을 잘 알 수가 없고, 다른 스트럭처 언어와 똑같은 형태라고 짐작하게 되는 안좋은 관습(?)이 있는 것 같다.

처음부터 객체 생성과 객체의 메소드를 호출하는 것을 이용하는 예제는 OO에 대한 마인드를 정립시켜 주며, 그 코드 하나로 계속적인 응용을 통해서 OO를 익히는 것이 중요하다.
너무 API, AWT의 위주의 입문서때문에 OO언어가 얼마나 많이 그 OO언의 철학적 의미를 상실되었는지는 정말 생각하고 싶지도 않다. 정말 후배들에게 알려줄 최고의 입문서가 나왔으면 하는 바램이다.. .

아니면, 내가 쓸까??
Posted by '김용환'
,