분류 전체보기 (328)
.NET (111)
S/W tip (35)
etc (63)
DB (34)
HOT item~! (48)
Disign pettens (4)
UX (6)
나의 S/W (2)
개발관련 이슈 (16)
Diary (1)
웹플러스 (1)
calendar
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
tags
archive
link
ColorSwitch 00 01 02
▣  S/W tip - 해당되는 글 35건

▣  프로그래머의 길 - S/W tip - 2010. 3. 31. 14:55


프로그래머의 길

머리말

본서는 필자가 대학 4년, 대학원 2년 그리고 C 언어와 4세대 언어를 갖춘 비주얼 툴을 사용한 6년간의 소프트웨어 개발에 걸쳐 듣고, 배우고, 경험한 바를 2년간의 사색을 토대로 작성된 내용입니다. 비록 적은 경험에 부족한 글이지만 필자의 사변적 이성(Speculative Reason)과 경험적 이성(Empirical Reason)이 독자 제현께 조금이나마 도움이 될까 하여 제가 그동안 정리했던 글을 모았습니다. 물론, 본 글이 있기까지 수 많은 선지식의 가르침과 선학과 후학들과의 교류가 있었음을 인정합니다. 본 글이 있기까지 필자에게 정신적 자양분을 제공한 많은 분들께 감사를 드립니다.
말씀드린 바와 같이, 본서는 필자가 조금씩 써두었던 글들을 모은 것입니다. 그러나, 필자가 작성해 둔 글들의 모임이 전혀 관련없는 글들로의 모임이 아니라 서로 모종의 연관을 맺고 있습니다. 따라서, 본서를 전체적으로 읽고 여러 번 읽다 보시면 각 장의 내용을 이해하는 것 뿐만아니라 각 장들과의 연관성까지 이해하실 수 있을 것입니다. 물론 제가 이전에 집필했던 "C 프로그래밍의 기초 및 학습론" 서적이나 출간 예정인 가제목 "수학에 기초한 공부론" 서적과 중복되는 부분이 있습니다. 그러나, 최대한 중복이 없도록 노력하였습니다. 그리고 본서는 "C 프로그래밍의 기초 및 학습론" 서적보다 더 개념적이고 사변적이며 철학적인 내용을 담고 있습니다. 따라서, 이해하기 어려운 내용이 다분히 많이 있을 것입니다. 그러나, 이러한 부류의 서적을 필요로 하는 개발자와 전산학자들이 존재한다는 생각으로 제 글을 모아 출간하게 되었습니다. 비록 내용이 모호하고 주관적이긴 해도, 나름대로 최대한 독자 제현님들께서 합리적이고 직관적으로 이해할 수 있도록 정리하였습니다. 또한, 본서에 수록된 글들은 원래 제가 작성해서 소프트웨어 개발 커뮤니티 게시판 등에 올렸던 글들이 많이 포함되어 있는데 이 글들을 약간만 고치고 글의 형태는 그대로 두었습니다. 따라서, 본서의 구성이 짜집기 형태로 비추어질 수 있는데 어떤 면에서 각 장마다 독특한 글의 형태를 유지시키고 독자들이 읽기에 편할 수 있다는 생각에서 원래의 글 형태를 그대로 유지시켰습니다. 그리고, 참고하기 편리하도록 각 장마다 그때 그때 해당하는 참고문헌들을 첨부하였습니다.
본서는 전산학을 공부하는 학생에서부터 개발자로 입문하고자 하는 분들 그리고 전산철학에 관심이 있는 분들을 위해 집필된 서적입니다. 또한, 인문학을 공부하시는 분들 중에서 소프트웨어 개발이나 프로그래머에 대한 철학적 이해를 얻고자 하시는 분들에게 다소 도움이 되도록 구성하였습니다. 그러나, 아무래도 본서의 내용이 필자가 실무에서 경험하고 전산 실무 경험자들의 이야기를 논구한 것이므로 전산학을 전혀 모르는 분들은 이해하기 어려울 것입니다. 그리고, 전산학을 대강 공부한 분들도 본서의 내용을 전체적으로 이해하는데는 다소 어려움이 있을 것입니다. 본서를 시간을 두고 천천히 읽으신 후, 실무 프로젝트를 수행하면서 그때 느끼는 독자 제현님들의 경험에 비추어 제 책의 내용을 반추해 보시면 도움이 될 것입니다. 본서는 필자가 실제 실무 프로젝트를 수행하면서 경험하는 바를 정리한 것이므로, 독자 제현님들께서 실제 소프트웨어 개발 프로젝트를 수행하는데 기초자료로 이용하시면 좋을 것입니다.
한편, 전산학자들이 개발자로서 좀더 발전된 방향으로 진화하기 위해서는 소프트웨어의 기술적인 내용뿐만아니라 소프트웨어 개발 과정에 대한 이해와 소프트웨어 개발을 위해 가져야 할 프로그래머의 자세 및 올바른 마인드(心法)을 증득해야 된다고 저는 생각합니다. 그리고 초보자나 입문자들에게도 그러한 마인드가 다분히 중시됩니다. 비록 필자의 천학비재로 내용이 알차지 못하고 빈약한 면이 많지만 본서가 개발자들에게 조금이나마 소프트웨어 공학에 대한 인간적이고 철학적인 인식을 마련해 준다면 정말 기쁘겠습니다.
또한 본서는 필자가 아는 한도에서의 프로그래머의 길을 말씀드린 것이며 필자의 글이 얼마나 올바르게 프로그래머가 걷는 길에 대해서 잘 설명하고 있는지는 필자도 확신할 수 없습니다. 다만, 필자가 선학과 후학들로부터 배우고, 듣고, 직접 경험한 바에 근거하여 보편타당하다고 생각되는 선상에서 글을 전개하였습니다. 또한 본서는 여러분에게 프로그래머의 길을 제시하는 것이라기 보다는 필자가 경험하고 이해하고 인식하는 바로서 프로그래머가 갖추어야 할 지식과 지혜를 말씀드린 것입니다. 따라서 본서에 부족한 점이 있을 수 있으므로 그 점에 대해서는 너그러운 양해를 구합니다.
본서의 구성은 다음과 같습니다. Chapter 1에서는 제가 생각하는 프로그래밍에 대한 사유를 정리하였습니다. Chapter 1은 프로그래머가 염두해 두어야 할 프로그래밍에 대한 사유를 담고 있습니다. 그리고 Chapter 2에서는 개발툴이나 언어를 사용하여 소프트웨어를 개발해야 할 때 도움이 될만한 사항을 조언의 형태를 빌어 설명합니다. Chapter 2의 내용을 프로그래머의 길을 걸어가는 분들게 조금이나마 도움이 되리라 생각합니다. 그리고 Chapter 3에서는 현재 인기있는 익스트림 프로그래밍과 애자일 방법론을 중심으로 소프트웨어 개발 프로젝트 수행에 관한 내용을 다룹니다. 프로젝트 수행론은 실무에서 프로젝트를 수행하면서 얻게 되는 느낌과 이해를 담고 있어 프로그래머의 길을 걷는 분들게 약간이나마 도움이 되리라 생각합니다. Chapter 4에서는 인기를 구가하고 있는 디자인패턴에 대한 필자의 생각과 견해를 다루었습니다. 그리고 Chapter 5부터 부록까지는 에세이 형태로 프로그래머가 알아두었으면 하는 내용을 다루고 있습니다. 본 장들은 다소 현학적인 내용이 많이 가미되어 있는데, 그것은 프로그래머가 단순히 코딩하는 기계가 아니라는 점을 강조하기 위해서입니다. 프로그래머는 생각하고 추론하고 직관력을 향상시킬 수 있으며 자신을 부단히 업그레이딩해 나가야한다고 필자는 생각합니다. 그렇기 위해서는 보다 넓고 심오한 시각을 갖는 것이 중요합니다. 이러한 시각을 얻을 수 있도록 나름대로 글을 정리한 것이 바로 Chapter 5에서 부록까지의 내용입니다. 예를 들어, 매트릭스 영화가 요즘 인기를 끌고 있고, 이 영화를 이해하려면 다분히 컴퓨터 과학에 대한 현학적 이해가 필요합니다. 이러한 현학적 이해에 부록의 내용이 다소 도움이 되리라 생각합니다. 본서의 부록에서 다루는 내용을 충분히 소화한다면 동양철학과 프로그래밍의 관계를 이해할 수 있을 것입니다. 물론, 부록의 내용은 단지 흥미위주의 소설이 아니라 무엇인가 프로그래머가 지향해야 할 프로그래밍의 세계관을 한 번 도시해 본 것이라 말씀드리고 싶습니다.
그리고, 본서는 단순한 특정 프로그래밍 언어와 개발툴에 대한 기술서적이 아니라는 것입니다. 그리고, Thinking In Java나 Thinking In C++와 같은 개념과 이론 그리고 기술이 접목된 서적도 아니라는 것입니다. 또한 Writing Solid Code나 Code Complete 그리고 The Pragmatic Programmer와 같은 기술과 철학을 종합시킨 서적들과도 다소 차이가 있습니다. 오히려 본서는 Kent Beck의 Extreme Programming Explained나 Jim Highsmith의 Agile Software Development Ecosystem과 비슷한 성격을 지닙니다. 그렇다고 본서가 이러한 방법론이나 프로그래머의 자세를 전문적으로 혹은 심도있게 다루는 책은 아닙니다. 본서는 개발자들과 프로그래머 입문자들을 위해 도움이 될만한 사항들을 필자의 경험과 선학과 후학의 이야기들 그리고 앞에서 언급한 서적들의 저자들이 갖고 있는 생각들을 종합하고 통합하려는 시도로 다분히 철학적인 접근 방법을 택했습니다. 그러나, 본서는 결코 철학서도 아닙니다. 오히려 프로그래머로서 가져야할 자세 및 심법(心法)의 중요성을 특정 프로그래밍 언어나 개발툴 그리고 특정 방법론에 국한하지 않고 언급하고 있습니다. 본서는 필자가 힘닿는 데로 개발자와 프로그래머의 시야를 보다 넓혀줄 수 있을까 하는 시도에서 집필된 것입니다. 그렇다고, 기술서적이나 이론서적들이 불필요한 것이 아닙니다. 오히려, 본서를 통해서 Code Complete나 Writing Solid Code, The Pragmatic Programmer, Extreme Programming Explained, Agile Software Development Ecosystem, UML Distilled, Applying UML and Patterns, Design Patterns 등과 같은 유명 전산학 및 프로그래밍 서적들의 목적과 취지를 이해하는데 도움이 되었으면 합니다. 즉, 본서를 통해서 이러한 서적들 하나 하나로부터 지식을 얻는데 조금이나마 도움이 되었으면 합니다. 물론, 필자는 책을 홍보할 목적을 가지고 말씀드린 것은 아닙니다. 제가 열거한 책들 외에도 좋은 책들이 있을 수 있으니까요.
한 때, 국내의 유명한 어느 컴퓨터 서적 출판사에서 일하는 직원과 대화를 나눈 적이 있는데, 그때 그 직원분이 전산서적이나 프로그래밍 서적을 구독하는 사람들이 취미 삼아 책을 모으는 경우가 있다고 이야기해 준 적이 있습니다. 물론 많지는 않지만 꽤 있는 것을 알게 되었습니다. 그것은 바로, 책으로부터 어떤 영감을 얻기 위한 것이라고 생각합니다. 본서를 전산학 책에 대한 메타 책으로 읽혀졌으면 하고 조심스럽게 바랍니다. 즉, 전산학 책을 읽을 수 있는데 어떤 영감을 이 책을 통해서 조금이나마 얻었으면 합니다.
필자가 아는 한도에서 소프트웨어 개발이라는 전장에서 생존을 위해 문제상황을 돌파하고 문제들과 싸워 이기기 위해서는 여러가지 술(術)을 구사할 수 있어야 합니다. 바로 소프트웨어 스킬로서의 기술을 의미합니다. 이러한 기술은 언어화되기가 어렵고 언어화될 경우 그 효력을 상실하기가 쉽습니다. 그래서 선학들은 이를 무언의 지식(Tacit Knowledge)이라고 말합니다.
하지만, 비록 소프트웨어 개발 기술을 언어화시키는 것이 실질적인 기술을 표현하지 못한다하더라도 어느 정도 개발자에게 도움이 될 수 있습니다. 즉, 언어라는 과정을 통해서 소프트웨어 개발 기술로서의 지식을 무의식적으로 승화시킨다면 그 차원에서는 개발 기술에 대한 의미가 비슷해지지 않나 생각해 봅니다. 우리가 국어를 처음 배울 때 자주 따라하고 반복하면서 저절로 암기화되어 무의식적인 차원까지 도달하는 것처럼 말입니다. 따라서, 소프트웨어 기술이라는 것이 행위적인 수단을 요체로하지만 이를 언어로 풀이해서 이해한 후, 깊이 학습하여 무의식적인 차원까지 이르르게 한다면 소프트웨어 기술을 익히는데 도움이 될 것입니다. 즉, 소프트웨어 기술에 대한 지식을 언어화하여 익히고 배우는 것이 어느정도 도움이 된다고 생각합니다. 물론, 실질적으로 일을 통해서 직접 체험을 통해서 증득하는 것만큼 직접적이지는 않지만 말입니다. 따라서, 본서의 반 사변적이고 반 경험적인 이성이 독자제현님들게 도움이 될 것이라 생각합니다.
또한, 소프트웨어 개발이라는 전장에 나가 문제상황을 돌파하고 문제들과 맞서 싸우기 위해서는 개발툴이나 언어에 의한 단순한 스킬로서의 기술이 아닌 술법(術法)을 알아야 합니다. 술법(術法)이라고 해서 어떤 도력(Occult Power)을 뜻하는 것이 아니라 기술을 쓰는 마음가짐과 자세를 뜻합니다. 검을 사용하는 검법처럼 소프트웨어 개발 기술을 사용하는데에도 법이 있으며, 이러한 법을 배워야 합니다. 그러나, 앞에서 말씀드렸듯이 이러한 법 또한 말로서 설명되어서 이해될 수 있기 보다는 실질적으로 옆에서 지켜 보고 직접 자신의 선생이나 스승으로부터 배워야 합니다. 즉, 소프트웨어 개발 기술에 대한 마음가짐과 자세를 언어로 표현한다는 것에는 한계가 있습니다.
동양의 옛 고전을 읽어보면 수레바퀴에 맞는 차축을 깍는 수레차 수리공에 대한 일화가 나옵니다. 수레바퀴에 맞는 차축을 깍으려면 수많은 시행착오를 통해 몸과 마음으로 배우고 익힌 노련한 전문 수레차 수리공의 기술이 필요합니다. 수레바퀴에 차축을 제대로 끼우려면 차축을 너무 얇게 깍아도 안되고 너무 두껍게 깍아도 안됩니다. 이러한 기술은 언어로 표현할 수 있는 문제가 아닙니다. 우리가 언어화할 수 있는 것은 그가 어떻게 수레바퀴에 맞는 차축을 깍는법을 배워왔는지 그 시행착오와 함께 그의 직관과 사유만을 배울 수 있습니다. 필자도 본서를 통해서 소프트웨어 개발에 관해 언어화할 수 있는 바의 한도 내에서 프로그래머로서 알아두어야할 소프트웨어 개발에 관한 내용을 담았습니다. 또한 소프트웨어 개발 자세와 마음가짐에 대해서 함께 담고자 하였습니다. 그러므로, 필자의 글에서 너무 많은 것을 얻으려하거나 지나친 기대를 하실 필요는 없다는 것을 삼가 말씀드립니다.
아무쪼록, 본서가 조금이나마 독자 제현님들께 소프트웨어 개발을 이해하는데 도움이 되었으면 합니다. 끝으로, 본서의 출판을 허락해 주신 홍릉과학출판사 사장님께 감사 드리며 직원분들께도 감사 드립니다.

차례

 

 

머리말
Chapter 1. 프로그래밍에 대한 사색 [15]
Chapter 2. 소프트웨어 개발 입문자분들께 드리는 31가지 조언 [20]
1. 처음에는 자신이 사용하는 개발툴이나 언어를 강력한 툴이자 언어로 생각하십시오. [25]
2. 어느 정도 숙달되면 개발툴이 아닌 업무에 주의를 기울이십시오. [31]
3. 처음에는 자신이 사용하는 개발툴이 갖고있는 기능의 전체상을 획득하도록 하시고 그 다음에 하나 하나 철저하고 자세하게 배우도록 하십시오. 그리고 중요한 지식과 기술을 중심으로 배우십시오. [34]
4. 프로젝트에서 대면하게 되는 새로운 요소 기술, 팁 그리고 노하우들을 하나 하나 기록하고 정리하여 여러분의 지식체계로 발전시키십시오. [53]
5. 자신이 사용하는 개발툴의 기능적 사용법, 요소 기술, 팁 및 노하우를 기록하고 정리하는 것 못지 않게 이를 여러분의 것으로 내면화하는 것이 중요합니다. [58]
6. 문제의 다양한 변화를 고려하고 다양한 해법을 모색하십시오. [61]
7. 개발툴은 기능적인 툴이라는 점을 잊지 마십시오. 즉, 개발툴에 대한 감각을 익히십시오. [66]
8. 반복을 두려워 하지 마십시오. 반복 속에 변화가 있습니다. 그 미묘한 변화를 터득하십시오. [70]
9. 가끔씩 소프트웨어의 실체를 파악하는데 주의를 기울일 필요도 있습니다. [74]
10. 요긴한 한 줄의 코드가 허황된 말이나 장황한 이론보다 더 중요할 수 있습니다. [76]
11. 다양한 요소 기술을 마스터하십시오. [78]
12. 문제 의식을 가지십시오. [83]
13. 자신이 사용하는 개발툴에 대한 전체적인 시야를 획득하도록 하십시오. 종종 예시적 사고(Predictive Thinking)가 도움이 될 때도 있습니다. [85]
14. 단순성(Simplicity)을 최대한 활용하십시오. [89]
15. 프로그래밍 그리고 프로젝트에서 즐거움을 찾으십시오. [95]
16. 다른 프로그래머들과의 교류를 이루어가면서 개발문화와의 흐름 및 휴먼네트워크와의 동시성을 유지하십시오. [106]
17. 업무와 관련하여 인간관계를 원활하게 유지하십시오. [109]
18. 팀웍을 유지하십시오. [111]
19. 소프트웨어 장인정신을 본받으십시오. [127]
20. 자신의 일에 긍지와 자부심을 가지십시오. 그리고 일에 몰입하십시오. 그 속에서 자유를 찾으십시오. [129]
21. 연속적이고 지속적으로 일을 하십시오. 그리고 규칙적으로 일하십시오. [133]
22. 요소 기술을 익혀 하나의 완성된 제품을 만들어 내도록 하십시오. 137]
23. 코드 가독능력과 작성능력을 향상시키십시오. [140]
24. 어느 정도 실력이 향상되면 SQL과 데이터베이스 활용에 대해서 공부를 하십시오. [147]
25. 남에게 가르침으로써 알고 있는 지식을 더 새롭게 하고 새로운 것을 배우는 기회를 얻으십시오. [158]
26. 선임 개발자와 동료 개발자 그리고 후배 개발자의 진지한 모습과 개발에 몰입하는 자세를 배우도록 하십시오. [160]
27. 변화에 적응하십시오. [162]
28. 전산을 전공하지 않았다고 반드시 마이너스 요인이 되는 것은 아닙니다. [164]
29. 익스트림 프로그래밍, 디자인패턴, 리팩토링 등의 최신 소프트웨어 개발 기술에도 관심을 가지십시오. [170]
30. 어느 정도 개발툴 실력이 확고하게 되면 영어, 경영지식 및 다양한 학문에 관심을 가지십시오. [172]
31. 항상 자신을 성찰하고 반성하며 끝임 없이 배우도록 노력하십시오. [174]
Chapter 3. 소프트웨어 개발 프로젝트 방법론의 이해 [181]
1. 필자가 익스트림 프로그래밍을 공부하게 된 배경 [182]
2. 익스트림 프로그래밍과 증험적 프로그래밍 사고 [186]
3. 익스트림 프로그래밍의 4대 가치와 10대 practice [190]
4. 협력(協力)프로그래밍과 지식공유 그리고 익스트림 프로그
래밍의 4대 가치에 관한 생각 [196]
5. 필자가 생각하는 Test First Programming 개념과 Prototype 개념의 결합 방법론 - 변형 TFP [202]
6. 통합된 시각(Unfied Perspective) [215]
7. 점진적 개발(Incremental development) [222]
8. 기민형 소프트웨어 개발 생태계(Agile Software development EcoSystem) [224]
9. WorkFlow와 문제공간/해법공간 [226]
10. 단순설계(SimpleDesign)에 대한 생각 [232]
11. 소프트웨어 라이프사이클과 업무 분석에 관한 해석 [238]
12. 실무적 소프트웨어 공학의 새로 패러다임 - 정형화(Formalization) [245]
13. 경영자이자 기술자로서의 궁극적 조화의 길 [255]
14. 프로그래머와 완벽주의 [260]

Chapter 4. 디자인패턴에 대한 소론(小論) [267]
1. 디자인패턴을 공부해야 하는 이유 [268]
2. 디자인패턴에 대한 생각 [272]
3. 디자인패턴 공부 방법 [275]
4. 필자가 디자인패턴을 좋아하는 이유 [280]

Chapter 5. 소프트웨어 공학에 대한 철학적 고찰 [288]

Chapter 6. 스터디 모임과 의사소통(커뮤니케이션)에 대한 소고 [304]
Chapter 7. 인생 수행의 방편으로서의 프로그래밍에 대한 개인적 소고 [320]
Chapter 8. 무의식적 정형화(Unconscious Formalization) [336]
Chapter 9. 프로그래머를 위한 내공 증득 [347]
부록. [샘플소설] 철학하는 프로그래머 [357]

 

 

 

Chapter 1. 프로그래밍에 대한 사색

 

 

