...

суббота, 25 июля 2020 г.

[Из песочницы] Побитовая арифметика в Java

Приветствую, дорогой читатель.

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

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

Сложение


Алгоритм:
private int add(int summand, int addend)
{
        /*Перенос.*/
        int carry       = 0x00;

        /*Итерировать до тех пор, пока не закончится перенос на старший разряд.*/
        while(addend != 0x00)
        {
                /*Выставить флаг под разрядами с установленными битами.*/
                carry   = (summand & addend);
                /*Снять с первого слагаемого биты, разряд по которым уже учтен.*/
                summand = summand ^ addend;
                /*Перенос переводится в старший разряд.*/
                addend  = (carry << 1);
        }
        return summand;
}

Для начала надо вспомнить о переносе в старший разряд. В десятичной системе под его определение (для текущего разряда) подпадают значения в диапазоне от 10 до 18:
109 +
019 =
128

В двоичной же системе переносится все, что больше единицы:
0001 +
0001 =
----
0010

или так:

0011 +
0011 =
----
0110

В последнем примере первыми складываются самые младшие биты:
1 + 1 = 10(два)

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

1 + 1 + 1 = 11 (три)

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

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

carry        = (summand & addend); 
0011    = 0011 & 0011

Это еще не перенос, но выставление «флагов» над разрядами, сложение которых оставляет перенос.

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

summand       = summand ^ addend;
0000    = 0011 ^ 0011

Как известно, побитовый оператор «Исключающее ИЛИ» выставит биты только если значения разрядов противоположны.

Третий шаг цикла — это преобразование «флагов» наличия переноса непосредственно в перенос. Для этого они сдвигаются на один шаг влево и присваиваются второму слагаемому:

addend = (carry << 1);
0110    = (0011 << 1);

На последующей итерации перенос зафиксирован не будет, т.к:
carry       = (summand & addend); 
0000    = 0000 & 0110

Второй шаг даст нам:
summand    = summand ^ addend;
0110    = 0000 ^ 0110,

Что является искомой суммой, а третий шаг завершит цикл while():
addend = (carry << 1);
0000    = (0000 << 1)

Вычитание


Алгоритм:
private int sub(int minuend, int subtrahend)
{
        /*Отрицательный перенос.*/
        int borrow      = 0x00;

        /*Итерировать до тех пор, пока не закончится перенос на младший разряд.*/
        while(subtrahend != 0x00)
        {
                /*Выставить флаг под разрядами с установленными битами.*/
                borrow = ((~minuend) & subtrahend);
                /*Снять с уменьшаемого биты, разряд по которым уже учтен.*/
                minuend = minuend ^ subtrahend;
                /*Перенос переводится в старший разряд.*/
                subtrahend = (borrow << 1);
        }
        return minuend;
}

Эквивалентен предыдущему с той лишь разницей, что значение уменьшаемого — это инвертированное слагаемое. Здесь реализовано правило арифметики, согласно которому сложение значений с противоположным знаком дает разность:
a + (-b); (-a) + b;

Таким образом, для реализации побитового вычитания достаточно инвертировать значение первого слагаемого унарным оператором «НЕ» и переименовать локальные переменные.

Умножение


Алгоритм:
public int multiply(int mul1, int mul2)
{
        int result = 0;
        /*Пока второй множитель не равен нулю.*/
        while(mul2 != 0)
        {
                /*Если установлен бит в очередном разряде...*/
                if ((mul2 & 1) == 1)
                {
                        /*сложить первый множитель с самим собою.*/
                        result = (result + mul1);
                }
                /*Очередной сдвиг первого множителя влево ("лесенка")*/
                mul1 <<=  1;
                /*Подводим очередной разряд в начало для сверки с условием оператора if()*/
                mul2 >>>= 1;
        }
        return result;
}

Вернемся к истокам: умножение в столбик в десятичной системе:
  25 *
  05 =
  --
 125 +
 00
 ---
 125

т.е. мы перемножаем каждый разряд второго множителя с первым множителем. Отсюда же следует, что произведение от старшего разряда сдвигается на один шаг влево. И наконец складываем промежуточные значения. То же самое происходит на побитовом уровне:
    0110 *
    0011 =
    ----
    0110 +
  0 110  +
 00 00   +
000 0    +
  - ----
  1 0010

Делаем вывод, что алгоритм только и должен, что складывать первый множитель с самим собою всякий раз как во втором множителе встречается установленный бит, естественно, с учетом правила перевода в старший разряд:
if ((mul2 & 1) == 1) //(0011 & 0001) == 0001
{
     result = (result + mul1); //0110 = 0000 + 0110
}

Дальше осуществляется сдвиг первого множителя на один разряд влево (формируем «лесенку»):
mul1 <<=  1; //1100 = 0110 << 1;

Теперь определяем, есть ли бит во втором по значимости разряде второго множителя:
mul2 >>>= 1; //0001 = 0011 >>> 1;

Цикл работает до тех пор, пока второй множитель не равен нулю. Хотел бы обратить внимание на следующее: от ресурса к ресурсу гуляет экземпляр этого алгоритма, где логический сдвиг второго множителя (mul2 >>>= 1;) заменен на арифметический (mul2 >>= 1;). Вероятно, он берет свое начало из реализации на C/C++, где есть ключевое слово unsigned и такая подмена не является проблемой. Однако в Java все типы чисел знаковые и если второй множитель будет представлен отрицательным значением, то такая оплошность приведет к вываливанию алгоритма в бесконечный цикл, т.к. второй множитель всегда будет отвечать его условию:
1000 >>1; //пока все хорошо
1100 >>1; //засада замаячила (ожидалось 0100)
1110 >>1; //ожидалось 0010
1111 >>1; // отсюда и далее второй множитель будет иметь значение -1

Деление


Алгоритм:
private int divide(int dividend, int divisor)
{
        /*Знак, частное и маска для выставления битов на частном.*/
        int quotient = 0x00, mask = 0x01;
        /*Для возвращения делителя в исходное состояние.*/
        int temp = divisor;
        /*Знак отрицательный если только одна переменная отрицательная.*/
        int sign = ((dividend < 0)^(divisor < 0)) ? sign = -1 : 1;
        
        /*Получить абсолютные значения.*/
        dividend        = dividend      < 0 ? ((~dividend) + 1) : dividend;
        divisor         = divisor       < 0 ? ((~divisor)  + 1) : divisor;
        
        /*Вернуть 0 если делимое меньше делителя.*/
        if (dividend < divisor) return quotient;

        while(dividend > 0)
        {
                /*Сдвигать влево пока условие истинно.*/
                if ((dividend >= (divisor << 0x01)) && ((divisor << 0x01) > 0))
                {
                        divisor <<= 0x01;
                        mask    <<= 0x01;
                }
                /*Граница обнаружена.*/
                else
                {
                        /*В переменной "частное" выставить бит.*/
                        quotient = quotient | mask;
                        /*Вычесть текущее значение делителя от делимого.*/
                        dividend = dividend - divisor;
                        /*Возвращаем делитель и маску в исходное положение.*/
                        divisor = temp;
                        mask    = 0x01;
                }
        }
        return quotient * sign;
}

С делением вышло не так гладко, как с предыдущими примерами: пришлось писать велосипед (сильно не бить).

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

count = 0;
1) 7 - 3 = 4; count = 1;
2) 4 - 3 = 1; count = 2;

7 / 3 = count;

