Стоит ли изучать Golang и если да, то как — отвечают эксперты


Оглавление (нажмите, чтобы открыть):

Язык программирования Go: мнения и перспектива

Введение

Go – это язык программирования, который был разработан корпорацией Google. Часто его еще называют “Golang” – сокращение от “Google language”. Это компилируемый и многопоточный язык, релиз которого состоялся в ноябре 2009 года, а самый свежий выпуск 1.6 датируется февралем 2020 года. Одной из ключевых фигур, которые принимали участие в создании Go, является Роб Пайк, известный разработчик языков программирования, а также операционных систем, в данный момент работающий в Google. Выступая на одной из конференций, он отметил, что язык Go – это попытка перенять лучшие стороны таких языков, как C++ и Java.

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

Применение

Язык Go разрабатывался как язык для создания различных высокоэффективных программ, однако большинство программистов сходятся во мнении, что лучше всего он подходит для создания веб-приложений (в качестве back-end). При этом Go дает возможности писать и другие проекты, к примеру, Docker, InfluxDB и Kubernetes. По сути, применение языка Go ограничивается тремя основными направлениями: сетевое программное обеспечение, консольные утилиты и бэкенд.

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

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

Плюсы языка Go

У языка Go есть несколько положительных черт, выделяемых программистами, которые на нем пишут.

Во-первых, это его простота. Язык Go разрабатывался в качестве замены C: его высокая производительность почти сопоставима с языком Си, но более простой синтаксис дает возможность разрабатывать приложения гораздо быстрее (к примеру, как на Python). При этом многие разработчики изучают этот язык после Python или PHP либо используют два языка в связке (Python/Go и PHP/Go). Упрощенный синтаксис облегчает не только написание своего собственного кода, но и чтение кода, написанного другими программистами, что особенно важно в командной работе. Эта особенность Go, в свою очередь, ведет к другому важному факту: быстрое освоение Go позволяет перевести внимание с изучения самого языка на изучение программирования в целом.

Программисты постоянно сравнивают язык Go с другими языками: в его пользу свидетельствует тот факт, что, к примеру, в PHP существует 67 ключевых слов, а в Go их всего лишь 25.

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

Поэтому некоторые компании (к примеру, CrowdStrike) сознательно переходят с других языков программирования на Go для того, чтобы в дальнейшем более легко расширять пул своих разработчиков.

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

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

Нельзя не отметить и четкую направленность языка Go: в отличие от PHP, на котором пишут большие проекты, Go больше предназначен для некрупных сервисов, которые необходимо быстро написать и внедрить, но которые должны отличаться чрезвычайной надежностью (так называемое robust software).

Развертка Go-приложения также выглядит намного проще, чем развертка приложения, написанного на PHP. Программируя на Go, вы можете создать артефакты для всех операционных систем или архитектур процессора, вам не нужно будет устанавливать Go на используемые вами сервера.

Синтаксис Go может быть непривычен тем, кто до этого программировал на PHP или Python. Если рассматривать код Go в сравнении с PHP, то Go не имеет объектов или классов, зато в нем есть структура, а точнее тип, который содержит именованные поля:

Еще одной причиной, по которой Go завоевывает все большую популярность, является наличие go fmt – инструмента, который помогает стандартизировать код. А использование go vet поможет вам найти возможные проблемы в коде. Иными словами, авторы языка Go попытались максимально упросить задачу разработки приложений на этом языке, особенно для новичков.

Именно поэтому многие на данный момент считают Go одним из лучших языков программирования и советуют изучать его не только студентам, но и школьникам. Кстати, такой прецедент уже был: учитель научил несколько 11-летних школьников писать и разбираться в коде на таком уровне, что они смогли написать генератор фракталов Мандельброта. А главное, для этого ему понадобилось всего 12-13 часов!

Минусы языка Go

В качестве негативной стороны Go часто называют его малую на данный момент распространенность – действительно, есть куда более распространенные языки программирования, которые используются для выполнения большинства задач. Значит ли это, что изучать Go не стоит? Совсем нет. Существует множество корпораций, которые используют язык Go в своих разработках. В первую очередь это, конечно же, Google Inc., а также Basecamp, BBC Worldwide, Canonical, DigitalOcean, Dropbox, eBay, Yahoo и многие другие компании по всему миру. Поэтому перспективы у этого языка программирования точно есть. Безусловно, программисты Go могут быть менее востребованы, чем, к примеру, PHP-разработчики, однако и конкуренция ниже, а значит, выше шанс найти интересную и хорошо оплачиваемую работу.

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

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

Вывод

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

Почему PHP разработчики, должны изучать Golang

Go или Golang, это быстрый, масштабируемый и довольно производительный язык программирования с открытым исходным кодом, разработанный Google и поддерживаемый сообществом. Все больше и больше приложений используют его в различных реализациях. Хотя Роб Пайк сказал, что «… мы ожидали, что программисты на C ++ увидят в Go альтернативу…», но я действительно думаю, что вы, ребята, Пхпешники, должны изучать Golang! Давайте я обьясню ПОЧЕМУ.

Легок для изучения

PHP прост в изучении. Golang так же прост, как PHP!

Синтаксис PHP похож на языки программирования семейства C (C / C ++ / Java и т. Д.). Если вы уже работали с этими языками, вам будет не так уж сложно написать немного строк кода, так же, как вы когда впервые начинали писать на PHP.

Golang является языком программирования семейства си C. Эм . с небольшой разницей в синтаксисе. К примеру, ключевое слово «for» аналогично такому же ключевому слову в PHP, но без пары круглых скобок. И ключевое слово «if» также без пары скобок. Советую прочитать Effective Go для того, чтобы узнать об этом больше.

Golang имеет только 25 ключевых слов и 47 операторов, разделителей или других специальных токенов. Не нужно пытаться запомнить все литералы наизусть. А система типов вообще красива и проста в использовании. Конечно не огромная обьектно-ориентированная инфраструктура, но структурные типы с методами свободно практикуются. По-праву, дизайн интерфейса — одна из моих любимых частей Го. По окончанию вашего «Тура по Го», основываясь на опыте работы с PHP, некоторые задания можно попробовать написать на нем.

Легок в использовании

PHP-скрипты будут оцениваются компонентами SAPI: модулем веб-сервера, PHP-fpm или CLI. Все, что нужно для развертывания PHP, — это среда SAPI. А как раз таки самая сложная для понимания часть PHP для начинающего — развертывание среды.

Любой код на Го будет скомпилирован и связан с нативным кодом. Поэтому нам не нужно развертывать среду для его выполнения, кроме среды сборки. И, кстати, по сравнению с развертыванием среды PHP, она не так сложна. Вы правда считаете, что развернуть среду для PHP действительно сложно? Я так не думаю. В самом деле!

Для развертывания среды сборки достаточно проделать всего 3 шага:

  • Загрузите исходный код Голанга
  • Настройте переменные среды. Вот ссылка на пост в блоге, хорошо обьясняющий все детали: настройка среды Go
  • Запустите «all.bash» в каталоге «src».

А можно пойти другим путем: используем бинарный пакет для настройки.

Затем можно использовать набор инструментов под названием «go». Использовать инструмент go не сложнее чем, тот же инструмент CLI в PHP. «The Go Tool» — здесь вы найдете подробное объяснение использования.

Миф о PHP

Если язык программирования довольно прост в изучении и использовании, должны ли мы изучать и использовать его? Многие языки программирования просты в изучении и использовании. Должны ли мы поэтому изучить и использовать их все? Ответ прост: НЕТ!

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

PHP — это «скриптовый язык общего назначения, интенсивно применяемый для разработки веб-приложений, являющийся одним из лидеров среди языков, применяющихся для создания динамических веб-сайтов. (Википедия)». Важная особенность PHP в том, что он встраивается в код вместе с HTML. PHP код пишется в теге « »; HTML пишется снаружи от тега. Язык, кроме того, имеет мощную систему расширения. Расширение можно написать даже на C с помощью Zend API. Фактически, обработку данных реализовали благодаря этим расширениям. ИМХО, PHP должен быть лучшим шаблонным языком программирования.

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

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

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

Пхпешники всегда ищут решения, вроде «многопоточность PHP» или параллельная среда RPC для PHP. Я не могу сказать, какая из них лучше. Но, я уверен, что для бэкэнда вам следует воспользоваться другим языком программирования. Я сам пробовал C (борьба с malloc / free) / Java (оступился и попал в ад jar) / Python (никогда не поддерживал его и терял типы ). Получаю больше производительности, должен бороться с управлением памятью; Если я использую GC, я должен развернуть и запустить виртуальную машину; Если мне станет удобно, неусидчивость меня погубит… У каждого языка есть свои преимущества и недостатки.

