Tuesday, June 12, 2012

Top 7 Programmers bad habits

1. The All code is crap, except mine, attitude.

I have bad news for you buddy, all code is crap. No matter how much effort you put on it, there is always a majority of programmers who are going to think that your code sucks and that they could have done it 10 times better. I have already covered this topic in previous posts, you can find more information of what exactly I mean when I say that all the code is crap here and here.

How to fix it : Don’t criticise others people code, it could be yours the one in the spotlight, try to make objective and professional observations instead, but don’t judge. Be humble and try to learn from everyone around you, hopefully then your code won’t be so bad.

2. The “I fix that in a second” catastrophe.

Taking shortcuts is very tempting, everyone has done it. There are actually situations where they are necessary, but in overall, they are dangerous, very dangerous and should be avoided. A shortcut which goes wrong may save you a few hours, but may cause months of pain.

How to fix it : Don’t trust yourself when carrying delicate activities. Ask someone else to review what you are doing. Make sure that if you are about to take a shortcut, you make very clear to the stakeholders what the reasons and the risks are. Try to get a manager to sign off every time you are about to take a shortcut.

3. The “That will only take a second” misconception.

Being Barcelona my favourite city, I am very proud of the Sagrada Familia Cathedral, which is very well know for its beautiness, and also for the time is estimated it will take to complete, (in construction since 1882), but that’s probably because they didn’t ask a programmer to estimate, otherwise the estimate would probably have been somewhere around 2 weeks.

How to fix it : For starters, is important to understand that accurate estimations in software development for non trivial solutions are impossible, we can only guess. Also remember that is very likely that you will find so many things which you didn’t foresee when you start developing that is worth multiplying the estimate to cover for those, I usually go with 1.5 or 2.

4. The ego spiral

Many programmers discussions look more like rooster fights than human discussions. This usually happens in design and architectural meetings. It is actually quite easy to detect this ego spirals, you just have to substitute most of what the contenders are saying with COC! COC! COCOCOOCCC! COOC!

How to fix it: Leave your ego at home. Big egos are one of the biggest non technical issues for any programmer. Keep in mind some basic considerations when making decisions.

5. “It wasn’t me!”

In my opinion, other bad habit from most programmers is the lack of accountability. We always have an excuse… It’s like if we were saying that under normal conditions we would never make a mistake, which honestly is quite hard to believe.

How to fix it: No need to cry, or to perform seppuku, (aka harakiri), when we make a mistake. Having a healthy attitude where we can you just say something like: “yeah, sorry, now we need to do this to fix this issue, my fault” is a very professional attitude, and it will help you to build a reputation and to be better considered by your colleagues.

6. The demotivated genius.

Repetitive and simple tasks are not the best motivators, but they need to be done, programmers tend to get demotivated and very unproductive when they need to complete them.

How to fix it: Discipline. Unfortunately, there isn’t any other remedy I can think of.

7. The premature programmer.

If programming was sex, there would be a lot of unsatisfied computers. You can just not go in, do things halfway through and then fall sleep. One of the concepts that I find most programmers struggling with is the concept of “Done”. Remember that done means: tested (and not only unit tested), documented, committed, merged…

How to fix it: This one is tricky, the complexity of non apparent necessary tasks to fully complete some functionality is quite high and usually requires discipline and training. Probably the two easiest ways to help a programmer understand if some code is done are peer reviews and demos.


Reference: Top 7 Programmers bad habits from our JCG partner Rajith Delantha at the Looping around with Rajith... blog.

Secure Password Storage - Don'ts, dos and a Java example

The importance of storing passwords securely
As software developers, one of our most important responsibilities is the protection of our users' personal information. Without technical knowledge of our applications, users have no choice but to trust that we're fulfilling this responsibility. Sadly, when it comes to passwords, the software development community has a spotty track record.
While it's impossible to build a 100% secure system, there are fortunately some simple steps we can take to make our users' passwords safe enough to send would-be hackers in search of easier prey.
If you don't want all the background, feel free to skip to the Java SE example below.
The Don'ts
First, let's quickly discuss some of the things you shouldn't do when building an application that requires authentication:
  • Don't store authentication data unless you really have to. This may seem like a cop-out, but before you start building a database of user credentials, consider letting someone else handle it. If you're building a public application, consider using OAuth providers such as Google or Facebook. If you're building an internal enterprise application, consider using any internal authentication services that may already exist, like a corporate LDAP or Kerberos service. Whether it's a public or internal application, your users will appreciate not needing to remember another user ID and password, and it's one less database out there for hackers to attack.
  • If you must store authentication data, for Gosling's sake don't store the passwords in clear text. This should be obvious, but it bears mentioning. Let's at least make the hackers break a sweat.
  • Don't use two-way encryption unless you really need to retrieve the clear-text password. You only need to know their clear-text password if you are using their credentials to interact with an external system on their behalf. Even then, you're better off having the user authenticate with that system directly. To be clear, you do not need to use the user's original clear-text password to perform authentication in your application. I'll go into more detail on this later, but when performing authentication, you will be applying an encryption algorithm to the password the user entered and comparing it to the encrypted password you've stored.
  • Don't use outdated hashing algorithms like MD5. Honestly, hashing a password with MD5 is virtually useless. Here's an MD5-hashed password: 569a70c2ccd0ac41c9d1637afe8cd932. Go to http://www.md5hacker.com/ and you can decrypt it in seconds.
  • Don't come up with your own encryption scheme. There are a handful of brilliant encryption experts in the world that are capable of outwitting hackers and devising a new encryption algorithm. I am not one of them, and most likely, neither are you. If a hacker gets access to your user database, they can probably get your code too. Unless you've invented the next great successor to PBKDF2 or bcrypt, they will be cackling maniacally as they quickly crack all your users' passwords and publish them on the darknet.