필자가 근 14년 동안 컴퓨터 공부를 한 후 지금 프로그래밍에 대해서 무엇이냐고 누군가 묻는다면 바로 이렇게 이야기하고 싶습니다.
"우리의 사유(또는 사유과정)와 대화가 곧 프로그래밍이며, 프로그래밍은 우리의 사유(또는 사유과정)와 대화이다." 라고 말입니다.
우리는 일상생활 속에서 대화를 나눕니다. 그리고 그 대화를 통해서 지식과 지혜를 얻습니다. 하지만 대화가 뒤틀리게 되면, 즉 서로의 의사소통이 제대로 이루어지지 않으면 두뇌는 복잡해지고 어수선해지고 짜증이 나게 됩니다. 마찬가지로, 컴퓨터의 세계도 프로그래밍된 프로그램이 버그를 갖고 제대로 동작하지 않으면 위험에 처하게 됩니다.
인간도 사유를 잘못하게 되면 자신을 위험하게 만듭니다. 바르지 못한 사유, 잘못된 생각, 쓸데없는 생각, 나쁜 생각 이러한 생각들은 자신을 위험스럽게 만듭니다. 그리고 타자(대화의 상대방)와 대화와 의사소통이 잘 안됩니다. 마찬가지로, 프로그램도 제대로 작성되지 않으면 제대로 동작하지 않습니다.
프로그램은 함수 또는 객체의 집합체로 생각할 때, 프로그램에 존재하는 함수 또는 객체들은 모두 하나의 독립적인 개체(Entity)가 됩니다. 이들은 함수의 경우 패러매터에 의해 그리고 객체들은 메소드에 의해 서로 커뮤니케이션합니다. 만약 패러매터가 잘못 넘겨지면 컴파일이 안되고 함수 호출자와 함수 피호출자 간에 커뮤니케이션이 이루어지지 못합니다. 또한 객체로 구성된 프로그램의 경우, 객체의 메소드를 호출한 측과 객체 간에 대화가 이루어지지 않습니다.
함수 자체에 버그가 존재할 경우, 그것은 사유의 오류라고 할 수 있으며 함수 간의 버그가 존재할 경우, 대화의 오류라고 할 수 있습니다. 마찬가지로, 객체의 경우도 메소드 자체에 버그가 존재할 경우, 그것은 사유의 오류이며, 객체의 호출측과 객체간에 버그가 존재할 경우 대화의 오류라고 할 수 있습니다.
간단하게 말해서, 프로그래밍이란 인간의 사유를 컴퓨터 세계에 옮겨 놓은 것을 말하며, 컴퓨터 상에 존재하는 프로그램들은 인간 사유의 결과물이고 또한 사유들간의 커뮤니케이션 집합체라고 할 수 있습니다.
사실, 프로그래밍의 고도의 정신적 육체적 에너지와 노동을 요구하는 과정이며, 제대로된 프로그램 실체를 만들기 위해서는 많은 노력이 필요합니다.
인간이 프로그램을 고치는 것이 힘든 만큼 한 번 만들어진 프로그램은 많은 일을 할 수 있고 이곳 저곳 배포되기도 하여 많은 파급효과를 갖습니다. 또한 프로그래밍에 사용된 기법들을 체계적으로 정리하면 그 기법들을 다른 프로그램 제작에 사용할 수 있으므로 소프트웨어 개발 기술을 축적시킬 수도 있습니다. 이러한 사실은 어떤 과학이나 학문 그리고 예술과 공학에도 적용될 것입니다. 그러나, 컴퓨터 분야에서 이러한 프로그래밍 노하우와 기술전수는 매우 빠르게 이루어지고 있다고 봅니다. 기술이 멈추어져 있는 것이 아니고 부단히 발전하기 때문에 과거의 기술에 집착하거나 정체되어 있기를 많은 개발자들은 거부하고 있습니다. 사실, 무엇인가 추구하고 많은 것을 얻고 새로운 것을 탐구하는 전산학인 들에게는 과거의 기술에 대한 집착은 큰 의미를 갖지 못합니다. 단, 온고지신(溫故知新)이라하여 과거의 지식을 새롭게 하는 것은 중요합니다. 즉, 어셈블리어의 기술이 바로 C 언어 기술로 이어지고 C 언어의 지식이 C++ 언어에 대한 지식으로 이어집니다.
사실, 과거의 거의 모든 프로그래밍 언어가 나름대로 현재의 프로그래밍 언어를 이루게 하는데 커다란 영향을 주었다고 할 수 있습니다. 그래서, C++을 잘 공부하면, Java 언어도 잘 공부하게 되고 반대로, Java 언어를 잘 공부하면 C++을 공부하기도 수월해 집니다. 물론, 각 언어의 특성과 개발툴의 성향이 있기 때문에 다소 상호 프로그래밍 언어를 배우는데 어려움이 따릅니다. 그러나, 프로그래밍 언어를 초월한 논리적인 사유 공간 속에서는 이러한 프로그래밍 언어 간의 차이는 사라집니다. 즉, 프로그래밍 언어를 탄생시킨 메타지식 체계에서는 이러한 프로그래밍 언어의 차이는 초극되고 단일한 형태로 본질로 귀일합니다. 즉, 그것은 바로 우리 인간의 사유이자 사유 과정과 별차이가 없다고 할 수 있습니다.
프로그래밍은 인간의 본질을 한 번 더 진지하게 사색하게 하며, 진지한 프로그래머는 항상 무한한 사유공간에 대해 경탄을 마지 않습니다. 우리의 사유공간을 저 무한한 우주에 비교한다면 프로그래머가 여행할 수 있는 사유의 도정은 사실 무한합니다. 실제로 프로그래머가 경험하는 사유의 도정 자체가 하나의 주제를 달고 형상화된 것이 프로그램이라고 할 수 있습니다.
프로그램을 가만히 들여다보면 우리가 사유한 과정을 정말 여실히 드러내고 있다는 것을 알 수 있습니다. 물론, 그러한 사유과정은 고뇌를 따르기도 하고 환희심을 주기도 합니다. 막혔던 곳이 트이고 새로운 길이 열리게 되면 우리는 정말 큰 즐거움을 얻습니다. 버그로 고통받고 있는 프로그램 자체를 치유하고자 하는 프로그래머의 고뇌하는 모습은 그것이 바로 프로그램과 프로그래머가 둘이 아니라는 것을 말해주는 듯 합니다. 실제로 프로그램은 프로그래머의 분신이며 화신입니다.
프로그래머는 단순히 코딩을 하는 것이 아니라, 사색하고 자신의 사유를 다듬고, 반복되는 코딩 속에서 나름대로의 법칙과 프로그래밍 세계에서 명시적으로 혹은 묵시적으로 부과하는 보편타당한 이치를 익히게 됩니다. 프로그램의 전체 구조는 결국 명령어들의 순차, 조건, 반복 이라는 과정들의 흐름으로 되어 있습니다. 즉, 우리 인간이 일반적으로 사유하는 방식과 별차이가 없습니다. 인간의 사유 흐름이 결국 컴퓨터 세계에 이입되면 그것이 프로그램이 되고 그 과정이 프로그래밍이 됩니다.
만약, 프로그래머로서 많은 시간을 보내고자 한다면 프로그래밍이란 무엇인가에 대해서 진지한 사색을 갖는 것도 나쁘지는 않을 것입니다. 왜냐하면 프로그래머에게 있어서 프로그래밍은 삶의 일부이기 때문입니다. 또한 훌륭한 프로그래머는 프로그래밍에 대해서 본질적인 통찰력을 얻습니다. 즉, 익스트림 프로그래밍에서처럼 Kent Beck은 프로그래머로서 지향하고 갖추어야 할 사유와 행동의 지침을 시사합니다. 프로그래머에게 있어서 프로그래밍은 삶의 연장선에 위치하며, 삶에서의 문제나 프로그래밍에서의 문제나 큰 차이를 느끼지 않는 듯 합니다. 그것은 중용(中庸)에서 언급한 것처럼 "군자는 학문을 통해서도 도를 행한다."는 가르침을 잘 말해줍니다. 만약 무엇인가를 배우고자 하고 프로그래밍을 통해서 그것을 얻고자 한다면 사실 누구나가 이 중용에서 말한 바를 알고 있을 것입니다.
그러나, 실제 IT 업계에서 이러한 프로그래밍에 대한 통찰을 얻는 것 보다 빠르게 일을 해야 하며, 지식을 체계화하고 축적하는데 상당히 어렵습니다. 그래서, 더욱 프로그래머들은 틈나는데로 자신의 지식을 정리하고 체계화하는 노력을 게을리해서는 안됩니다. 프로그래밍을 단순히 일로서 생각한다면 사실 프로그래밍이란 일은 상당히 힘든 일이 될 것입니다.
Pete Mcbreen은 그의 서적 "소프트웨어 장인정신"에서 소프트웨어 개발을 즐겁게 하라고 말합니다. 즉, 프로그래밍이 즐겁지 않다면 그리고 소프트웨어 개발이 즐겁지 않다면 그 프로세스에는 문제가 있다는 것을 말합니다. 프로그래밍과 소프트웨어 개발에 대해서 즐거움을 얻는 것이 바로 전문 프로그래머로 가는 첩경이 아닌가 생각합니다. 프로그래밍이 즐겁지 않다면 그 프로그래머의 길은 험난한 고뇌의 연속일지도 모릅니다. 그러나, 프로그래밍이 즐겁다면 프로그래머는 매우 빠르게 훌륭한 프로그래머로 자신을 변화시킬 수 있을 것입니다.

 

Chapter 2. 소프트웨어 개발 입문자분들께
드리는 31가지 조언

 

 

본 글은 전산학 및 프로그래밍 언어에 대한 기본 지식을 갖고 있는 분들을 위한 조언을 담고 있습니다. 필자가 실무에서 주력 언어로 사용한 언어가 C 언어와 파워빌더였고, 특히 파워빌더 개발툴을 오래 사용했기 때문에 파워빌더에 대한 내용을 주로 다룹니다. 그러나, 어떤 개발툴을 사용하건 간에 개발자가 갖추어야 할 마인드와 자세는 다를바 없으므로 보다 큰 견지에서 본 장의 글을 읽어주시면 될 것입니다. 필자는 C 언어와 같은 텍스트지향적이고 절차지향적인 언어를 사용하기도 하였으므로, 본 장에서 거론하는 대부분의 조언들이 C++, Java 등의 거의 모든 언어와 개발툴에도 적용된다고 생각합니다. 본 장에서 비주얼 개발툴이라고 굳이 언급한 것은 요즘의 C++ 언어도 비주얼 툴의 형태를 빌려 제공되고 있기 때문입니다. 그리고, 본 장은 특정 언어의 기능을 다루기 보다는 개발 언어와 개발툴을 익히고 공부하는 방법 그리고 자세에 대한 내용을 다루고 있습니다. 또한 이 글에서는 특정 언어와 개발툴에 대한 기능과 코드 분석은 일부를 제외하고는 거의 다루지 않습니다. 물론, 본 장에서 다루는 코드는 파워빌더의 스크립트 언어에 바탕을 두고 작성되었습니다.
본 장의 글은 7년에서 8년 동안 필자가 경험한 바를 나름대로 소화하고 정리한 글로서 특정 언어와 개발툴을 사용하여 실무 소프트웨어 개발 프로젝트에 입문하는 분들을 대상으로 하고 있습니다. 그러나, 글이 내용이 인생수행의 방편으로서 소프트웨어 개발을 생각하고 있는 필자의 지론에 의해 다소 내용이 함축적이고 은유적이기까지도 함으로 이점에 대해서 양해를 구합니다. 사실, 노자의 도덕경에서 이야기 한 바처럼 도가도 비상도(道可道 非常道)라고 하였으므로 말의 표면적 의미보다는 글자들 속에 새겨진 내적인 의미를 통찰하시는 것이 중요합니다.
본장에서 이야기하는 내용은 다소 사변적일 수 있습니다. 지행합일(知行合一)이라고 하여 아는 것과 행하는 것이 일체가 되어야 합니다. 필자도 이 지행합일을 실천하기가 어려워 나름대로 고민과 고생을 하였습니다. 그리고 지금도 잘 안 되는 경우도 있고 항상 이를 염두해 두고 살아갑니다. 본 장의 내용을 소화하여 여러분의 실무에 실제로활용 하였으면 합니다.
한편, 필자가 여기서 소프트웨어 개발 입문자분들이라고 한 것은 전혀 소프트웨어 개발을 모르는 분들에 대해서 이야기하는 것이 아닙니다. 특정 개발툴을 배우고자 하는 강한 열정과 뜻을 지니고 이곳 저곳 개발 언어와 툴에 관련된 서적과 전산 경력자들을 만나보고 뛰어 다니고 개발툴과 언어에 관한 강의도 들어보려고 노력하시는 분을 말씀드립니다. 그냥 전혀 개발툴을 모르시는 분은 시중의 개발툴 서적을 읽어보시고 한 번 정도 프로그램을 실행시켜 보았으면 합니다. 그리고 나름대로 한 권 정도의 서적에 대해서는 통찰을 얻으셨으면 합니다. 본 글은 처음으로 소프트웨어 개발 프로젝트를 수행하기 위해 준비하는 초급 개발자를 위한 글이라고 생각하시면 될 것입니다. 즉, 자신이 사용하는 개발툴에 대해서 책 한 권 정도 읽어 본 경험이 있으나 프로젝트 수행 경험이 없는 개발툴 입문자분들을 대상으로 글을 작성하였습니다.
본 글은 필자가 4년간 C 언어와 파워빌더 개발툴을 사용해서 프로그램을 개발해 본 경험을 토대로 정리한 것입니다. 부족한 내용이지만 그래도 필자의 글이 나름대로 도움이 되었으면 하는 바램으로 소프트웨어 개발 입문자분들을 위해 글을 정리하게 되었습니다. 서점이나 학원에서는 실제 특정 개발툴과 언어를 사용하는 방법에 대해서 개괄적이고도 자세하게 다룹니다. 하지만 개발툴과 언어를 배우는 방법과 자세 등에 대해서는 그렇게 많이 다루고 있지 않은 듯 합니다. 필자의 개인적 소견에 의하면 몇몇 서적을 제외하고는 시중의 서적들이 특히 소프트웨어 개발에 대해서는 많은 노하우를 제공하지 못하는 듯 합니다. 서적이 지향하고 추구해야 할 것은 개발툴과 언어를 사용하는 개발자들에게 개발툴의 기능과 사용법 그리고 언어의 문법과 코딩 방법을 가르쳐 주는 것을 넘어서 개발툴을 숙달하는 방법과 자세를 배우는 것을 가르쳐 주는 것입니다. 본 글은 특정 개발툴을 마스터하기 위해서 갖추어야할 개발자의 소양을 필자의 경험을 토대로 정리하였습니다. 특히, 파워빌더라는 구체적인 개발툴을 통해서 특정 개발툴을 체계적으로 배울 수 있는데 도움이 되는 학습방법과 자세들에 대해서 주제별로 정리하여 강좌로 마련하였습니다.
1995년도 겨울, 파워빌더, 비주얼 베이직 그리고 델파이 개발툴이 가장 인기 있는 비주얼 툴로서 각광받고 있었습니다. 그당시 이러한 글을 구하고자 노력했는데, 그 길을 제시한 글을 찾기가 어려웠습니다. 그리고 지금도 이러한 글은 잘 소개되어지지 않고, 많은 사람들이 이러한 글을 쓰기를 어려워하고 있는 듯합니다. 혹시 자기자랑이 되지 않을까 부담도 되고 과연 얼마나 보편타당하게 쓸 수 있을까하고 고민하게 되기도 하고 말입니다. 필자도 이 글을 쓰기에 앞서 이러한 부담을 갖게 되었는데, 용기를 내어 글을 씁니다. 부디, 필자의 경험과 지식이 미흡해도 너그러이 이해해 주셨으면 합니다.
이 글은 필자가 대학 때부터 전산학을 공부하여 지금까지 배워온 지식과 제가 접한 수많은 전산 및 프로그래밍 서적을 학습한 내용을 집약해서 담고 있습니다. 따라서, 어떤 부분은 다소 개념적인 내용이 나오기도 하고 이해하기 어려운 내용이 나올 수 있습니다. 그러나, 여러 번 글을 읽다보면 필자가 말하고자 하는 바를 이해할 수 있다고 생각합니다. 또한, 필자의 본 글이 개발자의 모든 삶을 대변해 주는 것은 아니며 다만 본인이 바라보는 개발자의 삶과 배움에 대한 인식을 정리한 것일 뿐입니다. 그러므로, 필자로부터 얻을 수 있는 것은 취하고 그렇지 못한 것은 서서히 익혀나가셔도 되지 않을까 생각합니다. 물론, 필자의 글에 오류가 있을 수 있으니 독자 제현님들의 현명한 식견에 근거하여 필자의 글을 읽어주시길 바랍니다.
각설하고, 중요한 것은 필자가 여기서 제시한 이야기들은 독자 제현님들의 개발 과정 동안 한 번쯤 생각해 볼 수 있는 내용들이라는 점입니다. 필자 혼자서 경험한 내용뿐만 아니라 다른 서적들(소프트웨어 장인정신, 익스트림 프로그래밍, Agile Methodology 등에 관련된 서적들)과 다른 개발자들의 이야기를 나름대로 정리한 것이므로, 지금 당장 소프트웨어 개발 입문자로서 여러분에게 중요하게 인식이 되지 않더라도 시간이 지나고 세월이 흐르면 여기서 필자가 논의한 내용을 어느 정도 이해할 수 있을 것이라 생각해 봅니다. 여기서는 6년 간의 소프트웨어 개발 프로젝트 경험을 통해 얻은 작지만 필자에게는 소중한 경험을 31가지 주제 하에 정리하였습니다. 필자 나름대로 몇 개월의 시간을 할애하여 개발자로서 보내온 삶의 여정에 있어 중요하다고 생각되는 이야기들을 이 글에 담았습니다. 그리고 저의 이야기보다 더 긴요하고 값진 이야기를 다른 분들로부터 들을 수 있으니 항상 깨어있는 자세로 개발 프로젝트를 수행해 나가셨으면 합니다.
한편, 기술을 배우는데 있어 요긴한 팁을 잘 아는 것이 중요합니다. The Pragmatic Programmer라는 서적에서는 저자들이 프로그래머가 알아두면 요긴할 사항을 항목별로 정리하여 Tip이라는 제목 하에 책에 배치하였습니다. 총 70여개에 달하는 팁은 우리가 프로그래밍하면서 대면하는 실수들과 버릇들에 대해서 똑똑한 조언자로서 우리에게 하나 하나 일러줍니다. 본서에서 언급한 31가지 조언도 The Pragmatic Programmer 서적의 70여개의 팁처럼 소프트웨어 개발 입문자분들게 실질적으로 스스로의 로드맵(RoadMap)을 읽는데 약간이나마 도움이 되었으면 합니다.

