brunch

You can make anything
by writing

C.S.Lewis

by 고드름웨어하우스 Aug 16. 2020

소프트웨어 학습 태도

적어도 7가지 학습 태도를 시도해보라.

이 글은 일곱 가지 학습 비법을 이야기하는 게 아니다. 변하지 않는 일곱 가지 학습 법칙을 이야기하려는 것도 아니다. 소프트웨어를 학습하는 누구나 적어도 일곱 가지 정도는 잊지 말고 시도해보라는 의미다. 소프트웨어를 학습하면서 좌절했거나 힘들거나 성장하고 싶거나 시작하는 사람이 시도해보길 바란다.


1. 내가 걷는 속력과 방향을 인지하자.

가장 먼저 필요한 것은 자기가 학습하는 방식이나 패턴을 한 발짝 물러나서 인지하는 것이다. 집에서 걸어서 어딘가 목적지를 가는 길이라고 생각해보자. 처음 가는 곳이라면 걸어갈 방향과 경로를 미리 찾아보거나 아는 사람에게 물어보기도 한다. 휴대폰이 익숙한 사람이라면 지도 앱을 펼쳐서 찾아갈 수도 있다. 걸어가는 동안에 옆에 누군가 같은 방향으로 가는 다른 사람이 있을 수 있다. 아는 사람이라면 속도를 맞춰서 같이 걸어갈 수도 있지만, 모르는 사람이라면 각자 속도로 각자 갈 길을 가고 있을 것이다. 그 사람이 어디로 가는지, 얼마나 빨리 걷는지 아니면 반대로 나보다 천천히 걷는지 중요하지 않다. 내가 가는 속력과 방향이 중요할 뿐이다.

내가 학습하는 과정에서 내가 학습할 수 있는 속도가 있다. 한꺼번에 인지할 수 있는 지식의 분량도 있다. 책을 읽더라도 읽고 기억할 수 있는 글자 수도 제한적이다. 자료가 모국어가 아니라 외국어라면 더 느려질 수도 있다. 무작정 앉아서 자료를 많이 찾아본다고 학습을 제대로 하고 있는 게 아닐 수도 있다. 학습의 방향이 문제 해결을 위해서 꼭 필요한 부속품이 아니라, 인과관계가 있거나 상관관계가 있는 것처럼 보이는 다른 지식을 학습하느냐고 시간을 더 많이 쏟기도 한다. 문제 해결을 위한 지식을 찾아 위에서 아래로  탐색을 했으면, 그 지식을 조합해서 아래서 위로 그 문제와 관련된 것인지 아닌지 종합적으로 판단해야 한다. 실제 개발 과정도 탑다운 방식으로 설계부터 구현까지 한 번에 끝날 것 같지만 그렇지 않다. 추상적인 상위 수준에서 구체적적인 하위 수준까지 몇 번이고 반복하면서 개발한다.


2. 익숙한 것을 내려놓고, 낯선 방식으로 해결하자.

우리가 익숙한 학습 방식은 누군가 강단에 서서 이미 구조화한 지식을 그대로 받아서 암기하는 방식이다. 그렇게 암기를 잘하면 시험을 잘 보고, 시험 성적이 좋으면 뛰어난 것으로 인지한다. 하지만 현실에 있는 소프트웨어 문제는 암기를 한다고 해서 해결할 수 있는 문제가 아니다. 다양한 도메인에 지식과 함께 소프트웨어는 말랑말랑하게 변화할 수 있어야 한다. 그러려면 소프트웨어를 학습하는 단계에서만이라도 익숙한 학습 방식을 내려놓고, 낯선 방식으로 직접 소프트웨어를 만들면서 해결하려고 해 보자.


학습을 하는 과정에서 스스로 자신의 학습 방식, 이해하는 방식, 설명하는 방식, 다시 학습과정을 개선하는 방식까지 학습에 대해 학습해야 한다. 그것은 앞서 설명한 속도와 방향을 인지하는 것에서부터 시작한다. 그리고 나면 익숙한 방식은 의도적으로 하지 않고, 의도적으로 낯선 방식을 선택해보자. 그러려면 제약사항을 추가하게 된다. 익숙한 것을 반복한다고 해서 학습 효과가 좋은 것이 아니다. 가만히 반복하거나 자연적으로 성장하는 음의 성장이라는 것이 있지만, 더 효과적인 방법은 의도적으로 낯선 환경을 만들고, 제약사항을 추가해서, 도전적이면서 살짝 어렵지만 재밌는 요소를 찾아서 학습하는 것이다.


