Golang: Панацея в бэкенд-разработке?

задняя часть Go

Резюме: В этой статье будут подробно представлены особенности языка Golang, его преимущества, недостатки и применимые сценарии.С помощью приведенных выше вопросов мы проанализируем все аспекты языка Go для читателей, чтобы помочь программистам, которые плохо знакомы с ИТ-индустрией. и иметь представление о Go. Заинтересованные разработчики узнают больше об этом популярном языке.

Эта статья опубликована в сообществе HUAWEI CLOUD.«Действительно ли популярный Golang является панацеей в бэкенд-разработке? 》, оригинальный автор: Марвин Чжан.

предисловие

Люди за пределами города хотят войти, люди в городе хотят выйти. -- Цянь Чжуншу "Осадный город"

Поскольку оркестрация контейнеров, микросервисы, облачные технологии и т. д. продолжают преобладать в ИТ-индустрии, Golang (язык Go, называемый Go), родившийся в Google в 2009 году, становится все более популярным среди разработчиков программного обеспечения. и востребованный, став сегодня самым популярным языком программирования для серверной части. В списке программных проектов, разработанных с помощью Golang, есть продукты звездного уровня, такие как Docker (контейнерная технология) и Kubernetes (контейнерная оркестровка), которые подрывают всю ИТ-индустрию, а также Prometheus (система мониторинга), Etcd (распределенное хранилище). , InfluxDB (база данных временных рядов) такой мощный и практичный известный проект. Конечно, область применения языка Go отнюдь не ограничивается контейнерами и распределенными системами. В настоящее время многие крупные интернет-компании используют Golang для создания серверных веб-приложений, таких как Toutiao, JD.com, Qiniuyun и т. д. Область поиска фреймворков, в которой долгое время доминировал Python, также постоянно развивается. пострадал от Golang из-за появления Colly, простого и удобного в использовании фреймворка для поисковых роботов. Golang стал языком программирования, который сегодня хочет изучать большинство инженеров-программистов. Приведенный ниже график является результатом исследования навыков программистов, проведенного HackerRank в 2020 году.

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

Введение в Голанг

Неслучайно Golang родился от интернет-гиганта Google. Все мы знаем, что корпоративная культура Google состоит в том, что 20% сотрудников занимаются побочными проектами, что позволяет инженерам создавать прорывные инновации в непринужденной обстановке. И Голанг постоянно вылупляется в эти 20% времени. Основатель языка Go также является известным лидером в ИТ-индустрии, включая Роба Пайка, члена основной группы Unix, Кена Томпсона, автора языка C, и Роберта Гриземера, основного участника движка V8. . Язык Go хорошо известен широкой публике из-за бурного развития технологии контейнеров Docker после того, как в 2014 году его исходный код был открыт. С тех пор язык Go пользуется спросом у большого количества разработчиков из-за его простого синтаксиса и высокой скорости компиляции, а также родилось много отличных проектов, таких как Kubernetes.

По сравнению с другими традиционными популярными языками программирования язык Go имеет много преимуществ, особенно егоЭффективная скорость компиляцииа такжеестественный параллелизм, будь как будетБыстрая разработка распределенных приложенийпредпочтительный язык. Язык Goстатически типизированный язык, то есть язык Go должен компилироваться так же, как Java и C#, и иметь полную систему типов, которая может эффективно уменьшить проблемы, вызванные несоответствием типов.проблемы с качеством кода. Поэтому язык Go очень подходит для построения парстабильностьа такжегибкостьЭто также важная причина, по которой многие крупные интернет-компании используют Golang для рефакторинга старого кода: традиционные статические языки ООП (такие как Java, C#) очень стабильны, но им не хватает гибкости; в то время как динамические языки (такие как PHP, Python, Ruby, Node.js) гибки, но им не хватает стабильности. Поэтому вполне естественно, что Golang, у которого есть «медвежья лапа и рыба», востребован разработчиками, ведь «мир давно страдает от Java/PHP/Python/Ruby».

