Избранное сообщение

Использование списков для ввода данных в Excel / Office / Excel

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

Ездил на экскурсию на хлебокомбинат.
Больше я хлеб не ем...
Ездил на экскурсию на мясокомбинат.
Больше я мясо не ем...
Завтра экскурсия на ликеро-водочный завод.
Я не поеду...

воскресенье, 30 апреля 2017 г.

Аквапарк в Дубай - 2 / Фото из личного архива




Смотри также:

Сравнение структур разделов GPT и MBR / Windows 10. Практика

Вы когда-нибудь задумывались о том, как загружается компьютер? Независимо от аппаратуры и операционной системы, все компьютеры при загрузке используют или традиционный метод BIOS-MBR, или более современный UEFI-GPT, реализованный в последних версиях ОС.

В этой статье мы сравним структуры разделов GPT и MBR; GPT означает GUID Partition Table, а MBR — Master Boot Record. Начнём с того, что разберём сам процесс загрузки.

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

Понимание процесса загрузки

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

Если два вида структур разделов: MBR и GPT. Структура разделов на диске определяет три вещи:
  1. Структура данных на диске.
  2. Код, который используется при загрузке, если раздел загрузочный.
  3. Где начинается и заканчивается раздел.

Процесс загрузки MBR

Вернёмся к процессу загрузки. Если в вашей системе используется структура разделов MBR, то первый процесс выполнения загрузит BIOS. Базовая структура ввода-вывода (Basic Input/Output System) включает в себя микропрограмму загрузчика. Микропрограмма загрузчика содержит низкоуровневые функции, такие как ввод с клавиатуры, доступ к видеодисплею, осуществление дисковых операций ввода-вывода и код для загрузки начальной стадии загрузчика. До того как BIOS может определить загрузочное устройство, он выполняет последовательность функций системной конфигурации, начиная со следующих:
  • Самотестирование при включении питания.
  • Обнаружение и инициализация видеокарты.
  • Отображение стартового экрана BIOS.
  • Осуществление быстрой проверки памяти (RAM).
  • Конфигурация устройств plug and play.
  • Определение загрузочного устройства.
Как только BIOS определил загрузочное устройство, он считывает первый дисковый сектор этого устройства в память. Первый сектор диска — это главная загрузочная запись (MBR) размером 512 байт. В этот размер поместились три объекта:
  • Первая стадия загрузчика (440 байт).
  • Таблица разделов диска (16 байт на раздел × 4 раздела) — MBR поддерживает только четыре раздела, подробнее об этом ниже.
  • Подписи диска (4 байта).

На этом этапе MBR сканирует таблицу разделов и загружает в оперативную память загрузочный сектор — Volume Boot Record (VBR).

VBR обычно содержит начальный загрузчик программ — Initial Program Loader (IPL), этот код инициирует процесс загрузки. Начальный загрузчик программ включает в себя вторую стадию загрузчика, который затем загружает операционную систему. На системах семейства Windows NT, таких как Windows XP, начальный загрузчик программ сначала загружает другую программу под названием NT Loader (аббревиатура NTLDR), которая затем загружает операционную систему.

Для операционных систем на ядре Linux используется загрузчик GRUB (Grand Unified Bootloader). Процесс загрузки похож на описанный выше, единственная разница в наименовании загрузчиков на первой и второй стадии.


В GRUB первая стадия загрузчика называется GRUB Stage 1. Она загружает вторую стадию, известную как GRUB Stage 2. Вторая стадия загружает получает список операционных систем на жёстких дисках и предоставляет пользователю список для выбора ОС для загрузки.

Процесс загрузки GPT

На том же этапе загрузки в структуре разделов GPT происходит следующее. GPT использует UEFI, в котором нет такой как у MBR процедуры хранения в загрузочном секторе первой стадии загрузчика с последующим вызовом второй стадии загрузчика. UEFI — унифицированный расширяемый интерфейс прошивки (Unified Extensible Firmware Interface) — является более продвинутым интерфейсом, чем BIOS. Он может анализировать файловую систему и даже сам загружать файлы.


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

Затем UEFI считывает GPT — таблицу разделов GUID. GUID расшифровывается как «глобальный уникальный идентификатор» (Globally Unique Identifier). GPT располагается в первых секторах диска, сразу после сектора 0, где по-прежнему хранится главная загрузочная запись для Legacy BIOS.

GPT определяет таблицу разделов на диске, на которой загрузчик EFI распознает системный раздел EFI. Системный раздел содержит загрузчики для всех операционных систем, установленных на других разделах жёсткого диска. Загрузчик инициализирует менеджер загрузки Windows, который затем загружает операционную систему.

Для операционных систем на ядре Linux существует версия GRUB с поддержкой EFI, которая загружает файл, такой как grub.efi, или загрузчик EFI, который загружает свой файл, такой как elilo.efi.

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

Различия между структурами разделов GPT и MBR

Если вы когда-нибудь пытались установить Windows 8 или 10 на новый компьютер, то скорее всего видели вопрос: какую структуру разделов использовать, MBR или GPT.

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

GPT — более новая и продвинутая структура разделов, и у неё много преимуществ, которые я перечислю ниже. MBR используется давно, она стабильная и обладает максимальной совместимостью. Хотя GPT со временем может вытеснить MBR, поскольку предлагает более продвинутые функции, но в некоторых случаях можно использовать только MBR.

Главная загрузочная запись

MBR — традиционная структура для управления разделами диска. Поскольку она совместима с большинством систем, то по-прежнему широко используется. Главная загрузочная запись расположена в первом секторе жёсткого диска или, проще говоря, в самом его начале. Она содержит таблицу разделов — информацию об организации логических разделов на жёстком диске.

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

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

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

Преимущества
  • Совместима с большинством систем.

Недостатки
  • Допускает только четыре раздела, с возможностью создания дополнительных подразделов на одном из основных разделов.
  • Ограничивает размер раздела двумя терабайтами.
  • Информация о разделе хранится только в одном месте — в главной загрузочной записи. Если она повреждена, то весь диск становится нечитаемым.

