I write this entry in response to Why Should I Bother?. The answer, in
short, is that I find Python to be a great language for getting things done,
and you shouldn't let stupid interviewers deter you from learning a language
that allows you to get more done.
I think I'm a pretty tough interviewer, so I also describe the things I'd
recommend that a Python coder knows before applying to a Java position, based
on my own technical-interview tactics.
A spectrum of formality
As my friend pointed out to me long ago, many computer scientists don't
care about effective programming methods, because they prefer theory.
Understandably, we computer scientists qua programmers (AKA software engineers)
find ourselves rent in twain.
As a computer science degree candidate, you are inevitably enamored with
complex formalities, terminology, [*] and a robust knowledge of mathematical
models that you'll use a few times per programming project (if you're lucky).
Pragmatic programming during a course of study often takes a back seat to
familiar computer science concepts and conformance to industry desires.
As a programmer, I enjoy Python because I find it minimizes boilerplate,
maximizes my time thinking about the problem domain, and permits me to use
whichever paradigm works best. I find that I write programs more quickly and
spend less time working around language deficiencies. Importantly, the
execution model fits in my brain.
Real Computer Scientists (TM) tend to love pure-functional programming
languages because they fit into mathematical models nicely — founded on
recursion, Curry-Howard isomorphism, and what have you — whereas Python is
strongly imperative and, in its dynamism, lacks the same sort of formality.
Languages like Java sit somewhere in the middle. They're still strongly
imperative (there are no higher-order functions in Java), but there are more
formalities. As the most notable example, compile-time type checking eliminates
the possibility of type errors, which gives some programmers a sense of safety.
[†] Such languages still let scientists chew on some computer sciencey
problems; for example, where values clash with the type system, like provably
eliminating NullPointerExceptions, which is fun, but difficult!
As the cost of increased formality, this class of languages is more
syntax-heavy and leans on design patterns to get some of the flexibility
dynamic typing gives you up front.
It's debatable which category of languages is easiest to learn, but Java-like
languages have footholds in the industry from historical C++ developer bases,
Sun's successful marketing of Java off of C++, and the more recent successes of
the C# .NET platform.
It makes sense that we're predominantly taught this category of languages in
school: as a result, we can play the percentages and apply for most available
developer jobs. Given that we have to learn it, you might as well do some
throw-away programming in it now and again to keep yourself from forgetting
everything; however, I'd recommend, as a programmer, that you save the fun
projects for whichever language(s) that you find most intriguing.
I picture ease-and-rapidity of development-and-maintenance on a spectrum from
low to high friction — other languages I've worked in fall somewhere on that
spectrum as higher friction than Python. Though many computer scientists much
smarter than I seem to conflate formality and safety, I'm fairly convinced I
attain code completion and maintainability goals more readily with the
imperative and flexible Python language. Plus, perhaps most importantly, I
have fun.
My technical-interview protocol
The protocol I use to interview candidates is pretty simple. [‡]
Analyze their background experience for potential weaknesses that would
affect their ability to perform in the position.
Don't let the candidate talk about anything until the last n minutes,
when they can ask questions or comment on the interview experience.
Hone in on the areas of potential weakness to determine how bad they are
(if they're bad at all).
Evaluate how easy it is to overcome those weaknesses. Determine where their
level in relevant areas falls in the Dreyfus model and how much it matters
to the description of the position.
Potential Java interview weaknesses
Interviewing a candidate whose background is primarily Python based for a
generic Java developer position (as in Sayamindu's entry), I would
immediately flag the following areas as potential weaknesses:
- Primitive data types
A programmer can pretty much get away never knowing how a number works in
Python, since you typically overflow to appropriately sized data types
automatically.
The candidate needs to know what all the Java primitives are when the
names are provided to them, and must be able to describe why you would
choose to use one over another. Knowing pass-by-value versus
pass-by-reference is a plus. In Python there is a somewhat similar
distinction between mutable and immutable types — if they understand
the subtleties of identifier binding, learning by-ref versus by-value will
be a cinch. If they don't know either, I'll be worried.
- Object oriented design
The candidate's Python background must not be entirely procedural, or they
won't fare well in a Java environment (which forces object orientation).
Additionally, this would indicate that they probably haven't done much
design work: even if they're an object-orientation iconoclast, they have to
know what they're rebelling against and why.
They need to know:
When polymorphism is appropriate.
What should be exposed from an encapsulation perspective.
What the benefits of interfaces are (in a statically typed,
single-inheritance language).
Basically, if they don't know the fundamentals of object oriented design,
I'll assume they've only ever written "scripts," by which I mean,
"Small, unimportant code that glues the I/O of several real applications
together." I don't use the term lightly.
- Unit testing
If they've been writing real-world Python without a single unit test or
doctest, they've been Doing it Wrong (TM).
unittest is purposefully modeled on xUnit. They may have to learn the
new jUnit 4 decorator syntax when they start work, but they should be able
to claim they've worked with a jUnit 3 -like API.
- Abstract data structures
Python has tuples, lists and dictionaries — all polymorphic containers --
and they'll do everything that your programmer heart desires. [§] Some
other languages don't have such nice abstractions.
It'd be awesome if they knew:
They must know (in ascending importance):
The difference between a HashMap and a
TreeMap.
The difference between a vector and a linked list, or
when one should preferred over the other. The names are
unimportant — I'd clarify that a vector was a dynamically growing
array.
The "difference" between a tree and a graph.
Turning attention to you, the reader: if you're lacking in data structures
knowledge, I recommend you read a data structures book and actually
implement the data structures. Then, take a few minutes to figure out where
you'd actually use them in an application. They stick in your head fairly
well once you've implemented them once.
Some interviewers will ask stupid questions like how to implement sorting
algorithms. Again, just pick up a data structures book and implement them
once, and you'll get the gist. Refresh yourself before the interview,
because these are a silly favorite — very few people have to implement
sorting functions anymore.
- Design patterns
Design patterns serve several purposes:
They establish a common language for communicating proposed solutions to
commonly found problems.
They prevent developers for inventing stupid solutions to a solved class
of problems.
They contain a suite of workarounds for inflexibilities in statically
typed languages.
I would want to assure myself that you had an appropriate knowledge of
relevant design patterns. More important than the names: if I describe them
to you, will you recognize them and their useful applications?
For example, have you ever used the observer pattern? Adapter pattern?
Proxying? Facade? You almost certainly had to use all of those if you've
done major design work in Python.
- Background concepts
These are some things that I would feel extra good about if the candidate
knew and could accurately describe how they relate to their Python analogs:
The importance of string builders (Python list joining idiom)
Basic idea of how I/O streams work (Python files under the hood)
Basic knowledge of typecasting (Python has implicit polymorphism)
Practical advice
Some (bad) interviewers just won't like you because you don't know their
favorite language. If you're interviewing for a position that's likely to be
Java oriented, find the easiest IDE out there and write an application in it
for fun. Try porting a Python application you wrote and see how the concepts
translate — that's often an eye-opener. Or katas!
If you find yourself unawares in an interview with these "language crusaders,"
there's nothing you can do but show that you have the capacity to learn their
language in the few weeks vacation you have before you start. If it makes you
feel better, keep a mental map from languages to number of jerks you've
encountered — even normalizing by developer-base size the results can be
surprising. ;-)
Footnotes
| [*] | Frequently unncessary terminology, often trending towards hot enterprise
jargon, since that's what nets the most jobs and grant money. |
| [†] | Dynamic typing proponents are quick to point out that this doesn't prevent
flaws in reasoning, which are the more difficult class of errors, and that
you'll end up writing tests for these anyway. |
| [‡] | Clearly candidates could exploit a vulnerability in my interview protocol:
leave off things they know I'm likely to test that they know particularly
well; however, I generally ask them to stop after I'm satisfied they
know something. Plus, the less I know about their other weaknesses the more
unsure I am about them, and thus the less likely I am to recommend them. |
| [§] | Though not necessarily in a performant way; i.e. note the existence of
collections.deque and bisect. Knowing Python, I'd quiz the
candidate to see if they knew of the performant datatypes. |