🔋 Труба данных – Telegram
🔋 Труба данных
3.99K subscribers
330 photos
5 videos
9 files
449 links
Авторский канал обо всем, что происходит в мире работы с данными: хранение, обработка, визуализация, как мы принимаем решения и как мы становимся профессионалами в работе с данными.

Автора канала - @SimonOsipov
Download Telegram
Рубикон перейден

Наступил тот момент, когда я понял: пора делиться тем, что я знаю и тем, о чем я узнаю. Поэтому я решил завести канал про дата инженеров.

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

Информация по размещению на канале
Вот тут всякая подробное про канал и размещение https://simonosipov.notion.site/f8e3b889848345bd964e17c124489076

Меня всегда можно найти по адресу @SimonOsipov.
Для начала, немного юмора.

Мне кажется, что вокруг BigData в целом столько хайпа и столько тумана войны одновременно, что очень легко запутаться, что из этого всего вещь полезная, а что - лишь временное явление.
Например, https://pixelastic.github.io/pokemonorbigdata/ - прекрасный сайт, который протестирует вас на знание технологий из стека BigData... или на то, что вы очень много играли в Pokemon GO.
Channel photo updated
Data Engineer. Восход

Российские локализаторы очень странно перевели название крайнего эпизода Звездных Войн The Rise of Skywalker -> Скайуокер. Восход. Поэтому я тоже не стал заморачиваться на тему названия этой записи.
На просторах интернета была найдена хорошая статья про рост спроса на дата инженеров.

У нее, кстати, есть продолжение. Но об этом в следующий раз..
О тестах замолвите слово

Мне повезло. У моего работодателя - несколько своих кластеров: расчетный, дев-тест и прод k8s, GP и так далее . Поэтому дата-саентисты могут гонять свои модельки туда-сюда сколько угодно раз без каких-либо забот. Я пару раз работал ночью и кластер даже ночью утилизируется минимум на 50%. Зачем задумываться о тестировании своих Spark приложений, если ошибки почти ничего не стоят в каком-то понимании (разве что модель придется заного запустить), а если еще самая тяжелая операция это toPandas(), то... О потерянном времени никто не думает.

Однако если ваши Spark приложения работают в облаке (AWS, Azure, GCP), то каждая ошибка может стоить очень дорого (например, если приложение падает после 10 часов работы). Следующее видео для тех, кому приходится запускать свои приложения в облаках и тех, кто понимает необходимость тестирования. Даже если у вас собственный кластер. Не надо HH и в продакшен


https://www.youtube.com/watch?v=S8CnHieFF28

Вещает Виталий Худобахшов из JetBrains на митапе у Wrike
Data Science Data Engineering is new sexy

Сначала пришли саентисты. И рассказали, что сейчас из всех этих данных сделают красиво. И вроде что-то получается, но вот заниматься архитектурой / инфраструктурой и черновой работой им не очень нравится, не очень хочется и не очень умеется. Конечно, это ведь математики, исследователи, ученые, аналитики, но не программисты и инженеры, их голова занята другим и это абсолютно нормально. Не говоря уже про код, который они производят. Конечно, недостижимая мечта - саентист, который пишет production-ready код приложения, с деплоем, тестами и проверкой качества данных, используя какой-нибудь паттерн проектирования. Те, кто так умеет - давно получают больше одной Козули и хорошо прикормлены в нужных местах.

Ох, сколько раз я слышал про неинтересные задачи, когда дело касается парсинга csv. И тут приходит осознание, что делать это надо, надо автоматизировать рутину, создавать витрины и все вот это. Наступает время искать Дата Инженеров.

Не люблю эту сегрегацию, мол саентисты это элита, а инженеры это обслуживающий персонал. В остальном - отличный выпуск подкаста с Артёмом Пичугиным — Head of Data Programs в Newprolab, в котором говорят про обучение именно таких специалистов, как я.

https://www.youtube.com/watch?v=h45p5JpA6x4



P.S. Ни в коем случае не накидываю на саентистов и аналитиков, отличные ребята, просто цели, задачи и средства достижения их у них другие, поэтому выходит как выходит.
Data Engineer. Падение

Продолжаем традицию дурацких названий. Помните, совсем недавно, я обещал вам продолжение статьи про рост важности позиции Дата Инженеров? Так вот, сдерживаю свое слово и представляю вашему вниманию вторую часть. Тут уже я не поленился и даже ее перевел. Вот о чем там буквально за пару минут:

Скучно и постоянное переключение контекстов
Во-первых, задачи ETL плюс-минус одинаковые и со временем надоедают всем. А во вторых, из-за того, что само исполнение задачи занимает какое-то время, приходится постоянно переключаться между задачами: одну выполняет компьютер, другую кодишь ты. Это изматывает.

Согласие во всем
Бывало у вас такое, есть три команы, каждая из которых собрала себе витрину одной и той же сущности, и у всех разные результаты? В моей работе так постоянно. В средних и крупных компаниях достижение "Единой точки правды" практически невозможно, ведь слишком много мнений на то, как и что нужно считать. В итоге, в компании появляется такое явление, как data silo. Это когда каждая команда или отдел создают свои базы данных, самостоятельно их наполняют и не делятся с остальными. Это одна из сложнейших проблем инженеров данных и ее решение требует существенных сдвигов в мышлении у команд и департаментов в целом.

Мы не попали на лодку Devops
Современный Data Engineering штука довольно дорогая и крайне чуствительная к ошибкам. Поэтому когда весь мир побежал внедрять практики devops, мы не потащили свой багаж туда, ибо очень дорого. А теперь расхлебываем, ибо почти все изменения в pipeline upstream (хрен переведешь адекватно) приводят к ошибкам и тому, что пайплайн останавливается.

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

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

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


С оригиналом можно ознакомиться здесь:
https://medium.com/@maximebeauchemin/the-downfall-of-the-data-engineer-5bfb701e5d6b
Минутка юмора

История смешная, а ситуация страшная.
За Postgres замолвите слово

https://www.youtube.com/channel/UC0SBGSNmBLrTZIkbN-lJHnw/playlists

Тут ребята с канала RuPostgres собрали 350+ видео про Postgres, начиная от основ и простых запросов, заканчивая оптимизацией, шардированием и вот это все. Советую себе сохранить и потихоньку посматривать. Ибо работа с СУБД - один из основных скилов дата инженеров.
Вредные советы. Вступление

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

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

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

Для того, чтобы изучить алгоритмы, есть 3 прекрасные книжки (в порядке возрастания сложности):

1) Грокаем Алгоритмы (Бхаргава)
2) Алгоритмы. Руководство по разработке (Скиена)
3) Алгоритмы. Построение и Анализ (Корман)

А вот чтобы писать "чистый код" нужно делать две вещи:

1) Писать хорошие штуки
2) Не писать плохие штуки (или антипаттерны).

Вот про набор плохих штук и будет эта серия заметок: какие подходы необходимо избегать в своем коде, чтобы потом токсичный душнила-сеньор не зарубил твой код на code-review. Погнали!
👍2
Вредные советы. 1. Доступ к защищенному аттрибуту извне

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

Кстати, если использовать __ (double underscore, двойное подчеркивание), то уже просто к аттрибуту обратиться не получиться, ибо произойдет такая штука, как name mangling.

Антипаттерн
class Rectangle(object):
def __init__(self, width, height):
self._width = width
self._height = height

r = Rectangle(5, 6)

print(f"Width: {r._width}")


А как надо?
Если вы прям уверены, что вам нужно обращаться к защищенному аттрибуту класса, делайте следующее:
1) Убедитесь, что это не приводит к неожиданным результатам далее
2) Рефакторьте код так, чтобы этот аттрибут стал частью публичного интерфейса класса

#вредныесоветы
Вредные советы. 2. Не пихайте лямбду в переменные

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

- У нас есть проблема..
- Ее можно решить с помощью регулярных выражений!
- У нас есть две проблемы...


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

Антипаттерн
f = lambda x: 2*x

Код выше присваивает лямбда выражение, которое возвращает удвоенное входящие значение. И это полностью идентично def.

А как надо?
def f(x):
return 2 * x

В этом случае имя результирующей функции именно f, а не дженерик <lambda>. В этом случае и дебажить проще будет, и один функционал не подменяется другим.


#вредныесоветы
Дата Инженеры vs. Дата Саентисты

Как же я не люблю этот булшит (бомбит настолько, что аж сюда написал): дата инженеры получают меньше, их работа это подносить данные, простые SQL макаки и вот это все. Или, например, как говорит автор вот этого видео: "Я знаю много Дата инженеров, они все недовольны своей работой". Да ну не доволен, уходи заниматься чем-то другим... И если FANG уже решили все свои проблемы с распределенными системами / пайплайнами и вот этим всем (в чем я сильно сомневаюсь, там вечно есть что делать), то нужно помнить, что в мире еще куча компаний, которым нужны инженеры.

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

https://www.youtube.com/watch?v=vmYaAzbv9xk

#пятничныйYoutube
Как стать программистом