Таблица разделов GUID (GPT)

GPT — более новый стандарт для определения структуры разделов на диске. Для определения структуры используются глобальные уникальные идентификаторы (GUID).

Это часть стандарта UEFI, то есть систему на основе UEFI можно установить только на диск, использующий GPT, например, таково требование функции Windows 8 Secure Boot.

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

Преимущества
  • Допускает неограниченное количество разделов. Лимит устанавливает операционная система, например, Windows допускает не более 128 разделов.
  • Не ограничивает размер раздела. Он зависит от операционной системы. Ограничение на максимальный размер раздела больше, чем объём любых существующих сегодня дисков. Для дисков с секторами по 512 байт поддерживается максимальный размер 9,4 ЗБ (один зеттабайт равен 1 073 741 824 терабайт)
  • GPT хранит копию раздела и загрузочных данных и может восстановить данные в случае повреждения основного заголовка GPT.
  • GPT хранит значения контрольной суммы по алгоритму циклического избыточного кода (CRC) для проверки целостности своих данных (используется для проверки целостности данных заголовка GPT). В случае повреждения GPT может заметить проблему и попытаться восстановить повреждённые данные из другого места на диске.

Недостатки
  • Может быть несовместима со старыми системами.

GPT против MBR


  • GPT допускает неограниченное количество основных разделов, в то время как MBR допускает только четыре основных, а остальные — дополнительные.
  • GPT позволяет создавать разделы любого размера, в то время как MBR имеет ограничение в 2 ТБ.
  • GPT хранит копию данных раздела, позволяя восстановить их в случае повреждения основного заголовка GPT; MBR хранит только одну копию данных раздела в первом секторе жёсткого диска, что может привести к потере всей информации в случае повреждении информации о разделах.
  • GPT хранит значения контрольной суммы для проверки, что данные не повреждены, и может выполнить необходимое восстановление из других областей диска в случае повреждения; MBR не имеет способа узнать о повреждении данных, вы можете узнать об этом только если компьютер откажется загружаться или исчезнет раздел.

Совместимость с операционными системами

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

MBR защищает данные GPT от перезаписи.

Apple MacBook'и используют GPT по умолчанию, так что невозможно установить Mac OS X на систему MBR. Даже хотя Mac OS X может работать на диске MBR, но установка на него невозможна. Я пыталась сделать это, но безуспешно.

Большинство операционных систем на ядре Linux совместимы с GPT. При установке ОС Linux на диск в качестве загрузчика будет установлен GRUB 2.

Для операционных систем Windows загрузка из GPT возможна только на компьютерах с UEFI, работающих под 64-битными версиями Windows Vista, 7, 8, 10 и соответствующими серверными версиями. Если вы купили ноутбук с 64-битной версией Windows 8, то с большой вероятностью там GPT.

Windows 7 и более ранние системы обычно устанавливают на диски с MBR, но вы всё равно можете преобразовать разделы в GPT, как будет рассказано ниже.

Все версии Windows Vista, 7, 8, 10 могут считывать и использовать данные из разделов GPT — но они не могут загружаться с таких дисков без UEFI.

Так GPT или MBR?

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

Проверьте тип раздела жёсткого диска

На каждом жёстком диске под Windows можно проверить тип разделов с помощью «Управления дисками» (Disk Management). Для запуска «Управления дисками» сделайте следующее:

Нажмите сочетание «горячих клавиш» Windows+R, откроется окно для запуска программ.

Наберите diskmgmt.msc и нажмите клавишу Enter.

Windows просканирует жёсткие диски и вскоре покажет их. Для проверки типа разделов любого жёсткого диска нажмите правой кнопкой мыши на плашку диска в нижней части интерфейса. Нужно нажимать на «Диск 0», «Диск 1» и так далее, а не на разделы.

В появившемся контекстном меню выберите «Свойства». Откроется окно со свойствами выбранного диска.

Перейдите на вкладку «Тома» и посмотрите на значение «Стиль раздела».



Если вы предпочитаете командную строку, то можете выбрать другой вариант. Его преимущества в том, что он чуть быстрее, поскольку сразу выводит на экран диски и стили разделов.
  1. Нажмите клавишу Windows, наберите cmd.exe, удерживая Ctrl и Shift, нажмите Enter.
  2. Подтвердите UAC-сообщение о повышении привилегий в системе.
  3. Наберите diskpart и нажмите Enter.
  4. Наберите list disk и снова нажмите Enter.

В списке перечислены все диски. В колонке Gpt указан стиль раздела для каждого диска. Если видите звёздочку в колонке, то это GPT, если её нет — это MBR.

Преобразование между MBR и GPT во время установки Windows

Есть два типичных сообщения об ошибке, которые могут возникнуть при установке Windows на жёсткий диск:
  • Ошибка № 1: «Windows не может быть установлена на этот диск. Выбранный диск не имеет стиль разделов GPT».
  • Ошибка № 2: «Windows не может быть установлена на этот диск. Выбранный диск имеет стиль разделов GPT».
Когда появляется одна из этих двух ошибок, то у вас может не быть возможности выбрать раздел для установки. Но это не значит, что с компьютером что-то не то.

Как вы уже знаете, MBR и GPT — это две абсолютно разные структуры разделов жёсткого диска. MBR — это традиционная структура разделов, а GPT — более новая.

Ошибка № 1 возникает, когда вы пытаетесь установить Windows на компьютер с UEFI, а раздел жёсткого диска не сконфигурирован для режима UEFI или совместимости с Legacy BIOS. Microsoft TechNet предлагает два варианта решения проблемы.

  1. Перезагрузить компьютер в режиме совместимости с Legacy BIOS. Этот вариант позволит сохранить текущий стиль раздела.
  2. Переформатировать диск под UEFI, используя стиль раздела GPT. Этот вариант позволит вам использовать функции прошивки UEFI. Переформатирование можно сделать самостоятельно, следуя инструкциям ниже. Всегда сохраняйте резервную копию данных перед форматированием.

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

