자기소개서와 포트폴리오를 작성하기
이 글은 프로그래머이면서 교육자로 살고 있는 한 명의 아빠가 아들과 함께 프로그래밍을 하면서 느낀 점을 기록하고 있는 글이다. 나와 아들의 추억을 남기기 위해 기록으로 남기고 있다.
아들과 함께 프로그래밍한 이전 이야기
아들과 함께 프로그래밍하기: 아들이 프로그래밍을 시작한 과정과 소물에서 발표한 내용
아들과 함께 프로그래밍 2: 다시 프로그래밍 학습을 시작하게 된 계기
아들과 함께 프로그래밍 3: 다음 단계의 성장을 위해 오프라인 교육 참여를 통해 느낀 점
아들과 함께 프로그래밍 4: 프로그래밍 학습을 마치고 개발자로서 시작한 과정
아들과 함께 프로그래밍 4 글의 마지막 부분에서 언급했듯이 아들은 고3으로 학교를 다니며 밑바닥부터 만드는 컴퓨팅 시스템 책을 학습하고 있다. 이 책은 이론적인 내용보다 컴퓨터를 직접 만들고 내가 직접 만든 컴퓨터에서 동작할 가상 머신, 고수준 언어, 운영체제까지 구현해보는 상당히 난이도가 있는 책이다. 컴퓨터의 동작 원리가 궁금하다고 해서 추천하기는 했는데 난이도가 너무 높아 끝까지 구현하리라는 기대는 하지 않았다.
이번 글에서는 아들이 어떤 과정으로 이 책을 학습했는지에 대해 다뤄보려고 한다. 아들은 학교에서 집에 있는 노트북에 접속해 프로그래밍 실습을 할 수 있는 환경을 구축했다. 학교 공부에는 아무런 관심도 없는 환경에서 프로그래밍 학습을 하는데 한 가지 장점이 있었다.
고3의 경우 대부분의 수업이 강의를 진행하는 것이 아니라 상당히 많은 시간(최대 50%까지)이 자습을 할 수 있는 환경이다. 그렇다 보니 선생님이 강의를 할 때는 구현해야 할 미션에 대한 설계나 손 코딩을 하고, 자습을 할 때는 설계나 손 코딩한 부분을 구현하는 방식으로 학습하는 것이 가능했다. 프로그래밍을 학습할 때 처음부터 무작정 구현을 시작하지 말고 설계나 의사 코드(pseudocode)를 작성한 후에 구현을 시작하는 것을 추천하는데 자연스럽게 이 방식으로 학습할 수밖에 없는 환경이 되었다. 구현 전에 설계나 의사 코드를 작성하라고 가이드하지만 설계나 의사 코드를 작성하는 것보다 구현이 훨씬 재미있기 때문에 대부분의 개발자들은 미션 요구사항을 받으면 바로 구현을 시작한다.
프로그래밍을 할 때 설계나 의사 코드의 중요성이 높은 부분은 요구사항 복잡하고 구현의 난이도 높은 경우이다. 아들 또한 ALU와 컴퓨터 구현과 같이 난이도가 높은 부분을 구현할 때 사전 설계나 의사 코드를 통해 검증하고 이후에 구현하는 방식으로 학습하고 있었다. 내가 특별히 어떻게 학습하라고 가이드하지 않았음에도 불구하고 자연스럽게 이 방식으로 학습하고 있어서 놀랐다.
밑바닥부터 만드는 컴퓨팅 시스템 책의 난이도가 높아 금방 포기할 줄 알았는데 미션을 하나씩 구현해 나가면서 재미도 생기고 자신감도 생기면서 5장의 컴퓨터 구현까지 완료했다. 검색을 하면 다른 개발자가 구현한 코드가 있음에도 불구하고 혼자 힘으로 모든 미션을 구현하다 보니 자신감은 점점 더 높아지고, 학습에 대한 재미도 생기는 것을 느낄 수 있었다.
하드웨어 영역이라 할 수 있는 컴퓨터 구현을 완료하고 소프트웨어 영역으로 넘어가 가상 머신을 구현하고 있을 때 우아한형제들에서 진행하는 우아한테크캠프 4기 모집 소식이 들렸다. 고3 이상 지원할 수 있는 여름 방학 인턴 과정이라 한번 도전해 볼 것을 추천했더니 지원해 보겠단다. 이전에는 경진대회 같은 곳 지원해 보라고 아무리 설득해도 아무 관심도 없다고 하더니 자신감이 생겼는지 갑자기 달라진 모습을 볼 수 있었다.
그렇게 밑바닥부터 만드는 컴퓨팅 시스템 책의 학습을 잠시 중단하고 우아한테크캠프 지원을 준비하기 시작했다. 지금까지 한 번도 작성해보지 않았던 자기소개서와 포트폴리오를 작성해 나갔다. 몇 날 며칠을 끙끙대며 작성한 자기소개서와 포트폴리오를 보여주며 피드백을 달라고 했다. 기대 이상으로 잘 작성해 구체적인 피드백을 주기보다 칭찬만 해주고 말았다.
Q. 본인이 생각하는 개발자가 갖추어야 할 덕목과, 여기에 비추어 봤을 때 본인의 어떤 점이 개발자로 일하기에 적합하다고 생각하시나요?
A. 개발자는 다른 사람이 제시한 의견을 경청해 듣고 자기가 생각한 방법보다 좋은 의견이라면 이를 수용하고 받아들이는 마음을 갖추어야 하고 자신의 의견이 더 좋다고 생각된다면 주장할 수 있는 마음도 가지고 있어야 합니다. 저는 다른 사람이 의견을 제시할 때 그냥 받아들이는 것이 아닌 ‘이 의견을 꼭 받아들여야 하는가?’, ‘더 좋은 방법이 있지 않을까?’ 등등 여러 가지 생각을 한 후 결정을 합니다. 또한 이해가 되지 않거나 다른 더 좋은 의견이 생각난다면 질문을 통해 서로 의견을 주고받으면서 더 좋은 방법을 생각해내기도 합니다. 낯가림이 심해서 별로 친하지 않은 사람들과 오랜 시간 의견을 주고받는 건 힘들 수 있지만 다른 사람의 의견에 대한 내 생각을 말하거나 내 의견을 주장하는 건 잘할 수 있습니다.
Q. 우아한테크캠프에 참여하고 싶은 이유를 자유롭게 기술하여 주세요.
A. 지금 고등학교를 다니면서 코딩을 하고 있습니다. 자는 시간을 제외한 하루의 절반 이상을 학교에서 보내기 때문에 자유롭게 프로그래밍을 학습할 수 있는 시간이 조금밖에 없습니다. 자습시간이나 쉬는 시간을 이용하여 학교에서도 학습하고 있지만 노트북을 사용하면 키보드 소리가 시끄러워서 친구들에게 피해를 줄까 봐 아이패드를 이용한 맥북과의 화면 미러링을 통해 불편한 환경에서 학습하고 있습니다. 몇 달만 참으면 졸업하여 이런 환경에서 벗어날 수 있지만 우아한테크캠프에 참여하게 된다면 좀 더 빠르게 좋은 환경에서 작업할 수 있다고 생각하여 참여하고 싶습니다. 또한 혼자 학습하다 보면 다양한 갈림길이 존재합니다. 클래스 설계, 중복 제거, 전체적인 흐름 등등 어떤 방식으로 구현하는 게 옳은 건지 정답은 없겠지만 더 깨끗하고 효율적인 코드를 작성하기 위한 방법을 배우고 싶기 때문입니다.
우아한테크캠프에 지원한 이유를 보면서 약간은 마음이 아팠지만 본인이 고등학교를 자퇴하지 않고 끝까지 마무리하겠다는 결정을 했으니 어쩌겠나? 재미없고, 지루하지만 끝까지 마칠 수밖에.
포트폴리오도 작성해야 하는지 물어보길래 경험 삼아 작성해 볼 것을 추천했다. 포트폴리오의 첫 번째는 밑바닥부터 만드는 컴퓨팅 시스템 책을 통해 구현한 컴퓨터였다. 컴퓨터를 구현한 것이 기존의 다른 소프트웨어에 비대 더 뿌듯했나 보다.
처음 접해보는 하드웨어 시스템 이기에 삽질도 많이 하고 상당히 지저분한 회로로 구현되어있습니다. 그래도 처음부터 끝까지 힌트 없이 제 스스로의 힘으로 구현했다는 점이 뿌듯합니다.
하드웨어 칩을 직접 만들며 제일 어려웠던 점은 python, java 등등 고수준 언어는 if문이 있어 조건에 따른 기능 수행을 쉽게 구현할 수 있지만 하드웨어 칩을 구현할 때는 if문이 없었다는 점입니다.
평소 하드웨어에 관심이 많았고 컴퓨터가 어떤 방식으로 동작되는지 궁금했었는데 책을 읽고 직접 만들어보면서 컴퓨터는 무식한데 속도만 빠르다는 것을 다시 한번 느꼈고 최초로 컴퓨터를 만들어낸 사람들과 지금의 컴퓨터로 발전시킨 사람들이 새삼 대단하게 느껴졌습니다.
그렇게 우아한테크캠프에 지원하고 코딩 테스트까지 참여했다. 4문제를 2시간 30분 동안 풀어야 하는 코딩 테스트였는데 한 문제 풀고 두 번째 문제 풀다가 끝났다고 한다. 코딩 테스트 언어가 자바스크립트였는데 지금까지 코틀린과 파이썬을 주력 언어로 사용하고, 자바스크립트는 웹 프로그래밍할 때 조금씩 사용해 본 경험밖에 없다 보니 예상보다 더 힘들었던 것 같다.
결과는 1차 코딩 테스트에서 탈락했다. 비록 탈락했지만 이번 지원을 통해 자기소개서와 포트폴리오를 작성하는 경험과 코딩 테스트가 어떻게 진행되는지에 대한 경험을 할 수 있어 그리 낙담하는 눈치는 아니다. 앞으로도 또 다른 기회는 많을 테니까.
아들은 우아한테크캠프 탈락에서 금방 회복했다. 다시 학교를 다니고, 밑바닥부터 만드는 컴퓨팅 시스템 미션을 다시 시작했다.
하드웨어에 대한 구현을 마치고 소프트웨어 영역으로 넘어왔을 때의 첫 번째 미션은 어셈블리어를 기계어로 변환하는 어셈블러를 구현하는 미션이었다. 이 미션은 예상보다 수월하게 완료했다.
미션 구현을 다시 도전했을 때 지금까지 구현했던 다른 미션에 비해 가장 난이도가 높은 가상 머신 2단계를 구현하는 것이었다. 가상 머신 2단계는 함수를 실행해야 하는 부분을 구현하는 미션이었는데 책이 설명하는 이론적인 내용을 아무리 읽어봐도 무슨 말인지 도통 이해가 되지 않는다며 어려움을 호소했다. 아무래도 가상 머신에서 함수를 호출해 실행하고 결과를 반환하는 과정이 힘들었으리라.
지금까지 미션을 진행하는 과정에서 어려움을 토로한 적이 없다 보니 정말 어려운 미션인가 보다고 생각하며 기다렸다. 그렇게 일주일을 기다렸을까? 배부르다며 같이 저녁 먹자는 제안도 거절하더니 저녁을 먹고 있는데 미션 구현에 성공했다는 반가운 소식을 전해왔다. 나는 아들의 미션 성공을 응원하기 위해 아들이 보낸 PR에 적극적인 피드백으로 호응해 주었다.
가상 머신 2단계 구현을 완료하고 아들과 가상 머신 구현에 대해 이야기하는 시간을 가졌다. 아들은 "지금까지 구현했던 파이썬과 코틀린에서 함수를 실행하는 과정 전체가 이해됐다."며 함수 호출과 반환까지의 과정을 설명한다. 나는 함수 실행 과정을 이해하기 위해 프로그래밍 언어 책을 몇 번씩 읽어봐도 잘 이해되지 않았던 기억이 있다. 프로그래머로 지낼 때는 관심도 없다 교육자의 길을 걷기 시작하면서 학습하기 시작했다. 프로그래머 경력 10년이 넘어서야 이해했던 내용인데 가상 머신 구현을 통해 빠르게 이해하는 것을 보면서 역시 가장 빠른 이해는 직접 구현해 보는 것이라는 것을 새삼 느낄 수 있었다.
책의 후반부로 갈수록 난이도가 점점 더 높아져 갔다. 특히 "10장 컴파일러 I: 구문 분석"과 "11장 컴파일러 II: 코드 생성" 미션을 진행할 때 가장 어려워했다. 10장과 11장 모두 책을 읽어도 무엇을 구현해야 할지 몰라 막막함으로 시작했다. 그런 막막함으로 며칠을 고민하더니 조금씩 도전하고, 해결하고, 다시 또 다른 문제를 만나고 해결하고의 반복이었다. 이런 반복의 과정을 거쳐 10장은 2주, 11장은 3주 만에 미션 구현을 완료했다. 책의 앞부분에서는 일주일에 2개의 미션을 완성하는 경우도 있었는데 그에 비하면 확실히 난이도가 높아졌다.
미션의 난이도가 높고, 무엇을 구현해야 할지 모르는 막막함 속에서도 포기하지 않고 도전을 반복한 부분과 온라인을 찾아보면 다른 사람이 구현한 코드도 있을 텐데 다른 사람의 도움 없이 스스로의 힘으로 미션 구현을 완료했다는 점을 칭찬하고 싶다. 아들이 밑바닥부터 만드는 컴퓨팅 시스템 책의 미션을 구현하며 얻은 가장 의미 있는 경험이 막막함 속에서도 끊임없이 길을 찾으면 길을 찾을 수 있다는 것이라 생각하다.
아들이 "11장 컴파일러 II: 코드 생성" 미션을 진행할 때였다. 미션에 대한 해결책을 찾지 못해 방황하고 있을 때 뜬금없이 이런 말을 했다.
아들: 아빠. 내가 이전에는 산을 하나 넘으면 더 높은 산이 나타나고, 또 하나를 넘으면 또 산이 등장하는 그런 류의 소설을 좋아하지 않았거든.
나: (무슨 뚱딴지같은 소리 하느냐며)...
아들: 최근에 계속해서 문제를 만나고 해결하는 그런 류의 소설을 읽고 있는데 딱 내가 그렇더라고. 하나를 해결하면 더 큰 문제가 등장하고...
나: 아빠가 의도적으로 미션을 그렇게 설계했거든. 지금 네가 가지고 있는 실력보다 약간 높은 미션에 도전할 수 있도록 말이야. 우리의 삶 또한 비슷해.
아들: ...
나: 이런 과정을 즐기면 좋겠다. 너를 성장시킬 수 있는 좋은 기회로 생각해라.
그렇게도 힘들어하던 10장과 11장도 모두 끝내고 대망의 "12장 운영체제" 구현을 시작했다. 책을 처음 도전할 때의 목표는 2개월이었는데 3개월을 채워가고 있었다. 6월 말까지 끝내는 것을 목표로 했는데 남은 시간은 일주일이었다. 일주일 안에 나를 도와 깨도 심으러 가야 하는 상황이라 시간적 여유가 많지 않았다. 그래서일까 깨를 심기 전후 남는 시간에 미션 구현에 집중하는 모습을 볼 수 있었다.
오전에 깨 심는 일을 모두 마치고, 오후에 바다가 보이는 카페에 들렀다. 이곳에서 아들과 12장 운영체제의 String.jack API를 짝 프로그래밍으로 구현하는 즐거운 경험도 할 수 있었다.
주말이 끝나고 월요일부터 1학기 기말고사 기간이었다. 기말고사 기간에는 시험이 끝나면 바로 하교하다 보니 1,2교시 후에 집으로 왔다. 집에 돌아오면 친구들과 3, 4시간씩 철권(최근 아들은 철권 게임에 빠져있다.)을 한다. 그렇게 한참 동안 철권을 한 후 아들의 공부가 시작된다. 기말고사 시험공부가 아닌 12장 운영체제 미션 구현이다. 그렇게 아들과 약속한 6월 말이 다가오고 있었다.
6월 30일. 기말고사 3일 차. 집에 오자마자 점심을 먹은 후 방에서 꿈쩍도 하지 않는다. 웬일인지 그 좋아하던 게임도 하지 않는다. 저녁 먹을 즈음 아들이 github push가 되지 않는다면 도움을 요청한다. 맞다. 운영체제 미션을 모두 완료하고 github push를 하는 순간이었다. 이로써 밑바닥부터 만드는 컴퓨팅 시스템 책과 함께한 3개월 과정이 끝나는 순간이었다. 아들은 6월 말까지의 약속을 지켰다. 정말 힘든 도전이라 생각했고, 끝까지 완료할 수 있으리라 기대하지 않았다. 하지만 어느 순간 아들은 많이 성장해 있었다. 특히 인터넷이나 주변의 어떠한 도움도 받지 않고 스스로의 힘으로 모든 미션 구현을 완료했다는 점을 더 인정해 주고 싶다.
'컴퓨터의 동작 원리가 궁금하다.'는 아들의 호기심으로부터 시작한 과정이다. 코드 책을 읽고 밑바닥부터 만드는 컴퓨팅 시스템 책의 미션 구현을 통해 컴퓨터 내부 동작 원리를 이해하는 쉽지 않은 과정이었다. 나 또한 밑바닥부터 만드는 컴퓨팅 시스템 책에 도전했지만 4장까지 진행한 후 바쁘다는 핑계로 미뤄두고 있었다.
이 말은 5장 이후부터 내가 아무런 도움도 줄 수 없다는 것이다. 정말 그랬다. 아들이 이 책에 도전하는 중 나는 어떠한 도움도 줄 수 없었다. 아들의 고민을 들어주고, 같이 고민해 주는 척하고, 위로하고, 할 수 있다는 자신감을 주는 것이 전부였다.
내가 아무런 도움을 줄 수 없는 미안함 때문에 "정말 해결하기 힘든 미션은 인터넷에 다른 사람이 구현한 코드를 참고해 봐라."라는 메시지를 던지기도 했다. 인터넷에 올라와 있는 구현 코드의 도움을 받을 수 있었음에도 불구하고 아들은 끝까지 스스로의 힘으로 모든 미션 구현을 완료했다. 어쩌면 처음부터 온전히 자신의 힘으로 모든 미션을 구현했기 때문에 난이도가 높아지는 이후의 미션도 스스로의 힘으로 구현할 수 있었으리라 생각한다.
역시나 아이들은 어른들이 생각하는 것보다 빠르게 성장하고, 자신이 좋아하는 것이라면 몰입도 잘한다는 것을 느낄 수 있는 3개월이었다. 어른들은 아이들이 하고 싶은 일에 몰입할 수 있는 환경을 만들어주고 무한한 신뢰를 주는 전부라는 생각을 했다.
아들을 통해 나 또한 많은 것을 보고 배울 수 있는 의미 있는 시간이었다. 아들과의 이 경험이 앞으로 소프트웨어 교육 과정을 설계하는데도 큰 도움이 될 듯하다.
‘밑바닥부터 만드는 컴퓨팅 시스템’ 책의 6장부터 12장까지 읽으며 구현한 컴퓨터의 소프트웨어입니다. 어셈블러를 시작으로 가상 머신, 컴파일러, 운영체제까지 만들게 됩니다.
가상 머신과 컴파일러는 1, 2단계로 나뉘어 있는데 1단계를 힘겹게 해결하고 나면 2단계를 다시 한번 힘겹게 해결해야 했습니다.
컴파일러는 어떤 식으로 구현해나가야 하는지 감이 잡히지 않아 막막했고 운영체제는 감이 잡히지만 예상치 못한 곳에서 에러가 발생해 어려웠습니다.
불가능할 거라 생각했던 컴퓨터를 전체적으로 만들어 보면서 미지의 어려움이 들이닥치면 긴장하게 되고 떨리지만 한발 한발 조금씩 나아가다 보면 마지막엔 처음 두려움을 느끼던 나 자신보다 한층 더 성장한 내가 기다리고 있다는 것을 느꼈습니다.