Директор бэкенда
36 subscribers
2 photos
Download Telegram
📝 Про live-кодинг и тестовые задания

За свою карьеру мне довелось несколько раз проходить собеседования, частью которых был или лайв кодинг в присутствии СТО (лида) или написание небольшого (а бывало и большого) тестового задания. Из них всех, я смог выделить лишь один кейс, который оставил у меня положительные эмоции от интервью. Так уж вышло, что это интервью я проходил буквально пару дней назад. Это был гибкий лайв кодинг, с ориентиром на твои скиллы (ты описываешь свои сильные стороны и тебе предлагают решить соответствующую задачу). Была достаточно лайтовая атмосфера, по ходу кодинга мы общались на разные темы, включая процесс найма и собственно пользы от лайв кодинга и тестовых заданий (СТО меня приятно удивил своим гибким мышлением и философией в некоторых вопросах).
После этого интервью я решил собрать и структурировать свои мысли по поводу роли тестовых заданий и лайв кодинга в современном процессе найма. Сразу скажу, что не смотря на положительный опыт, который я получил на последнем таком интервью, в 90% случаев, я крайне отрицательно отношусь к подобному процессу найма, считая это бесполезной тратой времени, которая не покажет и не расскажет ровным счётом ничего о кандидате.

Итак, что же представляют из себя эти 10%, в которых я считаю такой процесс уместным?

1. Конкурсные вакансии Junior / Junior+, с огромным количеством кандидатов. В этом случае уместно будет отправить на выполнение ⚠️ небольшое тестовое задание на решение какой либо проблемы вашего домена. Например, если вы разрабатываете продукт email рассылок, то небольшая задача на отслеживания статуса прочтения письма тут может быть очень уместна. Такое тестовое поможет отсеять ну совсем не релевантных кандидатов, не забирая уйму времени у вас и у них.
О лайв кодинге на данные позиции не может быть и речи, так как это достаточно повышенный стресс даже для опытного специалиста, поэтому из-за огромного волнения, есть вероятность упустить потенциально хорошего кандидата.
2. Собеседования на языки программирования, где сейчас это считается нормальной практикой и может показать глубину понимания определенных концепций. Хорошим примером тут будет язык Go.
Можно поспрашивать пару базовых вещей (слайсы, мапы, асинхронность), а затем предложить какой-то общий пример для демонстрации глубины понимания этих самых концепций. Такой процесс будет уместен для позиций Junior-Middle, но опять же, не всегда и только для подобных языков.

А что же там с Senior и выше?

А ничего. В большинстве случаев такие интервью не покажут его реальный уровень знаний, а только создадут негативный прецедент, особенно, если не предупредить о лайв кодинге заранее. Куда лучше будет поговорить о его ответственности и достижениях на предыдущих местах работы, какие сложности возникали у него на пути и как он решал те или иные практические задачи. Если у него есть опыт в смежном для вас домене, то можно вместе порассуждать над решением каких-то тривиальных кейсов из этой области.
Директор бэкенда
📝 Про live-кодинг и тестовые задания За свою карьеру мне довелось несколько раз проходить собеседования, частью которых был или лайв кодинг в присутствии СТО (лида) или написание небольшого (а бывало и большого) тестового задания. Из них всех, я смог выделить…
Теперь несколько личных советов по поиску работы для кандидатов.

👉 Если вы претендуете на позицию Junior, то вакансии с тестовым заданием могут стать для вас отличным шансом выделиться среди толпы кандидатов. Но только в том случае, если тестовое задание релевантно домену, в котором работает данная компания. Если же это типичные задачки из codewars и прочих сервисов - смело проходите мимо таких вакансий. Они никогда не покажут ваш реальный потенциал и не выделят вас из общей массы.
👉 Если вы Senior, то в целом, можете смело избегать любые вакансии, где присутствует один из видов кодинга. Есть куча компаний и вакансий где практикуется то, что я описал в абзаце про senior. Если компания с наймом через кодинг не является вашим приоритетом или если жизнь не заставляет вас хвататься за каждую возможность - то и не стоит тратить свое время на ерунду как говориться.
👉 Если вы Middle, то вам придется балансировать между двумя пунктами выше. Но в приоритете, я бы склонялся к пункту 2.
Please open Telegram to view this post
VIEW IN TELEGRAM
Не холивара ради, но справедливости.
Является ли javascript асинхронным?
Anonymous Poll
55%
Конечно
45%
Нет 🙅‍♂
Please open Telegram to view this post
VIEW IN TELEGRAM
Порой, меня накрывают периоды, когда мне надоедает все, чем я занимаюсь! Весь этот PHP с его request/response моделью и щадящим, всепрощающим синтаксисом. Это ваш Golang с его доводящей до ярости обработкой ошибок. Все эти задачи на борде, где надо реализовать очередную CRUD фичу (и не факт, что нужную). Ну вот буквально все!

А потом, я открываю VS Code и начинаю программировать на C. И знаете, всю эту хандру сразу как рукой снимает... 😅
static int ticks = 0;
pthread_mutex_t s_mutex;

void* work_fn(void *arg)
{
pthread_mutex_lock(&s_mutex);
struct thread_meta mt = *(struct thread_meta *)arg;

printf("Starting thread %d\n", mt.id);
ticks++;

pthread_mutex_unlock(&s_mutex);
free(arg);
pthread_exit(NULL);
}

pthread_t add_worker(int id, void *(*work_fn) (void *))
{
struct thread_meta *meta;
meta = malloc(sizeof(struct thread_meta));
meta->id = id;

pthread_t thread;
pthread_create(&thread, NULL, work_fn, meta);

return thread;
}
Иногда, при общении с другими разработчиками (в команде или за её пределами), замечаешь, как они оперируют понятием "POD" в системах, где нет (и скорее всего не будет) Kubernetes. Не то, чтобы я тригерился на это. Несмотря на путаницу в терминах, можно вполне легко догадаться, что человек имеет ввиду ноду, инстанс или просто vps. Однако, я все-таки рекомендую вам максимально прокачивать свою грамотность, ведь она - витрина вашей экспертизы. А то бывает, аж слух режет..
Тип ENUM в MySQL

Вообще, эти мысли касаются не сколько MySQL, сколько всех реляционных БД, где есть enum. Однако, поскольку львиная доля моего опыта связана именно с MySQL, оставлю заголовок как есть.

В течении моей карьеры, мне удалось поработать в нескольких командах, чье мнение про enum каждый раз разворачивалось на 180 градусов. Например, в текущей команде существует практика избегания enum'ов при создании таблиц. тогда как на предыдущем продукте мы создавали enum'ы даже в кейсах, где список допустимых значений состоял всего из одного элемента (так сказать, задел на будущие бизнес-требования). Учитывая, что я видел преимущества и недостатки обеих практик, хочу поделиться своей окончательно сформированной позицией на этот счет. Сразу предупреждаю - позиция сугубо субъективная и не претендует на конечную истину.

Итак, какие преимущества дает нам тип ENUM?
1. Ну конечно же это permitted set. Мы не сможем записать в колонку ничего, кроме набора допустимых значений. А значит - соблюдаем букву C по ACID.
2. Человекочитаемые данные при ручных запросах в БД. Этот пункт я считаю значимым преимуществом при работе с большими системами, особенно когда нужно быстро посмотреть и проанализировать информацию в production.
3. Экономия места. Особенно приятно в сочетании с человекопонятными данными. Максимальное место под значение - 2 байта. В реальном мире, вы в 99.99% случаев не выйдете за 1 байт. Звучит красиво! Да, но... лично я выделил это преимущество серым цветом, поскольку всё это ничего не стоит, если объёмы ваших таблиц меньше 10 млн. строк.

Что ж, преимущества мы разобрали. А что там насчет недостатков? Их есть у меня.
1. Нереально неудобные при работе с быстро меняющимися бизнес-требованиями. Сегодня вам нужно всего 3 значения в ENUM, а завтра добавилось еще 5, послезавтра - еще +1 и т.д. По сути, на каждый чих вам нужна миграция. "Что тут такого?" - скажете вы. Миграция пишется за 5 минут. И будете правы, если не писали ничего больше сайта для личного блога. А давайте расширим enum в таблице на 50 млн. строк, в проекте, где критично важно поддерживать минимальное время простоя. Привет lock на неопределенное время 🤝.
Ладно, на таких масштабах никто не делает ALTER "в лоб" (хотя и в таком случае есть возможность обойтись без локов). Применим классический pt-online-schema-change. Уже лучше, уже без локов. Осталось только подождать пару дней пока выполниться переливка данных..

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

2. "Без права на ошибку". Предположим, вы создали набор из значений пола: MANN и WOMAN, но допустили ошибку и не заметили её (если что, я специально допустил ошибку в MAN). Рано или поздно внутренний перфекционист заставляет принять решение об исправлении этой ошибки в enum, ведь весь ваш код также завязан на этом значении. Ну что ж, попробуйте исправить эту ошибку привычными вам способами, удачи.. 😏
Конечно этот пункт в какой-то мере притянут за уши, но важно помнить, что движок бд не даст вам просто так взять и поправить ошибку в enum, поэтому тщательно проверяйте орфографию 😅

Учитывая плюсы и минусы, описанные выше + реальный опыт использования двух подходов, лично для себя я сделал выводы в пользу НЕ использования типа ENUM при проектировании схемы бд. По мне, так этот маленький плюсик в виде человеко-понятных значений ну никак не может переплюнуть неудобства, которые добавляет этот тип. В конце концов, в современном PHP уже есть свой тип enum, который в сочетании с типизацией (например на TINYINT в бд), дает нам ту самую согласованность, минимализм и валидацию данных, при этом не лишая читаемости. А если уж так часто приходиться лезть на production, то задумайтесь о написании своих функций на уровне бд для маппинга данных в удобный вид.
ALTER очень больших таблиц в MySQL