Инструкции для преобразования жёсткого диска с MBR на GPT




С помощью Windows Setup

  1. Выключите компьютер и вставьте загрузочный накопитель Windows (USB или DVD).
  2. Загрузитесь с него в режиме UEFI.
  3. Выберите «Другое» (Custom) в типе установки.
  4. Появится экран с сообщением «Куда вы хотите установить Windows?» Выберите все разделы на диске и нажмите «Удалить».
  5. После успешного удаления диск будет представлять собой единую область нераспределённого пространства.
  6. Выберите нераспределённое пространство и нажмите «Далее». Windows определит, что компьютер загружен в режиме UEFI, и автоматически переформатирует диск с применением стиля раздела GPT. Процесс установки начнётся сразу после этого.
Преобразование вручную
  1. Выключите компьютер и вставьте загрузочный накопитель Windows (USB или DVD).
  2. Загрузитесь с него в режиме UEFI.
  3. Из установки Windows нажмите Shift+F10, чтобы открыть консоль. После каждой следующей команды нажимайте Enter.
  4. Запустите инструмент diskpart командой diskpart.
  5. Чтобы выбрать диск для преобразования, наберите list disk.
  6. Укажите номер диска для преобразования: select disk #.
  7. Очистите диск: clean.
  8. Преобразование в GPT осуществляется командой convert gpt.
  9. Наберите exit для выхода из diskpart.
  10. Закройте консоль и возвращайтесь к установке Windows.
  11. При выборе типа установки выберите «Другое». Диск будет представлять собой единую область нераспределённого пространства.
  12. Выберите нераспределённое пространство и нажмите «Далее». Windows начнёт установку.

Инструкции для преобразования жёсткого диска с GPT на MBR

Иногда бывает необходимо преобразовать диск в структуру разделов MBR. Например, если во время установки Windows возникает такое сообщение об ошибке:

«Windows не может быть установлена на этот диск. Выбранный диск имеет стиль разделов GPT»

Загрузка с GPT поддерживается только в 64-битных версиях Windows Vista, 7, 8, 10 и соответствующих серверных версиях на UEFI-системах. Это сообщение об ошибке означает, что ваш компьютер не поддерживает UEFI, а поэтому вы можете использовать только BIOS, который работает со структурой разделов MBR.

Microsoft TechNet предлагает два варианта решения проблемы.

  1. Перезагрузить компьютер в режиме совместимости с BIOS. Этот вариант позволит сохранить текущий стиль раздела.
  2. Переформатировать диск, используя стиль раздела MBR. Всегда сохраняйте резервную копию данных перед форматированием. Хотя есть сторонние утилиты для преобразования дисков в GPT с сохранением данных, но всё равно безопаснее сделать резервную копию на случай, если утилита не сможет завершить преобразование.

Если вы выбрали второй вариант, то следуйте пошаговой инструкции:

С помощью Windows Setup

  1. Выключите компьютер и вставьте загрузочный накопитель Windows (USB или DVD).
  2. Загрузитесь с него в режиме UEFI.
  3. Выберите «Другое» (Custom) в типе установки.
  4. Появится экран с сообщением «Куда вы хотите установить Windows?» Выберите все разделы на диске и нажмите «Удалить».
  5. После успешного удаления диск будет представлять собой единую область нераспределённого пространства.
  6. Выберите нераспределённое пространство и нажмите «Далее». Windows определит, что компьютер загружен в режиме BIOS, и автоматически переформатирует диск с применением стиля раздела MBR. Процесс установки начнётся сразу после этого.

Преобразование вручную

  1. Выключите компьютер и вставьте загрузочный накопитель Windows (USB или DVD).
  2. Загрузитесь с него в режиме BIOS.
  3. Из установки Windows нажмите Shift+F10, чтобы открыть консоль. После каждой следующей команды нажимайте Enter.
  4. Запустите инструмент diskpart командой diskpart.
  5. Чтобы выбрать диск для преобразования, наберите list disk.
  6. Укажите номер диска для преобразования: select disk #.
  7. Очистите диск: clean.
  8. Преобразование в GPT осуществляется командой convert mbr.
  9. Наберите exit для выхода из diskpart.
  10. Закройте консоль и возвращайтесь к установке Windows.
  11. При выборе типа установки выберите «Другое». Диск будет представлять собой единую область нераспределённого пространства.
  12. Выберите нераспределённое пространство и нажмите «Далее». Windows начнёт установку.

Источники

Следующие источники содержат дополнительную информацию о стилях разделов MBR или GPT:

Учёные математически обосновали возможность создания машины времени / Изобретения, открытия, гипотезы

Физики из Университета Британской Колумбии (Канада) разработали математическую формулу, согласно которой можно построить машину времени.
Как сообщает портал ScienceAlert, эта машина может представлять собой ящик, который движется по кругу в пространстве и времени.
В таких условиях помещённый внутрь объект сможет перемещаться в прошлое или будущее.
Как отметили учёные, проблема создания такой машины кроется в отсутствии подходящих материалов.
Прежде чем приступить к строительству машины времени, людям придётся изобрести материалы, которые могут искривлять пространство и время.

Смотри также:

5 худших приемов отечественного дизайна из 90-х / Сайтостроительство

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

Прием первый, креативный: использовать весь потенциал буквы «О»

Один из «креатиФФных» приемов, который с годами стал похож на заезженный анекдот про шашечки, который рассказывает пожилой таксист. Да, колесо, торт или апельсин похожи на букву «О». Но это не такая гениальная находка, чтобы непременно ее использовать. Можно без этого:

Прием второй, типографский: выровнять надписи по ширине



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

Прием третий, акцидентный: подобрать шрифт поинтереснее