Недостаток такого подхода становится особенно ощутимым при подаче устройству с ограниченными ресурсами последовательности из инструкций, как то: 2147483647 / 1; 2147483647 / 2; 2147483647 / 3, сложится впечатление, что приложение зависло.
Куда эффективней была бы работа на уровне битов. Но единственное найденное решение имеет тот недостаток, что для корректного вывода требуется тип переменных, на ступень выше охватываемого диапазона, т.е. если на вход подаете short, то тип локальных переменных должен быть int, иначе результат деления больших значений будет удивлять. В моем случае ситуация усугублялась отсутствием типа long.

Но вернемся к нашим баранам.

Для понимания принципа работы алгоритма необходимо вспомнить порядок деления столбиком:

делимое = 6, делитель = 2;
0110|0010
     ----

 110|10   //убираем избыточные биты для лучшего восприятия

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

1) (1 >= 10) -> условие не истинно, записываем ноль в частное
110|10
    --
    0

2) (11 >= 10) -> условие истинно, записываем единицу в частное
 110|10
-11  --
 10  01
 --
 01

Вот тут по-подробней. На выхлопе у нас получилось следующее: мы «вытолкнули» делитель влево до того разряда, где он минимизировал разность с делимым:
2.1) 0110 / 0010 -> 0110 - 0100 = 0010 = 2.

3) (10 >= 10) -> условие истинно, записываем еще одну единицу в частное
 110|10
-11  --
 10  011
 --
 -010
  010
  ---
  000

Этот механизм реализован в алгоритме. В цикле while() делитель должен сдвигаться влево до тех пор, пока не будет удовлетворять вышеописанному правилу. Параллельно с ним сдвигается маска частного. Оператор ветвления if() гласит: «сдвинуть можно если только результат этой операции не нарушит основное правило». Дополнительная проверка на отрицательное число связана с тем, что в Java выставленный самый старший бит – это отрицательное число. Без него цикл упадет в бесконечность:
//((divisor << 0x01) > 0) если закомментить это условие, то

1) 0111 >= 0010<<1
2) 0111 >= 0100<<1
3) 0111 >= 1000<<1 //! - тут if() посчитает, что отрицательный делитель меньше делимого, и будет прав.
4) 0111 >= 0000<<1
.... 

Как только алгоритм перестал отвечать условиям if(), код входит в else, где на частном устанавливается бит маски:
quotient = quotient | mask;
0010 = 0000 | 0010

Это аналогично выставлению битов при делении столбиком. Затем от делимого вычитается делитель:
dividend = dividend - divisor;
0010 = 0110 - 0100

После этого делитель и маска возвращаются в исходное состояние и цикл начинается вновь:
divisor = temp;
mask    = 0x01;

На последок хотел бы добавить несколько слов о дополнительном коде.

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

dividend = dividend < 0 ? ((~dividend) + 1) : dividend;
divisor = divisor < 0 ? ((~divisor) + 1) : divisor;

Тут происходит следующее: если число отрицательное, то его биты инвертируются, а результат складывается с единицей и получаем положительное (абсолютное) значение. Это же правило действительно для положительных чисел, например:
 6 = 0110 ->  ~6 = 1001 = 1001 + 1 = 1010 = -6
-6 = 1010 -> ~-6 = 0101 = 0101 + 1 = 0110 =  6

Но есть одно исключение — это максимально большое отрицательное число заданного типа, например:
int -2147483648 ->
~1000 0000 0000 0000 0000 0000 0000 0000 =
 0111 1111 1111 1111 1111 1111 1111 1111 + 1 =
 1000 0000 0000 0000 0000 0000 0000 0000.

Будьте осторожны.

Let's block ads! (Why?)

[Из песочницы] Путь в ИТ. Книга о том, как жить в ИТ профессионально и счастливо

Путь в ИТ. Обложка книги

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

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

Немного об авторе


Разработчик с опытом более 10 лет. Занималась медиасервисами в компании, создавшей Rutube. Работала над порталами Videomore.ru, СТС, Wifire TV Lite, video.khl.ru. Делала HTML5-плеера для КХЛ, ОТР, СТС и других крупных клиентов. Верстала под IE6 и разрабатывала SmartTV-приложения. Руководила фронтенд-отделом, собеседовала и собеседовалась за границу. Спикер митапов и конференций со скромным стажем. Сейчас фронтенд-разработчик в Яндексе.

Если интересно — внутри выдержки из советов и историй, а также ссылки на скачивание.

Фрагменты книги


О выборе и мотивации

Ищите, где почувствуете вдохновение, азарт, желание развиваться. Не прогибайтесь под другое. Отсекайте лишнюю бюрократию. Не дайте ей поглотить вас с первых лет реальной работы. Всегда помните конечную цель и сверяйтесь с ней как с компасом при каждом микрорешении в ваших начальных (равно как и последующих) шагах.
Если поняли, что не ваше, — бегите. Иначе вас затянет, вы станете таким же. Превратитесь в людей, на которых не хотели быть похожими. Проводя 9+ часов вместе, невозможно не слиться с окружением. Вы незаметно для себя перенимаете привычки, образ мышления, местные фирменные фразочки и шаблоны поведения. Шутки, коробившие вас в первые дни, внезапно начинают произноситься вами же спустя несколько месяцев. Не хотите стать таким? Бегите, ищите своих, ловите свою страсть.


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

Беритесь за пугающее остальных. Признание и успехи выше среднего лежат на боковых тропинках от проторенного пути. Не бойтесь амбициозных задач — главное, трезво оценивайте их потенциальную возможность, пусть и требующую от вас стать лучшей версией себя. Озвученное обещание и риск публичной неудачи способны заставить вас проявить стойкость и силу воли.
Как брать задачи? Не ройте себе яму. Берите, что успеете, крупное, берите важное, если нет — качественно делайте мелочи. Окружите себя успехом. Не подставляйтесь, беря ненужные и мутные задачи. Если они интересны вам, что ж, постарайтесь воспитать в себе привычку смотреть глазами бизнеса. Иначе вы останетесь, по мнению владельцев продукта и руководства, разработчиком немного не от мира сего, а таких не берут в космонавты-руководители.


О собеседованиях

Когда я собеседовалась в сиднейскую Canva, весьма любопытно прозвучало заявление рекрутера о том, что сейчас они ищут исключительно девушек. Несколько удивленная таким сексизмом прогрессивной страны, я незамедлительно переспросила: почему же? Ведь это звучит так нетрадиционно, согласитесь.
Как оказалось, политика компании исходит из максимального комфортного существования в рабочих пространствах представителей любого пола. Нанимая сейчас активно девушек, они стремятся избежать гендерных перекосов в коллективе и поддерживать баланс.
Очевидно, что сейчас в мире девушек серьезного уровня, подходящих для найма, гораздо меньше. А значит, каждая — гораздо более ценная находка (и, подозреваю, объект послаблений на технических собеседованиях), нежели ни в чем
не повинные разработчики мужского пола. <...>


О спортивном программировании

Я до сих пор с улыбкой вспоминаю одну задачку университетского этапа, звучавшую примерно так: «У сороконожки сорок ножек. Если сороконожка делает шаг правой ножкой, то она наступает себе на 1 ножку, если левой — на 2 ножки. <далее, кажется, шли еще некоторые дополнительные условия> Сколько ножек останется у сороконожки, если она начнет ходьбу с левой ножки? <и прилагалось, как водится, описание формата входных и выходных данных программы для прохождения тестов>». Суть решения данной задачи сводилась к набору единственной строчки кода, посылавшей в поток вывода цифру (нет, не 42): 40.


