• Trusted by:

Hire Freelance Java Developers and Engineers

Anna Chiara Bellini, Italy

Freelance Java Developer at Toptal since August 5, 2013
When Anna was a kid, her brother got a Commodore 64 for Christmas. He played video games, and she started coding. Since then, her career has spanned many different projects and programming technologies. But regardless of the task at hand, she always brings the same enthusiasm and passion. Click to continue

Sam Varshavchik, United States

Freelance Java Developer at Toptal since September 16, 2012
Sam is a senior freelance developer and architect with over 20 years of experience developing in the financial industry. Click to continue

Dathan Guiley, United States

Freelance Java Developer at Toptal since July 15, 2013
Dathan is a forward-thinking freelance software architect, developer, and leader with roots in effective software development. He has twenty years in the field and experience with in-house development and management work at top internet companies including Amazon, Netflix, Yahoo!, and Overstock. He has focused for the last three years on consulting, development, and management for startups and challenging projects. Click to continue

Ted Cohn, Puerto Rico

Freelance Java Developer at Toptal since February 1, 2014
Ted has 25+ years as a senior architect, technologist, developer, entrepreneur, and CTO. He led Barnes & Noble's Nook team in Palo Alto, created Pleo the dinosaur, Foodiebot chatbot ordering system and worked for Silicon Valley giants like Apple, Excite, and NeXT. He can develop new concepts, join/lead teams, and bring order to chaos. He loves innovating and delivering incredible products. Superb communication and presentation skills. Click to continue

Harold Frazier, Jr., United States

Freelance Java Developer at Toptal since September 5, 2012
Computers have been Harold's passion since he compiled his first program in elementary school. He will always appreciate how the software industry continues to change and grow through technology innovations that make our lives more enjoyable and efficient. Click to continue

Andrei Latyshau, Canada

Freelance Java Developer at Toptal since December 28, 2013
Andrei is an expert software designer with 6 years of hands-on experience in development of APIs and frameworks. He is a pragmatic systems architect, deep thinker, and generalist with strong skills to conceptualize complexities, uncertain ideas, and abstractions. He has been a passionate and inventive programmer, researcher, and self-learner since his school days. Click to continue

Pablo Lalloni, Argentina

Freelance Java Developer at Toptal since November 25, 2012
Pablo is an architect and developer with extensive experience in a wide range of techniques and technologies and a strong ability to understand and solve problems efficiently while keeping in mind the big picture. He consistently achieves very high quality and has successfully led several projects with small teams. Click to continue

Pablo Pera, United States

Freelance Java Developer at Toptal since April 15, 2014
Pablo has taken more than 10 mobile apps from idea to millions of users in the market, as the lead engineer of multiple teams in various companies, including his own. Before focusing full-time on Android apps, he worked for Google and CERN (home of the LHC particle accelerator) as well as various tech startups in NY. He has invaluable experience in all areas related to an Android app from design and coding to acquisition and growth. Click to continue

Steven S. Morgan, United States

Freelance Java Developer at Toptal since May 24, 2013
Steven is an expert Java architect and freelance developer with extensive experience in distributed architectures, scalable solutions, and flexible and maintainable designs. He is a team player with a knack for interacting well with diversity. He leads via his expertise and by the example he sets. Click to continue

Philip R Brenan, Portugal

Freelance Java Developer at Toptal since January 15, 2014
Philip is a freelance software developer who specializes in Android apps. He has achieved "Developer Select" status from Amazon, and has written and published 348 apps on Amazon, Google, and Nokia. He makes extensive use of Amazon Web Services, along with Java and JavaScript on Android to build apps that span the cloud. Click to continue
Trustpilot
Toptal on TV
"Toptal is killing it, it kind of owns this market."
Andrew Ross Sorkin Reviews Toptal
Cnbc 02e66b
"Tech companies simply cannot find the quality employees they want to hire. The solution: Toptal."
Liz Claman´s Review of Toptal
Fox 7ef901
Toptal in the press
“Despite accelerating demand for coders, Toptal prides itself on almost Ivy League-level vetting.”
Selina Wang
“Toptal allows corporations to quickly assemble teams that have the right skills for specific projects.”
Steven Norton
A hiring guide
The Vital Guide to Java Interviewing

Mastering Java is no small feat. Its extensive class libraries contain a wide array of capabilities and nuances, many of which are lost on the average developer. Those who have mastered the language can have a significant positive impact on your team's productivity and on your system's performance. Here are some targeted questions to help identify true masters of the language.

