DevFM – Telegram
DevFM
2.35K subscribers
80 photos
5 videos
492 links
О разработке: технологии, инструменты, system design, процессы, команды

Для связи @sa_bul
Download Telegram
Пятничное развлекательное

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

Венгерский математик Абрахам Вальд решил, что укреплять нужно места без пробоин. Если самолёт с пробоиной вернулся на базу, значит, повреждение не критичное. Это называется систематическая ошибка выжившего — survivorship bias. Мы судим о вернувшихся самолётах и не учитываем сбитые.

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

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

#fun
👍2042🔥1🌭1
Backup: январь

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

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

Архитектура проекта
— Проектируем систему — System Design
Практика распила монолита
— Жизненная история. Выбираемся из болота большого проекта
БезТЗатый программист

Интересное по Python
Python import: Advanced Techniques and Tips
— Классные pre-commit хуки
Покоряем большие CSV

Используем базы данных
Индексы в PostgreSQL
Этапы выполнения запросов в PostgreSQL
Manticore Search как замена Elasticsearch

Крутые базовые материалы
Вспоминая git
— Признаки хорошего логирования
Частичное клонирование репозитория

Строим веб-приложение
— Кажется, ваше приложение сейчас пятисотит
Авторизация через OAuth и OIDC
JWT и его друзья

Нейросети нас заменят
— Доступаемся до ChatGPT
Google Coding Interview With An Artificial Intelligence (ChatGPT)

#backup
🔥62🌭2
Практикуем Kubernetes

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

В этот раз посмотрим практическое руководство на официальном сайте кубера.

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

Все руководства, помимо практической части, сопровождаются теоретическими материалами.

Из приятного — можно ничего не устанавливать себе на компьютер, а пройти всё в терминале на сайте. Для большего погружения рекомендуем всё-таки развернуть у себя Minikube и делать практику локально.
#skills
👍4🔥32🌭2
Правильная структура ответа на собеседовании

Классический анекдот. Студент сдаёт экзамен по зоологии, а подготовился только к вопросу про блох. Тянет билет — там про собак. Начинает отвечать, что собака — млекопитающее, у неё есть голова, 4 лапы, хвост, всё это обильно покрыто шерстью, а в шерсти — блохи! И подробнейшим образом про блох. Преподаватель прерывает и просит рассказать про кошек. Студент снова: голова, усики, лапы, хвост и много шерсти, в которой — блохи, и опять про блох. Преподаватель снова прерывает и просит рассказать про рыб. Студент: тааак, рыбы., рыбы... плавают в воде, дышат жабрами, покрыты чешуёй. В чешуе блохи не водятся. Это спасает рыб от проблем с блохами. И снова про блох...

Рекомендуем версию этого анекдота с интересной историей из жизни про экзамен в РХТУ им. Менделеева. К чему это мы?

При ответе на собеседовании или на экзамене важно показать обширность и глубину ваших знаний. Выгодно максимально подробно отвечать, даже если ответ не совсем по теме. Забыли, что значит D в SOLID? Постарайтесь построить ответ так, чтобы максимально подробно рассказать про знакомые буквы. В процессе вспомнили другие темы, например, аббревиатуры, связанные с исходным вопросом? Пускайте в ход DRY, YAGNI, KISS, NIH-синдром, bus-factor и кучу другого материала, по возможности вплетая его в повествование. Высока вероятность, что собеседник забудет, что вы не до конца ответили на поставленный вопрос. Чем уместнее вы притянули смежные темы, тем менее заметна попытка скрыть незнание. Если тема совсем не к месту, то будет обратный эффект с обнаружением вашего незнания.

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

Но не злоупотребляйте таким приёмом. В работе важно уметь честно признать, что чего-то не знаешь. Нельзя знать всего, надо учиться у коллег, в том числе на правильном code review.

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

#devfm #sudo #edu #резюме
👍14🌭52
Многопоточный Python на примерах: избавляемся от дедлоков

