Ukfp

Книга: роман "Лунная пыль", Артур Кларк - фантастика

Нашел в подъезде оставленную книгу в которой было 3 фантастических произведения.
Одним из них был роман-катострофа "Лунная пыль". Я ее съел за день или два - затянуло также как и героев романа на лунном катере в провал из лунной пыли.

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

Очень понравилось - готов перечитывать по многу раз.

Ukfp

Книга: Стремись услышать Нет

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

Ты знаешь что в 8 из 10 раз тебе откажут, а нужно для спокойствия иметь хотя бы 5-6 вариантов, тогда для получения 5-6 ДА нам нужно услышать 40-48 НЕТ, а главное тут, что одно нет это лишь ступенька к цели и мы не останавливаемся пока не пройдем все. Да может быть и так что ДА мы услышим гораздо больше или еще меньше, но пока не получены все НЕТ - не останавливаться. Эдиссон в поисках своего варианта рабочей лапочки получил 10000 НЕТ до получения одного ДА, Дисней более 200 раз получал отказы на предложение построить парк развлечений Дисней Ленд, автор Гарри Поттера много раз получала отказ - издатели не верили, что это будет интересно читателям.

Мне это помогло в поиске работы в 2020 году!

Прослушал ее 03.2020

Серьёзно о главном

GoLang: Семантика типов в Go, что выбирать при объявлении типа и что использовать?

Нельзя было обойти вниманием эту статью "Design Philosophy On Data And Semantics" от Ardan Labs (06-2017)
https://www.ardanlabs.com/blog/2017/06/design-philosophy-on-data-and-semantics.html

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

Осмысленное создание и использование типов

  • Уже во время объявления типа решите какую семантику будете использовать при работе с ним (значиние или указатель)

  • Функции и методы должны уважать выбранную семантику типа

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

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

  • Избегай изменения семанитки для типа

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

Несколько конкретных примеров

Встроенные типы

Числовые, булевы, текстовые - по значению. Не используейте указатели на них, чтобы разделять значения пока у вас нет серьезной причины.
Пример из пакета strings:
func Replace(s, old, new string, n int) string

Ссылочные типы

slice, map, interface, function, channel - это ссылочные типы, скрывющие в своей реализации указатели. Их следует передавать по значнию, так как они были спроектированы, чтобы оставаться в стеке и снизить нагрузку на кучу (heap).

Пользовательские типы

Тут вы должны принимать решения сами, как написано выше.

Больше примеров в статье
Codded

Недавно слышал, что монолиты - эту будущее разработки программного обеспечения

Возможно вы встречали статью "I Just Heard That Monoliths Are The Future Of Software Development" опубликована 15.02.2020
Мне кажется её содержимое отлично продолжает пост "Микросервисы, не используй их пока...".

Многие купились пошли на поводу всяких модных словечек типа "микросервисы", мол что распиливание монолита на микросервисы решит все проблемы. Есть мнения что это не так: (1) "Monoliths are the future",  (2) "Monoliths Are the Future | Hacker News".


Что же стоит запомнить?

1) Монолиты - это будущее, потому что проблема, которую люди пытаются решить с помощью микросервисов, на самом деле не совпадает с реальностью.
Мы имеем дело с парадигмой ожидания против реальности. Большая часть этого может быть сведена к одному из них:
- Недостаток планирования, когда дело доходит до структуры сервиса
- Отсутствие опыта работы с распределенными архитектурами.
- Недостаток времени для тестирования и внедрения

Collapse )

Codded

Микросервисы - не используй их, пока...

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

Итак вот что еще удалось прочитать.

