Pull to refresh
31.91
Тензор
Разработчик системы Saby
Show first

Универсальные типы в python

Level of difficultyMedium
Reading time7 min
Views13K

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

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

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

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

Читать далее

Создаем кибер-разведку в компании на основе OSINT

Reading time10 min
Views27K

Привет ХАБР. Тема, которой посвящена эта статья с одной стороны важна, ведь в кибер-пространстве «неспокойно». Каждый день приходят новости, что ту или иную компанию взломали хакеры, получили дампы или зашифровали данные. Защищаться от кибер-угроз, выстраивая целую инфраструктуру из всевозможных средств защиты хорошо и нужно, но никогда не стоит забывать о разведке. В кибер-пространстве как в армии. Хорошо, когда на границах вырыты окопы, дежурит артиллерия и ПВО, но без разведки не понятно куда и чем противник будет атаковать. В цифровом мире базовая военная стратегия в целом не отличается. Разведка важна и нужна, чтобы быть готовыми и собирать данные, которые собирают злоумышленники о вас и вашей инфраструктуре. В этой статье разберем вопрос о том как создавалось направление кибер-разведки(OSINT open-source intelligence ) в компании.

С чего зародилась идея создания направления OSINT?

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

Путем расстановки приоритетов и реальных возможностей мы выделили основные направления для OSINT:

Читать далее

Эффективная FIFO-обработка для Node.js и Chrome

Reading time9 min
Views8.4K

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

В таких нагруженных системах, как коллектор нашего сервиса мониторинга PostgreSQL-серверов, создание и последующая подчистка Garbage Collector'ом подобных избыточных объектов и полей - непозволительная роскошь.

Но если внимательно посмотреть на эту схему, то можно заметить, что сами элементы очереди A, B, C линейно упорядочены. Так нельзя ли использовать в качестве очереди обычный массив с его .push() и .shift()?..

Насколько это будет эффективно, какие грабли встретятся на этом пути, и как их можно обойти - сегодня об этом.

Читать далее

Реверс-инжинирим структуру БД PostgreSQL по плану запроса к ней

Reading time4 min
Views5.6K

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

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

А ведь она уже и так находится "под ногами" в момент анализа плана запроса - надо только лишь удобно увидеть ее!

Читать далее

PostgreSQL Antipatterns: «где-то я тебя уже видел...»

Reading time4 min
Views23K

Иногда при анализе производительности запроса на предмет "куда ушло все время" возникает стойкое ощущение deja vu, что вот ровно этот же кусок плана ты уже где-то раньше видел...

Пролистываешь выше - и таки-да, вот он рядом - но почему он там оказался, и как выйти из Матрицы самому и помочь коллегам?

Читать далее

Разгоняем JS-парсер с помощью WebAssembly (часть 2: алгоритм и его оптимизации)

Reading time18 min
Views2.6K

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

Мы ведь теперь пишем "прямо на ассемблере" - значит, все будет супербыстро! Правда ведь?

Читать далее

SQL HowTo: ломаем мозг об дерево — упорядочиваем иерархию с рекурсией и без

Reading time10 min
Views9.5K
Видимо, это осень так влияет, что за последний месяц на PostgreSQL уже и в «Морской бой» играли, и «Жизнь» Конвея эмулировали… Что уж оставаться в стороне! Давайте и мы потренируем мозг в реализации нетривиальных алгоритмов на SQL.

Тем более, сегодняшняя тема родилась из обсуждения моей же статьи «PostgreSQL Antipatterns: «Бесконечность — не предел!», или Немного о рекурсии», где я показал, как можно заменить рекурсивное чтение иерархичных данных из таблицы на линейное.

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

Читать дальше →

Большие аппетиты маленьких Buffer в Node.js

Reading time4 min
Views4.6K
Я уже рассказывал про сервис мониторинга запросов к PostgreSQL, для которого мы реализовали онлайн-коллектор серверных логов, чья основная задача — одновременно принимать потоки логов сразу с большого количества хостов, быстро их разбирать на строки, группировать в пакеты по определенным правилам, обрабатывать и записывать результат в PostgreSQL-хранилище.



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

Мы погрузились в недра профайлера и обнаружили некоторые особенности работы с Buffer в Node.js, знание которых может сильно сэкономить ваше время и серверные ресурсы.
Читать дальше →

Создаем менеджмент уязвимостей(VM) в компании

Level of difficultyEasy
Reading time7 min
Views2.9K

Привет, Хабр! В этой статье поделюсь опытом и знаниями построения менеджмента уязвимостей в компании, ведь этот процесс, на мой взгляд, — базис информационной безопасности.

Почему VM важен?

Первый грейд (уровень) хакера начинается со Script Kiddy, то есть освоения навыка эксплуатации публичных уязвимостей с помощью эксплойтов, опубликованных как в открытом доступе (Metasploit, Github etc), так и в написанных самостоятельно.

Если вы спросите опытного пентестера (понятие «хакер» больше относится к незаконной деятельности), какие первые шаги он совершает в исследовании инфраструктуры на проникновение, то большая часть скажет, что проверяет объект на наличие публичных уязвимостей и возможность их проэксплуатировать. Это касается и внешней (опубликованной в интернете, например SMTP-сервера), и внутренней инфраструктуры (Active Directory). В среде пентестеров есть понятие «низко висящие фрукты» — это когда задачу по «пролому» цели можно выполнить очень быстро благодаря исследованным ранее уязвимостям и готовым эксплойтам. Как говорится, увидел PrintNightmare (CVE-2021-1675 и CVE-2021-34527) в инфраструктуре и захватил ее всю.

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

Читать далее

SQL HowTo: поиск «в ширину» внутри цикла (Advent of Code 2024, Day 10: Hoof It)

