학교에서 알려주지 않는 17가지 실무 개발 기술

2020. 5. 31. 23:39Engineer

반응형

저번에 산 책들을 다보고 새로 읽을 책을 사러 영풍문고에 가서 이 책 저 책 훓어 보다가 선택한 책. 콕 찝어 어떤 기술에 대한 것을 공부해야겠다 싶은게 없어서, 개발과 관련하여 팁이나 노하우가 있는 책을 고르다가 선택하였다. 


책에서 가끔씩 나오는 예제 코드들은 파이썬을 기반으로 작성한다. 


   책에 있는 팁 정리


  01. 문자열 인코딩


UTF-8

- 가장 많이 사용하는 문자열 인코딩. 최소 1바이트, 최대 6바이트 사용. 대부분 4바이트 내로 처리 

- 아스키 코드와 호환 가능

- 윈도우, 자바, 임베디드를 제외한 거의 모든 환경에서 문자열 처리 표준으로 봐도됨

- JSON은 UTF-8 인코딩만 사용. 다른 문자열 인코딩은 표준에서 지원하지 않음


UTF-16

- 자바와 윈도우 환경에서 호환성 외에는 사용할 이유가 별로 없음

- 2바이트 또는 4바이트 길이의 문자열을 사용. 아스키 코드와 호환되지 않음

- UTF-16기반 환경에서 UTF-8을 시용할 때는 사용 영역을 명확히 구분하는게 좋음. 


UTF-32

- 4바이트 고정

- 사용할일이 별로 없음


EUC-KR

- 한국에서 독자적으로 사용하는 문자열 인코딩. 고정된 2바이트

- 가능하다면 UTF-8로 바꾸는게 좋음


개발환경에서는 실제 문자열 길이와 컴퓨터가 할당하는 버퍼 크기를 동일하게 취급해 생기는 버그가 생각보다 많다. 문자열을 취급할 때는 어떤 문자열 인코딩 방식을 쓰는지 반드시 알아야 하고, 가능한 같은 문자열 인코딩을 사용하는 것이 좋다. 


MySQL은 UTF-8 타입에는 utf8과 utf8mb4가 있다. utf8은 3바이트까지 정상 처리하나, 4바이트 영역문자는 처리하지 못한다. 따라서 UTF-8과 완벽히 호환되는 문자 집합을 쓰고 싶다면 utf8mb4를 써야함. 이는 MySQL 설정에서 변경 가능


국내에서 만든 서비스를 연동할 때는 EUC-KR을 사용하는 경우가 있으니 주의 필요. 



  02. 다국어 처리


다국어를 처리하는 방법은 프로그래밍 언어나 소프트웨어 프레임워크마다 다르기 때문에 반드시 i18n을 사용할 필요는 없다. 하지만 동작 방식은 모두 비슷하다. 어떤 방법을 사용하던 다음 기준을 확실히 정해야 한다. 

  • 언어별로 누락되거나 더 이상 사용하지 않는 메시지를 관리할 수 있어야 한다. 
  • 중복된 묹장을 최대한 피하고 단어를 조합해 사용하여 재사용성을 늘리는 방법을 고민해야 한다. 
  • 언어 설정 기준을 확실하게 정해야 한다. 시스템 언어 설정을 따를지, 웹 브라우저의 요청 언어를 따를지, 요청 IP의 국가를 기준으로 할지. 
  • 언어마다 글자수가 다르다는 점을 주의해야 한다. 짧은 문장에선 문제가 없던 화면이 긴 문장을 사용하는 언어로 바꿀때, 문장이 폼 레이아웃을 뜷거나 화면 전체가 깨질수 있다. 
안드로이드나 iOS는 안드로이드 스튜디오와 XCode에서 다국어 처리를 지원한다. 

국가별로 다른 것은 언어만이 아니다. 날짜 표기법, 통화 기호, 길이, 무게와 같은 여러 단위가 국가별로 다르다. 특히 날짜와 시간 표기로 인한 문제가 잘 발생한다. 

  03. 날짜와 시간


단조 시간은 실제 시간으로 사용할 수 없지만, 불변성을 보장하므로 특정 작업을 하는데 걸리는 시간을 측정하거나 일정한 주기로 작업을 수행할때 사용되는 시간을 계산할 때 사용. 


실제 시간은 매달 1일 또는 특정 날짜인지 확인할 때, 실제 시간을 표기할 때 사용하는게 좋음


실제 시간 값은 서비스를 구성하는 모든 서버와 프로그램이 UTC(Coordinated Universal Time)를 사용하거나 그렇게 하기 어렵다면 동일한 타임존을 사용하는 것이 좋음. 그렇지않으면 서로 다른 두 서버의 로그를 함께 보기 어려워지거나, 여러 서버가 특정 시간에 동시에 수행하는 작업에 영향을 줄 수 있음