익숙한 개발 환경이나 언어, 도구를 생각해보자. 익숙한 통합 개발 환경 대신에 터미널에서 CLI 명령으로만 빌드를 직접 해보는 것도 좋다. 마우스 없이 키보드만으로 단축키를 쓰는 것도 좋다. 새로운 언어를 배우는 중이라면, 이전에 내가 익숙하게 풀었던 문제나 코드를 새로운 언어로 풀어봐도 좋다. 함수를 작성할 때 10줄 이내로만 작성하려고 시도해봐도 좋다. 이렇게 제약사항을 추가하면서 의도적인 수련을 반복하는 것을 권장한다. 만약 제약사항을 찾기 어렵거나, 자기 자신을 돌아보기 어렵다면 서로 다른 관점에서 피드백을 줄 수 있는 타인과 함께 관찰하는 것부터 시작해보자. 마치 낯선 야생의 환경, 정글에서 살아남기 위해서 필요한 것을 학습한다고 비유해보자.


3. 개구리를 해부하지 말고, 직접 만들어봐라.

이 말은 니콜라스 네그로폰데가 한 말이다. 생물 시간에 누구나 한 번쯤 해봤을 만한 개구리 해부에 대해 이야기한다. 개구리를 더 잘 이해하려면 개구리를 해부하는 것보다는 개구리와 똑같다고 부를 수 있을 만큼 개구리를 직접 만들어보라는 말이다. 정말 개구리와 똑같구나 싶을 정도로 만들려면 그만큼 개구리를 깊이 있게 이해하고 분석하고 설계하고 만들어야만 가능한 일이다. 이 비유를 소프트웨어 분야에도 적용할 수 있다. 소프트웨어는 태생적으로 컴퓨터 과학의 이론과 전자공학 기반으로 만들어진 하드웨어 사이에 존재한다. 이론적인 배경을 학습하고 소프트웨어로 만들어보고, 하드웨어 구조와 특성을 학습하고 소프트웨어로 만들어보자. 이론과 동일하게 동작하거나 하드웨어 없이 하드웨어처럼 동작하도록 만들려면 그만큼 제대로 이해하고 만들 수밖에 없다.


운영체제를 해부해서 개념만으로 이해하기보다는 운영체제의 구성요소를 모듈로 나눠서 직접 구현해본다고 생각해보자. 컴퓨터 CPU와 메모리, 네트워크 동작 방식, 데이터베이스 시스템, 컴파일러 등등 학교에서도 이론적으로만 배우고 끝나는 과목들을 소프트웨어로 직접 구현해 보는 것과는 전혀 다른 경험이 될 것이다. 개구리를 해부만 해본 사람과 개구리를 직접 만들어 본 사람은 엄청나게 큰 차이가 생긴다.


4. 자존심을 버리고, 자존감을 키우자.

낯선 지식과 경험을 학습하는 것은 외롭고 짜증 나고 지치는 일이다. 옆에 똘똘한 다른 친구를 볼 때마다 자존심이 상하기도 한다. 가끔씩은 천재들을 만나면 내가 일주일 고민한 것은 몇 시간 만에 학습하고 문제를 해결하기도 한다. 그것은 위에서 비유했던 것처럼 열심히 걸어서 목적지에 가깝게 다가갔는데, 눈 앞에서 택시 타고 내리는 누군가를 보면 뭔가 억울할 때가 있다. 하지만 그럴 필요가 없다. 학습할 때만큼은 자존심을 키워서 다른 사람과 비교하지 말고, 자존감을 키워서 스스로와 비교하려고 해야 한다. 몇 시간 전에 몰랐던 것을 깨닫거나 하루 이틀 전에 작성한 코드를 개선할 점을 찾을 수 있으면 조금씩 자신만의 속도로 성장하고 있다는 증거다.


학습 과정은 당연히 혼자 해야 한다고 생각한다. 그러면서 더욱 옆사람과 비교하게 된다. 비교하면 할수록 더 괴롭고 자괴감이 들뿐이다. 이 말을 충분히 공감하지만, 그 생각을 버리지 못한다. 누군가는 알아서 잘하는 것 같은데, 나만 뒤쳐지는 것 같은 날이 대부분이다. 그럴수록 시야를 바깥으로 돌리지 말고, 스스로 내면을 향하도록 해야 한다. 학습 과정에서 정말 필요한 것은 내가 제대로 된 방향으로 잘 가고 있는지 누군가 인정해주는 것이다. 적어도 한 사람만 나를 인정해준다면 힘들어도 포기하지 않는다. 그런 사람이 옆에 있거나 내가 그런 사람이 되어 줄 필요가 있다.


