Pull to refresh
12
0
Алексей Павлов @lexxpavlov

Программист

Send message

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

Спасибо за замечание🙏
Постараюсь в будущем учесть. +я поставил уровень сложности статьи "Средний". Хабр подсказал, что этот уровень для тех кто уже имеет некоторое представление о теме, поэтому я пренебрёг расшифровкой HR.
Сфера управления человеческими ресурсами сейчас сильно разрослась и включает не только КДП (кадровое делопроизводство) и подбор. Есть еще большие блоки про обучение, оценку персонала, бонусу и бенефиты, hr-брендинг, корпоративную коммуникацию (и еще несколько). В каждом направлении может быть сотрудник специализирующийся исключительно на этом направлении. Бывает, что один человек делаем кусочек из каждого направления.

Мой опыт разработки (больше восьми лет в разных командах) показывает, что лучше всего работает т.н. peer review — когда код проверяет коллега твоего же уровня. В этом случае роли чётко разделены:

  • Автор кода целиком несёт ответственность за свой код. Однако он не может оценить читаемость — для него его код всегда понятен — поэтому привлекает коллегу для code review.

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

Поддержка уровня читаемости кода — задача, с которой code review справляется, не добавляя лишних проблем.

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

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

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

  2. Есть один сеньор, который прекрасно ориентируется в проекте, но не успевает всё делать сам.

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

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

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

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

  • Миддлам обсуждать с сеньором реализацию до написания кода, а не после.

  • Дробить работу на задачи меньшего размера.

  • Сеньору прокачивать навыки ненасильственного общения.

  • Не играть в "бокс по переписке" в комментариях к ревью. Любой диалог длиннее двух реплик должен проходить в формате в очной встречи или созвона.

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

  • Писать юнит-тесты и настроить CI/CD на каждый пуш. Приступать к ревью только по факту успешного прохождения тестов.

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

Попробую написать спонтанный ликбез) Как получится, так получится.

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

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

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

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

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

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

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

А самолёт в атмосфере (реактивный) летит по сути так же, как ракета в космосе. Но он намного слабее ракеты, и не может лететь только отталкиваясь от струй сгоревшего топлива из сопел двигателей. Насколько я знаю, современные истребители могут какое-то время висеть хвостом вниз и даже подниматься вертикально вверх как ракета, но это недолго и неоптимально. Поэтому применяется хитрость: делаются крылья, которыми самолёт может опереться на воздух. Чем больше площадь крыльев и меньше лобовое сопротивление воздуха, тем слабее нужен двигатель. Планер вообще может летать без двигателя: его поднимают и поднимают вверх восходящие потоки, а он с них скатывается и скатывается, только успевай направлять его скатывание с одного потока на другой и можно висеть в воздухе хоть весь день; только со взлётом сложности — для взлёта всё-таки нужна мощность. Так что, если есть крылья, уже не нужен сильно мощный двигатель. А если самолёт винтовой или с турбиной, то он и вовсе отталкивается не от того, что сжёг и выбросил назал, а просто от воздуха, цепляясь за него лопатками турбин или лопастями винтов.
UFO landed and left these words here
На HN по этому поводу написали классный коммент :)

Итак, вы написали классную штуку, настало время её опубликовать:

1. Публикуете код под пермиссивной лицензией (MIT, BSD):
— А пусть им пользуются все, хоть их бабка!
— Вы умираете в нищете.

2. Публикуете код под копилефт-лицензией (GPL):
— Ни одна компания в здравом уме не подумает связываться с вашим кодом, а тем более не станет контрибьютить (разве что отделив его от того, что они считают своей интеллектуальной собственностью). Ну или они просто сопрут его, и вставят туда, где ваш код никто никогда не увидит.
— Вы умираете в нищете.

3. Публикуете код под коммерческой лицензией:
— Вас поливают грязью на HN.
— Никто им не пользуется.
— Вы умираете в нищете (вероятно).

4. Публикуете код под GPL + отдельной коммерческой лицензией:
— Вы постоянно судитесь со всеми т.к. все просто юзают GPL-версию (особенно если они могут спереть ваш код, и вставить туда, где его никто не увидит).
— Вы умираете в нищете.

Выберите свой стул.
UFO landed and left these words here