"Вам не нужна микросервисная архитектура" опубликовано 2017-05-25
Статья написана с позиции "адвоката дьявола" и о главных проблемах этого подхода.
Самое главное:
1) сложность, которая содержалась в большом и тяжелом монолитном приложении, никуда не ушла в тот момент, когда мы упростили код и вычленили всю логику в отдельные компоненты — теперь вся сложность, от которой мы избавились, прячется в зазоре между нашими сервисами — в том как они коммуницируют, как разворачиваются, как реагируют на изменения, и в других аспектах. Не стоит начинать новый проект с этого - за сиюминутный выигрыш в простоте кода, позднее придет расплата, которая может оказаться вам не по карману, если вы недостаточно опытны.
2) Если вы маленькая команда, и только начинаете, то — пишите обычные приложения — вам нужно бизнес развивать / удовлетворять, а не упражняться в элегантных архитектурах — если выживете, появится возможность какие-то фрагменты переписать “как надо”, а если вы вместо полезных фич будете всю дорогу бороться с инфраструктурными проблемами, то такого шанса может и не представиться.
3) Хотите иметь возможность переходить к сервисным архитектурам? Структурируйте внутреннее устройство вашего приложения, разбивайте его на компоненты, вычленяйте хорошие интерфейсы, библиотечные модули. См. архитектура на компонентах
Что стоит запомнить:
1) (Микро)Сервисы — это дорого не только с точки зрения самой разработки, как проектирования и написания кода — дорого с точки зрения поддержки, эксплуатации и отладки, внесения изменений. Настолько дорого, что процесс такой разработки может разорить небольшую компанию, или начинающий стартап.
2) Проблема 1 - еще одна точка отказа "Сеть" и дополнительная обработка сетевых ошибок (дополнительные ситуации о которых вы могли забыть или даже не знать). В вашу жизь войдут все категории сетевых проблем. Факт того, что все работает сегодня, совершенно не гарантирует, что оно так же будет работать завтра, если у вас нет полного контроля над сетью и тем, что в ней происходит (особенное если это в "облаках").
3) Проблема 2 - обработока удаленного вызова, это не тоже самое, что локальный вызов процедуры. Вот возникла у вас проблема при вызове, и что делать повторить вызов? А если вызов приводит к куче побочных эффектов в других сервисах, выставлению счетов и отправке уведомлений? Предстоит попотеть, чтобы после каждого такого эксцесса выяснить, что уже запущено в работу, а что нет и действовать исходя из полученной инфомации.
4) Проблема 3 - сложное и непредсказуемое интеграционное тестирование. Данные могут идти по цепочке сервисов, и по отдельности модульные тесты каждого сервиса проходят. Например сервис А получает данные от Б, а тот от В. Сервис Б умеет понимать разные форматы от В и отдавать результат вам в А. Тут вдруго поменяли форматы в В, тест пары Б-В проходит на тестовых данных, Б-А тоже проходит, то при прогоне А-Б-В тест не идет! А: не может обработать данные от Б полученные от В в новом формате. А не менялся, Б не менялся, но все сломалось. Решением может быть запуск всего набора сервисов и сквозного прогона типовых сценариев (это долго проводит и настраивать тоже). И В итоге запуская все вместе мы опять получили одно очень большое приложение...
5) Проблема 4 - развертывание усложняется, зависимости тоже. DevOPS инженеру придется несладно настраивая запуск нужных версий сервисов (особенно если у ваших протоколов нет версионности). Несколько версий сервится предьявляют взаимоисключающие требования к структуре БД с которой они работают - упс! Еще проблема.
6) Проблема 5 - мониторинг, сбор и анализ логов усложняется. Несколько экземпляров сервисов на разных машинах с разной аппаратной частью. Логи надо хранить централизовано, а если транспорт отказал, то складывать локально, а еще следить за доступностью сервисов (хранить результаты healthcheck в разные момоенты времени, чтобы знать кто был недоступен)
7) Проблема 6 - много точек входа API и на каждую свое описание, версионирование, авторизация, валидация и прочее...В одном приложении у вас одна точка публикации API и поддерживать нужно одну (ну две...позже).
8) Проблема 7 - разные люди проектируют API по разному, имея 100 сервисов имеете возможность 100 вариантов реализации и логики. И вам придется контролировать и сопровождать каждый API! Иногда придется вносить изменения в API нескольких сервисов для внесения измения в логику.
9) Проблема 8 - новая точка отказа, реестр сервисов / service locator. Ему нужна своя конфигурация для тестовой и рабочей среды.
10) Проблема 9 - рассинхронизация данных, когда несколько сервисов опираются на одно хранилище данных. В итоге можнет возникнуть конфликт на уровне структуры данных и придется их разносить.


"Microservices: don’t use them yet!" опубликовано 2019-12-26
Ситуация: ребята делали стартап командой в 3 инженера DevOps и 5 разработчиков (лид, 2 фронт, 2 бэк) и решили переделать лучше модно - микросервисами.
Что стоит запомнить:
1) Что у всех на слуху не обязательно подходит вам или что хорошо для Google вам может вообще не подойти (эти модные словечки AWS/Docker/Microservices)
2) Число микросервисов должно быть меньше числа их разработчиков. Разделяя традиционное монолитное приложение  мы делим его на независимые модули и обычно кладем в разные репозитарии - отлчно! Теперь мы можем получать ошибки из большего числа источников и еще больше скакать между ними (это плохо).
3) Разделили - класс. Только как теперь обратиться к общей бизнес логике, которая нужна нескольиким сервисам...о НЕТ! Нам нужен еще один сервис?! И нужно его тоже обернуть в REST/RPC и написать кучу кода поверх.
4) Раздувание набора рабочих инструментов - теперь нам нужно еще коечто модное, к тому что уже есть:  Docker, Express,Redis,Mysql,Kubernetes (kubectl),Swagger,React, Babel 6/7
5) Усложнение развертывания - теперь надо запустить запускать кучу сервисов и смотреть множество мест отказа (помните про наши 12 репозитариев ХаХА! - сказал пират)
Что поняли после разработки:
Можно было сделать иначе и проще:
- один репозитарий для всего, внутри каталог для исходников бекэнда и фронтэнда.
- общие правила для стилей кода, все тут.
- дать несколько репозитариев команде рисковать получить дублирование логики в разных репозитариях - и это хреново.
- пока у вас максимум 3 команды из 5 разрабочиков - не имеет смысла плодить множество репозитарев для частей бекэнда. Лучше пусть команда движется медленнее, но понимает код друг друга в этом репозитарии.

