System Design: frontend
Сегодня разберём задачку, которую реально дают на секции систем дизайн в Авито. Условие короткое: «спроектируй конструктор виджетов на JS-фреймворке» — штука, где из готовых блоков собираешь кусок интерфейса (карточку, баннер, секцию на выдаче) и выкатываешь пользователям.
Первое, что приходит в голову — drag-n-drop: таскаешь блоки по канвасу, а на выходе он генерит React-компоненты. За полчаса набросал, вроде работает. И вот тут ты уже проиграл: ты сделал «редактор, который выплёвывает вёрстку», а задача была про систему, которой пользуются не только разработчики и которая живёт дольше одного релиза фронта. Дальше весь пост — как из первого прийти во второе.
Начнем с вопросов, а не с кода
Условие специально дают без требований: ждут, что ты сам очертишь границы. Так что не лезь в код, сначала спроси. И главный вопрос один: кто собирает интерфейс в этом конструкторе и где потом рендерится результат. Звучит организационно, а на деле именно он задаёт всю архитектуру — сейчас увидишь как.
Идём за этим вопросом
Скорее всего дадут такой ответ(тут зависит от интервьюера конечно же, в какую степь он захочет уйти): собирать интерфейс часто будет не разработчик, а контент-менеджер. А результат должен приезжать не только на веб, но и на iOS с Android - и без релиза приложения. И это меняет всё: JS в стор мгновенно не докатишь, нативную вёрстку из React не соберёшь. Значит выход конструктора в принципе не может быть кодом. Отсюда рождается ядро всей задачи: конструктор не генерит вёрстку, он собирает её описание — сериализуемое дерево, JSON: какие виджеты, в каком порядке, с какими параметрами. А рисует это дерево отдельный рендер-движок, свой на каждой платформе. Вёрстка тут — данные, а не код. Называется это Backend-Driven UI; в Авито ровно ради этого построили движок Beduin. Придёшь к этому сам — ответ уже не джуна, а если и назвать в качестве примера известную реализацию твоей идеи, то это +реп сразу.
Раз вёрстка — это данные
Дальше всё вытекает из этой мысли. Виджет — независимый переиспользуемый блок с контрактом: строго типизированные параметры, у каждого свой тип и обязательность. И первый жирный плюсик: форму настройки не пишем руками под каждый блок, а генерим из контракта. Разработчик зарегистрировал виджет в каталоге, описал параметры — конструктор сам построил форму. Иначе на сотне виджетов утонешь в формочках. У Авито это так и устроено в их Bricks — привести известную реализацию к своим мыслям всегда +реп.
Где сыпятся
Все грабли — из той же мысли «это данные». Забыл про неё — провалился. Наверное, самое тонкое место - превью. Блок, который контент-менеджер видит в редакторе, должен рендериться по тем же правилам, что и прод у юзера — из того же описания и тем же рендером, а не отдельным мокапом на React. Иначе разойдутся: собрал красиво, опубликовал, а у юзера поехало. Никакого eval — это прямое следствие того, что описание есть данные. JSON пришёл из админки, где сидит не разработчик: валидируем по схеме (те ли типы, на месте ли обязательные поля, разрешённый ли виджет), но не исполняем. Начнёшь evalить — получишь дыру в безопасности и падение на первом же кривом вводе.
И то, на чём спотыкаются новички: не перерисовывай весь канвас на каждое изменение. Поменяли цвет у кнопки — обнови только кнопку. Иначе на большом макете редактор залагает на каждое нажатие.
Что тут на самом деле проверяют
Всё сводится к одному: понимаешь ли ты, что редактор с блоками — самая маленькая часть задачи. Собрать вёрстку из виджетов умеет и джун, это верхушка. А спроектировать надо то, что под ней: как это описание хранить и версионировать, доставлять на веб и обе мобилки, подтягивать в блоки живые данные, катить без релиза и откатывать, если сломается. Задал один вопрос «кто собирает и где рендерится» — и вся эта система развернулась сама.
В следующем посте — задача от Яндекса, которую дают бэкендерам!
Кстати, если хотите оставаться в тренде айти рынка и его требований, то советую наши курсы старт, на который мы продлили финальные скидки на 24 часа.
➡️ Записаться
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Сегодня разберём задачку, которую реально дают на секции систем дизайн в Авито. Условие короткое: «спроектируй конструктор виджетов на JS-фреймворке» — штука, где из готовых блоков собираешь кусок интерфейса (карточку, баннер, секцию на выдаче) и выкатываешь пользователям.
Первое, что приходит в голову — drag-n-drop: таскаешь блоки по канвасу, а на выходе он генерит React-компоненты. За полчаса набросал, вроде работает. И вот тут ты уже проиграл: ты сделал «редактор, который выплёвывает вёрстку», а задача была про систему, которой пользуются не только разработчики и которая живёт дольше одного релиза фронта. Дальше весь пост — как из первого прийти во второе.
Начнем с вопросов, а не с кода
Условие специально дают без требований: ждут, что ты сам очертишь границы. Так что не лезь в код, сначала спроси. И главный вопрос один: кто собирает интерфейс в этом конструкторе и где потом рендерится результат. Звучит организационно, а на деле именно он задаёт всю архитектуру — сейчас увидишь как.
Идём за этим вопросом
Скорее всего дадут такой ответ(тут зависит от интервьюера конечно же, в какую степь он захочет уйти): собирать интерфейс часто будет не разработчик, а контент-менеджер. А результат должен приезжать не только на веб, но и на iOS с Android - и без релиза приложения. И это меняет всё: JS в стор мгновенно не докатишь, нативную вёрстку из React не соберёшь. Значит выход конструктора в принципе не может быть кодом. Отсюда рождается ядро всей задачи: конструктор не генерит вёрстку, он собирает её описание — сериализуемое дерево, JSON: какие виджеты, в каком порядке, с какими параметрами. А рисует это дерево отдельный рендер-движок, свой на каждой платформе. Вёрстка тут — данные, а не код. Называется это Backend-Driven UI; в Авито ровно ради этого построили движок Beduin. Придёшь к этому сам — ответ уже не джуна, а если и назвать в качестве примера известную реализацию твоей идеи, то это +реп сразу.
Раз вёрстка — это данные
Дальше всё вытекает из этой мысли. Виджет — независимый переиспользуемый блок с контрактом: строго типизированные параметры, у каждого свой тип и обязательность. И первый жирный плюсик: форму настройки не пишем руками под каждый блок, а генерим из контракта. Разработчик зарегистрировал виджет в каталоге, описал параметры — конструктор сам построил форму. Иначе на сотне виджетов утонешь в формочках. У Авито это так и устроено в их Bricks — привести известную реализацию к своим мыслям всегда +реп.
Где сыпятся
Все грабли — из той же мысли «это данные». Забыл про неё — провалился. Наверное, самое тонкое место - превью. Блок, который контент-менеджер видит в редакторе, должен рендериться по тем же правилам, что и прод у юзера — из того же описания и тем же рендером, а не отдельным мокапом на React. Иначе разойдутся: собрал красиво, опубликовал, а у юзера поехало. Никакого eval — это прямое следствие того, что описание есть данные. JSON пришёл из админки, где сидит не разработчик: валидируем по схеме (те ли типы, на месте ли обязательные поля, разрешённый ли виджет), но не исполняем. Начнёшь evalить — получишь дыру в безопасности и падение на первом же кривом вводе.
И то, на чём спотыкаются новички: не перерисовывай весь канвас на каждое изменение. Поменяли цвет у кнопки — обнови только кнопку. Иначе на большом макете редактор залагает на каждое нажатие.
Что тут на самом деле проверяют
Всё сводится к одному: понимаешь ли ты, что редактор с блоками — самая маленькая часть задачи. Собрать вёрстку из виджетов умеет и джун, это верхушка. А спроектировать надо то, что под ней: как это описание хранить и версионировать, доставлять на веб и обе мобилки, подтягивать в блоки живые данные, катить без релиза и откатывать, если сломается. Задал один вопрос «кто собирает и где рендерится» — и вся эта система развернулась сама.
В следующем посте — задача от Яндекса, которую дают бэкендерам!
Кстати, если хотите оставаться в тренде айти рынка и его требований, то советую наши курсы старт, на который мы продлили финальные скидки на 24 часа.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤2👍1
Forwarded from Поступашки - ШАД, Стажировки и Магистратура
У России три пути: 18+, ***** и IT
И кажется, у нас случился переход между карьерными треками…
Нам неважно, какой у человека бэкграунд и чем он занимался раньше. Важно, куда он хочет прийти и что готов для этого делать.
Наша студентка, Алина, решила кардинально сменить сферу, пришла на «СТАРТ» и теперь готовится к своей новой цели — получить оффер в Яндекс.
Можно следить за успехами и учиться вместе с Алиной. На наши курсы старт, идут финальные 4 часа скидки.
➡️ Записаться
И кажется, у нас случился переход между карьерными треками…
Нам неважно, какой у человека бэкграунд и чем он занимался раньше. Важно, куда он хочет прийти и что готов для этого делать.
Наша студентка, Алина, решила кардинально сменить сферу, пришла на «СТАРТ» и теперь готовится к своей новой цели — получить оффер в Яндекс.
Можно следить за успехами и учиться вместе с Алиной. На наши курсы старт, идут финальные 4 часа скидки.
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Поступашки - ШАД, Стажировки и Магистратура
This media is not supported in your browser
VIEW IN TELEGRAM
⚡2
System Design: backend
Как и обещал — задачка с бэковой секции Яндекса. На system design там реально дают «спроектируй ленту новостей, как в Твиттере/ВК, где новостные посты выдаются на основе подписок на авторов»: человек подписан на кучу людей, открывает приложение и видит их посты, свежие сверху. Погнали.
Базовая идея — идти от базы: на открытии ленты делаем
Уточняем детали
Сначала уточни границы: сколько подписок у среднего юзера, сколько постов в день, какая задержка ок. Но главный вопрос один: есть ли у нас звёзды — аккаунты на миллионы подписчиков? Звучит как продуктовая мелочь, а на деле именно он разворачивает всю архитектуру — сейчас увидишь как.
Попробуем зайти от обратного
Ключевая идея, ради которой задача и придумана: не собирай ленту в момент, когда её открыли. Собери заранее. Когда автор публикует пост, мы разносим (fan-out) его по заранее посчитанным лентам всех подписчиков — кладём в «инбокс» каждого. Тогда открыть ленту — дешёвое чтение готового списка, без тяжёлого запроса по всем подпискам. Смысл манёвра: дорогую работу мы перенесли с частого чтения на редкую запись. Пост пишут один раз, а ленту с ним открывают тысячи раз — вот пусть будет тяжело один раз на записи, а не тысячу раз на чтении.
Возвращаемся к звёздам
А теперь тот самый вопрос. Fan-out на записи прекрасен — пока блогер с 40 миллионами подписчиков не нажмёт «опубликовать». Один пост превращается в 40 миллионов записей, разом, всплеском. Одна звезда убивает всю схему. Поэтому — гибрид. Обычные аккаунты разносим по подписчикам на записи. А посты звёзд не разносим: их мало, зато подписчиков тьма. Их подтягиваем в момент чтения и подмешиваем в готовую ленту. Разложил систему на два пути ровно из-за вопроса про звёзд — это ответ уже не ниже мидла.
В целом вся задача это пример из «Designing Data-Intensive Applications» Клеппманна, первая глава там ровно про ленту Твиттера. Готовишься к систем дизайну — тогда стоит ознакомиться с этой книжкой, не пожалеешь.
Где запнуться можно
Всё вытекает из мысли «работаем на записи». Забыл — провалился. Разнос — асинхронный, через очередь. Автор нажал «опубликовать» — его запрос не ждёт, пока пост доедет до десятков тысяч лент: кинули задачу в брокер, ответили сразу, подписчики увидят через секунду. Тут ок eventual consistency — лента не банковский баланс. В инбоксы кладём не посты, а их id. Хранить полный текст в ленте у каждого из тысяч подписчиков — копия одного и того же миллион раз. Держим ссылки, сам пост подтягиваем при чтении. Не разноси мёртвым душам: если юзер не заходил полгода, гонять его ленту на каждый пост подписок — жечь ресурсы впустую. Соберём на чтении, если вернётся. И идемпотентность: разнос будет ретраиться при сбоях, один и тот же пост не должен лечь в ленту дважды.
На что нацелена задача по итогу
Проверяют этой задачей одно: видишь ли ты, где в системе на самом деле тяжело. Наивный SELECT по подпискам — «лента как страница в базе», его напишет и джун. А инженер замечает, что ленту открывают в тысячи раз чаще, чем пишут пост, и переносит всю тяжесть туда, где она случается редко — на запись. Дальше это само тянет за собой и очередь, и гибрид под звёзд, и хранение по ссылкам: весь дизайн — следствие одного решения, считать ленту заранее, а не на лету. Дожал эту мысль — секция твоя.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Как и обещал — задачка с бэковой секции Яндекса. На system design там реально дают «спроектируй ленту новостей, как в Твиттере/ВК, где новостные посты выдаются на основе подписок на авторов»: человек подписан на кучу людей, открывает приложение и видит их посты, свежие сверху. Погнали.
Базовая идея — идти от базы: на открытии ленты делаем
SELECT * FROM posts WHERE author IN (на кого подписан) ORDER BY time LIMIT 50. В деве летает. Но в продовой бд так не прокатит: у юзера тысяча подписок, у каждого тысячи постов, и так одновременно долбят миллионы людей. Лента открывается на каждый заход — чтение это самый горячий путь, и вот на нём база и ляжет. Дальше обсудим, какое примерное решение от тебя ждут на собесе.Уточняем детали
Сначала уточни границы: сколько подписок у среднего юзера, сколько постов в день, какая задержка ок. Но главный вопрос один: есть ли у нас звёзды — аккаунты на миллионы подписчиков? Звучит как продуктовая мелочь, а на деле именно он разворачивает всю архитектуру — сейчас увидишь как.
Попробуем зайти от обратного
Ключевая идея, ради которой задача и придумана: не собирай ленту в момент, когда её открыли. Собери заранее. Когда автор публикует пост, мы разносим (fan-out) его по заранее посчитанным лентам всех подписчиков — кладём в «инбокс» каждого. Тогда открыть ленту — дешёвое чтение готового списка, без тяжёлого запроса по всем подпискам. Смысл манёвра: дорогую работу мы перенесли с частого чтения на редкую запись. Пост пишут один раз, а ленту с ним открывают тысячи раз — вот пусть будет тяжело один раз на записи, а не тысячу раз на чтении.
Возвращаемся к звёздам
А теперь тот самый вопрос. Fan-out на записи прекрасен — пока блогер с 40 миллионами подписчиков не нажмёт «опубликовать». Один пост превращается в 40 миллионов записей, разом, всплеском. Одна звезда убивает всю схему. Поэтому — гибрид. Обычные аккаунты разносим по подписчикам на записи. А посты звёзд не разносим: их мало, зато подписчиков тьма. Их подтягиваем в момент чтения и подмешиваем в готовую ленту. Разложил систему на два пути ровно из-за вопроса про звёзд — это ответ уже не ниже мидла.
В целом вся задача это пример из «Designing Data-Intensive Applications» Клеппманна, первая глава там ровно про ленту Твиттера. Готовишься к систем дизайну — тогда стоит ознакомиться с этой книжкой, не пожалеешь.
Где запнуться можно
Всё вытекает из мысли «работаем на записи». Забыл — провалился. Разнос — асинхронный, через очередь. Автор нажал «опубликовать» — его запрос не ждёт, пока пост доедет до десятков тысяч лент: кинули задачу в брокер, ответили сразу, подписчики увидят через секунду. Тут ок eventual consistency — лента не банковский баланс. В инбоксы кладём не посты, а их id. Хранить полный текст в ленте у каждого из тысяч подписчиков — копия одного и того же миллион раз. Держим ссылки, сам пост подтягиваем при чтении. Не разноси мёртвым душам: если юзер не заходил полгода, гонять его ленту на каждый пост подписок — жечь ресурсы впустую. Соберём на чтении, если вернётся. И идемпотентность: разнос будет ретраиться при сбоях, один и тот же пост не должен лечь в ленту дважды.
На что нацелена задача по итогу
Проверяют этой задачей одно: видишь ли ты, где в системе на самом деле тяжело. Наивный SELECT по подпискам — «лента как страница в базе», его напишет и джун. А инженер замечает, что ленту открывают в тысячи раз чаще, чем пишут пост, и переносит всю тяжесть туда, где она случается редко — на запись. Дальше это само тянет за собой и очередь, и гибрид под звёзд, и хранение по ссылкам: весь дизайн — следствие одного решения, считать ленту заранее, а не на лету. Дожал эту мысль — секция твоя.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Telegram
Art of Code
По вопросам: @vice22821
Чат: @code_of_art
Чат: @code_of_art
🔥6
System Design: backend
Задача с реального собеса Яндекса. Условие: приходит уведомление — id, тип (EMAIL/SMS/PUSH), получатель, текст. У получателя есть разрешённые каналы и блок-лист отправителей. Нужно отфильтровать уведомление и не отправить дубль, если такое же уже было за последние 24 часа. Хранилище реализовывать не надо — только контракты и логика. Погнали.
Понятное дело, что мы уже люди опытные и не побежим писать код, думать над DTO — мы сразу будем думать над системой проверок уведомлений. Для этого сначала нужно понять, какой информации нам не хватает.
Определим рамки задачи
Сначала границы: какие каналы поддерживаем, откуда берём настройки получателя, что считаем «таким же» уведомлением для дедупа.
Например, что значит «такое же»? «Ваш заказ №123 готов» и «Ваш заказ №124 готов» — дубль или нет? А если одно пришло по EMAIL, а второе по SMS?
Поэтому уточняем:
* дедуп общий для всех каналов или отдельный;
* что именно считается одинаковым уведомлением;
* что считается успешной отправкой;
* какие ожидаются RPS.
Но главный вопрос один: где мы помним, что уже отправляли? Это относится к устройству хранилища, которое нам сказали не реализовывать, но без этой информации нам всё же не обойтись — дальше вернёмся к этому.
Ядро решения
Ключевая мысль: фильтрация — это цепочка независимых проверок, через которую уведомление либо проходит целиком, либо отсеивается на первом же несоответствии.
Не один раздутый
- канал разрешён у получателя;
- отправитель не в блок-листе;
- уведомление не дубль за последние 24 часа.
Первый же фильтр, сказавший «нет», отсекает уведомление — остальные не гоняем. Такую систему легко расширять: новый фильтр = ещё одно звено, а не правка портянки.
Возвращаемся к дедупликации
Дедуп за 24 часа означает, что система должна хранить след недавно отправленных уведомлений. Ключ вроде:
Первый — что именно входит в
Где сыпятся
Порядок фильтров: дешёвые и отсекающие проверки — вперёд. Канал и блок-лист — настройки. Дедуп — поход в стор. Глупо лезть в стор за дедупом, если уведомление и так отсечётся выключенным push.
Но есть ещё одна ловушка — гонка на дедупе. Поэтому
Контракты, а не реализация
Откуда берутся настройки и история отправок — прячем за интерфейсами:
Что тут на самом деле проверяют
Проверяют одно: видишь ли ты, что это не «класс Notification с четырьмя полями», а конвейер фильтров с памятью о недавних отправках. Красивые модели нарисует и джун — и утонет в них, не дойдя до логики. Инженер сразу думает: что проверяем → в каком порядке → где храним состояние → что считаем дублем → что произойдёт при гонке.
А дальше строит pipeline от дешёвых проверок к дорогим, прячет источники данных за контрактами и понимает, что дедупликация — это не просто
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Задача с реального собеса Яндекса. Условие: приходит уведомление — id, тип (EMAIL/SMS/PUSH), получатель, текст. У получателя есть разрешённые каналы и блок-лист отправителей. Нужно отфильтровать уведомление и не отправить дубль, если такое же уже было за последние 24 часа. Хранилище реализовывать не надо — только контракты и логика. Погнали.
Понятное дело, что мы уже люди опытные и не побежим писать код, думать над DTO — мы сразу будем думать над системой проверок уведомлений. Для этого сначала нужно понять, какой информации нам не хватает.
Определим рамки задачи
Сначала границы: какие каналы поддерживаем, откуда берём настройки получателя, что считаем «таким же» уведомлением для дедупа.
Например, что значит «такое же»? «Ваш заказ №123 готов» и «Ваш заказ №124 готов» — дубль или нет? А если одно пришло по EMAIL, а второе по SMS?
Поэтому уточняем:
* дедуп общий для всех каналов или отдельный;
* что именно считается одинаковым уведомлением;
* что считается успешной отправкой;
* какие ожидаются RPS.
Но главный вопрос один: где мы помним, что уже отправляли? Это относится к устройству хранилища, которое нам сказали не реализовывать, но без этой информации нам всё же не обойтись — дальше вернёмся к этому.
Ядро решения
Ключевая мысль: фильтрация — это цепочка независимых проверок, через которую уведомление либо проходит целиком, либо отсеивается на первом же несоответствии.
Не один раздутый
if, а pipeline из мелких фильтров:- канал разрешён у получателя;
- отправитель не в блок-листе;
- уведомление не дубль за последние 24 часа.
Первый же фильтр, сказавший «нет», отсекает уведомление — остальные не гоняем. Такую систему легко расширять: новый фильтр = ещё одно звено, а не правка портянки.
Возвращаемся к дедупликации
Дедуп за 24 часа означает, что система должна хранить след недавно отправленных уведомлений. Ключ вроде:
recipient + type + id. А по нему — время отправки. Пришло новое — считаем ключ и смотрим, существует ли такой за последние 24 часа. И два неочевидных момента.Первый — что именно входит в
notificationIdentity. Сырый текст не всегда подходит: если в нём динамические данные, побайтовое сравнение может дать неправильную семантику. Поэтому сначала выясняем у интервьюера, что бизнес считает дублем. Второй — TTL. Записи должны сами протухать через 24 часа, иначе хранилище будет расти бесконечно.Где сыпятся
Порядок фильтров: дешёвые и отсекающие проверки — вперёд. Канал и блок-лист — настройки. Дедуп — поход в стор. Глупо лезть в стор за дедупом, если уведомление и так отсечётся выключенным push.
Но есть ещё одна ловушка — гонка на дедупе. Поэтому
check() и запись факта отправки должны быть атомарными. Например, через операцию tryReserve(key, ttl): первый запрос получает true, второй — false. А дальше интервьюер вполне может спросить: что будет, если мы зарезервировали уведомление, а внешний провайдер упал? Вот тут уже нужно отдельно определить семантику: защищаемся от повторного вызова сервиса или гарантируем отсутствие повторной доставки пользователю? Это разные задачи.Контракты, а не реализация
Откуда берутся настройки и история отправок — прячем за интерфейсами:
SettingsProvider, HistoryStore, и неважно, Redis там, PostgreSQL или внешний сервис. На собесе мы проектируем логику, а не привязываемся к конкретному хранилищу.Что тут на самом деле проверяют
Проверяют одно: видишь ли ты, что это не «класс Notification с четырьмя полями», а конвейер фильтров с памятью о недавних отправках. Красивые модели нарисует и джун — и утонет в них, не дойдя до логики. Инженер сразу думает: что проверяем → в каком порядке → где храним состояние → что считаем дублем → что произойдёт при гонке.
А дальше строит pipeline от дешёвых проверок к дорогим, прячет источники данных за контрактами и понимает, что дедупликация — это не просто
get() в Redis.Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Telegram
Art of Code
По вопросам: @vice22821
Чат: @code_of_art
Чат: @code_of_art
🔥7👍2🏆2
razbor_testa.pdf
66.4 KB
Обычно здесь разбираем бэкенд и фронтенд, но сегодня о другом.
У Авито сейчас идёт набор на курс по QA. Регистрация была до 16 августа, а до 19-го нужно ещё пройти тест.
Кто уже подался и тест пока не решил — забирайте разбор выше: 32 вопроса, от базы тестирования и приоритетов багов до основ кода, HTTP и командной строки, с подробным объяснением каждого ответа. Сам тест не то чтобы сложный, но лучше сверить логику заранее, чем гадать на скрининге.
Если с регистрацией не успели — тоже гляньте файл, чтобы понять, что ничего сложного нет и можно в будущем пробовать свои силы. Авито обещают фаст-трек после курса, а стажировка в бигтехе — то, о чём многие мечтают. Плюс из QA потом реально перекатиться в бэкенд, так что как способ вкатиться в индустрию вариант неплохой. Просто держите руку на пульсе следующего набора.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
У Авито сейчас идёт набор на курс по QA. Регистрация была до 16 августа, а до 19-го нужно ещё пройти тест.
Кто уже подался и тест пока не решил — забирайте разбор выше: 32 вопроса, от базы тестирования и приоритетов багов до основ кода, HTTP и командной строки, с подробным объяснением каждого ответа. Сам тест не то чтобы сложный, но лучше сверить логику заранее, чем гадать на скрининге.
Если с регистрацией не успели — тоже гляньте файл, чтобы понять, что ничего сложного нет и можно в будущем пробовать свои силы. Авито обещают фаст-трек после курса, а стажировка в бигтехе — то, о чём многие мечтают. Плюс из QA потом реально перекатиться в бэкенд, так что как способ вкатиться в индустрию вариант неплохой. Просто держите руку на пульсе следующего набора.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
❤5🔥2👍1
Гайд на GO в Авитo.pdf
203.4 KB
Полный цикл собесов на Go-разработчика в Авито
Идут последние 5 часов скидки на наши карьерные курсы ПРО. В честь этого в посте разберемся, как на самом деле устроен наём в Авито. Свёл официальный плейбук компании с внутренними методичками для интервьюеров по техническим секциям, которые предоставили наши выпускники. Получилась такая роудмапа: 4-5 встреч от первого созвона до оффера, и на каждом этапе могут разбить на несколько созвонов.
Этап 1. Звонок с рекрутером
Тут все по классике: обсуждение опыта, ожидания от новой работы, причины смены места. Можно и нужно закидывать встречные вопросы про команду и процессы - лучше перед этим с манифестом ознакомиться, так будешь выглядить подшаренным, что +реп дает.
Этап 2. Скоринговое интервью
30 минут в Zoom по техничке, но без лайвкодинга. Спрашивают несложные вопросы: по алгоритмам и структурам данных, языку программирования, HTTP, SQL, Git, Unix. Легкий фильтр перед тем, как тратить 2-3 часа на полноценную техничку, тут просто нужно готовиться по теории, ничего страшного здесь нет.
Этап 3. Техническое интервью
2-3 часа, реальный лайвкодинг на их платформе. Две обязательные секции плюс одна опциональная.
"Программирование" - общая для любого стека часть на алгоритмы и сложность, причём библиотечными функциями пользоваться нельзя, только руками. Час времени, easy/medium задачки, уровень определяют по чёткой сетке: от "не решил ни одной задачи" до "решил всё оптимально, без подсказок, ещё и объясняет вслух". В целом, если вдруг твой код не компилиться из-за синтаксической ошибки например, но ты объяснил свой код, то на это скорее всего закроют глаза просто. Реальные задачи в файле.
"Платформа" - уже под Go: указатели, горутины, каналы, context, сеть. Классика - горутины в цикле, которые ищут максимальное чётное число. Подробнее в файлике.
"Проектирование" - опциональная, идёт последней и только при успешном прохождении первых двух. Главный дифференциатор для выхода на грейд E5 и выше. Дают кейс вроде "спроектируй доску объявлений" или условие под конкретную команду, интервьюер играет заказчика и оценивает не столько итоговую схему, сколько ход рассуждений: начинают с простого варианта, а если остаётся время - усложняют требования. Рисуют в Draw.io, Miro, Whimsical или Excalidraw - стоит заранее зарегистрироваться и освоиться с инструментом, а не разбираться в интерфейсе на самом интервью.
Этап 4. Финальное интервью
Час с нанимающим менеджером и рекрутером. Уже не про код, а про мотивацию, soft skills и culture fit. Расскажут, чем занимается команда и как устроены процессы, а сами посмотрят, комфортно ли вам друг с другом и совпадают ли взгляды с ценностями команды.
Этап 5. Оффер
Письменно или на коротком созвоне. Если не прошли отбор, дают обратную связь, а на техническое интервью можно попробовать зайти повторно через полгода.
Подробней с задачами в прикрепленном файле, все это закрывается на наших курсах. Отзывы о прошлом наборе на курс Бэкенд ПРО здесь и ниже (ставьте бананы).
➡️ Записаться
Подписаться: @postypashki_old
Идут последние 5 часов скидки на наши карьерные курсы ПРО. В честь этого в посте разберемся, как на самом деле устроен наём в Авито. Свёл официальный плейбук компании с внутренними методичками для интервьюеров по техническим секциям, которые предоставили наши выпускники. Получилась такая роудмапа: 4-5 встреч от первого созвона до оффера, и на каждом этапе могут разбить на несколько созвонов.
Этап 1. Звонок с рекрутером
Тут все по классике: обсуждение опыта, ожидания от новой работы, причины смены места. Можно и нужно закидывать встречные вопросы про команду и процессы - лучше перед этим с манифестом ознакомиться, так будешь выглядить подшаренным, что +реп дает.
Этап 2. Скоринговое интервью
30 минут в Zoom по техничке, но без лайвкодинга. Спрашивают несложные вопросы: по алгоритмам и структурам данных, языку программирования, HTTP, SQL, Git, Unix. Легкий фильтр перед тем, как тратить 2-3 часа на полноценную техничку, тут просто нужно готовиться по теории, ничего страшного здесь нет.
Этап 3. Техническое интервью
2-3 часа, реальный лайвкодинг на их платформе. Две обязательные секции плюс одна опциональная.
"Программирование" - общая для любого стека часть на алгоритмы и сложность, причём библиотечными функциями пользоваться нельзя, только руками. Час времени, easy/medium задачки, уровень определяют по чёткой сетке: от "не решил ни одной задачи" до "решил всё оптимально, без подсказок, ещё и объясняет вслух". В целом, если вдруг твой код не компилиться из-за синтаксической ошибки например, но ты объяснил свой код, то на это скорее всего закроют глаза просто. Реальные задачи в файле.
"Платформа" - уже под Go: указатели, горутины, каналы, context, сеть. Классика - горутины в цикле, которые ищут максимальное чётное число. Подробнее в файлике.
"Проектирование" - опциональная, идёт последней и только при успешном прохождении первых двух. Главный дифференциатор для выхода на грейд E5 и выше. Дают кейс вроде "спроектируй доску объявлений" или условие под конкретную команду, интервьюер играет заказчика и оценивает не столько итоговую схему, сколько ход рассуждений: начинают с простого варианта, а если остаётся время - усложняют требования. Рисуют в Draw.io, Miro, Whimsical или Excalidraw - стоит заранее зарегистрироваться и освоиться с инструментом, а не разбираться в интерфейсе на самом интервью.
Этап 4. Финальное интервью
Час с нанимающим менеджером и рекрутером. Уже не про код, а про мотивацию, soft skills и culture fit. Расскажут, чем занимается команда и как устроены процессы, а сами посмотрят, комфортно ли вам друг с другом и совпадают ли взгляды с ценностями команды.
Этап 5. Оффер
Письменно или на коротком созвоне. Если не прошли отбор, дают обратную связь, а на техническое интервью можно попробовать зайти повторно через полгода.
Подробней с задачами в прикрепленном файле, все это закрывается на наших курсах. Отзывы о прошлом наборе на курс Бэкенд ПРО здесь и ниже (ставьте бананы).
Подписаться: @postypashki_old
Please open Telegram to view this post
VIEW IN TELEGRAM
Почему бэкендеру-новичку в 2026 мало уметь перекладывать JSON
Найм изменился. То, что стажёр делал за неделю, Claude и ChatGPT делают за десять минут и модели улучшаются каждый месяц. Итог простой: бизнесу больше не нужны «болванчики», исполняющие задачу по инструкции. Нужны те, кто понимает код, умеет спроектировать распределённую систему и, главное, умеет валидировать ИИ, потому что нейронка может как правдоподобную чушь, так и хороший результат генерировать
Что у джунов:
Junior Go, ITK academy: прямым текстом: PostgreSQL и SQL с транзакциями, JOIN и оптимизацией запросов, базовый Redis, REST API, сетевые протоколы и их уровни, принципы конкурентного программирования в Go, Docker и gRPC. Это джун, а тут уже и многопоточка, и сети, и транзакции.
Junior Java, ИТ-Холдинг Т1: позиция джуновская, а в требованиях: уверенное владение Java Core и multi-threading, знание основ и опыт разработки микросервисных систем, работа с брокерами сообщений (Kafka/RabbitMQ), опыт на высоконагруженных проектах, разные типы БД и понимание CI/CD. Многопоточка и брокеры в джун-вакансии буквально.
Младший Python-разработчик, Ozon: отдел разработки аналитических инструментов и управления данными. Бигтех спокойно берёт джунов на внутреннюю дата-платформу: Python, SQL и базы, REST-интеграции внутренних сервисов, дата-пайплайны.
Общая картина по всему рынку джунов та же: на бэкенде обязательны работа с БД, проектирование REST API и понимание архитектурных паттернов: микросервисы, монолит, event-driven. То есть очереди, кэш, микросервисы и БД глубже, чем «умею JOIN» - это базовый минимум.
А что с мидлами
Middle Go, Т-Банк, команда инструментов продуктовой аналитики: стек PostgreSQL, Kafka, Cassandra, Prometheus, Golang, Kubernetes; нужно понимать архитектуру многокомпонентных систем - балансировку нагрузки и отказоустойчивость, плюс менторить джунов.
Разница между грейдами
Средние вилки по рынку 2026: джун - 80–150 тысяч, миддл - 200–350. И попадают в верх именно те, кто дружит с распределёнкой и многопоточкой.
Именно это мы разбираем на курсе Backend Про. Всё, что нужно молодому специалисту, который хочет реально разбираться в коде и распределённых системах, а не перекладывать JSON. Как раз таких разрабов и требуют российский бигтех и западные компании на текущий момент.
Кому зайдёт:
- Джунам и стажёрам: выйти за пределы типичных CRUD и расширить выбор вакансий;
- Тем, кто имеет опыт и уже метит в миддлы: без архитектуры и распределёнки грейд не поднимут.
Что ботаем по модулям:
Модуль 1. Многопоточка: потоки и процессы, синхронизация, race condition, deadlock, thread-safe структуры. Там, где ИИ врёт чаще всего.
Модуль 2. Сети
Модуль 3. Межсервисное взаимодействие и микросервисы: микросервисы против монолита, RPC, REST, брокеры, gRPC, stateful/stateless.
Модуль 4. Базы: SQL и NoSQL, планы выполнения, блокировки, транзакции, уровни изоляции.
Модуль 5. Highload: репликация, шардирование, балансировка, оптимизация и отказоустойчивость.
Модуль 6. Разбираем blockchain
Отдельно проходимся по систем дизайну
На выходе вы умеете спроектировать систему, объяснить, где она отказывает, ускорить чужой код и поймать то, что нагенерил ИИ. С этим идут и на сильного джуна, и на миддла.
➡️ Записаться
Найм изменился. То, что стажёр делал за неделю, Claude и ChatGPT делают за десять минут и модели улучшаются каждый месяц. Итог простой: бизнесу больше не нужны «болванчики», исполняющие задачу по инструкции. Нужны те, кто понимает код, умеет спроектировать распределённую систему и, главное, умеет валидировать ИИ, потому что нейронка может как правдоподобную чушь, так и хороший результат генерировать
Что у джунов:
Junior Go, ITK academy: прямым текстом: PostgreSQL и SQL с транзакциями, JOIN и оптимизацией запросов, базовый Redis, REST API, сетевые протоколы и их уровни, принципы конкурентного программирования в Go, Docker и gRPC. Это джун, а тут уже и многопоточка, и сети, и транзакции.
Junior Java, ИТ-Холдинг Т1: позиция джуновская, а в требованиях: уверенное владение Java Core и multi-threading, знание основ и опыт разработки микросервисных систем, работа с брокерами сообщений (Kafka/RabbitMQ), опыт на высоконагруженных проектах, разные типы БД и понимание CI/CD. Многопоточка и брокеры в джун-вакансии буквально.
Младший Python-разработчик, Ozon: отдел разработки аналитических инструментов и управления данными. Бигтех спокойно берёт джунов на внутреннюю дата-платформу: Python, SQL и базы, REST-интеграции внутренних сервисов, дата-пайплайны.
Общая картина по всему рынку джунов та же: на бэкенде обязательны работа с БД, проектирование REST API и понимание архитектурных паттернов: микросервисы, монолит, event-driven. То есть очереди, кэш, микросервисы и БД глубже, чем «умею JOIN» - это базовый минимум.
А что с мидлами
Middle Go, Т-Банк, команда инструментов продуктовой аналитики: стек PostgreSQL, Kafka, Cassandra, Prometheus, Golang, Kubernetes; нужно понимать архитектуру многокомпонентных систем - балансировку нагрузки и отказоустойчивость, плюс менторить джунов.
Разница между грейдами
Средние вилки по рынку 2026: джун - 80–150 тысяч, миддл - 200–350. И попадают в верх именно те, кто дружит с распределёнкой и многопоточкой.
Именно это мы разбираем на курсе Backend Про. Всё, что нужно молодому специалисту, который хочет реально разбираться в коде и распределённых системах, а не перекладывать JSON. Как раз таких разрабов и требуют российский бигтех и западные компании на текущий момент.
Кому зайдёт:
- Джунам и стажёрам: выйти за пределы типичных CRUD и расширить выбор вакансий;
- Тем, кто имеет опыт и уже метит в миддлы: без архитектуры и распределёнки грейд не поднимут.
Что ботаем по модулям:
Модуль 1. Многопоточка: потоки и процессы, синхронизация, race condition, deadlock, thread-safe структуры. Там, где ИИ врёт чаще всего.
Модуль 2. Сети
Модуль 3. Межсервисное взаимодействие и микросервисы: микросервисы против монолита, RPC, REST, брокеры, gRPC, stateful/stateless.
Модуль 4. Базы: SQL и NoSQL, планы выполнения, блокировки, транзакции, уровни изоляции.
Модуль 5. Highload: репликация, шардирование, балансировка, оптимизация и отказоустойчивость.
Модуль 6. Разбираем blockchain
Отдельно проходимся по систем дизайну
На выходе вы умеете спроектировать систему, объяснить, где она отказывает, ускорить чужой код и поймать то, что нагенерил ИИ. С этим идут и на сильного джуна, и на миддла.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1👍1
System Design: Frontend
Эту задачу мне давали на собесе в одну из аутсорс компаний. Задача звучит следующим образом. Есть большой продукт с несколькими темами - светлая, тёмная, брендовые под разных заказчиков или разные ивенты. Темы должны переключаться на лету, без перезагрузки, и переиспользоваться между приложениями и командами. Спроектируй темизацию.
Есть соблазн сделать несколько CSS-файлов и переключать их, или прокидывать объект темы через контекст в каждый компонент. Второе к тому же вызовет перерендер всего дерева при смене темы. Задача про то, где физически живёт «текущая тема» и как менять её дёшево.
Первое, что стоит спросить у интервьюера - нужно ли переключение в рантайме без перезагрузки (почти всегда да) и шарятся ли токены между несколькими приложениями или микрофронтами. Второе определяет, куда выносить токены. Заодно уточни, нужны ли пользовательские кастомные темы.
Дальше поток. Дизайн-токены - это единый источник правды для цветов, отступов, шрифтов, радиусов. Не хардкод «#1E90FF» по компонентам, а семантические токены («color-primary», «spacing-md»). Компоненты ссылаются на токены, а не на конкретные значения.
А теперь про очки, и это ключевое решение. Переключение темы в рантайме проще и дешевле всего на CSS-переменных: компоненты используют var(--color-primary), а смена темы — это подмена значений переменных на корневом элементе. Никакого перерендера React вообще - браузер сам перекрашивает. Объясни, почему это лучше передачи темы через JS/контекст: контекст дёргает перерендер всего поддерева, CSS-переменные - нет. Токены выносим в отдельный пакет/слой, чтобы шарить между командами и микрофронтами. Честно назови trade-off: CSS-переменные требуют дисциплины - ни одного захардкоженного цвета в компонентах, иначе тема поедет частично. Проговорил «CSS-переменные вместо JS ради отсутствия перерендера» - это ответ архитектурного уровня.
Задача специфичная и заточена на понимание как CSS, так и JS: нужно помнить, что темизация - это про единый источник правды и про то, где хранится текущая тема, и знаешь ли, почему CSS-переменные бьют JS-переключение по цене.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Эту задачу мне давали на собесе в одну из аутсорс компаний. Задача звучит следующим образом. Есть большой продукт с несколькими темами - светлая, тёмная, брендовые под разных заказчиков или разные ивенты. Темы должны переключаться на лету, без перезагрузки, и переиспользоваться между приложениями и командами. Спроектируй темизацию.
Есть соблазн сделать несколько CSS-файлов и переключать их, или прокидывать объект темы через контекст в каждый компонент. Второе к тому же вызовет перерендер всего дерева при смене темы. Задача про то, где физически живёт «текущая тема» и как менять её дёшево.
Первое, что стоит спросить у интервьюера - нужно ли переключение в рантайме без перезагрузки (почти всегда да) и шарятся ли токены между несколькими приложениями или микрофронтами. Второе определяет, куда выносить токены. Заодно уточни, нужны ли пользовательские кастомные темы.
Дальше поток. Дизайн-токены - это единый источник правды для цветов, отступов, шрифтов, радиусов. Не хардкод «#1E90FF» по компонентам, а семантические токены («color-primary», «spacing-md»). Компоненты ссылаются на токены, а не на конкретные значения.
А теперь про очки, и это ключевое решение. Переключение темы в рантайме проще и дешевле всего на CSS-переменных: компоненты используют var(--color-primary), а смена темы — это подмена значений переменных на корневом элементе. Никакого перерендера React вообще - браузер сам перекрашивает. Объясни, почему это лучше передачи темы через JS/контекст: контекст дёргает перерендер всего поддерева, CSS-переменные - нет. Токены выносим в отдельный пакет/слой, чтобы шарить между командами и микрофронтами. Честно назови trade-off: CSS-переменные требуют дисциплины - ни одного захардкоженного цвета в компонентах, иначе тема поедет частично. Проговорил «CSS-переменные вместо JS ради отсутствия перерендера» - это ответ архитектурного уровня.
Задача специфичная и заточена на понимание как CSS, так и JS: нужно помнить, что темизация - это про единый источник правды и про то, где хранится текущая тема, и знаешь ли, почему CSS-переменные бьют JS-переключение по цене.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
🔥3🤩1
Forwarded from Поступашки - ШАД, Стажировки и Магистратура
Выходим на новый уровень с линейкой 1️⃣ 1️⃣ 1️⃣
Товарищи, если база уже есть, то следующий шаг — углубиться в специализацию, закрыть пробелы, освоить новые инструменты и стать сильнее как специалист.
Для этого мы запускаем ПРО — углублённые карьерные курсы для тех, кто хочет качать карьеру и заработок! Для записи и вопросов — пишите менеджеру
📎 Курсы ПРО подойдут тем, кто:
— уже знает основы и хочет глубже разобраться в своей специализации
— хочет перейти с junior на middle и расти дальше
— готовится к собеседованиям на более сильные позиции
— хочет сменить роль и добрать недостающие навыки
— уже на старте имеет сильную базу и хочет целиться выше стажёрских и junior-позиций
➡️ Действует гарантия: прошел курс, выполнил все рекомендации, но не получил оффер — вернем деньги
➡️ Курс длится 6 недель: теория, практика, домашние задания и пет-проект. Всё это время рядом преподаватель и куратор.
Открываем сразу 5 направлений:
➡️ Аналитика ПРО
➡️ ML ПРО
➡️ Backend ПРО
➡️ Алгоритмы ПРО
➡️ ИИ-агенты ПРО
В программу всех курсов войдет:
🔵 закрытый банк вопросов с интервью топовых бигтехов
🔵 разбор ближайшей стажировки в Т-банк и Яндекс
🔵 mock-собеседования с обратной связью
🔵 рефералка в бигтех после защиты пет-проекта
🔵 карьерная стратегия: резюме, поиск вакансий, подготовка к HR секциям
💰 Бонус для всех записавшихся до 23.08 — курс про поиск валютной удалёнки и работы за рубежом в подарок
Товарищи, если база уже есть, то следующий шаг — углубиться в специализацию, закрыть пробелы, освоить новые инструменты и стать сильнее как специалист.
Для этого мы запускаем ПРО — углублённые карьерные курсы для тех, кто хочет качать карьеру и заработок! Для записи и вопросов — пишите менеджеру
— уже знает основы и хочет глубже разобраться в своей специализации
— хочет перейти с junior на middle и расти дальше
— готовится к собеседованиям на более сильные позиции
— хочет сменить роль и добрать недостающие навыки
— уже на старте имеет сильную базу и хочет целиться выше стажёрских и junior-позиций
Открываем сразу 5 направлений:
Продвинутый SQL, A/B-тесты, эконометрика, Causal Inference и ML.
Вывод модели в прод, MLOps, рекомендательные системы, ранжирование, uplift и динамическое преобразование.
Многопоточка, System Desgin, Микросервисы, базы данных, кеширование, мониторинг и распределённые системы.
Продвинутые алгоритмы и задачи для сложных технических интервью в hft фонды, faang+, для олимпиад и контестов.
Будем разбираться не просто в LLM. Вы научитесь проектировать полноценные агентные системы и за курс соберём 5 собственных AI-агентов и пройдём весь путь от архитектуры и инструментов до работы с RAG, multi-agent системами, MCP, evals и деплоем.
В программу всех курсов войдет:
Please open Telegram to view this post
VIEW IN TELEGRAM
Мы тут постоянно разбираем system design — и по фронту, и по бэку. Но у теории есть одна засада: паттерны легко выучить как список названий. Гидратация, оптимистичное обновление, идемпотентность и т.д. — все слышали, многие даже перескажут определение. А на собесе или в проде вопрос звучит иначе: не «что такое circuit breaker», а «почему у тебя порог в 5 ошибок подряд не сработал» и «что бы ты поменял». И вот тут список названий не помогает.
Поэтому запускаем новую рубрику. Формат простой: берём известный опенсорсный проект — React, etcd, Excalidraw, Kafka, Postgres-обвязки — открываем их реальный код, PR или issue, и смотрим, какой паттерн там применён и, главное, зачем. Не абстрактное «есть коробочка, туда идут запросы», а конкретно: вот была проблема, вот как её решили, вот где решение всё равно упирается в потолок и какой компромисс инженеры сознательно приняли.
Почему это вам поможет. Во-первых, паттерн, увиденный в реальном коде, запоминается совсем не так, как определение из статьи — вы видите, от какой именно боли он спасает и что ломается без него. Во-вторых, это прямая подготовка к собесам: сильные вопросы по систем дизайну почти всегда звучат как «вот тут сделали так, а не иначе — почему?», и после этой рубрики у вас будут заготовленные ответы на реальных примерах, а не на выдуманных. В-третьих — и это, наверное, главное — вы будете учиться на чужом коде крупных проектов и вытаскивать оттуда идеи, возможно, некоторые даже пойдут и прочитают исходники после разборов. И так у вас будет формироваться навык, который отличает мидла от джуна сильнее, чем знание любого конкретного фреймворка.
Что планируется по бэку. Распределённые системы (консенсус, выборы лидера, репликация и почему «сервер подтвердил» ещё не значит «сохранено»), устойчивость под нагрузкой (circuit breaker, rate limiting, backpressure), и работа с данными (очереди, идемпотентность, изоляция транзакций).
Что будет по фронту. Тоже не про «как сверстать кнопку», а про архитектуру: как устроен прерываемый рендеринг в React, почему undo/redo в коллаборативных редакторах переписывают с нуля, как работает изоляция расширений и почему она защищает не от всего, что не так очевидно в optimistic update и реактивности.
Это примерный список того, что планируем разобрать в первую очередь, но если у вас есть предложения, то мы обязательно разберем интересующую вас тему.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Поэтому запускаем новую рубрику. Формат простой: берём известный опенсорсный проект — React, etcd, Excalidraw, Kafka, Postgres-обвязки — открываем их реальный код, PR или issue, и смотрим, какой паттерн там применён и, главное, зачем. Не абстрактное «есть коробочка, туда идут запросы», а конкретно: вот была проблема, вот как её решили, вот где решение всё равно упирается в потолок и какой компромисс инженеры сознательно приняли.
Почему это вам поможет. Во-первых, паттерн, увиденный в реальном коде, запоминается совсем не так, как определение из статьи — вы видите, от какой именно боли он спасает и что ломается без него. Во-вторых, это прямая подготовка к собесам: сильные вопросы по систем дизайну почти всегда звучат как «вот тут сделали так, а не иначе — почему?», и после этой рубрики у вас будут заготовленные ответы на реальных примерах, а не на выдуманных. В-третьих — и это, наверное, главное — вы будете учиться на чужом коде крупных проектов и вытаскивать оттуда идеи, возможно, некоторые даже пойдут и прочитают исходники после разборов. И так у вас будет формироваться навык, который отличает мидла от джуна сильнее, чем знание любого конкретного фреймворка.
Что планируется по бэку. Распределённые системы (консенсус, выборы лидера, репликация и почему «сервер подтвердил» ещё не значит «сохранено»), устойчивость под нагрузкой (circuit breaker, rate limiting, backpressure), и работа с данными (очереди, идемпотентность, изоляция транзакций).
Что будет по фронту. Тоже не про «как сверстать кнопку», а про архитектуру: как устроен прерываемый рендеринг в React, почему undo/redo в коллаборативных редакторах переписывают с нуля, как работает изоляция расширений и почему она защищает не от всего, что не так очевидно в optimistic update и реактивности.
Это примерный список того, что планируем разобрать в первую очередь, но если у вас есть предложения, то мы обязательно разберем интересующую вас тему.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
❤4🔥3
«Кабанчика» обязан знать каждый уважающий себя айти специалист, но осилить 700 страниц сплошного текста не так уж и просто.. Чтобы ты не тратил нервы и силы, я пересказ всю книгу всего за минуту. Смотрим!
https://www.youtube.com/shorts/i0nsmAUByZk
https://www.youtube.com/shorts/i0nsmAUByZk
YouTube
Пересказ "Кабанчика" за минуту | "Высоконагруженные приложения" Мартин Клеппман
Хочешь понять, как работают системы, которые не падают даже при мил...
🔥2
Стажировка в Авито одна из лучших возможностей для старта в разработке:
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету до 30.08 и выполнить тест. Разбор теста уже выложен на нашем курсе бэкенд про.
➡️ Записаться.
Как заполнять анкеты смотрим этот ролик. Вашу анкету оценивают рекрутеры, команды. Если вы им понравитесь, вам дадут видеоинтервью в асинхронном формате, индивидуальное тестовое задание и пригласят на финальные собеседования.
• Видео интервью в асинхронном формате - это, когда вы говорите сами с собой, а ваши ответы записывают. Для подготовки смотрите этот пост.
• Обычно тестовое задание: написать какой-нибудь сервер. Примеры тут
• На собеседовании будут обсуждать тестовое задание. Финальных собеседований может быть несколько: с лидом, с менеджером, с ментором и так далее. Гайд на собесы тут.
При идеальном мэтче, вы в Авито - поздравляю! На единичные стажировки можно подать здесь.
Подписаться: @codeof_art
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету до 30.08 и выполнить тест. Разбор теста уже выложен на нашем курсе бэкенд про.
Как заполнять анкеты смотрим этот ролик. Вашу анкету оценивают рекрутеры, команды. Если вы им понравитесь, вам дадут видеоинтервью в асинхронном формате, индивидуальное тестовое задание и пригласят на финальные собеседования.
• Видео интервью в асинхронном формате - это, когда вы говорите сами с собой, а ваши ответы записывают. Для подготовки смотрите этот пост.
• Обычно тестовое задание: написать какой-нибудь сервер. Примеры тут
• На собеседовании будут обсуждать тестовое задание. Финальных собеседований может быть несколько: с лидом, с менеджером, с ментором и так далее. Гайд на собесы тут.
При идеальном мэтче, вы в Авито - поздравляю! На единичные стажировки можно подать здесь.
Подписаться: @codeof_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Стажировка в Т-банк одна из лучших возможностей для старта в разработке:
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету до 6 сентября и выполнить экзамен. Разбор программирования уже выложен на нашем курсе бэкенд про.
➡️ Записаться.
Как заполнять анкеты смотрим этот ролик. Вашу анкету оценивают рекрутеры, команды. Если вы им понравитесь, вас пригласят на финальное собеседование.
На собесе может быть все, что угодно на усмотрение интервьюера: могут быть даже математические задачи на логику в духе тюремных загадок. Обязателен лайвкодинг с задачами, которые часто подбирают под ваше направление (фронтендерам замыкания и event loop, Goшникам работа с рутинами и т.п.). Технические вопросы сильно зависят от команды: например, в команде T‑Мобайла гоняют по сетям, а в продуктовых в основном спрашивают синтаксис и основы. Иногда собеседование может пройти в формате "вайбчека" без технических вопросов, но это скорее исключение. Короче все, что есть в нашей программе курсов бэкенд старт и бэкенд про. Пример нашего выпускника здесь.
Обычно финальный собес один на полтора часа. Если прям очень хорошо о себя завили в анкете и хорошо показали на собесе - команда может дать хороший отзыв и тогда вам могут предложить еще одно собеседование, но такое бывает редко. Дополнительный финальный собес можно получить, если податься на донабор, который проходит обычно спустя месяц основного набора.
При идеальном мэтче, вы в Т-банке - поздравляю!
Подписаться: @codeof_art
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету до 6 сентября и выполнить экзамен. Разбор программирования уже выложен на нашем курсе бэкенд про.
Как заполнять анкеты смотрим этот ролик. Вашу анкету оценивают рекрутеры, команды. Если вы им понравитесь, вас пригласят на финальное собеседование.
На собесе может быть все, что угодно на усмотрение интервьюера: могут быть даже математические задачи на логику в духе тюремных загадок. Обязателен лайвкодинг с задачами, которые часто подбирают под ваше направление (фронтендерам замыкания и event loop, Goшникам работа с рутинами и т.п.). Технические вопросы сильно зависят от команды: например, в команде T‑Мобайла гоняют по сетям, а в продуктовых в основном спрашивают синтаксис и основы. Иногда собеседование может пройти в формате "вайбчека" без технических вопросов, но это скорее исключение. Короче все, что есть в нашей программе курсов бэкенд старт и бэкенд про. Пример нашего выпускника здесь.
Обычно финальный собес один на полтора часа. Если прям очень хорошо о себя завили в анкете и хорошо показали на собесе - команда может дать хороший отзыв и тогда вам могут предложить еще одно собеседование, но такое бывает редко. Дополнительный финальный собес можно получить, если податься на донабор, который проходит обычно спустя месяц основного набора.
При идеальном мэтче, вы в Т-банке - поздравляю!
Подписаться: @codeof_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Forwarded from Поступашки - ШАД, Стажировки и Магистратура
This media is not supported in your browser
VIEW IN TELEGRAM
Открылся отбор на стажировку в Т-Банк
Задачи уже выложены в нашем чате (тут).
Специально для участников курсов про уже мы уже выложили разбор соответствующих экзаменов. В разборе мы покажем подход к решению задач и как оформить ответ, чтобы получить высокий балл.
Также на курсах будет доступно:
📌 Вопросы и запись — менеджеру
Задачи уже выложены в нашем чате (тут).
Специально для участников курсов про уже мы уже выложили разбор соответствующих экзаменов. В разборе мы покажем подход к решению задач и как оформить ответ, чтобы получить высокий балл.
Также на курсах будет доступно:
🔽 Курс по выходу на доход в валюте🔽 Разбор текущей стажировки Яндекса🔽 Гарантия оффера🔽 Огромный банк технических вопросов🔽 Рефералка в бигтех после защиты пет-проекта🔽 mock-собеседования с обратной связью
Please open Telegram to view this post
VIEW IN TELEGRAM
Реальное собеседование на стажировку Go‑разработчика в Т‑Банк
Наш студент сделал расшифровку записи собеса, делимся с вами! Кстати, решение экзамена уже выложено на нашем курсе бэкенд про, ии агенты про и алгоритмы про.
➡️ Записаться.
1. «Расскажи, что такое Firewall?»
Собеседование было в команду, которая разрабатывает host‑based firewall на eBPF с Control Plane в Kubernetes. Интервьюер рассказал про свою команду и задал этот уточняющий вопрос + спросил понял ли я, чем занимается команда.
• Firewall – система, управляющая сетевыми доступами: пропускает или блокирует трафик на основе правил (IP, порты, протоколы).
• Команда пишет распределённый firewall, который работает на десятках тысяч хостов в банке, управляется централизованно через Kubernetes. Стек: Go, eBPF, gRPC, Linux.
2. «Какой у тебя опыт с Linux и сетями?»
Я сам особо не занимался бэкендом и го, знаю основы: модель OSI, TCP vs UDP (TCP надёжный с подтверждением, UDP быстрый без гарантий), маски подсетей, маршрутизацию. Линуксом владею на уровне пользователя, но готов быстро адаптироваться.
3. «Чем процесс отличается от потока? Зачем вообще нужны потоки?»
• Процесс – изолированный экземпляр программы со своей памятью, файловыми дескрипторами.
• Поток – легковесная единица внутри процесса, потоки разделяют память процесса. Потоки нужны для параллельного выполнения задач внутри одного процесса и эффективного обмена данными.
4. «Чем горутина отличается от треда в Go?»
• Горутина – легковесный поток, управляемый рантаймом Go, а не ОС. Она занимает меньше памяти (несколько КБ), переключение между горутинами дешевле. Планировщик Go мультиплексирует горутины на системные треды (модель M:N).
• В отличие от тредов, горутины не привязаны жёстко к одному системному треду.
5. «Что такое gRPC? На каких протоколах работает? В чём отличие HTTP/2 от HTTP/1.1?»
• gRPC – фреймворк для удалённого вызова процедур от Google. Использует HTTP/2 в качестве транспорта и Protobuf для сериализации.
• HTTP/2 поддерживает мультиплексирование запросов, сжатие заголовков, работу в дуплексном режиме.
• По сравнению с HTTP/1.1, это даёт меньшую задержку и более эффективное использование соединений.
6. Задача на ревью кода
Дан HTTP‑хендлер, который проксирует запросы во внешнее API и кеширует ответы, чтобы реже ходить в платное API. Найденные проблемы:
• Кеш не заполнялся – после успешного запроса результат не сохранялся. ➜ Добавлена запись в map.
• Проверка наличия ключа – использовалась
• Метод POST – хендлер принимает только POST, хотя логичнее GET (но это контракт, оставлено).
• Race condition – конкурентные запросы к map без синхронизации. ➜ Добавлен
• Утечка памяти – кеш бесконечно растёт, нет ограничений по размеру или TTL. ➜ Нужно добавить политику вытеснения (LRU) или время жизни записей.
7. «Как бы ты добавил тесты?»
Я предложил тест, который проверяет, что повторный запрос не идёт в API (счётчик вызовов), и что при параллельных запросах нет гонок – с помощью флага
8. «После деплоя сервис падает через несколько дней без паники. Что делать?»
Причина – кеш разрастается до заполнения памяти. Решения:
• добавить ограничение на размер кеша,
• внедрить TTL для записей,
• настроить мониторинг памяти и алерты.
Еще больше вопрос в нашем открытом банке собесов и тестовых заданий: смотрите на сайте.
Подписаться: @codeof_art
Наш студент сделал расшифровку записи собеса, делимся с вами! Кстати, решение экзамена уже выложено на нашем курсе бэкенд про, ии агенты про и алгоритмы про.
1. «Расскажи, что такое Firewall?»
Собеседование было в команду, которая разрабатывает host‑based firewall на eBPF с Control Plane в Kubernetes. Интервьюер рассказал про свою команду и задал этот уточняющий вопрос + спросил понял ли я, чем занимается команда.
• Firewall – система, управляющая сетевыми доступами: пропускает или блокирует трафик на основе правил (IP, порты, протоколы).
• Команда пишет распределённый firewall, который работает на десятках тысяч хостов в банке, управляется централизованно через Kubernetes. Стек: Go, eBPF, gRPC, Linux.
2. «Какой у тебя опыт с Linux и сетями?»
Я сам особо не занимался бэкендом и го, знаю основы: модель OSI, TCP vs UDP (TCP надёжный с подтверждением, UDP быстрый без гарантий), маски подсетей, маршрутизацию. Линуксом владею на уровне пользователя, но готов быстро адаптироваться.
3. «Чем процесс отличается от потока? Зачем вообще нужны потоки?»
• Процесс – изолированный экземпляр программы со своей памятью, файловыми дескрипторами.
• Поток – легковесная единица внутри процесса, потоки разделяют память процесса. Потоки нужны для параллельного выполнения задач внутри одного процесса и эффективного обмена данными.
4. «Чем горутина отличается от треда в Go?»
• Горутина – легковесный поток, управляемый рантаймом Go, а не ОС. Она занимает меньше памяти (несколько КБ), переключение между горутинами дешевле. Планировщик Go мультиплексирует горутины на системные треды (модель M:N).
• В отличие от тредов, горутины не привязаны жёстко к одному системному треду.
5. «Что такое gRPC? На каких протоколах работает? В чём отличие HTTP/2 от HTTP/1.1?»
• gRPC – фреймворк для удалённого вызова процедур от Google. Использует HTTP/2 в качестве транспорта и Protobuf для сериализации.
• HTTP/2 поддерживает мультиплексирование запросов, сжатие заголовков, работу в дуплексном режиме.
• По сравнению с HTTP/1.1, это даёт меньшую задержку и более эффективное использование соединений.
6. Задача на ревью кода
Дан HTTP‑хендлер, который проксирует запросы во внешнее API и кеширует ответы, чтобы реже ходить в платное API. Найденные проблемы:
• Кеш не заполнялся – после успешного запроса результат не сохранялся. ➜ Добавлена запись в map.
• Проверка наличия ключа – использовалась
if val != "", что ломается при пустом ответе. ➜ Использован второй параметр ok при чтении из map.• Метод POST – хендлер принимает только POST, хотя логичнее GET (но это контракт, оставлено).
• Race condition – конкурентные запросы к map без синхронизации. ➜ Добавлен
sync.Mutex с Lock/Unlock при каждом обращении.• Утечка памяти – кеш бесконечно растёт, нет ограничений по размеру или TTL. ➜ Нужно добавить политику вытеснения (LRU) или время жизни записей.
7. «Как бы ты добавил тесты?»
Я предложил тест, который проверяет, что повторный запрос не идёт в API (счётчик вызовов), и что при параллельных запросах нет гонок – с помощью флага
-race.8. «После деплоя сервис падает через несколько дней без паники. Что делать?»
Причина – кеш разрастается до заполнения памяти. Решения:
• добавить ограничение на размер кеша,
• внедрить TTL для записей,
• настроить мониторинг памяти и алерты.
Еще больше вопрос в нашем открытом банке собесов и тестовых заданий: смотрите на сайте.
Подписаться: @codeof_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Открываем новую серию постов. Смысл такой: берём известный проект, смотрим, как в нём решили какую-нибудь неочевидную проблему, и разбираемся, чем этот приём полезен лично тебе в твоём коде. Без душной теории — только то, что реально пригодится. И начать хочу с истории, которая случалась с каждым, кто хоть раз что-то куда-то сохранял.
Ты сохранил данные. Сервис ответил «готово». Ты выдохнул и пошёл дальше. Знакомо? А теперь неприятная новость: «сервис ответил готово» и «данные действительно на месте» — это два разных события. Между ними есть щель, и данные умеют в неё проваливаться. Причём случается это ровно в тот момент, когда что-то ломается, — то есть в самый неподходящий. Чтобы увидеть эту щель во всей красе, посмотрим, как с ней воюет Kafka. А потом вернёмся к твоему коду, потому что проблема там ровно та же.
Как Kafka бережёт данные. Она хранит каждую порцию сообщений сразу на нескольких серверах: один главный, он принимает записи, остальные — его копии, они за ним повторяют. Звучит надёжно. Но вот ловушка, в которую попадают почти все. Главный сервер принял сообщение, записал у себя, ответил «принято» — и в следующую секунду умер. А копии не успели повторить за ним. На его место встаёт одна из копий, но у неё этого сообщения нет. Всё, сообщение исчезло. А отправитель-то уверен, что всё хорошо, — ему же ответили «принято».
Как эту дыру закрывают. У отправителя есть настройка, которая решает, когда считать сообщение сохранённым. Можно сказать «мне хватит, что его принял главный» — быстро, но это ровно та история с исчезновением. А можно потребовать «считать сохранённым, только когда его повторили и живые копии тоже». Вот тогда появляется настоящая гарантия: даже если главный умрёт, сообщение уже есть на других.
Но и это не всё. Что, если копии отстали и по одной повыпадали, а живым остался только главный? Тогда правило «пусть подтвердят копии» тихо превращается в «пусть подтвердит главный» — и мы снова там же, откуда начали. Поэтому есть ещё одна настройка-предохранитель: «если живых копий осталось меньше, чем нужно, — вообще перестань принимать записи и честно скажи об этом». Лучше отказать сразу, чем сделать вид, что всё сохранилось, и потерять данные молча.
И вот тут главная мысль, ради которой всё затевалось. Это выбор, а не значение по умолчанию. Хочешь надёжность — требуй подтверждения от нескольких копий, но тогда при поломке части серверов запись может встать колом (некому подтверждать). Хочешь, чтобы запись шла всегда, — ослабляешь требования, но растёт шанс что-то потерять. Идеального варианта «для всех» нет. Для денег ты выберешь надёжность и переживёшь, что иногда нельзя записать. Для какой-нибудь статистики — наоборот, пусть пишется всегда, а пара потерянных точек погоды не сделает.
А теперь — зачем тебе это, даже если ты Kafka в глаза не видел. Принцип простой и универсальный: ответ «готово» стоит ровно столько, сколько мест реально успели сохранить твои данные. Так что каждый раз, когда твой код получает «ок» откуда-то извне, спроси себя — «ок» от кого и что за ним стоит.
Пара примеров из обычной жизни. Пишешь в базу, у которой есть копии для чтения. Запись прошла, но копии могли ещё не успеть её получить. Читаешь сразу после записи из копии — а там пусто. Та же щель, вид сбоку. Или дёргаешь чужой сервис по сети и получаешь 200. Это значит «я принял твой запрос», а вовсе не «я довёл дело до конца» — если тебе важен именно результат, надо его проверить, а не верить на слово. И везде, где надёжность важнее скорости, ты за неё платишь — тем, что иногда придётся подождать или получить отказ. Это нормально. Ненормально — надеяться, что «да обычно долетает».
Если совсем коротко: надёжность — это не галочка «включил копии и забыл», а осознанное решение, сколько подтверждений тебе достаточно и чем ты за это готов заплатить. Почти все истории про «данные загадочно пропали» — и в Kafka, и в обычном коде — на самом деле про неправильно понятое слово «готово».
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Ты сохранил данные. Сервис ответил «готово». Ты выдохнул и пошёл дальше. Знакомо? А теперь неприятная новость: «сервис ответил готово» и «данные действительно на месте» — это два разных события. Между ними есть щель, и данные умеют в неё проваливаться. Причём случается это ровно в тот момент, когда что-то ломается, — то есть в самый неподходящий. Чтобы увидеть эту щель во всей красе, посмотрим, как с ней воюет Kafka. А потом вернёмся к твоему коду, потому что проблема там ровно та же.
Как Kafka бережёт данные. Она хранит каждую порцию сообщений сразу на нескольких серверах: один главный, он принимает записи, остальные — его копии, они за ним повторяют. Звучит надёжно. Но вот ловушка, в которую попадают почти все. Главный сервер принял сообщение, записал у себя, ответил «принято» — и в следующую секунду умер. А копии не успели повторить за ним. На его место встаёт одна из копий, но у неё этого сообщения нет. Всё, сообщение исчезло. А отправитель-то уверен, что всё хорошо, — ему же ответили «принято».
Как эту дыру закрывают. У отправителя есть настройка, которая решает, когда считать сообщение сохранённым. Можно сказать «мне хватит, что его принял главный» — быстро, но это ровно та история с исчезновением. А можно потребовать «считать сохранённым, только когда его повторили и живые копии тоже». Вот тогда появляется настоящая гарантия: даже если главный умрёт, сообщение уже есть на других.
Но и это не всё. Что, если копии отстали и по одной повыпадали, а живым остался только главный? Тогда правило «пусть подтвердят копии» тихо превращается в «пусть подтвердит главный» — и мы снова там же, откуда начали. Поэтому есть ещё одна настройка-предохранитель: «если живых копий осталось меньше, чем нужно, — вообще перестань принимать записи и честно скажи об этом». Лучше отказать сразу, чем сделать вид, что всё сохранилось, и потерять данные молча.
И вот тут главная мысль, ради которой всё затевалось. Это выбор, а не значение по умолчанию. Хочешь надёжность — требуй подтверждения от нескольких копий, но тогда при поломке части серверов запись может встать колом (некому подтверждать). Хочешь, чтобы запись шла всегда, — ослабляешь требования, но растёт шанс что-то потерять. Идеального варианта «для всех» нет. Для денег ты выберешь надёжность и переживёшь, что иногда нельзя записать. Для какой-нибудь статистики — наоборот, пусть пишется всегда, а пара потерянных точек погоды не сделает.
А теперь — зачем тебе это, даже если ты Kafka в глаза не видел. Принцип простой и универсальный: ответ «готово» стоит ровно столько, сколько мест реально успели сохранить твои данные. Так что каждый раз, когда твой код получает «ок» откуда-то извне, спроси себя — «ок» от кого и что за ним стоит.
Пара примеров из обычной жизни. Пишешь в базу, у которой есть копии для чтения. Запись прошла, но копии могли ещё не успеть её получить. Читаешь сразу после записи из копии — а там пусто. Та же щель, вид сбоку. Или дёргаешь чужой сервис по сети и получаешь 200. Это значит «я принял твой запрос», а вовсе не «я довёл дело до конца» — если тебе важен именно результат, надо его проверить, а не верить на слово. И везде, где надёжность важнее скорости, ты за неё платишь — тем, что иногда придётся подождать или получить отказ. Это нормально. Ненормально — надеяться, что «да обычно долетает».
Если совсем коротко: надёжность — это не галочка «включил копии и забыл», а осознанное решение, сколько подтверждений тебе достаточно и чем ты за это готов заплатить. Почти все истории про «данные загадочно пропали» — и в Kafka, и в обычном коде — на самом деле про неправильно понятое слово «готово».
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
🔥5👍1🎉1
Как стать миддлом
По стеку джуна и мидла сегодня спрашивают почти одно и то же. Открой любые вакансии - знание своего ЯП/фреймворка, SQL, Docker, Kafka/Redis, везде одно и то же. Так за что мидлу платят вдвое больше? Разбираемся на актуальных вакансиях Т-Банка и Ozon.
Джуну дают задачу. Мидлу — проблему
Джуну пишут конкретно, например, написать API под новый микросервис для техподдержки. Задача с границами: понятно, что на входе, что на выходе, когда готово. Бери и делай.
Мидлу пишут абстрактные вещи, для примера, рефакторить интеграционные решения и обеспечивать стабильность работы сервисов. Границ нет, не особо понятно, а какой конечный результат вообще и с чего начать-то. Тебе дают проблему, а задачу из неё ты достаёшь сам. И отвечаешь за результат, если твои микросервисы упадут в разгар рабочего дня и заказчик потеряет деньги, тут уже другой уровень отвественности по сравнению с джуном.
Вот и вся граница: джуна берут за умение закрывать задачи, мидла — за умение отвечать за систему. Всё остальное — следствие.
Стек тот же — уровень владения разный
В вакансиях джуна и мидла — одни и те же технологии. Разница в том, что от тебя с ними ждут.
Джуну: «знать Python», «понимать архитектуру ETL». Знать и понимать.
Мидлу: «проектировать микросервисы», «оптимизировать запросы», «самому работать с Docker». Не слышал про Kubernetes, а крутил руками.
Что конкретно учить, чтобы стать мидлом
«Бери больше ответственности и качай харды» - совет ни о чём. Ниже дам несколько конкертных советов, они не зависят от языка - работают хоть на Go, хоть на Python, хоть на Java.
System design. Главный навык мидла. Спроектировать сервис с нуля: где узкое место, что реплицировать, где кэш, что будет под нагрузкой в 10 раз больше. Это спрашивают почти на каждом собесе на мидла — и именно тут валятся вчерашние джуны.
Базы на уровне оптимизации. Не «умею писать SELECT», а читать план запроса, ставить индексы, понимать, почему запрос тупит на проде под реальными данными.
Docker и Kubernetes. Не теория — собрать образ, написать манифест, задеплоить, разобраться, почему под падает и рестартится в цикле.
Событийная архитектура. Kafka, очереди, как сервисы общаются асинхронно и что происходит с системой, когда один из них отваливается.
CI/CD. Как код доезжает до прода и как сделать так, чтобы релиз не положил систему.
Освоишь эти пять — и на собесе тебе будет что показать. Не строчку в резюме, а умение собрать работающую систему.
Коротко
Джун сидит в своей зоне и пишет задачи внутри неё. Мидл смотрит на проект целиком: как деплоится, как сервисы общаются, что упадёт под нагрузкой, почему вчерашний релиз положил прод. Архитектура для него — не то, что понимаешь, а то, что строишь.
За это и платят: по медиане backend-вакансий 2026 года джун получает около 135 тысяч, мидл — порядка 225. Почти вдвое.
Хочешь дорасти до мидла — не гонись за очередным фреймворком. Учись проектировать системы и отвечать за них. Ровно этому мы учим на нашем курсе бэкенд про.
➡️ Записаться.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
По стеку джуна и мидла сегодня спрашивают почти одно и то же. Открой любые вакансии - знание своего ЯП/фреймворка, SQL, Docker, Kafka/Redis, везде одно и то же. Так за что мидлу платят вдвое больше? Разбираемся на актуальных вакансиях Т-Банка и Ozon.
Джуну дают задачу. Мидлу — проблему
Джуну пишут конкретно, например, написать API под новый микросервис для техподдержки. Задача с границами: понятно, что на входе, что на выходе, когда готово. Бери и делай.
Мидлу пишут абстрактные вещи, для примера, рефакторить интеграционные решения и обеспечивать стабильность работы сервисов. Границ нет, не особо понятно, а какой конечный результат вообще и с чего начать-то. Тебе дают проблему, а задачу из неё ты достаёшь сам. И отвечаешь за результат, если твои микросервисы упадут в разгар рабочего дня и заказчик потеряет деньги, тут уже другой уровень отвественности по сравнению с джуном.
Вот и вся граница: джуна берут за умение закрывать задачи, мидла — за умение отвечать за систему. Всё остальное — следствие.
Стек тот же — уровень владения разный
В вакансиях джуна и мидла — одни и те же технологии. Разница в том, что от тебя с ними ждут.
Джуну: «знать Python», «понимать архитектуру ETL». Знать и понимать.
Мидлу: «проектировать микросервисы», «оптимизировать запросы», «самому работать с Docker». Не слышал про Kubernetes, а крутил руками.
Что конкретно учить, чтобы стать мидлом
«Бери больше ответственности и качай харды» - совет ни о чём. Ниже дам несколько конкертных советов, они не зависят от языка - работают хоть на Go, хоть на Python, хоть на Java.
System design. Главный навык мидла. Спроектировать сервис с нуля: где узкое место, что реплицировать, где кэш, что будет под нагрузкой в 10 раз больше. Это спрашивают почти на каждом собесе на мидла — и именно тут валятся вчерашние джуны.
Базы на уровне оптимизации. Не «умею писать SELECT», а читать план запроса, ставить индексы, понимать, почему запрос тупит на проде под реальными данными.
Docker и Kubernetes. Не теория — собрать образ, написать манифест, задеплоить, разобраться, почему под падает и рестартится в цикле.
Событийная архитектура. Kafka, очереди, как сервисы общаются асинхронно и что происходит с системой, когда один из них отваливается.
CI/CD. Как код доезжает до прода и как сделать так, чтобы релиз не положил систему.
Освоишь эти пять — и на собесе тебе будет что показать. Не строчку в резюме, а умение собрать работающую систему.
Коротко
Джун сидит в своей зоне и пишет задачи внутри неё. Мидл смотрит на проект целиком: как деплоится, как сервисы общаются, что упадёт под нагрузкой, почему вчерашний релиз положил прод. Архитектура для него — не то, что понимаешь, а то, что строишь.
За это и платят: по медиане backend-вакансий 2026 года джун получает около 135 тысяч, мидл — порядка 225. Почти вдвое.
Хочешь дорасти до мидла — не гонись за очередным фреймворком. Учись проектировать системы и отвечать за них. Ровно этому мы учим на нашем курсе бэкенд про.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2
Стажировка в Яндексе одна из лучших возможностей для старта в разработке:
• МНОГО КРАСИВЫХ СВОБОДНЫХ ЖЕНЩИН
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету и зарешать контест. Разбор контеста уже выложен на нашем курсе бэкенд про, алгоритмы про.
➡ Записаться.
Как заполнять анкеты смотрим этот ролик. После контеста вас ждет два алгособеса на 2 литкод задачи medium + вопросы по языке и возможно серверам. И наконец собеседования с командами. На моем опыте максимально, сколько может быть собесов с командой - 9.
Финальные собесы
Если команда точно понимает, что им нужен стажёр закрыть пару дыр и после он не нужен, то собес больше про твой опыт, почему Яндекс, как планируешь совмещать с учебой, а что будешь делать, если стажку не продлим/не возьмём в штат. Такие больше на метч с командой и посмотреть не будешь ли ты ныть, что на стажке будешь заниматься скучной фигней, расскажут какой есть пул задач и спросят, что из этого интересно. Обычно такое в продуктовые команды.
Или, например наш студент, собесился в команду Поиска, которая занимается инфраструктурой. Устроили настоящий собес по систем дизайну, просили спроектировать калькулятор, который вот выдаётся после запроса в поисковой строке, как накрутить серверный рендеринг, гоняли по сетям, по знанию тулов реакта (линтер, сборщик кода как работает, как то-то настроить). И после этого другой интервьюер давил, что вот нам нужны гении, ты явно не такой, а вот чем ты занимаешься, а почему учишься в залупинске, а не в мск, говорил, что на удаленку никого не берём и тд.
Или другой наш студент собесился в другую команду Яндекс 360 календарь, там максимально чилово было, поспрашивал за опыт, так вышло что они выпускники одного факультета, пообсуждали преподов, хобби, и всё.
По итогу еще раз многое зависит от команды и кто собесит. Выбирайте команду с умом, ее можно поменять.
Штат
Можно сразу на финале спросить, а будут ли места в штате. Конечно обмануть могут, но за вопрос денег не берут и пусть сила вам подскажет.
После стажировки есть несколько вариантов:
1. Если плохой отзыв от команды и говорят «уходи», то нужно заново проходить все собесы на стажера
2. Могут сказать, что ты не очень и иди на стажировку снова (без собесов, только финалы)
3. Можешь пойти в штат:
а) ты классный - можешь пойти к нам на миддла (но нужно опять пройти АА, потом финалы), если не пройдешь, то возьмут на джуна
б) ты не дотягиваешь до миддла - ты джун и если команда не готова взять джуна, то нужно идти искать, кто может взять к себе джуна самому
в) можно искать, кто готов взять к себе миддла/джуна и врубать свои навыки социальной инженерии на максимум
При идеальном мэтче, вы в Яндексе - поздравляю!
Подписаться: @codeof_art
• МНОГО КРАСИВЫХ СВОБОДНЫХ ЖЕНЩИН
• специалисты высокого класса
• зарплаты в среднем выше рынка
• современный стек и проекты
• хорошо выстроены процессы
• корпоративная культура
Для участия нужно подать анкету заполнить анкету и зарешать контест. Разбор контеста уже выложен на нашем курсе бэкенд про, алгоритмы про.
Как заполнять анкеты смотрим этот ролик. После контеста вас ждет два алгособеса на 2 литкод задачи medium + вопросы по языке и возможно серверам. И наконец собеседования с командами. На моем опыте максимально, сколько может быть собесов с командой - 9.
Финальные собесы
Если команда точно понимает, что им нужен стажёр закрыть пару дыр и после он не нужен, то собес больше про твой опыт, почему Яндекс, как планируешь совмещать с учебой, а что будешь делать, если стажку не продлим/не возьмём в штат. Такие больше на метч с командой и посмотреть не будешь ли ты ныть, что на стажке будешь заниматься скучной фигней, расскажут какой есть пул задач и спросят, что из этого интересно. Обычно такое в продуктовые команды.
Или, например наш студент, собесился в команду Поиска, которая занимается инфраструктурой. Устроили настоящий собес по систем дизайну, просили спроектировать калькулятор, который вот выдаётся после запроса в поисковой строке, как накрутить серверный рендеринг, гоняли по сетям, по знанию тулов реакта (линтер, сборщик кода как работает, как то-то настроить). И после этого другой интервьюер давил, что вот нам нужны гении, ты явно не такой, а вот чем ты занимаешься, а почему учишься в залупинске, а не в мск, говорил, что на удаленку никого не берём и тд.
Или другой наш студент собесился в другую команду Яндекс 360 календарь, там максимально чилово было, поспрашивал за опыт, так вышло что они выпускники одного факультета, пообсуждали преподов, хобби, и всё.
По итогу еще раз многое зависит от команды и кто собесит. Выбирайте команду с умом, ее можно поменять.
Штат
Можно сразу на финале спросить, а будут ли места в штате. Конечно обмануть могут, но за вопрос денег не берут и пусть сила вам подскажет.
После стажировки есть несколько вариантов:
1. Если плохой отзыв от команды и говорят «уходи», то нужно заново проходить все собесы на стажера
2. Могут сказать, что ты не очень и иди на стажировку снова (без собесов, только финалы)
3. Можешь пойти в штат:
а) ты классный - можешь пойти к нам на миддла (но нужно опять пройти АА, потом финалы), если не пройдешь, то возьмут на джуна
б) ты не дотягиваешь до миддла - ты джун и если команда не готова взять джуна, то нужно идти искать, кто может взять к себе джуна самому
в) можно искать, кто готов взять к себе миддла/джуна и врубать свои навыки социальной инженерии на максимум
При идеальном мэтче, вы в Яндексе - поздравляю!
Подписаться: @codeof_art
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2🤯2
Второй пост серии про паттерны на реальном коде. В прошлый раз говорили, почему «сохранилось» и «точно сохранилось» — не одно и то же. Сегодня — про идею, на которой держится половина софта вокруг нас, хотя мало кто задумывается про нее.
Если тебе приходится запускать чужой код, которому ты не доверяешь, — держи его от себя подальше, в отдельном процессе. Причина простая: чужой код умеет падать, зависать намертво и течь по памяти. Пусти его внутрь своего приложения — и однажды он утащит тебя за собой на дно. А отдельный процесс работает как стена: за ней хоть потоп, а на твою сторону вода не дойдёт. Поэтому одна упавшая вкладка в браузере не роняет остальные, и поэтому же плагины в редакторах живут отдельно от самого редактора.
Посмотрим, как это сделано в VS Code — там всё честно и наглядно. Расширения крутятся не внутри редактора, а в собственном процессе, у него и название есть — extension host. Замысел в одну строчку: что бы ни стряслось с расширениями, редактор обязан устоять.
И он выдерживает. Процесс с расширениями рухнул целиком — а редактор даже бровью не повёл: курсор мигает, текст на месте, файл спокойно сохраняется. Разработчики так и ставили задачу — пусть расширения хоть все разом отвалятся, но ни строчки твоей работы пропасть при этом не должно. Когда процесс падает, сверху выезжает плашка «расширения отключились, перезапустить?», жмёшь — и он поднимается заново. На то он и отдельный, что пересоздать его можно, ничего вокруг не задев.
А теперь то, из-за чего у людей годами пригорает. Стена стоит между редактором и расширениями — но между самими расширениями никакой стены нет. Все они набиты в один общий процесс и делят на всех единственный поток выполнения. А в JavaScript поток ровно один. И получается некрасивое: стоит одному расширению уйти в тяжёлые вычисления и занять поток надолго — как замирают вообще все расширения сразу. Не только виновник, а все соседи по процессу. Человек видит, что редактор целиком отупел и не реагирует, ругает VS Code последними словами — а нашкодило одно расширение, просто остальные заперты с ним в одной комнате.
Показательно, что и сама команда эту штуку архитектурно не победила — пошла в обход. VS Code теперь приглядывает за процессом с расширениями, и если тот перестал отвечать, тихонько включает профайлер: выясняет, кто съел весь поток, находит виновника и предлагает написать его автору. Проблему не убрали — её хотя бы вытащили на свет.
Тут есть тонкость, которую легко проскочить. Отдельный процесс спасает ровно от одного: сломанное расширение не утянет за собой редактор. Но заставить расширения не мешать друг другу он не может — это не входит в его задачу. Чтобы одно зависшее расширение не морозило соседей, пришлось бы городить следующий этаж защиты: свой процесс под каждое, тяжёлые задачи в фоновые потоки, лимиты по времени. И всё это не бесплатно — лишняя память, возня с общением между частями, более медленный запуск. В VS Code прикинули цену и решили, что оно того не стоит: одна общая крыша над всеми расширениями — осознанный размен между надёжностью и расходами.
Чему тут стоит научиться, даже если ты никогда не будешь писать редактор кода. Когда проектируешь что-то, что запускает не свой код — плагины, пользовательские скрипты, обработчики от сторонних команд, — заранее спроси себя: от чего именно я тут защищаюсь. «Чтобы чужое не уронило моё» и «чтобы одно чужое не мешало другому чужому» — две разные задачи, и вторая решается дороже. Их легко перепутать и поставить границу не там: думаешь, что защитился, а закрыл только половину. И второе: если задачу нельзя решить чисто — не грех сделать её хотя бы заметной. VS Code не смог развести расширения по-настоящему, но научился показывать пальцем на виновника, и это уже куда лучше, чем молча тормозить. Иногда честная диагностика ценнее красивого, но недостижимого решения.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Если тебе приходится запускать чужой код, которому ты не доверяешь, — держи его от себя подальше, в отдельном процессе. Причина простая: чужой код умеет падать, зависать намертво и течь по памяти. Пусти его внутрь своего приложения — и однажды он утащит тебя за собой на дно. А отдельный процесс работает как стена: за ней хоть потоп, а на твою сторону вода не дойдёт. Поэтому одна упавшая вкладка в браузере не роняет остальные, и поэтому же плагины в редакторах живут отдельно от самого редактора.
Посмотрим, как это сделано в VS Code — там всё честно и наглядно. Расширения крутятся не внутри редактора, а в собственном процессе, у него и название есть — extension host. Замысел в одну строчку: что бы ни стряслось с расширениями, редактор обязан устоять.
И он выдерживает. Процесс с расширениями рухнул целиком — а редактор даже бровью не повёл: курсор мигает, текст на месте, файл спокойно сохраняется. Разработчики так и ставили задачу — пусть расширения хоть все разом отвалятся, но ни строчки твоей работы пропасть при этом не должно. Когда процесс падает, сверху выезжает плашка «расширения отключились, перезапустить?», жмёшь — и он поднимается заново. На то он и отдельный, что пересоздать его можно, ничего вокруг не задев.
А теперь то, из-за чего у людей годами пригорает. Стена стоит между редактором и расширениями — но между самими расширениями никакой стены нет. Все они набиты в один общий процесс и делят на всех единственный поток выполнения. А в JavaScript поток ровно один. И получается некрасивое: стоит одному расширению уйти в тяжёлые вычисления и занять поток надолго — как замирают вообще все расширения сразу. Не только виновник, а все соседи по процессу. Человек видит, что редактор целиком отупел и не реагирует, ругает VS Code последними словами — а нашкодило одно расширение, просто остальные заперты с ним в одной комнате.
Показательно, что и сама команда эту штуку архитектурно не победила — пошла в обход. VS Code теперь приглядывает за процессом с расширениями, и если тот перестал отвечать, тихонько включает профайлер: выясняет, кто съел весь поток, находит виновника и предлагает написать его автору. Проблему не убрали — её хотя бы вытащили на свет.
Тут есть тонкость, которую легко проскочить. Отдельный процесс спасает ровно от одного: сломанное расширение не утянет за собой редактор. Но заставить расширения не мешать друг другу он не может — это не входит в его задачу. Чтобы одно зависшее расширение не морозило соседей, пришлось бы городить следующий этаж защиты: свой процесс под каждое, тяжёлые задачи в фоновые потоки, лимиты по времени. И всё это не бесплатно — лишняя память, возня с общением между частями, более медленный запуск. В VS Code прикинули цену и решили, что оно того не стоит: одна общая крыша над всеми расширениями — осознанный размен между надёжностью и расходами.
Чему тут стоит научиться, даже если ты никогда не будешь писать редактор кода. Когда проектируешь что-то, что запускает не свой код — плагины, пользовательские скрипты, обработчики от сторонних команд, — заранее спроси себя: от чего именно я тут защищаюсь. «Чтобы чужое не уронило моё» и «чтобы одно чужое не мешало другому чужому» — две разные задачи, и вторая решается дороже. Их легко перепутать и поставить границу не там: думаешь, что защитился, а закрыл только половину. И второе: если задачу нельзя решить чисто — не грех сделать её хотя бы заметной. VS Code не смог развести расширения по-настоящему, но научился показывать пальцем на виновника, и это уже куда лучше, чем молча тормозить. Иногда честная диагностика ценнее красивого, но недостижимого решения.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
🔥4❤1
System Design: frontend
Сегодня разберём задачу с собеса в геодезическую компанию — из тех, где приложение для полевых работ должно работать там, где связи нет в принципе. Спроектируй фронт, который живёт без интернета: специалист видит данные, что-то в них меняет, а когда сеть возвращается — всё уезжает на сервер и синхронизируется.
Почему такое вообще спрашивают. Геодезист выезжает на объект — поле, стройка, лес за городом, — и связи там может не быть весь день. А работать надо: открыть карту участка, занести замеры, отметить точки, что-то поправить. Если приложение при потере сети показывает белый экран, им попросту нельзя пользоваться в поле. Значит, оно должно работать так, будто интернет и не нужен, а сеть подхватывать само, когда специалист вернётся в зону покрытия.
Первое, что хочется ляпнуть, — «закешируем данные и всё». И вот это ловушка. Как только ты разрешаешь не только читать офлайн, но и менять данные, ты, по сути, строишь маленькую распределённую систему: у тебя появляется две копии правды (на устройстве и на сервере), и они умеют разъезжаться. Все классические боли распределёнки — конфликты, рассинхрон, порядок операций — теперь твои. Не подумал про них — решение развалится на первом же реальном сценарии.
Поэтому до того как проектировать, спроси интервьюера две вещи. Первая: что именно должно пахать офлайн — только чтение или запись тоже? Это небо и земля по сложности. Чисто чтение — задачка на кэш. Запись — уже та самая распределёнка. Вторая, и это гвоздь всей задачи: что делать, если геодезист поменял данные офлайн, а на сервере их за это время тоже кто-то поменял — например, коллега в офисе? Пока ты не ответил, как разруливать такой конфликт, — задача не закрыта.
Теперь как устроено внутри. Данные храним прямо на устройстве. Для структурированных данных — IndexedDB (это встроенная в браузер база; localStorage не годится — он крохотный и синхронный, тормозит всё вокруг). Картинки, стили, саму оболочку приложения кладём через Service Worker — это прослойка между приложением и сетью, которая отдаёт сохранённое, когда интернета нет. Читаем офлайн — берём из локальной базы. А с записью интереснее: когда человек что-то меняет без сети, мы не пытаемся тут же достучаться до сервера, а складываем изменение в локальную очередь. Появилась сеть — по очереди, в том же порядке, отправляем всё накопленное.
И вот мы уперлись в главное — в конфликты. Тут надо не просто сказать «ну разрулим», а назвать конкретный подход и объяснить, почему он. Самый простой — кто последний записал, того и правда. Работает, но молча затирает чужие изменения, а для замеров по объекту это чревато: перезатёр чью-то правку — и на объект поедут неверные координаты. Честнее — версии: у каждой записи есть номер версии, и если геодезист пытается сохранить поверх данных, которые на сервере уже обновились, сервер такое отклоняет, и мы решаем, что делать. Самый аккуратный, но и самый муторный вариант — сливать изменения по отдельным полям: один поправил координаты точки, другой — её описание, оба изменения выживают. Важно не назвать «правильный» ответ (его нет), а показать, что ты понимаешь разницу и осознанно выбираешь под ситуацию.
Ещё пара вещей, без которых разбор неполный. Синхронизацию лучше делать в фоне — есть Background Sync, который сам достучится до сервера, когда связь вернётся, даже если вкладку уже закрыли. И обязательно — честно показывать статус. Если человек поменял что-то офлайн, а на экране всё выглядит как «сохранено», он уйдёт довольный, а изменения висят в очереди и могут вообще не уехать. Маленькая плашка «изменения ещё не отправлены» снимает кучу боли.
Если совсем коротко: тут проверяют, понял ли ты, что offline-first — это не «кэш прикрутить», а полноценная распределёнка со своими конфликтами и с тем, что данные какое-то время живут несогласованными. Назвал конкретную стратегию разрешения конфликтов и вспомнил про честный статус для пользователя — значит, в теме.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
Сегодня разберём задачу с собеса в геодезическую компанию — из тех, где приложение для полевых работ должно работать там, где связи нет в принципе. Спроектируй фронт, который живёт без интернета: специалист видит данные, что-то в них меняет, а когда сеть возвращается — всё уезжает на сервер и синхронизируется.
Почему такое вообще спрашивают. Геодезист выезжает на объект — поле, стройка, лес за городом, — и связи там может не быть весь день. А работать надо: открыть карту участка, занести замеры, отметить точки, что-то поправить. Если приложение при потере сети показывает белый экран, им попросту нельзя пользоваться в поле. Значит, оно должно работать так, будто интернет и не нужен, а сеть подхватывать само, когда специалист вернётся в зону покрытия.
Первое, что хочется ляпнуть, — «закешируем данные и всё». И вот это ловушка. Как только ты разрешаешь не только читать офлайн, но и менять данные, ты, по сути, строишь маленькую распределённую систему: у тебя появляется две копии правды (на устройстве и на сервере), и они умеют разъезжаться. Все классические боли распределёнки — конфликты, рассинхрон, порядок операций — теперь твои. Не подумал про них — решение развалится на первом же реальном сценарии.
Поэтому до того как проектировать, спроси интервьюера две вещи. Первая: что именно должно пахать офлайн — только чтение или запись тоже? Это небо и земля по сложности. Чисто чтение — задачка на кэш. Запись — уже та самая распределёнка. Вторая, и это гвоздь всей задачи: что делать, если геодезист поменял данные офлайн, а на сервере их за это время тоже кто-то поменял — например, коллега в офисе? Пока ты не ответил, как разруливать такой конфликт, — задача не закрыта.
Теперь как устроено внутри. Данные храним прямо на устройстве. Для структурированных данных — IndexedDB (это встроенная в браузер база; localStorage не годится — он крохотный и синхронный, тормозит всё вокруг). Картинки, стили, саму оболочку приложения кладём через Service Worker — это прослойка между приложением и сетью, которая отдаёт сохранённое, когда интернета нет. Читаем офлайн — берём из локальной базы. А с записью интереснее: когда человек что-то меняет без сети, мы не пытаемся тут же достучаться до сервера, а складываем изменение в локальную очередь. Появилась сеть — по очереди, в том же порядке, отправляем всё накопленное.
И вот мы уперлись в главное — в конфликты. Тут надо не просто сказать «ну разрулим», а назвать конкретный подход и объяснить, почему он. Самый простой — кто последний записал, того и правда. Работает, но молча затирает чужие изменения, а для замеров по объекту это чревато: перезатёр чью-то правку — и на объект поедут неверные координаты. Честнее — версии: у каждой записи есть номер версии, и если геодезист пытается сохранить поверх данных, которые на сервере уже обновились, сервер такое отклоняет, и мы решаем, что делать. Самый аккуратный, но и самый муторный вариант — сливать изменения по отдельным полям: один поправил координаты точки, другой — её описание, оба изменения выживают. Важно не назвать «правильный» ответ (его нет), а показать, что ты понимаешь разницу и осознанно выбираешь под ситуацию.
Ещё пара вещей, без которых разбор неполный. Синхронизацию лучше делать в фоне — есть Background Sync, который сам достучится до сервера, когда связь вернётся, даже если вкладку уже закрыли. И обязательно — честно показывать статус. Если человек поменял что-то офлайн, а на экране всё выглядит как «сохранено», он уйдёт довольный, а изменения висят в очереди и могут вообще не уехать. Маленькая плашка «изменения ещё не отправлены» снимает кучу боли.
Если совсем коротко: тут проверяют, понял ли ты, что offline-first — это не «кэш прикрутить», а полноценная распределёнка со своими конфликтами и с тем, что данные какое-то время живут несогласованными. Назвал конкретную стратегию разрешения конфликтов и вспомнил про честный статус для пользователя — значит, в теме.
Подписаться: @codeof_art
Вступить в чатик: @code_of_art
🔥3