참고자료 : https://github.com/Gyubin/TIL/blob/master/ETC/how_to_study_programming.md


프로그래밍, 어떻게 공부할 것인가

김창준님의 마인드스케일 강의 기록

1. 연습량

전문성은 자동으로 획득되지 않는다. 연습량이 가장 중요하다.

  • 세계적 수준: 1만 시간
  • 전문가 수준: 8000 시간
  • 선생님 수준: 5000 시간
  • 아마추어: 2000 시간

대부분의 현업 프로그래머 수준은 2000, 3000, 5000 정도. 중요한 것은 업무량과 연습량은 다르다는 것.

  • 재즈 기타리스트의 경우 공연시간과 실력은 상관없었다. 지하실에서 혼자 연습한 시간은 유의미했다.
  • 체스 선수에서 토너먼트에서 경기를 치룬 시간은 상관없고, 혼자 복기하거나 연습한거는 유의미

2. 의도적 수련

  • work
  • play
  • deliberate practice(의도적인 연습)

24시간의 모든 활동은 위처럼 분류할 수 있다. 일반적 연습과 의도적 수련은 다르다. 어떤 부분이 약하면 그 부분에 집중해서 연습한다는 것이 의도적 수련이다.

피겨스케이트 선수 분석함. 세계적 선수 vs 지방 선수. 트리플 악셀을 세계적 선수들은 10번 이상 하지만 지방 선수들은 1-2번. 그래서 결과적으로 세계적 선수들이 더 많이 넘어짐. 지방 선수들은 자기가 잘하는 걸 더 많이 함.

A. 의도적 수련 정의

  • 잘 정의된 작업 - well defined task
  • 적절한 난이도 - appropriate difficulty
  • 정보가 풍부한 피드백 - informative feedback
  • 반복과 실수 교정의 기회 - opportunities for repetition and correction of errors

좀 더 구체적으로 SQ3R 방법론(시간이 많이 걸리므로 약식으로 3R만 해도 된다)

  • Survey: 목차를 보는 등에서 슥 훑어보기
  • Question: 생긴 질문 정리하기
  • Read: 궁금한 점을 찾았으니 적극적으로 읽게 됨
  • Recite: 책을 덮고 최대한 무슨 내용이었는지 생각하거나 적어보기
  • Review: 기억한게 맞는지 확인하기.

B. 프로그래밍 적용

  • 소스리딩을 순서대로 하면 비전문가. 클래스나 메소드 우선 분석하면 전문가.
  • 공부를 스스로 적극적으로 하도록 설계를 잘 해야 한다. 구체적으로 적어봐야 뭘 공부할지 나옴. 동사형태가 다양하게 나오도록.
  • 디자이너의 경우 잡지 떼기 방식이 있다. 잡지 한 권을 처음부터 끝까지 모든 사진을 직접 그래픽 툴로 그려보는 작업. 디자이너들이 주로 의도적 수련 하는 방법.
  • 잡지 떼기처럼 구체적이어야 함. 프로그램을 완성하겠다 이상으로, 어떤어떤 값도 테스트해보겠다.
  • 디자인패턴 열심히 써야지 -> 일주일 동안 안 짰던 코드를 검토하며 이번주의 패턴을 최소 세 군대 이상 적용해보자.
  • 살 빼자! 가 아니라 줄넘기 몇 개 하자!가 더 좋다. 목표 지향보다 과정? 행동 지향적인 문구가 더 좋다.
  • '목표 프로그램이 있다. 이걸 배워서 뭘 만들어보자.' 같은 경우는 SQ3R의 문제집단과 연관되며 좋은 방식. 그냥 열심히 공부해야지, 뭐 만들어봐야지. 이런걸로 안됨.
  • 6인치 망원경 바로 만드는거보다, 4인치 만들고 6인치 만드는게 전체 시간이 더 빠르다. - Allyn Thompson

3. 다른 조언

  • 새 언어로 새 문제를 풀지 마라. 뭐 하나는 편하게 해줘라.
  • 너무 쉽거나 너무 어려운건 뒤로 제끼고 -> 쉬우면 어렵게 만들어 공부하고, 어려우면 쉽게 만들어 공부한다.
  • 영어 단어도 완전 쉽거나, 완전 어려운건 제외하고 애매한 단어부터 먼저 외우면 좋다.
  • 내가 오늘 코딩한 것 중에 실수한걸 알고 있는가. 기록하자. 다음엔 안하도록.
  • 결과 피드백보다 과정 피드백이 더 낫다.
  • 액션과 피드백 사이의 시간을 줄여라.
  • 프로그램에서 테스트
    • 컴파일러
    • 단위테스트: 30분 짰으면 되돌아보기
    • 코드리뷰
    • 동료
    • 커뮤니티
  • 알고리즘 디자인 실력 증진 방법: 어려운 문제를 푼 후에 처음부터 완전히 새로 푸는 것. 해법의 통찰만을 유지하면서. 해법이 내가 희망하는 만큼 명료하고 직접적일 때까지 반복함. 비슷한 문제를 공략할 일반적인 룰을 찾기. 아까 주어진 문제를 아예 처음부터 최고로 효율적인 방향에서 접근하도록 이끌어줬을 그런 룰을 찾는 것.

A. 양과 질 사례

이런 실제 사례가 있다. 양으로 평가, 질로 평가하는 두 그룹에서 최고의 작품은 양 그룹에서 나왔다. 질 그룹은 앉아서생각만 함. 이론만. 실제로 해보는게 최고다. 즉 프로그래밍에선 같은걸 다르게 다른 맥락에서 여러번 해보는게 좋다. 조금씩 더 개선해보고, 실수를 많이 해야 한다.

B. 상담 사례

상담으로 유명한 어떤 외국 명사가 이혼 위기 부부를 상담하는 것을 시연하는 교육이 있었다. 강의를 듣는 사람 중 다음처럼 구체적으로 학습하는 사람이 있었다.

  • 시연 보기 전 나라면 어떤 질문을 할지 적어보기. 연습
  • 시연 보면서 연습
  • 정리

프로그래밍에서 디자인 패턴에 적용해본다면 다음과 같다.

  • 과거에 어댑터 패턴을 적용하면 좋았을게 뭐가 있을까 고민.
  • 현재
  • 정리

4. 짝 프로그래밍

A. 방식

  • 1분~10분정도 번갈아가면서 코딩하기
  • 30분동안 한 사람 하고 번갈아 하는건 짝프로그래밍이 아니다. 짧은 텀.
  • 암묵지를 배우기 좋다. 버그가 줄어든다.

B. 추천 방식

두 사람의 실력 차이가 클 때 잘 하는 사람이 주도를 해버리면 별로다. 잘하는애가 설명하는면 둘 다 지친다. 강의 하는것도 힘들고 알아듣는것도 부담되서 힘들다.

  • 3분 5분 간격으로 함.
  • 더 잘하는 사람이 할 때는 아무것도 말 안하고 쭉 함. 설명 안함.
  • 그 다음에 못하는 사람이 할 때는 잘하는 사람이 필요하다면 하나하나 다 가르쳐줌. 뭐 쳐라. 뭐 치고 뭐 해라 자세하게.
  • 미리 한 시간 할거면 미리 밑그림을 그려본다. 그러면 비전문가가 잘 따라감.
  • 비전문가는 끝나고 책 찾아보거나 질문하거나 실험해보는 활동을 한다.

5. 효과적 학습법

A. 비 효과적인 경우

  • 같은 자료를 반복해 읽기: 반복하는 term을 길게 두면(망각 주기) 괜찮다.
  • 형광펜 및 밑줄 긋기: 별로 안 중요한 내용도 표시하거나, 모든 내용을 다 표시하게될 경우 비효율적이다.
  • 요약하기: 공부한 자료를 보지 않고 요약하는 것은 효과 있음

B. 효과적 학습법

  • 방금 읽은 부분이 왜 그런지 자주 자문해보기: 과거 경험, 실제 사용 사례 등을 관련해서 설명해본다. 왜 에러가 났는지 우선 코드 보기 전에 상상해서 설명해봄 스스로에게. 이 방식은 '전이' 효과가 있다. 전이를 높이기 위해선 예를 들어 어떤 문제를 풀었을 때 그 문제에서 살짝 추가 기능을 더해서 풀어본다. 같은 문제를 계속 반복해서 푸는게 아니라 살짝씩 변경하는 것.
  • 섞어서 공부하기: 공부할 것이 A, B, C가 있다면 섞어서 공부한다. A-1, B-1, C-1, A-2, B-2, C-3 이런 식으로. A123 다 공부하고 B123 넘어가면 A를 잊을 가능성이 높다.
  • (효과 좋음) 연습 시험 치기: Cornell Note 활용법처럼 백견이 불여일타 -> 백타가 불여일시. 시험치기처럼 코드를 짜봐라. 보고 치지 말고 기억해서 쳐보기. API 기억해서 외워서 쳐보기. 매 번 검색하지말자.
  • (효과 좋음) 분산 연습: 지식 노동자는 한 번의 chunk. 붙어있는 연속되는 집중 시간을 갖는게 중요하다.(피터 드러커) 하지만 spacing이라고도 하는 분산연습을 하는것도 좋다. 공부를 하면 6시간 공부하는 것보다 1시간씩 공부해서 중간 중간 테스트하는 것이 최종 테스트에서 점수가 더 높다. Anki(Spaced Repetition Software) 라는 소프트웨어가 있다. 적절한 시간 간격으로 외우라고 띄워주는 것. 망각 주기와 연관.
  • 새 정보가 이미 아는 것과 어떻게 관련있는지(혹은 문제 푸는 단계를) 설명해보기

