한빛 데브그라운드 주니어 2019년 발표 내용 정리.
1. 문자열 인코딩: 인코딩이란 컴퓨터가 문자를 이해할 수 있게 만든 규칙.
- ASCII: ANSI에서 표준화한 7비트 부호체계. 영문 키보드로 입력할 수 있는 모든 기호들이 할당되어 있음. UTF-8과 호환, UTF-16과는 비호환.
- EUC-KR: 완성형 한글 인코딩 방식 중 하나로 시작은 '가', 끝은 '힝'. 지원 글자 수는 2,350자로 현대에 쓰이는 한글 11,172자에 비해 부족. (Legacy, 결제 모듈 등에서 아직 쓰임.)
- Unicode: 전 세계의 모든 문자를 다루도록 설계된 표준 문자 전산 처리 방식. Unicode 인코딩 방식엔 UTF-8, UTF-16, UTF-32가 있고, 일반적인 상황에선 UTF-8을 Unicode라 봐도 무방.
- UTF-8: 사실상 표준으로 글자당 1~4 바이트를 쓰는 가변 길이 인코딩 방식. 1바이트 영역은 ASCII 코드와 하위 호환성을 갖음.
- UTF-16: 2바이트 고정 인코딩 방식. 자바, 윈도우즈 API에서 쓰이는데 멀티바이트라고도 함. 호환성 목적으로 지금도 쓰임.
- UTF-32: 4바이트 고정. 데이터 낭비가 심해서 사실상 쓰지 않지만 가변 길이를 고려하지 않아도 되는 장점 또한 존재해 프로그램 내부적으로 쓰이는 경우도 있음.
2. Base64: 바이너리 데이터(이미지, 텍스트, 동영상)를 아스키 기반 문자열로 인코딩하는 방법. (Base64가 암호화는 아님.)
- 문자 코드에 영향을 받지 않도록 공통 ASCII 영역의 문자만을 이용해 인코딩 함.
- 64진법. 전자 메일이나 웹 등의 환경에서 바이너리 데이터를 전송하는데 쓰임. (RFC 1421, RFC 2045)
- 바이너리 -> 텍스트 변환 간 일반적으로 33% 데이터 용량이 증가.
3. JSON: 구조화 텍스트 기반 데이터 규격. 정수, 실수, 텍스트를 규격화해서 실어 나르는 용도.
- 장점: 범용적, 읽기 편함. 디버깅 용이. (JSON 자체가 JavaScript Object Notation인 만큼 JavaScript 언어와 궁합이 아주 좋다.)
- 단점: 고용량, 처리 비용이 높음. (일반적인 사용 사례에선 무시해도 되는 수준이나 Latency가 중요한 게임, 금융 도메인에선 사용에 제약.)
- JSON 규격 변경에서 오는 결함 가능성을 염두하고 사용해야 함.
- Latency가 중요한 경우엔 Google Protocol Buffer 또는 Apache Thrift 사용이 권장됨.
4. 다국어 처리: 프로그램 수정없이 여러 언어를 지원하는 기법.
- 리소스 파일 방식, 언어 설정 방식, 프로그램 방식(하드코딩)으로 대응할 수 있음.
- 일반적으론 Key:Value 기준으로 타깃 언어를 획득하는 방안.
- Python엔 gettext 패키지, 안드로이드, C# 등의 언어는 프레임워크 레벨에서 지원됨. 표준은 i18N
5. 날짜와 시간
- 데이터를 주고 받는 상호간 타임존이 서로 다르면 문제가 발생함. 타임존 기준은 UTC, 한국은 UTC+9. 하나의 시스템은 하나의 타임존을 쓰도록 하는 것이 권장됨.
- Apache Zookeeper 같은 분산 코디네이션 툴을 쓰면 특정 시스템의 타임존 변화를 감지할 수도 있음. 또는 주기적으로 상호간 타임존을 확인하고 맞추는 프로토콜을 반영하는 것도 고려할 수 있음.
- 시간엔 단조 시간과 실제 시간(벽 시계 시간, wall time)이 있음.
- 단조 시간? 운영체제나 CPU가 계산하는 시간으로 운영체제 시작 이후 종료까지 절대 바뀌지 않는 시간을 말함. 단조 시간은 컴퓨터마다 독립적.
6. 정규표현식 (Regex): 주어진 문자열 속에서 특정 패턴을 찾고자 할 때 쓰는 기술.
- 비밀번호 패턴에 숫자 1개, 영어 소문자 1개, 영어 대문자 1개 포함 조건 같은걸 적용한다면 정규 표현식으로 걸러낼 수 있음.
- 정규표현식은 regex101.com과 같은 사이트에서 미리 검증해볼 수 있음.
7. UUID: 범용 고유 식별자. 네트워크 상에서 서로 모르는 개체를 식별하기 위한 기술.
- 4개의 하이픈과 32개의 16진수 문자로 구성. 하이픈을 빼면 저장하는데 16바이트가 필요함.
- UUID v4는 중앙 관리 시스템에서 고유 ID를 할당받는 방식이 아니라 개발 주체가 스스로 식별자 이름을 짓는 방식임.
- 중앙의 서버 없이 Object, 작업, 요청 등에 ID를 메기고 싶은 경우 UUID를 쓰면 된다.
- 340,282,366,920,938,463,463,374,607,431,768,211,456개의 경우의 수를 갖기 때문에 사실상 중복은 없다고 인정됨.
- UUID에도 충돌은 있을 수 있으므로 신뢰성이 중요한 시스템에선 UUID Pool(UUID 십만개, 백만개를 먼저 생성한 뒤 그 안에서만 쓰도록)을 고려해야 함.
8. Random: 게임 규칙, 랜덤 박스, 암호화키, UUID 등을 만드는데 쓰임.
- 쓰임에 따라 유사난수와 완전 난수를 구분해야 함. 우리가 쓰고 있는 대부분의 난수는 유사 난수임.
- 유사난수는 난수를 흉내낸 난수로, SEED 값을 주면 SEED 값 기준으로 일련의 숫자를 만들어낸다. 완전한 난수에 비해 연산속도가 빠름.
- 게임에서 유사난수 같은걸 쓰면 특정 시간대의 아이템 드랍률을 미리 알 수도 있으므로 문제가 된다.
- 완전 난수는 암호학적으로 안전. 유사 난수에 비해 3~4배 느림. 노이즈를 이용해 난수를 만들어내므로 예측 불가. 인증키 생성, 게임 아이템 생성 등에 쓰인다.
9. 해쉬함수: 임의의 값을 고정길이 값으로 변환하는 알고리즘.
- 특정 해시 알고리즘은 입력값, 입력길이와 무관하게 항상 같은 길이의 문자열을 반환한다.
- 해시 맵 같은데 쓰인다. 해시 충돌이 있긴 하지만 가능성은 매우 낮으며 접근 비용이 O(1)이므로 매력적.
- 민감한 데이터의 변조를 막는데 쓸 수 있다. 암호를 해시화해서 저장하는데 보안 향상을 위해 Salt가 추가됨.
- SHA-256 이상을 쓰는것이 안전하지만 MurmurHash의 경우 안전하진 않아도 성능이 매우 좋아 Redis같은 곳에서 쓰인다.
10. HTTP(S): 웹의 기반 기술. 텍스트 기반의 통신.
- HTTP의 주요 성질은 Stateless. 상대가 살아있는지 요청하기 전엔 알 수 없다.
- HTTP는 기본적으로 1개의 요청당 1개의 소켓을 사용. 요청 전 연결하고 데이터를 주고받은 후 연결을 끊음.
- Stateless 성질을 보완하기 위해 Cookie, Session 등을 쓴다. (또는 웹소켓, HTTP/2를 쓰면 연결 중단 없이 데이터 송수신 가능)
- Header에 주요 정보가 담긴다. (User-Agent, Content-Type, Accept ...)
- HTTPS = HTTP + TLS, HTTPS의 암호화 수준은 TLS 버전에 따른다. 서버의 경우 인증된 제3자가 발급한 인증서가 필요.
- 분산 환경에선 스티키 세션(처음 연결된 서버와만 통신되게끔 하는 개념), CORS(서로 다른 도메인간 요청을 허용해 주는 것.)에 대해 알아둘 필요 있음.
okminseok님, 주니어 발표 자료를 이렇게 깔끔하게 정리해 주시다니 정말 유용해요! 특히 EUC-KR이 현대 한글을 다 담지 못해 2,350자만 지원한다는 부분이나, Base64 변환 시 용량이 33%나 늘어난다는 구체적인 수치들이 머리에 쏙쏙 들어오네요.
답글삭제