Многопоточное программирование — это непросто. Самое неприятное — схватить дедлок, то есть взаимную блокировку потоков, когда поток 1 занял ресурс А и пытается захватить ресурс Б, а в это же время поток 2 занял ресурс Б и пытается захватить А. В этом случае потоки взаимно блокируют друг друга.

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

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

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

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

#python
73🌭3👍2
За всё хорошее, против всего плохого

В статье Software engineering practices представлен обширный набор советов. Разберём их подробнее.

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

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

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

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

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

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

#edu
🔥722👍2🌭2
Design distributed cache

Хочется порекомендовать замечательный youtube-канал System Design Interview. Автор вещает на понятном русском английском :)

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

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

Всё достаточно просто, локальный кеш, LRU – алгоритм, применяемый для вытеснения данных при переполнении кеша. Дальше – интереснее, появляется распределённая система, и этот distributed вносит проблемы. Рассматриваются dedicated и co-allocated кластеры, способы управления кластером, какие алгоритмы применяются для распределения данных по шардам, их плюсы и минусы.

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

Вопрос, который не освещается в видео, но заслуживает внимания – прогревания кеша. Что делать при старте, когда кеши пустые?

P.S. У этого канала интересная история. Автор выпустил десяток добротных видео, получил много приятных отзывов и пропал на два года. Потом вернулся и сказал, что все это время готовил полноценный курс и не отвлекался. У нас пока руки не дошли посмотреть более подробно, но должно быть интересно.

#youtube #skills #резюме
👍7🌭6🔥3
Пятничное развлекательное

По пятницам у нас культурный код. Бэнкси – один из концептуальных художников современности, известный, по большей части, за граффити. В 2006 году Бэнкси выставил на аукцион картину Balloon Girl (Девочка с воздушным шаром), являющуюся копией его граффити 2002 года. В момент продажи картины дистанционно активировали шредер в раме картины. Трудно представить мысли нового владельца картины, на глазах которого 1 миллион фунтов стерлингов начал самоуничтожение. Результат прикрепим в комментариях, задумка выглядит интересной.

Позже картина была переименована в Love Is in the Bin (Любовь в мусорном баке). А в 2021 году её продали за 25 миллионов долларов.

Подробнее о Бэнкси на вики, более подробно тут.

В 2020 году вышел фильм Banksy с неплохим рейтингом. Вы смотрели? Как впечатления?

#fun #films
🔥5🌭5👍32
Как kafka хранит данные

Интересная статья A Practical Introduction to Kafka Storage Internals, посвящённая организации хранение данных в кафке.

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

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

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

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

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

#skills
🔥5👍32
Буфферный кеш в PostgreSQL

Очередная серия статей от ребят из postgres. На этот раз о механизме журналирования, он же write-ahead log, он же WAL. Статьи не из лёгких и требуют серьезного погружения.

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

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

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

Размер кеша – это, что рекомендуют менять сразу после развёртывания базы. По умолчанию он равен 128 Мб. Нет конкретного значения, которое стоит выбрать для кеша, всё зависит от задачи и лучше выяснять на практике. Автор рекомендует взять для начала 1/4 оперативной памяти. Также стоит учитывать, что postgres использует обычные вызовы операционной системы, поэтому происходит двойное кеширование – кеш СУБД и кеш ОС.

Горячий вопрос: прогрев кеша. В postgres для этого есть расширение pg_prewarm. С помощью него можно сразу прочитать в кеш данные определённых таблиц. Также можно сохранять состояние кеша и восстанавливать после перезагрузки сервера.

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

#skills #database
🔥62👍2🌭2
Моё разочарование в софте

Статья-нытьё про грустное состояние индустрии с точки зрения оптимизации. С момента выхода статьи прошло лет 5, лучше не стало.

Всё невыносимо медленно работает. Приложения огромные по размеру. Поддержка проектов прекращается всё быстрее, привет куче flash-игр. Управление зависимостями в программировании очень непростое.

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