The Dos
Okay, enough lecturing on what not to do. Here are the things you need to focus on:
  • Choose a one-way encryption algorithm. As I mentioned above, once you've encrypted and stored a user's password, you never need to know the real value again. When a user attempts to authenticate, you'll just apply the same algorithm to the password they entered, and compare that to the encrypted password that you stored.
  • Make the encryption as slow as your application can tolerate. Any modern password encryption algorithm should allow you to provide parameters that increase the time needed to encrypt a password (i.e. in PBKDF2, specifying the number of iterations). Why is slow good? Your users won't notice if it takes an extra 100ms to encrypt their password, but a hacker trying a brute-force attack will notice the difference as they run the algorithm billions of times.
  • Pick a well-known algorithm. The National Institute of Standards and Technology (NIST) recommends PBKDF2 for passwords. bcrypt is a popular and established alternative, and scrypt is a relatively new algorithm that has been well-received. All these are popular for a reason: they're good.
PBKDF2
Before I give show you some concrete code, let's talk a little about why PBKDF2 is a good choice for encrypting passwords:
  • Recommended by the NIST. Section 5.3 of Special Publication 800-132 recommends PBKDF2 for encrypting passwords. Security officials will love that.
  • Adjustable key stretching to defeat brute force attacks. The basic idea of key stretching is that after you apply your hashing algorithm to the password, you then continue to apply the same algorithm to the result many times (the iteration count). If hackers are trying to crack your passwords, this greatly increases the time it takes to try the billions of possible passwords. As mentioned previously, the slower, the better. PBKDF2 lets you specify the number of iterations to apply, allowing you to make it as slow as you like.
  • A required salt to defeat rainbow table attacks and prevent collisions with other users. A salt is a randomly generated sequence of bits that is unique to each user and is added to the user's password as part of the hashing. This prevents rainbow table attacks by making a precomputed list of results unfeasible. And since each user gets their own salt, even if two users have the same password, the encrypted values will be different. There is a lot of conflicting information out there on whether the salts should be stored someplace separate from the encrypted passwords. Since the key stretching in PBKDF2 already protects us from brute-force attacks, I feel it is unnecessary to try to hide the salt. Section 3.1 of NIST SP 800-132 also defines salt as a "non-secret binary value," so that's what I go with.
  • Part of Java SE 6. No additional libraries necessary. This is particularly attractive to those working in environments with restrictive open-source policies.
