Микросервисы со Spring Boot. Часть 1. Начало работы

Это первая часть серии статей по основам микросервисных архитектур.
В ней вы познакомитеь с концепцией микросервисов и узнаете, как создавать микросервисы с помощью Spring Boot и Spring Cloud.

Это руководство поможет вам изучить основы микросервисных архитектур. Мы также начнем рассматривать базовую реализацию микросервиса со Spring Boot.

Мы создадим пару микросервисов и заставим их общаться друг с другом с помощью сервера имен Eureka (Eureka Naming Server) и Ribbon для балансировки нагрузки на стороне клиента.

Это статья входит в серию статей «Микросервисы со Spring Boot»:

  • Часть 1. Начало работы с архитектурой Microservices
  • Часть 2. Создание микросервиса Forex
  • Часть 3. Создание микросервиса конвертации валют
  • Часть 4. Использование Ribbon для балансировки нагрузки
  • Часть 5. Использование сервера имен Eureka

Вы изучите:

  • Что такое монолит?
  • Что такое микросервис?
  • Каковы проблемы с микросервисами?
  • Как Spring Boot и Spring Cloud облегчают разработку микросервисов?
  • Как реализовать балансировку нагрузки на стороне клиента с помощью Ribbon?
  • Как реализовать сервер имен (Eureka Naming Server)?
  • Как связать микросервисы с сервером имен и Ribbon?

Обзор ресурсов

В этом руководстве мы создадим ресурс для студентов, предоставляющий три сервиса с использованием соответствующих URI и методов HTTP:

  • Получить список всех студентов — @GetMapping("/students")
  • Получить информацию о конкретном студенте — @GetMapping("/students/{id}")
  • Удалить информацию о студенте — @DeleteMapping("/students/{id}")
  • Создать запись о новом студенте — @PostMapping("/students")
  • Обновить данные о студенте — @PutMapping("/students/{id}")

Обзор микросервисов — общая картина

В этой серии статей мы создадим два микросервиса:

  • Forex Service — сокращенно FS
  • Сервис конвертации валют (Currency Conversion Service) — сокращенно CCS

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

Форекс сервис

Форекс сервис (FS, Forex Service) является поставщиком услуг. Он предоставляет стоимость обмена валюты для различных валют. Давайте предположим, что он общается с Forex Exchange и предоставляет текущую стоимость обмена между валютами. Пример запроса и ответа показан ниже:

GET to http://localhost:8000/currency-exchange/from/EUR/to/INR 

{   id: 10002,   from: "EUR",   to: "INR",   conversionMultiple: 75,   port: 8000, }

Ответ на запрос выше является обменным курсом евро к INR. В ответе ConversionMultiple равно 75.

О поле port мы поговорим чуть позже.

Сервис конвертации валют

Сервис конвертации валют (CCS) может конвертировать множество валют в другую валюту. Он использует сервис Forex для получения текущих значений обмена валюты. CCS является потребителем услуг. Пример запроса и ответа показан ниже:

GET to http://localhost:8100/currency-converter/from/EUR/to/INR/quantity/10000

{   id: 10002,   from: "EUR",   to: "INR",   conversionMultiple: 75,   quantity: 10000,   totalCalculatedAmount: 750000,   port: 8000, } 

Запрос выше позволяет определить стоимость 10000 евро в индийских рупиях. TotalCalculatedAmount составляет 750000 INR. Диаграмма ниже показывает связь между CCS и FS.

Eureka Naming Server и Ribbon

В зависимости от нагрузки у нас может быть несколько экземпляров Сервиса конвертации валют и Сервиса Форекс.

И количество экземпляров для каждого сервиса может меняться со временем. На рисунке ниже показан конкретный пример, где созданы 5 экземпляров сервиса Forex.

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

В этой серии статей мы будем использовать Ribbon для балансировки нагрузки и сервер имен Eureka для регистрации всех микросервисов.

Что такое монолитное приложение?

