thumbnail
뮌헨공대 컴퓨터공학과 (Informatik) 재학생의 회고록 (2)
KOR / 독일유학 / TUM / Computer Science
2024.08.14.

0. 방문해주신 분들께

저번 글에 이어서 뮌헨공대 컴퓨터공학과 1학년 2학기에 관해 글을 써보려고 합니다. 이번 글 또한 수필같은 형식으로 제가 느낀 점을 위주로 작성하다보니 어체가 딱딱할 수 있으니 양해 부탁드립니다!

1. 글을 시작하며

이 글을 읽는 독자분들은 아마 세 가지의 카테고리 중 하나에 포함될 것 이라고 생각한다.

  • 뮌헨공대나 독일 유학을 준비하는 학생/학부모님
  • 뮌헨공대에 갓 입학한 신입생
  • 뮌헨공대의 1학년 1학기를 살아남고 다음 학기를 준비하는 학생
  • 내 지인들? :D

이중에 처음 두 카테고리에 해당한다면, 일단 TUM의 공식 홈페이지나 이 블로그의 회고록(1)을 먼저 참조하길 바란다. 이번 글 부터는 그 전 학기를 무사히 통과했다는 가정 하에 글을 작성해 나가도록 하겠다.

1학년 1학기를 무사히 (혹은 좋은 성적으로) 통과할 수 있었다면 1학년 2학기에 대해선 큰 걱정을 하지 말라고 말하고 싶다. 그러나 의외로 1학년 2학기는 복병처럼 다가오는 경우가 많다.

특히 Wirtschaftsinformatik (경영정보학- 1학년 1학기에 ERA 대신 경영정보학 기초 과목을 수강한다. 경영정보학 기초는 통과하기 쉬운 과목 중 하나로 뽑히기 때문에 1학년 1학기의 재적에 대해 상대적으로 부담이 많이 적다) 에 재학하는 학생들의 경우에는 주위를 보았을 때 오히려 1학년 2학기가 1학년 1학기에 비해 압도적으로 어렵다고 평가하는 사람도 많을 뿐더러, 나 스스로도 모든 학기를 통틀어 유일하게 Endterm에서 한 번에 통과하지 못한 과목이 있는 학기이기 때문이다.(물론 추후에 Retake에서 무사히 통과했다)

심지어 1학년 2학기가 가장 어렵다고 하는 친구들도 심심찮게 볼 수 있다. 그럼에도 불구하고 상대적으로 악명이 높지 않은 이유는 (2) 명심해야 할 것 에서 알아보도록 하자!

1.1 당시 나의 근황

스스로에 대해 이야기하자면, 난 2학기로 넘어가는 방학에 지금 근무하고 있는 회사에 Cyber Security Engineer (Werkstudent, 20h/w)로 입사했다.

1학년 1학기때 나간 HackaTUM(교내 해커톤)에서 비록 최종우승은 하지 못했지만, 우리 회사에 커넥션이 있던 다른 Lehrstuhl의 선임이 프로젝트에 관심을 가지고 내게 회사의 정보와 함께 인터뷰를 제의해 주셨다.

마침 인턴을 시작해볼까 하며 정보보안 관련 업무로의 Job Searching을 하고 있던 나로서는 모의해킹 전문 회사에서의 커리어 찬스는 놓칠 수 없었고, 무사히 인터뷰와 기술면접을 통과해 6개월의 수습기간 후 Festanstellung(정직원)으로서 회사에 들어오게 되었다.

주 20시간 (오전에는 강의를 듣고 오후에는 사무실을 출근하는 식으로 진행했다)은 꽤나 많은 시간이지만 1학년 1학기를 무사히 끝낸 나로서는 충분히 해낼 수 있을거란 판단하에 결정한 일이고, 어찌되었든 실제 업무능력이 중요한 computer science 취업 시장에서 stand out 하기 위해서는 필요한 일이었다고 생각한다.

독일 대학생으로서의 첫 일자리에 관해서는 따로 글을 포스팅해보도록 하겠다. 내 이야기를 하는 이유는, 이것이 오늘 이야기 해 볼 “나태” 혹은 “자만”에 관련이 있기 때문이다. 각설하고, 본 글로 넘어가보도록 하자.

2. 명심해야 할 것

