코드스테이츠와 함께 프로그래밍을 시작하며

프로그래밍에 관심을 가지게 된 계기로 꼽을 수 있는 특정한 이벤트가 있는 것은 아니다. 평소 공학 분야에 필요한 브레인을 갖고 있다 생각하지도 않았고, 굳이 택하자면 목공이나 기계 등 물리적인 것, 즉 하드웨어 조작이나 제작에 대한 관심이 더 컸다. (그렇다고 하드웨어 분야에서 소질을 발견했다거나 한 것은 아니다. 십대를 보내면서는, 그런 기술을 계발할 기회를 딱히 만나지 못했다.)

2000년대 후반에서 2010년대 초, 한국에서 점수를 맞춰 컴공 전공으로 대학에 진학한 친구나 지인들이 휴학을 하면서까지 생명공학 등 다른 분야로 전과하는 것을 지켜보았다. 나는 한국에서 대학을 진학하지 않은 상태였고, 언어학을 공부하고자 주립대 편입을 생각하며 2010년 말 캘리포니아에 도착했다. 아무 생각도 없이 실리콘밸리의 심장(이라고 자부하지만 동네 친구들과는 늘 애플 빼고 아무것도 없는 Poopertino라고 자조적 농담을 많이 했던) 쿠퍼티노에 자리를 잡았으나, 실제로 수업을 듣고 과제를 한 시간보다는 커피를 만든 시간이 길었다. 나름 오래되어 단골 손님들이 건물과 함께 나이를 먹어왔다는 카페에서 일을 했는데, 위치 때문인지 늘 맞는 손님도 새로 찾는 손님도 대부분 IT업계 직원이거나 업계 취업을 준비중인 학생들이었다. 어느 회사의 새로운 제품이 발표될 때면 출시 전에 실제품을 심심치 않게 볼 수 있었고, WWDC가 다가올 때면 들썩이는 동네 분위기에 나도 모르게 동화되어 이런저런 이들과 이런저런 대화에 휩쓸리며 당장은 쓸모없지만 재미있는 정보들을 얻곤 했다.

그리고 2016년 초부터 2-3년에 걸쳐, 각기 다른 전공으로 학사과정을 밟고 있던 다양한 나이대의 친구들이 졸업 학년에 이르러 갑자기 자신의 전공을 컴퓨터과학과 접목하는 것으로 졸업 프로젝트의 방향을 수정하거나, 졸업 전후로 아예 방향을 틀어 (컴퓨터공학 분야의 석사 프로그램에 지원하는 등) 진로를 변경하는 것을 연이어 지켜보게 되었다. 자연스럽게 그 분야에 대한 주제에 슬금슬금 노출이 되었고, 이전처럼 애플이나 구글, 시스코 같은 대기업이 아니라, 친구들이 둥지를 튼 스타트업 기업들에 대한 이야기를 접하는 경우가 늘었다. 그래서 한국에 들어온 뒤에는, 서울 베이스의 스타트업 시장이 어떻게 폭발적인 성장을 이뤄왔는지를 목도하며 한동안 창업에 대한 세미나와 컨퍼런스에 열심히 참석했다.

그 때까지만 해도 나 스스로 프로그래머가 되고 싶다는 생각은 들지 않았다. "그걸"(뭘!?) 배워서 무엇을 할 수 있는지에 대한 인식 수준이 미미했고, 개발자라는 직업에 대한 이미지도 한정적이었다. 실은 아직까지도, 소위 IT업계에서 할 수 있는 직군이나 직무에 대한 거시적 전망이 완성되어 있지 않다. 이는 업계에 오래 종사한 분들을 틈틈이 만나 이야기를 청하는 것으로 조금씩 넓혀 가고 있는 중.

그러다 2019년 봄, 먼 옛날 친구로부터 추천받았던 책 CODE: The Hidden Language of Computer Hardware and Software (Charles Petzold, Microsoft)를 뒤늦게 읽고 많은 것이 바뀌었다. 세상을 보는 시야에 다른 하나의 렌즈가 장착된 느낌이었고, 이 세계를 조금 더 깊이 알고 싶다는 생각이 들었다. 마침 접수 가능한 시기가 맞아떨어져, 독학학위제 컴퓨터과학 전공 이론서를 뒤적이며 잠시 시험 공부를 했다. 시험 전후로 다양한 테크업계 세미나에 참석했고, 본격적으로 프로그래밍 언어를 공부해야겠다는 생각이 들 무렵, 코드스테이츠의 Women's Career Change라는 커리어 전환 장학 프로그램에 대한 소식을 접했다. 재빠르게 지원을 했고, 장학생으로 선발되어 프리코스를 수강하게 되었다. 그전까지 배운 것이 프로그래밍언어론, 자료구조, 컴퓨터시스템구조 등의 이론이었다면, 프리코스를 수강하며 실제로 코드를 작성하게 된 것이다. “시청”해야 할 온라인 강의만 나열된 것이 아니라 구체적인, 세분된 과제가 주어지기 때문에 컴퓨터 앞에 앉아 코딩을 시작하기까지 시간이 얼마 걸리지 않았다.

