컴퓨터 공학부 학부생이 배우는 과목에 대한 단상(~2학년까지)

HTML5한국사용자모임 운영자, 아이젝트 랩 대표 등의 사실 겉멋만 잔뜩 들어있는 수식어들이 있지만 결국 나는 컴공과 학부생일 뿐이다. 여타 대학생들과 별반 다를 것은 없다. 다만 실무를 조금 더 다른 친구들보다 빨리 접해봤을 뿐이지. 이에 따른 득과 실은 실로 그 격차가 매우 크다.

 그래도 가끔 후배들을 보면 대체 이 과목을 쓸때없이 왜 배워야 하는지를 모르는 친구들이 있다. 어떤 친구들은 마치 암기과목인 마냥 죽어라 암기만 하는 친구도 있고, 수학과목처럼 이해를 하려고 노력하는 친구도 있다. 컴퓨터가 학문으로써 존재하는 이유를 잘 생각해보면 쉬울텐데 말이다. 사실 컴퓨터가 학문이 될 수 있는 것은 산업과도 아주 밀접한 관련이 있는데 결국 보다 더 나은 SW를 만들기 위함이 아니던가.

 어쨌든 나도 성적을 썩 잘 받은 것은 아니지만, 하물며 나도 이런 과목들에 대해 왜 배웠는지에 대해서도 잘 몰랐지만 1년간 고찰하며, 그리고 실무에서 느낀 것을 토대로 배웠던 과목들에 대해 잠깐 생각해 보고자 한다.

  • 자료구조 분석, 설계

     컴공과에서는 매우 중요한 과목이다. 자료를 담는 체계는 사실 프로그램을 구상하는 가장 핵심적인 부분이라고 할 수 있다. 오늘날 컴퓨터가 존재할 수 있던 이유는 컴퓨터의 핵심적인 프로세서, 메모리, I/O 등이 존재해서 가능했다. 이 중에 우리는 프로그래밍에서 메모리를 통해 우리가 프로그램에 필요한 자료를 작성하고, 기억할 수 있게 한다. 가장 기본적으로 “변수(Variables)” 가 있고 그 변수들이 모여서 배열(Array)가 되고 메모리 할당과 구조체를 통해 리스트 자료구조를 만들 수 있고, 특히나 스텍 자료형은 함수를 호출할 때에, 혹은 Recursive한 프로그래밍을 만들 때 프로그램이 어떻게 동작하는지에 대한 이해를 돕는다. 

     그런데 문제는 컴공과라면 큐,스텍 뿐만 아니라 그래프와 트리에 대해서도 배우며, 특히 트리 구조에서 BST로 대표되는 수 많은 이진트리 알고리즘, AVL Tree, Red-Black Tree, Spray Tree, B-Tree, B+ Tree, Digital Search Tree, Patricia 등등이 문제다. 내가 공부했던 책인 “C로 쓴 자료구조론”의 절반 가량은 이러한 새로운 BST에 대한 내용으로 되어 있었다.

     그럼 이러한 자료형들이 실제 코딩할 때에는 얼마나 큰 영향을 미치는가? 사실 실무에서 누가 java.util.HashTable이 Red-Black Tree 구조로 되어있다는 것을 알겠는가. 아 물론 난 해시테이블도 잘 안쓰고 ArrayList와 HashMap의 추종자이다.하지만 타고타고 들어가보면 HashTable을 상속한 객체가 존재하는 것을 알게되고, 해시테이블이 레드-블랙 트리 구조를 가지고 있다 하면 수 많은 자료형에 대해 자료형의 높이는 2*log_2(n+1)이며 탐색 속도는 평균 log n을 유지한다는 것을 알 수 있을 것이다. 

     그런데 나는 사실 한번도 이런 속도에 대해 고려해 본 적이 없다. 내겐 주된 관심사가 웹에 있어서의 트래픽이었기 때문이다. 그래서 객체의 재활용에 대해서만 연구를 많이하곤 했다. 근데 따지고 보면 자료구조가 더 중요하다. 리스트를 잘 쓰면 배열에서 사용되는 메모리 낭비를 줄일 수 있다. 마찬가지로 일반적으로 가져다 쓰는 미리 정의된 자료형(자바에서 hashmap arraylist vector hashtable hashset set 등등) 이 어떠한 장/단점을 가지고 있는지 알 수 있다.

    근데 리스트를 쓰는 것은 여간 귀찮은 일이 아니다. 여러가지 예외 처리할 상황이 도사리고 있다. 그런데 중요한것은 우리가 이러한 예외처리를 하면서 내가 만든 프로그램을(그게 하물며 JSP로 구성된 단순한 페이지라도) 분석하는 데에 도움이 된다는 것이다. 그래서 나는 자료구조를 프로그래머라면 갖춰야 할 공통지식이라고 생각한다. 정적할당보다는 동적 할당이 낫고, 맵을 탐색하는 데에 있어서 어떤 방식이 더 나은지 정도를 아는 정도라고 할까. 어쩌면 프로그래머의 기본 습관이라고도 할 수 있을 것이다.

     조금 트리에 치우쳐서 얘기를 했는데 그래프 자료형은 약간 개인적인 생각에는 일반 응용SW나 웹SW보다는 임베디드니 아니면 공정관리 프로그램에 좀 더 어울리지 않는가 싶다. 내가 웹개발자라 그런지 몰라도 그래프는 아주 의미심장하게 와닿지는 않은 것 같았다. 만약 채팅 프로그램을 짜는데 클라이언트와 서버 간의 통신 구간과 속도가 정해져 있다면 어떻게 패킷을 전달해 주는지에 대한 탐색방법? 만약 이런 방식으로 접근한다면 자료구조는 하나의 단일 프로그램으로써의 의미가 아니라 대규모 프로그램 혹은 분석 프로그램에서 알고리즘 적인 개념이 더 강할 것 같다. 최소한 내가 생각하는 바는 그렇다.

    • 컴퓨터프로그램설계

     다른 학교는 어떻게 되어 있는지 몰라도 우리 학교에서는 자바의 기초부터 Swing까지 배우고(네트워크는 안배움) Term Project를 통해 자유 주제로 프로그램을 만들고 시연하는 과목이다. 애초에 난 너무 잘하려고 해서 시간을 많이 뺏겨버렸었는데..(페북연동+서버/클라 통신+Graphic Library) 어쨌든 1학년때 C와 C++을 배우면 2학년때 자바를 배우면서 많은 학생들이 프로그램에 관심이 생기곤 한다. 왜? 자바가 쉬우니깐. 적어도 Swing을 통해 아주 손쉽게 UI프로그래밍이 가능하니깐 말이다.(C로 하려면 MFC나 Win32 API를 써야하는데 나도 그랬지만 처음보는 사람은 복잡함..)

     그런데 문제는 여기서도 관심을 못보이는 몇몇 친구들이 있는데 난 그럼 참 문제라고 생각한다. 그건 결국 코딩에 대한 흥미가 없는 것이다. 코딩이란 것은 SW업계에서는 아주 기초 of 기초 이다. 나는 컨설팅만 한다던가 기획만 한다던가 해서 코딩을 몰라도 된다? 혹은 졸업하는데 코딩이 뭔 상관이냐.. 하는 소리를 하는 후배들을 보면 깝깝하다. 이런 친구들의 태반이 점수 맞춰서 대학 들어온 친구들인데 코딩은 못해도 자기가 만들고 싶은 프로그램을 생각하고 있기만 하면 될 것 같다. 그리고 만들려고 한번쯤 시도해 보면 코딩에 대해서는 누구보다도 관심있게 지켜보고 공부할 것이라고 생각한다. 

    • 컴퓨터시스템 및 어셈블리 언어

     뭐 어셈블리는 누가 들어도 어려워 보인다. 나도 대학 다시 복학할 때 가장 걱정한 과목이 어셈블리였다. 근데 생각보다 어렵진 않다. 나는 중학교 때에 C++이 당시 유행하지 않아서 C로 프로그래밍을 하곤 했는데 그때는 거의 GOTO문을 남발했던 것 같다. 그러다보니 프로그램이 완전 꼬이곤 했지만.. 어쨌든 그때의 C에서 변수가 제약되고 보다 더 정확하게 메모리를 활용해야 한다는 것 이외에는 크게 다르진 않는다. 물론 프로그램 적으로 제약되긴 했지만 자세히 따지고 보면 어셈블리는 C로 짜는 프로그램과 비슷하다. 

     어셈블리를 알아야 한다는 것 역시 프로그램을 보다 더 심도있게 분석하기 위해서 이다. 내가 만든 코드가 실제 컴퓨터 하드웨어에서는 어떻게 동작하는지, 미리 정의된 C 컴파일러 내에 미리 정의된 함수(예 : strcpy printf등)는 어떤 어셈블리 코드로 되어있는지 말이다. 예전엔 Visual Studio에서 C++로 코딩하다 갑자기 런타임 에러가 나서 “중단”을 누르면 어셈브릴 코드가 열리곤 해서 멘붕에 빠지곤 했는데 앞으론 그렇지 않을 것 같다. 물론 어셈블리 코드를 읽는 것은 하나의 전공 서적을 읽는 기분이 들긴 하지만 그래도 그렇게 심도있게 분석한 코드는 쉽게 잊혀지지 않을 것이다.

     중요한 것은 사실 웹개발을 하다보면 어셈블리는 전혀 사용할 때가 없다는 것이다. JSP로 만든다 쳐도 JVM이 알아서 해독해주니 이건뭐.. 어쨌든 어셈블리를 알아가면서 결국 가장 깊게 생각하고 배워야 할 것은 단연 컴퓨터에서 프로그램 언어가 어떻게 돌아가는지 정도일 것이다. 문제는 C도 모르고 이를 이해하려 한다면 솔직히 힘들다. C를 충분히 이해한 상태에서 접근하는 것이 가장 추천되는 어셈블리의 습득 방법일 것이다.

    • 오토마타와 형식언어
     2학년 2학기에 들어서 배우는 오토마타와 형식언어. 100% 이론과목인 이 과목은 처음엔 정말 왜배우나 싶더니 과거 컴퓨터라는 추상적인 개념의 것들이 어떻게 개념화 되어 실제로 구현되기까지 어떤 절차를 거쳐왔는지에 대한 이해를 필요로 하는 과목이다. 약간 컴퓨터에 대해 “이론”적 혹은 “수학”적인 관점에서의 역사 공부랄까.. FSM이니 TM이니 이런 것들은 결국 컴퓨터의 아주 기초적인 모델이 되었던 것들이다. 우리가 계산하는 수학을 어떻게 컴퓨터라는 개념에서 구현을 할 것인지들에 대한 개념.
     오래전에 컴퓨터는 커다란 컴퓨터와 자기디스크들로 구성된 것들을 도식화 하여 마치 하나의 식처럼 풀어나가는 것이 오토마타인 것 같다. 솔직히 흥미롭긴 하지만 만약 시간적 여유가 없으면 pass해도 좋을 과목인 것은 사실이다. 굳이 이를 배우지 않는다 해서 프로그래머로써 성장하는 데에는 전혀 지장이 없을 것으로 보이기 때문에..
    • 컴퓨터 구조
     내 생각엔 컴퓨터 구조는 C프로그래밍, 자료구조와 더불어 컴공과에서 배우는 과목 중 가장 TOP으로 중요한 과목이라고 생각한다. 나도 사실 2학기 때에 컴구를 제대로 듣지 못하고 공부를 대충한 것을 너무나도 후회하고 있다. 평소에 분산처리 서버에 대해 깊은 관심을 가지고 있는데 이를 하드웨어적 관점에서 구성하기 위해 어떤 컴퓨터 구조를 만들어야 하는지가 바로 이 과목의 목표이다. 그런데 이런 컴퓨터의 작은 처리를 위해 어떻게 해야 하는지를 열심히 서술하는데 나는 별로 관심이 없었다. 아니 사실 그 당시에 일하기에 바뻤지.. 그래서 프로세서가 실제로 어떻게 동작하는지, 프로세서와 캐시, 메모리, 그리고 I/O에 대한 실제 회로적 관점에서의 설계에 별다른 관심이 없었는데 이런 부분이 아주 기초적인 부분이 되어서 대규모 분산처리 서버를 구현할 수 있는 것이다. 
     나는 왜 나름대로 하드웨어에 대해서는 “고수”라고 자부하면서도 사실 CPU의 클럭이 의미하는 것이 정확하게 무엇인지, 그리고 CPU의 상세 스팩들이 개개별로 무엇을 의미하는지 조차 모르고 있었다. 단순히 클럭이 높으니 처리 속도가 빠를 것이다? 그런 것은 아주 가벼운 생각이다. CPU내에서 클럭이 어떻게 동작하며 클럭에 따라 프로그래밍한 명령어들이 어떻게 동작하는지, 거기서 일어나는 문제점은 무엇인지 등에 대해서는 분명 공부할 필요가 있다.
     사실 프로그래밍을 좋아하는 사람들은 하드웨어가 왜 중요한지는 잘 인지하지 못한다. 하드웨어에 대한 이해가 얼마나 되어 있는가, 이에 대한 심도있는 이해가 가능한가가 컴퓨터 공학부를 나왔느냐 안나왔느냐에 대한 차이인 것 같다. 나 또한 하드웨어에 대한 중요성을 별로 깊게 인지하지 못하였지만 어떤 프로그래밍이 하드웨어와 관련이 있지 않겠는가. 이 모든 언어들이 컴퓨터 안에서 돌아가는 것인데. 특히나 하드웨어 강국인 우리나라에서는 하드웨어와 관련된 소프트웨어가 대기업에서는 주로 사용되고 있으니 더욱 알아야 할 필요가 있다 생각한다.
    • 객체지향프로그래밍설계(Object-Oriented Programming)
     OOP 즉 객체지향 개념에 대한 과목이다. 주로 C++을 위주로 OOP의 주요 특성인 다형성, 상속, ADT과 STL등에 대해 공부하고 좋은 프로그래밍이란 어떤 것이냐에 대해 공부한다. 3학년떄 배우는 소프트웨어 공학의 선수과목이자 2학년 1학기때 배우는 자바 프로그래밍에 대한 후자 과목과도 같다. 또한 향후 디자인패턴에 대해 이해하기 위해서는 필수와도 같은 과목인데 OOP에 대해서는 아무리 오랫동안 공부한다 해도 사실 실무에서 잘 활용하기가 힘들 경우가 매우 많기 때문에 한번은 꼭 정리하고 넘어갈 필요가 있다. 실무에서 뭔 커플링이니 코헨션이니 이런거 다 고려해서 설계하기는 힘들다. 하지만 보다 더 윗선의 아키텍쳐 혹은 PL , PM등으로 넘어가기 위해서는 반드시 필요한 능력이 바로 “설계” 능력이다.
     한편으론 STL이나 템플릿 등이 꽤나 편리하고 클래스 한번 잘 알아두면 꽤나 고급 프로그래밍도 가능하니 잘 알아두는 것이 좋을 것 같다.
    • 무선이동통신
     이 과목은 내가 4학년 과목인데 땡겨서 들은 과목이다. 뭐 성적은 좋게 받았지만.. 평소 무선통신에 대해 상당히 깊은 관심이 있었다. 왜냐? 내가 다니던 디미고에서는 내가 고2던 당시 2004년에는 인터넷이 되지 않았으니.. 당시에 802.11g가 얼마나 혁신적이었는지 모른다. 54Mbps의 속도가.. 지금에야 802.11n으로 300Mbps까지도 나오지만. 당시 내 노트북엔 USB 1.1밖에 지원을 안해서 802.11a로 속도가 채 11Mbps가 나오지 않았다. 따라서 속도를 위해 나는 PCI-e로 Usb 2.0을 만들고 54Mbps속도를 내는 등.. 참으로 삽질 많이 했다. 이후에도 지금 다니는 회사나 집에서도 맨날 무선망 구축한다고 나름 무선통신에 있어서는 많은 관심이 있었는데.. 강의 내용이 죄다 영어라서 잘 이해를 하지 못한 점, 그리고 회사일 하느라 수업에 집중하지 못한 점은 내게 참으로 한심한 점이 아닐 수 없다.
     여튼 여기서 나는 IEEE 802.11ad에 대해 팀 프로젝트로써 조사하고 이에 대한 레포트도 작성하곤 했는데 이걸 가지고 내 친구 중 하나는 논문으로 낼 정도였다니 최근 유행하는 기술은 기술인가 보다. 속도가 기가급으로 나올 수 있다는 것이 향후 IDC등에서 쓰일 수 있을 것 같은데 음.. 유망한 과목이긴 하나, 평생 이 기술로는 먹고살고 싶지는 않기 때문에 그냥 배운 것으로 만족한다.
    • 소프트웨어 공학(Software Engineering)
     SE는 내가 적극 추천하는 과목이다. 좋은 프로그래밍의 조건에서부터 프로그램의 역사, 협업의 역사 등 다양한 부분에 있어서 공부를 할 수 있어서 좋다. 작년에는 내내 협업 시스템에 대해 공부하고 있었던지라 더없이 재미있었던 과목이었다. 물론 시험은 거의 암기식이긴 하지만.. 그래도 한번 공부해 두면 SW산업에 대해 폭넓은 이해를 할 수 있어서 매우 좋은 과목인 것은 사실이다. 
     뭐 이정도로 한번 정리해본다. 따지고 보면 1,2학년 1학기때까지는 기본기를, 2-2~3학년까지는 중급기술을, 4학년때는 내가 원하는 전공을 배우는 곳이 컴공과인 것 같다. 이후에 공부할 과목을 보니 사실상 확률과통계니 수치해석이니 미적분이니 공업수학이니.. 그런 수학과목과 영상처리, 게임설계, 설계패턴, DB프로그래밍, 소켓통신 등에 대한 좀 실무에 가까운 과목이 대부분이다.
     다만 아쉬운 부분은 너무 실무적인 것을 많이 배운다는 것이다. 대부분은 잘 느끼지 못하겠지만 올 한해동안 내가 한 팀 프로젝트만 5개 이다. 이 말은 “협업”에 대한 능력을 키워서 결국 협업으로 승부해야 하는 실무에서 잘 적응할 수 있는 능력을 키우는 것이다. 물론 회사 입장에서야 매우 좋고, 취업도 잘되니 학교도 좋다. 그런데 요즘엔 뭐 취업률 80% 라고 외치는 우리 학과가 사실은 별로 마음에 들지 않는다.. 사회에 나가서 잘 되면 모르겠지만 정년까지 정말 기계부속이 되어서 돌다 오는 경우도 너무 허다하니.. 그러자니 보다 더 공부를 하고 더 많은 개인적 개발 경험과 여러 경험을 토대로 더 멋진 무대로 진출하는 것이 좋지 않을까.. 참고로 그런 의미에서 나도 대학원 유학을 준비하고 있다.
     어쨌든 한 일주일간 고생해서 쓴 이 글이 컴퓨터 공학부에 대해서 “나는 과연 왜 이 학과를 다니는가?”를 고찰하고 있을 여러 후배들에게 작은 도움이 되길 바란다.