Русский
Русский
English
Статистика
Реклама

Книга

Игры, которые играют в людей что книга Игра в цифры рассказывает об игровой аналитике

10.03.2021 12:22:46 | Автор: admin
Из когда-то нишевого сегмента рынка игры сегодня превратились в высокодоходный транснациональный бизнес, опережающий по масштабам музыкальную индустрию и кинематограф. В игры уже вовлечено более 2,5 млрд человек (и это совсем не предел), а выручка ежегодно бьет новые рекорды. Причина этого не только в доступности игр и в росте свободного времени у населения: под капотом современных игр находятся технологии вовлечения, эффективно использующие математику, поведенческую экономику, психологию и дизайн. А в основе этих технологий системы игровой аналитики: именно они позволяют отследить поведение пользователей и определить наиболее цепляющие инструменты. И, в конечном счете, сделать так, чтобы люди проводили в играх как можно больше времени, получали максимум удовольствия и приносили максимум денег разработчикам.

Аналитика, таким образом, это кровеносная система современных игр, особенно в сегменте free-to-play (большинство бесплатных игр, в которых вам оставляют возможность заплатить за улучшения).

image

В конце прошлого года вышла книга Василия Сабирова Игра в цифры первое российское издание, полностью посвященное игровой (и продуктовой) аналитике. Под катом обзорный пересказ книги.

Дружелюбный гайд с небольшими недостатками


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

Однако книга не лишена недостатков. Один из них то, что материал не вполне актуализирован. Точнее, не создает такого впечатления. По мере чтения понимаешь, что основой Игры в цифры стали статьи из корпоративного блога, публичных докладов и выступлений автора, которые дополнили и собрали под одной обложкой. На момент первой публикации, а это период с 2016 по 2019 гг., это была очевидно актуальная информация. Но сейчас скриншоты, диаграммы и примеры с 3-5-летними датами, как минимум, выглядят устаревшими: всем известно, какими темпами развивается и меняется игровая индустрия. И читатель, встретивший не очень свежую диаграмму, может и остальную информацию воспринять как устаревшую (хотя это совсем не так).

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

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

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

Измеряй и властвуй!


image

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

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

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

Важнейший этап развития проекта soft launch (выпуск игры для ограниченной аудитории для тестирования и проверки на прочность). Наиболее популярные метрики на этом этапе:

  • 0-day Retention: доля вернувшихся в игру в течение 24 часов;
  • 1-day Retention: доля вернувшихся на следующий день;
  • Tutorial Retention и конверсия туториала: доля тех, кто прошел обучение (а также скорость его прохождения и доля тех, кто пропустил этот этап);
  • накопительный ARPU за N дней: сколько выручки в среднем приносит аудитория за период;
  • 7-day Retention: доля игроков, вернувшихся в игру через 7 дней после первого запуска.

image
Карта популярных метрик

Все метрики, при этом, в идеале должны быть основаны на определенном идейном фундаменте. И это тоже метрика, которая называется North-Star Metric (метрика Полярной звезды, NSM) и напрямую связана с уровнем лояльности пользователей. Полярная звезда объединяет доходность проекта, ценность для пользователей и измеримость. Определяя свою NSM, разработчики тем самым отвечают на вопрос для чего всё это, что в их бизнесе является ключевым.

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

Одна из важных задач аналитика выявить закономерности оттока (churn rate) игроков. Причинами оттока могут быть различные факторы качество самого продукта, высокая стоимость, привлечение нецелевой аудитории, переполненный рынок, проблемы с уровнем сложности (слишком хардкорный или, наоборот, без челленджа) и т.д. Соответственно, книга предлагает несколько путей уменьшения churn rate, в том числе:

  • создать правильное впечатление во время первой сессии, от которой зависит очень многое и которая определяет retention последующих дней;
  • изучать отзывы пользователей о приложении, чтобы понять, чем они недовольны и чего не хватает, а также использовать метрику Net Promoter Scope (NPS, индекс потребительской лояльности, основанный на опросах типа какова вероятность, что вы порекомендуете нашу игру);
  • напоминать пользователям о продукте, сообщать о новых функциях, бонусах, персональных предложениях посредством push- и email-уведомлений.
  • варьировать сложность, чтобы поддерживать интерес игроков.
  • быть лучше конкурентов, изучать потребности клиентов, их изменение, развивать и совершенствовать продукт.

Как только у проекта набирается пул игроков, в ход идут метрики игровой активности. Они учитывают, сколько активных пользователей (т.е. тех игроков, у которых была хотя бы одна сессия) получает игра за определенный период как правило, за день (метрика DAU), неделю (WAU) и месяц (MAU). Дополнительные показатели CCU (Сoncurrent Users пользователи, находящиеся в приложении в данный момент) и PCCU (пиковый показатель одновременной посещаемости).
Количество активных пользователей один из важнейших показателей продукта, который косвенно указывает на его успешность, сочетая в себе и качество привлечения новых пользователей, и метрики удержания, непосредственно влияя на доход. Поэтому при анализе активных пользователей стоит обращать внимание еще и на скорость роста аудитории, ведь эта метрика является одним из самых позитивных признаков активного развития продукта.

Монетизация и как ее не упустить


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

image
Пример, показывающий суммы и количество транзакций разных сегментов пользователей

  • Конверсию в платеж нужно считать не общей массой, а отдельно для первых и повторных платежей, а также учитывать платежи в разрезе стадий или уровней игры.
  • При анализе конверсии обязательно применять когортный подход для разных партий пользователей ее показатель может заметно отличаться. В особенности это важно, если вы проводите эксперименты по привлечению пользователей и оцениваете их эффективность.
  • Важная монетизационная метрика Paying Share, т.е. доля платящих пользователей от всей аудитории за определенный период. Зачастую она очень небольшая за исключением 1-2%, пользователи f2p-игр предпочитают не платить. Платящие игроки это самые ценные в проекте, но ведут они себя очень по-разному. Поэтому аналитику необходимо правильно их сегментировать, так чтобы пребывание в продукте стало для них максимально удобным и полезным.
  • Традиционно среди платящих пользователей выделяю три основных категории по размеру платежей: киты (whales, самые крупные платежи), дельфины (dolphins, середнячки) и пескари (minnows, небольшие суммы), плюс промежуточные сегменты. Другие варианты по количеству совершенных платежей (как часто платят), по времени совершения платежа (демонстрирует скорость конвертации).
  • Киты приносят основной доход, но найти их очень непросто. Как правило, киты покупают премиум-аккаунты, дополнительные уровни, необычное оружие и игровые предметы. Одна из задач геймдизайнеров найти потенциальных китов среди уже существующих игроков и предоставить им возможность потратить ту сумму, которую они готовы отдать.
  • Отдельный инструмент сегментации RFM-анализ: пользователи делятся на группы в зависимости от давности (Recency), частоты (Frequency) и общей суммы (Monetary) их платежей. По каждому из критериев выставляются баллы, и итоговая сумма баллов относит пользователя к тому или иному сегменту. В итоге можно выделить тех, кто платит часто, много и недавно (и направить ресурсы на их удержание), тех, кто платил мало и недавно (и стимулировать их на повторные платежи), или же тех, кто платил много, часто, но давно (и попробовать вернуть их в проект через push-уведомление, бонус или скидку).
  • Хорошо известный аналитикам показатель ARPU, средний доход с приложения на одного пользователя. ARPU позволяет увидеть, насколько эффективны ценовые эксперименты, правильный ли трафик мы используем, на правильный ли сегмент мы нацелились для монетизации. Чем выше ARPU тем больше доход игры. Производные от этой метрики ARPPU (средний доход от платящих пользователей) и Cumulative ARPU (суммарная выручка за определенный период от определенной когорты пользователей). Эти метрики позволяют прогнозировать, когда и какую сумму вам принесут новые пользователи из разных сегментов.
  • Еще одна важный инструмент, предлагаемый автором, FTPUE (First Time Paying User Experience). Это анализ тех обстоятельств и событий, которые сопровождают первую покупку. Важно понять, чем руководствуется пользователь, что его стимулирует и проверить гипотезы на других пользователях.

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

Культура аналитики


Заключительная часть книги посвящена вопросу развития data-driven-культуры подхода к управлению компанией на основе данных. Во главу угла ставится не интуиция и произвольные решения, а A/B-тест контролируемый способ проверки гипотез. В работе data-driven-компаниях выделяются несколько этапов: подготовка и анализ данных (именно это и делает аналитик); принятие решения, исходя из полученной информации (и опытный аналитик должен такое решение предложить); наконец, реализация решения, которая вновь запускает цикл процессов с начала.
Можно выделить следующие особенности data driven-культуры.

  • Руководители data-грамотны; они знают, что без отчета никуда.
  • Высокая культура A/B-тестирования. Если мы не уверены (а так чаще всего и бывает) мы проверяем гипотезу через сплит-тест.
  • Аналитики генерируют идеи, а не только предоставляют отчеты. Проактивность, запомните!
  • Совместный синтез гипотез. Аналитик в принятии решений ничуть не менее важен, чем продюсер.
  • Мы не знаем ответ, давайте найдем его с помощью анализа. Выжжем эту фразу на сердце железом раскаленным.


Заключение


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

Подробнее..

TypeScript. Продвинутые типы

10.09.2020 16:11:14 | Автор: admin
imageПривет, Хаброжители! Мы сдали в типографию очередную новинку
"Профессиональный TypeScript. Разработка масштабируемых JavaScript-приложений".
В этой книге программисты, которые уже знакомы с JavaScript на среднем уровне, узнают, как освоить TypeScript. Вы поймете, как TypeScript поможет масштабировать код в 10 раз лучше и снова сделать программирование увлекательным.

Вашему вниманию представлен отрывок одной главы из книги Продвинутые типы.

Продвинутые типы


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

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

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

Связи между типами

Рассмотрим связи в TypeScript подробнее.

Подтипы и супертипы

Мы уже затрагивали совместимость в разделе О типах на с. 34, поэтому сразу углубимся в эту тему, начиная с определения подтипа.
image


Вернитесь к рис. 3.1 и увидите встроенные в TypeScript связи подтипов.
image


Массив является подтипом объекта.

Кортеж является подтипом массива.

Все является подтипом any.

never является подтипом всего.

Класс Bird, расширяющий класс Animal, это подтип класса Animal.

Согласно определению, которое я только что дал для подтипа, это значит, что:

Везде, где нужен объект, можно использовать массив.

Везде, где нужен массив, можно использовать кортеж.

Везде, где нужен any, можно использовать объект.

Везде можно использовать never.

Везде, где нужен Animal, можно использовать Bird.
Супертип это противоположность подтипа.

СУПЕРТИП
Если у вас есть два типа, A и B, и при этом B является супертипом A, то вы можете безопасно использовать A везде, где требуется B (рис. 6.2).

image


И снова исходя из схемы на рис. 3.1:

Массив является супертипом кортежа.

Объект является супертипом массива.

Any является супертипом всего.

Never не является чьим-либо супертипом.

Animal это супертип Bird.
Это просто противоположный подтипам принцип и ничего более.

Вариантность

Для большинства типов достаточно легко понять, является ли некий тип A подтипом B. Для простых типов вроде number, string и др. можно обратиться к схеме на рис. 3.1 или самостоятельно определить, что number, содержащийся в объединении number | string, является подтипом этого объединения.

Но есть более сложные типы, например обобщенные. Подумайте над такими вопросами:

Когда Array является подтипом Array<В>?

Когда форма A является подтипом формы B?

Когда функция (a: A) => B является подтипом функции (c: C) => D?

Правила подтипизации для типов, содержащих другие типы (то есть имеющих параметры типа вроде Array, формы с полями вроде {a: number} или функции вроде (a: A) => B), осмысливать уже сложнее, потому что они не согласованы в разных языках программирования.

Чтобы облегчить чтение последующих правил, я представлю несколько элементов синтаксиса, который не работает в TypeScript (не беспокойтесь, он не математический):

A <: B означает, что A является подтипом того же, что и тип B;

A >: B означает, что A является супертипом того же, что и тип B.

Вариантность формы и массива

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

// Существующий пользователь, переданный с сервера.type ExistingUser = {    id: number   name: string}// Новый пользователь, еще не сохраненный на сервере.type NewUser = {   name: string}

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

function deleteUser(user: {id?: number, name: string}) {    delete user.id}let existingUser: ExistingUser = {    id: 123456,    name: 'Ima User'}deleteUser(existingUser)

deleteUser получает объект типа {id?: number, name: string} и передает в него existingUser типа {id: number, name: string}. Обратите внимание, что тип свойства id (number) это подтип ожидаемого типа (number | undefined). Следовательно, весь объект {id: number, name: string} это подтип {id?: number, name: string}, поэтому TypeScript это допускает.

Видите ли вы какие-либо проблемы с безопасностью? Есть одна: после передачи ExistingUser в deleteUser TypeScript не знает, что id пользователя был удален, поэтому если вы прочитаете existingUser.id после его удаления deleteUser(existingUser), то TypeScript по-прежнему будет считать, что existingUser.id имеет тип number.

Очевидно, что использование типа объекта там, где ожидается его супертип, небезопасно. Так почему же TypeScript это допускает? Суть в том, что он не задумывался как абсолютно безопасный. Его система типов стремится перехватывать реальные ошибки и делать их наглядными для программистов любого уровня. Поскольку деструктивные обновления (вроде удаления свойства) относительно редки на практике, TypeScript расслаблен и позволяет вам присвоить объект там, где ожидается его супертип.

А что насчет противоположного случая: можно ли присвоить объект там, где ожидается его подтип?

Добавим новый тип для старого пользователя, а затем удалим пользователя с этим типом (представьте, что вы добавляете типы в код, который написал ваш коллега):

type LegacyUser = {    id?: number | string    name: string}let legacyUser: LegacyUser = {    id: '793331',    name: 'Xin Yang'}deleteUser(legacyUser) // Ошибка TS2345: aргумент типа 'LegacyUser'                                  // несовместим с параметром типа                                  // '{id?: number |undefined, name: string}'.                                 // Тип 'string' несовместим с типом 'number |                                 // undefined'.

Когда вы передаете форму со свойством, чей тип является супертипом ожидаемого типа, TypeScript ругается. Все потому, что id это string | number | undefined, а deleteUser обрабатывает только тот случай, где id является number | undefined.

Ожидая форму, вы можете передать тип с типами свойств, которые <: ожидаемых типов, но не можете передать форму без типов свойств, являющихся супертипами их ожидаемых типов. Когда речь идет о типах, мы говорим: TypeScript-формы (объекты и классы) являются ковариантными в типах их свойств. То есть, чтобы объект A мог быть присвоен объекту B, каждое его свойство должно быть <: соответствующего ему свойства в B.
Ковариантность это один из четырех видов вариантности:
Инвариантность
Нужен конкретно T.
Ковариантность
Нужен <:T.
Контрвариантность
Нужен >:T.
Бивариантность
Устроит либо <:T, либо >:T.
В TypeScript каждый сложный тип является ковариантным в своих членах объектах, классах, массивах и возвращаемых типах функций, за одним исключением: типы параметров функций контрвариантны.

Не все языки применяют такое же конструктивное решение. В одних объекты являются инвариантными в типах свойств, потому что ковариантные типы свойств могут вести к небезопасному поведению. Другие языки имеют разные правила для изменяемых и неизменяемых объектов (попробуйте порассуждать об этом самостоятельно). Третьи, вроде Scala, Kotlin и Flow, даже имеют явный синтаксис, позволяющий программистам определять вариантность типов данных.
Создатели TypeScript предпочли баланс: инвариантность объектов в типах свойств повышает безопасность, но усложняет использование системы типов, поскольку заставляет вас запрещать то, что на деле безопасно (например, если не удалять id в deleteUser, передача объекта, являющегося супертипом ожидаемого типа, все равно будет безопасной).

Вариантность функции

Рассмотрим несколько примеров.

Функция A является подтипом функции B, если A имеет такую же или меньшую арность (число параметров), чем B, и:
1. Тип this, принадлежащий A, либо не определен, либо >: типа this, принадлежащего B.

2. Каждый из параметров A >: соответствующего параметра в B.

3. Возвращаемый тип A <: возвращаемого типа B.

Обратите внимание, что для того, чтобы функция A могла быть подтипом функции B, ее тип this и параметры должны быть >: встречных частей в B, в то время как ее возвращаемый тип должен быть <:. Почему происходит разворот условия? Почему не работает просто условие <: для каждого компонента (типа this, типов параметров и возвращаемого типа), как в случае с объектами, массивами, объединениями и т. д.?

Начнем с определения трех типов (вместо class можно использовать другие типы, где A :< B <: C):

class Animal {}class Bird extends Animal {    chirp() {}}class Crow extends Bird {    caw() {}}

Итак, Crow <: Bird <: Animal.
Определим функцию, получающую Bird и заставляющую ее чирикать:

function chirp(bird: Bird): Bird {    bird.chirp()    return bird}

Пока все хорошо. Что TypeScript позволяет вам передать в chirp?

chirp(new Animal) // Ошибка TS2345: аргумент типа 'Animal'chirp(new Bird) // несовместим с параметром типа 'Bird'.chirp(new Crow)

Экземпляр Bird (как параметр chirp типа bird) или экземпляр Crow (как подтип Bird). Передача подтипа работает, как и ожидалось.
Создадим новую функцию. На этот раз ее параметр будет функцией:

function clone(f: (b: Bird) => Bird): void {    // ...}

clone требуется функция f, получающая Bird и возвращающая Bird. Какие типы функций можно передать для f безопасно? Очевидно, функцию, получающую и возвращающую Bird:

function birdToBird(b: Bird): Bird {    // ...}clone(birdToBird) // OK

Что насчет функции, получающей Bird, но возвращающей Crow или Animal?

function birdToCrow(d: Bird): Crow {    // ...}clone(birdToCrow) // OKfunction birdToAnimal(d: Bird): Animal {    // ...}clone(birdToAnimal) // Ошибка TS2345: аргумент типа '(d: Bird) =>                             // Animal' несовместим с параметром типа                            // '(b: Bird) => Bird'.Тип 'Animal'                           // несовместим с типом 'Bird'.

birdToCrow работает, как и ожидалось, но birdToAnimal выдает ошибку. Почему? Представьте, что реализация clone выглядит так:

function clone(f: (b: Bird) => Bird): void {    let parent = new Bird    let babyBird = f(parent)    babyBird.chirp()}

Передав функции clone функцию f, возвращающую Animal, мы не сможем вызвать в ней .chirp. Поэтому TypeScript должен убедиться, что переданная нами функция возвращает как минимум Bird.

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

function animalToBird(a: Animal): Bird {  // ...}clone(animalToBird) // OKfunction crowToBird(c: Crow): Bird {  // ...}clone(crowToBird)        // Ошибка TS2345: аргумент типа '(c: Crow) =>                        // Bird' несовместим с параметром типа '                       // (b: Bird) => Bird'.

Чтобы функция была совместима с другой функцией, все ее типы параметров (включая this) должны быть >: соответствующих им параметров в другой функции. Чтобы понять почему, подумайте о том, как пользователь мог бы реализовать crowToBird, прежде чем передавать ее в clone?

function crowToBird(c: Crow): Bird {  c.caw()  return new Bird}

TSC-ФЛАГ: STRICTFUNCTIONTYPES
Из-за наследования функции в TypeScript по умолчанию ковариантны в своих параметрах и типах this. Чтобы использовать более безопасное контрвариантное поведение, которое мы только что изучили, нужно активировать флаг {strictFunctionTypes: true} в tsconfig.json.
Если вы уже используете {strict: true}, то ничего дополнительно делать не нужно.

Теперь, если clone вызовет crowToBird с new Bird, мы получим исключение, поскольку .caw определен во всех Crow, но не во всех Bird.

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

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

Совместимость

Взаимосвязи подтипов и супертипов являются ключевой концепцией любого статически типизированного языка. Они также важны для понимания того, как работает совместимость (напомню, что совместимость относится к правилам TypeScript, определяющим возможность использования типа A там, где требуется тип B).

Когда TypeScript требуется ответить на вопрос: Совместим ли тип A с типом B?, он следует простым правилам. Для не enum-типов вроде массивов, логических типов, чисел, объектов, функций, классов, экземпляров классов и строк, включая типы литералов, A совместим с B, если верно одно из условий.

1. A <: B.

2.A является any.

Правило 1 это просто определение подтипа: если A является подтипом B, тогда везде, где нужен B, можно использовать A.

Правило 2 это исключение из правила 1 для удобства взаимодействия с кодом JavaScript.
Для типов перечислений, созданных ключевыми словами enum или const enum, тип A совместим с перечислением B, если верно одно из условий.

1. A является членом перечисления B.

2. B имеет хотя бы один член типа number, а A является number.

Правило 1 в точности такое же, как и для простых типов (если A является членом перечисления B, тогда A имеет тип B и мы говорим, что B <: B).

Правило 2 необходимо для удобства работы с перечислениями, которые серьезно подрывают безопасность в TypeScript (см. подраздел Enum на с. 60), и я рекомендую их избегать.

Расширение типов

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

В главе 3 вы уже видели несколько примеров расширения типов. Рассмотрим другие.
Когда вы объявляете переменную как изменяемую (с let или var), ее тип расширяется от типа значения ее литерала до базового типа, к которому литерал принадлежит:

let a = 'x' // stringlet b = 3   // numbervar c = true   // booleanconst d = {x: 3}   // {x: number}enum E {X, Y, Z}let e = E.X   // E

Это не касается неизменяемых деклараций:

const a = 'x' // 'x'const b = 3   // 3const c = true   // trueenum E {X, Y, Z}const e = E.X   // E.X

Можно использовать явную аннотацию типа, чтобы не допустить его расширения:

let a: 'x' = 'x' // 'x'let b: 3 = 3  // 3var c: true = true  // trueconst d: {x: 3} = {x: 3}  // {x: 3}

Когда вы повторно присваиваете нерасширенный тип с помощью let или var, TypeScript расширяет его за вас. Чтобы это предотвратить, добавьте явную аннотацию типа в оригинальную декларацию:

const a = 'x' // 'x'let b = a  // stringconst c: 'x' = 'x'  // 'x'let d = c  // 'x'

Переменные, инициализированные как null или undefined, расширяются до any:

let a = null // anya = 3  // anya = 'b'  // any

Но, когда переменная, инициализированная как null или undefined, покидает область, в которой была объявлена, TypeScript присваивает ей определенный тип:

function x() {   let a = null  // any   a = 3   // any   a = 'b'   // any   return a}x()   // string

Тип const

Тип const помогает отказаться от расширения декларации типа. Используйте его как утверждение типа (см. подраздел Утверждения типов на с. 185):

let a = {x: 3}   // {x: number}let b: {x: 3}    // {x: 3}let c = {x: 3} as const   // {readonly x: 3}

const исключает расширение типа и рекурсивно отмечает его члены как readonly даже в глубоко вложенных структурах данных:

let d = [1, {x: 2}]              // (number | {x: number})[]let e = [1, {x: 2}] as const    // readonly [1, {readonly x: 2}]

Используйте as const, когда хотите, чтобы TypeScript вывел максимально узкий тип.

Проверка лишних свойств

Расширение типов также фигурирует, когда TypeScript проверяет, является ли один тип объекта совместимым с другим типом объекта.

Типы объектов ковариантны в их членах (см. подраздел Вариантность формы и массива на с. 148). Но, если TypeScript будет следовать этому правилу без дополнительных проверок, могут возникнуть проблемы.

Например, рассмотрите объект Options, который можно передать в класс для его настройки:

type Options = {    baseURL: string    cacheSize?: number    tier?: 'prod' | 'dev'}class API {    constructor(private options: Options) {}}new API({     baseURL: 'https://api.mysite.com',     tier: 'prod'})

Что произойдет теперь, если вы допустите ошибку в опции?

new API({   baseURL: 'https://api.mysite.com',   tierr: 'prod'         // Ошибка TS2345: аргумент типа '{tierr: string}'})                      // несовместим с параметром типа 'Options'.                        // Объектный литерал может определять только                       // известные свойства, но 'tierr' не существует                      // в типе 'Options'. Вы хотели написать 'tier'?

Это распространенный баг при работе в JavaScript, и хорошо, что TypeScript помогает его перехватить. Но если типы объектов ковариантны в их членах, как TypeScript его перехватывает?

Иначе говоря:

Мы ожидали тип {baseURL: string, cacheSize?: number, tier?: 'prod' | 'dev'}.

Мы передали тип {baseURL: string, tierr: string}.

Переданный тип это подтип ожидаемого типа, но TypeScript знал, что надо сообщить об ошибке.

Благодаря проверке лишних свойств, когда вы пытаетесь присвоить новый тип объектного литерала T другому типу, U, а в T есть свойства, которых нет в U, TypeScript сообщает об ошибке.

Новый тип объектного литерала это тип, который TypeScript вывел из объектного литерала. Если этот объектный литерал использует утверждение типа (см. подраздел Утверждения типов на с. 185) или присвоен переменной, тогда новый тип расширяется до регулярного типа объекта и его новизна пропадает.

Попробуем сделать это определение более емким:

type Options = {     baseURL: string     cacheSize?: number     tier?: 'prod' | 'dev'}class API {    constructor(private options: Options) {}}new API({     baseURL: 'https://api.mysite.com',    tier: 'prod'})new API({     baseURL: 'https://api.mysite.com',    badTier: 'prod' // Ошибка TS2345: аргумент типа '{baseURL:}) // string; badTier: string}' несовместим// с параметром типа 'Options'.new API({     baseURL: 'https://api.mysite.com',    badTier: 'prod'} as Options)let badOptions = {     baseURL: 'https://api.mysite.com',    badTier: 'prod'}new API(badOptions)let options: Options = {     baseURL: 'https://api.mysite.com',    badTier: 'prod' // Ошибка TS2322: тип '{baseURL: string;} // badTier: string}'несовместим с типом// 'Options'.new API(options)

Инстанцинируем API с baseURL и одно из двух опциональных свойств: tier. Все работает.

Ошибочно прописываем tier как badTier. Объект опций, который мы передаем в new API, новый (его тип выведен, он несовместим с переменной, и мы не делаем для него утверждения типа), поэтому при проверке лишних свойств TypeScript обнаруживает лишнее свойство badTier (которое определено в объекте опций, но не в типе Options).

Делаем утверждение, что неверный объект опций имеет тип Options. TypeScript больше не рассматривает его как новый и делает заключение из проверки лишних свойств, что ошибок нет. Синтаксис as T описан в подразделе Утверждения типов на с. 185.

Присваиваем объект опций к переменной badOptions. TypeScript больше не воспринимает его как новый и, произведя проверку лишних свойств, делает заключение, что ошибок нет.

Когда мы явно типизируем options как Options, объект, присваиваемый нами options, является новым, поэтому TypeScript выполняет проверку лишних свойств и находит баг. Заметьте, что в этом случае проверка лишних свойств не производится, когда мы передаем options в new API, но она происходит, когда мы пытаемся присвоить объект опций к переменной options.

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

Уточнение

TypeScript производит символическое выполнение вывода типов. Модуль проверки типов использует инструкции потока команд (вроде if, ?, || и switch) наряду с запросами типов (вроде typeof, instanceof и in), тем самым уточняя типы по ходу чтения кода, как это делал бы программист. Однако эта удобная особенность поддерживается весьма небольшим количеством языков.

Представьте, что вы разработали в TypeScript API для определения правил CSS и ваш коллега хочет использовать его, чтобы установить HTML-элемент width. Он передает ширину, которую вы хотите позднее разобрать и сверить.

Сначала реализуем функцию для разбора строки CSS в значение и единицу измерения:

// Мы используем объединение строчных литералов для описания// возможных значений, которые может иметь единица измерения CSStype Unit = 'cm' | 'px' | '%'// Перечисление единиц измеренияlet units: Unit[] = ['cm', 'px', '%']// Проверить каждую ед. изм. и вернуть null, если не будет совпаденийfunction parseUnit(value: string): Unit | null {  for (let i = 0; i < units.length; i++) {    if (value.endsWith(units[i])) {       return units[i]}}     return null}

Затем используем parseUnit, чтобы разобрать значение ширины, переданное пользователем. width может быт числом (возможно, в пикселах) или строкой с прикрепленными единицами измерения, или null, или undefined.

В этом примере мы несколько раз прибегаем к уточнению типа:

type Width = {     unit: Unit,     value: number}function parseWidth(width: number | string | null |undefined): Width | null {// Если width  null или undefined, вернуть заранее.if (width == null) {      return null}// Если width  number, предустановить пикселы.if (typeof width === 'number') {     return {unit: 'px', value: width}}// Попытка получить единицы измерения из width.let unit = parseUnit(width)if (unit) { return {unit, value: parseFloat(width)}}// В противном случае вернуть null.return null }

TypeScript способен понять, что свободная проверка равенства на соответствие null в JavaScript вернет true и для null, и для undefined. Он также знает, что если проверка пройдет, то мы сделаем возврат, а если мы не делаем возврат, значит, проверка не прошла и с этого момента тип width это number | string (он больше не может быть null или undefined). Мы говорим, что тип был уточнен из number | string | null | undefined в number | string.

Проверка typeof запрашивает значение при выполнении, чтобы увидеть его тип. TypeScript также пользуется преимуществом typeof во время компиляции: в ветви if, где проверка проходит, TypeScript знает, что width это number. В противном случае (если эта ветка делает return) width должна быть string единственным оставшимся типом.

Поскольку parseUnit может вернуть null, мы проверяем это. TypeScript знает, что, если unit верна, тогда она должна иметь тип Unit в ветке if. В противном случае unit неверна, что значит ее тип null (уточненный из Unit | null).

В завершение мы возвращаем null. Это может случиться, только если пользователь передаст string для width, но эта строка будет содержать неподдерживаемые единицы измерения.
Я проговорил ход мыслей TypeScript в отношении каждого произведенного уточнения типа. TypeScript проделывает огромную работу, учитывая ваши рассуждения в процессе чтения и написания кода и кристаллизуя их в проверку типов и порядок их вывода.

Типы размеченного объединения

Как мы только что выяснили, TypeScript хорошо понимает принципы работы JavaScript и способен отслеживать наше уточнение типов, словно читая мысли.

Допустим, мы создаем систему пользовательских событий для приложения. Начинаем с определения типов событий наряду с функциями, обрабатывающими поступление этих событий. Представьте, что UserTextEvent моделирует событие клавиатуры (например, пользователь напечатал текст <input />), а UserMouseEvent моделирует событие мыши (пользователь сдвинул мышь в координаты [100, 200]):

type UserTextEvent = {value: string}type UserMouseEvent = {value: [number, number]}type UserEvent = UserTextEvent | UserMouseEventfunction handle(event: UserEvent) {     if (typeof event.value === 'string') {         event.value // string         // ...         return   }         event.value // [number, number]}

TypeScript знает, что внутри блока if event.value должен быть string (благодаря проверке typeof), то есть event.value после блока if должно быть кортежем [number, number] (из-за return в блоке if).

К чему приведет усложнение? Добавим уточнения к типам событий:

type UserTextEvent = {value: string, target: HTMLInputElement}type UserMouseEvent = {value: [number, number], target: HTMLElement}type UserEvent = UserTextEvent | UserMouseEventfunction handle(event: UserEvent) {    if (typeof event.value === 'string') {        event.value // string        event.target // HTMLInputElement | HTMLElement (!!!)        // ...        return   }  event.value // [number, number]  event.target // HTMLInputElement | HTMLElement (!!!)}

Хотя уточнение и сработало для event.value, этого не случилось для event.target. Почему? Когда handle получает параметр типа UserEvent, это не значит, что нужно передать ему либо UserTextEvent, либо UserMouseEvent, на деле можно передать аргумент типа UserMouseEvent | UserTextEvent. И поскольку члены объединения могут перекрываться, TypeScript требуется более надежный способ узнать, когда и какой случай объединения актуален.

Сделать это можно с помощью типов литералов и определения тега для каждого случая типа объединения. Хороший тег:

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

Типизирован как тип литерала (строчный литерал, численный, логический и т. д.). Можно смешивать и сопоставлять различные типы литералов, но лучше придерживаться единственного типа. Как правило, это тип строчного литерала.

Не универсален. Теги не должны получать аргументы обобщенных типов.

Взаимоисключающий (уникален внутри типа объединения).

Обновим типы событий с учетом вышесказанного:

type UserTextEvent = {type: 'TextEvent', value: string,                                        target: HTMLInputElement}type UserMouseEvent = {type: 'MouseEvent', value: [number, number],                                        target: HTMLElement}type UserEvent = UserTextEvent | UserMouseEventfunction handle(event: UserEvent) {   if (event.type === 'TextEvent') {       event.value // string       event.target // HTMLInputElement       // ...       return   }  event.value // [number, number]  event.target // HTMLElement}

Теперь, когда мы уточняем event на основе значения его размеченного поля (event.type), TypeScript знает, что в ветке if event должен быть UserTextEvent, а после ветки if он должен быть UserMouseEvent, Поскольку теги уникальны в каждом типе объединения, TypeScript знает, что они являются взаимоисключающими.

Используйте размеченные объединения при написании функции, обрабатывающей различные случаи типа объединения. К примеру, при работе с действиями Flux, восстановлениями в Redux или с useReducer в React.

Более подробно с книгой можно ознакомиться и оформить предзаказ по специальной цене на сайте издательства
Подробнее..

Книга TypeScript быстро

22.04.2021 12:11:11 | Автор: admin
image Привет, Хаброжители! TypeScript быстро научит вас секретам продуктивной разработки веб- или самостоятельных приложений. Она написана практиками для практиков. В книге разбираются актуальные для каждого программиста задачи, объясняется синтаксис языка и описывается разработка нескольких приложений, в том числе нетривиальных так вы сможете понять, как использовать TypeScript с популярными библиотеками и фреймворками. Вы разберетесь с превосходным инструментарием TypeScript и узнаете, как объединить в одном проекте TypeScript и JavaScript. Среди продвинутых тем, рассмотренных авторами, декораторы, асинхронная обработка и динамические импорты. Прочитав эту книгу, вы поймете, что именно делает TypeScript особенным.


ДЛЯ КОГО ЭТА КНИГА
Эта книга написана для инженеров ПО, которые хотят повысить продуктивность разработки веб- или самостоятельных приложений. Мы, ее авторы, являемся практиками и книгу писали для таких же практиков. В ней не только объясняется синтаксис языка на простых примерах, но также описывается разработка нескольких приложений так вы можете понять, как использовать TypeScript с популярными библиотеками и фреймворками.

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

Этот материал, в свою очередь, предполагает, что у читателей уже есть практические познания в HTML, CSS и JavaScript, использующем последние нововведения из спецификации ECMAScript. Если вам знаком только синтаксис ECMAScript 5, рекомендуем просмотреть приложение, чтобы лучше понимать примеры кода, используемые в книге. Приложение выполняет роль введения в современный JavaScript.

СТРУКТУРА КНИГИ
Эта книга состоит из двух частей. В части 1 мы рассматриваем различные элементы синтаксиса TypeScript, приводя для наглядности небольшие образцы кода. В части 2 мы используем TypeScript в нескольких версиях блокчейн-приложения. Если ваша цель как можно быстрее освоить синтаксис TypeScript и сопутствующие инструменты, тогда части 1 будет достаточно.

Глава 1 поможет начать разработку с помощью TypeScript. Вы скомпилируете и запустите самые простые программы, чтобы понять суть рабочего процесса от написания программ в TypeScript и до их компиляции в выполняемый JavaScript. Мы также рассмотрим преимущества программирования в TypeScript в сравнении с JavaScript и представим вам редактор Visual Studio Code.

Глава 2 поясняет, как объявлять переменные и функции с типами. Вы научитесь объявлять псевдонимы типов с помощью ключевого слова type, а также узнаете, как объявлять пользовательские типы с классами и интерфейсами. Это поможет понять разницу между номинальными и структурными системами типов.

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

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

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

Глава 6 посвящена сопутствующим инструментам. В ней мы рассказываем об использовании карт кода и TSLinter (несмотря на то, что TSLinter считается устаревшим, многие разработчики по-прежнему им пользуются). Затем мы покажем вам, как компилировать и обвязывать (bundle) приложения TypeScript с помощью Webpack. Вы также узнаете, как и зачем компилировать TypeScript с помощью Babel.

Глава 7 научит вас использовать библиотеки JavaScript в вашем TypeScript-приложении. Мы начнем с объяснения роли файлов определений типов, а затем представим небольшое приложение, использующее библиотеку JavaScript в приложении TypeScript. В завершение мы пройдем через весь процесс постепенного перевода имеющегося проекта JavaScript в TypeScript.

В части 2 мы используем TypeScript в блокчейн-приложении. Здесь вы можете подумать: Ни одна из компаний, где я работал, не использует блокчейн, так зачем мне его изучать, если моя цель освоение TypeScript? Мы не хотели, чтобы наш образец приложения был очередным стандартным примером, поэтому озадачились поиском горячей технологии, в которой можно было бы применить различные элементы TypeScript, а также техники, представленные в части 1. Знакомство с тем, как TypeScript может быть использован в нетривиальном приложении, придаст содержанию больше практичности, даже если вы не собираетесь использовать блокчейн в ближайшем будущем.

В этой части книги вы разработаете несколько блокчейн-приложений: самостоятельное приложение, браузерное приложение, а также приложения на Angular, React.js и Vue.js. При этом можете выбрать к прочтению только интересующие вас главы, но обязательно прочитайте главы 8 и 10, где объясняются основные принципы.

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

В главе 9 описывается создание веб-клиента для блокчейна. Это приложение не будет использовать никакие фреймворки; в нем мы задействуем только HTML, CSS и TypeScript. Мы также создадим небольшую библиотеку для генерации хеша, которую можно будет использовать как в веб-, так и в самостоятельных клиентах. Помимо этого, вы увидите, как производить отладку кода TypeScript в своем браузере.

Глава 10 рассматривает код блокчейн-приложения, использующего сервер обмена сообщениями для связи между членами блокчейна. Мы создадим Node.js и WebSocket сервер в TypeScript и покажем вам, как для достижения консенсуса блокчейн использует правило длиннейшей цепочки. Вы найдете практические примеры использования TypeScript интерфейсов, абстрактных классов, квалификаторов доступа, перечислений и обобщенных типов.

В главе 11 дается краткий обзор разработки веб-приложений в Angular при помощи TypeScript, а глава 12 рассматривает код блокчейн-веб-клиента, разработанного с помощью этого фреймворка.

Глава 13 дает краткое введение в разработку веб-приложений в React.js с помощью TypeScript, а глава 14 рассматривает код блокчейн-веб-клиента, разработанного с React.

Глава 15 аналогичным образом представляет разработку веб-приложений в Vue.js с помощью TypeScript, а глава 16 рассматривает блокчейн-веб-клиент, разработанный с использованием Vue.

ИСПОЛЬЗОВАНИЕ КОМПИЛЯТОРА BABEL


Babel это популярный JS-компилятор, предлагающий решение для широко известной проблемы: не все браузеры поддерживают весь набор возможностей, объявленных в ECMAScript. Мы даже не говорим о полной реализации конкретной версии ECMAScript. В любой момент времени один из браузеров может реализовать конкретную выборку возможностей из ECMAScript 2019, в то время как другой по-прежнему будет понимать только ECMAScript 5. Посетите сайт caniuse.com и поищите arrow functions (стрелочные функции). Вы увидите, что Internet Explorer 11, OperaMini и некоторые другие браузеры их не поддерживают.

Если вы разрабатываете новое веб-приложение, то захотите протестировать его для всех браузеров, которые могут использоваться вашей целевой аудиторией. Babel позволяет вам писать современный JS и компилировать его в более старые версии. Несмотря на то что tsc дает возможность указать для компиляции конкретную целевую спецификацию ECMAScript (например, ES2019), Babel более точен. Он позволяет выборочно указать возможности языка, которые требуется трансформировать в JavaScript, поддерживаемый старыми браузерами.

На рис. 6.9 показан фрагмент таблицы совместимости с браузерами (из mng.bz/O9qw). Сверху вы видите названия браузеров и компиляторов, а слева расположен список возможностей. Браузер, компилятор или среда выполнения сервера могут полностью либо частично поддерживать некоторые из перечисленных возможностей, а плагины Babel позволяют указывать только конкретные из них, которые требуется трансформировать в более старый код. Полный список плагинов можно посмотреть в документации Babel: babeljs.io/docs/en/plugins.

image


В целях этого рассмотрения мы выбрали функцию Обрезка строк из ES2019 (см. черную стрелку слева от рис. 6.9). Давайте предположим, что наше приложение должно работать в браузере Edge. Проследуйте по вертикальной стрелке, и вы увидите, что Edge 18 на данный момент реализует обрезку строк только частично (2/4).

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

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

В разделе A.12 приложения мы включили скриншот из babeljs.io, иллюстрирующий Babel-инструмент REPL. Взгляните на меню Babel Try it now, показанное на рис. 6.10, где вы увидите навигационную панель, позволяющую конфигурировать предустановки.

Каждая предустановка просто является группой плагинов, и если вы хотите скомпилировать код в синтаксис ES2015, достаточно отметить галочкой es2015. Вместо указания имен спецификаций ECMAScript вы можете настраивать конкретные версии браузеров или других сред выполнения, используя опцию ENV PRESET. Белая стрелка на рис. 6.10 показывает редактируемое окошко с предполагаемыми значениями для предустановки ENV: >2%, ie11, safari>9. Это означает, что вы хотите, чтобы Babel скомпилировал код для запуска во всех браузерах, имеющих рыночный охват не менее 2%, а также в Internet Explorer 11 и Safari.

Ни IE11, ни Safari 9 не поддерживают стрелочные функции, и если вы введете (a, b) ?a+b;, Babel преобразует это в JS, который перечисленные браузеры понимают, как показано в правой части рис. 6.11.

СОВЕТ Если вы видите ошибки после ввода имен браузеров, уберите галочку Enabled после введения браузеров и версий. Это похоже на баг, но к моменту прочтения вами этой книги он может быть уже устранен.

Теперь давайте изменим предустановку на last 2 chrome versions (две последние версии Chrome), как показано на рис. 6.12. Babel достаточно сообразителен, чтобы понять, что последние две версии Chrome поддерживают стрелочные функции и нет нужды производить преобразование.

image

Предустановка ENV идет со списком браузеров, и вам нужно использовать верные имена и фразы, чтобы указать ограничения (например, last2majorversions, Firefox>=20 или >5% in US). Эти фразы перечислены в проекте browserslist, который доступен здесь: github.com/browserslist/browserslist.

Мы использовали предустановку ENV в Babel REPL, чтобы поиграть с целевыми средами, но эти настройки могут быть также сконфигурированы и использованы из командной строки. В листинге 6.15 мы добавим в файл конфигурации .babelrc следующее: babel/preset-env. В листинге 6.17 вы увидите файл .browserlistrc, в котором вы можете настроить конкретные браузеры и версии, как мы делали в Babel REPL. Подробнее о preset-env вы можете прочитать в документации Babel здесь: babeljs.io/docs/en/next/babel-preset-env.html.

image


Babel может использоваться для компиляции таких языков, как JavaScript, TypeScript, CoffeeScript, Flow и др. Например, фреймворк React использует синтаксис JSX, который не относится к стандарту JS, и Babel это понимает. В главе 12 мы используем Babel с приложением React.

Когда Babel компилирует TS, он не выполняет проверку типов в отличие от tsc. Создатели Babel не реализовали полноценный компилятор TS. Babel просто считывает TS-код и генерирует соответствующий синтаксис JS.

Должно быть, вы подумали: Я вполне доволен компилятором TS. Зачем вообще в эту книгу о TypeScript включать раздел о компиляторе JS-в-JS? Причина в том, что вы можете подключиться к проекту, где часть модулей написаны в JS, а часть в TS. В таких проектах Babel может уже быть частью потока разработки-развертывания. Например, Babel популярен среди разработчиков, использующих фреймворк React, который лишь недавно начал поддерживать TS.

Подобно любому npm-пакету, вы можете установить Babel локально или глобально (с опцией -g). Локальная установка внутри директории проекта делает этот проект самодостаточным, так как после запуска npm install вы можете использовать Babel, не ожидая, что он установлен где-то в другом месте (кто-нибудь может работать над вашим проектом с другого компьютера).

npm install babel/core babel/cli babel/preset-env

Здесь babel/core является компилятором Babel, babel/cli интерфейсом командной строки, а babel/preset-env это предустановка ENV, которую мы недавно рассматривали.

В реестре npmjs.org пакеты JavaScript могут быть организованы как ветки. Например, babel это ветка для пакетов, относящихся к Babel. angular это ветка для пакетов, принадлежащих фреймворку Angular. @types это место для файлов определений типов TS для различных популярных JS-библиотек.


В последующих разделах мы представим вам три небольших проекта. Первый использует Babel с JS, второй Babel с TS, а третий Babel, TS и Webpack.

Использование Babel с JavaScript

В этом разделе мы рассмотрим простой проект, использующий Babel с JavaScript и расположенный в директории babel-javascript. Мы продолжим работать с трехстрочным скриптом index.js, представленным в листинге 6.7 и использующем JS-библиотеку Chalk. Единственное изменение в следующем листинге заключается в том, что сообщение теперь гласит Compiled with Babel (Скомпилировано с помощью Babel).

Листинг 6.15. index.js: исходный код приложения babel-javascript

const chalk = require('chalk');const message = 'Compiled with Babel';console.log(chalk.black.bgGreenBright(message));


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

image


Babel настраивается в файле .babelrc, и наш файл конфигурации будет очень прост. Нам нужно только использовать preset-env для компиляции.

Листинг 6.17. Файл .babelrc

{    "presets": [       "@babel/preset-env"    ]}


Мы не настраивали здесь никакие конкретные версии браузеров, и без каких бы то ни было опций конфигурации babel/preset-env ведет себя в точности так же, как babel/preset-es2015, babel/preset-es2016 и babel/preset-es2017. Другими словами, все возможности языка, представленные в ECMAScript2015, 2016 и 2017, будут скомпилированы в ES5.

СОВЕТ Мы сконфигурировали Babel в файле .babelrc, который отлично подходит для статических конфигураций вроде нашей. Если ваш проект требует программного создания конфигураций Babel, вам понадобится использовать файл babel.config.js (подробнее в документации Babel здесь: babeljs.io/docs/en/config-files#project- wide-configuration). Если вы хотите увидеть, как Babel компилирует наш файл src/index.js, установите зависимости этого проекта, выполнив npm install, а затем запустите npm-скрипт из package.json: npm run babel.

Следующий листинг показывает скомпилированную версию index.js, созданную в директории dist. Она будет иметь следующее содержимое (сравните с листингом 6.15):

image


Скомпилированный файл по-прежнему вызывает require('chalk'), и эта библиотека расположена в отдельном файле. Помните, что Babel это не бандлер. Мы используем Webpack с Babel в разделе 6.4.3.


Можете запустить скомпилированную версию так:

node dist/index.js

Вывод консоли будет выглядеть схожим с изображенным на рис. 6.13.

Если бы мы захотели, чтобы Babel генерировал код, работающий в конкретных версиях браузеров, потребовалось бы добавить дополнительный файл конфигурации, .browserslistrc. Например, нам нужно, чтобы код работал только в двух последних версиях Chrome и Firefox. Мы можем создать следующий файл в корне проекта:

image


Листинг 6.19. Пример файла .browserslistrc

last 2 chrome versionslast 2 firefox versions


Теперь при запуске Babel не будет преобразовывать const в var, как в листинге 6.18, потому что и Firefox, и Chrome уже поддерживают ключевое слово const. Попробуйте сами, чтобы убедиться.

Использование Babel с TypeScript

В этом разделе мы рассмотрим простой проект, использующий Babel с TypeScript; он размещен в директории babel-typescript. Мы продолжим работать с трехстрочным скриптом, представленным в листинге 6.11 и использующим JS-библиотеку Chalk. Единственное изменение будет в том, что теперь сообщение гласит Compiled with Babel (Скомпилировано с помощью Babel).

Листинг 6.20. index.ts: исходный код приложения babel-typescript

import chalk from 'chalk';const message: string = 'Compiled with Babel';console.log(chalk.black.bgGreenBright(message));


В сравнении с package.json из чистого JS-проекта (см. листинг 6.16) наш TS-проект добавляет dev-зависимость preset-typescript, отделяющую типы TS от кода, чтобы Babel мог воспринимать его как чистый JS. Мы также добавим опцию --extensions '.ts' в npm-скрипт, запускающий Babel, как в листинге 6.21. Теперь Babel будет считывать файлы .ts.

image


Как правило, предустановки включают набор плагинов, но preset-typescript содержит только один, babel/plugin-transform-typescript. Этот плагин внутренне использует babel/plugin-syntax-typescript, чтобы считывать TypeScript, и babel/helper-plugin-utils для основных утилит плагинов.

Несмотря на то что babel/plugin-transform-typescript преобразует TS-код в синтаксис ES.Next, это не компилятор TS. Как бы странно это ни звучало, Babel просто стирает TypeScript. Например, он преобразует const x: number = 0 в const x = 0. babel/plugin-transform-typescript намного быстрее, чем компилятор TS, так как не производит проверку типов для вводных файлов.

babel/plugin-transform-typescript имеет несколько небольших ограничений, перечисленных в документации на babeljs.io/docs/en/babel-plugin-transform-typescript (например, он не поддерживает const enum). Для лучшей поддержки TS рассмотрите использование плагинов babel/plugin-proposal-class-properties и babel/plugin-proposal-object-rest-spread.

Прочитав первые пять глав этой книги, вы наверняка уже начали ценить проверку типов и обнаружение ошибок во время компиляции, осуществляемое реальным компилятором TS. Неужели теперь мы действительно предлагаем вам использовать Babel, чтобы стереть связанный с TS синтаксис? Не совсем так. В процессе разработки вы можете продолжать использовать tsc (с помощью tsconfig.json) и IDE с полной поддержкой TypeScript. Тем не менее на стадии развертывания вы можете все же ввести Babel- и ENV-предустановки. (Скорее всего, вы уже оценили гибкость, предлагаемую ENV-предустановками, при конфигурировании целевых браузеров, не так ли?)

В вашем процессе сборки вы можете даже добавить npm-скрипт (в package.json), запускающий tsc:

check_types: tsc --noEmit src/index.ts

Теперь вы можете последовательно запустить check_types и Babel при наличии локально установленного tsc:

npm run check_types && npm run babel

Опция --noEmit гарантирует, что tsc не сгенерирует никаких файлов (вроде index.js), так как это будет сделано командой babel, выполняемой сразу после check_types. Если в index.js присутствуют ошибки компиляции, процесс сборки провалится и команда babel даже не запустится.

СОВЕТ Если вы используете && (двойной амперсанд) между двумя npm-скриптами, они будут выполняться последовательно. Для параллельного выполнения используйте & (одинарный амперсанд). Подробности вы можете найти во врезке Использование амперсандов в npm-скриптах в Windows в главе 10.

В этом проекте файл конфигурации .babelrc включает babel/preset-typescript.

Листинг 6.22. Файл .babelrc

{"presets": ["@babel/preset-env","@babel/preset-typescript"]}


В сравнении с проектом babel-javascript мы сделали следующие относящиеся к TypeScript изменения:

Добавили опцию --extensions '.ts' в команду, запускающую Babel.
Добавили в package.json связанные с TypeScript dev-зависимости.
Добавили babel/preset-typescript в файл конфигурации .babelrc.

Чтобы скомпилировать наш простой скрипт index.ts, запустите следующий npm-скрипт из package.json:

npm run babel

Вы найдете скомпилированную версию index.js в директории dist. Вы можете запустить скомпилированный код так же, как мы это делали в предыдущем разделе:

node dist/index.js

Теперь давайте добавим в наш рабочий поток Webpack, чтобы связать скрипт index.js и JS библиотеку Chalk.

Использование Babel с TypeScript и Webpack

Babel это компилятор, но не бандлер, который необходим для любого реального приложения. Вы вольны выбирать из ряда доступных бандлеров (вроде Webpack, Rollup и Browserify), но мы будем придерживаться Webpack. В этом разделе мы рассмотрим простой проект, использующий Babel с TypeScript и Webpack. Расположен он в директории webpack-babel-typescript.

В разделе 6.3.2 мы рассмотрели настройку TypeScript-Webpack, и далее мы продолжим использовать наш трехстрочный исходный код из того проекта.

Листинг 6.23. index.ts: исходный код приложения webpack-babel-typescript

import chalk from 'chalk';const message: string = 'Built with Babel bundled with Webpack';console.log(chalk.black.bgGreenBright(message));


В следующем листинге показан раздел devDependency из package.json.

image


Сравните зависимости Babel в листингах 6.24 и 6.21. В листинге 6.24 присутствуют три изменения:

Мы добавили babel-loader, являющийся Webpack-загрузчиком для Babel.
Мы удалили babel-cli, потому что не будем запускать Babel из командной строки.
Вместо babel-cli Webpack будет использовать babel-loader как часть процесса связывания.

Как вы помните из раздела 6.3, Webpack использует файл конфигурации webpack.config.js. Для настройки TS с помощью Webpack мы использовали ts-loader (см. листинг 6.14). В данном же случае мы хотим, чтобы файлы с расширением .ts обрабатывал babel-loader. Следующий листинг показывает раздел Babel из файла webpack.config.js.

image


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

После установки зависимостей командой npm install мы готовы к созданию связки через выполнение команды bundleup из package.json:

npm run bundleup

Эта команда создаст index.bundle.js в директории dist. Этот файл будет содержать скомпилированную (при помощи Babel) версию файла index.js, а также код из JS-библиотеки Chalk. Запустить эту связку вы можете как обычно:

node dist/index.bundle.js

Вывод, показанный на рис. 6.14, будет знакомым.

Для генерации JavaScript не нужно выбирать между Babel и tsc. Они могут успешно сосуществовать в одном проекте.

image


Противники TypeScript зачастую используют такой аргумент: Если я буду писать на чистом JS, мне не потребуется использовать компилятор. Я смогу запустить JS-программу сразу после ее написания. Это абсолютно ошибочно, так как если вы не хотите игнорировать новейший синтаксис JS, представленный, начиная с версии 2015, потребуется процесс, который сможет компилировать код, написанный в современном JS, в код, который смогут понять все браузеры. Скорее всего, вы так или иначе будете использовать в своем проекте компилятор, будь то Babel, TypeScript или какой-либо другой.

ОБ АВТОРАХ

Яков Файн является сооснователем двух IT-компаний: Farata Systems и SuranceBay. Он автор и соавтор таких книг, как Java Programming: 24-Hour Trainer, Angular Development with TypeScript1, Java Programming for Kids и др. Являясь чемпионом Java, провел множество классов и семинаров, посвященных веб- и Java-технологиям. Помимо этого, также был докладчиком на международных конференциях. Файн опубликовал более тысячи статей в своем блоге на yakovfain.com. В твиттере и инстаграме его можно найти по адресу @yfain. Он также публикует видео на YouTube.

Антон Моисеев является ведущим разработчиком в SuranceBay. Провел за разработкой корпоративных приложений более десяти лет, работая с Java и .NET. Имеет обширный опыт и фокусируется на развитии веб-технологий, реализующих лучшие методики слаженной работы фронтенда и бэкенда. Некоторое время проводил обучение по фреймворкам AngularJS и Angular. Периодически Антон делает посты в блоге antonmoissev.com. В твиттере вы можете найти его по адресу @antonmoiseev.

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону TypeScript

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Хороший интерфейс невидимый интерфейс

30.10.2020 14:07:40 | Автор: admin
image Привет, Хаброжители! Сегодня мы решили поделиться бесплатной электронной книгой, где Голден Кришна заставляет нас критически взглянуть на назойливый экранный мир и демонстрирует, как можно создавать продвинутые технологии без цифровых интерфейсов. В своей умной, суровой и зачастую уморительной критической манере Голден подсказывает удивительные идеи, позволяющие выйти из плоскости экрана и при помощи всего трех принципов добиться более плодотворных инноваций. Если вы работаете в инженерной сфере или просто опасаетесь надвигающегося засилья гаджетов, эта книга будет для вас интересной и информативной. Вы сами убедитесь, что обходиться без интерфейсов можно и нужно.

2. Экранно-ориентированное мышление


Давайте напишем приложение!


Когда-то и где-то мы влюбились друг в друга.

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

Может быть, это было в 2009 году, когда со всех сторон раздавались нежные вкрадчивые призывы: Знаете, что самое потрясающее в iPhone? Если вы хотите справиться о состоянии снежного покрова в горах, для этого есть приложение!

Национальная ассоциация предприятий торговли инвентарем для зимних видов спорта утверждает, что лишь 2,6 % американцев отдыхают на горных склонах, причем в среднем всего восемь дней в году, но это неважно. Когда нежный шепоток прозвучал впервые, никто не подумал об этом. Услышав пение сирен, мы забыли обо всем остальном. Любовь и рассудок? Ну нет, это как смешать масло и уксус.

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

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

Для этого есть приложение!

Забудем, что примерно 780 млн людей в мире не имеют возможности пить чистую воду или что в богатой стране США больше полумиллиона8 бездомных. Мы отмахнулись от бытовых социальных проблем и массово двинулись в сторону технологий, где перебои и инновации оказывают значительное влияние на повседневную жизнь. Мы даем миру то, в чем он больше всего нуждается: больше мобильных приложений!

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

Любовь полна терпения и доброты. Любовь можно скачать за 99 центов.

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

Приложение само по себе вовсе не гарантирует, что где-то и для кого-то оно делает что-то полезное, но тсс! мы не должны покушаться на достоинство объекта всеобщей любви. Создание приложения преподносится как благая весть о чудесах и волшебстве: написание кем-то работающего кода, который каким-то образом сумел осветить темный и страшный путь в магазины приложений Apple и Google, преподносится как благословение небес.

New York Times создала рубрику App of the Week (Приложение недели) и завела постоянную колонку App Smart Extra, где встречаются драматические заголовки вроде Метеоприложение, которое работает. Оно работает? Как бы не лопнуть от восторга!

Во время финансового кризиса New York Times назвала Bloomberg приложением недели, потому что оно показывает основные данные фондового рынка. Что? Экстраординарно!

Так и вижу пользователя сайта USA Today, наливающего себе бокал шабли и включающего диск Норы Джонс, чтобы в полной мере насладиться трогательным текстом Пять новых приложений, которые изменят вашу жизнь. Я умиляюсь уже при виде вступления: приложения, приложения,
много приложений вот что на самом деле меняет жизнь!

Или, возможно, вы думаете: Ой, да я просто включу говорящую голову по CNN и забуду про эти смартфонные страсти. Еще раз спасибо, друг мой.
Вот реальные заголовки CNN:
image

image

Словом, что бы с вами ни случилось (кончилась туалетная бумага, вы кого-то выслеживаете или вообще умерли), вы знаете Для этого есть приложение!.

Джастин Бибер. Группа One Direction. Господь Бог. Согласно Google Trends все эти запросы уступают по популярности запросу приложение (app).

image

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

Приложение для дистанционного управления моим BMW разблокирует двери автомобиля, запускает кондиционер и делает многое другое!

Таким образом компании уходят от вопроса, как сделать лучше автомобильный ключ. Большинство приложений, открывающих двери, работают одинаково, поэтому давайте в исследовательских целях проверим, так ли восхитительно работает приложение BMW на iPhone с последней версией мобильной операционной системы Apple. По словам Apple, это самая продвинутая в мире мобильная ОС. В ее самой лучшей форме.
image

image

image

image

image

image

image

image

image

image

Погодите 13 шагов? Что вообще происходит? Все начиналось с того, что я шел к своей машине. Я просто хотел открыть дверь. Это, кажется, не сложно.

image

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

Это еще страсть или уже безумие? Это и в самом деле новая веха в развитии автомобильного ключа? Подумайте и честно признайтесь: ответ нет.

Я понимаю, отказаться от своего наркотика нелегко.

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

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

1. Подойти к машине.
2. Открыть дверь.


Все промежуточное можно смело отбросить.

Звучит невероятно? Между тем за целых 10 лет до выпуска этого 13-шагового приложения, до наступления эры экранно-ориентированного мышления, такая задача была успешно решена компанией Siemens и реализована Mersedes-Benz.

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

Улучшение автомобильного ключа? Безусловно.

На это некоторые возражали мне: Ну нет, без приложения не обойтись.

А что, если я запер ключи в машине? Вот тут-то и пригодится приложение!.

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

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

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

Этой мысли и посвящена книга:

Лучший интерфейс невидимый интерфейс.

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

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

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

Напрягите булочки.

Скачать
Подробнее..

Книга Гарвардский Некромант

17.11.2020 16:15:10 | Автор: admin
image Привет, Хаброжители! Гарвардский некромант рассказывает о том, как вели бы себя ученые, если бы магия реально существовала.
Это научная фантастика с акцентом на первом слове. Автор пишет как о реальных, так и о вымышленных научных исследованиях, но вымышленные описывает так, чтобы они удовлетворяли всем критериям настоящих научных работ. Этим книга немного напоминает таинственный Манускрипт Войнича кодекс, написанный на неизвестном, скорее всего несуществующем, языке с использованием неизвестного алфавита, но трудно отличимый от аутентичной древней рукописи. Научные чудеса проявляются не в виде горящих кустов и голосов в голове, а в виде неожиданных показаний приборов, статистических отклонений в продолжительности жизни подопытных червей и мышей, а также других, поддающихся объективному анализу, результатов опытов и наблюдений.


Жанр не хочется писать вымирающий, но очень редкий: интеллектуальная фантастика. Книга, целиком состоящая из единственного диалога, обманчиво похожа на обыкновенное интервью с ученым (и показывает мир науки точнее, чем многие невыдуманные интервью). Автор, широко известный своей борьбой со лженаукой и плохой наукой, рассказывает историю о реально существующей магии. Совместимы ли в одном мире магия, то есть, по определению, нарушение законов природы, и научный метод? Да при одном условии.

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

И ЖИВОТНОВОДСТВО!

Представляю, в какую ярость пришла общественность, услышав про принесение в жертву эмбрионов!

Забавно, но да.

И чего же тут забавного?

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

Пожалуйста, скажите мне, что вы придумали этический способ получения человеческих
эмбрионов.

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

И это сработало?

К сожалению, нет. Похоже, Ви Джас выступала за выбор и не считала, что эмбрион мыши

это мышь.

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

О да. Хотя им стоило радоваться. Ведь если бы наши опыты сработали, мы бы рассмотрели возможность жертвоприношения человеческих эмбрионов. Пришлось бы только узнать, можно ли их как-то гуманизировать. Учитывая, что они и так гуманизированы на все 100 % генома. Но вы ничего не спросили о контрольных группах, которые мы использовали.

А что там с контрольными группами?

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

Досадно.

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

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

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

image


image


Но кто-то все-таки пытался проверить эффект от жертвоприношений человеческих эмбрионов? Может быть, аборты как-то влияют на женщин?

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

ОБ АВТОРЕ

Александр Панчин окончил факультет биоинженерии и биоинформатики МГУ им. М. В. Ломоносова. В 2011 году защитил кандидатскую диссертацию в области математической биологии по теме Исследование общих закономерностей эволюции генома человека при дупликации генов и точечном мутагенезе. Работает старшим научным сотрудником в секторе молекулярной эволюции ИППИ РАН. Александр пишет научно-популярные тексты с 2008 года. Лауреат премии Просветитель за книгу Сумма биотехнологии, а также литературной премии имени Александра Беляева за антиутопию Апофения. Финалист премии За верность науке 2017. Автор книги Защита от темных искусств. Член Комиссии РАН по борьбе с лженаукой, совета просветительского фонда Эволюция и экспертного совета Премии имени Гарри Гудини.

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Панчин

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Перевод Интервью авторов Искусства схемотехники сообществу element14 (05.06.2015)

07.05.2021 02:13:27 | Автор: admin

После своей первоначальной публикации в 1980 году, книга "Искусство схемотехники" считается "Библией электронной техники". Инженеры отзываются о ней как о важной, основополагающей книге, которая оставила глубокий след и привила любовь к схемотехнике. Весьма ожидаемое третье издание книги было опубликовано ранее в этом году и уже получило восхищенные отзывы.

Сагар Джетани (Sagar Jethani) беседует от имени сообщества "element14" с соавторами книги, Полом Хоровицем (Paul Horowitz) и Уинфилдом Хиллом (Winfield Hill), о новом третьем издании.

Соавторы "Искусства схемотехники": Пол Хоровиц (слева) и Уинфилд Хилл (справа)Соавторы "Искусства схемотехники": Пол Хоровиц (слева) и Уинфилд Хилл (справа)

Сагар Джетани

Вопрос от одного из членов нашего сообщества, Дона Берки (Don Bertke).

Почему книга названа "Искусство схемотехники"? Разве схемотехника не строгий предмет? Ведь искусство подразумевает сочетание свободы и индивидуальности!

Пол Хоровиц

Это было идеей Уина, назвать книгу "Искусство схемотехники".

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

По нашему мнению, правильно спроектированная схема изящна.

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

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

Уинфилд Хилл

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

Пол Хоровиц

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

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

Из этих соображений мы и определили название книги.

Сагар Джетани

В чем особенности третьего издания книги? Книга полностью переписана или частично дополнена?

Уинфилд Хилл

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

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

Пол Хоровиц

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

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

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

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

Эти четыре главы, это действительно нечто!

Каждую из них можно рассматривать как небольшие, отдельные книги.

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

Уинфилд Хилл

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

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

Сагар Джетани

Один из членов нашего сообщества, Эрик Рэтклифф (Erik Ratcliff), интересуется, с какого издания ему начать изучение. До настоящего момента у него не было ни одного из изданий. Можете ли вы поподробнее рассказать о содержимом третьего издания, которого не найти во втором издании?

Уинфилд Хилл

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

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

Пол Хоровиц

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

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

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

Мы добавили в третье издание 90 осциллограмм, показывающих необычное поведение схем. Если сравнивать, то во втором издании их примерно пять.

Уинфилд Хилл

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

Пол Хоровиц

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

Сагар Джетани

Уин, вы упомянули, что некоторые темы второго издания исключили в третьем издании. Можете привести примеры?

Уинфилд Хилл

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

Те, кому интересны эти темы, всегда могут их найти во втором издании.

Пол Хоровиц

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

Сагар Джетани

В тексте книги часто встречаются ссылки на главы, помеченные "иксом". Члену нашего сообщества, Шабазу Юсуфу (Shabaz Yousaf), интересно, можете ли вы объяснить, что это за главы.

Пол Хоровиц

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

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

Всего мы выделили пять "икс"-глав.

Глава 1x, которая охватывает пассивные компоненты, такие как катушки индуктивности, конденсаторы и резисторы.

Глава 2x, которая охватывает биполярные транзисторы.

Глава 3x, которая охватывает полевые транзисторы.

Глава 4x, которая охватывает операционные усилители.

Глава 9x, которая охватывает источники питания и их применение.

Первоначально, мы хотели разместить эти главы следом за главами, из которых на них идут ссылки. Так получилось, что третье издание книги занимает свыше 1200 страниц даже без вкрапления "икс"-глав. Даже с учетом крупного формата страниц и до некоторой степени мелким шрифтом. Около года назад, нами было принято решение напечатать "икс"-главы отдельным изданием. Часть материала, который мы намеревались включить в "икс"-главы и который мы сочли очень важным, мывернули обратно в текст книги. Таким образом, некоторые главы в книге получились теперь более сложными.

Сагар Джетани

Когда Вы намереваетесь издать сборник "икс"-глав?

Пол Хоровиц

Сборник "икс"-глав планируется к изданию не ранее чем через два года. Конечно, я надеюсь, что это произойдет раньше. Сборник уже набран примерно на 50% с иллюстрациями и прочим материалом.

Сагар Джетани

Следующий вопрос поступил от члена нашего сообщества, Джона Вилтраута (John Wiltrout).

У второго издания есть известное приложение в виде "Студенческого руководства". Планируете ли Вы выпустить что-либо подобное для третьего издания?

Пол Хоровиц

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

Теперь, у этой книги новое название, "Постижение искусства схемотехники: вспомогательный лабораторный курс".

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

Книга включает лабораторные и классные занятия, а также весь материал, содержащийся в применяемых ныне руководствах для студентов. Вдобавок, в книге содержится еще кое-какой дополнительный материал. Данная книга снимает некоторую нагрузку с основной книги. Ее автором является Том Хейс (Tom Hayes), который был в свое время автором "Студенческого руководства" ко второму изданию.

Сагар Джетани

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

Пол Хоровиц

Да, я так считаю.

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

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

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

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

"Студенческое руководство" лишь призвано помочь начать практическую деятельность.

Уинфилд Хилл

Да, весь материал этой книги затрагивает связь теории и практики. Это присовокупляет практическую сторону к книге "Искусство схемотехники".

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

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

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

Сагар Джетани

Один из авторов статей в нашем сообществе, Элиша Вайт (Elecia White), интересуется:

"При характерной внушительности вашей книги (90 осциллограмм, 80 таблиц, свыше 1600 дискретных компонентов), имеются ли у Вас любимые схемы? Какие из них Вы постоянно приводите в качестве примеров?"

Пол Хоровиц

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

Это такая потрясающая картинка!

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

У меня было много "головной боли" при создании рисунка 8.58 в программе Adobe Illustrator. Он озаглавлен "Действующее значение плотности входного шума". И чтобы быть созданным, он потребовал от меня всех моих знаний о программе Adobe Illustrator.

Это наш любимый график.

Сагар Джетани

Есть ли у Вас любимые таблицы?

Пол Хоровиц (улыбаясь)

Нашей любимой является таблица 5.5, которая включает "великолепную семерку" высокоточных операционных усилителей.

На самом деле их там значительно больше!

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

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

По этому поводу у нас была интересная переписка с Джимом Уильямсом (Jim Williams). Мы обратили внимание на то, что спецификация полностью фиктивна. После этого с егостороны была длинная пауза, затем, понизив голос, он сообщил: "Вами раскрыт один из самых темных секретов Кремниевой долины."

Сагар Джетани

Вы предоставили любимый график и любимую таблицу. Есть ли у Вас любимая схема?

Уинфилд Хилл

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

Пол Хоровиц

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

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

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

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

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

Мы отталкивались от дискретной цифровой логики в направлении FPGA, CPLD и в итоге перешли к микроконтроллерам.

Мы истратили 12 страниц на то, чтобы показать вам полдюжины различных способов получения псевдослучайной последовательности. Отличным примером является рисунок 8.93 на странице 559, на котором показано, как использовать генератор шума с псевдослучайной битовой последовательностью и аналоговую фильтрацию, чтобы получать различные цвета шума: "белый", "розовый", "красный". Сюда еще стоит отнести графики, качественно характеризующие данную схему.

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

Уинфилд Хилл

К моим любимым относится схема на рисунке 9.13, со страницы 606.

Там показана схема внутреннего устройства линейного стабилизатора напряжения 317-й серии. Я всегда считал ее особенно элегантной и милой.

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

Не меньше, я люблю схемы функциональных блоков цифровых мультиметров под торговыми марками "HP", "Agilent" и "Keysight", которые мы разместили во многих частях книги. Например, рисунок 8.49 со страницы 513, рисунок 13.15 со страницы 896, рисунок 13.47 со страницы 919.

Сагар Джетани

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

Пол Хоровиц

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

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

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

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

Сейчас это направление бурно развивается.

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

По поводу будущего, я бы хотел привести цитату Нильса Бора:

"Предсказать что-либо очень сложно, особенно если это касается будущего."

Уинфилд Хилл

Предыдущее издание книги было опубликовано в 1989 году.

Это намек специально для тех, кто хочет знать, как что-либо меняется за 25 лет.

Пол Хоровиц

Я не думаю, что мы в свое время предвидели появление платформы "Arduino", сети Internet, журнала "Make" и многого другого.

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

Где теперь туннельные диоды? Они исчезли!

По-моему, те, кто берется за предсказание глупцы!

Уинфилд Хилл

Мы затрудняемся ответить на этот вопрос!

Сагар Джетани

Вы неоднократно упоминали огромное значение микроконтроллеров.

Сообщество "element14" популяризует широкое разнообразие микроконтроллеров. Шабаз и я недавно обсуждали, повлияло ли на процесс проектирования появление дешевых, полностью фунциональных плат на их основе.

Есть ли здесь подводные камни?

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

Возможно это немного чересчур, но приемлемо.

Пол Хоровиц

Хотелось бы предостеречь!

Вы конечно можете собрать схему из готовых блоков на микроконтроллерах, как конструктор "LEGO".

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

Позвольте в качестве примера привести ситуацию, сложившуюся у нас в Гарвардском университете.

У нас имеются студенты, с конструкторскими заданиями построить то-то и то-то.

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

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

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

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

С другой стороны, если это позволяет выполнить работу, то кто пожалуется, коли это предназначено исключительно для вас?

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

Уинфилд Хилл

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

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

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

Так каким же образом вы собираетесь впоследствии подключить их к выводам процессора?

Именно об этом мы подробно рассказываем в двенадцатой главе. А уже в тринадцатой главе мы обсуждаем подключения процессоров к аналоговым устройствам.

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

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

Вот этому мы и пытаемся научить.

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

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

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

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

Не малая часть повествования посвящена обучению читателей применять это многообразие устройств в своих проектах.

Сагар Джетани

Что делать инженерам, если они хотят держать свои навыки в тонусе?

Уинфилд Хилл

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

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

Пол Хоровиц

По этому поводу я общался с опытным схемотехником, Джимом Макартуром (Jim McArthur). Иногда в нашей книге мы приводим его цитаты.

И вот одна из них:

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

Вы всегда будете в курсе дела, если у вас имеется такое окружение.

Сагар Джетани

Я заметил, что Вы упоминаете в приложениях к третьему изданию книги наш магазин, "Newark Electronics".

Уинфилд Хилл

Я постоянный покупатель "Newark Electronics".

Пол Хоровиц

В приложении K, озаглавленном "Где мне купить электронные "вкусняшки"?", мы отдельно упомянули "Newark Electronics" за хороший ассортимент. Еще отмечу, что в "Newark Electronics" до сих пор есть печатный каталог!

К сожалению, в "Digi-Key" отказались от его выпуска пару лет назад.

Сагар Джетани

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

Пол Хоровиц

Конечно, я уже не верю в мемристоры.

Хотелось бы увидеть действительно энергонезависимую технологию памяти.

Я не думаю, что это будет флэш-память с плавающим затвором. Я считаю, что это будет кое-что гораздо лучше. Но я не уверен, что это будет одна из тех четырех технологий, которые претендуют на это сейчас. Возможно, это будет нечто совершенно иное. В нашей книге мы перечислили плюсы и минусы технологий магнитной памяти (MRAM), сегнетоэлектрической памяти (FeRAM), памяти на основе фазового перехода (PRAM) и ряда других.

Давайте через тридцать лет посмотрим, что из этого выйдет!

Сагар Джетани

Пол, Вы один из основателей программы по поиску внеземных цивилизации (SETI). Вы работали с ныне покойным Карлом Саганом (Carl Sagan). Расскажите о Вашей работе по данному направлению. Каковы задачи программы поиска внеземных цивилизаций сейчас?

Пол Хоровиц

Наша программа по поиску внеземных цивилизаций жива и здорова.

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

Мы не знаем, что посылают внеземные цивилизации, однако мы уверены, что они существуют.

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

Конечно, в Галактике Млечного Пути планет больше, чем звезд. А обитаемых планет примерно столько же, сколько и звезд. Скажем, примерно 100 миллиардов.

Все отлично складывается для возможности существования жизни в других местах.На самом деле все неплохо складывается даже для возможности существования примитивной жизни в других уголках нашей Солнечной системы.

Сагар Джетани

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

Пол Хоровиц

Самой передовой идеей является наблюдение оптических импульсов. Это основа наших исследований последних десяти лет.

Хотя радиоастрономия не потеряла своей актуальности. В настоящее время в радиоастрономии мало что происходит.

Проект радиотелескопа Аллена (Allen telescope array), на который возлагались большие надежды, был закрыт. У радиотелескопа в Аресибо (штаб-квартира программы SETI) слишком узкий луч для наблюдения за небом и ограниченный диапазон частот.

Контакт может произойти в любой момент.

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

Уинфилд Хилл (шутит улыбаясь)

Пол и его студенты спроектировали телескоп в Гарвардском университете, в штате Массачусетс. Он автоматически запускается в ясные ночи и сканирует небо в поисках сигналов от внеземной жизни. Пол не успел указать этого на своей страничке в сети, поскольку был сильно занят написанием третьего издания книги "Искусство схемотехники". Телескоп как раз заработает этой ночью. Не правда ли?

Пол Хоровиц (улыбается)

Я не против, но только сегодня немного облачно. Вот если бы погода была такой, как у Вас в Калифорнии, Сагар!

Позвольте мне закрыть эту тему маленькой цитатой! Она родилась во время экспериментов с радиосистемой и работ по модернизации телескопа, о котором только что упомянул Уин. Я тогда показал схему модернизации одному своему коллеге, Биллу Прессу (Bill Press), автору книги "Вычислительные рецепты" ("Numerical Recipes").

Билл посмотрел на проект, и сказал:

"Хоровиц, ты знаешь, что шанс прославиться у тебя один на миллион?".

Так и здесь.

Это было бы великим открытием! Это бы покончило с культурной изоляцией планеты Земля! Это был бы мост между формами разумной жизни, независимо друг от друга зародившимися на протяжении четырех миллиардов лет! Это было бы величайшее открытие в истории человечества!

Надежда вечный спутник искателя разумной жизни во Вселенной.

Уинфилд Хилл

Варианта всего два: либо это будет величайшее открытие в истории человечества, либо не будет ничего.

Пол Хоровиц (улыбается)

Да, либо не будет ничего.

Сагар Джетани

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

Уинфилд Хилл

Большое спасибо! Нам понравилось беседовать с Вами!

Пол Хоровиц

Если этот ваш член сообщества прав, то делает ли это нас святыми или кем-то наподобие?

Сагар Джетани (улыбаясь)

Она не уточнила!

Заключительная ремарка переводчика

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

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

У каждого автора имеется свой почерк. Поэтому я решил внести в свои публикации маленькую невинную традицию. Уж не обессудьте!

В конце каждой публикации будет объявляться муза.

Таким образом, музой этой публикации объявляется Наташа Васичева, за интересные методы "беспалевной" видеосъемки на смартфон. Как бы странно это не звучало для непосвященных и что бы ни значило.

Надеюсь статья Вам показалась интересной.

До новых встреч!

Подробнее..

Книга PowerShell для сисадминов

27.05.2021 16:21:56 | Автор: admin
image Привет, Хаброжители! PowerShell это одновременно язык сценариев и командная оболочка, которая позволяет управлять системой и автоматизировать практически любую задачу. В книге PowerShell для сисадминов обладатель Microsoft MVP Адам Бертрам aka the Automator покажет, как использовать PowerShell так, чтобы у читателя наконец-то появилось время на игрушки, йогу и котиков. Вы научитесь: -Комбинировать команды, управлять потоком выполнения, обрабатывать ошибки, писать сценарии, запускать их удаленно и тестировать их с помощью фреймворка тестирования Pester. -Анализировать структурированные данные, такие как XML и JSON, работать с популярными сервисами (например Active Directory, Azure и Amazon Web Services), создавать системы мониторинга серверов. -Создавать и проектировать модули PowerShell. -Использовать PowerShell для удобной, полностью автоматизированной установки Windows. -Создавать лес Active Directory, имея лишь узел Hyper-V и несколько ISO-файлов. -Создавать бесчисленные веб- и SQL-серверы с помощью всего нескольких строк кода! Реальные примеры помогают преодолеть разрыв между теорией и работой в настоящей системе, а легкий авторский юмор упрощает чтение. Перестаньте полагаться на дорогое ПО и невнятные советы из сети!

Для кого эта книга
Эта книга предназначена для ИТ-специалистов и системных администраторов, которым надоело постоянно использовать один и тот же интерфейс и выполнять одну и ту же задачу в пятисотый раз за этот год. Также она будет полезна для инженеров DevOps, которые испытывают затруднения с автоматизацией новых серверных сред, выполнением автоматических тестов или автоматизацией конвейера непрерывной интеграции / непрерывной доставки (CI/CD).

Не получится назвать отрасль, для которой PowerShell был бы полезен больше всего. Традиционная должность пользователя PowerShell в магазине Windows системный администратор Microsoft, однако PowerShell хорошо вписывается в набор инструментов любого сотрудника в сфере ИТ. Если вы работаете в ИТ, но не считаете себя разработчиком, эта книга для вас.

Поток управления


Немного повторим. В главе 3 мы узнали, как можно комбинировать команды с помощью конвейера и внешних сценариев. В главе 2 рассмотрели переменные и как их использовать для хранения значений. Одним из основных преимуществ работы с переменными является возможность писать с их помощью код, который работает не со значением, а со смыслом. Вместо того чтобы работать, например, с числом 3, вы будете работать с общим понятием $serverCount. За счет этого вы можете писать код, который работает одинаково, будь у вас один, два или тысяча серверов. Совместите эту способность с возможностью сохранять код в сценариях, которые можно запускать на разных компьютерах, и вы сможете начать решать задачи гораздо большего масштаба.

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

Немного о потоке управления

Мы напишем сценарий, который считывает содержимое файла, хранящегося на нескольких удаленных компьютерах. Чтобы продолжить работу, загрузите файл под названием App_configuration.txt из прилагаемых к книге материалов по ссылке github.com/adbertram/PowerShellForSysadmins/ и поместите его в корень диска C:\ на нескольких удаленных компьютерах. Если у вас нет удаленных компьютеров, пока просто продолжайте читать. В этом примере я буду использовать серверы с именами SRV1, SRV2, SRV3, SRV4 и SRV5.

Чтобы получить доступ к содержимому файла, воспользуемся командой Get-Content и укажем путь к файлу в значении аргумента параметра Path, как показано ниже:

Get-Content -Path "\\servername\c$\App_configuration.txt"

Для начала сохраним все имена наших серверов в массиве и запустим эту команду для каждого сервера. Откройте новый файл .ps1 и введите в него код из листинга 4.1.

Листинг 4.1. Извлечение содержимого файла с нескольких серверов

$servers = @('SRV1','SRV2','SRV3','SRV4','SRV5')Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"Get-Content -Path "\\$($servers[1])\c$\App_configuration.txt"Get-Content -Path "\\$($servers[2])\c$\App_configuration.txt"Get-Content -Path "\\$($servers[3])\c$\App_configuration.txt"Get-Content -Path "\\$($servers[4])\c$\App_configuration.txt"


Теоретически, этот код должен работать без проблем. Но в этом примере предполагается, что у вас что-то идет не так. Что делать, если сервер SRV2 не работает? А если кто-то забыл положить App_configuration.txt на SRV4? А может, кто-то изменил путь к файлу? Вы можете написать отдельный сценарий для каждого сервера, но это решение не будет масштабироваться, особенно когда вы начнете добавлять все больше и больше серверов. Вам нужен код, который будет работать в зависимости от ситуации.

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

Мы начнем с рассмотрения самого простого типа потока управления условного оператора.

Использование условных операторов

В главе 2 мы узнали, что существуют логические значения: истина и ложь. Логические значения позволяют создавать условные операторы, которые ставят задачу PowerShell выполнить определенный блок кода в зависимости от того, имеет ли выражение (называемое условием) значение True или False. Условие это вопрос с вариантами ответов да/нет. У вас больше пяти серверов? Работает ли сервер 3? Существует ли путь к файлу? Чтобы начать использовать условные операторы, давайте посмотрим, как преобразовать такие вопросы в выражения.

Построение выражений с помощью операторов

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

PS> 1 eq 1
True

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

-eq сравнивает два значения и возвращает True, если они равны.

-ne сравнивает два значения и возвращает True, если они не равны.

-gt сравнивает два значения и возвращает True, если первое больше второго.

-ge сравнивает два значения и возвращает True, если первое больше или равно второму.

-lt сравнивает два значения и возвращает True, если первое меньше второго.

-le сравнивает два значения и возвращает True, если первое меньше или равно второму.

-contains возвращает True, если второе значение является частью первого. Например, этот оператор позволяет определить, находится ли значение внутри массива.

В PowerShell есть и более продвинутые операторы сравнения. Здесь мы не будем на них останавливаться, но я рекомендую вам почитать о них в документации Microsoft по ссылке docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators или в разделе справки PowerShell (см. главу 1).

Вы можете использовать приведенные выше операторы для сравнения переменных и значений. Но выражение не обязательно должно быть сравнением. Иногда команды PowerShell можно использовать как условия. В предыдущем примере мы хотели узнать доступность сервера. С помощью командлета Test-Connection можно проверить наличие связи с сервером. Обычно в выходных данных командлета Test-Connection содержится много разной информации, но с помощью параметра Quiet вы можете заставить команду вернуть True или False, а с помощью параметра Count можно ограничить тест одной попыткой.

PS> Test-Connection -ComputerName offlineserver -Quiet -Count 1
False

PS> Test-Connection -ComputerName onlineserver -Quiet -Count 1
True

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

PS> -not (Test-Connection -ComputerName offlineserver -Quiet -Count 1)
True

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

Оператор if

Оператор if работает просто: если выражение X истинно, то сделайте Y. Вот и все!

Чтобы использовать оператор в выражении, пишется ключевое слово if, за которым следуют круглые скобки, содержащие условие. После выражения следует блок кода, выделенный фигурными скобками. PowerShell выполнит этот блок кода только в том случае, если это выражение будет иметь значение True. Если выражение if имеет значение False либо вообще ничего не возвращает, блок кода не будет выполнен. Синтаксис оператора if/then показан в листинге 4.2.

Листинг 4.2. Синтаксис оператора if

if (условие) {   # выполняемый код, если условие истинно}


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

Теперь давайте еще раз посмотрим на код, показанный в листинге 4.1. Я расскажу вам о том, как использовать оператор if, чтобы не пытаться достучаться до неработающего сервера. В предыдущем разделе мы уже видели, что команду Test-Connection можно использовать в качестве выражения, которое возвращает True или False, поэтому сейчас давайте упакуем Test-Connection в оператор if, а затем воспользуемся командой Get-Content, чтобы не пытаться обращаться к неработающему серверу. Сейчас мы поменяем код только для первого сервера, как показано в листинге 4.3.

Листинг 4.3. Использование оператора if для выборочного обращения

$servers = @('SRV1','SRV2','SRV3','SRV4','SRV5')if (Test-Connection -ComputerName $servers[0] -Quiet -Count 1) {   Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"}Get-Content -Path "\\$($servers[1])\c$\App_configuration.txt"--пропуск--


Поскольку у вас есть Get-Content в операторе if, вы не столкнетесь с какими-либо ошибками, если попытаетесь получить доступ к неработающему серверу; если тест завершится неудачно, ваш сценарий будет знать, что не следует пытаться считать файл. Код попытается получить доступ к серверу, только если он уже знает, что тот включен. Но обратите внимание, что этот код срабатывает только в том случае, если условие истинно. Достаточно часто вам нужно будет задать одно поведение сценария для истинного условия и другое для ложного. В следующем разделе вы увидите, как определить поведение для ложного условия с помощью оператора else.

Оператор else

Чтобы предоставить вашему оператору if альтернативу, можно использовать ключевое слово else после закрывающей скобки блока if, за которым будет следовать еще одна пара фигурных скобок, содержащая блок кода. Как показано в листинге 4.4, мы будем использовать оператор else, чтобы вернуть в консоль ошибку, если первый сервер не отвечает.

Листинг 4.4. Использование оператора else для запуска кода, если условие
не истинно

if (Test-Connection -ComputerName $servers[0] -Quiet -Count 1) {   Get-Content -Path "\\$($servers[0])\c$\App_configuration.txt"} else {   Write-Error -Message "The server $($servers[0]) is not responding!"}


Оператор if/else отлично работает, когда у вас есть две взаимоисключающие ситуации. В данном случае сервер либо подключен, либо нет, то есть нам нужно всего две ветви кода. Давайте посмотрим, как работать с более сложными ситуациями.

Оператор elseif

Оператор else охватывает противоположную ситуацию: если if не срабатывает, значит, выполните это в любом случае. Такой подход работает для двоичных условий, то есть когда сервер либо работает, либо нет. Но иногда приходится иметь дело с большим числом вариантов. Например, предположим, что у вас есть сервер, на котором нет нужного вам файла, и вы сохранили имя этого сервера в переменной $problemServer (добавьте в свой сценарий эту строку кода!). Это означает, что вам нужна дополнительная проверка, позволяющая узнать, является ли сервер, который вы опрашиваете в данный момент, проблемным. Это можно реализовать с помощью вложенных операторов if, как показано в коде ниже:

if (Test-Connection -ComputerName $servers[0] -Quiet -Count 1) {   if ($servers[0] eq $problemServer) {      Write-Error -Message "The server $servers[0] does not have the right         file!"   } else {      Get-Content -Path "\\$servers[0]\c$\App_configuration.txt"   }} else {   Write-Error -Message "The server $servers[0] is not responding!"}--пропуск--


Но есть и более аккуратный способ реализовать ту же логику с помощью оператора elseif, который позволяет вам проверить дополнительное условие, перед тем как вернуться к коду в блоке else. Синтаксис блока elseif идентичен синтаксису блока if. Итак, чтобы проверить проблемный сервер с помощью оператора elseif, запустите код из листинга 4.5.

Листинг 4.5. Использование блока elseif

if (-not (Test-Connection -ComputerName $servers[0] -Quiet -Count 1)) {    Write-Error -Message "The server $servers[0] is not responding!"} elseif ($servers[0] eq $problemServer)    Write-Error -Message "The server $servers[0] does not have the right file!"} else {   Get-Content -Path "\\$servers[0]\c$\App_configuration.txt" }--пропуск--


Обратите внимание, что мы не просто добавили оператор elseif, а заодно изменили логику кода. Теперь мы можем проверить, не находится ли сервер в автономном режиме, с помощью оператора not. Затем, как только мы определили сетевой статус сервера, мы проверяем, является ли он проблемным. Если это не так, мы используем оператор else для запуска поведения по умолчанию извлечения файла. Как видите, существует несколько способов структурировать код описанным образом. Важно то, что код работает и что он читабелен для человека со стороны, будь то ваш коллега, видящий его впервые, или вы сами спустя некоторое время после написания.

Вы можете объединить в цепочку сколько угодно операторов elseif, что позволяет учитывать самые разные сочетания обстоятельств. Однако операторы elseif являются взаимоисключающими: когда один из elseif принимает значение True, PowerShell запускает только его код и не проверяет остальные случаи. В листинге 4.5 это не вызвало никаких проблем, так как вам нужно было проверить сервер на предмет проблемности только после проверки работоспособности, но в дальнейшем я советую вам держать в уме эту особенность.

Операторы if, else и elseif отлично подходят для реализации ответа кода на простые вопросы типа да/нет. В следующем разделе вы узнаете, как работать с более сложной логикой.

Оператор switch

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

Обратите внимание, что теперь мы будем работать с другим типом условия. Если раньше нам нужны были ответы на вопросы типа да/нет, то теперь мы хотим получить конкретное значение одной вещи. Это сервер SRV1? SRV2? И так далее. Если бы вы работали только с одним или двумя конкретными значениями, оператор if подошел бы, но в данном случае оператор switch сработает гораздо лучше.

Оператор switch позволяет выполнять различные фрагменты кода в зависимости от некоторого значения. Он состоит из ключевого слова switch, за которым следует выражение в скобках. Внутри блока switch находится серия операторов, построенных по следующему принципу: сначала указывается значение, за ним следует набор фигурных скобок, содержащих блок кода, и наконец ставится блок default, как указано в листинге 4.6.

Листинг 4.6. Шаблон для оператора switch

switch (выражение) {   значениевыражения {      # Код   }   значениевыражения {   }   default {     # Код, который выполняется при отсутствии совпадений   }}


Оператор switch может содержать практически неограниченное количество значений. Если выражение оценивается как значение, выполняется соответствующий код внутри блока. Важно то, что, в отличие от elseif, после выполнения одного блока кода PowerShell продолжит проверять и остальные условия, если не указано иное. Если ни одно из значений не подойдет, PowerShell выполнит код, указанный в блоке default. Чтобы прекратить перебор условий в операторе switch, используйте ключевое слово break в конце блока кода, как показано в листинге 4.7.

Листинг 4.7. Использование ключевого слова break в операторе switch

switch (выражение) {   значениевыражения {      # Код      break   }--пропуск--


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

Листинг 4.8. Проверка различных серверов с помощью оператора switch

$currentServer = $servers[0]switch ($currentServer) {   $servers[0] {      # Check if server is online and get content at SRV1 path.      break   }   $servers[1] {      ## Check if server is online and get content at SRV2 path.      break   }   $servers[2] {      ## Check if server is online and get content at SRV3 path.      break   }--пропуск--


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

Использование циклов

Существует хорошее практическое правило для работы за компьютером: не повторяйся (dont repeat yourself, DRY). Если вы обнаружите, что выполняете одну и ту же работу, то, скорее всего, существует способ ее автоматизировать. То же самое и с написанием кода: если вы используете одни и те же строки снова и снова, вероятно, существует решение получше.

Один из способов избежать повторов использовать циклы. Цикл позволяет многократно выполнять код, до тех пор пока не изменится некоторое заданное условие. Условие остановки может запускать цикл заданное количество раз, либо до тех пор, пока не изменится некоторое логическое значение, либо определить бесконечное выполнение цикла. Каждый проход цикла мы будем называть итерацией.

PowerShell предлагает пять типов циклов: foreach, for, do/while, do/until и while. В этом разделе мы обсудим каждый тип цикла, отметим их уникальные черты и выделим лучшие ситуации для их использования.

Об авторе

Адам Бертрам (Adam Bertram) опытный ИТ-специалист и эксперт в области интернет-бизнеса с 20-летним стажем. Предприниматель, ИТ-инфлюенсер, специалист Microsoft MVP, блогер, тренинг-менеджер и автор материалов по контент-маркетингу, сотрудничающий со многими ИТ-компаниями. Также Адам основал популярную платформу TechSnips для развития навыков ИТ-специалистов (techsnips.io).

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону PowerShell

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Современный скрапинг веб-сайтов с помощью Python. 2-е межд. издание

12.04.2021 16:18:43 | Автор: admin
image Привет, Хаброжители! Если программирование напоминает волшебство, то веб-скрапинг это очень сильное колдунство. Написав простую автоматизированную программу, можно отправлять запросы на веб-серверы, запрашивать с них данные, а затем анализировать их и извлекать необходимую информацию. Новое расширенное издание книги знакомит не только с веб-скрапингом, но и поможет собрать любого вида данные в современном Интернете. В части I основное внимание уделено механике веб-скрапинга: как с помощью Python запрашивать информацию с веб-сервера, производить базовую обработку серверного отклика и организовать автоматизированное взаимодействие с сайтами. В части II исследованы более специфичные инструменты и приложения, которые пригодятся при любом сценарии веб-скрапинга. Разбирайте сложные HTML-страницы. Разрабатывайте поисковые роботы с помощью фреймворка Scrapy. Изучайте методы хранения данных, полученных с помощью скрапинга. Считывайте и извлекайте данные из документов. Очищайте и нормализуйте плохо отформатированные данные. Читайте и пишите информацию на естественных языках. Освойте поиск по формам и логинам. Изучите скрапинг JavaScript и работу с API. Используйте и пишите программы для преобразования изображений в текст. Учитесь обходить скрапинговые ловушки и блокаторы ботов. Протестируйте собственный сайт с помощью скрапинга.

Веб-краулинг с помощью API


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

По мере распространения методов генерации и загрузки контента с помощью JavaScript и Ajax описанная выше ситуация становится все менее привычной. В главе 11 мы рассмотрели один из способов решения указанной проблемы: использование Selenium для автоматизации браузера и извлечения данных. Это легко сделать. Это работает почти всегда.

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

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

Краткое введение в API

Существует бесчисленное количество книг, докладов и руководств о нюансах API REST, GraphQL21, JSON и XML, однако все они основаны на одной простой концепции. API определяет стандартизованный синтаксис, который позволяет одной программе взаимодействовать с другой, даже если они написаны на разных языках или имеют разную структуру.

Данный раздел посвящен веб-API (в особенности позволяющим веб-серверу взаимодействовать с браузером), и здесь мы будем понимать под API именно этот тип интерфейсов. Но вы можете учесть, что в других контекстах API также является обобщенным термином, который может обозначать, например, интерфейс, позволяющий программе на Java взаимодействовать с программой на Python, работающей на том же компьютере. API не всегда означает интерфейс через Интернет и не обязательно должен включать в себя какие-либо веб-технологии.

Веб-API чаще всего используются разработчиками для взаимодействия с широко разрекламированными и хорошо документированными открытыми сервисами. Например, американский кабельный спортивный телевизионный канал ESPN предоставляет API (http://personeltest.ru/away/www.espn.com/apis/devcenter/docs/) для получения информации о спортсменах, счетах в играх и др. У Google в разделе для разработчиков (http://personeltest.ru/aways/console.developers.google.com) есть десятки API для языковых переводов, аналитики и геолокации.

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

Например, в следующем URL pathparam является параметром пути:

example.com/the-api-route/pathparam

А здесь pathparam является значением параметра param1:

example.com/the-api-route?param1=pathparam

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

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

Вот пример ответа на API-запрос в формате JSON:

{"user":{"id": 123, "name": "Ryan Mitchell", "city": "Boston"}}


А вот ответ на API-запрос в формате XML:

<user><id>123</id><name>Ryan Mitchell</name><city>Boston</city></user>


Сайт ip-api.com (http://personeltest.ru/away/ip-api.com/) имеет понятный и удобный API, который преобразует IP-адреса в реальные физические адреса. Вы можете попробовать выполнить простой запрос API, введя в браузере следующее

ip-api.com/json/50.78.253.58

В результате вы получите примерно такой ответ:

{"ip":"50.78.253.58","country_code":"US","country_name":"United States","region_code":"MA","region_name":"Massachusetts","city":"Boston","zip_code":"02116","time_zone":"America/New_York","latitude":42.3496,"longitude":-71.0746,"metro_code":506}

Обратите внимание: в запросе есть параметр пути json. Чтобы получить ответ в формате XML или CSV, нужно заменить его на соответствующий формат:

ip-api.com/xml/50.78.253.58
ip-api.com/csv/50.78.253.58


API и HTTP-методы

В предыдущем разделе мы рассмотрели API, отправляющие на сервер GET-запрос для получения информации. Существует четыре основных способа (или метода) запроса информации с веб-сервера через HTTP:

GET;
POST;
PUT;
DELETE.

Технически типов запросов больше четырех (например, еще есть HEAD, OPTIONS и CONNECT), но они редко используются в API и маловероятно, что когда-либо встретятся вам. Подавляющее большинство API ограничиваются этими четырьмя методами, а иногда даже какой-то их частью. Постоянно встречаются API, которые используют только GET или только GET и POST.

GET тот запрос, который вы используете, когда посещаете сайт, введя его адрес в адресной строке браузера. Обращаясь по адресу ip-api.com/json/50.78.253.58, вы применяете именно метод GET. Такой запрос можно представить как команду: Эй, веб-сервер, будь добр, выдай мне эту информацию.

Запрос GET по определению не вносит изменений в содержимое базы данных сервера. Ничего не сохраняется и ничего не изменяется. Информация только считывается.

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

Запрос PUT при взаимодействии с сайтами используется реже, но время от времени встречается в API. Этот запрос применяется для изменения объекта или информации. Например, в API можно задействовать запрос POST для создания пользователя и запрос PUT для изменения его адреса электронной почты.

Запросы DELETE, как нетрудно догадаться, служит для удаления объекта. Например, если отправить запрос DELETE по адресу myapi.com/user/23, то будет удален пользователь с идентификатором 23. Методы DELETE нечасто встречаются в открытых API, поскольку те в основном создаются для распространения информации или чтобы позволить пользователям создавать или публиковать информацию, но не удалять ее из баз данных.

В отличие от GET запросы POST, PUT и DELETE позволяют передавать информацию в теле запроса, в дополнение к URL или маршруту, с которого запрашиваются данные.
Как и ответ, получаемый от веб-сервера, эти данные в теле запроса обычно представляются в формате JSON или реже в формате XML. Конкретный формат данных определяется синтаксисом API. Например, при использовании API, который добавляет комментарии к сообщениям в блоге, можно создать следующий PUT-запрос:

example.com/comments?post=123

с таким телом запроса:

{"title": "Great post about APIs!", "body": "Very informative. Really helped me out with a tricky technical challenge I was facing. Thanks for taking the time to write such a detailed blog post about PUT requests!", "author": {"name": "Ryan Mitchell", "website": "http://pythonscraping.com", "company": "O'Reilly Media"}}


Обратите внимание: идентификатор сообщения в блоге (123) передается в качестве параметра в URL, а контент создаваемого нами комментария в теле запроса. Параметры и данные могут передаваться и в параметре, и в теле запроса. Какие параметры обязательны и где передаются опять-таки определяется синтаксисом API.

Подробнее об ответах на API-запросы

Как мы видели в примере с сайтом ip-api.com в начале данной главы, важной особенностью API является то, что эти интерфейсы возвращают хорошо отформатированные ответы. Наиболее распространенные форматы ответов XML (eXtensible Markup Language расширяемый язык разметки) и JSON (JavaScript Object Notation нотация объектов JavaScript).

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

<user><firstname>Ryan</firstname><lastname>Mitchell</lastname><username>Kludgist</username></user>

А теперь посмотрите на те же данные в формате JSON:

{"user":{"firstname":"Ryan","lastname":"Mitchell","username":"Kludgist"}}


Это всего 73 символа, на целых 36 % меньше, чем те же данные в формате XML.
Конечно, вероятен аргумент, что XML можно отформатировать так:

<user firstname="ryan" lastname="mitchell" username="Kludgist"></user>


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

Другая причина, по которой JSON так быстро становится более популярным, чем XML, связана с изменением веб-технологий. Раньше получателями API были по большей части серверные скрипты на PHP или .NET. Сейчас вполне может оказаться, что получать и отправлять вызовы API будет фреймворк наподобие Angular или Backbone. Серверным технологиям до определенной степени безразлично, в какой форме к ним поступают данные. Однако библиотекам JavaScript, таким как Backbone, проще обрабатывать JSON.

Принято считать, что API возвращают ответ либо в формате XML, либо в формате JSON, однако возможен любой другой вариант. Тип ответа API ограничен только воображением программиста, создавшего этот интерфейс. Еще один типичный формат ответа CSV (как видно из примера с ip-api.com). Отдельные API даже позволяют создавать файлы. Можно отправить на сервер запрос, по которому будет сгенерировано изображение с наложенным на него заданным текстом, или же запросить определенный файл XLSX или PDF.

Некоторые API вообще не возвращают ответа. Например, если отправить на сервер запрос для создания комментария к записи в блоге, то он может вернуть только HTTP-код ответа 200, что означает: Я опубликовал комментарий; все в порядке! Другие запросы могут возвращать минимальный ответ наподобие такого:

{"success": true}


В случае ошибки вы можете получить такой ответ:

{"error": {"message": "Something super bad happened"}}


Или же, если API не очень хорошо сконфигурирован, вы можете получить не поддающуюся анализу трассировку стека или некий текст на английском. Отправляя запрос к API, как правило, имеет смысл сначала убедиться, что получаемый ответ действительно имеет формат JSON (или XML, или CSV, или любой другой формат, который вы ожидаете получить).

Об авторе

Райан Митчелл (Ryan Mitchell) старший инженер-программист в бостонской компании HedgeServ, в которой она разрабатывает API и инструменты для анализа данных. Райан окончила Инженерно-технический колледж им. Франклина В. Олина, имеет степень магистра в области разработки программного обеспечения и сертификат по анализу и обработке данных, полученный на курсах повышения квалификации при Гарвардском университете. До прихода в HedgeServ Райан трудилась в компании Abine, где разрабатывала веб-скраперы и средства автоматизации на Python. Регулярно выступает консультантом проектов по веб-скрапингу для розничной торговли, сферы финансов и фармацевтики. По совместительству работает консультантом и внештатным преподавателем в Северо-Восточном университете и Инженерно-техническом колледже им. Франклина В. Олина.

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Python

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Программирование на Rust

13.10.2020 14:23:08 | Автор: admin
image Привет, Хаброжители! Официальный гайд по языку программирования Rust поможет вам создавать более быстрое и надежное программное обеспечение. Высокоуровневая эргономика и низкоуровневое управление часто противоречат друг другу, но Rust бросает вызов этому конфликту.

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

  • Владение и заимствование, жизненный цикл и типажи.
  • Гарантированная безопасность программ.
  • Тестирование, обработка ошибок и эффективный рефакторинг.
  • Обобщения, умные указатели, многопоточность, типажные объекты и сопоставления.
  • Работа со встроенным менеджером пакетов Cargo для создания, тестирования, документирования кода и управления зависимостями.
  • Продвинутые средства работы с Unsafe Rust.

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

Для кого эта книга


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

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

В этой книге вы найдете два типа глав: концептуальные и проектные. В концептуальных главах вы будете усваивать тот или иной аспект языка. Мы вместе будем создавать небольшие программы, применяя то, что вы уже усвоили. Главы 2, 12 и 20 посвящены разработке проектов, остальные главы концептуальные.

В главе 1 рассказано, как установить Rust, написать программу Hello, World! и использовать пакетный менеджер и инструмент Cargo. Глава 2 представляет собой практическое введение в язык Rust. Здесь мы рассмотрим понятия с точки зрения высокоуровневого языка, а в последующих главах приведем дополнительные подробности. Если вы хотите сразу же приступить к практике, то сможете это сделать. Можно даже пропустить главу 3, в которой рассматриваются средства языка Rust, аналогичные средствам других языков программирования, сразу перейти к главе 4 и узнать о системе владения в Rust. Но если вы дотошны и предпочитаете разбирать каждую деталь, прежде чем переходить к следующей, то можете пропустить главу 2, перейти к главе 3, а затем вернуться к главе 2, когда захотите поработать над проектом. Так вы сможете применить знания, которые освоили.

В главе 5 обсуждаются структуры и методы, а в главе 6 рассматриваются перечисления, выражения match и конструкция управления потоком if let. Вы будете использовать структуры и перечисления для создания в языке Rust настраиваемых типов.

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

В главе 10 мы погрузимся в обобщения, типажи и жизненные циклы, которые дают вам возможность определять код, применимый к нескольким типам. Глава 11 полностью посвящена тестированию, которое даже несмотря на гарантии безопасности языка Rust является необходимым для обеспечения правильной логики программы. В главе 12 мы построим собственную реализацию подмножества функциональности инструмента командной строки grep, которая ищет текст внутри файлов. Для этого мы воспользуемся многими понятиями, которые обсуждаются в предыдущих главах.

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

В главе 16 мы рассмотрим разные модели конкурентного программирования и поговорим о том, как Rust помогает вам безбоязненно программировать в множестве потоков исполнения. Глава 17 обращается к сопоставлению идиом Rust с принципами объектно-ориентированного программирования, с которыми вы, возможно, знакомы.

Глава 18 представляет собой справочный материал о паттернах и сопоставлении с паттернами, которые являются мощными способами выражения идей во всех программах на языке Rust. Глава 19 содержит ряд дополнительных тем, представляющих интерес, включая небезопасный код Rust, макрокоманды и другие сведения о типажах, типах, функциях и замыканиях.
В главе 20 мы осуществим проект, в котором выполним реализацию низкоуровневого многопоточного сервера!

Наконец, несколько приложений в конце книги содержат полезную информацию о языке в справочном формате. В приложении А приводятся ключевые слова языка Rust, в приложении Б рассказывается об операторах и символах языка Rust, в приложении В рассматриваются генерируемые типажи, предусмотренные стандартной библиотекой, в приложении Г приводятся некоторые полезные инструменты разработчика, а в приложении Д даются пояснения по поводу редакций языка Rust.

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

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

Где могут использоваться паттерны


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

Ветви выражения match


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

   match ЗНАЧЕНИЕ {          ПАТТЕРН => ВРАЖЕНИЕ,          ПАТТЕРН => ВРАЖЕНИЕ,          ПАТТЕРН => ВРАЖЕНИЕ,   }

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

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

Условные выражения if let


В главе 6 мы обсуждали выражения if let главным образом как более краткий способ написания эквивалента выражения match, который совпадает только с одним случаем. Как вариант if let может иметь соответствующий else, содержащий выполняемый код, если паттерн в выражении if let не совпадает.

Листинг 18.1 показывает, что также существует возможность смешивать и сочетать выражения if let, else if и else if let. Благодаря этому мы получаем больше гибкости, чем при использовании выражения match, в котором можно выразить только одно сравниваемое с паттернами значение. Кроме того, условия в серии выражений if let, else if и else if let не обязательно должны относиться друг к другу.

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

Листинг 18.1. Смешивание выражений if let, else if, else if let и else

src/main.rs      fn main() {             let favorite_color: Option<&str> = None;             let is_tuesday = false;             let age: Result<u8, _> = "34".parse();      (1) if let Some(color) = favorite_color {          (2) println!("Используя ваш любимый цвет, {}, в качестве фона", color);      (3) } else if is_tuesday {          (4) println!("Вторник - зеленый день!");      (5) } else if let Ok(age) = age {          (6) if age > 30 {               (7) println!("Использование фиолетового цвета в качестве фона");              } else {               (8) println!("Использование оранжевого цвета в качестве фона");              }      (9) } else {          (10) println!("Использование синего цвета в качестве фона");           }     }

Если пользователь указывает любимый цвет (1), то это фоновый цвет (2). Если сегодня вторник (3), то фоновый цвет зеленый (4). Если пользователь указывает свой возраст в качестве строки и мы можем успешно разобрать ее как число (5), то цвет будет либо фиолетовым (7), либо оранжевым (8) в зависимости от значения числа (6). Если ни одно из этих условий не применимо (9), то фоновый цвет синий (10).

Эта условная структура позволяет поддерживать сложные требования. С жестко закодированными значениями, которые здесь есть, этот пример будет выводить

Использование фиолетового цвета в качестве фона.

Вы видите, что выражение if let может также вводить затененные переменные таким же образом, как и рукава выражения match: строка кода if let Ok(age) = age (5) вводит новую затененную переменную age, содержащую значение внутри варианта Ok. Это означает, что нужно поместить условие if age > 30 в этот блок (6): мы не можем совместить эти два условия в выражении if let Ok (age) = age && age > 30. Затененная переменная age, которую мы хотим сравнить с 30, будет недействительна до тех пор, пока новая область видимости не начнется с фигурной скобки.

Недостатком использования выражений if let является то, что компилятор не проверяет исчерпываемость, в то время как с выражениями match он это делает. Если бы мы пропустили последний блок else (9) и, следовательно, обработку некоторых случаев, то компилятор не предупредил бы нас о возможной логической ошибке.

Условные циклы while let


Похожий по конструкции с выражением if let условный цикл while let позволяет циклу while работать до тех пор, пока паттерн совпадает. Пример в листинге 18.2 показывает цикл while let, который использует вектор в качестве стека и выводит значения в векторе в порядке, обратном тому, в котором они были добавлены.

Листинг 18.2. Использование цикла while let для печати значений, пока метод stack.pop() возвращает Some

    let mut stack = Vec::new();    stack.push(1);    stack.push(2);    stack.push(3);    while let Some(top) = stack.pop() {          println!("{}", top);    }

В этом примере выводятся 3, 2 и затем 1. Метод pop берет последний элемент из вектора и возвращает Some(value). Если вектор пуст, то pop возвращает None. Цикл while продолжает выполнение кода в своем блоке до тех пор, пока pop возвращает Some. Когда pop возвращает None, цикл останавливается. Мы можем использовать условный цикл while let, чтобы удалить каждый элемент из стека.

Циклы for


В главе 3 мы упоминали, что цикл for это наиболее распространенная циклическая конструкция в коде на языке Rust, но мы еще не обсуждали паттерн, который берет for. В цикле for паттерном является значение, следующее непосредственно за ключевым словом for, поэтому в for x in y паттерном является x.

Листинг 18.3 показывает использование паттерна в цикле for для деструктурирования, или разложения, кортежа в рамках for.

Листинг 18.3. Использование паттерна в цикле for для деструктурирования кортежа

   let v = vec!['a', 'b', 'c'];   for (index, value) in v.iter().enumerate() {        println!("{} находится в индексе {}", value, index);   }

Код из листинга 18.3 выводит следующее:

   а находится в индексе 0   b находится в индексе 1   с находится в индексе 2

Мы используем метод enumerate, чтобы переделать итератор для порождения значения и индекса этого значения в итераторе, помещенных в кортеж. Первый вызов метода enumerate порождает кортеж (0, 'a'). Когда это значение сочетается с паттерном (index, value), то index равен 0, а value равно 'a', выводится первая строка данных.

Инструкции let


До этой главы мы прямо обсуждали использование паттернов только с выражениями match и if let, но на самом деле мы использовали паттерны и в других местах, в том числе в инструкциях let. Рассмотрим простую передачу значения переменной с помощью let:

let x = 5;

На протяжении всей книги мы сотни раз использовали инструкции let подобного рода, и хотя вы, возможно, не осознавали этого, вы использовали паттерны! В более формальном плане инструкция let выглядит так:

let ПАТТЕРН = ВРАЖЕНИЕ;

В таких инструкциях, как let x = 5;, с именем переменной в слоте ПАТТЕРН, имя переменной это всего лишь простая форма паттерна. Rust сравнивает выражение с паттерном и назначает любые имена, которые он находит. Поэтому в примере let x = 5; паттерном является x, который означает связать то, что совпадает здесь, с переменной x. Поскольку имя x представляет весь паттерн, то этот паттерн фактически означает связать все с переменной x, каким бы ни было значение.

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

Листинг 18.4. Использование паттерна для деструктурирования кортежа и создания сразу трех переменных

let (x, y, z) = (1, 2, 3);

Здесь мы сопоставляем кортеж с паттерном. Rust сравнивает (1, 2, 3) с (x, y, z) и видит, что это значение совпадает с паттерном, поэтому Rust связывает 1 с x, 2 с y и 3 с z. Можно думать об этом кортежном паттерне как о вложении в него трех отдельных паттернов переменных.
Если число элементов в паттерне не совпадает с числом элементов в кортеже, то совокупный тип не будет совпадать и мы получим ошибку компилятора. Например, листинг 18.5 показывает попытку деструктурирования кортежа из трех элементов в две переменные, которая не будет работать.

Листинг 18.5. Неправильное построение паттерна, переменные которого не совпадают с числом элементов в кортеже

let (x, y) = (1, 2, 3);

Попытка компиляции этого кода приводит к ошибке типа:

error[E0308]: mismatched types  --> src/main.rs:2:9   |2 |        let (x, y) = (1, 2, 3);   |           ^^^^^^ expected a tuple with 3 elements, found one with 2 elements   |   = note: expected type `({integer}, {integer}, {integer})`                    found type `(_, _)`

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

Параметры функций


Параметры функций также могут быть паттернами. Код в листинге 18.6, объявляющий функцию foo, которая берет один параметр x типа i32, теперь вам знаком.

Листинг 18.6. Сигнатура функции использует паттерны в параметрах

fn foo(x: i32) {     // здесь будет код}

Часть x это паттерн! Как и в случае с let, мы можем сопоставить кортеж в аргументах функции с паттерном. Листинг 18.7 разбивает значения в кортеже в момент, когда мы передаем его внутрь функции.

Листинг 18.7. Функция с параметрами, которые деструктурируют кортеж

src/main.rs      fn print_coordinates(&(x, y): &(i32, i32)) {            println!("Текущее местоположение: ({}, {})", x, y);      }      fn main() {            let point = (3, 5);            print_coordinates(&point);      }

Этот код выводит

Текущее местоположение: (3, 5)

Значения &(3, 5) совпадают с паттерном &(x, y), поэтому x равно 3, а y 5.
Кроме того, мы можем использовать паттерны в списках параметров замыкания таким же образом, как и в списках параметров функций, поскольку замыкания похожи на функции, как описано в главе 13.

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

Опровержимость: возможность несовпадения паттерна


Паттерны бывают двух видов: опровержимые и неопровержимые. Паттерны, которые будут совпадать с любым возможным переданным значением, неопровержимые. Примером является x в инструкции let x = 5;, потому что x совпадает абсолютно со всем и, следовательно, не может не совпасть. Паттерны, которые не совпадают с некоторыми возможными значениями, являются опровержимыми. Примером служит Some(x) в выражении if let Some(x) = a_value, потому что, если значение в переменной a_value равно None, а не Some, то паттерн Some(x) не совпадет.

Параметры функций, инструкции let и циклы for могут принимать только неопровержимые паттерны, поскольку программа не сможет делать ничего значимого, когда значения не совпадают. Выражения if let и while let принимают только опровержимые паттерны, поскольку по определению они предназначены для обработки возможной ошибки: функциональность условного выражения заключается в его способности выполнять разные действия в зависимости от успеха или провала.

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

Давайте рассмотрим, что происходит, когда мы пытаемся использовать опровержимый паттерн в месте, где Rust требует неопровержимый паттерн, и наоборот. Листинг 18.8 показывает инструкцию let, но для паттерна мы задали Some(x), опровержимый паттерн. Как и следовало ожидать, этот код не компилируется.

Листинг 18.8. Попытка использовать опровержимый паттерн с let

let Some(x) = some_option_value;

Если бы значение some_option_value было равно None, то оно не совпало бы с паттерном Some(x), то есть паттерн является опровержимым. Однако инструкция let может принимать только неопровержимый паттерн, поскольку код не может сделать ничего допустимого со значением None. Во время компиляции язык Rust будет жаловаться, что мы пытались использовать опровержимый паттерн там, где требуется неопровержимый паттерн:

error[E0005]: refutable pattern in local binding: `None` not covered  -->   |3 | let Some(x) = some_option_value;   |     ^^^^^^^ pattern `None` not covered

Поскольку мы не охватили (и не могли охватить!) каждое допустимое значение с паттерном Some(x), Rust по праву выдает ошибку компилятора.

Для устранения проблемы, когда у нас опровержимый паттерн вместо неопровержимого, мы можем изменить код, использующий паттерн: вместо let можно применить if let. Тогда, если паттерн не совпадает, то код в фигурных скобках будет пропущен и работа продолжится корректно. Листинг 18.9 показывает, как исправить код из листинга 18.8.

Листинг 18.9. Использование выражения if let и блока с опровержимыми паттернами вместо let

if let Some(x) = some_option_value {    println!("{}", x);}

Код готов! Это абсолютно правильный код, хотя он означает, что мы не можем использовать неопровержимый паттерн без ошибки. Если мы дадим выражению if let паттерн, который всегда будет совпадать, например x, как показано в листинге 18.10, то он компилироваться не будет.

Листинг 18.10. Попытка использовать неопровержимый паттерн с выражением if let

if let x = 5 {    println!("{}", x);};

Компилятор жалуется, что использовать выражение if let с неопровержимым паттерном не имеет смысла:

error[E0162]: irrefutable if-let pattern  --> <anon>:2:8   |2 | if let x = 5 {   |        ^ irrefutable pattern

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

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

Об авторах


Стив Клабник возглавляет команду по документированию Rust и является одним из ключевых разработчиков языка. Часто выступает с лекциям и пишет много открытого исходного кода. Ранее работал над такими проектами, как Ruby и Ruby on Rails.

Кэрол Николс является членом команды разработчиков Rust Core и соучредителем Integer 32, LLC, первой в мире консалтинговой компании по разработке ПО, ориентированной на Rust. Николс является организатором конференции Ржавый пояс (Rust Belt) по языку Rust.

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Rust

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Программируем на C 8.0. Атрибуты

18.06.2021 16:08:17 | Автор: admin
image Привет, Хабр! Обращаем ваше внимание на одну новинку (сдана в типографию), доступную уже сейчас для покупки в электронном виде.

Язык C# существует уже около двух десятилетий. Он неуклонно развивался и в плане возможностей, и в плане размера, но основные характеристики Microsoft всегда сохраняла без изменений. Каждая новая возможность должна идеально вписываться в состав предыдущих, улучшая язык, а не превращая его в несвязный набор различных функций.

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

Вашему внимаю предлагаю отрывок из книги.

Атрибуты


В .NET можно аннотировать компоненты, типы и их члены с помощью атрибутов. Назначение атрибута регулировать или изменять поведение платформы, инструмента, компилятора или CLR. Например, в главе 1 я демонстрировал класс, аннотированный атрибутом [TestClass]. Он сообщал инфраструктуре юнит-теста, что класс содержит ряд тестов, которые должны быть выполнены как часть набора тестов.

Атрибуты лишь содержат информацию, но ничего не делают сами по себе. Проведу аналогию с физическим миром. Если вы распечатываете этикетку, содержащую информацию о месте назначения и отслеживании, и прикрепляете ее к посылке, эта этикетка сама по себе не заставит посылку добраться до пункта назначения. Такая этикетка полезна только тогда, когда груз находится в обработке у транспортной компании. Когда компания заберет посылку, этикетка понадобится, чтобы определить, как и куда направить груз. Таким образом, этикетка важна, но ее единственной задачей является предоставление информации, которая требуется какой-либо системе. С атрибутами .NET все так же они работают только в том случае, если кто-то ожидает их найти. Некоторые атрибуты обрабатываются CLR или компилятором, но таких меньшинство. Большинство же используются платформами, библиотеками, инструментами (например, системами юнит-теста) или вашим собственным кодом.

Применение атрибутов

Во избежание необходимости вводить дополнительный набор понятий в систему типов .NET работает с ними как с экземплярами типов .NET. Для использования в качестве атрибута тип должен быть производным от класса System.Attribute, и это его единственная особенность. Чтобы применить атрибут, вы помещаете имя типа в квадратные скобки и, как правило, размещаете непосредственно перед целью атрибута. Листинг 14.1 показывает некоторые атрибуты из среды тестирования Microsoft. Один я применил к классу, чтобы указать, что он содержит тесты, которые я хотел бы запустить. Кроме этого, я применил атрибуты к отдельным методам, сообщая среде тестирования, какие из них представляют собой тесты, а какие содержат код инициализации, который должен выполняться перед каждым тестом.

Листинг 14.1. Атрибуты в классе юнит-теста

using Microsoft.VisualStudio.TestTools.UnitTesting;namespace ImageManagement.Tests{   [TestClass]   public class WhenPropertiesRetrieved   {      private ImageMetadataReader _reader;      [TestInitialize]      public void Initialize()      {         _reader = new ImageMetadataReader(TestFiles.GetImage());      }      [TestMethod]      public void ReportsCameraMaker()      {         Assert.AreEqual(_reader.CameraManufacturer, "Fabrikam");      }      [TestMethod]      public void ReportsCameraModel()      {          Assert.AreEqual(_reader.CameraModel, "Fabrikam F450D");      }   }}

Если вы заглянете в документацию по большинству атрибутов, вы обнаружите, что их настоящие имена оканчиваются на Attribute. Если нет класса с именем, указанным в скобках, компилятор C# попытается добавить Attribute, поэтому атрибут [TestClass] в листинге 14.1 ссылается на класс TestClassAttribute. Если хотите, вы можете записывать имя класса полностью, например [TestClassAttribute], но чаще используют более короткую форму.

Если необходимо применить несколько атрибутов, то у вас есть два варианта. Можно предоставить несколько наборов скобок или поместить несколько атрибутов в одну пару скобок, разделив их запятыми.

Некоторые типы атрибутов способны принимать аргументы конструктора. Например, среда тестирования Microsoft содержит атрибут TestCategoryAttribute. При запуске можно выбрать выполнение только тех тестов, которые принадлежат определенной категории. Данный атрибут требует, чтобы вы передали имя категории в качестве аргумента конструктора, потому что нет смысла применять этот атрибут без указания имени. Синтаксис для указания аргументов конструктора атрибута вполне ожидаемый (листинг 14.2).

Листинг 14.2. Атрибут с аргументом конструктора

[TestCategory("Property Handling")][TestMethod]public void ReportsCameraMaker(){...

Вы также можете указать свойства или значения полей. Характеристиками некоторых атрибутов можно управлять только через свойства или поля, но не через аргументы конструктора. (Если атрибут имеет множество необязательных настроек, обычно проще представить их как свойства или поля вместо определения перегрузки конструктора для каждой возможной комбинации настроек.) Синтаксис заключается в одной или нескольких записях вида PropertyOrFieldName=Value после аргументов конструктора (или вместо них, если их нет). В листинге 14.3 показан другой атрибут, используемый в юнит-тестировании, ExpectedExceptionAttribute, позволяющий указать, что при выполнении теста вы ожидаете, что он выдаст конкретное исключение. Тип исключения является обязательным, поэтому мы передаем его в качестве аргумента конструктора, но данный атрибут позволяет также указать, должен ли исполнитель теста принимать исключения типа, производного от указанного. (По умолчанию он принимает только точное совпадение.) Это поведение управляется с помощью свойства AllowDerivedTypes.

Листинг 14.3. Указание необязательных настроек атрибута со свойствами

[ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)][TestMethod]public void ThrowsWhenNameMalformed(){...

Применение атрибута не ведет к его созданию. Все, что вы делаете при применении атрибута, это предоставляете инструкции о том, как атрибут должен быть создан и инициализирован, если он кому-то потребуется. (Бытует распространенное заблуждение, что атрибуты метода создаются при запуске метода. Это не так.) Когда компилятор создает метаданные для сборки, он включает информацию о том, какие атрибуты были применены к каким элементам, включая список аргументов конструктора и значения свойств, а CLR будет извлекать и использовать эту информацию, только если это кому-то понадобится. Например, когда вы говорите Visual Studio запустить ваши юнит-тесты, он загрузит вашу тестовую сборку, а затем для каждого открытого типа запросит у CLR все связанные с тестированием атрибуты. Это и есть та точка, в которой создаются атрибуты. Если просто загрузить сборку, скажем добавив ссылку на нее из другого проекта, а затем использовать некоторые из содержащихся в ней типов, то атрибуты создаваться не будут они останутся не более чем набором инструкций, затерянных в метаданных вашей сборки.

Цели атрибутов

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

В большинстве случаев вы обозначаете цель, просто помещая атрибут непосредственно перед ней. Но это не сработает в случае сборок или модулей, потому что в вашем исходном коде нет ничего, что бы их представляло, все в вашем проекте идет в сборку, которую он производит. Модули, в свою очередь, тоже являются совокупностью (как правило, составляя сборку, как я описал в главе 12). Поэтому для них мы должны явно указать цель в начале атрибута. Вы часто будете видеть атрибуты уровня сборки, подобные показанным в листинге 14.4, в файле GlobalSuppressions.cs. Visual Studio иногда предлагает варианты для изменения вашего кода, и если вы решите подавить этот функционал, это можно сделать с помощью атрибутов уровня сборки.

Листинг 14.4. Атрибуты уровня сборки

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(   "StyleCop.CSharp.NamingRules",   "SA1313:Parameter names should begin with lower-case letter",   Justification = "Triple underscore acceptable for unused lambda parameter",   Scope = "member",   Target = "~M:Idg.Examples.SomeMethod")]

Атрибуты уровня модуля следуют той же схеме, хотя и встречаются гораздо реже. Не в последнюю очередь это происходит потому, что многомодульные сборки встречаются довольно редко и не поддерживаются .NET Core. В листинге 14.5 показано, как настроить возможность отладки конкретного модуля в том случае, если вы хотите, чтобы один модуль в многомодульной сборке был легко отлаживаемым, а остальные JIT-компилируемыми с полной оптимизацией. (Это специально придуманный сценарий, с помощью которого я могу показать синтаксис. На практике вы вряд ли захотите это делать.) Я расскажу об атрибуте DebuggableAttribute позже, в подразделе JIT-компиляция на с. 743.

Листинг 14.5. Атрибут уровня модуля

using System.Diagnostics;[module: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations)]

Возвращаемые значения методов могут быть аннотированы, и это также требует квалификации, потому что атрибуты возвращаемого значения располагаются перед методом, там же, где и атрибуты, которые применяются к самому методу. (Атрибуты для параметров не нуждаются в квалификации, потому что они располагаются в круглых скобках вместе с аргументами.) В листинге 14.6 показан метод с атрибутами, применяемыми как к методу, так и к типу возвращаемого значения. (Атрибуты в этом примере являются частью служб взаимодействия, которые позволяют коду .NET вызывать внешний код, такой как API ОС. В этом примере импортируется функция библиотеки Win32, что позволяет использовать ее из C#. Существует несколько различных представлений для логических значений в неуправляемом коде, поэтому в данном случае я аннотировал возвращаемый тип с помощью атрибута MarshalAsAttribute, указав, какой именно тип следует ожидать CLR.)

Оформить предзаказ бумажной книги можно на нашем сайте
Подробнее..

Книга Наглядный CSS

08.06.2021 14:19:38 | Автор: admin
image Привет, Хаброжители! На 1 июня 2018 года CSS содержал 415 уникальных свойств, относящихся к объекту style в любом элементе браузера Chrome. Сколько свойств доступно в вашем браузере на сегодняшний день? Наверняка уже почти шесть сотен. Наиболее важные из них мы и рассмотрим. Грег Сидельников упорядочил свойства по основной категории (положение, размерность, макеты, CSS-анимация и т. д.) и визуализировал их работу. Вместо бесконечных томов документации две с половиной сотни иллюстраций помогут вам разобраться во всех тонкостях работы CSS. Эта книга станет вашим настольным справочником, позволяя мгновенно перевести пожелания заказчика и собственное видение в компьютерный код!



Позиционирование


Тестовый элемент
image

Обратите внимание: на самом деле здесь три элемента. Во-первых, сам документ. Но теоретически это может быть html, или body, или любой другой родительский контейнер. Фактические стили будут применены к тестовому элементу в данном родительском контейнере. Данный образец в качестве примера будет использоваться в главе 6, касающейся позиции элемента.

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

Доступно пять типов позиционирования: static (статичное) (по умолчанию), relative (относительное), absolute (абсолютное), fixed (фиксированное) и sticky (липкое). Мы рассмотрим их на протяжении всей этой главы.

По умолчанию для всех элементов используется статичное позиционирование:

image

Относительное позиционирование практически такое же, как и статичное:

image

Статичное и относительное позиционирование
По умолчанию свойство position установлено в static, то есть элементы отображаются в том порядке, в котором они были указаны в вашем HTML-документе, в соответствии с нормальным потоком HTML-страницы.

На статично позиционированные элементы не влияют свойства top, left, right и bottom.

Чтобы понять разницу, создадим несколько основных стилей CSS:

001 /* Применить границу ко всем элементам <div> */002 div { border: 1px solid gray; }003004 /* Установить произвольные значения ширины и положения */005 #A { width: 100px; top: 25px; left: l00px; }006 #B { width: 215px; top: 50px; }007 #C { width: 250px; top: 50px; left:25px; }008 #D { width: 225px; top: 65px; }009 #E { width: 200px; top: 70px; left:50px; }

Граница 1px solid gray применена ко всем элементам div, поэтому теперь легче увидеть фактические размеры каждого HTML-элемента при отображении его в браузере.

Далее мы применим свойства position: static и position: relative к элементу div, чтобы увидеть разницу между статичным и относительным позиционированием.

image

По сути, элементы с позиционированием static и relative одинаковы, за исключением того, что элементы relative могут иметь top (верхнюю) и left (левую) позиции относительно их исходного местоположения. Относительные элементы также могут иметь right (правое) и bottom (нижнее) положение.

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

Следовательно, свойство position: relative не гарантирует полную точность при необходимости разместить элемент в идеальном месте в его родительском контейнере. Для такой цели больше всего подходит свойство position: absolute.

Абсолютное и фиксированное позиционирование

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

image

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

В данной главе мы рассмотрим более приближенные к реальности примеры.

Обратите внимание: если свойства width и height родителя не указаны явно, то применение позиционирования absolute (или fixed) к его единственному дочернему элементу преобразует его размеры в 0 0, однако данный элемент все равно будет позиционироваться относительно него:

image

На предыдущей схеме слева абсолютно позиционированные элементы не заполняют свой родительский контейнер содержимым. Они как бы плавают над ним, сохраняя положение относительно своего элемента-контейнера. Справа размеры родительского элемента заданы явно. Технически для потомка со свойством position: absolute не задан никакой эффект, его точка поворота все еще находится в положении 0 0 родительского элемента.

Чтобы элементы со свойством position: absolute были выровнены относительно их родителя, его свойство position не должно быть установлено в static (по умолчанию):

image

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

image

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

Использование свойства position: absolute для выравнивания элементов по углам родителя:

image

Изменить начальную точку, из которой будет рассчитываться смещение, можно, комбинируя положения top, left, bottom и right. Однако не получится одновременно использовать положения left и right, так же как и top и bottom. При таком применении один элемент перекроет другой.

Использование свойства position: absolute с отрицательными значениями:

image

Фиксированное позиционирование

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

Использование свойства position: fixed для размещения элементов в фиксированном месте на экране относительно документа:

image

Использование свойства position: fixed с отрицательными значениями:

image

Липкое позиционирование

Это позиционирование было одним из последних дополнений в CSS. Ранее для достижения того же эффекта вам приходилось писать собственный код JavaScript или мультимедийный запрос.
Липкое позиционирование часто используется для создания плавающих панелей навигации:

image

Далее приведен простой код, чтобы навигационная панель прилипала к верхней (top: 0) границе экрана. Обратите внимание: добавлен код -webkit-sticky для совместимости с браузерами на движке Webkit (такими как Chrome):

001 .navbar {002 /* Определение некоторых основных настроек */003 padding: 0px;004 border: 20px solid silver;005 background-color: white;006 /* Добавить липкость */007 position: -webkit-sticky;008 position: sticky;009 top: 0;010 }

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону CSS

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Еще более эффективный Agile

12.01.2021 16:20:24 | Автор: admin
image Привет, Хаброжители! Любой компании хочется добиться большей эффективности разработки ПО, ведь это напрямую влияет на прибыль. Большая часть литературы по Agile ориентирована на крупные компании с высокими темпами роста, но как быть, если ваша компания находится не на переднем фланге ИТ? Хорошая новость в том, что каждая организация может улучшить производительность, и эта книга поможет найти конкретные пути и решения, позволяющие извлечь максимальную выгоду от Agile-методов. Я не евангелист Agile. Я сторонник того, что работает, и противник того, что много обещает, но не приносит результатов. В этой книге методология Agile представлена не как движение, которое требует повышенной сознательности, а как набор специальных управленческих и технических методов, эффект и взаимодействие которых доступны для понимания любому бизнесмену или айтишнику. Энтузиасты Agile могут раскритиковать эту книгу за то, что она не пропагандирует передовые методы Agile. Но в этом и смысл акцент на практических методах, доказавших свою эффективность. История Agile полна идей, которые удалось успешно реализовать паре энтузиастов в некоторых организациях, но которыми невозможно пользоваться всем остальным, говорит Стив Макконнелл. Новая книга Стива Макконнелла, автора легендарных книг Code Complete и Software Estimation, объединяет реальный опыт сотен компаний. Воспользуйтесь простым и понятным руководством по современным и самым эффективным методам Agile.

ЕЩЕ БОЛЕЕ ЭФФЕКТИВНОЕ ВПОЛНЕНИЕ ПРОЕКТОВ


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

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

Терминология значительно различается. Некоторые компании считают, что понятие релиз это синоним слова проект. Другие думают, что понятие релиз относится к последовательной разработке, поэтому прекратили его использовать. Третьи определяют понятие функция как объем работ, рассчитанный на 39 человек и 12 года. В этой главе под словом проект я буду иметь в виду любые из перечисленных видов работ, то есть работу некоторого количества сотрудников в течение длительного времени.

КЛЮЧЕВОЙ ПРИНЦИП: НЕБОЛЬШИЕ РАЗМЕР ПРОЕКТОВ


За последние 20 лет наиболее известны случаи успешного применения Agile в небольших проектах. Agile первые 10 лет своего существования уделял большое внимание тому, чтобы проекты были небольшими, то есть 510 человек в команде (например, 39 разработчиков, владелец продукта и скрам-мастер). Акцент на небольшом размере проектов очень важен, потому что с небольшими проектами успешно справиться легче, нежели с крупными, как показано на рис. 9.1.

image

Каперс Джонс уже 20 лет постулирует, что мелкие проекты чаще завершаются успешно, чем крупные [Джонс, 1991; 2012]. Я обобщил большинство исследований о зависимости успешности проектов от размера в своих книгах Совершенный код [Макконнелл, 2004; СПб.: Питер, 2007] и Software Estimation: Demystifying the Black Art [Макконнелл, 2006].

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

Следовательно, чем крупнее становится проект, тем больше допускается ошибок (рис. 9.2). Это говорит не просто о том, что общее количество ошибок растет, а о том, что в крупных проектах несоизмеримо больше ошибок!

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

image

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

image

Эту обратную зависимость между размером и производительностью тщательно исследовали и проверяли на протяжении более 40 лет. Фред Брукс рассуждал на тему издержек масштаба при разработке ПО в первом издании своей книги Мифический человеко-месяц [Брукс, 1975; СПб.: Питер, 2021]. Работа Ларри Патнэма по оценке издержек при создании ПО подтвердила наблюдения Брукса [Патнэм, 1992]. Исследование модели издержек разработки (Cocomo) эмпирически подтвердило существование издержки масштаба дважды в исследовании конца 1970-х годов и в обновленном исследовании конца 1990-х [Боэм, 1981; 2000].

Вывод таков: чтобы максимально увеличить вероятность успешного выполнения проекта по Agile, старайтесь сохранять небольшие масштабы проекта (и команды).

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

Ключевой принцип: короткие спринты


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

Короткие спринты снижают количество промежуточных требований и улучшают реагирование на новые требования

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

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

image

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

image

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

Короткие спринты обеспечивают большую оперативность при работе с клиентами и заинтересованными сторонами

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

Короткие спринты укрепляют доверие стейкхолдеров

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

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

Короткие спринты помогают сократить время на эксперименты

В контексте Запутанные по Cynefin проблемы нужно сначала исследовать, прежде чем получится понять весь объем работ. Такие исследования нужно характеризовать так: Чтобы получить ответ на тот или иной вопрос, сделайте наименьшее необходимое количество работы. К сожалению, закон Паркинсона гласит, что работа занимает весь доступный объем времени. А до тех пор, пока у команды не разовьется железная дисциплина, решение вопроса, если на него выделен месяц, и займет ровно месяц. Но если есть всего две недели, то чаще всего и решение вопроса занимает две недели.

Короткие спринты позволяют вовремя обнаружить издержки и риски

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

Короткие спринты способствуют подотчетности команды

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

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

Короткие спринты способствуют подотчетности

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

Короткие спринты способствуют автоматизации

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

Короткие спринты чаще доставляют чувство удовлетворенности

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

Короткие спринты. Резюме


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

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


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

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

Оценка размера бэклога продукта

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

Расчет скорости

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

Планирование спринта

Команда осуществляет планирование объема работ на спринт, также измеряемый единицами сложности историй, на основе наблюдений за скоростью команды.

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

Отслеживание релиза

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

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

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

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


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

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

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

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

image

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

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

Вертикальные срезы обеспечивают более тесную обратную связь

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

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

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

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

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

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

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

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

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

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

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

Ключевой принцип: управляйте техническим долгом


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

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

Последствия технического долга

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

image


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

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

image


Крухтен, Норд и Озкая разработали отличную для понимания схему того, как появляется технический долг, какую (вероятную) ценность для бизнеса он имеет и как, в конечном счете, становится больше обязательством, чем активом (рис. 9.5).

image


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

Погашение технического долга

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

Виды долга и как с ним справиться

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

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

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

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

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

Унаследованный долг. Долг, унаследованный новой командой от старой кодовой базы.

Табл.9.1 показывает, какие подходы рекомендованы для реагирования на перечисленные виды долга.

image

Польза обсуждения технического долга

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

Выстройте структуру работы во избежание выгорания


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

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

Постоянные спринты не оставляют времени на отдых, если каждый спринт действительно проходит в темпе спринта.

Одно из противоядий от усталости после спринтов изменение по необходимости длительности спринтов. Системный способ его обеспечить использовать шаблон 6 2 1, шесть спринтов по две недели плюс один спринт длительностью одну неделю, в сумме 13 недель, которые как раз составляют один квартал.

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

Различная длина каденции спринта соответствует понятию устойчивого темпа, применяемого в Agile. Многие исследования по Agile приравнивают устойчивые темпы к отсутствию свободных вечеров и выходных. Но я думаю, что это досадное упрощение, которое игнорирует различия в предпочтениях условий труда разных людей. В качестве устойчивого темпа некоторыми предлагается 40-часовая рабочая неделя, но для других это прямая дорога скуке. Лично я большую часть лучшей своей работы проделал во взрывном режиме 55 часов в течение двух недель и затем 30 часов в течение последующих двух недель. В среднем может получиться около 40 рабочих часов в неделю, но у разных команд рабочие недели не всегда составляют 40 часов. Понимание устойчивого темпа у всех разное.

Прочие соображения


Внепроектная разработка ПО

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

Такие работы, конечно же, относятся к разработке ПО и также поддаются практическим методам Agile. Их можно проводить более эффективно, качественно, методично благодаря внедрению таких практических Agile-методов, как бережливое производство и Kanban. Но по моему опыту, компании обычно испытывают гораздо меньше проблем с работой такого характера, чем с разработкой ПО в масштабах проекта, поэтому основное внимание в этой книге уделяется работе над проектами, а не над ситуативной работой.
Рекомендации
Изучайте
Просмотрите историю итогов проектов. Соответствует ли опыт вашей компании общему мнению о том, что небольшие проекты чаще выполняются более успешно, чем крупные?
Просмотрите портфолио своих проектов. Какие из ваших крупных проектов можно поделить на несколько небольших?
Просмотрите каденции, по которым работают ваши команды. Сколько времени длятся спринты? Меньше чем три недели?
Узнайте, доставляют ли ваши команды функционал вертикальными срезами.
Узнайте, осуществляют ли ваши команды планирование на основании скорости.
Опросите свои команды о техническом долге. Как они воспринимают бремя долга и получится ли у них погасить его?
Приспосабливайтесь
Поощряйте ваши команды учитывать скорость работы при постановке целей спринта.
Разработайте план, по которому команда сможет доставлять работу вертикальными срезами, в том числе при проектировании и при уточнении бэклога владельцем продукта.
Поощряйте создание командами планов по регулированию технического долга.

Дополнительные ресурсы


[Фред Брукс, 1975]. Мифический человеко-месяц. Несмотря на то что книга не нова, она содержит классическое обсуждение трудностей, возникающих на пути к успеху при выполнении крупных проектов.
[Стив Макконнелл, 2019]. Understanding Software Projects Lecture Series. Серия Construx OnDemand. Сетевой ресурс (2019 год). ondemand.construx.com. В этих лекциях подробно обсуждается взаимосвязь размера проекта и динамики разработки ПО.
[Кеннет Рубин, 2012]. Essential Scrum: A Practical Guide to the Most Popular Agile Process. В этом всеобъемлющем руководстве по Скраму дано объяснение, как на основе единиц сложности и скорости команды планировать спринты и релизы.
[Филипп Крухтен и др., 2019]. Managing Technical Debt. Это во всех отношениях полноценное и продуманное рассуждение на тему технического долга.

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Agile

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Создаем динамические веб-сайты на PHP. 4-е межд. изд.

24.05.2021 18:21:26 | Автор: admin
image Привет, Хаброжители! Сложно найти что-то толковое про PHP? Проверенная временем, обновленная в четвертом издании, эта книга помогает начинающим разработчикам научиться всему, что необходимо для создания качественных веб-приложений.

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

Вы получите множество рекомендаций по стилю программирования и процессу разработки ПО от Кевина Татро и Питера Макинтайра. Этот материал, изложенный в доступной и компактной форме, поможет вам овладеть мастерством программирования на PHP. Общие сведения о том, какой результат можно получить, используя PHP. Основы языка, включая типы данных, переменные, операторы, управляющие команды. Функции, строки, массивы и объекты. Решение распространенных задач разработки: обработка форм, проверка данных, отслеживание сеансовых данных и cookie. Работа с реляционными базами данных (MySQL) и базами данных NoSQL (например MongoDB). Генерирование изображений, создание файлов PDF, парсинг файлов XML. Безопасность скриптов, обработка ошибок, оптимизация быстродействия и другие нетривиальные темы.

Для кого написана эта книга
PHP это плавильный котел для смешения направлений программирования. Веб-дизайнеры ценят его за доступность и удобство, а программистам нравится его гибкость, мощность, разнообразие и скорость. Обоим направлениям необходим понятный и точный справочник по языку. Если вы (веб-)программист, то эта книга написана для вас. Мы представим общую картину языка PHP, а затем изложим подробности, не отнимая у вас лишнего времени. Многочисленные примеры, практические рекомендации по программированию и советы по стилю помогут вам стать не просто программистом PHP, а хорошим программистом PHP.
Веб-дизайнеры оценят доступные и практичные рекомендации по использованию конкретных технологий: JSON, XML, сеансовых данных, генерирования PDF, работы с графикой и т. д. Описание PHP и базовые концепции программирования изложены в книге доступным языком.

Регулярные выражения


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

В PHP регулярные выражения применяются: для поиска совпадений (и извлечения информации из строк), для замены текста в соответствии с паттерном и для разбиения строк на массив меньших фрагментов. Функция preg_match() выполняет поиск регулярного выражения.

Perl давно считается эталонным языком для работы с регулярными выражениями. В PHP используется библиотека C pcre, обеспечивающая почти полную поддержку возможностей регулярных выражений Perl, которые работают с произвольными двоичными данными и позволяют безопасно выполнять поиск по паттернам или в строках, содержащих нулевой байт (\x00).

Большинство символов в регулярных выражениях являются литеральными, что отражается на поиске совпадений. Например, если вы ищете совпадение для регулярного выражения "/cow/" в строке Dave was a cowhand, то совпадение будет найдено, потому что последовательность символов cow встречается в этой строке.

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

preg_match("/^cow/", "Dave was a cowhand"); // возвращает falsepreg_match("/^cow/", "cowabunga!"); // возвращает true

Аналогичным образом символ $ в конце регулярного выражения означает, что совпадение должно завершаться в конце строки (то есть обозначает привязку регулярного выражения к концу строки).

preg_match("/cow$/", "Dave was a cowhand"); // возвращает falsepreg_match("/cow$/", "Don't have a cow"); // возвращает true

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

preg_match("/c.t/", "cat"); // возвращает truepreg_match("/c.t/", "cut"); // возвращает truepreg_match("/c.t/", "c t"); // возвращает truepreg_match("/c.t/", "bat"); // возвращает falsepreg_match("/c.t/", "ct"); // возвращает false

Чтобы обозначить совпадение для одного из этих специальных символов (метасимволов), экранируйте его с помощью обратного слеша:

preg_match("/\$5.00/", "Your bill is $5.00 exactly"); // возвращает truepreg_match("/$5.00/", "Your bill is $5.00 exactly"); // возвращает false

Регулярные выражения по умолчанию учитывают регистр символов, поэтому регулярное выражение "/cow/" не совпадет со строкой COW. Чтобы выполнить поиск совпадения символов без учета регистра, установите соответствующий флаг (показан далее в этой главе).

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

1. Набор допустимых символов, которые могут присутствовать в строке (например, алфавитные символы, цифры, конкретные знаки препинания).

2. Набор альтернатив для строки (например, com, edu, net или org).

3. Повторяющиеся последовательности в строке (например, как минимум одна, но не более пяти цифр).

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

Символьные классы

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

preg_match("/c[aeiou]t/", "I cut my hand"); // возвращает truepreg_match("/c[aeiou]t/", "This crusty cat"); // возвращает truepreg_match("/c[aeiou]t/", "What cart?"); // возвращает falsepreg_match("/c[aeiou]t/", "14ct gold"); // возвращает false

Движок регулярных выражений находит в строке символ c, после чего проверяет, является ли следующий символ гласной буквой (a, e, i, o или u). Если нет, то движок переходит к поиску следующего символа c. Если да, движок проверяет, является ли следующий символ буквой t. Если совпадение обнаружено, движок возвращает true или, в противном случае, возобновляет поиск следующего символа c.

Символьный класс можно инвертировать, поставив символ ^ в начало перечисления символов:

preg_match("/c[^aeiou]t/", "I cut my hand"); // возвращает falsepreg_match("/c[^aeiou]t/", "Reboot chthon"); // возвращает truepreg_match("/c[^aeiou]t/", "14ct gold"); // возвращает false

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

Символ (дефис) в символьных классах используется для определения диапазонов символов. Он упрощает определение таких символьных классов, как все буквы и все цифры:

preg_match("/[0-9]%/", "we are 25% complete"); // возвращает truepreg_match("/[0123456789]%/", "we are 25% complete"); // возвращает truepreg_match("/[a-z]t/", "11th"); // возвращает falsepreg_match("/[a-z]t/", "cat"); // возвращает truepreg_match("/[a-z]t/", "PIT"); // возвращает falsepreg_match("/[a-zA-Z]!/", "11!"); // возвращает falsepreg_match("/[a-zA-Z]!/", "stop!"); // возвращает true

Когда вы задаете символьный класс, некоторые специальные символы теряют свой смысл, тогда как другие, наоборот, приобретают новые роли. Так, якорный символ $ и точка теряют свои роли в символьных классах, тогда как символ ^ уже не обозначает привязку к началу строки, а инвертирует символьный класс, если является первым символом после открывающей квадратной скобки. Например, [^\]] совпадает с любым символом, кроме закрывающей квадратной скобки, тогда как [$.^] совпадает с любым из трех знаков (доллар, точка или крышка).

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

Символ | (вертикальная черта) используется для определения альтернатив в регулярных выражениях:

preg_match("/cat|dog/", "the cat rubbed my legs"); // возвращает truepreg_match("/cat|dog/", "the dog rubbed my legs"); // возвращает truepreg_match("/cat|dog/", "the rabbit rubbed my legs"); // возвращает false

Приоритет применения альтернатив может показаться странным: так, "/^cat|dog$/" выбирает один из двух вариантов "^cat" и dog$. Это означает, что совпадение будет найдено в строке, которая либо начинается с cat, либо завершается dog. Если вам нужна строка, содержащая только cat или dog, используйте регулярное выражение "/^(cat|dog)$/".

Символьные классы и альтернативы могут применяться, например, для проверки строк, которые не должны начинаться с буквы в верхнем регистре:

preg_match("/^([a-z]|[0-9])/", "The quick brown fox"); // возвращает falsepreg_match("/^([a-z]|[0-9])/", "jumped over"); // возвращает truepreg_match("/^([a-z]|[0-9])/", "10 lazy dogs"); // возвращает true

Повторяющиеся последовательности

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

Чтобы искать повторы отдельного символа, просто поставьте квантификатор за символом:

preg_match("/ca+t/", "caaaaaaat"); // возвращает truepreg_match("/ca+t/", "ct"); // возвращает falsepreg_match("/ca?t/", "caaaaaaat"); // возвращает falsepreg_match("/ca*t/", "ct"); // возвращает true

image


С квантификаторами и символьными классами можно решать такие задачи, как проверка на действительность телефонных номеров США:

preg_match("/[0-9]{3}-[0-9]{3}-[0-9]{4}/", "303-555-1212"); // возвращает truepreg_match("/[0-9]{3}-[0-9]{3}-[0-9]{4}/", "64-9-555-1234"); // возвращает false

Подпаттерны

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

preg_match("/a (very )+big dog/", "it was a very very big dog"); // возвращаетtruepreg_match("/^(cat|dog)$/", "cat"); // возвращает truepreg_match("/^(cat|dog)$/", "dog"); // возвращает true

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

preg_match("/([0-9]+)/", "You have 42 magic beans", $captured);// возвращает true и заполняет $captured

Нулевому элементу массива присваивается вся строка, в которой ведется поиск совпадений. В первом элементе хранится подстрока, совпавшая с первым подпаттерном (если совпадение обнаружено), во втором подстрока, совпавшая со вторым подпаттерном, и т. д.

Ограничители

Регулярные выражения в Perl эмулируют действия паттернов Perl, заимствуя из их синтаксиса ограничители. Чаще всего ограничителями выступают слеши (например, /паттерн/), реже любой неалфавитно-цифровой символ, кроме обратного слеша. В частности, это удобно при поиске совпадений для строк, содержащих слеши. Например, следующие вызовы эквивалентны:

preg_match("/\/usr\/local\//", "/usr/local/bin/perl"); // возвращает truepreg_match("#/usr/local/#", "/usr/local/bin/perl"); // возвращает true

Скобки круглые (), фигурные {}, квадратные [] и угловые <> тоже могут использоваться в качестве ограничителей паттернов:

preg_match("{/usr/local/}", "/usr/local/bin/perl"); // возвращает true

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

Следующие два паттерна эквивалентны, но второй читается намного проще:

'/([[:alpha:]]+)\s+\1/''/( # начать сохранение[[:alpha:]]+ # слово\s+ # пробел\1 # снова то же слово) # завершить сохранение/x'

Поведение при поиске совпадения

Точка. совпадает с любым символом, кроме символа новой строки (\n). Знак $ совпадает с концом строки или, если строка завершается символом новой строки, с позицией, непосредственно предшествующей этому символу:

preg_match("/is (.*)$/", "the key is in my pants", $captured);// $captured[1] содержит 'in my pants'

Символьные классы

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

image

image

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

[@[:digit:][:upper:]]

Однако символьный класс не может использоваться как конечная точка диапазона:
preg_match("/[A-[:lower:]]/", string);// недопустимое регулярное выражение
Символьная последовательность, которая в локальном контексте рассматривается как один символ, называется сверткой. Чтобы найти совпадение для одной из многосимвольных последовательностей в символьном классе, заключите ее в маркеры [. и .]. Например, если в локальном контексте присутствует свертка ch, следующий символьный класс будет совпадать с s, t или ch:

[st[.ch.]]

Последнее расширение символьных классов класс эквивалентности, для определения которого символы заключаются в [= и =]. Классы эквивалентности совпадают с символами, имеющими одинаковый приоритет упорядочения по правилам локального контекста. Например, локальный контекст может определять, что символы a, и имеют одинаковый приоритет упорядочения при сортировке. Чтобы найти совпадение для любого из них, используйте класс эквивалентности [=a=].

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону PHP

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Книга Эффективный Java. Тюнинг кода на Java 8, 11 и дальше. 2-е межд. издание

10.03.2021 14:15:34 | Автор: admin
image Привет, Хаброжители! Программирование и тестирование обычно принято относить к разным профессиональным сферам. Скотт Оукс признанный эксперт по языку Java уверен, что если вы хотите работать с этим языком, то обязаны понимать, как выполняется код в виртуальной машине Java, и знать, какие настройки влияют на производительность. Вы сможете разобраться в производительности приложений Java в контексте как JVM, так и платформы Java, освоите средства, функции и процессы, которые могут повысить производительность в LTS-версиях Java, и познакомитесь с новыми возможностями (такими как предварительная компиляция и экспериментальные уборщики мусора). В этой книге вы: Узнаете, как платформы и компиляторы Java влияют на производительность. Разберетесь c механизмом уборки мусора. Освоите четыре принципа получения наилучших результатов при тестировании производительности. Научитесь пользоваться JDK и другими инструментами оценки производительности. Узнаете как настройка и приемы программирования позволяют минимизировать последствия уборки мусора. Научитесь решать проблемы производительности средствами Java API. Поймете, как улучшить производительность приложений баз данных Java.

Для кого написана эта книга
Эта книга написана для специалистов по производительности и разработчиков, которые желают разобраться в различных аспектах влияния JVM и Java API на производительность. Если сейчас воскресный вечер, в понедельник ваш сайт должен принять первых посетителей, а вы хотите на скорую руку решить проблемы с производительностью эта книга не для вас.

Если у вас еще нет опыта анализа производительности и вы начинаете заниматься им в Java эта книга может вам помочь. Конечно, я постараюсь предоставить достаточно информации и контекста, чтобы начинающие специалисты могли понять, как следует применять основные настройки и принципы регулировки производительности в приложениях Java. Тем не менее системный анализ весьма обширная область. Существует ряд превосходных ресурсов, посвященных системному анализу в целом (и конечно, эти принципы применимы к Java); в этом смысле книга станет полезным приложением к этим текстам.

Однако на фундаментальном уровне, для того чтобы ваши программы Java работали действительно быстро, необходимо глубоко понимать, как работает JVM (и Java API). Существуют сотни флагов настройки Java, и настройка JVM не должна сводиться к тому, чтобы бездумно изменять эти флаги и смотреть, что из этого получится. Вместо этого я постарался подробно рассказать о том, что делают JVM и API, в надежде, что вы поймете суть происходящего, разберетесь в конкретном поведении приложения и осознаете, почему оно неэффективно работает. После этого вам останется решить простую (или относительно простую) задачу: избавиться от нежелательного (неэффективного) поведения.

У работы в области производительности Java есть один интересный аспект: по уровню подготовки разработчики часто сильно отличаются от инженеров из группы производительности или контроля качества. Я знаю разработчиков, которые помнят тысячи сигнатур малоизвестных методов, редко используемых в Java API, но понятия не имеют, что делает флаг -Xmn. И я знаю инженеров по тестированию, которые могут выжать последнюю каплю производительности установкой различных флагов уборщика мусора, но едва смогут написать программу Hello World на Java.

Производительность Java включает обе области: настройку флагов компилятора, уборщика мусора и т.д., а также оптимальное использование API. Я буду считать, что вы хорошо умеете писать программы на Java. Даже если вас в первую очередь интересуют непрограммные аспекты Java, мы проведем немало времени за обсуждением программ, включая примеры, которые предоставляют тестовые данные для примеров.

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


Алгоритмы уборки мусора



OpenJDK 12 предоставляет различные алгоритмы уборки мусора с разной степенью поддержки в более ранних версиях. В табл. 5.1 перечислены эти алгоритмы с указанием их статуса в выпусках OpenJDK и Oracle.

image


S полная поддержка; D считается устаревшим; E экспериментальная поддержка; E2 экспериментальная поддержка в сборках OpenJDK, но не в сборках Oracle.

Ниже приводятся краткие описания всех алгоритмов; в главе 6 приведена более подробная информация об их настройке.

Последовательный уборщик мусора

Последовательный уборщик мусора простейший из всех. Он используется по умолчанию, если приложение работает на машине клиентского уровня (32-разрядные JVM для Windows) или на однопроцессорной машине. Когда-то казалось, что последовательному уборщику мусора пора на свалку, но контейнеризация изменила ситуацию: с появлением одноядерных контейнеров Docker и виртуальных машин (даже с гиперпоточным ядром, которое воспринимается как два процессора) этот алгоритм снова стал актуальным.

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

Последовательный уборщик мусора включается при помощи флага -XX:+UseSerialGC (хотя обычно он используется по умолчанию в тех случаях, в которых он может использоваться). Учтите, что в отличие от многих флагов JVM последовательный уборщик мусора не отключается заменой знака + на знак (то есть с флагом -XX:-UseSerialGC). В тех системах, в которых последовательный уборщик мусора используется по умолчанию, он отключается выбором другого алгоритма уборки мусора.

Параллельный уборщик мусора

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

Параллельный уборщик мусора останавливает все потоки приложения на время малой и полной уборки мусора и полностью сжимает старое поколение во время полной уборки. Так как он используется по умолчанию во многих ситуациях, в которых уместно его использование, явно включать его не нужно. Чтобы включить его тогда, когда это потребуется, используйте флаг -XX:+UseParallelGC.

Учтите, что в старых версиях JVM параллельная уборка мусора включалась для старых и новых поколений по отдельности, поэтому иногда встречаются упоминания флага -XX:+UseParallelOldGC. Этот флаг считается устаревшим (хотя и продолжает функционировать, и его можно отключить для параллельной уборки только молодого поколения, если по какой-то причине возникнет такая необходимость).

Уборщик мусора G1

Уборщик мусора G1 использует стратегию конкурентной уборки мусора для очистки кучи с минимальными паузами. Этот уборщик используется по умолчанию в JDK 11 и более поздних версиях для 64-разрядных JVM на машинах, оснащенных двумя и более процессорами.
Уборщик мусора G1 делит кучу на области, но при этом рассматривает кучу как разделенную на два поколения. Некоторые области формируют молодое поколение, при уборке которого приостанавливаются все потоки приложения, а все живые объекты перемещаются в старое поколение или области выживших объектов (для чего используются множественные потоки).
В уборщике мусора G1 старое поколение обрабатывается фоновыми потоками, которым не нужно останавливать потоки приложения для выполнения большей части своей работы. Так как старое поколение делится на области, уборщик мусора G1 может освобождать объекты из старого поколения, копируя их из одной области в другую; это означает, что он (по крайней мере частично) сжимает кучу в ходе нормальной обработки. Это способствует предотвращению фрагментации куч G1, хотя полностью исключить ее нельзя.

За предотвращение полных циклов уборки мусора приходится расплачиваться процессорным временем: (множественные) фоновые потоки, которые уборщик мусора G1 использует для обработки старого поколения, должны располагать процессорным временем на время выполнения потоков приложения.

Уборщик мусора G1 включается при помощи флага -XX:+UseG1GC. В большинстве случаев он используется по умолчанию в JDK 11, но также сохраняет функциональность в JDK 8 особенно в поздних сборках JDK 8, содержащих многие важные исправления ошибок и улучшения производительности, которые были перенесены из более поздних выпусков. Как можно увидеть при углубленном анализе уборщика G1, в JDK 8 не поддерживается один важный аспект производительности, из-за которого данный механизм может стать непригодным для этого выпуска.

Уборщик мусора CMS

Уборщик мусора CMS стал первым конкурентным уборщиком. Как и другие алгоритмы, CMS останавливает все потоки приложений в ходе малой уборки мусора, которую он проводит в нескольких потоках.

CMS официально считается устаревшим в JDK 11 и выше, а использовать его в JDK 8 не рекомендуется. С практической точки зрения главный недостаток CMS заключается в том, что он не может сжимать кучу в ходе фоновой обработки. Если куча фрагментируется (что с большой вероятностью произойдет в какой-то момент), CMS приходится остановить все потоки приложения и сжать кучу, что противоречит самой цели конкурентного уборщика. С учетом этого обстоятельства и появлением уборщика G1 использовать CMS более не рекомендуется.
CMS включается флагом -XX:+UseConcMarkSweepGC, который по умолчанию равен false. Традиционно CMS также требовал установки флага -XX:+UseParNewGC (в противном случае уборка в молодом поколении будет выполняться одним потоком), хотя этот флаг считается устаревшим.

Экспериментальные уборщики мусора

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

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

Java предоставляет механизм, при помощи которого приложения могут инициировать принудительную уборку мусора: метод System.gc(). Вызывать этот метод почти всегда нежелательно. Вызов всегда запускает полную уборку мусора (даже если JVM работает с уборщиком G1 или CMS), поэтому потоки приложения будут остановлены на относительно длительный период времени. Вызов этого метода не сделает приложение более эффективным; он заставит уборку мусора выполниться ранее, чем она могла бы произойти, но в действительности проблема не исчезает, а всего лишь перемещается в другое место.

У каждого правила есть исключения, особенно при мониторинге производительности или хронометражных тестах. Для небольших хронометражных тестов, которые выполняют код для разогрева JVM, выполнение принудительной уборки мусора перед циклом измерений может иметь смысл. (Так поступает jmh, хотя обычно это не обязательно.) Аналогичным образом, при анализе кучи обычно стоит провести полную уборку мусора перед получением дампа. Многие способы получения дампа кучи все равно проводят полную уборку мусора, но ее также можно инициировать другими способами: выполнить команду jcmd<идентификатор_процесса> GC.run или подключиться к JVM при помощи jconsole и щелкнуть на кнопке Perform GC на панели Memory.

Другим исключением является механизм RMI (Remote Method Invocation), который вызывает System.gc() каждый час в процессе работы распределенного уборщика мусора. Периодичность вызова можно изменить, присвоив другие значения двум системным свойствам: -Dsun.rmi.dgc.server.gcInterval=N и -Dsun.rmi.dgc.client.gcInterval=N. Значения N задаются в миллисекундах, а значение по умолчанию равно 3 600 000 (один час).

Если вы выполняете сторонний код, который вызывает метод System.gc(), а для вас это нежелательно, уборку мусора можно предотвратить включением флага -XX:+DisableExplicitGC в аргументы JVM; по умолчанию этот флаг равен false. Такие приложения, как серверы Java EE, часто включают этот аргумент, для того чтобы вызовы RMI GC не мешали их работе.

Резюме

Поддерживаемые алгоритмы уборки мусора принимают разные меры для достижения своей цели минимизации воздействия уборки мусора на приложение.

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

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

Уборщик мусора G1 используется по умолчанию в JDK 11 и выше; он проводит конкурентную чистку старого поколения во время выполнения потоков приложения, теоретически избегая полной уборки мусора. Такая архитектура снижает вероятность полной уборки мусора по сравнению с CMS.

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

Выбор алгоритма уборки мусора

Выбор алгоритма уборки мусора зависит от нескольких факторов: от имеющегося оборудования, от специфики приложения, от целей приложения по производительности. В JDK 11 уборщик мусора G1 часто оказывается наилучшим вариантом; в JDK 8 выбор зависит от приложения.
Для начала будем условно считать, что алгоритм G1 является более подходящим вариантом, но у каждого правила есть свои исключения. В случае уборки мусора эти исключения связаны с объемом ресурсов процессора, необходимых приложению, относительно доступного оборудования и вычислительными ресурсами, необходимыми потокам G1 для фоновой обработки.

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

Более подробно с книгой можно ознакомиться на сайте издательства
Оглавление
Отрывок

Для Хаброжителей скидка 25% по купону Java

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Подробнее..

Как айтишнику издать свою книгу. Часть первая куда податься

31.05.2021 22:09:30 | Автор: admin

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

Книга, опыт выпуска которой и послужил источником данного материала, в статье ранее http://personeltest.ru/aways/habr.com/ru/post/512460/ набрала тысячи скачиваний и десятки благодарных отзывов.

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

Для начала: спасибо всем, кто поддержал. С тех пор книга прошла путь от бесплатного самиздата до книжных магазинов, заинтересовав крупные издательства. Забавное стечение обстоятельств и айтишное упорство привели к созданию новой дополненной версии уже от Эксмо/Бомбора.

А теперь к делу.

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

Часть 1. Куда податься с книгой.

Есть два пути: площадки самиздата и традиционные книжные издательства.

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

Плюсы и минусы первого варианта самиздата:

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

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

+ название книги, дизайн обложки на ваш вкус. Никаких сюрпризов от издательства;

+ никакой редактуры, искажающей ваш авторский текст;

+ услуги печати по требованию (print-on-demand) на основных площадках самиздата: при размещении через них в магазинах (Ozon, My-shop, Москва, Буквоед и др.) книга печатается при поступлении заказа. А значит можно продавать и печатные версии, нет перебоев с отсутствием тиражей, нет затрат автора на их подготовку и отправку в магазины или покупателям;

- денежные затраты: оплата художников/дизайнеров, верстальщиков, корректоров, печать тиражей за свой счет, а затем и реклама;

- временные затраты: поиск вышеупомянутых специалистов книжного дела и формулирования ТЗ, или выбор издательских сервисов и самостоятельная верстка в них, общение с поддержкой;

- сложность попадания в сетевые серьезные книжные офлайн-магазины;

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

Плюсы и минусы издательств*:

*(в случае наиболее традиционного сотрудничества на бесплатной основе по договору исключительной лицензии):

+ все делается издательством за их счет;

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

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

+ масштаб больше печатные тиражи (~2000-3000 экз. на старте), больше крупных магазинов;

+ солидность: сотрудничество в классическом книжном флоу вызывает вау-эффект, добавляет веса и серьезности;

+ больше каналов продвижения, специальные маркетинговые отделы;

+ как следствие проще попасть на полки книжных, в т.ч. офлайн, получить классический книжный путь.

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

- получаете, как правило, меньший процент роялти (авторских отчислений);

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

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

Площадки самиздата

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

Плюсы и минусы Ридеро:

+ меньше багов, приятнее интерфейс;

+ больше услуг. Заказать художнику свою обложку, перевод, аудиоверсию, отправку в офлайн-магазины или выкладку в аэропортах;

+ список магазинов релевантнее под IT-аудиторию (например, продажа печатной версии print-on-demand в Ozon, а не в My-shop как на ЛитРес);

+ оперативная поддержка;

- зависимость от посредничества и подсаживание на платные услуги. Например, скачать 1 раз сверстанную книгу в pdf 250 руб., fb2 еще 250 руб., для безлимита покупать подписку в 1000-1500 руб./мес. Поправить аннотацию в магазинах 2 мес. ожидания или доплата;

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

Отступление про бестселлеры в Ozon:

Однажды, зайдя на страницу своей книги в Ozon, я увидела на ней метку бестселлер. Предвкусила масштабы продаж Дарьи Донцовой. Дождавшись следующего месяца, получила статистику от Ridero 2 продажи. На вопрос в Ozon, а по какой логике книги получают метку бестселлер, получила политкорректный ответ как товары, наиболее популярные и продаваемые среди остальных. Уточнения, сколько нужно продаж и как определяются товары сравнения, остались без ответа. Так что стать бестселлером не сложно и за 1-2 книги (правда, ненадолго метка пропала через день-два), либо же, реальные продажи были чуть больше. Но к бестселлерам в Ozon стала относиться настороженнее.

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

Плюсы и минусы ЛитРес:

+ оперативная статистика без задержек в 1-2 мес. по самому ЛитРес-у, а это все же основная площадка электронных книг;

+ больший контроль за отображение книги на ЛитРес;

- сырость, на момент выбора не удалось загрузить, говорящих ошибок не было;

- свой дизайн обложки возможен только для лицевой стороны;

- только дефолтная верстка книги. Сделать на свой вкус более стильную по шрифтам и отступам (боль фронтендера!) верстку для печатной книги нельзя;

- медленнее поддержка;

- меньше привлекательных целевой айтишной аудитории каналов продажи. Например, нет Amаzon, нет продаж печатной версии на Ozon, Aliexpress;

- нет управления списком площадок для публикации книги: нельзя выбрать куда публиковать (и, вероятно, откуда удалять при желании потом), видимо кроме как во все текущие партнеры.

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

Мой путь на данном этапе

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

Изучив сайты МИФа, Эксмо/Бомборы, Альпины, Питера, ДМК-Пресса и прочих основных и не очень игроков книжного рынка, сроки рассмотрения, % одобрений, процессы, включая в том же МИФе требования дописывания глав под заказ редакторов по потребностям аудитории, прочие условия и веющее от них пренебрежительное и бесправное отношение к авторам поняла, что пока хочу сохранить свободу.

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

В то же время хотелось попасть в крупные сетевые книжные офлайн магазины вроде Читай-Город и Буквоед. Просто был такой пунктик :) Как метрика серьезности результата, качества контента и легкий вызов себе не каждое написанное в сети оказывается на полках классических книжных. И главное, как еще один сложнодоступный своим ходом канал распространения: чтобы студенты и начинающие могли зайти, увидеть и купить. Ведь главное для автора, чтобы его книги читали и использовали себе во благо как можно большее число людей.

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

С другой стороны, заранее уточнила у интересующих серьезных издательств:

  • будут ли рассматривать рукопись, ранее открыто размещенную в сети?

  • ранее опубликованную на ресурсах ЛитРес и аналогах для продажи?

  • распечатанную за счет автора малым тиражом?

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

Краткая сводка ответов:

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

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

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

Небольшая правовая ремарка

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

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

В ответ на присланную рукопись, руководитель отдела компьютерной литературы БХВ, отреагировал в ключе зачем выложили, как нам на этом теперь заработать? В целом резко и не очень дружелюбно (хотя местами по рыночному справедливо) прокомментировал присланные вводные, а затем сразу перешел к делу. Мол, хотят одну книгу выпустить, как бы им ее назвать, какие технологии вынести на обложку, что сейчас популярно во фронтенде. С лихой овцы хоть шерсти клок :) Естественно, после получения бесплатной консультации, инициативы по связи о моей книге не последовало. Интереса ради, я поинтересовалась сама позже, получив ответ о готовности сотрудничества только за деньги автора.

А еще, забегая вперед, не каждое предложение о сотрудничестве даже за счет издательства сейчас ведет к созданию бумажной версии и заветным полкам сетевых книжным. Все больше авторам рассылаются (вплоть до автоответов) письма счастья о готовности выпустить их произведение... Окрыленные признанием крупного издательства, будущие Джоан Роулинги спешат принять условия и перейти к изданию бестселлера. Однако договоры предполагают, как правило, закидывание электронной книги на ЛитРес и партнеров, что почти ничего не стоит издательству. В лучшем случае обещается аудио, а печатная если пойдут продажи электронной, что почти всегда рано никогда. Итого, вы просто дарите пассивный доход, лишая себя прав, шансов издаться на бумаге с другими серьезными игроками и большего роялти, размести вы книгу сами. Но об этом и прочих тонкостях работы с издательствами в следующих частях.

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

Продолжение в следующих частях:

Часть 2. Самиздат: сколько стоит свобода. Денежные и временные затраты на выпуск электронной и печатной книги.

Часть 3. Издательства: как попасть на полки книжных магазинов. Шансы на интерес к вам, опасные договоры и процесс выпуска книги.

Часть 4. Запись аудиоверсии книги.

Часть 5. Сколько получают авторы.

Подробнее..

Откуда берутся хорошие идеи. Конспект книги Стивена Джонсона

09.04.2021 16:11:40 | Автор: admin

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

Стивен Джонсон (Steven Johnson) известный американский ученый и писатель, автор двенадцати книг о взаимодействии науки, техники и человеческого опыта, в том числе, бестселлера Нет худа без добра: как современная массовая культура делает нас умнее.

Последние десять лет Джонсон изучает историю инноваций. Результаты его исследований и легли в основу бестселлера Откуда берутся хорошие идеи. Стивен продюсировал сериал Как мы до этого додумались о том, какая череда событий привела к важнейшим открытиям человечества. У него довольный популярный Twitter @stevenbjohnson.

Основная идея

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

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

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

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

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

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

  1. Смежные возможности

  2. Текучие сети

  3. Медленные догадки

  4. Интуитивная прозорливость

  5. Ошибка

  6. Экзаптация

  7. Платформы

1. Смежные возможности

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

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

Инкубатор ТарньеИнкубатор Тарнье

В последующие десятилетия конструкция инкубатора была усовершенствована.

Современные модели предусматривают режим кислородной терапии и массу других полезных функций. Сегодня все больницы развитых стран оснащены такими устройствами, спасающими тысячи детских жизней. В развивающихся странах ситуация гораздо сложнее в Либерии и Эфиопии умирают более 10% новорожденных. Основным препятствием является даже не высокая цена (стандартный инкубатор в американском госпитале может стоить более $40 тыс.) исследования показывают, что до 95% медицинского оборудования, пожертвованного развивающимся странам, выходит из строя в течение первых пяти лет использования. Проблема состоит в отсутствии запчастей и неспособности персонала больницы прочесть инструкцию по эксплуатации и ремонту на английском языке. Возникла необходимость в изобретении надежного и недорогого инкубатора, детали которого можно легко найти и заменить.

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

Инкубатор NeoNurture, designthatmatters.orgИнкубатор NeoNurture, designthatmatters.org

Устройство под названием NeoNurture снаружи выглядело как обычный инкубатор. Его эффективность была вдвое выше: запчасти были легко заменяемыми и доступными, а для устранения неполадок вполне достаточно было элементарных знаний по ремонту автомобиля. Нам нравится думать, что суперпродвинутый инкубатор за $40 000 прорывная инновация, но ведь такое устройство как NeoNurture куда более гениальная идея. Этот пример хорошо иллюстрирует модель смежных возможностей когда одна инновация влечет за собой следующую.

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

Влияние смежных возможностей можно проследить и в таком явлении как многократные открытия когда идея приходит в голову двум ученым одновременно. Пятна на Солнце были обнаружены в 1611 году одновременно четырьмя учеными, живущими в разных странах. Первую электрическую батарею изобрели два человека в 1745 году и в 1746 году. А Джозеф Пристли (в 1772 году) и Шееле Карл Вильгельм (в 1774 году) независимо друг от друга получили в лабораторных условиях кислород. Закон сохранения энергии был сформулирован четыре раза в конце 1840-х годов. Телефон, телеграф, паровой двигатель, радио почти все влиятельные технологические инновации изобретали неоднократно.

В начале 1920-х годов два ученых Колумбийского университета Уильям Огберн и Дороти Томас решили отследить все известные многократные открытия. Результаты этого исследования опубликованы в их труде с удивительным названием Изобретения неизбежны? (Are Inventions Inevitable?). Авторы обнаружили 148 случаев многократных инноваций, большинство из которых происходило в пределах одного десятилетия.

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

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

2. Текучие сети

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

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

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

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

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

3. Медленные догадки

Чарльз Дарвин в своей автобиографии описывает историю рождения теории естественного отбора как классический пример момента прозрения. В октябре 1838 года, спустя 15 месяцев после начала исследований, Дарвин сидит в своем кабинете и читает книгу Томаса Мальтуса о народонаселении. Труд Мальтуса наталкивает его на гениальную мысль, и в какой-то момент у него внезапно появляется идея алгоритма естественного отбора. Я понял, что наконец-то у меня появилась теория, с которой буду работать, пишет Дарвин в своей автобиографии.

Чарльз Дарвин, натуралистЧарльз Дарвин, натуралист

В начале 1970-х годов психолог и историк Говард Грубер решил вернуться к записям Дарвина и пересмотреть историю его открытия. Найденная Грубером в записях ученого история кардинально отличалась от описанной в автобиографии. Фактически уже в 1937 году у Дарвина была теория естественного отбора задолго до чтения работ Мальтуса. В его голове было множество элементов головоломки, но они не складывались в единую картину. Идея не пришла к нему в одно мгновение, она дрейфовала в сознании в течение длительного периода времени.

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

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

4. Интуитивная прозорливость

В научных открытиях, сделанных во сне, уже нет ничего мистического. Русскому ученому Д. И. Менделееву приснилась его знаменитая периодическая таблица химических элементов, а немецкий физик Фридрих Август Кекуле открыл формулу бензольного кольца после того, как ему приснилась змея, кусающая свой собственный хвост. Оказывается, в подсознании человека возможна обработка одновременно нескольких потоков информации, в точках пересечения которых может возникнуть творческая идея. Речь идет об интуитивной прозорливости (англ. serendipity) способности делать глубокие выводы или удачные открытия из ненамеренных наблюдений. Этот термин ввел английский писатель Хорас Уолпол в 1754 году, однако его активное употребление началось гораздо позже в первой половине XX века (период повышенной изобретательской активности). Яркие примеры этого явления открытие рентгеновского излучения Вильгельмом Рентгеном и взаимосвязи электричества и магнетизма Гансом Христианом Эрстедом.

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

Билл Гейтс, заядлый читатель и миллиардерБилл Гейтс, заядлый читатель и миллиардер

Известно, что Билл Гейтс и его преемник по Microsoft Рей Оззи ежегодно уходят в отпуск для чтения. В течение года они сознательно собирают стопки литературы, не связанной с ежедневной работой компании, а затем уходят на одну-две недели для глубокого погружения в чтение. Такой книжный интенсив помогает быстро переварить новые идеи и найти дополнительные возможности для построения инновационной среды внутри компании. Этот метод эффективен еще и потому, что легче вспомнить то, что вы читали вчера, чем то, что полгода назад. И хотя изначально вы не ищете конкретные идеи, но после прочтения книг вам в голову приходит именно то, что нужно.

Не каждый может позволить себе такой отпуск, как Билл Гейтс, но что мешает компаниям использовать эту концепцию в рабочем процессе? Многие организации поощряют своих сотрудников, чтобы те делали перерывы в работе для получения новой информации. Например, Google и ЗМ позволяют своим сотрудникам один день в неделю (20% рабочего времени) не заниматься текущей работой, а уделять время творчеству и разработке новых идей.

Попробуйте перенять опыт этих компаний иным способом например, создать открытую базу предложений сотрудников (в версии Web 2.0), которая позволит каждому вносить свои идеи, видеть предложения коллег, комментировать, дополнять и развивать их.

5. Ошибка

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

Александр Флеминг, создатель пенициллинаАлександр Флеминг, создатель пенициллина

В 1830-х годах один из создателей фотографии Луи Дагер несколько лет пытался получить изображение на посеребренных медных пластинах. Однажды ночью, после долгих неудачных попыток, он положил пластинку в шкаф с химическими веществами. Открыв его через несколько дней, Луи увидел на пластинке четкое изображение. Чтобы выяснить, какое вещество привело к желаемому результату, Дагер решил действовать методом исключения: ежедневно помещал в шкаф новую пластину, убирая по одному химикату. Позже выяснилось, что картинка проявлялась благодаря воздействию ртути.

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

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

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

6. Экзаптация

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

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

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

Тим Бернерс-Ли и гипертекстТим Бернерс-Ли и гипертекст

Разрабатывая язык HTML, Тим Бернерс-Ли даже не подозревал, что с его помощью пользователи в скором будущем смогут совершать покупки и обмениваться фотографиями. А разве мог упомянутый выше Фридрих Кекуле предположить, что змея из греческой мифологии поможет ему решить одну из насущных проблем органической химии определить формулу бензола?

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

7. Платформы

Удивительная история стоит за открытием системы GPS. Корни его уходят в 1950-е годы, когда СССР запустил первый искусственный спутник Земли. Американские исследователи следили за сигналом, исходящим от советского спутника, и выяснили, что благодаря эффекту Доплера при приближении спутника частота принимаемого сигнала увеличивается, а при отдалении уменьшается. Ученые пришли к выводу, что, зная точные координаты на Земле, можно определить положение и скорость спутника, а зная точное его положение, скорость и координаты объекта на Земле. Так родилась идея системы GPS, нашедшая применение только через 30 лет. Рональд Рейган объявил эту технологию доступной платформой, которую мог использовать и дорабатывать каждый гражданин. Посмотрите, что случилось с GPS за последние годы: система имеет огромную коммерческую ценность, в ее разработке приняло участие множество компаний.

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

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

Во Всемирной Паутине можно найти много ярких примеров создания инновационных платформ. Пожалуй, одной из самых прорывных является социальная сеть Twitter. Создавая в 2006 году платформу для интерактивного обмена информацией с друзьями, Джек Дорси, Эван Уильямс и Виз Стоун даже не подозревали, что Twitter станет инструментом, столь влиятельным в политике и бизнесе. Интересно, что подавляющее большинство пользователей Twitter взаимодействуют с сервисом с помощью программного обеспечения, созданного третьими лицами. Открытость платформы дала массу возможностей для стартапов.

Twitter, главная политическая платформа десятилетияTwitter, главная политическая платформа десятилетия

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

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

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


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

Подробнее..

Издательство Питер. Черная пятница 2020

27.11.2020 12:11:35 | Автор: admin
image

Привет, Хаброжители! Пришло время Черной пятницы. Подробности внутри.

image

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

Отдельные категории на сайте Бестселлеры O'Reilly, Head First O'Reilly, Manning, No Starch Press, Packt Publishing, Классика Computer Science, программирование для детей, научно-популярная серия New Science.

Книги по бизнесу, психологии, детский ассортимент.

Условия акции: 27 ноября06 декабря, скидка 40% на все бумажные книги по купону Бумажная книга, скидка 50% на все электронные книги по купону Электронная книга
Подробнее..

Летняя распродажа

21.06.2021 12:17:59 | Автор: admin
image

Привет, Хаброжители! Стартовала летняя распродажа от издательства Питер.

image


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

Отдельные категории на сайте Бестселлеры O'Reilly, Head First O'Reilly, Manning, No Starch Press, Packt Publishing, Классика Computer Science, программирование для детей, научно-популярная серия New Science.

Книги по бизнесу, психологии, детский ассортимент.

Условия акции: 21 июня27 июня, скидка 40% на все бумажные книги по купону Бумажная книга, скидка 50% на все электронные книги по купону Электронная книга
Подробнее..

Хидео Кодзима. Одинокий человек, избранный Богом

25.01.2021 14:08:49 | Автор: admin
imageПривет, Хаброжители! Мы сдали в типографию очередную новинку "Хидео Кодзима. Гены гения". Я на 70 процентов состою из фильмов так говорит про себя Хидео Кодзима, чье имя в индустрии игр знает каждый. Так что же подтолкнуло знаменитого разработчика на создание произведений, каждое из которых вызывает больше вопросов и обсуждений, чем дает ответов? Гены гения это сборник эссе Кодзимы, посвященных мемам единицам культурной информации, которые формируют личность точно так же, как биологические гены. Эти эссе проливают свет на все книги и фильмы, которые сформировали Хидео Кодзиму как личность и дали ему творческую энергию для создания шедевров геймдизайна. Единственная книга Кодзимы о Кодзиме теперь доступна на русском!

Вашему вниманию представлен отрывок одной главы из книги Одинокий человек, избранный Богом.

Одинокий человек, избранный Богом


Таксист | Режиссер Мартин Скорсезе

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

Это часть монолога таксиста Трэвиса Бикла, которого сыграл актер Роберт Де Ниро в американском фильме Таксист, снятом Мартином Скорсезе в 1976 году.

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

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

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

Я не хотел провести в этом состоянии всю жизнь. Я нашел для себя место, где мне было комфортно. В то время тема психологии человека не поднималась в обществе. Тогда никто не пытался решить проблемы посттравматического стрессового расстройства (ПТСР) и маниакальной депрессии.

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

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

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

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

В тот момент я подумал: Это кино обо мне! Картина была переполнена одиночеством. Меня охватил гнев от несправедливости и разочарования в XX веке. Тогда я был студентом, живущим в Японии. Я не был таксистом из Нью-Йорка и не наливал бренди в кукурузные хлопья. Я не приглашал девушку посмотреть порнофильм на свидании. И никогда не пытался убить кандидата в президенты. И тем не менее я четко ассоциировал себя с Трэвисом.

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

Мы видим одиночество и гнев молодого человека, бесцельно катающегося по темному городу. Иногда они изображены в невинном свете, иногда в романтическом, а иногда через жестокость. Потрясающий сценарий Пола Шредера, режиссерская работа Скорсезе, прекрасная игра Роберта Де Ниро, Харви Кейтеля, Джоди Фостер, Питера Бойла. Кроме того, это последний фильм, где Бернард Херрманн выступил в качестве композитора (вспомните изящную и красивую главную тему с альт-саксофоном Тома Скотта). Можно сказать, что Таксист это шедевр 70-х, собравший вместе невообразимое количество талантливых людей.

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

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

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

Когда я гулял в образе Трэвиса, почувствовал: что-то изменилось. Фильм не научил меня бороться с одиночеством. Это сделал Трэвис.

С тех пор прошло 30 лет. Чувство отрешенности, которое иногда валило меня с ног, теперь исчезло, как будто его и не было. Может, я переживал юношеский максимализм, характерный для подростков? Я перестал чувствовать одиночество, когда у меня самого появились дети. Я стал больше беспокоиться о настоящем и будущем моей семьи и в какой-то момент перестал быть Трэвисом. Возможно, я полностью освободился от гнетущего чувства одиночества, когда начал работать в игровой индустрии? Это в какой-то степени правда: я был слишком занят, чтобы грустить. Сейчас в мои игры играют люди, чьих имен и лиц я не знаю. Когда я осознал это, одиночество ушло из моей жизни, как будто бы с меня сняли заклятие. Теперь я скучаю по людям, и это совсем другое чувство. Я согласен с тем, что люди рождаются и умирают в одиночестве, но, пока мы живы, мы связаны с окружающим нас миром. Когда я сажусь в такси, я смотрю на шильдик с информацией о шофере. Наверное, я ищу Трэвиса, который где-то в моей душе сидит на водительском месте. Конечно, я никогда не встречал в реальном мире Трэвиса Бикла. В фильме он вытащил 14-летнюю девочку Айрис из борделя, но еще он спас меня от одиночества.

Вот почему я мечтаю однажды сесть в его такси и сказать:

Если бог создал одинокого человека, значит, он и сам был одинок.

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

Когда мы узнаем, что все чувствуют одиночество, мы перестаем быть одинокими.

Апрель 2007 года

Более подробно с книгой можно ознакомиться и оформить предзаказ по специальной цене на сайте издательства
Подробнее..

Метод Любищева и учет времени по мотивам книги Даниила Гранина Эта странная жизнь

23.11.2020 12:04:01 | Автор: admin

Каждый из нас хотя бы раз в жизни задумывался о времени, его неумолимости и быстротечности.Вроде бы вчера ты окончил школу и поступил в университет, а уже сегодня тебе 36 лет, ты женат и у тебя двое детей, а по ощущениям тапропасть времени, которая прошла, слилась в один миг. Все очень стремительноНе так давно, в наше не простое время я был на онлайн-конференции слушателем и один из спикеров, известный предприниматель и основатель крупной ИТ-фирмы с множеством филиалов по всей России, говорил о своем личном и рабочем времени. Все как у всех:времени мало, то, что есть трудно распределить между важным и важным, плюс семья, одно накладывается на другое и в результате нет ни на что времени. Конференция была онлайн, докладчик был дома, выступая в череде таких же докладчиков, доклады которых слились в одно и слушались мною фоном.Но этот харизматичный человек как-то по-домашнему все рассказывал,даже показал нам свою собаку-пекинеса (чтобы вы понимали про атмосферу доклада). Столь необычная подача материала естественно приковала к себе мое внимание, и я начал внимательно его слушать. Речь была о книге Даниила Гранина "Эта странная жизнь" и методе Любищева, который практиковал автор доклада. Докладчик честно сказал, что эта вторая его попытка использовать этот метод в своей работе и личной жизни. На самом деле не понятно на сколько его хватит (намеренно не рассказываю о сути, т.к. позже постараюсь сделать это сам). А в конце доклада был совет прочесть эту книгу

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

Про книгу "Эта странная жизнь" Даниила Гранина

Мне стало интересно, и я ее прочел. Странное ощущение от ее чтения, скажу откровенно. Как будто сел ты на лавочку в парке, а на ней уже сидит пожилой человек (Гранин). Он начинает с тобой говорить и в какой-то момент ты уже сам не понимаешь, как так получилось, что ты очень внимательно его слушаешь и ловишь каждое слово. Это совсем не похоже на книжный рассказ, больше на настоящий монолог. А рассказывает он о своем знакомом - профессоре Любищеве Александре Александровиче, который занимался наукой и добился в своей научной работе огромных результатов. Причем не только в энтомологии (раздел зоологии, изучающий насекомых), основной своей специальности, но и куче других наук: философии, зоологии, генетике, истории науки, математике. Был достаточно уважаемым в абсолютно разных кругах ученным. Когда Гранин рассказывал про профессора, у меняскладывалось впечатление, что он очень сильно переживал. Причем в самом начале я не совсем понимал причину почему, столь умудренный годами старик так переживает свой рассказ, но чем больше он говорил, тем больше становилось понятно, что он проецировал жизнь своего товарища по науке на себя. Его серьезно что-то беспокоило Любищев был примером для Гранина и Гранин, глядя на то, как организовал свою научную и личную жизнь его знакомый, как мне показалось, корил себя. Корил за то, что в отличииот своего коллеги, он не знает сколько он читает книг, как с годами меняется его работоспособность, как много он проводит времени с семьей и т.д. Это был разбор и переосмысление подхода одного умного человека к работе и жизни как жил другой выдающийся человек. Любищев был олицетворением устремленности. Например, Любищев, будучи энтомологом классифицировал блошек и, в то время как он шел на работу, ловил этих блошек на улице. Его коллекция этих блошек была больше, чем в музеях того времени. При всем при этом он не тратил на это свое рабочее время! Фи Скажет читатель. "Так что в этом выдающегося?".Мужик собирал блох, по дороге на работу. Это не достижение

На самом деле это пример того, о чем мы бы и не подумали бы никогда. Человек не тратил на коллекционирование своего РАБОЧЕГО времени, но имел сумасшедшую коллекцию.

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

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

Про Любищева и его систему

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

  1. Насколько хорошо он отработал в этот период по сравнению с прошлым периодом?

  2. Как многое из того, что он запланировал он выполнил и на сколько он продвинулся в этом?

  3. Сколькоон написал статей, рукописей, прочел книг, посетил выставок и т.д.?

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

Приведу очень хороший пример из нашей жизни.Навернякалюбой из вассталкивался с ситуацией, когда открываешь Ютубчик в обед в выходной день, начинаешь смотреть ролик, а потом еще, а потом еще Иглядь, через достаточно небольшой промежуток времени, а прошло уже часов 6 (!) При этом лично для вас время пролетело очень быстро. Любищев рассматривал время как что-то осязаемое и старался исключитьвот такие "быстрые" временные промежутки. Этого позволяет добиться как раз фиксирование времени, а фиксация порождает осознанность.

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

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

Про целесообразность

Наверное, вы, как и я задались простыми вопросами: зачем мне это надо? Писать, что-то постоянно фиксировать и не забывать это фиксировать. Гранин уверен, что это просто необходимо. Возьмем для примера руководителя проектов (РП) или тимлида, хотя тут можно взять, наверное, любогои подобрать свои вопросы.

  1. А сколько времени ты потратил за последний год на свое обучение?

  2. Сколько рабочего времени ты тратишь не на профильные задачи?

  3. И наоборот, сколько тратишь личного времени на рабочие вопросы?

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

Проблема в том, что ты этого не знаешь и вряд ли об этом даже задумывался Зачем вроде как это все тебе нужно? Я во всяком случае точно не задумывался.

А теперь возьмем твою личную жизнь.

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

  2. Есть хобби? Если оно есть, много посвятил ему времени за последний год?

  3. Как часто виделся со своими друзьями в этом году?

  4. Как известно, чтобы хорошо работать, необходим хороший отдых. А как ты отдыхал и сколько времени ушло на отдых?

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

И лично я, когда задавал себе эти вопросы - понял, что я ни черта не знаю о своем времени!

НИ-ЧЕ-ГО!

Про инструменты

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

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

Завел вот такую форму:
Форма Google FormsФорма Google Forms

В ней ввел категории (которые потом и оставил):

  1. Работа (все рабочие моменты)

  2. Простой (все что относится к отбросам времени - например, дорога на работу)

  3. Поддержка семьи (покупка в магазине, что-то домой)

  4. Семья (время, которое я провожу с женой и детьми)

  5. Еда (без комментариев)

  6. Сон (без комментариев)

  7. Обучение (курсы, чтение литературы и повышение квалификации)

  8. Спорт (тренажерка, занятия с тренером)

  9. Хобби (есть свой YouTube канал, где я занимаюсь поделками и DIY)

  10. Здоровье (врачи, посещение больниц)

  11. Яркость жизни (путешествия, какие-то яркие события и действия)

  12. Друзья (общение и встречи с друзьями)

  13. Прочее (все что не отнеслось к категориям выше)

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

Выглядит это вот так:
Ответы при заполнении формыОтветы при заполнении формыА это лист с результатами ответов в виде таблицыА это лист с результатами ответов в виде таблицы

Дальше можно строить по этой таблицы разные графики.

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

Про мобильное приложение и трудности

Я решил поискать что-то готовое на эту тему и ничего не нашел, чтобы мне понравилось и подошло под мои запросы. Решил зайти со своей стороны Компания, в которой я работаю занимается разработкой ПО. У нас есть десктопная и мобильная версию программы, которая предназначена для ИТ-компаний (складской учет, комплекты/комплектующие,учет заявок пользователей, инвентаризации, учет ремонтов и прочее). Не буду спойлерить, не об этом речь. В общем приняли решение реализовать блок учета времени по Любищевув своем ПО.

Наше мобильное приложение работает как в связке с десктопом, так и без него. Причем, когда без него это вполне самостоятельное приложение, которое может использовать любой на Android и iOS, причемабсолютно бесплатно.

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

  • Создать документ "Ежедневныйотчет".Он должен иметь возможность ввода данных и хранить как за день, так и за период и "собирать" все работы в себе.

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

  • Надо что-то придумать с переходящими датами. Я ложусь спать в 22:00, проснусь в 7:00, приложение должно разбить на два временных участка одно и то же действия с 22:00 до 23:59:59 - сон, с 00:00 до 7:00 - сон.

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

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

  • Должны быть графики и обычные отчеты причем с разной степенью детальности и с разными аналитическими разрезами.

  • Необходимы другие документы такие какЕжемесячные/Ежегодные отчеты, которые бы накапливали данные по ежедневным отчетам. Что бы можно было попытаться выбрать все за последний месяц посидеть и подумать над затратами и отчитаться перед самим собой. Этого пока нет, только в планах.

Что получилось?

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

Для тех, кому не терпится посмотреть:

Ссылка в Google Play

Ссылка в AppStore

Как выглядит мобильное приложение
Главный экран мобильного приложенияГлавный экран мобильного приложенияДобавление работ с главного экрана. Дата/время с/по устанавливаются автоматически, как и длительностьДобавление работ с главного экрана. Дата/время с/по устанавливаются автоматически, как и длительностьЕжедневные отчеты. Все работы и дела идут последовательноЕжедневные отчеты. Все работы и дела идут последовательноА вот и отчеты по учету времени. Внизу разные варианты. Вверху сам отчет с настройкамиА вот и отчеты по учету времени. Внизу разные варианты. Вверху сам отчет с настройкамиГрафикиГрафики

Выводы

По личным ощущениям блок учета рабочего времени не идеальный, но в целом, я получил то, что хотел. Можно вводить текст с описанием работы с клавиатуры, а можно надиктовать, если писать слишком долго. В этом месяце я переболел Covid-19 и по графику видно (видно ли?) проседание рабочей производительности и в каком периоде это произошло. Я руководитель проектов и даже болея вынужден кому-то помогать, с кем-то говорить, а где-то написать письмо. Поэтому на графике практически нет не рабочих периодов.

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

Из того, что сейчас можно сказать точно это интересно, даже если и не взлетит в отдаленной перспективе. Так же это весьма познавательно, когда открываешь случайный день и воспроизводишь его заново. Вдруг всплывают какие-то детали, дела, которые прошли, и ты про них "почти забыл". Не в плане что-то не сделал, а в плане каких-то мелочей, на которые не обратил внимание, а надо было бы. С удивлением понял, что рабочий день проходит хорошо, если действительно на рабочее время будет выделено в районе 5-6 часов. Обычно гораздо меньше получается. Даже элементарное попил кофе это минус 10 минут от рабочего, а в сумме таких кусочков набирается прям прилично. Об этом буду серьезно думать чуть позже. Осознавать это все весьма неожиданно.

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru