...

суббота, 13 февраля 2021 г.

Мнимая значимость

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

Несмотря на то, что это искажение восприятия успешно эксплуатируется большую часть человеческой истории, широкая публика обратила на него внимание после суда над О. Джей Симпсоном, известным в России по роли в культовой комедии «Голый Пистолет». На КДПВ он сбоку.

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

Как это сработало?

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

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

После такой блистательной демонстрации, примененная Кокраном тактика защиты стала предметом общественной дискуссии, получив название «Защита Чубакки» — взятого из посвященного Кокрану 214того эпизода мультсериала Южный Парк: 

Чубакка — это вуки с планеты Кашиик, но Чубакка живёт на планете Эндор. Подумайте об этом, в этом нет смысла! С чего бы вуки ростом два с половиной метра жить в Эндоре с 60-сантиметровыми эвоками? В этом нет смысла!

Но что ещё более важно, вы должны спросить себя, а при чём тут данное дело? Да ни при чём, леди и джентльмены, это не имеет никакого отношения к данному делу. В этом нет никакого смысла!

Взгляните на меня, я адвокат, защищающий крупную звукозаписывающую компанию, и я веду речь о Чубакке. Какой в этом смысл? Леди и джентльмены, я несу бессмыслицу, во всём этом вообще нет смысла!

Итак, запомните, когда вы, сидя в этой комнате, взвешиваете и сопрягаете Декларацию независимости, есть ли в этом смысл? Нет, в этом нет смысла!

Итак, леди и джентльмены, если Чубакка живёт на Эндоре, вы обязаны вынести оправдательный приговор. Спасибо, ваша честь, я закончил.

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

«Всё непонятное — на самом деле логично» — делает вывод школьник. И успокаивается.

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

Именно поэтому «Защита Чубакки» настолько эффективна: достаточно уверенным голосом сказать что-то непонятное, и большинство слушателей решит, что ты прав как толковый словарь. Увы и ах.

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

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

Окрыленная этим успехом, Дарья перепорхнула в универ, где этот приём не работал. Вот вообще — там преподавали зубры, кушавшие подобных «гениев» на завтрак. Весь первый год Дарья рыдала до, во время, и по итогам сессий. Потом как-то выровнялось.


Узнав про «Защиту Чубакки», я начал видеть её во всем — в речах политиков, в научных статьях, в художественной литературе…

Особенно в художественно литературе. Рассмотрим последнее чуть подробнее: мне, как литератору это близко. Вот например, читая роман канадского писателя-фантаста Питера Уоттса «Ложная слепота» (англ. Blindsight) — я был весьма удивлен — культовый статус этого романа в России никак не соответствовал его популярности на родине.

Конечно, такое уже бывало раньше: Гор Видал, помнится, как-то заметил что «Романы Курта Воннегута сильно проигрывают в оригинале...» — намекая на то, что переводчица Курта, блистательная Рита Райт-Ковалева, владеет русским заметно лучше, чем сам автор английским.

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

Но в случае Питера это объяснение не проходило — перевод Даниэля Смушковича, особенно его первая редакция, был просто ужасен, напоминая, порой, перегруженный научными терминами бессвязный набор слов.

Именно это, по-моему, сыграло главную роль в обретении популярности — массовый читатель ничего не понял, но на всякий случай восхитился. Так автор «студеного вакуума» стал в России научным фантастом «№1». Иган с Тедом Чаном нервно курят в сторонке.

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

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


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

 Но, не всё так безнадежно: столкнувшись с «Защитой Чубакки» смело используйте против «Тактику Гризли!».

Как известно, медведи гризли — самые опасные хищники в канадских лесах. От них просто нет спасения. Если вы побежите, гризли побежит ещё быстрее. Если вы броситесь в воду, гризли бросится в воду вслед за вами. Если залезете на дерево, гризли полезет вслед за вами... И самое страшное: от гризли невозможно спрятаться. Если он заметит, что вы спрятались, то он тоже спрячется!

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

Сцена после титров

Сцены после титров, увы, не будет. Будет просьба — у меня в "Прыжках через огонь" герой учится в Чапел-Хильском Университете Северной Каролины — и я был бы признателен за ссылки на книги или блоги, рассказывающие о бытности американских студентов — как организован процесс обучения, проживания и прочего.

Let's block ads! (Why?)

Отложенные задачи в рамках микро-сервисной архитектуры

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

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

Рисунок 1 - Принципиальная схема работы Trigger Hook
Рисунок 1 - Принципиальная схема работы Trigger Hook

задача, время запуска которой наступит не скоро

задача, время запуска которой скоро наступит

задача, время запуска которой наступило

обработанное задание

неподтвержденный статус задания в базе данных

команда на удаление

Жизненный цикл задачи:

  • При создании задачи она попадает в базу данных (квадратный блок) (красные и желтые).

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

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

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

Дальше постараюсь подробнее описать некоторые особенности и привести аргументы в пользу выбора данного решения.

Простота API

Id принимается в формате UUIDv4. Если не передать, то будет сгенерирован самостоятельно. Возможность передачи id задачи со стороны внешнего сервиса будет полезна при использовании асинхронного канала. Время запуска указывается в формате UNIX.

Создание:

task := &domain.Task{
        Id:         id,
        ExecTime: time,
}
triggerHook.Create(task)

Удаление:

triggerHook.Delete(task.Id)

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

for {
        result := triggerHook.Consume()
        if err != send(result.Task()) {
                result.Rollback()
        }
        result.Confirm()
}

Стойкость к сбоям

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

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

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

Точность и производительность

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

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

Были измерены основные показатели скорости обработки задач.

Сервер приложения:

  • AWS EC2 Ubuntu 20

  • t2.micro

  • 1 vCPUs 2.5 GHz

  • 1 GiB RAM

Сервер базы данных:

  • AWS RDS MySQL 8.0

  • db.t3.micro

  • 2 vCPUs

  • 1 GiB RAM

  • Network: 2085 Mbps

Тест

Длительность теста

Средняя скорость (задач/сек)

Количество задач

Создание задач

1 минута 11 сек

1396

100000

Удаление задач

52 сек

1920

100000

Отправка задач (состояние задачи от красной до голубой)

498 милисекунд

200668

100000

Подтверждение задач (состояние задачи от голубой до удаления)

2 сек

49905

100000

Мониторинг

Для быстрой проверки корректной работы Trigger Hook предоставляет возможность подключить time-series базу данных. На этапе инициализации есть возможность определить периодичность измерений и выбрать интересующие метрики. Полный список доступных метрик есть тут.

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

  • фатальные ошибки - приводящие к полной остановке приложения

  • ошибки на которые стоит обратить внимание, но которые не приводят к остановке 

  • дебаг сообщения

Далее в примере Вы можете увидеть пример подключения к InfluxDB+Grafana

Trigger Hook в составе микро-сервисной архитектуры

Асинхронное взаимодействие

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

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

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

Рисунок 2 - Схема коммуникации через асинхронный канал
Рисунок 2 - Схема коммуникации через асинхронный канал

На рисунке 3 показаны процессы создания сущности имеющий отложенное выполнение и на рисунке 4 выполнение при наступлении времени.

Рисунок 3 - Процесс создания сущности с отложенным выполнением
Рисунок 3 - Процесс создания сущности с отложенным выполнением
Рисунок 4 - Выполнение задания сущности
Рисунок 4 - Выполнение задания сущности

Совместный доступ

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

Верхний слой будет обладать доменным знанием. Другими словами, менеджер задач будет иметь определенный набор типов задач, определенный набор событий, относящихся к тем или иным типам задач. Например, обращение к интерфейсу будет звучать как “создай отложенную задачу на отправку email сообщения” или “создай отложенную задачу на списание платы по подписке на YouTube”, а уже сам менеджер задач будет обращаться к Trigger Hook с запросом “создай отложенную задачу”. Когда придет время запустить задачу, Trigger Hook создаст событие “время выполнения задания наступило”. Это событие перехватит менеджер задач, обработает его, выдав, например, событие “время списания платы по подписке наступило”. На рисунках 5 и 6 показан этот процесс.

Рисунок 5 - Создание задания с использованием промежуточного слоя
Рисунок 5 - Создание задания с использованием промежуточного слоя
Рисунок 6 - Обработка события с использованием промежуточного слоя
Рисунок 6 - Обработка события с использованием промежуточного слоя

