소히 잘나가는 회사들의 기준으로 삼는 조엘 테스트 항목을 보면 다음 문항을 찾아볼 수 있다. 신입사원들은 면접때 코드를 직접 짜는 실기시험을 봅니까?
그래서 그런지 점차 프로그래밍 면접을 시행하는 곳이 늘어나는 추세인 것 같다.
그럼에도 지금까지 나의 면접 경험을 떠올려보면 프로그래밍 면접을 봤던 회사들보다는 구술면접만 봤던 곳들이 많았다(그렇다면 내가 지원했던 곳은 잘 안나가는 회사였단 말인가?)
이처럼 손가락에 꼽을만큼 드물었음에도 지금껏 수년전 당시의 프로그래밍 면접 문제까지 생생하게 기억하고 있는 것은 스스로도 만족했던 좋은 기억보다는 실수나 준비부족으로 인해 결과가 좋지 못했던 기억이 더 많았기 때문이다.
그래서 이 책을 처음 받아봤을 때, 뒷면에 적힌 면접에서 코딩하라면 깜짝 놀라는 당신을 위한 책 이라는 문구가 더 크게 와 닿았을 지도 모르겠다..
이책은 IT 특히 프로그래머로 취업하려는 경우의 프로그래밍 면접에서 출제될 수 있는 거의 모든 분야(데이터베이스, 퍼즐, 심지어 기술과 무관한 문제까지도)의 문제들을 다루고 있다.
실무에서 거의 C 만 다루는 나에게 있어, 주어진 문제에 대해 프로그래밍 언어마다 각기 다른 방법으로 해결할 수 있다는 사실이 흥미로웠다.
개인적으로 가장 좋았던 내용은 CHAPTER 3장의 프로그래밍 문제 접근법이었다. 문제를 받고 곧바로 코딩을 시작하기 보다는 문제 해결을 위한 절차와 문제해결, 풀이분석까지 단계별로 설명해놓았는데, 해답(결과)보다는 그것을 도출해내는 과정이 더 중요하다는 진리(!)를 또 한번 깨닫게 되었다.
이에 대한 사례로서 혼자서 생각하고 풀기보다 문제를 출제한 면접관과 소통(대화)을 통해 문제에 대한 자신이 이해하고 있는 바와 이를 토대로 해결하려고 하는 방법을 정확히 전달하는 것이 중요하다는 것을 제시하고 있다.
또한 문제를 풀다가 막히더라도 심지어 도저히 못 푸는 문제가 나오더라도 바로 포기하지말고 푸는 노력을 보여주는 것이 중요하다는 조언도 빼놓지 않는다.
이책의 대부분은 출제 예상 문제 및 풀이에 분량을 할애하고 있다. 이뿐 아니라 구직을 하기전에 준비해야할 것들이나 일반적인 입사 지원 절차를 내용을 담고 있다. 개인적으로는 부록에 실렸던 영문이력서 예제와 작성방법에 대한 설명이 유익했다.
옥의 티라면, 읽으면서 오타와 일부 용어들에 대한 부연설명이 부족했다는 것이 아쉽다.
나름의 총평을 하자면, 프로그래밍 면접을 준비하는 사람이라면 이 한권으로 충분하겠다는 생각이 든다.
오타 목록
- 86페이지 - 18번째 줄(이 함수의 원형은 어떻게 잘아야 할까?)
- 90페이지 - 20번째 줄(createStack 에서는 비어있는 스택과 오류코드를 통시에 반환해야하기 때문이다)
- 206페이지 - 예제 코드(returnval)
- 220페이지 - 같은 문장 중복(전화번호를 알려줄 때 일곱자리 번호를 나타내는 단어로 알려주는 경우가 종종있다)
- 380페이지 - 문자의 부자연스러움(어느 정도 익숙해지는 것을 목표로 한다. 면접을)
부연 설명 필요
- 98페이지 - 9번째 줄(게다가 head 가 NULL 이기 때문에 curPos 는 NULL 이 되어 While 반복문의 본체(원어 병기)는 한번도 실행되지 않는다)
- 104페이지 - 11번째 줄(NULL 인지 확인한 다음 head 가 NULL 인 경우에는 디레퍼런스(적당한 단어 병기)를 하지 말아야 한다)
기억에 남는 구절
문제 해결을 위한 체계적인 접근 방법
문제를 확실히 이해한다
처음에 생각한 문제에 대한 가정이 틀리거나 면접관의 설명이 너무 간단하거나 어려워서 이해하기 힘든 경우가 있다. 이럴 때는 주저하지 말고 면접관에게 문제에 대한 질문을 해야 하며, 제대로 이해하기 전에 무작정 풀기 시작하는 일은 금물이다.
일단 문제를 이해하고 나면 간단한 예를 시도해 본다
이렇게 예를 시도하다 보면 문제를 어떻게 풀어야 할 지 감을 잡을 수도 있고, 혹시라도 잘못 이해한 부분이 있을 경우 오류를 정정할 수도 있다.
문제 풀이에 사용할 알고리즘과 자료구조에 초점을 맞춘다
이 단계에서는 면접관과의 의사소통이 중요하다. 계속해서 면접관에게 지금 무엇을 하고 있는지 얘기하자. 예를 들어, “값을 배열에 저장하고 정렬을 할 수 있을지 생각해보고 있는데, 배열에 있는 원소는 값을 기준으로 빨리 찾아낼 수가 없기 때문에 별로 좋지 않을 것 같네요” 같은 식으로 얘기하면 된다.
이런 식으로 얘기하다보면 면접의 핵심이라고 할 수 있는 자신의 능력을 보여주는 데도 도움이 되고, 면접관이 “거의 다 된 것 같네요. 근데 정말 값을 기준으로 원소를 찾아야 할까요? 혹시 다른 방법은 없을까요?” 같은 식으로 답하면서 힌트를 줄 수도 있다.
알고리즘과 구현 방법을 알아내고 나면 면접관에게 풀이를 설명한다
이렇게 함으로서 코딩으로 넘어갈지 알고리즘을 다시 살펴봐야 할지에 대해 아주 중요한 정보를 얻을 수 있다는 것은 분명하다.
코딩을 할 때도 뭘하고 있는지 설명한다
예를 들어 “여기에서는 배열을 전부 0으로 초기화합니다” 같은 식으로 설명을 할 수 있다. 이런 식으로 설명을 해 주면 면접관 입장에서 코드를 더 쉽게 따라갈 수 있다.
풀이에 대한 코드를 작성하기 전에, 그리고 작성하는 도중에도 계속해서 설명을 하자. 끊임없이 떠들자.
필요하다면 질문을 한다
레퍼런스에서 찾을 수 있을 법한 내용이라면 면접관한테 질문을 해도 큰 감점사유가 되지는 않는다. 예를들어 “잘 기억이 안나서 그러는데, 지역화된 날짜 시각을 출력할 때 어떤 형식 문자열을 쓰는지 알 수 있을까요?” 같은 질문은 별로 해가 되진 않는다. 물론 이미 외우고 있었다면 더 좋았겠지만.
코드를 완성하고 나면 바로 몇 가지 예를 시도해보고 맞는지 확인한다
이렇게 하면 자기가 만든 코드가 적어도 자기가 시도해 본 예에 대해서는 제대로 동작한다는 것을 분명하게 보여줄 수 있다. 그리고 자신의 사고 과정 및 결과를 확인하고 버그를 찾아내고자 하는 업무 자세를 보여줄 수 있는 기회도 된다. 예를 시도해 보면서 혹시 있을지 모르는 버그를 잡아내는 수확을 얻을 수도 있다.
모든 오류 및 특수 상황, 특히 경계 조건을 확인한다
예를 들어 동적으로 메모리를 할당했다면 메모리 할당이 제대로 성공적으로 되었는지 확인해야 한다(오류 확인코드를 모두 작성할 시간 여유가 없다면 적어도 말로 오류 확인이 필요하다는 설명은 해 줘야 한다). 예를 시도해보고 모든 오류 및 특수 상황을 확인한다.
문제를 풀다가 막히는 경우
만약 문제를 풀다가 막히게 됐을 때 포기하거나 좌절하는 것은 최악의 대응책이다. 계속해서 문제에 대한 관심을 가지고 문제를 풀려고 하는 모습을 보이자.
예를 다시 따져본다
예를 다시 확인해보면서 지금 하고 있는 것을 분석해보자. 시도해 보았던 특정 예를 일반적인 경우로 확장시켜보자. 꽤 복잡한 예를 사용해야 할 수도 있다. 그렇더라도 면접관에게 정답을 찾아내기 위한 끈기를 보여줄 수 있는 셈이기 때문에 나쁠 것은 없다.
다른 자료 구조를 시도해본다
연결 리스트, 배열, 해시 테이블, 이진 검색 트리 같은 다양한 자료구조를 써 보자.
언어에서 그리 많이 쓰이지 않는 기능 또는 고급 기능을 고려해보자
때때로 그런 기능을 활용하는 것이 문제 풀이의 핵심이 되는 경우도 있다.