Finally, a concrete example
Okay, here's some code to encrypt passwords using PBKDF2. Only Java SE 6 is required.
01import java.security.NoSuchAlgorithmException;
02import java.security.SecureRandom;
03import java.security.spec.InvalidKeySpecException;
04import java.security.spec.KeySpec;
05import java.util.Arrays;
06 
07import javax.crypto.SecretKeyFactory;
08import javax.crypto.spec.PBEKeySpec;
09 
10public class PasswordEncryptionService {
11 
12 public boolean authenticate(String attemptedPassword, byte[] encryptedPassword, byte[] salt)
13   throws NoSuchAlgorithmException, InvalidKeySpecException {
14  // Encrypt the clear-text password using the same salt that was used to
15  // encrypt the original password
16  byte[] encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt);
17 
18  // Authentication succeeds if encrypted password that the user entered
19  // is equal to the stored hash
20  return Arrays.equals(encryptedPassword, encryptedAttemptedPassword);
21 }
22 
23 public byte[] getEncryptedPassword(String password, byte[] salt)
24   throws NoSuchAlgorithmException, InvalidKeySpecException {
25  // PBKDF2 with SHA-1 as the hashing algorithm. Note that the NIST
26  // specifically names SHA-1 as an acceptable hashing algorithm for PBKDF2
27  String algorithm = "PBKDF2WithHmacSHA1";
28  // SHA-1 generates 160 bit hashes, so that's what makes sense here
29  int derivedKeyLength = 160;
30  // Pick an iteration count that works for you. The NIST recommends at
31  // least 1,000 iterations:
33  // iOS 4.x reportedly uses 10,000:
35  int iterations = 20000;
36 
37  KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength);
38 
39  SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
40 
41  return f.generateSecret(spec).getEncoded();
42 }
43 
44 public byte[] generateSalt() throws NoSuchAlgorithmException {
45  // VERY important to use SecureRandom instead of just Random
46  SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
47 
48  // Generate a 8 byte (64 bit) salt as recommended by RSA PKCS5
49  byte[] salt = new byte[8];
50  random.nextBytes(salt);
51 
52  return salt;
53 }
54}
The flow goes something like this:
  1. When adding a new user, call generateSalt(), then getEncryptedPassword(), and store both the encrypted password and the salt. Do not store the clear-text password. Don't worry about keeping the salt in a separate table or location from the encrypted password; as discussed above, the salt is non-secret.
  2. When authenticating a user, retrieve the previously encrypted password and salt from the database, then send those and the clear-text password they entered to authenticate(). If it returns true, authentication succeeded.
  3. When a user changes their password, it's safe to reuse their old salt; you can just call getEncryptedPassword() with the old salt.
Easy enough, right? If you're building or maintaining an application that violates any of the "don'ts" above, then please do your users a favor and use something like PBKDF2 or bcrypt. Help them, Obi-Wan Developer, you're their only hope.

Tuesday, May 1, 2012

JavaFX 2 vs. HTML5 for RIA

These days, we all try to develop a new project for realizing a Rich Internet Application (RIA). One of the first questions is: Which technologies and frameworks shall we use? The backend will be Java or another modern JVM language, as we are mainly experienced Java developer. In most use cases, we also prefer web frameworks, which allow to code mostly in Java, as many of us just have basic knowledge regarding HTML and JavaScript.

A decision has to be made for the upcoming project: Shall we use HTML5 or JavaFX 2 for realizing the web client? If you ask Google for “javafx or html5”, you do not find much information. In the majority of cases, you end up with a presentation hold at several IT conferences in 2011: “Moving to the Client: JavaFX and HTML5 Presentation”. Here is the Slideshare link (from JavaOne 2011): http://www.slideshare.net/steveonjava/moving-to-the-client-javafx-and-html5. Because this presentation does not help much, we took a look at pros and cons, which are listed below in this blog post.

But let’s start from the beginning…

What is a Rich Internet Application (RIA)?

There is no real definition for RIA. Therefore, here is my definition for this blog post:

“A Rich Internet Application provides a modern looking web application with animations, effects and multimedia features. The web application is hardly recognizable as web application. There is no classic HTML user interface with forms, drop down boxes or tables. Typical features of web browsers such as bookmarking or forwards / backwards navigation are usually missing / not required. Sometimes (i.e. if you use a web framework instead of just HTML5), a plugin must be installed (e.g. Java Runtime Environment or Adobe Flash Player). Pokerstars (www.pokerstars.com) is a very good example for a RIA.”

Alternatives

Several alternatives are available in the JVM environment for realizing a RIA:

  • Plain HTML5: Good solution, but you do not code in Java or another JVM language.
  • Adobe Flash / Flex: Dead! Even Adobe moves to HTML5.
  • Microsoft Silverlight: Dead! Even Microsoft Windows 8 moves to HTML5. (Of course, Silverlight is no real JVM solution, but you can make it work together with JVM backend. For the sake of completeness, I added it to this list.)
  • JavaFX: Java-based solution (replacement for Swing in the future).
  • Other JVM web frameworks besides JavaFX (JSF, GWT*, Wicket, Tapestry, Grails, Lift, “You-Name-It”): Not built for realizing RIAs. Yes, you can realize a RIA with these frameworks. Though, development is ugly, and the RIA will be ugly, too. So why would you do this? (Please remember my above definition of a RIA before you begin complaining in the comments!)
* GWT also has nice (experimental) HTML5 support for some features already: http://www.google.com/events/io/2011/sessions/gwt-html5-a-web-developers-dream.html => If Google continues adding support for HTML5 to GWT, this may be a good alternative in the next years, too – you develop only in Java, and you do NOT need a browser plugin because GWT generates plain HTML and JavaScript. However, there are also rumors that GWT is dying due to Google’s new language Dart. Google did not comment this yet, or release a roadmap for GWT.

So, the question is when to use JavaFX 2 instead of HTML5 for realizing a RIA (from the view of a Java developer)? If you do not know much about HTML5 or JavaFX, you should look at Wikipedia or google for other articles.