Вы когда-нибудь работали в проекте

  • Который выпускается (запускается в производство) раз в несколько месяцев
  • Который имеет широкий спектр функций и возможностей
  • В которой работает команда из более чем 50 человек
  • Где проблемы отладки — большая проблема
  • Где привнесение новых технологий и новых процессов практически невозможно

Это типичные характеристики монолитных приложений.

Монолитные приложения обычно огромны — более 100 000 строк кода. В некоторых случаях даже более миллиона строк кода.

Монолиты характеризуются следующим:

  • Большой размер приложения
  • Длительные циклы выпуска
  • Большие команды

Типичные проблемы включают:

  • Проблемы масштабируемости
  • Принятие новых технологий
  • Новые процессы — Agile?
  • Сложно автоматизировать тесты
  • Трудно адаптироваться к современным практикам разработки
  • Трудно адаптироваться к быстрому росту проекта

Микросервисы

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

Небольшие автономные сервисы, которые работают совместно — Сэм Ньюман (Sam Newman)

Разработка отдельного приложения в виде набора небольших сервисов, каждый из которых работает в своем собственном процессе и взаимодействует с облегченными механизмами, часто API-интерфейсом HTTP-ресурсов. Эти сервисы построены на бизнес-возможностях и могут быть развернуты независимо с помощью полностью автоматизированного механизма развертывания. Существует минимальный уровень централизованного управления этими службами, которые могут быть написаны на разных языках программирования и использовать разные технологии хранения данных — Джеймс Льюис (James Lewis) и Мартин Фаулер (Martin Fowler)

Хотя для микросервисов нет единого принятого определения, имеется несколько важных характеристик:

  • REST — построен вокруг RESTful ресурсов. Связь между сервисами может быть на основе событий или протокола HTTP.
  • Небольшие хорошо выбранные развертываемые блоки — ограниченный контекст
  • Облачные возможности — динамическое масштабирование

Как выглядит микросервисная архитектура?

Вот так будет выглядеть монолит. Одно приложение для всего.

Так будет выглядеть то же приложение при разработке с использованием Microservices Architecture.

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

Преимущества микросервисов

Преимущества:

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

Проблемы микросервисных архитектур

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

Давайте рассмотрим некоторые из проблем:

  • Требуется быстрая настройка: вы не можете потратить месяц на настройку каждого микросервиса. Вы должны быть в состоянии быстро создавать микросервисы.
  • Автоматизация: поскольку вместо монолита есть ряд более мелких компонентов, вам необходимо автоматизировать все — сборки, развертывание, мониторинг и т. Д.
  • Видимость: теперь у вас есть несколько небольших компонентов для развертывания и обслуживания. Может быть, 100 или 1000 компонентов. Вы должны быть в состоянии отслеживать и определять проблемы автоматически. Вам нужна отличная видимость вокруг всех компонентов.
  • Ограниченный контекст: определение границ микросервиса — непростая задача. Ограниченный контекст из доменного дизайна — хорошая отправная точка. Ваше понимание домена развивается в течение определенного периода времени. Вы должны убедиться, что границы микросервиса развиваются.
  • Управление конфигурациями: вам необходимо поддерживать конфигурации для сотен компонентов в разных средах. Вам потребуется решение для управления конфигурацией
  • Динамическое увеличение и уменьшение: преимущества микросервисов будут реализованы только в том случае, если ваши приложения могут легко масштабироваться в облаке.
  • Колода карт: Если микросервис в нижней части цепочки вызовов выходит из строя, он может повлиять на все остальные микросервисы. Микросервисы должны быть отказоустойчивыми.
  • Отладка: Когда возникает проблема, требующая изучения, вам может понадобиться изучить несколько служб в разных компонентах. Централизованное ведение журнала и инструментальные панели необходимы для облегчения отладки проблем.
  • Согласованность: у вас не может быть широкого спектра инструментов, решающих одну и ту же проблему. Хотя важно стимулировать инновации, важно также иметь децентрализованное управление языками, платформами, технологиями и инструментами, используемыми для реализации / развертывания / мониторинга микросервисов.

Решения проблем микросервисных архитектур