Мало кто интересуется шрифтами. Попросите назвать пять любимых шрифтов — большинство не сможет. Эта неразборчивость приводит к тому, что нас окружают нечитаемые, неподходящие и просто пошлые шрифты. Если вы не профессионал, лучше не пытаться сделать шрифт «поинтереснее»:


Прием четвертый, профессиональный: обвести



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

Прием пятый, выразительный: добавить эффекты к шрифту



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

Итог

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

И, как всегда, удачи в дизайне

Смотри также:

суббота, 29 апреля 2017 г.

Мишка купается / Забавные и милые



«Через год-два .NET Core потеснит Java на рынке enterprise решений»? — Интервью с Jon Skeet, Google

Наверняка, вы знаете, кто такой Джон Скит: №1 на Stack Overflow, автор C# in Depth, одной из лучших книг по .NET, разработчик в Google и 14-кратный MVP. Разработчиков такого масштаба не так много, хватит двух порядков, чтобы их всех перечислить. 19-20 мая Джон приедет в Петербург и выступит на DotNext 2017 Piter.

Мне удалось пообщаться с Джоном и взять у него большое интервью по поводу судьбы .NET, .NET Core, нововведений в C# 7 и общем уровне развития среднего разработчика в 2017 году.

Если говорить конкретно, то обсудили следующие вопросы:
  • Общее направление развития .NET и ошибки Microsoft;
  • Чего ждать от .NET Core в ближайшем будущем;
  • Стоит ли мигрировать на .NET Core, если у вас легаси на .NET Framework;
  • Проблемы и победы .NET на поприще кроссплатформенности;
  • Java vs .NET на рынке enterprise решений;
  • Чем хороши tuples и pattern matching в С# 7, а что стоило сделать иначе;
  • Небольшие, но приятные фичи C# 7;
  • Деградация сообщества разработчиков (и есть ли она);
  • Правильный подход к диагностике багов и постановке правильных вопросов на SO;
  • Гайд по изучению новых языков и платформ;
  • Проблемы с базовыми типами: числа, текст, дата и время;
Интервью получилось очень большое, но мне кажется, оно стоит каждой потраченной на него минуты.

О развитии .NET как платформы

— Приветствую, Джон, начнём с простых вопросов. В последнее время .NET Core и ASP.NET Core развиваются очень быстро и постоянно мняются. Вам, как разработчику, кажется, что платформа взяла верный курс?

— Я думаю, вопрос затрагивает два разных аспекта. Первый — это направление развития платформы, а второе — процесс поиска этого направления: Microsoft стали гораздо более открытыми во всём, что связано с .NET. сейчас почти все стало open source и это здорово. С другой стороны, это влечёт за собой изменения в ряде вещей: например, в процессе принятия решений. Мы будем наблюдать промежуточные шаги, вроде project.json-проектов и KVM. Во времена «старого» Майкрософт с его традиционным корпоративным путем разработки ПО подобного бы точно не произошло, и, возможно, мы сразу увидели бы инструментарий .NET в его текущем виде. Да, в сообществе была полная неразбериха, и лично мне было многое непонятно, но со временем ситуация прояснялась. На этой неделе я задал вопрос на Stack Overflow о том, что же представляет собой .NET Standard Library, и ситуация становится все лучше.

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

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

Если же говорить о направлении движения .NET, то здесь я крайне, крайне оптимистичен. Приятно видеть и активное развитие .NET как платформы, и её расширение на мобильные платформы, и то, как Xamarin ложится на всю эту историю. Все это сложно, но вдохновляет, и также наблюдается большой прогресс в языках, в инструментах. На мой взгляд, ситуация в целом прекрасна. Для меня это всё ещё и происходит в то время, когда я работаю над Google Cloud Platform в Google, стараясь сделать GCP отличным окружением для C#-разработчиков, и, конечно, .NET Core — важная часть этого.

Недавно на конференции Google Cloud Next 2017 мы с моим менеджером обсуждали возможность работы ASP.NET Core-приложений на GCP как в App Engine Flexible Environment, так и в контейнерах. И это одна из тех вещей, которые буквально несколько лет назад считались бы нелепыми. Требовалось провести работу с нашей стороны (в Google у нас есть расширение для Visual Studio, позволяющее деплоить в обе среды напрямую из VS), но также в этом не было бы смысла и без того, что Microsoft сделали с .NET Core. Честно говоря, мне кажется, что складывается выигрышная ситуация для всех.

— Я правильно понимаю, что сейчас вы занимаетесь Google Cloud Platform, которая является прямым конкурентов для MS Azure?

— Всё так, GCP конкурирует с MS Azure и Amazon AWS. Вообще, напрямую в разработку «кишков» платформы я не вовлечён. Все те крутые штуки, которые создают мои коллеги — вроде Cloud Spanner, BigQuery, Datastore или различных API машинного обучения — это великолепно, но не приносит пользы С#-разработчику, если он не может это использовать. Так что я создаю мост: у нас есть автогенерируемые библиотеки классов и некоторые новые виды кодогенераторов для упрощения всего процесса. И я добавляю туда немного рукописного кода в качестве клея или обёртки, чтобы сделать всё как можно бесшовнее и элегантнее.

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

— То есть ваша работа, фактически, сделать так, чтобы автогенерируемый код мог пройти тест Тьюринга? :)

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

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

— Всё зависит от того, где вы находитесь. Если ваш проект застрял в эпохе project.json или «я плевал на всё, я до сих пор на VS2013», то есть что наверстывать до последних релизов. Вышла VS2017, вышел .NET Core SDK, всё зарелизили, это больше не beta — и я призываю всех разобраться в том, что это значит. Да, на это нужно время, а документация всё ещё активно улучшается. Но это речь о пути, который надо проделать, чтобы нагнать текущее положение дел.

