...

суббота, 25 апреля 2020 г.

[Из песочницы] Мой опыт использования вертикального монитора

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


Мое рабочее место

Мое рабочее место


Как я к этому пришел

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


О расположении мониторов

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

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

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


Компаньон

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


  • Часы
  • Pomodoro таймер
  • Медиа плеер (для управления текущим воспроизведением в любой программе)
  • Информация о потреблении ресурсов

Скриншот

Виджеты

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


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

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


Чтение

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


Контент на мониторах разной ориентации

Разница горизонтального и вертикального мониторов


Чтение книги

Чтение книги

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


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

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

Таким образом, на внешнем мониторе я держу:


  • Браузер (для чтения документации)
  • Терминал (для просмотра или мелкого редактирования файлов, просмотра логов или вывода программы)
  • Плеер

Расположение окон во время работы

Расположение окон во время работы

Задействовать пространоство на 100% мне не удается, но я не считаю, что это необходимо.


Недостатки моего сетапа

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

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

Еще хотелось бы упомянуть проблемы с оконными менеджерами (WM). Во-первых, тайлинговые WM сложно настраивать для работы с вертикальными мониторами, а готовых конфигов я не нагуглил (не могу сказать, что хорошо пытался). Во-вторых, обычные (floating) WM странно позиционируют окна. Например, иногда окна Libre Office или Firefox появляются "за кадром".

Иногда возникают казусы с терминалом:


Терминал на половину экрана

Терминал на половину окна


Заключение

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

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

Let's block ads! (Why?)

Svelte, исчезающий фреймворк, который уже не исчезнет

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


Уточню еще раз, данная статья является ответной на публикацию «Svelte, исчезающий фреймворк, что всё никак не исчезал».

Disclaimer

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


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

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

Интервью


Про меня


action52champion: Меня переполняет восхищение от наглости писавших её. С серьёзнейшим видом эти люди приходят и начинают рассказывать что их фреймворк в принципе может рассматриваться как альтернатива большой тройке: Angular, React, Vue. Первый раз я подумал, что автор из-за своей неопытности на полном серьёзе рассматривает Svelte как вменяемую production-ready альтернативу устоявшимся фреймворкам.

Привет Экшн Чемпион, мне очень приятно быть здесь, спасибо что пригласил! Меня зовут Павел Малышев, я автор всех тех замечательных статей (даже несмотря на то, что большая их часть — переводы), которые так «переполняют» тебя. В данный момент времени я руковожу разработкой в небольшой Нижегородской студии по направлениям веб и Smart TV.

Даже если кто-то из наших читателей не следит за Svelte, возможно они могут знать меня по моим докладам на крупнейших IT конференциях России и СНГ, таких как HolyJS, РИТ++, FrontendConf, DUMP, CSS-Minsk-JS, мероприятиях Яндекса и всевозможных митапах в разных городах РФ.

Также мне довелось быть героем выпусков RadioJS №54-55, Веб-стандарты №170, Девшахты №94 и некоторых других. Кроме Svelte, я люблю рассказывать про изоморфные веб-приложения с SSR, PWA, Web components и SmartTV.

Про то, как и почему начали использовать Svelte


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

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

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

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

Если говорить конкретно о Svelte, то первый проект, на который он был выбран мною в 2017 году, — встраиваемый виджет для сайтов. На самом деле выбор был не велик — либо ванила, либо то, что компилируется в ванилу. Даже нами любимый в тот момент Vue в чистом виде весил ~25Кб gzip, что чудовищно много для такого проекта.

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

В том же году, уже после того как мы закончили проект, я написал свою первую статью о Svelte на Хабре «Магически исчезающий JS фреймворк», чтобы поделиться с сообществом новым и перспективным инструментом. Естественно, статью встретили довольно прохладно, о чем может свидетельствовать хотя бы то, что более-менее техническая статья с примерами кода и неплохим оформлением тогда собрала в 3 раза меньше плюсов чем ваш профанский «высер» сегодня. По факту это была одна из первых статей о Svelte вообще и не только русскоязычных.

Про проплаченные статьи и в чем «профит»


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

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

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

Окей, расскажу как это работает. Заказчики, как правило, делятся на 2 категории:

  1. где-то слышали что React/Vue/Angular/Ember/{вставить свое} — это круто, поэтому давайте юзать его
  2. ничего не понимают, поэтому полагаются на мнение специалистов.

К сожалению, часто 1-е навязывают решения исходя из хайпа/PR-а, который, конечно же, сильнее у тех инструментов за которыми стоят корпорации (React/Angular) и/или сильные сообщества (Vue + китайцы).

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

В целом, считаю что «лед тронулся» и мы добились своего. Если в 2017-18 годах делать проект на Svelte можно было только для заказчиков 2-го типа, то в 2019-20 годах о Svelte уже многие слышали и готовы использовать в своих проектах. Почти каждый день мне в личку Телеграм и в чат Svelte пишут люди, представители различных компаний, в том числе крупных сервисов, и спрашивают про Svelte и его экосистему. Рад что вы, уважаемый Экшн, дали мне возможность рассказать и об этом.

Про конкретные недостатки


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

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

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

Про Большую тройку


action52champion: Ну знаете как то: лисп замечательный язык, только на нём почти никто не пишет, хаскелл — язычище каких поискать(как и тех кто пишет на нём) и т.д. Всё хорошо, всё отлично, только никому не нужно. Так что давайте сразу зайдем с козырей. У нас есть большая тройка вёб-фреймворков. Она худо-бедно устоялась за последние 5 лет. На ней создана и работает куча проектов. Для неё есть куча библиотек и компонентов. Для неё исправлены многие детские болезни. У неё большое сообщество опытных профессионалов. Для неё куча работы.

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

Хорошо ли, что новые решения появляются? Однозначно «Да», потому что время идет и появляются новые задачи, новые вызовы. 10 лет назад, мы думали только о десктопах и ослике, 5 лет назад мы думали о мобильных, сегодня на первый план выходят IoT, embedded и носимые устройства.

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

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

Про Vue


action52champion: Я помню как взлетал и набирал популярность Vue на фоне реакта с ангуляром. Да пиар был, но Vue просто не нуждался в пиаре. Он решал реальные проблемы раздутости и сложности других фреймворков. Он взял то что было реализовано в других и реализовал в минималистичной форме. Он решал конкретную проблему — сложность и монструозность двух других фреймворков. Какую реальную проблему решает Svelte я не знаю. То что написано у них на сайте это заявление о благих намерениях.

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

Это код Vue (2014):

var app = new Vue({
  el: '#app',
  data: function() {
    return {
       greeting: 'Hello',
       firstName: 'Экшн',
       lastName: 'Чемпион'
    };
  },
  computed: {
      fullName: function() {
         return this.firstName + ' ' + this.lastName;
     }
  } 
});