Не-не-не. Это не реклама курсов по программированию с гарантией трудоустройства. Честно, если вы решили сменить профессию и рассматриваете курсы по программированию, бегите подальше от тех, кто обещает вам гарантию трудоустройства. Это все маркетинг.

А вот что действительно помогает трудоустроиться - так это работа над собой, над своими проектами, практика -> гайды/книги -> практика -> практика -> повторить. У меня есть знакомый приятель, который работал в институте физики, ему это надоело и он решил сменить направление. Пошел на курсы, поучился, после окончания не бросил и не сложил руки с фразой "Ну все, нанимайте меня", и спустя 8 месяцев он попал в уютную IT-шечку. Когда я ему предложил прийти в подкаст и рассказать свою историю, он ответил: "Ну не, мне нечего рассказывать, я ничего такого не сделал". Наоборот, ты дофига сделал.

Именно такие истории нужно рассказывать. Чтобы люди не боялись приходить в профессию, вне зависимости от пола и возраста и предыдущего опыта. И для того, чтобы поддержать вашу мотивацию, вот вам еще подборка "Как мы стали программистами" от канала @seniorsoftwarevlogger или впечатляющие истории ребят из Lamoda или такое же количество великолепных историй вот в этом треде в твиттере. Но больше всего я люблю подборку основателя FreeCodeCamp Квинси Ларсона "А не слишком ли я стар для этой фигни?"

#пятничныйYoutube
Вредные советы 3. Переопределение встроенных функций

Что не так?
У питончика есть приличное количество встроенных функций, которые доступны в интерпритаторе. Если у вас прям нет дико горящей причины их переопределить, не стоит называть другую функцию также, как встроенную или складировать что-то в переменную с таким именем. Это может вылезти в совсем неожиданном месте (и заметить будет с первого взгляда непросто) или вообще вылетать с ошибкой во время исполнения.

Антипаттерн
Посмотрите на пример ниже, в котором встроенная функция list() превратилась в переменную. Естественно, при попытке создать пустой список, используя встроенную функцию, мы получим ошибку. На таком примере это легко заметить, но когда у вас кодовая база в несколько сотен или тысяч строчек, искать придется долго.

>>> list = [1, 2, 3]
>>> list('my_string')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable


А как надо?
Надо всегда думать про названия переменных и функций, чтобы по ним было понятно, что в них лежит и, если возможно, понимать какого типа:

>>> numbers_list = [1, 2, 3]
>>> list('my_string')
['m', 'y', '_', 's', 't', 'r', 'i', 'n', 'g']


#вредныесоветы
Кто есть кто в этом Дата Caнса

Смешная игра слов с Игрой Престолов. Ладно, посмеялись и хватит. На самом деле, огромное количество компаний сейчас пытаются запрыгнуть на этот hype-train под названием "Data Science". Везде же большие данные, в них куча денег, надо срочно все анализировать и зарабатывать кучу денег. А вот понимания, кто им нужен и в каких количествах - нет. Экспертизы нет же в самом начале, поэтому непонятно, кого брать и кого он позовет за собой.

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

Для того, чтобы отличать data analyst, data scientist и data engineer, предлагаю посмотреть прекрасное видео от одного из основателей ODS (Open Data Science) сообщесва - Алексея Натекина

https://www.youtube.com/watch?v=lDkTNURDIaY

#пятничныйYoutube
Вредные советы 4. Порядок исключений
Когда случается исключение, то Питончик ищет в порядке очереди. Первое что подошло, то и выкидывает наверх. То есть, помня про наследование классов, даже если у нас вылетит специфичное исключение, то, наткнувшись первым делом на базывай класс Exception, Питон выдаст его. Сейчас покажу на примере:

Антипаттерн
Ниже написан код, который выдает ZeroDivisionError. И мы даже обернули все это в try/except и нужное исключение прописали. Однако, до него мы никогда не доберемся, потому что ZeroDivisionError это подкласс Exception, и поэтому, когда произойдет ошибка, программа полезет смотреть в ошибки, увидит базовый класс Exception и отдаст его. Все происходит линейно и полное совпадение не нужно. В коде ниже вылетит Exception:

try:
5 / 0
except Exception as e:
print("Exception")
except ZeroDivisionError as e:
print("ZeroDivisionError")


А как надо
А надо от частного к общему: сначала помещаем специфические, потом общие исключения. В таком случае мы не пропускаем детали, сваливая все в общую кучу.

try:
5 / 0
except ZeroDivisionError as e:
print("ZeroDivisionError")
except Exception as e:
print("Exception")


#вредныесоветы
К чему быть готовым на собеседованиях

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