А если говорить о будущем, следующая глобальная вещь, которая нас ожидает — это .NET Standard 2.0. У нас уже были .NET Standard 1.0, 1.2, 1.3, и т.д. — это не первая попытка облегчения кроссплатформенной разработки относительно portable class libraries. Но .NET Standard 2.0 — это дивный новый мир, покрывающий гораздо больше платформ, чем мы привыкли по десктопному .NET. Будут невероятно умные инструменты, позволяющие использовать библиотеки классов, написанные только под .NET 4.5: их авторы может быть даже их уже не поддерживают, но это не помешает запустить их в .NET Standard 2.0. Кроме того, я верю, что инструментарий становится все более низкоуровневым. Главное убедитесь, что не используете WPF и WinForms, и всё будет хорошо, такую библиотеку можно использовать в контексте .NET Standard 2.0.

Нам обещают именно такой путь развития, и текущий .NET Core SDK не просто хорош, а по-настоящему хорош — огромный шаг вперед по сравнению с тем, что было раньше. И я думаю, Microsoft на этом не остановится. Поэтому, если вы не пишете пользовательские приложения (где, очевидно, UI будет важен, и от платформы будет многое зависеть), вы во многом можете полагаться на то, что .NET есть .NET, и кроссплатформить по полной. Что всё это будет означать в контексте деплоя из Xamarin для Android и iOS — пока непонятно, но мне будет очень интересно посмотреть, как все получится.

— Вы рекомендуете всем по мере возможности переходить на новые версии .NET Core как можно раньше, поскольку он уже стабилен. А что делать с древними .NET 4.0 легаси проектами?

— В таком случае нет необходимости обновляться до .NET Core. Я бы сказал, что если используешь .NET Core со старой SDK, используешь project.json, то вот тогда определённо стоит мигрировать на новый инструментарий как можно поскорее. Торопиться не надо, но в roadmap это добавить стоит.

А если у вас только унаследованное приложение, которое работает только с .NET 4… тут все зависит от конкретного случая: если вы видите у него долгосрочное будущее, то может быть смысл инвестировать время в его обновление до .NET Core есть. Если у вас TargetFramework это .NET 4.0, и вы не используете какие-нибудь сомнительные библиотеки, то, скорее всего сможете просто портировать его на .NET Core и обнаружить, что выбор сред развёртывания сильно расширился.

Скажем, у вас уже есть некоторое количество сервисов, крутящихся на Windows Server, и вы слышите много хорошего о Linux-контейнерах (я в курсе, что существуют win-контейнеры, но в случае с Linux выбор куда шире). Если вы портируете их в .NET Core (а если предположить, что у вас ASP.NET-приложение, то в ASP.NET Core, это немного другое), то выиграете от улучшений тулинга и ширины выбора платформ. Скажем, когда дело дойдёт до Continuous Integration, у вас будет куда больше доступных окружений: вы можете использовать Travis, который не поддерживается Windows: «Эй, это не проблема, я всё также могу запускать тесты на Travis в рамках моей обычной CI». Все эти вещи улучшают жизнь.

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

Кроссплатформенность .NET и конкуренция на рынке серверного enterpise

— Понятно. Есть ещё вопрос о кроссплатформенности .NET: вы действительно думаете, что поддержка многих платформ — это хорошая идея? Вы уже упомянули, что у вас огромная инфраструктура, но сможет ли .NET соперничать с Java в категории кроссплатформенного энтерпрайза и бэкенда?

— Абсолютно! Я бы сказал, что это не просто хорошая идея для .NET, это необходимая идея для .NET. Я считаю, что судьба .NET в виде Windows-only платформы с поддержкой сторонних не-очень-то-хорошо-поддерживаемых окружений, нишевых платформ, с которыми люди больше страдают, чем работают, никогда не была перспективной. Так что это была необходимая работа, которая не просто высвободила большой потенциал, но также и не позволит .NET устареть через несколько лет. Я думаю, не-кроссплатформенным серверным решениям придётся несладко. Мы видим то же с окружениями, которые раньше были Linux-only или относились к среде Windows как к «бедной родственнице»: в Windows появилась поддержка для Ruby и Python, которая с течением времени стала заметно лучше. То же самое с Git… Да даже Bash (Shell) теперь есть на Windows. Я думаю, что мультиплатформенность сейчас — это «прожиточный минимум».

— Понятно. Не могу не задать холиварный вопрос: что вы думаете про .NET в сравнении с Java? Особенно на энтерпрайз-рынке, который, насколько я понимаю, глядя на работу Microsoft над Azure и энтерпрайз-инфраструктурой, является одним из целевых для компании.

— Я бы сказал, .NET определённо может конкурировать с Java, и если быть честным, я лично всегда предпочту разрабатывать на C#. Просто потому что сам язык намного лучше.

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

Кроме того, существует инерция. Мы знаем, что в мире много энтерпрайзных Java-программистов и приложений, и я не думаю, что многие люди скажут «Давайте возьмем это работающее Java-приложение и перепишем его под .NET». Скорее будет так: «Нам по-любому переписывать приложение, поэтому надо выбрать из парочки платформ». А если вы создаете новое приложение — неважно, веб-приложение, сервис или что-то подобное, я думаю, в этом случае Java и .NET должны идти ноздря в ноздрю. Я предполагаю что энтерпрайз будет остерегаться .NET Core ещё год-два, пока он не докажет свою состоятельность, но после этого ожидаю рост использования в энтерпрайзе, и тогда преимущества C# должны дать о себе знать.

— Да, я понял, спасибо. Я не буду здесь затрагивать более developer-friendly JVM-языки, потому что мы здесь не для холивара :) Но у меня ещё один вопрос: у вас уже есть реально накопленный опыт актуального живого опыта разработки приложений или сервисов под Linux на .NET?

— Вообще я не разрабатываю приложения в чистом виде, но недавно для Google Cloud Next 2017 вместе с моим менеджером мы внедрили очень маленькое веб-приложение на ASP.NET Core, которое я потом задеплоил в контейнер в AppEngineFlexible Environment. В таком масштабе — да, опыт есть. Также сайт Noda Time построен на ASP.NET Core, сейчас он задеплоен на Windows, но я надеюсь перенести его на Linux, и я не вижу абсолютно никаких причин, почему оно не должно заработать из коробки.

И по моему опыту, .NET Core для Linux очень хорош, пока вы используете только его. Места, в которых я нашёл проблемы, были в билд-скриптах: только сегодня утром я установил VS Code на мой Linux box, и с Noda Time всё было прекрасно для netcoreapp и netstandard-версий, но при попытке собрать код для .NET 4.5.1 оно сказало: «Эй, я понятия не имею что такое .NET 4.5.1» — поэтому потребовалось включить в билд пару ссылок на референсные сборки. Итак, если вы абсолютно кроссплатформены и нацелены только на .NET Core, я думаю всё хорошо, но если у вас уже есть несколько сборок, где некоторые куски кроссплатформенны, а другие привязаны к полному .NET Framework, тогда все не так хорошо, как хотелось бы. Я уверен, MS работают над этим, и я сам бы мог исправить ситуацию установкой референсных сборок в определённых местах, но я не хочу запускать Windows-код под Linux — я просто хочу кроссплатформеннный код. И эта часть, как я уже сказал, особенно хороша.

Пара слов о С# 7

— Поговорим о С#. Версия C# 7 уже вышла и доступна в VS 2017, у нас есть классы кортежей (tuples), pattern matching и другие фичи. Что вы как девелопер думаете об этом релизе и новых фишках? Будут ли они широко использоваться? Или вы бы предпочли, чтобы язык получил какие-то другие примочки? 

— Я крайне доволен C# 7. Сейчас я пишу о нём в четвёртом издании «C# in Depth», поэтому узнаю его гораздо лучше, чем раньше. Прямо сейчас я пишу о кортежах (tuples), фиче, которая выглядит простой, но имеет много скрытых мелочей. Изначально я настороженно относился к кортежам, но теперь вижу их преимущества в реализации. В чём я сейчас не уверен, так это стал бы ли я писать публичные API и выставлять кортежи наружу. Это решение ограничивает разработчиков языка легковесным неинкапсулируемым возвратным типом. В то время как, если возвращать определённый класс, это можно было бы улучшить с течением времени.

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

Другая важная фича, которую ты упомянул — pattern matching. И самое ценное в pattern matching в С# 7 — это не паттерны, которые мы получили, а введение самой идеи паттернов. Я сознательно разделяю эти понятия. В данный момент мы можем использовать паттерны в операторе «is» и в switch cases. Единственные паттерны, которые у нас есть сейчас — это эквивалентность и совпадение типов. Так что можно или задать «case x is 5», и найдётся совпадение, если значение равно 5, или можно искать совпадение по типу: «x is String». Ранее type matching вызывал возражения, но на практике оказался реально полезным.

Я уже принял первый C# 7 пулл-реквест в Noda Time от моего друга Билла Вагнера, и этот пулл-реквест наглядно показывает преимущества pattern matching на конкретных примерах. Но на самом деле это показывает извлечённые уроки из F# и Haskell, позволяющих описать функцию через то, как она будет вести себя в разных ситуациях — это по-настоящему понятный путь описания по сравнению с if-else-if-else-if-else. Когда мы говорим «этот case соответствует такому результату, а этот такому», по сути, мы делаем то же, что и if-else, но в гораздо более простом для понимания виде. Все это выглядит многообещающе, и я надеюсь, что в каких-то промежуточных релизах, вроде C# 7.1, мы увидим больше паттернов, таких как деконструкция значений.

Представим такую ситуацию. У вас есть DateTime, вы можете деконструировать его и найти с pattern matching случаи, где год больше 2016. Вы можете сделать нечто подобное и в C# 6, но поиск соответствий не будет использовать деконструкцию. Так что pattern matching в будущем может дать ещё многое. Это самые большие фичи С# 7, и их не стоит недооценивать.

Другое большое преимущество для большинства ASP.NET Core пользователей лежит в плосткости async/await: если раньше async-метод мог вернуть только Task, Task или void, то теперь можно вернуть что угодно, совпадающее с определённым паттерном (но это не то же, что pattern matching!), если там есть атрибут, говорящий если ты не создаёшь значение данного типа, используй эту фабрику». Я не думаю, что многие люди будут применять этот паттерн в своем коде, но они могут использовать имплементацию других людей. И ValueTask — более легковесную версия Task — будут использовать почти все, это структура, которую команда ASP.NET Core оптимизировала различными способами, и она будет особенно полезна в ситуациях с низким временем отклика, когда хочется получить все преимущества async, но при этом не нагружать GC заботой о лишних Task-объектах. На мой взгляд, это интересная фича, которую многие будут использовать, не вникая в детали «как имплементировать свой собственный возвратный тип».

Если просто посмотреть на список фич, то C#, помимо крупных нововведений, получает и небольшие — штуки вроде ref-local и ref-return, довольно сложные для понимания (по крайней мере, для меня). Я полагаю, они будут весьма полезны для Unity-разработчиков высокопроизводительных игр, которые весьма чувствительны к определённым аспектам перфоманса, вроде GC и тому подобного — есть ощушение, что они используют structs больше, чем другие разработчики.

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

int x;
if (int.TryParse("some text", out x))
{

}

достаточно просто if (int.TryParse("some text", out int x)), это объявит и распарсит одновременно. Это просто устранение маленького неудобства, и оно показывает намерения проектировщиков C#: везде, где есть какой-то дискомфорт и приходится писать какой-то код, который не хочется писать, потому что он выглядит некрасиво, это исправляют. И out-переменные помогают в этом, как и числовые литералы.

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

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

— Я думаю, на этом мы закончили с вопросами по .NET, но у меня есть еще пара более общих вопросов. В данный момент вы #1 в рейтинге Stack Overflow — вы годами отвечали там на тонны вопросов. Можете ли вы сказать, эволюционируют ли разработчики или становится всё больше глупых вопросов? 