Тем не мение,Язык Go не лишен недостатков.. С диалектическим мышлением можно предположить, что некоторые из выдающихся особенностей Голанга станут его обоюдоострым мечом. Например, преимущества простого синтаксиса Golang ограничат его способность справляться со сложными проблемами. В частности, отсутствие дженериков в языке Go значительно усложнило построение общей структуры. Хотя эта нерешенная проблема, вероятно, будет эффективно решена в версии 2.0, она также отражает недостатки звездных языков программирования. Конечно, недостатки Go на этом не заканчиваются: пользователи языка Go также будут жаловаться на его многословную обработку ошибок (Error Handling), отсутствие строгих ограничений на утиный тип (Duck Typing) и проблемы с форматом даты. Ниже мы начнем с характеристик языка Golang и проанализируем преимущества и недостатки Golang и сценарии применения проекта от мелкого до глубокого.

Особенности языка

Лаконичные грамматические особенности

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

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

func main() {  valInt := 1  // 自动推断 int 类型  valStr := "hello"  // 自动推断为 string 类型  valBool := false  // 自动推断为 bool 类型}

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

// 定义一个 struct 类type SomeClass struct {  PublicVariable string  // 公共变量  privateVariable string  // 私有变量}// 公共方法func (c *SomeClass) PublicMethod() (result string) {  return "This can be called by external modules"}// 私有方法func (c *SomeClass) privateMethod() (result string) {  return "This can only be called in SomeClass"}func main() {  // 生成实例  someInstance := SomeClass{    PublicVariable: "hello",    privateVariable: "world",  }}

Если вы реализуете приведенный выше пример на Java, вы можете увидеть подробные файлы классов .java, подобные этому.

// SomeClass.javapublic SomeClass {  public String PublicVariable;  // 公共变量  private String privateVariable;  // 私有变量    // 构造函数  public SomeClass(String val1, String val2) {    this.PublicVariable = val1;    this.privateVariable = val2;  }    // 公共方法  public String PublicMethod() {    return "This can be called by external modules";  }    // 私有方法  public String privateMethod() {    return "This can only be called in SomeClass";  }}...  // Application.javapublic Application {  public static void main(String[] args) {    // 生成实例    SomeClass someInstance = new SomeClass("hello", "world");  }}

Видно, что помимо хорошо заметных многослойных фигурных скобок, Java-код также наполнен большим количеством ключевых слов для модификаторов public, private, static, this и других, которые очень многословны; код Golang основан на простых соглашениях, таких как использование заглавных букв, избегайте множества повторяющихся модификаторов. Конечно, у Java и Go все еще есть некоторые различия в системе типов, что также делает Go несколько бессильным в решении сложных проблем, об этом мы поговорим позже. В целом можно сделать вывод, что синтаксис Go очень лаконичен для языка программирования со статической типизацией.

Встроенное параллельное программирование

Помимо высокой производительности, основной причиной, по которой язык Go стал первым выбором для распределенных приложений, является его естественное параллельное программирование. Эта функция параллельного программирования в основном исходит от Goroutine и Channel в Golang. Ниже приведен пример использования сопрограмм.

func asyncTask() {  fmt.Printf("This is an asynchronized task")}func syncTask() {  fmt.Printf("This is a synchronized task")}func main() {  go asyncTask()  // 异步执行,不阻塞  syncTask()  // 同步执行,阻塞  go asyncTask()  // 等待前面 syncTask 完成之后,再异步执行,不阻塞}

Как видите, ключевое слово go plus function call позволяет выполнять ее как асинхронную функцию, не блокируя код позади. Если ключевое слово go не добавлено, оно будет рассматриваться как синхронное выполнение кода. Если читатели знакомы с async/await, синтаксисом Promise в JavaScript и даже с многопоточным асинхронным программированием на Java и Python, вы обнаружите, что они не на порядок проще, чем асинхронное программирование в Go!

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

func longTask(signal chan int) {  // 不带参数的 for  // 相当于 while 循环  for {    // 接收 signal 通道传值    v := <- signal        // 如果接收值为 1,停止循环    if v == 1 {      break    }        time.Sleep(1 * Second)  }}func main() {  // 声明通道  sig := make(chan int)    // 异步调用 longTask  go longTask(sig)    // 等待 1 秒钟  time.Sleep(1 * time.Second)    // 向通道 sig 传值  sig <- 1    // 然后 longTask 会接收 sig 传值,终止循环}

интерфейсно-ориентированное программирование

Язык Go не является строго объектно-ориентированным программированием (ООП), он использует интерфейсно-ориентированное программирование (IOP), которое является более продвинутой моделью программирования, чем ООП. Являясь частью системы ООП, IOP уделяет больше внимания правилам и ограничениям, а также соглашениям о методах типов интерфейса, чтобы разработчики могли максимально сосредоточиться на более абстрактной логике программы, а не тратить время на более подробные методы реализации. . Многие крупные проекты используют модель программирования IOP. Если вы хотите узнать больше об интерфейсно-ориентированном программировании, ознакомьтесь с предыдущей статьей «Почему TypeScript является обязательным языком для разработки крупномасштабных интерфейсных проектов» в личном техническом блоге «Code Way», в котором есть подробный объяснение интерфейсно-ориентированного программирования.

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

// 定义 Animal 接口interface Animal {  Eat()  // 声明 Eat 方法  Move()  // 声明 Move 方法}// ==== 定义 Dog Start ====// 定义 Dog 类type Dog struct {}// 实现 Eat 方法func (d *Dog) Eat() {  fmt.Printf("Eating bones")}// 实现 Move 方法func (d *Dog) Move() {  fmt.Printf("Moving with four legs")}// ==== 定义 Dog End ====// ==== 定义 Human Start ====// 定义 Human 类type Human struct {}// 实现 Eat 方法func (h *Human) Eat() {  fmt.Printf("Eating rice")}// 实现 Move 方法func (h *Human) Move() {  fmt.Printf("Moving with two legs")}// ==== 定义 Human End ====

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

обработка ошибок

Обработка ошибок в Go печально известна своей многословностью. Вот простой пример.

package mainimport "fmt"func isValid(text string) (valid bool, err error){  if text == "" {    return false, error("text cannot be empty")  }  return text == "valid text", nil}func validateForm(form map[string]string) (res bool, err error) {  for _, text := range form {    valid, err := isValid(text)    if err != nil {      return false, err    }    if !valid {      return false, nil    }  }  return true, nil}func submitForm(form map[string]string) (err error) {  if res, err := validateForm(form); err != nil || !res {    return error("submit error")  }  fmt.Printf("submitted")  return nil}func main() {  form := map[string]string{    "field1": "",    "field2": "invalid text",    "field2": "valid text",  }  if err := submitForm(form); err != nil {    panic(err)  }}

Хотя весь приведенный выше код является вымышленным, можно увидеть, что код Go полон ошибочных утверждений, таких как if err := ...; err != nil { ... } . Это связано с тем, что язык Go требует, чтобы разработчики сами управляли ошибками, то есть ошибки в функциях должны выдаваться явно, иначе программа Go не будет выполнять никакой обработки ошибок. Поскольку в Go нет синтаксиса try/catch для обработки ошибок в традиционных языках программирования, ему не хватает гибкости в управлении ошибками, что приводит к ситуации, когда «ошибка летит по всему небу».

Однако законы диалектики говорят нам, что в этом есть свои преимущества. Во-первых, это заставляет разработчиков Go стандартизировать управление ошибками на уровне кода, что побуждает разработчиков писать более надежный код; во-вторых, этот способ явного возврата ошибок позволяет избежать «попробовать/поймать» Shuttle, потому что такой «моментальный» подход может привести к ошибкам, которые невозможно точно определить, что приводит к множеству непредсказуемых проблем; в-третьих, поскольку нет скобок try/catch или дополнительных блоков кода, общий код программы Go выглядит более чистым и читабельным.

разное

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

  • Быстро компилируется

  • Кроссплатформенность

  • отложить выполнение задержки

  • выбор/случай выбор канала

  • Компилировать непосредственно в исполняемую программу

  • Нетрадиционное управление зависимостями (вы можете напрямую ссылаться на репозиторий Github как на зависимость, например, import «github.com/crawlab-team/go-trace»)

  • Нетрадиционный формат даты (формат "2006-01-02 15:04:05", вы правильно прочитали, говорят, что это время основания Голанга!)

Обзор преимуществ и недостатков

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

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

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

Нельзя отрицать, что встроенная поддержка параллелизма в языке Go является очень инновационной функцией последних лет, что также является важной причиной, по которой она широко применяется в распределенных системах. При этом он очень быстрый по сравнению с Java, компиляция которого занимает десять минут. Более того, язык Go не жертвует стабильностью ради простого синтаксиса, вместо этого он стандартизирует стиль кода всего проекта Go за счет простых ограничений. Следовательно, «Быстрый» (Fast), «Краткий» (Concise), «Стабильный» (Robust)** — это цели разработки языка Go. В процессе изучения Golang мы не можем бездумно воспринимать все о нем, а должны судить о ситуации в реальном приложении проекта по его собственным характеристикам.

Применимая сцена

После предыдущего обсуждения различных аспектов Голанга мы можем сделать следующие выводы:Go — не панацея для бэкенд-разработки. В реальной разработке разработчикам в любом случае следует избегать использования Golang в качестве внутреннего языка разработки. Напротив,Инженеры должны иметь полное представление обо всех аспектах технологии-кандидата (язык, структура или архитектура), прежде чем принимать решение о выборе технологии, включая степень соответствия технологии-кандидата бизнес-потребностям, степень интеграции с командой разработчиков и ее обучение, развитие, временные затраты и другие факторы. Изучив некоторые языки программирования, включая интерфейс и серверную часть, автор обнаружил, что у каждого из них есть свои преимущества и соответствующие недостатки.Если язык программирования широко известен, это определенно неплохой язык.. Поэтому автор не будет утверждать, что «ХХХ — лучший язык в мире», а поделится с читателями личными представлениями о выборе технологий в конкретных сценариях применения. Конечно, эта статья является технической статьей для языка Go, далее автор поделится сценариями применения, для которых, как мне кажется, больше всего подходит Golang.

Распределенное приложение

Golang очень подходит для разработки в сценариях распределенных приложений. Основная цель распределенного приложения — использовать как можно большеВычислительные ресурсы и пропускная способность сети, чтобы максимизировать общую производительность и эффективность системы, важной функцией которой является параллелизм. И Go поддерживаетВысокий параллелизма такжеАсинхронное программированиелидер по части. Как упоминалось ранее, язык Go имеет встроеннуюДве функции параллелизма Goroutine и Channel упрощают бэкенд-разработчикам выполнение асинхронного программирования. В Golang также есть встроенная библиотека синхронизации., включая Mutex (блокировка взаимного исключения), WaitGroup (группа ожидания), Pool (временный пул объектов) и другие интерфейсы, помогающие разработчикам более безопасно контролировать параллельное поведение программ Go при параллельном программировании. Голанг и многие другиеСредства разработки распределенных приложений, такие как распределенные системы хранения (Etcd, SeaweedFS), библиотеки RPC (gRPC, Thrift), основные SDK баз данных (mongo-driver, gnorm, redigo) и т. д. Все это может помочь разработчикам эффективно создавать распределенные приложения.

Веб-краулер

Разработчики, которые немного разбираются в поисковых роботах, должны были слышать о Scrapy и, в худшем случае, о Python. На рынке существует бесчисленное количество технических книг о поисковых роботах Python, таких как «Практика разработки сетей Python 3» Цуй Цинцай и «Сборник веб-сканеров Python 3» Вэй Шидуна. Scrapy, высокопроизводительная среда сканирования, написанная на Python, была первым выбором инженеров-краулеров с момента ее выпуска.

Однако из-за недавнего быстрого развития языка Go все больше и больше инженеров-сканеров замечают большие преимущества разработки веб-сканеров с помощью Golang. Среди них краулер Colly, написанный на языке Go, теперь имеет более 13 тысяч звезд на Github. Его лаконичный API и эффективная скорость сбора привлекли многих инженеров краулеров и заняли часть доли Scrapy, первого брата в мире краулеров. Как упоминалось ранее, встроенная в язык Go функция параллелизма делает поисковые программы, сильно зависящие от пропускной способности сети, более эффективными, что значительно повышает эффективность сбора данных. Кроме того, как статический язык, язык Go имеет лучшие ограничения, чем динамический язык Python, поэтому его надежность и стабильность выше.

Серверный API

Golang имеет множество отличных серверных фреймворков, большинство из которых полностью поддерживает различные функциональные требования современных серверных систем: RESTful API, маршрутизация, промежуточное ПО, конфигурация, аутентификация и другие модули. А серверные приложения, написанные на Golang, обладают высокой производительностью и обычно имеют очень быструю скорость отклика. Автор однажды использовал Golang для рефакторинга серверного API Python в Crawlab, платформе управления поисковым роботом с открытым исходным кодом.Скорость отклика была оптимизирована с прежних сотен миллисекунд до десятков миллисекунд или даже нескольких миллисекунд.Практика показала, что Go язык полностью раздавил серверную производительность. Нажмите на динамический язык. Наиболее известными внутренними фреймворками на языке Go являются Gin, Beego, Echo и Iris.

Конечно, это не значит, что написание бэкенда на Golang — полностью правильный выбор. Автор будет использовать Java и C # в своей работе.После использования их соответствующих основных фреймворков (SpringBoot и .Net Core) я обнаружил, что, хотя эти два традиционных языка ООП имеют многословный синтаксис, они имеют богатые синтаксические функции, особенно дженерики. , Он может легко справиться с некоторой сложной логикой и повторяющимися бизнес-требованиями. Поэтому, я думаю, рассматривая возможность написания back-end API на Go, можно заранее заглянуть в Java или C#, они отлично справляются с написанием back-end бизнес-функций.

Суммировать

Эта статья начинается с основных грамматических особенностей языка Go и шаг за шагом анализирует преимущества и недостатки языка Go как внутреннего языка программирования, а также его пробные сценарии в реальной разработке программного проекта. Автор считает, что основное отличие Go от других языков заключается в том, чтоЛаконичный синтаксис,Естественная поддержка параллелизма,интерфейсно-ориентированное программирование,обработка ошибоки другие аспекты, а также проанализированы положительные и отрицательные стороны каждой особенности языка. Наконец, согласно предыдущему анализу, автор предложил применимые сценарии использования языка Go в качестве языка программирования для внутренней разработки, то естьРаспределенное приложение,Веб-краулера такжеСерверный API. Разумеется, область практического применения языка Go этим не ограничивается. Фактически, многие известные базы данных разработаны на Golang, например, базы данных временных рядов Prometheus и InfluxDB, а также TiDB, известная как NewSQL. Кроме того, с точки зрения машинного обучения язык Go также имеет определенные преимущества, но в настоящее время Google, похоже, не активно продвигает применение Go в машинном обучении из-за намерения сотрудничать со Swift и TensorFlow, но некоторые потенциальные возможности открываются. появились исходные проекты, такие как GoLearn, GoML, Gorgonia и т. д.

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

Нажмите «Подписаться», чтобы впервые узнать о новых технологиях HUAWEI CLOUD~