1. 화물 배송 현장을 위한 정산 서비스 bigpicture_truck 은 화물 기사들의 일일 배송 실적(신용·착불·추가금)과 주간 출금을 기록하고, 관리자가 전 직원의 정산 현황을 한눈에 파악할 수 있도록 돕는 서비스다. 기사는 매일 운행을 마치고 매출과 출금 내역을 입력하며, 관리자는 대시보드에서 차종별 필터와 검색을 거쳐 정산 합계를 확인하거나 직원별 상세 내역을 조회하고 엑셀로 내려받는다. 운전대를 잡고 이동하는 현장 기사들이 모바일 브라우저나 설치형 앱으로 매일 정산을 마감해야 하는 만큼, 입력의 명확성과 모바일 환경에서의 즉각적인 반응 속도가 서비스의 핵심이다. 2. 현장에서 마주한 세 가지 문제 서비스를 실제 운영하는 과정에서 기능과 성능 양쪽 모두에서 병목이 드러났다. 첫째, 정산 계산과 입력 방식이 지나치게 복잡했다. 기존에는 매출에서 '그 주에 일한 앞 5일'에 단가를 곱한 사납금을 제하고 실수령을 구한 뒤 출금을 차감하는 구조였다. 하지만 사납금 부과 방식은 현장 기사들에게 심리적인 압박을 주었고, 기준 요일을 따지는 계산식 또한 불필요한 혼선을 낳았다. 입력 방식 역시 '건별로 찍는 방식'과 '하루치를 몰아서 적는 방식'을 동시에 열어두었더니, 두 방식의 결과가 같음에도 기사들이 무엇을 골라야 할지 매번 고민해야 했다. 둘째, 모바일 환경의 터치 반응이 극도로 느렸다. 프로덕션 환경의 TTFB(Time to First Byte)를 측정한 결과 1.2~2.7초에 달했다. Vercel의 응답 헤더( x-vercel-id )를 추적해 보니 icn1::iad1 로 찍혔다. 사용자의 요청은 서울 엣지( icn1 )로 들어오는데, 서버리스 함수는 미국 동부( iad1 )에서 돌고 있었고, 데이터베이스(Supabase)는 서울에 있었다. 쿼리 하나를 던질 때마다 태평양을 두 번 건너야 했고, 레이아웃과 페이지 컴포넌트가 세션 확인과 프로필 조회를 각각 따로 수행해 네트워크 왕복 횟수마저 두 배로 늘어났다. 여기에 loading.tsx 조차 없어 탭을 눌러도 서버 응답이 올 때까지 화면이 멈춘 것처럼 보였다. 셋째, 정산 내역 수정의 권한과 이력 추적 체계가 없었다. 돈이 오가는 정산 데이터임에도 누가 언제 무엇을 고쳤는지 남지 않았다. 또한 직원이 지난 정산 내역을 임의로 고칠 수 있으면 주간 마감 데이터가 뒤틀릴 위험이 있었고, 반대로 당일 오기입한 내역까지 완전히 잠가버리면 관리자에게 사소한 수정 요청이 쏟아지는 문제가 있었다. 3. 구조적 단순화와 인프라 정리를 위한 판단 복잡해진 화면과 느린 흐름을 해결하기 위해 과감하게 덜어내고 바닥부터 정리하는 방식을 택했다. 정산 모델의 단순화 : 사납금 개념을 앱 전체에서 통째로 걷어냈다. 정산 구조를 매출 → 출금 → 미출금(매출 - 출금액) 세 줄로 축약했다. 복잡한 주간 근무일수 계산식을 지우고, AI 코칭 프롬프트와 공지사항, 설정 화면에서도 사납금 관련 로직을 전면 제거했다. 입력 UX의 단일화 : '건별 입력' 탭을 없애고 '하루 마감'과 '일주일 출금' 2개 탭으로 통일했다. 당일 총건수와 신용·착불·추가금 합계만 적어 마감하도록 통일해 현장의 입력 피로도를 낮췄다. 함수 리전 서울 고정 및 요청 최적화 : Vercel 서버리스 함수 실행 리전을 icn1 (서울)로 강제 지정했다. 데이터베이스가 있는 곳과 물리적 거리를 일치시켜 네트워크 지연을 없애는 것이 최우선이었다. 반복되는 프로필 조회는 React cache 로 묶어 요청당 1회만 실행되게 했고, 홈 화면에서 순차적으로 호출하던 AI 보고서 쿼리를 기존 정산 쿼리와 Promise.all 로 묶어 병렬화했다. RLS 기반 수정 통제와 DB 트리거 이력 관리 : 직원은 오직 '오늘 작성한 내역'만 수정·삭제할 수 있도록 제한했다. 이때 기준을 작업 일자( work_date )가 아니라 실제 등록 시점( created_at )으로 잡았다. 지난 날짜의 정산을 뒤늦게 올리더라도 방금 등록한 오타는 즉시 고칠 수 있어야 하기 때문이다. 관리자는 과거 내역까지 자유롭게 수정할 수 있게 하되, 변경 사항은 애플리케이션 코드가 아닌 PostgreSQL DB 트리거로 자동 기록하도록 설계했다. 화면 코드에 이력 로깅을 두면 API 엔드포인트나 진입 경로가 늘어날 때 누락이 발생하기 때문이다. 또한 Supabase의 anon 키가 노출되는 환경을 고려해 서버 액션뿐 아니라 RLS(Row Level Security)에도 동일한 시간 검증 규칙을 걸어 직접 호출 우회를 막았다. 4. 변경 전과 변경 후 4.1. 서버리스 함수 리전 지정 및 병렬 쿼리 처리 서버리스 함수가 미국 동부에서 돌며 DB 왕복 지연을 일으키던 문제를 해결하기 위해 vercel.json 에 서울 리전을 명시하고, 페이지 로드 시 필요한 데이터 조회를 하나로 묶었다. 변경 전: 순차 쿼리 호출 및 기본 리전 실행 // src/app/(app)/home/page.tsx const [{ data: entryData }, { data: weekDaily }, { data: weekWithdrawals }] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), ]); // 앞선 조회가 끝난 뒤 순차적으로 따로 호출하여 추가 왕복 시간 발생 const { data: aiRows } = await supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate); 변경 후: vercel.json 서울 리전 고정 및 병렬 조회 통합 // vercel.json { "framework": "nextjs", "regions": ["icn1"] } // src/app/(app)/home/page.tsx // 모든 초기 데이터를 Promise.all 내에서 병렬로 단 한 번에 조회 const [ { data: entryData }, { data: weekDaily }, { data: weekWithdrawals }, { data: aiRows }, ] = await Promise.all([ supabase .from("entries") .select("*") .eq("user_id", profile.id) .eq("work_date", workDate) .order("created_at", { ascending: false }) .limit(300), supabase .from("v_daily_totals") .select("work_date, count, credit, cod, extra, total") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo), supabase .from("withdrawals") .select("*") .eq("user_id", profile.id) .gte("work_date", weekFrom) .lte("work_date", weekTo) .order("created_at", { ascending: false }), supabase .from("ai_reports") .select("kind, content") .eq("user_id", profile.id) .eq("report_date", workDate), ]); 4.2. 정산 내역 수정 권한 통제 직원이 과거의 정산 데이터를 임의로 조작하지 못하도록 서버 액션 단계에서 작성 시점을 검증하도록 변경했다. 변경 후: 작성일 기준의 권한 판별 로직 // src/app/(app)/entry-actions.ts /** * 내역 수정·삭제 권한 판단: * - 관리자: 전 직원 내역 언제든 수정 가능 * - 직원: 본인 내역이면서 '오늘 작성한 것(created_at)'만 수정 가능 */ async function canModify(entryId: string): Promise<ActionResult> { const profile = await requireProfile(); const supabase = await createClient(); const { data } = await supabase .from("entries") .select("user_id, created_at") .eq("id", entryId) .maybeSingle(); if (!data) return { ok: false, error: "내역을 찾을 수 없습니다." }; if (profile.role === "admin") return { ok: true }; if (data.user_id !== profile.id) { return { ok: false, error: "본인 내역만 수정할 수 있습니다." }; } if (!isWrittenToday(data.created_at)) { return { ok: false, error: "오늘 적은 것만 수정할 수 있습니다. 지난 것은 관리자에게 말씀해 주세요.", }; } return { ok: true }; } 5. 정돈된 화면과 안정적인 운영 이번 작업을 통해 모바일 현장과 관리자 운영 환경 전반이 실질적으로 달라졌다. 체감 응답 속도와 입력 단순화 : Vercel 서버리스 함수를 서울( icn1 )로 옮겨 쿼리 왕복 시간을 줄였고, loading.tsx 와 스켈레톤, useLinkStatus 진행 막대를 적용해 탭 이동 시 멈춤 현상을 없앴다. 정산 입력은 '하루 마감' 하나로 정리되어 기사들이 작성 방식을 고민할 필요가 없어졌다. 정산 데이터의 무결성 확보 : 직원은 오늘 등록한 내역만 바로잡을 수 있고 과거 내역은 관리자만 수정할 수 있도록 분리했다. 수정 권한은 서버 액션과 RLS 양쪽에 걸려 있어 우회가 불가능하며, 관리자가 항목을 수정하거나 삭제할 때마다 DB 트리거가 이전 값과 변경 값을 빠짐없이 entry_logs 에 기록한다. 관리 업무의 효율화 : 관리자 대시보드에는 차종별 다중 필터와 선택 인원 합계 보기 기능이 붙었고, 조회 기간 그대로 직원별 시트와 누적 미출금액이 포함된 엑셀(.xlsx) 파일로 내려받을 수 있게 되었다. 독립적인 앱 배포 환경 구축 : Capacitor를 얹어 웹 서비스를 감싸는 형태로 안드로이드 정식 서명 키(PKCS12) 기반의 APK 자동 빌드 파이프라인(GitHub Actions)을 마련했다. 스토어 심사를 기다리지 않고 웹 배포만으로 앱 화면이 즉시 갱신되며, 카카오톡 인앱 브라우저 차단과 삼성 보안 설정을 안내하는 전용 설치 페이지( /install )를 제공해 현장 기사들의 설치 문의를 줄였다.
1. 서비스 소개 '샥(syak)'은 매장의 빈자리나 갑작스럽게 발생한 취소석을 실시간으로 감지하고, 해당 자리를 필요로 하는 소비자에게 맞춤형으로 매칭하여 예약을 연결해 주는 자동 매칭 서비스다. 매장(살롱 등)의 원장님에게는 비어 버린 예약 슬롯을 빠르게 채워 매출 손실을 막아주고, 소비자에게는 예약하기 힘든 인기 매장의 취소석을 선점할 수 있는 기회를 제공한다. 이를 위해 백엔드와 관리자 시스템은 실시간 슬롯 상태 변화와 정교한 카탈로그 조회 기능을 안정적으로 처리해야 한다. 2. 문제 이번 주 개발자 y10b가 해결하고자 한 핵심 문제는 운영 환경의 자원 제약으로 인한 데이터베이스 부하 와 수동 마케팅 작업의 비효율성 이었다. 첫째, 서비스가 구동되는 운영 환경은 912MB 메모리를 가진 소형 EC2 인스턴스였다. 이 환경에는 Redis가 따로 설정되어 있지 않아, 기존의 캐시 레이어가 캐싱을 전혀 수행하지 않는 NullCacheService (no-op)로 동작하고 있었다. 이로 인해 트래픽이 집중되는 소비자 카탈로그 조회와 지도 검색 요청이 매번 Supabase 실시간 DB로 직행했다. 무료 티어 Supabase의 지연 시간(간헐적으로 1초 이상 발생)이 고스란히 사용자 경험 저하로 이어졌다. 특히 지도 검색 시 사용자가 화면을 미세하게 움직일 때마다 정밀한 위경도 좌표가 매번 달라져 캐시 키가 미스되는 구조적 한계가 존재했다. 둘째, 관리자 페이지의 통계 및 파트너숍 조회 성능 문제였다. 기존 코드는 Supabase의 기본 1000행 제한(PostgREST limit) 범위 안에서 데이터를 조회할 때, 수집 범위가 늘어남에 따라 페이지네이션 루프를 중복 작성하다가 일부 데이터가 누락되는 버그를 안고 있었다. 또한 대량의 JSONB 데이터를 정렬 조건과 함께 조회하면서 발생하는 JSONB detoast 부하로 인해 데이터베이스 타임아웃 위험에 상시 노출되어 있었다. 셋째, 인스타그램 쓰레드(Threads)를 통한 소통 공수가 너무 컸다. 우리 채널에 달린 외부 고객의 댓글에 답글을 달거나 새로운 마케팅 글을 올리는 과정이 완전히 수동으로 처리되어 원장님들의 마케팅 피로도가 누적되고 있었다. 3. 판단 문제를 해결하기 위해 인프라를 무리하게 확장하는 대신, 주어진 소형 서버 환경에서 효율을 극대화할 수 있는 소프트웨어적 해결책을 선택했다. 인메모리 캐시 fallback 및 보수적 상한 설정: Redis를 추가로 띄우기 어려운 912MB EC2 환경임을 감안하여, 가용 메모리(~460MB) 범위 내에서 안전하게 동작할 수 있는 프로세스 내 LRU+TTL 기반의 InMemoryCacheService 를 구현했다. 리스트 엔트리가 커질 경우를 대비해 캐시 저장소의 상한을 300개로 보수적으로 제한했다. 이는 인기 매장 상세 정보와 자주 조회되는 목록을 커버하기에 충분한 크기다. 지도 좌표의 격자 스냅(Grid Snapping): 위경도 좌표를 소수점 둘째 자리(약 1.1km 격자)로 반올림하여 스냅한 뒤 캐시 키로 사용하기로 했다. 5km 박스 검색 범위 내에서는 중심점이 0.5km 내외로 이동하더라도 결과 차이가 사실상 없기 때문에, 근처 화면 이동 시 동일한 캐시를 공유하게 만들어 캐시 적중률을 극적으로 끌어올릴 수 있다. 페이지네이션 헬퍼 통합 및 통계 캐싱: 중복되던 range 루프를 fetchAllRows 헬퍼 함수 하나로 통일하여 데이터 누락 위험을 제거했다. 또한 관리자 통계 조회 결과에 2분의 짧은 인메모리 캐시를 적용하여, 관리자가 대시보드를 반복 새로고침하더라도 데이터베이스 왕복 지연을 발생시키지 않도록 설계했다. 원장님 말투를 학습한 쓰레드 마케팅 자동화: 쓰레드 API를 연동하여 외부 댓글을 수집하고, 우리가 이전에 작성했던 답글들을 '톤 샘플'로 추출했다. 이를 Gemini API에 few-shot 샘플로 전달함으로써, 인공지능이 원장님 특유의 친근한 말투("~더라고요", "프로필 링크에 정리해뒀습니다")를 학습하여 맞춤형 답글 초안을 추천하도록 구현했다. 4. 변경 전 / 변경 후 캐시 폴백 구조 변경 (BE: composition-root.ts ) 기존에는 Redis 연결 정보가 없으면 아무런 캐싱도 하지 않는 무력화 상태였으나, 변경 후에는 메모리 상한을 300으로 둔 인메모리 캐시 서비스로 안전하게 폴백하도록 개선했다. // 변경 전 const cache: ICacheService = process.env.REDIS_URL ? new RedisCacheService(process.env.REDIS_URL) : new NullCacheService(); // 변경 후 const cache: ICacheService = process.env.REDIS_URL ? new RedisCacheService(process.env.REDIS_URL) : new InMemoryCacheService(300); 지도 좌표 격자 스냅 적용 (BE: PgShopRepository.ts ) 정밀 좌표를 그대로 캐시 키로 쓰던 로직을 소수점 둘째 자리로 반올림 처리하여 미세한 지도 조작 시에도 캐시를 재사용할 수 있도록 변경했다. // 변경 후 async findMany(filter: ShopFilter): Promise<ShopListResult> { if (filter.lat != null && filter.lng != null) { filter = { ...filter, lat: Math.round(filter.lat * 100) / 100, lng: Math.round(filter.lng * 100) / 100 }; } const cacheKey = filterCacheKey(filter); const cached = await this.cache.get<ShopListResult>(cacheKey); if (cached) return cached; // DB 조회 및 캐시 저장 로직 수행... } 1000행 한도 누락 방지용 공통 페이지네이션 헬퍼 (BE: AdminController.ts ) 각 통계 조회 핸들러마다 개별적으로 작성하면서 누락 버그를 유발했던 페이지네이션 흐름을 안전한 공통 헬퍼 함수로 통합했다. // 변경 후 async function fetchAllRows<T>( buildPage: (from: number, to: number) => PromiseLike<{ data: T[] | null; error: unknown }>, batch = 1000, ): Promise<T[]> { const all: T[] = []; let offset = 0; for (;;) { const { data, error } = await buildPage(offset, offset + batch - 1); if (error) throw error; const rows = data ?? []; all.push(...rows); if (rows.length < batch) break; offset += batch; } return all; } LRU 및 TTL 지원 인메모리 캐시 구현 (BE: InMemoryCacheService.ts ) 별도 Redis 인프라가 없는 환경에서도 프로세스 내에서 안전하게 만료 시간과 최대 엔트리 수를 관리하는 캐시 서비스를 새로 구축했다. // 변경 후 export class InMemoryCacheService implements ICacheService { private store = new Map<string, { value: unknown; expiresAt: number }>(); constructor(private readonly maxEntries = 1000) {} async get<T>(key: string): Promise<T | null> { const hit = this.store.get(key); if (!hit) return null; if (Date.now() > hit.expiresAt) { this.store.delete(key); return null; } this.store.delete(key); this.store.set(key, hit); // LRU 순서 갱신 return hit.value as T; } async set(key: string, value: unknown, ttlSeconds: number): Promise<void> { if (this.store.has(key)) this.store.delete(key); this.store.set(key, { value, expiresAt: Date.now() + ttlSeconds * 1000 }); while (this.store.size > this.maxEntries) { const oldest = this.store.keys().next().value; if (oldest === undefined) break; this.store.delete(oldest); } } async del(key: string): Promise<void> { this.store.delete(key); } } 5. 결과 이번 최적화와 기능 개발을 통해 인프라 비용을 추가로 지출하지 않고도 시스템의 응답성과 마케팅 생산성을 대폭 개선했다. 서버 자원 보호 및 캐시 적중률 상승: 912MB 소형 서버 환경에서 안전한 인메모리 캐시 레이어가 정상 작동하기 시작했다. 특히 지도 좌표 스냅 덕분에 사용자가 지도를 움직여 주변 매장을 검색할 때 Supabase 직행 쿼리가 차단되고, 캐시 범위 내에서 즉각적인 응답이 가능해졌다. 관리자 도구의 안정성 확보: 1000행 한도 누락 문제를 헬퍼 함수로 완전 차단했고, 관리자 통계 조회 API에 2분의 TTL 캐시를 적용하여 관리자 새로고침 시 발생하는 Supabase 지연을 제거(응답 속도 0~1ms 수준으로 단축)했다. 마케팅 자동화 파이프라인 구축: 관리자 페이지의 마케팅 탭에서 쓰레드 댓글과 원장님 말투를 모방한 AI 추천 답글을 실시간으로 확인할 수 있게 되었다. 추천된 초안을 대시보드 내에서 간편하게 편집한 뒤, API 연동을 통해 즉시 쓰레드 답글로 등록하거나 새 글을 원클릭으로 발행하는 기능까지 성공적으로 배포되었다.
[노동인권과 법] 제3장 근로기준법 - 제4절 임금의 내용과 실제 임금이 무엇인지부터 시작하여 통상임금·평균임금의 차이, 임금 지급원칙, 최저임금, 휴업수당, 퇴직금·퇴직연금, 회사가 도산했을 때 임금을 보호받는 방법까지 정리한다. 1. 임금이란? 근로기준법에서 임금 이란 사용자가 근로의 대가로 근로자에게 지급하는 모든 금품을 말한다. 이름이 꼭 '월급'이나 '봉급'일 필요는 없다. 기본급 수당 상여금 그 밖의 금품 ↓ 이름보다 중요한 것은 '근로의 대가인가?' 즉, 어떤 돈의 이름이 무엇인지를 보는 것이 아니라 왜 지급되는 돈인지 가 중요하다. 2. 임금이 되기 위한 기본 조건 임금에 해당하려면 크게 두 가지를 생각하면 쉽다. 1 사용자가 지급하는가? 2 근로의 대가로 지급하는가? 이 두 가지가 핵심이다. 2.1. 사용자가 지급해야 한다 원칙적으로 사용자가 근로자에게 지급하는 금품이어야 한다. 예를 들어 근로자의 급여에서 사회보험료 근로소득세 등이 원천징수되었다고 해도 원래 근로자에게 지급될 임금에서 공제되는 것이므로 임금과 관련된 금액이다. 반면 고객이 근로자에게 직접 주는 팁이나 봉사료 는 원칙적으로 사용자가 지급하는 것이 아니므로 임금이 아니다. 다만 실제 관계에 따라 근로의 대가로 인정되는 경우에는 임금으로 판단될 수 있다. 3. 가장 중요한 기준: 근로의 대가인가? 임금인지 판단할 때 가장 중요한 것은 근로의 대가성 이다. 쉽게 말하면, 일을 했기 때문에 받는 돈인가? 를 보는 것이다. 근로 제공 ↓ 그 대가로 돈을 지급 ↓ 임금 반대로 단순히 일을 하면서 발생한 비용을 돌려주는 것이거나 사용자가 호의로 지급하는 금품이라면 원칙적으로 임금이 아니다. 4. 임금이 아닌 대표적인 것 PDF에서는 다음과 같은 금품은 원칙적으로 근로의 대가가 아니므로 임금이 아니라고 설명한다. 1 실비변상적 금품 업무를 수행하면서 실제 사용한 비용을 돌려주는 것이다. 예를 들어 출장비 업무 수행을 위한 비용 등이다. 근로의 대가 X 업무 때문에 사용한 돈을 돌려받는 것 O 2 은혜적·의례적 금품 사용자가 의무 없이 호의나 의례로 지급하는 금품이다. 예를 들어 축의금 조의금 축하금 격려금 등이 있을 수 있다. 3 복리후생적 급여 근로의 직접적인 대가가 아니라 근로자의 복지를 위해 제공되는 경우다. 예를 들어 사택 제공 등의 이익이 이에 해당할 수 있다. 5. 이름만 보고 판단하면 안 된다 수당이나 격려금처럼 이름만 보면 임금이 아닌 것처럼 보여도 실제로는 임금일 수 있다. 예를 들어 일정한 돈을 계속적으로 정기적으로 지급조건을 정해 근로자에게 지급 하고 있다면 근로의 대가성이 인정될 수 있다. 이름이 '격려금'이다 → 임금 아님? X 실제로 정기적·계속적으로 지급되고 지급조건도 정해져 있다 → 임금이 될 수 있음 6. 상여금도 임금일까? 상여금도 무조건 임금인 것도 아니고 무조건 임금이 아닌 것도 아니다. 계속적·정기적으로 지급되고 지급액이나 조건이 정해져 있다면 근로의 대가인 임금 으로 볼 수 있다. 반면 그때그때 회사 사정에 따라 일시적으로 지급되는 돈이라면 임금성이 부정될 수 있다. 쉽게 구별하면 매년 정해진 기준으로 계속 지급 → 임금 가능성 ↑ 그 해 회사 사정에 따라 한 번 특별히 지급 → 임금 가능성 ↓ 7. 임금에 해당할 수 있는 여러 수당 PDF에서는 일정한 요건을 충족하여 계속적·정기적으로 지급되는 다음과 같은 금품들이 임금에 해당할 수 있다고 설명한다. 가족수당 통근수당 식사대 체력단련비 학비보조금 하계휴가비 차량운행수당 등 하지만 같은 이름의 수당이라도 지급조건이나 실제 지급형태에 따라 임금 여부가 달라질 수 있다. 이름보다 실제 지급 성격이 중요하다. 8. 유급휴일·휴가수당도 임금인가? 근로기준법에 따라 지급되는 유급휴일수당 연차유급휴가수당 등은 근로자의 생활유지를 위해 법이 지급하도록 하는 금품으로 임금에 해당한다. 반면 PDF에서는 다음과 같은 것은 손해보상적인 성격을 가지므로 임금과 구별한다. 해고예고수당 재해보상금 9. 임금을 계산하는 두 가지 중요한 기준 노동법에서는 임금을 계산할 때 특히 많이 등장하는 두 개념이 있다. 통상임금 vs 평균임금 둘 다 임금이지만 사용하는 목적이 다르다. 10. 통상임금이란? 통상임금은 소정근로 또는 총근로에 대해 정기적·일률적으로 지급하기로 정한 임금 을 말한다. 쉽게 표현하면, 평소 정상적으로 일했을 때 받기로 정해진 기본적인 임금 수준 이라고 이해하면 된다. 11. 통상임금은 어디에 사용될까? 통상임금은 여러 수당을 계산하는 기준이 된다. 대표적으로 연장근로 가산임금 야간근로 가산임금 휴일근로 가산임금 해고예고수당 유급휴일·휴가수당 등을 계산할 때 사용된다. 통상임금 ↓ 연장근로수당 야간근로수당 휴일근로수당 해고예고수당 휴일·휴가수당 등의 계산기준 12. 통상임금의 핵심 요소 PDF에서는 통상임금을 판단할 때 소정근로의 대가, 정기성, 일률성 을 중요하게 설명한다. 12.1. 소정근로의 대가 근로계약에서 정해진 정상적인 근로에 대해 지급되는 돈이어야 한다. 연장근로처럼 추가로 일했기 때문에 지급되는 돈은 그 자체가 통상임금이 되는 것은 아니다. 정상적으로 정한 근로의 대가 → 통상임금 판단 대상 추가 연장근로를 해서 받은 수당 → 통상임금 자체는 아님 12.2. 정기성 매달 지급되어야만 정기적인 것은 아니다. 1개월보다 긴 주기로 지급되더라도 일정한 간격으로 계속 지급된다면 정기성 이 인정될 수 있다. 예를 들어 매년 일정 시기에 지급되더라도 계속 반복적으로 지급된다면 정기성 판단이 가능하다. 12.3. 일률성 모든 근로자에게 똑같이 지급되어야만 하는 것은 아니다. 일정한 조건이나 기준을 충족하는 모든 근로자에게 지급된다면 일률성 이 인정될 수 있다. 13. 통상임금과 '고정성' 이 부분은 PDF에서 중요하게 다루고 있다. 과거 판례에서는 통상임금을 판단할 때 정기성 + 일률성 + 고정성 을 중요하게 보았다. 예를 들어 특정 시점에 재직해야만 받을 수 있는 상여금 등은 고정성이 없다는 이유로 통상임금에서 제외되기도 했다. 하지만 PDF에서는 2024년 말 대법원 전원합의체 판결을 통해 고정성을 통상임금의 판단요소에서 제외 했다고 설명한다. 즉, 과거 정기성 + 일률성 + 고정성 ↓ 변화 소정근로의 대가 + 정기성·일률성 을 중심으로 판단하게 된 것이다. 따라서 종전에 고정성 문제 때문에 제외되었던 재직자 조건부 정기상여금 일정 근무일수 조건부 임금 재직자에게 지급되는 명절상여금 등도 소정근로의 대가라면 통상임금에 포함될 수 있다 고 PDF에서는 설명한다. 14. 통상임금에 들어갈 수 있는 것 PDF에서 예로 드는 것은 다음과 같다. 기본급 직책수당 기술수당 위험수당 식대 교통비 체력단련비 장기근속수당 정기상여금 등이다. 다만 실제 지급조건을 종합적으로 살펴봐야 한다. 15. 평균임금이란? 평균임금은 통상임금과 계산방법 자체가 다르다. 평균임금은 산정사유가 발생한 날 이전 3개월 동안 근로자에게 지급된 임금 총액을 그 기간의 총일수로 나눈 금액 이다. 쉽게 말하면, 직전 3개월 동안 받은 임금 총액 ÷ 직전 3개월의 총일수 = 1일 평균임금 이다. 16. 평균임금은 어디에 사용될까? 대표적으로 다음을 계산할 때 사용한다. 퇴직금 휴업수당 재해보상금 감급 한도액 평균임금 ↓ 퇴직금 휴업수당 재해보상 감급한도 계산의 기준 17. 통상임금과 평균임금의 차이 구분 통상임금 평균임금 기본 의미 정상적인 소정근로의 대가 실제 직전 3개월 임금의 평균 주요 기능 각종 가산수당 계산 퇴직금·휴업수당 등 계산 계산 특징 정기적·일률적인 임금 중심 직전 3개월 실제 임금 중심 쉽게 기억하기 통상임금 = 평소 얼마 받기로 했나? 평균임금 = 최근 3개월 실제로 평균 얼마 받았나? 18. 평균임금이 통상임금보다 낮다면? PDF에서는 결근 등 근로자의 책임으로 평균임금이 통상임금보다 낮아지는 경우에는 통상임금을 평균임금으로 한다 고 설명한다. 계산된 평균임금 < 통상임금 ↓ 통상임금을 평균임금으로 사용 근로자에게 지나치게 불리한 평균임금이 계산되는 것을 막기 위한 것이다. 19. 평균임금 산정이 지나치게 불합리한 경우 퇴직 직전 특별한 사정 때문에 임금이 비정상적으로 높아지거나 낮아질 수도 있다. 이런 경우 단순히 직전 3개월만 기계적으로 적용하면 평균임금의 본래 목적과 맞지 않을 수 있다. PDF에서는 평균임금이 이례적으로 현저히 높거나 낮아 불합리한 경우에는 평균임금 제도의 취지를 고려하여 객관적·합리적으로 판단 할 수 있다고 설명한다. 20. 임금 지급의 기본원칙 사용자는 임금을 아무 방식으로나 지급할 수 없다. 중요한 기본원칙은 다음과 같다. 1 통화지급 원칙 2 직접지급 원칙 3 전액지급 원칙 4 정기일지급 원칙 이 네 가지를 묶어서 기억하면 좋다. 21. 통화지급 원칙 임금은 원칙적으로 통화 , 즉 돈으로 지급해야 한다. 따라서 사용자가 마음대로 "월급 대신 우리 회사 물건으로 줄게." 라고 할 수는 없다. 현물이나 일반적인 어음·수표 등으로 지급하는 것도 제한된다. 22. 직접지급 원칙 임금은 근로자 본인에게 직접 지급 해야 한다. 예를 들어 근로자가 자신의 임금채권을 다른 사람에게 넘겼다고 해도 임금은 기본적으로 근로자에게 직접 지급하는 것이 원칙이다. 이유 임금은 근로자와 그 가족의 생활을 유지하는 중요한 수단이기 때문이다. 23. 전액지급 원칙 임금은 원칙적으로 전액을 지급 해야 한다. 사용자가 임의로 일부를 떼어서는 안 된다. 다만 법령이나 단체협약에 근거가 있다면 일정 금액을 공제할 수 있다. 대표적으로 세금 사회보험료 등이 있다. 원칙 월급 전액 지급 예외 법령·단체협약에 근거한 공제 23.1. 회사가 받을 돈과 월급을 마음대로 상계할 수 있을까? 원칙적으로 어렵다. 예를 들어 근로자가 회사에 손해를 끼쳤다고 해서 "너 때문에 회사가 100만 원 손해 봤으니까 이번 달 월급에서 100만 원 빼겠다." 와 같이 사용자가 마음대로 임금과 상계하는 것은 전액지급 원칙과 관련하여 제한된다. 24. 정기일지급 원칙 임금은 매월 1회 이상 일정한 날짜를 정해 지급 해야 한다. 예를 들어 매월 25일 매월 말일 등 일정한 지급일을 정함 이 필요하다. 근로자가 언제 임금을 받을지 알 수 있도록 하기 위한 것이다. 25. 비상시 임금 지급 근로자에게 긴급한 돈이 필요한 특별한 상황이 발생할 수 있다. PDF에서는 출산 질병 재해 그 밖에 정해진 비상한 경우 근로자가 비용을 마련하기 위해 요청하면 정기 임금지급일 전이라도 이미 일한 부분의 임금을 지급 하도록 하고 있다. 원래 월급날 전 + 비상한 사정 발생 + 근로자 청구 ↓ 이미 일한 부분의 임금을 미리 지급 26. 최저임금제도란? 최저임금은 국가가 "아무리 합의했다고 해도 이 금액보다 낮게 임금을 지급해서는 안 된다." 라고 임금의 최저선을 정하는 제도다. 근로자 ↔ 사용자 자유롭게 임금을 정할 수 있지만 ↓ 국가가 정한 최저선보다 낮게 정할 수 없음 27. 최저임금보다 낮게 계약하면? 근로자와 사용자가 서로 동의했다고 해도 최저임금보다 낮게 임금을 정하면 그 부분은 무효가 된다. 그리고 무효가 된 부분은 최저임금액을 지급하기로 한 것으로 본다. 앞에서 배운 강행적 효력 + 보충적 효력 이 그대로 나타나는 것이다. 28. 최저임금에 포함되는 임금 PDF에서는 최저임금 계산 시 매월 1회 이상 정기적으로 지급되는 임금을 중심으로 설명한다. 예를 들어 기본급 기술수당 면허수당 자격수당 특수작업수당 위험수당 벽지수당 유급주휴수당 일정한 근속수당 등이 있다. 또 PDF에서는 2024년부터 상여금 및 일정한 복리후생 성격의 통화지급 임금도 최저임금 산입범위에 포함되는 내용을 설명하고 있다. 29. 최저임금을 피하기 위한 형식적인 계약변경 실제 근무시간은 그대로인데 최저임금 위반을 피하려고 서류상의 소정근로시간만 줄이는 것 은 허용되지 않는다. 예를 들어, 실제로 일하는 시간 → 그대로 계약서상의 근로시간만 줄임 ↓ 시간당 임금이 높아 보이게 만듦 → 최저임금을 피하기 위한 탈법 문제 가 된다. 30. PDF에 제시된 최저임금 PDF에서는 2026년 적용 최저임금 을 다음과 같이 제시하고 있다. 구분 금액 시간급 10,320원 8시간 일급 82,560원 월 환산액 2,156,880원 이 수치는 이번 정리에서도 PDF에 적힌 내용을 그대로 사용한다. 31. 휴업수당 근로자는 일할 준비가 되어 있는데 사용자 측 사정 때문에 일을 하지 못하는 경우 가 있다. 이때 근로자의 생활을 보호하기 위해 지급하는 것이 휴업수당 이다. 근로자 → 일할 수 있음 하지만 사용자 측 사정 → 일을 못하게 됨 ↓ 휴업수당 32. 사용자의 귀책사유란? 여기서 사용자의 귀책사유는 단순히 사용자가 일부러 잘못한 경우만 의미하지 않는다. PDF에서는 사용자의 지배범위 안에서 발생한 경영상 장애도 폭넓게 포함한다고 설명한다. 예를 들어 공장이나 기계의 파손 원자재 부족 주문 감소 판매 부진 작업량 감소 원도급업체의 공사중단 전력공급 중단 등이 사용자의 귀책사유 문제가 될 수 있다. 33. 휴업수당은 얼마인가? 원칙적으로 사용자의 귀책사유로 휴업한 경우 평균임금의 70% 이상 을 지급해야 한다. 다만 평균임금의 70%가 통상임금보다 높은 경우에는 통상임금을 휴업수당으로 지급할 수 있다. 원칙 평균임금 × 70% 이상 다만 평균임금 70% > 통상임금 → 통상임금을 지급할 수 있음 34. 사업을 계속할 수 없을 정도라면? 부득이한 사유로 사업을 계속할 수 없고 노동위원회의 승인을 받은 경우 에는 법정기준보다 낮은 휴업수당을 지급할 수도 있다. 35. 도급·성과급 근로자의 임금보장 성과급이나 도급 방식으로 일하는 근로자도 실적이 없다는 이유만으로 임금이 사실상 0원이 되도록 해서는 안 된다. PDF에서는 사용자가 근로시간에 따라 일정액의 임금을 보장 하도록 설명한다. 예를 들어 사용자의 사정으로 원료가 없어 일을 못하거나 장시간 대기해야 하는 경우 근로자가 모든 위험을 부담하도록 해서는 안 된다는 취지다. 36. 퇴직금이란? 퇴직금은 사용자가 근로자에게 퇴직을 이유로 지급하는 급여 다. 이름이 퇴직금 퇴직위로금 퇴직보상금 등 무엇이든 실제 성격을 살펴본다. PDF에서는 현재의 퇴직급여제도를 근로자퇴직급여보장법 을 중심으로 설명한다. 37. 퇴직금을 받을 기본조건 사용자는 원칙적으로 계속근로기간 1년에 대해 30일분 이상의 평균임금 을 퇴직급여로 지급할 수 있도록 제도를 마련해야 한다. 계속근로 1년 ↓ 30일분 이상의 평균임금 이 기본구조다. 37.1. 퇴직급여 적용에서 제외되는 경우 PDF에서는 다음과 같은 경우 퇴직급여제도 설정의무가 없다고 설명한다. 1 계속근로기간 1년 미만 1년 미만 근로 → 원칙적으로 퇴직급여 대상 제외 2 초단시간근로자 4주를 평균하여 1주 소정근로시간이 15시간 미만 인 경우다. 주 15시간 미만 → 퇴직급여 적용 제외 38. 비정규직도 퇴직금을 받을 수 있을까? 계약의 명칭이나 고용형태가 중요한 것이 아니다. 예를 들어 일용직 임시직 촉탁직 이라고 해도 실제로 계속하여 1년 이상 근로 했다면 퇴직금 지급 문제가 발생한다. 또 비정규직으로 근무하다가 정규직으로 바뀌었더라도 근로관계가 끊기지 않고 이어졌다면 그 기간을 계속근로기간으로 볼 수 있다. 39. 징계해고되면 퇴직금을 못 받을까? PDF에서는 퇴직은 사직 해고 징계해고 등 근로관계가 종료되는 여러 경우를 포함한다고 설명한다. 따라서 징계해고됐다는 이유만으로 법정 퇴직금을 전부 지급하지 않아도 되는 것은 아니다. 40. 퇴직금 계산의 기본 퇴직금은 기본적으로 30일분 평균임금 × 계속근로연수 의 구조로 이해하면 된다. 핵심은 평균임금 + 계속근로기간 이다. 41. 계속근로기간 계속근로기간은 형식적인 계약기간만 보는 것이 아니라 실질적으로 근로관계가 계속되었는지 를 본다. 계약이 반복적으로 갱신되더라도 실제로 근로관계가 계속 이어졌다면 계속근로기간으로 인정될 수 있다. 42. 퇴직금 중간정산 원칙적으로 퇴직금은 퇴직할 때 지급한다. 하지만 법에서 정한 특별한 사유가 있고 근로자가 요구하는 경우에는 퇴직 전에 일부 퇴직금을 미리 받을 수 있다. 이를 퇴직금 중간정산 이라고 한다. 원칙 퇴직할 때 퇴직금 지급 예외 법에서 정한 사유 + 근로자 요구 ↓ 중간정산 가능 43. 중간정산이 가능한 대표적인 사유 PDF에서는 다음과 같은 사유를 설명한다. 무주택 근로자의 주택 구입 무주택 근로자의 전세금·보증금 부담 근로자·배우자·부양가족의 장기간 요양 파산선고 개인회생절차 개시결정 임금피크제 실시로 임금 감소 근로시간 단축으로 퇴직금이 감소하는 경우 천재지변 등 정해진 사유 등이다. 44. 중간정산 후 계속근로기간은? 적법하게 중간정산을 하면 그 이후 퇴직금을 계산하기 위한 계속근로기간은 중간정산 시점부터 다시 계산 한다. 입사 ↓ 5년 근무 ↓ 퇴직금 중간정산 ↓ 계속근로기간 다시 시작 ↓ 최종 퇴직금 계산 45. 월급에 퇴직금을 미리 포함하면? 사용자가 "매달 월급에 퇴직금까지 조금씩 포함해서 줄게." 라고 약정하는 것은 적법한 퇴직금 중간정산과 다르다. PDF에서는 이런 방식은 근로자가 퇴직금을 미리 포기하도록 하는 결과가 될 수 있으므로 퇴직금 지급으로서 효력이 없고 중간정산에도 해당하지 않는다 고 설명한다. 46. 퇴직연금 퇴직금 제도와 함께 퇴직연금제도 도 있다. 근로자가 퇴직한 이후 노후소득을 보다 안정적으로 보장하기 위해 만들어진 제도다. 퇴직연금은 크게 두 종류로 나뉜다. 1 확정급여형(DB) 2 확정기여형(DC) 47. 확정급여형(DB) 확정급여형은 근로자가 퇴직할 때 받을 급여 수준이 미리 정해진 방식 이다. 근로자가 받을 금액 → 미리 확정 적립금 운용 책임 → 사용자 측 부담이 큼 즉, 운용결과가 어떻게 되든 근로자에게 지급할 퇴직급여 수준을 맞춰야 한다. 48. 확정기여형(DC) 확정기여형은 반대로 사용자가 넣어야 할 부담금이 미리 정해져 있는 방식 이다. 근로자가 실제로 얼마를 받게 될지는 적립금 운용결과에 따라 달라질 수 있다. 사용자가 납부할 부담금 → 미리 확정 최종 퇴직급여 → 운용실적에 따라 달라질 수 있음 49. DB와 DC 쉽게 비교하기 구분 DB DC 무엇이 확정? 근로자가 받을 급여 사용자가 납부할 부담금 운용결과 위험 사용자 부담이 큼 근로자에게 영향을 줄 수 있음 특징 퇴직급여 수준이 비교적 명확 개인계좌를 중심으로 운용 기억법 DB = Benefit가 확정 = 받을 돈 중심 DC = Contribution이 확정 = 넣을 돈 중심 50. 개인형퇴직연금 개인형퇴직연금은 퇴직금을 한 번에 써버리는 것을 막고 노후자금으로 계속 활용할 수 있도록 하는 제도다. 직장을 옮기더라도 퇴직급여를 계속 적립해 두었다가 나중에 연금 일시금 형태로 받을 수 있도록 한다. 51. 회사가 망하면 밀린 임금은 어떻게 될까? 회사가 파산하거나 도산하면 근로자는 임금을 받기 어려워질 수 있다. 그래서 근로자의 임금채권을 다른 일반 채권보다 우선하여 보호하는 제도가 있다. 이를 임금채권 우선변제 라고 한다. 52. 최우선변제되는 임금채권 PDF에서는 특히 다음을 강하게 보호한다. 최종 3개월분의 임금 + 최종 3년간의 퇴직금 + 재해보상금 이들은 사용자의 재산에서 다른 여러 채권보다 최우선적으로 변제 받도록 하고 있다. 53. 기업 도산 시 변제순서 PDF의 흐름을 단순화하면 다음과 같다. 1 최종 3개월 임금 + 최종 3년 퇴직금 + 재해보상 ↓ 최우선 2 일정한 조세·공과금 ↓ 3 담보된 채권 ↓ 4 나머지 임금·퇴직금 채권 ↓ 5 기타 채권 즉, 근로자의 최소한의 생계를 위해 최근의 임금과 퇴직금을 특히 강하게 보호하는 것이다. 54. 임금채권보장제도 우선변제권이 있다고 해도 회사에 실제 재산이 없거나 복잡한 경매절차를 거쳐야 한다면 근로자가 임금을 받기 어려울 수 있다. 그래서 임금채권보장법 이 만들어졌다. 회사 파산 ↓ 임금·퇴직금 지급 불가능 ↓ 근로자가 청구 ↓ 국가의 제도를 통해 일정 금액 지급 이라는 구조다. 55. 체당금 PDF에서는 사용자가 파산 등으로 임금이나 퇴직금을 지급하지 못하면 일정한 경우 국가가 사업주를 대신하여 지급하는 제도를 설명한다. 이를 체당금 이라고 한다. 지급범위는 기본적으로 최종 3개월분 임금 최종 3년간 퇴직금 등을 중심으로 한다. 다만 모든 미지급액을 무제한으로 지급하는 것은 아니고 정해진 범위와 상한이 존재한다. 56. 임금채권의 소멸시효 임금을 받지 못했는데 아무런 권리행사를 하지 않고 오랜 시간이 지나면 더 이상 청구하지 못하게 될 수 있다. 이를 소멸시효 라고 한다.
1. 선택 정렬 저번주차에서 했던 내용에서 이어서 설명하자면 선택 정렬은 정렬되지 않은 부분에서 가장 작은 값을 찾아 맨 앞으로 가져오는 방식 이다. 예시 코드를 들어보자. def selection_sort(data): n = len(data) for i in range(n - 1): min_index = i for j in range(i + 1, n): if data[j] < data[min_index]: min_index = j data[i], data[min_index] = data[min_index], data[i] return data 라는 코드가 있다. 이 코드는 최솟값을 찾아서 현재 위치와 교환한다. 즉, 일단 현재 숫자를 가장 작은 숫자라 가정하고 더 작은 숫자를 발견하면 그 위치를 기억한다. 그리고 끝까지 찾아본 후 교환하면서 정렬을 실행한다. 이 정렬을 시각적으로 표현하면 이렇게 된다. 2. 삽입 정렬 삽입 정렬은 선택 정렬과 생각하는 방식이 다르다. 삽입 정렬은 삽입 정렬은 이미 정렬된 영역과 아직 정렬되지 않은 영역으로 나뉜다. 두 번째 요소부터 시작하여 자신의 왼쪽 요소와 한 칸씩 비교하며 왼쪽으로 이동한다. 자신보다 큰 요소들은 오른쪽으로 이동시키고, 자신보다 작거나 같은 요소를 만나면 그 바로 뒤에 삽입한다. 이 과정을 반복하면서 정렬된 영역을 확장한다. 삽입정렬은 key 를 활용하냐 안하냐에 따라 두가지 방식으로 나뉘는데, key를 사용하거나, 사용하지 않는 swap 방식이 있다. Key 활용 예시 코드를 들어보자. def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j + 1] = arr[j] j -= 1 arr[j + 1] = key return arr 여기에서 key = arr[i] 가 끼워 넣을 숫자이다. 그리고 j= i-1 로 바로 왼쪽부터 검사한다. while j >= 0 and arr[j] > key: 을 통해 만약 key 보다 큰 숫자가 있다면 arr[j + 1] = arr[j] 을 통해 오른쪽으로 보내고 그 자리에 arr[j + 1] = key 을 통해 key 를 삽입한다. key 를 통한 삽입 정렬을 이해하기 쉽게 시각화하면 이렇게 된다. SWAP Swap 방식은 key 를 사용하지 않고 삽입 정렬을 실행한다. 예시 코드를 들면 array = [6, 3, 5, 2, 4] for i in range(1, len(array)): for j in range(i, 0, -1): if array[j] < array[j - 1]: array[j], array[j - 1] = array[j - 1], array[j] else: break print(array) 라는 코드가 있다. 우선 첫 번째 요소 6은 혼자이므로 이미 정렬되었다고 간주한다. 먼저 두 번째 요소인 3부터 시작하여 왼쪽에 있는 6과 비교한다. 이때 6이 3보다 더 크므로 swap 한다 [6, 3, 5, 2, 4] ↕ [3, 6 | 5, 2, 4] 이러한 상황이 완성되게 된다. 이제 다음으로 세 번째 요소인 5를 바로 왼쪽의 6과 비교한다. 이때 6이 더 크므로 swap 한다. 여기서 끝이 아니라 한 칸 이동한 후 바로 왼쪽의 3과 또 값을 비교한다. 이때는 5가 3보다 더 크니까 swap 할 필요가 없어진다. [3, 5, 6 | 2, 4] 이러한 방식을 2와 4에 계속해서 적용하면 결국 [2, 3, 4, 5, 6] 이 나오게 된다. 이 과정또한 시각적으로 표현하면 이러한 모습이 된다. 3. K번째 수 문제 및 제한사항 입출력 예 선택 정렬 def solution(array, commands): answer = [] for command in commands: i = command[0] j = command[1] k = command[2] new_array = array[i-1:j] for a in range(len(new_array) - 1): min_index = a for b in range(a + 1, len(new_array)): if new_array[b] < new_array[min_index]: min_index = b new_array[a], new_array[min_index] = new_array[min_index], new_array[a] answer.append(new_array[k-1]) return answer 삽입 정렬 ```python
오늘 근무하면서 혼났다. 여기서 생존에 유리한 진화 경험을 한거 같아 적어본다. 오늘 왜 혼났냐면 신입사원에게 내가 뭘 잘못 가르쳤기 때문이다. 이 때문에 따로 불려가서 1대1로 혼났다. 내용은 다음과 같다. "너가 알고있는건 잘못되었고 이게 맞는거다. 잘못된걸 가르치다. 그 신입사원이 다른 신입에게 잘못된걸 가르칠 수 있기에 다음부턴 이렇게 가르쳐라." 대충 이런 말을 내게 했다. 지금까지 그 사람에게 혼난걸 생각하면 혼난 것도 아니였다. 오히려 다음부터는 잘 할거라는 믿음(?)이 있었기에 쉬쉬하며 넘어가 주었다. 마무리 내가 잘못했고, 적당히 맞는 말만 해주셨고, 적당히 넘어가주었다. 그런데 왜 나는 1대1로 대화할때 울컥하고 눈물이 나려고 했던걸까. 이는 악어의 눈물이 아니였을까? 위기 상황을 눈물로 동정심을 유발하고 빠져나갈려는 인류 진화의 산물이 아니였을까 싶다.
모델을 바꾸거나 추론을 여러 보드에 나누거나 개발 환경을 분리할 때, 먼저 결정할 질문은 같다. 지금 바꾸려는 대상에 맞춰 무엇을 검증할 것인가? 토큰 사용량, 장치의 메모리, 노드 간 전송, 호스트와의 연결은 각각 다른 근거를 요구한다. Google DeepMind가 2026년 7월 21일 발표로 표시한 Gemini 3.6 Flash·3.5 Flash-Lite·3.5 Flash Cyber 소개 , ESP32S3 추론 클러스터, Linux 개발 환경 도구 NSL을 이 질문에 맞춰 읽어 보자. 모델 제품군의 목표, 소형 보드의 실행 구성, 개발 환경의 설계를 같은 성능 순위에 놓을 수는 없다. 모델 교체를 검토한다면 업무 결과와 대기 시간을 함께 본다 Google은 운영 환경에서 AI 에이전트를 개발하는 고객과 개발자의 요구로 토큰 효율 개선, 지연 시간 단축, 안정적인 성능을 제시한다. 소개된 발표 내용에는 모델별 가격, 벤치마크 결과, 지연 시간 측정값이 나오지 않는다. 따라서 Flash-Lite라는 이름으로 비용 절감 폭을 계산하거나 Flash Cyber라는 이름에서 구체적인 보안 기능을 추정할 근거는 부족하다. 모델 교체를 검토하는 경우, 이 글의 제안은 자체 업무의 결과 적합성에 응답 시간과 재시도 발생 여부를 붙여 평가하는 것이다. 결과가 업무에 맞아야 교체할 이유가 생기고, 응답 시간과 재시도 기록이 있어야 발표에서 강조한 대기 시간과 안정성을 서비스 요구에 대조할 수 있기 때문이다. 토큰 효율이라는 목표 역시 가격 정보와 업무별 사용량 없이 곧바로 비용 절감액으로 옮기지 않는다. ESP32S3에서는 연산 경로와 데이터 형식을 구분한다 GeekNews의 ESP32S3 기반 1.58비트 BitNet 언어 모델 클러스터 소개 에는 0.5B 모델을 마스터 보드 1대와 연산 노드 6대에 분할한 구성이 나온다. 마스터는 토큰화와 임베딩을 맡고, 연산 노드는 각각 트랜스포머 블록 4개를 실행한다. 전체 24개 블록의 처리는 순차적으로 진행된다. 다음은 소개된 구성에서 다음 토큰을 선택하기까지의 처리 순서다. 마스터: 토큰화·임베딩 → 연산 노드 6대: 노드마다 트랜스포머 블록 4개를 순차 실행 → 마스터: 최종 RMSNorm·LM Head → 탐욕적 샘플링으로 다음 토큰 선택 노드 사이의 은닉 상태는 고속 SPI 데이지 체인을 통해 이동한다. 이때 모델 이름에 붙은 ‘1.58비트’를 저장과 전송 전반의 형식으로 받아들이면 실제 메모리 구성을 놓친다. 적용 대상 소개된 형식 또는 저장 위치 어텐션과 MLP의 투영 연산 1.58비트 연산 임베딩 INT4 마스터가 첫 연산 노드로 보내는 은닉 상태 FP32 KV 캐시 PSRAM 임베딩은 플래시에서 약 14MB를 사용하며, LM Head와 가중치를 공유한다. 이 구성을 제한된 메모리의 추론 후보로 검토한다면, 실행 시간의 검토 항목에 노드별 계산 시간, 은닉 상태 전송 시간, KV 캐시 접근 시간을 넣는 것이 이 글의 제안이다. 블록을 순서대로 실행하는 동안 계산뿐 아니라 전달과 메모리 접근도 일어나기 때문이다. 소개된 내용에는 초당 생성 토큰 수와 소비 전력 측정값이 없으므로, 속도나 경제성을 선택 기준으로 삼으려면 해당 측정이 추가로 필요하다. 보드에 올리기 전의 모델 준비도 검토 대상이다 이 프로젝트는 ESP-IDF 펌웨어와 함께 PC에서 사용하는 전처리 도구도 제공한다고 소개되어 있다. 준비 작업에는 어휘를 32K 토큰으로 축소하는 도구, BitNet 양자화 인지 학습 미세 조정, INT4 임베딩 가중치 패킹, 토크나이저 규칙의 바이너리 직렬화가 포함된다. 가중치의 형식과 물리적 정렬을 맞추는 작업도 여기에 속한다. 펌웨어 쪽에는 어셈블리로 최적화한 연산, 조회 테이블 활용, SPI DMA 송수신 구현이 등장한다. 소형 보드에서의 실행을 검토할 때는 펌웨어와 함께 모델 변환 및 배치 작업도 개발 범위에 넣어야 한다. 장치에서 실행되는 코드 외에 준비할 도구와 데이터 형식이 있기 때문이다. 어휘 축소와 양자화 이후의 생성 품질은 소개된 내용만으로 판단하기 어렵다. 이 구성을 실제 업무에 적용하려는 경우에는 변환된 모델의 결과 적합성을 검토 항목에 포함할 만하다. 보드에 배치하는 데 필요한 준비와 업무에 사용할 결과를 얻는 조건을 함께 평가하기 위해서다. NSL에서는 필요한 호스트 연결을 먼저 정한다 GeekNews의 NSL Linux 개발 환경 소개 에 따르면, NSL은 공유 VM 내부의 systemd-nspawn 컨테이너에서 각 Linux 머신을 실행한다. 설치한 패키지와 서비스, 파일은 세션 종료 후에도 남는다. 개발 도구를 호스트와 분리해 설치하면서 작업 공간을 이어 쓰는 방식이다. 일반 환경은 호스트와의 연결을 제공한다. 프로젝트 디렉터리에서 시작하면 같은 파일을 사용하고, 사용자 이름과 UID·GID를 호스트에 맞춰 파일 소유권을 유지한다. 개발 서버는 포워딩된 포트로 접근하며, Wayland 앱의 창은 Waypipe를 통해 호스트 데스크톱에 표시한다. 신뢰하지 않는 소프트웨어를 대상으로 하는 --isolated 모드는 전용 VM에서 실행하며, 설명상 호스트 파일·데스크톱·호스트 동작에 대한 접근을 차단한다. 구성 VM 사용 방식 호스트 연결 일반 환경 공유 VM 안의 컨테이너 프로젝트 파일 공유와 데스크톱 연동 제공 --isolated 모드 전용 VM 호스트 파일·데스크톱·호스트 동작 접근 차단 NSL을 검토할 때 이 글의 제안은 작업에 필요한 호스트 연결부터 적는 것이다. 같은 프로젝트 파일을 편집하거나 호스트에 앱 창을 띄워야 하는 작업이라면 그 연결이 개발 편의의 일부다. 신뢰하지 않는 소프트웨어를 실행하려는 경우에는 --isolated 가 설명하는 접근 차단 범위를 기준으로 검토한다. 소개된 v0.4.0은 현재 설계의 첫 릴리스이며, 당시에는 안정 버전이 없는 상태다. NSL 자체는 호스트에 패키지를 설치하지 않지만 필수 구성 요소는 미리 갖춰야 한다. 도입 작업을 잡을 때는 이 사전 준비와 개발 환경 내부의 도구 설치를 구별해 범위에 반영한다. 다음 검증을 고르는 기준 이 글의 제안은 ‘효율적’이라는 표현보다, 바꾸려는 대상에서 아직 답하지 못한 검증 항목을 우선하는 것이다. 그 답이 도입 결정을 바꿀 때 다음 실험이나 환경 구성을 진행할 이유가 생긴다. 원문: webi 기술 블로그 참고한 자료: Introducing Gemini 3.6 Flash, 3.5 Flash-Lite, and 3.5 Flash Cyber 1.58비트(BitNet) 언어 모델을 실행하는 ESP32S3 클러스터 Show HN: NSL - Linux용 WSL
서론(넘겨도 됨) it 분야를 포기하고 반도체로 노선을 바꾸고 다행히도 취업에 성공했다. 반도체 공장이다 보니 3교대 근무로 인해 심신의 여유가 없어 기숙사>회사>기숙사>회사>기숙사>회사 이런 생활을 하다 슬슬 익숙해지고 퇴사하고 다른 것도 할 여유가 생겨 지금까지 회사 다니면서 깨달은 삶의 지해를 공유하기 위해 글을 적어본다. 내가 깨달은 것을 알기 위해선 일단 내가 뭘 하는지를 알아야한다. 대충 내가 하는 일을 요약하면 1)전 공정에서 넘어온 자재를 준비 2)내 공정의 장비에 넣기 3)장비에서 나온 자재 정리해서 다음 공정으로 넘기기 이외)장비에서 뜬 오류 고치기, 장비에서 사용하는 부 자재 준비, 위에걸 장비를 2개를 돌리면서 약 6시간 동안 서서 하면 된다. 일어서서 근무하는게 아프긴 했지만 익숙해졌고, 처음 혼자할때는 바쁘긴 해도 장비를 멈추거나 하지 않아서 아웃풋은 잘 나왔고 또 식사시간(1시간) 휴식시간(30분)을 쉴 수 있기에 할만했다. 여기가까지는 좋았다. 문제는 다음이다. 식사 교대라는 벽을 느끼기 전까지 본론 식사교대는 옆 사람이 밥먹고 올때까지 그 사람의 장비를 내가 돌리는 것이다. 쉽게 말해 장비 2개 돌리다가 옆사람이 밥먹으러 가면 장비 4대를 내가 혼자 돌려야 한다. 할 일이 2배로 느는 것이다. 이 떄 옆사람 욕을 진짜 많이 했다. 준비하고 갈 수 있는데도 안해주고 가고, 오류 꺼주고 갈 수 있는데도 안꺼주고, 자재 넘기고 갈 수 있는데도 안 넘겨주고 내 장비 하기도 바빠서 못해주면 왜 안해주냐고 꼽주고 시발련 그 때도 식사교대때 옆사람 원망하면서 돌리고 있는데 오류가 진짜 많이 떴다. 자재 준비하고 있으면 오류뜨고, 오류 끄고 다른거 하러가면 또 똑같은 오류 뜨고, 동시에 3 장비에서 오류뜨고, 정리 안하고 간거 정리할때 오류 뜨고...(그때 생각하면 아직도 아찔하다.) 그렇게 멘탈 나가서 속으로 욕하면서 오류 끄고 있을때 순간 머리가 깨끗해졌다. 다른 사람이 된 듯 속에 있던 분노가 지워지고 '왜 화내고 있지? 그냥 하면 되잖아'라며 스스로에게 되뇌였고. 속으로 욕하는 날 보고 결국에는 나만 욕먹는 다는 사실에 한심해 했다.(왜 이런 현상이 일어났는지는 지금도 모르겠음) 그 뒤로 씩씩하게 하기로 했다. 어차피 해야할거 욕하고 불만만 해봤자 결국 나한테만 들리는 거고, 아무도 보지 않는다 생각해도 결국 나 스스로가 지켜보고 있었고, 씩씩하게 했기때문에 누가 뭐라해도 전혀 분하지 않았다. 이때 "피할 수 없다면 즐겨라"라는 말의 참 뜻을 몸으로 실감했다. 마무리 흔히들 많이쓰는 말인 "피할 수 없으면 즐겨라" 솔직히 이거 말 안된다 생각한다. 말이 된다 하더라도 이걸 할 수있는 사람은 진짜 극 소수의 마인드를 가진 사람이라 단정 지을 수 있다. 그럼 우리 같은 범인들은 우째해야 할까 바로 씩씩한 태도를 가지는게 포인트다. 세상살이 불만불평한다고 변하지 않는다. 변하는건 세상을 바라보는 우리의 시선이다. 스스로에게 부끄럼 없는 씩씩한 인생을 산다면 자연스럽게 즐길 수 있다 생각한다.
고객에게 맞는 답을 하려면 정보를 많이 모으기만 하면 될까요? 가입 상품과 이용 상황은 더 적절한 답에 도움이 됩니다. 개인화 서비스에는 필요한 정보를 골라 쓰고, 실제 업무를 처리하며, 허용된 범위에서 멈추는 구조가 함께 필요합니다. 고객이 로밍 요금을 물을 때 필요한 것은 자신의 가입 상품과 이용 상황에 맞는 안내입니다. 고객 정보를 얼마나 확보했는지만으로는 개인화 서비스의 설계를 설명하기 어렵습니다. 매출 22% 증가와 이탈 9% 감소를 읽는 법 성과를 비교하려면 언제, 어떤 고객을 대상으로 측정했는지 알아야 합니다. OpenAI가 공개한 고객 사례에는 이 조건들과 다른 사업 변화의 영향이 제시되지 않아, 개인화 기술의 기여를 따로 구분하기 어렵습니다. 가입자당 평균 매출을 뜻하는 ARPU는 고객 한 명당 매출을 보는 지표입니다. OpenAI는 Circles의 싱가포르 사례에서 이 값이 22% 늘었다고 소개합니다. AI 추천을 도입한 뒤 이탈이 9% 줄었다는 수치도 보고합니다. 이탈 감소의 단위는 9%로 제시됐으며, 이를 9%포인트로 바꿔 읽을 근거는 없습니다. 고객 지원을 맡는 CareX에는 자율 해결률 65%라는 수치가 제시됩니다. 다만 세 수치 모두 기술 공급사가 소개한 고객 사례의 보고값입니다. 다른 통신사가 같은 모델을 사용할 때 얻을 성과로 그대로 옮겨 잡기는 어렵습니다. 요금 조회와 상품 변경은 실패의 의미가 다릅니다 전문 에이전트가 요청을 넘겨받은 뒤에는 무엇을 구분해야 할까요? AI Concierge는 검색·계정 관리·지원·추천을 묶고 요청을 전문 에이전트로 전달합니다. 조회 지연은 재요청할 수 있지만 변경의 중복 실행은 고객 상태를 잘못 바꿀 수 있습니다. 중복 방지·결과 확인·상담원 인계 맥락은 설계 과제이며, 공개된 설명만으로 CareX의 구체적인 거래 처리 구조를 확인하기는 어렵습니다. 상품 변경 기능을 붙일 때는 요청을 전달한 뒤 고객 상태가 어떻게 바뀌었는지까지 살펴야 합니다. 따라서 실제 처리 기능에는 중복 실행을 막는 장치와 결과 확인이 필요합니다. 실패할 때 상담원에게 어떤 맥락을 넘길지도 함께 설계할 과제입니다. Circles에서는 AI Concierge가 요청을 전문 에이전트에 전달하고 CareX가 이를 뒷받침하지만, 공개된 설명에는 에이전트 간 통신과 구체적인 거래 처리 구조가 드러나지 않습니다. 기술 부채와 기술 중력을 구분하는 이유 오래된 청구 시스템과 출시를 서두르며 생략한 검증을 같은 문제로 봐도 될까요? ITWorld 글이 제안한 관점에서는 승인받은 지름길은 기술 부채, 승인 없는 지름길은 섀도 기술 부채, 당시 합리적이었으나 현대화가 필요해진 시스템은 기술 중력입니다. 오래된 청구 시스템의 의존성을 옮기는 일과 생략한 권한 검사·결과 검증을 복구하는 일에는 서로 다른 작업 계획이 필요합니다. 청구 시스템의 나이만 살펴서는 무엇을 고쳐야 하는지 정하기 어렵습니다. 당시에는 합리적이었던 시스템을 현대화하는 작업과, 출시를 서두르며 빠뜨린 권한 검사나 결과 검증을 복구하는 작업은 다릅니다. ITWorld 글은 이 차이를 설명하기 위해 선택 당시의 사정과 승인 여부를 구분합니다. 일정과 비용 때문에 승인받은 지름길에는 기술 부채라는 이름을 붙입니다. 승인 없는 지름길은 섀도 기술 부채로, 시간이 지나 현대화가 필요해진 시스템은 기술 중력으로 구분합니다. 이 관점에서 보면 기존 시스템의 의존성을 옮기는 계획과 새로 생략한 검증을 되살리는 계획을 따로 세워야 합니다. 정보 출처 설명과 실제 접근 기록은 별개입니다 데이터 출처를 확인할 때 필요한 것은 실제로 정보를 읽은 과정의 기록입니다. GeekNews의 요약에 따르면 Muse가 설명한 출처와 이후 확인됐다는 동기화 내역 사이에 차이가 있었습니다. 이 논쟁에서 살펴볼 설계 문제는 모델의 출처 설명을 어떻게 검증하느냐입니다. 어떤 연결 도구가 데이터를 읽었는지, 그때 어떤 권한을 사용했는지 기록해야 설명과 접근 내역을 대조할 수 있습니다. GeekNews는 Jason Aten의 사례를 인용해 허가하지 않은 Apple Messages 기록이 동기화됐다는 주장을 전합니다. 같은 페이지에는 이전에 부여한 권한과 다른 기기의 설정을 살펴야 한다는 반론도 있습니다. 주장과 반론이 함께 제시된 상태여서, 이 논쟁만으로 권한 우회가 있었는지와 그 원인을 확정하기는 어렵습니다. 통신 서비스에 적용할 설계 원칙으로는 요청에 필요한 데이터 범위를 먼저 정하는 방법이 있습니다. 사용량, 청구, 위치 정보에 접근할 수 있어도 로밍 문의에 모두 쓸 이유는 없습니다. 조회 권한과 변경 권한을 나누고, 도구가 실행되는 지점에서 허가받지 않은 데이터 접근을 막는 방식도 검토 대상입니다. 개발 효율 29% 향상과 고객 문제 해결을 따로 측정합니다 자율 해결률을 비교하려면 먼저 무엇을 해결로 셌는지 정해야 합니다. 답변을 생성한 요청을 세는 방식과 고객의 문제가 끝난 요청을 세는 방식은 측정 대상이 다릅니다. 같은 이름의 지표라도 이 기준이 달라지면 수치를 바로 비교하기 어렵습니다. 따라서 고객 지원의 성과를 읽을 때는 해결이라는 말이 가리키는 상태부터 정의해야 합니다. OpenAI는 Circles가 Codex를 설계, 코딩 보조, 단위 테스트에 활용해 개발 효율을 29% 높였다고 보고합니다. 그러나 계산 방식은 제시하지 않았습니다. 코드 작성에 걸린 시간을 줄였다는 뜻인지, 전체 개발 주기가 짧아졌다는 뜻인지 구분하기 어려워 팀의 생산성 목표로 바로 삼기는 어렵습니다. 개발 효율은 개발 활동을, 자율 해결률은 고객 지원 활동을 측정합니다. 고객에게 도입 효과가 있었는지 판단하기 위한 관찰 항목으로는 문제 해결 여부, 처리 지연, 재문의, 권한 밖 접근의 차단 여부를 제안합니다. 완료 조건은 고객의 일이 제대로 끝나는 것입니다 앞서 살펴본 조회와 변경은 실패했을 때의 영향이 달랐습니다. 기존 시스템을 현대화하는 일과 출시 과정에서 생략한 검증을 복구하는 일도 작업 계획을 달리해야 했습니다. 이런 차이를 구분해야 실제 처리 기능에 필요한 작업을 구체적으로 정할 수 있습니다. 데이터 접근은 연결 도구와 권한의 기록으로 살펴야 합니다. 성과 수치에는 무엇을 측정했는지에 대한 정의가 필요합니다. 특히 개발 효율과 고객 지원의 해결률은 각각의 활동을 기준으로 해석해야 합니다. 다음에 해 볼 것 — 적용을 시작할 때는 고객 요청 하나를 골라 처리 경로를 끝까지 정리합니다. 읽을 데이터, 실행할 변경, 실패 시 인계 대상을 연결하면 필요한 시스템 통합 작업을 구체화할 수 있습니다. 원문: webi 기술 블로그 참고한 자료: Circles powers telco personalization with OpenAI technology “모든 낡은 시스템이 부채는 아니다” 기술 부채라는 이름의 함정 놀랍지도 않게, Meta의 새 Muse AI 에이전트가 사용자 권한 설정을 노골적으로 무시함