저는 혼자서 학습하기 위해 데이터베이스를 설치하지 않고도, SQL을 연습할 수 있는 웹 서비스를 만들기 시작했습니다. 그 첫 번째 서비스가 ‘NULL지마’입니다. 문제에 필요한 데이터를 미리 준비해 두고, 사용자가 브라우저에서 문제를 열면 곧바로 쿼리를 실행할 수 있게 했죠. 이 서비스를 공개하고 나니, SQL 외의 다른 기술도 복잡한 준비 없이 연습할 수 있게 만들고 싶어졌고요.
그렇게 지금 개발하고 있는 서비스가 ‘나루(NARU)’입니다. SQL에 더해 자바(Java), 깃(Git), AWS, 리눅스(Linux), 네트워크까지 다룹니다. 실제 서버나 클라우드에 연결하는 대신, 과제에 필요한 동작만 브라우저 안에서 재현하는 방식입니다. 실습 문제도 문법을 묻기보다는 실제 업무 요청에 가깝게 구성했습니다. 예를 들어, ‘취소 주문을 제외하고 날짜별 매출을 구해주세요.’라는 요청을 읽고, 코드를 작성해 결과를 확인한 뒤, 어떤 조건을 적용했는지 설명을 남기는 식입니다.
이 글은 단순히 제가 만든 서비스를 소개하려고 쓴 글이 아닙니다. 아직 완성되지 않았고, 효과가 있다고 말할 수 있는 수치도 없습니다. 대신 만드는 과정에서 계속 같은 질문을 붙잡고 있었습니다. 설치 없이 연습하는 환경에서 학습자는 무엇을 배울 수 있고, 무엇은 배울 수 없을까? 화면에 성공 표시가 떴을 때, 그 성공은 무엇을 보증할까? 이 글에서는 이 질문들에 답하려고 내린 판단과, 그 판단 때문에 생긴 한계를 함께 정리해 보려고 합니다.

SQL을 연습할 환경을 직접 마련하려면 데이터베이스 프로그램을 설치하고, 접속 정보를 설정하고, 문제에 쓸 데이터를 넣어야 합니다. 데이터베이스 운영을 배우는 수업이라면 꼭 거쳐야 하는 과정입니다. 하지만 오늘 배우려는 내용이 ‘조건에 맞는 주문 찾기’라면, 설치와 데이터 준비부터 끝내야 할 이유는 크지 않습니다. NULL지마는 이 준비 과정을 건너뛰고 바로 쿼리를 작성해 볼 수 있도록 만든 서비스였습니다.
공개 후 반응을 살펴보면서 직접 확인할 수 있었던 지표는 등록 계정 수였습니다. 파이어베이스 인증(Firebase Authentication) 사용자 목록을 기준으로 등록 계정은 111개입니다. 아래는 실제 관리 화면을 캡처한 것으로, 계정 식별자와 사용자 UID는 가렸습니다. 다만 이 숫자는 생성된 계정 수일 뿐이고, 방문자 수나 실습 완료 건수, 만족도를 뜻하지는 않습니다. 그래서 이 숫자만으로 ‘학습 효과를 확인했다’고 말할 수는 없습니다. 공개 이후 계정 생성이 이어졌다는 사실을 출발점으로 삼되, 어떤 점이 실제로 유용했는지는 따로 확인해야 합니다.

앞서 언급한 매출 과제를 구체적으로 살펴보겠습니다. 문제에 ‘GROUP BY를 사용하세요.’라고 쓰면 학습자는 어떤 문법을 써야 할지 바로 압니다. 반면 ‘취소 주문을 빼고 날짜별 매출을 구해주세요.’라고 쓰면, 학습자는 먼저 이 요청을 SQL 조건으로 바꿔야 합니다.
어떤 주문을 남길지, 무엇을 더할지, 어떤 단위로 묶을지부터 정해야 하죠. 결국 같은 문법을 쓰더라도, 문제를 풀기 시작할 때 생각하는 내용이 달라집니다.

과제의 완료 기준도 요청에서 뽑아냈습니다. 이 문제에서는 결제 완료 주문만 남겼는지, 금액 합계를 구했는지, 날짜별로 묶었는지를 확인합니다. 세 기준은 각각 조건을 거르는 WHERE, 값을 더하는 SUM, 같은 기준끼리 묶는 GROUP BY와 연결됩니다. 문법 이름을 외우는 데서 그치지 않고, 그 문법이 왜 필요한지를 요청과 대조해 보도록 한 겁니다.