Testimonials
“While looking for a high-level Python/Django developer, I found Toptal via a simple Google search, and that was a stroke of luck for our company. We needed a expert engineer who could start on our project immediately as we had a tight deadline. We were introduced to Simanas and immediately knew he was a great choice who had already been vetted... and he exceeded our expectations with his work. Not having to interview and chase down an expert developer was an excellent time-saver and made everyone feel more comfortable with our choice to switch platforms to utilize a more robust language. Toptal made the process easy and convenient, and we are extremely happy with the results. Toptal is now the first place we look for expert-level help.”
Derek Minor
Senior VP of Web Development @ NetWorldMediaGroup
“In Higgle's early days, we needed best-in-class developers, at affordable rates, in a timely fashion. Toptal delivered! Higgle enjoyed working with Toptal and we appreciate their professionalism.”
Lara Aldag
CEO @ Higgle
“We've been incredibly pleased with our experience working with Toptal thus far. Their team worked quickly and efficiently to isolate the needs of our project, and they paired us with an appropriate developer within a couple days who we quickly contracted after a great interview. The work performed on our project was top-notch, and we can’t wait to make use of Toptal’s resources again.”
Ryan Staake
Owner @ Pomp&Clout
“With Toptal, we are able to find talented developers in a matter of weeks instead of months. The quality of talent they supply is extremely high as the developers are able to immediately onboard and ramp incredibly fast.”
Zac Carman
CEO @ ConsumerAffairs
“Marcos was a wonderful engineer and really helped us out on this project. Without him I feel like we really would have been at a loss.”
Jama Mohamed
Owner @ JM Technologies
“Working with Toptal has been a great experience. Prior to using them, I had spent quite some time interviewing other freelancers and wasn't finding what I needed. After engaging with Toptal, they matched me up with the perfect developer in a matter of days. Amaury, the developer I'm working with, had all of the right skills and experiences that I needed for my project. He not only delivers quality code, but he also makes suggestions on things that I hadn't thought of. It's clear to me that Amaury knows what he is doing and I'm happy to have him on the team. Highly recommended!”
George Cheng
CEO @ Bulavard, Inc.
“We really enjoy working with Toptal. The experience has been very positive, and we'd recommend it to anyone seeking developers on-demand.”
Jeff Kerr
CEO @ CaseFleet
“My experience with Toptal has exceeded expectations. I needed to quickly find a front-end developer, and the first person they recommended was a perfect fit. A month later, I needed an iOS developer and they delivered again. I'm incredibly impressed with the quality of the people in Toptal's network and how quickly I was able to find a match for my needs. Greco is an amazing web developer. He has great attention to detail, in such a way that his websites look just like the design mockups we created on Photoshop. Not only that, but his code is very organized, and he proved to be very skilled in React.js. I couldn't have been happier with his contributions to our company. Vadim is a very experienced software engineer, particular in iOS. He was able to help us build our mobile app in record speed, and also contributed to major mobile and architecture decisions. Vadim is a proactive and intelligent engineer and has impressed us from day one.”
Bruno De Martino
Head of Product @ Token
“It has been wonderful to work with Fabian for the past two years. He is an expert in JavaScript development and has built our embeddable widget and video player. He is a quick study and is able to learn how to integrate new technologies, which is so critical for a startup. He even took the extra effort to teach others on the team. He is super responsive and often went above and beyond to help us meet deadlines (including working on weekends). Thank you Fabian. Thank you Toptal for making it so easy to find and work with amazing talent.”
Natasha Mohanty
CTO @ FEM Inc
“With the pressure on and millions watching the Cleveland Cavaliers during the NBA Playoffs, Toptal delivered the talent and expertise needed to launch a brand new fan engagement platform.”
Conor Kenney
Director of Professional Services @ Cleveland Cavaliers
“We were extremely impressed with both Toptal and our developer, Bojan. They were extremely professional and flexible with our schedule. On multiple occasions, we needed to alter our timeline and they never hesitated to accommodate us. Bojan was communicative and delivered what we asked for on time and exactly to spec. I know that should we need additional work, will surely be looking to hire Bojan and Toptal again. ”
Stephen Vasallo
Co-founder @ Bubble
“I really enjoyed my experience with Toptal. Searching for a developer was both painless and engaging, and the first match was a perfect fit! Toptal is a fantastic way to find talented developers for small or large aspects of your project.”
Willem Shepherd
Creative Director @ Mookieyams
“Toptal has been extremely helpful to us in finding top remote talent. The ratio from interview to hire with Toptal candidates is the highest I've ever experienced in my professional career.”
Philipp Berner
Co-founder and CTO @ KeepSafe
“Andrea is doing an amazing job. I don't think we could have gotten a better person. He is fun to work with, he thinks out of the box, and he is extremely knowledgeable in what he is going. He not only does an excellent job, he also helps our company to differentiate our business model further (e.g. making our app offline-capable). I would recommend Andrea as well as Toptal any time to any friend.”
Pascal Girardat
Co-Founder / CEO @ Lifestage Solutions AG
“Toptal is a great resource for startups with ever changing product roadmaps and budgets. We had highly skilled and reasonably priced Toptal developers working for us within 8 business days of our first conversation with Toptal. It has been an empowering experience for our company to start working with Toptal.”
Chris Clark
CEO @ ModernStat Labs
“We had a wonderful experience with our Toptal consultant. He was very reliable and punctual, delivering excellent work on a budget—we will certainly be using him again!”
Barbara Karpf
President @ DecoratorsBest
“Nuno is brilliant! He has been extremely helpful and really knows his stuff with regard to Django in particular.”
John Yetter
Software Engineer @ Survox, Inc.
“Toptal has been an incredible source of amazing software engineering talent. The contractors who have worked with us have been top notch, spoke perfect English, and worked superbly with our team. We recommend Toptal without any reservations!”
Vineet Singal
Co-Founder @ Anjna Patient Education
“As an internet marketing company specializing in pay-per-click management, our clients frequently ask us to provide services that fall outside the scope of our primary business. We have found Toptal to be exactly the resource we need to connect with contractors so we can deliver our clients top tier web development talent at a reasonable cost.”
Pashmina Lalchandani
Owner @ Flowsimple
Hire a top Java developer now.
Toptal is a marketplace for top Java developers, engineers, programmers, coders, architects, and consultants. Top companies and start-ups choose Toptal freelancers for their mission critical software projects.
Full
profile
Anna Chiara BelliniItaly
When Anna was a kid, her brother got a Commodore 64 for Christmas. He played video games, and she started coding. Since then, her career has spanned many different projects and programming technologies. But regardless of the task at hand, she always brings the same enthusiasm and passion.
[click to continue…]
JavaSQLJavaScriptApache StrutsSpringSpring MVCJava ServletsMicrosoft ExcelAJAXJava EEJava SE
Hire
Full
profile
Sam VarshavchikUnited States
Sam is a senior freelance developer and architect with over 20 years of experience developing in the financial industry.
[click to continue…]
JavaSQLPerlC++jQueryMySQL
Hire
Full
profile
Dathan GuileyUnited States
Dathan is a forward-thinking freelance software architect, developer, and leader with roots in effective software development. He has twenty years in the field and experience with in-house development and management work at top internet companies including Amazon, Netflix, Yahoo!, and Overstock. He has focused for the last three years on consulting, development, and management for startups and challenging projects.
[click to continue…]
JavaJavaScriptSQLApache Struts 2AngularJSSpringHibernateJava ServletsAgile Software DevelopmentMySQLOracle SQLeCommerce
Hire
Full
profile
Ted CohnPuerto Rico
Ted has 25+ years as a senior architect, technologist, developer, entrepreneur, and CTO. He led Barnes & Noble's Nook team in Palo Alto, created Pleo the dinosaur, Foodiebot chatbot ordering system and worked for Silicon Valley giants like Apple, Excite, and NeXT. He can develop new concepts, join/lead teams, and bring order to chaos. He loves innovating and delivering incredible products. Superb communication and presentation skills.
[click to continue…]
JavaObjective-CCHTML5SQLJavaScriptMicrosoft Bot FrameworkJava CollectionsSQLiteNode.jsjQueryRubyMineAndroid Studio
Hire
Full
profile
Harold Frazier, Jr.United States
Computers have been Harold's passion since he compiled his first program in elementary school. He will always appreciate how the software industry continues to change and grow through technology innovations that make our lives more enjoyable and efficient.
[click to continue…]
JavaHTML5C#C++JavaScriptSQLAndroid SDKAndroid StudioAndroidWindows Mobile
Hire
Full
profile
Andrei LatyshauCanada
Andrei is an expert software designer with 6 years of hands-on experience in development of APIs and frameworks. He is a pragmatic systems architect, deep thinker, and generalist with strong skills to conceptualize complexities, uncertain ideas, and abstractions. He has been a passionate and inventive programmer, researcher, and self-learner since his school days.
[click to continue…]
JavaJavaScriptJava SEJava EEAPI Design
Hire
Full
profile
Pablo LalloniArgentina
Pablo is an architect and developer with extensive experience in a wide range of techniques and technologies and a strong ability to understand and solve problems efficiently while keeping in mind the big picture. He consistently achieves very high quality and has successfully led several projects with small teams.
[click to continue…]
JavaScalaJavaScriptGoExt JSHibernateHadoopScala IDEJava EEJava SE
Hire
Full
profile
Pablo PeraUnited States
Pablo has taken more than 10 mobile apps from idea to millions of users in the market, as the lead engineer of multiple teams in various companies, including his own. Before focusing full-time on Android apps, he worked for Google and CERN (home of the LHC particle accelerator) as well as various tech startups in NY. He has invaluable experience in all areas related to an Android app from design and coding to acquisition and growth.
[click to continue…]
JavaJavaScriptAndroid SDKParse Android SDKGitHubGitAgile Software DevelopmentAndroid
Hire
Full
profile
Steven S. MorganUnited States
Steven is an expert Java architect and freelance developer with extensive experience in distributed architectures, scalable solutions, and flexible and maintainable designs. He is a team player with a knack for interacting well with diversity. He leads via his expertise and by the example he sets.
[click to continue…]
JavaJava ServletsWebSocketsJava EEJ2SEJavaBeans
Hire
Full
profile
Philip R BrenanPortugal
Philip is a freelance software developer who specializes in Android apps. He has achieved "Developer Select" status from Amazon, and has written and published 348 apps on Amazon, Google, and Nokia. He makes extensive use of Amazon Web Services, along with Java and JavaScript on Android to build apps that span the cloud.
[click to continue…]
JavaSQLPerlCAndroid SDKAmazon APIAgile Software DevelopmentJava SEAmazon Web Services (AWS)AndroidJava MEJ2SEAmazon S3
Hire