Всё же не забывайте при разработке думать об оптимизации. Разница между загрузкой веб-страницы в 0.5 или 0.6 секунд может быть незаметна, но между 0.5 и 5 секундами целая пропасть. Не тащите в код зависимость, если она вам не нужна. Задумывайтесь о будущем. Но не занимайтесь оптимизацией ради оптимизации, решение бизнес-задачи всему голова.

Статья идейно перекликается с мыслями поста Страх и ненависть в ИТ.

#edu
6👍3🔥3🌭32
Нестареющая классика, шпаргалка по SSH

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

Начинается с базы, коротко и по делу. Не нужно авторизовываться по паролю, настраивайте вход по ключу. Ключ генерируется одной командой и может быть закрыт паролем. Разумеется, ключ состоит из двух частей: открытой и закрытой. На сервер ключ можно скопировать ручками или специальной командой. У сервера есть свой ключ, который помещается в known_hosts. Для копирования данных через ssh-сессию есть команда scp. Это база. Теоретические основы были в отдельном посте.

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

– можно выполнить команду на удалённом сервере, оставаясь в локальной командной строке. Интересное применение, например, вывести содержимое какого-то файла и с помощью конвейера скормить его локально запущенной программе

– если хотим вызвать удалённую команду, а её вывод поместить в локальный файл, то для этого можно пробросить stdin/out

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

– если локальная машина имеет графический x-сервер, а удаленная нет, то можно сделать так, чтобы приложения с сервера рисовались у вас на рабочем столе

– публичные wi-fi совсем небезопасны, а VPN порой просто режут, поэтому есть выход – работа ssh в режиме socks-proxy

– заканчивается статья такими схемами, от которых волосы начинают шевелиться: проброс портов, вложенные туннели, реверс-сокс-прокси и проброс авторизации

Интересный факт, которым меня мучали в институте, и он упоминается в статье: ip-адреса 127.0.0.1 и 127.1 идентичны и нет никакой ошибки. Вот такие пироги.

#skills
🔥13👍5🌭32
Стратегии деплоя

Новую версию приложения можно выкатить по-разному. В статье Six Strategies for Application Deployment перечислено аж 6 стратегий деплоя. Какую выбрать – зависит от ситуации, золотой пули нет. Помимо описания самих стратегий автор приводит достоинства и недостатки каждой. Эти знания окажутся очень полезными, когда придется делать выбор в пользу какой-то одной. А ещё каждая из стратегий сопровождается наглядной анимацией. В общем, всё для людей.

Теперь о стратегиях.

Recreate – самый топорный вариант. Старая версия приложения гасится, новая запускается. Вот так стратегия :)

Rolling-update – постепенно выкатываются инстансы приложения с новой версией, по мере выкатки трафик переключается на них, старые инстансы постепенно гасятся.

Blue/Green – рядом с уже запущенным приложением запускается копия с новой версией, после некоторых health checks трафик полностью переключается на новую версию, а старая гасится.

Canary – почти как Blue/Green, только после выкатки новой версии сначала на неё пускается небольшое количество трафика. Убеждаются в стабильности работы и переключают весь трафик. После этого старая версия гасится.

A/B testing – как Canary, только обычно применяется для принятия некоторых бизнес-решений. Пользователей, которых направят на новую версию приложения, выбирают по некоторым условиям. Например, на новую версию направляются пользователи с определённой геолокацией или определённым браузером.

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

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

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

#skills
👍7🌭43🔥2
Полиморфизм на практике

10-минутное видео от ExtremeCode, то есть специфическое по юмору и лексике — будьте осторожны. Проектируем магазин товаров для взрослых, примеры кода на C#. Необходимо реализовать работу с разными товарами так, чтобы можно было легко добавлять новые товары. Хорошо показаны плюсы и минусы полиморфизма и его реальное применение.

Раньше мы уже предлагали крутое видео про ООП в целом.

#skills
👍52🔥2🌭21
Пятничное развлекательное

20 лет назад на Бродвейском театре был поставлен мюзикл Avenue Q. Одной из песен в мюзикле была The Internet Is For Porn, которая завирусилась и породила целую волну клипов. Звук использован с видеорядом из World of Warcraft, Диснеевских мультиков, Гарри Поттера и многих других.

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