What is HTML5?

=> http://en.wikipedia.org/wiki/Html5

Important: HTML5 is HTML + CSS + JavaScript! It offers several next generation features for modern web development, such as Offline Storage or Application Cache.

What is JavaFX?

=> http://en.wikipedia.org/wiki/Javafx

Reminder: We are talking about JavaFX 2.0. The main difference to earlier versions is that JavaFX now offers a Java API instead of a new programming language (JavaFX Script). Thus, it is easy to learn for a Java developer.

Why HTML 5 / JavaScript?

Pros
  • W3C standard
  • It’s the future – no question!
  • No plugin is required, can be used in every (supported) web browser
  • Already many widgets and features available
Cons
  • Development with HTML / JavaScript instead of Java => Main disadvantage for a Java developer!
  • Spec not final yet (according to the roadmap not before 2014!)
  • Not supported by all browsers (yet)
  • Cross-browser development is necessary (JavaScript frameworks such as jQuery or Dojo solve this problem, but increase efforts nevertheless)


Probably, there are many other pros and cons for HTML5. Though, the named ones should be sufficient for deciding when to use HTML5 or JavaFX.

Why JavaFX 2?

Pros
  • Offers a Java API => Leverage your Java skills and use existing JVM features and libraries
  • Offers DSLs for further JVM languages, e.g. Groovy (GroovyFX) and Scala (ScalaFX). Read this article to learn how to benefit by using modern JVM languages instead of Java: “JavaFX 2.0 and Scala, Like Milk and Cookies” => http://www.javacodegeeks.com/2012/02/javafx-20-and-scala-like-milk-and.html
  • optional: “layouting” language FXML to split UI definition from behaviour => choose your favorite between programming (with Java) and layouting (with FXML)
  • Same development environment for backend and web client (including debugging, refactoring, etc.)
  • No cross-browser problems
  • CSS support (as in HTML)
  • HTML and / or JavaScript can be integrated in a JavaFX application
  • Swing and JavaFX can be used in same application, so existing Swing applications can be extended
  • JavaFX 2 provides a unified architecture for writing an application once and then deploying it to various contexts (standalone application, embedded in a web browser or run via Java Web Start). Additional contexts will be added in the future (e.g. running the same application on a mobile device).
Cons
  • Java Runtime Environment is required on client
  • Only parts of JavaFX are open source. The Oracle JavaFX runtime and SDK will continue to be released under the Java Binary Code License
  • JavaFX for Mac only available as Developer Preview (GA planned for the mid of 2012) => see JavaFX roadmap
  • JavaFX for Linux not available yet (Developer Preview planned for Q3 of 2012)
  • No information about future of JavaFX Mobile yet (at least I did not find anything, if someone has a link, please add a comment!)
  • Offers less widgets and other features than HTML5
  • Though JavaFX is the (future) replacement for Swing, development is different due to several new concepts. Of course, this is the consequence of adding RIA features such as animations => Thus, this is no real disadvantage, and its still easier for a Java developer to learn some new concepts than learning HTML and JavaScript

Conclusion

HTML5 and JavaFX 2 are both awesome for realizing RIAs including media, charts, animation, etc. In the end, both have a different target audience:
  • Public web applications should be realized with HTML5, because requiring a browser plugin is a no-go in most use cases. Therefore, even for Java developer there is no alternative to HTML5.
  • Within an enterprise, it may be acceptable to require a plugin. Probably, Java is already installed on most machines anyway. If all needed widgets and other features are available, JavaFX is the better choice for enterprise applications because a Java developer can realize RIAs much easier by developing in its well-known JVM environment.
Have fun realizing your RIA with HTML5 or JavaFX 2. By the way: We will probably choose JavaFX for our internal project because the required Java plugin is no show-stopper and most colleagues are Java developer.


Reference: When to use JavaFX 2 instead of HTML5 for a Rich Internet Application (RIA)? from our JCG partner Kai Wahner at the Blog about Java EE / SOA / Cloud Computing blog.

Tuesday, April 24, 2012

Java Concurrency with ReadWriteLock

Writing multithreaded java applications is not a piece of cake. Extra care must be taken because bad synchronization can bring your application to its knees. The JVM heap is shared by all the threads. If multiple threads need to use the same objects or static class variables concurrently, thread access to shared data must be carefuly managed. Since version 1.5, utility classes commonly useful in concurrent programming is included in the JSDK.

In Java synchronized keyword is used to acquire a exclusive lock on an object. When a thread acquires a lock of an object either for reading or writing, other threads must wait until the lock on that object is released. Think of a scenerio that there are many reader threads that reads a shared data frequently and only one writer thread that updates shared data. It's not necessary to exclusively lock access to shared data while reading because multiple read operations can be done in parallel unless there is a write operation.

