Поставщик высоконагруженного API Stream перешёл с Python на Go, хотя этот язык знают немногие. Причинами решения делимся под катом к старту курса по Backend-разработке на Go.

1. Производительность

Go — быстрый. Очень и очень быстрый. Его производительность близка к Java [сегодня используется на финансовом рынке для высокочастотного трейдинга — торговли на большой скорости — прим. ред.] или C++. В нашем случае Go чаще всего оказывался в 40 раз быстрее Python. Вот небольшое сравнение производительности этих языков.

2. Производительность языка имеет значение

Для многих приложений язык программирования — это просто связующее звено между программой и базой данных. И, как правило, производительность самого языка особо не важна. Но Stream — это поставщик API, который обеспечивает работу платформы с каналами и чатами более 700 компаний и более 500 миллионов конечных пользователей. Годами мы пытались оптимизировать Cassandra, PostgreSQL, Redis и т. д., но однажды наступает момент, когда пределы возможностей языка достигнуты.

Python — отличный язык, но для таких задач, как сериализация/десериализация, ранжирование и агрегирование, он довольно медлительный. Мы регулярно сталкивались с проблемами производительности, когда Cassandra получала данные за 1 мс, а следующие 10 мс Python тратил на превращение их в объекты.

3. Продуктивность разработчика и мало возможностей для креатива

Взгляните на этот небольшой кусок кода Go из статьи How I Start Go. Это отличная обучающая статьи и хорошая отправная точка для изучения Go.

Если вы новичок в Go, то в этом небольшом фрагменте кода вас мало что удивит. В нём показаны несколько присвоений, структуры данных, указатели, форматирование и встроенная HTTP-библиотека. Когда я только начал заниматься программированием, мне нравилось использовать тонкости возможностей Python. Python позволяет импровизировать с кодом, который вы пишете. Например, вы можете:

  • использовать метаклассы для самостоятельной регистрации классов при инициализации кода;

  • менять местами True и False;

  • добавлять функции в список встроенных функций;

  • перегружать операторы через magic-методы;

  • использовать функции в качестве свойств через декоратор @property.

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

Конечно же, это «просто» зависит от вашего конкретного случая. Если вы хотите создать базовое  CRUD API, то я бы порекомендовал всё-таки Django + DRF или Rails.

4. Конкурентность и каналы

Go, как и любой язык, стремится к простоте. Для него не придумывали множество новых понятий. Целью было создать простой язык — быстрый и удобный в работе. Единственная область, где в Go появилось нечто новое, — это горутины и каналы. (Если быть на 100% точными, то понятие CSP появилось в 1977 году, так что данное новшество — скорее уж, новый подход к старой идее).

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

Среда выполнения в Go справляется со всеми сложностями. Реализация конкуренции через горутины и каналы позволяет с лёгкостью использовать доступные ядра ЦП и обрабатывать конкурентный ввод-вывод — и всё это делается без усложнения разработки. Для запуска функции в горутине требуется минимальный шаблонный код (если сравнивать с Python/Java). Вы просто добавляете к вызову функции ключевое слово go:

С подходом Go к конкурентности очень легко работать. Это интересный способ реализации, если проводить параллель с тем же Node, в котором разработчику нужно быть предельно внимательным к тому, как обрабатывается асинхронный код. Ещё один прекрасный аспект конкурентности в Go — детектор гонки. Вы всегда заметите любые состояния гонки в асинхронном коде.

Перевод твита

Тук-тук

Состояние гонки

Кто там?

Несколько полезных ресурсов для знакомства с Go и каналами вы найдёте ниже.

5. Быстрая компиляция

Сейчас наш крупнейший микросервис, написанный на Go, компилируется за 4 секунды. Быстрая компиляция Go — это его главный плюс по сравнению с такими языками, как Java и C++, которые славятся своей медленной скоростью компиляции. Мне нравится сражаться на мечах, но ещё приятнее решать задачи, пока я помню, что должен делать мой код:

Перевод

— Эй, давайте работать!

— Компиляция!

— Ох, продолжайте.

6. Возможность создать команду

Начнём с очевидного: разработчиков Go гораздо меньше, чем для более старых языков (C++ и Java). По данным StackOverflow, 38% разработчиков знают Java, 19,3% разбираются в C++ и лишь 4,6% освоили Go. В данных на GitHub прослеживается схожая тенденция: Go используется чаще таких языков, как Erlang, Scala и Elixir, но его популярность ниже, чем у Java и C++.

К счастью, Go — очень простой и лёгкий в изучении язык. В нём есть нужные вам базовые функции и ничего более. Из новшеств можно выделить оператор defer и встроенное управление конкурентностью через горутины и каналы. Для приверженцев чистоты языка: Go далеко не первый реализовал эти концепции, но именно он сделал их популярными. Благодаря простоте Go любой разработчик на Python, Elixir, C++, Scala или Java, которого вы возьмёте в свою команду, разберётся в нём буквально за месяц.

Мы заметили, что, по сравнению с другими языками программирования, гораздо проще собрать команду разработчиков на Go. И если вы нанимаете сотрудников в таких конкурентных экосистемах, как Boulder and Amsterdam, то это весомое преимущество.

7. Прочная экосистема

Для таких команд, как наша (~20 человек), экосистема важна. Вы не сможете создать ценность для своих клиентов, если придётся заново изобретать всю функциональность с нуля. В Go есть отличная поддержка используемых нами инструментов. Надёжные библиотеки уже доступны для Redis, RabbitMQ, PostgreSQL, парсинга шаблонов, задач, выражений и RocksDB.

Экосистема Go в разы лучше, чем у таких новых языков, как Rust или Elixir. Разумеется, она не так хороша, как в Java, Python или Node, но это стабильная экосистема, а для многих базовых задач уже доступны качественные пакеты.

8. Gofmt, принудительное форматирование кода

Для начала, а что такое Gofmt? И нет, это не ругательство. Gofmt — это потрясающая утилита для командной строки; она встроена в компилятор Go специально для форматирования кода. В плане функциональности она очень похожа на autopep8 для Python.

Большинство из нас вообще-то не любит спорить о табах и пробелах, что бы ни показывали в сериале «Силиконовая долина». Форматирование должно быть единообразным, а сами его стандарты не особо важны. Gofmt избавляет от всех этих дискуссий, предлагая один официальный способ по форматированию кода.

9. gRPC и буферы протокола

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

Затем из этого манифеста автоматически генерируются серверный и клиентский коды. Итоговый код получается быстрым, оставляет совсем небольшой сетевой отпечаток и крайне прост в работе. Из того же манифеста вы можете сгенерировать клиентский код для многих других языков, включая C++, Java, Python и Ruby. Так что оставьте в прошлом неоднозначные конечные точки REST для внутреннего трафика, когда вам каждый раз приходится прописывать почти один и тот же клиентский и серверный код.

1. Нехватка фреймворков

В Go нет какого-то одного главного фреймворка, как, например, Rails для Ruby, Django для Python или Laravel для PHP. Это предмет самых горячих споров в сообществе Go, поскольку многие считают, что вам вообще не нужны никакие фреймворки. В некоторых случаях я полностью с ними согласен. Но если кто-то захочет создать простой CRUD API, то гораздо удобнее сделать это на Django/DJRF, Rails Laravel или Phoenix.

Дополнение: в комментариях пишут, что есть несколько проектов, которые предоставляют фреймворк для Go. Основными фаворитами называют Revel, Iris, Echo, Macaron и Buffalo. Мы предпочли не использовать фреймворки в Stream. Но для многих новых проектов, которые нацелены на предоставление простого CRUD API, отсутствие основного фреймворка является серьёзным недочётом.

