브이엠에스홀딩스
인턴·신입근거: 해양 산업 내 다양한 문제 영역을 대상으로 MVP를 빠르게 설계하고 출시합니다.
※ 실제 산출물이 아닌 AI 예측 시안입니다.
브이엠에스홀딩스는 해양(Maritime) 산업의 기술적 공백을 노려 여러 MVP를 빠르게 설계하고 출시하며, 하나의 제품에 고정되지 않고 시장 반응에 따라 방향을 바꿉니다. 이 자리는 그 MVP들의 백엔드를 맡아 Spring Boot 기반 REST API를 설계부터 배포까지 책임지고, LLM(Gemini, GPT 등)을 제품에 통합하는 역할입니다. 이 접수 API는 그 조합이 처음 만나는 문제에 놓입니다. 해양 산업은 디지털화가 거의 안 돼 배에서 오는 보고가 잘 정리된 요청이 아니라 표와 메신저 한 줄이 섞인 자유 형식이고, 그걸 정해진 항목으로 옮기는 일이 매일 반복됩니다. 항목 정의를 코드 밖 표에 둬서 제품이 바뀌어도 스키마를 갈아엎지 않게 한 것은 잦은 피봇을 전제로 한 설계이고, 확정 권한을 모델이 아니라 규칙에 둔 것은 잘못된 값이 장부에 남으면 정산과 배선 계획이 함께 틀어지기 때문입니다. 다만 이 포트폴리오는 REST API 설계와 멱등·상태 전이 처리, 근거 인용 검증, 컨테이너 배포라는 기술 역량을 보여주며, 해운과 선박 운항 도메인 전문성은 주장하지 않습니다. 모르는 도메인 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
자격요건 첫 줄이 Spring Boot 기반 REST API를 설계부터 배포까지 경험해 본 사람입니다. 접수 API는 멱등성과 상태 전이, 재제출 처리가 전부 설계 판단이라 이 역량이 그대로 드러나는 자리입니다.
LLM(Gemini, GPT 등)을 제품에 통합하는 AI 기반 서비스를 함께 개발한다고 적혀 있습니다. 분석 리포트가 아니라 백엔드 기능의 한 부분으로 모델을 넣되, 확정 여부는 규칙이 쥐는 구조여야 운영에 들어갑니다.
하나의 제품에 고정되지 않고 시장 반응에 따라 유연하게 방향을 전환하며, 초기 스타트업의 잦은 피봇을 즐길 사람을 찾습니다. 그래서 항목 정의가 바뀌어도 스키마와 코드를 갈아엎지 않는 구조가 실제 요구사항이 됩니다.
선박에서 올라온 자유 형식 보고를 `POST /reports` 로 받아, 항목 정의표에 있는 항목만 채워 넣는 백엔드 API입니다. 채운 값마다 원문 어느 줄에서 읽었는지를 함께 저장하고, 값을 못 채웠거나 단위가 뒤섞여 확정할 수 없는 항목이 하나라도 있으면 보고를 `확정` 으로 넘기지 않고 `보류` 로 두면서 빠진 항목만 담은 되묻기 목록을 응답에 실어 보냅니다. 담당자가 그 항목만 채워 다시 보내면 같은 항차 키로 묶여 앞선 제출을 덮고, 모든 필수 항목이 채워진 순간 `확정` 으로 전이합니다. 같은 보고가 두 번 들어와도 항차 키가 같으면 새 레코드를 만들지 않습니다. 항목 정의는 코드가 아니라 표에 있어서 새 MVP가 다른 항목을 요구해도 스키마를 갈아엎지 않습니다. 실제 선사 데이터를 가지고 있지 않으므로 입력은 작성자가 만든 더미 보고이며, 이 포트폴리오가 보여주는 것은 그 위에서 도는 접수 백엔드입니다.
선사 운항관리팀에서 매일 아침 배들의 보고를 받는 담당자입니다. 어떤 배는 표를 그려 보내고 어떤 배는 메신저로 두 줄만 보내는데, 저는 그걸 전부 같은 양식에 옮겨 적습니다. 값이 하나 빠져 있으면 배에 다시 물어야 하는데 무엇이 빠졌는지 제가 눈으로 찾아야 해서, 오후가 다 가서야 되묻는 일이 잦습니다. 받자마자 무엇이 비었는지 바로 알고 그 항목만 물어보고 싶고, 배가 같은 보고를 두 번 보내도 장부가 두 줄이 되지 않기를 바라는 사람입니다.
운항 보고의 항목 값은 대부분 원문에 그대로 적혀 있고 어느 줄에서 읽었는지도 지목할 수 있다고 보고, 모델에게는 값과 근거 줄만 뽑게 하고 확정 여부는 규칙이 쥐면, (a) 자유 형식 보고가 정해진 항목으로 채워지고, (b) 못 채운 항목이 있으면 확정되지 않고 그 항목만 되묻기로 돌아가며, (c) 채운 값이 맞았는지는 원문 인용 일치로 기계 판정되어 모델이 지어낸 값이 장부에 남지 않습니다.
`POST /reports` 로 자유 형식 보고를 받아 항목 정의표대로 채우고, 값마다 근거 줄을 남기며, 못 채운 항목이 있으면 보류 상태로 두고 되묻기 목록을 응답하는 백엔드입니다. 같은 항차 키로 다시 들어오면 앞선 제출을 덮고 모든 필수 항목이 차면 확정으로 전이합니다. 스캔 이미지 보고 판독은 이미지 처리가 들어가므로 2주차로 미루고, 1주차는 텍스트 보고만 받습니다.
선명과 항구명 표기 흔들림을 정규화 규칙으로 묶어 같은 항차가 갈라지지 않게 하고, 운항관리 담당 2명이 되묻기가 과하지 않았는지 라벨링해 일치도를 붙이는 단계입니다. 스캔 이미지 보고도 이때 접수 대상에 넣습니다.
Docker 이미지로 만들어 AWS ECS에 올리고, Terraform으로 인프라를 정의하며 GitHub Actions로 배포를 자동화하는 단계입니다. 항목 정의가 바뀌어도 무중단으로 반영되는지 확인합니다.
함정을 섞은 자유 형식 보고 40건을 접수 API에 넣으면 항목이 채워진 보고와 보류된 보고가 갈려 나오고, 보류 건은 어떤 항목이 왜 빠졌는지 되묻기 목록으로 돌아오는 걸 시연합니다
채운 값이 근거 줄에 실제로 있는지 문자열 대조로 100% 자동 판정합니다. 일부러 만든 함정 4종(단위 뒤섞임, 값 결측, 한 장에 두 항차, 원문에 없는 항목 요구)이 확정으로 넘어가지 않고 전부 보류로 빠지는지 매번 검사합니다
같은 항차 보고를 순서를 바꿔 세 번 보내도 레코드가 하나로 유지되고 마지막 상태만 남는 걸 보여줍니다. 형식이 깨진 요청 30종(빈 본문·항차 키 누락·잘못된 인코딩·지나치게 긴 본문)에도 API가 죽지 않고 무엇이 잘못됐는지 응답합니다
모델이 원문에 없는 값을 채우려 한 시도가 근거 줄 대조에서 걸려 장부에 남지 않는 걸 사례로 보여줍니다. 단, 보고와 정답을 모두 작성자가 만든 합성 기준이라 '성능 검증' 이 아니라 '데모 조건에서의 동작' 입니다
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 전부 작성자가 만든 더미데이터 자가채점이며, 실제 추출 정확도와 되묻기 적중률은 브이엠에스홀딩스가 다루는 선사의 실제 보고와 운항관리 담당자 검수가 있어야 측정 가능합니다. 이 백엔드는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다
이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 데이터 자가채점이라 '성능 증명' 이 아닙니다. 면접에서 '데모 조건 동작 + 실검증 준비 상태' 로 솔직히 설명합니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 단위 뒤섞임·값 결측·항차 혼재·선명 표기 흔들림 같은 경계 케이스를 더미 보고에 섞어, 쉬운 문제만 푸는 게 아님을 보여줍니다
되묻기가 잦아지면 담당자가 도구를 버립니다. 안전하게 만들수록 보류가 늘어나는 구조라, 보류 비율 자체를 지표로 놓고 어느 항목에서 되묻기가 몰리는지 봐야 항목 정의를 고칠 수 있습니다
항목 정의표를 코드 밖으로 뺐다고 해서 아무 항목이나 추가되는 것은 아닙니다. 필수 여부와 단위가 잘못 정의되면 그대로 잘못된 장부가 쌓이므로, 정의 변경 자체에 검토가 필요합니다
실제 도입 시 달라지는 것을 명시합니다. 선사 실제 보고 양식과 채널, 스캔 이미지 판독, 운항관리 담당자 검수로 교체해야 하며 이는 도입 단계 과제로 분리합니다
이 포트폴리오는 REST API 설계와 멱등·상태 전이 처리, 근거 인용 검증, 컨테이너 배포라는 기술 역량을 보여주며, 해운과 선박 운항 도메인 전문성은 주장하지 않습니다. 모르는 도메인 깊이는 면접에서 모른다고 말하는 편이 낫습니다
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
배에서 올라온 자유 형식 보고 원문입니다. 접수 API가 받는 입력이며, 표 형식과 메신저 한 줄이 섞이고 단위가 뒤섞이거나 값이 비어 있는 보고를 일부러 넣어 쉬운 데이터만 푸는 게 아님을 보여줍니다.
| inbound_id | received_at | channel | vessel_raw | voyage_no_raw | raw_text | is_resubmit | attachment_only |
|---|---|---|---|---|---|---|---|
| in001 | 2026-06-03T12:10:00+00:00 | MV HANARO | V-24 | DISTANCE RUN: 312 NM FO CONSUMED: 28.4… | false | false | |
| in002 | 2026-06-04T12:05:00+00:00 | messenger | M/V HANARO | V-24 | 오늘 298마일 뛰었고 FO 27100kg 썼습니다. 화물 그대로고 … | false | false |
| in003 | 2026-06-05T12:02:00+00:00 | satcom | MV SEJONG | S-11 | DIST 283 / FO 31.0 / CARGO 58900 / BUS… | false | false |
| in004 | 2026-06-06T12:04:00+00:00 | messenger | MV SEJONG | S-11 | 275마일 뛰었습니다. FO 29.8 썼고 DO 는 아직 집계 안 됐… | false | false |
| in005 | 2026-06-06T15:40:00+00:00 | messenger | MV SEJONG | S-11 | 아까 빠뜨린 DO 0.9 MT 입니다. | true | false |
아래 JSON Schema 에 맞는 선박 자유 형식 운항 보고 80건을 JSON 배열로 생성. 선박은 MV HANARO·MV SEJONG·MV ARIRANG·MV DAEHAN 네 척, raw_text 는 표 형식·메신저 한 줄·약어 나열을 고루 섞고 한국어와 영어를 함께 쓸 것.
{"type":"object","properties":{"inbound_id":{"type":"string"},"received_at":{"type":"string"},"channel":{"enum":["email","messenger","satcom","upload"]},"vessel_raw":{"type":"string"},"voyage_no_raw":{"type":["string","null"]},"raw_text":{"type":"string"},"is_resubmit":{"type":"boolean"},"attachment_only":{"type":"boolean"}},"required":["inbound_id","received_at","channel","vessel_raw","raw_text","is_resubmit","attachment_only"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라. (1) 단위가 KG 로 적혀 MT 로 환산해야 하는 보고 10건과 단위가 아예 없는 수치만 적힌 보고 8건(후자는 보류가 정답이어야 한다), (2) 필수 항목 하나가 빠진 보고 12건과 그 뒤에 빠진 항목만 채워 다시 보낸 is_resubmit=true 보고 12건(같은 vessel_raw·voyage_no_raw 로 묶여야 한다), (3) voyage_no_raw 가 null 이라 항차를 특정할 수 없는 보고 6건, (4) 같은 선박을 MV / M/V / 소문자로 다르게 적은 표기 흔들림 12건, (5) 같은 항구를 SINGAPORE / Singapore Port / SGSIN 으로 다르게 적은 보고 8건, (6) 한 본문에 두 항차가 섞인 보고 4건, (7) attachment_only=true 이고 raw_text 가 빈 보고 5건, (8) 앞선 보고와 내용이 완전히 같은 중복 전송 4건(레코드가 하나로 유지돼야 한다). inbound_id 는 in001 부터 연속으로. JSON 배열만.{"type":"object","properties":{"inbound_id":{"type":"string"},"received_at":{"type":"string"},"channel":{"enum":["email","messenger","satcom","upload"]},"vessel_raw":{"type":"string"},"voyage_no_raw":{"type":["string","null"]},"raw_text":{"type":"string"},"is_resubmit":{"type":"boolean"},"attachment_only":{"type":"boolean"}},"required":["inbound_id","received_at","channel","vessel_raw","raw_text","is_resubmit","attachment_only"]}접수 API가 채울 항목의 정의입니다. 코드가 아니라 표에 두어 새 MVP가 다른 항목을 요구해도 스키마를 갈아엎지 않게 합니다. 필수 여부와 단위, 확정을 막는 조건이 여기서 결정되므로 되묻기 규칙의 출처이기도 합니다.
| field | label_ko | type | unit | required | aliases | normalize | hold_if |
|---|---|---|---|---|---|---|---|
| distance_run_nm | 항주거리 | number | NM | true | ["DISTANCE RUN","DIST","항주거리","마일"] | — | ["값없음","항차모호"] |
| fo_consumed_mt | 연료유 소모 | number | MT | true | ["FO CONSUMED","FO","BUNKER FO","연료"] | kg_to_mt | ["값없음","단위없음","항차모호"] |
| do_consumed_mt | 경유 소모 | number | MT | true | ["DO CONSUMED","DO","경유"] | kg_to_mt | ["값없음","단위없음"] |
| cargo_mt | 적재 화물량 | number | MT | true | ["CARGO","CARGO ONBOARD","화물"] | ballast_to_zero | ["값없음"] |
| next_port_code | 다음 기항지 | string | — | true | ["NEXT PORT","BOUND FOR","기항지"] | port_to_locode | ["값없음"] |
아래 JSON Schema 에 맞는 운항 보고 항목 정의 30건을 JSON 배열로 생성. 항목은 코드가 아니라 표에 두는 설정이라는 전제로, 새 MVP 가 추가할 법한 항목까지 포함할 것.
{"type":"object","properties":{"field":{"type":"string"},"label_ko":{"type":"string"},"type":{"enum":["number","string","date","enum"]},"unit":{"type":["string","null"]},"required":{"type":"boolean"},"aliases":{"type":"array","items":{"type":"string"}},"normalize":{"type":["string","null"]},"hold_if":{"type":"array","items":{"enum":["값없음","단위없음","단위불일치","항차모호","이상값"]}}},"required":["field","label_ko","type","required","aliases","hold_if"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라. (1) aliases 가 서로 겹쳐 어느 항목인지 헷갈리는 쌍(FO / BUNKER FO / 연료) 3쌍, (2) aliases 가 비어 있어 자유 형식 본문에서는 못 짚는 항목 3건, (3) required=true 인데 hold_if 가 비어 있어 정의가 어긋난 항목 2건(정의 검토가 필요한 사례로 남길 것), (4) unit 이 null 인데 type 이 number 인 항목 3건(단위없음 보류가 걸려야 한다), (5) normalize 가 필요한 항목 8건 이상(kg_to_mt·port_to_locode·to_utc 등), (6) required=false 라 안 채워도 확정되는 선택 항목 10건. 같은 field 를 두 번 만들지 말 것. JSON 배열만.{"type":"object","properties":{"field":{"type":"string"},"label_ko":{"type":"string"},"type":{"enum":["number","string","date","enum"]},"unit":{"type":["string","null"]},"required":{"type":"boolean"},"aliases":{"type":"array","items":{"type":"string"}},"normalize":{"type":["string","null"]},"hold_if":{"type":"array","items":{"enum":["값없음","단위없음","단위불일치","항차모호","이상값"]}}},"required":["field","label_ko","type","required","aliases","hold_if"]}| Spring Boot (Kotlin) | 접수 엔드포인트와 상태 전이, 멱등 처리를 구현하는 REST API 본체(사내 Server 스택) |
| PostgreSQL | 보고 원문과 항목별 값·근거 줄, 항차 키, 상태 이력을 담는 저장소이자 멱등 판정의 기준 |
| MySQL | 항목 정의표와 정규화 사전처럼 자주 바뀌는 설정을 분리해 두는 용도로, 두 엔진 모두에서 스키마가 도는지 확인합니다 |
| LLM(Gemini, GPT) | 자유 형식 원문에서 항목 값과 그 값을 읽은 줄 번호를 뽑는 데만 쓰며, 확정 여부는 규칙이 판단합니다 |
| React.js | 접수 결과와 되묻기 목록을 확인하는 최소한의 운영 화면(백엔드 중심이라 필요한 만큼만 만듭니다) |
| Docker | 3주차에 API를 이미지 한 장으로 만들어 로컬과 운영에서 같은 것이 돌게 포장 |
| AWS ECS | 3주차에 컨테이너를 올려 접수 API를 운영하는 실행 기반 |
| Terraform | 3주차에 ECS와 데이터베이스, 시크릿을 코드로 정의해 같은 환경을 다시 세울 수 있게 남깁니다 |
| GitHub Actions | 테스트와 배포를 자동화해 항목 정의가 바뀌어도 손으로 올리지 않게 합니다 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우고 싶으면 2주차(표기 정규화·되묻기 검수)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(AWS ECS 배포·Terraform·배포 자동화)로 진행합니다.
보고 한 건을 접수한 결과입니다. 확정인지 보류인지, 채운 항목마다 값과 그 값을 읽어낸 원문 줄, 채우지 못한 항목과 그 이유, 되묻기 문구, 그리고 재제출이 앞선 제출을 덮었는지를 담습니다. 확정 판정이 규칙대로 됐는지 기계로 다시 검사할 수 있게 필드를 나눠 둡니다.
{"type":"object","properties":{"inbound_id":{"type":"string"},"report_key":{"type":["string","null"]},"status":{"enum":["확정","보류","거절"]},"superseded_inbound_id":{"type":["string","null"]},"filled":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"value":{"type":["string","number","null"]},"source_line":{"type":["number","null"]},"source_quote":{"type":"string"},"normalized_by":{"type":["string","null"]}},"required":["field","value","source_quote"]}},"missing":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"hold_reason":{"enum":["값없음","단위없음","단위불일치","항차모호","이상값"]},"ask_ko":{"type":"string"}},"required":["field","hold_reason","ask_ko"]}},"rejected_reason":{"type":["string","null"]}},"required":["inbound_id","status","filled","missing"]}[
{
"input_ref": "in002 · 메신저 한 줄 보고 · FO 가 KG 로 적혀 환산 필요",
"output": {
"inbound_id": "in002",
"report_key": "HANARO/V-24/2026-06-04",
"status": "보류",
"superseded_inbound_id": null,
"filled": [
{
"field": "vessel_id",
"value": "HANARO",
"source_line": 1,
"source_quote": "M/V HANARO",
"normalized_by": "strip_mv_prefix"
},
{
"field": "distance_run_nm",
"value": 298,
"source_line": 1,
"source_quote": "오늘 298마일 뛰었고",
"normalized_by": null
},
{
"field": "fo_consumed_mt",
"value": 27.1,
"source_line": 1,
"source_quote": "FO 27100kg 썼습니다",
"normalized_by": "kg_to_mt"
},
{
"field": "next_port_code",
"value": "SGSIN",
"source_line": 1,
"source_quote": "싱가포르 8일 아침 도착 예정",
"normalized_by": "port_to_locode"
}
],
"missing": [
{
"field": "do_consumed_mt",
"hold_reason": "값없음",
"ask_ko": "경유(DO) 소모량이 보고에 없습니다. 몇 MT 였는지 알려주시겠습니까?"
},
{
"field": "cargo_mt",
"hold_reason": "값없음",
"ask_ko": "적재 화물량이 '그대로' 로만 적혀 있습니다. 수치로 확인해 주시겠습니까?"
},
{
"field": "eta_utc",
"hold_reason": "값없음",
"ask_ko": "도착 예정이 '8일 아침' 으로만 적혀 있습니다. 시각을 알려주시겠습니까?"
}
],
"rejected_reason": null
}
},
{
"input_ref": "in005 · 앞선 보류 보고(in004)에서 빠진 DO 만 채워 재제출",
"output": {
"inbound_id": "in005",
"report_key": "SEJONG/S-11/2026-06-06",
"status": "확정",
"superseded_inbound_id": "in004",
"filled": [
{
"field": "do_consumed_mt",
"value": 0.9,
"source_line": 1,
"source_quote": "아까 빠뜨린 DO 0.9 MT 입니다",
"normalized_by": null
}
],
"missing": [],
"rejected_reason": null
}
},
{
"input_ref": "in008 · 한 본문에 두 항차가 섞여 어느 값인지 정할 수 없음",
"output": {
"inbound_id": "in008",
"report_key": null,
"status": "보류",
"superseded_inbound_id": null,
"filled": [
{
"field": "vessel_id",
"value": "DAEHAN",
"source_line": 1,
"source_quote": "MV DAEHAN",
"normalized_by": "strip_mv_prefix"
}
],
"missing": [
{
"field": "distance_run_nm",
"hold_reason": "항차모호",
"ask_ko": "한 보고에 VOYAGE 24 와 25 가 함께 있습니다. 어느 항차 기준으로 접수할까요?"
},
{
"field": "voyage_no",
"hold_reason": "항차모호",
"ask_ko": "항차 번호를 하나로 지정해 주시겠습니까?"
}
],
"rejected_reason": null
}
},
{
"input_ref": "in009 · 첨부만 있고 본문이 비어 1주차에는 읽을 수 없음",
"output": {
"inbound_id": "in009",
"report_key": null,
"status": "거절",
"superseded_inbound_id": null,
"filled": [],
"missing": [],
"rejected_reason": "본문이 비어 있고 첨부만 있습니다. 스캔 문서 판독은 아직 지원하지 않으므로 본문으로 다시 보내주시기 바랍니다."
}
}
][자동 검증: 결정론, 사람 없이 통과] 1. JSON Schema 통과: status·hold_reason 열거값과 filled·missing 구조를 기계로 검사해 형식이 깨진 출력을 거릅니다. 2. 근거 인용 대조: filled 의 source_quote 가 그 보고 raw_text 의 부분 문자열인지 공백 정규화 후 검사합니다. 원문에 없는 문장을 인용하면 그 자리에서 실패입니다. 3. 확정 조건 강제: field_defs 에서 required=true 인 항목이 하나라도 missing 에 있으면 status 는 반드시 '보류' 여야 합니다. 이 조합이 어긋나면 실패로 처리합니다. 잘못된 값이 장부에 확정되는 것을 막는 핵심 검사입니다. 4. 환산 검증: normalized_by 가 붙은 값을 원문 수치로 다시 환산해 맞는지 계산합니다(kg_to_mt 는 1000으로 나눈 값이어야 합니다). 5. 멱등 검사: 같은 report_key 로 들어온 제출이 새 레코드를 만들지 않고 superseded_inbound_id 로 앞선 제출을 가리키는지, 그리고 최종 상태가 하나만 남는지 확인합니다. 6. 되묻기 대상 일치: missing 의 field 가 모두 field_defs 에 있는 항목이고, 그 항목의 hold_if 에 해당 hold_reason 이 들어 있는지 대조합니다. [수동 검증: 사람 필요] 1. 운항관리 담당 2명이 되묻기가 과하지 않았는지(보고만 보고도 채울 수 있었는데 물어본 건 아닌지) 라벨링하고, 두 사람 판정 일치도를 Cohen's κ(두 사람 답이 우연 이상으로 일치하는 정도, 0~1)로 봅니다. 2. ask_ko 문구가 배에 그대로 보내도 될 어조인지 10% 표본을 사람이 읽습니다.
포트폴리오가 “무엇을 만들지”라면, 시나리오 테스트는 “현장에서 어떻게 판단·소통할지” 입니다. 실제 이 채용공고 맥락의 대본을 읽고 무엇을 물어야 할지 직접 써봅니다.
근거: 해양 산업 내 다양한 문제 영역을 대상으로 MVP를 빠르게 설계하고 출시합니다.