Thursday, December 27, 2012

A JavaScript Quiz and a JavaScript Quiz Engine

Here is a very simple JavaScript quiz for you to try and have some fun with!
For this quiz, I wrote a very simple quiz engine using JavaScript and some JQuery APIs. To create a quiz all you need to do is create a JSON object which contains Question / Answer info and pass it to a single API. The engine will:
  • determine if a question has a single answer or multiple answer and show radio buttons or check boxes accordingly.
  • display user progress
  • display results and correct / incorrect questions.
Source code is on my GitHub. I have also put the files on github pages. So if you want a quiz on your site, import the engine by simply importing the CSS and the JavaScript (ensure you also have JQuery being pulled in from somewhere).


Then create a JSON object of your questions and answers. The JSON object is an array of Question / Answer. Each element in the array consist is a map of three elements:
  • The question
  • The possible answers (the answers to present to the user) - specified as an ordered array.
  • The correct answer
For example:
var quiz_questions = {questions:[
                             {"question":"Which of the following is a risk of using Constructor function?", 
        "answers":["If it is invoked without using new keyword, the this variable is not bound to local object but to the global namespace.", "Performance risk", "There are no risks"],
        "correct_answer":"0"}, 
        ...]
The correct answer is a numeric value, which represents the position in the list of the possible answers. If there is more than one correct answer, separate the correct answers by commas. For example:
{"question":"Which of the following is true about functions?",
        "answers":["Functions can be expressed as literals", 
                   "Functions can be assigned to variables, array entries and properties of other objects",
             "Passed as arguments to other functions",
             "Returned as values from functions",
             "Can have properties created and assigned dynamically",
                                           "Can solve climate change?"],
         "correct_answer":"0,1,2,3,4"}
The engine will use check boxes for questions that have multiple answers and radio boxes for questions that have a single answer. To invoke the engine, it is just one API.
quizModule(quiz_questions, $('#intro'));
In this case $('#intro') is the dom element I want the quiz to sit below. quiz_questions is the JSON object containing the question / answer pairings.

There is no server request handling whatsoever after the quiz loads. Everything happens client side from the first question to the generation of results.

If you have any interesting JavaScript questions send them on and I'll add them to the quiz! Or use the engine and create your own quiz.

Wednesday, November 21, 2012

The Technology Radar

Acclaimed IT Consultancy company ThoughtWorks recently published its October Technology Radar.
This publication assessess software techniques, software tools, software platforms, software languages and makes recommendations regarding the various offerings.

In a world where the technologies changes are rapid and where choices can seem overwhelming it is a super publication and well worth reading. It is not everyday when industry Gurus such as Martin Fowler (Chief Scientist at thoughtworks) are going to tell you their expert opinions for free.  Some of the interesting points from the latest technology radar:
  1. The proliferation of work - in - progress limits. One method to achieve this is to use Kanban limits. "Kanban" traces back to the early days of the Toyota Production system and in English it is roughtly translated to "signboard". One aspect of the Kanban system is to limit impedemence mistmatch between inter-dependent processes by imposing work-in-process limits. So there is not point having a massive amount of development in progress at any one time and then all a sudden dumping this on a test teaam.
  2. 'Mobile first' - this is a technique which considers the mobile devices rather than last.  Some simple stats substantiate this:
  3. Regarding the build tools, Maven is going out of fashion. Interestingly because it never fully dumped XML.  I tend to agree with this.  While Maven offered some improvements over Ant in how it handled Maven, if you wanted to do anything which was not the Maven way you had to write a plugin which some people found hacky especially as project complexity grows.  Rake and Gradle offer better alternatives.
  4. The testing framework Jasmine for JavaScript gets a lot of praise.  QUnit (the one from JQuery which this blog covered recently) doesn't get any. Jasmine is more geared towards BDD whereas QUnit is more TDD.
  5. Very interestingly the performance and scalability tool Locust is suggested over JMeter. One advantage Locust has is that it is not thread bound. This means you do not need a separate thread to simulate every client.  to simulate some geographical dispersion amongst your clients  Saas Performance testing tools such as Blitz.io and Tealeaf are suggested as tools on the up.
  6. The most popular project in GitHub (over 40,000 stargazers at time of writing), Twitter Bootstrap is promoted for its powerfuls of components and features. I really like the look of Twitter Bootstrap. It is used by NASA, MSNBC and practically every start up.

Wednesday, November 14, 2012

Unit Testing your JavaScript

According to John Resig and Bear Bibeault 48% of JavaScript developement (see chapter 2, Secrets of the Java Script Ninja) do not test.  The advantages of unit testing code and developing in a test driven approach have been well documented and don't need to be rehashed - suffice to say the arguments are equally applicable to JavaScript code.  One popular approach to unit testing JavaScript is the QUnit framework. This framework was originally built to test JQuery and then evolved into a stand alone unit testing option for JavaScript in its own right. Let's consider an example. Suppose we have an architecture where the Web Tier makes AJAX REST style requests to a server and gets back information about entities in JSON format. It is probable that we will want to adapt the data that comes back into custom JavaScript objects that we can send on to various parts of the GUI. To convert the data, we use something similar to the GOF Adapter pattern. We collate methods involved in adapting different entities and then place them all in an object literal as follows:
var dublintech = dublintech || {};

// dataAdapter contains some functions to convert data.
// Idea is this can map JSON results from REST requests 
// to JavaScript formats the GUI expects.
dublintech.dataAdapter = {
    adaptStudents : function (data) {
        var adaptedStudentsVar = {
            students:[]
        };
  
        jQuery.each(data.students, function(indx, originalStudent){
            var student = {
                name: originalStudent.firstName + " " + originalStudent.lastName,
                dateOfBirth: originalStudent.dateOfBirth,
                nationality: originalStudent.nationality
            };
            adaptedStudentsVar.students.push(student);
        });
        return adaptedStudentsVar;
    },
 
    adaptHumans : function (data) {
       // ...
       // code to adapt humans
    },
 
    adaptAnimals : function(data) {
       // ...
       // code to adapt animals.
    }
};
This approach achieves a separation of concerns and is a good attempt at making things follow a stateless and functional paradigm.  
Note 1: Yes the above example is super simple. The only adaptation that is really happening is that the adpated name variable is made up from combining the first name with the last name that are in the JSON. The real world is obviously a more complicated place, but this simple adaptation example is enough to show how things hang together using QUnit.
Note 2: If you are wondering why I did not use a closure above, it is because there is no need for any state in these methods, hence there is no need to encapsulate any state. But again, in the real world you may not find it so easy to avoid state and if it comes you are better off encapsulating it using a closure.

And now the tests...

Ideally you'd like if:
  • any required testing libaries were taken from a public CDN.
  • your tests are 100% separate from your JavaScript code and have no impact your original source code.
  • your tests are easy to run and even easier to get results from.
To use the QUnit approach we simply write some JavaScript using the QUnit APIs in a HTML page. See below:
<html>
<head>
  QUnit basic example
  
  
  
  
</head>
<body>
  
<!-- test code </body> </html>

Now the salients points:
  1. The test exists in a separate file. It creates some test data, passes it to the adaptStudents method and checks that what is returned is what it should be.
  2. The JavaScript which contains the code that is being tested can be located anywhere that can be accessed by a HTTP request. So your test code does not have be located on the same machine / building as the JavaScript it is testing.
  3. The QUnit, JQuery libraries are pulled in from a CDN. 
  4. The test() API is a QUnit API which does exactly what it says  - that there is a test to execute!  There can be multiple tests() in the same file and they can be grouped using the module() API.
  5. equal() is a QUnit API which performs the actual test. QUnit has other assertion APIs (ok() and deepEqual()).
  6. It's simple to run this test. Just access this page in a web browser.
When the test is run, you get a picture like this:
Results
The results contain the following checkboxes
  • Hide passed tests - useful when you want to focus only on tests that failed
  • Check for globals - when selected QUnit will make a list of all properties on the window object, before and after each test and will check for differences. If properties are added or removed, the test will fail. 
  • No try/catch - If your test throws an exception, the testrunner will die, unable to continue running and will you will get the a  "native" exception. This can help debugging old browsers with bad debugging support like Internet Explorer 6.
The results page also contain the user agent used to run the tests (useful for screen shots), the total number of tests ran, the success summary and the overall execution time.  Each test is then detailed - including the number of failures, the numbers of success and the number of asserts in the test i.e. in this case (0, 3, 3).  You can also specify the number of assertions in a test and if they are not all invoked, the test will fail.

Anything else? 

Yes, QUnit can be used to test Asychronous code.  There are special APIs to indicate asynchronous code is being tested. QUnit can also test user interaction by leveraging JQuery trigger APIs.

What about mock objects?

There is no support for mock objects out of the box. However, there are a number of frameworks such as mockjax and sinjo.js  (in fact sinon.js has special support for QUnit).
Finally, I have put the source code detailed above on my Github.

Sunday, September 23, 2012

Is Java Dead or Invincible?


Is Java Dead?

Writer Isaac Asimov once said that "the only constant is change".  That isn't just a phrase in the software industry, it is an absolute fact.  Once, there was a day when Corba was king but it was usurped by Web Services.  Even within the world of Web Services, that used to be all about SOAP but now it's REST style services which are much more popular today.  Now somethings will obviously hang around a bit longer than others.  Relational databases have been around 40 years and aren't going to be kicked out by NoSql just yet. The HTTP protocol has been at version 1.1 since 1999 and has helped us use a thing called the Internet.  As for Java well that has been a pretty popular computer programming language for the last decade and a half.

According to Dutch research firm Tiobe in terms of overall popularity, Java ranked 5th in 1997, 1st in 2007 and 2nd in Sept 2012. At the time of writing there are over 2,000 Java progamming books on Amazon in English and there are almost 300,000 threads on Stackoverflow related to Java.   However, as George Orwell once said: "Whoever is winning at the moment will always seem to be invincible". But is Java invincible or beginning to die?  That's the question being asked more and more now.

In my humble opinion, the challenges to Java can be split into three categories:
  1. The rise of alternative languages
  2. Scalability / Multi-Core processors
  3. The return of the fat client.
Let's elaborate...

The rise of alternative languages

Alternative languages can be split into two groups: those that run on the JVM (Scala, Groovy etc)
and those that don't (Python, Ruby).  One interesting thing is that the first group is pretty large.  The languages that run on the JVM aren't mutual exclusive to Java and in a sense strengthen it reminding us what a remarkable piese of software engineering the JVM is.  Development teams can get that
extra bit of expressiveness in a niche language like Groovy, but can still call out to Java when they need some cool Java library or just need that extra bit of performance.  Remember the advantages in Groovy 2.0 speed it up but it is still not as fast as Java.

As for the features some of these languages provide that are not in Java, well that is the case but it won't always be the case.  Take a look at the roadmap for Java 8 and the features it will include. Just like Java EE 5 and 6 took ideas from Spring / Seam,  the Java lanuage in its 8th major release will be taking ideas from other languages. For example literal functions will be facilitated by Lambdas.  Java 8 Lamdas will have support for type inference and because they are just literals it will be possible to pass them around (and return them) just like a String literal or any anonymous Object.

That means instead of having to write an implementation of Comparator to pass to the Collections sort utility to sort a list of Strings, in Java 8 we will just do:
Collections.sort(list, (s1, s2) -> s1.length() - s2.length());

So, the alternative JVM languages don't exactly kick Java out of the party. It is still there, but in a party that has a better selection of music played and in a party where the guests encourages their host to be a better host.

Scaling on the multi-core platforms

As for multi-core and JVM - we all know that with a JVM running on a single core it was possible to spawn threads in the very first release of Java.  But these threads weren't executing in parallel, the CPU switched between them very quickly to create the impression that they were running in parallel. JStack may tell you that 50 threads have state "runnable" on your single core machine but this just means they are either running or eligible to run.  With multi-core CPUs it is possible to get true parallelism.  The JVM decides when to execute threads in parallel.

So what's the deal here?  Firstly, even though concurrency and threads were a feature of Java from the very beginning the language support was limited meaning development teams were writing a lot of their own thread management code - which could get ugly very quickly. This was alleviated greatly in JDK 1.5 with the arrival of a range of thread management features in the java.util.concurrent package.  Secondly, to get better parallelism something else was needed.  This came in Java 7 with Doug Lea's Fork / Join framework which uses clever techniques such as work stealing and double sided queues to increase parallelism. However, even with this Framework decomposing (and re-arranging) data is still a task that is needed to be done by the programmer.

Functional progamming gives us another option to perform computations on data sets in parallel.  
In Scala, for example, you just pass the function you wish to operate on the data and tell scala you want the computation to be parallelised.
outputAnswer((1 to 5).par.foreach(i => longComputation))

And guess what? The same will be available in Java 8.
Array.asList(1,2,3,4,5).parallel().foreach(int i ->heavyComputation())
Since scalability and performance are architectural cousins, it is worth stating that in many experiements Java still out performns other languages.  The excellent Computer Language Benchmark Game shows Java outperformaning many languages. It hammers the likes Perl, PHP, Python3, Erlang in many tests, beats Clojure, C# in nearly all tests and is only just behind C++ in terms in the performance results. Now,  performance tests can't cover everything and a context will always have some bias which favours one language over another but going by these tests it is not as if Java is a slow coach.

The fat client is back!

The return of the fat client

Since the advent of AJAX, Doug Crockford telling people how to use JavaScript and the rise of an excellent selection of JavaScript libraries the fat client is truely back.  Close your eyes and imagine what a cool single page web application such as gmail would look and feel like if it was just thin client web framework based on Spring MVC, JSF or Struts - you just cannot beat the performance of a well designed fat client.

One saving grace is that JavaScript is a lot more difficult to be good than some people think. It takes a lot more thinking to really understand  Closures, Modules and the various JavaScript best practises than it does to know your way around a web framework like Spring MVC and Struts. In addition, building a single page web application (again such as gmail) doesn't just require excellent JavaScript understanding it requires understanding of how the web works. For example, browsers don't put Ajax requests in the browser history.  So you gotta do something smart with fragment identifiers if you want the back and forward buttons to be usable and meaningful for the User.

There is a probably some room here for a hybrid approach which uses both a web framework and JavaScript and of course some JavaScript libraries.   This gives developers a structure to build an application and then the opportunity to use JavaScript, JQuery or whatever cool library takes there fancy for important parts of the Application that need to be jazzed up.   In a true fat web client approach, there should be no HTML served from the server (that means no JSPs), the only thing coming back from the server is data (in the form of JSON). However,  using a hybrid approach you can make a transition from thin to fat easier  and you can still put your JavaScript libraries on a CDN, you just won't get all the advantages of a full fat web client approach.

Summary

In summary, Java has had some bad moments. AWT was a rush job, Swing had performance problems, the early iterations of  EJB were cumbersome and JSF was problematic in comparison to other frameworks such as Struts and Spring MVC.  But, even today, extremely innovative projects such as Hadoop are built using Java.  It still has massive support from the open source community. This support has not only helped Java but also show Java some its problems and things it needs to get better at.   Java has shown it has the ability to evolve further and while other languages challenge it I don't think the game is over just yet.  It goes without saying, a lot will of the future of Java will depend on Oracle but let's hope whatever happens that the winner will be technology.

References

  1. Yammer and their migration to scala
  2. James Gosling taking about the state and future of Java at Google tech talk
  3. Article from Oracle describingFork and Join in Java 7
  4. Eric Bruno:Building Java Multi-Core applications
  5. Edgardo Hernandez:Parallel processing in Java
  6. IEEE top ten programming languages
  7. JDK 8 downloads
  8. Java Code Geeks article on Fork Join
  9. Good Fork Join article by Edward Harned
  10. Fork / Join paper from Doug Lea
  11. Fork / Join Java updates information from Doug Lea
  12. Scala Java Myths - great article by Urs Peter and Sander van der Berg