화면에서도 요청과 완료 기준을 편집기 옆에 두었습니다. 코드를 쓰다가 ‘뭘 빼야 했더라?’ 싶을 때 바로 다시 확인할 수 있어야 하기 때문입니다. 결과를 볼 때도 마찬가지입니다. 숫자가 표시됐다는 사실보다, 그 숫자가 취소 주문을 제외한 값인지가 더 중요합니다. 화면에 결과 표만 보여줘서는 이 차이를 확인하기 어렵습니다.
NULL지마에서 데이터를 조회하는 문제를 풀었다면, 나루에서는 개발자가 실무에서 처음 맡을 만한 다른 업무도 연습 대상으로 삼았습니다. 기존 코드를 읽고 수정하는 일은 Java와, 변경 내용을 확인하고 동료에게 전달하는 일은 Git과 관련됩니다.
서버 상태와 접속 문제를 살펴보는 일은 Linux·네트워크로, 클라우드 자원과 접근 권한을 이해하는 일은 AWS로 이어집니다. 그렇다고 SQL 다음에 반드시 이 순서로 배워야 한다는 뜻은 아닙니다. 성격이 다른 업무를 각각 연습할 자리를 마련한 것이죠.
기술은 달라도 과제에서 묻고 싶은 것은 비슷했습니다. 무엇을 해달라는 요청인지, 지금 상태는 어떤지, 무엇을 바꾸고 무엇을 확인해야 하는지입니다. 예를 들어, 코드 수정 실습에서는 문법뿐 아니라 수정 전후에 무엇이 달라졌는지가 중요하고, 권한 설정 실습에서는 명령이 성공했는지뿐 아니라 권한을 어디까지 허용했는지가 중요합니다. 그래서 과제를 늘릴 때도 기술별로 문제 수를 쌓기보다, 학습자가 무엇을 확인해야 하는지를 구체적으로 정하는 데 초점을 맞추고 있습니다.

물론 분명한 제약도 있습니다. 여러 기술을 다룬다고 해서 각 기술의 실제 환경을 모두 제공하는 것은 아닙니다. 지금은 과제에 필요한 명령과 상태만 골라서 구현하고 있습니다. 특히 AWS나 Linux라는 이름이 붙으면 실제 클라우드나 서버를 쓴다고 받아들이기 쉬워서, 화면에서 무엇이 실제로 실행되는지 따로 안내해야 합니다.
나루의 실습은 브라우저 안에서만 동작하는 학습용 시뮬레이션입니다. 사용자가 입력한 코드나 명령을 과제에 맞춰 해석하고, 미리 정한 규칙에 따라 상태와 결과를 보여줍니다. 화면에서 서버 상태를 바꿔도 사용자의 실제 서버가 재시작되지는 않습니다. AWS 과제를 실행해도 실제 클라우드 자원이 생성되지 않고, Git 과제를 풀어도 실제 저장소의 이력은 바뀌지 않죠.

실제 환경을 연결하려면 계정을 발급하고, 권한과 비용을 관리하고, 잘못 실행했을 때 복구하는 방법까지 마련해야 합니다. 모두 중요한 학습 주제지만, 첫 과제에서 한꺼번에 다루기는 어렵습니다. 그래서 현재 버전은 과제에 필요한 동작만 구현했습니다. 같은 조건에서 명령과 결과를 비교해 볼 수는 있지만, 실제 서버나 클라우드의 기능을 모두 실행할 수는 없습니다.
그만큼 배울 수 없는 것도 있습니다. 실제 서버의 응답 지연, 서버마다 다르게 설치된 프로그램, 클라우드 계정마다 다른 권한 같은 변수는 이 환경만으로는 충분히 경험하기 어렵습니다. 화면에 ‘가상 실행 결과’와 ‘학습용 데이터’라는 표시를 붙인 것도 이 때문입니다. 나루에서 성공했다는 것은 해당 과제의 조건을 통과했다는 뜻이지, 실제 운영 환경에서도 문제가 없다는 보증은 아닙니다.
매출 과제에서 결제 완료 주문만 골라 합계를 구했고, 모든 점검을 통과했다고 해보겠습니다. 그런데 그다음에 주문을 거르는 조건을 지웠다면 어떨까요? 화면에는 이전 실행의 초록색 성공 표시가 남아 있겠지만, 지금 코드가 맞는지는 알 수 없습니다. ‘한 번이라도 성공했는가’만 확인하면, 수정한 코드를 검증하지 않은 채 제출할 수 있습니다. 그래서 제출 기능에서는 이 상황을 구분해야 했습니다.

이를 위해 실행할 때 사용한 코드와 지금 편집기에 있는 코드를 비교하도록 구현했습니다. 실행한 뒤 코드가 달라졌다면 이전 결과로는 제출할 수 없고, 수정한 코드를 다시 실행해야 합니다. 새로 실행한 결과도 완료 기준을 통과해야 다음 단계로 넘어갈 수 있습니다. 사용자 입장에서는 실행 버튼을 한 번 더 누르는 일이지만, 제출하는 코드와 그 코드로 확인한 결과를 일치시키려면 필요한 절차입니다.

