Comments 74
Ну что за люди пошли… умных у них хватает, глупых тоже не надо…
Они не «умные», им самим нужно поучиться менеджменту. Не умеют использовать мозг других людей в интересах компании.
На самом деле эта ситуация не так уж и идиотична, как может показаться. Большая корпорация не может делать ставку на одного конкретного человека (если, конечно, его не зовут Элон Маск или Стив Джобс). Работники должны быть взаимозаменяемы, а весь процесс — задукоментирован и стандартизован. Шибко умный гарантировано не впишется в такой процесс. Беда в том, что местная политкорректность не позволяет в объявлении о работе написать конкретно про тип и стиль отдела, где соискателю предстоит работать — а стили эти весьма и весьма отличаются. Два последних проекта я специально искал в «болоте» — транснациональных корпорациях, где все предсказуемо и четко. Скучно, правда, но большие деньги. И не штормит. К текущему моменту отдохнул, и уже хочу щупать новых технологий и смотреть в горящие глаза, так сказать. Статистически (вот прямо из личного опыта) — из семнадцати компаний, где у меня были интервью за последний месяц, такая молодая-активная-технологичная-анархическая — попалась всего одна. Так что выбирать не из чего :)
Вообще-то я ходил на интервью в американскую контору, неподалеку от вашингтонского обкома.
Этот неловкий момент, когда поросёнок Пётр не знает, что ответить.
Товарищи, что вы хотите сказать всеми этими минусами? Что в России такого нет? В статье нет ни слова о том, что собеседование было в Америке.
Или это такая фанатичная любовь к России и нежелание признавать косяки процесса отечественной веб-разработки? Поясните, хотя бы…
Ну, во-первых, постинг «смешных картинок» сам по себе надоел. Во-вторых, тут ещё и шутка не удалась. Зато удалась шутка «Этот неловкий момент, когда поросёнок Пётр не знает, что ответить.»
Меня поражает то, что за плохую шутку можно получить больше минусов в карму, чем плюсов за хорошую статью.
Просто вы сравниваете эффект от катастрофически ужасного комментария и умеренно полезной статьи. Эффект по модулю от катастрофически ужасного комментария и умопомрачительно потрясающей статьи примерно равный, тут всё честно. Проблема в том, что первое написать несравнимо проще, чем второе…
Видимо, хотим сказать, что хоть хабр и не для политики, но откровенная русофобия, особенно беспричинная, тут тоже не приветствуется.
Да ну какая русофобия, какая политика, бросьте… Это просто неудачная шутка.
Идиоты… да простит меня «работодатель» =)
А вообще от таких комманд надо бежать что есть мочи, ибо нет на свете большего зла, нежели держащийся зубами за кресло коллектив.
Бежать — в точку. Я решил с глобальными корпорациями не сотрудничать пока. ПередохнУть надо. В корпорациях — много денег, членство в фитнесс-клубе и бесплатные завтраки. И никакого личностного и професионального роста (и сплошной микрософт). Я вот сейчас решил вложить свои ближайшие пол-года в стартап. Полная анархия, любые технологии, лишь бы работало. Буду учить Erlang и Ruby, наверно.
Работаю год в стартапе, теперь вот охота в корпорацию, нервы уже заканчиваются на все эти «Полная анархия, любые технологии, лишь бы работало». Особенно устал от «лишь бы работало». С профессиональным ростом тоже не всё хорошо, учиться не у кого, спецов не хватает, что-то хорошо изучить самому тяжело, т.к. времени на изучение не всегда много, т.к. надо быстрее, а не качественнее…
На Ruby сидит вся Силиконовая долина, так что иметь в портфолио пару сделанных RoR проектов полезно для карьеры. Хаскель должен щупать каждый современный программер, потому как вправляет мозги и повышает качество кода (в свое время сделал первые 50 задачек из Project Euler на Хаскеле исключительно для этой цели). Но мне почему-то кажется, что для реальных проектов Хаскель нежизнеспособен. Я, конечно, знаю пару людей, которые на нем пишут всякие крутые штуки, но…
Блин, не Силиконовая, а Кремниевая. Кремниевая долина. Ну мы же образованные люди. Давайте называть вещи их именами.
Здравсвуй, брат, я уже не думал, что найду хоть кого-то, кто правильно называет это место. Спасибо.
До сих пор сидят? Я думал тренд прошел уже, или они теперь пожинают плоды?)
Реально сидят. Я вот сейчас искал себе работу, и недели не проходило, чтоб какой-нибудь агент меня не дергал насчет Руби в окрестностях Сан-Франциско. Я им — ну вы же резюме читали, нет там никакого Руби. Они — ну ты же веб-девелопер, вдруг знаешь. И насчет зарплат, Руби-девы у них там получают примерно так же, как ДжаваСкрипторы, что обычно процентов на тридцать больше, чем чисто ПХПшники. Вообще, я думаю, Руби-на-Рельсах у них рванул, потому что Джава — уже не модно, а .NET — не круто и для лохов Про .NET не я придумал, это мне один стартапер сообщил (Кстати, на днях прогорел уже со своими Руби :)
Что значит прогорел? И кстати, как же скала, она сейчас даже в Раше вроде в моде) Хотя судя по всему там по-быстрее мода меняется, чем в СФ
Скальщиков — единицы. Причина — сложно найти рабротников, так что нет вакансий. Вот и нет программеров. Такая же фигня с некоторыми другими технологиями. Я тут общался с владельцем одного видеохостинга (хотят побить Netflix), спрашивал, почему у них не Erlang. Ответ — невозможно найти программеров, ни за какие деньги.

