Для любого разработчика глубокое понимание основных принципов системного проектирования является необходимым условием для создания стабильных и масштабируемых программных систем, способных обеспечивать высокую производительность. Системное проектирование (System Design) включает разработку архитектуры и структуры программной системы, направленную на удовлетворение специфических требований и обеспечение требуемых показателей производительности.

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

Вот 10 ключевых принципов системного проектирования, которые следует знать каждому программисту. Эти принципы лежат в основе создания программных систем, способных обрабатывать большие объемы данных, поддерживать высокую конкурентоспособность пользователей и гарантировать оптимальную производительность:

  • Масштабируемость

  • Доступность

  • Надежность

  • Устойчивость к сбоям

  • Стратегии кэширования

  • Балансировка нагрузки

  • Безопасность

  • Масштабируемое управление данными

  • Паттерны проектирования

  • Оптимизация производительности

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

Масштабируемость

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

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

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

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

Масштабируемость подразделяется на две ключевые категории: вертикальную и горизонтальную. Вертикальная масштабируемость означает усиление одного сервера или узла за счет увеличения его ресурсов, таких как процессор, оперативная память или объем хранения, для улучшения обработки возросшей нагрузки. Горизонтальная масштабируемость, в отличие от вертикальной, предусматривает расширение системы путем добавления новых серверов или узлов, что позволяет распределять нагрузку более равномерно и справляться с ростом спроса.

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

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

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

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

Разница между вертикальным и горизонтальным масштабированием
Разница между вертикальным и горизонтальным масштабированием

Доступность

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

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

Для оценки доступности часто используются такие показатели, как время безотказной работы системы (uptime), показывающее процент времени нормальной работы системы, и время простоя (downtime), отражающее периоды, когда система недоступна.

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

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

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

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

Надежность

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

Особенно высокие требования к надежности предъявляются в приложениях, где сбои могут привести к серьезным последствиям, например, авиационная, медицинская и финансовая сферы, а также в областях, где важна безопасность.

Для оценки надежности часто используются такие показатели, как среднее время между отказами (Mean Time Between Failures, MTBF), указывающее на среднюю длительность времени работы системы без сбоев, и частота отказов (Failure Rate, FR), отражающая частоту возникновения сбоев в течение определенного периода времени.

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

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

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

Устойчивость к сбоям

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

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

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

Этот принцип реализуется через внедрение избыточности, механизмов обнаружения и исправления ошибок, а также систем восстановления после сбоев, обеспечивая тем самым продолжение функционирования системы в случае выхода из строя отдельных компонентов или подсистем.

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

Устойчивость к сбоям играет критическую роль в поддержании высокого уровня доступности, надежности и стабильности систем, особенно в приложениях, где последствия системных отказов могут быть особенно серьезными.

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

Стратегии кэширования

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

Стратегии кэширования могут быть многообразными и должны соответствовать специфическим потребностям системы или приложения. Вот несколько распространенных подходов:

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

  • Частичное кэширование: Здесь в кэш помещается лишь часть данных, обычно часто запрашиваемые или самые используемые. Это решение предпочтительно для больших наборов данных или в ситуациях, когда не все данные постоянно востребованы.

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

  • Стратегии LRU (Least Recently Used) и LFU (Least Frequently Used): В рамках этих подходов из кэша удаляются неиспользуемые данные для освобождения пространства для новой информации. Они целесообразны, когда пространство кэша ограничено.

  • Write-through или Write-behind (write-back) кэширование: При write-through стратегии данные записываются одновременно в кэш и в первичный источник, в то время как write-behind стратегия предполагает запись сначала в кэш, а затем и в источник. Эти методы используются для поддержания согласованности между кэшем и источником данных.

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

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

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

Балансировка нагрузки

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

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

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

  • Круговой метод (Round Robin): Этот подход равномерно распределяет поступающие запросы между серверами или ресурсами по принципу очередности, обеспечивая справедливое распределение нагрузки между всеми участниками.

  • Метод наименьшего числа соединений (Least Connections): Новые запросы направляются к серверу или ресурсу с наименьшим текущим количеством активных соединений, что обеспечивает балансировку нагрузки в соответствии с текущей загруженностью.

  • Привязка по IP-адресу (Source IP Affinity): Запросы от одного IP-адреса всегда перенаправляются к одному и тому же серверу или ресурсу, что позволяет обслуживать клиента одним и тем же узлом для последовательности в обработке запросов.

  • Взвешенный круговой метод (Weighted Round Robin): Распределение запросов происходит с учетом весов, назначенных каждому серверу или ресурсу, что позволяет учитывать их производительность или мощность при назначении нагрузки.

  • Адаптивная балансировка (Adaptive Load Balancing): Нагрузка динамически распределяется на основе актуальной информации о состоянии, производительности или других метриках серверов или ресурсов, что позволяет оптимизировать производительность системы.

