Некоторые люди находят радость в изучении новых пешеходных маршрутов, ландшафтов и природных ландшафтов, в то время как другие предпочитают комфорт повторного посещения уже знакомых маршрутов. Эту аналогию можно удачно применить к области языков программирования.
На долгое время я глубоко погрузился в мир C++, старательно оттачивая свои навыки. Однако с началом нового проекта мне представилась возможность углубиться в область Go.
Отказ от ответственности. В этом сообщении блога не говорится о том, какой язык, Go или C++, лучше. Напротив, это наблюдение с точки зрения разработчика программного обеспечения. Я твердо верю, что оба языка играют важную роль в разработке программного обеспечения и могут гармонично сосуществовать.
Давайте сначала начнем с выяснения причин создания Go
Легенда гласит, что Go был придуман инженерами Google в минуты ожидания компиляции других программ. Разочаровавшись в существующем наборе инструментов, они приступили к фундаментальному переосмыслению системного программирования. , что привело к созданию оптимизированного и эффективно скомпилированного решения, которое превосходно справляется с обширными сценариями многопоточности, параллелизма и высокой производительности.
Go был создан для:
- масштабируемость
- параллелизм
- простота
Статья, написанная создателями, дает дополнительную информацию о зарождении Go.
Как раскрыть процесс обучения: мои моменты «Ага!»
Простота:
В то время как во многих языках основное внимание уделяется инновациям в синтаксисе, семантике или типизации, Go уделяет особое внимание улучшению самого процесса разработки программного обеспечения.
Программирование может быть сложной задачей, а решение проблем часто представляет собой еще большее препятствие. Определение оптимального решения проблемы иногда может показаться почти невозможным. В некоторых случаях языковые сложности могут усложнить решение насущной проблемы.
В проектах C++ команды могут тратить дни или даже недели на интеграцию сторонних библиотек, разработку стратегий управления памятью, реализацию пулов потоков и настройку веб-серверов с нуля. Напротив, Go предоставляет эти возможности прямо из коробки.
Go сегодня создан для разработки программного обеспечения
Хотя не все новое обязательно превосходно, язык программирования, разработанный специально для распространенной среды — масштабируемые облачные серверы, рассчитанные на высокую производительность — имеет значительные перспективы. Адаптируемость Go (системы сборки и наборы инструментов) распространяется практически на любую вычислительную платформу, что позволяет вам использовать его возможности как для создания полноценного веб-приложения, так и для создания утилиты для оптимизации задач предварительной обработки данных. Подобно Perl в период его расцвета, Go можно сравнить со швейцарским армейским ножом, хотя он избавился от накопленного лишнего и ненужного багажа, который часто портит платформы программирования, разработанные за последние несколько десятилетий.
Параллелизм — часть ДНК GoВ Go параллелизм — это основная функция, разработанная с нуля. В C++ параллелизм часто реализуется с использованием библиотек или внешних инструментов, что может привести к несогласованности и поведению, зависящему от платформы.
- Нет гонок за данными. Модель памяти Go и планировщик горутин предотвращают гонки за данными. В C++ для предотвращения гонок данных часто требуются сложные примитивы синхронизации, такие как мьютексы и блокировки.
- Низкие накладные расходы. Горутины имеют меньшие затраты памяти и выполнения по сравнению с потоками C++, что позволяет использовать тысячи одновременных горутин без значительного снижения производительности.
- Последовательная согласованность. Go предоставляет надежную модель памяти с последовательной согласованностью, что упрощает анализ поведения параллельных программ. В C++ обеспечение последовательной согласованности часто требует осторожного использования барьеров и ограждений памяти.
- Обработка ошибок.Go предлагает простой и последовательный подход к обработке ошибок с помощью нескольких возвращаемых значений, что может помочь предотвратить непредвиденное поведение, вызванное игнорированием ошибок. В C++ обработка ошибок может быть более подробной и подверженной ошибкам.
- Общение через каналы. Go поощряет общение между горутинами через каналы, что может помочь обеспечить чистое и безопасное взаимодействие между горутинами. В C++ связь между потоками часто опирается на общую память, что может привести к возникновению гонок.
- Встроенные инструменты. Go предлагает такие инструменты, как ключевое слово «go» для запуска горутин и оператор «select» для обработки операций с несколькими каналами, что упрощает сложные сценарии параллелизма. C++ требует, чтобы разработчики полагались на внешние библиотеки и механизмы для аналогичной функциональности.
- Масштабируемость.Модель параллелизма Go хорошо подходит для создания масштабируемых и высококонкурентных систем, что делает ее популярным выбором для современных облачных приложений. C++ можно использовать для аналогичных целей, но для достижения того же уровня масштабируемости может потребоваться больше усилий.
Управление памятью
- Простота. Управление памятью в Go упрощено, что снижает риск ошибок, связанных с памятью, и утечек памяти.
- Удобство параллелизма. Управление памятью в Go хорошо подходит для параллельных приложений, тогда как управление общей памятью в C++ может быть сложным.
- Безопасность и безопасность: Go помогает предотвратить распространенные уязвимости, связанные с памятью, повышая безопасность приложений.
- Простота обслуживания. Go упрощает обслуживание кода, уменьшая необходимость ручной отладки и оптимизации, связанной с памятью.
- Автоматическая сборка мусора: Go использует автоматическую сборку мусора, освобождая разработчиков от ручного выделения и освобождения памяти.
RAII
RAII (Resource Acquisition Is Initialization) — это метод программирования C++, который связывает жизненный цикл ресурсов с областью объектов, упрощая управление ресурсами и обеспечивая правильную очистку.
- Нет деструкторов. В Go отсутствуют деструкторы, которые есть в C++. Он не использует традиционный шаблон RAII, при котором ресурсы освобождаются автоматически, когда объект выходит за пределы области видимости.
- Явное управление ресурсами. В Go управление ресурсами является явным. Разработчики несут ответственность за закрытие файлов вручную, освобождение памяти и управление ресурсами с помощью функций или операторов отсрочки.
- Каналы и горутины. Модель параллелизма Go с каналами и горутинами упрощает управление ресурсами в параллельных сценариях. Каналы обеспечивают безопасное общение, а горутины управляют параллельными задачами.
- Безопасность памяти. Управление памятью в Go снижает риск утечек памяти по сравнению с C++, но может потребовать тщательной очистки ресурсов.
- Обработка ошибок.Подход Go поощряет явную обработку ошибок, гарантируя высвобождение ресурсов даже при наличии ошибок.
Подводя итог, можно сказать, что C++ в значительной степени опирается на RAII, который обеспечивает надежное управление ресурсами и безопасность исключений, но требует ручного кодирования. Go использует другой подход, делая упор на явное управление ресурсами и обработку ошибок, одновременно упрощая управление параллелизмом.
Давайте ответим на сложный вопрос: станет ли Go убийцей C++? Заменит ли он его?
Я считаю, что Go не заменит C++ полностью, но он наверняка найдет свое место в более широком спектре проектов. Некоторые специализированные области, такие как приложения операционных систем реального времени, по-прежнему будут требовать C++ из-за его особых требований и возможностей.
Вот несколько моментов, в которых C++, на мой взгляд, превосходит Go или C++ является лучшим выбором.
- Низкоуровневое системное программирование: C++ обеспечивает более детальный контроль над памятью и системными ресурсами, что делает его хорошо подходящим для задач низкоуровневого системного программирования, где необходимы прямые манипуляции с памятью.
- Среды с ограниченными ресурсами. В средах с серьезными ограничениями ресурсов, где критически важны минимизация использования памяти и оптимизация размера кода, C++ может обеспечить больший контроль над управлением ресурсами.
- Настраиваемое управление памятью. Для приложений с особыми требованиями к управлению памятью C++ позволяет разработчикам реализовывать собственные распределители памяти и детально контролировать структуру памяти.
- Взаимодействие с оборудованием. C++ обеспечивает лучшую поддержку взаимодействия с оборудованием и драйверов устройств, что делает его предпочтительным выбором для встроенных систем и аппаратного программирования. Подумайте о строках кэша: написание кода с поддержкой строк кэша на C++ позволяет вручную оптимизировать структуру памяти для уменьшения задержек, в то время как управление памятью и простота Go ограничивают возможности оптимизации низкоуровневого кэша.
- Приложения, критичные к производительности. В сценариях, где важна каждая микросекунда, C++ допускает низкоуровневую оптимизацию, которая может привести к повышению производительности по сравнению с управлением памятью со сбором мусора в Go.
- Устаревшие базы кода. Существующие базы кода C++, особенно с обширными библиотеками или зависимостями, нелегко перенести на Go. В таких случаях использование C++ может быть более практичным.
- Системы реального времени. Приложения, требующие строгих ограничений реального времени или детерминированного поведения, часто полагаются на C++ из-за его предсказуемой производительности и малой задержки. Задержки GO GC могут влиять на задержки приложений.
- Разработка игр/торговые платформы. Многие игровые движки и торговые платформы написаны на C++, и разработчики игр или торговых операций часто выбирают C++ из-за его производительности и контроля. Производительность взаимодействия с C. Разработка игр обычно включает вызов некоторых библиотек C (для OpenGL и прочего), и производительность этих вызовов может стать узким местом в интенсивной игре. Еще одним узким местом таких приложений является задержка GC.
Кто использует Go?
За последнее десятилетие Go получил широкое распространение, при этом его использование значительно возросло. Многочисленные проекты, в том числе многие инициативы с открытым исходным кодом, используют язык Go.
Go служит серверной частью для множества популярных приложений, включая Kubernetes, etcd, Twitch, Dropbox, SendGrid, Dailymotion и Uber.
https://github.com/golang/go/wiki/GoUsers
Сводка
Прошу прощения за аналогию, но мой опыт работы с базами данных и распределенными системами, естественно, влияет на мою точку зрения.
«Я вижу сходство между простотой Go и той, которую предлагают современные базы данных, платформы хранения и данных. Они направлены на решение сложных задач создания программного обеспечения, таких как масштабирование и управление распределенными системами и т. д., а также дают разработчикам возможность расставлять приоритеты в своей основной бизнес-логике. Точно так же Go упрощает многие языковые сложности, такие как параллелизм, управление памятью и масштабируемость».
Разработчики C++ привыкли думать, что умный код (я тоже виноват в этом)лучше скучного кода. Мой опыт работы с Go научил меня, что простота может быть ценной и полезной. во многих случаях более существенна.
Продолжая учиться, я с нетерпением жду возможности поделиться подробным опытом по темам, которые мы обсуждали в этом блоге.