А это код Ractive (2012):
var app = new Ractive({
  el: '#app',
  data: function() {
    return {
       greeting: 'Hello',
       firstName: 'Экшн',
       lastName: 'Чемпион'
    };
  },
  computed: {
      fullName: function() {
         return this.get('firstName') + ' ' + this.get('lastName');
     }
  } 
});

Как видите кроме незначительных косметических отличий, в остальном код практически идентичен.

Возможно вы скажете, что это олдскул и на Vue все пишут в SFC (2015 год):

<template>
<p> </p>
</template>

<script>
export default {
  data: function() {
    return {
       greeting: 'Hello',
       firstName: 'Экшн',
       lastName: 'Чемпион'
    };
  },
  computed: {
      fullName: function() {
         return this.firstName + ' ' + this.lastName;
     }
  } 
};
</script>

<style scoped>
p { color: red; }
</style>

А я вам отвечу, что «ничто не ново под луной» (с) — Ractive (2014):
<p> </p>

<script>
component.exports = {
  data: function() {
    return {
       greeting: 'Hello',
       firstName: 'Экшн',
       lastName: 'Чемпион'
    };
  },
  computed: {
      fullName: function() {
         return this.get('firstName') + ' ' + this.get('lastName');
     }
  } 
};
</script>

<style>
p { color: red; }
</style>

А еще тот самый Virtual DOM, или все таки Parallel DOM? Надеюсь я вас окончательно не запутал. Бегло пробежался по комментариям к оригинальной статье и понял, что вы не понимаете разницы между Virtual DOM и Shadow DOM, что явно следует из этого комментария:
action52champion: Shadow DOM ввели во фреймворки не от хорошей жизни. Его отсутсвие означает, что Svelte заведомо будет медленнее, где будет много обновлений.

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

Но продолжу. Одна из причин, почему в 2015 году мы пересели на Vue, заключала в том, что Ractive, который мы использовали с 2013 года, из-за отсутствия «агрессивных евангелистов» просто не смог выбиться и нарастить массу. В тоже время молодой Vue, похожий на него как 2 капли воды, на волне поддержки со стороны очень сплоченного и национально-ориентированного китайского сообщества, уже начал хайпить в поднебесной. Переезд оказался фактически бесплатным, хотя мы и потеряли часть крутых фичей Ractive, которых во Vue нет до сих пор.

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

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

Svelte, во многом, является продолжателем идей Ractive соединенных с идеями заложенными в Rollup (eg. минимализм, tree-shaking и т.п.) и это не удивительно, ведь у всех этих инструментов один автор.

Относительно недавно в Angular появилась AoT компиляция шаблонов, похожая на Svelte. А знаете где я видел (и даже использовал) нечто подобное в первый раз и это позволяло нам еще в 2013 году выкидывать ту часть рантайма, которая работала с шаблонами? Ну вы поняли.

Про то, почему так долго


action52champion: С практической точки зрения важно одно — насколько хорошо фреймворк решает реальные бизнес задачи. И с этой точки зрения, если взять 2 фреймворка примерно одинаково решающие задачи, но у одного из них больше коммьюнити и экосистема, разумно выбрать последний. Svelte вышел в 2016 году. Vue вышел в 2014. Разница в 2 года. Т.е. Svelte мог учесть все ошибки Vue и стать лучшим, отвоевать аудиторию и рынок. Но он до сих пор является полнейшей маргинальщиной известной в основном по своим хвалебным статьям.

Прежде чем ответить на вопрос, немного откорректирую ваше утверждение. По-сути Svelte вышел в 2017 году. Его автор, Рич Харрис, рассказал о нем в своем «Frameworks without the framework: why didn't we think of this sooner?» лишь в самом конце 2016.

Кроме того Svelte 1 был скорее proof-of-concept, о чем не раз обсуждалось как в сообществе, так и при общении с автором. Несмотря на это, именно Svelte 1 я использовал на первом проекте с виджетом и для такой задачи он работал отлично. В тот момент, мы продолжали писать на Vue и поддерживать проекты на Ractive. Первый более-менее серьезный проект был разработан уже на Svelte 2, релиз которого произошел только в середине 2018 года, о чем я сразу написал в соответствующей статье.

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

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

Возможно вы захотите узнать, почему мы не стали писать еще проекты на Svelte 1, раз он был так прекрасен. Кажется ответ очевиден — в тот момент он был действительно сыроват и подходил только для проектов типа виджетов. Не могу сказать что мы вообще забросили его. На Svelte 1 были также написаны несколько внутренних проектов, а также переписаны части старых приложений на Ractive. Те компоненты, которые были «узкими местами» в производительности Virtual DOM, были успешно переписаны на Svelte 1 и внедрены в проекты, увеличив производительность данных компонентов вдвое. Это также был весьма положительный опыт.

Про тупых и алчных фронтендеров


action52champion: Особенно актуально это для тех, кто только въезжает во фронтенд. Часто въезжает за деньгами. Так вот: в Svelte денег нет. Работы на нём тоже нет. И самое интересное — опыта на нём тоже не будет.

Очень эмоциональная формулировка. Мне почему-то подумалось, что вы как раз один из тех, кто «въехал во фронтенд за деньгами», причем кажется довольно недавно.

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

Про экосистему


action52champion: Мантра «у нас есть настоящая реактивность и небольшой размер фреймворка» на самом деле означает «во фреймворке нет кучи типовых фич, а осваивать большую тройку вам все равно придётся». Так вот, заклинаю всех входящих в мир фронтенда, не ведитесь на хвалебные статьи. Не ведитесь на эту чушь! Фреймворк без экосистемы в 2020 году целящий на место большой тройки — это мёртвый фреймворк.

Что касается Sveltе и его экосистемы. Стоит сразу отметить, что, несмотря на кажущуюся простоту и минимализм, Svelte весьма fullfeatured прямо из коробки. Как добротный UI фреймворк в нем есть абсолютно все, что необходимо для создания совеременного UI. Вот диаграмма по встроенным фичам, которую я готовил к одному из своих докладов:

Например, в том же React ничего такого и в помине нет. Хотя React у нас самый популярный UI фреймворк, а по функционалу не более чем шаблонизатор.

Конечно же внешняя экосистема пока намного скромнее. Однако Svelte уже имеет довольно обшиный список готовых решений и всевозможных наборов компонентов, которые вы можете найти тут и он движется в этом направлении ровно также, как до этого двигались и другие фреймворки. Жаль что такие как вы, бездумно пытаются забрать у него этот шанс. С другой стороны, я помню как пару-тройку лет назад все тоже самое писали про Vue, а лет 6 назад про React и ничего, прорвались. Невежды всегда остаются лишь невеждами.

Про «святое»


