개발 분야와 관계없이 알아야 하는 기술 10가지 - 이기곤@수아랩
한빛 데브그라운드 주니어 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(서로 다른 도메인간 요청을 허용해 주는 것.)에 대해 알아둘 필요 있음.