1학년 1학기의 Basisprüfung을 통과한 학생들은 대부분 스스로의 성과에 대해 자부심을 가지게 된다. 대부분이 하는 생각은 (그 시기의 나 또한 포함된다)다음과 같다:

  • 내가 그 무시무시한 1학기를 통과했어! 남은 학기들이 어려워봤자 얼마나 어렵겠어?
  • 이제 퇴학에 관한 부담도 없는데, 대학생활을 한 번 즐겨볼까?
  • 컴퓨터공학? 이제 어떻게 공부하면 되는지 알 것 같아. 혹은 나 조금 재능이 있는 것 같아!

이러한 생각의 대부분이 “1학년 1학기가 가장 어렵고, 나는 이를 통과했기 때문에 가장 큰 산을 넘었으며, 퇴학 걱정도 없는 1학년 2학기 쯤이야 충분히 통과할 수 있다.”로 귀결된다. 엄밀히 말하자면 이는 틀린 말이 아니다.

1학년 2학기 과목들의 순수 공부량은 어쩌면 1학년 1학기보다 확연히 적으며 설사 Endterm과 Retake에서 떨어진다고 한 들 퇴학의 위험이 없다. 내년에 다시 하면 될 뿐이고 실제 내 발에 불이 떨어지거나 하지 않는다. 그럼에도 1학년 2학기가 중요한 이유는 바로 추후 다가오는 2학년에서의 부담을 최대한 줄이기 위함 이라고 말할 수 있다.

실제로 내 친구들 중에서도 1학년 2학기에 통과를 못해 2학년 2학기에 다시 한 번 같은 과목을 재수강한 친구들이 있다. 하지만 명심하자.

2학년 2학기는 첫 학기보다도 어려운, 사실상 우리 과를 넘어서 TUM 전 학과에 걸쳐 가장 악명높은 과목들로 가득 찬 학기이다

여기에 정말로 작년에 통과하지 못 한 과목들을 추가로 공부하고 싶을까? 단언컨대 아니다. (실제로 떨어져서 2학년 2학기때 1학년 2학기 과목들을 같이 공부한 친구가 있다.

…아주 많이 힘들어 보였고 결과 또한 좋지 못했다)따라서 이 글을 보는 후배들에게 강조하고 싶다: 1학년 2학기에도 1학기처럼 충분한 시간을 공부에 투자해야 한다!

특히 곧 설명할 FPV나 LinAlg는 생각보다 낙제자가 정말 많이 나오는 과목이다. 이 과목들을 통과하지 못한다면 그 부담은 그대로 2학년 2학기로 이월된다.

하지만 나를 포함한 대부분의 친구들이 이런 사실을 알지 못했다. 당연히 통과할 수 있을거라는 근거없는 믿음을 가지고 취업 등의 학교 외 액티비티를 크게 늘렸고, 그게 내가 1학년 2학기를 “상대적으로” 수월하게 마치지 못한 요인으로 작용했다.

일을 시작한 것 자체가 문제라는것이 아니다. 단지 스스로가 많이 나태해져 있었고, 지금까지 하던것의 반만 해도 쉽게 통과할 수 있을 것이라는 근거없는 믿음에 사로잡혀있었기 때문이다.

도서관에서 많은 시간을 보냈던 1학기와는 달리 이런저런 취미활동이 내 우선순위 첫 번째에 올라왔고 실제로 시험기간도 굉장히 짧게 잡아 (과목당 2주정도 잡았던 걸로 기억한다)공부했다.

물론 주 20시간이라는 Work load가 미친 영향도(특히 회사에 적응해야하는 시기였기에) 적진 않지만 내가 알맞은 마음가짐으로 임했더라면 크게 문제는 없었을 것이다. 물론 결과적으론 다 잘 되었지만 누군가 내 실수를 반복하지 않길 바란다.

숨이 턱 막히는 독자들도 있을 것 같다. 그럼 도대체 좀 널널하게, 편하게 보낼 수 있는 학기는 언제라는거야?

애초에 TUM에 널널한 학기는 존재하지 않는다. 적어도 2학년 2학기까지의 모든 학기들은 꽤나 높은 난이도를 자랑한다고 말할 수 있다.

그렇다고 대학생활을 즐기지 말고 틀어박혀 공부만 하라는 것은 절대로 아니지만, 독일 대학생 (특히 TUM의) = 공부가 첫 번째라는 사실을 잊지 말자. 대학생활을 즐기는건 남는 시간에도 충분히 할 수 있다.