action52champion: Когда про реакт в начале его популярности писали даже в Спидинфо, было всё то же самое, только с одной разницей — реакт решал какие-то проблемы разработки. Даже если не решал, то он смог родить вокруг себя за 3 года такую мощную экосистему, которая перечеркнула все его недостатки. Я ненавижу реакт, но понимаю, что если не буду использовать его, то попросту проиграю в эффективности тем, кто его использует, имея доступ ко вкуснейшим компонентам и библиотекам. Не используя Svelte я не теряю ничего.

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

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

Про всякое разное


action52champion: Сам подход минимализма, который предлагает Svelte недостижим в принципе. Я не могу представить ситуацию когда целесообразно будет использовать не чистый JS или VueJS, а Svelte. Vanilla JS как преимущество, когда тайпскрипт стал уже практически стандартом для написания сложных проектов? Попытки выиграть в размере кода на мелком проекте, где большая часть это сторонние компоненты и библиотеки? Выиграть на размере фреймворка в по-настоящему крупном проекте? Отсутствие Virtual DOM, но взамен него костыль в виде очередного уровня транспиляции заложенной в саму суть фреймворка? Write less code? При нулевой экосистеме? Причем заметьте, что в примерах на сайте рассматриваются именно крохотные компоненты, на которых разница достигается только за счет того, что в Vuejs и React есть какая-то инициализация компонента или описание редьюсеров, которые сделаны не просто так.

Блиц вопрос, отлично.
  1. Минимализм достижим. Проблемы с этим возникают тогда, когда в саму основу решения заложен иной принцип. Например, Reduх по своей сути не может быть минималистичным из-за заложенного в него обилия бойлерплейта. В тоже время Storeon, работая по-сути по тем же принципам, остается минималистичным. В целом все современные фреймворки стремятся дробить свои компоненты как минимально возможные юниты. Кроме того, нужно понимать как писать максимально декларативный и state-driven код.
  2. Это не выбор между Vanilla JS и Svelte. Svelte — это и есть Vanilla JS, который вам не нужно писать и который в разы проще поддерживать и развивать.
  3. Typescript + сложные проекты — опять звучит как «мы все тут пишем энтерпрайзы», ну-ну. Не нужно обобщений и не нужно себе льстить. Далеко не все пишет сложные проекты в которых обязаельно нужен TS. Хотя если он вам так нужен, тогда о каком Vue может идти речь? Поддержка TS там ± такая же как в Svelte.
  4. Мы уже выяснили, что вы не понимаете что такое Virtual DOM. В Svelte заложен механизм трекинга зависимостей в момент компиляции, который в разы упрощает механизмы change detection и применения изменений в рантайме. За счет этого мы получаем значительный прирост в скорости и низкое потребление памяти.
  5. Про экосистему уже писал выше. Она далеко не нулевая. Лично участвовал в переписывании проектов с React и Vue. Кода получается в среднем в 1.5 раза меньше, а сам код выглядит лаконичнее и аккуратнее.
  6. Раз вам не нравятся примеры из документации Svelte. Можете предложить более серьезные на ваш взгляд кейсы из документаций других фреймворков?

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

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

Про сообщество


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

Рад что вы спросили об этом. Русскоязычное сообщество представлено основным чатом в телеграмм (@sveltejs), отдельным чатом для фреймворка Sapper (@sapperjs), каналом с вакансиями (@sveltejs_jobs) и новостями (@sveltejs_public), а также группой в VK (@sveltejs_ru).
Основная движуха идет в чате в котором уже больше 1,5К человек и довольно бодрый костяк активных товарищей.


На нашем первом оффлан митапе 22 февраля в Москве было более 170 человек, а онлайн трансляцию смотрели почти 1К посетителей. Следующий митап должен был быть в Питере в апреле-мае, но пандемия внесла свои коррективы в наши планы. Надеюсь скоро все наладится и мы продолжим. Можете следить за нашими митапами на официальной странице Svelte Russian Meetups.

Посмотрим кто еще говорит о Svelte. К примеру, вот уважаемый Андрей Мелихов (Девшахта) рассказывает как Яндекс.Деньги используют Svelte:

Вот, буквальная цитата Андрея Ситника (автор PostCSS/Autoprefixer/etc) на прошлогоднем HolyJS Piter:

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

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

Я конечно не сомневаюсь, что мой уважаемый интервьюер умнее нас всех… хотя нет, сомневаюсь. Извините, мысли вслух.

Про (НЕ)осознанность


action52champion: Контраргументы уровня — вы просто не смогли разобраться со Svelte — это вообще за гранью юмора. Люди, которые работают с ангуляром и реактом не могут разобраться в с маленьким простым Svelte? Наверное тут дело в самом Svelte. Или в том, что там в принципе не в чем разбираться, потому что ничего стоящего нет.

Кажется я уже отвечал на подобный вопрос, но готов повторить, раз вы предоставили мне такую возможность. Одна из проблем, которую лично я вижу в плане продвижения Svelte — это то, что визуально он слишком похож на фреймворки Большой тройки, хотя концептуально отличается довольно сильно. Особенно это ощущалось в Svelte 1/2, когда в сообщество и комментарии Хабра приходили люди и искрене не понимали чем Svelte отличается от Vue. И действительно, в тот момент оба были слишком похожи на Ractive. С выходом Svelte 3 различия стали ярче, но это не решило проблему полностью.

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


Про (НЕ)популярность


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

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

«Вы опять все проспали, голубчик». (с) Смотрите StateOfJS 2018 — Svelte в топ-1 среди «Other libraries», а в прошлом 2019 году стабильно вошел в основной пул frontend фреймворков, при этом лидирует по критерию «интереса» к нему:

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

В конце концов, посмотрите сколько существует вокруг всевозможных фреймворков/библиотек/платформ/$mol-ов и далеко не все из них встают в один ряд с Большой тройкой. Да хотя бы просто имеют свой хаб на популярном IT ресурсе и подсветку кастомного синтаксиса на Github.

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

Про OSS


action52champion: Svelte не соответствует этим требованиям. За время существования Svelte, сравнимое со временем существования других фреймворков до получения ими признания, вокруг Svelte не сложилось ничего. Ах, за тройкой стоят корпорации? Господа, вы вроде как претендуете на то что у вас замечательный фреймворк. Почему вы не можете найти финансирование для своего замечательного фреймворка? У вас же на сайте куча логотипов в секции Who's using Svelte?.. Может с ним что-то не так? Вы уверены, что если его допилить, то получится не второй VueJS только сырой?

Как мы уже выяснили ваше, за 2 года с начала популяризации Svelte и/или за 1 год с выпуска его популярной версии, вокруг него сложилось много всего, поэтому считаю этот вопрос голосновным.