The Vital Guide to Java Interviewing

The Challenge

Today, nearly 20 years after its initial launch, Java is reported to be the most in-demand language skill, and by a wide margin (twice as popular as the runner up, PHP).

With Java usage being so pervasive, there is no shortage of developers with Java listed on their resumes. But as with any technology, there’s knowing Java and then there’s really knowing Java. So how can you identify those who are true Java experts?

Java mastery, like many skills in life, takes time and a healthy dose of curiosity to fully leverage its power. Accordingly, as described in our post In Search of the Elite Few, an effective recruiting process needs to evaluate many dimensions of a candidate beyond just technical knowledge; attributes such as drive, integrity, and creativity are equally essential attributes of a master developer. Evaluating those dimensions of a candidate can then be augmented with questions – such as those presented herein – to help identify those who are true Java experts.

Assessing the Foundation

We begin with some questions that can help evaluate the depth of a candidate’s understanding of some fundamental Java paradigms and concepts.

Q: What are anonymous classes? When, why, and how would you use them? Provide an example.

Anonymous classes are in-line expressions, often single-use classes for convenience, that help make your code more concise. The following example instantiates a new ActionListener to handle events associated with a button:

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        /* do something in response to button action event */
    }
});

This makes sense since the class isn’t used elsewhere and doesn’t need a name. However, if you pass an anonymous class to a registration method, for instance, you may want to keep track of its reference, in order to be able to unregister it later. Let’s extend the above example to demonstrate this:

ActionListener listener = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        /* do something in response to button action event */
    };
button.addActionListener(listener);

/* some time later... */

button.removeActionListener(listener);

Q: What are abstract classes? When, why, and how would you use them? Provide an example.

Abstract classes are useful for defining abstract template methods that concrete subclasses must implement. All concrete subclasses are therefore guaranteed to honor the API specified by the abstract methods in the abstract class they inherit from. This is somewhat similar to the way in which a Java interface specifies an API for all classes that implement it.

The common use case is where there is a category of objects that have a common behavior (e.g., all shapes have an area), but the details of calculating or performing those functions varies from one object to another. For example:

 public abstract class Shape {
     public abstract double area();
 }
 
 public class Circle extends Shape {
     private double radius;
     
     public Circle(double radius) {
         this.radius = radius;
     }
     public double area() { return Math.PI * Math.pow(this.radius,2); }
 }
 
 public class Rectangle extends Shape {
     private double width, height;
     
     public Rectangle(double width, double height) {
         this.width = width;
         this.height = height;
     }
     public double area() { return this.width * this.height; }
 }

A couple of things worth noting:

  • Abstract classes may not be instantiated directly; only their concrete subclasses are instantiable.
  • A class may be declared abstract even if it has no abstract methods. This will preclude that class from being instantiated. This can be useful, for example, if a base class in a class hierarchy has no abstract methods but is not itself meant to be instantiated.