Об отношениях

Есть один тест, который вы пройдете всегда, — тест Тьюринга.
Будьте человеком, чувствуйте. Машины еще успеют появиться.
<...>
Как начальник — никогда не умаляйте важности личных отношений. Ошибочная недооценка их силы или невнимание к факту их наличия способны нанести неожиданный удар по атмосфере и составу вашей рабочей группы. Однажды увольнение одного из моих бывших коллег-менеджеров привело к побочному и крайне нежеланному для компании побочному эффекту — уходу единственного и ключевого на тот момент дизайнера продукта. <...>


О факультативах и широте кругозора

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


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

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


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

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


О выгорании и борьбе с ним

Признаки выгорания
Автоматизм <...>
Обратные отсчеты. До отпуска. До выходных. До вечера. Потом до обеда. До чая. Сужающиеся диапазоны ожидания чего-то иного. Жизнь впереди, а не здесь и сейчас в омуте текущей задачи.
Крайние левые мысли. Бросить всё. Уйти делать мебель, продавать самогонные аппараты. Получить другое образование и начать всё с нуля в этой новой (непременно лишенной всех тех проблем) сказочной области. Мозг подсказывает: пора что-то передернуть.


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

Путь в ИТ. Обложка книги

Пока (и непостоянно временно) она доступна на правах «опенсорса». Т.е. бесплатно.
Скачать можно с сайта way-in-it.ru. Там же можно отметиться о прочтении, взять бумажный экземпляр и поддержать книгу.

Больше форматов доступно на Яндекс.Диске

Let's block ads! (Why?)

Враги свободы

Многие из нас недавно прочли нашумевшую статью про WeChat, где браузер для чебурнета, состоящего из одного правительственного хоста, преподносился как нечто прекрасное. Во время дискуссии в комментариях, идея государственной цензуры всех пересылаемых сообщений была встречена с неодобрением. Автор оригинальной статьи искренне возмущен тем что большинство использовало систему кармы, чтобы остановить написание статей про прелести тоталитарного контроля всей страны. В ответ, ему было предложено задуматься над принципом
Никакой свободы врагам свободы
Который, однако, не всеми был понят в историческом контексте. Поэтому хотелось бы дать развернутое определение в ответ на статью с критикой этого принципа, и предоставить сообществу решить, так ли уж он плох.
Начнем с краткого исторического экскурса. Идеи свободы слова, собраний, печати, предпринимательства, отказа от налогов без представительства, права защищать свою жизнь и имущество, восходят к «новому времени» (примерно с 16ого века), к раннему либерализму. В этот период происходил распад старых средневековых феодально-крепостных систем, а более свободная система отношений, только зарождалась и была неочевидной. Такие мыслители как Джон Локк или Адам Смит, высказывали поистине нечто новое, не принятое раньше. Поэтому, предложив идею свободы слова, они не задумывались о такой простой вещи, а как впоследствии свободу слова защитить? Задумываться об этом казалось слишком рано.

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

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

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

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

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

Всем удачных выходных!

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

Let's block ads! (Why?)

Обучающие видео иранских хакеров утекли в сеть

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

Речь идёт о группе ITG18, известной также как APT35 или Charming Kitten. Это одно из объединений, которые финансируются иранским правительством. Группа неправильно настроила доступ к своим серверам, открыв для хранящейся на них информации доступ на три дня. Специалисты компании IBM X-Force обнаружили около 40 Гб обучающих видео длительностью в почти пять часов.

Как сообщает HotHardware, обучающие видео были записаны примерно за день до загрузки на сервер. В них демонстрируется, как получить доступ к аккаунту электронной почты при помощи заранее подготовленного списка учетных данных. На роликах хакеры пытаются взломать аккаунты чиновников Госдепартамента США и военных Греции. Кроме того, из найденных материалов стало известно, что у ITG18 был доступ к электронной почте и учетным записям в социальных сетях. Хакеры использовали информацию для входа в аккаунты и фильтровали контакты, фотографии и документы на Google Drive.

Как указывает HotHardware, в настоящее время хакеры нацелены на фармацевтические компании и президентские выборы в США. Многие из их атак также проходили после принятия решения о продлении санкций против Ирана. По словам исследователей в области безопасности, «ITG18 продемонстрировала, что выполняет операции для удовлетворения множества различных долгосрочных целей, которые соответствуют стратегическим интересам Ирана».

Let's block ads! (Why?)

Разбор: что нужно знать о коротких продажах на бирже и связанных с ними рисках

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

О какой проблеме идет речь


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

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

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

Что может пойти не так


Хемптон объясняет проблему на примере:

Допустим, существует два золотых рудника. Капитализация каждого из них примерно $250 млн, и считается, что запасы золота в каждом составляет примерно 1 млн унций. Извлечь его планируется в период с 2024 по 2037 год.

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

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

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

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

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

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

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

Как противостоять подобным ситуациям


По мнению Джона Хемптона, существует два способа противостоять подобным ситуациям. Первый и доступный частным биржевым торговцам – не вкладывать в спекуляции с короткими продажами значительные средства, выделять 0,1% капитала.

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

Фонды могут сами заниматься таким анализом или прибегать к услугам компаний, вроде Muddy Waters Research. И даже в этом случае им остается надеяться на то, что им удастся сбить цену акций явно переоцененной компани на 30-40%, а также подготовиться к возможным последствиям «шорта на 5%» – если стратегия не сработает сразу.

Читайте обзоры, аналитику рынков и инвестидеи в Telegram-канале ITI Capital

Полезные ссылки по теме инвестиций и биржевой торговли:


Let's block ads! (Why?)

Ракета от Амперки, часть 4: Сборка двигателя и огневые испытания

Однако, снова здравствуйте.
Прошла еще одна неделя — делимся результатами работы над нашей ракетой.

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

Склеивание шашек


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

Сборка двигателя


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

На противоположный конец трубы-корпуса сопло надевается с трудом, поэтому будем садить «на горячую». Фиксация будет осуществляться за счет трех винтов М5, установленых под 120 градусов.
Но для начала надо просверлить сопло под посадку винтов. Обычные сверла, имевшиеся в запасе, наотрез отказались сверлить нержавейку, рейд в ближайший магазин инструментов пополнил арсенал кобальтовыми сверлами, но неумелая рука сразу сломала два из них под диаметр 3мм. Звоним дядьке Кириллу и интересуемся, чем же сверлить эту сталь. Советы были примерно такие:

  • кобальтовые сверла — выполнено
  • низкие обороты
  • большое усилие подачи
  • СОЖ

В качестве СОЖа предлагалось использовать олеиновую кислоту в любом виде. У нас из доступного под рукой оказалось только подсолнечное. Важно при сверлении не уменьшать давление на материал и не повышать скорость вращения сверла, так как нержавейка при этом в точке контакта наклёпывается и резко повышает свою твердость, вследствие чего потом ее просверлить практически невозможно этим же сверлом. Учитывая все эти советы, отверстия были просверлены без особых проблем при помощи ручного шуруповерта в два прохода: сначала сверлом 3мм, затем 5.2мм.

В трубе же, она, уже просто стальная (Ст30, вроде), просверлилась без особых проблем, в отверстиях нарезали резьбу.

Абляция


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

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

Огневые испытания