Разница между балансировщиком нагрузки и API-шлюзом
Разница между балансировщиком нагрузки и API-шлюзом

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

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

Безопасность

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

В рамки принципов безопасности системного проектирования входят следующие аспекты:

  • Аутентификация: Обеспечение подтверждения личности пользователей или системных компонентов и назначение соответствующих уровней доступа на основании их идентификационных данных.

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

  • Шифрование: Защита конфиденциальной информации с использованием методов шифрования для предотвращения неправомерного доступа или раскрытия данных.

  • Аудит и логирование: Создание систем отслеживания и записи действий и событий в системе для последующего анализа и проверки соответствия.

  • Валидация входных данных: Проверка и санация введенной информации для защиты от уязвимостей, таких как SQL-инъекции, кросс-сайтовые скрипты (XSS) и подделка межсайтовых запросов (CSRF).

  • Обновления: Регулярное обновление системы с установкой последних патчей и обновлений безопасности для устранения известных уязвимостей.

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

  • Принцип наименьших привилегий: Предоставление пользовательских прав и привилегий на уровне, необходимом лишь для выполнения определенных задач, минимизируя тем самым риски, связанные с нарушением безопасности.

  • Защищенное соединение: Использование защищенных коммуникационных протоколов, таких как HTTPS или SSL/TLS, для обеспечения конфиденциальности и целостности передаваемых данных.

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

Масштабируемое управление данными

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

В общие принципы масштабируемого управления данными входят следующие составляющие:

  • Шардирование данных: Разделение обширных наборов данных на меньшие сегменты для их распределения по разным хранилищам или обработчикам, что снижает нагрузку на единичные элементы и обеспечивает параллельность в обработке, повышая тем самым производительность.

  • Распределённые базы данных: Применение распределённых систем хранения данных, которые могут распределять информацию по множеству узлов или серверов, способствуя горизонтальному масштабированию и улучшению производительности.

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

  • Кэширование и хранение в памяти: Использование кэша для часто запрашиваемой информации или хранение данных в памяти обеспечивает быстрый доступ и уменьшает зависимость от операций ввода-вывода, что способствует увеличению скорости обработки.

  • Индексация и оптимизация запросов: Разработка эффективных индексов и оптимизация запросов для ускорения поиска и обработки данных в больших объёмах информации.

  • Сжатие данных: Применение техник сжатия для уменьшения объёма данных, что улучшает процесс их хранения и передачи, особенно в случае больших наборов данных.

  • Архивация и очистка данных: Организация процессов архивации и удаления старых или редко используемых данных для сокращения объёма хранения и обеспечения более высокой производительности системы.

  • Масштабируемые платформы обработки данных: Использование масштабируемых решений, таких как Apache Hadoop, Apache Spark или Apache Flink, для обработки больших данных в распределённой среде.

  • Облачное управление данными: Оптимизация данных с помощью облачных сервисов, таких как Amazon S3, Amazon RDS или Google Bigtable, которые предоставляют гибкие и масштабируемые опции хранения и обработки данных.

  • Мониторинг и тестирование масштабируемости: Постоянный контроль за производительностью и проведение специальных тестов на масштабируемость для выявления и устранения узких мест, ограничений ресурсов и других проблем, а также для подтверждения, что методы управления данными адекватно справляются с увеличением объёмов информации и нагрузки.

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

Паттерны проектирования

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