Текст песни и перевод тут. Подробнее про сам мюзикл, история распространения на knowyourmeme.

А вообще, правило 34.

#fun
😁4👍3🔥2🌭21
GitOps – все ли так классно?

GitOps – подход, при котором всё состояние системы описывается в едином git-репозитории, а за синхронизацию с развёрнутой системой отвечает некий gitops-оператор. Звучит удобно.

В статье Что же такое GitOps? Его свойства и недостатки ребята из Фланта со всех сторон рассматривают этот подход.

Чтобы говорить о плюсах и минусах, хорошо бы с чем-то сравнивать. И автор сравнивает GitOps с так называемым CIOps. CIOps наиболее распространённый способ, когда деплоим просто из CI-системы. Этот способ подразумевает хранение конфигурационных файлов не в едином репозитории, а в репозиториях приложений.

В статьях, продвигающих gitops, нам говорят, что есть git-репозиторий и именно он является единственной точкой входа. Но это не совсем так. Ещё есть contaner registry – и как раз он вносит нюансы в стройную картину мира.

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

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

#skills
🔥5👍43🌭2
NULL в PostgreSQL

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

Перечислим ряд особенностей NULL, которые нам показались интересными.

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

Следующее, что важно понимать — чем NULL не является. Пустая строка, ноль, пустой массив, массив NULL – это всё не NULL. Но есть особенность – запись, в которой все поля NULL сама является NULL. В статье автор приводит неочевидные примеры на этот счёт.

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

Сравнивать что-то с NULL мало полезно — все равно получим NULL. Даже если захотим сравнить NULL и NULL. В результате получим сами знаете что.

Оказывается, имеет смысл писать "IS TRUE", а не "= TRUE". Потому что результат первой операции всегда будет TRUE или FALSE, а вот во втором варианте может выскочить неожиданный NULL.

Если хочется посчитать NULL или найти не NULL аргумент, то для этого есть специальные функции num_nulls и coalesce.

Такой привычный COUNT – и тот работает с подвохом. COUNT по конкретному полю посчитает только строки, где выражение NOT NULL, а вот COUNT(*) посчитает всё, включая NULL.

Если при сортировках хочется управлять NULL, то есть ключевое слово NULLS FIRST.

С индексами тоже интересно. Postgres использует индекс для поиска NULL значений. Если значений NULL много, плохая селективность, то лучше использовать последовательное сканирование вместо индекса. Чтобы исключить NULL из индекса можно использовать partial индекс с наложением условия IS NOT NULL. Автор дает практические советы, как найти кандидатов на такую оптимизацию.

Общий совет: если не планируете явно обрабатывать NULL, то стоит навешивать ограничение NOT NULL. Говоря об ограничениях, UNIQUE позволяет создать несколько записей со значением NULL, но в Postgres 14 появилась возможность запретить несколько NULL-записей.

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

#skills #database
🔥14👍32🌭2
Как сдвинуть гору Фудзи

Классическая книжка про подготовку к собеседованиям в Microsoft. Написана аж в 2003 году, но по факту покрывает практику собеседований примерно с 2000 по 2015 годы в компаниях из FAANG (Facebook/Meta*, Amazon, Apple, Netflix, Google/Alphabet), и примерно с 2010 по 2020 во многие российские.

О чём речь? Кто-то решил, что решение логических головоломок позволяет выявлять гениальных разработчиков, и такой формат собеседования ушёл в народ. И на собеседованиях стали давать логические задачи уровня "почему люки круглые", "за сколько взвешиваний можно найти одну из восьми фальшивых монет" и прочие крайне релевантные вопросы для middle python developer.

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

Рассмотрим несколько примеров. Наши ответы несколько отличаются от книги.

