윗 문장의 두 숫자는 2년간 회사에서 소프트웨어 개발하면서 회사 깃허브에 내가 추가하고 삭제한 라인의 수다. 순수히 개발과 관련된 코드만 카운트하고자 리팩토링과 주석을 추가한 커밋, 오픈 소스의 일부 기능을 빌려온 코드, Initial Commit 같은 것은 빼고 기능 추가 또는 버그 픽스를 위한 커밋만 추려냈다. 물론 이중에서도 다른 사람의 코드가 포함될 수 있으나 역으로 다른 사람의 커밋에도 내 코드가 포함돼 있을 것이니 어느 정도 상쇄한다고 보자. 별로 큰 차이는 없을 것이다.
제타위키에 따르면 휴가를 고려하지 않고 한국인이 1년간 일하는 날은 249일 정도가 된다고 한다. 여기서 2를 곱하면 난 2년간 최대 458일 일했을 것이다. 이 숫자를 내가 추가하고 삭제한 커밋의 라인 수로 나누면 평균 하루 5.27 라인을 추가하고 1.70 라인을 삭제한 결과가 나온다. 추가와 삭제를 합해서 하루에 7라인을 만들고 줄인 셈이다. 너무 적지 않은가? C언어로 "Hello World"만 출력해도 엔터를 포함해서 다섯 라인은 족히 나온다. 그동안 나는 무엇을 하면서 시간을 보내고 있었던 걸까?
프로그래밍을 업무 별로 나누면 코드를 짜고 리뷰 하고 받는 시간은 20~30%에 지나지 않는다. 나머지 시간은 기능을 만드는데 쓴다. 단 단순히 동작하는 코드를 만드는데 그치지 않는다. 기능을 만든다는 것은 퍼포먼스를 최적화하고 추후 변경될 소지가 있는 부분들을 예상하며 보안의 위협이 될만한 부분들을 처리할 수 있는 안정적인 코드를 만드는 것이다. 한 가지 기능을 개발할 때는 예상외로 고려할 것이 많다.
스마트폰의 헬스케어 앱을 만드는 개발자를 예로 들어보자. 개발자는 갤럭시 S9 이용해 걸음 수를 측정하는 기능을 만들어야 한다. 걸음수를 측정할 수 있는 알고리즘은 이미 마련되어 있으니 따로 논문을 찾아볼 필요는 없다. 이것을 구현해 스마트폰의 센서로부터 값을 읽어온 후 걸음수를 카운트한 후 메인 모듈에 값을 전달하기만 하면 된다. 아마 안드로이드에 익숙한 개발자라면 한 주 안에 끝낼 수 있을 것이다. 이미 마련된 알고리즘의 의사 코드(pseudo code)를 자바로 옮기고 값에 해당하는 변수에 센서의 값을 읽도록 바꾸면 된다. 노이즈가 좀 있겠지만 이럴 때는 센서 API에서 읽어온 값을 미세하게 조정하면 된다. 2~3일 코드 짜고 하루 이틀 정도 걸어보면서 디버깅하면 충분할 것이다.
만약 '디바이스가 바뀌는 경우'가 있다면 어떨까? 개발자의 코드 덕분에 서비스가 번창해서 갤럭시 S9뿐만 아니라 V30에서도 서비스를 제공해야 한다고 해보자. 가장 단순한 방법은 똑같은 코드를 그대로 V30에서 쓸 수 있는 코드로 바꾸면 된다. 단 예전에 갤럭시 S9에서 미세한 오류를 조정하기 위해 넣었던 수식들은 일일이 찾아서 치환해야 한다. 땜빵 코드이기에 이 정도의 삽질은 감수해야 한다. 그런데 중국시장에까지 진출해 샤오미 폰과 하웨이 폰에서도 지원해야 한다면 매번 코드를 바꿔서 끼워 넣을 것인가? 해마다 새로운 모델이 우후죽순으로 나오는데 모두 다 이런 방식으로 바꿔야 한다면 앞이 깜깜하다.
눈 앞에 있는 문제만 해결한 소프트웨어는 장기적으로 개발자를 괴롭힌다.
이런 삽질을 미연에 방지하기 위해선 개발 초기에 디바이스의 변경 가능성을 검토했어야 했다. 개발 당시에는 갤럭시 S9이 주 타깃이지만 서비스를 제공하는 업체라는 점에서는 헬스케어 앱은 다른 모델도 지원할 가능성이 아주 농후했다. 이점을 고려한 개발자는 알고리즘 함수의 인자에 미세한 오류를 조정한 센서 값을 넣을 수 있게 해 모델에 의존하지 않는 코드를 만들었을 것이다. 매번 똑같은 코드를 만들 필요가 없었다. 디바이스가 추가되면 몇회 디버깅 해본 후 미세 조정한 센서의 값만 수식으로 만들어주면 된다.
동료들과 회의하다보면 칠판은 어느새 그림처럼 변한다
OS나 클라우드 서비스처럼 플랫폼의 역할을 하는 소프트웨어는 기능을 구현하는 것도 만만치 않다. 그래서 동료들과 회의를 하며 아이디어를 도출하는 것뿐만 아니라 개발자들은 업무 중에 책과 논문을 읽어가며 공부하고 때론 관련 컨퍼런스에 참가해 다른 개발자에게 조언을 구하기도 한다. 기능 구현 방법에 대한 검토가 끝나면 여기서 파생될 수 있는 문제점들을 검토하는 시간이 된다. 현재 구현하려는 기능이 다른 팀의 모듈에 영향을 줄 수 있지는 않은지, 다른 플랫폼과 통신 방법은 적절한지, 추후 외부 모듈과 통신 인터페이스가 변경될 소지가 있는지 등 소프트웨어에서 나올 수 있는 모든 복합적인 요소를 고려하는 시간이다. 충분한 검토가 이뤄질수록 완성도 있는 소프트웨어가 만들어진다.
코드는 여러 복합적인 요소를 충분히 고려하고 만만의 준비를 마쳤을 때 작성한다. 코드 작성은 여태껏 찾아온 솔루션을 프로그래밍 언어로 옮기는 과정일 뿐이다. 작성한 코드가 버그 없고 가독성이 훌륭하며 의도한대로 동작한다면 라인의 수가 많든 적든 중요하지 않다. 더 안정적이고 더 지속가능하며 더 퍼포먼스가 좋은 소프트웨어일수록 코드 한 줄을 짜는 데는 오랜 시간이 소요된다.