Однако, важно упомянуть еще одну вещь: Svelte — это чисто community driven проект и сообщество не хочет быть ангажированно и аффилировано с какой-либо корпорацией. Буквально недавно, кто-то из сообщества завел разговор о Патреоне для автора фреймворка, но сам автор присек даже эти обсуждения. Я понимаю, что многие привыкли пользоваться благами OSS за просто так и даже предъявнять к ним свои бизнес-требования. Но на самом деле люди делающие OSS вам ничего не должны, уважаемые, а вот многие из нас могли бы и поучаствовать в OSS проектах, а не тупо зарабатывать деньги на чужих решениях.

Касательно Svelte, те самые «не такие» корпорации помогают нам по-другому. Например, Mail.Ru, очень помогли нам с первым в России митапом по Svelte. Предоставили свой прекрасный офис с оборудованием, печеньками, взяли на себя организацию трансляции и записи. Спасибо Mail.Ru!

Про то-то что


action52champion: Вы уверены, что в праве советовать этот фреймворк так категорично? Фронтенд — это область куда каждый день приходят новые люди без опыта. Они не в состоянии оценить масштаб ненужности Svelte. Они увидят хвалебные статьи где умные дядьки с серьёзным видом рассуждают о том какой там замечательный проброс событий, компилятор и т.д. Что интересно с академической точки зрения, но не с практической. Они подумают что с этим стоит связываться, потратят свое время и останутся ни с чем. А выдавая пачками статьи про то, как замечательно на Svelte можно сделать какую-то хрень, которую можно так же сделать на нормальных фреймворках, вы подкладываете начинающим людям огромную свинью.

Мой любимый вопрос! Почти как вишенка на торте.

Да я уверен что я в праве и вот почему:

  • Я знаю о чем говорю. Использую Svelte в своей работе и выкладываю решения в OSS.
  • Являюсь лицом принимающим решения по выбору технологий и отвечаю за успех проектов.
  • У меня есть с чем сравнивать. Кроме Svelte, имею опыт со многими фреймворками сейчас и в прошлом (Backbone, AngularJS, Ractive, Riot, Vue/Nuxt, React, LitElement).
  • Много общаюсь с теми, кто также использует Svelte и часто помогаю тем, кто хочет его изучить. Слышу их проблемы и стараюсь всегда предлагать решения.
  • Читаю доклады про Svelte и готов предметно отвечать на вопросы.

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

P/S


Интервью закончилось, а теперь алаверды. А вы, уважаемый @action52champio, уверены что вправе хаять инструмент, который не только не использовали, да и в глаза толком не видели? Какой у вас практический опыт со Svelte, да и вообще есть ли он хоть с одним из фреймворков? React вы не любите, во Vue не разбираетесь. Angular? Нет, не думаю.

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

Let's block ads! (Why?)

Чем развлечься в самоизоляции, или передаем данные с помощью звуковой карты

Привет Хабр.

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

Для тех кому интересно как это работает, продолжение под катом.

Для тестов мы воспользуемся программой MultiPSK, которая удобна тем, что поддерживает огромное количество разных стандартов связи, как любительских (они доступны как на прием, так и на передачу), так и профессиональных (доступен только прием). Разумеется, чтобы не делать статью гигантской, я выберу лишь наиболее популярные виды модуляции, и мы посмотрим что из этого получится. Изначально MultiPSK предназначена для радиосвязи, для чего звуковая карта должна подключаться к приемнику или передатчику, но ничего не запрещает воспроизводить сигнал прямо из колонок. Тест будет будет довольно простым — простой текст «1234567890» кодируется разными способами, сигнал проигрывается на ПК, и записывается смартфоном в другом конце квартиры. Разумеется, повторить нижеописанные опыты может любой желающий, никакого специального оборудования для этого не требуется.

Let's get started.

Частотная модуляция (FSK, Frequency Shift Keying)


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

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

Кстати о спектре, он исказился, хотя в принципе, форму сигнала угадать можно:

Посмотрим, сможет ли MultiPSK декодировать записанный звук. Увы, нет, на выходе лишь «мусор». Разные попытки нормализации и фильтрации к успеху также не привели:

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

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

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

Фазовая модуляция (PSK, Phase Shift Keying)


Следующий вид модуляции — фазовая, при которой передается синусоидальный сигнал, а информация кодируется изменением фазы.

Сигнал BPSK «до» и «после» передачи:

Результат распознавания: определилось где-то 20-40% символов, из строки 1234567890, как можно видеть, можно различить 3, 4, 7 и 9.

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

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

SSTV (Slow Scan Television)


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

Сигнал «до» и «после»:

Картинка с котиком, и попытка её приема:

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

Заключение


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

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

Всем удачных экспериментов.

Let's block ads! (Why?)

[Из песочницы] Почему разработчики такие медленные: распространенные проблемы и их решения

Привет, Хабр! Представляю вашему вниманию перевод статьи Why Development Teams are Slow: Common Software Jams and Solutions автора Эрика Эллиота.

Если вы больше любите слушать, чем читать, то в аудио формате перевод доступен на Яндекс.Музыке и в Apple Podcasts

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

  • Нереалистичные ожидания
  • Слишком много открытых тикетов
  • Неконтролируемый объем задач
  • Накопление код ревью
  • Плохая подготовка
  • Выгорание разработчиков
  • Баги
  • Текучка кадров

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

Нереалистичные ожидания


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

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

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

Мы часто забываем, что софт, который мы создаем — это что-то принципиально новое. Если уже есть софт, который делает то же самое, купите его, используйте, импортируйте модуль и т.д. Не нужно его заново писать с нуля. Новый же софт уникален. Он делает что-то новое или делает что-то иначе. Именно затем мы его и создаем. А раз мы этого ещё не делали, то откуда нам знать сколько времени это займет?

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

Как пишет Стив МакКоннелл, автор книги “Совершенный код”: «Заключение, что между продуктивностью работы разных программистов есть существенная разница было подтверждено множеством исследований профессиональных разработчиков (Curtis 1981, Mills 1983, DeMarco and Lister 1985, Curtis et al. 1986, Card 1987, Boehm and Papaccio 1988, Valett and McGarry 1989, Boehm et al. 2000). Нам не хватает данных чтобы предсказать как много времени потребуется для завершения нашего проекта. Мы узнаем каковы масштабы и сложность уже начав работу и этот процесс часто таит множество сюрпризов. Разработка это не только планирование, но и исследование, вне зависимости от того насколько тщательно мы пытались всё предусмотреть.»

«На первые 90 процентов кода уходит 10 процентов времени, потраченного на разработку. На оставшиеся 10 процентов кода уходит оставшиеся 90 процентов»
— Том Каргилл, Bell Labs

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

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

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

