Скоро очередные длинные выходные, поэтому расскажу немного про доклад с кодфеста "Батарейки заряжены" от Дарьи Бородиной
Ее теория строится на 3 индикатора усталости/заряженности у человека - физический, умственный и эмоциональный. И если вы устали умом, то не стоит читать книги или заниматься образованием в этот момент. Или если устали физически, то в отпуске прыгать по горам не самое лучшее решение
Давайте теперь по скринам:
0. Начало
1. "Что я сейчас НЕ замечаю?"
Вопрос, который нужно задавать себе по будильнику каждый час, чтобы отвлекаться от работы. Нельзя быть погруженным в задачу постоянно 8 часов в день. Нужны постоянные разрядки.
2. Блокировщики
Не самое лучшее решение, но это программы, которые блокируют ваш экран по истечение какого то времени, и так по в цикле весь рабочий день. Но если у вас какой-то важнный созвон, то будет не очень приятно посреди звонка отвалиться)
3. Аудит календаря
Для меня тяжелое решение планировать что-то на будущее🤪 Но те кто умеют могут попробовать этот вариант. Нужно разбавить свой рабочий график всеми видами отдыха, чтобы восполнить свои индикаторы заряда
4-5. Сундучок ресурсов
Вы можете заполнить для себя такую схему, которая будет и шпаргалкой к календарю из 3 пункта, и без календаря вы будете знать чем заняться, когда накопилась усталость или пришло время отдохнуть. Тут градация по времени отдыха и по индикатору усталости. Рядом скрин с примерами вариантов отдыха по каждому типу и долготе)
6. Пример получения нужных вам гормонов из разного отдыха
Кстати, на канале Дарьи можно получить еще много советов и получить варианты для отдыха
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7⚡1🦄1
В CodeStrike вы играете за элитного агента, действующего в мире, захваченном ИИ и алчными корпорациями
— Пишите настоящий код Python, чтобы взламывать системы, сражаться, обезвреживать ловушки, участвовать в гонках и выживать в напряженных боевых миссиях
Разрабы обещают, что игра подойдет всем — как новичкам, так и экспертам
Ознакомиться — тут.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1 1
#конспект #SQL
Сегодня кратко (выходные ж завтра) про подготовительные знания для развертывания БД на посгре☕️
Если есть какие-то команды, которые используете часто тож пишите в каменты, я что-то знал, что-то добавил от себя еще в конспект выше1️⃣
Сегодня кратко (выходные ж завтра) про подготовительные знания для развертывания БД на посгре
Для доступа к серверу баз данных в комплект PostgreSQL входит интерактивный терминал psql. Для его запуска нужно ввести команду
psql
Для получения краткой справки по всем сервисным командам нужно ввести
\?
Многие такие команды начинаются с символов «\d». Например, для того чтобы просмотреть список всех таблиц и представлений (views), созданных в той базе данных, к которой вы сейчас подключены, введите команду
\dt
Если же вас интересует определение (попросту говоря, структура) какой-либо конкретной таблицы базы данных, например, students, нужно ввести команду
\d students
Для получения списка всех SQL-команд нужно выполнить команду
\h CREATE TABLE
Восстановление БД из sql файла
-f путь до файла
-U пользователь, который будет подключаться к БД
psql -f demo_small.sql -U postgres
Подключение к БД из терминала
-U имя пользователя
-h хост с БД
-d имя БД
psql -U postgres -h localhost -d demo
Если есть какие-то команды, которые используете часто тож пишите в каменты, я что-то знал, что-то добавил от себя еще в конспект выше
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤩2🦄2
За это время в
Расскажу в каком формате уже удалось поработать
Первая итерация:
Когда я только пришел в компанию в продукт ISIM тут была одна большая команда бэков и фронтов (девопсы, тестировщики отдельно). Было все спокойно и размерено - релизы 1-2 раза в год, общая "корзина" с багами и фичами, кто освобождался брал следующую.
Плюсы:
+ команда разработки знает все, что происходит - кто какой баг фиксит, а кто какую фичу делает и что вообще происходит.
Минусы:
- слишком чилловая обстановка🛁
Вторая итерация:
Появляется новый CTO, который делит всех на фича-команды, в которые входят: лид, 2-3 бэка, 1-2 фронта, 1-2 тестировщика. 2-х недельные спринты и за 2-3 спринта - релиз
Становится немного динамичнее и как-то даже жопа подгорает на дедлайнах
Плюсы:
+ разработка стала намного быстрее.
Минусы:
- разработчики изолированы от других команд
- могут быть конфликты мердж реквестов
- баги фиксить тяжелее, если они не из твоей командной фичи
Третья итерация (и по настоящее время):
Все поделены по специализации: бэкендеры, фронтендеры, тестировщики, ядро и т.д. Релизы немного "распухли" до 6-8 недель. Появились фича-оунеры.
Плюсы:
+ разработка стала более прозрачной, так как на дейликах каждый рассказывает что и где он делает и какие проблемы есть
+ немного разжало булки из-за увеличения сроков релизов
+ добавилась возможность роста, если берешь роль фича-оунера. Рулишь фичей и своей командой из бэка, фронта, ядра, тестирования
Минусы:
- ... пока не понял🤔
Если есть какие плюсовые или минусовые истории в работе в команде - напишите, чтобы обменяться, так сказать, опытом
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5 2🦄1
#конспект #SQL
Пропустим пару глав об основных командах создания таблиц и добавлении строк, а так же о типах переменных🥱
Перейдем к различным видам ограничений
CHECK
Это ограничение бывает двух видов: уровня атрибута и уровня таблицы. Различие между ними только в синтаксическом оформлении: в обоих случаях в выражении могут содержаться обращения не только к одному, но и к нескольким атрибутам таблицы
Можно придумать для них осмысленные имена, которые облегчат понимание причин появления сообщений об ошибках
NOT NULL
Означает, что в столбце таблицы, на который наложено это ограничение, должны обязательно присутствовать какие-либо определенные значения
UNIQUE
Такое ограничение, наложенное на конкретный столбец, означает, что все значения, содержащиеся в этом столбце в различных строках таблицы, должны быть уникальными, т. е. не должны повторяться. Ограничение уникальности может включать в себя и несколько столбцов. В этом случае уникальной должна быть уже комбинация их значений
Это ограничение можно было бы записать и так, дав ему осмысленное имя:
В следующем примере комбинация значений серии и номера документа, удостоверяющего личность, является уникальной. Поэтому можно модифицировать определение таблицы таким образом:
Первичный ключ PRIMARY KEY
Ключ может быть как простым, т. е. включать только один атрибут, так и составным, т. е. включать более одного атрибута.
При этом в отличие от уникального ключа, определяемого с помощью ограничения UNIQUE, атрибуты, входящие в состав первичного ключа, не могут иметь значений NULL. Таким образом, определение первичного ключа эквивалентно определению уникального ключа, дополненного ограничением NOT NULL. Однако не стоит в реальной работе заменять первичный ключ комбинацией ограничений UNIQUE и NOT NULL, поскольку теория баз данных требует наличия в каждой таблице именно первичного ключа
В случае создания составного первичного ключа имена столбцов, входящих в его состав, перечисляются в выражении PRIMARY KEY через запятую:
Внешний ключ FOREIGN KEY
Внешние ключи являются средством поддержания так называемой ссылочной целостности (referential integrity) между связанными таблицами.
Создать внешний ключ можно в формате ограничения уровня атрибута следующим образом:
Поскольку внешний ключ в нашем примере ссылается на первичный ключ, можно использовать сокращенную форму записи этого ограничения, не указывая список атрибутов:
Можно определить внешний ключ и в форме ограничения уровня таблицы:
Варианты удаления связанных записей из ссылающейся таблицы:
Пропустим пару глав об основных командах создания таблиц и добавлении строк, а так же о типах переменных
Перейдем к различным видам ограничений
CHECK
Это ограничение бывает двух видов: уровня атрибута и уровня таблицы. Различие между ними только в синтаксическом оформлении: в обоих случаях в выражении могут содержаться обращения не только к одному, но и к нескольким атрибутам таблицы
CREATE TABLE progress
( ...
term numeric( 1 ) CHECK ( term = 1 OR term = 2 ),
mark numeric( 1 ) CHECK ( mark >= 3 AND mark <= 5 ),
...
);
Можно придумать для них осмысленные имена, которые облегчат понимание причин появления сообщений об ошибках
CREATE TABLE progress
( ...
mark numeric( 1 ),
CONSTRAINT valid_mark CHECK ( mark >= 3 AND mark <= 5 ),
...
);
NOT NULL
Означает, что в столбце таблицы, на который наложено это ограничение, должны обязательно присутствовать какие-либо определенные значения
UNIQUE
Такое ограничение, наложенное на конкретный столбец, означает, что все значения, содержащиеся в этом столбце в различных строках таблицы, должны быть уникальными, т. е. не должны повторяться. Ограничение уникальности может включать в себя и несколько столбцов. В этом случае уникальной должна быть уже комбинация их значений
CREATE TABLE students
( record_book numeric( 5 ) UNIQUE,
...
);
Это ограничение можно было бы записать и так, дав ему осмысленное имя:
CREATE TABLE students
( record_book numeric( 5 ),
...
CONSTRAINT unique_record_book UNIQUE ( record_book ),
...
);
В следующем примере комбинация значений серии и номера документа, удостоверяющего личность, является уникальной. Поэтому можно модифицировать определение таблицы таким образом:
CREATE TABLE students
( ...
doc_ser numeric( 4 ),
doc_num numeric( 6 ),
...
CONSTRAINT unique_passport UNIQUE ( doc_ser, doc_num ),
...
);
Первичный ключ PRIMARY KEY
Ключ может быть как простым, т. е. включать только один атрибут, так и составным, т. е. включать более одного атрибута.
При этом в отличие от уникального ключа, определяемого с помощью ограничения UNIQUE, атрибуты, входящие в состав первичного ключа, не могут иметь значений NULL. Таким образом, определение первичного ключа эквивалентно определению уникального ключа, дополненного ограничением NOT NULL. Однако не стоит в реальной работе заменять первичный ключ комбинацией ограничений UNIQUE и NOT NULL, поскольку теория баз данных требует наличия в каждой таблице именно первичного ключа
CREATE TABLE students
( record_book numeric( 5 ) PRIMARY KEY,
...
);
В случае создания составного первичного ключа имена столбцов, входящих в его состав, перечисляются в выражении PRIMARY KEY через запятую:
PRIMARY KEY ( имя-столбца1, имя-столбца2, ...)
Внешний ключ FOREIGN KEY
Внешние ключи являются средством поддержания так называемой ссылочной целостности (referential integrity) между связанными таблицами.
Создать внешний ключ можно в формате ограничения уровня атрибута следующим образом:
CREATE TABLE progress
( record_book numeric( 5 ) REFERENCES students ( record_book ),
...
);
Поскольку внешний ключ в нашем примере ссылается на первичный ключ, можно использовать сокращенную форму записи этого ограничения, не указывая список атрибутов:
CREATE TABLE progress
( record_book numeric( 5 ) REFERENCES students,
...
);
Можно определить внешний ключ и в форме ограничения уровня таблицы:
CREATE TABLE progress
( record_book numeric( 5 ),
...
FOREIGN KEY ( record_book )
REFERENCES students ( record_book )
);
Варианты удаления связанных записей из ссылающейся таблицы:
ON DELETE CASCADE - при удалении записи на которую ссылаются записи из другой таблицы они будут так же удаленыON DELETE RESTRICT или ON DELETE NO ACTION - запрет удаления строки из таблицы А, если в таблице Б есть хотя бы одна строка, ссылающаяся на удаляемую строку в таблице АON DELETE SET NULL - присваивание атрибутам внешнего ключа в строках таблицы значения NULLON DELETE SET DEFAULT - присваивание атрибутам внешнего ключа в строках таблицы значения по умолчанию (DEFAULT), если оно, конечно, было предписано при создании таблицыPlease open Telegram to view this post
VIEW IN TELEGRAM
👍6🐳3🦄2
Я кое как уместил эту тему в один пост) Следующие темы уже будут углубляться в язык SQL и оптимизацию запросов. Будет и сложнее, и интереснее 😏
Please open Telegram to view this post
VIEW IN TELEGRAM
Надоели ежедневные новости и подборки очередного ИИ инструмента, но это стоит того (сам попробовал, скрин прилагаю
Встала у вас задача создать приложение или перестроить схему БД, а может вы уже это сделали, но хочется себя проверить?
Заходим в Database Build, пишем обычным человеческим языком о чем ваше приложение - получаем готовую схему и миграции, PROFIT!
Я вот на примере Fibonacci написал небольшой промпт и схема на 95% сходится с текущей
Можно править, генерить фейковые данные, импортить из CSV и деплоить в Supabase в один клик
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4🤩2🦄1
На прошлой неделе услышал фразу от нашего лида: "Если в компании работают по SOLID, то бегите с их собеседования". Но я же учил, что это основа всех приложений...
Решил узнать еще мнений и понять - почему так?
«У класса не должно быть более одной причины для изменения». Другими словами, у каждого класса должна быть только одна ответственность
class Calculate:
def add(a: int, b: int) -> int:
return a + b
def sub(a: int, b: int) -> int:
return a - b
Вроде бы ответственность у класса одна - вычислять, но тут 2 разных метода
На самом деле, этот принцип работает в моменте - что нужно от класса на данный момент (YAGNI). Но что, если через месяц бизнесу потребуется, чтобы мы добавили методы умножения и деления?...
«Программные объекты должны быть открыты для расширения, но закрыты для модификации»
class Operation(Protocol):
def compute(self, a: int, b: int) -> int:
...
class Add:
def compute(self, a: int, b: int) -> int:
return a + b
class Sub:
def compute(self, a: int, b: int) -> int:
return a - b
def calculate(op: Operation, a: int, b: int) -> int:
return op.compute(a, b)
Тут все ок, принцип открытости/закрытости соблюдается
Но приходит бизнес и говорит - в следующем релизе нужно добавить расчет отношения a от 100 и b от 100... Но у нас же уже сделан интерфейс с 2 аргументами, а теперь надо еще и с одним
«функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом»
class Animal(Protocol):
@staticmethod
def move() -> None:
...
class Mammal:
@staticmethod
def move() -> None:
print("walk")
class Fish:
@staticmethod
def move() -> None:
print("swim")
def how_it_move(animal: Animal) -> None:
animal.move()
Все опять по принципу
Опять же, в моменте можно сделать по требованию, но спланировать потребности на будущее - невозможно
«Программные сущности не должны зависеть от методов, которые они не используют»
class Animal(Protocol):
def move(self):
...
def eat(self):
...
def grow(self):
...
def reproduction(self):
...
Сделал ты такой по принципу класс, но тут вспоминаешь "есть же животные, которые не двигаются!" - делаешь отдельный класс для движимых животных с этим методом.
Приходит заказчик и просит добавить еще растения
grow и reproduction.Пользователи начинают строчить в техподдержку: "Почему вы не учитываете бесплодных животных???". Надо отделять метод
reproduction Насколько надо гибко настроить интерфейсы, чтобы все учесть сразу?
«Положитесь на абстракции, а не на что-то конкретное»
class Operation(Protocol):
@staticmethod
def compute(a: int, b: int) -> int:
...
@staticmethod
def name() -> str:
...
class Add:
@staticmethod
def compute(a: int, b: int) -> int:
return a + b
@staticmethod
def name() -> str:
return "Add"
def calculate(op: Operation, a: int, b: int) -> int:
print(f"Running {op.name}")
return op.compute(a, b)
Пример утрированный, но для понимания подойдет)
Наша программа должна запускаться на интерпретаторе от 3.6 и выше, так как f-строки поддерживаются только с этой версии. Но появляются заказчики, которые не могут обновиться, но хотят пользоваться и заплатить за наш продукт
Получается, мы должны предусмотреть использование и на старых версиях питона? А что, если этого никогда не случится, то мы нарушим YAGNI?
Все это написано по материалам изученным в интернетах и не является дискредитацией SOLID. Он упрощает разработку и систематизирует ее, но упарываться им не стоит 100%
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯4👍2🤔2🔥1
...спустя 3 года работы в IT. И даже не не хочется оправдываться онлайн курсами)
#конспект #SQL
Представления
Работая с SQL запросами я понимал, когда читал уже написанные или если задача была сложнее обычного селекта из одной таблицы, то я просто обращался к ИИ за помощью
Но какие же вещи я упускал и не понимал...
При работе с базами данных зачастую приходится многократно выполнять одни и те же запросы, которые могут быть весьма сложными и требовать обращения к нескольким таблицам. Чтобы избежать необходимости многократного формирования таких запросов, можно использовать так называемые представления (views).
CREATE VIEW имя-представления [ ( имя-столбца [, ...] ) ] AS запрос;
Теперь мы можем вместо написания сложного первоначального запроса обращаться непосредственно к представлению, как будто это обычная таблица.
SELECT * FROM имя-представления;
В отличие от таблиц, представления не содержат данных. При каждом обращении к представлению в команде SELECT данные выбираются из таблиц, на основе которых это представление создано.
СУБД PostgreSQL предлагает свое расширение команды CREATE VIEW, а именно — фразу OR REPLACE. Если представление уже существует, то можно его не удалять, а просто заменить новой версией. Однако нужно помнить о том, что при создании новой версии представления (без явного удаления старой с помощью команды DROP VIEW) должны оставаться неизменными имена столбцов представления. Если же вы хотите изменить имя хотя бы одного столбца, то сначала нужно удалить представление с помощью команды DROP VIEW, а уже затем создать его заново.
PostgreSQL предлагает свое расширение — так называемое материализованное представление. Упрощенный синтаксис команды CREATE MATERIALIZED VIEW, предназначенной для создания материализованных представлений, таков:
CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] имя-мат-представления
[ ( имя-столбца [, ...] ) ]
AS запрос
[ WITH [ NO ] DATA ];
В момент выполнения команды создания материализованного представления оно заполняется данными, но только если в команде не было фразы WITH NO DATA. Если же она была включена в команду, тогда в момент своего создания представление остается пустым, а для заполнения его данными нужно использовать команду REFRESH MATERIALIZED VIEW.
Материализованное представление очень похоже на обычную таблицу. Однако оно отличается от таблицы тем, что не только сохраняет данные, но также запоминает запрос, с помощью которого эти данные были собраны.
Если впоследствии вам потребуется обновить данные в материализованном представлении, то выполните команду
REFRESH MATERIALIZED VIEW имя-мат-представления;
Кстати, пишу конспекты уже прочитав книгу, поэтому пробегаюсь по ней вторым заходом и нахожу места, которые пропустил/не так понял. Полезное закрепление получается
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3🦄1
#кибербез
Он считается первым в истории кибероружием, которое нанесло масштабные разрушения в физическом мире (и да, это недопустимое событие).
Сетевой червь вмешивался в работу промышленного оборудования — программируемых логических контроллеров (ПЛК) Siemens и рабочих станций SCADA-системы Simatic WinCC.
Предполагается, что заражение происходило из-за внутренних нарушителей (через USB-накопители), так как системы завода были изолированы от внешнего мира. Используя четыре уязвимости нулевого дня в Windows, Stuxnet заражал устройства под управлением этой ОС. Затем он искал системы с установленным ПО для управления ПЛК Simatic Step7, а после этого модифицировал исполняемый код внутри контроллеров.
Stuxnet заставлял центрифуги вращаться с опасными колебаниями скорости, что приводило к их постепенному разрушению. В результате из строя было выведено около тысячи центрифуг.
После обнаружения Stuxnet:
• Microsoft выпустила экстренное обновление, закрывшее уязвимость в .lnk-файлах Windows. Позже были устранены и другие уязвимости, которые использовал сетевой червь.
• Siemens опубликовала руководство по обнаружению и устранению вредоноса. Производители ПЛК начали внедрять контроль целостности кода и системно подходить к защите промышленного ПО.
• Антивирусные компании выпустили обновления сигнатур и инструменты удаления Stuxnet.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍2🤯1🦄1
За последний год работодатели снизили размер премий или вообще перестали их выплачивать почти трети россиян, выяснили «Известия». Чаще всего на лишение бонусов жалуются менеджеры, айтишники и риелторы. На фоне повышения налогов и ключевой ставки у бизнеса не остается возможностей платить больше денег. Хотя дефицит кадров сохраняется, компании теперь привлекают и удерживают людей другими привилегиями — ДМС, обучением, корпоративными скидками и расширенным соцпакетом.
Ну, будем честны перед собой. Даже я, который любит всякие плюшки, кроме зарплаты, всё равно изначально иду работать за деньги
НО... Например с ДМСом я в год экономлю по 100-200к. О его наличии я спрашиваю на собесах в первую очередь. Обучение и конференции это тоже экономия (поменьше, но все же).
У меня есть знакомые, которым похрену на всю эту корпоративную жизнь, ценности и остальное, главное
Хотя, если бы мне платили 500к/наносек, то скорее всего все эти ДМСы, обучения и развлечения я делал бы себе сам
Please open Telegram to view this post
VIEW IN TELEGRAM
💯4 2👍1
#SQL #конспект
Я думал пропустить этот раздел, так как он небольшой и вроде как простой. Но я хочу чтобы он был обязательно в конспекте и я его запомнил👐
Схемы базы данных
Посмотреть список схем в базе данных можно так:
По дефолту в БД создается
Но что, если я создал схему для основного или частого использования? Каждый раз писать схему такое себе. Делаем так:
Теперь имя схемы писать не обязательно. Можно указать сразу несколько схем для поиска таблиц при обращении к ним:
ВАЖНО понимать, что так определяется очередность поиска таблиц по схемам - сначала таблица ищется в
Посмотреть текущие
Посмотреть имя текущей схемы:
Я думал пропустить этот раздел, так как он небольшой и вроде как простой. Но я хочу чтобы он был обязательно в конспекте и я его запомнил
Схемы базы данных
Схема — это логический фрагмент базы данных, в котором могут содержаться различные объекты: таблицы, представления, индексы и др. В базе данных обязательно есть хотя бы одна схема. При создании базы данных в ней автоматически создается схема с именем public.
В каждой базе данных может содержаться более одной схемы. Их имена должны быть уникальными в пределах конкретной базы данных. Имена объектов базы данных (таблиц, представлений, последовательностей и др.) должны быть уникальными в пределах конкретной схемы, но в разных схемах имена объектов могут повторяться. Таким образом, можно сказать, что схема образует так называемое пространство имен.
Посмотреть список схем в базе данных можно так:
\dn
Список схем
Имя | Владелец
----------+----------
bookings | postgres
public | postgres
(2 строки)
По дефолту в БД создается
public схема. После создания своей схемы к ней можно обратиться так:SELECT * FROM bookings.aircrafts;
Но что, если я создал схему для основного или частого использования? Каждый раз писать схему такое себе. Делаем так:
SET search_path = bookings;
Теперь имя схемы писать не обязательно. Можно указать сразу несколько схем для поиска таблиц при обращении к ним:
SET search_path = bookings, public;
ВАЖНО понимать, что так определяется очередность поиска таблиц по схемам - сначала таблица ищется в
bookings, потом в public.Посмотреть текущие
search_path:SHOW search_path;
search_path
-------------
bookings
(1 строка)
Посмотреть имя текущей схемы:
SELECT current_schema;
current_schema
----------------
bookings
(1 строка)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🦄1 1
Напомню, что хакатон это своеобразное ИТ соревнование между командами по реальной задаче от заказчика. То есть тут и нетворкинг, и реальный проект в портфолио
А тут намечается у нас в Новосибирске оффлайн хакатон, да еще и с такими организаторами и призами!
Двухдневное мероприятие от 2ГИС и ИТМО AI Talent Hub:
А еще, это шанс попасть и посмотреть красивый офис 2ГИС
Локация: офис 2ГИС
Время: 19 июля 11:30 – 20 июля 19:00
Регистрируйся или перешли тому самому студенту
Кстати, рега
_________________________________________
Напомню, что очень важно получать от вас обратную связь в виде реакций и комментариев. Исторически сложилось, что кроме обычных реакций:
Please open Telegram to view this post
VIEW IN TELEGRAM
🦄11⚡3👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣10🏆3 2