1. 처음에는 자신이 사용하는 개발툴이나 언어를 강력한 툴이자 언어로 생각하십시오.
특정 개발툴에 입문하신 분이라면 먼저 앞으로 사용하게 될 개발툴에 대해서 자부심을 가지시길 바랍니다. 필자도 다른 여타의 개발툴을 놓고 망설이다가 결국 특정 개발툴을 사용하여 프로그램을 개발하기 시작한 것이 인연이 되어 4년 넘게 그 개발툴만을 사용하게 되었습니다. 그 당시, 비주얼 베이직, 델파이, 파워빌더 세 가지 개발툴이 가장 인기가 있었습니다. 이 개발툴들은 GUI 기능이 강력하고 이벤트 스크립트(Event Script)를 사용해서 프로그램을 작성하기 때문에 매우 모듈화 적인 프로그램이 가능합니다. 또한 비주얼 베이직과 파워빌더는 4GL(4세대 언어)를 채택하고 있어 프로그래밍 언어에 대한 지식이 없는 사용자들도 쉽게 배울 수 있습니다. 그러나, 파워빌더는 데이터윈도우라고 하는 강력한 일종의 재사용 가능한 컴포넌트를 가지고 있어 데이터베이스를 액세스하는데 있어서 매우 강력합니다. 비주얼 베이직의 경우 폼윈도우(GUI 화면)에 구성된 컨트롤들의 값을 받아와 다시 SQL문에 대입하여 이 SQL문을 데이터베이스에 보내는 방식을 사용하고 있습니다. 일반적으로, 파워빌더는 dw_1.Update()와 같은 단 하나의 문장으로 복잡한 처리를 단순하게 해결합니다. 그리고, 파워빌더는 데이터윈도우를 통해 강력한 리포트 작성을 할 수 있어 현업에서 매우 유용하게 사용됩니다.
물론, 비주얼 베이직과 델파이 및 그 외의 개발툴들도 나름대로 강력한 면모를 자랑하고 있습니다. 하지만, 필자는 필자가 사용한 파워빌더의 이름 네 글자가 그래도 가장 강렬하게 필자에게 호소력을 가져다 주었습니다. 그래서, 파워빌더를 채택하게 되었는데, 결국 지금까지 비주얼 베이직이나 델파이를 선택하지 않았던 것을 후회하지 않습니다. 즉, 필자는 지금도 파워빌더 사용을 선택한 것에 대해서 괜찮게 생각하고 있습니다.
제가 여러분께 처음에는 자신이 사용하는 개발툴을 강력한 툴로 생각하십시오 라고 말하는데는 이유가 있습니다. 물론, 실제로 필자에게는 필자가 선택한 개발툴은 강력한 툴이고 지금도 그렇게 인식하고 있습니다. 그러나, 처음 자신이 선택한 개발툴을 배우시는 분들은 해당 개발툴에 대해서 약간의 의구심과 망설임이 있을 겁니다. 요즘 잘 나가는 비주얼 C++이나 Java를 배우는 것이 더 낳지 않을까 라고 말입니다. 물론, 양수겹장이 강력하듯, 비주얼 C++이나 Java 언어 하나만을 고수하지 마시고, 이러한 언어에 추가로 4세대 언어 개발툴 하나를 더 지니고 있으면 개발자의 삶으로서 보다 넓은 사고와 기술을 겸비할 수 있는데 도움이 될 거라 생각합니다. 즉, Java 언어에 추가로 파워빌더를 배우시거나, 비주얼 C++에 추가로 파워빌더를 배우셔도 좋습니다. 또한 어떤 조합으로 언어와 개발툴 두 가지를 마스터하시려고 해도 상관은 없습니다. 예를 들어, Java 언어와 비주얼 베이직을 선택해도 괜찮습니다.
지금까지 제 글은 다분히 파워빌더 개발툴을 홍보하는 사람 같군요. 그렇게 보였다면 죄송합니다. 다만, 특정 개발툴과 언어를 배우시려고 마음을 먹었다면 자신이 선택한 개발툴과 언어가 좋건 나쁜 툴이건 상관하지 않고 긍정적으로 생각하시길 바랍니다. 즉, 한 6개월이고 1년 정도는 이 개발툴을 다루어서 이 개발툴의 구석구석 모든 기능과 기능들이 창출해내는 기법과 다양한 소프트웨어 기술들을 마스터하겠다고 결심을 하십시오.
자신이 사용하는 개발툴에 대해서 자부심을 갖지 못한다면 벌써 개발툴을 이해하고 배우는데 마이너스 요인이 되는 것입니다. 필자의 이야기만을 믿지 마시고, 주변에 자신과 동일한 개발툴과 언어를 잘 다루어 본 경험이 있거나 지금도 열심히 사용하고 있는 분들께 조언을 구해 보십시오. 과연 여러분께서 선택한 개발툴을 배우면 장래를 위해 비전이 있고 도움이 되는지 말입니다. 그리고 자신이 선택한 개발툴에 관한 개략적인 서적이나 기사 및 강좌들을 읽어보십시오. 그리고 신중하게 판단하십시오. 만약 자신이 특정 개발툴과 언어를 공부하겠다는 마음이 생긴다면, 그 즉시 해당 개발툴을 마스터하는 데에 자부심과 긍지를 갖고 도전하십시오.
한 2년여 정도 사용해보면 기본적으로 비주얼 개발툴에 대해서 커다란 기대감과 자부심은 사라질 것입니다. 왜냐하면, 2년여 동안 소프트웨어 개발 프로젝트를 세 개정도 수행해 보면 자신이 사용하고 있는 개발툴의 기능과 기법에 대한 전체적인 조감도를 그릴 수 있게 될 것입니다. 그리고 SQL이나 데이터베이스 테이블 설계의 중요성도 인식하게 될 것입니다. 결국, 비주얼 개발툴이 하나의 기능적 도구에 지나지 않다는 것을 여실히 느끼실 것입니다. 그러나, 2년여가 지나면 그렇게 느껴져야 당연한 것입니다. 저도 그렇게 느꼈고 많은 분들이 그렇게 느낄 것입니다. 특정 개발툴의 기능은 한정되어 있기 때문에 어느 정도 사용하면 중요한 기능과 불필요한 기능들이 구별되게 됩니다. 만약, 특정 개발툴의 모든 기능을 다 배우려고 하면 저도 몇 년이 더 걸릴지 확신할 수 없습니다. 그러나, 중요하고 자주 사용되는 기능을 배우게 되면 개발툴에 대한 전체적인 윤곽을 파악할 수 있을 겁니다. 2년 정도의 기간 동안 열심히 프로젝트를 수행하다보면 서서히 자신이 변화되는 것을 느낍니다. 그리고 결국 어느 정도 개발툴의 기능을 구석구석을 이해하게 될 것입니다. 이렇게 되면 개발툴에 대해서 애착과 탈피라는 두 갈래의 길에 서게 됩니다. 기다란 인생의 여정 속에 있어서 자신의 인생 길을 선택하는 기로에서 자신이 사용해 왔던 개발툴을 계속해서 사용할 것인가 아니면 다른 분야로 나아갈 것인가를 선택해야 합니다. 그러기 위해서는 어느 정도 세월이 흐른 뒤의 자신의 모습을 생각해 보면서 미래를 계획하는 것도 중요합니다. 그리고 그 때 선택은 여러분의 자유이며 여러분의 몫입니다. 하지만 지금 어느 특정 개발툴에 입문하셨다면 당분간은 그 개발툴을 사용함에 있어 자신감과 긍지를 가지십시오. 그리고 자신이 선정한 개발툴에 몰입하고 심취할 필요가 있습니다.
중요한 것은 처음 개발툴을 배우는 시점에서는 나중에 어떻게 개발툴을 생각하게 되던 배우고자 하는 개발툴에 대해 자긍심을 가져야 합니다. 만약 비주얼 베이직을 연마하고자 한다면 이 비주얼 베이직에 대해서 자긍심을 가져야 한다는 것입니다. 그렇지 않고는 개발툴에 대한 믿음과 신뢰가 형성되지 않아 개발툴과 친해지는데 어렵게 됩니다. 개발툴에 대한 자긍심은 개발툴에 대한 존경심과 맞물리며, 개발툴을 신뢰하는 마음을 갖게 됩니다. 즉, 이 개발툴만을 사용하면 무엇이든 개발할 수 있다라고 까지 말입니다. 물론, 반드시 그렇지는 않지만 말입니다. 또한 이렇게 개발툴에 지나치게 집착 해서는 안됩니다. 개발툴에 자긍심을 갖고 개발툴을 신뢰하고 개발툴을 마스터하고자 하는 것과 개발툴에 집착하는 것은 별개의 이야기가 될 수 있습니다. 여기서 말하는 집착하지 말라 는 이야기에는 말로 표현할 수 없는 이유가 존재함을 여러분이 직접 실무 프로젝트를 통해서 경험하셨으면 합니다. 프로젝트를 수행할 때 업무 중심적이 아니라 구현 종속적이 될 수 있으므로 말씀드리는 것입니다. 만약 개발툴에 집착하게 되면 업무 중심적이지 않고 구현 중심적이 됩니다. 그러면 프로그램 구조에 대한 전체적인 조망과 이해를 얻기 어렵습니다. 개발툴의 기능에 집착하게 되면 업무 중심적, 모듈 중심적 그리고 비즈니스 로직 중심적인 사고 및 인터페이스 중심적인 사고에서 벗어나게 됩니다. 나중에 프로젝트를 수행하다 보면 제 이야기의 의미를 이해하시리라 생각합니다.
또한, 제가 자신이 선택한 특정 개발툴만을 강력한 툴로 생각하시라는 것을 잘못 이해하셔서 다른 개발툴은 훌륭하지 못하다 라고 생각하지 않으셨으면 합니다. 다른 툴은 그 나름대로 특징이 있고 장점을 가지고 있습니다. 다만, 다른 툴의 탁월한 기능을 부러워하여 자신이 사용하는 개발툴의 장점과 훌륭한 점을 망각하지 않으셨으면 합니다. 지금 우리가 배워야 할 개발툴은 다른 개발툴이 아닌 여러분이 선택한 개발툴이라는 점을 잊지 마셨으면 합니다. 처음에는 자신이 선택한 개발툴을 강력한 툴로 생각하십시오 라고 말씀드렸던 것처럼 처음 시작할 때는 이런 마음을 가지시라는 것이며 어느 정도 시간이 지나면 저의 말씀에 집착할 필요가 없다는 것을 아시리라 생각합니다.

2. 어느 정도 숙달되면 개발툴이 아닌 업무에 주의를 기울이십시오.
개발툴에 집착하게 되면, 업무를 바로 볼 수 있는 시야가 좁아지게 됩니다. 실제로, 프로젝트를 수행하다 보면 자신이 사용하는 개발툴만을 사용하지 않고 다른 개발툴을 사용하는 경우도 있습니다. 프로젝트의 요체(要諦)가 되는 것은 업무입니다. 업무에 근거하여 개발툴들의 기능이 사용되는 것입니다. 따라서, 항상 업무에 익숙해지도록 노력해야 합니다. 개발툴을 구현을 위한 도구라면 업무는 설계를 위한 재료가 됩니다. 설계가 있어야 구현할 수 있습니다. 물론, 구현되어야 설계가 의미를 갖는 것이므로 개발툴의 기능적 사용도 중요합니다.
하지만, 필자의 경험상 설계가 구현보다 중요하다고 생각합니다. 필자가 처음 프로그래머로 일하였을 때, 순서도나 설계라는 개념에 익숙하지 않았습니다. 그러나, 실제 구현하다 보니 구현의 줄기가 되는 설계가 없이는 구현이 힘들다는 것을 느꼈습니다. 즉, 중추적인 설계가 없이는 개념이 자꾸 흔들리고 기본적 발상이 자꾸 변해버리기 때문에 구현하는데 일관적 논리성과 지속성이 결여됩니다. 어느 정도 확정된 설계가 있어야만 이를 근간으로 하여 구현부가 세워질 수 있습니다.
예를 들어, 우리가 간단한 출판사 관리 프로그램을 개발한다고 합시다. 개발툴만을 놓고 이 출판사 관리 프로그램을 구현할 수 있는 것은 아닙니다. 먼저, 출판사가 어떻게 운영되고 있으며 만들어질 프로그램이 출판사에서 어떤 역할을 하게 되는지를 파악해야 합니다. 이를 위해 소프트웨어 개발 방법론에서는 분석(Analysis)과 설계(Design)가 하나의 도구로서 도입되었습니다. 순서도, 데이터 흐름도 및 UML과 같은 도구들은 바로 이 분석과 설계를 위한 도구들입니다. 필자는 현업에서 이러한 분석과 설계가 중요함을 인식했지만 특별한 선임자로부터 이에 대한 기술과 지식을 전수 받지 못했습니다. 따라서, 분석과 설계에 관한 설명은 필자가 느끼고 생각하는 내용만으로 한정하여 말씀드립니다.
개발툴로 구현하게 되는 업무는 대부분 MIS(경영정보시스템)입니다. 즉, 영업/생산/회계/출하/자재/인사 등의 모듈을 개발하는 일입니다. 이러한 모듈들 각각이 바로 업무의 구현체입니다. 여러분이 어떤 분야에서 일하던지 업무가 있으며 이러한 업무를 중심으로 하여 모듈을 개발하게 됩니다. 업무가 프로그램의 근간을 이루고 있으며 업무를 모르고서는 프로그램 구조를 생각할 수 없습니다. 예를 들어, 파워빌더 개발툴로 구현하게 되는 프로그램의 핵심 부분이 데이터윈도우 개체이고 이 데이터윈도우 개체는 SQL 문을 포함하고 있습니다. 또한 이 SQL 문은 데이터베이스를 액세스하게 되는데 이 데이터베이스 구조는 바로 업무에 의해 결정됩니다. 즉, 하위 프로그램 모듈의 기반에는 업무가 자리하고 있다는 점입니다. 업무가 바뀌게 되면 자칫하면 데이터베이스 구조를 바꾸어야 하는 경우도 발생하게 되므로 업무 분석과 파악에 대한 완전하고 정확한 이해가 프로그램 개발에 필수적입니다.
한편, 프로그램 구조에서 업무에 의해 영향을 받는 곳이 크게 두 곳인데 첫째가 데이터베이스이고 둘째가 비즈니스 로직입니다. 비즈니스 로직은 프로그램 내에 이벤트 스크립트로 작성되거나 또는 저장형 프로시쥬어(Stored Procedure)로 작성됩니다. 여러분이 개발툴의 전문가로 나가기 위해서는 바로 이 두 가지 방법에 대해서 확실히 숙지하셔야 합니다. 또한 크게는 데이터베이스 설계와, 비즈니스 로직의 구현에 대해서 잘 알고 있어야 합니다. 개발툴 입문자로서 지금은 이 부분이 그렇게 많이 요구되지 않는데, 프로젝트를 수행하게 되면 업무가 어떻게 하나 하나 프로그램 구조 속에 들어오게 되는지 알게 될 것입니다.
사실, 어떻게 보면 개발툴 입문자분들의 개발자로서의 최종 목적은 특정 업무에 대한 완전한 이해와 광범위한 업무에 대한 해박한 지식이라고 할 수 있습니다. 개발툴 입문자분들의 여정을 살펴보면 먼저, 자신이 사용하는 개발툴의 개발환경과 기능을 익히는 것이고, 그 다음은 SQL과 데이터베이스를 이해하는 것이며 그 다음이 바로 업무라고 할 수 있습니다. 물론, 업무가 개발자의 최종목표가 될 수 있지만, 기술자가 아니라 경영자로 나가기 위해서는 또 하나의 시작점이 됩니다. 즉, 개발자의 삶은 인생의 끝이 없는 여정의 일부인 듯 합니다.
물론, 이렇게 세 가지로 구분을 지었는데, 프로젝트에서 일하게 되면, 두 가지 이상을 이해하고 있어야 하며, 어떨 때는 세 가지 모두를 익혀야 합니다. 그리고, 개발자의 생명력을 가장 오래 지속시킬 수 있는 것은 바로 업무라는 것을 인식해 두었으면 합니다. 왜냐하면, 개발툴이 바뀌어도 업무는 그렇게 많이 변화하지 않으니까 말입니다. 그리고 일반적인 업무에 대해서 이해하고 있는 상태에서는 업무가 조금 변화해도 그렇게 이해하는데 큰 어려움을 없지 않나 생각합니다.
업무는 프로그램 구조의 중추를 이루며 기업에서 매우 중요하게 인식되고 있는 부분입니다. 따라서, 개발툴 입문자분들은 목표를 멀리 보고 시간은 가지고 업무 마스터까지 도달하도록 노력하셨으면 합니다.

3. 처음에는 자신이 사용하는 개발툴이 갖고있는 기능의 전체상 을 획득하도록 하시고 그 다음에 하나 하나 철저하고 자세하 게 배우도록 하십시오. 그리고 중요한 지식과 기술을 중심으 로 배우십시오.
프로그래밍 언어건 개발툴이건 혹은 일반 학문이건 필자의 경험상 처음에 전체적으로 무엇이 있는지 알아야 하고 그 다음에는 차근차근 하나씩 하나씩 자세하고 철저하게 배워나가는 것이 중요하다고 생각합니다. 처음에는 대강이라도 책을 한 번 읽어 본 후 무엇이 중요하고 무엇이 덜 중요한지를 알아야 합니다. 윤곽(Outline)을 잡은 후에는 정밀하게 이해하도록 해야 합니다. 즉, 개발툴에 흐르고 있는 전체적 기술 지식에 대해서 어느 정도 윤곽을 설정했다면 그 다음으로는 중요하다고 생각되는 부분에 대해서 확실하게 이해하고 넘어가야 합니다. 만약, 여러분이 신입 프로그래머로서 처음 상품 매출매입 프로그램을 개발해야 한다고 합시다. 물론, 설계도(다이어그램과 테이블 구조)가 주어지고 여러분은 훌륭한 설계자의 지도를 받으며 특정 개발툴로 개발을 한다고 합시다.
이때 여러분은 이 상품 매출매입 프로그램과 관련된 부분에 사용되는 요소 기술(Element Skill)에 대해서 확실히 이해할 필요가 있습니다. 물론, 여러분은 입문자이므로 개발툴의 어떤 기능이 이용되는지, 즉, 어떤 스크립트 함수가 사용되는지 혹은 어떤 이벤트가 사용되는지 등을 알고있지 못합니다. 이때의 심정은 바닷가의 모래에서 잃어버린 조개껍질을 찾는 것과 비슷합니다. 무수히 많게 보여지는 요소 기술들 중에서 지금 당면한 프로젝트에 사용할 수 있는 요소 기술들을 찾아내야 합니다. 그 외의 요소 기술은 차후의 문제이고 지금 거론할 이야기가 아닙니다.
초보 프로그래머의 입장에서 상품 매출매입 프로그램과 같은 특정 프로그램을 가능한 한 정해진 시간 내에 구현해야 할 것입니다. 필자의 경우, 파워빌더 4.0을 사용할 당시 많은 사람들이 파워빌더의 기초적인 기능만을 이해하고 응용이나 팁 등이 많이 알려지지 않았기 때문에 파워빌더를 배우기가 참으로 힘들었습니다. 하지만 지금은 파워빌더 개발자 네트워크와 같은 온라인 커뮤니티와 파워빌더 서적 등을 통해서 파워빌더에 관한 지식과 요소 기술 그리고 팁 등을 배울 수 있게 되었습니다. 다른 개발툴도 마찬가지 일 것입니다. 그리고 가장 직접적으로 자신이 일하고 있는 회사의 선임자들로부터 조언과 가르침을 얻거나 전수 받을 수 있습니다. 만약, 여러분의 회사에 이미 구축되어 있는 개발툴의 기본 라이브러리(Base Library)가 구축되어 있다면 여러분은 매우 편리하게 상품 매출매입 프로그램을 개발할 수 있을 겁니다. 기본 라이브러리를 활용하면 시간을 단축시키고 버그를 줄이며 노력을 절감시키면서 상품 매출매입 프로그램을 완성할 수 있습니다. 즉, 기본 라이브러리는 생산성을 극대화시키는데 큰 역할을 합니다.
그러나, 만약 여러분이 기본 라이브러리를 사용할 수 없다면 여러분은 좀 더 많은 개발툴의 순수 기술을 배워나가야 합니다. 즉, 윈도우 하나를 생성하는 방법에서부터 데이터윈도우 컨트롤 상에 이벤트를 추가하는 방법에 이르기까지 많은 항목을 철저하게 공부하셔야 합니다. 물론, 그렇다고 기본 라이브러리를 사용한다고 해서 이러한 항목을 공부하지 않는다는 뜻은 아닙니다. 다음에는 이러한 개발툴 입문자분들이 한 번 쯤 꼭 알아두어야 할 기능들에 대해서 필자가 정리한 파워빌더 핵심정리 101 내용을 실었습니다. 물론, 필자의 주관이 가미되었기 때문에 다른 개발자 혹은 필자보다 더 경험이 많고 훌륭하신 개발자의 시야에는 필자의 101가지 사항이 빈약하고 불충분하다고 지적하실지도 모릅니다. 그리고 혹 어떤 분은 너무 많은 것을 입문자분들이 배우게 되는 것 아니냐고 이야기하실 수 있습니다. 그러므로, 여러분은 참고로 다음의 핵심정리 101 내용을 참고하시기 바랍니다. 다른 개발툴에 대해서도 분명히 이와 같은 개발툴과 언어의 중요한 아이템이 존재할 것입니다. 파워빌더 외의 경우, 즉 비주얼 베이직, 델파이, Java, C++ 등에 대해서는 다른 선학 프로그래머로부터 핵심 아이템을 구하시길 바랍니다. C 언어에 대해서는 필자의 서적 "C 프로그래밍의 기초 및 학습론"이 조금이나마 도움이 될 것입니다. 다른 개발툴 사용자분들께는 해당 툴들에 대한 핵심정리를 언급하지 못해 이점 양해를 구합니다.

