Давайте знакомиться) Меня зовут Макс Атыгаев. Я занимаюсь программированием всю сознательную жизнь) с юности и до сих пор)
Я пробовал Android разработку и даже выпустил пару приложений в Google Play, но потом понял что мир бекенда мне нравится больше.
Где-то в 2016 я открыл для себя Telegram и полюбил разработку ботов) Самый любимый проект - пересылка между групповым чатом в вк и групповым чатом в телеграм. То есть словно соединить два чата на разных сервисах в один)
Сейчас работаю в российской компании, в свободное от работы время веду канал на YouTube, RuTube, Telegram. В 2019 году начал консультировать и обучать людей программированию на Java.
Если у вас есть какие-нибудь вопросы к действующему разработчику то смело пишите) обсудим в комментах или сделаю отдельный пост)
"Я отказался от поддержки Mac OS. И никогда её не верну. Если мы делаем игру для Windows, мы и разрабатываем и компилируем её на винде. Без проблем. Для Линукса - врубаем виртуальную машину и компилируем на Линуксе. Готово. Знаете, что надо сделать на Маке? Это ужас. Сначала нам нужно добыть маковское железо. Это железо обычно стоит около 800 баксов, это ж Mac Mini. Затем покупаем лицензионные ключи, ключ обходится 100 долларов в год. Теперь нужно скомпилировать всю эту грёбаную фигню в Xcode. И если вы хоть что-то компилировали в Xcode - это говно собачье, я его ненавижу. Только после этого вы можете скомпилировать игру под Мак. Если игра сломается, тогда угадайте, что нужно сделать? А всё с самого начала. За ключ платить не надо, но нужно повторно его активировать, запихнуть в Xcode, и снова проделать ту же работу. И всё это - ради 0,02% от продаж [доля юзверей Mac OS от всех купивших игру]".
Что случилось с Intel? У Intel есть проблема с их микрокодом. Если вы не знаете, что такое микрокод, я дам вам самое простое объяснение. Представьте разные сектора на ЦП как маленькие здания, а микрокод указывает, куда и сколько электричества должно идти в каждое из зданий. Теперь представьте, что микрокод вместо этого направляет слишком много электричества в одну область, из-за чего здание выгорает и навсегда выходит из строя. Именно это и происходит. Оно сломано навсегда, и ваш ЦП постепенно деградирует со временем из-за этой проблемы. Они выпустят обновление в середине августа, в следующем месяце. Эта проблема существует начиная с 13-го поколения ЦП Intel. Если у вас Intel 13-го или 14-го поколения, потребляющий 65 ватт или больше, у вас есть эта проблема. И проблема может пока не проявляться на вашей машине, но она есть, и чем дольше вы будете использовать этот ЦП, тем хуже будет ситуация.
К чему обычно приводит такая практика и почему ситуация не меняется с годами?
Несмотря на многолетние предупреждения и настойчивые рекомендации экспертов, многие разработчики по-прежнему не могут избежать включения конфиденциальных данных в свой открытый код.
Проблема возникает из-за незрелых практик кодирования, когда разработчики встраивают ключи шифрования, токены безопасности, пароли и другие учётные данные непосредственно в исходный код, чтобы упростить разработку и облегчить программам доступ к базам данных или облачным сервисам. Тем не менее, такой подход делает программные продукты уязвимыми для внешних атак.
Так, ещё в далёком 2013 году одним из независимых исследователей безопасности было обнаружено, что обычный поиск в Интернете выявляет десятки учётных записей с открытыми данными. Один из таких уязвимых аккаунтов давал привилегированный доступ к репозиториям Chromium.org, где хранится исходный код одноимённого открытого браузера.
А в 2015 году компания Uber на собственном горьком опыте убедилась, насколько разрушительной может быть эта практика. Один или несколько разработчиков сервиса Ride в то время внедрили в исходный код проекта уникальный ключ безопасности, а затем без задней мысли опубликовали этот код на общедоступной странице GitHub. Когда хакеры обнаружили, что в коде содержится ключ, они скопировали его и использовали для доступа к внутренней базе данных Uber. Злоумышленникам тогда удалось похитить множество конфиденциальной информации, принадлежащей 50 тысячам водителей Uber.
На этой неделе исследователи из компании GitGuardian сообщили о нахождении почти 4000 уникальных секретов в 450 тысячах проектах, отправленных в PyPI, официальный репозиторий кода для языка программирования Python. В их числе были ключи к API Azure Active Directory, учётные данные GitHub OAuth, ключи Dropbox, учётные данные SSH и многие другие. Отмечается, что количество таких утечек лишь растёт с течением времени.
Исследование показывает, что утечки происходят в различных типах файлов, включая основные «.py»-файлы, файлы README и тестовые папки. Специалисты GitGuardian протестировали утечки и обнаружили, что 768 из них остаются активными, что дополнительно увеличивает риски.
Для безопасного доступа к базам данных и облачным ресурсам теперь существуют различные механизмы, такие как файлы «.env», хранимые в частных средах, вне открытых репозиториев кода, а также инструменты, такие как AWS Secrets Manager, Google Cloud’s Secret Manager или Azure Key Vault. Разработчики также могут использовать разнообразные сканеры для проверки кода на случайно включенные учётные данные перед его публикацией.
Исследование GitGuardian ограничивается PyPI, одним из многих открытых репозиториев, но нет оснований полагать, что проблема не распространена и в других репозиториях.
Это небольшое пособие для тех, кто решал стать разработчиком (программистом, кодировщиком), но не очень уверен в своих силах и способностей, да и желаниях тоже. Ходят устойчивые слухи, что сегодня (июнь 2024) ситуация для программистов на рынке труда в России выгодна для искателей работы. Это, действительно, так. Об этом мне поведала Начальник Управления по борьбе с персоналом Вера Ивановна.
***** С чего начать *****
Прежде чем погрузиться в бесконечный океан программирования, давайте, на берегу слегка пощупаем воду.
Проведите самодиагностику. Вам в школе нравилась математика? Вы любите играть в шахматы? Если ответили "да" на оба вопроса, скорее всего, программирование - это ваше дело.
Ну и, конечно, ваше личное желание. Если вы хотите писать длинные коды программ, погружаться в спагетти программного кода неизвестного программиста, который писал этот код десять лет назад, а теперь сбежал от ответственности, то это очень хорошо. Вы рождены, чтобы стать разработчиком, программистом.
Добро пожаловать в семью. У нас тут очень хорошо, комфортно. Наш девиз "Gens Una Sumas". Мы все помогаем друг другу как можем. Вы тоже вполне можете рассчитывать на такую помощь.
***** Javascript - начало всех начал *****
Давайте, начнем с языка Javascript (Джаваскрипт, Яваскрипт). Вообще, разных языков программирования очень много: Питон, PHP, C++, Java и т.д.
Javascript имеет то огромное преимущество перед другими языками программирования, что он уже есть в вашем телефоне, планшете, компьютере. Он встроен в любой браузер. Мы можете немедленно написать первую программу прямо сейчас.
Следуя старым добрым традициям, напишем первую программу в стиле вывода значения строки "Hello, World!"
Текст программы "Hello, World!"
console.log("Превед, Медвед!");
Скопируйте текст программы в буфер обмена, вставьте в консоль браузера (консоль открывается-закрывается по F12 или еще как-нибудь), нажмите "Enter".
Если вы ранее никогда не копипастели в консоль, то вполне возможно, консоль выдаст вам предупреждение.
Это важный момент. Браузер беспокоится о соблюдении простейших норм информационной безопасности. Не следует бездумно копипастить непонятный код, с интересом наблюдая, что из этого выйдет.
Текст программы "дважды два четыре"
let x=2
let y=2
console.log("x*y=", x*y);
Обратите внимание на интересную особенность языка Javascript: конец строки можно заканчивать символом ;, но можно и опускать.
Если все вы сделали правильно, то в консоли должна отобразиться информация, как на скриншоте ниже.
Теперь можно перейти к чуть более сложным задачам.
***** Факториал натурального числа *****
Факториал, - это число, умноженное на "себя минус один", затем на "себя минус два", и так далее до 1. Факториал n обозначается как n!
Текст программы "Факториал натурального числа"
function fact_fun(n) {
// делаем рекурсию только если n больше 1
if (n > 1) {
return n * fact_fun(n - 1);
}
else {
return 1;
};
//
}; // function fact_fun(n) {
//
В этой функции fact_fun интересно то, что она вызывает саму себя. Такой прием, когда функция вызывает сама себя, называется Рекурсия.
Чтобы стало совсем все понятно, попробуем визуализировать эту абстракцию с помощью картинки.
Посмотреть, как работает эта программа, и получить коды программ можно здесь.
Теперь переход к чуть более сложной программе.
***** Найти наибольшее число в массиве, являющееся полным квадратом *****
Описание работы алгоритма
*** 1 ***
Вводим несколько чисел из формы HTML, в нашем примере: 49, 64, 77, 25, 99.
Формируем массив:
temp_ar = [49,64,77,25,99];
*** 2 ***
Проходим циклом по этому массиву от нулевого элемента до последнего:
for (let x = 0; x < temp_ar.length; x++)
При проходе выполняем пункт 3.
*** 3 ***
Определяем, является ли текущий элемент полным квадратом с помощью специальной функции: is_int_cur_kv_fun(temp_ar[x])
Если текущий элемент является полным квадратом, выполняем пункт 4.
*** 4 ***
Проверяем, является ли текущий элемент большим по значению, чем max_int (изначально let max_int = null;)
if (temp_ar[x]>max_int)
Если больше, то фиксируем:
max_int = temp_ar[x];
*** 5 ***
Для данного набора чисел получаем результат 64, с такой расшифровкой:
1) 49 КВАДРАТ
2) 64 КВАДРАТ * Максимальный *
3) 77 НЕ квадрат
4) 25 КВАДРАТ
5) 99 НЕ квадрат
Посмотреть, как работает эта программа и получить коды программ можно здесь.
А здесь ограничимся скриншотом с этой страницы.
***** Для заданного числа N найти количество способов его записи в виде суммы положительных чисел *****
Для заданного числа N найти количество способов его записи в виде суммы положительных чисел (само число N также считать одной из форм записей такой суммы, т.е. N = N).
Эта задача популярна среди математиков. Например, герой рассказа Константина Оборотова "Осторожно, женщина!" использует эту задачу для объяснения, что такое математика.
Описание работы алгоритма
*** 1 ***
Получаем число над которым будем работать из формы HTML:
let task1_1 = jQuery('#task1_1').val();
*** 2 ***
Допустим, ввели число 4.
Разбиваем это число на массив temp_ar(4)[1,1,1,1]
Размерность массива temp_ar соответствует числу task1_1, все варианты разложения которого мы ищем.
*** 3 ***
Делаем цикл с условием while(temp_ar[0] < task1_1)
Т.е. проходим по циклу до тех пор, пока нулевой элемент массива temp_ar[0] не станет равным числу над которым работаем.
При этом значение числа task1_1 остается неизменным, а над массивом temp_ar проводим манипуляции, описанные далее
*** 4 ***
Проходим по массиву temp_ar от нулевого элемента до предпоследнего. При этом к минимальному элементу в текущем состоянии массива прибавляем 1
temp_ar[min1index] += 1;
*** 5 ***
При этом мы удаляем следующий элемент:
temp_ar.splice(min1index+1);
*** 6 ***
Дополняем массив необходимым количеством единиц на конце:
temp_ar.push(1);
Делаем это так, чтобы в любом текущем варианте состояния массива temp_ar, сумма его элементов всегда должна быть равна task1_1 (т.е. 4 в нашем примере)
*** 7 ***
После завершения основного цикла, временный массив temp_ar будет содержать единственный элемент, равный по значению числу task1_1
temp_ar: [4]
Всего для данного тестового примера получаем 5 вариантов:
1) 1+1+1+1=4
2) 2+1+1=4
3) 2+2=4
4) 3+1=4
5) 4=4
Посмотреть, как работает эта программа, и получить коды программ можно здесь.
А здесь ограничимся скриншотом с этой страницы.
Если вы догребли до этого места, если в процессе у вас появились идеи, как одну или несколько задач реализовать на вашем любимом языке программирования, значит, вы - разработчик. По меньшей мере, в душе.
Спасибо за внимание! Успехов в программировании, разработке и кодировании!
Знаете, что я обнаружил действительно интересного об СДВГ (синдроме дефицита внимания и гиперактивности)? Это то, как люди с СДВГ подходят к решению проблем и выполнению задач. Вот что меня действительно поразило: если вы дадите человеку с СДВГ страницу с домашним заданием, он, скорее всего, даже не притронется к ней. Но если вы предложите ему абсолютно такой же материал, но в форме игры, где после каждого вопроса он будет получать мгновенную обратную связь, он не только выполнит всё задание целиком, но и сделает это быстрее, чем человек без СДВГ. Это невероятно эффективно! Я всё чаще и чаще замечаю, что люди с СДВГ показывают потрясающие результаты, когда получают мгновенный отклик на каждое своё действие. А вот если им приходится ждать отложенной обратной связи, то, скорее всего, они вообще не возьмутся за дело. Поэтому, если у вас СДВГ, мой совет - превращайте всё в игру! Геймифицируйте все свои задачи, составляйте списки, начисляйте себе очки, одним словом - хакните сами себя.
Я считаю, что существует три основные формы еды: суп, сэндвич и Веллингтон. Все, что имеет слоистую, структурированную, плоскую форму, можно отнести к категории сэндвичей. Все, что представляет собой беспорядочную смесь ингредиентов, относится к категории супов. А вот все, что является капсулированным блюдом, можно назвать Веллингтоном. "Я уже не согласен с этой классификацией" [читает из чата] - это нормально. Но давайте рассмотрим некоторые примеры. "Карри - это сэндвич?". Карри - это суп. Рис - это суп. Хаотичная смесь ингредиентов. Лазанья - это сэндвич. Пицца -это сэндвич, так как у нее слоистая структура. Суши - это сэндвич. А вот человек - это Веллингтон. Да, вы правы.
Итак, хоть и планировал писать дневник из серии - сделал Х, сломал Y, починил Z.
Но в итоге все вылилось в три дня плохого настроения, хождение кругами по квартире и срыв злости на несчастной груше. Заклинило на этапе новой фичи, когда я понял что она тянет за собой десяток правок и добавлений. А потом посмотрел список будущих фичей необходимых для MVP. И с учетом рабочего графика ( графиков, ибо работ две ) понял что пару-тройку лет на это убью. И руки опустились.
Решил посмотреть, может сделать мобильную игрушку для тренировки, отработать процесс от и до. Полистал идеи, посмотрел свою идею, как ее в мобилу можно запихнуть. И понял что не хочу возиться с графикой, музыкой, раскруткой, деплоем в стим, разбором отзывов. Словно хочу написать, а дальше трава не расти. А дальше - больше. Понял что ни в одну из своих идей я играть не буду. Я на мобиле и так не играю вообще. А на компе изредка гонял танки и пару настолок ( вроде Colonize Mars или Сквозь века). И все. И тут заклинило окончательно. Выходит ничего из этих игр не хочу, а что хочу - очень надолго и теряю надежду увидеть хотя бы механику реализованной.
В общем пью кофе, работаю и пытаюсь про это не думать. Но каждую минуту возвращаюсь к тем идеям что накидал и думаю - а может попробовать все же сделать что-то крохотное?
Все началось с рабочей задачи по реализации весьма специфичной web-панели мониторинга и управления различным оборудованием, в которой нужно было получать данные и отправлять команды по разнообразным сценариям (периодический опрос, подписка на websocket-события, https-запросы и т.д.), а также выводить состояние и графики в реальном времени, динамически комбинируя различные источники данных в разных виджетах.
Кроме того, у панели было предусмотрено несколько настраиваемых режимов работы, которые переключались по запросу пользователя, что требовало массового управления маршрутами потоков данных внутри системы.
В первой итерации с использованием RxJS получилось много неструктурированного и сложно поддерживаемого кода, так как архитектура на RxJS вынуждала императивно описывать перестроение топологии при изменении правил маршрутизации «на лету». В нашем специфичном кейсе с динамическими виджетами это приводило к сайд-эффектам и сложностям в отладке. Кроме того, местами размывалась строгая типизация и мы лишались compile-time гарантий. Так появилась идея разработать собственное решение на основе альтернативной концепции — модели графа потоков данных.
В результате получившаяся модель продемонстрировала предсказуемое поведение и низкую связность компонентов, а кодовая база сократилась на ~30% и приобрела более декларативный вид. Убедившись в эффективности решения, мы решили оформить его в виде отдельной библиотеки с открытым исходным кодом — Transferum.
И что, получилась просто еще одна реактивная библиотека?
Не совсем. Классические FRP-библиотеки (RxJS, Bacon, Most) построены вокруг единственного примитива (Observable). Transferum же основан на композиции различных типов узлов с явно определенным поведением.
Каждый узел в графе потоков распространения данных явно декларирует свои способности: может ли он принимать данные через push, отдавать через pull, распространять полученный сигнал подписчикам, опрашивать источник, фильтровать, блокировать поток и т.д.
Объявленные узлом возможности являются одновременно флагами для использования в runtime и compile-time гарантиями наличия соответствующих методов, определяющих его поведение.
Ключевая идея: поведение системы описывается как композиция независимых возможностей, которые одновременно определяют тип, реализацию и правила взаимодействия.
Transferum предоставляет четыре слоя абстракции:
Трансферы — узлы графа (каналы, поллеры, мапперы, буферы, разветвители и концентраторы, реализации debounce, throttle, switchMap и т.д.).
Мосты — ребра графа — управляемые вентили между узлами с динамической маршрутизацией и гейтингом.
Операторы — stateless-трансформаторы и фильтры данных (используются трансферами, отвечающими за конвертацию данных).
Билдеры — fluent-конструкторы композитных трансферов из цепочек трансферов-примитивов.
Концептуальная и архитектурная основа — capability flags system. Каждый трансфер реализует CommunicationContractInterface — набор булевых флагов, определяющих его возможности.
Флаги isPushable, isPullable, isSubscribable, isGate и другие — это не просто свойства объекта. Это метаданные, которые:
Определяют TypeScript-интерфейс трансфера на этапе компиляции.
Управляют стратегией связывания с другими трансферами в рантайме (с помощью функции linkTransfers()).
Обеспечивают совместимость в билдерах без приведений типов.
Один набор флагов — три потребителя. Это единый источник истины для всей системы.
Когда флаг равен true, соответствующий метод входит в TypeScript-интерфейс трансфера. Это позволяет предоставлять трансфер пользователю вот так:
Transfer
// гомогенный трансфер: T -> [ Transfer ] -> T
Или вот так:
Transfer
// гетерогенный трансфер: TInput -> [ Transfer ] -> TOutput
Именно в таком формате типов фабрики в библиотеке возвращают трансферы. Например:
const pushChannel: Transfer;
const converter: Transfer;
// содержат методы push(), subscribe()
const manualBuffer: Transfer;
// содержит методы push(), pull(), trigger()
// trigger() в данном случае нужен, чтобы сделать запушенное значение
// доступным для чтения через pull()
const pollingProxy: Transfer
// содержит методы pull(), subscribe(), trigger(), activate(), deactivate(), toggle()
// может быть связан с pullable-источником благодаря поддержке поллинга
Эта «магия» работает в compile-time благодаря несколько замысловатой системе вычислимых типов:
Трансфер определяет своё поведение (push, pull, subscribe и др.), но никогда не ссылается и не проверяет класс другого трансфера. Он не знает, что является upstream или downstream — лишь выполняет свой контракт. Пользователь может создать свой трансфер, объявить и реализовать его возможности — и он органично и бесшовно впишется в экосистему.
2. Мосты не знают конкретных реализаций
Мост инспектирует capability flags, а не имена классов. Нет цепочки instanceof, нет переключения по имени класса. Любой output-трансфер может быть соединен с любым input-трансфером — при условии совместимости их флагов, о чем мы поговорим чуть ниже. Это применимо и к тем узлам, которые еще не существуют и будут созданы пользователем.
3. Значение undefined никогда не распространяется
В Transferum undefined означает «нет данных», а не «пустое значение». Оно подавляется на уровне внутренней реализации менеджера подписок — подписчики никогда не уведомляются с undefined. При этом для явных маркеров пустых значений можно использовать null. Мы сознательно пошли на этот компромисс, чтобы избежать runtime-оверхеда и сохранить нативную скорость работы на плотных потоках данных.
Связывание трансферов
Функция linkTransfers(lhs, rhs) соединяет output-трансфер (lhs) с input-трансфером (rhs) с автоматическим выбором стратегии связывания на основе возможностей этих трансферов:
Protocol-oriented design: механизм не спрашивает «какой это класс?» — он выясняет, какие у него есть возможности. Любая пара трансферов с совместимыми возможностями является linkable. Добавление нового класса трансфера требует только объявления его флагов и реализации соответствующих методов — как связать его с другим трансфером, связующий алгоритм разберется сам.
Синхронные и асинхронные трансферы сосуществуют и могут быть связаны между собой. linkTransfers() предпочитает sync-связывание, когда это возможно, а async-стратегии применяет только когда sync неприменим. Нет отдельного «асинхронного мира».
Поддержка backpressure
Ряд асинхронных трансферов (AsyncSinkTransfer, AsyncWriteTransfer, AsyncConvertTransfer, AsyncConditionTransfer) поддерживают необязательные поля в конфигурации: maxConcurrency, bufferSize и onBufferOverflow — для ограничения параллельных async-операций, очереди избыточных данных и graceful-обработки переполнения. По умолчанию — неограниченная обработка, без буферизации.
Локальная обработка ошибок
Transferum использует единую модель обработки ошибок для всех трансферов. Каждый трансфер, который может столкнуться с runtime-ошибкой, принимает опциональный onError-хэндлер в своей конфигурации.
А теперь — к примерам использования
Вот так можно просто и декларативно описать опрос и агрегирование данных из нескольких источников:
А вот как можно организовать динамический роутинг:
import {
createPushStoredChannelTransfer,
createBridgeMultiSelector,
createBridgeSelector,
createPassBridge,
} from 'transferum';
// Вариант 1. Выбор одного реципиента
const commandRouter = createBridgeSelector({
bridges: {
light: createPassBridge({ source: commandChannel, target: lightController, activated: false }),
thermostat: createPassBridge({ source: commandChannel, target: thermostatController, activated: false }),
lock: createPassBridge({ source: commandChannel, target: lockController, activated: false }),
},
initialKey: 'thermostat', // выбор по умолчанию
activated: true,
owned: true,
});
commandRouter.select('lock'); // выберем другой вариант
// Вариант 2. Выбор нескольких реципиентов
const loggersRouter = createBridgeMultiSelector({
bridges: {
prometheus: createPassBridge({ source: metricsChannel, target: prometheusWriter, activated: false }),
elk: createPassBridge({ source: metricsChannel, target: elkWriter, activated: false }),
sentry: createPassBridge({ source: metricsChannel, target: sentryWriter, activated: false }),
},
initialKeys: ['prometheus', 'elk'], // будут активированы по умолчанию
activated: true,
owned: true,
});
loggersRouter.check('elk'); // теперь выбраны все три
loggersRouter.uncheck('prometheus'); // выбраны elk, sentry
loggersRouter.select(['prometheus', 'sentry']); // выбраны prometheus, sentry
А вот пример c организацией игровой механики:
import {
createDebounceTransfer,
createConvertTransfer,
createMapOperator,
createBridgeSelector,
createPassBridge,
linkTransfers,
} from 'transferum';
// Источник: debounce нажатий клавиш (16ms ~ 1 кадр при 60 FPS)
const rawInputSource = createDebounceTransfer({ delay: 16 });
// Конвертер: KeyboardEvent -> код клавиши
const inputConverter = createConvertTransfer({
operator: createMapOperator((event) => event.code),
});
// Целевые системы-потребители пользовательских событий
const carSystem = { push: (cmd: string) => console.log(🚗 Car executing: ${cmd}) };
const planeSystem = { push: (cmd: string) => console.log(✈️ Plane executing: ${cmd}) };
const menuSystem = { push: (cmd: string) => console.log(📋 Menu processing: ${cmd}) };
// Роутер: динамическое переключение между игровыми контекстами
const gameplayRouter = createBridgeSelector({
bridges: {
driving: createPassBridge({ source: inputConverter, target: carSystem }),
flying: createPassBridge({ source: inputConverter, target: planeSystem }),
ui: createPassBridge({ source: inputConverter, target: menuSystem }),
},
initialKey: 'driving', // игрок начинает в машине
activated: true,
});
// Связывание источника с конвертером с автовыбором стратегии
linkTransfers(rawInputSource, inputConverter);
// Демонстрация:
// Игрок в машине нажимает "W"
rawInputSource.push(new KeyboardEvent('keydown', { code: 'KeyW' }));
// Через 16ms: 🚗 Car: KeyW
// ==================
// Переключаемся на самолёт
gameplayRouter.select('flying');
// Та же клавиша теперь управляет самолётом
rawInputSource.push(new KeyboardEvent('keydown', { code: 'KeyW' }));
// Через 16ms: ✈️ Plane: KeyW
Когда имеет смысл попробовать Transferum
Библиотека подойдет для:
TypeScript-first проектов — благодаря максимально строгой типизации и compile-time вычислению доступных методов любого трансфера на основе объявленных у него флагов возможностей.
Работы с pull-based источниками данных — polling API, датчиков, хранилищ с PollingProxy.
Смешанных sync/async пайплайнов — в единой модели без ручного преобразования.
Явного flow control — gates, bridges, selectors для runtime-маршрутизации.
Game development / IoT — frame-aligned tickers, idle polling, sensor aggregation.
Устойчивой обработки ошибок — локальная, non-fatal обработка: одна стадия не убивает пайплайн при условии переданного в конфиге обработчика ошибок, ничего не подавляется молча.
Результаты и планы
Библиотека уже используется в двух наших внутренних проектах и показывает свою эффективность. Код доступен на GitHub под лицензией MIT, библиотека не имеет внешних зависимостей и поставляется с подробной документацией (README + API Reference).
В одном из проектов граф состоит из ~80 узлов и стабильно обрабатывает несколько сотен событий в секунду без деградации. На основе этих данных в том числе рендерится 3D-сцена в Babylon.js со стабильным фреймрейтом ~60 FPS без микрофризов.
Тесты библиотеки покрывают не только отдельные трансферы, но и поведение системы в динамике: переподключение мостов, обработку ошибок в длинных асинхронных цепочках, а также разнообразные граничные случаи. Покрытие — 100%.
В дальнейшем планируем реализовать хуки и утилиты для более удобного и нативного использования Transferum с Vue и React. Если они окажутся в достаточной мере переиспользуемыми, оформим в отдельные пакеты-адаптеры.
Буду рад, если вы заглянете в репозиторий, попробуете библиотеку в деле и поделитесь замечаниями — обратная связь поможет сделать Transferum лучше.
P. S. Если вы сталкивались с похожими задачами и решили их как-то иначе — буду рад прочитать о вашем опыте в комментариях.
Перекурив и изучив что вообще на рынке мобильных, понял что очень сокращенная идея изначального проекта может жить.
Обрезав по максимуму идею, игровую систему - получилось ужать все до 3 экранов игрового процесса и несколько вложенных всплывашек. От игровой системы остались ошметки, многое костылями будет сделано.
А дальше я попробовал сделать в UE5 просто игру из одних менюшек. Никакого 3d или графония. Ужать удалось до ~400мб (?!) для windows 64bit
В UE4 ужалось до 00мб в windows 64bit.
С тоской посмотрел на всякие Game maker и Construct. Сильно проще, но там с объектами не очень хорошо ( четыре столпа ООП не существует в полном объеме).
Поэтому пошел смотреть Unity 2022. Ну, там собралось на ~70мб. Поэтому попробую на нем, заодно c# вспомню.
дизайн-концепт.
Маг прикован к своей башне, которая стоит в городе. визуал ( Маг связан некой черной щупальцей с домом и при перемещении она растет из его спины, словно он марионетка) . Он может посылать своих помощников в город или другие места за компонентами/заданиями.
Зрительно это как вид на город с башни. Фигурки помощников перемещаются по карте.
Помощники отличаются уровнем взаимодействия.
Некоторые быстрые, но просто передают записки. Некоторые медленные, но могут доставлять предметы. Каких-то горожане не любят, каких-то обожают.
Помощника можно лишится если репутация с местом куда послали низкая ( его убивают).
Выполнение заданий горожан или участие в событиях приводит к изменению рейтинга ( есть общий рейтинг города, а также отдельных персонажей/районов)
Чем выше рейтинг, тем ниже цены, больше обращений за помощью и вероятность предложения вещей на продажу вам.
При снижении рейтинга меньше продают компоненты и помощи. Достижении -Х рейтинга приводит к атаке на башню жителей/стражников. Это проигрыш.
Отказ в помощи проходящим караванам снижает рейтинг у них. Это порождает меньший поток посетителей + шанс ограбления башни или убийства героя.
Игровой процесс из трех частей: - Торговля в лавке. Диалог с приходящими покупателями\продавцами. - Лаборатория. Изготовление или разбор вещей, исследование заклинаний. - Карта города/мира. Запрос ресурсов/заданий с помощью помощников.
- Я потенциально хотел бы создать игру, но меня беспокоит то, что, пока я научусь делать игры, кто-нибудь уже додумается до такой же концепции и воплотит её в жизнь. Не окажется ли в таком случае, что время было потрачено зря?
- Нет. Потому что придумать идею - легко, реализовать - тяжело. Просто делай свою игру. Не беспокойся о том, что делают другие. Кому не похрен, что они там делают? Всё, что мы создаем - это все равно ремикс на ремикс. Так что делай свою игру. Делай её по-своему. Реализация главнее всего.
Ты не веришь в инопланетян? Давай посмотрим на это иначе. Многие из вас видели северное сияние. Оно происходит из-за электромагнитного поля вокруг Земли, которое защищает нас от космической радиации. У Солнца тоже есть своё электромагнитное поле, которое охватывает всю солнечную систему и также защищает нас. Радиация опасна для органической жизни. Так что нам делать, если мы хотим исследовать другие звездные системы? Мы уже начали это делать — отправляем роботов. Искусственный интеллект постоянно совершенствуется, и даже с простыми машинами мы можем создать системы, которые будут почти самовоспроизводящимися. Нужно лишь научить робота добывать и перерабатывать материалы для создания себе подобных. Создав сеть таких роботов, они смогут распространяться по галактике и передавать информацию обратно на Землю. Если инопланетяне посещают нас, то, скорее всего, это их зонды. Самое странное, что высока вероятность того, что органическая жизнь на их родной планете уже вымерла, и собранные данные больше никому не нужны.
Скорее всего, это история времен последних месяцев работы на Близзард, потому что именно в этой компании имело смысл просачиваться на работу через запасный вход, чтобы не встречаться с шеренгой менеджеров-культистов, дежурящих за главным входом.
"Итак, премся мы через чёрный вход, и эта женщина нам говорит: "У вас должны быть браслеты. Вам туда нельзя, при вас должны быть браслеты". И, я... Богом клянусь, это самое тупое, что я когда-либо пробовал провернуть. Я сделал джедайский жест и сказал: "Нам браслеты не нужны".
Затем я открыл дверь и всех запустил, а она стояла такая... Думаю, уверенность, которая от меня исходила, когда я исполнил этот жест, просто отключила её мозг, и она дала мне всех провести".
"В японском законе об авторском праве нет понятия "добросовестное использование". В Японии нет "добросовестного использования". Вообще. Не существует его. Исходя из этого... Если Нинтендо захочет поупражняться на вас в правовом преследовании - если вы из США или Европы или откуда угодно, - потому что в вашем продукте демонстрируется какая-нибудь заимствованная у них фигня, они имеют на это полное право. Потому что в Японии нет "добросовестного использования". Они могут вам помешать [реализовать ваш продукт]. И они много раз уже так делали. Возможно, вам покажется, что это некрасиво, но это в их силах. Так? Обычное дело. Вообще обычное дело. Теперь, имея это в виду, давайте представим, что Nintendo решили попреследовать Pocket Pair, типа: "Э, непорядок!"
[Pocket Pair - разработчики Palword, игры, концепция которой похожа на серию игр Pokemon от Нинтендо; Palword резко стал популярным и обрел большую базу недоброжелателей в соцсетях, которые пытаются заставить Нинтендо засудить Pocket Pair за использование ассетов Покемонов, только вот доказательств того, что они действительно видоизменили собственность Нинтендо, никто не может предоставить].
Ну, Pocket Pair открыто работали над этой игрой на протяжение трех лет. Они [Nintendo] ничего не предприняли. Теперь Pocket Pair выпустила эту игру и уже продала 5 миллионов копий. Они [Nintendo] все еще ничего не сделали. И вдобавок ко всему этому, вдобавок ко всему остальному, обе компании находятся в Японии, что означает, что это даже не международный процесс. Иск был бы подан в местный суд. Так что, если они [Nintendo] до сих пор этого не сделали, почему такой скулёж в Твиттере? Уверен, что Nintendo, одна из самых конфликтных игровых компаний в мире, разбирается в законах лучше, чем все эти диванные эксперты в Твиттере".
Представь, у тебя есть работа, которая платит определенную сумму денег. Затем ты получаешь повышение зарплаты. И ты думаешь: "О, классно! Теперь я могу купить более просторный дом, лучшую машину, крутой новый телефон". Но потом ты замечаешь: "Подождите, у меня не осталось свободных денег, несмотря на существенную прибавку к зарплате. Куда все делось?" Дело в том, что твои расходы выросли пропорционально новому уровню дохода. Всю жизнь, каждый раз когда мой "резервуар" становился больше, я старался не увеличивать свои траты. Если я и позволял себе большие расходы, то тщательно анализировал их необходимость. Потому что расширять свой образ жизни под новый уровень дохода - опасная стратегия. Если твой "резервуар" даст трещину из-за финансовых трудностей или понизится доход, но ты уже привык тратить все деньги, тебе придется очень сильно затянуть пояс. Это пугающая ситуация.
24 октября 2024 года в списке рассылки сообщества разработчиков Linux вышло официальное заявление разработчика «Байкал Электроникс» Сергея Сёмина по поводу исключения из списка мейнтейнеров Linux с темой "linux: прощание от волонтёра сообщества Linux".
Приветствую сообщество Linux-kernel, я уверен, что вы уже слышали новости, вызванные недавним коммитом Грега 6e90b675cf942e («MAINTAINERS: Remove some entrys due to various conform requirements»). Как вы могли заметить, изменение коснулось удаления некоторых разработчиков, связанных с Ru, из списка официальных сопровождающих ядра, включая меня.
Члены сообщества справедливо отметили, чтодовольнокороткий журнал коммитов содержал очень расплывчатые термины без явного обоснования изменений. Как бы я ни старался получить больше подробностей о причине, увы, старший сопровождающий, с которым я обсуждал этот вопрос, не дал объяснения, какие именно это были требования соответствия.
Я не буду приводить точный текст письма, так как это было личное сообщение, но ключевые слова - "санкции", "извините", "ничего не могу сделать", "поговорите с юристом вашей (компании)"...
Я не могу сказать за всех ребят, которых затронули изменения, но моя работа для сообщества была чистоволонтёрскойуже больше года (и до этого оплачивалось меньше половины). По этой причине у меня нет ни одного юриста (компании), с которым можно было бы поговорить, и, честно говоря, после того, как патч был объединён, я теперь не хочу этого делать.
Молча, за спиной у всех,обходястандартный процесс проверки патча, не уведомляя затронутых разработчиков/подсистем - это действительно худший способ сделать то, что было сделано. Никакой благодарности, никаких заслуг разработчикам за все эти годы преданной работы для сообщества. Независимо от причины ситуации, разве мы не заслужили большего? По крайней мере, добавить в файл CREDITS, нет?..
Я не могу поверить, что старшие сопровождающие ядра не учли, что патч не останется незамеченным, и ситуация может выйти из-под контроля с непредсказуемыми результатами для сообщества, если не сразу, то в среднесрочной или долгосрочной перспективе. Я уверен, что было много способов решить проблему менее пагубно, но они решили пойти по самому простому пути. Увы, что сделано, то сделано.
Точка бифуркации, слегка начатая год назад, только что была полностью реализована. Причина ситуации, очевидно, в политической почве, которая в данном случае, безусловно, разрушает фундамент, на котором изначально было построено сообщество. Если так, то Бог знает, что может быть дальше (кто ещё может быть санкционирован...), но реализованный шаг явно посылает плохой сигнал новичкам сообщества Linux, уже работающим волонтёрам и любителям вроде меня.
Даже если бы я все еще мог отправлять патчи или выполнять некоторые обзоры, после того, что было сделано, моя мотивация делать это как волонтёра просто исчезла. (Возможно, в будущем я займусь коммерческим апстримингом)
"Когда я работал в Близзард, у нас проводились тренинги по развитию сенситивности. И на этих тренингах по развитию сенситивности у нас было что-то типа семинаров, на которых нам показывали видео, и нам надо было решить, как было бы правильным поступить в данной ситуации. В общем, в одном из роликов парень в офисе влюбляется в девушку. К ней же подкатывает босс. И этот парень купил буррито в фудтраке, и он взял это буррито и бросил в босса. Просто швырнул его в видео. И на этом видео заканчивается. Типа, как парню следовало поступить? Что он сделал не так? Я такой: ну, может, не бросаться буррито. XD Так в офисе появился мем: всё, что может подвести тебя под увольнение, теперь звалось "кидаться буррито". Типа, если кто-то учудил что-то не шибко умное - о боги, этот пацан бросил буррито. Срань господня!"
Вот почему не стоит использовать яды против насекомых: они мастера химической защиты. Их тела устроены так, как будто они носят крошечные скафандры. Эти скафандры помогают им удерживать влагу и защищаться от химикатов и других вредных веществ. Поэтому использование ядов неэффективно, потому что насекомые со временем приспосабливаются к ним. Так происходит, например, с Raid — производителям приходится постоянно улучшать формулу, потому что насекомые становятся устойчивыми к ней. Вместо ядов лучше использовать физические раздражители. Физические раздражители — это то, с чем столкнулись наши астронавты на Луне. Лунная пыль, из-за отсутствия эрозии, оказалась невероятно острой и очень статичной. Она прилипала к их скафандрам и постепенно разъедала кевлар. На Земле можно использовать диатомовую землю. Она состоит из окаменевших диатомей, которые происходят из океана. Внешне она похожа на муку, не вредит людям и домашним животным. Но на микроскопическом уровне диатомовая земля прилипает к насекомым и разрезает их восковое покрытие, удерживающее влагу. В результате насекомые теряют влагу и высыхают, превращаясь в «муравьиную вяленую говядину». К тому же, диатомовая земля стоит около 10 долларов за 5 фунтов (2,27 кг), что весьма выгодно.
"Hidden Folks! У этой игры 97% положительных обзоров из 6967. Обзоры в Стиме оставляет примерно каждый 30-й человек, каждый 30-й! Игра стоит 15 долларов. Допустим, они все [6967*30] купили её по максимальному ценнику. На самом деле, нет, потому что многие покупают в разной фигне [наверное, про валюту в контексте региональных цен, или про другие магазины типа GOG с другими ценовыми политиками], и Стим забирает себе 30%. С этими допущениями игра принесла максимум 2,2 миллиона доллароов. Ага, а все такие: "Яне могу сделать короткую маленькую веселую и увлекательную игру". Вы можете. И это будет финансово выгодно. Вы можете это сделать. Вы в состоянии сделать игру, которая будет очаровательной и нелепой, и которая будет вам по силам. И вы сможете зарабатывать этим на жизнь."
Когда я только устроился в Blizzard, моя зарплата составляла 10 долларов в час. Вернее, я получал 10.50 долларов в час, так как работал в ночную смену. Через год, когда я перешел на дневную смену, моя зарплата стала 10 долларов в час. Я спросил: "Куда делись 50 центов? Это ж минус 1000 долларов в год". Мне ответили: "Эти 50 центов были надбавкой за ночную смену, и когда ты перешел на дневную, ты их потерял". Для примера, работая в крупнейшей игровой компании в мире, я зарабатывал на 2 доллара в час меньше, чем человек, работающий в продуктовом магазине Trader Joe's на той же улице с начальной зарплатой, и я уже больше года работал в этой компании. Это ужасно. AAA-компании недоплачивают своим сотрудникам. Это касается не только Blizzard, а всех крупных игровых компаний. Поэтому я с нетерпением жду, удастся ли им создать профсоюз. Вся индустрия наблюдает за развитием ситуации, потому что это просто ужас.
75% из нас не стоят взлома — это неверно. На самом деле это не так. Вы более ценны, чем думаете. Каждый человек, работающий в компании, имеет более привилегированный доступ, чем клиенты, которые приходят в этот бизнес. Каждый из нас имеет ценную информацию, и доступ к ней важен. Так что никогда не думайте, что вы не стоите взлома.
Комментарии