실행하면 결과 화면에 날짜별 매출이 나오고, 그 옆에 ‘결제 완료 주문 필터링’, ‘합계 계산’, ‘날짜별 그룹화’ 세 항목의 점검 결과가 표시됩니다. 그다음에는 작업 노트를 남길 수 있습니다. 이 과제라면 ‘어떤 주문을 제외했는지’, ‘날짜별로 나뉜 결과를 어떻게 확인했는지’를 적는 식입니다. 제출 단계에서는 실행 결과뿐 아니라 작업 노트와 확인 항목도 함께 점검합니다.
작업 노트를 둔 이유는 코드만으로는 알 수 없는 것이 있기 때문입니다. 코드만 받으면 작성자가 요청을 이해하고 풀었는지, 예제를 그대로 옮겼는지 구분하기 어렵습니다. 짧더라도 설명이 붙어 있으면 어디를 검토해야 할지 보입니다. 결제 상태를 잘못 해석했다면 그 조건을 두고 다시 이야기할 수 있고, 합계만 확인했다면 날짜별 결과도 확인해 달라고 요청할 수 있습니다. 자동 점검을 통과한 뒤에도 사람이 다시 살펴봐야 하는 이유가 여기에 있습니다.
NULL지마에서는 혼자 문제를 풀고, 결과를 확인하는 데 집중했습니다. 반면 나루에서는 스터디나 회사 온보딩에서 여러 사람이 같은 과제를 풀고, 결과물을 제출하고, 피드백을 받아 수정하는 과정까지 만들고 있습니다. 여러 사람을 연결하는 기능 자체가 목표는 아닙니다. 같은 요청을 서로 어떻게 이해했는지 비교하고, 각자 내린 선택을 설명해 볼 기회를 만들려는 것이죠.
현재는 개인 실습과 완료 기준 점검을 중심으로 개발하고 있고, 제출·검토·피드백 화면도 구성하는 중입니다. 팀 초대와 멘토 검토를 포함한 스터디 전체 과정은 아직 개발 중입니다. 따라서 이 글에서 설명하는 협업 방식은 완성된 기능을 써 본 후기가 아니라, 지금 구현하고 있는 방향입니다.
작업 기록을 저장할 때도 신경 써야 할 부분이 있습니다. 로그인하기 전에 쓰던 초안과 로그인한 계정의 기록이 섞이면 곤란합니다. 그래서 게스트와 로그인 계정의 임시 저장 공간을 따로 나눴습니다. 게스트로 작성한 기록은 사용자가 ‘가져오기’를 선택하면 계정으로 옮기고, 같은 계정에 더 최근 초안이 있으면 자동으로 복구합니다. 또 이전에 보낸 저장 요청의 응답이 늦게 도착해 최근 편집 내용을 덮어쓰지 않도록 확인하는 처리도 넣었습니다. 피드백 기능을 붙이기 전에, 제출한 사람이 쓴 내용이 제대로 남는지부터 점검해야 하기 때문입니다.
계정을 만든 사용자는 어디까지 갔을까요? 첫 쿼리를 실행했을 수도 있고, 문제만 읽고 창을 닫았을 수도 있습니다. 등록 계정 수만으로는 알 수 없습니다. 지금의 구성을 제대로 평가하려면 사용자가 첫 실행까지 도달했는지, 틀린 결과를 보고 코드를 수정해 다시 실행했는지, 작업 노트에 이유를 남겼는지까지 확인해야 합니다. 아직 이 항목들에 대한 수치는 없습니다. 실제 이용 과정과 피드백을 모아 지금의 설계를 검토해야 합니다.
또한 자동 판정에도 한계가 있습니다. 같은 결과를 내는 코드라도 얼마나 읽기 쉬운지, 실제 데이터에서 성능이 어떤지는 다를 수 있습니다. 정해진 규칙으로 정답 여부를 가리는 일과 더 나은 해결 방법을 이야기하는 일은 서로 다릅니다. 후자까지 성공 표시 하나로 대신하지 않고, 어떤 부분을 사람이 검토해야 하는지를 과제와 피드백 과정에서 드러내려 합니다.
데이터베이스를 설치하고, 서버를 구성하는 경험은 여전히 필요합니다. 다만 오늘의 목표가 주문을 걸러내는 조건을 이해하는 것이라면, 그 연습부터 시작해도 괜찮습니다. 그다음에는 실제 환경에서 같은 작업을 해 보면서, 브라우저 안에서는 드러나지 않았던 차이도 배워야 합니다. 이 두 단계가 이어져야 설치 없는 연습의 한계를 보완할 수 있습니다.
처음에는 SQL을 바로 실행할 수만 있어도 좋겠다고 생각했습니다. 이제는 결과가 나왔을 때 ‘이 결과가 왜 요청에 맞는가’를 확인하는 부분까지 만들고 있습니다. 앞서 살펴본 매출 과제도 숫자 두 줄이 찍히는 것으로 끝나지 않습니다. 취소 주문을 제대로 뺐는지, 수정한 코드로 다시 확인했는지, 다른 사람이 그 이유를 읽고 이해할 수 있는지까지가 이번 개발에서 다루는 문제입니다.
이 글은 AI의 도움을 받아 작성했습니다.
<참고>
현재 FDE로 일하시거나, 최근 1년 내 일하셨던 분들은
“국내 FDE 현황 조사 2026” 참여하고, 리포트 & 네이버페이 포인트 받아가세요!
ⓒ요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.