Вопрос 1, чисто на логику: "почему канализационные люки круглые". Тут неплохо бы показать ваше умение рассмотреть ситуацию со всех сторон:
– люки бывают квадратные, можно загуглить варианты
– круглая крышка не провалится вниз. Да, есть другие математические фигуры с таким же свойством, например, треугольник Рёло. Но круг из этих фигур требует наименьшего количества материала для производства
– человек в сечение круглый, поэтому канализационный колодец имеет форму цилиндра, поэтому крышка круглая
– круглую крышку можно катить

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

Вопрос 2. Ближе к реальной деятельности разработчика. Сколько всего бензоколонок в стране? Для ответа на этот вопрос нужно оценить число людей в стране, среднее число автомобилей на человека, среднюю частоту заправок автомобиля, среднее время заправки и так далее. Уметь оценить подобного рода величины при достаточно скудных входных данных полезно для system design, например, вспомним задачу проектирования поиска организаций по картам, где оценивалось число бизнесов в стране для определения размера базы данных.

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

Вопрос 3. Как тестировать солонку. Тут отправим вас к посту про тестирование карандаша.

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

#edu #резюме
👍9🌭421
Упрощаем жизнь руководителю

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

Ситуация. Документация проекта разбросана в разных местах, что, как мы писали, нехорошо. Что-то в confluence, что-то в вики проекта, что-то в ридми, что-то в головах разработчиков. Варианты действий
– публично ныть, что бардак
– жаловаться тимлиду, что бардак
– уволиться, потому что бардак :)
– действовать самостоятельно путём переноса документации в общее место и убеждения других разработчиков делать также. Этот вариант неплох для инициативных ребят, которые потом могут стать неплохими тимлидами сами
– прийти к руководителю и предложить хранить доку в общем месте. Предложить конкретное место с некоторым обоснованием из плюсов и минусов. Руководитель не всегда может видеть беду, разработчику виднее. Можно предложить ему style guide или какой-то набор практик для внедрения.

Руководитель будет рад таким инициативам от вас. Или нет, психология – наука не точная.

#devfm #edu
4🌭4🔥3👍2
Мемоизация и каррирование в Python

Небольшая статья о полезных фичах питона. Мемоизация – это сохранение результатов предыдущих вычислений, которое можно использовать для ускорения кода. Для ускорения вычисления числа Фиббоначи автор вручную создаёт декоратор, являющийся аналогом functools.lru_cache. Это стратегия кэширования least recently used, то есть удаления самых старых данных.

Каррирование – это техника преобразования функций, которая получила своё название в честь Хаскелла Карри. Язык Haskell тоже в его честь назвали. Вместо применения функции с N аргументами мы порождаем отдельную функцию с меньшим числом аргументов. Автор показывает каррирование и частичное применение на примерах.

А мы рассмотрим свой пример. Пусть у нас есть функция оценки студентов:
def add_mark(student, mark, date)

Из неё можно породить функции

add_mark_5(student, date)
add_mark_4(student, date)
add_mark_3(student, date)


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

А с помощью functools.partial мы можем ещё и динамически создавать частичные функции. Зафиксируем дату.

# заменяем третий аргумент на текущую дату
add_mark_today = partial(add_mark, date=datetime.datetime.now())
# теперь дату в параметры не пишем
add_mark_today("Ivan", 5)


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

#python
6👍6🔥3🌭3
Введение в logging на Python

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

Пора немного углубиться в детали логирования. Разберём модуль logging из стандартной библиотеки питона. В статье автор даёт пример лога своего проекта, подробно описывает сущность logger, после чего
– описывает уровни логирования debug-info-warning-error-critical, не забывает о методе exception, который работает как error плюс выводит информацию об исключении

– объясняет, что такое handler и разбирает некоторые варианты использования. К logger можно привязать несколько обработчиков, чтобы одновременно писать в несколько локаций. На наш взгляд, сейчас эта настройка потеряла актуальность – писать надо в стандартные потоки упакованного в докер приложения, а дальше собирать логи снаружи

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

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

– применяет LoggerAdapter для внедрения дополнительной информации в лог-сообщение

– применяет extra для логирования сущностей или их частей, например, включения в лог текста запроса веб-сервера

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

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

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

#python
🔥8👍52🌭2