Тесты ракетных двигателей — крайне опасное мероприятие, поэтому к месту их проведений и подготовке нужно отнестись максимально серьезно. Для наших испытаний мы выбрали заброшенный город-призрак Адуляр — бывший военный городок №310 ВЧ 51850 километрах в 80 от Москвы. Одним из факторов, повлиявших на такой выбор стало то, что военная часть обслуживала ЗРК С-51 «Беркут», чтобыло знаковым для нас — ракетостроителей-дилетантов.
За день до испытаний я съездил в Адуляр на разведку. Город действительно оказался давно заброшенным и необитаемым, однако территорию облюбовали различного вида киношники (к слову, на момент разведки на месте находилась съемочная группа какого-то музыкального клипа), а также страйкболисты (о чем свидетельствовало большое количество шариков для приводов) и любители огнестрела (повсюду лежаль гильзы от винтовок, пистолетов и охотничьих ружей). Основная достопримечательность — две пятиэтажки, стоящие друг напротив друга.

На следующий день мы в полном составе выдвинулись на испытания. По прибатию на место выбрали площадку для проведения испытаний, где была возможность установить камеры и при этом спрятаться за укрытия. Безопасность — прежде всего в таких делах. Установили стенд и зафиксировали его, вбив штырями в грунт, провели проверку, в ходе которой убедились, что всё работает в штатном режиме и не повредилось при транспортировке.
Затем зафиксировали двигатель на каретке стенда, еще раз убедились в отсутствии людей в опасной зоне, заняли места в укрытии и произвели зажигание.
Все произошло настолько быстро, что мы даже не успели удивиться или испугаться. Через несколько миллисекунд после старта запала был слышен свист, который резко прервался сильным хлопком.

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

Измерительный стенд показал крайне быстрый рост усилия тяги до 135 кг, при условии, что датчики были расчитаны на 100кг (2 по 50кг). Нельзя точно отверждать, что это значение было максимальным, однако, однозначно, не менее указанного. Кроме того, из-за возникшей ударной нагрузки каретка сломала одну из калёных направляющих диаметром 10мм, а также деформировалось коромысло, распределявшее нагрузку между двумя тензодатчиками. Последние тоже пострадали, так как оказались значительно выгнутыми и больше не реагировали на давление.

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

Видео по статье можно посмотреть здесь:

Let's block ads! (Why?)

[Перевод] Путь к пониманию шаблонных литералов в JavaScript

Спецификация ECMAScript, вышедшая в 2015 году (ES6), добавила в JavaScript новую возможность — шаблонные литералы (template literals). Шаблонные литералы дают нам новый механизм создания строковых значений. Этот механизм отличается множеством мощных возможностей, среди которых — упрощение создания многострочных конструкций и использование местозаполнителей для внедрения в строки результатов вычисления выражений. Кроме того, тут имеется и ещё одна возможность — теговые шаблоны (tagged template literals). Это — расширенная форма шаблонных литералов. Теговые шаблоны позволяют создавать строки с использованием выражений, находящихся внутри строк, и с применением особых функций. Всё это расширяет возможности программистов по работе со строками, позволяя, например, создавать динамические строки, которые могут представлять собой URL, или писать функции для тонкой настройки HTML-элементов.

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

Объявление строк


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

Строку в JavaScript можно представить как последовательность символов, заключённую в одинарные кавычки (' '):

const single = 'Every day is a good day when you paint.'

Ещё один вариант объявления строк заключается в использовании двойных кавычек (« «):
const double = "Be so very light. Be a gentle whisper."

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

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

// Экранирование одинарных кавычек в строке, ограниченной одинарными кавычками
const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross'

// Экранирование двойных кавычек в строке, ограниченной двойными кавычками
const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross"

console.log(single);
console.log(double);

Вызов пары методов log() приведёт к тому, что в консоль попадут две одинаковых строки.
"We don't make mistakes. We just have happy accidents." - Bob Ross
"We don't make mistakes. We just have happy accidents." - Bob Ross

Шаблонные литералы, с другой стороны, объявляют с использованием обратных кавычек (` `):
const template = `Find freedom on this canvas.`

Здесь не нужно экранировать одинарные или двойные кавычки:
const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross

Но обратные кавычки в таких строках экранировать необходимо:
const template = `Template literals use the \` character.`

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

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

Многострочные строки


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

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

const address =
  'Homer J. Simpson' +
  '742 Evergreen Terrace' +
  'Springfield'

Данный подход может позволить разбивать длинные строки на небольшие фрагменты и располагать их в текстовом редакторе на нескольких строках. Но это никак не влияет на то, какой получится итоговая строка. В данном случае значение строковой константы будет располагаться в одной строке. Те части, из которых собрано строковое значение, не будут разделены символами перевода строки или пробелами. Если вывести в консоль константу address, то там появится следующее:
Homer J. Simpson742 Evergreen TerraceSpringfield

Ещё один подход к записи подобных строк в редакторах кода заключается в использовании символа обратной косой черты (\), который ставится в конце фрагментов строк, и после которого, с новой строки, располагаются новые фрагменты:
const address =
  'Homer J. Simpson\
  742 Evergreen Terrace\
  Springfield'

При таком подходе сохраняются, например, пробелы, находящиеся перед фрагментами строки, но значение переменной, если вывести его в консоль, снова будет представлено единственной строкой:
Homer J. Simpson  742 Evergreen Terrace  Springfield

Создать настоящую многострочную строку можно, используя символ перевода строки (\n):
const address =
  'Homer J. Simpson\n' +
  '742 Evergreen Terrace\n' +
  'Springfield'

При выводе в консоль строкового значения, хранящегося в address, это значение будет занимать несколько строк:
Homer J. Simpson
742 Evergreen Terrace
Springfield

Правда, использовать символ перевода строки для создания многострочных строк не особенно удобно и просто. С другой стороны, создание многострочных строк с использованием шаблонных литералов выглядит гораздо проще и удобнее. Не нужно конкатенировать строки, не нужно использовать символ новой строки или обратную косую черту. Для создания многострочных строк с использованием шаблонных литералов достаточно просто, в конце очередного фрагмента строки, нажать клавишу Enter, и продолжить вводить следующую строку шаблонного литерала:
const address = `Homer J. Simpson
742 Evergreen Terrace
Springfield`

Если вывести эту константу в консоль, то выглядеть текст будет так же, как в редакторе:
Homer J. Simpson
742 Evergreen Terrace
Springfield

Тут надо учитывать то, что если между символами обратных кавычек содержатся пробелы, используемые для выравнивания кода, эти пробелы попадут в итоговый шаблонный литерал. Рассмотрим следующий пример:
const address = `Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield`

Хотя такой стиль написания кода упрощает его чтение, то, что попадёт в консоль после его вывода, будет выглядеть не очень-то привлекательно:
Homer J. Simpson
                 742 Evergreen Terrace
                 Springfield

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

Интерполяция выражений


Раньше, до выхода ES6, для создания динамических строк, в формировании которых участвовали значения переменных или выражения, использовалась конкатенация:
const method = 'concatenation'
const dynamicString = 'This string is using ' + method + '.'

Если вывести dynamicString в консоль, то получится следующее:
This string is using concatenation.

При использовании шаблонных литералов выражения можно внедрять в строку с использованием местозаполнителей. Местозаполнитель представляет собой конструкцию вида ${}. При этом всё, что содержится в фигурных скобках, рассматривается как JavaScript-код, а всё, находящееся за пределами этой конструкции, рассматривается как строка:
const method = 'interpolation'
const dynamicString = `This string is using ${method}.`

