스마트 온실 프로젝트에 대한 질문을 받았다

바로 어제 SaaS 제품을 개발하는 회사에서 면접을 봤다. 포트폴리오에는 다음 항목들을 넣었다.

  • 2025년에 제작한 코인 웹 시세 서비스
  • 2024년 가을 임베디드 수업 팀프로젝트로 만든 스마트 온실 시스템
  • 최근 진행한 프로젝트의 노션 정리 목록
  • 예전 깃위키 목록 캡처본, 깃 블로그 캡처본 (문서작성·보고서작성 능력을 어필하고 싶어서 넣었다)

얼마 지나지 않아 서류에 합격해서 서울의 면접장으로 향했다.

첫 번째 질문: 스마트 온실 시스템

처음 물어본 건 온실 시스템이었다. ‘왜 웹서비스를 놔두고 이걸?’ 하는 마음이 잠깐 스쳤지만, 사실 이 프로젝트는 내가 거의 전부 진행했고 발표도 성공적이었던, 나름 자랑스러운 프로젝트다. 당당하게 설명하려 했는데 막상 긴장해버려서 “센서데이터를 받아서 노드레드에 연동하고 챗봇 시스템으로 구현했다”고 대충 얼버무리고 말았다.

사실 더 할 말이 많았다.

  • 액추에이터로 워터펌프 모터를 통해 물을 줬다
  • 온습도센서가 아니라 토양 센서라서 흙에 직접 꽂아 사용했다
  • 다이소 행거에 비닐 천막을 연결해 비닐하우스처럼 만들고, 호스를 사서 구멍을 뚫어 워터펌프에 연결했다

이런 하나하나 정성 들인 과정은 tmi일 수도 있으니 면접관이 크게 궁금해하지 않았을 수도 있지만, 그래도 아쉬운 순간이었다.

두 번째 질문: MQTT와 HTTP의 차이

나를 얼어붙게 만든 질문이 있었다. MQTT와 HTTP의 차이를 아냐는 것이었다.

‘MQTT는 센서데이터를 수신하고, HTTP는 웹 데이터를 전송하는 것’ 정도로 대답했는데, 이어서 포트 번호 이야기가 나오자 패배를 직감했다. 오래된 기억인 데다 그동안 게임 개발에 몰두하다 최근에야 머신비전 쪽으로 방향을 튼 나로서는, 예전에 노드레드에 연결할 때 어떤 포트 번호를 썼는지 가물가물했다(대충 20번대였다는 것만 기억났다). 결국 “모르겠다”고 말해버렸다.

집 공유기에 접속해가며 포트포워딩을 공부하고, 수업 시간에 TCP·UDP를 열심히 필기했던 걸 생각하면 다음 날인 지금도 부끄러운 순간이다. 그래서 면접이 끝나고 제미나이쌤 한테 다시 물어보며 복습했다.

TCP / UDP / MQTT / HTTP 정리

  • TCP: 연결지향적 통신. 포트 번호로 연결을 식별하고, 순서 제어·재전송 등을 통해 데이터 전달의 정확성(신뢰성)을 보장한다.
  • UDP: 속도를 중시하는 비연결형 통신. 연결 절차 없이 포트 번호로 즉시 전송하며, 실시간 스트리밍에 주로 쓰인다(디지털미디어 수업에서 배운 예시로는 유튜브 채팅 같은 것).
  • MQTT: TCP 위에서 동작하는 프로토콜.
  • HTTP: 요청-응답(Request-Response) 방식의 1대1 통신.
  • MQTT의 Pub/Sub 방식: HTTP와 달리 1대다(多) 통신이 가능하다.
    • 헤더가 가벼워 저전력·저대역폭 환경에 적합
    • 비동기 통신이라 클라이언트 연결이 끊겨도 브로커가 메시지를 보관할 수 있음(지속 세션/Retained 메시지)
    • QoS(Quality of Service) 라는 메시지 전달 신뢰도 보장 체계 제공 — 0/1/2 단계로 “몇 번 전달을 보장할지”를 정하는 개념이며, 보안 체계는 아니다

신기했던 점은, 약속된 포트 번호로 파일 전송이나 원격 접속 등을 할 때 동일한 포트 번호를 같은 서버에서 TCP와 UDP 양쪽에 각각 쓸 수 있다는 것이다. TCP 포트와 UDP 포트는 서로 독립된 번호 체계이기 때문이다. 동작 원리는 대략 이렇다.

패킷 수신 → 헤더 분석 → 포트 테이블로 프로토콜(TCP/UDP) 구분 → 해당 포트로 전달

포트 번호

포트 번호는 0번부터 65,535번까지 존재한다. 그중 0~1023번은 국제 표준으로 지정된 ‘잘 알려진 포트(Well-known Port)’다. 다만 URL에서 포트가 생략되는 건 이 대역 전체가 아니라, 각 프로토콜의 기본 포트일 때만이다. 예를 들면:

  • 생략 가능할 때: http://naver.com → 브라우저가 자동으로 80번 포트를 찾는다(HTTP 기본 포트)
  • 직접 적어야 할 때: 웹 서버가 8080번처럼 표준이 아닌 포트를 쓴다면 http://mysite.com:8080 처럼 명시해야 한다
  • 보안 관련: 예를 들어 http://내주소:22 처럼 SSH(원격 접속) 용도로 예약된 포트에 웹 브라우저로 접근하려 하면, 브라우저가 이런 포트들을 ‘제한된 포트’로 취급해 접근을 막는 경우가 있다