In this post i'll give an example usage of ReadWriteLock interface which is introduced in the Java 1.5 API Doc. In Java Api Documentation it says :

 A ReadWriteLock maintains a pair of associated locks,
one for read-only operations and one for writing.
The read lock may be held simultaneously by multiple reader threads,
so long as there are no writers. The write lock is exclusive.


Reader threads can read shared data simultaneously. A read operation does not block other read operations. This is the case when you execute an SQL SELECT statement. But write operation is exclusive. This means all readers and other writers are blocked when a writer thread holds the lock for modifing shared data.

Writer.java This class represents a thread that updates shared data. Writer uses WriteLock of ReadWriteLock to exclusively lock access to dictionary.

01package deneme.readwritelock;
02  
03  
04 public class Writer extends Thread{
05   private boolean runForestRun = true;
06   private Dictionary dictionary = null;
07    
08   public Writer(Dictionary d, String threadName) {
09     this.dictionary = d;
10     this.setName(threadName);
11   }
12   @Override
13   public void run() {
14     while (this.runForestRun) {
15       String [] keys = dictionary.getKeys();
16       for (String key : keys) {
17         String newValue = getNewValueFromDatastore(key);
18         //updating dictionary with WRITE LOCK
19         dictionary.set(key, newValue);
20       }
21        
22       //update every seconds
23       try {
24         Thread.sleep(1000);
25       } catch (InterruptedException e) {
26         e.printStackTrace();
27       }
28     }
29   }
30   public void stopWriter(){
31     this.runForestRun = false;
32     this.interrupt();
33   }
34   public String getNewValueFromDatastore(String key){
35     //This part is not implemented. Out of scope of this artile
36     return "newValue";
37   }
38 }

Reader.java This class represents a thread that reads share data.
01package deneme.readwritelock;
02  
03 public class Reader extends Thread{
04    
05   private Dictionary dictionary = null;
06   public Reader(Dictionary d, String threadName) {
07     this.dictionary = d;
08     this.setName(threadName);
09   }
10    
11   private boolean runForestRun = true;
12   @Override
13   public void run() {
14     while (runForestRun) {
15       String [] keys = dictionary.getKeys();
16       for (String key : keys) {
17         //reading from dictionary with READ LOCK
18         String value = dictionary.get(key);
19          
20         //make what ever you want with the value.
21         System.out.println(key + " : " + value);
22       }
23        
24       //update every seconds
25       try {
26         Thread.sleep(1000);
27       } catch (InterruptedException e) {
28         e.printStackTrace();
29       }
30     }
31   }
32    
33   public void stopReader(){
34     this.runForestRun = false;
35     this.interrupt();
36   }
37 }

Dictionary.java This is a simple and thread safe dictionary. Read operations are managed through ReadLock and write operations (updates) are managed throuh WriteLock.
01package deneme.readwritelock;
02  
03 import java.util.HashMap;
04 import java.util.concurrent.locks.Lock;
05 import java.util.concurrent.locks.ReentrantReadWriteLock;
06  
07 public class Dictionary {
08    
09   private final ReentrantReadWriteLock readWriteLock =
10     new ReentrantReadWriteLock();
11  
12   private final Lock read  = readWriteLock.readLock();
13    
14   private final Lock write = readWriteLock.writeLock();
15    
16   private HashMap<String, String> dictionary = new HashMap<String, String>();
17    
18   public void set(String key, String value) {
19     write.lock();
20     try {
21       dictionary.put(key, value);
22     } finally {
23       write.unlock();
24     }
25   }
26    
27   public String get(String key) {
28     read.lock();
29     try{
30       return dictionary.get(key);
31     } finally {
32       read.unlock();
33     }
34   }
35  
36   public String[] getKeys(){
37     read.lock();
38     try{
39       String keys[] = new String[dictionary.size()];
40       return dictionary.keySet().toArray(keys);
41     } finally {
42       read.unlock();
43     }
44   }
45    
46   public static void main(String[] args) {
47     Dictionary dictionary = new Dictionary();
48     dictionary.set("java",  "object oriented");
49     dictionary.set("linux", "rulez");
50     Writer writer  = new Writer(dictionary, "Mr. Writer");
51     Reader reader1 = new Reader(dictionary ,"Mrs Reader 1");
52     Reader reader2 = new Reader(dictionary ,"Mrs Reader 2");
53     Reader reader3 = new Reader(dictionary ,"Mrs Reader 3");
54     Reader reader4 = new Reader(dictionary ,"Mrs Reader 4");
55     Reader reader5 = new Reader(dictionary ,"Mrs Reader 5");
56     writer.start();
57     reader1.start();
58     reader2.start();
59     reader3.start();
60     reader4.start();
61     reader5.start();
62   }
63    
64 }


