Art of Code
2.07K subscribers
51 photos
1 file
82 links
По вопросам: @vice22821

Чат: @code_of_art
Download Telegram
Новая линейка продвинутых карьерных курсов стартует уже в это воскресение 🎉

Мечтаешь стать крутым специалистом и с легкость тащить рабочие задачи и собесы, получив конкурентное преимущество? Хочешь овладеть знаниями и навыками для работы в крупной компании как Яндекс, Тинькофф или ВК? Узнал себя? Тогда записывайся у администратора на любой из курсов (если андроид - смотрим через яндекс браузер):

➡️ машинное обучение хард
➡️ бэкенд хард
➡️ аналитика хард
➡️ алгоритмы хард

Курсы продвинутые и рассчитаны на тех, у кого уже есть БАЗА, для тех, кто хочет затронуть более сложные темы и идеально подготовиться к собесам, для тех, кто претендует на что-то большее чем просто джуниор. Если вы только в начале своего пути, советуем курсы старт, на которые тоже до 16.08 действует скидка.

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

Помимо этого на курсах тебя ждут:
- продвинутые пет проекты и мини проекты, которые пойдут в портфолио;
- разбор реальных тестовых заданий бигтехов;
- разбор актуального контеста на стажировку в Яндекс и Тинькофф;
- банк реальных технических вопрос с собесов;
- разбор всех задач с алгособесов Яндекса!

А после прохождения курса тебя ждет пробный собес с подробной консультацией и сопровождением, рефералкой в Яндекс или в другие топовые компании!

📊 Цена 12'000р 7'200р при покупке до 16 августа включительно! Хочешь купить несколько курсов сразу? Дадим хорошую скидку!

Для вопросов и покупок пишем администратору и не тянем с этим: на каждом курсе количество мест ограничено!

Не забываем и про линейку старт, на которую тоже только до 16.08 действует скидка 40%!

➡️ алгоритмы старт
➡️ аналитика старт
➡️ машинное обучение старт
➡️ бэкенд разработка старт

ЗАПИСАТЬСЯ
Please open Telegram to view this post
VIEW IN TELEGRAM
1🗿1
Задача с собеса в яндекс на бекенд, камрады!!!

Что произойёт с целыми переменными a,b после выполнения?

a ^= b ^= a ^ = b;


1) a станет равно 0?
2) a,b станут равны?
3) a,b поменяются значениями
4) b станет равно 0, а a станет равным b
5) Undef behavior
6) Unspec behavior

Решение: очевидно будет Undefined behavior. Компилятор имеет право вычислять подвыражения в любом порядке, так как их порядок не задан стандартом. Он может начать с самого левого a ^= b, с самого правого a ^= b, или с середины. Результат будет разным в каждом из этих случаев.
2
int fn(int v) {
if (v == 1 || v == 0) {
return 1;
}
if (v % 2 == 0) {
return fn(v / 2) + 2;
}
return fn(v - 1) + 3;
}

fn(7)?
Решение: Вычисление fn(7):

v = 7 (нечётное):
return fn(6) + 3

v = 6 (чётное):
return fn(3) + 2

v = 3 (нечётное):
return fn(2) + 3

v = 2 (чётное):
return fn(1) + 2

v = 1:
return 1

Теперь поднимаемся обратно по цепочке вызовов:

Шаг 5: fn(1) = 1

Шаг 4: fn(2) = fn(1) + 2 = 1 + 2 = 3

Шаг 3: fn(3) = fn(2) + 3 = 3 + 3 = 6

Шаг 2: fn(6) = fn(3) + 2 = 6 + 2 = 8

Шаг 1: fn(7) = fn(6) + 3 = 8 + 3 = 11

Ответ
fn(7) = 11
4
// Выберите самый точный вариант вычисления суммы (предполагаем, что числа только положительные)

// Вариант 1
double sum(vector<float> &v) {
return accumulate(v.begin(), v.end(), 0.0);
}