실무에서는 서비스 발견 기능을 사용해 여러 서버가 같은 타임 존을 사용하는지 확인할 수 있음. 서버 개발자라면 ETCD나 주키퍼(Zookeeper)를 사용해 보는 것도 좋음



  04. 정규 표현식


정규 표현식은 Perl, POSIX, POSIX확장 등 여러 형태로도 존재하고 표준마다 조금씩 다름. 


정규 표현식을 사용할 때는 정규 표현식을 써도 되는지 판단하는 일이 가장 중요. 불필요하게 많은 규칙을 적용하거나, 속도 때문에 병목이 생긴다면 다른 접근 방법을 고민하는 것이 필요



  05. 범용 고유 식별자 (UUID)


컴퓨터 시스템 내에서 고유한 객체를 식별하기 위해 사용하는 값. 네트워크 상에 존재하는 여러 컴퓨터를 식별하기 위해 사용하기 시작했음. 오늘날 가장 많이 사용하는 버전은 4. 


충돌 가능성이 낮아서 범용적인 고유 식별자로 사용하기 좋으나, 16바이트나 필요하고 UUID 만으로는 정보 식별이 어려운 단점이 있음


실무에서 웹 서비스를 만들때는 동시에 여러 웹 서버가 작업 ID를 생성하므로 낮은 확률로 UUID가 충돌이 생길 수 있음. 이때는 충돌을 막기 위해 ETCD, Redis와 같은 서비스를 이용해 먼저 UUID를 생성한 쪽만 사용할 수 있게 해야함



  06. 난수


사용 목적에 따라 적당한 난수 생성 방식이 있음. 


식별자를 생성할 경우, 겹치지 않는 수를 빠르게 만드는 것이 중요. 메르센 트위스터처럼 속도가 빠르고 분포도가 큰 난수 알고리즘이 적절. 


OPT 또는 엑서스 토큰 발급할 경우, 서로 다른 서버에서 생성한 두 값이 충돌하지 않게 해야 하며 암호학적으로 안전한 난수를 사용해야함



  07. 해시 함수


해시 함수가 데이터 암호화를 제공하지는 않으므로 인터넷을 통해 데이터를 주고 받을 때는 해시 값과 별개로 데이터 자체를 암호화 할 필요가 있음


해시함수 정할 때 고려사항

- 입력값의 크기

- 보안 수준

- 해시 값의 용도(값 자체가 의미를 가지거나 식별자로 사용하는 경우)



  08. JSON


UTF-16 환경인 윈도우나 자바, EUC-KR등을 사용하는 환경에서는 JSON파일을 생성하거나 사용할 때 주의가 필요


키 문자열을 한글로 했을 때 불편한 예는, JSON 데이터를 객체로 직렬화/역직렬화 해주는 기능을 사용할 때 직접 키와 멤버 변수를 이어주게 코드를 작성해야 하는 번거로움이 있음


텍스트 기반의 데이터 규격인 JSON은 불필요한 트래픽 오버헤드가 있어 바이너리 기반 규격인 프로토콜 버퍼와 비교하여 느리고 메세지의 크기가 큼. 메시지 호환성 유지도 어려움. 주석을 사용할 수 없음


몽고DB를 사용하는 환경이라면 바이너리를 지원하는 JSON 규격인 BSON에 대해 공부하는 것도 좋음



  09. YAML (Yet Another Markup Language)


JSON과 비슷한 특징을 가지고 있지만, 중괄호나 큰따옴표를 사용하지 않기 때문에 보다 적은 용량으로 데이터를 직렬화 할 수있음. 그러나 바이너리 규격에 비해서는 여전히 비효율적. 그리고 JSON만큼 범용적으로 사용되고 있지도 않음



  10. XML


아직도 많이 사용되고 있으므로 잘 알아두면 소프트웨어 설정관리, API 이해 등에 도움이 됨


데이터 직렬화를 위한 규격이 필요하고 반드시 XML을 써야할 이유가 없다면 텍스트 기반의 JSON이나 바이너리 기반의 프로토콜 버퍼를 고려할 만함


애플리케이션 설정 파일을 만들기 위한 규격이 필요하면 YAML을 고려할만함. YAML을 사용할 수 없는 환경이라면 그때 XML을 추천. 


  11. 프로토콜 버퍼


구글에서 만든 바이너리 기반의 데이터 직렬화 규격. 


텍스트 기반의 메시지 규격인 JSON, XML 등은 라이브러리만 설치하면 코드안에서 원하는 데이터 규격을 만들 수 있음, 또는 라이브러리를 설치하지 않아도 텍스트 편집기를 이용해 규격만 일치하는 파일을 만들어도 문제 없이 사용가능함. 그러나 프로토콜 버퍼는 메시지 구조를 정의한 스키마 파일을 만들고 컴파일러를 이용해 스키마 파일을 인터페이스 코드로 만들어줘야함. 


