<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2714571064530517421</id><updated>2011-11-20T01:30:13.985-08:00</updated><category term='Tester expertize'/><title type='text'>On Software Development</title><subtitle type='html'>software development and management</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-5891083839810305920</id><published>2011-09-29T01:39:00.000-07:00</published><updated>2011-11-15T13:32:54.817-08:00</updated><title type='text'>C# ain`t too bad</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;C# ain`t too bad&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Nothing is really free in Microsoft`s world , but you can start by using the express editions of &lt;a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-csharp-express"&gt;Visual C# 2010&lt;/a&gt; and &lt;a href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-web-developer-express"&gt;Visual Web Developer 2010&lt;/a&gt; .&lt;br /&gt;It amazing how much better the (java) free eclipse IDE is compared to the free visual C# , but if you are willing to put few hundred $`s , The Ultimate version+Resharper should give eclipse a very good competition.&lt;br /&gt;&lt;br /&gt;Two notes:&lt;br /&gt;LINQ is absolutely brilliant.  It`s simply the best advancement in programming languages in the last 10 years.  I do hope java will get it soon.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nunit.org/index.php?p=download"&gt;NUnit&lt;/a&gt; is a great testing tool , especially with the new &lt;a href="http://www.nunit.org/index.php?p=attributes&amp;amp;r=2.5.10"&gt;attributes &lt;/a&gt;and &lt;a href="http://www.nunit.org/index.php?p=collectionConstraints&amp;amp;r=2.5.10"&gt;constraints&lt;/a&gt;&lt;br /&gt;But it does not integrate to VisualStudio Express (and Microsoft does not allow plugin/extensions to the epress edition)&lt;br /&gt;Don`t worry , just do:&lt;br /&gt;1. Add reference to NUnit in the project.  (Add reference -&amp;gt; .Net -&amp;gt; component name=NUnit frameworl&lt;br /&gt;2. Open the nunit-x86.exe (on windows7) , create a project and use "Add assembly" to target the relevant project dll/exe.&lt;br /&gt;3. Don`t run it manually, instead change the Program.cs to run it, instructions &lt;a href="http://nunit.net/blogs/?p=28"&gt;here&lt;/a&gt; . Note that you will need to add the nunit-gui-runner.dll from the NUnit ../bin/../lib directory&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-5891083839810305920?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/5891083839810305920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=5891083839810305920' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/5891083839810305920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/5891083839810305920'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2011/09/c-aint-too-bad.html' title='C# ain`t too bad'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-3867005745434016694</id><published>2011-05-11T12:26:00.000-07:00</published><updated>2011-10-06T02:30:17.441-07:00</updated><title type='text'>Principles</title><content type='html'>&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="line-height: 19px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;&lt;i&gt;&lt;b&gt;On requirements&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="line-height: 19px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;1. &lt;a href="http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it"&gt;You ain`t gonna need it&lt;/a&gt; - &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style=" line-height: 19px;  font-size:medium;" &gt;Always implement things when you actually need them, never when you just foresee that you need them.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; line-height: 19px;font-size:medium;" &gt;2. &lt;a href="http://www.blogger.com/MoSCoW%20Method"&gt;MoSCoW method&lt;/a&gt; (&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style=" line-height: 24px; "&gt;&lt;span style="font-weight: bold;"&gt;M&lt;/span&gt;ust &lt;span style="font-weight: bold;"&gt;S&lt;/span&gt;hould &lt;span style="font-weight: bold;"&gt;C&lt;/span&gt;ould &lt;span style="font-weight: bold;"&gt;W&lt;/span&gt;on`t)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style=" line-height: 19px;  font-size:medium;" &gt;All requirements are important, but they are prioritized to deliver the greatest and most immediate business benefits early. Developers will initially try to deliver all the M, S and C requirements but the S and C requirements will be the first to go if the delivery timescale looks threatened.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 19px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 19px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "&gt;&lt;span class="Apple-style-span"&gt;&lt;div style="line-height: normal; "&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;i&gt;On project scheduling&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="  ;font-size:medium;" &gt;1. &lt;a href="http://en.wikipedia.org/wiki/Brooks%27s_law"&gt;Brooks`s law&lt;/a&gt; -&lt;/span&gt;&lt;span class="Apple-style-span" style="  ;font-size:medium;" &gt; &lt;/span&gt;&lt;span class="Apple-style-span" style=" line-height: 19px;  font-size:medium;" &gt;adding manpower to a late software project makes it later. "Nine women can't make a baby in one month"&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style=" line-height: 19px;  font-size:medium;" &gt;2. &lt;a href="http://en.wikipedia.org/wiki/Parkinson%27s_Law"&gt;Parkinson`s Law&lt;/a&gt; - always time each task. &lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;  line-height: 19px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;  font-size:medium;" &gt;Work expands so as to fill the time available for its completion&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; "&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;div  style="border-collapse: separate; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;  font-size:medium;"&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style=" "&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 19px; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span" style=" "&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="line-height: 19px; "&gt;On &lt;/span&gt;Design&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;1. &lt;a href="http://en.wikipedia.org/wiki/Analysis_paralysis"&gt;Analysis paralysis&lt;/a&gt;  - &lt;/span&gt;&lt;span class="Apple-style-span" style=" line-height: 19px; "&gt;over-analyzing (or over-thinking) a situation, so that a decision or action is never taken, in effect paralyzing the outcome. A decision can be treated as over-complicated, with too many detailed options, so that a choice is never made, rather than try something and change if a major problem arises.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;2. &lt;a href="http://en.wikipedia.org/wiki/KISS_principle"&gt;KISS principle&lt;/a&gt;  - Keep it simple stupid.  The principle is best exemplified by the story of Johnson handing a team of design engineers a handful of tools, with the challenge that the jet aircraft they were designing must be repairable by an average mechanic in the field under combat conditions with only these tools. Hence, the 'stupid' refers to the relationship between the way things break and the sophistication available to fix them. &lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;.... &lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px; "&gt;It seems that perfection is reached not when there is nothing left to add, but when there is nothing left to take away&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style=" "&gt;3. &lt;a href="http://en.wikipedia.org/wiki/Rule_of_three_%28programming%29"&gt;Rule of three&lt;/a&gt;  ( not two as many think , three!) - &lt;/span&gt;&lt;span class="Apple-style-span" style=" "&gt;Rule of three is a code refactoring rule of thumb to decide when a replicated piece of code should be replaced by a new procedure. It states that you are allowed to copy and paste the code once, but that when the same code is replicated three times, it should be extracted into a new procedure.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: lucida grande;"&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-3867005745434016694?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/3867005745434016694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=3867005745434016694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3867005745434016694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3867005745434016694'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2011/05/priciples.html' title='Principles'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-810166357632768787</id><published>2011-04-29T08:20:00.001-07:00</published><updated>2011-06-16T12:51:46.938-07:00</updated><title type='text'>scala</title><content type='html'>AKKA http://days2010.scala-lang.org/node/138/162&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; color: rgb(51, 51, 51); font-family: 'trebuchet ms', verdana, arial, sans-serif; font-size: 13px; line-height: 18px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;Eclipse plugin for Eclise 3.4 is incredibility bad.&lt;br /&gt;Eclipse plugin for Eclipse 3.5.2 is &lt;a href="http://www.scala-ide.org/" style="font-weight: bold; color: rgb(51, 102, 204); "&gt;better&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;tutorials&lt;br /&gt;http://www.scala-lang.org/docu/files/ScalaTutorial.pdf&lt;br /&gt;http://www.scala-lang.org/docu/files/ScalaByExample.pdf&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/2714571064530517421-810166357632768787?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/810166357632768787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=810166357632768787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/810166357632768787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/810166357632768787'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2011/04/scala.html' title='scala'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-4305694068929452278</id><published>2010-09-23T03:04:00.000-07:00</published><updated>2011-10-06T02:27:06.493-07:00</updated><title type='text'>Postgres 9.0 hot-standby</title><content type='html'>&lt;div style="text-align: left;"&gt;Postgres 9.0 have a new feature "streaming-replication" + "warm-standby". In few words , it allow asynchronic replication between master and slave (there is a delay , but it is a small one) and the slave can do read-only queries.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://www.pgcon.org/2008/schedule/attachments/61_Synchronous%20Log%20Shipping%20Replication.pdf"&gt;synchronios replication&lt;/a&gt; is only planned for 9.1&lt;br /&gt;&lt;br /&gt;It`s a good time to recap the different sharding/master-slave options and their roles.&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;At first you develop the code for one DB instance and you assume three things about it:&lt;/div&gt;&lt;div&gt;1.  It will never fail - the machine,process and disks are eternal. &lt;/div&gt;&lt;div&gt;2.  data-scale: It can grow is size as much as you want - terra-bytes of disks space.&lt;br /&gt;3.  query(users) scale : The machine is as fast as you want - It can supports millions of fast queries in parallel.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;After  few months , you deploy it and then find out that these 3 things are  not so easy to achieve. Lets see what are the (Postgres) solutions for  them.&lt;/div&gt;&lt;br /&gt;&lt;div style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;&lt;u&gt;query-scale&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Scale-Up : Still one machine,  but buy the best one money can get - 8 cores,32GB  are relatively cheap.   But twice as strong machine will cost a lot more the twice the money.  If you need x2 or x4 , switch to scale-out.&lt;/li&gt;&lt;li&gt;Scale-Out :&lt;br /&gt;2.1  Scale reads not writes:  (good for mainly read DB)&lt;br /&gt;Use  one master server (read&amp;amp;write) and multiple read-only slave servers  which get periodically updated from the master server. The master and  slave share the same data.&lt;br /&gt;Postgres 9.0 supports it out-of-the-box&lt;br /&gt;2.2  Scale writes by &lt;a href="http://en.wikipedia.org/wiki/Shard_%28database_architecture%29"&gt;shardin&lt;span style="font-style: italic;"&gt;g&lt;/span&gt; &lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;&lt;u&gt;Fault-tolerance&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;For  transaction-DB where no record can be lost , this is a hard task.  For  data-warehouse which may loose the latest few minutes of updates , this  is much simpler.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; No data loss:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Shared-disks  :  the master writes to a shared storage. When it fails the slave mount  it and loads the data.  It is a "code-standby" as it can takes few  minutes to recover.&lt;/li&gt;&lt;li&gt;pgpool II - slows the updates on the master!&lt;/li&gt;&lt;li&gt;synchronios  log shipping (should be in postgres 9.1) - does not (considerably) slow  the master. Failover take 15 seconds (10 to detect failure , 5 to start  the warm-standby)&lt;/li&gt;&lt;/ol&gt; Some data loss allowed:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Postgres 9.0 warm-standy &amp;amp; streaming-replication&lt;/li&gt;&lt;li&gt;Slony-1 updates the slave using triggers&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Data scale&lt;/u&gt;&lt;/div&gt;&lt;div&gt;Start with more disks on the machine , then scale-out with sharding.&lt;/div&gt;&lt;div&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;&lt;div&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;img src="http://1.bp.blogspot.com/_9ZVz7LkV0As/TJtEkROmGPI/AAAAAAAAABU/z_rtdDO9IKQ/s400/compare-db.png" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 600px; height: 174px;" alt="" id="BLOGGER_PHOTO_ID_5520081158163273970" border="0" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&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/2714571064530517421-4305694068929452278?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/4305694068929452278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=4305694068929452278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/4305694068929452278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/4305694068929452278'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2010/09/postgres-90-hot-standby.html' title='Postgres 9.0 hot-standby'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_9ZVz7LkV0As/TJtEkROmGPI/AAAAAAAAABU/z_rtdDO9IKQ/s72-c/compare-db.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-970537311640407622</id><published>2010-07-13T00:27:00.000-07:00</published><updated>2010-07-22T10:11:15.557-07:00</updated><title type='text'>Axis2 RPC client perfromance</title><content type='html'>&lt;span style="font-family: arial;"&gt;The client time is consisted of few parts:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;* Open TCP connection to the server  (send sync, recieve syn/ack , send ack = 1 round trip)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;* Send/Recieve WS xml (send at least one packaget , recieve at least one back  = at least 1 round trip)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Let`s eliminate the TCP connection time.  My ping to the server is 222 ms. The server calculation time is small (less than 15ms). So one round-trip = ~235.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The goal is to reduce each WS call to one round-trip.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;1.  Use high HTTP1.1  keepAlive value:&lt;br /&gt;Pro : reduce the tcp-connection round-trip&lt;br /&gt;Cons:  Load-balancing based on IP will not function as intended , as after first connection the client will keep using the same host over and over.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: arial;"&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Make sure HTTP1.1 keepAlive is turned on on both client and server.&lt;br /&gt;Tomcat HTTP1.1 keepAlive is turned on by default  ( you can shut it off  in server.xml , Connector section , by adding  maxKeepAliveRequests="1".   [default is no parameter at all and means  100 requests )&lt;br /&gt;Turning it off will cause 2 round-trips - [first=626]  then 457, 455 , 458 , ...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Keep the connection alive by using it more frequently than the timeout.&lt;br /&gt;The default &lt;code&gt;keepAliveTimeout&lt;/code&gt; in Tomcat 6.0.18 is equals to &lt;code&gt;connectionTimeout&lt;/code&gt; which is typically 20000ms=20 seconds.&lt;br /&gt;It means that the TCP connection  will stay alive only if it is used more frequently than this.&lt;br /&gt;You can configure the tomcat to higher value (120seconds for example) in the server.xml, Connector section.&lt;br /&gt;Note: adding the parameter &lt;code&gt;keepAliveTimeout&lt;/code&gt;&lt;code&gt;="500000"&lt;/code&gt; alone is not enough for tomcat6.0.18 ,&lt;a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=46666"&gt;cause of this bug&lt;/a&gt;. you will need to add &lt;code&gt;disableUploadTimeout="false" &lt;/code&gt;&lt;code&gt;keepAliveTimeout&lt;/code&gt;&lt;code&gt;="500000" &lt;/code&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-family: arial;font-size:100%;" &gt;2. If your&lt;/span&gt;&lt;span style="font-family: arial;"&gt; data is more than few bytes, compress it to save transfer time.   You need to configure both the server and the client to support compression.&lt;/span&gt;&lt;br /&gt;&lt;ul style="font-family: arial;"&gt;&lt;li&gt;Client - GZIP options&lt;br /&gt;options.setProperty(HTTPConstants.MC_ACCEPT_GZIP ,true);&lt;br /&gt;&lt;br /&gt;[note A. if you configure HTTPConstants.MC_GZIP_REQUEST , the request itself will be compressed . will work fine for a server which support gzip. will fail on other-servers.&lt;br /&gt;If you requests are not huge , not worth the risk! ]&lt;br /&gt;[note B. this option can cause you problems if you have LB which is problematic with chunking :options.setProperty(HTTPConstants.CHUNKED,Boolean.TRUE ) ]&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sever: on apache6.0.18 configure on server.xml, Connector . Add: compression="on" , which means try to use compression depending on the client.&lt;br /&gt;Firefox 3.6.6 by default will not get it compressed, nor a WS client without GZIP options, but our optimized client will use it.&lt;/li&gt;&lt;li&gt;Note: this configuration should work with/without compression on both the client and the server side and should be "backward compatible".  Transfer time can be considerably reduced (in my case 500ms on 6KB to 260ms  on 1KB)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: arial;"&gt;         3. TCP connection optimization&lt;/span&gt;&lt;br /&gt;&lt;ul style="font-family: arial;"&gt;&lt;li&gt;TCP implementation increase the buffer size , sending more and more bytes per second , as long as the connection is not congested , so after a second or two , you will reach the optimal size.   But , on high-latency, high-bandwidth connections (100MB/s , 50ms latency)  the OS max tcp-buff limit the max throughput and can reduce by a factor of 2-10.&lt;br /&gt;A good max value should be:  round-trip[ping]* bandwidth .&lt;br /&gt;If this is your use case (like connection between data-centers) , &lt;a href="http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html"&gt;tune the system.&lt;br /&gt;&lt;/a&gt;example  = 100Mb/s = 12.5MB/s  . ping 100ms --&gt;  12.5MB/s*0.1s= 1.25MB.  the default on UNIX is 256KB , so you can get a boost of x5.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you are not using a persistent TCP connection , and the round-trip is large , for small files it will take few round-trips to get to optimal speed (and by then the file already finished). If this is your case, set the Socket receive/send buffer to high value immediately.&lt;/li&gt;&lt;li&gt;For low-latency , small-transmittion , also use Socket.setTcpNoDelay which disable &lt;a href="http://en.wikipedia.org/wiki/Nagle%27s_algorithm"&gt;Nagle`s algoritm&lt;/a&gt;.  Wikipedia quote:&lt;br /&gt;&lt;span style="font-style: italic;font-size:100%;" &gt;Nagle's algorithm works by combining a number of small outgoing  messages, and sending them all at once. Specifically, as long as there  is a sent packet for which the sender has received no acknowledgment,  the sender should keep buffering its output until it has a full packet's  worth of output, so that output can be sent all at once.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;P.S.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;1. The default Axis2 RPC Client do not use a pool of HTTP connectors. This default implementation is good only for tests and will cause problems in productions , follow the instruction &lt;/span&gt;&lt;a style="font-family: arial;" href="http://ws.apache.org/axis2/1_5_1/http-transport.html"&gt;here&lt;/a&gt;&lt;span style="font-family: arial;"&gt; and use MultiThreadedHttpConnectionManager.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;2.  To see TCP connection do (linux) "netstat -nap | grep &lt;/span&gt;&lt;server-ip style="font-family: arial;"&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;/server-ip&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-970537311640407622?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/970537311640407622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=970537311640407622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/970537311640407622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/970537311640407622'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2010/07/axis2-rpc-client-perfromance.html' title='Axis2 RPC client perfromance'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8077756767531926012</id><published>2010-03-26T06:58:00.001-07:00</published><updated>2010-03-28T13:37:02.379-07:00</updated><title type='text'>RAID and SSD</title><content type='html'>I really need a new desktop machine. The current dilemma is between large,cheap mechanical HD or small, costly, SSD. &lt;br /&gt;The second question is "to raid" or not "to raid".&lt;br /&gt;&lt;br /&gt;Solid-state-device VS mechanical disks:&lt;br /&gt;Typical windows usage &lt;a href="http://www.tomshardware.com/reviews/windows-ssd-performance,2518.html"&gt;is faster&lt;/a&gt; with SSD.  Question remains, is there a &lt;a href="http://ssd-reviews.com/index.php?s=6"&gt;good&amp;amp;cheap&lt;/a&gt; drive. The new generation from SanDisk (g3) claims the following &lt;a href="http://www.tomshardware.com/news/sandisk-g3-ssd-extremeffs-trim,9738.html"&gt;numbers&lt;/a&gt;:&lt;br /&gt;Average sequential (higher is better) and Random-access  latency(smaller is better)&lt;br /&gt;Read- 220MB/s ,write 120MB/s . 0.1-0.2 ms latency. cost: for 60,120GB for 229$,399$  &lt;br /&gt;&lt;br /&gt;Mechanical disks: Some &lt;a href="http://www.tomshardware.com/charts/3.5-hard-drive-charts/Windows-XP-Startup-Performance,673.html"&gt;numbers:&lt;/a&gt;&lt;br /&gt;VelociRaptor VR150          ,10,000 rpm, 300GB                         102MB/s  , 7ms  - ~200$&lt;br /&gt;Segate Baddacuda &lt;span&gt;ST3320613AS&lt;/span&gt; , 7200 rpm , 230GB  - 99.2MB/s ,17.1ms   - 50$&lt;br /&gt;&lt;br /&gt;Conclusion: SSD is worth the money&lt;br /&gt;&lt;br /&gt;Raid&lt;br /&gt;There are two goals for Raid.  One is performance , Second is fault-tolerance.   For a desktop owner the first tends to be the only relevant goal.  Let`s assume you have a budget of up to 2 HD`s.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/RAID_0#RAID_0"&gt;Raid 0&lt;/a&gt; - two striped disks. If a file contains 4 sections , disk one contains 1,3 . The other 2,4. &lt;br /&gt;on mechanical/ssd disks:   &lt;a href="http://www.tomshardware.com/charts/raid-matrix-charts/Average-Read-Transfer-Performance,218.html"&gt;x2 sequential-read&lt;/a&gt;  , &lt;a href="http://www.tomshardware.com/charts/raid-matrix-charts/Random-Access-Time,227.html"&gt;x0.9 random-read&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;P.S. What does the SATA150/SATA300 Interface means?&lt;br /&gt;This is the BUS  speed.  SATA150 supports up to 150MB/s  . SATA300 (or SATA-II) supports  up to 300MB/s.&lt;br /&gt;Make sure that the SATA interface max throughput &gt;  HD max throughput .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8077756767531926012?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8077756767531926012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8077756767531926012' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8077756767531926012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8077756767531926012'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2010/03/raid-and-ssd.html' title='RAID and SSD'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-2783245330938075166</id><published>2009-12-28T10:37:00.000-08:00</published><updated>2010-01-08T00:52:10.597-08:00</updated><title type='text'>Why small objects cloud hosting is so slow? Amazon S3 and SimpleDB performance</title><content type='html'>Is it possible to use S3 as a scalable storage for small objects?&lt;br /&gt;&lt;br /&gt;S3 is perfect for large objects (1GB file) but is quite bad for small objects like those a media-server needs (songs,images).&lt;br /&gt;Behind the scenes S3 uses standard disks with varying levels of replication and striping.  Standard disks have poor random-access, but a good sequential throughput.&lt;br /&gt;Each object has a minimal access time, caused by the disk seek time.see &lt;a href="http://www.linuxinsight.com/how_fast_is_your_disk.html"&gt;disk throughput and seek-time .&lt;/a&gt;&lt;br /&gt;The real solution for small files is either caching the most-accessed in-memory  (done by most of the Content-delivery-networks like CloudFront).&lt;br /&gt;If you want to retrieve thousands of small-objects per second and not use a cache, then the only way to do it fast is to spread them across as many physical disks as possible.  The number of disks does grows linearly with large files, as few files take a whole disk.&lt;br /&gt;But with small files, the number of disks grows very slowly  (500GB contains thousands of images) which may all sit in one machine.  That`s why S3 is not appropriate for small files.&lt;br /&gt;see &lt;a href="http://www.scribd.com/doc/12925792/HostedFTPcom-Amazon-S3-Performance-Report"&gt;read-performance of S3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For a real fast , cost-effective, random-access of small files the only solution will be different hardware: Solid-state disks.   They are becoming cheaper every year and their random access speed is close to sequential performance.&lt;br /&gt;Why there is no CDN with this solution yet?  Because caching of the most-access is enough for the typical website. The access pattern of most users is not really random. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;img src="http://www.blogger.com/img/blank.gif" alt="Link" class="gl_link" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-2783245330938075166?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/2783245330938075166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=2783245330938075166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2783245330938075166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2783245330938075166'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/12/why-small-objects-cloud-hosting-is-so.html' title='Why small objects cloud hosting is so slow? Amazon S3 and SimpleDB performance'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-1794455189707171775</id><published>2009-11-24T12:20:00.000-08:00</published><updated>2009-11-24T12:23:59.234-08:00</updated><title type='text'>Command&amp;Conquer managment approach</title><content type='html'>Great &lt;a href="http://www.joelonsoftware.com/articles/TwoStories.html"&gt;two&lt;/a&gt; &lt;a href="http://www.joelonsoftware.com/articles/fog0000000072.html"&gt;articles&lt;/a&gt; . A must read to anyone who manage anything more then himself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-1794455189707171775?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/1794455189707171775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=1794455189707171775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1794455189707171775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1794455189707171775'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/11/command-managment-approach.html' title='Command&amp;Conquer managment approach'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-2425863644887613470</id><published>2009-07-24T06:37:00.000-07:00</published><updated>2009-07-24T06:51:07.417-07:00</updated><title type='text'>Flex visualization libraries</title><content type='html'>multiple layouts : http://labs.kapit.fr/label/diagrammer&lt;br /&gt;Spring based map:     http://mark-shepherd.com/blog/springgraph-flex-component/&lt;br /&gt;Facebook integration:   http://www.adobe.com/devnet/facebook/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-2425863644887613470?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/2425863644887613470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=2425863644887613470' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2425863644887613470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2425863644887613470'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/07/flex-visualization-libraries.html' title='Flex visualization libraries'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8401556978253411434</id><published>2009-06-12T06:17:00.000-07:00</published><updated>2009-06-12T06:22:08.892-07:00</updated><title type='text'>Java update 6.14 and compressed Oops</title><content type='html'>From the release notes:&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;a name="hotspot14.0-G1-6u14"&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Compressed Object Pointers&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="font-style: italic;"&gt;The &lt;/span&gt;&lt;code style="font-style: italic;"&gt;-XX:+UseCompressedOops&lt;/code&gt;&lt;span style="font-style: italic;"&gt; option can improve performance of the 64-bit JRE  when the Java object heap is less than 32 gigabytes in size.  In this case, HotSpot compresses object references to 32 bits, reducing the amount of data that it must process. &lt;/span&gt;&lt;br /&gt;&lt;a name="hotspot14.0-G1-6u14"&gt;&lt;span style="font-style: italic;"&gt; (from: http://java.sun.com/javase/6/webnotes/6u14.html)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This gives a huge boost for memory-intensive applications.&lt;br /&gt;Take for example an application which heavily uses tree-maps.&lt;br /&gt;Tree element:  pointer to next  + pointer to previos + pointer to key + pointer to value (+ some housekeeping bytes).&lt;br /&gt;4 x64 bit pointers which can become 32 bits now. &lt;br /&gt;&lt;br /&gt;It won`t reduce the memory footprint to half , but it can give you an incredible boost.  so ... (-XX:+) UseCompressedOoops.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8401556978253411434?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8401556978253411434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8401556978253411434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8401556978253411434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8401556978253411434'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/06/java-update-614-and-compressed-oops.html' title='Java update 6.14 and compressed Oops'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-6588326249301026620</id><published>2009-04-30T12:34:00.000-07:00</published><updated>2009-05-03T14:17:55.164-07:00</updated><title type='text'>Fighting bytes - 64bit Lean hashmaps</title><content type='html'>Lets say you need to implement a 375,000,000 (more than 3/8 GB) key-value mapping &lt;span style="font-style: italic; font-weight: bold;"&gt;in live memory&lt;/span&gt;.&lt;br /&gt;The good: It is integer based and you have a 40GB RAM machine.&lt;br /&gt;The bad:   It is a multi-map : integer to multiple integer mapping.&lt;br /&gt;&lt;br /&gt;Lets start with the trivial solution:&lt;br /&gt;First of all, as we use 40GB , we need a 64bit java implementation.&lt;br /&gt;Lets use hashmap where key=Integer , value= LinkedList of Integers.&lt;br /&gt;HashMap cost (64bit) = aroud 60 bytes per entry.&lt;br /&gt;Integer cost(64 bit) = 24 byte. remeber we need one in key and at least one in value.&lt;br /&gt;LinkedList(64bit) = starts with ~80byes , ~40 more per entry.&lt;br /&gt;&lt;br /&gt;For fast calculation, lets assume one Integer in key and one in value.&lt;br /&gt;We get N*(60+24+24+120) = N*228 = 85.5GB.   Way above what we have - the 40GB include the linux , some GC room and few other applications.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;But The real max we can have per entry is 100bytes (which will get us to 37.5GB)&lt;/span&gt;&lt;br /&gt;So , what to do?&lt;br /&gt;We must reduce the multi-map cost (LinkedList is a big waste). We can also reduce the Map implementation.&lt;br /&gt;&lt;br /&gt;Lets start with the hashmap for a minute.&lt;br /&gt;It mainly consists of an Entry[]   = N*pointer_size&lt;br /&gt;and each entry is a hash value(integer) and three pointer(to key,to value, to next-entry) = 16(minimal-per-java-object)+4bytes+3*pointer_size = (64bit machines) 48.&lt;br /&gt;For a total of:  N*56.&lt;br /&gt;As the size of Entry[] is typically more than than the current size(load-factor ~0.75) , it will even be bigger.&lt;br /&gt;&lt;br /&gt;Use of open-addressing , can reduce the size (although there are certain other issues):&lt;br /&gt;N keys&lt;br /&gt;N values&lt;br /&gt;no need for hash(performance by caching), no need for next-entry.&lt;br /&gt;This can reduce the size by 4+8=12 ,  for a total of N*44. Drawback is that load-factor need to decrease.&lt;br /&gt;&lt;br /&gt;Other optimizations:&lt;br /&gt;if key/value are primitives , save a lof of space by using the value instead a pointer and a heap-allocated value.&lt;br /&gt;Integer as a key costs a pointer + 24 byte  (if integers are not object-pooled)&lt;br /&gt;int as a key(in a specialy designed map) only cost 4 byte!!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;array based - http://members.optusnet.com.au/~askitisn/CRPITV91Askitis.pdf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This post (http://stackoverflow.com/questions/629804/what-is-the-most-efficient-java-collections-library) gives a list of few customized hash implementation with up to 1/3 the java.util size.&lt;br /&gt;&lt;br /&gt;In particular &lt;a href="http://trove4j.sourceforge.net/javadocs/"&gt;Trove&lt;/a&gt; supplies TIntIntHash for int to int hashin TIntObjectHash and TIntArrayList which can be used for (half) efficent integer based multi-maps.&lt;br /&gt;It does not supports out-of-the-box multimaps.&lt;br /&gt;I`m pretty sure it will take me under the 100 bytes threshold. If not, the only other options is to implement a custom int to multi-int hash table, using open-addresing. I hope I won`t get to that (re-inventing wheels is not my cup of tea)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-6588326249301026620?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/6588326249301026620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=6588326249301026620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6588326249301026620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6588326249301026620'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/04/fighting-bytes-64bit-lean-hashmaps.html' title='Fighting bytes - 64bit Lean hashmaps'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8142706717736679101</id><published>2009-04-24T05:03:00.000-07:00</published><updated>2009-04-24T05:07:59.306-07:00</updated><title type='text'>Nice .... Google App Engine support java</title><content type='html'>Good new: http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html&lt;br /&gt;Good news for java web-developers . Sad news for the java cloud-based startups...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Going to port the python app to java. Yes, it will take 10 classes where in python it was 100 rows , but ....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8142706717736679101?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8142706717736679101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8142706717736679101' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8142706717736679101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8142706717736679101'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/04/nice-google-app-engine-support-java.html' title='Nice .... Google App Engine support java'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-3750948611060449129</id><published>2009-03-26T13:46:00.000-07:00</published><updated>2009-03-26T13:59:45.229-07:00</updated><title type='text'>Automation</title><content type='html'>1. Deployment automation&lt;br /&gt;2. Test automation&lt;br /&gt;&lt;br /&gt;Automatic deployment and automatic tests are the developer`s best friend. &lt;br /&gt;An application development has three stages: Development , Debugging and Maintanance.&lt;br /&gt;In the first stage you have a lot of time to spare. In the secod you have less and in the third you have none.&lt;br /&gt;&lt;br /&gt;Automatic test and deployment save you time and bugs on the 2nd and 3rd stage , when you really need them ( need to fix the bug and redeploy by noon tommorow morning otherwise your very important customer will drop you , and just now your QA is on vacation and your IT guy is on sick day ).&lt;br /&gt;But automation takes time to develop. It will elongate your development time (usually by mere few days) and automation may not be the coolest feature to develop (usually its pretty boring) ... you understand where it is going...&lt;br /&gt;&lt;br /&gt;When you are at maintanance mode and suffers greatly from the wasted time on the manual testing/deployment and you understands the need for this , you simply do not have time to spare on building it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Conclusion: Think ahead , in the development period , if the feature can benfit from automation down the line. If so , add the required days to the (middle) of the development period -  you will thanks yourself later for doing so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-3750948611060449129?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/3750948611060449129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=3750948611060449129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3750948611060449129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3750948611060449129'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/03/automation.html' title='Automation'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-2673736143736188707</id><published>2009-03-14T15:31:00.000-07:00</published><updated>2009-03-14T15:42:10.075-07:00</updated><title type='text'>Google App Engine</title><content type='html'>Prediction:&lt;br /&gt;Google App engine (or its copycats) will be the only way to develop web applications in the following years.&lt;br /&gt;They have everything exactly right except the programming language.  Note to google:  the average industry developer does not know Python. In fact if he knew Python, he would have  probably already been recruited as a  Google employee...   So your runtime environemnt is not usuable to us , the common programmers. &lt;br /&gt;&lt;br /&gt;When(and if) they  implement  PHP , Java (and maybe even ASP) runtimes , this project will become te industry leader and will kill all the data-stores(including Amazons) and half of the IT guys in the world.&lt;br /&gt;&lt;br /&gt;If they will be smart enough, it can even create a standard web-development kit , as long as it is not Python based!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-2673736143736188707?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/2673736143736188707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=2673736143736188707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2673736143736188707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2673736143736188707'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/03/google-app-engine.html' title='Google App Engine'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-1934835755641699202</id><published>2009-03-14T14:06:00.000-07:00</published><updated>2009-03-22T13:21:58.746-07:00</updated><title type='text'>Outsourcing</title><content type='html'>In the current state of the economy, outsourcing become more popular every day.&lt;br /&gt;Recruiting new workers is tough . Recruiting new workers from outsourcing is even tougher.&lt;br /&gt;&lt;br /&gt;I'm doing a grouse generalization here and I apologize for it in advance for this  observation:&lt;br /&gt;Outsourcing workers can be divided to two groups:&lt;br /&gt;The first group is extremely talented and experienced men who understands they can do a lot more money as outsourced-consultants than as regular workers.&lt;br /&gt;The second group is of the "refugees" - the less talented/experienced men which could not find a regular job as company employee and turned to outsourcing companies as a last resort&lt;br /&gt;&lt;br /&gt;The outsourcing H.R. will always tell you their workers are excellent for the job. So how can you distinguish between the extremely talented and the less-than-averages ones?&lt;br /&gt;One way is to have a good technical interview, but as you usually outsource the field in which your group do not have the technology expertise , it will be hard for you to really  estimate the interview results.&lt;br /&gt;A second way is quite simple. The expert will demand a salary which is usually more than twice the salary of a regular employee whereas the refugee will usually ask for a salary similar or even less than a regular employee.  So if the man you are interviewing wants a lot of money , there is a good chance he is the real deal.  If he is cheap , there is a good chance he is not worth a penny.&lt;br /&gt;&lt;br /&gt;I'm not saying anyone who demands lots of money is immediately good and that anyone who demands less is immediately bad , but pay attention to that...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-1934835755641699202?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/1934835755641699202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=1934835755641699202' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1934835755641699202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1934835755641699202'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/03/outsourcing.html' title='Outsourcing'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-3728799222598749059</id><published>2009-03-14T13:58:00.000-07:00</published><updated>2009-03-14T14:06:42.201-07:00</updated><title type='text'>Another Gem from Joel</title><content type='html'>Joel is truly a genius.   As I`m "maturing" in work experience , I see more and more how true his observations are.&lt;br /&gt;&lt;br /&gt;Joel is has written a great post on &lt;a href="http://joelonsoftware.com/items/2009/03/09.html"&gt;"How to be a Product Manager"&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;And a remark of few other great ones:&lt;br /&gt;1. &lt;a href="http://joelonsoftware.com/articles/fog0000000356.html"&gt;UI&lt;/a&gt; - Never show a UI-screen to an "outsider" before it is fully polished.&lt;br /&gt;2. &lt;a href="http://joelonsoftware.com/articles/LeakyAbstractions.html"&gt;The law of leaky Abstrsctions&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-3728799222598749059?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/3728799222598749059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=3728799222598749059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3728799222598749059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/3728799222598749059'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/03/another-gem-from-joel.html' title='Another Gem from Joel'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8691283697682471860</id><published>2009-01-24T08:56:00.000-08:00</published><updated>2009-01-24T09:03:25.428-08:00</updated><title type='text'>Running a web-server from home</title><content type='html'>So , you want to run a web-server from home (why? , for testing purposes, of course! , don`t deploy anything on home server. Your ISP will eventually block you...)&lt;br /&gt;&lt;br /&gt;Behind a router:&lt;br /&gt;1. Change tomcat back to port-80.&lt;br /&gt;2. Assign a LAN static-ip  to the web-server on the LAN.&lt;br /&gt;3. configure your router to do port-forwarding on port 80 to your static-ip.&lt;br /&gt;4. Use a dynamic-dns to map a domain into your ever-changing ISP provided ip address.&lt;br /&gt;And you are ready to go.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Few resources:&lt;br /&gt;&lt;a href="http://homepage.mac.com/car1son/static_port_fwd_externalip.html"&gt;Good ref (for MAC) &lt;/a&gt;&lt;br /&gt;http://www.canyouseeme.org/   - external site which tests your open ports.&lt;br /&gt;http://www.no-ip.com/                - dynamic-DNS (with free version for non-commercial usage)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8691283697682471860?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8691283697682471860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8691283697682471860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8691283697682471860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8691283697682471860'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/01/running-web-server-from-home.html' title='Running a web-server from home'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8342603564181426349</id><published>2009-01-15T12:43:00.000-08:00</published><updated>2009-01-24T08:56:04.420-08:00</updated><title type='text'>Web Servers</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;web-servers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Lots of buzz words are flying around when talking about web-servers. I assume you know what it is , and just want to find which of the free/commercial servers will better suit your need:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;web-servers For PHP/CGI/Pyton (etc) developers&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;1.  &lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Apache_server"&gt;Apache HTTP server&lt;/a&gt;  [ = HTTPd]- a C-based implementation of a web-server for which you can use modules with the well-known "script" languages: PHP , Perl , Pyton , Ruby.&lt;br /&gt;2. &lt;a href="http://wiki.codemongers.com/Main"&gt;NginX &lt;/a&gt;- 2nd generation server (faster,less known)A C-based implementation of web-server which allow you to use again the "Script" langugs. This is a rather new server with better io utilization which should outperforme the Apahce HTTP server.&lt;br /&gt;3. &lt;a href="http://en.wikipedia.org/wiki/Lighttpd"&gt;Lighttpd &lt;/a&gt;- another 2nd generation server, less table than NginX.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;web-servers For Java developers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://en.wikipedia.org/wiki/Apache_Tomcat"&gt;Apache Tomcat&lt;/a&gt;  - a JAva-based implementation of web-server for which you can write modules in Java (plain java servlets or JSP).  The internal modules which support the servlets are called "catelina" and the JSP is called "jasper" , but these names are only important for knowning which log file to look.   It is not related to the popular Apache-c-based-Http-server.  ( they share the "Apache" prefix cause they come from the same open-source organization , but there are dozens of Apache projects which are not technology related to one another)&lt;br /&gt;2. &lt;span style="font-weight: bold;"&gt;Jetty &lt;/span&gt;- a small webserver , usually used for web-applications which run on a very small scale ( some application need only to work only on the localhost , and Jetty is a good solution for them)&lt;br /&gt;3.  JRun&lt;br /&gt;4. Resin&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;font-size:130%;" &gt;web-server for ASP.NET&lt;/span&gt;&lt;br /&gt;Here, like in many microsoft applications, you have one and only one choice: IIS&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;Simple so far? lets make it bit more complex - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Interconnections!!!!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;On some sites, one web-server gets the original request and forward it to another web-server. Few milliseconds later , it gets the response and send it to the user.&lt;br /&gt;In this setups it is possible that the "gateway" web-server will be a c-based one , and the other is java-based one. They will connect to each other in a different protocol (its a waste to use HTTP between two servers) .&lt;br /&gt;For apache-http-server(c-based) to Apache-Tomcat(java-based) , the connector is using the AJP protocol. see &lt;span style="font-size:100%;"&gt;The Apache Tomcat Connector - AJP Protocol Reference&lt;/span&gt;&lt;br /&gt;http://tomcat.apache.org/connectors-doc/generic_howto/workers.html&lt;br /&gt;&lt;br /&gt;&lt;span id="intelliTxt"&gt;Why using interconnections?&lt;br /&gt;usually when the Apache(c-based)  is the load-balancer and the Tomcat`s really to the dynamic-http generation.&lt;br /&gt;Note that it is possible to run a web-app (pure java) of a load balancer on tomcat , but it (by rumers) does not get close to the Apache(c-based) performance at load balancing.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Performance&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;Benchmarks&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Between different web-server "languages"&lt;/span&gt;&lt;br /&gt;It will be intersting to see which web server flavor (c-based, java-based or IIS) performs better in similiar tasks of static pages and similiar dynamic pages.  Didn`t find a good comparison , but iI do do not see anyone chaning the implementation languge of his company site just because the other langugle web-server performance is better.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Inside java web-server&lt;/span&gt;&lt;br /&gt;http://www.webperformanceinc.com/library/reports/ServletReport/index.html - bottom line is that Tomcat and Resin are close. 1000 concurrent users per second  (when some have short sessions , some medium and some large -yes , it does not say much about the numbers in your site)&lt;br /&gt;http://tomcat.apache.org/articles/performance.pdf&lt;br /&gt;http://tomcat.apache.org/articles/benchmark_summary.pdf - static files (Tomcat VS apache-C-based-server)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;It`s hard to find reliable benchmark between all the web-server matrix.  (There should be a "Tom`s Hardware" type of benchmark for web-servers)&lt;br /&gt;That`s said , the actual server choices which are seem to be recommended.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Choose dynamic web-server , according to the language you are familiar with. If you use Java , the free Apache Tomcat should be great. &lt;/li&gt;&lt;li&gt;If you are not going to have a lot of static pages/images or load-balancing , you can use Tomcat for all the rest too. &lt;/li&gt;&lt;li&gt;Otherwise , Choose "static " web-server as one of the 2nd generation C-based servers. NginX is a good choice. Its probably better than the java based servers.  You can also use its load balancing capability.&lt;/li&gt;&lt;/ul&gt;Final notes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Look at the feature matrix of the servers you use. If you need advanced features (load balancing , proxing etc ) , your choice will be easier because the number of servers will be more limited.&lt;/li&gt;&lt;li&gt;Remeber to look for the bottlenecks: dynamic web-server usually uses a Database which tend to be the bottleneck. Static web-server bottleneck tend to be the bandwidth itself.&lt;/li&gt;&lt;/ul&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;br /&gt;&lt;br /&gt;&lt;h1 id="firstHeading" class="firstHeading"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h1&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8342603564181426349?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8342603564181426349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8342603564181426349' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8342603564181426349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8342603564181426349'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2009/01/web-servers.html' title='Web Servers'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-6694554122880548204</id><published>2008-10-26T18:04:00.000-07:00</published><updated>2008-10-26T18:08:45.390-07:00</updated><title type='text'>Joel on software</title><content type='html'>If you did not read his blog, you need to.  (&lt;a href="http://joelonsoftware.com"&gt;http://joelonsoftware.com&lt;/a&gt;)&lt;br /&gt;He is one of the best writers on software development , and my favorite blogger.&lt;br /&gt;&lt;br /&gt;Not all the posts are on software managment. The best software blogs , are from few years back. I gurantee it is worth your time to go to his archieve and look at it.&lt;br /&gt;&lt;br /&gt;A great recent pearl on standard API: &lt;a href="http://www.joelonsoftware.com/items/2008/03/17.html"&gt;martian headsets&lt;/a&gt; &lt;br /&gt;enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-6694554122880548204?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/6694554122880548204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=6694554122880548204' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6694554122880548204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6694554122880548204'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/joel-on-software.html' title='Joel on software'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-897757927724116684</id><published>2008-10-26T17:57:00.000-07:00</published><updated>2008-10-26T18:03:59.275-07:00</updated><title type='text'>coding and testing pipeline</title><content type='html'>This is one good Agile/Scrum concepts which is rarely used in most of the teams. I recommend using it even if your working "waterfall".&lt;br /&gt;&lt;br /&gt;Instead of releasing the full feature set for testing on beta /hand-over-to-test day, you need to have small releases , each one both &lt;span style="font-weight: bold;"&gt;stable&lt;/span&gt; and has additional testable feature.&lt;br /&gt;Benefits:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;This will allow the test team to start testing even before the regular date (more time to test means more bugs are found) &lt;/li&gt;&lt;li&gt;reduce the instability of the version , which save time for both developers and QA.&lt;/li&gt;&lt;li&gt;Allow faster feedback on bugs for the developers.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;There should be be multiple releases in each version. Don`t go to far and release one each week (remember that it has an overhead which can never reduced to zero, no matter what the "Agile" methodology says).&lt;br /&gt;I believe a once-in-month period is sufficent , for a 3 months-version perioid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-897757927724116684?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/897757927724116684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=897757927724116684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/897757927724116684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/897757927724116684'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/coding-and-testing-pipeline.html' title='coding and testing pipeline'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-782970511308920909</id><published>2008-10-26T17:47:00.000-07:00</published><updated>2008-10-26T17:57:18.358-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tester expertize'/><title type='text'>Tester expertize</title><content type='html'>For each new feature , make sure the QA (quality assurance) team gets all the info/training material as the developer does.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;If the tester learns what to test from the original developer , the testing level will be very poor , and will only verify that what the developer already knows.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;Anecdote regarding this:&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;On of my first jobs, I was responsible of an old feature which someone else (which is long gone) wrote. The tester did not know the feature and asked me , the responsible developer , what does this feature do.&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;After asking around and understanding that no one around knew this feature, I had to dwell into the code and describe what the code does.&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;The tester happily wrote it down and then went back to his office and started testing it.&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;Anyone see`s the problem here?&lt;/p&gt;&lt;p style="font-style: italic;" class="MsoNormal"&gt;The tester tested my understanding of the code and not what the feature should do. He found a bug and showed it to me. I then realized I failed to read what the code does in a corner case. Both he and I did not know whether the actual code behavior was ok or not , and we ended up telling that I was wrong understaning the code , not that the code has a bug.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-782970511308920909?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/782970511308920909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=782970511308920909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/782970511308920909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/782970511308920909'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/tester-expertize.html' title='Tester expertize'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-5044223377169444149</id><published>2008-10-26T17:11:00.000-07:00</published><updated>2008-10-26T17:45:39.653-07:00</updated><title type='text'>Develolper Expertize</title><content type='html'>Trivial principle ,yet usually ignored because lack of time in the short run.&lt;br /&gt;&lt;br /&gt;Developers must have  expertize in both the subject domain they are working on, whether it is finance/networking or music.&lt;br /&gt;They should also have a minimal level of knowledge in the programming language they are using.&lt;br /&gt;Sounds trivial? it is not.  Most teams has at least one "novice" programmer strait from the university which, usually, don`t have the required expertise I mentioned. You can:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Let him code new features&lt;/li&gt;&lt;li&gt;Let him only fix old features&lt;/li&gt;&lt;li&gt;Let him watch but never touch production-code. He can touch non-critical scripts.&lt;/li&gt;&lt;li&gt;We do not hire inexperienced employees.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;What happens in your team?&lt;br /&gt;I bet most of you answer (2) , some answer (1) , know that it is bad but have tight deadlines and only small percentage will answer (3) , and almost no one answered (4).&lt;br /&gt;&lt;br /&gt;What is the right answer?   I have to go with (3)  and in some cases even (4).&lt;br /&gt;I think the best analogy to this questions , is a case where a father and son need to paint the house together.&lt;br /&gt;Asking your 3-years old boy to help you paint the house is not helpfull.  Yes , he is cute and eager to help , but we both know you can do it alone in half the time you will do it together , because you need to superwise him all the time , make sure he does not "eat the paint" and paint the furntiure.&lt;br /&gt;When your kid is 10 years old you may start using him, knowing that although you will not save time yet,  this will help your kid learn the craft.&lt;br /&gt;When your kid is 12 , you still supervise him, but already gain a good time boost with his help.&lt;br /&gt;When your kid is 15 , he can do the job himself , and if you work together , you get the job done in half the time.&lt;br /&gt;&lt;br /&gt;Setting the analogy aside, you can can let your new employee write non-production code. This is either  internal-company-code or even unit-test-code.  At the first week or two , you probably won`t gain any time benefit from him doing that , but like the 10  years old kid , the developer learns the craft.&lt;br /&gt;For those of you who answered (1) with tight-deadlines , please understand that it will only take you &lt;span style="font-weight: bold;"&gt;more &lt;/span&gt;time , in the medium-long run.  What is code good for if it is written fast but does not pass first QA tests?&lt;br /&gt;For those who answered (2) , another analogy: lets say you missed a very small spot when painting the cieling , will you give your 3-years old boy the brush and a ladder and let him loose? you will probably , again , loose time. Fixing bugs is not a good way to make new employees learn the craft. It is only the "easy" (not caring) way to do it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Last emphasize , expertise of a new subject is needed even for an engineer with dozen years of experience. For example , multi-threading expertise is a hard and quite rare one.&lt;br /&gt;Don`t let any programmer write multi-threaded code before s/he had a course/book in the matter and few weeks(months?) of experience with writing non-production multi-threaded code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-5044223377169444149?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/5044223377169444149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=5044223377169444149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/5044223377169444149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/5044223377169444149'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/develolper-expertize.html' title='Develolper Expertize'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-2325854871558427038</id><published>2008-10-26T16:45:00.000-07:00</published><updated>2008-10-26T17:11:20.983-07:00</updated><title type='text'>Increasing Quality - review and unit-tests</title><content type='html'>These principles aim is to increase code-quality and thus overall productivy.  They aim to reduce the number of bugs which slip the development team. We know that bugs take (exponentially) longer time to solve depending to how fast they were traced.&lt;/p&gt;&lt;p class="MsoNormal"&gt;The 3 principles are:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;design review&lt;/li&gt;&lt;li&gt;unit-testing&lt;/li&gt;&lt;li&gt;code review&lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Design review&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;The most important review is not the code-review but the design review. This stage is mainly ignored in most of the companies. After the design is ready  (Im implicitly assuming you are doing some sort of a design before starting to code) , let the tech-leads/seniors/smart-people review it and give remarks.&lt;br /&gt;The benefits of design review:&lt;/p&gt;  &lt;p class="MsoNormal"&gt;(a) change done in this change and not after the code-review , will save days of work later.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;(b) change done here will most probably be actually done. A lot of code-reviews ends up saying "it should have been done differently but we do not have time to fix it and re-test it now , so leave it be".  In the design-review stage these does not happen.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;(c) will be used to communicate initial API between different components , helping other developers understand what to expect for.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Note that design-review must be enforced by the managers on the tech-leads/seniors , as it is usually done in the period when the tech-leads has the least time.The manager must press them on this issue.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;i&gt;&lt;span style=";font-family:Arial;font-size:14;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;i&gt;&lt;span style=";font-family:Arial;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;unit test&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;The best way to know the quality of a component is to ask the developer what is the level of functionallity he tested. Let there be the following answers:  "It may work" , "It probably works even on hard cases" , "It defentially works on all cases".&lt;/p&gt;&lt;p class="MsoNormal"&gt;The good result should be: "It defenitally works on avegarage and it probably works even in corner cases". less then that and they did not test enough , more than that , and they wasted time on unnecerayy tests.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;      &lt;p class="MsoNormal"&gt;Developers  should do extensive unit-testing , manaul , or better yet, automated ( in java the term "JUnits" is most familiar) . This developer testing goal should be to test the high-risk sections of the code. 80-90% coverage will be better than 100% coverage , if you have more tests of error-prone code.We must understand that on 99% of the features, full code coverage is both impossible and a waste of resouces!&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;It is OK for a developer to leave some tedious test cases to the quality-assurance people as long as the developers do make an effort to test few of these cases and knows that the code "probabily works".&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;i&gt;&lt;span style=";font-family:Arial;font-size:14;"  &gt;&lt;span style="font-size:130%;"&gt;code review&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;This is done quite commonly and its a good practice. This stage can help trace dozens of bugs very fast. It also helps to spread knowledge between team members , and provide coding feedback for the coder.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;One uncommon practice in code review I want to recommend is that the code-review will be done"offline" without the original developer sitting next to the reviewer.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;This will ensure the developer writes code that another human being can understand (usually using remarks, good naming conventions etc) , as he knows someone will read his code in few weeks and will suffer otherwise.&lt;/p&gt;&lt;p class="MsoNormal"&gt;It will also ensure that no bugs are swept under the table, as you don`t talk with the code-reviewer directly.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;The coder and the reviewer will meet twice : once before the code review for high-level explanation and once after the reviewer read the whole code, to share his remarks.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-2325854871558427038?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/2325854871558427038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=2325854871558427038' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2325854871558427038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2325854871558427038'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/increasing-quality-review-and-unit.html' title='Increasing Quality - review and unit-tests'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-1197232574990534465</id><published>2008-10-26T16:10:00.000-07:00</published><updated>2008-10-26T16:31:40.412-07:00</updated><title type='text'>Bug fixing assignment - the greatest dilema of them all</title><content type='html'>closing to the end of the first version development, the team find few bugs in the version. It always happen.  When should these bugs be fixed?&lt;br /&gt;Don`t listen to the engineer which will tell you: "I`m your best engineer , developing the cutting edge features the fastest in the company. Let the new programmers to solve the bugs. This way they will learn the system and make me available to new development".&lt;br /&gt;Does the enginner sounds reasnible to you? A lot of managers falls to this pit.  Its not that the engineer is evil , s/he usually really believes that is the best way to work.&lt;br /&gt;It is not.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I got two simple principles for you regaring bug-fixing:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The bug-fixer should be the original coder  if possible  (and it is the manager job to make it possible)&lt;/li&gt;&lt;li&gt;The bug-fixing time should be close to the finding of the bug time . It does not have to be in that day , but shortly after. (and not in the next bug-fix stage which is 3 months later)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;There is a great debate on these two principles, lots of manager will say the complete opposite. I will explain why I believe they are true.&lt;br /&gt;&lt;br /&gt;Principle 1 - The bug-fixer should be the original coder (if possible)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;feedback - The coder understand his own coding mistakes and becomes a better coder, which produces less bugs.&lt;/li&gt;&lt;li&gt;It will take the orginal coder a slight percentage of the time it will take to another programmer to solve it.&lt;/li&gt;&lt;li&gt;When solving a bug , there is always a small chance to introduce a new different one. When the fixer is not the original coder , the chances become much bigger.&lt;/li&gt;&lt;li&gt;Not all the bugs , but the nasty ones , are only simptoms to other ("chronic") bugs. The original coder will find the real bug and treat it.  Other programmer will probably cure the symtoms , not the problem.  One simple example:  a race-condition bug can be solved locally , but can be a symptom of multi-threading problem across-the-system.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Principle 2 - The bug-fixing time should be close to the finding of the bug time&lt;br /&gt;If you wait to end of the current  version to fix the bug you can have few problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When all the bug-fixes are concentrated in the end of the version , it is guranteed , that the bug assignment will never be as good.  &lt;/li&gt;&lt;li&gt;unstable development version until that time. Finding workaround for multiple developers will usually waste more time that fixing it  on the first place.&lt;/li&gt;&lt;li&gt; unstable test version - the QA team may not be able to test a feature well , or waste time in discovering an already known bug. This will further reduce the quality of the version.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-1197232574990534465?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/1197232574990534465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=1197232574990534465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1197232574990534465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/1197232574990534465'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/bug-fixing-assignment-greatest-dilema.html' title='Bug fixing assignment - the greatest dilema of them all'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-2138580105871260017</id><published>2008-10-26T15:43:00.000-07:00</published><updated>2008-12-14T16:40:27.769-08:00</updated><title type='text'>Focal points</title><content type='html'>This is a very simple principle which take`s zero effort to implement.  Surprisingly, a lot of teams do not implement it.&lt;br /&gt;&lt;br /&gt;The problem:&lt;br /&gt;When outsiders (non group guys) want to talk with insiders about a bug/feature/just-an-explanation , they rarely know who to refer to in the group.&lt;br /&gt;In a lot of teams , the outsider need to go through all the group members , one-by-one , to find out who can help him with the relevant subject. When this one-by-one walk is done by email, the outsider will probably give up after three or four fwd`ed mails.&lt;br /&gt;Add to that that sometimes the first-line-manager or 2nd-line-manager are also outsiders , and you can see what a horrific waste of time and bad intra-group communication is done here.&lt;br /&gt;On some cases (aka "Agile") this can also happen inside the group , as a feature/bug does not have a clear go-to guy and instead the "whole group" is responsible to everything.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;It does not matter if you used the "circle-of-knowledge" principle  / Agile / Scrum or any other methodologies, you must assign one  "focal point" person for each feature/area.&lt;br /&gt;&lt;br /&gt;The focal point will know which feature/bugs are being developed and will be able to say who developed it ,which bugs may be related and pinpoint the exact person which will be able to give you the final answer.&lt;br /&gt;They must know the field well , but do not need to be the one which actually write the code or knows the exact small details of everything.&lt;br /&gt;&lt;br /&gt;In a flat-hierarchy team , there can be a lot of focal-points , each one is responsible for his own area-of-expertize.&lt;br /&gt;In a traditional hierarchy team , the group/team leaders tend to be the focal points for all the areas their team are doing.&lt;br /&gt;&lt;br /&gt;It takes a MAX of 3 hops to get to the person which knows the answer:&lt;br /&gt;first hop - Danny points you to the focal point of this subject, Joe.&lt;br /&gt;second hop - Joe either knows the answer right away and we are done here, or knows exactly who solved the bug a month ago (Jenny) and send her a email, cc-ing himself regarding the problem.&lt;br /&gt;third hop - Jenny answers the problem and will never "pass-it-on".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;a final note: DO NOT MISTAKE FOCAL-POINT TO TEAM LEADER.&lt;br /&gt;Focal-point can be a non-senior programmer too, if he is the main expert in his field  (or the field is so un-intresting that no one wants to get near it)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-2138580105871260017?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/2138580105871260017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=2138580105871260017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2138580105871260017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/2138580105871260017'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/focal-points.html' title='Focal points'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-8253457667938989454</id><published>2008-10-26T14:20:00.000-07:00</published><updated>2008-10-26T15:38:07.008-07:00</updated><title type='text'>How to fight against "job-security" employee-principle using the "Circles-of-knowledge" manager-principle</title><content type='html'>This is a great principle I learned from a great manager in one of the last jobs I had.&lt;br /&gt;I`ll start describing the problem that this principle solves by a true example:&lt;br /&gt;&lt;br /&gt;A startup company , lets call it , "the guild" has 20 good dedicated workers which build a great and complex piece of software.  As "the guild"`s buisness is blooming they want to recruit 20 new employees each year.&lt;br /&gt;Some of the existing employees, usually the less bright ones , fear for their job/status when the new employees arrive and think of a clever way to have "job security". They do not teach the other employees anything about the systems they are working on and remain the only one knowning how to operate these systems.&lt;br /&gt;At the first year, the company still manage fine. The new employees work tend to "flow" around the old employee`s systems and the new and the old work in hamoney.&lt;br /&gt;At the second year, the old employees understand that they are the only ones knowing how to operate the core systems and they demand better salary/promotion etc. The manager ask himself (and some of his workers) can anyone else knows how to do thier jobs ? as the answer is negative - they did not allow anyone to get near those core-systems ,  the manager promotes the non-bright people to a team-leader jobs.&lt;br /&gt;At the third year , those team-leaders , continue to use the principle that helped them advance so well , on their previous jobs (the core-systems) and the new jobs: their whole new team don`t allow anyone near their code.&lt;br /&gt;At the fourth year , the "job security" principle is so bad , that no team can work with another team and no new feature which needs inter-team cooperation can be done.&lt;br /&gt;The employess demand a raise again , and as they are now totally irriplacable , get it.&lt;br /&gt;At the fifth year , the employees are getting bored and decide to move to another company.  They allow one month notice in which they will be willing to explain all the core-systems that they wrote to the new employee replacing them, but one month is never enough to pass a five years body of knowledge.&lt;br /&gt;At the sixth year, things in the core-systems , which now are not maintanaced by anyone , start to break. No one knows how to fix them and the core-systems are slowly getting deprecated and finally shut down.&lt;br /&gt;&lt;br /&gt;This is a true story which happend in various teams in the same company. I`ll bet you met at least one employee which is creating his "job-security" in every big company you worked on.&lt;br /&gt;&lt;br /&gt;Some of you are probably running to the "comments" and going to tell me about the great software development methadologies you are working on ( like  "Agile/XP") who succesfully  solve this problem by making sure that no one person will ever be responsible to one component.&lt;br /&gt;So let me say one thing, Agile/XP solve this problem , but creates another, even more serious one:  Instead of only one person knows how to work with the core-system , Agile/XP makes sure that NO ONE will know how to work with the core-system.&lt;br /&gt;&lt;br /&gt;Lets me describe the "circles-of-knowledge" solution (again, a young manager I worked with created and perfected it. Im only describing his idea). It can be summed by three simple principles:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Inner circle principle - Every big feature will have few(1-2) people which are responsible for it and have excellent knowledge on the code/bugs of the feature.&lt;/li&gt;&lt;li&gt;Outer circle principle - When coding/bug-fixing a big feature, few(1-2) other people will get tasks related to the feature which they are not in its inner-circle.&lt;/li&gt;&lt;li&gt;Make sure the circles overlaps and interwind as much as you can, creating good redundency among your employees&lt;/li&gt;&lt;/ol&gt;Usage example:&lt;br /&gt;On our team there there are 5 people ,lets call them A,B,C,D and E.  The team task is to develop a client-server system with 4 components, with the following man-hours percentages:&lt;br /&gt;server side framework (20%) , server-side application(big feature 40%) , client-side framework(10%) , client-side application(30%).&lt;br /&gt;This is an example , of work-division according to the circle-of-knowledge principle:&lt;br /&gt;A: inner circle - server-side FW               outer circle - server-side apps&lt;br /&gt;B: inner circle - server-side Apps            outer circle - server-side FW&lt;br /&gt;C: inner circle - server-side Apps            outer circle - client-side FW,client-side apps&lt;br /&gt;D: inner cirlce - client-side FW                outer-circle- server-side apps&lt;br /&gt;E: inner circle - clinet-side apps              outer circle - client-side FW&lt;br /&gt;&lt;br /&gt;This is only one example , of a possible division. The important thing to note is that big features will have more than one people in the inner-circle , and few on the outer circle too and that even the smallest feature will have someone in the outer-circle which have knowledge of it.&lt;br /&gt;And as there are more employees (imagine same team with 10 people)  the cirlcels overlaps become clearer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using these priciples , it is easy to see the end result:&lt;br /&gt;Redundency - you can "loose" 2 employees and still have excellent knowledge coverage of all the features.  Even if your "loose" half of your team,  you will still have excellent knowledge about the inner-circle features , and reasnilblee knowledge of the other featues , they covered as part of their outer circle.&lt;br /&gt;Resposibility - at any given time , each employee is directly responsible for a feature of his own. . It is clear who can help in a problem. It is clear who to praise for a job well done and whoto blaim for a system defacts.&lt;br /&gt;Efficency -  As all the features are covered with excellent level of knowledge , it is easy to develop new code or solve bugs.  There is never a "black-box" feature which all dread to touch.&lt;br /&gt;But you never incrase the outer-circle to the whole team, preventing the problem of "all-need-to-know everthing but end up knowing nothing".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A final note to clear things up: The division to the circle of knowledge is being created over a period of time , meaning , don`t go and divide each two-weeks feature into 4 different people (thats the mistake agile/xp guys tend to do).  Instead, make sure that over a long period of time , like 3-6 months , you slowly create this coverage. Example; The first team (inner-circle) will do the core feature on the first 2 months.  In the 3rd month a small feature needs to be added - assign one guy from the inner circle and one from the outer-circle. In the 4th month another small feature is added, again , put one from the inner circle and one from the outer-circle , and so on and so on.&lt;br /&gt;&lt;br /&gt;Using this method , is not easy at first for the manager, cause it requires a lot of premeditation of his part, but it is worth it. Who said the work of a manager is easy ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-8253457667938989454?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/8253457667938989454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=8253457667938989454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8253457667938989454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/8253457667938989454'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/how-to-fight-damaging-job-security-or.html' title='How to fight against &quot;job-security&quot; employee-principle using the &quot;Circles-of-knowledge&quot; manager-principle'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-9032092688500199596</id><published>2008-10-26T14:03:00.000-07:00</published><updated>2008-10-26T14:20:47.557-07:00</updated><title type='text'>Good Manager</title><content type='html'>You need a lot of character to become a good manager. I can`t teach you that (other blogs claim they can ...)&lt;br /&gt;I can give you simple work principles ,to-do and don`t-do list, I collected from the good/bad managers I had the privilege/horror to work with.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Recruiting: Small excellent groups are far more productive than big moderate groups. &lt;br /&gt;Following this rule allegedly &lt;span style="height: 10px; font-family: arial; font-size: 9pt; color: rgb(0, 0, 153);" dir="ltr" id="spnTrans1"&gt; &lt;/span&gt;contradicts a known principle: "The more people the manager has, the more important the manager is".  Yes , known problem.&lt;br /&gt;I can only suggest setting your ego aside when recruiting new employees and thinking what is really best, long run for the business and thus for you. I hope you will choose wisely.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Flatten the hierarchy of your team.  &lt;br /&gt;Find how many people can you effectively manage by yourself. The number is usually capped at 5-7. people.  If you have that many people, treat all as equal (in importance not in knowledge). If you have more than that , create sub-hierarchy's by creating 2-4 groups in the team and provide one group leader for each group. Tell them to treat each one of their employees as equal   [ this is a recursive principle :) ]&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Do a weekly-review of one hour with the whole team. Share managerial decisions (those you can) in the weekly meetings. Don`t let rumors rise , and Send a summary of the weeky-review after it , so people who could not join won`t waist a full day asking what did they miss. &lt;/li&gt;&lt;li&gt;When dividing tasks/pay you can never be equal with everyone. thats a fact.&lt;br /&gt;So Don`t hesitate to tell your employees that they will be compensaited in the next tasks/pay division. It will usually change their mood from sad "I wanna quit" to joy "The boss owes me a great thing next time" . Remember that they will wait for you to keep your promise.&lt;/li&gt;&lt;li&gt;keep your promises to your employees.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-9032092688500199596?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/9032092688500199596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=9032092688500199596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/9032092688500199596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/9032092688500199596'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/good-manager.html' title='Good Manager'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2714571064530517421.post-6342942056516679440</id><published>2008-10-26T13:59:00.000-07:00</published><updated>2008-10-26T14:02:48.293-07:00</updated><title type='text'>Hello World</title><content type='html'>In this blog , I will talk about software development. &lt;br /&gt;The good&lt;br /&gt;The bad&lt;br /&gt;and the Ugly things in software development.&lt;br /&gt;&lt;br /&gt;It is not intended for specific programming language , but on principals related to managing a software project as a whole.&lt;br /&gt;Trying to summarize here the work experience I had in quite a few projects , in small companies (start ups) and very big companies.&lt;br /&gt;&lt;br /&gt;so , lets start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2714571064530517421-6342942056516679440?l=onsoftwaredev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onsoftwaredev.blogspot.com/feeds/6342942056516679440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2714571064530517421&amp;postID=6342942056516679440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6342942056516679440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2714571064530517421/posts/default/6342942056516679440'/><link rel='alternate' type='text/html' href='http://onsoftwaredev.blogspot.com/2008/10/hello-world.html' title='Hello World'/><author><name>AssafOnSoftware</name><uri>http://www.blogger.com/profile/16142831758052316024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