Spring Boot

Spring Boot позволяет быстро создавать готовые приложения и предоставляет предоставляетследующие нефункциональные возможности:

  • встроенные серверы (простота развертывания с помощью контейнеров)
  • мониторинг метрик
  • мониторинг здоровья
  • внешняя конфигурация

Spring Cloud

Spring Cloud предоставляет решения для облачной активации ваших микросервисов. Он использует и основывается на некоторых облачных решениях, созданных компанией Netflix (Netflix OSS).

Важные модули Spring Cloud

  • Динамическое масштабирование вверх и вниз. Используя комбинацию:

— Сервера имен Eureka
— Ribbon (балансировка нагрузки на стороне клиента)
— Feign (упрощает разработку REST клиентов)

  • Видимость и мониторинг с:

— Распределенная трассировка Zipkin
— Netflix API шлюз

  • Управление конфигурацией с помощью Spring Cloud Config сервера
  • Отказоустойчивость с помощью Hystrix

В этой серии статей мы создадим два микросервиса:

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

  • Forex Service — сокращенно FS
  • Сервис конвертации валют (Currency Conversion Service) — сокращенно CCS

Диаграмма ниже показывает связь между CCS и FS. Мы установим связь между этими двумя компонентами.

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

И количество экземпляров для каждого сервиса может меняться со временем. На рисунке ниже показан конкретный пример, где созданы 5 экземпляров сервиса Forex.

Реализация решения для динамического масштабирования вверх и вниз требует ответа на два вопроса:

  • Как Служба конвертации валют (CCS) узнает, сколько экземпляров Forex Service (FS) активно?
  • Как Служба конвертации валют (CCS) распределяет нагрузку между активными экземплярами?

Поскольку мы хотим, чтобы это было динамичным, мы не можем жестко закодировать URL-адреса в сервисах FS в CCS. Вот почему мы вводим сервер имен.

Все экземпляры компонентов (CCS и FS) регистрируются на сервере имен Eureka. Когда FS должен вызвать CCS, он запросит Eureka Naming Server об активных экземплярах. Мы будем использовать Ribbon для балансировки нагрузки на стороне клиента между различными экземплярами FS.

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

Далее в этой серии статей:

  • Создание микросервиса Forex. Мы создадим простой REST сервис на основе Spring Boot Starter Web и Spring Boot Started JPA. Мы будем использовать Hibernate для реализации JPA и подключения к базе данных H2.
  • Создание сервиса конвертации валют CCS. Мы создадим простой REST сервис, используя Feign для вызова микросервиса Forex.
  • Использование Ribbon для балансировки нагрузки.
  • Внедрение Eureka Naming Service и подключение FS и CCS через Eureka.

ссылка на оригинал статьи https://habr.com/ru/post/484130/

Автоматная модель управления программ

1. Введение

В [1] был дан ответ на вопрос, что считать автоматным программированием (АП), но не была подробно описана модель конечного автомата (КА) в качестве модели управления автоматных программ. При этом понятно, что чистый абстрактный автомат на эту роль не годится, т.к. ограничен числом каналов. Но и структурная модель автомата, как и соответствующая ей теория структурных автоматов, не позволяют пока дать ответ по выбору модели автомата.

Проблема начинается с того, что среди множества работ по теории конечных автоматов (ТКА) мало дающих определение модели структурного конечного автомата (СКА). Правда, можно понять, что структурный автомат — это [структурная] схема из элементарных автоматов (функциональных элементов), реализующая модель абстрактного автомата [2]. Напомним, что в соответствии с теорией все начинается с создания модели устройства в форме абстрактного автомата, а затем ставится задача синтеза цифровой схемы, которая его реализует [3].

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

Правда, тут же закономерен вопрос — зачем еще один и довольно необычный «автоматный инструментарий»? На этот вопрос мы и попробуем ответить, дав определение модели [вложенного] автоматного управления, рассмотрев также ее преимущества по сравнению с обычной моделью программирования.

2. Определение модели управления автоматных программ