— Дело не в том, становятся ли программисты умнее или нет. Я бы сказал так: в ранние периоды вопросы на Stack Overflow были в целом качественнее, так как сайт был не так популярен. Уже давно его использование стало обычным делом, но сейчас это повсеместная практика — а это означает, что менее опытные разработчики, которые были всегда, теперь с большей вероятностью задают свои вопросы. Кроме того, множество хороших вопросов были заданы давно и остаются актуальными и по сей день, и если их задают сейчас, их по вполне понятным причинам закрывают как дубликаты. И я поймал себя на том, что я меньше отвечаю на вопросы, зато оставляю куда больше комментариев вида: «Вам следует попытаться продиагностировать проблему чуть глубже до того, как задавать вопрос, вот несколько советов, как это сделать, а пока что вопрос не очень хороший по содержанию». Я куда больше времени трачу на это, чем непосредственно отвечая на вопросы, потому что, по сути, сейчас не так много вопросов, на которые требуется ответ. Хотя в свете выхода C# 7 должны начать появляться хоршие вопросы конкретно об этой версии.

Нельзя сказать, что разработчики хуже, чем они должны быть, или что не осталось интересных вопросов. Просто баланс слегка сместился… А вто что меня действительно расстраивает: я вижу множество неопытных разработчиков (часть из которых не считает себя неопытными), демонстрирующих невнимание к другим людям. Они просто думают: «У меня есть проблема, но я не собираюсь сам искать решение, поэтому я попросту задам вопрос», — после чего идёт либо простыня кода, либо вообще никакого кода и фраза: «У меня тут проблемка, можете помочь?». Мы действительно сталкиваемся с вопросами, где нет никакой информации, кроме такой. Хотелось бы, чтобы люди прикладывали больше усилий к формулировке вопроса или учились исследовать проблему, если у них пока недостаточно навыков в диагностических техниках. Когда я учу новый язык или у меня возникает проблема, я всегда пытаюсь свести пример к необходимому минимуму. Ведь даже если люди ожидают, что я знаю ответ, это не всегда так.

Некоторое время назад я написал блог-пост о том, как запускал некоторые тесты на NUnit для Noda Time, и по каким-то причинам на Linux они работали сильно медленнее, чем на Windows. Следует заметить, что я запускал тесты с культурой en-uk, где было немного кода на NUnit, и в итоге оказалось, что он приводил к использованию String.EndsWith() на каждый assert.EndsWith() делает проверку с учётом культуры, хотя NUnit это не требовалось, в итоге это было исправлено. В итоге я обнаружил, что эта проверка и вызывала проблемы. Это было примерно так:

  1. я вижу, что это занимает очень много времени
  2. задаю себе вопрос — это мой код тормозит процесс, или какой-то другой?
  3. я нашёл один тест, который показал проблему
  4. далее я убрал столько кода, сколько мог из этого теста
  5. после этого я исключил Noda Time, написав маленький проект, запускающий NUnit вообще без логического кода
  6. после чего исключил NUnit из схемы, покопавшись в коде NUnit-код и найдя проблему «ааа, String.EndsWith(), окей, давай посмотрим, как оно выполняется»
  7. в этот момент я уже мог воспроизвести проблему с кодом 10 строк длины, запускавшим String.EndsWith() в цикле тысячи раз
  8. стало понятно, что именно этот код на Linux отрабатывал медленно, а на Windows очень быстро
  9. и предоставив всю эту информацию на SO, я смог получить ответ о том, что причина в культурной информации: она оптимизирована под Windows с UK English и не оптимизирована для Linux
  10. в итоге я смог подтвердить это путём запуска этого куска на US English, который был быстр и на Linux.

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

И я обнаружил, что многие люди не знают, как это делать, или просто не запариваются — они предпочитают задавать вопросы. Еще многие прыгают с головой в языки и платформы до того, как будут действительно готовы. Лично я пытаюсь изучать вещи по одной, зато как следует, но есть куча людей, которые говорят: «Я совершенно новенький в программировании. Сейчас я пишу приложение под Android на Java, взаимодействующее с SQLite. И этот код не работает», — окей, а это проблема Java, проблема Android или проблема SQLite? Вряд ли все три сразу. Что вы сделали, чтобы понять, что является источником проблемы? Поймите, я не докапываюсь, я пытаюсь научить людей помогать самим себе. Я твёрдо убежден, что понимание «как работает мой язык», отдельное от «как работает моя платформа» — это реальное преимущество в отношении того, как быстро вы сможете разобраться и начинать применять что-то при изучении нового.

— Что вы посоветуете начинающим программистам для относительно гладкого старта в целом или на какой бы то ни было платформах? Стоит ли мне обучаться самостоятельно, или лучше начать с фундаментального образования? На что делать в первую очередь? 

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

При изучении новой платформы или языка я всегда начинаю с небольшого консольного приложения, если там вообще есть консоль. С JavaScript сложнее, если только не учишь Node.js или что-то подобное. Для обычных языков вроде C#, Java, Ruby, Python убедитесь, что у вас есть набор инструментов, подходящий для старта. И не пытайтесь сразу сделать веб-приложение или веб-сервис — начните с маленького консольного приложения. У меня есть небольшой набор приложений, которые я пишу на старте. Одна из них — игра, которая загадывает число, а задача пользователя за 5 попыток угадать его, а она говорит, твой вариант больше правильного, меньше или правильный.

Разработка подобной программы отлично подходит в качестве первого шага овладения языком, потому что нет необходимости знать много о структурах данных, которые поддерживает платформа, о том, как работают словари и другие подобные вещи. Но ее достаточно, чтобы начать. А после этого уже можно сказать: «Окей, теперь я знаю, как выводить в консоль, как читать из консоли». Это может быть не слишком нужно для веб-приложения, но просто необходимо для диагностики: можно разбираться с кодом в отладчике, и вы скорее будете делать это в консольном приложении, чем в iOS-приложении, например. Я уверен, что под iOS отладочные инструменты тоже есть, но их гораздо сложнее понять, пока вы не погрузитесь в язык полностью.