여성기획자컨퍼런스 - 독학사 2단계 공부 - 여성테크커뮤니티 합동 세미나 - 코딩로봇 강사양성과정 - 테크우먼 세션 - WCC/코드스테이츠
(정리하자면 위와 같은 순서로 프리코스에 와 닿게 되었다)

아래는 수강 과정에서 적었던 노트의 일부.

Week 2 (07/29 ~ 08/04)
This Week I Learned...

  • Breaking down a solution to a given problem into small steps:

for example, to write a function that takes three words and returns the shortest length of the word,

  1. input three words
  2. get the length of each word
  3. compare the length of words
  4. return the shortest length of a word (in number)
  • Designing the series of steps, it helps (and most of the times is sheer necessary) to know which tool you can use: str.length

Write a function called "computePower". Given a number and an exponent, "computePower" returns the given number, raised to the given exponent.

What I first wrote was this:

function computePower(num, exponent) {
  num = Math.pow(num, exponent)
  return num;
}

Then later discovered that a shorter version is possible:

function computePower(num, exponent) {
 return num**exponent
}

Write a function called "computeAverageOfNumbers". Given an array of numbers, "computeAverageOfNumbers" returns their average. If given an empty array, it should return 0.

function computeAverageOfNumbers(nums) {
  let nums[nums];
  let length = nums.length;
  let sum = 0;
  for (let i = 0; i < length; i++) {
    sum += nums[i]
  }
  return sum / nums.length;
}

didn't work at all.

function computeAverageOfNumbers(nums) {
  let sum = 0;
  for (let i = 0; i < nums.length; i++) {
    sum += nums[i]
  }
  return sum / nums.length;
  if (nums = []) {
    return 0;
  }
}

didn't work because it failed to return 0 when the array is empty.

function computeAverageOfNumbers(nums) {
  if (nums.length != 0) {
    let sum = 0;
    for (let i = 0; i < nums.length; i++) {
      sum += nums[i]
    }
    return sum / nums.length;
  }
  else {
    return 0;
  }
}

There I went.


Write a function called getType that returns the data type of input parameters.

function getType(anything) {
  return typeof(anything);
  if (Array.isArray(anything) === true) {
    return 'array';
  }
  else if (Array.isArray(anything) === false) {
    return 'object';
  }
}

didn't work.

function getType(anything) {
  if (Array.isArray(anything) === true) {
    return 'array';
  }
  return typeof(anything);
}

Then it worked. ("What happens to code written after(below) return statements?" was a question worth exploring.)

Week 3 (08/05 ~ 08/11)
This Week I Learned...

Array.Methods

  • properties.length 배열의 길이 반환 return arr.length;
  • Array.isArray(obj) 검사할 객체가 배열이면 true, 아니면 false
  • .map 기존 배열과 동일한 길이의 새 형태 배열을 만들 때
  • .reduce 모든 element의 값을 누적해 하나의 결과로 return
  • .join 연결자
    var a = ['하늘', '바람', '별', '시'];
    var myvar1 = a.join();
    var myVar2 = a.join(', ');
    var myVar3 = a.join(' + ');
    var myVar4 = a.join('');
    var myVar5 = a.join('과 ');

Number Methods

  • Number.isInterger(value); boolean (true/false) 값
  • parseInt / parseFloat(value); 형 변환 (type casting) - 정수 혹은 소수 반환 (parseInt(value, radix) 는 진법 변환 시에도 사용)

Math Methods

  • floor / round Math.floor(x);는 숫자 x의 내림값을, Math.round(x);는 숫자 x의 반올림값을
  • random 0과 1 사이의 랜덤한 숫자를 반환

++ Git 버전관리 Command-Line

++ GitHub Page