В процессе эволюции практика программирования сформировала определенные требования к модели управления программ. Необходимо признать, что модель классического конечного автомата довольно мало им соответствует. И если уж стоит задача использовать автоматы в программировании, то ее необходимо адаптировать. Сделать желательно это в рамках теории автоматов. Основные претензии к существующему АП сводятся к тому, что это условие нарушается.

Определение 1. Назовем дизъюнктивной нормальной формой конечных автоматов (ДНКА) полностью определенные конечные автоматы, переходы которых помечены элементарными конъюнкциями логических переменных.

Модель ДНКА базируется на формальных моделях полностью (вполне) определенных автоматов с абстрактным состоянием [4] и логических автоматов [5].

Определение 2. Назовем дизъюнктивной формой конечного автомата (ДКА) автомат в форме ДНКА, содержащий только результативные переходы.

К результативными переходами отнесем переходы, помеченные выходными сигналами и переходы с прочерком на месте выходных сигналов, изменяющие текущее состояние автомата. Переходы, которые не включены в описание дизъюнктивного автомата, составляют дополнение ДКА (ДДКА) до полностью определенного автомата ДНКА. Такое дополнение представляет автомат, состоящий из изолированных состояний с переходами в виде петель и с прочерками на месте выходных сигналов.

3. Модель памяти для модели вычислений АП

Наличие множества входов и выходов ДКА задает параллелизм сопоставленных им программных операторов/функций. Для его корректной реализации необходима модель памяти типа CREW (concurrent read exclusive – write) [6]. В ее рамках чтение текущих значений данных разрешено со стороны множества всех функций (предикатов и действий), а изменение общих данных для параллельно исполняемых действий разрешено только одному из них.

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

Взаимодействие операторов автоматной программы с памятью далее будем называть теневой моделью памяти. Данная модель является существенной частью общей модели автоматного программирования. Она гарантирует корректность параллельной работы операторов АП и упрощает программирование параллельных процессов.

В рамках модели памяти фактически не нужны сложные и не очень надежные механизмы многопоточной синхронизации работы процессов (подробнее см. [7]). Но в случае необходимости в силу эквивалентности автоматов и граф-схем алгоритмов (ГСА) [8] модель автоматного программирования не ограничивает и их применение.

4. Вложенная и инерционная модели автоматов

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

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

Простейшая модель единичной задержки в форме автомата Мили показана на рис. 1 (см. для сравнения модель задержки в [2]). Ее задержки определяются единичным дискретным тактом. Более сложные модели транспортных задержек (подробнее о типах задержек см. [9]) в форме автомата Мили и совмещенной модели Мили-Мура представлены соответственно на рис. 2а и рис. 2б.

image
Рис. 1. Модель единичной задержки в форме автомата Мили

image
Рис. 2. Модель транспортной задержки Мили(а) и Мили-Мура (б)

Входной сигнал x3 (напомним, в автоматной программе ему соответствует предикат [1]) принимает истинное значение при равенстве значения счетчика тактов значению переменной t, равной величине задержек t01или t10. Значение переменной t присваивают сигналы y3 и y4 (в программе — одноименные выходным сигналам функции-действия). Сигналы y1, y2 устанавливают значение переменной, представляющей выход модели. Сигнал y5 увеличивает счетчик тактов, который сбрасывается сигналом y6.

Замечание 2. Внутренние состояния модели на рис. 1 удобно ассоциировать с состоянием выхода элемента. Это позволяет исключить не только операторы y1 и y2, но и саму переменную выхода.

Реализация вложения автоматов аналогичного вызову подпрограмм формирует технологию модульного автоматного программирования. При этом на программном уровне, в отличие от аналогичных попыток на аппаратном уровне (см. для сравнения [10]), сделать это много проще. Для этого в действие нужно вставить программный вызов вложенного автомата, а затем ядро реализации автоматов подобно обычному процессору организует возврат управления на текущий уровень вложенности.

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

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

image
Рис. 3. Модель задержки в форме вложенных автоматов