// Вариант 2
double sum(vector<float> &v) {
sort(v.begin(), v.end());
return accumulate(v.begin(), v.end(), 0.0);
}

// Вариант 3
double sum(vector<float> &v) {
sort(v.begin(), v.end(), greater<float>());
return accumulate(v.begin(), v.end(), 0.0);
}


Решение: Самый точный вариант — Вариант 2 (сортировка по возрастанию).

Объяснение:

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

Почему Вариант 2 самый точный:

Сортировка по возрастанию `(sort(v.begin(), v.end()))` означает, что мы начинаем суммировать с наименьших чисел

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

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

Почему другие варианты хуже:

Вариант 1: Без сортировки — порядок суммирования произвольный, возможна значительная потеря точности

Вариант 3: Сортировка по убыванию — начинаем с самых больших чисел, и когда к ним добавляются очень маленькие числа, они могут быть полностью проигнорированы из-за ограниченной точности


@codeof_art
@codeof_art
@codeof_art
🔥62
Вопросы с видео интервью в Авито

1️⃣расскажите о себе

2️⃣ Расскажите, какие цели вы ставите для развития в профессии? Какие навыки и знания вы хотите приобрести, чтобы достичь этих целей?

3️⃣ Приведите пример профессионального или личного достижения.

Какие шаги были предприняты?
Оцените по 10-ти балльной шкале, насколько сложно было достигнуть данного результата?

4️⃣ Приведите пример в рамках вашей работы, учёбы или студенческих активностей, где вы работали в команде или в паре с кем-либо.

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

5️⃣ Как вы предпочитаете работать: в команде или индивидуально? Что для вас самое сложное в командной работе?

6️⃣ Расскажите, пожалуйста, чем вам интересно выбранное направление? Почему хотите развиваться именно в нём?

7️⃣ Почему вы решили подать заявку на стажировку для разработчиков в Авито?

8️⃣ Выделите три критерия выбора работодателя, которые являются для вас самыми важными?

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

@codeof_art
🔥42🗿1
Активно развиваем наш открытый банк собесов:
Фронтенд
Бэкенд
Алгоритмы
Аналитика
ML & DS

Уже собрали более тысячи реальных собесов/тестовых заданий. Внести свой вклад в общее дело, можно заполнив форму.
Также очень много всего интересного на нашем сайте.
2❤‍🔥2
#include <iostream>
using namespace std;

int f(int a, int b) {
if (a == 0 || b == 0) {
return a + b;
}
if (a > b) {
return f(a - b, b);
}
return f(a, b - a);
}

int main() {
cout << f(17, 257) << endl;
return 0;
}

что напечатается на экране?

Решение: оптимальнее перебора по всем случаям ничего не нашлось поэтому просто ответ: 1 по алгоритму евклида

@codeof_art
@codeof_art
@codeof_art
4🗿3
Товарищи, Поступашкам нужны контент мейкеры. Если вы творческая личность, интересующейся фронтендом, бэкендом, мобильной разработкой, дата сайнс, аналитикой, алгоритмами, вам нравится писать посты/ придумывать идеи для контента, то обязательно пишите @vice22821. Оплата сдельная, ориентировочно за один пост от 2 тыс до 15 тыс рублей.

Обязательно делитесь с ребятами, которым это может быть интересно.
3
Задача на сравнение строк в джаве

public static void main(String[] args) {
String based1 = "Я стажёр и работаю за компот";
String based2 = "Я стажёр и работаю за компот";

String based3 = new String("Я стажёр и работаю за компот");
String based4 = new String("Я стажёр и работаю компот");
String based5 = new String("Я стажёр и работаю за компот").intern();

System.out.println(based1 == based2);
System.out.println(based1 == based3);
System.out.println(based3 == based4);
System.out.println(based4 == based5);
System.out.println(based1 == based5);
}

Что выведется на экране при сравнении этих строк?