Связь между компонентами приложения должна быть очень слабой. Это касается и микро-сервисов в целом. На практике, одной из причин усиления связи, является перенос части ответственности одного сервиса в другой. Поэтому, одной из самых сложных задач, является поиск границы раздела (монолитного, например) приложения на микро-сервисы. Что бы это сделать удачно, нужно учитывать специфику доменной области знаний и текущей реализации приложения. Теперь вопрос - в какой микро-сервис поместить слой “менеджер задач”?

Рисунок 7 - Менеджер задач в одном м/с с Trigger Hook
Рисунок 7 - Менеджер задач в одном м/с с Trigger Hook

На рисунке 7 показана схема, где менеджер задач является отдельным, микро-сервисом, содержащий доменное знание о типах задач, событиях относящихся к этим задачам. Как видно из схемы, предполагается совместное использование одного микро-сервиса менеджера заданий для разных клиентских микро-сервисов. У каждого микро-сервиса свой канал для получения событий. В RabbitMq такой канал событий легко реализовать в виде схемы direct.

Рисунок 8 - Менеджер задач как часть клиентского м/с
Рисунок 8 - Менеджер задач как часть клиентского м/с

На рисунке 8 показана иная схема, где менеджер задач является частью клиентского микро-сервиса и используется только для своих внутренних нужд. Такая схема подойдет если нет других микро-сервисов использующих отложенные задания или же каждый микро-сервис имеет свой менеджер задач с Trigger Hook микро-сервисом.

Масштабирование

Некоторые приложения сложнее масштабировать, чем другие. Все намного проще, если состояние приложения хранится только во внешнем хранилище с поддержкой конкурентного доступа, например, классическая связка PHP + MySQL. В этом случае несколько экземпляров приложения PHP разворачиваются на разных серверах, а Nginx балансирует нагрузку между ними, при этом, MySQL ресурс остается один на все экземпляры PHP приложений. Если MySQL не справляется, то уже независимо от PHP приложения, могут быть добавлены реплики.

Все несколько сложнее, когда приложение хранит собственное состояние. Его сложнее масштабировать горизонтально. Trigger Hook хранит свое состояние в оперативной памяти. Оно подгружает задачи, время запуска которых скоро наступит. Допустим, Вы создали задачу, время выполнения которой наступит примерно через 5 секунд. Это означает, что Trigger Hook уже погрузил ее для выполнения. Но Вы захотели отменить эту задачу. Для этого нужно вызвать метод API delete. Важно вызвать этот метод у того экземпляра приложения, который взял задачу на обработку. Это первая сложность.

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

На рисунке 9 показан пример масштабирования нагрузки. У каждого экземпляра Trigger Hook своя БД, на разных серверах (иначе особого смысла нет). Перед экземплярами Trigger Hook имеется балансировщик нагрузки. Кроме балансировки, он пишет в какую-нибудь  hash map базу данных, например, Redis, пару ключ-значение:

task_id:instance_host
Рисунок 9 - Схема горизонтального масштабирования
Рисунок 9 - Схема горизонтального масштабирования

Это нужно для обеспечения функции удаления задачи. Если в Вашем приложении не предусмотрено удаление, то достаточно балансера без базы данных. События, генерируемые экземплярами Trigger Hook можно пересылать по одному каналу через брокер. Генерирование id будет происходить на стороне клиентского сервиса (при асинхронном взаимодействии) или на стороне trigger hook (при асинхронном или синхронном взаимодействии). Для клиентских сервисов интерфейс не изменится.

Приложение для демонстрации Trigger Hook

Приложение состоит из пяти микро-сервисов. Каждый использует Docker контейнер. Все работает на Kubernetes. Приложение легко можно развернуть в minikube. Тут описана подробная инструкция.

Рисунок 10 - Упрощенная схема взаимодействия микро-сервисов
Рисунок 10 - Упрощенная схема взаимодействия микро-сервисов

Message service - сервис (рисунок 11), который предоставляет API для создания email сообщений и назначения отправки на определенное время или отмены. Также позволяет просмотреть полный список сообщений и их статусы.

Некоторые особенности:

  • Находится на уровне домена. 

  • Состоит из менеджера сообщений и менеджера заданий. 

  • Написан на PHP, фреймворк Symfony 5.

  • Работает в двух экземплярах. Первый обслуживает API запросы при помощи Nginx. Второй - запускает демон через supervisor для прослушивания события из очереди RabbitMQ. Имеет вспомогательные экземпляры для запуска миграций.

  • Использует схему с рисунка 8 для управления заданиями.

Рисунок 11 - Message service
Рисунок 11 - Message service

Message Dashboard - интерфейс для Message service (рисунок 12).

Рисунок 12 - Интерфейс демо-приложения
Рисунок 12 - Интерфейс демо-приложения

Сервис Mailer находится на уровне инфраструктуры. Должен непосредственно делать рассылку. Не реализован, так как не важен в рамках демо.

Trigger service - сервис уровня инфраструктуры. Использует GRPC канал для получения команд на создание и удаление заданий, AMQP для рассылки события наступления времени выполнения задания (триггер).

Рисунок 13 - Trigger service
Рисунок 13 - Trigger service

Monitoring - также находится на инфраструктурном уровне, так как показывает технические метрики без привязки к бизнес событиям. На рисунке 14 показано как выглядит панель. Используется Grafana и InfluxDB. Полное описание метрик есть тут.

Рисунок 14 - Технические метрики Trigger Hook
Рисунок 14 - Технические метрики Trigger Hook

Надеюсь, приложение и статья будут Вам полезны! Следите за моим github, следите за проектом, ставьте звездочки). Спасибо!

Let's block ads! (Why?)

НАСА: проложить путь людям на Марс может лишь ракета с ядерным реактором


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

Основная проблема — в отсутствии надежного транспортного средства. Сейчас идет подготовка ракеты и корабля от SpaceX, но до реального полета на Марс может пройти (и скорее всего, пройдет) несколько лет. Причем реактивная тяга такой ракеты образуется в результате сжигания жидкого топлива. А по мнению НАСА, ракеты на жидком топливе — не самый эффективный вид транспорта, нужны ядерные системы.
Топливо для ракет очень дорогое, а по словам представителей НАСА, для полета на Марс понадобится от 1000 до 4000 тонн топлива. Это несколько миллиардов долларов США за пуск (хотя, помнится, Маск говорил, что топливо — это всего 5% стоимости всего пуска). Правда, все сказанное относится к ракете самого агентства, которая называется Space Launch System. Она разрабатывается уже много лет, и пока что свет в конце туннеля этого проекта не появился.

Тем не менее, расчеты по полету на Марс с использованием сверхтяжелой ракеты-носителя SLS у НАСА есть. И эти расчеты показывают, что один пуск обойдется в $2 млрд. И это вроде только стоимость топлива. 10 пусков, которые нужны для отправки достаточного для основания небольшой станции полезного груза, обойдутся в $20 млрд.

По мнению представителей НАСА, более эффективный способ запуска — это ядерные ракеты.

Космический транспорт на ядерной тяге


Специалисты агентства подготовили отчет, в котором говорится, что для реализации миссии по отправке человека на Марс в 2039 году требуется именно ядерный транспорт.

«Один из ключевых моментов путешествия на Марс в том, что если мы хотим отправлять людей регулярно, то наиболее удобный путь — это как раз ракеты на ядерной тяге», — заявил Бобби Браун, представитель Jet Propulsion Laboratory.

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


Ядерная система требует гораздо меньше топлива — около 500 тонн вместо 4000, уже упоминавшихся выше. Если говорить об эксплуатации такой системы, то, по мнению агентства, расходы будут ниже, чем в случае эксплуатации топливной ракеты.

И что теперь?


В отчете говорится, что если НАСА планирует использовать ракеты на ядерной тяге через 10-15 лет, то разработку соответствующих технологий нужно начинать уже сейчас. Все это несколько странно, поскольку ранее агентство очень активно продвигало идею полетов на SLS. Сейчас эту ракету-носитель предлагается использовать для полетов на Луну.