6. 질문 중 좋은 내용

질문 1

안녕하세요? 저는 이번에 컴퓨터공학과로 편입을 하게 되는 학생입니다. 저는 여러 이유로 컴퓨터 공학에 매력을 느끼고 소프트웨어 개발자가 되고 싶어 편입을 했습니다. 3학년으로 들어가는데, 프로그래밍이나 컴퓨터과학 지식이 전무합니다. 그래서 가능한 빠르고 효율적으로 공부를 하고 싶어 틈틈히 알아 보던중 애자일 이야기 블로그를 발견하고 이 강의도 알게 됬습니다.

제가 입학전 3월전까지 목표로 하는것은 두 가지 인데요.

  • 프로그래밍의 기초를 닦는 것(파이썬 -> c언어)
  • 주요 전공과목을 미리 어느정도 이해, 암기, 숙달 시켜놓는것(자료구조, 알고리즘, 컴퓨터네트워크 등등)

문제는 이 강의중 나왔던 의도적수련을 적용하고, 예시 중"파이썬 -> c언어" 순으로 프로그래밍을 해 좋은 결과를 얻었던 분의 방법대로 해보자 하고 접근을 하려는데 막상 시작하려니 목적에 따라 교재가 다르고, 같은 목적의 교재라도 뭐가 좋고 뭐가 나쁜지 구별이 안되어 어떤 교재로 시작해야 할지 감도 못잡겠습니다. 그리고 생각하다보니 이 강의에서 소개된 방법에 적합한 기초교재도 존재할것 같았고, 존재한다면 알고 계실거 같아 추천을 부탁드립니다.

답변 1

안타깝게도 제가 아는 한에서 제가 소개한 방법에 적합한 기초교재가 흔하지 않습니다. 요즘 서적은 어떤지 제가 직접 확인을 해보지 않았는데, 온라인서점에서 몇 권 책을 검색해 목차를 보니 대동소이합니다.

목차로 봤을 때 그나마 좀 다르다고 느껴지는 책으로 다음이 있습니다.

이렇게 말씀을 드리긴 했는데, 제가 권해드리고 싶은 방법은 오히려 아래와 같습니다.

  1. 최고의 책을 구해 그걸로 공부할 생각보다 서로 성격이 다른 여러개를 구해 비교해 가며 공부한다는 마음을 갖는다
  2. 대형 서점에 가서 비슷한 주제를 다루는 서로 다른 스타일의 책들을 비교해보면서 뭔가 내 맘에 들고 끌리는 책들을 서너 권 고른다
  3. 그 책들을 공부할 때 목차 순서로 간다면 한 책으로 한 챕터 읽고 다른 책으로 해당 내용이 있는 부분을 찾아서 다시 읽는다
  4. 목차 순서로 가지 않는다면 목차를 훑어보고 흥미로운 부분을 골라 읽는다 (순서는 크게 신경쓰지 않는다)
  5. 책을 어떻게 읽느냐가 무척 중요하다 -- 조금 읽고 조금 시험쳐 보고(책 덮고 소스코드 재생해내기) 조금 응용/실험해 보고를 반복한다

질문 2

또 프로그래밍과 컴퓨터과학은 다르다고 들었습니다. 전공 공부에서 대학별로 커리큘럼이 겹치고 필수적인 부분을 먼저 공부하려고 하는데 위에 쓴 몇가지 말고도 전공이 꽤나 많던데 가장 필수적인 과목들과 그에 따른 가장 좋은 교재를 추천 부탁드립니다.

답변 2

(아래 내용은 제가 월간 마소 2001년 4월호 특집 "프로그램, 프로그래밍, 프로그래머" 기사에 썼던 내용들을 기반으로 수정하고 더 추가했습니다)

어떤 주제와 과목이 소프트웨어 개발자에게 중요한지에 대하여 연구들이 있습니다.

Lethbridge, 2000, What knowledge is important to a software professional (Computer, May, 2000)