(학기중부터 꾸준히 투자한다면 생각보다 많은 자유시간이 남는다!) 이에 대해서 더 말하다보면 너무 길어지기 때문에 언젠가 TUM 학생으로서의 Work(study)-Life Balance에 관한 글을 적어보도록 하겠다.

그럼 지금부터 실제 Inhalt에 대해 알아보겠다.

3. 1학년 2학기의 과목들과 팁

과목의 목록들은 일반적으로 다음과 같다:

  • 컴퓨터 구조 실습 (낙제율 약 35프로)
  • EIST (낙제율 약 30프로)
  • LinAlg (낙제율 약 55~60프로)
  • GAD (낙제율 약 45~55프로)
  • FPV (낙제율 약 65~70프로)

자세히 알아보도록 하자.

3.1 Grundlagenpraktikum : Rechenarchitektur (A.K.A GRA)

1학기때 들었던 ERA과목의 실습과목이라고 할 수 있다. (따라서 딱히 강의가 존재하지 않는다) 꽤나 흥미로운 과목인데, 다음과 같이 구성된다.

  • Assembly/C Programming (1~6주차)

어셈블리어로 (5주차부터는 C언어로) 한 주당 2개에서 3개정도의 문제를 풀어야 하며, 랭킹이 존재한다! 문제가 딱히 어렵지는 않다. 이 랭킹이 정말 재밌는데, 이 프로그램을 실행하는데 CPU가 사용한 사이클의 수(Takt)를 기준으로 점수가 매겨진다.

(시뮬레이션을 돌린다고 한다) 따라서 어떤 어셈블리 명령어가 얼마만큼의 사이클을 사용하는지도 Machine Level로 뜯어보며 알게되고, 실제로 명령어의 배치 순서에 따라 프로그램의 효율이 변하는것도 확인할 수 있게 된다.

사실 랭킹 자체가 의미가 있는 것은 아니고 문제를 풀기만 하면 된다. PGDP에 비해선 많이 쉽다. 난 당시 전체에서 700명 중 20명 안에 들었던걸로 기억하는데, 딱히 가산점이 주어지는 부분은 없었다.

하지만 손으로 그려가며 최적화를 해보려는 노력을 통해서 컴파일러들이 어떠한 과정으로 컴파일링을 하는지 대략적으로 이해할 수 있게 되고, 5주차부터는 실제로 그런 부분을 Makefile이나 기타 gcc 라이브러리를 활용하면서 어떠한 최적화 방식이 어떤 변화를 만드는지 확인할 수 있게 된다.

꽤 재밌었지만 문제를 풀기만 하면 되는 부분이고 성적에 영향을 미치는 부분이 없기에 조금 아쉬웠다. 일정 % 이상 문제를 풀었다면 7~12주차로 넘어갈 수 있게 되고, 사실상 당락만 결정짓는 첫 6주이다.

  • Problem Solving / Publishing scientific paper (7~12주차)

7주차부터는 2~3인의 팀으로(팀은 자율적으로 구성한다! 같이 할 친구들이 있다면 많은 어드벤티지가 있다) 문제를 배정받게 되고, 이를 효율적으로 풀어 세미 논문을 쓰는 것을 목적으로 과목이 진행된다. 평가는 총 3가지 부분에서 이루어진다:

  • 프로그램의 정확성/효율성
  • 논문으로의 표현
  • 발표

듣기만 하면 굉장히 쉬워 보이지만, 절대 그렇지 않다. 우리 조 같은 경우는 arcsinh(x) 라는 삼각함수를

  1. C 라이브러리가 제공하는 어떠한 함수도 사용하지 않고 (즉, 사칙연산만을 사용하고)
  2. Taylor Series와 Lookup-Interpolation 기법 각 두 가지의 방식으로 (각각 프로그램 개발)
  3. 최소 C 라이브러리가 제공하는 arcsinh(x) 함수보다 20% 빠르고 20% 정확하게 (20% 이상이면 가산점, 동급 이하라면 마이너스)
  4. CPU Performance와 Preciseness를 각각 C에서 제공하는 내장함수와 비교하여 그 차이점을 설명하고
  5. 어째서 이러한 결과값이 나오는지 수학적/데이터 구조의 관점으로 해석하는, 폭 넓은 과제였다. 당시 작성했던 논문의 일부를 가져와봤다.