При выводе dynamicString в консоль получится следующий результат:
This string is using interpolation.

Распространённый пример встраивания значений в строки — это создание динамических URL. Использование для этой цели конкатенации приводит к появлению громоздких и неудобных конструкций. Например, вот функция, которая генерирует строку доступа OAuth:
function createOAuthString(host, clientId, scope) {
  return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope
}

createOAuthString('https://github.com', 'abc123', 'repo,user')

Если вывести в консоль результат работы этой функции, то получится следующее:
https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

При использовании интерполяции программистам больше не нужно внимательно следить за кавычками, ограничивающими фрагменты строки, и за тем, где именно расположен оператор конкатенации. Вот — тот же пример, переписанный с использованием шаблонных литералов:
function createOAuthString(host, clientId, scope) {
  return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
}

createOAuthString('https://github.com', 'abc123', 'repo,user')

Результат работы функции будет таким:
https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

Для того чтобы убрать пробелы в начале и в конце строки, создаваемой с помощью шаблонного литерала, можно воспользоваться методом trim(). Например, в следующем фрагменте кода для создания HTML-элемента с настраиваемой ссылкой используется стрелочная функция:
const menuItem = (url, link) =>
  `
<li>
  <a href="${url}">${link}</a>
</li>
`.trim()

menuItem('https://google.com', 'Google')

Из итоговой строки будут удалены начальные и конечные пробелы, что позволит обеспечить правильность рендеринга элемента:
<li>
  <a href="https://google.com">Google</a>
</li>

Интерполировать можно целые выражения, а не только переменные. Например — как здесь, где в строку встраивается результат сложения двух чисел:
const sum = (x, y) => x + y
const x = 5
const y = 100
const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`

console.log(string)

Здесь объявлена функция sum() и константы x и y. После этого в строке используется и функция, и эти константы. Вот как выглядит константа string, выведенная в консоль:
The sum of 5 and 100 is 105.

Этот механизм может оказаться особенно полезным при использовании тернарного оператора, который позволяет проверять условия при формировании строки:
const age = 19
const message = `You can ${age < 21 ? 'not' : ''} view this page`
console.log(message)

Константа message, выведенная в консоль, может менять в зависимости от того, больше или меньше 21 значение, хранящееся в age. Так как в нашем примере это значение равняется 19, в консоль попадёт следующее:
You can not view this page

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

Теговые шаблоны


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

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

function tag(strings, ...expressions) {
  console.log(strings)
  console.log(expressions)
}

Если при создании тегового шаблона воспользоваться функцией tag, то может получиться такая конструкция:
const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`

Так как в функции tag выполняется вывод в консоль strings и expressions, при выполнении этого кода в консоль попадёт следующее:
["This is a string with ", " and ", " and ", " interpolated inside."]
[true, false, 100]

Видно, что первый параметр, strings, это массив, содержащий все строковые литералы:
"This is a string with "
" and "
" and "
" interpolated inside."

У этого аргумента ещё есть свойство raw, к которому можно обратиться как к strings.raw. Оно содержит строку, в которой не были обработаны управляющие последовательности. Например, \n будет просто символом \n, а не командой перевода строки.

Второй аргумент, ...expressions, это массив, содержащий все выражения:

true
false
100

В результате оказывается, что функции тегового шаблона tag передаются строковые литералы и выражения. Обратите внимание на то, что функция не обязана возвращать строку. Она может работать с переданными ей значениями и возвращать всё что угодно. Например, у нас может быть функция, которая ни на что не обращает внимания и просто возвращает null. Именно так написана функция returnsNull в следующем примере:
function returnsNull(strings, ...expressions) {
  return null
}

const string = returnsNull`Does this work?`
console.log(string)

В результате выполнения этого кода в консоль попадёт следующее:
null

В качестве примера действия, которое можно выполнить в теговом шаблоне, можно привести внесение изменений в каждое из выражений, например, таких изменений, которые заключаются в помещении выражений в HTML-теги. Создадим функцию bold, которая добавляет теги <strong> и </strong> в начало и в конец каждого выражения:
function bold(strings, ...expressions) {
  let finalString = ''

  // Проходимся по всем выражениям
  expressions.forEach((value, i) => {
    finalString += `${strings[i]}<strong>${value}</strong>`
  })

  // Добавляем последний строковой литерал
  finalString += strings[strings.length - 1]

  return finalString
}

const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`

console.log(string)

Здесь, для обхода массива expressions, используется цикл forEach. Каждый элемент заключается в теги <strong></strong>.
This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.

В популярных JavaScript-библиотеках можно найти несколько примеров использования теговых шаблонов. Так, в библиотеке graphql-tag используется шаблонный литерал gql для разбора строк запроса GraphQL и преобразования их в абстрактное синтаксическое дерево (abstract syntax tree, AST), понятное GraphQL:
import gql from 'graphql-tag'

// Запрос для получения имени и фамилии пользователя 5
const query = gql`
  {
    user(id: 5) {
      firstName
      lastName
    }
  }
`

Функции теговых шаблонов используются и в библиотеке styled-components, что позволяет создавать новые компоненты React из обычных элементов DOM и применять к ним дополнительные CSS-стили:
import styled from 'styled-components'

const Button = styled.button`
  color: magenta;
