singalen: (Default)
Треба і собі так зробити. Якщо буде що писати, гиги.
https://github.com/jbranchaud/til
singalen: (elvish_piper)
А что сейчас начинающим рекомендуют читать об ООП?
Раньше читали GoF или Бадда, а сейчас - ХЗ. Уйма паттернов типа State устарела, и Observer теперь почти всегда Listener или Callback, и State теперь обычно - Model из MVC, и MVC уже совсем другой.
Говорят, вот "Head First Object-Oriented Analysis and Design" ок? А что ещё?
singalen: (Johnny)
Ответ написался интересный, расшарю.

О преимуществах - процитирую свой диалог с товарищем.

N: почему некто переходит к вам с некоторого стабильного проекта?

V: При прочих равных...
Может, потому, что в стабильном проекте ты ни на что не влияешь и ничего нового не создаёшь, а так, правишь баги в системе раздачи баннеров?.. :) А здесь я реально вижу, как эта штука у меня в руках начинает шевелиться. От меня зависит вид конечного продукта и судьба компании. Я создаю что-то, чего раньше не было, что-то такое, что я и себе домой хочу поставить :)

А стабильность - мне надоела стабильность стеклянного потолка.

Здесь, в оффшоре, в аутсорсинге, никого старше лейтенанта не нанимают - все CxO на той стороне.

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

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

2. Мало кто, считая основателей, имеет опыт разработки продукта с нуля, когда нужно и сформировать видение продукта, и построить план (и бизнес-план), и построить план реализации, и архитектуру системы, и выбрать технологию, и чётко пройти по плану... организационные болезни, повторюсь, могут быть любыми. И если в корпорации какя-нибудь болезнь может тянуться десятилетиями в хронической форме, то в короткой и яркой жизни стартапа вы получите все симптомы в острой форме, упакованными в полгода.

3. Стартап может прогореть. Но это не страшно - см.п. "Преимущества".
singalen: (elvish_piper)
Смотрел я тут на приглашение на местный ивент — "Выстраивания процессов коммуникации, создание взаимоотношений со своими коллегами и заказчиками, подчиненными и высшим руководством".
И думал: "ну какой нахрен "процесс выстраивания взаимоотношений"?" Что за буллшит? Ты делаешь то, что от тебя нужно, толково и честно, насколько можешь". Я вообще оппортунист и не люблю формальный подход к людям.

А потом мне эта мысль напомнила замечание от молодого, и, очень, зараза, умного, человека, о книге, "PoEAA": "Ну кому нафиг нужны эти паттерны? Это же всё и так очевидно!"
Я тогда ответил, что паттерны - это язык. Одно слово этого языка описывает одновременно проблему, решение, и пределы его применимости.
И, по аналогии, весь буллшит вроде "build trust relationship", "establish communication channel", "manage expectations" и т.д. по букварю менеджмента - тоже язык паттернов.

Развиваем аналогию. Говорить, что "у меня прописан процесс выстраивания отношений" — это так же осмысленно, как гордо заявлять "мы используем паттерн Observer": может быть, ты описываешь адекватное решение, а может быть, в своей лабе (или, хуже, в первом проекте) тренировался применять все паттерны из ттолько что прочитанной книжки.
Любой процесс лучше, чем никакого? И да, и нет. Да — потому что не даёт забыть о типичном списке важных вещей. Нет — потому что, если ты делаешь процесс ради процесса, у тебя получится формальная и непрактичная хрень.

