Первая история: Jaskell

Мне рассказывали когда-то о компании, которая писала бекенд на Java и хотела нанимать талантливых разработчиков. Чтобы привлечь их, эта компания размещала вакансии на Haskell, и потом уговаривала этих кандидатов все-таки писать на Java. По-моему, это не очень красиво (вешать ложное объявление — нехорошо), но нас сегодня интересует сама идея, лежащая в основе этой тактики: толковый разработчик важнее, чем стек, которым он пользовался в последнее время.

Вот небольшое видео, иллюстрирующее эту идею:

Вторая история: Kotlin

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

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

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

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

Из этой истории у меня два вывода:

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

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

Третья история: Alter

Сейчас мы нанимаем разработчиков в Alter. Тут мы не компиляторы пишем, а платформу для психотерапии. Ничего особо экзотического: Python, Django, MySQL, вот это все. Каждый день помогаем сотням людей.

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

Но почему-то мы время от времени слышим от знакомых и знакомых знакомых: "а вот я хотел(а) к вам в команду, но я на Java пишу, а у вас Python". Так я и решил написать этот пост.

Важные оговорки:

  • Мы нанимаем опытных разработчиков (Senior и Middle), учить с нуля нам не выгодно. Когда берем Middle, следим, чтобы был потенциал роста до квалификации Senior. Если кандидат застрянет на уровне Middle навсегда, в небольшой команде такой разработчик не очень нужен.

  • На собеседовании мы обсуждаем вопросы, общие для всех бекендовых стеков: как работает HTTP, что делать, чтобы сервис держал нагрузку, как проектировать схемы БД, как искать и устранять ошибки и т.д.

А зачем вообще так делать? Вам что, питонистов не хватает?

Если вам хватает, мы за вас рады :)

Делать так стоит, только если затраты на поиск разработчиков на нужном стеке превышают затраты по онбордингу в этот стек. Ясное дело, если у вас очередь отличных специалистов, которые вдоль и поперек знают какую-нибудь Django (или на чем там у вас бек), то вы не будете смотреть кандидатов с опытом на FastAPI, PHP, Java и т.д. А если вы из десяти кандидатов скрепя сердце готовы взять одного, а он вам говорит, что неделю подумает, потому что у него тут еще три оффера намечается, то, наверное, вам имеет смысл подумать, как расширить воронку.

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

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

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

Это как у Джоэла: Smart and gets things done?

Еще в 2006 года Joel Spolsky писал в своем The Guerrilla Guide to Interviewing (version 3.0), что достаточно знать о кандидате две вещи: толковый и доводит дело до конца (smart and gets things done). Зачем же тогда этот пост?

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

Во-вторых, если ограничиться "smart and gets things done", онбординг может оказаться существенно дороже, чем если брать человека, который решал похожие задачи, просто другими инструментами. Так что мы для себя считаем, что бекендер-джавист превращается в бекендера-питониста как на том видео выше, а вот что там насчет других специализаций — это уже сложный вопрос, который в каждом конкретном случае надо решать индивидуально. Массовому читателю я готов рекомендовать только быстрый онбординг в другой стек, не в другую специализацию.

А всегда ли это так хорошо работает?

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

Не любой разработчик захочет поменять стек

  • Кто-то привязан душой к своему любимому фреймворку и ни за что не "предаст" его. Ну, это не наш клиент, что делать.

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

Некоторые стеки отличаются сильнее, и между ними переход значительно тяжелее

  • Как правило, это связано с тем, что и задачи надо другие решать: если вчера писал обычный бек на PHP, а завтра надо делать highload на Java, онбордиться будет сложновато.

  • Некоторые платформы/проекты до сих пор используют более низкоуровневые абстракции. PHP, Node.js и Python более-менее избавляют от необходимости думать о тредах, а в Java при желании можно этого счастья хлебнуть ого-го сколько. Это зависит от того, как написан ваш Java-проект. Не надо ожидать, что онбординг питониста в мультитрединг будет таким же легким, как онбординг джависта в Django.

