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

В далеком 2011 году в Ульяновске я начал создавать филиал широко известной в узких кругах компании Undev, той самой, которая писала софт для трансляции выборов президента, проведения ЕГЭ и многих других мероприятий. Основным стеком компании на тот момент был Ruby. Как известно, в регионах рубистов крайне мало, и на тот момент во всем Ульяновске это был десяток человек, которых все знали по именам.

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

Первоначально идея развития состояла в том, что мы используем Руби почти везде (и js, конечно). Ведь это дает столько возможностей:

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

  • Быстрый вход в любой проект

  • Отработанные схемы обучения

  • Большая экспертиза по Ruby, которая «шарится» между всеми командами

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

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

Проблемы начали проявляться сразу, как только приходилось писать что-то вне стандартного флоу «рельс». Практически любая библиотека или самостоятельный модуль были написаны в худших традициях ruby:

  • Метапрограммирование — основной способ написания программ. Все, что можно сгенерировать программно, генерируется программно. Даже если вы не знакомы с этой концепцией, то представьте себе программу, в которой невозможно найти GREP определения функций.

  • Манкипатчинг как основной способ расширить функциональность

  • Активное использование глобального состояния

Я уже не говорю про то, что код при этом часто оставлял желать лучшего сам по себе. В разговорах выяснялось, что многие решения были продиктованы исключительно ограниченностью кругозора и отсутствием понимания принципов программирования. Ребята не могли их дифференцировать от самого языка. Любую ситуацию они рассматривали с точки зрения конструкций Руби. Например, несмотря на то, что Руби декларируется как полностью ООП-язык, те задачи, которые требуют использования полиморфизма включения (через инверсию зависимостей), решаются через манкипатчинг и глобальное состояние в классах (которые сами — глобальные объекты).

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

В то время я познакомился с небезызвестным Львом Валкиным, одним из самых авторитетных для меня людей в программировании. Человеком, который приобщил десятки тысяч людей к функциональному программированию. В то время он занимался ныне не существующей компанией Echo, а позже и филиалом компании Machinezone. Хотя Лев уже давным-давно живет в Долине, в те годы он довольно часто приезжал на малую родину, как раз тогда мы (ульяновские айтишники) запускали конференции nastachku.ru и ulcamp.ru.

> Сейчас используем в основном Python, Erlang, Haskell, C, C++, Docker, Vagrant, AWS, Git, Centos, Bash. Но ничего не мешает нам расширить или сократить этот список. Главное, чтобы для решения задачи был подходящий инструмент.

Каждый раз когда мы встречались, моно- и поли- культуры были предметом обсуждения. Я отстаивал точку зрения удобности монокультуры для бизнеса, Лев придерживался противоположной идеи, что монокультура вредит. И немного примеров:

Выдержка из статьи на лурке:

> Далее, насчет именно функциональных языков программирования. Из семейства ML OCaml действительно самый практичный. Пользователей у него больше, чем у остальных диалектов ML, библиотек, соответственно, тоже гораздо больше. Инструментарий, пусть и довольно скудный, опять же богаче. Да, если отвлечься от ML, то у того же Haskell пользователей и библиотек еще куда больше, но Haskell по заявлению самого Пейтон-Джонса не предназначен для продакшен. Да, его используют там, но Пейтон-Джонс позиционирует и развивает его как именно исследовательский язык. Ну и, что куда важнее, как язык Haskell гораздо сложнее, порог вхождения в него гораздо выше. Оба языка достаточно маргинальны, чтоб легко найти разработчиков на них, но тот же Лев Валкин вполне себе набирает просто толковых людей себе в команду, а там за пару недель на OCaml оные начинают вполне себе писать.

Статья в блоге Льва, как у них появился clojure: https://lionet.livejournal.com/125495.html

Тогда мне стало понятно, что выбранная схема обучения программистов в Андеве готовит не программистов, а Rails-программистов. Проблема расширения кругозора усугублялась еще тем, что уровень автоматизации и интегрированности инструментов в Rails настолько высок, что ребятам было крайне сложно вытащить себя куда-то еще. Любая задача решается с помощью фразы “поставь гем”. Все сделано до нас, только найди и используй. Я уже не говорю про то, что такие разработчики с трудом могут понять границу применимости привычного инструмента и подобрать более подходящее решение под задачу.

В 2013 году я резко изменил курс. Вместо обучению Rails, мы начали учить фундаментальным основам информатики. Основным языком на время обучения стал Clojure. Основным источником вдохновения - SICP. Внутри самой компании начались перемены и сдвиг парадигмы в сторону расширения спектра используемых технологий и языков. Сразу оговорюсь, что это не было расширение ради расширения. Все было обосновано с точки зрения бизнеса, главное, что мы сняли табу на это расширение. В арсенале появились такие языки как go, python, а сейчас, в restream (ex-undev) пишут на всем подряд

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

Я считаю крайне важным, чтобы человек, который учится программировать, делал это не на том языке, на котором он будет (планирует) писать код за деньги. Причем не менее важно то, что язык должен быть совсем другой. Если вы писали в университете на c#, а на работе пишите на java, то для вас мало что поменялось. Переход с динамического на статический язык (или наоборот) дает гораздо больше для общего развития, еще лучше, если этот язык из другой парадигмы.

В те годы я сам начал активно писать на Erlang, Clojure, Python и даже немного OCaml с Haskell. С тех пор туда добавился TypeScript.

