Pull to refresh
7
1.2
Виктор Поморцев @SpiderEkb

Консультант направления по разработке

Send message

А, спасибо, понял. Да, наверное, так сработает. Массив в два размера окна, а окно для обработки скользит внутри него. Теперь дошло :-)

Ок. А что будет когда элементов станет, скажем, 2001 и вам нужно обработать окно с 1002 по 2001?

Речь-то идет о непрерывном бесконечном потоке данных... Там могут быть миллионы и миллиарды элементов (допустим это какой-то датчик, работающий годами в режиме 24/7 с частотой 10Гц), но вас всегда интересуют только последние 999 из них. В каждый момент времени. Т.е. пришел 1 000 000 элемент - вам нужно обработать его и 998 элементов перед ним.

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

Ну вот идут данные, например, с какого-то АЦП. И при поступлении нового отчета вам нужно посчитать... Ну, положим, медиану по последним 999 отсчетам. Т.е. вам нужно помнить последние 999 значений и постоянно пересчитывать медианное для них.

Возможно, я просто не понял вашу мысль.

Не очень понятна мысль.

Кольцевые буфера (уж простите меня за привычную терминологию) применяются там, где нужно работать со скользящим окном из последних N элементов в непрерывном потоке данных.

И если вам так надо именно непрерывное расположение в памяти, то количество одновременно заполняемых массивов у вас должно быть равно размеру окна (и каждый массив будет равен размеру окна). Хорошо, если у вас размер окна определяется однозначным числом. А если трех-, или, не дай бог четырех- или пятизначным?

Тут мало что придется постоянно вычислять номер текущего окна, так еще и для каждого окна вычислять позицию для очередного элемента...

Сложность вычислений растет просто катастрофически...

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

индекс можно вычислить через целочисленное деление i=j%N

В том же С % - это не целочисленное деления, а остаток от целочисленного деления.

int a = 5, b = 4, c;

c = b / a; // Целочисленное деление - с = 0
c = b % a; // Остаток от целочисленного деления - с = 4

Мысль правильная, формулировка - нет.

И да. "Циклический массив" (он же "кольцевой буфер") вещь давно известная и столь же давно применяемая.

Мне не совсем понятна причина, по которой может потребоваться изменение контракта.

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

В этом случае старую функцию не надо трогать а делать новую.

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

Так что с контрактами проблем у нас нет.

Ну я уже описал наши процессы.

Кратко - есть некая система. Очень большая. Примерная оценка (не самая свежая) такова

  • 27 тыс. программных объектов

  • 15 тыс. таблиц и индексов базы данных

  • Более 150 программных комплексов

  • Занимает более 30 Терабайт дискового пространства

  • В день изменяется более 1,5 Терабайт информации в БД

  • За день выполняется более 100 млн. бизнес операций

  • Одновременно обслуживается более 10 тыс. процессов

  • За год происходит более 1100 изменений в алгоритмах программ

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

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

Не очень понятно что такое "релиз-цикл" в вашем понимании.

Порой складывается впечатление что говорим о радикально разных вещах и просто не понимаем друг друга.

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

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

При этом вся система в целом как работала, так и работает. Но в ней постоянно что-то меняется, развивается, оптимизируется.

И вот что тут считать релиз-циклом? Время TTM для одной поставки? Оно достаточно велико в силу жестких требований по тестированию (которое обычно занимает больше времени по сравнению с разработкой).

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

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

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

Вот как-то так все это работает.

Либо у вас все очень хорошо с автоматизацией,

О какой автоматизации речь?

не совсем правда

Я сужу по ежедневной рассылке "Что делаем" от сопровождения. Там, в том числе, список поставок которые сегодня внедряются на пром.

Бэклог у каждого разраба достаточно длинный. И обычно ведешь сразу 2-3 задачи. Одна уходит в тест, сразу делаешь вторую, третью. И тут длина "конвейера" никак не влияет на его производительность. То, что внедряется сегодня, разрабатывалось не вчера и не позавчера даже. А что будет внедряться завтра не сегодня делалось.

сколько девов в команде

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

Как пример - есть такая сущность как "дата актуализации данных клиента" (по простому - "дата актуализации", ДА). Есть таблица этих дат для каждого клиента. Таблица историческая - в ней содержится вся история актуализаций. Используется оно много где, но в большинстве случаев нужна текущая ДА. Та, у которой максимальное время изменения записи.

Был ретривер - задаешь клиента, получаешь текущую ДА.

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