Ну да ладно! Давайте пока вернемся к Го!

Golang имеет GC, тем самым у нас нет необходимости заботиться об управлении памятью (или этому нужно уделять меньше внимания). И код компилируется в машинный код. Поэтому, «cp» и «mv» необходимы для развертывания приложения, написанного Golang. И как я только что говорил, Golang — это компилируемый язык со статической системой типов. Так что у вас нет шансов перепутать типы переменных. Конечно, одна из самых важных вещей — это PHPer, который переезжает и в Голанг, «не так уж выразительно, но можно улучшить производительность и играть с параллелизмом (Роб Пайк)». «Почему бы не использовать GO?» серьезно заявлял он.

Давайте я расскажу немного о собственном опыте в моей команде: мы используем Gearman для обработки данных бэкэнда. Мы подключили и настроили PHP через Gearman Job Server с помощью Gearman API. Оригинальный обьект worker был написан на python. С этой версией довольно много проблем (проблемы то наши, но из-за питона).

Но у нас работало и ладно . А потом мы решили переписать обьект worker на Го. И это было прекрасно. Я написал Gearman API для Golang и пакет Golang с использованием Zend API (cgo — еще одна удивительная вещь) для оценки PHP-скрипта в Golang. Затем объединили их вместе — обьект worker Gearman, который может выполнять сценарии PHP. Он уже около 3 месяцев у нас в продакшене и выглядит великолепно! И я также написал RPC-комбинатор для объединения вызовов RPC в PHP-скрипте. Будем использовать его в нашем следующем продукте.

Все идет по-плану, без споев! Спасибо Golang!

В любом случае, большинству PHP-разработчикам всегда нужно повышать свой уровень и изучать другие языки бэкэнд-разработки. Если вы начали для себя поиски нового языка или уже рьяно запрограммировали что то, почему бы вам не попробовать Голанг? Он сделает вашу жизнь немного легче и счастливее, и вы сможете больше времени проводить с семьей и друзьями, кушать любимую еду и посещать места, которые вы любите.

Вот почему вы, ребята, Пхпешники, должны изучать Голанг! Достаточно этих фактов? Я думаю, да!

Язык Go — зачем он нужен и что на нем пишут? [закрыт]

Этот язык уже несколько лет в поле видимости.

  • Но что на нем пишут?
  • И что можно написать?
  • Стоит ли его учить?
  • Или он скоро исчезнет?

Закрыт по причине того, что необходимо переформулировать вопрос так, чтобы можно было дать объективно верный ответ участниками Kromster says support Monica, ermak0ff, Streletz, PashaPash, Max Mikheyenko 13 ноя ’15 в 17:51 .

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

5 ответов 5

И что можно написать?

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

Вопрос риторический. С точки зрения покупаемости, готовый спрос на него почти отсутствует, в силу молодости и нераскрученности. Так что смысл в нём есть:

  1. Для себя, своего стартапа
  2. Продавать готовый продукт
  3. Выполнить заказ, если заказчику подходят плюсы этого языка (придётся объяснять/убеждать)

Как уже писали — исчезнуть он не может, т.к. OpenSource. Т.е. никто не отберёт у Вас написанное на нём, максимум будет ухудшаться развитие/поддержка, во что слабо верится, т.к у языка очень существенные плюсы.

Плюсы или «почему я выбрал Go»

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

По производительности для веб (готовые фреймворки) Go проигрывает только Java и С/С++ и наравне с node.js. При этом потребление ресурсов существенно ниже, чем у Java и производительность намного больше, чем у Python/Ruby.

Многопоточность

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

Простота

Он очень прост в освоении. Мне кажется даже элементарен, особенно если есть основа из Python/JavaScript. Есть также довольно занятная модель наследования, которая, как мне кажется более прозрачна чем классическое ООП, но немного непривычна поначалу.

Надёжность

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

Скорость компиляции

И, наконец, одна из главнейших фишек — не стоит бояться типизации и компиляции. В 145% случаев Вам не придётся объявлять тип переменой в коде — он задаётся автоматически при присвоении ей значения. Объявлять переменные заранее также не нужно.

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

Итого

Т.е. мы имеем плюсы из двух миров — скорость компиляции/запуска интерпретируемого и надёжность компилируемого языков. Плюc сверху производительность, мультипарадигменность (можно писать в функциональном стиле), простота и низкое ресурсопотребление.

Подходит ли это Вам — решать не мне. Мне — подходит, и я считаю его очень хорошим выбором для высоконагруженных сервисов (и не только).

Стоит ли изучать Golang и если да, то как — отвечают эксперты

7’157 подписчиков
3’625 просмотров на пост

Фронтенд, бэкенд, девопс. Пишем сами и агрегируем лучший контент из сети.

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

Детальная рекламная статистика будет доступна после прохождения простой процедуры регистрации

  • Детальная аналитика 70’046 каналов
  • Доступ к 28’004’146 рекламных постов
  • Поиск по 112’332’059 постам
  • Отдача с каждой купленной рекламы
  • Графики динамики изменения показателей канала
  • Где и как размещался канал
  • Детальная статистика по подпискам и отпискам

Найдено 386 постов

10 советов для тех, кто разрабатывает на React

Например, там вы найдёте рекомендации по использованию хуков, Context API, styled-components, фрагментов, Typescript: https://bit.ly/34BHB2d

Также читайте: 10 советов по использованию Vue.js

Подборка фронтенд-проектов для практики. Вторая часть.

— Блог на Gatsby. Gatsby — генератор статических сайтов, использующий React и GraphQL. Интересная альтернатива WordPress: https://tprg.ru/H4Gt

— Блог на Gridsome. Похож на Gatsby, вместо React использует Vue.js: https://tprg.ru/jlpB

— Аудио плеер на Quasar, похожий на SoundCloud. Этот проект покажет, как создать мобильное приложение с использованием Vue и фреймворка Quasar: https://tprg.ru/pkyh

— To-Do приложение на Svelte. Просто хороший гайд по созданию приложения с помощью Svelte 3 от начала до конца: https://tprg.ru/eOw1

Также читайте первую часть подборки.

Сайт, на котором собраны огромные планы по изучению фронтенда, бэкенда и девопса: https://roadmap.sh/

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

#фронтенд #бэкенд #devops

Атака HTTP request smuggling

HTTP request smuggling — это атака, при которой злоумышленник вмешивается в обработку последовательности HTTP-запросов, которую получает веб-приложение.

В статье разбираемся с этой атакой:
— что происходит во время атаки;
— какие уязвимости позволяют её выполнить;
— и как её предотвратить.

Читайте на сайте: https://tproger.ru/translations/http-request-smuggling/

Руководство, в котором детально разбирается ООП в контексте JavaScript


— объекты, свойства, методы, классы;
— инкапсуляция, абстракция, наследование, полиморфизм;
— агрегирование и композиция.

Подборка фронтенд-проектов для практики. Первая часть.

— Чат на Vue. Вы научитесь создавать компоненты, обрабатывать состояния, создавать маршруты, подключаться к сторонним сервисам и обрабатывать аутентификацию: https://tprg.ru/8Xpo

— Приложение для просмотра погоды на Angular 8. В проекте будут использоваться Firebase, рендеринг на стороне сервера, Flexbox: https://tprg.ru/mrN7

— Приложение для электронной коммерции на Next.js. В этом проекте вы узнаете, как создавать новые страницы и компоненты, извлекать данные, а также стилизовать и развёртывать приложение Next: https://tprg.ru/Pbk7

— Приложение для поиска фильмов на React с использованием API Hooks: https://tprg.ru/npzi

— Мультиязычный блог на Nuxt.js. В проекте вы будете использовать Storyblock-модуль, миксины, Vuex для управления состоянием: https://tprg.ru/zAuM

Типичный программист
: 59200 | на пост: 15306 | ER: 25.9%
Публикации Упоминания Аналитика

​​Прямо сейчас в Сколково проходит масштабная конференция по хайлоаду — HighLoad++ 2020. В программе больше 100 докладов и митапов, так что будет просто целая куча интересных выступлений!

Присоединяйтесь и смотрите топовые доклады по высоконагруженным системам и веб-разработке от известных специалистов, не отходя от экрана:
https://tprg.ru/Jozx

Руководство по основам безопасности Docker

Охватывает 3 основные категории:

— Если ваша ОС небезопасна, то и Docker не может быть в безопасности. Шаги, которые необходимо предпринять, чтобы обезопасить ОС при взаимодействии с Docker;