А прогорел — значит прогорел. Не смог вовремя найти очередной мешок денег (с инвесторами не сложилось, наверное) и все.
Не, программеров-середнячков тут реально много. И у них весьма четкое разделение по национальному признаку. На эту конкретную позицию возьмут, скорее всего, китайца. Они весьма, хмм… усердны. И не лезут, куда не надо.
А можете подробнее рассказать про разделение по национальному признаку? Про разные национальности, по отношения к ним и т.п. Лучше даже отдельной статьёй. Было бы очень интересно почитать.
Раз пять начинал писать ответ, но все какой-то неполиткоректный расизм получается, хоть и заходил с разных сторон. Пробую в шестой раз.

Две американки филипинского происхождения (бизнес-аналист и проджект-менеджер) коряво рисуют wireframes и подробно расписывают всяческие user stories. Лондонское дизайн-бюро берется нарисовать/наверстать красивых HTML+CSS (на деле отдают на оутсорс индусам, а сами только правят конечный вариант, но в коде кое-где попадаются комментарии на индусском английском). Этот дизайн достается канадским китайцам (которые очень хреново говорят по-английски) которые, на самом деле, junior-Java-backend-что-то там, но упрямо делают вид, что пишут на джаваскрипте и ExtJS. Упорно с утра до вечера пишут горы кода, который все равно нихера не работает. Про тесты слышали, даже сделали чего-то там, но все равно билд запускают со --skip-tests, потому что иначе валится. Билд-система, естественно, на Maven (тяжелое Java-наследие). Спустя четыре месяца во время очередной демонстрашки к видеоконференции подключается один из CTO (канадец немецко-датских кровей), система некстати валится, все получают мощный втык (а кое кто и пендель под зад), а разработка переезжает в филиал в Hong-Kong, которые втихаря оутсорсят в Индию, по совпадению тем же индусам, которые рисовали HTML. Пока эти индусы делают вид, что работают, местные канадские индусы — спецы по Oracle валят систему и уходят в глухую несознанку, обвиняя во всем Jenkins (с какого-то перепугу). Тут неожиданно происходит десант разнокалиберного начальства, свежевыгнанных китайцев берут обратно на работу делать надстройку над java-middleware, местных индусов отправляют в Индию помогать тамошним индусам, нанимают еще филипинцев рисовать бизнес-диаграммы, пару канадцев и одного американца координировать девелоперов и через месяц проект окончательно клинит, потому что все на всех показывают пальцами и обвиняют во всех девелоперских грехах. Программить некогда — все круглосуточно сидят на митингах. Тут опять происходит явление CTO народу, китайцев опять выгоняют (потому что контрактники), индусы коллективно получают втык, говорят, что вся беда и зло от ExtJS и надо все переделать в Dojo, потому что IBM. Им дают карт-бланш и они нанимают субподрядчика для делания build pack'а, который благополучно растворяется в Лондонском тумане со всеми деньгами и сроками (догадайтесь с одного раза, какую компанию в Лондоне они наняли). Вот в этом месте наступает реальная задница, потому как новая система уже разрекламирована в национальной прессе, и даже брошюры уже отпечатаны и разосланы клиентам. Никто уже никуда не бегает, все (включая среднее начальство) спокойно сидят и рассылают резюме. Тут появляется русский девелопер. На самом деле он был тут изначально, просто его и его идеи никого не интересовали, а филиппинские тетки вообще четко, внятно и сразу сказали, чтоб он не лез, куда не надо. Сейчас же ситуация безвыходная, и все идеи хороши. А идеи такие — повыкидывать всю избыточную функциональность, оставить пару интересных опций, назвать этот минимализм первым релизом, убедиться, что оно выдержит пару сотен тысяч клиентов и, затаив дыхание, запустить в продакшн. Через неделю код в продакшне, а тим круглосуточно в офисе наживую фиксит баги под лидерством русского программера. Еще через неделю все выдохнули — все ведь зашибись работает. Еще через неделю филиппинские тетки опять начали рисовать wireframe'ы, индусские индусы — потирать руки в предвкушении заказов, канадские китайцы — пожимать плечами, потому как это все копошение не способно поколебать ихний дзен, а русский программер уволился нафиг. Ибо нефиг.

