...

суббота, 28 ноября 2015 г.

«IT — это достаточно бедная индустрия» — интервью с Дмитрием Нестеруком из JetBrains

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

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

  • Чем технический евангелист отличается от Developer Advocate
  • Как работает евангелизм в JetBrains
  • О восприятии мира настоящими гиками
  • Почему IT — это бедная индустрия
  • Про маржу и инвестиции российских аутсорсеров
  • Про то, какие enterprise решения позорят индустрию и почему
  • Насколько далека JetBrains от своего простого потребителя
  • Об том, как индустрия видеоигр смогла «вырастить» под себя целый сектор железа
  • Что сейчас творится на рынке видеокарт
  • Что еще могут придумать компании, для того, чтобы программы работали быстрее
  • О том, как будет выживать ReSharper и о новой IDE на 64 бита

Вот видео, а под катом, как обычно, текстовая версия этого интервью.


(на одиннадцатой минуте нет звука. Знаем, чиним.)

Про технических евангелистов vs. Technology Advocate


— Дима, у меня к тебе такой вопрос – кто такой технический евангелист? Какие у него обязанности? Что он делает?

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

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

Помимо этого мы делаем некие маркетинговые материалы – в частности, скринкасты, вебинары…

— Блоги.

— Блоги, опять же, да. То есть, с одной стороны мы действительно описываем фичи наших продуктов, но у нас сейчас уклон идёт в то, чтобы делать общие технологические вещи. Если вот посмотреть на мои вебинары – например, последний – там мы не делаем такого, что «Вот, смотрите: вот наш продукт и вот наши фичи, мы сейчас вам по полочкам разложим, что там есть». То есть, такие вещи мы делаем просто скринкастами, а фичи продукта мы показываем в ходе какой-то тематической беседы. Например, давайте обсудим современный С++, какие там языковые фичи — и вот в фоне используется наш редактор, какие-то наши фичи, возможно, но мы как бы даже не упоминаем…

— В общем, понятно, что это некий трюк, эта техника называется product placement и известна ещё со времён первых фильмов о Джеймсе Бонде. То есть, 50 лет.

— Нюанс заключается в том, что пользователи, по сути, не хотят маркетинга. Многие компании не понимают, что если ты делаешь конференцию или event, полностью состоящий из маркетинга, то у людей будет какое-то отвращение. Вот мы так не делаем. Поэтому все доклады, которые я подаю на конференции – они все просто тематические. Есть конференция по С++ – я рассказываю, как делать что-то интересное на С++. А product placement – да, он есть в фоне и он никому не мешает. То есть, если я сделал что-то с, допустим, CLion, но если вы хотите использовать Eclipse, то – вперёд, никаких проблем.

Как работает евангелизм в JetBrains

— Ну понятно. Как по ощущению – евангелизм в JetBrains – он работает или не работает? Он помогает компании или нет?

Дело в том, что мы не единственные, кто занимается евангелизмом. Евангелизмом, например, занимается Microsoft и наши подходы кардинально разные, потому что у Microsoft более формальный подход – то есть, они нанимают стороннюю компанию, которая потом занимается тем, что она обзванивает потенциальных пользователей, неважно студенты это или бизнес, и спрашивает их: «Ребята, мы сделали мероприятие. У вас повысилось желание поставить Windows 10?».

Эти метрики – это KPI и эти метрики, фактически, делают бонусы евангелистам и т.д. Понятное дело, что у Microsoft в России, поскольку, в основном евангелизм, то у них команда больше и всё это систематизировано.

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

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

— То есть, фактически, это на уровне внутреннего ощущения?

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

— Это хорошо или плохо?

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

— Почему компания не хочет её расширять?

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

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

— Вот я знаю Баруха Садогурского, и он говорит, что термин «Developer Advocate» вы стырили у них. Он шутил, что ему религия не позволяет называться евангелистом и по этому поводу он Developer Advocate. А сейчас такое название вашей профессии действительно стало трендом. Барух большой молодец. В Java мире он, наверное, такой самый известный Advocate.

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

Ещё одна вещь, которую я не упомянул, которую тоже очень важно упомянуть – это походы к клиентам. То есть, мы, помимо поездок на какие-то мероприятия, мы ещё пишем – либо по потенциальным, либо по уже существующим клиентам. Мы говорим: «Ребят, хотите пообщаться? Мы придём, мы вам можем что-то рассказать, мы можем посидеть с блокнотом, записать ваши проблемы, посмотреть, как мы можем их лучше решить».

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

— Если попытаться по процентам твоего рабочего времени это всё разложить – как у тебя примерно получается? У вас же, наверное, в команде это по-разному, да?

— Слушай, на самом деле, всё очень не однородно в том смысле, что действительно есть мероприятия, на которые мы просто будем ездить каждый год практически, и то иногда мы делаем перерывы. Есть мероприятия, которые год от года поражают воображение. Допустим, ты знаешь, что там будет 20 000 человек на 3 дня и поэтому лучше не пропускать этот ивент. Поэтому в этом есть некая регулярность.

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

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

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

— Я тебе скажу больше – я обучаю сына программированию на FPGA, поэтому…

— То есть, твой сын тоже гик!

— Не знаю, в таком возрасте ещё рано говорить про гиков.

О восприятии мира настоящими Гиками

— Этот термин вообще сам по себе странный… У тебя есть ощущение, что ты воспринимаешь мир — и индустрию, и профессию, и отрасль — не так, как люди вокруг тебя в том же JetBrains, например?
— Это есть. И это, я бы сказал, было всегда, потому что я, когда только начал работать в IT-индустрии, когда я всё-таки решил не писать диссертацию, а пойти работать – я попал в очень странное место. В место, где, скажем так, мало кого интересовало вот это вот The Art of Programming.

— Это было в Петербурге?

— Да в Питере.

— Я знаю даже, что это за место – мы не будем его называть.

— Не будем. И, соответственно… Я бы не сказал, что я тогда был более гиком – просто я читал все книги, мне хотелось всё знать и, соответственно, я быстро вырос, но у меня быстро создалось впечатление, что просто никого вокруг ничто не интересует как на уровне софта, так и на уровне железа, а меня интересовало всё и сразу. То есть, соответственно, ощущение того, что IT, на самом деле, не такое гиковое, как могло было бы быть – оно до сих пор у меня есть. Потому что у нас есть некие конкретные люди, которые прямо прутся от технологии и им хочется всё знать, в том числе заниматься вещами экзотическими FPGA, XeonPhi, CUDA и т.д. Но большинству людей ничего этого не нужно. Большинству людей нужна просто зарплата в конце месяца. И всё.

— Пусть это нашим слушателям и читателям покажется снобской позицией, но в целом я с тобой соглашусь. У меня есть такое ощущение, что для многих IT — это просто способ существования такой. Это не увлечение и не хобби… Это же очень грустно. Если говорить более глобально – в мире огромное количество людей, которые занимаются тем, чем они не очень хотят на самом деле заниматься. Я вот только не знаю, насколько это именно для IT характерно или это вообще для мира?

— На самом деле, если говорить про своё неудовольствие жизнью, скажем так – я считаю, что IT ещё нормальная индустрия в этом плане. Например, у нас нет сильных физических нагрузок.

Почему IT — это бедная индустрия


— И в нашей индустрии кое-что платят, всё-таки.

— Да, кое-что платят. То есть, если посмотреть на средние заработные платы по миру для программистов – это 80 000 $, то есть, на это как-то можно жить. В России — в два с половиной раза меньше, но всё равно на это можно существовать. Поэтому естественно, что частный самолёт, наверное, нет, но для нормальной машины, квартиры, дачи – этого вполне хватает. Поэтому я никого не виню, я не говорю что плохо, когда люди идут в IT за стабильным доходом.

Другое дело, что в глобальном разрезе IT — это достаточно бедная индустрия. Как-то я был в гостях у подкаста «Разбор полетов» и честно сказал в эфире, что айтишник, то есть программист типичный – это даже не средний класс. Это рабочий класс, это некая функциональная должность, потому что сама индустрия IT по большому счету не является системообразующей. Она обслуживает другие индустрии — ритейл, банки, инвест-компании…
— Любой бизнес.
— Любой бизнес. Она обслуживает бизнес так же, как бизнес обслуживает аудит, как бизнес обслуживает бухгалтерия и все такое.

— То есть типичный кейс – это снизить издержки за счет внедрения некой автоматизации в каком-то бизнесе?

— Да.

— Меня, конечно, зацепил сейчас момент, насчет того, что мы бедная индустрия. Если сейчас какому-нибудь программисту сказать, что ИТ – это бедная индустрия, то, скорее всего, он тебя не поймет. Ты можешь раскрыть немножко эту тему?

— ИТ – бедная индустрия по той причине, например, что большинство разработчиков не могут по-хорошему позволить себе результат своего собственного труда. У нас появляются очень интересные технологии, из тех технологий, которые спасают душу индустрии, например, я бы назвал появление SSD, потому что до SSD работа с диском была просто мучительной операцией если у вас какой-то random access, а не просто линейные операции — все, смерть. Поскольку мы делаем IDE, для нас это больная тема, потому что разработчик без SSD он просто будет страдать.

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

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

