Атомики в Go: особенности внутренней реализации

Атомики в Go — это один из методов синхронизации горутин. Они находятся в пакете стандартной библиотеки sync/atomic. Некоторые статьи сравнивают atomics с mutex, так как это примитивы синхронизации низкого уровня. Они предоставляют бенчмарки и сравнения по скорости, например Go: How to Reduce Lock Contention with the Atomic Package.

Однако важно понимать, что, хотя это примитивы синхронизации низкого уровня, они разные по своей сути. Прежде всего атомики являются «low-level atomic memory primitives», как отмечено в документации, то есть являются примитивами низкого уровня реализующими атомарные операции с памятью. В этой статье я расскажу про некоторые особенности их внутренней реализации и отличие от мьютексов.

Внутреннее устройство atomics

Давайте сначала возьмем пример из документации и рассмотрим операцию Swap:

The swap operation, implemented by the SwapT functions, is the atomic equivalent of:

old = *addr *addr = new return old

Под SwapT подразумеваются все Swap операции с различными типами данных. Для примера возьмем SwapInt64. Функция описана в sync/atomic/doc.go:

func SwapInt64(addr *int64, new int64) (old int64)

Однако ее реализация уже не на Go, а на ассемблере и находится в sync/atomic/asm.s:

TEXT ·SwapInt64(SB),NOSPLIT,$0 JMPruntime∕internal∕atomic·Xchg64(SB)

Однако здесь мы видим переход на другую функцию (простой jump) с именем Xchg64 и эта функция находится в рантайме Go. Тут мы уже можем видеть разделение по архитектурам процессоров.

Вот код для 64-bit Intel 386:

// uint64 Xchg64(ptr *uint64, new uint64) // Atomically: //old := *ptr; //*ptr = new; //return old; TEXT ·Xchg64(SB), NOSPLIT, $0-24 MOVQptr+0(FP), BX MOVQnew+8(FP), AX XCHGQAX, 0(BX) MOVQAX, ret+16(FP) RET

А этот для ARM 64:

// uint64 Xchg64(ptr *uint64, new uint64) // Atomically: //old := *ptr; //*ptr = new; //return old; TEXT ·Xchg64(SB), NOSPLIT, $0-24 MOVDptr+0(FP), R0 MOVDnew+8(FP), R1 MOVBUinternal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4 CBZ R4, load_store_loop SWPALDR1, (R0), R2 MOVDR2, ret+16(FP) RET load_store_loop: LDAXR(R0), R2 STLXRR1, (R0), R3 CBNZR3, load_store_loop MOVDR2, ret+16(FP) RET

Стоит здесь отметить, что Go использует свой язык ассемблера. Это сделано для компиляции под различные платформы и подробнее почитать об этом можно, например, здесь: A Quick Guide to Go’s Assembler. Важно отметить, что компилятор оперирует полуабстрактным набором инструкций (semi-abstract instruction set). Выбор инструкций происходит частично после генерации кода. Например, операция MOV в итоге может быть как отдельной операцией, так и может быть преобразована в набор инструкций и это будет зависеть от архитектуры процессора. Сам же язык основан на Plan 9 assembler.

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

package main  import ( "sync/atomic" )  func main() { var old, new int64 = 1, 10 println(old, new) new = atomic.SwapInt64(&old, new) println(old, new) }

Я использовал IDA64 для анализа бинарного файла, но советую посмотреть на дизассемблированный код в Compiler Explorer (можно выбирать разные архитектуры, версии Go и т.п.). Интересно также будет взглянуть на этапы компиляции, представления ast и применяемые оптимизации в Go SSA Playground. Теперь давайте найдем в дизассемблированном коде функцию main:

Код для new = atomic.SwapInt64(&old, new) располагается ровно после первого call runtime_printunlock и до следующего сall runtime_printlock

mov     ecx, 0Ah mov     rdx, [rsp+28h+var_10] xchg    rcx, [rdx] mov     [rsp+28h+var_18], rcx

