Thumbnail for Реальное Собеседование на Junior Backend разработчика — Это нужно знать! by Артём Шумейко

Реальное Собеседование на Junior Backend разработчика — Это нужно знать!

Артём Шумейко

20m 52s2,812 words~15 min read
Auto-Generated

[0:00]Если вы боитесь проходить технические собеседования, не знаете, какие вопросы на них задают, как грамотно отвечать на вопросы интервьюера, то это видео для вас. Меня зовут Артём, я синьор Python разработчик и специально для этого видео сделал фейковое резюме и пошёл устраиваться на джуниор разработчика. По итогам прохождения двух собеседований в эту компанию, одно техническое, второе лайф-кодинг, я получил оффер. В конце видео я скажу, на какую сумму на руки мне предложили зарплату. А сейчас давайте поговорим немножко про сами вопросы. Они, на самом деле, мне кажется, были уровнем выше, чем джуниор. То есть это не джуниор разработчик, хотя я откликался именно на джуна. И это собеседование не самое обычное, обычные вопросы идут по базам данных, по устройству языка, по Git, Docker и так далее. А здесь были вопросы про то, как устроен интернет, про то, как работает браузер, про то, какие, в принципе, сервисы есть на этапе разработки бэкэнда. То есть здесь такое верхнеуровневое понимание, которое нужно каждому бэкэндеру, особенно начинающим. А в самом конце собеседования был один интересный практический кейс, где нужно было словами описать, как бы ты делал вот эту конкретную задачу. И это было, на самом деле, очень показательно. То есть если вы можете ответить, можете рассказать, как бы вы делали такую задачу, то вы, я бы ещё сказал, что считаетесь качественным специалистом. Если вы не можете ответить, прямо сыпетесь на этом вопросе, ну, наверное, вам стоило бы ещё подучиться. Поэтому обязательно досматривайте до конца. Перед началом, если вам интересно, какой сейчас рынок труда, как откликаться, как составлять резюме. Как я проходил собеседование в Яндекс, в Тиньков, насколько там много платят и так далее, то я приглашаю вас в свой Telegram-канал. Сейчас я там спешу о том, как я делаю свой стартап, который поможет айтишникам готовиться к техническим собеседованиям. Так что будет очень интересно, следите за новостями в Telegram-канале. Перед началом, если вам нравится подобный контент, вы хотите видеть больше собеседований на Junior, Middle, Senior и даже тех лидов, а они есть у меня, то ставьте лайк и подписывайтесь на канал, и новых видео не заставит себя долго ждать. А теперь переходим к собеседованию. Куда ты пишешь в браузере vk.com или google.com, что вообще происходит? Скажи, как может нам поподробнее. Итак, что же происходит, когда мы в браузере вводим в адресной строке vk.com или google.com? Это частый вопрос, на самом деле, и нажимаем Enter. Если отвечать, как вот джуниор разработчик, как бы я ответил? Я бы сказал, что у нас браузер и система распознавания доменных имён DNS определяет IP-адрес, на котором живёт, собственно, vk.com. Туда браузер отправляет запрос, на том сервере есть какой-то сервис, который слушает какой-то определённый порт и принимает все входящие запросы. Например, там просто развёрнут у нас бэкэнд на там Python, Java, GoLang, в принципе, неважно, на каком языке. Принимается запрос, дальше какая-то бизнес-логика уже написанная программистом осуществляется, например, идёт запрос в базу данных или запрос в кэш. Данные каким-то образом обрабатываются, формируются и обратным путём, точно таким же, браузер возвращается, и браузер уже как-то распарсит этот ответ, потому что всегда он в формате строк данные гоняются по HTTP. Ну это уже, наверное, даже нюанс. И пользователь получает свой ответ. В принципе, это достаточный ответ. Как бы я ответил на специалиста Middle уровня или близкого к Middle? Что ещё можно сказать? Ну, помимо того, что у нас есть DNS, можно сказать, что у нас сервер сам, который принимает запрос, это не просто развёрнутый бэкэнд, который слушает какой-то порт. Это довольно небезопасно. У нас сейчас стоит перед ним веб-сервер, например, Nginx или Nginx. Который балансирует нагрузку, э какое-то ограничивает количество соединений одновременных, чтобы у нас не были возможны дос-атаки. Который на другие серверы внутри нашего ВКонтакте, которых, естественно, там огромное количество серверов, на которых может лежать бэкэнд, проксирует, то есть вот какие-то можно термины уже употреблять. Также стоит упомянуть, что у нас сервисы обычно разворачиваются через докер, через контейнеры, часто используется микросервисная архитектура, потому что нам нужно уметь масштабировать наши приложения. Кстати, если вам интересно, как выглядят архитектуры современных веб-приложений, то обязательно посмотрите видео на моём канале про архитектуру. Оно очень понятно и на диаграммах на конкретных примерах вам показывает, как устроена сейчас бэкэнд архитектура. Дальше мы посылаем запрос. А как вообще запрос мы формируем, как браузер формирует запрос? Как же браузер формирует запрос? Ну, во-первых, как мы уже сказали, у нас есть какая-то система доменных имён, и сервер понял, что vk.com - это какой-то IP-адрес, и он на этот IP-адрес пошлёт запрос. Помимо этого, есть очень важный параметр - это тип запроса. Это на получение данных Get, это на добавление данных Post, на изменение Put, Patch. Ну вот можно, в принципе, перечислить все эти методы. Также у нас есть, естественно, заголовки, то есть браузер посылает какие-то заголовки. Часто это могут быть какие-то авторизационные данные, это могут быть данные о самом браузере. Если вы часто, может быть, видели header или заголовок под названием User-Agent. Браузер также отправляет заголовки, с какого ресурса отправлен запрос, есть ли какие-то настройки корсов и так далее. То есть очень много параметров, и углубляться здесь можно уже через то, что вы будете называть какие есть заголовки и для чего они используются. Так, следующий вопрос со звёздочкой. Смотри. А я, допустим, какая-нибудь, ну, не знаю, допустим, я написал сервис, у которого очень много интеграций, и мы хотим, допустим, передать данные клиенте с другой сервис. Ну, например, клиент идёт в другой сервис с нашим токеном, а и там хотят узнать наш, ну, типа данные одного клиента. Соответственно, мы хотим сделать так, чтобы другие сервисы могли проверять подпись, но при этом не могли сами эти токены отдавать.