Все очень просто.
1) Не выделяй память, если можно не выделять
2) Знай какие операции блокирующие, а какие нет. Очевидно читать файл или слать запросы в сеть в гуёвом потоке дело неправильное.
3) Не городи абстракций в одноразовых решениях или на среднем уровне архитектуры приложения. Конкретный код, под конкретное бизнес решение, никогда не будет переиспользован.
4) Соблюдай стайл-гайд
5) Если пишешь костыль, оставь огромный комментарий с цепочкой размышлений, который привёл к появлению костыля.
6) Если условие сложное, разбей на несколько булевых переменных с нормальным названием и скомбинируй. Если невозможно (например сложная регулярка), то оставь понятный текстовый пример, когда условие срабатывает и когда не срабатывает.
7) Не используй редких английских слов в названиях
8) Погугли хоть раз в жизни " best practices".
9) Не пиши сложно и оптимально, если код вызывается раз в час/сутки/жизнь.
10) Даже если ты невероятно крут и умен, помни, что читать и поддерживать твой код будут люди менее компетентные. Это не значит, что надо писать хуже, но значит, что в каждой точке, над которой пришлось подумать и сделать неочевидно — нужно оставить комментарий.

UFO landed and left these words here
А кстати вот, в копилку холиварных тем-то — прививаться или нет. В красном углу ринга потрясают шприцами с «генномодифицированной отравой» «злые алчные фармакологи, наживающиеся на детях», в синем углу воздела ложноножки и хищно щелкает вакуолями столбнячная палочка.
На очередном заседании депутатов, решался вопрос про окурки.
— Господа, ну загажено же все вокруг…
— Давайте уже что то решать, уже…
— Выкидывают окурки где хотят…
— …
Согласительная комиссия провела опрос и выяснила, что основной причиной, которую граждане называют: отсутствие урн в шаговой доступности.
Тут же, активным депутатом Медником, был разработан законопроект об урнах…
Коммунисты, внесли поправки о стоимости урны, не выше 1000 руб. штука и едином стандарте урны на всю Россию.
СР потребовала перекраски урн каждую весну.
Спустя год. Трасса. Вечер. Пост ГИБДД.
— Здрав… бубубубубу… Ваши документы.
— Вот.
— Счастливого пути. Не забудьте перекрасить свою урну.
Мерседес в топовой комплектации отъезжал с поста, а на переднем сиденье пассажира, печально покачивалась урна, привинченная прямо поверх дорогущей алькантары нежно бежевого цвета.
Водитель, в который раз подумал, что когда будут перекрашивать урну, нужно бы вытащить, а то опять загадят весь салон дурнопахнущей краской веселого желтого цвета.
Спасибо за статью! Игра понравилась, но все же добавлю мнение.

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

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

На мой взгляд, врагов в таких играх имеет смысл делать сразу 3D. Не обязательно с нуля. На unitystore есть куча моделей животных с анимациями. Покупаете пакет, вытаскиваете меши и отдаете дизайнеру на доработку. Чтобы из стандартных животных сделал фантазийных. Изменил пропорции, добавил элементы и т.п… Работа несложная, недорогая. А главное, даже кардинальные изменения могут не задействовать скининг (конечно если моделер это учтет), соответственно можно пользоваться готовыми анимациями.

Для гуманоидальных персонажей тоже есть хорошие инструменты, например, Adobe Fuse — для моделинга (с готовыми анимациями), Marvelous Designer — для одежды и т.п. Там есть готовые персонажи, и превратить человека в тролля можно буквально за несколько минут. Еще плюс в том, что ваши персонажи мелкие. Можно не стараться прорабатывать детали.
UFO landed and left these words here
Аргумент «есть люди, которым еще хуже» очень подлый и неконструктивный.

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

Во-вторых, что частично вытекает из первого, как вы предлагаете сравнивать, чьи проблемы серьезнее? Есть какая-то объективная численная метрика, типа там, «у Нотча проблемы на 123.8, а вот у меня на 153.2»?

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

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

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

Несколько советов:

1. Попробуйте встроить в игру код баннерных сетей, баннерообменок и видеорекламу (если их еще нет), и:
— монетизироваться через рекламу (полноэкранные баннеры это ОК),
— предлагать пользователям небольшие плюшки (бонусные уровни, звезды) за просмотр видео от Vungle или AdColony,
— направлять траффик со старых приложений на новые (для увеличения популярности) — Chartboost отлично это делает.

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

3. Есть ли в ваших проектах окна типа RateMe (напоминание через 7-10 минут игры поставить ей оценку в сторе)? Хорошие оценки и их число положительно сказываются на установках.

4. Добавьте на скриншоты игры короткие слоганы с перечислением достоинств, типа «Стопиццот уровней», «Реалистичная мышиная физика» (убедитесь, что они хорошо читаются с телефона).

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