У нас всего четыре инструкции: три mov и одна xchg. Дальнейший анализ затруднен, потому что количество тактов конкретной инструкции может зависеть от нескольких факторов, таких как модель и архитектура процессора, типы операндов (регистры, память) и некоторые другие условия (промах кеша, например). Если вам интересны более подробные расчеты и детали, то вы можете обратится к этому мануалу или к Intel® 64 and IA-32 Architectures Optimization Reference Manual (APPENDIX D. INSTRUCTION LATENCY AND THROUGHPUT).

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

Внутреннее устройство mutex

Мьютекс гораздо более комплексная структура по сравнению с atomic, чем может показаться на первый взгляд. Прежде всего у нас есть два вида мютексов: sync.Mutex и sync.RWMutex. У каждого из них есть методы Lock и Unlock, у RWMutex есть дополнительно метод RLock (блокирование для чтения). В обоих типах методы Lock довольно долгие по сравнению с атомиками.

У Mutex код метода Lock включает два вида блокировки. Первый вариант — это когда удается захватить не заблокированный мьютекс, второй вариант довольно долгий и он запускается если мьютекс заблокирован:

// Lock locks m. // If the lock is already in use, the calling goroutine // blocks until the mutex is available. func (m *Mutex) Lock() { // Fast path: grab unlocked mutex. if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { if race.Enabled { race.Acquire(unsafe.Pointer(m)) } return } // Slow path (outlined so that the fast path can be inlined) m.lockSlow() }

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

У RWMutex код метода Lock включает в себя вызов метода Lock структуры Mutex:

// Lock locks rw for writing. // If the lock is already locked for reading or writing, // Lock blocks until the lock is available. func (rw *RWMutex) Lock() { if race.Enabled { _ = rw.w.state race.Disable() } // First, resolve competition with other writers. rw.w.Lock()     //  Здесь пропущена часть кода ... } }

Да и сама структура RWMutex включает в себя структуру Mutex как одно из полей:

type RWMutex struct { w           Mutex  // held if there are pending writers     //  Здесь пропущена часть кода ... }

Метод RLock у RWMutex гораздо быстрее и содержит меньше кода, но тем не менее не быстрее атомика, который там задействован:

func (rw *RWMutex) RLock() {   //  Здесь пропущена часть кода ...   if atomic.AddInt32(&rw.readerCount, 1) < 0 { // A writer is pending, wait for it. runtime_SemacquireMutex(&rw.readerSem, false, 0)   }   //  Здесь пропущена часть кода ... }

Заключение

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


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

Пишем свою мини-СУБД на Golang (Часть 1)

Привет, Хабр! Создание небольшой системы управления базами данных — это всегда прекрасный опыт и способ почерпнуть новые знания или же, закрепить уже существующие навыки. В этом цикле статей мы попробуем собрать нашу небольшую СУБД с использованием стандартной библиотеки Go 😛

 Та самая инновационная СУБД

Та самая инновационная СУБД

Требования

Начнем с определения требований, которые мы хотим выдвинуть к нашей будущей СУБД (далее для позерства удобства будем называть ее repaDB). Здесь выделяют множество этапов, но если кратко это буквально несколько вопросов:

  • Зачем будем над этим работать?

  • Что будем делать?

  • Как это будем делать?

  • Какие у нас сроки?

Пойдем по порядку. Зачем мы будем над этим работать? Конечно же ради three hundred bucks бесценного опыта или школьного/студенческого проекта, но естественно, у больших дядечек, это будет «решить какую-то бизнес-задачу и, если получится, пополнить свой кошелек парой тройкой миллионов».

Тот самый друг-разработчик, который "ничего не получает"

Тот самый друг-разработчик, который «ничего не получает»

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

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

А теперь к следующему вопросу — Что будем делать? Здесь нужно понять, что именно мы (или наш big boss) хотим видеть в итоге от проекта. Наша цель — это хранить данные, в памяти, по принципу ключ-значение с неким TTL (ak Time to Live, ak время жизни). Любую цель можно достичь разными путями и наш случай не исключение. Так например, мы можем использовать уже готовое решение, либо же попросить кого-то написать за пачку дошика или *тут синоним к слову стащить*. Но мы с вами люди интеллигентные, поэтому будем писать своё собственное решение. Таким образом ответ на второй вопрос будет:

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

Определившись с тем что и зачем, перейдем к основополагающему вопросу — как это вообще сделать? Вопрос по истине уникальный и содержит в себе много подразделов, но мы с вами сделаем все на легке и не будем глубоко заходить в дебри проектирования. Перейдем сразу к примеру:

Наша СУБД должна уметь следующее: позволять подключаться по TCP, сохранять данные в память, безопасно их читать, обновлять, удалять данные и проверять существование некоторых ключей, а также иметь собственную библиотеку для удобства разработки (так как без этого будет сложно взаимодействовать с нашей базой данных, если вообще возможно). Все выше перечисленное — это бизнес требования.

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

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

Так же, все данные мы будем хранить в формате JSON на диске в виде файла, а также общаться с базой данных по TCP при помощи клиента, либо библиотеки для Go — это все уже не функциональные требования.

Ну и как итог, нам нет необходимости хранить сложные структуры такие как массивы, map’ы и т.д., и поэтому в качестве значения к ключу могут быть только типы данных string, bool и int. Это ограничения нашей системы.

Конечно, есть и последний вопрос — какие сроки? Но все мы понимаем, что это будет необходимость все сделать до «вчера» и отрефакторить когда-то потом. Так что мы не будем тут останавливаться надолго и перейдем к следующему разделу.

Структура проекта

Закончив с определением требований к нашему будущему must have решению, и потеряв по пути где-то этап с созданием ТЗ, мы переходим к структуре нашего будущего проекта. Это будет несколько репозиторием, т.е. все части проекта будут находиться в разных папках — модулях (а вы думали? у нас тут все по взрослому!). Каждый из модулей, будет основываться на стандартных принципах построения структуры go-приложения описанных вот тут.

Ниже список с описанием каждого модуля:

  • repa-dbздесь находится основной код нашей базы данных

  • repa-cliа тут находится код cli-клиента к нашей repaDB

  • repa-clientну, а тут соответственно код библиотеки для Golang

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

Заключение

На этом пока все. Это моя первая статья из цикла создания СУБД в которой я разобрал кратко создание требований к проекту и также кратко определил его структуру. Если есть замечания или вы хотите поделиться идеями? Буду рад почитать! Более подробно и с примерами кода можно будет ознакомиться позже.


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

Институт статистических исследований и экономики знаний НИУ ВШЭ ошибся при подсчете патентов российских IT-компаний

Исследователи Института статистических исследований и экономики знаний НИУ ВШЭ (Екатерина Стрельцова, Анастасия Нестеренко) в начале июня 2023 года представили рейтинг российских компаний по числу действующих патентов в сфере цифровых технологий.

Первое место занял Яндекс (411 документов, подтверждающих права на изобретения, полезные модели и промышленные образцы). В тройку лидеров вошли также Лаборатория Касперского (408 патентов) и Сбер со всеми дочерними организациями (305 патентов).

Источник

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

Яндекс имеет преимущественно патенты на изобретения (309 штук), 98 документов закрепляют права на промышленные образцы, 4 патента касаются полезных моделей. У Сбера иные подходы к работе: компания зарегистрировала 210 промышленных образцов, 91 изобретение и 4 полезные модели. Лаборатория Касперского практически все свои разработки (касающиеся преимущественно работы в сфере противодействия вирусам) оформляет как изобретения (406 штук).

Что касается всех остальных компаний, попавших в рейтинг, то, как подчеркивают ученые из ВШЭ, в десятку сильнейших также входят ИнфоТеКС (создатель сертифицированного программного обеспечения для информационной безопасности), Национальное радиотехническое бюро, ITV (ПО для систем безопасности), Smart Engines, ЭЛВИС-НеоТек, Vizex, InfoWatch и Супертел. 

Таким образом, резюмируют исследователи, национальными патентными IT-лидерами является «довольно узкая группа» субъектов: Яндекс, Лаборатория Касперского и Сбер имеют около 76% (!) действующих «цифровых» защитных документов на изобретения, почти 95% (!) — на промышленные образцы (подсчет ведется среди фирм, включенных в рейтинг). 

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

Об этом, кстати, говорят и власти. В Распоряжении Правительства Российской Федерации от 20.05.2023 № 1315-р сделан особый акцент на важности технологического суверенитета, предусматривающего не только запуск проектов нового сложного оборудования в разных сферах жизни, но и масштабное патентование создаваемых инноваций.

Ряд IT-корпораций (Ozon, Тинькофф и другие) вообще не попали в исследование: у многих из них, по мнению исследователей, нет действующих патентов на результаты изобретательской деятельности. 

Цитата: “Ряд крупных цифровых платформ и экосистем (Ozon, Wildberries, «ВКонтакте», «Авито», «Тинькофф» и др.) оказались за пределами группы лидеров. У многих на данный момент нет действующих патентов на результаты изобретательской деятельности, связанные с цифровыми технологиями”.

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

Но у Ozon (ООО “Интернет решения”) легко находится патент на полезную модель. А у Positive Technologies есть вот такой патент на изобретение. Вполне себе цифровые.   

У Ситроникса, который ни разу (!) не упоминается в исследовании можно найти аж 3 патента на изобретения, 2 на полезную модель и 1 на промышленный образец. Мы уверены, что у компаний, представленных на Хабре и не представленных в данном исследовании, есть хотя бы пара патентов в своем портфеле. 

Увы, патентный нигилизм — бич многих отечественных предприятий. Но это не значит, что патентов нет вовсе. Плохо искали.     

Это говорит нам о недобросовестно проведенном исследовании. Мы желаем коллегам из НИУ ВШЭ впредь более тщательно подходить к подобным исследованиям и не вводить в заблуждение представителей IT-сообщества. 

О сервисе Онлайн Патент

Онлайн Патент — цифровая система № 1 в рейтинге Роспатента. С 2013 года мы создаем уникальные LegalTech‑решения для защиты и управления интеллектуальной собственностью. Зарегистрируйтесь в сервисе Онлайн‑Патент и получите доступ к следующим услугам:

  • Онлайн‑регистрация программ, патентов на изобретение, товарных знаков, промышленного дизайна;

  • Подача заявки на внесение в реестр отечественного ПО;

  • Опции ускоренного оформления услуг;

  • Бесплатный поиск по базам патентов, программ, товарных знаков;

  • Мониторинги новых заявок по критериям;

  • Онлайн‑поддержку специалистов.

Больше статей, аналитики от экспертов и полезной информации о интеллектуальной собственности в России и мире ищите в нашем Телеграм‑канале.

Получите скидку в 1000 рублей на первый заказ. Подробнее в закрепленном посте


ссылка на оригинал статьи https://habr.com/ru/companies/onlinepatent/articles/745176/

Правильные тестовые данные или почему Вася Пупкин лучший друг тестировщиков?

Когда я был молодым…

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

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

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

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

В чем опасность рутины?

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

Пример ленивого и очень ленивого заполнения формы

Пример ленивого и очень ленивого заполнения формы

Что плохого в таком подходе? Деградация тестовых данных неизбежно приведет к деградации качества тестирования.

Почему это так? Что плохого в «Фывапр Йцукенг Павловна», если рассматривать это как тестовые данные?

Банальные примеры:

  • Если после регистрации на экране отображается уведомление об успешном прохождении процесса или после успешной авторизации в шапке выводятся полностью ФИО, то как понять, что строка со значениями ФИО не была обрезана внутри нашего «черного ящика»?

  • Если существует требование о четком порядке ФИО (во многих государственных АИС это жесткое правило), то как обнаружить ошибку, если разработчик сделает неправильный порядок? «Фывапр Йцукенг» и «Йцукенг Фывапр» с точки человеческого восприятия одинаковы, но с точки зрения выходных данных – это баг, который невозможно интуитивно обнаружить.

Таким образом, используя в качестве ФИО рандомные строки, вы сами стреляете себе в ногу.

Пример посерьезнее:

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

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

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

Кто же виноват?

Что же мешает каждый раз идти путем создания новых качественных данных? Ответ прост – лень. Как известно из исследований по нейробиологии, мы с трудом заставляем себя думать, когда речь идет о рутинных процессах. Подробнее об этом эффекте интересно написано в книге «Думай медленно… решай быстро» Даниэля Канемана. Автор так описывает закономерность умственной работы в любой сфере:

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

Наш мозг, как источник тестовых данных, с одной стороны является нашим союзником на короткие дистанции, а с другой — нашим врагом на длинные.

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

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

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

Источники правильных тестовых данных

Что такое «правильные» тестовые данные?

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

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

Вряд ли, отправляясь в ЗАГС для получения свидетельства для своей новорожденной дочери, вы выберите ей имя «Фывапр Йцукенг Павловна». Вряд ли вы назовете свою дочь мужским именем.
Вряд ли дата рождения персоны может быть более 100-110 лет.

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

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

Чем могут помочь открытые источники данных?

Как вы поняли, наш мозг — хороший источник тестовых данных, но обладает рядом недостатков.

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

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

  2. Биржи данных. Это площадки, где можно легально пробрести данные из различных предметных областей. Данные, как правильно, деперсонифицированы, но при этом наиболее близки к боевым. По своей сути такие данные являются целостной моделью реальных сущностей. Это их главный плюс. А минусы в том, что нужно платить за это, и они неизбежно будут устаревать. Такие данные можно использовать как при ручном тестировании, так и в автоматизированном. Например, наполнять ими заглушки, тестовые БД или использовать для генерации данных.

  3. Сервисы данных. По своей сути это веб-сайты, на которых можно сгенерировать данные нужного вам типа.

    Вот несколько примеров:

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

  4. Библиотеки генерации

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

    Например, JavaFaker. Эта библиотека с открытым кодом, которая имеет достаточно обширный набор предметных областей, для которых можно генерировать данные. Недостаток в том, что нет данных валидных для российских проектов. Например, в списке типов кредитных карт нет платежной системы МИР, да и вряд ли когда-нибудь будет.

    Типы генерируемых платежных систем в JavaFaker

    Типы генерируемых платежных систем в JavaFaker

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

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

Свой велосипед для данных!

pro.dagen.datageneratorhttps://github.com/upaul23/DataGenerator

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

Поскольку, по чистой случайности, автор статьи и автор библиотеки один тот же человек, то расскажу про нее чуть подробнее.

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

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

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

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

Ниже описание самой библиотеки:

Описание DataGenerator

Ниже текст из README самой библиотеки, в котором описан ее функционал.

DATAGENERATOR

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

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

Все реальные данные взяты из открытых источников и не нарушают права третьих лиц.

Методы генерации не являются идемпотентными, т.е. каждый последующий вызов метода будет возвращать уникальные данные. В качестве тезауруса используются списки, хранящиеся в тестовых файлах в папке resource/dictionary. Классы генераторов получают данные о расположении файлов из dagen.properties по соответствующим ключам.

Генерация данных происходит по алгоритму случайных выборок из тезауруса и комбинирования данных для создания сущности. Класс DataGenerator  – является точкой входа и содержит статические методы, для получения данных из соответствующих генераторов.

Библиотека генерирует следующие данные:

  • Персоны

  • Паспортные данные

  • СНИЛС

  • Расчетный счет банка

  • Банковские данные

  • ИНН для ФЛ

  • ИНН для ЮЛ

  • ОГРН для ЮЛ

  • Номер мобильного телефона

  • Номер городского телефона

  • Адрес электронной почты

  • Автомобильные гос. номера

  • Реквизиты банковских карт

Примеры использования:

//Персоны, отличные от Васи Пупкина FakePerson fakePerson = DataGenerator.persons().get(); FakePerson malePerson = DataGenerator.persons().get(Gender.MALE);  //Паспортные данные FakeRussianPassport fakeRussianPassport = DataGenerator.documents().passport();  //Банковский счет FakeAccount accountNumber = DataGenerator.accountDetails().account(   PersoneType.PERSON,   Currency.RUB,   ProfileType.COMMERCIAL,   DataGenerator.accountDetails().bank() );  //Почтовый адрес FakeAddress fakeAddress = DataGenerator.address().address();  //Банковская карта FakeCard fakeCard = DataGenerator.bankCard().card(   Banks.SBER,   CardType.MIR,   //Имя держателя карты. При генерации будет транслитерировано в латинские буквы   "Василий Пупкин" );  //Автомобильные гос. номера FakeCarStateNumber fakeCarStateNumber = DataGenerator.cars().stateNumber();  //Контакты FakePhoneNumber fakePhoneNumber = DataGenerator.contacts().mobile(); FakePhoneNumber fakePhoneNumber = DataGenerator.contacts().cityPhone(); String email = DataGenerator.contacts().email("test.ru");

Как подключить библиотеку?

Добавить в pom.xml вашего проекта, как зависимость:

<dependency>   <groupId>pro.dagen</groupId>   <artifactId>datagenerator</artifactId>   <version>1.2.0</version> </dependency>

Несмотря на то, что библиотека новая, ее код уже многие годы используется на реальном проекте. Не исключаю, что она может содержать некоторые проблемы и ошибки, которые еще не были найдены. Буду очень благодарен, если дадите конструктивную обратную связь или заведете тикет на улучшение в https://github.com/upaul23/DataGenerator.

Вместо заключения

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

на улучшение в https://github.com/upaul23/DataGenerator.


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

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

Связь между расстройством аутистического спектра (РАС) и «вторым мозгом» организма очевидна как никогда ранее

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

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

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

«До этого у нас был дым, указывающий на причастность микробиома к аутизму, а теперь у нас есть огонь», — говорит микробиолог Роб Найт из Калифорнийского университета в Сан-Диего.

Разработано новое лекарство, эффективное против нескольких видов рака

Японские исследователи разработали новый метод, который потенциально можно использовать для общего лечения нескольких видов рака с меньшим количеством негативных побочных эффектов, чем существующие в настоящее время методы. Результаты исследования, опубликованные 27 июня в журнале Chemical Science, показали, что опухоли у мышей выросли почти в три раза меньше, а выживаемость составила 100% после всего одной инъекции соединения, предназначенного для испускания небольшого количества альфа-излучения изнутри раковых клеток, что убивает их, но щадит здоровые ткани.

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

Астрономы обнаружили новый способ уничтожения звёзд

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

19 октября 2019 года астрономы определили источник именно такого события, названного GRB 191019A. Первым признаком был длительный гамма-всплеск, который продолжался около минуты (это долго по меркам гамма-всплесков, хотя есть свидетельства, что некоторые из них длятся гораздо дольше. Однако большинство из них длятся всего от нескольких секунд до нескольких микросекунд). Обсерватория Нила Герелса Свифта сразу же обнаружила его.

Умелец превратил пикап в водяной матричный принтер с помощью Raspberry Pi 4

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

Raspberry Pi отвечает за работу веб-интерфейса, принимает от пользователя новые сообщения и отправляет команду для запуска системы водяной печати. В данном случае Райдер решил использовать Raspberry Pi 4, но можно обойтись и более старой моделью, например, Raspberry Pi 3 B+ или даже Raspberry Pi Zero.

В видео Райдер описывает процесс проектирования и сборки проекта, который основывается на нескольких шлангах и клапанах. Соленоиды используются для выпуска воды по команде Raspberry Pi. Ведро с водой находится в задней части грузовика, соединённое с системой принтера, что позволяет легко перезаправлять его.


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