Tuesday, October 15, 2013

NFC vs Acoustics, Mobile Payments and HopOn



NFC (Near Field Communication) is an industry standard for communication between mobile devices as well as between mobile device and peripheral hardware, for tasks as mobile payments or controlling mobile functionality by area, or by proximity to some other device (see Samsung TecTile sticker for a cool use case by Samsung).
Note that NFC and Bluetooth are not the same technology (see the difference between the two here).

While it seems as a promising standard, adopted by most new mobile devices, iPhone still doesn't. Which makes it a bit difficult if you want to implement a generic application with communication between devices, or between device and hardware, and the device might be iPhone. Applications in that domain might be games (e.g. a bingo game that invites all devices in the room to participate, without a need to "register" or "know" the arranging server domain), broadcast communication in a closed environment (bus, train, airplane) and of course mobile payment.

As an alternative to NFC, some companies have proposed the interesting idea of using un-hearable, ultrasound, sound waves communication, companies like Brazilian startup NearBytes, Microsoft and others more. Idea is to use modern mobile device abilities to receive and to play inaudible signal (>18kHz), supported for example by iOS and Android.
(Read more about NearBytes here).

I came to this recently while following Israeli startup HopOn, presenting a working system for transportation mobile payment based on acoustic signal broadcasted by a small hardware device on the bus. Their technology seems promising and is already working in some bus lines in Tel-Aviv. See their marketing piece here, it's in Hebrew but you don't really need to understand Hebrew to follow it.



Monday, September 30, 2013

A practical UI note on the order of input elements in a form

Input elements in a form are usually arranged in their natural ordered, that is: an item that seems to come naturally first would come before another one which seems more naturally to be second. This is of course subjective, but most people would agree that First Name should come first.

Recently I got a feedback on a form, sent by a heavy-user using the specific form many times a day. His request was simple, yet I've never thought about that before. He was asking if we could be kind and helpful to reorder some of the input input elements in the form, so items that require the keyboard would be in one group while items that need only the mouse, such as check boxes and radio buttons, would be separately grouped on their own. This would allow him easier and quicker fill of the form, he said.

(One can argue that the easiest and quickest way to fill a form is by using only the keyboard. But it appears that this user, as probably many others, is good with the TAB key to move between elements, but he is not aware or not keen of using the arrow keys for navigating between radio buttons and space bar for checking or unchecking a check box).

In order not to break the natural order of things (keeping first name first, and gender male/female reasonably up in the form) the grouping should be done in areas of the form, which comes to my new practical note to be phrased as:

Try to avoid too many switches of keyboard input elements to mouse input elements, if those can be naturally ordered into reasonable sub-groups to avoid the switch. This would allow a more rapid fill of the form.

Wednesday, August 28, 2013

Frenemies and All@1MC - I'm proud of you!

Two groups I was guiding in Software Product workshop at the Academic College of Tel-Aviv-Yaffo won places #1 ("Frenemies") and #4 (All@1MC) out of 70 projects (all in very high level).

Frenemies, created by Oron Perahia, Chen Saranga, Anat Oren and Shachar Witkovsky, is a fully fledged Laser Tag system, including all the goodies a company that wants to run a Laser Tag arena would need, from the web site for registering to a game (buying a game) to the management of the site and the fighting scene itself, hardware and software.
Won #1.



All@1MC, created by Yael Hof, is a Client-Agent Media Center application for your Android mobile phone to serve as a very smart remote control for the PC which serves as your media center. The application allows your mobile to view the list of movies and pictures you have on your PC, start playing them on your TV via selection on your mobile, sending instructions to the media center PC via the home WiFi network, with an agent running on the media center PC. You can also get more details on the mobile before or while watching the movie, download content from the web (again, the mobile serves as a smart remote control, all operations are done on the mobile device, the actual download is happening on the media center PC) and watching a slideshow of your pictures on the TV, controlling the slideshow from the mobile.
Won #4.




Tuesday, July 3, 2012

Back to Basics - Bitwise Flags


Recently I was using a question about managing a parking garage in an Object Oriented course I'm teaching and in job interviews for a position I was recruiting.

The question asks to manage a parking garage where each customer can submit requirements when getting in, for specific parking place attributes (such as "shaded", "not blocked", "tall vehicle" etc.) and for consuming services while parking (such as "car wash", "electric charging" etc.)

The garage has of course parking places which support these requirements or some of them and able to provide the required services in some of the parking places.