Чтобы быстро поменять стек, надо хорошо понимать основы

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

  • Если HTTP-заголовки или SQL для кандидата — темный лес, тут не до смены стека

  • Если кандидат совсем не понимает, что его любимый фреймворк делает под капотом, ему будет сложно освоить новый фреймворк, который делает под капотом что-то другое

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

  • Поощрять вопросы и запросы на ревью

  • Быстро отвечать на вопросы, чтобы разблокировать товарища (если вопросы выглядят моментально гуглящимися, дружелюбно спросить в личке, в чем дело)

  • Вежливо и аргументированно подсказывать идиомы и разные фишечки на code review

  • Не ругать стек, с которого человек пришел, за недостаточно православное мировоззрение

Получается, для джунов этот подход не работает?

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

На самом деле с Junior разработчиками вопрос вообще лежит в другой плоскости. Далеко не всем командам в принципе имеет смысл брать неопытных людей. То есть, если честно, скорее всего на предложение "нам трудно искать синьоров, давайте наберем джунов и доучим на месте", ответ: "отличная идея, но нам это не выгодно".

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

А разве смена стека — это не шаг назад в карьере?

Рекрутеры, а иногда и кандидаты, говорят: если я перейду на новый язык/стек, я в нем не буду таким профи, как в своем привычном языке/стеке — это ведь я стану менее ценным специалистом!

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

  • синтаксис языка выучить — это только в первый раз сложно, а третий-пятый язык уже учится гораздо легче,

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

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

Вопрос в зал