북미지역 및 유럽의 소프트웨어 전문가(평균 10년 정도 종사한 사람들로 프로젝트 관리자나 프로그래머들) 200여명에게 몇 가지 질문을 하고 그 결과를 분석한 [결과](http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=841783 및 http://portal.acm.org/citation.cfm?id=621473)입니다. 대학에서 배운 것 중 어떤 것이 실제로 도움이 많이 되는지 등을 물었습니다.

다음은 졸업 후 중요하게 느꼈던 주제 탑20입니다(전체 75개 주제 중 가장 중요한 것부터)

  • 특정 프로그래밍 언어들
  • 자료 구조
  • 소프트웨어 디자인과 패턴
  • 소프트웨어 아키텍처
  • 요구사항 수집 및 분석
  • HCI(Human Computer Interaction) 및 유저 인터페이스
  • 객체 지향 기술 및 개념
  • 직업윤리와 프로페셔널리즘
  • 분석 및 디자인 방법
  • 청중에게 프레젠테이션하는 것
  • 프로젝트 관리
  • 테스팅, 검증 및 QA(Quality Assurance)
  • 알고리즘 설계
  • 기술적 글쓰기(Technical Writing)
  • 운영체제
  • 데이터베이스
  • 리더쉽
  • 형상 및 릴리즈 관리
  • 데이터 전송과 네트워크
  • 경영

비전공자들이 일을 해오면서 ‘전문가’가 되기 위해 자신들이 가장 많이 배워야 했던 것도 물었습니다. 특정 프로그래밍 언어들, 자료 구조, 테스팅, 검증 및 QA, 운영체제, 소프트웨어 디자인 및 패턴, 객체지향 기술 및 개념, 데이터베이스, 형상관리, 직업윤리 및 프로페셔널리즘 등이었습니다.

Surakka, 2007, What subjects and skills are important for software developers? (CACM, Jan, 2007)

위 레스브릿지 연구의 업데이트판입니다. 더 최근 연구이지만 조사한 사람 숫자는 많지 않습니다. 하지만 의미있는 사람들을 조사했습니다. 핀란드의 "탁월한" 개발자 몇 명을 선정해서 델파이 방법을 통해 결과를 얻었습니다. 교수가 생각하는 중요한 주제와 대학원생이 생각하는 중요한 주제도 조사가 되었습니다. 링크

두번째 논문에 보면(75쪽 도표) 실제 뛰어난 개발자, 혹은 경력 있는 개발자(레스브릿지의 연구결과), 교수, 대학원생 등이 중요하게 여기는 소프트웨어 개발 관련 주제들과 각 주제별 중요도 점수가 나와 있습니다. 레스브릿지의 결과와 크게 다르지는 않습니다. 인터넷의 중요성이 높아졌다는 점 정도가 차이라고 할 수 있겠죠.

대학원 진학 예정이건, 혹은 취업이 목표이건 "프로그래밍을 잘하는 것"이 여러모로 유리하기 때문에 현직 개발자가 졸업 후 중요하게 느낀 과목들을 유심히 봐야 하겠죠.

개별 과목별 가장 좋은 책에 대해서는 앞에 썼던, 제가 권하는 방법들을 역시 여기에서도 똑같이 권합니다.

예전에 알고리즘, 자료구조, 디자인패턴 등에 대해 책 추천을 하고 공부법을 쓴 기사가 있기는 합니다. 월간 마소 2002년 6월호 기사였습니다. 제목은 "어떻게 공부할까: 프로그래머를 위한 공부론"입니다.

위 두 기사는 pdf 파일을 공유해 드립니다.

불확실성이 높을 때에는 애자일 방법론을 쓰는 것이 좋다고 생각합니다. 학습에도 마찬가지로요. 완벽한 청사진을 구할 때까지 기다리기보다 우선 현재 자신에게 가까운 자원들(사람, 자료, 내 강점, 취미 등)을 활용해서 실험을 하고 그 피드백을 통해 계획을 조정하고 하는 것을 짧은 주기로(예컨대 한 달에 한 번씩 공부 계획을 점검한다거나) 반복해 보기를 권하고 싶네요.

특히 편입하셔서 같은 과 동기들과, 또 선배, 교수님들 중에서 내가 배울 점이 있는 사람들과 친해지시는 것이 굉장히 중요할 것이라 생각합니다. 입학식 하기 전부터도 찾아보면 그 사람들과 가까워질 기회가 있으리라 생각합니다. 그들로부터 얻는 정보가 책 몇 권의 중요성을 넘어서지 않을까 합니다. ^^; 관련하여 제가 블로그에 쓴 을 참고하세요.

즐거운 학창생활 되시길!

+ Recent posts