Два примера вещей, которые не стоит измерять:

  1. Прогнозирующие диаграммы выполнения задач (burndown charts), показывающие график количества открытых тикетов, предсказывающие дату окончания проекта, основываясь на недавних измерениях скорости работы;
  2. Количество тикетов, закрытых разработчиком, демонстрирующее как много задач завершил отдельный разработчик.

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

Диаграммы выполнения задач


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

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

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

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

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

График проекта, где количество тикетов сокращается

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

График проекта, тонущего в новых задачах

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

Цель — прозрачность процессов, а не красивая нисходящая кривая.

Остерегайтесь принципа Гудхарта: «Если измерение становится целью, то оно перестает быть полезным».

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

Эмпирическое правило для предсказаний такого рода:
«Если предсказание говорит, что вы можете что-то сделать к заданной дате, не верьте ему, если говорит, что не сможете — верьте.

Тикеты закрытые одним программистом


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

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

Много лет назад я работал над корзиной покупок для мирового лидера ритейла. Однажды я прекратил писать код и закрывать тикеты в Джире и добавил ещё один тикет: “Изучение юзабилити”.

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

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

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

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

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

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

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

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

Слишком много открытых задач


Казалось бы всё просто — открой тикет в трекере и двигайся дальше. Но каждая задача в трекере требует целого цикла переработки.

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

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

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

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

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

Неконтролируемый размер задач


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

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

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

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

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

Накопление задач по код ревью


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

Это фаза интеграции в “Continuous Integration” (CI). Проблема в том, что чем дольше PR остается открытым, тем больше времени на него тратится. Разработчики будут его открывать чтобы посмотреть, могут ли они помочь его смержить. Они оставят обратную связь, запросят изменения и реквест вернется к автору для внесения правок и дальнейшего одобрения этих изменений. А пока всё это происходит пулл реквест будет отдаляться всё дальше мастера.
Когда у нескольких девелоперов появляется привычка делать очень большие коммиты, то количество пулл реквестов начинает расти как снежный ком и интеграция становится всё более сложной.

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

Подсчитаем количество таких действий в стандартном сценарии:

  • Боб и Джейн начинают работу в одной и той же ветке (0 действий)
  • Боб вносит изменения и коммитит в свою ветку. Джейн делает то же самое (2 действия)
  • Код Боба попадает в мастер. Джейн скачивает себе изменения Боба и обнаруживает конфликт. Они его исправляет и коммитит результат в свою ветку. (3 действия)
  • Джейн открывает пулл реквест. Боб отмечает, что её изменения в его коде сломают что-то, что она не учла. Джейн вносит изменения с учетом комментариев Боба и снова коммитит код (4 действия)
  • PR Джейн наконец мержат. Всего 4 действия.

Теперь рассмотрим ситуацию, в которой коммиты были бы меньше, и пулл реквесты бы мержились быстрее:
  • Боб делает маленькое изменения и его код попадает в мастер (1 действие)
  • Джейн скачивает новую версию мастера и пишут свой код уже с учетом изменений Боба. (2 действия)
  • Поскольку коммит Джейн тоже маленький его быстро мержат в мастер. Итого всего два действия.

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

Плохая подготовка


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

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

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

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

Что можно сделать:

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

Профессиональное выгорание


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

Выгорание это серьезная проблема, которая может привести к потере разработчиков, текучке кадров, огромным расходам, росту бас фактора (Bus factor — мера сосредоточения информации среди отдельных членов проекта; фактор означает количество участников проекта, после потери которых проект не сможет быть завершён оставшимися участниками).

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

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

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

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

Уложиться в дедлайн проще, если использовать следующие приемы:

  • Лучше приоритизировать задачи и сокращать скоуп
  • Оптимизировать процессы
  • Распознавать и рефакторить запутанность в коде

Текучка кадров


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

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

Размещение вакансий обходится в 15—30 тысяч долларов. Время инженера стоит а среднем 90 долларов в час. Умножьте это на примерно 50 собеседований и много-много часов на то, чтобы отвечать на вопросы новичка и помогать ему прижиться в команде. Таким образом мы уже потратили 50 тысяч долларов, но это ещё не всё.

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

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

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

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

Как избежать текучки? Вот несколько советов из разных источников:

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

Баги


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

Согласно книге “Evaluating Software Engineering Technologies” (David N. Card, Frank E. Mc Garry, Gerald T. Page, 1978) хорошо оптимизированные процессы позволяют уменьшить количество ошибок, без увеличения затрат. Главная причина в том, что согласно другой книге “Software Assessments, Benchmarks, and Best Practices” (Каспер Джонс 2000) обнаружение и исправление дефектов это одна из самых время затратных и дорогих задач в разработке.

Баги печально известны тем, что вызывают необходимость переработки кода и чем позже вы их обнаружите, тем дороже будет их исправить. Когда разработчику поручают исправить баг, обнаруженный уже в продакшене, это часто отрывает его от того, чем он занимался. В книге “A Diary Study of Task Switching and Interruptions” (Mary Czerwinski, Eric J. Horvitz, Susan Wilhite) говорится о том, что задача, от которой нас отвлекли может занять вдвое больше времени и содержать вдвое больше ошибок, что говорит о том, что высокоприоритетные баги в каком-то смысле заразны: исправляя один, мы скорее всего наплодим новых.

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

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

Но это ещё не всё. У этого бага будет свой коммит, свой пулл-реквест, код ревью, интеграция и возможно даже свой деплой. И на любом этапе может упасть какой-нибудь тест и весь цикл CI/CD придется начинать заново.

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

Следующие советы помогут улучшить качество процессов.

  • Замедлитесь, чтобы ускориться. Медленный значит бесперебойный, бесперебойный значит быстрый.
  • Проводите дизайн ревью. Совокупность проверки кода и требований позволяет отловить до 70% багов.
  • Проводите код ревью. Хорошо проверенный код на 90% проще поддерживать. Один час рецензирования сохранить вам 33 часа поддержки. Программисты, которые проводят код ревью на 20% более продуктивны.
  • Используйте TDD подход. Он сокращает количество багов на 30-40 процентов
  • Используйте CI/CD. Это автоматизированный процесс объединяющий код ревью, автоматическое тестирование, автоматический деплой на тестовое окружение и наконец автоматический деплой в продакшн. Автоматизация всего процесса позволяет избежать ошибок и сэкономить многие рабочие часы, которые программисты тратили бы на ручной запуск всех процессов. Если вы ещё не используете CI/CD начните сегодня.
  • Повышайте покрытие тестами. Ваш процесс CI/CD должен запускать тесты и останавливаться в случае если хоть один из них упадет. Это поможет избежать деплоя багов в продакшн и сохранить вам много денег и времени. Ваша цель хотя бы на 70% покрытия, но постарайтесь держаться ближе к 80%. По мере приближения к 100% вы заметите, что покрытие функциональными тестами важных пользовательских процессов даст вам больше, чем дальнейшее увеличение объема юнит-тестов.