На рис.3 показана модель задержки, где рис.3а представляет модель верхнего уровня, а рис.3б и рис. 3в – варианты вложенных автоматов для транспортной и инерционной задержки (подробнее о типах задержек см. [8]). Одновременно это примеры двух типов вложенных автоматов – обычного и инерционного. Тип вложенного автомата задается именем его заключительных состояний: состояние с именем «00» определяет обычный выход из вложенного автомата, а состояние с именем «ХХ» не изменяет текущее состояние автомата верхнего уровня.

Важное пояснение для понимания алгоритма работы инерционной задержки. Для нее (см. рис. 3в) значение предиката x1 зависит от перехода, на котором создан вложенный автомат. Другими словами, предикат в состоянии «0» контролирует сохранение «нуля» на входе, а в состоянии «1» наоборот — «единицы». Если значение на входе равно нулю при нулевом значении выхода, то нужно возвращать истинное значение. Далее, если стабильность входа нарушена (значение x1 равно false) и время задержки не истекло (значение x3 — false), то выход из вложенного автомата реализуется через инерционное состояние (см. рис. 3в).

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

У модели на рис.3а действие z1 (символ z выбран для имен действий, включающих вызов вложенного автомата) создает вложенный автомат в том случае, если определено значение задержки. В рамках этого действия определяется заданный тип задержки, в соответствии с которым создается один из вложенных автоматов, представленных на рис.3б или рис. 3в.

На верхнем уровне иерархии вид автомата рис.3а по структуре полностью совпадает с моделью на рис.1, отличаясь лишь наличием действий на переходах. Задержки с вложенными автоматами имеют более простой вид в сравнении с одноуровневой моделью на рис.2. Вложенный автомат может рассматриваться и как некий «библиотечный автомат», который может быть вызван из любого другого автомата.

3. Объектное автоматное программирование

Автоматная модель управления, кроме графической формы, имеет и простую табличную форму — таблицу переходов (ТП), которую можно эффективно интерпретировать на языке С++. В его рамках отдельную автоматную программу (или ее часть) и, соответственно, ее определение в форме схемы программы S можно представлять классом. В этом случае модели памяти будут соответствовать свойства класса, множеству операций – методы класса, а автоматное управление в форме ТП будет описывать поведения класса. Введение управления в класс позволяет говорить об активных объектах, называемых также часто агентами и т.п.

Множество объектов с поведением в форме автоматного управления формализует понятие объектной автоматной параллельной программы. В этом случае модель любой параллельной программы может быть представлено схемой программы, в которой управление C будет представлено в форме автоматной сети, где компонентные автоматы описывают поведение активных объектов, память M представлено объединением свойств объектов, а множество операторов A – объединением методов объектов программы.

В среде ВКПа роль языка автоматного программирования возложена на язык С++. В «автоматном С++» объекты наделены активностью/поведением и имеют средства описания и реализации параллелизма, как на уровне методов отдельных объектов, так и на уровне описания параллельной работы множества объектов.

Существующие объектные реализации АП довольно сложны. В ВКПа его объектная реализация базируется на интерпретации автоматов и выделенном управлении программы. В отличие от прямой реализации автоматов, используемой, например, в SWITH-технологии, это исключает процедуру преобразования модели автомата в модель блок-схем. Используемый в ВКПа алгоритм интерпретации аналогичен методу интерпретации таблиц решений Э. Хамби [12].

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

4. Выводы

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

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

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

Список литературы