Q: Compare and contrast checked and unchecked exceptions. Provide examples.

Unchecked exceptions are exceptions that are not considered to be recoverable. Java doesn’t force you to catch or handle these because they indicate abnormal, unexpected problems with your code such as NullPointerException, ArithmeticException and IndexOutOfBoundsException. That is, these are problems you need to fix or prevent. Unchecked exceptions all derive from RuntimeException.

Checked exceptions are exceptions that are considered to be recoverable. Checked exceptions must explicitly be specified as part of a method’s API; that is, a method that may throw one or more checked exceptions must list those potential exceptions as part of its method declaration (the Java compiler will actually enforce this).

When calling a method that throws exceptions, the caller must either handle (i.e., catch) those exceptions or must throw them itself. For example, if a method throws a checked exception, the caller might decide to ignore the error and continue (swallow it), display a dialog to the user, or rethrow the exception to let a method higher up the call chain handle it (in which case it must also declare that it throws the checked exception).

For example:

public void readFile(File file) throws IOException, MyReadFileException {
    try {
        FileInputStream fis = new FileInputStream(file);
    } catch(FileNotFoundException e) {
        // We catch the FileNotFoundException and instead throw an IOException,
        // so we don't include FileNotFoundException in our "throws" clause above. 
        throw new IOException();
    }
    
    if (somethingBadHappened) {
        // We explicitly throw our own MyReadFileException here,
        // so we do include it in our "throws" clause above.
        throw new MyReadFileException();
    }
}

Checked exceptions clearly communicate and enforcing handling of error conditions. However, it can also be a pain for developers to continually need to include try/catch blocks to handle all known exceptions from the methods that they call. Although numerous checked exceptions are certainly permissible in Java, things can get a bit unwieldly. For example:

public void sillyMethod() throws DataFormatException, InterruptedException, 
	IOException, SQLException, TimeoutException, ParseException {
...
}

Accordingly, there has been raging debate for years on whether to use checked or unchecked exceptions when writing libaries, for example. As is true with many such debates, the truth is that there really is no one-size-fits-all, across-the-board correct answer. Checked and unchecked exceptions each have their own advantages and disadvantages, so the decision about which to use largely depends on the situation and context.

Q: Describe Generics and provide examples of generic methods and classes in Java.

Java generics enable programmers to specify, with a single method or class declaration, functionality that can be applied to multiple different data types. Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.

Here, for example, is a generic method that uses <E> as the placeholder for a generic type:

public <E> void printArray( E[] inputArray ) {
    // Display array elements              
    for ( E element : inputArray ) {        
        System.out.printf( "%s ", element );
    }
    System.out.println();
}

The above method could then be invoked with various types of arrays and would handle them all appropriately; e.g.:

// invoke generic printArray method with a Double array
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
printArray(doubleArray);

// invoke generic printArray method with a Character array
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
printArray(charArray);

There may be times, though, when you want to restrict the kinds of types that are allowed to be passed to a generic type parameter. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is accomplished in generic using a bounded type parameter, which list the type parameter’s name followed by the extends keyword. For example:

// determines the largest of three Comparable objects
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {                      
  T max = x; // assume x is initially the largest       
  if ( y.compareTo( max ) > 0 ) {
     max = y; // y is the largest so far
  }
  if ( z.compareTo( max ) > 0 ) {
     max = z; // z is the largest now                 
  }
  return max; // returns the largest object   
}

As with generic methods, the type parameter section of a generic class can have one or more type parameters separated by commas. For example:

public class Cell<T> {
  private T val;

  public void set(T val) { this.val = val; }

  public T get() { return val; }