5. 결과만 보기보다는 과정을 보자.

소프트웨어 개발은 결과적으로 문제를 해결하는 코드를 만드는 것이다. 그래서 결과 지향적으로 작성한 코드가 전부인 것으로 착각할 수 있다. 하지만 그렇지 않다. 문제 해결 과정에서 만들어진 코드 결과물은 문제 해결을 위한 솔루션 뿐만 아니라, 개발 과정에서 하는 논리적인 판단, 추론, 비교, 분류, 설득, 전달 과정이 포함되어야 한다. 코드 자체에 표현하지 않더라도, 설계부터 테스트, 코드 리뷰 과정, 이슈관리, 협업 과정 전체가 소프트웨어 개발 과정이다. 단지 코드가 전부가 아니다.


회사에서 선발이나 평가를 위해서 알고리즘 테스트처럼 점수화하기 쉬운 시험을 도입할 수 있다. 하지만 그런 평가 점수는 철저하게 평가를 통과하기 위해 작성된 코드에 대한 점수일 뿐이다. 그래서 알고리즘 테스트는 최소 프로그래밍 역량을 확인하는 수준이 바람직하다. 알고리즘 테스트로 실무 역량을 측정하는 것은 크게 상관관계가 없다. 함께 일하기 적합한 사람인가 확인하는 가장 좋은 방법은 말 그대로 같이 일해보는 것이다. 모든 교육 현장에서는 과정 중심으로 평가를 하기 위해서 노력을 많이 해야 한다. 정량적이고 기계적인 평가에서 벗어나야 한다. 요즘은 현업에서도 같이 일하는 사람들의 동료 평가를 더 중요하게 생각하는 회사도 많다.

당장 작성한 코드가 보여주는 나무만 보지 말고, 다른 코드와 함께 숲을 바라보기도 해야 한다. 좋은 방법으로는 짝 프로그래밍하면서 내비게이터와 드라이버를 번갈아 가면서 시야를 바꾸는 연습을 하는 것이다. 학습 과정에서 혼자 개발하다 보면 드라이버 시야에서 앞만 보고 달려서 기능 개발에만 만족하기도 한다. 그래서 가끔씩 내비게이터가 돼서 방향을 정하고, 이슈를 확인하고, 설득하는 과정이 필요하다.


6. 실수를 반복하면서 적어도 하나씩 개선하라.

사람들은 모두가 완벽하지 않아서 개발 과정은 완벽하지 않다. 개발자는 끊임없이 실수한다. 가장 많이 하는 실수는 컴파일 과정부터 걸러진다. 실수를 하는 것을 두려워할 필요가 없다. 오히려 실수를 하지 않으려고 하다 보면 문제가 될 수 있다. 우리는 실수를 반복하면서 익숙해지고, 익숙해지면서 성장한다. 본인이 실수를 통해서 성장하려면 적어도 하나씩 개선하면 된다. 실수를 방지하기보다는 실수를 통해서 배운 것을 개선하고, 자동화하고, 도구화하고, 다음 단계로 학습하며 나아가야 한다.


개선하는 포인트는 여러 가지 관점에서 달라질 수 있다. 개발 환경에 대한 개선부터, 코드를 작성하기 위한 고민거리, 코드 버전 관리를 위한 도구, 하다못해 코딩 스타일 표기법까지 다양하다. 학습하고 성장하는 과정에서 실수를 두려워하지 말라는 의미이다. 우리가 만드는 소프트웨어 코드가 항상 실수투성이여도 된다는 의미는 아니다. (그렇다고 실수가 없을 수는 없겠지만) 소프트웨어 설계부터 테스트까지 개발 과정에서 실수는 줄이고 결과 산출물은 어느 시점에서든지 깨끗한 상태를 유지하도록 노력해야 한다. 설계나 테스트하는 과정은 의도한 대로 (실수를 줄이고) 소프트웨어가 제대로 동작하도록 만들기 위한 것이다. 소프트웨어 공학 측면에서는 함께 중요한 것들도 있다. 개발 과정에서 버그를 발견해서 수정하는 것도 개선이고, 협업 과정에서 개발 프로세스의 병목 지점을 찾는 것도 개선이다. 애자일에서 지향하는 것은 모든 문제를 해결하는 단 하나의 방법을 의미하기보다는, 주어진 상황과 절차, 과정, 협업하는 모든 과정에서 점진적으로 개선하는 작은 방법들의 집합이라고 할 수 있다.