Заключение


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

Let's block ads! (Why?)

[Перевод] 23 непростых вопроса для JavaScript-собеседования

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


image

1. Объясните особенности проверки равенства значений в JavaScript


Сложность: *


В JavaScript есть два оператора для проверки равенства величин. Первый — это так называемый оператор строгого равенства. Второй — оператор нестрогого равенства, при использовании которого может производиться преобразование типов проверяемых величин.
  • Оператор строгого равенства (===) проверяет значения на равенство, не выполняя при этом преобразования типов.
  • Оператор нестрогого равенства (==) проверяет значения на равенство, выполняя их приведение к общему типу.
var a = "42";
var b = 42;

a == b;         // true
a === b;        // false

Вот некоторые правила, касающиеся использования различных операторов проверки равенства в JavaScript:
  • Если любое из сравниваемых значений может быть значением true или false — постарайтесь избегать оператора ==. Используйте оператор ===.
  • Используйте оператор === в том случае, если работаете со следующими значениями: 0, «» или [] (пустой массив).
  • Во всех остальных случаях можете безопасно использовать оператор ==. Причём, это не только безопасно, но и способствует упрощению кода и улучшению его читабельности.

Источник

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


Сложность: ***


Суть этого вопроса в том, чтобы выяснить, какие значения, в случае преобразования их к логическому типу, превращаются в false, а какие — в true.

Вот список значений, которые можно назвать «ложными» (falsy). Они, при преобразовании к логическому типу, превращаются в значение false:

  • «» (пустая строка).
  • 0, -0, NaN (не-число).
  • null, undefined.

«Ложным» является и логическое значение false.

Любое значение, которое не входит в этот список, при его преобразовании к логическому типу, превращается в true (такие значения называют «истинными» — truthy). Например:

  • «hello».
  • 42.
  • [ ], [ 1, «2», 3 ] (массивы).
  • { }, { a: 42 } (объекты).
  • function foo() { .. } (функции).

«Истинным» является и логическое значение true.

Источник

3. Что такое IIFE?


Сложность: ***


IIFE (Immediately Invoked Function Expression) — это немедленно вызываемое функциональное выражение. Такое выражение выполняется немедленно после создания.
(function IIFE(){
    console.log( "Hello!" );
})();
// "Hello!"

Этот паттерн часто используется для того чтобы не допустить загрязнения глобального пространства имён. Дело в том, что переменные, объявленные в IIFE (как и в любой другой обычной функции), невидимы за пределами этой функции.

Источник

4. Когда следует использовать стрелочные функции, которые появились в ES6?


Сложность: ***


Вот простые правила по использованию различных способов объявления функций, которыми я руководствуюсь, разрабатывая код для сред, поддерживающих стандарт ES6 и более новые стандарты:
  • Используйте ключевое слово function в глобальной области видимости и для свойств Object.prototype.
  • Используйте ключевое слово function для конструкторов объектов.
  • В остальных случаях используйте стрелочные функции.

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

Источник

5. В чём разница между ES6-классами и конструкторами функций?


Сложность: ***


Сначала рассмотрим примеры.

Функция-конструктор:

function Person(name) {
  this.name = name;
}

ES6-класс:
class Person {
  constructor(name) {
    this.name = name;
  }
}

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

Основная разница между конструкторами и классами проявляется при использовании наследования. Если нам нужно создать класс Student, являющийся подклассом класса Person, и добавить к этому новому классу поле studentId, то вот как будет выглядеть код, в котором используются конструкторы, и код, в котором применяются классы.

Функция-конструктор:

function Student(name, studentId) {
  // Вызываем конструктор суперкласса для инициализации полей, унаследованных от него.
  Person.call(this, name);

  // Инициализация собственных полей объекта.
  this.studentId = studentId;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

ES6-класс:
class Student extends Person {
  constructor(name, studentId) {
    super(name);
    this.studentId = studentId;
  }
}

Источник

6. Расскажите о методе Function.prototype.bind()


Сложность: ***


Процитируем MDN: «Метод bind() создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения this предоставленное значение. В метод также передаётся набор аргументов, которые будут установлены перед переданными в привязанную функцию аргументами при её вызове».

Полагаю, что метод .bind() особенно полезен для привязки значения this в методах классов, которые нужно передавать в другие функции. Этот приём часто используется в React-компонентах.

Источник 

7. Для чего обычно используются анонимные функции?


Сложность: ***


Анонимные функции используются при создании IIFE — конструкций, переменные, объявленные в которых, не загрязняют глобальную область видимости.
(function() {
  // Какой-то код.
})();

Анонимные функции применяют в качестве функций обратного вызова, которые используются лишь в одном месте программы. Код будет выглядеть более самодостаточным и читабельным в том случае, если коллбэк будет объявлен прямо в том месте, где он используется. Это избавляет от необходимости просматривать код в поиске тела функции.
setTimeout(function() {
  console.log('Hello world!');
}, 1000);

Анонимные функции удобно использовать в конструкциях, характерных для функционального стиля программирования, или при работе с библиотеками вроде Lodash (этот вариант их использования похож на их применение в качестве коллбэков).
const arr = [1, 2, 3];
const double = arr.map(function(el) {
  return el * 2;
});
console.log(double); // [2, 4, 6]

Источник

8. В чём разница между методом Object.freeze() и ключевым словом const?


Сложность: ***


Ключевое слово const и метод Object.freeze() — это совершенно разные вещи.

Ключевое слово const применяется к привязкам (к «переменным»). Оно создаёт иммутабельную привязку, то есть — к переменной (константе), объявленной с помощью ключевого слова const, нельзя привязать что-то новое. Константе нельзя присвоить новое значение.

const person = {
    name: "Leonardo"
};
let animal = {
    species: "snake"
};
person = animal; // Uncaught TypeError: Assignment to constant variable.

Метод Object.freeze() работает со значениями. А точнее — с объектными значениями. Он делает объект иммутабельным, что защищает от изменений значения свойств этого объекта.
let person = {
    name: "Leonardo"
};
Object.freeze(person);
person.name = "Lima"; // Uncaught TypeError: Cannot assign to read only property 'name' of object
console.log(person);

Обратите внимание на то, что сообщение об ошибке выводится в строгом режиме. В обычном режиме операция изменения свойства «замороженного» объекта просто не срабатывает.

Источник

9. Что такое «генератор»?


Сложность: ***


Генераторы — это функции, из которых можно «выходить», и в которые можно «входить» по мере необходимости. Их контекст (привязки переменных) сохраняется между сеансами «входа» в них. Генераторы объявляют с использованием ключевого слова function*. Такая функция, при её первом вызове, не выполняет код, возвращая особый объект, генератор, который позволяет управлять её выполнением. Для получения очередного значения, выдаваемого генератором, нужно вызвать его метод next(). Благодаря этому выполняется код функции до тех пор, пока в нём не встретится ключевое слово yield, возвращающее значение.

Функцию-генератор можно вызывать сколько угодно раз. Каждый раз будет возвращаться новый генератор. Но каждый генератор можно обойти лишь один раз.

function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
    let iterationCount = 0;
    for (let i = start; i < end; i += step) {
        iterationCount++;
        yield i;
    }
    return iterationCount;
}