Результат
true
false
false
false
true


Объяснение
based1 и based2 - строковые литералы одинаковы, джава помещает их в String Pool, где ссылки переменных указывают на один и тот же объект.
based3 создаётся через конструктор new => значение литерала находится в пуле, но new String() создаёт новый объект в куче, и ссылка указывает именно на этот новый объект.
based4 - ещё один новый объект в куче, отличный от based3.
based5 - применяем метод intern(), который ищет строку в пуле и возвращает ссылку на объект из пула, а не созданный через new (если не находит, то добавляет строку в пул).


Немножко о строках в java

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

@codeof_art
🔥32
Т-академия

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

    public static void main(String[] args) {
Integer stupidNum1 = 127;
Integer stupidNum2 = 127;
Integer stupidNum3 = Integer.parseInt("127");
Integer stupidNum4 = 128;
Integer stupidNum5 = 128;
Integer stupidNum6 = -129;
Integer stupidNum7 = -129;

System.out.println(stupidNum1 == stupidNum2);
System.out.println(stupidNum1 == stupidNum3);
System.out.println(stupidNum4 == stupidNum5);
System.out.println(stupidNum6 == stupidNum7);
}

Что будет выведено на экран при сравнении этих чисел?

Результат:
true
true
false
false


Объяснение:
В джаве значения в диапазоне от -128 до 127 включительно хранятся в Integer кэше.
Если инициализируется переменная со значением в указанном диапазоне, объект из кэша будет использован повторно => одна и та же ссылка на один и тот же объект.
Если значение не входит в диапазон, создаётся новый объект в куче, и при проверке на равенство через "==" сравниваться будут ссылки на разные объекты.
При создании значения через parseInt(): возвращается примитив int -> автоупаковка в Integer -> генерация вызова valueOf(), который проверяет, находится ли значение в диапазоне кэша, и либо возвращает кэшированный объект, либо создаёт новый объект типа Integer.

В общем, помните об этом, но сравнивайте числа через equals(), чтобы не заморачиваться.


@codeof_art
5🔥4🤩2
Задача на resize() хэшмапы в джаве

    public static void main(String[] args) {
Map<Integer, String> internMap = new HashMap<>(5);

internMap.put(1, "salary");
internMap.put(2, "?");
internMap.put(3, "thanks,");
internMap.put(4, "I");
internMap.put(5, "work");
internMap.put(6, "for");
internMap.put(7, "compote");

System.out.println("key 1 = " + internMap.get(1));
System.out.println("size = " + internMap.size());
}


При добавлении какого элемента произойдёт resize()?

Результат:
Ресайз произойдёт при добавлении 7-ого элемента, все элементы перераспределятся, ёмкость хэшмапы увеличится с 8 до 16.

Объяснение:
При создании хэшмапы с параметром 5 ёмкость на самом деле = 8, так как приводится к ближайшей степени двойки.
Предельное количество элементов высчитывается именно от реальной ёмкости и в джаве по умолчанию равняется 75% от заполненности => 8 * 0,75 = 6. Ресайз произойдёт на 7 элементе, когда предельное количество станет превышено.
Для 7 элементов это не критично, но в условиях больших данных ресайзы необходимо избегать, так как они замедляют хэшмапу во время перераспределения бакетов.


Стандартный способ расчёта ёмкости, если мы в курсе предполагаемого количества элементов:
int expectedElements = 1000;
int safeCapacity = (int) Math.ceil(expectedElements / 0.75) + 1;
Map<K, V> anotherStupidMap = new HashMap<>(safeCapacity);


@codeof_art
4
Ментор+

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

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

Что мы не обещаем
Мы не можем обещать нереальных или почти нереальных результатов как "оффер на 500 тыс (стажер)".
Мы не можем обещать попадание в конкретную компанию.

Как мы достигаем цели?

