<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-8870493191508591473</atom:id><lastBuildDate>Fri, 20 Jan 2012 11:42:07 +0000</lastBuildDate><category>экология</category><category>postgresql</category><category>wiki</category><category>javascript</category><category>clojure</category><category>erlang</category><category>задачка</category><category>реклама</category><category>web</category><category>fp</category><category>gentoo</category><category>stuff</category><category>дети</category><category>quote</category><category>map</category><category>skype</category><category>sip</category><category>tomcat</category><category>regexp</category><category>youtube</category><category>wine</category><category>picasa</category><category>Неми</category><category>linkage</category><category>photosight.ru</category><category>css</category><category>webkit</category><category>карта</category><category>python</category><category>куракин</category><category>tips</category><category>spring</category><category>video</category><category>code style</category><category>gimp</category><category>windows</category><category>alsa</category><category>imagemagick</category><category>performance</category><category>ноутбуки</category><category>eclipse</category><category>комиск</category><category>c++</category><category>jit</category><category>игрушки</category><category>linux</category><category>hazelcast</category><category>debug</category><category>story</category><category>artwork</category><category>социальная реклама</category><category>jabber</category><category>java</category><category>яндекс</category><category>webdav</category><category>security</category><category>photoshop</category><category>новости</category><category>смешарики</category><category>games</category><category>bash</category><category>paragliding</category><category>yourmart</category><category>flex</category><category>пикник</category><category>log4j</category><category>photo</category><category>android</category><category>blogger</category><category>sql</category><category>dns</category><category>gtk+</category><category>power</category><category>network</category><category>hosting git mercurial</category><category>mozilla</category><category>qt</category><category>парадром</category><title>Крылья, ноги... Хвост!</title><description /><link>http://dolzhenko.blogspot.com/</link><managingEditor>noreply@blogger.com (Vladimir Dolzhenko)</managingEditor><generator>Blogger</generator><openSearch:totalResults>185</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/dolzhenko" /><feedburner:info uri="dolzhenko" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/dolzhenko" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fdolzhenko" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4102778207847703702</guid><pubDate>Mon, 09 Jan 2012 17:11:00 +0000</pubDate><atom:updated>2012-01-18T00:05:03.898+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><title>java: cache padding</title><description>Думаю, что многие уже наслышаны о магии &lt;a href="http://mechanitis.blogspot.com/2011/07/dissecting-disruptor-why-its-so-fast_22.html"&gt;&lt;span class="i"&gt;cache padding&lt;/span&gt;&lt;/a&gt; в &lt;a href="http://code.google.com/p/disruptor/"&gt;disruptor&lt;/a&gt;'е.&lt;br /&gt;
&lt;br /&gt;
Однако, куда более интересный факт - наличие &lt;span class="i"&gt;cache padding&lt;/span&gt;'а уже в самом &lt;span class="i"&gt;jdk 1.5&lt;/span&gt;&lt;a name='more'&gt;&lt;/a&gt; &lt;a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Exchanger.html"&gt;java.util.concurrent.Exchanger&lt;/a&gt;:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class="java"&gt;    /**
     * A Slot is an AtomicReference with heuristic padding to lessen
     * cache effects of this heavily CAS'ed location.  While the
     * padding adds noticeable space, all slots are created only on
     * demand, and there will be more than one of them only when it
     * would improve throughput more than enough to outweigh using
     * extra space.
     */
    private static final class Slot extends AtomicReference&amp;lt;Object&amp;gt; {
        // Improve likelihood of isolation on &amp;lt;= 64 byte cache lines
        long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
    }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;span class="i b"&gt;добавлено:&lt;/span&gt; Спасибо вопросу Артёма и последующей дискуссии Рустана - в продолжении темы Руслан задал этот вопрос в &lt;a href="http://cs.oswego.edu/pipermail/concurrency-interest/2012-January/008848.html"&gt;concurrency interest&lt;/a&gt;, где участвовал и Doug Lea.&lt;br /&gt;
&lt;br /&gt;
Внимательно читайте исходники и да прибудет с вами просветление.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4102778207847703702?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/jqnuJF2LlG8/java-cache-padding.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>6</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2012/01/java-cache-padding.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-7313586696233550072</guid><pubDate>Sun, 18 Dec 2011 09:19:00 +0000</pubDate><atom:updated>2011-12-19T11:36:42.335+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Сортировка по частоте</title><description>&lt;div class="quote"&gt;Дан (очень) большой массив целых чисел, необходимо отсортировать по частоте появления элемента в массиве. &lt;br /&gt;
&lt;span class="i"&gt;Ограничения&lt;/span&gt;: постоянная память, сложность &lt;span class="i"&gt;O&lt;/span&gt;(&lt;span class="b"&gt;N&lt;/span&gt; &lt;span class="i"&gt;log&lt;/span&gt;(&lt;span class="b"&gt;N&lt;/span&gt;)).&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;Пример:&lt;/span&gt;&lt;br /&gt;
[ 1 3 1 ] -&amp;gt; [ 3 1 1 ] т.к. &lt;span class="i"&gt;частота&lt;/span&gt;(3) = 1; &lt;span class="i"&gt;частота&lt;/span&gt;(1) = 2&lt;br /&gt;
[ 7 1 1 0 ] -&amp;gt; [ 7 0 1 1 ]&lt;br /&gt;
[ 9 1 0 1 3 1 3 3 ] -&amp;gt; [ 9 0 1 1 3 3 3 ]&lt;br /&gt;
&lt;/div&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-7313586696233550072?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/3IpOqXARx50/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>4</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/12/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4280536872761736125</guid><pubDate>Sat, 19 Nov 2011 19:37:00 +0000</pubDate><atom:updated>2011-11-20T00:00:39.430+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><title>java: autoboxing и ==</title><description>С появлением &lt;span class="i"&gt;java 5&lt;/span&gt; появилась и такая вещь как &lt;span class="b"&gt;auto boxing&lt;/span&gt;, на мой взгляд штука скорее вредная, чем полезная, но не суть.&lt;br /&gt;
&lt;br /&gt;
Наверняка многие &lt;span class="i"&gt;java&lt;/span&gt; программисты сходу могут ответить на вопрос &lt;span class="i"&gt;&amp;laquo;какой будет результат ?&amp;raquo;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class="java"&gt;        Integer a = 100;
        Integer b = 100;
        Integer c = 300;
        Integer d = 300;
        
        System.out.println(a == b);
        System.out.println(c == d);&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Тем более, что многие книги, как то &lt;span class="i"&gt;Java Puzzlers&lt;/span&gt;, упоминают об этом.&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Всё бы ничего, да только вот многие не знают, что &lt;span class="b"&gt;cache&lt;/span&gt; можно расширить, точнее его вернюю границу:&lt;br /&gt;
&lt;pre class="code"&gt;-Djava.lang.Integer.IntegerCache.high=300&lt;/pre&gt;&lt;br /&gt;
и результат выше приведённого примера в обоих случаях будет &lt;span class="b i"&gt;true&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b"&gt;p.s.&lt;/span&gt; чем равно &lt;span class="b i"&gt;-Integer.MIN_VALUE&lt;/span&gt; ?&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4280536872761736125?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/hpl0lIFEObg/java-autoboxing.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>1</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/11/java-autoboxing.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-8674269008491507836</guid><pubDate>Fri, 28 Oct 2011 11:14:00 +0000</pubDate><atom:updated>2011-10-28T15:14:12.485+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">spring</category><title>Spring Boostrap</title><description>We uses spring framework within each our project. I would like to share some small and useful tricks we use in our &lt;span class="i"&gt;Bootstrap&lt;/span&gt; class.&lt;br /&gt;
&lt;br /&gt;
To load any xml spring context you have to run smth like&lt;pre class="code"&gt;&lt;code class="java"&gt;
try {
    final ClassPathXmlApplicationContext ctx = 
        new ClassPathXmlApplicationContext(
            new String[] {"application-context.xml"});
} catch ( final Throwable th) {
    log.error("Unable to start the context : " + th.getMessage(), th);
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
It's enough in the most cases.&lt;a name='more'&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
For sure - it should be one &lt;span class="i b"&gt;main&lt;/span&gt; class in the whole project or several. &lt;br /&gt;
&lt;br /&gt;
As well it would be better to add some more functionality there : &lt;ul&gt;&lt;li&gt;ctx.registerShutdownHook() - close context &amp;amp; releasing all resources on jvm shutdown&lt;/li&gt;
&lt;li&gt;&lt;span class="i b"&gt;log4j&lt;/span&gt; (or what do you prefer to use?) initialization - just &lt;span class="i b"&gt;org.apache.log4j.BasicConfigurator.configure()&lt;/span&gt; call.&lt;/li&gt;
&lt;li&gt;set the default &lt;span class="i b"&gt;java.lang.Thread.UncaughtExceptionHandler&lt;/span&gt; - it helps if some thread dies occasionally - at least you have a chance to log the exception for further investigation of the root cause - otherwise, thread will die peacefully and silent.&lt;/li&gt;
&lt;li&gt;add&lt;span class="i b"&gt;BeanPostProcessor&lt;/span&gt; instance at &lt;span class="i b"&gt;createBeanFactory&lt;/span&gt; method. It handles bean initialization phase:&lt;ul&gt;&lt;li&gt;just before bean start&lt;ul&gt;&lt;li&gt;to be sure where is the bean's class source location - just from properly packed jar-file or some hot-fix bypass.&lt;/li&gt;
&lt;li&gt;start timeout watchdog - if some start time of bean exceeding the reasonable threshold (e.g. 1 minute) and initialization hasn't been finished yet - put a warning message to have an earlier issue detection - probably the bean depends on some external system (as database) that unavailable at the moment of start.&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;after initialization - put a log message how long bean started&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-8674269008491507836?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/6O_zPWZeYes/spring-boostrap.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/10/spring-boostrap.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-7003617675177540676</guid><pubDate>Mon, 15 Aug 2011 19:52:00 +0000</pubDate><atom:updated>2011-08-16T00:38:36.910+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Два презерватива на необитаемом острове</title><description>&lt;div class="quote"&gt;&lt;img src="https://lh4.googleusercontent.com/-HI95UmsHAqA/Tkl3kLqWBuI/AAAAAAAAGaM/-Ufr0j41oYw/durex.jpg" style="display: block; float: left; margin: 10px 10px 10px 0;" /&gt;Волею судьбы на необитаемом острове оказалось &lt;span class="b"&gt;четверо&lt;/span&gt;: двое мужчин и еще две прелестные дамы. &lt;br /&gt;
&lt;br /&gt;
Через какое-то время природа взяла свое и было решено «заняться любовью», однако выяснилось, что все четверо болеют &lt;span class="i"&gt;венерическими&lt;/span&gt; заболеваниями, причем все - &lt;span class="b"&gt;разными&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку никто не желал добавлять себе еще одно, то после некоторых поисков было найдено &lt;span class="b"&gt;два&lt;/span&gt; презерватива.&lt;br /&gt;
&lt;br /&gt;
Как провести все четыре возможные встречи между разнополыми партнерами?&lt;/div&gt;
&lt;div class="clear"&gt;&lt;/div&gt;&lt;br/&gt;
&lt;span class="b i"&gt;внимание!&lt;/span&gt;  комментарии содержат ответ.&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-7003617675177540676?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/BEp75kOEcak/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh4.googleusercontent.com/-HI95UmsHAqA/Tkl3kLqWBuI/AAAAAAAAGaM/-Ufr0j41oYw/s72-c/durex.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/08/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-5676811698909865714</guid><pubDate>Wed, 13 Jul 2011 06:54:00 +0000</pubDate><atom:updated>2011-07-13T10:54:50.020+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: 12 монет и 3 взвешивания</title><description>&lt;div class="quote"&gt;Есть &lt;span class="b"&gt;12 монет&lt;/span&gt; и аптекарские весы с двумя чашами, которые могут показывать &lt;span class="i"&gt;больше&lt;/span&gt;, &lt;span class="i"&gt;меньше&lt;/span&gt; и &lt;span class="i"&gt;равно&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Известно, что одна из монет &lt;span class="b"&gt;фальшивая&lt;/span&gt; - отличается только по весу, причём не известно - тяжелее ли она настоящей или легче.&lt;br /&gt;
&lt;br /&gt;
Как при помощи только &lt;span class="b"&gt;трёх взвешиваний&lt;/span&gt; определить какая монета фальшивая и тяжелее ли она или легче настоящей ?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-5676811698909865714?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/NhDExlmPo4c/12-3.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>2</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/07/12-3.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4887332157456745119</guid><pubDate>Wed, 08 Jun 2011 11:54:00 +0000</pubDate><atom:updated>2011-08-24T21:49:45.980+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><title>Android: HTC MyTouch 4G</title><description>&lt;img style="display:block; margin:10px 10px 10px 0;float:left;"  src="https://lh5.googleusercontent.com/_0W-IrdaBLsY/Tdjzwx7ttZI/AAAAAAAAGB8/u_Lm0CeLjYE/htc-glacier.jpg"/&gt; Вот уже почти месяц как я счастливый обладатель &lt;span class="i"&gt;g-phone&lt;/span&gt; от HTC - MyTouch 4G, он же HTC Glacier.

Изначально бюджет был определён как 10т.руб за новый Android с &lt;span class="i"&gt;cpu&lt;/span&gt; класса 1GHz и &lt;span class="i"&gt;ram&lt;/span&gt; не менее 512Mb - в итоге поторговавшись на ebay был получен данный аппарат. В бюджет самого телефона уложился и ещё ~$40 пришлось отдать за пересылку из Америки в Россию.

После моего старого &lt;span class="i"&gt;кирпича&lt;/span&gt; от SonyEricsson 6летней давности радовало всё: cpu ARMv7 1Ghz, 768Mb ram; как выяснилось уже после покупки - это и &lt;span class="i"&gt;gpu&lt;/span&gt; на чипе Adreno 205, что делает работу с видео и графикой очень плавной и приятной; яркий и чёткий wvga (480 x 800) экран; две камеры - передняя и задняя (5Mpix); зарядка micro usb - он же и просто канал подключения к компу; wifi; gps; синхронизация с &lt;span class="i"&gt;google account&lt;/span&gt; (адресная книга, почта, google reader, picasa); стандарный minijack; акселлерометр - он же g-sensor; pattern lock screen и куча софта на android market. 

Словом, &lt;span class="i b"&gt;value for money&lt;/span&gt; - я считаю, что платить 20круб за телефон подобного класса, но у которого чуть лучше экран - это перебор.&lt;div class="clear"&gt;
&lt;/div&gt;
&lt;a name='more'&gt;&lt;/a&gt;
&lt;span style="font:1.2em;"&gt;Прошивка.&lt;/span&gt;

Примерно через пару неделю меня стали утомлять постоянно запущенные сервисы yahoo! mail, yahoo! messanger и ещё с десяток левых приложений, которые оживают самостоятельно даже после того, как их убиваешь. Всё это идёт в стандартной прошивке от htc.

Выход - &lt;span class="i"&gt;CyanogenMod&lt;/span&gt; - альтернативная прошивка, там же на wiki был найдена &lt;a href="http://wiki.cyanogenmod.com/index.php?title=TMobile_myTouch_4G:_Full_Update_Guide"&gt;инструкция по root'ованию и перепрошивке TMobile myTouch 4G&lt;/a&gt;. 

С первого раза прошивка меня не устроила - была потеряна интеграция с сервисами &lt;span class="i"&gt;google&lt;/span&gt; и прочее - было решено вернутся.

Затем попробовал прошивку &lt;a href="http://forum.xda-developers.com/showthread.php?t=978643"&gt;Royal Ginger&lt;/a&gt;, основанная на CyanogenMod прошивка - и надо сказать, что она мне очень даже понравилась: много новых и вкусных мелочей и значительно экономней кушает батарейку.

&lt;img style="display:block; margin:10px 10px 10px 0;float:left;"   src="https://lh4.googleusercontent.com/_0W-IrdaBLsY/Tdj37aPS5qI/AAAAAAAAGCA/Fq1ZMUn5c4s/pattern_lock_android.jpg"/&gt; 
Pattern Lock screen

При помощи такого нехитрого механизма можно блокировать экран от &lt;span class="i"&gt;случайных&lt;/span&gt; прикосновений и доступа. Очевидно, чем больше точек в графе, тем сложнее его подобрать.
&lt;div class="clear"&gt;
&lt;/div&gt;


&lt;img style="display:block; margin:10px 10px 10px 0;float:left;"    src="https://lh5.googleusercontent.com/_0W-IrdaBLsY/TdkiEJq3ZkI/AAAAAAAAGCY/aS-4Ujr1Jr0/Swype-Double-Letters1.jpg"/&gt;
Swype

Данный способ ввода позволяет печатать слова, не отрывая палец от экрана. Cоздателем технологии является Клифф Кушлер (Cliff Kushler), автор предиктивного ввода &lt;span class="i"&gt;T9&lt;/span&gt;.

Swype позволяет пользователю вводить слово, скользя пальцем от буквы к букве, поднимая палец только в промежутке между словами. Для угадывания слова Swype использует алгоритм исправления ошибок и лингвистическую модель языка. 

Безусловно, поддерживается как английский, так и русский ввод. 

Не является уникальной особенностью &lt;span class="i"&gt;android&lt;/span&gt;'а, но очень приятная функциональность. 

&lt;div class="clear"&gt;
&lt;/div&gt;

&lt;span style="font:1.2em;"&gt;Приложения.&lt;/span&gt;
Много всякого и интересного каждый может найти себе на &lt;span class="i"&gt;Android Market&lt;/span&gt;, для себя отметил:
&lt;ul&gt;
&lt;li&gt;LauncherPro&lt;/li&gt;
&lt;li&gt;ColorDict - offline словарь, ведёт историю поиска слов, понимает словари в формате &lt;span class="i"&gt;stardict&lt;/span&gt; - можно найти и словари &lt;span class="i"&gt;lingvo&lt;/span&gt; в данном формате, и очень полезный Oxford English-English Dictionary&lt;/li&gt;
&lt;li&gt;Locus Pro - карты и навигация, поддерживает карты OpenSteetMap, &lt;span class="i"&gt;google&lt;/span&gt;, &lt;span class="i"&gt;yandex&lt;/span&gt; и много других, кеширует в формате &lt;span class="i"&gt;sqlite&lt;/span&gt;, после чего доступно offline. Интерграция с gps и прочие плюшки типа треков и т.п.&lt;/li&gt;
&lt;li&gt;Google apps - это и GMail, Google Reader и Picasa&lt;/li&gt;
&lt;li&gt;VuDroid - читалка и &lt;span class="i"&gt;pdf&lt;/span&gt;, и &lt;span class="i"&gt;djvu&lt;/span&gt; с запоминанием страницу, где остановился.&lt;/li&gt;
&lt;li&gt;FancyWidget - можно было бы сказать, что стандарный widget часов и погоды, просто красивый и удобный.&lt;/li&gt;
&lt;li&gt;Skype как он есть&lt;/li&gt;
&lt;li&gt;Labyrinth - детская забава по катанию металлического шарика по лабиринту.&lt;/li&gt;
&lt;li&gt;Hybrid StopWatch - красивый и фунциональный секундомер с таймером&lt;/li&gt;
&lt;li&gt;cluBalance - widget, позволяющий следить за балансом: сколько потрачено за день, месяц; автоматическое обновление после каждого звонка, sms, internet подключения&lt;/li&gt;
&lt;li&gt;ConnectBot - ssh client&lt;/li&gt;
&lt;li&gt;MoboPlayer - медиа-плеер с плюшками - выбор звуковой дорожки, субтитров, вшитых в mkv, mov, mpv - кушает целую кучу медиа форматов и т.п&lt;/li&gt;
&lt;li&gt;RocketDial Pro - звонилка с поддержкой поиска имени по T9, организация контактов по группам и т.п&lt;/li&gt;
&lt;li&gt;SpringPad - заметки, задачи и т.п, сервис интегрируется как с mozilla firefox, так и chrome&lt;/li&gt;
&lt;li&gt;AlarmClock Plus - будильник, похож на стандартный, но можно настроить большую кнопку &lt;span class="b"&gt;snooze&lt;/span&gt; и маленькую &lt;span class="b"&gt;dismiss&lt;/span&gt;, отключение будильника по решению небольшого математического выражения &lt;/li&gt;

&lt;/ul&gt;
&lt;img style="display:block; margin:10px 10px 10px 0;float:left;"  src="https://lh5.googleusercontent.com/-npnrfs53QX0/TfEVoZ0K7nI/AAAAAAAAGEY/IJmsCvMviis/s512/android-glacier-quadrant.png"/&gt; &lt;span class="i"&gt;Добавлено:&lt;/span&gt;
Результаты Quadrant benchmark&lt;div class="clear"&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4887332157456745119?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/W8SePWR1hXA/android-htc-mytouch-4g.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh5.googleusercontent.com/_0W-IrdaBLsY/Tdjzwx7ttZI/AAAAAAAAGB8/u_Lm0CeLjYE/s72-c/htc-glacier.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/05/android-htc-mytouch-4g.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-2000359215845636962</guid><pubDate>Wed, 25 May 2011 09:32:00 +0000</pubDate><atom:updated>2011-11-20T12:17:35.157+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">performance</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>java: деградация пула строк</title><description>Наверняка многие java программисты знают о существовании &lt;span class="i"&gt;пула строк&lt;/span&gt;, который хранится в &lt;span class="i"&gt;PermGen&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме всего прочего каждая строка, которая была получена через &lt;pre class="code"&gt;&lt;code class="java"&gt;new String(data);&lt;/code&gt;&lt;/pre&gt;можно привести к &lt;span class="i"&gt;каноническому&lt;/span&gt; представлению посредством вызова метода &lt;span class="i"&gt;intern()&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Однако, доступ к полу строк может деградировать из-за большого кол-ва строк в пуле.&lt;br /&gt;
&lt;br /&gt;
В своей статье &lt;a href="http://www.javaspecialist.ru/2011/05/javalangstring.html"&gt;вы уверены, что знаете про строки все?&lt;/a&gt; автор упоминает, что сложность &lt;span class="i"&gt;intern()&lt;/span&gt; есть &lt;span class="i"&gt;O(N)&lt;/span&gt;, где N - размер &lt;span class="i"&gt;пула строк&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Надо сказать меня сильно удивило - т.к. ещё в стародавние времена, когда стали доступны исходники &lt;span class="i"&gt;sun hotspot jvm 1.4&lt;/span&gt; (кстати, именно из них собирался &lt;span class="i"&gt;blackdown-jdk&lt;/span&gt;) помню, что на уровне c++ &lt;span class="i"&gt;пул строк&lt;/span&gt; сделан как &lt;span class="i"&gt;Hashtable&lt;/span&gt;, у которого, как известно, сложность поиска &lt;span class="i"&gt;O(1)&lt;/span&gt; - т.е константа.&lt;a name='more'&gt;&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
Артём предоставил небольшой &lt;span class="i"&gt;benchmark&lt;/span&gt;, который таки показывает линейность: &lt;pre class="code"&gt;&lt;code class="java"&gt;public class StringPoolTest {

static final int N = 1000000;
static int k;

static String TEST_STRING = "0123456789";


public static void main(String[] args) throws Exception{
final StringPoolTest stringPoolTest = new StringPoolTest();
stringPoolTest.m();
}

private void m() throws Exception {
for(final int i : new int[]{100, 1000, 
10 * 1000,
20 * 1000,
25 * 1000,
100 * 1000, 
500 * 1000, 
1000 * 1000
}){
cleanAndPopulate(i);
tripleCount(N);
}
}

private void tripleCount(int n) {
count(n);
count(n);
count(n);
}

private void cleanAndPopulate(int n) throws Exception{
clean();
populate(n);
}

private void gc() throws InterruptedException {
System.out.println(" gc begin");
Runtime.getRuntime().gc();
Runtime.getRuntime().gc();
Runtime.getRuntime().gc();
System.out.println(" gc finished.");
}

private void count(int n) {
int i, j;
long t = System.nanoTime();
for (i = 0; i &amp;lt; n; i++) {
i++;
}
long t1 = System.nanoTime();
for (j = 0; j &amp;lt; n; j++) {
access();
j++;
}
long t2 = System.nanoTime();
k = i - j;//prevent JIT from clashing loop
System.out.println(size() + ": " + (((t2 - t1) - (t1 - t)) / n / 1e3) + " us." );
}

private String[] a;// = new String[N];

protected void access() {
TEST_STRING.intern();
}

protected void populate(int n) {
a = new String[n];
for (int i = 0; i &amp;lt; n; i++) {
a[i] = Integer.toString(i).intern();
}
}

protected void clean() throws InterruptedException {
a = null;
gc();
}

protected int size() {
return a.length;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
запускается на &lt;span class="i b"&gt;Sun JDK 1.6.0.25&lt;/span&gt; / &lt;span class="b i"&gt;OpenJDK 1.6.0.22&lt;/span&gt; всё с опциями &lt;pre class="code"&gt;&lt;code&gt;-verbose:gc 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDetails 
-XX:+PrintGCApplicationStoppedTime 
-XX:NewSize=144m 
-XX:MaxNewSize=144m 
-XX:PermSize=128m 
-XX:MaxPermSize=128m 
-XX:+UseParNewGC 
-XX:ParallelGCThreads=2 
-XX:MaxTenuringThreshold=1 
-XX:SurvivorRatio=8 
-XX:+UseConcMarkSweepGC 
-XX:+CMSParallelRemarkEnabled 
-XX:+CMSClassUnloadingEnabled 
-XX:+CMSPermGenSweepingEnabled 
-XX:CMSInitiatingOccupancyFraction=60 
-XX:+UseCMSInitiatingOccupancyOnly&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
и вот результаты, вызвавшие недоумение:&lt;br /&gt;
&lt;br /&gt;
&lt;img style="float:left;margin:10px;" src="https://lh5.googleusercontent.com/_0W-IrdaBLsY/TdzG7GlsZFI/AAAAAAAAGDM/WyeOQ7ecsjc/stringpooltest.png"/&gt;&lt;pre class="code"&gt;&lt;code&gt;100: 0.101 us.
1000: 0.102 us.
10000: 0.117 us.
20000: 0.127 us.
25000: 0.136 us.
100000: 0.37 us.
500000: 2.96 us.
1000000: 7.725 us.&lt;/code&gt;&lt;/pre&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;br /&gt;
Легко заметить, что время отклика на участке до &lt;span class="i"&gt;25000&lt;/span&gt; есть константа, после начинается рост.&lt;br /&gt;
&lt;br /&gt;
Взглянем более детально на &lt;a href="http://download.java.net/openjdk/jdk6/"&gt;исходный код openjdk jvm&lt;/a&gt;:&lt;br /&gt;
openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class="cpp"&gt;class StringTable : public Hashtable {
friend class VMStructs;

private:
// The string table
static StringTable* _the_table;

static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
oop basic_add(int index, Handle string_or_null, jchar* name, int len,
unsigned int hashValue, TRAPS);

// Table size
enum {
string_table_size = 1009
};

oop lookup(int index, jchar* chars, int length, unsigned int hashValue);

StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {}

StringTable(HashtableBucket* t, int number_of_entries)
: Hashtable(string_table_size, sizeof (HashtableEntry), t,
number_of_entries) {}

public:
// The string table
static StringTable* the_table() { return _the_table; }

static void create_table() {
assert(_the_table == NULL, "One string table allowed.");
_the_table = new StringTable();
}

static void create_table(HashtableBucket* t, int length,
int number_of_entries) {
assert(_the_table == NULL, "One string table allowed.");
assert(length == string_table_size * sizeof(HashtableBucket),
"bad shared string size.");
_the_table = new StringTable(t, number_of_entries);
}

///// cut 
};
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp:&lt;pre class="code"&gt;&lt;code class="cpp"&gt;oop StringTable::intern(Handle string_or_null, jchar* name,
int len, TRAPS) {
unsigned int hashValue = hash_string(name, len);
int index = the_table()-&amp;gt;hash_to_index(hashValue);
oop string = the_table()-&amp;gt;lookup(index, name, len, hashValue);

// Found
if (string != NULL) return string;

// Otherwise, add to symbol to table
return the_table()-&amp;gt;basic_add(index, string_or_null, name, len,
hashValue, CHECK_NULL);
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Всё выглядит вполне &lt;span class="i"&gt;hash table&lt;/span&gt;, если бы не один момент:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class="cpp"&gt;symbolOop SymbolTable::basic_add(int index, u1 *name, int len,
unsigned int hashValue, TRAPS) {
assert(!Universe::heap()-&amp;gt;is_in_reserved(name) || GC_locker::is_active(),
"proposed name of symbol must be stable");

// We assume that lookup() has been called already, that it failed,
// and symbol was not found.  We create the symbol here.
symbolKlass* sk  = (symbolKlass*) Universe::symbolKlassObj()-&amp;gt;klass_part();
symbolOop s_oop = sk-&amp;gt;allocate_symbol(name, len, CHECK_NULL);
symbolHandle sym (THREAD, s_oop);

// Allocation must be done before grapping the SymbolTable_lock lock
MutexLocker ml(SymbolTable_lock, THREAD);

assert(sym-&amp;gt;equals((char*)name, len), "symbol must be properly initialized");

// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.

symbolOop test = lookup(index, (char*)name, len, hashValue);
if (test != NULL) {
// A race occurred and another thread introduced the symbol, this one
// will be dropped and collected.
return test;
}

HashtableEntry* entry = new_entry(hashValue, sym());
add_entry(index, entry);
return sym();
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp&lt;pre class="code"&gt;&lt;code class="cpp"&gt;inline void BasicHashtable::add_entry(int index, BasicHashtableEntry* entry) {
entry-&amp;gt;set_next(bucket(index));
_buckets[index].set_entry(entry);
++_number_of_entries;
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;span class="i b"&gt;Кратко&lt;/span&gt;: &lt;span class="i"&gt;при добавлении нового элемента не происходит масштабирование таблицы&lt;/span&gt;, таблица создана изначально с 1009 &lt;span class="i"&gt;bucket&lt;/span&gt;'ов. &lt;br /&gt;
&lt;br /&gt;
При значительном увеличении &lt;span class="i"&gt;пула строк&lt;/span&gt; данная &lt;span class="i b"&gt;таблица вырождается&lt;/span&gt; - как следствие &lt;span class="i b"&gt;увеличивается число коллизий&lt;/span&gt; по &lt;span class="i"&gt;hash&lt;/span&gt; коду, что мы и наблюдаем на benchmark'е.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;Добавлено:&lt;/span&gt;&lt;br /&gt;
После было решено опробовать &lt;span class="i b"&gt;gcj 4.4.5&lt;/span&gt;:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class=""&gt;$  gcj --version
gcj (Gentoo 4.4.5 p1.0, pie-0.4.5) 4.4.5
$ gcj --main=StringPoolTest StringPoolTest.java -o StringPoolTest &amp;amp;&amp;amp; ./StringPoolTest &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
результат стабильный на всём рассматриваемом отрезке и составляет ~0.13us.&lt;br /&gt;
&lt;br /&gt;
По скольку на руках есть исходный код &lt;span class="i"&gt;OpenJDK 1.6.0.22&lt;/span&gt; не составило труда изменить размер &lt;span class="i"&gt;пула строк&lt;/span&gt;&lt;br /&gt;
openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp:&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code class="cpp"&gt;  // Table size
enum {
string_table_size = 20011
};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
И выполнить опять тот же тест&lt;br /&gt;
&lt;pre class="code"&gt;&lt;code&gt;100: 0.145 us.
1000: 0.153 us.
10000: 0.154 us.
20000: 0.154 us.
25000: 0.153 us.
100000: 0.155 us.
500000: 0.197 us.
1000000: 0.238 us.&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="i"&gt;Т.о. было найдено верное место в исходном коде jvm и результат изменений практически устранил деградации поиска строки в пуле.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-2000359215845636962?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/4VSVWcqw37Y/java-javautilstring-intern.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh5.googleusercontent.com/_0W-IrdaBLsY/TdzG7GlsZFI/AAAAAAAAGDM/WyeOQ7ecsjc/s72-c/stringpooltest.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/05/java-javautilstring-intern.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4284627907482644094</guid><pubDate>Tue, 08 Mar 2011 16:38:00 +0000</pubDate><atom:updated>2011-03-10T11:58:06.783+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Честный стражник и лжец</title><description>&lt;div class="quote"&gt;&lt;img style="display:block; margin:10px 10px 10px 0;float:left;" src="https://lh5.googleusercontent.com/_0W-IrdaBLsY/TXdjEI6J2oI/AAAAAAAAF4c/RYYsybE2CUg/gobliins2_1.jpg"/&gt;Перед вами две двери:&lt;br /&gt;одна из них ведет на &lt;span class="b"&gt;волю&lt;/span&gt;, другая - прямая дорога к &lt;span class="b"&gt;смерти&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Перед каждой из дверей сидит стражник, причем один из них - &lt;span class="i"&gt;лжец&lt;/span&gt;, а второй  говорит &lt;span class="i"&gt;правду&lt;/span&gt; и только правду; &lt;span class="i"&gt;однако&lt;/span&gt; вы не знаете, кто из них кто. &lt;br /&gt;&lt;br /&gt;Задав только &lt;span class="b"&gt;один&lt;/span&gt; вопрос &lt;span class="b"&gt;только одному из&lt;/span&gt; стражников, определить дорогу на свободу. &lt;br /&gt;&lt;br /&gt;Каков вопрос стоит задать &lt;span class="b"&gt;?&lt;/span&gt;&lt;/div&gt;&lt;div class='clear'&gt;&lt;/div&gt; &lt;span class="b i"&gt;внимание!&lt;/span&gt;  комментарии содержат ответ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4284627907482644094?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/odmPvE6JryM/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh5.googleusercontent.com/_0W-IrdaBLsY/TXdjEI6J2oI/AAAAAAAAF4c/RYYsybE2CUg/s72-c/gobliins2_1.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/03/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-692922665644670980</guid><pubDate>Tue, 08 Mar 2011 12:37:00 +0000</pubDate><atom:updated>2011-03-17T17:55:13.030+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><title>Serialization graph</title><description>Стандартная сериализация в java обладает рядом недостатков (см. &lt;span class="i"&gt;Effective Java&lt;/span&gt; 2nd edition, автор Josh Bloch стр. 289), среди которых: медленная сериалазиция (см. &lt;a href="https://github.com/eishay/jvm-serializers/wiki"&gt;jvm-serializers benchmarks&lt;/a&gt;) и сохранение полного графа объектов. &lt;br /&gt; Однако, идея сохранения графа имеет и положительный аспект.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Вкратце, процесс стандартной сериализации графа объекта выглядит так:&lt;br /&gt;&lt;div class="center"&gt;&lt;img src="https://lh3.googleusercontent.com/_0W-IrdaBLsY/TXYjB7Apt4I/AAAAAAAAF3Y/pqGkq_S8qy0/ser1.png" border="0"/&gt;&lt;/div&gt;&lt;br /&gt;Заголовок пакета содержит только описания классов без их свойств (можно назвать &amp;laquo;словарь объектов&amp;raquo;). &lt;br /&gt;При этом в сериализованном виде объекты представлены как ссылки (возможно, на не до конца проинициализированные объекты). &lt;br /&gt;Процесс десериализации создаёт карту объектов на основе &amp;laquo;словаря объектов&amp;raquo; , которые в последствии заполняет свойствами-примитивами (boolean, int, long и т.п) и в т.ч. и ссылками на объекты из &amp;laquo;словаря объектов&amp;raquo;.&lt;br /&gt;&lt;br /&gt;Т.о. стандарная сериализация позволяет разрешать циклические зависимости, а так же избегать повторов сериализации объектов в потоке.&lt;br /&gt;&lt;br /&gt;В противовес медленной сериализации, обратной совместимости, контролю сериализованного графа и т.п часто ставят &amp;laquo;ручную&amp;raquo; сериалализацию, например, используя &lt;span class="i"&gt;java.io.Externalizable&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Часто при передаче, н-р массива объектов, встречаются повторяющиеся объекты (как правило строки, но не только), т.е&lt;br /&gt;&lt;div class="center"&gt;&lt;img src="https://lh4.googleusercontent.com/_0W-IrdaBLsY/TXYjB_2qErI/AAAAAAAAF3U/PvQpgMGfuZs/ser2.png" border="0"/&gt;&lt;/div&gt;&lt;br /&gt;Введя понятие &lt;span class="i"&gt;&amp;laquo;словаря объектов&amp;raquo;&lt;/span&gt; (или &lt;span class="i"&gt;словаря строк&lt;/span&gt;) можно добиться &lt;span class="b i"&gt;уменьшения объёма&lt;/span&gt; пакета без существенных доп. нагрузок. &lt;br /&gt;&lt;br /&gt;&lt;span class="i"&gt;ps.&lt;/span&gt; на моём примере при сериализации около 200 объектов выигрыш составил ~ 50%.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-692922665644670980?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/4fDF0rKRdAw/serialization-graph.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh3.googleusercontent.com/_0W-IrdaBLsY/TXYjB7Apt4I/AAAAAAAAF3Y/pqGkq_S8qy0/s72-c/ser1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/03/serialization-graph.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-7708937447094983529</guid><pubDate>Mon, 17 Jan 2011 11:03:00 +0000</pubDate><atom:updated>2011-01-17T14:08:05.531+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">stuff</category><title>Stuff: Powerball</title><description>&lt;img src="http://lh4.ggpht.com/_0W-IrdaBLsY/TTQjBbu2KoI/AAAAAAAAF0A/1w0uaSxhypY/powerball_l.jpg" style="float:left; margin:20px;"/&gt; Пару дней покрутив &lt;span class="i"&gt;ручной тренажёр&lt;/span&gt; &lt;span class="b"&gt;power ball&lt;/span&gt; коллеги - решил купить себе тоже :)&lt;br /&gt;&lt;br /&gt;&lt;div class="clear"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-7708937447094983529?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/UYCiqdOIdc0/stuff-powerball.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_0W-IrdaBLsY/TTQjBbu2KoI/AAAAAAAAF0A/1w0uaSxhypY/s72-c/powerball_l.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/01/stuff-powerball.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-5848525293238849461</guid><pubDate>Sun, 16 Jan 2011 08:18:00 +0000</pubDate><atom:updated>2011-01-16T11:49:44.267+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>log2(1M)</title><description>Многие задачки, которые задают на собеседованиях появляются рано или поздно на ресурсах типа &lt;a href="braingames.ru"&gt;braingames.ru&lt;/a&gt;, что в общем-то и не удивительно.&lt;br /&gt;&lt;br /&gt;Так например, &lt;span class="i"&gt;fp&lt;/span&gt;-сообществу понравилась &lt;a href="http://dolzhenko.blogspot.com/2010/02/blog-post.html"&gt;эта задачка&lt;/a&gt;, придуманная в нашем отделе.&lt;br /&gt;&lt;br /&gt;По мотивам &lt;a href="http://www.glassdoor.com/blog/top-25-oddball-interview-questions-2010/"&gt;Top 25 Oddball Interview Questions Of 2010&lt;/a&gt; и особенно вопроса, задаваемого в &lt;span class="i"&gt;UBS&lt;/span&gt;&lt;div class="quote"&gt;sqrt(2000) = &lt;span class="b" style="font-size:1.5em;"&gt;?&lt;/span&gt;&lt;/div&gt; вспомнилась классическая задача, задаваемая у нас:&lt;div class="quote"&gt;log&lt;sub&gt;2&lt;/sub&gt;(1000000) = &lt;span class="b" style="font-size:1.5em;"&gt;?&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Не предполагается, что ответ будет с точностью до какого знака после запятой (точки) - достаточно оценить с точностью до &lt;span class="i"&gt;единицы&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-5848525293238849461?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/lBZZ-zdN-zw/log21m.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>5</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/01/log21m.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-6485785396396949437</guid><pubDate>Fri, 31 Dec 2010 21:20:00 +0000</pubDate><atom:updated>2011-12-19T01:01:06.907+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jit</category><title>Lock Coarsening, Biased Locking, Escape Analysis and others</title><description>Оптимизационные трюки, используемые при динамической компиляции jit'ом в java 6. В java 6 была существенно изменена (по сравнению с java 5) работа блокировок, существенно облегчив их, в java6u14 появился escape-анализ, который работает по-умолчанию, а так же много других интересных подходов.&lt;a name='more'&gt;&lt;/a&gt; &lt;br /&gt;
&lt;ul style="list-style-type:upper-roman;"&gt;&lt;li&gt;Lock coarsening, Eliminate locks - укрупнение блокировок&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;-XX:+EliminateLocks&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Данная опция, относящаяся к оптимизации многопоточных приложений, не удаляет блокировки в целом - имеет место устранение излишних блокировок в результате их объединения, и в некотором смысле их загрубление.&lt;br /&gt;
Несколько смежных блоков, которые выполняются под одним и тем же монитором могут быть объединены в блок с &lt;span class="i"&gt;одним&lt;/span&gt; захватом монитора.&lt;br /&gt;
Тем самым происходит &lt;span class="i"&gt;устранение&lt;/span&gt; излишних разблокирований и повторных захватов мониторов.&lt;br /&gt;
Если между двумя захватами одного и того же монитора находится блок не под монитором, дабы уменьшить число захватов он тоже окажется под монитором - это и есть загрубление блокировок (lock coarsening).&lt;div class="center"&gt;&lt;img src="http://lh5.ggpht.com/_0W-IrdaBLsY/TSQzYL6IeWI/AAAAAAAAFw0/3elnkMbfpZ4/eliminateLocks.png" /&gt;&lt;br /&gt;
&lt;span class="i"&gt;-XX:+EliminateLocks&lt;/span&gt;&lt;br /&gt;
Устранение лишних блокировок - Lock coarsening&lt;/div&gt;&lt;br /&gt;
На примере показано как устраняется overhead на захват монитора.&lt;/li&gt;
&lt;li&gt;Biased Locking - Смещение блокировок&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;-XX:+UseBiasedLocking&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;Обновлено.&lt;/span&gt;. Краткий пересказ &lt;a href="http://cheremin.blogspot.com/2011/04/biased-locking.html"&gt;Biased locking&lt;/a&gt; в &lt;a href="http://cheremin.blogspot.com/"&gt;рабочих заметках&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Механизм &lt;span class="i"&gt;biased locking&lt;/span&gt; основывается на свойстве, что большинство объектов захватывают монитор на очень малое время, так, что даже при большом количестве потоков &lt;span class="i"&gt;contention&lt;/span&gt; оказывается весьма мал.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="center"&gt;&lt;img src="https://lh4.googleusercontent.com/-q3fNXSanVUg/Tu5UUokPNUI/AAAAAAAAHDE/3gDbtg5rb9o/s420/biasLocking1.png" /&gt;&lt;br /&gt;
&lt;span class="i"&gt;-XX:-UseBiasedLocking&lt;/span&gt;&lt;br /&gt;
Иллюстрация работы с отключённым biased locking.&lt;/div&gt;&lt;br /&gt;
Для этого в JVM были реализованы spin-locks (&lt;span class="i"&gt;thin lock&lt;/span&gt;s), используется &lt;span class="i"&gt;ownerThreadId&lt;/span&gt;, и, пытаясь захватить монитор, &lt;span class="i"&gt;CAS&lt;/span&gt;(-1, threadId). Если &lt;span class="i"&gt;CAS&lt;/span&gt; удался &amp;mdash; захватили монитор, иначе делаеться еще несколько попыток в цикле (вдруг нынешний владелец отпустит монитор буквально через пару тактов). Количество итераций это предмет тонкого тюнинга, возможно даже адаптивного, на базе профиля предыдущих попыток. Если даже со спиннингом мы не захватили монитор &amp;mdash; откатываемся к OS-specific locks (&lt;span class="i"&gt;fat-lock&lt;/span&gt;s).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="center"&gt;&lt;img src="https://lh6.googleusercontent.com/-v31dJ4FEWTg/Tu5UUle510I/AAAAAAAAHDA/dJvImhHPFIM/s420/biasLocking2.png" /&gt;&lt;br /&gt;
&lt;span class="i"&gt;-XX:+UseBiasedLocking&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;li&gt;Escape analysis - Анализ локальности&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;-XX:+DoEscapeAnalysis&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Цель escape-анализа - определить локализован ли указатель создаваемого объекта внутри блока объекта или он &lt;span class="i"&gt;выходит (escape)&lt;/span&gt; за рамки данного блока (в &lt;span class="i"&gt;другую нить (thread)&lt;/span&gt;, может быть &lt;span class="i"&gt;возвращен из блока&lt;/span&gt;, а также, когда указатель помещён в &lt;span class="i"&gt;глобальную переменную&lt;/span&gt;).&lt;br /&gt;
&lt;br /&gt;
Исследование данной проблемы длится не один год, одна из подробных статей &lt;a href="http://www.research.ibm.com/people/g/gupta/escape.ps"&gt;Escape analysis for Java&lt;/a&gt; была представлена в 1999 году.&lt;br /&gt;
&lt;br /&gt;
В java каждая нить (thread) имеет свой собственный кусок памяти - &lt;span class="i"&gt;стек (stack)&lt;/span&gt;, который хранит  фреймы (историю вызовов методов), частичные результаты операций, локальные переменные (примитивы, в т.ч. и указатели/ссылки на объекты). В этом смысле java стек очень похож на стек C++, за исключением того, что в java стеком нельзя напрямую оперировать и создавать на нём объекты, как в C++.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="i"&gt;Куча (heap)&lt;/span&gt;, общая для всех нитей область памяти, используется для хранения всех создаваемых объектов.&lt;br /&gt;
&lt;div class="center"&gt;&lt;img src="http://lh6.ggpht.com/_0W-IrdaBLsY/TSQzYej0ceI/AAAAAAAAFxA/2PXkhPK9a4Q/escapeAnalysis11.png" /&gt;&lt;br /&gt;
&lt;span class="i"&gt;-XX:-DoEscapeAnalysis&lt;/span&gt;&lt;br /&gt;
Объекты создаются на общей куче&lt;/div&gt;&lt;br /&gt;
Благодаря escape-анализу объекты могут быть созданы прямо на стеке или размещены в регистрах (используя register allocator). Не смотря на то , что создание объекта на кучи всё достаточно дешёвая операция - есть обратная сторона - &lt;span class="i"&gt;Garbage Collector&lt;/span&gt;. Для высоконагруженных приложений даже вызов minor gc это существенные затраты. Объект, созданный на стеке, будет уничтожен, когда он покинет stack frame, в котором он был создан, как следствие - отсутствие нагрузки на (minor) GC.&lt;br /&gt;
&lt;div class="center"&gt;&lt;img src="http://lh4.ggpht.com/_0W-IrdaBLsY/TSSbDPxHskI/AAAAAAAAFxI/u7T5UEmwj6Q/escapeAnalysis2.png" /&gt;&lt;br /&gt;
&lt;span class="i"&gt;-XX:+DoEscapeAnalysis&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
Более того - нет необходимости использовать блокировку для локализованных объектов - т.к. жизненный цикл объекта ограничен одним блоком и никакая другая нить не может его &amp;laquo;увидеть&amp;raquo; или использовать (прямое следствие из определения &lt;span class="i"&gt;pointer escape&lt;/span&gt;) .&lt;br /&gt;
&lt;br /&gt;
В качестве примера используем следующий microbenchmark:&lt;pre class="code"&gt;&lt;code class="java"&gt;import java.util.*;

public class Foo {
public static void main(String[] args){
final int warmup = 100 * 1000; 
final int run = 1000 * 1000; 
foo(warmup);
final long start = System.nanoTime();
foo(run);
final long end = System.nanoTime();
System.out.println((end - start) / 1000 / 1e3);
}

private static int foo(int count){
int s = 0; 
for(int i = 0; i &amp;lt; count; i++){
Collection c = new ArrayList();
s += c.size();
}
return s;
}
}&lt;/code&gt;&lt;/pre&gt;&lt;pre class="code"&gt;$ java -XX:-DoEscapeAnalysis -verbose:gc -XX:+PrintGCDetails Foo
[GC [PSYoungGen: 12160K-&amp;gt;152K(14144K)] 12160K-&amp;gt;152K(46528K), 0.0019620 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 12312K-&amp;gt;136K(26304K)] 12312K-&amp;gt;136K(58688K), 0.0008050 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 24456K-&amp;gt;136K(26304K)] 24456K-&amp;gt;136K(58688K), 0.0006690 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 24456K-&amp;gt;136K(50624K)] 24456K-&amp;gt;136K(83008K), 0.0005730 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
65.78
Heap
PSYoungGen      total 50624K, used 14728K [0xa3e20000, 0xa7180000, 0xb3ac0000)
eden space 48640K, 30% used [0xa3e20000,0xa4c602a8,0xa6da0000)
from space 1984K, 6% used [0xa6f90000,0xa6fb2050,0xa7180000)
to   space 1984K, 0% used [0xa6da0000,0xa6da0000,0xa6f90000)
PSOldGen        total 32384K, used 0K [0x844c0000, 0x86460000, 0xa3e20000)
object space 32384K, 0% used [0x844c0000,0x844c0000,0x86460000)
PSPermGen       total 16384K, used 1900K [0x804c0000, 0x814c0000, 0x844c0000)
object space 16384K, 11% used [0x804c0000,0x8069b048,0x814c0000)&lt;/pre&gt;&lt;pre class="code"&gt;$ java -XX:+DoEscapeAnalysis -verbose:gc -XX:+PrintGCDetails Foo
0.747
Heap
PSYoungGen      total 14144K, used 4135K [0xa3ed0000, 0xa4e90000, 0xb3b70000)
eden space 12160K, 34% used [0xa3ed0000,0xa42d9d90,0xa4ab0000)
from space 1984K, 0% used [0xa4ca0000,0xa4ca0000,0xa4e90000)
to   space 1984K, 0% used [0xa4ab0000,0xa4ab0000,0xa4ca0000)
PSOldGen        total 32384K, used 0K [0x84570000, 0x86510000, 0xa3ed0000)
object space 32384K, 0% used [0x84570000,0x84570000,0x86510000)
PSPermGen       total 16384K, used 1893K [0x80570000, 0x81570000, 0x84570000)
object space 16384K, 11% used [0x80570000,0x807496f0,0x81570000)&lt;/pre&gt;&lt;br /&gt;
и такой же тест, для &lt;span class="i"&gt;java.util.Vector&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td colspan="2" style="text-align:center;"&gt;ArrayList&lt;/td&gt;&lt;td colspan="2" style="text-align:center;"&gt;Vector&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;-EA&lt;/td&gt;&lt;td&gt;+EA&lt;/td&gt;&lt;td&gt;-EA&lt;/td&gt;&lt;td&gt;+EA&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;время выполнения, ms:&lt;/td&gt;&lt;td&gt;65.78&lt;/td&gt;&lt;td&gt;0.747&lt;/td&gt;&lt;td&gt;115.805&lt;/td&gt;&lt;td&gt;0.83&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;срабатываний GC:&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;время работы GC, ms:&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;4.5&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
Как и ожидалось время выполнения значительно меньше, меньше вызовов GC, который удаляет объекты «как только так сразу» из young geneneration. Так же заметно ускорение работы thread-safe «версии» ArrayList'а - java.util.Vector.&lt;br /&gt;
&lt;br /&gt;
Однако, не стоит надеяться, что благодаря escape-анализу производительность увеличится столь же стремительно как в данном синтетическом тесте. Определённо можно сказать, что нагрузка на GC будет значительно меньше для большинства типов приложений.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="center"&gt;&lt;img src="http://lh3.ggpht.com/_0W-IrdaBLsY/TSTZOwjTFHI/AAAAAAAAFxU/tmlVIbhEWa4/noname.jpg"&gt;&lt;br /&gt;
график нагрузки gc реального приложения&lt;br /&gt;
до использования java6u14 и после,&lt;br /&gt;
по вертикали - суммарное время проведённое в gc&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;Оптимизация конкатенации строк&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;-XX:+OptimizeStringConcat&lt;/span&gt; (java 6u20+).&lt;br /&gt;
&lt;br /&gt;
Несколько типичных шаблонов по конкатенации можно оптимизировать, например, String использует тот же объект char[] (т.е та же ссылка/указатель) который хранит StringBuffer или StringBuilder: &lt;div class="quote"&gt;The end result is the saving of an unnecessary char[] allocation and a subsequent call to arraycopy.&lt;/div&gt;&lt;br /&gt;
Рассмотрим в деталях, что происходит, при формировании, например, сообщения:&lt;img src="http://lh6.ggpht.com/_0W-IrdaBLsY/TSTIeOzJf8I/AAAAAAAAFxQ/v1oYZhcQtHg/logMessage.png"&gt;&lt;br /&gt;
Более детально стоит обратить, что происходит в методе &lt;span class="i"&gt;java.lang.StringBuilder.toString()&lt;/span&gt;:&lt;pre class="code"&gt;&lt;code class="java"&gt;    public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}&lt;/code&gt;&lt;/pre&gt;и далее в конструкторе &lt;span class="i"&gt;java.lang.String&lt;/span&gt;:&lt;pre class="code"&gt;&lt;code class="java"&gt;    public String(char value[], int offset, int count) {
if (offset &amp;lt; 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count &amp;lt; 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1&amp;gt;&amp;gt;&amp;gt;1.
if (offset &amp;gt; value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
&lt;img src="http://lh5.ggpht.com/_0W-IrdaBLsY/TS4RjAGKQHI/AAAAAAAAFzk/aOrLOvzILRw/optimizeStrConcat.png"/&gt;
this.offset = 0;
this.count = count;
this.value = v;
}&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;Использование byte[] вместо char[] для строки содержащей исключительно ASCII символы.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="b i"&gt;-XX:+UseCompressedStrings&lt;/span&gt; (java6u21) &lt;br /&gt;
&lt;br /&gt;
&lt;span class="i"&gt;java.lang.String&lt;/span&gt; по своей сути является обёрткой вокруг массива &lt;span class="i"&gt;char[]&lt;/span&gt;, делая его защищённым и не изменяемым. &lt;span class="i"&gt;char&lt;/span&gt; занимает 2 байта. Если же строки используют исключительно &lt;span class="i"&gt;ASCII&lt;/span&gt; символы, т.е ограничены диапазоном одного байта - используя данную оптимизацию немного сэкономить память.&lt;br /&gt;
&lt;br /&gt;
Однако, не стоит ожидать, что объём используемой памяти сильно сократится.&lt;/li&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/ul&gt;Ссылки:&lt;ul style="list-style-type:lower-alpha;"&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/java/library/j-jtp09275.html"&gt;Java theory and practice: Urban performance legends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://work.tinou.com/2009/06/lock-coarsening-biased-locking-escape-analysis-for-dummies.html"&gt;Lock Coarsening, Biased Locking, Escape Analysis for Dummies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.oracle.com/technetwork/java/javase/tech/biasedlocking-oopsla2006-preso-150106.pdf"&gt;Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.amd.com/documentation/articles/pages/01302008_jvm.aspx"&gt;How JVMs use Escape Analysis to Improve Application Performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://java.sun.com/performance/reference/whitepapers/6_performance.html"&gt;Java SE 6 Performance White Paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6320351"&gt;new register allocator for c1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html"&gt;Java HotSpot VM Options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6892658"&gt;C2 should optimize some stringbuilder patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6650179"&gt;StringBuilder.toString() and StringBuffer.toString() optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-6485785396396949437?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/vYtk2xU-syo/lock-coarsening-biased-locking-escape.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_0W-IrdaBLsY/TSQzYL6IeWI/AAAAAAAAFw0/3elnkMbfpZ4/s72-c/eliminateLocks.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2011/01/lock-coarsening-biased-locking-escape.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-2278643709621197709</guid><pubDate>Sun, 31 Oct 2010 15:03:00 +0000</pubDate><atom:updated>2010-10-31T22:51:41.389+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">clojure</category><title>Applicative-order evaluation vs Normal-order evaluation</title><description>&lt;span class="i"&gt;Нормальным порядком вычисления&lt;/span&gt; (normal-order evaluation), если кратко, можно назвать такой порядок вычисления, что сперва происходит &amp;laquo;полная подстановка, затем редукция&amp;raquo;.&lt;br /&gt;&lt;br /&gt;&lt;span class="i"&gt;Аппликативный порядок вычисления&lt;/span&gt; (applicative-order evaluation), напротив, сперва происходит &amp;laquo;вычисление аргументов, затем вызов процедуры&amp;raquo;.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;В качестве наглядного примера - попробуем реализовать свою собственную функцию &lt;span class="b i"&gt;and&lt;/span&gt; для &lt;span class="i"&gt;clojure&lt;/span&gt;.&lt;br /&gt;&lt;pre class="code"&gt;&lt;code class="clojure"&gt;(defn&lt;br /&gt;  #^{:test (fn []&lt;br /&gt; (assert (true? (my-and true)))&lt;br /&gt; (assert (false? (my-and true false)))&lt;br /&gt; (assert (true? (my-and true true)))&lt;br /&gt; (assert (false? (my-and true true false)))&lt;br /&gt; (assert (true? (my-and true true true)))&lt;br /&gt;)}&lt;br /&gt;  my-and &lt;br /&gt;  ([x] x)&lt;br /&gt;  ([x &amp;amp; more] (if (false? x) x (reduce my-and more)))&lt;br /&gt;)&lt;/code&gt;&lt;/pre&gt;Отлично. &lt;br /&gt;&lt;br /&gt;Почему же тогда автор &lt;span class="b i"&gt;clojure&lt;/span&gt; решил использовать макросы в реализации функции &lt;a href="http://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L693"&gt;and&lt;/a&gt; ?&lt;br /&gt;&lt;br /&gt;В группе языков lisp, как впрочем и во многих других языках, используется &lt;span class="i"&gt;аппликативный порядок вычисления&lt;/span&gt; (в общем случае, если не используются мощности &amp;laquo;синтаксического сахара&amp;raquo;). &lt;br /&gt;&lt;br /&gt;Разница между &lt;span class="i b"&gt;my-and&lt;/span&gt; и &lt;span class="b i"&gt;and&lt;/span&gt; в том, что &lt;span class="i b"&gt;my-and&lt;/span&gt; использует аппликативный порядок (т.е все аргументы будут вычислены до вызова функции), в то время как &lt;span class="b i"&gt;and&lt;/span&gt; использует несколько иной порядок. &lt;br /&gt;И, поэтому, один из легальных способов изменить порядок вычисления - применение &lt;span class="i"&gt;макросов&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;В качестве примера используем функцию &lt;span class="b i"&gt;foo&lt;/span&gt;:&lt;pre class="code"&gt;&lt;code class="clojure"&gt;user=&amp;gt; (defn foo[x] (do (println "foo") x))&lt;br /&gt;user=&amp;gt; (my-and (foo false) (foo false) (foo true))&lt;br /&gt;foo&lt;br /&gt;foo&lt;br /&gt;foo&lt;br /&gt;false&lt;br /&gt;user=&amp;gt; (and (foo false) (foo false) (foo true))&lt;br /&gt;foo&lt;br /&gt;false&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="i"&gt;P.S.&lt;/span&gt; Строго говоря, &lt;span class="b i"&gt;and&lt;/span&gt; не использует нормальный порядок вычисления, а &amp;laquo;псевдонормальный порядок&amp;raquo; на один шаг.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-2278643709621197709?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/FWBlu5UCOSs/applicative-order-evaluation-vs-normal.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>0</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/10/applicative-order-evaluation-vs-normal.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-5276387656646482943</guid><pubDate>Sun, 26 Sep 2010 17:27:00 +0000</pubDate><atom:updated>2011-01-05T11:59:10.175+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">hazelcast</category><title>Hazelcast</title><description>&lt;div style="padding:15px;"&gt;&lt;img style="display:block; margin:10px;float:left;" src="http://lh5.ggpht.com/_0W-IrdaBLsY/TK2gUIzTMGI/AAAAAAAAFqc/GUjyAjwm9og/hz-logo.png"/&gt; &lt;span class="b"&gt;hazelcast&lt;/span&gt; &lt;br/&gt;&lt;span class="i"&gt;In-Memory Data Grid for Java&lt;/span&gt;&lt;br/&gt;&lt;a href="http://code.google.com/p/hazelcast/"&gt;hazelcast project&lt;/a&gt; on Google Code; &lt;a href="http://hazelcast.com/"&gt;Hazelcast.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.hazelcast.com/documentation.jsp"&gt;hazelcast documentation&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="b"&gt;Краткая история&lt;/span&gt;:&lt;ul&gt;&lt;li&gt;Start-up, основан 2008&lt;/li&gt;&lt;li&gt;Open source бизнес модель. Получение прибыли на консалтинге и поддержке самого Hazelcast&lt;/li&gt;&lt;li&gt;Более 100 пользователей, в основном в США и в Европе&lt;/li&gt;&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="b"&gt;Характеристики&lt;/span&gt;:&lt;ul&gt;&lt;li&gt;Pure java 5, NIO&lt;/li&gt;&lt;li&gt;Apache 2.0 licence&lt;/li&gt;&lt;li&gt;Light-weight &amp;amp; simple&lt;/li&gt;&lt;li&gt;Распределённая реализация &lt;ul&gt;&lt;li&gt;java.util.{Queue, Set, List, Map}&lt;/li&gt;&lt;li&gt;java.util.concurrency.locks.Lock&lt;/li&gt;&lt;li&gt;java.util.concurrent.ExecutorService&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Распределённый MultiMap для взаимосвязи один-ко-многим&lt;/li&gt;&lt;li&gt;Поддержка шифрования на уровне socket&lt;/li&gt;&lt;li&gt;Распределённые Topic для публикации/подписки сообщений&lt;/li&gt;&lt;li&gt;Socket level encryption support for secure clusters&lt;/li&gt;&lt;li&gt;Синхронное (write-through) и асинхронное (write-behind) сохранение в БД&lt;/li&gt;&lt;li&gt;Мониторинг и управление кластером через JMX&lt;/li&gt;&lt;li&gt;Поддержка инфомации о состоянии кластера и его членов&lt;/li&gt;&lt;li&gt;Динамическое обранужение&lt;/li&gt;&lt;li&gt;Динамическое масштабирование&lt;/li&gt;&lt;li&gt;Динамическое перераспределние резервных копий данных&lt;/li&gt;&lt;li&gt;Динамический fail-over &lt;/li&gt;&lt;li&gt;и другое&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="b"&gt;Конкуренты&lt;/span&gt;:&lt;br /&gt;Сами отцы Hazelcast'а называют своими конкурентами:&lt;ul&gt;&lt;li&gt;Oracle Coherence&lt;/li&gt;&lt;li&gt;IBM WebSphere eXtreme Scale / ObjectGrid&lt;/li&gt;&lt;li&gt;TerracoWa&lt;/li&gt;&lt;li&gt;Gigaspaces&lt;/li&gt;&lt;li&gt;Gemstone&lt;/li&gt;&lt;li&gt;JBossCache/JGroups/Infinispan&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Поскольку мой опыт ограничен &lt;span class="b i"&gt;Oracle/Tangosol Coherence&lt;/span&gt;, то сравниваю всегда именно с ним. Однако в целом продукты по функциональности очень похожи друг на друга:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Quick start: один единственный jar, который нужно добавить в &lt;span class="i"&gt;classpath&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Простое конфигурирование:&lt;ul&gt;&lt;li&gt;описание кластера - имя, пароль, шифрование, если необходимо&lt;/li&gt;&lt;li&gt;описание сети узлов- multicast,unicast,tcp/ip&lt;/li&gt;&lt;li&gt;декларация map и их свойств&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Очень схожий API, как по функционалу, так и по названию - порой отличие только в наименовании package'ей&lt;/li&gt;&lt;li&gt;Производительность (latency) - разница не более 30% (как +, так и -)&lt;/li&gt;&lt;li&gt;Детально не исследовался вопрос:&lt;ul&gt;&lt;li&gt;потребление cpu&lt;/li&gt;&lt;li&gt;потребление памяти&lt;/li&gt;&lt;li&gt;объём сетового траффика&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Безусловно есть и различия.&lt;br /&gt;Так, например, не касаясь вопросов лицензии и стоимости - не нашёл распределённый topic, queue, executor service&lt;br /&gt;&lt;br /&gt;&lt;span class="b"&gt;Bugs&lt;/span&gt; &amp;amp; &lt;span class="b i"&gt;Hazelcast&lt;/span&gt;:&lt;br /&gt;Ошибки присутствуют, как и в любом проекте и продукте, большая часть не мешает его нормальному использованию - на критические ошибки реагируют (посте отправки issue в &lt;a href="http://code.google.com/p/hazelcast/issues/list"&gt;issue tracker&lt;/a&gt;) достаточно быстро - был случай, когда patch был создан в течении часа после отпраки issue. &lt;br /&gt;&lt;br /&gt;&lt;span class="b i"&gt;Однако&lt;/span&gt;, было найденно несколько критических ошибок, которые не были исправлены (согласно svn и дате их "добавления") более полугода, что заставляет очень сильно задуматься/удивится/etc в свете заявления самих &lt;span class="b i"&gt;hazelcast&lt;/span&gt;'овцев о сотне пользователей в US/Europe.&lt;br /&gt;&lt;br /&gt;Maven dependency:&lt;pre class="code"&gt;&lt;code class="xml"&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;com.hazelcast&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;hazelcast-all&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.9&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ivy dependency:&lt;pre class="code"&gt;&lt;code class="xml"&gt;&amp;lt;dependency org="com.hazelcast" name="hazelcast-all" rev="1.9"/&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span class="b i"&gt;P.S.&lt;/span&gt; Можно сказать, что &lt;span class="b i"&gt;Hazelcast&lt;/span&gt; - это реальная &lt;span class="i"&gt;open source&lt;/span&gt; альтернатива &lt;span class="b i"&gt;Oracle Coherence&lt;/span&gt; под Apache license. Сообщество живое, реагируют быстро, новые идеи и функциональность приветствуется - проект растёт и вполне успешно.&lt;br /&gt;&lt;br /&gt;&lt;span class="b i"&gt;P.P.S.&lt;/span&gt; С недавних пор я &lt;span class="i"&gt;hazelcast committer&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-5276387656646482943?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/fJMXLOHeVPE/hazelcast.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_0W-IrdaBLsY/TK2gUIzTMGI/AAAAAAAAFqc/GUjyAjwm9og/s72-c/hz-logo.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/09/hazelcast.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-6340867670332696176</guid><pubDate>Wed, 16 Jun 2010 07:12:00 +0000</pubDate><atom:updated>2011-03-10T11:58:00.166+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задача Льва Толстого</title><description>&lt;div class="quote"&gt;&lt;img style="display:block; margin:10px;float:left;" src="http://lh3.ggpht.com/_0W-IrdaBLsY/TBh6xMwmM4I/AAAAAAAAFdc/7xWxzoDP0ys/1909-25-1.jpg"/&gt; Продавец продаёт шапку. Стоит &lt;span class="b"&gt;10 р&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Подходит покупатель, меряет и согласен взять, но у него есть только банкнота 25 р. Продавец отсылает мальчика с этими &lt;span class="b"&gt;25 р.&lt;/span&gt; к соседке разменять. &lt;br /&gt;&lt;br /&gt;Мальчик прибегает и отдаёт 10 + 10 + 5. &lt;br /&gt;&lt;br /&gt;Продавец отдаёт шапку и сдачу &lt;span class="b"&gt;15 руб.&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Через какое-то время приходит соседка и говорит, что 25 р. &lt;span class="b"&gt;фальшивые&lt;/span&gt;, требует отдать ей деньги. Ну что делать. Продавец лезет в кассу и возвращает ей деньги.&lt;br /&gt;&lt;br /&gt;На сколько обманули продавца &lt;span class="b"&gt;?&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class='clear'&gt;&lt;/div&gt; &lt;span class="b i"&gt;внимание!&lt;/span&gt;  комментарии содержат ответ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-6340867670332696176?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/7nKPjf_nXEE/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_0W-IrdaBLsY/TBh6xMwmM4I/AAAAAAAAFdc/7xWxzoDP0ys/s72-c/1909-25-1.jpg" height="72" width="72" /><thr:total>12</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/06/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-702250004503715620</guid><pubDate>Fri, 30 Apr 2010 10:54:00 +0000</pubDate><atom:updated>2010-04-30T16:18:40.912+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Круглый стол</title><description>&lt;div class="quote"&gt;&lt;img style="display:block; margin:10px;float:left;" src="http://lh5.ggpht.com/_0W-IrdaBLsY/S9q459W_V7I/AAAAAAAAFOA/Op53EBM_PC0/Reversi_istock.jpg"/&gt; За круглым столом сидят два игрока.&lt;br /&gt;&lt;br /&gt;Первый играет белыми круглыми фишками, второй - такими же, но чёрными.&lt;br /&gt;&lt;br /&gt;Игрок &lt;span class="b"&gt;должен&lt;/span&gt; положить на стол только &lt;span class="b"&gt;одну&lt;/span&gt; фишку, после чего ход переходит к другому игроку.&lt;br /&gt;&lt;br /&gt;Игрок проигрывает, если нет свободного места, чтобы положить фишку.&lt;br /&gt;&lt;br /&gt;Как следует действовать игроку, начинающему игру, чтобы &lt;span class="b"&gt;всегда&lt;/span&gt; выигрывать ?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-702250004503715620?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/Clrn5eYe6Xo/blog-post_30.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_0W-IrdaBLsY/S9q459W_V7I/AAAAAAAAFOA/Op53EBM_PC0/s72-c/Reversi_istock.jpg" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/04/blog-post_30.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-8446118006894429673</guid><pubDate>Wed, 28 Apr 2010 11:05:00 +0000</pubDate><atom:updated>2010-04-28T15:07:55.953+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Мальчики</title><description>&lt;div class="quote"&gt;В семье два ребенка, причём один из них мальчик.&lt;br /&gt;&lt;br /&gt;Какая вероятность что и другой &lt;span class="b"&gt;тоже мальчик&lt;/span&gt; ?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-8446118006894429673?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/3bhPVsm67OQ/blog-post_9772.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>8</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/04/blog-post_9772.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4236993755986258070</guid><pubDate>Wed, 28 Apr 2010 11:03:00 +0000</pubDate><atom:updated>2011-03-09T22:15:45.236+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Сколько лет детям</title><description>&lt;div class="quote"&gt;Встречаются 2 друга&lt;br /&gt;- Привет&lt;br /&gt;- Привет&lt;br /&gt;- Как дела?&lt;br /&gt;- Растут два сына дошкольника.&lt;br /&gt;- Сколько им лет?&lt;br /&gt;- Произведение их возрастов равно количеству голубей около скамейки.&lt;br /&gt;- Этой информации мне не достаточно.&lt;br /&gt;- Старший похож на мать.&lt;br /&gt;- Вот теперь я знаю сколько лет твоим детям.&lt;br /&gt;&lt;br /&gt;&lt;span class="b"&gt;Сколько лет детям?&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="b i"&gt;внимание!&lt;/span&gt;  комментарии содержат ответ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4236993755986258070?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/_-mODzEaDaM/blog-post_28.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>8</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/04/blog-post_28.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-3822907805424855515</guid><pubDate>Tue, 20 Apr 2010 10:09:00 +0000</pubDate><atom:updated>2010-04-20T14:19:59.142+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Таблетки</title><description>&lt;div class="quote"&gt;В джунглях тебя укусила ядовитая змея.&lt;br /&gt;&lt;br /&gt;В аптечке есть 4 таблетки - две типа &lt;span class="b i"&gt;А&lt;/span&gt; две типа &lt;span class="b i"&gt;Б&lt;/span&gt;, причём выглядят &lt;span class="b"&gt;абсолютно одинаково&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Противоядие - одна таблетка типа &lt;span class="b i"&gt;А&lt;/span&gt; и одна таблетка типа &lt;span class="b i"&gt;Б&lt;/span&gt;. &lt;br /&gt;Во всех других случаях умираешь от змеиного яда (т.е если выпить две таблетки &lt;span class="b i"&gt;А&lt;/span&gt;, или две &lt;span class="b i"&gt;Б&lt;/span&gt; или выпить сразу 2 &lt;span class="b i"&gt;А&lt;/span&gt; и 2 &lt;span class="b i"&gt;Б&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;Как стоит действовать?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-3822907805424855515?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/LEUZTgwHBEw/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>3</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/04/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-7665955464130692453</guid><pubDate>Sat, 17 Apr 2010 16:51:00 +0000</pubDate><atom:updated>2011-01-10T21:36:41.076+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jit</category><title>java: How to get PrintAssembly</title><description>Thanks to Roman Yaroslavtsev who gave me a link to an article &lt;a href="http://www.infoq.com/articles/memory_barriers_jvm_concurrency"&gt;Memory Barriers and JVM Concurrency&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;First of all this article is useful to gain a better understanding of &lt;span class="i"&gt;Java Memory Model&lt;/span&gt; - another great thing that I discover is ability to look inside of assembly code generated by &lt;span class="i"&gt;jit&lt;/span&gt;.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Refer to &lt;a href="http://dotsid.blogspot.com/2010/04/ldt.html"&gt;load-test-tool&lt;/a&gt; usage I going to use that simple example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;code class="java"&gt;public class ArrayIterationTest {&lt;br /&gt;&lt;br /&gt;  private final int[] data;&lt;br /&gt;&lt;br /&gt;  public ArrayIterationTest(final int size) {&lt;br /&gt;    this.data = new int[size];&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void doTest() {&lt;br /&gt;    for ( int i = 0; i &amp;lt; data.length; i++ ){&lt;br /&gt;  int j = data[i]; &lt;br /&gt; }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static final void main(String[] args){&lt;br /&gt;   final long t0 = System.nanoTime(); &lt;br /&gt;   ArrayIterationTest t = new ArrayIterationTest(1000000);&lt;br /&gt;   t.doTest();&lt;br /&gt;   System.out.println((System.nanoTime() - t0) / 1000 / 1e3);&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's start it (user's jvm is sun jdk 1.6.0_20):&lt;br /&gt;&lt;pre class="code"&gt;java -XX:+UnlockDiagnosticVMOptions&lt;br /&gt;-XX:+PrintAssembly -XX:PrintAssemblyOptions=hsdis-print-bytes&lt;br /&gt;-XX:CompileCommand=print,ArrayIterationTest&lt;br /&gt;ArrayIterationTest&lt;/pre&gt; and have got &lt;pre class="code"&gt;CompilerOracle: print ArrayIterationTest&lt;br /&gt;Could not load hsdis-i386.so; library not loadable; PrintAssembly is disabled&lt;br /&gt;14.029&lt;/pre&gt;&lt;br /&gt;So... &lt;br /&gt;&lt;br /&gt;Dude, where's my &lt;span class="b"&gt;hsdis-i386.so&lt;/span&gt; ? &lt;br /&gt;&lt;br /&gt;There is no hsdis-i386.so in dev-java/sun-jdk-1.6.0.20, nor in dev-java/sun-jdk-1.7.0.0_alpha89 or in dev-java/icedtea6-bin-1.8.0&lt;br /&gt;&lt;br /&gt;Let's fetch openjdk plugin implementation &lt;pre class="code"&gt;hg clone http://hg.openjdk.java.net/jdk7/hotspot/hotspot/src/share/tools/hsdis/ openjdk-hotspot&lt;/pre&gt;  and build it using hsdis's &lt;a href="http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/tip/src/share/tools/hsdis/README"&gt;README&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This version of the plugin requires the Gnu disassembler, which is available separately as part of the &lt;a href="http://directory.fsf.org/project/binutils"&gt;binutils  project&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;code class="bash"&gt;cd openjdk-hotspot/src/share/tools/hsdis/&lt;br /&gt;mkdir build &amp;amp;&amp;amp; cd build&lt;br /&gt;wget &lt;a href="http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.bz2"&gt;http://ftp.gnu.org/gnu/binutils/binutils-2.20.1.tar.bz2&lt;/a&gt; &lt;br /&gt;tar jxf binutils-2.20.1.tar.bz2 &amp;amp;&amp;amp; mv binutils-2.20.1 binutils &amp;amp;&amp;amp; cd ..&lt;br /&gt;make&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and start again it now: &lt;pre class="code"&gt;LD_LIBRARY_PATH=&lt;span class="i"&gt;openjdk-hotspot/src/share/tools/hsdis/build/linux-i586/&lt;/span&gt;:$LD_LIBRARY_PATH&lt;br /&gt;java -XX:+UnlockDiagnosticVMOptions&lt;br /&gt;-XX:+PrintAssembly -XX:PrintAssemblyOptions=hsdis-print-bytes&lt;br /&gt;-XX:CompileCommand=print,ArrayIterationTest&lt;br /&gt;ArrayIterationTest&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="i"&gt;Note:&lt;/span&gt; use your own path to &lt;span class="b"&gt;hsdis-&lt;span class="i"&gt;arch&lt;/span&gt;.so&lt;/span&gt; in LD_LIBRARY_PATH .&lt;br /&gt;&lt;br /&gt;And you've got something like this for your platform:&lt;br /&gt;&lt;pre class="code"&gt;CompilerOracle: print ArrayIterationTest&lt;br /&gt;Loaded disassembler from hsdis-i386.so&lt;br /&gt;Decoding compiled method 0xb3bb5c48:&lt;br /&gt;Code:&lt;br /&gt;[Disassembling for mach='i386']&lt;br /&gt;[Entry Point]&lt;br /&gt;[Verified Entry Point]&lt;br /&gt;  0xb3bb5d20: call   0xb7168b60         ;...e83b2e5b 03&lt;br /&gt;                                        ;   {runtime_call}&lt;br /&gt;  0xb3bb5d25: xchg   %ax,%ax            ;...666690&lt;br /&gt;  ...&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ps. for further information please refer to &lt;a href="http://wikis.sun.com/display/HotSpotInternals/PrintAssembly"&gt;PrintAssembly at wikis.sun.com&lt;/a&gt; as well as for prebuild &lt;span class="i"&gt;hsdis-i386.dll&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-7665955464130692453?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/Y3sEJy4L-tc/java-printassembly.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>2</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/04/java-printassembly.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-4133876200664541646</guid><pubDate>Sun, 28 Mar 2010 19:50:00 +0000</pubDate><atom:updated>2010-03-29T14:47:18.031+04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">fp</category><category domain="http://www.blogger.com/atom/ns#">clojure</category><title>FP-approach in Java via Goolge Collections</title><description>I'm going to demonstrate some elements of functional programming (&lt;span class="b i"&gt;fp&lt;/span&gt;) approach in java.&lt;br /&gt;&lt;br /&gt;For this purpose I use &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections Library&lt;/a&gt; - provides new and elegant collection types as well as some &lt;span class="b i"&gt;fp&lt;/span&gt; elements and techniques.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;A bit more about Google Collections Library:&lt;br /&gt;&lt;a href="http://code.google.com/p/google-collections/wiki/Faq"&gt;Google Collections Library FAQ&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.javalobby.org/articles/google-collections/"&gt;What is the Google Collections Library?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://bwinterberg.blogspot.com/2009/09/introduction-to-google-collections.html"&gt;Introduction to Google Collections by Benjamin Winterberg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For obvious cases I put examples in &lt;span class="b"&gt;clojure&lt;/span&gt; and in &lt;span class="b"&gt;java&lt;/span&gt; using fp-approach techniques.&lt;br /&gt;&lt;br /&gt;Took short and nice example from "Programming clojure" book - StringUtils.isBlank() is the method (from the &lt;a href="http://commons.apache.org/"&gt;Apache Commons&lt;/a&gt;) checks to see whether a string is blank: either empty or consisting of only whitespace :&lt;pre class="code"&gt;&lt;code class="java"&gt;public static boolean isBlank(String str) {&lt;br /&gt;  int strLen;&lt;br /&gt;  if (str == null || (strLen = str.length()) == 0) {&lt;br /&gt;    return true;&lt;br /&gt;  }&lt;br /&gt;  for (int i = 0; i &amp;lt; strLen; i++) {&lt;br /&gt;    if ((Character.isWhitespace(str.charAt(i)) == false)) {&lt;br /&gt;      return false;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;Here is a similar implementation in Clojure:&lt;pre class="code"&gt;&lt;code class="lisp"&gt;(defn blank? [s] (every? #(Character/isWhitespace %) s))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Java-fp-approach implementation of isBlank method powered by google collections,  string is a sequence of chars - that's why I had introduce &lt;a href="http://gist.github.com/346279"&gt;stringIterator&lt;/a&gt;:&lt;pre class="code"&gt;&lt;code class="java"&gt;import static ru.dolzhenko.lambda.iterators.StringIterator.*;&lt;br /&gt;&lt;br /&gt;import static com.google.common.collect.Iterators.*;&lt;br /&gt;&lt;br /&gt;public static boolean isBlank(String str) {&lt;br /&gt;return all(&lt;a href="http://gist.github.com/346279"&gt;stringIterator&lt;/a&gt;(str),&lt;br /&gt;  new Predicate&amp;lt;Character&amp;gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public boolean apply(Character ch) {&lt;br /&gt;      return Character.isWhitespace(ch);&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;&lt;span class="b i"&gt;map&lt;/span&gt; is function mapping, a classic primitive in functional programming - apply a function to all elements of a list, and return the resulting list.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;e.g. parse string values to numbers:&lt;pre class="code"&gt;&lt;code class="lisp"&gt;(map #(Integer/valueOf %) ["1" "2" "3"])&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;on java: &lt;pre class="code"&gt;&lt;code class="java"&gt;Collections2.transform(&lt;br /&gt;  ImmutableList.of("1", "2", "3"), &lt;br /&gt;  new Function&amp;lt;String, Integer&amp;gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public Integer apply(String from) {&lt;br /&gt;      return Integer.valueOf(from);&lt;br /&gt;    }&lt;br /&gt;  });&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Transform is also available for &lt;span class="i"&gt;Iterables.transform(Iterable, Function)&lt;/span&gt;, &lt;span class="i"&gt;Iterators.transform(Iterator, Function)&lt;/span&gt; etc.&lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;The &lt;span class="b i"&gt;reduce&lt;/span&gt; function is a little less obvious in its intent. This function reduces a list to a single value by combining elements via a supplied function.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="quote"&gt;The &lt;span class="b i"&gt;filter&lt;/span&gt; function returns elements of collection that satisfy predicate.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;For instance, Let's solve &lt;a href="http://projecteuler.net/index.php?section=problems&amp;id=1"&gt;ProjectEuler - Problem #1&lt;/a&gt; - find the sum of all the multiples of 3 or 5 below 1000:&lt;pre class="code"&gt;&lt;code class="lisp"&gt;(reduce + (filter #(or (zero? (mod % 3)) (zero? (mod % 5))) (range 1000)))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;... and the same on java: &lt;pre class="code"&gt;&lt;code class="java"&gt;// import static import static com.google.common.base.Predicates.*;&lt;br /&gt;// import static com.google.common.collect.Iterators.*;&lt;br /&gt;&lt;br /&gt;// import static ru.dolzhenko.lambda.iterators.&lt;a href="http://gist.github.com/346755#file_lambda_iterators.java"&gt;LambdaIterators&lt;/a&gt;.*;&lt;br /&gt;// import static ru.dolzhenko.lambda.functions.&lt;a href="http://gist.github.com/346755#file_lambda_functions.java"&gt;LambdaFunctions&lt;/a&gt;.*;&lt;br /&gt;// import static ru.dolzhenko.lambda.functions.&lt;a href="http://gist.github.com/346755#file_lambda_predicates.java"&gt;LambdaPredicates&lt;/a&gt;.*;&lt;br /&gt;&lt;br /&gt;final BigDecimal value = reduce(sum(), filter(range(1000),&lt;br /&gt;  or(&lt;br /&gt;    zero(mod(new BigDecimal(3))),&lt;br /&gt;    zero(mod(new BigDecimal(5)))&lt;br /&gt;  )));&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yeah, there are no &lt;span class="b i"&gt;reduce&lt;/span&gt; and &lt;span class="b i"&gt;range&lt;/span&gt; functions in google collections too, so I had to &lt;strike&gt;build my own theme park, with blackjack&lt;/strike&gt; make my own collection of functions &lt;a href="http://gist.github.com/346755"&gt;LambdaIterators &amp; Co.&lt;/a&gt; that supplement google collections with such useful functions as &lt;span class="b i"&gt;reduce&lt;/span&gt;, &lt;span class="b i"&gt;range&lt;/span&gt;, &lt;span class="b i"&gt;take&lt;/span&gt;, &lt;span class="b i"&gt;takeWhile&lt;/span&gt;, &lt;span class="b i"&gt;iterate&lt;/span&gt;, &lt;span class="b i"&gt;first&lt;/span&gt;, &lt;span class="b i"&gt;rest&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Definitely, &lt;span class="b i"&gt;Predicate&lt;/span&gt; is a function, so it can be described as &lt;pre class="code"&gt;&lt;code class="java"&gt;public interface Predicate&amp;lt;T&amp;gt; extends Function&amp;lt;T, Boolean&amp;gt;{ &lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;To avoid autoboxing overhead authors of google collections prefer to introduce new interface.&lt;br /&gt;&lt;br /&gt;After that we able to construct expressions like &lt;pre class="code"&gt;&lt;code class="lisp"&gt;(take 5 (filter even? (iterate inc 1)))&lt;/code&gt;&lt;/pre&gt;on java:&lt;pre class="code"&gt;&lt;code class="java"&gt;take(5, filter(iterate(inc(), BigDecimal.ONE), even()))&lt;/code&gt;&lt;/pre&gt; as well as for finite collection as well as for infinite collection - functions &lt;br /&gt;&lt;span class="b i"&gt;filter&lt;/span&gt;, &lt;span class="b i"&gt;transform&lt;/span&gt;, &lt;span class="b i"&gt;take&lt;/span&gt;, &lt;span class="b i"&gt;takeWhile&lt;/span&gt;, &lt;span class="b i"&gt;iterate&lt;/span&gt;, &lt;span class="b i"&gt;first&lt;/span&gt;, &lt;span class="b i"&gt;rest&lt;/span&gt; are lazy - in other words, elements are not calculated until they are needed.&lt;br /&gt;&lt;br /&gt;btw. &lt;a href="http://code.google.com/p/lambdaj"&gt;lambdaj&lt;/a&gt; is useful framework that provides pseudo fp approach in java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-4133876200664541646?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/A6Xi7baei-k/fp-approach-in-java-via-goolge.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><thr:total>4</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/03/fp-approach-in-java-via-goolge.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-6515036822916235398</guid><pubDate>Wed, 10 Mar 2010 10:31:00 +0000</pubDate><atom:updated>2011-03-09T22:16:53.907+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: Груши</title><description>&lt;div class="quote"&gt;&lt;img src="http://lh6.ggpht.com/_0W-IrdaBLsY/S5d07Fny3DI/AAAAAAAAE5k/yZiW9BfMLpQ/pears_9418_01_lill_.jpg" border="0" style="float:left;padding:20px;"&gt;В ящике 4 x 4 лежат груши (16 шт.)&lt;br /&gt;&lt;br /&gt;Какие 6 груш необходимо убрать, так, чтобы в каждой строке и каждом столбце было чётное число груш.&lt;div class='clear'&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="b i"&gt;внимание!&lt;/span&gt;  комментарии содержат ответ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-6515036822916235398?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/o8u9Xuj9-To/blog-post.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_0W-IrdaBLsY/S5d07Fny3DI/AAAAAAAAE5k/yZiW9BfMLpQ/s72-c/pears_9418_01_lill_.jpg" height="72" width="72" /><thr:total>9</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/03/blog-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-6819890660856209590</guid><pubDate>Mon, 01 Mar 2010 19:23:00 +0000</pubDate><atom:updated>2010-03-07T10:00:05.431+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">hosting git mercurial</category><title>Source hosting</title><description>Задумался я завести учётную запись на каком-нибудь социальном source hosting'е.&lt;br /&gt;Интересовали не только площадки для open source проектов, но и для личного закрытого использования.&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;И вот краткий обзор некоторых сервисов:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_0W-IrdaBLsY/S4y8juy1o3I/AAAAAAAAE30/lQyssgvPFAY/github.png" style="float: left;" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://github.com/"&gt;github&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: git&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;li&gt;Paid accounts: &lt;a href="http://github.com/plans"&gt;available&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;br /&gt;&lt;/th&gt;&lt;th&gt;Giga&lt;em&gt;&lt;/em&gt;&lt;/th&gt;&lt;th&gt;Medium&lt;/th&gt;&lt;th&gt;Small&lt;/th&gt;&lt;th&gt;Micro&lt;/th&gt;&lt;th&gt;Free&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Disk space&lt;/th&gt;&lt;td&gt;60.0 GB&lt;/td&gt;&lt;td&gt;2.4 GB&lt;/td&gt;&lt;td&gt;1.2 GB&lt;/td&gt;&lt;td&gt;0.6 GB&lt;/td&gt;&lt;td&gt;0.3 GB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Private repositories&lt;/th&gt;&lt;td&gt;300&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Private Collaborators&lt;/th&gt;&lt;td&gt;100&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Public repositories&lt;/th&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Wiki&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Issue tracker&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;SSL&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/cross.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Fee / month&lt;/th&gt;&lt;td&gt;$200&lt;/td&gt;&lt;td&gt;$22&lt;/td&gt;&lt;td&gt;$12&lt;/td&gt;&lt;td&gt;$7&lt;/td&gt;&lt;td&gt;&lt;span&gt;Free&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;К особенностям gitbuh'а стоит добавить сервис &lt;a href="http://gist.github.com/"&gt;gist.github&lt;/a&gt; позволяющий писать небольшие куски кода (snipplet) прямо из web'а с совместным доступом и, конечно же, версионностью.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_0W-IrdaBLsY/S4y8j_8faSI/AAAAAAAAE34/E2UdD7ObrvU/bitbucket.png" style="float: left;" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bitbucket.org/"&gt;bitbucket.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: mercurial&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;li&gt;Paid accounts: &lt;a href="http://bitbucket.org/plans/"&gt;available&lt;/a&gt;&lt;/li&gt;&lt;li&gt;+ openId login&lt;/li&gt;&lt;/ul&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Team&lt;/th&gt;&lt;th&gt;Large&lt;/th&gt;&lt;th&gt;Pro&lt;/th&gt;&lt;th&gt;Amateur&lt;/th&gt;&lt;th&gt;Free&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Disk space&lt;/th&gt;&lt;td&gt;50.0 GB&lt;/td&gt;&lt;td&gt;26.0 GB&lt;/td&gt;&lt;td&gt;5.0 GB&lt;/td&gt;&lt;td&gt;2.5 GB&lt;/td&gt;&lt;td&gt;1.0 GB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Private repositories&lt;/th&gt;&lt;td&gt;150&lt;/td&gt;&lt;td&gt;25&lt;/td&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Public repositories&lt;/th&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;td&gt;Unlimited&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;HTTP push/pull&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;SSH push/pull&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Wiki&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Issue tracker&lt;/th&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://bitbucket.org/m/img/icons/fugue/tick.png" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Fee / month&lt;br /&gt;&lt;/th&gt;&lt;td&gt;$100&lt;/td&gt;&lt;td&gt;$50&lt;/td&gt;&lt;td&gt;$12&lt;/td&gt;&lt;td&gt;$5&lt;/td&gt;&lt;td&gt;&lt;span&gt;Free!&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://unfuddle.com/images/unfuddle_git_and_subversion_hosting.png?1267899062"/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.assembla.com/"&gt;assembla.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: git, subversion&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;li&gt;Paid accounts: &lt;a href="http://www.assembla.com/plans"&gt;available&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.assembla.com/images/blue/assembla-logo.gif"/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.unfuddle.com/"&gt;unfuddle.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: git, subversion&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;li&gt;Paid accounts: &lt;a href="http://unfuddle.com/about/tour/plans"&gt;available&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Open Source oriented hosting:&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_0W-IrdaBLsY/S4zCpqQUpcI/AAAAAAAAE4A/2rXyZUErWzA/google_code.png" style="float: left;" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/projecthosting/"&gt;google code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: subversion, mercurial&lt;/li&gt;&lt;li&gt;Disk space: 1Gb&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;li&gt;Paid accounts: no&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_0W-IrdaBLsY/S4zCpeJSiVI/AAAAAAAAE38/8_2OxzElJW8/sf.png" style="float: left;" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/"&gt;sourceforge.net&lt;/a&gt;&lt;/li&gt;&lt;li&gt;repository type: SVN, Git, Mercurial, Bazaar, CVS servers&lt;/li&gt;&lt;li&gt;Free accounts: available&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.berlios.de/"&gt;berlios.de&lt;/a&gt;&lt;br /&gt;На всех площадках приосходит автоматическое резервирование данных.&lt;br /&gt;&lt;br /&gt;Дополнения приветствуются !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-6819890660856209590?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/M_1VrE2JwrI/source-hosting.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_0W-IrdaBLsY/S4y8juy1o3I/AAAAAAAAE30/lQyssgvPFAY/s72-c/github.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/03/source-hosting.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8870493191508591473.post-8876539221358949363</guid><pubDate>Fri, 26 Feb 2010 09:56:00 +0000</pubDate><atom:updated>2010-02-26T18:42:23.453+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">erlang</category><category domain="http://www.blogger.com/atom/ns#">clojure</category><category domain="http://www.blogger.com/atom/ns#">задачка</category><title>Задачка: A(4,3)</title><description>&lt;div class="quote"&gt;функция A(x,y) определена как&lt;br /&gt; A(0,y) = 1, y &amp;ge; 0 &lt;br /&gt; A(1,0) = 2 &lt;br /&gt; A(x,0) = x + 2, x &amp;ge; 2 &lt;br /&gt; A(x + 1, y + 1) = A( A(x, y + 1), y), x &amp;ge; 0, y &amp;ge; 0 &lt;br /&gt; &lt;br /&gt; A(4,3) = ?&lt;/div&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Данная функция есть &lt;a href="http://en.wikipedia.org/wiki/Ackermann_function"&gt;функция Аккермана&lt;/a&gt; - простой пример вычислимой функции, которая не является примитивно рекурсивной.&lt;br /&gt;&lt;br /&gt;&lt;div style="border:1px solid #000;padding:10px;text-align:center;height: 180px; background-color:white;text-align:center;"&gt;&lt;img src="http://lh4.ggpht.com/_0W-IrdaBLsY/S4elbMAcywI/AAAAAAAAE3U/9pcjJgu6V8c/Ackermann-complex.png" border="0" width="500" height="148"/&gt;&lt;br /&gt;F(z) = A(4, z)&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Попытки вычислить &lt;span class="b"&gt;A(4, 3)&lt;/span&gt; &lt;span class="i"&gt;в лоб&lt;/span&gt; обречены на провал (код на clojure):&lt;pre class="code"&gt;&lt;code class="lisp"&gt;(defn A([x y]&lt;br /&gt; (cond &lt;br /&gt;  (zero? x) 1&lt;br /&gt;  (and (= x 1) (zero? y)) 2&lt;br /&gt;  (and (&amp;gt;= x 2) (zero? y)) (+ x 2)&lt;br /&gt;  :else (recur (A (dec x) y) (dec y))&lt;br /&gt; )&lt;br /&gt;))&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Однако, на &lt;span class="i"&gt;erlang&lt;/span&gt; прямо в лоб решается запросто:&lt;pre class="code"&gt;&lt;code class="erlang"&gt;-module(ack).&lt;br /&gt;-export([a/2]).&lt;br /&gt;&lt;br /&gt;a(0,_) -&amp;gt; 1;&lt;br /&gt;a(1,0) -&amp;gt; 2; &lt;br /&gt;a(X,0) -&amp;gt; X+2;&lt;br /&gt;a(X,Y) -&amp;gt; a( a(X-1,Y), Y-1).&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;запускаем...&lt;br /&gt;&lt;pre class="code"&gt;&lt;code class="erlang"&gt;$ erl&lt;br /&gt;1&amp;gt; c(ack.erl).&lt;br /&gt;{ok,ack}&lt;br /&gt;2&amp;gt; ack:a(4,3).&lt;br /&gt;&lt;span class="i b"&gt;ответ скрыт&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Решить данную задачу на &lt;span class="i"&gt;clojure&lt;/span&gt; вполне реально - дерзайте!&lt;br /&gt;&lt;br /&gt;&lt;div style="float:left;border:1px solid #444;margin-right:10px;background-color:white;padding:10px;text-align:center;"&gt;&lt;img title="Tetrahedron" alt="Tetrahedron" src="http://projecteuler.net/images/levels/tetrahedron.gif"&gt;&lt;br /&gt;&lt;span class="b"&gt;Level 1&lt;/span&gt;&lt;/div&gt; &lt;span class="b"&gt;ps.&lt;/span&gt; Я тем временем заработал &lt;span class="b"&gt;Level 1&lt;/span&gt; на &lt;a href="http://projecteuler.net/index.php?section=problems"&gt;Project Euler&lt;/a&gt; - на мой взгляд, отличный способ прокачать навыки в функциональном программировании.&lt;div class='clear'&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8870493191508591473-8876539221358949363?l=dolzhenko.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/dolzhenko/~3/MNFanisQ1tA/a43.html</link><author>noreply@blogger.com (Vladimir Dolzhenko)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_0W-IrdaBLsY/S4elbMAcywI/AAAAAAAAE3U/9pcjJgu6V8c/s72-c/Ackermann-complex.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://dolzhenko.blogspot.com/2010/02/a43.html</feedburner:origLink></item></channel></rss>