И, не смотря на то, что часть советов относятся именно к карьере DS, я бы хотел заострить ваше внимание на двух других моментах:
1) Всегда знайте ваши слабые и сильные стороны.
2) Нужно знать, сколько ты хочешь денег и что тебе есть за что их платить.

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

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

#пятничныйYoutube

Ссылка на видео
Вредные советы 5. Return при создании объекта

Что не так
__init__ это специальный метод, который автоматически вызывается, когда в памяти резервируется место для объекта. Цель этого метода инициализировать экземпляр класса с его дефолтными значениями. Использование __init__ вместе с return заставляет этот метад делать что-то кроме инициализации объекта. Вся логика должна быть перенесена в отдельное от инициализации место.

Антипаттерн
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
self.area = width * height
return self.area

Метод __init__ не только создает экземпляр класса Rectangle, но и возвращает его площадь. Это нарушает правило "__init__ только для создания".

А как надо?
Нет никакой причины, почему класс Rectangle должен возвращать площадь сразу после создания объекта. Логику необходимо вынести в отдельное место, смотри код ниже:
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
self._area = width * height

@property
def area(self):
return self._area


Обрати внимание, что чтобы использовать декоратор @property нам понадобилось унаследовать Rectangle от object.

#ВредныеСоветы
Правило 10 000 часов

Скорее всего, вы все слышали про это правило: "Чтобы стать мастером-фломастером в чем-то, нужно потратить 10 000 часов на это". Это прям дофига времени, почти 5 лет полноценной работы с 9 до 18. Вот только тут есть маленькая особенность: столько времени нужно, чтобы стать топ 1% в чем-то. Но такие rockstar разработчики и инженеры нужны 1-2 на сотню человек в компании.

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

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

Так вот, автор этого прекрасного TED видео (внимание, английский язык) приводит простые 4 правила:

1) Разбиваем большую задачу на мелкие и фокусируемся на той, что даст нам наибольший эффект
2) Не прокрастинируем, набирая кучу всего вокруг. Берем столько, чтобы было достаточно начать делать.
3) Убираем все преграды для прокрастинации
4) Обещаем себе погрузиться в это как минимум на 20 часов

Все просто и легко. Особенно мне нравится пример, который приводит автор касательно п. 2: "Я хочу научиться программировать! Поэтому я подписался на 8 пабликов по программированию, 6 ютуб каналов, скачал 20 книг из Телеграма, сейчас все это просмотрю и смогу кодить". Да вот нифига! Чтобы научиться программировать, надо программировать. Вот и весь секрет успеха.

#пятничныйYoutube
https://www.youtube.com/watch?v=5MgBikgcWnY
Вредные советы 6. Геттеры и Сеттеры, прям как в Java

Открою страшную тайну: я начинал свой путь в программировании с Java, даже кучку книжек накупил и занимался на одном известном ресурсе с инопланетянами по Java программированию. Но мне Java не понравилась своей говорливостью (verbose), поэтому я переключился на более простой в чтении язык - Python.
Питончик это не джавка (с). Если вам нужно присвоить или получить аттрибут класса или объекта, просто сделайте это. А если вам нужно перед этим еще произвести какую-то логику - используйте декоратор. Давайте не превращать Python в Java, используя геттеры (метод для получения) и сеттеры (метод для присваивания).

Антипаттерн
В Java вполне себе типичное явление для всех аттрибутов класса, которые вы хотите выставить наружу, создавать геттеры и сеттеры. Так вот, в Python этого делать не надо.

class Square(object):
def __init__(self, length):
self._length = length

# Java стиль
def get_length(self):
return self._length

# Java стиль
def set_length(self, length):
self._length = length

r = Square(5)
r.get_length()
r.set_length(6)


А как надо?
Берем и обращаемся.
Обратите внимание, что нижних подчеркиваний перед аттрибутами нет (смотри #вредныесоветы 1. Защищенные аттрибуты).

class Square(object):
def __init__(self, length):
self.length = length

r = Square(5)
r.length
r.length = 6


Использование @property декораторов
Когда мы используем "защищенные" аттрибуты класса, просто так наружу показать мы их не можем, поэтому мы используем @property декораторы, чтобы воссоздать функциональность геттеров и сеттеров.

class Square(object):
def __init__(self, length):
self._length = length

@property
def length(self):
return self._length

@length.setter
def length(self, value):
self._length = value

@length.deleter
def length(self):
del self._length

r = Square(5)
r.length # автоматически вызывается геттер
r.length = 6 # автоматически вызывается сеттер


#вредныесоветы