2. Обработка ошибок

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

Ещё одна проблема — можно случайно забыть обработать ошибку. Тут пригодятся инструменты статического анализа (errcheck и megacheck). Несмотря на работоспособность этих обходных решений, всё это кажется не совсем правильным. Вы ждёте, что язык будет поддерживать надлежащую обработку ошибок.

3. Управление пакетами

С момента написания этой статьи Go прошёл долгий путь в управлении пакетами. Эффективными решениями являются модули Go; их единственная проблема заключается в том, что они нарушают работу таких инструментов для статического анализа, как errcheck. Вот обучающая статья по Go и использованию модулей Go.

Управление пакетами в Go нельзя назвать идеальным. Там по умолчанию отсутствует возможность задавать конкретную версию зависимости и создавать воспроизводимые сборки. Системы управления пакетами в Python, Node и Ruby гораздо лучше. Но с правильными инструментами управление пакетами в Go работает вполне прилично.

Для управления зависимостями вы можете использовать Dep — он позволяет указывать и закреплять версии. Помимо этого, мы используем инструмент с открытым кодом под названием VirtualGo, который упрощает работу с несколькими проектами, написанными на Go.

Python или Go

Обновление: с момента написания этой статьи разница в производительности Python и Go возросла. (Go стал быстрее, а Python остался тем же). Мы провели интересный эксперимент: взяли наш функционал  ранжирования каналов на Python и переписали его в Go. Взгляните на этот пример метода ранжирования:

Для его поддержки код на Python и на Go должен делать следующее:

  1. Разбирать выражение для оценки. В данном случае мы хотим превратить эту строку "simple_gauss(time)*popularity" в функцию, которая берёт активность в качестве входного значения и возвращает оценку на выходе.

  2. Создавать частично определённые функции на основе конфигурации JSON. Например, мы хотим, чтобы "simple_gauss" вызывала "decay_gauss" со шкалой в 5 дней, смещением в 1 день и коэффициентом убывания в 0,3.

  3. Разобрать конфигурацию "defaults", чтобы у вас был резервный вариант на случай, если какое-то поле в активности не будет определено.

  4. Воспользоваться функцией из шага № 1, чтобы присвоить баллы всем активностям в канале.

Разработка Python-версии кода ранжирования заняла примерно 3 дня. Сюда вошли написание кода, модульные тесты и документация. Затем около 2 недель ушло на оптимизацию кода. Одна из оптимизаций переводила выражение оценки (simple_gauss(time)*popularity) в абстрактное синтаксическое дерево.

Кроме того, мы реализовали логику кеширования, которая предварительно вычисляла оценку для определённого времени в будущем. А разработка Go-версии кода, наоборот, заняла не более 4 дней. Дальнейшей оптимизации для работы не потребовалось. Первая часть разработки шла быстрее на Python, но в итоге версия для Go оказалась менее трудоёмкой.

Дополнительным плюсом было и то, что код Go работал примерно в 40 раз быстрее, чем наш самый хорошо оптимизированный код на Python. Это лишь один из примеров роста производительности, с которой мы столкнулись, перейдя на Go. Но, конечно же, такое сравнение — из серии «сопоставлять несопоставимое»: 

  • код ранжирования был моим первым проектом на Go;

  • код Go писался после кода на Python, так что к тому времени я лучше понимал сценарий использования;

  • библиотека Go для разбора выражений была исключительно высокого качества.

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

Elixir или Go — заслуженное серебро

Ещё один опробованный нами язык — это Elixir. Он построен поверх виртуальной машины Erlang. Это удивительный язык; мы решили к нему присмотреться, поскольку у одного члена нашей команды имелся солидный опыт работы с Erlang. В своих примерах мы заметили, что исходная производительность Go выше.

Go и Elixir отлично справляются с тысячами параллельных запросов. Однако если присмотреться к производительности отдельного запроса, то для нас Go оказался в разы быстрее.

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

