‘개발’ 태그의 글
85편 RSS로 구독
85편
PostgreSQL 트랜잭션 ID 랩어라운드: VACUUM이 행을 동결하는 이유와 age(datfrozenxid) 읽는 법
PostgreSQL의 32비트 트랜잭션 ID가 한 바퀴 돌면 무슨 일이 생기는지, VACUUM의 동결과 relfrozenxid·datfrozenxid, 랩어라운드 방지 autovacuum, 경고와 쓰기 거부 단계, 복구 순서를 PostgreSQL 18 공식 문서로 정리했습니다.
Jump Consistent Hash: 표 없이 샤드 번호를 정하는 일관된 해시와 그 전제 조건
샤드를 10개에서 12개로 늘릴 때 hash mod n은 키의 5/6을 옮기지만 꼭 옮겨야 하는 건 1/6입니다. Lamping·Veach 논문의 Jump Consistent Hash 코드, 동작 원리, 버킷을 늘리고 줄일 때 생기는 일을 정리했습니다.
Python 제너레이터의 return 값은 어디로 갈까: StopIteration.value와 PEP 479
제너레이터에서 return한 값은 for 문에서는 보이지 않고 StopIteration.value에 담깁니다. yield from으로 받는 법, 제너레이터 안의 StopIteration이 RuntimeError가 되는 이유, close()의 반환값을 정리했습니다.
Referrer-Policy 값별로 Referer에 실리는 것: 전체 URL, 출처만, 아무것도 없음
링크를 누르거나 이미지를 불러올 때 브라우저가 Referer에 무엇을 담는지는 Referrer-Policy가 정합니다. 여덟 가지 값의 차이, URL에서 늘 빠지는 부분, 헤더·meta·속성의 관계, 리다이렉트와 Origin 헤더에 미치는 영향을 명세 기준으로 정리했습니다.
PostgreSQL 데이터 체크섬이 잡는 것과 놓치는 것
PostgreSQL 데이터 체크섬은 데이터 페이지를 읽을 때 손상을 감지합니다. 검사가 일어나는 시점, pg_checksums로 오프라인에서 켜는 방법, pg_stat_database 카운터, amcheck와 백업이 여전히 맡는 범위를 정리했습니다.
작은 TCP 쓰기가 멈칫하는 이유: Nagle 알고리즘과 지연 ACK, TCP_NODELAY
요청을 작은 write 두 번으로 나눠 보내면 두 번째 조각이 상대의 ACK를 기다릴 수 있습니다. Nagle 알고리즘과 지연 ACK의 규칙을 RFC 896, 1122, 9293으로 나눠 보고, TCP_NODELAY와 리눅스 전용 옵션이 각각 무엇을 바꾸는지 정리했습니다.
유니온 파인드의 경로 압축과 크기 가중치: α(n)은 어떤 구현에 붙는 숫자인가
유니온 파인드에서 크기 가중치, 경로 압축, 경로 절반이 parent 배열을 각각 어떻게 바꾸는지 작은 예로 따라가고, 최악 Θ(log n)과 연산 열 전체의 O(m α(n))이 어느 구현에 해당하는지 Princeton algs4 자료를 기준으로 정리했습니다.
KMP 실패 함수: 불일치가 나면 패턴은 어디로 돌아가나
KMP 문자열 검색에서 불일치 뒤 패턴의 어느 위치를 다시 비교할지 정하는 f·next 표의 정의와 계산법, 전체가 선형 시간이 되는 이유를 1977년 원 논문과 Princeton 구현으로 정리합니다.
Linux 커널 rbtree: 비교 함수를 저장하지 않고 노드를 구조체에 넣어 쓰는 레드-블랙 트리
Linux의 레드-블랙 트리는 비교 함수를 저장하지 않습니다. 노드를 구조체에 넣는 방식, 직접 쓰는 검색·삽입 루프와 호출마다 비교 함수를 받는 도우미, 색 비트, cached·augmented 트리, 락 없는 조회의 한계를 v6.17 소스로 정리했습니다.
REA로 할 수 있는 것, 조건이 맞아야 되는 것, 지원하지 않는 것
커밋을 고정한 공식 문서를 기준으로 REA의 능력을 표로 정리했습니다. 기본 제공 정적 경로, provider가 필요하거나 상태를 바꾸는 경로, 지원하지 않는 대상, Evidence와 '모름'을 읽는 법까지.
REA 안전하게 시작하기: 첫 연습, 팀 점검표, 30/60/90일 계획
먼저 알아 둘 것, 공식 Notes 픽스처로 하는 위험이 낮은 첫 조사, 팀을 위한 점검표, 제안하는 성공 기준, 중단 조건을 포함한 30/60/90일 시범 도입 계획을 정리했습니다.
REA 후기들은 실제로 무엇을 시험했나: 실행, 데모, 뉴스, 의견을 나눠 읽기
REA에 관한 외부 글 여덟 편을 '누가 무엇을 실행했나'로 분류했습니다. 독립 실행 두 편, 작성자 주장 데모 두 편, 뉴스·의견 세 편, 토론 스레드 한 곳이 각각 무엇을 뒷받침하는지 정리합니다.
REA의 장점과 그 대가, 그리고 앞으로 12~24개월의 다섯 가지 시나리오
REA의 장점은 대부분 같은 설계에서 나온 대가와 짝을 이룹니다. 여섯 쌍의 장단점, 누가 이득을 보는지, 반대 시나리오와 지켜볼 신호를 붙인 다섯 가지 조건부 시나리오. 예측이 아니라 분석입니다.
REA(Reverse Engineer Anything) 정리: 에이전트에게 분석 도구를 연결하는 방식, 배울 것, 지켜볼 것
GitHub에서 빠르게 주목받은 REA가 무엇이고 무엇이 아닌지, 에이전트와 함께하는 조사 흐름, 시작 전에 알아 두면 좋은 배경지식과 학습 순서, 안전과 권리의 경계를 공식 문서를 기준으로 정리했습니다.
Retry-After 헤더: 429, 503, 413, 3xx에서 각각 뜻하는 것과 클라이언트가 읽는 법
RFC 9110과 RFC 6585를 기준으로 Retry-After의 두 가지 값 형식, 상태 코드별 의미, HTTP-date와 초 단위 값을 대기 시간으로 바꾸는 방법, 잘못된 값과 큰 값을 다루는 방법을 정리했습니다.
write()가 성공하면 데이터는 디스크에 있을까: 짧은 쓰기, 늦게 오는 오류, fsync
write()의 성공은 디스크 기록을 뜻하지 않습니다. 짧은 쓰기 처리, Linux 4.13 이후 writeback 오류 보고, fsync와 fdatasync의 범위, 새 파일과 rename 뒤 디렉터리 fsync가 필요한 이유를 정리했습니다.
스킵 리스트: 동전 던지기로 정한 레벨이 O(log n) 검색을 만드는 방식
정렬된 연결 리스트에 무작위 레벨의 포인터를 더하면 검색이 왜 기대 O(log n)이 될까요? Pugh의 보고서에 실린 알고리즘, '기대' 시간의 범위, Java ConcurrentSkipListMap 문서가 약속하는 것을 정리했습니다.
HSTS가 막는 것과 못 막는 것: max-age, includeSubDomains, preload
Strict-Transport-Security 헤더를 받은 브라우저가 무엇을 바꾸는지 RFC 6797로 정리합니다. 첫 방문 문제, includeSubDomains의 이점과 위험, 단계적 max-age, 지금 preload를 권장하지 않는 이유까지.
리눅스 Transparent Huge Pages 설정 읽는 법: enabled, 크기별 설정, madvise, khugepaged
THP 설정은 최상위 enabled와 크기별 hugepages-<size>kB/enabled로 나뉩니다. inherit, MADV_HUGEPAGE와 MADV_NOHUGEPAGE, khugepaged의 범위, /proc과 sysfs에서 실제 사용을 확인하는 방법을 커널 문서 기준으로 정리했습니다.
길이를 모르는 스트림에서 k개를 고르게 뽑기: 저수지 샘플링(Algorithm R)
전체 개수를 모르는 데이터를 한 번만 읽으면서 k개를 무작위로 뽑는 저수지 샘플링. 교체 확률이 왜 k/i인지, 모든 원소가 k/n으로 남는 증명, k개 조합 전체가 고른지, 흔한 범위 실수까지 정리했습니다.
PostgreSQL UPDATE가 새 인덱스 항목을 만들지 않는 조건: HOT 업데이트와 fillfactor
PostgreSQL의 HOT(heap-only tuple) 업데이트가 일어나는 두 조건, 인덱스가 참조하는 열과 같은 페이지의 빈 공간을 공식 문서로 정리했습니다. fillfactor 설정과 pg_stat_user_tables로 비율을 보는 법도 다룹니다.
JavaScript sort()가 숫자를 이상하게 정렬하는 이유: 기본 문자열 비교와 비교 함수 규칙
[10, 9, 1, 100].sort()는 [1, 10, 100, 9]를 돌려줍니다. 기본 정렬의 문자열 비교, 비교 함수의 반환값과 일관성 조건, 원본 변경, undefined와 빈 칸, toSorted()를 ECMA-262 명세로 정리했습니다.
해시 테이블은 언제 O(1)이 아닐까: 충돌, O(n²) 삽입, 해시 플러딩
dict와 HashMap의 O(1)은 기댓값입니다. 키의 해시가 모두 같으면 n개 삽입에 비교가 최소 n(n−1)/2번 필요한 이유, Python 해시 무작위화와 PYTHONHASHSEED, Rust SipHash, Java의 Comparable 대응을 정리했습니다.
JWT 검증에서 alg를 믿으면 안 되는 이유: none, RS256→HS256 혼동과 알고리즘 고정
JWT 헤더의 alg는 토큰을 만든 쪽이 적는 값입니다. alg none과 RS256→HS256 혼동이 통하는 이유, RFC 8725가 요구하는 알고리즘 고정과 키 하나당 알고리즘 하나 원칙, 서명 다음에 확인할 iss·aud·exp·typ를 정리했습니다.
파이썬 기본 인자에 []를 쓰면 안 되는 이유: 기본값은 함수를 정의할 때 한 번만 만들어진다
def f(a, L=[])를 여러 번 호출하면 리스트가 계속 쌓입니다. 파이썬 공식 문서가 설명하는 기본값 평가 시점, __defaults__, None 패턴과 dataclass의 default_factory까지 예제로 정리했습니다.
PostgreSQL 테이블을 작업 큐로 쓸 때: FOR UPDATE SKIP LOCKED와 잠금이 풀리는 시점
여러 워커가 PostgreSQL 테이블에서 작업을 나눠 가져갈 때 쓰는 FOR UPDATE SKIP LOCKED를 공식 문서로 정리했습니다. 잠금이 유지되는 범위, LIMIT과 OFFSET, ORDER BY 순서, WITH 안의 잠금 절을 다룹니다.
Python .pyc는 언제 다시 만들어질까: timestamp와 hash 기반 무효화
CPython은 기본적으로 소스의 수정 시각과 크기로 .pyc가 최신인지 판단합니다. 이 방식이 놓칠 수 있는 경우와 checked-hash, unchecked-hash .pyc의 차이, compileall 사용법을 Python 3.14.8 문서 기준으로 정리했습니다.
SQLite의 -wal 파일이 계속 커질 때: 체크포인트와 끝나지 않는 읽기 트랜잭션
SQLite WAL 모드에서 -wal 파일이 줄지 않는 이유를 공식 문서로 정리했습니다. 자동 체크포인트 1000페이지, 읽기 트랜잭션이 체크포인트를 멈추는 원리, PASSIVE·FULL·RESTART·TRUNCATE의 차이와 journal_size_limit을 다룹니다.
DNS 레코드를 추가했는데 아직 '없는 이름'으로 나올 때: NXDOMAIN, NODATA와 네거티브 캐시
레코드를 추가한 뒤에도 일부 리졸버가 계속 '없음'으로 답하는 이유를 RFC로 정리했습니다. NXDOMAIN과 NODATA의 차이, SOA로 정해지는 네거티브 TTL, 하위 이름까지 막는 NXDOMAIN cut, 실패 캐시의 5분 상한을 다룹니다.
aria-label과 aria-labelledby가 함께 있으면 무엇이 읽힐까
스크린 리더가 읽는 이름은 정해진 순서로 계산됩니다. aria-labelledby, aria-label, label, placeholder의 우선순위와 흔한 실수를 W3C 문서로 확인합니다.
블룸 필터가 '없음'만 확신하는 이유
블룸 필터가 '확실히 없음'과 '있을 수도 있음'으로만 답하는 이유, 거짓 음성이 없다는 보장이 성립하는 조건, 거짓 양성 확률 식, 비트를 지우면 보장이 깨지는 이유를 정리합니다.
CORS 프리플라이트는 언제 생길까: OPTIONS 요청이 먼저 가는 조건
fetch()가 본 요청 전에 OPTIONS를 보내는 조건을 WHATWG Fetch 표준으로 정리했습니다. 안전 목록의 메서드와 헤더, application/json과 Authorization이 프리플라이트를 부르는 이유, Max-Age 기본값 5초도 다룹니다.
sort(() => Math.random() - 0.5)로 섞으면 안 되는 이유: Fisher–Yates 셔플
랜덤 비교 함수로 배열을 섞으면 왜 고르게 섞이지 않는지 ECMAScript 명세로 확인하고, 모든 순열이 같은 확률로 나오는 Fisher–Yates 셔플과 난수 범위·생성기 주의점을 정리했습니다.
git push --force-with-lease도 동료의 커밋을 지울 수 있다: 백그라운드 fetch와 --force-if-includes
rebase 뒤 강제 푸시할 때 --force-with-lease가 무엇을 비교하는지, IDE의 백그라운드 fetch가 그 보호를 무력화하는 이유, Git 2.30에 추가된 --force-if-includes와 기대값을 직접 적는 방법을 Git 공식 문서로 정리했습니다.
git reset --hard로 날린 커밋, reflog로 되찾기
reflog는 로컬 저장소에서 브랜치와 HEAD가 어디를 가리켰는지 기록합니다. 사라진 커밋을 찾아 브랜치로 살리는 방법과 기본 만료 기한(90일·30일), 복구가 안 되는 경우를 공식 문서 기준으로 정리했습니다.
HTTP 메서드의 안전과 멱등: POST 재시도는 위험하고 PUT은 괜찮은 이유
RFC 9110 기준으로 안전한 메서드와 멱등 메서드의 차이를 정리했습니다. 연결이 끊겼을 때 GET·PUT·DELETE는 다시 보내도 되고 POST·PATCH는 왜 조심해야 하는지, If-Match로 막는 방법까지 다룹니다.
NaN === NaN은 왜 false일까: 자바스크립트의 ===, Object.is, includes가 값을 비교하는 방식
JavaScript에서 NaN === NaN은 false인데 [NaN].includes(NaN)은 true입니다. ===, Object.is, includes·Map·Set이 NaN과 -0을 다르게 다루는 ECMA-262의 규칙을 코드와 함께 정리했습니다.
load average 4.0은 높은 걸까: 리눅스 부하 평균이 세는 것과 1·5·15분의 의미
리눅스 load average는 CPU 사용률이 아니라 실행 중·대기 중(R)과 끊을 수 없는 대기(D) 작업 수의 지수 평균입니다. 커널 소스와 man 페이지로 계산 방식, CPU 수로 읽는 법, PSI와의 차이를 정리했습니다.
encodeURIComponent가 URIError를 던지는 이유: 짝 잃은 서로게이트
문자열을 slice로 자르다 이모지가 반으로 갈리면 encodeURIComponent는 URIError를 던지고 TextEncoder는 EF BF BD를 씁니다. 짝 잃은 서로게이트의 정체와 isWellFormed·toWellFormed 사용법을 ECMA-262, Unicode 17.0 기준으로 정리했습니다.
트랜잭션 안의 SELECT 두 번이 다른 값을 돌려주는 이유: PostgreSQL READ COMMITTED와 스냅샷
PostgreSQL 기본 격리 수준인 READ COMMITTED에서 한 트랜잭션의 SELECT 두 번이 다른 결과를 내는 이유를 공식 문서로 정리했습니다. 문장마다 잡는 스냅샷, UPDATE의 재평가, REPEATABLE READ와 재시도도 다룹니다.
time 결과의 real, user, sys는 무엇이 다를까: 경과 시간과 CPU 시간
time 명령의 real, user, sys가 각각 무엇을 세는지 POSIX 정의로 정리하고, user+sys가 real보다 크거나 작을 때 읽는 법, 셸 time과 /usr/bin/time의 차이를 설명합니다.
인증 앱의 6자리 코드는 어떻게 만들어질까: TOTP 계산 과정
30초마다 바뀌는 인증 앱 코드가 서버와 맞아떨어지는 원리를 RFC 테스트 값으로 따라갑니다. 시간 단계, HMAC, 동적 절단, 서버 검증, 피싱에 약한 이유까지 정리했습니다.
toLowerCase로 대소문자 무시 비교가 틀리는 이유: 유니코드 케이스 폴딩
'straße'와 'STRASSE'는 toLowerCase()로 비교하면 다릅니다. 대소문자 변환과 케이스 폴딩의 차이, 터키어 i, 정규식 /iu의 단순 폴딩, 정규화와 함께 비교하는 법을 Unicode 17.0과 ECMAScript 2026 기준으로 정리했습니다.
리눅스 free 명령에서 free가 거의 0일 때: buff/cache와 available 읽는 법
free 명령의 free 칸이 작다고 메모리가 부족한 것은 아닙니다. /proc/meminfo와 커널 소스로 buff/cache, available, used의 뜻을 확인하고, 캐시를 습관적으로 비우면 성능에 해로울 수 있는 이유를 정리했습니다.
TIME-WAIT 소켓이 쌓이는 이유: TCP의 2×MSL과 리눅스의 60초, tcp_fin_timeout의 오해
TCP에서 먼저 연결을 닫은 쪽이 TIME-WAIT에 머무는 이유, RFC 9293의 2×MSL과 리눅스의 60초 고정값을 정리했습니다. tcp_fin_timeout이 실제로 정하는 것과 tcp_tw_reuse의 기본값도 다룹니다.
한글 다운로드 파일명이 깨질 때: Content-Disposition의 filename과 filename*
HTTP 다운로드에서 한글 파일명을 전달하는 filename과 filename*의 차이, UTF-8 퍼센트 인코딩, ASCII 대체 이름과 수신 측 보안 처리를 RFC 6266과 RFC 8187로 설명합니다.
터치 영역은 24px, 44px, 48dp 중 얼마나 커야 할까
WCAG 2.2의 24×24 CSS px AA 기준과 44×44 AAA 기준, Android의 48dp 권고를 구분하고 작은 아이콘의 실제 클릭 영역을 넓히는 방법을 정리했습니다.
git bisect run으로 버그 커밋 찾기: 종료 코드 0, 125, 127의 의미
git bisect가 이진 탐색으로 첫 bad 커밋을 찾는 방식과, bisect run이 종료 코드를 0은 good, 1~124와 126~127은 bad, 125는 skip, 그 밖의 값은 중단으로 읽는 규칙을 Git 공식 문서로 정리했습니다.
HTTP Range 요청과 206·416: 끊긴 다운로드는 어떻게 이어받을까
끊긴 다운로드를 이어받을 때 오가는 Range, Content-Range, If-Range 헤더와 206 Partial Content, 416 Range Not Satisfiable의 규칙을 RFC 9110으로 정리했습니다. 서버가 Range를 무시하는 경우도 다룹니다.
퀵 정렬은 언제 O(n²)이 될까: 표준 정렬이 최악을 막는 방법
정렬된 입력, median-of-3 killer, 적대적 비교 함수처럼 퀵 정렬을 이차 시간으로 만드는 경우와 introsort의 깊이 제한, C++·Rust·Go·Java 문서가 보장하는 범위를 정리합니다.
NOT IN 쿼리가 0건을 돌려줄 때: SQL의 NULL과 3값 논리
서브쿼리 결과에 NULL이 하나만 있어도 NOT IN 조건이 0건을 돌려주는 이유를 PostgreSQL·MySQL·SQLite 공식 문서로 정리했습니다. 3값 논리, WHERE의 행 선택 규칙, NOT EXISTS로 고치는 방법도 다룹니다.
다익스트라 알고리즘에 음수 가중치를 넣으면 왜 틀릴까
다익스트라의 탐욕적 선택이 음수 간선에서 깨지는 이유를 간선 세 개짜리 반례로 확인하고, 벨만–포드와 DAG 최단 경로를 언제 쓰는지 정리합니다.
CSV와 RFC 4180: 쉼표·큰따옴표·줄바꿈은 어떻게 처리하나
셀 안의 쉼표와 줄바꿈 때문에 CSV 열이 밀리는 이유를 RFC 4180, IANA text/csv 등록, W3C 표 데이터 권고, Python·Go 문서로 정리했습니다. RFC 4180이 정하지 않은 것도 나눠 봅니다.
git log와 git diff의 ..과 ...: 같은 기호가 다르게 동작하는 이유
git log에서 A..B와 A...B가 고르는 커밋, git diff에서 두 기호가 비교하는 지점을 Git 공식 문서와 직접 실행한 예로 정리합니다. 풀 리퀘스트 diff가 어느 쪽인지도 다룹니다.
401과 403의 차이: 인증이 없는 요청과 거부된 요청
HTTP 401 Unauthorized와 403 Forbidden의 차이를 RFC 9110과 OAuth 2.0 Bearer 토큰 명세로 정리했습니다. WWW-Authenticate 헤더, 재요청 규칙, 404로 존재를 숨기는 경우도 다룹니다.
2147483647에 1을 더하면: 언어마다 다른 정수 오버플로
Java int, Go int32, Rust i32에서 2147483647 + 1은 범위를 넘습니다. Java와 Go는 음수, Rust는 기본 Cargo 설정에서 dev 빌드면 패닉, release 빌드면 음수입니다. C의 INT_MAX + 1은 정의되지 않은 동작, Python은 2147483648입니다.
chmod 755와 644는 무슨 뜻일까: 권한 숫자와 rwx, 디렉터리의 x
chmod 755의 7과 5는 읽기·쓰기·실행 비트를 더한 8진수입니다. POSIX 규격을 기준으로 숫자와 rwx의 대응, 소유자·그룹·기타 판정, 디렉터리에서 r·w·x의 뜻, umask와 chmod -R의 함정을 정리했습니다.
힙은 정렬된 배열이 아니다: 우선순위 큐의 배열 순서와 인덱스 공식
heapq나 PriorityQueue를 출력하면 왜 정렬되어 있지 않을까요? 힙이 지키는 조건과 0부터 세는 부모·자식 인덱스 공식, 정렬된 리스트와의 비용 차이, 같은 우선순위 처리를 공식 문서로 정리했습니다.
package.json의 ^1.2.3과 ~1.2.3 차이: npm 버전 범위와 0.x의 함정
기본적으로 ^1.2.3은 1.2.3 이상 2.0.0 미만의 정식 버전을, ~1.2.3은 1.2.3 이상 1.3.0 미만의 정식 버전을 허용합니다. SemVer와 npm의 차이, 0.x, 프리릴리스, lockfile을 정리했습니다.
1.0.0-rc.1과 1.0.0, 어느 쪽이 높을까: SemVer 프리릴리스 순서와 ^ 범위
1.0.0-rc.1과 1.0.0 중 어느 쪽이 높은지, ^1.2.3이 1.5.0-beta.1을 고르지 않는 이유를 SemVer 2.0.0과 node-semver, Cargo 문서로 정리했습니다.
압축을 풀면 한글 파일명이 깨지는 이유: ZIP의 CP437과 UTF-8 플래그
ZIP을 풀었을 때 한글·일본어 파일명이 ╟╤▒█처럼 깨지는 이유를 PKWARE APPNOTE의 CP437 기본값, 범용 비트 플래그 11, Info-ZIP 0x7075 확장 필드와 Python·.NET 문서로 정리했습니다.
파일을 지웠는데 디스크 공간이 그대로인 이유: unlink와 열린 파일
rm으로 큰 파일을 지워도 df의 여유 공간이 늘지 않을 때가 있습니다. POSIX가 정한 링크 수와 열린 파일 규칙, du와 df가 다르게 보이는 까닭, Linux에서 원인을 찾고 공간을 되찾는 순서를 정리했습니다.
Cache-Control의 no-cache와 no-store 차이: 저장을 막는 쪽은 no-store다
no-cache는 캐시하지 말라는 뜻이 아닙니다. RFC 9111 기준으로 no-cache와 no-store, max-age=0, Pragma의 차이를 정리하고, CDN과 브라우저에서 동작이 달라지는 지점을 짚습니다.
음수 나머지 연산: -7 % 3이 언어마다 다른 이유
-7 % 3이 Python에서는 2, JavaScript·Java·C·Go에서는 -1인 이유를 절단·내림·유클리드 나눗셈으로 설명하고, 음수에서도 0 이상의 나머지를 얻는 방법을 정리했습니다.
UTF-8 BOM(EF BB BF): 보이지 않는 세 바이트를 표준마다 다르게 다루는 이유
UTF-8 파일 앞의 EF BB BF를 브라우저는 건너뛰고 JSON.parse는 오류로 보는 이유를 유니코드, RFC 3629, JSON(RFC 8259), WHATWG 인코딩·HTML 표준의 규칙으로 정리했습니다.
X-Frame-Options와 CSP frame-ancestors: 클릭재킹 방어 헤더, 둘 다 보내면 어떻게 될까
iframe 삽입을 막는 두 헤더의 차이를 CSP Level 3과 HTML 표준으로 정리했습니다. 둘을 함께 보낼 때의 우선순위, ALLOW-FROM이 무시되는 이유, meta 태그로는 안 되는 이유를 다룹니다.
이진 탐색의 삽입 위치: bisect, lower_bound, binarySearch는 무엇을 돌려주나
값이 없거나 중복될 때 Python bisect, C++ lower_bound, Java Arrays.binarySearch가 돌려주는 위치와 각 API의 전제 조건을 공식 문서와 C++ 표준을 따라 비교했습니다.
PNG 파일은 왜 89 50 4E 47로 시작할까: 시그니처와 청크 구조
PNG 파일이 늘 89 50 4E 47 0D 0A 1A 0A로 시작하는 이유, 길이·타입·데이터·CRC로 된 청크 구조, 대소문자로 속성을 나타내는 청크 이름 규칙과 필수 청크 순서를 W3C PNG 3판과 RFC 2083으로 정리했습니다.
diff의 @@ -1,7 +1,8 @@은 무슨 뜻일까: 통합 diff 읽는 법
diff -u와 git diff에 나오는 @@ 줄의 시작 줄과 줄 수, 범위가 0이 되는 경우, 기본 문맥 3줄, Git이 덧붙이는 함수 문맥을 POSIX 명세와 공식 문서로 설명합니다.
배열 끝에 추가하는 append는 왜 O(1)일까: 동적 배열과 상각 시간
가끔 배열 전체를 복사하는데도 append가 O(1)인 이유를 용량과 상각 분석으로 설명하고, Java·C++·Rust·Go 문서가 보장하는 범위와 구현이 정하는 증가율, 용량을 미리 잡는 방법을 정리했습니다.
Git 줄바꿈 설정: .gitattributes의 text·eol과 core.autocrlf는 어떻게 다른가
git diff에 ^M이 보일 때 확인할 설정을 Git 공식 문서 기준으로 정리했습니다. core.autocrlf와 .gitattributes의 text·eol이 각각 무엇을 정하는지, 이미 CRLF로 커밋된 파일은 어떻게 고치는지 다룹니다.
301, 302, 307, 308 리다이렉트의 차이: 영구와 임시, 그리고 POST가 GET이 되는 이유
HTTP 리다이렉트 301·302·303·307·308의 차이를 RFC 9110과 WHATWG Fetch 표준으로 정리했습니다. POST가 GET으로 바뀌는 조건, 캐시와 검색 엔진에서의 차이도 다룹니다.
Base64는 무엇이고 왜 쓸까: 인코딩 원리와 흔한 오해
Base64가 3바이트를 4글자로 바꾸는 방식, 결과가 약 33% 커지는 이유, 끝의 = 의미, URL-safe Base64와 한글·일본어를 다룰 때의 주의점을 RFC 4648을 기준으로 정리했습니다.
192.168.0.0/24의 /24는 무슨 뜻일까: CIDR와 서브넷 계산법
IP 주소 뒤의 /24가 뜻하는 것, 서브넷 마스크와의 관계, 네트워크·브로드캐스트 주소와 사용 가능한 호스트 수를 계산하는 방법, 사설 IP 대역을 예시와 함께 정리했습니다.
연한 회색 글씨는 왜 읽기 어려울까: WCAG 명도 대비 계산법
흰 배경의 연한 회색 글씨가 접근성 검사에서 떨어지는 이유를 WCAG 2의 상대 휘도와 명도 대비 공식으로 설명하고, 4.5:1·3:1·7:1 기준과 다크 모드에서 주의할 점을 실제 색상 값으로 정리했습니다.
도메인 이름이 IP 주소가 되기까지: DNS 조회 과정
브라우저에 주소를 입력하면 이름이 어떻게 IP 주소로 바뀌는지, 스텁 리졸버·재귀 리졸버·권한 서버·캐시의 역할과 A/AAAA 레코드, TTL을 RFC를 기준으로 정리했습니다.
0.1 + 0.2는 왜 0.3이 아닐까: 부동소수점의 원리
JavaScript·Python·Java에서 0.1 + 0.2가 0.30000000000000004가 되는 이유를 IEEE 754 배정밀도 형식으로 설명하고, 비교·반올림·금액 계산에서 피하는 방법을 정리했습니다.
해시 함수란 무엇인가: SHA-256, 체크섬, 비밀번호 저장까지
SHA-256이 항상 64자리인 이유, 한 글자만 바꿔도 결과가 전부 바뀌는 성질, 해시·암호화·인코딩의 차이, 다운로드 파일 검증, 그리고 비밀번호에 빠른 해시를 쓰면 안 되는 이유를 정리했습니다.
JSON.parse 에러가 가리키는 곳이 틀린 곳은 아니다: 자주 나는 JSON 오류 정리
끝에 남은 쉼표, 작은따옴표, 주석, NaN처럼 JSON 파서가 거절하는 것과, 큰 정수·중복 키처럼 오류 없이 값이 바뀌는 것을 RFC 8259 기준으로 정리하고 에러 위치를 읽는 법을 설명합니다.
한글 도메인이 xn--로 바뀌는 이유: 국제화 도메인과 퓨니코드
한국어.com이 DNS 설정이나 인증서에서 xn--3e0bk47br7k.com으로 보이는 이유, 퓨니코드가 글자를 영문으로 옮기는 방식, 변환 전 정규화 규칙과 동형 문자 피싱까지 RFC를 기준으로 정리했습니다.
안정 정렬(stable sort)이란: 같은 값의 순서가 지켜지는 정렬
안정 정렬의 뜻, 여러 기준으로 정렬할 때 왜 중요한지, Python·JavaScript·Java·C++ 표준 정렬이 무엇을 보장하는지 명세와 공식 문서를 기준으로 정리했습니다.
글자 수가 도구마다 다른 이유: 바이트, 코드 포인트, 눈에 보이는 글자
같은 글인데 워드, 채용 사이트, 문자 메시지, JavaScript가 서로 다른 글자 수를 내놓는 이유를 UTF-8 바이트, UTF-16, 코드 포인트, 눈에 보이는 글자(그래핌 클러스터) 단위로 풀고, 개발할 때 무엇을 기준으로 셀지 정리했습니다.
로그에 찍힌 1790550000은 몇 시일까: 유닉스 시간과 2038년 문제
유닉스 타임스탬프가 무엇을 세는지, 10자리와 13자리의 차이, 타임스탬프에 시간대가 없다는 뜻, 윤초와 2038년 문제, 데이터베이스에 시각을 저장하는 방법을 예시와 함께 정리했습니다.
한글 주소가 %EA%B2%80으로 바뀌는 이유: URL 인코딩 정리
검색 링크를 복사하면 한글이 %EA%B2%80…으로 바뀌는 이유, encodeURI와 encodeURIComponent·URLSearchParams의 차이, 공백의 %20과 +, %2520 같은 이중 인코딩 버그를 정리했습니다.
UUID v4와 v7, 무엇을 써야 할까: 128비트의 구조와 충돌 확률
UUID의 8-4-4-4-12 형식에서 버전과 변형 비트의 위치, v4의 실제 충돌 확률, 시각이 앞에 오는 v7이 데이터베이스 인덱스에 유리한 이유를 RFC 9562를 기준으로 정리했습니다.
찾는 글이 없습니다. 다른 낱말로 검색해 보세요.