파워빌더 핵심정리 101
1. 이벤트 구동형 프로그래밍(Event Driven Programming)에 대해서 이해하고 있나요?
2. 윈도우 컨트롤을 확장해 놓은 파워빌더 컨트롤의 기능에 대해서 이해하고 있나요?
3. 윈도우 오브젝트, 어플리케이션 오브젝트, 메뉴 오브젝트, 사용자 오브젝트 등 각종 오브젝트를 만드는 방법을 알고 있나요?
4. 라이브러리 페인터에서 각종 오브젝트를 다룰 수 있다는 것을 알고 있나요?
5. 컨트롤과 오브젝트는 모두 이벤트, 프로퍼티, 함수라는 3대 특성을 지니고 있다는 것을 이해하고 있나요?
6. 사용자가 작성하는 스크립트는 특정한 이벤트에 대한 스크립트로서 이벤트 스크립팅이라는 것을 알고 있나요?
7. 상속이 되는 오브젝트와 그렇지 못한 오브젝트를 분류할 수 있나요?
8. 상속이 지닌 장점과 단점에 대해서 기술적으로 이해하고 있나요?
9. 인스턴스 변수가 차지하는 역할을 윈도우 오브젝트의 관점에서 설명할 수 있나요?
10. 전역변수의 사용이 프로그램 전반에 걸쳐서 어떤 영향을 미치는지 알고있나요?
11. SQLCA 시스템 변수에 대해서 어떻게 이해하고 있나요?
12. 어플리케이션 오브젝트에서 데이터베이스와 연결하기 위해 설정하는 스크립트를 알고 있나요?
13. 파워빌더의 모든 오브젝트들과 컨트롤들이 어떠한 형태로 상속계층구조에 기반을 두고 있는지 이해하고 있나요?
14. 윈도우의 종류에는 메인윈도우, 자식윈도우, 팝업윈도우, 응답윈도우, MDI 프레임 및 마이크로헬프가 있는 MDI 프레임이 있다는 것을 알고 있나요? 그리고 이들 각각의 기능상의 차이를 이해하고 있나요?
15. 각종 윈도우 컨트롤(파워빌더 컨트롤)이 지니고 있는 기능상의 차이를 사용자 인터페이스 구현의 관점에서 이해하고 있나요?
16. 4GL 개발툴의 중심에는 파워스크립트가 있습니다. 이 파워스크립트의 강력함을 제대로 설명할 수 있나요?
17. 파워스크립트 페인터에서는 파워스크립트를 사용하여 이벤트 스크립팅을 할 수 있습니다. 파워스크립트 페인터의 구성에 대해서 전반적으로 이해하고 있나요?
18. 파워바와 페인터바의 기능상의 차이점을 설명할 수 있나요?
19. 배열을 선언하는 방법과 배열을 처리하는 방법을 이해하고 있나요? 그리고 배열의 크기를 가변적으로 설정하는 동적배열의 구현에 대해서 알고 있나요?
20. 배열의 초기화를 이해하고 있나요? 그리고, UpperBound() 함수 등 배열에 관련된 함수들에 대해서 이해하고 있나요?
21. 파워스크립트 언어는 강력한 스트링 처리를 구사하고 있습니다. 파워스크립트언어가 지원하는 Mid(), Left(), Pos(), Right() 등의 스트링 함수들에 대해서 이해하고 있나요?
22. 파워스크립트는 스트링의 결합연산자로서 +를 제공하고 있다. + 연산의 편안함을 얼마나 잘 인식하고 있나요?
23. sqlca 변수 중에서 sqlcode의 값에 대해서 어떻게 처리하고 있는지 알고 있나요?
24. 파워스크립트가 제공하는 제어문에는 어떤 종류가 있으며 각각의 기능상의 특징을 이해하고 있나요?
25. CONTINUE 문장은 루프 수행 도중 나머지 문장을 스킵하고 다음 루프로 갑니다. 이 CONTINUE 문장의 중요성을 알고 있나요?
26. 파워빌더는 프로그래머가 정의하여 사용할 수 있는 오브젝트 레벨의 사용자 정의 함수를 제공하고 있습니다. 오브젝트 수준에서 정의하는 사용자 정의함수를 만들어 사용할 수 있나요?
27. 파워빌더의 전역함수 작성을 이해하고 있으며 전역함수의 사용상의 특징을 알고 있나요?
28. 함수나 이벤트 스크립트에서 RETURN 문과 Return 코드에 대해서 정확하게 이해하고 있나요?
29. 파워빌더는 700여 개가 넘는 내장함수를 제공합니다. 이 함수들 중 중요한 함수들을 선별할 수 있으며 이들을 어떻게 사용하는지 구체적으로 그 용법에 대해서 자세히 알고 있나요?
30. 파워스크립트를 디버깅할 때 사용하는 디버거에 대해서 이해하고 있나요? 특히, Breakpoint 설정에 대해서 정확하게 알고 있나요?
31. 메뉴 오브젝트를 만들 수 있으며 만들어진 메뉴를 윈도우 오브젝트에 결합하는 방법을 알고 있나요?
32. 메뉴 오브젝트의 프로퍼티의 하나로서 Style 탭의 Shift Over에 대해서 이해하고 있나요?
33. 전역 구조체를 만들 수 있으며 파워스크립트에서 구조체를 사용하는 방법을 알고 있나요?
34. Open() 함수의 패러매터로 구조체를 넘기는 방법을 이해하고 있나요?
35. 오브젝트 레벨의 구조체와 오브젝트 레벨의 함수의 기능상의 제약에 대해서 알고 있나요?
36. 다섯 가지 유형의 사용자 오브젝트에 대해서 이해하고 있으며 제작방법을 알고 있나요?
37. 비주얼 사용자 오브젝트와 넌비주얼 사용자 오브젝트의 차이점을 알고 있나요?
38. 컨트롤이나 오브젝트에 사용자 이벤트를 새로 등록하는 방법을 알고 있나요?
39. 데이터베이스 프로파일의 기능을 이해하고 있나요?
40. ODBC 연결방법보다 빠른 Native 연결방법을 이해하고 있나요?
41. 데이터베이스를 생성하는 방법과 이를 위한 툴을 알고 있나요?
42. 데이터베이스에서 프라이머리 키와 포린키의 중요성과 차이점을 이해하고 있나요?
43. 데이터베이스 검색 속도를 향상시키기 위해서 인덱스를 설정하는데 이 인덱스의 효과적인 설정에 대해서 이해하고 있나요?
44. SELECT, INSERT, UPDATE, DELETE, CONNECT 등의 SQL 문장의 사용에 대해서 얼마나 잘 이해하고 있나요?
45. 데이터윈도우 컨트롤과 데이터윈도우 오브젝트의 상관관계를 알고 있으며 데이터윈도우의 개념을 명확하게 설명할 수 있나요?
46. 데이터윈도우 페인터를 사용하여 데이터윈도우 오브젝트를 만들고 관리할 수 있는 방법을 알고 있나요?
47. 데이터윈도우를 만들 때 설정하게 되는 데이터윈도우 소스와 프리젠테이션 스타일에 대해서 유형별로 구별하여 이해하고 있나요?
48. 데이터윈도우 오브젝트를 만들 때 일반적으로 가장 많이 쓰이는 것이 SQL Select 데이터소스입니다. 이 SQL Select를 자신 있게 사용할 수 있나요?
49. 데이터윈도우 오브젝트를 만들 때 일반적으로 가장 많이 쓰이는 것 프리젠테이션 스타일로 테뷸러(Tabular)와 프리폼(Freeform)이 있습니다. 이 두 가지 유형의 프리젠테이션 스타일을 어떨 때 사용하는지 구별해서 알고 있나요?
50. 데이터윈도우 오브젝트에 얹어서 사용할 수 있는 계산필드 (Computed Field) 또는 계산 오브젝트(Computed Object)의 사용법을 알고 있나요?
51. 계산필드(Computed Field) 또는 계산 오브젝트(Computed Object)의 Expression에서 사용할 수 있는 데이터윈도우 페인터 함수(또는 데이터윈도우 오브젝트 함수)의 종류별 사용법을 알고 있나요?
52. Average,Count,Page 번호, Sum, Today를 구하기 위해 Computed Field를 사용한다는 것을 알고 있나요?
53. 데이터윈도우 오브젝트의 작업영역이 헤더밴드,디테일밴드,서머리밴드,푸터밴드로 나뉘어지며 이 밴드 각각의 영역별 기능에 대해서 알고 있나요?
54. 데이터윈도우 페인터에서 데이터윈도우 오브젝트 위에 배치할 수 있는 컨트롤 오브젝트가 무엇무엇이 있으며 이들의 유형별 사용법을 알고 있나요?
55. 데이터윈도우 오브젝트 위에 배치할 수 있는 오브젝트들 중에서 가장 중요한 오브젝트가 컬럼 오브젝트(Column Object)입니다. 이 컬럼 오브젝트는 데이터윈도우 오브젝트 속의 오브젝트라 하여 일명 복합 오브젝트(Composite Object)를 구성합니다. 이 컬럼 오브젝트의 기능에 대해서 얼마나 잘 알고 있나요?
56. 데이터윈도우 페인터에서 컬럼 오브젝트의 Edit 탭에 있는 Style Type에는 크게 여섯 가지가 있습니다. 이들 각각에 대해서 유형별 사용법을 정확히 알고 있나요?
57. 컬럼 오브젝트의 Sytle Type 중 Edit 스타일에서 Limit, Auto Selection, Display Only, Showfocus Rectangle,Password, Required의 프로퍼티들 각각에 대해서 정확하게 사용법을 알고 있나요?
58. 컬럼 오브젝트의 Sytle Type 중 Edit 스타일에서 Code Table의 사용법과 이에 상응하는 Validate 프로퍼티의 사용법을 알고 있나요?
59. Code Table에서 데이터값과 디스플레이값의 차이점과 각각의 사용법을 알고 있나요?
60. 컬럼 오브젝트의 Sytle Type 중 EditMask 스타일에서 Mask 설정법을 알고 있나요?
61. 컬럼 오브젝트의 Sytle Type 중 EditMask 스타일에서 Auto Skip 프로퍼티의 기능을 알고 있나요?
62. 컬럼 오브젝트의 Sytle Type 중 DropDownDataWindow 스타일에서 Allow Editing, Always Show List, Always Show Arrow, Lines In DropDown, Width of DropDown의 프로퍼티들 각각에 대해서 정확하게 사용법을 알고 있나요?
63. 컬럼 오브젝트의 Sytle Type 중 RadioButtons 스타일에서 Columns Across 프로퍼티의 기능에 대해서 알고 있나요?
64. 사용자가 보기 쉬운 형태로 데이터를 디스플레이 해주어야 할 때 컬럼의 포맷 프로퍼티 사용합니다. 이 컬럼 오브젝트의 포맷을 원하는 대로 자유자재로 지정할 줄 알고 있나요?
65. 데이터윈도우 페인터에서 컬럼 오브젝트에 대한 검증규칙(Validation Rule)을 지정하는 방법을 알고 있나요?
66. 데이터윈도우 페인터에서 데이터윈도우 오브젝트의 밴드(Band)의 프로퍼티 중에서 Autosize Height 기능의 사용법을 알고 있나요?
67. 데이터윈도우 페인터에서 단축키를 자유자재로 사용할 줄 알고 있나요?
68. 데이터윈도우 페인터를 사용하여 데이터윈도우의 내용을 정렬(Sort)하거나 필터(Filter)하는 방법을 알고 있나요?
69. 데이터윈도우에 배치되는 컨트롤이나 오브젝트에 탭오더(TabOrder)를 지정하여 탭키를 지정된 순서로 이동하는 방법을 알고 있나요?
70. 데이터윈도우 페인터를 사용하여 데이터윈도우의 내용들 중 반복되는 값들을 한 번만 나타나도록 하는 방법을 알고 있나요?
71. 데이터윈도우 페인터의 Rows 메뉴에서 Retrieve Options의 Rows As Needed와 Rows to Disk 메뉴항목의 사용법을 알고 있나요?
72. 데이터윈도우 오브젝트가 Update가(저장이) 되도록 하려면 Update 프로퍼티를 지정해 주어야 합니다. Update Properties 설정 다이얼로그 박스의 사용법을 알고 있나요?
73. 데이터윈도우 페인터를 사용하여 데이터윈도우의 내용을 그룹(Group)짓는 방법을 알고 있나요?
74. 데이터윈도우의 네 가지 버퍼, Primary Buffer, Filter Buffer, Delete Buffer, Original Buffer 각각의 기능별 사용법을 알고 있나요?
75. 데이터윈도우의 행과 열의 아이템 상태를 얻어내고 설정하는 함수인 SetItemStatus()와 GetItemStatus() 함수의 사용법을 알고 있나요?
76. 데이터윈도우의 기본 항목인 아이템 컨트롤(또는 에디트 컨트롤)의 기능에 대해서 알고 있나요?
77. 데이터윈도우 오브젝트에서 또는 데이터윈도우 컨트롤에서 아이템 컨트롤(또는 에디트 컨트롤)에 있는 값을 얻어내는 함수 GetText()에 대해서 알고 있나요?
78. 데이터윈도우 컨트롤의 함수들 중 데이터베이스 관련 함수인 Retrieve(),Update(), InsertRow(), DeleteRow() 함수에 대해서 알고 있나요?
79. 데이터윈도우 컨트롤의 함수의 하나인 AcceptText() 함수의 기능에 대해서 알고 있나요?
80.데이터윈도우 이벤트들인 EditChanged, ItemChanged, ItemFocusChanged, RowFocusChanging, RowFocusChanged들 각각에 대해서 사용상의 차이를 알고 있나요?
81. 데이터윈도우 이벤트의 하나인 ItemChanged 이벤트에 적용되는 리턴값 0,1,2 각각의 차이점을 알고 있나요?
82. Modify() 함수와 Describe() 함수 각각의 사용법을 알고 있나요?
83. 파워스크립트 내에 SQL문장을 내장해서 코딩해 사용하는 방법을 알고 있나요?
84. 데이터윈도우를 조회용과 프린트용으로 구별해서 코딩해야 할 경우, ShareData()함수를 사용하면 편리합니다. 이 ShareData()함수의 사용법을 알고 있나요?
85. 오브젝트나 컨트롤의 함수 또는 프로퍼티를 참조해야 할 경우 도트(.)표기법을 사용합니다. 이 도트표기법을 자유자재로 사용할 수 있나요?
86. External 데이터윈도우의 사용법을 알고 있나요?
87. 전역함수를 작성하여 데이터윈도우 오브젝트 함수로 이용할 수 있습니다. 즉, 데이터윈도우 페인터에서 오브젝트의 Expression 다이얼로그 박스에서 호출해서 사용할 수 있습니다. 이 방법의 이점을 알고 있나요?
88. dw_1.Describe("Evaluate('lookupdisplay(fname)',1)") 은 dw_1 데이터윈도우의 1번 Row의 fname 컬럼의 디스플레이 값을 얻어내는 문장입니다. 이 문장을 이해할 수 있나요?
89. dw_1.Describe("Evaluate('sum(Amount)' 0)")은 데이터윈도우 오브젝트의 sum(Amount)의 값을 얻어내는 문장입니다. 이 문장을 알고 있나요?
90. 데이터윈도우 컨트롤에 대한 함수와 데이터윈도우 오브젝트의 컬럼 오브젝트 등에서 사용하는 데이터윈도우 오브젝트 함수간의 차이점을 구별할 수 있나요?
91. 데이터베이스와 관련하여 NULL 값을 처리해야 하는 문제가 중요합니다. 이 NULL 값을 처리하기 위해서 IsNULL() 함수가 중요하게 사용됩니다. NULL 값 처리에 자신을 가질 수 있나요?
92. 이벤트 스크립트를 작성할 때 EditChanged, ItemChanged, ItemFocusChanged, RowFocusChanging, RowFocusChanged 들은 dwo 패러매터를 가지고 있습니다. 이 dwo 패러매터의 기능을 이해할 수 있나요?
93. dw_1.Find("data ='" + ls_data +"'",1,dw_1.RowCount())는 첫 번째 로우에서부터 마지막 로우까지 코드가 ls_code와 같은 로우를 찾습니다. 이 스크립트 코드를 알고 있나요?
94. 데이터윈도우 버퍼와 관련된 데이터윈도우 함수로 ModifiedCount() 함수와 DeletedCount() 함수가 있습니다. 이 두 함수의 기능을 알고 있나요?
95. pbm_dwnkey 이벤트는 데이터윈도우에서 키를 처리하기 위해 사용됩니다. 이 이벤트를 사용자 이벤트로 정의해서 사용할 줄 알고 있나요?
96. 여러 로우를 한꺼번에 처리하는 방식을 멀티로우(Multi-Row) 처리 기법이라고 하며 폼 형태처럼 하나의 로우만을 처리하는 방식을 싱글로우(Single-Row) 처리 기법이라고 합니다. 이 데이터윈도우 프로그래밍 기법의 기능상 차이점을 이해하고 있나요?
97. 탭 컨트롤을 사용해서 문제영역을 구분지어 프로그래밍하는 방법에 대해서 잘 알고 있나요?
98. 트리뷰 컨트롤을 사용하여 조직내의 부서 체계를 트리 형태로 구성할 줄 알고 있나요?
99. 마스터/디테일(Master/Detail) 관계에 의한 프로그래밍을 할 줄 알고 있나요?
100. 데이터윈도우에서 특정 조건으로 데이터윈도우 내용물이 조회되도록 조회조건 (Retrival Agrument)을 거는 방법 알고 있나요?
101. 데이터베이스의 CURSOR에 대해서 이해하고 있나요? 다시 말해서, DELCARE 문, OPEN 문, FETCH 문, CLOSE 문, COMMIT 문의 순서로 데이터베이스의 레코드를 추출하는 방법에 대해서 알고 있나요?

필자가 앞에서 열거한 파워빌더 핵심정리 101은 파워빌더 입문자분들이 6개월 정도까지는 마스터할 항목들로 생각하고 숙지해 주셨으면 하고 예전에 정리했던 내용입니다. 또한 이 101가지 핵심 요소 기술들은 파워빌더 개발툴 기능의 전체상을 신속히 획득하는데 어느 정도 도움이 될 것입니다.
전체적으로 이러한 항목들을 숙지 한 상태에서 각 항목 하나 하나를 실전에서 대면하게 되면 그 때 대충 넘어가지 마시고 철저하고 꼼꼼하게 학습해 나가시기 바랍니다. 처음에 대면하게 된 내용을 대충 이해하고 넘어가면 다음에 또 마주하게 되면 다시 공부해야 합니다. 그러므로, 한 번 마주친 항목들은 철저하게 공부하셔야 합니다. 물론, 처음에 이해하기 너무 어려우면 대강의 기능적 이해라도 얻으신 후(기능적 사용을 암기해 둔 후) 서서히 그 원리와 이치를 궁리해 보셔도 됩니다. 이해가 잘 되지 않으면 암기하시고, 암기가 잘 안되시면 이해하십시오. 그리고 만약 이해도 되고 암기도 되면 이해와 암기를 모두 하십시오. 그리고 이해와 암기는 단순한 지식으로서의 암기가 아닌 프로그램 구조의 한 요소 기술로서 어떻게 역할을 하는가를 이해하시고 개발툴을 다루는 기능적 이해도 단편적 지식이 아닌 기능 사용의 절차와 과정 자체를 이해하도록 하십시오. 마법사의 경우에, 각 단계가 어떻게 해서 하나의 완전한 결과물을 만들어 내게 되는지를 이해할 필요가 있습니다. 만약 특정 요소 기술을 암기하시려면 실제 요소 기술이 어떻게 사용되어 프로그램의 구성요소로 활용되는지를 이해하셔야 합니다. 데이터윈도우의 Find()함수를 어떻게 사용하는지를 알려면 실제로 이 Find()함수가 필요하거나 사용되는 경우를 배워야 합니다. 실제로 응용되고 적용되는 사례를 통해서 공부할 때 그 효과가 있습니다. 이렇게 사례 학습을 통해 요소 기술을 공부하면 자연스럽게 암기가 됩니다. 즉, 무조건 암기하려 하지 마시고, 실제 사례를 잘 공부하셔서 자연스럽게 배우고자 하는 요소 기술을 암기하도록 하십시오.
각설하고, 이 101가지 항목에 대해서는 하나의 참고로 기억해 두시기 바랍니다. 물론, 제가 열거해 드린 101가지 항목 외에도 훨씬 더 많은 항목들이 존재할 수 있으며 나머지에 대해서는 책을 보거나 실전에서 대면했을 때 하나 하나 정리해 두시기 바랍니다.
그러나 여기서 말씀드릴 핵심 사항은 너무 많은 것을 배우려고 노력하기보다는 프로젝트에서 지금 현재 필요한 것을 철저하게 마스터하려고 노력하십시오. 단위 프로젝트에 배정된 요소 기술들을 익히고 그 다음 단위 프로젝트를 통해 새로운 기술들을 배워나가는 방식으로 비쥬얼 개발 노하우를 축적해 나가시면 됩니다. 처음부터 완벽하게 특정 지식과 기술을 마스터하기는 쉽지 않습니다. 그러나, 되도록 여러 번 마주하게 된 기술은 열심히 이해하고 암기하도록 하여 내면화(Internalization)시키도록 하십시오. 방만하고 산만하게 이것저것 모든 기술과 지식을 배우려고 힘을 분산시키지 마시고, 한 가지 한 가지 차근차근 그리고 철두철미하게 이해하고 암기해 나가도록 하십시오.
분명, 저의 방법대로 프로젝트에서 요구하는 요소 기술, 팁, 노하우 등을 차근차근 공부해 나간다면 소프트웨어 개발 프로젝트에 즐거움도 얻을 수 있으리라 생각해 봅니다. 필자는 새로운 요소 기술, 팁 그리고 노하우를 익힐 때마다 새록새록 즐거움에 잠기기도 하였습니다. 그것이 바로 프로젝트 수행의 활력이 되었고, 개발자로서 몇 년간을 지속할 수 있었던 힘이 되었습니다.
필자가 101가지 핵심정리로 요소 기술들을 열거한 것은 필자가 파워빌더를 배울 당시 무엇이 중요하고 소프트웨어 제품을 만들기 위해서는 어떤 요소 기술이 필요한지 몰랐습니다. 그리고 더욱이, 요소 기술이라는 것 자체에 대해서 전혀 알지 못했고, 요소 기술이 왜 중요한지도 몰랐습니다. 필자가 요소 기술이 필요하다는 것을 알게 되어 익히게 된 것은 1년 정도의 세월이 흐른 뒤였습니다. 되돌아 생각해보면 필자가 얼마나 어리숙했는지 알 수 있습니다. 누군가가 요소 기술의 중요성을 일러주고 가르쳐주었다면 고생을 덜 했을 테니까 말입니다. 물론, 그냥 요소 기술에 대해서 모르고 프로그램을 하다보니 오히려 요소 기술의 중요성을 더 절실하게 느끼게 된 것인지 모르지만 말입니다.
이 101가지 핵심 요소 기술을 처음부터 모두 한 번에 배우시려고 하지 마시고, 천천히 시간을 가지고 꾸준히 배우도록 하십시오. 그리고 이해가 잘 안가면 선임자나 동료 개발자에게 물어서라도 아시고 넘어가세요. 사실, 기능적인 것은 되도록 암기하시고, 스크립트로 작성해야 할 코드 부분은 먼저 이해를 하시고 암기하도록 하십시오. 그리고, 101가지 핵심정리를 항상 염두해 두시고, 이외에도 유용하다고 생각되는 요소 기술은 익혀두시기 바랍니다. 이와 같이, 핵심 요소 기술을 미리 알아 둔 상태로 요소 기술의 전체를 본 후 그 다음 요소 기술 하나 하나를 이해하고 알아나가는 것이 유익함을 아실 것입니다. 물론, 비주얼 베이직, 델파이 그리고 C++ 및 Java 언어에도 모두 해당합니다.
그리고, 처음에 이해가 안된다고 너무 걱정하시지 마시고, 천천히 익혀나가도록 하십시오. 시간을 들이고 공을 들이면 자연히 알게 됩니다. 그러므로 너무 조바심 내시면서 걱정할 필요가 없습니다. 필자도 요소 기술을 배우기 위해서 3년을 바쳐야 했고 지금도 가끔씩 요긴한 요소 기술을 대면하기도 합니다. 하지만, 분명한 것은 자주 대면하는 요소 기술은 반드시 익혀두도록 하십시오. 여유를 갖고 게으르지 않는 것이 중요합니다. 세상살이가 그렇듯 양면성을 잘 이해하고 잘 체득해 나가는 것이 중요합니다. 너무 많이 알려고 해도 안되고 너무 알려고 하지 않아도 안되고 말입니다. 중요한 것은 여러분의 프로젝트를 통해서 여러분 스스로의 학습모델과 학습태도를 익히시도록 하십시오.