— Инструкции по сборке файла конфигурации и созданию контейнеров;

— Нюансы безопасности при работе со специфическими фичами Docker Enterprise.

Бесплатные хакатоны для разработчиков

Пройдут в эти выходные, 9–10 ноября, в Москве и Санкт-Петербурге:

— В Москве пройдёт Hack.Genesis, на котором предложат решить одну из трёх задач и побороться за призовой фонд в 300 000 ₽. Также там будут работать образовательные интенсивы. Подробности: https://tproger.ru/events/hack-genesis/

Мастер Йода рекомендует:  Цукерберг создаст управдома с искусственным интеллектом

— В Санкт-Петербурге состоится Baltic Sea Hack. Будут представлены задачи из совершенно разных сфер: туризм, экология, помощь людям с ограничениями. Призовой фонд — 500 000 ₽. Подробности: https://tproger.ru/events/baltic-sea-hack/

10 советов по эффективному использованию фреймворка Vue.js: https://bit.ly/32QPQqJ

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

Читайте руководство по созданию веб-приложения, которое с помощью библиотеки face-api.js по фотографии человека определит его эмоции, пол и возраст: https://tprg.ru/Ky7j

Разработка веб-серверов на Go

Стандартная библиотека языка Go включает в себя много полезных компонентов «из коробки», с помощью которых можно легко разрабатывать серверные приложения.

В статье читайте, как написать веб-сервер на Go, начиная с базового «Hello World!» и заканчивая приложением, выполняющим следующие функции:
— использует Let’s Encrypt для HTTPS;
— выполняет маршрутизацию запросов к API;
— реализует промежуточную обработку запросов;
— раздаёт статические файлы;
— корректно завершает свою работу.

Читать статью: https://tproger.ru/translations/go-web-server/

Если вы хотите сразу увидеть готовый код, то заходите на GitHub: https://github.com/jordan-wright/http-boilerplate

Подробный гайд по оптимизации картинок для вашего сайта: https://bit.ly/2JxXSgp

Webpack на практике: с нуля до создания автотестов

Webpack создаёт граф зависимостей для JavaScript, CSS и прочих, выдавая однофайловые сборки кода так, чтобы вы могли импортировать все необходимые ресурсы JavaScript всего одним тегом script.

В этом руководстве рассказываем, как создать сборку для небольшого веб-приложения, а затем научим вас использовать Webpack для настройки автоматических тестов: https://tproger.ru/translations/webpack-from-zero-to-hero/

Также читайте: 5 плагинов для Webpack

Composition API во Vue 3

На нашем сайте появилась подробная текстовая расшифровка доклада с митапа по Vue.js: https://tproger.ru/video/composition-api-in-vue/

В этом докладе спикер рассказал про Composition API во Vue 3:
— зачем он вообще нужен;
— какие проблемы он решает;
— сравнение Options API и Composition API на примере простой игры;
— его плюсы и минусы;
— как с его помощью писать понятные, тестируемые и независимые компоненты.

20 React-инструментов, которые помогут повысить продуктивность вашей работы: https://tprg.ru/qpfn

Например, обратите внимание на Reactide — IDE для React.js. В этой IDE встроен Node.js сервер и браузер, поэтому все изменения в коде сразу будут отображаться в IDE.

#фронтенд #react #инструменты

Руководство по созданию приложения с помощью Django, Docker и PostgreSQL: https://tprg.ru/5Bo8

#фронтенд #бэкенд #docker #django #postgresql

Банковская карточка с приятной анимацией: https://codepen.io/JavaScriptJunkie/pen/YzzNGeR

Читайте историю про то, как девушка хотела научиться анимационному дизайну на CSS и поставила перед собой челлендж «25 дней CSS»: https://bit.ly/2MS45WC

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

[golang-ru] Стоит ли изучать golang и его будущее

Идея о том, что Go подойдет почти везде, где используется Erlang,
основана на обычном наблюдении:

Сплошные WebSocket/Comet-фреймворки.
Что еще на слуху? RabbitMQ, Riak, Ejabberd, CouchDB.

На самом деле вы упускаете простой момент: на гитхабе вы видите лишь
ограниченный объём софта.

Вы не увидите там бекенд какого-нибудь островка.

На CouchDB я бы не стал обращать внимание. Кац мягко говоря неоднозначный
программист.


Вы получили это сообщение, поскольку подписаны на группу GoLang Russian.

Малоизвестные преимущества Go: почему стоит выучить этот язык и с чего начать

Язык программирования Golang разработали в Google ещё в 2009 году, но стремительно набирать популярность начал только в последние годы. Разработчик Кирилл Роговой в своём блоге рассмотрел некоторые важные особенности Go. Материал доступен даже тем, кто не имеет опыта работы с Go, а в конце статьи можно найти ссылки на полезные ресурсы, которые помогут поближе познакомиться с этим языком.

GoDoc

Документации в Go — как и простоте — уделяется особое внимание. GoDoc — это инструмент статического анализа, который автоматически генерирует документацию из кода. В отличие от JavaDoc, PHPDoc или JSDoc, в GoDoc примечательно то, что для аннотирования инструмент использует исключительно английский язык.

GoDoc извлекает максимум информации из кода, чтобы структурировать и форматировать документацию. Она будет содержать всё необходимые «фишки» вроде перекрёстных ссылок, примеров кода и прямых ссылок на репозиторий системы управления версиями. Любой комментарий автоматически отражается в документации. Можно также добавлять фрагменты кода и их запускать прямо в браузере или локально.

GoDoc — единственный инструмент создания документации, который использует всё сообщество: документация для всех библиотек и приложений на Go имеет один формат, что помогает сберечь массу времени на её изучение.

Статический анализ кода

Значительное место в Go отведено статическому анализу. Подтверждение этому — такие инструменты, как godoc для создания документации, gofmt для форматирования кода, golint для его анализа и выявления возможных ошибок и многие другие. Все они объединены в единую утилиту контроля качества GoMetaLinter, которая запускает параллельно все анализаторы кода. Эти инструменты запускаются и как отдельные приложения командной строки и легко интегрируются с любой средой разработки.

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

Встроенная среда тестирования

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

Чтобы запустить тестирование, достаточно выполнить команду go test. Инструмент позволяет выполнять тесты параллельно, пропускать их, и много чего другого.

Обнаружение состояний гонки

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

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

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

Доступность

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

Go значительно проще освоить, чем Java, Javascript, Ruby, Python или даже PHP. Среду разработки достаточно легко настроить, а от команды понадобится намного меньше усилий для создания готового кода.

Рефлексия

Рефлексия — это способность добраться до различного рода метаинформации о таких конструкциях языка, как переменные или функции. Так как Go — статически типизированный язык, он имеет некоторые ограничения в плане обобщённого программирования, особенно в сравнении с динамическими Javascript или Python.

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

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

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

Ограничения

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

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

Культура

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

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

И Go в этом контексте — ценное приобретение. Код, созданный на нём, должен быть простым и понятным, без излишних абстракций и с акцентом на удобство в сопровождении. Go создан для того, чтобы сфокусироваться непосредственно на написании кода и не отвлекаться на подбор инструментов и настройку окружения. В нём «должен быть только один способ написать код».

Полезные ресурсы

Интерактивный тур по Go, с которого можно начать знакомство с языком.

Более подробно о преимуществах Go – в блогах на Medium:

Golang

Блог о языке программирования Go

среда, 6 ноября 2020 г.

Паттерны в Golang: Fan-In

Fan-In — это паттерн обмена сообщениями, используемый для создания воронки для работы среди исполнителей. Источником сообщений могут быть клиенты, а место назначения — сервер.

Мы можем смоделировать Fan-In паттерн используя каналы Go.

Функция `Merge` преобразует список каналов в один канал, запуская goroutine для каждого входящего канала, которая копирует значения в единственный исходящий канал.

Как только все send goroutine были запущены, запускается отдельная goroutine с функцией, ожидающей завершения всех запущенных, чтобы закрыть основной канал.

понедельник, 4 ноября 2020 г.

Golang в Google: дизайн языка на службе разработки программ, часть 5

14. Композиция, а не наследование

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

Вместо этого у Go есть интерфейсы, идея, которая далее кратко описана.

В Go интерфейс — это просто набор методов. Например, вот определение интерфейса Hash из стандартной библиотеки.

Все типы данных, которые реализуют эти методы, неявно удовлетворяют этому интерфейсу; нет implements декларации. Тем не менее, удовлетворенность интерфейса статически проверяется во время компиляции, поэтому отвязывающие (decoupling) интерфейсы безопасны для типов.

