책정리 51

유튜브 설계

14장 유튜브 설계 유튜브는 엄청난 규모의 전 지구적 서비스 문제 이해 및 설계 범위 확정 다음의 기능을 포함한다. 댓글 남기기 비디오 공유 좋아요 누르기 재생목록에 저장 구독 일간 능동 사용자가 5백만이고, 10%의 사용자가 하루에 1비디오 업로드 한다고 가정하자. 비디오의 평균 크기가 300MB라면, 매일 요구되는 저장 용량 150TB이다. 개력적 설계안 제시 및 동의 구하기 CDN을 새롭게 구축할 필요는 없다. (기존 클라우드 서비스 활용) 시스템 설계 면접은 모든 것을 밑바닥부터 만드는 것과는 관계가 없다. ** 저장소를 사용한다, 라고 언급만 해도 충분하다. 규모 확장이 쉬운 CDN을 만드는 것은 지극히 복잡하고, 많은 비용이 드는 일이다. 비디오 업로드 절차 사용자 : 유튜브를 시청하는 이용자..

async, await는 Promise는 제너레이터의 조합이다

콜백 지옥 비동기 프로그래밍을 사용하다 보면, 비동기 호출에 따른 후속 처리를 진행하면서 콜백 함수를 중첩해서 사용하게 되는 경우가 있다. get('/step1', a => { get(`/step2/${a}`, b => { get(`/step3/${b}`, c => { get(`/step4/${c}`, d => { // do something } } } } 이렇게 중첩 함수를 호출하면서 복잡도가 높아지는 현상을 콜백 지옥이라고 부른다. 다음과 같은 코드는 가독성을 나쁘게 하며, 개발 경험 면에서도 부정적인 영향을 끼친다. 또한 비동기 프로그래밍을 사용하면 에러를 캐치하지 못한다는 치명적인 단점이 있다. Promise의 등장 Promise는 ES6에서 도입된 ECMAScript 사양의 표준 빌트인 객체이다..

검색어 자동완성 시스템 설계

13장 검색어 자동완성 시스템 설계 범위 확정 필요한 검색어 자동완성 시스템 단어를 검색할 때 검색어의 첫 부분이 자동 완성된다. 검색 시 5개의 자동 완성 검색어가 표시된다. 인기 순위를 기준으로 5개, 맙춤법 검사나 자동 수정은 지원하지 않는다. 영어만을 사용하고, 모든 질의는 영어 소문자로 한다. DAU는 천만명이다. 요구사항 빠른 응답 속도: 시스템 응답속도 100밀리초 이내 연관성: 사용자가 입력한 단어와 연관된 것이 출력되어야 한다, 개략적 규모 추정 평균 1사람당 매일 10건 검색한다고 가정하고, 20바이트의 데이터를 입력한다고 가정한다. 검색어가 평균적으로 4개의 단어로 이루어진다고 가정하고, 각 단어는 5글자로 구성된다고 했을 때, 20바이트의 데이터를 입력한다고 한다. 검색창에 글자를 ..

채팅 시스템 설계

12장 채팅 시스템 설계 요구 사항 확인 응답 지연이 낮은 1:1, 그룹 채팅 모두 가능한 앱 모바일 & 웹 모두 지원 ⇒ 하나의 계정으로 여러 단말에 동시 접속 지원 5천만 DAU 100명까지 가능한 그룹 채팅 텍스트만 가능, 사요자 접속상태 표시 지원 10,000자 이하 암호화는 필요 없다. 채팅 이력을 영원히 보관해야한다. 개략적 설계안 메시지 발신 시 HTTP 프로토콜을 사용하여 채팅 서비스에 메시지를 보낸다. keep-alive 헤더로 클라이언트와 서버 사이의 연결을 끊지 않고 계속 유지할 수 있다. ⇒ TCP 접속 과정의 핸드세이크 횟수를 줄일 수 있다. 메시지 수신 시 HTTP는 클라이언트가 연결을 만들기 때문에, 서버에서 클라이언트로 메시지를 보내는 데이는 쉽게 쓰일 수 없다. 폴링 클라이..

뉴스 피드 시스템 설계

11장 뉴스 피드 시스템 설계 요구사항 앱, 웹 모두 지원해야한다. 뉴스 피드에 새로운 스토리를 올리고 친구들의 스토리를 볼 수 있도록 한다. 단순히 시간 흐름 역순으로 피드에 표시된다. 한 사람당 최대 5000명의 친구를 가질 수 있다. 매일 천만명이 방문한다. 피드에는 이미지, 비디오 등도 포함될 수 있다. 개략적 설계안 제시 뉴스 피드 시스템에는 크게 2가지 기능이 있다. 피드 발행 사용자가 스토리를 포스팅하면 해당 데이터를 캐시와 데이터베이스에 기록한다. 뉴스 피드 생성 모든 친구의 포스팅을 시간 흐름 역순으로 모아서 만든다. Rest API방식으로 API를 설계한다고 하면, 피드 발행 API는 POST /v1/me/feed 피드 읽기 API는 GET /v1/me/feed로 구현한다. 요청하는 유..

자바스크립트에서의 이벤트 핸들러 등록 방식

브라우저에서는 특정 사건(버튼 클릭, 마우스 스크롤 등)이 발생하면 이벤트를 발생시킨다. 이 때 브라우저가 이벤트를 감지하면 어떤 함수를 수행하도록 이벤트 핸들러를 등록할 수 있다. 그러면 사용자는 애플리케이션과 상호작용이 가능해진다. 이러한 방식의 프로그래밍을 이벤트 드리븐 프로그래밍 이라고 한다. 이벤트 핸들러 등록 방식 이벤트 핸들러 어트리뷰트 방식 버튼 함수 호출문을 할당하여 이벤트 핸들러로 등록한다. 이 경우에는 HTML과 자바스크립트가 섞여있기 때문에 관심사를 분리하기 어렵다는 단점이 있다. 하지만 React/Vue/Angular와 같은 SPA라이브러리에서 이러한 어트리뷰트 방식으로 이벤트를 처리하는 데, HTML, CSS, 자바스크립트 모두 뷰를 구성하기 위한 구성요소로 보기 때문이다. 이벤..

웹 크롤러 설계

9장 웹 크롤러 설계 크롤러는 검색 엔진에서 널리 쓰이는 기술로, 몇 개의 웹 페이지에서 시작하여 그 링크를 계속 따라 나가면서 새로운 콘텐츠를 수집한다. 크롤러 활용 예시 검색 엔진 인덱싱 (Search Engine Indexing) : 크롤러는 웹 페이지를 모아 검색엔진을 위한 로컬 인덱스를 만든다. googlebot 웹 아카이빙 : 정보를 장기보관하기 위해서 정보를 모은다. 보통 국립 도서관에서 아카이빙한다. 웹 마이닝 : 인터넷에서 유용한 지식을 도출해내기 위해 웹 모니터링 : 저작권이나 상표권이 침해되는 사례를 모니터링 1단계 문제 이해 및 설계 범위 확정 규모 확장성 웹에는 수십억개의 페이지가 존재한다. 병행성을 활용하여 효과적으로 웹크롤링 해야한다. 안전 웹은 함정으로 가득하다. 잘못 작성된..

자바스크립트, html로 짠 코드가 브라우저에서 렌더링되는 과정

우리가 자바스크립트, html, css를 사용해서 만든 코드를 크롬에서는 어떻게 해석하여 화면에 보여줄까? 다른 프로그래밍 언어인 자바나 파이썬은 운영체제나 가상 머신 위에서 실행되지만, 자바스크립트는 브라우저에서 html, css과 함께 실행된다는 특징이 있습니다. 즉, 브라우저가 HTML, CSS, 자바스크립트로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력해준다는 뜻입니다. 이 글에서는 이 과정에 대해 좀 더 상세하게 살펴볼 것입니다. 하루만에 제가 간단하게 만든 웹사이트가 있는데요, 다른 기술 없이 오직 html, css, javascript로만 만든 웹사이트입니다. 코드가 궁금하다면 깃헙에서 확인해주세요. 이 페이지를 로딩할 때 개발자 도구의 네트워크 탭을 살펴보면, 순차적으로 필요한 htm..

URL 단축기 설계

8장 URL 단축기 설계 URL 단축기 요구사항 매일 1억개의 단축 URL을 만들어낸다. 단축 URL의 길이는 짧으면 짧을 수록 좋다. 단축 URL에는 숫자(0-9), 영문자만 사용가능하다 만든 URL 정보를 삭제하거나 갱신할 수 없다. 높은 가용성과 규모 확장성, 장애 감내가 요구된다. 개략적 추정 매일 1억개라고 치면 1초당 1160개의 연산을 한다. 읽기 연산과 쓰기 연산의 비율이 10:1의 비율이라고 할 때 초당 11,600회 발생한다. 10년간 운영한다고 가정하면 1억 * 365 * 10 = 3650억개의 레코드를 보관해야하고, url 평균 길이가 100이라면 3650억 * 100 = 36.5tb를 저장해야한다. HTTP Redirect code 301 permanently moved : 브라우..

자바스크립트의 배열은 알고보니 객체였다?

이전 글에서 자바스크립트는 원시값(primitive values)를 제외하고는 모두 내부적으로 객체처럼 동작한다는 언급을 했었는데요. 자바스크립트에서 배열은 원시값에 해당하지 않습니다. 그렇다면 자바스크립트에서 배열은 어떻게 동작할까요? 객체처럼 동작하는 자바스크립트의 배열 자바스크립트에서는 배열을 만들면, Object를 상속하는 Array 클래스를 사용하여 객체를 만듭니다. 예시 코드를 살펴보겠습니다. let arr = []; arr.push(1); arr.push(2); arr.push("Prince"); arr.push("Aditya"); let keys = Object.keys(arr).join(" "); let values = Object.values(arr).join(" "); console...