Присоединяйтесь к моему телеграм-каналу CTO Лайфхаки

Подробнее о моих услугах для бизнеса

  • Полезные привычки, которые помогают оставаться в тонусе

    Полезные привычки, которые помогают оставаться в тонусе

    Сегодня выходной, и я решил немного отвлечься от темы программирования, чтобы поговорить о привычках, которые помогают быть лучше, заряженным и стремиться к чему-то большему. Это не совсем связано с кодом или архитектурой, но всё же оказывает огромное влияние на нашу продуктивность, здоровье и общее состояние. Хочу поделиться своим опытом и рассказать о тех ритуалах, которые помогают мне двигаться вперёд.


    Чтение: зарядка для ума

    Чтение — это привычка, которая должна быть у каждого. Она развивает мозг, расширяет кругозор и помогает расслабиться. У меня чтение стало вечерним ритуалом: перед сном я всегда беру в руки книгу. Сейчас я перечитываю цикл «Тёмная башня» Стивена Кинга. Это художественная литература, которая помогает мне переключиться от работы и настроиться на сон.

    Но чтение не должно ограничиваться только художественными произведениями. Техническая литература — это ещё один важный аспект. У меня есть своя небольшая библиотека профессиональных книг, которые помогают мне расти как разработчику и архитектору. Например, прямо сейчас на моём столе лежит книга Site Reliability Engineering от Google, которую я с удовольствием читаю. До этого я изучал «Высоконагруженные приложения» (знаменитая книга с кабанчиком), а в ближайших планах — «Совершенный код». Также читаю «Язык программирования Go», чтобы углубить свои знания.

    Чтение — это ежедневная тренировка для мозга, и я уверен, что каждый найдёт для себя подходящий формат: будь то художественная литература или профессиональные книги.


    Спорт: забота о теле

    Вторая важная привычка — спорт. Как разработчики, мы часто понимаем, как устроены системы и процессы. Но важно помнить, что наш организм — это тоже сложная система. Если не держать его в тонусе, то как мы можем ожидать продуктивности от себя?

    Я занимаюсь спортом через день: подтягивания, отжимания на брусьях. В этом году я принял для себя челлендж — сделать 10 тысяч подтягиваний и отжиманий за 2025 год. Уже выполнил 4 тысячи и явно перевыполню план! Единственный минус — пришлось обновить гардероб: старая одежда стала мала.

    Кроме тренировок важно добавлять прогулки. Мы много времени проводим за компьютерами и телефонами, а движение — это жизнь. Я стараюсь проходить минимум 10 тысяч шагов в день. Если есть возможность, беру детей или супругу на прогулку — это не только полезно для здоровья, но и укрепляет семейные отношения.


    Хобби: удовольствие для души

    Ещё одна привычка — заниматься чем-то для удовольствия. Для меня это программирование с использованием AI. Я реализую проекты, о которых давно мечтал, но раньше не хватало времени. Это приносит мне радость и одновременно развивает мои навыки.

    Важно помнить: работа — это не вся наша жизнь. Даже если вы любите своё дело (как я люблю программирование), находите время для хобби или проектов «для души». Это помогает сохранить баланс между работой и личной жизнью.


    Итог

    Эти простые привычки помогают мне оставаться в тонусе:

    1. Чтение: художественная и техническая литература.
    2. Спорт: тренировки через день и ежедневные прогулки.
    3. Хобби: занятия тем, что приносит радость.

    Каждый из нас может найти свои ритуалы, которые сделают жизнь лучше. Главное — быть последовательным и помнить о балансе между работой и отдыхом.

  • Adminer — Легкий способ заглянуть в БД

    Adminer — Легкий способ заглянуть в БД

    Продолжаю серию лайфхаков для разработки своих pet-проектов. Сегодня мы всего за 2 мегабайта заглянем внутрь базы данных на своем сервере.

    Для этого нам понадобится Adminer — легковесный интерфейс для просмотра своих таблиц. Больше подходит, конечно, для вашего dev/stage окружения, но можно и на проде, только учитывайте риски и не публикуйте порты наружу для коммерческого продукта.

    Все что нужно сделать — добавить в docker compose следующий код:

      # Adminer для управления базой данных (доступен только через внутреннюю сеть)
      adminer:
        image: adminer:latest
        depends_on:
          db:
            condition: service_healthy
        restart: unless-stopped
        environment:
          - ADMINER_DEFAULT_SERVER=db
        networks:
          - app_network
        # Не публикуем порты наружу для безопасности

    Дальше хитрый трюк, хотите открыть его в браузере у себя на компьютере? Запустите команду ssh туннеля для маппинга портов:

    ssh -L 8080:localhost:8080 user@remote_server_ip

    Это одна из тех команд, которые я хотел бы знать гораздо раньше в своей карьере. Теперь на локалхосте у вас удаленный сайт открывается, и доступен он только вам!

  • Dozzle — как Docker Desktop, только на сервере

    Dozzle — как Docker Desktop, только на сервере

    Все мы любим красивые логи, которые нам дают ребята из Платформы, где все понятно и хорошо видно. Но что делать со своими pet-проектами? Когда они уже в мини-продакшине, как посмотреть что творится в контейнере?

    Раньше я ходил через ssh, подключался интерактивно к контейнеру, смотрел в реальном времени логи, пока не обнаружил шикарный Dozzle!

    Всего одна команда и один конфигурационный файл, и вот у вас почти что свой Docker Desktop со всеми контейнерами и всеми логами в реальном времени!

    docker run --restart always -d -v  /var/run/docker.sock:/var/run/docker.sock -v /data:/data -p 8080:8080 amir20/dozzle --auth-provider simple

    и создать перед этим файл в /data/users.yml

    users:
      # "admin" here is username
      admin:
        email: me@email.net
        name: Admin
        # Generate with docker run amir20/dozzle generate --name Admin --email me@email.net --password secret admin
        password: $2a$11$9ho4vY2LdJ/WBopFcsAS0uORC0x2vuFHQgT/yBqZyzclhHsoaIkzK
        filter:

    Вот что получаем в итоге:

    Доступ к любому контейнеру и его логам. Все это можно через Caddy Server повесить на удобный вам поддомен и в реальном времени смотреть на то как работает ваш сайт. Или не работает, и узнать почему.

  • Шаблон Excalidraw для проведения интервью по системному дизайну

    Шаблон Excalidraw для проведения интервью по системному дизайну

    Для проведения интервью можно использовать следующий шаблон — позволяет структурировать ответ и не забыть спросить основные моменты, необходимые для проектирования:

    Скачать шаблон для https://excalidraw.com/

  • Сколько вебсокетов можно открыть на один чат сервер?

    Сколько вебсокетов можно открыть на один чат сервер?

    Количество WebSocket-соединений, которые можно открыть на одном чат-сервере, зависит от нескольких факторов, но теоретически это число может быть очень большим. Рассмотрим основные аспекты:

    Теоретический максимум

    Теоретически, максимальное количество WebSocket-соединений на одном сервере может достигать огромных значений. Каждое соединение уникально идентифицируется комбинацией IP-адреса клиента и порта источника. Это означает, что теоретический предел составляет около 2^48 (примерно 281 триллион) соединений на один порт сервера.

    Практические ограничения

    На практике количество соединений ограничивается несколькими факторами:

    1. Ресурсы сервера: Память, CPU и пропускная способность сети являются ключевыми ограничивающими факторами.
    2. Настройки операционной системы: Лимиты на количество открытых файловых дескрипторов и сетевых соединений могут ограничивать максимальное число WebSocket-соединений.
    3. Производительность сервера: С увеличением числа соединений может падать общая производительность системы.

    Реальные примеры

    • WhatsApp и Phoenix: Эти платформы достигли показателя в 2 миллиона одновременных WebSocket-подключений на одном сервере.
    • Эксперименты с Java: Исследователи смогли открыть более миллиона TCP-соединений на одном сервере, что применимо и к WebSocket.

    Оптимизация для большого количества соединений

    Для поддержки большого числа WebSocket-соединений рекомендуется:

    1. Использовать асинхронные библиотеки: Они значительно повышают производительность за счет одновременной обработки задач.
    2. Поддерживать многопоточность: Автоматическая или ручная настройка многопоточности помогает масштабировать производительность.
    3. Выбирать эффективные языки и фреймворки: NodeJS, Java и C# показали хорошие результаты в тестах производительности WebSocket-серверов.
    4. Оптимизировать настройки сервера: Увеличение лимитов на файловые дескрипторы и сетевые соединения в ОС может существенно повысить возможности сервера.
    5. Использовать балансировку нагрузки: Распределение соединений между несколькими серверами позволяет масштабировать систему горизонтально.

    В заключение, хотя теоретически возможно открыть миллионы WebSocket-соединений на одном сервере, практическое количество будет зависеть от конкретной конфигурации оборудования, оптимизации программного обеспечения и требований к производительности вашего чат-приложения. Для большинства реальных сценариев использования чат-сервер может эффективно обслуживать тысячи или даже десятки тысяч одновременных WebSocket-соединений при правильной настройке и оптимизации.

  • Какой фреймворк выбрать на основе RPS (Request per second)

    Какой фреймворк выбрать на основе RPS (Request per second)

    ФреймворкЯзыкRPSУдобствоЭкосистемаСообществоДокументацияМасштабируемостьБезопасностьИнтеграция
    ActixRust1000007788997
    WarpRust900007677997
    ASP.NET CoreC#600009999999
    FiberGo600008788888
    GinGo550008898888
    FastifyJS600009889889
    NestJSJS500009999999
    Spring BootJava4000081010910910
    MicronautJava350008878998
    FastAPIPython300009889888
    DjangoPython20009101010899
    HanamiRuby20007777787
    RailsRuby19001010109889
    LaravelPHP1000991010889
    SymfonyPHP9008999999
    1. Удобство: Насколько легко начать работу и разрабатывать с использованием фреймворка.
    2. Экосистема: Разнообразие и качество доступных библиотек и инструментов.
    3. Сообщество: Активность и размер сообщества разработчиков.
    4. Документация: Качество и полнота официальной документации.
    5. Масштабируемость: Способность фреймворка справляться с ростом нагрузки и размера приложения.
    6. Безопасность: Встроенные механизмы безопасности и легкость их реализации.
    7. Интеграция: Простота интеграции с другими технологиями и сервисами.

    При выборе фреймворка следует учитывать все эти факторы в контексте конкретного проекта. Например:

    • Для быстрой разработки прототипов могут подойти Ruby on Rails или Django.
    • Для высоконагруженных систем стоит обратить внимание на Actix, ASP.NET Core или Spring Boot.
    • Если важна гибкость и легковесность, то Fastify или Gin могут быть хорошим выбором.
    • Для корпоративных приложений с сложной бизнес-логикой Spring Boot или ASP.NET Core предоставляют широкие возможности.

    Сколько серверов надо?

    MAU (10^n)DAURPSСерверы (Fiber)Серверы (Django)
    10000 (10^4)3 5000.6111
    100000 (10^5)35 0006.0811
    1000000 (10^6)350 00060.7611
    10000000 (10^7)3 500 000607.6411
    100000000 (10^8)35 000 0006076.3914
    1000000000 (10^9)350 000 00060763.89231

  • Согласованное и рандеву хеширование

    Согласованное и рандеву хеширование

    Согласованное хеширование (Consistent hashing) — это специальная техника хеширования в компьютерных науках, которая обладает важным свойством: при изменении размера хеш-таблицы требуется перераспределить в среднем только n/m ключей, где n — количество ключей, а m — количество слотов.

    Основные особенности

    • Эффективность при масштабировании: В отличие от традиционных хеш-таблиц, где изменение количества слотов приводит к перераспределению почти всех ключей, согласованное хеширование минимизирует количество перемещаемых данных.
    • Распределение нагрузки: Техника равномерно распределяет ключи кэша по шардам, даже если некоторые шарды выходят из строя или становятся недоступными.

    Применение

    Согласованное хеширование широко используется в распределенных системах, особенно в:

    • Распределенных кэшах
    • Системах хранения данных (например, Amazon Dynamo)
    • Сетях доставки контента (CDN)
    • Балансировке нагрузки

    Принцип работы

    1. Ключи и серверы отображаются на виртуальную окружность (обычно от 0 до 2π).
    2. Каждый ключ назначается ближайшему серверу по часовой стрелке.
    3. При добавлении или удалении сервера перераспределяются только ключи, попадающие в его сегмент.

    Преимущества

    • Минимизация перераспределения данных при изменении количества серверов.
    • Улучшение масштабируемости и отказоустойчивости распределенных систем.

    Согласованное хеширование стало ключевой технологией для многих современных распределенных систем, обеспечивая эффективное распределение данных и нагрузки


    Рандеву-хеширование (Rendezvous hashing) или хеширование с наибольшим случайным весом (HRW) — это алгоритм, позволяющий клиентам достичь распределенного соглашения о выборе k вариантов из n возможных. Этот метод часто применяется в распределенных системах для назначения объектов серверам или прокси.

    Основные особенности

    • Простота: Алгоритм концептуально прост и легок в реализации.
    • Минимальное нарушение: При добавлении или удалении узла перераспределяются только объекты, связанные с этим узлом.
    • Равномерное распределение: Обеспечивает равномерное распределение объектов по узлам.
    • Поддержка взвешивания: Позволяет учитывать разную мощность узлов.

    Принцип работы

    1. Для каждого объекта и каждого узла вычисляется хеш-значение.
    2. Объект назначается узлу с наибольшим хеш-значением.
    3. При изменении набора узлов пересчитываются только затронутые объекты.

    Применение

    Рандеву-хеширование используется во многих реальных системах, включая:

    • Балансировщик нагрузки GitHub
    • Распределенная база данных Apache Ignite
    • Файловое хранилище Tahoe-LAFS
    • Pub/sub платформа Twitter EventBus

    Преимущества перед согласованным хешированием

    • Более простая концепция и реализация
    • Не требует предварительных вычислений или хранения токенов
    • Обеспечивает простое решение для распределенного k-соглашения

    Рандеву-хеширование становится все более популярным в современных распределенных системах благодаря своей простоте, эффективности и гибкости

    ХарактеристикаСогласованное хешированиеРандеву-хеширование
    Год изобретения19971996
    СложностьБолее сложныйПроще
    Метод отображенияОтображает узлы и ключи на кольцо хешированияВычисляет хеш-значения для каждой пары ключ-узел
    Размещение объектовПо часовой стрелке на хеш-кольцеВыбирает узел с наибольшим хеш-значением
    Балансировка нагрузкиХорошая, но могут быть горячие точкиВ целом лучше, более равномерная
    МасштабируемостьХорошо масштабируется при инкрементных измененияхМенее масштабируемо, пересчитывает все хеши
    Предварительные вычисления токеновТребует предварительного вычисления и хранения токеновНе требует предварительных вычислений токенов
    Сложность добавления/удаления узловO(K/N + log N)O(n) для базовой реализации
    Перераспределение ключейМинимальное перемещение ключейОбъекты перераспределяются на оставшиеся узлы
    Реальное использованиеCassandra, CouchbaseGitHub Load Balancer, Apache Ignite, Twitter EventBus
  • Какую базу использовать для высоконагруженного приложения?

    Какую базу использовать для высоконагруженного приложения?

    База данныхCAPQPSМасштабированиеОптимизацияIn memory/Disk basedОбласть применения
    Apache CassandraAPДо 1 000 000ГоризонтальноеWriteDisk basedБольшие данные, IoT
    MemcachedCPДо 1 000 000ГоризонтальноеReadIn memoryКэширование, веб-приложения
    RedisCPДо 500 000+ГоризонтальноеRead/WriteIn memoryКэширование, сессии
    Amazon DynamoDBAPДо 500 000Автоматическое горизонтальноеRead/WriteDisk basedВеб-приложения, мобильные приложения
    ClickHouseCPДо 300 000ГоризонтальноеRead/WriteDisk basedАналитика, большие данные
    CouchbaseAPДо 200 000ГоризонтальноеRead/WriteHybridВеб-приложения, мобильные приложения
    PostgreSQLCAДо 150 000Вертикальное, репликацияReadDisk basedТранзакционные системы, ГИС
    Oracle DatabaseCAДо 120 000Вертикальное, RAC кластерыRead/WriteDisk basedКорпоративные приложения, финансы
    MongoDBCPДо 100 000Горизонтальное и вертикальноеRead/WriteDisk basedВеб-приложения, IoT
    MySQLCAДо 100 000Вертикальное, репликацияReadDisk basedВеб-сайты, CMS
    EtcdCPДо 80 000ГоризонтальноеReadDisk basedРаспределенные системы, конфигурации
    Apache HBaseCPДо 30 000ГоризонтальноеWriteDisk basedБольшие данные, аналитика
    Microsoft Azure Cosmos DBAPВарьируетсяГоризонтальноеRead/WriteDisk basedГлобально распределенные приложения
    InfluxDBCPВарьируетсяГоризонтальноеRead/WriteDisk basedIoT, мониторинг
    PostGISCAВарьируетсяВертикальное, репликацияReadDisk basedГИС, картография
    Apache Spark SQLCPВарьируетсяГоризонтальноеRead/WriteIn memoryАналитика больших данных
    OpenSearchAPВарьируетсяГоризонтальноеReadDisk basedПоиск, логи
    CouchDBAPВарьируетсяГоризонтальноеRead/WriteDisk basedВеб-приложения, мобильные приложения
    FirebirdCAВарьируетсяВертикальное, репликацияRead/WriteDisk basedВстраиваемые системы, локальные приложения

    Примечания:

    1. «In memory» означает, что база данных хранит данные преимущественно в оперативной памяти для быстрого доступа.
    2. «Disk based» означает, что база данных в основном хранит данные на диске.
    3. «Hybrid» (как в случае с Couchbase) означает, что база данных использует как память, так и диск для оптимальной производительности.
    4. Значения QPS являются приблизительными и могут варьироваться в зависимости от конфигурации и нагрузки.
  • Памятка по системному дизайну

    Памятка по системному дизайну

    Выбор правильной архитектуры = Выбор правильных сражений + Управление компромиссами

    Перевод: https://gist.github.com/vasanthk/485d1c25737e8e72759f

    Основные шаги

    1. Уточнить и согласовать масштаб системы
    • Варианты использования (описание последовательностей событий, которые в совокупности приводят к полезному действию системы)
    • Кто будет использовать систему?
    • Как они будут ее использовать?
    1. Ограничения
    • В основном определите ограничения по обработке трафика и данных в масштабе.
    • Масштаб системы (запросы в секунду, типы запросов, объем записываемых данных в секунду, объем считываемых данных в секунду)
    • Особые системные требования, такие как многопоточность, ориентация на чтение или запись.
    1. Проектирование архитектуры высокого уровня (абстрактный дизайн)
    • Набросайте важные компоненты и связи между ними, не вдаваясь в детали.
    • Уровень сервиса приложений (обслуживает запросы)
    • Перечислите различные необходимые сервисы.
    • Уровень хранения данных
    • Например, масштабируемая система обычно включает веб-сервер (балансировщик нагрузки, load balancer), сервис (разделение сервисов, service partition), базу данных (кластер баз данных master/slave) и системы кэширования.
    1. Проектирование компонентов
    • Компоненты + конкретные API, необходимые для каждого из них.
    • Объектно-ориентированный дизайн для функциональности.
    • Сопоставление функций с модулями: один сценарий для одного модуля.
    • Рассмотрите отношения между модулями:
      • Некоторые функции должны иметь уникальный экземпляр (Одиночки, Singletons)
      • Основной объект может состоять из многих других объектов (композиция, composition)
      • Один объект является другим объектом (наследование, inheritance)
    • Проектирование схемы базы данных.
    1. Понимание узких мест
    • Возможно, вашей системе нужен балансировщик нагрузки и множество машин за ним для обработки пользовательских запросов.
    • Или, возможно, данных так много, что вам нужно распределить базу данных на несколько машин. Каковы некоторые недостатки, возникающие при этом?
    • Слишком ли медленная база данных и нуждается ли она в кэшировании в памяти?
    1. Масштабирование абстрактного дизайна
    • Вертикальное масштабирование (vertical scaling)
      • Масштабирование путем добавления большей мощности (CPU, RAM) к существующей машине.
    • Горизонтальное масштабирование (horizontal scaling)
      • Масштабирование путем добавления большего количества машин в пул ресурсов.

    Кэширование (Caching)

    Балансировка нагрузки помогает масштабироваться горизонтально на постоянно растущем числе серверов, но кэширование позволит вам гораздо эффективнее использовать уже имеющиеся ресурсы, а также сделает возможными иначе недостижимые требования к продукту.

    • Кэширование приложений требует явной интеграции в код приложения. Обычно оно проверяет, есть ли значение в кэше; если нет, извлекает значение из базы данных.
    • Кэширование базы данных, как правило, «бесплатно». Когда вы включаете базу данных, вы получаете некоторый уровень настройки по умолчанию, который обеспечит определенную степень кэширования и производительности.
    • Кэши в памяти (in-memory caches) наиболее мощны с точки зрения чистой производительности. Это потому, что они хранят весь набор данных в памяти, а доступ к RAM на порядки быстрее, чем к диску. Например, Memcached или Redis.

    Примеры:

    • Предварительный расчет результатов (например, количество посещений с каждого реферального домена за предыдущий день)
    • Предварительное создание дорогостоящих индексов (например, предлагаемые истории на основе истории кликов пользователя)
    • Хранение копий часто запрашиваемых данных в более быстром бэкенде (например, Memcache вместо PostgreSQL)

    Балансировка нагрузки (Load balancing)

    Публичные серверы масштабируемого веб-сервиса скрыты за балансировщиком нагрузки. Этот балансировщик нагрузки равномерно распределяет нагрузку (запросы от ваших пользователей) на вашу группу/кластер серверов приложений.

    Типы:

    • Умный клиент (трудно сделать идеально)
    • Аппаратные балансировщики нагрузки (дорого, но надежно)
    • Программные балансировщики нагрузки (гибридные — подходят для большинства систем)

    Репликация базы данных (Database replication)

    Репликация базы данных — это частое электронное копирование данных из базы данных на одном компьютере или сервере в базу данных на другом, чтобы все пользователи имели доступ к одному уровню информации. Результатом является распределенная база данных, в которой пользователи могут получить доступ к данным, относящимся к их задачам, не мешая работе других. Реализация репликации базы данных с целью устранения неоднозначности или несогласованности данных между пользователями известна как нормализация.

    Партиционирование базы данных (Database partitioning)

    Партиционирование реляционных данных обычно относится к разложению ваших таблиц либо по строкам (горизонтально), либо по столбцам (вертикально).

    Map-Reduce

    Для достаточно небольших систем вы часто можете обойтись специальными запросами к SQL-базе данных, но этот подход может не масштабироваться тривиально, когда количество хранимых данных или нагрузка на запись требует шардинга вашей базы данных, и обычно требует выделенных подчиненных узлов для выполнения этих запросов (в этот момент, возможно, вы предпочтете использовать систему, разработанную для анализа больших объемов данных, вместо борьбы с вашей базой данных).

    Добавление слоя map-reduce позволяет выполнять интенсивные операции с данными и/или обработкой за разумное время. Вы можете использовать его для расчета предлагаемых пользователей в социальном графе или для создания аналитических отчетов. Например, Hadoop, и, возможно, Hive или HBase.

    Платформенный слой (Сервисы) (Platform Layer (Services))

    Разделение платформы и веб-приложения позволяет масштабировать части независимо. Если вы добавляете новый API, вы можете добавить серверы платформы без добавления ненужной мощности для уровня веб-приложения.

    Добавление платформенного слоя может быть способом повторного использования вашей инфраструктуры для нескольких продуктов или интерфейсов (веб-приложение, API, приложение для iPhone и т.д.) без написания слишком большого количества избыточного шаблонного кода для работы с кэшами, базами данных и т.д.

    Ключевые темы для проектирования системы

    1. Параллелизм (Concurrency)
    • Понимаете ли вы потоки, взаимоблокировку и голодание? Знаете ли вы, как распараллеливать алгоритмы? Понимаете ли вы согласованность и когерентность?
    1. Сетевое взаимодействие (Networking)
    • Примерно понимаете ли вы IPC и TCP/IP? Знаете ли вы разницу между пропускной способностью и задержкой, и когда каждый фактор является релевантным?
    1. Абстракция (Abstraction)
    • Вы должны понимать системы, на которых вы строите. Знаете ли вы примерно, как работают ОС, файловая система и база данных? Знаете ли вы о различных уровнях кэширования в современной ОС?
    1. Производительность в реальном мире (Real-World Performance)
    • Вы должны быть знакомы со скоростью всего, что может делать ваш компьютер, включая относительную производительность RAM, диска, SSD и вашей сети.
    1. Оценка (Estimation)
    • Оценка, особенно в форме приблизительного расчета, важна, потому что она помогает вам сузить список возможных решений только до тех, которые осуществимы. Тогда вам нужно написать только несколько прототипов или микро-бенчмарков.
    1. Доступность и надежность (Availability & Reliability)
    • Думаете ли вы о том, как вещи могут выйти из строя, особенно в распределенной среде? Знаете ли вы, как проектировать систему для борьбы с сетевыми сбоями? Понимаете ли вы долговечность?

    Соображения по проектированию системы веб-приложений:

    1. Безопасность (CORS)
    2. Использование CDN
    • Сеть доставки контента (CDN) — это система распределенных серверов (сеть), которая доставляет веб-страницы и другой веб-контент пользователю на основе географического расположения пользователя, происхождения веб-страницы и сервера доставки контента.
    • Эта услуга эффективна для ускорения доставки контента веб-сайтов с высоким трафиком и веб-сайтов с глобальным охватом. Чем ближе сервер CDN географически к пользователю, тем быстрее контент будет доставлен пользователю.
    • CDN также обеспечивают защиту от больших всплесков трафика.
    1. Полнотекстовый поиск (Full Text Search)
    • Использование Sphinx/Lucene/Solr — которые достигают быстрых поисковых ответов, потому что вместо прямого поиска по тексту они ищут по индексу.
    1. Автономная поддержка/Прогрессивное улучшение
    • Service Workers
    • Web Workers
    1. Серверный рендеринг (Server Side rendering)
    2. Асинхронная загрузка активов (Lazy load items)
    3. Минимизация сетевых запросов (Http2 + bundling/sprites и т.д.)
    4. Продуктивность разработчиков/Инструментарий
    5. Доступность (Accessibility)
    6. Интернационализация
    7. Отзывчивый дизайн (Responsive design)
    8. Совместимость браузеров

    Рабочие компоненты архитектуры фронтенда

    1. Код
    • HTML5/WAI-ARIA
    • Стандарты и организация кода CSS/Sass
    • Объектно-ориентированный подход (как объекты разбиваются и собираются вместе)
    • JS фреймворки/организация/техники оптимизации производительности
    1. Доставка активов — Фронтенд операции
    2. Документация
    • Документы по внедрению
    • Руководство по стилю/Библиотека шаблонов
    • Диаграммы архитектуры (поток кода, цепочка инструментов)
    1. Тестирование
    • Тестирование производительности
    • Визуальная регрессия
    • Модульное тестирование
    • Сквозное тестирование
    1. Процесс
    • Git Workflow
    • Управление зависимостями (npm, Bundler, Bower)
    • Системы сборки (Grunt/Gulp)
    • Процесс развертывания
    • Непрерывная интеграция (Travis CI, Jenkins)

  • План проведения интервью по системному дизайну

    План проведения интервью по системному дизайну

    Перевод репозитория https://leetcode.com/discuss/career/229177/My-System-Design-Template

    1. Ожидания от функционала [5 мин]

    • Варианты использования
    • Сценарии, которые не будут охвачены
    • Кто будет использовать
    • Сколько пользователей будет
    • Шаблоны использования

    2. Оценки [5 мин]

    • Пропускная способность (QPS для запросов на чтение и запись)
    • Ожидаемая латентность системы (для запросов на чтение и запись)
    • Соотношение чтения/записи
    • Оценки трафика
    • Запись (QPS, объем данных)
    • Чтение (QPS, объем данных)
    • Оценки хранилища
    • Оценки памяти
    • Какие данные мы хотим хранить в кэше, если используем его
    • Сколько RAM и машин нам нужно для достижения этого
    • Объем данных для хранения на диске/SSD

    3. Цели проектирования [5 мин]

    • Требования к латентности и пропускной способности
    • Согласованность vs Доступность [Слабая/сильная/итоговая => согласованность | Отказоустойчивость/репликация => доступность]

    4. Высокоуровневый дизайн [5-10 мин]

    • API для сценариев чтения/записи критических компонентов
    • Схема базы данных
    • Базовый алгоритм
    • Высокоуровневый дизайн для сценариев чтения/записи

    5. Глубокое погружение [15-20 мин]

    Масштабирование алгоритма

    Масштабирование отдельных компонентов:

    • Доступность, согласованность и масштабируемость для каждого компонента
    • Паттерны согласованности и доступности

    Рассмотрение следующих компонентов, их интеграции и пользы:

    a) DNS

    b) CDN [Push vs Pull]

    c) Балансировщики нагрузки [Активный-Пассивный, Активный-Активный, Уровень 4, Уровень 7]

    d) Обратный прокси

    e) Масштабирование уровня приложений [Микросервисы, Обнаружение сервисов]

    f) БД [RDBMS, NoSQL]

    • RDBMS
    • Мастер-слейв, Мастер-мастер, Федерация, Шардинг, Денормализация, Оптимизация SQL
    • NoSQL
    • Ключ-Значение, Широкая колонка, Граф, Документ
    • Быстрый поиск:
      • RAM [Ограниченный размер] => Redis, Memcached
      • AP [Неограниченный размер] => Cassandra, RIAK, Voldemort
      • CP [Неограниченный размер] => HBase, MongoDB, Couchbase, DynamoDB

    g) Кэши

    • Клиентское кэширование, CDN кэширование, Кэширование веб-сервера, Кэширование базы данных, Кэширование приложений, Кэш на уровне запросов, Кэш на уровне объектов
    • Политики вытеснения:
    • Cache aside
    • Write through
    • Write behind
    • Refresh ahead

    h) Асинхронность

    • Очереди сообщений
    • Очереди задач
    • Обратное давление

    i) Коммуникация

    • TCP
    • UDP
    • REST
    • RPC

    6. Обоснование [5 мин]

    • Пропускная способность каждого уровня
    • Латентность между каждым уровнем
    • Обоснование общей латентности