<?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-7061498094705606309</id><updated>2011-10-25T04:29:55.551-07:00</updated><category term='Frameworks'/><category term='Code Review'/><category term='Technology'/><category term='Industry'/><category term='Eclipse'/><category term='C/C++'/><category term='Decent Code'/><category term='OOPSLA'/><category term='Debug'/><category term='Design'/><category term='Wiki'/><category term='Java'/><category term='Off-Shore'/><category term='Open Source'/><category term='Web'/><category term='Recruitment'/><category term='Testing'/><title type='text'>On Software and Other Animals</title><subtitle type='html'>AKA OnSoftwareAndOtherAnimals, SoftwareAnimals, or just SWAnimals</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-3412428968065402061</id><published>2011-08-18T04:03:00.000-07:00</published><updated>2011-08-18T07:43:29.833-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Big Map, String, GC, Memory Consumption and Performance</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/-EGarCCD0nrY/Tk0RezSYMHI/AAAAAAAABoc/AtSEgxygGOs/s1600/dictionary2.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5642185129026138226" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 225px; CURSOR: hand; HEIGHT: 170px" alt="" src="http://3.bp.blogspot.com/-EGarCCD0nrY/Tk0RezSYMHI/AAAAAAAABoc/AtSEgxygGOs/s400/dictionary2.jpg" border="0" /&gt;&lt;/a&gt;Hashtables are used in many cases to cache information in memory. There are other alternatives, like in memory databases, or flushing data to disk, but when all you need is a simple key-value relation and you need very high performance, the simple Java HashMap can do the trick. Usually cache can allow loosing information that was not claimed recently, assuming that recent usage of the data can foresee higher chances of this data to be claimed again soon, compared to less recently used data. But in some cases we prefer the cache to hold as much information as possible, which means a VERY BIG MAP.&lt;br /&gt;&lt;br /&gt;Important morals below are based on an application with HashMap holding 20M entries, in 64bit JVM and 6 GB (-d64 -Xmx6g ). The Map itself uses much less memory, but in order for the entire application to work smoothly we need the 6 GB.&lt;br /&gt;&lt;br /&gt;When coming to very big HashMap, there are a few considerations to take into account:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;The default load factor of 0.75 is reasonable. Don't play with it without understanding what you are doing. The load factor determines when the map should grow and rehash should occur, this happens when number of elements in the map gets above the result of (&lt;em&gt;capacity * load factor&lt;/em&gt;). Higher values of load factor means less rehash operations, but a map that is more dense. Calls to &lt;em&gt;get&lt;/em&gt; in a dense map are more costly since buckets are full with many entries that shall be iterated. Lower load factor values will create more rehash operations and a sparse map, which is more memory consuming but more efficient in &lt;em&gt;get&lt;/em&gt; calls. It should be noticed that load factor can be bigger than 1, which means we allow the table (number of buckets) to be smaller than number of entries.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: don't start with optimizing the load factor, it's a bad start.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Initial capacity is important. Starting the HashMap too small will result with rehash operations upon calls to put. Though HashMap doubles itself on resize, still failing to provide appropriate initial capacity may result with a few costly resize cycles.&lt;br /&gt;The recommended initial capacity, for load factor of 0.75, is: &lt;em&gt;1.5 * numElements&lt;br /&gt;&lt;/em&gt;(Read more: &lt;a href="http://stackoverflow.com/questions/434989/hashmap-intialization-parameters-load-initialcapacity"&gt;http://stackoverflow.com/questions/434989/hashmap-intialization-parameters-load-initialcapacity&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;In our case, the performance difference of setting 20M entries into the map, with setting the initial capacity to 30M (Java will in fact set the initial capacity to the closest power of 2 above this size), compared to no initial capacity set, was almost double the insertion time, with very clear workload on rehash and GC work following it.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: initial capacity is important. Set it!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Beware of memory leaks!&lt;br /&gt;Maps, as any long-leaving memory storage entity, are a potential source for leaks.&lt;br /&gt;In our case, the Map got Strings from file, but needed to use for the entries' keys only a small portion of each line read from the file. Thus, after reading each line from the file, some string tokenizing was done resulting with the key and value to store.&lt;br /&gt;Unfortunately the entire line read from file is kept in memory, even though we need only part of it... This is due to the way &lt;em&gt;substring&lt;/em&gt; and other similar tokenizing methods are implemented, which return a new String, that holds the old one with offsets inside. This is a known issue (for example see: &lt;a href="http://eyalsch.wordpress.com/2009/10/27/stringleaks/"&gt;http://eyalsch.wordpress.com/2009/10/27/stringleaks/&lt;/a&gt;).&lt;br /&gt;Solution is to manually create a new String and give it the substring portion you want to keep:&lt;br /&gt;&lt;em&gt;String key = new String(bigLine.substring(from, to));&lt;br /&gt;&lt;/em&gt;In our case, fixing a similar issue resulted with requiring 1.5GB less memory for the exact same scenario! It turned out that the map keys' kept a long tail that should have been cut.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: beware of holding a substring in a Map! Do it the right way.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In such a huge map, every byte in the key-value becomes 20M in the entire map. Thus saving a few bytes can worth the hassle. For example, instead of using String as the value, we decided to use char array (a simple char[]) thus saving: [1] a reference to the string object from the hashmap entry - instead holding a direct reference to char[]. In 64 bit this values to 8 bytes saving! [2] three int fields that are in String class: offset, count and hashmap. The offset and count fields are there to allow String to point at a position which is partial in the char[] it holds (directly related to the substring leak mention in item 3 above). We don't need this info. Also caching the hashmap value is redundant, as the Map entry itself does it.&lt;br /&gt;&lt;br /&gt;By using char[] instead of String as our value, we save 20 bytes per entry, which is 400MB total! And without hurting the code or making it more complex.&lt;br /&gt;&lt;br /&gt;Our key is also a String, but it cannot be turned into char[], as we need a proper hashcode and equals functions. Still, one should consider implementing a dedicated Key class that holds only the relevant info, char[] in our case. Since the extra reference cannot be saved, the saving here could be the 3 int fields in class String, which totals to 240MB for 20M entries.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: caching Strings in big Maps is costly. Think how to reduce the size of your key and value!&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The hashcode is crucial. Bad hashcode on the key, which creates bad distribution (too many keys get the same hashcode value) can be performance devastating. On the other hand, though of much less importance, a more efficient hashcode method has an influence over at least 20M insertion operations. Read how String hashcode is implemented to get the idea: &lt;a href="http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier"&gt;http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: check your key hashcode method, use some real data and validate that you get reasonable distribution. If needed, work on improving the hashcode method by using higher power multiplication on the key fields.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Know when to stop optimizing. In some cases you see a programmer keep optimizing when there is really nothing more to optimize (well, there is always more to optimize, but then it may result with taking parts to C and using JNI, or use direct byte arrays, things you would better not go to, if not really needed...).&lt;br /&gt;Calculate the most minimal amount of memory you need, save your time and don't try to optimize your application into less.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: set goals to your optimization efforts. Make sure the goals are not too aggressive, i.e. are feasible without re-writing the entire thing.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The entries of the big map will eventually arrive to the GC old-generation section. It means that in the described usage the old generation is going to be very big. There are two options to handle this, one is to play with the generation ratios, the other option is to set a big enough total heap memory to allow the old generation to be big enough. If you have enough resources on the machine you can go with the second option, otherwise you would need to dig into the generation ratio configuration.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;To summarize&lt;/u&gt;: size of the old generation section is crucial to prevent unnecessary full GC cycles. Configure the max heap size and/or the generation ratios.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;By optimizing the memory consumtion we got also much better performance, as the application went into less GC cycles. Some other parts of the drill include removing unused entries from the cache, in a dedicated thread, when reaching certain threshold, and more... The result is a huge cache running smoothly on a reasonable sized server.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-3412428968065402061?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/3412428968065402061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=3412428968065402061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3412428968065402061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3412428968065402061'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/08/big-map-string-gc-memory-consumption.html' title='Big Map, String, GC, Memory Consumption and Performance'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://3.bp.blogspot.com/-EGarCCD0nrY/Tk0RezSYMHI/AAAAAAAABoc/AtSEgxygGOs/s72-c/dictionary2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-4576549778131382299</id><published>2011-04-22T08:29:00.000-07:00</published><updated>2011-04-22T08:53:44.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Review'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Decent Code</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/-XhEFzA9c9ls/TbGjyx2DBEI/AAAAAAAABnw/KFglz5ELQO4/s1600/angrycat.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5598435904567051330" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 171px; CURSOR: hand; HEIGHT: 137px" alt="" src="http://2.bp.blogspot.com/-XhEFzA9c9ls/TbGjyx2DBEI/AAAAAAAABnw/KFglz5ELQO4/s400/angrycat.jpg" border="0" /&gt;&lt;/a&gt;Retrospecting the posts labled &lt;a href="http://softwareanimals.blogspot.com/search/label/Decent%20Code"&gt;Decent Code&lt;/a&gt; I see many good points worth memorizing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/08/do-you-have-api.html"&gt;Do you have an API?&lt;/a&gt; - the basic question before coding!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/04/do-you-have-theory.html"&gt;Do you have a theory?&lt;/a&gt; - the basic question before debugging!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/08/be-proud-of-your-code.html"&gt;Be proud of your code!&lt;/a&gt; - a simple advice, yet powerful, for code reviews&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2009/01/risks-of-redundant-code-or-less-is-more.html"&gt;The risks of redundant code (or - Less is More)&lt;/a&gt; - another powerful advice for code reviews&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/11/use-explaining-variables.html"&gt;Use Explaining Variables!&lt;/a&gt; - and another one for code reviews (I should consider a label for code reviews probably)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2010/09/resource-files.html"&gt;Resource Files&lt;/a&gt; - this is obvious for anybody today, yet ignored too often...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2011/01/freaking-behavior-of-small-little-cc.html"&gt;Freaking behavior of a small little C/C++ bug&lt;/a&gt; - avoid the non-void not returning a value!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2010/08/semi-colon-and-javalangoutofmemoryerror.html"&gt;Semi-colon and java.lang.OutOfMemoryError&lt;/a&gt; - the methodic way of analyzing OOM in Java programs&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and &lt;a href="http://softwareanimals.blogspot.com/search/label/Decent%20Code"&gt;many more&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;like for example...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/11/make-sure-to-have-strict-xsd.html"&gt;Make sure to have a strict XSD!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;or &lt;a href="http://softwareanimals.blogspot.com/2008/07/to-ajax-or-not-to-ajax.html"&gt;To AJAX or NOT to AJAX?&lt;/a&gt; - important to many web developers today which neglect the request-response model for AJAX idol, in many cases for no good reason.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and still, &lt;a href="http://softwareanimals.blogspot.com/search/label/Decent%20Code"&gt;many more&lt;/a&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-4576549778131382299?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/4576549778131382299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=4576549778131382299' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4576549778131382299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4576549778131382299'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/04/decent-code.html' title='Decent Code'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/-XhEFzA9c9ls/TbGjyx2DBEI/AAAAAAAABnw/KFglz5ELQO4/s72-c/angrycat.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-8938003796600302954</id><published>2011-03-31T22:55:00.000-07:00</published><updated>2011-04-22T09:01:06.945-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><title type='text'>The success of iPhone</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/-8wjRRNglTdw/TbGmIcIz8UI/AAAAAAAABn4/145XrOAv2Dw/s1600/giraffe.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5598438475720552770" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 135px; CURSOR: hand; HEIGHT: 118px" alt="" src="http://4.bp.blogspot.com/-8wjRRNglTdw/TbGmIcIz8UI/AAAAAAAABn4/145XrOAv2Dw/s400/giraffe.jpg" border="0" /&gt;&lt;/a&gt;Three years back, &lt;a href="http://softwareanimals.blogspot.com/2008/08/changelightbulbwindowhandleex-for-blind.html"&gt;I explained why Nokia is not supporting external applications&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Well, since then Apple has AppStore and Nokia has followed with OVI. And Samsung has its Internet@TV portal.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;It appears that focusing on the appliance itself is not enough nowadays.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-8938003796600302954?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8938003796600302954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8938003796600302954' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8938003796600302954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8938003796600302954'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/03/success-of-iphone.html' title='The success of iPhone'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/-8wjRRNglTdw/TbGmIcIz8UI/AAAAAAAABn4/145XrOAv2Dw/s72-c/giraffe.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-943356767440178801</id><published>2011-01-20T05:47:00.000-08:00</published><updated>2011-04-22T08:25:30.216-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><title type='text'>Thoughts following 2010 FogBugz and Kiln World Tour</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_msmuQKgFPkU/TTg983hs5ZI/AAAAAAAABm8/n3Yz0g6SI8g/s1600/fogbugs_kiln.PNG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5564265455522997650" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 91px" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/TTg983hs5ZI/AAAAAAAABm8/n3Yz0g6SI8g/s400/fogbugs_kiln.PNG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I was attending yesterday Joel Spolsky world tour for FogBugz and Kiln.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I must admit that till yesterday I thought that Joel has a great blog about SW development, but I didn't quite understand - who needs yet another bug tracking tool... is there still a real market for that, when you have today so many good free tools!?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;A few thoughts following the event:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Joel's presentation skills do not fall from his writing. The gathering starting with a projected countdown analog clock, Joel went on stage right at the moment when the countdown reached its end - with a pre-planned bug on the clock finish resulting with some fake errors and blue screens, which led Joel to open a bug, start his presentation, then get a response on his newly opened bug "poping accidentally" while in his presentation (interestingly enough, while his Outlook is closed :-) , which led to getting into the code itself using Kiln, comparing versions and eventually "solving" the bug and checking in. A full bug detection and solving cycle in 10 minutes. With a few jokes here and there, and while going quickly through the products' abilities and strength points.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The traditional tools for bug tracking and source control are OK. But even in this "already solved" domain, there is still room for improvements and for new players, either open source or commercial. When we have an idea to develop something we usually tend to check who already done that and how good it is. And when we see that there are already several reasonable solutions we assume that the market is closed for us on that. Well, Joel shows that there is always a market for realy good products, you don't have to invent a new big thing, you may need however to invent many small things.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Distributed Source Version Control - GIT, Mercurial, Kiln - disconnects the developers own copy from a repository, while preserving full history and repository context. This concept has several significant advantages:&lt;br /&gt;(a) You do not postpone your check-ins, being afraid of hurting the main repository, check-ins are made into your private copy. When you are ready you push your copy back to the main repository. Your check-ins preserve full history during your development! This is also important when you perform a merge and realize that your original file was overriden by a wrong change - you don't have to worry as you have your full history at hand and you can get back to your last check-in.&lt;br /&gt;(b) You can push your developments to another repository, e.g. to a QA repository, thus allowing to push relevant fixes quickly, without releasing them yet to the development repository.&lt;br /&gt;(c) Upon merge, it's easier to see for each change the exact origin of it. Managing several customer releases you can see which changes in the main release where merged into the customer release and which not.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-943356767440178801?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/943356767440178801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=943356767440178801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/943356767440178801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/943356767440178801'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/01/thoughts-following-2010-fogbugz-and.html' title='Thoughts following 2010 FogBugz and Kiln World Tour'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/_msmuQKgFPkU/TTg983hs5ZI/AAAAAAAABm8/n3Yz0g6SI8g/s72-c/fogbugs_kiln.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-5227092352780137506</id><published>2011-01-13T22:52:00.000-08:00</published><updated>2011-01-23T00:58:29.239-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='C/C++'/><title type='text'>Online IDE for almost any SW lang you can think of</title><content type='html'>Take a look at this one: &lt;a href="http://ideone.com/"&gt;http://ideone.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It supports:&lt;br /&gt;Ada, Assembler, AWK, Bash, bc, Brainf**k, C, C#, C++ se, C++0x, C99 strict, CLIPS, Clojure, COBOL, COBOL 85, Common Lisp (clisp), D (dmd), Erlang, F#, Factor, Falcon, Forth, Fortran, Go, Groovy, Haskell, Icon, Intercal, Java, JavaScript (rhino), JavaScript (spidermonkey), Lua, Nemerle, Nice, Nimrod, Objective-C, Ocaml, Oz, Pascal (fpc), Pascal (gpc), Perl, Perl 6, PHP, Pike, Prolog (gnu), Prolog (swi), Python, Python 3, R, Ruby, Scala, Scheme (guile), Smalltalk, SQL, Tcl, Text, Unlambda, Visual Basic .NET, Whitespace&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's very useful when you want to check little programs, like the ones I tried when writing &lt;a href="http://softwareanimals.blogspot.com/2011/01/freaking-behavior-of-small-little-cc.html"&gt;Freaking behavior of a small little C/C++ bug&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;[1]&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/TTvsziSp1QI/AAAAAAAABnM/GZju2tTZHRc/s1600/no-return-value1.PNG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5565302134668907778" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 239px" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/TTvsziSp1QI/AAAAAAAABnM/GZju2tTZHRc/s400/no-return-value1.PNG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[2]&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/TTvsz7nWW9I/AAAAAAAABnU/GQ5_joWkqu8/s1600/no-return-value2.PNG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5565302141466598354" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 266px" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/TTvsz7nWW9I/AAAAAAAABnU/GQ5_joWkqu8/s400/no-return-value2.PNG" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5227092352780137506?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5227092352780137506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5227092352780137506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5227092352780137506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5227092352780137506'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/01/online-ide-for-almost-any-sw-lang-you.html' title='Online IDE for almost any SW lang you can think of'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/TTvsziSp1QI/AAAAAAAABnM/GZju2tTZHRc/s72-c/no-return-value1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-6296507319386406981</id><published>2011-01-13T22:02:00.000-08:00</published><updated>2011-10-25T04:29:55.570-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><category scheme='http://www.blogger.com/atom/ns#' term='C/C++'/><title type='text'>Freaking behavior of a small little C/C++ bug</title><content type='html'>Oh boy.&lt;br /&gt;Read till the end the event and its root cause. Important morals follow below.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_msmuQKgFPkU/TThMp0sIqyI/AAAAAAAABnE/uWUtgbNXUOU/s1600/timer.GIF"&gt;&lt;img id="BLOGGER_PHOTO_ID_5564281621018356514" style="width: 200px; height: 196px;" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/TThMp0sIqyI/AAAAAAAABnE/uWUtgbNXUOU/s400/timer.GIF" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We run systems that on high capacity events handle thousands of transactions per second. One of the most heavy-traffic periods is New-Year's-Eve, the 31st of December, were most of our systems are under heavy stress around the world, stress that tends to difuse to our support teams. Structured and strict preparations usually make us pass this heavy-traffic day properly in most, if not all sites. Which happily was the case also this year.&lt;br /&gt;&lt;br /&gt;Shockingly, on January 2nd we had a crash in two sites.&lt;br /&gt;&lt;br /&gt;Analyzing the crash led to a timer that instead of re-scheduling itself for every 5 seconds, keeps snapping abruptly in periods of milliseconds.&lt;br /&gt;&lt;br /&gt;While still analyzing the case, reproducing it in our labs, the problem vanished as suddenly as it appeared, on the end of the same day. January 3rd, 00:00, systems went back to behave nicely.&lt;br /&gt;&lt;br /&gt;That's really odd. How does the bug relates to the date? Is it a coincidence? It doesn't look so, as a second after midnight problem disappears. Trying to reproduce it in the lab we got the same behavior: it is the bug of January 2nd 2011. (By the way, when running the system in our labs in debug mode, problem didn't reproduce! Bug appears only when running without debug! That's common for memory related bugs, smears etc.)&lt;br /&gt;&lt;br /&gt;To some of us, it sounded like the iPhone alarm bug. Which was reported also not to work properly on 2011 start, being fixed on its own, by January 3rd.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tipb.com/2010/12/31/iphone-bugs-alarms-working-2011/"&gt;http://www.tipb.com/2010/12/31/iphone-bugs-alarms-working-2011/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Maybe it's the same bug?&lt;br /&gt;&lt;br /&gt;iPhone runs on iOS which is Linux based. We also run on Linux. Maybe there is something with Linux timers on beginning of 2011?&lt;br /&gt;Looking for something in this direction led to nothing.&lt;br /&gt;&lt;br /&gt;On the other hand, analytical investigation led to the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The timer, when awakes, calls our callbak function. The callback function shall return an int value. Any value except 1 says "OK", 1 says - please call me again.&lt;/li&gt;&lt;li&gt;Our callback function didn't return a value at all&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Wait... - is it legal not to return a value from a non-void method?&lt;br /&gt;Unfortunately, in C/C++ it is. And the bevior is undefined. The function do return a value, in some environmnets it will be the last value from the register. And, well, occasionaly it can be 1.&lt;/p&gt;&lt;p&gt;See:&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pro/1610454#1610454"&gt;http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pro/1610454#1610454&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/2598084/function-with-missing-return-value-behavior-at-runtime"&gt;http://stackoverflow.com/questions/2598084/function-with-missing-return-value-behavior-at-runtime&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;What shall be done?&lt;/p&gt;&lt;p&gt;Read:&lt;/p&gt;&lt;p&gt;&lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html"&gt;http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html&lt;/a&gt; &lt;/p&gt;&lt;p&gt;-Wreturn-type&lt;/p&gt;&lt;p&gt;Warn whenever a function is defined with a return-type that defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void (falling off the end of the function body is considered returning without a value), and about a return statement with an expression in a function whose return-type is void. For C++, a function without return type always produces a diagnostic message, even when -Wno-return-type is specified. The only exceptions are `main' and functions defined in system headers. This warning is enabled by -Wall.&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Listen to compiler warnings!&lt;br /&gt;Solve all warnings, you should have a zero warnings policy.&lt;br /&gt;The problem above could be caught and solved as a warning (-Wreturn-type).&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you don't keep a policy of zero warnings, which you should, turn bad warnings as the one above into an error, with a compilation flag, e.g.: -Werror=return-type&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You may want to test your software in future time, for example, have a test system that runs all the time 30 days ahead, if there is a time related bug it may help catching it on time. It won't probably catch everything, but it could have catch the problem we had above!&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6296507319386406981?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6296507319386406981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6296507319386406981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6296507319386406981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6296507319386406981'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2011/01/freaking-behavior-of-small-little-cc.html' title='Freaking behavior of a small little C/C++ bug'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/_msmuQKgFPkU/TThMp0sIqyI/AAAAAAAABnE/uWUtgbNXUOU/s72-c/timer.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-7994697460044245827</id><published>2010-11-25T05:39:00.000-08:00</published><updated>2011-01-25T06:27:02.174-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C/C++'/><title type='text'>A simple generic template function</title><content type='html'>A simple generic template function for getting the minimum and maximum from STL container and simple arrays.&lt;br /&gt;&lt;br /&gt;Nothing too complicated, I just liked this example.&lt;br /&gt;&lt;br /&gt;&lt;pre style="BORDER-RIGHT: #cccccc 1px dashed; PADDING-RIGHT: 0px; BORDER-TOP: #cccccc 1px dashed; PADDING-LEFT: 0px; FONT-SIZE: 12px; BACKGROUND: url(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif) #f0f0f0; PADDING-BOTTOM: 0px; OVERFLOW: auto; BORDER-LEFT: #cccccc 1px dashed; WIDTH: 80%; COLOR: #000000; LINE-HEIGHT: 20px; PADDING-TOP: 0px; BORDER-BOTTOM: #cccccc 1px dashed; FONT-FAMILY: arial; HEIGHT: 600px; TEXT-ALIGN: left"&gt;&lt;code style="COLOR: #000000; WORD-WRAP: normal"&gt;1:  template&amp;lt;class Iterator&amp;gt;&lt;br /&gt;2:  pair&amp;lt;Iterator, Iterator&amp;gt; minMaxFinder(Iterator begin, Iterator end)&lt;br /&gt;3:  {&lt;br /&gt;4:      Iterator min = begin;&lt;br /&gt;5:      Iterator max = begin;&lt;br /&gt;6:      for(++begin ; begin != end; ++begin) {&lt;br /&gt;7:          if(*begin &amp;gt; *max) {&lt;br /&gt;8:              max = begin;&lt;br /&gt;9:          }&lt;br /&gt;10:         else if(*begin &amp;lt; *min) {&lt;br /&gt;11:             min = begin;&lt;br /&gt;12:         }&lt;br /&gt;13:      }&lt;br /&gt;14:      return pair&amp;lt;Iterator, Iterator&amp;gt;(min, max);&lt;br /&gt;15:  }&lt;br /&gt;16:  int main()&lt;br /&gt;17:  {&lt;br /&gt;18:      int iArr[] = {15, 5, 70, 2};&lt;br /&gt;19:      pair&amp;lt;int*, int*&amp;gt; minmax = minMaxFinder(&amp;amp;iArr[0], &amp;amp;iArr[4]);&lt;br /&gt;20:      cout &amp;lt;&amp;lt; *minmax.first &amp;lt;&amp;lt; ", " &amp;lt;&amp;lt; *minmax.second &amp;lt;&amp;lt; endl;&lt;br /&gt;21:      list&amp;lt;string&amp;gt; sList;&lt;br /&gt;22:      sList.insert(sList.end(), "small");&lt;br /&gt;23:      sList.insert(sList.end(), "smallish");&lt;br /&gt;24:      sList.insert(sList.end(), "big");&lt;br /&gt;25:      sList.insert(sList.end(), "biggish");&lt;br /&gt;26:      pair&amp;lt;list&amp;lt;string&amp;gt;::iterator, list&amp;lt;string&amp;gt;::iterator&amp;gt; &lt;br /&gt;27:               minmaxS = minMaxFinder(sList.begin(), sList.end());&lt;br /&gt;28:      cout &amp;lt;&amp;lt; *minmaxS.first &amp;lt;&amp;lt; ", " &amp;lt;&amp;lt; *maxminS.second &amp;lt;&amp;lt; endl;&lt;br /&gt;29:      return 0;&lt;br /&gt;30:  } &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;font-size:78%;"&gt;Code formatted with &lt;/span&gt;&lt;a href="http://codeformatter.blogspot.com/"&gt;&lt;span style="font-family:verdana;font-size:78%;"&gt;http://codeformatter.blogspot.com&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7994697460044245827?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7994697460044245827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7994697460044245827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7994697460044245827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7994697460044245827'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/11/simple-generic-template-function.html' title='A simple generic template function'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7744314371842808263</id><published>2010-11-22T07:16:00.000-08:00</published><updated>2011-01-20T07:40:54.235-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Frameworks'/><title type='text'>Thoughts on Open Source licenses, Patents on Software and such</title><content type='html'>I'm dealing with Open Source usage approval cycle, which is an important task in any company, last thing that you want is to have your developers use whatever they find on the web.&lt;br /&gt;&lt;br /&gt;Few insights and thoughts from my experience:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Developers in genral are mostly ignorant to legal issues. If not controlled they may use a free 30-days evaluation copy embedded in their system, just because the word free appeared somewhere in the site. In most cases they don't bother to read the license.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;With Off-Shore developers problem is even bigger. They tend to be much more open with open source, without seeing the risks. Even if they do follow the company policy, submitting usage requests for open source usage, you may find inside their code much more "embedded" un-approved snippets and libraries. I tend to think that the reason is the distance, they believe that even if caught the maximum you could do is yell at them over the phone or in e-mails, but you cannot beat them physically and they use it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;For above reasons and others, usage of open source must be controlled. There are scanning tools in the market that help you find un-reported usage of open source and commercial external software. Usage of such is helpful in finding the disobedient developers who still drop in whatever they like, fix that on time and beat them while the felony is still hot.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Scanning tools also point at many usages that are a very small snippet of something that looks like might be taken from an open source or even from an un-licensed example on the web. To some it seem a problem that should be fixed in the code, I personally believe that the rights on how to perform quick sort do not belong to anybody, even if part of some open source or are published on the web somewhere. Taking two notes from a melody doesn't harm its rights.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Same goes for patents on software. Publishing a patent on algorithm is problematic, but many patents are on "a method and a system". I have such one myself. Does it really prevent anyone from creating a new similar development? Should it?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7744314371842808263?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7744314371842808263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7744314371842808263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7744314371842808263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7744314371842808263'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/11/thoughts-on-open-source-licenses.html' title='Thoughts on Open Source licenses, Patents on Software and such'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-3982424262892893869</id><published>2010-09-20T00:26:00.000-07:00</published><updated>2010-09-20T00:39:55.776-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Resource Files</title><content type='html'>Programs interact with a user in many ways.&lt;br /&gt;They write things to a screen, send messages over the network, say things aloud. And more.&lt;br /&gt;&lt;br /&gt;In most cases, except maybe for debug logs, the string conveyed to the user shall be edited, and in some cases maybe even translated to other languages.&lt;br /&gt;&lt;br /&gt;It's pitty to still see today modules that interact with a user, without using external resource files. Guys - how do you want someone to edit your lovely messages into something readable? and translate it into Swedish? or Yiddish?&lt;br /&gt;&lt;br /&gt;The technical way of how to use resource file is a very old trick. The problem is that in the early days of a project, this is not the top prioirity (that's wrong, guys! the price at the beginning is very low!). The problem is that when it does become relevant, the code is full of strings in so many different places that it's a nightmare to do something.&lt;br /&gt;&lt;br /&gt;Things to do on the first day when starting a new project (don't postpone it to "later"):&lt;br /&gt;1. Use good logging mechanism (exiting one, don't invent the wheel)&lt;br /&gt;2. Use automatic build mechanism&lt;br /&gt;3. Use a resource file&lt;br /&gt;( -- do you have more - please add as a comment!)&lt;br /&gt;&lt;br /&gt;Well, wait I have one more - have a &lt;a href="http://softwareanimals.blogspot.com/2008/08/do-you-have-api.html"&gt;defined API&lt;/a&gt; (slash protocol slash wireframes) for the modules you are developing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-3982424262892893869?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/3982424262892893869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=3982424262892893869' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3982424262892893869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3982424262892893869'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/09/resource-files.html' title='Resource Files'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-6674813521494682924</id><published>2010-08-19T05:24:00.000-07:00</published><updated>2010-08-19T05:34:15.252-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Semi-colon and java.lang.OutOfMemoryError</title><content type='html'>&lt;span style="font-size:180%;"&gt;; ; ; ; ; ; ; ; ; ; ; ; ; ; &lt;/span&gt;&lt;span style="font-size:180%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I want to share with you a crash at customer site caused by java.lang.OutOfMemoryError.&lt;br /&gt;&lt;br /&gt;Here is the original code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;if (synchRemove(lobj.getSeqNum()) != null);&lt;br /&gt;&lt;span style="color:#ffffff;"&gt;____&lt;/span&gt;timeoutedList.add(lobj);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Can you see the problem?&lt;br /&gt;&lt;br /&gt;(Well it's much easier after the relevant lines of code are isolated. In reality it took a few days and nights to get to these lines, remember it occurred in customer environment where not all relevant info is easily available for the development team. The OOM doesn't necessarily occur at this line).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Moral:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Small semicolon can cause big troubles&lt;/li&gt;&lt;li&gt;It's hard to see everything in code review. A trouble-making redundant semicolon can skip the eyes of the reviewer&lt;/li&gt;&lt;li&gt;Load test may find such cases (but may still miss them, if the relevant scenario was not created)&lt;/li&gt;&lt;li&gt;Good unit tests may also help&lt;/li&gt;&lt;li&gt;Most Coding Guidelines require curly brackets for any block, even containing only one line. This could possibly reveal the error (if not by the developer, by the reviewer in code review)&lt;/li&gt;&lt;li&gt;Static code analysis tools, like &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt; – which is free, do point at such errors!&lt;/li&gt;&lt;li&gt;In some IDEs (e.g. Eclipse) you can configure the IDE to present warnings on such cases&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;in the above case, analyzing the heap dump, using &lt;a href="http://www.eclipse.org/mat/"&gt;MAT&lt;/a&gt;, led to the problematic giant list, then tracking all insertions into the list in the code, led to the faulty line.&lt;/p&gt;&lt;p&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/7061498094705606309-6674813521494682924?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6674813521494682924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6674813521494682924' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6674813521494682924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6674813521494682924'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/08/semi-colon-and-javalangoutofmemoryerror.html' title='Semi-colon and java.lang.OutOfMemoryError'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-1318273341046344198</id><published>2010-06-03T04:10:00.000-07:00</published><updated>2010-06-03T04:56:05.831-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>... and the UI is also going back</title><content type='html'>Following my last post on &lt;a href="http://softwareanimals.blogspot.com/2010/06/process-concurrency-are-we-stepping.html"&gt;concurrent processes&lt;/a&gt;, my good friend Effie Nadiv noted that the UI is also getting backwards.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/TAeP_26bDGI/AAAAAAAABZw/8K1s6irJGnY/s1600/sub-sub-sub-menu.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5478505798954585186" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 250px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/TAeP_26bDGI/AAAAAAAABZw/8K1s6irJGnY/s400/sub-sub-sub-menu.jpg" border="0" /&gt;&lt;/a&gt;Back in the old days, Lotus 1-2-3 had a menu line that was not opening to overlay your main screen but was instead changing the menu line each time you make a menu selection. One can argue that this is not optimal, but I remember it as something very useful. Today in some cases you find yourself struggling to open the sub-sub-sub-menu to select something, trying not to close the entire thing before you make your selection.&lt;br /&gt;&lt;br /&gt;It becomes also a common practice that any new dialog or window may hide previous ones, extra info may hide the main data etc. Effie argues that it all becomes from the philosophy that the application may do whatever it wants. Restrictions would heart creativity and we don't want that. So you have creativity in the new versions: my new version of Babylon has a fancy UI, ignoring the fact that it is not working, and the old one with the standard Windows UI was OK, it's a real charm. The new office is a nightmare, after you got used to something. Any new version of a SW tries to justify itself with a new fancy visual design which you don't want. You just want it to work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1318273341046344198?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1318273341046344198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1318273341046344198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1318273341046344198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1318273341046344198'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/06/and-ui-is-also-going-back.html' title='... and the UI is also going back'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/TAeP_26bDGI/AAAAAAAABZw/8K1s6irJGnY/s72-c/sub-sub-sub-menu.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-2138263189851185747</id><published>2010-06-03T02:25:00.000-07:00</published><updated>2010-06-03T04:10:40.084-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><title type='text'>Process Concurrency - are we stepping ahead or backward?</title><content type='html'>The first version of Apple's iPad allows only one running process. A bit limited, but most people reported high satisfaction. On the other hand, my OS allows for multi processes to run in parallel and it starts to turn me crazy.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#000099;"&gt;Why process concurrency is a BAD THING&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You are showing a presentation and suddenly some pop-up from another process pops&lt;/li&gt;&lt;li&gt;Doing a critical debugging task, you are all focused and sharpened, but then your machine starts being sluggish as some background process decides to take CPU time or memory&lt;/li&gt;&lt;li&gt;You open your task manager to understand why your machine is so sluggish and see a list of so many processes. What's all that? I don't need half of it. Though, the first "terminate" that you try shuts down the system.&lt;/li&gt;&lt;li&gt;Any utility today can decide to run in your background, to really control what runs in your background you need to be an expert, otherwise you lose your background to all sort of things you really don't know much about.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color:#000099;"&gt;How often do you click Ctrl+ALT+Del?&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;I find myself at least once a day using the Ctrl+ALT+Del to check what's holding my machine. How about you?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color:#000099;"&gt;So, how was it back then, in the good old times?&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In DOS, you could have only one process running. If you wanted to jump to another without closing your application you could use &lt;a href="http://en.wikipedia.org/wiki/Terminate_and_Stay_Resident"&gt;TSR&lt;/a&gt; but you could have only one TSR pop at a certain time, and when it was at the background it took NO resources, it just set there waiting for an interrupt without making any sigh.&lt;/p&gt;&lt;p&gt;The un-responsiveness that we get today from our systems is unbearable. Applications decide to go at the background to update themselves, or to index the file system, or to do other non-critical task. The feeling is that the resources of the machine &lt;em&gt;are not yours&lt;/em&gt;. You are lucky if the machine throws a bone at you giving you some resources.&lt;/p&gt;&lt;p&gt;The user experience you get today on a quad core, xGhz CPU with xGB fast RAM are worse than what you got on an old old x8086 machine, 1000 times weaker. The difference is that the old applications were much more focused on being lean and mean, never went to the net during their operation (the web was BBS and gopher), and they didn't run in parallel.&lt;/p&gt;&lt;p&gt;We need to go back to the old approach, giving the stage to one application at a time - all other would be HALTED and would not take any system resources. It sounds so limiting, but this is how DOS used to work. And this is how the first version of iPad works.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2138263189851185747?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2138263189851185747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2138263189851185747' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2138263189851185747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2138263189851185747'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/06/process-concurrency-are-we-stepping.html' title='Process Concurrency - are we stepping ahead or backward?'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-8536571224111155765</id><published>2010-05-31T07:45:00.000-07:00</published><updated>2010-06-03T08:42:10.777-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Java Unit Testing</title><content type='html'>There are a lot of tools and options out there for java unit testing, replacing JUnit or on-top of JUnit. Let's do some order in things.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;1. &lt;a href="http://testng.org/"&gt;TestNG&lt;/a&gt; vs. &lt;a href="http://www.junit.org/"&gt;JUnit4&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;TestNG came out to add features that were missing in JUnit 3.x.&lt;br /&gt;It did quite a good job and some may say that TestNG 5.10+ is still better than JUnit 4.7+&lt;br /&gt;TestNG has better data providing mechanism.&lt;br /&gt;TestNG has test dependency definition, missing in JUnit.&lt;br /&gt;TestNG has group level with fixtures on group. And it also has the ability to create automatic run file for all failed tests.&lt;br /&gt;All that said, JUnit has more extending libraries using its ability to extend JUnit TestCase and JUnit TestRunner.&lt;br /&gt;Both have very good IDE support, as well as Ant and Maven support.&lt;br /&gt;&lt;br /&gt;Coming to choose, both are good. &lt;strong&gt;I stick with JUnit&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Note that JUnit 4 made the mistake of integrating another library into its jar, that is the &lt;a href="http://code.google.com/p/hamcrest/"&gt;hamcrest&lt;/a&gt; core. They should have known better than that... The problem is that when you get the &lt;a href="http://code.google.com/p/hamcrest/downloads/list?q=hamcrest-all-in-one-jar"&gt;full hamcrest lib&lt;/a&gt; (to get the really powerful matchers that you need in your tests) it gets confused with the lib that came with JUnit. Solution is simple: put the full hamcrest that you bring to be first in the classpath, before the JUnit jar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2. Load&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://clarkware.com/software/JUnitPerf.html"&gt;JUnitPerf&lt;/a&gt; do the job with its ability to run tests in several threads.&lt;br /&gt;It's easy and useful, for integration stage and for any piece of code that may act differently under load.&lt;br /&gt;&lt;br /&gt;The following code was tested with JUnitPerf and it catches the bug of not synchronizing the addIfAbsent:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;public class MyList extends ArrayList&lt;br /&gt;// we test with the synchronized and without&lt;br /&gt;public &lt;u&gt;synchronized&lt;/u&gt; boolean addIfAbsent(Object o)&lt;br /&gt;boolean absent = !super.contains(o);if(absent) {&lt;br /&gt;super.add(o);&lt;br /&gt;}&lt;br /&gt;return absent;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The test that catches the bug when the synchronized is deleted:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;public class MyListTest extends TestCase {&lt;br /&gt;private MyList myList = new MyList();&lt;br /&gt;private int count = 0;&lt;br /&gt;MyListTest(String name) {&lt;br /&gt;super(name);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;TestSuite suite = new TestSuite();&lt;br /&gt;Test testToRun = new MyListTest("testMyList");&lt;br /&gt;int numUsers = 1000;&lt;br /&gt;int iterations = 5;&lt;br /&gt;suite.addTest(new LoadTest(testToRun, numUsers, iterations));&lt;br /&gt;return suite;&lt;br /&gt;}&lt;br /&gt;public void testMyList() {&lt;br /&gt;if(myList.addIfAbsent(count)) {&lt;br /&gt;// there is a gap here that may cause error on correct&lt;br /&gt;// implementation, in case of thread switch at this point&lt;br /&gt;synchronized (this) {&lt;br /&gt;++count;&lt;br /&gt;assertEquals(myList.size(), count);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000000;"&gt;This solution is not bullet proof.&lt;br /&gt;&lt;/span&gt;Theoretically it may give errors on correct scenario, and of course it can always miss bad implementation, as it’s a matter of timing.&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#ff6600;"&gt;However, in reality it does catch the problem!&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;JUnitPerf is simple and gets the job done.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3. Thread testing&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;It could be nice if we could have time the behavior of the code under test, to mimic race conditions and check how the code operates. The idea is to deliberately create race condition then to check that a synchronization lock is working as expected, ensure that unlocked blocks are fine, check for deadlocks and see if there data corruption.&lt;br /&gt;&lt;br /&gt;With such ability we could have create the race condition in the above code with a deterministic approach instead of using load.&lt;br /&gt;&lt;br /&gt;Suggested tools:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;&lt;a href="http://code.google.com/p/thread-weaver/"&gt;thread-weaver&lt;/a&gt;&lt;/u&gt; (version 0.1)&lt;br /&gt;allows the test to time different threads reach code points in a certain order, either explicitly or “semi-automatically”&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;&lt;a href="http://code.google.com/p/multithreadedtc/"&gt;MultiThreadedTC&lt;/a&gt;&lt;/u&gt; (version 1.01)&lt;br /&gt;allows to set time tickers on objects in the test itself, but NOT on the tested code, thus less relevant for most testing purposes &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Both tools are not highly supported, &lt;strong&gt;recommending still not to rush into it…&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;strong&gt;4. Mock Objects&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;There are 3 cases where you need a Mock Object in your test:&lt;br /&gt;&lt;br /&gt;(a) Tested code gets a complicated object as parameter&lt;br /&gt;&lt;u&gt;Solution&lt;/u&gt;: Mock the parameter with a Stub/Mock implementation&lt;br /&gt;&lt;br /&gt;(b) Tested code invokes a static call on some resource&lt;br /&gt;&lt;u&gt;Solution&lt;/u&gt;: Replace the static call with a Stub/Mock implementation&lt;br /&gt;&lt;br /&gt;(c) Tested code creates complicated objects&lt;br /&gt;&lt;u&gt;Solution&lt;/u&gt;: Replace the created objects with a Stub/Mock implementation&lt;br /&gt;&lt;br /&gt;The Mock utilities rely on one of the following technologies: java.reflection.Proxy, replacing the ClassLoader, byte code instrumentation and AOP weaving (which relies by itself on replacing the ClassLoader or on byte code instrumentation).&lt;br /&gt;&lt;br /&gt;Possible tools: Mockito, JMock, JMockit, EasyMock, JEasyTest and many others…&lt;br /&gt;&lt;br /&gt;There are differences between the tools in syntax and abilities.&lt;br /&gt;Tools that rely on Proxy cannot mock static behavior and object creation.&lt;br /&gt;&lt;br /&gt;The two possibile combinations that came to my final round were:&lt;br /&gt;(a) &lt;a href="http://code.google.com/p/jmockit/"&gt;JMockit&lt;/a&gt; 0.998&lt;br /&gt;(b) &lt;a href="http://easymock.org/"&gt;EasyMock&lt;/a&gt; 3.0 + &lt;a href="http://code.google.com/p/powermock/"&gt;PowerMock&lt;/a&gt; .1.3.8&lt;br /&gt;&lt;br /&gt;JMockit seems powerful and well documented, but in one of my tests the test failed without a reason and when I debugged it I saw that some exception is thrown within the JMockit code itself. Probably I did something wrong in the test, but still this is not what I expect for. Maybe the 1.0 version would be better...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;My selection here would be EasyMock + PowerMock &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;5. Other tools&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Other tools in this domain worth mentioning:&lt;br /&gt;- &lt;a href="http://www.dbunit.org/"&gt;DBUnit&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://httpunit.sourceforge.net/"&gt;HttpUnit&lt;/a&gt; (not only for tests)&lt;br /&gt;- &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; (it is a good tool for Web UI tests in general, and you can operate it from your java unit tests if you'd like)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-8536571224111155765?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8536571224111155765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8536571224111155765' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8536571224111155765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8536571224111155765'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/05/java-unit-testing.html' title='Java Unit Testing'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-381870574006944228</id><published>2010-04-14T04:58:00.000-07:00</published><updated>2010-06-06T22:27:30.297-07:00</updated><title type='text'>Beware of your long tail garbage</title><content type='html'>IBM’s PLDE seminar 2010 (&lt;a href="https://www.research.ibm.com/haifa/Workshops/plde2010/program.shtml" target="_blank"&gt;IBM Programming Languages and Development Environments Seminar 2010&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;An interesting session by Kathy Barabash on GC running with parallel cores raises an important note I haven't thought about: long referenced tails are harder for the GC to parallelize, as the GC cannot break long list efficiently into two threads. Thus if you create references with long distance from the root (local or static reference), your GC time would be longer compared to same number of references in a more spread structure.&lt;br /&gt;XALAN seem to sin with the above.&lt;br /&gt;&lt;br /&gt;Gilad Bracha opened with a overview of mistakes done by Java 1.0 which are living in Java till these days.&lt;br /&gt;&lt;br /&gt;Gili Nachum writes on the above two in his JavaTuning blog:&lt;br /&gt;&lt;a href="http://www.javatuning.com/ibms-plde-seminar-2010-review/"&gt;http://www.javatuning.com/ibms-plde-seminar-2010-review/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-381870574006944228?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/381870574006944228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=381870574006944228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/381870574006944228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/381870574006944228'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/04/beware-of-your-long-tail-garbage.html' title='Beware of your long tail garbage'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-5024736528468276177</id><published>2010-03-10T20:47:00.000-08:00</published><updated>2010-03-10T21:12:54.564-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><title type='text'>Cisco new router deliverring 322 Tbit/s</title><content type='html'>Cisco announced a new core router, named CSR-3, delivering 322 Tbit/s:&lt;br /&gt;&lt;a title="http://www.lightreading.com/document.asp?doc_id=" href="http://www.lightreading.com/document.asp?doc_id=188914&amp;amp;"&gt;http://www.lightreading.com/document.asp?doc_id=188914&amp;amp;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My brother-in-law is part of this project. I'm not sure whether his part is the extra 22 Tera bits beyond 300, but he is there inside for the past years and has a major role there.&lt;br /&gt;&lt;br /&gt;Whether this is a world shocking event for the internet world or not we will see, but for sure this is a landmark, comparing to the 56K b/sec not long ago (well, this is not an honest comparison, comparing home pace to core, but still the rate at the core level got from gigs to teras - factor of 1,000).&lt;br /&gt;&lt;br /&gt;It's a very happy declaration for companies doing video services, IPTV etc. Of course there is still the need to propagate these paces to the homes, with fiber to the home, but this is already happening at some countries and will expand (&lt;a href="http://www.ftthcouncil.eu/home/latest_news/latest_news/hong_kong_operator_announces_more_local_ftth_subscribers_than_any_country_in_europe/?cid=37&amp;amp;nid=498&amp;amp;catid=8"&gt;Hong Kong&lt;/a&gt;, &lt;a href="http://www.ftthcouncil.eu/home/latest_news/latest_news/fibre_to_the_home_for_every_citizen_in_the_hague/?cid=37&amp;amp;nid=521&amp;amp;catid=8"&gt;Hague&lt;/a&gt;, &lt;a href="http://www.ftthcouncil.eu/home/latest_news/latest_news/orange_will_invest_2_billion_euro_in_ftth/?cid=37&amp;amp;nid=515&amp;amp;catid=8"&gt;more Europe&lt;/a&gt;, and it happens that &lt;a href="http://news.yahoo.com/s/afp/20100303/tc_afp/usitcompanytelecominternetgoogleoffbeat"&gt;Kansas city&lt;/a&gt; even changed its name to get fiber).&lt;br /&gt;&lt;br /&gt;With 322 Tbits/s it sounds that someone needs to really start working on teleporting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5024736528468276177?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5024736528468276177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5024736528468276177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5024736528468276177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5024736528468276177'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/03/cisco-new-router-deliverring-322-tbits.html' title='Cisco new router deliverring 322 Tbit/s'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-5520229796457400870</id><published>2010-02-16T08:26:00.000-08:00</published><updated>2010-02-16T08:39:24.413-08:00</updated><title type='text'>Multiple Inheritance - should you?</title><content type='html'>It is often argued that multiple inheritance in C++ is not a good practice. This is why Java doesn't have this ability. Of course, multiple inheritance in C++ for something that is similar to interface implementation as in Java is reasonable, this is the case when all classes inherited from are pure abstract with no data members and no implementaions, only pure virtual methods, except one base which is the true parent.&lt;br /&gt;&lt;br /&gt;However, in some cases you do see in C++ multiple inheritance that is not just interface implementation. And in some cases it seems reasonable. The iostream library is using it quite a lot.&lt;br /&gt;&lt;br /&gt;I had a code review in which the developer used multiple inheritance. He said he was considering whether to use it or not and decided it serves his goal. Indeed it was OK, there was a class "SomeSortOfEventHandler" that was of both types "A_CertainEventHandler" and "AnotherKindOfEventHandler", that is, the "SomeSortOfEventHandler" was in fact handler for two kinds of events. In this case there was no need for virtual inheritance from the top parent ("AbstractEventHandler"), as the special "SomeSortOfEventHandler" need to have the data and behavior of both its parents.&lt;br /&gt;&lt;br /&gt;So far so good. But at a certain point there was a need to implement a virtual method in two flavors, one for being the child of one parent and the other for being the child of the other. This becomes nasty. One can add to the virtual method a parameter of type T (there is a template class at the top, that differentiate the different families under "AbstractEventHandler") - but this is not so elegant as there is no real need for this parameter. All other alternatives were also breaking the elegancy of the inheritance tree. Conclusion: better to create two separate classes and hold a pointer from one to the other to get the relation between two objects, rather than use multiple inheritance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5520229796457400870?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5520229796457400870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5520229796457400870' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5520229796457400870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5520229796457400870'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2010/02/multiple-inheritance-should-you.html' title='Multiple Inheritance - should you?'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-5685529536810111979</id><published>2009-11-22T06:48:00.000-08:00</published><updated>2009-11-22T09:01:36.189-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Array of Generic Type</title><content type='html'>&lt;span style="font-family:arial;"&gt;I was asked why one cannot create an array of generic type, which means this line cannot compile:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;// the below doesn't compile&lt;br /&gt;ArrayList&amp;lt;Integer&amp;gt;[] arrayOfLists = new ArrayList&amp;lt;Integer&amp;gt;[7];&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The compiler doesn't like the creation part, on the right, while the declaration alone, on the left, goes fine. This issue is widly discussed, e.g. nicely described &lt;a href="http://stackoverflow.com/questions/470198/java-generics-and-array-initialization"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are many ideas why it is forbidden and many suggestions for workarounds. But the nice colleague who asked me this question liked the most the workaround I suggested him, which is very simple.&lt;br /&gt;&lt;br /&gt;I started by asking why he needs this.&lt;br /&gt;&lt;br /&gt;And he explained that he needs to manage some info for 7 days a week:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;// the below doesn't compile&lt;br /&gt;ArrayList&amp;lt;SomeInfo&amp;gt;[] weeklyInfo = new ArrayList&amp;lt;SomeInfo&amp;gt;[7];&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I suggested to create two new classes, DailyInfo and WeeklyInfo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;class DailyInfo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private ArrayList&amp;lt;SomeInfo&amp;gt; dailyInfo = new ArrayList&amp;lt;SomeInfo&amp;gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class WeeklyInfo {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private DailyInfo[] dailyInfo = new DailyInfo[7];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In most cases this would be the right object oriented approach, which by the way solves the problem of array of generic type.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5685529536810111979?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5685529536810111979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5685529536810111979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5685529536810111979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5685529536810111979'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/11/array-of-generic-type.html' title='Array of Generic Type'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-6958712630048859015</id><published>2009-10-07T23:02:00.000-07:00</published><updated>2009-10-08T10:55:49.962-07:00</updated><title type='text'>m and n have switched on my keyboard...</title><content type='html'>&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;The letters 'm' and 'n' have been switched. I type 'm' and it comes out as 'n'. I remember something about a virus so I run my anti-virus (no result) and search the web (some results).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cone om! I’n beconimg imsame!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;It's so annoying. Maybe someone is fooling around with me.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;A quick glance at another keyboard: it's not that 'm' types 'n' -- the keys themselves changed places... each sits at the other one's location. A quick pull of the keys,&amp;nbsp;stucking them again&amp;nbsp;back into their right position and everything is great!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;After a short investigation it appears that my 6 years old son, who is using my computer for playing, accidentally popped out the 'm' and 'n', then put them again&amp;nbsp;in place quickly before I'll notice. Well, almost in place... He didn't intentinally planned for giving me a hoax, though it came out quite a good one for his age.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6958712630048859015?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6958712630048859015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6958712630048859015' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6958712630048859015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6958712630048859015'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/10/m-and-n-have-switched-on-my-keyboard.html' title='m and n have switched on my keyboard...'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-6183527907867502454</id><published>2009-09-23T06:23:00.000-07:00</published><updated>2009-09-23T13:47:36.453-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Auto-unboxing hazard -- the three states of Boolean: TRUE, FALSE, and...</title><content type='html'>&lt;span style="font-family:arial;"&gt;What do you say about the following code:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    if(isActive) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;        // dosomething&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If you are worried about the casting to Boolean in case where attribute &lt;span style="font-size:85%;"&gt;IS_ACTIVE&lt;/span&gt; doesn't exist, don't worry, it's OK to cast null to any type, null stays null.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;So, is it OK?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Well, no. The problem is with the auto-unboxing to primitive type boolean, which throws NullPointerException if the Boolean is null. Which is a bit hidden from the programmer who might miss this hazard when writing the code.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;How should we fix it?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Is the following a decent fix:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);&lt;br /&gt;    if(isActive) {&lt;br /&gt;        // dosomething&lt;br /&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If you ask "what's the fix?" - we turned the variable isActive to be Boolean rather than boolean. Which should eliminate any NullPointerException on the first line! But only in order to pass the exact same NullPointerException into the 'if'...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;So, what about:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);&lt;br /&gt;    if(isActive.booleanValue()) {&lt;br /&gt;        // dosomething&lt;br /&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Yes, you are right, same NullPointerException. Maybe now even more explicit.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;We could go with:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);&lt;br /&gt;    if(isActive != null &amp;amp;&amp;amp; isActive) {&lt;br /&gt;        // dosomething&lt;br /&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;But I believe this looks better:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);&lt;br /&gt;    if(Boolean.TRUE.equals(isActive)) {&lt;br /&gt;        // dosomething&lt;br /&gt;    } &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6183527907867502454?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6183527907867502454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6183527907867502454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6183527907867502454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6183527907867502454'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/09/auto-unboxing-hazard-three-states-of.html' title='Auto-unboxing hazard -- the three states of Boolean: TRUE, FALSE, and...'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-3522012151577175328</id><published>2009-09-22T23:05:00.000-07:00</published><updated>2009-09-22T14:10:21.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Frameworks -- Explicit and Implicit Wiring</title><content type='html'>&lt;span style="font-family:arial;"&gt;In any new project, there is that moment when you are reflecting whether a group of classes belong to the package "core" or "utils" or "framework", or whether you need all these three altogether. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SrkTw_as-vI/AAAAAAAABDk/r40GZqjB28Y/s1600-h/wiring.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SrkjHk267cI/AAAAAAAABDs/x_M1u6KI-5s/s1600-h/AutoWiring.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5384373442558225858" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 311px; CURSOR: hand; HEIGHT: 177px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SrkjHk267cI/AAAAAAAABDs/x_M1u6KI-5s/s400/AutoWiring.gif" border="0" /&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;The difference between utils, framework and core should be simple. Utils are the basic functions needed by everyone, mostly unrelated to this specific project. They are all stateless by definition, simple input and output, with no dependency with the project's structures. Utils can always be easily tested as stand alone. Core is the basic stuff. The stuff you would direct a new developer to learn first. It is project specific. It may include the basic types relevant for this project, interfaces, enums, project's basic exceptions, etc. Make sure to avoid making it a trash can. It's not the address for things without a context.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Framework is the tricky one of all three. As opposed to "utils", the role of "framework" as suggested by its name is more complex. A framework is a piece of behavior interacting with other code to represent a real, concrete, runtime behavior. Usually, even if built specifically for this project, it has some generic characteristics, it is written in a way that could be extended, or used in the future in other ways that we don't see currently. For this we use design patterns like strategy, command, visitor, and in fact almost any that you can think of, to create some kind of "dynamic behavior", or "dynamic wiring". Which means that the framework describes a behavior, but not entirely, only an exact usage can describe an end-to-end scenario. This is why frameworks are best explained with an example (while utils can be explained by what they simply do).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;There are good frameworks and bad ones. EJB in its first versions for example was horrible (some don't like it till today, a first bad impression is hard to fix). JDBC is a good framework. Java-Servlets is a good framework. What makes good frameworks good is that people find them easy to use, they save development time copmpared to other alternatives, and you would usually find over time very few versions of the same good framework (and the new versions would be fully compatible with old code). Of course the question is how to achieve this simplicity, real contribution and long-run future compatibility.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;When designing and implementing a framework, occasionally you want to make life easier for the user by doing something automatic for him, let's say pass the value of some field into another field with a relevant name convention -- thus the user doesn't have to write a single line of code! There is this trick in the framework which does it for him. Let's call it "implicit wiring". Alternatively, you may expose to the user a way to acquire the value and require him to pass it explicitly by writing his own code. Let's call it "explicit wiring".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;In some cases the difference is not so obvious. Suppose you have a controller which may implement many kinds of behavior, if not implemented than a default behavior is used by the framework. When the number of different behaviors of this controller start to inflate, things become a bit obscure, unreadable, thus maybe "implicit". A better approach would be to break the controller to different interfaces and allow the user to implement the interfaces representing the relevant behavior for him, thus checked by the compiler that no method is accidentally left out, more readable and "explicit". &lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;This discussion came out recently with my team member Effie. We had a reference between two UI elements, "table" and "toolbar". I suggested that if "table" doesn't declare on its referenced counterpart "toolbar" than we will assume by default that it relates to a toolbar with some predefined name (e.g. "toolbar"). That way, I said, even if the user forgot to give a name for his toolbar, things would work nicely.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;Effie's reaction was a bit frightening. (Well, not for someone who knows him). It is common in our work environment that a worker shouts at his boss. Which happened in this case. "I'm not working this way, if you want such a framework leave me out of it", was the part I can quote. Of course when he chilled out came the explanation. Implicit wiring is the base of all framework sins. I like such semi-emotional semi-professional reactions! And he was totally right. Think of someone trying to understand how the framework connects a toolbar to a table. And if he wants to add now another table and toolbar how can he do it? True, there is still the explicit way of referencing by name, but once I entered the implicit way, most cases would be using the implicit format which makes the explicit less known and less documented in examples. Also, implicit wiring tends to break over time, as at some point it may collide with something else and break old code. On the other hand, if you allow only the explicit way, all examples would present the explicit way, code would be always more simple to understand and maintain, and less prone for future incompatibilities. Even with the costs of higher efforts in the first implementation, explicit shall win.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;Frameworks in their nature do things behind your back. Try to narrow this behavior as much as you can. Make things explicit as much as possible. Less to explain and document and more for your framework future compatibility.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-3522012151577175328?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/3522012151577175328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=3522012151577175328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3522012151577175328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3522012151577175328'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/09/frameworks-explicit-and-implicit-wiring.html' title='Frameworks -- Explicit and Implicit Wiring'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SrkjHk267cI/AAAAAAAABDs/x_M1u6KI-5s/s72-c/AutoWiring.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-8050019604651302541</id><published>2009-09-22T14:11:00.000-07:00</published><updated>2009-09-22T15:06:55.974-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Write? Rewrite? Use? - Thoughts on shaky frameworks</title><content type='html'>&lt;span style="font-family:arial;"&gt;Java is a great language. A great framework, tool, environment, libraries, all of that. From the very beginning the designers of Java thought of almost anything. Well, almost. ResourceBundle didn't support UTF-8 till Java 6! A few bugs were opened on that during the years (&lt;/span&gt;&lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4093632"&gt;&lt;span style="font-family:arial;"&gt;4093632 &lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;from 1997, &lt;/span&gt;&lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4221013"&gt;&lt;span style="font-family:arial;"&gt;4221013&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; nicely written, &lt;/span&gt;&lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4749531"&gt;&lt;span style="font-family:arial;"&gt;4749531&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; begging, &lt;/span&gt;&lt;a href="http://bugs.sun.com/view_bug.do?bug_id=4919638"&gt;&lt;span style="font-family:arial;"&gt;4919638&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; and &lt;/span&gt;&lt;a href="http://bugs.sun.com/view_bug.do?bug_id=6204853"&gt;&lt;span style="font-family:arial;"&gt;6204853&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; giving a final attempt, probably missing some). But it took a long time for someone to listen.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Were they drunk those guys? localization with support only for ISO-8859-1? are you nuts?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Yes, you could use escaped unicode (like '\uXXXX'), but it's not readable. Yes, you could use a UTF-8 file and escape your unicode as part of your build process (native2ascii). Some IDEs (netbeans) volunteered to do this automatically for you. But this is still bad.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Luckily for us, in Java 6 you can construct a PropertyResourceBundle with a Reader, thus you can create a Reader based on UTF-8. Or maybe not so luckily? The ResourceBundle.getBundle still works the old way, you cannot ask it to use UTF-8, so they hacked only half way - what the point? (Yes, you can use the Java 6 ResourceBundle.Control class to control the creation of your bundles but it's so lame. I implemented it and it works, but amount of code needed for such a simple task is unreasonable).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Here comes the question: should we use this problematic framework or write our own implementation? After all, it's not rocket science.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Usually I tend to be very careful with suggesting "write your own version of it". Our development instinct is usually seeing the flaws in some existing implementation, convincing our boss that we must write our own new version of it. In many cases our new version misses some important parts that the preexisting implementation already handled. In some cases the drawbacks that we saw in the preexisting code are in fact design decisions required in order to deal with scenarios that we don't think of or ignore and may tackle us later. So when I do see some existing commonly used library I'm very careful before I decide it's not good for me.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I found &lt;/span&gt;&lt;a href="http://www.thoughtsabout.net/blog/archives/000044.html"&gt;&lt;span style="font-family:arial;"&gt;this suggested implementation&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. Seem much easier than the way to do that with the bone thrown at us with Java 6.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Still, might be not so bad idea to implement the entire thing, load of resource bundle, by myself. I still hesitate.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-8050019604651302541?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8050019604651302541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8050019604651302541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8050019604651302541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8050019604651302541'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/09/write-rewrite-use-thoughts-on-shaky.html' title='Write? Rewrite? Use? - Thoughts on shaky frameworks'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7041959596558036683</id><published>2009-08-14T13:38:00.000-07:00</published><updated>2009-08-15T14:12:00.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Off-Shore'/><title type='text'>Technology Optimism</title><content type='html'>&lt;span style="font-family:arial;"&gt;At the time of massive cutoffs, transition of positions to low-cost centers and the sour smell of pessimism in the air -- I feel the spirit of Technology Optimism.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;During the good times, the finest people with the brilliant ideas are sucked into the big corporations, tempted by nice salaries and all other perks. In many cases what they do in such positions is to work hard on projects that are later being shutdown. Let's admit, the big corporations are good at raising the money and selling the product, but when it comes to innovation, best innovative trick is to find the right startup to acquire. And this goes also for great innovative companies like google (GoogleMaps, GoogleVoice and many more are based on external acquisitions, see &lt;a href="http://en.wikipedia.org/wiki/List_of_acquisitions_by_Google"&gt;Wikipedia - List of acquisitions by Google&lt;/a&gt;).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;There is a great advantage in a crisis, being a tool in reforming the market back to an efficient structure. We need more innovation and much more efficient companies.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Many brilliant people who have been back into the market lately are fed up working for giant dinosaurs, and start working on their own new startups. It may be hard at this point to raise the initial capital, but these startups are thin and efficient. And in a year or two we will start seeing the results with new technology domains that we couldn't imagine before.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7041959596558036683?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7041959596558036683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7041959596558036683' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7041959596558036683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7041959596558036683'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/08/technology-optimism.html' title='Technology Optimism'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-1442768977954455565</id><published>2009-08-13T14:15:00.000-07:00</published><updated>2009-08-15T15:04:33.334-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><title type='text'>When a bug makes you crazy</title><content type='html'>&lt;span style="font-family:arial;"&gt;This week I was sitting on one of those bugs which almost make you scream. Something is wrong, but you cannot find what creates this f-word behavior.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I was working on some web page example for some Taglib framework, but the page insisted on having an extra element that I didn't create. And when picked using FireFox, it pointed at a node in the XHTML that I'm definitely not rendering...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Nothing in the code should make this happen. First suspicion is that I'm running an old instance, so I'm running a clean+compile and restarting the server, then when this doesn't change anything I'm adding a printout just to make sure. The new printout appears. Damn! I'm running the code that I'm looking at, but nothing there seems to be responsible for this result.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I know that &lt;a href="http://softwareanimals.blogspot.com/2008/04/do-you-have-theory.html"&gt;in order to debug I need a theory&lt;/a&gt;. But I cannot raise any theory, as clearly the result that I see is not something that is in the code... So I start playing (though I know it's not the methodic way for debugging, but I'm trying to play methodically). I find all places where I render this kind of element that is being rudely added where not belonged and I mark them each with a unique id. The id appears. Now I can identify the exact place that is responsible for this behavior, but I can't understand why it happens. An XHTML tag is added in a place in the document that surely I'm not printing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;It took me some time. Maybe too much time. But I understand now that FireFox tree view of the page is cheating me... The element that FF is presenting at a certain place on the tree cannot be there. I'm not printing it there. Suddenly a strike hits me: &lt;strong&gt;GET BACK TO THE BASICS&lt;/strong&gt;. Instead of using FireFox to locate for me the wicked node, let's view the source of the page. How simple and basic, though yet I spent about an hour before thinking about this simple thing.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;And indeed, when viewing the page source I see that the problem is that I'm opening some HTML tag somewhere and not closing it, but FF closes it for me way beyond this point, creating a very strange node that I didn't create. In the treeview of the page FF presented a tag with a start and an end, while I accidentatlly opened a tag at some point and didn't close it. Now it's much easier to see the problem. And I also note that indeed FF showed that there are errors on page, with this error listed.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Moral&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;When the tool you debug with shows something that you cannot explain, go back to the basics: tcpdump, sniffer, printouts. The debug tool may be misleading you!&lt;br /&gt;Believe only to bits and bytes, not to any fancy tool.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;If you are working on a Web page, first look at the "errors on page", if you always insist on first fixing these you will save valuable time.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;When a bug makes you crazy look him in his eyes, tell him that you will beat him. Don't show any weakness signs as these bastards know well how to recognize such signs.&lt;/span&gt;&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/7061498094705606309-1442768977954455565?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1442768977954455565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1442768977954455565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1442768977954455565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1442768977954455565'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/08/when-bug-makes-you-crazy.html' title='When a bug makes you crazy'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-8325062185805302983</id><published>2009-07-02T04:35:00.000-07:00</published><updated>2009-08-15T14:12:31.333-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><title type='text'>IE is a pain in the ass</title><content type='html'>&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Back in the old days when there were Internet Explorer (IE) and Netscape, everybody knew that it is very difficult to write something that would run perfectly on both. But since it was only two dominent browsers not many pointed the finger at IE. It was just that the two are different, life is challenging what could you say.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Today, when you have Opera and Chrome and Safari and FireFox -- ALL BEHAVING THE SAME -- and IE in his own realm, it is much easier to point the finger.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;And here are some who do point the finger:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://whyiesucks.blogspot.com/"&gt;http://whyiesucks.blogspot.com/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://iesucks.net/"&gt;http://iesucks.net/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://zipthefuckup.com/2009/03/31/ie-is-a-pain-in-my-ass/"&gt;http://zipthefuckup.com/2009/03/31/ie-is-a-pain-in-my-ass/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://empireenterprises.com/noie.html"&gt;http://empireenterprises.com/noie.html &lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://www.techsupportforum.com/design-forum/web-design-programming/111095-css-firefox-good-ie-bad.html"&gt;http://www.techsupportforum.com/design-forum/web-design-programming/111095-css-firefox-good-ie-bad.html&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;a href="http://channel9.msdn.com/forums/Coffeehouse/427835-Why-is-IE-so-bad/"&gt;http://channel9.msdn.com/forums/Coffeehouse/427835-Why-is-IE-so-bad/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;and there are more, just google for IE sucks or IE pain in the ass. Which it is, for most web developers.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;It's nice to see that the other browsers do have a strict implementation according to the W3C standards, resulting with uniform behavior and ease of development. It says good things on the W3C standards being well defined and about the discipline of the coders of the other browsers, as opposed to IE.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Microsoft needs to drop IE altogether, start with a new code base and a new brand name, the current one is ruined.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&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/7061498094705606309-8325062185805302983?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8325062185805302983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8325062185805302983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8325062185805302983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8325062185805302983'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/07/ie-is-pain-in-ass.html' title='IE is a pain in the ass'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-8038122829658824577</id><published>2009-06-23T23:28:00.000-07:00</published><updated>2009-06-24T05:22:54.149-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>JavaDay, JavaOne - Java Thoughts</title><content type='html'>&lt;span style="font-family:arial;"&gt;I was attending Sun's Java Day this week, here in Israel. The main themes Sun is pushing are JavaFX and MySQL.&lt;br /&gt;&lt;br /&gt;Some thoughts on both, as well as other topics.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;JavaFX&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Sun's interest here is clear. Every handset or any sort of device running JavaFX means more licensing fees for Sun. In fact, JavaME is one of the only Java environments which Sun's really see money from, at least for now. This would probably change in the future with much more agressive sell of JavaSE licenses for extra features and support, but still handsets is a very important addressable market, competing with others technologies such as the simple browser, Android, iPhone Objective-C, etc. Sun interest is to have as many applications as possible running on top of JavaME, JavaFX and LWUIT (the last two are a bit competing on the same square). More applications means more consumer power (consumers who want to run these applications) thus more pressure on the handsets manufectures to have JavaME and JavaFX on the handset, droping the required license fee at Sun's pocket.&lt;br /&gt;&lt;br /&gt;All fine till this point. But now it comes to JavaDay event, or JavaOne conference in SF. These events shall reflect what interests the Java community, be judgmental, compare competing technologies. But instead it becomes more and more a marketing event for what Sun is trying to push. Thus, JavaFX catch very high percents of all sessions (even a session on Maven had to be called "Deploying JavaFX apps with Maven" or something alike to get in...) And it is totally lacking the critic perspective, comparing with other competing technologies such as Android, GWT, zool, YUI, Adobe AIR etc.&lt;br /&gt;&lt;br /&gt;Is JavaFX interesting? probably yes, but not at the amounts poured at us.&lt;br /&gt;&lt;br /&gt;As for the judgmental perspective, I'm missing in JavaFX the separation between content and style, without that this would be a step back. Does JavaFX work with CSS? not that I know of. Is there a similar alternative? The declarative approach of JavaFX is good, but why the choice of JSON-like declarations and not XHTML? The language is very close to Groovy, but not exactly the same (Groovy is from Spring creators), is there a path to consolidate these two new scripting languages? And why should we go with a propraietary environment and language, and not with W3C standards adopted by the browsers running on mostly all handsets? ... Yes, I know there are answers for some of the questions above, but in the huge time dedicated for JavaFX, alternatives, as well as known flaws and drawbacks, were not discussed.&lt;br /&gt;&lt;br /&gt;Which brings me to the thought that independent Java events, such as &lt;/span&gt;&lt;a href="http://www.devoxx.com/"&gt;&lt;span style="font-family:arial;"&gt;Devoxx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, are a better meeting place for the community.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;MySQL&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;This was another theme at the event. MySQL is a powerful tool, the regulator shall take it out of the hands of Oracle to preserve competition.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Java Reference App&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Together with Ronen Perez, I was presenting a session called "Java Reference Application - putting all the buzzwords together" focusing on our selected libraries and tools.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Java Community and New Technologies&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;It's good to see all these smart people together. Being smart, people follow the trends and new technologies carefully, asking "what is it for me? how does it make my life easier?" In the past you could see people enthusiastic about any new thing, today you see people much more careful and reluctant. It's either that we are fed up with disappointments from previous "innovations" or that the pace of things require us all to be more cautious and conservative. This, together with the competition between technologies, requires new technologies to be well cooked and invest much more effort in getting us in.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-8038122829658824577?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8038122829658824577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8038122829658824577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8038122829658824577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8038122829658824577'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/06/javaday-javaone-java-thoughts.html' title='JavaDay, JavaOne - Java Thoughts'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-847286785002539250</id><published>2009-05-28T02:56:00.000-07:00</published><updated>2009-06-23T23:27:17.608-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><title type='text'>Technological Singularity</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/Sh5lD6Dws6I/AAAAAAAAArk/Qgsa0lLQ0xg/s1600-h/thematrix.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5340817325907030946" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 215px; CURSOR: hand; HEIGHT: 147px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/Sh5lD6Dws6I/AAAAAAAAArk/Qgsa0lLQ0xg/s320/thematrix.jpg" border="0" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;A singular point is a point in which the rules that define the spectrum around are no longer valid. In Mathematics a singular point is the point for which a function is undefined, in Physics, Gravitational Singularity means infinite gravitational field, known also to be a Black Hole.&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;Technological Singularity is the point of time when computers would be more inteligent than &lt;/span&gt;&lt;a href="http://2.bp.blogspot.com/_msmuQKgFPkU/Sh5k44Vu8OI/AAAAAAAAArc/ezy0k50NobQ/s1600-h/thematrix.jpg"&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;humans, thus creation of new computers and software programs can better be made by computers. Though sounds science fiction, something like the Matrix, I do know, as of today, of humans that are less inteligent than computers, one shall admit computers did part of the way.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;The steps towards singularity in software engineering would be the creation of new software languages which are much more declarative rather than procedural. Computers would be able to get well-formed requirements, or constraints, to create the required piece of software. Prof. David Harel started &lt;/span&gt;&lt;a href="http://www.wisdom.weizmann.ac.il/~harel/SCANNED.PAPERS/PlayInToCode.pdf"&gt;&lt;span style="font-family:arial;"&gt;talking about it&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; back in 2000. Now the problem with our usual requirements is that they are not so well-formed, filled with holes and hacked with contradicting constraints. But what if a computer can identify the holes and contradictions and ask us what we &lt;em&gt;really&lt;/em&gt; meant, then go and create the software. And maybe there is no need to ask us, since the computer knows better anyhow. The famous inventor and futurists &lt;a href="http://en.wikipedia.org/wiki/Ray_Kurzweil"&gt;Ray Kurzweil&lt;/a&gt; is speaking about technological singularity in his book &lt;a href="http://en.wikipedia.org/wiki/The%20Singularity%20is%20Near"&gt;The Singularity is Near&lt;/a&gt; with forecasts such as that by 2020 personal computers will have the same processing power as human brains and by 2030s &lt;a href="http://en.wikipedia.org/wiki/Mind_uploading"&gt;Mind Uploading&lt;/a&gt; would become possible.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:Georgia;"&gt;&lt;br /&gt;&lt;/span&gt;It's closer than you think. Declarative programming. Computers who understand requirements. Technological singularity. At which point the only occupation still relevant for humans would be lawyers, as computers cannot be mean enough for this job.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;The future is surely an adventure. Some would see the upside potential of it, others may see the risks, which are there of course. For those and for those it would be good to read some advice from Daniel H. Wilson, on &lt;/span&gt;&lt;a href="http://www.robotuprising.com/home.htm"&gt;&lt;span style="font-family:arial;"&gt;How To Survive a Robot Uprising: Tips on Defending Yourself Against the Coming Rebellion&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&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/7061498094705606309-847286785002539250?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/847286785002539250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=847286785002539250' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/847286785002539250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/847286785002539250'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/05/technological-singularity.html' title='Technological Singularity'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/Sh5lD6Dws6I/AAAAAAAAArk/Qgsa0lLQ0xg/s72-c/thematrix.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-2838703261990134360</id><published>2009-05-25T17:01:00.000-07:00</published><updated>2009-05-28T01:06:08.467-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Maven, Static Code Analysis, Code Coverage and more</title><content type='html'>&lt;span style="font-family:arial;"&gt;Static code analysis and Code Coverage are becoming as basic as IDE syntax highlighting. Tools like &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt;, &lt;a href="http://cobertura.sourceforge.net/"&gt;Cobertura&lt;/a&gt;, &lt;a href="http://checkstyle.sourceforge.net/"&gt;Checkstyle&lt;/a&gt;, &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt;, &lt;a href="http://www.eclemma.org/index.html"&gt;Eclemma&lt;/a&gt; and others, with plugins to Eclipse and Maven extensions, makes your life as a programmer more manageable, having &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; build a site for you with your code coverage results and following Checkstyle remarks in the IDE.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The title connects between things that are uncorrelated, except for being a measurement for modern Java development practicing. And of course Maven relates it all together also.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Today a Java programmer that knows only Java, even if very well, but intentionally ignores what's arround in the industry, e.g. sticking with good old Ant ("Why do I need this Maven, I'm doing just fine with Ant, just &lt;/span&gt;&lt;a href="http://www.urbandictionary.com/define.php?term=Leave%20me%20in%20your%20mother%20(azov%20oti%20be-ima%20shkha)"&gt;&lt;span style="font-family:arial;"&gt;leave me in your mother&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;") becomes a bit obsolete. The strength of Maven is that you can take a project with its POM.xml, and open it on another machine, even with another IDE that supports Maven.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;So, to summarize.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;As a programmer you are usually stressed and under pressure to close your tasks. Find some time to enhance your environment with the relevant &lt;/span&gt;&lt;a href="http://oreilly.com/catalog/9780596527938/"&gt;&lt;span style="font-family:arial;"&gt;Java Power Tools&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2838703261990134360?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2838703261990134360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2838703261990134360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2838703261990134360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2838703261990134360'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/05/maven-static-code-analysis-code.html' title='Maven, Static Code Analysis, Code Coverage and more'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7645597160174234316</id><published>2009-04-12T08:49:00.000-07:00</published><updated>2009-04-12T09:04:20.990-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Wicked Problems</title><content type='html'>&lt;span style="font-family:arial;"&gt;Wicked problems in software design are problems that tempt you into a certain solution or design that seems reasonable and easy but turn out to be holey as a leach.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SeIOyRFKN1I/AAAAAAAAAY0/dWNNVAutRzo/s1600-h/wicked.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5323833966246639442" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 190px; CURSOR: hand; HEIGHT: 125px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SeIOyRFKN1I/AAAAAAAAAY0/dWNNVAutRzo/s400/wicked.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Mature developers and software architects know how to avoid wicked problems. Managers with lack of technical background may fall into such traps without even noticing and without realizing the trap even in retrospect, you may find a manager who would be very proud of a solution his group created for a wicked problem, investing in it a few man months, without seeing other alternatives of avoiding it or implementing it a bit differently with much less effort and side effects.&lt;br /&gt;&lt;br /&gt;Straight solutions for wicked problems tend to be not only costly for implementing, but also for the long run, as the stitches sewed to close all holes tend to get unstitched, torn open.&lt;br /&gt;&lt;br /&gt;Let me take you through a very small problem that I was dealing with, and turned out to be wicked.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Some background. In web applications we need occasionally to get info from the server according to user selections without turning to a new page. This is called an AJAX operation. There are several frameworks for supporting easy implementation of AJAX calls. One of which is YUI (Yahoo User Interface), which does on top of this all sort of other great things, supporting similar web experience on different web browsers.&lt;br /&gt;&lt;br /&gt;YUI has a component for AJAX auto completion. The component is quite powerful and allows selections ranging from simple ones like this:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SeIOCt3hJBI/AAAAAAAAAYc/np4jh6CYQzU/s1600-h/autocomplete.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5323833149340328978" style="WIDTH: 203px; CURSOR: hand; HEIGHT: 229px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SeIOCt3hJBI/AAAAAAAAAYc/np4jh6CYQzU/s400/autocomplete.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;to more complicated, as this one:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_msmuQKgFPkU/SeIOC6pinJI/AAAAAAAAAYk/6MMpjGxzmS8/s1600-h/autocomplete2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5323833152771366034" style="WIDTH: 300px; CURSOR: hand; HEIGHT: 183px" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/SeIOC6pinJI/AAAAAAAAAYk/6MMpjGxzmS8/s400/autocomplete2.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In YUI the selection made is entered into the input-box and this is the information sent back to the server. We wanted to add the ability to send back to the server an ID instead of the selected value itself. This is useful since in many cases we want to present to the user meaningful text while the server really needs an ID. And we wanted it to work also for the multi-select version.&lt;br /&gt;&lt;br /&gt;The solution seemed to be simply to add a hidden field and put the IDs there. The server would of course need to send in the AJAX reply the text to present in the list and input-box, as well as the ID per each entry. Making it part of the JSON reply is simple. Now, every time the user makes a selection we can add the ID into the hidden field, even for multi-select.&lt;br /&gt;&lt;br /&gt;Simple and easy. We even found a few implementations like this on the net.&lt;br /&gt;&lt;br /&gt;But this is not enough...&lt;br /&gt;&lt;br /&gt;Since the user types his selection, he may type a selection without selecting (clicking on it) from the suggestion list. The user may also delete things after selecting them and then the hidden field needs to be updated. He may also retype characters into a selection made already, thus changing it to another, legal or not.&lt;br /&gt;&lt;br /&gt;One thing came to our mind is that this feature needs to go with "Forced Selection" which means that the user cannot add things into the input-box without selecting them from the suggestion list. This may solve some of the problems. But not the deletion problem, we still need to take care of user deleting a value from the input-box. The only way to tackle the deletion problem is by populating the IDs hidden field only when the user leaves this input-box (when the focus is lost, i.e. in the "onBlur" event). Then what we can do is to loop through all values in the input-box, add a relevant ID for each in the hidden field, and display a warning for illegal values (for which there is no matching ID). The problem now is that at this point we may not have all IDs, so we need to go back to the server, in an AJAX call and ask for the IDs. And the values in the input-box must be unique, that is: each must represent exactly one ID (there cannot be two John Doe).&lt;br /&gt;&lt;br /&gt;At this point we realized that we are going to work hard for a solution that would not bring much value to application writers, as they would need anyhow to implement a function on the server side for replacing textual values for IDs, and those textual values must be unique. So why don't just post the textual values back to the server as is, exactly as implemented originally by YUI.&lt;br /&gt;&lt;br /&gt;Well, there is one reason for the hard work. And it is supplying warnings to the user while he types and not following post back. By checking whether all textual values has legal IDs we can warn the user for illegal values before posting the form. But then, one needs to decide whether this worth the investment, and whether it can work well.&lt;br /&gt;&lt;br /&gt;We came to the conclusion that the people at YUI knew what they were doing. It is way too tricky to post back IDs. No, it's even more than that. It's wicked.&lt;br /&gt;&lt;br /&gt;Now, we invested about half a day in investigating the problem and thinking of solutions, and then eventually decided to avoid this implementation. How many of us would do the same after investing a week in investigating?&lt;br /&gt;&lt;br /&gt;A wicked problem is usually a problem that you'd better waive, avoid, abandon. Suggest other ways of doing it. Replace with another feature which is easiest to implement. The efforts of solving the wicked problem do not justify its value. Yes, a wicked problem is sexy, if you solve it you can become a true hero, it makes out a really neat feature. It is courage and experience, needed to realize the real effort for these wicked problems and to admit they do not worth it, even if some time was already invested in analysis and investigation. Or, to find the easier design, almost fulfilling the wicked problem, achieving most of the goals with much less effort.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7645597160174234316?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7645597160174234316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7645597160174234316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7645597160174234316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7645597160174234316'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/04/wicked-problems.html' title='Wicked Problems'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SeIOyRFKN1I/AAAAAAAAAY0/dWNNVAutRzo/s72-c/wicked.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-5459810299526214920</id><published>2009-03-29T04:03:00.000-07:00</published><updated>2009-05-28T00:40:11.671-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><title type='text'>Sun's Future</title><content type='html'>&lt;span style="font-family:arial;"&gt;Rumors on IBM about to acquire Sun has taken Sun's stock up recently. The idea of Sun being acquired were running around already for some months when Sun's stock was dropping to 10$ (e.g. &lt;/span&gt;&lt;a href="http://www.pcworld.idg.com.au/article/258102/sun_sale_dropping_profits_stock_price_fuel_speculation"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, from August 2008). Today Sun is traded back at about 8$, after jumping more than 60% in the past two weeks.&lt;br /&gt;&lt;br /&gt;When Jonathan Schwartz, Sun's CEO, &lt;/span&gt;&lt;a href="http://blogs.sun.com/jonathan/entry/java_is_everywhere"&gt;&lt;span style="font-family:arial;"&gt;announced&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; the change of Sun's ticker from SUNW to JAVA, at August 23rd 2007, that was the beginning of the end. The price of the stock was around 19$ then, after visiting 253$ (!!!) seven years earlier. The main problem is that unlike Microsoft or IBM, Sun never succeeded in making money out of software. They had a history of starting software products and then shutting them down, and they never really cashed the success of Java. Sun is a company with technical excellence and innovative spirit, but for the benefit of itself and of the software market, it shall find its place within a company that knows how to cash out these qualities.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-------------&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;May 2009:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Well, by now we all know that it was Oracle eventually to buy Sun. Still keeping the above relevant. I'm surly wishing all the best for this couple. And for IBM as well of course.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-------------&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5459810299526214920?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5459810299526214920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5459810299526214920' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5459810299526214920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5459810299526214920'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/03/suns-future.html' title='Sun&apos;s Future'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-3100079362783254332</id><published>2009-03-16T16:41:00.000-07:00</published><updated>2009-07-05T05:52:30.718-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Off-Shore'/><category scheme='http://www.blogger.com/atom/ns#' term='Recruitment'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Software Factories</title><content type='html'>&lt;span style="font-family:arial;"&gt;Before the industrial revolution most of the products were made by hand, crafted. Is software manufacturing today more like a confection (ready made clothing) or more like "haute couture"?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The term "Software Factory" was created for describing the possibility of getting software requirements and sending them into a "factory" for manufecturing. (Do not mix that with a Microsoft technology with a similar name).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The challenge is that with software, customer needs may be very complicated. Can we just send the requirements into a "Software Factory" and get it done? (This in some way contradicts the idea of constant communication embedded in Agile Development.)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Think of airport control system that needs to address all kind of airports and equipment. Think of banking software that shall address different banks and communicate with all sorts of external interfaces. Can we create modules that are generic enough so that customization for specific customer needs can be done by cheap work force and without too much complications and investment?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Most software projects cannot be cloned. There is no customer that resembles another, requirements are different and the "physical" legacy environment is not the same.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Closets are also not all the same. Each customer may have different specific requirements. Nevertheless, most carpenters manage to stay scalable and address specific requirements by setting standards, such as several available sizes (you can order a closet of 2.0 or 2.4 meter height, however, 3.0 meter height would be a special order, would be processed uniquely and priced accordingly) and several available woods.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;To achieve the ability of creating software as in "Software Factory", we shall:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Narrow the options and alternatives. State clearly what can be built as a standard and what is a special order.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Externalize a clear API&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Insist on always getting clear requirements before starting (did you see a carpenter starting to work on a closet before having all measurements?)&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Have core modules, easy to customize for very specific needs, with hooks and plug-ins for adding specific functionality&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Create a very strict and close way of customizing the product, allowing it to be done by cheap work force. Always prefer customization techniques which require less thinking. Customization &lt;u&gt;shall not be art&lt;/u&gt;, it shall be very technical and strict, preferably with clear instructions.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Both the core module and the customizable product shall be easily testable, each on its own.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I had a debate recently on whether the preferred technique for rendering raw data into HTML is JSP with Taglibs or XSL. Though XSL is very powerful and can do anything with raw XML at hand, I argue that a set of strict Taglibs with the instruction not to use Java code inside JSP makes it much easier to make this task in the mode of "Software Factory". In oppose to XSL, which is in some way an "art", using a strict set of predefined Taglibs is something that is much more narrowed, cannot handle all cases and special requirements, but can certainly provide most needs and most importantly, can be done by almost anyone, given clear requirements.&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;We are already in a period in which most organizations cannot afford having their software be "haute couture", they must settle on confection, ready-made, with some adaptations. Most software companies who would still manufecture their organizational software products as "haute couture" would not survive, unless in very specific and unique domains. When software becomes a commodity, like a cheap chip, the only way to produce it is in a "Software Factory" model.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-3100079362783254332?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/3100079362783254332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=3100079362783254332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3100079362783254332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3100079362783254332'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/03/software-factories.html' title='Software Factories'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-2553148259252716197</id><published>2009-03-13T00:49:00.000-07:00</published><updated>2009-03-13T01:35:38.626-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Real Life Architecture</title><content type='html'>&lt;span style="font-family:arial;"&gt;When designing a system one shall think of all possible scenarios and error cases. Ignoring a possible scenario may lead later to all sort of problems, ranging from crashes to logical errors (e.g. fulfilling a financial transaction without finishing the order process, so the customer is debited but would not get any product).&lt;br /&gt;&lt;br /&gt;One thing that we shall bear in mind is that &lt;strong&gt;listing all possible scenarios&lt;/strong&gt; does not mean &lt;strong&gt;implementing a solution for all possible scenarios&lt;/strong&gt;. There are error cases that are quite rare or not-so-rare but very difficult to handle, maybe even require a whole different design approach. A possible solution may be to log the problem to a specific database for manual handling, or for a later amending batch operation. Such approach can save a lot of the hassle during all stages: design, implementation and maintenance.&lt;br /&gt;&lt;br /&gt;I may rephrase the above rule: &lt;strong&gt;listing all possible scenarios is a MUST&lt;/strong&gt;, however, &lt;strong&gt;implementing a solution for all possible scenarios as an integral part of your system is probably not always the best solution&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Usually implementing a fully-blown solution for rare cases doesn't really work, as it is not tested enough for all variants and nuances of the exact scenario, and when the rare cases do happen you see that some modifications shall apply. Taking the treatment of rare special cases outside of the system, to either manual or batch operation may thus be a wise thing to do.&lt;br /&gt;&lt;br /&gt;I call this "Real Life Architecture" based on the famous article by Gregor Hohpe &lt;a href="http://www.eaipatterns.com/ramblings/18_starbucks.html"&gt;Starbucks Does Not Use Two-Phase-Commit&lt;/a&gt;, which appears also as a transcript at Joel Spolsky's &lt;a href="http://www.amazon.com/Best-Software-Writing-Selected-Introduced/dp/1590595009"&gt;The Best Software Writing I&lt;/a&gt;. Gregor argues that in real life we often use asynchronous messaging without worrying too much about error scenarios, which we do deal with when happen, in somewhat batch way. As an example Gregor goes through the ordering mechanism at Starbucks, its simplicity and efficiency.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2553148259252716197?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2553148259252716197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2553148259252716197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2553148259252716197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2553148259252716197'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/03/real-life-architecture.html' title='Real Life Architecture'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7531158886840082278</id><published>2009-02-28T22:31:00.000-08:00</published><updated>2009-05-28T00:37:10.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Be proud of your code!</title><content type='html'>&lt;span style="font-family:arial;"&gt;I'm usually quite proud of my code. If I'm not, I keep polishing it. When I review code of my guys, one of the things I insist of is to have the person's name on his code. Like on Dexter Horton Building.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If the guy says: "but all I did here is just to add this one little function".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;"Well," I say to him, "so add your name above the function".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If the guy says: "but all I did was to fix this line. I didn't really added any new line of code".&lt;br /&gt;"Well," I say to him, "so add your name above the line that you fixed, with a date and explanation of the fix".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;But if the guy says: "hmmm, I'm not sure I'd like to put my name here. I'm not sure it works so well". Then I jump and say "haha! this is exactly why I insist on having your name there. Not initials. Not your nick name. A name that we can trace back when you will be a big manager at IBM, so you better don't leave any bug there."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/Sc_w3eR1FiI/AAAAAAAAAPI/GUzv098RGsQ/s1600-h/Dexter_Horton_Building.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5318734520759162402" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 300px" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/Sc_w3eR1FiI/AAAAAAAAAPI/GUzv098RGsQ/s400/Dexter_Horton_Building.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The building above is real. I took this picture myself (I won't let you know where it's located. If you're curious you would probably google it.) I use this picture when I talk about code review and my insistence on having the developer's name on his or her code. Alex from mistralzonline, already documented this picture as part of his talk on &lt;a href="http://mistralzonline.blogspot.com/2008/07/present-and-represent.html"&gt;present and represent&lt;/a&gt;, at his blog "On Everything And Nothing In Particular".&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7531158886840082278?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7531158886840082278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7531158886840082278' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7531158886840082278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7531158886840082278'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/be-proud-of-your-code.html' title='Be proud of your code!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/Sc_w3eR1FiI/AAAAAAAAAPI/GUzv098RGsQ/s72-c/Dexter_Horton_Building.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-7594506951636427173</id><published>2009-01-29T02:51:00.000-08:00</published><updated>2009-03-08T11:51:43.693-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>The risks of redundant code (or - Less is More)</title><content type='html'>&lt;span style="font-family:arial;"&gt;One of the preferred refactoring methods of my choice is deleting redundant code.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I separate between excessive code and redundant code:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;1. Redundant code is code that &lt;u&gt;never runs&lt;/u&gt;:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Unreachable code&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Unused classes, interfaces and methods&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Commented-out code&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Code that looks wrong, then you understand that it is indeed wrong, but is being lucky enough not to be called&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Code that deals with cases that cannot happen&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Code that deals with cases that could happen in the past, but now cannot&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Code that is there for future cases, which are not occuring yet (and may be added &lt;em&gt;sometime&lt;/em&gt;)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;span style="font-family:arial;"&gt;2. Exc&lt;/span&gt;essive code is code &lt;u&gt;that runs&lt;/u&gt;, but can be reorganized into less lines of code:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Unnecessary abstractions, unneeded levels of delegations&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Copy-Paste that can be moved to methods, inheritance, templates&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Both are bad and should be treated. But &lt;strong&gt;the first category, redundant code, is much riskier&lt;/strong&gt;. The main risk of redundant code is that it looks innocent and useful, but &lt;strong&gt;it doesn't really work&lt;/strong&gt; and &lt;strong&gt;it is never tested&lt;/strong&gt;. In many cases you assume that there is some value in this code, so you keep it around, maybe it will become useful sometime. Well, most probably it will become useful by creating new bugs when you accidentally use it. &lt;u&gt;Remember&lt;/u&gt;: this code was never really tested, just being there, so familiar, part of your code, does not make it something that works. And in many cases it confuses you, as you believe that a feature is already written, because the code is there, you only need to pass another value or take some code out of a comment. But this code was not maintained or tested for ages, if at all! How can you rely on it? Why keep it there in the first place?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;My recommendation usually is to be very cautious with code that never ran and is just lying there, as it may be lying and not doing what it supposed to do.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Keeping unnecessary code requires you also to maintain these lines of code that you don't really need. Again, &lt;/span&gt;&lt;span style="font-family:Arial;"&gt;I say - get rid of it.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7594506951636427173?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7594506951636427173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7594506951636427173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7594506951636427173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7594506951636427173'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/01/risks-of-redundant-code-or-less-is-more.html' title='The risks of redundant code (or - Less is More)'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-4137034598974800318</id><published>2009-01-08T04:42:00.000-08:00</published><updated>2009-03-29T05:18:44.496-07:00</updated><title type='text'>Generic Software Mission Statement</title><content type='html'>&lt;span style="font-family:arial;"&gt;Following &lt;/span&gt;&lt;a href="http://softwareanimals.blogspot.com/2009/01/vision-mission-goals-objectives-and.html"&gt;&lt;span style="font-family:arial;"&gt;my previous post on the subject&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, I created the following generic mission statement:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Produce quality code, on time, for the success of the company.&lt;/strong&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Yes, I know, it's VERY GENERIC, but as a general mission statement for software groups it's quite good.&lt;br /&gt;&lt;br /&gt;The problem with a more specific mission statement is that it may miss the responsibility of some of your employees. I had a few years ago a small group dealing with projects for customer applications. In one of our business group talks, the business group manager threw at the entire group that the goal for the team in the following quarter was to achieve sales target of 1M$.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The problem was that it was a group of programmers, not sales people, and achieving sales target was not part of our responsibility. The manager was just pumping down to us his own target (probably adding 25%, just to increase our motivation). The results of this talk was horrible, people were going around thinking how to bring 1M$, instead of doing their programming tasks. It scared some and it totally ruined the motivation of most, who usually do not relate their code to money. Code is art, relating it to money makes it dirty. Instead of speaking of money it was much better to speak about features, projects and deadlines. Even setting for a programming team a target of number of customer projects to achieve is wrong. Mission and targets shall be focused on the responsibility area of the team. It's the manager's responsibility to hide all the rest.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-4137034598974800318?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/4137034598974800318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=4137034598974800318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4137034598974800318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4137034598974800318'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/01/generic-software-mission-statement.html' title='Generic Software Mission Statement'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7236716737420846659</id><published>2009-01-05T13:26:00.000-08:00</published><updated>2009-03-04T15:58:54.734-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Vision, Mission, Goals, Objectives and Mesurements</title><content type='html'>&lt;span style="font-family:arial;"&gt;Year start is a good oppotunity to think about vision, mission and goals. I know that there are those cynical of you, who treat vision and mission as a waste of time. I tend to agree. It's a waste of time if you invest in it too much, and it may become a farce when you invest 15 minutes or more in explaining your vision or mission statement to your organization. Vision and mission are a great tool for saying something short and not too meaningful, but there are still important as they do shed light on your VALUES -- what do you value and where you are going to put your efforts.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The much more important are the goals and objectives. This is your opportunity to list the strategic achievements you want to bring. Goals and objectives should be SMART. That is: &lt;u&gt;S&lt;/u&gt;pecific (not vauge or too general), &lt;u&gt;M&lt;/u&gt;easurable (state the measurement as part of the goal), &lt;u&gt;A&lt;/u&gt;ttainable (be realistic), &lt;u&gt;R&lt;/u&gt;elevant (related to your vision, even if you don't have one yet), and -- &lt;u&gt;T&lt;/u&gt;ime-bound (otherwise it's like an exam without a time limit). There are, by the way, &lt;a href="http://en.wikipedia.org/wiki/SMART_criteria"&gt;other interpretations for the SMART abbreviation&lt;/a&gt; but the main idea stays the same -- be clear and make the goals something that can be checked at a certain point of time and marked as done/not done.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;SMART is smart to say but difficult to do, especially when you plan the future, which is what you do with setting goals. Let's take some examples:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;For "Innovation", you may set the following goal: come up along the year with at least 5 new major (define major?) feature ideas, for which at least 3 would be judged as feasible and relevant to the market and at least one would be developed.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;"Quality" is tricky. You may want to give bonus to the programmer who creates the fewest bugs, you may want to read before &lt;a href="http://www.joelonsoftware.com/items/2006/08/09.html"&gt;what Joel thinks on that&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;"Investigating" new domain: what is the target goal to set? I usually set the goal as giving a lecture on the subject, at a certain agreed date. Usually it promises decent investigation of the subject. In some cases I add the requirement for documenting the material in our organizational wiki.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Setting strategic goals for the coming year/quarter/month is one of the most important tasks of a manager. Ask yourself, how you want your accomplishment powerpoint presentation to look like at the end of the period. Or maybe even better, prepare this powerpoint presentation ahead. Then set the goals and tasks that derived from it, aiming at minimum changes for your presentation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Once you have the goals and objectives you can go back to the vision and mission, it would be much easier now to state them in 5 minutes. And if you don't find something strong enough go for "Bring qualitative value to the organization".&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Georgia;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7236716737420846659?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7236716737420846659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7236716737420846659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7236716737420846659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7236716737420846659'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2009/01/vision-mission-goals-objectives-and.html' title='Vision, Mission, Goals, Objectives and Mesurements'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-1690157900642821352</id><published>2008-12-25T19:59:00.000-08:00</published><updated>2009-03-04T13:29:04.419-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Test Automation ROI</title><content type='html'>&lt;span style="font-family:arial;"&gt;Recently I was working on a ROI (Return-on-Investment) Model for Test Automation. It was quite interesting to note that there are not too many "ready-made-excels" out there for this purpose. The ones that exist come mainly from automation tool manufectures. So I went to creating my own model, resulting with interesting notions.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Test Automation ROI Ingredients&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Expenditure side&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;NRE (Non-Recurring Effort / Expense) - buying tool license, training people, raising the environemnt and infrastructure&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Implementing the initial testing scenarios&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Maintaining the testing scenarios and the environemnt and infrastructure&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Adding new scenarios and new required features to the environemnt and infrastructure&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Usually requires better trained testing engineers to maintain the automated testing system&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:Arial;"&gt;Revenue side&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;In the long run, may be able to reduce manpower (less manual testing is needed)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Reduce number of escaped defects&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Increase development confidence, allowing more features per release, thus less releases per year&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Shorter test and development cycles and improved TTM (Time-to-Market)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Enhances the abilities of the testing team ("soft" revenue)&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Influencing Factors&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;When coming to real life numbers it appears that it is very tricky to achieve positive ROI. And even if there is positive ROI the break even point comes after at least one year of investment, and in most cases two years. It's a simple case of big lump sum investment for future expected revenues.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The ROI is strongly related to the amount of bugs detected in the system in general and specifically in the field, number of existing manual testing engineers and the number of releases per year:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;A system with very low amount of bugs that are mostly found at testing room and not in the field, would make it harder for automation to have positive ROI, as the potential of reducing escaped defects is low&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;If the current existing number of manual testing engineers is small, potential of revenues in reducing manpower is low. However, if number of escaped defects is high automation can assist in lowering it&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Low number of releases per year would also make it harder to achieve positive ROI, as the lump sum investment is made for less cycles of use per year&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;The ROI is strongly related to the changes in the system:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Need for new scenarios and features in the environemt along the year means more investment in maintaing the testing system up-to-date&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The lifetime of an automated scenario before it becomes broken or irrelevant because of changes in the system is very important&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;On an "average" system with some major new features each year, about 4 major releases per year and about 20 major escaped defects per year, following can be found:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;In order to properly support and maintain a test automation project, you would probably need the same amount of people as you had before with manual testing, all along. The new features in your product requires new testing scenarios as well as new features in the test automation environment&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The major revenues stem from reducing number of major releases (adding more features per release) and from reduced number of defects in field&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;It takes about 18 months to return the investment&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Projects that are not stabilized yet and have too many changes would probably not earn from end-to-end test automation, although automated regression based on UnitTesting can still assist. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1690157900642821352?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1690157900642821352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1690157900642821352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1690157900642821352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1690157900642821352'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/12/roi-for-test-automation.html' title='Test Automation ROI'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-2461307672588649243</id><published>2008-12-17T07:07:00.000-08:00</published><updated>2009-02-12T11:43:53.691-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Module Separation</title><content type='html'>&lt;span style="font-family:arial;"&gt;Module separation is one of the oldest tricks in software engineering. As it is too complicated to attack a big problem, we split it and attack it in pieces. The pieces should eventually work together. We don't want to have two teams digging a tunnel from two sides of the mountain, missing the meeting point. In the tunnel case you get two tunnels which may have some value, with software you will just have a dysfunctional messy system.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;The engineering task, some would say the art, of defining the modules and the interactions between them, is crucial for the success of the system. Do we need our modules to be stateful? Do we want synchronous or asynchronous communication? What would be the messages language between the modules, would it be programming API or a communication layer? On top of which protocol the messages would travel? And on top of all, which modules should we define? and for each module, which modules it shall be aware of and which it shall be totally agnostic and unaware of?&lt;br /&gt;&lt;br /&gt;Usually we would like the communication between modules, i.e. the public interfaces that a module should expose, to be as little as possible. Operations or sub-operations that require much communication would be preserved in the same module while operations or sub-operations that require lesser amount of communication can be split. We should also like to have some hierarchy between modules so that not every module would have to know all the others, preventing cyclic dependencies is usually an architectural requirement.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;So, what is the definition of a module?&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Trying to create a definition of a module, or even better, a subscription, is not easy. Recently I was attending a session by &lt;a href="http://www.sei.cmu.edu/staff/rkazman/"&gt;Rick Kazman&lt;/a&gt; the co-author of &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0321154959"&gt;"Software Architecture in Practice"&lt;/a&gt;. Rick referred to this question, defining a module as "the set of tasks belonging to a unite topic, managed and built by an independent team of people." It is interesting to note that Rick's definition focus on the organizational aspects more than on architectural aspects of "what is a module". Rick argues that this goes well with &lt;a href="http://en.wikipedia.org/wiki/Conway"&gt;Conway's Law&lt;/a&gt; stated by Melvin Conway in 1968, arguing that the required communication between two teams has a direct relation to the required communication between the modules they develop. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Create your own module&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;A module should have a clear definition of roles and responsibilities, both technical (what the module does) and organizational (who is responsible of defects found at this module). It should have also a clear and concise public interface. A module would usually be deployed as one unit, but in many cases several modules would be deployed as a unit together. Different programming languages would give modules different semantics, syntax and deployment characteristics, yet still some programming languages may not have the notion of modules in the language itself. And, not less important, a module shall be clearly defined as a set of tasks managed and built by an independent team of people.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;How to do a 2000 pieces puzzle in a team&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5301813036635603730" style="WIDTH: 130px; CURSOR: hand; HEIGHT: 112px" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/SZPS3dozQxI/AAAAAAAAAGk/8qhJqzS1lhk/s320/dolphinphoto.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Doing a huge puzzle in a big team, does increasing the size of the team assist? Is there a number at which we will have a negative marginal contribution? (&lt;a href="http://en.wikipedia.org/wiki/The_Mythical_Man-Month"&gt;"Mythical Man Month"&lt;/a&gt;). Can you create "modules" here? This question about puzzle building is inspired by &lt;a href="http://jaoo.dk/aarhus-2008/file?path=/jaoo-aarhus-2008/slides//ChrisRupp_IdentifyingClientNeeds.pdf"&gt;Chris Rupp's talk at JAOO 2008&lt;/a&gt; (see video capture &lt;a href="http://blog.jaoo.dk/2008/12/01/understanding-requirements-engineering"&gt;here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;It's a very nice exercise for a management course. I would think of the following design: (a) dispatcher team - goes through the pieces and assign them to the other teams; (b) teams by colors and shades, e.g. Dark Blue team would deal with the sea part while the Light Blue team would deal with the sky; (c) frame team, getting all the pieces that shall compose the frame. Each team is a module, so we have a dispatching module, a few color building modules, by colors and shades, and a frame building module.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;In case of resource shortage we can settle without the dispatching team and let the building teams themselves do the dispatching. Number of people will define the separation into colors for the color building teams, but even if we would have 1,000 people we would not define 10 shades of blue, as the interaction between the teams (I got this blue piece but it seems unrelated to me) would be too exhausting.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Shall module definition be influenced by external factors?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;We saw in the puzzle example that to some extent, number of available people would influence the number of shade teams that we may define. Expertise and skill set of our resources, as well as their geographical disposition shall also play a role here, but we will leave this for a later post on the relations between organizational structure and architecture.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2461307672588649243?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2461307672588649243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2461307672588649243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2461307672588649243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2461307672588649243'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/12/module-separation.html' title='Module Separation'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/_msmuQKgFPkU/SZPS3dozQxI/AAAAAAAAAGk/8qhJqzS1lhk/s72-c/dolphinphoto.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-8157388002255323620</id><published>2008-11-30T01:15:00.000-08:00</published><updated>2008-11-30T10:36:10.558-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Use Explaining Variables!</title><content type='html'>&lt;span style="font-family:Arial;"&gt;Explaining variables are temporary variables that a method doesn't really need, but makes it more readable. I like them very much. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;"Introduce Explaining Variable" is in fact a refactoring method in Martin Fowler's famous Refactoring catalogue -- p. 124 in the Refactoring book (it's a bit against Fowler's "Replace Temp with Query" -- but this is controversial anyhow -- I for myself like temp variables in any shape and form! As long as they have meaningful name of course...).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Why temp "Explaining Variables" are great?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;It's better than a comment, the name of the variable says what you did in this funny math operation or complex logical act; comments are neglected sometimes, changing the logic and keeping the old, not accurate anymore, comment. The chances for a variable saying "isTheWorkerAvailableAndWithoutConstraints" to really mean what it says are much higher than a mere comment - we can count on the programmer that if something changes the name of the variable would change. Or we shoot him if not. With a comment we would feel bad to shoot a good programmer just for not updating a comment.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;It goes anywhere. You don't need to try and recall "so where are we now" or "what did we put in this variable" - the long funny name says it all, and says it everywhere it goes!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The name can carry with it important info as measurment units. I'm extremely fond of variables with names like "timeoutInMillisec" or "distanceInMeters" or "radiationTimeInSeconds". It can save lives. Or satellites.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;When calling a method it's sometimes more readable to send a temp variable with a decent name to hold the argument you want to send, rather than just send the argument. For example, a variable called "shouldSort" set to false may be much more readable than just sending "false". The programmer may also add, above the init to false, why false is the right value to send.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;Usually during code review, when a small thing is not clear, I prefer an explaining variable over a comment.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-8157388002255323620?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/8157388002255323620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=8157388002255323620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8157388002255323620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/8157388002255323620'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/11/use-explaining-variables.html' title='Use Explaining Variables!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-6371494194199115062</id><published>2008-11-14T09:04:00.000-08:00</published><updated>2008-11-29T15:29:44.634-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Make sure to have a strict XSD!</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;I'm going to tell you three things here:&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Don't invent new languages!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;XMLs are also languages (if they describe flow control)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;If you do create a new XML based language,&lt;/strong&gt; &lt;strong&gt;make sure that it has a strict schema!&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;-------&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/_msmuQKgFPkU/SR979kWqJRI/AAAAAAAAAGU/w2eLwKBuvbs/s1600-h/xmlsourceeditor.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5269066386707719442" style="WIDTH: 320px; CURSOR: hand; HEIGHT: 237px" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/SR979kWqJRI/AAAAAAAAAGU/w2eLwKBuvbs/s320/xmlsourceeditor.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Do not invent new languages&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;We have enough of them. And by a "new language" I mean anything that describes a flow, that includes all kind of weired XMLs. In some cases people call these XMLs "configuration" but when I look into it, it's NOT. Configuration is when you want to set a value to some attribute. If it is a complex attribute, e.g. a network topology, you may need to use XML, as you need a way to indicate hierarchy. But when it comes to defining a flow, and you have conditions maybe even method calls and loops, this is a new language! don't underestimate it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;What's BAD with creating your own new cute language?&lt;br /&gt;&lt;/strong&gt;(I'd even phrase it: "Why &lt;a href="http://en.wikipedia.org/wiki/Domain_Specific_Language"&gt;DSL&lt;/a&gt; sucks!")&lt;/p&gt;&lt;p&gt;Suppose that you have a service and you want to allow the user to externally configure its flow. Now you don't want to expose your code and allow the user to change it (that would be indeed a weird idea). And you don't want to load in run-time some external lib or dll or java class, which the user can compile and add. Which again is a reasonable decision. You want to keep it as simple as editing a text file. So you create your own little XML based language and it works great. The problem starts when problems start. And it's not a tautology. When something is not working correctly with your cute little language you find it very hard to debug it, as you don't have a proper debugger, nor even a proper IDE for it, not to speak of reasonable intellisence auto-complete. Your cute language is orphaned, to properly support it you will find yourself investing huge efforts, much beyond what you have planned originally.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;What's the alternative&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The best way, if you wish to have external flow configuration that includes conditions and such, is to use some existing script language and call it from your program. Perl, Python, JPython, of course Groovy, and others, can be good. The advantage is that you get a mature language with all the required surroundings. You can run the script from within your program and can get back feedback on variable values or return code. And it is much easier to explain the language to your user, you just point him to the language tutorial.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;But if you do need your own new XML based langauge&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Make sure that the language has a very strict XSD:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use enums for list of values, so the user cannot select anything, only what's legal&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use types: never allow to get a string for an int!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use regexp to define the allowed patterns of string values&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Don't use the same attribute for two purposes, it breaks the schema: if you can get either an int (number) or a string (variable), use two different attributes, each will have its own rule&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use different XML elements to oblige set of attributes: suppose that A-B and C-D are attribute couples (i.e. if I use attribute A I must also provide B, and if I use C I must provide D), it's better to break them into two different elements, even if they are similar in nature&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A strict schema gives you a good language protection, thus less bugs, a decent intellisence auto-complete if you use a decent XML editor, and a clear documentation for the user of what's right and what's wrong.&lt;/p&gt;&lt;p&gt;The same as any respectable language has its &lt;a href="http://en.wikipedia.org/wiki/Backus-Naur_form"&gt;BNF&lt;/a&gt;, if you invent a new XML based language you should base it on a strict schema.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6371494194199115062?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6371494194199115062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6371494194199115062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6371494194199115062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6371494194199115062'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/11/make-sure-to-have-strict-xsd.html' title='Make sure to have a strict XSD!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/_msmuQKgFPkU/SR979kWqJRI/AAAAAAAAAGU/w2eLwKBuvbs/s72-c/xmlsourceeditor.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-390717709099010463</id><published>2008-11-12T21:20:00.000-08:00</published><updated>2008-11-15T16:36:02.512-08:00</updated><title type='text'>* It's done already!</title><content type='html'>&lt;span style="font-family:arial;"&gt;Shlomi Hazan, a student of mine, was dragging his workshop for a second year. It was his last and final course. Finally, Thank God!, he submitted his work.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Here he is, with 2 laptops he brought with him, one desktop pc, one AudioCodes GW, a SIP phone and some POTS phones. He is in the computers lab, so though he did bring a lot of equipment, some of the equipment you see is part of the lab...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SR9nqZlk75I/AAAAAAAAAGM/a97iQhtZL6k/s1600-h/24-10-08_1055.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5269044067167432594" style="WIDTH: 200px; CURSOR: hand; HEIGHT: 160px" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SR9nqZlk75I/AAAAAAAAAGM/a97iQhtZL6k/s200/24-10-08_1055.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Now, I'm enthusiastic, not only because finally Shlomi decided to finish his degree and submit his workshop, but because it was a very nice workshop without too much code.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Shlomi presented a SIP Conference Call server. The thing is that using Asterisk you can get almost all of it done (and if you need for some reason a JAIN SIP stack, you will find an open source for this as well).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I think that &lt;a href='http://www.asterisk.org/'&gt;asterisk&lt;/a&gt; is an amazing open source project.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-390717709099010463?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/390717709099010463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=390717709099010463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/390717709099010463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/390717709099010463'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/11/its-done-already.html' title='* It&apos;s done already!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://3.bp.blogspot.com/_msmuQKgFPkU/SR9nqZlk75I/AAAAAAAAAGM/a97iQhtZL6k/s72-c/24-10-08_1055.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-5303160956545276014</id><published>2008-10-23T05:49:00.000-07:00</published><updated>2008-10-23T05:55:33.953-07:00</updated><title type='text'>NotifyingBlockingThreadPoolExecutor</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_5260331179983337666" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 111px; CURSOR: hand; HEIGHT: 91px" alt="" src="http://2.bp.blogspot.com/_msmuQKgFPkU/SQBzVnfReMI/AAAAAAAAAF0/1yUyb2tloMI/s200/threads.bmp" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I've found this &lt;a href="http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-pool-executor.html"&gt;interesting article&lt;/a&gt; in java.net, extending Java's ThreadPool.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5303160956545276014?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5303160956545276014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5303160956545276014' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5303160956545276014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5303160956545276014'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/10/notifyingblockingthreadpoolexecutor.html' title='NotifyingBlockingThreadPoolExecutor'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://2.bp.blogspot.com/_msmuQKgFPkU/SQBzVnfReMI/AAAAAAAAAF0/1yUyb2tloMI/s72-c/threads.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1215531013109909563</id><published>2008-10-12T17:59:00.001-07:00</published><updated>2008-11-29T15:33:30.445-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Don't Make Me Think!</title><content type='html'>&lt;span style="font-family:arial;"&gt;I'm reading the great "common sense approach to Web Usability" - &lt;b&gt;Don't Make Me Think&lt;/b&gt; book, by Steve Krug.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SPKgi5kwMuI/AAAAAAAAAFs/4KaSz6SmrEA/s1600-h/dont_make_me_think.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5256440236525761250" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SPKgi5kwMuI/AAAAAAAAAFs/4KaSz6SmrEA/s320/dont_make_me_think.jpg" border="0" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;And I recall that I have the exact same message when reviewing code: &lt;b&gt;Don't Make Me Think&lt;/b&gt;. If I have to think more than a second on a line of code it means that it's too complicated, you need to break it to two, maybe add a good comment above. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;If I start asking questions like "why did you do this or that?" it's not good, it means that your code is not self explanatory, or that you had a good reason for doing something in a special, maybe unorthodox way, or just not the way I'd think of doing it, but you didn't explain it well enough in a comment.&lt;br /&gt;&lt;br /&gt;When reviewing code I usually ask the developer, "OK open me the IDE, now let me try to understand by my own", "don't explain anything". "Shut up, stop explaining what you did, don't you understand I want some quite?!"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Then if I understand all by my own without a need to use my brain too much it's a good sign. The programmer gets his candy and we say goodbye. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;Otherwise the big refactoring, commenting, arranging work starts. Together with some oriental songs mumbling.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1215531013109909563?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1215531013109909563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1215531013109909563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1215531013109909563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1215531013109909563'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/10/dont-make-me-think.html' title='Don&apos;t Make Me Think!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SPKgi5kwMuI/AAAAAAAAAFs/4KaSz6SmrEA/s72-c/dont_make_me_think.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-3488272471688579520</id><published>2008-10-10T16:10:00.000-07:00</published><updated>2008-11-29T15:34:01.172-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Selecting the Right Technology or - the Art of "Satisficing"</title><content type='html'>&lt;p&gt;&lt;span style="font-family:arial;"&gt;These modern times are unmerciful. Back in the old days, when you had a programming task you could select between punching the pink punch-cards or the yellow punch-cards. Later, when Java came-up, if you selected Java, the library selection was quite easy: you went with what Java is providing – this was in fact one of the greatest things with Java – its built in set of common libraries, so there is one standard for IO work or Database connectivity. Any new programmer that comes along either knows already the standard or he should learn it. But no smartass would come knowing some all-different thing, asking dumb questions like “why are you using this and not that?” – luckily for us, there was only one option for everything.&lt;br /&gt;&lt;br /&gt;But we are now at new times. For every fart you want to make, there are several technologies you may use (pardon for the word “technology”). And selecting the right one is in some cases more troublesome than just doing the damn thing.&lt;br /&gt;&lt;br /&gt;Selecting the right technology: well, here is the “full process”:&lt;/span&gt; &lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Divide the thing you are going to build to relevant “topics”, each may need a whole different another set of technologies – you are anyway going to divide your project to modules or tasks. “Topics” may include: logging, configuration, communication channel, XML parsing and manipulation, database connectivity, caching, pooling, redundancy and failover support, build infrastructure, continuous integration support, unit test framework and code coverage support, static code analysis tool.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Build the list of ALL relevant technologies, for each relevant topic – don’t miss any relevant technology as it might be the one for you!&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Learn all technologies: write some code with each of them or at least read some example of code to see how much you like it; read analysis of pros and cons of each technology or do the analysis yourself; read some comparative benchmarks or better run them by yourself.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Create a nicely built comparison table for each topic, with all relevant comparison categories and aspects, create a team to discuss the comparison categories and give them weights, then give a (subjective) grade for each technology on each category and calculate the final score. If money is involved, add it to the equation somehow (not so simple, but with small amounts usually just added as another row to the comparison table with some grate from 0 to 10 or alike).&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;You have a winner, start working with it.&lt;br /&gt;&lt;/span&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SPKFOC1voPI/AAAAAAAAAFc/ycWgWJt3lmw/s1600-h/selecting.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5256410191421743346" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SPKFOC1voPI/AAAAAAAAAFc/ycWgWJt3lmw/s400/selecting.jpg" border="0" /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;From time to time (once in a few months / once a year) conduct the process again. You cannot of course just rest on the laurels. New technologies keep coming, so you need to go again and reassess your conclusions. Of course, you may need to give some weight on “knowing already this technology” or “paying already for this license” or “doing the work already”, but it doesn’t mean that you would not choose to replace it after all with something better, maybe something with much better performance, nicer user interface or easier maintenance.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This is the full process. The problem with the full process is that it is VERY COSTLY. To conduct it thoroughly you may invest in the selection much more than the gain between optimal and random (or a better “smart random”).&lt;br /&gt;&lt;br /&gt;The “full process” is probably the way for decisions with some several millions on the stake. And you would probably never go to #6 above, you &lt;em&gt;would&lt;/em&gt; rest on your laurels after a decision is made, even if a new promising technology is just out – they always appear and it’s a never ending race, like waiting for the best electric equipment to be a bit cheaper, once it’s there you would wait for the better new model to hit the same price. This is the road for never deciding and never taking an action, or taking a decision but always changing your mind (a road that leads eventually to a dead end dwelling a lunatic house).&lt;br /&gt;&lt;br /&gt;It’s simple economics, when you search for the cheapest Plasma TV-set, you MUST take into the equation the time spent and the fuel burnt. You may saved 100$ by investing 5 hours on the internet, 2 hours driving to the warehouse realizing that the thieves over there suddenly have a different price (“no, the price we gave you over the phone was for the TX model with no screen, you need the TWX which comes with a screen and is 400$ more, sorry!”). Eventually you get the TWX model that you want at what may seem as the real minimum price. But was it optimal?&lt;br /&gt;&lt;br /&gt;“Satisficing“ is the keyword here. This word, invented by the economist and computer scientist, &lt;a href="http://en.wikipedia.org/wiki/Herbert_Simon"&gt;Herbert Simon&lt;/a&gt;, who is the only person who won both Nobel Prize and the Turing Award. It refers to the act of &lt;strong&gt;&lt;em&gt;satisfying&lt;/em&gt;&lt;/strong&gt; by selecting a &lt;strong&gt;&lt;em&gt;suffice&lt;/em&gt;&lt;/strong&gt; choice -- not necessarily the optimal one.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;b&gt;How to Satisfice?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Make sure that you do not miss the major relevant technologies, those that everybody talks about. For this you MUST make yourself well familiar with the subject.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;There is a small chance that some un-spotted niche technology is your optimal choice, but since not many selected this niche technology, most chances it has some flaws. Missing a decent audience is a flaw as itself, which may affect later support, attention and availability of practiced manpower for this technology. So it's not a mistake to narrow the list to the major technologies that most people talk about and have the biggest communities, as long as you identify the domain correctly.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;A big community using the technology usually means that this technology is flexible and versatile enough to accommodate all, which is an important sign. Your needs would probably also grow and differ along time, you cannot fully foresee it now. Using a flexible enough technology is the cure for unexpected future needs.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;In many cases it's not a clear cut, nor is it a Black-n-White. You checked all aspects, consulted with colleagues and still hesitate -- flip a coin.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Standard protocols and APIs are for your rescue. If you have selected the wrong choice. A real crappy implementation. If it is based on a standard protocol or API you can just replace it with another implementation. Thus, do not tempt to proprietary extensions, stick to the standard. If there is an absolute need for using some proprietary extension (big efficiency boost or the only way to achieve something) narrow it to the minimum and isolate it in the code to a central place (e.g. one utility class which is the only one using the proprietary extensions). This way, if there is a need to change the implementation it would be easier to just re-implement the utility class.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Learning curve should be a factor. But you should remember it's a one time cost, compared to using the technology and maintaining the code, over several projects. Usually after you learn it, the complicated stuff becomes much less complicated not only for you but for the entire team, you find the way to wrap the complexities and make it easy to use. Give credit to the community, if it is said that something is good, wait before disqualifying it for being too complex.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Stick to things that work. If you see an example of two technologies working together (e.g. A and B) and a second example of another couple (C and D) but no other combination (no A and C or B and D), maybe there is a reason for that. Be caution before rushing to un-explored combinations.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;If you do want to be on the edge and rely on un-explored territories (something without a clear and exact example) -- build your own simple example before taking the technology to the real battlefield of your full-blown project. And be nice, publish your example!&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Consistency and uniformity are valuable! Try to select the same technologies for all your projects, thus you can share code, knowledge and bug fixes. Think twice before deviating to a new technology with investments in old substitute. Then think once more. Usually upgrading to a new version of a technology or moving to a whole different one is something to be done once in few years. If it happens to you twice a year check whether one of your programmers is checking all available technologies for some Academic assignment he is working on.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Be reluctant to adopt newly presented technologies in the market, even if everybody says it's the great new thing. Being on the cutting-edge may sometimes bleed! Technologies tend to mature, let others use the alpha and the beta. Wait for the 1.1 version. If you do want to take the new beta technology, make sure to test it well on a demo project which has the relevant features you need in your full-blown project.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Documented technology is always better than undocumented one. Prefer to ignore the less documented, even if it's cool.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Performance is important but is dynamic. Changes in HW and Computer Architecture (e.g. moving to multiple core CPU) may make a dominant choice descent. Updated versions of the implementations may also change the balance. Thus, usually if there is no real significant difference, of a multiple factor, performance should not play a distinctive role. Standard Protocols and APIs are more crucial.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Don't feel obliged to wait for a new version or a new technology that is about to come out, just because you want to explore it. It's like waiting on a new electric appliance model, there always be a new one coming shortly, for which you will feel again obliged to wait. Make your selections and go on.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;In many cases it's not a clear cut, nor is it a Black-n-White.&lt;br /&gt;You may feel here a deja-vu. Yes, I've said it already. But you must bear in mind that in many cases indeed, there is no right answer. This is another good reason to be conservative, keep with old technologies for which you have the knowledge and expertise, wait before adopting the cutting-edge, prefer documentation over nice fancy woos, prefer main stream over niche, prefer standards over proprietary.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Count on your gut feelings. But only after you do all the required investigations and exploring. Write some code, check the alternatives. But if after investing the effort you don't feel good with it - don't use it.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-3488272471688579520?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/3488272471688579520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=3488272471688579520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3488272471688579520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/3488272471688579520'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/10/right-technology.html' title='Selecting the Right Technology&lt;br/&gt; &lt;h3&gt;or - the Art of &quot;Satisficing&quot;&lt;/h3&gt;'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SPKFOC1voPI/AAAAAAAAAFc/ycWgWJt3lmw/s72-c/selecting.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-6259170592375941399</id><published>2008-09-25T06:18:00.000-07:00</published><updated>2008-11-29T15:35:02.546-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>RM-788, Knowledge Sharing and Wikis</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SNuTMSlO5LI/AAAAAAAAAFU/2XhORFKHvoc/s1600-h/RM-788.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5249951629986161842" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SNuTMSlO5LI/AAAAAAAAAFU/2XhORFKHvoc/s320/RM-788.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;I have a new "all in one" remote control. You get with it a small manual with instructions and operation codes. These things work that way: you need to set it to your appliances, so there is a specific code for each brand and model and you have to punch in the right code into the remote control, then if the code was accurate, you can start using the remote. In order to adjust it to the specific brand and model of your appliances you have to look for the appropriate codes, listed in the manual. So far so good. But it turned out that my TV set, PILOT of some unknown model, doesn't go with any of the codes listed in the manual for Pilot. One code did work, but only partially. Annoying.&lt;br /&gt;&lt;br /&gt;What would you do at this point? One option was to return the remote to the store and make it ship back to Taiwan or China or wherever it's manufactured.&lt;br /&gt;&lt;br /&gt;But then I remembered the great invention of the Internet. Maybe it will come to my rescue. So I Yahooed and Googled for the name of the remote control, &lt;strong&gt;RM-788 of Universal Electronics&lt;/strong&gt;. And I got to some reseller sites, and even to the site of Universal Electronics themselves. But apart from seeing the picture of my remote there was no useful info available.&lt;br /&gt;&lt;br /&gt;So I came back to the remote and to the manual. It appears that there is an auto-search function of the thing, which is a bit troublesome, being not really automatic, more like “semi-automatic” – the remote pass through all codes, but you have to check each code manually and then if not OK, you need to press the “Power” button to move to the next possible code. Since there are about 400 possible codes for TV sets I was a bit pessimistic. BUT, it did work! After a while I reached &lt;strong&gt;code 138&lt;/strong&gt; which worked perfectly for my Pilot TV (there is a way to know the currently set code, by counting number of led blinks for each digit, so the moment I got it working I wrote down immediately the magic number 138).&lt;br /&gt;&lt;br /&gt;Now comes my social responsibility. I wanted to share this knowledge somewhere, for the benefit of other Pilot-TV owners who may try to use this remote (even if one in the entire universe!). Needless to say that the manufacture site doesn't allow to add comments or tips. Probably they are afraid of obscene language comments, and don't have the resources for an editor. (Do you know of any company that do provide such a “drop a tip in my site” service?)&lt;br /&gt;&lt;br /&gt;There was one site on electronic appliances which did have the ability to add tips and even had the RM-788 remote listed in his catalogue! Unfortunately when trying to submit a tip the site ask me to register and fill in a ton of details (stuff like my mother maiden name, oh madden!) so I left this unwelcoming site in a hurry and rushed to my blog.&lt;br /&gt;&lt;br /&gt;Which made me think -- &lt;strong&gt;We need a Wiki here&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Just to clarify the terms. Speaking about Wiki and the Wiki idea, I refer to the concept of free editing with immediate publication. For some nuances a few operations may require prior registration, but not for adding or editing content. When editing is allowed only for the site owner, or is not immediately reflected in the site, then it's not Wiki for me, it's just a Content Management System, based maybe on Wiki framework and syntax, but not on the Wiki idea.&lt;br /&gt;&lt;br /&gt;The Wiki idea was invented as early as 1994 (see: &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/WikiWikiWeb"&gt;&lt;span style="font-family:arial;"&gt;http://en.wikipedia.org/wiki/WikiWikiWeb&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;).&lt;br /&gt;It came into wide notion with Wikipedia. Followed by many other Wiki sites, some as part of the &lt;/span&gt;&lt;a href="http://wikimediafoundation.org/"&gt;&lt;span style="font-family:arial;"&gt;WikiMedia foundation&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, others include &lt;/span&gt;&lt;a href="http://startrek.wikia.com/wiki/Main_Page"&gt;&lt;span style="font-family:arial;"&gt;Star Trek Wiki&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, &lt;/span&gt;&lt;a href="http://www.wowwiki.com/Main_Page"&gt;&lt;span style="font-family:arial;"&gt;World of Warcraft Wiki&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; and many more (some lists can be found &lt;/span&gt;&lt;a href="http://webtrends.about.com/od/wikilists/tp/list_of_wiki_sites.htm"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, and &lt;/span&gt;&lt;a href="http://webtrends.about.com/lr/wiki_list/250557/1/"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, and &lt;/span&gt;&lt;a href="http://wikindex.com/"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, and &lt;/span&gt;&lt;a href="http://www.wikiindex.org/"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, and of course &lt;/span&gt;&lt;a href="http://search.yahoo.com/search?p=list+wiki+sites"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; and &lt;/span&gt;&lt;a href="http://www.google.co.il/search?q=list+wiki+sites"&gt;&lt;span style="font-family:arial;"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;).&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Why Wiki is the best tool for knowledge sharing?&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;Because it allows someone with good will but no patience for bullshit to just get in and share his knowledge. Publishing the submission right away forces the submitter to pay more attention to his submission. Usually one would invest more time, when knowing that no other person is responsible of editing his post and fixing any spelling mistakes. Of course, someone may need to follow new or edited articles and validate them. But we don't have to wait for the validation in order to see how the new contribution looks, publicly. This is the Wiki idea!&lt;br /&gt;&lt;br /&gt;The fear of vandalism, by the way, is almost irrelevant, when it comes to internal knowledge sharing inside organizations. This is the reason Wiki becomes more and more as the method of choice for knowledge sharing internally inside big corporations.&lt;br /&gt;&lt;br /&gt;As for the RM-788 Pilot-TV code, it appears that there is a Wiki for Product information, called simply &lt;/span&gt;&lt;a href="http://www.productwiki.com/"&gt;&lt;span style="font-family:arial;"&gt;ProductWiki&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. It's commercial (not a non-profit). I would have drop my tip there, but it didn't have the spoken RM-788 listed in its catalogue, and required me to register for creating it, so I quit.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;For more on Wiki as a tool for knowledge sharing, and other good references for managing information in the Wiki way: &lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ikiw.org/"&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;http://www.ikiw.org/&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;-- and specifically: &lt;/span&gt;&lt;a href="http://www.ikiw.org/2008/03/13/create-a-participatory-knowledgebase-on-a-wiki/"&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;create-a-participatory-knowledgebase-on-a-wiki&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.wikipatterns.com/"&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;http://www.wikipatterns.com&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&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/7061498094705606309-6259170592375941399?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6259170592375941399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6259170592375941399' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6259170592375941399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6259170592375941399'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/09/knowledge-sharing.html' title='RM-788, Knowledge Sharing and Wikis'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/SNuTMSlO5LI/AAAAAAAAAFU/2XhORFKHvoc/s72-c/RM-788.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-2746104756971826859</id><published>2008-09-02T09:02:00.000-07:00</published><updated>2009-08-15T14:13:49.494-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><category scheme='http://www.blogger.com/atom/ns#' term='Technology'/><title type='text'>Google open sourcing their new browser, Chrome</title><content type='html'>&lt;span style="font-family:arial;"&gt;Google new browser, &lt;/span&gt;&lt;a href="http://googleblog.blogspot.com/2008/09/fresh-take-on-browser.html"&gt;&lt;span style="font-family:arial;"&gt;Chrome&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, is the talk of the day. And the &lt;/span&gt;&lt;a href="http://blogoscoped.com/google-chrome/"&gt;&lt;span style="font-family:arial;"&gt;comics&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; are indeed great.&lt;br /&gt;&lt;br /&gt;Some were enthusiastic about Google opening this vast project as an open source. Noble indeed. Google themselves are feeling virtuous about it, or at least want us to feel that way. After all, a great tool like this (no one really seen it yet, but they do know how to create a buzz and I guess it will be indeed a good browser) – by releasing this great, superb, new-era browser as an open source, anyone can take it and adapt it to his needs, even Microsoft can, and maybe will even do.&lt;br /&gt;&lt;br /&gt;So why did they do it? Why to open source? You can give it for free without opening it...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.gamesforthebrain.com/google-chrome/37"&gt;&lt;span style="font-family:arial;"&gt;Slide 37&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; lists the noble arguments.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/p&gt;&lt;/span&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SL1glvZatVI/AAAAAAAAAFM/CjkBRApqBwc/s1600-h/37[1].png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5241451742823626066" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SL1glvZatVI/AAAAAAAAAFM/CjkBRApqBwc/s320/37%5B1%5D.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;But could they really?&lt;br /&gt;Do they have the option the ship a proprietary browser?&lt;br /&gt;&lt;br /&gt;NO, because they don’t have one.&lt;br /&gt;&lt;br /&gt;This new Chrome browser is said to be built upon WebKit and Mozilla projects. Both projects are open sourced and require derived work to be open as well (section 3.2 in &lt;/span&gt;&lt;a href="http://www.mozilla.org/MPL/MPL-1.1.html"&gt;&lt;span style="font-family:arial;"&gt;Mozilla Public License&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; and 2 of the &lt;/span&gt;&lt;a href="http://www.gnu.org/licenses/lgpl-2.1.html"&gt;&lt;span style="font-family:arial;"&gt;LGPL&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;).&lt;br /&gt;&lt;br /&gt;They could have find a way to keep some of the code closed, like maybe the V8 javascript VM. But it would probably be too risky legally. And they might need their lawyers ready for Android issues (or for buying Sun).&lt;br /&gt;&lt;br /&gt;Bottom line:&lt;br /&gt;&lt;br /&gt;No need to be too cocky about open sourcing. As nice as it is that you open it, you probably had no other choice, other open source initiatives worked hard on writing parts of your code.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2746104756971826859?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2746104756971826859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2746104756971826859' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2746104756971826859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2746104756971826859'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/09/google-opening-chrome.html' title='Google open sourcing their new browser, Chrome'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SL1glvZatVI/AAAAAAAAAFM/CjkBRApqBwc/s72-c/37%5B1%5D.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-6955232475161810979</id><published>2008-09-01T04:17:00.000-07:00</published><updated>2008-09-01T04:22:09.937-07:00</updated><title type='text'>CPU and GPU, from nvision 2008</title><content type='html'>&lt;span style="font-family:arial;"&gt;Nvidia had a geek party in San Jose, called &lt;/span&gt;&lt;a href="http://www.nvision2008.com/"&gt;&lt;span style="font-family:arial;"&gt;nvision2008&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;.&lt;br /&gt;In one of the peak events of the conference, Adam Savage and Jamie Hyneman came to demonstrate the difference between a Central Processing Unit (CPU) and a Graphics Processing Unit (GPU), using color cannons.&lt;br /&gt;(See: &lt;/span&gt;&lt;a href="http://www.nvidia.com/content/nvision2008/day3.html"&gt;&lt;span style="font-family:arial;"&gt;http://www.nvidia.com/content/nvision2008/day3.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;). &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5241011009703894098" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SLvPvslP3FI/AAAAAAAAAFE/yShfpY0CU8Y/s320/nvision08.jpg" border="0" /&gt;&lt;br /&gt;Cory Ondrejka, former CTO at Linden Lab and one of Second Life founders posted the following videos from the party, showing the color cannons in action: &lt;/span&gt;&lt;a href="http://ondrejka.blogspot.com/2008/08/geek-celebrity.html"&gt;&lt;span style="font-family:arial;"&gt;collapsing geography: geek celebrity&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. Make you understand the power of GPUs. An inspiring color cannon! Wow! &lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6955232475161810979?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6955232475161810979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6955232475161810979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6955232475161810979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6955232475161810979'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/09/cpu-and-gpu-from-nvision-2008.html' title='CPU and GPU, from nvision 2008'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://3.bp.blogspot.com/_msmuQKgFPkU/SLvPvslP3FI/AAAAAAAAAFE/yShfpY0CU8Y/s72-c/nvision08.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1856719274836521744</id><published>2008-08-29T02:52:00.000-07:00</published><updated>2008-11-29T15:42:19.259-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Adding abilites to Java's ThreadPoolExecutor</title><content type='html'>&lt;span style="font-family:arial;"&gt;I had a discussion on Java's ThreadPoolExecuter, which seem not to have the ability to block producer from adding tasks when the thread pool's queue is full. I went through some possible solutions and I'm gonna write something about it, so please stay tuned (and if you have something to tip on this issue, say it now)&lt;/span&gt;&lt;span style="font-family:arial;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-----------------&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Happy to update:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;I've published it, in java.net, it is called &lt;/span&gt;&lt;a href="http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-pool-executor.html"&gt;&lt;span style="font-family:arial;"&gt;Creating a NotifyingBlockingThreadPoolExecuter&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1856719274836521744?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1856719274836521744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1856719274836521744'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/addining-abilites-to-javas.html' title='Adding abilites to Java&apos;s ThreadPoolExecutor'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-2945293215529956777</id><published>2008-08-28T11:28:00.000-07:00</published><updated>2009-08-15T14:14:55.556-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Industry'/><title type='text'>Google, on the way down</title><content type='html'>&lt;span style="font-family:arial;"&gt;I host my blog at blogspot, as you can see. Today I was editing the draft of the post "&lt;/span&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/08/changelightbulbwindowhandleex-for-blind.html"&gt;&lt;span style="font-family:arial;"&gt;ChangeLightBulbWindowHandleEx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;" when suddenly, between one automatic save to another, the draft just disappeared. Vanished. Gone. I was left with the title alone, no content.&lt;br /&gt;&lt;br /&gt;There is no versions saving in blogspot, so I couldn't go to the previous version. Then I thought maybe I can turn to blogspot support and ask them to recover my draft, they might have it there somewhere. Long shot, but worth trying.&lt;br /&gt;&lt;br /&gt;I started to look for the e-mail of the blogspot support.&lt;br /&gt;And, after a while I found the link saying &lt;/span&gt;&lt;a href="http://help.blogger.com/bin/request.py?contact_type=contact_policy"&gt;&lt;span style="font-family:arial;"&gt;Contacting Support&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. Great! So I followed it, to a nice page. And another nice page. And another. None of which offered an e-mail or a submission form. All tried to suggest advices for all sort of problems. There was a link leading to &lt;/span&gt;&lt;a href="http://groups.google.com/group/blogger-help"&gt;&lt;span style="font-family:arial;"&gt;Blogger Help&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, but there again, no e-mail or decent bug report form. BLAH!&lt;br /&gt;&lt;br /&gt;Then I started looking maybe someone already bumped into the same problem, maybe there is a hope somewhere. And I got to this &lt;/span&gt;&lt;a href="http://groups.google.com/group/blogger-help-troubleshoot/browse_thread/thread/27184b0927bb2137"&gt;&lt;span style="font-family:arial;"&gt;mailing thread&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; at the Google Blogger Help Group. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SLb7lP6vtVI/AAAAAAAAAE8/RbBz-BAoi8M/s1600-h/blogspot_problem.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5239651833838810450" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SLb7lP6vtVI/AAAAAAAAAE8/RbBz-BAoi8M/s320/blogspot_problem.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;It could have been funny if it wasn't sad.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Don't you care about your bugs?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I know it doesn't really say something about the business model of google. But it says that they lost it somewhere down the road. Don't you have enough resources to care about your quality?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If I'd have google stock I would sell now.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2945293215529956777?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2945293215529956777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2945293215529956777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2945293215529956777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2945293215529956777'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/google-on-way-down.html' title='Google, on the way down'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SLb7lP6vtVI/AAAAAAAAAE8/RbBz-BAoi8M/s72-c/blogspot_problem.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-5106552666188481680</id><published>2008-08-28T08:19:00.000-07:00</published><updated>2008-11-29T15:35:52.129-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>ChangeLightBulbWindowHandleExfor Blind Catalan-speaking SpaniardA response to mistralzonline on "Why is that?"</title><content type='html'>&lt;span style="font-family:arial;"&gt;My friend Alex Romanov, in a recent &lt;/span&gt;&lt;a href="http://mistralzonline.blogspot.com/2008/07/why-is-that.html"&gt;&lt;span style="font-family:arial;"&gt;post&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; at his blog, asked why Nokia is not supporting a synchronization tool for his Mac, while he could easily find such a free tool on the web. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SLbqkveC5dI/AAAAAAAAAEs/rB2r-Lstz-4/s1600-h/ChangeBulbPic.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5239633133430826450" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 241px; CURSOR: hand; HEIGHT: 205px" height="236" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SLbqkveC5dI/AAAAAAAAAEs/rB2r-Lstz-4/s320/ChangeBulbPic.jpg" width="292" border="0" /&gt;&lt;/a&gt;The answer for this question is found in the known article by Eric Lippert, “&lt;a href="http://blogs.msdn.com/ericlippert/archive/2003/10/28/53298.aspx"&gt;How many Microsoft &lt;/a&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2003/10/28/53298.aspx"&gt;employees does it take to change a lightbulb?&lt;/a&gt;”, making the math of how much resources are needed for a formal release of a simple thing. And since it takes a lot, you need not get off your course. Which can easily happen.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;To summarize, the answer is: &lt;/span&gt;&lt;span style="font-family:arial;"&gt;Focus.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Choose your lightbulbs!&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;I was once responsible of a State Machine module for a communication component. With the State Machine module we were providing also a nice editor tool, based on Microsoft Visio. The users liked the Visio editor which made life easier for them. We even thought of adding debug options to this editor to allow the users to run in debug mode in within our Visio tool. At some point I decided to stop the development and support of this tool and instructed all users to start writing their state machines in the raw XML that the module itself received as input. It happened when I realized that we are spending too much time on this nice utility. Every new feature in the State Machine module required a parallel development for the Visio tool. Too much support effort was invested in negotiating features with the users and bugs with the testing team, training and support, keeping up with the Visio versions and more. I realized that we do not have enough resources to support all of this (the resource was in fact one person, supporting by himself both the State Machine module and the Visio tool…, it was, by the way, the man behind mistralzonline from above, so he should know!). Focus is the word. When we realized that we cannot do it all at the required level of quality, we had to cut. And it’s better to cut the utility Visio tool rather than the module itself.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When Nokia decides not to provide the tool for synchronizing one of their models with Mac, it’s because they believe that with the resources they would put in it, they cannot decently do a good job. It’s not only development, it’s the entire life cycle, including support for users who get stuck (and do it better than google, a post on the horrible google support will follow soon).&lt;br /&gt;&lt;br /&gt;Now, Nokia has the option of managing a community or at least pointing to the available solutions on the web. After all, there was such a free tool out there. It is interesting to note that not many commercial companies officially manage such a development community or point at available supporting tools related with their product. Sun does have the java.net, but it’s more like an open source arena.&lt;br /&gt;&lt;br /&gt;Why is that?&lt;br /&gt;&lt;br /&gt;Because for Nokia, pointing at a tool, even if accompanied with the common disclaimer waiving any liability or guarantee, still means taking responsibility. If the tool infringes privacy, causes loss of data or just simply doesn’t work right, the furious public will come to Nokia. To take such a responsibility Nokia would have to thoroughly test the tool, which brings us back to square one. This is why they choose to refrain and let you pick it up by yourself, which as appears you can do quite well. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-5106552666188481680?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/5106552666188481680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=5106552666188481680' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5106552666188481680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/5106552666188481680'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/changelightbulbwindowhandleex-for-blind.html' title='ChangeLightBulbWindowHandleEx&lt;br/&gt;for Blind Catalan-speaking Spaniard&lt;h3&gt;A response to mistralzonline on &quot;Why is that?&quot;&lt;/h3&gt;'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/SLbqkveC5dI/AAAAAAAAAEs/rB2r-Lstz-4/s72-c/ChangeBulbPic.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1698624424751895972</id><published>2008-08-26T07:29:00.000-07:00</published><updated>2008-08-27T05:10:55.516-07:00</updated><title type='text'>Rolling the Dice - the Cube Project for Silverlight</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SLVAirBGTvI/AAAAAAAAAEc/yxok8u4vcEM/s1600-h/Pic2[1].jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5239164705922502386" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SLVAirBGTvI/AAAAAAAAAEc/yxok8u4vcEM/s200/Pic2%5B1%5D.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;I am teaching a "Product Workshop" course at the &lt;a href="http://www.mta.ac.il/"&gt;MTA&lt;/a&gt; college in Tel-Aviv&lt;/span&gt;&lt;span style="font-family:arial;"&gt;.&lt;br /&gt;Usually students submit something that can be used as a "black box" product, like: a web application managing event invitations, a simulator for physics rules and many other nice things.&lt;br /&gt;Whenever a student wants to create a library or a toolkit (that is, something to be used by other applications), I urge him or her (well, it's a him, let's stop with this political correctness, when it is a she the product is a very nice well designed, all screen pink, web application for match-making...&lt;sup&gt;*&lt;/sup&gt;), well, I urge him to put it out as an open source.&lt;br /&gt;&lt;br /&gt;So here is something recently created by my student, Itamar Kotler:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.codeproject.com/KB/silverlight/CubeProject.aspx"&gt;&lt;span style="font-family:arial;"&gt;http://www.codeproject.com/KB/silverlight/CubeProject.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;It's a component for creating a rotating cube out of 6 photos, right into your web site.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Funny that it is not inherently supported by Silverlight (there is something in Silverlight but the argument is that it doesn't really support full rotation through all possible angles). I guess it will have soon a decent substitute as part of Silverlight, which will probably disappoint Itamar. But then again he can always argue that he drove Microsoft to implement and present a decent rotating cube.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SLVAPLC13SI/AAAAAAAAAEM/4a5hHKEX-G8/s1600-h/Pic1[1].jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5239164370922364194" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SLVAPLC13SI/AAAAAAAAAEM/4a5hHKEX-G8/s400/Pic1%5B1%5D.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;sup&gt;*&lt;/sup&gt; Just before I'd be accused of being a male chauvinist swine, some of the best projects I get are from women. And I can live with pink screens.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1698624424751895972?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1698624424751895972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1698624424751895972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1698624424751895972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1698624424751895972'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/rolling-dice-cube-project-for.html' title='Rolling the Dice - the Cube Project for Silverlight'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SLVAirBGTvI/AAAAAAAAAEc/yxok8u4vcEM/s72-c/Pic2%5B1%5D.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1556784603669397398</id><published>2008-08-01T06:18:00.000-07:00</published><updated>2008-12-09T00:08:41.901-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Do you have an API?</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SI8URvt4b-I/AAAAAAAAAEE/o9x6yd5ygMI/s1600-h/acura_int_engine.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5228419987499675618" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SI8URvt4b-I/AAAAAAAAAEE/o9x6yd5ygMI/s320/acura_int_engine.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;This is &lt;strong&gt;so&lt;/strong&gt; &lt;strong&gt;basic&lt;/strong&gt;, yet still ignored so often.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;When you buy a SW tool or thinking of developing one, one of the first questions to ask is: is there some kind of API exposed? CLI (Command Line Interface)? Web Services Interface?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A product without a clear good API means that you cannot customize it to your own needs, it's a "take it or leave it". Of course, you can ask for features and then wait in line.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A good API must allow to preseve states when needed. Suppose I want to perform a series of operations, like for example a chain of queries, I need to be able to send the 2nd query for filtering the result set without reminding the tool what was the first query. And the results should probably be cached for a specific amount of time. So I'd probably need some session ticket, request Id or alike.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;With a good API I can use the tool in things that were not originally planned, and still do well. And when a question arises: does the tool know how to do this and that, the answer would much more easily be: yes, it does have the ability to programatically allow it on the client side.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Now if the product doesn't have an external good API, it probably says that it is not well designed with a clear separation of a Model View Controller (MVC) architecture.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;&lt;u&gt;Bottom line&lt;/u&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;u&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:Arial;"&gt;Even the most graphical product MUST have a model and an external API.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Start always by thinking on the API or CLI version and ignore the presentation layer.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;And think twice before taking a product that can be opearated only via its specific UI environment.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:Arial;"&gt;Think - MVC, MVC, MVC, MVC, MVC, MVC, MVC, MVC, MVC &lt;/span&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/7061498094705606309-1556784603669397398?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1556784603669397398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1556784603669397398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1556784603669397398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1556784603669397398'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/08/do-you-have-api.html' title='Do you have an API?'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SI8URvt4b-I/AAAAAAAAAEE/o9x6yd5ygMI/s72-c/acura_int_engine.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-4432653183933312715</id><published>2008-07-21T06:26:00.000-07:00</published><updated>2009-08-15T14:15:41.225-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>To AJAX or NOT to AJAX?</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SIUBMZ18OZI/AAAAAAAAAD8/yz3GDDcuDZg/s1600-h/ajax.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5225584255240518034" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SIUBMZ18OZI/AAAAAAAAAD8/yz3GDDcuDZg/s200/ajax.jpg" border="0" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; &lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I had today a discussion on when to use AJAX and when not.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The idea is simple: &lt;strong&gt;the plain old request-response is usually a good thing&lt;/strong&gt;, if you keep your pages small, which you should (CSS and JavaScripts should be external, thus a nicely built pure HTML page should be around 10-20K, not more).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The plain old request-response keeps your url meaningful - the state of the page is reflected by the url, which is a very good practice to follow.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The plain old request-response keeps your Back button function as it should, without any unnecessary tricks.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The plain old request-response keeps all your content available for search engines, which is usually what you want.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The plain old request-response keeps your user using what he is used to. No surprises.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:arial;"&gt;So - when should AJAX be used?&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Auto-completion&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;For fetching partial long lists based on some initial input&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Quick response to something insignificant, like showing the current results of a poll right after your vote is done, blocking you from re-voting (not that you cannot delete your cookie or session identifier and go back to the page to vote again, usually the vote is not registered per IP address)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;"&gt;Some additional insights on this topic can be found here:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://webdesign.about.com/od/ajax/a/aa092506.htm"&gt;&lt;span style="font-family:arial;"&gt;http://webdesign.about.com/od/ajax/a/aa092506.htm&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-4432653183933312715?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/4432653183933312715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=4432653183933312715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4432653183933312715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4432653183933312715'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/07/to-ajax-or-not-to-ajax.html' title='To AJAX or NOT to AJAX?'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/SIUBMZ18OZI/AAAAAAAAAD8/yz3GDDcuDZg/s72-c/ajax.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-476536324900011733</id><published>2008-07-20T23:16:00.000-07:00</published><updated>2008-12-09T00:08:42.139-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Building features organically</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SIT8u4b7gSI/AAAAAAAAAD0/y1tce5eFriE/s1600-h/Sewing_Machine.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5225579350010331426" style="WIDTH: 127px; CURSOR: hand; HEIGHT: 141px" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SIT8u4b7gSI/AAAAAAAAAD0/y1tce5eFriE/s200/Sewing_Machine.jpg" width="140" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I ran into this interesting post and wanted to share it with you:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://marcelo.sampa.com/marcelo-calbucci/brave-tech-world/Building-features-organically.htm"&gt;&lt;span style="font-family:arial;"&gt;http://marcelo.sampa.com/marcelo-calbucci/brave-tech-world/Building-features-organically.htm&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This is how it begins:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;blockquote&gt;One of the most interesting aspects of Agile development is to not build things&lt;br /&gt;that you won't use now or over-engineer a component because "we might need this&lt;br /&gt;in the future". That is a wonderful thing for developers and it does cut a lot&lt;br /&gt;of complexity and time to deliver the feature, by consequence making it less&lt;br /&gt;buggy.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Now, the rest is quite the same, so you can either go there or not.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;But the first comment (and only one when I visitied) is pretty smart. And counting on you lazy fellows that you might not invest in following the link and scrolling down, here's what Mike comments:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;I spec from the "top down" and build from the "bottom up". That way, I think I&lt;br /&gt;have a more throught-out overall plan, and it eliminates implementing some&lt;br /&gt;possible dead-end features. Specs are much more malleable and have far fewer&lt;br /&gt;requirements from a quality point of view. So I find it worthwhile to be a bit&lt;br /&gt;more expansive and "future thinking" in a spec. But when it comes down to&lt;br /&gt;implementation, I try to do as you say - and build from the bottom up with the&lt;br /&gt;minimum set of functionality that can be made to work consistently. You can then&lt;br /&gt;decide when you've "fiddled" enough, and decide to ship the features to your&lt;br /&gt;customers.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Well said.&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/7061498094705606309-476536324900011733?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/476536324900011733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=476536324900011733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/476536324900011733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/476536324900011733'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/07/building-features-organically.html' title='Building features organically'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/SIT8u4b7gSI/AAAAAAAAAD0/y1tce5eFriE/s72-c/Sewing_Machine.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1083242914445202676</id><published>2008-07-03T23:43:00.000-07:00</published><updated>2008-12-09T00:08:42.392-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Thinking Procedural From Object Oriented and Event Driven Back to Procedural Programming</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SG1lzXVkTII/AAAAAAAAADs/5-a1rnmo3_c/s1600-h/ClassDiagram.gif"&gt;&lt;img id="BLOGGER_PHOTO_ID_5218939476304481410" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SG1lzXVkTII/AAAAAAAAADs/5-a1rnmo3_c/s320/ClassDiagram.gif" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000099;"&gt;&lt;strong&gt;Object Oriented Programming&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Object Oriented Programming fits most of the applications we create today. The idea of methods or services, encapsulated into classes or components, with clear separation of concern, isolated from each other, is clear and obvious. This is the heart of the Object Oriented concept, of Component Based Development, of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;SOA&lt;/span&gt;, etc.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;color:#000099;"&gt;&lt;strong&gt;Event Driven Programming&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Event Driven is another concept, raised mainly from User Interface applications, but also protocol stacks, state machines, message brokers and all kind of listeners in general, can be seen as based on event driven concepts. Event Driven does not necessarily relate to Object Oriented Architecture. But yet, it is not a simple procedural programming.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;color:#000099;"&gt;&lt;strong&gt;Other Non-Procedural&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Other types of programming methods which are non-procedural in their nature may include Pattern Matching Programming (e.g. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;XSLT&lt;/span&gt;) and Declarative Programming (e.g. HTML, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SQL&lt;/span&gt;; some view Object Oriented Programming as declarative, I disagree).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#000099;"&gt;&lt;strong&gt;Thinking Procedural&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;All above - Object Oriented, Event Driven, Pattern Matching, Declarative Programming - keep us apart from the flow. We get used to ignore the flow, the entire end-to-end scenarios which eventually creates the system.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Long time since we created a pure procedural program. This made us stop thinking in a procedural way. Which is problematic, as eventually the program will run as a sequence and we have to make sure it will work properly.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Here come to rescue: Sequence Diagrams, Scenarios, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;XP&lt;/span&gt; User Stories, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;UI&lt;/span&gt; Storyboards and Test Driven Development. They were all invented to assist us solving the problem of forcing us back to "thinking procedural".&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SG1itrk1VvI/AAAAAAAAADk/1k7QdD3Px44/s1600-h/sequence.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5218936080123123442" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SG1itrk1VvI/AAAAAAAAADk/1k7QdD3Px44/s320/sequence.jpg" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1083242914445202676?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1083242914445202676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1083242914445202676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1083242914445202676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1083242914445202676'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/07/thinking-procedural-from-object.html' title='Thinking Procedural&lt;br&gt;&amp;nbsp;&lt;h3&gt;From Object Oriented and Event Driven Back to Procedural Programming&lt;/h3&gt;'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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/_msmuQKgFPkU/SG1lzXVkTII/AAAAAAAAADs/5-a1rnmo3_c/s72-c/ClassDiagram.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-2146660653872261971</id><published>2008-06-30T04:19:00.000-07:00</published><updated>2008-12-09T00:08:42.870-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Bim Bam BOM</title><content type='html'>&lt;span style="font-family:arial;"&gt;We had this strange bug recently, while trying to parse a perfectly healthy XML file we got an exception saying:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.xml.sax.SAXParseException: Document root element is missing.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;We could, however, open the XML file in the browser without an error. And also our XML editor took it without a problem. Yet, in our code trying to operate some XSL transformation using Xalan, we got the exception above. And the problem was not with the transformation itself, at least according to the exception. The problem is with the XML document starting without a root. Though the first character seen in the file was an opening triangle bracket...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Well, there are things beyond what you see.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;To find out what is the exact stream of bytes that the transformer receives, and doesn't like, we added the simplest debug line, dumping the bytes from the file to screen, not as chars but in their value. There appeared to be two bytes before the opening triangle bracket of the XML: &lt;strong&gt;&lt;span style="color:#660000;"&gt;FF FE&lt;/span&gt;&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;At this point, my friend and colleague &lt;a href="http://www.linkedin.com/pub/0/B4A/428"&gt;Effie Nadiv&lt;/a&gt; (famous for his &lt;a href="http://www.effie.co.il/"&gt;Hebrew site&lt;/a&gt;, and a UI authority and legend), shouted out: it's the BOM! Xalan doesn't recognize the BOM correctly!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;And without further ado he presented the file (same file) in text mode and in binary mode:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SGjQ4jxfavI/AAAAAAAAACo/1FU-xHPMGw0/s1600-h/text_bigger.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5217649838402792178" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SGjQ4jxfavI/AAAAAAAAACo/1FU-xHPMGw0/s320/text_bigger.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SGjWYcBHpjI/AAAAAAAAADI/wDgrYyxraTE/s1600-h/WithBOM_bigger.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5217655883634812466" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SGjWYcBHpjI/AAAAAAAAADI/wDgrYyxraTE/s400/WithBOM_bigger.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;See the FF FE at the beginning? This is the BOM.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;BOM&lt;/strong&gt; stands for &lt;strong&gt;B&lt;/strong&gt;yte-&lt;strong&gt;O&lt;/strong&gt;rder-&lt;strong&gt;M&lt;/strong&gt;ark, added to UTF-16 documents to denote the order of the bytes in each two consecutive bytes creating a character. UTF-8 documents may also have BOM, but it will be redundant and have no mean.&lt;br /&gt;&lt;br /&gt;To read more about Unicode, UTF-8, UTF-16 and BOM, you may want to go to:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://unicode.org/faq/utf_bom.html"&gt;&lt;span style="font-family:arial;"&gt;http://unicode.org/faq/utf_bom.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Byte_Order_Mark"&gt;&lt;span style="font-family:arial;"&gt;http://en.wikipedia.org/wiki/Byte_Order_Mark&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;But, before you rush to the above, a GREAT reading material to understand once and for all the entire encoding and charset thing:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.joelonsoftware.com/articles/Unicode.html"&gt;&lt;span style="font-family:arial;"&gt;The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; by Joel Spolsky.&lt;br /&gt;This is a must read!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;p&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;Specifically to solve the above problem we changed the doc to UTF-8 without BOM. Most text editors support conversion to different unicode transformation formats, and allow the user to decide whether to add BOM to UTF-8 or not (probably it's better not to add, just turn off the option underneath).&lt;/span&gt; &lt;p&gt;&lt;span style="font-family:arial;"&gt;.&lt;/span&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SGjZ9WJXNGI/AAAAAAAAADY/NVGPKEt7tZM/s1600-h/config.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5217659816248816738" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SGjZ9WJXNGI/AAAAAAAAADY/NVGPKEt7tZM/s400/config.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;=========================================&lt;br /&gt;&lt;/span&gt;Added 21/7/08:&lt;br /&gt;------------------------------&lt;br /&gt;Just found this old newsgroup entry on the subject...&lt;br /&gt;&lt;a href="http://biglist.com/lists/xsl-list/archives/200208/msg01302.html"&gt;&lt;span style="font-family:arial;"&gt;http://biglist.com/lists/xsl-list/archives/200208/msg01302.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;=========================================&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-2146660653872261971?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/2146660653872261971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=2146660653872261971' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2146660653872261971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/2146660653872261971'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/06/bim-bam-bom.html' title='Bim Bam BOM'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SGjQ4jxfavI/AAAAAAAAACo/1FU-xHPMGw0/s72-c/text_bigger.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-6526054496459672113</id><published>2008-06-26T05:53:00.000-07:00</published><updated>2008-12-09T00:08:43.180-08:00</updated><title type='text'>Tag, Log, Debug!</title><content type='html'>&lt;span style="font-family:arial;"&gt;I was presenting with my friend Alex Romanov our work on "Automated Log Generation and Analysis using Collaborative Tagging" at the &lt;/span&gt;&lt;a href="http://www.haifa.ibm.com/Workshops/ple2008/program.shtml"&gt;&lt;span style="font-family:arial;"&gt;IBM Programming Languages and Environments seminar 2008&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;, yesterday (25/6).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This is Alex with the poster describing our work:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SGOR9uPMuXI/AAAAAAAAAAo/jiJQkGekeuM/s1600-h/25-06-08_1315.jpg"&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SGOSLpT4_9I/AAAAAAAAAAw/JX9uLfZu4gA/s1600-h/25-06-08_1315.jpg"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216173522190663634" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SGOSLpT4_9I/AAAAAAAAAAw/JX9uLfZu4gA/s320/25-06-08_1315.jpg" border="0" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;More info on this work can be found here: &lt;a href="http://ed.finnerty.googlepages.com/taglogdebug"&gt;http://ed.finnerty.googlepages.com/taglogdebug&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;a href="http://ed.finnerty.googlepages.com/Automated_Log_Generation.pdf"&gt;Here you can find the initial paper&lt;/a&gt;.&lt;br /&gt;And finally, a blog that will follow our work was opened here: &lt;a href="http://taglogdebug.blogspot.com/"&gt;http://taglogdebug.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-6526054496459672113?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/6526054496459672113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=6526054496459672113' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6526054496459672113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/6526054496459672113'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/06/tag-log-debug.html' title='Tag, Log, Debug!'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SGOSLpT4_9I/AAAAAAAAAAw/JX9uLfZu4gA/s72-c/25-06-08_1315.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-4833112965826027415</id><published>2008-06-24T06:18:00.000-07:00</published><updated>2008-12-09T00:08:44.481-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='OOPSLA'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Eclipse Plugins Tutorial (OOPSLA '07)</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SGOyEOheKdI/AAAAAAAAABI/gOna7Qce5FQ/s1600-h/oopsla07_09.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216208579112872402" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SGOyEOheKdI/AAAAAAAAABI/gOna7Qce5FQ/s320/oopsla07_09.jpg" border="0" /&gt;&lt;/a&gt; &lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOx8PGjaKI/AAAAAAAAABA/a8qTOzp3lkQ/s1600-h/oopsla07_10.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216208441829451938" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOx8PGjaKI/AAAAAAAAABA/a8qTOzp3lkQ/s320/oopsla07_10.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;I was asked where can people get the materials from the tutorial on "Creating Plug-ins and Applications on Eclipse Platform" that Alex Romanov and I gave in Montreal on OOPSLA '07. It was while ago, and the materials are on the web already. But here are the links, as it seems google is not doing a good job referring people to the googlegroups site we created...&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;The tutorial deals with all the important things for getting started with Eclipse plug-ins: creating a plug-in project, the components of a plug-in project, GEF, MVC in the Eclipse Plug-in architecture, SWT, Actions, RCP and more.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;So here is &lt;a href="http://oopsla07_t49.googlegroups.com/web/oopsla07_t49-companion.pdf?gda=vZBTs0sAAACLLsnOMPfkrONCRMYFIi-5tf9ZYheZr9mdiS6T_ZL9U2G1qiJ7UbTIup-M2XPURDTEC1dypUwPdAA-XjtP8pNErynbaoq0hT5HnV2YIc7ecg"&gt;the companion booklet&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;And here are &lt;a href="http://oopsla07_t49.googlegroups.com/web/oopsla07_t49-slides.ppt?gda=glk5fEgAAACLLsnOMPfkrONCRMYFIi-5tf9ZYheZr9mdiS6T_ZL9U2G1qiJ7UbTIup-M2XPURDT7SCdIfWENu3Zb6-upc5RvGmAj5XgA6mfhHlBJReCTrw"&gt;the slides&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Both can be printed or redistributed, as is, for any purpose, referring back to the source.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Hope you can find it useful.&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SGOzCpGfITI/AAAAAAAAABw/ORF0oGRCiDU/s1600-h/Montreal2.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216209651399336242" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SGOzCpGfITI/AAAAAAAAABw/ORF0oGRCiDU/s200/Montreal2.jpg" border="0" /&gt;&lt;/a&gt; &lt;a href="http://3.bp.blogspot.com/_msmuQKgFPkU/SGOzCyhaW7I/AAAAAAAAAB4/pUew-b1Nzxk/s1600-h/Montreal3.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216209653928188850" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_msmuQKgFPkU/SGOzCyhaW7I/AAAAAAAAAB4/pUew-b1Nzxk/s200/Montreal3.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:78%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzDNo3tRI/AAAAAAAAACI/y3QlchjGECQ/s1600-h/oopsla07_06.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216209661207229714" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzDNo3tRI/AAAAAAAAACI/y3QlchjGECQ/s200/oopsla07_06.jpg" border="0" /&gt;&lt;/a&gt; &lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzC83oxeI/AAAAAAAAACA/U_e4lsCTOCg/s1600-h/oopsla07_05.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216209656705762786" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzC83oxeI/AAAAAAAAACA/U_e4lsCTOCg/s200/oopsla07_05.jpg" border="0" /&gt;&lt;/a&gt; &lt;a href="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzDIbvpeI/AAAAAAAAACQ/kQsNrHoWrkw/s1600-h/oopsla07_07.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5216209659809998306" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_msmuQKgFPkU/SGOzDIbvpeI/AAAAAAAAACQ/kQsNrHoWrkw/s200/oopsla07_07.jpg" border="0" /&gt;&lt;/a&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/7061498094705606309-4833112965826027415?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/4833112965826027415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=4833112965826027415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4833112965826027415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4833112965826027415'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/06/eclipse-plug-ins-tutorial-from-oopsla.html' title='Eclipse Plugins Tutorial (OOPSLA &apos;07)'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SGOyEOheKdI/AAAAAAAAABI/gOna7Qce5FQ/s72-c/oopsla07_09.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-1650005651428770927</id><published>2008-06-11T23:40:00.000-07:00</published><updated>2008-12-09T00:08:44.626-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>False Requirements</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_msmuQKgFPkU/SFA9hNkVS9I/AAAAAAAAAAg/_SiqRYlNcBE/s1600-h/giraffe.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="A giraffe" src="http://4.bp.blogspot.com/_msmuQKgFPkU/SFA9hNkVS9I/AAAAAAAAAAg/_SiqRYlNcBE/s200/giraffe.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Suppose you are assigned to design a system that should carry out people from place to place, and occasionally let's say once in ten years, would have to travel a giraffe. It's tricky, but you may be able to come out with some strange car with a very high ceiling, working out the balance and stabilization. It may not be so economic, but who is going to be piker when it comes to carrying giraffes. (One can of course suggest a car without a ceiling at all, which might be a good solution, but one of the other requirements rejects a convertible.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;It turns out that we are often bending and twisting simple systems just to carry the giraffe. And in many cases when digging into, we find out the giraffe was not even in the formal requirements to begin with! It grew in somewhere, in one's imagination, and became an important part of the system. Oh, how much we could have saved without this giraffe, and the system could have been much simpler...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;Let the giraffe travel on its own!&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;If it was in the original requirements, go back to the system analyst or the guy who wrote the requirements and ask him: do you really need this giraffe thing? maybe we can send him with another vehicle?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Giraffes are nice, but don't let them into your system.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Unless you want to run a zoo.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1650005651428770927?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1650005651428770927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1650005651428770927' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1650005651428770927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1650005651428770927'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/06/false-requirements.html' title='False Requirements'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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://4.bp.blogspot.com/_msmuQKgFPkU/SFA9hNkVS9I/AAAAAAAAAAg/_SiqRYlNcBE/s72-c/giraffe.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-4444697721173281101</id><published>2008-05-30T06:32:00.000-07:00</published><updated>2008-11-29T15:39:25.737-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Recruitment'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>What would you like to know about your candidate? (Or - how can you know that he is Smart and Gets things done?)</title><content type='html'>&lt;p&gt;&lt;span style="font-family:arial;"&gt;After &lt;/span&gt;&lt;a href="http://softwareanimals.blogspot.com/2008/05/java-generics-erasure-reification.html"&gt;&lt;span style="font-family:arial;"&gt;my session at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;JavaDay&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; I had a conversation with &lt;/span&gt;&lt;a href="http://www.linkedin.com/pub/0/510/283"&gt;&lt;span style="font-family:arial;"&gt;a colleague&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; from Sun on technical interviews. We started with the question whether a Java candidate should be in the details of Generics (e.g. know the term "erasure" and what it means). I'll touch this in a moment but let's begin in an ordered manner.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What do you need to achieve in an interview? &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The famous answer comes from Joel &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Spolky's&lt;/span&gt;&lt;/span&gt; &lt;a href="http://www.joelonsoftware.com/articles/fog0000000073.html"&gt;"Smart &amp;amp; Gets Things Done"&lt;/a&gt; known article (it has an updated version, but I like better the original one. And it got out by now also as a &lt;a href="http://www.joelonsoftware.com/items/2007/06/05.html"&gt;book&lt;/a&gt; carrying the same title!) Sorry for the massive PR for Joel (he is NOT my cousin), but this is really a great source to begin with.&lt;br /&gt;&lt;br /&gt;Following Joel, let's just mark out that you need to achieve two things in an interview: &lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;color:#000000;"&gt;&lt;ol&gt;&lt;li&gt;Attract the candidate: sell yourself, your company and the offered position. Make sure that if you want this person you will get him.&lt;br /&gt;-- This is highly important and sometimes neglected (e.g. making the candidate wait for his interview for 30 minutes), but we will keep this for another post.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Make a Hire / No Hire decision (is the candidate Smart and Gets things done?)&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;__________________&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;color:#000066;"&gt;&lt;strong&gt;What do you need to know about your candidate? &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Communication skills&lt;/strong&gt; - can he explain himself well. Ask him about his previous job or big project at college, see if he can well explain what he did.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Does he see the big picture?&lt;/strong&gt; - continuing with his big project, make him explain what other did in the same project, ask about other alternatives that were there to implement the same thing and why the one taken was selected.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Technologies&lt;/strong&gt; - ask about the technologies used in his big project and what can he tell about each of them.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Design&lt;/strong&gt; - you can learn about the candidate's design abilities by talking about the design of his big project, but it would be better here to tackle him with something he haven't thought about or at least didn't talk about in his previous interviews. It can be a pretty simple design, like some kind of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;LRU&lt;/span&gt;&lt;/span&gt; Cache, or Copy on Write mechanism, or anything else you have in mind. But make sure to listen - ask shortly, give enough time to think and then listen. This is a good opportunity to see how the guy thinks.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Implementation&lt;/strong&gt; - if the candidate is going to write code, let him do it in the interview. You will be amazed how many fail at this stage. There is a debate whether the code phase should be on paper, on a PC but only with a Text Editor (and Help?), or with a full-blown &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;IDE&lt;/span&gt;&lt;/span&gt;. Each of the alternatives may shed light on a different interesting angle. The super-candidate should excel in all of the environments, he may be using all of them in his day-to-day life simultaneously. What would we say about a candidate that gets the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;IDE&lt;/span&gt;&lt;/span&gt; but when lag-behind gives the excuse that he is not used to this &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;IDE&lt;/span&gt;&lt;/span&gt;? I believe paper exam for short implementation is good, as long as you tell the candidate that it's OK if he makes small syntax mistakes. The code should be considered as &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;pseud&lt;/span&gt;-code, but all important aspects should be included (e.g. resource management and exceptions). Then of course he has to explain what he did.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reading other people code&lt;/strong&gt; - many developers are really good in writing their own new code but do miserably when it comes to working with other people's code. During the implementation phase you should check this with your candidate, give him some strange &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;API&lt;/span&gt;&lt;/span&gt; that he has to use, suggest your implementation to one of the methods and ask for his opinion (it might be a good thing to throw into your implementation some obvious bug).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Effectiveness, Tidiness, Laziness&lt;/strong&gt; - do not ignore the tidiness you see during the interview. Usually this is what you will get later. Pressure is not an excuse for a mess. Watch the way the code is placed, either on the paper or in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;IDE&lt;/span&gt;&lt;/span&gt;. Laziness is OK as long as it does not effect the essence. In fact laziness is something you want to find in your candidate. You want to see that he gets things done and for that he should not finish some of the assignment you gave him, but it should be the trivial part. A candidate that cannot live with an unfinished task in a way that prevents him from even doing the parts that he could have finish, is someone that does not get things done. Effectiveness means starting with the tricky stuff leaving the trivial for the end. Identifying what is tricky and what is trivial is being smart.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;How does he fit the position?&lt;/strong&gt; - this is the place, after presenting the position and the assignments he would have to handle, to ask the candidate how does he see himself in this position, what he likes and what he doesn't, what he is strong at and what he still has to learn. This is the place to see that the candidate is attached to reality. You saw him already, you got some feelings and impression about him. Does your impression fits what he says about himself?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;----------------------------------&lt;br /&gt;Addition, 12/6/2008:&lt;br /&gt;----------------------------------&lt;br /&gt;Asking for the &lt;strong&gt;candidate's grades&lt;/strong&gt;, maybe even his &lt;strong&gt;SAT score&lt;/strong&gt; (&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;Psychometric&lt;/span&gt; exam called in some countries) - can also be a smart thing, assisting you to pinpoint the smart guys. It doesn't necessarily help, this is why you are having the interview, but it may shed some more light. And in my experience, even if there isn't a complete correlation with performance, high grades do say something and poor grades also have their say. Usually, not a surprise, a guy with high grades would do better than his fellow with poor grades. But do not let the grades confuse you, I saw some &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;promising candidates with marvelous grades who may barely complete an if-else.&lt;/span&gt;&lt;br /&gt;----------------------------------&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How much time should it all take?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Including the first part of attracting the candidate (speaking about the position, the organization, and yourself) - not less than 90 minutes. 2 hours may be reasonable.&lt;/p&gt;&lt;p&gt;__________________&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Is it a true / false question?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Joel says it is. There is only Hire / No Hire, nothing in between.&lt;/p&gt;&lt;p&gt;I agree, if we have the budget and attraction to get all the &lt;a href="http://us.imdb.com/title/tt0088559/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;MacGyvers&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; that we need, then yes. I do not mean that all employees should be superheros. They should, however, be &lt;u&gt;superheros in their field&lt;/u&gt;. If we need someone to handle XML configuration files we need someone who is a master in this domain, whistles &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;XPaths&lt;/span&gt;&lt;/span&gt; in his sleep and grains &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;XMLs&lt;/span&gt;&lt;/span&gt; with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;XSLs&lt;/span&gt;&lt;/span&gt; daily. He will not find his duty boring because he will deal with making it more efficient by inventing new utilities. Same thing would be with a secretary, we will want someone who knows how to create table of content in documents and use sophisticated attributes of the spreadsheet.&lt;/p&gt;&lt;p&gt;But what if we cannot attract superheros in the domain? Suppose the budget we have for developers doesn't bring us the most brilliant ones and we have to compromise.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Building your compromises&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The candidate should have a positive marginal output. Writing bugs gives negative output, writing bugs half of the time may also. When saying positive &lt;u&gt;marginal&lt;/u&gt; output, it means that you have to take into account the effort and investment to be made in this candidate if recruited.&lt;/li&gt;&lt;li&gt;Marginal output is related to the current mix of your team. If you have "good thinkers" but lack "coders", head for those who can code fast, even if not considered design superheros.&lt;/li&gt;&lt;li&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;Remember&lt;/span&gt; that there are qualities that can be gained (e.g. experience), while some other qualities are inherent. Prefer smart over experienced and capable over well trained. A smart novice can quickly become smart and experienced.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now back to the question we begun with. Suppose we recruit a Java developer. Does the candidate need to know what is "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;earsure&lt;/span&gt;&lt;/span&gt;" for Java Generics?&lt;/p&gt;&lt;p&gt;Answer is simple: if you already have in your team someone who read the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Generices&lt;/span&gt;&lt;/span&gt; literature and can serve as the team knowledge base, it's not the end of the world if the candidate does not know it. The team will have the knowledge. BUT - if you are now seeking for this "curious developer", make sure he &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_16"&gt;proves&lt;/span&gt; his curiosity!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Hiring decisions are of the most important decisions made by managers. The damage that can be made by an unfit employee are huge. Investing time in an organized recruitment process and in each of the relevant candidates is a must. At the end, the employee selected must have a positive marginal output that justifies his salary. Marginal output is related to the current mix of your team, so recruitment decisions should be made with the set of people that you have in mind, and with understanding of the qualities that you miss in your team and want to focus on.&lt;/p&gt;&lt;p&gt;----------------------------------&lt;br /&gt;Addition, 12/6/2008:&lt;br /&gt;---------------------------------- &lt;/p&gt;&lt;p&gt;Is Smart and Gets things done the all thing? What about motivated, doesn't get bored too quickly, having a good temper?&lt;br /&gt;You may want to read &lt;a href="http://discuss.fogcreek.com/joelonsoftware2/default.asp?cmd=show&amp;amp;ixPost=71361&amp;amp;ixReplies=24"&gt;these comments on Joel&lt;/a&gt; as well.&lt;/p&gt;&lt;p&gt;---------------------------------- &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-4444697721173281101?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/4444697721173281101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=4444697721173281101' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4444697721173281101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/4444697721173281101'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/05/what-would-you-like-to-know-about-your.html' title='What would you like to know about your candidate?&lt;h3&gt;&amp;nbsp;(Or - how can you know that he is Smart and Gets things done?)&lt;/h3&gt;'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7061498094705606309.post-344973769711730422</id><published>2008-05-26T09:34:00.000-07:00</published><updated>2008-11-29T15:40:18.779-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Java Generics, Erasure, Reification</title><content type='html'>&lt;span style="font-family:arial;"&gt;I gave today a talk in &lt;a href="http://il.sun.com/sunnews/events/2008/javaday/index.jsp"&gt;Sun's Java Day 2008, Israel&lt;/a&gt;, on Java Generics, Erasure, Subtyping, Super Type, Wildcards and a few words on Reification.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Though it's a bit of an old, Java 5, topic, and though the use of Generics is straight forward, the deeper understanding of why one gets type unsafe warnings, how to generify your own utility classes etc. - this needs some more attention. So I still find it relevant to talk about and it seems that it was relevant for most of the audience (I hope! ... well, in fact this is the feedback I got after the talk).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;The presentation itself is available in pdf format &lt;a href="http://softwareanimalsfiles.googlegroups.com/web/JavaDay2008_Generics_.pdf?gda=qkFwV0oAAABQUzsd_AgDp1j442-gbbmtExbt5QE-cFnM9oJlpvRNLWG1qiJ7UbTIup-M2XPURDQEGOXRwf6TjvhdJRjQH-zqtf0YOmj7N6S1EYa_hanTZA"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I want just to post here a small piece of code from the presentation. The main point of this code is how you can cast an object to T when T was actually erased and you don't have it in run-time.&lt;br /&gt;The important lines are emphasized.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;&lt;b&gt;public &amp;lt;T&amp;gt; T getContent(Column&amp;lt;T&amp;gt; column) {&lt;/b&gt;&lt;br /&gt;&lt;b&gt;  Object colContent;&lt;/b&gt;&lt;br /&gt;  String colName = column.getName();&lt;br /&gt;  if(colName != null) {&lt;br /&gt;    colContent = getContent(colName);&lt;br /&gt;  }&lt;br /&gt;  else {&lt;br /&gt;    Integer index = column.getIndex();&lt;br /&gt;    // TODO: if null throw something of your own&lt;br /&gt;    // (for now it will be NullPointerException)&lt;br /&gt;    colContent = getContent(index);&lt;br /&gt;  }&lt;br /&gt;  if(colContent == null) {&lt;br /&gt;    return null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // now we need to cast the returned type and that's not trivial&lt;br /&gt;&lt;br /&gt;  // need raw type as a bypass&lt;br /&gt;  // usually use Class&amp;lt;?&amp;gt; when the type of the Class is unknown&lt;br /&gt;  // but it won't work here!&lt;br /&gt;  @SuppressWarnings("unchecked")&lt;br /&gt;  &lt;b&gt;Class colClass = colContent.getClass();&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;  // we know that we hold the correct type&lt;br /&gt;  @SuppressWarnings("unchecked")&lt;br /&gt;  &lt;b&gt;Class&amp;lt;T&amp;gt; colClassT = colClass;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;  // now we can use the cast method of Class&amp;lt;T&amp;gt;&lt;br /&gt;  // If we were wrong regarding the type ClassCastException&lt;br /&gt;  // will be thrown (we can wrap with catch and replace with&lt;br /&gt;  // some application exception if necessary)&lt;br /&gt;  &lt;b&gt;return colClassT.cast(colContent);&lt;/b&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;--------------------------------------&lt;br /&gt;&lt;b&gt;Addition, 27/05/2008:&lt;/b&gt;&lt;br /&gt;--------------------------------------&lt;br /&gt;A day after posting this, I got a very innocent question on the code: why not just use simple casting to T: &lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;b&gt;return (T)colContent;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Well, I remembered that it's &lt;b&gt;&lt;i&gt;Not OK&lt;/i&gt;&lt;/b&gt;. But checking it again I recalled that &lt;b&gt;&lt;i&gt;Not OK&lt;/i&gt;&lt;/b&gt; means here that you get &lt;i&gt;'Type Safety: Unchecked Cast' &lt;/i&gt;warning, yet it does compile. What the compiler tells you is that it cannot check that the casting is fine at compile time, which is OK with us.&lt;br /&gt;(Isn't it always the case that the compiler cannot check down casting at compile time? raises the question why Java decided to give a warning on this...).&lt;br /&gt;So, a simpler version of the code would be of course:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;  // ...&lt;br /&gt;  // now we need to cast the returned type&lt;br /&gt;  // we prefer to use a local var so we can put&lt;br /&gt;  // the SuppressWarning here and not on the method&lt;br /&gt;  // (you cannot put it on a return statement)&lt;br /&gt;  @SuppressWarnings("unchecked")&lt;br /&gt;  &lt;b&gt;T retval = (T)colContent;&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;return retval;&lt;/b&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;Now, one can just ask: so what's all this thing with the Class&amp;lt;T&amp;gt;.cast() method if we can directly use the "plain old" casting way of (T).&lt;br /&gt;Well, in cases where Class&amp;lt;T&amp;gt;.cast() saves the 'type safety' warning, it worth using it. In our example above we get the warning anyhow (for the implementation using Class&amp;lt;T&amp;gt;.cast() we even get two), so in such a case it would be a better choice to go back to the "plain old" casting way of (T).&lt;br /&gt;For an example where Class&amp;lt;T&amp;gt;.cast() indeed omits the 'type safety' warning, see item 29 in "Effective Java", details below.&lt;br /&gt;Of course, if you do need the Class&amp;lt;T&amp;gt; instance itself, e.g. for reflection purposes, the original way presented above would be relevant.&lt;br /&gt;&lt;br /&gt;------------------------------------------------------&lt;br /&gt;&lt;b&gt;End of Addition, 27/05/2008.&lt;/b&gt;&lt;br /&gt;------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;The idea behind the code is based on &lt;a href="http://java.sun.com/developer/Books/effectivejava/"&gt;Josh Bloch's "Effective Java" 2nd Edition&lt;/a&gt;, item 29.&lt;br /&gt;&lt;img src="http://java.sun.com/developer/Books/effectivejava/effectivejava.gif" /&gt;&lt;br /&gt;&lt;br /&gt;(The code example is not in the book, it's my example based on item 29. So in case of any error please find me responsible...)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-344973769711730422?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/344973769711730422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=344973769711730422' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/344973769711730422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/344973769711730422'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/05/java-generics-erasure-reification.html' title='Java Generics, Erasure, Reification'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-7233502369153499447</id><published>2008-04-09T13:04:00.000-07:00</published><updated>2008-11-29T15:40:03.589-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Write your source as if it was open</title><content type='html'>&lt;span style="font-family:arial;"&gt;Sometimes you get to read some piece of code and you say "mmm, that's a good piece of code". Well, it doesn't necessarily occur too much, but I hope for you that it does happen, at least occasionally when reading your own code. &lt;/span&gt;&lt;span style="font-family:Arial;"&gt;But in many&lt;/span&gt;&lt;span style="font-family:arial;"&gt; cases you come to code that makes you shout "who the hell wrote this stuff", and you may recall that it was you as well.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000066;"&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;So, what makes a good code?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Is it comments?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;span style="font-family:arial;"&gt;Well, comments are important and we will surely dedicate a post to it sometime. But one can think of good code without&lt;/span&gt; too many comments. I&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;n fact in some cases comments are what makes bad code looks even worse.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Coding guidelines are surely important&lt;/strong&gt;&lt;br /&gt;Do you really think so? Making your code readable is a must, but as long as you are not doing crazy stuff you can keep your code readable without too much guidelines. Not saying that guidelines are &lt;/span&gt;&lt;span style="font-family:arial;"&gt;bad, but this is not what makes good code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Should it be simple? Should it be sophisticated?&lt;br /&gt;&lt;/strong&gt;This is in fact a target you cannot really set. The level of simplicity or complexity is an outcome of the problem you are solving. You should not try to get a simple solution for a complex problem, and you should not be too happy with a beautiful monstrosity built for a simple problem having in mind all the other problems that this pretty hide&lt;/span&gt;&lt;span style="font-family:arial;"&gt;ous thing may also solve in the future. So simplicity or sophistication per-se is not the target.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color:#000066;"&gt;Lacking a straightforward answer, let's ask the opposite question...&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;&lt;span style="color:#000066;"&gt;What makes a bad code? &lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Bad code is a code that you &lt;strong&gt;cannot explain&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Bad code is a code that you &lt;strong&gt;find hard to use&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Bad code is a code that &lt;strong&gt;repeats itself&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Bad code is a code that is &lt;strong&gt;tightly coupled&lt;/strong&gt; - everything needs everything, everyone needs to know anyone else, you cannot go easily from top to bottom, there is no top and no bottom&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;color:#000066;"&gt;&lt;strong&gt;Bad code is a code that you will not feel proud to publish under your name&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;To avoid writing bad code I suggest that you will think you are writing an open source. Assume someone else, that you do not have direct communication with, is going to use your code, thus your code should have clear API and be modular enough so it can be used in pieces (i.e. one doesn't need to understand the whole thing in order to create the first "Hello World"). And you should write it so you will be proud to publish it. This is writing your code as if it was an open source.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#000066;"&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;To summarize&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Pay attention to your API&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Modularity counts&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Be proud of your code, if you are not, think why and fix it&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-7233502369153499447?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/7233502369153499447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=7233502369153499447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7233502369153499447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/7233502369153499447'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/04/write-your-source-as-if-it-was-open.html' title='Write your source as if it was open'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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-7061498094705606309.post-1306625137466450438</id><published>2008-04-09T13:01:00.000-07:00</published><updated>2009-08-15T14:26:19.983-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='Decent Code'/><title type='text'>Do you have a theory?</title><content type='html'>&lt;span style="font-family:arial;"&gt;In many cases when I sit with a novice developer who is working on fixing a bug I see him or her throwing lines of code from here to there. When I ask "why did you do that", usually when the code looks already like after a burglar paid a visit, the answer I get is &lt;span style="color:#000066;"&gt;"it wasn't working, so I'm trying to fix it."&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Would you like someone to fix your car that way?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Debugging is considered sometimes a non-sceintific trial and error process - you try this and that, eventually the bug will be exhausted and you will break it. Well, it is not. This would only make you to mess your code and put new bugs in, break the original structure and leave the code in a strange, shaky position, usually explained later as "we needed to do that because there was a misterious bug in the original, proper code."&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Just as when fixing your car, the mechanic would probably not try to shove your carburetor into the fuel tank as a possible solution (well, we haven't tried this yet, who knows maybe it works), this is not the way for debugging.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Debugging should be methodical.&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Have a theory before you act&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Try to prove your theory on a simple code&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Divide and conquer - try to eliminate the bug by putting code in comments till the bug is gone, then analyze what is wrong in the lines commented out. But don't just throw these lines away, even if they look redundant at first sight, and don't move them around without understanding the problem&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Analyze the problem and what causes the bug before you start changing your code, u&lt;/span&gt;&lt;span style="font-family:arial;"&gt;se logs to analyze the problem in complex scenarios&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;If you are changing the code as part of a theory ("I think we might have to call the super class at the beginning of the function and not at the end...") - remember what you have changed, if your theory fails (the bug persists and the change does not have a value of its own, it was just a whim of the moment) - return to the original code before you go on&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;If your theory prove itself right, still make sure that you fully understand it (moving the call to the super class to the beginning of the function fixed the problem - now let's understand why it should be this way... does it always have to be this way? do we need to check other similar places?)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;"&gt;And never try to shove your carburetor into the fuel tank, even if it makes the car go (maybe the problem was that the carburetor was too dry) - not understanding what you have done is NOT a fix!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7061498094705606309-1306625137466450438?l=softwareanimals.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://softwareanimals.blogspot.com/feeds/1306625137466450438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7061498094705606309&amp;postID=1306625137466450438' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1306625137466450438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7061498094705606309/posts/default/1306625137466450438'/><link rel='alternate' type='text/html' href='http://softwareanimals.blogspot.com/2008/04/do-you-have-theory.html' title='Do you have a theory?'/><author><name>Amir Kirsh</name><uri>http://www.blogger.com/profile/13012043354376031676</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></feed>