— Я в свое время попал на работу в компанию Oracle. Прекрасная компания, но мне тоже дали один 19-дюймовый монитор. Но я просто взял и принес еще один свой, купил.

— Разработчики так и делают.

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

— Да. Менталитет людей он уже настроен такой, что вот, что нам дядя дал…

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

— Я видел, как люди заменяли диски на SSD.

— Или памяти доставляли.

– Сейчас, допустим, в JetBrains таких косяков нет, но если ты выйдешь за пределы JetBrains или еще нескольких хороших компаний и пойдешь по аутсорсам… Я бывал в местах достаточно ужасных. Именно не работал, а бывал. Там народ сидит в развалившемся заводе, у них у всех трубчатые мониторы…

— Когда это было?

— Это было году в 2008, может в 2010… Но понимаешь, SSD и мониторы – это верхушка айсберга. Мы говорим про SSD, мы не говорим про PCIe-based SSD-носители, мы не говорим про FusionIO-носители, мы не говорим про всякие экзотические…

— Не, ну PCIe и M2 – уже идут в индустрию.

— Если зайти сейчас в любую компанию и спросить, кто использует М2…

— Да кто хотя бы SSD использует? Я думаю, что уже на этом этапе мы закончим наше «исследование».

— А на самом деле, вещи, которыми я занимаюсь, т.е., например, использование GPU, Xeon Phi, FPGA — это вещи, которые давно существуют, ты можешь пойти на рынок и их купить. Но ИТ-индустрия, она либо делает вид, что они не релевантны, что их вообще не нужно рассматривать, либо она говорит, что это дорого. Она просто говорит, ну вот смотри, разработчику платим две тысячи долларов в месяц. А ты предлагаешь за две тысячи или за пять тысяч долларов купить какой-то девайс, который, типа, ускорит нам жизнь, но мы не очень понимаем, как он нам позволит больше зарабатывать.

Про маржу и инвестиции аутсорсеров

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

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

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

— Это один пример. Другой пример: есть компания-монополист. Ей плевать, разработка идет два года или двадцать лет. Потому что ее устройства все равно будут покупать. Соответственно, как ты думаешь, какой у нее стимул делать что-то постоянно?

— Никакого.

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

— Да, но с другой стороны тебе может начальник сказать: «слушай, вот конечно ты мне крутую штуку показал, но, блин, давай как-нибудь вы пока без нее». И это не какие-то выдуманные истории, это реальные истории. Компании, например, качественную IDE просто не хотят покупать, потому что им дорого. Хотя на самом деле, если посмотреть на ценник в разрезе тех же зарплат…

Но ты правильно сказал про маржу, маржа 30% — это, знаешь ли, хорошая маржа. Это скорее маржа аутсорсера, который работает «в черную», ему платят долларовым налом… Более реалистичная маржа для какого-нибудь крупного «белого» аутсорсера — 10-15%. И тогда инвестиции в IDE будут выедать из маржи…

— Мне кажется в России это бы никогда не работало. Потому что если тебе скажут, мол, чувак, ты бизнес сейчас будешь делать с маржой 10% — он скажет «да иди ты нафиг!». У нас инфляция выше…
— Возможно, в крупном, массовом аутсорсе 20% — это приемлемая сумма. Т.е да конечно люди хотят себе большую прибыль и сразу и это понятно.
— Я просто вообще не понимаю, может ты мне объяснишь… Мне кажется, что бизнес этот — очень сложный. Я имею в виду аутсорс, или то, что сейчас называется Service Company. Например, есть, крупная компания Luxoft. Они довольно прикольные, они научились довольно интересные вещи эффективно делать. Agile-процессы давно у них выстроены просто лучше всех…

— Иначе у них никто не закажет.

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

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

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

Про то, какие enterprise решения позорят индустрию и почему


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

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

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

Другое дело, что мы, как люди, которые заботятся об эффективности и о том, чтобы действительно что-то сделать— мы этим, толком, не занимаемся и даже порой не видим. Компания в которой я начинал работать она использовала Rational ClearCase, она использовала Rational ClearQuest, которые сейчас IBM-овскими стали. И это тихий ужас. Качество этого софта было ниже плинтуса. Оно настолько плохое, что непонятно, кто и как его писал. Продается оно за бешеные деньги, но очень плохо работает. Возникает вопрос: «а как такое вообще возможно? Кто это допустил? Как вообще это попало на рынок и как это кому-то продалось?».

— Это некомпетенция? Это какой-то коррупционный сговор?

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

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

Насколько далека JetBrains от своего простого потребителя

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

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

— Вот смотри, вот вы сидите в JetBrains, у вас по два монитора, у вас хорошие «жирные» компьютеры. А теперь представь себе человека, который сидит за слабеньким железом с одним 19-дюймовым монитором и пытается в ReSharper что-то сделать. У него «отжирается» вся память и тормозит все, что можно. У вас есть хоть что-то для него? Вы понимаете этого вашего конечного пользователя? Ведь он бесконечно далек от вас!

— Идет постоянный процесс по оптимизации. Оптимизации использования памяти, оптимизация производительности. Помимо ReSharper, у нас есть свои инструменты для профилирования. Мы пытаемся сделать все возможное. Естественно, это борьба с рантаймом, борьба с GC, и тут непонятно, что делать.

Вопрос, который ты задал, он более глобальный, в том смысле, что если бы задать вопрос так: «Почему вы не поддерживаете GPU?» Это хороший вопрос, потому что, по идее, если мы посмотрим на срез софта, который есть вообще в мире, очень мало софта поддерживает GPU. Есть Adobe и есть какие-то решения, которые используют CUDА. И тут можно было бы что-то сделать, но, опять-же, это очень нестабильный подход.

x86 — он везде. Вот ты написал свою Java- или .NET-программу… Под x86 у тебя не будет никакой векторизации, вот всего этого продвинутого…

— Это не совсем так. Скажем, в Java точно в простых случаях это все есть. Какое-нибудь сложение целых чисел в цикле — JIT-компилятор шикарно с этим справляется.

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

Отчасти, это все происходит по тем же причинам, по которым, очень тяжело, допустим, SIMD поддерживать. Потому что SIMD, то есть, большие регистры на CPU, и возможность работать с ними — они эволюционируют во времени. В старых процессорах они такие, потом они становятся больше, больше и ты не знаешь под какой стандарт писать, потому что это все не проходит. Это compatible в том смысле, что если ты скомпилировал программу под AVX, а на компьютере нет AVX – программа просто падает, потому что ты пытаешься выполнить инструкцию, которой на твоем процессоре нет.

— На самом деле, это решается в Runtime. Современный Runtime просто спрашивает процессор, мол, чувак, у тебя есть AVX или нету? JIT-компилятор этим и хорош, что он сам спросит у Runtime: «у тебя есть или у тебя нет?» и в зависимости от этого примет то или иное решение оптимизации.

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

— Как вообще в .NET обстоит дело с векторизацией?

— Ее нет. Ее сейчас делают для нового RuyJIT. Получилось довольно интересно, потому что Mono, линуксовая реализация .NET, давно уже сделали Mono.Simd — это такой Explicit API для векторизации. Конечно, это не JIT, который тебе все автоматически векторизует. Это именно Explicit штука, все нужно делать руками— оперировать векторами напрямую. Естественно, есть понимание того, что это, в принципе, надо.

— Иными словами, в Mono есть API, который заставляет Mono Runtime делать векторные операции?

— Да.

— Но это извращение, это явно не то, что нужно.

— А непонятно: мы далеко не всегда знаем, что на самом деле нужно…

— Почему я, как разработчик, должен это руками делать? Логичным будет разделить здесь ответственность. Для того, чтобы мне понять, что какое-то место в моем коде тормозит, мне надо профилировать, понять, что именно там можно развязать, и переписать это с помощью API, о котором говоришь… Но это дополнительные и трудные довольно шаги.

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

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

— Я тебе приведу такой пример. Ну, вот есть у нас SIMD, мы можем два массива из четырех чисел быстренько сложить, в регистрах получить результат. Представь, что я хочу использовать SIMD для поиска подстроки. У меня есть гигантский массив именно букв, а буква, допустим утрированно, это два байта. Автоматическая векторизация тут неприменима в принципе, потому что мне нужно брать массив одного типа, но рассматривать его как массив другого типа и использовать SIMD не просто для конструкций типа add, а использовать более сложные механизмы сравнения для того, чтобы сравнивать по четыре или по восемь символов сразу.

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

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

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

— Я такое видел в элементарных вещах, например, в простом сложении.

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

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

—Компилятор хорош, когда он может однозначно понять, что происходит. И если ты просто суммируешь циклы, то ты можешь с тем же успехом брать и делать все это на том же GPU, потому что это задачи, которые очевидно параллельны. А когда много задач, то не настолько все очевидно, система сама не поймет. Но возвращаясь к разработке, я бы сказал, что очень сложно все это как-то применять. Понимаешь, вот разбор исходного кода – это просто большое количество объектно-ориентированных структур. Они не имеют какой-то однородной формы, их нельзя просто взять, скормить на GPU. К тому же, напомню, что GPU не может просто брать текст из X86 и исполнять, оно может некое подмножество математики делать на каком-то там массиве данных. Соответственно, это подход сложный.
Другое дело, что есть много мест, где было бы неплохо получать GPU-ускорение при кодировании видео. Хотелось бы, чтобы везде все было GPU-accelerated, и последняя версия Adobe Media Encoder, часть Creative Suite, которая кодирует видео, она честно пишет, что она использует GPU и там какие-то подвижки заметны. Приятно, что хоть кто-то использует.

— Сжатие. Всем нужно ZIP.

— Да, но ситуация, на самом деле с использованием GPU достаточно плачевная все-таки. У нас просто, может, навыков нет, может, нет желания, в это влезать. У нас, как у индустрии в целом.

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


— А ты не думал о том, что это некие ограничения, которые просто legacy? У нас есть перед носом поразительный пример, когда целая индустрия спровоцировала рост целого сектора железного. Я говорю про игры и видеокарты. Это вообще уникальный случай, когда клиентский спрос так потрясающе двигал технологию.

— А ты заметил, что в свое время было ощущение того, что со звуком будет то же самое? Потому что тоже появлялись дискретные звуковые карты…

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

— Ты шел в магазин и покупал не просто звуковую карту, ты покупал звуковую карту плюс отдельный внешний усилитель, который с этой звуковой карты получал цифровые сигналы и потом на 5+1 все это раскидывал…

— И стоило это все долларов 300 минимум.

— Все это недешево, да. И было ощущение того, что это будет отдельное развитие. Но нюанс заключается в том, что люди поняли, что есть некая точка насыщения. MP3 с битрейтом 128 – это точка насыщения для большинства людей.
Соответственно вот тот пример, который я тебе привел с Доктором Дре и Beats — это хороший пример, который показывает, что возможно, людям-то и не нужно приличное качество музыки. У нас осталось ниша Hi-Fi, или Head-Fi ниша. Но она очень специфична, потому что там люди тратят гигантские суммы на усилители, наушники и так далее. Но большинство людей, если и различают как-то качество звука, им просто не нужен вот этот interference, у нас, например, есть BOSS.

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

Да, видеокарты — это уникальное решение, потому что людям захотелось играть, делать 3D… Вливание огромных денег в R&D… Знаешь, студентом и школьником я покупал эти карты за безумные какие-то деньги, и мои деньги вливались назад в R&D компании-производителя, которые потом позволили разрастись этой индустрии. И сейчас мы имеем графические карты без видеовыхода, которые используются просто для вычисления.

Что сейчас творится на рынке видеокарт


— Ни CUDA у NVidia ни APU у AMD я не могу назвать популярными решениями. Насколько масштабны вообще эти технологии? Или это все-таки удел гиков?

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

— А Intel кстати дают API для вычисления на их встроенном видеочипе?

— Не знаю ни о чем таком. Не уверен, что там работает CUDA. Хотя все же подвижки в индустрии есть. Очень интересные подвижки у Intel — они купили Altera и хотят на серверах забабахать FPGA.

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

— Да, например, индустрия игр влила деньги в GPU, финансовая индустрия влила какие-то деньги в FPGA, а FPGA, как понимаешь, штука, которая дороже в разработке раз в сто. То есть, это очень дорого для создания каких-то решений, но и на это нашелся спрос в высокочастотной торговле. Идея в том, чтобы разобрать поток TСP/IP и чего-то с ним сделать. Например, сделать табличку заказов прямо в железе.

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

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

— По разработке для FPGA — да.

— Ну сама плата может стоить не супер-дорого.

— Сама по себе она будет не дешевая, но это не безумные расходы. Безумные расходы — это суметь заставить это устройство делать то, что тебе нужно. У нас нет аналога обычного магазина для таких решений. Мы говорим: «Потребитель, слушай, есть плата. На ней есть 25 каких-нибудь FPGA. Если ты её себе поставишь, то твои игры будут еще круче». Хороший контрпример — это PhysX. А PhysX — это NVidia, и там есть мини-технология, которая привела к тому, что было время, когда люди ставили в компьютер и AMD-шную карту, которая считалась лучше для игр, и параллельно ставили карту NVidia. Windows поддерживает параллельно девайсы, а NVidia сделала подлянку — ты не можешь использовать PhysX и AMD. Но тут люди взбунтовались, и пришлось все откатить.

— Я помню, это кажется было лет 10 назад.

— Нет, может быть 5-6.

— Думаешь? То есть, это были времена второго Half-Life…

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

Но в целом, это неразрешимая проблема. Если Xeon Phi взять, то да — офигенная новейшая, но непонятно, что от него выиграет даже не обычный пользователь, а что от него получит IT-шный enterprise?

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

— Смотри, с Xeon Phi какая вещь… У тебя есть 60 или 80, в зависимости от модели, медленных ядер, которые имеют аппаратную многопоточность.

— Медленные — это уровня Pentium 4.

— Да. И они имеют 512 битный вектор, который ты, чтобы амортизировать эту карту, должен использовать. На большинстве карт, которые сейчас у людей стоят, вектор — 256 бит. Суть в том, что хотя Xeon Phi позиционируется как «считалка», но сравнения показывают, что все-таки он еще не дотягивает до Tesla. Нюанс в другом: если у тебя есть GPU, то каждое ядро твоего девайса должно делать одну и ту же задачу. У тебя есть хороший массив данных, и каждое ядро должно делать одну и ту же задачу. Если же ядра выполняют разные задачи, то ты теряешь многопоточность.

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

Смотри, у нас Intel постоянно говорит, что «у нас 80-ядерный процессор почти готов. Вот мы сейчас вам сделаем хорошо…» Они постоянно несут такую пургу. И ничего не происходит. У нас по-прежнему стандартные процессоры с 4 ядрами. Главное, они хоть что-то делают в контексте одной конкретной коробки, не выходя на уровень кластеров. И Xeon Phi, как мне кажется, — это интересное программно-аппаратное решение для интеграции. Если ты хочешь кому-то поставить сервер непрерывной интеграции или еще какой-нибудь back-end штуку и чтобы performance был нормальный — ты делаешь его на Xeon Phi и все у тебя становится хорошо. Xeon Phi помогает раскидывать задачи на все ядра и делает это одновременно, другое дело, что ядра сами по себе не такие быстрые.

— Вопрос — в стоимости этого решения.

— Да, вопрос в стоимости. Но если смотреть цены на Tesla и Xeon Phi, то они несравнимы.

— То есть соотношение доллар на единицу производительности не одинаковое?

— Конечно, Tesla все еще выигрывает.

— А Xeon Phi — это развивающаяся технология?

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

— Пятая серия? После четвертой сразу шестая идет.

— Оно, да. Оно где-то появилось в виде двухъядерных решений.

— Там есть пара процессоров буквально.

— Это очень хорошо показывает, что происходит в индустрии. Был провал с течение года, когда кто-то профукал целое поколение процессоров. Ни AMD ничего не сделала, ни индустрия не взбунтовалась. У всех все прекрасно.

— Проблема проста: лет 5 назад была анонсирована стратегия «Тик-Так». И в прошлом году Intel просто перестал в неё успевать, у них цикл разработки потихоньку растет, и они просто не уложились в двухлетний цикл.

— У меня такое впечатление, что Intel уже все равно. Вот они пропустили год — и их никто на рынке не накажет! Они де-факто монополисты. Мне в этот год нужен был комп, и у меня не было выбора — я покупаю Haswell, потому что я заложник этой истории. Я иду в магазин и все.

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

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

Что еще могут придумать компании, для того, чтобы программы работали быстрее


— Может быть, мы просто зажрались? Привыкли к этому? Мы ничего не делаем, а наши программы начинают работать быстрее?

— Этот free lunch давно кончился. Идея того, что не нужно оптимизировать для multicore потому что мы подождем, и выйдут новые процессоры, давно закончилось, и появилась новая эпоха многоядерности.

— Все говорили, что free lunch is over, все это стали понимать довольно давно, в классе серверных решений multicore давно существовал. Вышел в 2004-2005 году первый AMD двухъядерный, тогда они были законодателем моды. Вроде как все начали говорить: «Давайте освоим многопоточность». И такое ощущение, что к сегодняшнему дню более-менее научились.

— Научились. Но мы еще не получаем такого гигантского бенефита, потому что, если стандарт у нас все еще 4 ядра, то лучшее, что мы получим это ускорение в 3-4 раза.

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

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

— В серверный — можешь.

— Да, в серверный можно воткнуть еще второй процессор, но у нас нет такого линейного масштабирования. Соответственно, если ты хочешь в контексте одной машины наращивать мощность, ты будешь использовать Xeon Phi, потому что это твой единственный шаг — втыкать компьютер в компьютер.
Я бы еще отметил тот факт, что люди более-менее поняли, что нельзя наращивать требования к железу до бесконечности. Посмотри на игры. Было время, когда новая игра требовала новое железо. Сейчас уже не так: сейчас ты можешь играть в последний StarCraft на железе пятилетней давности.

— HD появилось, наконец-то высокое качество.

— Было время, когда новый софт выжирал у тебя по экспоненте ресурсы. Сейчас такого меньше происходит. Сейчас есть решения вроде Visual Studio, которые еще пытаются отжирать гигагерцы и гигабайты. Но Visual Studio тоже успокоилась, она поняла, что нельзя отъедать у людей ресурсы бесконечно. Слава богу, Visual Studio — 32-битный процесс, она лимитирована в этом плане.

О том, как будет выживать ReSharper и о Visual Studio 64 bit


— Как ReSharper будет в этой ральности выживать? Ведь клиентские проекты становятся все сложнее, а 32 бита – это, в том числе, ограничение по памяти. Что делать? Out-of-Process?

— Это по сути дела единственный вариант. Ты больше ничего не сможешь сделать.

— А у Microsoft нет в планах переписать студию на 64 бита?

— У них есть Visual Studio Code, типа мы сейчас с чистого листа начнем писать новую IDE и посмотрим, что там будет.

— И она 64 бита сразу?

— Вроде да. Было бы странно, если бы она не была 64 bit, потому что, это был бы выстрел себе в ногу. Проблема заключается в том, что с крупными компаниями типа Microsoft или Intel мы никогда не знаем, какие у них планы, не знаем, куда они хотят двигаться.

Вот есть Visual Studio Code. Хотим ли мы делать ReSharper для него? Непонятно, потому что Visual Studio Code – это отдельная тема, ее стратегия непонятна, и самое главное, ладно бы ее кто-то знал в Microsoft. Но создается ощущение, что даже в Microsoft порой продукты выпускаются инерционно, а не в каком-то понятном ключе.Сейчас вот они решили показать миру, какие они опенсорсные, какие кросплатформенные.

— Я думаю, что это бизнес-решение. Они же видят, что все ушло в Андроид, iOS и они, просто не сделав этого, рынок проиграют.

— Парадокс в том, что эти действия и те анонсы, которые были на недавнем Connect — непонятна сама их стратегия. У них же есть своя мобильная операционная система Windows Phone, у которой микроскопически маленький рынок, и они могли бы продолжать его развивать, но они еще лезут в эту тему с Андроидом и iOS. Но лезут или не лезут пока не понятно: то у них что-то выходит, то все задерживают. Такое ощущение, что у Microsoft нет какой-то направленной стратегии. У них каждый отдел что-то свое пилит, но иногда это вещи, о которых нам извне не дают никакой информации, куда там все идет.

Мы, как их клиенты, не можем адаптироваться в свою очередь. Мы не можем сказать, что мы завтра портируем ReSharper на Visual Studio Сode, потому что мы уверены, что Visual Studio Code будет офигенным решением. Visual Studio Сode могут убить так же, как и Silverlight.

— То есть для вас это огромные риски и вы ничего не можете с этим сделать? Каждый раз это такая игра: инвестировать или не инвестировать?

— Мы зависимы от Microsoft. У нас были такие кейсы, что Microsoft в последние минуты делает что-нибудь такое, что у нас в ReSharper код просто становится красным, и это анонсируется за день до релиза. Мы уже не успеваем вписаться. С этим ничего не сделать, потому что у Microsoft свои цели, которыми они не особо готовы делиться с партнерами.

— Но есть же очевидные сдвиги, например, другая модель анонсов Visual Studio. Если вы раньше работали как партнер, получали приватные билды, то сейчас билды публичные, и вы все как члены коммьюнити можете взять. Значит все-таки есть некое движение навстречу?

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

У нас пока .NET развивается в плане поддержки Mac OS и Linux. Вопрос в том, допилят ли они его? Потому что нет никакой гарантии, что они его дотянут до того состояния, когда можно какой-нибудь back-end перенести на Linux, чтобы он там работал идентично и с тем же перфомансом. Если это возможно, то это прекрасно, но тут у меня вопрос такой: «А где в этом деньги для Microsoft?». Уже нет своего Linux, чтобы на нем гнать .NET. На чем они деньги сделают?

— Cloud, мне кажется. Про это все говорят.

— Сейчас история такая, что ты скачиваешь Visual Studio Code для того, чтобы писать на нем под ASP.NET и в конце тебе захочется все это захостить в Windows Azure. Да, хорошая интересная история. Но я напомню, что сейчас ASP.NET не в первых рядах хотелок у тех, кто пишет Web.

Вопрос в том, что Microsoft мы все равно воспринимаем, как некий бизнес, который делает деньги точно так же, как JetBrains и другие компании. По крайней мере, в контексте JetBrains понятно: «Мы делаем хорошо разработчикам, получаем за это деньги». История на этом закончилась, она очень прямолинейная.

У Microsoft все немного не так, потому что у них все базируется на том, вы, юзеры, хотите операционку, чтобы на этой операционке что-то гнать. Последние телодвижения, в том числе Windows 10, они непонятные. Я на одном из компьютеров проапгрейдился до Windows 10 и я очень недоволен тем, как User Experience деградировал. Ты раньше писал название программы, оно тебе находило, сейчас почему-то не находит.
Это все странные подвижки. Есть впечатление, что Microsoft не монолитен, в отличие от Apple. В Apple еще ощущается единая стратегия, а в Microsoft несколько отделов, которые делают каждый свое. И потом что-то получится, что-то просочится наружу. Платформа .NET и язык C# – это основной успех. C# — это ИМХО лучший язык общего назначения.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Как создать круглую Progress Button

Урок по реализации круглой кнопки загрузки (далее progress button) by Colin Garven. Будем использовать, описанную by Jake Archibald, технику анимации SVG линий для того, чтобы анимировать progress button и показать пользователю состояния «success and fail».

image
Сегодня мы покажем вам как создать изящную progress button. Это уникальный концепт submit button, предложенный by Colin Garven. Сперва взгляните на это (Demo ), постарайтесь придумать, как реализовать, и просто наслаждайтесь анимацией. Идея состоит в следующем: при первом клике submit button трансформируется в круг, который покажет анимацию загрузки, используя свои границы (далее бордер). Когда анимация закончится, кнопка вернет исходную форму и покажет отметку, указывающую, что подтверждение прошло успешно или нет.

Существует несколько способов реализовать кнопку с таким эффектом. Думая о реализации только посредствам CSS, самой тяжёлой частью кажется круг прогресса. Существует техника реализации с помощью свойства clip. Anders Ingemann написал отличный полный tutorial (на LESS). Но мы будем использовать технику, основанную на SVG, CSS transitions и немного JS. Что касается круга прогресса, отметок success /fail, мы воспользуемся техникой рисования SVG линий, описанную by Jake Archibald.

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

Поехали!

The Master plan


Если вы внимательно изучили Colin’s Dribbble shot, то должны были заметить, что нам следует позаботиться о нескольких состояниях кнопки. Интересная часть – переход между двумя такими состояниями. Сперва мы должны показать простую кнопку с прозрачным фоном и цветным бордером. При наведении мышки кнопка заполняется цветом бордера, а текст становится белым.

image

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

image

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

image

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

image

Давайте создадим нашу разметку со всеми необходимыми элементами.

Разметка


Для разметки нам потребуется главный контейнер, кнопка со спаном(span), содержащим текст, и три SVG:
<!-- progress button -->
<div id="progress-button" class="progress-button">
        <!-- button with text -->
        <button><span>Submit</span></button>

        <!-- svg circle for progress indication -->
        <svg class="progress-circle" width="70" height="70">
                <path d="m35,2.5c17.955803,0 32.5,14.544199 32.5,32.5c0,17.955803 -14.544197,32.5 -32.5,32.5c-17.955803,0 -32.5,-14.544197 -32.5,-32.5c0,-17.955801 14.544197,-32.5 32.5,-32.5z"/>
        </svg>

        <!-- checkmark to show on success -->
        <svg class="checkmark" width="70" height="70">
                <path d="m31.5,46.5l15.3,-23.2"/>
                <path d="m31.5,46.5l-8.5,-7.1"/>
        </svg>

        <!-- cross to show on error -->
        <svg class="cross" width="70" height="70">
                <path d="m35,35l-9.3,-9.3"/>
                <path d="m35,35l9.3,9.3"/>
                <path d="m35,35l-9.3,9.3"/>
                <path d="m35,35l9.3,-9.3"/>
        </svg>

</div><!-- /progress-button -->


Используем Method Draw, ведь проще всего воспользоваться онлайн SVG генератором, чтобы нарисовать галочку и крестик для кнопки. Размеры всех SVG будут 70х70, так как высота нашей кнопки 70рх. Если мы хотим круг с бордером толщиной в 5 единиц нам нужно установить правильный радиус, когда будим рисовать его в графическом редакторе, да так чтобы весь круг с его бордером имел высоту 70рх. Заметьте, что в SVG обводка рисуется симметрично границе объекта. К примеру, обводка толщиной в 2рх увеличит круг радиусом в 10рх к реальным толщине и высоте 20+2 вместо 20+4(ширина бордера дважды), то есть формула 2*r+border. Для нашего случая мы знаем 2*r+5=70, от сюда наш круг должен иметь радиус в 32,5рх. Таким образом выходит: />.

К сожалению, мы не можем использовать только эти базовые размеры, потому что дефолтные параметры вставки у каждого браузера свои и мы не можем контролировать, где «анимация загрузки начнётся». Таким образом, нам придётся конвертировать эту форму в path и использовать его. Вы можете легко осуществить это в Method Draw under Object > Convert to Path.

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

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

CSS


Сперва необходимо стилизовать контейнер для кнопки:
.progress-button {
        position: relative;
        display: inline-block;
        text-align: center;
}


Укажем нашей кнопке цвета и шрифты. Что бы она соответствовала концепту, установим правильный бордер и шрифт Montserrat:
.progress-button button {
        display: block;
        margin: 0 auto;
        padding: 0;
        width: 250px;
        height: 70px;
        border: 2px solid #1ECD97;
        border-radius: 40px;
        background: transparent;
        color: #1ECD97;
        letter-spacing: 1px;
        font-size: 18px;
        font-family: 'Montserrat', sans-serif;
        -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s, border-width 0.3s, border-color 0.3s;
        transition: background-color 0.3s, color 0.3s, width 0.3s, border-width 0.3s, border-color 0.3s;
}


Также ставим transition для всех свойств, которые будут анимироваться (background-color, width etc.).

При наведении курсора мыши меняем цвет фона и цвет текста:

.progress-button button:hover {
        background-color: #1ECD97;
        color: #fff;
}


Уберем все обводки (outline):
.progress-button button:focus {
        outline: none;
}


Все SVG должны быть находиться по центру, все pointer-events отключены:
.progress-button svg {
        position: absolute;
        top: 0;
        left: 50%;
        -webkit-transform: translateX(-50%);
        transform: translateX(-50%);
        pointer-events: none;
}


Формы не должны иметь цвета заливки, так как мы хотим играть только с обводкой. Мы не показываем элементы ни в каких состояниях кнопки, кроме нужного, так что давайте спрячем их, сделав прозрачными:
.progress-button svg path {
        opacity: 0;
        fill: none;
}


Наш загрузочный круг будет создан установкой stroke-width в 5 единиц:
.progress-button svg.progress-circle path {
        stroke: #1ECD97;
        stroke-width: 5;
}


Success/fail индикаторы будут иметь обводку тоньше, и она должна быть белой. Свойству stroke-linecap установим значение round, так они будут красивее. У них установим быстрое изменение прозрачности:
.progress-button svg.checkmark path,
.progress-button svg.cross path {
        stroke: #fff;
        stroke-linecap: round;
        stroke-width: 4;
        -webkit-transition: opacity 0.1s;
        transition: opacity 0.1s;
}


Теперь давайте подрезюмируем и вспомним наш master plan. Нам необходимо было иметь возможность стилизовать три добавленных состояния (помимо дефолтного) кнопки и специальных элементов. Будем использовать классы “loading”, “success” и “error” для их индикации.

Кнопка станет круглой и будет выглядеть в точности как загрузочный круг SVG, когда мы начнем процесс загрузки:

.loading.progress-button button {
        width: 70px; /* make a circle */
        border-width: 5px;
        border-color: #ddd;
        background-color: transparent;
        color: #fff;
}


Помним, что мы уже установили transition, когда задавали стили для кнопки. Текст должен быстро исчезнуть, когда начнется анимация загрузки,…
.loading.progress-button span {
        -webkit-transition: opacity 0.15s;
        transition: opacity 0.15s;
}


… путем установки нулевого значения для прозрачности:
.loading.progress-button span,
.success.progress-button span,
.error.progress-button span {
        opacity: 0; /* keep it hidden in all states */
}


При смене состояний с loading на success/error нам не нужен transition, просто оставим текст скрытым.

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

/* Transition for when returning to default state */
.progress-button button span {
        -webkit-transition: opacity 0.3s 0.1s;
        transition: opacity 0.3s 0.1s;
}


При достижении последнего состояния необходимо переопределить transition, так как нам не надо анимировать цвет бордера или широту кнопки:
.success.progress-button button,
.error.progress-button button {
        -webkit-transition: background-color 0.3s, width 0.3s, border-width 0.3s;
        transition: background-color 0.3s, width 0.3s, border-width 0.3s;
}


Зададим цвета для последнего состояния:
.success.progress-button button {
        border-color: #1ECD97;
        background-color: #1ECD97;
}

.error.progress-button button {
        border-color: #FB797E;
        background-color: #FB797E;
}


Когда будет применен необходимый класс, нужно показать нашу SVG и анимировать stroke-dashoffset установкой следующео значения для transition:
.loading.progress-button svg.progress-circle path,
.success.progress-button svg.checkmark path,
.error.progress-button svg.cross path {
        opacity: 1;
        -webkit-transition: stroke-dashoffset 0.3s;
        transition: stroke-dashoffset 0.3s;
}


Добавим easing для анимации широты кнопки:
.elastic.progress-button button {
        -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1), border-width 0.3s, border-color 0.3s;
        -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1.6), border-width 0.3s, border-color 0.3s;
        transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.25, 0.25, 0.4, 1.6), border-width 0.3s, border-color 0.3s;
}

.loading.elastic.progress-button button {
        -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, 0, 0.75, 0.75), border-width 0.3s, border-color 0.3s;
        -webkit-transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, -0.6, 0.75, 0.75), border-width 0.3s, border-color 0.3s;
        transition: background-color 0.3s, color 0.3s, width 0.3s cubic-bezier(0.6, -0.6, 0.75, 0.75), border-width 0.3s, border-color 0.3s;
}


Если вы любите играть с другими easing-функциями – пробуйте Ceaser, CSS Easing Animation Tool by Matthew Lein.

Со стилями определились, творим магию дальше.

JavaScript

Начнем с инициализации некоторых элементов: button – это html-элемент button, progressEl – SVG элемент кольцо progress bar, а successEl, errorEl – SVG-элементы галочка и крестик соответственно:

function UIProgressButton( el, options ) {
        this.el = el;
        this.options = extend( {}, this.options );
        extend( this.options, options );
        this._init();
}

UIProgressButton.prototype._init = function() {
        this.button = this.el.querySelector( 'button' );
        this.progressEl = new SVGEl( this.el.querySelector( 'svg.progress-circle' ) );
        this.successEl = new SVGEl( this.el.querySelector( 'svg.checkmark' ) );
        this.errorEl = new SVGEl( this.el.querySelector( 'svg.cross' ) );
        // init events
        this._initEvents();
        // enable button
        this._enable();
}


Добавили функцию SVGEI, которая будет использоваться для того, то бы предоставить SVG-элементы и их paths. Мы кэшируем path и соответственно длину для каждого. Изначально мы «оттягиваем» все paths, управляя значениями свойств strokeDasharray и strokeDashoffset. Позже мы «втянем» их обратно, когда покажем загрузочный круг, или галочку, или крестик. Эту технику хорошо объясняет Jake Archibald в статье Animated line drawing in SVG. Устанавливаем значение stroke-dasharray равное длине path и оттягиваем его. Установив значение stroke-dashoffset также равное его длине, мы больше не видим его. Когда нам нужно будет показать фигуру — установим offset на 0, имитируя рисование фигуры:
function SVGEl( el ) {
        this.el = el;
        // the path elements
        this.paths = [].slice.call( this.el.querySelectorAll( 'path' ) );
        // we will save both paths and its lengths in arrays
        this.pathsArr = new Array();
        this.lengthsArr = new Array();
        this._init();
}

SVGEl.prototype._init = function() {
        var self = this;
        this.paths.forEach( function( path, i ) {
                self.pathsArr[i] = path;
                path.style.strokeDasharray = self.lengthsArr[i] = path.getTotalLength();
        } );
        // undraw stroke
        this.draw(0);
}

// val in [0,1] : 0 - no stroke is visible, 1 - stroke is visible
SVGEl.prototype.draw = function( val ) {
        for( var i = 0, len = this.pathsArr.length; i < len; ++i ){
                this.pathsArr[ i ].style.strokeDashoffset = this.lengthsArr[ i ] * ( 1 - val );
        }
}


Далее, мы должны инициализировать onclick event для нашей кнопки. Сначала кнопка превратится в круг (с помощью добавления класса loading). После окончания анимации, либо будет вызвана callback функция, либо прогресс установится на 100%. В данный момент кнопка отключается (это событие должно бы быть самым первым, однако такой браузер как firefox, например, не сможет удалить transitionend event):
UIProgressButton.prototype._initEvents = function() {
        var self = this;
        this.button.addEventListener( 'click', function() { self._submit(); } );
}

UIProgressButton.prototype._submit = function() {
        classie.addClass( this.el, 'loading' );
        
        var self = this,
                onEndBtnTransitionFn = function( ev ) {
                        if( support.transitions ) {
                                this.removeEventListener( transEndEventName, onEndBtnTransitionFn );
                        }
                        
                        this.setAttribute( 'disabled', '' );

                        if( typeof self.options.callback === 'function' ) {
                                self.options.callback( self );
                        }
                        else {
                                self.setProgress(1);
                                self.stop();
                        }
                };

        if( support.transitions ) {
                this.button.addEventListener( transEndEventName, onEndBtnTransitionFn );
        }
        else {
                onEndBtnTransitionFn();
        }
}


Как только прогресс достигнет 100%, необходимо обновить заполнение загрузочного круга. Затем нужно показать либо галочку, либо крестик. Через некоторое время (options.statusTime) мы уберём все индикаторы состояния и заново включаем кнопку. Обратите внимание, что все переходы контролируются посредством CSS.
UIProgressButton.prototype.stop = function( status ) {
        var self = this,
                endLoading = function() {
                        self.progressEl.draw(0);
                        
                        if( typeof status === 'number' ) {
                                var statusClass = status >= 0 ? 'success' : 'error',
                                        statusEl = status >=0 ? self.successEl : self.errorEl;

                                statusEl.draw( 1 );
                                // add respective class to the element
                                classie.addClass( self.el, statusClass );
                                // after options.statusTime remove status and undraw the respective stroke and enable the button
                                setTimeout( function() {
                                        classie.remove( self.el, statusClass );
                                        statusEl.draw(0);
                                        self._enable();
                                }, self.options.statusTime );
                        }
                        else {
                                self._enable();
                        }

                        classie.removeClass( self.el, 'loading' );
                };

        // give it a little time (ideally the same like the transition time) so that the last progress increment animation is still visible.
        setTimeout( endLoading, 300 );
}


Кнопка готова!

«We hope you enjoyed this tutorial and find it useful!»

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Почему электронная почта не умрет никогда

В последние пару лет в сети все чаще можно слышать дискуссии о том, что электронная почта, как инструмент коммуникации — пользователей между собой, и клиентов с компаниями — устарела и имеет целый ряд минусов. Такие материалы были, в том числе и на Хабре. В блоге Печкина мы много пишем об интересных техниках работы с email-рассылками, а сегодня представляем вашему вниманию адаптированный перевод материала из журнала The Atlantic, который призван объяснить, почему email — это лучшее, что до сих пор есть в интернете, и он не умрет никогда.

Все пытаются убить электронную почту.

«Электронная почта мертва – по крайней мере, так считают в Кремниевой долине», –пишет репортер Businessweek Эшли Вэнс (Ashlee Vance).


Соучредитель стартапа Asana Джастин Розенштайн (Justin Rosenstein) считает, что электронная почта стала «контрпродуктивной».
Создатели Slack – популярного корпоративного мессенджера – любят хвастаться тем, что «они спасли мир от 70000000 электронных писем» (если считать, что пять сообщений в Slack заменяют одно электронное письмо).

Так считают не только компании, продающие облачное программное обеспечение. Некоторые подростки (особенно те, которые моложе «миллениалов») тоже думают, что электронная почта бесполезна.

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

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

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

Электронную почту нельзя убить! Она живучая как таракан, в хорошем смысле этого слова. Это очень полезное качество.
«Отправлять и получать почту не очень сложно, что является её главным преимуществом, – считает Аарон Страуп Коуп (Aaron Straup Cope), специалист по цифровым и новым медиа из национального музея дизайна Купер-Хьюитт. – В следующий раз, когда кто-нибудь скажет вам, что электронная почта «мертва», попробуйте представить, сколько средств было потрачено на разработку нового решения, и во сколько обойдётся отказ от уже существующей системы».

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

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

Да, электронная почта поражает воображение, и вы должны радоваться этому!

* * *


За счет изменений, происходивших вокруг электронной почты, изменился и способ её использования. Электронная почта не умирает – она изменяется.

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

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

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

Электронная почта была «паспортом интернета». До того как почта стала использоваться для подтверждения личности пользователя в Facebook, заняться чем-то серьезным в интернете, можно было только используя электронную почту. Вам нужно подтвердить подлинность банковского счета? Электронная почта. Amazon? Электронная почта. Форумы? Электронная почта. Какое-то время электронная почта нужна была даже для регистрации на Facebook. Имя@Фамилия.com означало, что у вас был свой домен. Аккаунт на Hotmail мог означать, что в интернете вы новичок. Почтовый адрес Well говорил о том, что вы давно пользуетесь интернетом. Какое-то время аккаунт на Gmail был знаком элитарности. Сейчас у адреса электронной почты не так много функций, и он мало что значит. Появилось много новых способов самовыражения в сети.

Электронная почта была основным способом общения в сети. Только с её помощью можно было отправлять сообщения. BBS, чаты и форумы существовали столько же, сколько и почта, но только с помощью email люди могли напрямую, избегая чужого внимания, общаться друг с другом. Можно было общаться и без интернета, но с его появлением, процесс стал проще. Сейчас существует огромное количество способов связаться с кем-то в сети. С помощью телефона, профиля Facebook, аккаунта в Twitter, LinkedIn, Instagram, Qik, WhatsApp и т.п. В мире мобильных технологий разработчикам приложений нужен доступ к списку контактов пользователя, а не электронной почте.

Электронная почта использовалась для отправки файлов. После снижения популярности FTP-серверов, и до появления Dropbox и Google Drive, важные документы пересылали только с помощью электронной почты. Возможность прикрепить документ к письму была нужна всем. Попробуйте представить современный интернет без такой функции. Но по сравнению с современными хранилищами данных, электронная почта далека от идеала.

Электронная почта являлась основным инструментом для коммуникации в команде. Большинство компаний не смогли бы нормально функционировать без использования электронной почты. Исключение из правил – французская компания Atos, которая смогла запретить использование почты на рабочем месте.

Это именно та функция электронной почты, которую компании хотят преобразить. В 2013 году генеральный директор HootSuite в статье на сайте Fast Company объяснил, что электронная почта контрпродуктивна, невероятно прямолинейна, не способствует социальному общению и, что странно, приводит к появлению «складов» данных. К тому же, кому не хочется заполучить немного денег из бюджетов компаний? Стартапам, которым не удалось построить бизнес в потребительской среде, нужно гуда-то двигаться.

* * *


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

Так что же станет с почтой?

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

Журналист а Ян Богост (Ian Bogost) заметил, что мы используем название «почта» как метафору, описывая способ передачи сообщений между серверами. Но на самом деле электронная почта заменила не обычные письма, а другие способы обмена информацией: телефонные звонки, общение с человеком напрямую, заметки и рекламные акции.

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

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

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

Стоит отметить, что благодаря системам фильтрации, спам, которым заваливали наши ящики, стал незаметным. Вчера, я получил сотни таких писем, но не заметил ни одного, потому что Gmail и Atlantic отсеяли их, и они не попали в мой почтовый ящик. В то же время спам сообщения об интимных услугах можно найти по всему интернету. Я замечаю их на всех сайтах, в том числе на Facebook и Twitter.

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

Так раньше выглядела электронная почта (взято с Wikimedia)

Вспомните клиент Hotmail в 1996 году или Microsoft Outlook в 1999, или – я знаю, некоторые нерды возненавидят меня за это – Pine, использовавший протоколы Telnet в 1993 году. Сравните их с современными клиентами Gmail или Mailbox на iPhone. Процесс получения писем стал намного лучше, понятнее и современнее.

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

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

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

Хотя эволюция электронной почты очень важна для ее существования, тот факт, что ей удалось сохранить характеристики старой сети, отличает ее от других похожих приложений. Электронная почта – это открытый, обеспечивающий взаимодействие между данными, протокол. Кто-то может использовать сервисы Google, чтобы поднять сервер, кто-то может отправлять сообщения, используя корпоративное ПО Microsoft, но все они могут общаться друг с другом без проблем. Некоторые страны сделали все, что в их силах, чтобы помешать использовать или даже полностью уничтожить анонимную электронную почту после того, что сделал Сноуден. Действительно, ведь электронная почта – это самая защищенная и закрытая часть интернета, особенно если вы приняли дополнительные меры по повышению ее безопасности.

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

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

Возможно, нам удастся вернуть что-то от «старой сети», функционировавшей до появления Apple, Google, Amazon и Facebook, если мы перестанем создавать конкурентов этим компаниям, а начнем пользоваться электронной почтой, тем самым поддерживая её.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

ARM сегодня 25

25 лет назад, 27 ноября 1990, из фирмы Acorn Computers выделилась команда, разработавшая микропроцессоры ARM1, ARM2 и ARM3. Из тех двенадцати сооснователей — четверо продолжают работать в ARM по сей день, среди почти четырёх тысяч сотрудников, собравшихся из 71 стран мира.

Первые несколько лет вся ARM помещалась в большом сарае в деревне Swaffham Bulbeck, в 13км от Кембриджа; сейчас у компании больше сорока офисов, разбросанных по двадцати странам.


ARM не выпускает процессоры сама; но её партнёры за 25 лет выпустили 75 миллиардов чипов, реализующих одну из версий архитектуры ARM. Это на порядок больше, чем число кирпичиков в Великой китайской стене!

За пять лет — от первого выпущенного процессора ARM1 до основания компании ARM — было выпущено 130 тысяч чипов. Первым процессором, выпущенным ARM отдельно от Acorn, стал ARM610, разработанный специально для использования в Apple Newton — планшетном компьютере, опередившем своё время. Разочарованная коммерческим провалом Newton, Apple отказалась от идеи на долгие 17 лет; но и в следующем планшете от Apple, знаменитом iPad, также использовался процессор от ARM — Apple A4 на основе Cortex-A8. В нынешнем году чипы ARM выпускаются по полсотни штук каждую секунду — около 13 миллиардов за прошедшие 11 месяцев!

