DEV BOX

작게 만들고, 깊게 이해합니다.

시간대, 데이터, 복원. 개인 앱을 만들며 알아두면 좋은 개발의 기본.

THE LIBRARY

주제별 기록32

32개 글 중 12개 표시
DEV BOXAI agents / Contest retrospective

마감이 있는 AI 에이전트 대회, 무엇을 먼저 준비해야 할까: AI TOP 100 예선 후기

10월 31일 카카오 AI TOP 100 예선에서 다섯 시간 안에 AI 에이전트를 만들어 마감 직전에 제출했다. 문제 내용은 빼고, AI 둘과 나눈 역할과 잘 된 것, 마지막 배포 뒤에 온 자료와 크레딧, 실제 채널 시험에서 배운 것, 다음에 바꿀 아홉 가지를 적었다.

AI agentsAI TOP 100Claude Code
7분 읽기 · KO / EN
DEV BOXWeb / URL

검색어 C++를 보냈는데, 서버에는 왜 'C '로 도착할까

검색창에 C++를 넣었는데 서버에서 꺼낸 검색어는 C 뒤에 공백 두 칸이었습니다. 쿼리 문자열의 +는 폼 형식으로 읽는 함수에게만 공백이고, encodeURIComponent·decodeURIComponent 같은 퍼센트 인코딩 함수에게는 그냥 +이기 때문입니다. Node.js v24.21.0과 Python 3.9.6에서 실제로 실행한 결과로, 쓰는 함수와 읽는 함수를 어떻게 짝지어야 +와 공백이 그대로 돌아오는지 확인합니다.

URL encodingURLSearchParamsencodeURIComponent
9분 읽기 · KO / EN
DEV BOXNode.js / TypeScript

node로 .ts 파일을 바로 돌리면, 타입 검사는 누가 해 줄까

Node.js 24는 node app.ts로 TypeScript 파일을 바로 실행하지만, 타입을 공백으로 지울 뿐 맞는지는 검사하지 않습니다. Node.js v24.21.0에서 타입이 틀린 코드가 1000100을 내고 종료 코드 0으로 끝나는 것, enum과 type 없이 가져온 interface가 SyntaxError를 내는 것, tsconfig.json의 paths 별칭이 적용되지 않는 것을 실제로 실행해 확인하고, 타입 검사를 tsc에 따로 맡기는 설정을 살펴봅니다.

TypeScriptNode.jstype stripping
10분 읽기 · KO / EN
DEV BOXJavaScript / RegExp

같은 문자열인데 정규식 test()가 한 번은 true, 한 번은 false라면 어디를 볼까

g 플래그가 붙은 정규식 객체는 지난번 검색이 끝난 위치를 lastIndex에 기억합니다. Node.js v24.21.0에서 같은 문자열의 test()가 번갈아 true와 false를 내고 filter()가 행을 빠뜨리는 것을 실행해 보고, 메서드마다 lastIndex를 어떻게 다루는지와 목적별 고치는 방법을 정리합니다.

JavaScriptRegExplastIndex
7분 읽기 · KO / EN
DEV BOXWeb / HTTP caching

Cache-Control: no-cache라고 보냈는데 브라우저는 왜 응답을 저장할까

no-cache는 저장을 막지 않고, 서버에 확인 없이 다시 쓰는 일을 막습니다. Chromium 152에서 no-cache, no-store, max-age를 같은 순서로 실행해 서버 로그와 캐시만 읽는 요청으로 차이를 보고, 무엇을 고를지와 fetch의 cache 옵션까지 정리합니다.

HTTPCache-Controlno-cache
9분 읽기 · KO / EN
DEV BOXSQLite

SQLite에 FOREIGN KEY를 걸었는데, 없는 고객의 주문이 왜 들어갈까

SQLite의 외래 키 검사는 기본으로 꺼져 있고 연결마다 켜야 합니다. sqlite3 3.54.0, Python 3.12.14, Node.js v24.21.0에서 없는 고객의 주문이 들어가는 경우와 거부되는 경우를 실행해 비교하고, 트랜잭션과 오타 때문에 오류 없이 켜지지 않는 경우, 이미 들어간 행을 찾는 PRAGMA foreign_key_check를 살펴봅니다.

