commit
884ba0c596
|
@ -98,7 +98,7 @@
|
||||||
|
|
||||||
> 各种系统设计主题的摘要,包括优点和缺点。**每一个主题都面临着取舍和权衡**。
|
> 各种系统设计主题的摘要,包括优点和缺点。**每一个主题都面临着取舍和权衡**。
|
||||||
>
|
>
|
||||||
> 每个章节都包含着更的资源的链接。
|
> 每个章节都包含着更多的资源的链接。
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -207,7 +207,7 @@
|
||||||
|
|
||||||
那些有经验的候选人通常会被期望了解更多的系统设计的知识。架构师或者团队负责人则会被期望了解更多除了个人贡献之外的知识。顶级的科技公司通常也会有一次或者更多的系统设计面试。
|
那些有经验的候选人通常会被期望了解更多的系统设计的知识。架构师或者团队负责人则会被期望了解更多除了个人贡献之外的知识。顶级的科技公司通常也会有一次或者更多的系统设计面试。
|
||||||
|
|
||||||
面试会很宽泛的展开并在几个领域深入。这回帮助你了解一些关于系统设计的不同的主题。基于你的时间线,经验,面试的职位和面试的公司对下面的指导做出适当的调整。
|
面试会很宽泛的展开并在几个领域深入。这会帮助你了解一些关于系统设计的不同的主题。基于你的时间线,经验,面试的职位和面试的公司对下面的指导做出适当的调整。
|
||||||
|
|
||||||
* **短期** - 以系统设计主题的**广度**为目标。通过解决**一些**面试题来练习。
|
* **短期** - 以系统设计主题的**广度**为目标。通过解决**一些**面试题来练习。
|
||||||
* **中期** - 以系统设计主题的**广度**和**初级深度**为目标。通过解决**很多**面试题来练习。
|
* **中期** - 以系统设计主题的**广度**和**初级深度**为目标。通过解决**很多**面试题来练习。
|
||||||
|
@ -242,9 +242,9 @@
|
||||||
* 我们希望每秒钟处理多少请求?
|
* 我们希望每秒钟处理多少请求?
|
||||||
* 我们希望的读写比率?
|
* 我们希望的读写比率?
|
||||||
|
|
||||||
### 第二步:创造一个高级的设计
|
### 第二步:创造一个高层级的设计
|
||||||
|
|
||||||
使用所有重要的组件来描绘出一个高级的设计。
|
使用所有重要的组件来描绘出一个高层级的设计。
|
||||||
|
|
||||||
* 画出主要的组件和连接
|
* 画出主要的组件和连接
|
||||||
* 证明你的想法
|
* 证明你的想法
|
||||||
|
@ -273,11 +273,11 @@
|
||||||
|
|
||||||
论述可能的解决办法和代价。每件事情需要取舍。可以使用[可拓展系统的设计原则](#系统设计主题的索引)来处理瓶颈。
|
论述可能的解决办法和代价。每件事情需要取舍。可以使用[可拓展系统的设计原则](#系统设计主题的索引)来处理瓶颈。
|
||||||
|
|
||||||
### 信封背面的计算
|
### 预估计算量
|
||||||
|
|
||||||
你或许会被要求通过手算进行一些估算。涉及到的[附录](#附录)涉及到的是下面的这些资源:
|
你或许会被要求通过手算进行一些估算。涉及到的[附录](#附录)涉及到的是下面的这些资源:
|
||||||
|
|
||||||
* [使用信封的背面做计算](http://highscalability.com/blog/2011/1/26/google-pro-tip-use-back-of-the-envelope-calculations-to-choo.html)
|
* [使用预估计算量](http://highscalability.com/blog/2011/1/26/google-pro-tip-use-back-of-the-envelope-calculations-to-choo.html)
|
||||||
* [2 的次方表](#2-的次方表)
|
* [2 的次方表](#2-的次方表)
|
||||||
* [每个程序员都应该知道的延迟数](#每个程序员都应该知道的延迟数)
|
* [每个程序员都应该知道的延迟数](#每个程序员都应该知道的延迟数)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [Brazilian Portuguese](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Italian](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [Korean](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [Persian](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polish](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [Russian](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Turkish](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [Vietnamese](https://github.com/donnemartin/system-design-primer/issues/127) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)*
|
*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [Brazilian Portuguese](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Greek](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [Italian](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [Korean](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [Persian](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polish](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [Russian](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Spanish](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [Turkish](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [Vietnamese](https://github.com/donnemartin/system-design-primer/issues/127) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)*
|
||||||
|
|
||||||
# The System Design Primer
|
# The System Design Primer
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,11 @@ class CallCenter(object):
|
||||||
return employee
|
return employee
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def notify_call_escalated(self, call): # ...
|
def notify_call_escalated(self, call):
|
||||||
def notify_call_completed(self, call): # ...
|
pass
|
||||||
def dispatch_queued_call_to_newly_freed_employee(self, call, employee): # ...
|
|
||||||
|
def notify_call_completed(self, call):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dispatch_queued_call_to_newly_freed_employee(self, call, employee):
|
||||||
|
pass
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Hand(object):
|
||||||
|
|
||||||
def score(self):
|
def score(self):
|
||||||
total_value = 0
|
total_value = 0
|
||||||
for card in card:
|
for card in self.cards:
|
||||||
total_value += card.value
|
total_value += card.value
|
||||||
return total_value
|
return total_value
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class BlackJackHand(Hand):
|
||||||
|
|
||||||
def possible_scores(self):
|
def possible_scores(self):
|
||||||
"""Return a list of possible scores, taking Aces into account."""
|
"""Return a list of possible scores, taking Aces into account."""
|
||||||
# ...
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Deck(object):
|
class Deck(object):
|
||||||
|
@ -102,9 +102,9 @@ class Deck(object):
|
||||||
self.deal_index = 0
|
self.deal_index = 0
|
||||||
|
|
||||||
def remaining_cards(self):
|
def remaining_cards(self):
|
||||||
return len(self.cards) - deal_index
|
return len(self.cards) - self.deal_index
|
||||||
|
|
||||||
def deal_card():
|
def deal_card(self):
|
||||||
try:
|
try:
|
||||||
card = self.cards[self.deal_index]
|
card = self.cards[self.deal_index]
|
||||||
card.is_available = False
|
card.is_available = False
|
||||||
|
@ -113,4 +113,5 @@ class Deck(object):
|
||||||
return None
|
return None
|
||||||
return card
|
return card
|
||||||
|
|
||||||
def shuffle(self): # ...
|
def shuffle(self):
|
||||||
|
pass
|
||||||
|
|
|
@ -11,9 +11,14 @@ class LinkedList(object):
|
||||||
self.head = None
|
self.head = None
|
||||||
self.tail = None
|
self.tail = None
|
||||||
|
|
||||||
def move_to_front(self, node): # ...
|
def move_to_front(self, node):
|
||||||
def append_to_front(self, node): # ...
|
pass
|
||||||
def remove_from_tail(self): # ...
|
|
||||||
|
def append_to_front(self, node):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_from_tail(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Cache(object):
|
class Cache(object):
|
||||||
|
@ -24,7 +29,7 @@ class Cache(object):
|
||||||
self.lookup = {} # key: query, value: node
|
self.lookup = {} # key: query, value: node
|
||||||
self.linked_list = LinkedList()
|
self.linked_list = LinkedList()
|
||||||
|
|
||||||
def get(self, query)
|
def get(self, query):
|
||||||
"""Get the stored query result from the cache.
|
"""Get the stored query result from the cache.
|
||||||
|
|
||||||
Accessing a node updates its position to the front of the LRU list.
|
Accessing a node updates its position to the front of the LRU list.
|
||||||
|
|
|
@ -6,11 +6,20 @@ class UserService(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.users_by_id = {} # key: user id, value: User
|
self.users_by_id = {} # key: user id, value: User
|
||||||
|
|
||||||
def add_user(self, user_id, name, pass_hash): # ...
|
def add_user(self, user_id, name, pass_hash):
|
||||||
def remove_user(self, user_id): # ...
|
pass
|
||||||
def add_friend_request(self, from_user_id, to_user_id): # ...
|
|
||||||
def approve_friend_request(self, from_user_id, to_user_id): # ...
|
def remove_user(self, user_id):
|
||||||
def reject_friend_request(self, from_user_id, to_user_id): # ...
|
pass
|
||||||
|
|
||||||
|
def add_friend_request(self, from_user_id, to_user_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def approve_friend_request(self, from_user_id, to_user_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reject_friend_request(self, from_user_id, to_user_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class User(object):
|
class User(object):
|
||||||
|
@ -25,12 +34,23 @@ class User(object):
|
||||||
self.received_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
self.received_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
||||||
self.sent_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
self.sent_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest
|
||||||
|
|
||||||
def message_user(self, friend_id, message): # ...
|
def message_user(self, friend_id, message):
|
||||||
def message_group(self, group_id, message): # ...
|
pass
|
||||||
def send_friend_request(self, friend_id): # ...
|
|
||||||
def receive_friend_request(self, friend_id): # ...
|
def message_group(self, group_id, message):
|
||||||
def approve_friend_request(self, friend_id): # ...
|
pass
|
||||||
def reject_friend_request(self, friend_id): # ...
|
|
||||||
|
def send_friend_request(self, friend_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def receive_friend_request(self, friend_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def approve_friend_request(self, friend_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reject_friend_request(self, friend_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Chat(metaclass=ABCMeta):
|
class Chat(metaclass=ABCMeta):
|
||||||
|
@ -51,8 +71,11 @@ class PrivateChat(Chat):
|
||||||
|
|
||||||
class GroupChat(Chat):
|
class GroupChat(Chat):
|
||||||
|
|
||||||
def add_user(self, user): # ...
|
def add_user(self, user):
|
||||||
def remove_user(self, user): # ...
|
pass
|
||||||
|
|
||||||
|
def remove_user(self, user):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Message(object):
|
class Message(object):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
class VehicleSize(Enum):
|
class VehicleSize(Enum):
|
||||||
|
@ -92,11 +93,11 @@ class Level(object):
|
||||||
|
|
||||||
def _find_available_spot(self, vehicle):
|
def _find_available_spot(self, vehicle):
|
||||||
"""Find an available spot where vehicle can fit, or return None"""
|
"""Find an available spot where vehicle can fit, or return None"""
|
||||||
# ...
|
pass
|
||||||
|
|
||||||
def _park_starting_at_spot(self, spot, vehicle):
|
def _park_starting_at_spot(self, spot, vehicle):
|
||||||
"""Occupy starting at spot.spot_number to vehicle.spot_size."""
|
"""Occupy starting at spot.spot_number to vehicle.spot_size."""
|
||||||
# ...
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ParkingSpot(object):
|
class ParkingSpot(object):
|
||||||
|
@ -117,5 +118,8 @@ class ParkingSpot(object):
|
||||||
return False
|
return False
|
||||||
return vehicle.can_fit_in_spot(self)
|
return vehicle.can_fit_in_spot(self)
|
||||||
|
|
||||||
def park_vehicle(self, vehicle): # ...
|
def park_vehicle(self, vehicle):
|
||||||
def remove_vehicle(self): # ...
|
pass
|
||||||
|
|
||||||
|
def remove_vehicle(self):
|
||||||
|
pass
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Cache(object):
|
||||||
self.lookup = {}
|
self.lookup = {}
|
||||||
self.linked_list = LinkedList()
|
self.linked_list = LinkedList()
|
||||||
|
|
||||||
def get(self, query)
|
def get(self, query):
|
||||||
"""Get the stored query result from the cache.
|
"""Get the stored query result from the cache.
|
||||||
|
|
||||||
Accessing a node updates its position to the front of the LRU list.
|
Accessing a node updates its position to the front of the LRU list.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
|
||||||
class Graph(object):
|
class Graph(object):
|
||||||
|
|
||||||
|
@ -61,3 +63,4 @@ class UserGraphService(object):
|
||||||
def bfs(self, source, dest):
|
def bfs(self, source, dest):
|
||||||
# Use self.visited_ids to track visited nodes
|
# Use self.visited_ids to track visited nodes
|
||||||
# Use self.lookup to translate a person_id to a Person
|
# Use self.lookup to translate a person_id to a Person
|
||||||
|
pass
|
||||||
|
|
|
@ -2,33 +2,33 @@
|
||||||
|
|
||||||
class PagesDataStore(object):
|
class PagesDataStore(object):
|
||||||
|
|
||||||
def __init__(self, db);
|
def __init__(self, db):
|
||||||
self.db = db
|
self.db = db
|
||||||
...
|
pass
|
||||||
|
|
||||||
def add_link_to_crawl(self, url):
|
def add_link_to_crawl(self, url):
|
||||||
"""Add the given link to `links_to_crawl`."""
|
"""Add the given link to `links_to_crawl`."""
|
||||||
...
|
pass
|
||||||
|
|
||||||
def remove_link_to_crawl(self, url):
|
def remove_link_to_crawl(self, url):
|
||||||
"""Remove the given link from `links_to_crawl`."""
|
"""Remove the given link from `links_to_crawl`."""
|
||||||
...
|
pass
|
||||||
|
|
||||||
def reduce_priority_link_to_crawl(self, url)
|
def reduce_priority_link_to_crawl(self, url):
|
||||||
"""Reduce the priority of a link in `links_to_crawl` to avoid cycles."""
|
"""Reduce the priority of a link in `links_to_crawl` to avoid cycles."""
|
||||||
...
|
pass
|
||||||
|
|
||||||
def extract_max_priority_page(self):
|
def extract_max_priority_page(self):
|
||||||
"""Return the highest priority link in `links_to_crawl`."""
|
"""Return the highest priority link in `links_to_crawl`."""
|
||||||
...
|
pass
|
||||||
|
|
||||||
def insert_crawled_link(self, url, signature):
|
def insert_crawled_link(self, url, signature):
|
||||||
"""Add the given link to `crawled_links`."""
|
"""Add the given link to `crawled_links`."""
|
||||||
...
|
pass
|
||||||
|
|
||||||
def crawled_similar(self, signature):
|
def crawled_similar(self, signature):
|
||||||
"""Determine if we've already crawled a page matching the given signature"""
|
"""Determine if we've already crawled a page matching the given signature"""
|
||||||
...
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Page(object):
|
class Page(object):
|
||||||
|
@ -41,7 +41,7 @@ class Page(object):
|
||||||
|
|
||||||
def create_signature(self):
|
def create_signature(self):
|
||||||
# Create signature based on url and contents
|
# Create signature based on url and contents
|
||||||
...
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Crawler(object):
|
class Crawler(object):
|
||||||
|
|
Loading…
Reference in New Issue