1. Легенда
Мы прорабатываем с вами легенду, которую вы должны выучить и озвучить на собеседовании: где работали, что делали и так далее. Составляем конкретно под вас резюме.

Если вам нужно проработать легенду и составить резюме, но вы хотите проходить собеседования полностью самостоятельно, то это отдельная услуга. Она стоит 15 тысяч рублей. Для записи: @vice22821.

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

Если вам разово нужен специалист, который поможет на собеседовании: посидит на наушнике или пройдет лайвкодинг с удаленного доступа, то это отдельная услуга. Ориентировочная цена 10 тыс за пол часа собеса. Для записи: @vice22821

3. Теоретические занятия
Теоретические занятия в ментор+ не входят, ментор+ для тех, кому нужно трудоустройство. Если вам нужны знания, вам подойдут курсы.

Если у вас непростая ситуация и требуется консультация специалиста, то это отдельная услуга. Она стоит 8 тыс в час. Для записи: @vice22821.

Если вам нужно мок собеседование, то это отдельная услуга. Она стоит 8 тыс в час. Для записи @vice22821.

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

Оплата ментор +
Залог составляет 30 тыс. Уже после получения оффера нужно внести 1 месячную зарплату после вычета налогов.

Что если не получится
Если не получилось получить оффер по нашей вине (после собеседований в 5 компаний у вас нет оффера) в установленные сроки, то мы возвращаем вам залог.

Если не получилось получить оффер по вашей вине (например, вы решили отказаться от сотрудничества) в установленные сроки, то залог не возвращается.

Ответы на часто задаваемые вопросы

1. Сколько в среднем вся работа займет времени?
Если с вашей стороны нет задержек (например, уехали в отпуск), то максим 6 месяцев. Обычно удается получить оффер за 3 месяца.

2. Есть ли сопровождение на испытательном сроке?
Не входит в ментор+, отдельная услуга и обсуждается индивидуально.
4🗿4
Товарищи, Поступашкам нужны контент мейкеры. Если вы творческая личность, интересующейся бэкендом, дата сайнс, аналитикой, алгоритмами и так далее, вам нравится писать посты/ придумывать идеи для контента, то обязательно пишите @vice22821. Оплата сдельная, ориентировочно за один пост от 2 тыс до 15 тыс рублей.

Обязательно делитесь с ребятами, которым это может быть интересно.
2
Товарищи, мы обновили линейку СТАРТ и открываем новый набор! 🚀

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

Если раньше упор был только на технические навыки, то теперь на курсе вы также научитесь:
— составлять сильное резюме;
— презентовать свой опыт, даже если коммерческой работы не было;
— искать вакансии и понимать, куда лучше откликаться;
— проходить HR-этапы и уверенно чувствовать себя на всех интервью.

Открываем набор сразу на 4 направления:
- Аналитика
- Алгоритмы
- Backend
- Машинное обучение

📎Кому подойдет СТАРТ?

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

Что будет на курсах?

➡️Аналитика
Освоим SQL, продуктовые метрики, дашборды и A/B-тесты. В качестве пет-проекта пройдете полный цикл АВ тестирования — от запроса в БД до презентации результатов. Именно так работает аналитик.

➡️Алгоритмы
Разберем всё, что действительно спрашивают на технических интервью: структуры данных, графы, динамическое программирование, деревья, теория чисел и многое другое. Закроем фундамент для алгособеседований и контестов.

➡️Backend
Изучим архитектуру приложений, базы данных, Docker, gRPC и современные подходы к разработке. Итоговый пет-проект — полноценный сервис аналитики и прогнозирования цен криптовалют.

➡️Machine Learning
Метрики качества, классические алгоритмы, бустинг, нейронные сети и Transformer. Пет-проект — система кредитного скоринга. Без искусственных задач вроде «обучи свою LLM», только то, с чем реально сталкивается ML-инженер в начале карьеры.