Как я уже упоминал, этот первый шаг не затрагивает словари, списки, функции и тому подобное. Поэтому дальше начинайте писать следующее консольное приложение, которое покрывает все эти возможности, например: «создать список Strings и сделать на его основе другой список из перевёрнутых Strings» — маленькое приложение, которое делает только это. И если у вас появятся какие-либо проблемы, вы будете знать, что проблема только в понимании той конкретной темы, над которой вы сейчас работаете. Если вы хотите создать бесподобное приложение или игру, то держите это в голове. Но никогда не начинайте погружение в проект с нее. Вам нужен серьёзный фундамент, прежде чем создать что-то большое. Это всё равно что сказать «Мне хочется пробежать марафон, так что завтра, никогда раньше не бегав, я пойду и пробегу марафон». У вас не получится, это деморализует вас, и это только навредит вам — до этого нужно дорасти. Так же и с программным обеспечением.

Сложности в создании компьютерной модели реального мира


— Ого, последний пример хорош. Вот о чем я еще хотел спросить, в своем докладе для DotNext «Back to Basics» вы говорите о связи между реальной жизнью и моделями, которые мы создаём в разработке ПО: типами данных, структурами и тому подобным. Что-либо поменялось в этой области за последние пару лет? 

— Доклад посвящён трём наборам типов: как компьютеры взаимодействуют с числами, текстом, и датой/временем. В широком смысле за последние годы ничего не поменялось, легче точно не стало, возможно, даже стало слегка сложнее из-за Unicode как общемирового способа работы с текстом. Существует 65536 кодовых пунктов, некоторые из которых не назначены, и всё это называется Basic Multilingual Plane. А есть ещё другие planes, и раньше я мог говорить «можете их игнорировать, всё, что вам когда-либо понадобится, есть в BMP», так что не нужно беспокоиться о представлении не-BMP символов как пар BMP. И даже это уже неправда из-за эмодзи! 10 лет назад можно было никогда встретить символ не из BMP, а теперь большинство людей, читающих это интервью, видят как минимум один не-BMP символ в день.

Вот пример: у вас есть поле ввода, где пользователь может набрать не более 10 символов, что это значит? Даже без BMP вы можете иметь «e» с острым ударением на нём, и это может быть представлено как двумя символами, так и одним, в зависимости от нормализации. То же самое работает для emoji: в Java и .NET, если вы используете String.Length(), увидите длину два символа для каждого символа эмодзи. Значит ли это, что пользователь может ввести всего пять? Это будет странно с точки зрения пользователя: им говорят, что у них есть десять символов, но они могут ввести только пять. Так что да, эмодзи сделали жизнь сложнее.

В отношении чисел, похоже, ничего не изменилось. В отношении даты и времени с момента, когда я выступал с этим докладом впервые, кое-что поменялось на фронте .NET: Noda Time, моя собственная библиотека для работы с датами и временем. Она дошла до релиза, а сейчас я уже выпустил версию 2.0. Я бы сказал, что в случае с датой и временем всё постепенно становится лучше, всё больше людей проникаются пониманием, что проблема существует. У меня есть пара друзей, которые работают над улучшением основных типов даты и времени в JavaScript и добавлением новых, потому что мы использовали Date в JS очень долго, а оно во многих случаях работает неправильно. Поэтому они усердно работают над созданием более практичного JavaScript API для даты и времени, чем есть сейчас.

Все развивается, но базовые задачи компьютеров предполагают простые модели, а разработчики считают, что компьютер должен понимать и предметную область, и тогда возникают вопросы вроде: «я разделил 5 на 10 и получил 0, а не 0.5», — ну, стоило использовать числа с плавающей точкой или ещё что.

Вместо заключения


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

— Хорошо, я перейду от некоторых очень конкретных идей к некоторым обобщениям:

1. Определённо, попробуйте Noda Time, если вы используете где-либо в вашем коде дату и время. Если у вас есть DateTime.Now() где-то в вашей кодовой базе, то есть вероятность, что у вас есть ошибки. Поэтому я настоятельно рекомендую изучить Noda Time.

2. Если говорить в общем, мне также хочется, чтобы люди больше думали о документации. Есть проект под названием DocFX, который в некотором роде превзошёл Sandcastle, но я думаю, что мы можем сделать намного больше. Дополнительная документация с перекрёстными ссылками между разными элементами. Только представьте мир, в котором документация является достаточно машиночитаемой, чтобы, когда вы ссылаетесь на какую-либо документацию в Stack Overflow, вы просто нажимаете кнопку, начинаете вводить имя типа, и видите предварительный просмотр: «это тот тип, который вы имеете в виду?» Я думаю, жить в таком мире было бы замечательно.

3. Ещё важнее этого разнообразие людей в мире технологий. Я выступаю на многих конференциях, и аудитория, как правило, — белые мужчины, и это расстраивает меня. Нам нужно больше гендерного разнообразия, нам нужно больше расового разнообразия, просто взгляните на статистику… она расстраивает. Каждый должен участвовать в искоренении всех форм сексуального домогательства, всех форм расизма в нашей отрасли. Более того, поощрять окружающих, понимать подсознательные предубеждения и бороться за то, чтобы создать как можно более равное условия деятельности для всех.

Если отстраниться от нашей индустрии, мои личные интересы — это гендерное равенство в целом, скажем так, я уже 2,5 года начинающий феминист. Поэтому я рекомендую всем прочитать что-то вроде «Everyday sexism», чтобы посмотреть, как этот мир выглядит с точки зрения других людей. Все это довольно страшно, и это, безусловно, изменило мой взгляд на многие вещи.



Отдельно хочу поблагодарить Женю phillennium Трифонова и Андрея DreamWalker Акиньшина за помощь в подготовке поста. Плюсы вам в карму!