The question was to model and implement the management system for the garage, so customer requirements can be answered by pointing the car to the relevant free place or replying the customer that no free place satisfies the requirements.

Has one can understand from the title of this post, it is more than reasonable to think of bitwise flags here. However, the Object Oriented thinking might work here extra hours and lead to unnecessary classes, or even worse, horrible class hierarchies.

The beauty of bitwise flags is that matching can be done based on simple bitwise operations.

What do require some Object Oriented thinking is managing the price tariffs for the garage!

Thursday, August 18, 2011

Big Map, String, GC, Memory Consumption and Performance

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.

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.

When coming to very big HashMap, there are a few considerations to take into account:


  1. 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 (capacity * load factor). Higher values of load factor means less rehash operations, but a map that is more dense. Calls to get 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 get 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.

    To summarize: don't start with optimizing the load factor, it's a bad start.

  2. 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.
    The recommended initial capacity, for load factor of 0.75, is: 1.5 * numElements
    (Read more: http://stackoverflow.com/questions/434989/hashmap-intialization-parameters-load-initialcapacity).

    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.

    To summarize: initial capacity is important. Set it!

  3. Beware of memory leaks!
    Maps, as any long-leaving memory storage entity, are a potential source for leaks.
    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.
    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 substring 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: http://eyalsch.wordpress.com/2009/10/27/stringleaks/).
    Solution is to manually create a new String and give it the substring portion you want to keep:
    String key = new String(bigLine.substring(from, to));
    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.

    To summarize: beware of holding a substring in a Map! Do it the right way.

  4. 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.

    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.

    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.

    To summarize: caching Strings in big Maps is costly. Think how to reduce the size of your key and value!

  5. 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: http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier

    To summarize: 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.

  6. 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...).
    Calculate the most minimal amount of memory you need, save your time and don't try to optimize your application into less.

    To summarize: set goals to your optimization efforts. Make sure the goals are not too aggressive, i.e. are feasible without re-writing the entire thing.

  7. 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.

    To summarize: size of the old generation section is crucial to prevent unnecessary full GC cycles. Configure the max heap size and/or the generation ratios.

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.


Friday, April 22, 2011

Decent Code

Retrospecting the posts labled Decent Code I see many good points worth memorizing.



Do you have an API? - the basic question before coding!

Do you have a theory? - the basic question before debugging!


Be proud of your code! - a simple advice, yet powerful, for code reviews

The risks of redundant code (or - Less is More) - another powerful advice for code reviews

Use Explaining Variables! - and another one for code reviews (I should consider a label for code reviews probably)


Resource Files - this is obvious for anybody today, yet ignored too often...

Freaking behavior of a small little C/C++ bug - avoid the non-void not returning a value!

Semi-colon and java.lang.OutOfMemoryError - the methodic way of analyzing OOM in Java programs


and many more...


like for example...

Make sure to have a strict XSD!

or To AJAX or NOT to AJAX? - important to many web developers today which neglect the request-response model for AJAX idol, in many cases for no good reason.


and still, many more...

Thursday, March 31, 2011

The success of iPhone

Three years back, I explained why Nokia is not supporting external applications.


Well, since then Apple has AppStore and Nokia has followed with OVI. And Samsung has its Internet@TV portal.


It appears that focusing on the appliance itself is not enough nowadays.

Thursday, January 20, 2011

Thoughts following 2010 FogBugz and Kiln World Tour





I was attending yesterday Joel Spolsky world tour for FogBugz and Kiln.


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!?