Примерно в 2017 году я приехал в Санкт-Петербург как консультант в компанию Петер-Сервис, с которой и по сей день сотрудничаю. Меня пригласили как человека, который поможет наладить инженерные практики и посмотрит свежим взглядом на код и то, как ведется разработка. Честно скажу, что сам я в такого уровня сложности проектах не работал никогда: огромный биллинг, более 70 команд, тысячи людей и продукт, который должен работать как часы. Было даже немного страшно, что мой уровень окажется недостаточным для каких либо изменений. В целом оказалось, что напрасно.

Жизнь показала, что проблемы у всех одни и те же. В компании ярко выраженная монокультура. Большая часть команд, с которыми я работал, пишет исключительно на одном языке, чаще это Java. Причем, многие ребята либо всегда писали на Java, либо уже давно не видели ничего другого. Когда мы стали разбираться с конкретными проблемами, на которые наталкиваются ребята, стало понятно, что многие из них давно и успешно решены в Rails гораздо более удобными способами. Для некоторых команд отличным решением было бы использование React вместо jsf. Причем сам jsf был выбран, потому что «архитектор его знал», а попробовать js никто бы не решился. Нет соответствующей экспертизы и никто не готов брать на себя эту ответственность (оно и понятно). Также мало кто использовал принципы автоматного программирования, что приводило к трудноподдерживаемому коду (как минимум одна команда полностью переделала архитектуру одного из ключевых сервисов, связанного с платежами, после того, как мы «копнули» в сторону автоматов).

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

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

Собирая все вместе

  • Учите программирование сразу через несколько разных языков

  • Не будьте <язык>-программистом, различайте суть и реализацию

  • Постоянно смотрите по сторонам (достаточно фоловить в твиттере правильных людей и аккаунты).

  • Если вы писали только на статических языках, обязательно выучите динамический.

  • Если вы писали только на динамических языках, обязательно выучите статический.

  • Изучайте парадигмы программирования

  • Старайтесь использовать в повседневной практике хотя бы два языка (с учетом засилья js это не так сложно)

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

Понравился материал? Больше я пишу и снимаю:

Комментарии (12)


  1. toxicmt Автор
    26.08.2024 15:57

    Сам написал, сам прокомментировал. Наверное сейчас таким инструментом становится Go для части разработчиков, ну и никуда не девается Java


    1. Azgiliat
      26.08.2024 15:57
      +2

      А не JS? Веб, node на бэке и даже можно React native для мобилки. В каждой бочке затычка


      1. toxicmt Автор
        26.08.2024 15:57

        JS тоже да


    1. amironov
      26.08.2024 15:57

      Про C# тоже не стоит забывать.


  1. anonymous
    26.08.2024 15:57

    НЛО прилетело и опубликовало эту надпись здесь


  1. Biga
    26.08.2024 15:57
    +1

    Кодить попеременно на C++ и Python - не возникает проблем.

    Вот на JS и Python - мрак. Они перемешиваются.


  1. kozlov_de
    26.08.2024 15:57
    +2

    Если вы писали только на статических языках, обязательно выучите динамический

    Зачем это?

    Если не скрипт, не прототип и не фронт энд то зачем?

    Многоязычность в большой компании на большом проекте это возможно неплохо. Но количество экспертов должно быть больше количества языков )

    А экспертов много меньше чем просто программистов


  1. dsemenko
    26.08.2024 15:57
    +4

    Если я пишу на java и kotlin в продакшн, это считается за 2 языка? :D


  1. mvv-rus
    26.08.2024 15:57

    Тогда мне стало понятно, что выбранная схема обучения программистов в Андеве готовит не программистов, а Rails-программистов.

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

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

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

    • разрабатывать инструкции и выбирать (а то и создавать, если их нет на рынке) вспомогательные инструменты для специально обученных людей, чтобы они могли решать такие задачи, если они вдруг станут типовыми;

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

    Да, организовать работу таким обрзом сложнее, чем просто нанять группу работников-универсалов более высокой квалификации. Но, как показала история той же промышленной революции, рост эффективности производства лежит в этой стороне - в стороне углубления разделения труда, специализации и снижении требований к массовыи работникам. Если бы производством, как в Средние века, занимались бы сплошь квалифицированные мастера-ремесленники, чтобы стать которым нужно было показать свое умение, сделав chef d'oeuvre (шедевр, если в русском произношении), то мы бы ни за что не получили такого изобилия дешевой продукции промышленного производства, какое имеем сейчас.

    И я так наблюдаю, что в области разработки ПО бизнес пока что находится на стадии ремесленного производства (к сожалению это или к счастью - зависит от точки зрения).

    PS Все написанное выше к теме статьи относится косвенно: в ней обсуждается, как готовить программистов широкого профиля, а не нужно ли их готовить массово. Но раз автор упомянул, то я не смог пройти мимо.


  1. Dominux
    26.08.2024 15:57

    "Когда в руках молоток - всё вокруг кажется гвоздями"


  1. potan
    26.08.2024 15:57

    "На скольких языках вы пишите продакшен код?"

    На скольки пишут в компании, в комании в моем проекте, я пишу в компании, я пишу включая пет-проекты? Scala 2 и 3 - один язык или два?


  1. TheDreamsWind
    26.08.2024 15:57

    Не соглашусь с тезисами в статье, во всяком случае для карьеры пользы мало. Долгое время работал в аутсорсе из-за чего постоянно приходилось "бежать" за рынком: из iOS Objective-C в Java Android, из Java Android в iOS Swift, оттуда в ReactNative, затем в Node JS, пока, наконец не ушел в продуктовую компанию писать микросервисы. При переходе между стеками, рост "вширь" не ощущается, т.к. пока осваиваешь новые технологии, старые быстро забываются, и ценность твоей экспертизы не растет на рынке. Чего нельзя сказать о программах, которые расли вертикально, развиваясь в пределах одного стека - у них и экспертиза становилась глубже и тайтлы выше.