Тип обычно удовлетворяет многим интерфейсам, каждый из которых соответствует подмножеству своих методов. Например, любой тип, который удовлетворяет интерфейсу Hash, также удовлетворяет интерфейсу Writer:

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

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

Одним из крайних примеров является ядро ​​Plan 9, в котором все элементы данных системы реализованы точно в одном интерфейсе, API файловой системы, определенный 14 методами. Это единообразие допускало уровень композиции объектов, редко достигаемый в других системах, даже сегодня. Примеров предостаточно. Вот один из них: система может импортировать (в терминологии Plan 9) стек TCP на компьютер, который не имеет TCP или даже Ethernet, и через эту сеть подключиться к машине с другой архитектурой процессора, импортировать свое дерево /proc и запустить локальный отладчик для отладки точки останова удаленного процесса. Такая операция была обычным делом для Plan 9, ничего особенного. Способность делать такие вещи выпала из дизайна; это не требовало особой договоренности (и все было сделано на простом C).

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

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

Рассмотрим интерфейс Writer, показанный выше, который определен в пакете io: любой элемент, имеющий метод Write с этой сигнатурой, хорошо работает с дополнительным интерфейсом Reader:

Эти два взаимодополняющих метода позволяют создавать безопасные цепочки с богатым поведением, как обобщенные каналы Unix. Файлы, буферы, сети, шифраторы, компрессоры, кодировщики изображений и т.д. Могут быть соединены вместе. Процедура ввода-вывода в формате Fprintf использует io.Writer, а не, как в C, FILE*. Отформатированный принтер не знает, о чем пишет; это может быть кодировщик изображения, который, в свою очередь, пишет в компрессор, который, в свою очередь, пишет в шифратор, который, в свою очередь, пишет в сетевое соединение.

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

Также обратите внимание, что устранение иерархии типов также устраняет форму иерархии зависимостей. Удовлетворение интерфейса позволяет программе расти органично без заранее определенных контрактов. И это линейная форма роста; изменение интерфейса влияет только на непосредственных клиентов этого интерфейса; нет поддерева для обновления. Отсутствие implements деклараций беспокоит некоторых людей, но позволяет программам расти естественно, изящно и безопасно.

Интерфейсы Go оказывают большое влияние на дизайн программы. Мы видим это в одном месте — использование функций, которые принимают аргументы интерфейса. Это не методы, это функции. Некоторые примеры должны иллюстрировать их силу. ReadAll возвращает срез байтов (массив), содержащий все данные, которые можно прочитать из io.Reader:

Оболочки (wrappers) — функции, которые принимают интерфейс и возвращают интерфейс — также широко распространены. Вот несколько прототипов. LoggingReader регистрирует каждый вызов Read на входящем Reader. LimitingReader прекращает чтение после n байтов. ErrorInjector помогает тестировать, имитируя ошибки ввода/вывода. И еще много других.

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

15. Ошибки

Go не имеет средств исключений в общепринятом смысле, то есть нет структуры управления, связанной с обработкой ошибок. (Go предоставляет механизмы для обработки исключительных ситуаций, таких как деление на ноль. Пара встроенных функций, называемых panic и recover, позволяет программисту защищаться от таких вещей. Однако эти функции намеренно неуклюжи, редко используются и не интегрированы в библиотеки так, как, скажем, исключения интегрированы в библиотеки Java.)

Ключевой особенностью языка для обработки ошибок является предопределенный тип интерфейса, называемый error, который представляет значение, которое имеет метод Error, возвращающий строку:

Библиотеки используют тип error, чтобы вернуть описание ошибки. В сочетании с возможностью для функций возвращать несколько значений, легко вернуть вычисленный результат вместе со значением ошибки, если оно есть. Например, эквивалентный getchar в C не возвращает внеполосное значение в EOF и не генерирует исключение; он просто возвращает значение ошибки рядом с символом, при этом нулевое значение ошибки означает успех. Вот сигнатура метода ReadByte типа bufio.Reader буферизованного пакета ввода-вывода:


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

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

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

Кроме того, если ошибки используют специальные структуры управления, обработка ошибок искажает поток управления для программы, которая обрабатывает ошибки. Java-стиль блоков try-catch-finally чередует несколько перекрывающихся потоков управления, которые взаимодействуют сложным образом. Несмотря на то, что Go, напротив, делает более подробным проверку ошибок, явный дизайн обеспечивает прямой контроль над процессом — буквально.

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

16. Инструменты

Программная инженерия требует инструментов. Каждый язык работает в среде с другими языками и множеством инструментов для компиляции, редактирования, отладки, профилирования, тестирования и запуска программ.

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

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

Наиболее известным из них является gofmt, форматировщик исходного кода Go. С самого начала проекта мы планировали форматировать программы Go на компьютере, исключая целый класс споров между программистами: как мне выложить свой код? Gofmt запускается на всех программах Go, которые мы пишем, и большая часть сообщества с открытым исходным кодом также использует его. Он запускается как «предварительная проверка» для репозиториев кода, чтобы удостовериться, что все отмеченные в Go программы отформатированы одинаково.

Пользователи часто называют Gofmt одной из лучших функций Go, хотя она не является частью языка. Существование и использование gofmt означает, что с самого начала сообщество всегда рассматривало код Go как формат gofmt, поэтому программы Go имеют единый стиль, который теперь знаком всем. Единое представление делает код легче для чтения и, следовательно, ускоряет работу. Время, не затраченное на форматирование, сэкономлено. Gofmt также влияет на масштабируемость: поскольку весь код выглядит одинаково, командам легче работать вместе или с кодом других команд.

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

Первым примером был флаг -r (rewrite) на самом gofmt, который использует простой язык сопоставления с образцом для включения перезаписей на уровне выражения. Например, однажды мы ввели значение по умолчанию для правой части выражения среза: сама длина. Все исходное дерево Go было обновлено, чтобы использовать это значение по умолчанию с помощью одной команды:

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

Подобный, но более сложный процесс позволил использовать gofmt для обновления дерева, когда язык больше не требовал точек с запятой в качестве завершителей операторов, если оператор заканчивался символом новой строки.

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

Обратите внимание, что эти инструменты позволяют нам обновлять код, даже если старый код все еще работает. В результате, репозитории Go легко обновляются по мере развития библиотек. Старые API могут быть устаревшими быстро и автоматически, поэтому необходимо поддерживать только одну версию API. Например, мы недавно изменили реализацию буфера протокола Go, чтобы использовать функции «getter», которых раньше не было в интерфейсе. Мы запустили gofix для всего кода Go в Google, чтобы обновить все программы, использующие буферы протокола, и теперь используется только одна версия API. Подобные радикальные изменения в библиотеках C++ или Java практически невозможны в масштабах кодовой базы Google.

Наличие пакета синтаксического анализа в стандартной библиотеке Go также позволило использовать ряд других инструментов. Примеры включают инструмент go, который управляет построением программы, включая получение пакетов из удаленных репозиториев; программа извлечения документов godoc, программа для проверки соблюдения соглашения о совместимости API при обновлении библиотеки и многое другое.

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

Заключение

Использование Go растет внутри Google.

Его используют несколько крупных пользовательских служб, в том числе youtube.com и dl.google.com (сервер загрузки, который обеспечивает загрузку Chrome, Android и других загрузок), а также наш собственный golang.org. И, конечно же, многие маленькие делают это, в основном, с использованием встроенной поддержки Google App Engine для Go.

Многие другие компании также используют Go; список очень длинный, но некоторые из наиболее известных:

Похоже, что Go достигает своих целей. Тем не менее, еще рано говорить об успехе. У нас пока нет достаточного опыта, особенно с большими программами (миллионы строк кода), чтобы узнать, окупились ли попытки построить масштабируемый язык. Хотя все показатели положительные.

В меньшем масштабе некоторые незначительные вещи не совсем верны и могут быть изменены в более поздней (Go 2?) версии языка. Например, существует слишком много форм синтаксиса объявления переменных, программисты легко путаются с поведением нулевых значений внутри ненулевых интерфейсов, и есть много деталей библиотеки и интерфейса, которые могут использовать другой раунд проектирования.

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

Однако не все было исправлено. Мы все еще учимся (но язык пока зафиксирован).

Существенным недостатком языка является то, что реализация все еще нуждается в работе. Сгенерированный код компилятора и производительность среды выполнения, в частности, должны быть лучше, и работа над ними продолжается. Уже есть прогресс; на самом деле, некоторые тесты показывают удвоение производительности в версии для разработчиков сегодня (конец 2012 года) по сравнению с первым выпуском Go версии 1 в начале 2012 года.

Резюме

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