SQLiteFOREIGN KEYPRAGMA foreign_keys
8분 읽기 · KO / EN
DEV BOXWeb / Cookies

localhost의 포트가 다르면 쿠키도 따로 저장될까

localhost:4371과 localhost:4372에 쿠키 이름이 같은 앱 두 개를 띄우면 한쪽 로그인이 다른 쪽 쿠키를 덮어쓰고, 한쪽에서 로그아웃하면 다른 쪽도 풀립니다. 쿠키는 호스트 이름 단위로 저장되고 포트를 보지 않기 때문입니다. Node.js 서버 두 개를 Chromium 152 기반 브라우저로 열어 남긴 서버 로그로 이를 확인하고, SameSite=Strict와 __Host-로도 나뉘지 않는 이유, 쿠키 이름과 호스트 이름 가운데 무엇으로 나눌지를 정리합니다.

CookieslocalhostSet-Cookie
9분 읽기 · KO / EN
DEV BOXWeb / Next.js

환경변수를 바꾸고 다시 시작했는데, Next.js 화면에는 왜 예전 주소가 나올까

NEXT_PUBLIC_API_BASE를 바꾸고 next start를 다시 했는데 화면은 예전 API 주소를 부릅니다. Next.js 16.4.3에서 A 값으로 빌드하고 B 값으로 시작해 보니, NEXT_PUBLIC_ 변수와 미리 만든 페이지는 빌드 때 값에 머물고 NEXT_PUBLIC_가 없는 서버 변수만 요청 때 값을 읽었습니다. 어떤 값이 빌드 때 굳는지 가려내는 법과 고치는 세 가지 길을 실제 실행 결과로 정리합니다.

Next.jsenvironment variablesNEXT_PUBLIC_
10분 읽기 · KO / EN
DEV BOXGit / CLI

파일 이름의 대소문자만 바꾸면 git은 어느 이름을 기억할까

Mac에서 button.js를 Button.js로 바꾸면 git status는 조용하고 커밋할 것도 없다고 합니다. 대소문자를 가리지 않는 APFS에서 git은 core.ignoreCase에 따라 인덱스에 적힌 옛 이름을 계속 쓰기 때문입니다. git 2.54.0에서 실제로 실행한 결과로, 어느 이름이 남아 있는지 확인하고 git mv로 커밋에 넣는 방법을 봅니다. core.ignorecase를 false로 바꾸면 git mv는 멈추고, mv 뒤에 add한 커밋에는 이름이 둘 생깁니다.

gitgit mvcore.ignoreCase
11분 읽기 · KO / EN
DEV BOXWeb / JavaScript

복사한 객체를 고쳤는데 원본은 왜 같이 바뀔까

{ ...user }로 만든 복사본의 주소를 고쳤더니 원본 주소까지 바뀌었습니다. 스프레드와 Object.assign은 바깥 객체만 새로 만들고 안쪽 객체와 배열은 원본과 함께 쓰기 때문입니다. Node.js v24.21.0에서 실제로 실행한 결과로, 바꾸는 경로만 새로 만드는 방법과 structuredClone·JSON 왕복이 각각 무엇을 남기고 잃는지 확인합니다.

JavaScriptspread syntaxshallow copy
8분 읽기 · KO / EN
DEV BOXShell / Bash

set -e를 넣었는데 실패한 명령 뒤에도 스크립트는 왜 계속 돌까

set -e는 모든 실패에서 멈추지 않습니다. 파이프라인의 앞쪽 명령, if·&&·||에서 검사로 쓰인 명령과 그 안에서 부른 함수, local v=$(…)처럼 선언과 명령 치환을 한 줄에 쓴 곳에서는 실패 뒤에도 실행이 이어집니다. macOS의 Bash 3.2.57로 실제 실행한 결과와 GNU Bash 매뉴얼로 원인을 확인하고, pipefail·|| return·선언 분리로 고치는 방법을 정리합니다.