추가로 알아두면 좋은 것들:

포트 용도
1883 MQTT 기본 통신 포트
8883 MQTT TLS/SSL(보안 적용)
3000 웹 개발에서 흔히 쓰는 포트
4000 Jekyll 빌드 시 기본 포트
8080 Spring Boot(Gradle) Swagger 기본 포트
3306 MySQL 기본 포트

노드레드에 연결할 때 썼던 포트 번호가 아마 1883이었을 것 같다. 그리고 Grafana·InfluxDB에 접속할 때 끝자리가 8883이었던 것도 이제 기억난다.

Pub/Sub 구조

MQTT의 Pub/Sub 구조는 크게 세 요소로 이루어진다.

  • Publisher(발행자): 온습도센서, 토양습도센서, 다른 프로젝트(스마트홈)에서 썼던 시각 센서 등
  • Subscriber(구독자): 시각화 대시보드, 액추에이터(워터펌프 모터 등)
  • Broker(중개인): Mosquitto 같은 MQTT 브로커

참고: 이번 온실 프로젝트에서는 온습도센서가 아니라 토양 센서를 썼다고 앞서 적었는데, 여기서는 온습도센서도 발행자 예시로 들었다. 아마 다른 프로젝트(스마트홈 등)의 센서까지 함께 나열한 것 같은데, 실제로 어떤 센서가 어떤 프로젝트에 쓰였는지 한 번 더 정리해두면 다음 면접 때 헷갈리지 않을 것 같다.

세 번째 질문: 노드레드 데이터 흐름

두 번째로 대답하지 못한 질문은 “노드레드의 데이터 흐름을 설명해달라”는 것이었다. 노드가 연결된 화면 이미지는 떠올랐는데, 정작 전체 아키텍처는 떠오르지 않았다. Figma로 설계도까지 그려놨으면서 오래 안 보니 잊어버린 걸 보면, 시간이 지나면 중요한 기억도 망각하게 된다는 말이 맞는 것 같다.

정리하면 노드레드의 데이터 파이프라인은 다음과 같다.

  1. 생성: 센서가 물리 값을 측정
  2. 전송: MQTT Publisher가 토픽을 붙여 브로커(1883 포트)로 전송
  3. 처리: 노드레드가 Subscriber로서 데이터를 받아 비즈니스 로직 실행
  4. 시각화/액션: 노드레드 대시보드로 현황을 표시하고, 필요 시 제어 명령을 다시 MQTT로 발행

이렇게 MQTT의 특징과 포트부터 전체 흐름까지 AI와 대화하면서 다시 되짚고 나니, 이제 데이터 흐름을 설명해달라는 질문을 받아도 버벅이지 않을 수 있을 것 같다.

돌아보며

임베디드 프로젝트는 정리할수록 재밌다. GPT가 처음 나왔을 때 스마트 디바이스 수업을 들었었는데, 임베디드 보고서를 쓸 때마다 그 시절이 생각난다. 당시엔 AI가 거짓말을 많이 했어서, 수업 실습 결과물은 AI 의존을 최대한 줄이고 문장 다듬기 정도로만 AI를 활용했다.

자동화 도구에는 늘 장단점이 있다. 이번에 면접 본 회사도 실무에서 코드를 직접 작성하는 일은 드물고, 고성능·고비용 AI로 코드 작성을 자동화한다고 했다. 대신 서비스 인프라를 구축하려면 네트워크 환경에 대한 지식은 반드시 있어야 한다는 따끔한 조언을 들었다. 덕분에 프로젝트를 이렇게 돌아보고 글로 남길 수 있게 되었으니, 나에게는 정말 유익한 경험이었다.


P.S. 코인 시세 조회 서비스, 위키 기억과의 오차

코인 시세 조회 서비스 위키에서 작성했던 내용과 내 기억 사이에 괴리가 좀 있는 것 같다. 아마 내 기억이 중간발표 시점에서 멈춘 게 아닐까 싶다.

면접에서 “PostgreSQL을 썼냐, 안 썼으면 Supabase를 썼냐, Supabase는 어떻게 썼냐”는 질문을 받았는데, 순간 “안 썼어요, 계획서에만 그렇게 적혀 있고 실제로는 SQL까지 구현하지 못했다”고 답했다. 최근에 프로젝트를 복구시켜볼 때도 SQL 서버를 열기 직전까지만 돌려봤기 때문이다.

기말 발표 때 나는 프론트엔드 담당이라서 로그인 토큰을 로컬에 저장했던 걸로 기억한다. 그런데 회원가입한 수많은 회원 정보는 어떻게 저장했었는지가 잘 기억이 안 났다. 백엔드 담당 친구의 발표 내용을 들었었는데도 잊어버린 건지, 면접에서는 “본인은 프론트만 했군요”라는 말까지 들었다. (Next.js와 React 둘 다 했었고, 자동화 도구를 쓰긴 했지만 EJS로 백엔드 엔드포인트·API도 다른 수업에서 배웠고 Postman도 써본 적이 있는데…)

곰곰이 생각해보니 원래는 PostgreSQL을 쓰려다가 비용 문제로 Supabase로 갈아탔다고 백엔드 개발 친구가 이슈에 남겼던 게 어렴풋이 기억난다. 회원가입·로그인 기능은 구현했지만, 회원 정보를 담는 DB 시스템이 완성되기 전에 프로젝트가 마감된 것 같다.

위키에 흩어져 있는 계획 페이지들을 좀 다듬고, 이 부분을 다시 한번 파봐야겠다.