Текст, изложенный ниже актуален для MySQL версии 5.7+ и движка InnoDB. Если вы имеете более старую версию бд - срочно меняйте работу!

Итак, задача: выполнить ALTER большой таблицы MySQL (50 млн. строк, ориентировочный размер - 4 ГБ). Пусть это будет некоторый абстрактный альтер без привязки к определенным бизнес-требованиям (создание колонки, индекса и т.д.). Как мы можем решить эту задачу?

Вариант №1. В лоб!
А в самом деле, что может быть проще создания новой колонки?
ALTER TABLE employees ADD COLUMN salary int(11) NOT NULL DEFAULT 0;

Хороший вариант для таблиц размером до 50 тысяч строк, но мы тут вообще-то про серьезные вещи говорим 😎. Не пишите такой запрос если модифицируемая таблица действительно большая и ваша версия MySQL ниже 8.0 (об этом позже). В противном случае вы рискуете в очередной раз слушать лекции вашего тех. лида о том, как плохо делать ALTER в лоб, потому что блокировки, перестройка таблицы и прочие ай-ай-ай. Он кстати будет прав, но не полностью. Вот пример альтера, который не затронет ровным счетом ничего:
ALTER TABLE employees CHANGE COLUMN salary salary_old int(11) NOT NULL DEFAULT 0;

А вот еще один, более повседневный. Это типичный запрос на расширение допустимых значений для ENUM:
ALTER TABLE employees MODIFY COLUMN gender enum('male', 'female', 'unknown') DEFAULT NULL;

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

Вариант №2. По уму.
Этот вариант хорошо подходит, если требуется добавить новую колонку или даже несколько колонок и при этом свести к минимуму время выполнения такой модификации. В таком случае стоит задать себе вопрос: "А нужен ли вообще тут ALTER?". Модификация существующей таблицы может занять не один час, так почему бы нам тогда не создать новую таблицу с нужными колонками и связать её со старой?
CREATE TABLE `employee_salaries` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`employee_id` bigint(20) unsigned NOT NULL,
`salary` int(11) NOT NULL DEFAULT '0',
`created_at` decimal(14,4) NOT NULL,
`updated_at` decimal(14,4) NOT NULL,
PRIMARY KEY (`id`)
// Еще индексы
);

Хороший вариант для быстрого решения проблемы. Идеально применять там, где действительно нужно добавить несколько колонок и сэкономить время. Если же бездумно использовать по каждому чиху, то выльется вам в кучу одноколоночных таблиц с огромным количеством join'ов для выборки данных.

Вариант №3. Проверенный
Очевидно мы хотим избавиться от блокировок при выполнении ALTER. В таком случае наша задача может быть выполнена в несколько этапов:
1. Создаем новую таблицу с модифицированной схемой (схема старой таблицы + новые колонки).
2. Навешиваем на старую таблицу тригеры на insert/update/delete. Они должны фиксировать изменения данных в старой таблице и отображать их на новую (имеются ввиду те данные, которые будут модифицированы в момент процесса переливки, о чем ниже).
3. Выполняем переливку данных из старой таблицы в новую.
4. Переименовываем таблицы (старую заменяем новой).
5. Дропаем старую таблицу.

Я вам так скажу, писать все это дело руками - такое себе занятие. Поэтому умные дяди уже решили эту проблему за нас, предоставив нам такой замечательный инструмент, как pt-online-schema-change (или аналогичное решение). Это самый проверенный подход для модификации больших таблиц. Используйте его в 95% случаев. Конечно, у этого подхода есть и негативная сторона - время выполнения.

🍒 Вишенка на торте. MySQL 8+
С версии 8.0 в MySQL был добавлен новый алгоритм INSTANT. Он позволяет мгновенно вносить изменения в таблицы при выполнении команды ALTER (добавление/удаление колонок и другие операции). Это достигается за счет того, что он выполняет изменения таблицы на уровне метаданных, не требуя при этом никаких блокировок, а также не затрагивая файл данных самой таблицы. Он используется как алгоритм по-умолчанию (там, где допустимо) во всех новых версиях MySQL. К слову сказать, альтер с этим алгоритмом у меня выполнялся буквально за милисекунды..
А вы тоже заметили, как ресурс Medium то и дело пытается выманить с вас деньги за подписку на их сервис? Всего-то 5$ в месяц за доступ к premium-контенту по типу "ТОП-10 open-source альтернатив популярных SaaS" или "Основы PHP Fibers", которые штампуются с завидной регулярностью юными авторами данного ресурса.

Я вам так скажу — это целое искусство, зарабатывать деньги на плохом продукте. Но еще большее искусство — зарабатывать деньги на воде...