Level of difficultyEasy
Reading time6 min
Views1.9K

В этой челлендж-серии статей попробуем использовать PostgreSQL как среду для решения задач Advent of Code 2024.

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

В этой части снова сталкиваемся с вложенным в цикл рекурсивным поиском "в ширину".

Читать далее

Когда уверенность становится самонадеянностью: история одной фатальной ошибки

Level of difficultyEasy
Reading time6 min
Views4.4K

Привет, меня зовут Денис. Я учусь на 4 курсе Ярославского университета и работаю в Тензоре уже 1 год. Эта история о том, как за один день мой проект стал знаменит на всю компанию, а я получил колоссальный опыт и поседел в свои 21.

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

Спойлер: как вы уже поняли по названию, без ошибок не обошлось😅

Читать далее

Почта без хлопот: автоматизация отправки писем с помощью Python

Level of difficultyEasy
Reading time3 min
Views16K

Привет-привет! С вами снова Оля — программист Учебного центра компании «Тензор». Ранее я писала здесь о разработке ботов в Telegram, но в моем отделе не скупятся на творческие задачи — так что и эта статья вряд ли будет последней.

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

Читать далее

Приручаем многопоточность в Node.js (часть 5/5: автомасштабирование под нагрузку)

Reading time19 min
Views8.1K

В прошлых частях цикла мы:

- рассмотрели базовые концепты работы с многопоточностью в JavaScript на примере среды Node.js;

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

- использовали разделяемую память и Atomics-операции как самое быстрое средство обмена большими блоками данных;

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

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

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

Читать далее

SQL HowTo: обход дерева иерархии «по курсору» через двойную рекурсию

Reading time3 min
Views10K

В предыдущих статьях "PostgreSQL Antipatterns: навигация по реестру", "PostgreSQL 13: happy pagination WITH TIES" и "SQL HowTo: курсорный пейджинг с неподходящей сортировкой" я уже рассматривал проблемы навигации по данным, представленных в виде плоского реестра.

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

Читать далее

Upcoming events

SQL HowTo: «простое» прогнозирование

Reading time5 min
Views10K

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

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

Читать далее

Первый парсер на деревне

Reading time7 min
Views6K
Сегодня мы померяемся парсерами. Точнее, померяем эффективность разных вариантов JavaScript-парсеров на примере одной простой задачи преобразования строки конкретного формата в объект.


Вопросы сложностей организации многопоточности в JavaScript оставим за рамками этой статьи и сосредоточимся на различных вариантах и малоизвестных способах использования регулярных выражений для разбора строки buffers-атрибута узла плана PostgreSQL.

То есть из строки вида 'Buffers: shared hit=123 read=456, local hit=789' мы хотим как можно быстрее получить JSON такого формата:

{
  "shared-hit"  : 123
, "shared-read" : 456
, "local-hit"   : 789
}

Выглядит вроде все тривиально, правда же?

Читать дальше →

Фаззинг тестирование веб-интерфейса. Расшифровка доклада

Reading time7 min
Views7.2K


В начале этого года Тензор проводил митап в городе Иваново, на котором я выступил с докладом про эксперименты с фаззинг-тестированием интерфейса. Тут расшифровка этого доклада.

Когда обезьяны заменят всех QA? Можно ли отказаться от ручного тестирования и UI автотестов, заменив их фаззингом? Как будет выглядеть полная диаграмма состояний и переходов для простого TODO приложения? Пример реализации и о том, как работает такой фаззинг далее под катом.
Читать дальше →

Immutable Trie: найди то, не знаю что, но быстро, и не мусори

Reading time9 min
Views5.5K
Про префиксное дерево (Trie) написано немало, в том числе и на Хабре. Вот пример, как оно может выглядеть:


И даже реализаций в коде, в том числе на JavaScript, для него существует немало — от «каноничной» by John Resig и разных оптимизированных версий до серии модулей в NPM.

Зачем же нам понадобилось использовать его для сервиса по сбору и анализу планов PostgreSQL, да еще и «велосипедить» какую-то новую реализацию?..
Читать дальше →

Поддержка Touch в JavaScript

Reading time6 min
Views8.3K

image


Какие проблемы могут быть у frontend-программиста, если тестировщик запустит его приложение на iPad с новой трекпад-клавиатурой, Windows-планшете, с неопределенным состоянием “режима планшета” или ноутбуке с подключенным к нему телевизором c поддержкой Multi-touch?


Это далеко не полный список допустимых конфигураций оборудования, которые мы поддерживаем при разработке системы СБИС. Сегодня СБИС — это не только знакомое многим решение для сдачи отчетности, ведения электронного документооборота и бухгалтерии, но и набор инструментов для автоматизации розницы, общепита, доставки и логистики. В этих сферах нужно уметь хорошо работать на самых разных планшетах и гаджетах с различными экранами и типами устройств ввода. И далеко не всегда проблемы могут быть связаны с экзотическим сочетанием настроек операционных систем и драйверов: если взять обычный iPad с браузером Safari, Android планшет или ноутбук-трансформер на Windows10 с последней версией Google Chrome — везде будет свой набор ошибок и особенностей обработки пользовательского ввода.


Эта статья о том, как, а главное, зачем вводить в обычных Web приложениях режим поддержки Touch.

Читать дальше →

SQL HowTo: поиск пути и дихотомия (Advent of Code 2024, Day 18: RAM Run)

Level of difficultyEasy
Reading time8 min
Views1.2K

В этой челлендж-серии статей попробуем использовать PostgreSQL как среду для решения задач Advent of Code 2024.

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

Сегодня напишем для решения простую реализацию алгоритма Ли и дихотомии.

Читать далее

Information

Website
saby.ru
Registered
Founded
Employees
5,001–10,000 employees
Location
Россия