`

// <Button> теперь может использоваться как компонент

Кроме того, можно пользоваться стандартным методом String.raw, применяя его к теговым шаблонам для того чтобы предотвратить обработку управляющих последовательностей:
const rawString = String.raw`I want to write /n without it being escaped.`
console.log(rawString)

В консоль после выполнения этого кода попадёт следующее:
I want to write /n without it being escaped.

Итоги


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

А вы пользуетесь шаблонными литералами?

Let's block ads! (Why?)

Новости Blender3d

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

1. Как многим известно, Блендер теперь обзавелся LTS версиями, поддержка которых будет длиться 2 года.

Текущая LTS-версия 2.83. И как раз вчера вышло обновление 2.83.3 с исправлением разных ошибок

2. Помимо этого версия 2.90 перешла в стадию beta, а 2.91 в стадию alpha

Продолжают вносится изменения и новые опции в версию 2.9. Здесь отчет за прошлую неделю . В основном изменения касаются интерфейса и UV-редактора.

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


  • Редактирование штрихов Grease Pencil с помощью кривых. Название говорит само за себя. В Blender сейчас нельзя редактировать линии созданные с помощью Grease Pencil, как кривые Безье по аналогии с Illustrator и другими векторными программами. Что очень печально. Надеюсь, это удастся исправить
  • Улучшение производительности ввода-вывода для больших файлов. Речь идет про файлы OBJ, PLY, STL
  • Поддержка интерактивности в VR через OpenXR Action System. Не так давно Blender добавил возможность просматривать сцены в VR. Сейчас речь идет о том, чтобы позволить делать в VR что-то полезное
  • Информация о симуляции жидкостей. Поддержка вывода визуализации векторов скорости, внешних сил и т.д. в симуляции жидкостей
  • Many Light Sampling. Должно помочь в рендеринге с многими источниками света. Начинали делать, но так и не доделали в GSoC 2018. Сейчас пытаются доделать и внедрить в Блендер.
  • Volumetric Soft Body Simulation. Улучшенная система симуляции взаимодействия мягких тел

5. Кто знает английскую речь, может послушать еженедельное шоу Blender Today Live (вопросы и ответы) с блистательным Pablo Vazquez

На этой неделе больше особых интересностей нет. До следующей недели.

Ну и, конечно, призываю поддерживать Blender кодом и материально

Let's block ads! (Why?)

Онлайн-лекция «Реактивные и нативные приложения на Java Spring и Quarkus»

image

28 июля приглашаем на онлайн-лекцию о разработке приложений на Java Spring, Quarkus, Vert.x и GraalVM с деплоем в MicroK8s.

В программе лекции: Сергей Кошкинов и Андрей Смирнов покажут процесс создания приложения на Java-фреймворке Quarkus с деплоем в MicroK8s. А также сравнят производительность и потребления памяти приложений на Spring WebFlux, Spring Boot, Quarkus, Quarkus+Vert.x и скомпилированными в native code с помощью GraalVM.

Зарегистрироваться

Об экспертах


Сергей Кошкинов — разработчик в «МегаФоне», Oracle Certified Professional Java Programmer.

Андрей Смирнов — разработчик в «МегаФоне». В прошлом преподавал программирование в ННГУ им. Н. И. Лобачевского.

По теме:

Let's block ads! (Why?)

Расшифровка: почему у монетизаторов нет души, а токсичные члены команды — самые эффективные


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

7 июля в нашем инстаграм-аккаунте выступил Вячеслав Дреер, гейм-дизайнер и продюсер игр с 12-летним стажем. Слава работал в игровых подразделениях веб-мани, mail.ru, Фотостраны и принимал участие в более, чем 50 других проектов.

Во время эфира он без буллшита и увиливаний рассказал:

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

Делимся с вами расшифровкой.

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

Основная позиция, с которой я начинал – это гейм-дизайнер. После этого я вырос до менеджера, некоторое время занимался монетизацией, 3 раза был на позиции продюсера и руководителя направления. Принимал участие в 50+ игровых проектах, на различных площадках – мобильных, социалках, браузерках, клиентских играх. Такой у меня опыт. Максимальное количество людей, которыми руководил – 32. Основные компании, с которыми я работал – MAIL.RU, Фотострана, Аватарика, дочернее отделение WebMoney. И еще много мелких.

Есть ли монетизация после лутбоксов – кроме battle pass с лутбоксами?


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

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

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

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


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

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

Они запускают проект, в нем, допустим, 3000 пользователей. Они видят, что возвраты 30-го дня – 25%. Это говорит о том, что, если они нальют гораздо больше трафика, у них будет гораздо больше пользователей.

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

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

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

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

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

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


Эти игры берутся от хороших людей. Периодически случается так, что компании из 3-4 людей, которые горят играми (хотят их делать, для них игры – это святое и главное) берут и делают игры.

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

Недавно был пример: игра была Топ-4 во всем мире среди AR-игр и приносила очень скромные деньги. Идея была в том, что пользователь поиграет в нее, проникнется и сам заплатит. Но пользователь это делает не очень часто, если его не мотивировать.

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

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

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

В стартовом пакете будет набор золота и кристаллов с волшебным мечом, это все стоит 2 доллара. Мы смотрим, как часто этот пакет показывается пользователю. Собираем статистику: в игру зашло, например, 12К новичков, и из них только 500 увидело предложение? Это мало. Увидеть должны все 12К, которые зашли. Хотя еще надо сделать поправку на то, чтобы пользователь прошел туториал и увидел предложение после него (допустим, туториал пройдет 9К из 12 – все 9К должны увидеть предложение).

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

Дальше мы смотрим на то, что будет после того, как пользователь купит предложение – изменится ли качество его игры? Может быть, меч, который входит в него, ничего особенного и не дает игроку – тогда надо задать вопрос: «Зачем вы сделали такое предложение, которое пользователю неинтересно покупать»?

Разработчик отвечает, что не хочет дисбаланса, или что-то подобное. Но ведь он мог дать что-то по-настоящему полезное! Он хотел создать «куклу» — условно-годное предложение, которое на самом деле не годное; думал, что это будут покупать. Это неправильный подход.

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

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

Насколько этична монетизация, влияющая на игровой процесс?


Максимально этична.

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

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

Но если в монетизацию заложено правило типа «1 час фарма = 1 доллар», то через 10 часов школьник хоть и нафармит эти условные 10 долларов (и будет чувствовать, что он молодец), ты придешь и просто вложишь эти 10 долларов, и будешь наравне с ним.

Или, если хочешь его побить с гарантией, вложишь 20. На следующий день он будет более мотивированно фармить.

Ты приходишь с работы, ты устал, тебе плохо – ты меньше всего хочешь сейчас проигрывать 4 катки, чтобы настроение падало еще сильнее. Ты хочешь побеждать и релаксировать, и денежка поможет тебе это сделать.

В каких случаях в проекте нужны монетизаторы?


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

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

Во-вторых, когда надо повысить доходы. Допустим, они постепенно росли, пока ты прикручивал к продукту функционал – это всегда дает рост. Но в один момент они перестают расти – допустим, когда контента уже года на 4.

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

В целом, все просто. Если есть проект, и нужно, чтобы он больше зарабатывал – то нужен монетизатор.

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


Это правдиво. Каждый раз, когда меня приглашают в новый продукт, я запускаю 4 игровые сессии. Мне на это обычно нужно 2-2,5 дня. Я проживаю все эти 4 типа жизни параллельно.

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

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

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

И офисный сотрудник: у меня тяжелый день, я просто хочу отдохнуть. Мне нафиг не нужно еще чем-то нагружать свой мозг, я хочу просто заучить привычные схемы и билды, и побегать. И я ни в коем случае не хочу, чтобы меня нагибали. Так как я добросовестный сотрудник, у меня нет возможности заходить по 10 часов в игру и фармить. Если важные игровые эвенты приходятся, например, на 14 или 16 часов дня, офисный сотрудник сразу отваливается – ему игра не будет интересна, он не сможет конкурировать с другими.

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

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

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


С неграмотным сбором аналитики я сталкивался за последние 2 года довольно часто. В моей любимой компании, где я работал раньше, такого слабого отношения к аналитике не было. Но, как правило, людей устраивает общее количество аналитики в Unity Analytics / AppStore Connect / Firebase, и они глубоко не копают.

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

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

Едем дальше: может быть, люди зашли, но застопорились на 3 шаге из 12? Надо залезть в баланс и посмотреть, что там. Может, там что-то сложнопроходимое, что нужно переделать или сделать так, чтобы эту штуку можно было пройти за 0.50$. Возможность выбора игроком между днями фарма и небольшим взносом это нормально.

Кроме этого, конечно, есть еще огромное количество аналитики, которая неправильно собирается.

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

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

Почему нельзя делать справедливые игры, где у всех равные возможности?


Попробуйте примерить эту ситуацию на себя. Я к вам подхожу и говорю — а заплатите 10$. Вы говорите – а что мне за это будет? А ничего не будет, только скин красивенький, и все. Ты не будешь сильнее, ничего не изменится.
Ты скажешь – не, не хочу. И будешь прав! Пользователи платят за что-то ощутимое. Женщины хотят быть самыми красивыми, мужчины хотят быть самыми сильными. Вот если я предложу меч, который на 20% сильнее обычного — не надо на 200%, 20% достаточно — ты заплатишь, и будешь знать, что у тебя одна из вещей комплекта на 20% круче.

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

Ты тогда либо терпишь еще полгода без бонуса, либо покупаешь ее за $40. Конечно, это не должно создавать супер-дисбаланс. Не должно быть такого, что ты что-то покупаешь за 10$ и идешь бить весь сервер. +20% силы за вещь, стоящую денег – это нормально: если человек соберет несколько таких вещей, то он сможет побить с гарантией одного другого игрока, но не двух.

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

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

Либо ты тратишь 50$ и два месяца фарма пропускаешь, оказываясь наравне с теми, кто пришел в игру раньше и фармил эти два месяца, либо сам фармишь.

Самый главный человек в игровой команде – это *игровой* программист, почему так?


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

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

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

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

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


На самом деле, всякая «дальнейшая перспектива IP» — это красивые слова, имеющие мало общего с реальностью. Денег много не бывает. Видишь, что можешь получить деньги – получай деньги.

Дополнительный контент для полноценной игры – сравнительно недавно появился как феномен, примерно с очередного Assassin’s Creed. Там прикрутили к ААА-игре искусственный баланс, который требовал фармить, но можно было заплатить еще и играть комфортнее.

Может, это и не совсем здорово. Но, если это эффективно – а, раз так считает Ubisoft, то это должно быть эффективно – то они молодцы.

Недостаток такой модели в том, что, действительно, после реализации такой вещи в твоем продукте падает лояльность пользователей. Если следующий продукт сделать хуже – действительно получится так, что ты зарезал золотую курицу. Это не повлияет на уже существующие части Assassin’s Creed, но повлияет на будущие.

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

«Лояльность сообщества» – и это измеренная цифра, в неё можно верить – выражает мнение всего 5% игроков. Все, кто активен на форуме – и нытики, и хвалильщики – это 5% от всех игроков.

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

У нас были такие ситуации, когда пользователь громко орал на форуме «LITERALLY UNPLAYABLE, ВЫ ИСПОРТИЛИ МНЕ ВСЮ ИГРУ, ДА ЧТОБЫ Я ЕЩЕ ИГРАЛ У ВАС». Тогда я просил программиста отслеживать логи этого персонажа.

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

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

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

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

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

Если коротко: человек что-то купил и верит, что купил целиком – мы его обманываем?


Да. И это не очень хорошо.

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

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

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

Залезьте в какую-нибудь игру от Blizzard и её EULA, посмотрите, как конкретно игроков обманывают они. Они уже более 16 лет бодаются с исками от пользователей – из WoW, из Diablo.

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

Существуют ли люди, которые в одиночку создали игры мирового уровня?


Да, существуют.

Когда-то давно, на заре становления индустрии, был IceFrog – создатель DotA. Первая DotA была просто картой, созданной в редакторе для WarCraft III – там можно было самому дизайнить, прописывать скрипты.

У него была идея, и он создал шедевр мирового уровня. IceFrog на каждом обновлении (где были бы, допустим, два новых героя) зарабатывал по 50 тысяч долларов. Потом этого он ушел, игра развилась и спасла WarCraft III от загибания. Самого IceFrog перекупили Valve, и он создал DOTA 2 – но на старте он был один.

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

Второй пример это Notch. Это программист, который создал Minecraft — по большей части, один. До Minecraft он сделал 50 продуктов, о которых никто ничего не знает и не слышал, но только Minecraft загремел на весь мир, и в 2012 Notch вошел в десятку самых влиятельных игровых компаний мира (будучи одним человеком), на седьмое место.

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

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

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

Есть одиночки мирового уровня, есть те, кто просто выживает сам по себе. Важно понять вот что: компания из 300 людей, где самый низкооплачиваемый сотрудник получает 3000 евро (и это все умножается на налоги) обязана зарабатывать огромные суммы, чтобы просто существовать. А маленькая команда из одного человека может запускать мелочь, которая приносит 200 тысяч рублей в месяц в течение, допустим, трех лет.

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

Успешные одиночки существуют: программисты, художники, гейм-дизайнеры. Даже маркетологи: он заказывает какой-нибудь проект и знает, как наливать на него трафик. Сейчас много контор, которые собирают «под ключ», допустим, игры типа «три в ряд» по 10 тысяч долларов. Ты такую купил, знаешь, как работать с трафиком – и льешь его. Если видишь косяки – студия быстро апгрейдит проект в тех местах, которые ты называешь. Одиночки гораздо лучше выживают, потому что они более гибки, и их не интересуют миллиарды – им достаточно небольших денег, чтобы быть на плаву и считаться успешными.

Можно ли создать игру почти бесплатно?


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

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

Кто такой хороший менеджер, как им стать?


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

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

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

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

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

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

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

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

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

Как набрать крутую команду?


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

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

Как правило, команда у тебя уже есть, и ты в ней живешь и работаешь. Ты должен понимать, кто в неё входит: допустим, есть 8 программистов – 4 клиентских и 4 серверных, 2 аниматора, 2 иллюстратора, 2 дизайнера, 2 геймдиза (один – проджект), плюс 1 тестировщик и левел-дизайнер.

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

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

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

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

Но при этом необязательно самому быть великим программистом, чтобы завлечь крутого программиста: нужно просто быть крутым человеком, знающим продукт от и до. Допустим, есть программист, который начинает: «я твой код делал, я игровой программист!» Ты говоришь: «Хорошо, ты способен сделать весь продукт? Ты можешь в него надо добавить гейм-дизайнерские составляющие, монетизацию, маркетинг прикрутить? Нет. Но я это могу. Давай работать в команде. Ты делаешь свою часть работы хорошо, я – свою часть. Тогда проект выстрелит, и каждому из нас капнет достаточно денег, чтобы мы не чувствовали себя обманутыми». Человек понимает, что он действительно хороший программист, но при этом не шарит в маркетинге и дизайне, поэтому он скажет: да, давайте работать.

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

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

Два самых главных качества менеджера?


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

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

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

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

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

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

И всегда нужно брать ношу по себе. Я часто коммуницирую с людьми, которые сидят на позициях топ-менеджеров, и большинство из них сидит еще и на антидепрессантах. Они когда-то взяли груз, который не могут вынести. Ведь как работает продвижение по карьерной лестнице: у тебя есть команда, допустим, из 20 человек, и вы даете какой-то результат. У вас есть 7 проектов, вы их ведете, все хорошо, компания получает деньги. И тебе говорят: возьми теперь не 7, а 10 проектов, и в команду добавляют 40 людей. Но для того, чтобы вести 20 людей и 7 проектов, ты уже тратил в день не 8, а 12 часов, только не говорил никому. Ты много работал, тебе работа даже нравилась. А теперь придется работать еще больше. На первых порах ты радуешься: вау, я получил повышение, я крут. А потом ты осознаешь, что у тебя 16 рабочих часов на дню. Ты где-то берешь эти дополнительные часы, и тебя это начинает пожирать. Уровень стресса взлетает. Люди, которые наверху, вынуждены работать каждую секунду. Они головой всегда на работе, и, если появляется свободная минута, они тут же пытаются вернуться на нее же. Их уровень стрессоустойчивости обязан быть высоким.

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

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

У меня был пример, когда мне давали команду из программистов-джунов, их было 5, плюс 1 миддл. Периодически мы сталкивались с проблемами, на которые джуны тратили дня по 4 – именно от нехватки опыта. В этом случае спасало то, что у меня остались связи с мощными игровыми программистами из моей предыдущей компании. Я просто иногда спрашивал у них, как они решают у себя ту или иную проблему. За 5 или 10 минут давался такой ответ, после которого джуны говорили — вот, это то, чего не хватало, через 2 часа все сделаем. И делали. То же с художниками; если у вас накоплен пул из удаленных художников, можно в любое время, когда собственный художник заболел, перегружен и т.д., обратиться к ним и получить качественный материал за денежку.

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

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

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

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

Что делать, если проработал в индустрии 8 лет, но нет особых достижений? Какие выводы по себе делать, как анализировать свою работу? Стоит ли продолжать? Нужны ли такие люди компаниям?


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

Я работал на прибыльных проектах, но я их не создавал: просто работал в составе команды, которая работала на результат. 2 раза я повышал продукт на 50% (то есть, один и тот же продукт заставил приносить на 50% больше через месяц, и еще раз его же – через полгода). Каких-то суперуспехов у меня нет. Я был генеральным продюсером, но только небольших проектов. Я был руководителем игрового направления (одного из трех, там было 9 проектов, за которыми надо было следить, чтобы они приносили денежку).

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

Такие люди и делают основную, фундаментальную работу. Если вы — такой человек, значит, на вас держится кусок компании. Если в компании будет 150 авантюристов, которые каждый день будут выдавать какие-то новые идеи, хотеть зарабатывать не меньше 5 миллионов долларов за игру в месяц, требовать, чтобы все продукты были мирового уровня и так далее — компания развалится. За спиной каждого инициативного человека должны стоять те, кто действительно умеет доделывать работу до конца, и делать ее качественно. Если вы – такой человек, то это хорошо. В этом нет ничего зазорного, и вы нужны компании.

По статистике, примерно 85% молодых с горящими глазами успокаивается и становятся такими же крепкими серединками. А еще, тоже по статистике, один человек в своей жизни может создать только один гениальный продукт. Все гении, единожды создавшие что-то крутое, не могут повторить свой успех. Вы можете сами это проверить при более глубоком рассмотрении. Да, есть компании, чей учредитель когда-то создал «продукт №1», а через 8 лет появился «продукт №2», который стал не хуже; но, если присмотреться, то получится, что второй продукт по большей части создавали другие люди. Может быть, он их обучил, или они уже пришли в компанию крутыми, но создавали именно они.

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

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

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


Я расскажу историю. В геймдев я пришел в 2008 году, до 2009 работал удаленно; я приехал в Москву и в августе был принят на работу в Аструм Онлайн, а до этого не был в штате.

До 2016 года современного понятия «офисной этики», и других вещей, не было. Был просто набор энергичных людей, которые любили игры и хотели сами сделать себе крутую игру, чтоб другие игроки им деньги приносили. Это – логика всех игроков, которые до этого вкладывались в другие проекты.

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

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

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

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

Да, действительно, «токсичные люди» есть. Но большинство людей на этой модной волне начали, не разбираясь, записывать в «токсичных» всех. Если человек не высыпается из-за того, что у него дома ребенок маленький, и приходит на работу мрачным, и вякает раз на кого-то – всё. Он «токсичный», с ним не надо дружить. У другого человека кошка умерла – он тоже в подавленном настроении приходит, а к нему лезут: «жизнь веселая, не грусти»! Он в ответ делает посыл, и результат тот же.

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

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

Я часто привожу еще и такой пример. Представьте себе большой красивый лайнер. На борту играет музыка, люди в белых фраках, всё красиво, танцуется мега-вальс. Все хорошо, шампанское, атмосфера полной гармонии. Вдруг в палубе открывается люк, и оттуда со словами «КАКОГО ХРЕНА» вылезает грязный, одуревший от духоты механик. Из люка валит дым, механик матерится на всех. Он восемь часов что-то чинил на этом корабле по уши в мазуте, чтобы весь корабль не утонул, и не понимает этих людей. И они все такие: «Ой, какой же ты токсичный, ты не понимаешь, что весь мир состоит не только из негатива? Смотри на позитивную сторону!»
А теперь представьте, что на корабле будут только красивые люди во фраках с блестками, а механика – не будет. Либо корабль пойдет ко дну, либо половине красивых людей придется спуститься под палубу и работать вместо механика.

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

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

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

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

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

Зачастую они являются самыми хорошими сотрудниками. Они со словами «ДА ВАШУ МАТЬ» чинят то, что понаделали позитивные люди в белых рубашечках, которые в случае косяка хлопают глазками и говорят: «Ой, мы же одна команда, давай, ты нам поможешь?»

Какие книги и лекции надо почитать перед тем, как делать свою игру?


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

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

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

На моем старте карьеры, примерно через 3 года после того, как я начал заниматься геймдевом – у нас была студия из нескольких команд. Менеджеры сидели в одном кабинете, и туда, как правило, приходил генеральный продюсер, и говорил: «Ребятушки, а кто в этом месяце делает план по баблу?» Одни говорят: «Мы делаем». Другие говорят: «О, а мы еще больше делаем». А третьи: «Ой, а у нас все плохо». Генеральный и говорит третьим: «Вы-то, родные, и поедете на конференцию, людей учить будете! А остальные – работайте, к вам нет претензий».

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

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

Самое главное: во-первых, пока ты готовишь из программиста медийного представителя, он теряет в скилле; во-вторых, он на этой конференции тут же получит штуки 4 предложений о работе с удвоением зарплаты, потому что хорошо подал себя и рассказал историю успеха, которую другие желают повторить. Еще он тут же создаст канал на YT, где повторит прочитанные лекции и у него уже канал будет зарабатывать. Дальше он будет не код писать, а учиться делать новые конференции. И на побуждение вернуться к работе он ответит: «слушай, у меня тут канал уже приносит почти мою зарплату, да и предложения вот лежат… Давай, я просто уволюсь?» Все, ты потерял этого человека. Компании, которые по первости отправляют на конференции лучших людей — и обжигаются – понимают эту схему, и в следующий раз присылают людей похуже, хотя и более представительных.

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

Как считать баланс игр? Баланс и псевдобаланс, 2 типа псевдобаланса (pve, pvp), почему надо считать сложный баланс, как надо это делать?


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

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


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

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

Может ли специалист высокого уровня существовать за пределами больших компаний?


Я немного повторюсь, потому что по этой теме уже разворачивался.

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

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

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

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

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



Что было ранее


  1. Илона Папава, Senior Software Engineer в Facebook — как попасть на стажировку, получить оффер и все о работе в компании
  2. Борис Янгель, ML-инженер Яндекса — как не пополнить ряды стремных специалистов, если ты Data Scientist
  3. Александр Калошин, СEO LastBackend — как запустить стартап, выйти на рынок Китая и получить 15 млн инвестиций.
  4. Наталья Теплухина, Vue.js core team member, GoogleDevExpret — как пройти собеседование в GitLab, попасть в команду разработчиков Vue и стать Staff-engineer.
  5. Ашот Оганесян, основатель и технический директор компании DeviceLock — кто ворует и зарабатывает на ваших персональных данных.
  6. Сания Галимова, маркетолог RUVDS — как жить и работать с психиатрическим диагнозом. Часть 1. Часть 2.
  7. Илья Кашлаков, руководитель фронтенд-отдела Яндекс.Денег — как стать тимлидом фронтендеров и как жить после этого.
  8. Влада Рау, Senior Digital Analyst в McKinsey Digital Labs — как попасть на стажировку в Google, уйти в консалтинг и переехать в Лондон.
  9. Ричард «Левелорд» Грей, создатель игр Duke Nukem 3D, SiN, Blood — про личную жизнь, любимые игры и о Москве.

Let's block ads! (Why?)