paper_arsinh

이런 식으로 수학이 많이 활용되는 문제가 많이 나온다. (내 친구 중 한명은 이미지 멀티프로세싱과 Vectorization에 관한 과제를 받았었다) 이렇게 보면 굉장히 어려워 보이지만 마음 맞는 친구들과 그룹을 짠다면 어떻게든 답안을 찾게 된다.

우리도 처음엔 많이 헤맸지만, 같은 문제를 며칠씩 잡고 머리를 싸메다 보면 어떤 식으로든 결과에 근접해지기 마련이다. 여기서 내가 줄 수 있는 팁은 다음과 같다:

  1. 제때제때 시작하자! 문제 받았으면 바로 시작하는 게 좋다. 시험기간 다 와서 하려면 다른 과목도 공부하랴, 이것도 하랴 정신이 하나도 없다.
  2. 너무 프로그래밍에 시간을 쏟지 말자!

두 번째는 우리 그룹이 범한 실수인데, 배점은 프로그램 논문 발표 1:1:1이다. 우리 조는 프로그램에 너무 많은 시간을 쏟은 나머지 논문을 조금 빈약하게 작성했고, 그게 추후에 성적에 반영되었다.

물론 좋은 점수로 통과할 수 있었지만, 너무 프로그램 개발에만 집중한 나머지 다른 부분에서 점수를 헌납했다는건 지금도 조금 아쉬움으로 남는 포인트이다. 프로그램 개발은 빠르게 완료하고, 그를 분석하고 형식에 잘 맞추어 논문을 작성하는개 좋은 전략이라고 할 수 있다.

결과적으로 재미있고, 떨어지는것에 크게 두려움을 (물론 떨어지는 사람도 있다. 하지만 대부분 시간을 많이 투자하지 못했거나 그룹원간의 불화로 인해 프로젝트가 엎어지는 경우에 떨어진다) 가질 필요는 없는 과목이다.

하지만 다시 강조하여, 차일피일 미루다보면 어느새 시험기간이 되어 도저히 프로젝트를 완료할 수 없는 상황까지 갈 수 있으니, 부지런히 시간을 투자하자!

3.2 Einführung in die Softwaretechnik (A.K.A EIST)

1학년 2학기, 혹은 내 기준 전체 과목 중 가장 쉬운 과목 TOP 3에 드는 과목이다. 동시에 가장 컴공다운 과목이기도 한데 굉장히 실용적인 소프트웨어 프로그래밍 스킬에 대해 배운다. 전부 기억나진 않지만 대략적으로 배우는 테마는 다음과 같다:

  1. SCRUM과 Lifecycle 설계
  2. 클라우드 환경과 deploy, docker 프로그래밍, git
  3. 객체지향의 심화와 디자인 패턴
  4. 디자인 패턴 중 MVC 모델의 심화학습
  5. 에러 처리와 Accountability 확보, 클린 코딩

전부는 아니지만 대략적으로 이렇게 이뤄지는데, 컴공 뿐만 아니라 다른 학과에서도 많이 들으러 올 만큼 인기과목이다.

(쉬운 것도 당연히 한 몫 한다) PGDP와 마찬가지로 Artemis라는 플랫폼에서 매 주 퀴즈와 프로그래밍 문제가 나오며, 일정 이상 포인트를 모을 시 학점에 가산점이 붙는다. 문제들은 정말 쉽다 솔직히 GPT가 활성화된 지금(당연히 공식적으로는 GPT를 활용하면 안 된다) 시점에서는 아마 내가 할 때보다 더 간단하게 숙제를 풀 수 있을 것 같다.

대부분 실용적인 디자인에 목적에 맞는 메소드들을 작성하는 식인데, 1학기에 이어서 자바로 프로그래밍을 한다. 쉽지만 당연히 클라우드 deploy나 web server를 실제로 구동하여 테스트를 진행하기 때문에

(물론 우리가 볼 수는 없지만, 백엔드 채점머신을 자동화시켜서 그렇게 한다고 들었다) 한 번 제출하면 평가될 때 까지 2~3분정도 기다려야하는 단점이 있다. 따라서 Abgabe 30분 전에 시작하는 것은 추천하지 않는다. 솔직히 PGDP보다 5배정도 쉬워서 더 할 말은 없다.

