티스토리 뷰

프로그래밍/잡탕

학교에서 배운 것 정리

터프 프로그래머 2017. 8. 2. 23:39

최근 학교에서 그 동안 공부했던 것을 다시 훑어볼 일이 있었다. 공부하는 김에 각 강의에서 어떤 것들을 배웠나 정리해두면 도움이 되지 않을까 싶어서 여러 대학교에서 공통적으로 배울만한 강의명 아래 우리 학교에서는 무엇을 배웠는지 큰 분류상으로 정리해봤다. 세부 내용을 다 정리하자면 너무 복잡해질 것 같아서... 대충 이 강의에서는 저런 내용을 배우는구나 하고 참고할만한 정도로만 썼다. 좀 더 자세히 쓴 부분도 있는데, 그 동안의 경험상 해당 부분을 왜 배우는지 잘 모르는 경우가 많은 것으로 보였던 것에 대해서 약간의 부연 설명을 추가한 것이다. 나름대로 분류를 해서 정리하긴 했는데, 충분히 잘 분류했는지 모르겠다. 소프트웨어 공학 같이 중요하지만 내가 수강하지 않았기 때문에 리스트에 없는 것도 있다.


  • 수학에 대해
    • 컴퓨터수학
      • 이산 수학에 대해 배움
      • 명제, 증명, 집합, 정수론 기초에 대해 배우고
      • 알고리즘과 시간 복잡도 개념, 재귀 개념에 대해 배우고
      • 순열과 조합에 대해 배우고
      • 이진 관계 속성들에 대해 배우고
      • 부분 순서에 대해 배우고
      • 그래프에 대해 배우고
      • 트리에 대해 배우고
      • 탐색에 대해 배우고
      • 부울 대수에 대해 배움
    • 선형대수
      • 기하학적인 관점에서 문제를 접근하는 방법에 대해 배움
      • 일차연립방정식을 행렬로 계산하는 법을 배우고
      • 부분 공간을 배우고
      • 가우스 소거법을 배우고
      • LU 분해를 배우고
      • 벡터 공간을 배우고
      • 행렬식을 배우고
      • 정규 직교화를 배우고
      • 고유값과 고유벡터를 배움
    • 오토마타
      • 형식 언어와 계산 이론에 대해 배움
      • 형식 언어에 대해 배우고
      • finite automaton인 DFA, NFA로 regular grammar를 처리할 수 있음을 배우고
      • pumping lemma를 통해 어떤 언어가 regular language에 속하는지 판단할 수 있음을 배우고
      • pushdown automaton로 context free grammar를 처리할 수 있음을 배우고
      • 문법 간소화를 위한 촘스키 노말 폼에 대해 배우고
      • context free grammar를 기반으로 언어를 파싱하여 parse tree를 만드는 방법에 대해 배우고
      • turing machine의 원리와 계산 가능성에 대해 배우고
      • 계산 복잡도에 대해 배움
  • 프로그램 실행 과정에 대해
    • 논리회로
      • 0, 1로만 구분되는 전기 신호를 이용하여 복잡한 실행을 위해 논리 게이트들을 어떻게 구성하는지 배움
    • 컴퓨터구조
      • 논리 회로로 만들어진 CPU, 메모리와 같은 하드웨어에서 어셈블리 명령어 실행을 위해 알아야 할 것들을 배움
      • 산술 연산, 논리 연산, 메모리 접근, 실행 제어 명령어를 CPU 구조에서 어떻게 실행하는지 배우고
      • 그 명령어들을 더 빠르게 실행하기 위한 파이프라이닝 기법과 그 기법의 문제 해결 방법에 대해 배우고
      • 메모리 구조와 속도 향상을 위한 캐시, 논리 메모리를 물리 메모리로 맵핑하는 방법에 대해 배우고
      • IO 장치에서 IO가 어떻게 일어나는지 배우고
      • 인터럽트 처리 방법에 대해 배움
    • 시스템 프로그래밍
      • 간단한 명령어 집합을 가진 기계를 가정하고, 어셈블리 언어를 CPU에서 실행 가능한 목적 코드로 변환하는 어셈블러를 만들기 위해 알아야 할 것들을 배움
      • 어셈블리 언어를 파싱하여 각 명령어별로 인코딩하는 법을 배우고
      • 명령어별로 주소가 설정되고, 특정 명령어에 설정된 레이블을 이용하여 명령어 주소로 변환하는 법을 배우고
      • 변수에 메모리 할당을 위해 목적 코드를 어떻게 구성해야하는지 배우고
      • 만들어진 목적 코드를 읽어서 실행하는 시뮬레이터를 만듦으로써 프로그램이 CPU에서 어떻게 실행되는지 간접적으로 배움
    • 프로그래밍 언어
      • 어셈블리보다 더 고수준 언어, 예를 들면 C언어를 만들기 위해 고려해야 할 것들에 대해 프로그래밍 언어의 평가 기준인 readability, writability, reliability, cost 관점에서 살펴봄
      • 더욱 자연어에 가까워진 언어를 프로그램에서 읽어들이기 위한 문법 구조에 대해 배우고
      • 우리에게 익숙한 Expression들을 문법 구조와 LL, LR 파싱 방법에 따라 Syntax Tree를 만드는 법을 배우고
      • 이름, 바인딩, 영역에 대해 배우고
      • 여러가지 Type들을 지원하기 위해 고려해야 할 것들에 대해 배우고
      • 기본적인 expression statements 지원을 위해 고려해야 할 것들에 대해 배우고
      • selection statements(if, else, switch 등), iterative statements(for, while 등) 지원을 위해 고려해야할 것들에 대해 배우고
      • 서브 프로그램 기능 구현을 위해 알아야 할 것들을 배움
    • 컴파일러
      • 프로그래밍 언어를 통해 알게된 것들을 어셈블리로 변환하기 위한 컴파일러를 만드는 방법에 대해 배우며, 보통 교재로 많이 쓰는 책에서는 TINY라는 좀 더 간단한 언어에 대한 컴파일러를 만들어보는 식으로 배움
      • Lex를 이용한 Lexical Analysis 하는 법을 배우고
      • 하향식 파싱에 대해 좀 더 자세히 배우고
      • 상향식 파싱에 대해 좀 더 자세히 배우고
      • Yacc을 이용한 Syntax Analysis 후 Syntax Tree 만드는 법을 배우고
      • 만들어진 Syntax Tree를 Traverse 하면서 Semantic Analysis 하는 법을 배우고
      • 분석이 끝난 Syntax Tree를 미리 가정한 스택 머신의 명령어 집합의 어셈블리로 변환하는 법을 배우고
      • 만들어진 어셈블리를 실행할 수 있는 시뮬레이터로 실행해 봄
  • 프로그래밍에 대해
    • 자료구조
      • 프로그램에서 자료를 다루기 위해 필요한 여러가지 자료구조에 대해 배움
      • 스택과 큐
      • 연결 리스트, 환형 연결 리스트, 이중 연결 리스트
      • 트리, 트리 순회 방법, 이진 트리, 이진 탐색 트리, AVL 트리, 힙, 우선 순위 큐
      • 그래프, 무방향 그래프, 방향 그래프, 최소 신장 트리, 작업 네트워크
      • 위상 정렬
    • 알고리즘
      • 문제 해결을 하기 위한 알고리즘을 프로그래밍 언어로 구현하는 방법에 대해 배움
      • 여러가지 복잡도와 계산 방법을 배우고
      • 분할 정복 방법을 배우고
      • 다이나믹 프로그래밍 방법을 배우고
      • 그리디 접근 방법을 배우고
      • 백 트랙킹 방법을 배우고
      • 몬테 카를로 방법을 배우고
      • 분기 한정 방법을 배움
    • 문제 해결
      • 더 어려운 알고리즘들을 배움
      • 간단한 코딩 워밍업
      • 다이나밍 프로그래밍 - 0/1 Knapsack 문제, Longest Common Subsequence, Longest Increase Subsequence, Edit Distance
      • 기하 문제 - Area Formula, Convex Hull, Triangulation
      • 그래프 문제 - 위상 정렬, Strongly Connected Component, Maximum Flow 문제와 Ford-Fulkerson method, Bipartite Matching 문제와 Hungarian method, Kuhn-munkres algorithm
    • 객체 지향 프로그래밍
      • Swing으로 코딩하면서 객체 지향적으로 프로그래밍하는 방법에 대해 배움
      • Swing을 이용한 코딩을 하면서 객체 지향 프로그래밍의 몇 가지 특징들을 배우고
      • 팀 프로젝트로 프로그램 개발
    • 사용자 인터페이스
      • 안드로이드 개발을 하면서 객체 지향 프로그래밍을 좀 더 심화하여 배움
      • 안드로이드 개발을 전반적으로 배우고
      • 팀 프로젝트로 안드로이드 앱 개발
  • 네트워킹에 대해
    • 컴퓨터 통신과 네트워크
        • OSI 5계층의 각 계층, 특히 transport, network 계층에서 일어나는 일들을 자세히 배움
        • transport 계층의 TCP 프로토콜에서 어떻게 신뢰성 있는 통신을 하는지와 UDP 통신이 어떻게 되는지 배우고
        • network 계층에서 목적지까지 라우팅하는 방법을 배우고
        • network access 계층에서 이웃 노드에게 데이터를 전달하는 방법을 배우고
        • physical 계층에서 비트를 전송하는 방법을 배움
    • 네트워크 프로그래밍
      • 리눅스에서 소켓 API를 이용하여 네트워킹하는 방법을 자세히 배움
      • 고수준, 저수준 소켓 API들을 배우고
      • 운영체제에서 소켓을 어떻게 관리하고 연결하는지 배우고
      • 서버/클라이언트 구조를 배우고
      • 다중 소켓 처리를 위한 방법인 멀티프로세스, 멀티플렉싱, 멀티쓰레드 방법을 배우고
      • 유명한 프로토콜인 HTTP, FTP을 배워서 구현해봄
  • 인공 지능과 기계 학습에 대해
    • 지능형 시스템
      • 지능형 시스템이 무엇이고 어떻게 작동될 수 있는지 기본적인 부분에 대해 배움
      • 지식 표현 방식에 대해 배우고
      • reasoning에 대해 배우고
      • 널리 알려진 지능형 시스템들의 작동 방식에 대해 배움
    • 인공지능
      • 지적 행위를 할 수 있는, 인공 지능 프로그램을 만들기 위한 방법에 대해 배움
      • 에이전트와 환경의 개념에 대해 배우고
      • 문제 해결을 위한 탐색 방법에 대해 배우고
      • 제약 만족 문제와 풀이 방법에 대해 배우고
      • 명제 논리와 1차 논리를 이용하여 문제를 해결하는 논리적 에이전트에 대해 배움
    • 데이터 마이닝
      • 여러가지 감독 기계 학습 모델로 회귀, 분류를 하는 방법에 대해 배움
      • 통계적 학습이 무엇인지 배우고
      • 편향-분산 딜레마에 대해 배우고
      • 선형 회귀 방법을 이용한 회귀에 대해 배우고
      • 로지스틱 회귀, LDA, QDA 방법을 이용한 분류에 대해 배우고
      • resampling 방법에 대해 배우고
      • 선형 모델 선정과 정규화에 대해 배우고
      • 트리 기반 방법에 대해 배우고
      • Support Vector Machine에 대해 배움
  • 운영체제에 대해
    • 운영 체제가 하는 일들과 그 일을 하기 위해 어떤 자료구조와 알고리즘을 사용하는지 배움
    • 프로세스 관리에 대해 배우고
    • 메모리 관리에 대해 배우고
    • 스토리지 관리에 대해 배우고
    • 보호와 보안에 대해 배움
  • 데이터베이스에 대해
    • 사용에 대해
      • 데이터베이스를 사용하는 것에 대해 배움
      • 관계형 데이터 모델에 대해 배우고
      • SQL으로 질의하는 법에 대해 배우고
      • 상용 RDBMS가 제공하는 추가적인 기능들에 대해 배우고
      • ER 데이터 모델과 어떻게 RDB 디자인에 대해 배움
    • 개발에 대해
      • 데이터베이스를 만든다면 고려해야할 것들에 대해 배움
      • 트랜잭션이 무엇인지와 트랜잭션을 어떻게 관리하는지에 대해 배우고
      • 여러 트랜잭션을 동시에 실행하기 위한 방법을 배우고
      • 복구 기능과 안정적인 스토리지 운영 및 버퍼 관리 방법에 대해 배우고
      • 빠른 질의 처리를 위한 인덱스의 종류에 대해 배우고
      • 질의 처리를 위한 과정과 JOIN이나 정렬과 같은 몇 가지 주요 연산을 어떻게 처리하는지 배우고
      • ORDB 개념에 대해 배우고
      • 데이터 웨어하우스 및 마이닝과 관련된 부분을 조금 배우지만 의미는 크게 없는 듯