С упрощения начали, упрощением закончим. Чтобы быстро понять, к месту ли применяется процесс, задайте себе вопросы: какую проблему решает пункт плана "manage expectations"? Каковы пределы его применимости, когда имеет смысл прекратить этим заниматься?
singalen: (2002)
Это же прекрасно:
width = Math.max line.length for line in map
Впрочем, и на Груви неплохо:
def width = map*.length().max()
singalen: (freeman)
А вы, товарищи андроидные программисты, знаете, что можно установить в SDK intel-x86-шото, и, если у вас включена апаратная виртуаизация, то Android будет выполняться в родном Интеловском коде? То есть, в 5 раз быстрее, чем эмулируемый ARM.
И GPU хоста он тоже умеет юзать.
singalen: (hope_never_dies)
Жаль, не вижу, как продавать CAD/CAM. А не то у меня вот сейчас в кармане был бы неплохой продукт.
singalen: (Default)
Если std::ifstream(char* ) рушится сам по себе - это убеждает в правоте автора C++ FQA.

Heatmap?

3/1/12 20:11
singalen: (nerd)
Коллеги, кто пользовался сервисами для анализа активности веб-юзеров, с хитмапами и т.п.?

Я сходу нагуглил это:
https://www.crazyegg.com/overview/3
http://www.seevolution.com/features

но, может, кто-то чем-то пользовался и может порекомендовать?
singalen: (Default)
На докладе по легаси на expert labs меня спросили: зачем рефакторинг?
То есть, рефакторить, конечно, можно, но какая в этом цель?

Я тогда не сформулировал чёткого ответа, только пробулькал что-то про критичную подсистему, которую можно отделить и заменить.

И правда, сам по себе рефакторинг — процесс ненаправленный, хотя помогает изучить код. Одновременное существование рефакторингов "extract method" и "inline method" это доказывает.

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

И да, у работы с легаси должны быть SMART цели, "иначе бросание будет пустою забавою".
singalen: (кричал я из последних сил)
- Скоро процессоры станут такими мощными, что потянут любые задачи.
- Не скажи. Всегда можно написать какую-то херню. Если процессор выполнит её быстро, её можно в цикле выполнить миллион раз. Или в тысячу потоков. Или на кластере. Херня прекрасно масштабируется на любое железо.
singalen: (2002)
Вы часто получали от сайтов ошибку "502 Bad gateway блабла nginx 0.8"?

Почему люди вообще пользуются nginx-ом как кэширующим прокси, а не, скажем, Varnish-ем? Я знаю, nginx супер-быстрый.

Но если бэк-эндовый сервер ляжет, скорость nginx-у не поможет. А Varnish можно настроить на несколько бэк-эндов.

Мне видится такая схема:
* миррорим сайт в статический HTML;
* выкладываем эту статику хотя бы и в nginx;
* ставим фронт-эндом Varnish, а двумя бэк-эндами - основной сайт и статическую копию.

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

Есть накладка с content-type: если сайт выдаёт HTML без расширения, то wget --mirror и сохранит его без расширения, а статический веб-сервер не сможет сказать, какой это тип контента. Впрочем, если без расширений только HTML, то вот и вариант решения: wget --html-extension и вуаля.

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

Выглядит вполне жизнеспособно. Интересно получается.

Кто встречал что-нибудь подобное?
singalen: (humpty-dumpty)
Послезавтра (в четверг, 22го, в 18:30), Ciklum.

Продал его как ПМ-скую тему, что недалеко от истины.
Заходите :)

Ивент в фейсбуке, в линкедыне.
singalen: (Shunsui Kyōraku)
Придумал доклад-статью. Мыслей крутилось много, но как начал записывать - они куда-то схлынули, осталось немного флуда.

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

Если можно, с примерами и своими соображениями :) А я вас в докладе использую :)

Под катом мои соображения.

Существует “правильный” способ делать что угодно

и те де )
Это частный случай проблемы талантливого ребёнка - он с детства привык, что у него всё получается легко, с пол-пинка, и потом, если что-то получаться перестаёт, он начинает искать проблему в чём угодно - в коде программы, её архитектуре, операционной системе, "этой стране" - только не в себе.
singalen: (Default)
Искал веб-компонент, который умеет добавлять/удалять группы полей в форму. Или хотя бы как это называется :D

Нашёл сначала кусок кода (демо), а потом папа [livejournal.com profile] cray_flatline по нужным словам нашёл ещё:

* jquery-dynamic-form (демо)
* dynamicField (демо).

Други, кто знает что-нибудь получше?
singalen: (Default)
Завтра с товарищам читаем четыре 15-минутных доклада по тулзам управления проектами.
Мой — Redmine. Презенташка тут.

Желающие могут зайти послушать.
singalen: (Default)
Есть такое слово в английском жаргоне - "без мозга". Притащил я его из MtG. Относится к ситуации выбора: если выбор укладывается в определённый шаблон - то в 99.9% случаев надо делать шаблонный же выбор, не думая.

В программировании я сходу могу назвать такие вопросы-ноубрейнеры:
  • Много мелких классов или несколько крупных?
  • Знакомая команде технология или новая?
  • Вкладывать ли дополнительные усилия в оптимизацию с самого начала? Оптимизировать ли то, что ещё не измерил?
  • Написать самому или взять готовое - точно известно, что оно работает?
  • Если для воспроизведения (и каждого цикла тестирования) бага нужно более 15 минут, писать ли юнит тест?

А какие ноу-брейнеры назовёте Вы? И с какими из этих поспорите?
singalen: (Киораку)
Окончание. Начало здесь, вторая часть здесь.

Часть третья


Получили невероятное удовольствие. Оно было бы ещё больше, если бы мы на второй день таки-вывели и написали универсальный компилятор в LtG — но увы :D
Всё идёт к нулю

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

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

Примерно таким же тонким слоем чувствовали себя мы перед чемпионами, потому что:
  • надо было овладеть новым, "магическим" языком;
  • он почти что так и назывался - только слово Magic заменили словом Lambda;
  • мы тыкались в темноте, оттачивая комбинации наших примитивных эмпирических "заклинаний";
  • те, кто освоил теорию, в мгновение ока (от 200 до 900 ходов) выносили "в ноль" наш тщательно, вручную подобранный раш.
Не отпускало нас потом ещё два дня.

  • Браузнуть сырца можно тут: http://svn.victorsergienko.com/icfpc2011/trunk/domain-model/
  • Итого — примерно 71К на Груви + 35К юнит-тестов на нём же.
  • Нам не хватало как минимум одного, третьего программиста. И вообще, два программиста и два математика — это в четыре раза слабее, чем четыре программиста-математика. У японцев-Atomic-ов, которые, наверняка, станут чемпионами, как раз столько и было :)
  • Команда Ciklum бултыхается где-то в полупроходниках со своими 21-23 победами из 30 на неофициальном сервере.

А как оно было у японцев...


Четыре японских хаскеллиста:
  • собирали части пушки в разных словах (потом оказалось, что иначе в этом SKI-исчислении никак);
  • авто-компилировали все стратегии;
  • умели, если им что-то сломали, оживлять ячейку и продолжать любую (!) старую стратегию с того места, на которое возможно откатиться (!!!), и собирали подходящие запчасти по разным слотам (!);
    • У меня самовосстанавливаться умеют только две очень частных стратегии - dec() слабой ячейке врага, и revive() своей.
  • ещё они написали свой тестовый-контестовый сервер — от нечего делать, надо полагать.
  • эти монстры научились убивать "sitting duck" в 165 ходов.

Вот у меня недавно [livejournal.com profile] dima_kender спрашивал старый вопрос — какой язык программирования лучше для быстрой разработки :D

Я ответил старый ответ — язык, который хорошо знает команда. Ну и смотря чего разработка — десктоп, простой веб, рич веб, сложная логика или CRUD, с БД или без.

И дал свои предварительные ответы, при прочих равных:
Для веба — Rails, для десктопа — Windows.Forms.

Но если программисты и задача пыц-пыц какие умные, то Haskell, как показали последние дни.
singalen: (go-go-go)
Они заряжают пушку!
Зачем? Они будут стрелять!
В кого? В нас!

Продолжение. Начало здесь.

Команда