Reference: ReadWriteLock example in Java from our JCG partner Ilkin Ulas at the All your base are belong to us blog.

Monday, April 23, 2012

Why Developers Keep Making Bad Technology Choices

Today, software developers are faced with a great abundance of options when choosing how to design and implement systems. We are constantly bombarded with choice and are used to dealing with buzzwords like NoSQL, the cloud, REST, Map-Reduce and so on. However, developers in charge of designing systems can be easily seduced into incorporating technologies that don’t provide a clear benefit over simpler solutions that aren’t as modern or hip. It seems like the KISS principle (Keep it simple, stupid!), while often referenced, is often neglected in favour of more “enterprisey” solutions. Why is this?

There are probably a lot of reasons, but I’ve identified a few that I think cover the majority of cases. As professional developers, I feel strongly that we have a duty to our employers to provide the best long-term solutions and therefore we need to rein in our desires when they conflict with this. Software development is not yet in the same realm as medicine or engineering, but I think we do need to make steps towards the professionalism, duty and responsibility that come with working in those fields.

Reason #1 – Boredom

Developers are often solving the same types of problems over and over. Not all of us have the privilege of working on new types of projects all the time, and even if we are, it’s often not new ground; similar problems have usually been solved thousands of times before by software developers around the globe.

It’s no surprise then that we want to try something new, even if we’ve adequately solved a problem before. We are natural puzzle solvers, and sometimes you just want to try a new puzzle. I’m sure many of you with several years of experience have seen functional systems effectively replaced with a new implementation that uses different technologies for no clear reason other than to suit the fancy of new developers.

So what do we do about this? How do we scratch that itch for something new? A relational DB is just so boring compared to trying out the latest NoSQL platform. Who cares if we don’t really have a good use for it? Well, I’d say you have a few options. For example, take the initiative and find ways to build out the platform that might actually benefit from some new technology. Other than that, why not work on a pet project in your spare time? After all, our job is to deliver high quality software – not entertain ourselves.

Disclaimer: I’m not trying to dissuade anyone from using new technologies. Just identify their benefits and see if they are the best choice for what you are doing, and if what you have doesn’t do the job, go for it!

Reason #2 – Resume Padding

This is perhaps the saddest of the reasons why developers make poor technology choices, and it mainly affects organizations with poor decision-making processes, but it’s still very common.

Contracts and positions in software development are very fluid these days – it’s not uncommon for a developer to be at a new company every year or two. Gone are the days where hopping from job to job is considered a no-no. Since this is the case, a lot of developers leap-frog from position to position to climb the ladder. It’s far easier for an average or lower-skilled developers to get ahead by doing this instead of trying to move up within a single company.

Since this is the case, developers will often try to incorporate technologies to get experience in them so as to add a bullet-point to their resume. How useful the technology will be to the platform is of secondary importance. Often it doesn’t matter how much they actually use it – nobody can pretend that people don’t exaggerate their skills when looking for new work. Therefore, platforms from small to large will often end up using untested technologies, or just technologies that nobody in-house actually understands well. Companies are then left with poor systems using too many technologies with nobody to maintain them as developers jump ship to more promising positions.

I don’t believe that most developers do this, but those of us who disagree with such actions should work to push back when presented with developers who are trying to make bad choices.

Reason #3 – Peer Pressure

Peer pressure is perhaps the most difficult cause to resist. We all like to believe that we are independent agents that make our own informed decisions, but all of us are human, and event the most prickly people are social creatures that want to have a happy social group.

When faced with new or hip technologies, a lot of us are somewhat afraid to resist implementing something that doesn’t really seem like a good idea to us. But we should suppress this feeling as much as we can. If you are in an environment where discussion and disagreement are valued (as one would hope), you should feel free to voice your concerns even if you aren’t totally familiar with the latest-and-greatest. Remember that software technologies come and go, but the basic principles pretty much stay the same. So if something doesn’t seem to add up, speak up! If you are a junior developer, you should still feel free to add your input – having experience doesn’t make one right. Plus, you could very well gain some insight into the choices that are being made.

Reason #4 – Lack of Understanding

Finally, technologies are sometimes chosen because developers don’t understand how things are actually working in a platform, or don’t want to find out.

For example, if you don’t have experience with highly performant relational databases, you may be inclined to go the NoSQL route, out of fear that you may implement something that won’t scale. Often though, this fear can be unfounded. If you are using a tool improperly, of course it won’t work well. But don’t let lack of understanding or knowledge force you into an unwise course of action. If, in reality, a solution could be implemented well in a relational database, and your platform already uses one, it would be foolish to introduce a new dependency simply because you aren’t familiar with what you have.