프로토콜 버퍼는 메시지만 정의하면 검증, 누락과 관련된 인터페이스를 자동으로 생성하기 때문에 관리의 필요성이 크게 줄어듬. 메시지 크기도 가장 작아서 휴율적이고 빠름. 



  12. Base64


바이너리 데이터를 아스키 코드 일부와 일대일로 매칭되는 문자열로 단순 치환하는 인코딩 방식. 치환한 데이터의 길이는 기존 데이터 길이보다 약 30% 정도 들어나지만, 바이너리 데이터(이미지, 동영상, 음원 같은)를 문자열 기반 데이터로 취급할 수 있게 해줌

바이너리를 직접 문자열 메시지와 함께 첨부할 수 있고 예약 키워드로 사용하는 문자와 충동할 일도 없기 때문. 

만약 HTTP로 큰 파일을 보내야 한다면 HTTP 멀티 파트 기능을 이용하는게 좋음


  13. 데이터 압축


클라이언트와 서버가 받는 부하가 납득할 수있는 수준인지 확인 필요. 얼마나 많은 데이터를 줄이는지 확인하는 것도 필요. 압축 효율이 높아지는 데이터 크기를 미리 알아낸 다음, 보내는 데이터가 이 크기를 넘었을 때만 압축하게 하는 것이 가장 좋음


웹 서비스의 경우, 브라우저가 DEFLATE를 지원하지 않을 수있다는 점도 염두해 두어야함



  14. HTTP


서버와 클라이언트가 텍스트, 이미지, 동영상 등의 데이터를 주고 받을 때 사용하는 프로토콜. 상태가 없는 프로토콜. 


HTTP 응답 코드들 중에서 4xx와 5xx 코드를 주의 깊게 봐야함. 두 에러 코드 모두 클라이언트나 서버 애플리케이션 버그로 발생할 수 있기 때문.


개발자가 HTTP 표준에 부합한 웹 서버를 처음부터 만드는 것은 매우 어렵고 비효율적인 일임. 단순 요청 처리 이외에도 정적 파일 캐시, 로드 밸런스 기능 지원, 압축 및 보안 기능 등 고려해야 할게 많기 때문. 다행히 HTTP 표준에서 정의 하는 기능을 바로 사용할 수 있는 웹 서버 소프트웨어가 있음. 아파치와 Nginx. 아파치는 20년 전부터 사용해온 웹 서버로 안정성이 입증됐고 인증이나 많은 기능을 제공. Nginx는 아파치보다 뛰어난 성능과 가벼운 구조로 많은 인기. 



  15. RESTful API


서버와 클라이언트가 메시지를 주고 받을 때 가장 많이 사용하는 통신 규격. REST란 representational state transfer 약자로 분산시스템을 위한 소프트웨어 아키텍처의 한 형태. RESTful이란 REST의 조건을 만족한다는 뜻임. 


RESTful API는 정해진 표준이나 규격이 없어서 구현하는 사람에 따라 형태가 조금씩 다를 수 있음. 요즘은 많은 커뮤니티나 기업에서 API를 일관성있고 명확하게 만들 수 있도록 제공하는 가이드라인과 관례등을 안내하고 있음


API를 설계할 때는 API를 실제로 사용할 사용자 입장에서 생각해야 함. 


DDOS 또는 클라이언트 버그로 서버 API를 많이 호출할 수 있음. 서버에 부하가 생기는 일을 막기 위해 분당 API 호출을 제한할 정책 필요



  16. HTTPS 


전송계층 프로토콜로 TCP대신 TLS(Transport Layer Security) 프로토콜을 기반으로 하는 HTTP라고 이해하면됨


HTTPS를 사용하면 서버와 클라이언트가 주고 받는 메시지를 암호화하여 제삼자가 볼 수 없음. 


전 세계 모든 사람들에게 무료로 SSL 인증서를 발급해주는 letsencrypt 에서 무료로 인증서를 발급할 수 있음. 유효기간은 3개월이지만 인증서 갱신 자동화 기능을 제공하기 때문에 큰 문제가 되진 않음



  17. OAuth 2.0 


데이터를 간편하고 안전하게 주고 받기 위해 만들어진 표준. 액세스 토큰을 기반으로 사용자를 식별. 토큰은 API를 제공하는 리소스 서버만 발급할 수 있으며 일정 시간이 지나면 폐기 될 수 있음. 토큰에 권한을 설정 가능. 


JSON 웹 토큰 (JWT)을 사용하면 인가 서버를 통해 토큰을 검증 하는 대신 토큰 안에 인가 정보를 포함해 있기 때문에 인가 서버의 부하를 크게 줄일 수 있음. 구글 API는 JWT 기반임 


OAuth 2.0은 가로채기 공격에 취약한 만큼 다양한 방법을 적용하여 조치가 필요. 


반응형