Поскольку в основной таблице (как и во всех остальных основных таблицах) записи обновляются только через специальный update модуль, то ведение витрины не составляет проблем - просто модифицировали логику update модуля так, что при изменении ДА в основной таблице, он изменяет ее и в витрине.

Ну и ретривер переписали - теперь он не ищет по основной таблице, а просто берет запись по уникальному ключу из витрины.

Вкатили два модифицированных модуля (update + retrieve), запустили скрипт первоначального заполнения витрины и вуаля - всем кто пользуется этим параметром сразу стало лучше.

Все контракты сохранились, даже нет нужды смотреть кто и откуда его вызывает. Достаточно просто прогнать тесты самих модулей.

И такого сплошь и рядом. Сопровождение часто подкидывает "дефекты производительности" (объемы данных растут постоянно вместе с ростом количества клиентов - периодически выясняется что то, что раньше с запасом укладывалось в отведенное временное окно, сейчас перестало - нужно оптимизировать). И вот приходит что-то типа такого

"Коллеги, сервис *** за последние 5 недель увеличил потребление процессорных ресурсов в 3 раза!!!
Он уже является 2-м по величине сервисом после *****. В качестве альтернативы мы рассматриваем перенос запуска сервиса на резервный сервер, но там есть лаг по отставанию до 10 мин.
Заказчикам сервиса это может не понравиться :("

Смотрим узкие места, выявляем проблемный модуль, оптимизируем (часто это выливается в полное переписывание), тестируем, внедряемся и получаем

"Коллеги, доброе утро!
Спасибо!
Уже утром видим очень хороший результат!!!
Доработка сокращает потребление процессорных ресурсов почти в 10 раз!"

Иногда (если речь шла о каких-то ну очень критических вещах), после этого еще следует что-то типа такого:

Коллеги, добрый день

Вам сегодня должна прийти премия за особый вклад в развитие и оптимизацию нашей АБС, который сделан в рамках проекта *****, в части оптимизации процедур ****** в части комплаенс процедур и проверок (сокращение c 2 часов до 40 минут), ускорении процедуры *****, оптимизацию проверки ******

Ценим ваши усилия в этом и других направлениях вашей работы, неравнодушное отношение и подход!
Спасибо!

Это сверх регулярных бонусов, естественно.

И, повторюсь, речь всегда идет об отдельных модулях - небольшие программные объекты, которые можно тестировать (как вручную, так и автотестами) независимо от всего остального. И, соответственно, внедрять отдельно от всего остального. Главное - обратная совместимость контрактов. Это жесткое, но единственное требование.

И у нас всегда одна задача - одна поставка - один разработчик.

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

как часто вы релизитесь

Если говорить в целом по серверу, то 5-10 поставок ежедневно. Причем, поставка может содержать как 1-2, так и 10-15 объектов. У меня как-то была поставка из 180-ти объектов... Но это скорее исключение.

какой обьем регрессии ранят QA

Каждая поставка обязательно проходит полный цикл тестирования. Сначала первичное - в песочнице. Потом компонентное (в компонентных юнитах) - на соответствие FSD. Дальше идет бизнес-тест (на соответствие BRD) это уже другой юнит. Далее - интеграционное. Потом нагрузочное тестирование на копии промсреды. Заключительный этап - техтест на прелайв юните. И только после этого внедрение.

Любое изменение кода тащит за собой полный цикл тестирования. Это банк. АБС. Центральные сервера. Цена ошибки может исчисляться суммами с очень многими нулями.

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

Такое ощущение, что "против монолитов" специально придумываются примеры пострашнее.

В реальности же скорее все происходит как описал коллега @ErshoffPeter

Представьте себе монолит, который состоит из многих слабосвязанных между собою частей и ядро (модули, dll-ки, packages, наборы хранимых процедур - всё что угодно). Да и ядер может быть несколько. Вот и идут релизы хоть каждый день!

Мы тоже работаем с АБС

производители основных АБС сейчас так релизятся

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

Как пример. Есть команда системы расчетов (СР). В числе прочего у них есть сервис контроля платежей. И в нем есть проверки платежа по линии комплаенса. Которые уже делаем мы - команда автоматизации процессов комплаенс-контроля.

Как это реализуется? Есть "диспетчер проверок" - отдельный бинарник с функцией, которая будет вызываться из сервиса СР. Диспетчер получает на вход платежный документ, определяет параметры платежа и по ним принимает решение какие проверки, с какими параметрами и в каком порядке нужно применить к этому платежу. А потом вызывает каждую проверку (отдельный бинарник) в порядке очереди.

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

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

И так везде. Есть очереди - там есть движок, который читает из очереди сообщение, определяет его тип, по типу находит в настройках модуль-обработчик и передает сообщение ему. Нужно новое сообщение? Пишем обработчик (отдельный бинарник), прописываем в настройках движка и деплоим.

Аналогично журнальные мониторы. Есть движок который отследивает изменения в таблицах по системным журналам и вызывает соотв. мониторы по имени таблицы (опять по настройкам). Каждый монитор разрабатывается, отлаживается и деплоится отдельно. В деплой входит бинарник самого монитора + накат настроек в конфигурационные таблицы.

И все это никак не микросервисы. Но и монолитом, как таковым, не назовешь.

Согласен что в МКД все сложнее.

Но факт - любая вытяжка будет работать только при наличии притока. Так что есть у вас там вентилятор или нет - приток все равно нужен.

Мне проще - свой дом. Уже писал - канальник на малой скорости постоянно тянет через санузлы на улицу. Он тихий - его не слышно (расположен в санузле второго этажа над фальшпотолком). При превышении влажности включается на полную скорость (тогда его немного слышно, но не мешает).

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

Ни с влажностью, ни с запахами, ни со свежим воздухом в доме нет проблем - есть постоянный воздухообмен.

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

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

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

Когда строил дом, сразу подразумевал вентиляцию. Ориентировался на "полукратный воздухообмен" - полное замещение всего объема воздуха за два часа.

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

В качестве вентилятора выбран двухскоростной канальник TD-350/125 Silent от S&P. Там две обмотки обеспечивающие две скорости вращения крыльчатки. Производительность на первой 260м3/ч, на второй - 330м3/ч.

К нему два простейших контроллера влажности с Али - XH-W3005 и двухклавишный выключатель для ручного управления. Одна клавиша - вкл/выкл, вторая - первая/вторая скорости.

А дальше... Три релюшки (по две группы каждая) соединенные в нехитрую схему

Реле смонтированы в колодках на дин-рейке

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

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

Даже если вентилятор выключен (клавишей), от сигнала с контроллера влажности он все равно включится на вторую скорость (и потом выключится).

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

Все это работает вот уже три года. Никаких претензий нет - оно просто работает.

В спальнях и кабинете стоят КИВы Norvind Pro

Но это в основном на зиму. Летом просто окна открыты.

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

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

Я не помню, возможно уже были Б3-34. Но у меня не было, была предыдущая модель Б3-21. Тоже программируемая, чем отличались - не помню. Может памяти поменьше было, или еще что-то...

Не... Как-то не пересекаемся с ними. Очень далеки они от нашей кухни внутренней. На корпоративы не хожу, а тусовка у нас своя - CoreSystems DevConf - но это чисто про IBM i...

Да и там все молодые-креативные - "они художники, они так видят".

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

Даже не Москва :-) ФТФ УПИ (сейчас ФТИ УрФУ), кафедра молекулярной физики (изначально кафедра №23), 1982-1988. Две группы - "молекула первая" и "молекула вторая". У первой ФТ-0409 (разделение изотопов), в второй - ФТ-0311 (реакторы). Но это по вкладышу. В дипломе же у всего факультета "техническая физика"