Участникам курса также доступны:
🔵разбор контеста донабора Т-банк, стажировки в Яндекс, Авито буткемп DS (DS только на мл старт);
🔵mock-собеседования с обратной связью;
🔵закрытый банк вопросов с реальных интервью Яндекса, Т-Банка, Ozon, WB, Авито и других компаний;
🔵банк тестовых заданий и задач из бигтеха;
🔵реферальную рекомендацию в бигтех после успешной защиты пет-проекта.

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

🔊Подробную программу и стоимость курсов смотрите на сайте
Дополнительные скидки:
-500 , если учились уже у нас на других курсах
-500 ₽, если берете с другом

Действует гарантия: прошел курс, выполнил все рекомендации, но не получил оффер — вернем деньги

📌Для вопросов и записи на курс напишите менеджеру
Please open Telegram to view this post
VIEW IN TELEGRAM
3🗿2
ИИ ВСЕХ ЗАМЕНИТ! ЧТО ДЕЛАТЬ?

По результатам нашего опроса, 50% считает, что первые с рынка уйдут бэкендеры. Ещё 39% голосуют за аналитиков, а ML-специалисты пока чувствуют себя увереннее всех — за них отдали всего 11%.

Но кто на самом деле находится под угрозой?

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

Обсудим:
— какие задачи ИИ уже забирает у специалистов;
— где нейросети пока не могут заменить человека;
— какие навыки скоро станут бесполезными;
— чему учиться сейчас, чтобы не остаться без работы через пару лет.

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

Ну а ведущий эфира - легендарный Михаил Абрамович 😎

📅 Суббота, 19:00
🔗 Ссылка будет за 2 часа до эфира и в нашем боте @Postupashkianalitycsbot
🗿4
System Design

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

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

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

В целом структура данного собеса одинаковая и для фронта, и для бэка, ниже кратко разберем её.

Собираем требования. Задаём вопросы. Что за продукт, кто пользователи, какие ключевые сценарии, какие ограничения. Делим на функциональные требования (что система должна уметь) и нефункциональные (скорость, надёжность, доступность, безопасность). Половина хорошего ответа на собесе - это правильно заданные вопросы в первые несколько минут, но тут главное не задать слишком много вопросов, иначе можно себя закопать легко, тут важно не распыляться.

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

Что спрашивают у бэкендеров
Главный вопрос, на который ты весь час отвечаешь: выдержит ли твое решение миллион пользователей и не потеряем ли мы данные, если что-то упадёт.

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

Что по фронту
Тут же начинаем с одного пользователя, а затем масштабируемся. Также стоит учитывать, что у юзеров может быть плохой инет, древний браузер и кирпич вместо телефона. Это тоже сильное влияет на итоговое решение. Что стоит обсудить на этой секции: контракт API, стратегия рендеринга (CSR / SSR / SSG, гидрация), работа с состоянием. Дальше - производительность (размер бандла, ленивая загрузка, и прочие вещи), UX-состояния, доступность и локализация. И только потом выбор методологии под проект и уже совсем в конце сами компоненты.

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

Что общего
И там, и там проверяют одно и то же: умеешь ли ты работать в условиях неопределённости, видишь ли компромиссы и можешь ли объяснить, почему выбрал именно это. Формулировка уровня «я взял такой подход из-за ограничения X, но если бы было условие Y — выбрал бы Z» показывает в тебе инженера.

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

Подписывайтесь на канал и вступайте в чатик, товарищи, так вы не пропустите новый контент!

Подписаться: @codeof_art
🏆10
System Design: frontend

Разберём реальную задачку, её дали мне на собес в Яндекс Поиск. Пользователь вбивает в поиск «2+2», в выдаче нужно показать блок-калькулятор с уже посчитанным ответом, отрисовка серверная. Как реализуешь?

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

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