4. 프로젝트에서 대면하게 되는 새로운 요소 기술, 팁 그리고 노하우들을 하나 하나 기록하고 정리하여 여러분의 지식체계로 발전시키십시오.
필자가 처음 개발툴을 배웠을 때는 개발툴을 연마하는 데 필요한 요령 같은 것을 많이 전수 받지도 못했고 또한 필자가 이를 중요하게 생각하고 물어보려고 하지도 않았고 해서 요령이나 비결을 놓쳐 버렸습니다. 다름아니라, 프로젝트 수행시 새로운 요소 기술이나 팁 및 노하우를 접하게 되면 그것을 순간순간 기록해 놓고 정리하는 일입니다. 이러한 기록과 정리를 하지 않아 많은 세월 동안 자주 직면하는 프로그래밍 기법들과 노하우들을 매 번 다시 공부해야 하는 우를 범하곤 하였습니다. 지금 제가 다시 특정 개발툴을 공부한다면 결코 새로운 요소 기술과 팁 그리고 노하우 등을 정리하는 것을 게을리 하지 않을 것입니다.
회사의 중요한 기밀이 아니라면 자신의 노트에 기록하여 정리해 두는 것이 중요합니다!
여기서는 즉각적인 노트(Instant Note) 방법에 대해서 소개합니다. 여러분이 개발툴을 사용해서 프로그래밍을 하다 보면 순간순간 새롭게 알게 되는 소프트웨어 기법이나 팁 등을 대면하게 될 것입니다. 그리고 프로그램의 오류를 고치다 보면 다양한 해법이나 좋은 아이디어를 얻게 되기도 합니다. 이러한 정보들을 그냥 잃어버리지 말고 기록해 둘 필요가 있습니다. 연필을 사용해서 종이에 기록하면 손이 가게 되고 귀찮게 됩니다. 그래서, 윈도우즈 환경이라면 메모편집기를 실행시켜 화면에 상주시켜 놓습니다. 그리고, 순간순간 알게 되는 팁이나 노하우 등을 그 메모편집기에 기록해 두는 것입니다.
Instant Note를 사용하면 프로그래밍 할 때 겪게 되는 문제와 해법 그리고 팁이나 각종 노하우를 컴퓨터 상의 메모장을 띄어놓고 작업하면서 기록해 둘 수 있습니다. 이 메모장에는 디버깅할 때뿐만 아니라 새로운 프로그래밍 기법이나 팁 등을 발견하면 "그 즉시 간단하게 정리해서" 적어둡니다. 컴퓨터 한 쪽에 항상 조그만 메모편집기를 띄어 놓는 거죠. 이렇게 메모편집기를 띄어놓고 프로그래밍 작업할 때마다 발견되는 중요한 사항과 오류대처 방법 그리고 노하우 등을 기록해 두면 하루에 2~3가지 사항 그리고 많으면 5~6가지 사항을 기록할 수 있습니다. 이렇게 한 달을 진행하게 되면 그 수가 40~50가지 이상이 됩니다. 이 Instant Note에는 요긴한 코드패턴이 기록되기도 하고, 매우 유용한 팁이 기록되기도 하며, 프로그래밍 오류에 대한 대처방법이 기록되기도 합니다. Instant Note를 매일매일 작성하다보면 한 달이면 40~50개 이상의 정보가 모여지는데, 이것을 프린트해서 시간이 날 때 읽으면 자신의 프로그래밍 실력을 확실히 공고하게 할 수 있습니다. 제가 1달 정도 이 방법을 썼는데, A4 용지로 20~30 페이지가 출력되더군요. 알고 있는 것도 새롭게 적용된 경우에 대해서는 기록해 놓았지요. 응용력이 요구되는 일반 기법도 적어두면 도움이 됩니다.
이 Instant Note의 단점은 프로그래밍 작업의 연속성을 단절시키게 되어, 작업의 흐름을 저해할 수 있습니다. 따라서, 매우 바쁠 경우 Instant Note를 가급적 간단하게 작성하는 것이 좋고, 작업이 끝나고 정리하는 것도 도움이 될 겁니다. 그러나, 시간이 허락하고 프로그래밍에 여유를 가질 수 있다면 문제가 발견되고 요긴한 기법을 인식하게 되는 그 순간순간 InstantNote로 기록해 두는 것이 좋습니다.
이 즉각적인 노트(Instant Note)는 즉각적인 메모(Instant Memo)라고 하며, 프로그램 개발 시 컴퓨터 상에 메모작성 편집기를 띄어놓고 작업을 함을 말하며 요긴한 팁이나 기법 그리고 코드패턴 및 프로그래밍 오류 대처 해결방법 그리고 각종 트러블슈팅 방법 및 새롭게 알게 되거나 잊어버렸던 프로그래밍 지식을 기록해 두는 방법입니다. Instant Note를 정의하면 프로그래밍 작업 도중에 순간적으로 생각나거나 발생한 사항을 짧은 시간에 컴퓨터 상에 상주해 있는 메모편집기를 요약 기록함을 뜻합니다.
실시간으로 노트를 기록하기 때문에 프로그래밍 작업의 흐름을 단절시키는 듯 하나, 익숙하게 사용하다 보면 매우 도움이 됩니다. 단, 주의할 점은 프로그래밍 작업에 대한 집중력을 잃지 않는 상태에서 Instant Note 방법을 사용해야 하며, 본말전도의 형태가 되어서는 안됩니다. 즉, 노트에 치중하여 본연의 프로그래밍 작업에 대한 주의를 잃어버려서는 안됩니다. Instant Note가 한 달 쌓이게 되면 매우 소중한 자신의 프로그래밍 지식이 됩니다. 시간이 날 때 Instant Memo를 출력한 결과를 가지고 산책로의 벤치에 앉아 조용히 읽고 암기해 두면 좋습니다.
Instant Note를 단편적 지식 또는 실제 프로그래밍과 분절된 지식으로 남지 않게 하려면, 문제의 발생 원인과 조건 그리고 해결 방안의 다양한 경로를 문서화해 두는 것

출처 :  프로그래머의 길, 홍릉과학출판사, 신영호


▣  Windows Forms FAQ의 구성 방법 - S/W tip - 2010. 2. 19. 10:22

웹서핑 중 저같은 초심자분들께 유용할 것 같은 생각이 들어 이렇게 링크 올립니다.
 
http://www.microsoft.com/korea/msdn/smartclient/community/wffaq/default.aspx
 

Windows Forms FAQ의 구성 방법

이 FAQ의 항목은 일련의 페이지로 구성되어 있습니다. 여러 페이지로 구성된 이러한 항목의 구성 방법과 항목 간의 관계는 다음과 같습니다.

Windows Forms

Windows Forms에서는 .NET Framework 1.0 및 1.1에서의 Windows Forms 응용 프로그램, System.Windows.Forms.Form 클래스, 공용 대화 상자, 일반적인 몇 가지 읽기 권장 사항을 다룹니다.

주요 관계. 폼은 컨트롤이고 컨트롤은 구성 요소입니다. 폼에 적용되지만 폼에 한정되지는 않는 정보는 컨트롤 및 구성 요소(일반)을 참조하십시오.

관련 섹션. Visual Studio와 기타 도구 및 유틸리티를 사용하여 Windows Forms를 개발 및 디버깅하는 방법은 도구를 참조하십시오.

Windows Forms 응용 프로그램과 관련된 System.Windows.Forms 네임스페이스 외부의 정보는 .NET Framework를 참조하십시오.

Visual Studio 2005 및 .NET Framework 2.0을 사용하는 Windows Forms에 대한 자세한 내용은 Windows Forms 2.0을 참조하십시오.

컨트롤 및 구성 요소(일반)

컨트롤 및 구성 요소(일반)에서는 클래스의 모양 및 동작(behavior)과 디자인 타임 문제를 비롯하여 System.Windows.Forms.Control 및 System.ComponentModel.Componen 클래스를 다룹니다. Internet Explorer에서 컨트롤을 호스팅하는 것에 대한 섹션이 포함되어 있습니다.

주요 관계. 컨트롤은 구성 요소이고 폼은 컨트롤입니다.

관련 섹션. 특정 컨트롤 및 구성 요소(예: 컨트롤 및 구성 요소에서 파생된 클래스)는 컨트롤 및 구성 요소(특정)를 참조하십시오.

모든 컨트롤에 적용되는 데이터 소스 및 데이터 바인딩은 데이터를 참조하십시오.
특정 컨트롤에 적용되는 데이터 소스 및 데이터 바인딩은 컨트롤 및 구성 요소(특정)를 참조하십시오.

컨트롤 및 구성 요소(특정)

컨트롤 및 구성 요소(특정)에서는 System.Windows.Forms.Control 및 System.ComponentModel.Component에서 파생된 클래스를 다룹니다.

주요 관계. 컨트롤은 구성 요소이고 메뉴는 구성 요소이며 ContextMenu는 메뉴입니다. 도구 설명은 구성 요소이지만 대부분의 도구 설명 질문은 특정 컨트롤과 관련됩니다.

예외. 폼은 컨트롤이지만 폼에 대한 자세한 내용은 Windows Forms를 참조하십시오. CommonDialog는 구성 요소이지만 CommonDialog에 대한 자세한 내용은 Windows Forms을 참조하십시오.

관련 섹션. 모든 컨트롤과 구성 요소에 적용되는 정보는 컨트롤 및 구성 요소(일반)를 참조하십시오.

모든 컨트롤에 적용되는 데이터 소스 및 데이터 바인딩은 데이터를 참조하십시오.

데이터

데이터에서는 모든 컨트롤에 적용되는 데이터베이스, 데이터 소스, DataSet 클래스 및 데이터 바인딩을 다룹니다.

관련 섹션. 컨트롤 및 구성 요소컨트롤 및 구성 요소(특정)를 참조하십시오.

.NET Framework

.NET Framework에서는 CLR(Common Language Runtim) 기능, System.Windows.Forms 네임스페이스 외부의 FCL(Framework Class Library), Windows Form 응용 프로그램에 제한되지 않고 모든 .NET Framework 응용 프로그램에 적용되는 문제 등을 다룹니다.

관련 섹션. System.Windows.Forms 네임스페이스 및 Windows Forms 응용 프로그램에 대한 자세한 내용은 Windows Forms, 컨트롤 및 구성 요소(일반)컨트롤 및 구성 요소(특정) 를 참조하십시오.

System.Data 네임스페이스 및 데이터 바인딩에 대한 자세한 내용은 데이터를 참조하십시오.

Visual Studio와 기타 도구 및 유틸리티를 사용하여 .NET Framework에서 소프트웨어를 개발 및 디버깅하는 방법은 도구를 참조하십시오.

Windows Forms 2.0 응용 프로그램과 관련된 .NET Framework 2.0에 대한 자세한 내용은 Windows Forms 2.0을 참조하십시오.

도구

도구에서는 Windows Forms 응용 프로그램 및 기타 .NET Framework 응용 프로그램을 일반적으로 개발 및 디버깅하는 데 사용되는 Visual Studio 및 다른 도구와 유틸리티를 다룹니다.

관련 섹션. 디자이너에서 작동하는 컨트롤을 개발하고 디자인 타임에 컨트롤 작업을 수행하는 방법은 컨트롤 및 구성 요소(일반)에서 디자인 타임 섹션을 참조하십시오.

디자이너에서의 데이터 바인딩에 대한 자세한 내용은 데이터를 참조하십시오.

Windows Forms 2.0

Windows Forms 2.0에서는 Visual Studio 2005를 사용하는 .NET Framework 2.0의 Windows Forms와 관련된 문제를 다룹니다.

관련 섹션. .NET Framework 2.0에서 계속 사용할 수 있는 .NET Framework
1.1의 Windows Forms에 대한 자세한 내용은 Windows Forms, 컨트롤 및 구성 요소(일반), 컨트롤 및 구성 요소(특정), 데이터, 및 도구를 참조하십시오.

Windows Forms (System.Windows.Forms.Form)

일반

  • Windows Forms에 대한 간략하고 정확한 소개를 어디에서 확인할 수 있습니까?
  • 폼을 위한 기본 단추를 설정하는 방법은 무엇입니까?
  • 폼에서 값을 반환하는 방법은 무엇입니까?
  • VB6과 다르게 여러 폼을 작업하는 방법은 무엇입니까?
  • 폼을 인쇄하는 방법은 무엇입니까?
  • PrintPreview를 최대화된 창으로 표시하고 확대/축소를 제어하는 방법은 무엇입니까?
  • 폼의 비트맵을 캡처하는 방법은 무엇입니까?
  • 특정 폼의 TextBox를 다른 폼에서 액세스하는 방법은 무엇입니까?
  • 폼을 활성화하지 않고 표시하는 방법은 무엇입니까?
  • Windows Forms 응용 프로그램의 임의 위치에서 발생하는 예외를 파악하는 방법은 무엇입니까?
  • 폼의 시스템 메뉴에 항목을 추가하는 방법은 무엇입니까?
  • 프로그래밍 방식으로 비트맵에서 폼의 아이콘을 설정하는 방법은 무엇입니까?
  • System.Windows.Forms.Application.CompanyName에 의해 반환되는 회사 이름을 설정하는 방법은 무엇입니까?
  • 장시간 작업 도중에 상태 대화 상자를 백그라운드로 표시하고 사용자가 이를 취소할 수 있게 하는 방법은 무엇입니까?
  • 폼의 컨트롤이 읽기 전용인지 아닌지를 쉽게 관리하는 방법은 무엇입니까?
  • 사용자가 모달 대화 상자에서 다른 창을 클릭했는지 감지하는 방법은 무엇입니까?
  • 폼이나 컨트롤을 위한 HWND를 얻는 방법은 무엇입니까?
  • 폼이 작업 표시줄에 표시되지 않게 하는 방법은 무엇입니까?
  • 폼이 항상 바탕 화면에 있게 하는 방법은 무엇입니까?
  • 항상 모든 응용 프로그램의 창 위에 표시되는 모달이 아닌 최상위 폼을 만드는 방법은 무엇입니까?
  • 내 응용 프로그램에 대해서만 'TopMost'이고 다른 응용 프로그램의 경우에는 'TopMost'가 아닌 폼을 만드는 방법은 무엇입니까?
  • 여러 컨트롤에서 공용 이벤트 처리기를 공유하는 방법은 무엇입니까?

폼 및 컨트롤 만들기

  • Form 클래스의 이름에서 Form 클래스의 인스턴스를 만드는 방법은 무엇입니까?
  • 시작될 때 표시되지 않는 폼을 만드는 방법은 무엇입니까?
  • 모덜리스 대화 상자의 인스턴스가 한 번에 하나만 작성되거나 열리도록 하는 방법은 무엇입니까?
  • 런타임에 컨트롤을 Windows Form에 추가하는 방법은 무엇입니까?
  • 어셈블리 또는 DLL에서 컨트롤을 동적으로 로드하는 방법은 무엇입니까?
  • 프로그래밍 방식으로 컨트롤을 폼에 추가하고 컨트롤이 표시되도록 하는 방법은 무엇입니까?

폼 닫기 및 응용 프로그램 종료

  • Windows Form 응용 프로그램을 강제로 종료하는 방법은 무엇입니까?
  • 시스템 메뉴에서 폼을 닫았는지 아니면 Form.Close를 호출하여 닫았는지 확인하는 방법은 무엇입니까?
  • 닫기 단추를 사용자가 클릭했을 때 폼이 닫히지 않게 하는 방법은 무엇입니까?
  • 폼의 제목 표시줄에서 닫기 단추를 제거하는 방법은 무엇입니까?
  • 폼을 사용자가 닫을 때 확인 대화 상자를 표시하는 방법은 무엇입니까?

모양

  • 테두리나 제목 표시줄이 없는 시작 화면 스타일의 폼을 만드는 방법은 무엇입니까?
  • 크기 조정 테두리가 있고 제목 표시줄은 없는 폼을 만드는 방법은 무엇입니까?
  • 폼을 투명하게 만드는 방법은 무엇입니까?
  • 사각형이 아닌 폼을 만드는 방법은 무엇입니까?
  • 테두리가 없는 폼을 만드는 방법은 무엇입니까?
  • Windows Forms에 대한 사용자 지정 스타일을 제공하여 CSS가 HTML에 제공하는 것과 비슷한 기능을 제공하는 방법은 무엇입니까?
  • Windows Forms에서 그리기 및 칠하기를 수행하는 최상의 실행 방법은 무엇입니까?
  • VB6의 선 명령 기능을 대체하는 선을 그리는 방법은 무엇입니까?
  • 모든 컨트롤이 초기화될 때까지 폼 그리기를 일시 중단하는 방법은 무엇입니까?
  • 응용 프로그램에서 XP 스타일을 지원하기 위해 EnableVisualStyles 메서드를 사용하는 방법은 무엇입니까?
  • .NET Framework 1.1을 사용하는 Windows Forms에서 XP 테마를 사용하는 방법은 무엇입니까?
  • .NET Framework 1.0을 사용하는 Windows Forms에서 XP 테마를 사용하는 방법은 무엇입니까?

레이아웃

위치, 크기 및 이동

  • 폼을 프로그래밍 방식으로 최대화 또는 최소화하는 방법은 무엇입니까?
  • 작업 표시줄을 비롯한 전체 화면을 폼으로 덮는 방법은 무엇입니까?
  • 폼을 처음 열었을 때 화면의 오른쪽 하단에서 시스템 트레이 위에 폼을 표시하는 방법은 무엇입니까?
  • 사용자가 폼을 이동할 수 없게 하는 방법은 무엇입니까?
  • 폼의 크기를 제한하거나 제어하는 방법은 무엇입니까?
  • 사용자가 폼의 크기를 조정할 수 없게 하는 방법은 무엇입니까?
  • 디자인 타임과 런타임 사이에 화면 해상도가 변경될 경우 폼의 크기를 자동으로 조정하는 방법은 무엇입니까?
  • 폼을 가운데에 놓는 방법은 무엇입니까?
  • 테두리 없는 폼을 이동하는 것을 지원하는 방법은 무엇입니까?
  • 영역 드래그 효과가 있는 테두리 없는 폼의 크기를 조정하는 방법은 무엇입니까?

커서

  • 컨트롤의 커서를 변경하는 방법은 무엇입니까?
  • Cursor 클래스를 커서(.cur) 파일로 변환하는 방법은 무엇입니까?
  • 리소스 매니페스트에서 커서를 로드 및 표시하는 방법은 무엇입니까?
  • 현재 커서를 대기 커서로 설정하는 경우는 언제이며 대기 커서가 원했던 것보다 빨리 되돌려지는 이유는 무엇입니까?

키보드

  • 키 입력을 응용 프로그램으로 보내는 방법은 무엇입니까?
  • 응용 프로그램 전체에서 키보드 메시지를 처리하는 방법은 무엇입니까?
  • 포커스를 가진 컨트롤에 상관없이 폼 수준에서 특정 키를 처리하는 방법은 무엇입니까?

MDI: 다중 문서 인터페이스

  • .NET Framework를 사용하여 MDI 응용 프로그램을 만드는 방법은 무엇입니까?
  • MDI 클라이언트 컨테이너의 배경을 변경하는 방법은 무엇입니까?
  • 자식(child) 폼을 최대화하지 않고 전체 MDI 클라이언트를 자식(child) 폼으로 채우는 방법은 무엇입니까?
  • MDI 응용 프로그램에서 자식(child) 폼이 활성화될 경우 Activated 이벤트가 일관되게 발생하지 않는 이유는 무엇입니까?
  • MinimumSize 및 MaximumSize 속성이 작동하지 않을 경우에 MDI 자식(child) 폼의 크기를 제한하는 방법은 무엇입니까?
  • 자식(child) 폼의 인스턴스가 여러 개 만들어지지 않게 하는 방법은 무엇입니가?
  • MDIContainer 폼에서 MDI 자식(child) 폼이 추가되거나 제거될 경우 사용자 지정 처리를 수행하는 방법은 무엇입니까?
  • MDI 컨테이너에서 사용자 지정 그리기(예: 로고)를 수행하는 방법은 무엇입니까?

공용 대화 상자(System.Windows.Forms.CommonDialog)

  • OpenFileDialog를 사용하는 방법은 무엇입니까?
  • FolderBrowser 인스턴스가 처음 열렸을 때 이 인스턴스의 경로를 지정하는 방법은 무엇입니까?
  • 폴더 브라우저 클래스를 구현하는 방법은 무엇입니까?
  • FontDialog 클래스를 사용하여 컨트롤의 글꼴을 설정하는 방법은 무엇입니까?
  • ColorDialog를 사용하여 색을 선택하는 방법은 무엇입니까?

리소스

  • Windows Forms 프로그래밍과 관련 주제에 대한 읽을 만한 책들에는 어떤 것들이 있습니까?

▣  DLL HELL - S/W tip - 2010. 1. 20. 15:04

DLL 지옥(영어: DLL hell)은 마이크로소프트 윈도 기반의 프로그램에서 DLL을 사용할 경우 발생할 수 있는 복잡성을 뜻하는 말이다. 이 용어는 릭 엔더슨(Rick Anderson)이 2000년 1월에 발표한 〈DLL 지옥의 종말(The End of DLL Hell)〉 이라는 문서를 통해 대중에 소개되었다. 그 전에는 잠시 동안 마이크로소프트 내부에서 사용됐었다.

DLL 지옥은 DLL을 관리할 때 발생할 수 있는 모든 문제를 뜻한다. 여기에는 DLL 버전 충돌 문제, 프로그램이 의존하는 DLL 파일을 찾을 때의 어려움, 불필요한 DLL 파일 복사본이 만들어지는 문제 등이 포함된다.

DLL 지옥은 잠재적인 운영 체제 설계 결함의 한 예이다. 이 결함으로 인해 잘 작성된 프로그램도 문제를 일으킬 수 있는데, 이는 허술하게 작성된 프로그램의 나쁜 프로그래밍 습관이나 버그로부터 영향을 받을 수 있고, 이를 운영체제가 묵인하기 때문이다.

목차

[숨기기]

[편집] 문제점