  public static void main(String[] args) {
     Cell<Integer> integerCell = new Box<Integer>();
     Cell<String> stringCell = new Box<String>();
    
     integerCell.add(new Integer(10));
     stringCell.add(new String("Hello World"));

     System.out.printf("Integer Value :%d\n\n", integerCell.get());
     System.out.printf("String Value :%s\n", stringCell.get());
  }
}

Q: What is multiple inheritance? What are some potential problems with it and why has Java traditionally not supported it? How has this changed with the release of Java 8?

Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit characteristics and features from more than one parent object or parent class. It is distinct from single inheritance, where an object or class may only inherit from one particular object or class.

Until Java 8, Java only supported single inheritance. We’ll discuss Java 8’s quasi-support for multiple inheritance shortly, but first let’s understand what problems can result from multiple inheritance and why it has been so heavily avoided in Java.

The main argument against multiple inheritance is the complexity, and potential ambiguity, that it can introduce. This is most typically exemplified by the commonly cited “diamond problem”, whereby classes B and C inherit from class A, and class D inherits from both classes B and C. Ambiguity arises if there is a method in A that both B and C have overridden. If D does not override it, then which version of the method does it inherit; that of B, or that of C?

Let’s consider a simple example. A university has people who are affiliated with it. Some are students, some are faculty members, some are administrators, and so on. So a simple inheritance scheme might have different types of people in different roles, all of whom inherit from one common “Person” class. The Person class could define an abstract getRole() method which would then be overridden by its subclasses to return the correct role type, i.e.:

But now what happens if we want to model a the role of a Teaching Assistant (TA)? Typically, a TA is both a grad student and a faculty member. This yields the classic diamond problem of multiple inheritance and the resulting ambiguity regarding the TA’s getRole() method:

(Incidentally, note the diamond shape of the above inheritance diagram, which is why this is referred to as the “diamond problem”.)

Which getRole() implementation should the TA inherit? That of the Faculty Member or that of the Grad Student? The simple answer might be to have the TA class override the getRole() method and return newly-defined role called “TA”. But that answer is also imperfect as it would hide the fact that a TA is, in fact, both a faculty member and a grad student. There are multiple design approaches and patterns for addressing this type of situation without multiple inheritance, which is why some languages (Java being one of them) have made the decision to simply steer clear of multiple inheritance.

Java 8, however, introduces a form of quasi-support for multiple inheritance by allowing default methods to be specified on interfaces (prior to Java 8, only method signatures, not method definitions, were allowed on interfaces). Since Java does allow a single class to implement multiple interfaces (whereas a single class can only extend a single parent class), the allowance in Java 8 for method definitions in an interface introduces the potential for the diamond problem in Java for the first time.

For example, if A, B, and C are interfaces, B and C can each provide a different implementation to an abstract method of A, causing the diamond problem for any class D that implements B and C. Either class D must reimplement the method (the body of which can simply forward the call to one of the super implementations), or the ambiguity will be rejected as a compile error.

Gourmet Java

Here we present some more advanced concepts and issues that master Java programmers can be expected to be familiar with.

Q: How can you exit a thread reliably using an external condition variable?

Sometimes developers want to terminate a thread when an external condition becomes true. Consider the following example of a bus thread that continues to drive indefinitely until the pleaseStop variable becomes true.

boolean pleaseStop = false; // The bus pull cord.

public void pleaseStopTheBus() {
    pleaseStop = true;
}

public void startTheBus() {
    new Thread("bus") {
        public void run() {
            // Infinitely drive the bus.
            while (!pleaseStop) {
                // Take some time driving to the next stop.
            }
            pleaseStop = false; // Reset pull cord.
        }
    }.start();
}

Seems straightforward. However, Java doesn’t guarantee variable synchronization implicitly between thread boundaries, so this thread is not guaranteed to exit reliably, causing a lot of head scratching with less experienced Java developers.

Getting the above code to work properly would require synchronizing the threads as follows:

boolean pleaseStop = false; // The bus pull cord.
Object driver = new Object(); // We can synchronize on any Java object.

public void pleaseStopTheBus() {
	// Here in "thread 1", synchronize on the driver object
    synchronized (driver) {
        pleaseStop = true;
    }
}

public void startTheBus() {
    new Thread("bus") {
        public void run() {
            // Infinitely drive the bus.
            while (true) {
				// And here in "thread 2", also synchronize on the driver object
                synchronized (driver) {
                    if (pleaseStop) {
                        pleaseStop = false; // Reset pull cord.
                        return; // Bus stopped.
                    }
                }
                // Take some time driving to the next stop.
            }
        }
    }.start();
}

Q: How can null be problematic and how can you avoid its pitfalls?

For one thing, null is often ambiguous. It might be used to indicate success or failure. Or it might be used to indicate absence of a value. Or it might actually be a valid value in some contexts.

And even if one knows the meaning of null in a particular context, it can still cause trouble if the hapless developer forgets to check for it before de-referencing it, thereby triggering a NullPointerException.

One of the most common and effective techniques for avoiding these issues is to use meaningful, non-null defaults. In other words, simply avoid using null to the extent that you can. Avoid setting variables to null and avoid returning null from methods whenever possible (e.g., return an empty list rather than null).

In addition, as of JDK 8, Java has introduced support for the Optional<T> class (or if you’re using an earlier version of Java, you can use the Optional<T> class in the Guava libraries. Optional<T> represents and wraps absence and presence with a value. While Optional adds a bit more ceremony to your code, by forcing you to unwrap the Optional to obtain the non-null value, it avoids what might otherwise result in a NullPointerException.

Q: What is “boxing” and what are some of its problems to beware of?

Java’s primitive types are long, int, short, float, double, char, byte and boolean. Often it’s desirable to store primitive values as objects in various data structures that only accept objects such as ArrayList, HashMap, etc. So Java introduced the concept of “boxing” which boxes up primitives into object class equivalents, e.g., Integer for int, Float for float, and Boolean for boolean. Of course, as objects, they incur the overhead of object allocation, memory bloat and method calls, but they do achieve their purpose at some expense.

“Autoboxing” is the automatic conversion by the compiler of primitives to boxed objects and vice versa. This is simply a convenience, e.g.:

ArrayList<Integer> ints = new ArrayList<Integer>();

// Autoboxing.  Compiler automatically converts "35" into a boxed Integer.
ints.add(35); 

// So the above is equivalent to:  ints.add(new Integer(35));

Despite their convenience, though, boxed objects are notorious for introducing gnarly bugs, especially for less experienced Java developers.

For one thing, consider this:

System.out.println(new Integer(5) == new Integer(5));   // false

In the above line of code, we are comparing the identity of two Integer objects. Since each new Integer(5) creates a new object, one new Integer(5) will not equal another new Integer(5).

But even more troubling is the following seemingly inexplicable distinction:

System.out.println(Integer.valueOf(127) == Integer.valueOf(127));   // true
System.out.println(Integer.valueOf(128) == Integer.valueOf(128));   // false

Huh? How can one of those be true and the other be false? That doesn’t seem to make any sense. Indeed, the answer is quite subtle.

As explained in an easily overlooked note in the Javadoc for the Integer class, the valueOf() method method caches Integer objects for values in the range -128 to 127, inclusive, and may cache other values outside of this range as well. Therefore, the Integer object returned by one call to Integer.valueOf(127) will match the Integer object returned by another call to Integer.valueOf(127), since it is cached. But outside the range -128 to 127, Integer.valueOf() calls, even for the same value, will not necessarily return the same Integer object (since they are not necessarily cached).

It’s also important to note that computation using boxed objects can take around 6 times longer than using primitives, as can be evidenced by way of the following benchmarking code:

void sum() {
	Long sum = 0L; // Swap "Long" for "long" and speed dramatically improves.
	for (long i = 0; i <= Integer.MAX_VALUE; i++) {
		sum += i;
	}
}

Executing the above code with sum declared as Long took 6547ms whereas the same code with sum declared as long (i.e., the primitive type) took only 1138ms.

Q: What is type erasure?

The addition of Generics to the language has not been without its problems. A particularly thorny issue with Java Generics is that of type erasure.

As an example, consider the following code snippet:

List<String> a = new ArrayList<String>();
List<Integer> b = new ArrayList<Integer>();
return a.getClass() == b.getClass();  // returns true??!!

This should presumably return false since a and b are different class types (i.e., ArrayList<String> vs. ArrayList<Integer>), yet it returns true. Why?

The culprit here is type erasure. Once the above code passes all Java compiler validation, the compiler erases the String and Integer types in the above example, to maintain backward compatibility with older JDKs. The above code is therefore converted to the following by the Java compiler:

List a = new ArrayList();
List b = new ArrayList();
return a.getClass() == b.getClass();  // returns true (understandably)

And thus, in the compiled code, a and b are both simply untyped ArrayList objects, and the fact that one was an ArrayList<String> and the other was an ArrayList<Integer> is lost. Although in practice type erasure-related issues rarely cause problems for developers, it is an important issue to be aware of and can in certain cases lead to really gnarly bugs.

Q: Describe the Observer pattern and how to use it in Java. Provide an example.

The Observer pattern lets objects sign up to receive notifications from an observed object when it changes. Java has built-in support with the Observable class and Observer interface.

Here’s a simple example of an implementation of an Observable:

public class Exhibitionist {
	MyObservable myObservable = new MyObservable();

	public Exhibitionist() {}

	public java.util.Observable getObservable() {
		return myObservable;
	}

	private void trigger(String condition) {
		myObservable.invalidate();
		myObservable.notifyObservers(condition);
	}

	private class MyObservable extends java.util.Observable {
		private void invalidate() {
			setChanged();
		}
	}
}

And here’s a corresponding Observer example:

public class Voyeur implements Observer {

	public Voyeur(Exhibitionist exhibitionist) {
		// Register ourselves as interested in the Exhibitionist.
		exhibitionist.getObservable().addObserver(this);
	}
	
	@Override
	public void update(Observable o, Object arg) {
		// Called when the observable notifies its observers.
		System.out.println(arg.toString());
	}
}

There are a couple of downsides of using this though:

  1. The observed class must extend Observable and thus prevents it from extending a more desirable class (refer to our earlier discussion of multiple inheritance)
  2. Observed and observer classes are tightly coupled causing potential for NullPointerException’s if you are not careful.

To circumvent the first issue, an advanced developer can use a proxy (delegate) Observable object instead of extending it. To address the second issue, one can use a loosely coupled publish-subscribe pattern. For example, you might use Google’s Guava Library EventBus system where objects connect to a middleman.

Q: Describe strong, soft, and weak references in Java. When, why, and how would you use each?

In Java, when you allocate a new object and assign its reference (simply a pointer) to a variable, a strong reference is created by default; e.g.:

String name = new String(); // Strong reference

There are, however, two additional reference strengths in Java that you can specify explicitly: SoftReference and WeakReference. (There is actually one additional reference strength in Java which is known as a PhantomReference. This is so rarely used, though, that even highly experienced Java developers will most likely not be familiar with it, so we omit it from our discussion here.)

Why are soft and weak references needed and when are they useful?

Java’s garbage collector (GC) is a background process that periodically runs to free “dead” objects (one’s without strong references) from your application’s memory heap. Although the GC sometimes gives the impression of being a magical black box, it really isn’t that magical after all. Sometimes you have to help it out to prevent memory from filling up.

More specifically, the GC won’t free objects that are strongly reachable from a chain of strongly referenced objects. What that simply means is that, if the GC still thinks an object is needed, it leaves it alone, which is normally what you want (i.e., you don’t want an object you need to suddenly disappear when the GC kicks in).

But sometimes strong references are too strong which is where soft and weak references can come in handy. Specifically:

  • SoftReference objects are cleared at the discretion of the garbage collector in response to memory demand. Soft references are most often used to implement memory-sensitive caches.
  • WeakReference objects do not prevent their referents from being made finalizable, finalized, and then reclaimed. Weak references are most often used to implement canonicalized mappings.

Wrap up

Java continues to survive and thrive as a dominant and popular language. But as might be expected with any language that has gone through so many iterations, it has many nuances and subtleties that not all developers are familiar with. Moreover, the ever-increasing breadth of Java’s capabilities requires a great deal of experience to fully appreciate. Those who have mastered the language can therefore have a significant positive impact on your team’s productivity and your system’s performance, scalability, and stability.

The questions and tips presented herein can be valuable aids in identifying true Java masters. We hope you find them to be a useful foundation for “separating the wheat from the chaff” in your quest for the elite few among Java developers. Yet it is important to remember that these are merely intended as tools to be incorporated into the larger context of your overall recruiting toolbox and strategy.

(One final note: if your interest in Java is Android-centric, we suggest you read our Insider’s Guide to Android Interviewing as well.)

Hire Java developers now
Alvaro 1506e7

My team is going to personally help you find the best candidate to join your team.

Alvaro Oliveira
VP of Talent Operations