Продолжаем публикацию наших образовательных материалов. Этот курс посвящен изучению основ языка Go. На примере простой текстовой игры будут рассмотрены все основные задачи, с которыми сталкивается разработчик современных веб-приложений в крупных проектах, с реализацией их на Go. Курс не ставит задачи научить программированию с нуля, для обучения будут необходимы базовые навыки программирования.
Список лекций:
- Лекция 1. Введение
- Лекция 2. Функции, структуры, интерфейсы. Объектная модель
- Лекция 3. Асинхронная модель
- Лекция 4. Web. Работа с сетью
- Лекция 5. Работа с СУБД
- Лекция 6. Система тестирования
- Лекция 7. Reflect or generate?
- Лекция 8. Производительность
- Лекция 9. Context, unsafe, cgo
Вы получите опыт разработки высоконагруженных бекенд приложений на Go, а также научитесь поддерживать, тестировать и отлаживать приложения. Из курса вы узнаете о том, как поднять веб-сервер, обрабатывать HTTP-запросы и работать с SQL-базой; что такое горутины c каналами и как выглядит асинхронное программирование на Go; какие основные вещи требует экcплуатация при принятии проекта в production.
Курс ведут Василий Романов, технический менеджер Почты Mail.Ru, Илья Ожерельев, программист backend'a Почты Mail.Ru, и Дмитрий Дорофеев, программист frontend'a Почты Mail.Ru.
Лекция 1. Введение
Вводная лекция, в которой описывается история языка, его основные особенности, использование Go в Mail.ru, основные синтаксические конструкции языка и базовые типы данных.
Лекция 2. Функции, структуры, интерфейсы. Объектная модель
На второй лекции рассматриваются следующие вопросы:
Функции:
- Передача параметров по ссылке/значению.
- Именованные параметры.
- Замыкания.
- Функции высшего порядка.
- defer.
- Системные функции.
Структуры:
- struct, ООП.
- Методы.
- Embedded-объекты.
Интерфейс:
- Пустой интерфейс.
- Использование интерфейсов.
Лекция 3. Асинхронная модель
На третьей лекции рассматриваются параллелизм и многопоточность языка, Go-рутины (горутины), каналы, пакеты sync и atomic.
Лекция 4. Web. Работа с сетью
Из этой лекции вы узнаете о работе Go с сетью: работа с протоколом TCP, какие есть ограничения, особенности работы с URL, как строятся HTTP-запросы и ответы, и многое другое.
Лекция 5. Работа с СУБД
На пятой лекции рассказывается о клиентской (браузерной) части при работе с СУБД, а также о серверной части: построении бизнес-логики, создании сессии авторизации, профиля и работе с контентом.
Лекция 6. Система тестирования
Лекция посвящена построению системы тестирования для проверки кода на Go, вклбючая модульные тесты и выполнение непрерывной интеграции.
Лекция 7. Reflect or generate?
На лекции рассматриваются такие вопросы, как что такое рефлексия, законы рефлексии, использование go generate и так далее.
Лекция 8. Производительность
Как выявить медленно работающие части кода на Go и как их оптимизировать так, чтобы программа работала быстро в условиях ограниченности доступных ресурсов? Об этом вы узнаете из восьмой лекции.
Лекция 9. Context, unsafe, cgo
Заключительная лекция курса посвящена рассмотрению трёх тем: контекста (состояние запроса, отмена выполнения), unsafe (низкоуровневое программирование) и cgo (интеграция кодов на Go и С).
Плейлист всех лекций находится по ссылке. Напомним, что актуальные лекции и мастер-классы о программировании от наших IT-специалистов в проектах Технопарк, Техносфера и Технотрек по-прежнему публикуются на канале Технострим.
Комментарии (51)
beduin01
10.05.2017 17:27+3Судя по тому что рассказывают докладчики у Go есть только одно преимущество, можно легко и быстро создавать кучу легковесных потоков. В остальном не язык, а один сплошной архаизм поощряющий костылестроение в попытках обойти его конструктивные недостатки.
ainu
10.05.2017 17:39Код, не использующий потоки, на Go тоже легко и быстро пишется. Парсеры/серверы/утилиты.
VolCh
11.05.2017 10:31В наше время есть серверы, не использующие ту или иную реализацию параллельного выполнения запросов от клиентов?
ainu
11.05.2017 10:43В наше время есть программы, которые работают не на сервере.
В наше время есть cli-утилиты (например, сконвертить один файл в другой)
В наше время есть однопоточный bolt.
Параллельность — это ещё не всё.
Go — это не «язык с прикольной параллельностью, но вот жаль нет дженериков, ООП, эксепшенов, тьфу убогая архитектура».
На Go действительно можно быстро писать код, и не только многопоточный/конкуррентный.
Прошу заметить, что это не означает, что нельзя программировать на D/Rust/Scala/etc.ainu
11.05.2017 10:48Справедливости ради озвучу (хотя тут все это понимают), что любой сервер под капотом использует многопоточность в том или ином ей виде. Go-шный net/http сервер — тоже. Однако можно написать http сервер на Go (на основе net/http) и в коде не будет ни одного вызова go funcName().
beduin01
10.05.2017 17:40+1Я еще раз сделаю акцент на том, что Go подходит для создание кучи легковесных потоков, но совершенно не подходит для обработки данных (хотя если упороться можно хоть числодробилку на PHP написать).
package main import "fmt" func int64Sum(list []int64) (uint64) { var result int64 = 0 for x := 0; x < len(list); x++ { result += list[x] } return uint64(result) } func int32Sum(list []int32) (uint64) { var result int32 = 0 for x := 0; x < len(list); x++ { result += list[x] } return uint64(result) } func int16Sum(list []int16) (uint64) { var result int16 = 0 for x := 0; x < len(list); x++ { result += list[x] } return uint64(result) } func int8Sum(list []int8) (uint64) { var result int8 = 0 for x := 0; x < len(list); x++ { result += list[x] } return uint64(result) } func main() { list8 := []int8 {1, 2, 3, 4, 5} list16 := []int16{1, 2, 3, 4, 5} list32 := []int32{1, 2, 3, 4, 5} list64 := []int64{1, 2, 3, 4, 5} fmt.Println(int8Sum(list8)) fmt.Println(int16Sum(list16)) fmt.Println(int32Sum(list32)) fmt.Println(int64Sum(list64)) }
Тоже самое на D. В которому впрочем поддержка этих же легковесных потоков тоже есть.
import std.stdio; import std.algorithm; void main(string[] args) { [1, 2, 3, 4, 5].reduce!((a, b) => a + b).writeln; }
RPG18
10.05.2017 18:07+1но совершенно не подходит для обработки данных
У каждого свои данные. Я вот пишу что-то типа Socorro, но с поддержкой emscripten. Данными являются файлы символов, минидампы, то что сваливается в GlobalEventHandlers.onerror.
ReklatsMasters
10.05.2017 22:14А можно простейший пример этих легковесных потоков на D? Просто интересно сравнить.
beduin01
11.05.2017 09:52kilgur
11.05.2017 12:47Это все-таки разные вещи. Как минимум, в файберах управление переключается явно.
Weres
16.05.2017 11:18+1Yield нужно расставлять руками (в golang умный шедуллер) и распределением фиберов по тредам придётся, опять же, заниматься руками. Штука всё равно хорошая и D куда более мощный и приятный язык, чем Go, но всё-таки горутины куда более продвинуты.
KEKSOV
11.05.2017 13:46+1Простите, но Ваш пример, демонстрирующий «невозможность организовать на golang обработку данных», не выдерживает никакой критики. Лаконичность кода на D — да. C тем же успехом можно написать строчку на JS
и сказать, что JS аж на пять строк короче, чем D…[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array) { return previousValue + currentValue; });
А как насчёт сопровождения такого кода? Как насчёт отлова ошибок с данными на этапе компиляции? Тесты производительности гоняли?
madkite
11.05.2017 16:13+2В Вашем примере на D только один массив непонятного размера и бизнес-логика (суммирование) не вынесено в отдельную функцию. Если же создать 4 массива с элементами разных размеров и не инлайнить функцию суммирования (а написать template, который будет понимать разные типы), то кода будет чуть больше… Но в целом Ваши негодования понятны — отсутствие в стандартной библиотеки функции reduce (есть сторонние реализации) и отсутствие generic-ов — на эту тему уже много написано, даже авторами языка.
beduin01
12.05.2017 13:08-1Так же авторы языка делали Go для мелких утилит в 100-150 строк кода, поэтому Go в больших проектах это в первую очередь геморрой т.к. он не позволяет делать элементарные абстракции и обобщения.
Даже Python на фоне Go смотрится куда более продуманным и совершенным языком.
roma_dev
16.05.2017 11:17можете привести пример где go «совершенно не подходит для обработки данных»?
nizsheanez
16.05.2017 11:18-1Да, в примерах Go выглядит именно так, но в реальных проектах редко спотыкаешься о то что под каждый тип надо свой метод писать. У нас много разных сервисов на Go, и таких функций как в примере, ну может 2-3 от силы, а 2-3 функции в common это примерно 0% от кода проекта.
JekaMas
17.05.2017 10:28-1Соглашусь. Только на низком уровне с этим есть сложности и при потребности в максимальной прроизводительности: иначе же можно спокойно жить с fmt sync.map и прочим, принимающим и отдающим interface{} и не столкнуться с проблемами, ни кода ни производительности.
Мне кажется, что желание дженериков везде и всегда, сродни преждевременной оптимизации или неоправданному расширению задачи: надо было сделать для одного типа, но программист пробует написать обобщенный код.
Дженерики нужны, конечно, кодогенерация не помогает всегда, да и код усложняет в разы, как и отладку сгенерированного кода. И в самой стандартной библиотеке она не используется, то есть это решение и разработчикам golang не сильно нравится.
Но да, дженерики не настолько важны в действительной жизни. Рабочий код пишется и без них.
kshvakov
16.05.2017 11:18-1Это слишком «притянутый за уши» пример, как по мне, например, лучше один раз создать пакет sum (Int8, Int16 etc) и использовать его в проекте
package main import "sum" func main() { println(sum.Int8([]int8 {1, 2, 3, 4, 5})) }
чем пытаться понять из какого пакета прилетела функциональность writeln или reduce (соответственно, чем больше проект и больше пактов, тем сложнее, опять же для меня, все это поддерживать), так что только на основании этого я бы не стал утверждать, что он (Go) категорично не подходит для обработки данных
ЗЫ: и у D и у Go есть свои плюсы, но Go, в моем случае, предпочтительнее в силу своей очевидности
mnv
10.05.2017 18:24Не работал с Go, но слышал, что там не реализованы исключения. Есть ли какой-то устоявшийся альтернативный подход к выбрасыванию и обработке исключений?
kilgur
10.05.2017 20:57+2Вы потролить зашли? :) Запрос в гугле «golang обработка исключений» выдает ответ на ваш вопрос на stackoverflow и несколько статей (в том числе и на хабре) про обработку ошибок в go.
mnv
10.05.2017 23:31-4Почему же. Дело в том, что вместо привычного механизма исключений в Go предлагается несколько вариантов, но все они с первого взгляда какие-то неудобные. Есть даже библиотеки, которые пытаются воспроизвести что-то близкое к привычным исключениям. Может это и нормально, но для человека, не работающего с Go, это выглядит странно. Поэтому вполне нормальный вопрос.
kilgur
11.05.2017 07:43Я понимаю, почему вы ищете исключения в go — «привычный механизм», я не понимаю зачем? Например, вы привыкли ездить на велосипеде, видите как другие ездят на самокатах и удивляетесь — зачем они ногами от земли отталкиваются, есть же классная штука — педали, которые можно крутить… и ищете педали на самокате… даже где-то видели возможность прикрутить педали к самокату. Зачем? Если для вас важен механизм исключений при разработке, а обработка ошибок как возвращаемых значений в go кажется вам неудобной, не изучайте go. Есть множество других языков с исключениями.
Мне вот не понравился rust, не смог привыкнуть к его «свистульками и погремушкам», причем на уровне ощущений и эмоций, т.е. я не смогу объяснить — чем именно не понравился. Нет, так нет, я и не читаю статьи про rust.kilgur
11.05.2017 12:05Минусуют фанаты rust'а? Это я неудачный пример привел… холиварный. Буду иметь в виду.
DarkEld3r
12.05.2017 12:36+1А что раст? Там тоже "нет исключений". Просто перестроится сложно и не всегда понятное даёт ли это хоть какие-то преимущества. Люди привыкли жить с исключениями и находят в этом определённое удобство. Тут надо показать преимущества другого подхода, а не просто предлагать забыть о предыдущем опыте.
kilgur
12.05.2017 13:17Я не предлагаю забыть предыдущий опыт. Я немного о другом. В каждом языке есть свои особенности и, касаемо go, у разработчика нет выбора в подходе обработки ошибок — нельзя выбрать «go с исключениями» или «go с возвращаемыми ошибками». Выбор есть только выше уровнем — go или «не go». Если кому-то важны именно исключения, значит go следует вычеркнуть из списка «следующий язык программирования для изучения». Если жизнь не мила без дженериков — аналогично. Я об этом.
А «не фигово было бы изучить go, но в нем обработка ошибок какая-то неудобная...» я не понимаю. После подобного хочется спросить «Ииии?!» Дальше-то что? Если человек хочет узнать, как эта неудобная обработка ошибок работает и как ей пользоваться, ну, так «google в помощь» — информации навалом.
А про раст — мне неважно, есть там исключения или нет; если у меня хватит терпения и времени я приму его модель и неважно — насколько она отличается от go, python, php, lua (других языков я не знаю).
q1t
16.05.2017 11:18+2Так сказать для программиста/инженера выбор инструмента основываясь на эмоциях не самый лучший подход.
kilgur
17.05.2017 09:00-2Полностью с вами согласен. Но я себе выбирал не инструмент для каких-то конкретных задач, а тему для саморазвития, чтобы мозги «не кисли». Поэтому не стал «копать» — что именно меня не устроило в rust'е. По мелким админским задачам python'а хватает «за глаза», т.ч. я и Go пока не нашел применения на работе, к сожалению.
VolCh
11.05.2017 10:41+4Для человека, работавшего со, скажем так, Фортран и Си-подобными языками, некоторые варианты, предлагаемые Go, в частности возвращение из функций двух значений, одно из которых является и признаком, и сообщением об ошибке, являются куда более удобными, чем привычное либо возвращение ошибки магическим числом, либо падение процесса. Привычные по С++ подобным языкам исключения с раскруткой стека вызовов чащего всего используются не по назначению, не для обработки исключительных ситуаций, а для ветвления в зависимости от каких-то определенных условий.
kilgur
10.05.2017 18:56+6Простите, но уровень лекций — «ниже плинтуса». Может, это слишком субъективно, но я не смог досмотреть ни одной лекции. Хватило терпения только на 3. Я понимаю — парни волнуются, они разработчики, а не преподаватели. Но тем более тогда лучше сделать публичную версию специально отснятой — с монтажем, дублями и т.п. Видео и так очень отстает от книг в плане скорости подачи информации, а в этих лекциях скорость становится просто черепашьей, к сожалению. ИМХО, книга Кернигана и Донована за аналогичное время даст больше информации и основы go будут понятнее.
JekaMas
11.05.2017 14:59+1Во первых, мое почтение за большую работу. Сейчас это самый полный материал по Golang, по крайней мере, на русском языке.
Но для пробы посмотрел вторую лекцию и был удивлен: в лекции рассматриваются вопросы, которых или не существует или они по-другому работают в go. Рассмотрена передача параметров по ссылке и значению, но в go есть только передача по значению; предупреждается о переполнении стэка — ну это возможно, если всю память переполнить, впринципе…claygod
17.05.2017 09:50Рассмотрена передача параметров по ссылке и значению, но в go есть только передача по значению
В Golang есть передача по указателю ( http://golang-book.ru/chapter-08-pointers.html ) ну и для особых случаев пакет unsafe если уж действительно надо поработать на низком уровне.JekaMas
17.05.2017 10:21+1Указатель не есть тоже самое, что ссылка.
Можно сделать указатель, но в функцию его передашь все равно по значению. С unsafe то же самое. Ну будет uintptr — это не ссылка, а вполне себе значение.claygod
17.05.2017 11:39+1Давно я не брал в руки шашки.., но по сути, ссылка, это неизменяемый указатель… Можете написать пример кода на Go, в котором именно ссылка а не указатель потребовались, и так, чтобы именно существенно? (В вопросе нет иронии, плз, поделитесь проблемой).
JekaMas
17.05.2017 13:48Ну проблемы нет, есть неверный материал в лекциях, в частности из-за непонимания того, что в go есть только передача по значению можно написать такой неверный код
l0rda
16.05.2017 10:34Идея хорошая, но как уже писали — качество хромает, некоторых лекторов просто невозможно слушать. Если их научить не делать ээээ, убрать слова-паразиты и тп, все получится. Но хоть какой-то контент на русском стал появляться по гоу, за это спасибо.
pfihr
18.05.2017 23:40В первой лекции в конце ошибка, при передаче слайса и сложных типов, они НЕ передаются по ссылке, а передается копия структуры с указателем (копия дескриптора переменной). Если внутри фугкции произойдет изменение этого аргумента такое, что потребует реаллокации массива в памяти, то внутри функции создастся копия слайса с массивом, и снаружи функции дальнейшие изменения уже не будут видны. Поэтому и рекомендуют передавать указатели на сложные типы, а не сами переменные типа.
ainu
Спасибо! Насколько я вижу, уровень выше (и ценнее!) среднего youtube-ролика а-ля «основы Golang» или «как мы уменьшали stop-the-world в GC»
ainu
А ещё советую в заголовок, текст или в теги добавить «golang». Это общепринятая рекомендация для именования материалов, чтобы было проще гуглить.
igordata
Я тоже за golang, потому go гуглится с трудом, т.к. является распространённым словом.