DLL을 사용하다 보면 많은 문제들에 마주치게 되는데, 이는 특히 시스템에 많은 프로그램을 설치한 후 제거한 상황이라면 더욱 두드러진다. 이중 가장 일반적이면서도 까다로웠던 문제는 시스템 DLL이 다른 버전의 DLL로 덮어 써져서, 일부 애플리케이션이 동작하지 않게 되는 경우였다. 마이크로소프트에서 'DLL 스탐핑(DLL Stomping)'이라고도 부르는 이러한 DLL 덮어쓰기 문제는 윈도 2000을 통해 소개된 윈도우 파일 보호(Windows File Protection, WFP)[1] 기능을 통해 대부분 해결되었다. WFP이 있기 전에는 다음과 같은 원인들 때문에 DLL 호환 관련 문제가 발생했었다:

  • 의무적인 표준 DLL 버전 관리 방식과 이름 짓기, 파일 시스템 위치 스키마가 없었다는 점.
  • 의무적인 표준 소프트웨어 설치 방법이 없었다는 점
  • DLL 애플리케이션 이진 인터페이스 관리를 위한 중앙 집중적인 권위 있는 지원이 없었다는 점.
  • 파일 이름이 같은 서로 호환되지 않는 DLL들을 허용할 수 있는 안전 장치가 없었다는 점.
  • 배포되는 버전 구별을 위한 내부 버전 번호가 없었다는 점.
  • 사용자가 의심스러운 DLL을 복사하거나, 기존의 DLL을 변경하는 것을 예방하는 간단한 관리 도구조차 없었다는 점.

DLL 호환 문제 해결을 위한 '병렬식 컴포넌트 공유(Side-by-Side Component Sharing)'[2] 같은 일부 예방 기법은 DLL의 복사본을 만들고, 각 버전의 DLL들이 필요에 따라 따로 메모리로 올려지도록 하기 때문에, DLL 공유에 따른 메모리 절약 효과가 감소하게 된다. 또한 버그 수정과 보안 업데이트 시에도 복잡성 증가 등의 영향을 받게 된다.

[편집] 사례들

DLL 지옥은 위에서 보는 것처럼 윈도 2000 이전에는 매우 일반적인 현상이었다. DLL 지옥의 주요 원인은 운영 체제에서 DLL 설치에 대해 어떠한 제한도 하지 않았다는 점이다. 운영 체제는 단지 애플리케이션 설치 프로그램이 항상 올바르게 동작하기를 바랬으며, 시스템 DLL을 덮어 쓰기 전에 DLL의 버전을 확인해야 하는 것도 설치 프로그램의 몫이었다. 애플리케이션의 설치를 단순화하는 표준 도구 프로그램들은 마이크로소프트와 기타 업체들에 의해 제공되었다. 마이크로소프트는 자사 로고의 사용 승인을 받길 원하는 소프트웨어 벤더들에게 먼저 표준 인스톨러를 사용하여 올바르게 동작하는 보증된 설치 프로그램을 만들 것을 요구하기도 하였다. DLL 설치에 대한 이러한 접근 방법은 그리 큰 해결책은 되지 못했으며, 사용자는 인터넷의 인기에 따라 올바른 설치 프로그램을 가지지 않는 애플리케이션을 접할 기회가 점점 더 많아져 갔다.

제임스 도널드(James Donald)는 자신의 2003년도 문서 〈공유 라이브러리의 개선된 이식성(Improved Portability of Shared Libraries)[3]〉에서 DLL 지옥이 마이크로소프트 윈도보다는 리눅스에서 더 심각하다고 주장하였다. 여러 리눅스 배포판들은 자신의 배포판에 맞춰 패키징되지 않은 소프트웨어라이브러리를 업데이트하는데 있어 문제를 앓고 있는데, 이는 일부 오픈 소스 라이브러리가 버전이 바뀜에 따라 API를 변경하는 경우도 있기 때문이다. 윈도 환경이 아닌 다른 곳에서는 이 문제를 의존성 지옥이라 부른다. 그러나 이것과 DLL 지옥을 혼동해서는 안된다. DLL 지옥은 의존성 지옥의 한 형태일 뿐이다.

마이크로소프트 윈도, 리눅스, 맥 오에스 텐을 통틀어 의존성 지옥에 대한 최근의 사례를 든다면 모질라 프로젝트에서 사용하는 게코 런타임 엔진(Gecko Runtime Engine, GRE)을 꼽을 수 있다. 모질라 재단이 발표하는 모든 소프트웨어 제품은 각각 자신만의 게코 런타임 엔진을 포함하는데, 이는 프로그래밍 인터페이스가 서로 충돌할 수 있는 환경이기 때문이다. 따라서 만약 사용자가 썬더버드, 파이어폭스, 썬버드를 설치하게 된다면, 사용자의 시스템에는 세 개의 GRE가 복사되게 된다. 이 세 개의 GRE는 언제 GRE의 소스 트리로부터 갈래되었는지에 따라 서로 호환될 수도, 호환되지 않을 수도 있다. 에피퍼니(Epiphany) 같은 모질라 재단 밖의 프로젝트는 GRE를 사용하기 위해 특정 버전의 모질라 스위트(Mozilla Suite)에 의존하는데, 이 경우 버전이 틀려지게 되면 동작하지 않게 된다. 반면에 엔뷰(Nvu) 같은 프로젝트는 자신만의 GRE 복사본을 사용한다.

[편집] 대응 수단

DLL 지옥을 피하는 데에는 여러 방법이 알려져 있으며, 이들 모두를 동시에 사용하면 최적의 효과를 얻을 수 있다:

  • 레지스트레이션-프리 COM: 윈도 XP는 '레지스트레이션-프리 COM(Registration-free COM, 등록이 필요없는 COM)'이라 불리는 새로운 COM 오브젝트 등록 모드를 소개하였다. 이 기능은 닷넷의 발표와 맞물려 소개되었기 때문에 그리 잘 광고되지는 않았다. 레지스트레이션-프리 COM은 애플리케이션이 COM 오브젝트들을 설치할 때 COM 등록에 필요한 정보를 전역적인 레지스트리가 아닌 자신의 디렉터리에 저장하여 사용할 수 있도록 한다. 엄밀히 말해 이 기능은 해당 COM 컴포넌트들을 단일 애플리케이션에서 사용할 경우에만 적용이 가능하다. 이 기능을 통해 각 애플리케이션은 자신에게 필요한 버전의 COM DLL을 설치하여 사용할 수 있는데, 이 결과로 시스템에는 특정 DLL에 대한 다양한 버전의 DLL 파일들이 존재하게 된다. (마이크로소프트에서는 이를 '병렬식 어셈블리(Side-by-side Assemblies)'[4] 라 부른다.) 레지스트레이션-프리 COM 을 사용하면 대부분 DLL 지옥을 피할 수 있다. 다만 최소 윈도 XP 또는 그 이상의 상위 버전의 OS가 필요하며, EXE COM 서버 및 시스템 전역적인 컴포넌트들 즉 MDAC, MSXML, 다이렉트X인터넷 익스플로러 등에는 사용할 수 없다.
  • DLL 파일들의 의존성을 추적 및 관리할 수 있는 패키지 관리 시스템을 운영 체제에 포함하여, 사용자에게 패키지 관리 시스템의 사용을 장려하고, 수동으로 DLL 파일을 설치하지 말 것을 권고한다.
  • 라이브러리 배포에 대한 사항을 중앙에서 집중 관리할 수 있는 시스템을 마련하고, 라이브러리를 변경하려면 이 시스템을 통하도록 한다; 이를 통해, 여러 버전의 소프트웨어에 대해서도 서로 호환성이 유지되도록 할 수 있다. 예를 들어 만약 특정 하위 버전의 소프트웨어가 현재의 라이브러리와 서로 호환되지 않는다면, 그 소프트웨어를 위해 시스템은 호환 가능한 인터페이스를 제공하거나, 적절히 격리된 형태로 해당 소프트웨어가 요구하는 버전의 패키지를 공급하도록 할 수 있다.
  • 만약 소프트웨어 개발에 있어 라이브러리의 수정이 불가피하다면, 이 라이브러리의 DLL을 프로그램의 개인적인 공간 즉 프로그램 디렉터리 같은 곳에 두거나, 라이브러리를 프로그램에 정적으로 링크하여 컴파일하도록 한다.
  • 적절한 소프트웨어 디자인 방법을 따른다. DLL은 시스템의 구성 요소들을 모듈화하여 별개의 라이브러리로 만드는 훌륭한 방법이다; 그러나 모든 경우에서 항상 사용해야 하는 것은 아니다. 예를 들어 만약 프로그램이 다른 어느 곳에서도 사용되지 않는 라이브러리를 필요로 한다면, 이를 정적으로 링크하여 용량 증가 등의 특별한 불이익 없이 실행 속도를 향상시킬 수 있다.

[편집] .NET에 대한 동기 부여로서 DLL 지옥

2002년 2월, 마이크로소프트는 대중에 닷넷 프레임워크를 공개하였다. 이 프레임워크는 어셈블리(assemblies)[5]라 불리는 새로운 버전의 패키지 배포 시스템을 포함하고 있으며, 공용 라이브러리 런타임(common library runtime)에 대한 지원을 제공한다. 공용 라이브러리 런타임에서 많은 DLL 코드가 베이스 파운데이션 클래스(base foundation class)로 이동되었다.

[편집] 같이 보기

[편집] 바깥 고리


▣  c# 간단 정리 - S/W tip - 2009. 12. 11. 12:13

   
변수
열거형-사용자가 정의한 일련의 이산적인 겂들을 가진 변수 형식, 숫자 대신 사람이 좀더 읽기 쉬운 상수들을 효율적으로 사용하기 위한것
구조체-다른 변수 형식들을 하나로 조직화하는 복합 변수 형식
배열   -한 형식의 값들을 여러 개 담을 수 잇는 형식 (색인을 통해서 개별 값들에 접근한다.)
명시적 변환 속성-구성속성-빌드-산술연산오버플로/언더플로확인 : 이것을 True로 바꾸면 unchecked를 명시적으로 지정하지 않는한모든
표신식에서 오버플로 점검한다.
. Convert.ToBoolean(val), Convert.ToByte(val), Convert.ToChar(val), Convert.ToDecimal(val), Convert.ToDouble(val)
  Convert.ToInt32(val) - int로 변환
문자열조작 "<string>.TrimStart()   :  문자열의 앞이나 뒤 중 한 쪽의 빈칸들만 제거하려 할 때
<string>.TrimEnd()"
"<string>.PadLeft()    : 문자열 앞.뒤에 추가적인 빈칸들을 채우는 명령
<string>.PadRight()"
<string>.Split() : 하나의 문자열을 구분 문자들을 기준으로 나워서 string배열로 만들어준다.(기준이 되는 구분문자는 char배열로지정)
변수의Default값 정수타입        :0
부동소수 타입:0.0
char              : null문자(\u0000)
decimal         :0.0
bool               :false
조건문 <<  IF 문의 형식  >>

if(조건식)
   문장
else
  문장
---------------------
if(조건식){
   문장
}else{
  문장
}
  <<  switch문의 형식  >>

switch(표현식)
{
  case constant1:
      명령문
      break;
  case constant2:
      명령문
      break;
  default:
      명령문
      break;
}
반복문 << while문의 형식>                         <<do while 문의 형식>>

while(조건식){문장}                        do{문장}
                                                      while(조건식);
private사용하는 이유 1. 클래스 내부에서만 사용하기 위해서
2. 외부에서 들어오는 데이터라 할지라고 직접적인 할당보다는 간접적으로 할당하기 위해서
new Family sister = new Family()의 분석
Family    : 클래스로 생성한 데이터 타입
sister     : Family 데이터타입으로 선언한 변수
new       : 메모리를 생성하는 연산자
Family() : 메모리 생성 후 초기화 작업을 담당하는 생성자
=> 클래스를 이용하여 만든 변수를 다른 변수들과 구분하기 위해Object또는Instance라는 용어를 사용
ref와 out키워드 ref : 참조할 변수는 반드시 초기화되어 있어야 한다.
out : 참조할 변수가 반드시 초기화될 필요는 없다.
<상수>
const 키워드
. 상수를 선언하는 키워드
. Const로 선언한 변수는 반드시 초기화 되어야 한다. - 초기화되어 있지 않다면 한번 설정되면 바꿀수 없다는 상수의 법칙에 위배
. Const는 자동으로 static 이 된다.
<상수>
readonly키워드
. Static 키워드를 사용하면 static 상수가 된다. 사용하지 않으면 일반 상수가 된다.
. 반드시 초기화 할 필요는 없다.
.
Static readonly일 경우 스태틱 생성자에서 초기화할 수 있다.(횟수제한-> 한번만 가능)
   - 상수의 기본 성질인 중복해서 값을 설정할 수 없다는 것이 포인트

. 일반 readonly일 경우 생성자에서 초기화 할 수 있다.
. Static readonly일 경우 클래스의 이름으로 접근가능
. 일반 readonly일 경우 객체의 이름으로 접근가능
static static으로 선언된 필드나 메서드는 스태틱이라고 하는 특수한 메모리 영역에 단 하나의 메모리가 생성되기 때문에 클래스 전체에
공유가능 
스태틱 특성상 객체를 생성하지 않고 클래스의 이름으로 해당 상수에 바로 접근가능하다.
열거형 (Enum/Enumeration)
. 이름을 가지는 정적 정수형 상수이다.
. 상수이므로 값이 한번 설정되면 변경할 수 없다.
. 열거형의 멘버들의 초기값은 0부터 자동으로 1씩 증가한다. 만약 중간에 임의의 값이 설정된 곳부터는 해당 값을 1씩 증가시켜 할당
  (순차적인 숫자 값을 가져올 경우 현변환 필수겠죠)
. 열거형에서 사용할 수 있는 형 =><<   byte, sbyte, short, ushort, int, unit, long, ulong  >>
네임스페이스와어셈블리 . 진입점을 포함하는 형태의 실행파일(.exe)
. 진입점을 포함하지 않는 라이브러리 형태의 파일(.dll)
. [참고]exe나 dll 은 모두 중간언어(IL) 형태로 되어 있다.
Main()메서드의 특징 . 프로그램의 시작점이다.
. Main() 메서드가 끝나면 프로그램은 종료한다.
. 반환형은 void나 int 둘 중의 하나이어야 한다.
. Main() 메서드에서 객체를 생성하거나 다른 메서드를 호출할 수 있다.
. 명령프롬프트 상의 매개변수를 읽기 위해서 string배열을 사용한다.
Static 멤버필드 . 모든 클래스에서 공유하기 위한 멤버를 선언하는 데 사용
. 변수, 메서드, 속성,연산자 및 생성자에 사용할 수 있음
. 인덱서 , 소멸자에는 사용할 수는 없음
. 클래스 내의 모든 곳에서 사용할 수 있는 공유변수
Static 멤버메서드 . Public static 메서드일 경우 객체를 생성하지 않고 클래스의 이름으로 접근가능
. 객체를 생성하지 않고도 사용할 수 있는 공유 메서드
. 스태틱 메서드를 이용하여 일반 멤버필드에 접근 불가
. 일반 멤버필드는 객체 생성 후에 존재하기 때문에 스태틱 메서드에서는 접근 불가
Main()메서드가
static인 이유
C#에서는  Main()메서드를 실행할때 CLR 에서 실행 클래스의 객체가 생성되기 전에 접근해야 하기 때문에 스태틱으로 선언
오버로딩(Overloading) . 하나의 클래스 내에서 동일한 이름을 가진 여러 개의 메서드
. 메서드들의 구별은 메서드의 매개변수의 개수와 매개변수의 형에 의행서 구분
. 리턴타입(Return Type)으로는 구별하지 않는다.
오버로딩규칙 . 매개변수의 개수가 달라야 한다.
. 매개변수의 타입이 달라야 한다.
. 위의 개수와 다입중 하나만 달라도 오브로딩의 조건이 성립된다.
. 메서드이 리턴타입은 오버로딩을 구분할 때 사용하지 않는다.
상속(Inheritance) . 계층구조 형태로 클래스들을 생성시키는 방법
. 상위클래스를 기본 클래스라고 하며 하위클래스를 파생클래스라고 한다.
. 상속을 하면 상위클래스의 능력을 하위클래스에서 모두 이용할 수 있다.
Inheritance특징 . 생성자는상속되지 않고 하위클래스의 객체가 만들어질 때 상위클래스의 생성자가 자동으로 호출된다.
. 클래스는 중복상속할 수 없으며 단일 상속만 가능하다.
sealed키워드 . Sealed키워드는 클래스로부터의 상속을 막을 때 사용
Constructor의 특징 . 생성자는 리턴타입(Returm Type)이 없다.
  - ( 이유 : new 연산자가 메모리를 생성한 후 해당 메모리의 참조값을 객체변수에게 리턴해 버리기 때문에 생성자는 리턴이 없고 초기화만 담당  )
. 생성자의 이름은 클래스의 이름과 동일하다
. New 연산자가 힙(Heap)영역에 해당 클래스의 메모리를 생성한 직후 호출된다.
. 생성자는 말 그대로 객체가 생성될 때 호출되는 메서드입니다. 객체를 생성하는 순간에 함께 함께 호출될 수 있다는 장점이 있다.
   
소멸자(Destructor) . 객체가 소멸되기 전에 호출되어 객체에 부여된 메모리의 회수를 담당
. 실제적으로 메모리의 호수 여부는 Garbage Collector가 담당한다.
. 매개변수와 접근 제한자를 가질 수 없다.
<<  4.9  protected 접근자  >>  
디자인타임의접근문제 상속받아서 코딩하고 있는 순간, 상속을 받아서 하나의 새로운 클래스를 제작하고 있는 순간,
 하위클래스 입장에서 상위 클래스의 접근 문제를 다룬다.
상속 관계에서의 private .  상위클래스를 상속받은 하위클래서 내에서 상위클래스의 private멤버필드에 직접 접근할 수 없다.
. 어떠한 경우라도 private이면 public메서드를 통해서만 접근 가능하다.
상속 관계에서의
protected
. 아버지의 protected 멤버는 실행타임에선 private이면서 아들에게는 완전한 public이 된다.
  -모든 면에서 private을 수행하면서 상속의 관계에서만 public의 행위를 하는 것이 바로 protected 이다.
Internal접근자 . Private과 public의 중간 형태로 한의 Assembly 내에서만 접근을 허락하는 접근자
. 같은 어셈블리(즉 같은 프로그램 내) 안에 있어야 접근 가능하다.
메서드 재정의 종류 . new 키워드를 이용한 재정의
. Virtual, override 키워드를 이용한 재정의
Upcasting(업케스팅) . 정의 - 하위 클래스의 객체를 상위클래스의 객체로 형변환한 것
. New 키워드를 이용하여 메서드를 재정의한 후 업캐스팅 했을 때
 - 업캐스팅 되었을 때 상위 클래스는 상위클래스 내의 메서드만을 호출한다.
virtual,override,new의
관계
. Virtual : 하위 클래스에서 재정의해서 사용할 것을 표시
. Override : 상위클래스에서 virtual로 표시된 메서드를 재정의할 때 사용
. New : 상위클래스의 메서드를 완전히 무시할 대 사용
this를사용하는 곳 . 자신을 참조하는 this를 이용하여 멤버를 이용할 수 있다.
.  디자인타임에 자기 자신을 직접 참조할 수 있는 참조변수이다.
.  디자인타임에 자기 자신을 참조할 수 있는 유일한 키워드이다.
- 디자인타임에 하나의 이름으로 자시능ㄹ 참조하고 실행 타임에서는 각각에 적용
this.멤버 . 지금은 클래스 내부의 this이지만 언젠가 생성될 내 메롬리의 this라고 해석할 수 있다.
  즉 , 언젠가 생성될 메모리의 참조값이 되는 것입니다.
자신의 멤버를
가르키는 this
. 메서드의 매개변수와 클래스의 멤버필드를 구분해 주어야 할 때 사용
. This키워드를 사용하지 않아도 무방
this() . 자신의 생성자를 호출할 때도 사용
. 자신의 생성자를 재사용하기 위새서 생성자를 호출하는 방법을 제공
base() 키워드 . 디자인타임에 아버지를 참조하는 유일한 참조변수이다.
. 무시당한 아버지클래스의 메서드를 사용하고 싶을 때 사용한다.
. 아버지 생성자에 매개변수가 존재한다면 생성자의 매개변수의 형과 개수를 맞추어 주어야한 호출이 가능
. 생성자 내에서 아버지 생성자를 호출하기 위해 사용
Boxing // UnBoxing . 박싱(Boxing) : 값타입을 참조타입으로 변환하는 기법
. 언박싱(UnBoxing) : 참조타입을 값타입으로 변환하는 기법
Boxing의 순서 . 값타입 변수를 객체화하기 위한 메모리를 Heap영역에 생성한다. 이공간을 Box라고 한다.
. P 에 있는 값을  Heap에 생성한 Box로 복사
. 참조타입 변수 o에 Box의 참조값을 할당
예>  int p = 123;
       object o = p
UnBoxing의 순서 . 해당 객체가 지정한 값타입을 Boxing한 값인지 확인
. 박싱된 객체라면 객체의 값을 값타입 변수에 복사한다.
. Boxing한 메모리와 UnBoxing한 메모리 두 개가 존재한다.
추상클래스가 되는 방법 . 몸체가 없는( 메서드의 구현부가 없다는 뜻) 메서드를 하나라도 포함하고 있는 클래스
. 몸체없는 메서드를 포함하고 잇지 않더라도 클래스를 선언할 때 abstract 키워드를 포함하고 있는 경우
< 추상메서드는 묵시적으로 virtual메서드이다.>
Abstract Class
(추상클래스)
추상클래스는 객체가 가지는 특성들을 추상화시켜 놓고 구체적인 구현은 이 추상클래스를 상속받는 파생클래스에서 하도록 한것
. Abstract 키워드를 사용
. 몸체없는 추상메서드를 하나라도 포함하고 있으면 추상클래스가 된다.
. 추상클래스가 되면 반드시 클래서 선언부에 abstract 키워드를 명시해야 한다.
. 클래스를 선언할 때 클래스 앞에 abstract 키워드를 사용하면 추상메서드를 포함하고 있지 않아도 추상클래스가 된다.ㅋ
. 추상클래스는 객체(인스턴스)를 생성할 수 없다.
. 추상메서드는 묵시적으로 가상메서드(Virtual Method)가 된다.
. 추상메서드는 virtual키워드를 사용하지 않지만 자동으로 virtual이 된다.
Abstract Method
(추상메서드)
. 몸체가 없는, 몸뚱이가 없는 메서드
. 프로토타입(Prototype)만 가지고 있음
 virtual키워드가 디폴트로 포함되어 있음