1. Машина Тьюринга, как модель автоматных программ. [Электронный ресурс], Режим доступа: habr.com/ru/post/481998, свободный. Яз. рус. (дата обращения 07.01.2020).
2. КУДРЯВЦЕВ В.Б., АЛЕШИН С.В., ПОДКОЛЗИН А.С. Введение в теорию автоматов – М.: Наука. Гл. ред. физ.-мат. лит., 1985. – 320 с.
3. ГЛУШКОВ В.М. Синтез цифровых автоматов. М.: Физматгиз, 1962.
4. ЗАКРЕВСКИЙ А.Д. Логический синтез каскадных схем. – М.: Наука. Гл. ред. Физ.-мат. лит., 1981. – 416 с.
5. КУЗНЕЦОВ О.П. Графы логических автоматов и их преобразования // Автоматика и Телемеханика. – 1975. – №9.– С. 149-158.
6. Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ – М.: МЦНМО, 2001. – 960 с.
7. БУЧ Г., РАМБО ДЖ., ЯКОБСОН И. Язык UML. Руководство пользователя. Второе издание. Академия АЙТИ: Москва, 2007. – 493 с.
8. БАРАНОВ С.И. Синтез микропрограммных автоматов. – Л.: Энергия, 1979. – 232с.
9. АРМСТРОНГ ДЖ.Р. Моделирование цифровых систем на языке VHDL: Пер с англ./М.: Мир, 1992. – 175 с.
10. АМБАРЦУМЯН А.А., ЗАПОЛЬСКИХ Е.Н. Об одном подходе к временной декомпозиции автоматов. I, Автомат. и телемех., 1981, выпуск 2, 135-144
11. ШАЛЫТО А. А. Парадигма автоматного программирования. Научно-технический вестник Санкт-Петербургского государственного университета информационных технологий, механики и оптики. Вып. 53. Автоматное программирование. 2008, с. 3–23.
12. ХАМБИ Э. Программирование таблиц решений. М.: Мир, 1976. – 86 с.

ссылка на оригинал статьи https://habr.com/ru/post/484588/

Чтобы пацанам было не стыдно показать

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

Советы типа «писать красивый код», «хорошо комментировать свои доработки», «изучать современные фреймворки» — очень полезные, но, увы, второстепенные. Они идут прицепом к главному качеству программиста, которое надо в себе развивать.

Вот это главное качество: пытливый ум.

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

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

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

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

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

Как развивать пытливость ума? Ничего сложного. Я много лет назад придумал простую стратегию:
Чтобы пацанам было не стыдно показать.

Если ваше решение не стыдно показать пацанам, то оно – превосходно. Если вы копаетесь в проблеме до упора, и вам не стыдно об этом рассказать пацанам, то вы – красавчик.

Только не превращайте эту формулировку в девиз клуба анонимных алкоголиков. Если вы ни фига не разобрались, или написали говнокод, сдались на полпути, развесили сопли и устраиваете эмоциональный стриптиз типа «я такой тупой, и не боюсь в этом признаться!», выставляя свою никчемность напоказ и ожидая, что вас пожалеют – вы, увы, ни хрена не программист.

Вот вам пример. Недавно один стажер ковырялся с задачей в достаточно сложном механизме – и технически, и методически. Копался, как я понял, целый день. В основном сам, но просил помощи и у коллег. Кто-то из матёрых посоветовал ему лезть в отладчик. Под вечер стажер дополз до меня.

Я, если честно, думал, что стажер смотрит не там и видит не то, а мне придется копаться с самого начала. Корона давила, короче. А оказалось, что стажер в одном шаге от решения. Собственно, этот шаг я и помог ему сделать. Но главное не в этом.

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

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

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

Так что, господа стажеры и новички: ваши шансы – такие же, как у старожилов. Не смотрите, что у старого дяденьки много опыта и сертификатов – пытливость ума от этого не зависит.

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

Стратегия «чтобы пацанам было не стыдно показать» — очень проста и легко применима в любой момент. Остановитесь хоть сейчас, хоть через час, хоть через год и ответьте – то, что вы сделали, не стыдно пацанам показать? То, как вы старались и искали решение, не стыдно пацанам показать? То, как вы каждый день бьетесь над повышением своей эффективности, не стыдно пацанам показать?

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

ссылка на оригинал статьи https://habr.com/ru/post/484590/

Внешняя компонента для 1С Мобильной платформы(BroadcastReceiver)

Все сказанное в статье будет интересно исключительно разработчикам 1С.
Сегодня мы разберем внешнюю компоненту для «1С Мобильное приложение». Эта статья появилась по двум причинам. Разрабатывать будем все под тот же АТОЛ Smart.Lite

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