7. 스스로 여러 가지 답을 찾고, 남에게 공유하라.

단 하나의 답을 찾기보다는 각자 다른 답을 가진 동료들과 함께 여러 가지 답을 찾으려고 하자. 엔지니어가 하는 일은 여러 가지 답을 찾는 것이다. 모든 상황에서 완벽한 단 한 가지 방법은 과학자들이 찾는 수식에만 있다. 그 수식을 현실에서 구현할 때는 주어진 환경에 맞춰서 다양한 해결 방법이 있다. 소프트웨어 엔지니어 분야는 다른 엔지니어링 분야보다 더 다양하고 유연한 해결 방법이 존재한다. 물리적으로 주어진 환경을 시뮬레이션하기 때문이기도 하고, 소프트웨어 개발 환경 자체가 유연하기 때문이다.


그렇게 유연한 환경에서 개발하는 데도 학습하다 보면 익숙한 환경에서만 모든 것을 해결하려고 생각이 닫혀버리기도 한다. 그래서 소프트웨어 엔지니어에게 중요한 것은 사고의 유연성이다. 말랑말랑하게 사고할 줄 알아야 한다. 소프트웨어는 어느 분야 전문가든지 함께 일을 해야만 하는 데, 다른 분야에서 익숙한 사고방식이 새로운 분야에서는 닫혀버린 사고방식이 될 수 있다. 말랑말랑하게 말할 줄 알아야 한다. 남을 설득한다는 핑계로 혹은 잘잘못을 가리거나 논리적으로 독소 가득한 표현을 써서 상대를 이겨야만 뛰어난 것이 아니다.

소프트웨어 분야가 상대적으로 발전이 빠르고 변화에 익숙한 것은 오픈 소스 문화가 보여준 유연한 사고방식에 있다. 마치 의사들처럼 경험을 공유하고, 코드를 공유하고, 다른 사람 코드에 기여하면서 작은 프로젝트가 거대한 오픈 소스 프로젝트가 된다. 우리나라는 라이선스에 대한 인식이 상대적으로 잘 되어 있지 않다. 아이들에게 코딩 교육을 한다는 그 어디를 봐도, 라이선스를 표시하거나 인용하거나 출처를 밝히는 것을 본 적이 없다. 해외에서는 아이들이 만드는 학습용 소프트웨어도 자기가 작성하지 않는 코드뿐만 아니라, 직접 제작하지 않는 이미지나 리소스까지 라이선스를 표기한다. 어른도 소프트웨어는 무료로 복제해서 사용해도 된다는 의식이 팽배하다. 모바일에서 앱이나 앱 내 아이템 구매가 익숙해지고 있지만 현질이라고 폄훼한다. 오픈 소스 문화와 가치를 인정하자는 게 아니라, 코드나 리소스 라이선스에 대한 인식부터 바꿔야 한다.


오픈 소스 문화가 가지는 가장 큰 장점은 다른 사람과 공유한다는 점이다. 오픈 소스도 세부적으로는 정말 다양한 라이선스 정책이 있다. GPL처럼 일부를 사용하는 코드는 무조건 공개해야 하는 철학적인 라이선스도 있고, MIT나 APACHE처럼 좀 더 유연하고 사용하기 자유로운 라이선스도 있다. 구글, 페이스북, 애플, 마이크로소프트 같은 큰 회사들 직원들도 오픈 소스에 기여하고, 비즈니스를 확장한다. 오픈 소스를 기반으로 하기 때문에 무료로 배포하는 리눅스라는 운영체제를 가지고 사업을 하는 레드헷 같은 회사도 존재한다.