Свойства, которые привели к этому, включают:

  • ясные зависимости
  • ясный синтаксис
  • ясная семантика
  • композиция, а не наследование
  • простота, обеспечиваемая моделью программирования (сборка мусора, конкурентность)
  • легкие инструменты (инструмент go, gofmt, godoc, gofix)
Мастер Йода рекомендует:  Раскрывающийся список в HTML тег select

Если вы еще не попробовали Go, мы советуем вам это сделать.

Golang в Google: дизайн языка на службе разработки программ, часть 4

12. Конкурентность

Конкурентность важна для современной вычислительной среды с ее многоядерными машинами, на которых работают веб-серверы с несколькими клиентами, что можно назвать типичной программой Google. Этот вид программного обеспечения не особенно хорошо обслуживается C++ или Java, которым не хватает достаточной поддержки конкурентности на уровне языка.

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

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

Получившийся язык позволяет нам плавно соединить конкурентность с вычислениями. Рассмотрим веб-сервер, который должен проверять сертификаты безопасности для каждого входящего вызова клиента; в Go легко сконструировать программное обеспечение, используя CSP для управления клиентами как независимо выполняемыми процедурами, но при этом использовать все возможности эффективного компилируемого языка, доступного для дорогостоящих криптографических вычислений.

Таким образом, CSP является практичным для Go и для Google. При написании веб-сервера, канонической программы Go, модель отлично подходит.

Есть одно важное предостережение: Go не является полностью безопасным для памяти при наличии конкурентности. Совместное использование разрешено, а указатель на канал является идиоматическим (и эффективным).

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

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

13. Сборка мусора

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

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

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

Язык намного проще в использовании из-за сборки мусора.

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

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

Ключевым моментом является то, что Go предоставляет программисту инструменты для ограничения выделения путем управления макетом структур данных. Рассмотрим определение простого типа структуры данных, содержащей буфер (массив) байтов:

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

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

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

Чтобы дать программисту такую ​​гибкость, Go должен поддерживать то, что мы называем внутренними указателями на объекты, расположенные в куче. Поле X.buf в приведенном выше примере находится внутри структуры, но допустимо захватить адрес этого внутреннего поля, например, чтобы передать его в процедуру ввода-вывода. В Java, как и во многих языках со сборщиком мусора, невозможно создать внутренний указатель, подобный этому, но в Go это идиоматично. Эта точка проектирования влияет на то, какие алгоритмы сбора данных можно использовать, и может усложнить их, но после тщательного обдумывания мы решили, что необходимо разрешить внутренние указатели из-за преимуществ для программиста и способности снизить нагрузку (возможно, сложнее реализовать) на сборщик. Пока что наш опыт сравнения похожих программ на Go и Java показывает, что использование внутренних указателей может оказать существенное влияние на общий размер арены, задержку и время сбора.

Таким образом, Go является языком со сборщиком мусора, но дает программисту некоторые инструменты для управления издержками сбора.

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

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

Продолжение, начало в части 1 и части 2.

9. Синтаксис

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

Таким образом, Go был разработан с ясностью и удобством и имеет чистый синтаксис. По сравнению с другими языками в семействе C его грамматика скромна по размеру: всего 25 ключевых слов (C99 — 37; C++ 11 — 84; цифры продолжают расти). Что еще более важно, грамматика является правильной и поэтому легко разбирается (в основном; есть несколько причуд, которые мы могли бы исправить, но не обнаружили достаточно рано). В отличие от C и Java и особенно C++, Go может быть проанализирован без информации о типе или таблицы символов; нет конкретного типа контекста. Грамматику легко разъяснить, и поэтому инструменты легко писать.

Одна из деталей синтаксиса Go, которая удивляет программистов на С, заключается в том, что синтаксис объявления ближе к Паскалю, чем к С. Объявленное имя появляется перед типом, и есть еще ключевые слова:

по сравнению с C

Объявления, введенные с помощью ключевого слова, легче анализировать как для людей, так и для компьютеров, и синтаксис типа, не являющийся синтаксисом выражения, как в C, оказывает значительное влияние на синтаксический анализ: он добавляет грамматику, но устраняет неоднозначность. Но есть и хороший побочный эффект: для инициализации объявлений можно удалить ключевое слово var и просто взять тип переменной из выражения. Эти два объявления эквивалентны; второе короче и идиоматичнее:

Синтаксис функции прост для простых функций. В этом примере объявляется функция Abs, которая принимает одну переменную x типа T и возвращает единственное значение float64:

Метод — это просто функция со специальным параметром, его получателем, который можно передать функции, используя стандартную запись «точка». Синтаксис объявления метода помещает получателя в скобки перед именем функции. Вот та же самая функция, теперь как метод типа T:

А вот переменная (замыкание) с аргументом типа T; Go имеет функции первого класса и замыкания:

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

Мы поговорим об ошибках позже.

В Go есть одна особенность — он ​​не поддерживает аргументы функций по умолчанию. Это было намеренное упрощение. Опыт подсказывает нам, что аргументы по умолчанию позволяют слишком легко исправлять недостатки проектирования API, добавляя больше аргументов, что приводит к слишком большому количеству аргументов с взаимодействиями, которые трудно распутать или даже понять. Отсутствие аргументов по умолчанию требует определения большего количества функций или методов, так как одна функция не может содержать весь интерфейс, но это приводит к более ясному API, который легче понять. Все эти функции также нуждаются в отдельных именах, что проясняет, какие комбинации существуют, а также стимулирует к большему размышлению о наименовании, критическом аспекте ясности и читабельности.

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

10. Именование

Go использует необычный подход к определению видимости идентификатора, возможность для клиента пакета использовать элемент, названный идентификатором. В отличие, например, от private и public ключевых слов, в Go само имя содержит информацию: регистр начальной буквы идентификатора определяет видимость. Если начальный символ является заглавной буквой, идентификатор экспортируется (общедоступный); в противном случае это не так:

  • заглавная буква: Name видно клиентам пакета
  • в противном случае: name (или _Name) не видно клиентам пакета

Это правило распространяется на переменные, типы, функции, методы, константы, поля — на все. Это все, что нужно сделать.

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

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

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

  • всеобъемлящая (universe) (предварительно объявленные идентификаторы, такие как int и string)
  • пакет (все исходные файлы пакета находятся в одной области видимости)
  • файл (только для импорта пакетов переименовывает; на практике это не очень важно)
  • функция (обычная)
  • блок (обычный)

Нет пространства для пространства имен, класса или другой оберточной конструкции. Имена происходят из очень немногих мест в Go, и все имена соответствуют одной и той же иерархии областей видимости: в любом заданном месте в исходном коде идентификатор обозначает ровно один языковой объект, независимо от того, как он используется. (Единственное исключение — метки утверждений, цели утверждений break и т.п.; они всегда имеют область видимость функции.)

Это имеет последствия для ясности. Обратите внимание, например, что методы объявляют явного получателя и что он должен использоваться для доступа к полям и методам типа. Там нет неявного this. То есть всегда пишут

(где rcvr — это любое имя, выбранное для переменной-получателя), поэтому все элементы типа всегда отображаются лексически связанными со значением типа-получателя. Точно так же квалификатор пакета всегда присутствует для импортированных имен; всегда пишут io.Reader, а не Reader. Это не только ясно, но и освобождает идентификатор Reader как полезное имя для использования в любом пакете. На самом деле в стандартной библиотеке есть несколько экспортируемых идентификаторов с именем Reader или Printf, но какой из них упоминается, всегда однозначно.

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

Кратко, имена локальные. В C, C++ или Java имя y может относиться к чему угодно. В Go y (или даже Y) всегда определяется внутри пакета, в то время как интерпретация x.Y ясна: найдите x локально, Y принадлежит ему.

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

Следует упомянуть еще один аспект именования: поиск метода всегда осуществляется только по имени, а не по сигнатуре (типу) метода. Другими словами, у одного типа никогда не может быть двух методов с одинаковым именем. Учитывая метод x.M, существует только один M, связанный с x. Опять же, это позволяет легко определить, к какому методу относится только имя. Это также упрощает реализацию вызова метода.

11. Семантика

Семантика операторов Go обычно C-подобна. Это компилируемый, статически типизированный, процедурный язык с указателями и так далее. По замыслу он должен чувствовать себя знакомым программистам, привыкшим к языкам в семействе С. При запуске нового языка важно, чтобы целевая аудитория могла быстро его выучить; укоренение Go в семействе C помогает молодым программистам, большинство из которых знают Java, JavaScript и, возможно, C, находить Go легким в освоении.

