|
|
|
|
|
<!doctype html>
|
|
|
<html lang="zh" class="no-js">
|
|
|
<head>
|
|
|
|
|
|
<meta charset="utf-8">
|
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
|
|
|
|
<meta name="description" content="开发知识wiki">
|
|
|
|
|
|
|
|
|
<meta name="author" content="tink">
|
|
|
|
|
|
|
|
|
<link rel="canonical" href="https://docs.cyub.vip/dev-wiki/system-design/system-design-primer/solutions/system_design/mint/">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="icon" href="../../../../../images/favicon.ico">
|
|
|
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.4.4">
|
|
|
|
|
|
|
|
|
|
|
|
<title>Design Mint.com - 开发知识wiki</title>
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../assets/stylesheets/main.bd3936ea.min.css">
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../assets/stylesheets/palette.356b1318.min.css">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Fira+Code:300,300i,400,400i,700,700i%7CFira+Code:400,400i,700,700i&display=fallback">
|
|
|
<style>:root{--md-text-font:"Fira Code";--md-code-font:"Fira Code"}</style>
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings1.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings2.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings3.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings4.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings5.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-enum-headings6.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site.css">
|
|
|
|
|
|
<link rel="stylesheet" href="../../../../../css/print-site-material.css">
|
|
|
|
|
|
<script>__md_scope=new URL("../../../../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script id="__analytics">function __md_analytics(){function n(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],n("js",new Date),n("config",""),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&n("event","search",{search_term:this.value})}),document$.subscribe(function(){var a=document.forms.feedback;if(void 0!==a)for(var e of a.querySelectorAll("[type=submit]"))e.addEventListener("click",function(e){e.preventDefault();var t=document.location.pathname,e=this.getAttribute("data-md-value");n("event","feedback",{page:t,data:e}),a.firstElementChild.disabled=!0;e=a.querySelector(".md-feedback__note [data-md-value='"+e+"']");e&&(e.hidden=!1)}),a.hidden=!1}),location$.subscribe(function(e){n("config","",{page_path:e.pathname})})});var e=document.createElement("script");e.async=!0,e.src="https://www.googletagmanager.com/gtag/js?id=",document.getElementById("__analytics").insertAdjacentElement("afterEnd",e)}</script>
|
|
|
|
|
|
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link href="../../../../../assets/stylesheets/glightbox.min.css" rel="stylesheet"/><style>
|
|
|
html.glightbox-open { overflow: initial; height: 100%; }
|
|
|
.gslide-title { margin-top: 0px; user-select: text; }
|
|
|
.gslide-desc { color: #666; user-select: text; }
|
|
|
.gslide-image img { background: white; }
|
|
|
.gscrollbar-fixer { padding-right: 15px; }
|
|
|
.gdesc-inner { font-size: 0.75rem; }
|
|
|
body[data-md-color-scheme="slate"] .gdesc-inner { background: var(--md-default-bg-color);}
|
|
|
body[data-md-color-scheme="slate"] .gslide-title { color: var(--md-default-fg-color);}
|
|
|
body[data-md-color-scheme="slate"] .gslide-desc { color: var(--md-default-fg-color);}</style> <script src="../../../../../assets/javascripts/glightbox.min.js"></script></head>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
|
|
|
|
|
|
|
|
|
|
|
|
<script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
|
|
|
|
|
|
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
|
|
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
|
|
<label class="md-overlay" for="__drawer"></label>
|
|
|
<div data-md-component="skip">
|
|
|
|
|
|
|
|
|
<a href="#design-mintcom" class="md-skip">
|
|
|
跳转至
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
<div data-md-component="announce">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<header class="md-header" data-md-component="header">
|
|
|
<nav class="md-header__inner md-grid" aria-label="页眉">
|
|
|
<a href="../../../../.." title="开发知识wiki" class="md-header__button md-logo" aria-label="开发知识wiki" data-md-component="logo">
|
|
|
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89">
|
|
|
<path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" />
|
|
|
<path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" />
|
|
|
<path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" />
|
|
|
<path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" />
|
|
|
</svg>
|
|
|
|
|
|
</a>
|
|
|
<label class="md-header__button md-icon" for="__drawer">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
|
|
|
</label>
|
|
|
<div class="md-header__title" data-md-component="header-title">
|
|
|
<div class="md-header__ellipsis">
|
|
|
<div class="md-header__topic">
|
|
|
<span class="md-ellipsis">
|
|
|
开发知识wiki
|
|
|
</span>
|
|
|
</div>
|
|
|
<div class="md-header__topic" data-md-component="header-topic">
|
|
|
<span class="md-ellipsis">
|
|
|
|
|
|
Design Mint.com
|
|
|
|
|
|
</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<form class="md-header__option" data-md-component="palette">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
|
|
|
|
|
|
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_3" hidden>
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8v2m9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1 0 1.71-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5 5 5 0 0 0-5-5Z"/></svg>
|
|
|
</label>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_2">
|
|
|
|
|
|
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3Z"/></svg>
|
|
|
</label>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_3">
|
|
|
|
|
|
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_2" hidden>
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5M7 15a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3Z"/></svg>
|
|
|
</label>
|
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-header__button md-icon" for="__search">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
|
|
|
</label>
|
|
|
<div class="md-search" data-md-component="search" role="dialog">
|
|
|
<label class="md-search__overlay" for="__search"></label>
|
|
|
<div class="md-search__inner" role="search">
|
|
|
<form class="md-search__form" name="search">
|
|
|
<input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
|
|
<label class="md-search__icon md-icon" for="__search">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
|
|
|
</label>
|
|
|
<nav class="md-search__options" aria-label="查找">
|
|
|
|
|
|
<a href="javascript:void(0)" class="md-search__icon md-icon" title="分享" aria-label="分享" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7 0-.24-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91 1.61 0 2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08Z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
<button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
|
|
|
</button>
|
|
|
</nav>
|
|
|
|
|
|
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
|
|
|
|
|
</form>
|
|
|
<div class="md-search__output">
|
|
|
<div class="md-search__scrollwrap" data-md-scrollfix>
|
|
|
<div class="md-search-result" data-md-component="search-result">
|
|
|
<div class="md-search-result__meta">
|
|
|
正在初始化搜索引擎
|
|
|
</div>
|
|
|
<ol class="md-search-result__list" role="presentation"></ol>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
<div class="md-container" data-md-component="container">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-tabs" aria-label="标签" data-md-component="tabs">
|
|
|
<div class="md-grid">
|
|
|
<ul class="md-tabs__list">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../.." class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
简介
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../computer-system/io/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
操作系统
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../computer-network/tcp/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
计算机网络
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../database/mysql/%E7%AE%80%E4%BB%8B/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
数据库
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../language/Go/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
开发语言
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
系统设计
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../jupyter/Go-Frameworks-Github-Fork-Stats/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Jupyter
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../video/os/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
视频
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-tabs__item">
|
|
|
<a href="../../../../../qa/redis/" class="md-tabs__link">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QA
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</div>
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
|
|
<main class="md-main" data-md-component="main">
|
|
|
<div class="md-main__inner md-grid">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
|
|
<div class="md-sidebar__scrollwrap">
|
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="导航栏" data-md-level="0">
|
|
|
<label class="md-nav__title" for="__drawer">
|
|
|
<a href="../../../../.." title="开发知识wiki" class="md-nav__button md-logo" aria-label="开发知识wiki" data-md-component="logo">
|
|
|
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89">
|
|
|
<path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" />
|
|
|
<path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" />
|
|
|
<path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" />
|
|
|
<path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" />
|
|
|
</svg>
|
|
|
|
|
|
</a>
|
|
|
开发知识wiki
|
|
|
</label>
|
|
|
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../.." class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
简介
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
操作系统
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_2">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
操作系统
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/io/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
IO
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/proc/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
proc文件系统
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/nptl/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
NPTL
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_4" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_2_4" id="__nav_2_4_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
容器
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_4_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_2_4">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
容器
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../container/install/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
简介
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../container/image/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
镜像
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../container/cgroup/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
cgroup
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../container/namespace/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
namespace
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/command/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
常用命令
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/systemtap/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Systemtap
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/cpu-arch/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
CPU架构
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-system/compiling-linux-kernel/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
编译Linux内核
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
|
<a href="../../../../../computer-network/tcp/" class="md-nav__link ">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
计算机网络
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_3" id="__nav_3_label" tabindex="">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_3">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
计算机网络
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../computer-network/http/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
HTTP
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
数据库
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_4">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
数据库
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_1" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_4_1" id="__nav_4_1_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
mysql
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_1_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_4_1">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
mysql
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/mysql/%E7%AE%80%E4%BB%8B/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
概览
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/mysql/%E4%BA%8B%E5%8A%A1/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
事务
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/mysql/%E7%B4%A2%E5%BC%95/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
索引
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/mysql/FAQ/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
FAQ
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_2" >
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
|
<a href="../../../../../database/elasticsearch/" class="md-nav__link ">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Elasticsearch
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_4_2" id="__nav_4_2_label" tabindex="">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_2_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_4_2">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
Elasticsearch
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/elasticsearch/memory/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
内存占用
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/elasticsearch/performance_tuning/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
性能调优
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/elasticsearch/production_configuring/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
生产配置参考
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/elasticsearch/doc_values_and_fielddata/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
docs value与 field data
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../database/redis/redis/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Redis
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
开发语言
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_5">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
开发语言
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../language/Go/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Go
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
|
<a href="../../../../" class="md-nav__link ">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
系统设计
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_6" id="__nav_6_label" tabindex="">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_6">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
系统设计
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../cache/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
缓存系统
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
系统设计入门
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_4" >
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-nav__link md-nav__container">
|
|
|
<a href="../../../../../what-should-you-know/" class="md-nav__link ">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
what you should know
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
|
|
|
|
|
|
<label class="md-nav__link " for="__nav_6_4" id="__nav_6_4_label" tabindex="">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_6_4_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_6_4">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
what you should know
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/GPU/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
每个开发人员都应该了解 GPU 计算的知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/hardware/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
每个程序员都应该了解的硬件知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_4_4" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_6_4_4" id="__nav_6_4_4_label" tabindex="0">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
每个程序员都应该了解的内存知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_6_4_4_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_6_4_4">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
每个程序员都应该了解的内存知识
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E5%BA%94%E8%AF%A5%E4%BA%86%E8%A7%A3%E7%9A%84%E5%86%85%E5%AD%98%E7%9F%A5%E8%AF%86/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
【总结版】每个程序员都应该了解的内存知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/What%20Every%20Programmer%20Should%20Know%20About%20Memory.pdf" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
【英文】What Every Programmer Should Know About Memory
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/%E6%AF%8F%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E9%83%BD%E5%BA%94%E8%AF%A5%E4%BA%86%E8%A7%A3%E7%9A%84%E5%86%85%E5%AD%98%E7%9F%A5%E8%AF%86.pdf" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
【中文】每个程序员都应该了解的内存知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_4_5" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_6_4_5" id="__nav_6_4_5_label" tabindex="0">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
每个系统程序员都应该了解的并发知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_6_4_5_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_6_4_5">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
每个系统程序员都应该了解的并发知识
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../what-should-you-know/concurrency-primer.pdf" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
【英文】What every systems programmer should know about concurrency
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="https://www.bilibili.com/read/cv26734224" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
【中文】每个系统程序员都应该了解的并发知识
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Jupyter
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_7">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
Jupyter
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../jupyter/Go-Frameworks-Github-Fork-Stats/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Go-Frameworks-Github-Fork-Stats
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../jupyter/Pandas%E5%AE%8C%E5%85%A8%E6%8C%87%E5%8D%97/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Pandas完全指南
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7_3" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_7_3" id="__nav_7_3_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Spark上手示例
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_7_3_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_7_3">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
Spark上手示例
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../jupyter/Spark%E4%B8%8A%E6%89%8B%E7%A4%BA%E4%BE%8B1%EF%BC%9ARDD%E6%93%8D%E4%BD%9C/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Spark上手示例1:RDD操作
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../jupyter/Spark%E4%B8%8A%E6%89%8B%E7%A4%BA%E4%BE%8B2%EF%BC%9ADataFrame%E6%93%8D%E4%BD%9C/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Spark上手示例2:DataFrame操作
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
视频
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_8">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
视频
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../video/os/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
操作系统
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../video/Data%20structures/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
数据结构与算法
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../video/c_c%2B%2B/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
C/C++
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../video/Go/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Go
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_9" >
|
|
|
|
|
|
|
|
|
<label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
QA
|
|
|
</span>
|
|
|
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
</label>
|
|
|
|
|
|
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
|
|
|
<label class="md-nav__title" for="__nav_9">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
QA
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-scrollfix>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/redis/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
redis
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/mysql/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
mysql
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/tcp/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
tcp
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/http/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
http
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/cache/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
缓存
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/nginx/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
nginx
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/queue/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
消息队列
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/io/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
IO
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/protobuf/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
protobuf
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/go/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
go
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/dist/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
分布式
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/es/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
Elasticsearch
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/docker/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
docker
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="../../../../../qa/ref/" class="md-nav__link">
|
|
|
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
|
参考资料
|
|
|
</span>
|
|
|
|
|
|
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
|
|
<div class="md-sidebar__scrollwrap">
|
|
|
<div class="md-sidebar__inner">
|
|
|
|
|
|
|
|
|
<nav class="md-nav md-nav--secondary" aria-label="目录">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<label class="md-nav__title" for="__toc">
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
|
目录
|
|
|
</label>
|
|
|
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#step-1-outline-use-cases-and-constraints" class="md-nav__link">
|
|
|
Step 1: Outline use cases and constraints
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Step 1: Outline use cases and constraints">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#use-cases" class="md-nav__link">
|
|
|
Use cases
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Use cases">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#well-scope-the-problem-to-handle-only-the-following-use-cases" class="md-nav__link">
|
|
|
We'll scope the problem to handle only the following use cases
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#out-of-scope" class="md-nav__link">
|
|
|
Out of scope
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#constraints-and-assumptions" class="md-nav__link">
|
|
|
Constraints and assumptions
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Constraints and assumptions">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#state-assumptions" class="md-nav__link">
|
|
|
State assumptions
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#calculate-usage" class="md-nav__link">
|
|
|
Calculate usage
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#step-2-create-a-high-level-design" class="md-nav__link">
|
|
|
Step 2: Create a high level design
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#step-3-design-core-components" class="md-nav__link">
|
|
|
Step 3: Design core components
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Step 3: Design core components">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#use-case-user-connects-to-a-financial-account" class="md-nav__link">
|
|
|
Use case: User connects to a financial account
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#use-case-service-extracts-transactions-from-the-account" class="md-nav__link">
|
|
|
Use case: Service extracts transactions from the account
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Use case: Service extracts transactions from the account">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#category-service" class="md-nav__link">
|
|
|
Category service
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#use-case-service-recommends-a-budget" class="md-nav__link">
|
|
|
Use case: Service recommends a budget
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#step-4-scale-the-design" class="md-nav__link">
|
|
|
Step 4: Scale the design
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#additional-talking-points" class="md-nav__link">
|
|
|
Additional talking points
|
|
|
</a>
|
|
|
|
|
|
<nav class="md-nav" aria-label="Additional talking points">
|
|
|
<ul class="md-nav__list">
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#nosql" class="md-nav__link">
|
|
|
NoSQL
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#caching" class="md-nav__link">
|
|
|
Caching
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#asynchronism-and-microservices" class="md-nav__link">
|
|
|
Asynchronism and microservices
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#communications" class="md-nav__link">
|
|
|
Communications
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#security" class="md-nav__link">
|
|
|
Security
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#latency-numbers" class="md-nav__link">
|
|
|
Latency numbers
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
<li class="md-nav__item">
|
|
|
<a href="#ongoing" class="md-nav__link">
|
|
|
Ongoing
|
|
|
</a>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</nav>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-content" data-md-component="content">
|
|
|
<article class="md-content__inner md-typeset">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h1 id="design-mintcom">Design Mint.com<a class="headerlink" href="#design-mintcom" title="Permanent link">¶</a></h1>
|
|
|
<p><em>Note: This document links directly to relevant areas found in the <a href="https://github.com/donnemartin/system-design-primer#index-of-system-design-topics">system design topics</a> to avoid duplication. Refer to the linked content for general talking points, tradeoffs, and alternatives.</em></p>
|
|
|
<h2 id="step-1-outline-use-cases-and-constraints">Step 1: Outline use cases and constraints<a class="headerlink" href="#step-1-outline-use-cases-and-constraints" title="Permanent link">¶</a></h2>
|
|
|
<blockquote>
|
|
|
<p>Gather requirements and scope the problem.
|
|
|
Ask questions to clarify use cases and constraints.
|
|
|
Discuss assumptions.</p>
|
|
|
</blockquote>
|
|
|
<p>Without an interviewer to address clarifying questions, we'll define some use cases and constraints.</p>
|
|
|
<h3 id="use-cases">Use cases<a class="headerlink" href="#use-cases" title="Permanent link">¶</a></h3>
|
|
|
<h4 id="well-scope-the-problem-to-handle-only-the-following-use-cases">We'll scope the problem to handle only the following use cases<a class="headerlink" href="#well-scope-the-problem-to-handle-only-the-following-use-cases" title="Permanent link">¶</a></h4>
|
|
|
<ul>
|
|
|
<li><strong>User</strong> connects to a financial account</li>
|
|
|
<li><strong>Service</strong> extracts transactions from the account<ul>
|
|
|
<li>Updates daily</li>
|
|
|
<li>Categorizes transactions<ul>
|
|
|
<li>Allows manual category override by the user</li>
|
|
|
<li>No automatic re-categorization</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>Analyzes monthly spending, by category</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li><strong>Service</strong> recommends a budget<ul>
|
|
|
<li>Allows users to manually set a budget</li>
|
|
|
<li>Sends notifications when approaching or exceeding budget</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li><strong>Service</strong> has high availability</li>
|
|
|
</ul>
|
|
|
<h4 id="out-of-scope">Out of scope<a class="headerlink" href="#out-of-scope" title="Permanent link">¶</a></h4>
|
|
|
<ul>
|
|
|
<li><strong>Service</strong> performs additional logging and analytics</li>
|
|
|
</ul>
|
|
|
<h3 id="constraints-and-assumptions">Constraints and assumptions<a class="headerlink" href="#constraints-and-assumptions" title="Permanent link">¶</a></h3>
|
|
|
<h4 id="state-assumptions">State assumptions<a class="headerlink" href="#state-assumptions" title="Permanent link">¶</a></h4>
|
|
|
<ul>
|
|
|
<li>Traffic is not evenly distributed</li>
|
|
|
<li>Automatic daily update of accounts applies only to users active in the past 30 days</li>
|
|
|
<li>Adding or removing financial accounts is relatively rare</li>
|
|
|
<li>Budget notifications don't need to be instant</li>
|
|
|
<li>10 million users<ul>
|
|
|
<li>10 budget categories per user = 100 million budget items</li>
|
|
|
<li>Example categories:<ul>
|
|
|
<li>Housing = $1,000</li>
|
|
|
<li>Food = $200</li>
|
|
|
<li>Gas = $100</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>Sellers are used to determine transaction category<ul>
|
|
|
<li>50,000 sellers</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>30 million financial accounts</li>
|
|
|
<li>5 billion transactions per month</li>
|
|
|
<li>500 million read requests per month</li>
|
|
|
<li>10:1 write to read ratio<ul>
|
|
|
<li>Write-heavy, users make transactions daily, but few visit the site daily</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<h4 id="calculate-usage">Calculate usage<a class="headerlink" href="#calculate-usage" title="Permanent link">¶</a></h4>
|
|
|
<p><strong>Clarify with your interviewer if you should run back-of-the-envelope usage calculations.</strong></p>
|
|
|
<ul>
|
|
|
<li>Size per transaction:<ul>
|
|
|
<li><code>user_id</code> - 8 bytes</li>
|
|
|
<li><code>created_at</code> - 5 bytes</li>
|
|
|
<li><code>seller</code> - 32 bytes</li>
|
|
|
<li><code>amount</code> - 5 bytes</li>
|
|
|
<li>Total: ~50 bytes</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>250 GB of new transaction content per month<ul>
|
|
|
<li>50 bytes per transaction * 5 billion transactions per month</li>
|
|
|
<li>9 TB of new transaction content in 3 years</li>
|
|
|
<li>Assume most are new transactions instead of updates to existing ones</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>2,000 transactions per second on average</li>
|
|
|
<li>200 read requests per second on average</li>
|
|
|
</ul>
|
|
|
<p>Handy conversion guide:</p>
|
|
|
<ul>
|
|
|
<li>2.5 million seconds per month</li>
|
|
|
<li>1 request per second = 2.5 million requests per month</li>
|
|
|
<li>40 requests per second = 100 million requests per month</li>
|
|
|
<li>400 requests per second = 1 billion requests per month</li>
|
|
|
</ul>
|
|
|
<h2 id="step-2-create-a-high-level-design">Step 2: Create a high level design<a class="headerlink" href="#step-2-create-a-high-level-design" title="Permanent link">¶</a></h2>
|
|
|
<blockquote>
|
|
|
<p>Outline a high level design with all important components.</p>
|
|
|
</blockquote>
|
|
|
<p><a class="glightbox" href="http://i.imgur.com/E8klrBh.png" data-type="image" data-width="auto" data-height="auto" data-desc-position="bottom"><img alt="Imgur" src="http://i.imgur.com/E8klrBh.png" /></a></p>
|
|
|
<h2 id="step-3-design-core-components">Step 3: Design core components<a class="headerlink" href="#step-3-design-core-components" title="Permanent link">¶</a></h2>
|
|
|
<blockquote>
|
|
|
<p>Dive into details for each core component.</p>
|
|
|
</blockquote>
|
|
|
<h3 id="use-case-user-connects-to-a-financial-account">Use case: User connects to a financial account<a class="headerlink" href="#use-case-user-connects-to-a-financial-account" title="Permanent link">¶</a></h3>
|
|
|
<p>We could store info on the 10 million users in a <a href="https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms">relational database</a>. We should discuss the <a href="https://github.com/donnemartin/system-design-primer#sql-or-nosql">use cases and tradeoffs between choosing SQL or NoSQL</a>.</p>
|
|
|
<ul>
|
|
|
<li>The <strong>Client</strong> sends a request to the <strong>Web Server</strong>, running as a <a href="https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server">reverse proxy</a></li>
|
|
|
<li>The <strong>Web Server</strong> forwards the request to the <strong>Accounts API</strong> server</li>
|
|
|
<li>The <strong>Accounts API</strong> server updates the <strong>SQL Database</strong> <code>accounts</code> table with the newly entered account info</li>
|
|
|
</ul>
|
|
|
<p><strong>Clarify with your interviewer how much code you are expected to write</strong>.</p>
|
|
|
<p>The <code>accounts</code> table could have the following structure:</p>
|
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>id int NOT NULL AUTO_INCREMENT
|
|
|
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>created_at datetime NOT NULL
|
|
|
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>last_update datetime NOT NULL
|
|
|
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>account_url varchar(255) NOT NULL
|
|
|
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>account_login varchar(32) NOT NULL
|
|
|
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>account_password_hash char(64) NOT NULL
|
|
|
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>user_id int NOT NULL
|
|
|
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>PRIMARY KEY(id)
|
|
|
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>FOREIGN KEY(user_id) REFERENCES users(id)
|
|
|
</span></code></pre></div>
|
|
|
<p>We'll create an <a href="https://github.com/donnemartin/system-design-primer#use-good-indices">index</a> on <code>id</code>, <code>user_id</code>, and <code>created_at</code> to speed up lookups (log-time instead of scanning the entire table) and to keep the data in memory. Reading 1 MB sequentially from memory takes about 250 microseconds, while reading from SSD takes 4x and from disk takes 80x longer.<sup><a href=https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know>1</a></sup></p>
|
|
|
<p>We'll use a public <a href="https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest"><strong>REST API</strong></a>:</p>
|
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>$ curl -X POST --data '{ "user_id": "foo", "account_url": "bar", \
|
|
|
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a> "account_login": "baz", "account_password": "qux" }' \
|
|
|
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a> https://mint.com/api/v1/account
|
|
|
</span></code></pre></div>
|
|
|
<p>For internal communications, we could use <a href="https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc">Remote Procedure Calls</a>.</p>
|
|
|
<p>Next, the service extracts transactions from the account.</p>
|
|
|
<h3 id="use-case-service-extracts-transactions-from-the-account">Use case: Service extracts transactions from the account<a class="headerlink" href="#use-case-service-extracts-transactions-from-the-account" title="Permanent link">¶</a></h3>
|
|
|
<p>We'll want to extract information from an account in these cases:</p>
|
|
|
<ul>
|
|
|
<li>The user first links the account</li>
|
|
|
<li>The user manually refreshes the account</li>
|
|
|
<li>Automatically each day for users who have been active in the past 30 days</li>
|
|
|
</ul>
|
|
|
<p>Data flow:</p>
|
|
|
<ul>
|
|
|
<li>The <strong>Client</strong> sends a request to the <strong>Web Server</strong></li>
|
|
|
<li>The <strong>Web Server</strong> forwards the request to the <strong>Accounts API</strong> server</li>
|
|
|
<li>The <strong>Accounts API</strong> server places a job on a <strong>Queue</strong> such as <a href="https://aws.amazon.com/sqs/">Amazon SQS</a> or <a href="https://www.rabbitmq.com/">RabbitMQ</a><ul>
|
|
|
<li>Extracting transactions could take awhile, we'd probably want to do this <a href="https://github.com/donnemartin/system-design-primer#asynchronism">asynchronously with a queue</a>, although this introduces additional complexity</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>The <strong>Transaction Extraction Service</strong> does the following:<ul>
|
|
|
<li>Pulls from the <strong>Queue</strong> and extracts transactions for the given account from the financial institution, storing the results as raw log files in the <strong>Object Store</strong></li>
|
|
|
<li>Uses the <strong>Category Service</strong> to categorize each transaction</li>
|
|
|
<li>Uses the <strong>Budget Service</strong> to calculate aggregate monthly spending by category<ul>
|
|
|
<li>The <strong>Budget Service</strong> uses the <strong>Notification Service</strong> to let users know if they are nearing or have exceeded their budget</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>Updates the <strong>SQL Database</strong> <code>transactions</code> table with categorized transactions</li>
|
|
|
<li>Updates the <strong>SQL Database</strong> <code>monthly_spending</code> table with aggregate monthly spending by category</li>
|
|
|
<li>Notifies the user the transactions have completed through the <strong>Notification Service</strong>:<ul>
|
|
|
<li>Uses a <strong>Queue</strong> (not pictured) to asynchronously send out notifications</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<p>The <code>transactions</code> table could have the following structure:</p>
|
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>id int NOT NULL AUTO_INCREMENT
|
|
|
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a>created_at datetime NOT NULL
|
|
|
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a>seller varchar(32) NOT NULL
|
|
|
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a>amount decimal NOT NULL
|
|
|
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a>user_id int NOT NULL
|
|
|
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a>PRIMARY KEY(id)
|
|
|
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a>FOREIGN KEY(user_id) REFERENCES users(id)
|
|
|
</span></code></pre></div>
|
|
|
<p>We'll create an <a href="https://github.com/donnemartin/system-design-primer#use-good-indices">index</a> on <code>id</code>, <code>user_id</code>, and <code>created_at</code>.</p>
|
|
|
<p>The <code>monthly_spending</code> table could have the following structure:</p>
|
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>id int NOT NULL AUTO_INCREMENT
|
|
|
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>month_year date NOT NULL
|
|
|
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a>category varchar(32)
|
|
|
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a>amount decimal NOT NULL
|
|
|
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a>user_id int NOT NULL
|
|
|
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a>PRIMARY KEY(id)
|
|
|
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a>FOREIGN KEY(user_id) REFERENCES users(id)
|
|
|
</span></code></pre></div>
|
|
|
<p>We'll create an <a href="https://github.com/donnemartin/system-design-primer#use-good-indices">index</a> on <code>id</code> and <code>user_id</code>.</p>
|
|
|
<h4 id="category-service">Category service<a class="headerlink" href="#category-service" title="Permanent link">¶</a></h4>
|
|
|
<p>For the <strong>Category Service</strong>, we can seed a seller-to-category dictionary with the most popular sellers. If we estimate 50,000 sellers and estimate each entry to take less than 255 bytes, the dictionary would only take about 12 MB of memory.</p>
|
|
|
<p><strong>Clarify with your interviewer how much code you are expected to write</strong>.</p>
|
|
|
<div class="language-python highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="k">class</span> <span class="nc">DefaultCategories</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
|
|
|
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>
|
|
|
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a> <span class="n">HOUSING</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a> <span class="n">FOOD</span> <span class="o">=</span> <span class="mi">1</span>
|
|
|
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> <span class="n">GAS</span> <span class="o">=</span> <span class="mi">2</span>
|
|
|
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a> <span class="n">SHOPPING</span> <span class="o">=</span> <span class="mi">3</span>
|
|
|
</span><span id="__span-4-7"><a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-4-8"><a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a>
|
|
|
</span><span id="__span-4-9"><a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="n">seller_category_map</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
</span><span id="__span-4-10"><a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="n">seller_category_map</span><span class="p">[</span><span class="s1">'Exxon'</span><span class="p">]</span> <span class="o">=</span> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">GAS</span>
|
|
|
</span><span id="__span-4-11"><a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="n">seller_category_map</span><span class="p">[</span><span class="s1">'Target'</span><span class="p">]</span> <span class="o">=</span> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">SHOPPING</span>
|
|
|
</span><span id="__span-4-12"><a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="o">...</span>
|
|
|
</span></code></pre></div>
|
|
|
<p>For sellers not initially seeded in the map, we could use a crowdsourcing effort by evaluating the manual category overrides our users provide. We could use a heap to quickly lookup the top manual override per seller in O(1) time.</p>
|
|
|
<div class="language-python highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="k">class</span> <span class="nc">Categorizer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
|
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>
|
|
|
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">seller_category_map</span><span class="p">,</span> <span class="n">seller_category_crowd_overrides_map</span><span class="p">):</span>
|
|
|
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_map</span> <span class="o">=</span> <span class="n">seller_category_map</span>
|
|
|
</span><span id="__span-5-5"><a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_crowd_overrides_map</span> <span class="o">=</span> \
|
|
|
</span><span id="__span-5-6"><a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="n">seller_category_crowd_overrides_map</span>
|
|
|
</span><span id="__span-5-7"><a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a>
|
|
|
</span><span id="__span-5-8"><a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="k">def</span> <span class="nf">categorize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transaction</span><span class="p">):</span>
|
|
|
</span><span id="__span-5-9"><a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> <span class="k">if</span> <span class="n">transaction</span><span class="o">.</span><span class="n">seller</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_map</span><span class="p">:</span>
|
|
|
</span><span id="__span-5-10"><a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_map</span><span class="p">[</span><span class="n">transaction</span><span class="o">.</span><span class="n">seller</span><span class="p">]</span>
|
|
|
</span><span id="__span-5-11"><a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="k">elif</span> <span class="n">transaction</span><span class="o">.</span><span class="n">seller</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_crowd_overrides_map</span><span class="p">:</span>
|
|
|
</span><span id="__span-5-12"><a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_map</span><span class="p">[</span><span class="n">transaction</span><span class="o">.</span><span class="n">seller</span><span class="p">]</span> <span class="o">=</span> \
|
|
|
</span><span id="__span-5-13"><a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_crowd_overrides_map</span><span class="p">[</span><span class="n">transaction</span><span class="o">.</span><span class="n">seller</span><span class="p">]</span><span class="o">.</span><span class="n">peek_min</span><span class="p">()</span>
|
|
|
</span><span id="__span-5-14"><a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">seller_category_map</span><span class="p">[</span><span class="n">transaction</span><span class="o">.</span><span class="n">seller</span><span class="p">]</span>
|
|
|
</span><span id="__span-5-15"><a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="k">return</span> <span class="kc">None</span>
|
|
|
</span></code></pre></div>
|
|
|
<p>Transaction implementation:</p>
|
|
|
<div class="language-python highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="k">class</span> <span class="nc">Transaction</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
|
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>
|
|
|
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">created_at</span><span class="p">,</span> <span class="n">seller</span><span class="p">,</span> <span class="n">amount</span><span class="p">):</span>
|
|
|
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a> <span class="bp">self</span><span class="o">.</span><span class="n">created_at</span> <span class="o">=</span> <span class="n">created_at</span>
|
|
|
</span><span id="__span-6-5"><a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a> <span class="bp">self</span><span class="o">.</span><span class="n">seller</span> <span class="o">=</span> <span class="n">seller</span>
|
|
|
</span><span id="__span-6-6"><a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span>
|
|
|
</span></code></pre></div>
|
|
|
<h3 id="use-case-service-recommends-a-budget">Use case: Service recommends a budget<a class="headerlink" href="#use-case-service-recommends-a-budget" title="Permanent link">¶</a></h3>
|
|
|
<p>To start, we could use a generic budget template that allocates category amounts based on income tiers. Using this approach, we would not have to store the 100 million budget items identified in the constraints, only those that the user overrides. If a user overrides a budget category, which we could store the override in the <code>TABLE budget_overrides</code>.</p>
|
|
|
<div class="language-python highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="k">class</span> <span class="nc">Budget</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
|
|
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>
|
|
|
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">income</span><span class="p">):</span>
|
|
|
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> <span class="bp">self</span><span class="o">.</span><span class="n">income</span> <span class="o">=</span> <span class="n">income</span>
|
|
|
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> <span class="bp">self</span><span class="o">.</span><span class="n">categories_to_budget_map</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_budget_template</span><span class="p">()</span>
|
|
|
</span><span id="__span-7-6"><a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a>
|
|
|
</span><span id="__span-7-7"><a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="k">def</span> <span class="nf">create_budget_template</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
|
</span><span id="__span-7-8"><a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a> <span class="k">return</span> <span class="p">{</span>
|
|
|
</span><span id="__span-7-9"><a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">HOUSING</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">income</span> <span class="o">*</span> <span class="mf">.4</span><span class="p">,</span>
|
|
|
</span><span id="__span-7-10"><a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">FOOD</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">income</span> <span class="o">*</span> <span class="mf">.2</span><span class="p">,</span>
|
|
|
</span><span id="__span-7-11"><a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">GAS</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">income</span> <span class="o">*</span> <span class="mf">.1</span><span class="p">,</span>
|
|
|
</span><span id="__span-7-12"><a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a> <span class="n">DefaultCategories</span><span class="o">.</span><span class="n">SHOPPING</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">income</span> <span class="o">*</span> <span class="mf">.2</span><span class="p">,</span>
|
|
|
</span><span id="__span-7-13"><a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-7-14"><a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a> <span class="p">}</span>
|
|
|
</span><span id="__span-7-15"><a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a>
|
|
|
</span><span id="__span-7-16"><a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a> <span class="k">def</span> <span class="nf">override_category_budget</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">category</span><span class="p">,</span> <span class="n">amount</span><span class="p">):</span>
|
|
|
</span><span id="__span-7-17"><a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a> <span class="bp">self</span><span class="o">.</span><span class="n">categories_to_budget_map</span><span class="p">[</span><span class="n">category</span><span class="p">]</span> <span class="o">=</span> <span class="n">amount</span>
|
|
|
</span></code></pre></div>
|
|
|
<p>For the <strong>Budget Service</strong>, we can potentially run SQL queries on the <code>transactions</code> table to generate the <code>monthly_spending</code> aggregate table. The <code>monthly_spending</code> table would likely have much fewer rows than the total 5 billion transactions, since users typically have many transactions per month.</p>
|
|
|
<p>As an alternative, we can run <strong>MapReduce</strong> jobs on the raw transaction files to:</p>
|
|
|
<ul>
|
|
|
<li>Categorize each transaction</li>
|
|
|
<li>Generate aggregate monthly spending by category</li>
|
|
|
</ul>
|
|
|
<p>Running analyses on the transaction files could significantly reduce the load on the database.</p>
|
|
|
<p>We could call the <strong>Budget Service</strong> to re-run the analysis if the user updates a category.</p>
|
|
|
<p><strong>Clarify with your interviewer how much code you are expected to write</strong>.</p>
|
|
|
<p>Sample log file format, tab delimited:</p>
|
|
|
<div class="language-text highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>user_id timestamp seller amount
|
|
|
</span></code></pre></div>
|
|
|
<p><strong>MapReduce</strong> implementation:</p>
|
|
|
<div class="language-python highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="k">class</span> <span class="nc">SpendingByCategory</span><span class="p">(</span><span class="n">MRJob</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>
|
|
|
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">categorizer</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a> <span class="bp">self</span><span class="o">.</span><span class="n">categorizer</span> <span class="o">=</span> <span class="n">categorizer</span>
|
|
|
</span><span id="__span-9-5"><a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a> <span class="bp">self</span><span class="o">.</span><span class="n">current_year_month</span> <span class="o">=</span> <span class="n">calc_current_year_month</span><span class="p">()</span>
|
|
|
</span><span id="__span-9-6"><a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-9-7"><a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a>
|
|
|
</span><span id="__span-9-8"><a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a> <span class="k">def</span> <span class="nf">calc_current_year_month</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-9"><a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a><span class="w"> </span><span class="sd">"""Return the current year and month."""</span>
|
|
|
</span><span id="__span-9-10"><a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-9-11"><a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a>
|
|
|
</span><span id="__span-9-12"><a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a> <span class="k">def</span> <span class="nf">extract_year_month</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-13"><a id="__codelineno-9-13" name="__codelineno-9-13" href="#__codelineno-9-13"></a><span class="w"> </span><span class="sd">"""Return the year and month portions of the timestamp."""</span>
|
|
|
</span><span id="__span-9-14"><a id="__codelineno-9-14" name="__codelineno-9-14" href="#__codelineno-9-14"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-9-15"><a id="__codelineno-9-15" name="__codelineno-9-15" href="#__codelineno-9-15"></a>
|
|
|
</span><span id="__span-9-16"><a id="__codelineno-9-16" name="__codelineno-9-16" href="#__codelineno-9-16"></a> <span class="k">def</span> <span class="nf">handle_budget_notifications</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">total</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-17"><a id="__codelineno-9-17" name="__codelineno-9-17" href="#__codelineno-9-17"></a><span class="w"> </span><span class="sd">"""Call notification API if nearing or exceeded budget."""</span>
|
|
|
</span><span id="__span-9-18"><a id="__codelineno-9-18" name="__codelineno-9-18" href="#__codelineno-9-18"></a> <span class="o">...</span>
|
|
|
</span><span id="__span-9-19"><a id="__codelineno-9-19" name="__codelineno-9-19" href="#__codelineno-9-19"></a>
|
|
|
</span><span id="__span-9-20"><a id="__codelineno-9-20" name="__codelineno-9-20" href="#__codelineno-9-20"></a> <span class="k">def</span> <span class="nf">mapper</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-21"><a id="__codelineno-9-21" name="__codelineno-9-21" href="#__codelineno-9-21"></a><span class="w"> </span><span class="sd">"""Parse each log line, extract and transform relevant lines.</span>
|
|
|
</span><span id="__span-9-22"><a id="__codelineno-9-22" name="__codelineno-9-22" href="#__codelineno-9-22"></a>
|
|
|
</span><span id="__span-9-23"><a id="__codelineno-9-23" name="__codelineno-9-23" href="#__codelineno-9-23"></a><span class="sd"> Argument line will be of the form:</span>
|
|
|
</span><span id="__span-9-24"><a id="__codelineno-9-24" name="__codelineno-9-24" href="#__codelineno-9-24"></a>
|
|
|
</span><span id="__span-9-25"><a id="__codelineno-9-25" name="__codelineno-9-25" href="#__codelineno-9-25"></a><span class="sd"> user_id timestamp seller amount</span>
|
|
|
</span><span id="__span-9-26"><a id="__codelineno-9-26" name="__codelineno-9-26" href="#__codelineno-9-26"></a>
|
|
|
</span><span id="__span-9-27"><a id="__codelineno-9-27" name="__codelineno-9-27" href="#__codelineno-9-27"></a><span class="sd"> Using the categorizer to convert seller to category,</span>
|
|
|
</span><span id="__span-9-28"><a id="__codelineno-9-28" name="__codelineno-9-28" href="#__codelineno-9-28"></a><span class="sd"> emit key value pairs of the form:</span>
|
|
|
</span><span id="__span-9-29"><a id="__codelineno-9-29" name="__codelineno-9-29" href="#__codelineno-9-29"></a>
|
|
|
</span><span id="__span-9-30"><a id="__codelineno-9-30" name="__codelineno-9-30" href="#__codelineno-9-30"></a><span class="sd"> (user_id, 2016-01, shopping), 25</span>
|
|
|
</span><span id="__span-9-31"><a id="__codelineno-9-31" name="__codelineno-9-31" href="#__codelineno-9-31"></a><span class="sd"> (user_id, 2016-01, shopping), 100</span>
|
|
|
</span><span id="__span-9-32"><a id="__codelineno-9-32" name="__codelineno-9-32" href="#__codelineno-9-32"></a><span class="sd"> (user_id, 2016-01, gas), 50</span>
|
|
|
</span><span id="__span-9-33"><a id="__codelineno-9-33" name="__codelineno-9-33" href="#__codelineno-9-33"></a><span class="sd"> """</span>
|
|
|
</span><span id="__span-9-34"><a id="__codelineno-9-34" name="__codelineno-9-34" href="#__codelineno-9-34"></a> <span class="n">user_id</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">,</span> <span class="n">seller</span><span class="p">,</span> <span class="n">amount</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">'</span><span class="p">)</span>
|
|
|
</span><span id="__span-9-35"><a id="__codelineno-9-35" name="__codelineno-9-35" href="#__codelineno-9-35"></a> <span class="n">category</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">categorizer</span><span class="o">.</span><span class="n">categorize</span><span class="p">(</span><span class="n">seller</span><span class="p">)</span>
|
|
|
</span><span id="__span-9-36"><a id="__codelineno-9-36" name="__codelineno-9-36" href="#__codelineno-9-36"></a> <span class="n">period</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">extract_year_month</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span>
|
|
|
</span><span id="__span-9-37"><a id="__codelineno-9-37" name="__codelineno-9-37" href="#__codelineno-9-37"></a> <span class="k">if</span> <span class="n">period</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_year_month</span><span class="p">:</span>
|
|
|
</span><span id="__span-9-38"><a id="__codelineno-9-38" name="__codelineno-9-38" href="#__codelineno-9-38"></a> <span class="k">yield</span> <span class="p">(</span><span class="n">user_id</span><span class="p">,</span> <span class="n">period</span><span class="p">,</span> <span class="n">category</span><span class="p">),</span> <span class="n">amount</span>
|
|
|
</span><span id="__span-9-39"><a id="__codelineno-9-39" name="__codelineno-9-39" href="#__codelineno-9-39"></a>
|
|
|
</span><span id="__span-9-40"><a id="__codelineno-9-40" name="__codelineno-9-40" href="#__codelineno-9-40"></a> <span class="k">def</span> <span class="nf">reducer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
|
|
</span><span id="__span-9-41"><a id="__codelineno-9-41" name="__codelineno-9-41" href="#__codelineno-9-41"></a><span class="w"> </span><span class="sd">"""Sum values for each key.</span>
|
|
|
</span><span id="__span-9-42"><a id="__codelineno-9-42" name="__codelineno-9-42" href="#__codelineno-9-42"></a>
|
|
|
</span><span id="__span-9-43"><a id="__codelineno-9-43" name="__codelineno-9-43" href="#__codelineno-9-43"></a><span class="sd"> (user_id, 2016-01, shopping), 125</span>
|
|
|
</span><span id="__span-9-44"><a id="__codelineno-9-44" name="__codelineno-9-44" href="#__codelineno-9-44"></a><span class="sd"> (user_id, 2016-01, gas), 50</span>
|
|
|
</span><span id="__span-9-45"><a id="__codelineno-9-45" name="__codelineno-9-45" href="#__codelineno-9-45"></a><span class="sd"> """</span>
|
|
|
</span><span id="__span-9-46"><a id="__codelineno-9-46" name="__codelineno-9-46" href="#__codelineno-9-46"></a> <span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
|
|
|
</span><span id="__span-9-47"><a id="__codelineno-9-47" name="__codelineno-9-47" href="#__codelineno-9-47"></a> <span class="k">yield</span> <span class="n">key</span><span class="p">,</span> <span class="nb">sum</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
|
|
|
</span></code></pre></div>
|
|
|
<h2 id="step-4-scale-the-design">Step 4: Scale the design<a class="headerlink" href="#step-4-scale-the-design" title="Permanent link">¶</a></h2>
|
|
|
<blockquote>
|
|
|
<p>Identify and address bottlenecks, given the constraints.</p>
|
|
|
</blockquote>
|
|
|
<p><a class="glightbox" href="http://i.imgur.com/V5q57vU.png" data-type="image" data-width="auto" data-height="auto" data-desc-position="bottom"><img alt="Imgur" src="http://i.imgur.com/V5q57vU.png" /></a></p>
|
|
|
<p><strong>Important: Do not simply jump right into the final design from the initial design!</strong></p>
|
|
|
<p>State you would 1) <strong>Benchmark/Load Test</strong>, 2) <strong>Profile</strong> for bottlenecks 3) address bottlenecks while evaluating alternatives and trade-offs, and 4) repeat. See <a href="../scaling_aws/">Design a system that scales to millions of users on AWS</a> as a sample on how to iteratively scale the initial design.</p>
|
|
|
<p>It's important to discuss what bottlenecks you might encounter with the initial design and how you might address each of them. For example, what issues are addressed by adding a <strong>Load Balancer</strong> with multiple <strong>Web Servers</strong>? <strong>CDN</strong>? <strong>Master-Slave Replicas</strong>? What are the alternatives and <strong>Trade-Offs</strong> for each?</p>
|
|
|
<p>We'll introduce some components to complete the design and to address scalability issues. Internal load balancers are not shown to reduce clutter.</p>
|
|
|
<p><em>To avoid repeating discussions</em>, refer to the following <a href="https://github.com/donnemartin/system-design-primer#index-of-system-design-topics">system design topics</a> for main talking points, tradeoffs, and alternatives:</p>
|
|
|
<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#domain-name-system">DNS</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#content-delivery-network">CDN</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#load-balancer">Load balancer</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#horizontal-scaling">Horizontal scaling</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#reverse-proxy-web-server">Web server (reverse proxy)</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#application-layer">API server (application layer)</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#cache">Cache</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#relational-database-management-system-rdbms">Relational database management system (RDBMS)</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#fail-over">SQL write master-slave failover</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#master-slave-replication">Master-slave replication</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#asynchronism">Asynchronism</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#consistency-patterns">Consistency patterns</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#availability-patterns">Availability patterns</a></li>
|
|
|
</ul>
|
|
|
<p>We'll add an additional use case: <strong>User</strong> accesses summaries and transactions.</p>
|
|
|
<p>User sessions, aggregate stats by category, and recent transactions could be placed in a <strong>Memory Cache</strong> such as Redis or Memcached.</p>
|
|
|
<ul>
|
|
|
<li>The <strong>Client</strong> sends a read request to the <strong>Web Server</strong></li>
|
|
|
<li>The <strong>Web Server</strong> forwards the request to the <strong>Read API</strong> server<ul>
|
|
|
<li>Static content can be served from the <strong>Object Store</strong> such as S3, which is cached on the <strong>CDN</strong></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>The <strong>Read API</strong> server does the following:<ul>
|
|
|
<li>Checks the <strong>Memory Cache</strong> for the content<ul>
|
|
|
<li>If the url is in the <strong>Memory Cache</strong>, returns the cached contents</li>
|
|
|
<li>Else<ul>
|
|
|
<li>If the url is in the <strong>SQL Database</strong>, fetches the contents<ul>
|
|
|
<li>Updates the <strong>Memory Cache</strong> with the contents</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<p>Refer to <a href="https://github.com/donnemartin/system-design-primer#when-to-update-the-cache">When to update the cache</a> for tradeoffs and alternatives. The approach above describes <a href="https://github.com/donnemartin/system-design-primer#cache-aside">cache-aside</a>.</p>
|
|
|
<p>Instead of keeping the <code>monthly_spending</code> aggregate table in the <strong>SQL Database</strong>, we could create a separate <strong>Analytics Database</strong> using a data warehousing solution such as Amazon Redshift or Google BigQuery.</p>
|
|
|
<p>We might only want to store a month of <code>transactions</code> data in the database, while storing the rest in a data warehouse or in an <strong>Object Store</strong>. An <strong>Object Store</strong> such as Amazon S3 can comfortably handle the constraint of 250 GB of new content per month.</p>
|
|
|
<p>To address the 200 <em>average</em> read requests per second (higher at peak), traffic for popular content should be handled by the <strong>Memory Cache</strong> instead of the database. The <strong>Memory Cache</strong> is also useful for handling the unevenly distributed traffic and traffic spikes. The <strong>SQL Read Replicas</strong> should be able to handle the cache misses, as long as the replicas are not bogged down with replicating writes.</p>
|
|
|
<p>2,000 <em>average</em> transaction writes per second (higher at peak) might be tough for a single <strong>SQL Write Master-Slave</strong>. We might need to employ additional SQL scaling patterns:</p>
|
|
|
<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#federation">Federation</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#sharding">Sharding</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#denormalization">Denormalization</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#sql-tuning">SQL Tuning</a></li>
|
|
|
</ul>
|
|
|
<p>We should also consider moving some data to a <strong>NoSQL Database</strong>.</p>
|
|
|
<h2 id="additional-talking-points">Additional talking points<a class="headerlink" href="#additional-talking-points" title="Permanent link">¶</a></h2>
|
|
|
<blockquote>
|
|
|
<p>Additional topics to dive into, depending on the problem scope and time remaining.</p>
|
|
|
</blockquote>
|
|
|
<h4 id="nosql">NoSQL<a class="headerlink" href="#nosql" title="Permanent link">¶</a></h4>
|
|
|
<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#key-value-store">Key-value store</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#document-store">Document store</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#wide-column-store">Wide column store</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#graph-database">Graph database</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#sql-or-nosql">SQL vs NoSQL</a></li>
|
|
|
</ul>
|
|
|
<h3 id="caching">Caching<a class="headerlink" href="#caching" title="Permanent link">¶</a></h3>
|
|
|
<ul>
|
|
|
<li>Where to cache<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#client-caching">Client caching</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#cdn-caching">CDN caching</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#web-server-caching">Web server caching</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#database-caching">Database caching</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#application-caching">Application caching</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>What to cache<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#caching-at-the-database-query-level">Caching at the database query level</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#caching-at-the-object-level">Caching at the object level</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li>When to update the cache<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#cache-aside">Cache-aside</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#write-through">Write-through</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#write-behind-write-back">Write-behind (write-back)</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#refresh-ahead">Refresh ahead</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<h3 id="asynchronism-and-microservices">Asynchronism and microservices<a class="headerlink" href="#asynchronism-and-microservices" title="Permanent link">¶</a></h3>
|
|
|
<ul>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#message-queues">Message queues</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#task-queues">Task queues</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#back-pressure">Back pressure</a></li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#microservices">Microservices</a></li>
|
|
|
</ul>
|
|
|
<h3 id="communications">Communications<a class="headerlink" href="#communications" title="Permanent link">¶</a></h3>
|
|
|
<ul>
|
|
|
<li>Discuss tradeoffs:<ul>
|
|
|
<li>External communication with clients - <a href="https://github.com/donnemartin/system-design-primer#representational-state-transfer-rest">HTTP APIs following REST</a></li>
|
|
|
<li>Internal communications - <a href="https://github.com/donnemartin/system-design-primer#remote-procedure-call-rpc">RPC</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li><a href="https://github.com/donnemartin/system-design-primer#service-discovery">Service discovery</a></li>
|
|
|
</ul>
|
|
|
<h3 id="security">Security<a class="headerlink" href="#security" title="Permanent link">¶</a></h3>
|
|
|
<p>Refer to the <a href="https://github.com/donnemartin/system-design-primer#security">security section</a>.</p>
|
|
|
<h3 id="latency-numbers">Latency numbers<a class="headerlink" href="#latency-numbers" title="Permanent link">¶</a></h3>
|
|
|
<p>See <a href="https://github.com/donnemartin/system-design-primer#latency-numbers-every-programmer-should-know">Latency numbers every programmer should know</a>.</p>
|
|
|
<h3 id="ongoing">Ongoing<a class="headerlink" href="#ongoing" title="Permanent link">¶</a></h3>
|
|
|
<ul>
|
|
|
<li>Continue benchmarking and monitoring your system to address bottlenecks as they come up</li>
|
|
|
<li>Scaling is an iterative process</li>
|
|
|
</ul>
|
|
|
|
|
|
<hr>
|
|
|
<div class="md-source-file">
|
|
|
<small>
|
|
|
|
|
|
最后更新:
|
|
|
<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date">2024-06-08</span>
|
|
|
|
|
|
|
|
|
</small>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</article>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg>
|
|
|
回到页面顶部
|
|
|
</button>
|
|
|
|
|
|
</main>
|
|
|
|
|
|
<footer class="md-footer">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="md-footer-meta md-typeset">
|
|
|
<div class="md-footer-meta__inner md-grid">
|
|
|
<div class="md-copyright">
|
|
|
|
|
|
<div class="md-copyright__highlight">
|
|
|
Copyright © 2023 - 2024 Tink
|
|
|
</div>
|
|
|
|
|
|
|
|
|
Made with
|
|
|
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
|
|
Material for MkDocs
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="md-social">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a href="https://github.com/squidfunk" target="_blank" rel="noopener" title="github.com" class="md-social__link">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a href="https://hub.docker.com/r/squidfunk/mkdocs-material/" target="_blank" rel="noopener" title="hub.docker.com" class="md-social__link">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a href="https://pypi.org/project/mkdocs-material/" target="_blank" rel="noopener" title="pypi.org" class="md-social__link">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M439.8 200.5c-7.7-30.9-22.3-54.2-53.4-54.2h-40.1v47.4c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3zM167.8 248.1h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4zm-6.7-142.6c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4 11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a href="https://fosstodon.org/@squidfunk" target="_blank" rel="noopener me" title="fosstodon.org" class="md-social__link">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a href="https://twitter.com/squidfunk" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
</footer>
|
|
|
|
|
|
</div>
|
|
|
<div class="md-dialog" data-md-component="dialog">
|
|
|
<div class="md-dialog__inner md-typeset"></div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<script id="__config" type="application/json">{"base": "../../../../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.footer", "navigation.indexes", "navigation.sections", "navigation.tabs", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../../../assets/javascripts/workers/search.f886a092.min.js", "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}}</script>
|
|
|
|
|
|
|
|
|
<script src="../../../../../assets/javascripts/bundle.94c44541.min.js"></script>
|
|
|
|
|
|
<script src="../../../../../js/print-site.js"></script>
|
|
|
|
|
|
|
|
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
|
document$.subscribe(() => { lightbox.reload() });
|
|
|
</script></body>
|
|
|
</html> |