Накладные расходы микросервисов М.Фаулер 2015
Codded

GRPC: обработка ошибок на клиенте

Разрабатывая сервис на GO с GRPC встал вопрос при описании proto файлов "Нужно ли вносить описание ошибки приложения в ответ?". Изначально я так и сделал. Определил новый тип Error и добавил его первым полем во все ответы, получилось так:

message Error {
message Metadata {
string key = 1;
string value = 2
}
string code = 1; // код ошибки, константа
string message = 2; // сообщение об ошибке
string detail = 3; // дополнительные данные об ошибке, пояснения 
repeated Metadata meta = 4; // метаданные в виде ключ=значение
}
message ConfigStatusAnswer {
// Данные ошибки. Заполнено в случае ошибки выполнения запроса
Error error = 1;
// дата последнего изменения конфигурации
google.protobuf.Timestamp last_changed_time = 2;
// контрольная сумма конфигурации (опционально)
string checksum = 3;
}

Вроде бы логично. Но я решил все таки посмотреть, как это рекомендуют делать разработчики gRPC.
Оказалось они предлагают не вносить это информацию в каждый ответ, а вписывать ее в метаданные и оттуда клиент их должен достать. Меня интерисовало также как это будет выглядеть в коде на TypeScript, т.к. мы используем Improbable grpc-web для публикации API и он умеет работать с TypeScript. В нашем проекте один из клиентов это одностраничик (SPA) на Vuejs, похоже на это пример в статье "A TODO app using grpc-web and Vue.js (12.2018)"

Как же создавать ошибки на сервере (Go) и обрабатывать их на клиенте (TypeScript) тогда?

Collapse )
Codded

Visual Studio Code: мои настройки

Я начал исползовать Visual Studio Code, когда два года назад начал изучать язык программирования GO.
Сначала эта среда мне не очен понравилась, не было панели нструментов, кнопки Запустить, да еще и на 32 разрядной Windows нельзя установить отладчик для GO. Поработав в ней я привык и даже считаю ее удобной.
Конечно не все поддерживается из коробки, но расширения с успехом удовлетворяют дополнительные потребности.

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

Также классная вешь Zen Mode, когда редактор открывается в полный экран и скрывается все кроме кода, он отцентрирован посередине экрана - ничего не отвлекает.

Подключаю шрифт с лигатурами Fira Code. В настройках задать его:
"editor.fontFamily": "Fira Code",
"editor.fontLigatures": true


Я использую следующие расширения VS CodeCollapse )

Codded

GoLang: код, который растет с изяществом

Прочитал статью-презентацию Andrew Gerrand "Go: code that grows with grace" https://talks.golang.org/2012/chat.slide 2012 год

В ней даны примеры постепенного внесений нового функуионала в программу на GO. Как это можно делать без усложнения кода.
Примеры в основном затрагивают работу с сетью по TCP, HTTP, Websocket на примере приложения ЧатРулетка, где каждый подключившийся соединяется со следующим первым подключившимся.
В коде можно увидеть, как подключение к серверу сделано по TCP, HTTP, Websocket. Как одновременно в одном сервере можно обрабатывать сообщеия по TCP и WebSocket. Как интерфейсы упрощают переиспользование и работу с кодом разных классов. При этом показывается модель конкурентного исполнения при помощи горутин и взаимодействие через каналы. В примере даже добавляют чат бота на основе цепей Маркова, который будет выдавать фразы и отвечать, если к человеку не подсоединился партнер в течении заданного интервала времени.

Серьёзно о главном

GoLang: продвинутые техники для конкурентного программирования

Просмотрел видео "Google I/O 2013 - Advanced Go Concurrency Patterns" https://www.youtube.com/watch?v=QDDwwePbDtw
Что стоит запомнить и применить?

1. Техника  "цикл for-select"
2. Техника "Служебный канал, канал для ответа (chan chan error)"
3. Техника  "nil-каналы в выражениях select для временной приостановки"
4. Используйте инструменты для обнаружения состояния гонки данных (data race, флаг -race) и взаимоблокировок.

На видео описывется три ошбики к коде с конкурентным исполнением (1 - состояние гонки при обращении к данным / решение (канал с каналом для отчетов/ошибок), 2-приостановка цикла из-за Sleep / Решение (делаем задержку по готовности канала), 3-цикл может заблокироваться навсегда если нет данных в канале) и способы их решения приведенными техниками.

Также даны несколько техник улучшения работы главного цикла обработки:

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

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

  3. Как сделать основную процедуру получения данных неблокируемой (код в видео, создает канал для результатов, техника 2)

Collapse )