Кроме того, труднее найти/обучить разработчиков на Elixir. Все эти причины склонили чашу весов в сторону Go. Тем не менее у Elixir есть просто потрясающий фреймворк Phoenix, который однозначно заслуживает внимания.

Заключение

Go — это высокопроизводительный язык с отличной поддержкой конкурентности. Он почти такой же быстрый, как C++ и Java. На разработку кода в Go уходит чуть больше времени, чем в Python или Ruby, но вы существенно экономите на оптимизации кода. У нас есть небольшая команда разработчиков в Stream, который поддерживает работу каналов и чатов для более 500 миллионов конечных пользователей.

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

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

Наш новый Chat API также полностью написан на Go. Если вы хотите узнать о языке больше, почитайте статьи из списка ниже. А если интересно познакомиться со Stream, начните с этого интерактивного урока.

Полезные ссылки

А мы поможем прокачать ваши навыки или с самого начала освоить профессию, востребованную в любое время:

Выбрать другую востребованную профессию.

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


  1. rstepanov
    07.06.2022 12:29
    +16

    Go — быстрый. Очень и очень быстрый. Его производительность близка к Java или C++.

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


    1. Cloud66
      07.06.2022 14:48
      +3

      о Java говорят конечно не в контексте десктопных приложений, говоря о производительности.


      1. rstepanov
        07.06.2022 14:53
        +3

        Да я и на бэке видел замечательные примеры вроде "запуск занимает 10-15 минут, создается 100500 потоков, системные требования - 32 Гб RAM, какой-нибудь Xeon на 20 ядер", все, что система делает, - парсит XML/JSON/ISO8583, собирает похожее сообщение и пересылает дальше + кладет в базу данные по операции.


        1. Cloud66
          07.06.2022 15:23

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


          1. iamkisly
            07.06.2022 18:35
            -1

            Может, но всю работу сделает cpp)
            Этим он напоминает Винсента из сериала "Конь БоДжек"


            1. dyadyaSerezha
              08.06.2022 00:40

              А я сначала подумал, что это почтальон Печкин. ????


    1. Hivemaster
      07.06.2022 21:32
      +2

      Не видел ни одного быстрого продукта на Java.

      Тем временем Apache Kafka, без которой не обходится ни один высоконагруженный проект, системы типа Apache Flink, в реалтайме прожёвывающие поток данных Twitter'а, упомянутые в статье биржевые системы, обрабатывающие по два миллиона транзакций в секунду - это всё работает на JVM.

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

      Да я и на бэке видел замечательные примеры вроде "запуск занимает 10-15 минут, создается 100500 потоков, системные требования - 32 Гб RAM, какой-нибудь Xeon на 20 ядер", все, что система делает, - парсит XML/JSON/ISO8583, собирает похожее сообщение и пересылает дальше + кладет в базу данные по операции.

      А я вижу замечательные примеры, как микросервис примерно 40 000 раз в секунду парсит JSON, кладёт в БД одни данные, забирает другие, собирает новый JSON, отправляет его и при этом потребляет 512 Mb оперативы.


      1. rstepanov
        07.06.2022 22:22

        Каждому java-"микросервису", поди, своя java-машина нужна?

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


        1. sergey-gornostaev
          08.06.2022 08:58
          +2

          У нас не 40k RPS, конечно, но некоторые наши микросервисы легко одним инстансом обрабатывают 1000 запросов в секунду с хипом в 512 мегабайт. Проблемы производительности в Java решаются хорошей архитектурой, правильно подобранными технологиями и качественным кодом. Как и везде, впрочем.


      1. dyadyaSerezha
        08.06.2022 00:44
        +1

        Думаю, что там везде применяются "анти-джавовские" паттерны, такие как имплемнтация реюзабельных (mutable) строк, работа без сборщика мусора и т.д.


        1. sergey-gornostaev
          08.06.2022 08:53

          Spring Reactor, Akka или Netty позволяют добиться очень высоких показателей без какого либо тюнинга сборки мусора или ухищрений со стороны кода. В LMAX своё детище Disruptor используют с отключенным сборщиком мусора, но и без этого он показывает очень хорошие результаты. В код Kafka каждый может заглянуть, вполне себе идиоматичная Scala без хаков.


  1. aktuba
    07.06.2022 12:30

    Его производительность близка к Java

    По той-же ссылке из поста: https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go.html

    дальше и читать смысла нет, наверное…


  1. gohrytt
    07.06.2022 13:52
    +4

    Статья должна была закончиться

    Короче - потому что модно


    1. aceofspades88
      07.06.2022 16:29
      +2

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


      1. gohrytt
        08.06.2022 15:43

        Я если что пишу на го) Тут больше про неинформативность статьи


  1. SergeiMinaev
    07.06.2022 15:23
    +1

    Go — быстрый. Очень и очень быстрый. Его производительность близка к Java [сегодня используется на финансовом рынке для высокочастотного трейдинга — торговли на большой скорости — прим. ред.]

    Называть быстрым язык, работающий через виртуальную машину, можно, разве что, в сравнении с Python... Она же ресурсы жрёт жуть :) Java в производительности очень уступает C/C++/Rust.

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

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

    Лично для меня Go располагается где-то посередине между Rust и Python. Хороший, по идее, вариант, если нужно выбрать какой-то один язык для бэкенда. Но для себя решил не отказываться от Python, а плюсом изучить системный Rust.

    PS: Решили в Go вопрос с дженериками? Нужны они, в итоге, или не нужны? :)


    1. rstepanov
      07.06.2022 15:31
      +1

      PS: Решили в Go вопрос с дженериками? Нужны они, в итоге, или не нужны? :)

      Они теперь есть :) Нужны или нет - сами думайте :)


    1. stranger777
      07.06.2022 15:43

      PS: Решили в Go вопрос с дженериками? Нужны они, в итоге, или не нужны? :)

      Да, их сделали. Но чуть после этой статьи в другом техноблоге вышел материал, где автор предупреждает и показывает, как дженерики Go могут замедлить код. Так что, как всегда, верно "не плодить сущности без необходимости". Я это понимаю как вопрос удобства переезда с С++ — чисто психологический. Авторы решили "просто сделать это", чтобы закрыть вопрос и как-то конкурировать с плюсами.


    1. tdemin
      07.06.2022 18:08
      +1

      1. SergeiMinaev
        07.06.2022 22:05
        +2

        Конечно, нет. Я про Java.


  1. RC_Cat
    07.06.2022 18:23
    +1

    Тем временем Python 3.11 beta показывает увеличение производительности до 60%.


    1. iamkisly
      07.06.2022 18:46
      +2

      А я, а у меня.. у меня net7 в два раза быстрее go)
      Это намек на то, что никто никогда не конкретизирует, в каком именно контексте появился импрув. Ну не может язык/фреймворк стать быстрее целиком. Всегда за подобным байтом кроется улучшение пары каких-то нишевых фич, но это не делает погоды всему сообществу.


      1. RC_Cat
        07.06.2022 19:08

        Это просто результат работы описанный тут https://habr.com/ru/post/662087/


  1. Moraiatw
    07.06.2022 18:34

    Python использовался для высоконагруженных API?


    1. niksite
      07.06.2022 22:59

      Instagram? Disqus? Достаточно высоконагружены?


      1. Moraiatw
        08.06.2022 09:56
        +1

        если они используют питон, то мне их жаль


        1. fishHook
          08.06.2022 10:22
          +3

          Вот у нас есть какой-то код, допустим, он получает некие данные и сериализует их в JSON. И у нас есть две имплементации - на Си и на чистом питоне. И, скажем, код на Си работает в 100 раз быстрее. Очевидно преимущество Си. Но это пока мы не начнем применять этот код на практике. Когда приложение 50 миллисекунд ковыряется в БД, потом сериализует ответ в JSON и отправляет на клиент, то вообще не важно займет сериализация 0.1 миллисекунду или целую миллисекунду, потому что узкое место - СУБД, и заменив питон на Си вы не получите 100-кратное увеличение производительности, вы получите только около 1,5%


          1. Moraiatw
            08.06.2022 15:12

            Ну так давайте NGINX напишем на питоне, все равно же узкое место - БД. Но почему то он написан на С.

            Кстати, БД тоже можно написать на питоне, раз уж такая пьянка )


            1. fishHook
              08.06.2022 16:20

              каким образом для NGINX узкое место - БД, потрудитесь объяснить, пожалуйста


              1. Moraiatw
                08.06.2022 21:29

                За nginx обычно стоит бекенд на каком нибудь скриптовом языке, который берет данные из БД. (Статические сайты сейчас вряд ли остались).


          1. aceofspades88
            08.06.2022 17:29

            этими 0,9 мс можно пренебречь если ваш код в день использует 3,5 землекопа, если их на порядки больше, то помимо графиков нагрузки в системах мониторинга эти "только около 1,5%" еще и на толщину вашего кошелька вполне себе повлияют.


            1. fishHook
              08.06.2022 18:15

              >Instagram? Disqus? Достаточно высоконагружены?

              Ну, вероятно, не влияют


    1. germn
      08.06.2022 11:04

      Для "высоконагруженных API" надо использовать не Python, Go или Java, а правильную архитектуру с горизонтальным скалированием и балансировщиком нагрузки.


  1. dyadyaSerezha
    08.06.2022 00:52
    +1

    Go, как и любой язык, стремится к простоте.

    Чтоо?? Если сравнить абсолютно любой язык язык версии 1.0 с текущей, то это быстрое движение в сторону сложности.


    1. stranger777
      08.06.2022 20:02

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


  1. AnthonyMikh
    08.06.2022 02:16
    +1

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


    1. stranger777
      08.06.2022 12:23
      +1

      Размер скринов мы поправили. Спасибо, что заметили.

      Если вы присмотритесь к оригиналу, то увидите, что там тоже используются скрины (причём именно того размера, который был у нас до замены), то есть кода, который можно было бы скопировать, просто нет. Видимо, автор сделал скрины из-за приватности репозитория: ссылки на gist тоже не работают.


  1. HellWalk
    08.06.2022 09:49

    Мы заметили, что, по сравнению с другими языками программирования, гораздо проще собрать команду разработчиков на Go

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

    Ещё одна проблема — можно случайно забыть обработать ошибку

    Это как еще? Чтобы проигнорировать ошибку нужно специально написать:

    result, _ := func()

    Где _ и будет обозначением игнорирования второго элемента (последним в го всегда возвращается ошибка).

    Концепция го в плане ошибок как раз нацелена на то, чтобы ошибка была обработана сразу. А не оставлена на "потом где-то в другом месте исключение обработается"


    1. Moraiatw
      08.06.2022 09:57

      В чем отличие?


    1. rustler2000
      08.06.2022 11:33

      Подозреваю что простой go vet ругаться будет на такое


  1. yakimka8
    08.06.2022 14:35

    менять местами True и False;

    Что имелось в виду?


    1. stranger777
      08.06.2022 19:33

      Думаю, речь шла о классическом трюке замены:

      >>> a = True
      >>> b = False
      >>> a, b = b, a
      >>> print(a)
      False
      >>> print(b)
      True

      Или о переопределении __bool__ , когда, например, объект класса Liar при проверке должен по определению или по умолчанию возвращать False.


  1. AirLight
    10.06.2022 01:49

    Что такое буферы протокола?


  1. lanseg
    10.06.2022 08:01

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

    Дженерики добавили - и на том спасибо.