Да, согласен. Причем, с каждым новым релизом все неудобнее и неудобнее.

Но это не в мой огород камень :-) Я пишу под центральные сервера (которые на IBM i работают). Все, что там на фронтах придумывают к нам приходит в виде очередного вебсервиса для которого мы делаем т.н. "сервис-модуль" на нашей стороне. И никаких интерфейсов (кроме небольшого количества чисто технических "опций", работающих в текстовом эмуляторе терминала IBM5250) у нас нет - >80% того что пишем вообще в фоновых заданиях (batch job) работает

А вообще мое направление - "автоматизация процессов комплаенс-контроля".

Одно из отличий РБМК (и вообще канальных реакторов с графитовой кладкой) от водно-водяных в том, что они позволяют не останавливать реактор на полную перезагрузку каждый раз, а до определенного момента делать частичную перезагрузку без остановки реактора.

Вообще, изначально, подобные реакторы делались как "промышленные" - для наработки оружейного Pu239.

Это был эксперимент с целью проверить "а насколько хватит до срабатывания САОР" - реактор все равно на перезагрузку нужно было останавливать.

Никто же не думал что САОР при этом отключат "на случай если вдруг не получится - мы быстренько подключим насосы и еще раз попробуем".

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

1
23 ...

Information

Rating
1,313-th
Location
Екатеринбург, Свердловская обл., Россия
Works in
Date of birth
Registered
Activity