정리하고 나니까 양이 꽤 된다. 그래도 시간을 아예 날린 것은 아닌건지...

몇 개 강의는 굳이 학교에서 들을 필요 없었다 싶은 것들도 있다. 위 리스트에서는 객체 지향 프로그래밍이나 사용자 인터페이스 같은 강의인데, 혼자 공부할 일이 있는 류가 대체로 굳이 학교에서 들을 필요가 없었던 것들에 많이 포함된다. (수강했던 강의들 중 굳이 학교에서 배울 필요 없었다 싶은 강의들은 리스트에 추가하지 않았다.) 예를 들어 컴퓨터 구조, 프로그래밍 언어, 컴파일러 같은 것들은 앞으로 따로 찾아서 공부할 일이 잘 없을 것이라 생각한다. 찾아본다 하더라도 그 때 닥친 문제를 해결하기 위한 아주 지엽적인 부분만 조금 찾아보는 수준일 것이다. 전체를 다 공부하기엔 시간이 너무 많이 드니까. 그러나 전체적인 흐름을 이해하고 있는 것과 각각 작은 부분만을 알고 넘어가는 것은 그 분야의 이해도에 있어 큰 차이를 보일 것이라 생각한다. 

아직 초보 수준인 내가 이렇게 말하는게 설득력은 별로 없겠지만... 대학교에서 공부하기 전부터 코딩을 해왔지만 근 4년 간 컴퓨터 과학 내에서 다양한 전공들을 공부하고 난 지금, 과거의 나와 지금의 나를 비교해보면 문제를 어떻게 해결할지 생각할 때 좀 더 풍부하게 생각할 수 있게 된 것 같다. 이런 점에서 학교에서 실무를 많이 가르쳐야 한다는 주장에 대해서는 딱히 공감하지 않는 편이다. 예를 들어 학교에서 React를 이용한 웹 개발이나 게임 엔진을 이용한 게임 개발 같은 것을 굳이 배울 필요가 없다고 생각하는게, 그건 그냥 혼자 알아서 공부하면 되는 것이라고 생각하기 때문이다. 학교에서 배워야 할 것은 좀 더 근본적인 것, 그리고 그것을 바탕으로 새로운 지식을 만들어낼 수 있는 능력이라고 생각한다. 새로운 지식들도 결국 그 지식을 만들기 위해 그 이전의 이론을 활용한 것인 경우가 많으니까 말이다. 아예 새로운 개념조차도 그 개념을 생각해내는 것 자체는 이전의 지식 없이 불가능하지 않나 싶다.

마지막으로 대학 생활이 4년 정도를 그냥 일을 하는 것에 비해 더 나은 경험이었는지, 등록금만 따졌을 때 도합 3천만원에 달하는 수업료를 낼만한 가치가 있는 경험이었는지는 섣불리 판단 못 하겠다. 어쨌든 이제 거의 끝이다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday