← All posts tagged программирование

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

Вот есть ресурсы, которые расшарены между сессиями (операторы составляют пакеты задач, которые станут расписанием для ресурсов). У каждого ресурса есть свой приоритет типа статический, меняется только применением самого ресурса где-то. То есть, если ресурс "занят" в 5 процедурах за день, то его статический приоритет равен 5, условно. Есть приоритет динамический, зависит от текущего набора задач во всех сессиях, где этот ресурс потенциально может быть использован. Ядро умеет всё это дело динамически крутить-вертеть и компоновать так, чтобы операторы получали непротиворечивые данные, чтобы ресурсы не были забронированы одновременно на несколько задач.
И вот есть закавыка — оператор в определенных условиях может начать бронирование с определенного ресурса. То есть, сначала выбран ресурс, а потом уже накидываются задачи. И бизнес пожелал, чтобы при постановке задачи, при распределении исполнителей на роль в первую очередь был выбран тот ресурс, с которого оператор начал сессию бронирования. Казалось бы, чо там — приоритеты же. Но оба приоритета блять обслуживаются централизованно, ядром. А тут в сессии надо просто изначально "предпочесть" ресурс! Были мысли и про модификаторы и про сессионный процессинг. Полный пиздец, очень накладно.
Тут на помощь приходит гуй! В интерфейсе оператор может по своему усмотрению сменить исполнителя в роли, на любого из доступных. Это норм, это user action, всё зашибись. Ну так и давайте типа оператор "кликнул" первым делом на наш этот ресурс, чо там :)
Всё работает, все довольны, зашибись. Только вот смотрю на это с т.з. алгоритмистики и data flow. Взяли задачу, выдрали нужные "роли", собрали ресурсы, посчитали занятость, отобрали подходящих, отсортировали по приоритетам, построили расписание, выдали сессии все расчеты, выгрузили в гуй. И тут же блять "кликаем", повторили весь цикл заново :)
Атас. Не делайте так.

PS. Это вопрос проектирования и архитектуры, есичо. Не предусмотрели в начале.
Vugluskr
работа программирование Есть специфический проектик. Морда на ваадине, унутрях — спринг с этими вашими DI и хибернейт с этими вашими ентитями.
Помимо обычных юзерских сессий есть сессии логические — по редактированию и коллективному резервированию общих ресурсов.
4-ый день решаю задачку по корректному захвату и отпусканию ресурсов.
Доходит до маразмов. Есть сложная многокомпонентная форма из нескольких, не связанных между собой блоков. Один из блоков — листинг контейнеров. В каждом контейнере — набор ресурсов (уникальный). Еще один из блоков — нечто вроде графика Гантта, отображение занятости ресурсов. Когда в графике окошко двигают — што-то меняется, в табличке нужно данные переписать. Когда в табличке что-то меняют — в графике нужно соответственно кубики подвигать. Ну суть понятна, да? Ну так вот всё сделали, а блять удаление всего контейнера забыли. Просто в диздоке забыли нарисовать кнопочку удаления :) Ну и экстренно встраивать, понятно. Кнопочка — в табличке. Сделал сначала тупо — по нажатию в табличке дропается строчка, из общей сессии удаляется контейнер, все заинтересованные оповещаются, мол, изменился набор контейнеров (как на добавление), ожидалось, что всё перерисуется и хоп-хей-лалалей. Хуй там! Как водится, всплыли нюансы. В табличке либо не должно быть совсем элементов (контейнеров), либо если есть хоть один — то какой-то всегда "выбран". И вот есть краткий миг, если удаляют выбранный контейнер, когда в табличке есть элементы (она не пуста), а не выбрано нихуя. И тут наступает полный пролапс гениталий. NPE выпадает аж в 5 местах сразу.
Акей, думаю я, пойдём умным путём — сбросим селекшн на соседа, а сами удалимся. Хуй там! Спасибо ебучему клиент-серверу и выбранной концепции "курсора" в общих сессиях — не успевает селекшн переделаться, как мы ломимся со своим удалением и наступает ожидаемый пиздец с NPE.
Акей, думаю я (на третий день ебли), пойдём ваще-пиздец-каким-умным путём — сделаем состояние Stop-The-World на всей морде пока идёт удаление! Дитынахуй сказал мне ваадин, ничо не знаю, у меня всё ровно! И продолжил сбрасывать селект на табличке, точнее, клиент шлёт анселект и дальше всё крутится-вертится невзирая на эти ваши остановки мира :)
Акей, думаю я, щаз сделаем железобетонную логику событие-листенер на ебучее удаление. Делаю, всё железно, всё в тестах збс. И тут на сцену выползает старый добрый сука хибернейт. Ой, а что это вы объектик не отпустили, не евиктнули, а удаляете?! Ненене, так не пойдет, идите-ка вы на хуй, на всякий случай. На этом моменте взвыл. Рвал, метал, вспоминал всех добрыми словами.

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

Ебаный экибастуз.

Дизайнеры! Рисуйте внимательно, бля!
Архитекторы! Проектируйте внимательно, бля!
Манагеры! Горите в аду, сука, со своими ебучими "щаз мы тут костылик за полчаса слепим"!
Vugluskr
Java программирование popcorn прокино прожизнь *длядуши Не так давно я рассказывал про хуйнюшку, которая фильмы качает домой с сервака. С тех пор я всё это время с ней сношался вечерами. И вот наконец версия 0.99 готова. Что в результате имеем. Сервер — мониторит transmission на предмет скачиваний. Для каждого торрента, если тот содержит фильмы (определяем по расширению), создает запись, ломится в imdb, если находит что-то подходящее — берем название, делаем .nfo, берем постеры и баннеры. Если это сериал — то создаем структуру сезонов-эпизодов. Для фильмов картинки берутся с fanart, для сериалов — с tvdb. Если всё нашлось, то при отстуствии действий со стороны админа, через час фильма будет выставлена на скачку для клиента, если она уже докачалась в трасмишне; если не докачалась — подождем докачки, потом так же час буферного времени и вперёд. Если не нашлось (название торрента совсем хуёвое), то будем ждать админа. Админ через веб-интерфейс может поправить всю детализацию, удалить к хуям, добавить/заменить постер/фанарт и т.д.
Клиентик. Живет дома, раз в N минут ломится на сервак, в сокет. Посредством json-протокольчика они с сервером обемниваются данными — авторизация и каталог доступного для скачивания. Клиент определяет, что ему нужно скачать. Смотрит на размеры файлов, делает разбиение на потоки. У клиента есть несколько ограничителей:
— количество потоков на скачивание лимитировано
— в конфиге настраиваются так называемые caps — ограничения по дням недели и/или времени суток. Штоп оно не жрало весь наш дохленький канальчик, пока мы с женой всякие вконтактики вечером читаем.
— каждый поток скачивает не более N байт от файла.
То есть, например, если файл — 25 гиг, клиент разбивает задачу на 75 частей по 330 мб (условно) и начинает это дело сосать. Итак, после всех ограничений, клиентик определил что ему качать, можно ли качать (не забит ли пул тредов) и каким образом ему качать (медленно и печально или стремительно и борзо). После этого, он опять общается с сервером, запрашивает разрешение. Сервер выдает ключики, клиент открывает коннекты на другой порт и начинает сливать доброе добро в несколько горл. Тредики пишут в один файл асинхронно, ведется учет меток и позиций. Есть обслуживание обрывов связи, зависания рутера, отказа канала. Есть принудительное понижение "жадности", если отклик хуевый. Есть возвраты и перекачивание частей, если вдруг учет лажанул.
По окончании скачивания, берутся баннер/постер, nfo, всё это дело правильно именуется и укладывается, и в финале дергается ненаглядный попкорн, штоп он проапдейтил свою базку, на предмет новой фильмы.

Чего хотелось достичь. Во-первых, минимизировать моё человеческое участие во всём процессе. Этого я достиг полностью. Если начальный торрент называется хоть как-то более-менее правильно, то практически наверняка всё случится само собой. За это спасибо imdb-шному поиску — релевантность выдачи крайне на высоте.
Во-вторых, постеры-баннеры. NMJ встроенный в попкорн в этом плане хромает на все 4 лапы, сука. Самостоятельно постоянно промахивается и не находит картинок. А смотреть на правильные обложки/задники гораздо приятнее, чем на умолчательные картинки.
В-третьих, непрерывность процесса. Я постоянно забывал перебрасывать скачанные фильмы, апдейтить попкорн. И плюс ко всему, ставишь на закачку из дома — рутер повис или канал ебнулся и все встало раком. Раздражало пиздец. Это тоже победил.
В-четвертых, хотелось сделать клиентик "одним куском" без ебнутых зависимостей, без базы данных, без развесистых настроек. Этого достиг. Один jar, с одним конфигом из 10 строк. Можно отдавать друзьям, можно качать с другого места и т.д. Переносимость, мультиплатформенность, етц :) Java rulez.
И последнее. Ставишь сливаться большой файл. Жена детей накормила, спать уложила, села в чятиках болтать, а канал засран шопестец, она начинает ныть, мол "интернетов нету". И так каждый день. Очень хотелось сделать нормальный шедулинг. Тоже сделано.
Итого, я отличный молодец, все поставленные цели успешно отпобедил.
Vugluskr
Java программирование Почему-то многие недооценивают мощь, силу и красоту enum. Периодически натыкаюсь на случаи реализации развесистых интерфейсов и имплементаций для лимитированных наборов значений. Явно же можно обойтись енумом. Но как оказалось мало кто знает (и даже предполагает), что енум может имплементировать интерфейсы, иметь свои методы (включая абстрактные) и разные конструкторы. То есть, не предполагают гибкости. А она есть.
Vugluskr
программирование прожизнь Иногда поражаюсь быдлокодерам. Казалось бы, очевидные базовые истины всем должны быть известны, даже тем кто учился программить по самоучителю для чайников:
— взял ресурс/память, попользовал — освободи его, мать твою, долбоёб! Открыл стрим/дескриптор/ресурс — закрой за собой!
— если ресурс разделяемый (используется параллельно) и ты его чем-то меняешь — ну блять, сделай лок, уведоми других, сука
— избегай глобальных вещей — открытых всем ветрам объектов, переменных, методов. Особенно, блядь, глобальных переменных. Научись, козлина, делать константы и конфиги.
— изменил што-то — запиши (зафиксируй) только это что-то, а не весь объект/ресурс целиком.
— заново инициализируешь структуру/коллекцию/контейнер — ну очисти от старого говна сначала, тупое ты животное, блять.

Так ведь хуй же. Головой-то думают единицы :(
Vugluskr
программирование прожизнь Долго трахался с генерацией пдф, никак не мог сообразить как же блять соотнести реальный размер букв с задаваемым размером шрифта. Дошел до совсем уж извращений. Вроде как всё сошлось. Визуально — акей, канает. Но сомнения гложут. Решил померять натурально, чтоб уж быть уверенным. А линейки-то хуй. День потратил, думал купить в книжаре, забыл заехать. Сегодня, блять, осенило. Сгенерил и напечатал линейку :)
Осенение спрогрессировало, сгенерил сетку-миллиметровку, отпечатал весь док на ней. Всё оказалось тютелька в тютельку.
PS В процессе всей ебли выяснилось, что принтер у меня старенький, он не умеет печатать на нижних пол-дюйма страницы. И это не лечится никоим образом.
Это была славная битва.
/me закурил и отвернулся к стенке
Vugluskr
работа программирование vaadin вынамписали Вот какое впечатление на непосвященных производит ваадин:

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

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

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

Как могут заметить все наблюдательные — я не включил сюда ничего из того, што обычно важно для айтидрочеров — наличие/отсутствие каких-либо модных фреймворков, покрытие кода юнит-тестами, соответствие технологий времени (бгыгыгы), читаемый и красивый код, наличие/отсутствие микрооптимизаций, использование/игнорирование каких-либо "движков".
Всё это идёт в хуй. Конечному юзеру (для которого делается софт, на минуточку) это всё глубоко по хуям. Его интересует, штоп работало и не глючило. Родили вы это в пароксизме скрама и agile-блудняка или же выдавили единолично, по строчечке в течение 10 лет — юзеру до пизды. Красиво вы написали или некрасиво — ещё раз по хуям и до пизды.
И да, ещё. Юзер знать не знает про всякие ваши дедлайны, переработки и прочую рутину. Ему похуй, сделали вы это за 2 дня или за 2 часа. И даже если он узнает, што "этот модуль был написан за 3 часа!" — ему всё равно будет похуй.
Vugluskr
работа программирование прожизнь Меня "аж трисёт", когда вижу хардкод типа ссылок, прямых текстов для возврата и прочая. Локали, проперти и, в последнюю очередь, вариант "на-грани" — надписи на кнопках.
Ёбаные говнокодеры от пхп, блеать. Всё намешано в кучу — логика, уи, модель, бизнес, база. Помойка, блеать!
Vugluskr
Java программирование Из серии "советы моему сыну-программисту"
Сынок, вот делаешь ты синглтон. Или, прастихоспади, бин какой-нить. Или фабрику. Короче, уникальный объект. Есть у тебя в нём какие-то поля. Ну, предположим Map какой-нибудь. Или там константа. Ты ж не совсем дурак, ты ж сделал его final, да? А теперь не поленись и сделай его еще и static. Да-да, статик в синглтоне. И все делегированные методы от него — синхронизированные. И не важно, что мапу ты родил как-нибудь типа Collections.synchronizedMap(new ConcurrentHashMap<>()), поверь сейчас на слово, просто сделай. При случае посмотришь в инструкциях jvm как оно инлайнится и скажешь спасибо своему старику.
Vugluskr
Java программирование форматирование Я достаточно непривередлив в смысле форматирования кода. У меня есть свои привычки, но я вполне нормально отношусь к другим стилям форматирования. Но. Есть одна фишка, которая меня сильно раздражает. Вот например возьмём код "экономного" чувака, которому жалко пробелов:
while(p!=null){

Акей, вполне себе допускаю, что кому-то такой вырвиглаз нравится читать. И тот же чувак, блять тратит аж целую строчку, чтоб обернуть скобками однострочник:
while(p!=null){
p=(Page)p.getParent();
}

Ну сука, ну экономишь на всём — дык будь последователен, напиши вот так:
while(p!=null)p=(Page)p.getParent();

Читаешь исходники такого "экономиста" и вроде как надрочился уже, что кругом перл-стайл, а потом хуяк и какой-нибудь глупый инлайн развернут, типа:
public Page getCurrentPage(){
Page p=getDefaultPage();
return p;
}


Словом, не так раздражает само глупое форматирование, как непоследовательность его применения.
Vugluskr
Java программирование длядуши сниппеты code.jwebhelp.ru
Вот сделал и запустил маленький проектик — сниппеты кода. Можно добавлять свои, можно рыться по чужим. Если будет кому-то полезно — велкам. Если не полезно, то просто потыкайтесь, буду признателен. Сейчас там просто для начала занесено несколько сниппетов. Можно голосовать и грабить корованы.
У меня огромная помойка исходников, периодически приходится рыться в ней в поисках фичи, которую уже когда-то делал и писать заново лень :) В 2009 году я даже для IDEA написал плагинчик на эту тему: plugins.jetbrains.com но плагинчик отсох, вроде бы потому что идеевцы сменили архитектуру, не помню. Недавно решил пошерстить эти ваши инт0рнеты на предмет готовых сервисов, нашел вот этих ребят: code-snippets.ru но у них мне не понравилось то, что я не могу добавить свои сниппеты и то, что нет тегов/меток. И оценок/рейтингов. Решил заебенить своё, ну и заебенил :)
И да, верстать и дизайнить я не умею, такшта пришлось спиздить у них дизайн с версткой. Так как там вроде бы все стандартное от бутстрэп, то я особо не страдаю (ну, чутка совсем, уж извините).
Сделано всё на java, jwebhelp, tomcat, xml-xslt, nginx