Dojo — dojotoolkit.org/reference-guide/dojo/declare.html#dojo-declare
Sencha (ExtJS) — www.rogerwilco.ru/2011/04/sencha-extjs.html
qooxdoo — qooxdoo.org/documentation/0.7/oo_feature_summary
MooTools — www.phpeveryday.com/articles/MooTools-Basic-Creating-Classes-MooTools-P919.html
Prototype — www.prototypejs.org/learn/class-inheritance
AtomJS — github.com/theshock/atomjs/blob/master/Docs/Class/Class.md
JSClass — jsclass.jcoglan.com/classes.html
code.google.com/p/jsclassextend/
github.com/jcoglan/js.class
Cobra — justin.harmonize.fm/index.php/2009/01/cobra-a-little-javascript-class-library/
github.com/JustinTulloss/cobra
The $class Library- www.uselesspickles.com/class_library/
Classy — classy.pocoo.org/
YUI 3 — www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/
Coffee-Script — jashkenas.github.com/coffee-script/#classes
JavascriptClasses — code.google.com/p/javascript-classes/
AJS — amix.dk/blog/post/19038
jsFace — github.com/tannhu/jsface
JsOOP — jsoop.codeplex.com/
joot — code.google.com/p/joot/wiki/API
oopsjs — code.google.com/p/oopsjs/
Objs — github.com/tekool/objs/wiki
oorja — maxpert.github.com/oorja/
objx — code.google.com/p/objx/wiki/OClass
jsclassextend — code.google.com/p/jsclassextend/
prolificjs — code.google.com/p/prolificjs/wiki/OOP
objectize — code.google.com/p/objectize/

code.google.com/p/core-framework/wiki/Inheritance
code.google.com/p/sfjsoo/
code.google.com/p/jslproject/
code.google.com/p/magic-classes/wiki/MagicClassesOverview

github.com/ded/klass
github.com/jiem/my-class
github.com/kilhage/class.js
github.com/Jakobo/Sslac
github.com/BonsaiDen/neko.js
github.com/finscn/GT-Class
github.com/deadlyicon/klass.js
github.com/neuromantic/CodeJS
github.com/cj/js-oo
github.com/darthapo/klass.js
github.com/nemisj/zet.js
github.com/k33g/species
github.com/benekastah/JS-Class
github.com/tobeytailor/def.js
github.com/rstrobl/squeakyJS
github.com/shinyplasticbag/MojoClass
github.com/firejune/class
github.com/gcoguiec/jquery-class
github.com/daffl/JS.Class
github.com/pavelz/class.js
github.com/zerodogg/jqsimple-class
github.com/bnoguchi/class-js
github.com/arian/Klass
github.com/kuwabarahiroshi/joo
github.com/iamleppert/SimpleClass
github.com/aenoa/Noode.js
github.com/stomlinson/SuperClass
github.com/jzimmek/klazz
github.com/kbjr/class.js
github.com/jhnns/node.class
github.com/borysf/declare/blob/master/declare.js
github.com/ShadowCloud/BF-Class
github.com/pic-o/jsClass
github.com/rosamez/jquery.klass
github.com/yuki-kimoto/javascript-Class_Simple
github.com/yaksnrainbows/jarb
github.com/thirashima/UnderClass
github.com/arahaya/package.js
github.com/arieh/Class.def
github.com/bogdan-dumitru/jsClass
github.com/pomke/pomke.js
github.com/sgolasch/jClassify
github.com/kbjr/Classy
github.com/cthackers/jClass
github.com/davidjbeveridge/Clasico
github.com/edave64/protojazz
github.com/mrac/solid.js
github.com/benekastah/Classy
github.com/damianmr/JSMiniClass
github.com/benekastah/classesWithCash
github.com/dialog/Resig-Class
github.com/mpodriezov/OJS
github.com/dtinth/twcs.js
github.com/percyhanna/js-class
github.com/jalopez/SimpleClassJS
github.com/jhamlet/proteus
github.com/petebrowne/classify
github.com/TdroL/Classy.js
github.com/azendal/neon
github.com/aulizko/Alan-Point-JavaScript-Library/tree/master/src/oop
Ещё можно юзать такие правила на файрволе:

#TCP Filters ##
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
#SYN+FIN
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
#SYN+RST
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
#FIN+RST
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
#FIN w/o ACK before
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP 
#PSH w/o ACK before
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
#URG w/o ACK before
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP


Information

Rating
Does not participate
Location
Саратов, Саратовская обл., Россия
Date of birth
Registered
Activity