Самое интересное в проекте то, что средства на него НАСА не запрашивала, но Конгресс США все равно выделил средства. Причем в этом году агентство получило сразу $110 млн именно на исследование возможностей ядерных систем запуска.

Если НАСА решит все же развивать это направление и дальше, то средств понадобится еще больше. Тем не менее, агентство считает, что справится со всеми проблемами. «Это технологический проект, для работы над которыми и было создано НАСА, так что вся страна ждет от нас результатов», — заявил Браун.

А что Starship?


Несмотря на проблемы, топливная ракета-носитель Starship, разрабатываемая SpaceX, постепенно эволюционирует. Результаты испытаний дают надежду на то, что в течение нескольких лет ракета сможет отправить людей и оборудование на Марс.

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

Представители НАСА при этом считают, что у проекта Маска есть все шансы на реализацию, так что два параллельных сценария полета на Красную планету — это хорошо.

Реальна ли ядерная ракета в ближайшем обозримом будущем?



Честно говоря, вряд ли. Скорее всего, этот отчет — просто чисто теоретическое изыскание, которое не получит продолжения, по крайней мере, сейчас. Дело в том, что даже с отработанной технологией двигателей на жидком топливе у НАСА проблемы.

Та же ракета-носитель SLS уже давно вызывает вопросы не только у обычных людей, но и у правительства США. Проект стоит огромную кучу денег, на проект SLS НАСА тратит в год примерно столько, сколько хватило бы на 15-20 пусков Falcon Heavy. Эта ракета отъедает весьма изрядную долю бюджета агентства, речь идет о миллиардах и миллиардах долларов.

В 2018 году НАСА попыталось рассказать о том, насколько полезной будет эта ракета. Дескать, она может выводить на орбиту «цельные грузы большой массы» за раз. Другие ракеты вроде бы так делать не могут. И все бы хорошо, но это просто слова, поскольку плана эксплуатации SLS пока нет — просто потому, что и такие вот «цельные» грузы пока выводить на орбиту не требуется.

И, повторимся, речь идет о технологии, которой уже несколько десятков лет. Да, конечно, сверхтяжелая ракета отличается от всего того, что использовало НАСА ранее, но разница не кардинальная.

А в случае ядерных ракет мы говорим о совершенно новых технологиях, которые разрабатывались ранее лишь в порядке чисто теоретических проектов. Проблемой будет даже создание относительно небольшой ракеты на ядерной тяге для полетов на орбиту. Сложно представить, сколько средств, ресурсов и времени понадобится для того, чтобы с нуля создать огромную ракету с ядерным реактором для полета на Марс. $110 млн, которые получило НАСА на проработку этого направления — просто капля в море. Полный бюджет проекта будет таким, что не то, что у НАСА, у всей страны денег не хватит.


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

Так что ядерные ракеты пока так и останутся красивой теорией. А если у Маска все пройдет хорошо, и его проект по полету на Марс будет реализован, то и необходимости в «ядерных полетах», скорее всего, уже не будет.

Let's block ads! (Why?)

Россия и Китай подпишут Меморандум о сотрудничестве в строительстве исследовательской станции на Луне

11 февраля 2021 года Премьер-министр РФ Михаил Мишустин поручил Роскосмосу подписать с Китаем Меморандум о взаимопонимании по сотрудничеству в области создания Международной научной лунной станции.
Согласно распоряжению № 304-р, «правительство РФ принимает предложение Роскосмоса, согласованное с МИДом, Минюстом России и другими заинтересованными федеральными органами исполнительной власти и предварительно проработанное с КНР, о подписании Меморандума о взаимопонимании между правительством РФ и правительством Китая о сотрудничестве области создания Международной научной лунной станции».

Также правительство РФ разрешило Роскосмосу вносить в Меморандум изменения, не имеющие принципиального характера.

По информации «ТАСС», в ноябре 2017 года между Роскосмосом и Китайским национальным космическим управлением была подписана программа сотрудничества в области космоса на 2018-2022 годы. Она включала в себя шесть разделов: изучение Луны и дальнего космоса, космическая наука и связанные с ней технологии, спутники и их применение, элементная база и материалы, сотрудничество в области данных дистанционного зондирования Земли и другие темы. Для реализации проектов в рамках данной программы в космических ведомствах России и Китая были созданы рабочие подгруппы.

В начале февраля этого года представитель Роскосмоса сообщил «ТАСС», что госкорпорация обсуждает с коллегами из Китая возможные научные задачи для базы на Луне и прорабатывает техническую реализацию проекта.

25 января 2021 года Роскосмос заявил, что вышел из проекта лунной орбитальной станции НАСА. Рогозин пояснил, что Роскосмос никогда не входил в экспертную группу по созданию лунной орбитальной станции НАСА. Этот проект Рогозин назвал «неинтересным и полностью американским с ограниченным участием внешних партнеров».

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

Let's block ads! (Why?)

Google захватывает Python

Google объявили себя идейным спонсором Питона. Visionary Sponsor как они это называют. Начали они с того, что вчера перечислили в фонд Питона 350 тысяч долларов. Гугл уже 10 лет спонсируют Питон, ничего нового вроде бы, но кроме нового термина они поставили новые цели:

  • Поиск зловредного кода в базе pip.

  • Улучшение основных частей Питона.

  • Оплачиваемая фулл-тайм должность "разработчик CPython"

В Гугл используют Питон во многих сервисах, Гугл распространяет библиотеки на Питоне и у них много денег, вроде всё логично, надо спонсировать, тем более создатель и майнтайнер как раз отошёл от дел. Но на первом месте в списке приоритетов стоит в сущности контроль над PyPI/pip install. Разумеется не обойдётся только "поиском" зловредного кода, его будут и удалять, сотрудники Гугл с помощью алгоритмов Гугл. Значит начнутся ситуации как с Google Play, "спасите мой пакет забанили без объяснения причин!" После того, как Микрософт купили Github кто удивится желанию эффективных менеджеров контролировать ещё одну крупную площадку, почему бы не монетизировать её в конце-концов или использовать в других благих целях.

Чего сейчас опасаются многие, так это форка, несогласные с политикой идейного спонсора могут захотеть развивать Питон самостоятельно, а это может всё испортить. Форк Питона не намного проще чем форк браузера, начнутся несовместимости, резкие изменения, могут выйти два совершенно непохожих друг на друга четвёртых Питона. Есть много творческих способов для корпорации испортить оупенсорс проект своей добротой, вспомним хоть вмешательство Oracle которое привело к тому, что теперь есть Open Office и Libre Office.

С другой стороны можно ожидать передовых технологий JIT компиляции в CPython, версии Питона для Андроида. Если фулл-тайм разработчик будет уровня Lars Bak или Daan Leijen может быть в Питоне будет убран GIL появятся мощные возможности для многозадачности и параллельности. Мечты. Не близки ли слова мечта и visionary? Кроме Visionary у Питона есть Sustainability sponsors, Maintaining sponsors, Contributing sponsors, Supporting sponsors, Partner sponsors, Participating sponsors и Associate sponsors. Отличаются они суммой доната, 1500 для Associate и 150000 для Visionary с плавным градиентом для остальных позиций. Причём вся эта красота из восьми позиций была создана буквально перед самым объявлением о идейном спонсорстве. Обнуление такое.

Кроме денег Гугл хочет видеть всю инфраструктуру Питона живущей в своём облаке. В особенности репозиторий pip. Ee Durbin директор Питона по инфраструктуре уже согласился. Это очень хорошо, сказал он, потому что теперь можно использовать BigQuery на индексе репозитория!

Как ни странно, при невероятной популярности Питона, в 2019 году ключевые разработчики интерпретатора и тулзов посчитали, что все вместе они нарабатывают часов примерно на две фулл-тайм позиции. Так что если с помощью Гугл это число станет 3 или ещё лучше 4, то будет удвоение! Всего два фуллтаймера в эквиваленте, при том, что компании которые строят свой бизнес на Питоне в совокупности стоят триллионы, такова экономика опенсорс.