[6:09]Тема безопасности довольно сложная и обширная. И что здесь нужно сказать в первую очередь? В первую очередь, естественно, мы упоминаем протокол HTTPS - это защищённая версия протокола HTTP. И HTTPS мы не можем прослушать, перехватить так, как это мы можем легко сделать с HTTP. Это первое и основное. Далее, мы используем пост-запросы вместо Get-запросов. Например, когда мы логинимся куда-то, авторизуемся, там вводим почту и пароль. Мы ни в коем случае не используем Get-запросы, потому что в Get-запросах все данные передаются в самом URL, и это неправильно. Все чувствительные данные нужно передавать в теле запроса, это называется request body. Помимо этого, естественно, каждый запрос, который связан каким-то образом с безопасностью, у нас подкрепляется авторизационными данными. Это может быть JWT токен, это может быть ID сессии, ну, в принципе, это уже даже углубление, наверное, в авторизацию, то есть какие-то авторизационные данные. Это может быть подтверждение по там эсэмэске, это может быть подтверждение по почте, то есть любые способы ещё дополнительной идентификации личности. Друзья, если вы хотите стать Python бэкэнд разработчиком, у меня для вас важная новость. У меня есть курс по бэкэнд разработке на одном из самых популярных фреймворков на Python - это FastAPI. В курсе мы с полного нуля проектируем проект, пишем его, используем самый современный стек, который требуется дальше на реальной работе. И выкладываем его на сервер, чтобы показывать работодателю и добавить в своё портфолио. Курс прошло уже больше 500 человек, многие нашли работу Junior или сразу Middle разработчиками и успешно работают на позиции Python бэкэнд. Переходите на мой сайт, по ссылке в описании и ознакамливайтесь с тарифами, отзывами и обязательно пробуйте бесплатные модули, чтобы понять, подходит ли вам этот курс. Все ссылки будут в описании, буду рад видеть вас на курсе. О'кей, мы отправили запрос по HTTP. Нам вернулся ответ, что ответить? Бывает несколько типов ответа от сервера. Первый - это когда, в принципе, сервер недоступен, его нет, он не отвечает по этому IP-адресу, и браузер вернёт, естественно, ответ, что, ну, такого сервера нет. Как бы ответ будет очень скуден. Бывает такое, что сервер есть, но он просто не справился с обработкой запроса. И, допустим, он просто ляжет, то есть какая-то ошибка случится, и он не сможет даже никакой ответ отправить, и в итоге браузер отобразит пятисотую ошибку. А бывает, когда, то есть пятисотая ошибка связана с внутренней ошибкой сервера. Бывает, когда сервер смог обработать запрос, и он либо выдал ошибку, либо выдал какой-то успешный статус. И в таком случае в браузер приходят, собственно, данные ответа и какие-то заголовки. То есть очень важно, что нам сервер возвращает заголовки. Это могут быть, если мы логинимся, это могут быть куки, какие-то авторизационные данные. Это могут быть какие-то специфические хедеры, специфические заголовки. Также нам приходит код HTTP ответа, это число в диапазоне от 100 до 599. Обычно нам приходит двухсотый статус, это значит, что всё о'кей, собственно, он так и называется. Может прийти статус номером 201. Это тоже значит, что всё о'кей, сервер прислал положительный ответ, просто у нас 201 отвечает за создание объекта. То же самое может быть связано с клиентскими ошибками, там 400. Это значит, что что-то клиент прислал не то, не те данные, не те авторизационные данные. Как-то не так сформировался запрос. А бывают ошибки по типу 401, что вы не авторизованы, 403 - у вас нет доступа вообще к этому эндпоинту, к этой ручке, к этим ресурсам и так далее. Так, о'кей, хорошо. А давай про тоже про авторизацию, а вот как, на твой взгляд, чаще всего, ну, дальше очень много исключений в мире IT, а оптимальнее делать авторизацию. То есть, чтобы она тратила меньше ресурсов нашего сервера, то есть JWT, либо это просто какой-то ID сессии, который мы храним в базе, либо что-то ещё. Очень часто сравнивают JWT и сессии. И здесь очень простой ответ. Внутри сессии ничего не хранится, это просто рандомная последовательность цифр и букв, которая на бэкэнде связана с конкретным пользователем, например, с вами. И когда фронтенд отправляет вот эту рандомную последовательность букв и цифр на бэкэнд, бэкэнду приходится пойти в базу и понимать, а что за юзер ко мне пришёл. В то же время в JWT токене внутри него уже зашиты данные про пользователя, чаще всего это ID пользователя, то есть не какие-то чувствительные данные типа емейла, пароля и так далее. Нет, именно вот, например, айдишник там это первый пользователь и так далее, потому что на бэкэнде очень часто достаточно просто ID пользователя. И, в принципе, это всё различие. Мы не лезем лишний раз в базу данных и экономим довольно много ресурсов на этом. А, давай немного попроектируем. Смотри, а мы делаем новый проект. Там будет авторизация по номеру телефона. Ну и регистрация тоже в одном, можно сказать, окошке. То есть ты вводишь номер телефона, если пользователь не создаём. А, вводишь номер телефона, присылается эсэмэска. Если пользователь вводит правильный пароль, ну, код, то мы создаём этого пользователя, если он уже был и ввёл правильный пароль, то мы просто авторизуем его. Как бы ты реализовал эту логику? Какие нужны методы для этого апишки? Как, э, ну, что с базой надо там, какие таблицы, как это с ней работать? Ну и самое главное, какие бывают узкие кейсы, когда это будет плохо работать либо небезопасно. Это, на самом деле, задачка на подумать, задачка на умение представлять себе, как это выглядит на фронтенде, на бэкэнде. То есть я в своей голове сразу представил какую-то картинку, как на фронтенде эта форма выглядит, на каких сайтах она была реализована и как она была реализована. И уже из этого исходил. То есть в первую очередь мы создаём какую-то ручку, какой-то эндпоинт на бэкэнде, чтобы по нему можно было обращаться. Туда приходит, как параметр, номер телефона. Причём очень важно, что мы используем не Get-запрос, а Post-запрос, потому что мы отправляем чувствительные данные, наш номер телефона. И, например, один параметр - это Phone и номер телефона. Что делает бэкэнд после получения номера телефона? Он генерирует какой-то случайный код, который будет валиден для этого пользователя. Причём код, очень важно, будет ограничен по времени. То есть, условно, в ближайшие 5 минут этот код будет валиден, потом уже нет, чтобы нельзя было перебором других пользователей взломать.