시험도 마찬가지로 Artemis 플랫폼에서 원격으로 진행하며(이건 추후에 바뀔 수도 있다고 들었다) 2시간 내에 7개의 프로그래밍 문제를 푸는 식이다. 보통 git 한 문제, dockerfile이나 클라우드 관련 한 문제, 디자인 패턴 별 메소드 작성하는 문제 등 7문제정도 출제된다.

문제를 빠르게 읽고(한 문제당 텍스트가 꽤 길다) 메소드를 작성해야하는데 솔직히 여기서 떨어진 친구는 못 봤다. 물론 만점맞가가 쉬운 건 아니지만 떨어지는것도 (적어도 1학기를 살아남았다면) 쉽지 않을 것 같다. 수업도 시험도 영어로 진행되기에 일반 한국 유학생으로서도 부담이 적을 것 같다.

여기선 통과가 목적이라기보단 만점을 목적으로 공부(딱히 공부할 게 있는건 아니지만)하는게 학점에게 좋을 것이다. 하지만 나는 입학 전에도 웹 프로그래밍이나 자바는 꽤 친숙한 편이었기에, 만약 자바의 극 초보자의 경우에는 조금 주의가 필요하다.

3.3 Lineare Algebra (A.K.A LinAlg)

선형대수학이다. AI붐이 일어난 지금 조금 더 열심히 공부할 걸…이라는 후회가 드는 과목인데, AI 관련 코스는 추후에 대부분이 LinAlg를 전제로 삼는다.

따라서 AI쪽에 관심이 있는 학생이라면 이 과목은 열심히 공부하는 것을 추천한다.

이 과목은 조금 특이한데, 수업을 진행하는 교수님에 따라 난이도가 극명하게 갈린다. 대표적인 “나쁜” 교수님으로는 Karpfinger가 있다. 이 분의 악명(?)에 대해서는 조금 후에 설명하겠다.

선형대수학은 한국 공대에서 배우는(동생이 공부하는 책을 확인해봤을때) 것들과 크게 다르지 않다. 다만 TUM의 대부분의 수학 과목이 그렇듯이 증명 문제가 과하게 많이 나온다.

수준 자체만 놓고 보면 1학기때 배우는 DS에 비해서 양도 난이도도 많이 낮은 편이라고 생각한다. 하지만 크게 다른 점이 있는데:

연습(계산)문제를 과하다싶게 많이 풀어봐야 하는 부분이 있다는 것이다

방금 증명문제가 많이 나온다고 해놓고 무슨 소리인가 싶겠지만, Karpfinger교수님을 예시로 들어보겠다. Karpfinger 교수님의 시험같은 경우에는 50%의 계산문제, 50%의 증명문제로 출제된다.

문제는 계산문제에서 일반적인 다른 수학 과목들과 다르게 Folgefehler, 즉 부분점수가 존재하지 않는다. (나도 여기에서 점수가 어마어마하게 깎여나가 증명문제를 만점 맞았는데도 점수가 좋지 않았다)

보통 LinAlg의 계산 문제들은 많은 단계를 거쳐서 답에 도달해야 하는데 (예를 들어 Eigenvector 계산 후 Eigenraum 계산, 그 후에 계산된 Eigenraum의 특성을 적는 문제라던지) 여기서 정말 마지막 답만 보고 점수를 준다.

따라서 중간에 한 단계에서라도 실수를 한다면 그 후의 계산은 모조리 틀리기 때문에 그 문제의 점수를 받지 못하게 되는 식이다.

실제로 풀이과정을 적는 칸도 존재하지 않는다.

이 문제를 해결할 수 있는 방법은 정말 문제를 많이 풀어보는 것이다. 나는 증명에 너무 집중한 나머지(LinAlg의 증명 문제는 꽤나 재밌다) 문제를 많이 풀어보지 못했고, 시험 당일에 여기저기 계산실수를 많이 했다.

이건 애초에 교수님이 강조하시는 부분이기도 해서 (조금 한국적인 면이 있는 교수님이다. 증명보다는 활용이나 주어진 식에 대입하는 걸 더 좋아하신다) 그 말씀대로만 해도 충분하다.