Кстати можно посчитать, что если бы интерпретатор Питона был в два раза быстрее, то можно было бы сократить расход электроэнергии и выбросы СО2 в атмосферу на чувствительную величину, это как с биткоином. Пропозал на такие оптимизации в CPython висит уже не один год, денег нет. JIT уже пришёл в Ruby, PHP8, Lua, но не в Питон. Наверное скорость в языке не главное. И защита природы и экономия электричества не главное, главное -- держать репозиторий всех пакетов написанных на Питоне на своих серверах. Ведь там же столько зловредного кода.

Let's block ads! (Why?)

[Перевод] Заметки о Unix: как команда newgrp работала в Unix V7?

В материале, посвящённом причинам существования команды newgrp, мы узнали о том, что группам в Unix можно назначать пароли, о том, что эта команда позволяет пользователю менять свою (основную) группу. Мы выяснили, что эта команда появилась в Unix V6, что гораздо раньше, чем я ожидал. Меня тогда заинтересовал вопрос о том, как именно работала команда newgrp в Unix V7. Исходный код V7 (а так же — справку и другие материалы) можно найти на tuhs.org. Поэтому ничто не мешает нам почитать код реализации этой команды, находящийся в файле newgrp.c.


(Можно посмотреть и исходный код, имеющий отношение к V6, но он гораздо сложнее, поэтому я буду рассматривать код V7. Помимо того, что V7 обычно считают системой, с которой началась современная Unix, всё, что было сделано до V7, выглядит иначе, и, как минимум, кажется немного странным.)

Я полагал, что newgrp работает с группами, защищёнными паролями, примерно так: кто угодно может выполнить команду наподобие newgrp GROUP, и если ему известен пароль, он будет помещён в группу без необходимости указания его в качестве (потенциального) члена группы в /etc/group. Возможно, именно так работает современная версия newgrp, доступная в вашем дистрибутиве. Но в V7 эта команда работала иначе. Начнём с извлечения из справки (newgrp.1):

Пароль требуется в том случае, если у группы есть пароль, а у пользователя — нет.

Когда большинство пользователей входит в систему, они являются членами группы other. Команда newgrp известна командной оболочке, которая выполняет её напрямую, без форка.


Во-первых, если только вы не являетесь членом специальной группы other, вы должны быть записаны в /etc/group независимо от того, назначен ли группе пароль или нет. Затем, как сказано в справке, пароль группы требуется лишь в том случае, если у вашей учётной записи пароля нет. Если же у учётной записи есть пароль, то пароль группы игнорируется. Другими словами, можно не использовать пароль группы для того чтобы иметь возможность предоставить кому угодно, знающему такой пароль, потенциальную возможность доступа к группе. Пароль группы используется только для защиты группы от входа в неё пользователей с аккаунтами без паролей (если такие пользователи в системе присутствуют и если они внесены в дополнительную группу).

При работе с группами, которым назначен пароль, обычная Linux-версия newgrp ведёт себя с такими группами, членом которых вы являетесь, так же, как и V7-версия команды. Но она ещё и позволяет входить в любые группы, для которых задан пароль, в том случае, если этот пароль вам известен (так сказано в справке, я это не проверял). Во FreeBSD, к которой у меня есть доступ, пользоваться паролями групп не рекомендуется, в справке говорится, что newgrp обычно устанавливается без бита setuid. Ещё там сказано, что пароль запрашивается только тогда, когда пользователь не входит в число членов группы.

(Я полагаю, что это значит, что в стандартной установке FreeBSD пользователь не может использовать newgrp для перехода в группу, в которую он был добавлен через /etc/group.)

Возможно, вас заинтересовало последнее предложение из процитированной мной справки по V7-версии newgrp. Причина наличия этой особенности заключается в том, чтобы исключить существование дополнительных процессов командной оболочки, которые, вероятно, пользователю не нужны (это привело бы к использованию дополнительных системных ресурсов на маломощных машинах, на которых работала V7). С концептуальной точки зрения, если выполняют команду newgrp, то обычно стремятся к тому, чтобы переключить текущую сессию командной оболочки на новую группу. Если оболочка просто выполнит newgrp как обычную команду, то будет осуществлено переключение групп для её собственного процесса, а затем будет выполнена программа /bin/sh, дающая пользователю новую оболочку в новой группе. Это было бы похоже на то, как если бы пользователь выполнил бы команду sh в login-оболочке. Если при таком подходе выполнить несколько команд newgrp, то всё закончится тем, что у пользователя будет целая куча оболочек.

А командная оболочка V7 распознаёт команду newgrp (а так же — команду login) и не создаёт форк для её выполнения. Вместо этого она запускает newgrp, пользуясь системным вызовом exec, и заменяет login-оболочку на newgrp (которая затем идеально заменяет её другой оболочкой, и V7-версия newgrp, на самом деле, всегда стремится к тому, чтобы открывать таким образом новую командную оболочку).

(Тут всё самое интересное кроется в комбинации msg.c и xec.c; взгляните на обработку SYSLOGIN).

Исследуете ли вы старые дистрибутивы Unix для того чтобы лучше понять современные системы?

Let's block ads! (Why?)

Пиксели, Excel, Kotlin и немного ностальгии…

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

Предисловие

На дворе стоял 2000-й год. Кризис 98 года остался позади. Я учился в 8 классе местной школы, в небольшом городке. С началом учебного года всех ждало небольшое событие - ввели урок информатики. Многие отнеслись к этому, как к еще одному предмету который надо учить, но были и те, у кого загорелись глаза. В числе последних оказался и я.

Надо отметить, что информатику хоть и ввели, но "ввести новые компьютеры" забыли, потому что денег на эти цели не было. На службе у нашей школы тогда стояли машины made in USSR - "Электроника МС 0511" и несколько их чуть более современных аналогов. Работали они только по им самим ведомым законам, или после прихода некоего "Николая Владимировича" - местного мастера.

фото с сайта - red-innovations.su
фото с сайта - red-innovations.su

Вести предмет как водится поставили молодого и "горячего" преподавателя - девушку 26 лет, которая кстати очень старалась. Мы учили системы счисления и переводили письменно числа из одной в другую. Читали про общее устройство ПК и конечно был Бейсик. У каждого тетрадка была в прочной прозрачной обложке, сзади которой была нарисована система координат. Это был своего рода холст для эскизов фигур, которые мы потом старательно переносили в код.

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

Рисуем первое изображение

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

fun drawPixel(
    x:Int, y:Int, red:Int, green:Int, blue: Int,
    image: BufferedImage
) {
    image.setRGB(x, y, Color(red,green,blue).rgb)
}

Чтобы проверить работу набросал метод, который выводит картинку с пикселями рандомного цвета. В функции можно понизить значение каждого из каналов цвета, задав диапазон - красного redRng, зеленого greenRng и синего blueRng цвета.

fun drawRandImage( 
    image: BufferedImage, stepSize: Int = 1,  
    redRng: Int = 255, greenRng: Int = 255, blueRng: Int = 255
) { 
    for(posX in 0 until image.width step stepSize){ 
        for (posY in 0 until image.height step stepSize) {
            val r = if (redRng <= 0) 0 else Random.nextInt(0, redRng) 
            val g = if (greenRng <= 0) 0 else Random.nextInt(0, greenRng)
            val b = if (blueRng <= 0) 0 else Random.nextInt(0, blueRng) 
            drawPixel(posX, posY, r, g, b, image) 
        }  
    }
}

Если поставить в цикле шаг stepSize отличный от единицы и занизить один из каналов, то можно получить интересный эффект.

рандомное изображение 1.) step 3, RGB (11, 238, 229) 2.) step 2, RGB (181, 19, 227)
рандомное изображение 1.) step 3, RGB (11, 238, 229) 2.) step 2, RGB (181, 19, 227)

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

fun writeImage(img: BufferedImage, file: String) {
    val imgthread = Thread(Runnable {
        ImageIO.write(img, File(file).extension, File(file))
    })
    try {
        imgthread.start()
    } catch (ex: Exception) {
        ex.printStackTrace()
        imgthread.interrupt()
    }
}

Останавливаться на этом было глупо, поэтому следующим шагом решил сделать "рисовалку" на базе двумерного списка.

Пиксельное сердце

Координаты для отрисовки решил сделать в виде двумерного списка ArrayList<List<Int>>. Получить "пиксельный" эффект мне помогла функция drawTitle, которая "дергает" в цикле drawPixel, рисуя "big pixel" в виде плитки.