To avoid this, read and learn! If you are making choices, examine your assumptions and see if they hold up. Consult with senior developers who have worked with the tools in question and ask specifics about what they can and can’t do well. It’s never a waste to learn more about the tools that are available to us, and it will very likely pay dividends well into the future if you take the initiative.

Reason #5 – Misunderstanding or Solving Non-Existent Problems

This point ties into my previous point a little bit, but it really deserves its own discussion since it is such a big problem.

A common theme when developers pitch a new technology is that it does X and Y and protects against Z. But a lot of the time, X, Y and Z were never issues in the first place. For example, if we have a read-only data set that needs to be cached on multiple nodes in a cluster, someone may pitch a caching technology that offers distributed data sets where elements are not duplicated on each node. But what if the data set is small and we don’t anticipate any change that would necessitate distributed caching? We’d be introducing new technology that is inherently slower, more brittle and more complicated for a problem that doesn’t exist!

To guard against this, developers need to make sure that they understand the problem domain all the way through, and they also need to cross-check their assumptions to make sure they are correct. Sometimes we assume things that actually aren’t the case, so the latter step is important. Avoid the temptation to cover “what-if” situations. Chances are, you ain’t gonna need it, and if you do, we usually overestimate the cost of making changes at a later date, not realizing we are basically committing to the same effort now to avoid a slim chance of having to do the same amount of work later.

So What Should We Do?

So what are the rights things to do when choosing technologies? To start with, you might want to review the following points, and try to make it a team decision. The more input you have, the less likely you are to miss a piece of information that might alter your decision.
  • Review the requirements – consistency, failover, performance, etc.
  • Evaluate if what you have can meet the need well. If so, this is almost always the right choice.
  • Investigate how other technologies would meet the need, and factor in the costs of extra dependencies and potential failure points (nothing is free, and every new technology can have significant maintenance costs).
  • Find out your team’s expertise – favour things that you know well.
  • Factor in any other concerns like pricing, timelines, etc.
  • Discuss with the team, and make a pros and cons list.
These are just guidelines, and you can approach it any way you like, because the main thing is that you do make the decision carefully and rationally.

I hope that nobody takes this article to mean that new technologies are scary or that they should just be avoided! For instance, I’ve used NoSQL as an example already. I believe it definitely fills a need that exists and I’ve used it before to solve specific problems, but sometimes I think we get caught up in the fun stuff, and forget our ultimate goals. Just keep your objectives in mind and try to make the best long-term choice.


Reference: Why Developers Keep Making Bad Technology Choices from our JCG partner Craig Flichel at the Carfey Software Blog blog.

The Greatest Developer Fallacy Or The Wisest Words You’ll Ever Hear?

"I will learn it when I need it"! I've heard that phrase a lot over the years; it seems like a highly pragmatic attitude to foster when you're in an industry as fast-paced as software development. On some level it actually IS quite pragmatic, but on another level I am annoyed by the phrase. It has become a mantra for our whole industry which hasn't changed said industry for the better. The problem is this, in the guise of sounding like a wise and practical developer, people use it as an excuse to coast. There is too much stuff to know, it is necessary to be able to pick certain things up as you go along – part of the job. But, there is a difference between having to "pick up" some knowledge as you go along and doing absolutely everything just-in-time.

The whole industry has become a bunch of generalists, maybe it has always been this way, I just wasn't around to see it, either way I don't like it. Noone wants to invest the time to learn anything really deeply, not computer science fundamentals, not the latest tech you're working with, not even the language you've been coding in every day, for the last few years. Why bother, it will be replaced, superseded, marginalised and out of fashion before you're half way done. I've discussed this with various people many times, but noone seems to really see it as a problem. "Just being pragmatic dude". In the meantime we've all become clones of each other. You want a Java developer, I am a Java developer, you're a Java developer, my neighbour is a Java developer. What differentiates us from each other – not much! Well, I've got some jQuery experience. That's great, so you know how to build accordion menu then? Sure, I Google it and steal the best code I find :). In the meantime, if you need to hire a REAL expert (in anything, maybe you're writing a fancy parser or need to visualise some big data), I hope you've stocked up on beer and sandwiches cause you're gonna be here a while.

Ok, there are ways to differentiate yourself, I have better communication skills, which is why I do better. That's important too, but, developers differentiating themselves based on soft skills rather than developer skills – seems a bit twisted. We all communicate really well but the code is a mess :). Hell, I shouldn't really talk, I am a bit of a generalist too. Of course I'd like to think of myself as a T-shaped individual, but if we're completely honest, it's more of a dash-shaped or underscore-shaped with maybe a few bumps :). To the uninitiated those bumps might look like big giant stalactites – T-shaped indeed. You seem like an expert without ever being an expert, just one advantage of being in a sea of generalists.

Investing In Your Future

I don't want to preach about how we should all be investing in our professional future, everybody knows we should be. Most people probably think they are infact investing, they rock up to work, write a lot of code maybe even do some reading on the side, surely that must make them an expert in about 10 years, and a senior expert in 20 (I keep meaning to write more about this, one day I'll get around to it :))? But, if that was the way, every old person would be an expert in a whole bunch of stuff and that is emphatically not the case. Maybe it is just that people don't know how to build expertise (there is an element of truth to this), but I have a sneaking suspicion that it's more about lack of desire rather than lack of knowledge. What was that saying about the will and the way – totally applicable in this case?