++ 무엇보다도, 배운 것은 그때그때 적고 응용해본 뒤, 어떤 부분에서 실패하고 무엇을 고쳐서 성공했는지 바로바로 기록해야 한다는 것.


배운 것을 정리하고 복기하는 위해, 그리고 공부하는 과정에서 지치는 것을 방지하기 위해 쓰는 TWIL의 본 목적과, 코드스테이츠에서 장려하는 블로깅에 대한 강박 사이에서 흔들리다 그냥 what I learned에 집중해서 간단하게 작성하게 되었다. 다뤄보지 않은 언어를 가지고 매주 새로운 개념을 접하고, 정리하고, 페어-프로그래밍하고, 리뷰 쓰고, 블로그에 쓸 것을 따로 정리하고, 프로젝트 하고, 그걸 다른 태스크로 가득한 일상의 일정과 함께 해야 하기에 부담스럽다. 학습하는 경험과 그로부터의 output(을 즐기고 그걸 가지고 실험하는 데)에만 집중할 수 있게, 프로그램 수료를 위한 리뷰·블로깅 등 직접 출력/콘텐츠 제작 요구조건이 완화되면 어떨까 생각도 해 봤다. 하지만 (특히 WCC 장학생들의 블로깅 결과물을 보고) 뛰어난 사람들은 다방면에서 두각을 드러낸다는 것을 깨달으며, 내 부족함에 과하게 괴로워하기보다 주어진 과제들을 포기하지 않고 끝내는 것에 방점을 두기로 한다. (8/11)

Week 4 (08/12 ~ 08/18)
This Week I Learned...

Koans 과제

  • 커맨드라인으로 로컬 컴퓨터에서 git 운용하며 차근차근. 하나씩 해결하는 것의 즐거움
  • emptyArray = []; typeof.Array = Object 이거 아직 못 풀었음
  • methods 전반적인 복습, 특히 reduce와 slice (splice?)
  • JavaScript Basic & Algorithm 과제 해결(w/simpler and more straightforward codes)에의 실마리

TestBuilder.js 과제
console에서 local ~ 안 되는 거 쿠키 해제하고서야 사용 가능해짐

  • var prefix = cardNumber.substring(0, 2); 이런 식으로 하니 안 됐고 slice로만 진행.
  • step one에서 계속 넘어가지 않고 헤맴: 테스트하라고 준 카드번호 4개를 전부 다 입력해 봐야만 넘어갈 수 있는 거였음 (마지막 else “Network not defined. Cannot process payment.” 임의로 붙여서 다 만들었는데 딱 두 회사 것만 하는 거였음: 코드 작성에 익숙하지 않은 자들을 위해 가독성을 좀 높여서 과제 요구사항을 정리해 줬으면)
  • step two에서 카드 번호 중 하나둘씩 빠뜨리고 테스트해서 계속 fail.
  • step three에서는 완전 삽질해서 한 줄 한 줄 조건을 작성. 이걸 어떻게 축약할 수 있을까?
for (var prefix = 644; prefix <= 649; prefix ++) { ~

이게 length로는 되지 않는다.

Scope
local & global

Let greeting = ‘Hello’;

Function greetingsomeone(); {
  Let firstName = ‘Josh’;
  Return greeting + ‘’ + firstName; 
}

Greetsomeone();
FirstName();
  • In JavaScript, calling a function to the lexical sense creates a scope of its own.
  • var 은 { block } 을 벗어나도 같은 function scope 안에서는 그대로 사용한다.

Week 6 (08/26 ~ 09/02)
This Week I Learned...

setTimeout(callback, millisecond): 일정 시간 후에 함수를 실행

  • arguments: 실행할 callback 함수, callback 함수 실행 전 기다려야 할 시간 (밀리초)
  • return value: 임의의 타이머 ID
setTimeout(function() {
  console.log('1초 후 실행');
}, 1000);
// 123

setInterval(callback, millisecond): 일정 시간의 간격을 두고 함수를 반복적으로 실행

  • arguments: 실행할 callback 함수, 반복적으로 함수를 실행시키기 위한 시간 간격 (밀리초)
  • return value: 임의의 타이머 ID
    setInterval(function() {
    console.log('1초마다 실행');
    }, 1000);
    // 345

clearInterval(timerId): 반복 실행중인 타이머를 종료
(argument: timer ID, return값 없음)

var timer = setInterval(function() {
  console.log('1초마다 실행');
}, 1000);
clearInterval(timer);
// 더 이상 반복 실행되지 않음