Источник

10. Когда стоит использовать генераторы?


Сложность: ***


Если в двух словах описать основные полезные возможности генераторов, то окажется, что они заключаются в следующем:
  • Код, в котором используется генератор, сам определяет момент получения следующего значения. Генератор отвечает только за возврат значений, управление им осуществляется извне.
  • Существуют асинхронные генераторы. Они позволяют работать с асинхронными потоками данных.

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

Источник

11. Что такое «поднятие переменных»?


Сложность: ****


Сущность концепции «поднятия переменных» заключается в том, что объявления «поднимаются» в верхнюю часть текущей области видимости. В результате переменной можно воспользоваться до её объявления. Поднимаются лишь объявления переменных, но не код их инициализации. Обратите внимание на то, что поведение переменных, объявляемых с использованием ключевого слова var, отличается от поведения переменных и констант, объявленных с использованием let и const.

Источник

12. Что выведет следующий код?


Сложность: ****

var output = (function(x) {
  delete x;
  return x;
})(0);

console.log(output);

Этот код выведет 0. Оператор delete используется для удаления свойств объектов. А x — это не свойство объекта — это локальная переменная. Оператор delete не воздействует на локальные переменные.

Источник

13. Что выведет следующий код?


Сложность: ****

var Employee = {
  company: 'xyz'
}
var emp1 = Object.create(Employee);
delete emp1.company
console.log(emp1.company);

Этот код выведет xyz. Свойство company является не свойством объекта emp1, а свойством его прототипа. Оператор delete не удаляет свойства прототипов объектов. У объекта emp1 нет собственного свойства company. Проверить это можно так:
console.log(emp1.hasOwnProperty('company')); // false

Если нам всё же необходимо удалить это свойство — сделать это можно, либо напрямую обратившись к объекту Employee (delete Employee.company), либо — обратившись к прототипу объекта emp1, воспользовавшись его свойством __proto__ (delete emp1.__proto__.company).

Источник

14. Расскажите о шаблоне проектирования «Прототип»


Сложность: ****


Прототип (Prototype) — это порождающий шаблон проектирования. Он используется для создания объектов. Объекты, созданные с его помощью, содержат значения, скопированные из их прототипа (из объекта-образца). Этот шаблон ещё называют шаблоном Свойства (Properties).

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

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

Источник

15. Что такое «временная мёртвая зона» в ES6?


Сложность: ****


В ES6 выполняется подъём переменных и констант, объявленных с использованием ключевых слов let и const (выполняется и подъём сущностей, объявленных с использованием ключевых слов var, class и function). Однако в коде имеется зона, простирающаяся от входа в область видимости до объявления переменной или константы. При обращении к переменной или константе в этой зоне будет выдана ошибка. Это и есть «временная мёртвая зона» (Temporal Dead Zone, TDZ).
//console.log(aLet)  // выбросит ReferenceError

let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10

В данном примере TDZ заканчивается после объявления aLet, но не после присвоения aLet значения.

Источник

16. Можете ли вы описать основное различие методов массивов forEach() и map()? В каких ситуациях вы предпочли бы один из этих методов другому?


Сложность: ****


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

Вот как работает .forEach():

  • Он перебирает элементы массива.
  • Он выполняет переданную ему функцию обратного вызова для каждого элемента массива.
  • Он ничего не возвращает.
const a = [1, 2, 3];
const doubled = a.forEach((num, index) => {
  // Сделать что-то с num и/или с index.
});

// doubled = undefined

Вот краткая характеристика метода .map():
  • Он перебирает элементы массива.
  • Он преобразует каждый элемент исходного массива в элемент нового массива, вызывая переданную ему функцию для каждого элемента исходного массива.
const a = [1, 2, 3];
const doubled = a.map(num => {
  return num * 2;
});

// doubled = [2, 4, 6]

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

Источник

17. Чем отличаются друг от друга необъявленная переменная, переменная, содержащая значение null, и undefined-переменная? Как проверить переменную на предмет того, что она необъявлена, а также на null и undefined?


Сложность: ****


Необъявленная переменная создаётся при назначении значения идентификатору, который не был ранее объявлен с использованием var, let или const. Необъявленные переменные объявляются в глобальной области видимости, за пределами текущей области видимости. В строгом режиме при попытке назначения значения необъявленной переменной будет выброшено исключение ReferenceError. Использовать необъявленные переменные не рекомендуется — так же, как не рекомендуется использовать глобальные переменные. Их стоит всеми силами избегать. Для того чтобы обезопасить себя от последствий использования необъявленных переменных, воспользуйтесь блоком try/catch.
function foo() {
  x = 1; // Выбрасывает в строгом режиме ReferenceError
}

foo();
console.log(x); // 1

Переменная, содержащая undefined — это объявленная переменная, которой не назначено некое значение. Значение undefined образует собственный тип данных. Если функция ничего не возвращает, и при этом результат её вызова записывается в переменную, то в эту переменную попадёт undefined. Для того чтобы организовать проверку на undefined, можно воспользоваться оператором строгого равенства (===) или оператором typeof, который возвратит строку undefined. Обратите внимание на то, что при проверке на undefined не следует пользоваться оператором нестрогого равенства (==), так как он считает равными значения undefined и null.
var foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true

console.log(foo == null); // true. Не используйте такую конструкцию для проверки на undefined!

function bar() {}
var baz = bar();
console.log(baz); // undefined

Переменная, содержащая значение null, должна быть явным образом установлена в это значение. Она символизирует отсутствие значения и отличается от undefined-переменной тем, что значение, находящееся в ней, было ей явным образом назначено. Для того чтобы проверить значение на null, достаточно воспользоваться оператором строгого равенства. Для проверки на null, как и в случае с проверкой на undefined, не следует пользоваться оператором нестрогого равенства, считающим равными значения null и undefined.
var foo = null;
console.log(foo === null); // true
console.log(typeof foo === 'object'); // true

console.log(foo == undefined); // true Не используйте такую конструкцию для проверки на null!