Interface의 구성요소
/특징
Method, Property, Event, Indexer
. 인터페이스 내의 멤버는 모두 몸체가 없다.
. 인터페이스의 멤버는 디폴트로 전부 public이다.
. 내부에 필드를 가질 수 없다.
. 멤버에 어떠한 접근자, 한정자도 붙이지 않는다.
Interface의 멤버가
 public인 이유
. 인터페이스를 하위클래서에서 구현하기 위해서는 최소한 하위클래서에서 접근할 수 있어야 하며
  인터페이스로 외부에서 작업하기 위해서는 인터페이스의 멤버는 기본적으로 public이어야 한다.
- 인터페이스내의 멤버 앞에 abstract, public, protected, internal, private, virtual, override, static과 같은 키워드들 사용못함
Interface 메서드
구현 주의사항
. 인터페이스 멤버의 접근지정자는 자동으로 public이 된다 때문에 구현하는 클래스에서도 이와 일치시키기 위해 public을 명시
  클래스의 멤버는 접근지정자가 명시된지 않으면 private으로 지정된다.    Public void a(){…}
. 그러나 명시적으로(상속받은 인터페이스네 같은 이름의 메서드가 존재시) 구현한 메서드는 접근 지정자를 붙이지 않는다.
override . 추상클래스와 인터페이스의 추상메서는 모두 가상(virtual)메서드이 성질을 가지고 있습니다. 하지만 추상클래스내의
 추상메서드를 재정의할 때에는 override 키워드를 사용하여 메서드를 재정의하지만 인터페이스 내의 추상메서드를 재정의할
 때에는 override키워드를 사용하지 않습니다.
추상클래스와
인터페이스의 공통점
. 스스로 객체를 생성할 수 없다.
. Upcasting이 가능하다.
. 모든 추상 멤버를 구현해야 한다.
. 추상클래스와 인터페이스의 추상메서드는 virtual(가상)메서드이다.
추상클래스와
인터페이스의 차이점
. 인터페이스는 멤버의 접근지정자를 선언할 수 없다.
. 추상클래스 내의 멤버에 접근지정자를 사용해서 선언할 수 있다.
. 인터페이스는 인터페이스들 끼리의 상속과 중복구현이 가능하다.
. 추상클래스는 클래스이기 때무에 단일 상속을 원칙으로 한다.
. 인터페이스는 일반적인 멤버필드를 포함할 수 없다.
. 추상클래스는 일반적인 멤버필드나 멤버메서드를포함할 수 있다.
. 인터페이스는 멤버를 abstract키워드로 선언할 수 없다.
. 추상클래스에서 추상메서드는 abstract키워드로 명시해야 한다.
. 인터페이스의 추상메서드는 구현할 때 override를 사용하지 않지만 추상클래스에서는 override르르 사용하여 재정의 한다.
메서드 재정의에서의
업캐스팅(Upcasting)
. New 키워드를 이용한 메서드 재정의에서 나타나는 업캐스팅
  - 업캐스팅된 상위클래스의 객체는 상위 클래스 내의 메서드만을 호출한다.
  - 아들의 몸체지만 아버지의 이름이라면 아버지의 메서드만 호출할 수 있다.
. Virtual 키워드를 이용한 메서드 재정의에서 나타나는 업캐스팅
 - 상위클래스의 이름으로 메서드를 호출했을 때 해당 메서드가 재정의되어 있을 경우에만 하위클래스의 메서드를 호출할 수 있다.
 - 아들의 몸체지만 아버지의 이름으로 아들의 메서드를 호출한다.
Delegate정의 . 메서드의 대리자
. 메서드를 보다 효율적으로 사용하기 위하여 특정 메서드 자체를 캡슐화할 수 있게 만들어 주는 방법
배열의 분류 . Value Type의 배열
. Object 배열
배열의 특징 . 같은 데이터 타입의 변수를 한꺼번에 여러 개 생성할 수 있다.
. 배열의 크기는 배역의 첨자(index)로 결정된다.
. 첨자에 해당하는 만큼의 같은 데이터타입을 가진 메모리가 생성된다.
. 배열의 메모리는 연속적으로 잡히게 된다.
. 배열은  참조값(ReferenceValue)을 잉ㅇ하여 핸들링할 수 있다.
. 배열의 이름은 연속된 변수들을 참조하기 위한 참조값이다.
. 배열의 요소는 변수이다.
. 배열은 객체다.
배열의 선언 데이터형[] 변수명 = new 데이터형[첨자];
배열의 선언 및 초기화 예> 배열의 이름이 mydream이고 int형의 배열 요소를 10개 생성한다면
. 선언과 메모리 할당을 동시에   =>    int[] mydream = new int[10];
. 선언과 메모리 할당의 분리      =>    int[] mydream ;                                                     
                                                      mydream = new int[10];
배열의 선언과
동시 초기화
● int[] mydream = new int[]{100,200,300,400,500,600,700,800,900,999};
● int[] mydream = {100,200,300,400,500,600,700,800,900,999};
값타입의 배열과
객체배열의 생성시 차이점
. 값타입(Value Type)배열                                       => 배열 생성과 동시에 메모리 확보
. 객체(object)배열 , 참조타입(Reference type)배열  => 객체변수의 이름들만 생성할 뿐, 객체의 메모리는 생성되지 않음 .
  - 객체변수의 참조값 자체를 위한 메로리만 확보, 배열 요소의 메모리는 따로 생성해 주어야 함.
HashCode? 해시코드는 메모리가 생성될 때 객체에  부여되는 32bit 정수형으로 서로 다른 객체는 같은 해시코드를 부여 받을 수 없다.
따라서, 해시코드가 없다는 것은 아직 메모리가 생성되지 않았다는 것을 의미 결국, NullreferenceException이 발생
2 차원 배열 초기화 int[,] myarray = new int[3,2]
2 차원배열선언과
동시초기화

 

int[,] myarray = new int[,]{{1,2},{3,4},(5,6}};
int[,] myarray = {{1,2},{3,4},(5,6}};
참고> string[,]  saRObjId = {{sObjId[i].ToString()},{"ContentsList"}};
=================================================================
using System;
class ArrayDemo
{
 public static void Main()
 {
  string[] sid = {"a","b","c","d"};    //가변적으로 변화는 값이다
  string[,] obj = new string[sid.Length,2];

  for (int i=0; i < sid.Length ; i++)
  {
   obj[i,0] = sid[i];  //**
   obj[i,1] = "z";     //**

   for (int j=0; j < 2; j++)
    Console.WriteLine("Element({0},{1})={2}", i, j, obj[i,j]);
  }


 }
}


배열의 길이(Length)와
차원(Rank)의 수
. 배열의 길이는 배열이름.Length로 나타낸다.
. 배열의 차원의 수는 배열이름.Rank로 나타낸다.
System.Array클래스 . Public abstract class Array : Icloneable, Ilist, Icollection, Ienumerable
. 배열을 생성하고 지원하는 언어 구현의 기본적 클래스
. 배열은 기본적으로 Array클래스를 상속한다.
Array클래스의
유용한 메서드
. Array.Sort(배열) - 배열을 작은 순으로 정렬
. Array.Reverse(배열)  - 배열을 큰 순으로 정렬
. Array.Clear(배열,0,5) - 0번째부터 5번째까지 6개를 0으로 초기화
. Array.IndexOf(배열,55) - 배열의 첫부터 검색하여 55가 있는 index의 위치를 반환
. Array.LastIndexOf(배열,5) - 배열의 끝에서부터 검색하여 처음으로 5가 있는 위치를 리턴
Array클래스이 메서드 . 배열은 Array클래스를 상속받았기 때문에 Array클래스의 메서드들은 대부분static 메서드이기 때문에 클래스의
  이름을 통해서만 접근할 수 있다.
배열을 복사하는 방법 . Array.Copy() 메서드를 이용하는 방법  => 배열의 일부분 복사(부분 배열 복사)
. Clone() 메서드를 이용하는 방법          => 배열의 전체 복사 ( 배열의 메모리 차원의 복사)
Array.Copy()메서드 . 원본과 복사본 배열 객체가 존재하고 있어야 한다.
. 주로 배열의 부분복사를 위해 사용된다.
배열.Clone() 메서드 . 원본 배열의 메모리를 통째로 복사해 준다.
. Object형을 반환하므로 다운캐스팅(Downcasting)을 해주어야 한다.
foreach문 . Array이나 collection 내에 존재하는 각 요소들에 대해 접근할 수 있게 해주는 제어문
<<  형식 >>  foreach(데이터타입  변수명  in 배열명){ 실행문장 }

. 데이터타입 : foreach 문 내부에서 사용될 반복변수의 형
. 반복변수    : 컬렉션 요소의 값을 반복적으로 얻어내는 변수
. 컬렉션식    : foreach 문을 실행시킬 배열이나, 컬렉션
 
foreach문 특징 . 메모리에 저장된 순서대로 요소 값이 호출됨
. 반복변수는 오직 읽기전용으로 사용
. 따라서, 반복변수를 사용한 배열요소의 데이터 값을 변경할 수는 없다.
Array 객체 만들기
. System.Array.CreateInstance()메서드
 - Array 클래스의 새 객체를 생성하는 메서드
 - 스택틱(static) 메서드
. Array 클래스 객체 입출력
 - SetValue(Object obj, int i)   => 지정된 요소를 지정된 값에 출력(첫번째 매개변수: 저장할 데이터, 두번째매개변수: 인덱스)
 - GetValue(int i)                    => 지정된 요소의 값 출력
문자열  . 문자열은 System.String 클래스의 객체이다.
. 문자열은 문자상수의 집합니다.
.   + 연산자를 사용하여 두 문자열을 연결하여 새로운 문자열을 생성한다.
. 특수문자를 문자 그대로 받아들일 때는 @를 사용한다.
문자열 주요 메서드 . IndexOF()       - 문자열을 첫 부분부터 검색하여 입력한 문자열을 제일 먼저 만나는 위치를 int로 반환
. LastindexOf() - 문자열을 마지막 부분부터 검색하여 입력한 문자열을 제일 먼저 만나는 위치를 int로 반환
. Replace(a,b) - 문자열에서 특정 문자(a)를 원하는 문자 (b) 로 치환한 문자열을 반환한다.
. Substring()    - 문자열에서 지정된 위치에 있는 부분 문자열을 반환합니다.
System.Text.StringBuilder . Stringbuilder의 용량은 추가되는 데이터가 커지면 문자를 저장하는데 필요한 메모리를 자동으로 늘리기 때문에 동적으로
   용량이 늘어난다.(기본용량 16)
. Public sealed class StringBuilder
. 문자열의 수정을 가능하게 하는 클래스
Stringbuilder클래스의
메서드 및 속성
. Append(데이터) - 지정된 문자열 표현을 StringBuilder 객체의 끝에 추가
. EnsureCapacity(int capacity)  - 인스턴스의 용량을 최소한 지정된 값이 되도록 함
. ToString()  - StringBuilder를 String으로 변환
. Capacity 속성 - 인스턴스의 요량을 지정하거나 반환
. Length 속성 - 인스턴스의 길이를 가져오거나 설정
Collection류 클래스들의
 특징
. 켈렉션류 클래스들은 ㅅ형 메모리 데이터베이스의 기능인 수정, 삭제, 검색, 삽입 등의 기능을 함
. 동적으로 메모리 확장 가능
컬렉션류 인터페이스의
특징
. 인터페이스들은 컬렉션류 클래스들의 일관성과 사용상의 편리성을 제공
. 컬렉션 인터페이스들은 많은 컬렉션 클래스들 사이에 공통된 사용자 패턴을 정의
IEnumerable
인터페이스의 메서드
public interface IEnumberable{
           IEnumerator GetEnumerator();
          }
IEnumerator속성 object Current - 컬렉션에서 현재 객체에 대한 참조(Element)를 반환하는 읽기전용 속성
IEnumerator 메서드 . Bool MoveNext();
  - 열거자를 컬렉션의 다음 요소로 커서를 이동시킨다.
  - 다음 요소가 존재하지 않는다면 false를 존재한다면 true를 리턴한다.
  - 커서를 이동시킨 뒤 Current속성을 이용하여 데이터를 추출할 수 있다.
. Void Reset();
  - Current 포인터를 컬렉션의 처음 부분 앞에 있는 정의하지 않은 값으로 다시 설정한다.
  - Reset을 호출한 후 Current를 접근하기 전에 MoveNext()를 호출해야 한다.  이유는 처음에는 Current참조가 정의되어
     있지 않기 때문이다.
ICollection인터페이스
속성
. Int Count  -컬렉션의 객체 수를 반환한다. 즉, 켈렉션 내에 얼마나 많은 객체가 잇는지 알아낸다.
. Bool IsSynchronized -  다중 스레드된 액세스를 위해 컬렉션에 대한 액세스(Access)를 동기화한 경우 true를 반환한다.
                                       컬렉션이 동기화되는지에 따라서 쓰레드 안전성이 있는지 검사한다.
. Object SyncRoot - SyncRoot 속성은 스레드에서 컬렉션에 대한 액세스를 동기화하기 위해 사용할 수 있는 객체를 반환한다.
                             -  CLR 은 자동으로 어떤 .NET 형식 인스턴스라도 동기화 루트(SyncRoot)가 되도록 한다.
                             - SyncRoot 는 하나 이상의 코드 문장이 동시에 한 스페드에 의해서만 실행되는 것을 확실하게 하기 위해
                               잠거거나 해제할 수 있다.,
                             -  ICllection.SyncRoot를 실행하면 항상 적절한SyncRoot객체를 반환한다.
ICollection인터페이스
메서드
.  Void CopyTo(Array array, int index)  - 지정한 배열 위치부터 컬렉션의 요소를 배열로 복사한다.
IList 인터페이스 속성 . bool   IsFixedSize {get;}  - 리스트가 고정 길이 리스트인지 체크한다.
. bool   IsReadOnly{get;}  - 리스트가 읽기전용인지 체크한다.
. object  this[int  index] {get;set;}  - 인덱스 값으로 데이터를 얻거나 추가할 수 있다.
                                                       - 인덱서(Indexer)
IList 인터페이스 메서드 . int Add(object value);              -  리스트 끝에 데이터를 추가할 수 있다.
. void Clear();                            -  리스트의 모든 데이터를 제거한다.
. bool  Contains(object value);  - 어떤 데이터가 리스트내에 존재하는지 여부를 체크한다.
. int IndexOf(object value)         - 리스트 내의 특정 데이터의 위치를 반환한다.
. void Insert(int index, object value); - 리스트 내의 특정 위치에 대이터를 삽입한다.
. void RemoveAt(int index);               - 참조 또는 인덱스에 의해 지정한 인덱스의 데이터를 제거한다.
IDictionary 인터페이스
속성
.  bool IsFixedSize{get;};  - 컬렉션의 크기가 정해져 있는지 검사한다.
.  bool IsReadOnly {get;}  - 컬렉션이 읽기전용인지 검사한다.
.  ICollection Keys {get;}    - 컬렉션 내의 모든 키를 나열한다.
.  ICollection Values {get;}  - 컬렉션 내의 모든 값을 나열한다.
IDictionary 인터페이스
메서드
. void Add(object key, object value); - 키와 값을 전달하여 데이터를 컬렉션에 추가한다.
. void Clear();                                   - 컬렉션을 비운다.
. bool Contains(object Key);             - 특정 키가 데이터와 연관되어 있는지 검사한다.
. IDictionaryEnumerator GetEnumerator();  - 키와 갓을 나열한다.  IdictionaryEnumerator 인터페이스를 반환한다.
. boid Remove(object key);                         -  삭제할 값의 키를 전달하여 데이터를 컬렉션에서 삭제한다.
IDictionaryEnumerator
 인터페이스의 상속구조
. DictonaryEntry Entry{get;}   - 열거 요소내의 키와 값을 가져온다.
. Object  Key {get;}                -  열거 요소내의 키를 가져온다.
. Object Value {get;}              - 열거요소 내의 값을 가져온다.
ArrayList클래스의
프로토타입
. public class ArrayList  : IList, ICollection, IEnumerable, Icloneable
Hashtable 클래스의
프로토타입
. public class Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, Icloneable
- IDictionary 인터페이스의 대표적인 예
- 객체를 삽입할때 특별한 Key와 Value을 같이 입력해야 한다.
SortedList 클래스의
프로토타입
.  Public class SortedList : IDictionary, ICollection, IEnumerable, Icloneable
 - SortedList는 키의 목록 또는 값의 목록만 반환하는 메서드를 제공
 - SortedList는 내부적으로 두 개의 배열 즉, 키에 대한 배열과 관련 값에 대한 배열을 유지하여 요소를 목록에 정장
 - SortedList는 각 요소에 대해 키, 값 또는 인덱스의 세가지 방법으로 액세스함.
 - 요소가 삽입되면, 지정된 키가 이미 존재하는지 검사 -> 중복을 허용치 않음
Queue 클래스 . public class Queue : ICollection, IEnumerable, ICloneable
Queue 클래스의 특징 . 선입선출 컬렉션 클래스
. Enqueue() 메서드는 Queue의 첫위치에 요소를 삽입
. Dequeue() 메서드는 Queue의 마지막 위치의 요소를 삭제
. Peek() 메서드는 Queue의 마지막 위치의 요소를 제거하지 않고 반환
Stack 클래스의
프로토타입
. Public class Stack : ICollection, IEnumerable, Icloneable
Stack 클래스의 특징 . 후입선출 컬렉션 클래스
. Push() 메서드는 Stack의 맨 위에 요소를 삽입
. Pop() 메서드는 Stack의 맨 위에 있는 요소를 삭제하고 데이터를 반환
. Peek() 메서드는 Stack의 맨 위에 있는 요소를 제거하지 않고 반환
BitArray 클래스의
프로토타입
. public sealed class BitArray  : ICollection, IEnumerable, Icloneable
 - BitArray b = new BitArray(8);
 - 8비트를 가지는 비트배열 생성
 -  모든 비트는 false로 설정
NameValueCollection
클래스
 
Exception
표준 예외들
. Exception  : Object형으로 모든 예외의 기본클래스
. SystemException : Exception 형으로 모든 런타임 생성 오류의 기본 클래스
. IndexOutOFRangException : SystemException 형으로 매열이 올바르지 않게 인덱싱되는 경우에만 런타임에 의해 throw된다.
           배열의 인덱스가 유효한 범위를 벗어날 때 사용   ex)  arr[arr,Length+1]
. NullReferenceException  : SystemException형으로  null 객체가 참조되는 경우에만 런타임에 의해 throw됨. 
                   ex) object o = null;   o.ToString();
. InvalidOperationExceptio  : System.Exception형으로 유효하지 않은 상태에 있을 때 메서드에 의해 throw됨
. ArgumentException : SystemException형으로 모든 인수 예외의 기본 클래스 입니다.
. ArgumentNullException : ArgumentException형으로 인수에 null을 혀용하지 않는 메서드에 의해  throw됨.
                     ex) string s = null;     "Calclulate".IndexOf(s);
. ArgumentOutRangeException : ArgumentException형으로 인수가 지정된 범위에 있는지 검사하는 메서드에 의해 throw됨
                  ex)string s = "string";  s.Chars[9];
. ExternalException : SystemException형으로 런타임 외부에서 발생하거나 런타임 외부의 환경을 대상으로 하는
                            예외의 기본 클래스
. COMExceptionExternalException :  COM HRESULT 정보를 캡슐화하는 예회, COM interop 에서 사용됨
. SEHException : ExternalException형으로  Win32 구조의 예외처리 정보를 캡슐화하는 예외, 곤리되지 않는 코드
   interrupt에서 사용
try~catch . try(예외감시자)      - 예외가 발생할 가능성이 있는 코드의 영역을 지정
. catch(예외처리기) - try에서 발생한 예외들에 대해 어떤 종류의 예외를 어떻게 처리해 줄 것인가를 결정
try~catch 사용형식  try{}
 catch(예외타입 변수명) {  }
다중 catch 문을 사용할
때의 주의사항
. 각각의 catch문은 반드시 서로 다른 종류의 예외를  처리할 것
. catch 문에서 사용될 예외 객체는 하위예외타입을 상위 예외타입보다 먼저 사용할 것
try~catch~finally문 try{     //예외를 발생시킬 가능성이 있는 코드
    }
catch(예외타입1  변수명)
    {    // 예외1이 발생했으 때 실행되는 코드
    }
catch(예외타입2 변수명)
    {    // 예외2가 바랭했을 때 실행되는 코드
    }
finally
    {    // 필수 실행 코드
    }
Exception 클래스에서
예외의 상태정보 속성
. StackTrace 속성       :  이 속성에는 오류 발생 위치를 알 수 있으며 스택을 추적한 정보를 포함하고 있다.
                                     스택 추적에는 소스파일 이름과 프로그램 줄 번호가 포함됩니다.
. InnerException 속성 :  예외가 발생했을 때 하나의 예외가 발생하면 또 다른 예외로 이어지게 되는데 하나의 예외에
                                     포함된 다른 예외정보를 포함하고 있는 속성
. Message 속성         :   예외에 포함된 메시지를 포함하고 있는 속성
. HelpLink 속성           :  예외의 원인에 대한 정보를 제공하는 도움말 파일의 URL 또는 URN이 보관 될 수 있다.
checked & unchecked
키워드
. Arithmetic Overflow  - 산술연산 중 특정 타입의 변수가 허용하는 값의 범위를 초과하는 것
. CLR 에서 오버플로에 대한 기본 설정
  - 상수식(일반상수로만 이루어진 식) : 컴파일 시 오버플로 검사
  - 비상수식(변수를 포함되어 만들어진 식) : 오버플로를 검사하지 않음
