소프트웨어 개발자 채용 인터뷰
- 2025-03-21
A job interview for software developers.
Articles
- 2022-05-23 - The science of interviewing developers
내가 요즘 쓰는 방법
(2025년 3월 메모)
기존 채용 방식은 몇 가지 이유에서 적절치 않아 보였다.
- 전통적 코딩 테스트는 직무 관련성도 낮고 “코딩 테스트 특화 교육”이 워낙 보편화되어 변별력이 낮아지는 등 여러 문제가 있다. 하지만 코딩하는 모습을 관찰할 기회 없이 개발자를 채용하는 게 좋은 방법인 것 같지도 않다.
- 모두가 실무에서 AI 지원 프로그래밍을 하고 있고 ChatGPT 등을 쓰는 상황에서 이걸 틀어막고 채용 면접을 보는 건 적절치 않아 보인다. (참고: 생성형 AI와 프로그래머의 역량)
- 실무에서는 아무도 조용히 골방에 앉아서 개발하지 않는다. 옆자리에(혹은 슬랙 채널에) 동료가 있고, 언제든 서로 이야기를 나누며 함께 문제를 풀어간다. 지원자가 혼자 조용히 코딩하는 모습을 지켜보기만 하는 방식으로는 지원자의 의사소통 방식 등을 충분히 관찰할 수 없다. (참고: Contextual inquiry)
이와 별개로, 아래와 같은 바램도 있었다.
- 등락 여부와 무관하게 인터뷰 과정 자체가 지원자에게 유익한 경험이 되면 좋겠다.
- 인터뷰 과정은 지원자를 평가하는 자리이기도 하지만, 동시에 지원자가 회사를 평가하는 자리이기도 하다. 지원자가 면접관(취업할 경우 함께 일할 동료)을 관찰하고 평가할 기회도 풍성하게 주어지면 좋겠다.
- “인터뷰 전에 과제를 제출하기” 등 지원자에게 별도의 시간을 할애하도록 요구하지 않는 방식이면 좋겠다. (예전에 해봤는데 지원자도 힘들고, 평가하는 나도 시간이 너무 많이 들어서 힘들었다)
이런 고민을 바탕으로 이런 같은 방식을 생각해봤다.
- 짧은 코드(30줄 내외?)와 함께 현재의 문제 상황을 제시한 뒤, 수단과 방법을 가리지 말고(ChatGPT 사용 권장) 문제를 해결해달라고 말한다. 면접관은 지원자를 도와주는 사수 역할을 하므로 언제든 적극적으로 도움을 요청하라고 알려준다.
예를 들어, 지원자에게 다음과 같이 상황을 제시한다.
- 간단한 검색 API를 추가했음. 기능은 정상 작동하지만 동시간 대에 사용자가 몰라면 응답 지연이 발생.
- 응답 지연이 생기는 상황에서도 CPU 사용량은 0%에 가까움.
- 다음 코드를 읽고 위 문제의 원인을 추측한 뒤 해결하세요.
- 그 외에도 코드에 다양한 잠재적 개선점들이 있습니다. 최대한 개선하세요.
- ChatGPT, 웹 검색, 옆 자리 동료(면접관)에게 물어보기 등 수단과 방법을 가리지 말고 문제를 해결하세요.
그리고 코드를 보여준다.
import Koa from 'koa'
import Router from 'koa-router'
import { readdirSync, readFileSync } from 'fs'
const router = new Router().post('/search', async ({ request, response }) => {
const c = request.query.category as 'books' | 'movies' | 'music'
const q = request.query.term as string
try {
response.body = { files: searchFilesInCategory(c, q) }
} catch (error) {
response.body = { error: String(error) }
}
})
function searchFilesInCategory(category: 'books' | 'movies' | 'music', keyword: string): string[] {
const files = readdirSync(`./data/${category}`)
return files.filter(x => readFileSync(`./data/${category}/${x}`, 'utf-8').includes(keyword.toLowerCase()))
}
new Koa().use(router.routes()).listen(80)
지원자에게 화면을 공유해달라고 요청한 뒤 지원자가 문제를 푸는 과정을 도와주며 그 과정을 관찰한다.
기술적으로는 아래와 같은 측면들을 볼 수 있다. 알고리즘 문제 풀이와 달리 실무와 밀접한 지식들을 테스트할 수 있다.
- 문제 상황에 대한 기술로부터 동기 IO가 문제임을 잘 추측해내나?
- 동기 I/O를 비동기 I/O 코드로 잘 고치나?
- 간단한 문제:
readdirSync()
를readdir()
로 바꾸고await
을 붙이나?function
을async function
으로 고치나? 반환 타입을string[]
에서Promise<string[]>
로 고치나? - 좀 복잡한 문제:
files.filter()
안에 담겨 있는readFileSync()
를await readFile()
로 변경하면서Array.prototype.filter()
대신for-loop
혹은Promise
를 반환하는map()
등으로 적절히 수정하고Promise.all()
을 쓰나? - 좀 더 복잡한 문제:
files
의 순서가 보장되는 게 중요한지 확인하는가? 스로틀링(throttling)의 필요성에 대해 언급하는가?
- 간단한 문제:
- 테스트가 없는 상황에서 Hyperaware editing 하나? (Working Effectively With Legacy Code)
- 필요한 질문을 충분히 하나, 그냥 막 고치나? 예:
GET
이 아닌POST
를 쓴 특별한 이유가 있는지 물어보고 고치나? - 검색 요청을
GET
이 아닌POST
로 하고 있는 게 문제라고 인식하나? - URL의 동사
/search
를/files
등 명사로 고치나? music
만 단수고 나머지는 복수인 비일관성을 발견하나?- 정적 검사와 런타임 유효성 검사의 차이를 구분하나?
request.query.category
와request.query.term
에 대해 유효성 검사가 필요하다는 점을 언급하나? - 파일 경로 인젝션 공격 가능성을 발견하나?
- 오류 상황에서 HTTP 200 응답을 보내는 문제를 지적하나?
- 일관성 없는 변수명(예: q과 term)을 수정하나?
- 소소한 코드 중복을 잡아내나?
- 80 포트에 binding 하는 이유가 뭔지 물어보나?
- 사용자가 입력한 검색어에 대해서는
String.prototype.toLowerCase()
를 하면서 파일 컨텐츠에 대해서는 안하는 문제를 지적하나? - 코드를 읽고 이해하는 속도, 사소한 키입력(예: 커서 움직임, “이름 변경” 등 에디터의 리팩토링 기능을 사용하는지 여부 등) 등을 관찰하며 지원자가 평소에 꾸준히 코딩을 하는 사람인지 관찰할 수 있다.
- 어떤 문제들이 더 남아 있는지 궁금해하나?
지원자가 ChatGPT를 사용하는 모습을 관찰하면서도 여러가지 정보를 얻을 수 있다.
- ChatGPT에게 뭐라고 물어보는지 관찰하면 지원자가 현 상황을 어떻게 인식하고 있는지 구체적으로 알 수 있다. Think aloud와 유사한 효과.
- 원하는 바를 ChatGPT에게 얼마나 명확하게 전달하는지, ChatGPT의 답을 제대로 이해하는지 관찰할 수 있다. 서면 의사소통(written communication) 능력의 한 단면을 관찰할 수 있다.
- ChatGPT의 제안 중 뭘 수용/의심하는지, 왜 그렇게 생각하는지 물어보며 구체적인 대화를 나눌 수 있다.
마지막으로, 실제와 유사한 문제 상황을 놓고 지원자와 대화를 나누는 경험을 해볼 수 있다.
- “만약에 이런 상황이라면 어떻게 하시는 편인가요?” 같은 뜬구름 잡는 얘기가 아니라 “그러게요, 6번 줄에서 쿼리스트링에 대해서 유효성 검사를 어떻게 하면 좋을까요?”처럼 훨씬 더 실제 상황에 가까운 대화를 나눌 수 있다.
- 지원자의 약점을 잡아내는 모드가 아니라 지원자의 동료 입장에서 문제 해결을 도와주는 모드에 좀 더 가까워진다는 장점이 있다.
두 개 회사에서 이 방식을 써봤는데 지금까지는 마음에 든다.