오픈 소스 철학이 너무 거창한 것 같다면, 학습 과정에서 다른 사람과 지식을 공유할 방법을 찾아보자. 내가 학습하고 작성한 코드를 그대로 공유하라는 게 아니다. 내가 다른 사람이 작성한 코드를 그대로 가져와서 복사 붙여 넣기 해서 사용하는 것은 나에게 전혀 도움이 되지 않은다. 학습자 입장에서 오픈 소스를 사용하려면 해당 소스를 이해하고 필요한 부분을 수정해서 오픈 소스에 기여할 수 있는 수준에서 사용하는 게 좋다. 그렇지 않으면 독이 든 술잔을 들고 있는 꼴이다. 언제 독을 마실지 모른다는 의미다. 반대로 학습하기 어려워하는 친구가 있다고 해서 코드를 주는 것도 좋지 않는 방법이다. 정말 어디부터 시작할지 모르겠다면, 다른 사람 코드를 눈으로 가볍게 읽고 덮은 다음에, 처음부터 자기만의 방식으로 다시 작성해보길 권장한다.




소프트웨어 학습 과정은 혼자서 묵묵히 학습하는 것보다는 비슷한 고민을 하는 동료가 함께 하는 것을 권장한다. 스터디 그룹처럼 다양한 배경을 가진 4-5명이 함께 하면 서로 피드백을 주기도 적당하다. 옆에 다른 사람이 학습하는 과정을 살펴볼 수도 있고, 그러면 자신의 속도와 방향을 인지하기 쉽다. 그렇지만 옆에 있는 친구가 잘하는 것 같으면 상대적인 박탈감을 느낄 수도 있다. 우리는 학교를 다니면서 친구들과 경쟁에 익숙해서, 자기 자신을 보는 게 아니라 숫자를 비교하는 데 익숙하다. 자존감을 높이려면 어제의 나, 일주일 전의 나와 비교해야 한다. 내가 내 속도로 성장하고 있다는 것을 깨닫는 게 중요하다. 옆에 있는 친구도 똑같이 외로울 테니 서로 잘하고 있다는 것을 인정해주자. 짝 프로그래밍을 시도해보는 것도 좋다. 하지만 짝 프로그래밍이 힘들기만 하고 대화하기 어렵다면 과감하게 포기해도 된다.


구체적으로 지식을 학습하고 코드를 작성하는 단계에서는 책이나 블로그를 보면서 따라 하는 것으로 만족하면 안 된다. 그건 사고하는 과정이 빠진 상태로 결과를 복사해서 붙여 넣는 것뿐이다. 죽은 개구리를 해부한 것처럼 펼쳐진 코드를 공부하기보다는, 직접 만들려고 시도해봐라. 50% 정도 비슷하게 만드는 건 엄청 쉽다. 90% 정도 비슷하게 만드는 것은 꽤 어렵다. 99% 이상으로 똑같이 만들려면 원리를 명확하게 이해하고 구현해야만 가능하다. 구현하는 과정은 익숙한 방법으로 쉽게 해결하지 말고, 낯선 환경에서 제약사항을 추가하면서 점진적으로 구현하자. 같은 문제를 제약사항을 바꾸거나 동작 환경을 바꿔서 다른 시각에서 해결해보는 것도 좋다. 학습 과정에서는 일부러 실수를 해보자. 아직 동작하는 코드를 만들지 못하면 초조한 마음이 생길 수 있다. 그럴수록 이런저런 방향으로 시도해보고 실패해보고 방황해보는 게 좋다. 무작위로 아무 방향이나 하기보다는 조건을 가정하고 결과를 예측하고 시도하고 테스트하면서 측정해서 가정이 맞는지 공학적인 반복 주기를 만들어보자. 그러고 나서 개선해도 늦지 않다.


마지막으로 그렇게 학습한 과정, 실패했던 가정들, 측정하기 위한 방법들, 결과적으로 선택한 해결 방법과 결과 코드를 정리해서 오픈 소스 형태로 공유하려고 해 보자. 꼭 깃헙에 올려야 하는 것은 아니다. 자신의 생각을 자기만의 표현으로 설명할 수 있으면 된다. 함께 학습하는 동료가 있다면 말로 설명하고 피드백을 받는 것도 좋다. 이미 알고 있다고 생각했던 것도 말로 표현하지 못하는 경우도 많다. 아직까지는 채용 인터뷰들이 알고 있는 것을 설명하도록 전화나 화상, 대면으로 진행하기 때문에 말하기 연습도 필요하다. 소프트웨어 개발자는 코드로 보여준다지만, 자신의 코드가 의도한 자신의 생각은 꼭 설명할 수 있어야 한다.

작가의 이전글 온라인 소프트웨어 교육에 필요한 하드웨어
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari