2

I'm currently writing an interview question for a java expert profile. Here it is:


Considering this code :

listing 1

package com.example;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Searching {
    public static void main(String[] args) {
        int input = Integer.valueOf(args[0]);
        String[] strings = {"1", "2", "4", "8", "16", "32", "64", "128"};
        List<Integer> integers = new ArrayList<Integer>();
        for (String s : strings) {
            integers.add(Integer.valueOf(s));
        }
        System.out.println("index of "+input+" is:"+Collections.binarySearch(integers, input, cmp));
    }

    static Comparator<Integer> cmp = new Comparator<Integer>() {
        public int compare(Integer i, Integer j) {
            return i < j ? -1 : (i == j ? 0 : 1);
        }
    };
}

This code is then compiled with this cmd line

listing 2

javac com/example/Searching.java

and run with this command line

listing 3

java com/example/Searching 128

QUESTION A:

Executing listing 3 produce:

index of 128 is:-8

Can you explain this output ?

QUESTION B:

Considering this

 java com/example/Searching 32

output is

index of 32 is:5

Can you explain this output ?

QUESTION C:

Assuming you have a JRE 1.6, a shell, and a text editor. What would you change to listing 1 and/or listing 2 and/or listing 3 to produce this output:

index of 128 is:7

remark: the less you change, the better it is.


My questions are :

  • what would be your answer to those questions ?
  • how to improve it ?
ben75
  • 29,217
  • 10
  • 88
  • 134
  • 8
    I think you have a low threshold for "expert" – Flexo Feb 02 '13 at 11:08
  • 1
    not sure... what would be your answer ? – ben75 Feb 02 '13 at 11:10
  • How can the index be 8 in an array with only 8 items – Esailija Feb 02 '13 at 11:13
  • It's not `8` but `-8`, see here why: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#binarySearch%28java.util.List,%20java.lang.Object,%20java.util.Comparator%29 – Michał Kupisiński Feb 02 '13 at 11:15
  • 6
    @Esilija It is -8. It means that the value was not found, and (in case it was there) it would be in the 7th position. The value is not found because it is comparing Integer with == (instead of equals). `32` is found because Java has a "funny" feature that caches all Integer that represent values between -128 and 127 (so all the Integer objects which hold `32` are the same object). – SJuan76 Feb 02 '13 at 11:16
  • 2
    @Flexo and I think you have no idea about this what SJuan76 wrote :) – Michał Kupisiński Feb 02 '13 at 11:21
  • The questions here seem to be: 1. a poll to get a sample of what a java programmer might think. 2. A question that can't have a clear right answer about how could this test be improved. Neither seems a good fit for stackoverflow. – Pablo Feb 02 '13 at 11:27
  • 1
    @emka86 - I don't consider myself to be a Java expert (and [yes, I am familiar with autoboxing](http://stackoverflow.com/a/12551108/168175)), but I also don't consider memorising API reference material to be the mark of an expert. – Flexo Feb 02 '13 at 11:28
  • 1
    @SJuan76 So instead of just returning -1 to signal not found like I am used to, it also signals the possible index where the item could be at the same time, as in `~-8 == 7`.. wow. :) – Esailija Feb 02 '13 at 11:29
  • @Flexo just adding an answer to explain my expectations with this question. – ben75 Feb 02 '13 at 14:15

3 Answers3

4

As an interview question, I would make the problem simpler. I have found that in interviews it can be much harder to solve these sort of problems without allot of hints. After a couple of questions they can't answer, interviewees can give up which isn't always productive.


Can you explain this output ?

There is a bug in the code with i == j which impact A & B differently. In one case the sort assumes the value is less than 128 and in the second it matches 32 because this is cached.

If you try something like -XX:+AggressiveOpts` or another option to increase the Integer cache size it would match in each case.

What would you change to listing 1

Change i == j ? 0 : -1 to i > j ? -1 : 0

Of course using Integer.compare() would some the problem ;)

how to improve it

Depending on the purpose of the program, I would use

int count = 0;
for(int n = Integer.parseInt(args[0]); n != 0; n >>>= 1)
  count++;
System.out.println(count);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • You didn't answer to question B. Why is it 5, and so why is it correct ? according your answer to question A there is a bug. – ben75 Feb 02 '13 at 11:15
  • There is also a bug in question B. ;) – Peter Lawrey Feb 02 '13 at 11:16
  • 1
    ... but it happens to work due the Integer cache size. – Peter Lawrey Feb 02 '13 at 11:23
  • @ben75 one of the first things a Java programmer should have learned is that comparing objects (pointers) is different from comparing values. Whether or not two pointers pointing to the same "value" are "identical" depends on whether or not they are actually the same pointer under a different name. Therefore you finding index 5 (correct answer) to searching for "32" is the "lucky chance" of Integer.parseInt() returning the same Integer object (pointer) twice for "32" more than anything else. – user268396 Feb 02 '13 at 11:26
  • @user268396 : sorry but you are wrong. read Peter answer – ben75 Feb 02 '13 at 11:27
  • @user268396 It's not an accident, Java 6 will cache values `-128 to 127` always and use this in `Integer.valueOf(String)` Some versions of Java 5.0 didn't do this, only for `Integer.valueOf(int)` – Peter Lawrey Feb 02 '13 at 11:48
  • @PeterLawrey That feature is called internalization, right? If I'm mistaken here I'm curious what the difference to internalization would be. – G. Bach Feb 02 '13 at 12:38
  • @Peter Lawrey accepting this because of the first note (see also my answer explaining my expectations) – ben75 Feb 02 '13 at 14:25
  • @PeterLawrey yes, we all known this is the case for the usual Java implementation (Oracle and HotSpot). There is AFAIK no requirement that *all* implementations do it, which is why I put "lucky chance" in quotes. – user268396 Feb 02 '13 at 15:49
  • @user268396 `JLS 5.1.7` "an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2. " – Peter Lawrey Feb 02 '13 at 16:02
4

Answer to C :

public class Searching {
    public static void main(String[] args) {
        int input = Integer.parseInt(args[0]);
        int[] values = {1, 2, 4, 8, 16, 32, 64, 128};
        System.out.println("index of " + input + " is:" + Arrays.binarySearch(values, input));
    }
}

since an expert wouldn't leave that code as awful as it is.

How to improve the interview question?

Don't do puzzles in an interview.

Or take a look at this page.

Community
  • 1
  • 1
bowmore
  • 10,842
  • 1
  • 35
  • 43
  • Yes, out of the box thinking like this is far more impressive than raw puzzle solving ability – Esailija Feb 02 '13 at 11:45
  • Question C is not about "puzzle solving ability", but "question reading ability". You only have a JRE so your only option is to modify listing 3. Thanks for the link. – ben75 Feb 02 '13 at 12:02
  • 1
    Ouch, you got me. You're still just selecting puzzle solvers rather than problem solvers. :) – bowmore Feb 02 '13 at 12:24
0

Just to explain my expectations with this question:

QUESTION A :

  • demonstrate basic knowledge of java language (difference between == and equals)
  • ability to understand ugly (and uncommented) code written by someone else

QUESTION B :

  • demonstrate more "in depth" knowledge of JVM and the Integer cache (in my opinion, not the most important)
  • demonstrate self-confidence : even if this strange behavior seems indicate that the answer the question A is not correct.

QUESTION C :

  • demonstrate the ability to carefully understand and assimilate constraints. In this case, there is no JDK available and so modifying listing1 or listing2 is not an option.

Additionally, it gives a clue for answering question B.

(i.e. adding a System property in the command line is what I'm expecting as an answer to this question : java.lang.Integer.IntegerCache.high).

ben75
  • 29,217
  • 10
  • 88
  • 134