fun drawTile(
    startX: Int, startY: Int, size: Int, 
    red: Int, green: Int, blue: Int, image: BufferedImage
) {
    for (posX in startX until startX+size) {
        for (posY in startY until startY+size) {
            drawPixel(posX,posY,red,green,blue,image)
        }
    }
}

Настала очередь обработать массив с числами. Сказано-сделано. Добавив с помощью оператора when обработку 4 цветов…

fun drawImage(pixels: ArrayList<List<Int>>, image: BufferedImage) {
    pixels.forEachIndexed { posY, row ->
        row.forEachIndexed { posX, col ->
            when(col) {
                1 -> drawTile(posX*10,posY*10,10,255,2,0,image)
                2 -> drawTile(posX*10,posY*10,10,156,25,31,image)
                3 -> drawTile(posX*10,posY*10,10,255,255,255,image)
                else -> drawTile(posX*10,posY*10,10,23,0,44,image)
            }
        }
    }
}

…и создав список в виде двумерного массива, где каждая цифра соответствует своему цвету (1 = красный, 2 = темно-красный, 3 = белый, 4 = фиолетовый)

val map = arrayListOf(
    listOf(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
    listOf(0,0,0,1,1,1,0,0,0,1,2,2,0,0,0),
    listOf(0,0,1,3,3,1,1,0,1,1,1,2,2,0,0),
    listOf(0,1,3,3,1,1,1,1,1,1,1,1,2,2,0),
    listOf(0,1,3,1,1,1,1,1,1,1,1,1,2,2,0),
    listOf(0,1,1,1,1,1,1,1,1,1,1,1,2,2,0),
    listOf(0,1,1,1,1,1,1,1,1,1,1,1,2,2,0),
    listOf(0,0,1,1,1,1,1,1,1,1,1,2,2,0,0),
    listOf(0,0,0,1,1,1,1,1,1,1,2,2,0,0,0),
    listOf(0,0,0,0,1,1,1,1,1,2,2,0,0,0,0),
    listOf(0,0,0,0,0,1,1,1,2,2,0,0,0,0,0),
    listOf(0,0,0,0,0,0,1,2,2,0,0,0,0,0,0),
    listOf(0,0,0,0,0,0,0,2,0,0,0,0,0,0,0),
    listOf(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
)

...на выходе получил такую красоту. Мой внутренний "школьник" был очень доволен.

pixel heart
pixel heart

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

Excel как холст

Следующим вечером я продолжил. Сперва подумал о JS (Resct JS), но тут нужно было переписывать все полностью на нем, да и JavaScript я пробовал слишком давно. Хотелось взять что-то простое…

По работе часто приходится работать с таблицами, поэтому само собой выбор остановился на Excel. Привел строки столбцы к виду квадратной сетки и вуаля - наш холст готов к работе с цифровыми красками. Осталось лишь только получить данные из ячеек. "Цифровая бумага все стерпит" - подумал я, и взял Apache POI - библиотеку для работы файлами word, excel, pdf. Документация у нее написана хорошо, но некоторые примеры кода там явно требуют корректировки.

Для начала набросал простую лямбду для преобразования hex в rgba, которая отдает стандартный джавовский класс Color.

val toRGBA = { hex: String ->
    val red = hex.toLong(16) and 0xff0000 shr 16
    val green = hex.toLong(16) and 0xff00 shr 8
    val blue = hex.toLong(16) and 0xff
    val alpha = hex.toLong(16) and 0xff000000 shr 24
    Color(red.toInt(),green.toInt(),blue.toInt(),alpha.toInt())
}

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

fun getPixelColors(file: String, listName: String): ArrayList<List<String>> {
    val table = FileInputStream(file)
    val sheet = WorkbookFactory.create(table).getSheet(listName)

    val rowIterator: Iterator<Row> = sheet.iterator()
    val rowArray: ArrayList<Int> = ArrayList()
    val cellArray: ArrayList<Int> = ArrayList()

    while (rowIterator.hasNext()) {
        val row: Row = rowIterator.next()
        rowArray.add(row.rowNum)
        val cellIterator = row.cellIterator()

        while (cellIterator.hasNext()) {
            val cell = cellIterator.next()
            cellArray.add(cell.address.column)
        }
    }
    val rowSize = rowArray.maxOf { el->el }
    //...проходим по листу 
    //...и формируем массив
    return pixelMatrix
}

Функция немаленькая и всю ее приводить я не буду (ссылка на код в конце статьи). Конечно, ее можно сократить, но ради читаемости я оставил все как есть. И тут хотелось бы остановиться на одном моменте.

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

val rows = sheet.lastRowNum
val cells = sheet.getRow(rows).lastCellNum // + rows

val pixArray = Array(rows+1) {Array(ccc+1) {""} }

...то Вы получите ошибку OutOfBounds. Количество строк (row) получается всегда правильным, но количество ячеек порой то меньше, то больше чем нужно. Я так и не понял, почему результат "скачет", причем проявляется это рандомно. Исправить это можно при помощи iterator.hasNext(), который реально возвращает последнюю ячейку.

Редактор пикселей в Excel
Редактор пикселей в Excel

Дело сталось за малым - преобразовать нашу "пиксельную матрицу" в картинку и вернуть в качестве результата BufferedImage. В отличии от начала статьи, тип картинки у нас изменился на - TYPE_INT_ARGB, чтобы не закрашенные ячейки таковыми и оставались.

fun renderImage(pixels: ArrayList<List<String>>): BufferedImage {
    val resultImage = BufferedImage(
        pixels[0].size*10,
        pixels.size*10,
        BufferedImage.TYPE_INT_ARGB
    )
    pixels.forEachIndexed { posY, row ->
        row.forEachIndexed { posX, col ->
            drawTile(
                (posX)*10,(posY)*10, 10,
                toRGBA(col).red, toRGBA(col).green,toRGBA(col).blue,
                toRGBA(col).alpha, resultImage
            )
        }
    }
    return resultImage
}

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

отрисованная картина в Excel. за основу взята работа Mockingjay1701
отрисованная картина в Excel. за основу взята работа Mockingjay1701

Выводы

Весь код доступен по ссылке на github. Что дальше? В планах добавить поддержку svg, может добавить несколько фильтров (blur, glitch, glow, etc..), переписать все с “индусского кода” на человеческий, добавить поддержку xls (HSSF Color) и возможно набросать пару тестов. Чего-то больше добавлять не имеет смысла, так как это скорее интересная задача с легким налетом ностальгии, чем какой-то проект.

Послесловие

Конечно, можно было ограничиться лишь "Фотошопом и Экселем" (ctrl+c, ctrl+v), но цель была не просто получить пиксельный "шедевр" в пару кликов. Хотелось вспомнить школьные уроки информатики, ту теплую атмосферу: Бейсик, старые компьютеры, пиксельные рисунки на экране черно-белого монитора "Электроника МС". Да черт побери, в конечном счете это хоть и простая, но интересная задача, потратить на которую пару вечеров просто приятно.

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

Пусть через пару лет "Электронику МС" сменили современные аналоги на базе Pentium, те первые занятия на старых компьютерах навсегда останутся со мной, ведь именно они вложили в меня любовь к компьютерам и всему что с ними связано...

А с чего начиналась информатика у Вас в школе?

Всем спасибо! Всем пока!

Let's block ads! (Why?)

Как научиться проходить собеседование в Google


На этой неделе у нас выступала Ава Катушка — тренер в Verbetcetera.

Verbetcetera — буткамп для тех, кто хочет подготовиться к интервью в Большой пятерке — Google, Amazon, Facebook, Apple и Microsoft. Менторы Verbetcetera распределены по 5 странам, уже работают в компаниях-таргетах, знают все про специфику работы и требования к кандидатам на разных рынках.

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


Меня зовут Ава Катушка. Я училась в МФТИ, на факультете computer science, который называется ФИВТ. Мой третий курс был довольно сложным, у меня было много стресса, экзамены, навалились проблемы со здоровьем, семейные проблемы.

Я помню, я зашла в книжный магазин и увидела книгу «О чем мечтать». Мне стало интересно; я помнила, что когда-то о чем-то мечтала, но не помнила, о чем. Я раскрыла эту книгу, и прямо там, в «Библио-Глобусе», начала выполнять упражнения из этой книги. И оказалось, что я выполняла ожидания всех людей вокруг – моей семьи, учителей, кого угодно, кроме своих собственных. Я тогда сильно разозлилась. Мне стало интересно – чего же я, собственно, сама хочу. Позже я сидела в Парке Горького и думала об этом. Я поняла, что хочу путешествовать, хочу завести друзей – у меня была с этим проблема – и хочу с нуля написать свой вебсайт. И у меня, как по волшебству, в том году все начало сбываться.
Оказалось, что есть такой способ путешествовать, где тебе еще и заплатят за это: стажировка. Так я попала в Google в Нью-Йорке, там у меня была стажировка. Где-то в середине стажировки меня спросили, хочу ли я остаться на fulltime. Я подумала – почему бы не попробовать, хотя я и не думала, что меня возьмут. Но меня взяли, и я переехала в Мюнхен. Я работала в качестве software engineer в течение трех лет, у меня довольно разнообразный опыт в этом качестве. Сначала я работала и стажировалась как SRI (site reliability engineer) – делала много всего интересного, там была сестринская команда. Но скоро мне показалось, что мне хочется писать больше кода. Я перешла в команду SVI, там мы писали тревел-сайт внутри самой компании, для гуглеров. И под конец я еще узнала, что есть такая специальность — UXE, UX-инженер. Стала изучать немного UX и перешла туда, пытаясь объединить два мои интереса по рисованию и программированию. Получилось у меня довольно средне, но это тоже опыт в области.

Сейчас я не работаю в Google, я как бы решила взять время на то, чтобы узнать, что мне нравится, пробовать всякие гипотезы. В частности, мне хотелось попробовать работать на себя. Я начала вспоминать, что мне в жизни нравилось, и оказалось – мне очень нравился процесс подготовки к интервью. Когда я подавала в разные компании, взаимодействовала с людьми из этих компаний, решала задачи. Это был очень светлый период в моей жизни. Я тогда говорила с другом и узнала, что не у всех этот период – светлый, люди стрессуют на интервью, и потом – «слава богу, это закончилось, я наконец-то работаю». Мне показалось, что я могу, наверно, поделиться чем-то позитивным, превратить этот процесс поиска работы и интервьюирования во что-то приятное, о чем хорошо вспоминать с удовольствием.

Сначала я хотела сама консультировать, но я нашла совет в книге по бизнесу: если хочешь сделать что-то, то сначала найди людей, которые уже это делают что-то хорошее, и ты сможешь у них очень много чему научиться. Тогда я нашла компанию Verbetcetera, там ребята уже занимались тем, чем хотела заниматься я. Там был уже круг менторов; software-engineering-направление было довольно свежее, то есть, оно началось только в 2020 году Но с 2018 существовало менторство PM-ов, которое протекало довольно хорошо. И мне оказались очень близки ценности этой компании: все менторы прошли путь, сами работают в области. Это были ребята, близкие мне по духу, все были (и есть) из FAANG (Facebook, Apple, Amazon, Netflix, Google). Очень классная собралась команда, было интересно присоединиться и попробовать себя в роли ментора.

Я хотела бы рассказать про технологические интервью, ответить на вопросы. Я буду рассказывать про определенную структуру в интервью, останавливаться, смотреть на вопросы, отвечать и идти дальше. Я бы хотела поговорить о coding-интервью: какие вопросы на них задают, какие мифы с этим связаны, как выглядит, в общем, процесс поиска работы с точки зрения компании и кандидата; что такое system design interview, на что оно влияет и какие там есть мифы и популярные заблуждения.

Coding-интервью – что же это такое?


Часто спрашивают, какие вопросы на таких интервью задают. Допустим, один из этих вопросов может быть такой: «на вход поступает зашифрованная строка, раскодируйте ее». Строка может быть такая: 3[A]2[BC]. Раскодируется как AAABCBC. То есть, то, что внутри квадратной скобки, повторяется столько раз, какое число перед скобкой. И вам во время интервью нужно написать программу, которая делает раскодирование.

Такой вопрос действительно задавали на интервью Bloomberg, Amazon, Apple, Cisco, Google, Microsoft; кажется, довольно простой вопрос, даже если вы не связаны с программированием. Но у него может быть двойное дно – например, может быть несколько уровней вложения. Допустим, такая строка: [[[A[[C]].

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

Какие темы спрашивают в собеседованиях?


Примеры популярных тем – массивы, строки (как мы уже рассмотрели), задачи на графы. Иногда – сильно замаскированные: например, составить расписание курсов, при том, что у каждого курса есть предварительный курс (пререквизит). Есть задачи на рекурсию: например, есть популярная задача про цены. Даются цены на акцию в течение какого-то количества дней, и нужно придумать алгоритм покупки-продажи для максимального дохода. Иногда встречаются задачи из математики или геометрии, но их не очень много; никаких специальных знаний по этим предметам не нужно, нужны самые базовые, но их тоже хорошо уметь решать. Вообще, очень хорошо иметь фундамент в computer science, ощущать себя комфортно, чтобы решение задач на интервью не составляло проблем.

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

Несмотря на то, что в чистом виде computer science не применяется к работе, базовые знания все равно довольно полезны, когда вы работаете в software engineering. По сути, эти задачи – это прокси дальнейшей работы. Вместо того, чтобы спрашивать, хороший ли вы разработчик, вам дают задачи и смотрят, как вы себя ведете с ними. И хорошие ответы на вопросы коррелируют с тем, что вы – хороший разработчик.

Какие компании задают такие вопросы на интервью?


Довольно много, и не только FAANG (но и они тоже). У меня есть список: Microsoft, Bloomberg, Uber, Adobe, Oracle, ByteDance, eBay, LinkedIn, Yahoo, VMWare, Salesforce, Cisco – на самом деле, я еще многих не вставила. То есть, такие вопросы довольно популярны. Причем, например, в Google и junior, и middle, и senior developer получают одинаковые вопросы, никаких различий нет.

Есть такой популярный миф: важно ли участие в алгоритмических соревнованиях. Меня это сильно волновало: я в них не участвовала ни в школе, ни в институте. Люди часто говорят, что, если ты не участвовал, то твое время уже прошло – ты всегда будешь плохо проявлять себя на интервью. Но это не так. Несмотря на то, что, конечно, участие в соревнованиях вам поможет и будет подспорьем, интервью от них отличаются. Вопросы похожи, вам тоже нужно решить задачу за ограниченное время, но ее решение вы презентуете не системе, которая должна пройти тесты, а человеку. Человек смотрит и пытается по решению задачи оценить, хочет ли он с вами работать. Важно не только то, что вы находите решение, но и то, как вы его находите, как вы думали, сколько вариантов рассмотрели, можете ли вы их донести до человека. Это очень важный аспект.

Человек, который вас интервьюирует – он инженер, он тоже не решает такие задачи регулярно; скорее всего, последний раз, когда он это делал, был во время его собственного интервью. И он должен найти ответ на вопрос: хочет ли он с вами работать, хорошо ли будет с вами работать. Не нужно его пугаться. Он не хочет поставить вас в суперстрессовые условия; он, наоборот, хочет дать вам позитивный опыт интервью.

Общий фреймворк для coding-интервью


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

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

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

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

Q: какой уровень английского желателен?

Желательно свободно разговаривать, чтобы свободно понимать интервьюера и выражать свои мысли. Необязательно super-advanced, intermediate должно хватить.

Q: какие изменения произошли в наборе Google по сравнению с тем, что описано в Cracking Coding Interview?

Тут нужно понять, что именно сравнивать с чем. Но я думаю, что основные мысли из Cracking Coding Interview до сих пор актуальны. Не так сильно все изменилось.

Q: где можно поднять свой уровень технического английского?

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

Q: насколько задания с leetcode отражают актуальную специфику задач, которые задают в Google? Актуальны ли задачи с прошлого, позапрошлого года?

Во-первых, вам важно, чтобы задачу, которая вам попалась на интервью, вы не видели раньше. Если задача будет знакомая, и вы будете заранее знать, как ее делать, то это вам не поможет. Это, наоборот, навредит: это будет заметно. Вам нужно иметь незнакомую задачу, но нужно прорешивать много подобных задач. Leetcode для этого хорошо годится; если вы решаете задачи на разные темы, покрываете популярные темы по computer science – в какой-то момент вы станете готовы.

Q: какие языки можно использовать для решения задачи на техническом интервью? Я сейчас решаю задачи с leetcode на JavaScript, но слышала, что нужны Python или C++.

Любой из этих языков – JavaScript, Python или C++ — годится, здесь все равно. Если вы пишете на JavaScript, хорошо, глубоко его знаете, это ваш язык – тогда идите на интервью с JavaScript.

Q: есть ли у вас подход, чтобы правильно оценивать время на каждую задачу на auto code interview, когда есть несколько задач и ограничение по времени?

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

Q: задачи, с которыми сталкивался на интервью Amazon и Google, требовали далеко не базового computer science

Ну, я называю это базовым. Мне так кажется.

Q: если кандидатам на junior и senior задают одинаковые вопросы, то как определяют, на какой grade взять разработчика?

Это определяется не по результатам coding interview, а по результатам system design и behavioral interview.

Q: как вообще Google?

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

Далее я расскажу о подготовке к интервью: как готовиться, как компании нанимают разработчиков, сколько потребуется времени


В Google и во многих подобных компаниях процесс выглядит так. Сначала нужно быть замеченным, пройти через рекрутера. Потом идет initial screening, где вам дают 1-3 coding interviews – те самые вопросы, которые мы обсуждали ранее.

Если вы это прошли, то вы переходите на onsite. Там будет большой набор из интервью, обычно от 2 до 4 coding, плюс system design и behavioral. Если вы хорошо показали себя на onsite, то вы получаете offer. У Google в него включается ваша зарплата, relocation bonus – оплата переезда. Часто в offer включат акции компании; я получала такой offer, который их включал – но не сразу, а через год работы.

На первом этапе надо сделать так, чтобы тебя заметили. Я от себя советую попробовать найти кого-то из компании, поговорить с людьми, которые в компании. Так вам станет немного понятна внутренняя культура компании. Кроме того, если вы друг другу понравились, то человек, который в компании, сможет вас порекомендовать – статистика показывает, что рекомендации увеличивают шанс прохождения первого этапа («быть замеченным») в 8 раз относительно заявок через сайт. Ну, для кого-то и заявки через сайт работают.

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

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

  • краткость: уложитесь в 1 страницу
  • ориентация на результаты: опишите свои достижения — «достиг X, сделав Y с помощью Z»
  • ориентация на данные: опишите масштаб ваших проектов – загрузку, прибыль и т.д.
  • ссылки: приведите ссылки для демонстрации ваших проектов
  • оценка: попросите кого-нибудь оценить ваше резюме перед отсылкой
  • меньше специализированных терминов: вас должны понимать

Но, наверно, очень важно сказать, что это довольно сложно сделать одному. По крайней мере, мне было сложно: нужно описывать себя, описывать свои достижения, сделать это хорошим языком, понятным другому человеку. Это хорошо делать с другом, с коллегой; можно прийти к нам, в Verbetcetera, к ментору – попробовать сделать свое резюме так, чтобы его было легко читать, и оно производило хорошее впечатление.

Дальнейшая подготовка обычно состоит из решения задач – например, на том же leetcode – на разные темы, на языке, который вы выбрали. Это может быть JavaScript, Typescript, C++, Java, Python и так далее. Очень многие языки. Еще классно иметь практику в парах – проводить практические интервью для тренировки процесса, это называется mock interview. Вы можете практиковаться с друзьями, есть и специальные сервисы; мы тоже предоставляем такую услугу – можно приходить и практиковаться с ментором. И еще – вы пытаетесь повысить свои шансы получить оффер тем, что вы подаете во многие компании. Проходите интервью, и в итоге куда-то попадаете (туда, куда хотите, я надеюсь); конечно, чтобы эта схема сработала, важно иметь хороший фундамент computer science.

Я интервьюировала нескольких человек, которые недавно проходили в Google, и получалось так: одной-двух недель никому не хватает. Никто не сказал мне, что за две недели подготовился к интервью и прошел. Часто требуется 2-3 месяца, и при этом человек занимается по 8 часов в день. И для этого все равно требуется фундамент – из института, со специальных курсов, чтобы такие задачи не были совершенно новыми. Кто-то на leetcode писал, что весь процесс занял год (правда, этот человек одновременно работал).

Q: какие зарплаты предлагают?

Можете посмотреть на Glassdoor, там можно узнать, какие зарплаты в какой компании предлагаются (в среднем).

Q: Есть ли у вас менторы на .NET-стеке?

Мы как бы не готовим на конкретный язык, у нас менторство по алгоритмам и system design. Конкретный язык для нас не имеет значения, мы не подтягиваем по языку.

Разберем последнее интервью – system design interview. Что это за интервью, какие тут существуют ошибки и мифы, и как к нему готовиться.

Это интервью определяет ваш grade (уровень) в компании. На нем задаются сложные открытые вопросы. Например, «как бы вы написали Google Docs (или Instagram, или Facebook Messenger)». Естественно, для system design interview разные ожидания: если вы junior, от вас практически ничего не ожидается. Но, если вы senior, вы должны классно себя проявить.

Я встречала такое мнение, что к этому интервью бесполезно готовиться: либо у вас уже есть знания и опыт, либо нет. Конечно, знания по system design не появляются сами по себе с наработкой опыта (хотя опыт помогает), но я бы рекомендовала готовиться к этому интервью всем – и junior в том числе.

Структурирование опыта здорово помогает. Вы начинаете видеть за пределами своего маленького кусочка кода, видеть компоненты, видеть целиком процесс, то, как выглядит продукт, из каких серверов, балансировщиков, кэшов он состоит, где в этом продукте могут быть узкие места и уязвимости, как его можно расширить, что делать, если он будет расти. Подготовка к system design interview помогает расти как разработчику, она существенно влияет на offer и позицию. Если вы по сути senior или хороший middle, но вы не готовитесь, то вас, видимо, возьмут на позицию junior, и вам придется уже внутри компании проходить процесс promotion – подтверждения peer review и все остальное, чтобы прийти на позицию, которую вы уже, возможно, занимали в другой компании. Поэтому есть большой смысл готовиться, чтобы сэкономить себе время и получить сразу классный offer. Конечно, offers на позиции senior и junior сильно отличаются – в Google это десятки тысяч евро.

Готовиться к system design interview гораздо сложнее, чем к coding. Нет никакой тестовой системы, которая скажет, что было правильно, а что неправильно. Важно иметь какого-то человека (обычно какого-нибудь senior-разработчика), который бы дал тебе feedback на то, насколько адекватно ты отвечаешь на вопросы. Очень классно иметь базу структурированных знаний и много практиковаться в парах. Можно приходить на system design mock interview, которые мы делаем в Verbetcetera. Также мы думаем когда-нибудь сделать курс по system design.

Общий фреймворк того, как вести себя на system design interview, очень похож на фреймворк для coding interview. Не надо торопиться в начале, надо задавать уточняющие вопросы, пытаться понять, в чем состоит задача. Никогда не нужно сразу начинать решать или давать какой-то ответ, который вы запомнили с какого-то сайта; возможно, в голове у вас и у интервьюера совершенно разные задачи – важно изначально это согласовать, очень много внимания уделять общению и пониманию. Второй этап после согласования задачи – начертить высокоуровневый дизайн для задачи, и его тоже согласовать. После этого надо обсудить, какие в этом дизайне могут возникнуть проблемы, что в нем наиболее интересно, и погрузиться в самую важную и интересную проблему. Под конец интервью надо еще раз пройтись по нему, резюмировать свое решение и предложить какие-нибудь идеи насчет того, что еще может быть сделано и улучшено. И все это нужно сделать минут за 45 (даже меньше, потому что бывают всякие технические заминки) – это очень сложно сделать с ходу, нужно готовиться.

Q: где-то есть профили всех менторов?

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

Q: по каким направлениям ментор оценивает? Только навыки программирования, или еще английский и навыки самопрезентации?

Вас оценивают по навыкам программирования, по умению решать задачи; английский должен быть достаточным для коммуникации (не нужен супер-уровень). Самопрезентация, наверно, тоже влияет, но не так сильно. Наверно, сильнее влияет то, насколько вы адекватный человек? Если вы придете на behavioral interview и говорите, что ненавидите клиентов, наверно, вам не дадут offer, несмотря на навыки самопрезентации.

Q: если senior завалил system design, то предлагают ли ему позицию middle/junior?

Да, обычно просто даунгрейдят. Это распространенная ситуация: senior просто не готовится к system design, заваливает его, и ему предлагают начальную позицию. Но, естественно, если у человека действительно есть level, то он может быстрее обычного расти внутри компании. Немного обидно будет, конечно, что не взяли сразу на senior после интервью.

Q: Эти mock interview по дизайну в РБ (не расслышал название, где и как проводятся, можно более точную ссылку?) у вас проходят на английском или на русском языке? Вообще, менторы у вас из каких стран?

Все mock interview проходят на английском, потому что в реальности они будут проходить на английском. Менторы распределены; я в России, большинство – в Европе, в Англии. Довольно разрозненная компания из разных уголков мира. Ссылка, наверно, будет в описании ролика.

Q: можно ли будет скачать презентацию?

Я не думаю, но можно будет посмотреть в ролике.

Q: mock interview онлайн или оффлайн для москвичей?

Об опции оффлайн мы еще не думали, пока все в онлайне.

Итак, мы сегодня обсудили coding interview – какие вопросы на них задают, популярные ошибки и мифы, как готовиться, сколько времени это занимает (чтобы вы реалистично подходили к процессу и не думали, что у всех это занимает всего 2 недели). И system design – зачем к нему готовиться, и как это вам поможет.

Еще я хотела сделать объявление. Мы хотим набрать курс: если кто-то из ребят хочет разобраться в алгоритмах, которые нужны для tech interview – мы набираем группы, с марта. Группы маленькие, по 3-5 человек или меньше (почти индивидуальные занятия), для работы с менторами из FAANG. Мы в течение трех месяцев будем проходить все основы, которые нужны для подготовки к техническим интервью. Чтобы, если вы чувствуете, что вы на этой теме провисаете, у вас сложился наконец-то хороший фундамент, и вы себя почувствовали уверенно. Это особенно подходит для людей, которые не могут выделить fulltime для подготовки к интервью, которые работают активно — такой формат курса может подойти.

И, если у вас скоро интервью – приходите к нам на mock interview. По алгоритмам, по system design; когда мы его сделаем, будет курс по system design. Я буду очень рада, если вы придете.

Q: будут ли еще наборы, например, в мае?

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

Будьте готовы, вкладывайте в себя и в свои знания. Вы все классные, у вас все получится.

Let's block ads! (Why?)

Что такое свидетельство?

Эта статья из цикла, возможно Вы что то пропустили.

Эта статья является частью цикла «Занимательная картография (Краткое введение в рациональность)»

Почему нам кажется, что реальность работает каким-то определённым образом? Откуда берутся убеждения о том, как устроены явления окружающие нас? Должны ли мы одинаково доверять всем таким убеждениям?

Откуда берётся Карта?

Начнём с чистого листа. Буквально. Представьте, что у Вас нет никакой карты, только лист бумаги и чертёжные принадлежности. Как Вы можете её нарисовать?

Вариант 1: Вы можете пойти и посмотреть, что там на территории. Если увидите дерево, то можете нарисовать дерево. В данном случае связь между деревом на территории и деревом на карте максимально короткая. Дерево на карте существует, ПОТОМУ что Вы увидели его на территории. Конечно, на деле Вы могли немного промахнуться. Поставить его чуть левее того забора. Но связь короткая. Вы, по крайней мере, не перепутаете дерево с горой. Хотя всё ещё можете перепутать куст с собакой, особенно ночью.

У данного варианта есть минус. Территорию нужно обходить самостоятельно, а много Вы так не обойдёте.

Вариант 2: Скопировать ранее составленные карты других людей. Вариант очевидно хорош. Так Вы сможете быстро составить представление об огромной территории.

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

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

Свидетельства за и против

Генерал сидел в штабе. Вокруг одни враги. В штаб зашёл его подчинённый – майор разведки. Он принёс карту новой местности, на которой вчера с трудом закрепились. Но ведь кругом враги, что если они подменили карту у майора прямо перед входом? Или может майор сам уже враг? Ох уж эти шпионские игры. Но как проверить соответствует ли карта территории? В течение часа, ломая голову над этим вопросом (а ещё над вопросом, не живёт ли он в симуляции врагов), Генерал решил предпринять максимально нестандартный для себя ход. Он решил сравнить кусок карты, описывающий опушку вокруг штаба и собственно опушку вокруг штаба. Он вышел и посмотрел вокруг. Опушка соответствовала. Но Генерал не стал делать вывод обо всей карте сразу. Однако он отметил, что раз здесь карта совпала с территорией, он ОБЯЗАН чуть-чуть повысить своё доверие к ней.

Давайте назовём ситуацию, когда Вы обнаруживаете объект с карты на реальной территории – свидетельством в пользу (см. UPD) этой карты. Ведь прогноз карты сбылся, а это явно говорит за то, чтобы ей доверять.
Если же карта не предсказывает какой-то объект на территории, или предсказывает несуществующий объект – назовём это свидетельством против данной карты.

Убеждения, как и карты, рождают прогнозы. Если прогноз сбывается, это свидетельство в пользу убеждения (подтверждающие), если прогноз не сбывается – свидетельство против (опровергающие).

«Доверяйте свидетелям тогда, когда не задеты их интересы, их пристрастия и предрассудки, а также жажда чудес. Когда же замешаны эти чувства, требуйте подтверждений — тем больше, чем сильнее противоречат вероятности их утверждения» Томас Генри Гексли.

Баланс свидетельств

А ещё Генерал решил, что он тем слабее повысит своё доверие к карте (и Майору), чем меньшую часть карты он проверил. То есть если карта описывает целый континент, а он осмотрел только одну опушку около штаба, то его уверенность в данной карте должна повыситься совсем незначительно. А если карта описывает совсем маленькую территорию (в два раза больше опушки, например), то это обязано сильно повысить его уверенность в ней. Если же он проверит три опушки, а совпадут две, значит стоит ожидать, что из следующих трёх опушек одна вновь будет неверная. Необходимо обновлять свою уверенность в карте с каждой новой опушкой.

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

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

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

Доверие источникам

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

Иными словами, если Вы кому-то (или во что-то) сильно верите, Вы ОБЯЗАНЫ иметь много свидетельств за (тут дело и в качестве и в количестве, как и завещал Генерал). То есть причиной доверия к источнику, служит то, что он даёт Вам точные убеждения. А точность этих убеждений определяется балансом свидетельств.

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

Абсолютно слепая вера

Как только мы отвязываем нашу уверенность от свидетельств – мы слепнем. Если мы придём к Генералу и скажем ему, что карта верна вне зависимости от того, что он видит на опушке, он сочтёт нас за шпиона. Но предположим, мы всё же верим, что карта описывает территорию на 100% точно. Что мы должны делать, если своими глазами увидим свидетельство против? Игнорировать территорию не лучшая идея. Если «абсолютная» карта говорит что впереди мост, а Вы не видите моста, то помните: реальность не спросит Вас, во что Вы верите.

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


Псс. А ещё у меня есть канал в телеграмме.

UPD: В комментариях вполне резонно попросили обосновать выбор терминов "Свидетельство за" и "Свидетельство против". Технически любое свидетельство просто сдвигает степень уверенности во всех картах которые описывают наличие или отсутствие данного объекта (причём чем сильнее они его ожидают, тем сильнее сдвигается степень уверенности). Если карта очень уверена в существовании некоторого объекта на территории, а другая карта менее уверена, то в случае если объекта нет — первая получит больший удар по репутации, чем вторая. Но если объект есть, первая получит больший бонус чем вторая. На знак это не повлияет. Если объект есть и карта его предсказывает — плюс, если нет — минус.

Поэтому мы можем смело сказать: если прогноз карты совпал с территорией — это однозначно аргумент в пользу этой карты (свидетельство за). С оговоркой, что на силу аргумента влияет ряд факторов. Данные факторы я планирую рассмотреть в отдельной серии постов (здесь будет ссылка).

Let's block ads! (Why?)