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

Поэтому проведем экперимент, сравним алгоритм по умолчанию, и пару считающихся лучшими алгоритмов. Выберем, так сказать, the best of the best среди хэширования :) Конкретно для меня, это равная вероятность состояний отдельных бит, в 32х битном целом. Т.е. чем ближе вероятность появления «1» в каждой из позиций к вероятности ½ тем лучше.
Читать далее »»

Кто там говорит что perl-код не читабелен? Вот вам реализация soundex на языке K:

sdx:"bfpvcgjkqsxzdtlmnr"!(4#1),(8#2),(3 3 4 5 5 6)
nn:{d2:x where x > 0;r:d2 where d1:0w<>':d2}
soundex:{(x[0],(nn (sdx@1 _ x)),l:4#0)[til 4]}

угу, именно так... Похоже что клавиатуру протирали.
Теперь запускаем: Читать далее »»

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

1. Используйте атрибуты для одной группы

Выносите короткие значения из одной группы в атрибуты.
Лучше

<user name="John" sname="Smith"/>

чем

<user>
 <name>John</name>
 <sname>Smith</sname>
</user>

Читать далее »»

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

Так вот, я к тому что Spring предоставляет возможность указать какие поля позволено менять извне. И при формировании объекта, из переданных в POST значений, будут заполненны лишь определенные поля.
Указывается все очень просто:

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        super.initBinder(request, binder);
        binder.setAllowedFields(new String[] {"title", "content"});
}

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

В 2004 году Google рассказал о модели обработки данных которую они использую. Основана она на том что данные обрабатывает пара простых функций Map и Reduce. Первая их которых выделяет множество пар Ключ/Значений из входящих данных (тоже являющихся парами Ключ/Значение), а вторая производит объединение/группировку этих пар, и, опять же, выдает наружу таки пары, чаще всего в меньшем количестве чем пришло на вход. Дополнительным элементом является распределенная файловая система GoogleFS, благодаря которой обрабатываемый файл, и вся промежуточная информация, становится легко доступной с любого компьютера в кластере.

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

Так же эту идею можно встретить под названием Split/Aggregate. Т.е. суть в том что входные данные (неважно какого размера) разбиваются на отдельные элементы (этап split), к примеру построчно, каждая строка как отдельное значение для обработки. Эти блоки строк раcпределяются по кластеру для обработки, где для каждой строки вызывается функция обработки (map). Результат выполнения опять объединяется (reduce/aggregate) в выходной файл. Если нужно, то данные сохраняются отсортироваными в определенном порядке, к примеру по внешнему ключу.
Читать далее »»

Одной из фич Struts Framework, помимо MVC для веба, была библиотека тегов Tiles, идущая с ним. Тайлы много что могут, но главное что они помогают сделать наследования страниц. Да, так же как объекты, в корневом определяем базовые методы, а в предках что то переопределяем и добавляем новое.
При этом эта библиотека может использоваться и отдельно от Struts, она прекрасно интегрируется в Spring Framework.
Вот без тайлов как может выглядеть структура JSP страницы?

[инклюд хидера]
[тело страницы]
[инклюд футера]

Ну вроде так ничего сложного, типичный PHP стиль. А теперь допустим в хидере у нас что то меняется, например картинка раздела, подключается дополнительный css, JavaScript или еще что то. Вот тут все и начинается: в хидере пишется страшная логика охватывающая весь проект, которая, в зависимости от адреса, начинает что то включать/выключать, при инклюде передаются различные параметры, чтобы все это работало и т.д. Немного неудобно получается.
Читать далее »»

JYaml в качестве DSL

13 апреля 2007

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

В минувшую субботу, на rupy 2007 возникло небольшое обсуждение с Андреем Таранцевым по поводу скорости вычисления числа из ряда фибоначи в ruby/jruby, что было одним из тестов производительности языков. Проблема возникла в том что последний очень медленно считал, в сотни и тысячи раз медленней java. JRuby вычисляет 40 элемент за 26 минут, а java 1,7 секунды. Python тоже не быстр, но ближе к java.
Андрей предположил что это связано с тем что язык динамический, все можно переопределять, и т.д., поэтому мат. операции такие медленные. Я вот проверил, у меня возникло подозрение что вина в рекурсии, посчитал время вычисления для разных языков:
Ruby Recursion Benchmark
Если тоже самое вычислять итеративным алгоритмом, то время резко падает и остаётся в районе миллисекунд, без особого видимого роста, по крайней мере на таком объеме. Я знал что рекурсия это не очень быстро, но честно говоря никогда не замерял насколько, и очень удивлён что такое огромное влияние.
Вот такое вот разочарование :( Если на чистоту то и java тоже не любит часто любимую мной рекурсию, даже такую простую, т.к. тоже не имеет tail call optimization, и даже в любой момент может упасть по OutOfMemoryException из-за рекурсии, я уже спотыкался на этом когда то.

PS: на самом деле для ruby, а точнее Ruby on Rails, все это насчёт рекурсии совсем неважно, но иметь ввиду все же надо.

Большинство статей/туториалов по Spring Framework заостряют внимание на использовнии его в web приложении, и многие даже не задумываются что можно его использовать по иному. Я несколько раз сталкивался с удивлением других разработчиков, когда они слышали от меня что спринг прекрасно работает в большинстве других случаев, и знаю что иногда его отвергали, несмотря на все его удобства, считая что он не походит для разработки, к примеру, десктопного приложения.
На самом деле контекст приложения очень просто подключается к любому приложению, к примеру через класс FileSystemXmlApplicationContext. При этом всю структуру можно описать в Spring, а далее написать загрузчик типа такого:

public final class Boot {

    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("config/main.xml");
        App app = (App) ctx.getBean("main.app");
        app.run();
    }
}

где App это класс приложения (не важно какого, десктоп или просто консоль), который описан бином main.app"" в контексте config/main.xml, и у него есть метод run запускающий это приложение.

Решение задачки было на самом деле простым, если присмотрется к условию :) Суть ведь не в том чтобы определить кто из них больше, на сколько, а лишь вывести на экран один из трех вариантов, а для простоты из двух.

Читать далее »»