Тем не менее, Go вносит много небольших изменений в семантику C, в основном для обеспечения надежности. Они включают:

  • нет арифметики указателей
  • нет неявных числовых преобразований
  • границы массива всегда проверяются
  • нет псевдонимов типов (после типа X int, X и int являются разными типами, а не псевдонимами)
  • ++ и — являются утверждениями, а не выражениями
  • присваивание не является выражением
  • законно (даже рекомендуется) брать адрес стековой переменной
  • и многое другое

Существуют и более значительные изменения, далеко идущие от традиционных моделей C, C++ и даже Java. К ним относятся лингвистическая поддержка для:

  • конкурентности
  • сборки мусора
  • типов интерфейсов
  • отражения (reflection)
  • переключателей типа

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

Golang в Google: дизайн языка на службе разработки программ, часть 2

Продолжение, начало в части 1

5. Ввод Go

Когда сборки идут медленно, есть время подумать. Миф о происхождении Go гласит, что именно во время одной из этих 45-минутных сборок Go был задуман. Считалось, что стоит попытаться разработать новый язык, подходящий для написания больших программ Google, таких как веб-серверы, с учетом соображений разработки программного обеспечения, которые улучшат качество жизни программистов Google.

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

  • Он должен работать в масштабе для больших программ с большим количеством зависимостей, над которыми работают большие команды программистов.
  • Это должно быть знакомо, грубо говоря C-подобно. Программисты, работающие в Google, находятся в начале своей карьеры и наиболее знакомы с процедурными языками, особенно из семьи C. Необходимость быстрого повышения производительности труда программистов на новом языке означает, что язык не может быть слишком радикальным.
  • Это должно быть современно. C, C++ и в некоторой степени Java довольно старые, разработанные до появления многоядерных машин, современных сетей и разработки веб-приложений. Существуют особенности современного мира, которые лучше соответствуют новым подходам, таким как встроенная конкурентность.

На этом фоне давайте посмотрим на дизайн Go с точки зрения разработки программного обеспечения.

6. Зависимости в Go

Так как мы подробно рассмотрели зависимости в C и C++, хорошее место для начала нашего тура — посмотреть, как Go их обрабатывает. Зависимости определяются синтаксически и семантически языком. Они явные, понятные и «вычислимые», то есть простые в написании инструментов для анализа.

Синтаксис заключается в том, что после предложения package (тема следующего раздела) каждый исходный файл может иметь один или несколько утверждений импорта, включающих ключевое слово import и строковую константу, идентифицирующую пакет, который будет импортирован в этот исходный файл (только):

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

Есть еще один шаг, на этот раз в реализации компиляторов, который идет еще дальше, чтобы гарантировать эффективность. Рассмотрим программу Go с тремя пакетами и граф зависимостей:

  • пакет А импортирует пакет В
  • пакет B импортирует пакет C
  • пакет А не импортирует пакет С

Это означает, что пакет A использует C только транзитивно через использование B; то есть никакие идентификаторы из C не упоминаются в исходном коде для A, даже если некоторые из элементов, которые A использует из B, упоминают C. Например, пакет A может ссылаться на тип структуры, определенный в B, который имеет поле с типом определенным в C, но этот A не ссылается на себя. В качестве мотивирующего примера представьте, что A импортирует отформатированный пакет B ввода/вывода, который использует реализацию буферизованного ввода/вывода, предоставленную C, но что A сам не вызывает буферизованный ввод/вывод.

Чтобы собрать эту программу, сначала компилируется C; зависимые пакеты должны быть собраны до пакетов, которые зависят от них. Затем B компилируется; наконец, A компилируется, и затем программа может быть связана.


Когда A компилируется, компилятор читает объектный файл для B, а не его исходный код. Этот объектный файл для B содержит всю информацию о типе, необходимую для выполнения компилятором

пункта в исходном коде для A. Эта информация включает в себя любую информацию о C, которая понадобится клиентам B во время компиляции. Другими словами, когда B компилируется, сгенерированный объектный файл содержит информацию о типе для всех зависимостей B, которые влияют на открытый интерфейс B.

Этот дизайн имеет тот важный эффект, что когда компилятор выполняет утверждение import, он открывает ровно один файл, объектный файл, идентифицируемый строкой в ​​утверждении import. Это, конечно, напоминает подход Plan 9 C (в отличие от ANSI C) к управлению зависимостями, за исключением того, что компилятор записывает файл заголовка при компиляции исходного файла Go. Однако этот процесс более автоматический и даже более эффективный, чем в Plan 9 C: данные, считываемые при оценке импорта, представляют собой просто «экспортированные» данные, а не общий исходный код программы. Влияние на общее время компиляции может быть огромным и масштабироваться по мере роста базы кода. Время на выполнение графа зависимостей и, следовательно, на компиляцию может быть экспоненциально меньше, чем в модели «включая включаемый файл» C и C++.

Стоит отметить, что этот общий подход к управлению зависимостями не оригинален; идеи восходят к 1970-м годам и распространяются через такие языки, как Modula-2 и Ada. В семействе C Java имеет элементы этого подхода.

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

Такой подход к управлению зависимостями является единственной основной причиной того, что компиляции Go выполняются быстрее, чем компиляции на C или C++. Другим фактором является то, что Go помещает данные экспорта в объектный файл; некоторые языки требуют, чтобы автор писал или компилятор генерировал второй файл с этой информацией. Это вдвое больше файлов, чтобы открыть. В Go есть только один файл, который нужно открыть для импорта пакета. Кроме того, подход с одним файлом означает, что данные экспорта (или заголовочный файл в C/C++) никогда не могут устареть относительно объектного файла.

Для записи, мы измерили компиляцию большой программы Google, написанной на Go, чтобы увидеть, как разветвление исходного кода сравнивается с анализом C++, сделанным ранее. Мы обнаружили, что это примерно 40Х, что в пятьдесят раз лучше, чем в C++ (а также проще и, следовательно, быстрее в обработке), но все же больше, чем мы ожидали. Для этого есть две причины. Во-первых, мы обнаружили ошибку: компилятор Go генерировал значительное количество данных в разделе экспорта, которые там не обязательно должны быть. Во-вторых, в данных экспорта используется подробная кодировка, которая может быть улучшена. Мы планируем решить эти проблемы.

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

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

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

При разработке стандартной библиотеки большие усилия были потрачены на контроль зависимостей. Может быть лучше скопировать небольшой код, чем использовать большую библиотеку для одной функции. (Тест в сборке системы жалуется, если возникают новые основные зависимости.) Гигиена зависимостей препятствует повторному использованию кода. Одним из примеров этого на практике является то, что (низкоуровневый) net пакет имеет свою собственную процедуру преобразования целочисленных значений в десятичные, чтобы избежать зависимости от большого и имеющего много зависимостей отформатированного пакета ввода-вывода. Другой заключается в том, что пакет преобразования строк strconv имеет частную реализацию определения ‘печатаемых’ символов, а не вытягивает большие таблицы классов символов Юникода; то, что strconv соблюдает стандарт Unicode, проверяется тестами пакета.

7. Пакеты

Проект системы пакетов Go объединяет некоторые свойства библиотек, пространств имен и модулей в единую конструкцию.

Каждый исходный файл Go, например «encoding/json/json.go», начинается с утверждения package, например:

где json — это «имя пакета», простой идентификатор. Имена пакетов обычно лаконичны.

Чтобы использовать пакет, импортирующий исходный файл идентифицирует его по пути пакета в утверждении import. Значение «путь пакета» не определено языком, но на практике и условно это разделенный слешем путь к каталогу с исходным файлом пакета в репозитории:

Затем имя пакета (в отличие от пути) используется для определения элементов из пакета в импортируещем исходном файле:

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

В нашем примере путь к пакету — «encoding/json», а имя пакета — «json». Вне стандартного репозитория соглашение должно помещать имя проекта или компании в корень пространства имен:

Важно понимать, что пути к пакетам уникальны, но для имен пакетов таких требований нет. Путь должен однозначно идентифицировать импортируемый пакет, а имя — это соглашение о том, как клиенты пакета могут ссылаться на его содержимое. Имя пакета не обязательно должно быть уникальным и может быть переопределено в каждом исходном файле импорта путем предоставления локального идентификатора в утверждении import. Следующие два оба импортируют эталонные пакеты, которые называют себя package log, но для импорта их в один исходный файл один из них должен быть (локально) переименован:

Мастер Йода рекомендует:  У вас есть 25 лошадей. Сколько забегов вам нужно устроить, чтобы определить трех самых быстрых из

Каждая компания может иметь свой собственный package log, но нет необходимости делать имя пакета уникальным. Скорее наоборот: стиль Go предполагает, что имена пакетов должны быть короткими, четкими и очевидными, а не беспокоиться о коллизиях.