А вот как вы думаете: для фронтэндеров это тоже работает? Мы пока пишем в своих вакансиях, что нужен опыт на React.js, но, может, зря мы так делаем?

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


  1. evnuh
    03.12.2021 20:08
    +33

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


  1. isitnull
    03.12.2021 20:25
    +5

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

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

    Высказывание "талантливый человек талантлив во всём" довольно часто работает, и особенно ценен такой подход в ситуации новых проектов и трудно формализуемых задач, работа над которыми имеет перспективу более 3-5 лет.


  1. DmitryKazakov8
    03.12.2021 20:43
    +2

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


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


    Даже если знаешь, как идеально все организовать с точки зрения логики — подобрать подходящие библиотеки и написать аналогичную систему на другом стеке — дело не месяцев, но лет, путем нескольких масштабных итераций рефакторинга. Для чего это нужно, если на своем стеке решишь бизнес-задачи за N времени, а на новом за N*X? Если люди приходят "получить новый опыт, расширить свои компетенции и прокачаться" — это хорошо, но компаниям нужно совершенно не это, а качественное и быстрое решение задач. Поэтому на вакансии на других стеках я даже не смотрю — самокритик меня живьем съест, если буду делать задачи за значительно более долгое время, не смогу планировать сроки даже приблизительно, и качество значительно упадет. Считаю, что это более ответственный подход, чем "пойду не знаю куда и будь что будет, там разберусь".


    1. sgjurano
      04.12.2021 00:04
      +4

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

      Это очень поверхностное суждение, на бэкенде самое интересное начинается далеко не на уровне обработки запросов — это всего лишь триггер, один из множества.

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


    1. dzhiharev
      04.12.2021 00:42
      +11

      Как-то вы однобоко представляете себе работу бэкенда :)
      Так и бэкендер сможет сказать — что там на этом фронте? Все формочки одинаковые, UI паттерны устоялись — знай себе дергай api, да во вьюхи пихай. А вот на бэкенде все разное, там sql, тут nosql, вон там всякие кафки и рэббиты, очереди, многопоточность, нагрузку нужно распределять, данные с одной стороны размажь и продублируй, с другой обеспечь целостность и непротиворечивость…
      На мой взгляд разницы во фронтенде и бэкенде особой нет. Везде есть задачи разной степени сложности и в каких-то случаях смена стека проходит проще, в каких-то сложнее.
      Я сам фронтендер, если что :)


      1. DmitryKazakov8
        04.12.2021 14:01
        -3

        SQL синтаксис запросов и работа с базой разве сильно отличаются? Если используются ORM, только в синтаксисе различия, поэтому это не в счет сложности миграции. Кафки и рэббиты тоже те же самые, адаптеры как правило пишутся в сопоставимом формате — разве нет? Та же история про целостность и непротиворечивость — паттерны реимплементируются. Конечно, будут некоторые локальные особенности и ограничения подходов в фреймворках на других языках — но концептуально все, в моем понимании, то же самое.


        А вот многопоточность да, может очень сильно различаться. Если не прав, буду рад более подробному объяснению — сам только на php и node.js фулстачил, да на python по мелочи дорабатывал — каких-то концептуальных отличий не видел, кроме ноды — там можно писать изоморфный код бэк-фронт, делать единую схему моделей и валидаций апи бэк-фронт. В этом смысле удобство и переиспользуемость шикарные, но производительность по сравнению с более низкоуровневыми серверными языками оставляет желать лучшего (судя по обзорным статьям), хотя и на ноде под танком 1000 запросов / сек для ряда кейсов сервер за 10мс секунд стабильно отдавал ответ, если задача не требует подключения к базе. Существенные различия по скорости только в сложных сценариях, включающих походы в разные базы и микросервисы. Но у нас речь не о скорости, а о сложности перехода в бэке с одного стека на другой — и тут мой опыт говорит, что это намного проще, чем на фронте.


        1. sgjurano
          04.12.2021 14:40
          +1

          Стоит наверное начать с того, что одних популярных баз сейчас очень много: реляционные (MySQL, PostgreSQL), документоориентированные (MongoDB), key-value (Redis, Memcache), колоночные (Clickhouse) и wide-column (Cassandra, ScyllaDB), NewSQL (CockroachDB, TiDB), графовые (Neo4j, Dgraph) и полнотекстовые (Elasticsearch, Sphinx), есть ещё базы для control-plane (ZooKeeper, Consul, Etcd).

          С message-brokers в целом попроще, основные это: RabbitMQ, Kafka и Pulsar — у каждой своя архитектура и каждая со своими особенностями и best-practices.

          Хорошо бы понимать хотя бы примерно как они устроены внутри, в чём их различия и уметь их эффективно применять.


          1. DmitryKazakov8
            04.12.2021 14:54

            Да, с половиной я работал, и с Firebase для no-server сайтов. Речь о том, насколько разное взаимодействие с одной и той же базой на разных серверных языках. Вряд ли переход на другой язык потребует внезапно изменить базу одного типа на другую — скорее всего останется та же самая, а переход на другую будет по причинам, не зависимым от языка.


            Во фронтенде используется хранилище в оперативной памяти, взаимодействие с которым реализуется через state manager, который у разных фреймворков, как правило, кардинально различается, и в этом плане все сложнее.


            1. sgjurano
              04.12.2021 14:55

              С этим я согласен, язык глубоко вторичен :)


  1. konsoletyper
    03.12.2021 21:15
    +5

    Всё так. У меня по этому поводу как раз синдром самозванца. Мне постоянно присылают непрошенные вакансии на Java/Kotlin (и почему-то даже .NET) senior developer. Я читаю список требований и понимаю, что вообще мои текущий знания нерелевантны. И что мне делать, если меня внезапно попрут с текущего места? Остаётся только надеяться, что рано или поздно я выйду на людей, которых впечатлит мой опыт и мои скилы и которые поверят, что вспомнить Spring, которого я лет 8 уже не трогал, я быстро смогу. Но учитывая конвейер найма, не думаю, что это случится прямо совсем быстро. Останется мне с апломбом приходить и заявлять, что я синиор и продаю не знания какого-то там фреймворка, а общеинженерные навыки. Интересно, вот действительно, что важнее: понимать, как в очередном фреймворке используются корутины Kotlin или глубокое понимание устройства этих самых корутин и причин именно такого их дизайна в языке и рантайме языка?

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

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

    И главное: вот нанимаешь такой человека с хорошим резюме. И вещи он правильные на собеседовании говорит. А как нанимаешь - он сидит и пишет комментарии на Хабре ничего не делает. Так что в этом смысле конкретный стек вообще вещь не принципиальная.


    1. tuxi
      05.12.2021 00:21

      и которые поверят, что вспомнить Spring, которого я лет 8 уже не трогал
      Вы не одиноки! Из-за повального засилья Spring в вакансиях, пришлось несколько лет назад расширить кругозор и начать использовать Golang в небольших проектах. Просто чтобы хоть какая-то подушка безопасности была.


  1. un1t
    03.12.2021 21:56

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

    Я тоже думаю, что сменить стек бакенда не проблема, если речь не идет о чем-то с большим порогом вхождения типа С++.

    Мой стек это python/django также был опыт работы 2.5 года node.js. Конечно же я знаком с другими языками программирования C++/Go/Kotlin/Rust, но большого опыта в них нет, так что на это никто даже не смотрит.

    Я пробовал откликаться на вакансии на go, и мне вообще никто не ответил. Я правда не много откликался, но все-таки это показатель.

    А в одной вакансии по node.js мне сказали, что мой опыт c node.js не релевантен, т.к. это было 5 лет назад и что 2.5 года этого не достаточно. (Это при общем стаже 14 лет)


  1. mSnus
    03.12.2021 22:21
    +4

    С незнакомым стеком тратится туча времени на дурацкие ошибки от разного приведения типов до непривычных способов работы с стандартными вещами (с массивами, например) и изобретения велосипедов, которые в данном стеке уже существуют.

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


  1. kreddos
    04.12.2021 04:35
    +1

    А разве смена стека — это не шаг назад в карьере?

    Тут мое мнение совпадает с вашим, и я полностью согласен с вашими доводами.

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

    Более того на одном из прошлых мест работы, когда ты помогал ребятам с java, руководителем это не воспринималось как твое развитие, следовательно ты не растешь как специалист в своей области, а исходя из этого и поднимать тебе зп нет смысла. Хоть это и грустно, но я с таким сталкивался ни раз :(


  1. mentin
    04.12.2021 05:52
    +1

    Я придерживаюсь таких же принципов, стек не важен. Сам менял C++ на Java, на C++, на C#, на С++. Работодатели попадались разумные, скажем когда проходил последнее интервью на С++ позицию, писал код на С#. Ничего, одна из интервьюеров оказалось была Java программистом, и когда я написал что-то неправильное с точки зрения Java мы приятно обсудили разницу в пространствах имён в Java и C#.

    Но надо очень следить что человек будет учить новый стек, а не работать по принципу "на Фортране можно писать на любом языке". У нас часть тестов были на Питоне, и занявшись ими однажды, я ужаснулся как всё ужасно, сколько ошибок они пропускают и так далее. Были написаны как на Фортране, ничего не ясно, кроме того что там миллион багов. Вот за такое надо было гнать. Я Питон знаю плохо, но поймал знакомого питониста, и за 30 минут мы превратили это в идиоматический Питон, код читался как родной язык.


  1. fransua
    04.12.2021 09:24
    +1

    Во фронтенде фреймворк зачастую подменяет основы веба: вместо HTML специфичные компоненты, вместо CSS - Styled Components, и так далее. Настолько, что знание основ может даже мешать: как например onInput/onChange в React.

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


  1. Victor_koly
    04.12.2021 16:06

    По поводу идеи "У нас проект на Java, а не сможем ли мы переписать его на Пайтон?". Очень условно говорим, что если к нам пришел "явно не Джун" в Пайтоне, то он понимает, что в Пайтон он будет использовать вместо JDBC. Это я сейчас пишу условно, т.к. я совсем не программист.

    Значит ему только нужно объяснить опсам, что установить на сервер вместо GlassFish.


  1. vsh797
    04.12.2021 19:48
    +1

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


  1. CaerDarrow
    05.12.2021 03:31

    Ясное дело, если у вас очередь отличных специалистов, которые вдоль и поперек знают какую-нибудь Django (или на чем там у вас бек)

    Если разраб вдоль и поперёк знает только один фреймворк, 3/4 батареек из которого становятся все менее актуальны, он не такой уж и отличный. Сейчас все новое пилят на сервисах/микросервисах и питонисту, стоит иметь представление о 3-4 фреймворках:

    1. что-то простое, как топор (flask)

    2. что-то асинхронное и простое, как топор (aiohttp)

    3. что-то напичканное полезными батарейками (FastApi/Django, чаще DRF)

    Поэтому да, крут тот, кто знает в первую очередь базу, а не фреймворк. И подход:

    На собеседовании мы обсуждаем вопросы, общие для всех бекендовых стеков: как работает HTTP, что делать, чтобы сервис держал нагрузку, как проектировать схемы БД, как искать и устранять ошибки и т.д.

    как раз отсеит тех, кто ковырял только джангу. Но так ли нужно ли это, если:

    Ничего особо экзотического: Python, Django, MySQL, вот это все

    ?


  1. BATPYIIIKOB
    06.12.2021 11:22
    +1

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