A few thoughts following the event:



  1. 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.


  2. 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.


  3. 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:
    (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.
    (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.
    (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.

Thursday, January 13, 2011

Online IDE for almost any SW lang you can think of

Take a look at this one: http://ideone.com/


It supports:
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


It's very useful when you want to check little programs, like the ones I tried when writing Freaking behavior of a small little C/C++ bug:

[1]


[2]

Freaking behavior of a small little C/C++ bug

Oh boy.
Read till the end the event and its root cause. Important morals follow below.





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.

Shockingly, on January 2nd we had a crash in two sites.

Analyzing the crash led to a timer that instead of re-scheduling itself for every 5 seconds, keeps snapping abruptly in periods of milliseconds.

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.

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.)

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.

http://www.tipb.com/2010/12/31/iphone-bugs-alarms-working-2011/


Maybe it's the same bug?

iPhone runs on iOS which is Linux based. We also run on Linux. Maybe there is something with Linux timers on beginning of 2011?
Looking for something in this direction led to nothing.

On the other hand, analytical investigation led to the following:

  1. 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.
  2. Our callback function didn't return a value at all
Wait... - is it legal not to return a value from a non-void method?
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.
See:
http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pro/1610454#1610454
http://stackoverflow.com/questions/2598084/function-with-missing-return-value-behavior-at-runtime
What shall be done?
Read:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-Wreturn-type
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.

Morals
  • Listen to compiler warnings!
    Solve all warnings, you should have a zero warnings policy.
    The problem above could be caught and solved as a warning (-Wreturn-type).
  • 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
  • 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!

Thursday, November 25, 2010

A simple generic template function

A simple generic template function for getting the minimum and maximum from STL container and simple arrays.

Nothing too complicated, I just liked this example.

1:  template<class Iterator>
2: pair<Iterator, Iterator> minMaxFinder(Iterator begin, Iterator end)
3: {
4: Iterator min = begin;
5: Iterator max = begin;
6: for(++begin ; begin != end; ++begin) {
7: if(*begin > *max) {
8: max = begin;
9: }
10: else if(*begin < *min) {
11: min = begin;
12: }
13: }
14: return pair<Iterator, Iterator>(min, max);
15: }
16: int main()
17: {
18: int iArr[] = {15, 5, 70, 2};
19: pair<int*, int*> minmax = minMaxFinder(&iArr[0], &iArr[4]);
20: cout << *minmax.first << ", " << *minmax.second << endl;
21: list<string> sList;
22: sList.insert(sList.end(), "small");
23: sList.insert(sList.end(), "smallish");
24: sList.insert(sList.end(), "big");
25: sList.insert(sList.end(), "biggish");
26: pair<list<string>::iterator, list<string>::iterator>
27: minmaxS = minMaxFinder(sList.begin(), sList.end());
28: cout << *minmaxS.first << ", " << *maxminS.second << endl;
29: return 0;
30: }


Code formatted with http://codeformatter.blogspot.com

Monday, November 22, 2010

Thoughts on Open Source licenses, Patents on Software and such

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.

Few insights and thoughts from my experience:

  • 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.
  • 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.
  • 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.
  • 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.
  • 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?

Monday, September 20, 2010

Resource Files

Programs interact with a user in many ways.
They write things to a screen, send messages over the network, say things aloud. And more.

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.

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?

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.

Things to do on the first day when starting a new project (don't postpone it to "later"):
1. Use good logging mechanism (exiting one, don't invent the wheel)
2. Use automatic build mechanism
3. Use a resource file
( -- do you have more - please add as a comment!)

Well, wait I have one more - have a defined API (slash protocol slash wireframes) for the modules you are developing.

Thursday, August 19, 2010

Semi-colon and java.lang.OutOfMemoryError

; ; ; ; ; ; ; ; ; ; ; ; ; ;

I want to share with you a crash at customer site caused by java.lang.OutOfMemoryError.

Here is the original code:

if (synchRemove(lobj.getSeqNum()) != null);
____timeoutedList.add(lobj);

Can you see the problem?

(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).


Moral:

  1. Small semicolon can cause big troubles
  2. It's hard to see everything in code review. A trouble-making redundant semicolon can skip the eyes of the reviewer
  3. Load test may find such cases (but may still miss them, if the relevant scenario was not created)
  4. Good unit tests may also help
  5. 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)
  6. Static code analysis tools, like FindBugs – which is free, do point at such errors!
  7. In some IDEs (e.g. Eclipse) you can configure the IDE to present warnings on such cases

in the above case, analyzing the heap dump, using MAT, led to the problematic giant list, then tracking all insertions into the list in the code, led to the faulty line.


Thursday, June 3, 2010

... and the UI is also going back

Following my last post on concurrent processes, my good friend Effie Nadiv noted that the UI is also getting backwards.


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.

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.

Process Concurrency - are we stepping ahead or backward?

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.

Why process concurrency is a BAD THING

  • You are showing a presentation and suddenly some pop-up from another process pops
  • 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
  • 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.
  • 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.

How often do you click Ctrl+ALT+Del?

I find myself at least once a day using the Ctrl+ALT+Del to check what's holding my machine. How about you?

So, how was it back then, in the good old times?

In DOS, you could have only one process running. If you wanted to jump to another without closing your application you could use TSR 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.

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 are not yours. You are lucky if the machine throws a bone at you giving you some resources.

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.

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.

Monday, May 31, 2010

Java Unit Testing

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.

1. TestNG vs. JUnit4

TestNG came out to add features that were missing in JUnit 3.x.
It did quite a good job and some may say that TestNG 5.10+ is still better than JUnit 4.7+
TestNG has better data providing mechanism.
TestNG has test dependency definition, missing in JUnit.
TestNG has group level with fixtures on group. And it also has the ability to create automatic run file for all failed tests.
All that said, JUnit has more extending libraries using its ability to extend JUnit TestCase and JUnit TestRunner.
Both have very good IDE support, as well as Ant and Maven support.

Coming to choose, both are good. I stick with JUnit.

Note that JUnit 4 made the mistake of integrating another library into its jar, that is the hamcrest core. They should have known better than that... The problem is that when you get the full hamcrest lib (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.


2. Load

JUnitPerf do the job with its ability to run tests in several threads.
It's easy and useful, for integration stage and for any piece of code that may act differently under load.

The following code was tested with JUnitPerf and it catches the bug of not synchronizing the addIfAbsent:

public class MyList extends ArrayList
// we test with the synchronized and without
public synchronized boolean addIfAbsent(Object o)
boolean absent = !super.contains(o);if(absent) {
super.add(o);
}
return absent;
}
}


The test that catches the bug when the synchronized is deleted:

public class MyListTest extends TestCase {
private MyList myList = new MyList();
private int count = 0;
MyListTest(String name) {
super(name);
}

TestSuite suite = new TestSuite();
Test testToRun = new MyListTest("testMyList");
int numUsers = 1000;
int iterations = 5;
suite.addTest(new LoadTest(testToRun, numUsers, iterations));
return suite;
}
public void testMyList() {
if(myList.addIfAbsent(count)) {
// there is a gap here that may cause error on correct
// implementation, in case of thread switch at this point
synchronized (this) {
++count;
assertEquals(myList.size(), count);
}
}
}
}


This solution is not bullet proof.
Theoretically it may give errors on correct scenario, and of course it can always miss bad implementation, as it’s a matter of timing.
However, in reality it does catch the problem!
JUnitPerf is simple and gets the job done.


3. Thread testing

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.

With such ability we could have create the race condition in the above code with a deterministic approach instead of using load.

Suggested tools:

  • thread-weaver (version 0.1)
    allows the test to time different threads reach code points in a certain order, either explicitly or “semi-automatically”
  • MultiThreadedTC (version 1.01)
    allows to set time tickers on objects in the test itself, but NOT on the tested code, thus less relevant for most testing purposes

Both tools are not highly supported, recommending still not to rush into it…


4. Mock Objects

There are 3 cases where you need a Mock Object in your test:

(a) Tested code gets a complicated object as parameter
Solution: Mock the parameter with a Stub/Mock implementation

(b) Tested code invokes a static call on some resource
Solution: Replace the static call with a Stub/Mock implementation

(c) Tested code creates complicated objects
Solution: Replace the created objects with a Stub/Mock implementation

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).