이렇게 말하면 쉬워보이지만 낙제율이 60프로 가까이 되는 과목이기때문에 너무 긴장을 놓는것은 좋지 않다. 그리고 내가 해본 모든 과목중에 가장 복습의 중요성이 높았던 과목이었다.

중간에 일주일을 쉰다면, 그 다음주부터 진행하는 내용을 전혀 이해할 수 없다. 그도 그럴것이 그 주에 배운 내용을 다음주에 바로 써야하는 형식이기 때문에… 꼭 복습을 하고, 테마를 그때그때 이해하자. 다른 과목들보다도 이 과목에선 특히 중요하다.

3.4 Grundlagen der Algorithmen und Datenstrukturen (A.K.A. GAD)

컴공의 대표 과목이라고 할 수 있는 알고리즘과 데이터 구조 과목이다. 나도 입학 전에 이런저런 알고리즘 서적을 많이 접해봤었는데, 실제로 이 과목에서 배우는 내용도 그런 알고리즘 서적들과 많이 비슷하다.정렬부터 시작해서 고급 정렬 알고리즘, 힙 구조, Hash의 이론적 접근 등에 대해 배운다.

다른 점이 있다면 Tree 데이터 구조에 많은 시간을 할애한다는 부분이다(Tree 구조는 백준 기준으로 대부분 골드 상위 티어 이상이며, 플래티넘 문제가 가장 많았던걸로 기억한다). B Tree, AVL Tree등 트리란 트리는 다 배운 것 같다. Hash도 단순히 해싱이 아닌 수학적인 이론(LinAlg에서 배우는 내용이 여기서도 일부 나온다)에서 접근하여 여러가지 해싱 기법과 해싱의 궁극적 지향점에 대해 이론적으로 증명하는 시간을 갖는다.

이 과목 또한 Artemis에서 매 주 문제가 나오며, 70프로 이상 풀 시에는 보너스가 주어진다. GAD의 문제는 타 알고리즘 사이트의 문제와 비슷하다. 다만 백준 기준으로는 골드 이상의 문제들이 나오고 꽤나 많은 부분을 정확하게 구현하지 않으면 안 되기 때문에, 내 기억상으로 2학기때 가장 숙제를 푸는데 시간이 많이 걸렸던 과목이 GAD 아니었나 싶다.

시험 자체는 그렇게 어렵지 않다. 손으로 알고리즘을 따라하는 게 대부분이기때문에 알고리즘을 이해하고 있다면 통과하는 것에 대해선 큰 문제를 느끼지 못 할 것이다.

3.5 Funktionale Programmierung und Verifikation (A.K.A FPV)

1학년의 마지막 고비, 나를 포함한 많은 친구들이 재시험을 맛봐야했던 (실제로 내 스터디의 경우에는 이 과목에서 가장 많이 떨어졌었다. 대부분은 열심히 공부해서 재시험에선 합격했다) Functional Programming이다!

이 과목에서는 Haskell 아니면 Ocaml(최근은 Ocaml이 많다. 우린 중간에 Pascal이라는 고대 언어도 공부했다. 우리 어머니도 대학시절때 하셨다고 한다..)같은 함수형 언어로 프로그램을 짜는 법을 배운다.

함수형 언어란 간단하게 객체지향에 대척점 (물론 최근에는 둘을 합치려는 시도도 많다)에 있는 언어들인데, 실생활에서 사용하는 혹은 애초에 볼 수 있는 기회가 그렇게 많지 않기 때문에 굉장히 이질적이고 또 처음에 컨셉을 이해하고 익숙해지는데 많은 시간이 걸린다.

일단 이 과목의 문제점은, 대부분의 1학년생이 아직 재귀에 익숙하지 않다는 점에서 기인한다. 간단하게 코드를 한 번 봐보자.

type 'a tree =
| Leaf
| Node of 'a * 'a tree * 'a tree

let rec size = function
  | Leaf -> 0
  | Node (_, left_tree, right_tree) -> 1 + size (left_tree) + (size right_tree)

  (* 예시:
      2
     / \
    1   3  *)

이건 Ocaml에서 Tree를 사용하는 방법이다. 첫 번째 세 줄은 tree 자료구조를 정의한다. tree는 그림에서 볼 수 있듯이 당연히 Leaf(맨 밑에 오는 경우)거나 부모 - 왼쪽 subtree - 오른쪽 subtree 의 형식으로 나뉜다.