Другой пример: в базе кода Google много server пакетов.

8. Удаленные пакеты

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

Вот как можно использовать пакет doozer с github. Команда go get использует инструмент go build для извлечения репозитория с сайта и его установки. После установки его можно импортировать и использовать как любой обычный пакет.

Стоит отметить, что команда go get рекурсивно загружает зависимости, свойство стало возможным только потому, что зависимости явные. Кроме того, выделение пространства путей импорта делегируется URL-адресам, что делает децентрализованным и, следовательно, масштабируемым именование пакетов в отличие от централизованных реестров, используемых другими языками.

Golang в Google: дизайн языка на службе разработки программ, часть 1

Язык программирования Go был задуман в конце 2007 года как ответ на некоторые проблемы, с которыми мы сталкивались при разработке программной инфраструктуры в Google. Сегодняшний вычислительный ландшафт практически не связан с той средой, в которой были созданы используемые языки, в основном C++, Java и Python. Проблемы, создаваемые многоядерными процессорами, сетевыми системами, массивными вычислительными кластерами и моделью веб-программирования, скорее были решены как обходные пути, чем решены как задуманные изначально. Более того, масштаб изменился: современные серверные программы состоят из десятков миллионов строк кода, работают с сотнями или даже тысячами программистов и обновляются буквально каждый день. Что еще хуже, время сборки, даже на больших кластерах компиляции, увеличилось до многих минут, даже часов.

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

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

1. Введение

Go — это компилируемый, конкурентный, имеющий сборщик мусора, статически типизированный язык, разработанный в Google. Это проект с открытым исходным кодом: Google импортирует публичный репозиторий, а не наоборот.

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

2. Go в Google

Go — это язык программирования, разработанный Google для решения проблем Google, и у Google большие проблемы.

Аппаратное обеспечение большое, а программное обеспечение большое. Есть много миллионов строк программного обеспечения, с серверами в основном на C++ и множеством Java и Python для других частей. Тысячи инженеров работают над кодом, находящимся в «голове» одного дерева, включающего все программное обеспечение, поэтому со дня на день происходят значительные изменения на всех уровнях дерева. Большая специализированная распределенная система сборки делает разработку в таком масштабе осуществимой, но она все еще медлительная.

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

Кратко, разработка в Google велика, может быть медленной и часто неуклюжей. Но это эффективно.

Цели проекта Go состояли в том, чтобы устранить медлительность и неуклюжесть разработки программного обеспечения в Google и тем самым сделать процесс более продуктивным и масштабируемым. Язык был разработан для людей, которые пишут, читают, отлаживают и поддерживают большие программные системы.

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

Но как язык может помочь в разработке программного обеспечения? Остальная часть этой статьи является ответом на этот вопрос.

3. Болевые точки

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

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

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

В качестве простого, автономного примера рассмотрим представление структуры программы. Некоторые наблюдатели возражали против C-образной блочной структуры Go с фигурными скобками, предпочитая использовать пробелы для отступов в стиле Python или Haskell. Тем не менее, у нас был большой опыт отслеживания сбоев сборки и тестирования, вызванных межъязыковыми сборками, где фрагмент Python, встроенный в другой язык, например, посредством вызова SWIG, тонко и незаметно нарушается изменением отступа окружающего кода. Поэтому наша позиция такова: хотя места для отступов хороши для небольших программ, они плохо масштабируются, и чем больше и разнороднее кодовая база, тем больше проблем это может вызвать. Лучше отказаться от удобства из-за безопасности и надежности, поэтому у Go есть ограниченные скобками блоки.

4. Зависимости в C и C++

Более существенная иллюстрация масштабирования и других проблем возникает при обработке зависимостей пакетов. Мы начнем обсуждение с обзора того, как они работают в C и C++.

Стандарт ANSI C, впервые принятый в 1989 году, продвигал идею #ifndef «охраняет» («guards») в стандартных заголовочных файлах. Идея, которая сейчас распространена повсеместно, заключается в том, что каждый заголовочный файл заключен в скобки с условным блоком компиляции, чтобы файл мог быть включен несколько раз без ошибок. Например, заголовочный файл Unix схематически выглядит так:

Предполагается, что препроцессор C читает файл, но игнорирует содержимое во втором и последующих чтениях файла. Символ _SYS_STAT_H_, определяемый при первом чтении файла, «охраняет» («guards») последующие вызовы.

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

Но это очень плохо масштабируется.

В 1984 году компиляция ps.c, исходного кода команды Unix ps, #include наблюдалась 37 раз к тому времени, когда была выполнена вся предварительная обработка. Хотя при этом содержимое отбрасывается 36 раз, большинство реализаций C открывают файл, читают его и сканируют все 37 раз. Фактически, без большой хитрости это поведение требуется потенциально сложной макросемантикой препроцессора С.

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

Технически говоря, так не должно быть. Понимая долгосрочные проблемы с использованием средств защиты #ifndef, разработчики библиотек Plan 9 выбрали другой, не-ANSI подход. В Plan 9 было запрещено содержать в заголовочных файлах дополнительные пункты #include; все #include должны были находиться в файле C верхнего уровня. Конечно, это требовало некоторой дисциплины — программист должен был перечислять необходимые зависимости ровно один раз, в правильном порядке — но документация помогла, и на практике это сработало очень хорошо. В результате, независимо от того, сколько зависимостей имел исходный файл C, каждый файл #include читался ровно один раз при компиляции этого файла. И, конечно же, было легко увидеть, нужен ли был #include, убрав его: отредактированная программа скомпилируется только тогда, когда зависимость не понадобится.

Наиболее важным результатом подхода Plan 9 была гораздо более быстрая компиляция: объем ввода-вывода, который требуется для компиляции, может быть значительно меньше, чем при компиляции программы с использованием библиотек с защитой #ifndef.

Однако вне Plan 9 «guards» подход является общепринятой практикой для C и C++. Фактически, C++ усугубляет проблему, используя тот же подход с более высокой степенью детализации. По соглашению, программы на C++ обычно структурированы с одним заголовочным файлом на класс или, возможно, небольшим набором связанных классов, группировка намного меньше, чем, скажем, . Поэтому дерево зависимостей намного сложнее, отражая не библиотечные зависимости, а полную иерархию типов. Более того, заголовочные файлы C++ обычно содержат реальный код — объявления типа, метода и шаблона, а не только простые константы и сигнатуры функций, типичные для заголовочного файла C. Таким образом, C++ не только отправляет больше компилятору, но и то, что он отравляет, сложнее компилировать, и каждый вызов компилятора должен повторно обрабатывать эту информацию. При создании большого бинарного файла C++, компилятор мог бы тысячи раз научиться представлять строку, обрабатывая заголовочный файл . (Для сведения, около 1984 года Том Каргилл заметил, что использование препроцессора C для управления зависимостями будет долгосрочным обязательством для C++ и должно быть решено.)

Создание одного бинарного файла C++ в Google может открывать и читать сотни отдельных заголовочных файлов десятки тысяч раз. В 2007 году инженеры по сборке в Google разработали сборку основного бинарного файла Google. Файл содержал около двух тысяч файлов, которые, если их просто объединить, составили 4,2 мегабайта. Ко времени расширения #include на вход компилятора было доставлено более 8 гигабайт, что составляет 2000 байт на каждый исходный байт C++.

В качестве другой точки данных, в 2003 году система сборки Google была перемещена из одного файла Makefile в дизайн для каждого каталога с более управляемыми, более явными зависимостями. Типичный бинарный файл сократился примерно на 40% по размеру файла, просто из-за более точной записи зависимостей. Несмотря на это, свойства C++ (или C в этом отношении) делают непрактичным автоматическую проверку этих зависимостей, и сегодня у нас все еще нет точного понимания требований к зависимостям больших бинарных файлов Google C++.

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

Даже с распределенной системой сборки большая сборка Google может занять много минут. Этот бинарный файл 2007 года занял 45 минут с использованием системы распределенной сборки предшественника; сегодняшняя версия той же программы занимает 27 минут, но, конечно, программа и ее зависимости за это время выросли. Инженерные усилия, необходимые для масштабирования системы сборки, едва ли могли опередить рост создаваемого программного обеспечения.

Чем мне нравится Go и как его изучать?

В течение последнего года я пишу на Go и написал много кода на Go. Порефакторил кучу микросервисов с Питона и Руби.

Go мне нравится следующими пунктами:

  1. Удобство работы с concurrency
  2. Отличная стандартная библиотека.
  3. Очень удобно писать тесты.
  4. Низкий порог вхождения
  5. res, err := something()

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