Possible tools: Mockito, JMock, JMockit, EasyMock, JEasyTest and many others…

There are differences between the tools in syntax and abilities.
Tools that rely on Proxy cannot mock static behavior and object creation.

The two possibile combinations that came to my final round were:
(a) JMockit 0.998
(b) EasyMock 3.0 + PowerMock .1.3.8

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...

My selection here would be EasyMock + PowerMock


5. Other tools

Other tools in this domain worth mentioning:
- DBUnit
- HttpUnit (not only for tests)
- Selenium (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)

Wednesday, April 14, 2010

Beware of your long tail garbage

IBM’s PLDE seminar 2010 (IBM Programming Languages and Development Environments Seminar 2010)

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.
XALAN seem to sin with the above.

Gilad Bracha opened with a overview of mistakes done by Java 1.0 which are living in Java till these days.

Gili Nachum writes on the above two in his JavaTuning blog:
http://www.javatuning.com/ibms-plde-seminar-2010-review/

Wednesday, March 10, 2010

Cisco new router deliverring 322 Tbit/s

Cisco announced a new core router, named CSR-3, delivering 322 Tbit/s:
http://www.lightreading.com/document.asp?doc_id=188914&

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.

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).

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 (Hong Kong, Hague, more Europe, and it happens that Kansas city even changed its name to get fiber).

With 322 Tbits/s it sounds that someone needs to really start working on teleporting.

Tuesday, February 16, 2010

Multiple Inheritance - should you?

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.

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.

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.

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.