예시에 대입해보면 2는 트리 객체인 동시에 두 subtree를 가지고 있다. 이는 세 번째 줄의 타입에 해당한다. ‘a(노드 2), ‘a tree(왼쪽 subtree), ‘a tree(오른쪽 subtree)가 될 것이다. 그럼 재귀적으로 우린 두 개의 ‘a tree를 얻게 된다.

이 ‘a tree는 또다시 Leaf거나 부모 노드로서 2개의 subtree를 가지게 될 것이다. \

그렇다면 밑에 size 함수는 어떨까?

tree를 넣었을 때 Leaf인 경우(root 노드 딱 하나만 존재하는 경우, Leaf도 세고 싶으면 1을 return하면 된다)에는 0을 return하고 (기저조건), 부모 노드인 경우에는 1(부모 노드) + size l(왼쪽 subtree의 크기, 재귀 호출) + size r(오른쪽 subtree 크기, 재귀 호출)을 하면 될 것이다.

더 간단하게 말해서: tree의 총 node 개수가 얼마야? 라고 누군가 물었을 때 “왼쪽 트리의 크기와 오른쪽 트리의 크기를 합친 거야” 라고 대답할 수 있지 않겠는가? 방금 한 대답이 재귀적 문제풀이방식에 해당된다.

학기중 우리는 내내 이러한 문제들 (방금 본 예시는 단언컨대 Ocaml로 만들 수 있는 가장 간단한 문제이다)과 사고방식에 익숙해져야 하고, 학기말즈음에는 재귀적 사고방식에는 도가 트게 된다. CS적 사고방식을 키우는 데에는 많은 도움이 되는 과목이지만 그만큼 어렵다.

또한 이게 전부도 아니다! Ocaml은 두 번째 챕터에서 다루는 언어이고, 첫 번째 챕터는 “프로그램의 증명”에 관해 배운다. A라는 프로그램이 이러이러한 명령어가 주어졌을 때 정말 B라는 과제를 수행하는가? 에 대한 증명인데, 일단 부울 기호들에 아주 익숙해야지 수월하게 공부할 수 있다.

이건 여기서 설명하기는 조금 추상적인 내용이라, 강의를 직접 들어보는것을 추천한다. Loop Invariants라고 유튜브에 검색하면 이것저것 나올 것이다.

이 과목도 다른 과목들과 비슷하게 Artemis에 문제가 올라오며, 일 주일에 한 번씩 Tutorium에서 Quiz를 푼다.

Quiz와 Artemis에서 푼 문제들을 합산하여 가산점이 나온다. 시험은 우리 학년에서 처음으로 대면 온라인으로 치뤘는데, EIST와 비슷한 형식이지만 시험장에 직접 노트북을 들고가서 감시 하에 치는데, 이 시험이 정말 어렵다.

3.6 FPV의 시험

주어지는 시간은 두 시간으로, 두 시간 내에 3개의 이론 문제 (다지선다형 문제 하나, 프로그램 증명에 관한 문제 하나, Big Ocaml Tree나 Induction에 관한 문제 하나)와 3개의 프로그래밍 문제가 나온다.

그런데 그 4개의 프로그래밍 문제가 숙제에서 나오는 수준으로 어렵다 사실 숙제 문제와 대부분 비슷하지만, 아마 학기중에 느낄 것이다. Ocaml은 에러가 엄청나게 터진다.

타입 하나 잘못적으면 프로그램 실행 자체가 안되고 조그마한 실수만 있어도 전부 붉게 표시된다. 그리고 에러가 어디에서 발생하는지도 쉽게 나오지 않는다. (함수형 언어이니 당연하다)

하지만 제출한 프로그램이 실행이 안되면 로직이 대부분 맞더라도 바로 0점 처리된다! 이게 바로 악랄한 부분이다. 내가 아무리 로직을 잘 짜서 냈어도, 로직이 거의 완벽하게 작동해도 혹시 거기에 쉼표 하나가 잘 못 들어가서 컴파일이 안되면 바로 그 문제는 0점처리다.

이건 학기초부터 이야기되는 부분이고, 실제로도 그렇다. 절대 자비를 베풀지 않는다! 두 시간 내에 OCaml을 이용한 재귀 문제를 에러 없이 푸는 것은 정말 쉽지 않다. 아마 실제로 해보면 그 시간이 얼마나 짧은건지 느낌이 올 것이다. 각설하고, 그럼 어떤 식으로 시험을 준비하면 좋을까?