В этот раз я не собирался созывать команду программистов со всего города, а захотел ограничиться родной конторой. Записалось четверо, но в конце концов из них остался только старый олимпиадный товарищ Максим ([livejournal.com profile] mihmax).
В прошлые годы нам сильно не хватало математиков, поэтому в этом году мы привели аж двоих - Леонида (без ЖЖ) и [livejournal.com profile] nushasmall.

Мы с Максимом решили писать на родном Groovy, на котором пишем уже 2 года. Добавили к нему Groovy++, чтобы оно компилировалось так же эффективно, как Java (и оно так и было! правда, не без странных ошибок)

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

В этом году всё было не так.
много и сумбурно )

По ходу дела


(писать в stdout нельзя - сервер не поймёт вывод программы и засчитает техническое поражение. Мы как-то полтора часа одну такую шнягу ловили)
...сбросил на телефоне звонок от жены. Это хуже, чем писать в stdout.

...(третья доставка за два дня):
— Вам наша пицца нравится, да?
— Очень кушать хочется!

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

Окончание следует.
singalen: (freeman)
Если добавить зомби, всё становится круче.
Мила Йовович


Пока японская трава не отпускает, надо писать.
Наша команда, кста, прославляет своим названием (и, надеюсь, бе-ме результатом) компанию Ciklum.

Последние три дня прошли в зомбическом угаре.
Задание на очередное соревнование ICFPC японцы придумали на редкость удачное, хотя и слишком умное для нас :D

В этом году програмы участников должны играть друг с другом в некую Lambda: the Gathering - гибрид Magic: the Gathering, SKI-исчисления (вот пример готового языка) и машины Тюринга.

Правила


Если вкратце, у двух игроков есть:
  • 15 видов "карт", каждая из которых - это функция;
  • игровое поле из 256 ячеек. У ячейки есть "жизнь" (в начале игры - 10000) и "значение" (число или функция), в начале - функция I(x)=x.
Зомби

Вот примеры карт-функций:
  • I(x) возвращает x
  • succ(x) возвращает x+1
  • copy(i) возвращает значение i-й ячейки врага
  • attack(i, j, n) бьёт (255-j)-ю ячейку врага на 9n/10 жизней, ценой убавления n жизней у нашей i-й ячейки;
  • zombie(i x) садит в (обязательно мёртвую) (255-i)-ю ячейку врага шпиона-зомби с функцией x, который будет делать на поле врага всё, на что запрограммирован; там есть нюансы, о них позже;
  • revive(x) оживляет мёртвую ячейку и даёт ей 1 очко жизни.

Ходы. Игроки ходят по очереди. Каждый ход:
  • сначала наступает "час зомби", когда подсаженные врагом зомби ("см. рис. 1") автоматически вылазят из могил и делают своё дело, противное всему живому;
  • потом игрок применяет (вычисляет) одну из 15 "карт"-функций к значению одной своей ячейки,
  • или же наоборот, применяет значение (тоже функцию) из одной "ячейки" к "карте".
  • если функция вычислилась без ошибки, то результат записывается в ту же ячейку;
  • в любом случае, у вычисления функции может быть побочный эффект, который остаётся.

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

Например, функция K(x, y), применённая к x, вернёт другую функцию - Kx - которая, применённая к любому y, вернёт x ("запомнит" x, а y выбросит). Таким образом, K позволяет отложить вычисление x столько раз, сколько K мы навесим на x.

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

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

В "час зомби" функции, меняющие здоровье, работают "наоборот": inc() уменьшает на 1 нашей, а dec() увеличивает вражеской ячейке; attack() всё так же платит здоровьем нашей, чтобы увеличить (!) здоровье вражеской, а help() не "переливает" из одной нашей в другую, а уменьшает здоровье обеим. Собственно, help() в функции зомби — самое мощное атакующее оружие.

День первый


Вот сели мы за это задание...

Продолжение здесь, окончание здесь

March 2023

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 

Syndicate

RSS Atom
Page generated 6/7/25 10:33

Expand Cut Tags

No cut tags