В зависимости от сферы применения, паттерны проектирования можно классифицировать на различные категории, включая:

  • Порождающие паттерны: Эти паттерны фокусируются на методах создания объектов, предлагая гибкие и повторно используемые подходы. К таким паттернам относятся Singleton, Factory Method, Abstract Factory, Builder и Prototype.

  • Структурные паттерны: Они направлены на упорядочение классов и объектов для создания более обширных структур или систем. Примеры включают Adapter, Bridge, Composite, Decorator и Facade.

  • Поведенческие паттерны: Эти паттерны ориентированы на управление взаимодействием и обменом информацией между объектами или компонентами системы. В их число входят Observer, Strategy, Command, Iterator и Template Method.

  • Архитектурные паттерны: Они предоставляют рекомендации для разработки общей структуры систем на высоком уровне. Среди примеров можно выделить MVC (Model-View-Controller), MVVM (Model-View-ViewModel), слоистую архитектуру, микросервисы и событийно-управляемую архитектуру.

Паттерны проектирования являются ключевым элементом в системном проектировании, так как они обеспечивают испытанные и стандартизированные решения для распространённых задач проектирования, усиливают качество программного кода и способствуют лёгкости его поддержки и расширения.

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

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

Оптимизация производительности

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

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

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

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

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

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

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


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

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

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