여기서 내가 말하고 싶은 부분은 선택과 집중이다. 일단 학기중에 많이 OCaml 프로그래밍을 해 보는 것은 당연하지만(숙제 끝났다고 방치하지 말고, 푼 문제를 n번 다시 풀어본다는 생각을 갖자), 이것만으로는 처음 시험을 보면 멘붕이 올 가능성이 크다. 적어도 나는 그랬다.

특히 시험을 칠 때, 프로그래밍 문제부터 시작하는걸 추천하며 꼭 어려운 문제가 섞여있기 때문에 프로그래밍 3개의 문제 중 2개를 완벽하게 푸는 것을 추천한다.

한 문제는 다른 이론 문제를 풀고 와서 시간이 남으면 (솔직히 남을 리가 없다고 생각하지만) 마저 푸는 걸로 하는 전략을 선택하는게 현명하다고 생각한다. 물론 누구나에게나 난이도의 차이가 존재하기 때문에 자신이 있다면 자신만의 방법을 찾는것도 좋겠지만, FPV는 전년도의 시험을 절대 공개하지 않는다.

따라서 어떤 식으로 시험이 나오는지 전혀 알 수가 없다. (물론 나는 내가 본 시험의 문제들을 가지고 있지만, 여기에 올리기는 조금 그렇다) 따라서 어떤 문제를 위주로 연습할지, 어디에 우선순위를 두고 시험을 진행할지에 대해선 충분히 고민해보는 것이 좋을것이다.

나 또한 첫 시험에서 엉뚱한 부분에 시간을 많이 할애하여 대부분의 시험 문제를 풀지 못한 채 제출했고, 수많은 친구들과 함께(탈락률이 70%였다…) Retake 시험을 응시해야 했다.

방학에 친구들과 많은 Learning Session을 가진 결과 도출한 결론이 선택과 집중이었고(당연히 Retake는 훨씬 어렵게 나왔다) 이를 통해 내가 아는 문제를 완벽하게 풀은 결과, 꽤 좋은 점수로 FPV를 통과할 수 있었다!

4. 1학년 2학기 후기

개인적으로 많이 힘든 일이 있던 시기이기도 했고, 일을 시작해서 정신이 하나도 없었던 기억 외에는 솔직히 어떻게 2학기가 지나갔는지 지금으로서는 잘 기억이 나지 않는다.

이 글을 보면 아시다시피, 대부분의 과목에 숙제가 존재하는 학기이고, 어떤 다른 학기보다도 숙제가 많다. 프로그래밍을 어마어마하게(각 과목별로 최소 일 주일에 3~4시간은 투자해야 문제들을 풀 수 있다!) 많이 해야하는 학기이기도 하다.

전반적으로 말해서 “나태해지려면 얼마든지 나태해질 수 있는 학기”인 반면에 “열심히 하려면 할 게 넘치다 못해 터지는 학기”라고 할 수 있겠다.

그리고 전자와 후자는 시험기간에 희비가 명확하게 엇갈린다. 원체 뜯어보면 여기저기 요구하는게 많은 과목들이라(애초에 GRA는 세미 논문을 학기말에 제출해야한다. 이거 우습게 보면 곤란하다), 조금 뒤쳐지기 시작하면 나중에 따라가기도 버거워진다.

따라서 버겁고 귀찮더라도 모든 과목의 숙제를 꾸준히 하도록 하자. 당장은 학기중에 놀고싶은 마음이 크겠지만, es rentiert sich! 시험기간에, 또는 나중에 붙는 가산점에서 그 점이 보답될 것이라고 확신한다. 그리고 긴 여름방학을 제대로 즐기도록 하자! 시험기간에 고생했으니, wir haben’s verdient! :D

5. 글을 마치며

오늘도 쓰다 보니 글이 많이 길어졌습니다. 쓸 점이 있을까 싶었는데 작성하다보니 이런저런 하고싶은 말이 많이 떠오르더라고요. 모두들 즐거운 대학생활 되시길 바라며, 1학년을 무사히 마치시길 바라겠습니다. 다음 글은 이어서 2학년 1학기와 진로선택에 관해 이야기해보겠습니다!

Source

  • Me!