Примерно четверть всех выпущенных чипов приходится на процессор ARM7TDMI, выпускаемый с 1998 г.

Но самое впечатляющее достижение — то, что в день рождения ARM на хабре появился полный неоправданного пессимизма пост «Сегодняшний мир — это amd64, armv7 и aarch64. Всё остальное мертво, Джим».
По мнению разработчика OpenBSD, две из трёх живых на сегодняшний день архитектур — это архитектуры ARM!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

пятница, 27 ноября 2015 г.

[Из песочницы] Удобый просмотр MAC адресов на портах свитчей huawei, linksys, dlink, extreme при помощи expect

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

Освоил expect и сразу в бой. Написал, опробовал, получилось. Теперь делюсь с Вами, может кому и пригодится.
Сначала создадим пустой файлик: nano ./get_mac.sh

Теперь нужно вставить внутрь туда код который ниже:

#!/usr/bin/expect -f
if {[llength $argv] != 2} {
puts "Не верно указаны переменные: ./get_mac 10.5.X.XXX 'port'"
exit 1
}
set ip [lindex $argv 0]
set eth [lindex $argv 1]
set login "ЛОГИН НА СВИТЧЕ"
set pass "ПАРОЛЬ"
package require Expect
spawn telnet $ip

expect {
        "*assw*" {
        send "$pass\n"
        expect "*>"
        send "su\n"
        expect "*ass*"
        send "$pass\n"
        expect "*>"
        send "disp mac-addr dy | inc $eth\n"
        expect "*>"
        send "q\n"}

        "*User Name*" {
        send "$login\n"
        expect "*asswor*"
        send "$pass\n"
        expect "*#"
        send "show brid address-table ethernet e$eth\n"
        expect "*#"
        send "exit\n"}

        "*login*" {
        send "admin\n"
        expect "*password*"
        send "$pass\n"
        expect "*#*"
        send "show fdb port $eth\n"
        expect "*#*"
        send "exit\n"}

         "*Name*" {
        send "$login\n"
        expect "*Word*"
        send "$pass\n"
        expect "*#"
        send "show fdb port $eth\n"
        expect "*#"
        send "logo\n"}
}
interact


Теперь рассмотрим как это работает.

В командной строке нужно написать вызов скрипта ,ip Вашего свитча, и порт на котором хотим поглядеть МАС: ./get_mac.sh 10.5.0.10 1

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

У свитчей Huawei есть особенность. Можно считать таблицу fdb динамически и сортировать по содержащемуся значению. По этому для этих свитчей рекомендуется более точно указывать параметр порта. К примеру Eth0/0/Номер порта или 0/0/Номер порта. Иначе скрипт вывалит все маки в которых содержится переменная и скрипт может вылететь по причине ожидания.

Данный скрипт проверен на железках huawei s2326TP-EI, dlink des-3028, linksys sr224g4 и extreme summit 200-24. По идее будет работать и на dlink'ах других серий таких как 32,35 и cisco.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Стоит ли овчинка выделки или про “грандиозные” обновления программ

Всем доброго здравия!

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

Наши заблуждения стоят нам напрасно потерянного времени!

Итак, кому интересно, добро пожаловать под кат!
Краткая предыстория

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

Обязательное условие при создании прототипа, он не должен повторять или копировать существующие приложения в сторе.

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

Одним из таких прототипов и являлось приложение “Clean for VK”, которое без дополнительных манипуляций по его развитию, показывало хорошее число установок в сторе.

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

Сейчас по идее, в меня должны полететь камни, что еще мол один открыл для себя SDK социальной сети ВК).

Не совсем так, чуть дальше я покажу один “костыль”, не имеющий никакого отношения к SDK.

Выдержано ли было условие “не повторять и не копировать” из магазина приложений? Выдержано на 100%! На тот момент, App Store пестрил мессенджерами всех мастей и видов для ВК, различными “шпиЁнами” для неё же, но страницу/профиль пользователя не чистило ни одно приложение.

Вот так выглядел и работал прототип приложения
image

Откуда уши торчат?

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

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

О конкурентах

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

Когда прототип стал базовым и почему?

Сделать приложение базовым было решено в тот момент, когда количество активных установок превысило 10000 и появилась уверенность, что программу будут устанавливать и далее, даже при наличии образовавшихся конкурентов. На тот момент пришло понимание, что несмотря на попадание программы в ТОП платных социальной категории российского сегмента App Store, конверсия приложения оставляет желать лучшего и его нужно развивать!

Особенности реализации

При разработке я стараюсь использовать NSOperation*, чтобы можно было более наглядно управлять очередью операций, GCD практически не использую, но иногда при быстрой правке метода могу воткнуть и GCD. Здесь и далее подразумевается, что все методы в приложении завернуты в NSOperation, но подробно многопоточность я рассматривать не буду.

Кстати, огромное спасибо Егору из Rambler&Co за недавний доклад по NSOperation. Было познавательно и интересно!

В основном, практически весь функционал строится на официальном SDK, который позволяет покрыть 90% потребностей в разработке для данной сети.

Спойлер с методами SDK
Пользователи
users.get
users.search
users.isAppUser
users.getFollowers
users.report
users.getNearby

Авторизация
auth.checkPhone
auth.signup
auth.confirm
auth.restore

Стена
wall.get
wall.search
wall.getById
wall.post
wall.repost
wall.getReposts
wall.edit
wall.delete
wall.restore
wall.pin
wall.unpin
wall.getComments
wall.addComment
wall.editComment
wall.deleteComment
wall.restoreComment
wall.reportPost
wall.reportComment

Фотографии
photos.create
photos.editAlbum
photos.getAlbums
photos.get
photos.getAlbumsCount
photos.getById
photos.getUploadServer
photos.getOwnerPhotoUploadServer
photos.getChatUploadServer
photos.saveOwnerPhoto
photos.saveWallPhoto
photos.getWallUploadServer
photos.getMessagesUploadServer
photos.saveMessagesPhoto
photos.report
photos.reportComment
photos.search
photos.save
photos.copy
photos.edit
photos.move
photos.makeCover
photos.reorderAlbums
photos.reorderPhotos
photos.getAll
photos.getUserPhotos
photos.deleteAlbum
photos.delete
photos.restore
photos.confirmTag
photos.getComments
photos.getAllComments
photos.createComment
photos.deleteComment
photos.restoreComment
photos.editComment
photos.getTags
photos.putTag
photos.removeTag
photos.getNewTags

Друзья
friends.get
friends.getOnline
friends.getMutual
friends.getRecent
friends.getRequests
friends.add
friends.edit
friends.delete
friends.getLists
friends.addList
friends.editList
friends.deleteList
friends.getAppUsers
friends.getByPhones
friends.deleteAllRequests
friends.getSuggestions
friends.areFriends
friends.getAvailableForCall

Виджеты
widgets.getComments
widgets.getPages

Работа с данными
storage.get
storage.set
storage.getKeys

Статус
status.get
status.set

Аудиозаписи
audio.get
audio.getById
audio.getLyrics
audio.search
audio.getUploadServer
audio.save
audio.add
audio.delete
audio.edit
audio.reorder
audio.restore
audio.getAlbums
audio.addAlbum
audio.editAlbum
audio.deleteAlbum
audio.moveToAlbum
audio.setBroadcast
audio.getBroadcastList
audio.getRecommendations
audio.getPopular
audio.getCount

Страницы
pages.get
pages.save
pages.saveAccess
pages.getHistory
pages.getTitles
pages.getVersion
pages.parseWiki
pages.clearCache

Группы
groups.isMember
groups.getById
groups.get
groups.getMembers
groups.join
groups.leave
groups.search
groups.getInvites
groups.banUser
groups.unbanUser
groups.getBanned
groups.edit
groups.editPlace
groups.getSettings
groups.getRequests
groups.editManager
groups.addLink
groups.deleteLink
groups.editLink
groups.reorderLink
groups.removeUser
groups.approveRequest

Обсуждения
board.getTopics
board.getComments
board.addTopic
board.addComment
board.deleteTopic
board.editTopic
board.editComment
board.restoreComment
board.deleteComment
board.openTopic
board.closeTopic
board.fixTopic
board.unfixTopic

Видеозаписи
video.get
video.edit
video.add
video.save
video.delete
video.restore
video.search
video.getUserVideos
video.getAlbums
video.getAlbumById
video.addAlbum
video.editAlbum
video.deleteAlbum
video.reorderAlbums
video.reorderVideos
video.addToAlbum
video.removeFromAlbum
video.getAlbumsByVideo
video.getComments
video.createComment
video.deleteComment
video.restoreComment
video.editComment
video.getTags
video.putTag
video.removeTag
video.getNewTags
video.report
video.reportComment

Заметки
notes.get
notes.getById
notes.getFriendsNotes
notes.add
notes.edit
notes.delete
notes.getComments
notes.createComment
notes.editComment
notes.deleteComment
notes.restoreComment

Места
places.add
places.getById
places.search
places.checkin
places.getCheckins
places.getTypes