Bashset -epipefail
7분 읽기 · KO / EN
DEV BOXPython

Python round(2.5)는 왜 3이 아니라 2일까

Python의 round()는 정확히 가운데인 값을 짝수 쪽으로 보내서 round(2.5)가 2입니다. round(2.675, 2)가 2.67인 것은 또 다른 이유, 2진 float 저장값 때문입니다. Python 3.12.14 실행 결과로 두 원인을 나눠 보고, 금액은 문자열로 만든 Decimal에 ROUND_HALF_UP을 명시하는 방법과 JavaScript Math.round()와의 차이를 정리합니다.

Pythonround()banker's rounding
8분 읽기 · KO / EN
12 / 32개
ALL NOTES

전체 목록31

이 상자에 담긴 글을 제목만 모아 연도별로 놓았습니다.

202629편

  1. 마감이 있는 AI 에이전트 대회, 무엇을 먼저 준비해야 할까: AI TOP 100 예선 후기AI agents / Contest retrospective
  2. 검색어 C++를 보냈는데, 서버에는 왜 'C '로 도착할까Web / URL
  3. node로 .ts 파일을 바로 돌리면, 타입 검사는 누가 해 줄까Node.js / TypeScript
  4. 같은 문자열인데 정규식 test()가 한 번은 true, 한 번은 false라면 어디를 볼까JavaScript / RegExp
  5. Cache-Control: no-cache라고 보냈는데 브라우저는 왜 응답을 저장할까Web / HTTP caching
  6. SQLite에 FOREIGN KEY를 걸었는데, 없는 고객의 주문이 왜 들어갈까SQLite
  7. localhost의 포트가 다르면 쿠키도 따로 저장될까Web / Cookies
  8. 환경변수를 바꾸고 다시 시작했는데, Next.js 화면에는 왜 예전 주소가 나올까Web / Next.js
  9. 파일 이름의 대소문자만 바꾸면 git은 어느 이름을 기억할까Git / CLI
  10. 복사한 객체를 고쳤는데 원본은 왜 같이 바뀔까Web / JavaScript
  11. set -e를 넣었는데 실패한 명령 뒤에도 스크립트는 왜 계속 돌까Shell / Bash
  12. Python round(2.5)는 왜 3이 아니라 2일까Python
  13. Promise.all이 실패했는데 나머지 요청은 왜 계속 돌까Web / JavaScript
  14. API에서 받은 주문 번호의 끝자리가 왜 바뀔까Web / JavaScript
  15. package.json의 ^0.2.3은 왜 0.3.0으로 올라가지 않을까Tools / npm
  16. Python 함수를 다시 불렀는데 왜 지난번 값이 남아 있을까Python
  17. forEach 안의 await는 왜 반복문을 멈추지 못할까JavaScript
  18. 숫자 배열을 sort()했는데 왜 10이 9보다 앞에 올까JavaScript
  19. gitignore에 적었는데 왜 계속 커밋될까Git
  20. 보낸 JSON에서 필드가 왜 사라졌을까JavaScript
  21. fetch는 404를 받았는데 왜 catch로 가지 않을까Web
  22. Meta Muse, 한국에서 바로 써보기AI Agents
  23. SQLite 백업, 파일이 생겼다면 이제 복원해 볼 차례SQLite
  24. 개인 앱의 날짜가 하루 밀릴 때: 저장 시간과 표시 시간 구분하기JavaScript
  25. 브라우저가 JSON 요청을 막았는데 서버에는 왜 안 보일까Web
  26. POST로 보냈는데 다음 주소는 왜 GET일까Web
  27. AI에게 일을 맡겼는데 왜 계속 헛돌까: 하네스·루프·그래프 쉽게 이해하기AI Agents
  28. 개인 앱의 오류 메시지: 사용자가 다음 행동을 알게 만들기Apps
  29. 바이브 코딩이 막히는 건 모델이 아니라 지도다AI