Обновить
6
0
Виталий @olivera507224

Разработчик серверного ПО

Отправить сообщение
// UnitOfWork --
func (ths *SQLStore) UnitOfWork(fn func(writer port.Writer) error) (err error) {
	trx := ths.db.Begin()
	if err != nil {
		return err
	}

А для чего здесь идёт проверка ошибки? err в данном случае объявлена как именованный результат, при входе в метод она безальтернативно будет рана nil. Код return err в этом примере недостижим.

Многопоточность появилась и успешно применялась задолго до появления концепций по которым мы дискутируем (я надеюсь это то слово которое следует здесь применять).

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

А я боюсь за этим может последовать: надо сжечь, желательно вместе с автором.

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

Полностью поддерживаю. Очень странно видеть в тексте, который описывает понимание автором базовых вещей, принципиальную ошибку уровня новичка, в которой утверждается что Асинхронность всегда подразумевает Многопоточность. В том же С# концепция async/await подразумевает работу с тасками, которые все одновременно вполне могут работать как в одном потоке, так и в нескольких - как решит рантайм. В случае большого количества мелких тасков, генерирующих iobound, нет смысла запускать их в отдельных потоках, потому что создание потоков - удовольствие не из дешёвых. По уровню абстракции таски в C# примерно сопоставимы с горутинами в Go.

Даже немного страшно читать дальше.

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

Всё нормально тут выведет: https://go.dev/play/p/MMNrjvhi1zh.

Автор либо невнимательно пишет, либо просто не проверяет что делает его код перед тем как добавить его в статью. Там ещё много подобных косяков.

Без проблем выведет в данном примере.

package main

import "fmt"

func mayPanic() {
    panic("a problem occurred")
}

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()

    mayPanic()

    fmt.Println("After mayPanic()")
}

Функция mayPanic вызывает панику. В функции main, блок defer с функцией recover перехватывает эту панику, позволяя программе продолжить выполнение после функции mayPanic. Без recover программа бы завершилась сразу после паники, не выполнив код, следующий за вызовом mayPanic.

Автор, ты точно пишешь на Go? Код на 18 строке недостижим. Эта программа в текущем исполнении никогда не выведет "After mayPanic()". После выполнения всех отложенных вызовов (defer) происходит возврат из функции, в данном случае - завершение программы. Код после паники никогда не будет исполняться, даже если будет вызвана функция recover, иначе это бы не имело смысла. Неужели перед публикацией было очень сложно скопировать кусок кода и проверить его в Go Playground?

А чем сложностьО(2) отличается от сложности О(1)?

А, ты имеешь ввиду async/await, если я правильно понял. Нет, этот паттерн в Го не реализован. Хотел бы я сказать что он тут и не нужен, но вот мне порой его недостаёт, особенно когда приходится резко перепрыгнуть с того же Питона на Го.

А есть в GO классические коррутины?

Смотря что вкладывать в понятие космических корутин.

И есть ли там конкурентность вообще?

Есть. И автор статьи на протяжении всей статьи её описывает.

Вы подключились по ssh, а дальше?

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

Всегда работал исходя из подхода "Сначала интерфейс, потом контракт, потом клиент". Ну ладно, лукавлю, не всегда. Но как только попробовал - отказаться уже не смог. Под интерфейсом я подразумеваю моки эндпойнтов на сервере, облепленные докстрингами настолько, насколько это вообще возможно. Из получившихся моков как правило без особых проблем собирается опенапи спецификация, из которой также без проблем генерируется пакет для клиента (генератор тут незаменим). Когда цепочка налажена, весь алгоритм можно запихнуть в какой-нибудь Gitlab CI/CD, и вот уже после обновления сервера мы можем автоматом получать необходимые клиенту пакеты, которые аккуратно складываются в корпоративный реестр.

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

Явное преимущество Vim становится очевидным при подключении по SSH к удаленным серверам. В таких сценариях VS Code не слишком удобен, в то время как для ввода «vim» с клавиатуры и начала редактирования потребуется всего пара секунд.

Никогда не подключался по SSH к удалённому серверу через Вим, но очень часто делаю это из-под VSCode. Не совсем понял, чем способ Ctl+Shift+P -> подключиться по ssh -> ввести имя пользователя и хост -> ввести кодовую фразу ключа менее удобен чем аналогичный, подозреваю, способ в Вим?

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

Всё же апельсины пишутся через А :)

Когда я только начинал знакомиться с Го, первое, о чемя подумал после прочтения о функции init, было "Вау! Тут же можно без каких-то костылей просто и беззастенчиво генерировать синглтоны!" Должен признаться, я с таким подходом знатно наговнокодил в своём первом коммерческом проекте на Го...

Ну, я описал собственные впечатления, в плане синтаксиса я бы вообще отдал предпочтение Lua.

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

Соль в том, что 99,9% ошибок никак не должны приводить к панике, они должны быть именно обработаны. Паника - это крайний случай, я её обычно вызываю только в функции main, если не завелось что-то очень критичное.

Информация

В рейтинге
Не участвует
Откуда
Железнодорожный (Московск.), Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Фулстек разработчик
Старший
SQL
PostgreSQL
Python
Linux
Docker
.NET Core
Golang
Tarantool
ClickHouse
FastAPI