상수식의 기본 성질 . 상수식은 checked가 기본 성질이다.
. 상수식은 컴파일러가 컴파일할 때 오버플로를 검사한다.
비상수식의 기본 성질 . 비상수식은 unchecked가 기본 성질이다.  (즉, 비상수식에서 오버프로가 발생하더라도 체크하지 않는다는 뜻)
. 컴파일 시 비상수식의 오버플로는 점검될 수 없다.
. 실행시(런타임)에 오버플로가 발생할 수 있다.
. 실행시 오버플로의 에러 감지를 위해서 checked키워드를 이용한다.
Stream의 정의 . 자료의 입출력을 도와주는 추상적인 개념의 중간 매개체
데이터 흐름의
방향성 분류
. 입력스트림( Stream, TextReader,BinaryReader)   
. 출력스트림(Stream, TextWriter, BinaryWriter)
데이터 처리하는
단위기준
. Byte Stream    Character Stream 으로 구분
입력스트림의 사용 . 목표지점에 대이터 스트림 생성
. 알맞은 데이터 스트림으로 변환
. 데이터 입력(Read 계열 메서드)
. 데이터 스트림 닫기(Close() 메서드)
출력스트림의 사용 . 목표지점에 데이터 스트림 생성
. 알맞은 데이터 스트림으로 변환
. 데이터 출력 또는 저장 (Write 계열 메서드)
. 데이터 스트림 닫기 (Close() 메서드 )
Byte Stream의 종류 . Stream              : 스트림 계층 구조의 최상위 추상 기본 클래스
. BufferedStream : 바이트스트림에 버퍼 기능의 추가
. FileStream         : 파일 I/O 에 사용
. MemoryStream : 메모리에 사용
Character Stream의
종류
. TextReader, TextWriter : 문자스트림 계층 구조의 최상위 추상클래스
. StreamReader              : 입력 바이트스트림을 문자스트림으로 변환
. StreamWriter                : 출력 바이트스트림을 문자스트림으로 변환
. StringReader                : 문자열을 핸들하기 위한 입력 문자스트림
. StringWriter                  : 문자열을 핸들하기 위한 출력 문자 스트림
파일, 디렉터리 관련
클래스들
. FileSystemInfo               -  파일시스템 객체를 나타내는 기본 클래스
. Directory, DirectoryInfo  - 디렉터리를 나타내는 기본 클래스
. File, FileInfo                   - 파일을 나타내는 기본 클래스
. Path                              - 경로를 조작하기 위한 클래스
File 클래스 . Public sealed class File
. FileStream의 객체 생성
. 파일 관련 메서드 제공
. 멤버메서드들이 public static으로 선언
File 클래스의
주요메서드
. AppendText()               :  UTF-8로 인코딩된 텍스트를 추가하는 STreamWriter를 만든다.
. Copy()                         :  새파일에 기존 파일을 복사
. Create()                       : 경로에 파일을 만든다.
. CreateText()                : UTF-8로 인코딩된 텍스트를 쓰기 위해 새 파일을 만들거나 연다.
. Delete()                       :  파일을 삭제합니다.  지정된 파일이 없어도 예외가 throw되지 않는다.
. Exists()                       : 파일이 있는지 여부를 확인한다.
. GetAttributes()             : 정규화된 경로에 있는 파일의 FileAttributes를 가져옴.
. GetCreationTime()      : 파일 또는 디렉터리를 마지막으로 액세스한 날짜와 시간을 반환
. GetLastAccessTime() : 파일 또는 디렉터리를 마지막으로 액세스한 날짜와 시간을 반환
. GetLastWriteTime()     : 파일 또는 디렉터리를 마지막으로 쓴 날짜와 시간을 반환
. Move()                        : 파일을 새 위치로 이동하고 파일의 이름을 새로 정할 수 있다.
. Open()                       : 지정된 경로에서 FileStream을 엽니다.
. OpenRead()              : 읽기용으로 팡ㄹ을 엽니다.
. OpenText()                : UTF-8 로 인코딩된 텍스트 파일을 읽기용으로 Open
. OpenWrite()               : 쓰기용으로 기존 파일을 엽니다.
. SetAttributes()            : 파일의 지정된 FileAttributes를 가져온다.
. SetCreationTime()      : 파일이 만들어진 날짜와 시간을 설정
. SetLastAccessTime() : 파일을 마지막으로 액세스한 날짜와 시간을 설정
. SetLastWriteTime()      : 파일에 마지막으로쓴 날짜와 시간을 설정
Directory 클래스  . 디렉터리의 생성, 이동, 삭제의 기능을 이용할 수 있다.
. public sealed class Directory
. 디렉터리 생성 및 삭제
. 하위디렉터리 생성 및 삭제
. 디렉터리 관련 메서드 제공
. 멤버메서드는 모두 public static 으로 선언되어 있다.
Path 클래스 . public sealed class Path
. 파일이나 디렉터리의 경로의 확장 및 변경, 수정하는 클래스
. 멤버메서드, 멤버필드 모두 public static으로 선언되어 있다.
Stream 클래스 . public  abstract class Stream : MarshlbyRefObject, IDisposable
. 바이트스트림 클래스들의 추상 기본 클래스
. 기본적이 입출력에 관련된 메서드를 포함하고 있다.
. 바이트 스트림 클래스들이란  Stream 계열의 BufferedStream, FileStream, MemoryStream, NetworkStream, CryptoStream등
  - 추상클래스이므로 스트림을 직접 생성하지는 못하고 , Stream 클래스를 구현하여 각각의 장치에 맞는 스트림을 만들어 사용
스트림을 얻기 위한
Console의 정적 메서드
. public static Stream OpenStandardOutput()
  - 표준 출력스트림을 가져옵니다.
.  public static Stream OpenStandardOutput(int)
  -  표준 출력스트림을 가져와서 지정한 버퍼 크기로 설정
Stream클래스의
속성(Property)
. CanRead : 파생클래스에서 재정의될 때 현재 스트림이 읽기를 지원하는지 여부 확인
. CanSeek : 파생클래스에서 재정의 될 때 현재 스트림이 검색을 지원하는지 여부 확인
. CanWrite: 파생 클래스에서 재정의 될 때 현재 스트림이 쓰기를 지원하는지 여부 확인
. Length: 파생클래스에서 재정의된 경우 스트림 바아트의 길이 반환
. Position: 파생클래스에서 재정의되면 현재 스트림 내의 위치를 가져오거나 설정
FileStream 클래스 . public class FileStream : Stream
. 파일에서 스트림을 생성할 때 사용
. 바이트 형식의 파일을 읽고 쓸 때 사용
. Stream 클래스의 모든 기능 사용 가능
FileStream의 변환 . 바이트가 아니라 문자 방식으로스트림을 사용하기 위해서는 FileStream 클래스를 StreamReader 클래서와
  StreamWriter 클래스로 변환하여 사용합니다.  스트림의 변환 절차를 거치면 자동적으로 바이트스트림을 문자스트림으로
  핸들할 수 있게 해줍니다.  StreamReader클래스와 StreamWriter 클래스는 바이트스트림을 문자스트림으로 변환하고자 할 때
  주로 사용합니다.
File 클래스를 이용하여
스트림을 생성하는 예
FileStream을 이용하여 직접 FileStream을 생성할 수 있지만
예 >   FileStream fs = new FileStream(path, FileMode.Create);
File클래스의 OpenRead()메서드를 이용하여 FileStream 객체를 생성할 수도 있습니다.
예 >  FileStream fs = File.Openread("C:\C#Example\03\HelloWorld\test.txt");
FileMode 상수 . Append          : 해당 파일이 있을 경우 파일을 열고, 파일의 끝까지 검색하거나 새 파일을 만듬
. Create            : 운영체제에서 새 파일을 만듬. 해당 파일이 있으면 덮어씀.
. CreateNew     : 운영체제에서 새 파일을 만듬. 파일이 존재하면 Exception 발생
. Open              : 운영체제에서 기존 파일을 열도록 지정 파일이 없으면 Exception 발생
. OpenOrCreate: 파일이 있으면 열고, 없으면 새 파일을 만듬
. Truncate         : 기존 파일을 열고, 파일 크기가 0 바이트가 도도록 만듬.
SeekOrigin 상수 . Begin     : 스트림의 맨 앞을 지정합니다.
. Curerent : 스트림 내의 현재 위치를 지정합니다.
. End        : 스트림의 맨 끝을 지정합니다.
Fush() Flsh() 메서드는 스트림에 기록한 모든 데이터들을 목표지점으로 밀어내는 역할
Peek() Peek()메서드는 읽을 데이터가 있으면 그 값을 반환하지만, 없으면 -1을 반환하는 메서드
BufferedStream 클래스 . public sealed class BufferedStream : Stream
. BufferedStream은 내부적으로 버퍼 기능을 제공해 준다.
. 디폴트 버퍼 사이즈는 4096 Bytem
. 내부에 버퍼를 사용하기 때문에 처리하는 속도가 훨씬 빠름
MemoryStream 클래스  . public sealed class MemoryStream : Stream
. 메모리에서 스트림 생성
. 부호없는(unsigned)바이트 배역 (byte[])로 저장된 데이터를 캡슐화
TextReader & TextWriter
클래스
. public abstract class TextReader : MarshalbyRefObject, Idisposable
. public abstract class TextWriter : MarshalbyRefObject, Idisposable
. 문자스트림(Character Stream)의 최상위 클래스
StringReader &
StringWriter
 클래스
. public class sStringReader : TextReader
. public class StringWriter     : TextWriter
. StringReader 클래스는 string형 데이터를 매개변수로 직접 스트림 생성
. StringWriter 클래스는 스트림에 문자를 기록한다.
StreamReader &
StreamWriter
클래스 
. public class StreamReader : TextReader
. public class StreamWriter : TextWriter
. 바이트스트림  - >  문자스트림
. TextReader 와 TextWriter를 상속받는 문자스트림
. 바이트 스트림을 문자스트림으로 변환할 때 사용
BinaryReader &
BinaryWriter
클래스
. public class BinaryReader :IDisposable
. public class BinaryWriter : Idsposable
. 타입에 따라 이진 데이터를 읽거나 쓸 경우 사용하는 클래스
Object 클래스 .  .NET Framework 최상위 클래스
. 모든 클래스는 Object클래스를 상속
Object 클래스의
멤버메서드
. public virtual bool Equals(object obj)
 - 지정한 객체가 현재 객체과 같은지 비교
 - 디폴트는 참조비교, 파생되어 다양한 비교를 함
. public static bool Equals(object obj1, object obj2)
 - 지정한 두 객체가 같은 객체인지 비교하는 스태틱 메서드
 - 매개변수로 들어오는 객체의 Equals()에 따라서 비교가 결정
. public static bool ReferenceEquals(object obj1, object obj2)
 - obj1 과 obj2 같은 참조값을 가지는지 비교
. public virtual int GetHashCode()
 - 객체의 HashCode 값 반환
 - 기본 참조코드 반환, 파생되어 다양한 형식의 유일키 반환
. public Type GetType()
 - 런타입시 객체의 형 반환
. public virtual string ToString()
 - 재정의하지 않았을 때 디폴트로 객체의 타입을 출력한다.
 - 객체의 정보출력을 목적으로 함, 재정의되어 객체의 다양한 정보를 반환
. protected ~ Object()
 - 메모리 해제시 가ㅣ지콜렉터에 의해 자동호출
. protected object MemberwiseClone()
 - 객체의 메로리 단순 복사
해시코드(HashCode)란? . CLR이 부여하여 객체를 식별하는 고유한 ID
. GetHashCode()에 의하여 반환
.  사용자가 GetHashCode()를 재정의하여 사용할 수 있음
GetType() 메서드 . System.Type의 객체를 반환하는 메서드
  ※ Type 클래스 : 프로그램이 실행될 때 클래스는 CRL에 로딩되어질 것입니다. CLR에 로딩된 클래스는 클래스 내의 모든
                            정보를 담고 있습니다.  예를 들어 , 생성자가 몇 개인지, 멤버필드가  어떠한 것인 있는지, 누구로부터 상속을
                           받았는지 등에 관한 클래스 자체의 모든 정보를 담고 있습니다. 가령, 여러분이 문자열을 핸들하고자 한다면
                           string 클래스를 사용합니다.  이와 마찬가지로 클래스의 모든 정보를 핸들하고자 한다면 Type클래스를
                           이용하는 것입니다.
Type 클래스의 메서드가
제공하는 클래스 정보
. 클래스 타입에 관관 정보 : 클래스 상속, 인터페이스 구현 등의 정보
. 클래스 멤버에 관한 정보 : 메서드 , 속성, 이벤트, 객체의 정보
Reflection이란 실행시에 객체를 통해 클래스의 정보를 분석해내는 프로그램 기법
일반적인 클래스의 사용 . 클래스 디자인
. 클래스를 이용해서 객체변수 선언
. 선언된 객체에 메모리 할당
. 객체변수를 통해서 메서드 호출
리플렉션(Reflection)
기법의 사용
. 메모리를 보유하고 있는 객체가 존재할 경우
. 객체의 형(Type) 정보를 알아낸다. (즉, 해당 객체의 Type 클래스 생성)
. 생성된 Type과 해당 객체의 메모리를 이용하여 멤버들을 호출할 수 있다.
클래스의 형정보
(Type Information)가
존재하는 곳
. 파일 어셈블리(Assembly) 내에 형정보가 들어 있다.
. 어셈블리에 존재하는 클래스가 로딩되었다면 CLR의 모모리 내에도 형정보가 존재한다.
. 해당 객체가 CLR 내에 존재한다는 것은 해당 클래스의 타입(형)정보가 로딩되었다는 것을 의미한다.
Type 클래스  . Type 클래스는 클래스의 모든 정보를 관리하는 클래스
. 특정 객체의 타입(Type)만 알고 있다면, 이 Type을 이용하여 모든 작업을 할 수 있다.
Type을 얻을 수 있는 방법 . 객체.Type()
. Type.GetType("클래스 명")
. Typeof(클래스명)
동적바인딩과
정적바인딩
typeof 키워드는 클래스 자체를 인수로 받아서 컴파일 시에 그 클래스를 검사사하기 때문에 해당하는 클래스가 없다면 예외를 발생
그리고, 실행시(Run-Time) 에는 이미 확인된 타입을 그대로(정적으로) 사용하는 것입니다. 하지만, Type.GetType() 메서드는
프로그램 실행시, 해당 구문을 실행할 때 문자열로 지정된 타입을 동적으로 찾아서 그 형을 반환하므로, 컴파일 타임과는 상관이
없게 되는 것이입니다.
Type 클래스를 분석하는
방법
. 생성자를 알아낼 때 : public ConstructorInfo[] GetConstructors() 사용
. 메서드를 알아낼 때 : public MethodInfo[] GetMethods() 사용
. 변수를 알아낼 때   : public FieldInfo[] GetFields() 사용 
대리자(Delegate) . 메서드의 대리자
. 메서드를 보다 효율적으로 사용하기 위하여 특정 메서드 자체를 캐슐화할 수 있게 만들어 주는 방법
대리자(Delegate) 구현단계 . 1단계 : Delegate할 메서드를 정한다.
. 2단계 : 메서드에 맞는 Delegate 선언하기
              - 메서드의 리턴타입과 매개변수를 정확하게 일치(반환형, 매개변수 개수, 매개변수 타입)
. 3단계 : 임의의 객체 만들기
. 4단계 : Delegate 생성과 호출
Delegate의 선언 . 사용하려는 Delegate의 형을 생성하는 부분
   public delegate void TopDelegator(string str);
. 메서드의 선언 (시그너쳐)
  public void NormalMethod(string str)
  public static void StaticMethod(string str)
Delegate의 생성 . 생성된 Delegate 타입으로 부터 Delegate 객체를 생성하는 부분
  - Delegate객체를 만들 대의 매개변수는 메서드의 이름이다.
  - 예) TopDelegator dele = new TopDelegator(t.NormalMethod);
Delegate를 사용하여
메서드 호출하는 부분
. 생성된 Delegate 객체를 사용하여 메서드를 호출하는 부분
  td1("jabook")
  td2("소설같은 C#")
Delegate의 해석 . 메서드의 포인터를 편리하게 사용하는 방법을 제공한다.
. Safe Type Method Pointer
. Method의 Pointer를 C#에서는 Delegate라는 형식을 빌어 사용할 수 있게 해준다.
. 메서드를 Delegate라는 것에서 관리하게 하고 메서드의 반환형과 매개변수 등의 안전성을 보장 받는다.
Thread에 사용되는
Delegate의 구현
. ThreadTest tt = new ThreadTest(); //임의의 객체
. Thread t = new Thread(new ThreadStart(tt.메서드));
. thread.Start();
ThreadStart . 스레드를 만들기 위해서는 스레드로 사용할 메서드를 반드시 ThreadStart 델리케이트로 만들어야 합니다.
  ThreadStart 델리케이트는 라이브러리 내부에 선언되어 있으며 여러분은  스레드를 만들고자 할 때 ThreadStart를
  사용하기만 하면 됩니다.
하나의 Delegate에
다른 Delegate를 추가,
삭제하는 방법
. 추가하려는 메서드를 담고 있는 객체를 += 연산자를 사용하여 등록
. 추가한 메서드를 제거할 때에는 -= 연산자를 사용하여 제거
. 멀티 Delegate를 사용할 때 메서드는 반드시 void를 반환해야 함
이벤트란? . 이벤트(Event) 그 자체
. 이벤트를 발생시키는 이벤트 발생기
. 이벤트를 받는 이벤트 처리기 (Event Handler)
일반적인 이벤트 순서 1단계 : GUI 이벤트를 테스트 하기 위한 윈도우 폼 만들기
2단계 : 폼에 등록된 이벤트 찾가(Click)
3단계 : Click 이벤트 처리기(Event Handler) 만들기 
           EventHandler의 형태 => private void ClickReceive(object sender, EventArgs e){  }
                                                object sender : 메시자가 어디서 발생하는지 발생된 곳의 참조값을 의미
                                                EventArgs e    :  이벤트의 데이터를 담고 있는 매개변수
4단계 : Form의 Click 이벤트에 이벤트  처리기 등록하기
5단계 : Click 이벤트 발생, 이벤트, 이벤트 처리
Event의 처리 순서 1. User가 폼을 클릭한다.(Click 이벤트 발생)
2. 폼의 Click 이벤트에 연결된 이벤트 처리기를 찾는다 (등록된 EventHandler검색)
3. 이벤트 처리기를 호출한다. (EventHandler 호출, 매개변수로 ㅎ출자와 이멘트의 정보를 주고 Eventhandler를 호출한다.
4. EventHandler에 포함된 메서드를 호출하여 작업을 처리한다.
전처리 지시어의 종류 . #define, #undef ; 조건부 컴파일 기호를 정의하거나 정의를 해제할  때 사용
. #if, #elif, #else, #endif : 소스 코드의 특정 부분을 조건적으로 건너 뛸 때 사용
. #line : 오류나 경고에 대해 생성되는 줄 번호를 제어할 때 사용
. #error, #warning : 오류나 경고를 발생시킬 대 사용
. #region, #endregion: 소스 코드의 특정 부분을 명시적으로 표시할 때 사용
스레드( Therad)의 특징 . 프로그램내의 일련의 작업단위
. 스레드 단위로 CPU의 제어권을 확보할 수 있다.
. 스레드를 프로그래머가 직접 제어할 수 있다.
Process와 Thread Process는 실행중인 하나의 프로그램을 의미하고,
Thread는 프로세서내에서 작업의 단위로서 여거 개 존재할 수 있다.

Process  - Thread   t1   - TLS(Thread Local Storage)
                                      - Call Stack
                ---------------------------------------
               - Thread   t2   - TLS(Thread Local Storage)
                                      - Call Stack

※ Call Stack : Thread 내에서 사용하는 메서드 호출 순서와 메서드 내부에서 사용하는 메모리를 저장하는 역할 담당
                      ( 스레드에서 사용하는 메모리 자체)
※ TLS : 스레드 자신의 정보를 저장하는 역할

Thread 상태 Unstarted(생성 직후의 상태) - Runnable(실행 가능한 상태) - Suspended(대기상태) - Stopped( 실행을 끝내고 죽은 상태)
Thread 클래스에 정의된
메서드
Thread.Start() - 해당 스레드의 실행
Thread.Abort()- 해당 스레드의 종료
Thread.Join() - 해당 스레드의 실행 종료시까지 대기
Thread.Suspend() - 해당 스레드를 대기 상태로 변경
Thread.Resume() -  해당 스레드를 실행 상태로 변경
Thread.Sleep() -  해당 스레드를 특정 시간동안 대기 상태로 변경
스레드를 대기상태로
보내는 방법
. Sleep()
  - 지정한 시간(Millisecond) 동안 스레드를 대기상태로 만듬
  - 지정된 시간이 지나면 자동으로 Runnable 상태가 된다.
. Suspend()
 - 스레드를 대기상태로 보낸다.
 - 다시 실행 상태가 되기 위해서는 Resume() 메서드를 호출해야 한다.
 -  Resume()을 호출하지 않으면 스레드는 Runnable 상태로 되돌아 올 수 없다.
스레드의 종료 . 자동 종료 - 해당 메서드의 종료
. 강제 종료 - Abort() 메서드를 이용하여 ThreadAbortException을 발생하여 종료
. ThreadAbortException
                - 일반적으로는 처리할 수 없는 예외 해당
                - 단, 스레드가 WaitSleepJoin 상태라면 이 예외를 처라할 수 있음
동기화(Synchronization) . 스레드가 자원을 공유할 때 한번에 하나의 스레드만 사용
. 하나의 스레드가 공유자원을 사용할 때 공유자원에 lock을 걸어준다.
동기화(Synchronization)
위한 방법들
. Lock 키워드의 사용
. Threading 네임스페이스의 Monitor 클래스의 사용
. Threading 네임스페이스의 Mutex 클래스의 사용
Marshaling ? 예> 객체를 메모리로 통째로 저장한 후 다른 컴퓨터로 전송했는데 이것을 복원해서 사용하려 합니다.
  컴퓨터간에 사요하은 데이터타입의 메모리가 다르거나 데이터를 저장하는 형태가 다르다면 어떻게 될까요?
  이것을 방지하기 위해서는 적절한 정보를 첨부해서 객체를 전송하거나 다른 방법을 강구해야만 합니다.  이러한 형식을 맞추기
  위해서 해주는 작업을 마샬링 이라고 합니다.


▣  개발환경 자동화에 대한 추천 조합 - 2009. 11. 13. 09:32

보호되어 있는 글입니다. 내용을 보실려면 비밀번호를 입력하세요.



articles
recent replies
recent trackbacks
notice
Admin : New post