С чего начать?

Начать можно с хабра С чего начать новичку в Go, или же можно пойти по официальному пути.

В целом, если вы довольно адекватный и у вас много опыта, то Go вы освоите за пару часов, пройдя тур по Go. Дальше только писать код.

Из книг рекомендую “Язык программирования Go” от Кернигана.

Umputun тут был

заметки на разные темы

Домой
Еженедельный подкаст
Подкаст Радио-Т
Пираты РТ
Теория и практика звукозаписи

Go или не Go?

Цель этого поста попытаться ответить на ряд вопросов которые я получаю время от времени. Самый популярный это «стоит ли изучать?», второй по популярности «а как это сделать?» и 3й — «это ведь отстой, как ты мог сказать про него хорошего?»

Давайте по пунктам. На вопрос «стоит ли его изучать», я смело скажу — да, стоит. И этому есть пара весомых причин:

Это вполне практичный язык и умение писать на нем позволит вам сделать что-то. Это «что-то» можно сделать и на других языках, но можно и на Go. Если иметь ввиду небольшие домашние проекты, то тут по практичности и скорости достижения результата Go, для меня, примерно на одном уровне с Python. Однако, если проект не самый мелкий и/или его развитие и сопровождения может потребоваться, то тут я отдам предпочтение Go.

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

Теперь попробую развернуть, обосновать и ответить за все.

Писать небольшие и средние проекты на Go на удивление приятно, быстро и результативно. Я не знаю, как будет в случае действительно больших проектов, такого опыта у меня пока не много, но с мелкими и средними все в порядке. С момента моего практического соприкосновения с Go, я написал на нем целую кучу того, где я раньше использовал python, и где мне всегда казалось, что это слишком много для python, либо где использовал java и ощущал, что java это перебор для такого. Не бахвальства ради, но прояснения для, вот короткий список:

бэкенд того, что делает news.radio-t.com. Это проект а не проектик, там на самом деле много всего за сценой.

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

бот для нашего гиттер чата. Он тоже был на java много лет и, честно говоря, его можно было бы переписать на чем угодно. Там с годами многие самые сложные вещи устарели, а то, что осталось – оно совсем простое. Но писать на Go его было просто и приятно.

идет неспешный процесс написание новой версии ukeeper v2 на Go. Тут все несколько сложнее. Это реально большой проект на java и он перерос себя и свою архитектуру. Я пару раз уже засучивал рукава и пытался раздробить его на мелкие части, убрать старый хлам и упростить все, что можно. Но задача это пугающе велика и по сути сводится к переписыванию многих частей с использованием современных методов и технологий, плюс к вдумчивому отсеканию лишнего. В виде эксперимента я попытался написать основной сервис, тот что делает главную магию, на Go и результат приятно удивил. Код простой и почти прямой, производительность более чем, масштабируемость в ассортименте. И на написание этого сервиса ушло всего пару выходных.

есть целый ряд мелких и средних проектов по работе, которые были либо написаны с нуля, либо как upgrade с их py версии, которая стала выходить из под контроля. Там много чего, начиная от диспетчера RMQ с хитрым форвардингом и до систем управления ресурсами в AWS. Есть и более традиционные системы для бизнес задач и вычислительные системы и разное другое.

В процессе столь тесного общения с Go я заметил целый ряд особенностей:

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

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

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

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

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

Если к этому моменту я вас убедил и ваши рукава засучены, а пальцы зависли над клавиатурой в непреодолимом желании попробовать, то вот вам ответ на вопрос «как и что учить?». Во первых, я бы не советовал читать книги по Go. Да, есть пара достойных книг которые может и стоит почитать со временем, но гораздо практичней будет просмотреть 3 ресурса:

  1. Go by Example – очень лаконично, и почти о всем, что надо для быстрого старта.
  2. Learn X in Y minutes – прелестный способ, мой личный фаворит.
  3. How to Write Go Code — тоже коротко и сердито.

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

По поводу «это отстой, a не язык». Тут мне трудно спорить и не только потому, что я это и сам говорил. Язык, для ценителей, на самом деле не самый . выразительный. И для беглого взгляда, программа на Go выглядит странно, а для многих неприятно. Однако, к тому, как оно выглядит привыкаешь быстро, ну и это «бее» можно выдать и о любом новом синтаксисе. Я помню, как меня доставал по началу питон со своими отступами и java с своими длинными конструкциями.

И про скудность языка тоже не поспоришь. Да, он такой. Да, там нет многого из того, что хотелось в том числе и мне. Однако, как и все практичное в нашей области, Go это компромисс. И этот компромисс действительно выглядит не особо привлекательно со стороны. Я вполне понимаю критиков языка и местами разделяю их позицию, за исключением их вывода — «это неподходящий язык, в топку его». Из моего практического опыта эти компромиссы не настолько суровы как кажется со стороны. На Go можно писать код, можно читать код и оба эти процесса на удивление приятны. Тут есть какой-то особый феномен который я затрудняюсь описать. По всем признакам Go должен был оказаться провалом и ошибкой природы, но на практике это реально рабочий инструмент вполне подходящий к целому классу задач.

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

Реакция Конора МакГрегора на бой Абубакара Нурмагомедова с Дэвидом Завадой / Обзор UFC Москва

Ойнатқышты басқару элементтерін көрсету

Автоматты түрде ойнату

  • Жарияланды 2020 ж. 9 Қар.
  • ПРОМОКОД — ANTONOV
    В этом видео: Узнаем результат поединка на UFC в Москве между братом Хабиба — Абубакаром Нурмагомедовым и его соперником! Послушаем реакцию Конора МакГрегора на поражение Абубакара
    Мой канал является членом медиа-сообщества Yellow Br > ybmfamily Спорт

Пікірлер • 375

Жара пошла ! Если ставишь, залетайте сюда : bit.ly/2GA3jth , а бонусы можно получить по промокоду
— ANTONOV

ДЕРУТСЯ ОДНИ , а ОБСУЖДАЮТ ДРУГИХ!
ВЫ ЛУЧЩЕ ЭТОТ ПРИЁМ РАЗБЕРИТЕ , КАК ПОПАЛСЯ И Т.Д , А НЕ КОММЕНТАРИИ ТРЕТЬИХ ЛИЦ !

Конор лает, караван UFC идет дальше.

Конор гандон одним словам

WTF . KHABIB IS DANGEROUS TOP 10 FIGHTER BUT HE COUSIN LOOK LIKE . OMG THIS COUSIN IS NOT KHABIB LEVELLL ������������������������������������������

пацаны найдите вы эту нагицу или как ее там без шумихи! не давайте ему реванша

Конору нужно вспомнить как он сначала от Нейта а потом от Хабы стучал а потом жадно воздух глотал! Ведёт себя как чмо!

А за Забита искренне рад! Больших побед тебе бро!

КОНОР МЫ ТЕБЯ МЫ РАКОМ ПОСТАВИМ. СВОЙ ЯЗЫК ПРОГЛАТИШ.

Конар род консервы

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

�������� �� Это еще был дебют в Юфс вахахах

команда Хабиба : тролинг про то что сдался.
Конор : тролинг про то что сдался.
вы там в ufc совсем ебанулись? как тёлки. Пиздежа больше чем времени в октагоне проводят, самый крупный конфликт ufc построен на метании «стрел» друг в друга, после выйдут, пару минут подеруться, выйдут и будут говном поливать, чтобы мы схавали, типо воевали между собой как фанаты. 90% фанатов, как зомби верят каждому слову кому покланяются, тошно, поэтому всем и нравится Забит, что он дерется и не более, скромный и воспитанный. Команда Конора и Хабиба, два самых популярных лагеря в mma, за которыми следит весь мир единоборств, ведут себя как дети, которым надо обязательно ответить, на любую критику от других бойцов.

Самое главное что Абубакар не болтал лишнее перед боем как Конор, позор это тогда сначала болтат на саперника что попало а потом здаться (постучать) например как Конор болтал перед боем с Хабибом а потом постучал, а Абубакар ничего лишнего не болтал перед боем вёл скромно и в безвыходном положении здался, все задаются когда есть без входная положения, как вы видели даже Фёдор здался когда то но это не позор, позор это тогда когда болтаеш много а потом постучать как это любит делать Конор

Я бы на месте Конора, вспомнил бы автобус,и как кто то менжанулся из автобуса выйти !

Конор так сказал, потому что над ним смеялся Хабиб и говорил что стучат только трусы, выходит его брат трус по логике Хабиба, Абубакар по делу проиграл, слишком много болтает, болтунов бог наказывает

Добавить комментарий