[13:42]Далее. Мы сгенерировали код. Перед тем, как отправлять пользователю SMS, нужно занести в базу данных, что вот для этого телефона вот этот код будет валиден до этого времени, то есть в ближайшие 5 минут. Как только мы внесли в базу данные, мы отправляем SMS. Это происходит, естественно, на бэке, это может быть обращение к другому микросервису, это может быть тот же самый сервис, который является монолитом и отправляет сообщения. Не суть важно. После этого браузер получает от бэкэнда какой-то айдишник записи из базы данных, например, там пятый или пятьдесят пятый, то есть какая строчка в базе данных это. И предлагает пользователю ввести пароль. Ему уже эсэмэска пришла. И он вводит пароль, нажимает войти, и на бэкэнд уже на новый адрес, на новую ручку отправляется этот самый код, и, очень важно, естественно, это какой-то айдишник. То есть уже не номер телефона, а айдишник. И, соответственно, чтобы мы могли в базе однозначно понять, тот это код или нет. Бэкэнд, естественно, принимает айдишник и код, и в базе данных ищет эту строчку, смотрит, валиден ли ещё код. Если нет, отправляет ошибку. Если да, то сравнивает код, и если всё о'кей, то отправляет какие-то авторизационные данные человеку. То есть сопоставляет, что вот с этим номером телефона связан вот этот человек. Как-то его данные оборачивает в тот же, например, JWT токен или просто генерирует сессию и отправляет данные, условно, чтобы человек уже зашёл в систему. Что здесь важно предусмотреть в таком случае? Ну и, естественно, важно, чтобы не обьюзили нашу платформу, чтобы не мог какой-то хакер отправлять сотни запросов на все номера телефонов, там бесконечное количество раз в секунду. Это просто поломает нашу систему, взломает всех пользователей простым перебором, потому что обычно пароли временные - это вот там четыре, пять, может, шесть символов. Поэтому мы должны на уровне веб-сервера, например, Nginx, ограничить количество запросов. Мы можем это сделать и на уровне фреймворка, например, FastAPI на Python или вообще любой другой фреймворк на бэкэнде. Но лучше это делать на стороне веб-сервера, всё-таки это, скорее, его ответственность. То есть какие-то меры мы должны предпринять по ограничению. Например, по IP-адресу, то есть что вот этот IP-адрес не может вот столько запросов отправлять, или что там вот этот номер телефона не может вот с этого IP-адреса вот столько запросов отправлять. То есть каким-то образом фильтровать IP-адрес и по номеру телефона. В целом, такого ответа будет достаточно. Естественно, могут быть какие-то ещё подводные камни, но это плюс-минус решает данную проблему. Сейчас скину в чатик. Вот у меня есть такой Dockerfile. Что бы ты в нём улучшил? Что такое Dockerfile? В первую очередь, это конфигурационный файл для докера. Мы хотим создать какой-то образ нашего приложения, чтобы его можно было потом масштабировать, запускать там на любой машине, где угодно, в любых условиях. Что нам нужно учесть? Первое - это версия Python. Ну, естественно, здесь непонятно, что за Python, нужно указать версию конкретную, например, там 3.9, 3.10, 3.11, 3.12, то есть насколько далеко вы продвинулись в своём познании этого мира и насколько у вас не legacy код. Да, то есть часто бывает, что там Python 2.7 у кого-то бывает, почему нет? Далее, у нас сразу копируются абсолютно все файлы из нашей локальной директории в докер образ. Это неправильно, потому что в таком случае у нас каждый раз будут обновляться зависимости, как будто бы для докера, и он каждый раз будет устанавливать зависимости. Вместо этого нужно сначала сделать копии requirements.txt, то есть скопировать только зависимости, да, и в принципе, это актуально не только для не только для Python, но и для других языков. И у нас в данном случае докер закэширует этот слой, этот этап сборки, и у нас не будут каждый раз устанавливаться зависимости. То есть они будут браться из кэша, и это ультра круто. Естественно, всегда нужно помнить об этом и использовать эту историю. После этого мы уже все остальные файлы копируем из локальной директории в докер образ, и после этого уже используем Entrypoint, CMD для того, чтобы запустить Python Main.py нашу программу. Это собеседование я прошёл отлично, получил замечательный фидбек, и меня пригласили на второй этап, на лайф-кодинг, который я также отлично сдал. Собственно, если вам интересно, видео набираем 2.000 лайков, и я выкладываю вторую часть, и после этого я получил оффер. Напомню, что это была начальная позиция на Python разработчика, это не был там Middle, это не был Senior, это был Junior. И изначально мы договаривались на сумму 80.000 рублей, да, с рекрутером. Но после собеседования я попросил 100, и мне одобрили 100.000 рублей на руки.

[19:35]Много это или нет? Непонятно, тяжело сказать. Тяжело сказать, что было бы, если бы отвечал не так глубоко, потому что, на самом деле, вопросы, на мой взгляд, были не уровня Джуниор. Особенно про то, как устроен там у нас JWT токены, как работает авторизация, это всё уже познаётся на практике и обычно в коммерческих проектах, потому что на проектах мы, ну, не всегда запариваемся с авторизацией, потому что это нам просто как будто даже не надо и неинтересно. Что вы думаете об этом собеседовании, обязательно пишите комментарии, интересно послушать ваше мнение. Достойная ли оплата, сложные ли вопросы, хорошие ли у меня были ответы, и если нет, то обязательно поправляйте, буду рад почитать корректные ответы. Если вам интересно посмотреть мои другие собеседования, обязательно заглядывайте на бусти, ссылка будет в описании, и там есть четыре собеседования. Есть на тех лида, на фулстек разработчика, на алгоритмические собеседования в Яндекс и ещё одно собеседование. Покупайте подписку и наслаждайтесь просмотром. С вами был Артём. Всем пока.

Need another transcript?

Paste any YouTube URL to get a clean transcript in seconds.

Get a Transcript