I've gone completely off-track. "Investing in professional future" is just one of those buzzword things, the mantra is "I will learn it when I need it". It was good enough for my daddy and it has served me well so far. Let's apply this thinking to finance, "I will invest my money when I think I need the money". Somehow it doesn't quite have the same kind of pragmatic ring to it.

You Don't Know What You Don't Know

We've all had those moments where you're going through major pain trying to solve a problem until someone comes along and tells you about algorithm X or technology Y and it makes everything fast and simple. It was lucky that person just happened to be there to show you the "easy" way, otherwise you would have spent days/weeks trying to figure it out and it would have been a mess. You can't be blamed for this though, you don't know what you don't know. For me, this is where the "I will learn it when I need it" mentality falls over. You can't learn something if you don't know it exists. Google goes a long way towards mitigating this problem, but not all the way. There are plenty of problems you will encounter in the wild where you can beat your head against the wall ad infinitum unless you know what class of problem you're looking at (e.g. if you know a bit about searching and constraint propagation, solving sudoku is easy, otherwise it's really quite hard). You can't learn about an algorithm if you're not aware of it or its applicability. You can't utilise a technology to solve a problem if you don't even realise it has that capability. You're not going to always have someone there to point you in the right direction. I am willing to bet there is a billion lines of code out there right now which can be replaced with a million lines of faster, cleaner, better code simply because whoever wrote it didn't know what they didn't know.

I seem to be making a case for the opposite side here, if knowing what you don't know is the ticket then surely we should be focusing on breadth of knowledge. Superficial awareness of as much stuff as possible should see us through, we'll be able to recognise the problems when we see them and then learn what we need more deeply. Except it doesn't work like that, skimming subjects doesn't allow you to retain anything, our brain doesn't work that way. If we don't reinforce and dig deeper into the concepts we quickly page that information out as unimportant, it is a waste of time (think back to cramming for exams, how much do you remember the next day?). However if you focus on building deeper understanding of a subject – in an interesting twist – you will gain broad knowledge as well (which you will actually be able to retain). My grandad is a nuclear physicist, several decades of working to gain deeper knowledge of the subject has made him an expert, but it has also made him an excellent mathematician, a decent chemist, a pretty good geologist, a fair biologist etc. Just some empirical evidence that seeking depth leads to breadth as a side-effect.

Can You Learn It Fast Enough

Some stuff just takes a long time to learn. I am confident I can pick up an ORM framework I haven't seen before without even breaking stride, I've used them before, the concepts are the same. But what if you need to do some speech to text conversion, not quite as simple, not enough background. Hopefully Google will have something for us to copy/paste. That was a bad example, only research boffins at universities need to do that crap. How about building a website then, we all know how to do that, but what if you need to do it for 10 million users a day. We just need to learn everything about scaling, I am sure the users will wait a month or two for us to get up to speed :). Yeah, I am just being stupid, all we need to do is hire an expert and … errr … oh wait, we're all out of beer and sandwiches.

Why Should I Care

Working with experts is freaking awesome. You may have experienced it before, everything they say is something new and interesting, you learn new tricks with every line of code, you can almost feel your brain expanding :). You want to learn from the experts, so it's really sad when you can't find any. Since everyone is only learning when they "need it", noone can teach anything to anyone. The chunk of wisdom here is this, you want to work with experts, but the experts also want to work with experts, so what are you doing to make sure the experts want to work with you? Being able to learn something when you need it is a good skill to have, but you can not let it be your philosophy as a developer. Yes it is a big industry you can't learn everything, so pick something and make sure you know it backwards, if you're curious enough to follow up on the interesting bits, you'll find you have a decent grasp of a lot of other stuff at the end. And if you do a good enough job, other super-awesome-smart people are going to want to come and hang around you cause they'll be able to learn something from you and you'll be able to learn much from them. Everybody will be a winner.


Reference: The Greatest Developer Fallacy Or The Wisest Words You’ll Ever Hear? from our JCG partner Alan Skorkin at the Skorks blog.