До этого у меня уже был опыт написания c++ внешних компонент. И даже есть шаблон под x86 платформу. Писалось вообще без понимания c++. Но тем не менее, в двух проектах работает, и не падает. Переходим к сути проблемы. Нужна нативная компонента для получения Broadcast сообщений в 1С. Пробежимся по интернету и поймем, что готовые решения есть. Но все они находятся на мной не очень любимом сайте, за черезмерную жадность. А платить за черный ящик я не хотел. Тем не менее там попалась отличная статья «Внешние компоненты мобильной платформы 1С для ОС Андроид». В ней описывается как слепить мобильную версию компоненты, и что надо установить. Как я понимаю вот здесь лежат исходники по мотивам которой и написана та самая статья. Огромное спасибо доброму человеку за труды. Очень помогло на живом примере понять что и как работает. Далее пришлось немного расширить свой кругозор как же работает JNI. Просто и понятно здесь и здесь. Рекомендую ознакомиться с ними. Уверен, что настоящим программистам c++ мой код не понравится. Прошу отнестись снисходительно и ткнуть, что можно улучшить и написать правильней.
Приступим. Я взял исходный код с репозитория который указывал раньше, и почти полностью его переделал под свои нужды. Взять можно здесь. Пробежимся по основным моментам. Главное процедурой у нас является startEventsWatch В ней мы проверяем, что у нас не подключен BroadcastReceiver и переопределяем функцию onReceive Там мы смотрим какое событие к нам пришло, заполняем поля, и вызываем функцию OnBroadcastReceive и вот она то и является связующей функцией между java и С++ и переносит нас из мира Android в мир 1С. Об этом чуть позже. Заветные строчки, что же мы хотим получать в 1С выглядят вот так.

filter.addAction("com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST"); filter.addAction(NEW_KEY_UP);

Здесь описывается, что мы ожидаем событие(action) от сканера. В моем случае это com.xcheng.scanner.... В вашем случае в зависимости от сканера, будет другая строка. Соответственно и данные внутри сообщения, тоже будут другими. Как правило эти данные можно получить у производителя ТСД. Ну или посмотреть в logcat. Еще я хотел получать коды нажатия аппаратных кнопок. Но проблема в лоб не решилась. Простое добавления onKeyUP в код и отправка этого в sendBroadcast успехом не увенчались. Оно и не удивительно, наша Activity не на переднем плане. По этой причине пришлось быстренько накидать AccessibilityService

startEventsWatch

  public void startEventsWatch()   {      if (m_Receiver==null)     {       m_Receiver = new BroadcastReceiver() {         @Override         public void onReceive(Context context, Intent intent) {           if (intent != null) {             String event, type, data;              switch (intent.getAction()) {               case "com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST":                 event = "NewBarcode";                 type = intent.getStringExtra("EXTRA_BARCODE_DECODING_SYMBOLE");                 data = intent.getStringExtra("EXTRA_BARCODE_DECODING_DATA");                 OnBroadcastReceive(m_V8Object, event, type, data);                 break;               case NEW_KEY_UP:                 event = "NewKeyUP";                 type = "key";                 data = intent.getStringExtra(KEY_CODE);                 OnBroadcastReceive(m_V8Object, event, type, data);             }           }         }       };        IntentFilter filter = new IntentFilter();       filter.addAction("com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST");       filter.addAction(NEW_KEY_UP);        m_Activity.registerReceiver(m_Receiver, filter);     }    } 

Теперь вернемся к нашей отправке данных в 1С. Наша OnBroadcastReceive вызывает процедуру extern "C" JNIEXPORT void JNICALL Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive(JNIEnv* env, jclass jClass, jlong pObject, jstring j_event, jstring j_type, jstring j_data) Вот здесь мы можем добавить переменные, с которыми хотим работать со стороны Java. jstring j_event, jstring j_type, jstring j_data Это переменные в которых я передаю, событие, тип ШК, и сам ШК. Могут быть и другие данные.

Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive

extern "C" JNIEXPORT void JNICALL Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive(JNIEnv* env, jclass jClass, jlong pObject, jstring j_event, jstring j_type, jstring j_data) { 	IAddInDefBaseEx *pAddIn = (IAddInDefBaseEx *) pObject; 	if (pAddIn != nullptr) { 		 		std::wstring ws_event =ToWStringJni(j_event); 		std::wstring ws_type = ToWStringJni(j_type); 		std::wstring ws_data = ToWStringJni(j_data);  		std::wstring obj_data{};  		obj_data = L"{\"type\": \"" + ws_type + L"\", \"data\": \"" + ws_data + L"\"}";	  		WcharWrapper wdata((wchar_t*)obj_data.c_str()); 		WcharWrapper wmsg((wchar_t*)ws_event.c_str());  		pAddIn->ExternalEvent(s_EventSource, wmsg, wdata); 	} }

std::wstring ws_event =ToWStringJni(j_event); Этим мы переводим строку из jstring в std::wstring, и потом это все запаковываем для 1С WcharWrapper wmsg((wchar_t*)ws_event.c_str());Спасибо умному человеку за функцию конвертации. Вторая функция идет из коробки в примере от 1С.

Заголовок спойлера

std::wstring ToWStringJni(jstring jstr) { 	std::wstring ret; 	if (jstr) 	{ 		JNIEnv* env = getJniEnv(); 		const jchar* jChars = env->GetStringChars(jstr, NULL); 		jsize jLen = env->GetStringLength(jstr); 		ret.assign(jChars, jChars + jLen); 		env->ReleaseStringChars(jstr, jChars); 	} 	return ret; }

Тем кто не хочет все устанавливать и сам компилировать. Вот готовые релизы.

На этом все. Жду комментариев.

ссылка на оригинал статьи https://habr.com/ru/post/479132/

Дайджест свежих материалов из мира фронтенда за последнюю неделю №398 (13 — 19 января 2020)

Предлагаем вашему вниманию подборку с ссылками на новые материалы из области фронтенда и около него.

Веб-разработка    |    CSS    |    JavaScript    |    Браузеры

Веб-разработка

habr 32 совета веб-разработчику, который хочет вырасти над собой в 2020 году
habr Выпущен «шрифт для разработчиков» JetBrains Mono
Новые форматы микроразметки Google за 2019 год
en Навигация в вебе с помощью геймпада
en Решение вопроса с элементом Section
en Вечные статьи для веб-разработчиков

CSS

habr Так когда же всё таки можно использовать !important?
en Эффект клика в стиле Material design с помощью pointer events и CSS Custom Properties
en Стоит ли хостить Google Fonts у себя?
en Продумывание вариантов стилизации для веб-компонентов
en CSS4 уже здесь!
en Как использовать селектор псевдо-класса :root в CSS
en Добавление разделителей в раскладки с CSS-in-JS

JavaScript

habr Ванильный JavaScript и HTML. Никаких фреймворков. Никаких библиотек. Никаких проблем
habr О 30-кратном увеличении параллелизма в Node.js
habr Бандлинг JavaScript-кода и производительность: передовые методики

Браузеры

На фоне реструктуризации из Mozilla уволено 70 сотрудников
Google намерен до 2022 года прекратить поддержку сторонних Cookie в Chrome
Как в новом Microsoft Edge установить расширения для Google Chrome
Chrome, вслед за Safari и Firefox, тоже начнёт блокировать сторонние cookie, но не сразу
Microsoft будет поддерживать Edge для Windows 7 не менее 18 месяцев
Разработчики Chromium предложили унифицировать и объявить устаревшим заголовок User-Agent
en В Chrome в течение двух лет планируют отключить поддержку сторонних cookies на сайтах
en Обновление до нового Microsoft Edge
en Как мы делали Picture-in-Picture в Firefox Desktop для большего контроля над видео

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

Дайджест за прошлую неделю.
Материал подготовили dersmoll и alekskorovin.

ссылка на оригинал статьи https://habr.com/ru/post/484592/