Аккаунт
account.getCounters
account.setNameInMenu
account.setOnline
account.setOffline
account.lookupContacts
account.registerDevice
account.unregisterDevice
account.setSilenceMode
account.getPushSettings
account.setPushSettings
account.getAppPermissions
account.getActiveOffers
account.banUser
account.unbanUser
account.getBanned
account.getInfo
account.setInfo
account.changePassword
account.getProfileInfo
account.saveProfileInfo

Сообщения
messages.get
messages.getDialogs
messages.getById
messages.search
messages.getHistory
messages.send
messages.delete
messages.deleteDialog
messages.restore
messages.markAsRead
messages.markAsImportant
messages.getLongPollServer
messages.getLongPollHistory
messages.getChat
messages.createChat
messages.editChat
messages.getChatUsers
messages.setActivity
messages.searchDialogs
messages.addChatUser
messages.removeChatUser
messages.getLastActivity
messages.setChatPhoto
messages.deleteChatPhoto

Новости
newsfeed.get
newsfeed.getRecommended
newsfeed.getComments
newsfeed.getMentions
newsfeed.getBanned
newsfeed.addBan
newsfeed.deleteBan
newsfeed.ignoreItem
newsfeed.unignoreItem
newsfeed.search
newsfeed.getLists
newsfeed.saveList
newsfeed.deleteList
newsfeed.unsubscribe
newsfeed.getSuggestedSources

Мне нравится
likes.getList
likes.add
likes.delete
likes.isLiked

Опросы
polls.getById
polls.addVote
polls.deleteVote
polls.getVoters
polls.create
polls.edit

Документы
docs.get
docs.getById
docs.getUploadServer
docs.getWallUploadServer
docs.save
docs.delete
docs.add

Закладки
fave.getUsers
fave.getPhotos
fave.getPosts
fave.getVideos
fave.getLinks
fave.addUser
fave.removeUser
fave.addGroup
fave.removeGroup
fave.addLink
fave.removeLink

Уведомления
notifications.get
notifications.markAsViewed

Статистика
stats.get
stats.trackVisitor
stats.getPostReach

Поиск
search.getHints

Приложения
apps.getCatalog
apps.get
apps.sendRequest
apps.deleteAppRequests
apps.getFriendsList
apps.getLeaderboar
apps.getScoreМетод

Служебные
utils.checkLink
utils.resolveScreenName
utils.getServerTime

Данные ВК
database.getCountries
database.getRegions
database.getStreetsById
database.getCountriesById
database.getCities
database.getCitiesById
database.getUniversities
database.getSchools
database.getSchoolClasses
database.getFaculties
database.getChairs

Подарки
gifts.get

other
execute

Так, получение друзей пользователя для анализа и последующей обработки, решается достаточно просто:

NSInteger offset = 0;
    NSMutableArray *friends = [NSMutableArray new];
    NSMutableArray *banFriends = [NSMutableArray new];
    NSArray *array = nil;
    do {
        array = [self requestFriendsWithOffset:offset];
            [friends addObjectsFromArray:array];
        offset += 5000;
    } while (array.count);
    for (int i = 0; i < friends.count; i++) {
        if (friends[i][@"deactivated"]) {
            [banFriends addObject:friends[i]];
        }
    }

Сам метод получения друзей

- (NSArray *)requestFriendsWithOffset:(NSInteger)offset {

    __block NSArray* responseResult = @[];
    VKRequest *request = [[VKApi friends] get:@{@"offset": @(offset),
                                                @"count": @"5000",
                                                @"fields": @"deactivated"}];
    request.waitUntilDone = YES;
    [request executeWithResultBlock:^(VKResponse *response) {
    NSArray* items = response.json[@"items"];
        if ([items count] < 1) {
            responseResult = @[];
        } else {
            responseResult = items;
        }
    } errorBlock:^(NSError *error) {
        NSLog(@"ERROR FRINDS REQUEST %@", error.localizedDescription);
    }];
    return responseResult;
} // requestFriendsWithOffset

Единственное, что пришлось освоить метод “execute”, для ускорения работы приложения при выборке контента. Сам метод использует в своей работе VKScript, как аналог JavaScript. Использовать его достаточно просто и эффективно, но так получилось, что внятных ответов по его использованию у официального сообщества ВК получить не удалось.

Пример подготовки запроса для execute

- (NSString *)codeForComments:(NSArray *)array
                andWithOffset:(NSInteger)offset {
    
    NSMutableString *codeString = [NSMutableString new];
    if (array.count > 0) {
    NSMutableString *tempString = [NSMutableString new];
    for (int i = 0; i < array.count; i++) {
    NSString *string = [NSString stringWithFormat:@" ,API.wall.getComments({\"post_id\":\"%@\",\"count\":\"100\",\"extended\":\"1\",\"offset\":\"%@\"})", [array[i] stringValue], [NSString stringWithFormat:@"%ld", (long)offset]];
            [tempString appendString:string];
        }
    NSString * extractString = [tempString substringFromIndex:2];
        [codeString appendString:@"return ["];
        [codeString appendString:extractString];
        [codeString appendString:@"];"];
    }
    return [NSString stringWithFormat:@"%@", codeString];
} // codeForComments

Сам запрос при выполнении

- (NSArray *)executeCommentsForPosts:(NSString *)codeString {

    NSDictionary *parametrs = @{@"code":codeString};
    __block NSArray *responseResult = @[];
    VKRequest *request = [VKApi requestWithMethod:@"execute"
                                    andParameters:parametrs
                                    andHttpMethod:@"GET"];
    request.waitUntilDone = YES;
    [request executeWithResultBlock:^(VKResponse *response) {
    NSArray *tempArray = response.json;
        if ([tempArray count] < 1) {
            responseResult = @[];
        } else {
            responseResult = tempArray;
        }
    } errorBlock:^(NSError *error) {
        NSLog(@"ERROR LOADING COMMENTS %@", error.localizedDescription);
    }];
    return responseResult;
} // executeCommentsForPosts

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

Собственно, о “костылях”

Ну а как без костылей? Запланировав в обновлении метод чистки лайков на стене, не составило труда сделать выборку всех отметок “нравится”, где по логике обработчика нужно было добавить пользователя в черный список, после чего его отметки должны исчезнуть из всех постов. Но я поймал настойщий ступор после того, как обнаружил, что метод “account.banUser” не решает проблемы удаления лайка. Все отметки оставались на своих местах. Обратившись с вопросом к сообществу разработчиков ВК, я получил отсылки только к данному методу. Поиск в google & stackoverflow также не принес результатов. Встречались лишь упоминания о том, что данная операция ранее успешно применялась в программе VKBot, но она не работоспособна на настоящий момент и проверить так ли это, я не смог.

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

Для исследования использовалась программа из Mac App Store — “Cellist”, выступающая в качестве прокси, через которую можно прогонять трафик для исследований. Настроив программу на ноутбуке, я получил ssl-сертификат для своего телефона и настроил устройство так, чтобы в сеть оно ходило через этот прокси на моем компьютере. Далее просто была авторизация на своей странице, случайный выбор поста и ручное удаление лайка.

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

Ну а далее все просто. Осталось лишь в коде воссоздать последовательность операций, что действие как будто происходит в браузере.

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

- (id)initWithUserID:(NSString *)userID
            andObjID:(NSString *)objectID {
    
    if (self = [super init])
        stringUserID = userID;
        stringObjectID = objectID;
    return self;
} // initWithID


- (void)main {
    
    if (self.isCancelled) {
        return;
    }
    [self prepareHashWithUserID:stringUserID
                    andObjectID:stringObjectID];
} // main


- (void)prepareHashWithUserID:(NSString *)userID
                  andObjectID:(NSString *)objID {
    
    NSString *wallUserID = [[NSUserDefaults standardUserDefaults] stringForKey:@"wallUserID"];
    NSString *objectWall = [NSString stringWithFormat:@"wall%@_%@", wallUserID, objID];
    
    
    NSString *urlString = [NSString stringWithFormat:@"http://ift.tt/1TatAww", userID, objectWall];
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request
                                         returningResponse:&response
                                                     error:&error];
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSArray *array = [dataString componentsSeparatedByString:@"hash: '"];
    NSString *hashString = array[1];
    array = [hashString componentsSeparatedByString:@"'"];
    hashString = array[0];
    [self deleteLike:userID
             andHash:hashString
            andObjID:objectWall];
} // prepareHashWithUserID


- (BOOL)deleteLike:(NSString *)userID
           andHash:(NSString *)hash
          andObjID:(NSString *)objID {
    
    NSString *urlString = [NSString stringWithFormat:@"http://ift.tt/1PfOcp4", hash, userID, objID];
    NSURL *url = [NSURL URLWithString:urlString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    [NSURLConnection sendSynchronousRequest:request
                          returningResponse:&response
                                      error:&error];
    BOOL result;
    if (!error) {
        result = YES;
    } else {
        result = NO;
    }
    return result;
} // deleteLike

Новая реализация приложения. Как все выглядит
image

Изменилось ли что-нибудь после обновления?

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

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

“Виртуально сынок мы миллионеры, но на деле имеем лишь 2-х … и 1-го сына …."

Посмотреть то, что получилось, можно здесь: App Store

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

P.S.: Хотелось бы послушать разработчиков, как они повышают конверсию. Если кому есть что рассказать, то прошу писать в комментах или личных сообщениях.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.