Дальше поток простой. Бэк поиска понимает, что запрос - это выражение, парсит его и считает на сервере, отдаёт готовый HTML с уже проставленным ответом. Юзер видит «4» до того, как загрузился хоть один килобайт нашего JS. Вот, собственно, ради этого здесь и нужен SSR. Потом виджет гидрируется и становится кликабельным, и с этого момента все вычисления живут на клиенте - бегать на сервер за каждым нажатием кнопки нельзя, это верный способ завалить секцию.

Состояние приезжает с сервера и обязательно сериализуется в разметку, а не пересчитывается заново на клиенте, иначе поймаешь hydration mismatch и блок мигнёт при перерисовке. После гидрации стейт полностью локальный, виджет автономен. Контракт с бэком выдачи выглядит примерно как выражение, его нормализованный вид и результат, причём результат передаём строкой, а не числом - иначе можем потерять точность. И ошибки проговариваем отдельно: невалидное выражение, деление на ноль и переполнение это три разных состояния, а не одно «что-то пошло не так».

Теперь возвращаемся к тому вопросу про клики. Ответ на него такой: подавляющее большинство вбили «2+2», увидели «4» и ушли, они никогда не нажмут ни одной кнопки. Так зачем мы им грузим и гидрируем интерактивный калькулятор? Гидрируем лениво, по первому взаимодействию - клику, наведению. До этого на странице лежит статичный HTML, который стоит ноль. Если это сказать на собесе, то это большой плюсик для тебя, ответ явно не джуна.

Дальше добираем очки от интервьюера. Гидрируем независимо от остальной выдачи, чтобы наш виджет не утащил за собой SERP. Никакого eval ни на сервере, ни на клиенте - выражение пришло от пользователя, это недоверенный ввод, нужен нормальный парсер. Про eval интервьюер спросит почти наверняка, а если не спросит, скажи сам, +реп. Результат детерминирован, «2+2» всегда даёт «4», значит блок прекрасно кэшируется. Ну и резервируем высоту блока, чтобы выдача не прыгала, делаем настоящие кнопки вместо дивов с onclick и вешаем aria-live на результат, чтобы скринридер его озвучил. Сразу видно, что человек думает о доступности, тоже +реп гарантирован.

Если коротко, проверяют здесь одно: понимаешь ли ты разницу между «отрендерить» и «сделать интерактивным», и умеешь ли не платить за интерактивность там, где она девяноста пяти процентам людей не нужна.

Подписывайтесь на канал и вступайте в чатик, товарищи, так вы не пропустите новый контент!

Подписаться: @codeof_art
8👍4
Уточнил у кандидата работал ли он со скоринговыми моделями как "Ясасу Бибу" и "Цист Яна". Ответ убил.

https://youtube.com/shorts/ccNWpP5grzg
🔥4
System Design: backend

Обещали разобрать бэк - делаем. Задачка с собеса в Сбере: нужно передавать файлы большого размера. Через мессенджер не выйдет, упрёмся в лимиты, значит либо торрент, либо поднимать свой сервер, либо что-то ещё. Как спроектируешь?

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

Дальше развилка, ради которой задачу и дают. Можно пойти в P2P, когда файл льётся напрямую между участниками, а мы храним только метаданные. Мы не платим за хранение и за исходящий трафик, и чем популярнее файл, тем быстрее раздача, потому что получатели сами становятся источниками. Но обе стороны обязаны быть онлайн одновременно, придётся возиться с NAT и фаерволами, а фолбэк на релей - это уже снова наш сервер и наш трафик. Можно пойти централизованно: отправитель залил, получатель забрал когда захотел, никто никого не ждёт, но мы платим за хранение и, главное, за исходящий трафик, который тут и будет основной статьёй расходов. А в проде почти всегда получается гибрид, где метаданные, авторизация и сигналинг идут через наш сервер, а данные - напрямую между клиентами, где это возможно. Вот эту мысль и надо озвучить: выбор определяется требованиями.

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

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

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

Подписывайтесь на канал и вступайте в чатик, товарищи, так вы не пропустите новый контент!

Подписаться: @codeof_art
5