Я ответил на ваш вопрос?
Жаль что топику уже больше суток и этот комментарий мало кто прочитает. Из него могла бы получиться отличная статья.
Ну конечно же чуть приврал, как же без этого? Но вообще это все фактически срисовано с моего позапрошлого контракта. И это сейчас вспоминать весело, а тогда было ой не до смеха.
UFO landed and left these words here
Ну конечно же, я, кто ж еще :)

На самом деле так обычно и происходит. Наш программер обычно универсален, креативен и болеет душой за проект. Есть немного буржуйских начальников, которые это понимают и которым подходит такой стиль работы подчиненных. Тогда в компании получается сразу много русских программеров и контора тогда процветает. Праавда, бывает и наоборот — мы так же известны своим разгильдяйством и запросто можем ушатать крепкий бизнес :)
Я тоже в этом месте подумал про
 'undefined'===typeof b

или
 undefined===b

или
arguments.length
А если, говорят, сигнатура функции должна быть типа такой: add(num1)(num2)?

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

var sum = add(num1);
alert(sum(num2)); // алерт для примера, что бы что-то сделать с результатом

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

Возвращаясь к теме автора я не вижу никакой фактической полезности в этой задаче, умение сделать задачу с implicit преобразованием класса в функцию или число это похвально как хобби, но если это понадобится для проекта, либо активно там используется, то черт рад такому проекту.
UFO landed and left these words here
Мне как то раз так же ответили в Яндекс… почему то было обидно. :(
Вот вам ещё 3 теста, которые не проходит ваш текущий код:

assert.equal(add(0)(0.5), 0.5);
assert.equal(add('aa')(1), 1);
assert.equal(add('aa'), 0);


Лучше заменить parseInt(val+'', 10) на более стандартное приведение к числу +val (оно вызовет .valueOf), а если предполагаем что строки и другие объекты у нас считаются нулями (с чем я бы поспорил), то добавляем "|| 0". Получаем короче и симметричнее:

var add = function (orig) {
  var inner = function (val) {
    return add((+val || 0) + (+orig || 0));
  };
  inner.valueOf = function () {return +orig || 0;};

  return inner;
};
Вот возращением хитрых функций для последующего использования в JS я занимался, но вот рекурсивный вызов для ()() не попадался (кроме книжных примеров как с add). Это на практике где то используется?
вот мне тоже интересно, чего стараются добиться интервьюеры, предлагая подобные задачи на собеседовании? интересный трюк, забавный. но какова практическая польза? ведь, если кто-то напишет такой чудо-код для продакшен, сами же выгонят за проф.невменяемость.
Частичное применение вполне полезный прием, когда понимаешь как работает. Вот пример из живого проекта:

cas.on(cas.EVENT_CA_EXTENDED_MESSAGE, ui.emit.bind(ui, ui.EVENT_SHOW_POPUP));


Аналог без частичного применения:

cas.on(cas.EVENT_CA_EXTENDED_MESSAGE, function (message) {
  ui.emit(ui.EVENT_SHOW_POPUP, message);
});


Пробрасывает событие с новой меткой, почему бы и нет…
Ага, я что то подобное то же делаю, но не для экономии 2 строчек а сразу так 100. ;)
Только почему у меня странное дежавю… как будто это декоратор из Python.
придумать реализацию для функции высшего порядка, которой часто пользуешься — наивную как в underscore или быструю как lodash — почему бы нет. но в описанном случае ведь ежу понятно, что карринг и частичное применение функций — разные вещи. для карринга арность функции должна быть фиксированой (см. определение). а то что было предложено сделать это плод какого-то нездорового воображения.
В больших корпорациях подавляющее большинство технических интервьюеров — какие-то девелоперы, зачастую даже не имеющие отношение к отделу или проекту, куда хотят нанять человечка. Это вроде как обязательная отработка, сидеть на таких интервью (сам часто сидел, знаю). На таких интервью очень часто спрашивают заковыристые штуки, недавно прочитанные в какой-нибудь статье, и мало имеющие отношение к реальной работе или, что хуже, очень конкретно-специфические вещи (точные параметры функций, к примеру), которые никто не помнит, потому что они гуглятся за 10 секунд. В этом случае практической пользы не так чтобы много, но все-таки можно вытянуть разговор в нужное русло, чтобы очаровать остальных не шибко технических присутствующих товарищей. Главное – что? Главное — уметь решать задачи. Выкрутиться из такой противной ситуации — это тоже задача, так?
И меньшинство случаев тоже имеется. Реальные задачи, где надо в натуре понимать паттерны и шаблоны, потому как на этом у них строится вся кодовая база.
Ну и экстремальные случаи встречаются. Уникумы. К примеру, у меня был один такой — там в натуре надо было натягивать глаз на задницу через ухо — не просто написать тестовое задание, но написать его с использованием некоего фреймворка, и в задании были прописаны совершенно нежизнеспособные обязательные ответвления, чтоб использовать разные особенности этого фреймворка. Я там убил два с половиной дня, чтоб оно все заработало как надо, потому как документации практически никакой, комьюнити отсутствует, гугль ничего не знает, а код этого фреймворка ужасен в своей эпичности — фабрики классов, производящие другие фабрики и прочая прелесть. Была выдана даже ссылка на ютуб с презентацией этого фреймворка на какой-то конференции. Количество просмотров этой презентации было 78. За год. Наверно, половина просмотров — такие же несчастные соискатели, как и я. Муть полнейшая. Зато из презентации я узнал, что интервьюер — это как раз автор этого фреймворка. Мне потом агент сказал, что этот автор уже несколько месяцев пытается кого-то нанять на работу.
Дальше оптимизируем для множественных обращений :)
var add = function (n) {

    var orig = +n || 0,
        inner = function (val) {
            return add((+val || 0) + orig);
        };


    inner.valueOf = function () {return orig;};

    return inner;

};
по вашему примеру, если разрешить складывать произвольные значения, а не только числа:

assert.equal(add('aa')(1), 'aa1');

то получается еще короче:

var add = function (orig) {
  var inner = function (val) {
    return add(orig + val);
  };
  inner.valueOf = function () {return orig;};

  return inner;
};
Я не знаток в JS. Расскажите пожалуйста что это за странное начало кода it ('text', function () {? Я как бы понимаю ещё такое начало (function () { (создаём отдельный приватный контекст), но причём тут it и текст в начале? И желательно линк на чтиво.
Это же тесты так пишут. Если надо чего оттестировать, заворачивают код в describe('test name', function () { /* вот тут тестируемый код */});
Ну и всякие assert и should используют. Короче, visionmedia.github.io/mocha/
Премного благодарен. Никогда не связывался с тестированием JS, очень познавательно.
Интересная задача. Я не смог удержаться и прежде чем читать спойлеры в комментариях решил сделать свою реализацию )

var add = function (x) {
    x = +x;
    var adder = function (y) {
        y = +y;
        return add(x + y);
    };
    adder.valueOf = function () {
        return x;
    };
    adder.toString = function () {
        return x.toString();
    };
    return adder;
};

небольшой апгрейд :)

var sum = function (args) {
  return Array.prototype.slice.call(args).reduce(function (m, el) { return m + el; }, 0);
};

var add = function () {
  var orig = sum(arguments);
  var inner = function () {
    var val = sum(arguments);
    
    return add((+val || 0) + (+orig || 0));
  };
  inner.valueOf = function () {return +orig || 0;};

  return inner;
};

assert.equal(add(2, 0)(3), 5);
Скажите, а какой смысл делать операцию +||0 уже после sum()? По-хорошему, эту операцию должна сама sum делать.
вдруг кому-нить будет интересна такая задачка
function sum(a,b) {return a+b}
function mul(a,b) {return a*b}
var a = make(1)(2)(3)(4)(5)
var b = make(2)(3)(4)

a(sum) // 15
b(sum) // 9
a(mul) // 120 
b(mul) // 24

смысл понятен — применить к последовательности заранее не известную функцию
решили?
… а теперь тоже самое только без массивов )
Скрытый текст
function make(x){
  var args = [];
  function f(y){
    if(typeof y == 'function')return args.reduce(y);
    return args.push(y), f;
  }
  return f(x);
}

function make(x){
  function f(){
    var y = Array.prototype.pop.call(arguments);
    if(typeof y == 'function')return Array.prototype.reduce.call(arguments, y);
    return f = f.bind(null, y);
  }
  return f(x);
}

Вот только толку от второго варианта? :) Ни скорости, ни красоты функциональщины.
Я думаю, rmaksim имел в виду СОВСЕМ без массивов
function make(x) {
  return f(function(y) { return x; });

  function f(h) {
    return function(x) {
      if(typeof x == 'function') return h(x);
      return f(function(y) { return y(x, h(y)); });
    }
  }
}
Так во 2ом варианте массива и нет СОВСЕМ, только аргументы :) Хотя да, ваш вариант посимпатичней, после 3 дней без сна сразу до такого не додумался.
UFO landed and left these words here
Only those users with full accounts are able to leave comments. Log in, please.