Спасибо за прочтение(:

Комментарии (20)


  1. Ctochastik
    04.05.2024 17:03
    +4

    Хороший обзор, спасибо. Я бы ещё добавил про Monolith First Approach - иногда рациональнее не пытаться всё создавать с микросервисов


  1. vic_1
    04.05.2024 17:03
    +1

    Охренеть, постарался, спс


  1. splatt
    04.05.2024 17:03
    +5

    История из серии "ожидание - реальность".

    Проходил как-то собеседование в одну из FAANG компаний. Изучил кучу подготовительных материалов (включая их собственные, которые они высылают заранее, где была схема как в статье).

    На собеседовании по system design мне предложили сделать бесконечный скролл ленты новостей, при этом исключительно фронтенд, "don't worry about back-end" (huh?)

    На любые мои вопросы о требованиях к дизайну фичи (о каких платформах идет речь, разрешена ли автоматическая подгрузка или пользователь должен нажать load more, сколько новостей планируется загружать за раз, какой объем данных, планируется ли подгрузка новых новостей или только старых т.е. должна ли быть лента двухсторонняя итд), собеседующий (не очень) велживо уходил от ответа.

    А при попытке объяснить, что при дизайне таких систем нужно начинать с high level understanding (невозможно "просто придумать фронтенд" не зная, как будет работать бэкенд или хотя бы какие к нему должны быть требования) собеседующий предлагал "приступить уже к работе" и "начинать уже писать какой-нибудь код"

    Надо сказать что по окончанию интервью я так и не понял, что именно собеседующий от меня хотел, и в компанию меня не взяли.


    1. amazingname
      04.05.2024 17:03

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

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


    1. emerald_isle
      04.05.2024 17:03
      +1

      Неожиданно, конечно. Обычно подобные уточняющие вопросы сами по себе - жирный плюс к вашей оценке. Тогда как сам вопрос намеренно с размытой формулировкой, чтобы тысячи уточнений можно было задать.


    1. amazingname
      04.05.2024 17:03
      +1

      А.. я кажется понял что это у вас было. Это вероятно был первый раунд интервью, на котором отбрасывают тех кто вообще не знает как писать код.

      Например, меня тоже однажды попросили написать контроллер с пейджингом, и их интересовало исключительно, знаю ли я синтаксис. Т.е. я должен был помнить команды linq для пропуска и выбора N, нужные для пейджинга. После того как я толком не вспомнил, на полном серьезе стали объяснять мне, что пейджинг это хитрая вещь, не каждый с ней справляется и нужно сначала пропустить а потом получить N. Но в целом они были убеждены, что если человек не помнит синтаксис для пейджинга, значит он не строчит контроллеры целыми днями и значит им такой человек не нужен, будь он хоть супер-программистом.

      Т.е. это то о чем я выше писал - вместо того чтобы проверить уровень разработчика они ищут маркеры, отмечающие насколько часто он сталкивается с задачами которые ему собираются давать. У меня например спрашивали что означают ошибки 400 и 404. За недостаточно уверенным ответом последовало "если вы веб разрабочтик, как вы можете плохо помнить такие просты ошибки", на ответ, что это все обычно пишут мидлы, а я уже больше 5 лет как тимлид, спросили - "эта должность была чисто менеджерская без программирования?" и так далее. Как проходить подобные интервью пока не понял, задают десяток подобных вопросов и всегда находят что-то что не помнишь здесь и сейчас и что по их мнению кодер всегда помнит.

      На их вопрос про ленту надо было тупо настрочить хоть что-то чтобы они поняли что вы делаете подобные вещи периодически.


      1. imanushin
        04.05.2024 17:03

        Как проходить подобные интервью пока не понял, задают десяток подобных вопросов и всегда находят что-то что не помнишь здесь и сейчас и что по их мнению кодер всегда помнит.

        Если в роли предполагается знания языков программирования (ну или определенного), то необходимо показать необходимый уровень, причем каждый следующий включает в себя предыдущий. Условно говоря, джуниор может завалиться на вопросе для мидла, а синьор (и, особенно, тимлид) - нет.

        Другими словами, если Вы не пишете код (а потому собеседование будет пройти непросто), то лучше выбирать роли чистого управленца, где будут спрашивать про MBA, попросят показать, как Вы выбираете risk appetite и пр.


        1. amazingname
          04.05.2024 17:03

          Я еще как пишу код, и на вопросы типа "в какой момент конкурентный dictionary будет залочен весь" отвечаю без проблем. Потому что этот вопрос на понимание а не маркеры релевантности опыта.

          Проблема с маркерами в том, что у вас должен быть в точности тот опыт, который они ждут и прямо вчера, иначе вы никогда не вспомните как называется что-то про что они спрашивают. Причем беда в том, что таких вопросов на маркеры задают 10 и если хотя-бы в одном не совсем в цель - сразу отбрасывают. Если ты достаточно универсальный специалист, который писал на всем подряд, то поди вспомни "Какие есть команды, чтобы прочитать последнее значение из observable RxJS?". Но они похоже рассуждат "нам нужен фулскак с ангуларом, который целыми днями шлепает формы, значит он должен это по идее помнить, если не помнит, нам такой не нужен".


      1. splatt
        04.05.2024 17:03

        А.. я кажется понял что это у вас было. Это вероятно был первый раунд интервью, на котором отбрасывают тех кто вообще не знает как писать код.

        Лол нет. То о чем вы говорите - это phone screen. А это было именно Systems Design интервью, последний раунд on-site (хотя дело было в самом начале пандемии, так что всё-равно по видео). Уже после recruiter phone screen, technical phone screen, и трех раундов coding interview. С материалами подготовки прямо как в этой статье, которые сам интервьюер видимо не читал.


        1. amazingname
          04.05.2024 17:03

          В опыте за последние два месяца phone screen - это разговор с HR. После него традиционно следует короткое тех интервью на 45 минут на котором индус с ужасным акцентом, сломанным микрофоном и половиной головы на экране проверяет по списку ответы на вопросы. Что у них дальше пока ни разу дальше не смог пройти :). Поэтому скорее примут свои аутсортеры у которых все привычнее.


        1. shuron
          04.05.2024 17:03

          Не повезло.
          У меня тоже есть подобный опыт.
          Вообщ процессы найма в компаниях иногда оочень странные.
          Большая удача конгда интервьюэры действительно хотят разобраться в том что ты можешь а что нет и что тебя мотивирует и если это налажено уже многое говорит о компании.


      1. AccountForHabr
        04.05.2024 17:03
        +1

        Linq Skip и Take это по-моему база. Неужели трудно повторить базу перед прохождением собеса? Ну и TL оценивают и как разработчика при прохождении интервью.


        1. amazingname
          04.05.2024 17:03
          +2

          Так они же в вакансии не пишут, что требуется бэк-енд девелопер, который будет писать Rest API для UI. Они пишут что нужен Angular/React - .Net фул-стак со знанием Azure/AWS, MS SQL/MongoDB, практическм опытом CI/CD, Docker, не менее одного года работы с Kafka (серьезно, так и было написано), стронг в multi-threading и безопасности.
          Учитывая что шансы на каждом отдельном подобном собесе на международном рынке сейчас 1:100, представьте объем синтаксиса который нужно держать в голове для того чтобы получить работу при том что невозможно найти идеально релевантную позицию, приходится пробовать на все близкие. Еще месяц хождений по собесам и он будет у меня в голове, но это сплошная мука, если честно.

          Моя теория - эти люди упрощают себе задачу. Пользуясь тем что на рынке сейчас по 10 кандидатов на каждое место они не пытаются выяснить кто может работать а просто проверяют помнишь ли ты все что по их мнению понят участники их проекта.

          Возможно я не во все пока въехал. Если у кого-то есть опыт как крякнуть эти скрины с индусами, пишите :).


          1. splatt
            04.05.2024 17:03

            Есть книга, которая так и называется, Cracking the coding interview. Сильно рекоммендую.


  1. AntonLarinLive
    04.05.2024 17:03

    Сравните с наймом начальников над программистами:
    - Я подниму вам $NNN за два года. Я уже такое сделал в пяти местах. И ещё я племянник зама CFO.
    - Вы приняты.


  1. murkin-kot
    04.05.2024 17:03
    +3

    К сожалению, тема архитектуры в ИТ отдана на откуп дизайнеров, которые художники, литераторы, но никак не инженеры.

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

    Инженеры гарантируют что-то в своих конструкциях доказуемо, то расчётами и ссылками на данные об известных экспериментах. Как гарантируют что-то "архитекторы" (которые художники)? Вот так:

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

    То есть они гарантируют, что они способны. Очень надёжная гарантия!

    Или вот ещё:

    Для оценки надежности часто используются такие показатели, как среднее время между отказами

    Ну ведь прекрасно! Дом стоит сто лет - он надёжен! А вот самолёт непрерывно летает всего несколько часов, а потом его надо обслуживать. Он ненадёжен (по мнению архитекторов), ведь среднее время между отказами в сложной системе на порядки меньше, чем в простой. Значит архитектор всегда выберет надёжное решение - дом, который не то что летать, двигаться не сможет. Да, это решение с высокой надёжностью (в сравнении с самолётом), но решает ли оно проблемы заказчика? По критерию, выбранному архитекторами - оно прекрасно решает все возможные проблемы.

    Или вот так они голосуют за безопасность:

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

    В списке для презентации заказчику указаны "лучшие практики"? Указаны, аж две или три штуки! Всё, мы в безопасности!

    И так же во всём остальном:

    Паттерны проектирования в области системных разработок представляют собой проверенные и широко применяемые решения

    Слизал стандартное решение у соседа - молодец! Оно проверено и широко применяется. Ну и что, если другие давно в кроссовках ходят вместо лаптей, зато лапти проверены тысячами лет эксплуатации!

    Вы скажете ,что в лаптях неудобно бегать? Не проблема. Архитектор вам ответит вот так:

    Производительность в контексте системного проектирования обозначает способность программной системы быстро и эффективно обрабатывать данные

    То есть в лаптях тоже можно быстро и эффективно что-то обрабатывать. А насколько быстро? Это уже вопрос не к архитектору, он за свою работу (в основном языком) деньги уже честно получил.

    Как-то так и получается в итоге, что в стране 900 000 (почти миллион, да) программистов, а автоматизацией пока лишь пугают, поскольку до завершения этого прибыльного процесса ещё очень и очень далеко. Зато сколько на такую орду нужно архитекторов!


    1. WhatAboutSE
      04.05.2024 17:03

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


  1. AlexunKo
    04.05.2024 17:03

    Очень здорово когда это изложено в одном месте. Конечно, многое все еще остается за бортом, но 80% вещей с собеседований оно таки покрывает.


  1. ermadmi78
    04.05.2024 17:03
    +4

    System Design Interview - практика хорошая. Но опасная. Так как в руках неопытного интервьюера такое собеседование очень быстро превращается в игру "угадай мелодию", и, по сути, начинает работать как инструмент "отрицательного отбора". Если кандидат угадал "идеальную" архитектуру, которую интервьюер спроектировал в своей голове - он проходит. Предложил что-то "нестандартное" - т.е. выходящее за рамки компетенций и/или профессионального опыта интервьюера - не проходит.

    Поэтому, чтобы практика System Design Interview начала приносить пользу, необходимо сначала очень тщательно отобрать самих интервьюеров. И, крайне желательно, чтобы собеседование проводил не один, а несколько независимых друг от друга интервьюеров. И, чтобы независимые интервьюеры во время подготовки отчета по результатам собеседования не общались между собой и не знали оценки своих коллег. Так можно существенно снизить уровень "субъективизма" при принятии решения, и избежать отрицательного отбора.


  1. Batalmv
    04.05.2024 17:03

    Ни о чем :)

    По сути перечисление без понимания "КАК" :)

    Ну прочитали вы, что надо быть умным и красивым. А вот как таким стать...