Я стараюсь никогда не оставлять переменные в необъявленном состоянии, или в состоянии, когда они объявлены, но им явным образом не назначено никакого значения. Если я не собираюсь записывать в переменную какое-то значение сразу после её объявления, я записываю в неё null. Если вы пользуетесь линтером, то он обычно сообщает о случаях использования необъявленных переменных.

Источник

18. Расскажите о шаблоне проектирования «Открытый модуль»


Сложность: *****


Шаблон «Открытый модуль» (Revealing Module) является разновидностью шаблона «Модуль» (Module). Цель использования этого шаблона заключается в поддержке инкапсуляции и в открытии некоторых свойств и методов, возвращённых в объектном литерале. Вот как будет выглядеть непосредственная реализация этого шаблона:
var Exposer = (function() {
  var privateVariable = 10;

  var privateMethod = function() {
    console.log('Inside a private method!');
    privateVariable++;
  }

  var methodToExpose = function() {
    console.log('This is a method I want to expose!');
  }

  var otherMethodIWantToExpose = function() {
    privateMethod();
  }

  return {
      first: methodToExpose,
      second: otherMethodIWantToExpose
  };
})();

Exposer.first();        // Вывод: This is a method I want to expose!
Exposer.second();       // Вывод: Inside a private method!
Exposer.methodToExpose; // undefined

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

Источник

19. В чём разница между объектами Map и WeakMap?


Сложность: *****


Эти объекты ведут себя по-разному в том случае, если переменная, содержащая ссылку на объект, являющийся ключом одной из пар ключ/значение, оказывается недоступной. Вот пример:
var map = new Map();
var weakmap = new WeakMap();

(function() {
    var a = {
        x: 12
    };
    var b = {
        y: 12
    };

    map.set(a, 1);
    weakmap.set(b, 2);
})()

После того, как завершается выполнение IIFE, у нас уже не будет доступа к объектам a и b. Поэтому сборщик мусора удаляет ключ b из weakmap и очищает память. А вот содержимое map остаётся при этом неизменным.

В результате оказывается, что объекты WeakMap позволяют сборщику мусора избавляться от тех своих записей, на ключи которых нет ссылок во внешних переменных. Объекты map хранят пары ключ/значение вне зависимости от наличия или отсутствия внешних ссылок на ключи. То же самое можно сказать и о реализации структуры данных Map с использованием обычных массивов. В WeakMap используются «слабые» ссылки на ключи. Они не препятствуют работе сборщика мусора в том случае, если на объект, используемый в роли ключа, нет других ссылок.

Источник

20. Как в JavaScript-функции передаются параметры: по ссылке или по значению?


Сложность: *****


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

Вот пример:

function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num);
console.log(obj1.item);
console.log(obj2.item);

Вот что выведет этот код:
10
changed
unchanged

Источник

21. Как организовать «глубокую заморозку» объекта?


Сложность: *****


Для того чтобы обеспечить «глубокую заморозку» объекта с использованием Object.freeze(), нужно создать рекурсивную функцию, которая «замораживает» свойства объекта, которые также являются объектами.

Вот пример обычной «заморозки» объекта:

let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
Object.freeze(person); // делает объект иммутабельным
person.profession.name = "doctor";
console.log(person); //вывод { name: 'Leonardo', profession: { name: 'doctor' } }

Вот — «глубокая заморозка»:
function deepFreeze(object) {
    let propNames = Object.getOwnPropertyNames(object);
    for (let name of propNames) {
        let value = object[name];
        object[name] = value && typeof value === "object" ?
            deepFreeze(value) : value;
    }
    return Object.freeze(object);
}
let person = {
    name: "Leonardo",
    profession: {
        name: "developer"
    }
};
deepFreeze(person);
person.profession.name = "doctor"; // TypeError: Cannot assign to read only property 'name' of object

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

Источник

22. Почему JavaScript-программисты испытывают проблемы при использовании ключевого слова this?


Сложность: *****


Самое важное, что нужно понять о this, заключается в том, что у функций нет фиксированного значения this. Это значение зависит от того, как именно вызывается функция. Если мы говорим о том, что функция вызывается с некоторым конкретным значением this, это значит, что это значение определяется не во время объявления функции, а во время её вызова. Вот некоторые особенности this:
  • Если функция вызывается в обычном виде (то есть, с использованием конструкции вида someFunc()), то this будет ссылаться на глобальный объект (в браузере это window). Если код выполняется в строгом режиме, то в this будет записано значение undefined.
  • Если функция вызывается как метод объекта, то ключевое слово this будет представлено объектом, которому принадлежит метод.
  • Если функцию вызывают с использованием call или apply, this будет представлено тем, что указано в качестве первого аргумента call или apply.
  • Если функция вызывается в виде обработчика события, то в this будет целевой элемент события.
  • Если функцию вызывают в виде конструктора, с использованием ключевого слова new, то в this будет новый объект, прототип которого установлен в качестве свойства prototype функции-конструктора.
  • Если функция создана с использованием метода bind, то ключевое слово this функции будет жёстко привязано к значению, переданному bind в качестве первого аргумента. Это — единственное исключение из правила, в соответствии с которым функции не имеют жёстко заданного значения this. Функции, созданные с использованием bind, имеют иммутабельное значение this.

Источник

23. Сравните использование конструкции async/await и генераторов для реализации одного и того же функционала


Сложность: *****


  • При итерировании генератора с использованием метода .next() каждый вызов этого метода приводит к возврату одного значения с помощью ключевого слова yield. При использовании конструкции async/await await-выражения выполняются последовательно.
  • Конструкция async/await упрощает реализацию определённого сценария использования генераторов.
  • Значения, возвращаемые генератором, всегда имеют вид {value: X, done: Boolean}, а асинхронные функции возвращают промисы, разрешаемые со значением X, либо завершаются с ошибкой.
  • Асинхронную функцию можно преобразовать в генератор, использующий промисы. Ниже приведён пример такого преобразования.

Вот асинхронная функция:
// Асинхронная функция
async function init() {
    const res1 = await doTask1();
    console.log(res1);

    const res2 = await doTask2(res1);
    console.log(res2);

    const res3 = await doTask3(res2);
    console.log(res3);

    return res3;
}

init();

Вот аналогичный генератор.
// Эта функция выполняет генератор
function runner(genFn) {
    const itr = genFn();

    function run(arg) {
        let result = itr.next(arg);

        if (result.done) {
            return result.value;
        } else {
            return Promise.resolve(result.value).then(run);
        }
    }

    return run;
}

// Вызывает функцию runner с передачей ей генератора
runner(function* () {
    const res1 = await doTask1();
    console.log(res1);

    const res2 = await doTask2(res1);
    console.log(res2);

    const res3 = await doTask3(res2);
    console.log(res3);

    return res3;
});

Источник

Уважаемые читатели! Какие вопросы по JavaScript встречались вам на собеседованиях?

Let's block ads! (Why?)